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

嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路

嵌入式Linux驱动开发pinctrl篇1——从寄存器到子系统驱动演进之路仓库已经开源所有教程主线内核移植跑新版本imx-linux/uboot都在这里或者一起来尝试跑7.0的Linux欢迎各位大佬观摩喜欢的话点个⭐仓库地址https://github.com/Awesome-Embedded-Learning-Studio/imx-forge静态网页https://awesome-embedded-learning-studio.github.io/imx-forge/前言我们为什么要折腾这个说实话在上一章我们通过ioremap()writel()的方式点亮 LED 的时候我真的感觉很有成就感。你看一行writel(val, GPIO1_DR)就能让 LED 亮起来这种直接操控硬件的感觉真的很爽。但后来我发现一个问题这种方式在简单的 demo 里确实没问题可一旦项目复杂起来代码会变得非常难以维护。你想想如果你的驱动里到处都是writel(0x0209C000, ...)这样的硬编码地址过两个月再回头看你自己都得翻手册才能搞清楚这行代码在干什么。更糟糕的是这种直接操作寄存器的方式有个致命问题它把硬件细节和驱动逻辑混在一起了。如果你明天换了块板子GPIO 引脚重新分配了整个驱动代码得大改。这就像是你家里装修电工把所有电线都裸露在外面每次想改动个开关位置都得重新布线。这时候我就在想有没有一种办法能让驱动开发者不需要知道底层寄存器地址也不需要手动配置引脚复用只要说我要控制 GPIO1_IO03就能用答案就是pinctrl gpio 子系统。从直接操作寄存器说起让我们先回顾一下上一章我们是怎么点灯的。如果你还记得我们做了这么几件事// 1. 映射寄存器地址IMX6U_CCM_CCGR1ioremap(0x020C406C,4);MUX_CTL_GPIO1_IO03ioremap(0x020E0068,4);PAD_CTL_GPIO1_IO03ioremap(0x020E02F4,4);GPIO1_GDIRioremap(0x0209C004,4);GPIO1_DRioremap(0x0209C000,4);// 2. 使能时钟writel(readl(IMX6U_CCM_CCGR1)|(326),IMX6U_CCM_CCGR1);// 3. 配置引脚复用writel(0x5,MUX_CTL_GPIO1_IO03);// 4. 配置电气特性writel(0x10B0,PAD_CTL_GPIO1_IO03);// 5. 设置方向为输出writel(readl(GPIO1_GDIR)|(13),GPIO1_GDIR);// 6. 点灯writel(readl(GPIO1_DR)~(13),GPIO1_DR);这里有什么问题呢让我数一数硬编码的物理地址到处都是。每个寄存器地址都是硬编码的换个芯片就得全部改掉。配置步骤冗长且容易出错。你得记住时钟→复用→电气特性→方向→数据少一步都不行。而且这些步骤的顺序还有讲究搞错了就可能起不来。代码没法复用。每个驱动都得重复这套流程没法共享。没有冲突检测。如果两个驱动都想用同一个引脚没人提醒你最后就是两个驱动打起来。和设备树脱节。我们前面花了那么多功夫学设备树结果驱动里还是用硬编码地址设备树的引脚配置信息根本没用到。说实话这种写法在嵌入式开发的早期确实很常见。那时候芯片简单引脚少驱动也不多这么写还能接受。但现在都 2026 年了我们的系统越来越复杂如果还用这种方式写驱动真的会把自己逼疯。驱动分离与分层的哲学现在让我们来聊聊 Linux 内核是怎么解决这个问题的。核心思想就四个字分离与分层。什么叫分离就是把硬件相关的操作和设备驱动的逻辑分开。硬件相关的操作——配置引脚复用、设置电气特性、使能时钟——这些事情应该由专门的子系统来处理而不是每个驱动都自己写一套。什么叫分层就是在驱动和硬件之间插入一层抽象这层抽象负责屏蔽硬件差异给上层提供统一的接口。你可以把它理解成搬家。传统的方式是你每个房间的东西都自己搬这很累。新的方式是你请了一支专业的搬家队子系统你只需要告诉他们把这台电视搬到新家剩下的打包、运输、拆包、摆放都由他们搞定。你不需要知道搬家车怎么开也不需要知道电视怎么打包你只需要知道我要搬电视这个意图。在我们的 LED 驱动里“搬家队就是 pinctrl 子系统和 gpio 子系统。我们只需要告诉它们我要用 GPIO1_IO03设置为输出”剩下的引脚配置、时钟使能都由它们搞定。这里有个很重要的设计理念驱动不应该知道硬件的细节。驱动只需要知道我要控制哪个 GPIO至于这个 GPIO 的寄存器地址是多少、需要配置哪些位、时钟要不要使能这些都不是驱动该关心的事情。pinctrl gpio 子系统全景图现在让我们来看看这两个子系统是如何协同工作的。我先给你画个全景图有个整体印象┌─────────────────────────────────────────────────────────────────┐ │ 用户空间程序 │ │ open(/dev/AES_LED) │ └─────────────────────────────┬───────────────────────────────────┘ │ 系统调用 ▼ ┌─────────────────────────────────────────────────────────────────┐ │ LED 驱动 (我们的代码) │ │ of_get_named_gpio(led-gpio) │ │ gpio_set_value(gpio, 1) │ └─────────────────────────────┬───────────────────────────────────┘ │ GPIO API ▼ ┌─────────────────────────────────────────────────────────────────┐ │ GPIO 子系统核心层 │ │ (gpiolib.c - 提供统一接口) │ └───────────────────┬─────────────────────────────┬───────────────┘ │ │ ▼ ▼ ┌───────────────────────────────┐ ┌───────────────────────────────┐ │ GPIO 控制器驱动 (mxc) │ │ GPIO 控制器驱动 (其他) │ │ (gpio-mxc.c) │ │ │ └───────────────┬───────────────┘ └───────────────────────────────┘ │ 寄存器操作 ▼ ┌─────────────────────────────────────────────────────────────────┐ │ pinctrl 子系统 │ │ (配置引脚复用和电气特性) │ └─────────────────────────────────────────────────────────────────┘ │ 设备树解析 ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 硬件寄存器 │ │ IOMUXC, GPIO_DR, GPIO_GDIR, CCM_CCGR, ... │ └─────────────────────────────────────────────────────────────────┘从这个图里你可以看到几个关键点我们的驱动只需要调用 GPIO API。像gpio_set_value()这样的函数我们不需要知道底层寄存器在哪也不需要知道怎么操作。GPIO 子系统负责管理所有 GPIO 控制器。无论是 i.MX 的 GPIO 控制器还是其他厂商的都通过统一的接口向上提供能力。pinctrl 子系统负责引脚配置。在我们使用某个 GPIO 之前pinctrl 子系统已经根据设备树配置好了引脚的复用功能和电气特性。设备树是配置的中心。所有的硬件配置信息——引脚复用、电气特性、GPIO 编号——都写在设备树里驱动通过设备树获取这些信息。为什么要用两个子系统你可能会问为什么不能一个子系统搞定非要分成 pinctrl 和 gpio 两个这里有个很重要的设计理念职责分离。pinctrl 子系统负责的事情是这个引脚要配置成什么功能GPIOUARTSPI它的电气特性是什么驱动强度上下拉。gpio 子系统负责的事情是这个 GPIO 引脚的值是 0 还是 1它是输入还是输出。你可以这么理解pinctrl 是装修队进场之前把房间的基础设施搞好gpio 是开关装修好了之后你来控制灯的开关。如果装修没搞好比如引脚没配置成 GPIO 功能你按开关也没用。这种分离的设计还有一个好处可移植性。你的驱动代码只需要调用 gpio 子系统的接口至于底层是什么芯片、引脚怎么配置完全不影响你的代码。换芯片的时候只需要修改设备树和 pinctrl/gpio 控制器驱动你的驱动代码可以完全不动。现在的 LED 驱动是什么样的让我们先看看最终效果有个直观的感受。这是使用子系统之后的 LED 驱动代码硬件抽象层部分// 从设备树获取 GPIO 编号led.gpio_sub_sys_nrof_get_named_gpio(led.device_tree_node,led-gpio,0);// 设置为输出模式初始值为 1gpio_direction_output(led.gpio_sub_sys_nr,1);// 设置 GPIO 值gpio_set_value(led.gpio_sub_sys_nr,0);// 点亮就这么简单没有物理地址没有ioremap没有寄存器操作。我们只需要告诉子系统我要用这个 GPIO剩下的都由子系统搞定。那么子系统是怎么知道这个 GPIO 需要配置什么引脚复用、什么电气特性的呢答案在设备树里iomuxc { pinctrl_aes_led: led_grp { fsl,pins MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 ; }; }; / { imx_aes_led { compatible imxaes_led; pinctrl-names default; pinctrl-0 pinctrl_aes_led; led-gpio gpio1 3 GPIO_ACTIVE_LOW; status okay; }; };这里有两个关键信息pinctrl-0 pinctrl_aes_led告诉 pinctrl 子系统这个设备需要用哪个引脚配置。led-gpio gpio1 3 GPIO_ACTIVE_LOW告诉 GPIO 子系统这个设备用的是 gpio1 控制器的第 3 号引脚而且它是低电平有效的。子系统会在设备加载的时候自动读取这些配置把引脚配置好。等我们的驱动代码执行的时候引脚已经配置完毕我们可以直接使用了。接下来我们要做什么现在我们对子系统有了整体印象接下来的章节会深入分析每个部分。我们的学习路径是这样的硬件基础先搞清楚 i.MX 6ULL 的引脚复用和 GPIO 模块是怎么工作的这是理解子系统的前提。pinctrl 子系统深入源码分析 pinctrl 子系统是如何工作的它和设备树是如何交互的。gpio 子系统同样深入源码看看 gpio 子系统是如何管理 GPIO 的它的 API 是怎么实现的。设备树配置学习如何在设备树里正确配置 pinctrl 和 gpio。驱动实现编写一个完整的 LED 驱动使用新 API从设备树读取配置控制 LED。编译测试上板验证看看我们的驱动是否能正常工作。内核对比对比主线内核和 imx 内核的差异看看这两个内核在子系统实现上有什么不同。在正式开始之前我需要提醒你一点子系统的源码量很大pinctrl-imx.c 就有两万多行gpio-mxc.c 也有七百多行。我们不可能逐行分析每一段代码那样会迷失在细节里。我们的策略是抓住主线理解核心流程遇到细节再看。另外我会用主线内核third_party/linux_mainline和 imx 内核third_party/linux-imx进行对比让你看看这两个内核在实现上的差异。这对于你以后做内核移植或者驱动兼容会很有帮助。准备好了吗让我们先从硬件基础开始搞清楚我们在操作什么。下一步阅读 02_hardware_foundation.md 了解 i.MX 6ULL 的引脚复用和 GPIO 硬件原理。相关阅读嵌入式Linux嵌入式Linux驱动开发设备树驱动改造——从硬编码到设备树的实战之旅 - 相似度 100%04. OF API 基础与验证——从 DTS 到代码的桥梁 - 相似度 82%嵌入式Linux嵌入式Linux驱动开发板级DTS实操与完整实战演练——从修改设备树到点亮LED的完整闭环 - 相似度 82%

