Skip to content

Conversation

david-cermak
Copy link
Collaborator

@david-cermak david-cermak commented Sep 29, 2025

WIP, needs testing


Note

Introduces UART DMA (UHCI) terminal/DTE with config flags, updates API and build, and enables optional DMA in the modem_console example.

  • Core (esp_modem):
    • UART DMA terminal: Add UHCI-based implementation src/esp_modem_uart_dma.cpp with public API include/esp_modem_uart_dma.h.
    • API: Add create_uart_dma_dte in esp_modem_api.hpp and implement in src/esp_modem_api_target.cpp.
    • Config: Extend esp_modem_uart_term_config with use_dma and dma_buffer_size (defaults set in ESP_MODEM_DTE_DEFAULT_CONFIG).
    • Build: Include src/esp_modem_uart_dma.cpp in CMakeLists.txt and add dependency on esp_driver_uart.
  • Example (modem_console):
    • DMA integration: Conditionally enable DMA via Kconfig; set use_dma and dma_buffer_size; create DTE with create_uart_dma_dte when enabled; add logs.
    • Docs/Config: Update README with UART DMA details; enable DMA by default and set buffer size in sdkconfig.defaults.

Written by Cursor Bugbot for commit 3b0b7dd. This will update automatically on new commits. Configure here.

@david-cermak david-cermak self-assigned this Sep 29, 2025
cursor[bot]

This comment was marked as outdated.

.uart_port = uart.port,
.tx_trans_queue_depth = 2,
.max_receive_internal_mem = dma_buffer_size,
.max_transmit_size = dma_buffer_size,

Check warning

Code scanning / clang-tidy

ISO C++ requires field designators to be specified in declaration order; field 'max_receive_internal_mem' will be initialized after field 'max_transmit_size' [clang-diagnostic-reorder-init-list] Warning

ISO C++ requires field designators to be specified in declaration order; field 'max_receive_internal_mem' will be initialized after field 'max_transmit_size' [clang-diagnostic-reorder-init-list]
// Protect shared state access
if (xSemaphoreTake(rx_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
size_t current_received_size = received_size;
bool current_rx_complete = rx_complete;

Check warning

Code scanning / clang-tidy

Value stored to 'current_rx_complete' during its initialization is never read [clang-analyzer-deadcode.DeadStores] Warning

Value stored to 'current_rx_complete' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
// Protect shared state access
if (xSemaphoreTake(rx_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
size_t current_received_size = received_size;
bool current_rx_complete = rx_complete;

Check warning

Code scanning / clang-tidy

unused variable 'current_rx_complete' [clang-diagnostic-unused-variable] Warning

unused variable 'current_rx_complete' [clang-diagnostic-unused-variable]
if (rx_mutex) {
vSemaphoreDelete(rx_mutex);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Uninitialized Mutex Leads to Undefined Behavior

The rx_mutex member isn't initialized in the UartDmaTerminal constructor. When DMA is disabled, this leaves rx_mutex with an undefined value, causing the destructor's if (rx_mutex) check and vSemaphoreDelete call to operate on an uninitialized pointer, which can lead to undefined behavior.

Fix in Cursor Fix in Web

// Notify the task that data is available
xSemaphoreGiveFromISR(terminal->rx_semaphore, &xHigherPriorityTaskWoken);

return xHigherPriorityTaskWoken; // Return whether a higher priority task was woken
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: ISR Mutex Conflict and Return Type Mismatch

The uhci_rx_event_callback runs in an ISR, but it uses rx_mutex (a regular mutex) with ISR-safe semaphore functions, which can lead to undefined behavior. There's also a type mismatch where the function returns a BaseType_t (xHigherPriorityTaskWoken) while declared to return bool.

Fix in Cursor Fix in Web

xSemaphoreGive(rx_mutex);
return copy_len;
}
return 0; // Timeout or error
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: DMA Buffer Corruption During Concurrent Access

A race condition exists where the DMA rx_buffer is accessed by the read() function or on_read callback while the DMA hardware may be concurrently writing to it. The rx_mutex protects software state but doesn't prevent the DMA hardware from corrupting the buffer during software operations like memmove or on_read processing, leading to data corruption or inconsistent reads.

Additional Locations (1)

Fix in Cursor Fix in Web

src/esp_modem_term_uart.cpp
src/esp_modem_netif.cpp)
set(dependencies driver esp_event esp_netif)
set(dependencies driver esp_event esp_netif esp_driver_uart)
Copy link
Collaborator

@tore-espressif tore-espressif Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@david-cermak Is there any ETA for this change?

Currently it breaks our builds with esp-idf/master. (We build esp_modem_usb_dte in our USB CI, which in turn pulls in esp_modem.) https://github.com/espressif/esp-usb/actions/runs/18191462194/job/51787270030?pr=276#step:4:1917

We can temporarily disable the build job if next esp_modem release needs more time

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe...?

Suggested change
set(dependencies driver esp_event esp_netif esp_driver_uart)
set(dependencies esp_event esp_netif esp_driver_uart)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can temporarily disable the build job if next esp_modem release needs more time

Please disable the build for now, got some breaking changes on master already, so I'll have to branch off...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants