17
17
//! The Pico must first be placed into BOOTSEL mode so that the test runner can
18
18
//! load a program.
19
19
use anyhow:: { anyhow, Context , Result } ;
20
- use std:: future:: Future ;
20
+ use bytemuck:: { Pod , Zeroable } ;
21
+ use std:: { future:: Future , mem:: size_of} ;
21
22
use tokio:: {
22
23
io:: { AsyncWriteExt , BufStream } ,
23
24
task:: spawn_blocking,
@@ -243,7 +244,7 @@ async fn program_and_run_by_picoboot(exe: &std::path::Path) -> Result<()> {
243
244
244
245
let hdr = PicobootCmd :: new_write ( * region_addr as u32 , region_data. len ( ) as u32 ) ;
245
246
let ( result, device_handle_tmp) =
246
- write_bulk_all ( device_handle, out_endpoint_i, hdr . as_bytes ( ) ) . await ;
247
+ write_bulk_all ( device_handle, out_endpoint_i, bytemuck :: bytes_of ( & hdr ) ) . await ;
247
248
device_handle = device_handle_tmp;
248
249
let num_bytes_written = result. with_context ( || "Failed to issue a 'write' command." ) ?;
249
250
if num_bytes_written != 32 {
@@ -274,7 +275,7 @@ async fn program_and_run_by_picoboot(exe: &std::path::Path) -> Result<()> {
274
275
) ;
275
276
276
277
let hdr = PicobootCmd :: new_reboot ( loadable_code. entry as u32 , 0x2004_2000 , 100 ) ;
277
- let ( result, _) = write_bulk_all ( device_handle, out_endpoint_i, hdr . as_bytes ( ) ) . await ;
278
+ let ( result, _) = write_bulk_all ( device_handle, out_endpoint_i, bytemuck :: bytes_of ( & hdr ) ) . await ;
278
279
let num_bytes_written = result. with_context ( || "Failed to issue a 'reboot' command." ) ?;
279
280
if num_bytes_written != 32 {
280
281
anyhow:: bail!( "Short write ({} < 32)" , num_bytes_written) ;
@@ -465,41 +466,39 @@ fn open_picoboot() -> Result<PicobootInterface> {
465
466
}
466
467
467
468
#[ repr( C ) ]
468
- #[ derive( Clone , Copy ) ]
469
+ #[ derive( Clone , Copy , Pod , Zeroable ) ]
469
470
struct PicobootCmd {
470
471
_magic : u32 ,
471
472
_token : u32 ,
472
473
_cmd_id : u8 ,
473
474
_cmd_size : u8 ,
474
475
_reserved : u16 ,
475
476
_transfer_length : u32 ,
476
- _args : PicobootCmdArgs ,
477
+ /// One of `PicobootCmdArgs*`
478
+ _args : [ u8 ; 16 ] ,
477
479
}
478
480
479
481
#[ repr( C ) ]
480
- #[ derive( Clone , Copy ) ]
481
- union PicobootCmdArgs {
482
- _reboot : PicobootCmdArgsReboot ,
483
- _addr_size : PicobootCmdArgsAddrSize ,
484
- }
485
-
486
- #[ repr( C ) ]
487
- #[ derive( Clone , Copy ) ]
482
+ #[ derive( Clone , Copy , Pod , Zeroable ) ]
488
483
struct PicobootCmdArgsAddrSize {
489
484
_addr : u32 ,
490
485
_size : u32 ,
491
486
_pad : [ u8 ; 8 ] ,
492
487
}
493
488
494
489
#[ repr( C ) ]
495
- #[ derive( Clone , Copy ) ]
490
+ #[ derive( Clone , Copy , Pod , Zeroable ) ]
496
491
struct PicobootCmdArgsReboot {
497
492
_pc : u32 ,
498
493
_sp : u32 ,
499
494
_delay_ms : u32 ,
500
495
_pad : [ u8 ; 4 ] ,
501
496
}
502
497
498
+ const _: ( ) = assert ! ( size_of:: <PicobootCmd >( ) == 32 ) ;
499
+ const _: ( ) = assert ! ( size_of:: <PicobootCmdArgsAddrSize >( ) == 16 ) ;
500
+ const _: ( ) = assert ! ( size_of:: <PicobootCmdArgsReboot >( ) == 16 ) ;
501
+
503
502
impl PicobootCmd {
504
503
/// Writes a contiguous memory range of memory (Flash or RAM) on the RP2040.
505
504
fn new_write ( addr : u32 , size : u32 ) -> Self {
@@ -510,13 +509,11 @@ impl PicobootCmd {
510
509
_cmd_size : 0x08 ,
511
510
_reserved : 0 ,
512
511
_transfer_length : size,
513
- _args : PicobootCmdArgs {
514
- _addr_size : PicobootCmdArgsAddrSize {
515
- _addr : addr,
516
- _size : size,
517
- _pad : [ 0 ; _] ,
518
- } ,
519
- } ,
512
+ _args : bytemuck:: cast ( PicobootCmdArgsAddrSize {
513
+ _addr : addr,
514
+ _size : size,
515
+ _pad : [ 0 ; _] ,
516
+ } ) ,
520
517
}
521
518
}
522
519
@@ -529,14 +526,12 @@ impl PicobootCmd {
529
526
_cmd_size : 0x0c ,
530
527
_reserved : 0 ,
531
528
_transfer_length : 0 ,
532
- _args : PicobootCmdArgs {
533
- _reboot : PicobootCmdArgsReboot {
534
- _pc : pc,
535
- _sp : sp,
536
- _delay_ms : delay_ms,
537
- _pad : [ 0 ; _] ,
538
- } ,
539
- } ,
529
+ _args : bytemuck:: cast ( PicobootCmdArgsReboot {
530
+ _pc : pc,
531
+ _sp : sp,
532
+ _delay_ms : delay_ms,
533
+ _pad : [ 0 ; _] ,
534
+ } ) ,
540
535
}
541
536
}
542
537
@@ -549,9 +544,4 @@ impl PicobootCmd {
549
544
) ;
550
545
value
551
546
}
552
-
553
- fn as_bytes ( & self ) -> & [ u8 ; 32 ] {
554
- assert_eq ! ( std:: mem:: size_of:: <Self >( ) , 32 ) ;
555
- unsafe { & * <* const _ >:: cast ( self ) }
556
- }
557
547
}
0 commit comments