串口DMA调试注意事项(经验)

发布于 2019-08-18 20:39:06
做项目时使用官方串口DMA例程,在跑数据接收压力测试时发现了一些细节问题,正是这些问题卡了我2天。现在终于得到解决,在此立个贴做记录。例程现象:
1. 串口DMA在接收过程中,是不定长接收的。就算你上位只发送了1次,例程接收端总会给你2 - N段不定长数据给你。论坛上也有类似的帖子说是底层驱动的某些特性。
2. 串口DMA在接收线程中serial_thread_entry里面不可以做协议数据解析,尽管这是个独立的线程,尽管你的数据解析函数没有任何阻塞线程的动作,都不行。你必须把接收到的数据通过其他途径转移到其他线程去处理(比如消息队列)。否则会产生意想不到异常,现象是在运行一段时间后tshell卡死,或者当前接收线程直接在ps列表消失,但是依然可以接收数据,无论哪样最终都会让tshell完全卡死加死机,就连cmTraceback也救不了(不能百分百触发异常播报),cmTraceback只会告诉你的shell串口在接收中断处有问题,但是具体什么问题我看不出。个人怀疑是 rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size); 这个函数有隐藏阻塞,如果在下文加上长延时的数据解析会导致跟tshell冲突。
尝试过,提高或降低tshell 或 syswork或其他线程优先级,增大串口或线程缓冲区。都不行。
解决办法:
串口接收线程收到的数据只能再中转到其他线程去做处理。 以下是我串口生产者,和消费者代码。
小提示:
消费者线程的优先级要高于生产者线程的优先级(消息队列应用),否则会出现数据覆盖的现象。比如,高优先级生产者队列入了3次数据,低优先级消费者线程出队列只能取到最后一条数据。这个我也很纳闷。我觉得可能跟线程抢占有关或者优先级翻转之类的现象,解决办法也许把消费者和生产者加上互斥锁后应该就能解决,但是这样的话,因为被锁了,生产者线程有可能不能及时接受到外来数据导致丢包。




消费者.png
生产者.png

查看更多

关注者
1
被浏览
1.7k
9 个回答
aozima
aozima 2019-08-18
拒绝白嫖,拒绝键盘侠!
谢谢分享
我夏了夏天
我夏了夏天 认证专家 2019-08-19
谢谢楼主分享
hsrock
hsrock 2019-08-20
谢谢分享,值得参考
zxc807492312
zxc807492312 2019-08-21
就是要再开一个线程专门用于rt_device_read,然后发送出去吗?
bevis
bevis 2019-08-21
zxc807492312 发表于 2019-8-21 13:22
就是要再开一个线程专门用于rt_device_read,然后发送出去吗?


rt_device_read历程已经有了,只需要把read到的数据,放到其他线程解析处理
RickFlying
RickFlying 2019-08-26
楼主你好,我现在遇到跟你一样的问题,我按照你的思路,把串口协议解析相关的函数单独放到另外一个线程里,依然不行。

问题可能出在我自己编写的串口协议解析函数上了。

能否恳请您分享一下您消费者线程中 msg_handler() 函数的源码呢?看见您在协议解析部分做的很完善,十分想参考学习一下。(感谢)
bevis
bevis 2019-08-27
RickFlying 发表于 2019-8-26 19:56
楼主你好,我现在遇到跟你一样的问题,我按照你的思路,把串口协议解析相关的函数单独放到另外一个线程里, ...


这个函数主要是处理每一次接收的零散包,把收到的零散包放进去,里面用switch case逐字解析,把当前包长解析完后,还没到达包尾的case就返回特定值,重新在外面取数。
你这个问题还有个原因是,你确定你在另一个线程取的数是正确的?
RickFlying
RickFlying 2019-08-27
bevis 发表于 2019-8-27 09:15
这个函数主要是处理每一次接收的零散包,把收到的零散包放进去,里面用switch case逐字解析,把当前包长 ...


取得数据是正确的。我看您的描述,跟我预想实现的功能差不多,尤其您程序中的那个判断是否到达包尾的功能,正是我想实现的,不过我的解析有很大局限性,并不能向您的程序一样返回不同的状态作为判断。还有您提到的重新在外面取数的功能,是不是为了解决串口DMA接收出现数据分包的情况呢?

以上,十分想参考学习一下您的这个函数的具体实现。最近在搞这一块代码,遇到很多瓶颈。可否分享一下这个函数的代码让我参考参考???(qq:2625844328)
bevis
bevis 2019-08-27
RickFlying 发表于 2019-8-27 16:55
取得数据是正确的。我看您的描述,跟我预想实现的功能差不多,尤其您程序中的那个判断是否到达包尾的功能 ...


加你了

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览