Linux驱动开发:gpio子系统

目录

1、GPIO配置流程

2、GPIO子系统API

2.1 of_find_node_by_path

2.2 of_get_named_gpio

2.3 gpio_request 与 gpiod_get 与 gpiod_get_index

2.4 gpio_direction_input 与 gpiod_direction_input

2.5 gpio_direction_output 与 gpiod_direction_output

2.6 gpio_get_value 与 gpiod_get_value

2.7 gpio_set_value 与 gpiod_set_value

2.8  gpiod_get_from_of_node

2.9 gpio_free 与 gpiod_put

3、GPIO子系统驱动程序

3.1 没有platform总线前怎么得到gpio节点

3.1.1 修改设备树

3.1.2 驱动程序:老版接口

3.1.3 驱动程序:新版接口

3.2 platform总线下得到

3.2.1 修改设备树:配置pinctrl

3.2.2 修改设备树:配置自己的节点

3.2.3 驱动程序


1、GPIO配置流程

        如果要操作GPIO引脚的话,需要先将所用引脚配置为GPIO功能,这需要通过Pinctrl子系统来实现。

        在Pinctrl子系统将引脚配置为GPIO功能后,就可以使用GPIO子系统来设置GPIO的方向等。

        在设备树中,“GPIO组”就是一个GPIO Controller,这通常都由芯片厂家设置好。我们要做的是找到它名字,比如“gpio1”,然后指定要用它里面的哪个引脚,比如<&gpio1 0>。

        我们需要关心里面的这2个属性:

#gpio-controller; 表示这个节点是一个GPIO Controller,它下面有很多引脚。

#gpio-cells = <2>; 表示这个控制器下每一个引脚要用2个32位的数(cell)来描述。

普遍的用法是,用第1个cell来表示哪一个引脚,用第2个cell来表示有效电平:

GPIO_ACTIVE_HIGH : 高电平有效

GPIO_ACTIVE_LOW : 低电平有效

可参考的帮助文档

Linux-4.9.88/Documentation/devicetree/bindings/gpio/gpio.txt 

Linux-4.9.88/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt

2、GPIO子系统API

2.1 of_find_node_by_path

struct device_node *of_find_node_by_path(const char *path)
/**/
功能:通过路径或者节点结构体
参数:
    @path:路径
返回值:成功返回节点的首地址,失败返回NULL

2.2 of_get_named_gpio

int of_get_named_gpio(struct device_node *np,const char *propname, int index)
/*
功能:根据节点结构体解析gpio编号
参数:
    @np:节点指针
	@propname:键
    @index:索引号
返回值:成功返回gpio的编号,失败返回错误码
*/

2.3 gpio_request 与 gpiod_get 与 gpiod_get_index

int gpio_request(unsigned gpio, const char *label)
/*
功能:申请要使用的gpio
参数:
    @gpio:gpio的编号
    @label:标签名
返回值:成功返回0,失败返回错误码
*/
//如果是一个GPIO就用gpiod_get,如果有多个就用gpiod_get_index
struct gpio_desc *__must_check gpiod_get(struct device *dev, 
    const char *con_id, enum gpiod_flags flags)

struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
					       const char *con_id,
					       unsigned int idx,
					       enum gpiod_flags flags)
/*
功能:申请要使用的gpio
参数:
    @dev: device结构体,如果有platform,则 &pdev->dev
    @con_id: 键
    @idx: 索引号
    @flags: 0
返回值:成功返回gpio_desc 结构体,失败返回错误码
*/

2.4 gpio_direction_input 与 gpiod_direction_input

int gpio_direction_input(unsigned gpio)
/*
功能:设置gpio的为输入
参数:
    @gpio:gpio的编号
返回值:成功返回0,失败返回错误码
*/
int gpiod_direction_input(struct gpio_desc *desc)
/*
功能:设置gpio为输入
参数:
    @desc:gpio_desc结构体
返回值:成功返回0,失败返回错误码
*/

2.5 gpio_direction_output 与 gpiod_direction_output

int gpio_direction_output(unsigned gpio, int value)
/*
功能:设置gpio的为输出
参数:
    @gpio:gpio的编号
    @value:默认电平的状态 1高电平  0低电平
返回值:成功返回0,失败返回错误码
*/
int gpiod_direction_output(struct gpio_desc *desc, int value)
/*
功能:设置gpio为输出
参数:
    @desc:gpio_desc结构体
返回值:成功返回0,失败返回错误码
*/

