/* * The Kconfig surface ESP-Hosted's C compiles against in this project. * * Two parts, deliberately separated: * * sdkconfig_idf.h ESP-IDF v6.0.2's generated header, verbatim, from the build in * 02-esp32p4-m3-radio that reached transport state "active" on this die. * Unedited, so its provenance is checkable. * * this file that header, plus a short list of overrides. Each one states what it changes * and why, so the delta from the proven configuration is reviewable rather than * buried in 1,400 generated lines. * * The generated header is used rather than a hand-picked subset because ESP-Hosted's headers derive * struct layouts and the slave target from these symbols: CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6 is * what defines H_SLAVE_TARGET_ESP32C6, and CONFIG_ESP_HOSTED_USE_MEMPOOL is what decides the length * of hosted_osi_funcs_t (see abi_assert.c). Hand-picking would be a second, unproven configuration. * * Nothing here starts a FreeRTOS kernel or an IDF component. The CONFIG_FREERTOS_* values only * shape type declarations; src/net/port.zig and src/io/p4.zig supply the runtime. */ #pragma once #include "sdkconfig_idf.h" /* ------------------------------------------------------------------------------------------------ * Override 1: SDIO queue depths, 20 -> 4 each. * * IDF's build ran with 20 TX and 20 RX descriptors. That is a reasonable number when the heap is * PSRAM-backed; here it is not. Forty in-flight buffers at MAX_SDIO_BUFFER_SIZE (1536 B) reserve * ~60 KB before a single task stack exists, and this image has ~128 KB of L2MEM in total with * nothing initialising the 32 MB of PSRAM. * * Four each was the first attempt and it was measured wrong. Once the board associated, the AP's * ordinary broadcast traffic filled a four-deep queue immediately: the console filled with * "task still writing Rx data to queue!", the receive counter froze at 8 frames, and the board * stopped answering ARP - so it took a DHCP lease and then went silent, which looked like a bug in * the IP stack rather than a queue two sizes too small. * * Sixteen each was then too many, for the reason that makes this setting awkward: with the mempool * off (override 3) every frame is a fresh `_h_malloc_align(MAX_TRANSPORT_BUFFER_SIZE, 64)` from our * heap, so the depths bound peak heap demand at (tx + rx) x 1536 bytes. At sixteen each that is * ~49 KB of a 56 KB heap, and the board duly ran out: "mempool OOM start (RX)" at 11 s, then * "STA TX: mempool_alloc failed, dropping pkt", after which nothing moved in either direction. * * Eight each: ~24.5 KB peak, against a heap sized well above it in examples/http.zig. Deep enough * that ordinary broadcast traffic does not fill the queue between two `tick`s, shallow enough that a * burst cannot exhaust the heap and stop the transmit path as collateral damage. That second * property is the one worth protecting: a receive queue that overflows drops a frame, but a heap * that empties takes the whole radio down. * ---------------------------------------------------------------------------------------------- */ #undef CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE #define CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE 8 #undef CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE #define CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE 8 /* These two are aliases the transport reads; they must follow the values above rather than the * originals, or the queues and the descriptors disagree about their own depth. */ #undef CONFIG_ESP_SDIO_TX_Q_SIZE #define CONFIG_ESP_SDIO_TX_Q_SIZE CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE #undef CONFIG_ESP_SDIO_RX_Q_SIZE #define CONFIG_ESP_SDIO_RX_Q_SIZE CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE /* ------------------------------------------------------------------------------------------------ * Override 2: Bluetooth off. * * The IDF build this configuration came from used BLE through the C6, so it enabled NimBLE and the * VHCI transport. This project does not do Bluetooth, and leaving it on is not free: ESP-Hosted's * transport calls hci_drv_init() unconditionally (transport_drv.c:126), and with NimBLE enabled that * pulls in the real vhci_drv.c and the whole NimBLE host - ble_transport_*, os_mbuf_*, * ble_hs_mbuf_to_flat - which is another stack this image has no reason to carry. * * With these off, ESP-Hosted's own host/drivers/bt/hci_stub_drv.c compiles to a no-op hci_drv_init * and a drop-everything hci_rx_handler. That file is in the source list in build.zig, which is why * this is a configuration change rather than a Zig stub: the C already ships the right answer for a * host without Bluetooth, and using it keeps one fewer thing for us to get wrong. * * The C6 still reports HCI capability in its capability byte (0x0d on this board). That is the * coprocessor saying what it can do, not a request; declining is the host's decision. * ---------------------------------------------------------------------------------------------- */ #undef CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE #undef CONFIG_ESP_HOSTED_NIMBLE_HCI_VHCI #undef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID #undef CONFIG_ESP_HOSTED_BLUEDROID_HCI_VHCI #undef CONFIG_BT_ENABLED #undef CONFIG_BT_NIMBLE_ENABLED /* ------------------------------------------------------------------------------------------------ * Override 3: mempool off. * * ESP-Hosted's mempool recycles fixed-size packet buffers instead of going to malloc each time. It * needs a backend, supplied by `os_mempool_get_ops()`, and on ESP-IDF that comes from FreeRTOS's own * pool implementation. This image has no FreeRTOS, and mempool.c treats a null ops table as a hard * failure rather than a fallback (mempool.c:63-65, "hosted mempool init failed: no mempool ops") - * which is what the second run of examples/radio.zig printed. * * The choice is to write a pool backend or to switch the optimisation off. Off, for now: the * allocator behind _h_malloc (src/net/heap.zig) is a coalescing free list over a static buffer, so * the same-size churn mempool exists to avoid is already cheap and cannot fragment the way a * general-purpose heap would. If profiling later says otherwise, the backend is a small job and this * is the one line to flip back. * * Layout note, because this looks dangerous and is not: turning this off does NOT change * hosted_osi_funcs_t. port_esp_hosted_host_config.h:127-131 defines H_USE_MEMPOOL to 1 or to 0, and * the struct's four mempool members are guarded by `#ifdef`, which only asks whether the name is * defined. Both ways the struct is 284 bytes. src/net/hosted/abi_assert.c asserts that directly. * ---------------------------------------------------------------------------------------------- */ #undef CONFIG_ESP_HOSTED_USE_MEMPOOL #define CONFIG_ESP_HOSTED_USE_MEMPOOL 0 /* ------------------------------------------------------------------------------------------------ * Override 4: the ESP-Hosted CLI off. * * A console command set for poking the transport at runtime. It needs IDF's `console` component - * esp_console_cmd_register, a line editor, and a UART driver - none of which exists in this image, * and none of which this project wants: the serial line here is a log, not a shell. * * `H_ESP_HOSTED_CLI_ENABLED` is an `#ifdef` on the *value* of this symbol being defined * (transport_drv.c:804), so it must be #undef'd rather than defined to 0. * ---------------------------------------------------------------------------------------------- */ #undef CONFIG_ESP_HOSTED_CLI_ENABLED /* ------------------------------------------------------------------------------------------------ * Override 5: compile DEBUG-level logging in. * * The generated configuration stops at CONFIG_LOG_MAXIMUM_LEVEL 3 (INFO), which compiles ESP_LOGD * away entirely. That hides exactly the lines needed to tell a stalled receive path apart from a * silent slave: sdio_drv.c:1190 logs "--- Wait for SDIO intr ---" at DEBUG on every pass of * sdio_read_task, so its presence or absence answers "is the read task still looping?" directly. * * 4, not 5: VERBOSE adds a per-interrupt line that floods a 115200 baud console and changes the * timing of the thing being measured. * * The runtime filter in src/net/hosted_glue.zig is separate and independent - this only decides what * exists in the image to be filtered. * ---------------------------------------------------------------------------------------------- */ #undef CONFIG_LOG_MAXIMUM_LEVEL #define CONFIG_LOG_MAXIMUM_LEVEL 4