通過查詢的方法獲取按鍵值
驅動程序 botton_drive.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/device.h>
//#include <asm/arch/regs-gpio.h>
//#include <asm/hardware.h>
static struct class *seconddrv_class;
static struct class_device*seconddrv_class_dev;
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpncon = NULL;
volatile unsigned long *gpndat = NULL;
static int second_drv_open(struct inode *inode, struct file *file)
{
//printk("second_drv_open\n");
/* 配置GPm0,1,2,3為輸出 */
*gpmcon &= ~((0xf<<(4*0)) | (0xf<<(4*1)) | (0xf<<(4*2)) | (0xf<<(4*3)));
*gpmcon |= ((0x1<<(4*0)) | (0x1<<(4*1)) | (0x1<<(4*2)) | (0x1<<(4*3)));
/* 配置GPn0,1,2,3,4,5為輸入 */
*gpncon &= ~((0x3<<(2*0)) | (0x3<<(2*1)) | (0x3<<(2*2)) | (0x3<<(2*3)) | (0x3<<(2*4)) | (0x3<<(2*5)));
//*gpncon |= ((0xf<<(4*0)) | (0xf<<(4*1)) | (0xf<<(4*2)) | (0xf<<(4*3)) | (0xf<<(4*4)) | (0xf<<(4*5)));
return 0;
}
static ssize_t second_drv_read(struct file *file, const char __user *buf, size_t size, loff_t * ppos)
{
unsigned char KEY_val[6];
if(size != sizeof(KEY_val))
return -EINVAL;
int regval;
regval = *gpndat;
/* 讀出個個引腳的狀態 */
KEY_val[0] = (regval & 1<<0) ? 1:0;
KEY_val[1] = (regval & 1<<1) ? 1:0;
KEY_val[2] = (regval & 1<<2) ? 1:0;
KEY_val[3] = (regval & 1<<3) ? 1:0;
KEY_val[4] = (regval & 1<<4) ? 1:0;
KEY_val[5] = (regval & 1<<5) ? 1:0;
/* 傳遞給用戶 */
copy_to_user(buf, KEY_val, sizeof(KEY_val));
return sizeof(KEY_val);
}
static struct file_operations second_drv_fops = {
.owner = THIS_MODULE, /* 這是一個宏,推向編譯模塊時自動創建的__this_module變量 */
.open = second_drv_open,
.read= second_drv_read,
};
int major;
static int second_drv_init(void)
{
//printk(KERN_ERR "second_drv_init\n");
major = register_chrdev(0, "secondt_drv", &second_drv_fops); // 注冊, 告訴內核
seconddrv_class = class_create(THIS_MODULE, "seconddrv");
seconddrv_class_dev = device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "bottons"); /* /dev/bottons */
gpmcon = (volatile unsigned long *)ioremap(0x7F008820, 16);
gpmdat = gpmcon + 1;
gpncon = (volatile unsigned long *)ioremap(0x7F008830, 16);
gpndat = gpncon + 1;
return 0;
}
static void second_drv_exit(void)
{
//printk(KERN_ERR "second_drv_exit\n");
unregister_chrdev(major, "second_drv"); // 卸載
device_unregister(seconddrv_class_dev);
class_destroy(seconddrv_class);
iounmap(gpmcon);
iounmap(gpncon);
}
module_init(second_drv_init);
module_exit(second_drv_exit);
MODULE_LICENSE("GPL");