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>
83 lines
3.0 KiB
Plaintext
83 lines
3.0 KiB
Plaintext
----------------------
|
|
--- IMPORTANT TODO ---
|
|
----------------------
|
|
|
|
--------------------
|
|
--- NEEDED TESTS ---
|
|
--------------------
|
|
- test:
|
|
- service method lookups
|
|
- out-of-order fields in messages (ie if the number isn't ascending)
|
|
- gaps in numbers: check that the number of ranges is correct
|
|
- default values
|
|
- message unpack alloc failures when allocating new slab
|
|
- message unpack alloc failures when allocating unknown field buffers
|
|
- packed message corruption.
|
|
- meta-todo: get a list of all the unpack errors together to check off
|
|
|
|
---------------------
|
|
--- DOCUMENTATION ---
|
|
---------------------
|
|
Document:
|
|
- services
|
|
- check over documentation again
|
|
|
|
--------------------------
|
|
--- LOW PRIORITY STUFF ---
|
|
--------------------------
|
|
- support Group (whatever it is)
|
|
- proper support for extensions
|
|
- slot for ranges in descriptor
|
|
- extends is implemented as c-style function
|
|
whose name is built from the package, the base message type-name
|
|
and the member. which takes the base message and returns the
|
|
value, if it is found in "unknown_values".
|
|
boolean package__extension_member_name__get(Message *message,
|
|
type *out);
|
|
void package__extension_member_name__set_raw(type in,
|
|
ProtobufCUnknownValue *to_init);
|
|
|
|
------------------------------------
|
|
--- EXTREMELY LOW PRIORITY STUFF ---
|
|
------------------------------------
|
|
- stop using qsort in the code generator: find some c++ish way to do it
|
|
|
|
----------------------------------------------
|
|
--- ISSUES WE ARE PROBABLY GOING TO IGNORE ---
|
|
----------------------------------------------
|
|
- strings may not contain NULs
|
|
|
|
-------------------------
|
|
--- IDEAS TO CONSIDER ---
|
|
-------------------------
|
|
|
|
- optimization: structures without repeated members could skip
|
|
the ScannedMember phase
|
|
|
|
- optimization: a way to ignore unknown-fields when unpacking
|
|
|
|
- optimization: certain functions are not well setup for WORDSIZE==64;
|
|
especially the int64 routines are inefficient that way.
|
|
The best might be an internal #define WORDSIZE (sizeof(long)*8)"
|
|
except w/ a real constant there, one that the preprocessor can use.
|
|
I think the functions in protobuf-c.c are already tagged.
|
|
|
|
- lifetime functions for messages:
|
|
message__new()
|
|
return a new message using an allocator with standard allocation policy
|
|
message__unpack_onto(...)
|
|
unpack onto an initialized message
|
|
message__clear(...)
|
|
clears all allocations, does not free the message itself
|
|
message__free(...)
|
|
free the message.
|
|
[yeah, right: after typing it out, i see it's way too complicated]
|
|
|
|
- switching to pure C.
|
|
- Rewrite the code-generator in C, including the parser.
|
|
- This would have the huge advantage that we could use ".proto" files
|
|
directly, instead of having to invoke the compilers.
|
|
- keep in a separate c file for static linking optimziation purposes
|
|
- need alignment tests
|
|
- the CAVEATS should discuss our structure-packing assumptions
|