Skip to content

Commit 01b9f23

Browse files
committed
pybricks: Unify deinit by queueing noop task.
1 parent be6304e commit 01b9f23

File tree

9 files changed

+60
-16
lines changed

9 files changed

+60
-16
lines changed

lib/pbio/drv/bluetooth/bluetooth_btstack.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,16 @@ const char *pbdrv_bluetooth_get_fw_version(void) {
629629
return "v1.4";
630630
}
631631

632+
static PT_THREAD(noop_task(struct pt *pt, pbio_task_t *task)) {
633+
PT_BEGIN(pt);
634+
task->status = PBIO_SUCCESS;
635+
PT_END(pt);
636+
}
637+
638+
void pbdrv_bluetooth_queue_noop(pbio_task_t *task) {
639+
start_task(task, noop_task, NULL);
640+
}
641+
632642
static void init_advertising_data(void) {
633643
bd_addr_t null_addr = { };
634644
gap_advertisements_set_params(0x30, 0x30, PBDRV_BLUETOOTH_AD_TYPE_ADV_IND, 0x00, null_addr, 0x07, 0x00);

lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,16 @@ const char *pbdrv_bluetooth_get_fw_version(void) {
259259
return pbdrv_bluetooth_fw_version;
260260
}
261261

262+
static PT_THREAD(noop_task(struct pt *pt, pbio_task_t *task)) {
263+
PT_BEGIN(pt);
264+
task->status = PBIO_SUCCESS;
265+
PT_END(pt);
266+
}
267+
268+
void pbdrv_bluetooth_queue_noop(pbio_task_t *task) {
269+
start_task(task, noop_task, NULL);
270+
}
271+
262272
/**
263273
* Sets advertising data and enables advertisements.
264274
*/

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,16 @@ const char *pbdrv_bluetooth_get_fw_version(void) {
294294
return pbdrv_bluetooth_fw_version;
295295
}
296296

297+
static PT_THREAD(noop_task(struct pt *pt, pbio_task_t *task)) {
298+
PT_BEGIN(pt);
299+
task->status = PBIO_SUCCESS;
300+
PT_END(pt);
301+
}
302+
303+
void pbdrv_bluetooth_queue_noop(pbio_task_t *task) {
304+
start_task(task, noop_task, NULL);
305+
}
306+
297307
/**
298308
* Sets advertising data and enables advertisements.
299309
*/

lib/pbio/include/pbdrv/bluetooth.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@ const char *pbdrv_bluetooth_get_hub_name(void);
240240
*/
241241
const char *pbdrv_bluetooth_get_fw_version(void);
242242

243+
/**
244+
* Queues a task that does nothing. When this task completes, all tasks
245+
* before it will have finished or failed.
246+
*/
247+
void pbdrv_bluetooth_queue_noop(pbio_task_t *task);
248+
243249
/**
244250
* Starts the advertising process, including configuring advertisements and
245251
* telling the Bluetooth chip to start advertising. Advertising should
@@ -394,6 +400,9 @@ static inline const char *pbdrv_bluetooth_get_fw_version(void) {
394400
return "";
395401
}
396402

403+
static inline void pbdrv_bluetooth_queue_noop(pbio_task_t *task) {
404+
}
405+
397406
static inline void pbdrv_bluetooth_start_advertising(void) {
398407
}
399408

pybricks/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void pb_package_pybricks_deinit(void);
3131

3232
#if PYBRICKS_PY_COMMON_BLE
3333
mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channels_in);
34-
void pb_type_BLE_cleanup(void);
34+
void pb_type_ble_start_cleanup(void);
3535
#endif
3636

3737
#if PYBRICKS_PY_COMMON_CHARGER

pybricks/common/pb_type_ble.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -502,15 +502,15 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(pb_type_BLE,
502502
/**
503503
* Creates a new instance of the BLE class.
504504
*
505-
* Do not call this function more than once unless pb_type_BLE_cleanup() is called first.
505+
* Do not call this function more than once unless pb_type_ble_start_cleanup() is called first.
506506
*
507507
* @param [in] broadcast_channel_in (int) The channel number to use for broadcasting.
508508
* @param [in] observe_channels_in (list[int]) A list of channels numbers to observe.
509509
* @returns A newly allocated object.
510510
* @throws ValueError If either parameter contains an out of range channel number.
511511
*/
512512
mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channels_in) {
513-
// making the assumption that this is only called once before each pb_type_BLE_cleanup()
513+
// making the assumption that this is only called once before each pb_type_ble_start_cleanup()
514514
assert(observed_data == NULL);
515515

516516
mp_int_t broadcast_channel = mp_obj_get_int(broadcast_channel_in);
@@ -558,17 +558,14 @@ mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channel
558558
return MP_OBJ_FROM_PTR(self);
559559
}
560560

