运行模式

在stm32或freertos中只有两种运行模式:特权与非特权

ARM Cortex-M 内核(如 Cortex-M3/M4/M7)的一项安全机制,用于实现操作系统的 任务隔离、安全内核保护和资源访问控制

三、切换方式和原理
✅ 1. 控制当前任务是否为特权模式:
控制寄存器:CONTROL 寄存器的第 0 位决定运行模式。

CONTROL[0] = 0 特权模式
CONTROL[0] = 1 非特权模式

可使用如下指令切换模式:

__set_CONTROL(__get_CONTROL() | 0x1); // 切换为非特权模式
__set_CONTROL(__get_CONTROL() & ~0x1); // 切换为特权模式(仅在特权模式中有效)
注意:一旦进入非特权模式,只能通过异常(如 SVC)切换回特权模式!

  1. 非特权任务如何访问系统资源?
    无法直接访问例如 NVIC, SCB, SYSTICK 等系统寄存器

需通过 SVC(SuperVisor Call)中断 请求服务

SVC 会触发异常,切到特权模式中执行对应的“系统服务”函数

四、MPU(Memory Protection Unit)与模式配合
MPU 可配置内存区域的访问权限:

指定某段内存 仅可由特权模式访问

非特权模式访问将触发 Memory Fault 异常

非常适合任务隔离、保护内核数据

例如:

MPU_ConfigRegion(region, addr, size, PERM_PRIV_RW); // 仅特权可访问

例子:

#include "stm32f4xx.h"

void SVC_Handler(void);

// 用 SVC 请求软复位
void svc_reset_request(void) {
    __asm("svc 0x00");  // 发出 SVC 中断,编号为 0
}

// SVC 中断处理函数,在这里执行特权操作
void SVC_Handler(void) {
    // 特权模式下写 AIRCR 触发系统复位
    SCB->AIRCR = (0x5FA << 16) | (1 << 2); // VECTKEY | SYSRESETREQ
}

// 切换为非特权模式
void switch_to_unprivileged(void) {
    __set_CONTROL(__get_CONTROL() | 0x01);  // 设置 CONTROL[0] = 1,进入非特权
    __ISB();  // 指令同步,确保立即切换
}

int main(void) {
    // 初始为特权模式
    switch_to_unprivileged();  // 切换为非特权模式

    // 非特权模式无法直接访问 SCB->AIRCR
    // 所以发出 SVC 请求,让特权模式执行 reset
    svc_reset_request();  

    while (1);
}

cortex-a对应9种模式的寄存器组