![]() |
AVR SD Safety Framework 1.0.0
|
This page provides additional guidance on using the Safety Framework APIs beyond the standard documentation. It highlights advanced usage options to enhance flexibility for specific applications.
When creating schedules for TM_Startup, the total duration of all Tasks in the schedule is intended to be slightly less than the configured WDT timeout to ensure timely execution and clearing within the Fault Detection Time Interval (FDTI). However, if the schedule is longer than FDTI, the T_HandleWatchdog Task can be included in the schedule one or more times.
The example below shows T_HandleWatchdog inserted between application Tasks in start-up and Mission Mode schedules.
The selectable WDT timeouts have low granularity, which can make it difficult to match the configured WWDT_CLOSED_WINDOW and WWDT_OPEN_WINDOW values to a specific Application Fault Detection Time Interval (FDTI). To effectively increase the resolution of the Watchdog timer, the WDT Timeout can instead be configured to half of or less than the FDTI, where the Application schedule used in TM_Scheduler includes one or more additional T_HandleWatchdog calls. Another option is calling the TM_Scheduler multiple times within FDTI.
With this approach, the values used in WWDT_CLOSED_WINDOW and WWDT_OPEN_WINDOW can be tuned and accumulated such that it is ensured that WDT will time out within an FDTI suitable for the Application.
The example below targets an example Application FDTI of approximately 6 ms. Accumulating two WWDT periods with the given config satisfies the 6 ms FDTI while each individual timeout remains within the available WDT granularity.
The straightforward usage of the TM_Scheduler is to provide a constant schedule that is executed each Fault Detection Time Interval (FDTI) period. However, it is also possible to switch between two or more constant schedules or even update the schedule dynamically as required by the Application. This requires the addition of an application-specific Schedule Manager. A dynamic schedule array can have a fixed length where a NULL pointer is added for unused indices since TM_Scheduler will just skip them.
Examples:
The Framework offers a few optional Tasks that can be included in the Application Startup Schedule when running TM_Startup. For the Startup Schedule, T_HandleResetReason and T_HandleNotificationErrors are intended to be included. However, the ordering in the schedule may depend on the Error Handler configuration and application requirements.
If any application-specific error handling depends on the Application to be initialized by e.g. sending a message, all relevant Pre-startup and Startup Error IDs can be configured to NOTIFICATION criticality, and T_HandleNotificationErrors called last in the schedule to handle them before exiting Safe State. Alternatively, they can be set to NON_CRITICAL or CRITICAL to be handled immediately. If no Error IDs are set to NOTIFICATION, the Task can be omitted.
Likewise, if handling of the reset reason requires Application initialization, T_HandleResetReason can be called after the Application initialization Tasks in the schedule. If handling the reset reason is not required by the Application, this Task can be omitted, but requires manual clearing of persistent memory, see T_HandleResetReason for more information. Please note that handling the reset reason is highly recommended.
The example below places application-specific initialization Tasks first, then T_HandleResetReason (so it can rely on the initialized Application), and finally T_HandleNotificationErrors last to handle any NOTIFICATION errors before exiting the Safe State. The ordering should be adapted to the Error Handler configuration and application requirements.
The Framework offers a few optional Tasks that can be included in the Application Schedule when running TM_Scheduler. This includes T_HandleNotificationErrors, T_RunNextLatentFaultDiag and T_EnterIdleSleep.
The T_HandleNotificationErrors Task is intended to be scheduled regularly to ensure all NOTIFICATION errors are eventually handled. However, how often it is called depends on the desired definition of NOTIFICATION errors. They can either be treated as errors that must be handled within FDTI, but not immediately, by including the Task each schedule window or as errors that should be handled whenever the Application has time by only including it occasionally. If choosing the latter, using an increased NOTIFICATION_LOG_SIZE value is recommended. If no Error IDs are set to NOTIFICATION, the Task can be omitted.
The T_RunNextLatentFaultDiag Task is provided for applications that require run-time detection of latent faults (faults occurring within the safety mechanisms themselves). Normally, such run-time diagnostics are unnecessary if the Application includes sufficiently frequent device resets (e.g., one driving cycle in automotive applications), since all latent fault diagnostics are executed at startup. However, applications with high up-time can benefit from run-time latent fault detection.
The Task executes one latent fault diagnostic each time it is called. Due to varying execution times, particularly when considering diagnostics that are disabled by default, scheduling the Task as-is can be challenging. It is primarily provided as a reference implementation to demonstrate possible usage. In general, the Task is intended to run at a very low frequency, ensuring that all diagnostics complete within the "Latent Fault Detection Time Interval (LFDTI)" of the Application, which is typically in the order of hours.
The T_EnterIdleSleep Task is provided for applications that have a long FDTI relative to each schedule window. In other words, the Task can be added at the end of a schedule to Idle sleep before starting the next schedule to reduce power consumption. Since the Synchronous Watchdog (SWDT) stops counting while in Idle sleep, the Task can be scheduled with a short DUR_ENTER_IDLE_SLEEP value. It is up to the Application to ensure a wake-up source that starts the next schedule within FDTI. Since the CRCSCAN can only run on Flash memory in Idle sleep, the Task is also intended to optionally start this action to eventually perform a full scan of a Flash section.
The CRCSCAN peripheral can be used in Manual mode to perform hardware accelerated CRC computation on Application data to detect data corruption. It is recommended to use this on any applicable Application data, such as data transfers, EEPROM data validation or calibration data using the APIs provided in the Checksum Manager.
The example below shows an application-specific Task that verifies a range of EEPROM data by feeding it into a Manual Mode CRC-16 calculation and comparing the result against a known-good reference checksum, reporting the outcome to the Error Handler. See MW_StartCrcManualMode, MW_FeedCrcManualMode and MW_EndCrcManualMode for the CRC algorithms, bit widths and behavior.
This example shows how the manual CRCSCAN APIs can be used to validate received messages:
To validate expected/correct device configuration after Special Function Registers (SFR) initialization of all peripherals, the CRCSCAN can be used in Manual mode to read the values of all relevant SFRs to generate a CRC checksum.
It is recommended to use an external oscillator as either the main clock or as a reference clock in the CFM or CFD that monitors the main clock. However, since this is Application specific, the device is initialized using only internal oscillators in T_InitSafetySystem. It is recommended that the Application startup schedule includes Tasks that configures and enables the external oscillator, while also reconfiguring the CFMs and CFDs to account for this source once the oscillator is stable. Note that CFM and CFD should be disabled while switching clock sources. The free CFM and CFD resource can either be configured to monitor the same clock signals redundantly, or used for Application specific monitoring.
Refer to the Concept for Clock chapter in the Device Safety Manual to see the intended clock configurations used in the examples below.
The example below shows an application specific task that enables an external 32 kHz oscillator and reassigns the CFM channels to use it as a measurement reference.
If INIT_VMON_ALWAYS_ON is set to DISABLED to reduce power consumption, the VREG Monitor (VMON) will be turned off when going into Standby or Power-down sleep modes. As an additional safety mechanism, the VMON is disabled (VDIS) flag in the SLPCTRL.INTFLAGS register may be set when this occurs. Normally, this may trigger a SLPCTRL interrupt and may result in an ERRCTRL error after wake. To avoid this, the VDIS bit in the SLPCTRL.INTCTRL register should be cleared.
If INIT_VMON_FULL_POWER_MODE is set to DISABLED (Auto Mode), the VMON Sleep Entry (VSLP) flag in the SLPCTRL.INTFLAGS register may be set when entering Standby or Power-down sleep. The flag may also be set when switching the main clock source to OSC32K or XOSC32K while the VMON is enabled. This may also trigger a SLPCTRL interrupt and may result in an ERRCTRL error after wake.
To avoid this, the VSLP bit in the SLPCTRL.INTCTRL register should be cleared.
In either case, the VREGWARN error channel should be configured to NOTIFICATION severity using the ERRCTRL.ESCVREGWARN register in the Application Shutdown Task called by TM_Shutdown.
Some diagnostics provided can optionally be included or excluded from the Framework Tasks, see DIAG_STARTUP_CFD0, DIAG_STARTUP_CFD1, DIAG_STARTUP_ERRCH_CFD0 and DIAG_STARTUP_ERRCH_CFD1.
The CFD error injection takes in the range of approximately 300 µs - 600 µs to complete and has therefore been split into begin and end diagnostic functions. There is no built-in mechanism for knowing whether the error injection failed, and it is left to the Application to ensure sufficient time separation before calling the end API. This can be done by calling the end API in an application-specific task included in the Application Startup Schedule that runs after two CFD measurement periods have completed.
If the Application requirements permit it, the INIT_REDUNDANT_CFD setting can be enabled instead of performing error injection. In that case, it is recommended to enable DIAG_STARTUP_ERRCH_CFD0 and DIAG_STARTUP_ERRCH_CFD1.
If the Application only uses CFD0 (to monitor the main clock), it is still recommended to enable INIT_REDUNDANT_CFD while the error injection diagnostic is performed to ensure that CFD1 monitors the main clock while CFD0 is not. An application-specific Task in the Application Startup Schedule can disable CFD1 after ending the CFD0 diagnostic.
If the Application requires using CFD1 to monitor another clock, both CFD0 and CFD1 error injection diagnostics should be run. If both diagnostics are enabled in the Run Startup Diagnostics Task, both diagnostics will be started in parallel. During this time, no CFD is monitoring the main clock. While still in a Safe State, if this is not deemed acceptable, the INIT_REDUNDANT_CFD setting can be enabled and only DIAG_STARTUP_CFD0 set to enabled. In this configuration, the CFD1 is monitoring the main clock while the CFD0 is not. Once the application-specific Task in the Application Startup Schedule completes the diagnostic, it can begin the CFD1 diagnostic. Later in the schedule, the CFD1 diagnostic can be completed, and CFD0 and CFD1 can be re-configured as required by the Application.
Some diagnostics provided can optionally be included or excluded from the Framework Tasks, see DIAG_PERIODIC_CFD0, DIAG_PERIODIC_CFD1, DIAG_PERIODIC_ERRCH_CFD0 and DIAG_PERIODIC_ERRCH_CFD1.
Please see Using CFD diagnostics in Startup first for necessary context. If the Application requires latent fault detection while in Mission Mode and does not use the redundant CFD1 and/or CFM1 enabled by INIT_REDUNDANT_CFD and INIT_REDUNDANT_CFM, the provided error injection diagnostics can be enabled. However, this requires careful consideration.
The Run Next Latent Diagnostic Task only starts the CFDn diagnostic. It is the responsibility of the Application to ensure that the diagnostic is completed. This can be achieved by either scheduling an application-specific Task in the Application Schedule that ends it after sufficient time has passed, or use a timer resource to generate an interrupt once the diagnostic is complete. If not ended correctly, the CFD mechanism is effectively disabled.
Since the device is not in a Safe State, it can be considered a risk to disable the CFD or CFM monitoring the main clock while performing the error injection diagnostic. However, if done correctly, both diagnostics should still be completed within a minimum FDTI of 1 ms. As an additional measure, the CFM0 can monitor the main clock while CFD0 is disabled and vice versa, as long as both diagnostics are not run at the same time. However, it is still recommended to consider setting the other CFD or CFM to monitor the main clock for the duration of the diagnostic. In this case, the diagnostic of one CFD should be completed before starting a diagnostic of the other. This is automatically prevented if the Run Next Latent Diagnostic Task is scheduled infrequently relative to the Application FDTI.
Some diagnostics provided can optionally be included or excluded from the Framework Tasks, see DIAG_PERIODIC_WDT_COUNT.
The WDT count diagnostic has a relatively small impact on Latent Fault coverage metrics. Moreover, WDT is a safety mechanism that has a dedicated monitor and a redundant Synchronous Watchdog, making any faults in the WDT latent faults. The WDT expire diagnostic is run at startup and also detects a stuck WDT counter. For this reason, the Application may not require running the count diagnostic within every FDTI period.
If enabled, it is the responsibility of the Application to begin the diagnostic, while the T_HandleWatchdog Task ends it. This is to avoid busy-waiting for the WDT counter register to synchronize every 4th 32kHz WDT clock tick. The Application must ensure a sufficient time separation of at least 4 WDT clocks with tolerance from beginning the diagnostic to ending it. This can be achieved by including an application-specific Task that calls MW_DiagWdtCountBegin in the beginning of the Application Startup Schedule and Application Schedule. The diagnostic can also be initiated in an ISR.
During shutdown, TM_Shutdown enters a Safe State, reconfigures the Watchdogs and then loops: it enters Standby or Power-Down sleep, wakes on an interrupt, optionally clears the Watchdogs and re-enters sleep. The loop ends only when an application-specific interrupt handler requests an exit, which restarts the device. See TM_Shutdown for the full sequence. Since application-specific interrupt handlers are expected to service the watchdogs through TM_ShutdownRequestWatchdogs and request exit through TM_ShutdownRequestExit, the choice of wake-up sources determines how the watchdogs and exit conditions are handled.
Because the device re-enters sleep after every wake-up, multiple unrelated wake-up sources are well behaved. The Watchdog Timer (WDT) continues to count in sleep, so it must be cleared before the configured SHUTDOWN_WDT_DURATION expires, which is why a periodic wake-up is recommended. The Synchronous Watchdog (SWDT), by contrast, does not count in any sleep mode and resumes from its retained value on each wake-up. However, it cannot be disabled once enabled, so TM_Shutdown configures it to its maximum non-windowed timeout of 0xFFFF peripheral cycles, which is approximately 3.3 ms at 20 MHz. Only handling watchdogs in a periodic wake-up should be enough in most use cases. However, if it is assumed that the application will spend more than 0xFFFF main clock cycles awake in other interrupts, handling the watchdogs in every wake-up interrupt should be considered.
The Framework is designed to accommodate the following use cases, ordered from the simplest configuration to the more complex ones:
Both request APIs set a flag that TM_Shutdown reads once per shutdown cycle, so a request issued while the device is already awake can be missed for the current cycle.
A design pattern that mitigates these concerns is to let asynchronous interrupt handlers set software flags, and to let the periodic interrupt handler read them. The periodic handler then acts as a small schedule for acting on recorded events, requesting the exit and clearing the Watchdogs from a single, predictable point in time. The cost is that an event is only acted upon at the next periodic wake-up.
Use case 1: watchdog disabled
Setting SHUTDOWN_WDT_DURATION to WDT_TIMEOUT_OFF disables the WDT during shutdown, so no periodic wake-up is needed and the device can sleep indefinitely until an exit is requested. When the WDT is disabled, the device can get stuck in sleep, so an external reset signal is recommended. With an external reset available, the application may not need any interrupt handler at all if no interrupts are expected. If the application is still expected to wake-up multiple times while sleeping, TM_ShutdownRequestWatchdogs should be called to clear the SWDT through those interrupts. Alternatively, the application can also prevent the SWDT from creating any interrupts or resetting the device by reconfiguring the SWDT and ERRCTRL similarly to how it is accomplished for SLPCTRL in Using VMON in Deep Sleep.
Use case 2: periodic wake-up only
Use case 3: periodic wake-up with unrelated wake-up sources
The PIT ISR from use case 2 is unchanged.
Use case 4: asynchronous exit request
Use case 5: immediate restart from an interrupt handler
By default, SHUTDOWN_SAFE_STATE is enabled, so TM_Shutdown enters the Safe State by floating (tri-stating) all I/O pins before entering shutdown sleep. This disables output drivers and internal pull-ups. If the application needs to drive a pin while sleeping SHUTDOWN_SAFE_STATE can be disabled.
When it is disabled, it is the responsibility of the application to ensure safe operation before entering sleep. This can be achieved by manually tri-stating all I/O pins and then configuring the output pin in the application-specific shutdown Task passed to TM_Shutdown.
Beyond selecting the sleep mode with SHUTDOWN_POWER_DOWN, several supply-supervision safety mechanisms remain active in sleep and can be relaxed to reduce power consumption further. Since these mechanisms exist to detect unsafe supply conditions, relaxing them trades safety coverage for lower power and should only be done while in a Safe State and with an external reset source available.
The Voltage Regulator Monitor (VMON) is controlled through Framework configuration. Setting INIT_VMON_ALWAYS_ON to DISABLED turns the VMON off in Standby and Power-Down sleep, which requires the handling described in Using VMON in Deep Sleep. When the VMON is kept enabled, INIT_VMON_FULL_POWER_MODE selects between full power mode (faster wake-up) and power-saving mode (lower consumption). Setting it to DISABLED uses Auto Mode, which also requires the handling described in Using VMON in Deep Sleep.
The Brown-out Detector (BOD) sleep settings should be configured through BODCFG user fuses selected based on the application requirements. If permissible, it can be disabled entirely while sleeping.
The Watchdog Timer (WDT) sleep settings should be configured through SHUTDOWN_WDT_DURATION, by setting it to WDT_TIMEOUT_OFF it will be disabled while sleeping, as further described in Configuring Wake-up Sources and Watchdog Handling in Shutdown Sleep. If the application requires the WDT to be enabled while sleeping, another power-saving measure could be to disable the WDT monitor in sleep by configuring the WDTMON bit field in the SYSCFG1 fuse to SLEEP.
If a single-bit ECC error (ECC1) is detected in RAM, Flash or EEPROM, the data returned on the read access is automatically corrected by the ECC hardware. However, the erroneous bit in the stored word remains flipped, meaning that reading the same location again will trigger a new ECC1 error. This increases the risk that a later bit error in the same protected word will result in a non-correctable ECC2 error. If the failure is transient, meaning the memory cell is not permanently stuck, it can therefore be desirable for the Application to attempt repair of the affected memory location.
In general, an ECC1 error can correspond either to flipped data bits or to flipped ECC parity bits. If the issue is in the address portion protected by ECC, the hardware instead reports an ECC2 error, since the protected address no longer matches the data, meaning data has effectively been written to or read from the wrong location. In principle, repair of an ECC1 error is therefore done by reading the ECC-corrected value and writing it back to the same location in memory. If the issue is in the ECC parity bits rather than the data itself, rewriting the corrected word will also regenerate the correct ECC parity.
However, in practice, repair of ECC1 errors is Application specific and depends on the memory type, the memory architecture and whether the Application deems it safe to rewrite the affected location.
In general, run-time writes to Flash are discouraged. However, correcting EEPROM data is considered more feasible. In both cases, the same general principle applies. When an ECC error is detected, the NVMCTRL.ADDR register is frozen for as long as the ECC error flag remains set. This allows the Application to determine which NVM location triggered the error. If the ECC flag is cleared too soon, the register will resume updating on subsequent NVM accesses and instruction fetches, and the error context is lost. If a single-bit NVM ECC error is reported, either FECC1 (Flash) or EECC1 (EEPROM), the ADDR register can be used to determine the affected Flash or EEPROM location. The corrected value can then be read from that location and written back using the Flash or EEPROM write APIs available to the Application.
For RAM, the same principle applies, but the implementation depends on the RAM word size of the device. RAMCTRL.ADDR reports the address of the failing location in the data space, so it can be used directly as a pointer to the affected RAM word. The corrected value can then be read from RAM and written back to the same word. When the location is read, the value returned is already corrected by the ECC hardware, and the subsequent write-back refreshes the stored data and ECC parity.
For devices where each RAM word corresponds to one byte, the address can be used directly as a byte address. For devices where each protected RAM word spans multiple bytes, the reported address is word-aligned and identifies the start of the affected word. A pointer to the full word can therefore be used to read and write back the entire corrected word, removing the need to decode which specific byte triggered the ECC1 error.
If a rewrite succeeds, reading the same location again should no longer trigger ECC1. If an ECC2 error is reported at any point, the condition should be treated as non-correctable and the repair attempt considered failed.
The following example is given for reference only and shows one possible way to attempt repair of a RAM ECC1 error: