@@ -29,7 +29,7 @@ pub fn device(d: &Device, items: &mut Vec<Tokens>) -> Result<()> {
29
29
#![ deny( warnings) ]
30
30
#![ allow( non_camel_case_types) ]
31
31
#![ feature( const_fn) ]
32
- #![ feature( optin_builtin_traits ) ]
32
+ #![ feature( used ) ]
33
33
#![ no_std]
34
34
35
35
extern crate cortex_m;
@@ -93,46 +93,25 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
93
93
. collect :: < Vec < _ > > ( ) ;
94
94
interrupts. sort_by_key ( |i| i. value ) ;
95
95
96
- let mut fields = vec ! [ ] ;
97
- let mut exprs = vec ! [ ] ;
98
- let mut variants = vec ! [ ] ;
99
96
let mut arms = vec ! [ ] ;
97
+ let mut elements = vec ! [ ] ;
98
+ let mut names = vec ! [ ] ;
99
+ let mut variants = vec ! [ ] ;
100
100
101
101
// Current position in the vector table
102
102
let mut pos = 0 ;
103
- // Counter for reserved blocks
104
- let mut res = 0 ;
105
- let mut uses_reserved = false ;
106
103
let mut mod_items = vec ! [ ] ;
107
104
mod_items. push (
108
105
quote ! {
109
- use cortex_m:: ctxt:: Context ;
110
- use cortex_m:: exception;
111
106
use cortex_m:: interrupt:: Nr ;
112
107
} ,
113
108
) ;
114
109
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 ) ) ;
133
112
}
134
113
135
- let name_pc = Ident :: new ( interrupt. name . to_sanitized_upper_case ( ) ) ;
114
+ let name_uc = Ident :: new ( interrupt. name . to_sanitized_upper_case ( ) ) ;
136
115
let description = format ! (
137
116
"{} - {}" ,
138
117
interrupt. value,
@@ -142,72 +121,39 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
142
121
. map( |s| util:: respace( s) )
143
122
. unwrap_or_else( || interrupt. name. clone( ) )
144
123
) ;
145
- fields. push (
146
- quote ! {
147
- #[ doc = #description]
148
- pub #name_pc: extern "C" fn ( #name_pc) ,
149
- } ,
150
- ) ;
151
124
152
125
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
- ) ;
173
126
174
127
variants. push (
175
128
quote ! {
176
129
#[ doc = #description]
177
- #name_pc ,
130
+ #name_uc ,
178
131
} ,
179
132
) ;
180
133
181
134
arms. push (
182
135
quote ! {
183
- Interrupt :: #name_pc => #value,
136
+ Interrupt :: #name_uc => #value,
184
137
} ,
185
138
) ;
186
139
140
+ elements. push ( quote ! ( Some ( #name_uc) ) ) ;
141
+ names. push ( name_uc) ;
187
142
pos = interrupt. value + 1 ;
188
143
}
189
144
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) ) ;
198
146
mod_items. push (
199
147
quote ! {
200
- /// Interrupt handlers
201
- #[ allow( non_snake_case) ]
202
- #[ repr( C ) ]
203
- pub struct Handlers {
204
- #( #fields) *
148
+ extern "C" {
149
+ #( fn #names( ) ; ) *
205
150
}
206
151
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
+ ] ;
211
157
212
158
/// Enumeration of all the interrupts
213
159
pub enum Interrupt {
@@ -222,6 +168,52 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
222
168
}
223
169
}
224
170
}
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
+ }
225
217
} ,
226
218
) ;
227
219
0 commit comments