Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

uClinux Interrupt issues

I have a custom component that I'm connecting to the nios2 with a PIO bridge. The component is essentially a selectable timer that I'm using as a trigger throughout the whole device, the same trigger is also used as the Interrupt for the cpu (to capture all the other registers I have wired up).

I register the irq fine, (it shows up in proc/interrupts), but when I unmask the interrupt by writing to the pio. The whole system hangs. Well actually, when I request the IRQ as IRQF_SHARED, the system doesnt hang, but it is interrupting about 1000 times more often than expected (i.e. if the timer is set to 100ms, you would expect ~10 interrupts a second, I'm getting thousands). If I throw in an IRQF_POSEDGE and set the timer to something long(like 5 seconds), it hangs on the first interrupt.

I have commented out the entire interrupt handler, so all it does is return a IRQ_HANDLED . and it still hangs.

Thanks for the help,

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    So I ended up solving the problem. After thoroughly reading the PIO core datasheet, I learned that I have to clear the interrupts after handling it, otherwise the system will keep interrupting.

    As for the stalling issue, I had a buffer in the driver to buffer ~100 acquisitions (so user space programs had some time to react). And it seems that There wasn't enough heap space left on my DE2 sdram, after a few triggers it started eating into some vital kernel component and stalling the system.

    On a related note. Does anyone know the best way to notify a userland program that an interrupt has occurred? I need to somehow send out my acquired data through either USB or ethernet, and I want to wake the sending process after an interrupt has occured and get it to read the buffer and send the data along to my computer for recording.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    To do a decent interface between a user program and an interrupt enabled hardware device you should write a Kernel driver.

    Now the user program (after a open() ) will do (e.g.) a read(). The Kernel driver implements the read function as a blocking read and thus the user program will stall in the read(). After the interrupt (and when it is finished doing the data transfer with the hardware), the Kernel driver unlocks the block and the user program continues to run.

    If the user program is supposed to do any work while waiting on the data transfer, it can either be done as a multithreded application with one thread stalling in the read() while others keep running, or you can use select() or epoll() to have the program notified by the driver. select() and epoll() need additional interfaces in the Kernel driver.

    -Michael
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    To do a decent interface between a user program and an interrupt enabled hardware device you should write a Kernel driver.

    Now the user program (after a open() ) will do (e.g.) a read(). The Kernel driver implements the read function as a blocking read and thus the user program will stall in the read(). After the interrupt (and when it is finished doing the data transfer with the hardware), the Kernel driver unlocks the block and the user program continues to run.

    If the user program is supposed to do any work while waiting on the data transfer, it can either be done as a multithreded application with one thread stalling in the read() while others keep running, or you can use select() or epoll() to have the program notified by the driver. select() and epoll() need additional interfaces in the Kernel driver.

    -Michael

    --- Quote End ---

    I already wrote a driver and implemented the polling interface, I was wondering if there is any ... faster method of polling the driver. This is the main purpose of the embedded device, this polling is essentially all its going to do. Rather than relying on message passing via poll().
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What I described has nothing to do with polling. In fact the name of the epoll() function is misleading (See "Linux Device Drivers" by Rubini et al).

    - The driver can unblock read() immediately after the interrupt was handled

    - The driver can unblock select() immediately after the interrupt was handled. Now the user program will immediately execute the appropriate code unless it still in some other path and did not reach the select statement

    - similar stuff is happening with epoll(). Here the alternatives don't need to be scanned but are addressed directly.

    - If a multithreaded program dedicates one thread to waiting on the event to happen, it can do the blocking read() and thus start immediately after the driver handled the interrupt. If this thread has a higher (realtime-) priority than other threads it will preempt all other threads of the application and do it's work at once (unless the Kernel schedules some even higher priority tasks).

    -Michael