2.6 gpio_get_value 与 gpiod_get_value

int gpio_get_value(unsigned gpio)
/*
功能:读取管脚的值
参数:
    @gpio:gpio的编号
返回值:1高电平  0低电平
*/
int gpiod_get_value(const struct gpio_desc *desc)
/*
功能:读取管脚的值
参数:
    @desc: gpio_desc结构体
返回值:1高电平  0低电平
*/

2.7 gpio_set_value 与 gpiod_set_value

void gpio_set_value(unsigned gpio, int value)    
/*
功能:设置输出电平的值
参数:
     @gpio:gpio的编号
	 @value:1高电平  0低电平
返回值:无
*/
void gpiod_set_value(struct gpio_desc *desc, int value)
/*
功能:设置输出电平的值
参数:
    @desc: gpio_desc结构体
    @value: 1高电平  0低电平
返回值:无
*/

2.8  gpiod_get_from_of_node

struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, 
const char *propname, int index, enum gpiod_flags dflags, const char *label)
/*
功能:在设备树节点信息结构体中获取并申请要使用的gpio编号,然后输出
    此函数一个函数就完成了申请加上输出的功能
参数:
    @node:设备树节点信息结构体指针
    @propname:键名
    @index:索引
    @dflags:gpio状态值
        GPIOD_OUT_LOW
        GPIOD_OUT_HIGH
    @label:标签,填写NULL
返回值:成功返回gpio描述结构体指针,失败返回错误码指针
*/

2.9 gpio_free 与 gpiod_put

void gpio_free(unsigned gpio)
/*
功能:释放gpio
参数:
     @gpio:gpio的编号
返回值:无   
*/
void gpiod_put(struct gpio_desc *desc)
/*
功能:释放gpio
参数:
     @desc:gpio_desc结构体
返回值:无   
*/

3、GPIO子系统驱动程序

3.1 没有platform总线前怎么得到gpio节点

3.1.1 修改设备树

设备树文件在

arch/arm/boot/dts/100ask_imx6ull-14x14.dts

 在根节点下写自己的节点

myleds{ 
	led1=<&gpioe 10 0>; 
	led2=<&gpiof 10 0>; 
	led3=<&gpioe 8 0>;  
};

3.1.2 驱动程序:老版接口

struct device_node *node;
int gpiono;
static int __init mycdev_init(void)
{
	//1.获取节点
	node = of_find_node_by_path("/myleds");

	//2.解析得到gpio
	gpiono = of_get_named_gpio(node, "led1", 0);

	//3.申请使用的gpio
	gpio_request(gpio,NULL));

	//4.通过gpio申请设备
	gpio_direction_output(gpiono, 0);

	return 0;
}

static void __exit mycdev_exit(void) 
{
	gpio_set_value(gpiono,0);
	gpio_free(gpiono);
}

3.1.3 驱动程序:新版接口

static int __init mycdev_init(void)
{
	//1.获取节点
	node = of_find_node_by_path("/myleds");
	
    //2、申请GPIO
    //此函数一个函数就完成了申请加上输出的功能
	desc = gpiod_get_from_of_node(node, "led2", 0, GPIO_OUT_HIGH, 0);

	return 0;
}


static void __exit mycdev_exit(void) 
{
	gpiod_set_value(desc,0);
	gpiod_put(desc);
}

3.2 platform总线下得到

3.2.1 修改设备树:配置pinctrl

使用imx图形化界面来配置引脚

//在pinctrl下设置引脚
&iomuxc_snvs

myled_for_gpio_subsys: myled_for_gpio_subsys{       
    fsl,pins = <
        MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03        0x000110A0
    >;
};

3.2.2 修改设备树:配置自己的节点

在根节点下写自己的节点

myled {
    compatible = "100ask, leddrv" ;
    pinctrl-names = "default";
    pinctrl-0 = <&myLed_for_gpio_subsys>;
    led-gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
};

3.2.3 驱动程序

static ssize_t led_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	gpiod_set_value(led_gpio, status);

}

static struct file_operations led_drv = {
	.write   = led_drv_write,
};

static int chip_demo_gpio_probe(struct platform_device *pdev)
{	    
    led_gpio = gpiod_get(&pdev->dev, "led", 0);
    register_chrdev(0, "100ask_led", &led_drv);
    	
    return 0;
}

