New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix NimBLEDevice::init() deadlock problem #584
base: release/1.4
Are you sure you want to change the base?
Conversation
When the priority of NimBLEDevice::init() is greater than (tskIDLE_PRIORITY+1), NimBLEDevice::init() will block NimBLE host task and wait for NimBLE host task infinitely
I've never heard of or experienced this issue before, do you have any examples where this can be reproduced? |
Hello @h2zero, Here is the minimum reproducible example (it tested it with bc333cc), #include <NimBLEDevice.h>
void InitNimbleTask(void* args)
{
Serial.println("Initializing NimBLEDevice");
NimBLEDevice::init("NimBLE-Arduino");
Serial.println("Initialized");
NimBLEDevice::startAdvertising();
vTaskDelete(NULL);
}
void setup() {
Serial.begin(115200);
// host_task has priority (configMAX_PRIORITIES - 4)
const uint32_t priority = (configMAX_PRIORITIES - 3);
// host_task is pinned at core 0
xTaskCreatePinnedToCore(InitNimbleTask, "InitNimbleTask", 8192, NULL, priority, NULL, 0);
}
void loop() {
} As stated in the PR, I think it's because
When NimBLEDevice::init() has priority greater than (configMAX_PRIORITIES - 4) , the host_task starves.
And if we set the priority of Some even trickier situation,
|
Due to the nature of the BLE stack I would highly recommend using a task priority for the application that is less than the host task. Is there a specific purpose to have your application run at a higher priority than the host task? |
Actually, I don't really need the priority of application be higher, I just accidentally found this problem when I set different task priority for my application. |
@CW-B-W That is a great explanation, thank you for this. I have tested your example and propose a different fix. Instead of the semaphore, could you just replace the |
NimBLEDevice::host_task()
has priority(configMAX_PRIORITIES - 4)
, which is defined atNimBLE-Arduino/src/nimble/porting/npl/freertos/src/nimble_port_freertos.c
Lines 60 to 61 in bc333cc
When the priority of
NimBLEDevice::init()
is greater than(configMAX_PRIORITIES - 4)
,NimBLEDevice::init()
will blockNimBLEDevice::host_task()
but still wait forNimBLEDevice::host_task()
infinitely (waiting form_synced
to be set), resulting in the deadlock betweenNimBLEDevice::init()
andNimBLEDevice::host_task()
.This is caused by this while loop
NimBLE-Arduino/src/NimBLEDevice.cpp
Lines 909 to 911 in bc333cc
When the priority of
NimBLEDevice::init()
is greater thanNimBLEDevice::host_task()
, it cannot yield and letNimBLEDevice::host_task()
be executed.Using a binary semaphore can resolve this problem.