Skip to content

Commit

Permalink
feat: Support uploading hex file
Browse files Browse the repository at this point in the history
Naive implementation, assuming the addresses start at 0 and increment.
  • Loading branch information
florisla committed Oct 10, 2023
1 parent f99d628 commit 600aa07
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 2 deletions.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ classifiers = [
dynamic = ["version"]

[project.optional-dependencies]
hex = [
"intelhex",
]
dev = [
"wheel",
"twine",
Expand Down
4 changes: 4 additions & 0 deletions stm32loader/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class DataMismatchError(Stm32LoaderError):
"""Exception: data comparison failed."""


class MissingDependencyError(Stm32LoaderError):
"""Exception: required dependency is missing."""


class ShowProgress:
"""
Show progress through a progress bar, as a context manager.
Expand Down
30 changes: 30 additions & 0 deletions stm32loader/hexfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Load binary data from a file in Intel hex format."""

from stm32loader.bootloader import MissingDependencyError

try:
import intelhex
except ImportError:
intelhex = None


def load_hex(file_path: str) -> bytes:
"""
Return bytes from the given hex file.
Addresses should start at zero and always increment.
"""
if intelhex is None:
raise MissingDependencyError(
"Please install package 'intelhex' in order to read .hex files."
)

hex_content = intelhex.IntelHex()
hex_content.loadhex(str(file_path))
hex_dict = hex_content.todict()

addresses = list(hex_dict.keys())
assert addresses[0] == 0
assert addresses[-1] == len(addresses) - 1

return bytes(hex_content.todict().values())
9 changes: 7 additions & 2 deletions stm32loader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import os
import sys
from types import SimpleNamespace
from pathlib import Path

try:
from progress.bar import ChargingBar as progress_bar
Expand All @@ -35,6 +36,7 @@

from stm32loader import __version__, bootloader
from stm32loader.uart import SerialConnection
from stm32loader.hexfile import load_hex

DEFAULT_VERBOSITY = 5

Expand Down Expand Up @@ -323,8 +325,11 @@ def perform_commands(self):
# pylint: disable=too-many-branches
binary_data = None
if self.configuration.write or self.configuration.verify:
with open(self.configuration.data_file, "rb") as read_file:
binary_data = bytearray(read_file.read())
data_file_path = Path(self.configuration.data_file)
if data_file_path.suffix == ".hex":
binary_data = load_hex(data_file_path)
else:
binary_data = data_file_path.read_bytes()
if self.configuration.unprotect:
try:
self.stm32.readout_unprotect()
Expand Down
2 changes: 2 additions & 0 deletions tests/data/small.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:10000000000102030405060708090A0B0C0D0E0F78
:00000001FF
14 changes: 14 additions & 0 deletions tests/unit/test_hexfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

from pathlib import Path

HERE = Path(__file__).parent
DATA = HERE / "../data"


from stm32loader.hexfile import load_hex


def test_load_hex_delivers_bytes():
small_hex_path = DATA / "small.hex"
data = load_hex(small_hex_path)
assert data == bytes(range(16))

0 comments on commit 600aa07

Please sign in to comment.