个人网站用什么域名好,盐城网站开发厂商,一个logo设计要多少钱,自己网站做虚拟币违法吗在上一节内存屏障指令之DMB、DSB和ISB详解中#xff0c;介绍了一下内存屏障的三个指令的作用并举了一些例子#xff0c;对于内存屏障指令的使用时机#xff0c;与处理器架构(比如Cortex-M和Cortex-A)和处理器的系统实现(同样的架构#xff0c;有不同的实现#xff0c;如ST…在上一节内存屏障指令之DMB、DSB和ISB详解中介绍了一下内存屏障的三个指令的作用并举了一些例子对于内存屏障指令的使用时机与处理器架构(比如Cortex-M和Cortex-A)和处理器的系统实现(同样的架构有不同的实现如STM32、NXP都有基于Cortex-M4的单片机)都有关系。
本节将通过20个例子继续深入理解内存屏障主要从以下两方面来介绍 1处理器架构要求指在硬件体系结构中定义的规范和要求。它描述了处理器的指令集、寄存器、中断控制、内存访问、流水线结构等硬件特性。这些规范通常由处理器设计者或者架构定义组织(如ARMx86等)确定。架构要求是通用的适用于所有基于该架构的处理器。
2系统实现要求指在具体处理器实现中根据架构要求来实现这些规范的具体方法。每个处理器制造商可以根据架构规范设计和生产自己的处理器但他们的实现必须遵循架构规范。实现要求可能因处理器型号、版本和制造商而异。 文章目录 1 内存中普通数据的访问2 设备(外设)间的访问3 位带访问4 SCS外设访问5 通过NVIC使能中断6 通过NVIC关闭中断7 用CPS和MSR指令使能中断8 用CPS和MSR指令关闭中断9 禁用外设中断10 更改中断的优先级11 向量表配置-VTOR12 向量表条目配置13 内存映射的改变14 进入睡眠模式15 自启16 CONTROL寄存器17 MPU编程18 多主系统19 信号量和互斥锁(单核和多核)20 自修改代码总结 1 内存中普通数据的访问
这种情况下没有必要在每次内存访问之间都使用内存屏障
处理器架构只要不影响程序的运行处理器就可以对数据传输重新排序系统实现在Cortex-M处理器中数据传输是按照编程的顺序进行的
2 设备(外设)间的访问
在外设编程或外设访问期间不需要在每一步之间使用内存屏障指令
处理器架构对同一设备的访问必须按照程序的顺序进行系统实现Cortex-M处理器不会重排序数据传输
如果编程顺序涉及许多不同的设备
处理器架构当访问不同的设备并且两个设备之间的编程顺序可能影响结果时需要内存屏障。这是因为总线结构可能具有通往每个设备的不同总线分支并且不同总线分支可能具有不同的延迟。系统实现Cortex-M处理器不会对数据传输进行重新排序因此当访问不同的设备时不需要内存屏障
3 位带访问
Cortex-M3和Cortex-M4处理器上的位带访问是一个特殊的特性。它可以让内存映射的两个部分成为位可寻址的
处理器架构位带特性不是ARMv7或ARMv6体系结构的一部分因此对于使用内存屏障进行位带访问没有体系结构定义的要求系统实现Cortex-M3和Cortex-M4处理器处理位带访问、位带区域以及位带别名区域以编程顺序。没有必要使用内存屏障
ARM Cortex-M0和Cortex-M0处理器没有位带特性。可以使用bus wrapper向Cortex-M0和Cortex-M0处理器添加位带特性。在这种情况下bus wrapper必须保持正确的内存顺序。
4 SCS外设访问
SCS外设访问例如NVIC和调试访问通常不需要使用内存屏障指令:不需要在每个SCS访问之间插入内存屏障指令也不需要在SCS访问和设备内存访问之间插入内存屏障指令。 处理器架构SCS所在的内存区域的MPU默认配置为强有序自带DMB的作用如下图所示 系统实现不需要在每个SCS访问之间插入内存屏障指令也不需要在SCS访问和设备内存访问之间插入内存屏障指令
处理器架构要求
如果需要立即看到SCS寄存器写入的效果则需要DSB不需要在相邻的两次访问SCS之间添加内存屏障指令如果下一条指令必须在前一条指令产生作用后执行此时需要调用DSB指令例子如下
SCB-SCR | SCB_SCR_SLEEPDEEP_Msk; /* Enable deepsleep */
__DSB(); /* Ensure effect of last store takes effect */
__WFI(); /* Enter sleep mode */
---------------------
void Device_IRQHandler(void) {software_flag 1; /* Update software variable used in thread */SCB-SCR ~SCB_SCR_SLEEPONEXIT_Msk; /* Disable sleeponexit */__DSB(); /* Ensure effect of last store takes effect */return;
}注意当程序访问的是Normal内存时SCS访问时系统架构层面的DMB不能保证内存排序。如果程序的操作依赖于对SCS的访问与对普通内存的访问之间的顺序那么就需要使用内存屏障指令比如DMB或DSB。下面是一个例子
STR R0, [R1] ; Access to a Normal Memory location
DMB ; Add DMB ensures ordering for ALL memory types
STR R3, [R2] ; Access to a SCS location
DMB ; Add DMB ensures ordering for ALL memory types
STR R0, [R1] ; Access to a Normal Memory location如果[R1]指向的是设备内存区域或强有序内存区域则不需要DMB
系统实现要求 在现有的Cortex-M处理器中忽略DMB或DSB指令不会导致错误因为这些处理器中的SCS已经包含DSB行为
在Cortex-M0、M0处理器中这种行为在访问完成后立即发生。在SCS访问后并不严格要求DSB。在Cortex-M3和M4处理器中内存屏障的作用在访问SCS后立即生效。对于SCS内存的访问除了特殊情况下的SLEEPONEXIT更新外通常不严格要求使用DSB指令。 如果异常处理程序在异常返回之前禁用了SCS中的SLEEPONEXIT特性则在SCR写入之后在异常返回之前需要DSB指令。参考前面的Device_IRQHandler例子。
看一下在系统实现层面对SCS访问的表现 图中说得很清楚每次访问SCS(包括NVIC)都具有对设备/强序访问的自动添加数据同步屏障DSB的连带作用。所以对于前面处理器架构要求中的例子DSB可以去掉
SCB-SCR | SCB_SCR_SLEEPDEEP_Msk; /* Enable deepsleep */
__WFI(); /* Enter sleep mode */注意
现有的Cortex-M处理器不会重新排序任何数据传输因此不需要使用DMB指令对于Cortex-M3和Cortex-M4处理器如果SCS加载/存储后的指令是NOP指令或者是条件失败(condition failed)指令则NOP指令或条件失败指令可以与SCS加载/存储指令并行执行
5 通过NVIC使能中断
通常NVIC操作不需要使用内存屏障指令代码如下所示
device_config(); // Setup peripheral
NVIC_ClearingPending(device_IRQn); // clear pending status
NVIC_SetPriority(device_IRQn, priority); // set priority level
NVIC_EnableIRQ(device_IRQn); // Enable interrupt当一个中断事件发生时它可以先进入pending状态而不管中断是否使能
前面有提到从架构上看每次访问SCS(NVIC属于SCS)时对于设备内存或强有序内存的访问访问相邻两次的操作之前都会插入DMB。 而从Cortex-M处理器的系统实现来看每次访问SCS(NVIC属于SCS)时对于设备内存或强有序内存的访问访问相邻两次的操作之前都会插入DSB。 对于Cortex-M处理器来说由于其流水线特性如果中断已经处于挂起状态处理器可以在执行中断服务程序之前在NVIC中启用中断后执行最多两个额外的指令。如下图所示 处理器架构要求 不同的应用有不同的要求
在一般的NVIC操作中无需使用内存屏障NVIC和外设之间的操作间无需使用内存屏障如果一个已经挂起的中断需要在使能NVIC后马上被响应需要添加一个DSB紧接着还要添加一个ISB
如果中断后的指令依赖于挂起的中断的结果就应该添加内存屏障指令。处理中断的例子如下所示
LDR R0, 0xE000E100 ; NVIC_SETENA address
MOVS R1, #0x1
STR R1, [R0] ; Enable IRQ #0
DSB ; Ensure write is completed
; (architecturally required, but not strictly
; required for existing Cortex-M processors)
ISB ; Ensure IRQ #0 is executed
CMP R8, #1 ; Value of R8 dependent on the execution
; result of IRQ #0 handler如果省略了上面的内存屏障指令CMP将在中断发生之前执行如下图所示 系统实现要求 不同的应用有不同的要求
在一般的NVIC操作中无需使用内存屏障如果一个已经挂起的中断需要在使能NVIC后马上被响应需要添加一个ISB指令
注意由于对NVIC(SCS)的访问本身就具有DSB内存屏障因此省略DSB指令仍然可以立即识别已启用和挂起的中断。
6 通过NVIC关闭中断
由于Cortex-M的流水线架构可以在进入中断序列(中断事件发生时处理器执行的一系列操作和指令)的同时写入NVIC来禁用中断。因此中断处理程序有可能会在NVIC禁用中断后立即执行。 处理器架构要求 根据不同的应用需求需要使用内存屏障
在禁用IRQ时一般的NVIC编程不需要使用内存屏障在NVIC编程与外设编程之间也不需要使用内存屏障如果需要确保在NVIC禁用中断后不会触发中断可以添加DSB指令然后再添加ISB指令
下面是一个切换中断处理函数(修改向量表)的例子
#define MEMORY_PTR(addr) (*((volatile unsigned long *)(addr)))NVIC_DisableIRQ(device_IRQn);
__DSB();
__ISB();
// Change vector to a different one
MEMORY_PTR(SCB-VTOR0x40(device_IRQn2))(void) device_Handler;系统实现要求 根据不同的应用需求需要使用内存屏障
在正常的NVIC编程中禁用IRQ时不需要使用内存屏障在NVIC编程和外设编程之间也不需要使用内存屏障如果需要确保在NVIC禁用中断后不会触发中断可以添加ISB指令
7 用CPS和MSR指令使能中断
在正常的应用程序中在使用CPS指令启用中断后不需要添加任何屏障指令
_enable_irq(); /* 实际上是执行CPSIE I来清除PRIMASK */如果一个中断已经处于挂起状态在调用CPSIE I后处理器将处理该中断。然而在处理器进入异常处理程序之前可能会执行额外的指令
对于Cortex-M3或Cortex-M4处理器在进入中断服务程序之前最多可以执行两条额外的指令对于Cortex-M0处理器在进入中断服务程序之前最多可以执行一条附加指令
如下图所示 处理器架构要求
如果有必要确保在执行后续操作之前识别到挂起的中断则应该在CPSIE i之后使用ISB指令如下图所示 在两个临界区任务之间如果你希望允许一个挂起的中断发生可以使用ISB指令来实现。代码如下所示
__enable_irq(); // CPSIE I : Enable interrupt
__ISB(); // Allow pended interrupts to be recognized
__disable_irq(); // CPSID I : Disable interrupt还有一个典型的例子是 时序图如下
当使用MSR指令启用中断时要求同上
系统实现要求 在Cortex-M处理器中
如果有必要确保在执行后续操作之前识别挂起的中断则应该在CPSIE i之后使用ISB指令。这与处理器架构要求相同有一个例外是CPSIE后面跟着CPSID但在Cortex-M处理器中可以不用在CPSIE和CPSID之间插入ISB。代码如下
时序图如下
在系统实现需求中不需要在__enable_irq()和__disable_irq()之间添加内存屏障指令。但是在处理器架构要求中如果需要在CPSIE和CPSID指令之间识别中断则需要使用ISB指令。
当使用MSR指令启用中断时要求同上 根据处理器架构要求在某些情况下如果需要确保中断能够在正确地被识别则需要添加ISB指令。这是因为在一些特定的处理器架构中中断的使能和禁用可能需要额外的同步来保证其正确性。因此根据架构要求使用ISB指令是一种确保正确行为的方法。在系统实现要求中未添加内存屏障的情况下这个操作在特定架构中已经被合理地处理了因此不需要额外的内存屏障。在刚刚的代码中根据具体的系统实现要求它并不需要在__enable_irq()和__disable_irq()之间添加内存屏障指令。这意味着在特定的处理器实现中中断使能和禁用的操作已经在硬件层面上得到了适当的同步无需额外的内存屏障指令。 8 用CPS和MSR指令关闭中断
CPSID指令在指令流中自我同步无需在CPSID之后插入内存屏障指令。 处理器架构要求 无需使用内存屏障。
系统实现要求 无需使用内存屏障。
当使用MSR指令关闭中断时要求同上
9 禁用外设中断
当在外设上禁用一个中断时由于系统中存在多种可能的延迟源可能需要额外的时间。下图显示了多种不同的延时源 即使在禁用外设之后也可能会在短时间内收到来自禁用外设的中断请求。
处理器架构要求 无要求一切由下面的系统实现要求决定。
系统实现要求 延迟取决于设备。对于大多数情况如果IRQ同步器中的延迟很小可以使用以下步骤来禁用中断
通过写入其控制寄存器CONTROL来禁用外设中断读取外设的控制寄存器以确保其已更新在NVIC中禁用IRQ清除NVIC中的IRQ挂起状态读取IRQ挂起状态。如果IRQ挂起被设置了清除外设中的IRQ状态然后再次清除NVIC中的IRQ挂起状态。必须重复此步骤直到NVIC IRQ挂起状态保持清除。
这个步骤序列适用于大多数简单的微控制器设备可以成功地禁用中断。然而由于系统内可能发生的各种延迟因素建议联系芯片供应商或制造商获取支持。
10 更改中断的优先级
优先级的设置由SCS中NVIC的Priority Level寄存器决定。对于Cortex-M3或Cortex-M4处理器优先级级别可以动态地进行更改。然而对于ARMv6-M处理器例如Cortex-M0或Cortex-M0不支持对已启用的中断或异常的优先级进行动态更改。在启用中断之前就应该设置优先级。
处理器架构要求 由于SCS是强有序内存所以NVIC配置不需要内存屏障。但是在更改中断优先级后如果中断已启用并且需要中断按照新的优先级级别执行应该在其后插入DSB和ISB指令。
注意在ARMv6-M处理器上只有在中断被禁用时才应该更改中断的优先级级别否则结果是不可预测的
如果下一个指令是CPSIE或MSR根据处理器架构要求应该插入一个DSB指令然后再插入一个ISB指令(如果想让一个挂起的中断马上被识别到就调用ISB否则可以不调用)。这样的操作顺序可以确保中断状态的正确切换和指令的顺序执行以防止中断状态的不一致或指令乱序执行问题。
系统实现要求 在Cortex-M处理器中访问中断优先级寄存器本身就有DSB屏障了因为SCS是强有序内存。在Cortex-M3或Cortex-M4处理器中
如果需要立即识别优先级的更改需要使用ISB指令如果不需要在随后的操作之前立即识别优先级的更改则不需要插入内存屏障指令如果下一个操作是SVC异常则不需要插入内存屏障指令 对于Cortex-M3或Cortex-M4处理器如果优先级级别的更改可能导致新的中断嵌套(比当前正在执行的中断优先级高)并且我们希望立即执行此中断则需要插入ISB指令。否则由于流水线的原因最多可能会多执行两条指令。
11 向量表配置-VTOR
在Cortex-M3和Cortex-M4处理器中向量表的位置由SCS中VTOR(Vector Table Offset Register)的设置决定。
处理器架构要求 从架构上讲在更改VTOR后如果要立即产生异常并使用最新的向量表设置则应该使用DSB指令。 系统实现要求 在Cortex-M3、Cortex-M4和Cortex-M0处理器中对SCS的访问本身就具有DSB屏障因此不需要插入DSB指令。
Cortex-M0处理器没有VTOR
12 向量表条目配置
这里指的是更新向量表中的各个条目(entry)。
处理器架构要求 如果向量表位于RAM(如SRAM/SDRAM)中无论是通过VTOR重新定位还是通过设备相关的内存重映射机制进行重新定位从架构上讲在更新向量表条目后如果要立即使能异常则需要使用内存屏障指令。如下图所示 如果下一条指令是访问RAM则还需要一个DMB指令 也就是说如果向量表保存在普通内存而不是强有序内存中需要考虑内存屏障操作。 系统实现要求 在Cortex-M处理器中省略DSB或DMB指令在修改向量条目时不会引发任何问题因为异常条目序列在最后一个内存访问完成之前不会启动。
13 内存映射的改变
许多微控制器都包含了一种特定于设备的内存重映射功能允许在运行时通过编程配置寄存器来更改内存映射这个寄存器应放置在设备内存(device memory)中。在更改内存映射配置期间是否需要内存屏障指令取决于以下因素
受影响的内存空间是否涵盖程序代码即是否包括指令。处理器与内存配置寄存器之间的特定于设备的数据路径例如写缓冲区(CPU和寄存器之间需要经过写缓冲区)。 处理器架构要求 这里讨论的要求适用以下条件除了处理器内部的任何内部写缓冲区外没有影响内存重映射控制寄存器的设备特定写缓冲区内存映射切换中没有额外的硬件延迟
从架构上讲在进行内存映射更改的前后应该插入内存屏障指令
... ; application code before switching
DSB ; Ensure all memory accesses are completed
STR remap, [remap_reg] ; Write to memory; map control register
DSB ; Ensure the write is completed
ISB ; Flush instruction buffer (optional, only required if
; the memory map change affects program memory)
... ; application code after switching如果受影响的内存没有在任何程序代码中使用则在内存映射更改后需要插入DSB指令但可以省略ISB指令。 系统实现要求 这里讨论的要求同样适用以下条件
除了处理器内部的任何内部写缓冲区外没有影响内存重映射控制寄存器的设备特定写缓冲区内存映射切换中没有额外的硬件延迟
在Cortex-M处理器中
在进行内存映射更改之前不需要DSB或DMB指令因为这些处理器不允许两个写操作序列重叠在重映射后需要进行DSB然后ISB的序列以确保使用最新的内存映射获取程序代码 在这个案例研究中做出了两个假设。如果这些假设无效例如如果处理器与内存控制寄存器之间的数据路径包含额外的系统级写缓冲区那么内存屏障指令不能保证传输完成。在这种情况下
可以从先前访问的区域执行读取操作以确保写缓冲区被清空。如果已向系统的各个部分发出了多个写传输可能需要多次读取操作以确保所有写缓冲区都被清空。或者微控制器或SoC可能具有状态寄存器指示是否存在任何正在进行的传输并在内存重映射完成时进行通知。如果需要这允许程序代码考虑内存重映射逻辑上的额外硬件延迟。
具体的差异还是得详细咨询不同芯片制造商。 14 进入睡眠模式
在Cortex-M处理器中可以使用WFI和WFE指令进入睡眠模式。
处理器架构要求 从架构上来说应该在执行WFI或WFE指令之前使用DSB指令
系统实现要求 对于不包含系统级写缓冲区的简单设计在进入Cortex-M3(r2p0或更高版本)、Cortex-M4、Cortex-M0和Cortex-M0处理器的睡眠模式之前不需要使用内存屏障指令。这由处理器自身处理。如果内部总线包含一个位于处理器之外的系统级写缓冲区则情况就更复杂了。在这种情况下仅使用DSB指令可能是不够的因为系统控制逻辑可能会在缓冲写完成之前关闭时钟。 时钟信号被关闭可能不会导致错误这取决于系统级设计、使用的休眠操作以及进入休眠模式前正在访问的外设。建议联系芯片供应商或制造商获取设备详细信息。通常可以通过向写缓冲器添加一个虚拟读操作以确保写缓冲器被清空来解决这个问题。下图显示了一个可能的解决方法
15 自启
Cortex-M处理器具有自启(self-reset)功能。可以通过AIRCR寄存器中的SYSRESETREQ位触发系统复位。在CMSIS库中可以使用C函数NVIC_SystemReset(void)来使用这个功能。
处理器架构要求 在自启之前需要使用DSB指令来确保所有未完成的传输都已完成同时可以使用CPSID I关闭中断这个是可选的它可以防止在自启过程中触发一个已启用的中断请求。 系统实现要求 在Cortex-M处理器上如果没有使用CPSID指令DSB指令是可选的。因为对SCS的访问已经具有DSB屏障在写操作完成之前自启无法开始。如下图所示 如果使用了CPSID指令则应插入DSB指令以确保CPSID在前一个传输完成后才执行。这样如果前面的传输有导致imprecise bus fault它会在禁用中断之前发生。
在ARMv6-M上没有bus fault异常因此在Cortex-M0处理器上不可用 如果系统在总线级别存在写缓冲区时可以通过在写缓冲区中进行虚拟读操作来确保在执行CPSID指令和进行自启之前系统级别的写缓冲区已被清空。如下图所示 如果你使用的是CMSIS 2.0或更高版本则NVIC_SystemReset(void)函数已经包含了DSB指令。
16 CONTROL寄存器
CONTROL寄存器是Cortex-M处理器中实现的特殊寄存器之一它可以通过MSR和MRS指令访问。
处理器架构要求 从架构上来说在修改CONTROL寄存器后应使用ISB指令。 下面是一个从特权执行切换到非特权执行的代码。
Cortex-M0中不支持此操作
MOVS R0, #0x1
MSR CONTROL, R0 ; Switch to non-privileged state
ISB ; Instruction Synchronization Barrier
...ISB确保以正确的特权级别取指如下图所示 我们还可以使用CONTROL寄存器来选择在线程模式下使用哪个堆栈指针。
系统实现要求 在Cortex-M处理器中写入CONTROL寄存器后不执行ISB指令不会导致程序错误除非你更改特权级别且之前的权限级别已经预取接下来的指令。当且仅当你需要使用正确权限级别获取后续指令时才需要ISB指令。
17 MPU编程
MPU是Cortex-M0、Cortex-M3和Cortex-M4处理器的可选功能。
处理器架构要求
MPU配置寄存器位于SCS中因此在MPU编程的每个步骤之间不需要插入内存屏障指令强有序内存不会强制执行与正常内存访问相关的顺序。 在架构设计中MPU编程序列之前需要执行DMB以及在MPU编程完成后使用DSB来确保所有设置都被所有的总线可见如果MPU设置的更改影响程序内存还应添加一个ISB指令以确保使用更新的MPU设置重新获取指令
如果在异常处理程序中执行MPU编程步骤则不需要ISB指令因为异常进入和退出边界已经具有ISB。例如在运行RTOS的应用程序中可以在PendSV异常处理程序内进行上下文切换期间更新用户线程的MPU区域设置。在PendSV和用户线程之间切换异常退出序列确保MPU设置生效。这适用于当前Cortex-M处理器的架构行为和系统实现。
系统实现要求
在Cortex-M0、Cortex-M3和Cortex-M4处理器上在进入MPU编程代码之前省略DMB指令不会引起问题在完成MPU编程代码之后省略DSB指令也不会引起问题。如果对MPU设置的更改只影响保存数据的内存而不影响保存程序内存则在Cortex-M处理器上不需要ISB指令。如果需要使用新的MPU设置来取后续指令则需要ISB指令。
18 多主系统
如果你希望你的代码在多个系统中都能正常运行即考虑代码在不同架构下的可移植性那么使用内存屏障指令是很有必要的。
处理器架构要求 当处理共享数据并且需要确保它们在内存中的顺序不被改变或混乱时需要使用DMB或DSB指令。例如则在启动DMA操作之前需要使用DMB指令。
也可以使用DSB代替DMB 如果没有DMB在架构上两个存储区可能会被重新排序或重叠比如DMA可能在数据更新完成之前开始。另一个多主机示例是两个处理器之间共享内存中的信息通信。当向在不同处理器上运行的另一个程序传递数据时通常会将数据写入共享内存然后在共享内存中设置一个软件标志。在这种情况下应使用DMB或DSB指令来确保两个内存访问之间的内存顺序正确 两个处理器之间的交互不限于共享内存。另一种可能的交互方式是事件通信(如消息队列)。在这种情况下可能需要使用DSB指令来确保内存传输和事件之间的正确顺序被保留。
系统实现要求 在前面处理器架构要求的前两张图中去掉DMB或DSB指令时并不会产生错误因为Cortex-M处理器不会重新排序内存传输且不允许两个写传输重叠执行。
在Cortex-M3和Cortex-M4处理器中处理器架构要求中的最后一张图需要使用DSB指令。但在Cortex-M0处理器中省略DMB或DSB指令不会导致这三个示例中的任何错误因为Cortex-M0处理器中没有写缓冲区。
19 信号量和互斥锁(单核和多核)
信号量和互斥量操作在许多操作系统中是必不可少的。它们可以在单处理器环境或多处理器环境中使用。
在多处理器环境中信号量操作需要将软件变量放置在多个处理器之间共享内存中。为了确保正确的操作应该使用内存屏障指令。如果在多处理器系统中存在缓存则必须确保使用正确的缓存配置以使共享内存中的数据在所有处理器之间一致。
处理器架构要求 在信号量和互斥量操作中应使用DMB指令。下面的例子展示了获取锁的简单代码获取锁后需要使用DMB指令
/* Note: __LDREXW和__STREXW是CMSIS函数 */
void get_lock(volatile int *Lock_Variable)
{ int status 0;do {while (__LDREXW(Lock_Variable) ! 0); // Wait until Lock_Variable is freestatus __STREXW(1, Lock_Variable); // Try to set Lock_Variable} while (status!0); //retry until lock successfully__DMB();return;
}同样地释放锁的代码在开始时应该有一个内存屏障
void free_lock(volatile int *Lock_Variable)
{__DMB(); // Ensure memory operations completed beforeLock_Variable 0;// releasing lockreturn;
}这样做是为了避免在释放锁之前由于流水线的原因其它线程就“提前”释放了锁从而可以访问共享资源。
系统实现要求
在使用Cortex-M3和Cortex-M4处理器的微控制器设备上在信号量和互斥操作中省略DMB指令不会导致错误。但在下面的情况下可能会出错
处理器具有缓存软件在多核系统中使用。
ARM建议在操作系统设计中的信号量和互斥操作中使用DMB指令。
Cortex-M0和Cortex-M0处理器没有互斥访问的指令
20 自修改代码
通常我们的代码是静态的不能被修改。但其实允许程序在运行时修改自己的代码修改之后的代码会被立即执行从而改变代码的行为。这种情况一般用于反作弊(提高程序的复杂性和安全性)、加密和解密(提高数据安全性)。
如果程序包含自修改代码如果修改后的程序代码要在修改后不久执行就需要使用内存屏障。由于程序代码可以被预取应该执行DSB指令然后执行ISB指令以确保流水线被刷新。
处理器架构要求 架构需求是在修改程序内存后使用DSB指令后紧跟一个ISB指令。
STR new_instr, [inst_address1]
DSB ; Ensure store is completed before flushing pipeline
ISB ; Flush pipeline
B inst_address1 ; Execute updated program下图显示了满足自修改代码的处理器架构和实现要求所需的内存屏障指令。 如果系统中存在缓存则应该缓存刷新操作来确保更新指令缓存。
系统实现要求 总的来说在修改程序内存后需要先使用DSB然后使用ISB。如果处理器或系统中没有写缓冲区或缓存例如基于Cortex-M0的微控制器则可以省略DSB。
Cortex-M3和Cortex-M4处理器可以预取多达六条指令。如果应用程序在修改程序内存中的指令后不久执行该指令可能会使用之前的指令。如果指令在修改后一段时间内未使用程序可能可以正常工作但不能完全保证。
某些Cortex-M3和Cortex-M4设计可能具有特定于实现的程序缓存以加速程序存储器访问。在修改程序代码后可能需要额外的步骤来确保程序缓存被清除。
总结
在ARM体系架构中内存屏障是一种用来确保程序在多核或多线程环境下按照预期顺序执行的机制。ARM定义了三种内存屏障指令分别是DMB(数据内存屏障)、DSB(数据同步屏障)和ISB(指令同步屏障)。
DMB指令用于确保内存访问的顺序性。在多核处理器中不同核的缓存可能会引起数据一致性的问题DMB指令在多核之间添加屏障确保指令的执行顺序与内存访问的顺序一致避免数据的读写乱序。
DSB指令用于确保指令的完成和数据的同步。它保证在DSB指令之前的所有指令都已经完成执行然后再执行DSB指令之后的指令。这样可以避免指令的乱序执行和数据的读写乱序确保执行的顺序性。
ISB指令用于确保指令的同步。它会刷新所有的指令缓存和流水线使指令序列的执行从ISB指令之后重新开始。这样可以保证在ISB指令之前的所有指令都已经执行完毕并且清除了所有执行过程中的缓存使得指令的执行结果与预期一致。
综上所述ARM的内存屏障机制通过DMB/DSB/ISB指令确保程序在多核或多线程环境下的正确顺序执行。这些指令提供了内存和指令的同步和顺序性保证保证了程序的正确性和可靠性。 文章转载自: http://www.morning.kyflr.cn.gov.cn.kyflr.cn http://www.morning.ppghc.cn.gov.cn.ppghc.cn http://www.morning.ggfdq.cn.gov.cn.ggfdq.cn http://www.morning.wcgfy.cn.gov.cn.wcgfy.cn http://www.morning.ymmjx.cn.gov.cn.ymmjx.cn http://www.morning.tralution.cn.gov.cn.tralution.cn http://www.morning.dtnjr.cn.gov.cn.dtnjr.cn http://www.morning.yrqb.cn.gov.cn.yrqb.cn http://www.morning.zqmdn.cn.gov.cn.zqmdn.cn http://www.morning.zlgr.cn.gov.cn.zlgr.cn http://www.morning.pwlxy.cn.gov.cn.pwlxy.cn http://www.morning.fbdkb.cn.gov.cn.fbdkb.cn http://www.morning.nhzxr.cn.gov.cn.nhzxr.cn http://www.morning.pffx.cn.gov.cn.pffx.cn http://www.morning.mwzt.cn.gov.cn.mwzt.cn http://www.morning.xkjqg.cn.gov.cn.xkjqg.cn http://www.morning.gppqf.cn.gov.cn.gppqf.cn http://www.morning.qmkyp.cn.gov.cn.qmkyp.cn http://www.morning.rmdsd.cn.gov.cn.rmdsd.cn http://www.morning.rlwcs.cn.gov.cn.rlwcs.cn http://www.morning.nqrlz.cn.gov.cn.nqrlz.cn http://www.morning.ljzgf.cn.gov.cn.ljzgf.cn http://www.morning.rqqn.cn.gov.cn.rqqn.cn http://www.morning.zcyxq.cn.gov.cn.zcyxq.cn http://www.morning.yzfrh.cn.gov.cn.yzfrh.cn http://www.morning.bfrsr.cn.gov.cn.bfrsr.cn http://www.morning.lpmdy.cn.gov.cn.lpmdy.cn http://www.morning.ztqyj.cn.gov.cn.ztqyj.cn http://www.morning.fwnqq.cn.gov.cn.fwnqq.cn http://www.morning.mcwrg.cn.gov.cn.mcwrg.cn http://www.morning.rfgkf.cn.gov.cn.rfgkf.cn http://www.morning.fqlxg.cn.gov.cn.fqlxg.cn http://www.morning.gktds.cn.gov.cn.gktds.cn http://www.morning.pypqf.cn.gov.cn.pypqf.cn http://www.morning.fjmfq.cn.gov.cn.fjmfq.cn http://www.morning.kkdbz.cn.gov.cn.kkdbz.cn http://www.morning.xgmf.cn.gov.cn.xgmf.cn http://www.morning.zlnf.cn.gov.cn.zlnf.cn http://www.morning.bwgrd.cn.gov.cn.bwgrd.cn http://www.morning.xhrws.cn.gov.cn.xhrws.cn http://www.morning.lsfzq.cn.gov.cn.lsfzq.cn http://www.morning.zrfwz.cn.gov.cn.zrfwz.cn http://www.morning.xbdrc.cn.gov.cn.xbdrc.cn http://www.morning.bykqg.cn.gov.cn.bykqg.cn http://www.morning.ktblf.cn.gov.cn.ktblf.cn http://www.morning.lqchz.cn.gov.cn.lqchz.cn http://www.morning.nfbkz.cn.gov.cn.nfbkz.cn http://www.morning.fnfxp.cn.gov.cn.fnfxp.cn http://www.morning.qdbcd.cn.gov.cn.qdbcd.cn http://www.morning.hxxyp.cn.gov.cn.hxxyp.cn http://www.morning.fsrtm.cn.gov.cn.fsrtm.cn http://www.morning.fglxh.cn.gov.cn.fglxh.cn http://www.morning.knjj.cn.gov.cn.knjj.cn http://www.morning.kjyhh.cn.gov.cn.kjyhh.cn http://www.morning.lpbrp.cn.gov.cn.lpbrp.cn http://www.morning.fbccx.cn.gov.cn.fbccx.cn http://www.morning.nmtyx.cn.gov.cn.nmtyx.cn http://www.morning.xqjrg.cn.gov.cn.xqjrg.cn http://www.morning.bloao.com.gov.cn.bloao.com http://www.morning.fwdln.cn.gov.cn.fwdln.cn http://www.morning.qnlbb.cn.gov.cn.qnlbb.cn http://www.morning.mxmdd.cn.gov.cn.mxmdd.cn http://www.morning.cqyhdy.cn.gov.cn.cqyhdy.cn http://www.morning.chehb.com.gov.cn.chehb.com http://www.morning.tdscl.cn.gov.cn.tdscl.cn http://www.morning.mhxlb.cn.gov.cn.mhxlb.cn http://www.morning.ghlyy.cn.gov.cn.ghlyy.cn http://www.morning.xbzfz.cn.gov.cn.xbzfz.cn http://www.morning.kdnrp.cn.gov.cn.kdnrp.cn http://www.morning.daxifa.com.gov.cn.daxifa.com http://www.morning.hdwjb.cn.gov.cn.hdwjb.cn http://www.morning.cxtbh.cn.gov.cn.cxtbh.cn http://www.morning.gwyml.cn.gov.cn.gwyml.cn http://www.morning.drmbh.cn.gov.cn.drmbh.cn http://www.morning.ahlart.com.gov.cn.ahlart.com http://www.morning.lyhrg.cn.gov.cn.lyhrg.cn http://www.morning.lwtld.cn.gov.cn.lwtld.cn http://www.morning.knmby.cn.gov.cn.knmby.cn http://www.morning.daxifa.com.gov.cn.daxifa.com http://www.morning.hkpn.cn.gov.cn.hkpn.cn