3.2.1 DIAG_CORTEX_M0
The DIAG_CORE_M0p module is designed to verify the correct functionality of the Cortex M0 processor through a set of C function calls.
The DIAG_CORE_M0p software test API is mapped to the following safety mechanisms:
| Function | Diagnostic Mechanism | Use Case | Elapse Time(μs)~ |
|---|---|---|---|
| DIAG_CORE_M0p_STL_Init() | NONE | POST / OnDemand | 32.6 |
| DIAG_CORE_M0p_STL() | ARM S/W Test Library (STL) | POST / OnDemand | 121.1 |
| DIAG_CORE_M0p_get_STL_Last_Executed() | NONE | POST / OnDemand | 5.0 |
Exception Handling
Core diagnostic related exception code added in stl_exception.c file. If System integrator is using their own exception handler, then code needs to be added in the exception handler. And exception handler must be registered in vector table.
#define STL_MPU_CTRL 0xE000ED94// Global Variable
int STL_exceptions; int STL_exc_result; int STL_exc_MPU; uint32_t STL_IPSR_golden_value = 0;// NMI Interrupt
if (STL_exceptions == 1)
{
STL_exceptions = 0;
uint32_t control_flow_value = 0x5A7F10CE;
/* rotate result right of 1 bit */
STL_exc_result = (STL_exc_result << 1) | (STL_exc_result >> (32 - 1));
/* add control flow value to result */
STL_exc_result += control_flow_value;// Hard Fault exceptionif (STL_exceptions == 1)
{
STL_exceptions = 0;
uint32_t control_flow_value = 0xE1538952;
/* rotate result right of 1 bit */
STL_exc_result = (STL_exc_result << 1) | (STL_exc_result >> (32 - 1));
/* add control flow value to result */
STL_exc_result += control_flow_value;
}
elseif (STL_exc_MPU == 1)
{
/* disable mpu */
uint32_t* stl_mpu_ctrl_p = (uint32_t*) STL_MPU_CTRL;
*stl_mpu_ctrl_p = 0x0;
STL_exc_MPU = 0;
/* Init control flow value */
uint32_t control_flow_value = 0x5A7816BC;
/* rotate result right of 1 bit */
STL_exc_result = (STL_exc_result << 1) | (STL_exc_result >> (32 - 1));
/* add control flow value to result */
STL_exc_result += control_flow_value;
}
//SV Exception
if (STL_exceptions == 1)
{
STL_exceptions = 0;
uint32_t control_flow_value = 0x12FCAA37;
/* rotate result right of 1 bit */
STL_exc_result = (STL_exc_result << 1) | (STL_exc_result >> (32 - 1));
/* add control flow value to result */
STL_exc_result += control_flow_value;
}
//PendSV Exception
if (STL_exceptions == 1)
{
STL_exceptions = 0;
uint32_t control_flow_value = 0x4576960A;
/* rotate result right of 1 bit */
STL_exc_result = (STL_exc_result << 1) | (STL_exc_result >> (32 - 1));
/* add control flow value to result */
STL_exc_result += control_flow_value;
}
Configuring the Diagnostic
SAFE Systick can be configured as illustrated to supported to support all diagnostics:

Run-time Pre-requisites
NVMCTRL_Initialize();
CLOCK_Initialize();
Using the Diagnostic for DIAG_CONTEXT_OOR
#include "definitions.h"
uint8_t __attribute__((section(".persist"))) last_test;
DIAG_TEST_STATUS DIAG_CORE_CM0_Example()
{
DIAG_TEST_STATUS ret_value = DIAG_TEST_NOT_EXECUTED;
//The DIAG_CORE_M0p_STL_Init function is only called once,
//should be outside of the main loop.
//Calls to DIAG_CORE_M0p_STL will run a different test
//each time (repeating after 21 tests).
DIAG_CORE_M0p_STL_Init(DIAG_CONTEXT_OOR);
ret_value = DIAG_TEST_FAILED;
if ( DIAG_TEST_PASSED == DIAG_CORE_M0p_STL(DIAG_CONTEXT_OOR) )
{
ret_value = DIAG_TEST_PASSED;
}
last_test = DIAG_CORE_M0p_get_STL_Last_Executed(); // optional
return ret_value;
}
Using the Diagnostic for DIAG_CONTEXT_OL
#include "definitions.h"
uint8_t __attribute__((section(".persist"))) last_test;
DIAG_TEST_STATUS DIAG_CORE_CM0_Example()
{
DIAG_TEST_STATUS ret_value = DIAG_TEST_NOT_EXECUTED;
DIAG_CORE_M0p_STL_Init(DIAG_CONTEXT_OL);
/* disable IRQ */
__disable_irq();
ret_value = DIAG_TEST_FAILED;
if ( DIAG_TEST_PASSED == DIAG_CORE_M0p_STL(DIAG_CONTEXT_OL) )
{
ret_value = DIAG_TEST_PASSED;
}
last_test = DIAG_CORE_M0p_get_STL_Last_Executed(); // optional
/* renable IRQ interrupts */
__enable_irq();
return ret_value;
}