本帖最后由 杨为民 于 2024-3-31 10:57 编辑
一、梦想照亮现实 (1)有个人说:“我有一个梦”,然后那个梦就实现了。有个网友有个理想: 对于单片机应用中断是最重要的实时响应技术手段。我理解他理想的RTOS系统是: 如果一个硬件中断的条件成立,就应该让该中断立刻发生,实现实时响应。 具体地说,对于STC32G单片机,理想的RTOS系统在任何时候都不应该关闭总中断(EA=0),哪怕关闭的极短的时间也不行,因为这个极短的关闭总中断的时间就成了限制RTOS系统的实时响应时间的上限。 (2)根据前文介绍的中断外任务切换方法,笔者认为V1.20版本的“挑战者x51 uC/OS-II移植版”已经实现了这个理想。 二、不使用任何中断的uC/OS-II移植版
(3)在前文范例的基础上,笔者删去了挑战者x51 V1.10版本中的与中断有关的程序,形成了V1.20版本,形成了本文的范例。下图是V1.10版本未删除的移植选项: 下图是V1.20版本已删除所有与中断有关的部分的移植选项: (4)首先删除了所有的临界区保护方法,第52行和第53行定义临界区保护方法为空。根据uC/OS-II的设计,所有uC/OS-II的程序均不会对任何中断进行操作。 (5)其次删除原型中有关“PendSv”的全部程序,将中断里任务切换函数“OSIntCtxSw()”指定为空。根据uC/OS-II的设计,所有uC/OS-II的程序均不会依赖任何中断。
(6)最后在本文范例中删除前文范例中与定时器中断有关的全部程序,比如下面的初始化程序: 以及定时器中断ISR。这样本文范例是在没有任何中断的情况下运行的单片机RTOS范例。 这证明V1.20版本的挑战者x51 uC/OS-II与中断无关,用户可以像裸机程序一样自由地使用任何硬件中断,对这些硬件中断事件V1.20版本的响应是“零延时”的。 三、uC/OS-II中断外任务切换使用方法 (7)本文范例的实时任务的优先级从高到低为任务A、任务B、任务C。范例的主任务是任务B,范例演示了将任务控制权切换到比自己优先级高或者低的任务的方法。
(8)下图是本文范例的主函数: 从中可以看到已经没有任何关于中断的程序了。
(9)下图是任务B中进行任务切换部分的程序: 其中第167行是将任务切换到任务A去的语句。由于任务A的优先级2比任务B的优先级3高,因此,第167行语句一执行,首先就会将任务B挂起在该程序行处,然后就去将任务控制权切换到任务A去执行。 如果一个任务要将任务控制权切换到优先级比自己高的任务时,只需要用“OSTaskResume”语句唤醒高优先级任务即可。
(10)下图是任务A的程序: 本文范例开始运行后,由于任务A优先级最高,它首先运行,然后在第98行处挂起自己,等待被唤醒。然后范例将控制权交给任务B去执行。 当任务A被任务B唤醒后,任务A的程序将从第98行的函数返回,顺序执行任务程序,直到再次在第98行处挂起自己,等待被唤醒。然后范例将控制权返回给任务B去恢复执行。 如果一个任务要将任务控制权返回到优先级比自己低的任务时,只需要用“OSTaskSuspend”语句挂起自己即可。 (11)前面任务B的第149行程序唤醒任务C(对于只有三个任务,这一行是多余的),使得任务C处于就绪状态。但由于任务B的优先级比高于任务C,任务C不会立即执行。当第150行程序挂起任务B时,任务的控制权才交给任务C去执行。 如果一个任务要将任务控制权切换到优先级比自己低的任务时,不但需要用“OSTaskResume”语句唤醒低优先级任务,而且还需要用“OSTaskSuspend”语句挂起自己。
(12)下图是本文范例运行效果的逻辑分析仪截屏: 其中通道2是任务B信号,通道3是任务切换信号,通道4是任务A信号,通道5是任务C信号。 从中可以看出,无需借助任何中断,也不会干预任何中断,V1.20版本的挑战者x51 uC/OS-II移植版可以正常运行,实现单片机RTOS系统的按优先级进行任务切换功能。 附件:本文范例源程序
|