日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

pinctrl和gpio子系统

發布時間:2023/12/3 综合教程 44 生活家
生活随笔 收集整理的這篇文章主要介紹了 pinctrl和gpio子系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

1.pinctrl子系統

? ? 1)pinctrl子系統簡介

? ? 2)I.MX6ULL的的pinctrl子系統驅動

? ? 3)設備樹中添加pinctrl節點模板

2.gpio子系統

? ? 1)gpio子系統簡介

? ? 2)I.MX6ULL的的gpio子系統驅動

? ? 3)gpio子系統API函數

? ? 4)設備樹中添加gpio節點模板

? ? ? ? ? ?1、創建test設備節點

? ? ? ? ? ?2、添加pinctrl信息

? ? ? ? ? ?3、添加GPIO屬性信息

? ? 5)與gpio相關的OF函數

4.實驗程序編寫

? ? 1)修改設備樹文件

? ? ? ? ? ?1、添加pinctrl節點

? ? ? ? ? ?2、添加LED設備節點

? ? ? ? ? ?3、檢查PIN是否被其他外設使用

5.運行測試

? ? 1)編譯驅動程序和測試APP

? ? ? ? ? ?1、編譯驅動程序

? ? ? ? ? ? 2、編譯測試APP

? ? 2)運行測試


? ? ? Linux內核提供了pinctrl和gpio子系統用于GPIO驅動,本章我們就來學習一下如何借助pinctrl和

? ? ? gpio子系統來簡化GPIO驅動開發。

1.pinctrl子系統

? ? 1)pinctrl子系統簡介

? ? ? ? ? ? ? Linux驅動講究驅動分離與分層,pinctrl和gpio子系統就是驅動分離與分層思想下的產物,

? ? ? ? ? ? ? 驅動分離與分層其實就是按照面向對象編程的設計思想而設計的設備驅動框架,關于驅動

? ? ? ? ? ? ? 的分離與分層我們后面會講。

? ? ? ? ? ? ? 本來pinctrl和gpio子系統應該放到驅動分離與分層章節后面講解,但是不管什么外設驅

? ? ? ? ? ? ? 動,GPIO驅動基本都是必須的,而pinctrl和gpio子系統又是GPIO驅動必須使用的,所以

? ? ? ? ? ? ? 就將pintrcl和gpio子系統這一章節提前了。

? ? ? ? ? ? ? 我們先來回顧一下上一章是怎么初始化LED燈所使用的GPIO,步驟如下:

? ? ? ? ? ? ? 1、修改設備樹,添加相應的節點,節點里面重點是設置reg屬性,reg屬性包括了GPIO相

? ? ? ? ? ? ? ? ? ? 關寄存器。

? ? ? ? ? ? ? 2、獲取reg屬性中IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03和

? ? ? ? ? ? ? ? ? ? IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03這兩個寄存器地址,并且初始化這兩個

? ? ? ? ? ? ? ? ? ?寄存器,這兩個寄存器用于設置GPIO1_IO03這個PIN的復用功能、上下拉、速度等。

? ? ? ? ? ? ? 3、在步驟2里面將GPIO1_IO03這個PIN復用為了GPIO功能,因此需要設置GPIO1_IO03

? ? ? ? ? ? ? ? ? ? 這個GPIO相關的寄存器,也就是GPIO1_DR和GPIO1_GDIR這兩個寄存器。

? ? ? ? ? ? ? 總結一下,步驟2中完成對GPIO1_IO03這個PIN的初始化,設置這個PIN的復用功能、上

? ? ? ? ? ? ? 下拉等,比如將GPIO_IO03這個PIN設置為GPIO功能。步驟3中完成對GPIO的初始化,

? ? ? ? ? ? ? 設置GPIO為輸入/輸出等。

? ? ? ? ? ? ? 如果使用過STM32的話應該都記得,STM32也是要先設置某個PIN的復用功能、速度、上

? ? ? ? ? ? ? 下拉等,然后再設置PIN所對應的GPIO。其實對于大多數的32位SOC而言,引腳的設置

? ? ? ? ? ? ? 基本都是這兩方面,因此Linux內核針對PIN的配置推出了pinctrl子系統對于GPIO的配

? ? ? ? ? ? ? 置推出了gpio子系統。本節我們來學習pinctrl子系統,下一節再學習gpio子系統。

? ? ? ? ? ? ? 大多數SOC的pin都是支持復用的,比如I.MX6ULL的GPIO1_IO03既可以作為普通的

? ? ? ? ? ? ? GPIO使用,也可以作為I2C1的SDA等等。此外我們還需要配置pin的電氣特性,比如上/

? ? ? ? ? ? ? 下拉、速度、驅動能力等等。

? ? ? ? ? ? ? 傳統的配置pin的方式就是直接操作相應的寄存器,但是這種配置方式比較繁瑣、而且容

? ? ? ? ? ? ? 易出問題(比如pin功能沖突)。pinctrl子系統就是為了解決這個問題而引入的,pinctrl子系

? ? ? ? ? ? ? 統主要工作內容如下:

? ? ? ? ? ? ? 1、獲取設備樹中pin信息。

? ? ? ? ? ? ? 2、根據獲取到的pin信息來設置pin的復用功能

? ? ? ? ? ? ? 3、根據獲取到的pin信息來設置pin的電氣特性,比如上/下拉、速度、驅動能力等。

? ? ? ? ? ? ? 對于我們使用者來講,只需要在設備樹里面設置好某個pin的相關屬性即可,其他的初始

? ? ? ? ? ? ? 化工作均由pinctrl子系統來完成,pinctrl子系統源碼目錄為drivers/pinctrl。

? ? 2)I.MX6ULL的的pinctrl子系統驅動

? ? ? ? ? ? ? 1、PIN配置信息詳解

