FuSa 8-Bit Libraries Safety Framework
Loading...
Searching...
No Matches
Main Example

Example main file for demonstrating usage of the Framework Task Managers. More...

Files

file  main_example.h
 Defines configurations used in main_example.c.

Macros

#define STARTUP_SCHEDULE_LEN   3U
 Configures the schedule length of the example Application Startup Schedule.
#define SCHEDULE_LEN   3U
 Configures the schedule length of the example Application Schedule.
#define DUR_UNTIL_NEXT_SCHEDULE   200UL
 Configures the duration in system clock cycles until the first Task in the next example Application schedule is run, after completing the last Task in the previous one.

Functions

static void INIT3_SECTION PreMain (void)
 Runs the Pre-startup Task Manager before entering Main.
int main (void)
 Runs the Startup, Scheduler and optionally Shutdown Task Managers.
 ISR_BADISR_vect ()
 Runs the Interrupts Task Manager to handle interrupt requests without a dedicated ISR.
 ISR_NMI_vect ()
 Runs the Interrupts Task Manager to handle a Non-maskable Interrupt (NMI).
 ISR_BOD_VLM_vect ()
 Runs the Interrupts Task Manager to handle a Brown-out Detector (BOD) interrupt.
 ISR_ERRCTRL_INT_vect ()
 Runs the Interrupts Task Manager to handle a Error Controller (ERRCTRL) channel interrupt.
 ISR_CLKCTRL_INT_vect ()
 Runs the Interrupts Task Manager to handle a Clock Controller (CLKCTRL) interrupt.
 ISR_SLPCTRL_INT_vect ()
 Runs the Interrupts Task Manager to handle a Sleep Controller (SLPCTRL) interrupt.
 ISR_SWDT_INT_vect ()
 Runs the Interrupts Task Manager to handle a Synchronous Watchdog Timer (SWDT) interrupt.
 ISR_NVMCTRL_ERROR_vect ()
 Runs the Interrupts Task Manager to handle a NVM Controller (NVMCTRL) error interrupt.
 ISR_RAMCTRL_INT_vect ()
 Runs the Interrupts Task Manager to handle a RAM Controller (RAMCTRL) error interrupt.
 ISR_CRCSCAN_INT_vect ()
 Runs the Interrupts Task Manager to handle a CRC Scan (CRCSCAN) interrupt.

Variables

 FUSES
 Sets a Framework compatible User Fuses configuration.
 LOCKBITS = LOCKBITS_DEFAULT
 Sets a Memory Sections Access Protection (Lock) Configuration.
bool suspendScheduler = false
 Defines an example boolean for the Application to optionally start the Shutdown sequence.
static const scheduleEntry_t appStartupSchedule [STARTUP_SCHEDULE_LEN]
 Defines an example Application Startup Schedule with optional Tasks.
static const scheduleEntry_t appSchedule [SCHEDULE_LEN]
 Defines an example Application Schedule with optional Tasks.
static const scheduleEntry_t appShutdownTask
 Defines an example Application Shutdown Task schedule entry.

Detailed Description

Example main file for demonstrating usage of the Framework Task Managers.

Version
1.0.0-alpha.1

This file is used as an example to demonstrate how the Task Managers can be invoked from the main-file level. The PreMain function is responsible for running the Pre-startup Task Manager, resulting in multiple device resets before completing the Pre-startup sequence and entering the main function. The main function is responsible for calling the Startup Task Manager, which initializes both the Safety System and the Application, before exiting the Safe State and starting Mission Mode. In Mission Mode, the Scheduler Task Manager is called each Fault Detection Time Interval (FDTI) to manage system Watchdogs and run the Application defined schedule, with optional Tasks provided by the Framework. The Application can optionally suspend the Scheduler to run the Shutdown Task Manager, which will re-enter Safe State and maintain safe deep sleep modes (Standby or Power-Down) until the Application requests ending the Shutdown sequence with a system reset. Any Interrupt Requests (IRQs) related to interrupt vectors regarding errors reported by hardware safety mechanisms have dedicated Interrupt Service Routines (ISRs) that call the appropriate Interrupt Task Manager to handle them. Finally, a Framework compliant configuration for User Fuses are provided, with an interface for locking the device with the Lock Fuse.

