@@ -2,15 +2,15 @@ use std::collections::HashMap;
2
2
3
3
use cast:: u64;
4
4
use quote:: Tokens ;
5
- use svd:: { Device , Peripheral } ;
5
+ use svd:: Peripheral ;
6
6
use syn:: Ident ;
7
7
8
8
use errors:: * ;
9
9
use util:: { self , ToSanitizedUpperCase } ;
10
10
use Target ;
11
11
12
12
/// Generates code for `src/interrupt.rs`
13
- pub fn render ( device : & Device , target : & Target , peripherals : & [ Peripheral ] ) -> Result < Vec < Tokens > > {
13
+ pub fn render ( target : & Target , peripherals : & [ Peripheral ] ) -> Result < Vec < Tokens > > {
14
14
let interrupts = peripherals
15
15
. iter ( )
16
16
. flat_map ( |p| p. interrupt . iter ( ) )
@@ -20,6 +20,7 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
20
20
let mut interrupts = interrupts. into_iter ( ) . map ( |( _, v) | v) . collect :: < Vec < _ > > ( ) ;
21
21
interrupts. sort_by_key ( |i| i. value ) ;
22
22
23
+ let mut root = vec ! [ ] ;
23
24
let mut arms = vec ! [ ] ;
24
25
let mut from_arms = vec ! [ ] ;
25
26
let mut elements = vec ! [ ] ;
@@ -29,9 +30,6 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
29
30
// Current position in the vector table
30
31
let mut pos = 0 ;
31
32
let mut mod_items = vec ! [ ] ;
32
- mod_items. push ( quote ! {
33
- use bare_metal:: Nr ;
34
- } ) ;
35
33
for interrupt in & interrupts {
36
34
while pos < interrupt. value {
37
35
elements. push ( quote ! ( None ) ) ;
@@ -85,63 +83,17 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
85
83
let n = util:: unsuffixed ( u64 ( pos) ) ;
86
84
match * target {
87
85
Target :: CortexM => {
88
- let is_armv6 = match device. cpu {
89
- Some ( ref cpu) => cpu. name . starts_with ( "CM0" ) ,
90
- None => true , // default to armv6 when the <cpu> section is missing
91
- } ;
92
-
93
- if is_armv6 {
94
- // Cortex-M0(+) are ARMv6 and don't have `b.w` (branch with 16 MB range). This
95
- // can cause linker errors when the handler is too far away. Instead of a small
96
- // inline assembly shim, we generate a function for those targets and let the
97
- // compiler do the work (sacrificing a few bytes of code).
98
- mod_items. push ( quote ! {
99
- #[ cfg( feature = "rt" ) ]
100
- extern "C" {
101
- fn DEFAULT_HANDLER ( ) ;
102
- }
103
-
104
- #[ cfg( feature = "rt" ) ]
105
- #[ allow( non_snake_case) ]
106
- #[ no_mangle]
107
- pub unsafe extern "C" fn DH_TRAMPOLINE ( ) {
108
- DEFAULT_HANDLER ( ) ;
109
- }
110
- } ) ;
111
- } else {
112
- mod_items. push ( quote ! {
113
- #[ cfg( all( target_arch = "arm" , feature = "rt" ) ) ]
114
- global_asm!( "
115
- .thumb_func
116
- DH_TRAMPOLINE:
117
- b DEFAULT_HANDLER
118
- " ) ;
119
-
120
- /// Hack to compile on x86
121
- #[ cfg( all( target_arch = "x86_64" , feature = "rt" ) ) ]
122
- global_asm!( "
123
- DH_TRAMPOLINE:
124
- jmp DEFAULT_HANDLER
125
- " ) ;
126
- } )
127
- }
128
-
129
- mod_items. push ( quote ! {
130
- #[ cfg( feature = "rt" ) ]
131
- global_asm!( #aliases) ;
132
-
86
+ root. push ( quote ! {
133
87
#[ cfg( feature = "rt" ) ]
134
88
extern "C" {
135
89
#( fn #names( ) ; ) *
136
90
}
137
91
138
- #[ allow( private_no_mangle_statics) ]
139
92
#[ cfg( feature = "rt" ) ]
140
93
#[ doc( hidden) ]
141
94
#[ link_section = ".vector_table.interrupts" ]
142
95
#[ no_mangle]
143
- #[ used]
144
- pub static INTERRUPTS : [ Option <unsafe extern "C" fn ( ) >; #n] = [
96
+ pub static __INTERRUPTS: [ Option <unsafe extern "C" fn ( ) >; #n] = [
145
97
#( #elements, ) *
146
98
] ;
147
99
} ) ;
@@ -178,106 +130,117 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
178
130
Target :: None => { }
179
131
}
180
132
181
- mod_items . push ( quote ! {
133
+ let interrupt_enum = quote ! {
182
134
/// Enumeration of all the interrupts
183
135
pub enum Interrupt {
184
136
#( #variants) *
185
137
}
186
138
187
- unsafe impl Nr for Interrupt {
139
+ unsafe impl :: bare_metal :: Nr for Interrupt {
188
140
#[ inline]
189
141
fn nr( & self ) -> u8 {
190
142
match * self {
191
143
#( #arms) *
192
144
}
193
145
}
194
146
}
147
+ } ;
195
148
196
- use core:: convert:: TryFrom ;
149
+ if * target == Target :: CortexM {
150
+ root. push ( interrupt_enum) ;
151
+ } else {
152
+ mod_items. push ( quote ! {
153
+ use core:: convert:: TryFrom ;
197
154
198
- #[ derive( Debug , Copy , Clone ) ]
199
- pub struct TryFromInterruptError ( ( ) ) ;
155
+ #[ derive( Debug , Copy , Clone ) ]
156
+ pub struct TryFromInterruptError ( ( ) ) ;
200
157
201
- impl TryFrom <u8 > for Interrupt {
202
- type Error = TryFromInterruptError ;
158
+ impl TryFrom <u8 > for Interrupt {
159
+ type Error = TryFromInterruptError ;
203
160
204
- #[ inline]
205
- fn try_from( value: u8 ) -> Result <Self , Self :: Error > {
206
- match value {
207
- #( #from_arms) *
208
- _ => Err ( TryFromInterruptError ( ( ) ) ) ,
161
+ #[ inline]
162
+ fn try_from( value: u8 ) -> Result <Self , Self :: Error > {
163
+ match value {
164
+ #( #from_arms) *
165
+ _ => Err ( TryFromInterruptError ( ( ) ) ) ,
166
+ }
209
167
}
210
168
}
211
- }
212
- } ) ;
169
+ } ) ;
170
+ }
213
171
214
172
if * target != Target :: None {
215
173
let abi = match * target {
216
174
Target :: Msp430 => "msp430-interrupt" ,
217
175
_ => "C" ,
218
176
} ;
219
- mod_items. push ( quote ! {
220
- #[ cfg( feature = "rt" ) ]
221
- #[ macro_export]
222
- macro_rules! interrupt {
223
- ( $NAME : ident, $path: path, locals: {
224
- $( $lvar: ident: $lty: ty = $lval: expr; ) *
225
- } ) => {
226
- #[ allow( non_snake_case) ]
227
- mod $NAME {
228
- pub struct Locals {
229
- $(
230
- pub $lvar: $lty,
231
- ) *
232
- }
233
- }
234
-
235
- #[ allow( non_snake_case) ]
236
- #[ no_mangle]
237
- pub extern #abi fn $NAME ( ) {
238
- // check that the handler exists
239
- let _ = $crate :: interrupt:: Interrupt :: $NAME ;
240
177
241
- static mut LOCALS : self :: $NAME :: Locals =
242
- self :: $NAME :: Locals {
178
+ if * target != Target :: CortexM {
179
+ mod_items. push ( quote ! {
180
+ #[ cfg( feature = "rt" ) ]
181
+ #[ macro_export]
182
+ macro_rules! interrupt {
183
+ ( $NAME : ident, $path: path, locals: {
184
+ $( $lvar: ident: $lty: ty = $lval: expr; ) *
185
+ } ) => {
186
+ #[ allow( non_snake_case) ]
187
+ mod $NAME {
188
+ pub struct Locals {
243
189
$(
244
- $lvar: $lval ,
190
+ pub $lvar: $lty ,
245
191
) *
246
- } ;
192
+ }
193
+ }
247
194
248
- // type checking
249
- let f: fn ( & mut self :: $NAME :: Locals ) = $path;
250
- f( unsafe { & mut LOCALS } ) ;
251
- }
252
- } ;
253
- ( $NAME : ident, $path: path) => {
254
- #[ allow( non_snake_case) ]
255
- #[ no_mangle]
256
- pub extern #abi fn $NAME ( ) {
257
- // check that the handler exists
258
- let _ = $crate :: interrupt:: Interrupt :: $NAME ;
259
-
260
- // type checking
261
- let f: fn ( ) = $path;
262
- f( ) ;
195
+ #[ allow( non_snake_case) ]
196
+ #[ no_mangle]
197
+ pub extern #abi fn $NAME ( ) {
198
+ // check that the handler exists
199
+ let _ = $crate :: interrupt:: Interrupt :: $NAME ;
200
+
201
+ static mut LOCALS : self :: $NAME :: Locals =
202
+ self :: $NAME :: Locals {
203
+ $(
204
+ $lvar: $lval,
205
+ ) *
206
+ } ;
207
+
208
+ // type checking
209
+ let f: fn ( & mut self :: $NAME :: Locals ) = $path;
210
+ f( unsafe { & mut LOCALS } ) ;
211
+ }
212
+ } ;
213
+ ( $NAME : ident, $path: path) => {
214
+ #[ allow( non_snake_case) ]
215
+ #[ no_mangle]
216
+ pub extern #abi fn $NAME ( ) {
217
+ // check that the handler exists
218
+ let _ = $crate :: interrupt:: Interrupt :: $NAME ;
219
+
220
+ // type checking
221
+ let f: fn ( ) = $path;
222
+ f( ) ;
223
+ }
263
224
}
264
225
}
265
- }
266
- } ) ;
226
+ } ) ;
227
+ }
267
228
}
268
229
269
- let mut out = vec ! [ ] ;
270
-
271
230
if interrupts. len ( ) > 0 {
272
- out. push ( quote ! {
273
- pub use interrupt:: Interrupt ;
274
-
231
+ root. push ( quote ! {
275
232
#[ doc( hidden) ]
276
233
pub mod interrupt {
277
234
#( #mod_items) *
278
235
}
279
236
} ) ;
237
+
238
+ if * target != Target :: CortexM {
239
+ root. push ( quote ! {
240
+ pub use interrupt:: Interrupt ;
241
+ } ) ;
242
+ }
280
243
}
281
244
282
- Ok ( out )
245
+ Ok ( root )
283
246
}
0 commit comments