uCOSIII学习笔记之OSCtrSW( )
来源:互联网 发布:java验证码工具类 编辑:程序博客网 时间:2024/06/06 04:52
在PM0056文档中的4.4.3节,介绍了Interrupt control and state register (SCB_ICSR),即:地址为0xE000ED04的寄存器。
位定义如下图所示:
所以:宏OS_TASK_SW() 手工将 NVIC的 PendSV悬起寄存器中写 1。悬起后,在其它的 ISR都完成了处理后,才执行PendSV异常(相关详细内容请看这篇博客)。PendSV异常会自动延迟上下文切换的请求,为实现这个机制,需要把 PendSV设置为最低优先级的异常1。
OS_CPU_PendSVHandler CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack STM R0, {R4-R11} LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP; LDR R1, [R1] STR R0, [R1] ; R0 is SP of process being switched out ; At this point, entire context of process has been savedOS_CPU_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 END
PendSV异常函数在os_cpu_a.s文件中。
(1)&(2) The Cortex-M3 auto-saves half of the processor context on any exception, and restores same on return from exception. So only saving of R4-R11 is required and fixing up the stack pointers. When the processor takes an exception, unless the exception is a tail-chained or a late-arriving exception, the processor pushes information onto the current stack. This operation is referred as stacking and the structure of eight data words is referred as stack frame. The stack frame contains the following information:
- R0-R3, R12
- Return address (PC+4)
- PSR
- LR (R14)
“stack frame”中的内容就是任何异常在执行其异常服务程序之前自动保存到栈(PSP)中的内容。所以在执行PendSV异常服务函数是只用保存寄存器R4-R11,和R13(SP)。其中,R4-R11保存在任务堆栈中(The task being switching out),而R13(SP)保存在任务控制块中(OSTCBCurPtr->OSTCBStkPtr = SP)。任务堆栈指针用的是PSP。
MRS R0, PSP ; PSP is process stack pointer CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack STM R0, {R4-R11} LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP; LDR R1, [R1] STR R0, [R1] ; R0 is SP of process being switched out
(3) Call OSTaskSwHook()
如果需要的话,可以在执行任务切换的时候执行一些附加的操作,添加在OSTaskSwHook()中。
函数调用时,LR寄存器用于保存函数的额返回地址。但通常函数嵌套不止一层,所以在执行函数调用前需要保存LR中的内容。
但发生异常时,LR寄存器用于保存EXC_RETURN,EXC_RETURN的值是在进入异常服务程序之前,“stacking”过程完成时,加载到LR寄存器中的。
所以在第(7)步时,为了确保PendSV异常使用PSP返回到用户级,执行了ORR LR, LR, #0x04;语句。
PUSH {R14} ; Save LR exc_return value LDR R0, =OSTaskSwHook ; OSTaskSwHook(); BLX R0 POP {R14}
(4) Get current high priority
任务控制块结构体的第一个成员便是OSTCBStkPtr.
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; LDR R1, =OSPrioHighRdy LDRB R2, [R1] STRB R2, [R0]
(5) Get current ready thread TCB
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr; LDR R1, =OSTCBHighRdyPtr LDR R2, [R1] STR R2, [R0]
(6) Get new process SP from TCB
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr
(7) Restore R4-R11 from new process stack
LDM R0, {R4-R11} ; Restore r4-11 from new process stack ADDS R0, R0, #0x20 MSR PSP, R0 ; Load PSP with new process SP
(7) Perform exception return which will restore remaining context
ORR LR, LR, #0x04 ; Ensure exception return uses process stack CPSIE I BX LR ; Exception return will restore remaining context
- PendSV异常的优先级设置在函数OSStartHighRdy()中完成,此函数由汇编编写,在os_cpu_a.s文件。博客中所有的代码都来自于micrium官方基于STM32L152移植的UCOSIII代码. ↩
- uCOSIII学习笔记之OSCtrSW( )
- UCOSIII学习之UCOSIII系统移植
- uCOSIII学习笔记之任务堆栈的初始化
- STM32-UCOSIII学习笔记3
- ucosIII学习
- 读uCOSIII源码笔记
- UCOSIII初次学习知识点
- ucosIII 学习资料汇总
- STM32自学笔记——UCOSIII
- 嵌入式项目1--UCOSiii操作系统的学习
- uCosIII之软件定时器的使用
- stm32-学习经验总结 ———UCOSIII-软件定时器
- iot小能手:【GAgent+STM32+UCOSIII】之智能贴锁
- ucosIII 信号量
- UCOSIII 中断
- UCOSIII移植
- UCOSIII-延时
- UCOSIII-中断
- 六大设计原则
- Android四大组件之一——Activity
- 解决React Native的Image组件中不更新图片的问题
- 2016-09-02
- Android 摆动的球体
- uCOSIII学习笔记之OSCtrSW( )
- ubuntu下如何看我的显卡驱动是否装好了(转自 雪谦信的博客)
- i.mx6soloX开发 之 文件系统
- tjut 3560
- HTML+CSS学习笔记 (五)
- Http和Https的区别
- NYOJ 176 整数划分(二)
- 深入理解Redux:10个来自专家的Redux实践建议
- 深入理解HashMap(及hash函数的真正巧妙之处)