Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Example ble_app_hrs_freertos of SDK15.2.0 failing FreeRTOS assertion.

Hello Nordic experts,

I am working with nRF5_SDK_15.2.0_9412b96 SDK.

In example nRF5_SDK_15.2.0_9412b96/examples/ble_peripheral/ble_app_hrs_freertos/main.c I have at line № 969 a call to nrf_sdh_freertos_init. This function is that which instantiates the BLE FreeRTOS task, the handle of which is stored in static variable m_softdevice_task defined at line № 57 of file nRF5_SDK_15.2.0_9412b96/components/softdevice/common/nrf_sdh_freertos.c.

As line № 57 of this file, a function SD_EVT_IRQHandler calls the FreeRTOS primitive xTaskResumeFromISR as follows : « xTaskResumeFromISR( m_softdevice_task ) », which requires from the FreeRTOS perspective that « m_softdevice_task != NULL », otherwise assertion « configASSERT( xTaskToResume ); » at line № 1837 of file nRF5_SDK_15.2.0_9412b96/external/freertos/source/tasks.c will fail.

Now, the issue is that form the code in example nRF5_SDK_15.2.0_9412b96/examples/ble_peripheral/ble_app_hrs_freertos/main.c I am afraid that it is possible that SD_EVT_IRQHandler be called before nrf_sdh_freertos_init, which will cause this assertion to be failed.

Could you please confirm or not my analysis ?

If yes could you please provide a fix, my proposal is to call nrf_sdh_freertos_init immediately before callllble_stack_init at line № 953 of file nRF5_SDK_15.2.0_9412b96/examples/ble_peripheral/ble_app_hrs_freertos/main.c.

Parents
  • Hi,

    Very good question.

    First of all, there is a race condition in using xTaskResumeFromISR which should be replaced by notify API as mentioned in this answer.

    You question is still valid after you use the fixed mentioned in the above link.

    That is the reason we use hook_fn in nrf_sdh_freertos_init where we start the radio activity (Advertise or scan) that will be able to generate the first interrupt in SD_EVT_IRQHandler .

    So the m_task_hook function will only be called of softdevice_task has been started. If softdevice_task is not started then no radio activity will occur and hence there is no possibility in triggering SD_EVT_IRQHandler.

  • Hello,

    Thank you for the answer. Your first recommendation — ie hacking the SDK in order to replace xTaskResumeFromISR by vTaskNotifyGiveFromISR was OK for me.

    However for the second recommendation, I got into trouble, which indeed I am the only one to blame. This re-opened some leftover dirty code which I had not done properly by lack of time, and now I cannot postpone this…
    In some other FreeRTOS task I am calling nrf_drv_clock_hfclk_request. I should have used sd_clock_hfclk_request instead as you recommended here. However, for some reason which I must admit I have not investigated, it was somehow working properly in this dirty way — well I should have checked this thouroughly too.

    Anyway, my trouble is now that I need to know whether I need to use nrf_drv_clock_hfclk_request or sd_clock_hfclk_request depending on whether the SoftDevice is initialised or not, which now depends on the order in which the two FreeRTOS tasks are initialized. OK, this is probably something that I can overcome by using some by some atomic flag, or some such stuff.

    I would like to raise however the following question : is that possible to initialise the SoftDevice in a way that the sd_clock_hfclk_request primitive is available — does this primitive need at all that the SoftDevice be initialised in any way, or does it suffice that the SoftDevice .hex be flashed on chip — while the event causing SD_EVT_IRQHandler to be called be not activated ?

  • That is a good question.

    If you look into components\softdevice\s140\headers\nrf_soc.h file, you will see NRF_SOC_SVCS

    enum NRF_SOC_SVCS
    {
    SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
    SD_PPI_CHANNEL_ENABLE_SET,
    SD_PPI_CHANNEL_ENABLE_CLR,
    SD_PPI_CHANNEL_ASSIGN,
    SD_PPI_GROUP_TASK_ENABLE,
    SD_PPI_GROUP_TASK_DISABLE,
    SD_PPI_GROUP_ASSIGN,
    SD_PPI_GROUP_GET,
    SD_FLASH_PAGE_ERASE,
    SD_FLASH_WRITE,
    SD_FLASH_PROTECT,
    SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
    SD_MUTEX_ACQUIRE,
    SD_MUTEX_RELEASE,
    SD_NVIC_ENABLEIRQ,
    SD_NVIC_DISABLEIRQ,
    SD_NVIC_GETPENDINGIRQ,
    SD_NVIC_SETPENDINGIRQ,
    SD_NVIC_CLEARPENDINGIRQ,
    SD_NVIC_SETPRIORITY,
    SD_NVIC_GETPRIORITY,
    SD_NVIC_SYSTEMRESET,
    SD_NVIC_CRITICAL_REGION_ENTER,
    SD_NVIC_CRITICAL_REGION_EXIT,
    SD_RAND_APPLICATION_POOL_CAPACITY,
    SD_RAND_APPLICATION_BYTES_AVAILABLE,
    SD_RAND_APPLICATION_GET_VECTOR,
    SD_POWER_MODE_SET,
    SD_POWER_SYSTEM_OFF,
    SD_POWER_RESET_REASON_GET,
    SD_POWER_RESET_REASON_CLR,
    SD_POWER_POF_ENABLE,
    SD_POWER_POF_THRESHOLD_SET,
    SD_POWER_RAMON_SET,
    SD_POWER_RAMON_CLR,
    SD_POWER_RAMON_GET,
    SD_POWER_GPREGRET_SET,
    SD_POWER_GPREGRET_CLR,
    SD_POWER_GPREGRET_GET,
    SD_POWER_DCDC_MODE_SET,
    SD_APP_EVT_WAIT,
    SD_CLOCK_HFCLK_REQUEST,
    SD_CLOCK_HFCLK_RELEASE,
    SD_CLOCK_HFCLK_IS_RUNNING,
    SD_RADIO_NOTIFICATION_CFG_SET,
    SD_ECB_BLOCK_ENCRYPT,
    SD_RADIO_SESSION_OPEN,
    SD_RADIO_SESSION_CLOSE,
    SD_RADIO_REQUEST,
    SD_EVT_GET,
    SD_TEMP_GET,
    SVC_SOC_LAST
    };

    All the bold svcs are available even if the softdevice is not enabled. Just flashing them to the flash memory is enough for them to work. But the rest (including SOC_SVC_BASE_NOT_AVAILABLE) are only available when the softdevice is enabled.

  • OK, thank you for reply, that will definitely help me to make it.

Reply Children
No Data
Related