LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Parallel Port Interrupt problem with C code? (https://www.linuxquestions.org/questions/linux-kernel-70/parallel-port-interrupt-problem-with-c-code-452120/)

James Scrymgeour 06-06-2006 10:57 AM

Parallel Port Interrupt problem with C code?
 
The problem is that this code does not work correctly and I am not quite sure why, the problems I have are:

1) The code works the first time it is loaded and picks up the first generated interrupt, but when i generate a 2nd or 3rd interrupt this is not picked up, even if i rmmod the module and insmod it again does not pick up an interrupt until i reset?
this could be because of the next problem!

2) when i use the make command i get the following compile error: in function `xinit_module`:
warning: passing arg 2 of `request_irq` from incompatible pointer type

I have checked the modules (more modules) and the module is added and removed correctly, there is no error code generated by ret (from request_irq), more interrupts says that 2 interrupts have been produced!

any light you could shed over the problems would be much appreciated, obviously it would be ideal to get rid of warning, but more importantly the fact that it only picks up one interrupt per boot is the most annoying thing!!
THanks
James

The code:

#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <asm/io.h>

#define BASEPORT 0x378

static int handler(void)
{
// do stuff
printk(">>> PARALLEL PORT INT HANDLED\n");
return 0;
}

int xinit_module(void)
{
int ret;
ret = request_irq(7, handler(), SA_INTERRUPT, "parallelport", NULL);
//set port to interrupt mode; pins are output
outb_p(0x10, BASEPORT + 2);

printk("return code = %d\n", ret);
printk("Wait for interrupt to be generated\n");
return 0;
}

void xcleanup_module(void)
{
disable_irq(7);
free_irq(7, NULL);
printk ("closed\n");
}

module_init(xinit_module);
module_exit(xcleanup_module);
MODULE_LICENSE("GPL");

James Scrymgeour 06-06-2006 04:18 PM

Got to the bottom of the repeating the interrupt problem, something to do with the kernel of vector linux 3.0 I think, am trying to install 4.0 now to see if that sorts out the problem, i still get the error message though if anyone can help with that?
thanks
James

theNbomr 06-06-2006 04:49 PM

I don't know so much about interrupt handling under linux; maybe the kernel does this automatically, but from my MS-DOS days I know you had to end a hardware interrupt by resetting the interrupt controller status. In assembler language, it was done like this:

Code:

   
    mov    al, 020h                    ; issue EOI to 8259 PIC
    out    020h, al
    pop    ax
    iret

I seem to recall the symptom of failing to do this was exactly as you describe.

Just a thought...

(Boy, I really miss doing that kind of stuff. I really need to get back into it somehow.)

--- rod.

sundialsvcs 06-06-2006 08:43 PM

The best way to attack this sort of problem is ... "use the Source, Luke!" :) Go out to some of the existing hardware-driver source-code and find some piece of existing code that's doing something similar to yours. And, read it carefully.

Then, go to the kernel directories and look at the actual source code of the routines that you are calling. Look also at the Documentation subdirectory. "grep" can be your best friend.

This is easily the best, fastest, and most authoritative way to deal with issues and questions like these. "You have All Of The Source: you don't have to guess." :)

jineshkj 06-07-2006 05:48 AM

see the status port
 
the bit no 2 of parallel port status register (BASE + 1) contains IRQ status. may be u to have clear it before leaving the irq handler.

ghatamos 06-07-2006 06:01 AM

The error you are talking about is not really an error, it is just a warning that there is a type mismatch. You can ignore it

For your missing interrupt problems, I think you are not clearing the interrupt status bit in your interrupt handler so you are not getting the succeeding interrupts. Try adding in your handler code some status cleanup mechanism.

If that does not work, try disabling then re-enabling the interrupt in your handler and see if that helps.

James Scrymgeour 06-07-2006 06:22 AM

Thanks, I tried removing and adding handler but it still requires reset to pick up a second interrupt!!
The program works with the warning under redhat8.0, picking up multiple interrupts,

so i dont know if it is a vector linux problem or if it just handles it differently, and what you said is happening, Unfortunately my laptop im using isnt powerful enough for read hat 8.0, so currently trying to install slack 10.2, hoping that this will work.

jineshkj 06-07-2006 06:38 AM

Quote:

