以下内容转载自安富莱电子: http://forum.armfly.com/forum.php
本章教程为大家讲解 RTX 运行模式的一个重要知识点,特权级模式和非特权级模式,有些资料或者书籍将非特权级模式称为用户模式。
RTX 任务特权级知识点说明
对于初学者只需记住本小节的知识点即可,如果要深入的了解还是需要花些时间去研究下 Cortex-M3
或者 M4 权威指南。
对于使用 Cortex-M3 或者 M4 内核的芯片来说,RTX 操作系统可以让任务运行在特权级或者非特权
级模式,这两种模式是 M3 或者 M4 内核本身所具有的特性。
在特权级模式下,用户可以访问和配置系统控制寄存器,比如 NVIC 中断控制器。然而,如果是在非
特权级模式下,系统控制寄存器是不允许访问的,一旦访问将导致硬件异常。
Unprivileged:
非特权级,起到保护用户任务的作用,防止用户可以在任意任务中访问和修改系统寄存器,操作不当
会造成系统崩溃。
Privileged:
特权级,这种模式下用户可以在任意任务中对系统控制寄存器的访问和修改。
有了这点基础的认识之后,还有以下四个疑问有待解决。
非特权级模式下那些寄存器不可访问
对于 Cortex-M3 或者 M4 内核来说,所有的核心外设寄存器都是只能在特权级下才可以访问,那些
又是核心外设寄存器呢,对于 STM32 来说需要大家看编程手册,如下这些核心外设所有的寄存器都需要
在特权级下才可以访问:
关于 MPU,NVIC,SCB 和 STK 四个单元的其它寄存器是否需要在特权级下才可以访问,大家可以按照
我上面说的方法进行查看。
除了核心外设寄存器以外,M3/M4 内核的特殊功能寄存器也是不能在非特权级下访问的,特殊功能
寄存器主要包括以下寄存器:
程序状态寄存器组(PSRs 或曰 xPSR)
中断屏蔽寄存器组(PRIMASK, FAULTMASK,以及 BASEPRI)
控制寄存器(CONTROL)
对于参考手册上面所说的 SPI,USART,USB 等所有外设寄存器都是可以在非特权级下进行访问的。
非特权级模式下核心外设寄存器如何初始化
如果用户将 RTX 操作系统的任务设置在非特权级模式下运行,那么核心外设寄存器应该放在哪里进行
初始化呢,主要有以下两种方法:
使用 SVC(Supervisor Call)软中断,这个在第 19 章有详细讲解。
在初始化和开启 RTX 多任务前做核心外设的初始化。
Cortex-M3 或者 M4 内核如何切换两种模式
Cortex-M3/M4 中的特殊功能寄存器包括:
程序状态寄存器组(PSRs 或曰 xPSR)
中断屏蔽寄存器组(PRIMASK, FAULTMASK,以及 BASEPRI)
控制寄存器(CONTROL)
其中控制寄存器 CONTROL 是用来设置特权级和非特权级切换的,CONTROL 寄存器定义如下:
RTX 任务特权等级的设置方法
RTX 任务特权等级的设置方法比较简单,查看 RTX 系统的配置向导,如下图 9.1 所示:
Run in privileged mode
此参数就是用来设置特权级和非特权级的,选上单选框表示使能任务工作在特权级模式,取消单选框
表示任务工作在非特权级模式。
RTX 任务特权等级深入认识
本小节的知识点对于初学者来说比较难理解,需要积累了一定的经验后才能更好的理解,不过还是建
议读一读。
深入了解 Cortex-M3/M4 内核的特权等级就不得不说说两种操作模式,Cortex-M3/M4 支持两种操
作模式,两种操作模式分别是:
Handler mode,中断模式,简单的说就是指的异常服务程序是处在中断模式。
Thread mode,线程模式,简单的说就是异常服务程序以外的程序都是处在线程模式。
当处理器处在线程状态下时,既可以使用特权级,也可以使用用户级;另一方面,handler 模式
总是特权级的。在系统复位后,处理器进入线程模式+特权级。
在特权级下的代码可以通过置位 CONTROL[0]来进入用户级。而不管是任何原因产生了任何异常,
处理器都将以特权级来运行其服务例程,异常返回后,系统将回到产生异常时所处的级别。用户级下的代
码不能再试图修改 CONTROL[0]来回到特权级。它必须通过一个异常 handler,由那个异常 handler 来修
改 CONTROL[0],才能在返回到线程模式后拿到特权级。下图是特权级线程模式和用户级线程模式的切换图:
户程序代码出问题时,不会让它成为害群之马,因为用户级的代码是禁止写特殊功能寄存器和 NVIC 中断
寄存器的。另外,如果还配有 MPU,保护力度就更大,甚至可以阻止用户代码访问不属于它的内存区域。
为了避免系统堆栈因应用程序的错误使用而毁坏,我们可以给应用程序专门配一个堆栈,不让它共享
操作系统内核的堆栈。在这个管理制度下,运行在线程模式的用户代码使用 PSP,而异常服务例程则使用
MSP。这两个堆栈指针的切换是智能全自动的,就在异常服务的始末由硬件处理。
如前所述,特权等级和堆栈指针的选择均由 CONTROL 负责。当 CONTROL[0]=0 时,在异常处理
的始末,只发生了处理器模式的转换,如下图所示。
开发板实验 :
RTX 配置:
RTX 配置向导详情如下: