对比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分步修改

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

相关推荐
机器视觉知识推荐、就业指导10 小时前
STM32 外设驱动模块:热敏电阻传感器模块
stm32·单片机·嵌入式硬件
GilgameshJSS12 小时前
STM32H743-ARM例程9-IWDG看门狗
c语言·arm开发·stm32·单片机·嵌入式硬件·学习
Hello_Embed12 小时前
STM32 智能垃圾桶项目笔记(一):超声波模块(HC-SR04)原理与驱动实现
c语言·笔记·stm32·单片机·嵌入式软件·嵌入式项目
wdfk_prog14 小时前
[Linux]学习笔记系列 -- lib/sort.c 通用的排序库(Generic Sorting Library) 为内核提供标准的、高效的排序功能
linux·运维·c语言·笔记·stm32·学习·bug
what&&why15 小时前
STM32控制继电器
单片机·嵌入式硬件
liujing1023292918 小时前
Day03_STM32F103C8T6学习笔记6-9章(江科大)
笔记·stm32·学习
我不吃西红柿k19 小时前
蓝桥杯嵌入式——基础模块的使用(初始化+调度器+LED+按键+LCD)
单片机·嵌入式硬件
XCOSnTh19 小时前
XCOSnTh单片机的串口
c语言·单片机·嵌入式硬件·算法·xcosnth
沉在嵌入式的鱼21 小时前
STM32--大功率mos管驱动模块
stm32·单片机·mos管
驱动起爆大师x_x1 天前
CAN总线的数据采样和同步问题
stm32·嵌入式硬件·学习·can