user3202429
user3202429

Reputation: 117

Filling const array with unknown amount of defines

Is there a more elegant way to do this:

#if   SCID_BASE
const uint32_t baseaddr[] = {SCIA_BASE, SCIB_BASE, SCIC_BASE, SCID_BASE};
#elif SCIC_BASE
const uint32_t baseaddr[] = {SCIA_BASE, SCIB_BASE, SCIC_BASE};
#elif SCIB_BASE
const uint32_t baseaddr[] = {SCIA_BASE, SCIB_BASE };
#else
const uint32_t baseaddr[] = {SCIA_BASE};
#endif

SCI_BASE are defines from outside my program and uint32_t values

I need the base addresses in runtime but it is platform dependent how many ports there are.

Thanks!

Upvotes: 1

Views: 49

Answers (2)

Gerhardh
Gerhardh

Reputation: 12404

What about something like this:

const uint32_t baseaddr[] = {
  SCIA_BASE,
#ifdef SCIB_BASE
  SCIB_BASE,
#ifdef SCIC_BASE
  SCIC_BASE,
#ifdef SCID_BASE
  SCID_BASE,
#endif
#endif
#endif
};

Or if you don't want to care about mathinc #endifs:

const uint32_t baseaddr[] = {
  SCIA_BASE,
#ifdef SCIB_BASE
  SCIB_BASE,
#endif
#ifdef SCIC_BASE
  SCIC_BASE,
#endif
#ifdef SCID_BASE
  SCID_BASE,
#endif
};

That is easy to extent if you get new addresses. Just add another 3 lines per address.

Upvotes: 2

Lundin
Lundin

Reputation: 215114

A more elegant way is to do something like this, in some global "mcu.h".

extern volatile const uint32_t SCI_PORTS; // number of supported ports

Then in "mcu.c":

#include "mcu.h"

#ifdef MCU_ABC_X
  volatile const uint32_t SCI_PORTS = 2; // allocated at fixed address
#elif MCU_ABC_Y
  volatile const uint32_t SCI_PORTS = 3; // allocated at fixed address
...
#endif

Then your array will always be

#include "mcu.h"

const uint32_t baseaddr[] = {SCIA_BASE, SCIB_BASE, SCIC_BASE, SCID_BASE};

for(size_t i=0; i<SCI_PORTS; i++)
  send(baseaddr[i], "hello world");

You only use SCI_PORTS number of items in that array. This allows SCI_PORTS to be placed at a fixed address like an EEPROM cell, and you'll then get the same binary no matter which MCU family member you compile for.

Upvotes: 1

Related Questions