Zynq-7000系列平臺linux下操作MIO/EMIO GPIO方法

開發板:Zynq7030數據採集板
開發環境:Xilinx Vivado + SDK -18.3
交叉編譯工具:arm-linux-gnueabihf-
目的:通過Linux下GPIO驅動控制開發板上的LED燈

linux下操作Zynq7030平臺GPIO方法和操作其他平臺GPIO方法大同小異,只是要注意Zynq平臺GPIO號的計算方法與其他平臺略有不同。比如:NXP的imx6q平臺的GPIO號計算方法爲:

                                          GPIOP_N;                                                                                                                                                                                              nr=(P -1)* 32 + N;

而Zynq平臺GPIO號計算方法需要查看/sys/class/gpio路徑下的gpiochips編號,它反映了GPIO在系統中的地址,是所有GPIO編號的初始編號,所有的GPIO編號都要在此基礎上計算。

(1)Linux下Sysfs方式直接操作GPIO

現在我要在linux用戶空間直接用命令行的方式點亮如下電路圖的小燈:

首先查明/sys/class/gpio下的gpiochips編號:

上面的結果表明第一個GPIO口編號爲906,我使用的GPIO口爲EMIO11,總共有54個MIO口,所有我的GPIO口編號爲

                                         906+54-1+11=970

然後通過如下方法操作GPIO:

可以看到,輸出0到gpio970/value時,LED燈亮,輸出1時,燈滅。

現對上面的一些操作下說明:
/sys/class/gpio/路徑下相關文件說明:

File Description
export 將GPIO節點導入到用戶空間
unexport 將GPIO節點移除用戶空間
gpiochip* 該目錄下保存系統中GPIO寄存器信息:每個寄存器控制引腳的起始編號base,寄存器名稱,引腳總數

/sys/class/gpio/gpio960/路徑下相關文件說明:

File Description
direction 配置GPIO口輸方面,"in"爲輸入;"out"爲輸出
value GPIO爲輸出時可設置GPIO口電平,"0"爲低電平;"1"爲高電平
edge 設置GPIO口輸入時觸發方式:“none”, “rising”, “falling”, or “both”
active_low 按照官方的說法是翻轉電平,輸入非零的數即上升沿變爲下降沿

(2)用戶空間APP方式操作GPIO

除了上面操作GPIO的方法,還可以在應用程序中使用APP的方式來操作GPIO,具體程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main()
{
    int valuefd, exportfd, directionfd;

    exportfd = open("/sys/class/gpio/export", O_WRONLY);
    if (exportfd < 0)
    {
        printf("Cannot open GPIO to export.\n");
        exit(1);
    }
    write(exportfd, "970", 4);
    close(exportfd);

    directionfd = open("/sys/class/gpio/gpio970/direction", O_RDWR);
    if (directionfd < 0)
    {
        printf("Cannot open GPIO direction.\n");
        exit(1);
    }
    write(directionfd, "out", 4);
    close(directionfd);

    valuefd = open("/sys/class/gpio/gpio970/value", O_RDWR);
    if (valuefd < 0)
    {
        printf("Cannot open GPIO value.\n");
        exit(1);
    }

    while (1)
    {
        write(valuefd,"1", 2);
        sleep(1);
        write(valuefd,"0", 2);
        sleep(1);       
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章