-
Notifications
You must be signed in to change notification settings - Fork 2.1k
cpu/esp32: fix and improve UART initialization #19146
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
cpu/esp32: fix and improve UART initialization #19146
Conversation
If LOG_LEVEL >= 4, such as in `tests/log_printfnoformat`, the ESP-IDF config function called for the GPIO pins of the UART will output the configuration with `printf` before the `_GLOBAL_REENT` structure is initialized. This causes a crash during system startup. Therefore the initialization by `syscalls_init` must be called earlier in the startup procedure.
Since PR RIOT-OS#19100 it is possible to define: - other pins for `UART_DEV(0)` than the default pins - different `UART_DEV(0)` pins for the bootloader and RIOT To allow correct reinitialization of the UART pins used by the bootloader as well as their usage for other purposes, the pin usage for the default UART0 pins and the UART pins used by the bootloader are reset to `_GPIO`. This is done in `uart_system_init` which has to be called earlier in the startup procedure.
The TX line is set and temporarily configured as a pull-up open-drain output before configuring it as a push-pull output to avoid a several msec long LOW pulse resulting in some garbage.
To avoid garbage on reconfiguring the UART console pins, e.g. in initialization of the `arduino` module, pins that are already configured as UART pins must not be initialized.
|
At least the log_noformat test was run prior to cancelation and succeeded, so this indeed seems to fix the issue. |
maribu
left a comment
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.
bors merge
Code looks good and at least one test previously failing now succeeds in the CI.
|
🕐 Waiting for PR status (GitHub check) to be set, probably by CI. Bors will automatically try to run when all required PR statuses are set. |
| return -1; | ||
| } | ||
| assert(uart_config[uart].txd != GPIO_UNDEF); | ||
| assert(uart_config[uart].rxd != GPIO_UNDEF); |
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.
There are use cases of TX only / RX only UARTs.
This is generally allowed by other UART implementations, e.g sam0_common.
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.
OK understand, also the ESP8266 has a second UART device which can only be TX.
But this change is not a regression from the previous implementation, which didn't really work for TX-only and RX-only interface, because it didn't handle the TX and RX pin separately.
For now, this PR would fix the problem in the release version. The handling of TX- or RX-only UARTs could be improved as a follow-up.
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.
Ok, let’s do that as a follow-up then
bors merge
|
bors cancel |
|
Build succeeded: |
|
Thanks for reviewing and testing. |
19148: cpu/esp32: fix and improve UART initialization [backport 2023.01] r=maribu a=gschorcht # Backport of PR #19146 ### Contribution description This PR fixes issue #19138 that was introduced with PR #19100. It contains the following changes to fix the problems and to improve the UART initialization: - If `LOG_LEVEL` is greater or equal 4, such as in `tests/log_printfnoformat`, the ESP-IDF config function called for the GPIO pins of the UART will output the configuration with `printf` before the `_GLOBAL_REENT` structure is initialized. This causes a crash during system startup. Therefore the initialization by `syscalls_init` must be called by `earlier in the startup procedure. - Since PR #19100 it is possible to define: - other pins for `UART_DEV(0)` than the default pins - different `UART_DEV(0)` pins for the bootloader and RIOT To allow correct reinitialization of the UART pins used by the bootloader as well as their usage for other purposes, the pin usage for the default UART0 pins and the UART pinsused by the bootloader are reset to `_GPIO`. This is done in `uart_system_init` which has to be called earlier in the startup procedure. - To avoid garbage on reconfiguring the UART console pins, e.g. in initialization of the `arduino` module, pins that are already configured as UART pins must not be initialized. - To avoid a several msec long LOW pulse resulting in some garbage during the UART initialization, the TX line is set to HIGH and temporarily configured as a pull-up open-drain output before configuring it as a push-pull output. The PR requires a backport to 2023.1 ### Testing procedure The following tests should work with this PR: - [ ] `tests/log_color` - [ ] `tests/log_printfnoformat` - [ ] `tests/sys_arduino` ### Issues/PRs references Fixes #19138 Co-authored-by: Gunar Schorcht <[email protected]>
19192: cpu/esp32: fixes for boot issues and crashes on ESP32 r=gschorcht a=Flole998 ### Contribution description In syscalls_init() there is a call to malloc(), which will return NULL if the heap is not initialized before, causing the entire board to fail booting if MODULE_ESP_IDF_HEAP is used. API of [vTaskDelete()](https://www.freertos.org/a00126.html) says, that if NULL is passed to vTaskDelete the calling task should be deleted. This PR needs a backport to 2023.01. ### Testing procedure Just compiling on the ESP32S2 and running it with WiFi caused it to not start anymore, no output, nothing. When Null is written to that null-pointer it hangs. The second commit fixed an issue/assertion fail that happens when the WiFi connection drops/disconnects. ### Issues/PRs references Issue was introduced with PR #19146 Co-authored-by: Flole998 <[email protected]>
19192: cpu/esp32: fixes for boot issues and crashes on ESP32 r=kaspar030 a=Flole998 ### Contribution description In syscalls_init() there is a call to malloc(), which will return NULL if the heap is not initialized before, causing the entire board to fail booting if MODULE_ESP_IDF_HEAP is used. API of [vTaskDelete()](https://www.freertos.org/a00126.html) says, that if NULL is passed to vTaskDelete the calling task should be deleted. This PR needs a backport to 2023.01. ### Testing procedure Just compiling on the ESP32S2 and running it with WiFi caused it to not start anymore, no output, nothing. When Null is written to that null-pointer it hangs. The second commit fixed an issue/assertion fail that happens when the WiFi connection drops/disconnects. ### Issues/PRs references Issue was introduced with PR #19146 Co-authored-by: Flole998 <[email protected]>
19196: cpu/esp32: fixes for boot issues and crashes on ESP32 [backport 2023.1] r=benpicco a=gschorcht # Backport of PR #19192 ### Contribution description In `syscalls_init()` there is a call to `malloc()`, which will return `NULL` if the heap is not initialized before, causing the entire board to fail booting if module `esp_idf_heap` is used, for example if the WiFi network interface is used. API of [vTaskDelete()](https://www.freertos.org/a00126.html) says, that if NULL is passed to vTaskDelete the calling task should be deleted. This PR needs a backport to 2023.01. ### Testing procedure ``` USEMODULE=esp_idf_heap BOARD=esp32-wroom-32 make -C tests/malloc ```` should work now but hangs in startup without the PR. ### Issues/PRs references Issue was introduced with PR #19146 Co-authored-by: Flole998 <[email protected]>
Contribution description
This PR fixes issue #19138 that was introduced with PR #19100. It contains the following changes to fix the problems and to improve the UART initialization:
If
LOG_LEVELis greater or equal 4, such as intests/log_printfnoformat, the ESP-IDF config function called for the GPIO pins of the UART will output the configuration withprintfbefore the_GLOBAL_REENTstructure is initialized. This causes a crash during system startup. Therefore the initialization bysyscalls_initmust be called by `earlier in the startup procedure.Since PR cpu/esp_common: allow configuration of UART0 #19100 it is possible to define:
UART_DEV(0)than the default pinsUART_DEV(0)pins for the bootloader and RIOTTo allow correct reinitialization of the UART pins used by the bootloader as well as their usage for other purposes, the pin usage for the default UART0 pins and the UART pinsused by the bootloader are reset to
_GPIO. This is done inuart_system_initwhich has to be called earlier in the startup procedure.To avoid garbage on reconfiguring the UART console pins, e.g. in initialization of the
arduinomodule, pins that are already configured as UART pins must not be initialized.To avoid a several msec long LOW pulse resulting in some garbage during the UART initialization, the TX line is set to HIGH and temporarily configured as a pull-up open-drain output before configuring it as a push-pull output.
The PR requires a backport to 2023.1
Testing procedure
The following tests should work with this PR:
tests/log_colortests/log_printfnoformattests/sys_arduinoIssues/PRs references
Fixes #19138