fix(connectivity): harden BLE reprovisioning under memory pressure

This commit is contained in:
chenjintao
2026-08-25 14:09:44 +08:00
parent 140e90447c
commit 6495f0e107
6 changed files with 323 additions and 58 deletions
+74
View File
@@ -0,0 +1,74 @@
# BLE Provisioning Memory Recovery
## Failure Mode
Runtime Wi-Fi recovery can fall back to mini-program BLE provisioning after
saved network candidates fail. The BLE controller requires contiguous internal
DMA-capable memory even when the NimBLE host is configured to use external RAM.
Starting BLE late in a fragmented runtime previously allowed a controller
allocation to fail inside ROM code, followed by an assertion and an interrupt
watchdog reset.
## Runtime Transition
Before runtime reprovisioning starts BLE, the control plane now:
1. Blocks new runtime work through the runtime stop gate.
2. Clears active PTT state.
3. Stops local wake detection and its owned capture path.
4. Stops the multimodal client and downstream playback.
5. Fully deinitializes the multimodal audio pipeline.
6. Switches the running LCD renderer to the provisioning QR expression.
7. Stops the Wi-Fi station.
The provisioning queue and event group are allocated first. Memory headroom is
then checked before entering the BLE controller. NimBLE is initialized before
the 4096-byte provisioning worker is created, preserving one additional
contiguous internal block during controller startup.
## Memory Gate
BLE initialization proceeds only when both configured thresholds are met:
```text
CONFIG_TQ_MINI_PROGRAM_PROVISIONING_MIN_FREE_INTERNAL_BYTES=49152
CONFIG_TQ_MINI_PROGRAM_PROVISIONING_MIN_LARGEST_DMA_BYTES=12288
```
Both current values and thresholds are logged before BLE startup. These values
are conservative guards against the observed 4096-byte controller allocation
failure and leave room for the controller's preceding allocations.
## Recovery Boot
If the runtime cannot provide enough headroom, the control plane writes a
magic value and its inverse to RTC no-init memory, waits 100 ms for logs, and
performs a controlled software restart. The marker is one-shot and does not
write flash.
On the next boot, application composition keeps the battery safety service but
defers the boot sound, LCD render worker, factory CLI worker, and turntable
calibration. Connectivity skips the saved-credential STA attempt and starts
BLE provisioning before full runtime workers. The LCD renderer starts only
after BLE has secured its controller memory. Successful provisioning tears
down BLE and restarts into the normal boot sequence.
While provisioning is active, the worker logs every 10 seconds that it is
waiting for mini-program credentials. Runtime transitions keep the LCD active
on the provisioning QR expression, so a healthy wait state is distinguishable
from a stalled device.
If recovery-boot BLE startup itself fails, the one-shot mode is cleared and
normal runtime startup resumes instead of entering a restart loop.
## Validation
Required device validation covers:
- normal boot provisioning with no saved credentials;
- runtime Wi-Fi loss followed by failed candidate traversal;
- low-memory fallback through the one-shot recovery boot;
- successful provisioning followed by a normal reboot;
- repeated Wi-Fi/BLE transitions under audio and local-wake load;
- confirmation that no `BLE_INIT: Malloc failed`, ROM assertion, or interrupt
watchdog reset occurs.