ARM寄存器简介

支持不同类型编译器的宏定义

__CC_ARM

  • 对应编译器:ARM Compiler (也叫 ARM C Compiler),是 ARM 公司开发的编译器,通常用于嵌入式开发。
  • 用途 :这个宏在使用 ARM 编译器(如 armccarmclang)时会被自动定义。
  • 典型用途:用于在代码中加入特定于 ARM 编译器的指令或者优化。

__ICC_ARM

  • 对应编译器:IAR Embedded Workbench for ARM(IAR ARM 编译器),这是一个广泛用于嵌入式系统的编译工具链。
  • 用途:这个宏在使用 IAR 编译器时会被自动定义。
  • 典型用途:用于区分代码在 IAR 编译器下的特定实现或特性。

__GNUC__

  • 对应编译器:GNU 编译器套件(GCC),这是一个开源的编译器,广泛用于各种平台和操作系统,支持多种架构(包括 ARM)。
  • 用途 :这个宏在使用 GCC 或其变种(如 arm-none-eabi-gcc)时会被自动定义。
  • 典型用途:用于针对 GCC 编译器进行条件编译,可以在 GCC 下启用特定的功能或优化。

总结:

  • __CC_ARM:用于 ARM 编译器(如 armcc 或 armclang)。
  • __ICC_ARM:用于 IAR 编译器(IAR Embedded Workbench for ARM)。
  • __GNUC__:用于 GNU 编译器(如 GCC,支持多种平台)。

屏蔽中断函数

屏蔽全局中断

复制代码
PRIMASK 寄存器 是 ARM 处理器的一个特殊寄存器,用于控制中断的全局使能/屏蔽。它的作用是控制是否允许中断发生。具体来说,
设置 PRIMASK 为 1 时,会禁用所有的不可屏蔽中断(Non-Maskable Interrupts,NMI 和 Hard Fault 之外的中断);
而设置为 0 时,则允许中断的发生。

这个函数的作用是通过给定的 priMask 值,设置 ARM 处理器的 PRIMASK 寄存器,从而控制中断的使能或屏蔽。
    \param [in]    priMask  Priority Mask
 */
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
  register uint32_t __regPriMask         __ASM("primask");
  __regPriMask = (priMask);
}

屏蔽临界中断

如何屏蔽某个优先级一下的中断

你提供的代码是一个 ARM Cortex-M 体系结构的内联函数实现,用于设置 BASEPRI 寄存器的值。BASEPRI 寄存器是一个控制寄存器,用于设置中断优先级的屏蔽阈值,影响哪些中断可以被触发。它是 ARM Cortex-M 处理器中重要的控制寄存器之一,通常在嵌入式系统的操作系统(RTOS)中用于实现中断优先级的控制。

代码分析

复制代码
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
  register uint32_t __regBasePri         __ASM("basepri");
  __regBasePri = (basePri & 0xff);
}
  1. __STATIC_INLINE:
  • __STATIC_INLINE 是一个修饰符,表示这个函数是静态内联函数。内联函数(inline)告诉编译器尽可能将函数调用内联化,从而提高效率。STATIC 表示该函数在当前文件范围内有效,不能在其他文件中访问。

  • 这种写法通常用于库函数或者操作硬件寄存器的辅助函数,以便减少函数调用的开销。

  1. uint32_t __regBasePri __ASM("basepri"):
  • register 表示该变量应当存储在寄存器中,而非内存。通过将变量声明为 register,编译器会尽量将其存储在 CPU 寄存器中,这样可以提高访问速度。

  • __ASM("basepri") 是 GCC 风格的内嵌汇编语法,用来告诉编译器将该变量与 ARM 的 BASEPRI 寄存器关联。也就是说,这行代码将 __regBasePri 变量映射到 BASEPRI 寄存器,以便在后续操作中可以直接对 BASEPRI 寄存器进行赋值。

  1. __regBasePri = (basePri & 0xff):
  • basePri & 0xff 用于确保传入的 basePri 参数的值不会超过 8 位(即只保留低 8 位)。BASEPRI 寄存器是 8 位的(在 ARM Cortex-M 处理器中,BASEPRI 的位宽为 8),因此只会使用 basePri 参数的低 8 位来设置 BASEPRI 寄存器。
  1. 功能实现:
  • 该函数将输入的 basePri 值(经过 8 位掩码处理)写入到 BASEPRI 寄存器中。

  • BASEPRI 寄存器控制中断的屏蔽级别。其值是一个优先级屏蔽值,决定了当前处理器是否允许响应某些中断。如果当前中断优先级高于 BASEPRI 寄存器的值,则该中断会被屏蔽。

