GPIO外设何时获得其成员地址分配?(When does GPIO peripheral get its members addresses assigned?)

编程入门 行业动态 更新时间:2024-10-26 22:28:51
GPIO外设何时获得其成员地址分配?(When does GPIO peripheral get its members addresses assigned?)

从stm32f446xx.h我们有一个GPIO_TypeDef的定义

typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef;

这用于初始化一些GPIO外设。 关注GPIOA:

#define PERIPH_BASE ((uint32_t)0x40000000) #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

所以我的问题是:

#define指令是否声明并初始化该结构并将其放置在指向GPIOA_BASE的地址处? 或者是定义语句只声明结构,但不初始化其成员?

成员如何在没有明确定义的情况下获得正确的地址位置? 我们如何知道GPIOA->MODER与GPIOA_BASE地址相同? 同样,我们如何知道GPIOA->ODR导致地址GPIOA_BASE +偏移0x014 ? 仅仅是因为当我们声明结构并通过#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)命令告诉它它位于GPIOA_BASE时,它所有的成员变量都会按照它们出现在结构GPIOA_TypeDef中的顺序在内存中声明和初始化? 这是有道理的,因为每个占用4个字节,但我不确定是否是这种情况。

如果成员变量没有按结构中列出的顺序声明,那么它们如何分配内存地址?

From stm32f446xx.h we have a definition of GPIO_TypeDef

typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef;

This is used to initialize some GPIO peripherals. Focusing on GPIOA:

#define PERIPH_BASE ((uint32_t)0x40000000) #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

So my questions are:

Is the #define directive declaring and initializing the struct and putting it at address pointed to at `GPIOA_BASE? Or is the define statement just declaring the struct but not initializing its members?

How do the members get their address placement correct without it being explicitly defined? How do we know that GPIOA->MODER leads to the same address as GPIOA_BASE? Likewise how do we know GPIOA->ODR leads to the address GPIOA_BASE + offset 0x014? Is it simply because when we declare the struct and tell it that it's located at GPIOA_BASE with the #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) command all it's member variables are declared and initialized in memory in the order they appear in the struct GPIOA_TypeDef? That would make sense since each takes 4 bytes but I am unsure if this is the case.

If the member variables are not declared in the order they are listed in the struct then how do they get their memory addresses assigned?

最满意答案

名称“C”用于描述两件事情:

一系列语言,以相当一致的方式将源代码构造映射到目标机器构造。 通常没有“标准”记录如何执行这样的映射,并且异常目标平台的实现将与更常见的平台的行为不同,但类似平台的编译器通常表现相似。

一种语言,其中仅包含C11标准强制要求的功能,并且通常省略了在所有平台上未一致实现的功能,即使类似平台的C编译器也会对它们进行类似处理。

您在上面引用的代码是为编译器设计的,这些编译器在第一个系列中处理语言,这是适应ARM处理器的需求。 在该语言中,结构中的每个项目将被放置在满足其对齐要求的最低偏移处。 C11标准或其任何前身都不要求编制者保证以这种方式布置结构,对于那些有时以其他方式表明这一事实的人来说,也不要采取任何方便的方式。 从C11标准的角度来看,结构要素可以任意放置,受限制较少。 我认为C89的作者可能认为编译器编写者会在有或没有授权的情况下按顺序进行布局,除非在罕见的平台上有可能有其他令人信服的理由,因此没有理由要求他们表现得像他们一样无论如何要去。 然而,有些人似乎认为缺乏授权意味着是任意安排事情的公开邀请,任何依赖于特定布局的代码都应被视为“有缺陷”。

The name "C" is used to describe two things:

A family of languages which map source code constructs onto target-machine constructs in a rather consistent fashion. There's often no "standard" documenting how such mapping should be performed, and implementations for unusual target platforms will behave differently from those for more common ones, but compilers for similar platforms will generally behave similarly.

A language which contains only the features mandated by the C11 Standard, and generally omits features which aren't implemented consistently on all platforms, even though C compilers for similar platforms would have processed them similarly.

The code you cite above is designed for compilers that process a languages in the first family, which is adapted to the needs of ARM processors. In that language, each item of a structure will be placed at the lowest offset which satisfies its alignment requirement. Neither the C11 Standard, nor any of its predecessors, requires that compilers guarantee to lay out structures in such fashion, nor do any of them even any convenient way for those that sometimes do otherwise to indicate that fact. From the point of view of the C11 Standard, structure elements may be arbitrarily placed subject subject to relatively few constraints. I think the authors of C89 probably figured that compiler writers would lay things out sequentially, with or without a mandate, except on rare platforms where there might be a compelling reason to do otherwise, and thus saw no reason to demand that they behave as they were going to anyway. Some people, however, seem to believe the lack of a mandate was meant to be an open invitation to arrange things arbitrarily, and any code that would rely upon a particular layout should be viewed as "defective".

更多推荐

本文发布于:2023-08-04 03:46:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1408884.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:外设   分配   成员   地址   GPIO

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!