48
48
//! This crate is supplied as is without any warranty. Use at your own risk.
49
49
50
50
mod display_handler;
51
+ mod output;
51
52
mod parse;
52
53
53
54
use anyhow:: Context ;
@@ -193,13 +194,21 @@ fn init_display_handler(verbosity: log::LevelFilter) -> std::sync::Arc<Mutex<Dis
193
194
std:: sync:: Arc :: new ( Mutex :: new ( DisplayHandler :: new ( logger) ) )
194
195
}
195
196
196
- /// Main entry point of the CLI
197
- fn main ( ) -> Result < ( ) , anyhow:: Error > {
197
+ fn main_inner ( ) -> Result < crate :: output:: Output , anyhow:: Error > {
198
198
// Parse command line arguments
199
199
let options = parse:: options ( ) . run ( ) ;
200
200
201
+ let mut cli_output =
202
+ output:: Output :: new ( std:: env:: args_os ( ) , & options. stm32_cube_programmer_dir ) ;
203
+
204
+ let verbosity = if options. quiet {
205
+ log:: LevelFilter :: Error
206
+ } else {
207
+ options. verbose
208
+ } ;
209
+
201
210
// Init api
202
- let display_handler = init_display_handler ( options . verbosity ) ;
211
+ let display_handler = init_display_handler ( verbosity) ;
203
212
let api = stm32cubeprogrammer:: CubeProgrammer :: builder ( )
204
213
. cube_programmer_dir ( & options. stm32_cube_programmer_dir )
205
214
. display_callback ( display_handler. clone ( ) )
@@ -211,6 +220,8 @@ fn main() -> Result<(), anyhow::Error> {
211
220
. list_available_probes ( )
212
221
. with_context ( || "Failed to list available probes" ) ?;
213
222
223
+ cli_output. add_probe_list ( & probes) ;
224
+
214
225
// Early return if the list_probes flag is set
215
226
if options. list_probes {
216
227
if probes. is_empty ( ) {
@@ -221,7 +232,7 @@ fn main() -> Result<(), anyhow::Error> {
221
232
}
222
233
}
223
234
224
- return Ok ( ( ) ) ;
235
+ return Ok ( cli_output ) ;
225
236
}
226
237
227
238
// Select a probe
@@ -231,54 +242,77 @@ fn main() -> Result<(), anyhow::Error> {
231
242
}
232
243
233
244
let selected_probe = select_probe ( & probes, & options. probe_serial ) ?;
245
+ cli_output. add_selected_probe ( selected_probe) ;
234
246
235
247
// Create a managed connection
236
248
let mut programmer_connection =
237
249
ProgrammerConnection :: new ( & api, selected_probe, options. protocol . into ( ) ) ;
238
250
239
- programmer_connection. connection ( ) . map_err ( |x| {
240
- error ! ( "Failed to connect to target: {:?}" , x) ;
241
- x
242
- } ) ?;
251
+ // Connect to the target and add target information to the output
252
+ cli_output. add_target_information (
253
+ programmer_connection
254
+ . connection ( )
255
+ . map_err ( |x| {
256
+ error ! ( "Failed to connect to target: {:?}" , x) ;
257
+ x
258
+ } ) ?
259
+ . general_information ( ) ,
260
+ ) ;
243
261
244
262
// Check if the command list includes a fus command and if so, check if the current target even supports FUS
245
263
// Early return if the target does not support FUS
246
264
if options
247
265
. target_commands
248
266
. iter ( )
249
267
. any ( |command| matches ! ( command, parse:: TargetCommand :: UpdateBleStack ( _) ) )
250
- && !programmer_connection. connection ( ) ?. fus_support ( )
268
+ && !programmer_connection
269
+ . connection ( ) ?
270
+ . general_information ( )
271
+ . fus_support
251
272
{
252
273
error ! ( "The target does not support FUS commands" ) ;
253
274
return Err ( anyhow:: anyhow!( "The target does not support FUS commands" ) ) ;
254
275
}
255
276
256
277
// Handle commands
257
278
for command in options. target_commands {
258
- match command {
279
+ let command_output = match command {
259
280
parse:: TargetCommand :: FlashBin ( bin_file_info) => {
281
+ log:: info!( "Flash binary file: {}" , bin_file_info) ;
282
+
260
283
display_handler
261
284
. lock ( )
262
285
. unwrap ( )
263
286
. set_message ( "Flashing binary file" ) ;
264
287
265
288
programmer_connection
266
289
. connection ( ) ?
267
- . download_bin_file ( bin_file_info. file , bin_file_info. address . 0 , false , true )
290
+ . download_bin_file ( & bin_file_info. file , bin_file_info. address . 0 , false , true )
268
291
. with_context ( || "Failed to flash binary file" ) ?;
292
+
293
+ output:: CommandOutput :: FlashBin {
294
+ file : bin_file_info. file ,
295
+ address : bin_file_info. address . 0 ,
296
+ }
269
297
}
270
298
parse:: TargetCommand :: FlashHex { file } => {
299
+ log:: info!( "Flash hex file: `{:?}`" , file) ;
300
+
271
301
display_handler
272
302
. lock ( )
273
303
. unwrap ( )
274
304
. set_message ( "Flashing hex file" ) ;
275
305
276
306
programmer_connection
277
307
. connection ( ) ?
278
- . download_hex_file ( file, false , true )
308
+ . download_hex_file ( & file, false , true )
279
309
. with_context ( || "Failed to flash hex file" ) ?;
310
+
311
+ output:: CommandOutput :: FlashHex { file }
280
312
}
281
313
parse:: TargetCommand :: UpdateBleStack ( ble_stack_info) => {
314
+ log:: info!( "Update BLE stack: {}" , ble_stack_info) ;
315
+
282
316
display_handler
283
317
. lock ( )
284
318
. unwrap ( )
@@ -305,7 +339,7 @@ fn main() -> Result<(), anyhow::Error> {
305
339
if flash {
306
340
fus_programmer
307
341
. upgrade_wireless_stack (
308
- ble_stack_info. file ,
342
+ & ble_stack_info. file ,
309
343
ble_stack_info. address . 0 ,
310
344
false ,
311
345
true ,
@@ -317,19 +351,53 @@ fn main() -> Result<(), anyhow::Error> {
317
351
. start_wireless_stack ( )
318
352
. with_context ( || "Failed to start BLE stack" ) ?;
319
353
}
354
+
355
+ output:: CommandOutput :: UpdateBleStack {
356
+ file : ble_stack_info. file ,
357
+ address : ble_stack_info. address . 0 ,
358
+ }
359
+ }
360
+ parse:: TargetCommand :: BleStackInfo { compare } => {
361
+ display_handler
362
+ . lock ( )
363
+ . unwrap ( )
364
+ . set_message ( "Get BLE stack information" ) ;
365
+
366
+ let fus_programmer = programmer_connection. fus_connection ( ) ?;
367
+ let target_version = fus_programmer. fus_info ( ) . wireless_stack_version ;
368
+
369
+ log:: info!( "FUS info: {}" , fus_programmer. fus_info( ) ) ;
370
+
371
+ if let Some ( compare) = compare {
372
+ log:: info!( "Comparing BLE stack versions. Given version: {} ; Version on target: {} ; Stack up to date: {}" , compare, target_version, compare == target_version) ;
373
+ }
374
+
375
+ fus_programmer
376
+ . start_wireless_stack ( )
377
+ . with_context ( || "Failed to start BLE stack" ) ?;
378
+
379
+ output:: CommandOutput :: BleStackInfo ( fus_programmer. fus_info ( ) . clone ( ) )
320
380
}
321
381
parse:: TargetCommand :: Reset ( reset_mode) => {
382
+ log:: info!( "Resetting target: {:?}" , reset_mode) ;
383
+
322
384
display_handler
323
385
. lock ( )
324
386
. unwrap ( )
325
387
. set_message ( "Resetting target" ) ;
326
388
327
389
programmer_connection
328
390
. connection ( ) ?
329
- . reset_target ( reset_mode. into ( ) )
391
+ . reset_target ( reset_mode. clone ( ) . into ( ) )
330
392
. with_context ( || "Failed to reset target" ) ?;
393
+
394
+ output:: CommandOutput :: Reset {
395
+ reset_mode : reset_mode. into ( ) ,
396
+ }
331
397
}
332
398
parse:: TargetCommand :: MassErase => {
399
+ log:: info!( "Mass erase" ) ;
400
+
333
401
display_handler
334
402
. lock ( )
335
403
. unwrap ( )
@@ -339,8 +407,12 @@ fn main() -> Result<(), anyhow::Error> {
339
407
. connection ( ) ?
340
408
. mass_erase ( )
341
409
. with_context ( || "Failed to mass erase target" ) ?;
410
+
411
+ output:: CommandOutput :: MassErase
342
412
}
343
413
parse:: TargetCommand :: Protect => {
414
+ log:: info!( "Enable read protection" ) ;
415
+
344
416
display_handler
345
417
. lock ( )
346
418
. unwrap ( )
@@ -350,8 +422,12 @@ fn main() -> Result<(), anyhow::Error> {
350
422
. connection ( ) ?
351
423
. enable_read_out_protection ( )
352
424
. with_context ( || "Failed to enable read protection" ) ?;
425
+
426
+ output:: CommandOutput :: Protect
353
427
}
354
428
parse:: TargetCommand :: Unprotect => {
429
+ log:: info!( "Disable read protection" ) ;
430
+
355
431
display_handler
356
432
. lock ( )
357
433
. unwrap ( )
@@ -361,11 +437,22 @@ fn main() -> Result<(), anyhow::Error> {
361
437
. connection ( ) ?
362
438
. disable_read_out_protection ( )
363
439
. with_context ( || "Failed to disable read protection" ) ?;
440
+
441
+ output:: CommandOutput :: Unprotect
364
442
}
365
- }
443
+ } ;
366
444
445
+ cli_output. add_command_output ( command_output) ;
367
446
display_handler. lock ( ) . unwrap ( ) . set_finish ( ) ;
368
447
}
369
448
449
+ Ok ( cli_output)
450
+ }
451
+
452
+ /// Main entry point of the CLI
453
+ fn main ( ) -> Result < ( ) , anyhow:: Error > {
454
+ let output = main_inner ( ) ?;
455
+ println ! ( "{}" , serde_json:: to_string_pretty( & output) ?) ;
456
+
370
457
Ok ( ( ) )
371
458
}
0 commit comments