新闻  |   论坛  |   博客  |   在线研讨会
串口DMA跑数据接收压力测试的问题及其解决办法
dianlaotie | 2022-03-24 14:08:56    阅读:1330   发布文章

做项目时使用官方串口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次数据,低优先级消费者线程出队列只能取到最后一条数据。这个我也很纳闷。我觉得可能跟线程抢占有关或者优先级翻转之类的现象,解决办法也许把消费者和生产者加上互斥锁后应该就能解决,但是这样的话,因为被锁了,生产者线程有可能不能及时接受到外来数据导致丢包。


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客