版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16777851/article/details/82470429
这一小节很简单,在读函数中返回两个gpio的状态就可以
#include <linux/fs.h> /* 包含file_operation结构体 */
#include <linux/init.h> /* 包含module_init module_exit */
#include <linux/module.h> /* 包含LICENSE的宏 */
#include <asm/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <asm/gpio.h>
#include <linux/gfp.h>
#define GPH0_BASE 0xe0200c00
static unsigned int major;
static struct class *button_class;
static struct device *button_dev;
struct gpio_reg {
unsigned int con;
unsigned int dat;
};
static struct gpio_reg *gph0 = NULL;
/* open函数 */
static int button_drv_open(struct inode *inode, struct file *file)
{
/* 输入口是gph0 2.3, 配置成输入模式 */
gph0->con &= ~((0xf << 2*4)|(0xf << 3*4));
return 0;
}
ssize_t button_drv_read(struct file *file, char __user *array, size_t size, loff_t *ppos)
{
char buf[2];
int len;
if(size < 2)
{
return -EINVAL;
}
/* 读gpio的状态 */
buf[0] = (gph0->dat & (1 << 2)) ? 1 : 0;
buf[1] = (gph0->dat & (1 << 3)) ? 1 : 0;
/* 赋值只是为了消除告警 */
len = copy_to_user(array ,buf, 2);
return 2;
}
static const struct file_operations button_drv_file_operation = {
.owner = THIS_MODULE,
.open = button_drv_open,
.read = button_drv_read,
};
static int __init button_drv_init(void)
{
/* 获取一个自动的主设备号 */
major = register_chrdev(0,"button_drv",&button_drv_file_operation);
if(major < 0)
{
printk("register_chrdev button_drv fail \n");
goto err_register_chrdev;
}
/* 创建一个类 */
button_class = class_create(THIS_MODULE, "button_class");
if(!button_class)
{
goto err_class_create;
}
/* 创建从属这个类的设备 */
button_dev = device_create(button_class,NULL,MKDEV(major, 0), NULL, "button");
if(!button_dev)
{
goto err_device_create;
}
gph0 = ioremap(GPH0_BASE, 8);
if(!gph0)
{
goto err_ioremap;
}
return 0;
/* 倒影式错误处理机制 */
err_ioremap:
device_unregister(button_dev);
err_device_create:
class_destroy(button_class);
err_class_create:
unregister_chrdev(major,"button_drv");
err_register_chrdev:
return -EIO;
}
static void __exit button_drv_exit(void)
{
/* 取消映射 */
iounmap(gph0);
/* 注销类里面的设备 */
device_unregister(button_dev);
/* 注销类 */
class_destroy(button_class);
/* 注销字符设备 */
unregister_chrdev(major,"button_drv");
}
module_init(button_drv_init);
module_exit(button_drv_exit);
MODULE_LICENSE("GPL");
应用程序重直接读按键值。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
char buf[2];
int fd = open("/dev/button", O_RDWR);
if(fd < 0)
{
printf("open /dev/%s fail\n",argv[1]);
return -1;
}
while(1)
{
read(fd, buf, 2);
if((buf[0] == 0)||(0 == buf[1]))
{
printf("buf = %d, %d \n", buf[0],buf[1]);
}
}
return 0;
}
按键效果
因为是在应用程序中直接循环读取,一次按键会返回产生大量的重复。
查看cpu使用率
发现直接这样使用按键,极大程度的消耗cpu资源。