歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> arm6410按鍵驅動程序

arm6410按鍵驅動程序

日期:2017/3/1 9:56:02   编辑:Linux編程

通過查詢的方法獲取按鍵值
驅動程序 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");

Copyright © Linux教程網 All Rights Reserved