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.

CCS/TM4C129ENCPDT: Linkerscript gcc

Part Number: TM4C129ENCPDT
Other Parts Discussed in Thread: SEGGER, UNIFLASH

Tool/software: Code Composer Studio

Dear TI-Team

My FreeRTOS projcet is running fine at address 0. Now i want to use a bootloader (works fine on other projects).

My problem is, that i am not able to set an offset in the flash-memory. I changed the flash origin and the intvect base address.

When i flash the bootloader with the LM Flash tool everything is fine, but when i send my code to the µC it overrides the bootloader and therefore my programm isn't able to run.

The project is using:

- TM4C129ENCPDT

- CCSv8

- Linaro v7.2.1 compiler with libc_nano runtime library.

- Segger Jlink

What am i missing here?

(standard ld file form the tCTivaWare lib with space for privileged function and privileged data)

Linker script:

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


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

_vRamTop = ORIGIN( SRAM ) + LENGTH( SRAM );

/* Variables used by FreeRTOS-MPU. */
_Privileged_Functions_Region_Size = 16K;
_Privileged_Data_Region_Size = 512;

__FLASH_segment_start__ = ORIGIN( FLASH );
__FLASH_segment_end__ = __FLASH_segment_start__ + LENGTH( FLASH );

__privileged_functions_start__ = ORIGIN( FLASH );
__privileged_functions_end__ = __privileged_functions_start__ + _Privileged_Functions_Region_Size;

__SRAM_segment_start__ = ORIGIN( SRAM );
__SRAM_segment_end__ = __SRAM_segment_start__ + LENGTH( SRAM );

__privileged_data_start__ = ORIGIN( SRAM );
__privileged_data_end__ = ORIGIN( SRAM ) + _Privileged_Data_Region_Size;

ENTRY(ResetISR)

SECTIONS {

    PROVIDE (_intvecs_base_address = 0x00004000);

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

    privileged_functions : {
    	*(privileged_functions)
    	. = _Privileged_Functions_Region_Size;
    } > FLASH

    .text : {
    /* Non privileged code kept out of the _Privileged_Functions_Region_Size or flash. */
    	. = __privileged_functions_start__ + _Privileged_Functions_Region_Size;

        CREATE_OBJECT_SYMBOLS
        *(.text)
        *(.text.*)
        . = ALIGN(0x4);
        KEEP (*(.ctors))
        . = ALIGN(0x4);
        KEEP (*(.dtors))
        . = ALIGN(0x4);
        PROVIDE(__preinit_array_start = .);
        KEEP (*(.preinit_array*))
        PROVIDE(__preinit_array_end = .);
        . = ALIGN(0x4);
        PROVIDE(__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
        PROVIDE(__init_array_end = .);
        KEEP(*(.init))
        . = ALIGN(0x4);
        PROVIDE(__fini_array_start = .);
        KEEP (*(.fini_array*))
        PROVIDE(__fini_array_end = .);
        KEEP(*(.fini))
    } > FLASH


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

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

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

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

    _etext = .;

    privileged_data : {
    	__bss_start__ = .;
    	*(privileged_data)
    } > SRAM

    . = ORIGIN( SRAM ) + _Privileged_Data_Region_Size;

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

    .data : ALIGN (4) {
        __data_load__ = LOADADDR (.data);
        __data_start__ = .;
        *(.vtable)
        *(.data)
        *(.data*)
        . = ALIGN (4);
        __data_end__ = .;
    } > SRAM AT> FLASH


    .heap : {
        __heap_start__ = .;
        end = __heap_start__;
        _end = end;
        __end = end;
        KEEP(*(.heap))
        __heap_end__ = .;
        __HeapLimit = __heap_end__;
    } > SRAM

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

}

(i just modified the RTOS handlers and the asm code since i am using c++ and i dont want to use the init_array code from the stdlib)

Startup script:

//*****************************************************************************
//
// Startup code for use with TI's Code Composer Studio and GNU tools.
//
// Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************

#include <stdint.h>
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"

//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************
void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);
static void MPUFaultHandler(void);

#ifndef HWREG
#define HWREG(x) (*((volatile uint32_t *)(x)))
#endif


//*****************************************************************************
//
// The entry point for the application.
//
//*****************************************************************************
extern int main(void);

//*****************************************************************************
//
// Reserve space for the system stack.
//
//*****************************************************************************
static uint32_t pui32Stack[256];

