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/CC2650: Compiler bug(?) / recommendations for CC2650 / BLE-stack 2.2.1

Part Number: CC2650
Other Parts Discussed in Thread: BLE-STACK, SYSBIOS

Tool/software: TI C/C++ Compiler

I'm currently looking into an issue where a custom board is entering an error state, that I'm not able to debug. I can single-step through most of the initialization, some of the tasks start, but as soon as I let the firmware run (and the interrupts start firing), the board hangs. Any attempt to pause it from the debugger will give the following error:

Cortex_M3_0: Trouble Halting Target CPU: (Error -2062 @ 0x0) Unable to halt device. Reset the device, and retry the operation. If error persists, confirm configuration, power-cycle the board, and/or try more reliable JTAG settings (e.g. lower TCLK). (Emulation package 7.0.48.0) 

My firmware is using BLE-stack 2.2.1, is built on the Serial Port Profile example (spp_server), and adds a few changes to the existing tasks, and an additional, custom task running at priority 1. For the compiler, I've initially been using the recommended TI 5.2.6 compiler.

The code has been working just fine, until a recent change. The change looks fairly innocent, and I've currently narrowed it down to the addition of three global volatile bool variables in the custom task implementation file (which is a cpp file). I've commented out all other added functionality from that commit - only the three volatile bools remain. With 0-2 volatile bools, everything works - when the third is added, the problem above happens.

I tried recompiling with the 16.9.4 LTS compiler, and here everything works again.

