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

Linux驱动开发—设备树描述引脚复用 Pinmux 与Pinctrl

书接上回:Linux驱动开发—设备树基本概念,语法详解-CSDN博客

文章目录

    • Pinmux 概念
    • Pinctrl 概念
      • 多路复用(Pin Multiplexing)
      • 引脚配置(Pin Configuration)
      • 引脚控制(Pin Control)
      • Pinctrl 在软件中的实现
      • 使用场景
    • 使用设备树描述引脚复用
      • 理论上描述示例
      • 实际上NXP示例
      • 实际上RK示例

Pinmux 概念

Pinmux,或 Pin Multiplexer,是一种在电子电路设计中使用的技术,用于在一个芯片上多路复用(共享)引脚的功能。通过 pinmux,可以将一个引脚配置为多种功能,例如 GPIO(通用输入输出)、UART(通用异步收发传输器)、I2C(集成电路间总线)、SPI(串行外设接口)等。这样可以在有限的引脚资源下实现更多的功能,增加芯片的灵活性和可扩展性。pinmux 广泛应用于嵌入式系统设计、微控制器、系统级芯片(SoC)等领域,特别是在需要实现多种外设功能且引脚资源有限的情况下。

这样设计的优点:

  1. 节省引脚资源:通过共享引脚的方式,减少了芯片对引脚数量的需求。
  2. 灵活性高:可以根据实际应用需求灵活配置引脚功能。
  3. 成本降低:减少了对外部引脚扩展的需求,从而降低了硬件成本。

例如,一个 MCU(微控制单元)可能有一个引脚可以配置为 GPIO 或 UART 的 TX 引脚。通过设置 pinmux 配置寄存器,可以选择这个引脚的具体功能。

Pinctrl 概念

Pinctrl(Pin Control)是与 pinmux 密切相关的概念,但更为广泛。Pinctrl 是一个综合的引脚管理框架,涵盖了引脚的多路复用、配置和实时控制。通过 pinctrl,设计人员可以灵活地配置和管理芯片引脚,提高系统的功能性和可靠性。它不仅包括引脚的多路复用,还涵盖了对引脚电气特性的配置和控制。Pinctrl 通常涉及以下几个方面:

多路复用(Pin Multiplexing)

这是 pinmux 的主要功能,即选择一个引脚的具体功能,例如将一个引脚配置为 UART、I2C、SPI 或 GPIO。

引脚配置(Pin Configuration)

配置引脚的电气特性,包括:

  • 上拉或下拉电阻:通过内部上拉或下拉电阻来确定引脚的默认状态。
  • 驱动强度:控制引脚输出的电流能力。
  • 输入/输出模式:设置引脚为输入模式、输出模式或高阻态。
  • 中断配置:设置引脚中断的触发方式,例如上升沿、下降沿或电平触发。

引脚控制(Pin Control)

这是指对引脚的实时控制和管理,例如使能或禁用特定引脚的功能,或者在运行时动态改变引脚的配置。

Pinctrl 在软件中的实现

在操作系统层面,如 Linux,pinctrl 通常由一个专用的子系统管理。设备树(Device Tree)文件中定义了引脚的多路复用和配置,内核引导时会根据这些配置初始化引脚。典型的设备树片段简单示例:

pinctrl {uart0_pins: uart0 {pins = "PA0", "PA1";function = "uart";bias-pull-up;drive-strength = <4>;};
};

使用场景

  • 嵌入式系统:在嵌入式设备中,通过 pinctrl 管理引脚的多路复用和配置,实现外设功能。
  • SoC(系统级芯片):在复杂的 SoC 设计中,pinctrl 用于配置和管理多个子系统的引脚。
  • 低功耗设计:通过配置引脚的低功耗模式,减少系统的整体功耗。

使用设备树描述引脚复用

理论上描述示例

假设我们有一个 UART 接口,需要配置其引脚:

