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.
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!
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?
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