1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
//! Runtime and startup support for i.MX RT processors.
//!
//! This crate builds on `cortex-m-rt` and adds support for i.MX RT processors.
//! Using this runtime crate, you can specify FlexRAM sizes and section allocations,
//! then use it to boot your i.MX RT processor.
//!
//! The crate achieves this with
//!
//! - a build-time API to define the memory map.
//! - a runtime library to configure the embedded processor.
//!
//! Both APIs are exposed from the same package. The interface changes depending on the
//! build environment.
//!
//! # Getting started
//!
//! Make sure you're familiar with [`cortex-m-rt`][cmrt] features. This crate re-exports
//! the `cortex-m-rt` interface. Use this interface to implement your program's entrypoint,
//! register exceptions, and interrupts. You should be familiar with specifing a linker
//! script for your embedded project.
//!
//! [cmrt]: https://docs.rs/cortex-m-rt/0.7.1/cortex_m_rt/
//!
//! # Dependencies
//!
//! In your embedded target, depend on `imxrt-rt` in both of
//!
//! - the `[dependencies]` section of your Cargo.toml
//! - the `[build-dependencies]` section of your Cargo.toml
//!
//! Use the same crate version in both locations. If you enable features, you must enable
//! features in both locations. See the features section for more information.
//!
//! ```text
//! [dependencies.imxrt-rt]
//! version = # $VERSION
//!
//! [build-dependencies.imxrt-rt]
//! version = # Same as $VERSION
//! ```
//!
//! # Linker script
//!
//! **Link against `imxrt-link.x`**, which is automatically made available on the linker search path.
//! Do not link against `link.x` from `cortex-m-rt`.
//!
//! You may change the name of the linker script by using the `RuntimeBuilder`.
//!
//! # Host configuration
//!
//! In your project, create a `build.rs` script that configures the runtime. The simplest `build.rs`
//! looks like this:
//!
//! ```no_run
//! use imxrt_rt::{Family, RuntimeBuilder};
//!
//! /// CHANGE ME depending on your board's flash size.
//! const FLASH_SIZE: usize = 16 * 1024 * 1024; // 16 MiB.
//! /// CHANGE ME depending on your board's chip.
//! const FAMILY: Family = Family::Imxrt1060;
//!
//! fn main() {
//! RuntimeBuilder::from_flexspi(FAMILY, FLASH_SIZE)
//! .build()
//! .unwrap();
//! }
//! ```
//!
//! This script works for any i.MX RT 1060-based system that has 16 MiB of external flash.
//! Change the flash size and chip family based on your hardware. It uses the default configuration,
//! which tries to give a reasonable memory layout for all processors.
//! To understand the default configuration, see the [`RuntimeBuilder`] documentation.
//!
//! A more advanced runtime configuration looks like this:
//!
//! ```no_run
//! # use imxrt_rt::{Family, RuntimeBuilder};
//! use imxrt_rt::{FlexRamBanks, Memory};
//! # const FLASH_SIZE: usize = 16 * 1024 * 1024; // 16 MiB.
//! # const FAMILY: Family = Family::Imxrt1060;
//!
//! fn main() {
//! RuntimeBuilder::from_flexspi(FAMILY, FLASH_SIZE)
//! .flexram_banks(FlexRamBanks {
//! ocram: 0,
//! dtcm: FAMILY.flexram_bank_count() / 2 + 2,
//! itcm: FAMILY.flexram_bank_count() / 2 - 2,
//! })
//! .text(Memory::Itcm)
//! .vectors(Memory::Itcm)
//! .rodata(Memory::Dtcm)
//! .data(Memory::Dtcm)
//! .bss(Memory::Dtcm)
//! .uninit(Memory::Dtcm)
//! .stack(Memory::Dtcm)
//! .stack_size(4 * 1024)
//! .heap(Memory::Dtcm)
//! .heap_size(512)
//! .build()
//! .unwrap();
//! }
//! ```
//!
//! This configuration maximizes the TCM allocation by removing OCRAM blocks. It takes two
//! banks from ITCM, and gives them to DTCM. It ensures that all sections are allocated to
//! DTCM instead of OCRAM. It reduces the stack size, and reserves space for a small heap.
//!
//! No matter the configuration, the runtime ensures that all contents are copied from flash
//! into their respective locations before `main()` is called.
//!
//! # Target integration
//!
//! If your runtime uses flash, link against a FlexSPI configuration block (FCB) crate. The
//! crate is expected to export a `static FLEXSPI_CONFIGURATION_BLOCK` that describes how the
//! FlexSPI peripheral interacts with your external flash chip. If an FCB crate doesn't exist
//! for your hardware, you can use the [`imxrt-boot-gen` crate](https://docs.rs/imxrt-boot-gen/0.2.0/imxrt_boot_gen/)
//! to define one. See the [`teensy4-fcb` crate](https://docs.rs/teensy4-fcb/0.3.0/teensy4_fcb/)
//! for an example of an FCB crate that is compatible with this runtime.
//!
//! Finally, use `imxrt-rt` in your firmware just as you would use `cortex-m-rt`. See the [`cortex-m-rt`
//! documentation][cmrt] for examples.
//!
//! # Feature flags
//!
//! `imxrt-rt` supports the features available in `cortex-m-rt` version 0.7.2. If you enable a feature,
//! you must enable it in both the `[dependencies]` and `[build-dependencies]` section of your package
//! manifest. For example, if the `cortex-m-rt` `"device"` feature were needed, then enable this crate's
//! `"device"` feature in both places.
//!
//! ```text
//! [dependencies.imxrt-rt]
//! version = # $VERSION
//! features = ["device"] # Add the feature here...
//!
//! [build-dependencies.imxrt-rt]
//! version = # Same as $VERSION
//! features = ["device"] # ... and here
//! ```
//!
//! # Limitations
//!
//! The crate considers the assignment of FlexRAM memory banks to ITCM/DTCM/OCRAM
//! an implementation detail. Additionally, the implementation does not care
//! about the assignment of memory bank power domains. This seems to matter most on
//! the 1050, which has the widest spread of bank-to-power domain assignment
//! (according to AN12077).
//!
//! There is no support for ECC on 1170. The runtime assumes that OCRAM and TCM ECC
//! is disabled, and that the corresponding memory banks can be used for OCRAM.
//!
//! The runtime installs a `cortex-m-rt` `pre_init` function to configure the runtime.
//! You cannot also define a `pre_init` function, and this crate does not support any
//! other mechanism for running code before `main()`.
//!
//! The implementation assumes all flash is FlexSPI.
#![cfg_attr(all(target_arch = "arm", target_os = "none"), no_std)]
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "arm", target_os = "none"))] {
mod target;
pub use target::*;
} else {
mod host;
pub use host::*;
}
}