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.

CC2640R2F: XDC Startup functions increase boot time

Part Number: CC2640R2F
Other Parts Discussed in Thread: CC2640

HI,

I have a project utilizing Sensor Controller and Bluetooth.  Boot startup time is critical to the application.  We need to boot into the sensor controller application quickly and then perform Bluetooth actions at leisure.

However the additional XDC startup functions that are required to initialize components required by Bluetooth are increasing boot time to an unacceptable time.

So my question is how can I stop the XDC startup functions executing before main(), and then manually call these functions after the boot critical code.

I am using IAR workbench8.32.3.20228 , xdctools 3_51_3_28 and simplelink_cc2640r2_sdk_3.02.00.21.

The configuro tool command line is 

"$XDC_DIR$\xs" --xdcpath="$PROJ_XDCPATH$" iar.tools.configuro -c "$TOOLKIT_DIR$" --cc "$COMPILER_PATH$" --device "$DEVICE$" --compileOptions $COMPILER_ARGS_ROOT_QUOTED$ --linkOptions $LINKER_ARGS_QUOTED$ --profile release --projFile "$PROJ_PATH$" --cfgArgs "{}" -o $XDC_BUILD_OUTPUT_DIR$ $FILE_PATH$

working on config file app_ble.cfg (content listed below)

utils.importFile("common/cc26xx/kernel/cc2640/config/cc2640_r2_csdk.cfg");

/*
* Extend the cc2640 configuration
*/


/* Set the vector table address correctly */
m3Hwi.resetVectorAddress = 0x00000E00;

/* Set the hwi */
halHwi.create(16, '&ResetButtonCallback');

/* Heap Configuration defines the type of Heap you want to use for the system (application + Stack)
* Only one Heap buffer will be allocated. This heap will be shared by the system and the stack through one manager (HeapMem, HeapMem+HeapTrack or OSAL)
* You can still decide to create several heaps if you want, but at least one heap needs to be created.
* The stack must have a Heap to run.
* The different Heap manager available are :
* OSAL HEAP: legacy Heap manager provided with all BLE sdk. By default, this Heap manager is used.
* HeapMem:  heap manager provided by TI-RTOS (see TI-RTOS user guide for properties)
* HeapTrack: module on top of HeapMem allowing an easy debugging of memory allocated through HeapMem.

* The heap manager to use is selected by setting HEAPMGR_CONFIG to the corresponding value (see below)
* 0 = osal Heap manager, size is static.
* 0x80 = osal Heap manager, with auto-size: The remainning RAM (not used by the system) will be fully assign to the Heap.
* 1 = HeapMem with Static size
* 0x81 = HeapMem with auto-size. The remainning RAM (not used by the system) will be fully assign to the Heap.
* 2 = HeapTrack (with HeapMem) with fixe size
* 0x82 = HeapTrack (with HeapMem) with auto-size: The remainning RAM (not used by the system) will be fully assign to the Heap.
*
* If HEAPMGR_CONFIG is not defined, but the configuration file ble_stack_heap.cfg is used, then the value HEAPMGR_CONFIG = 0x80 is assumed.
* If HEAPMGR_CONFIG is not defined, and the file ble_stack_heap.cfg is not used, then the value HEAPMGR_CONFIG = 0x80 is assumed and the default Heap size will be 3072
* unless you define HEAPMGR_SIZE to a different value in the project option (0 meaning auto-size).
*
* From the configuration below, two #define will be created that will be used by the application to setup the Heap:
* #define HEAPMGR_SIZE
* #define HEAPMGR_CONFIG
* In order to use those define, this include line needs to be added: #include <xdc/cfg/global.h>
*
* In order for the auto-size Heap to work, the following symbol needs to be created by the linker:
* heapStart
* heapEnd
*
*/
/* modification of HEAPMGR_CONFIG and HEAPMGR_SIZE value must be done inside the include file bellow (ble_stack_heap.cfg) */
utils.importFile("common/cc26xx/kernel/cc2640/config/ble_stack_heap.cfg");

