当前位置: 首页 > news >正文

湖州 网站建设专业微网站营销

湖州 网站建设,专业微网站营销,网站营销工作流程,php网站开发环境搭建目录 一、硬件原理 二、添加设备树 1、创建pinctrl 2、创建节点 3、检查 编译复制 三、修改工程模板​编辑 四、驱动编写 1、添加keyio函数 2、添加调用 3、驱动出口函数添加释放 4、添加原子操作 5、添加两个宏定义 6、初始化原始变量 7、打开操作 8、读操作 总体代…目录 一、硬件原理 二、添加设备树 1、创建pinctrl 2、创建节点 3、检查 编译复制 三、修改工程模板​编辑 四、驱动编写 1、添加keyio函数  2、添加调用 3、驱动出口函数添加释放 4、添加原子操作 5、添加两个宏定义 6、初始化原始变量 7、打开操作 8、读操作 总体代码如下 五、应用编写 总体代码如下 验证 一、硬件原理 打开原理图找到KEY 可以看到KEY0是接到UART1 CTS上 打开参考手册找到IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B 看到是可以复用为GPIO1_IO18的 根据IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B配置的电气属性为0xF080具体属性如下 配置UART1_CTS_B的IO属性          *bit 16:0 HYS关闭      *bit [15:14]: 11 默认22K上拉      *bit [13]: 1 pull功能      *bit [12]: 1 pull/keeper使能      *bit [11]: 0 关闭开路输出      *bit [7:6]: 10 速度100Mhz      *bit [5:3]: 000 关闭输出      *bit [0]: 0 低转换率 二、添加设备树 1、创建pinctrl 先查找UART1_CTS对应的宏这个在arch/arm/boot/dts/imx6ul-pinfunc.h 在iomuxc里添加keygrp 2、创建节点 创建key节点 3、检查 添加完之后在文件里分别搜索MX6UL_PAD_UART1_CTS_B__GPIO1_IO018和gpio1 18检查一下是否有存在使用避免占用 打开开发板检查创建是否存在 编译复制 三、修改工程模板 修改makefile 复制基本的字符驱动模板到key.c 四、驱动编写 自行编写好基本的字符设备 1、添加keyio函数  在驱动入口前添加  96行of_find_node_by_path 函数通过路径来查找指定的节点“key”返回找到的节点 102行of_get_named_gpio函数获取设备树中“key-gpios”属性信息0为其第一个信息获取到的 GPIO 编号 108行gpio_request 函数在使用 GPIO 之前申请GPIO 管脚设名字“key0”返回值0申请成功 114行gpio_direction_input函数设置 GPIO 为输入返回值0设置成功 2、添加调用 在驱动入口函数里面后部添加 在驱动入口里面调用 keyio函数  3、驱动出口函数添加释放 4、添加原子操作 5、添加两个宏定义 方便原子操作值不是固定的  6、初始化原始变量 初始化keyvalue,把宏INVAKEY赋值给keyvalue在驱动入口函数定义 7、打开操作 设置私有数据 8、读操作 61行获取私有数据 63-67行 gpio_get_value函数返回值为 GPIO 的输入电平状态1 为高电平0 为低电平。如果按下不放就是1进入while等待释放释放为0取反进入while中执行 atomic_set函数把KEY0VALUE赋值给keyvalue。否则直接执行 atomic_set函数把宏INVAKEY赋值给keyvalue 69行atomic_read函数读取keyvalue值赋给value 71行copy_to_user函数把value的值拷贝给用户空间成功执行拷贝操作则返回0 总体代码如下 #include linux/module.h #include linux/kernel.h #include linux/init.h #include linux/fs.h #include linux/uaccess.h #include linux/io.h #include linux/cdev.h #include linux/device.h #include linux/of.h #include linux/of_address.h #include linux/of_irq.h #include linux/slab.h #include linux/of_address.h #include linux/of_gpio.h #include linux/atomic.h#define KEY_CNT 1 /* 设备号个数 */ #define KEY_NAME key /* 名字 */#define INVAKEY 0x00 #define KEY0VALUE 0XF0/* 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; /* 按键值 */ } key; /* key设备 *//** description : 打开设备* param - inode : 传递给驱动的inode* param - filp : 设备文件file结构体有个叫做private_data的成员变量* 一般在open的时候将private_data指向设备结构体。* return : 0 成功;其他 失败*/ static int key_open(struct inode *inode, struct file *filp) {filp-private_data key;return 0; }/** description : 从设备读取数据* param - filp : 要打开的设备文件(文件描述符)* param - buf : 返回给用户空间的数据缓冲区* param - cnt : 要读取的数据长度* param - offt : 相对于文件首地址的偏移* return : 读取的字节数如果为负值表示读取失败*/ static ssize_t key_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt) {int value;struct key_dev *dev filp-private_data;int ret 0;if(gpio_get_value(dev-key_gpio) 0){/*按下*/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, };/*key io初始化*/ static int keyio_init(struct key_dev *dev) { int ret 0; /*初始化atomic*/atomic_set(key.keyvalue,INVAKEY);dev-nd of_find_node_by_path(/key);if (dev-nd NULL){ret -EINVAL;goto fail_nd;}dev-key_gpio of_get_named_gpio(dev-nd, key-gpios, 0);if (dev-key_gpio 0){ret -EINVAL;goto fail_gpio;}ret gpio_request(dev-key_gpio, key0);if (ret){ret -EBUSY;printk( IO %d cant request\r\n, dev-key_gpio);}ret gpio_direction_input(dev-key_gpio);if (ret){ret -EINVAL;goto fail_input;}return 0; fail_input:gpio_free(dev-key_gpio); fail_gpio: fail_nd:device_destroy(key.class, key.devid);return ret; }/** description : 驱动入口函数* param : 无* return : 无*/ static int __init key_init(void) {int ret 0;/* 初始化原子变量 */atomic_set(key.keyvalue,INVAKEY);/* 注册字符设备驱动 */key.major 0;/* 1、创建设备号 */if (key.major){ /* 定义了设备号 */key.devid MKDEV(key.major, 0);register_chrdev_region(key.devid, KEY_CNT, KEY_NAME);}else{ /* 没有定义设备号 */alloc_chrdev_region(key.devid, 0, KEY_CNT, KEY_NAME); /* 申请设备号 */key.major MAJOR(key.devid); /* 获取分配号的主设备号 */key.minor MINOR(key.devid); /* 获取分配号的次设备号 */}if(ret 0){goto fail_devid;}printk(major %d , minor %d \r\n, key.major, key.minor);/* 2、初始化cdev */key.cdev.owner THIS_MODULE;cdev_init(key.cdev, key_fops);/*初始化的 cdev 结构体变量*//* 3、添加一个cdev */cdev_add(key.cdev, key.devid, KEY_CNT);/*添加字符设备*/if(ret){goto fail_cdevadd;}/* 4、创建类 */key.class class_create(THIS_MODULE, KEY_NAME);if (IS_ERR(key.class)){ret PTR_ERR(key.class);goto fail_class;}/* 5、创建设备 */key.device device_create(key.class, NULL, key.devid, NULL, KEY_NAME);if (IS_ERR(key.device)){ret PTR_ERR(key.device);goto fail_device;}ret keyio_init(key);if (ret 0){goto fail_device;}printk(key_init\r\n);return 0; fail_device:class_destroy(key.class); fail_class:cdev_del(key.cdev); fail_cdevadd:unregister_chrdev_region(key.devid,KEY_CNT); fail_devid:return ret; }/** description : 驱动出口函数* param : 无* return : 无*/ static void __exit key_exit(void) {/* 注销字符设备驱动 */cdev_del(key.cdev);/* 删除cdev */unregister_chrdev_region(key.devid, KEY_CNT); /* 释放设备号 */device_destroy(key.class, key.devid);/*摧毁设备*/class_destroy(key.class);/*删除类*/gpio_free(key.key_gpio);/*释放io*/ }module_init(key_init); module_exit(key_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(zuozhongkai);五、应用编写 总体代码如下 #include sys/types.h #include sys/stat.h #include fcntl.h #include stdio.h #include unistd.h #include stdlib.h #include string.h#define INVAKEY 0x00 #define KEY0VALUE 0XF0/*argc:应用程序参数个数argv数组元素个数argv:具体参数,也可以写作char **argv./keyAPP filename ./keyAPP /dev/key */ int main(int argc, char *argv[]) {int fd,retvalue;char *filename;unsigned char databuf[1];int value0;/*判断命令行输入参数是否正确*/if(argc ! 2){printf(error usage!\r\n);return -1;}/*用指针指向文件*/filename argv[1];/*打开文件*/fd open(filename , O_RDWR);if(fd 0){printf(file open failed\r\n,filename);return -1;}/*循环读取*/while(1){read(fd,value,sizeof(value));if(value KEY0VALUE){printf(KEY0 press , value %d\r\n,value);}}/*关闭文件*/close(fd);return 0; } 循环读取处用read读取内核拷贝的数据 验证 可以看到按下按键就会打印value的值 这里埋下一个伏笔运行测试APP会占用99%的CPU资源 后续章节进行介绍
http://www.hkea.cn/news/14451079/

