LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-14-2005, 09:19 PM   #1
Elric of Grans
Member
 
Registered: May 2005
Posts: 46

Rep: Reputation: 15
Interrupt Handler: identifying source...


G'Day,

I am writing some code for a system device, and most parts seem to be working fine now, however, up to this point I have stepped around an issue with the interrupt handler: I really need to address it now.

There are actually 8 identical devices on this system, any of which could trigger the interrupt: they all use the same interrupt line, and logically should use the same handler. All the handler needs to do is write a 1 to a register field, but the address of that register varies depending on which of the 8 devices requested it. For testing, I have only used a single device, however, I now need it to be able to identify which of the 8 triggered it. Is there a way to do this?

If I look at the arguments of a handler, they receive:
int irq,
void *dev_id, and
struct pt_regs *regs

int irq is likely useless here, and I am not sure struct pt_regs *regs would be of any use either, but what about void *dev_id? I have not been able to identify what it is, or what it is for, so perhaps that is what I need? Or is there another way I should go about this? If worst comes to worst, I could poll all 8 registers to identify which one asserted the interrupt, but that is a tad inefficient. If possible, I would like to take a more elegant solution.

Thanks for any advice!

PS
There is also an oddity I have observed that I cannot explain. I am exporting some values to sysfs, however two of them are returning illogical values. They are both reading the same register (value = 0x42). One of the files returns:
sprintf(buffer, "%lu\n", (value & (1 << 6)))
the other
sprintf(buffer, "%lu\n", (value & (1 << 2)))
The former actually returns 64, while the latter 2: I was expecting 1 in both cases. Am I mading some stupid oversight here? It just seems *too* simple to get wrong...
Interestingly enough, in a different case, (value & (1 << 1)) works fine: no matter the value of the register, it always correctly returns 0 or 1.
 
Old 08-14-2005, 09:25 PM   #2
Elric of Grans
Member
 
Registered: May 2005
Posts: 46

Original Poster
Rep: Reputation: 15
Err... actually, foget the PS: I just realised what was wrong! Can I plead Monday?
 
Old 08-16-2005, 09:35 AM   #3
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,610
Blog Entries: 4

Rep: Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905
For some devices, all that you can do is to poll, and sometimes what you need to do ... is poll. If "eight identical devices" are rigged on just one board, it may well raise the interrupt just one time to signal that one-or-more of the devices need attention. If they are separate boards all sharing the same IRQ, then if you can "poll" all of them and thus avoid "X" consecutive interrupts, you also come out ahead. Even though interrupts happen constantly, they are disruptive to the processor's attempts at pipelining .. which is where modern processors get their phenomenal rated speeds. Once you find yourself in a first-level interrupt handler, "you're there, make the most of it."

An interrupt-handler is not necessarily the time to try to be "efficient." Interrupts are not like software signals. What you need to think of, instead, is being thorough. Make sure that an interrupt does not wander by, trying to tell you something, and you "efficiently" don't notice.

You also need to consider that perhaps the interrupt does not belong to you at all. It may belong to another device, unrelated to yours. Or, by some unhappy luck of the draw, the interrupts could pile-up so that both your device and another device have signaled for attention at precisely the same nano-bleem, so that the interrupt is for (or can be treated as) both your device and someone else's, at the same time. It can get strange. You can never predict it. That's why you need to be conservative. And in any case, the time that you spend inside the routine is a lot less costly than the time the kernel and the CPU have already spent in getting you there.

The only purpose of the "upper half" (initial interrupt-response) processing should be to notice what needs to be done and queue-up the appropriate "lower half" routines to actually do the work... then get out and let the next upper-half routine do its thing. But you will come out ahead if you happen to detect that several identical devices all need servicing and can, by polling their status-registers, stop them from all generating (consecutive, redundant) interrupts.

Last edited by sundialsvcs; 08-16-2005 at 09:42 AM.
 
Old 08-16-2005, 11:29 AM   #4
rstewart
Member
 
Registered: Feb 2005
Location: Sunnyvale, CA
Distribution: Ubuntu
Posts: 205

Rep: Reputation: 38
Quote:
An interrupt-handler is not necessarily the time to try to be "efficient." Interrupts are not like software signals. What you need to think of, instead, is being thorough. Make sure that an interrupt does not wander by, trying to tell you something, and you "efficiently" don't notice.
Uh,

Writing inefficient ISRs is definitely a cause for poor latency issues. In an ISR you definitely do want to be as efficient as possible, but I do agree that you also want to be thorough. You want to come in, process everything that needs to be processed in order to completely service the interrupt, and get out of Dodge - writing the most efficient and optimized code that you can write. The longer you stay in an ISR, the longer you are holding off lower priority events.
 
Old 08-16-2005, 09:03 PM   #5
Elric of Grans
Member
 
Registered: May 2005
Posts: 46

Original Poster
Rep: Reputation: 15
Thanks for the advice. I have observed interrupts working for any device I select now.

ISR do need to be efficient, however, especially for embedded systems, such as this one. If I make this ISR much longer than it is now, then the whole thing falls over under certain situations.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Linux Interrupt Handler lucky6969b Linux - Software 1 12-01-2005 11:55 AM
printk in the interrupt handler lordofring Programming 3 08-23-2005 08:00 PM
<0>Kernel panic: Aiee, killing interrupt handler! In interrupt handler - not syncing mrb Linux - Newbie 2 01-09-2005 09:47 AM
Why this interrupt handler does not work? opereira Programming 1 03-04-2004 01:37 PM
Timer Interrupt Handler opereira Programming 1 03-03-2004 04:57 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration