-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
shared/tinyusb: Buffer startup stdout (banner) to send once usb cdc is connected. #14485
base: master
Are you sure you want to change the base?
shared/tinyusb: Buffer startup stdout (banner) to send once usb cdc is connected. #14485
Conversation
Code size report:
|
7fddddc
to
4d29eec
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #14485 +/- ##
=======================================
Coverage 98.39% 98.39%
=======================================
Files 161 161
Lines 21204 21204
=======================================
Hits 20864 20864
Misses 340 340 ☔ View full report in Codecov by Sentry. |
Initial tests working on rp2!
|
4d29eec
to
3b8e785
Compare
|
|
3b8e785
to
526af51
Compare
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be a really nice addition, thanks @andrewleech 😁
shared/tinyusb/mp_usbd_cdc.c
Outdated
} | ||
n = MIN(n, tud_cdc_write_available()); | ||
if (n == 0) { | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, if disconnected then after the tinyusb FIFO is full then further output is dropped until USB-CDC connects.
Could this lead to some misleading situations where USB host connects and receives:
banner
early program output
[unknown number of dropped bytes here]
contemporary output that was sent after USB host connected
Is that right? Does it seem like a problem?
The best solution I can see from this perspective would be to rotate bytes out of the overflowing FIFO as needed, but (a) this is quite slow if USB never connects and (b) not supported by current TinyUSB API.
However there is tud_cdc_n_write_clear()
which empties the write FIFO. What do you think about doing this each time the FIFO fills up while disconnected? It means maybe some buffered bytes are lost, but the "new after old with missing middle" situation shown above can't happen.
(Note this isn't a request necessarily, I'm not fully convinced this is worth worrying about.)
Related request I do have is that it'd be good to have a short comment or so in here please, outlining the intended execution flow for this "disconnected, buffering" case as it may not be obvious to future readers why it's structured like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you raise a good question. My thoughts were that keeping the banner (and maybe a little after it) is a good thing to display on connection.
But yes it could be somewhat confusing if there's a running application with more information, the disconnect in log could seem quite random. I'm not too sure how STM handles this currently, whether it's the initial data persisted or the latest data. @dpgeorge do you have a preference here?
A comment or two is definitely warranted regardless!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In stm32 it's a rolling ring buffer, so new data is always placed into the pending CDC output buffer, and if the ring buffer is full then the oldest data is lost. That means on connection to a USB host, the host sees a consistent history of the most recent data, possibly truncated at the beginning of that data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @dpgeorge, the consistent view of "latest data" does make sense really. I'll have a closer look to see if I can make it automatically overwrite, I actually think this might be possible.
If not, the suggestion of "clear on full" might be worth doing instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah, this is convenient: https://github.com/hathach/tinyusb/blob/1f259b3ab0f1b9587dee9c0bfb5574d70d021640/src/class/cdc/cdc_device.c#L250
void cdcd_init(void) { ... // Config TX fifo as overwritable at initialization and will be changed to non-overwritable // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal. // In this way, the most current data is prioritized. tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true);
So yeah if I basically remove the "space in buffer" check when not connected, it'll pretty much "just work". Though I'll need to confirm behavior when you try to write more than a buffer's worth in one go, whether it keeps the start or end of the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is certainly convenient!
It may actually be impossible to debug this with mpremote, given the pyserial hard-coded flush of the input buffer on open. 🤦 But it should be visible with other serial programs, I'd expect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the change and it seemed to work fine! Even with mpremote.... I added a main.py on the samd51 board:
print(list(range(512)))
Now when I start mpremote I see:
$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] or Ctrl-x to exit this shell
486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511]
MicroPython v1.23.0-preview.379.g130e763226.dirty on 2024-05-25; ItsyBitsy M4 ExpreType "help()" for more information.
>>>
526af51
to
aff686c
Compare
Note this PR currently has the TinyUSB submodule pinned to my PR with required SOF updates, so it won't currently build easily. This upstream PR will need to be merged first, it's blocked by the need to test on renesas. |
FWIW I think we could emulate something similar by adding a callback in the mp_usbd_task, or maybe even soft timer. However I think better to stick with the approach you've already used, if it's going to be available soon. |
Yes I'd originally thought of using a soft timer however it does have some overheads, and I'm not sure if all needed ports have it enabled. I think the upstream change should be achievable, I've had very productive discussions on it already. I'm just blocked by renesas port testing, I can't figure out the auto generated code being used in the board profiles there enough to enable USB on the evk board I've loaned. |
130e763
to
54e0abf
Compare
I've now got a renesas board working finally and have finished the implementation there, it's all working too. I just need to clean up some of the commented code in the nrf stuff and it's all good to go! |
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
54e0abf
to
9b8d07d
Compare
This PR has tested working on
The required updates to TinyUSB have been merged upstream and the submodule here is now pinned to the matching master commit. As such I consider this PR complete and ready for review. |
At startup, buffer stdout / microypthon banner so that it can be printed on initial connection of mpremote, just like stm port does.
Requires: hathach/tinyusb#2629 (merged) and hathach/tinyusb#2647 (merged)
Extra details: hathach/tinyusb#2595
Sitting on top of #14462
functional change
This change is most obvious when you've first plugged in a micropython device (or hit reset) when it's a board that uses USB (CDC) serial in the chip itself for the repl interface. This doesn't apply to UART going via a separate usb-serial chip.
On all ports other than stm32 currently, nothing happens when you first run a terminal like mpremote on a freshly booted board.
A user might typically first hit enter to look for a repl prompt
>>>
to ensure they are connected to a micropython board, then maybe hit ctrl-d to soft reboot and see the banner to check they're connected to the right board.On stm however, on a freshly started board when you connect mpremote the banner is immediately shown!.
This PR extends this behaviour to rp2, mimxrt, samd and renesas. It's also extended to esp32s2 / s3 in the follow up PR.