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.

TM4C129ENCPDT: Global Variables corrupted by being overwritten by local variables being placed in same location on the Stack

Part Number: TM4C129ENCPDT

I am having an issue with the Tiva C Tm4c129.  I understand globals are considered bad practice, but I am porting code that is presently working without issue on a lesser equipped m3 Stellaris mcu.  

I looked at the document for migration from Stellarisware to Tivaware.

I'm using GPIO, Uart, SSI, Systick and I2C peripherals without any issues and the code functions as expected.

The problem I am having is variables being overwritten. 

Everything appears to be fine but then within a function I find a function local array uses a RAM location already occupied by a global variable.

No matter what changes I make to stack size the problem persists.  I make other changes to reduce call stack depth and it just moves the problem to a new place.

I started with IAR 7.5, now am using IAR 8.32 for ARM.  I have tried using the default linker file, changing the stack size.  I've used linker and startup_ewarm from Tiva example folder.

At first I was having problems with strtok.  I would call it and after leaving would find a file global variable now had the same value as the pointer which was assigned by strtok to my token pointer.

Considering the migration from Stellaris, is using data types like unsigned int going to cause problems?  I looked at the map file and the size look correct.

What other things could cause this sort of behavior?  Any expert advice would be extremely appreciative!

Thank You.

  • Hello Dustin,

    How are you declaring the global variable? Do you have any optimizations on? Is the global variable being used across files, or in an ISR?
  • I have no optimizations enabled.  I've had trouble with both static variables declared towards the beginning of a file and only used in the file and also non static variables declared at the beginning of a file and externed for use across files.

    What is really strange to me is that I have plenty of ram.  The last processor I was using had 32kb, this one has 256kb.  I am pretty certain the stack is not growing into the data region.  In the linker I changed the start address of SRAM to 0x20010000.  The memory was overwritten in exactly the same way but the global variable location was offset 0x10000.  I make changes in code and now the problem is somewhere else.

  • Hello Dustin,

    I don't think this is a RAM issue personally.

    Have you tried declaring the globals as a volatile?

    If they are being used in any ISR's that can be really important to ensure the values are both updated and retained correctly.
  • I am not familiar with the IAR tools, but it looks like the stack is created in the file "startup_ewarm.c". The default version of this file (in project0) has the stack as size 64 words (256 bytes) and in a section ".noinit".  Does the IAR linker create a map file? What location is the location of the global variable that is being corrupted compared to the stack location? The stack starting address (high address) is programmed into location 0x00000000 of the flash.

    //*****************************************************************************
    //
    // Reserve space for the system stack.
    //
    //*****************************************************************************
    static uint32_t pui32Stack[64] @ ".noinit";
    
    //*****************************************************************************
    //
    // A union that describes the entries of the vector table.  The union is needed
    // since the first entry is the stack pointer and the remainder are function
    // pointers.
    //
    //*****************************************************************************
    typedef union
    {
        void (*pfnHandler)(void);
        uint32_t ui32Ptr;
    }
    uVectorEntry;
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000.
    //
    //*****************************************************************************
    __root const uVectorEntry __vector_table[] @ ".intvec" =
    {
        { .ui32Ptr = (uint32_t)pui32Stack + sizeof(pui32Stack) },
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
    

  • //*****************************************************************************
    //
    // The entry point for the application startup code.
    //
    //*****************************************************************************
    extern void __iar_program_start(void);
    
    //*****************************************************************************
    //
    // Reserve space for the system stack.
    //  (space is reserved by the linker, as specified in the IDE and .icf file)
    //
    //*****************************************************************************
    #pragma segment="CSTACK"
    
    //*****************************************************************************
    //
    // A union that describes the entries of the vector table.  The union is needed
    // since the first entry is the stack pointer and the remainder are function
    // pointers.
    //
    //*****************************************************************************
    typedef union
    {
        void (*pfnHandler)(void);
        void* __ptr;
    }
    uVectorEntry;
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000.
    //
    //*****************************************************************************
    __root const uVectorEntry __vector_table[] @ ".intvec" =
    {
    	{ .__ptr = __sfe( "CSTACK" ) },         // The initial stack pointer
        __iar_program_start,                    // The reset handler

    Thank you so Much!  That was the issue.  The original project for Stellaris was set up use the linker file to setup ram.  I changed my startup_ewarm.c to use the linker by changing to this.