GPIO(General-purpose input/output)即通用輸入輸出,根據(jù)名字就能夠了解到在實(shí)際應(yīng)用中可以有很多種用途,最常見的便是用來控制LED燈的亮滅,或用來偵測(cè)輸入信號(hào)的高低變化。英創(chuàng)工控主板都給用戶提供了豐富的GPIO資源,ESMARC系列的板卡擁有32位GPIO,為了方便用戶能夠更方便的進(jìn)行開發(fā),英創(chuàng)公司進(jìn)一步在軟件上也增加了一些實(shí)用的功能。在GPIO用作控制LED燈的時(shí)候,用戶可以直接使用Linux的LED子系統(tǒng)來對(duì)指定的GPIO口進(jìn)行設(shè)置和操作,比如LED的亮滅或者設(shè)置觸發(fā)方式等。如果是將GPIO設(shè)置為輸入狀態(tài)偵測(cè)輸入信號(hào)的高低變化,一旦電平發(fā)生變化,內(nèi)核就會(huì)通知應(yīng)用程序,這時(shí)使用select函數(shù)就可以接收到內(nèi)核發(fā)出的消息,不用再通過while或者for函數(shù)不斷的輪詢,實(shí)際的功能已經(jīng)在ESMARC系列的ESM6800主板上通過測(cè)試和驗(yàn)證了。下面就針對(duì)兩個(gè)功能來介紹一下具體的使用方法。
用戶使用GPIO控制LED燈,可以直接調(diào)用英創(chuàng)公司提供的API函數(shù),將GPIO置為輸出然后置高或者置低。不過Linux系統(tǒng)將控制LED燈的這部分功能整合起來,設(shè)計(jì)成了一個(gè)標(biāo)準(zhǔn)的LED子系統(tǒng),對(duì)LED子系統(tǒng)的操作在shell環(huán)境中就能完成。英創(chuàng)公司也將這部分功能的支持加入到了板卡中,如果熟悉使用LED子系統(tǒng)來控制的用戶,就可以選用這種方式。通過加載一個(gè)內(nèi)核模塊led-emtronix.ko來啟用LED子系統(tǒng),加載的時(shí)候通過參數(shù)gpios來設(shè)置需要使用LED子系統(tǒng)操作的GPIO,gpios參數(shù)為一個(gè)32位的整數(shù),代表32位GPIO,1表示enable而0表示disable。所以當(dāng)我們選用GPIO0~GPIO3時(shí),加載內(nèi)核模塊的命令如下:insmode led-emtronix.ko gpios=0x0f,加載完成后,用戶可以在/sys/class/leds/目錄下看到新生成了四個(gè)對(duì)應(yīng)的文件夾LED1、LED2、LED3和LED4,注意,為了方便用戶區(qū)分,LED子文件夾的標(biāo)號(hào)和GPIO的標(biāo)號(hào)是一一對(duì)應(yīng)的,比如GPIO10生成的子文件夾為L(zhǎng)ED10。
加載內(nèi)核模塊
我們選擇LED0這個(gè)目錄進(jìn)入,可以看到里面有許多文件,我們要使用到的文件為brightness和trigger這兩個(gè)。
文件列表
brightness這個(gè)文件用來控制LED的開關(guān),對(duì)應(yīng)板卡的GPIO電平高低,當(dāng)brightness文件的值為0時(shí),GPIO輸出低電平,當(dāng)brightness文件的值為1時(shí)GPIO則輸出高電平,需要注意的是,加載內(nèi)核模塊后,默認(rèn)情況為輸出低電平即brightness文件的值為0。在shell中需要查看brightness的值可以使用命令cat brightness:
查看brightness文件
如果是需要設(shè)置brightness文件的值,則可以使用echo命令:
設(shè)置brightness文件的值
另一個(gè)文件trigger的作用是設(shè)置觸發(fā)方式,默認(rèn)為none即沒有觸發(fā)方式。使用cat命令讀取trigger文件可以得到支持的所有觸發(fā)方式,如下圖看到有磁盤,定時(shí)器,心跳,背光等多種觸發(fā)方式:
查看觸發(fā)方式
有方括號(hào)的表示為現(xiàn)在的有效觸發(fā)方式,如果要選用heartbeat作為觸發(fā)方式,還是使用echo命令來進(jìn)行設(shè)置:
設(shè)置trigger
設(shè)置之后可以通過示波器看到對(duì)應(yīng)的GPIO像心跳一樣,每秒會(huì)進(jìn)行一次拉高拉底。按照上面所介紹的方法,就能夠使用LED子系統(tǒng)來對(duì)板卡的GPIO進(jìn)行控制。
接下來介紹一下輸入事件通知的功能,英創(chuàng)板卡的GPIO上電是默認(rèn)都為輸入狀態(tài)(有3.3V上拉),在默認(rèn)狀態(tài)下是不會(huì)響應(yīng)輸入電平變化進(jìn)行事件通知的。要啟用這一功能,需要調(diào)用英創(chuàng)公司提供的,設(shè)置GPIO輸入狀態(tài)的API來實(shí)現(xiàn)。也就是在程序中需要調(diào)用一次API,設(shè)置GPIO為輸入,才會(huì)使能這一位GPIO的輸入事件通知功能,代碼如下:
int GPIO_OutDisable(int fd, unsigned int dwDisBits)
{
int rc;
struct double_pars dpars;
dpars.par1 = ESM6800_GPIO_OUTPUT_DISABLE;
dpars.par2 = dwDisBits;
rc = write(fd, &dpars, sizeof(struct double_pars));
return rc;
}
rc = GPIO_OutDisable(fd, i1); //set GPIO as input
if(rc < 0)
{
printf("GPIO_OutEnable::failed %d\n", rc);
return rc;
}
當(dāng)設(shè)置完成后,GPIO作為輸入狀態(tài),同時(shí)內(nèi)核會(huì)在輸入的電平變化時(shí)通知應(yīng)用層,使用select函數(shù)來監(jiān)聽GPIO的句柄的讀事件就能夠獲取到通知,用戶可以通過多線程的方式來實(shí)現(xiàn),代碼如下:
while( 1 )
{
//設(shè)置讀事件
FD_ZERO(&fdRead);
FD_SET(fd,&fdRead);
//設(shè)置超時(shí)時(shí)間
aTime.tv_sec = 0;
aTime.tv_usec = 20000;
ret = select(fd+1,&fdRead,NULL,NULL,&aTime);
//printf( "select ret = %d\n", ret);
if (ret < 0 )
{
printf("error!\n");
break;
}
if (ret > 0)
{
//判斷是否讀事件
if (FD_ISSET(fd,&fdRead))
{
//讀事件觸發(fā),進(jìn)行相應(yīng)的動(dòng)作
dwPinState = 0xffffffff;
rc = GPIO_PinState(fd, &dwPinState);
if(rc < 0)
{
printf("GPIO_PinState::failed %d\n", rc);
return rc;
}
printf("PinState = 0x%08x\n", dwPinState);
}
}
}
當(dāng)輸入電平發(fā)生變化,select偵測(cè)到讀事件,就可以進(jìn)行相應(yīng)的操作,示例代碼只是簡(jiǎn)單的讀取了當(dāng)前GPIO的輸入電平狀態(tài),用戶可以根據(jù)實(shí)際的應(yīng)用來修改。當(dāng)有多路GPIO用于偵測(cè)輸入電平變化的時(shí)候,在接收到讀事件后,如果需要判斷是哪一位GPIO偵測(cè)到電平變化,就要立刻讀取當(dāng)前GPIO的狀態(tài)來以此進(jìn)行判斷。對(duì)于不需要這一功能的用戶也不會(huì)有什么影響,當(dāng)調(diào)用函數(shù)將GPIO設(shè)置為輸入后,不使用select函數(shù)去監(jiān)聽GPIO的句柄即可,其他功能都和原來一致。
英創(chuàng)公司希望通過增加一些類似的實(shí)用功能,讓用戶的開發(fā)能夠更加方便,如果在使用過程中遇到任何問題,可以和英創(chuàng)公司的工程師聯(lián)系尋求技術(shù)支持。
-
Linux
+關(guān)注
關(guān)注
87文章
11511瀏覽量
213872 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6102瀏覽量
36313
發(fā)布評(píng)論請(qǐng)先 登錄
科普|信創(chuàng)是什么?一文讀懂“信息技術(shù)應(yīng)用創(chuàng)新”戰(zhàn)略

