哪些变量类型/大小在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 } }
在上面的代码中,我可以在不使用互斥锁的情况下执行此操作? 我的怀疑如下:
-
volatile bool
:安全 – 不需要互斥 -
volatile uint8_t
:safe – 不需要互斥锁 -
volatile uint16_t
:safe – 不需要互斥锁 -
volatile uint32_t
:safe – 不需要互斥锁 -
volatile uint64_t
:UNSAFE – 你必须使用一个关键部分或MUTEX! -
volatile float
:safe – 不需要互斥锁 -
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中隐藏。