fix: unbrick boot — revert -S6 Clear(), add reentrancy guard, -S7 #9
+6
-1
@@ -129,7 +129,12 @@
|
|||||||
// SKUDAK customization suffix: bump on every Skudak-side change so the OpenInverter
|
// SKUDAK customization suffix: bump on every Skudak-side change so the OpenInverter
|
||||||
// web UI shows a distinct version (e.g. "4=1.20.R-S4") and we can visually confirm
|
// web UI shows a distinct version (e.g. "4=1.20.R-S4") and we can visually confirm
|
||||||
// the right firmware is flashed. Match the stm32-sine -S<N> convention.
|
// the right firmware is flashed. Match the stm32-sine -S<N> convention.
|
||||||
#define VERSTR STRINGIFY(4=VER-S5)
|
// -S6 was withdrawn (PR #8 closed): the canary-rebuild attempt called
|
||||||
|
// canMap->Clear() inside MapChargerMessages, which recursed through the
|
||||||
|
// HandleClear callback and stack-overflowed at boot before the terminal
|
||||||
|
// came up. Jumping straight to -S7 so any bench that still reports -S6
|
||||||
|
// in the openinverter UI is visibly the broken build and gets re-flashed.
|
||||||
|
#define VERSTR STRINGIFY(4=VER-S7)
|
||||||
|
|
||||||
/***** enums ******/
|
/***** enums ******/
|
||||||
|
|
||||||
|
|||||||
+26
-5
@@ -108,20 +108,41 @@ static void Ms100Task(void)
|
|||||||
|
|
||||||
static void MapChargerMessages()
|
static void MapChargerMessages()
|
||||||
{
|
{
|
||||||
|
// SKUDAK: Reentrancy guard. canMap->Clear() (libopeninv canmap.cpp) ends
|
||||||
|
// with canHardware->ClearUserMessages(), which fires the HandleClear
|
||||||
|
// callback below — which calls back into THIS function. If this function
|
||||||
|
// ever calls Clear() itself, the chain becomes infinite recursion → stack
|
||||||
|
// overflow → HardFault before the terminal/web UI come up (this is what
|
||||||
|
// bricked -S6 on Kyle's bench, see PR #8 postmortem). The static guard
|
||||||
|
// makes any future "accidental Clear() inside the rebuild path" a no-op
|
||||||
|
// re-entry rather than a chip-bricking fault. Safe because this function
|
||||||
|
// is only invoked from main() and from the HandleClear callback, both
|
||||||
|
// single-threaded contexts; never from an ISR.
|
||||||
|
static bool in_progress = false;
|
||||||
|
if (in_progress) return;
|
||||||
|
|
||||||
uint32_t dummyId;
|
uint32_t dummyId;
|
||||||
uint8_t dummyOfs;
|
uint8_t dummyOfs;
|
||||||
int8_t dummyAdd, dummyLen;
|
int8_t dummyAdd, dummyLen;
|
||||||
float dummyGain;
|
float dummyGain;
|
||||||
bool dummyrx;
|
bool dummyrx;
|
||||||
|
|
||||||
//check sample value, if it is mapped assume valid CAN map
|
// SKUDAK: tmpobcmax is the canary for the -S5+ CAN-map schema. If it's
|
||||||
if (canMap->FindMap(Param::hwaclim, dummyId, dummyOfs, dummyLen, dummyGain, dummyAdd, dummyrx)) return;
|
// already mapped, the persistent flash map is up-to-date — preserve it
|
||||||
|
// and any user customizations. If it's NOT mapped, the saved map is
|
||||||
//canMap->Clear();
|
// from an older firmware that didn't broadcast OBC temp on 0x211 byte 7.
|
||||||
|
//
|
||||||
|
// We deliberately do NOT call canMap->Clear() here. Clear() triggers
|
||||||
|
// HandleClear, and the recursion is fatal (see guard comment above). The
|
||||||
|
// upgrade path is: user issues "canclear" via the openinverter terminal
|
||||||
|
// or web UI to nuke the stale map manually. That single Clear fires
|
||||||
|
// HandleClear once, this function re-runs additively, and Save() persists.
|
||||||
|
if (canMap->FindMap(Param::tmpobcmax, dummyId, dummyOfs, dummyLen, dummyGain, dummyAdd, dummyrx)) return;
|
||||||
|
|
||||||
|
in_progress = true;
|
||||||
ChargerCAN::MapMessages(canMap);
|
ChargerCAN::MapMessages(canMap);
|
||||||
|
|
||||||
canMap->Save();
|
canMap->Save();
|
||||||
|
in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This function is called when the user changes a parameter */
|
/** This function is called when the user changes a parameter */
|
||||||
|
|||||||
Reference in New Issue
Block a user