RK3568驅(qū)動(dòng)指南|第十二篇 GPIO子系統(tǒng)-第130章 GPIO的調(diào)試方法

迅為RK3568開發(fā)板驅(qū)動(dòng)指南GPIO子系統(tǒng)GPIO子系統(tǒng)API函數(shù)的引入

迅為RK3568驅(qū)動(dòng)指南GPIO子系統(tǒng) GPIO操作函數(shù)實(shí)驗(yàn)

RK3568驅(qū)動(dòng)指南|第十二篇 GPIO子系統(tǒng)-第135章 GPIO子系統(tǒng)與pinctrl子系統(tǒng)相結(jié)合實(shí)驗(yàn)

飛凌嵌入式ElfBoard ELF 1板卡-input子系統(tǒng)之input子系統(tǒng)簡(jiǎn)介
嵌入式學(xué)習(xí)-飛凌嵌入式ElfBoard ELF 1板卡-Pinctrl和GPIO子系統(tǒng)之ioctl介紹
飛凌嵌入式ElfBoard ELF 1板卡-Pinctrl和GPIO子系統(tǒng)之LED驅(qū)動(dòng)
嵌入式學(xué)習(xí)-飛凌嵌入式ElfBoard ELF 1板卡-Pinctrl和GPIO子系統(tǒng)之GPIO子系統(tǒng)
飛凌嵌入式ElfBoard ELF 1板卡-Pinctrl和GPIO子系統(tǒng)之ioctl介紹
飛凌嵌入式ElfBoard ELF 1板卡-Pinctrl和GPIO子系統(tǒng)之GPIO子系統(tǒng)
飛凌嵌入式ElfBoard ELF 1板卡-Pinctrl和GPIO子系統(tǒng)之Pinctrl子系統(tǒng)
GPIO在嵌入式系統(tǒng)中的作用
中科創(chuàng)達(dá)榮獲2024年軟件和信息技術(shù)服務(wù)優(yōu)秀企業(yè)
linux--LED子系統(tǒng)一文讀懂

評(píng)論