BASEPRI 寄存器简介

在 ARM Cortex-M 处理器中,BASEPRI 是一个用于中断优先级屏蔽的寄存器,它使得在特定优先级下,只有优先级高于或等于 BASEPRI 的中断才会被响应。其工作原理如下:

  • 值的含义

    • BASEPRI 寄存器的值是 8 位的(对于 Cortex-M),通常表示中断的屏蔽优先级。

    • BASEPRI 寄存器的值设置为某个优先级时,所有优先级低于该值的中断将被屏蔽(不被处理),而优先级高于或等于该值的中断将被允许。

    • 例如,如果 BASEPRI 设置为 0x10(16的十六进制表示),那么只有优先级高于 0x10 的中断可以被触发。

  • 设置 BASEPRI 的用途

    • BASEPRI 寄存器用于调度器或者中断管理中,以允许操作系统或任务管理器屏蔽低优先级的中断,在处理关键任务或代码段时,避免中断打断当前执行。

    • 它常常用于嵌入式系统中,在实时操作系统(RTOS)中控制中断优先级。

示例:如何使用 __set_BASEPRI

假设你在开发一个实时操作系统,可能会在某些时刻禁用优先级较低的中断,确保高优先级任务的稳定执行。你可以使用这个函数来设置 BASEPRI 寄存器。

复制代码
void enter_critical_section(void)
{
    __set_BASEPRI(0x80);  // 设置 BASEPRI 为 0x80,屏蔽所有优先级低于 0x80 的中断
}

void exit_critical_section(void)
{
    __set_BASEPRI(0x00);  // 退出临界区,恢复为默认的中断优先级屏蔽
}

总结

  • 该函数用于设置 BASEPRI 寄存器的值,以控制中断的优先级屏蔽。

  • 通过使用 basePri & 0xff,确保只使用 basePri 的低 8 位来控制 BASEPRI

  • BASEPRI 的值影响中断的响应行为,允许控制哪些中断可以被触发,哪些需要被屏蔽,通常用于实时操作系统中的临界区管理。

PSP,MSP

在 ARM 架构中,PSP(Process Stack Pointer)寄存器是一个用于管理进程或线程栈的指针寄存器。它是 ARMv7-M 和 ARMv8-M 等架构中的一部分,特别用于 Cortex-M 系列处理器。PSPMSP(Main Stack Pointer)共同工作,它们用于不同的栈模式。

1. PSP 的定义与作用

PSP进程栈指针 ,用于在特定的模式下(通常是线程模式)指向栈顶的位置。它是 Cortex-M 处理器中的一个特殊寄存器,主要用于嵌入式操作系统的任务切换和栈管理。具体来说,PSP 用于管理每个任务(线程)或进程的栈,当任务上下文切换时,操作系统会切换 PSP

  • MSP(Main Stack Pointer):通常用于异常处理和中断上下文,指向主栈(用于处理异常、中断等)。
  • PSP(Process Stack Pointer):通常用于线程模式,指向进程栈(应用程序代码或任务的栈)。

2. PSP 与 MSP 的切换

  • 默认模式下

    • 当 MCU 处于 异常模式 (比如进入中断或系统调用)时,MSP(主栈指针)被使用。
    • 当 MCU 处于 线程模式 (应用程序代码执行时),如果程序显式地切换到了 PSP,那么就会使用 PSP
  • 任务切换 : 在操作系统中,多个任务需要切换上下文。当任务切换时,操作系统保存当前任务的栈内容到当前的栈指针(通常是 PSP),并恢复下一个任务的栈指针(也是通过 PSP)。这保证了每个任务有独立的栈空间。

3. 如何切换到 PSP

