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}