Hello,
On a Cortex-M3 core, I want to start an (relocated) application from a bootloader running from the first pages in internal flash.
After reading several articles on the internet and this forum I made an implementation containing the several suggestions, but still I have a problem:
my application crashes somewhere in the start-up, where the JTAG connection is lost. See next screenshot
Development environment:
------------------------
IDE = CCS v6.1
Target = CC2650 MCU from TI, connected via the Wireless Connectivity Development Kit.
This CC2650 chip contains an ARM-M3 core.
The application does make use of TI-RTOS/SYS-BIOS.
The application which is crashing now, does run OK when locating it at address 0 (no bootloader)
When relocating it to another address (0x8000 in my example), and starting it from the bootloader located at address 0, it crashes even before the main is reached.
This crash location does happen on different locations (when stepping through the assembly)
This is what I have done:
-------------------------
STEP 1. create bootloader, running from address 0x0000
This bootloader does not run in RAM and it jumps to the application via the next routine:
;**************************************************************************** ;* C: void BL_jumpToApp(void *address): ;* ;* Description: Jump unconditionally to the address in [r0] ;* [r0] = address of the App (starting with the vector table) ;**************************************************************************** ; Vector Table Offset Register (CPU_SCS:VTOR): 0xE000ED08 CPU_SCS_BASE .set 0xE000E000 ; see <inc/hw_memmap.h> CPU_SCS_O_VTOR .set 0x0D08 ; see <inc/hw_cpu_scs.h> : Vector Table Offset CPU_SCS_VTOR_TBLOFF_S .set 7 ; see <inc/hw_cpu_scs.h> : TBLOFF shifts BL_jumpToApp: .asmfunc ; Shift address to the TBLOFF area in CPU_SCS:VTOR (bit 7-29) lsl r2, r0, #CPU_SCS_VTOR_TBLOFF_S ; Create Vector Table Offset Register reference mov r1, #CPU_SCS_O_VTOR orr r1, r1, #CPU_SCS_BASE ldr r3, [r1] ; Set the vector table address to the App address str r2, [r1] ldr r3, [r1] ; TEST: to see if writing to CPU_SCS:VTOR did succeed ; Update stack pointer from user code vector table ldr r1, [r0] mov sp, r1 ; Load user code reset handler and jump to the user code ldr r0, [r0, #4] bx r0
This function is called from the bootloader via BL_jumpToApp(0x08000), which will start the application.
This seems to work fine. The application starts at its ResetISR.
STEP 2. The linker file for the application looks as follows:
--retain=g_pfnVectors --entry_point ResetISR --args 0x8 /* Suppress warnings and errors: */ /* - 10063: Warning about entry point not being _c_int00 */ /* - 16011, 16012: 8-byte alignment errors. Observed when linking in object */ /* files compiled using Keil (ARM compiler) */ --diag_suppress=10063,16011,16012 #define BL_SIZE 0x8000 #define FLASH_BASE BL_SIZE #define FLASH_SIZE (0x20000 - BL_SIZE) #define RAM_BASE 0x20000000 #define RAM_SIZE 0x5000 #define APP_BASE BL_SIZE MEMORY { FLASH1 (RX) : origin = 0x00000000, length = BL_SIZE FLASH (RX) : origin = FLASH_BASE, length = FLASH_SIZE SRAM (RWX) : origin = RAM_BASE, length = RAM_SIZE } /* Section allocation in memory */ SECTIONS { /* .intvecs : load > FLASH_BASE */ .resetVecs : load > APP_BASE .text : > FLASH .const : > FLASH .constdata : > FLASH .rodata : > FLASH .cinit : > FLASH .pinit : > FLASH .init_array : > FLASH .emb_text : > FLASH .ccfg : > FLASH (HIGH) .vtable : > SRAM .vtable_ram : > SRAM vtable_ram : > SRAM .data : > SRAM .bss : > SRAM .sysmem : > SRAM .stack : > SRAM (HIGH) .nonretenvar : > SRAM } __STACK_TOP = __stack + __STACK_SIZE;
I created here an extra MEMORY region FLASH1, otherwise the automatic generated linker file for SYS-BIOS will overlap/conflict with this linker file.
STEP 3: Modify the linking order.
In the project properties I modified the linking order for the automatic generated linker file for SYS-BIOS and my own linker file (see above),
where my own linker file is executed first.
STEP 4: Modify the CFG file.
In the configuration file I have added the following lines:
var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
m3Hwi.resetVectorAddress = 0x00008000;
m3Hwi.vectorTableAddress = 0x00008000;
Questions:
---------
- What is wrong in described approach?
- I tried all kind of suggestions as you see. Are there redundant steps here?
- Is there somewhere a clean example with a clean CCS linker file (and configuration file?) that shows how to create a relocated application that is started from a bootloader running from internal flash?
- What does cause my crash with a JTAG disconnect (see screenshot)?
Relocation of SYS-BIOS?
-----------------------
I saw one issue in the generated map files which does not seem correct to me:
The complete application code should be located after 0x8000. However, some SYS-BIOS related code is still located in page 0, overwriting the bootloader program.
This SYS-BIOS code location is defined by the automatic generated linker file, where I show a fragment below:
.const:xdc_runtime_Error_policy__C: LOAD > 0x0000058c .const:xdc_runtime_IModule_Interface__BASE__C: LOAD > 0x00000538 .const:xdc_runtime_Startup_lastFxns__C: LOAD > 0x0000051c
This fragment will locate code at e.g. 0x0000058c, which will destroy the bootloader, which is located there.
So I can run my bootloader + application now only by first flashing the APP, then flashing the bootloader.
This is not OK of course, and is maybe the cause of my problem.
Here my last question is:
- How can I avoid this? How can I relocate this SYS-BIOS stuff in the automatic generated linker file?
Can anyone help me out here?