微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > uCOS-II的移植步骤

uCOS-II的移植步骤

时间:11-27 来源:互联网 点击:

这个里面有个PSP进程堆栈指针,关于这个指针和主堆栈指针的区别需要好好的看看权威指南

OS_CPU_PendSVHandler ;xPSR, PC, LR, R12, R0-R3已自动保存
CPSID I ;任务切换期间需要关中断 Prevent interruption during context switch
MRS R0, PSP ;R0 = PSP PSP is process stack pointer 线程堆栈指针
CBZ R0, OS_CPU_PendSVHandler_nosave ;如果PSP==0跳转到OS_CPU_PendSVHandler_nosave去执行 在多任务的初始化时PSP被初始化为0 Skip register save the first time
;若果PSP如果是0,标示任务没有运行过,那么不需要压栈

SUBS R0, R0, #0x20 ;R0 -= 0x20 保存R4-R11到任务堆栈 共32个字节

STM R0, {R4-R11} ;压栈R4-R11, 其他8个寄存器是在异常时自动压栈的
LDR R1, =OSTCBCur ;获取OSTCBCur->OSTCBStkPtr

LDR R1, [R1] ;R1 = *R1 (R1 = OSTCBCur)
STR R0, [R1] ;*R1 = R0 (*OSTCBCur = SP) R0 is SP of process being switched out
;将当前任务的堆栈保存到自己的任务控制块
;OSTCBCur->OSTCBStkPtr = PSP
;程序运行此位置,已经保存了当前任务的context了

; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value 保存R14,因为后面要调用函数
LDR R0, =OSTaskSwHook ; OSTaskSwHook(); R0 = &OSTaskSwHook
BLX R0 ; 调用OSTaskSwHook()
POP {R14} ; 恢复R14

LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; R0 = &OSPrioCur
LDR R1, =OSPrioHighRdy ; R1 = &OSPrioHighRdy
LDRB R2, [R1] ; R2 = *R1 (R2 = OSPrioHighRdy)
STRB R2, [R0] ; *R0 = R2 (OSPrioCur = OSPrioHighRdy)

LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;;R0 = &OSTCBCur
LDR R1, =OSTCBHighRdy ; R1 = &OSTCBHighRdy
LDR R2, [R1] ; R2 = *R1 (R2 = OSTCBHighRdy)
STR R2, [R0] ; *R0 = R2 (OSTCBCur = OSTCBHighRdy) 此时 [R2] = 新任务的PSP

LDR R0, [R2] ;R0 = *R2 (R0 = OSTCBHighRdy), 此时R0是新任务的SP R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
LDM R0, {R4-R11} ; 从任务堆栈SP恢复R4-R11 Restore r4-11 from new process stack
ADDS R0, R0, #0x20 ; 调整PSP R0 += 0x20
MSR PSP, R0 ; Load PSP with new process SP PSP = R0, 用新任务的SP加载PSP
ORR LR, LR, #0x04 ; Ensure exception return uses process stack 确保LR位2为1,返回后使用进程堆栈PSP
CPSIE I ;开中断
BX LR ; Exception return will restore remaining context 中断返回

END

由于是第一次的学习关于操作系统的知识,里面的理解估计有很多不对的地方。随着自己的理解就会有所修正。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top