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.

SerialBLEBridge in Central mode instead of Peripheral = stack pointer outside of stack range

Hi, I've been working for a couple weeks now to try and adapt the SerialBLEBridge example from the wiki to work in Central mode instead of Peripheral mode.  So, really, what I tried to do was merge the SerialBLEBridge, which I can independently get to work in peripheral mode, with the SimpleBLECentral example project that I can also get to work independently, and I seem to have integrated the serial bridge part in correctly since I can send commands and respond with data correctly, but when I try and call GAPCentralRole_StartDiscovery I get a stack overflow.  

I've been stuck on this for a while now and have not been able to find a way to solve this.  The exact error is:

The stack 'IdataStack' is filled to 100% (192 bytes used out of 192). The warning threshold is set to 90.%
The stack 'XdataStack' is filled to 100% (640 bytes used out of 640). The warning threshold is set to 90.%
The stack pointer for stack 'XdataStack' (currently XData:0xFFFF) is outside the stack range (XData:0x0001 to XData:0x0281)

I feel like I've made a little progress by reducing the size of all of my constant variables, and reducing the sizes of the serialbridge buffers, but nothing I do seems to get me past this.  I've never been able to successfully do a discovery..

Difficult to answer this one, I know, but hoping someone has an idea.

I'm using BLE stack 1.4

