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.

FaultISR with Linar0 4.83 and CCS6.1.1.00022

Other Parts Discussed in Thread: TM4C123GH6PM

I have a program which is failing when initializing an array to zero, ie:

char data[100]={0};

This code using Linaro 4.8.3 calls the memset function which is creating a hard fault. I did set the stack pointer to the top of SRAM, and the program is very simple so stack should not be issue. 

The NVIC_Fault_STAT has No Compressor Usage Fault Set. 

Below is the last instruction before the fault is set:

The code runs if compiled with the TI compiler, note I would use TI's compiler but at $750 for CCS I would just buy a chip from another vendor like Atmel. 

I also tried the same code with Linaro 4.9.3 however it is getting stuck in the Default ISR Handler when executing code below, again in the memset. 

Thanks

Trampas

  • Moving it to the CCS Forum
  • Trampas,

    Which device is this? I was unable to reproduce this in a MSP432 Launchpad, but I declared the variable as volatile to prevent the compiler from simply removing it. If this is a Cortex A device, Linaro requires a lot of stack for semihosted projects to properly work.

    I suspect the hard fault error is being triggered either by a misplacement of the stack or something that is overwriting it. To double check this, search your .map file generated by the linker and see if you see any overlapping memory sections. Also, you can load the code (but disable run to main) and check if valid stack data is being overwritten.

    Regards,
    Rafael
  • Trampas Stern said:
    This code using Linaro 4.8.3 calls the memset function which is creating a hard fault.

    I am guessing you are using a Cortex-M4 (e.g. Tiva C series) device which only supports Thumb mode instructions.

    If you link a GCC library which uses ARM mode instructions the library function can trigger a hard fault.

    See Working with GCC libraries on how to select the correct GCC library for a Cortex-M4. 

  • I am using the TIVA-C TM4C123GH6PM. 

    GCC options are:

    -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=soft -mfpu=fpv4-sp-d16 -DPART_TM4C123GH6PM -DTARGET_IS_BLIZZARD_RB1 -Dgcc -I"C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q3/arm-none-eabi/include" -I"C:/ti/TivaWare_C_Series-2.1.1.71" -ffunction-sections -fdata-sections -g -gdwarf-3 -gstrict-dwarf -Wall -MD -std=c99 -c

  • I am using the TIVA-C TM4C123GH6PM.

    GCC compile options are:

    -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=soft -mfpu=fpv4-sp-d16 -DPART_TM4C123GH6PM -DTARGET_IS_BLIZZARD_RB1 -Dgcc -I"C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q3/arm-none-eabi/include" -I"C:/ti/TivaWare_C_Series-2.1.1.71" -ffunction-sections -fdata-sections -g -gdwarf-3 -gstrict-dwarf -Wall -MD -std=c99 -c

    The GCC linker options are:

    -march=armv7e-m -mthumb -mfpu=fpv4-sp-d16 -DPART_TM4C123GH6PM -DTARGET_IS_BLIZZARD_RB1 -Dgcc -ffunction-sections -fdata-sections -g -gdwarf-3 -gstrict-dwarf -Wall -Wl,-Map,"Pd_Analyzer.map" -L"C:/ti/TivaWare_C_Series-2.1.1.71/driverlib/gcc" --verbose


    I have tried setting the stack to the top of SRAM, additionally since there are several other function calls before this I doubt it is a stack problem.


    /*****************************************************************************
    //
    // linker variable for top of stack
    //
    //*****************************************************************************
    extern uint32_t _stack_top;

    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    // To be added by user

    //*****************************************************************************
    //
    // The vector table. Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    __attribute__ ((section(".intvecs")))
    void (* const g_pfnVectors[])(void) =
    {
    (void (*)(void))((uint32_t)&_stack_top ),
    // The initial stack pointer



    /******************************************************************************
    *
    * Default Linker script for the Texas Instruments TM4C123GH6PM
    *
    * This is derived from revision 15071 of the TivaWare Library.
    *
    *****************************************************************************/

    MEMORY
    {
    FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000
    SRAM (WX) : ORIGIN = 0x20000000, LENGTH = 0x00008000
    }

    REGION_ALIAS("REGION_TEXT", FLASH);
    REGION_ALIAS("REGION_BSS", SRAM);
    REGION_ALIAS("REGION_DATA", SRAM);
    REGION_ALIAS("REGION_STACK", SRAM);
    REGION_ALIAS("REGION_HEAP", SRAM);
    REGION_ALIAS("REGION_ARM_EXIDX", FLASH);
    REGION_ALIAS("REGION_ARM_EXTAB", FLASH);

    heap_size = 1024;
    _stack_top = ORIGIN(SRAM)+LENGTH(SRAM);

    SECTIONS {

    PROVIDE (_intvecs_base_address = 0x0);

    .intvecs (_intvecs_base_address) : AT (_intvecs_base_address) {
    KEEP (*(.intvecs))
    } > REGION_TEXT

    PROVIDE (_vtable_base_address = 0x20000000);

    .vtable (_vtable_base_address) : AT (_vtable_base_address) {
    KEEP (*(.vtable))
    } > REGION_DATA

    .text : {
    CREATE_OBJECT_SYMBOLS
    *(.text)
    *(.text.*)
    . = ALIGN(0x4);
    KEEP (*(.ctors))
    . = ALIGN(0x4);
    KEEP (*(.dtors))
    . = ALIGN(0x4);
    __init_array_start = .;
    KEEP (*(.init_array*))
    __init_array_end = .;
    *(.init)
    *(.fini*)
    } > REGION_TEXT

    PROVIDE (__etext = .);
    PROVIDE (_etext = .);
    PROVIDE (etext = .);

    .rodata : {
    *(.rodata)
    *(.rodata*)
    } > REGION_TEXT

    .data : ALIGN (4) {
    __data_load__ = LOADADDR (.data);
    __data_start__ = .;
    *(.data)
    *(.data*)
    . = ALIGN (4);
    __data_end__ = .;
    } > REGION_DATA AT> REGION_TEXT

    .ARM.exidx : {
    __exidx_start = .;
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    __exidx_end = .;
    } > REGION_ARM_EXIDX

    .ARM.extab : {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > REGION_ARM_EXTAB

    .bss : {
    __bss_start__ = .;
    *(.shbss)
    *(.bss)
    *(.bss.*)
    *(COMMON)
    . = ALIGN (4);
    __bss_end__ = .;
    } > REGION_BSS

    .heap : {
    __heap_start__ = .;
    . = . + heap_size;
    end = __heap_start__;
    _end = end;
    __end = end;
    KEEP(*(.heap))

    __heap_end__ = .;
    __HeapLimit = __heap_end__;
    } > REGION_HEAP

    .stack : ALIGN(0x8) {
    _stack = .;
    __stack = .;
    KEEP(*(.stack))
    } > REGION_STACK
    }

    From the MAP file...

    0x00000400 heap_size = 0x400
    0x20008000 _stack_top = (ORIGIN (SRAM) + 0x8000)
    0x00000000 PROVIDE (_intvecs_base_address, 0x0)
  • Hi,

    I was able to run the code on a TM4C123GH6PM - basically, its initialization is somewhat different than MSP432, as it resets the target prior to a code load.

    In other words, for Tiva you can try enable the option shown below and see if it works.

    Changing stack or heap sizes on the project were not effective as well.

    Hope this helps,

    Rafael

    P.S. Just FYI, I did something slightly different than you when allocating heap and stack, which is usually clearer for me. 

    In the linker I also added symbols to expand the stack (__stack_size__) and the heap (__heap_size__).

    tm4c123gh6pm.lds file said:

    .heap : {

    __heap_start__ = .;

    end = __heap_start__ + __heap_size__;

    _end = end;

    __end = end;

    KEEP(*(.heap))

    __heap_end__ = .;

    __HeapLimit = __heap_end__;

    } > REGION_HEAP

    .stack : ALIGN(0x8) {

    _stack = . + __stack_size__;

    __stack = _stack;

    KEEP(*(.stack))

    } > REGION_STACK

    However, instead of defining them on the file itself, I added them to the project options.

    All this yielded the following map.

    myPjt.map said:

    .heap 0x200006b8 0x0

    0x200006b8 __heap_start__ = .

    0x20000ab8 end = (__heap_start__ + __heap_size__)

    0x20000ab8 _end = end

    0x20000ab8 __end = end

    *(.heap)

    0x200006b8 __heap_end__ = .

    0x200006b8 __HeapLimit = __heap_end__

    .stack 0x200006b8 0x0

    0x20000ab8 _stack = (. + __stack_size__)

    0x20000ab8 __stack = _stack

    *(.stack)

  • I found the "reset target" box as well... That took a few hours... Seems like it would default to that when selecting GCC.

    I was doing the stack size like I did the heap size, in the linker script, however I usually set the stack to end/top of RAM then monitoring stack usage in firmware by filling stack with known value and looking from end of heap to see how much has been used. This way I have less of risk of stack overflow in production code.

    Note that If I compile my code using Eclipse and Linaro, then flash into target it will run. However it will not run if done using CCS, hence I think it some configuration options I have messed up or a library issue.

    I have also read that with GCC 4.8 there was some issues with the stock libc that caused hard faults on cortex, but not sure if CCS has stock libc or custom built. I did try 4.9.3 and the results are different, that is the hard fault becomes an "default ISR handler." The only thing that changed is the compiler version, rest of project options remained the same. Therefore I was wondering if the issue was something like floating point hardware/software stack issue or something else?

    I also used the GCC from launchpad.net with newlib in eclipse which works. I would just kick CCS to curb except the XDS200 only works in CCS. Additionally I still have not figured out how to recompile the driverlib for hardware floating point support. The fact that I paid $300 for XDS200 and it only works in the full version of CCS ($750) stinks. I like TI hardware but Atmel and other vendors give their tools away.
  • Hi,

    Trampas Stern said:
    Note that If I compile my code using Eclipse and Linaro, then flash into target it will run. However it will not run if done using CCS, hence I think it some configuration options I have messed up or a library issue.

    Interesting; I can only imagine this or the Eclipse debugger you are using (OpenOCD?) is resetting the device without your knowledge (either explicitly via a switch or implicitly by design).

    Trampas Stern said:
    I have also read that with GCC 4.8 there was some issues with the stock libc that caused hard faults on cortex, but not sure if CCS has stock libc or custom built. I did try 4.9.3 and the results are different, that is the hard fault becomes an "default ISR handler." The only thing that changed is the compiler version, rest of project options remained the same.

    I built my code with CCS's default 4.8.4. Also, CCS does not rebuild anything for the GCC ARM compiler - all libraries are identical to this toolchain.

    Trampas Stern said:
    The fact that I paid $300 for XDS200 and it only works in the full version of CCS ($750) stinks. I like TI hardware but Atmel and other vendors give their tools away.

    I can't comment on pricing and its reasons, but to somehow "sweeten the deal", CCS + XDS200 + Cortex M4 are a good combination that supports the more advanced Instrumentation Trace Macrocell (ITM). If you don't know about it, you can check this short demo.

    Regards,

    Rafael

  • The eclipse build was flashed with standalone flash utility. I am unable to get OpenOCD or GDB working with XDS200.

    Even if I load the code from the CCS build and hard reset the code will not run.
  • If someone is available tomorrow I would be happy to host a teamviewer session to debug this issue. Again I assume it is a stupid mistake on my part.

    I would kick CCS to the curb and just use eclipse and OpenOCD but the XDS200 does not work with OpenOCD and I have been unable to get the GDB emulator application from TI to use GDB with the XDS200. Seems the download from website does not include the executable (yet another issue). I guess I could go buy a launchpad to use as JTAG adapter or a bit wiggler device, kind of a shame to have a XDS200 and be forced to use a launchpad for JTAG...

    In the mean time I have contacted Atmel and they have given me some development boards and offered local FAE support, so I will finish the schematics to swap out of the TI processor with Atmel tomorrow and order PCBs this week.

    It is a sad to remove a working TI chip....
  • If you had a full CCS license that enables you to use the TI compiler and your XDS200 does that get you past this?
  • I have a full license currently, and it works with TI's compiler.

    The issue is as we hire more people we will have to buy licenses for each new employee. Granted it would only be ~5 engineers, however also consider the support aspect. Atmel is kind enough to offer local FAE support, TI told me to find a distributor and call them.

    So it becomes simple:

    1. Chip Price - Atmel is $6 in volume, TI is around $12 (almost cheaper to buy the launchpad and remove chips)
    2. Tools - Atmel is free, TI is $750 per engineer
    3. Support - Atmel is offering local FAE, TI offers E2E forum
    4. Chip Quality and Peripherals - not much difference in our application.
    5. Debugger/ICE - about the same, TI has XDS200 but only works with full version of CCS.
    6. Experience - I have experience with TM4C and code base to start from, Atmel is a new learning curve.

    The biggest difference is not the tool cost, but the support. If the tools were free I would not have been trying to get GCC working and I would have a few days of my life back. So if I got better support by buying the tools it would justify the cost of tools, but that is not the case.