Merge #322
322: rj/itcm r=jordens a=jordens * close #315 * would profit from cortex-m-rtic 0.6 elevating the attributes to the actual ISR thus removing the veneer Co-authored-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
commit
9587088de2
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -145,18 +145,15 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cortex-m-rt"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "980c9d0233a909f355ed297ef122f257942de5e0a2cb1c39f60684b65bcb90fb"
|
||||
source = "git+https://github.com/rust-embedded/cortex-m-rt.git?rev=a2e3ad5#a2e3ad54478c6b98e519a1b0946395d790c0b6c7"
|
||||
dependencies = [
|
||||
"cortex-m-rt-macros",
|
||||
"r0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m-rt-macros"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4717562afbba06e760d34451919f5c3bf3ac15c7bb897e8b04862a7428378647"
|
||||
version = "0.6.11"
|
||||
source = "git+https://github.com/rust-embedded/cortex-m-rt.git?rev=a2e3ad5#a2e3ad54478c6b98e519a1b0946395d790c0b6c7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -588,12 +585,6 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r0"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.3"
|
||||
|
@ -46,10 +46,12 @@ miniconf = "0.1.0"
|
||||
shared-bus = {version = "0.2.2", features = ["cortex-m"] }
|
||||
serde-json-core = "0.3"
|
||||
|
||||
# rtt-target bump
|
||||
[dependencies.rtt-logger]
|
||||
git = "https://github.com/quartiq/rtt-logger.git"
|
||||
rev = "70b0eb5"
|
||||
|
||||
# rewrite
|
||||
[dependencies.mcp23017]
|
||||
git = "https://github.com/lucazulian/mcp23017.git"
|
||||
rev = "523d71d"
|
||||
@ -58,6 +60,11 @@ rev = "523d71d"
|
||||
features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"]
|
||||
version = "0.9.0"
|
||||
|
||||
# link.x section start/end
|
||||
[patch.crates-io.cortex-m-rt]
|
||||
git = "https://github.com/rust-embedded/cortex-m-rt.git"
|
||||
rev = "a2e3ad5"
|
||||
|
||||
[patch.crates-io.miniconf]
|
||||
git = "https://github.com/quartiq/miniconf.git"
|
||||
rev = "c6f2b28"
|
||||
|
3
build.rs
Normal file
3
build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
}
|
20
memory.x
20
memory.x
@ -13,10 +13,6 @@ MEMORY
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.itcm : ALIGN(8) {
|
||||
*(.itcm .itcm.*);
|
||||
. = ALIGN(8);
|
||||
} > ITCM
|
||||
.axisram (NOLOAD) : ALIGN(8) {
|
||||
*(.axisram .axisram.*);
|
||||
. = ALIGN(8);
|
||||
@ -33,4 +29,18 @@ SECTIONS {
|
||||
*(.sram3 .sram3.*);
|
||||
. = ALIGN(4);
|
||||
} > SRAM3
|
||||
} INSERT AFTER .bss;
|
||||
.itcm : ALIGN(8) {
|
||||
. = ALIGN(8);
|
||||
__sitcm = .;
|
||||
*(.itcm .itcm.*);
|
||||
. = ALIGN(8);
|
||||
__eitcm = .;
|
||||
} > ITCM AT>FLASH
|
||||
__siitcm = LOADADDR(.itcm);
|
||||
} INSERT AFTER .uninit;
|
||||
|
||||
ASSERT(__sitcm % 8 == 0 && __eitcm % 8 == 0, "
|
||||
BUG(cortex-m-rt): .itcm is not 8-byte aligned");
|
||||
|
||||
ASSERT(__siitcm % 4 == 0, "
|
||||
BUG(cortex-m-rt): the LMA of .itcm is not 4-byte aligned");
|
||||
|
@ -120,6 +120,8 @@ const APP: () = {
|
||||
/// Because the ADC and DAC operate at the same rate, these two constraints actually implement
|
||||
/// the same time bounds, meeting one also means the other is also met.
|
||||
#[task(binds=DMA1_STR4, resources=[adcs, digital_inputs, dacs, iir_state, settings, telemetry], priority=2)]
|
||||
#[inline(never)]
|
||||
#[link_section = ".itcm.process"]
|
||||
fn process(c: process::Context) {
|
||||
let adc_samples = [
|
||||
c.resources.adcs.0.acquire_buffer(),
|
||||
|
@ -157,6 +157,8 @@ const APP: () = {
|
||||
/// It outputs either I/Q or power/phase on DAC0/DAC1. Data is normalized to full scale.
|
||||
/// PLL bandwidth, filter bandwidth, slope, and x/y or power/phase post-filters are available.
|
||||
#[task(binds=DMA1_STR4, resources=[adcs, dacs, lockin, timestamper, pll, settings, telemetry], priority=2)]
|
||||
#[inline(never)]
|
||||
#[link_section = ".itcm.process"]
|
||||
fn process(c: process::Context) {
|
||||
let adc_samples = [
|
||||
c.resources.adcs.0.acquire_buffer(),
|
||||
|
@ -105,6 +105,52 @@ pub struct PounderDevices {
|
||||
/// Static storage for the ethernet DMA descriptor ring.
|
||||
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();
|
||||
|
||||
/// Setup ITCM and load its code from flash.
|
||||
///
|
||||
/// For portability and maintainability this is implemented in Rust.
|
||||
/// Since this is implemented in Rust the compiler may assume that bss and data are set
|
||||
/// up already. There is no easy way to ensure this implementation will never need bss
|
||||
/// or data. Hence we can't safely run this as the cortex-m-rt `pre_init` hook before
|
||||
/// bss/data is setup.
|
||||
///
|
||||
/// Calling (through IRQ or directly) any code in ITCM before having called
|
||||
/// this method is undefined.
|
||||
fn load_itcm() {
|
||||
extern "C" {
|
||||
static mut __sitcm: u32;
|
||||
static mut __eitcm: u32;
|
||||
static mut __siitcm: u32;
|
||||
}
|
||||
use core::{ptr, slice, sync::atomic};
|
||||
|
||||
// NOTE(unsafe): Assuming the address symbols from the linker as well as
|
||||
// the source instruction data are all valid, this is safe as it only
|
||||
// copies linker-prepared data to where the code expects it to be.
|
||||
// Calling it multiple times is safe as well.
|
||||
|
||||
unsafe {
|
||||
// ITCM is enabled on reset on our CPU but might not be on others.
|
||||
// Keep for completeness.
|
||||
const ITCMCR: *mut u32 = 0xE000_EF90usize as _;
|
||||
ptr::write_volatile(ITCMCR, ptr::read_volatile(ITCMCR) | 1);
|
||||
|
||||
// Ensure ITCM is enabled before loading.
|
||||
atomic::fence(atomic::Ordering::SeqCst);
|
||||
|
||||
let len =
|
||||
(&__eitcm as *const u32).offset_from(&__sitcm as *const _) as usize;
|
||||
let dst = slice::from_raw_parts_mut(&mut __sitcm as *mut _, len);
|
||||
let src = slice::from_raw_parts(&__siitcm as *const _, len);
|
||||
// Load code into ITCM.
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
|
||||
// Ensure ITCM is loaded before potentially executing any instructions from it.
|
||||
atomic::fence(atomic::Ordering::SeqCst);
|
||||
cortex_m::asm::dsb();
|
||||
cortex_m::asm::isb();
|
||||
}
|
||||
|
||||
/// Configure the stabilizer hardware for operation.
|
||||
///
|
||||
/// # Args
|
||||
@ -157,9 +203,12 @@ pub fn setup(
|
||||
log::set_logger(&LOGGER)
|
||||
.map(|()| log::set_max_level(log::LevelFilter::Trace))
|
||||
.unwrap();
|
||||
log::info!("starting...");
|
||||
log::info!("Starting");
|
||||
}
|
||||
|
||||
// Before being able to call any code in ITCM, load that code from flash.
|
||||
load_itcm();
|
||||
|
||||
// Set up the system timer for RTIC scheduling.
|
||||
{
|
||||
let tim15 =
|
||||
@ -872,6 +921,7 @@ pub fn setup(
|
||||
|
||||
#[cfg(feature = "pounder_v1_1")]
|
||||
let pounder_stamper = {
|
||||
log::info!("Assuming Pounder v1.1 or later");
|
||||
let etr_pin = gpioa.pa0.into_alternate_af3();
|
||||
|
||||
// The frequency in the constructor is dont-care, as we will modify the period + clock
|
||||
@ -934,13 +984,13 @@ pub fn setup(
|
||||
digital_inputs,
|
||||
};
|
||||
|
||||
// Enable the instruction cache.
|
||||
core.SCB.enable_icache();
|
||||
|
||||
// info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap());
|
||||
// info!("Built on {}", build_info::BUILT_TIME_UTC);
|
||||
// info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET);
|
||||
log::info!("setup() complete");
|
||||
|
||||
// Enable the instruction cache.
|
||||
core.SCB.enable_icache();
|
||||
|
||||
(stabilizer, pounder)
|
||||
}
|
||||
|
@ -90,11 +90,11 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||
}
|
||||
|
||||
#[cortex_m_rt::exception]
|
||||
fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
|
||||
unsafe fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
|
||||
panic!("HardFault at {:#?}", ef);
|
||||
}
|
||||
|
||||
#[cortex_m_rt::exception]
|
||||
fn DefaultHandler(irqn: i16) {
|
||||
unsafe fn DefaultHandler(irqn: i16) {
|
||||
panic!("Unhandled exception (IRQn = {})", irqn);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user