驱动中写串口问题。
我在驱动中打开了串口,用tty的write和file的write往串口发数据,这些工作我都放在tasklet里面处理的,10ms调度一次,每次发送32字节,问题是我慢着点发就没有问题,一旦发快点就丢数据或是乱序。
为什么我在应用层发就不丢数据或是数据乱序呢?
驱动中的设置跟应用层我都设成一样了。115200 8N1,一旦速度上1k/s就乱。再快就panic了。
希望牛人帮忙解答啊,在线等!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你这个问题可能跟Modem串口驱动那位兄弟的问题比较类似。
首先,串口的特性需要明白,它是一个低速设备,它的发送能力可能与你的处理器的能力是数量级上的差异,串口是一个字节一个字节的发送数据的。
其次,在应用层发送数据时,应用层序会有一个缓冲区,就是说应用程序可以等待,串口在发送完一个字节后,通过某种状态通知应用层而继续取缓冲区数据发送。
你如果在tasklet中做发送,那么很显然,这是工作在内核空间,内核没有提供这个缓冲的机制。于是,它不顾及串口的处理能力,强行的把数据塞给串口发送,而串口本身有自己的硬件缓冲,当然这个缓冲相当小,在它无法容纳别人给它的数据的时候,它就被迫丢弃数据,只做自己力所能及的事情。
于是,你这个现象也就很好解释了。
我觉得,串口通常有发送结束的中断,以及相关状态位来检测其对前一个字节是否发送结束,你可以查看一下,保证在发送结束后再发下一个字节才是合理的。另外,tasklet不允许睡眠,在考虑这个问题时,你也要注意。
非常感谢版主的解答,我想是kernel没有缓冲机制造成的,如果我去检测串口硬件的标志位,估计不大可能,我没有kernel源码,驱动是模块加载上去的。看来最好的办法是直接控制串口的驱动了,另外这个任务实时性很高,再没有比tasklet更好的处理方式。
再次感谢版主!~
实时性再高,也不能超过串口处理负荷,否则就会牺牲可靠性来满足实时性了,呵呵。
可以自己剖析一下这个驱动嘛
[ 本帖最后由 dreamice 于 2008-11-21 11:01 编辑 ]
说的也是,一旦睡眠就至少是10ms,我得保证10ms内的延时,万一不行就放应用层。
我试试放在应用层的延时先!
我觉得这种情况下用工作队列更好
工作队列可以睡眠,且可以在不同的处理器上运行,这是它的优点,但是,其执行点有时候显得无法预知,所以,必须权衡使用哪样一种策略。