![]() |
AVR SD Safety Framework 1.0.0
|
This page contains information regarding measurements.
This section describes how execution times are measured for functions in the AVR SD Safety Framework. The measurements are intended as input when selecting Task duration values. They are not formal WCET bounds.
Test conditions are selected by inspecting the source code and identifying a comparatively long relevant path through each function. Configuration-controlled functionality is enabled where it increases the executed work, and early-return paths are avoided unless they represent the relevant measured case.
The measurements cover all Tasks called by the Task Managers and all middleware diagnostic functions. The intervals corresponding to DUR_UNTIL_FIRST_SCHEDULE and DUR_UNTIL_NEXT_SCHEDULE are also measured.
Measurements are performed using the -O1, -O2, -O3 and -Os compiler optimization levels.
Two TCB peripherals configured in cascade mode count system-clock cycles. The timers are started immediately before the measured function and stopped immediately after it returns. The timer start and stop overhead is measured during initialization and subtracted from each result.
The target runs at a configured 20 MHz system clock and uses an explicit default fuse configuration. The compiler, DFP, target device and build environment are identified in the corresponding release notes.
The measurement project is built with TEST. Several configuration options that are compile-time constants in a production build are variables in this build. Their checks are therefore evaluated at run time and may add a small amount of execution time.
The measurement configuration enables all optional startup diagnostics and all entries in the periodic latent-diagnostic queue. Periodic WDT and SWDT count diagnostics are enabled. Error reporting uses NOTIFICATION, and the notification log contains five entries.
Unless stated otherwise in the result table, underlying peripheral error flags are not set and state-dependent error-reporting paths are excluded. The result table identifies the relevant arranged state and any important exclusions.
Each function is called under the configured test conditions and measured once per compiler optimization level. Diagnostic return values and required setup or cleanup operations are checked. A failed diagnostic or measurement setup causes the measurement run to report FAIL.
Functions that intentionally reset the device or otherwise cannot provide a meaningful return measurement are reported as Not measured.
MW_DiagCrcScan is measured from function entry until return with global interrupts and the CRCSCAN ISR enabled. The result includes CRCSCAN setup, Idle sleep, CRC interrupt handling, result verification and cleanup under the fixed test configuration.
MW_ReportDiagCrcDone and T_HandleCrcInterrupt are measured inside the CRCSCAN ISR. ISR entry and exit are therefore excluded from these individual measurements. T_HandleCrcInterrupt is measured for regular Flash-scan completion and diagnostic completion, and the largest result is reported.
T_VerifyFlashIntegrity is not measured because its elapsed time depends on the configured Flash sections, CRC configuration, sleep and interrupt timing.
The result table contains the measurements for -O1, -O2, -O3 and -Os, the maximum measured value and a comment describing the relevant test conditions.
The maximum is the largest valid measurement across the compiler optimization levels. Default Task durations are conservative overestimates based on this value. The selected defaults are provided in tasks_config.h, or in the corresponding example configuration where applicable. The System Integrator should adjust these values for the final application configuration and timing requirements.
The results apply to the documented configuration and measured paths. They do not include application execution between Task Manager calls, unrelated interrupts, scheduling delays or state-dependent error handling unless explicitly stated.
Measurements that include waiting for a hardware diagnostic to complete can vary with peripheral-clock and analog operating conditions.
The measurements do not demonstrate that every feasible execution path has been exercised and must not be treated as formal WCET bounds.
| Measurement Name | Measured Cycles O1 | Measured Cycles O2 | Measured Cycles O3 | Measured Cycles Os | Maximum | Comment |
|---|---|---|---|---|---|---|
| T_HandlePreStartupErrors | 1154 | 926 | 917 | 998 | 1154 | All four persistent pre-startup error flags set. |
| T_InitSafetySystem | 3038 | 2728 | 2731 | 3017 | 3038 | All optional initialization paths enabled. |
| T_RunStartupDiagnostics | 13830 | 12237 | 12182 | 15498 | 15498 | All optional startup diagnostics enabled. |
| T_HandleResetReason | 407 | 388 | 377 | 414 | 414 | Valid software-reset information. Includes the reset callback. |
| T_StartMissionMode | 246 | 236 | 236 | 241 | 246 | Heartbeat and strict safe-state handling enabled. |
| T_RunNextLatentFaultDiag | 1494 | 1401 | 1520 | 1631 | 1631 | Maximum of all 20 enabled diagnostics. Measures only the Begin call for diagnostics split into Begin and End. |
| T_EnterIdleSleep | 74 | 72 | 72 | 77 | 77 | Global interrupts disabled so sleep is refused. Does not include sleep or wake-up. |
| T_HandleWatchdog | 147 | 139 | 139 | 142 | 147 | WDT count diagnostic enabled and completed successfully. |
| T_HandleSyncWatchdog | 347 | 330 | 330 | 334 | 347 | Called inside the open window. Intentional waiting is excluded. |
| T_HandleNotificationErrors | 6786 | 6644 | 6644 | 7388 | 7388 | All 17 error channels set. Notification log full. Entries handled using an empty callback. |
| DUR_UNTIL_FIRST_SCHEDULE | 237 | 208 | 161 | 212 | 237 | From return of T_StartMissionMode to the first T_HandleSyncWatchdog call inside the first TM_Schedule. |
| DUR_UNTIL_NEXT_SCHEDULE | 362 | 284 | 237 | 282 | 362 | From return of the final T_HandleSyncWatchdog call in one TM_Schedule to the first T_HandleSyncWatchdog call in the next TM_Schedule. |
| T_EnsureSafeState | Not measured | Not measured | Not measured | Not measured | Not measured | Part of the reset-driven pre-startup sequence. |
| T_DetermineResetReason | Not measured | Not measured | Not measured | Not measured | Not measured | Part of the reset-driven pre-startup sequence. |
| T_RunResetDiagnosticFsm | Not measured | Not measured | Not measured | Not measured | Not measured | Intentionally resets the device. |
| T_HandleNmiInterrupt | Not measured | Not measured | Not measured | Not measured | Not measured | Halts until a timeout resets the device. |
| T_HandleBodInterrupt | 39 | 34 | 34 | 38 | 39 | |
| T_HandleClockInterrupt | 774 | 758 | 758 | 833 | 833 | |
| T_HandlePowerInterrupt | 522 | 509 | 509 | 575 | 575 | No VMON diagnostic completion pending. |
| T_HandleSwdtInterrupt | 425 | 405 | 405 | 428 | 428 | |
| T_HandleNvmInterrupt | 610 | 601 | 601 | 667 | 667 | |
| T_HandleRamInterrupt | 349 | 342 | 342 | 389 | 389 | |
| T_HandleCrcInterrupt | 220 | 205 | 205 | 200 | 220 | Regular CRC completion path. This was the longer path. |
| T_HandleBadInterrupt | 123 | 112 | 112 | 110 | 123 | |
| T_HandleErrorChInterrupt | 630 | 608 | 556 | 624 | 630 | Maximum of 17 measurements with one individual error channel set at a time. Underlying peripheral error flags not set. |
| MW_DiagClockCfd0Begin | 337 | 309 | 309 | 356 | 356 | Begin call only. The asynchronous diagnostic duration is excluded. |
| MW_IsDiagCfd0Ongoing | 10 | 10 | 10 | 16 | 16 | Called while the CFD0 diagnostic is active. |
| MW_DiagClockCfd0End | 302 | 273 | 273 | 328 | 328 | Called after the CFD0 diagnostic has completed. |
| MW_DiagClockCfd1Begin | 338 | 310 | 310 | 357 | 357 | Begin call only. The asynchronous diagnostic duration is excluded. |
| MW_IsDiagCfd1Ongoing | 10 | 10 | 10 | 16 | 16 | Called while the CFD1 diagnostic is active. |
| MW_DiagClockCfd1End | 302 | 273 | 273 | 328 | 328 | Called after the CFD1 diagnostic has completed. |
| MW_DiagClockCfm0 | 1444 | 1352 | 1450 | 1579 | 1579 | |
| MW_DiagClockCfm1 | 1444 | 1352 | 1471 | 1579 | 1579 | |
| MW_DiagCpuLockstep | Not measured | Not measured | Not measured | Not measured | Not measured | Intentionally resets the device. |
| MW_DiagErrorChannelSplim | 409 | 386 | 346 | 479 | 479 | |
| MW_DiagErrorChannelCfd0 | 409 | 386 | 356 | 493 | 493 | |
| MW_DiagErrorChannelCfd1 | 409 | 386 | 356 | 493 | 493 | |
| MW_DiagErrorChannelCfm0 | 409 | 386 | 356 | 493 | 493 | |
| MW_DiagErrorChannelCfm1 | 409 | 386 | 356 | 493 | 493 | |
| MW_DiagErrorChannelEeprom | 409 | 386 | 356 | 493 | 493 | |
| MW_DiagErrorChannelEvsys0 | 409 | 386 | 356 | 493 | 493 | |
| MW_DiagErrorChannelEvsys1 | 409 | 386 | 356 | 472 | 472 | |
| MW_DiagRamParity | 901 | 711 | 711 | 1077 | 1077 | |
| MW_DiagNvmParity | 1344 | 985 | 985 | 1581 | 1581 | |
| MW_DiagRamEcc | 977 | 823 | 823 | 1108 | 1108 | |
| MW_DiagNvmFlashEcc | 1141 | 914 | 914 | 1319 | 1319 | |
| MW_DiagNvmEepromEcc | 925 | 754 | 754 | 1081 | 1081 | |
| MW_DiagVmonOverBegin | 339 | 326 | 316 | 339 | 339 | Begin call only. The asynchronous diagnostic duration is excluded. |
| MW_IsDiagVmonOverDone | 36 | 39 | 39 | 46 | 46 | Called while the overvoltage diagnostic is active. |
| MW_DiagVmonOverEnd | 294 | 274 | 273 | 284 | 294 | Called after overvoltage detection has completed. |
| MW_DiagVmonUnderBegin | 338 | 323 | 316 | 338 | 338 | Begin call only. The asynchronous diagnostic duration is excluded. |
| MW_IsDiagVmonUnderDone | 38 | 39 | 39 | 46 | 46 | Called while the undervoltage diagnostic is active. |
| MW_DiagVmonUnderEnd | 293 | 274 | 270 | 283 | 293 | Called after undervoltage detection has completed. |
| MW_IsDiagVmonOngoing | 10 | 10 | 10 | 16 | 16 | Called while a VMON diagnostic is active. |
| MW_DiagSwdtCount | 100 | 98 | 98 | 110 | 110 | |
| MW_DiagSwdtExpire | 489 | 453 | 453 | 599 | 599 | |
| MW_DiagWdtCountBegin | 87 | 82 | 82 | 89 | 89 | Begin call only. |
| MW_IsDiagWdtCountOngoing | 10 | 10 | 10 | 16 | 16 | Called while the WDT count diagnostic is active. |
| MW_DiagWdtCountEnd | 106 | 105 | 105 | 112 | 112 | Called after the WDT counter has incremented. |
| MW_DiagWdtExpire | Not measured | Not measured | Not measured | Not measured | Not measured | Intentionally resets the device. |
| MW_IsDiagCrcOngoing | 10 | 10 | 10 | 16 | 16 | Called while a CRC diagnostic is active. |
| MW_ReportDiagCrcDone | 24 | 25 | 25 | 24 | 25 | Called while a CRC diagnostic is active. |
| MW_DiagCrcScan | 386 | 370 | 370 | 387 | 387 | Includes the complete error-injection scan, Idle sleep and CRC interrupt handling. |
| T_InitSafeShutdown | 1196 | 1105 | 1105 | 1149 | 1196 | Safe-state entry and clock-monitor shutdown enabled. |
| T_HandleShutdownWatchdogs | 201 | 174 | 174 | 179 | 201 | Called after T_InitSafeShutdown has configured the watchdogs. |
| T_EnterShutdownSleep | Not measured | Not measured | Not measured | Not measured | Not measured | Depends on sleep and wake-up conditions. |
| T_VerifyFlashIntegrity | Not measured | Not measured | Not measured | Not measured | Not measured | Depends on configured Flash sections, CRC configuration, sleep and interrupt timing. |
| T_RestartDevice | Not measured | Not measured | Not measured | Not measured | Not measured | Intentionally resets the device. |
This section describes how the stack depth of the Safety Framework is estimated and how the measurement results should be interpreted.
The Safety Framework uses a layered call structure without recursion or run-time-sized stack allocation. Calls proceed from the Task Managers through Tasks, middleware and drivers without looping back through the call hierarchy. The normal call-chain depth is therefore bounded.
Interrupts can add further call chains on top of the interrupted code. The measurement calculates the deepest base call chain and the stack depth of each Interrupt Service Routine separately, then combines them according to the supported interrupt nesting.
The analysis covers the Safety Framework code reached from main, pre-startup, the Task Managers and the Framework Interrupt Service Routines. All optional startup diagnostics and all entries in the periodic latent-fault diagnostic queue are enabled.
Application code and Application Interrupt Service Routines are not included.
Measurements are performed using the -O1, -O2, -O3 and -Os XC8 compiler optimization levels.
The Safety Framework is compiled using XC8 with the -fstack-usage option. The generated stack-usage information provides the stack frame size of each compiler-generated function.
The linked ELF file is disassembled using avr-objdump. The disassembly is used to determine the stack usage of assembly functions and reconstruct the calls between functions.
The stack depth of each call chain is calculated by adding the function stack frames and the two-byte return address added by each function call. Tail calls reuse the caller's stack frame and do not add a return address. Interrupt measurements also include the program counter stored by the interrupt hardware and the registers saved when entering the Interrupt Service Routine.
Calls through Schedules, callback tables and handler tables are resolved using the contents of the linked build. The analysis fails if a call cannot be resolved, a function has no calculated stack usage, or recursion or run-time-sized stack allocation is detected.
The XC8 -mchp-stack-usage analysis is also generated. It cannot calculate the complete Safety Framework stack depth because calls to functions written in assembly are reported as indeterminate stack adjustments. The measurement method has been verified against -mchp-stack-usage using call chains containing only compiler-generated functions, where both methods produce the same result.
The result table contains one column for each compiler optimization level. The Max Stack Depth column contains the largest value across these optimization levels.
Base context is the deepest call chain reached from main or pre-startup without an interrupt.
Each ISR row contains the deepest call chain reached from that interrupt entry point.
Base context, deepest ISR and NMI combines the deepest base call chain, the deepest maskable ISR and the NMI. This applies when no interrupt vector is assigned to priority level 1, since two maskable interrupts cannot then be active at the same time.
Base context, two deepest ISRs and NMI also includes a second maskable ISR. This applies when an interrupt vector is assigned to priority level 1 using INIT_INT_LVL1. This result is used when defining the documented INIT_STACK_LIMIT.
The results apply to the compiler, DFP, build configuration and Safety Framework version identified in the corresponding release notes.
The combined results are conservative overestimates because they assume that each interrupt occurs at the point of greatest stack usage in the preceding context, with the non-returning NMI occurring last, and do not account for critical sections or other states that may prevent the assumed nesting. The stack depth reached during normal execution is therefore likely to be significantly lower.
| Measurement Name | Measured Stack Depth O3 | Measured Stack Depth Os | Measured Stack Depth O1 | Measured Stack Depth O2 | Max Stack Depth | Comment |
|---|---|---|---|---|---|---|
| Base context | 69 | 73 | 73 | 69 | 73 | Task Manager to Task to middleware to driver, without any interrupt. Deepest chain from main and from the Pre-startup hook. |
| ERRCTRL_INT ISR | 52 | 50 | 53 | 52 | 53 | |
| RAMCTRL_INT ISR | 47 | 46 | 48 | 47 | 48 | |
| NVMCTRL_ERROR ISR | 47 | 46 | 48 | 47 | 48 | |
| CRCSCAN_INT ISR | 45 | 42 | 48 | 45 | 48 | |
| Unhandled vector ISR | 45 | 42 | 48 | 45 | 48 | |
| SWDT_INT ISR | 47 | 46 | 48 | 47 | 48 | |
| BOD_VLM ISR | 45 | 42 | 48 | 45 | 48 | |
| NMI ISR | 47 | 44 | 48 | 47 | 48 | |
| SLPCTRL_INT ISR | 47 | 46 | 48 | 47 | 48 | |
| CLKCTRL_INT ISR | 47 | 44 | 48 | 47 | 48 | |
| Base context, deepest ISR and NMI | 168 | 167 | 174 | 168 | 174 | One maskable interrupt active. Applies when no vector is assigned to priority level 1. |
| Base context, two deepest ISRs and NMI | 215 | 213 | 222 | 215 | 222 | Two maskable interrupts active. Applies when a vector is assigned to priority level 1. |