uint16_t 和 uint32_t 中断在 Cortex M 架构中安全吗?

Is uint16_t and uint32_t interrupt safe in Cortex M architecture?

我正在研究一些嵌入式的东西。我有多个中断可能正在处理相同的数据,所以我想知道 uint16_tuint32_t 数据类型是否是中断安全的。

如果中断正在处理 uint16/32_t 数据并且在中途被另一个试图读取该数据的中断中断,它将看到损坏的数据。这是一种可能的情况吗?

谢谢

Cortex-M 处理器不会损坏数据并赋予您未定义的值。该值将始终是确定性的。然而,在中断的情况下,有许多条件会影响数据的值。 uint16/32_t 数据可以位于内存中,或仅位于处理器寄存器内。如果在内存中,它可以是 16/32 位对齐的,也可以不是 16/32 位对齐的。处理器,例如M0 或 M4,以及对数据执行的操作,例如加或乘,也很重要。所有这些都将决定用于处理数据的指令是否是原子的。

您可以在 Joseph Yiu 的 discussion and this 回答中找到更多详细信息。

一般来说,如果指令是原子的(单次执行周期),中断是无法干扰数据操作的。但是,在您的 C 代码级别,uint16/32_t 数据操作可能需要超过 1 条指令。因此,很难保证程序按预期运行。这也适用于 uint8_t 数据。您可能希望在处理共享数据之前禁用中断,然后再启用中断。此 中很好地介绍了该技术(请参阅第 2 点)。

为了扩展来自@DinhQC 的 ,关于 16 位和 32 位数据类型的所有 single-result 指令都是 'atomic' 相对于 Cortex-M 只要数据正确对齐(并且您必须非常努力地让 C 编译器为您提供未对齐的数据,因为未对齐的访问速度很慢并且需要特殊处理)。在大多数实现中,Multiple-result 像 LDMSTM 这样的操作可以被中断和恢复,但是 LDM 或 [=11= 中每个单独的 32 位传输的完整性] 保证。

重要的是要了解您正在执行的操作是否是机器级别的单指令。例如,如果您正在递增共享变量,这将需要三个指令:读取、修改和写入。如果在读写之间发生了中断,中断服务程序修改了同一个变量,ISR returns.

时,这个修改会被覆盖

安全的方法是使用某种 hardware-supported 机制来强制共享数据的原子性或互斥性。在 Cortex-M 上有比禁用和 re-enabling 中断更强大、更灵活和更快的互斥方法,但是,值得注意的是 STREXLDREX 指令(可用在 C 中也是如此)。查看 my answer to this other question 了解更多信息。