哪些变量类型/大小在STM32微控制器上是primefaces的?

以下是STM32微控制器上的数据类型: http : //www.keil.com/support/man/docs/armcc/armcc_chr1359125009502.htm 。

这些微控制器使用32位ARM核心处理器。

哪些数据类型具有自动primefaces读取和primefaces写入访问权限?

我很确定所有32位数据类型都有(因为处理器是32位),并且所有64位数据类型都不行(因为读取或写入64位字需要至少2个处理器操作),但是bool (1字节)和uint16_t / int16_t (2字节)怎么样?

上下文:我在STM32上的多个线程(单核,multithreading,或称为FreeRTOS中的 “任务”)之间共享变量,需要知道是否需要通过关闭中断来强制执行primefaces访问,互斥体等

更新:

请参阅此示例代码:

 volatile bool shared_bool; volatile uint8_t shared u8; volatile uint16_t shared_u16; volatile uint32_t shared_u32; volatile uint64_t shared_u64; volatile float shared_f; // 32-bits volatile double shared_d; // 64-bits // Task (thread) 1 while (1) { // Write to the values in this thread. // What I write to each variable will vary. Since other threads // are reading these values, I need to ensure my *writes* are atomic, or else // I must use a mutex to prevent another thread from reading a variable in the middle // of this thread's writing. shared_bool = true; shared_u8 = 129; shared_u16 = 10108; shared_u32 = 130890; shared_f = 1083.108; shared_d = 382.10830; } // Task (thread) 2 while (1) { // Read from the values in this thread. // What thread 1 writes into these values can change at any time, so I need to ensure // my *reads* are atomic, or else I'll need to use a mutex to prevent the other // thread from writing to a variable in the midst of reading // it in this thread. if (shared_bool == whatever) { // do something } if (shared_u8 == whatever) { // do something } if (shared_u16 == whatever) { // do something } if (shared_u32 == whatever) { // do something } if (shared_u64 == whatever) { // do something } if (shared_f == whatever) { // do something } if (shared_d == whatever) { // do something } } 

在上面的代码中,我可以在不使用互斥锁的情况下执行此操作? 我的怀疑如下:

  1. volatile bool :安全 – 不需要互斥
  2. volatile uint8_t :safe – 不需要互斥锁
  3. volatile uint16_t :safe – 不需要互斥锁
  4. volatile uint32_t :safe – 不需要互斥锁
  5. volatile uint64_t :UNSAFE – 你必须使用一个关键部分或MUTEX!
  6. volatile float :safe – 不需要互斥锁
  7. volatile double :不安全 – 你必须使用一个关键部分或MUTEX!

使用FreeRTOS的关键部分示例:
– https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html

 // Force atomic access with these critical section atomic access guards. taskENTER_CRITICAL(); // do the (now guaranteed to be safe) read or write here taskEXIT_CRITICAL(); 

相关,但没有回答我的问题:

  • ARM中的primefaces操作
  • ARM:从int atomic写/读?
  • (我自己在8位AVR [和Arduino]微控制器中的primefaces性问题和答案): https : //stackoverflow.com/a/39693278/4561887

更新2018年10月30日:我不小心引用了(稍微)错误的文件(但是说的完全一样),所以我在这里修复了它们。 有关详细信息,请参阅本答案底部的“关于2018年10月30日更改的说明”。

我绝对不明白这里的每一个字,但ARM v7-M架构参考手册 ( 在线资源 ; PDF文件直接下载 )(不是技术参考手册[TRM],因为它不讨论primefaces性)validation了我的假设:

在此处输入图像描述

所以……我认为我问题底部的7个假设都是正确的。 [2018年10月30日:是的,这是正确的。 请参阅下文了解详情。]


更新2018年10月29日:

还有一点点花絮:

FreeRTOS创始人,专家和核心开发人员Richard Barry在tasks.c ……

/ *不需要临界区,因为变量的类型为BaseType_t。 * /

…在STM32上读取“unsigned long”(4字节)volatile变量时。 这意味着他至少可以100%确定4字节的读写操作在STM32上是primefaces的。 他没有提到小字节读取,但对于4字节读取,他是最确定的。 我必须假设4字节变量是本机处理器宽度,并且字对齐 ,对于这是真的至关重要。

tasks.c ,来自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。 * /

