1
1
use std:: collections:: HashMap ;
2
+ use std:: fmt:: Write ;
2
3
3
4
use cast:: u64;
4
5
use quote:: Tokens ;
@@ -10,7 +11,11 @@ use util::{self, ToSanitizedUpperCase};
10
11
use Target ;
11
12
12
13
/// Generates code for `src/interrupt.rs`
13
- pub fn render ( target : & Target , peripherals : & [ Peripheral ] ) -> Result < Vec < Tokens > > {
14
+ pub fn render (
15
+ target : & Target ,
16
+ peripherals : & [ Peripheral ] ,
17
+ device_x : & mut String ,
18
+ ) -> Result < Vec < Tokens > > {
14
19
let interrupts = peripherals
15
20
. iter ( )
16
21
. flat_map ( |p| p. interrupt . iter ( ) )
@@ -32,7 +37,7 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
32
37
let mut mod_items = vec ! [ ] ;
33
38
for interrupt in & interrupts {
34
39
while pos < interrupt. value {
35
- elements. push ( quote ! ( None ) ) ;
40
+ elements. push ( quote ! ( Vector { _reserved : 0 } ) ) ;
36
41
pos += 1 ;
37
42
}
38
43
pos += 1 ;
@@ -63,42 +68,87 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
63
68
#value => Ok ( Interrupt :: #name_uc) ,
64
69
} ) ;
65
70
66
- elements. push ( quote ! ( Some ( #name_uc) ) ) ;
71
+ elements. push ( quote ! ( Vector { _handler : #name_uc } ) ) ;
67
72
names. push ( name_uc) ;
68
73
}
69
74
70
- let aliases = names
71
- . iter ( )
72
- . map ( |n| {
73
- format ! (
74
- "
75
- .weak {0}
76
- {0} = DH_TRAMPOLINE" ,
77
- n
78
- )
79
- } )
80
- . collect :: < Vec < _ > > ( )
81
- . concat ( ) ;
82
-
83
75
let n = util:: unsuffixed ( u64 ( pos) ) ;
84
76
match * target {
85
77
Target :: CortexM => {
78
+ for name in & names {
79
+ writeln ! ( device_x, "PROVIDE({} = DefaultHandler);" , name) . unwrap ( ) ;
80
+ }
81
+
86
82
root. push ( quote ! {
87
83
#[ cfg( feature = "rt" ) ]
88
84
extern "C" {
89
85
#( fn #names( ) ; ) *
90
86
}
91
87
88
+ #[ doc( hidden) ]
89
+ pub union Vector {
90
+ _handler: unsafe extern "C" fn ( ) ,
91
+ _reserved: u32 ,
92
+ }
93
+
92
94
#[ cfg( feature = "rt" ) ]
93
95
#[ doc( hidden) ]
94
96
#[ link_section = ".vector_table.interrupts" ]
95
97
#[ no_mangle]
96
- pub static __INTERRUPTS: [ Option < unsafe extern "C" fn ( ) > ; #n] = [
98
+ pub static __INTERRUPTS: [ Vector ; #n] = [
97
99
#( #elements, ) *
98
100
] ;
101
+
102
+ /// Macro to override a device specific interrupt handler
103
+ #[ cfg( feature = "rt" ) ]
104
+ #[ macro_export]
105
+ macro_rules! interrupt {
106
+ ( $Name : ident, $handler: path, state: $State : ty = $initial_state: expr) => {
107
+ #[ allow( unsafe_code) ]
108
+ #[ no_mangle]
109
+ pub unsafe extern "C" fn $Name ( ) {
110
+ static mut STATE : $State = $initial_state;
111
+
112
+ // check that this interrupt exists
113
+ let _ = $crate :: Interrupt :: $Name ;
114
+
115
+ // validate the signature of the user provided handler
116
+ let f: fn ( & mut $State ) = $handler;
117
+
118
+ f( & mut STATE )
119
+ }
120
+ } ;
121
+
122
+ ( $Name : ident, $handler: path) => {
123
+ #[ allow( unsafe_code) ]
124
+ #[ no_mangle]
125
+ pub unsafe extern "C" fn $Name ( ) {
126
+ // check that this interrupt exists
127
+ let _ = $crate :: Interrupt :: $Name ;
128
+
129
+ // validate the signature of the user provided handler
130
+ let f: fn ( ) = $handler;
131
+
132
+ f( )
133
+ }
134
+ } ;
135
+ }
99
136
} ) ;
100
137
}
101
138
Target :: Msp430 => {
139
+ let aliases = names
140
+ . iter ( )
141
+ . map ( |n| {
142
+ format ! (
143
+ "
144
+ .weak {0}
145
+ {0} = DH_TRAMPOLINE" ,
146
+ n
147
+ )
148
+ } )
149
+ . collect :: < Vec < _ > > ( )
150
+ . concat ( ) ;
151
+
102
152
mod_items. push ( quote ! {
103
153
#[ cfg( feature = "rt" ) ]
104
154
global_asm!( "
@@ -114,14 +164,20 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
114
164
#( fn #names( ) ; ) *
115
165
}
116
166
167
+ #[ doc( hidden) ]
168
+ pub union Vector {
169
+ _handler: unsafe extern "msp430-interrupt" fn ( ) ,
170
+ _reserved: u32 ,
171
+ }
172
+
117
173
#[ allow( private_no_mangle_statics) ]
118
174
#[ cfg( feature = "rt" ) ]
119
175
#[ doc( hidden) ]
120
176
#[ link_section = ".vector_table.interrupts" ]
121
177
#[ no_mangle]
122
178
#[ used]
123
179
pub static INTERRUPTS :
124
- [ Option < unsafe extern "msp430-interrupt" fn ( ) > ; #n] = [
180
+ [ Vector ; #n] = [
125
181
#( #elements, ) *
126
182
] ;
127
183
} ) ;
@@ -152,6 +208,8 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
152
208
mod_items. push ( quote ! {
153
209
use core:: convert:: TryFrom ;
154
210
211
+ #interrupt_enum
212
+
155
213
#[ derive( Debug , Copy , Clone ) ]
156
214
pub struct TryFromInterruptError ( ( ) ) ;
157
215
0 commit comments