完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
首先我把我有疑问的这段代码挑选出来,然后选出里面有疑问的代码:
OS_CPU_PendSVHandler ;xPSR, PC, LR, R12, R0-R3 已自动保存 CPSID I ;任务切换期间需要关中断 MRS R0, PSP ;R0 = PSP ;如果PSP == 0,跳到OS_CPU_PendSVHandler_nosave 执行 #1 CBZ R0, OS_CPU_PendSVHandler_nosave ;保存R4-R11 到任务堆栈 SUBS R0, R0, #0x20 ;R0 -= 0x20 STM R0, {R4-R11} ;保存 R4-R11到任务堆栈 ;OSTCBCur->OSTCBStkPtr = SP; LDR R1, =OSTCBCur ;R1 = &OSTCBCur LDR R1, [R1] ;R1 = *R1 (R1 = OSTCBCur) STR R0, [R1] ;*R1 = R0 (*OSTCBCur = SP) #2 OS_CPU_PendSVHandler_nosave ;调用OSTaskSwHook() USH {R14} ;保存R14,因为后面要调用函数 LDR R0, =OSTaskSwHook ;R0 = &OSTaskSwHook BLX R0 ;调用OSTaskSwHook() POP {R14} ;恢复 R14 ;OSPrioCur = OSPrioHighRdy; LDR R0, =OSPrioCur ;R0 = &OSPrioCur LDR R1, =OSPrioHighRdy ;R1 = &OSPrioHighRdy LDRB R2, [R1] ;R2 = *R1 (R2 = OSPrioHighRdy) STRB R2, [R0] ;*R0 = R2 (OSPrioCur = OSPrioHighRdy) ;OSTCBCur = OSTCBHighRdy; LDR R0, =OSTCBCur ;R0 = &OSTCBCur LDR R1, =OSTCBHighRdy ;R1 = &OSTCBHighRdy LDR R2, [R1] ;R2 = *R1 (R2 = OSTCBHighRdy) STR R2, [R0] ;*R0 = R2 (OSTCBCur = OSTCBHighRdy) LDR R0, [R2] ;R0 = *R2 (R0 = OSTCBHighRdy), 此时 R0是新任 的 SP ;SP = OSTCBHighRdy->OSTCBStkPtr #3 LDM R0, {R4-R11} ;从任务堆栈SP恢复R4-R11 ADDS R0, R0, #0x20 ;R0 += 0x20 MSR SP, R0 SP = R0,用新任务的 SP加载PSP ORR LR, LR, #0x04 ;确保 LR 位2 为 1,返回后使用进程堆栈 #4 CPSIE I ;开中断 BX LR ;中断返回 END 然后下面这些是我的不解之处,希望能有人帮忙解答出来: 移植ucosii 所遇到的疑问: 1、在任务调度函数中void OS_Sched (void)有这么两行代码: void OS_Sched (void){ 。。。。。。。。。。。//省略 if (OSPrioHighRdy != OSPrioCur) { OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; 。。。。。。。。。。。。//省略 } 为什么只要判断就绪的最高优先级任务不是当前任务就可以了呢?UCOS不是可剥夺型的内核嘛?应该是就绪任务表中的最高优先级任务小于或者说优先级高于当前任务,就进行任务切换嘛? 2、在os_cpu_a.asm文件中的PendSV 中断处理函数OS_CPU_PendSVHandler里面有这么一段话: ;保存R4-R11 到任务堆栈 SUBS R0, R0, #0x20 ;R0 -= 0x20 //有疑问的地方 //为什么要先让R0=R0-20? STM R0, {R4-R11} ;保存 R4-R11到任务堆栈 ;OSTCBCur->OSTCBStkPtr = SP; LDR R1, =OSTCBCur ;R1 = &OSTCBCur LDR R1, [R1] ;R1 = *R1 (R1 = OSTCBCur) STR R0, [R1] ;*R1 = R0 (*OSTCBCur = SP) #2 (加颜色为有疑问的地方。)为什么要先让R0=R0-20? 3、在os_cpu_a.asm文件中的PendSV 中断处理函数OS_CPU_PendSVHandler的最后几句代码里面有这么一条代码: ORR LR, LR, #0x04 ;确保 LR 位2 为 1,返回后使用进程堆栈 #4 为什么在这里要确保LR的位2为1? 有人这么解释的“因为在中断处理函数中使用的是 MSP,所以在返回任务后必须使用PSP,所以LR位2 必须为 1。”但是如果这么样的话,我又有疑问了,是使用MSP还是PSP不是由CONTROL[1]决定的嘛? |
|
相关推荐
12个回答
|
|
SUBS R0, R0, #0x20 ;R0 -= 0x20 //有疑问的地方
//为什么要先让R0=R0-20? 解答: 因为0x20=32,所以R0=R0-32,相当于向后移动一个单元(一个字长)。 这个是我后来突然想到的,如果不对,求指正。。。 |
|
|
|
对于疑问1,我突然想出来了:
其实不用做比较的原因不是其他的函数做了这个工作,是因为连当前运行的任务也在整个就绪任务表中,就绪的任务变为运行态以后,并没用把他从就绪表中删除,所以就绪任务表中最高就绪优先级的任务只用两种情况一种是比当前运行态的任务优先级高的任务进入了就绪态,一个就是当前运行的任务。就绪的任务只有当调用OSTaskDel()或者OSTaskSuspend()以后,才会从就绪表中删除。 呵呵,想了好久才想到这个原因,不知道对不对?如果不正确,请指正。 看着自己在这里提的问,半天没人回答,是不是因为提的太笨了点呢?呵呵... |
|
|
|
|
|
|
|
回复【4楼】发烧友:
-------------------------------- 呵呵,这个我看过了,就是因为在看的过程中,对一些代码有疑问,所以才发帖的,不过还是十分感激你的回复,呵呵 对于疑问3,我现在也找到相关资料,在< |
|
|
|
看看邵贝贝的书第三章任务调度,这里是为了避免对当前任务进行没要的任务调度,很有研究代码的精神。
|
|
|
|
顶,邵贝贝那可是权威啊!呵呵!
|
|
|
|
|
|
|
|
我也遇到过这样类似的问题
|
|
|
|
非常感谢!正在找的资料!
|
|
|
|
我也是初学ucos,我的理解是这样的
问题1: ucos-ii是可剥夺内核,始终最先运行优先级最高的任务,除非中断或者自动放弃CPU控制权,所以在任务切换时只要当前任务不是最高优先级,就会做任务切换。 问题2: CM3是向下满栈的,也就是向下增长的,每入栈一字节之前,SP减1;这里需要入栈R4~R11共8个32位寄存器的值,也就是32个字节,所以自减32也即是0x20 问题3: ucosii 不区分特权级和用户级,程序始终工作在特权级;MSP、PSP两个堆栈指针的切换是全自动的,就在出入异常服务例程时由硬件处理。MSP是异常处理来用,PSP任务程序来用,所以返回时需要切换到PSP |
|
|
|
谢谢楼主,我也对疑问3疑惑不解,看到你这个终于找到了答案!
|
|
|
|
CORTEX-M3内核权威手册中讲到了,在进入中断时, LR的用法将被重新解释,其值也被更新成一种特殊的值,称为“EXC_RETURN”,
并且在异常返回时使用。 EXC_RETURN的二进制值除了最低4位外全为1,而其最低4位则有另外的含义,可以参考表9.3 EXC_RETURN位段详解,图片咋发啊,自己查看下内核权威手册吧 |
|
|
|
只有小组成员才能发言,加入小组>>
709 浏览 0 评论
1116 浏览 1 评论
2494 浏览 5 评论
2833 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2675 浏览 6 评论
使用eim外接fpga可是端口一点反应都没有有没有大哥指点一下啊
661浏览 9评论
672浏览 7评论
请教大神怎样去解决iMX6Q在linux3.0.35内核上做AP失败的问题呢
789浏览 6评论
634浏览 5评论
679浏览 5评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 09:26 , Processed in 1.280877 second(s), Total 102, Slave 83 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号