autosar_data_abstraction/communication/physical_channel/flexray.rs
1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 communication::{
4 AbstractPhysicalChannel, FlexrayCluster, FlexrayCommunicationConnector, FlexrayCommunicationCycle,
5 FlexrayFrame, FlexrayFrameTriggering, PhysicalChannel,
6 },
7};
8use autosar_data::{Element, ElementName, EnumItem};
9
10/// the `FlexrayPhysicalChannel` represents either channel A or B of Flexray cluster
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct FlexrayPhysicalChannel(Element);
13abstraction_element!(FlexrayPhysicalChannel, FlexrayPhysicalChannel);
14impl IdentifiableAbstractionElement for FlexrayPhysicalChannel {}
15
16impl FlexrayPhysicalChannel {
17 /// get the channel name of a `FlexrayPhysicalChannel`
18 #[must_use]
19 pub fn channel_name(&self) -> Option<FlexrayChannelName> {
20 let cn = self
21 .0
22 .get_sub_element(ElementName::ChannelName)?
23 .character_data()?
24 .enum_value()?;
25 match cn {
26 EnumItem::ChannelA => Some(FlexrayChannelName::A),
27 EnumItem::ChannelB => Some(FlexrayChannelName::B),
28 _ => None,
29 }
30 }
31
32 /// get the cluster containing this physical channel
33 ///
34 /// # Example
35 ///
36 /// ```
37 /// # use autosar_data::*;
38 /// # use autosar_data_abstraction::*;
39 /// # use autosar_data_abstraction::communication::*;
40 /// # fn main() -> Result<(), AutosarAbstractionError> {
41 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
42 /// # let package = model.get_or_create_package("/pkg1")?;
43 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
44 /// # let cluster = system.create_flexray_cluster("Cluster", &package, &FlexrayClusterSettings::default())?;
45 /// let channel = cluster.create_physical_channel("Channel", FlexrayChannelName::A)?;
46 /// let cluster_2 = channel.cluster()?;
47 /// assert_eq!(cluster, cluster_2);
48 /// # Ok(())}
49 /// ```
50 ///
51 /// # Errors
52 ///
53 /// - [`AutosarAbstractionError::ModelError`] An error occurred in the Autosar model
54 pub fn cluster(&self) -> Result<FlexrayCluster, AutosarAbstractionError> {
55 let cluster_elem = self.0.named_parent()?.unwrap();
56 FlexrayCluster::try_from(cluster_elem)
57 }
58
59 /// add a trigger for a flexray frame in this physical channel
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// # use autosar_data::*;
65 /// # use autosar_data_abstraction::*;
66 /// # use autosar_data_abstraction::communication::*;
67 /// # fn main() -> Result<(), AutosarAbstractionError> {
68 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
69 /// # let package = model.get_or_create_package("/pkg1")?;
70 /// # let frame_package = model.get_or_create_package("/Frames")?;
71 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
72 /// # let cluster = system.create_flexray_cluster("Cluster", &package, &FlexrayClusterSettings::default())?;
73 /// let channel = cluster.create_physical_channel("Channel", FlexrayChannelName::A)?;
74 /// let frame = system.create_flexray_frame("Frame", &frame_package, 64)?;
75 /// let timing = FlexrayCommunicationCycle::Repetition {base_cycle: 1, cycle_repetition: CycleRepetition::C1};
76 /// channel.trigger_frame(&frame, 1, &timing)?;
77 /// # Ok(())}
78 /// ```
79 pub fn trigger_frame(
80 &self,
81 frame: &FlexrayFrame,
82 slot_id: u16,
83 timing: &FlexrayCommunicationCycle,
84 ) -> Result<FlexrayFrameTriggering, AutosarAbstractionError> {
85 FlexrayFrameTriggering::new(self, frame, slot_id, timing)
86 }
87
88 /// iterate over all frame triggerings of this physical channel
89 ///
90 /// # Example
91 ///
92 /// ```
93 /// # use autosar_data::*;
94 /// # use autosar_data_abstraction::{*, communication::*};
95 /// # fn main() -> Result<(), AutosarAbstractionError> {
96 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
97 /// # let package = model.get_or_create_package("/pkg1")?;
98 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
99 /// # let cluster = system.create_flexray_cluster("Cluster", &package, &FlexrayClusterSettings::default())?;
100 /// # let channel = cluster.create_physical_channel("Channel", FlexrayChannelName::A)?;
101 /// # let frame = system.create_flexray_frame("Frame", &package, 64)?;
102 /// # let timing = FlexrayCommunicationCycle::Repetition {base_cycle: 1, cycle_repetition: CycleRepetition::C1};
103 /// channel.trigger_frame(&frame, 1, &timing)?;
104 /// for ft in channel.frame_triggerings() {
105 /// println!("Frame triggering: {:?}", ft);
106 /// }
107 /// # assert_eq!(channel.frame_triggerings().count(), 1);
108 /// # Ok(())}
109 pub fn frame_triggerings(&self) -> impl Iterator<Item = FlexrayFrameTriggering> + Send + use<> {
110 self.0
111 .get_sub_element(ElementName::FrameTriggerings)
112 .into_iter()
113 .flat_map(|elem| elem.sub_elements())
114 .filter_map(|elem| FlexrayFrameTriggering::try_from(elem).ok())
115 }
116}
117
118impl From<FlexrayPhysicalChannel> for PhysicalChannel {
119 fn from(channel: FlexrayPhysicalChannel) -> Self {
120 PhysicalChannel::Flexray(channel)
121 }
122}
123
124impl AbstractPhysicalChannel for FlexrayPhysicalChannel {
125 type CommunicationConnectorType = FlexrayCommunicationConnector;
126}
127
128//##################################################################
129
130/// A flexray cluster may contain the channels A and/or B.
131///
132/// This enum is an abstraction over the \<CHANNEL-NAME\> element.
133#[derive(Debug, Clone, Copy, PartialEq, Eq)]
134pub enum FlexrayChannelName {
135 /// Channel A
136 A,
137 /// Channel B
138 B,
139}
140
141//##################################################################
142
143#[cfg(test)]
144mod test {
145 use crate::{
146 AbstractionElement, AutosarModelAbstraction, SystemCategory,
147 communication::{FlexrayChannelName, FlexrayClusterSettings},
148 };
149 use autosar_data::{AutosarVersion, ElementName};
150
151 #[test]
152 fn channel() {
153 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
154 let pkg = model.get_or_create_package("/test").unwrap();
155 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
156 let settings = FlexrayClusterSettings::default();
157 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
158
159 let channel = cluster
160 .create_physical_channel("channel_name", FlexrayChannelName::A)
161 .unwrap();
162 let c2 = channel.cluster().unwrap();
163 assert_eq!(cluster, c2);
164
165 let wrapped_channel: super::PhysicalChannel = channel.clone().into();
166 assert_eq!(wrapped_channel, super::PhysicalChannel::Flexray(channel.clone()));
167
168 // damage the channel info by removing the channel name
169 let elem_channelname = channel.element().get_sub_element(ElementName::ChannelName).unwrap();
170 elem_channelname.remove_character_data().unwrap();
171 assert!(channel.channel_name().is_none());
172
173 // now there is no longer a channel A
174 let channel2 = cluster.create_physical_channel("channel_name2", FlexrayChannelName::A);
175 assert!(channel2.is_ok());
176 }
177}