【RTOS知识点】RTOS相关知识点(更新中)

一、什么是任务? 

  在裸机系统中,系统的主体就是 main 函数里面顺序执行的无限循环,这个无限循环里
面 CPU 按照顺序完成各种事情。在多任务系统中,我们根据功能的不同,把整个系统分割
成一个个独立的且无法返回的函数,这个函数我们称为任务。具体代码如下: 
void task_entry (void *parg)
{
/* 任务主体,无限循环且不能返回 */
  for (;;)
 {
/* 任务主体代码 */
 }
}

二、操作模式以及特权级别

1、操作模式:处理者模式(handler mode,以后不再把 handler 中译——译注)和线程模式(thread mode)。引入两个模式的本意,是用于区别异常服务例程的代码——包括中断服务例程的代码,普通应用程序的代码。

2、特权级别:特权级和用户级,主要是提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。

合法的操作流程如下图:(如果看不懂可以参考CM3权威指南)

 三、Cortex-M3 的双堆栈机制

1、堆栈指针:

主堆栈指针(MSP),或写作SP_main。这是缺省的堆栈指针,它由OS内核、异常服务例程以及所有需要特权访问的应用程序代码来使用。
进程堆栈指针(PSP),或写作SP_process。用于常规的应用程序代码(不处于异常服用例程中时)。

2、当 CONTROL[1]=0 时,只使用 MSP ,此时用户程序和异常 handler 共享同一个堆栈。

3、当 CONTROL[1]=1 时,线程模式将不再使用 MSP ,而改用 PSP handler 模式永远使用 MSP)。 进入异常时的自动压栈使用的是进程堆栈,进入异常 handler 后才自动改为 MSP,退出异常时切换回PSP,并且从进程堆栈上弹出数据。

四、异常返回

当异常服务例程执行完毕后,需要很正式地做一个“异常返回”动作序列,从而恢复先前的系 统状态,才能使被中断的程序得以继续执行。从形式上看,有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所示。

五、什么是临界段

临界段用一句话概括就是一段在执行的时候不能被中断的代码段。在 FreeRTOS 里面,这个临界段最常出现的就是对全局变量的操作。那么什么情况下临界段会被打断?一个是系统调度,还有一个就是外部中断。在FreeRTOS,系统调度,最终也是产生 PendSV中断,在 PendSV Handler 里面实现任务的切换,所以还是可以归结为中断。既然这样,FreeRTOS对临界段的保护最终还是回到对中断的开和关的控制。
为了快速地开关中断, Cortex-M 内核专门设置了一条 CPS 指令,有 4 种用法。
1 CPSID I ;PRIMASK=1 ;关中断
2 CPSIE I ;PRIMASK=0 ;开中断
3 CPSID F ;FAULTMASK=1 ;关异常
4 CPSIE F ;FAULTMASK=0 ;开异常
PRIMASK FAULTMAST Cortex-M内核 里面三个中断屏蔽寄存 器中的两个,还有一个是 BASEPRI。在 FreeRTOS中,对中断的开和关是通过操作 BASEPRI 寄存器来实现的,即大
于等于 BASEPRI 的值的中断会被屏蔽,小于 BASEPRI 的值的中断则不会被屏蔽,不受FreeRTOS 管理。

六、空闲任务和阻塞延时

空闲任务:空闲任务是系统在【启动调度器】的时候创建的优先级最低的任务,空闲任 务主体主要是做一些系统内存的清理工作。当任务需要延时,进入阻塞状态,那 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 的值,然后进行任务切换。

九、时间片

FreeRTOS 与隔壁的 RT-Thread μC/OS 一样,都支持时间片的功能。所谓时间片就
是同一个优先级下可以有多个任务,每个任务轮流地享有相同的 CPU 时间,享有 CPU
时间我们叫时间片。在 RTOS 中,最小的时间单位为一个 tick ,即 SysTick 的中断周期,
RT-Thread μC/OS 可以指定时间片的大小为多个 tick ,但是 FreeRTOS 不一样,时间片只
能是一个 tick 。与其说 FreeRTOS 支持时间片,倒不如说它的时间片就是正常的任务调度。

猜你喜欢

转载自blog.csdn.net/qq_29031103/article/details/120772034
今日推荐