FuSa 8-Bit Libraries Safety Framework
Loading...
Searching...
No Matches
tasks_startup.c
Go to the documentation of this file.
1
22
23// Standard Library Includes
24#include <stdbool.h>
25#include <stdint.h>
26
27// Framework Includes
28#include <define_error_flags.h>
29#include <define_error_ids.h>
31#include <error_handler.h>
38#include <tasks_config.h>
39#include <tasks_startup.h>
41
42// Private function prototypes
43static bool IsPersistentValsUnreliable(void);
44static bool IsPersistentFlagsUnreliable(void);
45static errInjectReset_t ConvertToErrInjReason(uint8_t errInjReasonVal);
46static resetReason_t ConvertToResetReason(uint8_t resetReasonVal);
47static errId_t ConvertToErrId(uint8_t resetErrorIdVal);
48static void ReportPreStartupErrors(bool isSafeIoFault, bool isCpuCompFault, bool isWdtExpFault,
49 bool isSwdtExpFault);
50
52{
53 // Retrieve all error flags from persistent memory
54 const bool isSafeIoFault = MW_GetPersistentFlag(PFLAG_IO_FLOAT_FAULT);
55 const bool isCpuCompFault = MW_GetPersistentFlag(PFLAG_CPU_INJ_FAULT);
56 const bool isWdtExpFault = MW_GetPersistentFlag(PFLAG_WDT_INJ_FAULT);
57 const bool isSwdtExpFault = MW_GetPersistentFlag(PFLAG_SWDT_INJ_FAULT);
58
59 const bool isFlagsUnreliable = IsPersistentFlagsUnreliable();
60
61 // Ensure persistent flags do not interfere with a future reset by clearing them
63
64 if (isFlagsUnreliable)
65 {
67 }
68 else
69 {
70 ReportPreStartupErrors(isSafeIoFault, isCpuCompFault, isWdtExpFault, isSwdtExpFault);
71 }
72}
73
75{
76 errFlag_t flag = ERROR;
77
78 // Enable watchdogs with configured WDT period and SWDT open window + inital closed window
79 flag = InitWatchdogs();
81
82 // Set configured main clock frequency and enable CFD0 and CFM0 to monitor the main clock
83 flag = InitClocks();
85
86 // Configure the severity and I/O float of each error channel and the error controller timeout
87 flag = InitErrorController();
89
90 // Configure interrupt scheduling and enable interrupts for all error channel sources
91 flag = InitInterrupts();
93
94 // Configure the device sleep mode and the internal and external power monitors (VMON and VLM)
95 flag = InitPower();
97
98 // Configure NVM ECC behaviour and the Stack Pointer Limit in RAM
99 flag = InitMemories();
101}
102
104{
105 errFlag_t flag = ERROR;
106
107 // Performs enabled CFM error injections and begins enabled CFD error injections
109
110 /*
111 * The VMON error injection diagnostics have long execution times. To reduce the overall Task
112 * execution time, the diagnostics are initiated while other diagnostics are run concurrently.
113 */
114 flag = MW_DiagVmonOverBegin();
116
117 // Bus parity error injection between CPU and memory (RAM, Flash, EEPROM)
119
120 if (flag == NO_ERROR) // Only complete diagnostic if successfully started
121 {
122 while (MW_IsDiagVmonOverDone() == false)
123 {
124 // The error injection must complete before checking the result of the diagnostic
125 }
126 flag = MW_DiagVmonOverEnd();
128 }
129
130 // Initiate the undervoltage VMON error injection diagnostic to run concurrently
131 flag = MW_DiagVmonUnderBegin();
133
134 // ECC error injection for memory controllers (RAM and NVM)
136
137 // Error injection on ERRCTRL channels without error source diagnostics (SPLIM, EVSYS0/1)
139
140 if (flag == NO_ERROR) // Only complete diagnostic if successfully started
141 {
142 while (MW_IsDiagVmonUnderDone() == false)
143 {
144 // The error injection must complete before checking the result of the diagnostic
145 }
146 flag = MW_DiagVmonUnderEnd();
148 }
149}
150
152{
153 errFlag_t flag = NO_ERROR;
154
155 // Configure the WDT to run in Window mode, but it will only take effect after the next clear
158
159 /* Intentional misra-c2012-2.2/14.3 deviation */
161 {
163 }
164
165 /* Intentional misra-c2012-2.2/14.3 deviation */
167 {
168 flag = MW_DisableForceFloat(); // Release all tri-stated I/O pins and exit Safe State
170 }
171
172 flag = MW_EnableGlobalInterrupts(); // Ensure hardware errors can be reported and handled
174}
175
177{
178 resetInfo_t resetInfo = {
179 .reason = RSTRSN_UNKNOWN,
180 .id = ERRID_NONE,
181 };
182
183 // Retrieve reset reason and Error ID from persistent memory
184 const uint8_t resetReasonVal = MW_GetPersistentVal(PVAL_RESET_REASON);
185 const uint8_t resetErrorIdVal = MW_GetPersistentVal(PVAL_ERRID_REASON);
186
187 const bool isRstReasonUnreliable = IsPersistentValsUnreliable();
188
189 // Ensure persistent values does not interfere with a future reset by clearing them
191
192 if (isRstReasonUnreliable)
193 {
195 }
196 else
197 {
198 resetInfo.reason = ConvertToResetReason(resetReasonVal); // Defaults to unknown if invalid
199
200 if (resetInfo.reason == RSTRSN_SOFTWARE)
201 {
202 // Include which Error ID was reported before the software reset was issued
203 resetInfo.id = ConvertToErrId(resetErrorIdVal); // Defaults to none if invalid
204 }
205
206 // Issue user configurable callback
207 resetReasonCallback(resetInfo);
208 }
209}
210
211// Checks values from persistent memory for reliability
212static bool IsPersistentValsUnreliable(void)
213{
214 // If the reset FSM was corrupted, the true reset reason might have been erroneously overwritten
215 const uint8_t errInjReasonVal = MW_GetPersistentVal(PVAL_ERRINJ_REASON);
216 const errInjectReset_t errInjReason = ConvertToErrInjReason(errInjReasonVal);
217 const bool isFsmStateCorrupted = (errInjReason == ERRINJ_RESET_CORRUPT);
218
219 const bool isValsCorrupted = MW_IsPersistentValsCorrupt();
220
221 return (isFsmStateCorrupted || isValsCorrupted);
222}
223
224// Checks flags from persistent memory for reliability
225static bool IsPersistentFlagsUnreliable(void)
226{
227 /*
228 * Persistent flags are unreliable if any of the following occur:
229 * 1. The flags themselves are corrupted (tested by MW_IsPersistentFlagsCorrupt)
230 * 2. The Pre-Startup Diagnostic FSM reports a corrupt state, leading to potential false
231 * positives/negatives
232 * 3. The persistent values are corrupted meaning that the Pre-Startup Diagnostic FSM state is
233 * unreliable (both 2 and 3 are tested by IsPersistentValsUnreliable)
234 */
235 const bool isValsUnreliable = IsPersistentValsUnreliable();
236 const bool isFlagsCorrupted = MW_IsPersistentFlagsCorrupt();
237
238 return (isValsUnreliable || isFlagsCorrupted);
239}
240
241// Converts and validates an Error Injection Reason value from unsigned int to it's correct type
242static errInjectReset_t ConvertToErrInjReason(uint8_t errInjReasonVal)
243{
244 /* Intentional misra-c2012-10.5 deviation */
245 errInjectReset_t errInjReason = (errInjectReset_t)(errInjReasonVal);
246
247 // Assumes that corrupt is the highest enum value
248 if (errInjReason > ERRINJ_RESET_CORRUPT)
249 {
250 errInjReason = ERRINJ_RESET_CORRUPT;
251 }
252
253 return errInjReason;
254}
255
256// Converts and validates a reset reason value from unsigned int to it's correct type
257static resetReason_t ConvertToResetReason(uint8_t resetReasonVal)
258{
259 /* Intentional misra-c2012-10.5 deviation */
260 resetReason_t resetReason = (resetReason_t)(resetReasonVal);
261
262 if (resetReason >= RSTRSN_MAX)
263 {
264 resetReason = RSTRSN_UNKNOWN; // Defaults to unknown if out of range
265 }
266
267 return resetReason;
268}
269
270// Converts and validates an Error Id value from unsigned int to it's correct type
271static errId_t ConvertToErrId(uint8_t resetErrorIdVal)
272{
273 /* Intentional misra-c2012-10.5 deviation */
274 errId_t resetErrorId = (errId_t)(resetErrorIdVal);
275
276 if (resetErrorId >= ERRID_MAX)
277 {
278 resetErrorId = ERRID_NONE; // Defaults to none if out of range
279 }
280
281 return resetErrorId;
282}
283
284// Reports any faults detected in the pre-startup sequence to the Error Handler
285static void ReportPreStartupErrors(bool isSafeIoFault, bool isCpuCompFault, bool isWdtExpFault,
286 bool isSwdtExpFault)
287{
288 if (isSafeIoFault)
289 {
291 }
292
293 if (isCpuCompFault)
294 {
296 }
297
298 if (isWdtExpFault)
299 {
301 }
302
303 if (isSwdtExpFault)
304 {
306 }
307}
Defines error flag type for indicating detected errors in Middleware services.
errFlag_t
Defines the error flag used by Middleware services to indicate error detection.
@ NO_ERROR
Defines for IDs associated with specific errors.
errId_t
Defines unique Error IDs for reporting system errors to EH_HandleError.
@ ERRID_WWDT_TIMEOUT_VAL
@ ERRID_DIAG_SWDT_EXPIRE
@ ERRID_INIT_WATCHDOGS
@ ERRID_GPR_FLAGS
@ ERRID_DIAG_WDT_EXPIRE
@ ERRID_DIAG_CPU_COMP
@ ERRID_GPR_VALS
@ ERRID_MAX
@ ERRID_INIT_CLOCKS
@ ERRID_NONE
@ ERRID_INIT_INTERRUPTS
@ ERRID_INT_DISABLED
@ ERRID_DIAG_VMON_OVER
@ ERRID_INIT_POWER
@ ERRID_SAFE_IO
@ ERRID_FORCE_FLOAT
@ ERRID_INIT_ERRCTRL
@ ERRID_INIT_MEMORIES
@ ERRID_DIAG_VMON_UNDER
Defines type for storing the reason of a device reset caused by an error injection.
errInjectReset_t
Defines possible reasons for a device reset due to an error injection.
void EH_HandleError(errFlag_t flag, errId_t id)
Handles error based on configured Error ID criticality if the error flag is set.
errFlag_t MW_DisableForceFloat(void)
Disables forced floating (tri-stating) of all I/O pins.
void MW_StartHeartbeat(void)
Starts the Heartbeat output signal.
errFlag_t MW_EnableGlobalInterrupts(void)
Enables global interrupts on the device.
void MW_ClearPersistentVals(void)
Clears all stored persistent values in GPR.
bool MW_GetPersistentFlag(persistentFlag_t flagType)
Reads two redundant bits for each boolean flags in General Purpose Registers (GPR) that is stored for...
bool MW_IsPersistentFlagsCorrupt(void)
Compares two redundant bits for each boolean flags in General Purpose Registers (GPR) and checks if a...
void MW_ClearPersistentFlags(void)
Clears all stored persistent flags in GPR.
uint8_t MW_GetPersistentVal(persistentVal_t valueType)
Reads a value in General Purpose Registers (GPR) that is stored for preserving data between resets.
bool MW_IsPersistentValsCorrupt(void)
Checks if any of the stored persistent values are corrupted.
@ PVAL_RESET_REASON
@ PVAL_ERRINJ_REASON
@ PVAL_ERRID_REASON
@ PFLAG_WDT_INJ_FAULT
@ PFLAG_IO_FLOAT_FAULT
@ PFLAG_CPU_INJ_FAULT
@ PFLAG_SWDT_INJ_FAULT
errFlag_t MW_DiagVmonUnderBegin(void)
Starts error injection diagnostic to detect faults in the VMON undervoltage detector.
errFlag_t MW_DiagVmonOverEnd(void)
Completes error injection diagnostic to detect faults in the VMON overvoltage detector.
errFlag_t MW_DiagVmonUnderEnd(void)
Completes error injection diagnostic to detect faults in the VMON undervoltage detector.
bool MW_IsDiagVmonOverDone(void)
Checks if the VMON overvoltage error injection has been completed.
errFlag_t MW_DiagVmonOverBegin(void)
Starts error injection diagnostic to detect faults in the VMON overvoltage detector.
bool MW_IsDiagVmonUnderDone(void)
Checks if the VMON undervoltage error injection has been completed.
resetReason_t
Type defines for all possible reset sources.
@ RSTRSN_UNKNOWN
@ RSTRSN_SOFTWARE
errFlag_t InitPower(void)
Private function, only exposed for unit testing and should not be called directly.
void T_RunStartupDiagnostics(void)
Runs all enabled startup diagnostics and reports any detected faults to the Error Handler.
void RunStartupDiagParity(void)
Private function, only exposed for unit testing and should not be called directly.
void T_HandlePreStartupErrors(void)
Retrieves and validates stored Pre-startup error flags from persistent memory and reports them to the...
void RunStartupDiagErrorCh(void)
Private function, only exposed for unit testing and should not be called directly.
errFlag_t InitClocks(void)
Private function, only exposed for unit testing and should not be called directly.
errFlag_t InitInterrupts(void)
Private function, only exposed for unit testing and should not be called directly.
void T_StartMissionMode(void)
Transitions the device from Safe State into Mission Mode.
errFlag_t InitWatchdogs(void)
Private function, only exposed for unit testing and should not be called directly.
errFlag_t InitErrorController(void)
Private function, only exposed for unit testing and should not be called directly.
void T_HandleResetReason(void)
Retrieves and validates stored reset info from persistent memory and issues configurable callback for...
void RunStartupDiagEcc(void)
Private function, only exposed for unit testing and should not be called directly.
void RunStartupDiagClock(void)
Private function, only exposed for unit testing and should not be called directly.
void T_InitSafetySystem(void)
Initializes the Safety System according to Assumptions of Use and user configurations.
errFlag_t InitMemories(void)
Private function, only exposed for unit testing and should not be called directly.
#define STRICT_SAFE_STATE
Configures whether to use a strict Safe State to Mission Mode transition in TM_PreStartup and TM_Star...
#define HEARTBEAT_OUTPUT
Enables the heartbeat output signal on an I/O pin before entering Mission Mode.
#define WWDT_OPEN_WINDOW
Configures the Windowed Watchdog Timer (WWDT) Open Window duration in Mission Mode.
#define WWDT_CLOSED_WINDOW
Configures the Windowed Watchdog Timer (WWDT) closed window duration in Mission Mode.
const rstCallback_t resetReasonCallback
Configures the user-configurable callback function used for application specific reset handling in T_...
#define ENABLED
Used to enable optional Task features through macro configurations.
errFlag_t MW_SetWdtTimeout(wdtTimeout_t window, wdtTimeout_t period)
Configures and enables the Watchdog Timer in either Normal or Window mode.
Implements APIs for the Power Manager Diagnostics.
Defines a data structure for storing information about a device reset.
resetReason_t reason
Contains private function prototypes for tasks_startup.h.