Note
To configure the compile-time behaviour of Task Managers and the Tasks they are calling, see tasks_config.h.
To configure the compile-time system error handling behaviour and the Error Handler called by Tasks, see error_handler_config.h.
To more easily demonstrate usage without concrete knowledge of Application requirements and to provide a straightforward overview, this example file and main_example.h are intentionally not MISRA C:2012-compliant. These files are considered out of scope for the deviation record, but the violations are listed here for completeness:
  • The headerfile defines global static arrays for scheduling instead of at block scope, when they are only used inside the main function, violating Rule 8.9, but improves readability in the example. Moreover, it ensures that an accidentally empty schedule array task pointer is initialized to NULL, ensuring well defined behavior.
  • This file uses the standard approach for setting the User Fuses and Lock Fuse on AVR, which is compiler-specific and inherently violates Directive 4.6 and Rules 2.8, 8.4, 8.7 and 21.2.
  • This file defines a file scope boolean that is only used inside the main function, which violates Rules 8.4, 8.7 and 8.9. However, an extern declaration can be added in an Application specific header for testing the example, which would eliminate these violations.
  • This file places a function in a special memory section using compiler-specific language extensions (attribute) which is inherently non-compliant and specifically violates Rule 2.1.
  • This file uses the standard approach for defining ISRs on AVR, which is compiler-specific and inherently violates Rules 2.7, 8.2, 8.4, 8.7 and 21.2.
UML Class Diagrams

UML Activity Diagrams

UML Sequence Diagrams

Macro Definition Documentation

◆ DUR_UNTIL_NEXT_SCHEDULE

#define DUR_UNTIL_NEXT_SCHEDULE   200UL

Configures the duration in system clock cycles until the first Task in the next example Application schedule is run, after completing the last Task in the previous one.

Note
The total duration of all Tasks in the schedule, combined with this value, is intended to be slightly less than the configured Watchdog timeout to ensure timely execution and clearing within Fault Detection Time Interval (FDTI).
This example value is configured with the default configurations in tasks_config.h, particularly values in WWDT_CLOSED_WINDOW, WWDT_OPEN_WINDOW and the default durations used in the example appSchedule. It also assumes DIAG_PERIODIC_WDT_COUNT is set to DISABLED.

Measured WCET: TODO: Default with tolerance: TODO:

Todo
Set the correct value

Definition at line 72 of file main_example.h.

Function Documentation

◆ main()

int main ( void )

Runs the Startup, Scheduler and optionally Shutdown Task Managers.

This example main function demonstrates how TM_Startup can be used with an example appStartupSchedule and how TM_Scheduler can be used with an example appSchedule. In addition it shows that suspendScheduler can optionally be set to true to use TM_Shutdown with an example appShutdownTask.

Note
For usage of the Pre-Startup Task Manager see PreMain.
For usage of the Interrupts Task Manager see each Interrupt Service Routine (ISR) in ISR_BADISR_vect, ISR_NMI_vect, ISR_BOD_VLM_vect, ISR_ERRCTRL_INT_vect ISR_CLKCTRL_INT_vect, ISR_SLPCTRL_INT_vect, ISR_SWDT_INT_vect, ISR_NVMCTRL_ERROR_vect, ISR_RAMCTRL_INT_vect and ISR_CRCSCAN_INT_vect
Return values
EXIT_FAILUREThe TM_Shutdown function returned instead of ending in a device reset.

Definition at line 204 of file main_example.c.

◆ PreMain()

void INIT3_SECTION PreMain ( void )
static

Runs the Pre-startup Task Manager before entering Main.

This function is placed in the .init3 memory section in order to execute the Pre-startup sequence before entering the main function.

Note
See init3 for an overview of the .initN sections.

The TM_PreStartup function is placed in the .init3 section for the following reasons: Since TM_PreStartup is responsible for immediately ensuring that the device is in a Safe State after a reset, it should be called as soon as possible after a reset. However, in order to safely execute code that performs compares with zero and calls other functions, it should run after the .init2 memory section. The Pre-startup sequence involves multiple device resets as a result of performing error injection diagnostics. In order to reduce the execution time of the sequence, the function is called before the .init4 memory section to avoid copying data from Flash to RAM multiple times. However, this leads to certain restrictions for all functions running in .init3, since the full C environment is not initialized.

Warning
Functions called inside .init3 must adhere to restrictions listed in init3.
This function will reset the device as part of normal execution.

Definition at line 180 of file main_example.c.

Variable Documentation

◆ appSchedule

const scheduleEntry_t appSchedule[SCHEDULE_LEN]
static
Initial value:
= {
[2U] = { NULL, 0U }
}
void T_RunNextLatentFaultDiag(void)
Runs a different latent fault diagnostic function each time it is called.
void T_HandleNotificationErrors(void)
Ensures Error IDs with 'NOTIFICATION' criticality are handled.
#define DUR_HANDLE_NOTIFICATION_ERRORS
Configures the run-time duration for T_HandleNotificationErrors in system clock cycles.
#define DUR_RUN_NEXT_LATENT_FAULT_DIAG
Configures the run-time duration for T_RunNextLatentFaultDiag in system clock cycles.

Defines an example Application Schedule with optional Tasks.

This example Application Schedule is used as input to TM_Scheduler to demonstrate usage of an application-specific Schedule. The Schedule is intended to be filled with application-specific Tasks that implements both safety and non-safety related Application requirements, and can optionally include Tasks provided by the Framework.

Each Task in the Schedule is configured with a fixed duration in system clock cycles, ensuring a fixed schedule execution time, to ensure the Watchdog is cleared within FDTI without any additional timing resources. The configured durations must account for the Worst Case Execution Time (WCET), including handling of errors reported by Tasks or through interrupts. The total Application Schedule execution time should be set to be slightly lower than the WDT timeout (with clock tolerances), which is configured using WWDT_CLOSED_WINDOW and WWDT_OPEN_WINDOW.

In this example schedule, optional Tasks are included to ensure that any errId_t reported with NOTIFICATION error criticality is handled within the FDTI, and one latent fault diagnostic is run each schedule window. However, this might not be required for the Application. See tips_and_tricks for information on using the optional Tasks in the Schedule, recommended scheduling order and additional optional Tasks that can be included.

Note
See tips_and_tricks for information on options for having a dynamic or static schedule.

Definition at line 132 of file main_example.h.

◆ appShutdownTask

const scheduleEntry_t appShutdownTask
static
Initial value:
= {
NULL, 0U
}

Defines an example Application Shutdown Task schedule entry.

This example Application Shutdown Task schedule entry is used as input to TM_Shutdown to demonstrate usage. The schedule entry is intended to be set to an application-specific Task that is responsible for making the Application ready for the shutdown procedure. This could include disabling peripherals and external circuits, sending a message or configuring the periodic wakeup source(s) used to manage the watchdog and determine when to exit the Shutdown sequence.

In this example, the schedule entry is set to NULL to skip Task execution, since the implementation is specific to the Application.

Todo
The TM_Shutdown API is not yet implemented and the appShutdownTask is included only to demonstrate future Framework capabilities.

Definition at line 155 of file main_example.h.

◆ appStartupSchedule

const scheduleEntry_t appStartupSchedule[STARTUP_SCHEDULE_LEN]
static
Initial value:
= {
[2U] = { NULL, 0U }
}
void T_HandleResetReason(void)
Retrieves and validates stored reset info from persistent memory and issues configurable callback for...
#define DUR_HANDLE_RESET_REASON
Configures the run-time duration for T_HandleResetReason in system clock cycles.

Defines an example Application Startup Schedule with optional Tasks.

This example Application Startup Schedule is used as input to TM_Startup to demonstrate usage of an application-specific Startup Schedule. The Startup Schedule is intended to be filled with application-specific Tasks that initializes the Application according to both safety and non-safety requirements, and can optionally include Tasks provided by the Framework.

