ARM基础(6):内存屏障指令之DMB、DSB和ISB详解

这篇具有很好参考价值的文章主要介绍了ARM基础(6):内存屏障指令之DMB、DSB和ISB详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内存屏障是一个通用术语,用于指代一条或多条指令,它们强制处理器在执行加载(load)或存储(store)指令时进行同步事件。ARMv7-M 和 ARMv6-M架构都提供了三个内存屏障指令来支持内存顺序模型。这三个内存屏障指令分别是:DMBDSBISB

1 DMB、DSB和ISB之概述

(1)Data Memory Barrier(DMB):数据内存屏障
主要用于多核处理器系统中,不同的处理器可能同时执行数据内存传输指令。DMB指令确保在DMB之前的所有显式数据内存传输指令都已经在内存中读取或写入完成,同时确保任何后续的数据内存传输指令都将在DMB执行之后开始执行,否则有些数据传输指令可能会提前执行。
(2)Data Synchronization Barrier(DSB):数据同步屏障
在计算机的体系结构中,处理器在执行指令时通常会利用指令流水线来提高性能。但也会产生一些问题,比如在多线程编程中,两个线程同时对共享的内存进行读写操作,由于读/写操作的重排序,就会导致数据的不一致。

当执行DSB指令时,它确保在DSB之前的所有显式数据内存传输指令都已经在内存中读取或写入完成,同时确保任何后续的指令都将在DSB执行之后开始执行。

(3)Instruction Synchronization Barrier(ISB):指令同步屏障
指令的流水线允许处理器同时执行多条指令的不同阶段,然而这样并行执行可能会导致一些问题,特别是涉及到上下文切换的情况,如实时操作系统的任务切换。当上下文切换时,可能指令流水线中的指令还在执行,而此时上下文已经改变,导致指令执行的结果不正确。

通过插入ISB指令,处理器会将流水线中的指令全部刷新,从而确保之前的指令不会影响后续指令的执行,并且后续指令将从正确的上下文开始重新获取。

tips:大多数CPU的体系架构在异常的入口和出口都有ISB的语义(自动执行)
当处理器执行代码时,可能会遇到异常情况,例如中断、系统调用、或者其他外部事件的触发。在这些情况下,处理器需要暂时中止当前的任务,转而处理异常事件,然后再返回到之前的任务继续执行。

具体来说,在进行异常进入之前,处理器会执行ISB操作。这样做的目的是刷新指令流水线,确保异常处理程序的指令是从正确的地址开始执行,避免异常之前的指令对异常处理程序造成干扰。

而在异常处理程序执行完毕后,处理器需要返回到之前被中断的任务继续执行。在进行异常返回之前,处理器同样会执行ISB操作。这样做的目的是刷新指令流水线,确保返回时从正确的地址重新获取指令,避免异常处理程序的指令对正常任务造成干扰。

(4)API
在C语言中,可以使用CMSIS或各种C编译器提供的函数来调用内存屏障指令。

内存屏障 CMSIS函数 MDK-ARM,DS-5和RVDS中集成的C编译器
DMB _DMB() _dmb(0xF)
DSB _DSB() _dsb(0xF)
ISB _ISB() _isb(0xF)
  • 这里的0xF表示指定一个完整系统屏障(Full System Barrier)操作,它将确保读写的屏障操作,适用于芯片内部的内存(如SRAM)和外部的内存(如自己接的HyperRAM),无论该内存是Shareable还是Non-Shareable。

2 三种指令的典型案例

1、DMB
DMB指令保证了两个内存访问能按正确的顺序执行。实际上DMB在Cortex-M的处理器中用得并不多,因为Cortex-M处理器不会重新排序内存事务(Memory transaction)。但如果想要软件能在其他ARM处理器上重用(如Cortex-M移植到Cortex-A),尤其是在多主系统中,DMB是必要的。下面举几个例子:
(1)DMA
在使用DMA控制器时,需要在CPU内存访问和DMA操作之间插入DMB屏障,以确保CPU当前的内存读写操作在DMA开始之前完成。

(2)多核系统中的信号量
在多核系统中,使用信号量进行核间同步。需要使用DMB来强制指定内存执行顺序,以避免潜在的竞态条件或数据不一致性。

