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/CC1310: Problem when changing FLASH_BASE address: linker error

Part Number: CC1310
Other Parts Discussed in Thread: SYSBIOS

Tool/software: Code Composer Studio

Hi

I have an application, that I want to place from FLASH address 0x1000. This is based on a TI example project: rfSynchronizedPacketRx_CC1310

I am working on a bootloader, placed from 0x0000 - 0x0FFF ( 1 page, 4096 bytes). This is almost done. I only need to build my main application to start from page 1 = 0x1000.

I change the .cmd file like this:

/* The starting address of the application. Normally the interrupt vectors */
/* must be located at the beginning of the application. */
//#define FLASH_BASE 0x0000  // Original, used without bootloader. Works finw
//#define FLASH_SIZE 0x20000
#define FLASH_BASE 0x1000    // Application moved 1 page
#define FLASH_SIZE 0x1F000   // and length decreased 1 page
#define RAM_BASE 0x20000000
#define RAM_SIZE 0x5000

But when I change FLASH_BASE, I get these linker errors:

DEFAULT memory range overlaps existing memory range FLASH DEFAULT memory range overlaps existing memory range FLASH rfSynchronizedPacketRx_CC1310DK_7XD_tirtos_ccs C/C++ Problem

DEFAULT memory range overlaps existing memory range SRAM DEFAULT memory range overlaps existing memory range SRAM rfSynchronizedPacketRx_CC1310DK_7XD_tirtos_ccs C/C++ Problem

I have googled my self to death, and looked through the project settings, but I can not find anywhere, that there should be another definition of the FLASH BASE address.

Can anyone help me in the right direction?

Thanks!

