1.按键驱动button.c代码如下
-
//moudle.h 包含了大量加载模块需要的函数和符号的定义
-
#include <linux/module.h>
-
//kernel.h以便使用printk()等函数
-
#include <linux/kernel.h>
-
//fs.h包含常用的数据结构,如struct file等
-
#include <linux/fs.h>
-
//uaccess.h 包含copy_to_user(),copy_from_user()等函数
-
#include <linux/uaccess.h>
-
//io.h 包含inl(),outl(),readl(),writel()等IO口操作函数
-
#include <linux/io.h>
-
#include <linux/miscdevice.h>
-
#include <linux/pci.h>
-
//init.h来指定你的初始化和清理函数,例如:module_init(init_function)、module_exit(cleanup_function)
-
#include <linux/init.h>
-
#include <linux/delay.h>
-
#include <linux/device.h>
-
#include <linux/cdev.h>
-
#include <linux/gpio.h>
-
#include <linux/irq.h>
-
#include <linux/sched.h>
-
#include <linux/interrupt.h>
-
#include <linux/poll.h>
-
//irq.h中断与并发请求事件
-
#include <asm/irq.h>
-
//下面这些头文件是IO口在内核的虚拟映射地址,涉及IO口的操作所必须包含
-
//#include <mach/gpio.h>
-
#include <mach/regs-gpio.h>
-
#include <plat/gpio-cfg.h>
-
#include <mach/hardware.h>
-
#include <mach/map.h>
-
-
-
static struct class *button_class;
-
static int major;
-
-
-
static int button_open(struct inode *inode, struct file *file)
-
{
-
/*设置6410的GPIO管脚的功能可以用s3c_gpio_cfgpin函数*/
-
s3c_gpio_cfgpin(S3C64XX_GPN(0), S3C_GPIO_INPUT);//设置GPN0为输入引脚
-
s3c_gpio_cfgpin(S3C64XX_GPN(1), S3C_GPIO_INPUT);//设置GPN1为输入引脚
-
s3c_gpio_cfgpin(S3C64XX_GPN(2), S3C_GPIO_INPUT);//设置GPN2为输入引脚
-
s3c_gpio_cfgpin(S3C64XX_GPN(3), S3C_GPIO_INPUT);//设置GPN3为输入引脚
-
s3c_gpio_cfgpin(S3C64XX_GPN(4), S3C_GPIO_INPUT);//设置GPN4为输入引脚
-
s3c_gpio_cfgpin(S3C64XX_GPN(5), S3C_GPIO_INPUT);//设置GPN5为输入引脚
-
return 0;
-
}
-
-
static ssize_t button_read(struct file *file, char __user *buf, size_t size, loff_t * ppos)
-
{
-
unsigned char button_vals[6];
-
-
if (size != sizeof(button_vals))
-
return -EINVAL;//若返回的数据大小不等于数组大小,返回错误值
-
-
button_vals[0] = gpio_get_value(S3C64XX_GPN(0)) ;//读取GPNDAT0的值
-
button_vals[1] = gpio_get_value(S3C64XX_GPN(1)) ;//读取GPNDAT2的值
-
button_vals[2] = gpio_get_value(S3C64XX_GPN(2)) ;//读取GPNDAT3的值
-
button_vals[3] = gpio_get_value(S3C64XX_GPN(3)) ;//读取GPNDAT4的值
-
button_vals[4] = gpio_get_value(S3C64XX_GPN(4)) ;//读取GPNDAT5的值
-
button_vals[5] = gpio_get_value(S3C64XX_GPN(5)) ;//读取GPNDAT6的值
-
-
if( copy_to_user(buf, button_vals, sizeof(button_vals)) )//把button_val的值传递给用户(测试程序)
-
{
-
printk("error in function ‘copy_to_user’ !\n");
-
return -EFAULT;
-
}
-
return 0;
-
}
-
-
static ssize_t button_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
-
{
-
return 0;
-
}
-
-
static struct file_operations button_fops = {
-
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
-
.open = button_open,
-
.read = button_read,
-
.write = button_write,
-
};
-
-
static int button_init(void)
-
{
-
major = register_chrdev(0, "button_dev", &button_fops);//注册,告诉内核
-
button_class = class_create(THIS_MODULE, "button_cls");
-
device_create(button_class, NULL, MKDEV(major, 0), NULL, "button");/* /dev/button */
-
-
return 0;
-
}
-
-
static void button_exit(void)
-
{
-
unregister_chrdev(major, "button_cls");
-
device_destroy(button_class, MKDEV(major, 0));
-
class_destroy(button_class);
-
}
-
-
module_init(button_init);
-
module_exit(button_exit);
-
-
MODULE_LICENSE("GPL");
2.按键测试程序button_test.c代码如下
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <stdio.h>
-
-
int main(int argc, char **argv)
-
{
-
int fd;
-
unsigned char button_vals[6];
-
int cnt = 0;
-
-
/*打开/dev/button设备*/
-
fd = open("/dev/button", O_RDWR);
-
if (fd < 0)
-
printf("can't open!\n");
-
-
/*死循环*/
-
while(1)
-
{
-
/*从驱动程序中读取button_vals的值,与驱动程序中的copy_to_user对应*/
-
read(fd, button_vals, sizeof(button_vals));
-
-
/*如果有按键按下,打印*/
-
if(!button_vals[0] || !button_vals[1] || !button_vals[2] || !button_vals[3] || !button_vals[4] || !button_vals[5])
-
{
-
printf("%4d button pressed : %d %d %d %d %d %d\n", cnt++, button_vals[0] ,button_vals[1] ,button_vals[2] ,button_vals[3] ,button_vals[4] ,button_vals[5]);
-
}
-
}
-
return 0;
3.执行测试程序后,按下按键后就能打印出按键信息,但是程序一直处于死循环状态,大量消耗cpu资源
可通过./button_test &命令使测试程序后台运行,然后用top命令查看cpu使用状态,可见cpu使用率接近100%。
阅读(761) | 评论(0) | 转发(0) |