? ? ? ? ? ? ? ? ? ?要使用pinctrl子系統,我們需要在設備樹里面設置PIN的配置信息,畢竟pinctrl子系統

? ? ? ? ? ? ? ? ? ?要根據你提供的信息來配置PIN功能,一般會在設備樹里面創建一個節點來描述PIN的

? ? ? ? ? ? ? ? ? ?配置信息。打開imx6ull.dtsi文件,找到一個叫做iomuxc的節點,如下所示:

756 iomuxc: iomuxc@020e0000 {
757 	compatible = "fsl,imx6ul-iomuxc";
758 	reg = <0x020e0000 0x4000>;
759 };

? ? ? ? ? ? ? ? ? ? iomuxc節點就是I.MX6ULL的IOMUXC外設對應的節點,看起來內容很少,沒看出什

? ? ? ? ? ? ? ? ? ?么跟PIN的配置有關的內容啊,別急!打開imx6ull-alientek-emmc.dts,找到如下所示

? ? ? ? ? ? ? ? ? ? 內容:

311 &iomuxc {
312 	pinctrl-names = "default";
313 	pinctrl-0 = <&pinctrl_hog_1>;
314 	imx6ul-evk {
315 		pinctrl_hog_1: hoggrp-1 {
316 			fsl,pins = <
317 				MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
318 				MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059
319 				MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059
320 				MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x13058
321 				>;
322	 		};
......
371 		pinctrl_flexcan1: flexcan1grp{
372 			fsl,pins = <
373 				MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
374 				MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
375 			>;
376 		};
......
587 		pinctrl_wdog: wdoggrp {
588 			fsl,pins = <
589 				MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
590 			>;
591 		};
592 	};
593 };

? ? ? ? ? ? ? ? ? ?以上代碼就是向iomuxc節點追加數據,不同的外設使用的PIN不同、其配置也不同,因

? ? ? ? ? ? ? ? ? ?此一個蘿卜一個坑,將某個外設所使用的所有PIN都組織在一個子節點里面。以上代碼

? ? ? ? ? ? ? ? ? ?中pinctrl_hog_1子節點就是和熱插拔有關的PIN集合,比如USBOTG的ID引腳。

? ? ? ? ? ? ? ? ? ? pinctrl_flexcan1子節點是flexcan1這個外設所使用的PIN,pinctrl_wdog子節點是wdog

? ? ? ? ? ? ? ? ? ?外設所使用的PIN。如果需要在iomuxc中添加我們自定義外設的PIN,那么需要新建一

? ? ? ? ? ? ? ? ? ?個子節點,然后將這個自定義外設的所有PIN配置信息都放到這個子節點中。將其與以

? ? ? ? ? ? ? ? ? ?上代碼結合起來就可以得到完成的iomuxc節點,如下所示:

1 iomuxc: iomuxc@020e0000 {
2 		compatible = "fsl,imx6ul-iomuxc";
3 		reg = <0x020e0000 0x4000>;
4 		pinctrl-names = "default";
5 		pinctrl-0 = <&pinctrl_hog_1>;
6 		imx6ul-evk {
7 			pinctrl_hog_1: hoggrp-1 {
8 				fsl,pins = <
9 						MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
10 						MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059
11 						MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059
12 						MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x13058
13				 >;
......
16 			};
17		};
18 };

? ? ? ? ? ? ? ? ? ?第2行,compatible屬性值為“fsl,imx6ul-iomuxc”,前面講解設備樹的時候說過,Linux

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 內核會根據compatbile屬性值來查找對應的驅動文件,所以我們在Linux內核源

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 碼中全局搜索字符串“fsl,imx6ul-iomuxc”就會找到I.MX6ULL這顆SOC的pinctrl

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 驅動文件。稍后我們會講解這個pinctrl驅動文件。

? ? ? ? ? ? ? ? ? ?第9~12行,pinctrl_hog_1子節點所使用的PIN配置信息,我們就以第9行的

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? UART1_RTS_B這個PIN為例,講解一下如何添加PIN的配置信息,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?UART1_RTS_B的配置信息如下:

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059

? ? ? ? ? ? ? ? ? ?首先說明一下,UART1_RTS_B這個PIN是作為SD卡的檢測引腳,也就是通過此PIN就

? ? ? ? ? ? ? ? ? ?可以檢測到SD卡是否有插入。UART1_RTS_B的配置信息分為兩部分:

? ? ? ? ? ? ? ? ? ?MX6UL_PAD_UART1_RTS_B__GPIO1_IO19和0x17059,我們重點來看一下這兩部

? ? ? ? ? ? ? ? ? ?分是什么含義,前面說了,對于一個PIN的配置主要包括兩方面,一個是設置這個PIN

? ? ? ? ? ? ? ? ? ?的復用功能,另一個就是設置這個PIN的電氣特性。所以我們可以大膽的猜測

? ? ? ? ? ? ? ? ? ?UART1_RTS_B的這兩部分配置信息一個是設置UART1_RTS_B的復用功能,一個是

? ? ? ? ? ? ? ? ? ?用來設置UART1_RTS_B的電氣特性。

? ? ? ? ? ? ? ? ? ?首先來看一下MX6UL_PAD_UART1_RTS_B__GPIO1_IO19,這是一個宏定義,定義

? ? ? ? ? ? ? ? ? ?在文件arch/arm/boot/dts/imx6ul-pinfunc.h中,imx6ull.dtsi會引用imx6ull-pinfunc.h這個

? ? ? ? ? ? ? ? ? ?頭文件,而imx6ull-pinfunc.h又會引用imx6ul-pinfunc.h這個頭文件(繞啊繞!)。從這

? ? ? ? ? ? ? ? ? ?里可以看出,可以在設備樹中引用C語言中.h文件中的內容。

? ? ? ? ? ? ? ? ? ?MX6UL_PAD_UART1_RTS_B__GPIO1_IO19的宏定義內容如下:

