对于这个问题的最终、明确的答案,请直接跳到下面标题为“我的问题的最终答案".
2018 年 10 月 30 日更新:我不小心引用了(稍微)错误的文档(但说的是完全相同的事情),所以我在这里的答案中修复了它们。有关详细信息,请参阅本答案底部的“关于 2018 年 10 月 30 日变更的说明”。
我绝对听不懂这里的每一个字,但是ARMv7-M架构参考手册 (在线源码 https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/ddi0403/latest/armv7-m-architecture-reference-manual; PDF文件直接下载 https://static.docs.arm.com/ddi0403/ed/DDI0403E_d_armv7m_arm.pdf)(不是技术参考手册 [TRM],因为它不讨论原子性)验证了我的假设:
所以......我认为我的问题底部的 7 个假设都是正确的。 [2018 年 10 月 30 日:是的,这是正确的。详情请见下文。]
2018 年 10 月 29 日更新:
还有一个小花絮:
FreeRTOS 创始人、专家和核心开发人员 Richard Barry 在tasks.c
...
/* 不需要临界区,因为变量的类型为 BaseType_t。 */
...在 STM32 上读取“unsigned long”(4 字节)易失性变量时。这意味着他至少 100% 确定 4 字节读写在 STM32 上是原子的。他没有提到较小字节的读取,但对于 4 字节的读取,他确信无疑。我必须假设 4 字节变量是本机处理器宽度,而且,字对齐 http://www.keil.com/support/man/docs/armcc/armcc_chr1359125009502.htm,对于这一点是否成立至关重要。
From tasks.c
,FreeRTOS v9.0.0 中的第 2173-2178 行,例如:
UBaseType_t uxTaskGetNumberOfTasks( void )
{
/* A critical section is not required because the variables are of type
BaseType_t. */
return uxCurrentNumberOfTasks;
}
他用了这个确切的短语...
/* 不需要临界区,因为变量的类型为 BaseType_t。 */
...在此文件中的两个不同位置。
我的问题的最终答案:所有类型 bolded下面 9 行列表中的类型)是原子的。
此外,在仔细检查第141页的TRM(如我上面的屏幕截图所示)后,我想指出的关键句子是:
在 ARMv7-M 中,单拷贝原子处理器访问是:
• all byte访问。
• all halfword访问半字对齐的位置。
• all word访问字对齐的位置。
And, 根据此链接 http://www.keil.com/support/man/docs/armcc/armcc_chr1359125009502.htm,以下对于“在 ARM C 和 C++ 中实现的基本数据类型”(即:在 STM32 上)成立:
bool
/_Bool
是“字节对齐”(1 字节对齐)
int8_t
/uint8_t
是“字节对齐”(1 字节对齐)
int16_t
/uint16_t
是“半字对齐”(2 字节对齐)
int32_t
/uint32_t
是“字对齐”(4 字节对齐)
-
int64_t
/uint64_t
是“双字对齐”(8 字节对齐)
float
是“字对齐”(4 字节对齐)
-
double
是“双字对齐”(8 字节对齐)
-
long double
是“双字对齐”(8 字节对齐)
- 所有指针都是“字对齐”(4 字节对齐)
这意味着我现在拥有并理解我需要的证据最后声明上面的所有粗体行都具有自动原子读写访问权限(当然不是递增/递减,这是多个操作)。这是我的问题的最终答案。 我认为这种原子性的唯一例外可能是在打包结构中,在这种情况下,这些本来自然对齐的数据类型可能不会自然对齐。
另请注意,在阅读技术参考手册时,“单副本原子性”显然仅意味着“单核 CPU 原子性”或“单 CPU 核架构上的原子性”。这与“多副本原子性”形成对比,“多副本原子性”指的是“多处理系统”或多核 CPU 架构。维基百科指出“多处理是在单个计算机系统中使用两个或多个中央处理单元(CPU)”(https://en.wikipedia.org/wiki/Multiprocessing https://en.wikipedia.org/wiki/Multiprocessing).
我的架构有问题,STM32F767ZI https://www.st.com/en/microcontrollers/stm32f767zi.html(带有 ARM Cortex-M7 内核)是单核架构,因此显然适用“单副本原子性”,正如我上面从 TRM 中引用的那样。
进一步阅读:
- ARM:从 int 写入/读取是原子的吗? https://stackoverflow.com/questions/9399026/arm-is-writing-reading-from-int-atomic
- 原子/易失性/同步之间有什么区别? https://stackoverflow.com/questions/9749746/what-is-the-difference-between-atomic-volatile-synchronized
- 打包结构内的变量可以被原子读取吗? https://stackoverflow.com/questions/14662135/can-variables-inside-packed-structures-be-read-atomically
关于 2018 年 10 月 30 日变更的说明:
- 我有这个参考:ARMv7 技术规范 https://www.cs.utexas.edu/%7Esimon/378/resources/ARMv7-AR_TRM.pdf(技术参考手册)。然而,这在两个方面是错误的:1) 这根本不是 TRM! TRM 是一本简短的(约 200 页)技术参考手册。然而,这是“架构参考手册”,而不是 TRM。这是一个更长、更通用的文档,因为架构参考手册的数量级约为 1000~2000 页。 2) 这是针对 ARMv7-A 和 ARMv7-R 处理器的,但我需要的有关 STM32 mcu 的手册是针对 ARMv7-M 处理器的。
- 以下是 ARM Cortex-M7 处理器技术参考手册的正确链接。在线的:https://developer.arm.com/docs/ddi0489/latest https://developer.arm.com/docs/ddi0489/latest. PDF: https://static.docs.arm.com/ddi0489/d/DDI0489D_cortex_m7_trm.pdf https://static.docs.arm.com/ddi0489/d/DDI0489D_cortex_m7_trm.pdf.
- 正确的 TRM 就在上面,第 99 页 (5-36) 上说:“了解更多
有关原子性的信息,请参阅 ARM®v7-M 架构参考手册。”因此,这是该手册。在线下载链接:https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/ddi0403/latest/armv7-m-architecture-reference-manual https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/ddi0403/latest/armv7-m-architecture-reference-manual. PDF: https://static.docs.arm.com/ddi0489/d/DDI0489D_cortex_m7_trm.pdf https://static.docs.arm.com/ddi0489/d/DDI0489D_cortex_m7_trm.pdf。它讨论了第 79-80 页(A3-79 到 A3-80)的原子性。
To create原子访问防护(通常由关闭中断当读取和写入时not原子)参见:
- [我的问答]在 STM32 微控制器中禁用和重新启用中断以实现原子访问防护的各种方法有哪些? https://stackoverflow.com/a/71626598/4561887
- My doAtomicRead()func 可以在不关闭中断的情况下进行原子读取 https://stackoverflow.com/a/71625693/4561887