uC/OS-II源码解析(os_task.c)
2017-05-11 16:06
369 查看
/* ** ver: 2.52 ** file: os_task.c ** brief: 任务相关操作 C 文件 */ #ifndef OS_MASTER_FILE #include "includes.h" /* 包含头文件 */ #endif /* *************************************************************************** * 改变任务优先级 * * brief : 该函数用来改变任务优先级 * * oldprio : 旧的任务优先级 * * newprio : 新的任务优先级 * * Returns : OS_NO_ERR 优先级修改成功 * OS_PRIO_INVALID 无效优先级 * OS_PRIO_EXIST 优先级已经存在 * OS_PRIO_ERR 不存在优先级对应的任务 **************************************************************************** */ #if OS_TASK_CHANGE_PRIO_EN > 0 INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif #if OS_EVENT_EN > 0 OS_EVENT *pevent; #endif OS_TCB *ptcb; INT8U x; INT8U y; INT8U bitx; INT8U bity; #if OS_ARG_CHK_EN > 0 /* 参数检查 */ if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF) || newprio >= OS_LOWEST_PRIO) { /* 优先级检查 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { OS_EXIT_CRITICAL(); /* 已经存在 newprio 优先级的任务 */ return (OS_PRIO_EXIST); } else { OSTCBPrioTbl[newprio] = (OS_TCB *)1;/* 占用 OSTCBPrioTbl[newprio] */ OS_EXIT_CRITICAL(); y = newprio >> 3; /* 预运算 */ bity = OSMapTbl[y]; x = newprio & 0x07; bitx = OSMapTbl[x]; OS_ENTER_CRITICAL(); if (oldprio == OS_PRIO_SELF) { /* 是否改变自身优先级 */ oldprio = OSTCBCur->OSTCBPrio; /* 改变自身优先级 */ } ptcb = OSTCBPrioTbl[oldprio]; if (ptcb != (OS_TCB *)0) { /* 任务存在 */ OSTCBPrioTbl[oldprio] = (OS_TCB *)0;/* 移除 TCB */ if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /* 如果任务是就绪,则清除 */ if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { OSRdyGrp &= ~ptcb->OSTCBBitY; } OSRdyGrp |= bity; /* 使优先级任务进入就绪 */ OSRdyTbl[y] |= bitx; #if OS_EVENT_EN > 0 } else { pevent = ptcb->OSTCBEventPtr; if (pevent != (OS_EVENT *)0) {/* 任务正在等待事件发生 */ /* 清除等待任务 */ if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { pevent->OSEventGrp &= ~ptcb->OSTCBBitY; } pevent->OSEventGrp |= bity;/* 使新优先级任务等待 */ pevent->OSEventTbl[y] |= bitx; } #endif } OSTCBPrioTbl[newprio] = ptcb; /* 把任务控制块给新优先级任务 */ ptcb->OSTCBPrio = newprio; /* 初始化任务控制块 */ ptcb->OSTCBY = y; ptcb->OSTCBX = x; ptcb->OSTCBBitY = bity; ptcb->OSTCBBitX = bitx; OS_EXIT_CRITICAL(); OS_Sched(); /* 任务调度 */ return (OS_NO_ERR); } else { /* 任务不存在 */ OSTCBPrioTbl[newprio] = (OS_TCB *)0;/* 释放 OSTCBPrioTbl[newprio] */ OS_EXIT_CRITICAL(); return (OS_PRIO_ERR); } } } #endif /*$PAGE*/ /* **************************************************************************** * 创建一个任务 * * brief : 创建任务,不能在 ISR 中调用 * * task : 指向任务函数的指针 * * pdata : 传递给任务的参数 * * ptos : 堆栈栈顶指针 * * prio : 任务优先级 * * returns : OS_NO_ERR 创建任务成功 * OS_PRIO_EXIT 任务已经存在 * OS_PRIO_INVALID 无效优先级 ***************************************************************************** */ #if OS_TASK_CREATE_EN > 0 INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif OS_STK *psp; INT8U err; #if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO) { /* 检查优先级有效性 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* 检查优先级唯一性 */ OSTCBPrioTbl[prio] = (OS_TCB *)1; /* 占用 OSTCBPrioTbl[prio] */ OS_EXIT_CRITICAL(); /* 初始化任务堆栈 */ psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* 初始化任务控制块 */ err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++; /* 任务数加 1 */ OS_EXIT_CRITICAL(); if (OSRunning == TRUE) { /* 任务调度 */ OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0;/* 释放 OSTCBPrioTbl[prio] */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); } #endif /*$PAGE*/ /* ********************************************************************************* * 创建一个任务 * * brief : 创建任务,类似于函数 OSTaskCreate(),对其进行了扩展 * * task : 指向任务函数的指针 * * pdata : 传递给任务的参数 * * ptos : 堆栈栈顶指针 * * prio : 任务优先级 * * id : 任务 ID * * pbos : 堆栈栈底指针 * * stk_size : 对栈大小 * * pext : TCB 扩展数据结构指针 * * opt : 选择项. * OS_TASK_OPT_STK_CHK 堆栈检查 * OS_TASK_OPT_STK_CLR 堆栈清 0 * OS_TASK_OPT_SAVE_FP 保存浮点寄存器 * * * returns : OS_NO_ERR 创建任务成功 * OS_PRIO_EXIT 任务已经存在 * OS_PRIO_INVALID 无效优先级 ******************************************************************************** */ /*$PAGE*/ #if OS_TASK_CREATE_EXT_EN > 0 INT8U OSTaskCreateExt (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio, INT16U id, OS_STK *pbos, INT32U stk_size, void *pext, INT16U opt) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif OS_STK *psp; INT8U err; #if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO) { /* 检查优先级有效性 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* 检查优先级唯一性 */ OSTCBPrioTbl[prio] = (OS_TCB *)1; /* 占用 OSTCBPrioTbl[prio] */ OS_EXIT_CRITICAL(); if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) || /* 堆栈检查 */ ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) { /* 堆栈清 0 */ #if OS_STK_GROWTH == 1 (void)memset(pbos, 0, stk_size * sizeof(OS_STK)); #else (void)memset(ptos, 0, stk_size * sizeof(OS_STK)); #endif } /* 堆栈初始化 */ psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* 任务控制块初始化 */ err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++; /* 任务数加 1 */ OS_EXIT_CRITICAL(); if (OSRunning == TRUE) { /* 任务调度 */ OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0; /* 释放 占用 OSTCBPrioTbl[prio] */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); } #endif /*$PAGE*/ /* ********************************************************************************** * 删除一个任务 * * bried: 删除任务,通过重新创建可以再次激活任务 * * prio : 任务优先级 * * returns : OS_NO_ERR 成功 * OS_TASK_DEL_IDLE 不允许删除空闲任务 * OS_PRIO_INVALID 无效优先级 * OS_TASK_DEL_ERR 任务不存在 * OS_TASK_DEL_ISR 不能中断中删除任务 * ********************************************************************************** */ /*$PAGE*/ #if OS_TASK_DEL_EN > 0 INT8U OSTaskDel (INT8U prio) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif #if OS_EVENT_EN > 0 OS_EVENT *pevent; #endif #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) OS_FLAG_NODE *pnode; #endif OS_TCB *ptcb; BOOLEAN self; if (OSIntNesting > 0) { /* 不能在中断中删除任务 */ return (OS_TASK_DEL_ISR); } #if OS_ARG_CHK_EN > 0 if (prio == OS_IDLE_PRIO) { /* 不允许删除空闲任务 */ return (OS_TASK_DEL_IDLE); } if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {/* 检查优先级有效性 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* 删除自己 */ prio = OSTCBCur->OSTCBPrio; /* 获取优先级 */ } ptcb = OSTCBPrioTbl[prio]; if (ptcb != (OS_TCB *)0) { /* 任务必须存在 */ if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* 取消任务就绪 */ OSRdyGrp &= ~ptcb->OSTCBBitY; } #if OS_EVENT_EN > 0 pevent = ptcb->OSTCBEventPtr; if (pevent != (OS_EVENT *)0) {/* 任务正在等待事件 */ if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { pevent->OSEventGrp &= ~ptcb->OSTCBBitY;/* 取消等待事件 */ } } #endif #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) pnode = ptcb->OSTCBFlagNode; if (pnode != (OS_FLAG_NODE *)0) {/* 任务等待时间标志组 */ OS_FlagUnlink(pnode); /* 取消等待时间标志组 */ } #endif ptcb->OSTCBDly = 0; /* 防止开中断后 OSTimeTick()又将任务就绪 */ ptcb->OSTCBStat = OS_STAT_RDY; /* 防止其他任务ISR调用 OSTaskResume()使任务运行 */ if (OSLockNesting < 255) { /* 禁止任务调度 */ OSLockNesting++; } OS_EXIT_CRITICAL(); /* 开中断,以缩短中断响应 */ OS_Dummy(); /* 确保中断被打开过 */ OS_ENTER_CRITICAL(); /* 关中断 */ if (OSLockNesting > 0) { /* 运行任务调度 */ OSLockNesting--; } OSTaskDelHook(ptcb); /* 调用用户自定义钩子函数 */ OSTaskCtr--; /* 任务数减 1 */ OSTCBPrioTbl[prio] = (OS_TCB *)0;/* 从优先级表中去除 任务控制块 */ if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* 移除待删除任务的任务控制块 */ ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; OSTCBList = ptcb->OSTCBNext; } else { ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; } ptcb->OSTCBNext = OSTCBFreeList; /* 任务控制块还给空链表 */ OSTCBFreeList = ptcb; OS_EXIT_CRITICAL(); OS_Sched(); /* 任务调度 */ return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_TASK_DEL_ERR); } #endif /*$PAGE*/ /* ************************************************************************************** * 请求删除任务 * * brief : 这个函数被用来 : * a) 任务A 通知任务B 删除任务B 就是老子不会杀你,你自杀的意思 * b) 任务B 查看是否有其他任务删除自己,注意 我要自杀了 * 是不是有点小懵逼. 简单的说就是, 你想删除一个任务 * 然而,这个任务占用一些资源 (内存缓冲区,信号量, 邮 * 箱, 队列 等等). 因此这个任务不能被删除,否则会导致 * 存储器漏洞,这就需要使用 OSTaskDelReq() 去通知到被 * 删除的任务,让其释放资源后删除自己,例如, 任务 #10 * 需要被删除. 任务#5将调用OSTaskDelReq(10),任务#10 * 调用OSTaskDelReq(OS_PRIO_SELF)查询是否有其他任务要 * 删除自己,如果返回 OS_TASK_DEL_REQ, 则任务 #10 完 * 成删除自己的动作 * * void Task_#10(void *data) * { * . * . * while (1) { * OSTimeDly(1); * if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) { * 释放资源; * 释放内存; * OSTaskDel(OS_PRIO_SELF); * } * } * } * * prio : 优先级 * * Returns : OS_NO_ERR 成功 * OS_TASK_NOT_EXIST 任务不存在 * OS_TASK_DEL_IDLE 不允许删除空闲任务 * OS_PRIO_INVALID 优先级无效 * OS_TASK_DEL_REQ 发出任务删除请求 ************************************************************************************* /*$PAGE*/ #if OS_TASK_DEL_EN > 0 INT8U OSTaskDelReq (INT8U prio) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif BOOLEAN stat; INT8U err; OS_TCB *ptcb; #if OS_ARG_CHK_EN > 0 if (prio == OS_IDLE_PRIO) { /* 不允许删除空闲任务 */ return (OS_TASK_DEL_IDLE); } if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {/* 检查任务优先级优先级 */ return (OS_PRIO_INVALID); } #endif if (prio == OS_PRIO_SELF) { /* 删除自己 */ OS_ENTER_CRITICAL(); stat = OSTCBCur->OSTCBDelReq; /* 返回是否需要删除自己 */ OS_EXIT_CRITICAL(); return (stat); } OS_ENTER_CRITICAL(); ptcb = OSTCBPrioTbl[prio]; /* 获取任务控制块 */ if (ptcb != (OS_TCB *)0) { /* 任务必须存存在 */ ptcb->OSTCBDelReq = OS_TASK_DEL_REQ; /* 设置删除任务请求 */ err = OS_NO_ERR; } else { err = OS_TASK_NOT_EXIST; /* 任务不存在 */ } OS_EXIT_CRITICAL(); return (err); } #endif /*$PAGE*/ /* *********************************************************************************** * 恢复挂起的任务 * * brief : 恢复被挂起的任务 * * prio : 任务优先级 * * returns : OS_NO_ERR 成功 * OS_PRIO_INVALID 无效优先级 * OS_TASK_RESUME_PRIO 任务不存在 * OS_TASK_NOT_SUSPENDED 任务没有被挂起 *********************************************************************************** */ #if OS_TASK_SUSPEND_EN > 0 INT8U OSTaskResume (INT8U prio) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; #if OS_ARG_CHK_EN > 0 if (prio >= OS_LOWEST_PRIO) { /* 检查优先级的有效性 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* 检查任务是否存在 */ OS_EXIT_CRITICAL(); return (OS_TASK_RESUME_PRIO); } if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) {/* 任务被挂起 */ if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* 取消挂起状态 */ (ptcb->OSTCBDly == 0)) { /* 不能有延时 */ OSRdyGrp |= ptcb->OSTCBBitY; /* 使任务就绪 */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); OS_Sched(); /* 任务调度 */ } else { OS_EXIT_CRITICAL(); } return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_TASK_NOT_SUSPENDED); } #endif /*$PAGE*/ /* ********************************************************************************** * 堆栈检测 * * brief : 该函数用于检测任务的堆栈使用情况 * * prio : 任务优先级 * * pdata : 保存堆栈使用情况的数据结构指针 * * returns : OS_NO_ERR 成功 * OS_PRIO_INVALID 无效优先级 * OS_TASK_NOT_EXIST 任务不存在 * OS_TASK_OPT_ERR 选项错误 *********************************************************************************** */ #if OS_TASK_CREATE_EXT_EN > 0 INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *pdata) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; OS_STK *pchk; INT32U free; INT32U size; #if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* 检查优先级有效性 */ return (OS_PRIO_INVALID); } #endif pdata->OSFree = 0; /* 初始化局部变量 */ pdata->OSUsed = 0; OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* 是否检测自身堆栈 */ prio = OSTCBCur->OSTCBPrio; } ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* 任务不存在 */ OS_EXIT_CRITICAL(); return (OS_TASK_NOT_EXIST); } if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* 检查 OPT 的有效性 */ OS_EXIT_CRITICAL(); return (OS_TASK_OPT_ERR); } free = 0; size = ptcb->OSTCBStkSize; pchk = ptcb->OSTCBStkBottom; OS_EXIT_CRITICAL(); #if OS_STK_GROWTH == 1 while (*pchk++ == (OS_STK)0) { /* 计算堆栈中 0 的数量 */ free++; } #else while (*pchk-- == (OS_STK)0) { free++; } #endif pdata->OSFree = free * sizeof(OS_STK); /* 计算剩余字节数 */ pdata->OSUsed = (size - free) * sizeof(OS_STK); /* 计算已使用字节数 */ return (OS_NO_ERR); } #endif /*$PAGE*/ /* *********************************************************************************** * 挂起任务 * * breif: 该函数用于挂起一个任务,可以使其他任务或者自身 * * prio : 待挂起任务优先级. 如果等于 OS_PRIO_SELF,则挂起自身并进行任务调度 * * returns : OS_NO_ERR 成功 * OS_TASK_SUSPEND_IDLE 不允许挂起空闲任务 * OS_PRIO_INVALID 无效优先级 * OS_TASK_SUSPEND_PRIO 任务不存在 ********************************************************************************** */ #if OS_TASK_SUSPEND_EN > 0 INT8U OSTaskSuspend (INT8U prio) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif BOOLEAN self; OS_TCB *ptcb; #if OS_ARG_CHK_EN > 0 if (prio == OS_IDLE_PRIO) { /* 不允许挂起空闲任务 */ return (OS_TASK_SUSPEND_IDLE); } if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* 检查优先级有效性 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* 挂起自身 */ prio = OSTCBCur->OSTCBPrio; self = TRUE; } else if (prio == OSTCBCur->OSTCBPrio) { /* 挂起自身 */ self = TRUE; } else { self = FALSE; /* 非自身挂起 */ } ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* 待挂起任务不存在 */ OS_EXIT_CRITICAL(); return (OS_TASK_SUSPEND_PRIO); } if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* 清除就绪表相应位 */ OSRdyGrp &= ~ptcb->OSTCBBitY; } ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* 状态设置为挂起态 */ OS_EXIT_CRITICAL(); if (self == TRUE) { /* 任务调度 */ OS_Sched(); } return (OS_NO_ERR); } #endif /*$PAGE*/ /* ************************************************************************************ * 查询任务 * * brief: 查询一个任务的状态 * * prio : 待查询任务优先级 * * Returns : OS_NO_ERR 成功 * OS_PRIO_INVALID 无效优先级 * OS_PRIO_ERR 错误的优先级 ************************************************************************************ */ #if OS_TASK_QUERY_EN > 0 INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; #if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* 检查优先级有效性 */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* 是否查询自身 */ prio = OSTCBCur->OSTCBPrio; } ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* 任务不存在 */ OS_EXIT_CRITICAL(); return (OS_PRIO_ERR); } memcpy(pdata, ptcb, sizeof(OS_TCB)); /* 复制 TCB 内容 */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); } #endif
相关文章推荐
- uC/OS-II源码解析(os_q.c)
- uC/OS-II源码解析(os_cfg.h)
- uC/OS-II源码解析(os_mutex.c)
- uC/OS-II源码解析(includes.h)
- uC/OS-II源码解析(os_mbox.c)
- uC/OS-II源码解析(ucos_ii.c)
- uC/OS-II源码解析(os_mem.c)
- uC/OS-II源码解析(os_cpu_c.c)
- uC/OS-II源码解析(os_sem.c)
- uC/OS-II源码解析(os_cpu_a.asm)
- uC/OS-II源码解析(os_time.c)
- uC/OS-II源码解析(os_cpu.h)
- uC/OS-II源码解析(os_core.c)
- uC/OS-II源码分析(二)
- uC/OS-II源码分析(总体思路一)
- 【专题】uC/OS-II内核架构解析(5)---uC/OS-II通信与同步
- 【专题】uC/OS-II内核架构解析(1)---嵌入式RTOS
- 【专题】uC/OS-II内核架构解析(4)---uC/OS-II任务管理
- 【专题】uC/OS-II内核架构解析(3)---uC/OS-II系统核心
- uC/OS-II源码分析(总体思路 三)