对比ODR直接赋值的非原子操作和BSRR原子操作

🔍 原子操作 vs 非原子操作

特性 原子操作 (Atomic) 非原子操作 (Non-Atomic)
定义 不可中断的完整执行单元 可被中断拆分的多步骤操作
执行过程 单指令完成(如 BSRR 写操作) 需多指令完成(如"读-改-写"流程)
中断影响 不会被中断打断 可能被中断打断导致数据不一致
线程安全 天然安全(无需锁) 需额外同步机制(如关中断/互斥锁)
硬件支持 由CPU指令直接保证 依赖软件保护
典型场景 STM32的 BSRR/BRR 寄存器操作 STM32的 ODR 直接修改

⚠️ 非原子操作的风险场景(以STM32的ODR为例)

假设在 主循环中断函数 中同时修改 GPIOA->ODR

复制代码
// 主程序流程
void main() {
    GPIOA->ODR |= (1 << 5);  // 步骤1: 读取ODR
                             // 步骤2: 修改bit5
                             // 步骤3: 写回ODR
}

// 中断服务函数
void TIM_IRQHandler() {
    GPIOA->ODR |= (1 << 6);  // 在步骤1-3之间可能被触发!
}
危险时序
复制代码
主程序: [读ODR] -> [改bit5]   -> [写回ODR]
          │         ▲          ▲
中断触发: └─────────┘          │
          [读ODR] -> [改bit6] -> [写回ODR]

结果

主程序对 PA5 的修改被中断中的 PA6 修改覆盖 ,导致 PA5 设置失败!


🛡️ 为什么BSRR是原子操作?

STM32 的 BSRR 寄存器设计精妙:

复制代码
// 置位PA5(低16位有效)
GPIOA->BSRR = (1 << 5);     // 单指令完成:0→1

// 清零PA5(高16位有效)
GPIOA->BSRR = (1 << (5 + 16)); // 单指令完成:1→0

硬件机制

  • CPU 通过单次总线写操作 修改 BSRR

  • 硬件自动解析位操作,直接改变ODR状态

  • 无中间状态,不会被中断打断


🔧 非原子操作的解决方案

1. 关中断保护(裸机系统)
复制代码
__disable_irq();                 // 关中断
GPIOA->ODR |= (1 << 5);          // 安全修改
__enable_irq();                  // 开中断
2. 互斥锁(RTOS系统)
复制代码
osMutexAcquire(gpio_mutex, osWaitForever);  // 获取锁
GPIOA->ODR |= (1 << 5);                     
osMutexRelease(gpio_mutex);                 // 释放锁
3. 硬件原子指令(Cortex-M3/4/7)
复制代码
// 使用LDREX/STREX指令(需汇编或C封装)
__atomic_or_fetch(&GPIOA->ODR, (1<<5), __ATOMIC_SEQ_CST);

💡 关键理解

  1. 原子性 = 操作不可分割

    像物理学中的原子一样不可再分,要么完整执行,要么完全不执行。

  2. 非原子操作的本质风险
    数据竞争(Data Race):多个执行流(主程序+中断/多线程)同时访问共享资源(如ODR寄存器)且至少一方在写。

  3. 嵌入式场景的典型非原子操作

    • 多步寄存器修改(如 ODR, CR 等)

    • 非对齐数据访问(如32位机读写64位数据)

    • 外设状态机切换(如先读标志位再写命令)


📚 现实类比

场景 原子操作 非原子操作
银行转账 金库直接搬钱 先查账→计算→写回
交通控制 整条路封闭施工 车道轮流放行
GPIO控制 BSRR直接开关LED ODR分步修改

非原子操作如同「拆墙时被人塞新砖」------ 最终墙体状态不可预测!

相关推荐
时光找茬8 小时前
【瑞萨AI挑战赛-FPB-RA6E2】+ 从零开始:FPB-RA6E2 开箱测评与 e2 studio 环境配置
c++·单片机·边缘计算
@good_good_study9 小时前
FreeRTOS内存管理
单片机
Hello_Embed10 小时前
libmodbus 移植 STM32(基础篇)
笔记·stm32·单片机·学习·modbus
qqssss121dfd13 小时前
STM32H750XBH6的ETH模块移植LWIP
网络·stm32·嵌入式硬件
想放学的刺客14 小时前
单片机嵌入式试题(第27期)设计可移植、可配置的外设驱动框架的关键要点
c语言·stm32·单片机·嵌入式硬件·物联网
天昊吖14 小时前
stc8H启用DMA发送后 卡住【踩坑日志】
单片机
李永奉15 小时前
杰理芯片SDK开发-ENC双麦降噪配置/调试教程
人工智能·单片机·嵌入式硬件·物联网·语音识别
BackCatK Chen15 小时前
第 1 篇:软件视角扫盲|TMC2240 软件核心特性 + 学习路径(附工具清单)
c语言·stm32·单片机·学习·电机驱动·保姆级教程·tmc2240
兆龙电子单片机设计15 小时前
【STM32项目开源】STM32单片机多功能电子秤
stm32·单片机·开源·毕业设计·智能家居
切糕师学AI15 小时前
ARM 架构中的复位(Reset)与复位流程
arm开发·单片机·嵌入式·复位