一、什么是任务?
void task_entry (void *parg)
{
/* 任务主体,无限循环且不能返回 */
for (;;)
{
/* 任务主体代码 */
}
}
二、操作模式以及特权级别
1、操作模式:处理者模式(handler mode,以后不再把 handler 中译——译注)和线程模式(thread mode)。引入两个模式的本意,是用于区别异常服务例程的代码——包括中断服务例程的代码,普通应用程序的代码。
2、特权级别:特权级和用户级,主要是提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。
合法的操作流程如下图:(如果看不懂可以参考CM3权威指南)
三、Cortex-M3 的双堆栈机制
1、堆栈指针:
主堆栈指针(MSP),或写作SP_main。这是缺省的堆栈指针,它由OS内核、异常服务例程以及所有需要特权访问的应用程序代码来使用。
进程堆栈指针(PSP),或写作SP_process。用于常规的应用程序代码(不处于异常服用例程中时)。

四、异常返回
当异常服务例程执行完毕后,需要很正式地做一个“异常返回”动作序列,从而恢复先前的系 统状态,才能使被中断的程序得以继续执行。从形式上看,有3种途径可以触发异常返回序列,如 表9.2所示。而不管使用哪一种,都需要用到先前储到LR的EXC_RETURN。
在进入异常服务程序后,将自动更新LR的值为特殊的EXC_RETURN。这是一个高 28位全为1的值,只有[3:0]的值有特殊含义,如表9.3所示。当异常服务例程把这个值送往PC时,就 会启动处理器的中断返回序列。因为LR的值是由CM3自动设置的,所以只要没有特殊需求,就不要 改动它。
如果主程序在线程模式下运行,并且在使用MSP时被中断,则在服务例程中LR=0xFFFF_FFF9(主 程序被打断前的LR已被自动入栈)。 如果主程序在线程模式下运行,并且在使用PSP时被中断,则在服务例程中LR=0xFFFF_FFFD(主程序被打断前的LR已被自动入栈)。
如果主程序在Handler模式下运行,则在服务例程中LR=0xFFFF_FFF1(主程序被打断前的LR已被 自动入栈)。这时的所谓“主程序”,其实更可能是被抢占的服务例程。事实上,在嵌套时,更深 层ISR所看到的LR总是0xFFFF_FFF1,如图9.5所示。
五、什么是临界段
1 CPSID I ;PRIMASK=1 ;关中断
2 CPSIE I ;PRIMASK=0 ;开中断
3 CPSID F ;FAULTMASK=1 ;关异常
4 CPSIE F ;FAULTMASK=0 ;开异常

六、空闲任务和阻塞延时
空闲任务:空闲任务是系统在【启动调度器】的时候创建的优先级最低的任务,空闲任 务主体主要是做一些系统内存的清理工作。当任务需要延时,进入阻塞状态,那 CPU 又去干什么事情了?如果没有其它任务可以 运行,RTOS 都会为CPU创建一个空闲任务,这个时候 CPU 就运行空闲任务。
阻塞延时:即任务需要延时的时候,任务会放弃CPU的使用权,CPU可以去干其它的事情,当任务延时时间到,重新获取CPU使用权,任务继续运行,这样就充分地利用了CPU的资源。
七、任务优先级
就绪列表 pxReadyTasksLists[ configMAX_PRIORITIES ]是一个数组,数组里面存的是就绪任务的 TCB(准确来说是 TCB 里面的 xStateListItem 节点),数组的下标对应任务的 优先级,优先级越低对应的数组下标越小。空闲任务的优先级最低,对应的是下标为 0 的链表。任务在创建的时候,会根据任务的优先级将任务插入到就绪列表不同的位置。相同优先级的任务插入到就绪列表里面的同一条链表中,即时间片的支持。
八、延时列表
在 FreeRTOS 中,有一个任务延时列表(实际上有两个,为了方便讲解原理,我们假装合并为一个,其实两个的作用是一样的),当任务需要延时的时候,则先将任务挂起, 即先将任务从就绪列表删除,然后插入到任务延时列表,同时更新下一个任务的解锁时刻变量:xNextTaskUnblockTime 的值。
xNextTaskUnblockTime 的值等于系统时基计数器的值 xTickCount 加上任务需要延时的值 xTicksToDelay。当系统时基计数器 xTickCount 的值与 xNextTaskUnblockTime 相等时,就表示有任务延时到期了,需要将该任务就绪。
任务延时列表表维护着一条双向链表,每个节点代表了正在延时的任务,节点按照延 时时间大小做升序排列。当每次时基中断(SysTick 中断)来临时,就拿系统时基计数器的 值 xTickCount 与下一个任务的解锁时刻变量 xNextTaskUnblockTime 的值相比较,如果相 等,则表示有任务延时到期,需要将该任务就绪,否则只是单纯地更新系统时基计数器 xTickCount 的值,然后进行任务切换。
九、时间片