【发布时间】:2021-08-15 01:14:53
【问题描述】:
以下三行代码是用 1 条 MOV 指令修改位的优化方法,而不是使用较少中断安全的 read-modify-write 习惯用法。它们彼此相同,并且设置了 GPIO 端口的数据寄存器中的 LED_RED 位:
*((volatile unsigned long*)(0x40025000 + (LED_RED << 2))) = LED_RED;*(GPIO_PORTF_DATA_BITS_R + LED_RED) = LED_RED;GPIO_PORTF_DATA_BITS_R[LED_RED] = LED_RED;
LED_RED 就是(volatile unsigned long) 0x02。在此微控制器的内存映射中,该寄存器(和其他)的前 2 个 LSB 未使用,因此第一个示例中的左移是有意义的。
GPIO_PORTF_DATA_BITS_R 的定义是:
#define GPIO_PORTF_DATA_BITS_R ((volatile unsigned long *)0x40025000)
我的问题是: 为什么在使用指针算术或数组索引(分别为第 2 方法和第 3 方法)时不需要左移两次?我很难理解。提前谢谢你。
【问题讨论】:
-
不存在“较少中断安全”的代码——有中断安全的代码和非中断安全的代码。并且不要假设单行 C 意味着单次写入 - 确保您正在写入 GPIO 中的“设置”或“清除”寄存器,这样才会安全。
-
使用相同的 LED_RED 值作为地址的一部分,并且作为您正在写入的值,几乎可以肯定是错误的。但是如果不知道微控制器的细节和 LED_RED 的值,就不可能知道。它可能会像您所期望的那样工作,但不是设计使然。