从0到1教你写UCOS-III 第十一部分:支持多优先级

       在本章之前, OS 还没有到优先级,只支持两个任务互相切换,从本章开始, 任务中我们开始加入优先级的功能。在 uC/OS-III 中,数字优先级越小,逻辑优先级越高。


11.1 定义优先级相关全局变量:

       在支持任务多优先级的时候,需要在 os.h 头文件添加两个优先级相关的全局变量,具体定义见代码清单 11-1。
代码清单 11-1 定义优先级相关全局变量

/* 在 os.h 中定义 */
/* 当前优先级 */
OS_EXT OS_PRIO OSPrioCur;
/* 最高优先级 */
OS_EXT OS_PRIO OSPrioHighRdy;

11.2 修改 OSInit()函数:

        刚刚新添加的优先级相关的全部变量,需要在 OSInit()函数中进行初始化,具体见代码清单 11-2 ,其实 OS 中定义的所有的全局变量都是在 OSInit()中初始化的。
代码清单 11-2 OSInit()函数
 

void OSInit (OS_ERR *p_err)
{
/* 配置 OS 初始状态为停止态 */
OSRunning = OS_STATE_OS_STOPPED;
/* 初始化两个全局 TCB,这两个 TCB 用于任务切换 */
OSTCBCurPtr = (OS_TCB *)0;
OSTCBHighRdyPtr = (OS_TCB *)0;
/* 初始化优先级变量 */
OSPrioCur = (OS_PRIO)0;
OSPrioHighRdy = (OS_PRIO)0;
/* 初始化优先级表 */
OS_PrioInit();
/* 初始化就绪列表 */
OS_RdyListInit();
/* 初始化空闲任务 */
OS_IdleTaskInit(p_err);
if (*p_err != OS_ERR_NONE) {
return;
}
}

11.3 修改任务控制块 TCB:

       在任务控制块中,加入优先级字段 Prio,具体见代码清单 11-3 。优先级Prio 的数据类型为 OS_PRIO,宏展开后是 8 位的整型,所以只支持 255 个优先级。
代码清单 11-3 在 TCB 中加入优先级
 

struct os_tcb {
CPU_STK *StkPtr;
CPU_STK_SIZE StkSize;
/* 任务延时周期个数 */
OS_TICK TaskDelayTicks;
/* 任务优先级 */
OS_PRIO Prio;
/* 就绪列表双向链表的下一个指针 */
OS_TCB *NextPtr;
/* 就绪列表双向链表的前一个指针 */
OS_TCB *PrevPtr;
};

11.4 修改 OSTaskCreate()函数:

       修改 OSTaskCreate()函数,在里面加入优先级相关的处理,具体见代码清单 11-4 。
代码清单 11-4 OSTaskCreate()函数 加入优先级处理
 

void OSTaskCreate (OS_TCB *p_tcb,
OS_TASK_PTR p_task,
void *p_arg,
OS_PRIO prio,                       (1)
CPU_STK *p_stk_base,
CPU_STK_SIZE stk_size,
OS_ERR *p_err)
{
CPU_STK *p_sp;
CPU_SR_ALLOC();                     (2)
/* 初始化 TCB 为默认值 */
OS_TaskInitTCB(p_tcb);              (3)
/* 初始化堆栈 */
p_sp = OSTaskStkInit( p_task,
p_arg,
p_stk_base,
stk_size );
p_tcb->Prio = prio;                (4)
p_tcb->StkPtr = p_sp;
p_tcb->StkSize = stk_size;
/* 进入临界段 */ 
OS_CRITICAL_ENTER();               (5)
/* 将任务添加到就绪列表 */           (6)
OS_PrioInsert(p_tcb->Prio);
OS_RdyListInsertTail(p_tcb);
/* 退出临界段 */
OS_CRITICAL_EXIT();                (7)
*p_err = OS_ERR_NONE;
}

       代码清单 11-4(1): 在函数形参中,加入优先级字段。任务的优先级由用户在创建任务的时候通过形参 Prio 传进来。
       代码清单 11-4(2): 定义一个局部变量,用来存 CPU 关中断前的中断状态,因为接下来将任务添加到就绪列表这段代码属于临界短代码,需要关中断。
       代码清单 11-4(3): 初始 化 TCB 为默认值,其实就是全部初始化为 0,OS_TaskInitTCB()函数在 os_task.c 的开头定义,具体见代码清单 11-5。
代码清单 11-5 OS_TaskInitTCB()函数

void OS_TaskInitTCB (OS_TCB *p_tcb)
{
p_tcb->StkPtr = (CPU_STK *)0;
p_tcb->StkSize = (CPU_STK_SIZE )0u;
p_tcb->TaskDelayTicks = (OS_TICK )0u;
p_tcb->Prio = (OS_PRIO )OS_PRIO_INIT; (1)
p_tcb->NextPtr = (OS_TCB *)0;
p_tcb->PrevPtr = (OS_TCB *)0;
}

       代码清单 11-5 (1): OS_PRIO_INIT 是任务 TCB 初始化的时候给的默认的一个优先级 , 宏 展 开 等 于 OS_CFG_PRIO_MAX , 这 是 一 个 不 会 被 OS 使 用 到 的 优 先 级 。OS_PRIO_INIT 具体在 os.h 中定义。
       代码清单 11-4&

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值