190 #define MX6UL_PAD_UART1_RTS_B__UART1_DCE_RTS 	0x0090 0x031C 0x0620 0x0 0x3
191 #define MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 	0x0090 0x031C 0x0000 0x0 0x0
192 #define MX6UL_PAD_UART1_RTS_B__ENET1_TX_ER 		0x0090 0x031C 0x0000 0x1 0x0
193 #define MX6UL_PAD_UART1_RTS_B__USDHC1_CD_B 		0x0090 0x031C 0x0668 0x2 0x1
194 #define MX6UL_PAD_UART1_RTS_B__CSI_DATA05 		0x0090 0x031C 0x04CC 0x3 0x1
195 #define MX6UL_PAD_UART1_RTS_B__ENET2_1588_EVENT1_OUT 	0x0090 0x031C 0x0000 0x4 0x0
196 #define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 				0x0090 0x031C 0x0000 0x5 0x0
197 #define MX6UL_PAD_UART1_RTS_B__USDHC2_CD_B 				0x0090 0x031C 0x0674 0x8 0x2

? ? ? ? ? ? ? ? ? ?以上代碼中一共有8個以“MX6UL_PAD_UART1_RTS_B”開頭的宏定義,大家仔細觀察

? ? ? ? ? ? ? ? ? ?應該就能發現,這8個宏定義分別對應UART1_RTS_B這個PIN的8個復用IO。查閱

? ? ? ? ? ? ? ? ?《I.MX6ULL參考手冊》可以知UART1_RTS_B的可選復用IO如圖1所示:

?圖1?UART1_RTS_B引腳復用

? ? ? ? ? ? ? ? ? ?以上代碼196行的宏定義MX6UL_PAD_UART1_RTS_B__GPIO1_IO19表示將

? ? ? ? ? ? ? ? ? ?UART1_RTS_B這個IO復用為GPIO1_IO19。此宏定義后面跟著5個數字,也就是這個

? ? ? ? ? ? ? ? ? ?宏定義的具體值,如下所示:

0x0090 0x031C 0x0000 0x5 0x0

? ? ? ? ? ? ? ? ? ?這5個值的含義如下所示:

<mux_reg conf_reg input_reg mux_mode input_val>

? ? ? ? ? ? ? ? ? ?綜上所述可知:

? ? ? ? ? ? ? ? ? ?0x0090:mux_reg寄存器偏移地址,設備樹中的iomuxc節點就是IOMUXC外設對應的

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?節點,根據其reg屬性可知IOMUXC外設寄存器起始地址為0x020e0000。因

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?此0x020e0000+0x0090=0x020e0090,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B寄存器地址正好是

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x020e0090,大家可以在《IMX6ULL參考手冊》中找到

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B這個寄存器的位域圖,如

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖2所示:?

?圖2?寄存器位域圖

? ? ? ? ? ? ? ? ? ?因此可知,0x020e0000+mux_reg就是PIN的復用寄存器地址。

? ? ? ? ? ? ? ? ? ?0x031C:conf_reg寄存器偏移地址,和mux_reg一樣,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x020e0000+0x031c=0x020e031c,這個就是寄存器

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IOMUXC_SW_PAD_CTL_PAD_UART1_RTS_B的地址。

? ? ? ? ? ? ? ? ? ?0x0000:input_reg寄存器偏移地址,有些外設有input_reg寄存器,有input_reg寄存

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?器的外設需要配置input_reg寄存器。沒有的話就不需要設置,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?UART1_RTS_B這個PIN在做GPIO1_IO19的時候是沒有input_reg寄存器,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?因此這里intput_reg是無效的。

? ? ? ? ? ? ? ? ? ?0x5:mux_reg寄存器值,在這里就相當于設置

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B寄存器為0x5,也即是設置

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?UART1_RTS_B這個PIN復用為GPIO1_IO19。

? ? ? ? ? ? ? ? ? ?0x0:input_reg寄存器值,在這里無效。

? ? ? ? ? ? ? ? ? ?這就是宏MX6UL_PAD_UART1_RTS_B__GPIO1_IO19的含義,看的比較仔細的同學

? ? ? ? ? ? ? ? ? ?應該會發現并沒有conf_reg寄存器的值,config_reg寄存器是設置一個PIN的電氣特性

? ? ? ? ? ? ? ? ? ?的,這么重要的寄存器怎么沒有值呢?回到以上代碼中,第9行的內容如下所示:

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059

? ? ? ? ? ? ? ? ? ?MX6UL_PAD_UART1_RTS_B__GPIO1_IO19我們上面已經分析了,就剩下了一個

? ? ? ? ? ? ? ? ? ?0x17059,反應快的同學應該已經猜出來了,0x17059就是conf_reg寄存器值!此值

? ? ? ? ? ? ? ? ? 由用戶自行設置,通過此值來設置一個IO的上/下拉、驅動能力和速度等。在這里就相

? ? ? ? ? ? ? ? ? 當于設置寄存器IOMUXC_SW_PAD_CTL_PAD_UART1_RTS_B的值為0x17059

? ? 3)設備樹中添加pinctrl節點模板

? ? ? ? ? ? ? 我們已經對pinctrl有了比較深入的了解,接下來我們學習一下如何在設備樹中添加某個外

? ? ? ? ? ? ? 設的PIN信息。關于I.MX系列SOC的pinctrl設備樹綁定信息可以參考文檔

? ? ? ? ? ? ? Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt。這里我們虛擬一個名為

? ? ? ? ? ? ? “test”的設備,test使用了GPIO1_IO00這個PIN的GPIO功能,pinctrl節點添加過程如下:

? ? ? ? ? ? ? 1、創建對應的節點

? ? ? ? ? ? ? ? ? ? 同一個外設的PIN都放到一個節點里面,打開imx6ull-alientek-emmc.dts,在iomuxc節

? ? ? ? ? ? ? ? ? ? 點中的“imx6ul-evk”子節點下添加“pinctrl_test”節點,注意!節點前綴一定要為

? ? ? ? ? ? ? ? ? ? “pinctrl_”。添加完成以后如下所示:

1 pinctrl_test: testgrp {
2     /* 具體的 PIN 信息 */
3 };

? ? ? ? ? ? ? 2、添加“fsl,pins”屬性

? ? ? ? ? ? ? ? ? ? 設備樹是通過屬性來保存信息的,因此我們需要添加一個屬性屬性名字一定要為

? ? ? ? ? ? ? ? ? ? “fsl,pins”,因為對于I.MX系列SOC而言,pinctrl驅動程序是通過讀取“fsl,pins”屬性值

? ? ? ? ? ? ? ? ? ? 來獲取PIN的配置信息,完成以后如下所示:

1 pinctrl_test: testgrp {
2 		fsl,pins = <
3 			/* 設備所使用的 PIN 配置信息 */
4 		>;
5 };

? ? ? ? ? ? ? 3、在“fsl,pins”屬性中添加PIN配置信息

? ? ? ? ? ? ? ? ? ?最后在“fsl,pins”屬性中添加具體的PIN配置信息,完成以后如下所示:

1 pinctrl_test: testgrp {
2 		fsl,pins = <
3 			MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 config /*config 是具體設置值*/
4 		>;
5 };

2.gpio子系統

? ? 1)gpio子系統簡介

? ? ? ? ? ? ? 上一小節講解了pinctrl子系統,pinctrl子系統重點是設置PIN(有的SOC叫做PAD)的復用和

? ? ? ? ? ? ? 電氣屬性,如果pinctrl子系統將一個PIN復用為GPIO的話,那么接下來就要用到gpio子系

? ? ? ? ? ? ? 統了。gpio子系統顧名思義,就是用于初始化GPIO并且提供相應的API函數比如設置

? ? ? ? ? ? ? GPIO為輸入輸出,讀取GPIO的值等gpio子系統的主要目的就是方便驅動開發者使用

? ? ? ? ? ? ? gpio,驅動開發者在設備樹中添加gpio相關信息,然后就可以在驅動程序中使用gpio子

? ? ? ? ? ? ?系統提供的API函數來操作GPIO,Linux內核向驅動開發者屏蔽掉了GPIO的設置過程,極

? ? ? ? ? ? ?大的方便了驅動開發者使用GPIO。

? ? 2)I.MX6ULL的的gpio子系統驅動

? ? ? ? ? ? ? 1、設備樹中的gpio信息

? ? ? ? ? ? ? ? ? ? I.MX6ULL-ALPHA開發板上的UART1_RTS_B做為SD卡的檢測引腳,UART1_RTS_B

? ? ? ? ? ? ? ? ? ? 復用為GPIO1_IO19,通過讀取這個GPIO的高低電平就可以知道SD卡有沒有插

? ? ? ? ? ? ? ? ? ? 入。首先肯定是將UART1_RTS_B這個PIN復用為GPIO1_IO19,并且設置電氣屬性,

? ? ? ? ? ? ? ? ? ? 也就是上一小節講的pinctrl節點。打開imx6ull-alientek-emmc.dts,UART1_RTS_B這

? ? ? ? ? ? ? ? ? ? 個PIN的pincrtl設置如下:

316 pinctrl_hog_1: hoggrp-1 {
317 	fsl,pins = <
318 		MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
......
322 	>;
323 };

? ? ? ? ? ? ? ? ? ? 第318行,設置UART1_RTS_B這個PIN為GPIO1_IO19。

? ? ? ? ? ? ? ? ? ? pinctrl配置好以后就是設置gpio了,SD卡驅動程序通過讀取GPIO1_IO19的值來判斷

? ? ? ? ? ? ? ? ? ? SD卡有沒有插入,但是SD卡驅動程序怎么知道CD引腳連接的GPIO1_IO19呢?肯定

? ? ? ? ? ? ? ? ? ? 是需要設備樹告訴驅動啊!在設備樹中SD卡節點下添加一個屬性來描述SD卡的CD引

? ? ? ? ? ? ? ? ? ? 腳就行了,SD卡驅動直接讀取這個屬性值就知道SD卡的CD引腳使用的是哪個GPIO

? ? ? ? ? ? ? ? ? ? 了。SD卡連接在I.MX6ULL的usdhc1接口上,在imx6ull-alientek-emmc.dts中找到名

? ? ? ? ? ? ? ? ? ? 為“usdhc1”的節點,這個節點就是SD卡設備節點,如下所示:

760 &usdhc1 {
761 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
762 	pinctrl-0 = <&pinctrl_usdhc1>;
763 	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
764 	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
765 	/* pinctrl-3 = <&pinctrl_hog_1>; */
766 	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
767 	keep-power-in-suspend;
768 	enable-sdio-wakeup;
769 	vmmc-supply = <&reg_sd1_vmmc>;
770 	status = "okay";
771 };

? ? ? ? ? ? ? ? ? ?第765行,此行本來沒有,是作者添加的,usdhc1節點作為SD卡設備總節點,usdhc1

? ? ? ? ? ? ? ? ? ?節點需要描述SD卡所有的信息,因為驅動要使用。本行就是描述SD卡的CD引腳

? ? ? ? ? ? ? ? ? ?pinctrl信息所在的子節點,因為SD卡驅動需要根據pincrtl節點信息來設置CD引腳的復

? ? ? ? ? ? ? ? ? ?用功能等。762~764行的pinctrl-0~2都是SD卡其他PIN的pincrtl節點信息。但是大家

? ? ? ? ? ? ? ? ? ?會發現,其實在usdhc1節點中并沒有“pinctrl-3=<&pinctrl_hog_1>”這一行,也就是說

