36#include <etl/algorithm.h>
37#include <etl/basic_string.h>
38#include <etl/bit_stream.h>
39#include <etl/string.h>
42#include <satnogs-comms-lib/version.hpp>
44#include <zephyr/dfu/mcuboot.h>
45#include <zephyr/kernel.h>
46#include <zephyr/retention/blinfo.h>
47#include <zephyr/sys/byteorder.h>
48#include <zephyr/task_wdt/task_wdt.h>
50#if CONFIG_BOOTLOADER_MCUBOOT
51#include <bootutil/boot_status.h>
52#include <bootutil/image.h>
114 struct gnss_data data;
116 writer.write<uint32_t>(data.info.satellites_cnt, 32);
117 writer.write<uint32_t>(data.info.hdop, 32);
118 writer.write<uint8_t>(data.info.fix_status, 8);
119 writer.write<uint8_t>(data.info.fix_quality, 8);
120 writer.write<uint32_t>(data.utc.hour, 32);
121 writer.write<uint32_t>(data.utc.minute, 32);
122 writer.write<uint32_t>(data.utc.millisecond, 32);
123 writer.write<uint32_t>(data.utc.month_day, 32);
124 writer.write<uint32_t>(data.utc.month, 32);
125 writer.write<uint32_t>(data.utc.century_year, 32);
179 auto &
radio = b.radio();
182 writer.write(
radio.enabled(scr::interface::UHF), 1);
183 writer.write(
static_cast<bool>(
radio.direction(scr::interface::UHF)), 1);
184 writer.write(
static_cast<uint8_t
>(iface.get_state()), 2);
185 writer.write(
static_cast<uint8_t
>(
radio.uhf().get_filter()), 1);
187 writer.write<uint32_t>(
188 static_cast<uint32_t
>(
191 writer.write<uint32_t>(
192 static_cast<uint32_t
>(
195 const auto &stats = iface.get_stats();
196 writer.write(stats.tx_frames, 32);
197 writer.write(stats.tx_frames_fail, 32);
198 writer.write(stats.tx_frames_drop, 32);
199 writer.write(stats.rx_frames, 32);
200 writer.write(stats.rx_frames_inval, 32);
201 writer.write(stats.rx_frames_drop, 32);
202 writer.write<uint64_t>(stats.last_rx_ts, 64);
204 writer.write<uint64_t>(stats.last_valid_rx_ts, 64);
218 auto &
radio = b.radio();
221 writer.write(
radio.enabled(scr::interface::SBAND), 1);
222 writer.write(
static_cast<bool>(
radio.direction(scr::interface::SBAND)),
224 writer.write(
static_cast<uint8_t
>(iface.get_state()), 2);
225 writer.write(
radio.sband().mixer_lock(), 1);
226 writer.write(
static_cast<uint8_t
>(
radio.sband().get_filter()), 1);
228 writer.write<uint32_t>(
229 static_cast<uint32_t
>(
radio.frequency(scr::interface::SBAND,
232 writer.write<uint32_t>(
233 static_cast<uint32_t
>(
radio.frequency(scr::interface::SBAND,
237 const auto &stats = iface.get_stats();
238 writer.write(stats.tx_frames, 32);
239 writer.write(stats.tx_frames_fail, 32);
240 writer.write(stats.tx_frames_drop, 32);
241 writer.write(stats.rx_frames, 32);
242 writer.write(stats.rx_frames_inval, 32);
243 writer.write(stats.rx_frames_drop, 32);
244 writer.write<uint64_t>(stats.last_rx_ts, 64);
246 writer.write<uint64_t>(stats.last_valid_rx_ts, 64);
254 static constexpr size_t size = 6U;
277 writer.write<uint8_t>(
version, 3);
278 writer.write<uint8_t>(
type, 1);
279 writer.write<uint8_t>(
sec_hdr, 1);
280 writer.write<uint16_t>(
apid, 11);
282 writer.write<uint16_t>(
count, 14);
283 writer.write<uint16_t>(
length, 16);
301 serialize(etl::bit_stream_writer &writer,
float x);
304 serialize(etl::bit_stream_writer &writer,
double x);
312 tm_header.
apid =
static_cast<uint16_t
>(Apid);
313 tm_header.
count = tlc.get_frame_count();
315 etl::bit_stream_writer bit_stream_hdr(
317 etl::bit_stream_writer bit_stream_pld(
323 tm_header.
length = bit_stream_pld.size_bytes() + 1;
342 serialize(etl::bit_stream_writer &writer, uint8_t
const buf[],
size_t len)
344 for (
size_t i = 0; i < len; ++i) {
345 writer.write<uint8_t>(
buf[i], 8);
356 writer.write<
bool>(success, 1);
367 writer.write<uint64_t>(k_uptime_get(), 64);
396 writer.write<uint64_t>(k_uptime_get(), 64);
406 writer.write<
bool>(thermal_state.uhf_triggered, 1);
407 writer.write<
bool>(thermal_state.sband_triggered, 1);
408 writer.write<
bool>(thermal_state.uhf_sensor_valid, 1);
409 writer.write<
bool>(thermal_state.sband_sensor_valid, 1);
410 writer.write<
bool>(thermal_state.pcb_sensor_valid, 1);
415 auto retained_mem_str = log.get_latest_exception();
416 for (
size_t i = 0; i < retained_mem_str.size(); ++i) {
417 writer.write<uint8_t>(
static_cast<uint8_t
>(retained_mem_str[i]), 8);
420 writer.write<uint8_t>(0x0, 8);
433 for (
size_t i = 0; i < hash_len; i++) {
434 writer.write<uint8_t>(hash[i], 8);
437 writer.write<uint8_t>(0x0, 8);
446 writer.write<uint32_t>(scl::version::hw_major, 32);
447 writer.write<uint32_t>(scl::version::hw_minor, 32);
448 writer.write<uint32_t>(scl::version::hw_patch, 32);
451 writer.write<uint32_t>(scl::version::lib_major, 32);
452 writer.write<uint32_t>(scl::version::lib_minor, 32);
453 writer.write<uint32_t>(scl::version::lib_patch, 32);
457 writer.write<uint32_t>(satnogs::comms::version::fw_major, 32);
458 writer.write<uint32_t>(satnogs::comms::version::fw_minor, 32);
459 writer.write<uint32_t>(satnogs::comms::version::fw_patch, 32);
474 writer.write<
bool>(fpga.enabled(), 1);
475 writer.write<
bool>(fpga.get_fpga_done(), 1);
477 writer.write<
bool>(
false, 1);
478 writer.write<
bool>(
false, 1);
479 writer.write<
bool>(
false, 1);
480 writer.write<uint8_t>(
static_cast<uint8_t
>(fpga.get_boot_mode()), 2);
495 writer.write<uint8_t>(
511 writer.write<uint8_t>(
static_cast<uint8_t
>(
time.
get(t)), 8);
512 writer.write<uint64_t>(t, 64);
524 writer.write<
bool>(s.enabled(), 1);
525 writer.write<
bool>(s.mounted(), 1);
526 writer.write<
bool>(
static_cast<bool>(s.get_dir()), 1);
536#if CONFIG_BOOTLOADER_MCUBOOT
538 blinfo_lookup(BLINFO_MODE, &v,
sizeof(v));
539 writer.write<uint8_t>(v, 8);
541 blinfo_lookup(BLINFO_SIGNATURE_TYPE, &v,
sizeof(v));
542 writer.write<uint8_t>(v, 8);
544 blinfo_lookup(BLINFO_RECOVERY, &v,
sizeof(v));
545 writer.write<uint8_t>(v, 8);
546 blinfo_lookup(BLINFO_RUNNING_SLOT, &v,
sizeof(v));
547 writer.write<uint8_t>(v, 8);
549 struct image_version mcuboot_version;
550 blinfo_lookup(BLINFO_BOOTLOADER_VERSION,
551 reinterpret_cast<char *
>(&mcuboot_version),
552 sizeof(mcuboot_version));
553 writer.write<uint32_t>(mcuboot_version.iv_major, 32);
554 writer.write<uint32_t>(mcuboot_version.iv_minor, 32);
555 writer.write<uint32_t>(mcuboot_version.iv_revision, 32);
558 blinfo_lookup(BLINFO_MAX_APPLICATION_SIZE,
reinterpret_cast<char *
>(&s),
560 writer.write<uint32_t>(s, 32);
561 writer.write<
bool>(boot_is_img_confirmed(), 1);
564 uint8_t areas[2] = {FIXED_PARTITION_ID(slot0_partition),
565 FIXED_PARTITION_ID(slot1_partition)};
567 for (uint8_t i = 0; i < 2; i++) {
568 struct mcuboot_img_header mcuboot_hdr;
569 memset(&mcuboot_hdr, 0,
sizeof(mcuboot_hdr));
570 boot_read_bank_header(areas[i], &mcuboot_hdr,
sizeof(mcuboot_hdr));
571 writer.write<uint32_t>(mcuboot_hdr.h.v1.image_size, 32);
572 writer.write<uint32_t>(mcuboot_hdr.h.v1.sem_ver.major, 32);
573 writer.write<uint32_t>(mcuboot_hdr.h.v1.sem_ver.minor, 32);
574 writer.write<uint32_t>(mcuboot_hdr.h.v1.sem_ver.revision, 32);
584 serialize(etl::bit_stream_writer &writer, etl::istring &path)
587 etl::string_ext res(
reinterpret_cast<char *
>(writer.begin()),
588 writer.capacity_bytes());
590 writer.skip(res.length() * 8 + 8);
603 path, (uint8_t *)(writer.begin() +
sizeof(uint32_t)), len,
offset);
604 writer.write<uint32_t>(bytes, 32);
605 writer.skip(8 * bytes);
613 serialize(etl::bit_stream_writer &writer, etl::istring &path)
617 memcpy(writer.begin(), path.c_str(), path.size());
618 writer.skip(8 * path.size());
619 writer.write<
char>(
'\0', 8);
620 writer.write<uint32_t>(ret, 32);
662 writer.write<uint8_t>(
665 writer.write<uint8_t>(
667 writer.write<uint8_t>(
673 writer.write<uint8_t>(agc1.avg, 2);
674 writer.write<uint8_t>(agc1.input, 1);
675 writer.write<uint8_t>(agc1.tgt, 3);
678 writer.write<uint8_t>(
680 writer.write<uint8_t>(
684 writer.write<uint8_t>(fsk.baudrate, 3);
688 writer.write<uint8_t>(fsk.baudrate, 3);
721 writer.write<uint8_t>(
724 writer.write<uint8_t>(
726 writer.write<uint8_t>(
732 writer.write<uint8_t>(agc1.avg, 2);
733 writer.write<uint8_t>(agc1.input, 1);
734 writer.write<uint8_t>(agc1.tgt, 3);
737 writer.write<uint8_t>(
739 writer.write<uint8_t>(
743 writer.write<uint8_t>(fsk.baudrate, 3);
747 writer.write<uint8_t>(fsk.baudrate, 3);
780 serialize(etl::bit_stream_writer &writer,
size_t start_sector,
size_t sectors)
785 nbytes = etl::clamp(nbytes, 0U, writer.available<uint8_t>());
787 reinterpret_cast<uint8_t *
>(writer.end() +
sizeof(uint32_t)),
800 writer.write<uint8_t>(resp.
session, 8);
801 writer.write<uint8_t>(
static_cast<uint8_t
>(resp.
s), 8);
802 writer.write<uint32_t>(resp.
ack, 32);
static error_handler & get_instance()
Singleton access to the error_handler subsystem.
uint32_t hwinfo_reset_cause() const
Retrieves the hardware reset cause from the MCU.
const utils::iface_ctrl & uhf()
const utils::iface_ctrl & sband()
static io & get_instance()
comms::lib::power & power()
Returns a reference to the power subsystem.
comms::lib::radio & radio()
Returns a reference to the radio subsystem.
comms::lib::fpga & fpga()
Returns a reference to the FPGA subsystem.
static board & get_instance()
Gets a reference to the single instance of the Board interface class.
@ EFUSES
Power measured by eFuses.
@ EMC1702
Power measured by the EMC1702 sensor.
@ CAN2_LPWR
Low-power mode for CAN Bus 2.
@ CAN1_LPWR
Low-power mode for CAN Bus 1.
@ RF_5V
RF 5V voltage/current channel.
@ V_BAT
Battery voltage channel.
@ FPGA
FPGA voltage/current channel.
@ DIG_3V3
Digital 3.3V voltage/current channel.
@ VIN
Input voltage channel.
Radio subsystem providing TX/RX functionality on UHF and S-Band.
clk_src get_clk_src() const
Retrieves the current clock source of the AT86RF215 PLL.
static logger & get_instance()
Singleton access to the logger subsystem.
uint8_t data[mtu]
Buffer to hold the data.
size_t len
Data size in bytes.
static constexpr size_t mtu
static settings & get_instance()
Get a singleton access to the settings subsystem.
@ THERMAL_UHF_SHUTDOWN_TEMP
@ THERMAL_SBAND_ENABLE_TEMP
@ SBAND_GAIN0_CALIB_SLOPE
@ SBAND_AGC0_CALIB_INTRCPT
@ THERMAL_PCB_SHUTDOWN_TEMP
@ THERMAL_SBAND_SHUTDOWN_TEMP
@ THERMAL_UHF_ENABLE_TEMP
@ SBAND_TRX_TURNAROUND_MS
@ SBAND_GAIN0_CALIB_INTRCPT
@ UHF_GAIN0_CALIB_INTRCPT
@ THERMAL_PCB_ENABLE_TEMP
size_t read(const etl::istring &path, uint8_t *b, size_t len, size_t offset)
Reads from a file starting from specific offset.
void ls(const etl::istring &path, etl::istring &res)
Lists the contents of a directory.
uint64_t du(const etl::istring &path)
Calculate the disk usage of a file or directory likewise the 'du' command of Linux.
size_t read_raw(uint8_t *b, size_t start_sector, size_t sectors)
Reads directly raw sectors from the eMMC, bypassing any filesystem.
static storage & get_instance()
bool is_dir(const etl::istring &path)
Check if a path is a directory.
static constexpr size_t SECTOR_SIZE
static telecommand & get_instance()
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer, bool success)
static void append_git_hash(etl::bit_stream_writer &writer, const char *hash)
static constexpr size_t hash_max_len
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer, size_t start_sector, size_t sectors)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer, const ota::response_tlm &resp)
static void serialize(etl::bit_stream_writer &writer, uint8_t const buf[], size_t len)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer, etl::istring &path)
static void serialize(etl::bit_stream_writer &writer, etl::istring &path)
static void serialize(etl::bit_stream_writer &writer, etl::istring &path, size_t offset, size_t len)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void serialize(etl::bit_stream_writer &writer)
static void send_ring_buffer_logs_tlm(msg_arbiter::msg &m, const size_t num_of_logs)
void operator=(telemetry const &)=delete
static telemetry & get_instance()
static void send_all_ota_sessions_info_tlm(msg_arbiter::msg &m)
static void serialize(etl::bit_stream_writer &writer, float x)
static void tlm(msg_arbiter::msg &m, Args &&...args)
telemetry(telemetry const &)=delete
static thermal & get_instance()
Time and position information.
void gnss(struct gnss_data &data)
Retrieve latest GNSS information.
time_src get(uint64_t &t)
Gets the time in ms.
uint64_t uptime()
Gets the current system uptime in milliseconds.
uint64_t last_gnss_update_uptime()
Gets the system uptime (in milliseconds) at the time of the last GNSS fix.
uint64_t last_nmea_update_uptime()
static time & get_instance()
@ PCB
PCB temperature sensor.
@ UHF_PA
UHF PA temperature sensor.
@ SBAND_PA
S-Band PA temperature sensor.