【全志T113

您所在的位置:网站首页 全志t113-i和t113-s3 【全志T113

【全志T113

2023-10-23 13:17| 来源: 网络整理| 查看: 265

【全志T113-S3_100ask】4-编写按键驱动 前言 (一)查看原理图(二)修改设备树(三)编写驱动 key_drv.c(四)编写测试应用 key_drv_test.c(五)编写Makefile(六)测试

前言

本来想写一下点灯的驱动的,结果发现板子上没有用户的led灯?????那就试着写一下按键的驱动吧。

(一)查看原理图

在原理图里,找到了用户按键USER KEY的内容 在这里插入图片描述 并且是连接在核心板的PB 4 引脚上 在这里插入图片描述 看起来没有用作其他功能。

(二)修改设备树

设备树在以下目录里 /disk/buildroot-100ask_t113-pro/buildroot/output/build/linux-d96275805a67d54998123d36e59108cb1ed52ad5/arch/arm/boot/dts

添加一级子节点

key { #address-cells = ; #size-cells = ; reg = ; compatible = "allwinner,sunxi-pinctrl-test"; pinctrl-names = "default"; pinctrl-0 = ; key-gpio = ; /* KEY0 */ status = "okay"; };

添加 pio

key_pins_a: userkey { allwinner,pins = "PB4" ; };

添加后如下: 在这里插入图片描述

(三)编写驱动 key_drv.c #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define KEY_CNT 1 /* 设备号个数 */ #define KEY_NAME "key" /* 名字 */ /* 定义按键值 */ #define KEY0VALUE 0XF0 /* 按键值 */ #define INVAKEY 0X00 /* 无效的按键值 */ /* key设备结构体 */ struct key_dev{ dev_t devid; /* 设备号 */ struct cdev cdev; /* cdev */ struct class *class; /* 类 */ struct device *device; /* 设备 */ int major; /* 主设备号 */ int minor; /* 次设备号 */ struct device_node *nd; /* 设备节点 */ int key_gpio; /* key所使用的GPIO编号 */ atomic_t keyvalue; /* 按键值 */ }; struct key_dev keydev; /* key设备 */ /* * @description : 初始化按键IO,open函数打开驱动的时候 * 初始化按键所使用的GPIO引脚。 * @param : 无 * @return : 无 */ static int keyio_init(void) { keydev.nd = of_find_node_by_path("/key"); if (keydev.nd== NULL) { return -EINVAL; } keydev.key_gpio = of_get_named_gpio(keydev.nd ,"key-gpio", 0); if (keydev.key_gpio int ret = 0; filp->private_data = &keydev; /* 设置私有数据 */ ret = keyio_init(); /* 初始化按键IO */ if (ret int ret = 0; int value; struct key_dev *dev = filp->private_data; if (gpio_get_value(dev->key_gpio) == 0) { /* key0按下 */ while(!gpio_get_value(dev->key_gpio)); /* 等待按键释放 */ atomic_set(&dev->keyvalue, KEY0VALUE); } else { atomic_set(&dev->keyvalue, INVAKEY); /* 无效的按键值 */ } value = atomic_read(&dev->keyvalue); ret = copy_to_user(buf, &value, sizeof(value)); return ret; } /* * @description : 向设备写数据 * @param - filp : 设备文件,表示打开的文件描述符 * @param - buf : 要写给设备写入的数据 * @param - cnt : 要写入的数据长度 * @param - offt : 相对于文件首地址的偏移 * @return : 写入的字节数,如果为负值,表示写入失败 */ static ssize_t key_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) { return 0; } /* * @description : 关闭/释放设备 * @param - filp : 要关闭的设备文件(文件描述符) * @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, .write = key_write, .release = key_release, }; /* * @description : 驱动入口函数 * @param : 无 * @return : 无 */ static int __init mykey_init(void) { /* 初始化原子变量 */ atomic_set(&keydev.keyvalue, INVAKEY); /* 注册字符设备驱动 */ /* 1、创建设备号 */ if (keydev.major) { /* 定义了设备号 */ keydev.devid = MKDEV(keydev.major, 0); register_chrdev_region(keydev.devid, KEY_CNT, KEY_NAME); } else { /* 没有定义设备号 */ alloc_chrdev_region(&keydev.devid, 0, KEY_CNT, KEY_NAME); /* 申请设备号 */ keydev.major = MAJOR(keydev.devid); /* 获取分配号的主设备号 */ keydev.minor = MINOR(keydev.devid); /* 获取分配号的次设备号 */ } /* 2、初始化cdev */ keydev.cdev.owner = THIS_MODULE; cdev_init(&keydev.cdev, &key_fops); /* 3、添加一个cdev */ cdev_add(&keydev.cdev, keydev.devid, KEY_CNT); /* 4、创建类 */ keydev.class = class_create(THIS_MODULE, KEY_NAME); if (IS_ERR(keydev.class)) { return PTR_ERR(keydev.class); } /* 5、创建设备 */ keydev.device = device_create(keydev.class, NULL, keydev.devid, NULL, KEY_NAME); if (IS_ERR(keydev.device)) { return PTR_ERR(keydev.device); } return 0; } /* * @description : 驱动出口函数 * @param : 无 * @return : 无 */ static void __exit mykey_exit(void) { /* 注销字符设备驱动 */ gpio_free(keydev.key_gpio); cdev_del(&keydev.cdev);/* 删除cdev */ unregister_chrdev_region(keydev.devid, KEY_CNT); /* 注销设备号 */ device_destroy(keydev.class, keydev.devid); class_destroy(keydev.class); } module_init(mykey_init); module_exit(mykey_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("z");

参考了正点原子的按键驱动:

(四)编写测试应用 key_drv_test.c #include "stdio.h" #include "unistd.h" #include "sys/types.h" #include "sys/stat.h" #include "fcntl.h" #include "stdlib.h" #include "string.h" /* 定义按键值 */ #define KEY0VALUE 0XF0 #define INVAKEY 0X00 /* * @description : main主程序 * @param - argc : argv数组元素个数 * @param - argv : 具体参数 * @return : 0 成功;其他 失败 */ int main(int argc, char *argv[]) { int fd, ret; char *filename; int keyvalue; if(argc != 2){ printf("Error Usage!\r\n"); return -1; } filename = argv[1]; /* 打开key驱动 */ fd = open(filename, O_RDWR); if(fd read(fd, &keyvalue, sizeof(keyvalue)); if (keyvalue == KEY0VALUE) { /* KEY0 */ printf("KEY0 Press, value = %#X\r\n", keyvalue); /* 按下 */ } } ret= close(fd); /* 关闭文件 */ if(ret


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3