21
21
"""Flash firmware to STM32 microcontrollers over a serial connection."""
22
22
23
23
24
- import os
25
- import sys
26
- import copy
27
24
import argparse
28
25
import atexit
26
+ import copy
27
+ import os
28
+ import sys
29
+
30
+ try :
31
+ from progress .bar import ChargingBar as progress_bar
32
+ except ImportError :
33
+ progress_bar = None
29
34
30
35
from stm32loader import __version__ , bootloader
31
36
from stm32loader .uart import SerialConnection
32
37
33
38
DEFAULT_VERBOSITY = 5
34
39
35
40
36
- class HelpFormatter (
37
- argparse .RawDescriptionHelpFormatter ,
38
- argparse .ArgumentDefaultsHelpFormatter
39
- ):
41
+ class HelpFormatter (argparse .RawDescriptionHelpFormatter , argparse .ArgumentDefaultsHelpFormatter ):
42
+ """Custom help formatter -- don't print confusing default values."""
43
+
40
44
def _get_help_string (self , action ):
41
45
action = copy .copy (action )
42
46
# Don't show "(default: None)" for arguments without defaults,
@@ -54,8 +58,10 @@ def tweak_action(action):
54
58
if action .dest == "port" :
55
59
action .required = True
56
60
return action
61
+
57
62
return super ()._format_actions_usage (map (tweak_action , actions ), groups )
58
63
64
+
59
65
class Stm32Loader :
60
66
"""Main application: parse arguments and handle commands."""
61
67
@@ -75,97 +81,139 @@ def debug(self, level, message):
75
81
def parse_arguments (self , arguments ):
76
82
"""Parse the list of command-line arguments."""
77
83
parser = argparse .ArgumentParser (
78
- epilog = '\n ' .join ([
79
- 'examples:' ,
80
- ' %(prog)s -p COM7 -f F1' ,
81
- ' %(prog)s -e -w -v example/main.bin' ,
82
- ]),
83
- formatter_class = HelpFormatter )
84
+ epilog = "\n " .join (
85
+ [
86
+ "examples:" ,
87
+ " %(prog)s -p COM7 -f F1" ,
88
+ " %(prog)s -e -w -v example/main.bin" ,
89
+ ]
90
+ ),
91
+ formatter_class = HelpFormatter ,
92
+ )
84
93
85
94
data_file_arg = parser .add_argument (
86
- "data_file" , metavar = "FILE.BIN" , type = str , nargs = "?" ,
87
- help = "file to read from or store to flash" )
95
+ "data_file" ,
96
+ metavar = "FILE.BIN" ,
97
+ type = str ,
98
+ nargs = "?" ,
99
+ help = "file to read from or store to flash" ,
100
+ )
88
101
89
102
parser .add_argument (
90
- "-e" , "--erase" , action = "store_true" ,
91
- help = "erase (note: this is required on previously written memory)" )
103
+ "-e" ,
104
+ "--erase" ,
105
+ action = "store_true" ,
106
+ help = "erase (note: this is required on previously written memory)" ,
107
+ )
92
108
93
109
parser .add_argument (
94
- "-u" , "--unprotect" , action = "store_true" ,
95
- help = "unprotect in case erase fails" )
110
+ "-u" , "--unprotect" , action = "store_true" , help = "unprotect in case erase fails"
111
+ )
96
112
97
113
parser .add_argument (
98
- "-w" , "--write" , action = "store_true" ,
99
- help = "write file content to flash" )
114
+ "-w" , "--write" , action = "store_true" , help = "write file content to flash"
115
+ )
100
116
101
117
parser .add_argument (
102
- "-v" , "--verify" , action = "store_true" ,
103
- help = "verify flash content versus local file (recommended)" )
118
+ "-v" ,
119
+ "--verify" ,
120
+ action = "store_true" ,
121
+ help = "verify flash content versus local file (recommended)" ,
122
+ )
104
123
105
124
parser .add_argument (
106
- "-r" , "--read" , action = "store_true" ,
107
- help = "read from flash and store in local file" )
125
+ "-r" , "--read" , action = "store_true" , help = "read from flash and store in local file"
126
+ )
108
127
109
128
length_arg = parser .add_argument (
110
- "-l" , "--length" , action = "store" , type = int ,
111
- help = "length of read" )
129
+ "-l" , "--length" , action = "store" , type = int , help = "length of read"
130
+ )
112
131
113
132
default_port = os .environ .get ("STM32LOADER_SERIAL_PORT" )
114
133
port_arg = parser .add_argument (
115
- "-p" , "--port" , action = "store" , type = str , # morally required=True
134
+ "-p" ,
135
+ "--port" ,
136
+ action = "store" ,
137
+ type = str , # morally required=True
116
138
default = default_port ,
117
- help = "serial port" +
118
- ("" if default_port else " (default: $STM32LOADER_SERIAL_PORT)" ))
139
+ help = (
140
+ "serial port" + ("" if default_port else " (default: $STM32LOADER_SERIAL_PORT)" )
141
+ ),
142
+ )
119
143
120
144
parser .add_argument (
121
- "-b" , "--baud" , action = "store" , type = int , default = 115200 ,
122
- help = "baudrate" )
145
+ "-b" , "--baud" , action = "store" , type = int , default = 115200 , help = "baudrate"
146
+ )
123
147
124
148
address_arg = parser .add_argument (
125
- "-a" , "--address" , action = "store" , type = int , default = 0x08000000 ,
126
- help = "target address" )
149
+ "-a" , "--address" , action = "store" , type = int , default = 0x08000000 , help = "target address"
150
+ )
127
151
128
152
parser .add_argument (
129
- "-g" , "--go-address" , action = "store" , type = int , metavar = "ADDRESS" ,
130
- help = "start executing from address (0x08000000, usually)" )
153
+ "-g" ,
154
+ "--go-address" ,
155
+ action = "store" ,
156
+ type = int ,
157
+ metavar = "ADDRESS" ,
158
+ help = "start executing from address (0x08000000, usually)" ,
159
+ )
131
160
132
161
default_family = os .environ .get ("STM32LOADER_FAMILY" )
133
162
parser .add_argument (
134
- "-f" , "--family" , action = "store" , type = str ,
163
+ "-f" ,
164
+ "--family" ,
165
+ action = "store" ,
166
+ type = str ,
135
167
default = default_family ,
136
- help = "device family to read out device UID and flash size; "
137
- "e.g F1 for STM32F1xx" +
138
- ("" if default_family else " (default: $STM32LOADER_FAMILY)" ))
168
+ help = (
169
+ "device family to read out device UID and flash size; "
170
+ "e.g F1 for STM32F1xx"
171
+ + ("" if default_family else " (default: $STM32LOADER_FAMILY)" )
172
+ ),
173
+ )
139
174
140
175
parser .add_argument (
141
- "-V" , "--verbose" , dest = "verbosity" , action = "store_const" , const = 10 ,
176
+ "-V" ,
177
+ "--verbose" ,
178
+ dest = "verbosity" ,
179
+ action = "store_const" ,
180
+ const = 10 ,
142
181
default = DEFAULT_VERBOSITY ,
143
- help = "verbose mode" )
182
+ help = "verbose mode" ,
183
+ )
144
184
145
185
parser .add_argument (
146
- "-q" , "--quiet" , dest = "verbosity" , action = "store_const" , const = 0 ,
147
- help = "quiet mode" )
186
+ "-q" , "--quiet" , dest = "verbosity" , action = "store_const" , const = 0 , help = "quiet mode"
187
+ )
148
188
149
189
parser .add_argument (
150
- "-s" , "--swap-rts-dtr" , action = "store_true" ,
151
- help = "swap RTS and DTR: use RTS for reset and DTR for boot0" )
190
+ "-s" ,
191
+ "--swap-rts-dtr" ,
192
+ action = "store_true" ,
193
+ help = "swap RTS and DTR: use RTS for reset and DTR for boot0" ,
194
+ )
152
195
153
196
parser .add_argument (
154
- "-R" , "--reset-active-high" , action = "store_true" ,
155
- help = "make reset active high" )
197
+ "-R" , "--reset-active-high" , action = "store_true" , help = "make reset active high"
198
+ )
156
199
157
200
parser .add_argument (
158
- "-B" , "--boot0-active-low" , action = "store_true" ,
159
- help = "make boot0 active low" )
201
+ "-B" , "--boot0-active-low" , action = "store_true" , help = "make boot0 active low"
202
+ )
160
203
161
204
parser .add_argument (
162
- "-n" , "--no-progress" , action = "store_true" ,
163
- help = "don't show progress bar" )
205
+ "-n" , "--no-progress" , action = "store_true" , help = "don't show progress bar"
206
+ )
164
207
165
208
parser .add_argument (
166
- "-P" , "--parity" , action = "store" , type = str , default = "even" ,
209
+ "-P" ,
210
+ "--parity" ,
211
+ action = "store" ,
212
+ type = str ,
213
+ default = "even" ,
167
214
choices = self .PARITY .keys (),
168
- help = 'parity: "even" for STM32, "none" for BlueNRG' )
215
+ help = 'parity: "even" for STM32, "none" for BlueNRG' ,
216
+ )
169
217
170
218
parser .add_argument ("--version" , action = "version" , version = __version__ )
171
219
@@ -186,11 +234,13 @@ def parse_arguments(self, arguments):
186
234
187
235
if not self .configuration .port :
188
236
port_arg .required = True
189
- atexit .register (lambda : print (
190
- "{}: note: you can also set the environment "
191
- "variable STM32LOADER_SERIAL_PORT" .format (parser .prog ),
192
- file = sys .stderr ,
193
- ))
237
+ atexit .register (
238
+ lambda : print (
239
+ "{}: note: you can also set the environment "
240
+ "variable STM32LOADER_SERIAL_PORT" .format (parser .prog ),
241
+ file = sys .stderr ,
242
+ )
243
+ )
194
244
195
245
if self .configuration .read or self .configuration .write or self .configuration .verify :
196
246
data_file_arg .nargs = None
@@ -237,9 +287,7 @@ def connect(self):
237
287
show_progress = self ._get_progress_bar (self .configuration .no_progress )
238
288
239
289
self .stm32 = bootloader .Stm32Bootloader (
240
- serial_connection ,
241
- verbosity = self .configuration .verbosity ,
242
- show_progress = show_progress
290
+ serial_connection , verbosity = self .configuration .verbosity , show_progress = show_progress
243
291
)
244
292
245
293
try :
@@ -284,9 +332,7 @@ def perform_commands(self):
284
332
if self .configuration .write :
285
333
self .stm32 .write_memory_data (self .configuration .address , binary_data )
286
334
if self .configuration .verify :
287
- read_data = self .stm32 .read_memory_data (
288
- self .configuration .address , len (binary_data )
289
- )
335
+ read_data = self .stm32 .read_memory_data (self .configuration .address , len (binary_data ))
290
336
try :
291
337
bootloader .Stm32Bootloader .verify_data (read_data , binary_data )
292
338
print ("Verification OK" )
@@ -331,7 +377,8 @@ def read_device_uid(self):
331
377
flash_size , device_uid = self .stm32 .get_flash_size_and_uid_f4 ()
332
378
except bootloader .CommandError as e :
333
379
self .debug (
334
- 0 , "Something was wrong with reading chip family data: " + str (e ),
380
+ 0 ,
381
+ "Something was wrong with reading chip family data: " + str (e ),
335
382
)
336
383
return
337
384
@@ -341,22 +388,10 @@ def read_device_uid(self):
341
388
342
389
@staticmethod
343
390
def _get_progress_bar (no_progress = False ):
344
- if no_progress :
345
- return None
346
- desired_progress_bar = None
347
- try :
348
- from progress .bar import ( # pylint: disable=import-outside-toplevel
349
- ChargingBar as desired_progress_bar ,
350
- )
351
- except ImportError :
352
- # progress module is a package dependency,
353
- # but not strictly required
354
- pass
355
-
356
- if not desired_progress_bar :
391
+ if no_progress or not progress_bar :
357
392
return None
358
393
359
- return bootloader .ShowProgress (desired_progress_bar )
394
+ return bootloader .ShowProgress (progress_bar )
360
395
361
396
362
397
def main (* args , ** kwargs ):
0 commit comments