//*****************************************************************************
//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
extern void xPortPendSVHandler(void);
extern void vPortSVCHandler(void);
extern void xPortSysTickHandler(void);

//*****************************************************************************
//
// 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.
//
//*****************************************************************************
//try()
__attribute__ ((section(".intvecs")))
void (* const g_pfnVectors[])(void) =
{
    (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)),
                                            // The initial stack pointer
    ResetISR,                               // The reset handler
    NmiSR,                                  // The NMI handler
    FaultISR,                               // The hard fault handler
    MPUFaultHandler,                        // The MPU fault handler
    IntDefaultHandler,                      // The bus fault handler
    IntDefaultHandler,                      // The usage fault handler
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    vPortSVCHandler,                        // SVCall handler
    IntDefaultHandler,                      // Debug monitor handler
    0,                                      // Reserved
    xPortPendSVHandler,                     // The PendSV handler
    xPortSysTickHandler,                    // The SysTick handler
    IntDefaultHandler,                      // GPIO Port A
    IntDefaultHandler,                      // GPIO Port B
    IntDefaultHandler,                      // GPIO Port C
    IntDefaultHandler,                      // GPIO Port D
    IntDefaultHandler,                      // GPIO Port E
    IntDefaultHandler,                      // UART0 Rx and Tx
    IntDefaultHandler,                      // UART1 Rx and Tx
    IntDefaultHandler,                      // SSI0 Rx and Tx
    IntDefaultHandler,                      // I2C0 Master and Slave
    IntDefaultHandler,                      // PWM Fault
    IntDefaultHandler,                      // PWM Generator 0
    IntDefaultHandler,                      // PWM Generator 1
    IntDefaultHandler,                      // PWM Generator 2
    IntDefaultHandler,                      // Quadrature Encoder 0
    IntDefaultHandler,                      // ADC Sequence 0
    IntDefaultHandler,                      // ADC Sequence 1
    IntDefaultHandler,                      // ADC Sequence 2
    IntDefaultHandler,                      // ADC Sequence 3
    IntDefaultHandler,                      // Watchdog timer
    IntDefaultHandler,                      // Timer 0 subtimer A
    IntDefaultHandler,                      // Timer 0 subtimer B
    IntDefaultHandler,                      // Timer 1 subtimer A
    IntDefaultHandler,                      // Timer 1 subtimer B
    IntDefaultHandler,                      // Timer 2 subtimer A
    IntDefaultHandler,                      // Timer 2 subtimer B
    IntDefaultHandler,                      // Analog Comparator 0
    IntDefaultHandler,                      // Analog Comparator 1
    IntDefaultHandler,                      // Analog Comparator 2
    IntDefaultHandler,                      // System Control (PLL, OSC, BO)
    IntDefaultHandler,                      // FLASH Control
    IntDefaultHandler,                      // GPIO Port F
    IntDefaultHandler,                      // GPIO Port G
    IntDefaultHandler,                      // GPIO Port H
    IntDefaultHandler,                      // UART2 Rx and Tx
    IntDefaultHandler,                      // SSI1 Rx and Tx
    IntDefaultHandler,                      // Timer 3 subtimer A
    IntDefaultHandler,                      // Timer 3 subtimer B
    IntDefaultHandler,                      // I2C1 Master and Slave
    IntDefaultHandler,                      // CAN0
    IntDefaultHandler,                      // CAN1
    IntDefaultHandler,                      // Ethernet
    IntDefaultHandler,                      // Hibernate
    IntDefaultHandler,                      // USB0
    IntDefaultHandler,                      // PWM Generator 3
    IntDefaultHandler,                      // uDMA Software Transfer
    IntDefaultHandler,                      // uDMA Error
    IntDefaultHandler,                      // ADC1 Sequence 0
    IntDefaultHandler,                      // ADC1 Sequence 1
    IntDefaultHandler,                      // ADC1 Sequence 2
    IntDefaultHandler,                      // ADC1 Sequence 3
    IntDefaultHandler,                      // External Bus Interface 0
    IntDefaultHandler,                      // GPIO Port J
    IntDefaultHandler,                      // GPIO Port K
    IntDefaultHandler,                      // GPIO Port L
    IntDefaultHandler,                      // SSI2 Rx and Tx
    IntDefaultHandler,                      // SSI3 Rx and Tx
    IntDefaultHandler,                      // UART3 Rx and Tx
    IntDefaultHandler,                      // UART4 Rx and Tx
    IntDefaultHandler,                      // UART5 Rx and Tx
    IntDefaultHandler,                      // UART6 Rx and Tx
    IntDefaultHandler,                      // UART7 Rx and Tx
    IntDefaultHandler,                      // I2C2 Master and Slave
    IntDefaultHandler,                      // I2C3 Master and Slave
    IntDefaultHandler,                      // Timer 4 subtimer A
    IntDefaultHandler,                      // Timer 4 subtimer B
    IntDefaultHandler,                      // Timer 5 subtimer A
    IntDefaultHandler,                      // Timer 5 subtimer B
    IntDefaultHandler,                      // FPU
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // I2C4 Master and Slave
    IntDefaultHandler,                      // I2C5 Master and Slave
    IntDefaultHandler,                      // GPIO Port M
    IntDefaultHandler,                      // GPIO Port N
    0,                                      // Reserved
    IntDefaultHandler,                      // Tamper
    IntDefaultHandler,                      // GPIO Port P (Summary or P0)
    IntDefaultHandler,                      // GPIO Port P1
    IntDefaultHandler,                      // GPIO Port P2
    IntDefaultHandler,                      // GPIO Port P3
    IntDefaultHandler,                      // GPIO Port P4
    IntDefaultHandler,                      // GPIO Port P5
    IntDefaultHandler,                      // GPIO Port P6
    IntDefaultHandler,                      // GPIO Port P7
    IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
    IntDefaultHandler,                      // GPIO Port Q1
    IntDefaultHandler,                      // GPIO Port Q2
    IntDefaultHandler,                      // GPIO Port Q3
    IntDefaultHandler,                      // GPIO Port Q4
    IntDefaultHandler,                      // GPIO Port Q5
    IntDefaultHandler,                      // GPIO Port Q6
    IntDefaultHandler,                      // GPIO Port Q7
    IntDefaultHandler,                      // GPIO Port R
    IntDefaultHandler,                      // GPIO Port S
    IntDefaultHandler,                      // SHA/MD5 0
    IntDefaultHandler,                      // AES 0
    IntDefaultHandler,                      // DES3DES 0
    IntDefaultHandler,                      // LCD Controller 0
    IntDefaultHandler,                      // Timer 6 subtimer A
    IntDefaultHandler,                      // Timer 6 subtimer B
    IntDefaultHandler,                      // Timer 7 subtimer A
    IntDefaultHandler,                      // Timer 7 subtimer B
    IntDefaultHandler,                      // I2C6 Master and Slave
    IntDefaultHandler,                      // I2C7 Master and Slave
    IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
    IntDefaultHandler,                      // One Wire 0
    IntDefaultHandler,                      // HIM PS/2 0
    IntDefaultHandler,                      // HIM LED Sequencer 0
    IntDefaultHandler,                      // HIM Consumer IR 0
    IntDefaultHandler,                      // I2C8 Master and Slave
    IntDefaultHandler,                      // I2C9 Master and Slave
    IntDefaultHandler,                      // GPIO Port T
    IntDefaultHandler,                      // Fan 1
    0,                                      // Reserved
};

