diff options
| author | Mathias <[email protected]> | 2022-09-26 06:53:40 +0200 |
|---|---|---|
| committer | Mathias <[email protected]> | 2022-09-26 06:53:40 +0200 |
| commit | b2a327a85884f822d011964bcd44b463b301467f (patch) | |
| tree | 692d65cfe08babc79240c8374d4f6fedc26ffb7a /embassy-boot/boot/src/lib.rs | |
| parent | 7f16b1cd23f53a429bf074e76254bcf592c0b9cf (diff) | |
Add get_state helpers to allow self-testing before calling mark_booted
Diffstat (limited to 'embassy-boot/boot/src/lib.rs')
| -rw-r--r-- | embassy-boot/boot/src/lib.rs | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs index 1c4d2d47f..6f22d08ea 100644 --- a/embassy-boot/boot/src/lib.rs +++ b/embassy-boot/boot/src/lib.rs | |||
| @@ -604,6 +604,21 @@ impl FirmwareUpdater { | |||
| 604 | self.dfu.len() | 604 | self.dfu.len() |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | /// Obtain the current state. | ||
| 608 | /// | ||
| 609 | /// This is useful to check if the bootloader has just done a swap, in order | ||
| 610 | /// to do verifications and self-tests of the new image before calling | ||
| 611 | /// `mark_booted`. | ||
| 612 | pub async fn get_state<F: AsyncNorFlash>(&mut self, flash: &mut F, aligned: &mut [u8]) -> Result<State, F::Error> { | ||
| 613 | flash.read(self.state.from as u32, aligned).await?; | ||
| 614 | |||
| 615 | if !aligned.iter().any(|&b| b != SWAP_MAGIC) { | ||
| 616 | Ok(State::Swap) | ||
| 617 | } else { | ||
| 618 | Ok(State::Boot) | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 607 | /// Mark to trigger firmware swap on next boot. | 622 | /// Mark to trigger firmware swap on next boot. |
| 608 | /// | 623 | /// |
| 609 | /// # Safety | 624 | /// # Safety |
| @@ -673,8 +688,8 @@ impl FirmwareUpdater { | |||
| 673 | self.dfu.from + offset + data.len() | 688 | self.dfu.from + offset + data.len() |
| 674 | ); | 689 | ); |
| 675 | 690 | ||
| 676 | FirmwareWriter(self) | 691 | FirmwareWriter(self.dfu) |
| 677 | .write_firmware(offset, data, flash, block_size) | 692 | .write_block(offset, data, flash, block_size) |
| 678 | .await?; | 693 | .await?; |
| 679 | 694 | ||
| 680 | Ok(()) | 695 | Ok(()) |
| @@ -690,13 +705,28 @@ impl FirmwareUpdater { | |||
| 690 | 705 | ||
| 691 | trace!("Erased from {} to {}", self.dfu.from, self.dfu.to); | 706 | trace!("Erased from {} to {}", self.dfu.from, self.dfu.to); |
| 692 | 707 | ||
| 693 | Ok(FirmwareWriter(self)) | 708 | Ok(FirmwareWriter(self.dfu)) |
| 694 | } | 709 | } |
| 695 | 710 | ||
| 696 | // | 711 | // |
| 697 | // Blocking API | 712 | // Blocking API |
| 698 | // | 713 | // |
| 699 | 714 | ||
| 715 | /// Obtain the current state. | ||
| 716 | /// | ||
| 717 | /// This is useful to check if the bootloader has just done a swap, in order | ||
| 718 | /// to do verifications and self-tests of the new image before calling | ||
| 719 | /// `mark_booted`. | ||
| 720 | pub fn get_state_blocking<F: NorFlash>(&mut self, flash: &mut F, aligned: &mut [u8]) -> Result<State, F::Error> { | ||
| 721 | flash.read(self.state.from as u32, aligned)?; | ||
| 722 | |||
| 723 | if !aligned.iter().any(|&b| b != SWAP_MAGIC) { | ||
| 724 | Ok(State::Swap) | ||
| 725 | } else { | ||
| 726 | Ok(State::Boot) | ||
| 727 | } | ||
| 728 | } | ||
| 729 | |||
| 700 | /// Mark to trigger firmware swap on next boot. | 730 | /// Mark to trigger firmware swap on next boot. |
| 701 | /// | 731 | /// |
| 702 | /// # Safety | 732 | /// # Safety |
| @@ -764,7 +794,7 @@ impl FirmwareUpdater { | |||
| 764 | self.dfu.from + offset + data.len() | 794 | self.dfu.from + offset + data.len() |
| 765 | ); | 795 | ); |
| 766 | 796 | ||
| 767 | FirmwareWriter(self).write_firmware_blocking(offset, data, flash, block_size)?; | 797 | FirmwareWriter(self.dfu).write_block_blocking(offset, data, flash, block_size)?; |
| 768 | 798 | ||
| 769 | Ok(()) | 799 | Ok(()) |
| 770 | } | 800 | } |
| @@ -779,14 +809,14 @@ impl FirmwareUpdater { | |||
| 779 | 809 | ||
| 780 | trace!("Erased from {} to {}", self.dfu.from, self.dfu.to); | 810 | trace!("Erased from {} to {}", self.dfu.from, self.dfu.to); |
| 781 | 811 | ||
| 782 | Ok(FirmwareWriter(self)) | 812 | Ok(FirmwareWriter(self.dfu)) |
| 783 | } | 813 | } |
| 784 | } | 814 | } |
| 785 | 815 | ||
| 786 | /// FirmwareWriter allows writing blocks to an already erased flash. | 816 | /// FirmwareWriter allows writing blocks to an already erased flash. |
| 787 | pub struct FirmwareWriter<'a>(&'a mut FirmwareUpdater); | 817 | pub struct FirmwareWriter(Partition); |
| 788 | 818 | ||
| 789 | impl<'a> FirmwareWriter<'a> { | 819 | impl FirmwareWriter { |
| 790 | /// Write data to a flash page. | 820 | /// Write data to a flash page. |
| 791 | /// | 821 | /// |
| 792 | /// The buffer must follow alignment requirements of the target flash and a multiple of page size big. | 822 | /// The buffer must follow alignment requirements of the target flash and a multiple of page size big. |
| @@ -794,7 +824,7 @@ impl<'a> FirmwareWriter<'a> { | |||
| 794 | /// # Safety | 824 | /// # Safety |
| 795 | /// | 825 | /// |
| 796 | /// Failing to meet alignment and size requirements may result in a panic. | 826 | /// Failing to meet alignment and size requirements may result in a panic. |
| 797 | pub async fn write_firmware<F: AsyncNorFlash>( | 827 | pub async fn write_block<F: AsyncNorFlash>( |
| 798 | &mut self, | 828 | &mut self, |
| 799 | offset: usize, | 829 | offset: usize, |
| 800 | data: &[u8], | 830 | data: &[u8], |
| @@ -803,11 +833,11 @@ impl<'a> FirmwareWriter<'a> { | |||
| 803 | ) -> Result<(), F::Error> { | 833 | ) -> Result<(), F::Error> { |
| 804 | trace!( | 834 | trace!( |
| 805 | "Writing firmware at offset 0x{:x} len {}", | 835 | "Writing firmware at offset 0x{:x} len {}", |
| 806 | self.0.dfu.from + offset, | 836 | self.0.from + offset, |
| 807 | data.len() | 837 | data.len() |
| 808 | ); | 838 | ); |
| 809 | 839 | ||
| 810 | let mut write_offset = self.0.dfu.from + offset; | 840 | let mut write_offset = self.0.from + offset; |
| 811 | for chunk in data.chunks(block_size) { | 841 | for chunk in data.chunks(block_size) { |
| 812 | trace!("Wrote chunk at {}: {:?}", write_offset, chunk); | 842 | trace!("Wrote chunk at {}: {:?}", write_offset, chunk); |
| 813 | flash.write(write_offset as u32, chunk).await?; | 843 | flash.write(write_offset as u32, chunk).await?; |
| @@ -838,7 +868,7 @@ impl<'a> FirmwareWriter<'a> { | |||
| 838 | /// # Safety | 868 | /// # Safety |
| 839 | /// | 869 | /// |
| 840 | /// Failing to meet alignment and size requirements may result in a panic. | 870 | /// Failing to meet alignment and size requirements may result in a panic. |
| 841 | pub fn write_firmware_blocking<F: NorFlash>( | 871 | pub fn write_block_blocking<F: NorFlash>( |
| 842 | &mut self, | 872 | &mut self, |
| 843 | offset: usize, | 873 | offset: usize, |
| 844 | data: &[u8], | 874 | data: &[u8], |
| @@ -847,11 +877,11 @@ impl<'a> FirmwareWriter<'a> { | |||
| 847 | ) -> Result<(), F::Error> { | 877 | ) -> Result<(), F::Error> { |
| 848 | trace!( | 878 | trace!( |
| 849 | "Writing firmware at offset 0x{:x} len {}", | 879 | "Writing firmware at offset 0x{:x} len {}", |
| 850 | self.0.dfu.from + offset, | 880 | self.0.from + offset, |
| 851 | data.len() | 881 | data.len() |
| 852 | ); | 882 | ); |
| 853 | 883 | ||
| 854 | let mut write_offset = self.0.dfu.from + offset; | 884 | let mut write_offset = self.0.from + offset; |
| 855 | for chunk in data.chunks(block_size) { | 885 | for chunk in data.chunks(block_size) { |
| 856 | trace!("Wrote chunk at {}: {:?}", write_offset, chunk); | 886 | trace!("Wrote chunk at {}: {:?}", write_offset, chunk); |
| 857 | flash.write(write_offset as u32, chunk)?; | 887 | flash.write(write_offset as u32, chunk)?; |
