Skip to content

Commit

Permalink
Merge #322
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
bors[bot] and jordens authored May 28, 2021
2 parents d79fb4d + 79d30b4 commit 9587088
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 23 deletions.
15 changes: 3 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("cargo:rerun-if-changed=memory.x");
}
20 changes: 15 additions & 5 deletions memory.x
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ MEMORY
}

SECTIONS {
.itcm : ALIGN(8) {
*(.itcm .itcm.*);
. = ALIGN(8);
} > ITCM
.axisram (NOLOAD) : ALIGN(8) {
*(.axisram .axisram.*);
. = ALIGN(8);
Expand All @@ -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");
2 changes: 2 additions & 0 deletions src/bin/dual-iir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
2 changes: 2 additions & 0 deletions src/bin/lockin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
58 changes: 54 additions & 4 deletions src/hardware/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
4 changes: 2 additions & 2 deletions src/hardware/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 9587088

Please sign in to comment.