Guides
Loading firmware
The board boots the firmware you would flash, with no changes. Client.start and Board.start take one file or a list of images.
An ELF file
from hardlabs_sdk import Client
board = Client().start("company_name/board_name", "build/app.elf")Several images
Give a bootloader and its application at the addresses you flash them to. A raw .bin needs its address. ELF and Intel HEX files carry their own addresses.
board = Client().start("company_name/board_name", [
"bootloader.bin@0x00400000",
"app.bin@0x00410000",
])
print(board.firmware["images"]) # where each image was loaded, with its sha256The processor boots from the image at the lowest address, as it would from flash. Image does the same as the file@address string:
from hardlabs_sdk import Image
board.start([Image("bootloader.bin", 0x00400000), Image("app.bin", 0x00410000)])Memory chips
A board's F-RAM, EEPROM and SPI NOR chips hold what your firmware left there on the bench: configuration, calibration, a log, a file system. Give a chip an image the same way, naming it by its reference designator, at an offset within it if you like:
board = Client().start("company_name/board_name", [
"app.elf",
"config.bin@U7", # U7 from offset 0
"calibration.bin@U12:0x100", # U12 from offset 0x100
Image.from_bytes(settings, "settings.bin", part="U7", address=0x100), # bytes your test works out
])
print(board.memory_loaded) # what went whereWhile the board runs, Board.memory reads and writes a chip as the firmware sees it:
u7 = board.memory("U7") # or board.U7.memory
print(board.memories()) # every memory chip, with its size
header = u7.read(0, 16)
u7.write(0x100, b"4") # as if another device wrote them
assert u7[0x100:0x102] == b"4"A chip keeps what it holds for as long as the simulation runs, as on a real board. A fresh Board.start gives every chip the images you named and leaves the rest blank, so every run starts from the same state. Board.restart keeps what they hold. When the board stops, it is gone unless you save it first, and a later run can start from what you saved:
board.stop(save_memory="nvm/") # nvm/U7.bin, nvm/U12.bin, … and nvm/memory.json
from hardlabs_sdk import memory_images
board = Client().start("company_name/board_name", ["app.elf", *memory_images("nvm/")])A name the board doesn't have, or an image that runs past a chip's end, is refused before the board boots. Chip images and reads travel compressed, so a large NOR chip that is mostly erased costs a few kilobytes. The processor's own flash is different: it starts from its images at every boot, restarts included.
Restarting
Board.restart power-cycles the board: the firmware boots again and the memory chips keep what they hold. Pass new firmware to boot that instead. Serial ports you have open keep their addresses across a restart.
board.restart()
board.restart("build/app-v2.elf")The board's own firmware
Leave the firmware out to boot whatever the board was published with. The demo board runs this way.
board = Client().start("hardlabs/demo-board")