continue flash loader
Some checks failed
Rust/va416xx-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2024-07-12 10:44:41 +02:00
parent c53702ee74
commit ac015d1473
Signed by: muellerr
GPG Key ID: A649FB78196E3849
4 changed files with 137 additions and 3 deletions

View File

@ -1,14 +1,19 @@
#!/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
from tmtccmd.com.ser_utils import prompt_com_port
from spacepackets.ecss.tc import PusTc
from pathlib import Path
import dataclasses
from elftools.elf.elffile import ELFFile
BAUD_RATE = 115200
@ -27,10 +32,24 @@ APP_B_SIZE_ADDR = 0x3FFF8
APP_B_CRC_ADDR = 0x3FFFC
APP_IMG_SZ = 0x1E000
CHUNK_SIZE = 896
MEMORY_SERVICE = 6
RAW_MEMORY_WRITE_SUBSERVICE = 2
BOOT_NVM_MEMORY_ID = 1
_LOGGER = logging.getLogger(__name__)
def main():
@dataclasses.dataclass
class LoadableSegment:
name: str
offset: int
size: int
data: bytes
def main() -> int:
print("Python VA416XX Image Loader Application")
logging.basicConfig(
format="[%(asctime)s] [%(levelname)s] %(message)s", level=logging.DEBUG
@ -65,13 +84,78 @@ def main():
)
com_if = SerialCobsComIF(serial_cfg)
com_if.open()
if args.flash and not args.path:
_LOGGER.error("App Path needs to be specified for the flash process")
file_path = None
if args.flash:
if not args.path:
_LOGGER.error("App Path needs to be specified for the flash process")
return -1
file_path = Path(args.path)
if not file_path.exists():
_LOGGER.error("File does not exist")
return -1
ping_tc = PusTc(apid=0x00, service=PusService.S17_TEST, subservice=1)
if args.ping:
_LOGGER.info("Sending ping command")
com_if.send(ping_tc.pack())
if args.flash:
assert file_path is not None
loadable_segments = []
_LOGGER.info("Parsing ELF file for loadable sections")
with open(file_path, "rb") as app_file:
elf_file = ELFFile(app_file)
for segment in elf_file.iter_segments("PT_LOAD"):
if segment.header.p_filesz == 0:
continue
name = None
for section in elf_file.iter_sections():
if (
section.header.sh_offset == segment.header.p_offset
and section.header.sh_size > 0
):
name = section.name
if name is None:
_LOGGER.warning("no fitting section found for segment")
continue
# print(f"Segment Addr: {segment.header.p_paddr}")
# print(f"Segment Offset: {segment.header.p_offset}")
# print(f"Segment Filesize: {segment.header.p_filesz}")
loadable_segments.append(
LoadableSegment(
name=name,
offset=segment.header.p_paddr,
size=segment.header.p_filesz,
data=segment.data(),
)
)
for idx, segment in enumerate(loadable_segments):
_LOGGER.info(
f"Loadable section {idx} {segment.name} with offset {segment.offset} and size {segment.size}"
)
for segment in loadable_segments:
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
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]
)
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)
while True:
data_available = com_if.data_available(0.4)
if data_available:
@ -80,6 +164,7 @@ def main():
print("Received replies: {}", reply)
break
com_if.close()
return 0
if __name__ == "__main__":

View File

@ -1,3 +1,4 @@
spacepackets == 0.24
tmtccmd == 8.0.1
toml == 0.10
pyelftools == 0.31

24
scripts/memory_app_a.x Normal file
View File

@ -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
};

24
scripts/memory_app_b.x Normal file
View File

@ -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
};