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

Improve handling of interrupt allocation #1063

Closed
20 tasks done
jessebraham opened this issue Jan 5, 2024 · 23 comments
Closed
20 tasks done

Improve handling of interrupt allocation #1063

jessebraham opened this issue Jan 5, 2024 · 23 comments
Assignees
Labels
status:in-progress This task is currently being worked on

Comments

@jessebraham
Copy link
Member

jessebraham commented Jan 5, 2024

Currently when using the async (and some other) features, a number of interrupts are automatically bound to handlers.

This can be problematic for various reasons. One such example is implementing the embedded_hal_async::delay::DelayNs trait, which when implemented for TIMG$n/SYSTIMER conflict with the Embassy time drivers. In other cases, users may want to define their own interrupt handlers for certain peripherals, while still using the default interrupt handlers defined via the async feature in the HAL. This is presently not possible.

I'm not sure what the solution for this is yet. #1047 tried making the interrupt handlers overrideable, but we did not end up merging this; see the discussion in the PR for details. I would like to hear people's thoughts on potential solutions to this problem.

Progress:

Peripheral conversion

@jessebraham jessebraham added the RFC Request for comment label Jan 5, 2024
@bjoernQ
Copy link
Contributor

bjoernQ commented Jan 5, 2024

I like the idea of runtime binding of interrupt handlers as suggested here: #1047 (comment)

I had a brief look at our code and I think it won't add much more latency - if any - for the vectored interrupt handling (which I guess is the most used option)

@MabezDev
Copy link
Member

MabezDev commented Jan 5, 2024

Fleshing out my ideas from #1047 (comment).

I believe that we might want to remove the async feature from the hal, we can keep it if we like of course, but what I really mean is that a feature should not determine a driver whether a driver is async or blocking, it should be determined by how its initialized.

Let's use Uart as an example. Imagine we introduce a new typestate for the mode Uart<T: Instance, M>, in which the mode can be two concrete types, Blocking and Async. We can now have custom constructor for each "mode". Instead of explaining in text, here is a concise playground link with the basic idea: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1ed57ede8b38f89bed84058ca5dbc3b4.

With the above in mind, we need changes to the current interrupt mechanism. The current mechanism uses linkage to bind the interrupt handlers, but we need to turn this into a runtime mechanism. The code inside the interrupt module, will most likely stay the same. What will change is how we install the interrupt fn ()'s into the __INTERRUPTS array. Most likely this will be done through the constructor of peripheral drivers.

@bjoernQ
Copy link
Contributor

bjoernQ commented Jan 5, 2024

Basically, had a similar thing in mind (minus the type-state).

Most likely this will be done through the constructor of peripheral drivers.

And in case of non-async we probably want to provide a function to register a user provided interrupt handler.

The code inside the interrupt module, will most likely stay the same.

I also think so - I think we need to place __INTERRUPTS in RAM for RISCV - IIRC it's currently on flash

@MabezDev
Copy link
Member

Basically, had a similar thing in mind (minus the type-state).

FYI the reason I added the type-state is so we only implement certain traits in specific modes, for example, we don't want to implement the async traits if a driver is initialized in blocking mode.

@MabezDev
Copy link
Member

MabezDev commented Jan 24, 2024

After some discussion, I think we're all on board with trying to explore the proposal above.

We found four areas we'll need to investigate before we can commit to this design:

  • User facing, how do we map interrupts as resources? How do we customize handlers? How do we pass them into peripheral drivers?
  • Internally, what work do we need to do to handle the new interrupts, how to enable them? What do we do with the current interrupt modules API?
  • Linkage - Hopefully the linker changes should be minimal, but we should look into what we need to remove from the pacs, and where to place the interrupt array now that we are binding at runtime.

Extended goals, not critical to the initial design:

  • Edge cases - What do we do with DMA channels? DMA channels that can be split? DMA Channels that are tied to a specific peripheral? Are there any other edge-case peripherals to consider?

@MabezDev
Copy link
Member

Thanks to @bjoernQ for investigating much of this! With the exploratory PR in #112, we can check off three of the four items in the list. The last side to explore is the user facing side, how we change the driver constructors and how users interact with interrupts.

For now we are focusing on unifying the HAL.

@MabezDev MabezDev added the status:blocked Unable to progress - dependent on another task label Feb 19, 2024
@jessebraham
Copy link
Member Author

@MabezDev what is this blocked on?

