a653rs/apex/error.rs
1/// bindings for ARINC653P1-5 3.8 health monitoring
2pub mod basic {
3 use crate::apex::process::basic::*;
4 use crate::apex::types::basic::*;
5
6 /// ARINC653P1-5 3.8.1 Maximum message size in bytes
7 pub const MAX_ERROR_MESSAGE_SIZE: usize = 128;
8
9 /// ARINC653P1-5 3.8.1
10 pub type ErrorMessageSize = ApexInteger;
11 /// ARINC653P1-5 3.8.1
12 pub type ErrorMessage = [ApexByte; MAX_ERROR_MESSAGE_SIZE];
13
14 /// ARINC653P1-5 3.8.1 Process level error
15 #[repr(u32)]
16 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
17 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18 #[cfg_attr(feature = "strum", derive(strum::FromRepr))]
19 pub enum ErrorCode {
20 DeadlineMissed = 0,
21 /// error raised by [raise_application_error](crate::prelude::ApexErrorP4Ext::raise_application_error)
22 ApplicationError = 1,
23 NumericError = 2,
24 /// unallowed syscall / OS request
25 IllegalRequest = 3,
26 StackOverflow = 4,
27 MemoryViolation = 5,
28 /// I/O error
29 HardwareFault = 6,
30 /// info for saving data before power off
31 PowerFail = 7,
32 }
33
34 /// ARINC653P1-5 3.8.1
35 #[derive(Debug, Clone, PartialEq, Eq)]
36 pub struct ErrorStatus {
37 /// related implementation dependent address
38 pub failed_address: SystemAddress,
39 pub failed_process_id: ProcessId,
40 pub error_code: ErrorCode,
41 /// error message length
42 pub length: ErrorMessageSize,
43 pub message: ErrorMessage,
44 }
45
46 /// ARINC653P1-5 3.8.1
47 #[repr(u32)]
48 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
49 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50 #[cfg_attr(feature = "strum", derive(strum::FromRepr))]
51 pub enum ErrorHandlerConcurrencyControl {
52 /// processes are paused when error handler is active
53 ProcessesPause = 0,
54 /// processes run parallel to error handler
55 ProcessesScheduled = 1,
56 }
57
58 /// ARINC653P4 3.8.2 required functions for health monitoring functionality
59 pub trait ApexErrorP4 {
60 /// APEX653P4 3.8.2.1 report message to health monitor
61 ///
62 /// # Errors
63 /// - [ErrorReturnCode::InvalidParam]: `message` is too large
64 fn report_application_message(message: &[ApexByte]) -> Result<(), ErrorReturnCode>;
65
66 /// APEX653P4 3.8.2.4 trigger error handler process
67 ///
68 /// # Errors
69 /// - [ErrorReturnCode::InvalidParam]: `message` is larger than [MAX_ERROR_MESSAGE_SIZE]
70 /// - [ErrorReturnCode::InvalidParam]: `error_code` is not [ErrorCode::ApplicationError]
71 fn raise_application_error(
72 error_code: ErrorCode,
73 message: &[ApexByte],
74 ) -> Result<(), ErrorReturnCode>;
75 }
76
77 /// ARINC653P1-5 3.8.2 required functions for health monitoring functionality
78 pub trait ApexErrorP1 {
79 /// APEX653P1-5 3.8.2.2
80 ///
81 /// # Errors
82 /// - [ErrorReturnCode::NoAction]: error handler exists already
83 /// - [ErrorReturnCode::InvalidConfig]: not enough memory is available
84 /// - [ErrorReturnCode::InvalidConfig]: `stack_size` is too large
85 /// - [ErrorReturnCode::InvalidMode]: our current operating mode is [OperatingMode::Normal](crate::prelude::OperatingMode::Normal)
86 fn create_error_handler(
87 entry_point: SystemAddress,
88 stack_size: StackSize,
89 ) -> Result<(), ErrorReturnCode>;
90
91 /// APEX653P1-5 3.8.2.3 get current error status
92 ///
93 /// # Errors
94 /// - [ErrorReturnCode::InvalidConfig]: the calling process is not an error handler
95 /// - [ErrorReturnCode::NoAction]: no error exists right now
96 fn get_error_status() -> Result<ErrorStatus, ErrorReturnCode>;
97
98 /// APEX653P1-5 3.8.2.5
99 ///
100 /// # Errors
101 /// - [ErrorReturnCode::InvalidConfig]: no error handler exists
102 /// - [ErrorReturnCode::InvalidMode]: our current operating mode is [OperatingMode::Normal](crate::prelude::OperatingMode::Normal)
103 fn configure_error_handler(
104 concurrency_control: ErrorHandlerConcurrencyControl,
105 processor_core_id: ProcessorCoreId,
106 ) -> Result<(), ErrorReturnCode>;
107 }
108}
109
110/// abstraction for ARINC653P1-5 3.8 health monitoring
111pub mod abstraction {
112 use super::basic::{ApexErrorP1, ApexErrorP4};
113 // Reexport important basic-types for downstream-user
114 pub use super::basic::{
115 ErrorCode, ErrorHandlerConcurrencyControl, ErrorStatus, MAX_ERROR_MESSAGE_SIZE,
116 };
117 use crate::prelude::*;
118
119 /// Free extra functions for implementer of [ApexErrorP4]
120 pub trait ApexErrorP4Ext: ApexErrorP4 {
121 /// report message to health monitor
122 ///
123 /// # Errors
124 /// - [Error::InvalidParam]: `message` is too large
125 fn report_application_message(message: &[ApexByte]) -> Result<(), Error>;
126
127 /// trigger error handler process
128 ///
129 /// # Errors
130 /// - [Error::InvalidParam]: `message` is larger than [MAX_ERROR_MESSAGE_SIZE]
131 fn raise_application_error(message: &[ApexByte]) -> Result<(), Error>;
132 }
133
134 /// Free extra functions for implementer of [ApexErrorP1]
135 pub trait ApexErrorP1Ext: ApexErrorP1 {
136 /// get current error status
137 ///
138 /// # Errors
139 /// - [Error::InvalidConfig]: the calling process is not an error handler
140 /// - [Error::NoAction]: no error exists right now
141 fn error_status() -> Result<ErrorStatus, Error>;
142 }
143
144 impl<E: ApexErrorP4> ApexErrorP4Ext for E {
145 fn report_application_message(message: &[ApexByte]) -> Result<(), Error> {
146 E::report_application_message(message.validate_write(MAX_ERROR_MESSAGE_SIZE as u32)?)?;
147 Ok(())
148 }
149
150 fn raise_application_error(message: &[ApexByte]) -> Result<(), Error> {
151 E::raise_application_error(
152 ErrorCode::ApplicationError,
153 message.validate_write(MAX_ERROR_MESSAGE_SIZE as u32)?,
154 )?;
155 Ok(())
156 }
157 }
158
159 impl<E: ApexErrorP1> ApexErrorP1Ext for E {
160 fn error_status() -> Result<ErrorStatus, Error> {
161 Ok(E::get_error_status()?)
162 }
163 }
164
165 impl<E: ApexErrorP1> StartContext<E> {
166 /// # Errors
167 /// - [Error::NoAction]: error handler exists already
168 /// - [Error::InvalidConfig]: not enough memory is available
169 /// - [Error::InvalidConfig]: `stack_size` is too large
170 pub fn set_error_handler(
171 &self,
172 entry_point: SystemAddress,
173 stack_size: StackSize,
174 ) -> Result<(), Error> {
175 E::create_error_handler(entry_point, stack_size)?;
176 Ok(())
177 }
178
179 /// # Errors
180 /// - [Error::InvalidConfig]: no error handler exists
181 pub fn configure_error_handler(
182 &self,
183 concurrency_control: ErrorHandlerConcurrencyControl,
184 processor_core_id: ProcessorCoreId,
185 ) -> Result<(), Error> {
186 E::configure_error_handler(concurrency_control, processor_core_id)?;
187 Ok(())
188 }
189 }
190}