ARM Cortex-M 处理器通过特定的指令和控制寄存器来切换栈指针:

  • 切换到 PSP

    • 当 CPU 进入线程模式时,可以通过设置 CONTROL 寄存器的位来选择使用 PSP

    • 例如,CONTROL 寄存器的 SPSEL 位为 1 时,栈指针会使用 PSP,而不是默认的 MSP

      MRS R0, CONTROL ; 读取 CONTROL 寄存器
      ORR R0, R0, #1 ; 设置 SPSEL 位为 1
      MSR CONTROL, R0 ; 更新 CONTROL 寄存器

  • PSP 切换回 MSP

    • 通过将 CONTROL 寄存器的 SPSEL 位清零,CPU 就会使用 MSP

4. PSP 在任务栈中的应用

在使用 RTOS(如 FreeRTOS)时,操作系统需要为每个任务分配独立的栈空间。当任务启动时,PSP 会被设置为该任务的栈底(或栈顶的指针)。在任务切换时,操作系统保存当前任务的 PSP 并加载新任务的 PSP

5. PSP 寄存器的结构

PSP 寄存器是一个 32 位寄存器,指向当前任务栈的顶部(栈增长方向是从高地址到低地址)。因此,PSP 会随着栈的推入(函数调用、局部变量分配等)向低地址递减。

  • 栈帧:当函数被调用时,栈帧会被压入栈中,其中包含函数返回地址、保存的寄存器等信息,PSP 会在此过程中自动更新。

6. 总结

  • PSP:进程栈指针,用于指向线程模式下的栈空间。
  • MSP:主栈指针,用于指向异常模式下的栈空间。
  • 通过设置 CONTROL 寄存器的 SPSEL 位,可以在 PSPMSP 之间切换。
  • PSP 在多任务环境下为每个任务提供独立的栈空间,保证任务切换时栈的隔离。

PSP 寄存器的管理是 ARM Cortex-M 系列处理器在多任务操作系统中的一个重要功能,确保每个任务具有自己的栈空间,避免栈溢出和数据冲突。

中断优先级管理寄存器

ISPRInterrupt Software Priority Register 的缩写,通常在基于 ARM Cortex-M 处理器的微控制器中使用。它是一个用于中断优先级管理的寄存器,允许软件设置中断的优先级。ISPR 寄存器可以帮助实现中断的优先级控制和处理中断的顺序。

算术操作的结果、条件判断等标志寄存器

APSRApplication Program Status Register 的缩写,是 ARM 架构中一个重要的状态寄存器,负责存储处理器的当前状态信息,特别是在程序执行期间的标志位。它包含了许多影响程序执行和控制流程的标志位,例如算术操作的结果、条件判断等。

APSR 寄存器的主要组成部分:

在 ARM 处理器中,APSR 通常包括以下几个标志位:

  1. N (Negative flag)

    • N 位表示最后一次算术或逻辑操作的结果是否为负数。如果操作结果为负,N 位被设置为 1,否则为 0。
  2. Z (Zero flag)

    • Z 位表示最后一次算术或逻辑操作的结果是否为零。如果结果为零,Z 位被设置为 1,否则为 0。
  3. C (Carry flag)

    • C 位表示最后一次算术操作是否产生进位(对于加法)或借位(对于减法)。对于无符号整数运算,C 位指示是否有进位或借位。
  4. V (Overflow flag)

    • V 位表示最后一次算术操作是否发生溢出。如果在有符号整数运算中,结果溢出了表示的范围,V 位会被设置为 1,否则为 0。
  5. Q (Saturation flag)

    • Q 位在某些特定操作中(如饱和算术运算)被设置,表示该操作结果是否发生饱和。饱和运算是指当计算结果超出了数据类型的最大值或最小值时,结果会被固定为最大或最小值。

APSR 在 ARM 架构中的作用

APSR 主要用于反映处理器的状态,以便程序根据不同的标志位进行条件跳转或执行不同的操作。这些标志位在算术运算、比较、逻辑操作等执行时被更新,且通常与 条件执行分支指令 (如 BEQBNEBGT 等)配合使用,以实现条件判断和流程控制。

  1. 标志位的更新
  • 每当进行算术操作(如加法、减法、乘法等)时,处理器会自动更新 APSR 寄存器中的标志位。

  • 比如,ADD 指令会更新 APSR,根据加法结果设置 N、Z、C 和 V 标志位。

  • 在进行 CMP(比较)指令时,处理器会更新 APSR 以反映两个数的比较结果,通常是通过设置 Z 标志来指示两个数是否相等。

  1. 条件执行
  • ARM 处理器支持条件执行机制,条件执行依赖 APSR 中的标志位。例如,如果 Z 位为 1(表示操作结果为零),可以通过条件指令(如 BEQ)进行跳转。

