Skip to content

Commit 6d4ba31

Browse files
committed
unix/mpbthciport: Use mp_thread_run_on_mp_thread.
This replaces the previous code that used the scheduler (via thread) to run the BLE host stack. Now the host stack can run directly on the thread, and then modbluetooth.c will use mp_thread_run_on_mp_thread to run the Python-level callbacks on a MicroPython thread as necessary. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
1 parent c19a243 commit 6d4ba31

File tree

2 files changed

+20
-30
lines changed

2 files changed

+20
-30
lines changed

ports/unix/mpbthciport.c

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#error Unix HCI UART requires MICROPY_PY_THREAD
3535
#endif
3636

37+
#if !MICROPY_PY_THREAD_RTOS
38+
#error Unix HCI UART requires MICROPY_PY_THREAD_RTOS
39+
#endif
40+
3741
#include "extmod/modbluetooth.h"
3842
#include "extmod/mpbthci.h"
3943

@@ -59,46 +63,25 @@ STATIC int uart_fd = -1;
5963
// Must be provided by the stack bindings (e.g. mpnimbleport.c or mpbtstackport.c).
6064
extern bool mp_bluetooth_hci_poll(void);
6165

62-
// For synchronous mode, we run all BLE stack code inside a scheduled task.
63-
// This task is scheduled periodically (every 1ms) by a background thread.
64-
65-
// Allows the stack to tell us that we should stop trying to schedule.
66+
// Allows the stack to tell us that we should stop running the hci poll loop.
6667
extern bool mp_bluetooth_hci_active(void);
6768

68-
// Prevent double-enqueuing of the scheduled task.
69-
STATIC volatile bool events_task_is_scheduled = false;
70-
71-
STATIC mp_obj_t run_events_scheduled_task(mp_obj_t none_in) {
72-
(void)none_in;
73-
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
74-
events_task_is_scheduled = false;
75-
MICROPY_END_ATOMIC_SECTION(atomic_state);
76-
mp_bluetooth_hci_poll();
77-
return mp_const_none;
78-
}
79-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task);
80-
8169
STATIC const useconds_t UART_POLL_INTERVAL_US = 1000;
8270
STATIC pthread_t hci_poll_thread_id;
8371

72+
// We run the host stack periodically (every 1ms) by a background thread.
73+
// Because MICROPY_PY_THREAD_RTOS is enabled, when the host stack tries
74+
// to call into Python, it will use mp_thread_run_on_mp_thread to run
75+
// the callbacks on a Python thread.
8476
STATIC void *hci_poll_thread(void *arg) {
8577
(void)arg;
8678

87-
DEBUG_printf("hci_poll_thread: starting\n");
88-
89-
events_task_is_scheduled = false;
90-
79+
// TODO: Replace with select().
9180
while (mp_bluetooth_hci_active()) {
92-
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
93-
if (!events_task_is_scheduled) {
94-
events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none);
95-
}
96-
MICROPY_END_ATOMIC_SECTION(atomic_state);
81+
mp_bluetooth_hci_poll();
9782
usleep(UART_POLL_INTERVAL_US);
9883
}
9984

100-
DEBUG_printf("hci_poll_thread: stopped\n");
101-
10285
return NULL;
10386
}
10487

ports/unix/mpconfigport.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,24 +218,31 @@ static inline unsigned long mp_random_seed_init(void) {
218218
#include <stdio.h>
219219
#endif
220220

221-
// If threading is enabled, configure the atomic section.
222221
#if MICROPY_PY_THREAD
222+
// If threading is enabled, configure the atomic section.
223223
#define MICROPY_BEGIN_ATOMIC_SECTION() (mp_thread_unix_begin_atomic_section(), 0xffffffff)
224224
#define MICROPY_END_ATOMIC_SECTION(x) (void)x; mp_thread_unix_end_atomic_section()
225+
226+
// Also enable RTOS support (really, OS in this case).
227+
#define MICROPY_PY_THREAD_RTOS (1)
225228
#endif
226229

230+
#include <sched.h>
231+
227232
// In lieu of a WFI(), slow down polling from being a tight loop.
228233
#ifndef MICROPY_EVENT_POLL_HOOK
229234
#define MICROPY_EVENT_POLL_HOOK \
230235
do { \
231236
extern void mp_handle_pending(bool); \
232237
mp_handle_pending(true); \
238+
MP_THREAD_GIL_EXIT(); \
233239
usleep(500); /* equivalent to mp_hal_delay_us(500) */ \
240+
sched_yield(); \
241+
MP_THREAD_GIL_ENTER(); \
234242
} while (0);
235243
#endif
236244

237245
// Configure the implementation of machine.idle().
238-
#include <sched.h>
239246
#define MICROPY_UNIX_MACHINE_IDLE sched_yield();
240247

241248
#ifndef MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy