Root cause (verified against our exact IDF tree, not the community guess): the "258" in "sdio_write_task: Failed to send data: 258" is NOT a timeout (that is 263). 258 = 0x102 = ESP_ERR_INVALID_ARG. On the ESP32-P4, block- mode CMD53 writes require the SOURCE buffer to be 64-byte (cache-line) aligned; the IDF sdmmc driver rejects a misaligned source with INVALID_ARG BEFORE any bus activity. esp_hosts write loop then declares "Unrecoverable host sdio state" and reboots the whole P4. The audio TX payload is not 64-aligned, so streaming mic audio wedged on the very FIRST frame (which is exactly what we saw: listening -> instant Failed to send -> reboot). This also explains why buffer/queue/clock/retry tuning all did nothing: the write never reached the bus. And why our symptom was instant, not after ~100 writes (the community block-mode-desync theory) — it is the first misaligned buffer, every time. Fix: vendored esp_hosted 2.12.11 as an editable local component (overrides the registry copy) and bounce a misaligned TX payload through one aligned DMA scratch buffer in hosted_sdio_write_block (port_esp_hosted_host_sdio.c). TX is serialized by the bus lock so a single static bounce buffer is safe; freed in hosted_sdio_deinit. Host-only change — no C6 reflash. VERIFIED ON HARDWARE (autonomous self-test): 40s of continuous mic-audio upstream streaming — the traffic that previously wedged on the first frame — ran clean, zero timeouts, zero reboots. A guarded SDIO_TX_SELFTEST harness is kept (compiled out) for future SDIO stress testing. Credit: root cause + patch designed via multi-agent investigation; the precise 258=INVALID_ARG decode (correcting the upstream community timeout assumption) came from checking our actual esp_err.h. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| Supported Hosts | ESP32 | ESP32-P Series | ESP32-H Series | ESP32-C Series | ESP32-S Series | Any other MCU hosts |
|---|
| Supported Co-Processors | ESP32 | ESP32-C Series | ESP32-S Series |
|---|
ESP-Hosted Co-processor Memory Info Example
This host example enables a memory monitor on the co-processor. This can be used to monitor the heap usage on the co-processor. Once enabled, the host can:
- query the heap usage on the co-processor at any time, or
- get a periodic memory report from the co-processor, or
- get a memory report only when the heap size on the co-processor falls below memory thresholds set by the host
This has been tested with the ESP32-C5 co-processor, flashed with the standard ESP-Hosted slave example from the ESP Component Registry, or built from the slave directory from ESP-Hosted Github.
To show the heap size changing on the co-processor, the example enables Wi-Fi, then connects and disconnects from an AP.
Prerequisite
Setting up the Co-Processor
Fetch the co-processor code using the ESP Registry ESP-Hosted-MCU Slave example.
Quick steps:
idf.py create-project-from-example "espressif/esp_hosted:slave"
cd slave
idf.py set-target <cp_chip_type>
Start idf.py menuconfig and ensure that Example Configuration ---> Enable Memory Monitor Interface is enabled.
Note
PSRAM must be enabled on the co-processor to get memory reports on external memory and to set the external memory thresholds. Ensure that
Component config--->ESP PSRAM--->Support for external, SPI-connected RAMis enabled.
Now build and flash the code on the co-processor.
idf.py -p <cp_port> flash monitor
Where cp_chip_type is one of ESP32, ESP32-C Series or ESP32-S Series as the co-processor.
Alternatively, you built from the slave directory of the ESP-Hosted-MCU GitHub repository.
Building the Host
Start idf.py menuconfig and ensure that Component Config ---> ESP-Hosted config ---> Enable Memory Monitor Interface is enabled. There are three ways to configure the example:
- Do a one time query: enable
Query Memory Info only once - Get a periodic report: enter a
Memory Monitor Interval(default is10seconds) and enableAlways send a memory report - Get a report only when memory falls below a threshold: disable
Always send a memory reportand enter one or more threshold values for DMA / 8-bit for internal / external memory
See the section below for more information on how to configure the example.
Now build and flash the code on the host.
idf.py -p <host_port> flash monitor
Setting up the Memory Info Request
The example uses this API call to set the memory monitor:
esp_err_t esp_hosted_set_mem_monitor(esp_hosted_config_mem_monitor_t *config, esp_hosted_curr_mem_info_t *curr_mem_info)
where:
esp_hosted_config_mem_monitor_t: pointer to the structure containing the mem monitor configurationesp_hosted_curr_mem_info_t: pointer to a structure that will hold the returned memory report when the call returns. This is valid only if the return value isESP_OK
See esp_hosted_misc_types.h for details on the structures.
For example, to enable the memory monitor to periodically return a report every 10 seconds:
esp_hosted_curr_mem_info_t curr_mem_info = { 0 };
esp_hosted_config_mem_monitor_t config = {
.config = ESP_HOSTED_MEMMONITOR_ENABLE,
.report_always = true,
.interval_sec = 10,
// since we always get a report, no need to set thresholds
.internal_mem.threshold_mem_dma = 0,
.internal_mem.threshold_mem_8bit = 0,
.external_mem.threshold_mem_dma = 0,
.external_mem.threshold_mem_8bit = 0,
};
esp_err_t res = esp_hosted_set_mem_monitor(&config, &curr_mem_info);
curr_mem_info contains the current heap info from the co-processor if res is ESP_OK.
Memory Info Reported
The returned memory report contains this information from the co-processor:
- the current memory report configuration on the co-processor
- the current total heap size
- the current internal and external free and largest free block for DMA or for 8/16/...-bit access
Memory Monitor Event
If periodic reporting is enabled, or when heap memory falls below a set threshold, a memory report event is sent to the host by the co-processor, with an event base of ESP_HOSTED_EVENT:
ESP_HOSTED_EVENT_MEM_MONITOR: sent by the co-processor to the Host with a memory usage report of typeesp_hosted_event_mem_info_tas the event data.
The event data contains this information from the co-processor:
- the current total free heap size
- the minimum free heap size since boot
- the current internal and external free and largest free block for DMA or for 8/16/...-bit access
How to Use This Example
The example shows how heap usage on the co-processor changes when Wi-Fi operations are performed:
- Starts the example with Wi-Fi disabled
- Enable Wi-Fi
- Connect to an AP
- Disconnected from an AP
Delays are deliberately introduced after each step to give time for memory reports to be returned (if enabled).
The example also shows how to use the memory monitor in the following ways:
- Get a one time report: the memory report is read once on app start up.
- Periodically generate a memory report: a memory report is generated periodically.
- Generate a memory report when memory usage drops below a threshold: no memory report is received until after the Wi-Fi connection has cause heap space to drop below a set threshold.
The hardware used in the example is a ESP32-P4 connected to a ESP32-C5 as the co-processor with PSRAM on the C5 enabled.
Configuring the memory report options on the ESP32-P4 host
Set the correct chip target:
idf.py set-target esp32p4
Open the project configuration menu:
idf.py menuconfig
Set the memory report configuration as required. The sections below show the configuration setup. Then, configure the Wi-Fi station parameters at needed:
- Set WiFi SSID.
- Set WiFi Password.
Optional: If you need, change the other Wi-Fi options according to your requirements.
Build and Flash
Run idf.py -p HOST_PORT flash monitor to build, flash and monitor the
project.
(To exit the serial monitor, type Ctrl-].)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
Example Output
Example 1: Generate a one time report
A one-time memory report is queried by the host.
In the Kconfig Example Configuration:
- enable
Query Memory Info only once(other memory report settings are now hidden) - set the required Wi-Fi settings
This is the example output. A report is generated only once.
Select to see output
[...]
I (1867) hosted_meminfo: ESP-Hosted Transport is UP
I (1997) hosted_meminfo: ESP-Hosted is ready
I (2137) RPC_WRAP: Coprocessor Boot-up
I (2137) hosted_meminfo: *** got INIT event from co-processor ***
I (2137) hosted_meminfo: *** Co-processor Reset Reason 1 ***
I (2137) hosted_meminfo: ======= Current Co-processor Mem Info =====
I (2137) hosted_meminfo: mem monitoring enabled : 0
I (2137) hosted_meminfo: report always : 0
I (2137) hosted_meminfo: reporting interval : 0
I (2137) hosted_meminfo: current heap size : 4299348
I (2137) hosted_meminfo: ----------------------------------------------
I (2137) hosted_meminfo: | | | Largest |
I (2137) hosted_meminfo: | Current Heap Size | Free Size | Free Block |
I (2137) hosted_meminfo: |-------------------|-----------|------------|
I (2137) hosted_meminfo: | Internal DMA | 123359 | 86016 |
I (2137) hosted_meminfo: | Internal 8Bit | 139303 | 86016 |
I (2137) hosted_meminfo: | External DMA | 0 | 0 |
I (2137) hosted_meminfo: | External 8Bit | 4191920 | 4128768 |
I (2137) hosted_meminfo: ----------------------------------------------
I (2137) hosted_meminfo: delaying for 10 secs before connecting
I (12137) transport: Attempt connection with slave: retry[0]
I (12137) transport: Transport is already up
I (13187) wifi station: wifi_init_sta finished.
I (13187) RPC_WRAP: ESP Event: wifi station started
I (13187) H_API: esp_wifi_remote_connect
I (13207) RPC_WRAP: ESP Event: wifi station started
I (13807) RPC_WRAP: ESP Event: Station mode: Connected
I (14217) RPC_WRAP: ESP Event: Station mode: Connected
I (14217) RPC_WRAP: ESP Event: Station mode: Connected
I (14237) esp_wifi_remote: esp_wifi_internal_reg_rxcb: sta: 0x40046e20
--- 0x40046e20: wifi_sta_receive at /home/kysoh/esp/github_esp-idf/components/esp_wifi/src/wifi_netif.c:38
I (15257) wifi station: got ip:10.10.2.152
I (15257) esp_netif_handlers: sta ip: 10.10.2.152, mask: 255.255.255.0, gw: 10.10.2.1
I (15257) wifi station: connected to ap SSID:xxx password:yyy
I (15257) hosted_meminfo: delaying for 10 secs before disconnecting
I (25277) main_task: Returned from app_main()
I (25287) RPC_WRAP: ESP Event: Station mode: Disconnected
I (25287) wifi station: do not reconnect
[...]
Example 2: Periodically generate a memory report
The co-processor sends a memory report periodically.
In the Example Configuration:
- disable
Query Memory Info only once - set
Memory Monitor Interval (in seconds). Default is 10 seconds - enable
Always send a memory report - set the required Wi-Fi settings
This is the example output. A report is generated at every reporting interval.
Select to see output
[...]
I (1867) hosted_meminfo: ESP-Hosted Transport is UP
I (1997) hosted_meminfo: ESP-Hosted is ready
I (2137) RPC_WRAP: Coprocessor Boot-up
I (2137) hosted_meminfo: *** got INIT event from co-processor ***
I (2137) hosted_meminfo: *** Co-processor Reset Reason 1 ***
I (2137) hosted_meminfo: ======= Current Co-processor Mem Info =====
I (2137) hosted_meminfo: mem monitoring enabled : 1
I (2137) hosted_meminfo: report always : 1
I (2137) hosted_meminfo: reporting interval : 10
I (2137) hosted_meminfo: current heap size : 4299280
I (2137) hosted_meminfo: ----------------------------------------------
I (2137) hosted_meminfo: | | | Largest |
I (2137) hosted_meminfo: | Current Heap Size | Free Size | Free Block |
I (2137) hosted_meminfo: |-------------------|-----------|------------|
I (2137) hosted_meminfo: | Internal DMA | 123291 | 86016 |
I (2137) hosted_meminfo: | Internal 8Bit | 139235 | 86016 |
I (2137) hosted_meminfo: | External DMA | 0 | 0 |
I (2137) hosted_meminfo: | External 8Bit | 4191920 | 4128768 |
I (2137) hosted_meminfo: ----------------------------------------------
I (2137) hosted_meminfo: delaying for 20 secs before connecting
I (12137) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (12137) hosted_meminfo: Total free heap size : 4299532
I (12137) hosted_meminfo: Min free heap size : 4295348
I (12137) hosted_meminfo: ----------------------------------------------
I (12137) hosted_meminfo: | | | Largest |
I (12137) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (12137) hosted_meminfo: |-------------------|-----------|------------|
I (12137) hosted_meminfo: | Internal DMA | 123699 | 86016 |
I (12137) hosted_meminfo: | Internal 8Bit | 139643 | 86016 |
I (12137) hosted_meminfo: | External DMA | 0 | 0 |
I (12137) hosted_meminfo: | External 8Bit | 4191920 | 4128768 |
I (12137) hosted_meminfo: ----------------------------------------------
I (22137) transport: Attempt connection with slave: retry[0]
I (22137) transport: Transport is already up
I (22287) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (22287) hosted_meminfo: Total free heap size : 4288288
I (22287) hosted_meminfo: Min free heap size : 4288288
I (22287) hosted_meminfo: ----------------------------------------------
I (22287) hosted_meminfo: | | | Largest |
I (22287) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (22287) hosted_meminfo: |-------------------|-----------|------------|
I (22287) hosted_meminfo: | Internal DMA | 112455 | 77824 |
I (22287) hosted_meminfo: | Internal 8Bit | 128399 | 77824 |
I (22287) hosted_meminfo: | External DMA | 0 | 0 |
I (22287) hosted_meminfo: | External 8Bit | 4191920 | 4128768 |
I (22287) hosted_meminfo: ----------------------------------------------
I (23187) wifi station: wifi_init_sta finished.
I (23197) RPC_WRAP: ESP Event: wifi station started
I (23197) H_API: esp_wifi_remote_connect
I (23207) RPC_WRAP: ESP Event: wifi station started
I (23717) RPC_WRAP: ESP Event: Station mode: Connected
I (24227) RPC_WRAP: ESP Event: Station mode: Connected
I (24227) RPC_WRAP: ESP Event: Station mode: Connected
I (24237) esp_wifi_remote: esp_wifi_internal_reg_rxcb: sta: 0x40046e38
--- 0x40046e38: wifi_sta_receive at /home/kysoh/esp/github_esp-idf/components/esp_wifi/src/wifi_netif.c:38
I (25277) wifi station: got ip:10.10.2.152
I (25277) esp_netif_handlers: sta ip: 10.10.2.152, mask: 255.255.255.0, gw: 10.10.2.1
I (25277) wifi station: connected to ap SSID:xxx password:yyy
I (25277) hosted_meminfo: delaying for 20 secs before disconnecting
I (32137) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (32137) hosted_meminfo: Total free heap size : 4256044
I (32137) hosted_meminfo: Min free heap size : 4253944
I (32137) hosted_meminfo: ----------------------------------------------
I (32137) hosted_meminfo: | | | Largest |
I (32137) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (32137) hosted_meminfo: |-------------------|-----------|------------|
I (32137) hosted_meminfo: | Internal DMA | 80279 | 45056 |
I (32137) hosted_meminfo: | Internal 8Bit | 96223 | 45056 |
I (32137) hosted_meminfo: | External DMA | 0 | 0 |
I (32137) hosted_meminfo: | External 8Bit | 4191852 | 4128768 |
I (32137) hosted_meminfo: ----------------------------------------------
I (42137) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (42137) hosted_meminfo: Total free heap size : 4256044
I (42137) hosted_meminfo: Min free heap size : 4253944
I (42137) hosted_meminfo: ----------------------------------------------
I (42137) hosted_meminfo: | | | Largest |
I (42137) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (42137) hosted_meminfo: |-------------------|-----------|------------|
I (42137) hosted_meminfo: | Internal DMA | 80279 | 45056 |
I (42137) hosted_meminfo: | Internal 8Bit | 96223 | 45056 |
I (42137) hosted_meminfo: | External DMA | 0 | 0 |
I (42137) hosted_meminfo: | External 8Bit | 4191852 | 4128768 |
I (42137) hosted_meminfo: ----------------------------------------------
I (45297) main_task: Returned from app_main()
I (45307) RPC_WRAP: ESP Event: Station mode: Disconnected
I (45307) wifi station: do not reconnect
I (52137) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (52137) hosted_meminfo: Total free heap size : 4256900
I (52137) hosted_meminfo: Min free heap size : 4253944
I (52137) hosted_meminfo: ----------------------------------------------
I (52137) hosted_meminfo: | | | Largest |
I (52137) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (52137) hosted_meminfo: |-------------------|-----------|------------|
I (52137) hosted_meminfo: | Internal DMA | 81135 | 45056 |
I (52137) hosted_meminfo: | Internal 8Bit | 97079 | 45056 |
I (52137) hosted_meminfo: | External DMA | 0 | 0 |
I (52137) hosted_meminfo: | External 8Bit | 4191852 | 4128768 |
I (52137) hosted_meminfo: ----------------------------------------------
[...]
Example 3: Generate a memory report when heap memory drops below threshold
The co-processor only sends a memory report when heap memory drops below a threshold value. Here, a report is only sent while the station is connected to the AP.
In the previous example, the Internal DMA free size after connecting is 80279, and after disconnecting is 81135. We choose a value that is in between for the threshold: 81000. Adjust this value as required based on your system.
In the Example Configuration:
- disable
Query Memory Info only once - set
Memory Monitor Interval (in seconds). Default is 10 seconds - disable
Always send a memory report - set
Threshold for internal DMA Heap Memory (in bytes)to81000 - set the threshold for other parameters to
0to disable them - set the required Wi-Fi settings
This is the example output. A report is generated only when the internal DMA heap memory is lower than the threshold of 81,000 bytes (only when connected to the AP).
Select to see output
[...]
I (1867) hosted_meminfo: ESP-Hosted Transport is UP
I (1997) hosted_meminfo: ESP-Hosted is ready
I (2137) RPC_WRAP: Coprocessor Boot-up
I (2137) hosted_meminfo: *** got INIT event from co-processor ***
I (2137) hosted_meminfo: *** Co-processor Reset Reason 1 ***
I (2137) hosted_meminfo: ======= Current Co-processor Mem Info =====
I (2137) hosted_meminfo: mem monitoring enabled : 1
I (2137) hosted_meminfo: report always : 0
I (2137) hosted_meminfo: reporting interval : 10
I (2137) hosted_meminfo: current heap size : 4299292
I (2137) hosted_meminfo: ----------------------------------------------
I (2137) hosted_meminfo: | | | Largest |
I (2137) hosted_meminfo: | Current Heap Size | Free Size | Free Block |
I (2137) hosted_meminfo: |-------------------|-----------|------------|
I (2137) hosted_meminfo: | Internal DMA | 123303 | 86016 |
I (2137) hosted_meminfo: | Internal 8Bit | 139247 | 86016 |
I (2137) hosted_meminfo: | External DMA | 0 | 0 |
I (2137) hosted_meminfo: | External 8Bit | 4191920 | 4128768 |
I (2137) hosted_meminfo: ----------------------------------------------
I (2137) hosted_meminfo: delaying for 20 secs before connecting
I (22147) transport: Attempt connection with slave: retry[0]
I (22147) transport: Transport is already up
I (23197) wifi station: wifi_init_sta finished.
I (23207) RPC_WRAP: ESP Event: wifi station started
I (23207) H_API: esp_wifi_remote_connect
I (23217) RPC_WRAP: ESP Event: wifi station started
I (23817) RPC_WRAP: ESP Event: Station mode: Connected
I (24237) RPC_WRAP: ESP Event: Station mode: Connected
I (24237) RPC_WRAP: ESP Event: Station mode: Connected
I (24247) esp_wifi_remote: esp_wifi_internal_reg_rxcb: sta: 0x40046e32
--- 0x40046e32: wifi_sta_receive at /home/kysoh/esp/github_esp-idf/components/esp_wifi/src/wifi_netif.c:38
I (25267) wifi station: got ip:10.10.2.152
I (25267) esp_netif_handlers: sta ip: 10.10.2.152, mask: 255.255.255.0, gw: 10.10.2.1
I (25267) wifi station: connected to ap SSID:xxx password:yyy
I (25267) hosted_meminfo: delaying for 20 secs before disconnecting
I (32137) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (32137) hosted_meminfo: Total free heap size : 4256020
I (32137) hosted_meminfo: Min free heap size : 4253572
I (32137) hosted_meminfo: ----------------------------------------------
I (32137) hosted_meminfo: | | | Largest |
I (32137) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (32137) hosted_meminfo: |-------------------|-----------|------------|
I (32137) hosted_meminfo: | Internal DMA | 80255 | 47104 |
I (32137) hosted_meminfo: | Internal 8Bit | 96199 | 47104 |
I (32137) hosted_meminfo: | External DMA | 0 | 0 |
I (32137) hosted_meminfo: | External 8Bit | 4191852 | 4128768 |
I (32137) hosted_meminfo: ----------------------------------------------
I (42137) hosted_meminfo: ======== Event: Co-processor Mem Info ========
I (42137) hosted_meminfo: Total free heap size : 4256020
I (42137) hosted_meminfo: Min free heap size : 4253572
I (42137) hosted_meminfo: ----------------------------------------------
I (42137) hosted_meminfo: | | | Largest |
I (42137) hosted_meminfo: | Heap Size | Free Size | Free Block |
I (42137) hosted_meminfo: |-------------------|-----------|------------|
I (42137) hosted_meminfo: | Internal DMA | 80255 | 47104 |
I (42137) hosted_meminfo: | Internal 8Bit | 96199 | 47104 |
I (42137) hosted_meminfo: | External DMA | 0 | 0 |
I (42137) hosted_meminfo: | External 8Bit | 4191852 | 4128768 |
I (42137) hosted_meminfo: ----------------------------------------------
[...]
References
- ESP-IDF documentation on Memory Capabilities
- ESP-IDF documentation on Heap information.
- ESP-IDF capabilities of memory systems