ARM Cortex-M 内存访问
ARM Cortex-M memory access
来自 Cortex-M0+ Devices Generic User Guide 关于内存区域-
2.2.1. Memory regions, types and attributes
Strongly-ordered:
The processor preserves transaction order relative to all other transactions.
和-
Address range:
0xE0000000- 0xE00FFFFF
Memory region: Private Peripheral Bus
Memory type: Strongly- ordered
Description: This region includes the NVIC, System timer, and System Control
Block. Only word accesses can be used in this region.
现在,从CMSIS documentation-
#define __DMB()
Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
根据以上信息,似乎在访问 0xE0000000- 0xE00FFFFF
内存地址范围的代码中,例如 NVIC
控制器和 SysTick
配置寄存器,我确实不需要使用 __DMB
因为它实际上是由硬件执行的。
因此,例如,如果我们查看 __NVIC_EnableIRQ
-
/**
\brief Enable Interrupt
\details Enables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
}
它不包含 __DMB()
(也没有 __DSB()
或 __ISB()
),所以如果我启用中断 X,然后启用中断 Y,操作之间没有障碍-
NVIC_EnableIRQ(X); /* Note: __NVIC_EnableIRQ is defined as NVIC_EnableIRQ */
NVIC_EnableIRQ(Y);
是否承诺 HW 不会重新排序内存访问并会在中断 Y 之前启用中断 X(假设编译器确实将函数实现为内联)?
Is it promised that the HW will enable interrupt X before interrupt Y
是的。编译器不得优化写访问或更改顺序 - ISER 在 CMSIS header.
中声明为 volatile
请注意,与较大的同类产品不同,Cortex-M0+ 没有写入缓冲区。
订单有保证,但除此之外别无其他。想象一下这种情况:您已经进入中断处理程序并将中断作为最后一条指令禁用。如果你有挂起的中断等待服务,那么不能保证你不会再次进入中断处理程序。为了防止它,您需要在离开中断例程之前留出足够的时间,读回写入的值或使用屏障。
使用什么屏障指令是个很有趣的问题。不是一两个字就能回答的
这是关于写缓冲区的 link to the interesting article which covers the topic, and some information
来自 Cortex-M0+ Devices Generic User Guide 关于内存区域-
2.2.1. Memory regions, types and attributes
Strongly-ordered:
The processor preserves transaction order relative to all other transactions.
和-
Address range: 0xE0000000- 0xE00FFFFF
Memory region: Private Peripheral Bus
Memory type: Strongly- ordered
Description: This region includes the NVIC, System timer, and System Control Block. Only word accesses can be used in this region.
现在,从CMSIS documentation-
#define __DMB()
Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion.
根据以上信息,似乎在访问 0xE0000000- 0xE00FFFFF
内存地址范围的代码中,例如 NVIC
控制器和 SysTick
配置寄存器,我确实不需要使用 __DMB
因为它实际上是由硬件执行的。
因此,例如,如果我们查看 __NVIC_EnableIRQ
-
/**
\brief Enable Interrupt
\details Enables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
}
它不包含 __DMB()
(也没有 __DSB()
或 __ISB()
),所以如果我启用中断 X,然后启用中断 Y,操作之间没有障碍-
NVIC_EnableIRQ(X); /* Note: __NVIC_EnableIRQ is defined as NVIC_EnableIRQ */
NVIC_EnableIRQ(Y);
是否承诺 HW 不会重新排序内存访问并会在中断 Y 之前启用中断 X(假设编译器确实将函数实现为内联)?
Is it promised that the HW will enable interrupt X before interrupt Y
是的。编译器不得优化写访问或更改顺序 - ISER 在 CMSIS header.
中声明为volatile
请注意,与较大的同类产品不同,Cortex-M0+ 没有写入缓冲区。
订单有保证,但除此之外别无其他。想象一下这种情况:您已经进入中断处理程序并将中断作为最后一条指令禁用。如果你有挂起的中断等待服务,那么不能保证你不会再次进入中断处理程序。为了防止它,您需要在离开中断例程之前留出足够的时间,读回写入的值或使用屏障。
使用什么屏障指令是个很有趣的问题。不是一两个字就能回答的
这是关于写缓冲区的 link to the interesting article which covers the topic, and some information