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.

TM4C1294NCPDT: FreeRTOS 10.2.1 and Tiva

Part Number: TM4C1294NCPDT

Hi!

I am working on porting the FreeRTOS kernel onto a TM4C1294ncpdt custom board. I am using FreeRTOS 10.2.1 and CCS 9.1.

I have created a project, allocated 51200 (50k) bytes for heap. 32768(32k) bytes for stack and I believe I have the linker file to match. I have used some of the older examples as well as the FreeRTOS download example as a comparison. 

Without any tasks created, the scheduler launches and hits the systick isr as expected. 

The problem I am having is with a task creation. As part of the task creation, there is a memset function to "Fill the stack with a known value to assist debugging" within the tasks.c file. This memset puts my micro into a fault isr. The memory browser appears to indicate not a single iteration succeeded.

I am stumped. What in a memset would cause my processor to hit a hard fault handler? The code seems to be passing in logical SRAM location and size. Is there something else I need to have enabled to support memset? ANY insight would be greatly appreciated. 

Thank you! 

  • Here is an old application note that discusses debugging hard faults on Cortex M series devices:

    http://www.ti.com/lit/an/spma043/spma043.pdf

  • I have seen this document before. I appreciate the link. It did not help unfortunately. The precise bus address it was giving was in a reserved area of memory. 

    I did however make some progress. I have it narrowed down to three lines of code. 

    // Enable the EEPROM Peripheral
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);
    while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0)){

    }
    tmp32 = EEPROMInit(); // For some reason this is not a ROM_* function

    if(tmp32 != EEPROM_INIT_OK){
    while(1){

    }
    }

    Enabling the eeprom causes the issue later when calling memset. I haven't actually gotten to the point of making an eeprom calls. Just enabling in my board peripheral init function. Removing this lines and the problem goes away. 

    I'll have to do more digging to explain this one. The errata doesn't seem to have any explanations. The only close one was the MEM#12 code jumps from flash to rom when eeprom is active and may never return. However, the working bit for the eeprom is not counting. I only see the eeprom offset register ticking away. 

    I'll keep digging unless someone has an explanation for this.

  • Writing to a reserved location will definitely give an abort. If associated with the memset function, it could be that you are somehow using a non-initialized variable as an address. The EEPROM initialization may just change what the value is in the register that is used such that the error no longer occurs. If you can identify the address and assembly instruction that actually caused the abort by looking in the link register, you might be able to set a breakpoint on that instruction and identify the address that is being used. 

  • Hi Bob,

    I think you are onto something. The problem still persists with the EEPROM init removed. 

    I was getting a imprecise bus fault but following the link you provided, I seem to have isolated it to the xPortPendSVHandler within the portasm.asm freeRTOS port. Following a freeRTOS recommendation, I set the DISWBUF bit within the NVIC_ACTLR register. This did set what appears to be a precise bus fault error, as the "BFARV" bus fault address register valid bit is set as well as the "STAT_PRECISE" bit is also set. However, the address given makes no sense. Is this a valid method to try and pin point an issue?

    Handling imprecise bus faults (from freeRTOS) 

    https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

    While not specifically writing to flash, could my issue be perhaps related to this post?

    https://e2e.ti.com/support/microcontrollers/other/f/908/p/671683/2494679

  • Hi,

      Bob is out of office. 

      Since you have a precise fault then you should be able to put a breakpoint at the address that causes the fault and check what the instruction is doing. Do you know which address that generated the fault? 

      Earlier you said you are trying to use memset to initialize the stack. Are you calling the memset or this is called by the FreeRTOS? What is the length being passed to memset? I'm not sure why the memset is used to initialize the stack. The stack might have been pushed to store some context before the memset and the memset just wipes out the memory and when you return with the pop, it causes the fault. This is just a guess. 

  • Hi Charles,

    Thanks for filling in. 

    I believe I was lead astray on the previous memset. That or I have a very fragile project. The memset doesn't seem to be the issue anymore. with the update to disable cache and force a imprecise fault to become a precise I get the screen shot above. The fault location of 0xFFFFFFDC makes no sense to me. Prior to disabling cache, i followed the link Bob had given for debugging hard faults. Using the exception stack frame, I narrowed it down to a block of assembly code within the portasm.asm. Specifically the xPortPendSVCHandler. 

    With the DISWBUF set, and setting through with the debugger, I land on the following line sending me to the fault isr:

    	;/* Save the core registers. */
    	stmdb r0!, {r4-r11, r14}
    

    I am not up to speed on the M4 assembly instructions, but I'm not sure why that instruction would cause a precise hardware fault with a bogus fault address.

  • HI Jeff,

      What is in r0 register? This instruction is trying to push data onto the stack. If r0 contains a corrupted value then it can lead to a bus fault. For example, if the r0 contains an invalid address pointer then it will lead to a bus fault by the memory system. Can you try to increase your stack size and see if that makes a difference? 

  • Hi Charles,

    Prior to the fault, it is 0x00. Attached is screen shots of my registers prior to the fault as well as my stack size (32k) and my cmd file. I'll try doubling the stack size but it seems excessive. 

    Thanks!


    /****************************************************************************** * * Default Linker Command file for the Texas Instruments TM4C1294NCPDT * * This is derived from revision 15071 of the TivaWare Library. * *****************************************************************************/ --retain=g_pfnVectors #define CRC_SIZE 4 #define FW_ID_SIZE 72 #define APP_BASE 0x00000000 #define APP_SIZE 0x38000 - FW_ID_SIZE - CRC_SIZE #define FW_ID_BASE APP_BASE + APP_SIZE #define CRC_BASE APP_BASE + APP_SIZE + FW_ID_SIZE #define RAM_BASE 0x20000000 #define HFLT_SIZE 32 #define RAM_SIZE 0x00040000-HFLT_SIZE #define HFLT_BASE RAM_BASE+RAM_SIZE MEMORY { FLASH (RX) : origin = APP_BASE, length = APP_SIZE FWID (R) : origin = FW_ID_BASE, length = FW_ID_SIZE, fill = 0xFFFFFFFF CRC (R) : origin = CRC_BASE, length = CRC_SIZE SRAM (RWX) : origin = RAM_BASE, length = RAM_SIZE HFLT (RW) : origin = HFLT_BASE, length = HFLT_SIZE } /* The following command line options are set as part of the CCS project. */ /* If you are building using the command line, or for some reason want to */ /* define them here, you can uncomment and modify these lines as needed. */ /* If you are using CCS for building, it is probably better to make any such */ /* modifications in your CCS project and leave this file alone. */ /* */ /* --heap_size=0 */ /* --stack_size=256 */ /* --library=rtsv7M4_T_le_eabi.lib */ /* Section allocation in memory */ SECTIONS { .intvecs: load = APP_BASE .text : palign(32), load = FLASH .fwid : load = FWID .crc : load = CRC .const : palign(32), load = FLASH .cinit : palign(32), load = FLASH .pinit : palign(32), load = FLASH .init_array : > FLASH .stack : > RAM_BASE .vtable : > SRAM .data : > SRAM .bss : > SRAM .sysmem : > SRAM .hflt : > HFLT type = NOINIT }

  • Hi Jeff,

      The r0 is incorrect. 0x0 is a address to the flash memory. You can't push data onto flash and therefore, the flash controller will generate bus error when it is written. The stack will be on SRAM which starts at 0x20000000. You will need to roll some instructions to find out why the r0 was loaded the wrong value. 

  • Hi Charles,

    I appreciate the confirmation. That line is buried well within the FreeRTOS port.asm file. I have no explanation as to why that is causing the fault. 

    One thing I noticed, on the one example project that is available, the optimization is enabled to level 2 Global optimizations. For fun I tried it. The problem went away. This does not give me a warm and fuzzy feeling. I'll be posting on their message board. 

    Thanks again!

  • Hi Jeff,

      How did you increase the stack size? Normally, the linker command will have the below example line but I don't see in you .cmd file. Can you add this line to yours but replace the 4096 with the 32k you have? 

    __STACK_TOP = __stack + 4096;

  • Hi Charles,

    I have been updating via the project properties->arm linker->basic options->set c system stack size->32768. 

    I removed that line after rearranging the memory sections as part of the cmd file. My understanding is that was a legacy line required for a library that has either updated their search methods (using the standard compiler definition of __STACK_TOP) or no longer requires that definition.

    Is that not a correct assumption?

    Thanks,

    Jeff

  • Hi Jeff,

      The __STACK_TOP is a pointer to the top of the stack that will be loaded to the SP register. Please see below startup_ccs.c. Are you not using the standard startup_ccs.c file. How are you loading the SP register?

    //*****************************************************************************
    //
    // 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.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler

  • Hi Charles,

    Agreed. I did need to update my startup_ccs file. I swapped out __STACK_TOP with __STACK_END which appear to be identical defined addresses. __STACK_END just being a compiler supported definition removing the requirement of defining stack size in two locations. (I am terrible at remembering to update both).

    Cheers,

    Jeff

     

  • Hi Jeff,

      Can you please let me know if the issue is hence resolved?