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.

Sensor Controller / BLE crash

Hi everyone,

I'm using the Sensor Controller with a custom Simple BLE project. With my smartphone, I send a message to start several times the Sensor Controller between the connections events. The Sensor controller will blink a LED and alert the main CPU when over, the main function will wait the connections events to start the sensor.

It works around 60 times, but then everything stop and i'm unable to find the reason. Even the BLE communication crash.

The job of the sensor controller is described below, initialization and termination code are empty. The Sensor Controller is not driven by the RTC.

U16 x = 0;
U16 n = 0;
while(x < cfg.connInterval) {
    gpioSetOutput(cfg.pAuxioOLedCtrl[n]);
    fwDelayUs(1800, FW_DELAY_RANGE_2_MS);
    gpioClearOutput(cfg.pAuxioOLedCtrl[n]);
    fwDelayUs(200, FW_DELAY_RANGE_200_US);
    x = x + 4;
}
fwGenAlertInterrupt();

Functions used to init, start and stop the sensor controller : 

void SensorController_init(void)
{
	scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);
	scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);

	scifOsalInit();
	scifInit(&scifDriverSetup);
	IntMasterEnable();
}
SCIF_RESULT_T SensorController_stop(void)
{
	SCIF_RESULT_T res;
	scifResetTaskStructs(BV(SCIF_LED_BLINKER_TASK_ID),BV(SCIF_STRUCT_OUTPUT));

	res = scifStopTasksNbl(BV(SCIF_LED_BLINKER_TASK_ID));
	return res;
}
SCIF_RESULT_T SensorController_start_once(uint16_t tck, uint32_t start)
{
	SCIF_RESULT_T sys ;

	// Give SensorController interval time
	scifTaskData.ledBlinker.cfg.connInterval = (uint16_t)tck;
	sys = scifStartTasksNbl(BV(SCIF_LED_BLINKER_TASK_ID));	// Init - execute - terminate
	return sys;
}

When the smartphone will command the system to start, I register to the HCI connection event :

HCI_EXT_ConnEventNoticeCmd(selfEntity,PERI_CON_EVT_COMPLETE_EVT);

I will wait on the connection event and start the sensor controller 

if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
        	ICall_Event *pEvent = (ICall_Event*)pMsg;
        	if(pEvent->signature == 0xffff)
		{
        		pEvent->signature &= ~0xffff;
        		if(pEvent->event_flag == PERI_CON_EVT_COMPLETE_EVT)	// Connection event started
			{
        			pEvent->event_flag &= ~PERI_CON_EVT_COMPLETE_EVT;
        			  // Do x steps
        			SensorController_start_once(TCK, start);
        			LCD_WRITE_STRING("Started",LCD_PAGE4);
        			while(scifWaitOnNbl(0) != SCIF_SUCCESS);
        			if(Semaphore_pend(Semaphore_handle(&semScTaskAlert),BIOS_NO_WAIT))
        			{
        			    scifClearAlertIntSource();
        			    scifAckAlertEvents();
	        		}
        			SensorController_stop();
        			while(scifWaitOnNbl(0) != SCIF_SUCCESS);
			}
		}
          Peri_Peripheral_processStackMsg((ICall_Hdr *)pMsg);	// Process inter-task message
        }

The system will turn around 64 times, always (even with a task_sleep between) before crashing. And all functions return SCIF_SUCCESS.

If I send another BLE order, write orders on android will not respond and the system will start one - two times the sensor before complete freeze.

Any help is welcome.

Have a nice day

