Linux 内核空间与用户空间异步通信机制

来源:互联网 发布:windows update被禁用 编辑:程序博客网 时间:2024/05/29 10:43





/* * @fileexirq.c * @authorfzs * @date2016-12-13 */#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/console.h>#include <linux/sysrq.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/nmi.h>#include <linux/mutex.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/irqreturn.h>#include <linux/spinlock.h>#include <asm/io.h>#include <asm/irq.h>volatile unsigned int *pic_vaddr6 = NULL, *pic_vaddr5 = NULL;extern void open_softirq(int nr, void (*action)(struct softirq_action *));extern phys_addr_t get_immrbase(void);static atomic_t ex_interrupt_has_happen = ATOMIC_INIT(0);static wait_queue_head_t ex_interrupt;#define MPC85xx_PIC_EIVPR60x500c0#define WAIT_FOR_EXTERN_INTERRUPT0x1#if 1static irqreturn_t exirq_process ( int irq, void *dev_id ){int handled = 0;u32 regdata;//printk("come in irq_process \n");#if 1regdata = in_be32(pic_vaddr6);//printk("pic_eivpr6 value = %x \n", regdata);if(regdata & 0x40000000){atomic_set(&ex_interrupt_has_happen, 1);wake_up_interruptible(&ex_interrupt);}#endif//spin_lock(&i->lock);handled = 1;//spin_unlock(&i->lock);return IRQ_RETVAL(handled);}#endifstatic long exirq_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){                                                                                               switch (cmd)                                                                              {case WAIT_FOR_EXTERN_INTERRUPT://printk("wait for extern interrupt\n");wait_event_interruptible(ex_interrupt,atomic_read(&ex_interrupt_has_happen)!=0);atomic_set(&ex_interrupt_has_happen, 0);//printk("get an interrupt\n");break;default:printk("cmd=%d error\n",cmd);break;}return 0;}#if 0static struct timer_list test_timer;static void timer_action(unsigned long aa){atomic_set(&ex_interrupt_has_happen, 1);wake_up_interruptible(&ex_interrupt);test_timer.expires = jiffies+(HZ*10);add_timer(&test_timer);}#endifstatic struct file_operations exirq_fops = {         .owner = THIS_MODULE,         .unlocked_ioctl = exirq_ioctl};struct cdev exirq_cdev; int major;int exirq_int_init(void){unsigned int regdata = 0;int ret = 0;init_waitqueue_head(&ex_interrupt);atomic_set(&ex_interrupt_has_happen, 0);#if 1pic_vaddr6 = ioremap(get_immrbase() + MPC85xx_PIC_EIVPR6, 64);/* init EIVPR4 to 0x80000 */regdata = 0x80000; /* priority=8; vector=0 *///regdata |= 1<<22;out_be32(pic_vaddr6, regdata);/* init EIDR4 to let core process the int*/regdata  = 2;out_be32((pic_vaddr6+4), regdata);#endif/* we must use IRQF_SHARED mode. here IRQF_SHARED=0x80 */ret = request_irq(16, exirq_process, 0x80, "IRQ4",1); if (ret < 0) printk("irq4 request fail.\n");else printk("irq4 request success.\n");#if 0init_timer(&test_timer);test_timer.function = timer_action;test_timer.expires = jiffies + (HZ * 10);add_timer(&test_timer);#endifreturn 0;}static struct class *exirq_cls;dev_t dev_id;static int __init exirq_init(void)  {    printk("exirq init...\n");  exirq_int_init();alloc_chrdev_region(&dev_id, 0, 1, "exirq");major = MAJOR(dev_id);cdev_init(&exirq_cdev, &exirq_fops);cdev_add(&exirq_cdev, dev_id, 1);exirq_cls = class_create(THIS_MODULE, "exirq");device_create(exirq_cls, NULL, dev_id, NULL, "exirq");/* for test *//*fpga_int_register_callback(0,test1);fpga_int_register_callback(1,test2);*/  return 0;  }  static void __exit exirq_exit(void)  {     printk(KERN_ALERT "exirq driver exit\n");device_destroy(exirq_cls, MKDEV(major, 0));    class_destroy(exirq_cls); /* 3.3 删除cdev*/cdev_del(&exirq_cdev); /* 3.4 释放设备号*/unregister_chrdev_region(MKDEV(major, 0), 1);free_irq(16,1);}  module_init(exirq_init);  module_exit(exirq_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("fzs");

