static int chip_demo_gpio_remove(struct platform_device *pdev)
{
    unregister_chrdev(major, "100ask_led");
	gpiod_put(led_gpio);
    
    return 0;
}


static const struct of_device_id ask100_leds[] = {
    { .compatible = "100ask,leddrv" },
    { },
};

/* 1. 定义platform_driver */
static struct platform_driver chip_demo_gpio_driver = {
    .probe      = chip_demo_gpio_probe,
    .remove     = chip_demo_gpio_remove,
    .driver     = {
        .name   = "100ask_led",
        .of_match_table = ask100_leds,
    },
};

static int __init led_init(void)
{    
    platform_driver_register(&chip_demo_gpio_driver); 
}

static void __exit led_exit(void)
{
    platform_driver_unregister(&chip_demo_gpio_driver);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/17050.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

html5地理位置信息介绍, 百度地图使用

文章目录 1. HTML5中地理信息API1.1 Geolocation 接口 2. 在vue中使用百度地图3. 在react中使用百度地图 1. HTML5中地理信息API HTML5 的地理位置 API 可以让你获取用户的地理位置信息&#xff0c;并将其用于许多不同的应用场景&#xff0c;例如&#xff1a; 在地图上显示用…

钴基双金属氧化物储能材料的高效制备和电化学应用

一、引言 钴金属氧化物作为一类典型的储能材料&#xff0c;既可以用于锂离子电池负极材料&#xff0c;又可以用于超级电容器电极材料&#xff0c;因而备受关注 。在作为锂离子电池负极材料时&#xff0c;具有较高的理论比容量&#xff0c;但充放电体积变化较大、材料导电性较差…

爬虫为什么需要ip

爬虫需要使用爬虫ip主要是为了解决以下问题&#xff1a; 1、反爬虫机制&#xff1a;许多网站会设置反爬虫机制来防止爬虫程序的访问&#xff0c;例如限制IP地址的访问频率、检测访问来源等。使用爬虫ip可以绕过这些限制&#xff0c;使得爬虫程序更难被检测到。 2、访问限制&a…

浅拷贝和深拷贝

浅拷贝&#xff1a; 定义&#xff1a;浅拷贝&#xff08;Shallow Copy&#xff09;是一种简单的对象复制方式&#xff0c;将一个对象的数据成员直接复制给另一个对象&#xff08;通常是通过默认的复制构造函数或赋值运算符实现&#xff09;&#xff0c;这些数据成员可以是基本…

JavaScript:字符串

文章目录 字符串344. 反转字符串reverse() 方法&#xff08;打基础的时候&#xff0c;不要太迷恋库函数&#xff09;代码及思路 541. 反转字符串 IIJavaScript String split() 方法JavaScript Array join() 方法代码分析见注释 剑指 Offer 05. 替换空格思路注意&#xff1a;上面…

网络基础学习:什么是网络与网络发展史

什么是网络与网络发展史 什么是网络&#xff1f;什么是网络发展史&#xff1f;分组交换技术TCP/IP技术Web技术ARPANET&#xff08;1969年&#xff09;Internet&#xff08;1983年&#xff09;万维网&#xff08;1990年&#xff09;移动互联网&#xff08;2007年&#xff09;物联…

KDGK-F断路器机械特性测试仪

一、产品概述 KDGK-F 断路器机械特性测试仪可用于各电压等级的真空、六氟化硫、少油、多油等电力系统高压开关的机械特性参数测试与测量。测量数据稳定&#xff0c;抗干扰性强&#xff0c;可在500KV等级及以下电站做实验&#xff0c;接线方便&#xff0c;操作简单&#xff0c;是…

第14章 项目采购管理

文章目录 采购管理包括如下几个过程14.2 编制采购计划 462编制采购计划的输出1&#xff09;采购管理计划2&#xff09;采购工作说明书3&#xff09;采购文件 14.2.3 工作说明书&#xff08;SOW&#xff09; 14.3 实施采购 47414.3.2 实施采购的方法和技术 476&#xff08;1&…

No.054<软考>《(高项)备考大全》【冲刺8】《软考之 119个工具 (6)》

《软考之 119个工具 &#xff08;6&#xff09;》 99.应急应对策略:100.风险在评估:101.风险审计:102.偏差和趋势分析:103.技术绩效测量:104.自制或外购分析:105.市场调研:106.投标人会议:107.建议书评价技术:108.独立核算:109.广告:110.采购谈判:111.合同变更控制系统:112.采购…

ArduPilot之GPS Glitch问题M8N模块配置

ArduPilot之GPS Glitch问题&M8N模块配置 1. 源由2. 现象3. 视频分析3.1 配置&#xff08;不理想&#xff09;3.2 配置优化3.3 优化配置短时间3D LockGlitch3.4 优化配置长时间3D DGPS Lock3.5 使用尽量多的卫星系统3.5.1 配置一3.5.2 配置二 3.6 同一时间段&#xff08;M8N…

3.3 泰勒公式例题分析

例1 写出函数f(x)带有拉格朗日余项的n阶麦克劳林公式 我的答案&#xff1a; 一、信息 1.f(x)的表达式 2.目标求这个f(x)的n阶麦克劳林公式 二、分析 条件1&#xff1a;告诉我f(x)的表达式为我后续带入公式做准备 条件2&#xff1a;告诉我用什么公式和此次求解的方向 三…

平面设计师都在用的设计素材网站,免费下载~

很多新手设计师不知道去哪里找高清、免费的设计素材&#xff0c;今天我就给大家推荐5个设计素材网站&#xff0c;免费下载&#xff0c;赶紧收藏起来把&#xff01; 1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx 菜鸟图库是我推荐过很多次的网站&#xff0c;主要是站内素…

普通2本,去过字节外包,到现在年薪25W+的测试开发,我的2年转行心酸经历...

个人简介 我是一个普通二本大学机械专业毕业&#xff0c;17年毕业&#xff0c;19年转行&#xff0c;目前做IT行业的软件测试已经有3年多&#xff0c;职位是高级测试工程师&#xff0c;坐标上海… 我想现在我也有一点资格谈论关于转行这个话题&#xff1b;希望你在决定转行之前…

unity-VRTK-simulator开发学习日记2(抛物线 导包|使用|调用方法)

导包 使用抛物线 1.层级目录下添加抛物线曲线 曲线上面那个是直线 2.将跟踪控制器 给到抛物线的“跟随资源” &#xff08;选择哪只手射出射线&#xff09; 3.激活按键 找到模拟手柄按键 找到simulator的交互的几个按键&#xff08;ButtonOne为例&#xff09; value&#x…

从4k到42k,软件测试工程师的涨薪史,给我看哭了

清明节一过&#xff0c;盲猜大家已经无心上班&#xff0c;在数着日子准备过五一&#xff0c;但一想到银行卡里的余额……瞬间心情就不美丽了。 最近&#xff0c;2023年高校毕业生就业调查显示&#xff0c;本科毕业月平均起薪为5825元。调查一出&#xff0c;便有很多同学表示自己…

第六章 Iptables与Firewalld防火墙

第六章 Iptables与Firewalld防火墙 一、Iptables 1、策略与规则链 &#xff08;1&#xff09;、防火墙策略规则的设置 一种是“通”即放行&#xff0c;另一种是“堵”即阻止。 当防火墙的默认策略为拒绝时&#xff08;堵&#xff09;&#xff0c;就要设置允许规则通&#x…

[论文笔记] In Search of an Understandable Consensus Algorithm (Extended Version)

In Search of an Understandable Consensus Algorithm (Extended Version) 寻找可理解的共识算法 (扩展版) [Extended Paper] [Original Paper] ATC’14 (Original) 摘要 Raft 是一个用于管理复制日志的共识算法. Raft 更易于理解, 且为构建实际的系统提供了更好的基础. Raf…

Redis 基础

0. Redis 基础 如果对 Redis 还不了解的同学可以先看一下这篇 Redis 基础文章 &#xff0c;这里面介绍了 Redis 是什么&#xff0c;以及怎么用 1. Redis 管道 我们通常使用 Redis 的方式是&#xff0c;发送命令&#xff0c;命令排队&#xff0c;Redis 执行&#xff0c;然后返…

基于SpringBoot3从零配置MybatisPlus

基于SpringBoot3从零配置MybatisPlus记录 文章目录 1.环境2.表数据准备3. 配置pom配置yml 配置MapperScan 3.问题总结问题1: Property sqlSessionFactory or sqlSessionTemplate are required问题2&#xff1a;org.apache.ibatis.binding.BindingException: Invalid bound stat…

ETL到底是什么?

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事。 前段时间和大家聊了一个话题&#xff0c;就是为什么要用构建数据仓库&#xff0c;而不是直连数据源的方式开发报表&#xff1f;通…
最新文章