Skip to content
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

Const Generics and Async features for Peripherals #186

Open
1 task
pranav12321 opened this issue Aug 31, 2022 · 1 comment
Open
1 task

Const Generics and Async features for Peripherals #186

pranav12321 opened this issue Aug 31, 2022 · 1 comment
Assignees
Labels
✨ feature New things!

Comments

@pranav12321
Copy link
Contributor

what

To use future based model for Peripherals and have non blocking implementation on reading peripherals. Particularly useful for DMA based peripheral accesses, cached accesses and devices where access time is too long.
Also implement support for const generics for Number of pins.

steps

  • [[ steps ]]

[[ What steps will we need to take to implement this feature? ]]

where

branch: feat-

[[
This should be:

open questions

[[
Unknowns and questions about the design/implementation of this feature.
This is kind of a catch all for anything that doesn't fit in the above categories.
]]

@pranav12321 pranav12321 added the ✨ feature New things! label Aug 31, 2022
@pranav12321 pranav12321 self-assigned this Aug 31, 2022
@rrbutani
Copy link
Member

This is definitely something that merits further discussion; some initial thoughts:

Async Peripherals

Surface level this looks a little like #185 but I am not sure: the intent of #185 (and #184) is to support host platforms where implementations of the peripheral traits (and the RPC traits) will require async. From the perspective of the LC-3 userspace the APIs are still blocking though.

However it sounds like what you're describing is actually a change in the semantics of the LC-3 userspace APIs?

To use future based model for Peripherals and have non blocking implementation on reading peripherals. Particularly useful for DMA based peripheral accesses, cached accesses and devices where access time is too long.

I totally understand the appeal of exposing non-blocking interfaces to the LC-3 userspace but I think it's worth pointing out that we have an existing interface for this: interrupts. Given that I don't think there's a way to retrofit a non-blocking I/O model onto the existing mem-mapped interfaces while retaining the benefits of being non-blocking (there's not really much work we can do (other than replying to rpc messages, perhaps?) when an memory mapped access comes back as "not ready", we just have to wait for the access to finish before we can have the interpreter continue) I think interrupts are our best bet for exposing interfaces where we expect blocking I/O to be too slow to be practical.

I am unsure if this is what you had in mind but to me an interesting angle is leveraging async in Peripheral traits as a more elegant way to provide the backing implementations for these interrupt based LC-3 interfaces; i.e. for GPIO, an async fn read(...) -> ... function from which we generate the blocking read counterpart as well as the interrupt_ready/interrupt_clear adapters. I'm skeptical this is worth the effort given the obstacles (as mentioned in #184 async traits today are lowered as trait objects + allocations which are unsuitable for embedded applications and have runtime cost, the async story for embedded devices is still developing and requiring an async executor for your device/architecture somewhat restricts the devices UTP can run on and the ease with which it can be ported to new devices), the downsides (a little more complexity across the stack; being pretty familiar with Pin<_> and the Future trait will become a requirement for working with the interpreter<->peripheral trait layer, the debugging experience with async suffers a little), and the limited upside (most LC-3 I/O will probably still be blocking anyways and at best we can expect to be able to process incoming requests but not much else when blocking on these accesses, most peripherals probably will not have long access times/expensive compute) but it's maybe worth discussing.

@pranav12321 perhaps you can clarify what you had in mind?

Const Generics

Also implement support for const generics for Number of pins.

Stable const generics can definitely help us make cleaner abstractions for several components in our stack and we've already started to use them in places (i.e. our Fifo's length: #166, the precision of ADC readings: 74c92fb) in the project.

However, I'm not sure they're a good fit for modeling the number of pins on peripherals (like GPIO, ADC, Timers, and PWM). I think we actually want pin counts to be static and not something device implementators can tune for a few reasons:

  • consistency across the platform: we want LC-3 programs that work on one implementation of UTP to work elsewhere
  • Control and RPC become complicated in the presence of variable const generic params that are not known at compile-time
    • none of this is technically insurmountable but it is complexity that I'd rather avoid

@pranav12321 what do you see as being the upside to using const generics for pins?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ feature New things!
Projects
None yet
Development

No branches or pull requests

2 participants