@@ -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