Hi Joakim,
many thanks for your comprehensive answer.
First, let's clear up one thing regarding the current
implementation: The static const structs defined in periph_conf.h are
garbage collected in all modules where they are not directly used, so
usually, this means that it will only use ROM once (in the .rodata
section of the appropriate periph driver object). You can see this in
the .map file in the bin dir after building, there should only be one
reference to each configuration struct.
Yes, that's what I meant when I said "Each object file would have an
own copy of this static variable if it is used." I should have added
"and only if it is used" to clarify that.
I don't know if using the _NUMOF macro constitutes as usage with
regards to linker GC, if the compiler is smart then the struct itself
should not be allocated when you only use sizeof(pwm_conf) but never
reference pwm_conf itself.
I would guess that the `sizeof(array/array[0])` can be determined during
compile time and the structure is not allocated.
Putting the configuration struct in the periph driver implementation
file is equivalent to putting it in the header from the compiler
point of view when building the periph driver, so it should be
possible to perform the same optimizations as when the configuration
is in periph_conf.h, which is good.
Provided that it is used in periph module only.
Putting the configuration in the periph driver implementation will
place the configuration inside the CPU, which is bad for flexibility
and configurability.
Unless you also define an initializer macro somewhere in the board
config, e.g. periph_conf.h, which is a bit more inconvenient than the
current approach due to multi line macros needing to escape newlines
etc.
You are right, but there should be only configurable parts exposed in
header file. For example, for the ESP32 PWM, configuration details such
as the periphery module used, the register set used, the signal group
used, or the interrupt source used must not be changed by board
definition and should not be exposed to the header file. In case of
ESP32 PWM, only the pins used as PWM channels are configurable which is
exposed as a simple list of GPIO pins.
My impression is, if I'm not wrong, that some MCUs expose not only
configuration details but also implementation details in their `*_conf`
structs.
One possible alternative solution is to create a periph_conf.c file
in the board directory, and use extern declarations in periph_conf.h
just like you proposed in order to let the drivers access the
It was not a proposal but just a description how it is realized for
ESP32 boards at the moment. I'm just looking for some advise on whether
to change to the usual approach used in RIOT for other boards.
structs. The drawback here is that the compiler will not be able to
optimize away execution paths which are not reachable using the
current configuration. On some implementations this will make no
difference but on others this will make the code a lot larger due to
multiple large branches which would normally be optimized away due
to dead code elimination in the compiler.
In the case of ESP32, if I place the static arrays of PWM pins in the
header file instead of defining them as macros, the code gets a bit larger.
XFA would also have the same drawback as the periph_conf.c solution,
because the whole array is not visible to the compiler during
compilation of periph/abcd.c, so it can't fully perform DCE and other
optimizations.
Ah ok, I understand.
To summarize your e-mail, you would advise to change the definitions of
ESP32 boards to expose configuration structures in header files
according to the RIOT approach for board definitions.
Regards
Gunar