Skip to content

Conversation

@dlech
Copy link
Member

@dlech dlech commented Jul 19, 2025

The less ambitious alternative to #332.

This time, instead of duplicating a bunch of stuff, we finish the TODO to move the stdin buffer out of pbsys_bluetooth and into pbsys_host. Then we can hook up the USB stdin to this as well.

It is possible for print functions to raise an exception, so we need to
catch this when printing a final exception since the nlr stack is empty
at that point and would otherwise cause a crash.
@dlech dlech mentioned this pull request Jul 19, 2025
dlech added 4 commits July 18, 2025 23:50
Move the stdin buffer from pbsys/bluetooth to pbsys/host so that it can
be used by other host interfaces, such as USB stdio. All connections
will share the same stdin buffer.

All function names are renames from "rx" to "stdin" to reflect the
current usage. The "rx" naming was a holdover from when this was
originally only used for Bluetooth RX via the Nordic UART Service.

A new PBSYS_CONFIG_HOST_STDIN_BUF_SIZE option is introduced to set a
platform-specific buffer size. Bluetooth-only hubs continue to use the
same size that was used in pbsys/bluetooth. Hubs with USB are set to
64 bytes to match the USB endpoint size.
Fix issue with pbsys_host_stdout_write() not being cancellable. The
static state variables in the function required that the function be
called repeatedly until it returned something other than PBIO_ERROR_AGAIN.
However, in MicroPython, an exception may be raised in between calls,
which would leave the state variables in an inconsistent state causing
incorrect behavior on the next call.

We can save code size on platforms that only have one transport by only
calling the relevant function instead of trying to duplicate the stream
to a non-existent transport.

Then, to handle platforms with multiple transports, rework the logic to
be able to send data to multiple transports without having to maintain
state between calls. This is done by ensuring that we only send the
same amount of data to each transport.
Implement the Pybricks Profile event subscription flag.

This saves us from trying to send messages to the host when there is no
app running to receive them. Previously, trying to write to stdout
would block forever because of this.

The 5 millisecond timeout is arbitrary. Wireshark shows that the OUT
endpoint is being serviced in less than 1 ms, so this should be plenty
of time even if some hosts are an order of magnitude slower. We don't
want to make it too big because it will delay user programs for this
long and we don't want to mess up someone's control loop too badly.
Now that USB is mostly working, we can enable it by default on SPIKE
Essential and Prime hubs.
@coveralls
Copy link

coveralls commented Jul 19, 2025

Coverage Status

coverage: 57.481% (+0.2%) from 57.254%
when pulling 3c424d0 on dlech:usb-stdio-v2
into 16e7a48 on pybricks:master.

Add an extra check to make sure USB data has been sent before as well
to pbsys_host_tx_is_idle() if applicable.

Also document the function while we are here.
@dlech dlech merged commit 96cdd12 into pybricks:master Jul 19, 2025
17 checks passed
@dlech dlech deleted the usb-stdio-v2 branch July 19, 2025 17:37
@laurensvalk
Copy link
Member

Thanks!

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