ucos OS_SchedNew函数
来源:互联网 发布:深度解读淘宝运营pdf 编辑:程序博客网 时间:2024/04/30 03:01
说明:这个函数由ucos的其他服务调用,用来决定即将运行的优先级最高的任务。它改变全局变量OSPrioHighRdy。 参数:无 返回值:无 注意: 这个函数是内部函数,外部应用无法调用。 这个函数被调用时,中断被假定为关闭。 INT8U y; y = OSUnMapTbl[OSRdyGrp]; // OSUnMapTbl可以理解为一个解码表 OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]); //OSReadyTbl的大小为【OS_LOWEST_PRIO/8+1】 OS_PRIO *ptbl; //任务数大于64时 *ptbl是指向16位数的指针 if ((OSRdyGrp & 0xFFu) != 0u) //有任务优先级低于64的函数就绪时那高于64的就不要计算了,算了最高优先级也不是它 { y = OSUnMapTbl[OSRdyGrp & 0xFFu];//数字后面加u表示无符号整形 } y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u; } ptbl = &OSRdyTbl[y]; //OSReadyTbl的大小为【OS_LOWEST_PRIO/16+1】与任务数小于64时不同 if ((*ptbl & 0xFFu) != 0u) { OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]); } else { OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u); } 1.任务数小于64的情况 先明确几个变量的作用 1.(u8)OSRdyGrp:每一个bit代表一个组,一共8组,每组管理8个任务(具体哪一个记录在OSRdyTbl中)。 2.(u8)OSPrioHighRdy:格式与OS_PRIO相同,记录当前最高优先级任务的优先级。 3.(u8)OS_PRIO:来自 EVENT CONTROL BLOCK(事件控制块)用来记录任务优先级,与优先级一对一关系。 4.(u8)OSReadyTbl:就绪表啦!按bit排就是下面的样子。 OSRdyGrp|=OSMapTbl[OS_PRIO>>3] //记录组就绪标志 //OS_PRIO的yyy有2^3种取法,记录组号TBL[yyy](就绪表第几行) OSRdyTbl[prio>>3]|= OSMapTbl[OS_PRIO&0x07] //在TBL[yyy]上记录列就绪标志(在就绪表中写就绪标志) //OS_PRIO&0x07就是XXX。OSMapTbl[OS_PRIO&0x07]把XXX转换为位掩码 OSMapTbl数组如下 OSMapTbl[8]={00000001,00000010,00000100,00001000,00010000,00100000,01000000,10000000} 这个数组就是把XXX或YYY转换为上面格式,用来给OSRdyGrp,TBL[yyy]的特定bit置1。 OS_SchedNew的作用就是依靠0SRdyGrp和OSRdyTbl计算出就绪任务的最高优先级,解码方法如下。 y = OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]); 用OSUnMapTbl[OSRdyGrp]确定最高就绪组Y。OSRdyGrp比如最高就绪组是0组,那么OSRdyGrp的可能是00000001,00000011,00000101,00001001......11111111.一共2^7种。我们通过判断置1的最小就绪位是0位就可以知道最高就绪组为0组。计算机(人视觉的并行处理比计算机强多了)也要一位一位判断。先看第零位是不是1,是就是第零组,不是判断第2位。那前几位还好说,后面几位的计算量是相当大的。不想算干脆用个已经算好的答案来映射吧。OSUnMapTbl就是这样一个对答案数组(有效减少计算量)。
OSUnMapTbl[OSRdyGrp]的值计算好后保存在Y中,OSRdyTbl[y]记录的就是最高就绪组中的就绪情况。OSUnMapTbl[OSRdyTbl[y]]用答案表算出这组中最高就绪任务X。(y << 3u)这个就是他在第几组,一组8个任务,Y<<3相当于Y*8 OSPrioHighRdy就等于Y*8+X 2.任务数大于64的情况
任务数大于64时任务就绪表就是16*16=256( OSRdyGrp和OSRdyTbl是16位的),可以管理256个任务了。 if ((OSRdyGrp & 0xFFu) != 0u) //判断优先级前64位的任务是否就绪。 { y = OSUnMapTbl[OSRdyGrp & 0xFFu];} // 前128(8*16)个任务最高就绪级的计算方法和情况一是一样的但是OSPrioHighRdy格式不是00YYYXXX 而是YYYYXXXX 2^4*2^4=256 else { y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u;} // OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] 计算后八组加8就是表示前八组都没有就绪。(一共16组)因为还是八组一起判断的所以 OSUnMapTbl可以通用。 ptbl = &OSRdyTbl[y]; //这里用个指针来代替 OSRdyTbl[y]应该有助于提高计算速度 if ((*ptbl & 0xFFu) != 0u) {OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]);} else {OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u);} OSUnMapTbl[(*ptbl & 0xFFu)])X的前8位就绪 OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u)X的后八位就绪要加8 (y << 4u) 就是Y*16 OSPrioHighRdy就等于Y*16+X
//新版本提供了对256个任务的支持,由 OS_SchedNew函数计算出优先级再交给OS_Sched使用。
//书上的版本是没有这个函数的。
static void OS_SchedNew (void)
{
#if OS_LOWEST_PRIO <= 63u //根据任务数是否大于64采取不同的计算方案
#else //任务数大于64时计算优先级的方法 INT8U y;
else
{
#endif
}
补上详细的计算方法:
0 0
- ucos OS_SchedNew函数
- uCOS-II函数解析
- ucos函数简析
- uCOS-II函数解析
- UCOS 任务函数
- ucos 任务延时函数
- UCOS中的OSStatInit()函数
- uCOS-II 常用函数参考手册
- uCOS OSTaskCreate()函数分析
- ucos-ii OSTaskSuspend函数分析
- ucos-ii 之OSTaskDel函数
- ucos-ii 之OSTaskDelReq函数
- UCOS中断函数的编写
- UCOS中断函数的编写
- uCOS-II 常用函数参考手册
- uCOS-II任务延时函数
- ucos II 任务延时函数
- Ucos II 任务延时函数
- printk()函数的总结
- 强大的Core Image
- Redmine:自动预览附件图片
- 数据总线, 地址总线, 控制总线详解.
- 解决:dubbo找不到dubbo.xsd报错
- ucos OS_SchedNew函数
- ios 简单滤镜效果
- Linux下mysql数据库的导入导出操作
- UIImageView 的contentMode属性应用
- Android 内存优化之OOM
- mutex and condition_variable[c++11]
- OpenCV:Mat元素访问方法、性能
- iOS性能优化---转载《二》小心别让圆角成了你列表的帧数杀手
- Java学习第8天(2):面向对象-继承-子父类关系