Each Task in the schedule is configured with a fixed duration in system clock cycles, ensuring a fixed Startup sequence execution time. The configured durations must account for Worst Case Execution Time (WCET), including error handling. The total Application Startup Schedule execution time must be accounted for when configuring the INIT_WDT_DURATION.

In this example schedule, optional but recommended Framework Tasks are included to ensure handling of the determined reset reason in T_HandleResetReason and that any errId_t reported with NOTIFICATION error criticality is handled before exiting the Safe State.

Note
Set the resetReasonCallback and notificationErrorCallback configuration for application-specific reset and error handling.
See tips_and_tricks for information on using the optional Tasks in the Startup Schedule, recommended scheduling order and additional optional Tasks that can be included.

Definition at line 100 of file main_example.h.

◆ FUSES

FUSES
Initial value:
= {
.WDTCFG = WINDOW_OFF_gc | PERIOD_OFF_gc,
.BODCFG = LVL_BODLEVEL1_gc | SAMPFREQ_128HZ_gc | ACTIVE_ENABLE_gc | SLEEP_ENABLE_gc,
.SYSCFG0 = FUSE_SYSCFG0_DEFAULT,
.SYSCFG1 = WDTMON_ON_gc | MVSYSCFG_DUAL_gc | SUT_0MS_gc,
.CODESIZE = FUSE_CODESIZE_DEFAULT,
.BOOTSIZE = FUSE_BOOTSIZE_DEFAULT,
.PDICFG = FUSE_PDICFG_DEFAULT,
}

Sets a Framework compatible User Fuses configuration.

This struct is used to write to the User Fuses when programming the device. It is configured to be compatible with Framework requirements:

The Watchdog Timer (WDT) is explicitly not enabled through fuses, since this sets the LOCK bit, preventing reconfiguration of the WDT timeout and mode. The Framework reconfigures the watchdog at multiple stages as part of normal execution flow.

The Brown-out Detector (BOD) configuration follows safety-related best practices by being set to run in Continuous mode, using the Level 1 threshold and is enabled during device sleep. The sample frequency configuration does not have an effect in Continuous mode. The Framework assumes the BOD is initialized when configuring and enabling the Voltage Level Monitor (VLM).

System Configuration 0 is set to default values because these settings are specific to the Application. Enabling automatic CRCSCAN of the Boot section in Flash is recommended, but requires that the expected checksum is added at the end of the Boot section when programming the device. If this is enabled, it is recommended to clear the CRCSCAN Done flag in the Application Startup Schedule.

System Configuration 1 follows safety-related best practices by explicitly enabling the WDT Clock Monitor feature, even while the device is in Standby- or Power-Down sleep mode sleep modes, to ensure detection of a WDT clock source failure. The other settings are specific to the Application and set to default values.

The Flash memory sections settings are specific to the Application and set to default values.

The Program and Debug Interface Disable (PDID) security feature is set to the default value during development, but recommended to be activated to avoid modification of the Flash in the deployed Application.

Definition at line 116 of file main_example.c.

◆ LOCKBITS

LOCKBITS = LOCKBITS_DEFAULT

Sets a Memory Sections Access Protection (Lock) Configuration.

This struct is used to write a Key value to the Lock Fuse when programming the device in order to select whether the device should be locked or unlocked. Locking the device not only prevents Flash access, but also enables several safety-related internal hardware monitors that prevents the Unified Programming Interface (UPDI), On Chip Debugging (OCD) and Design for Test (DFT) systems from affecting device behavior. The Key is set to the default value to prevent the device from being locked during development.

Warning
Modifying the default value will Lock the device. The only way to unlock the device is a Chip Erase, given that PDID is not activated.

Definition at line 140 of file main_example.c.

◆ suspendScheduler

bool suspendScheduler = false

Defines an example boolean for the Application to optionally start the Shutdown sequence.

This boolean is used in the main function example to demonstrate how the Application can exit Mission Mode and start the Shutdown sequence, using TM_Shutdown, by setting it to true. This can be done by an application-specific Task running in the Scheduler or in an Interrupt Service Routine (ISR).

Note
The boolean is not defined statically as it is intended to be declared externally in a headerfile in order to provide access to the Application when testing the example.

Definition at line 154 of file main_example.c.