aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/Cargo.toml6
-rw-r--r--board/build.rs7
-rw-r--r--board/src/imxrt1010evk.rs2
-rw-r--r--board/src/lib.rs2
-rw-r--r--src/host.rs21
-rw-r--r--tests/inspect_elf.rs107
6 files changed, 143 insertions, 2 deletions
diff --git a/board/Cargo.toml b/board/Cargo.toml
index 836230c..449b807 100644
--- a/board/Cargo.toml
+++ b/board/Cargo.toml
@@ -40,6 +40,12 @@ imxrt1010evk = [
"dep:rtt-target",
"dep:panic-rtt-target",
]
+imxrt1010evk-ram = [
+ "imxrt-ral/imxrt1011",
+ # No FCB required.
+ "dep:rtt-target",
+ "dep:panic-rtt-target",
+]
imxrt1170evk-cm7 = [
"imxrt-ral/imxrt1176_cm7",
"dep:imxrt1170evk-fcb",
diff --git a/board/build.rs b/board/build.rs
index 4531667..e44a11d 100644
--- a/board/build.rs
+++ b/board/build.rs
@@ -60,6 +60,13 @@ fn main() {
.heap_size_env_override("BOARD_HEAP")
.build()
.unwrap(),
+ "imxrt1010evk_ram" => {
+ imxrt_rt::RuntimeBuilder::from_ram(imxrt_rt::Family::Imxrt1010)
+ .heap_size(1024)
+ .build()
+ .unwrap();
+ println!("cargo:rustc-cfg=from_ram");
+ }
_ => continue,
}
break;
diff --git a/board/src/imxrt1010evk.rs b/board/src/imxrt1010evk.rs
index 9a596e9..9bcf120 100644
--- a/board/src/imxrt1010evk.rs
+++ b/board/src/imxrt1010evk.rs
@@ -2,7 +2,7 @@
use crate::ral;
-#[cfg(target_arch = "arm")]
+#[cfg(all(target_arch = "arm", not(feature = "imxrt1010evk-ram")))]
use imxrt1010evk_fcb as _;
#[cfg(target_arch = "arm")]
use panic_rtt_target as _;
diff --git a/board/src/lib.rs b/board/src/lib.rs
index ebc76ad..f4912be 100644
--- a/board/src/lib.rs
+++ b/board/src/lib.rs
@@ -10,7 +10,7 @@ cfg_if::cfg_if! {
mod teensy4;
pub use teensy4::*;
- } else if #[cfg(feature = "imxrt1010evk")] {
+ } else if #[cfg(any(feature = "imxrt1010evk", feature = "imxrt1010evk-ram"))] {
mod shared { pub mod imxrt10xx; }
use shared::imxrt10xx::prepare_pit;
diff --git a/src/host.rs b/src/host.rs
index 6a01f9d..56a9d0f 100644
--- a/src/host.rs
+++ b/src/host.rs
@@ -401,6 +401,27 @@ impl RuntimeBuilder {
linker_script_name: DEFAULT_LINKER_SCRIPT_NAME.into(),
}
}
+
+ /// Create a runtime that executes from RAM.
+ pub fn from_ram(family: Family) -> 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: None,
+ linker_script_name: DEFAULT_LINKER_SCRIPT_NAME.into(),
+ }
+ }
+
/// Set the FlexRAM bank allocation.
///
/// Use this to customize the sizes of DTCM, ITCM, and OCRAM.
diff --git a/tests/inspect_elf.rs b/tests/inspect_elf.rs
index f0ca005..9c20111 100644
--- a/tests/inspect_elf.rs
+++ b/tests/inspect_elf.rs
@@ -197,6 +197,8 @@ struct Section {
size: u64,
}
+// No top-level constant for OCRAM, since placement varies
+// across 1000 and 1100 MCUs.
const DTCM: u64 = 0x2000_0000;
const ITCM: u64 = 0x0000_0020;
@@ -328,6 +330,111 @@ fn imxrt1010evk() {
);
}
+#[test]
+#[ignore = "building an example can take time"]
+fn imxrt1010evk_ram() {
+ let path = cargo_build("imxrt1010evk-ram").expect("Unable to build example");
+ let contents = fs::read(path).expect("Could not read ELF file");
+ let elf = Elf::parse(&contents).expect("Could not parse ELF");
+
+ let binary = ImxrtBinary::new(&elf, &contents);
+
+ let stack = binary.section(".stack").unwrap();
+ assert_eq!(
+ Section {
+ address: DTCM,
+ size: 8 * 1024
+ },
+ stack,
+ "stack not at ORIGIN(DTCM), or not 8 KiB large"
+ );
+ assert_eq!(binary.section_lma(".stack"), stack.address);
+
+ let vector_table = binary.section(".vector_table").unwrap();
+ assert_eq!(
+ Section {
+ address: stack.address + stack.size,
+ size: 16 * 4 + 240 * 4
+ },
+ vector_table,
+ "vector table not at expected VMA behind the stack"
+ );
+ assert!(
+ vector_table.address.is_multiple_of(1024),
+ "vector table is not 1024-byte aligned"
+ );
+ assert_eq!(
+ binary.section_lma(".vector_table"),
+ stack.address + stack.size,
+ "vector_table LMA == VMA for RAM boot",
+ );
+
+ let xip = binary.section(".xip").unwrap();
+ let text = binary.section(".text").unwrap();
+ assert_eq!(text.address, aligned(ITCM + xip.size, 4), "text");
+ assert_eq!(
+ binary.section_lma(".text"),
+ aligned(ITCM + xip.size, 4),
+ "text LMA == VMA for RAM boot"
+ );
+
+ let rodata = binary.section(".rodata").unwrap();
+ assert_eq!(rodata.address, 0x2020_0000, "rodata VMA in OCRAM");
+ assert_eq!(
+ rodata.address,
+ binary.section_lma(".rodata"),
+ "rodata LMA == VMA for RAM boot"
+ );
+
+ let data = binary.section(".data").unwrap();
+ assert_eq!(
+ data.address,
+ rodata.address + aligned(rodata.size, 4),
+ "data VMA in OCRAM behind rodata"
+ );
+ assert_eq!(
+ data.size, 4,
+ "blink-rtic expected to have a single static mut u32"
+ );
+ assert_eq!(
+ binary.section_lma(".data"),
+ rodata.address + aligned(rodata.size, 4),
+ "data LMA == VMA for RAM boot"
+ );
+
+ let bss = binary.section(".bss").unwrap();
+ assert_eq!(
+ bss.address,
+ data.address + aligned(data.size, 4),
+ "bss in OCRAM behind data"
+ );
+ assert_eq!(binary.section_lma(".bss"), bss.address, "bss is NOLOAD");
+
+ let uninit = binary.section(".uninit").unwrap();
+ assert_eq!(
+ uninit.address,
+ bss.address + aligned(bss.size, 4),
+ "uninit in OCRAM behind bss"
+ );
+ assert_eq!(
+ binary.section_lma(".uninit"),
+ uninit.address,
+ "uninit is NOLOAD"
+ );
+
+ let heap = binary.section(".heap").unwrap();
+ assert_eq!(
+ Section {
+ address: vector_table.address + vector_table.size,
+ size: 1024
+ },
+ heap,
+ "1 KiB heap in DTCM behind vector table"
+ );
+ assert_eq!(heap.size, 1024);
+ assert_eq!(binary.section_lma(".heap"), heap.address, "Heap is NOLOAD");
+}
+
fn baseline_teensy4(binary: &ImxrtBinary, dcd_at_runtime: u32, stack_size: u64, heap_size: u64) {
assert_eq!(
Fcb {