相关文章:

嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路

嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路 仓库已经开源!所有教程,主线内核移植,跑新版本imx-linux/uboot都在这里,或者一起来尝试跑7.0的Linux!欢迎各位大…...

Python DXF文件处理革命:ezdxf库的深度解析与实战指南

Python DXF文件处理革命:ezdxf库的深度解析与实战指南 【免费下载链接】ezdxf Python interface to DXF 项目地址: https://gitcode.com/gh_mirrors/ez/ezdxf 在CAD数据交换领域,DXF格式一直是工业标准,但传统的DXF处理工具往往复杂难…...

别再乱接线了!用PulseView+逻辑分析仪抓STM32 SPI波形,保姆级避坑指南

逻辑分析仪实战:精准捕获STM32 SPI波形的五大黄金法则 当你在调试STM32的SPI外设时,是否遇到过这样的困境:代码配置完全按照手册操作,但逻辑分析仪显示的波形却充满毛刺、数据残缺不全?这往往不是代码逻辑的问题&#…...

中国航空器拥有者及驾驶员协会:我国低空经济重点政策制度汇编(2025)

这份文档是2025 年中国低空经济重点政策制度汇编,由中国航空器拥有者及驾驶员协会编制,全面梳理国家 地方两级低空经济相关法律法规、规章标准与产业政策,核心是构建低空经济 “法律 - 规章 - 标准 - 政策” 四层制度体系,为低空…...