当一个核要访问共享资源之前,它会先检查信号量的状态。如果信号量已经被另一个核获取,当前核就必须等待,直到信号量状态变为可用。这个等待过程需要保证在一个核释放信号量之后,其他核能够立即看到信号量状态的变化,而不是因为处理器优化或缓存导致的无效读取而产生错误。

在这里,DMB的作用就是强制执行内存顺序。通过在核获取信号量之前插入DMB屏障,确保在DMB之前的所有内存操作都完成。这样,在一个核释放信号量之后,其他核获取信号量的操作能够看到最新的信号量状态,从而实现正确的同步。

(3)多核系统中的邮箱
类似地,在核之间通过邮箱机制通信时,需要使用DMB来对邮箱的内存访问正确顺序,避免通信问题。

2、DSB
在Cortex-M处理器中,DSB可以用来:
(1) 确保对SCS(System Control Space)的修改在下一条指令执行之前生效

在ARM Cortex-M处理器中,SCS是一个特殊的内存区域,包含了一些系统控制寄存器和配置信息,用于管理处理器和系统的各种功能和特性。访问SCS的寄存器可以影响处理器的行为,例如启用或禁用特定的中断、配置时钟、设置系统控制位等。为了确保对SCS的修改在下一条指令执行之前生效,需要使用DSB指令进行数据同步。

(2)确保在执行特权级指令之前,内存中的数据已经更新
在ARM Cortex-M处理器中,一些特殊的指令如SVC(Supervisor Call,特权级调用)、WFI(Wait For Interrupt,等待中断)、WFE(Wait For Event,等待事件)等操作,涉及到特权级的转换或者等待系统事件发生,需要使用DSB指令。

3、ISB
ISB指令用于清空流水线,确保在ISB指令之前的所有上下文修改操作的效果被后续操作正确识别。有一个很典型的例子:
CONTROL寄存器的修改
在修改CONTROL寄存器后,应该使用ISB指令。比如我们修改CONTROL寄存器中的相关字段以进入特权模式,然后下一行代码就是一些特权操作,在这之前就需要使用ISB指令来让处理器正确识别新的特权级。

3 总结

本文详细说明了DMB、DSB和ISB三个指令的含义和使用时机。但大多数简单处理器不会对内存传输进行重新排序,因此,体系结构的需求和处理器的实现需求是不同的。例如,大多数应用程序可以在现有的Cortex-M处理器上正确运行,而无需使用任何内存屏障指令。

但是,如果要将应用程序移植到高端处理器,则内存屏障指令的遗漏可能会导致应用程序出现故障。如果要将软件移植到具有多个处理器的系统上,内存屏障的使用也很重要。例如,在多处理器系统中处理信号量时,应该使用内存屏障指令来确保系统中的其他处理器能够以正确的顺序观察到数据的变化。

ARM建议软件开发人员基于架构需求开发软件,而不是基于处理器特定的行为。这确保了软件代码的可移植性和可重用性。处理器特定的行为在相同架构的不同的发布版本之间也可能有所不同。文章来源地址https://www.toymoban.com/news/detail-625363.html