? ? ? ? ? ? ? ? ? ?并沒有指定CD引腳的pinctrl信息,那么SD卡驅動就沒法設置CD引腳的復用功能啊?

? ? ? ? ? ? ? ? ? ?這個不用擔心,因為在“iomuxc”節點下引用了pinctrl_hog_1這個節點,所以Linux內

? ? ? ? ? ? ? ? ? ?核中的iomuxc驅動就會自動初始化pinctrl_hog_1節點下的所有PIN。

? ? ? ? ? ? ? ? ? ?第766行,屬性“cd-gpios”描述了SD卡的CD引腳使用的哪個IO。屬性值一共有三個,

? ? ? ? ? ? ? ? ? ?我們來看一下這三個屬性值的含義,“&gpio1”表示CD引腳所使用的IO屬于GPIO1組,

? ? ? ? ? ? ? ? ? ? “19”表示GPIO1組的第19號IO,通過這兩個值SD卡驅動程序就知道CD引腳使用了

? ? ? ? ? ? ? ? ? ?GPIO1_IO19這GPIO?!癎PIO_ACTIVE_LOW”表示低電平有效,如果改為

? ? ? ? ? ? ? ? ? ?“GPIO_ACTIVE_HIGH”就表示高電平有效。

? ? ? ? ? ? ? ? ? ?根據上面這些信息,SD卡驅動程序就可以使用GPIO1_IO19來檢測SD卡的CD信號

? ? ? ? ? ? ? ? ? ?了,打開imx6ull.dtsi,在里面找到如下所示內容:

504 gpio1: gpio@0209c000 {
505 	compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
506 	reg = <0x0209c000 0x4000>;
507 	interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
508 		<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
509 	gpio-controller;
510 	#gpio-cells = <2>;
511 	interrupt-controller;
512 	#interrupt-cells = <2>;
513 };

? ? ? ? ? ? ? ? ? ? gpio1節點信息描述了GPIO1控制器的所有信息,重點就是GPIO1外設寄存器基地址以

? ? ? ? ? ? ? ? ? ? 及兼容屬性。

? ? ? ? ? ? ? ? ? ? 第505行,設置gpio1節點的compatible屬性有兩個,分別為“fsl,imx6ul-gpio”和

? ? ? ? ? ? ? ? ? ? “fsl,imx35-gpio”,在Linux內核中搜索這兩個字符串就可以找到I.MX6UL的GPIO驅動

? ? ? ? ? ? ? ? ? ? 程序。

? ? ? ? ? ? ? ? ? ? 第506行,reg屬性設置了GPIO1控制器的寄存器基地址為0X0209C000,大家可以打

? ? ? ? ? ? ? ? ? ? 開《I.MX6ULL參考手冊》找到“Chapter28:General Purpose Input/Output(GPIO)”章節

? ? ? ? ? ? ? ? ? ? 第28.5小節,有如圖3所示的寄存器地址表:

圖3?GPIO1寄存器表

? ? ? ? ? ? ? ? ? ? 從圖3可以看出,GPIO1控制器的基地址就是0X0209C000。

? ? ? ? ? ? ? ? ? ? 第509行,“gpio-controller”表示gpio1節點是個GPIO控制器。

? ? ? ? ? ? ? ? ? ? 第510行,“#gpio-cells”屬性和“#address-cells”類似,#gpio-cells應該為2,表示一共有

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 兩個cell,第一個cell為GPIO編號,比如“&gpio1 3”就表示GPIO1_IO03。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第二個cell表示GPIO極性,如果為0(GPIO_ACTIVE_HIGH)的話表示高電

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?平有效,如果為1(GPIO_ACTIVE_LOW)的話表示低電平有效。

? ? 3)gpio子系統API函數

? ? ? ? ? ? ? ?對于驅動開發人員,設置好設備樹以后就可以使用gpio子系統提供的API函數來操作指定

? ? ? ? ? ? ? ?的GPIO,gpio子系統向驅動開發人員屏蔽了具體的讀寫寄存器過程。這就是驅動分層與

? ? ? ? ? ? ? ?分離的好處,大家各司其職,做好自己的本職工作即可。gpio子系統提供的常用的API函

? ? ? ? ? ? ? ?數有下面幾個:

? ? ? ? ? ? ? ?1、gpio_request函數

? ? ? ? ? ? ? ? ? ? ? ? gpio_request函數用于申請一個GPIO管腳,在使用一個GPIO之前一定要使用

? ? ? ? ? ? ? ? ? ? ? ? gpio_request進行申請,函數原型如下:

int gpio_request(unsigned gpio, const char *label)

? ? ? ? ? ? ? ? ? ? ? ?函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? ?gpio:要申請的gpio標號,使用of_get_named_gpio()函數從設備樹獲取指定GPIO

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 屬性信息,此函數會返回這個GPIO的標號。

? ? ? ? ? ? ? ? ? ? ? ?label:給gpio設置個名字。

? ? ? ? ? ? ? ? ? ? ? ?返回值:0,申請成功;其他值,申請失敗。

? ? ? ? ? ? ? ?2、gpio_free函數

? ? ? ? ? ? ? ? ? ? ? ?如果不使用某個GPIO了,那么就可以調用gpio_free函數進行釋放。函數原型如下:

void gpio_free(unsigned gpio)

? ? ? ? ? ? ? ? ? ? ? ?函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? ?gpio:要釋放的gpio標號。

? ? ? ? ? ? ? ? ? ? ? ?返回值:無

? ? ? ? ? ? ? ?3、gpio_direction_input函數

? ? ? ? ? ? ? ? ? ? ? 此函數用于設置某個GPIO為輸入,函數原型如下所示:

int gpio_direction_input(unsigned gpio)

