这在C中到底意味着什么?

时间:2019-01-08 20:20:39

标签: c pointers

#define RegisterX_Address (*((volatile unsigned int*)0x400253FC))

我需要了解C语言中的(*((volatile unsigned int*)0x400253FC))是什么,我知道这是一个指向其中一个寄存器地址的指针,但是为什么这样写呢??

4 个答案:

答案 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);

这就是为什么它是这样写的。另外,按书面规定,它不会消耗内存作为变量。