fix: uebersprungenes Recovery-Image ist kein Fehler mehr
Lehnte die Recovery ein Image ab, weil es bereits die laufende Version traegt, meldete die Firmware das als last_ota_error=trailer. Wer eine Lampe im Feld ausliest, haette dort einen Trailer-Fehler gesehen, wo in Wahrheit nichts passiert ist - und die Meldung in der Konsole lautete "update failed". Das bewusste Ueberspringen hat jetzt einen eigenen Zustand (nl_ota_skipped()), setzt keinen Fehlerwert und wird als "image already up to date" protokolliert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c5d76efb25
commit
37a5fe2ca9
@@ -162,8 +162,14 @@ void nl_recovery_try(void)
|
|||||||
tls_os_time_delay(HZ / 2);
|
tls_os_time_delay(HZ / 2);
|
||||||
waited += 500;
|
waited += 500;
|
||||||
}
|
}
|
||||||
if (feeding)
|
if (feeding) {
|
||||||
|
/* A skipped image (same version as the running firmware) is not a failure - saying so
|
||||||
|
would leave a healthy lamp looking like it had rejected a broken image. */
|
||||||
|
if (nl_ota_skipped())
|
||||||
|
printf("recovery: image already up to date, continuing normal boot\r\n");
|
||||||
|
else
|
||||||
printf("recovery: update failed (%s), continuing normal boot\r\n",
|
printf("recovery: update failed (%s), continuing normal boot\r\n",
|
||||||
nl_ota_last_error() ? nl_ota_last_error() : "unknown");
|
nl_ota_last_error() ? nl_ota_last_error() : "unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
+8
-2
@@ -23,6 +23,7 @@ static char s_url[NL_OTA_URL_MAX];
|
|||||||
static volatile bool s_busy;
|
static volatile bool s_busy;
|
||||||
static volatile bool s_reject_running_version; /* recovery path only, see nl_ota_start_recovery() */
|
static volatile bool s_reject_running_version; /* recovery path only, see nl_ota_start_recovery() */
|
||||||
static const char * volatile s_error;
|
static const char * volatile s_error;
|
||||||
|
static volatile bool s_skipped;
|
||||||
static u32 s_stack[NL_OTA_STACK];
|
static u32 s_stack[NL_OTA_STACK];
|
||||||
static char s_tail_version[NL_TRAILER_VERSION_LEN]; /* used by the hook, kept off its 2 KB stack */
|
static char s_tail_version[NL_TRAILER_VERSION_LEN]; /* used by the hook, kept off its 2 KB stack */
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ void nl_ota_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool nl_ota_busy(void) { return s_busy; }
|
bool nl_ota_busy(void) { return s_busy; }
|
||||||
|
bool nl_ota_skipped(void) { return s_skipped; }
|
||||||
const char *nl_ota_last_error(void) { return s_error; }
|
const char *nl_ota_last_error(void) { return s_error; }
|
||||||
void nl_ota_set_error(const char *e) { s_error = e; }
|
void nl_ota_set_error(const char *e) { s_error = e; }
|
||||||
|
|
||||||
@@ -61,7 +63,10 @@ bool nl_fwup_verify_tail(const uint8_t sha256[32], const uint8_t *tail, uint32_t
|
|||||||
if (strcmp(s_tail_version, NINLIGHT_FW_VERSION) == 0) {
|
if (strcmp(s_tail_version, NINLIGHT_FW_VERSION) == 0) {
|
||||||
printf("ota: recovery image already carries the running version %s, not flashing\r\n",
|
printf("ota: recovery image already carries the running version %s, not flashing\r\n",
|
||||||
s_tail_version);
|
s_tail_version);
|
||||||
s_error = "trailer";
|
/* Deliberately skipped, not failed: leave last_ota_error alone. Reporting "trailer"
|
||||||
|
* here used to make a perfectly healthy lamp look like it had rejected a malformed
|
||||||
|
* image, which is exactly the wrong thing to read off a lamp in the field. */
|
||||||
|
s_skipped = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
printf("ota: recovery image version %s (running %s)\r\n", s_tail_version, NINLIGHT_FW_VERSION);
|
printf("ota: recovery image version %s (running %s)\r\n", s_tail_version, NINLIGHT_FW_VERSION);
|
||||||
@@ -90,7 +95,7 @@ static void ota_task(void *arg)
|
|||||||
log_url(s_url);
|
log_url(s_url);
|
||||||
rc = t_http_fwup(s_url);
|
rc = t_http_fwup(s_url);
|
||||||
/* Only reached on failure - the SDK resets the chip itself after a good image. */
|
/* Only reached on failure - the SDK resets the chip itself after a good image. */
|
||||||
if (s_error == NULL)
|
if (s_error == NULL && !s_skipped)
|
||||||
s_error = "download";
|
s_error = "download";
|
||||||
printf("ota: failed (rc=%d, %s)\r\n", rc, s_error);
|
printf("ota: failed (rc=%d, %s)\r\n", rc, s_error);
|
||||||
{
|
{
|
||||||
@@ -125,6 +130,7 @@ static int ota_start(const char *url, bool reject_running_version)
|
|||||||
}
|
}
|
||||||
s_busy = true;
|
s_busy = true;
|
||||||
s_error = NULL;
|
s_error = NULL;
|
||||||
|
s_skipped = false;
|
||||||
s_reject_running_version = reject_running_version;
|
s_reject_running_version = reject_running_version;
|
||||||
memcpy(s_url, url, n + 1);
|
memcpy(s_url, url, n + 1);
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ int nl_ota_start(const char *url);
|
|||||||
* forever. A deliberate re-flash of the same version stays possible over the REST API. */
|
* forever. A deliberate re-flash of the same version stays possible over the REST API. */
|
||||||
int nl_ota_start_recovery(const char *url);
|
int nl_ota_start_recovery(const char *url);
|
||||||
bool nl_ota_busy(void);
|
bool nl_ota_busy(void);
|
||||||
|
/* True when the last recovery attempt deliberately skipped an image whose version already
|
||||||
|
matches the running firmware - that is not a failure and sets no last_ota_error. */
|
||||||
|
bool nl_ota_skipped(void);
|
||||||
/* NULL, or one of: download, crc, trailer, device_mismatch, hash, busy */
|
/* NULL, or one of: download, crc, trailer, device_mismatch, hash, busy */
|
||||||
const char *nl_ota_last_error(void);
|
const char *nl_ota_last_error(void);
|
||||||
void nl_ota_set_error(const char *e);
|
void nl_ota_set_error(const char *e);
|
||||||
|
|||||||
Reference in New Issue
Block a user