Service event handler: IRQ callback or FreeRTOS task?

I want to fully understand the use of RTOS in conjunction with the stack.

As an example, I took an example ble_app_hrs_freertos (SDK v15.0).

Add a service, for example, BAS.

Event handler for this service:

void ble_bas_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{ 
    ... 
}

When start the project, a task is created to handle the SD events:

void SD_EVT_IRQHandler(void)
{
     BaseType_t xYieldRequired;

     xYieldRequired = xTaskResumeFromISR( m_softdevice_task );

     if( xYieldRequired == pdTRUE )
     {
         portYIELD_FROM_ISR(xYieldRequired);
     }
}


/* This function gets events from the SoftDevice and processes them. */
static void softdevice_task(void * pvParameter)
{
    NRF_LOG_DEBUG("Enter softdevice_task.");

    if (m_task_hook != NULL)
    {
        m_task_hook(pvParameter);
    }

    while (true)
    {
        nrf_sdh_evts_poll(); // Let the handlers run first, in case the EVENT occured before creating this task.
        vTaskSuspend(NULL);
    }
}


void nrf_sdh_freertos_init(nrf_sdh_freertos_task_hook_t hook_fn, void * p_context)
{
    NRF_LOG_DEBUG("Creating a SoftDevice task.");

    m_task_hook = hook_fn;

    BaseType_t xReturned = xTaskCreate(softdevice_task,
                                       "BLE",
                                       NRF_BLE_FREERTOS_SDH_TASK_STACK,
                                       p_context,
                                       2,
                                       &m_softdevice_task);
    if (xReturned != pdPASS)
    {
        NRF_LOG_ERROR("SoftDevice task not created.");
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }
}

So, question:


1. Handlers for services are called from this task or earlier, from an interrupt?

2. Event handler for service it's IRQ callback or RTOS callback (callback from softdevice_task)?

Thanks,

Parents
  • Very nice questions CheMax,

    1) You could have directly handled all the services from this IRQ like a non-RTOS standalone application, then you know, it doesn't look neat to process so much in the interrupts when we can do that better in the RTOS tasks. To answer you question, services are handled in the task. 

    2) You have pasted the code snippet exactly where this happens. The event handling is done in the task that suspends itself until the SWI interrupt resumes it to process incoming events.

Reply
  • Thank ,

    I understand that if I want to pass the event of enabling a notification for this service to the task I need, I should use the api function for interrupts (with a suffix FromIsr).

    For example, this:

    static void ads_cds_evt(cds_svc_t *cds_service, cds_svc_evt_t *p_evt)
    {
      NRF_LOG_INFO("Incoming event: %d", p_evt->evt_type);
      switch(p_evt->evt_type)
      {
        case CDS_SVC_EVT_NOTIFICATION_ENABLED: 
         xEventGroupSetBitsFromISR(eAdsFlags, eAdsEvtNtfEnable, NULL);
        break;
        
        ...
      }
    }

    Is not it?

Children