linux 中断


中断

gpio子系统

一系列关于GPIO设置的函数linux-3.5/arch/arm/mach-exynos/include/mach/

测试gpio端口是否合法
int gpio_is_valid(int number);

申请某个gpio端口当然在申请之前需要显示的配置该gpio端口的pinmux
int gpio_request(unsigned gpio, const char *label)

标记gpio的使用方向包括输入还是输出
/*成功返回零失败返回负的错误值*/
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);

获得gpio引脚的值和设置gpio引脚的值(对于输出)
int gpio_get_value(unsigned gpio);
void gpio_set_value(unsigned gpio, int value);

gpio当作中断口使用
int gpio_to_irq(unsigned gpio);
返回的值即中断编号可以传给request_irq()和free_irq()

导出gpio端口到用户空间
int gpio_export(unsigned gpio, bool direction_may_change);
/* 撤销GPIO的导出 */
void gpio_unexport();

request_irq
free_irq

 

了解一些关于中断的知识,下面开始写驱动

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/miscdevice.h>
  4 #include <linux/fs.h>
  5 #include <linux/interrupt.h>
  6 #include <linux/gpio.h>
  7 #include <mach/gpio.h>
  8 #include <asm-generic/ioctl.h>
  9 #include <asm/uaccess.h>
 10 
 11 #define     MAGIC                     'B'
 12 #define     GET_BTN_VAL              _IOR(MAGIC, 1, unsigned long)
 13 
 14 typedef struct
 15 {
 16     unsigned int gpio;
 17     unsigned int btn;
 18     unsigned int irq;
 19     char*        name;
 20 }irq_typedef;
 21 
 22 static irq_typedef irqsource[] =
 23 {
 24     {EXYNOS4_GPX3(2),1,0,"btn1"},
 25     {EXYNOS4_GPX3(3),2,0,"btn2"},
 26     {EXYNOS4_GPX3(4),3,0,"btn3"},
 27     {EXYNOS4_GPX3(5),4,0,"btn4"}
 28 };
 29 
 30 static unsigned long btn_num;
 31 
 32 static irqreturn_t gpio_irq_handler(int irq, void *dev)
 33 {
 34     irq_typedef* curdev = (irq_typedef *)dev;
 35 
 36     printk("%s\n",curdev->name);
 37     printk("btn(drv):%d\n",curdev->btn);
 38 
 39     btn_num = curdev->btn;
 40     
 41     return 0;
 42 }
 43 
 44 static long btn_ioctl(struct file *fil, unsigned int cmd, unsigned long arg)
 45 {
 46     unsigned long ret;
 47     void __user *argp = (void __user *)arg;
 48 
 49     switch(cmd)
 50     {
 51         case GET_BTN_VAL:
 52             //ret = copy_to_user((void __user *) argp, (void *)&btn_num,4);
 53              put_user(btn_num, (unsigned int __user *) argp);
 54             break;
 55         default:return -EINVAL;
 56     }
 57     
 58     return 0;
 59 }
 60 
 61 
 62 static struct file_operations btn_irq_fops =
 63 {
 64     .owner            = THIS_MODULE,
 65     .unlocked_ioctl    = btn_ioctl,
 66 };
 67 
 68 static struct miscdevice btn_irq_misc = 
 69 {
 70     .minor        = 255,
 71     .name        = "btn",
 72     .fops        = &btn_irq_fops,
 73 };
 74 
 75 static __init int btn_irq_init(void)
 76 {
 77     int i,ret;
 78 
 79     misc_register(&btn_irq_misc);
 80 
 81     for(i=0;i<4;i++)
 82     {
 83         irqsource[i].irq = gpio_to_irq(irqsource[i].gpio);
 84         ret = request_irq(irqsource[i].irq,gpio_irq_handler,IRQF_TRIGGER_FALLING,irqsource[i].name, &irqsource[i]);
 85     }
 86     
 87     return ret;
 88 }
 89 
 90 static __exit void btn_irq_exit(void)
 91 {
 92     int i;
 93 
 94     for(i=0;i<4;i++)
 95         free_irq(irqsource[i].irq, &irqsource[i]);
 96 
 97     misc_deregister(&btn_irq_misc);
 98 }
 99 
100 module_init(btn_irq_init);
101 module_exit(btn_irq_exit);
102 MODULE_LICENSE("GPL");
 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/stat.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <stdlib.h>
 7 #include <sys/ioctl.h>
 8 
 9 #define     MAGIC                     'B'
10 #define     GET_BTN_VAL              _IOR(MAGIC, 1, unsigned long)
11 
12 int main(int argc,char *argv[])
13 {
14     int btn_fd,btn_val=0;
15 
16     if(argc!=2)
17     {
18         printf("Usage:<%s> </dev/?node>\n",argv[0]);
19         return -1;
20     }
21 
22     btn_fd = open(argv[1],O_RDONLY);    
23 
24     while(1)
25     {
26         ioctl(btn_fd,GET_BTN_VAL,btn_val);
27         //ioctl(btn_fd,GET_BTN_VAL,&btn_val);
28         sleep(1);
29 
30         printf("btn_val(irq):%d\n",btn_val);
31     }
32 }
 1 obj-m    += btnirq.o
 2 SOURCE = btntest.o
 3 
 4 CROSS_COMPLIE = arm-linux-
 5 CC = $(CROSS_COMPLIE)gcc
 6 
 7 KERNDIR = /centos/xyd/linux-3.5
 8 #CURDIR  = $(shell pwd)
 9 CURDIR  = `pwd`
10 
11 .PHONY: module clean
12 
13 all: module $(SOURCE:.o=)
14 
15 module:
16     $(MAKE) -C $(KERNDIR) M=$(CURDIR) modules
17 
18 $(SOURCE:.o=):$(SOURCE)
19     $(CC) -o $@ $^
20 
21 %.o:%.c
22     $(CC) -c $<
23 
24 clean:
25     $(MAKE) -C $(KERNDIR) M=$(CURDIR) clean
26     rm $(SOURCE:.o=)

 

posted @ 2017-06-09 11:26  root-linux  阅读(238)  评论(0编辑  收藏  举报