zencan_node/
node_state.rs

1//! Implements node state struct
2use crate::object_dict::ObjectFlagSync;
3
4use crate::pdo::Pdo;
5use crate::storage::StorageContext;
6
7/// A trait by which NodeState is accessed
8pub trait NodeStateAccess: Sync + Send {
9    /// Get the receive PDO objects
10    fn get_rpdos(&self) -> &[Pdo];
11    /// Get the transmit PDO objects
12    fn get_tpdos(&self) -> &[Pdo];
13    /// Get the PDO flag sync object
14    fn get_pdo_sync(&self) -> &ObjectFlagSync;
15    /// Get the storage context object
16    fn storage_context(&self) -> &StorageContext;
17}
18
19/// The NodeState provides config-dependent storage to the [`Node`](crate::Node) object
20///
21/// The node state has to get instantiated (statically) by zencan-build, based on the device config
22/// file. It is then provided to the node by the application when it is instantiated, and accessed
23/// via the [`NodeStateAccess`] trait.
24#[allow(missing_debug_implementations)]
25pub struct NodeState<const N_RPDO: usize, const N_TPDO: usize> {
26    rpdos: [Pdo; N_RPDO],
27    tpdos: [Pdo; N_TPDO],
28    pdo_sync: ObjectFlagSync,
29    storage_context: StorageContext,
30}
31
32impl<const N_RPDO: usize, const N_TPDO: usize> Default for NodeState<N_RPDO, N_TPDO> {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl<const N_RPDO: usize, const N_TPDO: usize> NodeState<N_RPDO, N_TPDO> {
39    /// Create a new NodeState object
40    pub const fn new() -> Self {
41        let rpdos = [const { Pdo::new() }; N_RPDO];
42        let tpdos = [const { Pdo::new() }; N_TPDO];
43        let pdo_sync = ObjectFlagSync::new();
44        let storage_context = StorageContext::new();
45        Self {
46            rpdos,
47            tpdos,
48            pdo_sync,
49            storage_context,
50        }
51    }
52
53    /// Access the RPDOs as a const function
54    pub const fn rpdos(&'static self) -> &'static [Pdo] {
55        &self.rpdos
56    }
57
58    /// Access the TPDOs as a const function
59    pub const fn tpdos(&'static self) -> &'static [Pdo] {
60        &self.tpdos
61    }
62
63    /// Access the pdo_sync as a const function
64    ///
65    /// This is required so that it can be shared with the objects in generated code
66    pub const fn pdo_sync(&'static self) -> &'static ObjectFlagSync {
67        &self.pdo_sync
68    }
69
70    /// Access the storage_context as a const function
71    pub const fn storage_context(&'static self) -> &'static StorageContext {
72        &self.storage_context
73    }
74}
75
76impl<const N_RPDO: usize, const N_TPDO: usize> NodeStateAccess for NodeState<N_RPDO, N_TPDO> {
77    fn get_rpdos(&self) -> &[Pdo] {
78        &self.rpdos
79    }
80
81    fn get_tpdos(&self) -> &[Pdo] {
82        &self.tpdos
83    }
84
85    fn get_pdo_sync(&self) -> &ObjectFlagSync {
86        &self.pdo_sync
87    }
88
89    fn storage_context(&self) -> &StorageContext {
90        &self.storage_context
91    }
92}