硬件平台是STM32F407,ARM Cortex-M4内核。
查看os_sys_init的定义,在rtl.h中定义如下:
#define os_sys_init(tsk) os_set_env(); _os_sys_init((U32)rt_sys_init,tsk,0,NULL)
其中os_set_env是由汇编实现的:
__asm void os_set_env (void) {
/* Switch to Unprivileged/Privileged Thread mode, use PSP. */
MOV R0,SP ; PSP = MSP
MSR PSP,R0
LDR R0,=__cpp(&os_flags)
LDRB R0,[R0]
LSLS R0,#31
MOVNE R0,#0x02 ; Privileged Thread mode, use PSP
MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP
MSR CONTROL,R0 ; 读R0值并写入CONTROL寄存器
BX LR
ALIGN
}
下面我们来分析代码的作用:
MOV R0,SP ;把SP(R13)(主堆栈指针)传送给R0
MSR PSP,R0 ;特殊寄存器操作,把R0传送给PSP(进程堆栈指针)
LDR R0,=__cpp(&os_flags) ;加载c语言定义的os_flags的指针到R0
LDRB R0,[R0] ;把R0指向的数据保存到R0中
LSLS R0,#31 ;把R0中的数据左移31位并将结果保存到R0中
MOVNE R0,#0x02 ;如果R0非0,则使用特权模式
MOVEQ R0,#0x03 ;如果R0位0,则不适用特权模式
MSR CONTROL,R0 ;特殊寄存器操作,把配置好的R0值写入CONTROL寄存器
查看《STM32F3 and STM32F4 Series Cortex-M4 programming manual》,可以找到关于Stack和CONTROL寄存器的相关内容。
关于Stack
STM32F4使用递减的Stack。这意味着栈指针指向栈内存的最后的一个栈项。当处理器往Stack中压入
一个新项时,栈指针先递减然后把项写入新的内存位置。处理器实现了两个栈,住栈和进程栈,各自
拥有自己的栈指针。在线程模式,CONTROL寄存器控制处理器使用主栈或者进程栈。在处理器模式,处理器始终使用主栈。
关于CONTROL
CONTROL寄存器: CONTROL寄存器控制stack的使用和软件在线程模式下的特权等级,并且标记
FPU是否处于激活状态
The CONTROL register controls the stack used and the privilege level for software
execution when the processor is in Thread mode and indicates whether the FPU state is
active.CONTROL寄存器的位定义如下:
Bit[0]:nPRIV 线程模式特权等级。0表示特权模式,1表示非特权模式
Bit[1]:SPSEL 活动栈指针选择。选择当前的栈。0表示当前栈指针是MSP,1表示当前栈指针是PSP。
在处理器模式读为0且忽略写操作。内核会自动根据返回结果自动更新它。
Bit[2]:FPCA 指示是否启用浮点运算单元。
有此可见,os_set_env函数的主要作用就是配置CONTROL寄存器,根据配置情况来配置rtx运行在特权模式或者非特权模式,同时启用FPU。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/chinley/article/details/47277267