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.

Figuring out which Task (or code segment) led to CPU Hard Fault

Other Parts Discussed in Thread: SYSBIOS

MCU: TM4C1294NCPDT

TI-RTOS: v2.01.00.03

CCS: v6.0.1.0040

-

Hello,

    Often I find that the CPU lands up into a HARD FAULT. How can I figure out (during run time) that which particular task was running when the HARD FAULT occured? To figure this out, I would prefer that upon a HARD FAULT an error code be written to a particular location in the eeprom memory of the MCU, so that, later on the system can figure out the cause (or probable cause) of the fault. How to implement this?

Thanks

Regards

Soumyajit

  • Soumyajit,

    Using the register core dump from the Hard fault, the callback stack can be reconstructed. Check this topic on the SYS/BIOS wiki for more information:

    http://processors.wiki.ti.com/index.php/SYS/BIOS_FAQs#4_Exception_Dump_Decoding_Using_the_CCS_Register_View

    Hope this helps.
    Vikram
  • Hi Soumyajit --

    You can replace the default exception handler with the following lines your .cfg file:

    ti_sysbios_family_arm_m3_Hwi = xdc.useModule('ti.sysbios.family.arm.Hwi');
    ti_sysbios_family_arm_m3_Hwi.excHandlerFunc = "&myExceptionHandler";

    You should then review the Hwi_excHandlerMin() and Hwi_excHandlerMax() code functions in ti/sysbios/family/arm/m3/Hwi.c for the 2 options provided by SYS/BIOS and steal some good stuff from those implementations.

    You can also hook in your own exception hook function which will be called by excHandlerMin (or Max).

    Hwi.excHookFunc = '&myExceptionHook';

    This function is passed an exception context. Here's an example of a hook function.

    Void myExceptionHook(Hwi_ExcContext *excp)
    {
    System_printf("Exception context = 0x%x\n", excp);
    Stack_unwind((Int32)excp->sp, (Int32)excp->lr, (Int32)excp->pc);
    }


    -Karl-
  • Hi Karl,

      I tried to add

    -

    ti_sysbios_family_arm_m3_Hwi = xdc.useModule('ti.sysbios.family.arm.Hwi');

    ti_sysbios_family_arm_m3_Hwi.excHandlerFunc = "&myExceptionHandler";

    -

     in the .cfg file but the compilers shoots up error showing "Description Resource Path Location Type

    xdc.MODULE_NOT_FOUND: xdc.module: no module named 'Hwi' in the package ti.sysbios.family.arm fatsdusbcopy.cfg /DL_Tiva_v2 Configuration Validation XDCTools Configuration Marker".

    -

    Can you also brief me in what is the function of stack unwind function & what exactly its doing with stack pointer link register & PC?

    -

    You have provided a function named "myExceptionHook(Hwi_ExcContext *excp)", inside this function is it necessary that during an actual exception the function should not return & should be in an indefinite loop? What I mean is that, what will happen say if inside the function I access the LCD (hardware), display something on the LCD & return from this function. In the example code you have provided for the function "myExceptionHook(Hwi_ExcContext *excp)", it shows the two statements will be executed & the function will return.

    -

    Also I was unable to figure out which header file to include if I want to keep the function "myExceptionHook(Hwi_ExcContext *excp)" in my main.c file; the compiler is giving error that "Hwi_ExcContext" is undefined.....

    -

    Thanks

    -

    Regards

    Soumyajit

  • Hey Vikram,
    Thanks for your reply, but I wanted to debug a Hard Fault when NO programmer/debugger is physically connected to the Tiva C MCU. The MCU should handle the exception all by itself & figure out which Task was executing at the time of the exception & display the Task Instance Name on the LCD. This is because, once the product is deployed on-site, it becomes difficult to attach a debugger on site & watch!!
    -
    Thanks
    -
    Regards
    Soumyajit

  • Hi Soumyajit,

    Karl's solution may help with your exception handling.

    Regarding your questions to Karl: There was a small typo: "m3" was missing from the package name.

    The corrected code is:
    ti_sysbios_family_arm_m3_Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
    ti_sysbios_family_arm_m3_Hwi.excHandlerFunc = "&myExceptionHandler";

    Use the following header to resolve the compiler error:
    #include <ti/sysbios/family/arm/m3/Hwi.h>

    I am not sure about Stack_unwind function. I will need to dig in a bit. But please note, in Karl's solution, there two different approaches: One through the "excHandlerFunc" and the other through "excHookFunc". The documentation of these configuration parameters can be found here: http://downloads.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/6_40_03_39/exports/bios_6_40_03_39/docs/cdoc/index.html

    Hope this helps.
    Vikram
  • Hello Vikram,

    Thanks for pointing out the typo. Can you tell me by referring to the following error print that how do I figure out which module is meant by module#42? Also what does line 1036 & line 1113 mean? These are line numbers of which code file? Also how do I figure out which function resides in memory location 0x0001f172?

    {module#42}: line 1036: E_hardFault: FORCED

    {module#42}: line 1113: E_busFault: PRECISERR: Immediate Bus Fault, exact addr known, address: ffffffff

    Exception occurred in background thread at PC = 0x0001f172.

    Thanks

    Regards

    Soumyajit

  • The module name can be figured in two ways:
    1) set test.isLoaded=true in the .cfg file and rebuild and test. This configuration will provide you with full name of the module instead of the shortened form.
    2) Or, look for Module__id__C in the generated c file which is generated in Debug/configPkg/package/cfg/<proj_name>_p<target_name>.c. The module name associated with 0x2A (i.e. module id 42) will be the module.

    The line number refers to the line number in the module (.c file).

    For figuring out the function, either use the CCS debugger to decode the PC by loading the value into the PC register or use the .map file generated to look for the function addresses.

    Hope it helps.

    Vikram
  • Hi Vikram,

     Firstly, sorry for the delayed response. I did try to open the "<proj_name>_p<target_name>.c" file but what I found is :

    //-

    /* Handle__label__S */

    xdc_runtime_Types_Label *ti_sysbios_family_arm_m3_Hwi_Handle__label__S(xdc_Ptr obj, xdc_runtime_Types_Label *lab)

    {

       lab->handle = obj;

       lab->modId = 42;

       xdc_runtime_Core_assignLabel(lab, 0, 0);

       return lab;

    }

    //-

     Can you please tell me how do I know the Task name which was being executed during the hard fault from the above code chunk?

    "lab->handle = obj;" - indicates modId 42, but how will I figure out the Task or function being executed at that time?

    -

    Thanks

    -

    Regards

    Soumyajit

  • Hi Soumyajit,

    We need to find the <modulename>_Module__id__C in that .c file. Here is a code snippet from my example application:

    /* Module__id__C */
    #pragma DATA_SECTION(ti_sysbios_knl_Clock_Module__id__C, ".const:ti_sysbios_knl_Clock_Module__id__C");
    __FAR__ const CT__ti_sysbios_knl_Clock_Module__id ti_sysbios_knl_Clock_Module__id__C = (xdc_Bits16)0x17;

    In the above snippet, the Module Id 0x17 (23 in decimal) is associated with the module ti/sysbios/knl/Clock.

    Similarly if you search in that ,c file, you should be able to find the module associated with module id 0x2A (42 in decimal).

    Vikram

  • The above solution will help find the module id. To check which function or Task caused the hard fault, use the PC, SP, LR values from the hard fault core dump printed on the console and use these values to set the PC, SP, LR registers in the Register view (in CCS). The Call Stack will now point to the function that caused the hard fault.

    Hope this helps,
    Vikram