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