561-
void pb_type_BLE_cleanup(void) {
561+
void pb_type_ble_start_cleanup(void) {
562562
static pbio_task_t stop_broadcasting_task;
563563
static pbio_task_t stop_observing_task;
564564
pbdrv_bluetooth_stop_broadcasting(&stop_broadcasting_task);
565565
pbdrv_bluetooth_stop_observing(&stop_observing_task);
566566
observed_data = NULL;
567567
num_observed_data = 0;
568-
569-
while (stop_broadcasting_task.status == PBIO_ERROR_AGAIN || stop_observing_task.status == PBIO_ERROR_AGAIN) {
570-
MICROPY_VM_HOOK_LOOP
571-
}
568+
// Tasks awaited in pybricks de-init.
572569
}
573570

574571
#endif // PYBRICKS_PY_COMMON_BLE

pybricks/iodevices/pb_type_iodevices_lwp3device.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,10 @@ STATIC void pb_lwp3device_configure_remote(void) {
321321
}
322322
}
323323

324-
void pb_type_Remote_cleanup(void) {
324+
void pb_type_lwp3device_start_cleanup(void) {
325325
static pbio_task_t disconnect_task;
326326
pbdrv_bluetooth_peripheral_disconnect(&disconnect_task);
327-
328-
while (disconnect_task.status == PBIO_ERROR_AGAIN) {
329-
MICROPY_EVENT_POLL_HOOK
330-
}
327+
// Task awaited in pybricks de-init.
331328
}
332329

333330
mp_obj_t pb_type_remote_button_pressed(void) {

pybricks/pupdevices.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extern const mp_obj_type_t pb_type_pupdevices_TiltSensor;
2727
extern const mp_obj_type_t pb_type_pupdevices_UltrasonicSensor;
2828

2929
pb_type_device_obj_base_t *pupdevices_ColorDistanceSensor__get_device(mp_obj_t obj);
30-
void pb_type_Remote_cleanup(void);
30+
void pb_type_lwp3device_start_cleanup(void);
3131

3232
#endif // PYBRICKS_PY_PUPDEVICES
3333

pybricks/pybricks.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "py/objtuple.h"
1111
#include "py/runtime.h"
1212

13+
#include <pbdrv/bluetooth.h>
1314
#include <pbio/version.h>
1415

1516
#include <pybricks/common.h>
@@ -133,10 +134,20 @@ void pb_package_pybricks_init(bool import_all) {
133134
// REVISIT: move these to object finalizers if we enable finalizers in the GC
134135
void pb_package_pybricks_deinit(void) {
135136
#if PYBRICKS_PY_COMMON_BLE
136-
pb_type_BLE_cleanup();
137+
pb_type_ble_start_cleanup();
137138
#endif
138139
// Disconnect from remote.
139140
#if PYBRICKS_PY_PUPDEVICES
140-
pb_type_Remote_cleanup();
141+
pb_type_lwp3device_start_cleanup();
141142
#endif // PYBRICKS_PY_PUPDEVICES
143+
144+
#if PYBRICKS_PY_COMMON_BLE && PYBRICKS_PY_PUPDEVICES
145+
// By queueing and awaiting a task that does nothing, we know that all user
146+
// tasks and deinit tasks have completed.
147+
static pbio_task_t noop_task;
148+
pbdrv_bluetooth_queue_noop(&noop_task);
149+
while (noop_task.status == PBIO_ERROR_AGAIN) {
150+
MICROPY_VM_HOOK_LOOP
151+
}
152+
#endif
142153
}

0 commit comments

Comments
 (0)