cortex求助uC/OS-II任务调度函数PendSV_Handler

BloomW 2013-03-15 07:57:07
加精
/*********************************************************************************************************
** Function name: PendSV_Handler
** Descriptions: uC/OS-II任务调度函数
** input parameters: none
** output parameters: none
** Returned value: none
** Created by: chenmingji
** Created Date: 2009-07-24
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
__asm void PendSV_Handler(void)
{
IMPORT __GuiOsEnterSum
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTaskSwHook

preserve8

CPSID I /*ban interrupt*/
PUSH {R4-R7} ; 问题1:为何进任务调度异常就直接压栈了(SP指向哪?),那样压进的是不是系统栈?
MOV R0,R8 ; 我们的目的是要把原来任务的现场压进任务自己所有的栈啊???
MOV R1,R9
MOV R2,R10
MOV R3,R11
PUSH {R0-R3}

MOV R4,LR ; 问题2:LR中存的返回地址应该是被打断的原来的任务啊?而最后用BX LR岂不是又跳回去了???
BL OSTaskSwHook
MOV LR,R4


LDR R1, =__GuiOsEnterSum
LDR R0, [R1]
PUSH {R0}

LDR R2, =OSTCBCur /*save stk pointer in OSTCBCur->OSTCBStkPtr*/
LDR R2, [R2]
MOV R0,SP
STR R0, [R2]

LDR R4, =OSPrioCur /*change the OSPrioCur to OSPrioHighRdy*/
LDR R5, =OSPrioHighRdy
LDRB R6, [R5]
STRB R6, [R4]

LDR R6, =OSTCBHighRdy /* change the OSTCBCur to OSTCBHighRdy*/
LDR R6, [R6]
LDR R4, =OSTCBCur
STR R6, [R4]

LDR R0, [R6] /* get the OSTCBHighRdy->OSTCBStkPtr */
MOV SP,R0
POP {R0}
STR R0, [R1] /* R0 = __GuiOsEnterSum*/ ;不太理解__GuiOsEnterSum在任务切换时的作用。

CMP R0, #0
BNE OUT
CPSIE I /* enable interrupt*/
OUT /* label*/
POP {R0-R3}
MOV R8,R0
MOV R9,R1
MOV R10,R2
MOV R11,R3
POP {R4-R7}

BX LR

}

...全文
2833 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
天马影帝 2013-04-30
  • 打赏
  • 举报
回复
引用 1 楼 BloomW 的回复:
回去看了下《权威指南》,根据理解,我自己来解答这个问题吧!大家有什么见解可以讨论交流。 __asm void PendSV_Handler(void) /*由于用户没有对控制寄存器CONTROL进行设置SP类型,系统与用户程序默认公用一个MSP*/ { IMPORT __GuiOsEnterSum /*声明全局变量*/ IMPORT OSTCBCur IMPORT OSTCBHighRdy IMPORT OSPrioCur IMPORT OSPrioHighRdy IMPORT OSTaskSwHook preserve8 CPSID I /*ban interrupt*/ /*任务切换目的1:保存旧任务现场*/ /*由于进入异常前,硬件自动把被打断任务的8个特殊的寄存器压入栈中,下面只需要手动压入通用寄存器*/ PUSH {R4-R7} /*进入异常后,将使用一直是用MSP*/ MOV R0,R8 MOV R1,R9 MOV R2,R10 MOV R3,R11 PUSH {R0-R3} MOV R4,LR /*LR在进入异常的时候被重新解释,在进入handler前,他的值被更新成EXC_RETURN,他的值不同,决定不同含义,详见《权威指南》*/ BL OSTaskSwHook MOV LR,R4 LDR R1, =__GuiOsEnterSum LDR R0, [R1] PUSH {R0} LDR R2, =OSTCBCur /*save stk pointer in OSTCBCur->OSTCBStkPtr*/ LDR R2, [R2] MOV R0,SP STR R0, [R2] LDR R4, =OSPrioCur /*change the OSPrioCur to OSPrioHighRdy*/ LDR R5, =OSPrioHighRdy LDRB R6, [R5] STRB R6, [R4] LDR R6, =OSTCBHighRdy /* change the OSTCBCur to OSTCBHighRdy*/ LDR R6, [R6] LDR R4, =OSTCBCur STR R6, [R4] LDR R0, [R6] /* get the OSTCBHighRdy->OSTCBStkPtr */ MOV SP,R0 POP {R0} STR R0, [R1] /* R0 = __GuiOsEnterSum*/ CMP R0, #0 BNE OUT CPSIE I /* enable interrupt*/ OUT /*任务切换目的2:切换新任务现场*/ POP {R0-R3} /*用新任务的SP把几个通用寄存器出栈,同时SP更新,为接下来硬件自动出栈返回做准备*/ MOV R8,R0 MOV R9,R1 MOV R10,R2 MOV R11,R3 POP {R4-R7} BX LR /*LR在进入中断时被更新成了EXC_RETURN,把这个值写入PC意味着中断返回,并不是回到LR所指向的地址, 返回的地址PC值硬件自动压入了栈中,系统收到这个返回指令后自动把之前压入栈的寄存器pop出(出栈时继续延用新任务的SP),并按顺序赋给相应的寄存器,包括PC(从而实现跳转),*/ }
楼主您好,我的ucosii中可能也是这个原因导致的HardFault_Handler,但是我的PendSV_Handler是系统默认的汇编写的,搞不太清楚,您可以教教我吗?谢谢您了QQ506127336
further_away 2013-03-26
  • 打赏
  • 举报
回复
看下Cortex-M3权威 就晓得了
u010041491 2013-03-26
  • 打赏
  • 举报
回复
真的很不错 不错
秀男 2013-03-26
  • 打赏
  • 举报
回复
真的很不错 不错
a82931599 2013-03-22
  • 打赏
  • 举报
回复
真的很不错 不错
guo359981 2013-03-21
  • 打赏
  • 举报
回复
获国家
jieg3000 2013-03-20
  • 打赏
  • 举报
回复
very good!!!!
张三丰 2013-03-20
  • 打赏
  • 举报
回复
继续关注 顶起
C834791363 2013-03-20
  • 打赏
  • 举报
回复
不错真的很不错
BloomW 2013-03-16
  • 打赏
  • 举报
回复
回去看了下《权威指南》,根据理解,我自己来解答这个问题吧!大家有什么见解可以讨论交流。 __asm void PendSV_Handler(void) /*由于用户没有对控制寄存器CONTROL进行设置SP类型,系统与用户程序默认公用一个MSP*/ { IMPORT __GuiOsEnterSum /*声明全局变量*/ IMPORT OSTCBCur IMPORT OSTCBHighRdy IMPORT OSPrioCur IMPORT OSPrioHighRdy IMPORT OSTaskSwHook preserve8 CPSID I /*ban interrupt*/ /*任务切换目的1:保存旧任务现场*/ /*由于进入异常前,硬件自动把被打断任务的8个特殊的寄存器压入栈中,下面只需要手动压入通用寄存器*/ PUSH {R4-R7} /*进入异常后,将使用一直是用MSP*/ MOV R0,R8 MOV R1,R9 MOV R2,R10 MOV R3,R11 PUSH {R0-R3} MOV R4,LR /*LR在进入异常的时候被重新解释,在进入handler前,他的值被更新成EXC_RETURN,他的值不同,决定不同含义,详见《权威指南》*/ BL OSTaskSwHook MOV LR,R4 LDR R1, =__GuiOsEnterSum LDR R0, [R1] PUSH {R0} LDR R2, =OSTCBCur /*save stk pointer in OSTCBCur->OSTCBStkPtr*/ LDR R2, [R2] MOV R0,SP STR R0, [R2] LDR R4, =OSPrioCur /*change the OSPrioCur to OSPrioHighRdy*/ LDR R5, =OSPrioHighRdy LDRB R6, [R5] STRB R6, [R4] LDR R6, =OSTCBHighRdy /* change the OSTCBCur to OSTCBHighRdy*/ LDR R6, [R6] LDR R4, =OSTCBCur STR R6, [R4] LDR R0, [R6] /* get the OSTCBHighRdy->OSTCBStkPtr */ MOV SP,R0 POP {R0} STR R0, [R1] /* R0 = __GuiOsEnterSum*/ CMP R0, #0 BNE OUT CPSIE I /* enable interrupt*/ OUT /*任务切换目的2:切换新任务现场*/ POP {R0-R3} /*用新任务的SP把几个通用寄存器出栈,同时SP更新,为接下来硬件自动出栈返回做准备*/ MOV R8,R0 MOV R9,R1 MOV R10,R2 MOV R11,R3 POP {R4-R7} BX LR /*LR在进入中断时被更新成了EXC_RETURN,把这个值写入PC意味着中断返回,并不是回到LR所指向的地址, 返回的地址PC值硬件自动压入了栈中,系统收到这个返回指令后自动把之前压入栈的寄存器pop出(出栈时继续延用新任务的SP),并按顺序赋给相应的寄存器,包括PC(从而实现跳转),*/ }

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