@bjoernQ
Copy link
Contributor

bjoernQ commented Feb 29, 2024

I wanted to start working on the real implementation of this after the next HAL release (I certainly can start behind the curtain earlier). Good thing is we don't need to have it in a big-bang

@jessebraham jessebraham removed the status:blocked Unable to progress - dependent on another task label Mar 12, 2024
@MabezDev MabezDev added the status:in-progress This task is currently being worked on label Mar 13, 2024
@MabezDev MabezDev pinned this issue Mar 13, 2024
@MabezDev MabezDev changed the title RFC: Improve handling of interrupt allocation Improve handling of interrupt allocation Mar 13, 2024
@MabezDev MabezDev removed the RFC Request for comment label Mar 13, 2024
@jessebraham
Copy link
Member Author

@MabezDev @bjoernQ no big rush, but whenever we get a chance could we please try to summarize what work still remains to be done in order to close this issue?

@MabezDev
Copy link
Member

The next steps are as follows:

@bjoernQ will be taking care of DMA, which is another special case like GPIO.

The next stage for the rest of the drivers needs to be designed. I've posted some ideas earlier in this thread, but this isn't a full solution, but it's pretty close I think. We can probably skip the interrupt as a resource bit for now, and keep interrupt enable outside of the driver (though we can move it in the driver for async mode).

I probably won't get to it today, but I'll try and get a small-ish driver converted (maybe uart?) and see how it feels. Once we have a pattern to copy we can split the work up a bit.

@jessebraham
Copy link
Member Author

For some reason there were some peripherals listed in the task list that we do not currently support interrupts for, so I have removed those as they're irrelevant to this task.

@jessebraham
Copy link
Member Author

jessebraham commented Apr 2, 2024

Working on the usb_serial_jtag driver.

@bjoernQ
Copy link
Contributor

bjoernQ commented Apr 3, 2024

Working on TWAI now

@JurajSadel
Copy link
Contributor

Working on debug-assist

@bjoernQ
Copy link
Contributor

bjoernQ commented Apr 3, 2024

I'll look into SoftwareInterruptControl and friends next

@jessebraham
Copy link
Member Author

Once the remaining items in the task list have been completed, we should do a review to ensure that we have not missed any peripherals. While doing this, it may also be beneficial to determine which existing drivers have not implemented interrupt support, though that probably deserves a separate issue for tracking.

@bjoernQ
Copy link
Contributor

bjoernQ commented Apr 4, 2024

Once the remaining items in the task list have been completed, we should do a review to ensure that we have not missed any peripherals.

At least there shouldn't be any usage of #[interrupt] anymore. IIRC we also want to remove that macro once all drivers are changed

While doing this, it may also be beneficial to determine which existing drivers have not implemented interrupt support, though that probably deserves a separate issue for tracking.

Definitely another issue, agreed. I think there are also some drivers which can bind an interrupt handler now but it's almost impossible to really make use of that in user code. But that's probably another issue on its own then

@playfulFence
Copy link
Contributor

I'll take PCNT

@JurajSadel
Copy link
Contributor

Working on rtc-wdt

@SergioGasquez
Copy link
Member

I think the changes are not required for MCPWM, just removed it from the list

@jessebraham
Copy link
Member Author

jessebraham commented Apr 4, 2024

There are only two items remaining in our current task list which do not already have PRs opened:

  • LCD_CAM - Status unsure of what's left to do; still waiting on hardware to arrive to Brno office (has been ordered) so we can test this
  • RTC_WDT - Being worked on by @JurajSadel

We will need to review the code base in its current form and ensure that we have not missed anything, but I think we're pretty close to being done here. Thanks a bunch to everybody who has helped out with this already!

@bjoernQ
Copy link
Contributor

bjoernQ commented Apr 5, 2024

Seems like LCD_CAM currently doesn't offer or use any interrupt functionality. I suggest to remove it from the list - whenever interrupt support is added it will follow the new way of handling interrupts

EDIT: I removed it

@JurajSadel JurajSadel self-assigned this Apr 5, 2024
@jessebraham
Copy link
Member Author

Looks like we're done here! I'm going to go ahead and close this issue, if we discover any other drivers which we've missed we can open issues on a per-case basis.

Thanks again everybody for helping out with this!

@jessebraham jessebraham unpinned this issue Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:in-progress This task is currently being worked on
Projects
Archived in project
Development

No branches or pull requests

6 participants