Skip to content

Conversation

@laurensvalk
Copy link
Member

@laurensvalk laurensvalk commented Sep 23, 2025

This is one of the last steps in the major overhaul in the past year concerning the UI, HMI, Bluetooth, async, and program start/stop. The long term goals here were to generalize the host interface to facilitate connectivity other than BLE such as USB. This has been added to Prime/Essential Hub, and is key to enabling EV3 and NXT support.

pbio/sys/host: Schedule status update.
pbio/drv/usb: Hook up receive handler and status.

Before we do it for Bluetooth in the next commit, let's start with USB. This removes the pbio/sys dependency from the USB drivers. Instead we schedule the status and set a callback for calling pbsys/command. Also fixes a minor status timer issue in the EV3 USB driver.

            prev_status_flags = new_status_flags;
            if (new_status_flags != prev_status_flags) {
                // this would never run

pbio/drv/bluetooth: Full overhaul.

This moves the remaining functionality of pbsys/bluetooth to pbdrv/bluetooth to be consistent with the USB drivers. This way, bluetooth and usb don't have to depend on the system status and runtime. This drops one level of abstraction, so that printing with stdout no longer goes through two cascaded processess/

This replaces scheduling arbitrary Bluetooth tasks with dedicated scheduling of stdout/status/peripheral/scan task categories. This allows all categories to be simultaneously scheduled, while also immediately copying configuration data and raising if a conflicting operation is already in progress.

For example, you can now set the remote bluetooth light or broadcasting data without clashes. When the operation is available for scheduling, data is copied right away so we avoid issues with using MicroPython data after free, simplifying the module code.

The pbio_task queue is replaced with a common process loop that will go over the above task categories and execute it if something was scheduled. This also gives us deterministic control over the order of operations. We are also no longer killing the Bluetooth SPI process from pbsys, potentially in the middle of something.

Procedures such as scan and connect and disconnect are now also awaitable, so a dedicated connect() method could now be added trivially.

Throughput of stdout is improved slightly for short messages as there is no longer a double-buffer in pbsys that would block if a send operation was already queued. Data can now be queued whenever there is room in the buffer, and the main Bluetooth process will drain as much as it can the next time it gets around the loop of Bluetooth tasks.

While we are doing all this, replace the Contiki protothreads with pbio/os protothreads.


Work in progress

  • The Bluetooth tests still need upgrading, so the CI will fail for now.
  • Add pbdrv_bluetooth_deinit. We used to simply kill the Bluetooth process, but we can now wait for pending tasks and shut down gracefully.
  • Test advertising and scanning. This code has been updated but not tested yet.

Future consideration
With the major overhaul out of the way, we could consider doing the following in future releases.

  • Have two peripherals (probably only on the BTstack hubs)
  • Keep the peripheral connected after the program ends, primarily useful for Xbox which otherwise completely turns off
  • Don't reset Bluetooth after a program run if no new connection was made, so we don't populate Pybricks Code with invalid devices (longstanding bug in the old driver)
  • Expose an awaitable connect method on the Remote, which has been asked for a few times.

This is not yet implemented for the driver side.

At the moment, the usb drivers poll the status for partial changes, and the bluetooth status is managed by pbsys/bluetooth, which is to be removed.
@coveralls
Copy link

Coverage Status

coverage: 59.604% (+0.3%) from 59.255%
when pulling d71fdfa on btrework
into 0f065bb on master.

This moves the remaining functionality of pbsys/bluetooth to pbdrv/bluetooth to be consistent with the USB drivers. This way, bluetooth and usb don't have to depend on the system status and runtime. This drops one level of abstraction, so that printing with stdout no longer goes through two cascaded processess/

This replaces scheduling arbitrary Bluetooth tasks with dedicated scheduling of stdout/status/peripheral/scan task categories. This allows all categories to be simultaneously scheduled, while also immediately copying configuration data and raising if a conflicting operation is already in progress.

For example, you can now set the remote bluetooth light or broadcasting data without clashes. When the operation is available for scheduling, data is copied right away so we avoid issues with using MicroPython data after free, simplifying the module code.

The pbio_task queue is replaced with a single loop that will go over the above task categories and execute it if something was scheduled. This also gives us deterministic control over the order of operations.

Procedures such as ascan and connect and disconnect are now also awaitable, so a dedicated connect() method could now be added trivially.

Throughput of stdout is improved slightly for short messages as there is no longer a double-buffer in pbsys that would block if a send operation was already queued. Data can now be queued whenever there is room in the buffer, and the main Bluetooth process will drain as much as it can the next time it gets around the loop of Bluetooth tasks.

While we are doing all this, replace the Contiki protothreads with pbio/os protothreads.
Otherwise clean always led to errors such as

../drv/bluetooth/bluetooth_btstack.c:25:10: fatal error: genhdr/pybricks_service.h: No such file or directory
   25 | #include "genhdr/pybricks_service.h"
@laurensvalk
Copy link
Member Author

Splitting this into a few separate PRs for future reference.

@laurensvalk laurensvalk merged commit 0b30a63 into master Sep 29, 2025
35 of 41 checks passed
@laurensvalk laurensvalk deleted the btrework branch September 29, 2025 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants