首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Pinctrl子系统和其主要结构体引入

  • 25-03-04 14:01
  • 4612
  • 5072
blog.csdn.net

往期内容

input子系统专栏:

  1. 专栏地址:input子系统
  2. input角度:I2C触摸屏驱动分析和编写一个简单的I2C驱动程序
    – 末片,有往期内容观看顺序

I2C子系统专栏:

  1. 专栏地址:IIC子系统
  2. 具体芯片的IIC控制器驱动程序分析:i2c-imx.c-CSDN博客
    – 末篇,有往期内容观看顺序

总线和设备树专栏:

  1. 专栏地址:总线和设备树
  2. 设备树与 Linux 内核设备驱动模型的整合-CSDN博客
    – 末篇,有往期内容观看顺序

img

前言

Linux 4.x内核文档

  • Documentation\pinctrl.txt?pinctrl.txt
  • Documentation\devicetree\bindings\pinctrl\pinctrl-bindings.txt?pinctrl-bindings.txt
  • arch/arm/boot/dts/imx6ull-14x14-evk.dts
  • arch/arm/boot/dts/100ask_imx6ull-14x14.dts
  • drivers\pinctrl\freescale\pinctrl-imx6ul.c?pinctrl-imx6ul.c
  • drivers\pinctrl\freescale\pinctrl-imx.c?pinctrl-imx.c

本节主要介绍一下Pinctrl子系统以及Pincontroller的相关数据结构体,讲解这些结构体中哪些成员是去进行描述引脚、复用引脚以及配置引脚。有多个Pincontroller的话,那么这个Pincontroller是用什么结构体来进行抽象描述的。

1.介绍

内核文档:

  • Documentation\pinctrl.txt?pinctrl.txt
  • Documentation\devicetree\bindings\pinctrl\pinctrl-bindings.txt?pinctrl-bindings.txt

img

Pinctrl:Pin Controller,用来控制引脚的:

  • 引脚枚举与命名(Enumerating and naming)
  • 引脚复用(Multiplexing):比如用作GPIO、I2C或其他功能
  • 引脚配置(Configuration):比如上拉、下来、open drain、驱动强度等

Pinctrl驱动由芯片厂家的BSP工程师提供,一般的驱动工程师只需要在设备树里:

  • 指明使用那些引脚
  • 复用为哪些功能
  • 配置为哪些状态

在一般的设备驱动程序里,甚至可以没有pinctrl的代码。

对于一般的驱动工程师,只需要知道“怎么使用pinctrl”即可。

目标:分析理解BSP工程师写好的Pinctrl子系统驱动代码、分析Pinctrl子系统的主要数据结构、如何去使用BSP工程师提供的Pinctrl子系统(设备树、client的数据结构构造)

2.使用Pinctrl要掌握的重要概念

?02_使用Pinctrl要掌握的重要概念.docx

3.Pinctrl子系统使用示例

3.1 要做什么

以I2C为例

img

  • 查看原理图确定使用哪些引脚:比如pinA、pinB

  • 生成pincontroller设备树信息

    • 选择功能:比如把pinA配置为I2C_SCL、把pinB配置为I2C_SDA
    • 配置:比如把pinA、pinB配置为open drain
  • 使用pincontroller设备树信息:比如在i2c节点里定义"pinctrl-names"、“pinctrl-0”

3.2 生成Pincontroller设备树信息

生成pincontroller设备树信息,有3种方法:

  • 有些芯片有图形化的工具,可以点点鼠标就可以配置引脚信息,得到pincontroller中的信息
  • 有些芯片,只能看厂家给的设备树文档或者参考设备树的例子
  • 最差的就是需要阅读驱动代码才能构造设备树信息。

3.2.1 安装工具

?【IMX】6ull引脚复用配置工具.zip

3.2.2 根据原理图生成pinctrl信息

&iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&BOARD_InitPins>;
    imx6ull-board {
        i2c1_pins: i2c1_pins {                /*!< Function assigned for the core: Cortex-A7[ca7] */
            fsl,pins = <
                MX6UL_PAD_UART4_RX_DATA__I2C1_SDA          0x000018B0
                MX6UL_PAD_UART4_TX_DATA__I2C1_SCL          0x000018B0
            >;
        };
    };
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

对于pinctrl有自己的驱动程序,去解析设备树,比如\Linux-4.9.88\drivers\pinctrl\freescale\pinctrl-imx6ul.c------>\Linux-4.9.88\drivers\pinctrl\freescale\pinctrl-imx.c

3.3 在client节点使用pinctrl

&i2c1 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&i2c1_pins>;
    status = "okay";
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

对于使用了pinctl的client,也有自己的驱动程序去解析该设备树:\Linux-4.9.88\drivers\input\keyboard\gpio_keys.c

具体的解析过程后面会有章节讲解

4. 设备树

4.1 理想模型

img

每个节点的function都各自标明,左侧就是pincontroller,右侧则是使用了pincontroller的client

对于pincontroller,其下引脚组的作用已经在节点表示,比如uart{function=“uart0” },表示其下引脚用于uart

该pincontroller有三个子节点,有三种功能:uart、spi、i2c,function是在节点中通过"function="来定义的

4.2 实际的例子

img

function是imx6ull-evk,其内部的子节点的function前提都是该imx6ull-evk,比如pinctrl_csik:csilgrp子节点中fsl,pins这些引脚都只支持imx6ull评估版且是用于 CSI 摄像头的,至于pinctrl_i2cl:i2clgrp引脚组( 描述了与 I2C 接口相关的引脚配置 )和pinctrl_hog_1:hog_grp-1引脚组也是一样

该pincontroller只有一个子节点,也就是Imx6ull-evk,其下的都是组引脚节点,表示Imx6ull-evk评估版支持哪些功能的组引脚,这些子节点(pinctrl_hog_1, pinctrl_csik, pinctrl_i2cl 等)是在描述 imx6ull-evk 评估板所支持的不同引脚配置,并且每个引脚组都关联到不同的硬件功能模块,function的标明是在lable处定义的,也就是子节点的命名处pinctrl_csil、pinctrl_csik、pinctrl_hog_1,又或者是node也可以看出来。

img

5. Pincontroller的数据结构

主要是pinctrl_desc和pinctrl_dev

Linux 4.x内核文档

  • Documentation\pinctrl.txt?pinctrl.txt
  • Documentation\devicetree\bindings\pinctrl\pinctrl-bindings.txt?pinctrl-bindings.txt
  • arch/arm/boot/dts/imx6ull-14x14-evk.dts
  • arch/arm/boot/dts/100ask_imx6ull-14x14.dts
  • drivers\pinctrl\freescale\pinctrl-imx6ul.c?pinctrl-imx6ul.c
  • drivers\pinctrl\freescale\pinctrl-imx.c?pinctrl-imx.c

记住pinctrl的三大作用,有助于理解所涉及的数据结构:

  • 引脚枚举与命名(Enumerating and naming)
  • 引脚复用(Multiplexing):比如用作GPIO、I2C或其他功能
  • 引脚配置(Configuration):比如上拉、下来、open drain、驱动强度等

5.1 结构体引入

pincontroller虽然是一个软件的概念,但是它背后是有硬件支持的,所以可以使用一个结构体来表示它:pinctrl_dev。

怎么构造出pinctrl_dev?我们只需要描述它:提供一个pinctrl_desc,然后调用pinctrl_register就可以:

struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
                                     struct device *dev, void *driver_data);
  • 1
  • 2

img

img

struct pinctrl_dev 是用于管理引脚控制(pinctrl)类设备的结构体,它是 Linux 内核中引脚控制子系统的一部分。引脚控制子系统用于管理 GPIO(通用输入输出)和引脚复用功能。此结构体包含与引脚控制器相关的各种信息

//\Linux-4.9.88\drivers\pinctrl\core.h
struct pinctrl_dev {
	struct list_head node;//用于将当前引脚控制器设备加入全局引脚控制器链表。
	struct pinctrl_desc *desc;//指向引脚控制器描述符的指针,描述符包含了引脚控制器的详细信息,比如可管理的引脚和复用功能等。
	struct radix_tree_root pin_desc_tree;
    //使用 Radix 树来存储该引脚控制器的每个引脚的描述符,Radix 树是一种高效的内存数据结构,用于快速检索引脚信息。
    
	struct list_head gpio_ranges;
    //一个链表,存储了该引脚控制器负责管理的 GPIO 范围(GPIO ranges),这些范围是在运行时添加的。
    
	struct device *dev;
    //对应的设备指针,表示该引脚控制器设备。
    
	struct module *owner;//模块所有者,用于引用计数,防止模块在使用过程中被卸载。
    
	void *driver_data;
    //驱动数据,用于驱动程序在注册到引脚控制器子系统时存储特定的驱动信息。
    
	struct pinctrl *p;//表示该设备的 pinctrl_get() 结果,用于关联引脚控制和设备。
	struct pinctrl_state *hog_default;//表示该设备默认状态下被 "hog" 的引脚状态,"hog" 是指在设备初始化时强占一些引脚。
	struct pinctrl_state *hog_sleep;//表示该设备进入睡眠状态时被 "hog" 的引脚状态。
	struct mutex mutex;//一个互斥锁,用于在每次执行引脚控制器相关操作时确保线程安全。
#ifdef CONFIG_DEBUG_FS
	struct dentry *device_root;//该设备在 debugfs 中的根目录指针,用于调试文件系统。
#endif
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

其中比较重要的就是pinctrl_desc结构体:

\Linux-4.9.88\include\linux\pinctrl\pinctrl.h

struct pinctrl_desc {
	const char *name; //引脚控制器的名称,用于标识该控制器。
	const struct pinctrl_pin_desc *pins; //一个指向引脚描述符数组的指针。每个引脚描述符(pinctrl_pin_desc)描述了该控制器管理的引脚。
	unsigned int npins;//引脚描述符数组的大小,表示控制器管理的引脚数量,通常通过 ARRAY_SIZE() 来计算数组大小。
	const struct pinctrl_ops *pctlops;//引脚控制操作,这个下面会将---作用1
	const struct pinmux_ops *pmxops;//引脚复用操作,这个下面会将---作用2
	const struct pinconf_ops *confops;//引脚配置操作(如设置引脚的电压、电流、上拉/下拉等)---作用3
	struct module *owner;
#ifdef CONFIG_GENERIC_PINCONF
	unsigned int num_custom_params;
	const struct pinconf_generic_params *custom_params;
	const struct pin_config_item *custom_conf_items;
#endif
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

看下pinctrl_desc中的pinctrl_pin_desc结构体, 用于描述板卡或机器上每个引脚(pin)、焊盘(pad)或其他可以复用的单元的信息 。一个pin controller有多个引脚:

\Linux-4.9.88\include\linux\pinctrl\pinctrl.h
struct pinctrl_pin_desc {
	unsigned number;
    //每个引脚在全局引脚号空间中的唯一标识符。引脚号确保不同引脚具有唯一性。
	const char *name;
    //引脚的名称。这个字段通常用于给引脚提供一个易于识别的名字,例如 GPIO1 或 UART_TX。
	void *drv_data;
    //驱动程序为每个引脚定义的特定数据。这是驱动层的数据,pinctrl 核心部分不会对其进行处理或更改。该字段用于存储引脚相关的驱动特定信息。
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

对于pinctrl_desc结构体中的pinctrl_ops、pinmux_ops、pinconf_ops由于篇幅原因,会在本专栏第二篇文章中进一步讲解。

文章知识点与官方知识档案匹配,可进一步学习相关知识
C技能树结构体结构体与函数220410 人正在系统学习中
注:本文转载自blog.csdn.net的憧憬一下的文章"https://blog.csdn.net/caiji0169/article/details/143352837"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top