杨为民 发表于 2024-5-23 03:19:15

华山论剑(3): CosyOS-II-STC8H在测试高优先级中断服务调用时崩溃了

本帖最后由 杨为民 于 2024-5-24 16:27 编辑

5月15日,采用“不关闭总中断”的临界区保护方法的CosyOS-II推出了官宣的“零中断延迟测试”程序:
5/22,实时操作系统RTOS线上教学,参会送【USB转双串口,烧录器,仿真器】 https://www.stcaimcu.com/forum.php?mod=viewthread&tid=1807 (出处: 国芯技术交流网站)
笔者挑选了“CosyOS-II-STC8H-工程模板”,将原来每秒进行1次的“高优先级中断系统服务调用”修改为每25微秒(25uS)进行1次,结果在测试时系统崩溃了。下面是测试过程和测试结果。(1)测试类型选择1(有服务调用并恢复task_3):
(2)增加任务1和任务2的LED/逻辑分析仪信号输出:
其中在第53行增加“P01=~P01;”作为任务1的信号输出,在第66行增加“P02=~P02;”作为任务2的信号输出。(3)修改任务3的信号输出:
其中在第79行增加“P04=~P04;”作为任务3的信号输出。对任务3的最重要修改是注释掉第77行原来串口输出语句,这样就可以排除系统崩溃中串口的因素。(4)对于高优先级中断中调用系统服务的周期的修改测试:
CosyOS-II的测试方法是将定时器1设置为最高优先级模式,然后将定时器1的中断周期设置为5微秒。然后在定时器1的ISR中用一个计数器控制进行中断调用的周期。其中第100行程序是调用“iResumeTask(task_3)”系统服务来唤醒任务3。原来的第95行是每秒调用一次。第96行是每10毫秒调用一次,第97行是每25微秒调用一次。测试时注释掉其中两行,留下一行进行对应的测试。(5)每秒一次中断调用的测试结果:
其中可以看到通道3的中断内系统服务调用信号,通道4的任务3的每秒一次的周期反转信号。(6)每10毫秒一次中断调用的测试结果:
从中可以看到通道4的任务3的每10毫秒一次的周期反转信号和通道3的中断调用信号。图中通道1和通道2是任务1和任务2的信号,任务每激活一次信号就反转一次。(7)每25微秒一次中断调用的测试结果:
从图中可以看出系统运行时崩溃了,除了定时器1的5微秒的中断信号,其他任务1、2、3的信号都没有了。
(8)对于崩溃的原因,笔者觉得不是程序BUG造成的,而是由于CosyOS-II没有采用关闭总中断作为临界区保护方法造成的。





tzz1983 发表于 2024-5-23 07:50:17

本帖最后由 tzz1983 于 2024-5-23 10:10 编辑

杨老师,你排查一下是否是因为CPU使用率超过100%了,这么高频的周期中断,完全可能的。
如果是这样,则造成除了中断代码本身,其它的代码都没有机会执行。
如果我的猜想成立,那就不算是BUG,只能说处理能力达不到这么高的速度。

就拿祼机来说, 同样给25微秒的周期中断,只要中断代码本身的代码执行时间接近25微秒,
那主程序必然是没机会执行的,就是“崩溃“。

杨为民 发表于 2024-5-23 10:03:02

tzz1983 发表于 2024-5-23 07:50
杨老师,你排查一下是否是因为CPU使用率超过100%了,这么高频的周期中断,完全可能的。
如果是这样,则造成 ...

改改你不仔细阅读中文题目的坏毛病:我说是BUG了吗?

杨为民 发表于 2024-5-23 10:04:54

tzz1983 发表于 2024-5-23 07:50
杨老师,你排查一下是否是因为CPU使用率超过100%了,这么高频的周期中断,完全可能的。
如果是这样,则造成 ...

还是等本尊给个官宣的说法吧

CosyOS 发表于 2024-5-23 11:33:47

本帖最后由 CosyOS 于 2024-5-23 12:27 编辑

系统崩溃的原因
1、首先不是因为 定时器1中断的 5us周期 时间过短,否则,源测试程序也不能正常运行了。