相关文章:

  • 大型门户网站建设多少钱wordpress doc插件
  • 微信小程序开发模板网站微网站O2O平台平台开发
  • 网站建设lnmp数据库和wordpress
  • 爱心互助网站开发百度竞价推广方案的制定
  • 辽宁建设厅网站什么时候换的网站怎么做商桥
  • asp加dw做网站wordpress tagline
  • 图片展示型网站模板下载美食网站建设服务策划书
  • 用php做的网站用什么数据库音乐 wordpress
  • 响应式网站优势甘肃住房和城乡建设厅网站首页
  • 高职网站建设专业书中卫市建设局网站
  • 网站风格搜seo
  • 南京网站建设多少钱成都代理记账
  • 自学手机网站开发东莞网站建设分享seo
  • 网站建设与管理期中考wordpress 爆路径
  • 鄂州网站建设价格找国外公司做网站
  • 淮安网站制作山西省住房和城乡建设厅网站报名
  • 商融建设集团有限公司网站十大放黄不登录不收费
  • 建设集团网站报告书深圳专业网站建设服务
  • 西安网站开发xamokj工信部网站信息查询
  • 手机网站怎么解析网站配置系统
  • 做彩票网站代理赚钱吗楚州网站开发
  • 免费私人网站建设4500双休一天8小时
  • 公司多个门户是做二级域名还是做多个网站html5做简单网站
  • 宜昌做网站的个人网站有什么缺点
  • 长春市网站制作公司做贸易做个外贸网站有必要吗
  • 甘肃省交通建设项目招投标中心网站jquery网站开发平台
  • 哪些网站做科技专题网站构建工具
  • 如何建设手机端网站关于h5的网站模板
  • 抚州市做棋牌网站慧聪网郭凡生
  • 金融理财网站建设方案大连做网页工作室