Hercules安全MCU平台:从硬件锁步到软件诊断,构建功能安全系统基座

1. 平台定位与核心价值解析在医疗、工业控制以及轨道交通这些领域,开发产品从来不只是实现功能那么简单。每一次代码的写入、每一次信号的输出,背后都关联着人的生命安全与重大财产保障。我经历过不少项目,在功能开发完成后,团队最…...

算法和数学模型转换在FPGA中实现问题

1.关于指数运算在FPGA中实现问题 比如,高斯函数,在FPGA直接实现指数函数会极大的消耗资源,并且延迟比较大; 这种一般的使用办法,就是使用LUT查找表来替换; 或者使用分段线性逼近法则; 或者使用泰…...

ArcMap新手必看:手把手教你给‘无家可归’的图层安个‘家’(Define Projection保姆级教程)

ArcMap坐标系急救指南:从“Unknown”到精确定位的完整解决方案 引言:当图层变成“流浪者”时 第一次在ArcMap中看到图层属性显示“Unknown”或“Undefined”时,很多新手会陷入困惑——这些数据明明有坐标数值,为什么软件却无法识别…...

c++生产者消费者者模式笔记-1阻塞问题

生产者消费者模式是并发编程的核心模式之一,核心是想要提高程序的运行效率。 这里记录一下自己的思考,使用通俗易懂的语言,和以日志记录为例,解读生产者消费者模式,并实现生产者消费者模式。 将生产者消费者模式的核心…...

