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.

Compiler/CC1352R: Customized Bootloader as part of application

Part Number: CC1352R


Tool/software: TI C/C++ Compiler

I would like to combine a customized bootloader with my application. In detail my bootload functionality would be placed in the last flash page (as BIM) and would then jump to my normal/remaining application. But when doing development and debugging I would like to download both via debugger to the processor. When I download now my application it overrides also the last flash page (at least by setting CCFG register) and then the bootloader is gone. But in principle I could have all funktionality in my application (at least I guess).

My idea: all the code that belongs to the bootloader functionality is moved from the linker into the last flash page. The linker command file (cc13x2r1f3.cmd) contains already a definition for FLASH_LAST_PAGE. All the remaining code from my application is moved to FLASH.

Normally code is put to .text section that is mapped to FLASH. When I define now a new section, e.g. .boottext, where the boot functions are put in and which is mapped to FLASH_LAST_PAGE I would get what I want, right? But I don't know how to tag my bootloader functions with .boottext (some #pragma???).

I still might have problems with data. Preferably my boot part can define global/static variables that are put at one address. The application part can then define also global variables but these could be located on those addresses that where already used from the bootload functionality. In principle for data also different sections, e.g. .bss and .bootbss, could be defined. But is it possible to overlap two sections? Even here I don't know how to define a new section for data and map a dedicated variable to this section.

Any help would be beneficial

Erwin

  • Hi Erwin, 

    Assigning an expert to comment. 

    Thanks, 
    Elin

  • Hi Erwin,

    Did you see the Boot Image Manager example we created for our over the air download (OAD) examples? In this solution the bootloader (BIM) and application image is created with different projects in CCS/IAR. Their boundary is set in the linker command file (.cmd/.icf file).

    You can use the BIM project as a starting point for your bootloader. Please find it in the following folder: C:\ti\simplelink_cc13x2_26x2_sdk_4_10_00_78\examples\nortos\CC1352R1_LAUNCHXL\bim\bim_onchip

  • Hi,

    yes I saw it and it helped very much to be able to get already a rough framework for our customized bootloader. I think I can get the normal/old behaviour implemented that does:

    1. create a bootloader as one project. The whole debugger is located in the last flash page.
    2. Download this bootloader to the target with out XDS110 debugger.
    3. So now only the bootloader runs on the target.
    4. Develop the application in a different project. Downloading this with the debugger would override the bootloader as at least for CCFG values the last flash page is overwritten. So I can develop the application only without bootloader.
    5. From application output. e.g. intel hex format, I remove the part of the last flash page and create that kind of file, that is accepted from the bootloader.
    6. On the target where my bootloader is running, I use the customized functionality to put the application (without last flash page) into internal memory. My application starts at usual with address zero.
    7. From that point of view onwards after a reset my bootloader detects that there is a valid application and jumps to zero to start it.

    I would like to be in the position to debug my application together with the bootloader. But that's not possivle with the described normal behaviour. From what I've read until now this should be possible by using #pragma SET_CODE_SECTION to put my bootloader functionality into a new section that is maped to the already existing FLASH_LAST_PAGE section. The application code doesn't use this pragma and is therefore put into .text section.

    I still see problems with data sections. Preverable the global/static variables of my bootloader functionality is also put into a different section (again #praga SET_DATA_SECTION). But this section should then use the same address range as .bss where the variables of my application are located. Don't know yet if this is possible. I still have to read the ARM Assembly Language Tools User Guide.

    Another issue thatiis not fully clear to me is the vector table. BIM defines in an own startup_ccs.c a g_pfnVectors array that is filled with the differnt handler functions. But my application does it somewhere internaly inside som TI tools and/or SYS_BIOS stuff. Preferably I have to array, one for the bootloader functionality and one for the application (I guess even located at different addresses). But how to switch from the bootload vector to the application vector without a reset? Or is this automatically done when the bootloader calls the function at address 0 to start the application?

    Hopy you understand me

    Erwin

  • Hi Erwin,

    Downloading an application image should not overwrite the CCFG or bootloader code. Please see any OAD example to see how this is solved in application images:

    For debugging, please see the OAD SimpleLink Academy lab. Task 4 will walk you through how to debug the bootloader and application image.

  • Hi Marie,

    I did a look at the provide links. But now I think there is a fundamental difference between what we call a bootloader and what is called OAD.

    A bootloader will still run and be able to install a new application when anything in the application is not working. OAD is a standardized way to get a new application installed. But this installation must be performed from the application itself. So if there is an error in the application that lead to a crash I'm not able to install another application. Of course this assumes that the functionality to get the new application is completely done in the bootloader. In our case the application is given via the I2C interface to the processor; so nothing with BLE.

    Having no OAD supported by my application it's also clear how to debug my application, even including OAD/BIM functionality when I have all symbols.

    I have to create a bootloader that can still accept image data when the application crashes very early. Our application is created in C++ and we use a lot of static/global objects. The constructors of those classes are called even before main() starts. But the BIM principle is that main() is located inside BIM. So if I have an error in one of my constructors BIM is not started and there is no possibility for me to receive a new application image via I2C. If there is no crash or the crash would happen after BIM has "switched to application" I could use BIM/bootloader I2C driver to get the new application.

    As (with my bootloader understanding) bootloader and application are two independent applications they have two _c_int00 functions and two different C++ initialization tables. But having just one application with OAD support there is just one.

    In all your OAD examples the startup is:

    • ResetISR is called
    • SetupTrimDevice is called
    • _c_int00 is called
    • Global/static variables are initialized, including constructor of global C++ objects
    • main (of BIM is called)
    • BIM performs the checks and eventuelly overrides internal flash
    • BIM jumps to the start address of the application. This address is located in the OAD header in the first bytes of the internal flash
    • I guess the start address of the application is the address of (application)main. Or how is this address obtained?

    As said, with problems in the initialization/constructors of global objects I have no possibility to give a working application anymore. I have to flash it internally.

    BTW: You wrote "Downloading an application image should not overwrite the CCFG or bootloader code". You are right when I download an application via OAD. But I'm in the development phase and putting my application to the processor is done with the debugger that always overwrites CCFG.

    At the moment it looks to me that even from hardware point of view a bootloader with our understood functionality (which is expected to be delivered) cannot be done. To get something similar I have to eliminate all global/static variables that might lead to problems (which means everything except simple data arrays that are not modified).

    Or do you (or some other expert) have another solution for this?

    BR
    Erwin

  • I just realize that my last statement seems not to be correct.

    Implementing as two applications should be possible. CCFG are still bound to the bootloader. All bootloader code can reside in the last flash page. CCFG determines that _c_int00 and main are called from bootloader / last flash page.

    If now magically the "main" application is completely located into the other lower flash pages, the boot loader simply jumps to address 0 and then the application including their _c_int00 is called.

    The vectortable can also be moved from last flash page to first flash page so that after that the interrupt routines of the application are called.

    Everything like normal bootloader work. It's just not possible to have both applications in the flash when connected with the debugger.

    In our old projects this was also not possible. My hope, to get it now with the newer (better?) processor, is simply not becoming truth.

    Is there a possiblity to download with code composer studio an own hex file or even read the internal flash of a connected CC1352R to a hex file?

  • Hi Erwin,

    Sorry for the late reply.

    It's possible to read the memory of a CC1352R device with CCS or Flash Programmer.