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

Cortex-M3 特色功能——位带操作(Bit-Band)

该文章同步至公众号OneChan


1. 总体概览:什么是位带操作?

在嵌入式开发中,我们经常需要单独设置或清除某个寄存器的某一位(例如 GPIO 的输出数据寄存器)。传统做法是“读-改-写”:先读取整个寄存器的值,修改对应的位,再写回。但这种方法在多任务或中断环境下可能存在风险——如果两个操作同时进行,可能导致数据不一致。

Cortex-M3 引入位带操作来解决这个问题。它将位带区(一个包含多个位的普通内存区域)的每一位,映射到别名区中的一个字地址(32 位)。对别名区中某个字的读写,硬件会自动转换为对位带区对应位的原子操作。

总体原理图

图 1 解释:这张图展示了位带操作的整体流程。


2. 细节展开:位带区的映射原理

Cortex-M3 定义了两个 1MB 的位带区,分别对应两个 32MB 的别名区:

映射公式推导图

位带别名区中的每个字(32 位)对应位带区中的一个位。换算关系如下:

图 2 解释:这张图推导了从位带区到别名区的地址转换公式。

重要:这个转换完全由硬件完成。如果程序员手动计算地址并访问,也是合法的,但更常见的做法是使用宏或函数来生成别名地址。


3. 操作流程:传统方式 vs 位带方式

为了突出位带操作的原子性和效率,我们对比两种方式:传统“读-改-写”和位带别名访问。

传统读-改-写操作(非原子)

图 3a 解释:传统方式在多任务环境中可能产生竞态条件。

位带别名操作(原子)

图 3b 解释:使用位带别名地址操作时,每个写操作在硬件层面都是原子的。

关键:位带操作的原子性是由总线矩阵AHB-APB 桥(如果外设在 APB 上)保证的。对别名区的访问会被转换成对位带区的独占访问,整个过程不可被其他总线主设备打断。


4. 代码实例:国产芯片上的位带操作

以下代码基于某国产 Cortex-M3 芯片(具体型号不便透露),演示如何使用位带操作控制 GPIO 输出和实现共享变量。

4.1 定义位带地址转换宏

通常,芯片厂商的库或示例代码会提供类似下面的宏,方便程序员计算别名地址。

// 位带区基地址#definePERIPH_BASE0x40000000UL#defineSRAM_BASE0x20000000UL// 别名区基地址#definePERIPH_BB_BASE0x42000000UL#defineSRAM_BB_BASE0x22000000UL// 转换宏:将位带区地址和位号转换为别名地址#defineBITBAND(addr,bitnum)((addr&0xF0000000)+0x02000000+((addr&0x000FFFFF)<<5)+(bitnum<<2))// 另一种常见写法(适用于外设和SRAM)#defineBITBAND_PERIPH(addr,bitnum)(PERIPH_BB_BASE+((addr-PERIPH_BASE)*32)+(bitnum*4))#defineBITBAND_SRAM(addr,bitnum)(SRAM_BB_BASE+((addr-SRAM_BASE)*32)+(bitnum*4))// 通过别名地址访问位#defineBITBAND_REG(addr,bitnum)(*((volatileunsignedlong*)(BITBAND(addr,bitnum))))

代码解释

4.2 应用示例:操作 GPIO 输出

假设某芯片的 GPIOA 端口输出数据寄存器地址为GPIOA_ODR,我们想单独设置第 5 脚为高电平。

// 传统方式(非原子)GPIOA->ODR|=(1<<5);// 读-改-写// 位带方式(原子)#defineGPIOA_ODR_BIT5BITBAND_REG((uint32_t)&GPIOA->ODR,5)GPIOA_ODR_BIT5=1;// 直接置位

代码解释

4.3 应用示例:共享变量标志位

在 RTOS 中,任务之间常用标志位通信。如果标志位存储在 SRAM 中,可以使用位带操作确保原子性。

// 定义一个在 SRAM 中的标志变量volatileuint32_tg_flags__attribute__((at(0x20001000)));// 指定地址,方便计算// 定义第 3 位的别名#defineFLAG_BIT3BITBAND_SRAM((uint32_t)&g_flags,3)// 任务 A 设置标志voidTaskA(void){FLAG_BIT3=1;// 原子置位}// 任务 B 清除标志voidTaskB(void){FLAG_BIT3=0;// 原子清零}// 中断服务程序查询标志voidISR_Handler(void){if(FLAG_BIT3){// 原子读取(返回 0 或 1)// 处理事件}}

