Re: interrupts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 9/20/05, Manu Anand <manu.anand@xxxxxxxxx> wrote:
> 
> 
> On 9/20/05, raja <vnagaraju@xxxxxxxxxxxx> wrote:
> > actually i am writing a module to sense the timer interrupt.
> > Any way for every clock tick the timer updates the system time.I want to
> > find out the process's information that was running at the time the
> > timer interrupt occures. 
> 
> 
> Hi Raja:
> 
> Am I write in assuming that u want ur module to sort of hook on to timer
> interrupt? The idea being that ur module should also be invoked when the
> timer interrupt handler is invoked. 
> 
> In that case, the approach you've followed will not work. Timer interrupt is
> not shared.
> 
> When the kernel receives the interrupt, it invokes sequentially each
> reqistered handler on the line. However in your case the call 
> 
> request_irq(TIMER_INTERRUPT,
> timer_interrupt_handler,SA_SHIRQ,DEVICE_NAME,&devNo);
> 
> will fail since the IRQ line is already registered for timer interrupt in an
> exclusive non-shared( specified using SA_INTERRUPT 

Manu, I think it will not matter. Actually if we see the code which
invokes the registered handlers for any IRQ line ( handle_IRQ_event()
function ), we will come to know that there is only one special
handling for SA_INTERRUPT flag. If this flag is not set for the first
handler, then the interrupts are enable on local CPU. It does not
block the invocation of other handlers in the IRQ handler's list.

If we also see the function implementation of request_irq(), we do not
do any handling for ~SA_SHIRQ flag in that function, so this is also
not the function which can restrict us to register our handler for non
shared interrupt line.

here is the definition of request_irq() function and handle_IRQ_event() function

==========================================
78 fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
79                                 struct irqaction *action)
80 {
81         int ret, retval = 0, status = 0;
82 
83         if (!(action->flags & SA_INTERRUPT))
84                 local_irq_enable();
85 
86         do {
87                 ret = action->handler(irq, action->dev_id, regs);

here we are simply invoking the registered handlers for specified IRQ
line one by one

88                 if (ret == IRQ_HANDLED)
89                         status |= action->flags;
90                 retval |= ret;
91                 action = action->next;
92         } while (action);
93 
94         if (status & SA_SAMPLE_RANDOM)
95                 add_interrupt_randomness(irq);
96         local_irq_disable();
97 
98         return retval;
99 }



310 int request_irq(unsigned int irq,
311                 irqreturn_t (*handler)(int, void *, struct pt_regs *),
312                 unsigned long irqflags, const char * devname, void *dev_id)
313 {
314         struct irqaction * action;
315         int retval;
316 
317         /*
318          * Sanity-check: shared interrupts must pass in a real dev-ID,
319          * otherwise we'll have trouble later trying to figure out
320          * which interrupt is which (messes up the interrupt freeing
321          * logic etc).
322          */
323         if ((irqflags & SA_SHIRQ) && !dev_id)
324                 return -EINVAL;

check if shared IRQ, but device id is not given, return error, no
check for non shared IRQs done in this function

325         if (irq >= NR_IRQS)
326                 return -EINVAL;
327         if (!handler)
328                 return -EINVAL;
329 
330         action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
331         if (!action)
332                 return -ENOMEM;
333 
334         action->handler = handler;
335         action->flags = irqflags;
336         cpus_clear(action->mask);
337         action->name = devname;
338         action->next = NULL;
339         action->dev_id = dev_id;
340 
341         retval = setup_irq(irq, action);
342         if (retval)
343                 kfree(action);
344 
345         return retval;
346 }
==========================================

-Gaurav

> // Check out
> http://lxr.linux.no/source/arch/i386/mach-default/setup.c#L74
> static struct 
> irqaction irq0 = 
> { timer_interrupt, SA_INTERRUPT, 
> CPU_MASK_NONE, "timer", NULL, NULL};
> 
> Your approach is valid for interrupts specified with SA_SHIRQ flag.
> 
> 
> Manu
> 
> 
>  
> 
> > I have registered my handler that prints simply a message when ever the 
> > timer interrupt occures.But it is not working.It is not printing any
> > message.
> > 
> > I am listing my code below.Will you please help me
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > #ifndef __KERNEL__
> >         #define __KERNEL__ 
> > #endif
> > 
> > #ifndef MODULE
> >         #define MODULE
> > #endif
> > 
> > #include <linux/kernel.h>
> > #include <linux/init.h>
> > #include <linux/module.h>
> > #include <linux/fs.h>
> > #include <linux/interrupt.h> 
> > 
> > MODULE_AUTHOR("RAJA");
> > MODULE_DESCRIPTION("TIMER INTERRUPT");
> > MODULE_LICENSE("GPL");
> > 
> > #define DEVICE_NAME "timer_interrupt"
> > #define TIMER_INTERRUPT 0
> > static int __init init_timer_interrupt(void); 
> > static void __exit exit_timer_interrupt(void);
> > 
> > static irqreturn_t timer_interrupt_handler(unsigned
> int,void *, struct
> > pt_regs *);
> > 
> > int devNo;
> > struct file_operations fops = {};
> > 
> > static irqreturn_t timer_interrupt_handler(unsigned int
> irq,void *data, 
> > struct pt_regs *regs)
> > {
> >         printk("Timer Interrupt Occured\n");
> >         return 0;
> > }
> > 
> > static int __init init_timer_interrupt()
> > {
> >         printk("Entered Into init_timer\n"); 
> >         devNo = register_chrdev(0,DEVICE_NAME,&fops);
> > 
> >
> request_irq(TIMER_INTERRUPT,timer_interrupt_handler,SA_SHIRQ,DEVICE_NAME,&devNo);
> >         printk("Exited From init_timer\n");
> >         return 0; 
> > }
> > 
> > static void __exit exit_timer_interrupt()
> > {
> >         printk("Entered Into exit_timer\n");
> >         unregister_chrdev(devNo,DEVICE_NAME);
> >         free_irq(TIMER_INTERRUPT,&devNo);
> >         printk("Exited From exit_timer\n"); 
> > }
> > 
> > module_init(init_timer_interrupt);
> > module_exit(exit_timer_interrupt);
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > On Tue, 2005-09-20 at 17:02 +0500, Fawad Lateef wrote:
> > > On 9/20/05, raja < vnagaraju@xxxxxxxxxxxx> wrote:
> > > > yaa.
> > > > I have checked /proc/interrupts.
> > > > But there it is given the interrupt numbers.
> > > >
> > > > actually the requirement is i am writing a module that it senses when 
> > > > ever the interrupt occures and prints the interrupt number.
> > > >
> > > > Will you please help me.
> > > >
> > > >
> > >
> > > What sort of module you are writing ?? How you are going to sense 
> > > interrupts when they occurs ?? I think for getting signal through the
> > > call-backed function from the kernel you have to register your
> > > interrupt handlers, so that you can be notified by the kernel ........ 
> > >
> > > Or hack into the kernel, to get notified for each interrupt, but AFAIK
> > > your module can't get every single interrupt until you register them
> > > with the kernel ........
> > >
> > > Correct me if I m wrong !!!! 
> > >
> > >
> > 
> > 
> > --
> > Kernelnewbies: Help each other learn about the Linux kernel.
> > Archive:       http://mail.nl.linux.org/kernelnewbies/
> > FAQ:           http://kernelnewbies.org/faq/
> > 
> > 
> 
>  


-- 
- Gaurav
my blog: http://lkdp.blogspot.com/
--

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux