当前位置: 首页 > article >正文

ARM寄存器简介

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

__CC_ARM

  • 对应编译器:ARM Compiler (也叫 ARM C Compiler),是 ARM 公司开发的编译器,通常用于嵌入式开发。
  • 用途:这个宏在使用 ARM 编译器(如 armcc 或 armclang)时会被自动定义。
  • 典型用途:用于在代码中加入特定于 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 表示该函数在当前文件范围内有效,不能在其他文件中访问。

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

2. uint32_t __regBasePri __ASM("basepri"):

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

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

3. __regBasePri = (basePri & 0xff):

  • basePri & 0xff 用于确保传入的 basePri 参数的值不会超过 8 位(即只保留低 8 位)。BASEPRI 寄存器是 8 位的(在 ARM Cortex-M 处理器中,BASEPRI 的位宽为 8),因此只会使用 basePri 参数的低 8 位来设置 BASEPRI 寄存器。

4. 功能实现:

  • 该函数将输入的 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 位,可以在 PSP 和 MSP 之间切换。
  • 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 标志来指示两个数是否相等。

2. 条件执行

  • 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 还保存异常返回信息,表示异常返回地址和状态。


http://www.kler.cn/a/428897.html

相关文章:

  • 内网渗透测试工具及渗透测试安全审计方法总结
  • 解决 多层跳板机情况下,ssh可以成功连但是VSCode失败
  • 1.写在前面
  • Rust Actix Web 项目实战教程 mysql redis swagger:构建用户管理系统
  • 学技术学英文:通过jmeter命令行工具生成聚合报告文件到csv文件
  • Spring 核心技术解析【纯干货版】- Ⅶ:Spring 切面编程模块 Spring-Instrument 模块精讲
  • 基于单片机的书写坐姿规范提醒器设计(论文+源码)
  • 粉丝生产力与开源 AI 智能名片 2+1 链动模式商城小程序的融合创新与价值拓展
  • PyTorch 本地安装指南:全面支持 macOS 、 Linux 和 Windows 系统
  • wazuh-modules-sca
  • 麒麟 V10 系统(arm64/aarch64)离线安装 docker 和 docker-compose
  • 使用trace-cmd跟踪Linux内核函数:一次愉快的内核探险
  • BurpSuite-7(自动化漏扫)
  • Redis的五种数据类型(Set、Zset)
  • K8s面试系列:K8s常用 API 资源总结速记
  • Redis过期删除(淘汰)策略概念和理解,以及key已过期内存未释放的处理方式
  • Unity控制物体材质球的改变
  • 解决流网络中不存在s~u~t路径的节点的最大流问题
  • 分享一个开源的网络加速器
  • Vue Web开发(三)
  • 前端路径“@/“的使用和配置
  • 【第一篇】逆向实战,exe游戏 逆向实战之某网络游戏---本文仅供学习-仅供学习-----逆向程序-优雅草央千澈-逆向端游实战---逆向某很火很火的游戏实战。
  • 【Linux】WSL:Win运行Linux
  • 【深度学习】利用Java DL4J 构建和训练医疗影像分析模型
  • 【C语言--趣味游戏系列】--电脑关机整蛊小游戏
  • Brain.js(八):RNNTimeStep 实战教程 - 股票价格预测 - 实操需警慎