? ? ? ? ? ? ? ? ? ? ? 函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? gpio:要設置為輸入的GPIO標號。

? ? ? ? ? ? ? ? ? ? ? 返回值:0,設置成功;負值,設置失敗。

? ? ? ? ?? ? ?4、gpio_direction_output函數

? ? ? ? ? ? ? ? ? ? ? 此函數用于設置某個GPIO為輸出,并且設置默認輸出值,函數原型如下:

int gpio_direction_output(unsigned gpio, int value)

? ? ? ? ? ? ? ? ? ? ? ?函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? ?gpio:要設置為輸出的GPIO標號。

? ? ? ? ? ? ? ? ? ? ? ?value:GPIO默認輸出值。

? ? ? ? ? ? ? ? ? ? ? ?返回值:0,設置成功;負值,設置失敗。

? ? ? ? ? ? ? ?5、gpio_get_value函數

? ? ? ? ? ? ? ? ? ? ? 此函數用于獲取某個GPIO的值(0或1),此函數是個宏,定義所示:

#define gpio_get_value  __gpio_get_value
int __gpio_get_value(unsigned gpio)

? ? ? ? ? ? ? ? ? ? ? 函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? gpio:要獲取的GPIO標號。

? ? ? ? ? ? ? ? ? ? ? 返回值:非負值,得到的GPIO值;負值,獲取失敗。

? ? ? ? ? ? ? ?6、gpio_set_value函數

? ? ? ? ? ? ? ? ? ? ? 此函數用于設置某個GPIO的值,此函數是個宏,定義如下

#define gpio_set_value  __gpio_set_value
void __gpio_set_value(unsigned gpio, int value)

? ? ? ? ? ? ? ? ? ? ? 函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? gpio:要設置的GPIO標號。

? ? ? ? ? ? ? ? ? ? ? value:要設置的值。

? ? ? ? ? ? ? ? ? ? ? 返回值:無

關于gpio子系統常用的API函數就講這些,這些是我們用的最多的。

? ? 4)設備樹中添加gpio節點模板

? ? ? ? ? ? ? ?繼續完成之前的test設備,在之前中我們已經講解了如何創建test設備的pinctrl節點。本

? ? ? ? ? ? ? ?節我們來學習一下如何創建test設備的GPIO節點。

? ? ? ? ? ?1、創建test設備節點

? ? ? ? ? ? ? ? ? ? ? ? 在根節點“/”下創建test設備子節點,如下所示:

1 test {
2 	/* 節點內容 */
3 };

? ? ? ? ? ?2、添加pinctrl信息

? ? ? ? ? ? ? ? ? ? ? ?在之前我們創建了pinctrl_test節點,此節點描述了test設備所使用的GPIO1_IO00這

? ? ? ? ? ? ? ? ? ? ? ?個PIN的信息,我們要將這節點添加到test設備節點中,如下所示:

1 test {
2 		pinctrl-names = "default";
3 		pinctrl-0 = <&pinctrl_test>;
4 		/* 其他節點內容 */
5 };

? ? ? ? ? ? ? ? ? ? ? ?第2行,添加pinctrl-names屬性,此屬性描述pinctrl名字為“default”。

? ? ? ? ? ? ? ? ? ? ? ?第3行,添加pinctrl-0節點,此節點引用之前創建的pinctrl_test節點,表示tset設備的

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?所使用的PIN信息保存在pinctrl_test節點中。

? ? ? ? ? ?3、添加GPIO屬性信息

? ? ? ? ? ? ? ? ? ? ? ?我們最后需要在test節點中添加GPIO屬性信息表明test所使用的GPIO是哪個引

? ? ? ? ? ? ? ? ? ? ? ?腳,添加完成以后如下所示:

1 test {
2 		pinctrl-names = "default";
3 		pinctrl-0 = <&pinctrl_test>;
4 		gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
5 };

? ? ? ? ? ? ? ? ? ? ? ? 第4行,test設備所使用的gpio。

? ? ? ? ? ? ? ? ? ? ? ?關于pinctrl子系統和gpio子系統就講解到這里,接下來就使用pinctrl和gpio子系統來

? ? ? ? ? ? ? ? ? ? ? ?驅動I.MX6ULL-ALPHA開發板上的LED燈。

? ? 5)與gpio相關的OF函數

? ? ? ? ? ? ? ?在之前的代碼中,我們定義了一個名為“gpio”的屬性,gpio屬性描述了test這個設備所使

? ? ? ? ? ? ? ?用的GPIO。在驅動程序中需要讀取gpio屬性內容,Linux內核提供了幾個與GPIO有關的

? ? ? ? ? ? ? ?OF函數,常用的幾個OF函數如下所示:

? ? ? ? ? ? ? ?1、of_gpio_named_count函數

? ? ? ? ? ? ? ? ? ? ?of_gpio_named_count函數用于獲取設備樹某個屬性里面定義了幾個GPIO信息,要

? ? ? ? ? ? ? ? ? ? ? 注意的是空的GPIO信息也會被統計到,比如:

gpios = <0&gpio1 1 20&gpio2 3 4>;

? ? ? ? ? ? ? ? ? ? ?上述代碼的“gpios”節點一共定義了4個GPIO,但是有2個是空的,沒有實際的含義。

? ? ? ? ? ? ? ? ? ? ? 通過of_gpio_named_count函數統計出來的GPIO數量就是4個,此函數原型如下:

int of_gpio_named_count(struct device_node *np, const char *propname)

? ? ? ? ? ? ? ? ? ? ? 函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? np:設備節點。

? ? ? ? ? ? ? ? ? ? ? propname:要統計的GPIO屬性。

? ? ? ? ? ? ? ? ? ? ? 返回值:正值,統計到的GPIO數量;負值,失敗。

? ? ? ? ? ? ? ? 2、of_gpio_count函數

