This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SAFETI_DIAG_LIB: Issue whit VIM_SOFTWARE_TEST and CPU self test with SafeTIDiaglib

Part Number: SAFETI_DIAG_LIB

Hello everyone,

I am trying to use the SafeTI DiagLib with the Hercules  TMS270LS1224 Launchpad, and for the moment, I am facing some issues, that lead me to ask for some help.

Here is the aim: I would like to have a function that I will call at each complete sequence of my main application in a while() loop. That functino would be a target_self_test() which executes each required tests for the application, based on the SafeTI Diaglib API. 

So something like this (n.b. All the calls for the sl functions, ESM callback etc... copy-paste from the example SL_TMS570LS1227_NoOS):

error_t target_selftest(void)
{
    volatile boolean        retVal;
    uint8 error_happened = 0;

    /* Init SL ESM for SL callback requirement */
    SL_ESM_Init(ESM_ApplicationCallback);

    /* Self Test for VIM Module */

    retVal = SL_SelfTest_VIM(VIM_SOFTWARE_TEST); // Fail
    if (true == retVal) {
        char tmps[] = "Test VIM_SOFTWARE_TEST successfully passed\n";
        sciSend(scilinREG, sizeof(tmps),  (unsigned char *)tmps);
    }
    else {
        char tmps[] = "Test VIM_SOFTWARE_TEST Failed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        error_happened = 1;
    }


    retVal = SL_SelfTest_VIM(VIM_SRAM_PARITY_TEST);
    //INCREMENT_PASS_FAIL_COUNTER(ST_PASS, retVal);
    if (true == retVal) {
        char tmps[] = "Test VIM_SRAM_PARITY_TEST successfully passed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
    }
    else {
        char tmps[] = "Test VIM_SRAM_PARITY_TEST Failed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        error_happened = 1;
    }

    /* Self Test for SPI as GIO */
    retVal = SL_SelfTest_SPI(SPI_ANALOG_LOOPBACK_TEST, SL_SPI3);
    if (true == retVal) {
        char tmps[] = "Test SPI_ANALOG_LOOPBACK_TEST successfully passed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
    }
    else {
        char tmps[] = "Test SPI_ANALOG_LOOPBACK_TEST Failed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        error_happened = 1;
    }
    /* Self Test for GIO */
    retVal = SL_SelfTest_GIO(GIO_ANALOG_LOOPBACK_TEST, SL_GIOPORTB, 1);
    if (true == retVal) {
        char tmps[] = "Test GIO_ANALOG_LOOPBACK_TEST successfully passed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
    }
    else {
        char tmps[] = "Test GIO_ANALOG_LOOPBACK_TEST Failed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        error_happened = 1;
    }

    /* Self Test for MIBSPI as GIO */
    retVal = SL_SelfTest_SPI(SPI_ANALOG_LOOPBACK_TEST, SL_SPI3); // Fail
    //INCREMENT_PASS_FAIL_COUNTER(ST_PASS, retVal);
    if (true == retVal) {
        char tmps[] = "Test SPI_ANALOG_LOOPBACK_TEST successfully passed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
    }
    else {
        char tmps[] = "Test SPI_ANALOG_LOOPBACK_TEST Failed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        error_happened = 1;
    }

    /* Self Test for SPI as GIO */
    retVal = SL_SelfTest_LIN(LIN_ANALOG_LOOPBACK_TEST, SL_LIN2); // Fail
    //INCREMENT_PASS_FAIL_COUNTER(ST_PASS, retVal);
    if (true == retVal) {
        char tmps[] = "Test LIN_ANALOG_LOOPBACK_TEST successfully passed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
    }
    else {
        char tmps[] = "Test LIN_ANALOG_LOOPBACK_TEST Failed\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        error_happened = 1;

    if (1 == error_happened) {
        char tmps[] = "Target selftests failed.\n";
        sciSend(scilinREG,sizeof(tmps),  (unsigned char *)tmps);
        while(1);
    }

     return (error_t) retVal;

}


/* Main app */

int main(void)
{
/* USER CODE BEGIN (3) */
    uint8_t temps[] = "Init done\n";
    error_t ret_value = APP_OK;

    /** Modules init */

    /* Init GIO for LED */
    gioInit();

    /* Init SCI/LIN */
    sciInit();

    /* Init RTI */
    rtiInit();

    /* Init MIBSPI for Switch */
    mibspiInit();

    /* IRQ Allowed */
    _enable_IRQ();

    /* Call self test routine  before starting IRQ and app*/
    ret_value = target_selftest();

    /* Start RTI Counter Block 0, 500ms */
    rtiStartCounter(rtiCOUNTER_BLOCK0);
    /* Start RTI Counter Block 1, 5ms */
    rtiStartCounter(rtiCOUNTER_BLOCK1);

    /* Enable RTI Compare 0 & 1 interrupt notification */
    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    rtiEnableNotification(rtiNOTIFICATION_COMPARE1);

    /* Call app_init */
    ret_value = app_init();

    /** Modules init finished **/
    sciSend(scilinREG, sizeof(temps), (unsigned char *)temps);

    /* App */
    while(APP_OK == ret_value) {
       app_main();
       ret_value = target_selftest();
    }

/* USER CODE END */

    return 0;
}

This is just to give an idea of what I would like to do of course.

Now the issue: 

As you can see, two tests are failing, VIM_SOFTWARE, LIN_ANALOG_LOOPBACK_TEST (for SL_LIN2 and SL_SPI3). Let's just forget about the LIN_ANALOG_LOOPBACK_TEST  for the moment because I haven't explored it yet. So why the VIM_SOFTWARE doesn't work ? Well, it seems that the test it waiting for a variable to be changed via interrup. This appears on the sl_selftest.c where the test is applied as:

#if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_TMS570LS07x_) || defined(_TMS570LS09x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM44x_) || defined(_RM42x_) || defined(_TMS570LS04x_)
        /* cause interrupt (SRAM_RADECODE_DIAGNOSTICS interrupt in this case) - storing retval to avoid misra-c violation */
        tmp = SL_SelfTest_SRAM(SRAM_RADECODE_DIAGNOSTICS, TRUE, &failInfoTCMRAM);

        tmp = tmp; /* to avoid compiler warning */
#endif

        /* check if the ISR called */
        if(vimTestFlag)
        {
            retVal = TRUE; /*Test passed*/
        }

        /* Clear global flag */
        vimTestFlag = FALSE;

        /* Clear test type */
        SL_FLAG_CLEAR(testType);
        break;

There, vimTestFlag is never changed to anything else than false. And when I look into the selftestRam, it seems that the SRAM_RADECODE_DIAGNOSTICS  should provide the needed interrupt to change this variable (in the function ESM_ApplicationCallback):

#if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_TMS570LS07x_) || defined(_TMS570LS09x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM44x_) || defined(_RM42x_) || defined(_TMS570LS04x_) || defined(_TMS570LC43x_) || defined(_RM57Lx_)
    case SRAM_RADECODE_DIAGNOSTICS:
        retVal = TRUE;

#if (FUNCTION_PROFILING_ENABLED != 0)
        SL_Record_Errorcreationtick(testType);
#endif

        /*flag is set to indicate the current test which is ongoing and
        These flags are used in the sl_esm.c so as to mask the esm callback*/
        (void)SL_FLAG_SET(SRAM_RADECODE_DIAGNOSTICS);
#if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_TMS570LS07x_) || defined(_TMS570LS09x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM44x_) || defined(_RM42x_) || defined(_TMS570LS04x_)
        _SL_SelfTest_SRAM_RAD(sl_tcram1REG, sram_stResult);
        /* Note : nERROR pin gets Activated but it is not cleared here but in next _SL_HoldNClear_nError
         * that is called after few lines with in this function. If User needs can uncomment below Line.*/
        //_SL_HoldNClear_nError()
        if (ST_PASS == *sram_stResult) {
            sl_esmREG->SR1[1] = (uint32)(1U << ESM_G2ERR_B0TCM_UNCORR);
            sl_esmREG->SSR2 = (uint32)(1U << ESM_G2ERR_B0TCM_UNCORR);
            /*flag is set to indicate the current test which is ongoing and
            These flags are used in the sl_esm.c so as to mask the esm callback*/
            (void)SL_FLAG_SET(SRAM_RADECODE_DIAGNOSTICS);
            _SL_SelfTest_SRAM_RAD(sl_tcram2REG, sram_stResult);
            _SL_HoldNClear_nError(); /* Clear nError */
            if (ST_PASS == *sram_stResult) {
                sl_esmREG->SR1[1] = (uint32)(1U << ESM_G2ERR_B1TCM_UNCORR);
                sl_esmREG->SSR2 = (uint32)(1U << ESM_G2ERR_B1TCM_UNCORR);
            }
        }
#endif
#if defined(_TMS570LC43x_) || defined(_RM57Lx_)
        _SL_SelfTest_SRAM_RAD(sl_l2ramwREG, sram_stResult);
        _SL_HoldNClear_nError(); /* Clear nError */

#endif
        /*clear the flags which indicate tests ongoing*/
        SL_FLAG_CLEAR(SRAM_RADECODE_DIAGNOSTICS);
        break;
#endif


Ok so at this point, I faced the fact that I must have parameterized something in the wrong way, classic. Let's go to the doc. The SafeTI Diaglib documentation does not provide anything specific concerning the VIM_SOFTWARE_TEST. Only that you need to use SL_SelfTest_VIM. M'okay..
But, the Safety Manual underlines the fact that a special boot up sequence might be done to work in a perfect context. So I checked the Standard Initialization Sequence for Hercules Microcontrollers. Of course, I realized that my startup code (in sys_startup.c) was not providing all the required points there.
By checking my Halcogen (and, as I was there, comparing it with the halcogen project from the example provided with the diaglib), I realized that a lot of things where missing (all the CPU selftest at the boot time (So CCM check, STC check, etc etc..., but also the mapping between ESM interruption -low interrupt- which is then managed by the VIM).

Ok, now my global conf should be ok. Based on what there were in the example (which, actually do not even work on my launchpad).
After bringing all of this, I have a wonderful startup code which blocks. It blocks while waiting for CPU selftest there (when checking CCMSR reg). And by the, Code Composer Studio let me confirm that CCMKEYR is well written as 0x06u, so it is done as a Supervisor mode:

    /* Run a diagnostic check on the CCM-R4F module */
    /* This step ensures that the CCM-R4F can actually indicate an error */

    /* Configure CCM in self-test mode */
    CCMKEYR = 0x6U;
    /* Wait for CCM self-test to complete */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    while ((CCMSR & 0x100U) != 0x100U)
    {
    }/* Wait */

So... What should I do now ? In sum:

* The launchpad does not start if I enable all the self test, or let say at least the CPU self test, at boot time.

* The VIM_SOFTWARE_TEST always return as failing because the RADECODE ram test does not seems to trigg the callback changing the good value

What am I missing ???

Thanks a lot for helping me !



  • Hi,

    Yoan Lefevre said:

    Ok so at this point, I faced the fact that I must have parameterized something in the wrong way, classic. Let's go to the doc. The SafeTI Diaglib documentation does not provide anything specific concerning the VIM_SOFTWARE_TEST. Only that you need to use SL_SelfTest_VIM. M'okay..

    But, the Safety Manual underlines the fact that a special boot up sequence might be done to work in a perfect context. So I checked the Standard Initialization Sequence for Hercules Microcontrollers. Of course, I realized that my startup code (in sys_startup.c) was not providing all the required points there.
    By checking my Halcogen (and, as I was there, comparing it with the halcogen project from the example provided with the diaglib), I realized that a lot of things where missing (all the CPU selftest at the boot time (So CCM check, STC check, etc etc..., but also the mapping between ESM interruption -low interrupt- which is then managed by the VIM).

    Ok, now my global conf should be ok. Based on what there were in the example (which, actually do not even work on my launchpad).
    After bringing all of this, I have a wonderful startup code which blocks. It blocks while waiting for CPU selftest there (when checking CCMSR reg). And by the, Code Composer Studio let me confirm that CCMKEYR is well written as 0x06u, so it is done as a Supervisor mode:

    So... What should I do now ? In sum:

    * The launchpad does not start if I enable all the self test, or let say at least the CPU self test, at boot time.

    * The VIM_SOFTWARE_TEST always return as failing because the RADECODE ram test does not seems to trigg the callback changing the good value

    What am I missing ???

    Thanks a lot for helping me !

    You mentioned that you tried to follow the initialization sequence recommended for Hercules micro-controllers. Also, there's a comment "Based on what there were in the example (which, actually do not even work on my launchpad)." - I am not sure if you meant that you have tested the included sample project for TMS570LS12x and whether that failed.

    Could you try the example project included in C:\ti\Hercules\SafeTI Diagnostic Library\2.4.0\build\TMS570LS1227_NoOS on your TMS570LS1227 LaunchPad? I have tested the sample project for VIM software test, disabling all other tests in app_main_NoOS.c and the VIM software test works correctly.

    Thanks,

    Girish

  • Hi Girish and thanks for answering,

    Things have been a bit forward since last time (actually since pretty much yesterday to be honnest).

    I succeeded in running the TMS570LS1227_NoOS on my launchpad and I understood why it wasn't working. Basically because the projet was NOT set with the good EABI, which lead in a wrong arm assembly generation, and brought me pretty quick to a CPU error interruption. 

    Once corrected, I've been able to to get into the the entire application with all the BIST and SelfTest provided by the API for a set of HW and peripherals. And I got NO errors on any of them (well actualy one, on flash, but it is normal since it is fault injection into Flash and CRC compared).

    Furthermore, I found an error into the TMS570LS1227_NoOS code, line 699

    /*running all posible 2 port algorithms on 2 port momories*/
    for(i = 0;i < sizeof(all2portmemories);i++)
        	{
        		for(j =0;j<sizeof(all2portalgos);j++)
        		{
    ...

    I don't know if you have the same but the sizeof alone for an array of uint32 wrong. And actually, few line after, there is the same instruction but corrected:

    for(i = 0;i < (sizeof(all1portmemories)/sizeof(uint32));i++)
        	{
        		for(j =0;j<(sizeof(all1portalgos)/sizeof(uint32));j++)
        		{

    Anyway, I am trying to understand the mapping between the Safety Feature or Diagnostic in the documentation and what I should actually check.

    For instance, to validate ADC10 (in order to compute a pertinent SFF in a safety context), I should call SL_SelfTest_ADC in both ADC_SELFTEST_ALL and ADC_SRAM_PARITY_TEST for both adc register.

    And actually, I could not manage to find anywhere in the documentation a place refering to this. Only in the example code (and, btw, I have some conflicts between the documentation generated with the code SafeTIDiagnosticLibrary-User'sGuide-v2.4.0.chm and the Software_Safety_Manual.pdf. See ADC4 and ADC10 for instance).

    If you have any idea concerning how to get a better knowledge of all of this, I take it ! 

    Thank you again for answering.

    Regards,

    Yoan

  • Yoan Lefevre said:

    Hi Girish and thanks for answering,

    Things have been a bit forward since last time (actually since pretty much yesterday to be honnest).

    I succeeded in running the TMS570LS1227_NoOS on my launchpad and I understood why it wasn't working. Basically because the projet was NOT set with the good EABI, which lead in a wrong arm assembly generation, and brought me pretty quick to a CPU error interruption. 

    Once corrected, I've been able to to get into the the entire application with all the BIST and SelfTest provided by the API for a set of HW and peripherals. And I got NO errors on any of them (well actualy one, on flash, but it is normal since it is fault injection into Flash and CRC compared).

    Thanks, good to know you were able to make progress.

    Yoan Lefevre said:

    Furthermore, I found an error into the TMS570LS1227_NoOS code, line 699

    /*running all posible 2 port algorithms on 2 port momories*/
    for(i = 0;i < sizeof(all2portmemories);i++)
        	{
        		for(j =0;j<sizeof(all2portalgos);j++)
        		{
    ...

    I don't know if you have the same but the sizeof alone for an array of uint32 wrong. And actually, few line after, there is the same instruction but corrected:

    for(i = 0;i < (sizeof(all1portmemories)/sizeof(uint32));i++)
        	{
        		for(j =0;j<(sizeof(all1portalgos)/sizeof(uint32));j++)
        		{

    Yes, this is a bug in the example code.

    Yoan Lefevre said:

    Anyway, I am trying to understand the mapping between the Safety Feature or Diagnostic in the documentation and what I should actually check.

    For instance, to validate ADC10 (in order to compute a pertinent SFF in a safety context), I should call SL_SelfTest_ADC in both ADC_SELFTEST_ALL and ADC_SRAM_PARITY_TEST for both adc register.

    I will take this feedback to enhance documentation about the mapping of exact tests to a recommended safety diagnostic, but this product is not under active development, and will be refreshed in a maintenance update with bug fixes.

    In the meantime, please ask your queries on this forum.

    Yoan Lefevre said:

    And actually, I could not manage to find anywhere in the documentation a place refering to this. Only in the example code (and, btw, I have some conflicts between the documentation generated with the code SafeTIDiagnosticLibrary-User'sGuide-v2.4.0.chm and the Software_Safety_Manual.pdf. See ADC4 and ADC10 for instance).

    If you have any idea concerning how to get a better knowledge of all of this, I take it ! 

    Thank you again for answering.

    Regards,

    Yoan

    I do not see any difference between the software safety manual for the Hercules Safety diagnostic library or the Hercules safety diagnostic library user's guide for ADC4 and ADC10.

    thanks,

    Girish

  • Girish said:

    I do not see any difference between the software safety manual for the Hercules Safety diagnostic library or the Hercules safety diagnostic library user's guide for ADC4 and ADC10.

    thanks,

    Girish

    Yeah, I also found out why I was wrong about this... I was talking about the doxygen documentation SafeTIDiagnosticLibrary-User'sGuide-v2.4.0.chm, in which there are the documentations for both TMS570LC43x/RM57Lx devices and TMS57012x. So there are two pages called Safety manual to API mapping and Safety manual to API mapping: TMS570LC43x/RM57Lx devices which do not have the same tests obviously....
    So yup, my bad for this one.
    Regards, 
    Yoan