Skip to content

Commit b60408c

Browse files
committed
zephyr: device: Add a possible static element with each device
Allow the dt-rust.yaml file to specify a `static_type` value for device nodes. The generated code for the nodes will reserve a static value of that type, and pass it into the constructor. There is a NoStatic which is the default. As it is zero size, it will not cause any code to be generated for the types that do not need static. Fix the flash device to accept this argument, but the fix for gpio will come in a subsequent patch. Signed-off-by: David Brown <[email protected]>
1 parent 28f7ec6 commit b60408c

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

dt-rust.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
raw:
1616
type: myself
1717
device: crate::device::gpio::Gpio
18+
static_type: crate::device::gpio::GpioStatic
1819

1920
# The gpio-leds node will have #children nodes describing each led. We'll match on the parent
2021
# having this compatible property. The nodes themselves are built out of the properties associated

zephyr-build/src/devicetree/augment.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ pub enum Action {
130130
/// The name of the full path (within the zephyr-sys crate) for the wrapper node for this
131131
/// device.
132132
device: String,
133+
/// Full path to a type if this node needs a static associated with each instance.
134+
static_type: Option<String>,
133135
},
134136
/// Generate all of the labels as its own node.
135137
Labels,
@@ -138,7 +140,11 @@ pub enum Action {
138140
impl Action {
139141
fn generate(&self, _name: &Ident, node: &Node, tree: &DeviceTree) -> TokenStream {
140142
match self {
141-
Action::Instance { raw, device } => raw.generate(node, device),
143+
Action::Instance {
144+
raw,
145+
device,
146+
static_type,
147+
} => raw.generate(node, device, static_type.as_deref()),
142148
Action::Labels => {
143149
let nodes = tree.labels.iter().map(|(k, v)| {
144150
let name = dt_to_lower_id(k);
@@ -181,8 +187,9 @@ pub enum RawInfo {
181187
}
182188

183189
impl RawInfo {
184-
fn generate(&self, node: &Node, device: &str) -> TokenStream {
190+
fn generate(&self, node: &Node, device: &str, static_type: Option<&str>) -> TokenStream {
185191
let device_id = str_to_path(device);
192+
let static_type = str_to_path(static_type.unwrap_or("crate::device::NoStatic"));
186193
match self {
187194
Self::Myself => {
188195
let ord = node.ord;
@@ -192,12 +199,17 @@ impl RawInfo {
192199
pub unsafe fn get_instance_raw() -> *const crate::raw::device {
193200
&crate::raw::#rawdev
194201
}
202+
#[allow(dead_code)]
203+
pub(crate) unsafe fn get_static_raw() -> &'static #static_type {
204+
&STATIC
205+
}
195206

196207
static UNIQUE: crate::device::Unique = crate::device::Unique::new();
208+
static STATIC: #static_type = #static_type::new();
197209
pub fn get_instance() -> Option<#device_id> {
198210
unsafe {
199211
let device = get_instance_raw();
200-
#device_id::new(&UNIQUE, device)
212+
#device_id::new(&UNIQUE, &STATIC, device)
201213
}
202214
}
203215
}
@@ -220,10 +232,12 @@ impl RawInfo {
220232

221233
quote! {
222234
static UNIQUE: crate::device::Unique = crate::device::Unique::new();
235+
static STATIC: #static_type = #static_type::new();
223236
pub fn get_instance() -> Option<#device_id> {
224237
unsafe {
225238
let device = #target_route :: get_instance_raw();
226-
#device_id::new(&UNIQUE, device, #(#args),*)
239+
let device_static = #target_route :: get_static_raw();
240+
#device_id::new(&UNIQUE, &STATIC, device, device_static, #(#args),*)
227241
}
228242
}
229243
}
@@ -239,10 +253,11 @@ impl RawInfo {
239253

240254
quote! {
241255
static UNIQUE: crate::device::Unique = crate::device::Unique::new();
256+
static STATIC: #static_type = #static_type::new();
242257
pub fn get_instance() -> Option<#device_id> {
243258
unsafe {
244259
let device = #path :: get_instance_raw();
245-
#device_id::new(&UNIQUE, device, #(#get_args),*)
260+
#device_id::new(&UNIQUE, &STATIC, device, #(#get_args),*)
246261
}
247262
}
248263
}

zephyr/src/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ impl Unique {
4141
!self.0.fetch_or(true, Ordering::AcqRel)
4242
}
4343
}
44+
45+
/// For devices that don't need any associated static data, This NoStatic type will take no space
46+
/// and generate no code, and has the const constructor needed for the type.
47+
pub(crate) struct NoStatic;
48+
49+
impl NoStatic {
50+
pub(crate) const fn new() -> Self {
51+
Self
52+
}
53+
}

zephyr/src/device/flash.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Note that currently, the flash partition shares the controller, so the underlying operations
44
// are not actually safe. Need to rethink how to manage this.
55

6-
use super::Unique;
6+
use super::{NoStatic, Unique};
77
use crate::raw;
88

99
/// A flash controller
@@ -22,6 +22,7 @@ impl FlashController {
2222
#[allow(dead_code)]
2323
pub(crate) unsafe fn new(
2424
unique: &Unique,
25+
_static: &NoStatic,
2526
device: *const raw::device,
2627
) -> Option<FlashController> {
2728
if !unique.once() {
@@ -50,6 +51,7 @@ impl FlashPartition {
5051
#[allow(dead_code)]
5152
pub(crate) unsafe fn new(
5253
unique: &Unique,
54+
_static: &NoStatic,
5355
device: *const raw::device,
5456
offset: u32,
5557
size: u32,

0 commit comments

Comments
 (0)