Thanks

  • Hi,

    I sent it to a concerned engineer. We will get back you ASAP. Please bear with us.

    Thanks,

    PM

  • additional information:

    Looking further I think a good deal of the extra boot time is consumed in function __iar_zero_init3 which is zero initialising static ram areas, many of which seem to be declared within library code.   It may be the case that many of these could be declared as noinit to reduce the number of ram zeroing iterations.

    Within function __iar_zero_init3, it takes 4 cycles to clear a 4 bytes area of ram, plus setup overhead.

  • Hi Glenn,

    Have you already tried the solution you evoked in your last message? I am a bit unsure if this is the best idea. I mean it could produce some side effects (maybe only after a couple of boots) if you don't initialize properly the RAM.

    To begin, here is a link (http://processors.wiki.ti.com/index.php/SYS/BIOS_for_Stellaris_Devices) to an article explaining the boot sequence of the TI devices. It is quite old and originally written for Stellaris Devices but it is a gold mine for people who want to optimize the boot time of their device. In addition, you can save time on boot (if it has not been done before) by inactivate the memory water mark (this requires to set the whole RAM to 0xBE). This can be done by defining the OSALMEM_METRICS as FALSE. 

    To finish, here is an idea I never tried but that could interest you. If you manage to start the sensor controller before the end of the booting sequence of the main core, then you will save a lot of time. So why not trigger the startup of the Sensor Controller as soon as the required trim has been performed? This could be done in the function System_Setup() (in the file system_init.c) or a bit latter (if the first one is not possible) inside the resetHook() (in the file system_init.c too).

    Sorry for not giving you any ready-made solution but I really hope this will help you,

    Best regards,

  • Hi Clement,

    Unfortunately the link you provide just opens a page with no text.?
    I'd still be very interested to read this article.

    I have succeeded in drastically reducing boot time to my critical code by doing a deferred ram initialization as follows:
    1. copy csmain.s into the project from the IAR installation
    2. edit csmain.c so it does not branch to the _iar_data_init3 function.
    3. add manual calls to __iar_data_init3() and iar_startup_exec() in my C "main" function after my boot critical code including the sensor controller setup and run.
    4. ensure all static variables in my boot critical code are prefixed with __no_init and explicitly initialized as required by code.

    Although this work wells it may be risky to maintain (especially by others), and so I'll try to find a cleaner solution

    I will look at the OSALMEM_METRICS  to see if this alone can provide the required savings as a cleaner solution.

    I won't mark as resolved yet in case a cleaner solution can be found and documented here.

    Thanks

    Glenn

  • Here is the link to the page I mentioned: processors.wiki.ti.com/.../BIOS_for_Stellaris_Devices (I have updated the link in my previous message).

    By the way, I am going to ask you to mark your thread as resolved, not because I don't want to support you anymore but because you produced a very interesting answer that I would like people easily find. Thanks for your contribution.

    Best regards,

  • Hi Clement,

    Thanks for updated link. This helps the understanding of the sequence.

    In our case the __iar_data_init3 is consuming around 50000 cycles and the iar_startup_exec around 30000 cycles.

    Deferring the iar_startup_exec  alone will not give us the required time saving.

    So the principle of the solution I cited above will have to be used.

    A cleaner implementation may be to take ownership of the startup sequence by effectively implementing our own "iar_program_startup"

    As you asked I will consider marking as resolved, but it is likely further additions will be likely as we progress a solution.  How is that achieved if "resolved" ?

  • This is not problem: marking the thread as resolved does not close it. And if it is the case (there is a sort of timeout after 30 days), you can basically open a new thread asking the moderator to complete the current thread :)

    Best regards,

  • Ok

    Thanks Glenn

  • Hi Clement,

    I have succeeded with  a cleaner solution.

    1. In the app_ble.cfg file used by xdc/confiuro

    Boot.trimDevice = false;
    var Startup = xdc.useModule('xdc.runtime.Startup');
    Startup.resetFxn = "&myCritcalReset";

    2 Create C function. myCriticalReset

     void myCriticalReset(void)
    {
           SetupTrimDevice();
           BootCritical_function();     // in this function execute all the boot time critical code
                                                    // remembering that no statics will have been initialised 
    }

    The boot process will then proceed as normal processing Cinit records to initialise statics etc, executing xdc statup code for modules and jumping to main

    Although this still requires that the boot critical code must be written carefully to avoid use of initialised static variables (including zero initialised), at least there is no editing of low level files.

    Regards

    Glenn

  • Thank you for sharing!

    Best regards,