[Linux]中断按键

[Linux]中断按键

艾恩凝

2021/4/6

INTRODUCIOTN

利用中断减小资源使用

CODE

  1#include <linux/module.h>
  2#include <linux/kernel.h>
  3#include <linux/fs.h>
  4#include <linux/init.h>
  5#include <linux/delay.h>
  6#include <linux/irq.h>
  7#include <asm/uaccess.h>
  8#include <asm/irq.h>
  9#include <asm/io.h>
 10#include <asm/arch/regs-gpio.h>
 11#include <asm/hardware.h>
 12
 13#define BUTTON_MAJOR_NUMBER 200
 14#define DEVICE_NAME  "button_drv"
 15
 16static struct class *button_drv_class;
 17static struct class_device	*button_drv_class_dev;
 18
 19volatile unsigned long *GPFCON;
 20volatile unsigned long *GPFDAT;
 21
 22volatile unsigned long *GPGCON;
 23volatile unsigned long *GPGDAT;
 24
 25static int button_drv_close(struct inode *inode, struct file *file);
 26
 27static DECLARE_WAIT_QUEUE_HEAD(button_waitq);//register interrupt
 28static volatile int ev_press = 0;//interrupt flags,if interrupt will  set 1 
 29
 30struct pins_desc{
 31	unsigned int pin;
 32	unsigned int key_val;
 33};
 34static unsigned char key_val;
 35struct pins_desc pins_descs[4] = {
 36	{S3C2410_GPF0, 0x01},
 37	{S3C2410_GPF2, 0x02},
 38	{S3C2410_GPG3, 0x03},
 39	{S3C2410_GPG11, 0x04},
 40};
 41
 42
 43static irqreturn_t buttons_irq(int irq, void *dev_id){
 44	struct pins_desc * pindesc = (struct pins_desc *)dev_id;
 45	unsigned int pinval;
 46
 47	pinval = s3c2410_gpio_getpin(pindesc->pin);
 48
 49	if (pinval)
 50	{
 51		/* 松开 */
 52		key_val = 0x80 | pindesc->key_val;
 53	}
 54	else
 55	{
 56		/* 按下 */
 57		key_val = pindesc->key_val;
 58	}
 59
 60    ev_press = 1;                  /* interrupt  */
 61    wake_up_interruptible(&button_waitq);   /* wake up */
 62
 63
 64	return IRQ_RETVAL(IRQ_HANDLED);
 65}
 66
 67static int button_drv_open(struct inode *inode,struct file *file){
 68    // *GPFCON &= ~((0x3<<(0*2)) | (0x3<<(2*2)));
 69    // *GPGCON &= ~((0x3<<(3*2)) | (0x3<<(11*2)));
 70    //request_irq(IRQ_EINT0,button_irq,);
 71    request_irq(IRQ_EINT0,  buttons_irq, IRQT_BOTHEDGE, "S2", &pins_descs[0]);
 72	request_irq(IRQ_EINT2,  buttons_irq, IRQT_BOTHEDGE, "S3", &pins_descs[1]);
 73	request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_descs[2]);
 74	request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_descs[3]);
 75    return 0;
 76}
 77
 78static ssize_t button_drv_read(struct file *file, const char __user *buf, size_t count, loff_t * ppos){
 79	if (count != 1)
 80		return -EINVAL;
 81	wait_event_interruptible(button_waitq, ev_press);//sleep
 82	copy_to_user(buf, &key_val, sizeof(key_val));
 83	ev_press = 0;
 84    return 1;
 85}
 86//copy_from_user
 87
 88static struct file_operations button_drv_fops = {
 89    .owner   =   THIS_MODULE,  
 90    .open    =   button_drv_open,   
 91	.read	 =	 button_drv_read,
 92	.release =   button_drv_close,
 93};
 94
 95static int  button_drv_init(void){
 96    register_chrdev(BUTTON_MAJOR_NUMBER,DEVICE_NAME, &button_drv_fops);//register tell kernel
 97    button_drv_class = class_create(THIS_MODULE, DEVICE_NAME);
 98    button_drv_class_dev = class_device_create(button_drv_class, NULL, MKDEV(BUTTON_MAJOR_NUMBER, 0), NULL, DEVICE_NAME);
 99   
100    GPFCON = (volatile unsigned long *)ioremap(0x56000050, 16);
101	GPFDAT = GPFCON + 1;
102
103    GPGCON = (volatile unsigned long *)ioremap(0x56000060, 16);
104	GPGDAT = GPGCON + 1;
105   
106    return 0;
107}
108
109static void  button_drv_exit(void){
110    unregister_chrdev(BUTTON_MAJOR_NUMBER, DEVICE_NAME);//unregister tell kernel
111    class_device_unregister(button_drv_class_dev);
112	class_destroy(button_drv_class);
113	iounmap(GPFCON);
114	iounmap(GPGCON);
115}
116static int button_drv_close(struct inode *inode, struct file *file)
117{
118	free_irq(IRQ_EINT0, &pins_descs[0]);
119	free_irq(IRQ_EINT2, &pins_descs[1]);
120	free_irq(IRQ_EINT11, &pins_descs[2]);
121	free_irq(IRQ_EINT19,&pins_descs[3]);
122	return 0;
123}
124
125module_init(button_drv_init);
126module_exit(button_drv_exit);
127MODULE_AUTHOR("https://aeneag.xyz");
128MODULE_VERSION("0.1");
129MODULE_DESCRIPTION("S3C2440 Button Driver");
130MODULE_LICENSE("GPL");
131

CONCLUSION

不想多说话了,代码好写,需要理解东西比较多


    


公众号'艾恩凝'
个人公众号
个人微信
个人微信
    吾心信其可行,
          则移山填海之难,
                  终有成功之日!
                                  ——孙文
    评论
    0 评论
avatar

取消