到了这里,关于ARM基础(6):内存屏障指令之DMB、DSB和ISB详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ARM汇编寄存器和常用指令详解

    对于32位及其以下的ARM处理器来说,函数调用规则如下: 父函数与子函数的入口参数以此通过 R0~R3 这4个寄存器传递。 父函数在调用子函数前先将子函数入口参数存入 R0~R3 寄存器中,若只有一个入口参数则使用 R0 寄存器传递,若有2个入口参数则使用 R0 和 R1 寄存器传递,以

    2024年02月03日
    浏览(50)
  • ARM LDREX/STREX指令以及独占监控器详解

    Linux驱动开发中有一个特别重要的知识点必须掌握,即并发访问、竞态以及同步。 什么是并发? 多个执行单元(进程、线程、中断) 同时 对一个共享资源进行访问;此处的共享资源可以是外设、内存或者软件层面的全局变量静态变量等;只要并发的多个执行单元存在对共享

    2024年02月09日
    浏览(43)
  • Debug工具Trace32的ARM内存访问类型详解

    关于Trace32的访问类型的基本概念可以参考博文: Trace32使用教程-访问类型(Access Class)_SOC罗三炮的博客-CSDN博客 本文将以ARMv8为基础,详解Trace32的内存访问类型。 内存访问类型 描述 A 绝对寻址(物理地址),即绕过MMU E 运行时访问。(可以由 SYStem.CpuAccess 和SYStem.MemAccess命令来

    2024年02月16日
    浏览(40)
  • ARM hint instruction-WFI(Wait For Interrupt)指令详解

    WFI(Wait For Interrupt)指令是ARM中的一个Hint 指令,内核执行hint指令的时候不需要依赖额外的处理操作。WFI指令可以让CPU进入standby 模式,即低功耗模式,此时内核会暂停其他活动,一直等待中断事件的发生,检测到中断发生后,WFI指令执行完成,CPU退出standby模式。 本文将从ARM

    2024年02月08日
    浏览(32)
  • 【ARM64 常见汇编指令学习 16 -- ARM64 SMC 指令】

    上篇文章:ARM64 常见汇编指令学习 15 – ARM64 标志位的学习 下篇文章:ARM64 常见汇编指令学习 17 – ARM64 BFI 指令 在ARMv8架构中,同步异常主要包括以下几种: Undefined Instruction :未定义指令异常,当处理器尝试执行一条未定义的指令时会触发。 Supervisor Call (SVC) :这是一种特殊

    2024年02月13日
    浏览(44)
  • 【ARM系列】ARM常用汇编指令

    在调试芯片启动代码或者分析ARM core运行流程的过程中,尝尝需要对照软件代码的反汇编文件进行分析,因此有必要掌握一些常用的arm汇编指令。 指令格式:MOV{条件}{S} 目的寄存器,源操作数 指令含义:将源操作数赋值给目的寄存器。源操作数可以是寄存器,立即数或带移位

    2024年02月04日
    浏览(38)
  • 【ARM64 常见汇编指令学习 13 -- ARM 汇编 ORG 伪指令学习】

    上篇文章:ARM64 常见汇编指令学习 12 – ARM 汇编函数 的学习 下篇文章:ARM64 常见汇编指令学习 14 – ARM 汇编 .balign,.balignw,.balign 伪指令学习 在ARM汇编中,\\\" org \\\"是一个汇编器伪指令,用于设置下一条指令的装入地址。\\\" org \\\"后面跟着的是一个表达式,这个表达式的值就是下一条

    2024年02月14日
    浏览(46)
  • 【ARM 常见汇编指令学习 5 -- arm64汇编指令 wzr 和 xzr】

    上篇文章:ARM 常见汇编指令学习 4 – ARM64 比较指令 cbnz 与 b.ne 区别 下篇文章:ARM 常见汇编指令学习 6 - bic(位清除), orr(位或), eor(异或) ARMv8 在硬件层名引入了一个新的 zero 寄存器 : XZR (64-bits), WZR (32-bits)。比如要将某一变量赋值为0x0, 由于ARM不允许直接操作内存单元上的数据

    2024年02月15日
    浏览(79)
  • 【ARM64 常见汇编指令学习 20 -- ARM 指令 .include与 .asciz 详细介绍】

    在 ARM 汇编语言中, .include 命令用于插入另一个源文件的内容。它的作用类似于 C 语言中的 #include 预处理命令。这个命令通常在源文件的顶部使用,但也可以在任何地方使用。 语法如下: 这里的 \\\"filename\\\" 是你想要包含的文件名。这个文件名可以是绝对路径,也可以是相对于

    2024年02月11日
    浏览(53)
  • 【ARM 常见汇编指令学习 3 -- ARM64 无符号位域提取指令 UBFX】

    上篇文章:ARM 常见汇编指令学习 2 – 存储指令 STP 与 LDP 下篇文章:ARM 常见汇编指令学习 4 – ARM64 比较指令 cbnz 与 b.ne 区别 在代码中如何监控寄存器的某1bit, 或者某几bit ? ARM 提供了一个汇编指令:UBFX 就可以用于该功能。 UBFX 有2种语法分别是对32bit 寄存器和64bit寄存器。

    2024年02月15日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包