Linux嵌入式驱动开发07——GPIO驱动过程记录(飞凌开发板)
文章目录
- 全系列传送门
- 1. 在/arch/arm/boot/dts/imx6q-pinfunc.h查找
- 2. 在设备树配置文件中添加设备节点定义以及其引脚定义
- 3. 修改设备树文件添加配置
- 4. drivers/gpio目录下添加gpio驱动
- 新建driver/gpio/gpio-user.c
- 在`driver/gpio/Makefile`添加:
- 在driver/gpio/Kconfig添加:
- 5. 通过make menuconfig来进行配置
- 加载环境变量
- 清除之前的编译
- 复制arch/arm/config/imx_v7_defconfig ->.config
- make menuconfig
- 复制 .config 到 arch/arm/config/imx_v7_defconfig
- 执行编译
- 查看验证
- 验证
全系列传送门
Linux嵌入式驱动开发01——第一个驱动Hello World(附源码)
Linux嵌入式驱动开发02——驱动编译到内核
Linux嵌入式驱动开发03——杂项设备驱动(附源码)
Linux嵌入式驱动开发04——应用层和内核层数据传输
Linux嵌入式驱动开发05——物理地址到虚拟地址映射
Linux嵌入式驱动开发06——第一个相对完整的驱动实践编写
Linux嵌入式驱动开发07——GPIO驱动过程记录(飞凌开发板)
Linux嵌入式驱动开发08——字符设备(步步为营)
Linux嵌入式驱动开发09——平台总线详解及实战
Linux嵌入式驱动开发10——设备树开发详解
Linux嵌入式驱动开发11——平台总线模型修改为设备树实例
Linux嵌入式驱动开发12——pinctl和gpio子系统实践操作
Linux嵌入式驱动开发13——ioctl接口(gpio控制使用)
Linux嵌入式驱动开发14——中断的原理以及按键中断的实现(tasklet中断下文)
Linux嵌入式驱动开发15——等待队列和工作队列
Linux嵌入式驱动开发16——按键消抖实验(内核定时器)
Linux嵌入式驱动开发17——输入子系统
Linux嵌入式驱动开发18——I2C通信
1. 在/arch/arm/boot/dts/imx6q-pinfunc.h查找
/arch/arm/boot/dts
打开头文件
imx6q-pinfunc.h
查找EIM_A17
#define MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x0f4 0x408 0x000 0x5 0x0
2. 在设备树配置文件中添加设备节点定义以及其引脚定义
然后,我们要在设备树中添加引脚定义,打开imx6qdl-sabresd.dtsi
imx6qdl-sabresd.dtsi
添加下面的两部分代码
gpio_user: gpios{pinctrl-names = "default";pinctrl-0 = <&pinctrl_user>;compatible = "gpio-user";gpio0{label = "D01";gpios = <&gpio3 15 1>;default-direction = "out";};gpio1{label = "D02";gpios = <&gpio2 21 1>;default-direction = "out";};};
保证这些引脚没有被定义,把复用去掉
pinctrl_user: usergrp {fsl,pins = <MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x0b0b10MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x0b0b10>;};
3. 修改设备树文件添加配置
arch/arm/boot/dts/imx6q-c-sabresd.dts
添加代码
&gpio_user {pinctrl-names = "default";pinctrl-0 = <&pinctrl_user>;fsl,user;status = "okay";
};
4. drivers/gpio目录下添加gpio驱动
drivers/gpio
目录下
添加gpio驱动gpio-user.c,名字需要与节点定义里的驱动名字保持相同,客户也可以自己编写驱动。
新建driver/gpio/gpio-user.c
Linux嵌入式飞凌开发板GPIO驱动模块modules_gpio_test
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/fs.h>#define GPIO_U_IOCTL_BASE 'x'
#define GPIOC_OPS _IOWR(GPIO_U_IOCTL_BASE,0,int)#define MAX_GPIO_NR 32struct gpio_user_data{const char *label;bool input;unsigned gpio;unsigned dft;
};
static struct gpio_misc{struct miscdevice misc;struct gpio_user_data *data;int gpio_count;
} *gpio_misc;static int gpio_user_open(struct inode *inodp, struct file *filp)
{if(!gpio_misc)return -ENODEV;return 0;
}static int gpio_user_release(struct inode *inodp, struct file *filp)
{if(!gpio_misc)return -ENODEV;return 0;
}static long gpio_user_ioctl(struct file *filp, unsigned int cmd,unsigned long arg)
{int no, offset;unsigned long val;unsigned long __user *p = (void __user *)arg;struct gpio_user_data *data;unsigned long get_value;if(!gpio_misc)return -ENODEV;data = gpio_misc->data;if(_IOC_TYPE(cmd) != GPIO_U_IOCTL_BASE)return -EINVAL;switch(_IOC_NR(cmd)){case 0:if(get_user(val,p))return -EFAULT;if(data[val].input){val = gpio_get_value(data[val].gpio);put_user(val,p);} else {gpio_set_value(data[val].gpio,val >> 31);}break;default:return -ENOTTY;}return 0;
}static const struct file_operations gpio_user_fops = {.owner = THIS_MODULE,.open = gpio_user_open,.release = gpio_user_release,.unlocked_ioctl = gpio_user_ioctl,
};static void gpio_user_init_default(void)
{int i,ret;struct gpio_user_data *data;data = gpio_misc->data;for(i = 0;i < gpio_misc->gpio_count;i++){if(!gpio_is_valid(data[i].gpio)){continue;}ret = gpio_request(data[i].gpio,data[i].label);if(ret < 0){continue;}if(data[i].input){gpio_direction_input(data[i].gpio);}else{gpio_direction_output(data[i].gpio,data[i].dft);}}
}
static void gpio_user_free_default(void)
{int i;struct gpio_user_data *data;data = gpio_misc->data;for(i = 0;i < gpio_misc->gpio_count;i++){if(!gpio_is_valid(data[i].gpio)){continue;}gpio_free(data[i].gpio);}
}
static int gpio_user_probe(struct platform_device *pdev)
{int index;struct device_node *node = pdev->dev.of_node, *child;gpio_misc = devm_kzalloc(&pdev->dev,sizeof(*gpio_misc),GFP_KERNEL);if(!gpio_misc){return -ENOMEM;}gpio_misc->gpio_count = of_get_available_child_count(node);if(!gpio_misc->gpio_count){return -ENODEV;}if(gpio_misc->gpio_count > MAX_GPIO_NR){gpio_misc->gpio_count = MAX_GPIO_NR;}gpio_misc->data = devm_kzalloc(&pdev->dev,sizeof(struct gpio_user_data) * gpio_misc->gpio_count,GFP_KERNEL);if(!gpio_misc->data){return -ENOMEM;}index = 0;for_each_available_child_of_node(node,child){const char *input;struct gpio_user_data *data = &gpio_misc->data[index++]; data->label = of_get_property(child,"label",NULL) ? : child->name;input = of_get_property(child,"default-direction",NULL) ? : "in";if(strcmp(input,"in") == 0)data->input = true;data->gpio = of_get_gpio_flags(child,0,&data->dft);}gpio_user_init_default();gpio_misc->misc.name = "gpio";gpio_misc->misc.minor = MISC_DYNAMIC_MINOR;gpio_misc->misc.fops = &gpio_user_fops;return misc_register(&gpio_misc->misc);
}
static int gpio_user_remove(struct platform_device *pdev)
{gpio_user_free_default();misc_deregister(&gpio_misc->misc);return 0;
}static const struct of_device_id of_gpio_user_id_table[] = {{ .compatible = "gpio-user",},{},
};MODULE_DEVICE_TABLE(of,of_gpio_user_id_table);static struct platform_driver gpio_user_driver = {.probe = gpio_user_probe,.remove = gpio_user_remove,.driver = {.owner = THIS_MODULE,.name = "gpio-user",.of_match_table = of_gpio_user_id_table,},
};
module_platform_driver(gpio_user_driver);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:gpio-user");
同时修改Kconfig和Makefile文件。
修改dirver/gpio目录下的Kconfig和Makefile文件:
在driver/gpio/Makefile
添加:
obj-$(CONFIG_GPIO_USER_INTF) += gpio-user.o
在driver/gpio/Kconfig添加:
config GPIO_USER_INTFtristate "gpio user interface"---help---this driver for all gpio control
5. 通过make menuconfig来进行配置
在目录linux-4.1.15
下,首先进行的操作
加载环境变量
. /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
然后,
清除之前的编译
make distclean
复制arch/arm/config/imx_v7_defconfig ->.config
arch/arm/config/imx_v7_defconfig
到目录linux-4.1.15
下,修改名字为
.config
make menuconfig
然后运行
make menuconfig
修改完成后,保存,然后打开 .config
文件,可以看到我们的gpio已经加载了过来
然后
复制 .config 到 arch/arm/config/imx_v7_defconfig
cp .config arch/arm/config/imx_v7_defconfig
最后
执行编译
make distclean
make imx_v7_defconfig
make zImage -j16
make dtbs
make modules -j16
编译结束后
查看验证
验证
复制我们的测试程序到开发板
我们的测试程序,测试的是DO1,也就是EIM_AD15,out是输出,0是选择了第一个DO1对应的EIM_AD15,1的话就是选择DO2对应的EIM_A17,最后的0或者1就是输出的高低电平
Linux嵌入式驱动开发07——GPIO驱动过程记录(飞凌开发板)相关推荐
- 海康Camera MVS Linux SDK二次开发封装ROS packge过程记录(c++)
Livox Lidar + HIKROBOT Camera系列 最近在开发相机和激光雷达融合的slam算法,主要用于三维重建,想实时的得到彩色点云地图,传感器选择了海康威视的工业相机和大疆的固态激光 ...
- 关于NXP官网i.mx6q与飞凌开发板i.mx6q之间的差异
首先介绍一下他们都是使用的i.mx6q处理芯片,飞凌是根据NXP官网上的开发板设计的核心板,但是飞凌的debug调试串口不是和NXP官网的开发板使用的一个口,大家要特别注意,在将飞凌的信息下载到NXP ...
- 【WinCE】流设备驱动简介及GPIO驱动的实现
流设备驱动实际上就是导出标准的流接口函数的驱动,这是文档上面的定义.在WinCE中,所有的流设备都导出流设备接口,这样WinCE中的Device Manager可以加载和管理这些流设备驱动. 流设备 ...
- WinCE流设备驱动简介及GPIO驱动的实现
作者:ARM-WinCE 流设备驱动实际上就是导出标准的流接口函数的驱动,这是文档上面的定义.在WinCE中,所有的流设备都导出流设备接口,这样WinCE中的Device Manager可以加载和管理 ...
- 开发人员学Linux(1):VirtualBox中安装CentOS7过程记录
2019独角兽企业重金招聘Python工程师标准>>> 在开发过程中常常需要进行一些预研,而有些操作对操作系统可能具有破坏性且是不可恢复的,或者需要在不同的操作系统中去观察结果,虽然 ...
- LINUX驱动开发(二)GPIO驱动框架
1. 驱动框架 pinctrl子系统+gpio子系统+设备树+platform总线. pinctrl子系统重点在设置引脚复用,gpio子系统用于初始化引脚. Linxu提供总线-设备-驱动模型,用于将 ...
- linux -- 嵌入式2.6.37wifi-vnt6656移植驱动
[A] 2.6.32.2内核下的移植 这里是友善之臂提供的2.6.32.2内核 + VNT6656 WLAN源代码 1.20.03的编译和使用方法: 1.编译驱动模块 目前1.20. ...
- s3c2440 ARM9 裸机驱动第一篇-GPIO驱动(汇编)
一 开发环境: 1.ubuntu 2.JZ2440开发板 二 硬件部分 JZ2440开发板上将GPF4-7四个引脚外接LED,从电路图可以得知,IO口为低电平时LED灯亮. 查询s3c2440 数据数 ...
- linux系统中离线安装python3.7过程记录
最近公司新弄来一台linux redhat 4.4.7服务器,准备在上面离线安装python3.7,安装过程中出现一些问题,特此记录下来. 首先在python官网上下载了 Python-3.7.3. ...
最新文章
- 导师对帮助研究生顺利完成学业提出了20条劝告:第一,不要有度假休息的打算.....
- 讲真,上班路上 1 小时算很幸福了!
- Android 10.0 PackageManagerService(三)APK扫描-[Android取经之路]
- flex 3 使用手册
- 第一行代码第一章——你的第一行Android代码
- 深入Java关键字null
- myeclipse中添加Oracle数据库
- 7.请解释泛型list集合的长度为什么动态的?_Java面试题集合篇一
- UVA 1411 - Ants(二分图完美匹配)
- Vue项目中如何实现用户登录及token验证?
- 极光推送源码api封装改造
- 常见内网穿透工具使用总结
- 西南交大计算机绘图b,网络大学西南交大离线作业计算机绘图B
- 英语好不好,不影响做外贸
- 风车网陈晓峰回忆录:我的两个月倒闭史
- 使用XML表达表格数据
- python简单成绩录入,python实现简单成绩录入系统
- cocos2d-x 使用 CCScale9Sprite 实现微信对话框
- 云主机安全防护服务有哪些
- Python :18Python计算器