Skip to content

Commit 6bf9ec7

Browse files
committed
espressif/common-hal/_bleio/Adapter.c: use busy-waiting, to allow background tasks to run
1 parent 1019e91 commit 6bf9ec7

File tree

4 files changed

+51
-28
lines changed

4 files changed

+51
-28
lines changed

locale/circuitpython.pot

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2219,8 +2219,9 @@ msgstr ""
22192219
msgid "Unsupported hash algorithm"
22202220
msgstr ""
22212221

2222+
#: ports/espressif/common-hal/_bleio/Adapter.c
22222223
#: ports/espressif/common-hal/dualbank/__init__.c
2223-
msgid "Update Failed"
2224+
msgid "Update failed"
22242225
msgstr ""
22252226

22262227
#: ports/espressif/common-hal/_bleio/Characteristic.c

ports/espressif/common-hal/_bleio/Adapter.c

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "shared-bindings/_bleio/Connection.h"
2525
#include "shared-bindings/_bleio/ScanEntry.h"
2626
#include "shared-bindings/time/__init__.h"
27+
#include "shared/runtime/interrupt_char.h"
2728

2829
#include "controller/ble_ll_adv.h"
2930
#include "nimble/hci_common.h"
@@ -47,22 +48,23 @@
4748
#include "shared-module/os/__init__.h"
4849
#endif
4950

50-
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
51+
// Status variables used while busy-waiting for events.
52+
static volatile bool _nimble_sync;
53+
static volatile int _connection_status;
5154

52-
bool ble_active = false;
55+
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
5356

5457
static void nimble_host_task(void *param) {
5558
nimble_port_run();
5659
nimble_port_freertos_deinit();
5760
}
5861

59-
static TaskHandle_t cp_task = NULL;
6062

6163
static void _on_sync(void) {
6264
int rc = ble_hs_util_ensure_addr(false);
6365
assert(rc == 0);
6466

65-
xTaskNotifyGive(cp_task);
67+
_nimble_sync = true;
6668
}
6769

6870
// All examples have this. It'd make sense in a header.
@@ -133,15 +135,26 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
133135

134136
ble_store_config_init();
135137

