autosar_data_abstraction/ecuinstance.rs
1use crate::communication::{
2 CanCommunicationController, CommunicationController, EthernetCommunicationController,
3 FlexrayCommunicationController, LinMaster, LinSlave,
4};
5use crate::{
6 AbstractionElement, ArPackage, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
7};
8use autosar_data::{Element, ElementName};
9
10/// The `EcuInstance` represents one ECU in a `System`
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct EcuInstance(Element);
13abstraction_element!(EcuInstance, EcuInstance);
14impl IdentifiableAbstractionElement for EcuInstance {}
15
16impl EcuInstance {
17 // Create a new EcuInstance
18 //
19 // This new EcuInstance will not be connected to a System.
20 pub(crate) fn new(name: &str, package: &ArPackage) -> Result<EcuInstance, AutosarAbstractionError> {
21 let elem_pkg_elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
22 let elem_ecu_instance = elem_pkg_elements.create_named_sub_element(ElementName::EcuInstance, name)?;
23
24 Ok(EcuInstance(elem_ecu_instance))
25 }
26
27 /// Create a CAN-COMMUNICATION-CONTROLLER for this ECU-INSTANCE
28 ///
29 /// The ECU must have one controller per bus it communicates on.
30 /// For example, if it communicates on two CAN buses, then two CAN-COMMUNICATION-CONTROLLERs are needed.
31 ///
32 /// # Example
33 ///
34 /// ```
35 /// # use autosar_data::*;
36 /// # use autosar_data_abstraction::*;
37 /// # fn main() -> Result<(), AutosarAbstractionError> {
38 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
39 /// # let package = model.get_or_create_package("/pkg1")?;
40 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
41 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
42 /// let can_controller = ecu_instance.create_can_communication_controller("CanCtrl")?;
43 /// # Ok(())}
44 /// ```
45 ///
46 /// # Errors
47 ///
48 /// - [`AutosarAbstractionError::ModelError`] An error occurred in the Autosar model while trying to create the ECU-INSTANCE
49 pub fn create_can_communication_controller(
50 &self,
51 name: &str,
52 ) -> Result<CanCommunicationController, AutosarAbstractionError> {
53 CanCommunicationController::new(name, self)
54 }
55
56 /// Create an ETHERNET-COMMUNICATION-CONTROLLER for this ECU-INSTANCE
57 ///
58 /// The ECU must have one controller per bus it communicates on.
59 /// For example, if it communicates on two CAN buses, then two CAN-COMMUNICATION-CONTROLLERs are needed.
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// # use autosar_data::*;
65 /// # use autosar_data_abstraction::*;
66 /// # fn main() -> Result<(), AutosarAbstractionError> {
67 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
68 /// # let package = model.get_or_create_package("/pkg1")?;
69 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
70 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
71 /// let ethernet_controller = ecu_instance
72 /// .create_ethernet_communication_controller("EthCtrl", Some("ab:cd:ef:01:02:03".to_string()))?;
73 /// # Ok(())}
74 /// ```
75 ///
76 /// # Errors
77 ///
78 /// - [`AutosarAbstractionError::ModelError`] An error occurred in the Autosar model while trying to create the ECU-INSTANCE
79 pub fn create_ethernet_communication_controller(
80 &self,
81 name: &str,
82 mac_address: Option<String>,
83 ) -> Result<EthernetCommunicationController, AutosarAbstractionError> {
84 EthernetCommunicationController::new(name, self, mac_address)
85 }
86
87 /// Create a FLEXRAY-COMMUNICATION-CONTROLLER for this ECU-INSTANCE
88 ///
89 /// The ECU must have one controller per bus it communicates on.
90 /// For example, if it communicates on two CAN buses, then two CAN-COMMUNICATION-CONTROLLERs are needed.
91 ///
92 /// # Example
93 ///
94 /// ```
95 /// # use autosar_data::*;
96 /// # use autosar_data_abstraction::*;
97 /// # fn main() -> Result<(), AutosarAbstractionError> {
98 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
99 /// # let package = model.get_or_create_package("/pkg1")?;
100 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
101 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
102 /// let flexray_controller = ecu_instance
103 /// .create_flexray_communication_controller("FlexrayCtrl")?;
104 /// # Ok(())}
105 /// ```
106 ///
107 /// # Errors
108 ///
109 /// - [`AutosarAbstractionError::ModelError`] An error occurred in the Autosar model while trying to
110 /// create the FLEXRAY-COMMUNICATION-CONTROLLER
111 pub fn create_flexray_communication_controller(
112 &self,
113 name: &str,
114 ) -> Result<FlexrayCommunicationController, AutosarAbstractionError> {
115 FlexrayCommunicationController::new(name, self)
116 }
117
118 /// Create a LIN-MASTER communication controller for this ECU-INSTANCE
119 ///
120 /// The ECU must have one controller per bus it communicates on.
121 /// For example, if it communicates on two LIN buses, then two LIN-MASTER or
122 /// LIN-SLAVE communication controllers are needed.
123 ///
124 /// # Example
125 ///
126 /// ```
127 /// # use autosar_data::*;
128 /// # use autosar_data_abstraction::*;
129 /// # fn main() -> Result<(), AutosarAbstractionError> {
130 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
131 /// # let package = model.get_or_create_package("/pkg1")?;
132 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
133 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
134 /// let can_controller = ecu_instance.create_lin_master_communication_controller("LinMasterCtrl")?;
135 /// # Ok(())}
136 /// ```
137 ///
138 /// # Errors
139 ///
140 /// - [`AutosarAbstractionError::ModelError`] An error occurred in the Autosar model while trying to create the LIN-MASTER
141 pub fn create_lin_master_communication_controller(&self, name: &str) -> Result<LinMaster, AutosarAbstractionError> {
142 LinMaster::new(name, self)
143 }
144
145 /// Create a LIN-SLAVE communication controller for this ECU-INSTANCE
146 ///
147 /// The ECU must have one controller per bus it communicates on.
148 /// For example, if it communicates on two LIN buses, then two LIN-MASTER or
149 /// LIN-SLAVE communication controllers are needed.
150 ///
151 /// # Example
152 ///
153 /// ```
154 /// # use autosar_data::*;
155 /// # use autosar_data_abstraction::*;
156 /// # fn main() -> Result<(), AutosarAbstractionError> {
157 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
158 /// # let package = model.get_or_create_package("/pkg1")?;
159 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
160 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
161 /// let can_controller = ecu_instance.create_lin_slave_communication_controller("LinSlaveCtrl")?;
162 /// # Ok(())}
163 /// ```
164 ///
165 /// # Errors
166 ///
167 /// - [`AutosarAbstractionError::ModelError`] An error occurred in the Autosar model while trying to create the LIN-MASTER
168 pub fn create_lin_slave_communication_controller(&self, name: &str) -> Result<LinSlave, AutosarAbstractionError> {
169 LinSlave::new(name, self)
170 }
171
172 /// return an interator over all communication controllers in this `EcuInstance`
173 ///
174 /// # Example
175 ///
176 /// ```
177 /// # use autosar_data::*;
178 /// # use autosar_data_abstraction::*;
179 /// # fn main() -> Result<(), AutosarAbstractionError> {
180 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
181 /// # let package = model.get_or_create_package("/pkg1")?;
182 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
183 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
184 /// ecu_instance.create_flexray_communication_controller("FlexrayCtrl")?;
185 /// ecu_instance.create_can_communication_controller("CanCtrl")?;
186 /// for ctrl in ecu_instance.communication_controllers() {
187 /// // ...
188 /// }
189 /// # assert_eq!(ecu_instance.communication_controllers().count(), 2);
190 /// # Ok(())}
191 /// ```
192 pub fn communication_controllers(&self) -> impl Iterator<Item = CommunicationController> + Send + use<> {
193 self.0
194 .get_sub_element(ElementName::CommControllers)
195 .into_iter()
196 .flat_map(|cc| cc.sub_elements())
197 .filter_map(|ccelem| CommunicationController::try_from(ccelem).ok())
198 }
199}
200
201//##################################################################
202
203#[cfg(test)]
204mod test {
205 use crate::*;
206 use autosar_data::AutosarVersion;
207
208 #[test]
209 fn ecu() {
210 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
211 let package = model.get_or_create_package("/pkg1").unwrap();
212 let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
213 let ecu_instance = system.create_ecu_instance("ecu_name", &package).unwrap();
214 ecu_instance
215 .create_flexray_communication_controller("FlexrayCtrl")
216 .unwrap();
217 ecu_instance.create_can_communication_controller("CanCtrl").unwrap();
218 ecu_instance
219 .create_ethernet_communication_controller("EthCtrl", None)
220 .unwrap();
221 assert_eq!(ecu_instance.communication_controllers().count(), 3);
222 }
223}