RTOS笔记1

2015-04-27 17:17

什么是多任务:

通过频繁的任务切换来保证在一段时间内,每个任务都能得到合适的运行时间。在任务调度器中,可以通过标志任务的重要性,使有实时要求的任务得以优先运行。

任务的切换:保存现场(将SP指向任务的私有堆栈,并压入CPU的重要寄存器)后,修改SP指针,通过RET或者RETI指令将预先保存好的指令地址弹到PC寄存器,从而改变程序运行的地址。​

1.任务在运行时,SP一直指向私有栈,所以在切入调度器时,运行地址已经被自动压入堆栈。如果是中断程序,还会自动保存CPU现场。

2.在Main函数完成系统初始化后,需要有一个空闲任务(Task0)来占领CPU的空闲时间。​

3.任务的切换有两种调度器——中断调度(主要是时间片调度)和程序调度(强行调度)

系统有两条任务队列:普通任务队列(TaskQueue)和优先任务队列(TaskQueue_Pri)

当有优先任务存在时,​会一直运行优先队列里的任务。所以在删除任务(包括任务进入延时或者等待消息)的时候,如果队列为空了,必须要第一时间修改系统标志位。在Trim后,不必修改。

系统标识结构体内容:

uchar TaskID;          //当前任务号

uchar SystemState;       //系统运行状态标志 on off

uchar NewTaskID;        //新任务号

uchar TimeBlock;       //任务运行时间片寄存器

uchar SchLock;      //调度器锁

uchar IntNesting;    //中断嵌套状态

uchar SystemMode;     //系统运行模式

uchar SystemPri;   //优先运行状态

任务标志结构体内容:

uchar TaskSP;       //任务栈顶地址

uint TaskDelay;       //任务延时寄存器

bit TaskPri;         //标志一个任务是目前否是优先任务​

uchar TaskState;    //任务状态标志 run stop delay

uchar TaskLastState;   //任务被挂起前的状态

任务切换过程:

1.到点(任务运行状态、时间等因素),进入临界状态。

2.检查系统是否存在优先队列(SystemPri)。

3.从相应的队列中取出任务(GetTaskID),这个函数会自动Trim队列以保持队列的完整性。被取出的新任务号放入系统​标志结构体中的NewTaskID,准备进入切换过程。到此为止任务切换已经进入必然,不可能撤销了。

4.​将当前的现场压入堆栈(在中断调度器中就不需要了,已经被系统自动压栈了)。完成后将目前的SP地址保存在任务标志结构体中的TaskSP中等待下次调用。

5.​修改系统标志结构体,正式将NewTaskID放入TaskID中,NewTaskID清零。

6.​在新任务的标志结构体中读取TaskSP地址,并将上一次保存好的现场弹出到各个寄存器。

7.通过RET或RETI结束调度进入新的程序地址。​

在一个任务中使用调度函数,在调度函数结束后会自动进入新任务而不是原来的断点,原任务的内容在调度函数内会进行妥善保存。

任务注册的过程:

1.​任务具有唯一性,每个任务只能单独运行一个线程。

2.根据任务的需求,在结构体内设置其优先级​

​任务延时:

1.任务调用延时函数

2.进入延时函数后,系统进入临界状态。在临界状态下,保存当前的现场。

3.将延时的时间存入任务控制块的TaskDelay,并改变任务的运行状态为Delay状态。

4.调用调度器函数调入新任务,被延时的任务则不需要加入就绪任务队列。

如果任务数量很多,可以另外建立一个延时任务队列。

猜你喜欢

转载自blog.csdn.net/laoponline/article/details/111050559
今日推荐