fix(firmware): include sdkconfig.h in edge_processing.h, and pin the subcarrier grid - #1802
fix(firmware): include sdkconfig.h in edge_processing.h, and pin the subcarrier grid#1802clonea1 wants to merge 1 commit into
Conversation
594d4b7 to
21f045f
Compare
…itches on Follow-up to the review on ruvnet#1792. The requested regression test turned up two defects in this PR that the test now guards. **edge_processing.h never included sdkconfig.h.** The header switches EDGE_MAX_SUBCARRIERS on CONFIG_SOC_WIFI_HE_SUPPORT but did not include the file that defines it. Any translation unit that reaches this header without sdkconfig.h already in scope evaluates an undefined identifier in #if as 0, silently selects the 128-bin pre-HE grid on a 256-bin part, and reproduces the exact bug this PR exists to fix -- no error, no warning, a clean build and a dead edge pipeline. It happens to work today only because the .c files that include it pull sdkconfig.h in first. Also repairs mojibake in that comment: two em-dashes had been round-tripped through cp1252 and read "—". **The fuzz target carried a dead copy of the constant.** As flagged, fuzz_edge_enqueue.c defined its own EDGE_MAX_SUBCARRIERS 128 -- but it is referenced nowhere in that file. It exercises the SPSC ring, bounded by EDGE_MAX_IQ_BYTES, and never consults the subcarrier grid. So updating it would not have produced the requested end-to-end coverage; the define was simply dead and free to drift. Removed, with a comment saying where the grid is pinned instead. The real coverage is test_edge_subcarrier_grid.c, built twice against the REAL header because the constant is target-conditional and one compilation can only prove one branch. It asserts the grid matches the target, that a 256-bin HE20 frame clears the guard, that a full-width frame still fits one ring slot (so truncation cannot simply relocate into ring_push's memcpy clamp), and that the pre-HE size is unchanged so fixing C6 costs S3 no .bss. Two deliberate choices worth stating. The test never re-implements the guard predicate -- restating it would recreate precisely the drift hazard that let this bug through. And the HE macro is supplied by a stub sdkconfig.h (test/stubs_he/), never by -D on the command line, because -D would compile the right branch regardless and mask the missing include entirely. The expectation is driven by a test-only EXPECT_HE marker rather than by CONFIG_SOC_WIFI_HE_SUPPORT itself. That is not incidental: the first version of this test used the real macro to choose its own expectations, so when the header failed to see it the test quietly asserted the pre-HE case and passed against the broken header. Running it as a negative control caught that. Verified in espressif/idf:v5.4 -- against the unfixed header the HE build fails three checks naming the missing include; with the fix both builds pass; and the C6 firmware still builds clean. Rebased onto 33a9e90. The one conflict was in test/Makefile against the test_serial_onboarding targets ruvnet#1902 added; the resolution is additive, both targets are kept in .PHONY, all and host_tests. The clean: rule now also removes test_edge_grid_he and test_edge_grid_pre_he, which it never did. Co-Authored-By: claude-flow <ruv@ruv.net>
21f045f to
4d76da3
Compare
|
Rebased onto current The one conflict was Two defects on this branch fixed while rebasing. The Verified, not assumed. Re-ran as a negative control with the
🤖 Generated with claude-flow |
Minor follow-up to #1792, which merged with a latent form of the bug it fixed still in it.
The gap
edge_processing.honmainnow reads:The header switches on
CONFIG_SOC_WIFI_HE_SUPPORTbut never includes the file that defines it. Any translation unit that reaches this header withoutsdkconfig.halready in scope evaluates an undefined identifier in#ifas 0, silently selects the 128-bin pre-HE grid on a 256-bin part, andprocess_frame()then rejects every frame — which is exactly the failure #1792 was written to remove.It works today only because the
.cfiles that include it happen to pullsdkconfig.hin first. Nothing enforces that, no warning fires, and the build stays green.One line fixes it. Also repairs two em-dashes in that comment block that had been round-tripped through cp1252 and read
—.The test
test_edge_subcarrier_grid.cpinsEDGE_MAX_SUBCARRIERSagainst the real header, built twice because the constant is target-conditional and one compilation can only prove one branch. It asserts the grid matches the target, that a 256-bin HE20 frame clears the guard, that a full-width frame still fits one ring slot (so truncation cannot simply relocate intoring_push()'s memcpy clamp), and that the pre-HE size is unchanged so fixing C6 costs S3 no.bss.Two deliberate choices:
sdkconfig.h(test/stubs_he/), never from-Don the command line.-Dwould compile the right branch regardless and mask the missing include completely — the bug above would pass a green test.The expectation is driven by a test-only
EXPECT_HEmarker rather than byCONFIG_SOC_WIFI_HE_SUPPORTitself. That is not incidental: the first version of this test used the real macro to choose its own expectations, so when the header could not see it, neither could the test — it quietly asserted the pre-HE case and passed against the broken header. Running it as a negative control caught that.On the fuzz harness
The review on #1792 asked for
fuzz_edge_enqueue.c's localEDGE_MAX_SUBCARRIERS 128to be updated so it would exercise the 256 path. Worth flagging that this would not have worked: that define is dead — referenced nowhere in the file. The target exercises the SPSC ring, bounded byEDGE_MAX_IQ_BYTES, and never consults the subcarrier grid.So it is removed rather than updated, with a comment pointing at where the grid is actually pinned. A stale private copy of a load-bearing constant is precisely how the original bug stayed invisible.
Verification
In
espressif/idf:v5.4:mainheader, the HE build fails three checks, naming the missing include directlyNo hardware evidence is claimed or needed here — this is a header-inclusion correctness fix and a host test, both fully determined at compile time. Separately, I still owe #1792 a real C6 boot log confirming the 256-bin premise and the restored pipeline; that will be posted on the closed PR for the record when I next have a node on a cable.