【问题标题】:Why to type case absolute memory address in embedded c?为什么在嵌入式 c 中输入大小写绝对内存地址?
【发布时间】:2021-03-09 19:02:36
【问题描述】:

我很想了解为什么我们需要对一个绝对物理内存地址进行类型转换,以及它对编译器有什么影响,如果我们对地址进行类型转换,或者我们不

我在寻找访问绝对物理地址的不同方法时遇到了following code

例如这里我们有一个地址0x40020C00,它指向PORTA(有多个这样的端口,如下所示)。

如果我们要访问此地址的偏移量之一以写入一些位(为了将 I/O 引脚配置为输入/输出,然后只需切换 LED),我们可以将其编码如下:

typedef struct
{
  uint32_t MODER;   // mode register,                     offset: 0x00
  uint32_t OTYPER;  // output type register,              offset: 0x04
  uint32_t OSPEEDR; // output speed register,             offset: 0x08
  uint32_t PUPDR;   // pull-up/pull-down register,        offset: 0x0C
  uint32_t IDR;     // input data register,               offset: 0x10
  uint32_t ODR;     // output data register,              offset: 0x14
  uint32_t BSRR;    // bit set/reset register,            offset: 0x18
  uint32_t LCKR;    // configuration lock register,       offset: 0x1C
  uint32_t AFRL;    // GPIO alternate function registers, offset: 0x20
  uint32_t AFRH;    // GPIO alternate function registers, offset: 0x24
} GPIO_t;

volatile GPIO_t*   const portd       = (GPIO_t*)0x40020C00;

int main(void)
{
  *rcc_ahb1enr |= (1 << 3); // enable PortD's clock

  uint32_t moder = portd->MODER;
  moder |= (1 << 16);
  moder &= ~(1 << 17);
  portd->MODER = moder;

  while (1) {
    portd->ODR |= (1 << 8);  // led-on
    sleep(500);
    portd->ODR &= ~(1 << 8); // led-off
    sleep(500);
  }
}

我的问题是:

在这一行中,volatile GPIO_t* const portd = (GPIO_t*)0x40020C00; 为什么我们要用数据的返回类型(GPIO_t*) 类型转换绝对内存地址(0x40020C00), 指针何时具有正确的返回类型?

注意:我知道为什么它被编码为 volatile 和 const 指针(即因为它是寄存器的绝对物理地址,我们不希望编译器优化用于访问这些地址的变量和我们承诺不改变指针地址。)

感谢您的解释/答案,并提前致谢!

【问题讨论】:

  • 0x40020C00 是一个整数,一般认为与指针类型不兼容。因此需要显式转换。不知道你在问什么。
  • 这么说吧,如果我将地址类型转换为(uintptr_t *)(uint32_t *),会不会正确(假设从地址返回的数据是uint32_t long) ?甚至有必要进行这种铸造吗?我不能只使用指针而不进行转换吗?
  • 您将其转换为您希望从该地址读取的类型的指针,就是这样。如果不强制转换,它将根本无法编译或抛出警告。

标签: c pointers memory casting type-conversion


【解决方案1】:

强制转换是必要的,因为您要在语言不允许隐式转换的两种类型之间进行转换。

常量0x40020C00 的类型为int。虽然int 可以隐式转换为其他整数类型,但它不能隐式转换为指针。所以你需要应用演员表。

【讨论】:

  • 我可以合法地将其类型转换为 unitptr_t 或 uint32_t 而不是 GPIO_t 吗?还是必须将其类型转换为正在读入的指针的类型定义?
  • @Karan 将其转换为不同的整数类型并不重要。从整数转换为指针需要显式转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
相关资源
最近更新 更多