#define RegisterX_Address (*((volatile unsigned int*)0x400253FC))
我需要了解C语言中的(*((volatile unsigned int*)0x400253FC))
是什么,我知道这是一个指向其中一个寄存器地址的指针,但是为什么这样写呢??
答案 0 :(得分:2)
在任何平台上,内存地址0x400253FC
包含1个int
数据。
如果取消引用0x400253FC
,则会获得该值。
这可能用于以下用途:
unsigned int GetCPUTemperature()
{
unsigned int temp;
temp = RegisterX_Address;
return temp;
}
将数据直接映射到特定的内存地址并不常见,但是经常发生在嵌入式开发中。
volatile
关键字告诉编译器它无法缓存,存储或重用其获取的值。每次访问时,它都必须从内存中检索值,因为无论在何处写入数据,都会定期在程序范围之外更新该值。
答案 1 :(得分:0)
之所以这样写,是因为这恰好在与该特定微控制器一起使用的特定编译器上起作用。 volatile
最有可能向编译器指示它不应进行优化,否则将导致无法实际读取硬件寄存器。
答案 2 :(得分:0)
它是一个宏,用于访问(可能是)内存映射的I / O引脚。
编译器或硬件本身知道内存的特定地址还有其他用途。当您的源代码从该寄存器中读取时,它实际上是在从输入引脚上读取值,这是直接连接到处理器的导线。该地址是特殊的,并且这类事情通常专门与该特定硬件相关联。 (这就是为什么您需要一个用于不同硬件的不同驱动程序的shmorgas板,并且它们并非都可以方便地互换的原因)。对于更高级别执行的所有误导和概括,有时需要使用实际地址直接对实际硬件进行读写。
内部*
将其声明为指针。外部*
正在取消引用。是的,C语言中的指针是语言中最令人困惑的部分之一。 *
符号实际上有两个工作。一个是在声明期间,它描述了一块数据。显式强制转换为声明:(volatile unsigned int*)
。这迫使编译器将十六进制值视为指向易失性无符号整数的指针。第二个指令在使用该宏*(myPointer)
时执行,该指针已取消引用,因此,您不是在使用值0x400253FC
,而是在查看位于ADDRESS 0x400253FC
中的数据记忆。因为它可能已映射到硬件,所以它甚至都不是内存。 (这取决于。无论哪种方式,它都仍称为ICD中的寄存器。我认为寄存器是芯片上的特定寄存器,与通过MMU相比,程序集可以直接使用什么组件。但是对于硬件专家来说,一切都是“寄存器” ,他们就像使用“地址”一样使用它)。
我猜它是一个I / O引脚,因为它易失。这是一条指令,指示编译器在优化时不要做任何假设,因为它的值可以在后面更改。就像硬件收到信号时一样。或者当输出线自动复位为低电平时。易失性变量还用于线程之间的共享内存,但是在微控制器上,它通常是I / O。
答案 3 :(得分:0)
只需尝试...
#define RegisterX_Address (*((volatile unsigned int*)0x400253FC))
unsigned int fun ( void )
{
return(RegisterX_Address);
}
给予
00000000 <fun>:
0: 4b01 ldr r3, [pc, #4] ; (8 <fun+0x8>)
2: 6818 ldr r0, [r3, #0]
4: 4770 bx lr
8: 400253fc
写起来比
简单volatile unsigned int *RegisterX_Address;
RegisterX_Address = (volatile unsigned int *)0x400253FC;
return(*RegisterX_Address);
这就是为什么它是这样写的。另外,按书面规定,它不会消耗内存作为变量。