本帖最后由 杨为民 于 2024-3-31 11:21 编辑
一、引 言 (1)笔者在论坛中提出了对RTOS系统的基本测试方法和测试程序,引起了很大的反响和争议,包括对任务切换速度的测试、临界区保护方法为空(方法0)时的任务调度测试、对于临界区保护方法1(关闭总中断的方法)在临界区保护嵌套中进行任务调度的测试、对于临界区保护方法2(对任务调度加锁/解锁的方法)在临界区保护嵌套中进行任务调度的测试、以及对于临界区保护方法3(不关闭任何中断的方法,见前文)的测试。 本文将介绍笔者对RTOS系统的下一个基本测试方法和测试程序——单片机RTOS系统对用户程序打开/关闭总中断的响应。 (2)对于裸机编程应用,用户可以自由地打开和关闭总中断。对于一个具体的单片机RTOS系统,在RTOS程序中用户是否可以自由地(或者多大程度地)使用非系统中断(包括打开和关闭总中断EA)是衡量单片机RTOS重要的一项指标,这项指标影响着用户的编程方法和应用领域。 通常RTOS系统都包括定时器节拍等系统中断,因此运行时总中断总是打开的EA=1。但是系统运行的时候允不允许用户自由地写EA=0关闭所有中断,以及长时间关闭总中断会对系统产生什么影响对于不同的RTOS系统却是不同的。 (3)为了测试挑战者x51移植版V3.30是否允许用户自由地关闭打开总中断EA,本文提供了三个范例:第一个范例是三个实时任务同时执行,第二个范例是观察关闭和打开总中断的影响,第三个是任务交替执行。 (4)通常给用户进行测试的产品都采用“黑箱”模型,挑战者x51-RTOS产品测试版也是以库函数的封装方式提供的, 产品测试版以封装的方式提供的最大优点是容易确定是产品内部的问题还是测试程序的问题。 二、范例一:实时多任务同时执行 (5)本文范例一的任务A是一个P0端口的LED灯闪烁,任务的程序如下图: 其中第72行和第79行是P0端口的8个LED灯一起闪烁的视觉效果,第74行到第77行和第81行到第84行是供逻辑分析仪显示的通道2信号,信号是一个连续的40毫秒周期的方波。
(6)本文范例的任务B是一个P1端口的LED灯闪烁,任务的程序如下图: 其中第96行和第101行是P1端口的左右各4个LED灯交替闪烁的视觉效果,第97行到第100行(100毫秒方波)和第102行到第105行(30毫秒方波)是供逻辑分析仪显示的通道4信号。
(7)本文范例的任务C是一个P3端口的LED灯闪烁,任务的程序如下图: 其中第119行和第120行是P3端口的6个LED跑马灯的视觉效果,第121行到第124行是供逻辑分析仪显示的通道5信号,信号是一个连续的40毫秒周期的方波。
(8)本文范例均使用定时器0作为系统节拍中断源,使用定时器3作为对比中断源,观察总中断EA的关闭对它们的影响。下图是相关的程序: 其中第74行到第77行将定时器0补充设置为不可屏蔽中断的模式3,在第91行到第97行的定时器0中断的ISR中第95行是RTOS的系统节拍函数调用,第93行和第96行在逻辑分析仪的0通道产生1毫秒周期的正脉冲。 图中的第113行到第116行的定时器3中断的ISR是在逻辑分析仪6通道上产生5KHz的方波。定时器3的中断是否发生依赖于总中断EA是否打开。
(9)下图是范例一运行时的逻辑分析仪截图: 通道0和通道6的中断信号是连续的,通道2的任务A信号、通道4的任务B信号和通道5的任务C信号也都是连续的。 由于范例一任务中所有控制LED灯闪烁的延时函数都采用了RTOS的休眠函数“OSTimeDly()”,在延时期间对挂起当前任务,将CPU执行权留给其他就绪任务去执行,从图中可以看出任务A、任务B和任务C是同时执行的。 三、范例二:关闭和打开总中断的影响
(10)本文范例二的任务A与任务B与范例1的相同,只是在任务B的主循环中加上关闭和打开总中断EA的语句,以观察EA对RTOS系统运行的影响。任务B的程序如下图: 其中第95行和第103行分别为关闭和打开总中断EA,第94行和第102行是将EA的状态显示逻辑分析仪的第1通道上,高电平为EA=1,低电平EA=0。
(11)下图是范例二运行时的逻辑分析仪截图: 其中通道1周期地显示出高低电平信号,代表总中断EA交替地关闭和打开。 (12)从上图中可以得出以下结果,在一个任务中关闭和打开总中断EA: 对不可屏蔽中断定时器0中断(系统中断)通道0没有影响。对三个实时任务的连续执行通道2、通道4和通道5没有影响。 对于一般定时器3中断通道6,EA=0(低电平)期间中断被关闭。 (13)结论:对于挑战者x51移植版V3.30,用户可以在同一个任务里自由地关闭和打开总中断,对非系统中断进行控制,不影响任务的执行。 四、范例三:任务交替执行
(14)本文范例三的任务A与范例1的相同,只是在任务B的主循环中加上关闭总中断EA和在任务C中打开总中断EA的语句,以观察EA对RTOS系统任务调度的影响。其中任务B的程序如下图: 其中第100行和第101行在任务B中断关闭总中断。任务C的程序如下图: 范例三任务C将6个跑马灯程序分为两半,在其中第132行到133行打开总中断EA。图中第131行休眠延时程序是为了在逻辑分析仪上产生一个打开EA的时间信号。
(15)下图是范例三运行时的逻辑分析仪截图: 对比范例二,可以看出在任务C中打开总中断EA并不影响任务C的执行和任务调度。 在任务B循环中关闭总中断EA,导致任务B要循环三次关闭三次总中断EA才能挂起自己,将任务控制权交给任务C去执行,因此也不影响任务B的执行和任务调度。 (16)结论:对于挑战者x51移植版V3.30,用户可以在不同的任务里自由地关闭和打开总中断,对非系统中断进行控制,不影响任务的执行和任务的调度。 五、微山x51-uCOSII移植版V1.10范例二测试 (17)微山x51-uCOSII移植版V1.10是笔者为uC/OS-II教学开发的一个教学版本,该版本的临界区保护方法为直接关闭总中断的不可嵌套的方法1: #defineOS_ENTER_CRITICAL() EA=0 /* 直接禁止中断 */ #defineOS_EXIT_CRITICAL() EA=1 /* 直接允许中断 */
下图是该版本对本文范例二的测试结果: 其中由于通道1被中断内任务切换信号占用,总中断EA信号改在了通道7。 从图中可以看出,关闭总中断EA=0从整体上看对于三个任务也没有什么影响,并且对定时器0(不是不可屏蔽的模式)和定时器3中断也没有什么影响。这个结果说明对于微山x51-uCOSII移植版V1.10,用户程序根本不可能有效地关闭总中断,因此只要一碰到RTOS的核心函数里面的临界区保护退出语句,中断立马就被打开了。 (18)结论:对于微山x51移植版V1.10,用户不能够自由地关闭和打开总中断,对非系统中断进行控制,虽然这不会影响到RTOS系统本身和任务的调度。 六、uCOS-II-2.93.01移植版范例二测试
(19)uCOS-II-2.93.01 for STC32G12K128移植版的临界区保护方法为利用局部变量保存总中断状态的可嵌套的方法3,下图是该版本对本文范例二的测试结果: 从图中可以看到开机LOGO信号之后,任务B一开始执行系统就停机了,所有中断不再发生,任务调度无法进行。
(20)这时如果将任务B中关闭和打开总中断EA的语句注释掉,程序便能正常运行,见下图: 其中通道1是没有注释掉的EA电平信号。这证明上面的死机是关闭总中断产生的。 对比微山x51临界区保护方法1的结果,可以知道这里的问题出在可嵌套的方法3上。当总中断被用户(不是RTOS系统)关闭后,执行临界区进入保护语句时,保存的是总中断关闭状态,然后执行临界区退出保护语句时恢复的仍然是总中断关闭状态,因此总中断永远不会再被打开,整个系统死机。
(21)结论:对于uCOS-II-2.93.01 for STC32G12K128移植版,用户不能够自由地关闭和打开总中断,对非系统中断进行控制,并且甚至会关闭RTOS系统本身和任务的调度。
|