• 某模块休眠时接收短信不能在串口显示的问题


    问题描述:
    休眠时模块接收短信,连接USB组合的AT串口,不能显示短信信息。

    【测试步骤】
    1、短信接收方式设置为存储而不显示(AT+CNMI=2,1,0,0,0);
    2、执行AT命令,使能低功耗;
    3、长按DTR按键进入低功耗;
    4、间隔30s以上测试一次来短信,共测试接收短信3次;
    5、释放DTR按键;
    6、读取接收短信内容;
    7、执行AT命令,恢复默认设置。
    【预期结果】
    1、短信接收方式设置成功;
    2、使能低功耗成功,返回OK;
    3、成功进入低功耗,设备管理器USB口掉口;
    4、低功耗模式下来短信,能唤醒模块,唤醒成功率为100%;
    5、模块成功退出低功耗;
    6、模块接收到的短信与辅测终端发送的短信一致;
    7、恢复默认设置成功。
    【实测结果】
    6、模块退出低功耗后,不上报来短信提示,发送一条AT指令后才上报来短信。

    分析:
    应用的同事反馈UartWrite -> xxx_handler_write --> write这里返回值w_cnt是正数,表示写正常,但是休眠后最终没有在串口AT上打印出来,怀疑是底层驱动的问题。
    思路:看一下 w_cnt = write(m_pc_write_fd, buf, len)调用的流程,是不是只写到缓存里去了。

    流程:
    应用的write调用
    –> tty_write(tty_io.c)
    –> do_tty_write
    –> n_tty_write
    –> gs_write (u_serial.c)
    –> gs_start_tx

    gs_start_tx这个函数实现usb底层对数据的封装,传送到usb的端点。
    通过添加打印,发现休眠时gs_write这个函数里port->port_usb为空,只是把数据存到了buf,并没有调用gs_start_tx(port)。意味着USB端口还没有正常配置完成,并没有写成功。所以需要修改了这里的代码逻辑:如果没有写成功,给上层报一个负值,表示写出错,由上层保证写正确。

    static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count)
    {
    	struct gs_port	*port = tty->driver_data;
    	unsigned long	flags;
    
    	pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n",
    			port->port_num, tty, count);
    
    	spin_lock_irqsave(&port->port_lock, flags);
    	
    	if (count)
    		count = gs_buf_put(&port->port_write_buf, buf, count);
    
    	/* treat count == 0 as flush_chars() */
    	if (port->port_usb)
    		gs_start_tx(port);
    		
    	spin_unlock_irqrestore(&port->port_lock, flags);
    
    	return count;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这里无论是否发送成功,都会返回count。
    修改如下:

    #define USB_DISCONNECT_ERR		-11
    
    static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count)
    {
    	struct gs_port	*port = tty->driver_data;
    	unsigned long	flags;
    
    	pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n",
    			port->port_num, tty, count);
    
    	spin_lock_irqsave(&port->port_lock, flags);
    	
    	//begin:stone modify for tty disconnect
    	if (port->port_usb)
    	{
    		if (count)
    			count = gs_buf_put(&port->port_write_buf, buf, count);
    	}
    	else
    		count = USB_DISCONNECT_ERR;
    	//end:stone modify for tty disconnect
    	
    	/* treat count == 0 as flush_chars() */
    	if (port->port_usb)
    		gs_start_tx(port);
    	spin_unlock_irqrestore(&port->port_lock, flags);
    
    	return count;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    RabbitMQ快速入门
    【matplotlib基础】--子图
    人工智能AI:农业病虫害计算机视觉-西红柿番茄病害识别(10种病害)
    Flutter整体框架
    数据结构-排序算法总结
    考研过程中遇到学习焦虑怎么办--缓解学习焦虑的神奇方法
    linux系统操作/基本命令/vim/权限修改/用户建立
    组件间通信
    JDBC连接
    市面上跑步耳机哪种好、2023年最适合跑步用的耳机排名
  • 原文地址:https://blog.csdn.net/cornerstone1/article/details/127766661