程序信息状态寄存器

xPSRExtended Program Status Register )是 ARM 架构中用于存储处理器当前状态的重要寄存器,特别是在 ARM Cortex-M 系列微处理器中,xPSR 用于保存程序执行的状态信息。它比传统的 APSR 更为扩展,包含更多的控制位和状态标志。xPSR 在处理器进入或退出异常(例如中断)时非常关键。

xPSR 结构

xPSR 寄存器的位结构通常包括以下几个部分:

  1. N (Negative Flag)

    • 这与 APSR 中的 N 位相同,表示最后一次算术或逻辑操作的结果是否为负。
  2. Z (Zero Flag)

    • 这与 APSR 中的 Z 位相同,表示最后一次算术或逻辑操作的结果是否为零。
  3. C (Carry Flag)

    • 这与 APSR 中的 C 位相同,表示最后一次算术操作是否产生进位或借位。
  4. V (Overflow Flag)

    • 这与 APSR 中的 V 位相同,表示最后一次算术操作是否发生溢出。
  5. Q (Saturation Flag)

    • APSR 中的 Q 位相同,表示操作是否发生了饱和。
  6. IT[3:0] (If-Then Control Bits)

    • 这些控制位用于支持 ARM 指令集中的 If-Then 语句。它们指示下一个几条指令是否需要条件执行。
  7. GE[3:0] (Greater-than or Equal Flags)

    • 这些标志与算术操作的条件代码相关,表示大于或等于的条件结果。
  8. T (Thumb State)

    • 这个位表示当前处理器处于 Thumb 模式还是 ARM 模式。Thumb 模式是 ARM 的一种指令集变种,指令较短,适用于内存受限的系统。
  9. I (Interrupt Disable)

    • 这个位表示是否禁用了中断。如果 I 位为 1,则禁用中断。
  10. F (Fast Interrupt Disable)

    • 这个位表示是否禁用了快速中断(FIQ)。如果 F 位为 1,则禁用快速中断。
  11. M[4:0] (Mode Bits)

    • 这些位表示当前处理器的工作模式。不同的模式有不同的处理优先级和特权级。例如,主模式(USER )、中断模式(IRQ )和快速中断模式(FIQ)等。
  12. CONTROL Register

    • 在某些 ARM 系列中,xPSR 还与 CONTROL 寄存器结合使用,后者控制特权模式与用户模式的切换、栈指针的选择等。
  13. EXC_RETURN (Exception Return)

    • 在发生异常时,xPSR 还保存异常返回信息,表示异常返回地址和状态。
相关推荐
切糕师学AI7 小时前
ARM 汇编指令:LDM
汇编·arm开发
ShiMetaPi7 小时前
GM-3568JHF丨ARM+FPGA异构开发板系列教程:外设教程 09 CAN
arm开发·fpga开发·fpga·rk3568
未来之窗软件服务8 小时前
幽冥大陆(八十)Win7环境下ARM架构开发—东方仙盟练气期
arm开发·架构·仙盟创梦ide·东方仙盟
未来之窗软件服务1 天前
国产化系统(一)ARM轻量化系统开发与试用全指南—东方仙盟练气期
arm开发·仙盟创梦ide·东方仙盟·阿雪技术观·国产化操作系统
林政硕(Cohen0415)1 天前
ARM Linux Qt Widget 虚拟键盘输入法移植
linux·arm开发·qt·键盘·输入法
100编程朱老师2 天前
Linux 下互联网络编程的基础知识
arm开发
番茄灭世神3 天前
32位ARM单片机视频教程第一篇
arm开发·单片机·嵌入式·gd32·pn学堂
驱动探索者3 天前
[缩略语大全]之[ARM CPU]篇
arm开发
ArrebolJiuZhou4 天前
00 arm开发环境的搭建
linux·arm开发·单片机·嵌入式硬件
迪三达4 天前
智能体开发-2-MCP
arm开发