[Linux]查询方式按键驱动
查询方式按键驱动
艾恩凝 2021/3/23
序
按键和led差不多,只不过按键换成了读取操作
程序
驱动程序
#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 <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#define BUTTON_MAJOR_NUMBER 200
#define DEVICE_NAME "button_drv"
static struct class *button_drv_class;
static struct class_device *button_drv_class_dev;
volatile unsigned long *GPFCON;
volatile unsigned long *GPFDAT;
volatile unsigned long *GPGCON;
volatile unsigned long *GPGDAT;
static int button_drv_open(struct inode *inode,struct file *file){
*GPFCON &= ~((0x3<<(0*2)) | (0x3<<(2*2)));
*GPGCON &= ~((0x3<<(3*2)) | (0x3<<(11*2)));
return 0;
}
static ssize_t button_drv_read(struct file *file, const char __user *buf, size_t count, loff_t * ppos){
unsigned char key_vals[4];
if (count != sizeof(key_vals))
return -EINVAL;
key_vals[0] = (*GPFDAT & (1<<0)) ? 1 : 0;
key_vals[1] = (*GPFDAT & (1<<2)) ? 1 : 0;
key_vals[2] = (*GPGDAT & (1<<3)) ? 1 : 0;
key_vals[3] = (*GPGDAT & (1<<11)) ? 1 : 0;
copy_to_user(buf, key_vals, sizeof(key_vals));
return sizeof(key_vals);
}
static struct file_operations button_drv_fops = {
.owner = THIS_MODULE,
.open = button_drv_open,
.read = button_drv_read,
};
static int button_drv_init(void){
register_chrdev(BUTTON_MAJOR_NUMBER,DEVICE_NAME, &button_drv_fops);//register tell kernel
button_drv_class = class_create(THIS_MODULE, DEVICE_NAME);
button_drv_class_dev = class_device_create(button_drv_class, NULL, MKDEV(BUTTON_MAJOR_NUMBER, 0), NULL, DEVICE_NAME);
GPFCON = (volatile unsigned long *)ioremap(0x56000050, 16);
GPFDAT = GPFCON + 1;
GPGCON = (volatile unsigned long *)ioremap(0x56000060, 16);
GPGDAT = GPGCON + 1;
return 0;
}
static void button_drv_exit(void){
unregister_chrdev(BUTTON_MAJOR_NUMBER, DEVICE_NAME);//unregister tell kernel
class_device_unregister(button_drv_class_dev);
class_destroy(button_drv_class);
iounmap(GPFCON);
iounmap(GPGCON);
}
module_init(button_drv_init);
module_exit(button_drv_exit);
MODULE_AUTHOR("https://aeneag.xyz");
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("S3C2440 Button Driver");
MODULE_LICENSE("GPL");
测试程序
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int fd;
unsigned char key_vals[4];
int cnt = 0;
printf("please use ./test_button_drv /dev/button_drv");
fd = open(argv[1], O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
while (1)
{
read(fd, key_vals, sizeof(key_vals));
if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3])
{
printf("%04d key pressed: %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]);
}
}
return 0;
}
慢慢搞
吾心信其可行,
则移山填海之难,
终有成功之日!
——孙文
则移山填海之难,
终有成功之日!
——孙文
评论
0 评论