Thanks

  • Have you tried increasing the stack size? You can do this in the IAR project configuration settings under General Options -> Stack/Heap tab. The default XDATA stack size is set to 0x280 (640). You can increase this (assuming that your application doesn't use up the remaining RAM on the device).

  • I did max that out. I had to reduce the size of the circular buffer in the serialblebridge example project in order to get it to compile with the default configuration, then reduced them even more in order to try and create more stack space.  I've got the serialblebridge circular buffer down to 64bytes and the xdata stack size taking up the rest of the space and still get the stack problems.  There really isn't anything else in my code that takes up stack space, and no recursive function calls. So, I am left wondering if Central mode (as opposed to peripheral mode) inherently takes up a lot of stack space, or maybe there are some setting I can tweak to make it use less?

  • In our experience, the error messages you report are due to the debugger; maybe losing synchronization with the target.  In fact you can stimulate the error message by unplugging the the CC Debugger from the target and then plug it back in.  The debugger then reports:

    "The stack pointer for stack 'XdataStack' (currently XData:0x0000) is outside the stack range (XData:0x0001 to XData:0x03C1) "

    You can also stimulate the problem by cycling power on target board while connected to the debugger.  

     

  • Very interesting...  Is there a way to stop that from happening?  Or typical reasons for that happening?

    Or rather here's a bit more data for you.  Would it be consistent with this problem to also have the processor reset?  I print a debug message when the processor resets and each time I call the GAPCentralRole_StartDiscovery function I also get the debug message printed "Central Init".

  • I don't know what exactly is the cause, but am suggesting that you look elsewhere than stack size because the problem is probably not what it appears.  My hunch is a loss of synchronization between debugger and processor; this might well be related to processor reset.  

    In any case, if your processor resets each time you call a function, I would look closer at the function and how you're using it. 

  • Richard, I've dug in to this even further and have more information.  Before I thought I was seeing the processor reset when calling GAP_DeviceDiscoveryRequest() (in central mode I want to discover peripherals...).  I broke this down further and in fact it doesn't reset if I start discovery when no devices are advertising.  But, as soon as I set a peripheral to advertise the device resets.  

    Here are a couple screenshots that show the last point of normal behavior I can find before the everything resets.  The first is when the GAP discovery times out without ever seeing a device advertise (this is what normal looks like here).  The second occurs right when I turn a peripheral on to advertise while the master is in GAP discovery mode. 

    Notice in both cases the pMsg->event (defined 0xD0) is a GAP_MSP_EVENT and in the first one I receive that event in my pGapCentralRoleCB callback function.  But in the second instance I don't receive any event, instead I get a reset...

    Is there anything you can see in that pMsg data struct that can give me a hint as to what is going on?  Is there any way to debug this further?

    Thanks

  • More information...  I followed the pMsg pointer to memory through for the two examples I gave and figured out what's going on.  

    As soon as I turn on a peripheral while my Central is in discovery mode gapCentralRole_ProcessGAPMsg() gets called with the opCode set to GAP_DEVICE_INIT_DONE_EVENT.  See that function below (no modification from the sample central.c file TI produces).  So, no error messages, or discernible status message, just sends an opCode that device init is done.  

    Can you tell me what GAP could be doing that would cause this to happen?  It's really a black box to me what is going on.  All of my discovery settings are exactly what TI recommends out of the box for SimpleBLECentral.  My peripheral is a Polar HeartRate Monitor, and it can connect to other Centrals fine.

    /*********************************************************************
     * @fn      gapCentralRole_ProcessGAPMsg
     *
     * @brief   Process an incoming task message from GAP.
     *
     * @param   pMsg - message to process
     *
     * @return  none
     */
    static void gapCentralRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
    {
      switch ( pMsg->opcode )
      {
        case GAP_DEVICE_INIT_DONE_EVENT:
          {
            gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *) pMsg;
    
            if ( pPkt->hdr.status == SUCCESS )
            {
              // Save off the generated keys
              VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapCentralRoleIRK );
              VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapCentralRoleSRK );
    
              // Save off the information
              VOID osal_memcpy( gapCentralRoleBdAddr, pPkt->devAddr, B_ADDR_LEN );
            }
          }
          break;
    
        case GAP_LINK_ESTABLISHED_EVENT:
          {
            gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *) pMsg;
    
            if (pPkt->hdr.status == SUCCESS)
            {
              // Notify the Bond Manager of the connection
              VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr,
                                       pPkt->connectionHandle, GAP_PROFILE_CENTRAL );
            }
          }
          break;
    
        case GAP_LINK_TERMINATED_EVENT:
          {
            uint16 connHandle = ((gapTerminateLinkEvent_t *) pMsg)->connectionHandle;
    
            VOID GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
    
            // Cancel RSSI reads
            GAPCentralRole_CancelRssi( connHandle );
          }
          break;
    
        // temporary workaround
        case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
          VOID GAPBondMgr_ProcessGAPMsg( pMsg );
          break;
    
        default:
          break;
      }
    
      // Pass event to app
      if ( pGapCentralRoleCB && pGapCentralRoleCB->eventCB )
      {
        pGapCentralRoleCB->eventCB( (gapCentralRoleEvent_t *) pMsg );
      }
    }

  • It sounds like the reset occurs when the BLE stack discovers a device.  Suggest you assume that the BLE stack is working correctly and focus on your callback, especially the GAP_DEVICE_INFO_EVENT and GAP_DEVICE_DISCOVERY_EVENT cases.

  • I have been, but I feel like I've exhausted every option to look at.  When there is no device advertising, then the callbacks occur properly when discovery times out and I see the event/opcode come in as expected tracing it all the way through from central.c to my main app callback function.  So, aside from confirming that my callback is hooked in properly I just can't figure out what is going on.

    I almost feel like the issue may have to do with adding these defines in the C preprocessor:

    SERIAL_INTERFACE
    HAL_UART=TRUE
    NPI_UART_PORT=HAL_UART_PORT_1
    HAL_UART_SPI=1
    HAL_UART_DMA=0

    Can enabling those features mess with the way Central profile operates or overwrite some memory somewhere?

  • Was this problem ever resolved? I am having the same problem except with SimpleBLEObserver.

    When no device is discovered, the debugger works just as expected. When I enable my advertisement application, and it detects a device, it jumps out of the stack and simply resets. Not sure what I should be looking at next any solutions/suggestions?

    Thanks.