From 46937f5bf9b80a60650915124ec1d092f842c103 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 Sep 2024 18:55:15 +0200 Subject: [PATCH] try to test this --- Cargo.toml | 9 +- flashloader/image-loader.py | 92 +++++++++++++------ flashloader/slot-a-blinky/.gitignore | 2 + flashloader/slot-a-blinky/Cargo.toml | 42 +++++++++ flashloader/slot-a-blinky/memory.x | 24 +++++ flashloader/slot-a-blinky/src/main.rs | 23 +++++ flashloader/slot-b-blinky/.cargo/config.toml | 42 +++++++++ .../slot-b-blinky/.cargo/def-config.toml | 42 +++++++++ flashloader/slot-b-blinky/.gitignore | 2 + flashloader/slot-b-blinky/Cargo.toml | 42 +++++++++ flashloader/slot-b-blinky/memory.x | 24 +++++ flashloader/slot-b-blinky/src/main.rs | 23 +++++ va416xx-hal/src/nvm.rs | 4 +- 13 files changed, 340 insertions(+), 31 deletions(-) create mode 100644 flashloader/slot-a-blinky/.gitignore create mode 100644 flashloader/slot-a-blinky/Cargo.toml create mode 100644 flashloader/slot-a-blinky/memory.x create mode 100644 flashloader/slot-a-blinky/src/main.rs create mode 100644 flashloader/slot-b-blinky/.cargo/config.toml create mode 100644 flashloader/slot-b-blinky/.cargo/def-config.toml create mode 100644 flashloader/slot-b-blinky/.gitignore create mode 100644 flashloader/slot-b-blinky/Cargo.toml create mode 100644 flashloader/slot-b-blinky/memory.x create mode 100644 flashloader/slot-b-blinky/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index d50955e..c04e850 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,16 @@ resolver = "2" members = [ "bootloader", - "examples/simple", "flashloader", + "flashloader", + "examples/simple", "va416xx", "va416xx-hal", "vorago-peb1" ] +exclude = [ + "flashloader/slot-a-blinky", + "flashloader/slot-b-blinky", +] [profile.dev] codegen-units = 1 @@ -34,4 +39,4 @@ debug-assertions = false # <- lto = true opt-level = 'z' # <- overflow-checks = false # <- -strip = true # Automatically strip symbols from the binary. +# strip = true # Automatically strip symbols from the binary. diff --git a/flashloader/image-loader.py b/flashloader/image-loader.py index 3bbfcf0..55014e7 100755 --- a/flashloader/image-loader.py +++ b/flashloader/image-loader.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 -from dataclasses import dataclass from spacepackets.ecss.defs import PusService import toml import struct import logging import argparse -from typing import List import time from tmtccmd.com.serial_base import SerialCfg from tmtccmd.com.serial_cobs import SerialCobsComIF @@ -102,6 +100,7 @@ def main() -> int: assert file_path is not None loadable_segments = [] _LOGGER.info("Parsing ELF file for loadable sections") + total_size = 0 with open(file_path, "rb") as app_file: elf_file = ELFFile(app_file) @@ -115,17 +114,17 @@ def main() -> int: and segment.header.p_paddr != BOOTLOADER_START_ADDR ): raise ValueError( - f"detected possibly invalid start address {segment.header.p_paddr} for " + f"detected possibly invalid start address {segment.header.p_paddr:#08x} 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"detected possibly invalid start address {segment.header.p_paddr:#08x} 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"detected possibly invalid start address {segment.header.p_paddr:#08x} for " f"App B, expected {APP_B_START_ADDR}" ) name = None @@ -149,38 +148,75 @@ def main() -> int: data=segment.data(), ) ) + total_size += segment.header.p_filesz + context_str = None + if args.flash == "bl": + context_str = "Bootloader" + elif args.flash == "a": + context_str = "App Slot A" + elif args.flash == "b": + context_str = "App Slot B" + _LOGGER.info( + f"Flashing {context_str} with image {file_path} (size {total_size})" + ) for idx, segment in enumerate(loadable_segments): _LOGGER.info( - f"Loadable section {idx} {segment.name} with offset {segment.offset} and size {segment.size}" + f"Loadable section {idx} {segment.name} with offset {segment.offset:#08x} and size {segment.size}" ) for segment in loadable_segments: + segment_end = segment.offset + segment.size current_addr = segment.offset - while current_addr < segment.offset + segment.size: - next_chunk_size = segment.offset + segment.size - current_addr - if next_chunk_size > CHUNK_SIZE: - next_chunk_size = CHUNK_SIZE - next_packet = pack_memory_write_command( - current_addr, - segment.data[current_addr : current_addr + next_chunk_size], + pos_in_segment = 0 + while pos_in_segment < segment.size: + next_chunk_size = min(segment_end - current_addr, CHUNK_SIZE) + data = segment.data[ + pos_in_segment : pos_in_segment + next_chunk_size + ] + _LOGGER.info( + f"Sending memory write command for address {current_addr:#08x} and data with " + f"length {len(data)}" ) - current_addr += next_chunk_size + next_packet = pack_memory_write_command(current_addr, 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) + current_addr += next_chunk_size + pos_in_segment += next_chunk_size + time.sleep(0.2) 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 + _LOGGER.info("Blanking the bootloader checksum") + # Blank the checksum. For the bootloader, the bootloader will calculate the + # checksum itself on the initial run. + checksum_write_packet = pack_memory_write_command( + BOOTLOADER_CRC_ADDR, bytes([0x00, 0x00, 0x00, 0x00]) + ) + com_if.send(checksum_write_packet.pack()) 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) + crc_addr = None + size_addr = None + if args.flash == "a": + crc_addr = APP_A_CRC_ADDR + size_addr = APP_A_SIZE_ADDR + elif args.flash == "b": + crc_addr = APP_B_CRC_ADDR + size_addr = APP_B_SIZE_ADDR + assert crc_addr is not None + assert size_addr is not None + _LOGGER.info( + f"Writing app size {total_size } at address {size_addr:#08x}" + ) + size_write_packet = pack_memory_write_command( + size_addr, struct.pack("!I", total_size) + ) + com_if.send(size_write_packet.pack()) + time.sleep(0.2) + crc_calc = PredefinedCrc("crc-32") + for segment in loadable_segments: + crc_calc.update(segment.data) + checksum = crc_calc.digest() + _LOGGER.info( + f"Writing checksum 0x[{checksum.hex(sep=',')}] at address {crc_addr:#08x}" + ) + checksum_write_packet = pack_memory_write_command(crc_addr, checksum) + com_if.send(checksum_write_packet.pack()) while True: data_available = com_if.data_available(0.4) if data_available: diff --git a/flashloader/slot-a-blinky/.gitignore b/flashloader/slot-a-blinky/.gitignore new file mode 100644 index 0000000..7f153fc --- /dev/null +++ b/flashloader/slot-a-blinky/.gitignore @@ -0,0 +1,2 @@ +/target +/app.map diff --git a/flashloader/slot-a-blinky/Cargo.toml b/flashloader/slot-a-blinky/Cargo.toml new file mode 100644 index 0000000..89ea213 --- /dev/null +++ b/flashloader/slot-a-blinky/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "slot-a-blinky" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +cortex-m-rt = "0.7" +va416xx-hal = { path = "../../va416xx-hal" } +panic-rtt-target = { version = "0.1.3" } +rtt-target = { version = "0.5" } +cortex-m = { version = "0.7", features = ["critical-section-single-core"] } +embedded-hal = "1" + +[profile.dev] +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +# This is problematic for stepping.. +# opt-level = 'z' # <- +overflow-checks = true # <- + +# cargo build/run --release +[profile.release] +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = 3 # <- +overflow-checks = false # <- + +[profile.small] +inherits = "release" +codegen-units = 1 +debug-assertions = false # <- +lto = true +opt-level = 'z' # <- +overflow-checks = false # <- +# strip = true # Automatically strip symbols from the binary. diff --git a/flashloader/slot-a-blinky/memory.x b/flashloader/slot-a-blinky/memory.x new file mode 100644 index 0000000..9d8c317 --- /dev/null +++ b/flashloader/slot-a-blinky/memory.x @@ -0,0 +1,24 @@ +/* Special linker script for application slot A with an offset at address 0x4000 */ +MEMORY +{ + FLASH : ORIGIN = 0x00004000, LENGTH = 256K + /* RAM is a mandatory region. This RAM refers to the SRAM_0 */ + RAM : ORIGIN = 0x1FFF8000, LENGTH = 32K + SRAM_1 : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ +/* SRAM_0 can be used for all busses: Instruction, Data and System */ +/* SRAM_1 only supports the system bus */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); + +/* Define sections for placing symbols into the extra memory regions above. */ +/* This makes them accessible from code. */ +SECTIONS { + .sram1 (NOLOAD) : ALIGN(8) { + *(.sram1 .sram1.*); + . = ALIGN(4); + } > SRAM_1 +}; diff --git a/flashloader/slot-a-blinky/src/main.rs b/flashloader/slot-a-blinky/src/main.rs new file mode 100644 index 0000000..517b20c --- /dev/null +++ b/flashloader/slot-a-blinky/src/main.rs @@ -0,0 +1,23 @@ +//! Simple blinky example using the HAL +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::digital::StatefulOutputPin; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va416xx_hal::{gpio::PinsG, pac}; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("VA416xx HAL blinky example for App Slot A"); + + let mut dp = pac::Peripherals::take().unwrap(); + let portg = PinsG::new(&mut dp.sysconfig, dp.portg); + let mut led = portg.pg5.into_readable_push_pull_output(); + loop { + cortex_m::asm::delay(1_000_000); + led.toggle().ok(); + } +} diff --git a/flashloader/slot-b-blinky/.cargo/config.toml b/flashloader/slot-b-blinky/.cargo/config.toml new file mode 100644 index 0000000..71a2c31 --- /dev/null +++ b/flashloader/slot-b-blinky/.cargo/config.toml @@ -0,0 +1,42 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "gdb-multiarch -q -x jlink/jlink.gdb" +# runner = "arm-none-eabi-gdb -q -x jlink/jlink-reva.gdb" +# runner = "gdb-multiarch -q -x jlink/jlink-reva.gdb" + +# Probe-rs is currently problematic, possibly because of the +# ROM protection? +# runner = "probe-rs run --chip VA416xx" +# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"] + + +rustflags = [ + "-C", + "link-arg=-Tlink.x", + # "-C", + # "linker=flip-link", + # "-C", + # "link-arg=-Tdefmt.x", + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", + "link-arg=--nmagic", + # Can be useful for debugging. + "-Clink-args=-Map=app.map" +] + +[build] +# (`thumbv6m-*` is compatible with all ARM Cortex-M chips but using the right +# target improves performance) +# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) + +[alias] +rb = "run --bin" +rrb = "run --release --bin" +ut = "test --target=x86_64-unknown-linux-gnu" +oc = "objcopy" + +[env] +DEFMT_LOG = "info" diff --git a/flashloader/slot-b-blinky/.cargo/def-config.toml b/flashloader/slot-b-blinky/.cargo/def-config.toml new file mode 100644 index 0000000..22e52d8 --- /dev/null +++ b/flashloader/slot-b-blinky/.cargo/def-config.toml @@ -0,0 +1,42 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "gdb-multiarch -q -x jlink/jlink.gdb" +# runner = "arm-none-eabi-gdb -q -x jlink/jlink-reva.gdb" +# runner = "gdb-multiarch -q -x jlink/jlink-reva.gdb" + +# Probe-rs is currently problematic, possibly because of the +# ROM protection? +# runner = "probe-rs run --chip-description-path ./scripts/VA416xx_Series.yaml" +# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"] + + +rustflags = [ + "-C", + "link-arg=-Tlink.x", + # "-C", + # "linker=flip-link", + # "-C", + # "link-arg=-Tdefmt.x", + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", + "link-arg=--nmagic", + # Can be useful for debugging. + # "-Clink-args=-Map=app.map" +] + +[build] +# (`thumbv6m-*` is compatible with all ARM Cortex-M chips but using the right +# target improves performance) +# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) + +[alias] +rb = "run --bin" +rrb = "run --release --bin" +ut = "test --target=x86_64-unknown-linux-gnu" +genbin = "objcopy --release -- -O binary app.bin" + +[env] +DEFMT_LOG = "info" diff --git a/flashloader/slot-b-blinky/.gitignore b/flashloader/slot-b-blinky/.gitignore new file mode 100644 index 0000000..7f153fc --- /dev/null +++ b/flashloader/slot-b-blinky/.gitignore @@ -0,0 +1,2 @@ +/target +/app.map diff --git a/flashloader/slot-b-blinky/Cargo.toml b/flashloader/slot-b-blinky/Cargo.toml new file mode 100644 index 0000000..c60bdb4 --- /dev/null +++ b/flashloader/slot-b-blinky/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "slot-b-blinky" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +cortex-m-rt = "0.7" +va416xx-hal = { path = "../../va416xx-hal" } +panic-rtt-target = { version = "0.1.3" } +rtt-target = { version = "0.5" } +cortex-m = { version = "0.7", features = ["critical-section-single-core"] } +embedded-hal = "1" + +[profile.dev] +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +# This is problematic for stepping.. +# opt-level = 'z' # <- +overflow-checks = true # <- + +# cargo build/run --release +[profile.release] +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = 3 # <- +overflow-checks = false # <- + +[profile.small] +inherits = "release" +codegen-units = 1 +debug-assertions = false # <- +lto = true +opt-level = 'z' # <- +overflow-checks = false # <- +# strip = true # Automatically strip symbols from the binary. diff --git a/flashloader/slot-b-blinky/memory.x b/flashloader/slot-b-blinky/memory.x new file mode 100644 index 0000000..4a9dcb0 --- /dev/null +++ b/flashloader/slot-b-blinky/memory.x @@ -0,0 +1,24 @@ +/* Special linker script for application slot B with an offset at address 0x22000 */ +MEMORY +{ + FLASH : ORIGIN = 0x00022000, LENGTH = 256K + /* RAM is a mandatory region. This RAM refers to the SRAM_0 */ + RAM : ORIGIN = 0x1FFF8000, LENGTH = 32K + SRAM_1 : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ +/* SRAM_0 can be used for all busses: Instruction, Data and System */ +/* SRAM_1 only supports the system bus */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); + +/* Define sections for placing symbols into the extra memory regions above. */ +/* This makes them accessible from code. */ +SECTIONS { + .sram1 (NOLOAD) : ALIGN(8) { + *(.sram1 .sram1.*); + . = ALIGN(4); + } > SRAM_1 +}; diff --git a/flashloader/slot-b-blinky/src/main.rs b/flashloader/slot-b-blinky/src/main.rs new file mode 100644 index 0000000..5663410 --- /dev/null +++ b/flashloader/slot-b-blinky/src/main.rs @@ -0,0 +1,23 @@ +//! Simple blinky example using the HAL +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::digital::StatefulOutputPin; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va416xx_hal::{gpio::PinsG, pac}; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("VA416xx HAL blinky example for App Slot B"); + + let mut dp = pac::Peripherals::take().unwrap(); + let portg = PinsG::new(&mut dp.sysconfig, dp.portg); + let mut led = portg.pg5.into_readable_push_pull_output(); + loop { + cortex_m::asm::delay(8_000_000); + led.toggle().ok(); + } +} diff --git a/va416xx-hal/src/nvm.rs b/va416xx-hal/src/nvm.rs index 621bf93..90a3732 100644 --- a/va416xx-hal/src/nvm.rs +++ b/va416xx-hal/src/nvm.rs @@ -260,6 +260,8 @@ impl Nvm { /// Call [Self::shutdown] on drop. impl Drop for Nvm { fn drop(&mut self) { - self.shutdown(unsafe { &mut pac::Sysconfig::steal() }); + if self.spi.is_some() { + self.shutdown(unsafe { &mut pac::Sysconfig::steal() }); + } } }