我正在使用STM32F0微控制器。 SPI接收/传输FIFO的顶部可通过内存访问进行访问。 这种特殊的微控制器允许我从FIFO的顶部读取/写入8位或16位。 更准确地说,当执行LDRB / STRB指令时,将从FIFO弹出/推送8位,当执行LDRH / STRH指令时,将从FIFO弹出/推送16位。
STMicroelectronic提供的硬件抽象层提供了这种语法来读取SPI FIFO。
return *(volatile uint8_t*)&_handle->Instance->DR; // Pop 1 byte
return *(volatile uint16_t*)&_handle->Instance->DR; // Pop 2 byte
*(volatile uint8_t*)&_handle->Instance->DR = val; // Push 1 byte
*(volatile uint16_t*)&_handle->Instance->DR = val; // Push 2 bytes
在这里,DR
是一个指向 SPI FIFO 顶部的 uint32_t*
我使用这种语法构建我的软件,它运行良好。唯一的问题是,g++ 抛出了许多有关类型转换的警告。更具体地说:
Inc/drivers/SPI.h:70:50: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
return *(volatile uint16_t*)&_handle->Instance->DR;
经过一些阅读,似乎在 C++ 中使用联合并不是一个好主意。我仍然尝试了一下,但遇到了一些问题。实际上,在联合中通过指针访问内存会导致我的微控制器崩溃,就像未对齐的内存访问一样。
static_cast
和 reinterpret_cast
抛出与 C 风格转换相同的警告
由于我的最终目标是使编译器使用 LDRB/STRB 和 LDRH/STRH 指令,因此我无法使用带有 void*
的 memcpy
。
我在 Stack Overflow 上找到的其他解决方案都取决于用例。
有什么建议吗?