Fix dma nvic issues on dual core lines
This commit addresses #3256 by disabling dma NVIC interrupt enablement at startup. Instead, per-channel NVIC interrupt enablement is now done with the rest of the dma channel configuration. This ensures that each core will only handle the interrupts of the DMA channels that it uses.
This commit is contained in:
parent
6d9ed4c080
commit
2b7e76efe9
@ -1494,6 +1494,36 @@ fn main() {
|
|||||||
.flat_map(|p| &p.registers)
|
.flat_map(|p| &p.registers)
|
||||||
.any(|p| p.kind == "dmamux");
|
.any(|p| p.kind == "dmamux");
|
||||||
|
|
||||||
|
let mut dma_irqs: BTreeMap<&str, Vec<String>> = BTreeMap::new();
|
||||||
|
|
||||||
|
for p in METADATA.peripherals {
|
||||||
|
if let Some(r) = &p.registers {
|
||||||
|
if r.kind == "dma" || r.kind == "bdma" || r.kind == "gpdma" || r.kind == "lpdma" {
|
||||||
|
for irq in p.interrupts {
|
||||||
|
let ch_name = format!("{}_{}", p.name, irq.signal);
|
||||||
|
let ch = METADATA.dma_channels.iter().find(|c| c.name == ch_name).unwrap();
|
||||||
|
|
||||||
|
// Some H7 chips have BDMA1 hardcoded for DFSDM, ie no DMAMUX. It's unsupported, skip it.
|
||||||
|
if has_dmamux && ch.dmamux.is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_irqs.entry(irq.interrupt).or_default().push(ch_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
let mut dma_ch_to_irq: BTreeMap<&str, Vec<String>> = BTreeMap::new();
|
||||||
|
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
for (irq, channels) in &dma_irqs {
|
||||||
|
for channel in channels {
|
||||||
|
dma_ch_to_irq.entry(channel).or_default().push(irq.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ch_idx, ch) in METADATA.dma_channels.iter().enumerate() {
|
for (ch_idx, ch) in METADATA.dma_channels.iter().enumerate() {
|
||||||
// Some H7 chips have BDMA1 hardcoded for DFSDM, ie no DMAMUX. It's unsupported, skip it.
|
// Some H7 chips have BDMA1 hardcoded for DFSDM, ie no DMAMUX. It's unsupported, skip it.
|
||||||
if has_dmamux && ch.dmamux.is_none() {
|
if has_dmamux && ch.dmamux.is_none() {
|
||||||
@ -1502,6 +1532,16 @@ fn main() {
|
|||||||
|
|
||||||
let name = format_ident!("{}", ch.name);
|
let name = format_ident!("{}", ch.name);
|
||||||
let idx = ch_idx as u8;
|
let idx = ch_idx as u8;
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
let irq = {
|
||||||
|
let irq_name = if let Some(x) = &dma_ch_to_irq.get(ch.name) {
|
||||||
|
format_ident!("{}", x.get(0).unwrap())
|
||||||
|
} else {
|
||||||
|
panic!("failed to find dma interrupt")
|
||||||
|
};
|
||||||
|
quote!(crate::pac::Interrupt::#irq_name)
|
||||||
|
};
|
||||||
|
|
||||||
g.extend(quote!(dma_channel_impl!(#name, #idx);));
|
g.extend(quote!(dma_channel_impl!(#name, #idx);));
|
||||||
|
|
||||||
let dma = format_ident!("{}", ch.dma);
|
let dma = format_ident!("{}", ch.dma);
|
||||||
@ -1532,6 +1572,7 @@ fn main() {
|
|||||||
None => quote!(),
|
None => quote!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "_dual-core"))]
|
||||||
dmas.extend(quote! {
|
dmas.extend(quote! {
|
||||||
crate::dma::ChannelInfo {
|
crate::dma::ChannelInfo {
|
||||||
dma: #dma_info,
|
dma: #dma_info,
|
||||||
@ -1539,31 +1580,20 @@ fn main() {
|
|||||||
#dmamux
|
#dmamux
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
dmas.extend(quote! {
|
||||||
|
crate::dma::ChannelInfo {
|
||||||
|
dma: #dma_info,
|
||||||
|
num: #ch_num,
|
||||||
|
irq: #irq,
|
||||||
|
#dmamux
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========
|
// ========
|
||||||
// Generate DMA IRQs.
|
// Generate DMA IRQs.
|
||||||
|
|
||||||
let mut dma_irqs: BTreeMap<&str, Vec<String>> = BTreeMap::new();
|
|
||||||
|
|
||||||
for p in METADATA.peripherals {
|
|
||||||
if let Some(r) = &p.registers {
|
|
||||||
if r.kind == "dma" || r.kind == "bdma" || r.kind == "gpdma" {
|
|
||||||
for irq in p.interrupts {
|
|
||||||
let ch_name = format!("{}_{}", p.name, irq.signal);
|
|
||||||
let ch = METADATA.dma_channels.iter().find(|c| c.name == ch_name).unwrap();
|
|
||||||
|
|
||||||
// Some H7 chips have BDMA1 hardcoded for DFSDM, ie no DMAMUX. It's unsupported, skip it.
|
|
||||||
if has_dmamux && ch.dmamux.is_none() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dma_irqs.entry(irq.interrupt).or_default().push(ch_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dma_irqs: TokenStream = dma_irqs
|
let dma_irqs: TokenStream = dma_irqs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(irq, channels)| {
|
.map(|(irq, channels)| {
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use crate::{interrupt, pac};
|
|||||||
pub(crate) struct ChannelInfo {
|
pub(crate) struct ChannelInfo {
|
||||||
pub(crate) dma: DmaInfo,
|
pub(crate) dma: DmaInfo,
|
||||||
pub(crate) num: usize,
|
pub(crate) num: usize,
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
pub(crate) irq: pac::Interrupt,
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
pub(crate) dmamux: super::DmamuxInfo,
|
pub(crate) dmamux: super::DmamuxInfo,
|
||||||
}
|
}
|
||||||
@ -259,10 +261,12 @@ pub(crate) unsafe fn init(
|
|||||||
foreach_interrupt! {
|
foreach_interrupt! {
|
||||||
($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
|
($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
|
||||||
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, dma_priority);
|
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, dma_priority);
|
||||||
|
#[cfg(not(feature = "_dual-core"))]
|
||||||
crate::interrupt::typelevel::$irq::enable();
|
crate::interrupt::typelevel::$irq::enable();
|
||||||
};
|
};
|
||||||
($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
|
($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
|
||||||
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, bdma_priority);
|
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, bdma_priority);
|
||||||
|
#[cfg(not(feature = "_dual-core"))]
|
||||||
crate::interrupt::typelevel::$irq::enable();
|
crate::interrupt::typelevel::$irq::enable();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -341,6 +345,11 @@ impl AnyChannel {
|
|||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) {
|
) {
|
||||||
let info = self.info();
|
let info = self.info();
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
{
|
||||||
|
use embassy_hal_internal::interrupt::InterruptExt as _;
|
||||||
|
info.irq.enable();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
super::dmamux::configure_dmamux(&info.dmamux, _request);
|
super::dmamux::configure_dmamux(&info.dmamux, _request);
|
||||||
|
|||||||
@ -18,6 +18,8 @@ use crate::pac::gpdma::vals;
|
|||||||
pub(crate) struct ChannelInfo {
|
pub(crate) struct ChannelInfo {
|
||||||
pub(crate) dma: pac::gpdma::Gpdma,
|
pub(crate) dma: pac::gpdma::Gpdma,
|
||||||
pub(crate) num: usize,
|
pub(crate) num: usize,
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
pub(crate) irq: pac::Interrupt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GPDMA transfer options.
|
/// GPDMA transfer options.
|
||||||
@ -57,6 +59,7 @@ pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: P
|
|||||||
foreach_interrupt! {
|
foreach_interrupt! {
|
||||||
($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => {
|
($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => {
|
||||||
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority);
|
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority);
|
||||||
|
#[cfg(not(feature = "_dual-core"))]
|
||||||
crate::interrupt::typelevel::$irq::enable();
|
crate::interrupt::typelevel::$irq::enable();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -67,6 +70,12 @@ impl AnyChannel {
|
|||||||
/// Safety: Must be called with a matching set of parameters for a valid dma channel
|
/// Safety: Must be called with a matching set of parameters for a valid dma channel
|
||||||
pub(crate) unsafe fn on_irq(&self) {
|
pub(crate) unsafe fn on_irq(&self) {
|
||||||
let info = self.info();
|
let info = self.info();
|
||||||
|
#[cfg(feature = "_dual-core")]
|
||||||
|
{
|
||||||
|
use embassy_hal_internal::interrupt::InterruptExt as _;
|
||||||
|
info.irq.enable();
|
||||||
|
}
|
||||||
|
|
||||||
let state = &STATE[self.id as usize];
|
let state = &STATE[self.id as usize];
|
||||||
|
|
||||||
let ch = info.dma.ch(info.num);
|
let ch = info.dma.ch(info.num);
|
||||||
|
|||||||
@ -197,6 +197,7 @@ pub use crate::pac::NVIC_PRIO_BITS;
|
|||||||
|
|
||||||
/// `embassy-stm32` global configuration.
|
/// `embassy-stm32` global configuration.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// RCC config.
|
/// RCC config.
|
||||||
pub rcc: rcc::Config,
|
pub rcc: rcc::Config,
|
||||||
@ -303,6 +304,7 @@ mod dual_core {
|
|||||||
pub struct SharedData {
|
pub struct SharedData {
|
||||||
init_flag: AtomicUsize,
|
init_flag: AtomicUsize,
|
||||||
clocks: UnsafeCell<MaybeUninit<Clocks>>,
|
clocks: UnsafeCell<MaybeUninit<Clocks>>,
|
||||||
|
config: UnsafeCell<MaybeUninit<Config>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sync for SharedData {}
|
unsafe impl Sync for SharedData {}
|
||||||
@ -325,6 +327,8 @@ mod dual_core {
|
|||||||
rcc::set_freqs_ptr(shared_data.clocks.get());
|
rcc::set_freqs_ptr(shared_data.clocks.get());
|
||||||
let p = init_hw(config);
|
let p = init_hw(config);
|
||||||
|
|
||||||
|
unsafe { *shared_data.config.get() }.write(config);
|
||||||
|
|
||||||
shared_data.init_flag.store(INIT_DONE_FLAG, Ordering::SeqCst);
|
shared_data.init_flag.store(INIT_DONE_FLAG, Ordering::SeqCst);
|
||||||
|
|
||||||
p
|
p
|
||||||
@ -372,9 +376,23 @@ mod dual_core {
|
|||||||
fn init_secondary_hw(shared_data: &'static SharedData) -> Peripherals {
|
fn init_secondary_hw(shared_data: &'static SharedData) -> Peripherals {
|
||||||
rcc::set_freqs_ptr(shared_data.clocks.get());
|
rcc::set_freqs_ptr(shared_data.clocks.get());
|
||||||
|
|
||||||
|
let config = unsafe { (*shared_data.config.get()).assume_init() };
|
||||||
|
|
||||||
// We use different timers on the different cores, so we have to still initialize one here
|
// We use different timers on the different cores, so we have to still initialize one here
|
||||||
#[cfg(feature = "_time-driver")]
|
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
|
unsafe {
|
||||||
|
dma::init(
|
||||||
|
cs,
|
||||||
|
#[cfg(bdma)]
|
||||||
|
config.bdma_interrupt_priority,
|
||||||
|
#[cfg(dma)]
|
||||||
|
config.dma_interrupt_priority,
|
||||||
|
#[cfg(gpdma)]
|
||||||
|
config.gpdma_interrupt_priority,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "_time-driver")]
|
||||||
// must be after rcc init
|
// must be after rcc init
|
||||||
time_driver::init(cs);
|
time_driver::init(cs);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,6 +16,7 @@ pub enum LseMode {
|
|||||||
Bypass,
|
Bypass,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct LseConfig {
|
pub struct LseConfig {
|
||||||
pub frequency: Hertz,
|
pub frequency: Hertz,
|
||||||
pub mode: LseMode,
|
pub mode: LseMode,
|
||||||
@ -80,6 +81,7 @@ fn bdcr() -> Reg<Bdcr, RW> {
|
|||||||
return crate::pac::RCC.csr1();
|
return crate::pac::RCC.csr1();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct LsConfig {
|
pub struct LsConfig {
|
||||||
pub rtc: RtcClockSource,
|
pub rtc: RtcClockSource,
|
||||||
pub lsi: bool,
|
pub lsi: bool,
|
||||||
|
|||||||
@ -37,6 +37,7 @@ pub struct Hsi {
|
|||||||
|
|
||||||
/// Clocks configutation
|
/// Clocks configutation
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// HSI Configuration
|
/// HSI Configuration
|
||||||
pub hsi: Option<Hsi>,
|
pub hsi: Option<Hsi>,
|
||||||
|
|||||||
@ -76,6 +76,7 @@ pub enum HrtimClockSource {
|
|||||||
|
|
||||||
/// Clocks configutation
|
/// Clocks configutation
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
pub hse: Option<Hse>,
|
pub hse: Option<Hse>,
|
||||||
|
|||||||
@ -63,6 +63,7 @@ pub struct Pll {
|
|||||||
/// Used to calculate flash waitstates. See
|
/// Used to calculate flash waitstates. See
|
||||||
/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency
|
/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency
|
||||||
#[cfg(stm32f2)]
|
#[cfg(stm32f2)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub enum VoltageScale {
|
pub enum VoltageScale {
|
||||||
/// 2.7 to 3.6 V
|
/// 2.7 to 3.6 V
|
||||||
Range0,
|
Range0,
|
||||||
@ -76,6 +77,7 @@ pub enum VoltageScale {
|
|||||||
|
|
||||||
/// Configuration of the core clocks
|
/// Configuration of the core clocks
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
pub hse: Option<Hse>,
|
pub hse: Option<Hse>,
|
||||||
|
|||||||
@ -33,6 +33,7 @@ pub struct Hse {
|
|||||||
/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
|
/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
|
||||||
/// dividers. Be sure to keep check the datasheet for your specific part for the appropriate
|
/// dividers. Be sure to keep check the datasheet for your specific part for the appropriate
|
||||||
/// frequency ranges for each of these settings.
|
/// frequency ranges for each of these settings.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Pll {
|
pub struct Pll {
|
||||||
/// PLL Source clock selection.
|
/// PLL Source clock selection.
|
||||||
pub source: PllSource,
|
pub source: PllSource,
|
||||||
@ -55,6 +56,7 @@ pub struct Pll {
|
|||||||
|
|
||||||
/// Clocks configutation
|
/// Clocks configutation
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// HSI Enable
|
/// HSI Enable
|
||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
|
|||||||
@ -32,6 +32,7 @@ pub struct Hse {
|
|||||||
/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
|
/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
|
||||||
/// dividers. Be sure to keep check the datasheet for your specific part for the appropriate
|
/// dividers. Be sure to keep check the datasheet for your specific part for the appropriate
|
||||||
/// frequency ranges for each of these settings.
|
/// frequency ranges for each of these settings.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Pll {
|
pub struct Pll {
|
||||||
/// PLL Source clock selection.
|
/// PLL Source clock selection.
|
||||||
pub source: PllSource,
|
pub source: PllSource,
|
||||||
@ -54,6 +55,7 @@ pub struct Pll {
|
|||||||
|
|
||||||
/// Clocks configutation
|
/// Clocks configutation
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// HSI Enable
|
/// HSI Enable
|
||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
|
|||||||
@ -120,7 +120,7 @@ impl From<TimerPrescaler> for Timpre {
|
|||||||
/// Power supply configuration
|
/// Power supply configuration
|
||||||
/// See RM0433 Rev 4 7.4
|
/// See RM0433 Rev 4 7.4
|
||||||
#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
|
#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
|
||||||
#[derive(PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum SupplyConfig {
|
pub enum SupplyConfig {
|
||||||
/// Default power supply configuration.
|
/// Default power supply configuration.
|
||||||
/// V CORE Power Domains are supplied from the LDO according to VOS.
|
/// V CORE Power Domains are supplied from the LDO according to VOS.
|
||||||
@ -180,6 +180,7 @@ pub enum SMPSSupplyVoltage {
|
|||||||
|
|
||||||
/// Configuration of the core clocks
|
/// Configuration of the core clocks
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub hsi: Option<HSIPrescaler>,
|
pub hsi: Option<HSIPrescaler>,
|
||||||
pub hse: Option<Hse>,
|
pub hse: Option<Hse>,
|
||||||
|
|||||||
@ -30,6 +30,7 @@ pub struct Hse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Clocks configuration
|
/// Clocks configuration
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
// base clock sources
|
// base clock sources
|
||||||
pub msi: Option<MSIRange>,
|
pub msi: Option<MSIRange>,
|
||||||
|
|||||||
@ -59,6 +59,7 @@ pub struct Pll {
|
|||||||
pub divr: Option<PllDiv>,
|
pub divr: Option<PllDiv>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
// base clock sources
|
// base clock sources
|
||||||
pub msi: Option<MSIRange>,
|
pub msi: Option<MSIRange>,
|
||||||
|
|||||||
@ -15,6 +15,7 @@ pub struct Hse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Clocks configuration
|
/// Clocks configuration
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
// base clock sources
|
// base clock sources
|
||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
|
|||||||
@ -5,8 +5,8 @@ MEMORY
|
|||||||
BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
|
BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
|
||||||
FLASH : ORIGIN = 0x08008000, LENGTH = 64K
|
FLASH : ORIGIN = 0x08008000, LENGTH = 64K
|
||||||
DFU : ORIGIN = 0x08018000, LENGTH = 68K
|
DFU : ORIGIN = 0x08018000, LENGTH = 68K
|
||||||
SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64
|
SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128
|
||||||
RAM (rwx) : ORIGIN = 0x20000040, LENGTH = 32K - 64
|
RAM (rwx) : ORIGIN = 0x20000080, LENGTH = 32K - 128
|
||||||
}
|
}
|
||||||
|
|
||||||
__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER);
|
__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER);
|
||||||
@ -21,4 +21,4 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
*(.shared_data)
|
*(.shared_data)
|
||||||
} > SHARED_RAM
|
} > SHARED_RAM
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,8 @@ MEMORY
|
|||||||
{
|
{
|
||||||
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
||||||
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
|
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
|
||||||
SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64
|
SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128
|
||||||
RAM (rwx) : ORIGIN = 0x20000040, LENGTH = 64K - 64
|
RAM (rwx) : ORIGIN = 0x20000080, LENGTH = 64K - 128
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
@ -12,4 +12,4 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
*(.shared_data)
|
*(.shared_data)
|
||||||
} > SHARED_RAM
|
} > SHARED_RAM
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user