//*****************************************************************************
//
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory.  The initializers for the
// for the "data" segment resides immediately following the "text" segment.
//
//*****************************************************************************
extern uint32_t __data_load__;
extern uint32_t __data_start__;
extern uint32_t __data_end__;
extern uint32_t __bss_start__;
extern uint32_t __bss_end__;

//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event.  Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called.  Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//
//*****************************************************************************
void
ResetISR(void)
{
    uint32_t *pui32Src, *pui32Dest;

    //
    // Copy the data segment initializers from flash to SRAM.
    //
    pui32Src = &__data_load__;
    for(pui32Dest = &__data_start__; pui32Dest < &__data_end__; )
    {
        *pui32Dest++ = *pui32Src++;
    }

    //
    // Zero fill the bss segment.
    //
    __asm("    .thumb_func\n"
          "    ldr     r0, =__bss_start__\n"
          "    ldr     r1, =__bss_end__\n"
          "    mov     r2, #0\n"
          "bss_zero_loop:\n"
          "        cmp     r0, r1\n"
          "        it      lt\n"
          "        strlt   r2, [r0], #4\n"
          "        blt     bss_zero_loop\n\n");


    //
    // Enable the floating-point unit.  This must be done here to handle the
    // case where main() uses floating-point and the function prologue saves
    // floating-point registers (which will fault if floating-point is not
    // enabled).  Any configuration of the floating-point unit using DriverLib
    // APIs must be done here prior to the floating-point unit being enabled.
    //
    // Note that this does not use DriverLib since it might not be included in
    // this project.
    //
    HWREG(0xE000ED88) = ((HWREG(0xE000ED88) & ~0x00F00000) | 0x00F00000);


    __asm("    ldr r0, =__init_array_start\n"
          "    ldr r1, =__init_array_end\n"
          "globals_init_loop:\n"
          "        cmp     r0, r1\n"
          "        it      lt\n"
          "        ldrlt   r2, [r0], #4\n"
          "        blxlt   r2\n"
          "        blt     globals_init_loop");

    main();

}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI.  This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
static void
NmiSR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
FaultISR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives an unexpected
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
IntDefaultHandler(void)
{
    //
    // Go into an infinite loop.
    //
    while(1)
    {
    }
}

