-
Notifications
You must be signed in to change notification settings - Fork 919
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
machine: modify UART and USB CDC ACM Read() to be blocking #3984
base: dev
Are you sure you want to change the base?
Conversation
dbc215f
to
bfdec40
Compare
4667e1f
to
8febc48
Compare
8febc48
to
a56237c
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.
LGTM
The only change I would like to propose is to name 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.
Using a callback for receiving serial data eliminates the need for polling.
Is that the only reason? Because handling things inside an interrupt is a pretty big hammer. If this is the only reason, a much better approach would be to make methods like ReadByte
blocking (to avoid polling).
Also, this is a new API so should be added here: https://tinygo.org/docs/reference/machine/#uart
src/machine/uart.go
Outdated
func (uart *UART) SetRXCallback(cb func(byte) bool) { | ||
uart.rxCallback = cb | ||
} |
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 needs documentation that includes the following:
- it is an interrupt (not just a regular callback)
- it should describe what the return value is
See for example:
tinygo/src/machine/machine_nrf.go
Lines 73 to 80 in 731532c
// SetInterrupt sets an interrupt to be executed when a particular pin changes | |
// state. The pin should already be configured as an input, including a pull up | |
// or down if no external pull is provided. | |
// | |
// This call will replace a previously set callback on this pin. You can pass a | |
// nil func to unset the pin change interrupt. If you do so, the change | |
// parameter is ignored and can be set to any value (such as 0). | |
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error { |
Thanks for the suggestion. Please see the latest commit fe186e9, which implements blocking I opted to change the |
@xudongzheng The essence of this PR is to make the In that case, I believe it should be implemented without using a channel. Additionally, this change will break compatibility with TinyGo. Documentation is also necessary for this, and it needs to be reviewed carefully. Of course, it might also be an option to define a struct like
|
I don't quite see how this would be implemented without channels. For that reason, I initially opted for adding a callback rather than changing the I think the overhead of channel should be pretty low, and it should be one or two at most since there won't be that many serial ports. Performance-wise, it works well enough as I was able to receive about 400KB/s on RP2040 over USB CDC ACM.
I agree, though I would like a bit more clarity on the implementation direction before I start working on the documentation. |
fe186e9
to
7e0f686
Compare
7e0f686
to
27f2fb3
Compare
008029b
to
64da725
Compare
64da725
to
9a6abca
Compare
Hi! Is there any progress on merging this PR? |
Using a callback for receiving serial data eliminates the need for polling.
So far I've only modified the files for RP2040 as that's what I'm testing on. If this PR is in the right direction, I will modify
type UART struct
for the other boards as well.