implement CRC write
Some checks failed
Rust/va416xx-rs/pipeline/pr-main There was a failure building this commit
Some checks failed
Rust/va416xx-rs/pipeline/pr-main There was a failure building this commit
This commit is contained in:
parent
1cc8645781
commit
1b313d21c4
@ -34,3 +34,4 @@ debug-assertions = false # <-
|
||||
lto = true
|
||||
opt-level = 'z' # <-
|
||||
overflow-checks = false # <-
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
|
@ -18,7 +18,7 @@
|
||||
#![no_std]
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use crc::{Crc, CRC_16_IBM_3740};
|
||||
use crc::{Crc, CRC_32_ISO_HDLC};
|
||||
use panic_rtt_target as _;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va416xx_hal::{
|
||||
@ -47,7 +47,7 @@ const FLASH_SELF: bool = false;
|
||||
|
||||
const BOOTLOADER_START_ADDR: u32 = 0x0;
|
||||
const BOOTLOADER_END_ADDR: u32 = 0x4000;
|
||||
const BOOTLOADER_CRC_ADDR: u32 = 0x3FFE;
|
||||
const BOOTLOADER_CRC_ADDR: u32 = 0x3FFC;
|
||||
const APP_A_START_ADDR: u32 = 0x4000;
|
||||
pub const APP_A_END_ADDR: u32 = 0x22000;
|
||||
// The actual size of the image which is relevant for CRC calculation.
|
||||
@ -64,7 +64,7 @@ pub const VECTOR_TABLE_OFFSET: u32 = 0x0;
|
||||
pub const VECTOR_TABLE_LEN: u32 = 0x350;
|
||||
pub const RESET_VECTOR_OFFSET: u32 = 0x4;
|
||||
|
||||
const CRC_ALGO: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_3740);
|
||||
const CRC_ALGO: Crc<u32> = Crc::<u32>::new(&CRC_32_ISO_HDLC);
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
enum AppSel {
|
||||
@ -111,6 +111,7 @@ fn main() -> ! {
|
||||
WDT_FREQ_MS,
|
||||
));
|
||||
}
|
||||
|
||||
let nvm = Nvm::new(&mut dp.sysconfig, dp.spi3, &clocks);
|
||||
|
||||
if FLASH_SELF {
|
||||
@ -172,7 +173,7 @@ fn main() -> ! {
|
||||
}
|
||||
|
||||
fn check_own_crc(wdt: &OptWdt, nvm: &Nvm, cp: &cortex_m::Peripherals) {
|
||||
let crc_exp = unsafe { *(BOOTLOADER_CRC_ADDR as *const u16) };
|
||||
let crc_exp = unsafe { *(BOOTLOADER_CRC_ADDR as *const u32) };
|
||||
wdt.feed();
|
||||
// I'd prefer to use [core::slice::from_raw_parts], but that is problematic
|
||||
// because the address of the bootloader is 0x0, so the NULL check fails and the functions
|
||||
@ -219,7 +220,7 @@ fn check_app_given_addr(
|
||||
image_size_addr: u32,
|
||||
wdt: &OptWdt,
|
||||
) -> bool {
|
||||
let crc_exp = unsafe { *(crc_addr as *const u16) };
|
||||
let crc_exp = unsafe { *(crc_addr as *const u32) };
|
||||
let image_size = unsafe { *(image_size_addr as *const u32) };
|
||||
wdt.feed();
|
||||
let crc_calc = CRC_ALGO.checksum(unsafe {
|
||||
|
@ -10,6 +10,7 @@ import time
|
||||
from tmtccmd.com.serial_base import SerialCfg
|
||||
from tmtccmd.com.serial_cobs import SerialCobsComIF
|
||||
from tmtccmd.com.ser_utils import prompt_com_port
|
||||
from crcmod.predefined import PredefinedCrc
|
||||
from spacepackets.ecss.tc import PusTc
|
||||
from pathlib import Path
|
||||
import dataclasses
|
||||
@ -19,7 +20,7 @@ from elftools.elf.elffile import ELFFile
|
||||
BAUD_RATE = 115200
|
||||
BOOTLOADER_START_ADDR = 0x0
|
||||
BOOTLOADER_END_ADDR = 0x4000
|
||||
BOOTLOADER_CRC_ADDR = 0x3FFE
|
||||
BOOTLOADER_CRC_ADDR = 0x3FFC
|
||||
APP_A_START_ADDR = 0x4000
|
||||
APP_A_END_ADDR = 0x22000
|
||||
# The actual size of the image which is relevant for CRC calculation.
|
||||
@ -104,9 +105,29 @@ def main() -> int:
|
||||
with open(file_path, "rb") as app_file:
|
||||
elf_file = ELFFile(app_file)
|
||||
|
||||
for segment in elf_file.iter_segments("PT_LOAD"):
|
||||
for (idx, segment) in enumerate(elf_file.iter_segments("PT_LOAD")):
|
||||
if segment.header.p_filesz == 0:
|
||||
continue
|
||||
# Basic validity checks of the base addresses.
|
||||
if idx == 0:
|
||||
if (
|
||||
args.flash == "bl"
|
||||
and segment.header.p_paddr != BOOTLOADER_START_ADDR
|
||||
):
|
||||
raise ValueError(
|
||||
f"detected possibly invalid start address {segment.header.p_paddr} for "
|
||||
f"bootloader, expected {BOOTLOADER_START_ADDR}"
|
||||
)
|
||||
if args.flash == "a" and segment.header.p_paddr != APP_A_START_ADDR:
|
||||
raise ValueError(
|
||||
f"detected possibly invalid start address {segment.header.p_paddr} for "
|
||||
f"App A, expected {APP_A_START_ADDR}"
|
||||
)
|
||||
if args.flash == "b" and segment.header.p_paddr != APP_B_START_ADDR:
|
||||
raise ValueError(
|
||||
f"detected possibly invalid start address {segment.header.p_paddr} for "
|
||||
f"App B, expected {APP_B_START_ADDR}"
|
||||
)
|
||||
name = None
|
||||
for section in elf_file.iter_sections():
|
||||
if (
|
||||
@ -138,24 +159,28 @@ def main() -> int:
|
||||
next_chunk_size = segment.offset + segment.size - current_addr
|
||||
if next_chunk_size > CHUNK_SIZE:
|
||||
next_chunk_size = CHUNK_SIZE
|
||||
app_data = bytearray()
|
||||
app_data.append(BOOT_NVM_MEMORY_ID)
|
||||
# N parameter is always 1 here.
|
||||
app_data.append(1)
|
||||
app_data.extend(struct.pack("!I", current_addr))
|
||||
app_data.extend(struct.pack("!I", next_chunk_size))
|
||||
app_data.extend(
|
||||
segment.data[current_addr : current_addr + next_chunk_size]
|
||||
next_packet = pack_memory_write_command(
|
||||
current_addr,
|
||||
segment.data[current_addr : current_addr + next_chunk_size],
|
||||
)
|
||||
current_addr += next_chunk_size
|
||||
next_packet = PusTc(
|
||||
apid=0,
|
||||
service=MEMORY_SERVICE,
|
||||
subservice=RAW_MEMORY_WRITE_SUBSERVICE,
|
||||
app_data=app_data,
|
||||
)
|
||||
com_if.send(next_packet.pack())
|
||||
time.sleep(0.5)
|
||||
crc_calc = PredefinedCrc("crc-32")
|
||||
for segment in loadable_segments:
|
||||
crc_calc.update(segment)
|
||||
if args.flash == "bl":
|
||||
crc_addr = BOOTLOADER_CRC_ADDR
|
||||
elif args.flash == "a":
|
||||
crc_addr = APP_A_CRC_ADDR
|
||||
elif args.flash == "b":
|
||||
crc_addr = APP_B_CRC_ADDR
|
||||
else:
|
||||
raise ValueError(f"unknown flash target {args.flash}")
|
||||
checksum = crc_calc.digest()
|
||||
checksum_write_packet = pack_memory_write_command(crc_addr, checksum)
|
||||
com_if.send(checksum_write_packet.pack())
|
||||
time.sleep(0.5)
|
||||
while True:
|
||||
data_available = com_if.data_available(0.4)
|
||||
if data_available:
|
||||
@ -167,5 +192,21 @@ def main() -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def pack_memory_write_command(addr: int, data: bytes) -> PusTc:
|
||||
app_data = bytearray()
|
||||
app_data.append(BOOT_NVM_MEMORY_ID)
|
||||
# N parameter is always 1 here.
|
||||
app_data.append(1)
|
||||
app_data.extend(struct.pack("!I", addr))
|
||||
app_data.extend(struct.pack("!I", len(data)))
|
||||
app_data.extend(data)
|
||||
return PusTc(
|
||||
apid=0,
|
||||
service=MEMORY_SERVICE,
|
||||
subservice=RAW_MEMORY_WRITE_SUBSERVICE,
|
||||
app_data=app_data,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -1,4 +1,5 @@
|
||||
spacepackets == 0.24
|
||||
tmtccmd == 8.0.1
|
||||
tmtccmd == 8.0.2
|
||||
toml == 0.10
|
||||
pyelftools == 0.31
|
||||
crcmod == 1.7
|
||||
|
@ -52,6 +52,7 @@ static CLOCKS: OnceCell<Clocks> = OnceCell::new();
|
||||
#[rtic::app(device = pac, dispatchers = [U1, U2, U3])]
|
||||
mod app {
|
||||
use super::*;
|
||||
use cortex_m::asm;
|
||||
use embedded_hal_nb::nb;
|
||||
use panic_rtt_target as _;
|
||||
use rtic::Mutex;
|
||||
@ -157,8 +158,9 @@ mod app {
|
||||
// `shared` cannot be accessed from this context
|
||||
#[idle]
|
||||
fn idle(_cx: idle::Context) -> ! {
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
loop {
|
||||
asm::nop();
|
||||
}
|
||||
}
|
||||
|
||||
#[task(
|
||||
|
Loading…
Reference in New Issue
Block a user