智能视频转PPT:3分钟实现视频内容自动提取的完整方案

智能视频转PPT:3分钟实现视频内容自动提取的完整方案 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾为整理会议录像中的PPT内容而烦恼?手动暂停、截…...

【Perplexity健身计划搜索实战指南】:20年AI搜索专家亲授3大精准检索心法,错过再等一年

更多请点击: https://codechina.net 第一章:Perplexity健身计划搜索实战指南导论 Perplexity 是一款以推理深度和引用可追溯性见长的 AI 搜索工具,特别适合需要结构化、证据支撑型信息检索的场景。在健身领域,用户常面临计划泛滥…...

MC/DC覆盖率:从原理到实战,破解100%覆盖率的迷思与挑战

1. 项目概述:当“完美”成为负担在软件测试领域,尤其是对安全关键系统(比如航空航天、汽车电子、医疗设备)的验证,我们常常听到一个词:100%覆盖率。这听起来像是一个终极目标,一个完美的终点。但…...

MATLAB数据处理小技巧:用reshape函数把一维数组变成你想要的任意形状(附图像处理实例)

MATLAB数据处理实战:reshape函数的高效应用与图像处理案例 当你面对一堆杂乱无章的一维数据时,是否曾为如何将其整理成适合分析的格式而头疼?在MATLAB中,reshape函数就像一位魔术师,能够在不改变数据本质的情况下&…...

3分钟掌握京东自动抢购神器:告别“手慢无“的终极指南

3分钟掌握京东自动抢购神器:告别"手慢无"的终极指南 【免费下载链接】autobuy-jd 使用python语言的京东平台抢购脚本 项目地址: https://gitcode.com/gh_mirrors/au/autobuy-jd 还在为京东限时秒杀商品总是抢不到而烦恼吗?面对心仪的热…...

Keil C编译器字符串常量合并机制与内存优化

1. Keil C编译器中的字符串常量合并机制解析在嵌入式开发中,内存优化是一个永恒的话题。Keil C编译器(包括C51、C166和C251版本)提供了一项智能特性——自动合并重复的字符串常量。这个功能看似简单,但对资源受限的嵌入式系统而言…...

百考通AI智能聚类文献,告别碎片化罗列

撰写文献综述,是学术写作中承上启下的关键一步。它不仅要展示你对研究领域的了解程度,更要体现你的归纳能力、批判思维和问题意识。然而,现实中许多学生却因资料庞杂、逻辑混乱或时间不足,难以写出一篇真正“有据、有理、有深度”…...

电子制造工厂场景,AI自动化方案主流厂商横评:2026年智慧工厂选型深度解析

站在2026年的时间节点回看,电子制造工厂的数字化转型已完成从“单点自动化”向“系统智能化”的跨越。 随着全球供应链波动的常态化,AI自动化方案已不再是锦上添花的“实验室项目”, 而是关乎企业在0.1毫米精度竞争中能否生存的底层基座。 根…...

免费开源乐谱识别工具Audiveris:从纸质乐谱到数字音乐的三步转换指南

免费开源乐谱识别工具Audiveris:从纸质乐谱到数字音乐的三步转换指南 【免费下载链接】audiveris Latest generation of Audiveris OMR engine 项目地址: https://gitcode.com/gh_mirrors/au/audiveris 还在为整理成堆的纸质乐谱而烦恼吗?Audiver…...

思源宋体TTF:5分钟掌握免费商用中文字体的完整使用指南

