Share SD maintenance failure cleanup to retain RAK Full capacity
This commit is contained in:
1 parent
684df9c643
commit
0f8cd1e019
2 files changed
+28
-25
No files matched your search
+19
-21
@@ -57,6 +57,19 @@ static void formatSdCardElapsed(char* out, size_t out_len, bool recorded,
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the three failure exits shared even with LTO: each must preserve the
|
||||
// card error before reset cleanup can replace it, then sample the finish time.
|
||||
static __attribute__((noinline)) bool finishSdCardFailure(
|
||||
mesh::ota::OtaContext& context, mesh::ota::OtaStoreSdNrf52& card,
|
||||
char* reply, size_t capacity, const char* format) {
|
||||
char error[80];
|
||||
strncpy(error, card.last_error(), sizeof(error) - 1);
|
||||
error[sizeof(error) - 1] = 0;
|
||||
context.finishSdCardReset(millis());
|
||||
snprintf(reply, capacity, format, error);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool handleSdCardSet(SdCardCLIState& state, MainBoard& board,
|
||||
const char* config, char* reply, size_t capacity) {
|
||||
if (!config || !reply || capacity == 0
|
||||
@@ -139,13 +152,8 @@ bool handleSdCardSet(SdCardCLIState& state, MainBoard& board,
|
||||
|
||||
if (is_format) {
|
||||
if (!card.formatCard(board)) {
|
||||
char error[80];
|
||||
strncpy(error, card.last_error(), sizeof(error) - 1);
|
||||
error[sizeof(error) - 1] = 0;
|
||||
context.finishSdCardReset(millis());
|
||||
snprintf(reply, capacity, "Error: SD card format failed: %s",
|
||||
error);
|
||||
return true;
|
||||
return finishSdCardFailure(context, card, reply, capacity,
|
||||
"Error: SD card format failed: %s");
|
||||
}
|
||||
context.finishSdCardReset(millis());
|
||||
state.format_recorded = true;
|
||||
@@ -155,25 +163,15 @@ bool handleSdCardSet(SdCardCLIState& state, MainBoard& board,
|
||||
}
|
||||
|
||||
if (!card.eraseCard(board)) {
|
||||
char error[80];
|
||||
strncpy(error, card.last_error(), sizeof(error) - 1);
|
||||
error[sizeof(error) - 1] = 0;
|
||||
context.finishSdCardReset(millis());
|
||||
snprintf(reply, capacity, "Error: SD card erase failed: %s",
|
||||
error);
|
||||
return true;
|
||||
return finishSdCardFailure(context, card, reply, capacity,
|
||||
"Error: SD card erase failed: %s");
|
||||
}
|
||||
state.erase_recorded = true;
|
||||
state.erase_at = millis();
|
||||
|
||||
if (!card.formatCard(board)) {
|
||||
char error[80];
|
||||
strncpy(error, card.last_error(), sizeof(error) - 1);
|
||||
error[sizeof(error) - 1] = 0;
|
||||
context.finishSdCardReset(millis());
|
||||
snprintf(reply, capacity, "Error: SD card erased but format failed: %s",
|
||||
error);
|
||||
return true;
|
||||
return finishSdCardFailure(context, card, reply, capacity,
|
||||
"Error: SD card erased but format failed: %s");
|
||||
}
|
||||
state.format_recorded = true;
|
||||
state.format_at = millis();
|
||||
|
||||
@@ -22,6 +22,7 @@ CONTEXT = r'''
|
||||
#include <MeshCore.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
namespace mesh { namespace ota {
|
||||
inline bool ethernet_owned = false;
|
||||
inline bool rak4631_ethernet_owns_spi() { return ethernet_owned; }
|
||||
@@ -44,16 +45,17 @@ struct FetchStore {
|
||||
struct OtaStoreSdNrf52 {
|
||||
unsigned formats = 0, erases = 0, spaces = 0, lists = 0;
|
||||
uint16_t page = 0;
|
||||
char error[120] = "card unavailable";
|
||||
bool format_ok = true, erase_ok = true, read_ok = true;
|
||||
bool formatCard(MainBoard&) { ++formats; return format_ok; }
|
||||
bool eraseCard(MainBoard&) { ++erases; return erase_ok; }
|
||||
bool formatCard(MainBoard&) { ++formats; strcpy(error, "card unavailable"); return format_ok; }
|
||||
bool eraseCard(MainBoard&) { ++erases; strcpy(error, "card unavailable"); return erase_ok; }
|
||||
bool getSpace(MainBoard&, uint64_t& used, uint64_t& free) {
|
||||
++spaces; used = 12; free = 34; return read_ok;
|
||||
}
|
||||
bool listFiles(MainBoard&, uint16_t p, char* reply, size_t cap) {
|
||||
++lists; page = p; snprintf(reply, cap, "> files page=%u", unsigned(p)); return read_ok;
|
||||
}
|
||||
const char* last_error() const { return "card unavailable"; }
|
||||
const char* last_error() const { return error; }
|
||||
};
|
||||
struct OtaContext {
|
||||
OtaManager manager;
|
||||
@@ -65,7 +67,7 @@ struct OtaContext {
|
||||
unsigned prepares = 0, finishes = 0;
|
||||
OtaStoreSdNrf52& sdStagingStore() { return card; }
|
||||
void prepareSdCardReset() { ++prepares; }
|
||||
void finishSdCardReset(uint32_t) { ++finishes; }
|
||||
void finishSdCardReset(uint32_t) { ++finishes; strcpy(card.error, "cleanup replaced error"); }
|
||||
};
|
||||
inline OtaContext context;
|
||||
inline bool acquired = false, out_of_memory = false;
|
||||
@@ -133,6 +135,7 @@ int main() {
|
||||
context.card.format_ok = false;
|
||||
assert(command("set sdcard format"));
|
||||
assert(strstr(reply.text, "format failed") && context.prepares == 1 && context.finishes == 1);
|
||||
assert(strcmp(reply.text, "Error: SD card format failed: card unavailable") == 0);
|
||||
assert(!state.format_recorded);
|
||||
context.card.format_ok = true;
|
||||
assert(command("set sdcard format")); assert(state.format_recorded && state.format_at == clock_ms);
|
||||
@@ -141,9 +144,11 @@ int main() {
|
||||
assert(command("set sdcard format --force")); assert(context.card.formats == formats + 1);
|
||||
context.card.erase_ok = false;
|
||||
assert(command("set sdcard erase")); assert(strstr(reply.text, "erase failed"));
|
||||
assert(strcmp(reply.text, "Error: SD card erase failed: card unavailable") == 0);
|
||||
assert(!state.erase_recorded && context.prepares == context.finishes);
|
||||
context.card.erase_ok = true; context.card.format_ok = false;
|
||||
assert(command("set sdcard erase")); assert(strstr(reply.text, "erased but format failed"));
|
||||
assert(strcmp(reply.text, "Error: SD card erased but format failed: card unavailable") == 0);
|
||||
assert(state.erase_recorded && context.prepares == context.finishes);
|
||||
context.card.format_ok = true;
|
||||
assert(command("set sdcard erase --force")); assert(strstr(reply.text, "erase and format complete"));
|
||||
|
||||
Reference in new issue
Block a user