Chandrika Joshi
Chandrika Joshi

Reputation: 1271

Accessing a nested structure

I have a nested structure like below:

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;
};

This structure has been instantiated in the main function in a structure as below:

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;
};

Somewhere further in the code, the structure is accessed as follows:

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

and

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

Where self is declared as struct stm32fxxx_gpio *self

My question is: how is self->state different from self->gregs? How are these two access to the structure is different.

The code is compiled and runs fine. I want to know how these two access return different data? Or what is the use of such nested structures?

I understand state contains the gpio_state attributes as well. But state structure does not have attributes different from gpio_state structure, then why do we need structures in this case?

Upvotes: 2

Views: 141

Answers (2)

0___________
0___________

Reputation: 68004

You try to reinvent the wheel and you did it wrong.

  1. you have defined structures with the hardware registers.
  2. Your declarations are not "generic" as many families have different registers. For example F3xx has additional BRR register.
  3. Order of the registers is wrong.
  4. Some peripherals have unused space between the registers. For example
     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;

If your idea is to save registers in the RAM it is enough to

GPIO_TypeDef savedGPIOs[NUMBER_OF_GPIOS];

and

savedGPIOs[0] = *GPIOA;

but I do not see too much sense in it.

Upvotes: 0

chqrlie
chqrlie

Reputation: 145287

self->state and self->regs are 2 different pointers. The code probably initializes these fields to point to parts of the same structure.

Upvotes: 1

Related Questions