我正在研究并行端口驱动程序。现在我已经看到了从并行端口获取中断的方法。
由其中之一,
首先制作控制寄存器 1(IRQ)的第 4 个引脚。然后使 nACK 低。
所以我在数据引脚 8 和 nACK 之间进行了切换。所以,如果我写一些具有 msb 1 的数据,那么如果该开关打开,它将被中断。现在我有一个问题。如果我断开该开关并再次连接,那么它不会给我中断。
那么,我怎么能做我通过开关被中断的事情是连接与否。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/parport.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <asm/irq.h>
#include <linux/kthread.h>
#define DEVICE_NAME "parlelport"
struct pardevice *pdev;
static int dummy;
int ret;
static irqreturn_t recv_handler(int irq, void *dev_id)
{
printk("we inside if isr");
return 0;
}
int led_open(struct inode *inode, struct file *file)
{
printk("1\n");
printk("Device File Opened\n");
char byte1;
byte1=inb(0x37A);
printk("%d \n",byte1);
return 0;
}
ssize_t led_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
printk("2\n");
char byte=inb(0x37A);
printk("%d",byte);
byte = byte | 0x10; // 0x10= 00010000, 4th pin of CTRL reg
outb(byte, 0x37A); //which enable IRQ
char kbuf;
copy_from_user(&kbuf, buf, 1);
parport_claim_or_block(pdev); /* Claim the port */
parport_write_data(pdev->port, kbuf); /* Write to the device */
//parport_release (pdev);
return count;
}
int led_release(struct inode *inode, struct file *file)
{
printk("3\n");
printk("Device File Released\n");
char byte;
byte=inb(0x37A);
printk("%d", byte);
return 0;
}
static struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
.write = led_write,
.release = led_release,
};
static int led_preempt(void *handle)
{
printk("4\n");
return 1;
}
static void led_attach(struct parport *port)
{
printk("5\n");
pdev = parport_register_device(port, DEVICE_NAME, led_preempt, NULL, NULL, 0, NULL);
printk("Port attached\n");
char byte1;
byte1=inb(0x37A);
printk("%d \n",byte1);
}
static void led_detach(struct parport *port)
{
printk("6\n");
parport_unregister_device (pdev);
printk("Port Deattached\n");
}
static struct parport_driver led_driver = {
.name= "led",
.attach = led_attach,
.detach = led_detach,
};
int __init led_init(void)
{
printk("7\n");
if (register_chrdev(89, DEVICE_NAME, &led_fops))
{
printk("Can't register device\n");
return -1;
}
char byte=inb(0x37A);
printk("%d",byte);
byte = byte | 0x10;
outb(byte, 0x37A);
char byte1;
byte1=inb(0x37A);
printk("%d %d \n",byte,byte1);
parport_register_driver(&led_driver);
ret= request_irq(7, recv_handler, IRQF_SHARED, "parlelport", &dummy);
printk("%d",ret);
return 0;
}
void __exit led_cleanup(void)
{
printk("8\n");
unregister_chrdev(89, DEVICE_NAME);
if(!ret)
free_irq(7, &dummy);
parport_unregister_driver(&led_driver);
printk("LED Driver unregistered.\n");
return;
}
module_init(led_init);
module_exit(led_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vikrant Patel");
测试.c 文件
int main()
{
int fd=open("/dev/parlelport",O_RDWR);
char byte;
printf("Enter Value to send on parallel port");
scanf("%c",&byte);
printf("Byte value is %c\n",byte);
if(write(fd,&byte,sizeof(char)))
{
printf("\nSuccessfully written on port");
}
getchar();
getchar();
close(fd);
}