嵌入式C#定义
在embedded C中,我遇到了以下(以及更多类似的)示例: GPIOA_AHB_BASE是一个地址,它是前面定义的。这段代码到底是做什么的?我知道defines是预处理器的指令,因此它用define中给定的值替换所有实例。比如说,嵌入式C#定义,c,arm,embedded,cmsis,C,Arm,Embedded,Cmsis,在embedded C中,我遇到了以下(以及更多类似的)示例: GPIOA_AHB_BASE是一个地址,它是前面定义的。这段代码到底是做什么的?我知道defines是预处理器的指令,因此它用define中给定的值替换所有实例。比如说, #define GPIOA_AHB GPIOA_AHB_BASE 将GPIOA_AHB替换为GPIOA_AHB_BASE已定义的任何值。我不明白第一个案例中发生了什么…问题中的信息无法说明全部细节,但是: 如果源代码包含GPIOA\u-AHB作为标识符,则
#define GPIOA_AHB GPIOA_AHB_BASE
将GPIOA_AHB替换为GPIOA_AHB_BASE已定义的任何值。我不明白第一个案例中发生了什么…问题中的信息无法说明全部细节,但是:
GPIOA\u-AHB
作为标识符,则最初将替换为((GPIOA\u-AHB\u类型*)GPIOA\u-AHB\u基)
GPIOA_AHB_Type
或GPIOA_AHB_BASE
本身是否为宏#define GPIOA_AHB_BASE 0x10000
,则该值将插入替换文本中。类似地,如果存在#define GPIOA_AHB_Type uint8_t
,则该值将插入替换文本,导致代码包含:
((uint8_t *)0x10000)
从
GPIOA_AHB
的定义中,我可以得出结论,它用于引用GPIO/AHB
设备的寄存器
访问这些寄存器的符号是GPIOA\u AHB->some\u register
如果您在第二种情况下定义了
GPIOA_AHB
,那么它将只是一个普通数字。如果不先将其强制转换为描述该设备内寄存器偏移量的结构(GPIOA\u AHB\u Type
),或者手动添加该设备寄存器空间内每个寄存器的偏移量,则无法使用它引用寄存器。您可能会得到预处理的源代码格式(例如,使用类似于gcc-C-e yoursource.C>yoursource.i
)谢谢!到第3点为止。我现在知道发生了什么。部分((uint8_t*)0x10000)仍然很模糊…这会返回存储在地址0x10000处的值,并将其转换为uint8\u t吗?在我展示的假设扩展中,您会有一个表达式,如:uint8\u t b=*GPIOA\u AHB;
从该地址读取一个字节,或*GPIOA\u AHB=0x83;
将一个字节写入该地址(您可以读取或写入的地址)是准确的;详细的机制取决于定义。如果GPIOA\u AHB\u类型
是一个结构而不是简单的类型,那么您可以使用GPIOA\u AHB->member
访问该结构的成员。主要的一点是,它将硬件指定的内存地址转换为C程序可以使用的内容。这是不可移植的e、 但是有效。更常见的是,这类宏的编写方式是:#define GPIOA_AHB(*(volatile uint8_t*)GPIOA_AHB_BASE)
。这样您就不必取消引用,而是将寄存器视为任何其他变量。此外,该类型需要是volatile的,因为它是一个硬件内存位置。
((uint8_t *)0x10000)