尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Linux设备树在根节点添加key后,为什么还需要添加pinctrl_key部分?

Linux设备树在根节点添加key后,为什么还需要添加pinctrl_key部分? 这是一个非常硬核且典型的内核驱动开发问题。你问到了设备树Device Tree中最容易让初学者困惑的“分层设计”逻辑。直接回答你的核心疑问在根节点添加key按键只是定义了“功能需求”而添加pinctrl部分则是定义了“物理实现”。两者缺一不可少了pinctrl内核只知道你要用按键但不知道该去操作哪根引脚、怎么操作这根引脚。为了让你彻底理解我把这个过程拆解为硬件电路设计的三个层次1. 根节点下的“key”功能节点你在根节点或根节点下的某个子节点添加的key属于功能抽象层。/ { key: key-node { compatible gpio-keys; // 告诉内核这是一个GPIO按键 pinctrl-names default; // 引用下面定义的pinctrl状态 pinctrl-0 key_pins; // 把“功能”和“引脚”绑定起来 button-1 { label KEY_POWER; gpios gpio1 10 GPIO_ACTIVE_LOW; linux,code 116; // 按键键值 (POWER) }; }; };这个节点只负责三件事告诉内核“我是个按键”compatible。告诉内核“按下去后上报什么键值”linux,code。引用了一个叫key_pins的东西但并没有定义这个key_pins具体是什么。2. pinctrl_key 部分引脚功能节点你在/pinctrl或/pinmux节点下添加的pinctrl_key属于物理实现层。pinctrl { key_pins: key_pins { pins GPIO1_IO10; // 指定具体芯片引脚 function gpio_in; // 复用功能作为GPIO输入 bias-pull-up; // 使能内部上拉电阻防止悬空 input-enable; // 使能输入模式 drive-strength 2; // 驱动电流能力 }; };这个节点负责另外三件事引脚复用Pin Mux芯片的同一个物理引脚可能有“UART”“I2C”“GPIO”等多种功能。pinctrl告诉芯片这个脚要当gpio_inGPIO输入用而不是串口。电气特性是否需要上拉/下拉电阻引脚速率是多少这直接关系到按键的稳定性和抗干扰能力。电源域归属属于哪个电压域1.8V还是3.3V。3. 为什么一定要分开写核心原因解耦与复用同一个功能节点key可以适配不同的硬件板子。比如你的产品有高配版和低配版按键功能完全一样但低配版用了不同的GPIO引脚。此时你只需修改pinctrl_key里的引脚号功能节点key-node的代码一行都不用改。SoC 管脚数量巨大一颗ARM芯片有上百个引脚如果每个功能节点都要重复写“输入输出模式”“上拉电阻”这些电气参数代码会极度冗余。抽象成pinctrl后多个设备可以共享同一套引脚配置。驱动分离gpio-keys驱动只管“检测电平变化上报事件”它不需要知道引脚怎么复用的而pinctrl子系统专门管“引脚怎么配置”。这是Linux内核“单一职责原则”的体现。4. 编译时的“链接”过程关键你可能会想“我在key节点里写了pinctrl-0 key_pins编译器怎么知道对应哪个”key_pins是一个标签引用Label Reference。设备树编译DTC时编译器会去/pinctrl下找到key_pins: key_pins { ... };这个节点并把它的物理地址和配置数据填入key节点的pinctrl-0属性中。内核启动时pinctrl子系统会解析key节点的pinctrl-0属性进而调用SoC底层的寄存器操作把对应的物理引脚真正配置成GPIO模式。5. 如果不添加 pinctrl_key 会发生什么编译阶段如果pinctrl-0引用的标签key_pins不存在DTC编译会直接报错生成不了dtb文件。运行阶段假设你硬编码绕过了编译检查内核在probegpio-keys驱动时GPIO子系统会因为该引脚尚未配置复用功能而初始化失败按键驱动无法加载。更严重的情况是该引脚可能被默认配置为UART功能你在按键上按下去信号会被UART控制器当作串口数据解析导致系统异常。一个便于记忆的比喻功能节点key 你家装修的“设计图”上面写着“这里要装一个开关”。pinctrl节点 电工的“施工图”上面写着“从配电箱拉一根2.5平方的铜线到墙上这个86盒接在L端”。没有设计图电工不知道装什么没有施工图设计师的话只是空想。如果你现在正在移植某个开发板的按键驱动遇到了编译报错比如undefined reference to key_pins或者probe失败可以把你的设备树片段发出来我可以帮你具体看下是引脚编号冲突还是复用功能没写对。
返回列表