-
Notifications
You must be signed in to change notification settings - Fork 463
Description
In the following controller code:
mynewt-nimble/nimble/controller/src/ble_ll_rfmgmt.c
Lines 285 to 300 in 7b14eab
| void | |
| ble_ll_rfmgmt_release(void) | |
| { | |
| struct ble_ll_rfmgmt_data *rfmgmt = &g_ble_ll_rfmgmt_data; | |
| os_sr_t sr; | |
| OS_ENTER_CRITICAL(sr); | |
| ble_ll_event_remove(&rfmgmt->release_ev); | |
| if (g_ble_ll_rfmgmt_data.state != RFMGMT_STATE_OFF) { | |
| ble_ll_event_add(&rfmgmt->release_ev); | |
| } | |
| OS_EXIT_CRITICAL(sr); | |
| } |
ble_ll_event_add is called while inside a critical section. This calls:
mynewt-nimble/nimble/controller/src/ble_ll.c
Lines 1426 to 1430 in 7b14eab
| void | |
| ble_ll_event_add(struct ble_npl_event *ev) | |
| { | |
| ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev); | |
| } |
In case of FreeRTOS,
mynewt-nimble/porting/npl/freertos/include/nimble/nimble_npl_os.h
Lines 100 to 104 in 7b14eab
| static inline void | |
| ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev) | |
| { | |
| npl_freertos_eventq_put(evq, ev); | |
| } |
mynewt-nimble/porting/npl/freertos/src/npl_os_freertos.c
Lines 60 to 80 in 7b14eab
| void | |
| npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev) | |
| { | |
| BaseType_t woken; | |
| BaseType_t ret; | |
| if (ev->queued) { | |
| return; | |
| } | |
| ev->queued = true; | |
| if (in_isr()) { | |
| ret = xQueueSendToBackFromISR(evq->q, &ev, &woken); | |
| portYIELD_FROM_ISR(woken); | |
| } else { | |
| ret = xQueueSendToBack(evq->q, &ev, portMAX_DELAY); | |
| } | |
| assert(ret == pdPASS); | |
| } |
As you can see above, xQueueSendToBack is called with portMAX_DELAY. I guess at the very least, we should add a zero delay if we're within a critical section. Also, see https://forums.freertos.org/t/critical-sections-freertos-api-calls/17352.