Hi,恭喜顺利进入该章节!

如果说前面只是通过简单的两个任务来演示RTOS的核心工作过程;那么从这节课就开始,我们就开始设计功能完善的RTOS。请注意,在接下来的课时中,需要你具备良好的数据结构知识。如果不具备,也不用太担心,因为课程中会介绍,但是要求你付出比较多的时间和精力。

主要内容

本课程中引入了临界区的概述,然后针对临界区提出了开/关中断地保护方法。
之所以要引入,是因为内核很多代码和数据可以直接被任意任务共享,为了避免读写冲突,所以要借助这种方法加以隔离。这种方法是最简单但有效的方法。也许你还有其它的方法。

重点难点

注意事项

在同学问到:在进入临界区后,如果有调用tTaskSwitch()/tTaskSched()会不会立即任务切换;如果不立即切换,是不是这次切换就丢失了?
实际上,在tTaskSwitch()只是设置了PendSVC挂起。如果当前中断被关闭,这个挂起请求不会丢失,其会在中断开启时立即响应。所以,不存在上述所说的问题。

应用实例

临界区保护 - 图1
A:模拟器是这样设计的,实际硬件设调试时也是这样。执行单步操作,内核并不会跑到中断去执行。不过软件触发异常会立即响应。

退出临界区后为什么直接进入 SysTick中断了?

Q:退出临界区后 为什么下一步会直接就进入 SysTick中断了? 按理说应该是在退出临界区后 执行下一步的代码 然后到了中断的时间10ms 才会中断的吧 但是我调试结果 一步一步走 发现 退出临界区后 瞬间就进入了中断 这是为什么?
A:中间有个for循环,里面时间较长,应该是在执行这中间的代码时候,产生了定时中断请求。不过由于进入临界区,中断被屏蔽了,所以中断暂时无法响应。等后面退出时,一开中断,系统就可以响应中断,进入sysTick。
注意,不管有没有响应中断。systick都是一直在计数的。它是一个自动减1的计数器,减到0后会自动加载最大的值,再继续减。那这样的话 会出现下面的情况:把中断开启后 此时去响应中断了 但是此时计数器的值不是从新开始递减计数的
很可能计数器的值已经 减到了一半 那么此时就不是标准的10ms 响应一次中断了
所以,临界区中的代码,应当尽可能的短小。如果你的应用中,需要保护的代码执行时间长,那么就得用信号量之类的保护机制。

get_PRIMASK()/disable_IRQ()的含义

Q:get_PRIMASK()的含义是什么
A:
get_PRIMASK(),即获取当前全局中断是否开启。__disable_IRQ()指关闭全局中断。这是Cortex-M内核指令的调用,具体请看其源码实现和内核数据手册。或者baidu下