/* * @fileexirq.c * @authorfzs * @date2016-12-13 */#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/console.h>#include <linux/sysrq.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/nmi.h>#include <linux/mutex.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/irqreturn.h>#include <linux/spinlock.h>#include <asm/io.h>#include <asm/irq.h>volatile unsigned int *pic_vaddr6 = NULL, *pic_vaddr5 = NULL;extern void open_softirq(int nr, void (*action)(struct softirq_action *));extern phys_addr_t get_immrbase(void);static atomic_t ex_interrupt_has_happen = ATOMIC_INIT(0);static wait_queue_head_t ex_interrupt;#define MPC85xx_PIC_EIVPR60x500c0#define WAIT_FOR_EXTERN_INTERRUPT0x1#if 1static irqreturn_t exirq_process ( int irq, void *dev_id ){int handled = 0;u32 regdata;//printk("come in irq_process \n");#if 1regdata = in_be32(pic_vaddr6);//printk("pic_eivpr6 value = %x \n", regdata);if(regdata & 0x40000000){atomic_set(&ex_interrupt_has_happen, 1);wake_up_interruptible(&ex_interrupt);}#endif//spin_lock(&i->lock);handled = 1;//spin_unlock(&i->lock);return IRQ_RETVAL(handled);}#endifstatic long exirq_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){                                                                                               switch (cmd)                                                                              {case WAIT_FOR_EXTERN_INTERRUPT://printk("wait for extern interrupt\n");wait_event_interruptible(ex_interrupt,atomic_read(&ex_interrupt_has_happen)!=0);atomic_set(&ex_interrupt_has_happen, 0);//printk("get an interrupt\n");break;default:printk("cmd=%d error\n",cmd);break;}return 0;}#if 0static struct timer_list test_timer;static void timer_action(unsigned long aa){atomic_set(&ex_interrupt_has_happen, 1);wake_up_interruptible(&ex_interrupt);test_timer.expires = jiffies+(HZ*10);add_timer(&test_timer);}#endifstatic struct file_operations exirq_fops = {         .owner = THIS_MODULE,         .unlocked_ioctl = exirq_ioctl};struct cdev exirq_cdev; int major;int exirq_int_init(void){unsigned int regdata = 0;int ret = 0;init_waitqueue_head(&ex_interrupt);atomic_set(&ex_interrupt_has_happen, 0);#if 1pic_vaddr6 = ioremap(get_immrbase() + MPC85xx_PIC_EIVPR6, 64);/* init EIVPR4 to 0x80000 */regdata = 0x80000; /* priority=8; vector=0 *///regdata |= 1<<22;out_be32(pic_vaddr6, regdata);/* init EIDR4 to let core process the int*/regdata  = 2;out_be32((pic_vaddr6+4), regdata);#endif/* we must use IRQF_SHARED mode. here IRQF_SHARED=0x80 */ret = request_irq(16, exirq_process, 0x80, "IRQ4",1); if (ret < 0) printk("irq4 request fail.\n");else printk("irq4 request success.\n");#if 0init_timer(&test_timer);test_timer.function = timer_action;test_timer.expires = jiffies + (HZ * 10);add_timer(&test_timer);#endifreturn 0;}static struct class *exirq_cls;dev_t dev_id;static int __init exirq_init(void)  {    printk("exirq init...\n");  exirq_int_init();alloc_chrdev_region(&dev_id, 0, 1, "exirq");major = MAJOR(dev_id);cdev_init(&exirq_cdev, &exirq_fops);cdev_add(&exirq_cdev, dev_id, 1);exirq_cls = class_create(THIS_MODULE, "exirq");device_create(exirq_cls, NULL, dev_id, NULL, "exirq");/* for test *//*fpga_int_register_callback(0,test1);fpga_int_register_callback(1,test2);*/  return 0;  }  static void __exit exirq_exit(void)  {     printk(KERN_ALERT "exirq driver exit\n");device_destroy(exirq_cls, MKDEV(major, 0));    class_destroy(exirq_cls); /* 3.3 删除cdev*/cdev_del(&exirq_cdev); /* 3.4 释放设备号*/unregister_chrdev_region(MKDEV(major, 0), 1);free_irq(16,1);}  module_init(exirq_init);  module_exit(exirq_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("fzs");














0 0
原创粉丝点击