本帖最后由 杨为民 于 2024-3-31 10:56 编辑
一、挑战者x51 uC/OS-II移植版简介
(1)挑战者x51是将uC/OS-II移植到STC32G单片机上的移植版的名称。挑战者x51的设计目标是一个公开源代码的具有产品级可靠性的移植版,通过开源的代码展示单片机RTOS产品的可靠性与底层代码和顶层设计之间的关系,供教学、学习和研究使用。 由于挑战者x51的RTOS的核心部分直接使用了Micrium公司的uC/OS-II以源代码,因此挑战者x51的使用者如果计划在商业产品中使用,则需要联系Micrium公司得到正确的许可。 (2)挑战者x51的原型来源于网友tzz1983的“UCOSII - STC32G12K128”,按照他自己的介绍是“自已花了两天时间把USOS2.91版本移植到了STC32G12K128上面。 移植过程还算比较顺利。(参考了STC官网上FREERSOS的汇编代码,和M3的移植思路),只花了一天多一点的时间。”通常我们将这种花几天的时间就推出来的RTOS移植版称为“玩家版”。 具体文章见:UCOSII - STC32G12K128 移植 (3)挑战者x51的原型的最大特色是使用了用定时器4硬件中断代替软中断的方法(以后称这种方法为“替代法”)。这种替代法具有明显的两个优点:程序简明易懂和任务切换速度很快。 关于挑战者x51的原型的介绍见下面文章: 《STC32G单片机RTOS任务切换的“替代法”介绍》 (4)产品级移植版与玩家版最大的差别在于RTOS系统的可靠性。一个移植版要实现产品级的可靠性,移植前的顶层设计(通常是对很多选项进行反复地权衡和精心地选择)和移植时对底层代码的反复考量以及移植后对整个系统进行严苛的测试这三个部分缺一不可。 (5)笔者计划以系列文章的形式,逐步介绍如何将一个玩家版的可靠性改造提升到产品级的移植版。本文是系列文章的第一篇,介绍对于关闭单片机总中断(EA)的RTOS临界区保护方法的选择和对替代法软中断程序的修改。 二、关闭单片机总中断(EA)的RTOS临界区保护方法 (6)由于STC32G/F系列单片机(没有开放TRAP指令)和STC8单片机的CPU架构不像其他CPU架构有可屏蔽/不可屏蔽中断、硬件/软件中断等各种中断类型,要想对用户程序中的中断进行统一控制,只有关闭总中断(EA=0)和打开总中断(EA=1)一种方法。 由于临界区保护是决定单片机RTOS系统可靠性的最基本和最重要的方法,笔者在论坛中专门开贴与网友交流,这里就不再讨论了,感兴趣的网友可以查看下列文章: 《STC单片机uC/OS-II移植记(5):临界区保护方法研究 》 《关于STC单片机RTOS中的临界区保护问题 》 《STC-RTOS vs STC-DOS:再论临界区保护方法》
(7)挑战者x51的原型的临界区保护方法3,笔者认为一是不完美:在一个函数内无法多次嵌套,二是理念不同:对于多任务的程序,如果在临界区中任务被切换,则配对的临界区退出功能就会被“挂起”,这会导致无法预料的情况发生,导致整个RTOS系统的可靠性下降。 因此本次挑战者x51移植版的临界区保护选择方法9,具体的程序介绍见下文中的方法: 《uC/OS-II移植记(9):微山x51-uCOSII中的可嵌套临界区保护方法》
三、替代法“软中断”的临界区保护方法 (8)一般的单片机或者计算机的RTOS都用专门的“软中断指令”来实现任务的切换。这些软中断指令(比如INT n和TRAP等指令)具有3个鲜明的特点:一是不可屏蔽,也就是说通常的关闭全部中断的指令对它不起作用,即使关闭了全部可被关闭的中断,这种软中断指令可以立即执行,产生一个软中断。二是中断优先级高,一般仅次于不可屏蔽的硬中断和CPU异常内部软中断,因此一旦软中断开始执行,在中断指令(RETI)发布前,不会被其他用户中断打断。三是当软中断指令用于任务切换时,前面两个特点导致了整个任务切换过程连续执行不被打断,相当于任务切换过程处于“指令级的临界区保护之中”。 (9)挑战者x51的原型的替代法“软中断”程序分三个部分,由于替代法使用的是STC32G单片机的硬中断,不具备上面提到的真正软中断指令的3个特点,因此存在两个可靠性方面的隐患。前两部分程序见下图: (10)上面程序的第97行到第111行是第一部分,是将当前任务的寄存器现场保存到系统堆栈中。这部分程序没有任何保护措施,由于进入这个硬中断时总中断是打开的(EA=1),因此这部分程序在执行过程中有可能被其他中断(系统中断或者用户中断)打断,进行其他处理。由于RTOS只是一个系统平台,无法预料用户的中断程序会做什么事,所以存在可靠性隐患。 (11)上面程序的第116行到第131行是第二部分,是除了调用任务切换钩子函数外,将决定正在运行的任务是哪个任务的两个变量从“当前任务”改变为“任务优先级最高的任务”,完成了任务切换的第一步切换系统指标变量。 在挑战者x51的原型中这个部分用关闭总中断的方法进行了临界区保护。由于前面的第一部分允许其他中断的发生,因此第116行到第123行的临界区进入保护代码考虑了总中断被其他中断的ISR程序关闭的可能,采取了嵌套保护方法。
(12)第三部分的程序如下: 其中第134行到第149行时第三部分程序,从系统堆栈中恢复寄存器现场。 这个部分存在严重的可靠性隐患。如果在第三部分程序执行中产生其他中断,并且如果这其他中断导致新的最高优先级任务诞生(比如一个更高优先级任务的休眠期到了,或者被中断唤醒就绪),然后在返回这个第三部分之前进行任务切换,就将导致严重的后果。
(13)借鉴前面指出的软中断指令具有的3个鲜明特点,本文挑战者x51移植版采用一个简单的方法克服原型中的那两个可靠性隐患,具体程序如下: 在任务切换“软中断”的第一行程序执行关闭中断的指令。由于中断ISR的第一条指令肯定会被执行,所以对于STC32G单片机第100行程序会将所有中断关闭,整个任务切换程序将会连续第执行到最后一行才打开中断,使得这个替代法的硬中断模拟了真正的“软中断指令”,对整个任务切换程序实现了最高级别的临界区保护措施。 四、范例程序简介 (14)本文的范例的多任务程序采用了下文介绍的测试2程序,测试的结果也与下文一样,这里就不再一一做介绍了: 《惊天大BUG之三:关闭总中断的临界区保护方法测试》 本文范例程序:
|