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