Kaare

  • There are two issues you are encountering at the same time here. First of all, your reset vector is by default placed at address 0x0000'0000. This is outside any memory regions you have specified, and hence the linking will fail. You need to move the reset vector inside your flash region. Additionally, on CC13x0/CC26x0 devices, the reset vector MUST be 0x3C bytes aligned, meaning the smallest address within your specified flash region is address 0x0000'1010. This is set in your TI-RTOS .cfg file as such:

    /* ================ Hwi configuration ================ */
    var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
    ...
    m3Hwi.resetVectorAddress = 0x1010; /* must be 0x3C aligned */

    The second issue is that you most likely have configured TI-RTOS to be in ROM, which has an unfortunate coincidence. TI-RTOS in ROM requires jump tables placed in flash in order to operate, and this is hard coded. More specifically, TI-RTOS in ROM will place jump tables in the following address range 0x0000'1000 - 0x0000'14FE. Placing anything in this range will most certainly guarantee to fail. And lo and behold, the reset vector above is within this range. You can do two things: 1. either move the reset vector outside this range; or, 2. place TI-RTOS in flash.

    In order to place TI-RTOS in flash, set the following in your TI-RTOS .cfg file:

    /* ================ ROM configuration ================ */
    /*
     * To use BIOS in flash, comment out the code block below.
     */
    // Simple comment out the following lines.
    //var ROM = xdc.useModule('ti.sysbios.rom.ROM');
    //ROM.romName = ROM.CC1350;
    

    Note that I haven't mentioned correctly configuring the image valid address in CCFG, which is the address of the reset vector the ROM bootloader will jump to during boot. If your initial reset vector is your own custom bootloader in page 1, then you can probably leave it as is. 

    Now, this begs me to ask you the question; why do you want to write your own bootloader? 

  • Hi Severin

    Thanks for your response (and sorry for missing your response a couple of months ago. I did not see it...)

    To answer the your last question first: "Now, this begs me to ask you the question; why do you want to write your own bootloader? "
    I did not write my own bootloader. I have tweaked the TI bootloader example to my needs: I need to read the new image from an external memory, through a UART. I can't imagine that there is a standard way to do this :)

    My first problem is that I did not find any .cfg files in my project, but I realize now, that it is placed in the TI RTOS project.
    There are 3 .cfg files. I guess that it is the "release.cfg" I need to modify, as the other two are nearly empty.

    But in the same workspace, I have the bootloader project. I'm not sure if this includes the TI RTOS project settings?
    The bootloader is not based on TI RTOS directly, because of space constraints.
    Anyway, I can make a new workspace for the bootloader, to keep them separated.

    Next question:
    "The second issue is that you most likely have configured TI-RTOS to be in ROM"
    I did not, but TI did when they made the example I have based the project on :).
    If I place it in FLASH, I guess the penalty is much more code ?
    I have very limited FLASH available to my application already, so this would be a major drawback.

    Next question:
    "TI-RTOS in ROM will place jump tables in the following address range 0x0000'1000 - 0x0000'14FE"
    That may explain why the BIM example jumps to address 0x0000'1500 to start application, even if the application actually starts at 0x0000'1000 ?

    Next question:
    How can 0x0000'1010 be 0x3C aligned?

    To summarize:
    Is it possible to:
    1) #define FLASH_BASE 0x000'1000
    2) Change reste vector to 0x0000'1010

    That would be easy, I think, but there is so many details, that makes me pretty uncertain ...

    Thanks
    Kaare
  • 1) Yes, FLASH_BASE can be 0x0000'1000.
    2) Yes, if you put TI-RTOS in flash. And yes, that will increase flash usage of your application.
  • 1) OK

    2) Placing TI RTOS in FLASH is not an option, due to limited space left.

    From your description, it is not 100% clear what I must do, when I have the TI RTOS in ROM.

    You mention that JUMP vectors are placed from 0x0000'1000 and 2kB.

    But I am not sure what this means to my application, or how I should build it.

    Thanks

    Kaare

  • When having TI-RTOS in ROM, simply put the reset vector somewhere else than the range 0x1000 - 0x14FE.

    Regarding alignment of the reset vector address, I misread the error message from the TI-RTOS build locally. An alignment of 4 bytes is required, not 0x3C :) Hence, you can use the reset vector address 0x1500 if you want.

    Also, in your linker script, remember to set the FLASH_SIZE to be from page 1-30, not 1-31. That should equal FLASH_SIZE = 0x1E000. Additionally, you must remove the CCFG file from your project, as this should now be part of your bootloader project, and not the application.
  • Thanks, things are slowly getting more clear :)
    I will look into this in a couple of days (out of office next 1½ days)

    br
    Kaare
  • I have now done the following:

    - Main application starts from 0x0000'1000 and 30 pages

    - Removed ccfg file from project, and from the .cmd file, where I commented this, and moved (HIGH)

    .emb_text : > FLASH (HIGH)
    // .ccfg : > FLASH (HIGH)

    I can now build the main application, and binary looks right in my eyes :)

    Memorymap for the entire FLASH (128kB) should now be like this:

    0x0000'0000 : Bootloader (1 page)

    0x0000'1000 : TI RTOS jump table (part of the main application 30 pages)

    0x0000'1500 : Application start / interrupt vectors. Bootloader jumps to this address

    0x0001'F000 : Bootloader application + 88 bytes CCFG

    I have succeeded to program the application binary to location 0x0000'1000 and forth.

    I made a dump of all 128kB FLASH, and this looks fine, both bootloader pages and the application binary.

    But when I let the bootloader jump to 0x0000'1500, I end up in an exception handler:

    "ti_sysbios_family_arm_m3_Hwi_excHandler__I(unsigned int*, unsigned int)() at Hwi.c:808 0x1001BBD2"

    Jump is performed here:

    // Load address of reset function from the fixed location of the image's
    // reset vector and jump.
    #ifdef TIRTOS_IN_ROM
    asm(" MOV R0, #0x1500 ");
    #else
    asm(" MOV R0, #0x1010 "); // Not used, because we use TI RTOS in ROM
    #endif
    asm(" LDR R1, [R0, #0x4] ");

    // Reset the stack pointer,
    asm(" LDR SP, [R0, #0x0] ");

    // And jump.
    asm(" BX R1 ");

    I have tried to attach two files: dump of the 128kB memory, after bootloader has copied main app to FLASH 0x0000'1000....

    And the main application binary.

    Not sure if this is possible: the preview looks weird...

    I think I am really close to success, but I just need the last bit...

    Thanks

    Kaare

    MemDump.txt

    MainApp.txt

  • Please, any comments on the last post?

    br

    Kaare

  • Kaare,

    I've been out-of-office the last two days. I'm currently looking into it.
  • Could you share the .bin file with me?
  • Also, please refer to the following guide on how to parse HWI exceptions:

    dev.ti.com/.../debugging-index.html
  • The .bin file for the Main application is in the post from february 16.
    It is called "MainApp.txt". I had to rename to .txt because my mail would not accept .bin :)

    br
    Kaare
  • And you also find the complete memory dump in the same post.
    Here you can see that the MainApp binary is placed from 0x1000 as I would expect.
  • OK, I will look into that later (5-6 hours from now)
  • Ok, thanks. Could you also share with me the map file?
  • Any updates on the HWI exception parsing?
  • Hi Severin

    Sorry, did not see that you asked for this...

    But my bootloader application use TI RTOS in ROM, and I don't think this is possible then?

    I did try, but get an error because i can not include hwi.h.

    Tried the same in my main applicaton, which is based in TI RTOS in FLASH, and it is possible in that project.

    Is there another way to do it with TI RTOS in ROM?

  • Sorry, I made a mistake in the previous post:
    My bootloader application does NOT use TI RTOS at all, not even in ROM.
    It is my my main application that uses TI RTOS in ROM.
  • I am playing around, reading code, googling etc., and then suddenly it worked!
    But I don't think I really changed anything:
    I was trying to debug the application when I want to jump to main application, and then, when I singlestepped over the code, it actually started.

    I have a main loop, which does nothing but reading on the UART Rx.
    Then, when I want to release the bootloader, and let it finish and jump to application, I disable the systick timer, and make the jump.
    See below.
    This does not work. BUT, when I placed a breakpoint at "u8Ged = 1", and singestepped through, the debugger kind of lost track when jumping over SysTickDisable(), but then I relaized that the main application was actually running!
    This is a success, but not 100%, as I don't understand why, and I of course have to make it work without singlestepping :)

    Do you have any idea of what can cause this behavior?


    // Loop, receiving RX chars from UART:
    while( u8Ged == 0 )
    {
    if( C_SIM868_RxBytes() == true )
    {
    u8Ged = 1; // Breaks the loop when returning true. Breakpoint placed here
    }

    }

    SysTickDisable(); // Singlestepping over this, starts the main application.


    // Load address of reset function from the fixed location of the image's
    // reset vector and jump.
    #ifdef TIRTOS_IN_ROM
    asm(" MOV R0, #0x1500 ");
    #else
    asm(" MOV R0, #0x1010 ");
    #endif
    asm(" LDR R1, [R0, #0x4] ");

    // Reset the stack pointer,
    asm(" LDR SP, [R0, #0x0] ");

    // And jump.
    asm(" BX R1 ");
  • Latest news:

    The reason why I succeeded to start application (JUMP 0x1500), was not due to debugging. It was just a coinsidence, because when I debugged to test the jump, I did not re-program the application.

    So, what I see now is:

    1: Run the bootloader (JTAG)

    2: Flash the application binary

    3: Jump to 0x1500

    4: Does not start application

    1: Run bootloader (JTAG)

    2: Jump to 0x1500

    3: Application starts

    So, when I have flashed the binary to flash, I can not start the application. I have to reset/reprogram by JTAG, and then I can make the jump.

    Why is that?

    And what should I do to make it happen?

    Thanks

    Kaare

  • Problem found and solved!

    Even though I understand it 100%:

    When I first started up the bootloader project, I tried to set up the UART to use RX interrupt.

    I never succeeded to do this, because the interrupt was never generated.

    So now I just poll the RX register.

    If I start the bootloader application but DO NOT receive anything on the UART, I can make the jump to 0x1500, and start the main application.

    But if I have received something on the UART, I can't.

    I know it has something to do with the interrupt, but as sayd, I never receive any interrupts (it might be setup wrong).

    If I remove the code enabling the interrupt, I can make the jump, even if I have received UART data.

    Bottom line: It works now :)

    Thanks for your help!

    br

    Kaare