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

对比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. 嵌入式场景的典型非原子操作

    • 多步寄存器修改(如 ODRCR 等)

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

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


📚 现实类比

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

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

http://www.xdnf.cn/news/11004.html

相关文章:

  • 机器学习——主成分分析PCA
  • 07.MySQL内置函数
  • 开发体育比分平台,有哪些坑需要注意的
  • Gephi中的Isometric Layout 插件使用应该用什么数据格式
  • UE5 2D角色PaperZD插件动画状态机学习笔记
  • el-select 实现分页加载,切换也数滚回到顶部,自定义高度
  • 2025.5.28 需求文档的撰写
  • xxhash和md5
  • 接口自动化测试之pytest 运行方式及前置后置封装
  • 蓝桥杯_DS18B20温度传感器---新手入门级别超级详细解析
  • 多模态大模型中的Projector模块深度解析
  • 苍穹外卖--HttpClient
  • Nginx上传大文件的配置
  • 普中STM32F103ZET6开发攻略(四)
  • 【Prompt实战】国际翻译小组
  • I2C 通信协议
  • Java并发编程:读写锁与普通互斥锁的深度对比
  • GitHub 趋势日报 (2025年06月02日)
  • Excel表格批量下载 CyberWin Excel Doenlaoder 智能编程-——玄武芯辰
  • IP查询与网络风险的关系
  • 基础知识掌握
  • 构建基于深度学习的人体姿态估计系统 数据预处理到模型训练、评估和部署 _如何利用人体姿态识别估计数据集_数据进行人体姿态估计研究的建议Human3.6M
  • Web前端为什么要打包?Webpack 和 Vite 如何助力现代开发?
  • 【Redis】set 类型
  • 腾讯下乡了。。。
  • Linux远程连接主机——ssh命令详解
  • 适老化场景重构:现代家政老年照护虚拟仿真实训室建设方案​
  • 结构性设计模式之Composite(组合)
  • AUTOSAR CP——Can模块
  • 游戏开发常见数据压缩