Sebastien

  • Have you tried to use scifExecuteTasksOnceNbl instead to start the task?
    With the way you have structured your code as of today I think you also need to wait for the task to complete using scifWaitOnNbl after stopping it.

    Regards,
    Svend
  • I also tried the scifExecuteTaskOnceNbl and the same problem appears. I use the scifWaitOnNbl after starting and stopping the sensor controller.
  • Hello Pittet,
    If you look at the led_blinker example project that comes with the sensor controller studio you can see how you should stop the task. Try to use the following from main.c in the example project (\Documents\Texas Instruments\Sensor Controller Studio\examples\led_blinker):

    if (scifStopTasksNbl(BV(SCIF_LED_BLINKER_TASK_ID)) == SCIF_SUCCESS) {
    scifWaitOnNbl(42);
    scifResetTaskStructs(BV(SCIF_LED_BLINKER_TASK_ID), BV(SCIF_STRUCT_OUTPUT));
    }

    You have to call scifStopTasksNbl before you call scifResetTaskStructs.

  • Thanks for the answers,

    I changed my SensorController_stop function like this ;

    SCIF_RESULT_T SensorController_stop(void)
    {
    	SCIF_RESULT_T res = SCIF_SUCCESS;
    	res = scifStopTasksNbl(BV(SCIF_LED_BLINKER_TASK_ID));
    	if(res == SCIF_SUCCESS){
    		while(scifWaitOnNbl(0) != SCIF_SUCCESS);
    		scifResetTaskStructs(BV(SCIF_LED_BLINKER_TASK_ID),BV(SCIF_STRUCT_OUTPUT));
    	}
    
    	return res;
    }

    But it stop as before, around 63-64 start/stop of the controller sensor.

    If I ask to do 10 - 20 turns it will be ok, but when 60 turns have been made, the system crash

    Thanks in advance for your help

  • I seems that the system stay in Power.c when crashing.... with the debugger i can see that after a certain point there is no more reactions in the BLE stack. The connections events are not triggered anymore !
  • Hi again,

    I tried this morning something different, I removed the sensor controller functions and only increments a static value between the connection event: The system does crash as before !

    Here are the tasks when crashed, the Idle Task is running and everything is blocked... it seems that the stack size is not the problem. 

    Any help is welcome

    Have a nice day

    Sebastien

  • If somebody does have a CC2650EM-7ID and the SmartRF06, here is my source code (minimal implementation) to crash / stop the system without a known reason (actually).

    The system, when connected, will register to advertising / connection events and count until 1500. For the moments it counts only to 68

    Thanks in advance !

    /*********************************************************************
     * INCLUDES
     */
    
    #include <xdc/std.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/drivers/LCD/LCDDogm1286.h>
    #include <ti/sysbios/family/arm/cc26xx/Power.h>
    #include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
    #include <driverlib/aon_rtc.h>
    #include <driverlib/gpio.h>
    #include <driverlib/ioc.h>
    #include <driverlib/prcm.h>
    #include <ICall.h>
    #include <string.h>
    
    #include <inc/hw_types.h>
    #include <inc/hw_memmap.h>
    #include <inc/hw_ioc.h>
    #include <inc/hw_gpio.h>
    #include <inc/hw_uart.h>
    
    #include "gatt.h"
    #include "hci.h"
    #include "gapgattserver.h"
    #include "gattservapp.h"
    
    #include "DevInfoService.h"
    #include "Simple_BLE_peripheral.h"
    #include "peripheral.h"
    #include "gapbondmgr.h"
    #include "util.h"
    
    #include "board_LCD.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    /*********************************************************************
     * CONSTANTS
     */
    #define DEFAULT_ADVERTISING_INTERVAL    	320		// Interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_TIMEOUT			1		// Advertising Timeout in sec
    #define DEFAULT_ADVERTISING_TIMEOFF			30000 	// Advertising Timeoff in msec (after timeout)
    #define DEFAULT_DISCOVERABLE_MODE      		GAP_ADTYPE_FLAGS_LIMITED // Discoverable mode (limited/general)
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL 	320		// Min Connection interval (units of 1.25ms, 80=100ms)
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL   640		// Max Connection interval (units of 1.25ms, 80=100ms)
    #define DEFAULT_DESIRED_SLAVE_LATENCY    	10		// Requested slave latency
    #define DEFAULT_DESIRED_CONN_TIMEOUT        1000	// Connection Timeout
    #define DEFAULT_ENABLE_UPDATE_REQUEST       TRUE	// Enable update request
    #define DEFAULT_CONN_PAUSE_PERIPHERAL       10		// Connection Pause BLEpheral time value (in seconds)
    
    #define BLE_TASK_PRIORITY          			1		// Task priority - max = 5
    
    #define DEFAULT_BOND_PASS_KEY				000000	// Pass key for appairing
    #define BLE_CON_EVT_COMPLETE_EVT  			0x0001  // Connection interval event
    #define BLE_ADV_EVT_COMPLETE_EVT  			0x0002  // Advertising event
    #define BLE_CHANGE_STATE_EVT	   			0x0004	// Connection state event
    
    #define BLE_TASK_STACK_SIZE					644
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static ICall_EntityID selfEntity;		// Entity ID globally used to check for source and/or destination of messages
    static ICall_Semaphore sem;				// Semaphore globally used to post events to the application thread
    static Semaphore_Struct semScTaskAlert;	// Semaphore used to wait for Sensor Controller task ALERT event
    
    
    static uint8_t attDeviceName[] = "******";	// GAP GATT Attributes
    
    static Clock_Struct BLEodicClock;		// Clock instances for internal BLEodic events.
    static Queue_Struct appMsg;				// Queue object used for app messages
    static Queue_Handle appMsgQueue;
    
    // Task struct and stak size - has to be global values !
    Task_Struct BLE_Task;
    Char BLE_TaskStack[BLE_TASK_STACK_SIZE];
    
    /*********************************************************************
     * GAP - SCAN RSP DATA + ADVERTISEMENT DATA
     * Max size 31 bytes !
     */
    
    static uint8_t scanRspData[] =
    {
      0x0C,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x50, 0x65, 0x72, 0x69, 0x5F, 0x53, 0x65, 0x6E, 0x73, 0x6F, 0x72,
    
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // Tx power level : 0dBm
    };
    
    static uint8_t advertData[] =
    {
      0x02,  			 	// length of this data
      GAP_ADTYPE_FLAGS,		// Flags; this sets the device to use limited discoverable mode
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED
    };
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    typedef struct
    {
      uint8_t event;  	// Which profile's event
      uint8_t status; 	// New status
    } BLE_Evt_t;			// App event passed from profiles.
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void Simple_BLEpheral_init( void );
    static void Simple_BLE_taskFxn(UArg a0, UArg a1);
    
    static void Simple_BLE_stateChangeCB(gaprole_States_t newState);
    static void Simple_BLE_enqueueMsg(uint8_t event, uint8_t status);
    
    static void Simple_BLE_processStackMsg(ICall_Hdr *pMsg);
    static void Simple_BLE_processGATTMsg(gattMsgEvent_t *pMsg);
    static void Simple_BLE_processAppMsg(BLE_Evt_t *pMsg);
    
    static void Simple_BLE_processStateChangeEvt(gaprole_States_t newState);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    static gapRolesCBs_t Simple_BLE_gapRoleCBs =
    {
      Simple_BLE_stateChangeCB,    // Profile State Change Callbacks
      NULL,     						// When a valid RSSI is read from controller
    };
    
    static gapBondCBs_t Simple_BLE_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /* @fn      Simple_BLEpheral_init
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup. */
    static void Simple_BLEpheral_init(void)
    {
      ICall_registerApp(&selfEntity, &sem);			// Register the current thread as an ICall dispatcher application
    
      //HCI_EXT_SetSCACmd(40);						// Set device's Sleep Clock Accuracy
      appMsgQueue = Util_constructQueue(&appMsg);	// Create an RTOS queue for message from profile to be sent to app.
    
      /* Create one-shot clocks for internal BLEodic events.
      Util_constructClock(&BLEodicClock, Simple_BLE_clockHandler,
                          BLE_BLEODIC_EVT_BLEOD, 0, false, BLE_BLEODIC_EVT);*/
    
      Board_openLCD();	// Enable LCD
    
      Semaphore_Params semParams;
      Semaphore_Params_init(&semParams);
      semParams.mode = Semaphore_Mode_BINARY;
      Semaphore_construct(&semScTaskAlert, 0, &semParams);
    
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);	 //Time upon connection before connection (default : 5sec)
    
      // Setup the GAP BLEpheral Role Profile
      {
        uint8_t initialAdvertEnable = TRUE; // device starts advertising upon initialization
    
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
        uint16_t advTimeout = DEFAULT_ADVERTISING_TIMEOUT;
        uint16_t advertOffTime = DEFAULT_ADVERTISING_TIMEOFF;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
    
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 	sizeof(uint8_t)		, &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, 	sizeof(uint16_t)	, &advertOffTime);
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_EN, 	sizeof(uint8_t)		, &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t)	, &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t)	, &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, 	sizeof(uint16_t)	, &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER,sizeof(uint16_t)	, &desiredConnTimeout);
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, 	sizeof(scanRspData)	, scanRspData);
    	GAPRole_SetParameter(GAPROLE_ADVERT_DATA, 		sizeof(advertData)	, advertData);
    
    	GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);	// BLE BLEpheral v102
    
        GAP_SetParamValue(TGAP_LIM_ADV_TIMEOUT, advTimeout);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, advTimeout);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);	// Same for general and limited mode
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      {	// Setup the GAP Bond Manager
    	uint32_t passkey = DEFAULT_BOND_PASS_KEY;
        uint8_t mitm = FALSE;
        uint8_t bonding = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE,sizeof(uint32_t), &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, 	 sizeof(uint8_t) , &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t) , &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t) , &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t) , &bonding);
      }
    
      // Initialize GATT Client
      VOID GATT_InitClient();
      GATT_RegisterForInd(selfEntity);
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
      VOID GAPBondMgr_Register(&Simple_BLE_BondMgrCBs);	// Start Bond Manager
      VOID GAPRole_StartDevice(&Simple_BLE_gapRoleCBs);	// Start the Device
    }
    
     /*@fn      Simple_BLE_createTask
     * @brief   Task creation function and confiuration */
    void Simple_BLE_createTask(void)
    {
      Task_Params taskParams;
    
      Task_Params_init(&taskParams);
      taskParams.stack = BLE_TaskStack;
      taskParams.stackSize = BLE_TASK_STACK_SIZE;
      taskParams.priority = BLE_TASK_PRIORITY;
    
      Task_construct(&BLE_Task, Simple_BLE_taskFxn, &taskParams, NULL);
    }
    
    /* @fn      Simple_BLE_taskFxn
     * @brief   Application task entry point for the Simple BLE BLEpheral */
    static void Simple_BLE_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      Simple_BLEpheral_init();
    
      uint16_t test_val = 0;
    
      for (;;)
      {
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
          if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
            	ICall_Event *pEvent = (ICall_Event*)pMsg;
            	if(pEvent->signature == 0xffff)
    			{
            		if(pEvent->event_flag == BLE_CON_EVT_COMPLETE_EVT)	// Connection event started
    				{
            			Task_sleep(250);	// Wait end of connection event
            			pEvent->event_flag &= ~BLE_CON_EVT_COMPLETE_EVT;
            			test_val++;
            			LCD_WRITE_STRING_VALUE("test_val :", (uint16_t)test_val, 10, LCD_PAGE2);
            			if(test_val >= 1500){
            				HCI_EXT_ConnEventNoticeCmd(selfEntity,0);
            				HCI_EXT_AdvEventNoticeCmd(selfEntity,0);
            			}
    				}
            		else if(pEvent->event_flag == BLE_ADV_EVT_COMPLETE_EVT)	// Connection event started
    				{
            			Task_sleep(500);	// Wait end of advertising event
            			pEvent->event_flag &= ~BLE_ADV_EVT_COMPLETE_EVT;
            			test_val++;
            			LCD_WRITE_STRING_VALUE("test_val :", (uint16_t)test_val, 10, LCD_PAGE2);
            			if(test_val >= 1500){
            				HCI_EXT_ConnEventNoticeCmd(selfEntity,0);
            				HCI_EXT_AdvEventNoticeCmd(selfEntity,0);
            			}
    				}
    			}
              Simple_BLE_processStackMsg((ICall_Hdr *)pMsg);	// Process inter-task message
            }
            else if (pMsg)
              ICall_freeMsg(pMsg);
          }
    
          if (!Queue_empty(appMsgQueue))	// If RTOS queue is not empty, process app message.
          {
            BLE_Evt_t *pMsg = (BLE_Evt_t *)Util_dequeueMsg(appMsgQueue);
            if (pMsg)
            {
              Simple_BLE_processAppMsg(pMsg);	// Process message.
              ICall_free(pMsg);						// Free the space from the message.
            }
          }
        }
      }
    }
    
    /* @fn      Simple_BLE_processStackMsg
     * @brief   Process an incoming stack message.*/
    static void Simple_BLE_processStackMsg(ICall_Hdr *pMsg)
    {
      if(pMsg->event == GATT_MSG_EVENT)
      {
    	  Simple_BLE_processGATTMsg((gattMsgEvent_t *)pMsg);
      }
    }
    
    /* @fn      Simple_BLE_processGATTMsg
     * @brief   Process GATT messages */
    static void Simple_BLE_processGATTMsg(gattMsgEvent_t *pMsg){
      GATT_bm_free(&pMsg->msg, pMsg->method);
    }
    
    /* @fn      Simple_BLE_processAppMsg
     * @brief   Process an incoming callback from a profile.*/
    static void Simple_BLE_processAppMsg(BLE_Evt_t *pMsg)
    {
      if(pMsg->event == BLE_CHANGE_STATE_EVT)
      {
    	  Simple_BLE_processStateChangeEvt((gaprole_States_t)pMsg->status);
      }
    }
    
    /* @fn      Simple_BLE_stateChangeCB
     * @brief   Callback from GAP Role indicating a role state change.*/
    static void Simple_BLE_stateChangeCB(gaprole_States_t newState){
      Simple_BLE_enqueueMsg(BLE_CHANGE_STATE_EVT, newState);
    }
    
    /* @fn      Simple_BLE_processStateChangeEvt
     * @brief   Process a pending GAP Role state change event.*/
    static void Simple_BLE_processStateChangeEvt(gaprole_States_t newState)
    {
    
      if(newState == GAPROLE_STARTED)
      {
    	uint8_t ownAddress[B_ADDR_LEN];
    	uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
    	GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);	// use 6 bytes of device address for 8 bytes of system ID value
    	systemId[0] = ownAddress[0];
    	systemId[1] = ownAddress[1];
    	systemId[2] = ownAddress[2];
    	systemId[4] = 0x00;				// set middle bytes to zero
    	systemId[3] = 0x00;
    	systemId[7] = ownAddress[5];	// shift three bytes up
    	systemId[6] = ownAddress[4];
    	systemId[5] = ownAddress[3];
    
    	DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
      }
      else if (newState == GAPROLE_ADVERTISING)
      {
          LCD_WRITE_STRING("Advertising", LCD_PAGE1);
      }
      else if (newState == GAPROLE_CONNECTED)
      {
    	uint8_t peerAddress[B_ADDR_LEN];
    
    	GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    	LCD_WRITE_STRING("Connected", LCD_PAGE1);
    	HCI_EXT_ConnEventNoticeCmd(selfEntity,BLE_CON_EVT_COMPLETE_EVT);	// Register to connection events
    	HCI_EXT_AdvEventNoticeCmd(selfEntity,BLE_ADV_EVT_COMPLETE_EVT);	// Register to advertising events
      }
      else if (newState == GAPROLE_WAITING)
      {
    	LCD_WRITE_STRING("Disconnected", LCD_PAGE1);
      }
    }
    
    /* @fn      Simple_BLE_enqueueMsg
     * @brief   Creates a message and puts the message in RTOS queue.*/
    static void Simple_BLE_enqueueMsg(uint8_t event, uint8_t status)
    {
      BLE_Evt_t *pMsg ;
      pMsg = ICall_malloc(sizeof(BLE_Evt_t));
    
      // Create dynamic pointer to message.
      if (pMsg)
      {
        pMsg->event = event;
        pMsg->status = status;
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);	// Enqueue the message
      }
    }
    
    /*********************************************************************
    *********************************************************************/
    

  • Pittet,

    You are not freeing memory correctly so the stack heap manager will fail to allocate more RAM for messages.
    Define HEAPMEM_METRIC when compiling and check at least the variables heapmgrMemAlo / heapmgrMemFail to see the current heap status.

    When I did that in your code I see 20 allocations failed and current usage is 2584 bytes after it failed.

    Regards,
    Svend
  • Thanks for the answer,

    How can I free correctly the memory ? Where are the variables or mechanisms needing so much RAM ? I thought it was a stack problem but I wasn't able to find the beginning of the problem.

    Thanks in advance
    Sebastien
  • The stack is allocating memory for every connection event sent to your application that should be freed.
    See SWRU393 chapter 4.3.2.1.1 for example code on how this is done.

    I think there are two things needing to change:

    1:
    Simple_BLE_processStackMsg needs to be put in an "else". This is forwarded to the GATT client to free the contents of the message but not the message itself.

    2:
    The "else if (pMsg)" should be only an "if". Without it any connection event notice messages will never be freed and the heap continues to build up.
  • Thanks a lot ! It does solve the problem !

    Have a nice day
    Sebastien