Flash status: scan PICOBIN blocks for per-slot validity and version
This commit is contained in:
@@ -3,12 +3,15 @@
|
||||
#include "pico/bootrom.h"
|
||||
#include "hardware/flash.h"
|
||||
#include "hardware/watchdog.h"
|
||||
#include "boot/picobin.h"
|
||||
#include "dispatch.h"
|
||||
#include "net.h"
|
||||
#include "debug_log.h"
|
||||
|
||||
static constexpr uint32_t XIP_BASE_ADDR = 0x10000000;
|
||||
static constexpr uint32_t FLASH_SIZE = 2 * 1024 * 1024;
|
||||
static constexpr uint32_t SLOT_A_OFFSET = 0x00000;
|
||||
static constexpr uint32_t SLOT_B_OFFSET = 0x80000;
|
||||
static boot_reason detected_boot_reason;
|
||||
|
||||
static void poke_watchdog() {
|
||||
@@ -88,16 +91,43 @@ std::optional<ResponseFlashWrite> handle_flash_write(const responder&, const Req
|
||||
return ResponseFlashWrite{};
|
||||
}
|
||||
|
||||
static SlotInfo scan_slot(uint32_t flash_offset) {
|
||||
SlotInfo info{};
|
||||
constexpr uint32_t scan_limit = 4096;
|
||||
auto* scan = reinterpret_cast<const uint32_t*>(XIP_BASE_ADDR + flash_offset);
|
||||
auto* scan_end = scan + scan_limit / 4;
|
||||
while (scan < scan_end && *scan != PICOBIN_BLOCK_MARKER_START) scan++;
|
||||
if (scan >= scan_end) return info;
|
||||
info.valid = true;
|
||||
|
||||
auto* p = reinterpret_cast<const uint8_t*>(scan + 1);
|
||||
auto* end = reinterpret_cast<const uint8_t*>(scan + 64);
|
||||
while (p + 2 <= end) {
|
||||
uint8_t type = p[0];
|
||||
uint8_t size_words = p[1];
|
||||
if (type == PICOBIN_BLOCK_ITEM_2BS_LAST) break;
|
||||
uint32_t item_bytes = static_cast<uint32_t>(size_words) * 4;
|
||||
if (p + item_bytes > end) break;
|
||||
if (type == PICOBIN_BLOCK_ITEM_1BS_VERSION && size_words >= 2) {
|
||||
auto* words = reinterpret_cast<const uint16_t*>(p + 4);
|
||||
uint16_t minor = words[0];
|
||||
uint16_t major = words[1];
|
||||
info.version = (static_cast<uint32_t>(major) << 16) | minor;
|
||||
}
|
||||
p += item_bytes;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
std::optional<ResponseFlashStatus> handle_flash_status(const responder&, const RequestFlashStatus&) {
|
||||
ResponseFlashStatus resp;
|
||||
boot_info_t bi;
|
||||
if (rom_get_boot_info(&bi)) {
|
||||
if (rom_get_boot_info(&bi))
|
||||
resp.boot_partition = bi.partition;
|
||||
resp.boot_type = bi.boot_type;
|
||||
} else {
|
||||
else
|
||||
resp.boot_partition = -1;
|
||||
resp.boot_type = 0;
|
||||
}
|
||||
resp.slot_a = scan_slot(SLOT_A_OFFSET);
|
||||
resp.slot_b = scan_slot(SLOT_B_OFFSET);
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user