My questions are:

  1. Is the above a known issue, and can someone maybe provide a bit more insight into what is going on?
  2. Are there any known issues when using the 16.9.x LTS series of compilers, instead of the recommended 5.2.6 compiler with the BLE-stack?
  3. In continuation of 2, what is the reason for 5.2.6 being the recommended compiler, rather than the newer ones?
  • Hi Simon,

    Have you tried checking if this is a memory issue? I.e. check the task stacks and the heap?

    The BLE-Stack 2.2.1 is tested with the TI ARM Compiler 5.2.6, that's why it's the recommended compiler. In many cases using the TI ARM Compiler 16.9.x will result in compiler errors or the BLE-Stack not working as intended.
  • Hi Marie,

    Thanks for your input!

    My main trouble is that I can't get access with the debugger once the chip crashes.

    Without the three extra volatile bools, all stacks are fine though (all at a max of ~80% usage or so), and I have a baseline heap usage of around 40% (with about 1.5kB left), when the device is booted and idle - so I can't really see how the three extra variables (3 bytes in total, going neither on the heap nor the stack) can mess something up, unless there's something else going on?...

    Also, do you have examples of cases where the 16.9.x compilers don't work with the BLE-stack?

    Thanks in advance!

  • I've been looking a bit more into the differences now, and as I can see, some of the .cinit sections get different sizes. I'd expect this to happen for the general case, as the new booleans need to be initialized also, but I see that the .cinit..data:ti_sysbios_knl_Clock_Module__state__V.load and .cinit..data:ti_sysbios_family_arm_cc26xx_Timer_Module__state__V.load suddenly take up one byte less? Why would the size of these change, just by adding an otherwise unrelated volatile boolean variable?

    Relevant sections of the .map files, first with 3 volatile boolean variables added, firmware does not work:

    .cinit    0    0000e208    00000830     
                   0000e208    00000673     (.cinit..data.load) [load image, compression = rle]
                   0000e87b    00000005     --HOLE-- [fill = 0]
                   0000e880    0000002d     (.cinit..data:ti_sysbios_family_arm_m3_Hwi_Module__state__V.load) [load image, compression = rle]
                   0000e8ad    00000003     --HOLE-- [fill = 0]
                   0000e8b0    0000002c     (.cinit..data:ti_sysbios_knl_Task_Module__state__V.load) [load image, compression = rle]
                   0000e8dc    00000004     --HOLE-- [fill = 0]
                   0000e8e0    00000020     (.cinit..data:ti_sysbios_knl_Clock_Module__state__V.load) [load image, compression = rle]
                   0000e900    0000001f     (.cinit..data:ti_sysbios_BIOS_Module__state__V.load) [load image, compression = rle]
                   0000e91f    00000001     --HOLE-- [fill = 0]
                   0000e920    00000011     (.cinit..data:ti_sysbios_knl_Swi_Module__state__V.load) [load image, compression = rle]
                   0000e931    00000007     --HOLE-- [fill = 0]
                   0000e938    0000000c     (.cinit..data:ti_sysbios_family_arm_cc26xx_Timer_Module__state__V.load) [load image, compression = rle]
                   0000e944    0000000c     (__TI_handler_table)
                   0000e950    0000000a     (.cinit..data:xdc_runtime_Memory_Module__state__V.load) [load image, compression = rle]
                   0000e95a    00000006     --HOLE-- [fill = 0]
                   0000e960    00000009     (.cinit..data:ti_sysbios_family_arm_cc26xx_TimestampProvider_Module__state__V.load) [load image, compression = rle]
                   0000e969    00000007     --HOLE-- [fill = 0]
                   0000e970    00000009     (.cinit..data:xdc_runtime_Startup_Module__state__V.load) [load image, compression = rle]
                   0000e979    00000007     --HOLE-- [fill = 0]
                   0000e980    00000009     (.cinit..data:xdc_runtime_System_Module__state__V.load) [load image, compression = rle]
                   0000e989    00000007     --HOLE-- [fill = 0]
                   0000e990    00000008     (.cinit..TI.bound:dmaSpi0RxControlTableEntry.load) [load image, compression = zero_init]
                   0000e998    00000008     (.cinit..TI.bound:dmaSpi0TxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9a0    00000008     (.cinit..TI.bound:dmaSpi1RxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9a8    00000008     (.cinit..TI.bound:dmaSpi1TxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9b0    00000008     (.cinit..bss.load) [load image, compression = zero_init]
                   0000e9b8    00000080     (__TI_cinit_table)
    

    Here with 2 volatile boolean variables added, firmware does work:

    .cinit    0    0000e208    00000838     
                   0000e208    0000066d     (.cinit..data.load) [load image, compression = rle]
                   0000e875    00000003     --HOLE-- [fill = 0]
                   0000e878    0000002d     (.cinit..data:ti_sysbios_family_arm_m3_Hwi_Module__state__V.load) [load image, compression = rle]
                   0000e8a5    00000003     --HOLE-- [fill = 0]
                   0000e8a8    0000002c     (.cinit..data:ti_sysbios_knl_Task_Module__state__V.load) [load image, compression = rle]
                   0000e8d4    00000004     --HOLE-- [fill = 0]
                   0000e8d8    00000021     (.cinit..data:ti_sysbios_knl_Clock_Module__state__V.load) [load image, compression = rle]
                   0000e8f9    00000007     --HOLE-- [fill = 0]
                   0000e900    0000001f     (.cinit..data:ti_sysbios_BIOS_Module__state__V.load) [load image, compression = rle]
                   0000e91f    00000001     --HOLE-- [fill = 0]
                   0000e920    00000011     (.cinit..data:ti_sysbios_knl_Swi_Module__state__V.load) [load image, compression = rle]
                   0000e931    00000007     --HOLE-- [fill = 0]
                   0000e938    0000000d     (.cinit..data:ti_sysbios_family_arm_cc26xx_Timer_Module__state__V.load) [load image, compression = rle]
                   0000e945    00000003     --HOLE-- [fill = 0]
                   0000e948    0000000c     (__TI_handler_table)
                   0000e954    00000004     --HOLE-- [fill = 0]
                   0000e958    0000000a     (.cinit..data:xdc_runtime_Memory_Module__state__V.load) [load image, compression = rle]
                   0000e962    00000006     --HOLE-- [fill = 0]
                   0000e968    00000009     (.cinit..data:ti_sysbios_family_arm_cc26xx_TimestampProvider_Module__state__V.load) [load image, compression = rle]
                   0000e971    00000007     --HOLE-- [fill = 0]
                   0000e978    00000009     (.cinit..data:xdc_runtime_Startup_Module__state__V.load) [load image, compression = rle]
                   0000e981    00000007     --HOLE-- [fill = 0]
                   0000e988    00000009     (.cinit..data:xdc_runtime_System_Module__state__V.load) [load image, compression = rle]
                   0000e991    00000007     --HOLE-- [fill = 0]
                   0000e998    00000008     (.cinit..TI.bound:dmaSpi0RxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9a0    00000008     (.cinit..TI.bound:dmaSpi0TxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9a8    00000008     (.cinit..TI.bound:dmaSpi1RxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9b0    00000008     (.cinit..TI.bound:dmaSpi1TxControlTableEntry.load) [load image, compression = zero_init]
                   0000e9b8    00000008     (.cinit..bss.load) [load image, compression = zero_init]
                   0000e9c0    00000080     (__TI_cinit_table)

    It just looks a bit strange to me, that adding variables could have effects on this? And, I'm just guessing here, but the __TI_handler_table sounds like something that could cause trouble if it gets corrupted - and one of the sections that change in size is just before that?...

    Another observation - the global booleans are initialized to false when defined. If I remove this initialization and instead just set the variables to false in one of the existing functions running at startup, everything works.

  • Do you see this error on a TI dev board by any chance? If you decrease the TCLK rate, do you still see the issue (you can configure this in the .ccxml file)?

    The 16.9 LTS compiler used to incur additional task stack consumption over the 5.2.x ( I can remember what for; but this was fixed since we made this release) and as a result, we recommend our customers to use the toolchain version as noted in the release notes.

    I'm concerned switching to 16.9 is perhaps masking the error or you might be using the latest version where the tasks aren't growing anymore.

  • Hi Tom,

    Thanks for the info! Good to know at least one of the things to look for - is there a list of any other known issues somewhere?

    The board I'm using is a custom board, but I guess it shouldn't be too hard to see if I can get something similar running on a Launchpad board also, to see it that exhibits the same error. Would it help if I tried that, and would there be anything specific to look out for in that case?

    I've tried lowering the TCLK - started out at our default 10MHz, and tried 1MHz, 100kHz and 50kHz, all with the same "Unable to halt device" error.

    During my testing with the new compiler I haven't seen any problems with task stacks though, but as I might just have been lucky I can try again, and have a good look at how they behave...

    By the way - are there any plans for retesting the stack with the newest 16.9.x LTS compiler at some point, and possibly updating the recommendation if everything works out?

  • Hi Tom - quick bump for my two main questions - is there a list of known issues with BLE Stack 2.2.1 and the 16.9.x LTS compilers somewhere? Also - any plans for retesting the stack with the newest 16.9.x LTS compiler at some point, and possibly updating the recommendation if everything works out?

    Thanks in advance!