最近工作中接到一个需求:MTK平台和PC通过USB线传输数据。查看/usb/gadget目录下代码,发现android有实现好的usb转虚拟串口可以使用,本以为串口通信会很简单的,却遇到平台接收数据丢包的问题,花了两个星期才定位出来。因此在这里记录下定位过程。
问题描述:
PC串口助手发送数据,平台这边应用程序接收,会出现概率性接收不到,%5左右的概率,且丢的包没有什么规律。
应用程序:
fd_vcom = open("/dev/ttyGS0", O_RDWR);
while (1)
{
ret = read(fd_vcom, buff_rev, 9); --------阻塞模式,上位机发送数据,read没有返回
}
由于对串口传输不了解,对很多现象觉得很奇怪,如串口助手发送后又接收到一样的数据(linux 串口配置flag ECHO的作用)。
一开始怀疑是串口配置不对的问题,因此一直在试串口的不同配置,如把串口配置成规范模式(已行为单位)和原始数据模式。
发现配置都试过了还是丢包。串口配置flag如下:
https://blog.csdn.net/ywcpig/article/details/92081108
网上查资料很多都说串口丢包一般是中断没有响应或者buffer溢出的问题,如下面的博客:
https://blog.csdn.net/u013095415/article/details/83991859
但我的问题明显不是这两个,因为如果是中断没有响应的话,那串口自发自收就应该不对,而现象确是没有丢包;而如果是buffer溢出的话,也不应该是read没返回,而应该是数据值不对。(当然这是找到原因后分析的,当时的思路没这么清晰)
然后就怀疑中断的问题,想看看中断处理程序有没有收到数据,只能去看usb转串口的驱动。代码分析是看的这篇博客:
https://blog.csdn.net/dongkun152/article/details/102587758
大概写一下读和写的流程:
/usb/gadget/function/u_serial.c
读:
gs_read_complete(tasklet_schedule(&port->push);)
gs_rx_push(tty_insert_flip_string tty_flip_buffer_push将buffer传给tty层)
gs_start_rx(usb_ep_queue)
写:
gs_write()
gs_start_tx(usb_ep_queue)
gs_write_complete
在gs_rx_push函数里添加打印发现中断确实是有接收到数据,那说明就是在往上发的过程中出了问题,而上面是tty子系统,没有办法,只能去看tty驱动了。
tty驱动读写流程
tty/tty_io.c tty核心层
tty/n_tty.c tty线路规程
http://blog.sina.com.cn/s/blog_7d76fcfc0100wqjf.html
读:
读分为两段,第一段:
read tty_read n_tty_read(add_wait_queue,如果暂无数据可读,调用wait_woken休眠)
第二段:
usb中断收到数据 gs_rx_push tty_flip_buffer_push __receive_buf(调用kill_fasync发送异步信号,
wake_up_interruptible_poll唤醒调用n_tty_read的进程)
到了这里,在read的各个函数添加打印,似乎都正常打印,还是没看出哪里有问题,就是发现有莫名奇妙的的tty_poll的打印(select的调用,正是其他进程调用的select)(log的打印顺序有点乱,干扰了判断)
最后只能去找tty_poll是哪里来的,让自己的程序使用异步信号,然后把唤醒去掉,发现就不丢包了,于是推测是有另外的进程也在读取数据。
一、linux usb gadget
https://blog.csdn.net/yaozhenguo2006/article/details/7696679
二、usb转虚拟串口
https://www.cnblogs.com/ant-man/p/9508328.html
https://blog.csdn.net/dongkun152/article/details/102587758
https://www.cnblogs.com/tureno/articles/11077936.html
三、tty驱动
http://blog.sina.com.cn/s/blog_7d76fcfc0100wqjf.html
https://www.cnblogs.com/adera/p/13451638.html
https://blog.csdn.net/javac_/article/details/37914387
四、串口配置
https://blog.csdn.net/ywcpig/article/details/92081108