一、驱动源码
硬件原理图
#include "nuc972_gpio.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define KEY_DEV_NUMS 1
#define KEY_NAME "key"
struct key_dev{
dev_t devid;
int major;
int minor;
struct cdev cdev;
struct class *class;
struct device *device;
};
struct key_dev key;
/* */
#define SET_DIR 0X0100
#define GET_DIR 0X0200
#define SET_ODR 0X0300
#define GET_ODR 0X0400
#define GET_IDR 0X0500
#define GPIOA 0x0000
#define GPIOB 0x0001
#define GPIOC 0x0002
#define GPIOD 0x0003
#define GPIOE 0x0004
#define GPIOF 0x0005
#define GPIOG 0x0006
#define GPIOH 0x0007
#define GPIOI 0x0008
#define GPIOJ 0x0009
/* PF13-KEY1 PF14-KEY2 */
static int key_gpio_init(void)
{
int temp;
int ret = 0;
set_gpio_direction(GPIOF,0x0000);
return ret;
}
static int key_open(struct inode *inode, struct file *filp)
{
key_gpio_init();
return 0;
}
static ssize_t key_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
int temp;
int ret = 0;
temp = get_gpio_idr(GPIOF);
ret = copy_to_user(buf,&temp,sizeof(temp));
return 0;
}
static int key_release(struct inode *inode, struct file *filp)
{
return 0;
}
static struct file_operations key_fops = {
.owner = THIS_MODULE,
.open = key_open,
.read = key_read,
.release = key_release,
};
static int __init key_init(void)
{
int ret = 0;
key.major = 0;
if(key.major)
{
key.devid = MKDEV(key.major, 0);
ret = register_chrdev_region(key.devid,KEY_DEV_NUMS,KEY_NAME);
}else
{
ret = alloc_chrdev_region(&key.devid,0,KEY_DEV_NUMS,KEY_NAME);
key.major = MAJOR(key.devid);
key.minor = MINOR(key.devid);
}
if(ret < 0)
{
printk("register chrdev failed!\r\n");
goto fail_devid;
}
printk("key major = %d, minor = %d \r\n", key.major,key.minor);
cdev_init(&key.cdev, &key_fops);
key.cdev.owner = THIS_MODULE;
ret = cdev_add(&key.cdev, key.devid, KEY_DEV_NUMS);
if(ret < 0)
{
printk("cdev_add failed!\r\n");
goto fail_cdevadd;
}
key.class = class_create(THIS_MODULE, KEY_NAME);
if(IS_ERR(key.class))
{
printk("class_create failed!\r\n");
ret = PTR_ERR(key.class);
goto fail_class;
}
key.device = device_create(key.class, NULL, key.devid, 0, KEY_NAME);
if(IS_ERR(key.device))
{
printk("device_create failed!\r\n");
ret = PTR_ERR(key.device);
goto fail_device;
}
printk("key init success!\r\n");
return 0;
fail_device:
class_destroy(key.class);
fail_class:
cdev_del(&key.cdev);
fail_cdevadd:
unregister_chrdev_region(key.devid,KEY_DEV_NUMS);
fail_devid:
return ret;
}
static void __exit key_exit(void)
{
device_destroy(key.class,key.devid);
class_destroy(key.class);
cdev_del(&key.cdev);
unregister_chrdev_region(key.devid, KEY_DEV_NUMS);
printk("key_exit!\r\n");
}
module_init(key_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("mx");
MakeFile
#
#obj-m += nuc972_gpio.o
key-objs := key_input.o nuc972_gpio.o
obj-m := key.o
PWD := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR :=/home/maxuan/linuxbsp/linux-3.10.x
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
二、应用源码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "unistd.h"
int main(int argc, char *argv[])
{
int keyvalue = 0;
int destvalue = 0;
int fd;
int ret = 0;
char *filename;
if(argc != 2)
{
printf("Error Usage!\r\n");
return -1;
}
filename = argv[1];
fd = open(filename,O_RDWR);
if(fd < 0)
{
printf("file %s open failed!\r\n",filename);
return -1;
}
destvalue = 1<<13;
while(1)
{
keyvalue = 0xffff;
read(fd,&keyvalue,sizeof(keyvalue));
if(keyvalue & destvalue)
{
}else
{
printf("KEY1 is pressed!!\r\n");
}
}
close(fd);
return 0;
}
三、实验总结
1、能跑起来,没做消抖,先这样吧