cgccembeddedmplabpic32

"initializer element is not constant" when using constant structs


I'm working with PIC32, MPLABX and XC32 and currently I have to make a lot of hardware description for each peripheral. Some of the tasks are something like:

In file1.h

extern const stream_t EHAL_PIN_STREAM_TEMPLATE;

In file1.c

const stream_t EHAL_PIN_STREAM_TEMPLATE = { 
    .field1 = constant, .field2 = constant, ... 
}

In file2.h

#include "file1.h"

const stream_ehal_pin_t EHAL_STREAM_PIN_RF1 = {
    .stream = EHAL_PIN_STREAM_TEMPLATE,
    .pin = &EHAL_PIN_RF1
};

Basically, I'm making a map between our streams and PIC32.RF1 digital pin and I wanted to make this using const global variables, but I get initializer element is not constant error when I try to use EHAL_PIN_STREAM_TEMPLATE.

Do you know any solution besides making EHAL_STREAM_PIN_RF1 initialization in runtime?

EDIT

Because I didn't wanted to make runtime initialization my solution was to make one macro per each EHAL_PIN_STREAM_TEMPLATE field and use those macros to fill EHAL_STREAM_PIN_RF1 structures:

 #include "file1.h"

 const stream_ehal_pin_t EHAL_STREAM_PIN_RF1 = {
    .stream = {FIELD1_TEMPLATE_VALUE, FIELD2_TEM...},
    .pin = &EHAL_PIN_RF1
 };

Solution

  • It is not possible to do what you want.

    There are three points in time to make initialization:

    Compile-time initialization needs the value at compilation - you may use macros for that, but not the value of a variable from a different compilation unit (a different .c file) as that is simply unavailable outside that compilation unit.

    Link-time initialization does not exist for simple values, it exists only for addresses of variables/functions within other compilation units. So, you can initialize a variable with the address of something in a different compilation unit, and that address will be substituted during linking.

    Run-time initialization is also an option but you didn't like that...

    Normally, people define macros in a header file (which can be included into multiple .c files) for such a purpose, if run-time initialization is not desired.