uC/OS-III之任务就绪表学习总结
来源:互联网 发布:同轴圆柱形电容器算法 编辑:程序博客网 时间:2024/05/19 07:08
1.任务就绪表包含两部分:一个就绪优先级位映射表OSPrioTbl[],用来标明哪个优先级下有任务就绪;一个就绪任务列表OSRdyList[],其中包含指向各个就绪任务的指针。
2.就绪优先级位映射表OSPrioTbl[]
// 就绪优先级位映射表的大小,由定义在文件os.h的164行#define OS_PRIO_TBL_SIZE (((OS_CFG_PRIO_MAX - 1u) / DEF_INT_CPU_NBR_BITS) + 1u)// 就绪优先级位映射表,定义在文件os_prio.c的40行CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE]; // 以下函数来自于文件os_proc.c,58行-155行void OS_PrioInit (void) // 初始化优先级位映射表{ CPU_DATA i; for (i = 0u; i < OS_PRIO_TBL_SIZE; i++) { OSPrioTbl[i] = (CPU_DATA)0; }}OS_PRIO OS_PrioGetHighest (void) // 查找就绪的最高优先级{ CPU_DATA *p_tbl; OS_PRIO prio; prio = (OS_PRIO)0; p_tbl = &OSPrioTbl[0]; while (*p_tbl == (CPU_DATA)0) { // 查找非零项 prio += DEF_INT_CPU_NBR_BITS; // 计算优先级 p_tbl++; } prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); // 查找第一个不为零的项 return (prio);}void OS_PrioInsert (OS_PRIO prio) // 置位就绪优先级位映射表中对应的优先级位{ CPU_DATA bit; CPU_DATA bit_nbr; OS_PRIO ix; ix = prio / DEF_INT_CPU_NBR_BITS; // 计算优先级在就绪优先级映射表中的表项位置 bit_nbr = (CPU_DATA)prio & (DEF_INT_CPU_NBR_BITS - 1u); // 计算优先级在表项中的偏移位置 bit = 1u; bit <<= (DEF_INT_CPU_NBR_BITS - 1u) - bit_nbr; OSPrioTbl[ix] |= bit;}void OS_PrioRemove (OS_PRIO prio) // 清零就绪优先级位映射表中对应优先级的位{ CPU_DATA bit; CPU_DATA bit_nbr; OS_PRIO ix; ix = prio / DEF_INT_CPU_NBR_BITS; // 计算优先级在就绪优先级映射表中的表项位置 bit_nbr = (CPU_DATA)prio & (DEF_INT_CPU_NBR_BITS - 1u); // 计算优先级在表项中的偏移位置 bit = 1u; bit <<= (DEF_INT_CPU_NBR_BITS - 1u) - bit_nbr; OSPrioTbl[ix] &= ~bit;}
3.就绪任务列表OSRdyList[]
// 就绪表的表项,定义在os.h文件的690行,该表项可以与任务控制块TCB构成双向链表struct os_rdy_list { OS_TCB *HeadPtr; // 指向对应优先级下就绪任务表的头部 OS_TCB *TailPtr; // 指向对应优先级下就绪任务表的尾部 OS_OBJ_QTY NbrEntries; // 对应优先级下就绪任务的数量};// 就绪表的定义位于os.h文件的1116行。每一个表项对应一个优先级,就绪表的索引号就是任务对应的优先级OS_EXT OS_RDY_LIST OSRdyList[OS_CFG_PRIO_MAX];// 以下函数来自于os_core.c文件,1965行-2386行void OS_RdyListInit (void) // 初始化并清空就绪表{ OS_PRIO i; OS_RDY_LIST *p_rdy_list; for (i = 0u; i < OS_CFG_PRIO_MAX; i++) { // 清空就绪表 p_rdy_list = &OSRdyList[i]; p_rdy_list->NbrEntries = (OS_OBJ_QTY)0; p_rdy_list->HeadPtr = (OS_TCB *)0; p_rdy_list->TailPtr = (OS_TCB *)0; }}void OS_RdyListInsert (OS_TCB *p_tcb) // 在就绪表中插入一个任务控制块{ OS_PrioInsert(p_tcb->Prio); // 在优先级位映射表中置位与该任务的优先级对应的位 if (p_tcb->Prio == OSPrioCur) { OS_RdyListInsertTail(p_tcb); // 该任务与当前正在执行的任务处于同一优先级,那么就把它插入到双向链表的尾部 } else { OS_RdyListInsertHead(p_tcb); // 该任务与当前正在执行的任务处于不同优先级,那么就把它插入到双向链表的头部 }}void OS_RdyListInsertHead (OS_TCB *p_tcb) // 在双向链表的头部插入一个任务控制块{ OS_RDY_LIST *p_rdy_list; OS_TCB *p_tcb2; p_rdy_list = &OSRdyList[p_tcb->Prio]; if (p_rdy_list->NbrEntries == (OS_OBJ_QTY)0) { // CASE 0: Insert when there are no entries p_rdy_list->NbrEntries = (OS_OBJ_QTY)1; // This is the first entry p_tcb->NextPtr = (OS_TCB *)0; // No other OS_TCBs in the list p_tcb->PrevPtr = (OS_TCB *)0; p_rdy_list->HeadPtr = p_tcb; // Both list pointers point to this OS_TCB p_rdy_list->TailPtr = p_tcb; } else { // CASE 1: Insert BEFORE the current head of list p_rdy_list->NbrEntries++; // One more OS_TCB in the list p_tcb->NextPtr = p_rdy_list->HeadPtr; // Adjust new OS_TCBs links p_tcb->PrevPtr = (OS_TCB *)0; p_tcb2 = p_rdy_list->HeadPtr; // Adjust old head of list's links p_tcb2->PrevPtr = p_tcb; p_rdy_list->HeadPtr = p_tcb; }}void OS_RdyListInsertTail (OS_TCB *p_tcb) // 在双向链表的尾部插入一个任务控制块{ OS_RDY_LIST *p_rdy_list; OS_TCB *p_tcb2; p_rdy_list = &OSRdyList[p_tcb->Prio]; if (p_rdy_list->NbrEntries == (OS_OBJ_QTY)0) { // CASE 0: Insert when there are no entries p_rdy_list->NbrEntries = (OS_OBJ_QTY)1; // This is the first entry p_tcb->NextPtr = (OS_TCB *)0; // No other OS_TCBs in the list p_tcb->PrevPtr = (OS_TCB *)0; p_rdy_list->HeadPtr = p_tcb; // Both list pointers point to this OS_TCB p_rdy_list->TailPtr = p_tcb; } else { // CASE 1: Insert AFTER the current tail of list p_rdy_list->NbrEntries++; // One more OS_TCB in the list p_tcb->NextPtr = (OS_TCB *)0; // Adjust new OS_TCBs links p_tcb2 = p_rdy_list->TailPtr; p_tcb->PrevPtr = p_tcb2; p_tcb2->NextPtr = p_tcb; // Adjust old tail of list's links p_rdy_list->TailPtr = p_tcb; }}void OS_RdyListMoveHeadToTail (OS_RDY_LIST *p_rdy_list) // 将一个任务控制块TCB从双向链表的头部移到尾部{ OS_TCB *p_tcb1; OS_TCB *p_tcb2; OS_TCB *p_tcb3; switch (p_rdy_list->NbrEntries) { case 0: case 1: break; case 2: /* SWAP the TCBs */ p_tcb1 = p_rdy_list->HeadPtr; /* Point to current head */ p_tcb2 = p_rdy_list->TailPtr; /* Point to current tail */ p_tcb1->PrevPtr = p_tcb2; p_tcb1->NextPtr = (OS_TCB *)0; p_tcb2->PrevPtr = (OS_TCB *)0; p_tcb2->NextPtr = p_tcb1; p_rdy_list->HeadPtr = p_tcb2; p_rdy_list->TailPtr = p_tcb1; break; default: /* Move only if there are more than 2 OS_TCBs in the list */ p_tcb1 = p_rdy_list->HeadPtr; /* Point to current head */ p_tcb2 = p_rdy_list->TailPtr; /* Point to current tail */ p_tcb3 = p_tcb1->NextPtr; /* Point to new list head */ p_tcb3->PrevPtr = (OS_TCB *)0; /* Adjust back link of new list head */ p_tcb1->NextPtr = (OS_TCB *)0; /* Adjust forward link of new list tail */ p_tcb1->PrevPtr = p_tcb2; /* Adjust back link of new list tail */ p_tcb2->NextPtr = p_tcb1; /* Adjust forward link of old list tail */ p_rdy_list->HeadPtr = p_tcb3; /* Adjust new list head and tail pointers */ p_rdy_list->TailPtr = p_tcb1; break; }}void OS_RdyListRemove (OS_TCB *p_tcb) // 将任务控制块TCB从就绪表中删除{ OS_RDY_LIST *p_rdy_list; OS_TCB *p_tcb1; OS_TCB *p_tcb2; p_rdy_list = &OSRdyList[p_tcb->Prio]; p_tcb1 = p_tcb->PrevPtr; /* Point to next and previous OS_TCB in the list */ p_tcb2 = p_tcb->NextPtr; if (p_tcb1 == (OS_TCB *)0) { /* Was the OS_TCB to remove was at the head? */ if (p_tcb2 == (OS_TCB *)0) { /* Yes, was it the only OS_TCB? */ p_rdy_list->NbrEntries = (OS_OBJ_QTY)0; /* Yes, no more entries */ p_rdy_list->HeadPtr = (OS_TCB *)0; p_rdy_list->TailPtr = (OS_TCB *)0; OS_PrioRemove(p_tcb->Prio); } else { p_rdy_list->NbrEntries--; /* No, one less entry */ p_tcb2->PrevPtr = (OS_TCB *)0; /* adjust back link of new list head */ p_rdy_list->HeadPtr = p_tcb2; /* adjust OS_RDY_LIST's new head */ } } else { p_rdy_list->NbrEntries--; /* No, one less entry */ p_tcb1->NextPtr = p_tcb2; if (p_tcb2 == (OS_TCB *)0) { p_rdy_list->TailPtr = p_tcb1; /* Removing the TCB at the tail, adj the tail ptr */ } else { p_tcb2->PrevPtr = p_tcb1; } } p_tcb->PrevPtr = (OS_TCB *)0; p_tcb->NextPtr = (OS_TCB *)0;}
阅读全文
0 0
- uC/OS-III之任务就绪表学习总结
- uc/os-iii学习笔记-任务就绪表
- UC/OS基础知识之任务就绪表
- uC/OS-III之任务切换学习总结
- uC/OS-III之任务调度总结
- uC/OS-III之任务挂起表
- uc/os之任务就绪表操作(一)
- uc/os之任务就绪表操作(二)
- uC/OS-III之学习总结
- uC/OS-II学习笔记(2012.12.11)任务就绪表之如何理解OSUnMapTbl[]
- uC/OS-II 学习笔记之:任务就绪表-举例详解!
- uC/OS II任务就绪表
- uc/os-ii任务就绪表
- UC/OS II 任务管理(2)之就绪表和就绪组
- uc/os-III任务管理总结
- uC/OS-II任务调度之就绪表及最高优先级任务判定算法
- uC/OS-II任务就绪表及任务调度
- uc/os-iii学习笔记-任务挂起表
- 数据库设计三范式
- Scala函数式编程课后习题答案(第六章)
- QT 中文字符乱码
- C#序列化与反序列化
- 郑桂兰董事长再访日月潭文武庙协天庙佛光大学等台湾地标进行文化交流
- uC/OS-III之任务就绪表学习总结
- Python numpy实现二维数组和一维数组拼接
- 端口号类型
- python之读写excel文件
- 郑桂兰董事长与台湾良机集团董事长张广博商务洽谈
- liunx基本命令(一)
- Linux_无法运行可执行文件
- POJ 1679
- Shell脚本中倒计时应用 – echo用法详解