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.

OSAL Task Not Working

Other Parts Discussed in Thread: CC2541

Basically, I've got two OSAL application tasks, and whichever one has the lower priority never seems to process events.

I've got a CC2541 that I'm working with, and I believe my project started life as the SimpleBLEPeripheral.  The main application task sets up all the bluetooth stuff and then calls osal_set_event on itself to start advertising after initialization.  It was working fine until I added a second application task to handle blinking LEDs and whatnot.

Added the ProcessEvent function to tasksArr[], and added the Init function to osalInitTasks(), making sure they were both in the same order, right above the main application task in priority.  Again, at the end of the init function, the task calls osal_set_event on itself to light an LED signifying that the board has started up.

At this point, the LED worked, but bluetooth never started advertising.  If I swapped priority on the task list (in both the array and the Init calls), then bluetooth would advertise properly, but the light would never come on.  It's not a matter of either task never completing, because the board continues to process events at later times.  And since both work on their own, I don't understand why it's like the second one doesn't exist when they're both present in the code.

Can anyone tell me what's going on?

  • Hey Christopher,

    As a sanity check I went through and tried to add a blink LED task to the SimleBLEPeripheral project to see if I could get it working. Both apps tasks ran properly (basically the SimpleBLEPeripheral worked and just turned the LED on in the beginning). Here are the changes I made:

    In SimpleBLEPeripheral.c:

    In OSAL_SimpleBLEPeriphal.c:

    These are the same basic steps you describe but maybe these will give you a baseline to look at to understand what is different in your application. One thing I would check would be to make sure you are returning the cleared events variable otherwise OSAL will continue to call process events which would block lower priority tasks.

    -Matt

  • Here's my task array:

    // The order in this table must be identical to the task initialization calls below in osalInitTask.
    const pTaskEventHandlerFn tasksArr[] =
    {
      LL_ProcessEvent,                                                  // task 0
      Hal_ProcessEvent,                                                 // task 1
      HCI_ProcessEvent,                                                 // task 2
      OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),           // task 3
      L2CAP_ProcessEvent,                                               // task 4
      GAP_ProcessEvent,                                                 // task 5
      GATT_ProcessEvent,                                                // task 6
      SM_ProcessEvent,                                                  // task 7
      GAPRole_ProcessEvent,                                             // task 8
      GAPBondMgr_ProcessEvent,                                          // task 9
      GATTServApp_ProcessEvent,                                         // task 10
      BLEDevice_ProcessEvent,                                           // task 11
      LED_ProcessEvent                                                  // task 12
    };
    

    My task initializations:

    void osalInitTasks( void )
    {
      uint8 taskID = 0;
    
      tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
      osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
    
      /* LL Task */
      LL_Init( taskID++ );
    
      /* Hal Task */
      Hal_Init( taskID++ );
    
      /* HCI Task */
      HCI_Init( taskID++ );
    
      /* Callback Timer Tasks */
      osal_CbTimerInit( taskID );
      taskID += OSAL_CBTIMER_NUM_TASKS;
    
      /* L2CAP Task */
      L2CAP_Init( taskID++ );
    
      /* GAP Task */
      GAP_Init( taskID++ );
    
      /* GATT Task */
      GATT_Init( taskID++ );
    
      /* SM Task */
      SM_Init( taskID++ );
    
      /* Profiles */
      GAPRole_Init( taskID++ );
      GAPBondMgr_Init( taskID++ );
    
      GATTServApp_Init( taskID++ );
    
      /* Application */
      BLEDevice_Init( taskID );
      LED_Init( taskID );
    }
    

    The device init function:

    void BLEDevice_Init( uint8 task_id )
    {
      BLEDevice_TaskID = task_id;
    
      bunch of BLE setup here
      
      // Setup a delayed profile startup
      osal_set_event( BLEDevice_TaskID, START_DEVICE_EVT );
    }
    

    The device task event handler:

    uint16 BLEDevice_ProcessEvent( uint8 task_id, uint16 events )
    {
    
      VOID task_id; // OSAL required parameter that isn't used in this function
    
      if ( events & SYS_EVENT_MSG )
      {
        uint8 *pMsg;
    
        if ( (pMsg = osal_msg_receive( BLEDevice_TaskID )) != NULL )
        {
          BLEDevice_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
    
          // Release the OSAL message
          VOID osal_msg_deallocate( pMsg );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & START_DEVICE_EVT )
      {
        // Start the Device
        VOID GAPRole_StartDevice( &BLEDevice_DeviceCBs );
    
       // Start Bond Manager
        VOID GAPBondMgr_Register( &BLEDevice_BondMgrCBs );
    
        uint8 advert = TRUE;
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advert );
        return ( events ^ START_DEVICE_EVT );
      }
    
      // Discard unknown events
      return 0;
    }
    

    The LED init:

    void LED_Init( uint8 task_id )
    {
      LED_TaskID = task_id;
      osal_set_event( LED_TaskID, LED_CYCLE_EVT );
    }
    

    And finally the LED event processor:

    uint16 LED_ProcessEvent( uint8 task_id, uint16 events )
    {
    
      VOID task_id; // OSAL required parameter that isn't used in this function
      
      static uint8 led_cycle_state = 0;
    
      if ( events & SYS_EVENT_MSG )
      {
        uint8 *pMsg;
    
        if ( (pMsg = osal_msg_receive( LED_TaskID )) != NULL )
        {
          LED_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
    
          // Release the OSAL message
          VOID osal_msg_deallocate( pMsg );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & LED_CLEAR_EVT )
      {
        ClearLEDs();
        return ( events ^ LED_CLEAR_EVT );
      }
    
      if ( events & LED_CYCLE_EVT )
      {
        switch ( led_cycle_state )
        {
          case 0:
            ClearLEDs();
            SetLED(RED_LED,ON);
            break;
          case 1:
            ClearLEDs();
            SetLED(YELLOW_LED,ON);
            break;
          case 2:
            ClearLEDs();
            SetLED(GREEN_LED,ON);
            break;
        }
        led_cycle_state++;
        if (led_cycle_state > 2)
          led_cycle_state = 0;      
        if (led_cycle_state)
          osal_start_timerEx( LED_TaskID, LED_CYCLE_EVT, LED_CYCLE_EVT_PERIOD );
        else
          osal_start_timerEx( LED_TaskID, LED_CLEAR_EVT, LED_CYCLE_EVT_PERIOD );
        return ( events ^ LED_CYCLE_EVT );
      }
    
      // Discard unknown events
      return 0;
    }
    

    If I keep the task array in that order, START_DEVICE_EVT occurs and the LED_CYCLE_EVT never happens.  If I switch the order of BLEDevice_ProcessEvent andLED_ProcessEvent in tasksArr[], and their init functions in osalInitTasks, then the LED_CYCLE_EVT occurs, but START_DEVICE_EVT never happens.

  • In osalInitTasks() when you write:

      BLEDevice_Init( taskID );
      LED_Init( taskID );

    You are defining your task IDs for both app tasks to be the same. When you call a set event for either BLEDevice_TaskID or LED_TaskID it's going to create an event with an ID corresponding to the same position in the function pointer array tasksArr. That is why no matter when you switched them it was only calling events for the first function pointer in the list.

    Try changing the first init call to BLEDevice_Init( taskID++ ); this way your taskID variables won't be the same and see if that fixes things.

    -Matt

  • Wow.  Yeah.  That was it.  Can't believe I missed that.  I realized it before the end of your first sentence.  Thank you.