这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » Cortex-M3/M4的寄存器之CONTROL寄存器

共1条 1/1 1 跳转至

Cortex-M3/M4的寄存器之CONTROL寄存器

院士
2025-01-19 16:20:32     打赏

Cortex-M3/M4的寄存器之CONTROL 寄存器

CONTROL 寄存器定义:栈指针的选择(主栈指针/进程栈指针)。线程模式的访问等级(特权/非特权)。另外,对于具有浮点单元的 Cortex-M4 处理器,CONTROL, 寄存器中有一位表示当前上下文(正在执行的代码)是否使用浮点单元。

注意 对于 ARMv6-M,nPRIV和非特权等级的实现是和设计实现相关的,而且在最初的Cortex-M0 和 Cortex-M1 产品上是不可用的,其在 Cortex-M0+上则是可选的。

CONTROL寄存器只能在特权访问等级进行修改操作,而读取操作则在特权和非特权访问等级都可以。

控制寄存器_01.png

控制寄存器_02.png

复位后,CONTROL寄存器默认为0,这也就意味着处理器此时处于线程模式、具有特权访问权限以及使用主栈指针。通过写 CONTROL寄存器,特权线程模式的程序可以切换栈指针的选择或进人非特权访问等级。不过,nPRIV(CONTROL的第0位)置位后,运行在线程模式的程序就不能访问CONTROL 寄存器了。

运行在非特权等级的程序无法再切换回特权访问等级,这样就提供了一个基本的安全模型。例如,嵌入式系统中可能会具有运行在非特权访问等级的不受信任的应用,这些应用的访问权限就需要受到限制,以免不可靠的程序引起整个系统的崩溃。

若有必要将处理器在线程模式切换回特权访问等级,则需要使用异常机制。在异常处理期间,处理程序可以清除 nPRIV 位。在返回到线程模式后,处理器就会进人特权访问等级。

控制寄存器_04.png

若使用嵌入式 OS,每次上下文切换时都可以重新编程 CONTROL,寄存器,以满足应用间不同的特权访问等级需要。

nPRIV 和 SPSEL,的设置共有4种组合方式,其中3种在实际应用中较为常见。

控制寄存器_05.png

对于未使用嵌入式 OS 的多数简单应用,无须修改 CONTROL寄存器的数值。整个应用可以运行在特权访问等级并且只使用 MSP。

控制寄存器_06.png

要利用 C语言访问 CONTROL,寄存器,可以使用符合 CMSIS 的设备驱动库提供的以下函数:

x=_get_CONTROL();//读取 CONTROL 寄存器的当前值
_set_CONTROL(x);//设置 CONTROL 寄存器的数值为x

在修改 CONTROL 寄存器的值时需要注意以下两点::

- 对于具有浮点单元(FPU)的 Cortex-M4 处理器,或具有 FPU 的 ARMv7-M 处理器,由于浮点单元的存在,FPCA 位会自动置位。若程序中包含浮点运算但FPCA 位被意外清除,而且接下来产生了一个中断,那么浮点单元寄存器中的数据将不能在异常入口流程保存,且可能会被中断处理覆盖。在这种情况下,继续执行被中断的任务时,程序可能无法继续正确地处理。

- 在修改了 CONTROL, 寄存器后,从架构来看,应该使用指令同步屏障(ISB)指令(或符合 CMSIS的设备驱动库中的–ISB()函数),以确保本次修改对接下来的代码能起到作用。由于 Cortex-M3、Cortex-M4、Cortex-M0+、Cortex-M0 以及 Cortex-M1 的流水线非常简单,不使用 ISB 指令也不会引起什么问题。

要用汇编访问 CONTROL 寄存器,可以使用 MRS 和 MSR 指令:

MRS r0,CONTROL  ;将 CONTROL 寄存器读入 RO
MSR CONTROL,rO  ;将 R0 写入 CONTROL 寄存器

可以通过检查 CONTROL 和 IPSR 的数值来确定当前是否为特权等级。

int in_privileged(void)
{
    if( _get_IPSR()!=0)
        return 1;//True
    else if(( _get_CONTROL()&0x1)==0)
        return 1;//True
    else
        return 0; //False
}





关键词: Cortex-M3     CONTROL     寄存器    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]