33# otatool is used to perform ota-level operations - flashing ota partition
44# erasing ota partition and switching ota partition
55#
6- # SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
6+ # SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
77# SPDX-License-Identifier: Apache-2.0
8- from __future__ import division , print_function
9-
108import argparse
119import binascii
1210import collections
1614import tempfile
1715
1816try :
19- from parttool import PARTITION_TABLE_OFFSET , PartitionName , PartitionType , ParttoolTarget
17+ from parttool import PARTITION_TABLE_OFFSET
18+ from parttool import PartitionName
19+ from parttool import PartitionType
20+ from parttool import ParttoolTarget
2021except ImportError :
2122 COMPONENTS_PATH = os .path .expandvars (os .path .join ('$IDF_PATH' , 'components' ))
2223 PARTTOOL_DIR = os .path .join (COMPONENTS_PATH , 'partition_table' )
2324 sys .path .append (PARTTOOL_DIR )
24- from parttool import PARTITION_TABLE_OFFSET , PartitionName , PartitionType , ParttoolTarget
25+ from parttool import PARTITION_TABLE_OFFSET
26+ from parttool import PartitionName
27+ from parttool import PartitionType
28+ from parttool import ParttoolTarget
2529
2630__version__ = '2.0'
2731
@@ -35,15 +39,31 @@ def status(msg):
3539 print (msg )
3640
3741
38- class OtatoolTarget ():
39-
42+ class OtatoolTarget :
4043 OTADATA_PARTITION = PartitionType ('data' , 'ota' )
4144
42- def __init__ (self , port = None , baud = None , partition_table_offset = PARTITION_TABLE_OFFSET , partition_table_file = None ,
43- spi_flash_sec_size = SPI_FLASH_SEC_SIZE , esptool_args = [], esptool_write_args = [],
44- esptool_read_args = [], esptool_erase_args = []):
45- self .target = ParttoolTarget (port , baud , partition_table_offset , partition_table_file , esptool_args ,
46- esptool_write_args , esptool_read_args , esptool_erase_args )
45+ def __init__ (
46+ self ,
47+ port = None ,
48+ baud = None ,
49+ partition_table_offset = PARTITION_TABLE_OFFSET ,
50+ partition_table_file = None ,
51+ spi_flash_sec_size = SPI_FLASH_SEC_SIZE ,
52+ esptool_args = [],
53+ esptool_write_args = [],
54+ esptool_read_args = [],
55+ esptool_erase_args = [],
56+ ):
57+ self .target = ParttoolTarget (
58+ port ,
59+ baud ,
60+ partition_table_offset ,
61+ partition_table_file ,
62+ esptool_args ,
63+ esptool_write_args ,
64+ esptool_read_args ,
65+ esptool_erase_args ,
66+ )
4767 self .spi_flash_sec_size = spi_flash_sec_size
4868
4969 temp_file = tempfile .NamedTemporaryFile (delete = False )
@@ -71,8 +91,8 @@ def _get_otadata_info(self):
7191 for i in range (2 ):
7292 start = i * (self .spi_flash_sec_size >> 1 )
7393
74- seq = bytearray (self .otadata [start : start + 4 ])
75- crc = bytearray (self .otadata [start + 28 : start + 32 ])
94+ seq = bytearray (self .otadata [start : start + 4 ])
95+ crc = bytearray (self .otadata [start + 28 : start + 32 ])
7696
7797 seq = struct .unpack ('I' , seq )
7898 crc = struct .unpack ('I' , crc )
@@ -118,7 +138,9 @@ def is_otadata_info_valid(status):
118138
119139 try :
120140 if isinstance (ota_id , int ):
121- ota_partition_next = filter (lambda p : p .subtype - gen .MIN_PARTITION_SUBTYPE_APP_OTA == ota_id , ota_partitions )
141+ ota_partition_next = filter (
142+ lambda p : p .subtype - gen .MIN_PARTITION_SUBTYPE_APP_OTA == ota_id , ota_partitions
143+ )
122144 else :
123145 ota_partition_next = filter (lambda p : p .name == ota_id , ota_partitions )
124146
@@ -192,8 +214,8 @@ def is_otadata_info_valid(status):
192214 def read_ota_partition (self , ota_id , output ):
193215 self .target .read_partition (self ._get_partition_id_from_ota_id (ota_id ), output )
194216
195- def write_ota_partition (self , ota_id , input ):
196- self .target .write_partition (self ._get_partition_id_from_ota_id (ota_id ), input )
217+ def write_ota_partition (self , ota_id , input_file ):
218+ self .target .write_partition (self ._get_partition_id_from_ota_id (ota_id ), input_file )
197219
198220 def erase_ota_partition (self , ota_id ):
199221 self .target .erase_partition (self ._get_partition_id_from_ota_id (ota_id ))
@@ -205,8 +227,10 @@ def _read_otadata(target):
205227 otadata_info = target ._get_otadata_info ()
206228
207229 print (' {:8s} \t {:8s} | \t {:8s} \t {:8s}' .format ('OTA_SEQ' , 'CRC' , 'OTA_SEQ' , 'CRC' ))
208- print ('Firmware: 0x{:08x} \t 0x{:08x} | \t 0x{:08x} \t 0x{:08x}' .format (otadata_info [0 ].seq , otadata_info [0 ].crc ,
209- otadata_info [1 ].seq , otadata_info [1 ].crc ))
230+ print (
231+ f'Firmware: { otadata_info [0 ].seq :#08x} \t { otadata_info [0 ].crc :#08x} | '
232+ f'\t { otadata_info [1 ].seq :#08x} \t { otadata_info [1 ].crc :#08x} '
233+ )
210234
211235
212236def _erase_otadata (target ):
@@ -220,12 +244,12 @@ def _switch_ota_partition(target, ota_id):
220244
221245def _read_ota_partition (target , ota_id , output ):
222246 target .read_ota_partition (ota_id , output )
223- status ('Read ota partition contents to file {}' . format ( output ) )
247+ status (f 'Read ota partition contents to file { output } ' )
224248
225249
226- def _write_ota_partition (target , ota_id , input ):
227- target .write_ota_partition (ota_id , input )
228- status ('Written contents of file {} to ota partition' . format ( input ) )
250+ def _write_ota_partition (target , ota_id , input_file ):
251+ target .write_ota_partition (ota_id , input_file )
252+ status (f 'Written contents of file { input_file } to ota partition' )
229253
230254
231255def _erase_ota_partition (target , ota_id ):
@@ -240,20 +264,28 @@ def main():
240264
241265 parser .add_argument ('--quiet' , '-q' , help = 'suppress stderr messages' , action = 'store_true' )
242266 parser .add_argument ('--esptool-args' , help = 'additional main arguments for esptool' , nargs = '+' )
243- parser .add_argument ('--esptool-write-args' , help = 'additional subcommand arguments for esptool write_flash' , nargs = '+' )
244- parser .add_argument ('--esptool-read-args' , help = 'additional subcommand arguments for esptool read_flash' , nargs = '+' )
245- parser .add_argument ('--esptool-erase-args' , help = 'additional subcommand arguments for esptool erase_region' , nargs = '+' )
267+ parser .add_argument (
268+ '--esptool-write-args' , help = 'additional subcommand arguments for esptool write-flash' , nargs = '+'
269+ )
270+ parser .add_argument ('--esptool-read-args' , help = 'additional subcommand arguments for esptool read-flash' , nargs = '+' )
271+ parser .add_argument (
272+ '--esptool-erase-args' , help = 'additional subcommand arguments for esptool erase-region' , nargs = '+'
273+ )
246274
247275 # There are two possible sources for the partition table: a device attached to the host
248276 # or a partition table CSV/binary file. These sources are mutually exclusive.
249277 parser .add_argument ('--port' , '-p' , help = 'port where the device to read the partition table from is attached' )
250278
251279 parser .add_argument ('--baud' , '-b' , help = 'baudrate to use' , type = int )
252280
253- parser .add_argument ('--partition-table-offset' , '-o' , help = 'offset to read the partition table from' , type = str )
281+ parser .add_argument ('--partition-table-offset' , '-o' , help = 'offset to read the partition table from' , type = str )
254282
255- parser .add_argument ('--partition-table-file' , '-f' , help = 'file (CSV/binary) to read the partition table from; \
256- overrides device attached to specified port as the partition table source when defined' )
283+ parser .add_argument (
284+ '--partition-table-file' ,
285+ '-f' ,
286+ help = 'file (CSV/binary) to read the partition table from; '
287+ 'overrides device attached to specified port as the partition table source when defined' ,
288+ )
257289
258290 subparsers = parser .add_subparsers (dest = 'operation' , help = 'run otatool -h for additional help' )
259291
@@ -269,15 +301,25 @@ def main():
269301 slot_or_name_parser_args .add_argument ('--slot' , help = 'slot number of the ota partition' , type = int )
270302 slot_or_name_parser_args .add_argument ('--name' , help = 'name of the ota partition' )
271303
272- subparsers .add_parser ('switch_ota_partition' , help = 'switch otadata partition' , parents = [slot_or_name_parser , spi_flash_sec_size ])
304+ subparsers .add_parser (
305+ 'switch_ota_partition' , help = 'switch otadata partition' , parents = [slot_or_name_parser , spi_flash_sec_size ]
306+ )
273307
274- read_ota_partition_subparser = subparsers .add_parser ('read_ota_partition' , help = 'read contents of an ota partition' , parents = [slot_or_name_parser ])
275- read_ota_partition_subparser .add_argument ('--output' , help = 'file to write the contents of the ota partition to' , required = True )
308+ read_ota_partition_subparser = subparsers .add_parser (
309+ 'read_ota_partition' , help = 'read contents of an ota partition' , parents = [slot_or_name_parser ]
310+ )
311+ read_ota_partition_subparser .add_argument (
312+ '--output' , help = 'file to write the contents of the ota partition to' , required = True
313+ )
276314
277- write_ota_partition_subparser = subparsers .add_parser ('write_ota_partition' , help = 'write contents to an ota partition' , parents = [slot_or_name_parser ])
315+ write_ota_partition_subparser = subparsers .add_parser (
316+ 'write_ota_partition' , help = 'write contents to an ota partition' , parents = [slot_or_name_parser ]
317+ )
278318 write_ota_partition_subparser .add_argument ('--input' , help = 'file whose contents to write to the ota partition' )
279319
280- subparsers .add_parser ('erase_ota_partition' , help = 'erase contents of an ota partition' , parents = [slot_or_name_parser ])
320+ subparsers .add_parser (
321+ 'erase_ota_partition' , help = 'erase contents of an ota partition' , parents = [slot_or_name_parser ]
322+ )
281323
282324 args = parser .parse_args ()
283325
@@ -324,7 +366,7 @@ def main():
324366 target = OtatoolTarget (** target_args )
325367
326368 # Create the operation table and execute the operation
327- common_args = {'target' :target }
369+ common_args = {'target' : target }
328370
329371 ota_id = []
330372
@@ -338,18 +380,18 @@ def main():
338380 pass
339381
340382 otatool_ops = {
341- 'read_otadata' :(_read_otadata , []),
342- 'erase_otadata' :(_erase_otadata , []),
343- 'switch_ota_partition' :(_switch_ota_partition , ota_id ),
344- 'read_ota_partition' :(_read_ota_partition , ['output' ] + ota_id ),
345- 'write_ota_partition' :(_write_ota_partition , ['input' ] + ota_id ),
346- 'erase_ota_partition' :(_erase_ota_partition , ota_id )
383+ 'read_otadata' : (_read_otadata , []),
384+ 'erase_otadata' : (_erase_otadata , []),
385+ 'switch_ota_partition' : (_switch_ota_partition , ota_id ),
386+ 'read_ota_partition' : (_read_ota_partition , ['output' ] + ota_id ),
387+ 'write_ota_partition' : (_write_ota_partition , ['input' ] + ota_id ),
388+ 'erase_ota_partition' : (_erase_ota_partition , ota_id ),
347389 }
348390
349391 (op , op_args ) = otatool_ops [args .operation ]
350392
351393 for op_arg in op_args :
352- common_args .update ({op_arg :vars (args )[op_arg ]})
394+ common_args .update ({op_arg : vars (args )[op_arg ]})
353395
354396 try :
355397 common_args ['ota_id' ] = common_args .pop ('name' )
0 commit comments