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.

Start relocated application from bootloader running from flash on M3 core.

Other Parts Discussed in Thread: CC2650, SYSBIOS, CC2640

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?

  • Hi Gerrit,

    Let me look at this today and I will get back to you. I'm going to try to relocate a CC2650 to the 1st flash sector and see what I run into.
  • OK Gerrit, I've got good and bad news.

    Good news, I got to the bottom of the kernel relocation business. I'm seeing it as well. I went throught the same steps as you described and you're on good track. The const entries you're seeing are automagically generated by SYS/BIOS' ROM module. These are hardcode references to point to RTSC module const structs.

    That's where I start with the bad news... You can't get rid of them while using the ROM module for your application. This is hindsight constraint that we've run into with the CC2650 (only) so far. To turn off the ROM, you need to comment out:

    //var ROM = xdc.useModule('ti.sysbios.rom.ROM');
    //ROM.romName = ROM.CC2650;

    As a result, your application will have flash size impact. I believe the max will be ~8KB. If you take out the ROM module, your app should link properly.

  • Hello Tom,

    Thanks for the reply.
    Question1: Is this a chip related problem or CCS related?
    Question2: If it is chip related, I assume the other chips in the same range (e.g. CC2640) has the same problem?
    Question3: If it is CCS related, is there a planned SW update that will solve this?

    I followed your suggestion, and indeed the mesh-up of the first FLASH segment has been solved.
    The FLASH size penalty was 14 KB in my case (but I am running in Debug configuration; the Release configuration might consume less FLASh memory)
    Now I am able to run the application a bit further, but still it crashes before the main is started.
    The crash happens somewhere in the SYS-BIOS, were it jumps to an exit routine.
    Question4: Is there an easy way to debug these kind of exits? I have seen it more often and it is hard to debug it because you do not have history information; e.g. there is no call stack.
    I can image there is a CCS plugin that assists in these kind of SYS-BIOS exceptions.

    When debugging this I was able to pinpoint the problem to the next spot:
    Before the main is called, several initializations are done. One of them is the startup of several SYS-BOIS modules:
    - ti_sysbios_knl_Clock_Module_startup_E()
    - ti_sysbios_knl_Swi_Module_startup_E()
    - ti_sysbios_knl_Task_Module_startup_E()
    - ti_sysbios_hal_Hwi_Module_startup_E()
    - ti_sysbios_family_arm_m3_Hwi_Module_startup_E()
    During this last call the crash does happen; to be exact: at line 277 in the module:
    "C:\ti\tirtos_simplelink_2_13_01_09\products\bios_6_42_00_08\packages\ti\sysbios\family\arm\m3\hwi.c"
    Question5: Do you have an idea what is causing this? I guess one or another configuration setting in the cfg file.

    While debugging I run into another problem: suddenly I cannot flash anymore.
    CCS refuses it with the next error:

    So my JTAG connection seesm to have a problem.
    Now I test the JTAG connection via the *.cccml file where there is a 'Test Connection' feature in the 'Advanced' TAB
    When running this, the following result is show:

    [Result]
    
    
    -----[Print the board config pathname(s)]------------------------------------
    
    C:\Users\gerrit\AppData\Local\TEXASI~1\CCS\
        ti\0\0\BrdDat\testBoard.dat
    
    -----[Print the reset-command software log-file]-----------------------------
    
    This utility has selected a 100- or 510-class product.
    This utility will load the adapter 'jioserdesusbv3.dll'.
    The library build date was 'Jul 23 2015'.
    The library build time was '19:45:35'.
    The library package version is '6.0.14.0'.
    The library component version is '35.35.0.0'.
    The controller does not use a programmable FPGA.
    The controller has a version number of '4' (0x00000004).
    The controller has an insertion length of '0' (0x00000000).
    This utility will attempt to reset the controller.
    This utility has successfully reset the controller.
    
    -----[Print the reset-command hardware log-file]-----------------------------
    
    The scan-path will be reset by toggling the JTAG TRST signal.
    The controller is the FTDI FT2232 with USB interface.
    The link from controller to target is direct (without cable).
    The software is configured for FTDI FT2232 features.
    The controller cannot monitor the value on the EMU[0] pin.
    The controller cannot monitor the value on the EMU[1] pin.
    The controller cannot control the timing on output pins.
    The controller cannot control the timing on input pins.
    The scan-path link-delay has been set to exactly '0' (0x0000).
    
    An error occurred while hard opening the controller.
    
    -----[An error has occurred and this utility has aborted]--------------------
    
    This error is generated by TI's USCIF driver or utilities.
    
    The value is '-230' (0xffffff1a).
    The title is 'SC_ERR_PATH_MEASURE'.
    
    The explanation is:
    The measured lengths of the JTAG IR and DR scan-paths are invalid.
    This indicates that an error exists in the link-delay or scan-path.
    
    [End: Texas Instruments XDS100v3 USB Debug Probe]

    This indicated a to a problem in the driver (TI's USCIF)

    In the E2E forum and the internet I could not find a satisfying answer for this problem.
    The only hint I found to update the TI emupack.
    I downloaded and installed the latest version (July 15). But this did not help.
    By the way: when installing this emupack, it replies with the following error message:

    This can be solved by running the install as administrator.
    Hint: add this suggestion in the error message, which can save some searching time for the user (like me).

    So, now I cannot debug further anymore. Maybe this is a target hardware problem, but I can change the HW only mid next week.
    Question6: do you have a solution for this problem?
    Right now, this is the blocking item for me. When there is no solution for this problem next week, I suggest that I move this problem to another threat in order to keep the problem discussions clean.

  • Gerrit,

    Question1: Is this a chip related problem or CCS related?
    Question2: If it is chip related, I assume the other chips in the same range (e.g. CC2640) has the same problem?
    Question3: If it is CCS related, is there a planned SW update that will solve this?

    Not CCS. It's a tricky situation with the way RTSC module work and how we've implemented this with the ROM. We suspect that there is a way to do this, but it's not a clean solution and we don't have any good instructions to do this yet.

    Question4: Is there an easy way to debug these kind of exits? I have seen it more often and it is hard to debug it because you do not have history information; e.g. there is no call stack.

    There should be a callstack. It should look like something as shown here. No CCS plug-ins are needed.

    - ti_sysbios_family_arm_m3_Hwi_Module_startup_E()
    During this last call the crash does happen; to be exact: at line 277 in the module:
    "C:\ti\tirtos_simplelink_2_13_01_09\products\bios_6_42_00_08\packages\ti\sysbios\family\arm\m3\hwi.c"
    Question5: Do you have an idea what is causing this? I guess one or another configuration setting in the cfg file.

    Can you verify that the Hwi's dispatchTable is in SRAM, not in flash? See the .map file for "ti_sysbios_family_arm_m3_Hwi_dispatchTable"

    While debugging I run into another problem: suddenly I cannot flash anymore.

    You may have bricked your device. See the CC2650 FAQ. Let's see if this helps you out. If it doesn't then you may need to post a question on the Bluetooth Low Energy Forum.

  • Hello Tom,

    The shown callstack is indeed the callstack I see in case of a SYS-BIOS call to exit. What I meant was that this call stack does not indicate the cause. E.g. when I make a wrong call to a SYS-BIOS routine by providing wrong parameters, such an exit may happen, and then you don't know what went wrong.
    Is there an easy way to show the (possible) cause of such an exit call?

    Regarding the 'bricked device' problem: that is solved now.
    When exchanging the 26CC50 board with another one, the problem was solved.
    The 'bricked device' is also 'repaired' now by simply erasing the complete flash via another tool: the TI programmer.

    The SYS-BIOS routine that is crashing now is indeed located in FLASH, but my board is working again and  I can continue debugging this problem.
    I will notify when this problem is solved or if I need further support.

    Greetings,
    Gerrit Slot

  • Hello Tom,

    My problem is solved now. The mentioned crash situation is solved now, without making any changes. I guess the experienced crash situation was the introduction to the device getting 'bricked'. Why that happened is unclear to me, but I have a stable situation again.
    Thanks for the support.
  • Disabling the ROM module seems to have a sideeffect: SysCallback does not seem to work as before. For instance:

    SysCallback.putchFxn = "&uartPrintf_putch";   

    Does not have any effect anymore. Is there a way to fix this?

  • Let me answer my own question: you can fix this by adding this to your cfg:

    System.SupportProxy = SysCallback;

  • So, what is the current situation regarding this? Has there been made any progress in newer version that might remedy this problem and save us some flash?
  • Which problem are you talking about? These thread is getting pretty long. Can you please open a new thread and reference this one. Please include the versions and device you are using.

    Todd
  • I'm talking about the initial problem of the thread: that you cannot use the ROM version of driverlib if you relocate the kernel, like when your application does not start at the default address (what is mostly the case if you use a separate bootloader). I hardly think that this would need a new topic. We're currently on version 2.16.00.08.

  • The dynamic relocation problem is due to the contents of the ROM kernel code itself. It is not a fixable problem if you are using the ROM-based TI-RTOS kernel.

    ROM based driverlib calls are not related to this issue.

    Alan
  • Hi,
    I see that "RTOS in ROM look-up table" is not relocatable as mentioned here and in this post:
    https://e2e.ti.com/support/wireless_connectivity/bluetooth_low_energy/f/538/t/433035

    So, using kernel ROM leads to linker error when FLASH_BASE has offset.
    Now assume we have an Application_A with FLASH_BASE and resetVectorAddress 0x0, using kernel ROM. It will be compiled and linked with no problem.
    And we have an Application_B with FLASH_BASE and resetVectorAddress 0x4000, using kernel ROM again. linker.cmd file will be generated and we get a linker error.

    Then arrange linker.cmd so SECTIONS will look like this:

    SECTIONS
    {
    .data:ti_sysbios_knl_Clock_Module__state__V: LOAD > 0x20000178
    .data:ti_sysbios_family_arm_cc26xx_TimestampProvider_Module__state__V: LOAD > 0x200001ec
    .data:xdc_runtime_Startup_Module__state__V: LOAD > 0x200001f0
    .data:ti_sysbios_BIOS_Module__state__V: LOAD > 0x200001a4
    .data:ti_sysbios_knl_Swi_Module__state__V: LOAD > 0x200001c8
    .data:ti_sysbios_knl_Task_Module__state__V: LOAD > 0x20000100
    .data:xdc_runtime_Memory_Module__state__V: LOAD > 0x20000200
    .data:xdc_runtime_System_Module__state__V: LOAD > 0x200001f8
    .data:ti_sysbios_family_arm_m3_Hwi_Module__state__V: LOAD > 0x20000144
    .data:ti_sysbios_family_arm_cc26xx_Timer_Module__state__V: LOAD > 0x200001e4
    }

    Now, Application_B will be linked with no error and look-up table stands where it should, thanks to Application_A.
    Is this a healthy workaround?

    Thanks,
    Caglar

  • Can you please open a new thread? This one is too long and makes the search engine less effective.

    Todd