2、而是因为每 25us 调用一次 iResumeTask(task_3)。
25us的时间太短了,PendSV中切换任务差不多也是这个时间。
由于 iResumeTask 是挂起服务,是要入队列的,
每25us调用一次,是典型的“生产速度 > 消费速度”,会造成 PendSV 中根本来不急执行服务,
并最终导致 “中断挂起服务队列” 持续溢出,内存被覆盖。

3、即使内存不会覆盖,系统也无法正常运行。
因为 定时器1中断每5us发生一次,最大执行时间 大概是 4us多;
即使中断中不调用服务,PendSV中断的执行时间至少也需20us;
每25us 调用一次 iResumeTask(task_3),需要 PendSV 来执行,
由于来不急执行源源不断的服务,
会导致 中断挂起服务队列 的实际深度会越来越深,
PendSV中的处理时间也会越来越长,形成 “恶性循环”,
并最终导致 只能是在这两个中断里来回不停的 “折腾”,再没有时间做其它的事情。

对于这种极端测试情况,CosyOS 确实是无法胜任的,建议用户更换其它RTOS来实现。

如果把 每25us 调用一次 iResumeTask(task_3),改为 每50us调用一次,大概率可能会成功的。





CosyOS 发表于 2024-5-23 11:45:26

本帖最后由 CosyOS 于 2024-5-23 12:03 编辑

其实,每25us调用一次服务也不是说就不行,但是不能是 “源源不断的每25us调用一次”。
如果是短暂的并发,即使是每5us调用一次 iResumeTask(task_3),也是可以的。
如连续10次、或20次的,每5us调用一次 iResumeTask(task_3),都是没有问题的,
只要中断挂起服务缓存不溢出就行。这也正是队列的意义,支持有限的并发。
但是,如果是 “永不停息的 每5us~25us 调用一次”,那就 gameover 了!



zxcv1973 发表于 2024-5-23 11:58:47

tzz1983 发表于 2024-5-23 07:50
杨老师,你排查一下是否是因为CPU使用率超过100%了,这么高频的周期中断,完全可能的。
如果是这样,则造成 ...

51的中断机制不会造成主程序没机会执行,只是执行比较慢而已

CosyOS 发表于 2024-5-23 12:01:36

zxcv1973 发表于 2024-5-23 11:58
51的中断机制不会造成主程序没机会执行,只是执行比较慢而已

是的,你说的正确!
是挂起服务队列的持续溢出,导致内存覆盖的原因。

杨为民 发表于 2024-5-23 12:49:02

本帖最后由 杨为民 于 2024-5-23 12:55 编辑

CosyOS 发表于 2024-5-23 11:33
系统崩溃的原因
1、首先不是因为 定时器1中断的 5us周期 时间过短,否则,源测试程序也不能正常运行了。


(1)对于崩溃的原因,我相信本尊的判断。

(2)下面是50uS一次调用的测试结果:


明显可以看出任务3开始工作了。由于任务3是中断调用的任务,中断任务的优先级大于任何非中断的任务2和任务3,因此但凡CPU有一点空闲,首先就切换到任务3了。
(3)下面是100uS一次调用的测试结果:



明显可以看出不但任务3工作,非中断的任务2和任务3也开始工作了。

(4)我的结论:
由于存在“典型的“生产速度 > 消费速度”,会造成 PendSV 中根本来不急执行服务,并最终导致 “中断挂起服务队列” 持续溢出,内存被覆盖。”的内在原因,
对于CosyOS-II-STC8H来说,连续的两次高优先级中断调用服务的时间“最短不得低于25微秒”,因此并没有实现“连续的两次高优先级中断调用服务的零中断延迟”。
(5)我的建议:CosyOS-II如果要继续使用“零中断延迟”作为标志性词,应该进行更加明确其含义和使用范围,这样才算得上是对用户负责。




杨为民 发表于 2024-5-23 12:54:16

CosyOS 发表于 2024-5-23 11:33
系统崩溃的原因
1、首先不是因为 定时器1中断的 5us周期 时间过短,否则,源测试程序也不能正常运行了。



“对于这种极端测试情况,CosyOS 确实是无法胜任的,建议用户更换其它RTOS来实现。”

我可以把这句话理解为是挑战,是要打擂台PK吗?
页: [1] 2
查看完整版本: 华山论剑(3): CosyOS-II-STC8H在测试高优先级中断服务调用时崩溃了