&uart0 {pinctrl-names = "default";pinctrl-0 = <&uart0_pins>;status = "okay";
};
pinctrl {uart0_pins: uart0_pins {pins = "PA0", "PA1";  // 引脚名称function = "uart";    // 引脚功能bias-pull-up;         // 上拉电阻drive-strength = <4>; // 驱动强度};
};

引脚组通常在特定设备节点中引用,以便在设备初始化时进行配置。

&uart0 {pinctrl-names = "default";pinctrl-0 = <&uart0_pins>;status = "okay";
};

引脚端:固定的语法: pinctrl 名字和 pinctrl 引脚

在这个例子中,&uart0 节点引用了 uart0_pins 引脚组,并将其命名为 default 配置。系统启动时,UART0 的引脚将根据 uart0_pins 引脚组的定义进行配置。

配置端:不同Soc 厂商可能不一样,没有通用标准

pinctrl {uart0_pins: uart0_pins {pins = "PA0", "PA1";  // 引脚名称function = "uart";    // 引脚功能bias-pull-up;         // 上拉电阻drive-strength = <4>; // 驱动强度};
};

常见属性:

  • pins:定义引脚组中的具体引脚。
  • function:定义引脚的功能,例如 UART、I2C、SPI 等。
  • bias-disable:禁用上拉或下拉电阻。
  • bias-pull-up:启用上拉电阻。
  • bias-pull-down:启用下拉电阻。
  • drive-strength:设置引脚的驱动强度,通常以 mA 为单位。
  • slew-rate:设置引脚的转换速率,影响信号的上升和下降时间。
  • input-enable:启用输入功能。
  • output-enable:启用输出功能。

实际上NXP示例

将NXP源码中dtb翻译出来主要的源码,截取部分引脚复用示例;

iomuxc {compatible = "fsl,imx8qm-iomuxc";pinctrl-names = "default";pinctrl-0 = <0x0e>;imx8qm-mek {hoggrp {fsl,pins = <0x73 0x00 0x600004c 0xb2 0x03 0x600004c 0x27 0x03 0x600004c 0x0f 0x03 0x600004c 0x9e 0x03 0x21 0x6f 0x03 0x21 0x6e 0x03 0x21 0x10 0x03 0x21 0x66 0x03 0x21 0x05 0x03 0x21 0x4b 0x03 0x21 0x4c 0x03 0x21 0x4e 0x03 0x21 0x4f 0x03 0x21 0xb3 0x03 0x21 0x5e 0x03 0x21>;linux,phandle = <0x0e>;phandle = <0x0e>;};uart_cm41grp {fsl,pins = <0x0b 0x01 0x6000020 0x0c 0x01 0x6000020>;linux,phandle = <0xde>;phandle = <0xde>;};esai0grp {fsl,pins = <0x68 0x00 0xc6000040 0x69 0x00 0xc6000040 0x6a 0x00 0xc6000040 0x6b 0x00 0xc6000040 0x6c 0x00 0xc6000040 0x6d 0x00 0xc6000040 0x70 0x00 0xc6000040>;linux,phandle = <0x137>;phandle = <0x137>;};fec1grp {fsl,pins = <0xff 0x00 0x14a0 0xa6 0x00 0x6000020 0xa5 0x00 0x6000020 0xf4 0x00 0x61 0xf3 0x00 0x61 0xf5 0x00 0x61 0xf6 0x00 0x61 0xf7 0x00 0x61 0xf8 0x00 0x61 0xf9 0x00 0x61 0xfa 0x00 0x61 0xfb 0x00 0x61 0xfc 0x00 0x61 0xfd 0x00 0x61 0xfe 0x00 0x61>;linux,phandle = <0x124>;phandle = <0x124>;};};};

同样分为两部分:

定义引脚端: 配置的引脚为<0x0e>,具体的含义需要查询数据手册

		compatible = "fsl,imx8qm-iomuxc";pinctrl-names = "default";pinctrl-0 = <0x0e>;

定义配置端:以串口UART为例

			uart_cm41grp {fsl,pins = <0x0b 0x01 0x6000020 0x0c 0x01 0x6000020>;linux,phandle = <0xde>;phandle = <0xde>;};

NXP中,一般定义为fsl,pins属性,具体解析如下:

引脚编号 (pin number):指定具体的物理引脚。

模式/功能 (mux mode):指定引脚的复用模式,使得一个引脚可以有多个功能。

电气属性 (electrical properties):配置引脚的电气特性,比如上拉/下拉电阻、驱动强度等。

第一组数据:0x0b 0x01 0x6000020

  • 引脚编号 (0x0b):这是引脚编号。
  • 模式 (0x01):这是引脚的复用模式,使得该引脚用于某个特定的功能。
  • 电气属性 (0x6000020):这是引脚的电气属性,通常包含配置如上拉/下拉电阻、驱动强度等。 具体属性需要查询数据手册

第二组数据:0x0c 0x01 0x6000020

  • 引脚编号 (0x0c):这是引脚编号。
  • 模式 (0x01):这是引脚的复用模式,使得该引脚用于某个特定的功能。
  • 电气属性 (0x6000020):这是引脚的电气属性。具体属性需要查询数据手册

实际上RK示例

以RK3588 设备树源码为例

gpio-keys {compatible = "gpio-keys";autorepeat;pinctrl-names = "default";pinctrl-0 = <&pwr_key>;power {gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;linux,code = <KEY_POWER>;label = "GPIO Key Power";debounce-interval = <100>;wakeup-source;};
};
&pinctrl {pinctrl-names = "default";pinctrl-0 = <&rtc_32k>;buttons {pwr_key: pwr-key {rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>;};};usb {usb_drv: usb-drv {rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;};};sdio-pwrseq {wifi_enable_h: wifi-enable-h {rockchip,pins = <0 RK_PA2 0 &pcfg_pull_none>;};};
};

定义引脚端: 配置的引脚为<&pwr_key>,具体的含义需要查询数据手册

		pinctrl-names = "default";pinctrl-0 = <&pwr_key>;

定义配置端 :复用电源按键

	buttons {pwr_key: pwr-key {rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>;};};

rockchip,pins = <0 RK_PA2 0 &pcfg_pull_none>;具体解析如下:

通过将 pwr_key 引脚配置为 rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>,明确了 PA6 引脚的电气属性和复用模式。这使得 pwr_key 可以在 gpio-keys 节点中被引用,并正确配置为电源按键。这个配置表明,PA6 引脚设置为上拉模式(pcfg_pull_up),并且默认工作在 GPIO 模式(复用模式为 0)。这种配置确保了按键按下时能被正确识别,并且有适当的电气特性来防止误触发。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • (24)(24.1) FPV和仿真的机载OSD(三)
  • 【图书推荐】《数据资产管理核心技术与应用》
  • JAVA中的Wrapper类
  • 认识消息队列:Spring Boot 实现 MQ 消息队列,解锁异步、削峰、广播等高级功能!
  • Pygame游戏开发进阶:碰撞检测和声音效果
  • 武汉流星汇聚:中国制造业与跨境电商共舞,性价比领先全球电商平台
  • django基于大数据的电影推荐系统-计算机毕业设计源码71246
  • 【计算机网络——1.4接入网和物理媒体】
  • 【编程笔记】解决移动硬盘无法访问文件或目录损坏且无法读取
  • 深入解析数据仓库ADS层-从理论到实践的全面指南
  • gin框架传入的gin.context参数是池化的
  • 3.串口(UART)
  • 写一个获取cookie方法
  • 我的cesium for UE踩坑之旅(蓝图、UI创建)
  • Genymotion adb shell
  • ES6指北【2】—— 箭头函数
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • iOS 系统授权开发
  • javascript数组去重/查找/插入/删除
  • JavaScript学习总结——原型
  • js递归,无限分级树形折叠菜单
  • JS字符串转数字方法总结
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • PAT A1050
  • ReactNativeweexDeviceOne对比
  • sessionStorage和localStorage
  • Vue--数据传输
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 规范化安全开发 KOA 手脚架
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 来,膜拜下android roadmap,强大的执行力
  • 嵌入式文件系统
  • 使用agvtool更改app version/build
  • 首页查询功能的一次实现过程
  • 为视图添加丝滑的水波纹
  • 一个完整Java Web项目背后的密码
  • 一起参Ember.js讨论、问答社区。
  • 一天一个设计模式之JS实现——适配器模式
  • 用element的upload组件实现多图片上传和压缩
  • 你对linux中grep命令知道多少?
  • postgresql行列转换函数
  • 通过调用文摘列表API获取文摘
  • ​批处理文件中的errorlevel用法
  • #NOIP 2014# day.2 T2 寻找道路
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (力扣)1314.矩阵区域和
  • (三十五)大数据实战——Superset可视化平台搭建
  • (算法)Game
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别
  • (游戏设计草稿) 《外卖员模拟器》 (3D 科幻 角色扮演 开放世界 AI VR)
  • .net core 6 集成和使用 mongodb
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)