UCOS-II移植ARM的读书笔记知识点

UCOS-II移植ARM的读书笔记知识点

内核结构
1临界段,OS_ENTER_CRITICAL和OS_EXIT_CRITICAL
开关中断的实现方法分三种:
1)直接用处理器指令
2)在堆栈中保存中断的开关状态,然后再关中断。
3)通过编译器提供的c函数来保存处理器状态字的值。
2任务
 
3任务状态
睡眠态:在ROM或RAM中,交给UCOS要调用下面两个函数之一:OSTaskCreate或者OSTaskCreateExt,调用之后告诉了UCOS任务的起始地址,优先级,要使用多少栈空间。
就绪态:建立了任务之后,就进入就绪态。如果是由任务建立的新任务且优先级更高,那么新建的任务将立即得到CPU使用权。通过OSTaskDel将一个任务返回到睡眠态。
运行态:调用OSStart可以启动多任务,该函数运行用户初始化代码中已建的优先级最高的任务。
等待态:正在运行的任务通过两个函数将自己延迟即进入等待状态。OSTimeDly或者OSTimeDlyHMSM。这两个函数将会立即执行强制任务切换,让下一个优先级最高且进入就绪态的任务运行。当延时时间到后,系统服务函数OSTimeTick将会让等待的任务进入就绪态。在运行中的任务如果调用OSFlagPend、OSSemPend、OSMutexPend、OSMboxPend或者OSQPend时时间并没有发生,那么该任务就进入等待态,此时最高优先级的就绪态任务进入运行态。当等待事件发生或者等待超时,该任务就从等待态进入就绪态。
中断服务态:正在运行的任务可以被中断。被中断了的任务进入中断服务态。响应中断时该任务被挂起,中断服务子程序可能报告多个事件发生,从而使得更高优先级的任务进入就绪态,当中断返回时会重新判断优先级,让最高优先级的任务运行,如果由更高优先级的任务那么先执行,直到被挂起的任务的优先级最高才会返回到被中断挂起的任务。
4任务控制块TCB
当任务建立的时候一个任务控制块TCB就被赋值,任务控制块能确保任务从被中断的那一点丝毫不差的继续运行。OS_TCB全部驻留在RAM中。OS_TCB中包括:指向当前任务堆栈栈顶的指OSTCBStkPtr、指向用户定义的任务控制块扩展OSTCBExtPtr(该扩展数据结构包含任务名字、跟踪某个任务的执行事件、跟踪切换到某个任务的次数)、指向任务堆栈栈底的指针OSTCBStkBottom(如果堆栈指针递减则指向任务使用的栈空间的最低地址)、存有栈中可容纳的指针元数目OSTCBStkSize(是指针元数目,乘以地址宽度即为实际栈容量)、选择项OSTCBOpt(传给OSTaskCreateExt)、用于存储任务的识别码OSTCBId、用于任务控制块双向链表的前后链接OSTCBNext/OSTCBPrev、指向事件控制块的指针OSTCBEventPtr、指向传递给任务的消息的指针OSTCBMsg、指向事件标志节点的指针OSTCBFlagNode、使任务进入就绪态的事件标志OSTCBFlagsRdy、延时或者挂起一段事件时用来计时的变量OSTCBDly、任务的状态字OSTCBStat(OS_STAT_READY-就绪态)、任务的优先级OSTCBPrio、用于加速任务进入就绪态的过程或进入等待事件发生状态的过程OSTCBX/OSTCBY/OSTCBBitX/OSTCBBitY、一个表示该任务是否须删除的布尔量OSTCBDelReq。所有的任务控制块OS_TCB都是放在任务控制块列表数组OSTCBTbl【】中。所有任务控制块OS_TCB都被链接成单向空任务链表。任务一旦建立,空任务控制块指针OSTCBFreeList指向的任务控制块便赋给了该任务。任务建立时,任务建立函数调用任务控制块初始化函数OS_TCBInit。在初始化OS_TCB的时候调用了用户自定义的函数OSTCBInitHook和OSTaskCreateHook函数。两个函数都是扩展作用的。当新建的任务块要插入表中时先要关中断,新任务的控制块总是插在OSTCBList表的开头。
5就绪表
每个就绪的任务都放在就绪表中,就绪表中有2个变量OSRdyGrp和OSRdyTbl【】。OSRdyGrp中任务按优先级分组,8个任务一组,8位表示8组任务中每组是否有进入就绪态的任务。进入就绪态后,就绪表OSRdyTbl【】中相应元素的相应位置1。因此,使任务进入就绪态的程序为:
OSRdyGrp |=OSMapTbl[prio>>3];
OSRdyTbl[prio>>3] |=OSMapTbl[prio & 0x07]; OSMapTbl[]是屏蔽字,将0-7的下标转换成各自位置1的8位值
通过优先级判定表OSUnMapTbl查找任务的优先级,即OSUnMapTbl[OSRdyGrp]×8+OSUnMapTbl[OSRdyTbl[OSUnMapTbl[OSRdyGrp]]]。得到优先级后,查任务控制块优先级表OSTCBPrioTbl【】得到指向相应任务的任务控制块OS_TCB。
6任务调度
任务级的调度是由OSSched完成,中断级的调度是由函数OSIntExt完成的。任务调度函数将找出优先级最高的进入就绪态的任务,检查该任务是否是当前正在运行的任务,如果不是才进行任务调度。为了实现任务的切换将该任务的控制块从任务控制块优先级表中取出并赋给OSTCBHighRdy,将统计切换次数的变量加1来跟踪任务切换次数。最后就可以使用宏调用OS_TASK_SW完成实际上的任务切换
任务切换:将被挂起任务的寄存器推入堆栈再将准备运行的任务的寄存器从栈中恢复到寄存器。因此UCOS运行就绪态任务要做的就是恢复所有的CPU寄存器并运行中断返回指令。这里是一段重点,为了实现任务切换,运行OS_TASK_SW人为模仿了一次中断。在ARM中由软中断指令来实现上述操作。必须给汇编语言函数OSCtxSw提供中断向量。OSCtxSw除了需要OS_TCBHighRdy指向即将被挂起的任务,还需让当前任务控制块OSTCBCur指向即将被挂起的任务。OSCtxSw挂起了正在执行的任务而让CPU执行更重要的任务。
 
7任务级的任务切换OSCtxSw
OSCtxSw是宏调用通常含有软中断指令,切换是靠中断级代码完成的。UCOS将与实际处理器相关的软件中断机制封装起来易于移植。P93-P95详细介绍了整个过程。恩。。大概明白了任务切换的实现方式,为我理解移植工作打下了不小的基础埃。。。