Parent epic: #512 (E29) · Depends on: S29.01 (done). Independent of S29.04.
Motivation
S29.01 deliberately duplicated the store/security-policy/lifecycle machinery into Bdd/Targets/FreeRtosLwip/main.c rather than DRY it then. The two FreeRTOS target main.c files (1258 + 1111 lines) now share ~600 lines near-verbatim — every store/policy function, the whole OnSet body, the Service task, the SD setup, ErrorHandlerEx, and the message-state globals. The only genuine divergence is the network backend (PlusTcp vs LwipRaw adapter wiring + platform bring-up) and GetHostname (different IP-stack read). Extract the shared surface so a future change (e.g. S29.05's Plus-FAT swap, a new store policy) is made once, not twice-in-sync.
Approach (agreed): one focused refactor
New Bdd/Targets/Common/BddTargetFreeRtosPipeline.{c,h} owning everything platform-independent:
- State: message globals (appName/msgid/msg/port/…), SD handles +
sdList + atomicCounter, CircularBuffer + mutex + ring, lifecycle mutex, solidSyslog + config + ready/teardown flags, all store/policy state.
- Functions: the helpers, all store/policy lifecycle (
RebuildWithFileStore, EnsureFatFsMounted, Create/DestroySecurityPolicy, DestroyCurrentStore, callbacks), the full OnSet, ServiceTask, ErrorHandlerEx, GetAppName/TimeQuality/Endpoint/EndpointVersion, SemihostingExit, the SD/config assembly, and the InteractiveTask body.
Each main.c shrinks to the platform seam — it injects the built switchingSender (its PlusTcp / LwipRaw adapters), a GetHostname callback (reads its IP stack), and a sender-teardown callback, then runs the shared pipeline. main(), IP/tcpip bring-up, hooks, and adapter construction stay in main.c.
Acceptance criteria
Out of scope
- The Plus-FAT swap (S29.05);
Platform/PlusFat/ (S29.04); any library/Tier-1/2 code.
Environments
freertos-cross (both targets) + docker-compose BDD oracle run for validation.
Parent epic: #512 (E29) · Depends on: S29.01 (done). Independent of S29.04.
Motivation
S29.01 deliberately duplicated the store/security-policy/lifecycle machinery into
Bdd/Targets/FreeRtosLwip/main.crather than DRY it then. The two FreeRTOS targetmain.cfiles (1258 + 1111 lines) now share ~600 lines near-verbatim — every store/policy function, the wholeOnSetbody, the Service task, the SD setup,ErrorHandlerEx, and the message-state globals. The only genuine divergence is the network backend (PlusTcp vs LwipRaw adapter wiring + platform bring-up) andGetHostname(different IP-stack read). Extract the shared surface so a future change (e.g. S29.05's Plus-FAT swap, a new store policy) is made once, not twice-in-sync.Approach (agreed): one focused refactor
New
Bdd/Targets/Common/BddTargetFreeRtosPipeline.{c,h}owning everything platform-independent:sdList+ atomicCounter, CircularBuffer + mutex + ring, lifecycle mutex,solidSyslog+ config + ready/teardown flags, all store/policy state.RebuildWithFileStore,EnsureFatFsMounted,Create/DestroySecurityPolicy,DestroyCurrentStore, callbacks), the fullOnSet,ServiceTask,ErrorHandlerEx,GetAppName/TimeQuality/Endpoint/EndpointVersion,SemihostingExit, the SD/config assembly, and theInteractiveTaskbody.Each
main.cshrinks to the platform seam — it injects the builtswitchingSender(its PlusTcp / LwipRaw adapters), aGetHostnamecallback (reads its IP stack), and a sender-teardown callback, then runs the shared pipeline.main(), IP/tcpip bring-up, hooks, and adapter construction stay inmain.c.Acceptance criteria
Bdd/Targets/Common/; both targets link it; the ~600 duplicated lines exist once.main.cretains only network wiring + the injected seam (GetHostname, sender build, sender teardown).Platform/PlusTcpsymbols in the lwIP ELF.@storesuite from S29.01.Out of scope
Platform/PlusFat/(S29.04); any library/Tier-1/2 code.Environments
freertos-cross (both targets) + docker-compose BDD oracle run for validation.