autosar_data_abstraction/ecuinstance.rs
1use crate::communication::{
2 CanCommunicationController, CommunicationController, EthernetCommunicationController,
3 FlexrayCommunicationController,
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 create the ECU-INSTANCE
110 pub fn create_flexray_communication_controller(
111 &self,
112 name: &str,
113 ) -> Result<FlexrayCommunicationController, AutosarAbstractionError> {
114 FlexrayCommunicationController::new(name, self)
115 }
116
117 /// return an interator over all communication controllers in this `EcuInstance`
118 ///
119 /// # Example
120 ///
121 /// ```
122 /// # use autosar_data::*;
123 /// # use autosar_data_abstraction::*;
124 /// # fn main() -> Result<(), AutosarAbstractionError> {
125 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
126 /// # let package = model.get_or_create_package("/pkg1")?;
127 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
128 /// let ecu_instance = system.create_ecu_instance("ecu_name", &package)?;
129 /// ecu_instance.create_flexray_communication_controller("FlexrayCtrl")?;
130 /// ecu_instance.create_can_communication_controller("CanCtrl")?;
131 /// for ctrl in ecu_instance.communication_controllers() {
132 /// // ...
133 /// }
134 /// # assert_eq!(ecu_instance.communication_controllers().count(), 2);
135 /// # Ok(())}
136 /// ```
137 pub fn communication_controllers(&self) -> impl Iterator<Item = CommunicationController> + Send + 'static {
138 self.0
139 .get_sub_element(ElementName::CommControllers)
140 .into_iter()
141 .flat_map(|cc| cc.sub_elements())
142 .filter_map(|ccelem| CommunicationController::try_from(ccelem).ok())
143 }
144}
145
146//##################################################################
147
148#[cfg(test)]
149mod test {
150 use crate::*;
151 use autosar_data::AutosarVersion;
152
153 #[test]
154 fn ecu() {
155 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
156 let package = model.get_or_create_package("/pkg1").unwrap();
157 let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
158 let ecu_instance = system.create_ecu_instance("ecu_name", &package).unwrap();
159 ecu_instance
160 .create_flexray_communication_controller("FlexrayCtrl")
161 .unwrap();
162 ecu_instance.create_can_communication_controller("CanCtrl").unwrap();
163 ecu_instance
164 .create_ethernet_communication_controller("EthCtrl", None)
165 .unwrap();
166 assert_eq!(ecu_instance.communication_controllers().count(), 3);
167 }
168}