-
Notifications
You must be signed in to change notification settings - Fork 2.1k
drivers/periph/gpio_ll: shrink gpio_conf_t #20236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The following change is needed to avoid compilation errors. diff --git a/cpu/esp32/periph/gpio_ll.c b/cpu/esp32/periph/gpio_ll.c
index 2c3d730d84..13f387b516 100644
--- a/cpu/esp32/periph/gpio_ll.c
+++ b/cpu/esp32/periph/gpio_ll.c
@@ -151,7 +151,6 @@ int gpio_ll_init(gpio_port_t port, uint8_t pin, const gpio_conf_t *conf)
/* since we can't read back the configuration, we have to save it */
_gpio_conf[gpio] = *conf;
- _gpio_conf[gpio].schmitt_trigger = false;
if (esp_idf_gpio_config(&cfg) != ESP_OK) {
return -ENOTSUP; |
3b3ca2e
to
d315010
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, did you test this on all affected architectures?
d315010
to
3a69bf6
Compare
So, finally: EFM32
|
@benpicco Is the ACK still valid? The change since ACK boils down to passing the conf no longer as |
4dc9960
to
69ffb62
Compare
69ffb62
to
7d08c3c
Compare
7d08c3c
to
bd4e920
Compare
This commit optimizes the `gpio_conf_t` type in the following regards: - The "base" `gpio_conf_t` is stripped from members that only some platforms support, e.g. drive strength, slew rate, and disabling of the Schmitt Trigger are no longer universally available but platform-specific extensions - The `gpio_conf_t` is now crammed into a bit-field that is 8 bit or 16 bit wide. This allows for storing lots of them e.g. in `driver_foo_params_t` or `uart_conf_t` etc. - A `union` of the `struct` with bit-field members and a `bits` is used to allow accessing all bits in a simple C statement and to ensure alignment for efficient handling of the type Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
Printing the newline after the state was printed is not optional. This also moves the call to `gpio_ll_print_conf()` and `puts("")` to a static function to safe enough ROM so that this still can be flashed on `nucleo-l011k4`.
The default pin config is only a place holder anyway. But if it is invalid at least on AVR most of the firmware is considered unreachable. This updates the default GPIO config to something that should look plausible to the compiler for all MCUs supporting GPIO LL, so that ROM and RAM size in the CI start making sense.
bd4e920
to
04d537c
Compare
Now that `gpio_conf_t` is on all implemented platforms no larger than a register, we can more efficiently pass it by value rather than via pointer.
04d537c
to
9222762
Compare
Woohooo! 👯 🎉 Thx for the reviews :) |
Contribution description
This commit optimizes the
gpio_conf_t
type in the following regards:gpio_conf_t
is stripped from members that only some platforms support, e.g. drive strength, slew rate, and disabling of the Schmitt Trigger are no longer universally available but platform-specific extensionsgpio_conf_t
is now crammed into a bit-field that is 8 bit or 16 bit wide. This allows for storing lots of them e.g. indriver_foo_params_t
oruart_conf_t
etc.union
of thestruct
with bit-field members and abits
is used to allow accessing all bits in a simple C statement and to ensure alignment for efficient handling of the typeIn addition
gpio_conf_t
is no longer passed via pointer, but by value. Because it now is small enough to fit in a register on all supported platforms, this results in less overhead when callinggpio_ll_init()
.Testing procedure
The provided test app should still work for all supported MCU families.
Trade-Off Involved
Dropping members (such as disabling of the Schmitt Trigger, or selecting the slew rate) that are not universally found from the common interface is IMO uncontroversial. The more fancy MCUs just provide their own
gpio_conf_t
and still provide all the features they have, but the basic MCUs have a lot less overhead.The use of bit fields is IMO controversial:
Pros:
gpio_conf_t
to the point that it is acceptable to heavily use it infoo_params_t
in drivers orfoo_conf_t
in the boardsperiph_conf.h
Cons:
gpio_ll_init()
,gpio_ll_query_conf()
, andgpio_ll_print_conf
.gpio_ll_query_conf()
andgpio_ll_print_conf()
are super useful for debugging, but I don't see them used for other stuff. IMO overhead here doesn't mattergpio_ll_init()
IMO doesn't matter that much, as this is not typically done.gpio_ll_init()
is too slow already as it is. But I think it would be possible to add an optional API for just changing the direction. In any case, this is out of scope of this PR.)==> The overhead in terms of ROM specifically for
gpio_ll_init()
is the most relevant oneOn Cortex M0 / STM32
This PR:
master
:On Cortex M0+ / EFM32ZG
This PR:
master
:On Cortex M4(F) / STM32
This PR:
master
:On Cortex M4(F) / nRF5x
This PR:
master
:On AVR
This PR:
master
:On ESP32
This PR:
master
:Summary
The size of
gpio_conf_t
goes down from 7 B to 1 B or 2 B, so at least 5B is saved for every storedgpio_conf_t
. This comes for a cost for up to 26 B increase ingpio_ll_init()
.We safe ROM latest when 6 instances of
gpio_conf_t
are stored in flash. This would already be the case when two SPI buses with onegpio_conf_t
per pin is used.Issues/PRs references
None