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: YFV (WCSP): Custom board firmware will not run (in or out of debug) after adding a few lines of code

Part Number: CC2640R2F
Other Parts Discussed in Thread: CC2640, , SYSBIOS

We are developing firmware using CC2640 SDK v4.30.00.08 in CCS v10.  The firmware is based on the BLE 5 Simple Peripheral example.  Development has been proceeding fine as features are added.  After adding the most recent set of modules, the firmware builds with no linker issues, and loads normally when starting a debug session, but after the firmware is loaded, rather than setting the firmware to start in main and enabling the resume button, the debug environment indicates the firmware is running.  The firmware is actually in the weeds not running.  The behavior is the same as described in the first part of this thread:

(+) CCS Unable to debug CC2650 code - Bluetooth forum - Bluetooth® - TI E2E support forums

The thread transitions to a different problem without a resolution to the original issue, unless the suggestion to change to a different optimization level is considered the solution.

We are going to be hard-pressed to fit the entire application into the flash on this part, so changing optimization levels toward speed away from size optimization is not an option.  I was concerned this latest code would not fit.  If this issue is related to code size, I would expect the build to fail, with the linker indicating that X space is required but the biggest available window is Y.  This has happened a couple times along the way, and I have been able to remove unused code to get the new code to fit, and development has proceeded from there.  Since the firmware is building successfully, I do not know whether to suspect code size.

I commented out a block of the new code as shown below:

bool startCaptureTask()
{
   CaptureMode captureMode = getCaptureMode();
   uint16_t taskStartDelay = getTaskStartDelayTime();
/*
   TaskConstructor taskConstructor = NULL;

   switch (captureMode)
   {
      case CAPTURE_MODE_A:

         taskConstructor = modeADataCollectorTask;

         break;

      case CAPTURE_MODE_B:

         taskConstructor = modeBDataCollectorTask;

         break;

      default:

      // Unrecognized mode; can't start a task

      return false;
   }

   return startNewTask(taskConstructor, taskStartDelay);
 */
   return false;
}

After this change, everything works fine.  This is code that is not executed at all unless directed to do so by a connected client.

If I modify the function to get rid of the switch block and simply assign one of the task structs to taskContructor, a debug session will start normally and wait to begin execution in main, but the firmware crashes at the Task_create call in ICall_createRemoteTasksAtRuntime.  Not sure how adding/removing unrelated code would lead to a BLE stack init crash.

Any info on where to look would be appreciated.

  • Hey Tony,

    Thanks for all the detail. I've assigned your post to an expert to comment.

  • Hi,

    Thanks for the thorough post.

    after the firmware is loaded, rather than setting the firmware to start in main and enabling the resume button, the debug environment indicates the firmware is running.  The firmware is actually in the weeds not running. 

    The explanation for this behaviour is that the code is failing initialization at runtime.

    The default configuration of the debugger is to auto-run to main. If, for some reason, the code fails to properly run before reaching main, it will just continue to run until some halt point is reached (breakpoint, etc) or a manual halt is issued.

    To further debug this issue and be able to step-by-step and try to find the exact root cause, disable the auto-run to main disable the option shown in section 7.2.5 of the CCS User's Guide.

    Unfortunately the causes for this to happen are many but, in your particular case, indeed it seems that a memory overrun may be happening during allocation. I would first try to check what are the heap configurations (check the file TOOLS/app_ble.cfg file on your project) for instructions on how to configure and increase the system heap.

    tip: I would create a copy of the file referenced file <ble_stack_heap.cfg> to modify it freely.

    Another possibility would be stack, although I think this is not really the reason but it is easy to experiment as well. If you want to change it, go to project properties --> ARM Linker --> Stack size

    Optimization itself may be responsible for some of these issues, especially if you are accessing variables that were optimized out - if I recall correctly, the object constructors run before main, which matches the symptoms of what you are seeing.

    I will try to think about additional details and report back in case I find anything relevant.

    Hope this helps,

    Rafael

  • Hi,

    The BLE5 Stack is big for CC2640R2F. I recommend you use other TI BLE MCU's that are recommended for BLE5.

    -kel

  • Thanks, Rafael.  That was certainly an interesting exercise.  I configured the debugger initially as you suggested, then after seeing that the application was blowing up at the BL  __TI_auto_init instruction in boot.asm, I configured it to run to __TI_auto_init in auto_init.asm at the start of a session.  It runs through this code with no issue I can recognize:

    _b1_:
    	.if __TI_AVOID_EMBEDDED_CONSTANTS
    	.thumb
    	MOVW	r5, __TI_CINIT_Base
    	MOVT	r5, __TI_CINIT_Base
    	MOVW	r7, __TI_CINIT_Limit
    	MOVT	r7, __TI_CINIT_Limit
    	MOVW	r6, __TI_Handler_Table_Base
    	MOVT	r6, __TI_Handler_Table_Base
    	.state16
    	.else
            LDR     r5, c_cinit_start
            LDR     r7, c_cinit_end
            LDR     r6, handler_start
    	.endif
    _b1_loop_:   
            CMP     r5,r7
            BCS     _b1_loop_end_
            LDMIA   r5!, {r0,r1}
            LDRB    r4, [r0]
            LSL     r4, r4, #2
            LDR     r4, [r6,r4]
            ADD     r0, r0, #1
            .if !__TI_TMS470_V4__
            BLX     r4
            .else
            BL      IND$CALL
            .endif
            B       _b1_loop_
    _b1_loop_end_:
    

    Then gets here:

    LDR	r0, c_exec
    	.endif
    	CMP	r0, #0
    	BEQ	_no_exec_
    	BLX	r0

    It winds up in ti_sysbios_family_arm_m3_Hwi_excHandler__I after this point.

    I ran the version of the firmware with the commented out code, and it gets past the BLX r0 instruction successfully.  Except for the values of c_cinit_start and c_cinit_end, both versions appear to execute the same.  The value of r0 (1001c415) when the firmware version that fails reaches this point is the same value as is present when the version that succeeds gets there, so I am not able to identify the nature of the failure from stepping through here.

    I looked at the map files for the two versions of firmware, and looking at the basic flash usage numbers, commenting out those lines of code results in a reduction in flash use of 3552 bytes.  It's not just those few lines of code that are removed from the image in the version that works.  It also removes 2 of the most recently added modules/.obj files since this the only place these are used.  But flash does not appear to be the problem.

    The heap is configured for auto-size.  Including the commented out lines in the build leaves around 2500 bytes free, while the default for a fixed-size heap is 6400 bytes.  I reduced the size of the largest buffer in the application, and now the application runs, so it looks like the issue is with the size of the heap, and we'll have to keep as close an eye on RAM use as program flash use.

    Thanks very much for your help.

  • Thanks, Kel.  I'm not sure changing micros is going to be an option for us at this point.  We'll be taking a look at this thread:

    CC2640: Reduce BLE-Stack code size - Bluetooth forum - Bluetooth® - TI E2E support forums

    ...and other info to see if we might have some options to pare down the space used by the stack.