Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions tockloader/board_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,18 @@ class BoardInterface:
"flush_command": "probe-rs download {binary} --binary-format bin --base-address 0x10000000 --chip CY8C624AAZI-S2D44",
},
},
"stm32wle5jc": {
"description": "Seeed Studio LoRa-E5 board based on the STM32WLE5JC SoC",
"arch": "cortex-m4",
"page_size": 2048,
"no_attribute_table": True,
"openocd": {
"prefix": "source [find interface/stlink.cfg]; \
transport select hla_swd; \
source [find target/stm32wlx.cfg];",
"address_maximum": 0x08040000,
},
},
}

def __init__(self, args):
Expand Down
20 changes: 19 additions & 1 deletion tockloader/openocd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import time

from .board_interface import BoardInterface
from .exceptions import TockLoaderException
from .exceptions import TockLoaderException, ChannelAddressErrorException

# global static variable for collecting temp files for Windows
collect_temp_files = []
Expand All @@ -33,6 +33,7 @@ def __init__(self, args):

# Store the serial number if provided
self.openocd_serial_number = getattr(self.args, "openocd_serial_number")
self.address_maximum = None

def attached_board_exists(self):
# Get a list of attached devices, check if that list has at least
Expand Down Expand Up @@ -84,6 +85,8 @@ def open_link_to_board(self):
self.openocd_prefix = board["openocd"]["prefix"]
if self.openocd_commands == {} and "commands" in board["openocd"]:
self.openocd_commands = board["openocd"]["commands"]
if self.address_maximum == None and "address_maximum" in board["openocd"]:
self.address_maximum = board["openocd"]["address_maximum"]

# And we may need to setup other common board settings.
self._configure_from_known_boards()
Expand Down Expand Up @@ -248,6 +251,11 @@ def _list_emulators(self):
openocd_cmd=self.openocd_cmd
)
)
openocd_commands.append(
'{openocd_cmd} -c "source [find interface/stlink.cfg]; transport select hla_swd; source [find target/stm32wlx.cfg]; init; exit;"'.format(
openocd_cmd=self.openocd_cmd
)
)

# These are the magic strings in the output of openocd we are looking
# for. If there is a better way to do this then we should change. But,
Expand All @@ -259,6 +267,7 @@ def _list_emulators(self):
("(mfg: 0x049 (Xilinx), part: 0x3631, ver: 0x1)", "arty"),
("SWD DPIDR 0x2ba01477", "microbit_v2"),
("stm32f4x.cpu", "stm32f4discovery"),
("stm32wlx.cpu", "stm32wle5jc"),
]

emulators = []
Expand Down Expand Up @@ -306,6 +315,9 @@ def flash_binary(self, address, binary, pad=False):
# The "normal" flash command uses `program`.
command = "program {{binary}} verify {address:#x}; reset;"

if self.address_maximum and address + len(binary) > self.address_maximum:
raise ChannelAddressErrorException()

# Check if the configuration wants to override the default program command.
if "program" in self.openocd_commands:
command = self.openocd_commands["program"]
Expand All @@ -329,6 +341,9 @@ def flash_binary(self, address, binary, pad=False):
self._run_openocd_commands(command, binary)

def read_range(self, address, length):
if self.address_maximum and address + length > self.address_maximum:
raise ChannelAddressErrorException()

# The normal read command uses `dump_image`.
command = "dump_image {{binary}} {address:#x} {length};"

Expand Down Expand Up @@ -360,6 +375,9 @@ def read_range(self, address, length):
return read

def clear_bytes(self, address):
if self.address_maximum and address >= self.address_maximum:
raise ChannelAddressErrorException()

logging.debug("Clearing bytes starting at {:#0x}".format(address))

binary = bytes([0xFF] * 8)
Expand Down
23 changes: 20 additions & 3 deletions tockloader/tockloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ class TockLoader:
"cy8cproto_62_4343_w": {
"start_address": 0x10100000,
},
"stm32wle5jc": {
"start_address": 0x8018000,
},
},
}

Expand Down Expand Up @@ -1669,14 +1672,25 @@ def is_valid(slices):
optional_binary = app.get_binary(app_address)
if optional_binary:
logging.info("Flashing app {} binary to board.".format(app))
self.channel.flash_binary(app_address, optional_binary)
try:
self.channel.flash_binary(app_address, optional_binary)
except ChannelAddressErrorException:
logging.info(
"Failed to find space to flash app {}.".format(app)
)
pass
app_address = app_address + app.get_size()

# Then erase the next page if we have not already rewritten all
# existing apps. This ensures that flash is clean at the end of the
# installed apps and makes sure the kernel will find the correct end
# of applications.
self.channel.clear_bytes(app_address)
try:
self.channel.clear_bytes(app_address)
except ChannelAddressErrorException:
# We are at the end of flash and there are no bytes
# left to clear.
pass

def _replace_with_padding(self, app):
"""
Expand Down Expand Up @@ -1717,7 +1731,10 @@ def _extract_all_app_headers(self, verbose=False, extract_app_binary=False):
logging.debug(
"Reading for app header @{:#x}, {} bytes".format(address, header_length)
)
flash = self.channel.read_range(address, header_length)
try:
flash = self.channel.read_range(address, header_length)
except ChannelAddressErrorException:
break

# if there was an error, the binary array will be empty
if len(flash) < header_length:
Expand Down