[tools] uf2ota: fix for Python 3.7, fix Windows path compatibility
This commit is contained in:
@@ -12,12 +12,12 @@ Some CPUs support dual-OTA schemes: firmware runs from one image, while the othe
|
||||
|
||||
Each firmware image may be either applicable:
|
||||
|
||||
1. only when flashing OTA1 (`part:file::`)
|
||||
2. only when flashing OTA2 (`::part:file`)
|
||||
3. for both schemes to a single partition (`part:file`)
|
||||
4. for both schemes but different partitions (`part1:file:part2:file`)
|
||||
5. for both schemes but with a different binary (`part:file1:part:file2`)
|
||||
6. for both schemes, with different binaries and target partitions (`part1:file1:part2:file2`)
|
||||
1. only when flashing OTA1 (`part;file;;`)
|
||||
2. only when flashing OTA2 (`;;part;file`)
|
||||
3. for both schemes to a single partition (`part;file`)
|
||||
4. for both schemes but different partitions (`part1;file;part2;file`)
|
||||
5. for both schemes but with a different binary (`part;file1;part;file2`)
|
||||
6. for both schemes, with different binaries and target partitions (`part1;file1;part2;file2`)
|
||||
|
||||
\* *`part` means partition here*
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ uf2ota: error: the following arguments are required: action, inputs
|
||||
Generate a UF2 file from a firmware image or several images.
|
||||
|
||||
```bash
|
||||
$ python uf2ota.py write --family RTL8710B --board wr3 --version 0.4.0 --fw esphome:2022.6.0-dev ota1:xip1.bin:ota2:xip2.bin
|
||||
$ python uf2ota.py write --family RTL8710B --board wr3 --version 0.4.0 --fw esphome:2022.6.0-dev "ota1;xip1.bin;ota2;xip2.bin"
|
||||
|
||||
$ ls -l out.uf2
|
||||
-rw-r--r-- 1 Kuba None 605696 May 28 14:35 out.uf2
|
||||
@@ -21,15 +21,15 @@ $ ls -l out.uf2
|
||||
|
||||
## inputs format
|
||||
|
||||
Format for `inputs` parameter is `part:file[:part:file]` (square brackets mean optional). First two (colon separated) values correspond to flashing OTA1 region, second two to OTA2.
|
||||
Format for `inputs` parameter is `part;file[;part;file]` (square brackets mean optional). First two (colon separated) values correspond to flashing OTA1 region, second two to OTA2.
|
||||
|
||||
Partition name can be suffixed by `+offset`, which causes writing the image file to the partition after some byte offset. Both files and/or partition names can be equal. Values can be empty (like `part:file::` or `::part:file`) if OTA1/2 images are not present in this file.
|
||||
Partition name can be suffixed by `+offset`, which causes writing the image file to the partition after some byte offset. Both files and/or partition names can be equal. Values can be empty (like `part;file;;` or `;;part;file`) if OTA1/2 images are not present in this file.
|
||||
|
||||
When using two different firmware binaries, they need to have the same `offset` and be of the same size.
|
||||
|
||||
`inputs` parameter can be repeated in order to embed multiple files in the UF2. For example:
|
||||
```
|
||||
bootloader:boot.bin ota1:xip1.bin:ota2:xip2.bin config:config1.bin:config:config2.bin
|
||||
```bash
|
||||
"bootloader;boot.bin" "ota1;xip1.bin;ota2;xip2.bin" "config;config1.bin;config;config2.bin"
|
||||
```
|
||||
will:
|
||||
- flash the bootloader in both OTA schemes
|
||||
|
||||
@@ -129,11 +129,11 @@ class Input:
|
||||
ota2_file: str = None
|
||||
|
||||
def __init__(self, input: str) -> None:
|
||||
input = input.split(":")
|
||||
input = input.split(";")
|
||||
n = len(input)
|
||||
if n not in [2, 4]:
|
||||
raise ValueError(
|
||||
"Incorrect input format - should be part+offs:file[:part+offs:file]"
|
||||
"Incorrect input format - should be part+offs;file[;part+offs;file]"
|
||||
)
|
||||
# just spread the same image twice for single-OTA scheme
|
||||
if n == 2:
|
||||
|
||||
@@ -60,7 +60,7 @@ class UF2:
|
||||
while True:
|
||||
data = self.f.read(512)
|
||||
if len(data) not in [0, 512]:
|
||||
print(f"Block size invalid ({len(data)=})")
|
||||
print(f"Block size invalid ({len(data)})")
|
||||
return False
|
||||
if not len(data):
|
||||
break
|
||||
@@ -69,7 +69,7 @@ class UF2:
|
||||
return False
|
||||
|
||||
if self.family != Family.INVALID and self.family != block.family:
|
||||
print(f"Mismatched family ({self.family=} != {block.family=})")
|
||||
print(f"Mismatched family ({self.family} != {block.family})")
|
||||
return False
|
||||
self.family = block.family
|
||||
|
||||
|
||||
@@ -68,19 +68,19 @@ class Block:
|
||||
def decode(self, data: bytes) -> bool:
|
||||
# check block size
|
||||
if len(data) != 512:
|
||||
print(f"Invalid block size ({len(data)=})")
|
||||
print(f"Invalid block size ({len(data)})")
|
||||
return False
|
||||
# check Magic 1
|
||||
if letoint(data[0:4]) != 0x0A324655:
|
||||
print(f"Invalid Magic 1 ({data[0:4]=})")
|
||||
print(f"Invalid Magic 1 ({data[0:4]})")
|
||||
return False
|
||||
# check Magic 2
|
||||
if letoint(data[4:8]) != 0x9E5D5157:
|
||||
print(f"Invalid Magic 2 ({data[4:8]=})")
|
||||
print(f"Invalid Magic 2 ({data[4:8]})")
|
||||
return False
|
||||
# check Magic 3
|
||||
if letoint(data[508:512]) != 0x0AB16F30:
|
||||
print(f"Invalid Magic 13({data[508:512]=})")
|
||||
print(f"Invalid Magic 13({data[508:512]})")
|
||||
return False
|
||||
|
||||
self.flags.decode(letoint(data[8:12]))
|
||||
@@ -134,4 +134,4 @@ class Block:
|
||||
file_size = self.file_size
|
||||
family = self.family.name
|
||||
tags = [(k.name, v) for k, v in self.tags.items()]
|
||||
return f"Block[{block_seq}/{block_count}]({flags=}, {address=}, {length=}, {file_size=}, {family=}, {tags=})"
|
||||
return f"Block[{block_seq}/{block_count}](flags={flags}, address={address}, length={length}, file_size={file_size}, family={family}, tags={tags})"
|
||||
|
||||
@@ -61,9 +61,12 @@ def cli():
|
||||
uf2.put_str(Tag.LT_VERSION, args.version)
|
||||
|
||||
if args.fw:
|
||||
(fw_name, fw_ver) = args.fw.split(":")
|
||||
uf2.put_str(Tag.FIRMWARE, fw_name)
|
||||
uf2.put_str(Tag.VERSION, fw_ver)
|
||||
if ":" in args.fw:
|
||||
(fw_name, fw_ver) = args.fw.split(":")
|
||||
uf2.put_str(Tag.FIRMWARE, fw_name)
|
||||
uf2.put_str(Tag.VERSION, fw_ver)
|
||||
else:
|
||||
uf2.put_str(Tag.FIRMWARE, args.fw)
|
||||
|
||||
uf2.put_int8(Tag.OTA_VERSION, 1)
|
||||
uf2.put_str(Tag.DEVICE, "LibreTuya")
|
||||
|
||||
Reference in New Issue
Block a user