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.

CC1352R: Principal problem with bootloader functionality?

Part Number: CC1352R
Other Parts Discussed in Thread: SYSCONFIG, SYSBIOS

Hello,

I'm writing a customized bootloader that resides in the last flash page and can therefore override all the other flash pages, which can then be used by the application.

Of course my application uses also the first flash page. As usual before updating the (first) page I have to erase it. Only then I can program the right content. But at the beginning of the first page there is the address of my program, i.e. the address where the CPU should jump to. In my case this is the start of my bootloader, the last flash page. Erasing the first page and then writing the right content (containing again the right start address) is ok.

But when there is a reset/power cut in the unlucky moment after I have erased the first flash page but before the new content is written, the processor doesn't find a valid start address and my whole device is broken (no bootloader started).

Is there any solution for this principle problems or do we simply have to say "while you do an update no power cut is allowed" (which we can't guarantee in our case).

BR
Erwin

  • Hi Erwin,

    On the CC1352 device, the CCFG region (in the last flash page) contains the "SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID" field which defines if there is a valid image (not FFFFFFFF) and where this is located. This is then used by the ROM bootcode to do the initial application code jump.

    It is thus recommended to set this to 0x56000 in the case where you have the bootloader on the last flash page to assure the device always boots into the bootloader. This means that as long as you can rework your code to not depend on any other code other then that in the last page then the potential corruption of for example page 0 would not prevent you from starting over. 

    Best regards,

    Max

  • That's the way it should be and how I have to do it. Thank you very much for this important tip.

    I tried to find now already the place in CCS togther with TIBIOS and TI driver where I put the information that the compiler/linker should put 0x560000 into the hex file at address 0x57FEC, where SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID is located.

    I found C:\ti\simplelink_cc13x2_26x2_sdk_3_40_00_02\source\ti\devices\cc13x2_cc26x2\startup_files\ccfg.c telling that I should create my_ccfg.c that should then contain #define SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID 0x56000.

    I tried that and had no luck. Isn't there a special location inside my project directory where I should place this file? I tried under startup but also in the root of my project. There was no compiler/linker error (no big surprise) but looking at the generated HEX file there was still 0 a the right location.

    C:\ti\simplelink_cc13x2_26x2_sdk_3_40_00_02\source\ti\devices\cc13x2_cc26x2\startup_files\ccfg.c tells also that I should include this file in my_ccfg.c. But including this with the hard coded path is not the best way. In CCS I can select a different SDK version, which would lead then to a different path. So if I have to include the original ccfg.c (isn't this already be done somewhere in the whole build process?) how to do this correctly and nice?

    BR
    Erwin

  • Hi Erwin, 

    It should be enough to define it on "project level", you do not really need to include any new files. The original ccfg.c file checks for pre-existing defines first so as long as you define "SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID" globally in project settings, that should be the value later used when compiling.

  • Hi,

    I got it running by inserting SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID=0x56000 as "Predefined Symbols" in my project properties under Build/ARM Compiler/Predefined Symbols.

    But I think this is not the optimal location.

    Unfortunately I still  haven't understood the whole build process detailed enough. This is my understanding:

    1. SysConfig tool is startet that parses <project>.syscfg that contains all the definitions I clicked on in the graphical SysConfig Editor. This tool generates some source code located under <project>\<configuration>\syscfg.
    2. XDCtools does the same or is used by SysConfig. Don't know.
    3. Now all the extenstions to the ROM functions, so all code that is still running from flash but uses/implements/wraps the ROM functions, are compiled. This is done with clem4f and asmem4f, which seems to be special c-compiler and assembler. The output is put into a library, called rom_sysbio.aem4f
    4. Now the created files under <project>\<configuration>\syscfg are compiled with the selected compiler (TI compiler in my case).
    5. After that all my files are compiled with the selected compiler (TI compiler in my case)
    6. Finally some files, mainly for ble stack and icall, from <SDK>\sources are compiled with the selected compiler (TI compiler in my case)
    7. The linker takes now all the compiled files and links it to <project>.out together
    8. The armhex utility converts this out file into a hex file

    So at which step the code that represents the CCFG register is generated? Isn't this ccfg.c from SDK somewhere used? I don't see in the console output that this file is used from a compiler. Can it be that this is used from SysConfig and/or XDCtools? In the project properties there is also a secion vor XDStools where something could be inserted. Would this be the right place for the SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID define?

    BR
    Erwin

  • I figure another problem where you might help me.

    I declared now a bootloader main c function that I declare to be located at 0x56000 by the usage of a special code section. As this main function is now not called from another function in my application the linker removes this function from the executable.

    As a workaround I call this main function from one function of my application and prevent doing some real stuff in that case. But that's not so nice.

    I was even looking in the project properties under linker for a setting that en/disables removing of unused function. Unfortunately I didn't found such. What did I overlook?

    BR
    Erwin

  • Hi Erwin,

    Without knowing your exact setup, I could elaborate on how we propose a bootloader + application setup and on the steps listed above. Starting with the bootloader + application situation, we typically recommend keeping these as two separate project (maybe this is what you do). In that case, assuming the bootloader to be located on the last flash page, only the "bootloader project" will contain any CCFG information. The "application project" would in this scenario not include any reference to the CCFG file (as it does/should not span the last flash page).

    You could have a look at the TI bootloader (BIM) project found under the NoRTOS examples if you want a clear example on how this is handled "in source". Generally, any project that is to include the CCFG region actually include a "ccfg.c" file, in the case of the BIM this is named "ccfg_app.c" and it is typically a two line file that simply links in to the "default" CCFG settings. Any additional changes you might want to do could then be done in this "top-level" file (see image below):

    What this means for the CCFG from a "build" perspective is that it is compiled together with the rest of your project source code. Note that the BIM project in this case does not use SysConfig. If you do you either need to remove the "Add CCFG" from the SysConfig script (open as text) or stay with the "project level define", this because SysConfig will generate the equivalent ccfg.c file  which means you can't modify the file (as it will be re-generated the next time you hit build).

    Long story short: the ccfg.c is compiled together with the rest of the project and in the case where you do not use SysConfig to generate the base file, you can add the defines inside the "top-level" ccfg.c file. The XDCTools has nothing to do with the CCFG.

     

    As for your other questions, I would summarize the steps as this myself:

    1) SysConfig runs and generate C/H files based on templates and your settings (consider it a template engine)

    2) XDCTools run to put together the TI-RTOS kernel as defined in the .cfg file. This include a great amount of gray magic and wishing but in the end, the XDCTools produce some C source file(s) and one or more library files to be used in the reminder of the project. 

    3) Really part of the XDCTools work, some of the TI-RTOS kernel exists in ROM and depending on the .cfg file, it either uses the ROM version or place them in FLASH. This would suggest your kernel is configured to use the ROM functions. Do not confuse this with other ROM functions such as the Flash APIs etc, this is strictly the "sysbios" part (read as TI-RTOS).

    4-6) You could consider this a single step if you wish, "compiling the project". The steps prior to this, 1-3, is really "pre-processing" steps. This is also where the CCFG.c file is compiled (IF present in the project).

    7) What you said

    8) Dito

     

  • Hi M-W,

    thanks for the information and it increases again my knowledge about the processor and its usage.

    With the atmel processors, we used before, we also had two independent applications: the boot loader and the real application. But with this setup (at least for us) it was not possible to debug a setup where boot loader and application are running on the target. But that is exactly the configuration running at customer site.

    Having now both in one project has the advantage to see the whole stuff from the debugger. When you download you application with debugger you also have automatically the boot loader included.

    So everything is clear enough at the moment and I'm willing to close this issue with "resolved". I would just like to get some information whether it is possible to put my boot loader main c-function in the output file even I don't call it explicitely in my application. Even for this I have the workaround to call this function and by using some data not doing anything when the function is called the second time.

    BR
    Erwin

  • Hi Erwin,

    It is possible for sure using either linker directives or pragmas to conserve it, the project split is however the recommended approach.

    You could still debug a "full product" on the customer site, you just need to add the symbol files yourself. Say that you for example launch a debug session based on the "application project", then you would need to load/add the symbol/out file of the "bootloader" to the session in order to get the "full project" debugging experience.

    In CCS, this could for example be done as in the image below (once in a active debug session):

  • I thought it would work now but that's not the case.

    By defining SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID as project define I see a new value in the CCFG register. But it has no influence on the startup of my project. When I download the image with the debugger my normal application starts. Looking under Registers for CCFG region I see the value under IMAGE_VALID_CONF. Even giving a value of 0x36000, which should point somewhere into some code, my normal application starts.

    So changing this CCFG register seems not to do what should be done. Is there something more I  have to do. I will now take the bim example (looked already in parts before) and try to get it started on my HW.

    BR
    Erwin

  • Hi Erwin,

    If you are running in a debug session, it might not reflect what you would see when booting the device "normally". This as the debug session would run the device to the entry point based on expectation, not CCFG value. This is why you could for example debug a OAD BLE project without having the BIM flashed and it could seem to work fine but as soon as you reset it, it "clicks".

    I suggest you test to run it without the debugger and see if the device seem to run the bootloader as expected in that case.

  • Hi,

    so we have the issue again that with debugger the processor does different things than running without debugger. And at least I don't know the differences. I asked it already some time ago a extra issue in this forum but got no sufficient response. So I have to live with it. I guess the difference is only the basic startup so what I do in my real application is the same. Otherwise it would be hard to fix a bug when the behaviour with debugger is different than to running at customer site.

    At the moment I'm thinking to go back to the old design where the boot loader is a separate application (which was also recommended from TI) but where I cannot debug easy a setup where application and boot loader are running on the target.

    When I now don't talk about boot loader but wants to have an application that doesn't start at address 0 but at 0x56000. Could this be realized? The application would then consist of some functionality located in the last flash page and the remaining functionality is in lower flash pages. And my application would take care that it runs also when all the other flash pages are erased and the remaining functionality (located in last flash page) supports to get the remaining functionality through an I2C interface. In that case my main function would also be located in the last flash page. But what's with the whole startup code (provided from the compiler and SDK) executed before my main function is called? That should also be in the last flash page. Could this be realized by locating the normal .text segment with a linker command into the last flash page? All my remaining application would then be located in another section with #pragma SET_CODE_SECTION. Could this work? As initialization of global variables is also done from the startup code, that is running in last flash page, it would no be allowed to use global variables (I'm doing C++) that uses constructors from the lower flash area. Could such an application use TIRTOS and TI driver? Of course I would assure that the related initialization functions like ICALL_init(), DMM.init() or BIOS_start() would only be called from a function located in the lower flash area.

    That sounds feasable. Or do you disagree? The bim_onchip example could act as starting point, right?

    BR
    Erwin

  • Hi Erwin,

    What you suggest sound very much like the BIm bootloader + application setup (with your own take on the BIM portion). From a project point of view, it is mostly down to linker file setups. 

    Take the bootloader (or what ever you want to call the application you run on the last flash page), it is the ONLY application of the two that should contain the CCFG.c file and you can use the linker file to assign it to the last flash page (just change the flash region to target that page). 

    Take then the application, I assume there is some kind of header information somewhere that you can search for but let us disregard that for a minute. The Application doe snot include any CCFG region as it it is limited to pages 0 - (N-2) (N-1 being the last). As for startup code and initiation, this is part of that applications reset routine which means that when your "bootloader" makes the jump to the other application, it should target the jump into the ResetISR of that application which means it will run just like it would do in a "normal" case. 

    In short, you should not need to pragma place anything in the split project case, just adjust the linker memory map accordingly and you should be fine (this is what the BIM and OAD projects using it does).