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 #!/usr/bin/env python3
from dataclasses import dataclass
from spacepackets.ecss.defs import PusService from spacepackets.ecss.defs import PusService
import toml import toml
import struct
import logging import logging
import argparse import argparse
from typing import List
import time import time
from tmtccmd.com.serial_base import SerialCfg from tmtccmd.com.serial_base import SerialCfg
from tmtccmd.com.serial_cobs import SerialCobsComIF from tmtccmd.com.serial_cobs import SerialCobsComIF
from tmtccmd.com.ser_utils import prompt_com_port from tmtccmd.com.ser_utils import prompt_com_port
from spacepackets.ecss.tc import PusTc from spacepackets.ecss.tc import PusTc
from pathlib import Path from pathlib import Path
import dataclasses
from elftools.elf.elffile import ELFFile
BAUD_RATE = 115200 BAUD_RATE = 115200
@ -27,10 +32,24 @@ APP_B_SIZE_ADDR = 0x3FFF8
APP_B_CRC_ADDR = 0x3FFFC APP_B_CRC_ADDR = 0x3FFFC
APP_IMG_SZ = 0x1E000 APP_IMG_SZ = 0x1E000
CHUNK_SIZE = 896
MEMORY_SERVICE = 6
RAW_MEMORY_WRITE_SUBSERVICE = 2
BOOT_NVM_MEMORY_ID = 1
_LOGGER = logging.getLogger(__name__) _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") print("Python VA416XX Image Loader Application")
logging.basicConfig( logging.basicConfig(
format="[%(asctime)s] [%(levelname)s] %(message)s", level=logging.DEBUG format="[%(asctime)s] [%(levelname)s] %(message)s", level=logging.DEBUG
@ -65,13 +84,78 @@ def main():
) )
com_if = SerialCobsComIF(serial_cfg) com_if = SerialCobsComIF(serial_cfg)
com_if.open() com_if.open()
if args.flash and not args.path: file_path = None
_LOGGER.error("App Path needs to be specified for the flash process") 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) ping_tc = PusTc(apid=0x00, service=PusService.S17_TEST, subservice=1)
if args.ping: if args.ping:
_LOGGER.info("Sending ping command") _LOGGER.info("Sending ping command")
com_if.send(ping_tc.pack()) com_if.send(ping_tc.pack())
if args.flash: 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: while True:
data_available = com_if.data_available(0.4) data_available = com_if.data_available(0.4)
if data_available: if data_available:
@ -80,6 +164,7 @@ def main():
print("Received replies: {}", reply) print("Received replies: {}", reply)
break break
com_if.close() com_if.close()
return 0
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,3 +1,4 @@
spacepackets == 0.24 spacepackets == 0.24
tmtccmd == 8.0.1 tmtccmd == 8.0.1
toml == 0.10 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
};