本文主要是介绍驱动:irq中断,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
按键中断
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <asm-generic/errno-base.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/wait.h>
#include <linux/sched.h>#define DEV_NAME "key"static wait_queue_head_t wq;
static int condition = 0;irqreturn_t irq_handler(int num, void * arg)
{printk("num = %d arg = %d\n", num, *(int *)arg);condition = 1;wake_up_interruptible(&wq);return IRQ_HANDLED;
}static int open (struct inode * inode, struct file * file)
{printk("key open ...\n");return 0;
}static ssize_t read (struct file * file, char __user * buf, size_t len, loff_t * offset)
{//copy_to_user(buf, &value, sizeof(value));condition = 0;wait_event_interruptible(wq, condition);printk("key read ...\n");return 4;
}static ssize_t write (struct file * file, const char __user * buf, size_t len, loff_t * offset)
{return 0;
}static int close (struct inode * inode, struct file * file)
{printk("key close ...\n");return 0;
}static struct file_operations fops =
{.owner = THIS_MODULE,.open = open,.read = read,.write = write,.release = close
};static struct miscdevice misc =
{.minor = MISC_DYNAMIC_MINOR,.name = DEV_NAME,.fops = &fops
};static int arg = 100;static int __init key1_init(void)
{int ret = misc_register(&misc);if(ret < 0)goto err_misc_register;ret = request_irq(IRQ_EINT8, irq_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, "key_irq", &arg); if(ret < 0)goto err_request_irq;init_waitqueue_head(&wq);printk("key_init ...\n");return ret;err_misc_register:misc_deregister(&misc);printk("key misc_register faikey\n"); return ret;err_request_irq:disable_irq(IRQ_EINT8);free_irq(IRQ_EINT8, &arg);return ret;
}static void __exit key_exit(void)
{disable_irq(IRQ_EINT8);free_irq(IRQ_EINT8, &arg);misc_deregister(&misc);printk("key_exit ###############################\n");
}module_init(key1_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");
adc
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <asm-generic/errno-base.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/wait.h>
#include <linux/sched.h>#define DEV_NAME "adc"
#define ADCCON 0x58000000
#define ADCDAT0 0x5800000C
#define CLKCON 0x4C00000C
static volatile unsigned long * adccon;
static volatile unsigned long * adcdat0;
static volatile unsigned long * clkcon;static wait_queue_head_t wq;
static int condition = 0;irqreturn_t irq_handler(int num, void * arg)
{printk("num = %d arg = %d\n", num, *(int *)arg);condition = 1;wake_up_interruptible(&wq);return IRQ_HANDLED;
}static void init_adc(void)
{*adccon = (1 << 14) | (49 << 6);
}static void start_adc(void)
{*adccon |= (1 << 0);
}static unsigned short read_adc(void)
{unsigned short data = *adcdat0 & 0x3ff;return data;
}static int open (struct inode * inode, struct file * file)
{init_adc();printk("adc open ...\n");return 0;
}static ssize_t read (struct file * file, char __user * buf, size_t len, loff_t * offset)
{//copy_to_user(buf, &value, sizeof(value));unsigned short value = 0;printk("adc read start ...\n");condition = 0;start_adc(); wait_event_interruptible(wq, condition);value = read_adc();copy_to_user(buf, &value, sizeof(value));printk("adc read ...\n");return sizeof(value);
}static ssize_t write (struct file * file, const char __user * buf, size_t len, loff_t * offset)
{return 0;
}static int close (struct inode * inode, struct file * file)
{printk("adc close ...\n");return 0;
}static struct file_operations fops =
{.owner = THIS_MODULE,.open = open,.read = read,.write = write,.release = close
};static struct miscdevice misc =
{.minor = MISC_DYNAMIC_MINOR,.name = DEV_NAME,.fops = &fops
};static int arg = 100;static int __init adc_init(void)
{int ret = misc_register(&misc);if(ret < 0)goto err_misc_register;ret = request_irq(IRQ_ADC, irq_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, "adc_irq", &arg); if(ret < 0)goto err_request_irq;adccon = ioremap(ADCCON, sizeof(*adccon));adcdat0 = ioremap(ADCDAT0, sizeof(*adcdat0));clkcon = ioremap(CLKCON, sizeof(*clkcon));*clkcon |= (1 << 15);printk("clkcon = 0x%lx\n", *clkcon);init_waitqueue_head(&wq);printk("adc_init ...\n");return ret;err_misc_register:misc_deregister(&misc);printk("adc misc_register faiadc\n"); return ret;err_request_irq:disable_irq(IRQ_ADC);free_irq(IRQ_ADC, &arg);return ret;
}static void __exit adc_exit(void)
{iounmap(clkcon);iounmap(adcdat0);iounmap(adccon);disable_irq(IRQ_ADC);free_irq(IRQ_ADC, &arg);misc_deregister(&misc);printk("adc_exit ###############################\n");
}module_init(adc_init);
module_exit(adc_exit);
MODULE_LICENSE("GPL");
应用层adc
1 #include <fcntl.h> 2 #include <stdio.h>3 #include <stdlib.h>4 #include <string.h>5 #include <unistd.h>6 7 int main(int argc, const char *argv[])8 {9 int fd = open("/dev/adc",O_RDWR);10 if (fd < 0)11 {12 perror("open adc fail");13 return -1;14 }15 16 unsigned short value = 0;17 while(1)18 {19 int ret = read(fd, &value, sizeof(value));20 float v = 3.3 * value / 1024.0;21 printf("ret = %d adc value = %d v = %.3f\n",ret, value,v);22 sleep(2);23 }24 25 close(fd);26 return 0;27 }
这篇关于驱动:irq中断的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!