…在此文件中的两个不同位置。

我的问题的最终答案:

此外,如上面的截图所示,仔细检查p141上的TRM后,我想指出的关键句是:

在ARMv7-M中,单拷贝primefaces处理器访问是:
•所有字节访问。
•所有半字访问半字对齐位置。
•对字对齐位置的所有字访问。

并且, 根据此链接 ,以下适用于“在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字节对齐)< - NOT GUARANTEED ATOMIC
  • float是“字对齐的”(4字节对齐)
  • double是“双字对齐”(8字节对齐)< - NOT GUARANTEED ATOMIC
  • long double是“双字对齐”(8字节对齐)< - NOT GUARANTEED ATOMIC
  • 所有指针都是“字对齐”(4字节对齐)

这意味着我现在已经理解了我需要的证据, 最终确定上面的所有粗体行都具有自动primefaces读写访问权限 (但当然不是递增/递减,这是多个操作)。 这是我的问题的最终答案。 这种primefaces性的唯一例外可能是在我认为的打包结构中,在这种情况下,这些自然对齐的数据类型可能不是自然对齐的。

另请注意,在阅读技术参考手册时,“单拷贝primefaces性”显然仅仅意味着“单核CPUprimefaces性”或“单CPU核心架构上的primefaces性”。 这与“多拷贝primefaces性”形成对比,“多拷贝primefaces性”指的是“多重处理系统”或多核CPU架构。 维基百科称“多处理是在单个计算机系统中使用两个或多个中央处理单元(CPU)”( https://en.wikipedia.org/wiki/Multiprocessing )。

我所讨论的架构STM32F767ZI (带有ARM Cortex-M7内核)是一种单核架构,正如我在TRM上面引用的那样,显然是“单拷贝primefaces性”。

进一步阅读:

  • ARM:从int atomic写/读?
  • atomic / volatile / synchronized有什么区别?
  • 压缩结构中的变量可以primefaces读取吗?

关于2018年10月30日变更的说明:

  • 我有这个参考: ARMv7 TRM (技术参考手册)。 但是,这在两个方面是错误的:1)这根本不是TRM! TRM是一个简短的(约200 pgs)技术参考手册。 然而,这是“架构参考手册”,而不是TRM。 它是一个更长,更通用的文档,因为架构参考手册大约为~1000~2000 pgs。 2)这适用于ARMv7-A和ARMv7-R处理器,但我所需的STM32 mcu手册适用于ARMv7-M处理器。
  • 以下是ARM Cortex-M7处理器技术参考手册的正确链接。 在线: https : //developer.arm.com/docs/ddi0489/latest 。 PDF: https : //static.docs.arm.com/ddi0489/d/DDI0489D_cortex_m7_trm.pdf 。
  • 上面正确的TRM,在p99(5-36)上说,“有关primefaces性的更多信息,请参阅”ARM®v7-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/ddi0489/d/DDI0489D_cortex_m7_trm.pdf 。 它讨论了p79-80(A3-79到A3-80)的primefaces性。

取决于你的意思是primefaces。

如果不是简单的加载或存储操作就好

 a += 1; 

那么所有类型都不是primefaces的。

如果它是简单存储或加载操作32位,则16位和8位数据类型是primefaces的。 如果寄存器中的值必须归一化8和16位存储并且加载可能不是primefaces的。

如果你的硬件支持比特带,那么如果使用比特带,则支持比特带的存储区中的位操作(置位和复位)是primefaces的

注意。

如果您的代码不允许未对齐操作,则8位和16位操作可能不是primefaces操作。

CPU核心寄存器可以处理primefaces“算术”!

它可以是任何类型, 一个或四个字节取决于体系结构和指令集

但是,修改位于存储器中的任何变量至少需要3个系统步骤: RMW =读取存储器以进行寄存,修改寄存器和写入寄存器到存储器。

因此,只有控制CPU寄存器的使用才能实现primefaces修改,这意味着需要使用纯汇编程序而不使用C或Cpp编译器。

当您使用C \ Cpp编译器时,它将全局或全局静态变量放在内存中,因此C \ Cpp不提供任何primefaces操作和类型

注意:您可以使用例如“FPU寄存器”进行primefaces修改(如果您确实需要它),但是您必须从架构具有FPU的编译器和RTOS中隐藏。