理解uC/OS的任务切换和任务就绪表、就绪组

uC/OS的任务切换

1、每个任务都创建了一个任务运行的堆栈,每次任务切换时找到就绪的优先级最高的任务,将堆栈指针指向该任务,然后就恢复该任务对CPU的占有。

2、uC/OS的任务切换分为两种:

一种是非中断情况下,当任务被阻塞、创建、删除时,需要调用任务切换函数OS_Schedule,保存运行的上下文(运行地址和CPU寄存器),压到堆栈里面去。需要注意的是,因为当前还在被换出的任务中运行,因此该任务返回后将执行任务切换的最后一句(实际上就是我们在调用函数时的情况一样,函数运行变量的进栈和出栈),然后返回恢复任务运行地址。

一种是中断处理的任务切换函数,中断产生后,会自动将一部分寄存器值压入到堆栈,不需要去保存环境。直接将堆栈指针指向优先级最高的任务堆栈的栈顶,然后依次弹出各CPU寄存器的值到CPU寄存器进行环境恢复,最后弹出任务地址和任务参数,转到任务地址去运行。

任务就绪表、就绪组

这两张查找表表示的是查找的优先级任务最高就绪,用空间换时间的方法实现的。这里在uC/OS管理了64个任务,在版本2.82以后扩展至255个任务。

就绪组是一个无符号字符类型,就绪表是无符号字符数组类型,大小为8。是通过结合就绪表和就绪组字符的位来实现对优先级的查找。

1、根据任务优先级来给就绪组和就绪表赋值

如优先级23=8*2+7,23/8相当于表示在哪个就绪组的哪个位置置1,这里是第二组,所以用OSRdyGrp|=OSMapTbl[prio>>3],这里的或操作就是通过查询OSMapTbl给就绪组置1。OSMapTbl[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}映射表。

同时用OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07]给就绪表赋值,这里是prio&0x07是相当于取余的操作,比如这里的23取余的操作是7。后面的操作和上类似。

2、根据就绪组和就绪表来找到最低优先级任务赋值

y=OSUnMapTbl[OSRdyGrp];本来可能有几个任务就绪了,要找到最低的优先级就绪组需要计算,这里是通过查表的方式来实现的,比如之前我们的OSRdyGrp的值为10000100这里第八位最高位为1是因为必须有空闲任务一直运行,而第三位为1是之前我们优先级23的赋值,这个值换成十进制为132,通过查表OSUnMapTbl得到为2。

如果不查表的话,调用这样一个函数:

INTU8 fun(INTU8 n)

{

INTU8  count=0,

while(n!=0)

{

count++;

if(n&1==1)

{

return count;

}

n<<=1;

}

}

count就是就绪组最低位,计算的方式浪费时间。

同时OSPrioHighRdy=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]]),这里的跟上面也是同样的道理查找就绪表里面位最低的优先级,再和之前组里查找的数相加就得到最低或准备好的优先级的任务了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值