@@ -87,7 +87,7 @@ pub fn device(
87
87
} ) ;
88
88
}
89
89
90
- :: generate:: interrupt ( target, & d. peripherals , items) ;
90
+ :: generate:: interrupt ( d , target, & d. peripherals , items) ;
91
91
92
92
const CORE_PERIPHERALS : & [ & str ] = & [
93
93
"CPUID" ,
@@ -173,6 +173,7 @@ pub fn device(
173
173
174
174
/// Generates code for `src/interrupt.rs`
175
175
pub fn interrupt (
176
+ device : & Device ,
176
177
target : & Target ,
177
178
peripherals : & [ Peripheral ] ,
178
179
items : & mut Vec < Tokens > ,
@@ -241,21 +242,48 @@ pub fn interrupt(
241
242
let n = util:: unsuffixed ( u64 ( pos) ) ;
242
243
match * target {
243
244
Target :: CortexM => {
244
- mod_items. push ( quote ! {
245
- #[ cfg( all( target_arch = "arm" , feature = "rt" ) ) ]
246
- global_asm!( "
247
- .thumb_func
248
- DH_TRAMPOLINE:
249
- b DEFAULT_HANDLER
250
- " ) ;
245
+ let is_armv6 = match device. cpu {
246
+ Some ( ref cpu) if cpu. name . starts_with ( "CM0" ) => true ,
247
+ _ => false ,
248
+ } ;
251
249
252
- /// Hack to compile on x86
253
- #[ cfg( all( target_arch = "x86_64" , feature = "rt" ) ) ]
254
- global_asm!( "
255
- DH_TRAMPOLINE:
256
- jmp DEFAULT_HANDLER
257
- " ) ;
250
+ if is_armv6 {
251
+ // Cortex-M0(+) are ARMv6 and don't have `b.w` (branch with 16 MB range). This
252
+ // can cause linker errors when the handler is too far away. Instead of a small
253
+ // inline assembly shim, we generate a function for those targets and let the
254
+ // compiler do the work (sacrificing a few bytes of code).
255
+ mod_items. push ( quote ! {
256
+ #[ cfg( feature = "rt" ) ]
257
+ extern "C" {
258
+ fn DEFAULT_HANDLER ( ) ;
259
+ }
260
+
261
+ #[ cfg( feature = "rt" ) ]
262
+ #[ allow( non_snake_case) ]
263
+ #[ no_mangle]
264
+ pub unsafe extern "C" fn DH_TRAMPOLINE ( ) {
265
+ DEFAULT_HANDLER ( ) ;
266
+ }
267
+ } ) ;
268
+ } else {
269
+ mod_items. push ( quote ! {
270
+ #[ cfg( all( target_arch = "arm" , feature = "rt" ) ) ]
271
+ global_asm!( "
272
+ .thumb_func
273
+ DH_TRAMPOLINE:
274
+ b DEFAULT_HANDLER
275
+ " ) ;
276
+
277
+ /// Hack to compile on x86
278
+ #[ cfg( all( target_arch = "x86_64" , feature = "rt" ) ) ]
279
+ global_asm!( "
280
+ DH_TRAMPOLINE:
281
+ jmp DEFAULT_HANDLER
282
+ " ) ;
283
+ } )
284
+ }
258
285
286
+ mod_items. push ( quote ! {
259
287
#[ cfg( feature = "rt" ) ]
260
288
global_asm!( #aliases) ;
261
289
0 commit comments