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

Bind multiple interrupts? #1021

Open
Erhannis opened this issue Feb 15, 2025 · 2 comments
Open

Bind multiple interrupts? #1021

Erhannis opened this issue Feb 15, 2025 · 2 comments

Comments

@Erhannis
Copy link

ATM it seems like you can only bind a task to at most one interrupt; is there any deeply rooted reason you couldn't bind it to more than one interrupt? I have a task managing a hardware UART, but I'm having trouble sending data without just blocking until it's done. I can't find a way to disable the "tx buffer empty" interrupts when I don't have anything to send (without also dropping the rx fifo), so if I have that interrupt enabled, once I run out of data the task is perpetually called, starving other tasks. I thought, maybe I can just add a timer that triggers every 100us and runs the UART update task, too. Unfortunately, it seems like you can only bind a task to a single interrupt. How hard would it be to permit e.g. binds = [LPUART5, GPT2], and would it incur overhead like locks?

I looked at cargo expand, and copied one of the interrupt handlers into a function I can call from a second handler, like

    unsafe fn LPUART5_dupe() {
      const PRIORITY: u8 = 1u8;
      rtic::export::run(
        PRIORITY,
        || { lpuart5_interrupt(lpuart5_interrupt::Context::new()) },
      );
    }

though I also wondered if the nested runs were necessary/good, so I also considered directly running

unsafe {
  lpuart5_interrupt(lpuart5_interrupt::Context::new());
}

in my timer task. Are either of these safe? I suspect there'd be trouble if the two tasks had different priorities, but what if they were the same? (I've tested both, btw, and they SEEM to work, but of course that's no guarantee it's SAFE.)

@perlindgren
Copy link
Collaborator

Hi, Erhannis

If the underlying hardware has separate rt/tx interrupts it is possible to have separate tasks.

A shared interrupt handler would need to check if a rt or tx or even both has happened, this is usually done by polling. The interrupt might be needed clearing in the peripheral (depending on the hw).

/Per

@Erhannis
Copy link
Author

Erhannis commented Mar 9, 2025

You mean, check rx/tx just so my code responds appropriately? Sure; I'm doing that - I'm primarily wondering if binding a single task to multiple interrupts (which doesn't appear possible through the standard RTIC syntax) would create UB. For instance, perhaps the rx interrupt firing while the tx is still being handled could cause the the handler to run again at the same time, resulting in two mutable references to the same local stuff. Also, I'm currently on a one-core device, but perhaps things are different on a multi-core device. Are either of my workarounds safe in practice? Under what assumptions?

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

No branches or pull requests

2 participants