點添加key后,為什么還需要添加pinctrl_key部分?)
這是一個非常硬核且典型的內(nèi)核驅動開發(fā)問題。你問到了設備樹Device Tree中最容易讓初學者困惑的“分層設計”邏輯。直接回答你的核心疑問在根節(jié)點添加key按鍵只是定義了“功能需求”而添加pinctrl部分則是定義了“物理實現(xiàn)”。兩者缺一不可少了pinctrl內(nèi)核只知道你要用按鍵但不知道該去操作哪根引腳、怎么操作這根引腳。為了讓你徹底理解我把這個過程拆解為硬件電路設計的三個層次1. 根節(jié)點下的“key”功能節(jié)點你在根節(jié)點或根節(jié)點下的某個子節(jié)點添加的key屬于功能抽象層。/ { key: key-node { compatible gpio-keys; // 告訴內(nèi)核這是一個GPIO按鍵 pinctrl-names default; // 引用下面定義的pinctrl狀態(tài) pinctrl-0 key_pins; // 把“功能”和“引腳”綁定起來 button-1 { label KEY_POWER; gpios gpio1 10 GPIO_ACTIVE_LOW; linux,code 116; // 按鍵鍵值 (POWER) }; }; };這個節(jié)點只負責三件事告訴內(nèi)核“我是個按鍵”compatible。告訴內(nèi)核“按下去后上報什么鍵值”linux,code。引用了一個叫key_pins的東西但并沒有定義這個key_pins具體是什么。2. pinctrl_key 部分引腳功能節(jié)點你在/pinctrl或/pinmux節(jié)點下添加的pinctrl_key屬于物理實現(xiàn)層。pinctrl { key_pins: key_pins { pins GPIO1_IO10; // 指定具體芯片引腳 function gpio_in; // 復用功能作為GPIO輸入 bias-pull-up; // 使能內(nèi)部上拉電阻防止懸空 input-enable; // 使能輸入模式 drive-strength 2; // 驅動電流能力 }; };這個節(jié)點負責另外三件事引腳復用Pin Mux芯片的同一個物理引腳可能有“UART”“I2C”“GPIO”等多種功能。pinctrl告訴芯片這個腳要當gpio_inGPIO輸入用而不是串口。電氣特性是否需要上拉/下拉電阻引腳速率是多少這直接關系到按鍵的穩(wěn)定性和抗干擾能力。電源域歸屬屬于哪個電壓域1.8V還是3.3V。3. 為什么一定要分開寫核心原因解耦與復用同一個功能節(jié)點key可以適配不同的硬件板子。比如你的產(chǎn)品有高配版和低配版按鍵功能完全一樣但低配版用了不同的GPIO引腳。此時你只需修改pinctrl_key里的引腳號功能節(jié)點key-node的代碼一行都不用改。SoC 管腳數(shù)量巨大一顆ARM芯片有上百個引腳如果每個功能節(jié)點都要重復寫“輸入輸出模式”“上拉電阻”這些電氣參數(shù)代碼會極度冗余。抽象成pinctrl后多個設備可以共享同一套引腳配置。驅動分離gpio-keys驅動只管“檢測電平變化上報事件”它不需要知道引腳怎么復用的而pinctrl子系統(tǒng)專門管“引腳怎么配置”。這是Linux內(nèi)核“單一職責原則”的體現(xiàn)。4. 編譯時的“鏈接”過程關鍵你可能會想“我在key節(jié)點里寫了pinctrl-0 key_pins編譯器怎么知道對應哪個”key_pins是一個標簽引用Label Reference。設備樹編譯DTC時編譯器會去/pinctrl下找到key_pins: key_pins { ... };這個節(jié)點并把它的物理地址和配置數(shù)據(jù)填入key節(jié)點的pinctrl-0屬性中。內(nèi)核啟動時pinctrl子系統(tǒng)會解析key節(jié)點的pinctrl-0屬性進而調(diào)用SoC底層的寄存器操作把對應的物理引腳真正配置成GPIO模式。5. 如果不添加 pinctrl_key 會發(fā)生什么編譯階段如果pinctrl-0引用的標簽key_pins不存在DTC編譯會直接報錯生成不了dtb文件。運行階段假設你硬編碼繞過了編譯檢查內(nèi)核在probegpio-keys驅動時GPIO子系統(tǒng)會因為該引腳尚未配置復用功能而初始化失敗按鍵驅動無法加載。更嚴重的情況是該引腳可能被默認配置為UART功能你在按鍵上按下去信號會被UART控制器當作串口數(shù)據(jù)解析導致系統(tǒng)異常。一個便于記憶的比喻功能節(jié)點key 你家裝修的“設計圖”上面寫著“這里要裝一個開關”。pinctrl節(jié)點 電工的“施工圖”上面寫著“從配電箱拉一根2.5平方的銅線到墻上這個86盒接在L端”。沒有設計圖電工不知道裝什么沒有施工圖設計師的話只是空想。如果你現(xiàn)在正在移植某個開發(fā)板的按鍵驅動遇到了編譯報錯比如undefined reference to key_pins或者probe失敗可以把你的設備樹片段發(fā)出來我可以幫你具體看下是引腳編號沖突還是復用功能沒寫對。