gpt4 book ai didi

linux - 使用并行端口中断

转载 作者:太空宇宙 更新时间:2023-11-04 11:22:59 26 4
gpt4 key购买 nike

我正在研究并口驱动程序。现在我已经看到了从并口获取中断的方法。

其中一个,

First make 4th pin of control reg 1(IRQ). then make nACK low.

所以我在数据引脚 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);
}

最佳答案

我明白了。

First make a thread put the Enable IRQ code in that thread so it will continuously execute it whenever i connect pins at my hardware then it will be interrupted.

检查此代码以供引用。

#include <linux/module.h>
#include <linux/parport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>

#define DEVICE_NAME "parlelport"
#define DATA 0x378
#define STATUS 0x379
#define CONTROL 0x37A

struct pardevice *pdev;
struct task_struct *ts1, *ts2;

int dummy;
char buf1='1',buf2='2';
char byte='0';

int thread1(void *data)
{
while(1)
{
outb(byte, CONTROL); /* 0x30 = 0011 0000 , makes IRQ pin(5th bit) enable */

printk("Thread1\n");
parport_claim_or_block(pdev); /* Claim the port */
parport_write_data(pdev->port, buf1); /* Write to the device */
parport_release(pdev); /* Release the port */

msleep(4000);
if (kthread_should_stop())
break;

}
return 0;
}


int thread2(void *data)
{
while(1)
{
outb(byte,CONTROL); /* 0x30 = 0011 0000 , makes IRQ pin(5th bit) enable */

printk("Thread2\n");
parport_claim_or_block(pdev); /* Claim the port */
parport_write_data(pdev->port, buf2); /* Write to the device */
parport_release(pdev); /* Release the port */

msleep(4000);
if (kthread_should_stop())
break;

}
return 0;
}


int led_open(struct inode *inode, struct file *file)
{
printk("Device File Opened\n");

ts1=kthread_run(thread1,NULL,"kthread"); /* Initiation of thread 1 */
msleep(2000);
ts2=kthread_run(thread2,NULL,"kthread"); /* Initiation of thread 2 */

return 0;
}

ssize_t led_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
return count;
}

int led_release(struct inode *inode, struct file *file)
{
printk("Device File Released\n");
kthread_stop(ts1);
kthread_stop(ts2);

buf1='1';
buf2='2';

outb_p(0x00,DATA);
return 0;
}

static irqreturn_t recv_handler(int irq, void *unused)
{
printk("we inside of isr");

buf1= buf1 ^ 0x7F;
buf2= buf2 ^ 0x7F;

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)
{
return 1;
}

static void led_attach(struct parport *port)
{
pdev = parport_register_device(port, DEVICE_NAME, led_preempt, NULL, NULL, 0, NULL);
printk("Port attached\n");
}

static void led_detach(struct parport *port)
{
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)
{

/*Register our ISR with the kernel for PARALLEL_IRQ */
if (request_irq(7, recv_handler, IRQF_SHARED, DEVICE_NAME ,&dummy))
{
printk("Registering ISR failed\n");
return -ENODEV;
}

/*Register Character Device Driver at 89 Major number*/
if (register_chrdev(89, DEVICE_NAME, &led_fops))
{
printk("Can't register device\n");
return -1;
}

/*Register parallel port driver with parport structure led_driver*/
parport_register_driver(&led_driver);

return 0;

}



void __exit led_cleanup(void)
{
unregister_chrdev(89, DEVICE_NAME); /* Unregister char driver */
free_irq(7, &dummy); /* Free the ISR from IRQ7 */
parport_unregister_driver(&led_driver); /* Unregister the parallel port driver */

printk("LED Driver unregistered.\n");
return;
}

module_init(led_init);
module_exit(led_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vikrant Patel");

关于linux - 使用并行端口中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16791374/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com