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=)