continue flash loader
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
c53702ee74
commit
ac015d1473
@ -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__":
|
||||
|
@ -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
24
scripts/memory_app_a.x
Normal 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
24
scripts/memory_app_b.x
Normal 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
|
||||
};
|
Loading…
Reference in New Issue
Block a user