指向寄存器地址的指针

pointer to register address

本文关键字:指针 地址 寄存器      更新时间:2023-10-16

当涉及到引用程序中的另一个变量时,我通常对指针有很好的理解,但引用/写入寄存器呢。这两个代码版本会执行相同的操作吗?

#define REGISTER 0x0001 
volatile unsigned int* baseAddress = (unsigned int*) 0x60000000;
baseAddress[REGISTER] = 0x10101010;

volatile unsigned int* realRegister = (unsigned int*) 0x60000004;
realRegister = 0x10101010;

不能有指向寄存器的指针或引用。寄存器不构成计算机主内存的一部分,也不能使用内存地址进行寻址。

尽管使用了名为REGISTER#define,但您的代码段与寄存器完全无关。它们试图写入正常的可寻址内存。在某些操作系统架构上,特定的内存地址可以直接映射到硬件端口(在某些设备上包括寄存器)。然而,大多数现代操作系统并不支持这一点。它们使用了虚拟内存的概念,指针不会直接映射到硬件位置。

关于您发布的代码,这两个部分不完全相同。第二个不会编译,因为您正试图为指针分配一个整数。您可以通过在赋值(*realRegister = 0x10101010;)之前取消引用指针来编译它,但这两段代码仍然不完全相同:

第一段代码将其值写入地址

reinterpret_cast<char*>(0x60000000) + sizeof(unsigned int)

相比之下,第二段代码将其值写入地址

reinterpret_cast<char*>(0x60000000) + 4

–这两段代码仅在具有sizeof(unsigned int) == 4的机器上相同。

对于您的问题,术语寄存器有两个概念含义:处理器内用于保存值的位置和硬件可寻址设备用于保存值。

让我们跳过关于处理器寄存器的部分,因为这些寄存器没有外部世界可以访问的地址。(有些处理器会这样做。)

例如,让我们使用UART,它是一种将并行数据转换为串行数据的设备,通常用于从嵌入式系统输出数据。

仅考虑发送部分,就有一个状态寄存器和一个数据寄存器。状态寄存器具有表示何时完成字符传输的位。数据寄存器保存要传输的字符。

假设这些是32位宽的顺序寄存器,它们从基址0x1000开始。

您可以将模具设置为:

uint32_t * UART_BASE = (uint32-t *) 0x1000;

状态寄存器可以被称为UART_BASE[0],数据寄存器可以被称作UART_BASE[1]

还有其他方式来表示硬件设备,例如使用结构和每个寄存器作为结构内的字段;或者每个寄存器具有单独的指针。

应该是(*realRegister) = 0x10101010;,但除此之外,是的,它们看起来是一样的。