static void
MPUFaultHandler(void)
{
    //
    // Go into an infinite loop.
    //
    while(1)
    {
    }
}

regards,

Lukas

  • Hello Lukas,

    Lukas Thumfart said:
    but when i send my code to the µC it overrides the bootloader and therefore my programm isn't able to run.

    Can you describe this step better? Are you using the bootloader to load the code? An IDE? LM Flash? Uniflash? I need to know how you are trying to upload code after the bootloader has been loaded to better offer feedback.

  • I erase the device with J-Link commander, so that i can flash the bootloader with LM-Flash (DFU).

    Currently i want to flash and debug the programm with a Segger J-Link. Later on i want to flash the binary of the project with the LM-Flasher too (setting the start address).

    The flags for the GNU compiler, linker and object utility are set in the CodeComposerStudio 8.3.

    i followed the guide from: https://e2e.ti.com/support/microcontrollers/other/f/908/p/479812/1728894

    and modified the linkerscript and startabcode to following:

    startup:

    //*****************************************************************************
    //
    // Startup code for use with TI's Code Composer Studio and GNU tools.
    //
    // Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Software License Agreement
    //
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    static void MPUFaultHandler(void);
    
    #ifndef HWREG
    #define HWREG(x) (*((volatile uint32_t *)(x)))
    #endif
    
    
    //*****************************************************************************
    //
    // The entry point for the application.
    //
    //*****************************************************************************
    extern int main(void);
    
    //*****************************************************************************
    //
    // Reserve space for the system stack.
    //
    //*****************************************************************************
    extern char *__StackTop;
    
    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    extern void xPortPendSVHandler(void);
    extern void vPortSVCHandler(void);
    extern void xPortSysTickHandler(void);
    
    //*****************************************************************************
    //
    // 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.
    //
    //*****************************************************************************
    //try()
    __attribute__ ((section(".intvecs")))
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))&__StackTop,            // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        MPUFaultHandler,                        // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        vPortSVCHandler,                        // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        xPortPendSVHandler,                     // The PendSV handler
        xPortSysTickHandler,                    // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        IntDefaultHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler,                      // GPIO Port T
        IntDefaultHandler,                      // Fan 1
        0,                                      // Reserved
    };
    
    //*****************************************************************************
    //
    // The following are constructs created by the linker, indicating where the
    // the "data" and "bss" segments reside in memory.  The initializers for the
    // for the "data" segment resides immediately following the "text" segment.
    //
    //*****************************************************************************
    extern uint32_t __data_load__;
    extern uint32_t __data_start__;
    extern uint32_t __data_end__;
    extern uint32_t __bss_start__;
    extern uint32_t __bss_end__;
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        uint32_t *pui32Src, *pui32Dest;
    
        //
        // Copy the data segment initializers from flash to SRAM.
        //
        pui32Src = &__data_load__;
        for(pui32Dest = &__data_start__; pui32Dest < &__data_end__; )
        {
            *pui32Dest++ = *pui32Src++;
        }
    
        //
        // Zero fill the bss segment.
        //
        __asm("    .thumb_func\n"
              "    ldr     r0, =__bss_start__\n"
              "    ldr     r1, =__bss_end__\n"
              "    mov     r2, #0\n"
              "bss_zero_loop:\n"
              "        cmp     r0, r1\n"
              "        it      lt\n"
              "        strlt   r2, [r0], #4\n"
              "        blt     bss_zero_loop\n\n");
    
    
        //
        // Enable the floating-point unit.  This must be done here to handle the
        // case where main() uses floating-point and the function prologue saves
        // floating-point registers (which will fault if floating-point is not
        // enabled).  Any configuration of the floating-point unit using DriverLib
        // APIs must be done here prior to the floating-point unit being enabled.
        //
        // Note that this does not use DriverLib since it might not be included in
        // this project.
        //
        HWREG(0xE000ED88) = ((HWREG(0xE000ED88) & ~0x00F00000) | 0x00F00000);
    
        //init_array without stdlib
        __asm("    ldr r0, =__init_array_start\n"
              "    ldr r1, =__init_array_end\n"
              "globals_init_loop:\n"
              "        cmp     r0, r1\n"
              "        it      lt\n"
              "        ldrlt   r2, [r0], #4\n"
              "        blxlt   r2\n"
              "        blt     globals_init_loop");
    
    
        //
        // Call the application's entry point.
        //
        main();
    
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    
    static void
    MPUFaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    

    linker script:

    /******************************************************************************
     *
     * Default Linker script for the Texas Instruments TM4C129ENCPDT
     *
     * This is derived from revision 15071 of the TivaWare Library.
     *
     *****************************************************************************/
    
    
    MEMORY
    {
    	/*BOOTLD (RX): ORIGIN = 0x000000000, LENGTH = 0x00004000*/
        FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00100000
        SRAM (WX)  : ORIGIN = 0x20000000, LENGTH = 0x00040000
    }
    
    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);
    
    
    /* Variables used by FreeRTOS-MPU. */
    _Privileged_Functions_Region_Size = 16K;
    _Privileged_Data_Region_Size = 1024;
    
    __FLASH_segment_start__ = ORIGIN( FLASH );
    __FLASH_segment_end__ = __FLASH_segment_start__ + LENGTH( FLASH );
    
    __privileged_functions_start__ = ORIGIN( FLASH );
    __privileged_functions_end__ = __privileged_functions_start__ + _Privileged_Functions_Region_Size;
    
    __SRAM_segment_start__ = ORIGIN( SRAM );
    __SRAM_segment_end__ = __SRAM_segment_start__ + LENGTH( SRAM );
    
    __privileged_data_start__ = ORIGIN( SRAM );
    __privileged_data_end__ = ORIGIN( SRAM ) + _Privileged_Data_Region_Size;
    
    /*
     * The '__stack' definition is required by crt0, do not remove it.
     */
    __stack = ORIGIN(SRAM) + LENGTH(SRAM);
    _estack = __stack;
    
    
    /*
     * The entry point is informative, for debuggers and simulators,
     * since the Cortex-M vector points to it anyway.
     */
    ENTRY(ResetISR)
    
    SECTIONS {
    
    
        PROVIDE (_intvecs_base_address = 0x00000000);
    
        .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
    
        privileged_functions : {
        	. = ALIGN(4);
        	*(privileged_functions)
        	__privileged_functions_actual_end__ = .;
        	. = _Privileged_Functions_Region_Size;
        } > FLASH
    
    
        .text : {
        /* Non privileged code kept out of the _Privileged_Functions_Region_Size or flash. */
        	. = __privileged_functions_start__ + _Privileged_Functions_Region_Size;
    
    		CREATE_OBJECT_SYMBOLS
    		. = ALIGN(0x4);
            *(.text)
            *(.text.*)
            . = ALIGN(0x4);
            KEEP (*(.ctors))
            . = ALIGN(0x4);
            KEEP (*(.dtors))
            . = ALIGN(0x4);
            PROVIDE(__preinit_array_start = .);
            KEEP (*(.preinit_array*))
            PROVIDE(__preinit_array_end = .);
            . = ALIGN(0x4);
            PROVIDE(__init_array_start = .);
            KEEP (*(SORT(.init_array.*)))
    		KEEP (*(.init_array))
            PROVIDE(__init_array_end = .);
            . = ALIGN(0x4);
            PROVIDE(__fini_array_start = .);
            KEEP (*(SORT(.fini_array.*)))
            KEEP (*(.fini_array))
            PROVIDE(__fini_array_end = .);
            . = ALIGN(0x4);
            *(.init)
            *(.fini)
        } > REGION_TEXT
    
    
        PROVIDE (__etext = .);
        PROVIDE (_etext = .);
        PROVIDE (etext = .);
    
        .rodata : {
            *(.rodata)
            *(.rodata*)
        } > REGION_TEXT
    
        privileged_data : {
        	*(privileged_data)
    		__privileged_data_actual_end__ = .;
    		/*. = _Privileged_Data_Region_Size;*/
        } > SRAM
    
    	.data : ALIGN (4) {
            __data_load__ = LOADADDR (.data);
            __data_start__ = .;
            *(.data)
            *(.data*)
            . = ALIGN (4);
            __data_end__ = .;
        } > REGION_DATA AT> REGION_TEXT
    
        .ARM.extab : {
            *(.ARM.extab* .gnu.linkonce.armextab.*)
        } > REGION_ARM_EXIDX
    
        .ARM.exidx : {
            __exidx_start = .;
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
            __exidx_end = .;
        } > REGION_ARM_EXTAB
    
        .bss : {
            __bss_start__ = .;
            *(.shbss)
            *(.bss)
            *(.bss.*)
            *(COMMON)
            . = ALIGN (4);
            __bss_end__ = .;
        } > REGION_BSS
    
        .heap : {
            __heap_start__ = .;
            end = __heap_start__;
            _end = end;
            __end = end;
            . = . + HEAPSIZE;
            KEEP(*(.heap))
            __heap_end__ = .;
            __HeapLimit = __heap_end__;
        } > REGION_HEAP
    
        .stack : ALIGN(0x8) {
            _stack = .;
            __stack = .;
            __StackTop = . ;
            . = . + STACKSIZE;
            KEEP(*(.stack))
        } > REGION_STACK
    
    }
    

    With this settings the RTOS task are doing fine.

    When i:

    - change  the FLASH to ORIGIN = 0x00004000, LENGTH = 0x000FC000

    - and the _intvecs_base_address = 0x0004000

    - flash the bootloader

    - and want to debug my program

    the CCS memory browser shows, that the region of the bootloader gets overwritten (by 0x0) and therefore im not able to run the program.

    Thank you in advance!

  • Hello Lukas,

    If you are using CCS it is probably doing a full flash erase due to default CCS flash settings. The linker file wouldn't change that behavior alone, you also need to tell CCS not to erase certain segments.

    You can adjust this for a project by launching a debug session, going to the Tools Menu, and select 'On-Chip Flash'. From there you can specify the address ranges that will be erased when going into debug by address range. This should let you avoid removing any code from 0x00000000 to 0x00004000. See if that solves your issue.
  • Since i am using the Segger J-Link there is no option like 'On-Chip Flash'. Sadly in the Debugconfigurations there is no option to preserve data from getting erased.

    At this point i dont think, that the J-Link EDU is overwriting my bootloader, since its 0x00 (seems like the FILL behaviour from GNU) and erasing with Segger is giving 0xFF.

    Is there another way to protect a section of the FLASH?

  • Hello Lukas,

    There is an MPU available for the device, but that may be a bit of overkill I feel. J-Link should be able to skip programming areas when the IDE is properly setup.

    And I wasn't trying to say specifically that the J-Link programmer alone was responsible, but it just programs based on the file output given to it (.bin, .hex etc.) so you need to make sure when that file is generated or when the IDE is used (which are the steps I was trying to describe), that it is setup to tell the programmer to skip over a section not FILL or ERASE said section.

    I don't know as much about GCC, but if you are using GCC via CCS, then you can ask the folks in the Code Composer Studio forum about how to prevent programming over sections of Flash with GCC: e2e.ti.com/.../
  • I am actually using the MPU-port of my RTOS to create restricted tasks. We former used the TI compiler, but we want to use some unit testing frameworks which require GNU. Therefore i ported the whole project. Without the offset from the bootloader the tasks are doing fine. I also have some issue with the size of the .bin-file. Looks like i dont understand the default fill behaviour of gcc.

    Is it possible to relocate this thread to the CCS-forum, so that all info is given?

    Thanks in advance.

    @the CCS Folks:

    Why is gcc overwriting my bootloader?

    Should i include the .hex of my bootloader to my project, that i can start debugging? If so, how to do it?

    regards Lukas

  • Hello Lukas,

    I will direct this thread to the CCS folks.

    In the future you can also use Ask a Related Question and it will create a link back to the post you created from so others can see the prior conversation.
  • This resolved my issue:
    e2e.ti.com/.../2930783
    thanks.

    regards,
    Lukas