0

我正在使用並行端口驅動程序。現在我已經看到了從並行端口獲取中斷的方法。使用並行端口中斷

由它們中的一個,

首先使控制章第1條(IRQ)的第四引腳。 然後使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"); 

TEST.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); 
} 
+1

我建議你在這裏發佈一些代碼。 – marko

+0

byte = byte | 0x10的; // 0x10 = 00010000,CTRL寄存器的第4個引腳...是需要設置的端口的第4個引腳還是第4個引腳?因爲,如果它的第4個引腳,那麼十六進制值應該是0x8。沒有冒犯,你可以再次檢查。我告訴我所觀察到的。 – 2013-05-29 04:58:11

+0

對不起,我的錯誤。如果從0開始從LSB開始計數,則爲第4位。所以它是正確的。 –

回答

0

我知道了。

首先讓一個線程 把啓用IRQ代碼在該線程 所以每當我在我的硬件那麼它就會被中斷引腳連接,將繼續執行它 。

檢查此代碼爲您的參考。

#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");