代码解释


5. 深入分析:位带操作的原子性本质与局限

5.1 原子性的硬件实现

位带操作的原子性来源于:

因此,即使 CPU 支持中断,在硬件层面,位带操作是不可被其他总线访问打断的。

5.2 位带操作的适用场景

5.3 局限性

5.4 与 CMSIS 标准的关系

ARM 的 CMSIS-Core 提供了__BIT_BAND()宏和__LDREXB/__STREXB等指令,但位带操作是 Cortex-M3/M4 特有的,Cortex-M0/M0+ 不支持。因此,在可移植代码中,应谨慎使用。


6. 总结

位带操作是 Cortex-M3 内核提供的一项精巧的硬件特性,其本质可以归纳为:

  1. 地址映射的原子操作:通过将每个位映射到一个独立的字地址,将对位的操作转化为对字的操作,并在硬件层面保证原子性。
  2. 简化并发控制:在多任务或中断环境中,位带操作可以避免传统读-改-写带来的竞态风险,无需额外加锁。
  3. 提高代码可读性:通过宏定义别名,代码可以直接表达“置位某位”的意图,更加清晰。
  4. 性能优化:相比使用指令进行位操作(如BICORR),位带操作在某些情况下可以减少指令数量,但主要优势在于原子性和便利性。

理解位带操作,不仅能让你写出更健壮的底层驱动,也能帮助你深入理解 Cortex-M 内核的总线架构和原子性设计思想。在实际开发中,合理利用位带操作,可以显著提高代码的可靠性和效率。

希望这次的深度剖析能让你对位带操作有更本质的认识。如果你还有其他疑问,欢迎继续探讨!

http://www.jsqmd.com/news/507525/

相关文章:

  • 商店盗窃行为破窗行为商品安防检测数据集VOC+YOLO格式2173张1类别
  • 2026环保合规纸塑染料助剂优质厂家推荐 - 资讯焦点
  • Qwen3.5-9B图文对话精彩案例:上传电路图问原理、传PPT页问逻辑漏洞
  • 免费获取乡镇级GeoJson边界数据的3种实用方法
  • 气熙B7空气净化器电话查询:使用前需了解的关键注意事项 - 品牌推荐
  • 长寿命检测开关的新选择:ALPS SPVT210101 VS 国产替代 TONEVEE KFC-VT-318BY 高达2万次寿命
  • 履霜坚冰,龙战于野:当权力失去约束,欲望成为人性的灾难
  • AES算法解剖课:用MATLAB逐行还原字节代换/行位移的数学之美
  • PyTorch中autograd.Function.apply的5个实战技巧(附自定义ReLU实现)
  • Acme .NET 工具类库:一站式解决.NET开发高频场景问题
  • 室内要素识别建筑物内部地面墙壁天花板识别分割数据集labelme格式1031张3类别
  • 2026年消防桥架厂家推荐:防火/镀锌/大跨度/节能桥架专业供应商精选——郑州畅通机电有限公司 - 品牌推荐官
  • 2026 SRM 系统深度测评:鲸采云凭自定义适配多行业采购场景
  • 2024年Java vs Go vs Python:企业级开发选谁更香?实战代码对比
  • [特殊字符] 当 AI 拥有「过目不忘」:OpenClaw 记忆系统完全指南
  • 2026年无锡抖音代运营TOP5名单出炉,行业格局数据公布 - 精选优质企业推荐榜
  • 郑州私人订制月子服务哪家? - 中媒介
  • 深度学习实战:LSTM与Attention机制融合优化城市交通流量预测
  • **reZonator**软件使用教程
  • 三角算法 200 刻度有规律
  • 日本三井NMN和其他高纯NMN相比,真正差异不只在数字 - 资讯焦点
  • ANSYS Workbench模态仿真入门:5步搞定方形薄板自由边界振动分析
  • Python 之获取安装包所占用磁盘空间大小
  • OpenVINO实战:从模型部署到边缘计算性能优化
  • DCT-Net风格迁移:从名画到卡通
  • 郑州郑东新区产后修养哪里找? - 中媒介
  • 2026年聚氨酯砂浆地坪厂家推荐:食品/医药/电子/车库地坪工程用水性聚氨酯砂浆自流平供应商精选 - 品牌推荐官
  • AI原生应用领域自然语言处理的技术突破
  • 2026年线路抢修场景电缆头产品深度评测报告 - 资讯焦点
  • MATLAB图像处理:精准截取目标区域的imcrop实战指南