2

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?

Chandrika Joshi
  • 1,211
  • 11
  • 24
  • 1
    What is the type of `self`? There is missing ending of the `stm32fxxx_state` structure declaration. The enclosing `};` is missing. Does `stm32fxxx_state` has any other members? – KamilCuk May 01 '19 at 10:57
  • The first snippet should not compile. Possible duplicate of https://stackoverflow.com/questions/1815677/nested-structures – Quimby May 01 '19 at 10:59
  • self is defined as struct stm32fxxx_gpio *self. So its a pointer of type struct stm32fxxx_gpio. – Chandrika Joshi May 01 '19 at 11:00
  • @KamilCuk : yes, the structure has few more members same like gpio_state. Answering your questions kind of now giving me an idea why this might have been done. But it would be great, if you explain as i'm new to data structures. – Chandrika Joshi May 01 '19 at 11:12
  • `state` is an array of struct `stm32fxxx_state` while `regs` is a struct `stm32fxxx_gpio_state` . That is the difference if that is what you are asking – Bhargav Kinnal May 01 '19 at 11:48
  • `self->regs->OTYPER;` this will definitely not compile. `regs` is the array of integers not the pointer to the structure or union – 0___________ May 01 '19 at 14:38
  • @ChandrikaJoshi btw you try to reinvernt the wheel - all is already defined and can be used straight away. – 0___________ May 01 '19 at 14:39
  • Possible duplicate of [Nested structures](https://stackoverflow.com/questions/1815677/nested-structures) – Kamiccolo May 01 '19 at 15:40
  • You haven't shown the initialization of `self->state` and `self->regs`. All you've shown is that they are declared as pointers to structures. Show us how the pointers are initialized. Also show how `self` is initialized. – kkrambo May 01 '19 at 19:28
  • Is the question why `self->regs->OTYPER;` works without array indexing? If so, it works as a sloppy but valid way to access the first element of the array. Bad code. – Lundin May 02 '19 at 07:00
  • I thank you guys for pointing out the mistakes in the code and how it might or might not compile(which it does, probably you cant see it because you dont know the complete code?). But I'm not asking that. I'm asking, when nested structures are used , how this kind of access to structures works? – Chandrika Joshi May 02 '19 at 07:39
  • @P__J__ : I think you confused regs of array and regs of type struct stm32fxxx_gpio_state, I have changed it to gregs. I hope its clear now – Chandrika Joshi May 02 '19 at 11:44

2 Answers2

1

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

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • They are two completely unrelated types so why would they point at the same structure? – Lundin May 02 '19 at 06:56
  • Thanks for editing the code. I should have taken care of indentation. Secondly you are right. But I do not understand how to access these attributes of the union and structures. The code is a sample code developed by someone else and it works, I'm trying to use the same but understand how he has accessed these structures and unions – Chandrika Joshi May 02 '19 at 07:51
0

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.

Tarick Welling
  • 3,119
  • 3
  • 19
  • 44
0___________
  • 60,014
  • 4
  • 34
  • 74