初级会员
- 积分
- 157
- 金钱
- 157
- 注册时间
- 2015-11-26
- 在线时间
- 31 小时
|
楼主 |
发表于 2020-5-8 16:15:04
|
显示全部楼层
mrs r0, psp;读取进程栈指针,保存在R0里
isb;指令同步屏障
/* 获取当前的任务控制块. */
ldr r3, =g_CurThreadPtr;获取pCurrentTCB指针的存储地址,这个指针永远指向正在运行的任务。
ldr r2, [r3];取R3所保存的地址处的值赋值给R2,即获取到了当前任务的存储地址
/* 判断任务是否使用了FPU,如果使用了FPU的话,进行任务切换的时候就需要将FPU的S16-31寄存器保存在任务堆栈中,S0-15自动保存的 */
tst r14, #0x10
it eq
vstmdbeq r0!, {s16-s31}
/* 保存核心寄存器. */
stmdb r0!, {r4-r11,r14}
str r0, [r2] ;寄存器R0的值写入到寄存器R2所保存的地址中去,即将新的栈顶保存在任务控制块的第一个字段中。
/* Cortex中断默认情况下有一个数值为0的优先级。大多数情况下0代表最高级优先级。绝对不可以在优先级为0的中断服务例程中调用RTOS API函数*/
stmdb sp!, {r0, r3};寄存器R3的值临时压栈,寄存器R3中保存了当前任务的控制块,接下来要操作任务上下文切换,为了防止R3被改写,所以临时先压栈
mov r0, #0x20;
msr basepri, r0;关中断
dsb;数据同步屏障
isb;指令同步屏障
bl OEOS_SwitchContext;该函数来获取下一个要运行的任务
mov r0, #0
msr basepri, r0;开中断
ldmia sp!, {r0, r3};r3出栈,恢复寄存器R3的值。note:此时r3所保存的地址处数据改变,已经变成了下一个要运行任务的任务控制块
ldr r1, [r3]
ldr r0, [r1];获取新的要运行任务的任务堆栈栈顶,并将栈顶保存在寄存器R0中。
/* Pop the core registers. r0-r3等其它的寄存器,内核会自动pop*/
ldmia r0!, {r4-r11,r14};运行的任务的现场
/* 是否支持FPU,支持就手动恢复S16-31 */
tst r14, #0x10
it eq
vldmiaeq r0!, {s16-s31}
msr psp, r0;更新进程栈指针PSP的值
isb;指令同步屏障
bx r14;函数返回,bx为间接跳转指令,即跳转到存放在r14中的地址处,R14寄存器也叫链接寄存(LR)。
|
|