思源宋体TTF:5分钟掌握免费商用中文字体的完整使用指南 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 如果你正在寻找一款既专业又免费的中文字体,那么思源宋体…...

BBDown:专业高效的哔哩哔哩命令行下载器完全指南

BBDown:专业高效的哔哩哔哩命令行下载器完全指南 【免费下载链接】BBDown Bilibili Downloader. 一个命令行式哔哩哔哩下载器. 项目地址: https://gitcode.com/gh_mirrors/bb/BBDown 在当今数字内容消费时代,高效获取和管理在线视频资源已成为许多…...

PotPlayer字幕翻译插件终极指南:3步实现跨语言视频无障碍观看

PotPlayer字幕翻译插件终极指南:3步实现跨语言视频无障碍观看 【免费下载链接】PotPlayer_Subtitle_Translate_Baidu PotPlayer 字幕在线翻译插件 - 百度平台 项目地址: https://gitcode.com/gh_mirrors/po/PotPlayer_Subtitle_Translate_Baidu 还在为外语视…...

STM32串口高效通信秘籍:巧用DMA+空闲中断实现不定长数据收发(基于CubeIDE)

STM32串口高效通信秘籍:巧用DMA空闲中断实现不定长数据收发(基于CubeIDE) 在物联网设备和嵌入式系统开发中,串口通信是最基础也最关键的通信方式之一。无论是传感器数据采集、设备间通信还是与上位机交互,稳定高效的串…...

Keil MDK 项目迁移避坑指南:当你的旧工程遇到‘Default Compiler Version 5 is not available’

Keil MDK项目迁移实战:编译器版本冲突的工程级解决方案 当你从同事手中接过一个历史遗留的Keil MDK项目,或从版本控制系统拉取多年前的嵌入式工程时,最令人头疼的莫过于打开工程后迎面而来的编译器报错。其中"Default Compiler Version …...

嵌入式网络硬件设计避坑指南:如何为你的SOC选配合适的PHY芯片与接口(MII/RMII实战解析)

嵌入式网络硬件设计避坑指南:如何为你的SOC选配合适的PHY芯片与接口(MII/RMII实战解析) 在嵌入式系统设计中,网络功能已成为现代智能设备的标配需求。无论是工业控制、物联网终端还是消费电子产品,稳定可靠的网络连接往…...

告别卡顿!用Sunshine打造私人游戏串流服务器的完整指南

告别卡顿!用Sunshine打造私人游戏串流服务器的完整指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾经梦想过在任何设备上流畅玩PC游戏?无论是躺…...

在华为欧拉openEuler 22.03 SP2上搞定Oracle 11g R2:一个踩坑无数的可视化安装实录

在华为欧拉openEuler 22.03 SP2上搞定Oracle 11g R2:一个踩坑无数的可视化安装实录 当国产操作系统遇上传统商业数据库,这场跨越技术栈的"联姻"注定充满挑战。作为在openEuler 22.03 SP2上成功部署Oracle 11g R2的实践者,我将以时间…...

不只是定位:教你用开源GNSS/INS平台玩转多传感器融合与抗干扰

不只是定位:开源GNSS/INS平台的多传感器融合与抗干扰实战指南 在自动驾驶、无人机和机器人领域,精准的定位与导航系统是核心竞争力的体现。传统单一GNSS系统在城市峡谷、电磁干扰等复杂环境下表现往往不尽如人意,而单纯依赖惯性导航系统(INS)…...

如何用3分钟完成淘宝淘金币全任务?终极自动化脚本完全指南

如何用3分钟完成淘宝淘金币全任务?终极自动化脚本完全指南 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本,包含蚂蚁森林收取能量,芭芭农场全任务,解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojinbi …...

如何用Python自动化脚本轻松抢到大麦网演唱会门票:终极指南

如何用Python自动化脚本轻松抢到大麦网演唱会门票:终极指南 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 还在为抢不到心仪演唱会门票而烦恼吗?当周杰伦、五月天等热门演…...

告别键盘连击烦恼:KeyboardChatterBlocker 智能解决方案详解

告别键盘连击烦恼:KeyboardChatterBlocker 智能解决方案详解 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker 你是否曾经在打…...

N_m3u8DL-RE完整教程:跨平台流媒体下载的终极解决方案

N_m3u8DL-RE完整教程:跨平台流媒体下载的终极解决方案 【免费下载链接】N_m3u8DL-RE Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文. 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8DL-RE …...