在 STM32 上使用 register 关键字

在 STM32 上使用 register 关键字时,有一些特别需要注意的事项。虽然 register 是 C 语言中的一个标准关键字,它用于提示编译器将变量尽可能存放在寄存器中,以加速访问,但在 STM32 这样的嵌入式平台上,还是需要考虑几个方面:

1. STM32 的寄存器有限

STM32 的微控制器(MCU)拥有有限数量的寄存器(通常是 16 个通用寄存器)。因此,register 并不会将所有变量都放入寄存器,而是依赖于编译器的智能选择。

注意点:

  • 如果声明的局部变量比较多,编译器可能会选择不将所有变量都放入寄存器。
  • 在 STM32 系列中,尤其是小型型号(如 STM32F030,STM32F1 系列),寄存器资源非常紧张,过度使用 register 可能会导致寄存器分配冲突或性能下降。
  • 对于大多数情况下,编译器会自动优化局部变量,通常不需要显式使用 register

2. register 变量不能取地址

使用 register 声明的变量不能使用 & 操作符取其地址,因为它们是寄存器变量,不能被直接访问。如果你尝试取寄存器变量的地址,编译器会报错。

c 复制代码
register int x = 10;
int *p = &x;  // 编译错误:无法取寄存器变量的地址

如果在代码中需要取变量的地址,那么应该避免使用 register

3. register 和优化设置

对于嵌入式开发,STM32 的编译器(如 Keil5)通常会做自动优化。尤其是在开启 -O3-Os 优化选项时,编译器会自动根据情况将局部变量存放到寄存器中,实际上很多时候你并不需要手动指定 register

  • -O3 优化: 该优化等级下,编译器会最大程度优化代码,包括变量寄存器分配,因此许多情况下,即使不使用 register,编译器也会将频繁使用的变量存储在寄存器中。
  • -Os 优化: 该选项关注代码的尺寸,编译器会尽可能减少代码大小,同时考虑将变量放入寄存器中,以提升性能。

在启用这些优化时,register 关键字的作用可能会显得不那么重要,因为编译器已经在做类似的优化。

4. 特殊寄存器

对于 STM32 微控制器,除了普通的通用寄存器外,还有一些专用寄存器(如 SFR, 特殊功能寄存器)。这些寄存器和通用寄存器有所不同,它们用于控制外设、系统设置等。使用 register 时,不能期望 STM32 编译器会将这些特殊寄存器存入普通的通用寄存器。

建议:

  • 如果操作的是硬件寄存器(如 GPIOUSART 等外设寄存器),应该直接使用该外设的寄存器地址,而不应依赖 register 关键字。

5. register 和 STM32 外设访问优化

在 STM32 中访问外设寄存器时,寄存器的值往往是需要直接映射到内存的。在这种情况下,编译器可能会将外设寄存器地址作为指针处理,而不是使用 register 来优化。对于外设的寄存器,手动优化(例如通过 DMA 或通过内存映射外设等)通常比使用 register 更为有效。

6. register 和 ARM 架构

STM32 微控制器基于 ARM Cortex-M 内核(如 Cortex-M3、M4、M7)。ARM 处理器本身有一套高效的寄存器管理和流水线机制,编译器在优化时会根据 ARM 的特点做相应优化。

注意:

  • ARM 处理器已经具有相对较多的寄存器(如 ARM Cortex-M4 有16个通用寄存器),如果使用 register,编译器会尽量选择合适的寄存器来存放变量。
  • 对于复杂的 ARM 指令集,编译器会在优化时选择合适的寄存器使用策略,因此即使不显式声明 register,编译器通常也能合理地优化寄存器的使用。

总结:

在 STM32 上使用 register 时,有以下几点需要特别注意:

  1. 有限的寄存器资源 :STM32 的寄存器数量有限,过度使用 register 可能会导致寄存器分配冲突。
  2. 不能取地址 :声明为 register 的变量不能取地址,因此如果需要传递指针或取地址,不能使用 register
  3. 编译器优化 :Keil5 等编译器会自动进行优化,通常在开启高级优化(如 -O3)时,不需要显式使用 register,编译器会自动决定将局部变量放入寄存器中。
  4. 适用场景register 最适用于频繁访问的局部变量,但对于 STM32 外设寄存器操作,应直接操作地址,而不应使用 register

在 STM32 的开发过程中,很多时候依赖编译器的优化能力,特别是在 Keil5 环境下,编译器的优化已经非常强大,因此对 register 的使用可以保持谨慎,并根据实际情况决定。

相关推荐
易水寒陈5 分钟前
MultiTimer源码分析
stm32·单片机
白羽陌16 分钟前
STM32入门教程
stm32·单片机·嵌入式硬件
高工智能汽车1 小时前
车规MCU,开启“巨变”
单片机·嵌入式硬件
TEL136997627501 小时前
PTCB818A说明书 配套PL27A1芯片MCU参数说明
网络·单片机·嵌入式硬件
硬汉嵌入式2 小时前
【无标题】
stm32·wifi·英飞凌·sdio·赛普拉斯·cyw43·cyw55
客家元器件2 小时前
LPDDR5选型参数
嵌入式硬件
✎ ﹏梦醒͜ღ҉繁华落℘2 小时前
实际项目开发单片机—Flash错误
单片机
一个平凡而乐于分享的小比特2 小时前
单片机内部时钟 vs 外部时钟详解
单片机·嵌入式硬件·内部时钟·外部时钟
xyx-3v2 小时前
RK3506G移植APM飞控的可行性
单片机·学习
才鲸嵌入式3 小时前
香山CPU(国产开源)的 SoC SDK底层程序编写,以及其它开源SoC芯片介绍
c语言·单片机·嵌入式·arm·cpu·verilog·fpga