[Linux]查询方式按键驱动

查询方式按键驱动

艾恩凝 2021/3/23

按键和led差不多,只不过按键换成了读取操作

程序

驱动程序

 1#include <linux/module.h>
 2#include <linux/kernel.h>
 3#include <linux/fs.h>
 4#include <linux/init.h>
 5#include <linux/delay.h>
 6#include <asm/uaccess.h>
 7#include <asm/irq.h>
 8#include <asm/io.h>
 9#include <asm/arch/regs-gpio.h>
10#include <asm/hardware.h>
11
12#define BUTTON_MAJOR_NUMBER 200
13#define DEVICE_NAME  "button_drv"
14
15static struct class *button_drv_class;
16static struct class_device	*button_drv_class_dev;
17
18volatile unsigned long *GPFCON;
19volatile unsigned long *GPFDAT;
20
21volatile unsigned long *GPGCON;
22volatile unsigned long *GPGDAT;
23
24
25static int button_drv_open(struct inode *inode,struct file *file){
26    *GPFCON &= ~((0x3<<(0*2)) | (0x3<<(2*2)));
27    *GPGCON &= ~((0x3<<(3*2)) | (0x3<<(11*2)));
28    return 0;
29}
30
31static ssize_t button_drv_read(struct file *file, const char __user *buf, size_t count, loff_t * ppos){
32    unsigned char key_vals[4];
33	if (count != sizeof(key_vals))
34		return -EINVAL;
35	key_vals[0] = (*GPFDAT & (1<<0)) ? 1 : 0;
36	key_vals[1] = (*GPFDAT & (1<<2)) ? 1 : 0;
37
38	key_vals[2] = (*GPGDAT & (1<<3)) ? 1 : 0;
39	key_vals[3] = (*GPGDAT & (1<<11)) ? 1 : 0;
40
41	copy_to_user(buf, key_vals, sizeof(key_vals));
42    return sizeof(key_vals);
43}
44
45static struct file_operations button_drv_fops = {
46    .owner  =   THIS_MODULE,  
47    .open   =   button_drv_open,   
48	.read	=	button_drv_read,	   
49};
50
51static int  button_drv_init(void){
52    register_chrdev(BUTTON_MAJOR_NUMBER,DEVICE_NAME, &button_drv_fops);//register tell kernel
53    button_drv_class = class_create(THIS_MODULE, DEVICE_NAME);
54    button_drv_class_dev = class_device_create(button_drv_class, NULL, MKDEV(BUTTON_MAJOR_NUMBER, 0), NULL, DEVICE_NAME);
55   
56    GPFCON = (volatile unsigned long *)ioremap(0x56000050, 16);
57	GPFDAT = GPFCON + 1;
58
59    GPGCON = (volatile unsigned long *)ioremap(0x56000060, 16);
60	GPGDAT = GPGCON + 1;
61   
62    return 0;
63}
64
65static void  button_drv_exit(void){
66    unregister_chrdev(BUTTON_MAJOR_NUMBER, DEVICE_NAME);//unregister tell kernel
67    class_device_unregister(button_drv_class_dev);
68	class_destroy(button_drv_class);
69	iounmap(GPFCON);
70	iounmap(GPGCON);
71}
72
73module_init(button_drv_init);
74module_exit(button_drv_exit);
75MODULE_AUTHOR("https://aeneag.xyz");
76MODULE_VERSION("0.1");
77MODULE_DESCRIPTION("S3C2440 Button Driver");
78MODULE_LICENSE("GPL");
79

测试程序

 1
 2#include <sys/types.h>
 3#include <sys/stat.h>
 4#include <fcntl.h>
 5#include <stdio.h>
 6
 7int main(int argc, char **argv)
 8{
 9	int fd;
10	unsigned char key_vals[4];
11	int cnt = 0;
12	printf("please use ./test_button_drv  /dev/button_drv");
13	fd = open(argv[1], O_RDWR);
14	if (fd < 0)
15	{
16		printf("can't open!\n");
17	}
18
19	while (1)
20	{
21		read(fd, key_vals, sizeof(key_vals));
22		if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3])
23		{
24			printf("%04d key pressed: %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]);
25		}
26	}
27
28	return 0;
29}
30
31

慢慢搞


    


公众号'艾恩凝'
个人公众号
个人微信
个人微信
    吾心信其可行,
          则移山填海之难,
                  终有成功之日!
                                  ——孙文
    评论
    0 评论
avatar

取消