OS是如何运转起来的?(一般情况下,不考虑系统的一些配置被修改).

1.系统变量常量配置
在程序的最开头,先定义你需要的任务的堆栈大小,优先级,此时CPU已经将系统的一些变量,常量储存于实际物理地址了(例如任务堆栈)
#define .....
...
2.运行到OSInit();
首先是一个主函数,CPU运行第一个函数OSInit();在这里,CPU初始化一些系统变量的值,例如一些任务记数器等.
然后创建两个基本的任务:空闲任务(CPU闲置时就连续运行此任务),统计任务(统计空闲任务,以便计算CPU的使用率).
void Main(void)
{
  OSInit();
  BSP_Iint();//初始化宿主系统 
  OSTaskCreate(Main_Task, (void *)0, (OS_STK *)&Main_Stack[TASK_STACK_SIZE-1], Main_PRIO);
  OSStart();
}

      
3. 建立空闲任务的过程

3.1 OSTaskStkInit(任务堆栈初始化函数)

  根据任务函数入口,传递的参数,栈顶,选择项,4个参数决定物理栈顶指针,这个栈里还有其他参数,比如PC值,这些参数都保存在这个物理栈里,在任务开始运行时,将这些值取出,而当任务因为某种原因中断了,则保存这些值,这样下次就能从中断的那个状态再次运行这个任务.
初始化堆栈,从栈顶依次压入,任务函数入口,各个寄存器,这样恢复任务的时候先恢复各个寄存器,最后才将任务函数入口压入PC,从而运行任务

3.2 OSTCBInit (初始化一个任务控制块)

  将各个参数填入这个控制块,并且生成一个双向任务链表,每次初始化的任务控制块将会添加入链表的左端,这个双向链表在时钟节拍中会用到.
最后在就绪表里将此任务对应的位置一,表示这个任务已经就绪了.

3.3 如果以上都成功了,则任务记数器+1. 接下来会检查OSRunning,如果它为0,说明系统还未运行,这样空闲任务就建立了,等待OSStart 函数开始运行系统,如果OSRunning 为1,说明系统已经运行,这样就执行一次任务调度,任务调度的作用是,如果刚刚建立的任务优先级最高,就运行这个任务. 以下分析任务调度函数

3.4 OSSched(任务调度函数)

   如果任务调度的条件成立,则将就绪表里优先级最高的任务赋予OSPrioHighRdy(等待运行里优先级最高的任务)(这个地方有个疑问:在这个地方运行完后,OSPrioHighRdy和OSPrioRdy会变成什么) 如果这个最高优先级的任务还没运行,那么任务切换计数器+1,执行OS_TASK_SW 任务切换函数. 接下来解析任务切换函数功能

3.5 OS_TASK_SW(任务切换函数)

   保存处理器的值,将当前任务的堆栈指针保存到当前任务的OS_TCB , OSTCBCur , OSPrioCur 赋予最高优先级任务,堆栈指针赋予最高优先级任务指针,将堆栈中的内容恢复,执行中断返回指令,这样就运行了最高优先级任务了,这里就是空闲任务.
3.6 OSTickISR (时钟节拍函数)

  时钟一到,保存寄存器值,当前的堆栈指针SP赋予OSTCBCur.OSTCBStkPtr,调用OSTimeTick()
OSTimeTick 节拍服务函数
  将每个TCB中的.OSTCBDly-1,如果OSTCBDly为0了,任务原先也没有被挂起,就将任务置为就绪态,如果原先被挂起,就先将OSTCBDly为1.

posted on 2011-04-08 20:33  深蓝工作室  阅读(1222)  评论(0编辑  收藏  举报