版主
- 积分
- 11922
- 金钱
- 11922
- 注册时间
- 2015-11-5
- 在线时间
- 2086 小时
|
发表于 2016-10-2 21:23:50
|
显示全部楼层
本帖最后由 FreeRTOS 于 2016-10-2 21:26 编辑
查了下权威指南,先放上CLZ的定义吧
再放上一个例子:
如果我的理解没错的话,CLZ指令是计算某个字节从左边数起的0的个数,遇到非零位就终止
我看了下UCOS-III的源码,跟任务切换相关的找到下面这个函数:
[mw_shl_code=applescript,true]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) { /* Search the bitmap table for the highest priority */
prio += DEF_INT_CPU_NBR_BITS; /* Compute the step of each CPU_DATA entry */
p_tbl++;
}
prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); /* Find the position of the first bit set at the entry */
return (prio);
}[/mw_shl_code]
先说明下,我没研究过UCOS-III的源码,如有错误的地方请指出哈。
按照我以前对UCOS-II的内核的理解,UCOS有一个任务就绪表,并且这个表每个字节都被对应的任务独占
UCOS在任务切换时会查询这个表是否有任务就绪,按照上面的代码应该就是在查找到已就绪的更高优先级的任务后调用了CPU_CntLeadZeros
来计算前导0的个数,我不知道统计这个对内核有何意义,不过可以肯定的告诉你freertos没有用这条指令,并且内核跟UCOS完全不一样,获取
高优先级的就绪任务时的方式也完全不一样,换句话说吧freertos并不需要计算前导0,因为对内核没啥用
这里提供下UCOS-III的PendSV中断手动切换任务的汇编代码
[mw_shl_code=applescript,true]PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20
MSR PSP, R0 ; Load PSP with new process SP
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
CPSIE I
BX LR ; Exception return will restore remaining context[/mw_shl_code]
这部分代码跟freertos没太大差别,其实嵌入式操作系统的任务切换原理也基本一致的,也就是利用中断来修改中断返回地址以实现一个人为可控的跳转
个人认为这部分代码也不能完全体现一个系统内核调度,因为在这部分汇编代码里也会调用C函数来执行任务切换的工作,个人认为没多大可比性
最后一点,如果单独从一条汇编指令来断定某个系统的任务调度的快慢,那未免太肤浅了吧。。。
之前有数据对比过,freertos的任务调度速度是比UCOS快一点的,因为freertos内核比较简单,并不像UCOS那么复杂,当然内核越复杂功能和稳定性
也就越强,这也是为何从来没有人质疑过UCOS的地位。
个人愚见,并没有任何冒犯的意思,希望有机会可以多交流,呵呵!
|
|