Skip to content

Commit aff4cb0

Browse files
committed
adapt to incoming changes in cortex-m and cortex-m-rt
1 parent 93d9706 commit aff4cb0

File tree

2 files changed

+66
-74
lines changed

2 files changed

+66
-74
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/generate.rs

Lines changed: 65 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn device(d: &Device, items: &mut Vec<Tokens>) -> Result<()> {
2929
#![deny(warnings)]
3030
#![allow(non_camel_case_types)]
3131
#![feature(const_fn)]
32-
#![feature(optin_builtin_traits)]
32+
#![feature(used)]
3333
#![no_std]
3434

3535
extern crate cortex_m;
@@ -93,46 +93,25 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
9393
.collect::<Vec<_>>();
9494
interrupts.sort_by_key(|i| i.value);
9595

96-
let mut fields = vec![];
97-
let mut exprs = vec![];
98-
let mut variants = vec![];
9996
let mut arms = vec![];
97+
let mut elements = vec![];
98+
let mut names = vec![];
99+
let mut variants = vec![];
100100

101101
// Current position in the vector table
102102
let mut pos = 0;
103-
// Counter for reserved blocks
104-
let mut res = 0;
105-
let mut uses_reserved = false;
106103
let mut mod_items = vec![];
107104
mod_items.push(
108105
quote! {
109-
use cortex_m::ctxt::Context;
110-
use cortex_m::exception;
111106
use cortex_m::interrupt::Nr;
112107
},
113108
);
114109
for interrupt in &interrupts {
115-
if pos < interrupt.value {
116-
let name = Ident::new(&*format!("_reserved{}", res));
117-
res += 1;
118-
let n = util::unsuffixed(u64(interrupt.value - pos));
119-
120-
uses_reserved = true;
121-
fields.push(
122-
quote! {
123-
/// Reserved spot in the vector table
124-
pub #name: [Reserved; #n],
125-
},
126-
);
127-
128-
exprs.push(
129-
quote! {
130-
#name: [Reserved::Vector; #n],
131-
},
132-
);
110+
while pos < interrupt.value {
111+
elements.push(quote!(None));
133112
}
134113

135-
let name_pc = Ident::new(interrupt.name.to_sanitized_upper_case());
114+
let name_uc = Ident::new(interrupt.name.to_sanitized_upper_case());
136115
let description = format!(
137116
"{} - {}",
138117
interrupt.value,
@@ -142,72 +121,39 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
142121
.map(|s| util::respace(s))
143122
.unwrap_or_else(|| interrupt.name.clone())
144123
);
145-
fields.push(
146-
quote! {
147-
#[doc = #description]
148-
pub #name_pc: extern "C" fn(#name_pc),
149-
},
150-
);
151124

152125
let value = util::unsuffixed(u64(interrupt.value));
153-
mod_items.push(
154-
quote! {
155-
#[doc = #description]
156-
pub struct #name_pc { _0: () }
157-
unsafe impl Context for #name_pc {}
158-
unsafe impl Nr for #name_pc {
159-
#[inline(always)]
160-
fn nr(&self) -> u8 {
161-
#value
162-
}
163-
}
164-
impl !Send for #name_pc {}
165-
},
166-
);
167-
168-
exprs.push(
169-
quote! {
170-
#name_pc: exception::default_handler,
171-
},
172-
);
173126

174127
variants.push(
175128
quote! {
176129
#[doc = #description]
177-
#name_pc,
130+
#name_uc,
178131
},
179132
);
180133

181134
arms.push(
182135
quote! {
183-
Interrupt::#name_pc => #value,
136+
Interrupt::#name_uc => #value,
184137
},
185138
);
186139

140+
elements.push(quote!(Some(#name_uc)));
141+
names.push(name_uc);
187142
pos = interrupt.value + 1;
188143
}
189144

190-
if uses_reserved {
191-
mod_items.push(
192-
quote! {
193-
use cortex_m::Reserved;
194-
},
195-
);
196-
}
197-
145+
let n = util::unsuffixed(u64(pos));
198146
mod_items.push(
199147
quote! {
200-
/// Interrupt handlers
201-
#[allow(non_snake_case)]
202-
#[repr(C)]
203-
pub struct Handlers {
204-
#(#fields)*
148+
extern "C" {
149+
#(fn #names();)*
205150
}
206151

207-
/// Default interrupt handlers
208-
pub const DEFAULT_HANDLERS: Handlers = Handlers {
209-
#(#exprs)*
210-
};
152+
#[link_section = ".vector_table.interrupts"]
153+
#[used]
154+
static INTERRUPTS: [Option<unsafe extern "C" fn()>; #n] = [
155+
#(#elements,)*
156+
];
211157

212158
/// Enumeration of all the interrupts
213159
pub enum Interrupt {
@@ -222,6 +168,52 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
222168
}
223169
}
224170
}
171+
172+
#[macro_export]
173+
macro_rules! interrupt {
174+
($NAME:ident, $f:ident, local: {
175+
$($lvar:ident:$lty:ident = $lval:expr;)*
176+
}) => {
177+
#[allow(non_snake_case)]
178+
mod $NAME {
179+
pub struct Locals {
180+
$(
181+
pub $lvar: $lty,
182+
)*
183+
}
184+
}
185+
186+
#[allow(non_snake_case)]
187+
#[no_mangle]
188+
pub extern "C" fn $NAME() {
189+
// check that the handler exists
190+
let _ = $crate::interrupt::Interrupt::$NAME;
191+
192+
static mut LOCALS: self::$NAME::Locals =
193+
self::$NAME::Locals {
194+
$(
195+
$lvar: $lval,
196+
)*
197+
};
198+
199+
// type checking
200+
let f: fn(&mut self::$NAME::Locals) = $f;
201+
f(unsafe { &mut LOCALS });
202+
}
203+
};
204+
($NAME:ident, $f:ident) => {
205+
#[allow(non_snake_case)]
206+
#[no_mangle]
207+
pub extern "C" fn $NAME() {
208+
// check that the handler exists
209+
let _ = $crate::interrupt::Interrupt::$NAME;
210+
211+
// type checking
212+
let f: fn() = $f;
213+
f();
214+
}
215+
}
216+
}
225217
},
226218
);
227219

0 commit comments

Comments
 (0)