-
Notifications
You must be signed in to change notification settings - Fork 187
feat: support timeouts and deadlines #1018
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -135,6 +135,8 @@ pub const instance = struct { | |
| } | ||
| }; | ||
|
|
||
| pub const TimeFrontier = union(enum) { timeout_us: u64, deadline: mdf.time.Deadline }; | ||
|
|
||
| /// An API for interacting with the RP2040's UART driver. | ||
| /// | ||
| /// Note: Assumes proper GPIO configuration, does NOT configure GPIO pins. | ||
|
|
@@ -148,20 +150,28 @@ pub const UART = enum(u1) { | |
|
|
||
| pub const Writer = struct { | ||
| uart: UART, | ||
| deadline: mdf.time.Deadline, | ||
| timeFrontier: TimeFrontier, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: fields should be snake case |
||
| interface: std.Io.Writer, | ||
|
|
||
| pub fn set_deadline(self: *Writer, deadline: mdf.time.Deadline) void { | ||
| self.*.timeFrontier = TimeFrontier{.deadline = deadline}; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doing self.* here is not necessary. Field access dereferences the pointer automatically |
||
| } | ||
| }; | ||
|
|
||
| pub const Reader = struct { | ||
| uart: UART, | ||
| deadline: mdf.time.Deadline, | ||
| timeFrontier: TimeFrontier, | ||
| interface: std.Io.Reader, | ||
|
|
||
| pub fn set_deadline(self: *Reader, deadline: mdf.time.Deadline) void { | ||
| self.*.timeFrontier = TimeFrontier{.deadline = deadline}; | ||
| } | ||
| }; | ||
|
|
||
| pub fn writer(uart: UART, deadline: mdf.time.Deadline, buffer: []u8) Writer { | ||
| pub fn writer(uart: UART, timeFrontier: TimeFrontier, buffer: []u8) Writer { | ||
| return .{ | ||
| .uart = uart, | ||
| .deadline = deadline, | ||
| .timeFrontier = timeFrontier, | ||
| .interface = .{ | ||
| .buffer = buffer, | ||
| .vtable = &.{ | ||
|
|
@@ -171,10 +181,10 @@ pub const UART = enum(u1) { | |
| }; | ||
| } | ||
|
|
||
| pub fn reader(uart: UART, deadline: mdf.time.Deadline, buffer: []u8) Reader { | ||
| pub fn reader(uart: UART, timeFrontier: TimeFrontier, buffer: []u8) Reader { | ||
| return .{ | ||
| .uart = uart, | ||
| .deadline = deadline, | ||
| .timeFrontier = timeFrontier, | ||
| .interface = .{ | ||
| .buffer = buffer, | ||
| .seek = 0, | ||
|
|
@@ -190,18 +200,24 @@ pub const UART = enum(u1) { | |
| const uart_writer: *Writer = @alignCast(@fieldParentPtr("interface", w)); | ||
| const uart = uart_writer.uart; | ||
|
|
||
| var deadline: mdf.time.Deadline = undefined; | ||
| switch (uart_writer.timeFrontier) { | ||
| .deadline => |d| deadline = d, | ||
| .timeout_us => |t| deadline = time.deadline_in_us(t) | ||
| } | ||
|
Comment on lines
+203
to
+207
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: switch can be used as an expression so you could do const deadline: mdf.time.Deadline = switch (uart_writer.time_frontier) {
.deadline => |d| d,
.timeout_us => |t| time.deadline_in_us(t),
}; |
||
|
|
||
| // bytes from buffer are not included in count. | ||
| w.end -= uart.write_blocking(w.buffer[0..w.end], uart_writer.deadline) catch |err| switch (err) { | ||
| w.end -= uart.write_blocking(w.buffer[0..w.end], deadline) catch |err| switch (err) { | ||
| error.Timeout => unreachable, | ||
| }; | ||
| assert(w.end == 0); | ||
|
|
||
| var n: usize = 0; | ||
| n += uart.writev_blocking(data[0 .. data.len - 1], uart_writer.deadline) catch |err| switch (err) { | ||
| n += uart.writev_blocking(data[0 .. data.len - 1], deadline) catch |err| switch (err) { | ||
| error.Timeout => unreachable, | ||
| }; | ||
| for (0..splat) |_| | ||
| n += uart.write_blocking(data[data.len - 1], uart_writer.deadline) catch |err| switch (err) { | ||
| n += uart.write_blocking(data[data.len - 1], deadline) catch |err| switch (err) { | ||
| error.Timeout => unreachable, | ||
| }; | ||
|
|
||
|
|
@@ -211,10 +227,17 @@ pub const UART = enum(u1) { | |
| fn stream(r: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize { | ||
| const uart_reader: *Reader = @alignCast(@fieldParentPtr("interface", r)); | ||
| const uart = uart_reader.uart; | ||
|
|
||
| var deadline: mdf.time.Deadline = undefined; | ||
| switch (uart_reader.timeFrontier) { | ||
| .deadline => |d| deadline = d, | ||
| .timeout_us => |t| deadline = time.deadline_in_us(t) | ||
| } | ||
|
|
||
| return switch (limit) { | ||
| .nothing => 0, | ||
| else => { | ||
| const b = uart.read_word_blocking(uart_reader.deadline) catch return error.ReadFailed; | ||
| const b = uart.read_word_blocking(deadline) catch return error.ReadFailed; | ||
| try w.writeByte(b); | ||
| return 1; | ||
| }, | ||
|
|
@@ -559,7 +582,7 @@ var uart_logger: ?UART.Writer = null; | |
| /// .logFn = hal.uart.log, | ||
| /// }; | ||
| pub fn init_logger(uart: UART) void { | ||
| uart_logger = uart.writer(.no_deadline, &.{}); | ||
| uart_logger = uart.writer(.{.deadline = .no_deadline}, &.{}); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can become |
||
| uart_logger.?.interface.writeAll("\r\n================ STARTING NEW LOGGER ================\r\n") catch {}; | ||
| } | ||
|
|
||
|
|
||
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.
nit: maybe format this on multiple lines?
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.
You can add here a
so you can do .no_deadline directly when you don't want any deadline.