代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断。为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完毕后,要立即开中断。
由于Cortex-M3/M4的RTX内核库中没有关闭中断的操作,也就是说RTX的源码中不存在临界段。如果源码中有临界段的话,会给系统带来什么问题呢?比如此时某个任务正在调用系统API函数,而且此时中断正好关闭了,也就是进入到了临界区中,这个时候如果有一个紧急的中断事件被触发,这个中断就不能得到及时执行,必须等到中断开启才可以得到执行,如果关中断时间超过了紧急中断能够容忍的限度,危害是可想而知的。像uCOS-II,uCOS-III和FreeRTOS的源码中都是有临界段的。
除了上面说的操作系统源码所带的临界段以外,用户写应用的时候也有临界段的问题,比如以下两种:
u 读取或者修改变量(特别是任务间通信的全局变量)的代码,一般来说这是最常见的临界代码。
u 调用公共函数的代码,特别是不可重入的函数,如果多个任务都访问这个函数,结果是可想而知的。
总之,对于临界段要做到执行时间越短越好,要不会影响系统的实时性。
简单的说,为了防止当前任务的执行被其它高优先级的任务打断而提供的锁机制就是任务锁。实现任务锁可以通过给调度器加锁或者直接关闭RTOS内核定时器(就是前面一直说的系统滴答定时器)来实现。
u 通过给调度器加锁实现
给调度器加锁的话,就无法实现任务切换,高优先级任务也就无法抢占低优先级任务的执行,同时高优先级任务也是无法向低优先级任务切换的。像uCOS-II和uCOS-III是采用的这 种方法实现任务锁。特别注意,这种方式只是禁止了调度器工作,并没有关闭任何中断。
u 通过关闭RTOS内核定时器实现
关闭了RTOS内核定时器的话,也就关闭了通过RTOS内核定时器中断实现任务切换的功能,因为在退出定时器中断时需要检测当前需要执行的最高优先级任务,如果有高优先级任务就绪的话需要做任务切换。RTX操作系统是采用的这种方式实现任务锁的。
u Task Configuration
l Number of concurrent running tasks
允许创建4个任务,实际创建了如下四个任务
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :消息处理,这里是用作LED闪烁和串口打印任务正在运行。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。
l Number of tasks with user-provided stack
创建的4个任务都是采用自定义堆栈方式。
u Task Configuration
l Number of concurrent running tasks
允许创建4个任务,实际创建了如下四个任务
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :消息处理,这里是用作LED闪烁和串口打印任务正在运行。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。
l Number of tasks with user-provided stack
创建的4个任务都是采用自定义堆栈方式。