Linux按键驱动程序设计(6)-驱动支持多按键优化

  • 在前面的基础上,实现多按键中断,这里实现2个,k1,k3。
  • 通过应用程序,打印出产生中断的key号。
  • 代码如下:
  • key.c
 #include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/uaccess.h>

#define GPGCON 0x56000060
#define GPGDAT 0x56000064

struct work_struct *key_work; 
struct timer_list key_timer;

unsigned int *gpio_data;
unsigned int key_num;

// 工作队列函数
void key_work_func(struct work_struct *work)
{
    mod_timer(&key_timer, jiffies + HZ/10);  // 延时100ms	
}

// 判断按键是否真正按下
void key_timer_func(unsigned long data)
{
    unsigned short key_vall;
    key_vall = readw(gpio_data)&0x01;    
    if (key_vall == 0)
	{
		printk("key1 down!\n");
		key_num = 1;
	}
		
    key_vall = readw(gpio_data)&0x20;    
    if (key_vall == 0)
	{
		printk("key3 down!\n");
		key_num = 3;
	}
}

// 中断处理函数
irqreturn_t key_int(int irq, void *dev_id)
{
    // 1.检测是否发生了按键中断	
    
    // 2.清除已经发生的按键中断
    
    // 3.提交下半部分
    schedule_work(key_work);
    
    return 0;
}

// 按键的初始化函数
void key_hw_init()
{
    unsigned int *gpio_config;
    unsigned int data;
    
    gpio_config = ioremap(GPGCON, 4);	
    data = readl(gpio_config);
    data &= ~0xc03;        // 设置GPIO寄存器
    data |= 0x802;
    writel(data, gpio_config);	
    
    gpio_data = ioremap(GPGDAT, 4);	
}                                                

int key_open(struct inode *node, struct file *filp)
{
    return 0;
}

ssize_t key_read (struct file *filp, char __user *buf, size_t size, loff_t *pos)
{	
    copy_to_user(buf, &key_num, 4);
    
    return 4;	
}

const struct file_operations key_fops = 
{	
    .open = key_open,
    .read = key_read,		
};

// 初始化miscdevice
struct miscdevice key_miscdev = 
{
    .minor = 200,
    .name = "mykey",
    .fops = &key_fops,
};	

static int button_init()
{
    // 注册miscdevice
    misc_register(&key_miscdev);
    
    // 注册中断处理程序
    request_irq(IRQ_EINT8, key_int, IRQF_TRIGGER_FALLING, "mykey", 0);  // K1
    request_irq(IRQ_EINT13, key_int, IRQF_TRIGGER_FALLING, "mykey", 0);  // K3  
    
    // 按键初始化
    key_hw_init();
    
    // 创建工作1
    key_work = kmalloc(sizeof(struct work_struct), GFP_KERNEL);
    INIT_WORK(key_work, key_work_func);
    
    // 初始化定时器
    init_timer(&key_timer);
    key_timer.function = key_timer_func;
    
    // 注册定时器
    add_timer(&key_timer);
    
    return 0;		
}

static void button_exit()
{	
     // 注销miscdevice
    misc_deregister(&key_miscdev);  
    
    // 注销中断处理程序
    free_irq(IRQ_EINT8, 0);
    free_irq(IRQ_EINT13, 0);
}

MODULE_LICENSE("GPL");

module_init(button_init);
module_exit(button_exit);
  • key_app.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd;
    int key_num;   
   
    // 打开设备文件
    fd = open("/dev/mini2440key",0);
    
    if (fd < 0)
        printf("open device fail!\n");
    
    // 读取设备
    read(fd, &key_num, 4);
    printf("key is %d\n",key_num);
    
    // 关闭设备 
    close(fd);	
		
}
  • 编译后把key.ko安装到开饭板中,
    • #insmod key.ko
  • 创建设备文件,由于按键驱动程序可以分成混杂设备,主设备号统一为10,次设备号自己定义,这里为200
    • mknod dev/mini2440key c 10 200
  • 运行结果

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值