NFYG2022 发表于 2023-7-5 14:09:41

RTThread中用软件定时器结合信号量控制UART的问题

MCU有一个UART发送任务,以200Hz频率(5ms间隔)发送20字节数据给上位机。想着最近看了写rtthread信号量的资料,就想用二值信号量+200Hz定时器控制UART发送。

就是在定时器回调函数中,把二值信号量置1。UART循环发送任务每次发送前都获取该信号量。但问题是这样的UART发送经常丢数据、卡顿,甚至阻塞上位机的下行命令......

不知道原因何在,后来放弃了信号量,换回了传统的【在回调函数中置send flag为1的方法】,就没有卡顿、丢数据的情况了。

搞不懂这里的原因,难道获取信号量、释放信号量、线程调度是很耗时的操作吗?

security 发表于 2023-7-5 15:04:51

当任务主动退让了 CPU 占有权后,在所等待的同步对象释放时,想要再次占有 CPU 时,需要看自己是不是那个最高优先级的就绪任务,以及等待同步对象时的入队方式(RT_IPC_FLAG_FIFO 还是 RT_IPC_FLAG_PRIO),是的话,才会优先把 CPU 占有权还给你。

检查一下任务优先级相关的。

初音之恋 发表于 2023-7-5 15:55:59

我觉得直接sleep5ms发送不是更方便吗,目测数据在发送过程中flag已经被置位了(5ms 发送20个字节时间够不够?),导致回调函数用信号量的时候还没有回收回来就被卡了

NFYG2022 发表于 2023-7-5 16:15:36

security 发表于 2023-7-5 15:04
当任务主动退让了 CPU 占有权后,在所等待的同步对象释放时,想要再次占有 CPU 时,需要看自己是不是那个最 ...
(引用自2楼)

一共2个任务线程,主任务 和 UART发送,都以200Hz执行,理想的执行计划是每个5ms间隔内,先执行主任务,再执行UART发送。
UART波特率921.6kbps,发送20bytes只要约0.2ms,绰绰有余,主任务也不耗时。

security 发表于 2023-7-6 09:50:16

NFYG2022 发表于 2023-7-5 16:15
一共2个任务线程,主任务 和 UART发送,都以200Hz执行,理想的执行计划是每个5ms间隔内,先执行主任务, ...
(引用自4楼)

考虑一下以下这种场景的可能性:
1、假设在 6ms 的时间点,等待信号量
2、假设定时器在 7ms 的时间点,释放了信号量
3、发送任务,在 6ms 的时间点,等不到信号量,就将任务挂起来了,此时 CPU 转入执行主任务(执行时长为 5ms)
4、定时器在 7ms 的时间点,释放了信号量,唤醒了 UART 发送任务
5、UART 发送任务被插入到就绪任务列表中,但由于主任务和 UART 发送任务的优先级一样,而且主任务本身还在运行状态,因此必须等到主任务的 5ms 执行完毕,才会去执行 UART 发送任务

Mrp_Young 发表于 2023-7-6 09:54:59

5ms,9600波特率发送1个字节都要1ms了。

security 发表于 2023-7-6 09:56:52

Mrp_Young 发表于 2023-7-6 09:54
5ms,9600波特率发送1个字节都要1ms了。
(引用自6楼)

楼主是 921600 的波特率。

think_a_second 发表于 2023-7-6 10:29:54

分步测试:
1. 先测没定时器和信号量,只用sleep
2. 只用定时器,在定时器回调函数里发送数据
3. 在定时器回调函数释放信号量,线程获取信号量并发送
页: [1]
查看完整版本: RTThread中用软件定时器结合信号量控制UART的问题