136-
cp_task = xTaskGetCurrentTaskHandle();
137-
138+
_nimble_sync = false;
138139
nimble_port_freertos_init(nimble_host_task);
139-
// Wait for sync.
140-
ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(200));
140+
// Wait for sync from nimble task.
141+
const uint64_t timeout_time_ms = common_hal_time_monotonic_ms() + 200;
142+
while (!_nimble_sync && (common_hal_time_monotonic_ms() < timeout_time_ms)) {
143+
RUN_BACKGROUND_TASKS;
144+
if (mp_hal_is_interrupted()) {
145+
// Return prematurely. Then the interrupt will be raised.
146+
return;
147+
}
148+
}
149+
150+
if (!_nimble_sync) {
151+
mp_raise_RuntimeError(MP_ERROR_TEXT("Update failed"));
152+
}
141153
} else {
142154
int ret = nimble_port_stop();
143-
while (xTaskGetHandle("nimble_host") != NULL) {
144-
vTaskDelay(pdMS_TO_TICKS(2));
155+
while (xTaskGetHandle("nimble_host") != NULL && !mp_hal_is_interrupted()) {
156+
RUN_BACKGROUND_TASKS;
157+
common_hal_time_delay_ms(2);
145158
}
146159
if (ret == 0) {
147160
nimble_port_deinit();
@@ -309,15 +322,16 @@ static int _mtu_reply(uint16_t conn_handle,
309322
if (error->status == 0) {
310323
connection->mtu = mtu;
311324
}
312-
xTaskNotify(cp_task, conn_handle, eSetValueWithOverwrite);
325+
// Set status var to connection handle to report that connection is now established.
326+
// Another routine is waiting for this.
327+
_connection_status = conn_handle;
313328
return 0;
314329
}
315330

316331
static void _new_connection(uint16_t conn_handle) {
317332
// Set the tx_power for the connection higher than the advertisement.
318333
esp_ble_tx_power_set(conn_handle, ESP_PWR_LVL_N0);
319334

320-
321335
// Find an empty connection. One should always be available because the SD has the same
322336
// total connection limit.
323337
bleio_connection_internal_t *connection = NULL;
@@ -353,13 +367,14 @@ static int _connect_event(struct ble_gap_event *event, void *self_in) {
353367
switch (event->type) {
354368
case BLE_GAP_EVENT_CONNECT:
355369
if (event->connect.status == 0) {
356-
// This triggers an MTU exchange. Its reply will unblock CP.
370+
// This triggers an MTU exchange. Its reply will exit the loop waiting for a connection.
357371
_new_connection(event->connect.conn_handle);
358372
// Set connections objs back to NULL since we have a new
359373
// connection and need a new tuple.
360374
self->connection_objs = NULL;
361375
} else {
362-
xTaskNotify(cp_task, -event->connect.status, eSetValueWithOverwrite);
376+
// The loop waiting for the connection to be comnpleted will stop when _connection_status changes.
377+
_connection_status = -event->connect.status;
363378
}
364379
break;
365380

@@ -397,24 +412,31 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
397412
ble_addr_t addr;
398413
_convert_address(address, &addr);
399414

400-
cp_task = xTaskGetCurrentTaskHandle();
401-
// Make sure we don't have a pending notification from a previous time. This
402-
// can happen if a previous wait timed out before the notification was given.
403-
xTaskNotifyStateClear(cp_task);
415+
const int timeout_ms = SEC_TO_UNITS(timeout, UNIT_1_MS) + 0.5f;
404416
CHECK_NIMBLE_ERROR(
405417
ble_gap_connect(own_addr_type, &addr,
406-
SEC_TO_UNITS(timeout, UNIT_1_MS) + 0.5f,
418+
timeout_ms,
407419
&conn_params,
408420
_connect_event, self));
409421

410-
int error_code;
411422
// Wait an extra 50 ms to give the connect method the opportunity to time out.
412-
CHECK_NOTIFY(xTaskNotifyWait(0, 0, (uint32_t *)&error_code, pdMS_TO_TICKS(timeout * 1000 + 50)));
423+
424+
const uint64_t timeout_time_ms = common_hal_time_monotonic_ms() + timeout_ms;
425+
// _connection_status gets set to either a positive connection handle or a negative error code.
426+
_connection_status = BLEIO_HANDLE_INVALID;
427+
while (_connection_status == BLEIO_HANDLE_INVALID && (common_hal_time_monotonic_ms() < timeout_time_ms)) {
428+
RUN_BACKGROUND_TASKS;
429+
if (mp_hal_is_interrupted()) {
430+
// Return prematurely. Then the interrupt exception will be raised.
431+
return mp_const_none;
432+
}
433+
}
434+
413435
// Negative values are error codes, connection handle otherwise.
414-
if (error_code < 0) {
415-
CHECK_BLE_ERROR(-error_code);
436+
if (_connection_status < 0) {
437+
CHECK_BLE_ERROR(-_connection_status);
416438
}
417-
uint16_t conn_handle = error_code;
439+
const uint16_t conn_handle = _connection_status;
418440

419441
// TODO: If we have keys, then try and encrypt the connection.
420442

ports/espressif/common-hal/_bleio/Connection.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ static void _start_discovery_timeout(void) {
191191
}
192192

193193
static int _wait_for_discovery_step_done(void) {
194-
while ((_last_discovery_status == 0) &&
195-
(common_hal_time_monotonic_ms() < _discovery_start_time + DISCOVERY_TIMEOUT_MS)) {
194+
const uint64_t timeout_time_ms = _discovery_start_time + DISCOVERY_TIMEOUT_MS;
195+
while ((_last_discovery_status == 0) && (common_hal_time_monotonic_ms() < timeout_time_ms)) {
196196
RUN_BACKGROUND_TASKS;
197197
if (mp_hal_is_interrupted()) {
198198
// Return prematurely. Then the interrupt will be raised.

ports/espressif/common-hal/dualbank/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void dualbank_reset(void) {
2727

2828
static void __attribute__((noreturn)) task_fatal_error(void) {
2929
ESP_LOGE(TAG, "Exiting task due to fatal error...");
30-
mp_raise_RuntimeError(MP_ERROR_TEXT("Update Failed"));
30+
mp_raise_RuntimeError(MP_ERROR_TEXT("Update failed"));
3131
}
3232

3333
void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t offset) {

0 commit comments

Comments
 (0)