Originally Posted by James Scrymgeour
Thanks, I tried removing and adding handler but it still requires reset to pick up a second interrupt!!


so, have u added the code to reset the IRQ status in port 379? please post your modified interrupt handler code...

James Scrymgeour 06-07-2006 06:59 AM

Oh sorry jineshkj i see what you mean now, i thought you meant to remove the module and reload.

do you mean if i put into my handler routine 2 lines to clear then reset it to high to enable interrupts again like this?

static int handler(void)
{
// do stuff
printk(">>> PARALLEL PORT INT HANDLED\n");
outb_p(0x00, BASEPORT + 2);
outb_p(0x10, BASEPORT + 2);
return 0;
}

I havent yet tried this, will give it a go now, if this isnt what you mean please could you let me know!! thanks
James

jineshkj 06-07-2006 07:11 AM

i'm sorry, but what i meant was something like:

outb_p( inb_p(BASE+1) & ~(1<<2), BASE+1 );


to reset the "IRQ Status bit" in the "IRQ Status register".

James Scrymgeour 06-07-2006 07:16 AM

Ok, thanks I will try that.
sorry i am not very experienced with c and linux, took it on as a final year uni project (which is due in next week ahhhh!!) and have had to teach myself!!
Just getting vector back up and running now will post outcome!!

James Scrymgeour 06-07-2006 08:44 AM

Hi thanks very much for your time and help,
unfortunately what you suggested didnt make any difference, so i thought i would just have a play around with it adding different bits and pieces. and the code which works is as follows: (clearing the irq register and reloading it when an interrupt occurs)

#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <asm/io.h>

#define BASEPORT 0x378

static int handler(void)
{
// do stuff
printk(">>> PARALLEL PORT INT HANDLED\n");
outb_p(0x00, BASEPORT +2);
outb_p(0x10, BASEPORT +2);
return 0;

}

int xinit_module(void)
{
int ret;
ret = request_irq(7, handler, SA_INTERRUPT, "parallelport", NULL);


//set port to interrupt mode; pins are output
outb_p(0x00, BASEPORT + 2);
outb_p(0x10, BASEPORT + 2);

printk("wait for interrupt\n");
printk("return code %d \n", ret);
return 0;
}

void xcleanup_module(void)
{
disable_irq(7);
free_irq(7, NULL);
printk("closed\n");
}

module_init(xinit_module);
module_exit(xcleanup_module);
MODULE_LICENSE("GPL");


Quite strange though, the interrupt only works when i send a signal to set all the parallel port pins to high. I have pins 9 and 10 connected together, but tried leaving the port set at high and then touching the connectors together like an external switch but no interrupt generates, does anyone know any thing about this or why its doing it?
thanks
James

jineshkj 06-07-2006 11:20 PM

good to hear that the code is working now. see if u can get the book "The Indispensable PC Hardware Book" from ur library. it should give u most of the details of the most commonly used pc hardware and more...

James Scrymgeour 06-08-2006 10:53 AM

Sorted now thanks, just needed to condition the input signal! to make a nice square wave!!
Now all thats left to do is make the module interact with my user programs!
from what i understand before i try there is a fork command and exec which is what i require!!

Craftonix 01-11-2010 08:26 AM

A few Years Later ...
I have the same problem ...

The kernel changes but hard to make work simple things.

I just read :
www(dot)captain(dot)at (slash) howto-linux-kernel-parallel-port-interrupt(dot)php

And try to make it work under : Ubuntu Karmic Koala (Linux 2.6.31-16)

I added :
#define SA_INTERRUPT IRQF_DISABLED

SA_INTERRUPT seems deprecated

Further later when i make the :
sudo insmod ./parint.ko

and see what happen in dmesg ... i don't see any IRQ Handler Trace
and in cat /proc/interrupt i see no interrupt

I also try to kill all device attached to IRQ 7
sudo rmod lp
sudo rmod parport_pc
sudo rmod ppdev
sudo rmod parport

I also tested the older version skeleton.c from the same site

It does not work better but i see interrupt in cat /proc/interrupt.

Perhaps someone can help me figure out what happens ..

To generate IRQ i have a frequency generator Wired to the right pins of Parallel port.

Best Regards and Happy New Year

Ps: Sorry for link but site does not accept links (spam protection i suppose)


All times are GMT -5. The time now is 09:18 PM.