正如學(xué)習(xí)C語(yǔ)言時(shí)寫的第一段代碼都是“HelloWorld!”,接觸一款新的處理器時(shí)往往是從點(diǎn)亮一個(gè)LED開始;而點(diǎn)亮一個(gè)LED,則需要操作這款芯片的GPIO外設(shè)。
那么作為廣受歡迎的i.MX6ULL處理器,它的GPIO外設(shè)應(yīng)該如何配置呢?今天小編就將通過(guò)飛凌嵌入式的OKMX6ULL-S開發(fā)板來(lái)為大家詳細(xì)介紹。
i.MX6ULL處理器的GPIO配置
i.MX6ULL運(yùn)行的是Linux系統(tǒng),眾所周知Linux下一切皆文件。在Linux系統(tǒng)當(dāng)中,有一個(gè)文件專門用于配置處理器的各個(gè)外設(shè),包括GPIO,這個(gè)文件被稱為“設(shè)備樹”,i.MX6ULL的設(shè)備樹在內(nèi)核源碼中的路徑為:arch/arm/boot/dtbs/。
在這個(gè)路徑下我們可以看到很多設(shè)備樹文件,我們要使用的設(shè)備樹是:okmx6ull-s-emmc.dts以及okmx6ull-s-nand.dts。打開以上任意一個(gè)設(shè)備樹文件,可以看到二者均引用了imx6ull-14x14-evk.dts,因此對(duì)設(shè)備樹的修改都是基于imx6ull-14x14-evk.dts。
找到其中的 &iomuxc 節(jié)點(diǎn),可以看到在 pinctrl_hog_1:hoggrp-1 節(jié)點(diǎn)下已有部分GPIO復(fù)用,內(nèi)容如下:
1、硬件原理分析
查看硬件原理圖,6ULL-S底板上有兩個(gè)LED,以LED2為例,LED2的陰極接在了GPIO9引腳上,當(dāng)GPIO9為低時(shí),LED點(diǎn)亮。
打開硬件資料/用戶手冊(cè)/FETMX6ULx-S核心板管腳功能分配表20200624.xlsx,通過(guò)查表得知GPIO9對(duì)應(yīng)的是i.MX6ULL的GPIO1_IO09。
2、設(shè)置引腳復(fù)用
前面我們提到了&iomuxc節(jié)點(diǎn)下增加引腳復(fù)用,參數(shù)我們先設(shè)置為0x17059,后面會(huì)解釋配置方法。配置如下:
3、注釋掉沖突部分
接下來(lái)打開內(nèi)核源碼中的:arch/arm/boot/dts/imx6ull-14x14-evk.dts
因接下來(lái)要對(duì)GPIO進(jìn)行操作,為防止該節(jié)點(diǎn)影響,需要注釋掉設(shè)備樹中的LED節(jié)點(diǎn),如下圖紅框中所示:
4、更新設(shè)備樹
重新編譯設(shè)備樹,命令如下:
/opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi //執(zhí)行環(huán)境變量
make dtbs 這條命令會(huì)編譯所有的設(shè)備樹,編譯后再次查看確認(rèn)已經(jīng)生成新的dtb文件。
接下來(lái),我們將剛剛生成的設(shè)備樹文件拷貝到OKMX6ULL-S開發(fā)板——可以通過(guò)U盤,也可以通過(guò)TFTP、NFS、FTP這樣的網(wǎng)絡(luò)服務(wù)將生成的dtb文件拷貝到開發(fā)板上。
以eMMC版本為例,我們可以直接將設(shè)備樹文件:okmx6ull-s-emmc.dtb拷貝到/run/media/mmcblk1p1/路徑下,替換掉該路徑下的同名文件,之后重啟開發(fā)板。
5、操作GPIO
1. 計(jì)算對(duì)應(yīng)sys/class/gpio的值GPIOn_IOx= (n-1)*32 + x
GPIO1_IO09=(1- 1)*32 + 9 = 9
2. 將GPIO1_IO09=設(shè)置為輸出
echo9 > /sys/class/gpio/export 用于通知系統(tǒng)需要導(dǎo)出控制的GPIO引腳編號(hào)
echo"out" > /sys/class/gpio/gpio9/direction 控制為輸出
echo"1" > /sys/class/gpio/gpio9/value 輸出為高電平,LED熄滅
或者echo"0" > /sys/class/gpio/gpio9/value輸出為低電平,LED點(diǎn)亮
echo9 > /sys/class/gpio/unexport 通知系統(tǒng)取消導(dǎo)出
6、GPIO參數(shù)詳解
現(xiàn)在我們轉(zhuǎn)過(guò)頭來(lái)了解一下剛剛都用到了哪些參數(shù):
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09這一長(zhǎng)串,是一個(gè)宏定義,可以在imx6ul-pinfunc.h文件當(dāng)中查看,細(xì)心的小伙伴可能已經(jīng)注意到了imx6ul-pinfunc.h這個(gè)文件是6UL的,這是因?yàn)閕mx6ull-pinfunc.h引用了imx6ul-pinfunc.h,并且增加了部分內(nèi)容。
打開arch/arm/boot/dtbs/imx6ul-pinfunc.h文件,找到MX6UL_PAD_GPIO1_IO09的宏定義如下:
這些宏定義就是GPIO1_IO09這個(gè)引腳可以復(fù)用的功能。每一個(gè)宏定義后面都有5個(gè)參數(shù),再加上剛剛我們?cè)?amp;iomuxc節(jié)點(diǎn)下配置的0x17059一共是6個(gè)參數(shù),通過(guò)它們就可以完成一個(gè)GPIO的配置了,這6個(gè)參數(shù)分別為:
mux_ctrl_ofs:MUX寄存器偏移地址
pad_ctrl_ofs:PAD寄存器偏移地址
sel_input_ofs:輸入選擇寄存器偏移地址
mux_mode:MUX寄存器值
sel_input:輸入選擇寄存器值
pad_ctrl:PAD寄存器值
以上6個(gè)參數(shù)對(duì)應(yīng)了3個(gè)寄存器的偏移地址和寄存器值。我們接下來(lái)重點(diǎn)介紹一下MUX寄存器和PAD寄存器。
1. MUX寄存器
全名是SW_MUX_CTL_PAD_GPIO1_IO09,意為GPIO復(fù)用寄存器,在i.MX6ULL的數(shù)據(jù)手冊(cè)有它的詳細(xì)介紹,我們可以從飛凌官方提供的資料中找到:硬件資料/數(shù)據(jù)手冊(cè)/i.MX6ULLRM.pdf。
打開32.6.16小節(jié),可以看到寄存器偏移地址和我們官方提供的文件中是一致的。而ALT0-ALT8則分別對(duì)應(yīng)了這個(gè)GPIO可以復(fù)用的功能,0x5對(duì)應(yīng)的就是將GPIO5_IO09復(fù)用成GPIO1_IO09。
2. PAD寄存器
全稱SW_PAD_CTL_PAD_GPIO1_IO09,意為GPIO電氣參數(shù)配置寄存器,這個(gè)是我們需要重點(diǎn)關(guān)注的內(nèi)容,因?yàn)闊o(wú)論是剛剛提到的MUX寄存器,還是輸入選擇寄存器,NXP官方都已經(jīng)為我們寫好了宏定義,但是這個(gè)寄存器的值,需要用戶根據(jù)自身需求來(lái)設(shè)置,參考的資料依舊是i.MX6ULLRM.pdf,在32.6.162小節(jié),有關(guān)于PAD寄存器每一位的詳細(xì)解釋。
HYS(bit16):使能遲滯比較器,當(dāng)IO作為輸入功能的時(shí)候有效,開啟遲滯比較器可以濾掉一些干擾。這一位為0時(shí)禁止遲滯比較器,為1時(shí)使能遲滯比較器。
PUS(bit15:14):設(shè)置上下拉電阻,一共有四種選項(xiàng)可以選擇:
PUE(bit13):當(dāng)IO作為輸入的時(shí)候,這一位用來(lái)設(shè)置IO使用上下拉還是狀態(tài)保持器。當(dāng)為0的時(shí)候使用狀態(tài)保持器,當(dāng)為1的時(shí)候使用上下拉。狀態(tài)保持器在IO作為輸入的時(shí)候才有用,顧名思義,就是當(dāng)外部電路斷電以后此IO口可以保持住以前的狀態(tài)。
PKE(bit12):此位用來(lái)使能或者禁止上下拉/狀態(tài)保持器功能,這一位為0時(shí)禁止上下拉/狀態(tài)保持器,為1時(shí)使能上下拉和狀態(tài)保持器。
ODE(bit11):開漏使能,當(dāng)IO作為輸出的時(shí)候,用來(lái)禁止或者使能開漏輸出,這一位為0的時(shí)候禁止開漏輸出,為1的時(shí)候就使能開漏輸出功能。
SPEED(bit7:6):當(dāng)IO用作輸出的時(shí)候,此位用來(lái)設(shè)置IO速度。
DSE(bit5:3):當(dāng)IO用作輸出的時(shí)候用來(lái)設(shè)置IO的驅(qū)動(dòng)能力,可以簡(jiǎn)單理解為IO口上串聯(lián)的電阻大小,電阻越小驅(qū)動(dòng)能力越強(qiáng),總共有8個(gè)可選項(xiàng):
SRE(bit0):IO翻轉(zhuǎn)速度,為1時(shí)IO電平跳變時(shí)間更快,對(duì)應(yīng)波形更陡;為0時(shí)IO電平跳變時(shí)間要慢一些,波形也更平緩。
介紹完了PAD寄存器的每一位,我們?cè)倩仡^看一下剛剛配置的0x17059,將它展開成二進(jìn)制為:0001 0111 0000 0101 1001。
bit15:14設(shè)置為01,對(duì)應(yīng)的是100K上拉,這是因?yàn)長(zhǎng)ED的陰極接到了GPIO上,保持默認(rèn)狀態(tài)下LED為熄滅狀態(tài)。
bit5:3,這里配置的是R0/6,小伙伴們也可以試一下配置成其他的值,觀察LED的亮度會(huì)不會(huì)有變化。
以上就是為i.MX6ULL處理器配置GPIO的全過(guò)程,希望能夠?qū)ζ聊磺暗母魑?a class="article-link" target="_blank" href="/tag/%E5%B7%A5%E7%A8%8B%E5%B8%88/">工程師小伙伴有所幫助。想要了解更多有關(guān)FETMX6ULL-S詳情和資料,可進(jìn)入飛凌嵌入式官網(wǎng)。
作者:李寧寧