? ? ? ? ? ? ? ? ? ? ? 和of_gpio_named_count函數一樣,但是不同的地方在于,此函數統計的是“gpios”

? ? ? ? ? ? ? ? ? 這個屬性的GPIO數量,而of_gpio_named_count函數可以統計任意屬性的GPIO信息,

? ? ? ? ? ? ? ? ? ? ? ?函數原型如下所示:

int of_gpio_count(struct device_node *np)

? ? ? ? ? ? ? ? ? ? ? ?函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? ?np:設備節點。

? ? ? ? ? ? ? ? ? ? ? ?返回值:正值,統計到的GPIO數量;負值,失敗。

? ? ? ? ? ? ? ? 3、of_get_named_gpio函數

? ? ? ? ? ? ? ? ? ? ? 此函數獲取GPIO編號,因為Linux內核中關于GPIO的API函數都要使用GPIO編號,

? ? ? ? ? ? ? ? ? ? ? 此函數會將設備樹中類似<&gpio5 7 GPIO_ACTIVE_LOW>的屬性信息轉換為對應的

? ? ? ? ? ? ? ? ? ? ? GPIO編號,此函數在驅動中使用很頻繁!函數原型如下:

int of_get_named_gpio(struct device_node *np, const char *propname, int index)

? ? ? ? ? ? ? ? ? ? ? 函數參數和返回值含義如下:

? ? ? ? ? ? ? ? ? ? ? np:設備節點。

? ? ? ? ? ? ? ? ? ? ? propname:包含要獲取GPIO信息的屬性名。

? ? ? ? ? ? ? ? ? ? ? index:GPIO索引,因為一個屬性里面可能包含多個GPIO,此參數指定要獲取哪個

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GPIO的編號,如果只有一個GPIO信息的話此參數為0。

? ? ? ? ? ? ? ? ? ? ? 返回值:正值,獲取到的GPIO編號。負值,失敗。

4.實驗程序編寫

? ? 1)修改設備樹文件

? ? ? ? ? ?1、添加pinctrl節點

? ? ? ? ? ? ? ? ? ? ? ?I.MX6U-ALPHA開發板上的LED燈使用了GPIO1_IO03這個PIN,打開imx6ull-

? ? ? ? ? ? ? ? ? ? ? ?alientek-emmc.dts,在iomuxc節點的imx6ul-evk子節點下創建一個名為

? ? ? ? ? ? ? ? ? ? ? ?“pinctrl_led”的子節點,節點內容如下所示:

1 pinctrl_led: ledgrp {
2 		fsl,pins = <
3 				MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */
4 		>;
5 };

? ? ? ? ? ? ? ? ? ? ? 第3行,將GPIO1_IO03這個PIN復用為GPIO1_IO03,電氣屬性值為0X10B0。

? ? ? ? ? ?2、添加LED設備節點

? ? ? ? ? ? ? ? ? ? ? ?在根節點“/”下創建LED燈節點,節點名為“gpioled”,節點內容如下:

1 gpioled {
2 		#address-cells = <1>;
3 		#size-cells = <1>;
4 		compatible = "atkalpha-gpioled";
5 		pinctrl-names = "default";
6 		pinctrl-0 = <&pinctrl_led>;
7 		led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
8 		status = "okay";
9 }

? ? ? ? ? ? ? ? ? ? ? ?第6行,pinctrl-0屬性設置LED燈所使用的PIN對應的pinctrl節點。

? ? ? ? ? ? ? ? ? ? ? ?第7行,led-gpio屬性指定了LED燈所使用的GPIO,在這里就是GPIO1的IO03,低

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 電平有效。

? ? ? ? ? ? ? ? ? ? ? ?稍后編寫驅動程序的時候會獲取led-gpio屬性的內容來得到GPIO編號,因為gpio子

? ? ? ? ? ? ? ? ? ? ? ?系統的API操作函數需要GPIO編號。

? ? ? ? ? ?3、檢查PIN是否被其他外設使用

? ? ? ? ? ? ? ? ? ? ? ?這一點非常重要!!!

? ? ? ? ? ? ? ? ? ? ? 很多初次接觸設備樹的驅動開發人員很容易因為這個小問題栽了大跟頭!因為我們所

? ? ? ? ? ? ? ? ? ? ? 使用的設備樹基本都是在半導體廠商提供的設備樹文件基礎上修改而來的,而半導體

? ? ? ? ? ? ? ? ? ? ? 廠商提供的設備樹是根據自己官方開發板編寫的,很多PIN的配置和我們所使用的開

? ? ? ? ? ? ? ? ? ? ? 發板不一樣。比如A這個引腳在官方開發板接的是I2C的SDA,而我們所使用的硬件

? ? ? ? ? ? ? ? ? ? ? 可能將A這個引腳接到了其他的外設,比如LED燈上,接不同的外設,A這個引腳的

? ? ? ? ? ? ? ? ? ? ? 配置就不同。一個引腳一次只能實現一個功能,如果A引腳在設備樹中配置為了I2C

? ? ? ? ? ? ? ? ? ? ? 的SDA信號,那么A引腳就不能再配置為GPIO,否則的話驅動程序在申請GPIO的時

? ? ? ? ? ? ? ? ? ? ? 候就會失敗。檢查PIN有沒有被其他外設使用包括兩個方面:

? ? ? ? ? ? ? ? ? ? ? 1.檢查pinctrl設置。

? ? ? ? ? ? ? ? ? ? ? 2.如果這個PIN配置為GPIO的話,檢查這個GPIO有沒有被別的外設使用。

? ? ? ? ? ? ? ? ? ? ? 在本章實驗中LED燈使用的PIN為GPIO1_IO03,因此先檢查GPIO_IO03這個PIN有

? ? ? ? ? ? ? ? ? ? ? 沒有被其他的pinctrl節點使用,在imx6ull-alientek-emmc.dts中找到如下內容:

