Skip to content

Commit deb379e

Browse files
committed
feat: configurable link section attribute for irqs
This change introduces a new config field that allows `svd2rust` to target which linker sections get assigned to the `__INTERRUPTS` static, with reasonable defaults. Previously on RISC-V, the choice was always left up to the compiler, and it seemed to always pick `.rodata`. Unfortunately, in my context, that meant placing the LUT in a memory range that had a lot of highly variable latency, which cost not just time but predictability in servicing interrupts. With this change in place, I'm able to target a particular section (e.g. `.data`, or `.trap.rodata`) for the placement of the static, which grants more granular control over the ultimate loaded memory address. For the full details about the problem, please see: esp-rs/esp-hal@e29f3d5
1 parent d1ddb1b commit deb379e

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

src/generate/interrupt.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ pub fn render(
118118
writeln!(device_x, "PROVIDE({name} = DefaultHandler);")?;
119119
}
120120

121+
let link_section_name = config
122+
.interrupt_link_section
123+
.as_deref()
124+
.unwrap_or(".vector_table.interrupts");
125+
let link_section_attr = quote! {
126+
#[link_section = #link_section_name]
127+
};
128+
121129
root.extend(quote! {
122130
#[cfg(feature = "rt")]
123131
extern "C" {
@@ -132,7 +140,7 @@ pub fn render(
132140

133141
#[cfg(feature = "rt")]
134142
#[doc(hidden)]
135-
#[link_section = ".vector_table.interrupts"]
143+
#link_section_attr
136144
#[no_mangle]
137145
pub static __INTERRUPTS: [Vector; #n] = [
138146
#elements
@@ -144,6 +152,14 @@ pub fn render(
144152
writeln!(device_x, "PROVIDE({name} = DefaultHandler);").unwrap();
145153
}
146154

155+
let link_section_name = config
156+
.interrupt_link_section
157+
.as_deref()
158+
.unwrap_or(".vector_table.interrupts");
159+
let link_section_attr = quote! {
160+
#[link_section = #link_section_name]
161+
};
162+
147163
root.extend(quote! {
148164
#[cfg(feature = "rt")]
149165
extern "msp430-interrupt" {
@@ -158,7 +174,7 @@ pub fn render(
158174

159175
#[cfg(feature = "rt")]
160176
#[doc(hidden)]
161-
#[link_section = ".vector_table.interrupts"]
177+
#link_section_attr
162178
#[no_mangle]
163179
#[used]
164180
pub static __INTERRUPTS:
@@ -172,6 +188,14 @@ pub fn render(
172188
writeln!(device_x, "PROVIDE({name} = DefaultHandler);")?;
173189
}
174190

191+
let link_section_attr = if let Some(section) = &config.interrupt_link_section {
192+
quote! {
193+
#[link_section = #section]
194+
}
195+
} else {
196+
quote! {}
197+
};
198+
175199
root.extend(quote! {
176200
#[cfg(feature = "rt")]
177201
extern "C" {
@@ -186,6 +210,7 @@ pub fn render(
186210

187211
#[cfg(feature = "rt")]
188212
#[doc(hidden)]
213+
#link_section_attr
189214
#[no_mangle]
190215
pub static __EXTERNAL_INTERRUPTS: [Vector; #n] = [
191216
#elements
@@ -197,6 +222,14 @@ pub fn render(
197222
writeln!(device_x, "PROVIDE({name} = DefaultHandler);")?;
198223
}
199224

225+
let link_section_attr = if let Some(section) = &config.interrupt_link_section {
226+
quote! {
227+
#[link_section = #section]
228+
}
229+
} else {
230+
quote! {}
231+
};
232+
200233
root.extend(quote! {
201234
#[cfg(feature = "rt")]
202235
extern "C" {
@@ -210,6 +243,7 @@ pub fn render(
210243
}
211244

212245
#[cfg(feature = "rt")]
246+
#link_section_attr
213247
#[doc(hidden)]
214248
pub static __INTERRUPTS: [Vector; #n] = [
215249
#elements

src/util.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ pub struct Config {
5959
pub source_type: SourceType,
6060
#[cfg_attr(feature = "serde", serde(default))]
6161
pub log_level: Option<String>,
62+
#[cfg_attr(feature = "serde", serde(default))]
63+
pub interrupt_link_section: Option<String>,
6264
}
6365

6466
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -120,6 +122,7 @@ impl Default for Config {
120122
input: None,
121123
source_type: SourceType::default(),
122124
log_level: None,
125+
interrupt_link_section: None,
123126
}
124127
}
125128
}

0 commit comments

Comments
 (0)