Boot reason via watchdog scratch register, reboot/picoboot CLI commands, enum msgpack support

This commit is contained in:
Ian Gulliver
2026-04-12 08:17:22 +09:00
parent 9b7362c460
commit 6c3e0757f9
8 changed files with 110 additions and 6 deletions

View File

@@ -13,6 +13,7 @@ static constexpr handler_entry handlers[] = {
};
int main() {
handlers_init();
dispatch_init();
dispatch_run(handlers);
}

View File

@@ -6,6 +6,7 @@
extern std::string_view firmware_name;
void handlers_init();
std::optional<ResponsePICOBOOT> handle_picoboot(const responder& resp, const RequestPICOBOOT&);
std::optional<ResponseInfo> handle_info(const responder& resp, const RequestInfo&);
std::optional<ResponseLog> handle_log(const responder& resp, const RequestLog&);

View File

@@ -373,6 +373,10 @@ public:
requires std::is_integral_v<T> && (!std::is_same_v<T, bool>)
pack_result pack(T n) { return pack_integer(n); }
template <typename T>
requires std::is_enum_v<T>
pack_result pack(T v) { return pack_integer(static_cast<std::underlying_type_t<T>>(v)); }
pack_result pack(bool v) { return pack_bool(v); }
pack_result pack(float v) { return pack_float(v); }
pack_result pack(double v) { return pack_double(v); }
@@ -727,6 +731,16 @@ public:
}
};
template <typename T>
requires std::is_enum_v<T>
result<parser> unpack(const parser &p, T &out) {
std::underlying_type_t<T> v;
auto r = unpack(p, v);
if (!r) return r;
out = static_cast<T>(v);
return r;
}
template <typename T>
requires std::is_integral_v<T> && (!std::is_same_v<T, bool>)
result<parser> unpack(const parser &p, T &out) {

View File

@@ -44,14 +44,20 @@ struct RequestInfo {
auto as_tuple() { return std::tie(); }
};
enum class boot_reason : uint8_t {
cold_boot = 0,
request_reboot = 1,
};
struct ResponseInfo {
static constexpr int8_t ext_id = 5;
std::array<uint8_t, 8> board_id;
std::array<uint8_t, 6> mac;
std::array<uint8_t, 4> ip;
std::string firmware_name;
auto as_tuple() const { return std::tie(board_id, mac, ip, firmware_name); }
auto as_tuple() { return std::tie(board_id, mac, ip, firmware_name); }
boot_reason boot;
auto as_tuple() const { return std::tie(board_id, mac, ip, firmware_name, boot); }
auto as_tuple() { return std::tie(board_id, mac, ip, firmware_name, boot); }
};
struct RequestLog {

View File

@@ -9,6 +9,17 @@
static constexpr uint32_t XIP_BASE_ADDR = 0x10000000;
static constexpr uint32_t FLASH_SIZE = 2 * 1024 * 1024;
static constexpr uint32_t REBOOT_MAGIC = 0x504D5242;
static boot_reason detected_boot_reason;
void handlers_init() {
if (watchdog_hw->scratch[0] == REBOOT_MAGIC)
detected_boot_reason = boot_reason::request_reboot;
else
detected_boot_reason = boot_reason::cold_boot;
watchdog_hw->scratch[0] = 0;
}
std::optional<ResponsePICOBOOT> handle_picoboot(const responder&, const RequestPICOBOOT&) {
dispatch_schedule_ms(100, []{ reset_usb_boot(0, 1); });
@@ -24,6 +35,7 @@ std::optional<ResponseInfo> handle_info(const responder&, const RequestInfo&) {
resp.mac = ns.mac;
resp.ip = ns.ip;
resp.firmware_name = firmware_name;
resp.boot = detected_boot_reason;
return resp;
}
@@ -67,7 +79,10 @@ std::optional<ResponseFlashWrite> handle_flash_write(const responder&, const Req
}
std::optional<ResponseReboot> handle_reboot(const responder&, const RequestReboot&) {
dispatch_schedule_ms(100, []{ watchdog_reboot(0, 0, 0); });
dispatch_schedule_ms(100, []{
watchdog_hw->scratch[0] = REBOOT_MAGIC;
watchdog_reboot(0, 0, 0);
});
return ResponseReboot{};
}

View File

@@ -25,6 +25,7 @@ static constexpr handler_entry handlers[] = {
};
int main() {
handlers_init();
dispatch_init();
gpio_init(LED_PIN);