480 pinctrl_tsc: tscgrp {
481 	fsl,pins = <
482 		MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
483 		MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
484 		MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
485 		MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
486 	>;
487 };

? ? ? ? ? ? ? ? ? ? ? pinctrl_tsc節點是TSC(電阻觸摸屏接口)的pinctrl節點,從第484行可以看出,默認情

? ? ? ? ? ? ? ? ? ? ? 況下GPIO1_IO03作為了TSC外設的PIN。所以我們需要將第484行屏蔽掉!和C語言

? ? ? ? ? ? ? ? ? ? ? 一樣,在要屏蔽的內容前后加上“/*”和“*/”符號即可。其實在I.MX6U-ALPHA開發板上

? ? ? ? ? ? ? ? ? ? ? 并沒有用到TSC接口,所以第482~485行的內容可以全部屏蔽掉。

? ? ? ? ? ? ? ? ? ? ? 因為本章實驗我們將GPIO1_IO03這個PIN配置為了GPIO,所以還需要查找一下有沒

? ? ? ? ? ? ? ? ? ? ? 有其他的外設使用了GPIO1_IO03,在imx6ull-alientek-emmc.dts中搜索“gpio1 3”,

? ? ? ? ? ? ? ? ? ? ? ?找到如下內容:

723 &tsc {
724 	pinctrl-names = "default";
725 	pinctrl-0 = <&pinctrl_tsc>;
726 	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
727 	measure-delay-time = <0xffff>;
728 	pre-charge-time = <0xfff>;
729 	status = "okay";
730 };

? ? ? ? ? ? ? ? ? ? ? ?tsc是TSC的外設節點,從726行可以看出,tsc外設也使用了GPIO1_IO03,同樣我

? ? ? ? ? ? ? ? ? ? ? ?們需要將這一行屏蔽掉。然后在繼續搜索“gpio1 3”,看看除了本章的LED燈以外還

? ? ? ? ? ? ? ? ? ? ? ?有沒有其他的地方也使用了GPIO1_IO03,找到一個屏蔽一個。

? ? ? ? ? ? ? ? ? ? ? ?設備樹編寫完成以后使用“make dtbs”命令重新編譯設備樹,然后使用新編譯出來的

? ? ? ? ? ? ? ? ? ? ? ?imx6ull-alientek-emmc.dtb文件啟動Linux系統。啟動成功以后進入“/proc/device-

? ? ? ? ? ? ? ? ? ? ? ?tree”目錄中查看“gpioled”節點是否存在,如果存在的話就說明設備樹基本修改成

? ? ? ? ? ? ? ? ? ? ? ?功?(具體還要驅動驗證),結果如圖4所示:

?圖4??gpio子節點

5.運行測試

? ? 1)編譯驅動程序和測試APP

? ? ? ? ? ?1、編譯驅動程序

? ? ? ? ? ? ? ? ? ? ? ? 編寫Makefile文件,本章實驗的Makefile文件和之前

? ? ? ? ? ? ? ? ? ? ? ? 實驗基本一樣,只是將obj-m變量的值改為gpioled.o,Makefile內容如下所示:

1 KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
......
4 obj-m := gpioled.o .o
......
11 clean:
12 $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

? ? ? ? ? ? ? ? ? ? ? ? ?第4行,設置obj-m變量的值為gpioled.o。

? ? ? ? ? ? ? ? ? ? ? ? ? 輸入如下命令編譯出驅動模塊文件:

make -j32

? ? ? ? ? ? ? ? ? ? ? ? ?編譯成功以后就會生成一個名為“gpioled.ko”的驅動模塊文件。

? ? ? ? ? ? 2、編譯測試APP

? ? ? ? ? ? ? ? ? ? ? ? ?輸入如下命令編譯測試ledApp.c這個測試程序:

arm-linux-gnueabihf-gcc ledApp.c -o ledApp

? ? ? ? ? ? ? ? ? ? ? ? ? 編譯成功以后就會生成 ledApp這個應用程序。

? ? 2)運行測試

? ? ? ? ? ? ? ?將上一小節編譯出來的gpioled.ko和ledApp這兩個文件拷貝到rootfs/lib/modules/4.1.15目

? ? ? ? ? ? ? ?錄中,重啟開發板,進入到目錄lib/modules/4.1.15中,輸入如下命令加載gpioled.ko驅動

? ? ? ? ? ? ? ?模塊:

depmod //第一次加載驅動的時候需要運行此命令
modprobe gpioled.ko //加載驅動

? ? ? ? ? ? ? ?驅動加載成功以后會在終端中輸出一些信息,如圖5所示:

?圖5?驅動加載成功以后輸出的信息

? ? ? ? ? ? ? ?從圖5可以看出,gpioled這個節點找到了,并且GPIO1_IO03這個GPIO的編號為3。驅動

? ? ? ? ? ? ? ?加載成功以后就可以使用ledApp軟件來測試驅動是否工作正常,輸入如下命令打開LED

? ? ? ? ? ? ? ?燈:?

./ledApp /dev/gpioled 1 //打開 LED 燈

? ? ? ? ? ? ? ?輸入上述命令以后觀察I.MX6U-ALPHA開發板上的紅色LED燈是否點亮,如果點亮的話說

? ? ? ? ? ? ? ?明驅動工作正常。在輸入如下命令關閉LED燈:

./ledApp /dev/gpioled 0 //打開 LED 燈

? ? ? ? ? ? ? ?輸入上述命令以后觀察I.MX6U-ALPHA開發板上的紅色LED燈是否熄滅。如果要卸載驅動

? ? ? ? ? ? ? ?的話輸入 如下命令即可:

rmmod gpioled.ko

總結

以上是生活随笔為你收集整理的pinctrl和gpio子系统的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。