Re: nRF52833DK, s113 and nRF5_SDK v16.0.0
It appears that nrf_sdh_freertos.c needs to be modified to support JUST_WORKS and LESC because the softdevice_task() in nrf_sdh_freertos.c never calls nrf_lesc_request_handler() causing attempts to pair and bound to timeout..
After exchanging emails with Daniel Veilleux, we came up the following necessary changes to nrf_sdh_freertos.c:
Two tasks:
- The existing softdevice_task() running at a high priority
- A new lesc_request_task() running at a low priority
The lesc_request_task() is woken by the softdevice_task() to call nrf_ble_lesc_request_handler(), but at a lower priority than the softdevice_task(). Here's an example:
- Softdevice_task() and lesc_request_task() are blocked
- SD_EVT_IRQHandler() sends a notification to softdevice_task()
- Softdevice_task()
- Sends a notification to lesc_tequest_task()
- Calls nrf_sdh_evts_poll()
- Blocks on the next SD_EVT_IRQHandler() notification
- lesc_request_task()
- Calls nrf_ble_lesc_request_handler()
- Blocks on the next Softdevice_task()
- Repeat...
Here's the changes I made to the app_ble_hrs_freertos example to test:
// main.c
...
static void gap_params_init(void) {
ret_code_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&sec_mode);
...
}
...
static void services_init(void) {
...
// Here the sec level for the Heart Rate Service can be changed/increased.
hrs_init.hrm_cccd_wr_sec = SEC_JUST_WORKS;
hrs_init.bsl_rd_sec = SEC_JUST_WORKS;
...
// Here the sec level for the Battery Service can be changed/increased.
bas_init.bl_rd_sec = SEC_JUST_WORKS;
bas_init.bl_cccd_wr_sec = SEC_JUST_WORKS;
bas_init.bl_report_rd_sec = SEC_JUST_WORKS;
...
}
// nrf_sdh_freertos.c
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, incase the EVENT occured before creating this task */
xTaskNotifyGive(m_lesc_task); /* wake the LESC task */
(void) ulTaskNotifyTake(pdTRUE, /* Clear the notification value before exiting (equivalent to the binary semaphore). */
portMAX_DELAY); /* Block indefinitely (INCLUDE_vTaskSuspend has to be enabled).*/
}
}
static void lesc_task(void* pvParameter) {
NRF_LOG_DEBUG("Enter lesc_task.");
for(;;) {
(void) ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
NRF_LOG_INFO("calling nrf_ble_lesc_request_handler()...")
nrf_ble_lesc_request_handler();
}
}
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( lesc_task,
"LESC",
NRF_BLE_FREERTOS_LESC_TASK_STACK,
p_context,
tskIDLE_PRIORITY+1,
&m_lesc_task);
if (xReturned != pdPASS) {
NRF_LOG_ERROR("SoftDevice LESC task not created!");
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
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);
}
}
This seems to work correctly, but I'd like to have it officially blessed by Nordic before I place it production code.