访问嵌套结构

时间:2019-05-01 10:56:34

标签: c data-structures embedded stm32

我的嵌套结构如下:

struct stm32fxxx_state {
    struct stm32fxxx_gpio_state {
        union {
            uint32_t regs[10];
            struct {
                uint32_t MODER;
                uint32_t OTYPER;
                uint32_t OSPEEDR;
                uint32_t PUPDR;
                uint32_t IDR;
                uint32_t ODR;
                uint32_t BSRR;
                uint32_t LCKR;
                uint32_t AFRL;
                uint32_t AFRH;
            };
        };
    } GPIO[STM32FXXX_NUM_GPIOS];

    struct stm32fxxx_spi_regs {
        union {
            uint16_t regs[9];
            struct {
                uint16_t CR1;
                uint16_t CR2;
                uint16_t SR;
                uint16_t DR;
                uint16_t CRCPR;
                uint16_t RXCRCR;
                uint16_t TXCRCR;
                uint16_t I2SCFGR;
                uint16_t I2SPR;
            };
        };
    } SPI[STM32FXXX_NUM_SPIS];
    uint32_t PWR_CR;
    uint32_t PWR_CSR;
};

此结构已在main函数中以以下结构实例化:

struct stm32fxxx_gpio {
    SysBusDevice parent;

    MemoryRegion mmio;
    qemu_irq irq;

    uint8_t port_id, _port_id;

    struct stm32fxxx_state *state;
    struct stm32fxxx_gpio_state *gregs;
};

在代码中更远的地方,该结构的访问方式如下:

uint32_t valx = val ^ self->state->GPIO[self->port_id].MODER;

uint32_t valx = val ^ self->gregs->OTYPER;

self被声明为struct stm32fxxx_gpio *self的地方

我的问题是:self->stateself->gregs有何不同?这两种访问结构的方式有何不同。

代码已编译并可以正常运行。我想知道这两个访问如何返回不同的数据?还是这种嵌套结构有什么用?

我知道state也包含gpio_state属性。但是state结构没有与gpio_state结构不同的属性,那么为什么在这种情况下我们需要结构?

2 个答案:

答案 0 :(得分:1)

self->stateself->regs是2个不同的指针。代码可能会初始化这些字段以指向相同结构的各个部分。

答案 1 :(得分:0)

您尝试重新发明轮子,但做错了。

  1. 您已经使用硬件寄存器定义了结构。
  2. 您的声明不是“通用的”,因为许多家庭有不同的登记册。例如F3xx具有附加的BRR寄存器。
  3. 寄存器的顺序错误。
  4. 某些外设在寄存器之间有未使用的空间。例如
     typedef struct
    {
      __IO uint32_t ACR;          /*!< FLASH access control register,              Address offset: 0x00 */
      __IO uint32_t KEYR;         /*!< FLASH key register,                         Address offset: 0x04 */
      __IO uint32_t OPTKEYR;      /*!< FLASH option key register,                  Address offset: 0x08 */
      __IO uint32_t SR;           /*!< FLASH status register,                      Address offset: 0x0C */
      __IO uint32_t CR;           /*!< FLASH control register,                     Address offset: 0x10 */
      __IO uint32_t AR;           /*!< FLASH address register,                     Address offset: 0x14 */
      uint32_t      RESERVED;     /*!< Reserved, 0x18                                                   */
      __IO uint32_t OBR;          /*!< FLASH Option byte register,                 Address offset: 0x1C */
      __IO uint32_t WRPR;         /*!< FLASH Write register,                       Address offset: 0x20 */

    } FLASH_TypeDef;

如果您的想法是将寄存器保存在RAM中,则足以

GPIO_TypeDef savedGPIOs[NUMBER_OF_GPIOS];

savedGPIOs[0] = *GPIOA;

但我认为它没有太多意义。