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.

stuck after porting to stack 2.2

Other Parts Discussed in Thread: CC2650, SYSBIOS

Hello,

I’ve ported an existing cc2650 project (based on the simple peripheral project) from using the BLE stack 2.1 to version 2.2. Everything compiles and links again, but now I ran into runtime problems. When I start the application, a break point in the GATT servers task function is never reached. When I break into the debugger, I get a current program counter pointing to 0x1001bbd6 without any back trace available.
When I comment out, the creation of the stack task (ICall_createRemoteTasks()), the break point is reached, so I assume that the CPU is hanging/trapping within the stack task, which prevents the task scheduler from calling other task functions. According to the Technical Reference Manual (SWCU117F) this range (0x1001bbd6) is still flash, but as the cc2650 has only 128k (0x20000) of flash, this address must be something else (rom maybe; is there some documentation, documenting this?).
Does someone of you successfully ported an existing stack 2.1 project to 2.2, ran into the same issue and fixed that? Any idea / advice on how to tackle this issue?
Thanks in advance and kind regards,
Torsten
  • Hello Torsten,

    Indeed, you have hit an abort but 0x1001bbd6 is a ROM function, not flash. It's hard to say what the issue could be from the description alone, but did you confirm the stack project is built/flashed correctly and programmed with the correct ICALL_STACK0 address. See "3.10.2 Application and Stack Flash Boundary" in the SW Developer's Guide (SWRU393).

    I would start there.

    Best wishes
  • Hello JXS,

    thank you very much for responding. Yes, I've checked the ICALL_STACK0 address. It's still 0xf000 (as for the original SimplePeriperhal example) and that's confirmed by looking into the map files of the application and the stack project. Both, flash and ram do not overlap for the stack and the application project.

    The assembly code at the address 0x1001bbd6 is:

    0x1001bbd6: cmp r2, #0
    0x1001bbd8: beq 0x1001bbd6:

    With r2 being #0. I wonder under which circumstance does such a loop makes sense? I can only think of an endless loop or some kind of wait for an ISR that sets R2 to some value other then #0.

    The stack pointer points into the heap, which makes sense, if the stacks stack is allocated on the heap (at least I didn’t found any symbol that sounds like the stacks stack in the map file).
    I’ve looked at the top of the stack, when the CPU is running this loop. The only address, that is at the top of the stack, that is within the application or stack image, is 0x0000B747 which is (according to the map files) ICall_primMalloc(). I’ve set a break point to that function but it seems to run without problems.

    The only interrupt vectors that are within the interrupt vector table that points to the ROM region are 0x1001CA01 and 0x1001CA3F, which is clearly not the 0x1001bbd6, that I’m observing.

    Puh, what options do I have now?

    - Keep poking around in the dark, hoping that I finally stumble over the mistake I made?
    - Role back my porting so far and do it again, hopping that I will not do the same mistake again?

    Anything else that comes to mind? Any chance that I get the source for ROM functions?

    Thanks in advance,

    Torsten
  • By following the link register and assembly code over ~5 function calls, I’ve managed to confirm, that the endless loops origins from the task function of the task create by ICall_createRemoteTasks. The task function simply calls the function at ICALL_STACK0_ADDR and passing it the address of a configuration struct named user0Cfg. I’ve checked that the argument to ICALL_STACK0_ADDR (startup_entry) is passed correctly. So there is very little, that I can do on that end.

    Here is the complete function that contains the infinite loop:
    0x1001bbc8: ldr r2, [pc, #0x14]  ; boils down to 0x20000148
    0x1001bbca: push {r3, lr}
    0x1001bbcc: ldr r2, [r2]
    0x1001bbce: movs r3, #1
    0x1001bbd0: strh r3, [r2]
    0x1001bbd2: ldr r2, [pc, #0x10]  ; boils down to 0x000004A0
    0x1001bbd4: ldr r2, [r2]         ; loads 0x000004A0
    0x1001bbd6: cmp r2, #0           ; r2 is 0 here
    0x1001bbd8: beq 0x1001bbd6:
    0x1001bbd8: blx r2
    0x1001bbd8: pop {r3, pc}

    So it looks like, that the function is loading a function address from 0x000004A0, which (is according to the map file) ti_sysbios_family_arm_m3_Hwi_excHandlerFunc__C and has the value zero. When I install the SimplePeripheral Example, the very same address (0x000004A0) contains the very same symbol and the very same value (0x0000).
    So the question is not, why this vector is 0, but why this vector is invoked, right? Does someone have an idea, what the purpose of this ti_sysbios_family_arm_m3_Hwi_excHandlerFunc__C vector is and what might cause the unknown code in the ROM might trigger to call it?
    Thanks for listening!
  • Ok, now as I was desperate enough, I replaced my project files (as suggested) with the project file from the SimplePeripheral project and started from scratch to make the project position independent. The resulting SimplePeripheral project worked. Then I replace the simeple_peripheral-Service with my service, I added all the required sources and added SRC_BLE_CORE/common/cc26xx/board_key.c to the project.

    Now the project compiles and links again, but it’s not running anymore. When starting the firmware, a function called ICall_primRegisterApp() is called. That function does a linear search in a 6 element long array ICall_entities, searching for an empty slot. It does not find an empty entry and is calling ICALL_HOOK_ABORT_FUNC(). Looks like I have to fiddle with some defines again…
    When I set a breakpoint in the ICall_primRegisterApp() function, why can't I inspect the global variable ICall_entities? (Error: identifier not found: ICall_entries)
  • I found out, that if I introduce a bug into the SimplePeripheral example that simply does not free memory allocated by events received by ICall_fetchServiceMsg(), by commenting out the call to ICall_freeMsg(), I get the exact same behavior:
    - The CPU is running in the loop above.
    - The current PC is not on top of any of the RTOS tasks call stacks.
    - The display on the eval board is showing nothing.

    Now I wonder if a memory leak (shortage) is the only reason for the RTOS to go into this infinite loop or if there are other causes. Is there a way to install some kind of memory shortage handler, that would be called if the allocator is not able to allocate the requested amount of memory?

    BTW: Under RTOS Object View, I can watch HeapMem. There seams to be one heap and when the infinite loops happens, that heap has still a totalFreeSize (and largestFreeSize) of 0x258. Does the RTOS/icall use it's own heap for messages?

    kind regards,
    Torsten
  • Hi Torsten,

    There is a small BIOS heap that is used for dynamically allocating RTOS objects (like clocks, etc), however the BLE stack and the application use the ICALL heap. What compiler version are you using to build the project? Can you build and run the default examples with the SDK?
  • Hi Sean,

    the compiler version is:

    C:\Users\Torsten>C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.6/bin/armcl --compiler_revision
    5.2.6

    I've tried just the simple_peripheral_cc2650em example and that works (advertising looks reasonable, I can connect to the device and interact with in on a GATT level).

    kind regards,

    Torsten

  • Hello Sean,

    Currently I’m experimenting with a setup, where the device does not add any additional GATT services (only the GAP service). I can easily change that example from „working“ to „not working“, by removing the device name from the scan response data. Now I made a diff between the map files of the working and the not-working versions. What puzzles me, is that the symbol rfRegTbl (defined in blue_user_config.c to be an array of 20 32-bit values), begins at an address that would not be proper aligned for 32 bit integers, for the not working version (left side), but begins at a proper aligned address in the working version (right side).

    Is rfRegTbl accessed in a manner that requires the symbol to be 32-bit aligned?

    Can I instruct the linker to force a certain alignment for a single symbol, or for all symbols?

    Please see the attached screenshot.

    kind regards,

    Torsten

  • I've managed to place the rfRegTbl in an own linker output section, and thus forced the alignment to be 4 byte, and now my striped down version works. I will see if that works for the overall version too...

    Here is my patch:

    Index: cc26xx_app.cmd
    ===================================================================
    --- cc26xx_app.cmd	(revision 428)
    +++ cc26xx_app.cmd	(working copy)
    @@ -128,8 +128,14 @@
         .emb_text       :   >> FLASH | FLASH_LAST_PAGE
         .ccfg           :   >  FLASH_LAST_PAGE (HIGH)
     
    +
    +	ble_user_config {
    +		./ICallBLE/ble_user_config.obj(.data)
    +	} > SRAM
    +
     	GROUP > SRAM
     	{
    +		ble_user_config
     	    .data
     	    .bss
     		.vtable
    

  • Jep, that fixed the original problem too :-)
  • Thanks Torsten. i was seeing an issue connecting after adding the board_key.c file. Applying this fix has addressed the issue.
  • Apologies for replying to a year-old post, but this was the first Google result I found when researching the same problem, which appears to continue to affect the current version of the BLE stack (2.2.1.18).

    The root cause of this issue appears to be that regOverride_t, the type that rfRegTbl resolves to, is defined in ble_sdk_2_02_01_18/src/components/hal/src/target/_common/cc26xx/rf_hal.h like so:

    PACKED_TYPEDEF_UNION
    {
      hwOverride_t hwRegOverride;
      fwOverride_t fwRegOverride;
    } regOverride_t;

    PACKED_TYPEDEF_UNION ultimately resolves to (for CCS/TI compiler) "typedef union __attribute__((__packed__))" with the packed attribute explicitly telling the compiler to omit the padding required to preserve word-alignment (See SPNU151P section 5.16.4).

    The fix is to change "PACKED_TYPEDEF_UNION" at line 833 in rf_hal.h to "typedef union".

  • Yes, rfRegTbl is of type regOverride_t. My fix just forced the linker to align that symbol properly, so that the ROM code, that is accessing the table won't crash. This way you don't have to touch the library source (a fix that you have to redo with every new version).

    But, of cause, if TI would fix that, it would save us a lot of trouble.