diff options
Diffstat (limited to 'src/host.rs')
| -rw-r--r-- | src/host.rs | 103 |
1 files changed, 86 insertions, 17 deletions
diff --git a/src/host.rs b/src/host.rs index eb10b22..e8325a7 100644 --- a/src/host.rs +++ b/src/host.rs @@ -127,9 +127,26 @@ fn region_alias(output: &mut dyn Write, name: &str, placement: Memory) -> io::Re #[derive(Debug, Clone, PartialEq, Eq)] struct FlashOpts { size: usize, + offset: u32, flexspi: FlexSpi, } +impl FlashOpts { + /// Produce the flash address of the image within + /// FlexSPI memory. + fn flash_origin(&self, family: Family) -> Option<u32> { + self.flexspi + .start_address(family) + .map(|start_address| start_address + self.offset) + } + + /// A bootable image (with the boot header) isn't offset + /// in flash. + fn is_boot_image(&self) -> bool { + self.offset == 0 + } +} + #[derive(Debug, Clone, PartialEq, Eq)] struct EnvOverride { default: usize, @@ -342,6 +359,43 @@ impl RuntimeBuilder { heap_size: EnvOverride::new(0), flash_opts: Some(FlashOpts { size: flash_size, + offset: 0, + flexspi: FlexSpi::family_default(family), + }), + linker_script_name: DEFAULT_LINKER_SCRIPT_NAME.into(), + } + } + + /// Allocate a flash partition for this program to be booted by your software. + /// + /// `partition_size` is the size of the flash allocation, in bytes, for this + /// program. `partition_offset` describes the byte offset where the partition + /// starts. The offset is from the start of the FlexSPI memory region. + /// + /// The program constructed at this flash location cannot be booted by NXP's boot + /// ROM. You should bring your own software to execute this program. Note that + /// [the runtime behaviors](RuntimeBuilder) ensure that the vector table is placed + /// in flash at the given `partition_offset`. + /// + /// To compute a partition offset from two absolute flash addresses, use + /// [`Family::flexspi_start_addr`] to learn the FlexSPI starting address. + pub fn in_flash(family: Family, partition_size: usize, partition_offset: u32) -> Self { + Self { + family, + flexram_banks: family.default_flexram_banks(), + text: Memory::Itcm, + rodata: Memory::Ocram, + data: Memory::Ocram, + vectors: Memory::Dtcm, + bss: Memory::Ocram, + uninit: Memory::Ocram, + stack: Memory::Dtcm, + stack_size: EnvOverride::new(8 * 1024), + heap: Memory::Dtcm, + heap_size: EnvOverride::new(0), + flash_opts: Some(FlashOpts { + size: partition_size, + offset: partition_offset, flexspi: FlexSpi::family_default(family), }), linker_script_name: DEFAULT_LINKER_SCRIPT_NAME.into(), @@ -508,19 +562,21 @@ impl RuntimeBuilder { if let Some(flash_opts) = &self.flash_opts { write_flash_memory_map(writer, self.family, flash_opts, &self.flexram_banks)?; - let boot_header_x = match self.family { - Family::Imxrt1010 - | Family::Imxrt1015 - | Family::Imxrt1020 - | Family::Imxrt1040 - | Family::Imxrt1050 - | Family::Imxrt1060 - | Family::Imxrt1064 - | Family::Imxrt1160 - | Family::Imxrt1170 => include_bytes!("host/imxrt-boot-header.x").as_slice(), - Family::Imxrt1180 => include_bytes!("host/imxrt-boot-header-1180.x").as_slice(), - }; - writer.write_all(boot_header_x)?; + if flash_opts.is_boot_image() { + let boot_header_x = match self.family { + Family::Imxrt1010 + | Family::Imxrt1015 + | Family::Imxrt1020 + | Family::Imxrt1040 + | Family::Imxrt1050 + | Family::Imxrt1060 + | Family::Imxrt1064 + | Family::Imxrt1160 + | Family::Imxrt1170 => include_bytes!("host/imxrt-boot-header.x").as_slice(), + Family::Imxrt1180 => include_bytes!("host/imxrt-boot-header-1180.x").as_slice(), + }; + writer.write_all(boot_header_x)?; + } } else { write_ram_memory_map(writer, self.family, &self.flexram_banks)?; } @@ -695,10 +751,7 @@ fn write_flash_memory_map( writeln!( output, "FLASH (RX) : ORIGIN = {:#X}, LENGTH = {:#X}", - flash_opts - .flexspi - .start_address(family) - .expect("Already checked"), + flash_opts.flash_origin(family).expect("Already checked"), flash_opts.size )?; write_flexram_memories(output, family, flexram_banks)?; @@ -901,6 +954,22 @@ impl Family { }, } } + + /// Returns the starting address for the given `flexspi` instance. + /// + /// If a FlexSPI instance isn't available for this family, the return + /// is `None`. Otherwise, the return is the starting address in the + /// MCU's memory map. + /// + /// ``` + /// use imxrt_rt::{Family::*, FlexSpi::*}; + /// + /// assert_eq!(Imxrt1060.flexspi_start_addr(FlexSpi1), Some(0x6000_0000)); + /// assert!(Imxrt1010.flexspi_start_addr(FlexSpi2).is_none()); + /// ``` + pub fn flexspi_start_addr(self, flexspi: FlexSpi) -> Option<u32> { + flexspi.start_address(self) + } } /// FlexRAM bank allocations. |
