樹莓派學習筆記——使用檔案IO操作GPIO SysFs方式

來源:互聯網
上載者:User

標籤:樹莓派   sysfs   gpio   

0 前言    本文描述如果通過檔案IO sysfs方式控制樹莓派 GPIO連接埠。通過sysfs方式控制GPIO,先訪問/sys/class/gpio目錄,向export檔案寫入GPIO編號,使得該GPIO的操作介面從核心空間暴露到使用者空間,GPIO的操作介面包括direction和value等,direction控制GPIO方向,而value可控制GPIO輸出或獲得GPIO輸入。    Linux學習可從應用出發,先不糾結Linux驅動編寫,先把Linux給玩起來。
    【相同與不同】    本文和【EasyARM i.mx28學習筆記——檔案IO方式操作GPIO】內容相似,大部分代碼相同。通過檔案IO操作可以有效地避免平台差異,雖然EasyARM im287平台和樹莓派完全不同,但是通過sysfs操作GPIO實現代碼大致相同。    和EasyARM im287不同,此處並沒有使用交叉編譯工具,有樹莓派中的gcc工具鏈編譯連結獲得可執行檔,而EasyARM im287並不能這樣操作。EasyARM im287採用busybox指令集,這也與樹莓派中的debian指令集存在差異。
    【相關博文】    【EasyARM i.mx28學習筆記——檔案IO方式操作GPIO】    【樹莓派學習筆記——Shell指令碼操作GPIO】    【樹莓派學習筆記——交叉編譯工具鏈】    【 Linux學習筆記——例說makefile 索引博文】
    【代碼倉庫】    代碼倉庫位於bitbucket——rpi-gpio-sysfs ,請使用Hg複製或者直接下載zip包。請不要使用任何版本的IE瀏覽器訪問連結,除非你已經知道所使用的IE瀏覽器符合HTML5標準。推薦使用Google或者Firefox瀏覽器訪問,若使用國產雙核瀏覽器請切換到極速模式。    【原理圖示意】
圖1 連線1 暴露GPIO操作介面
static int gpio_export(int pin){    char buffer[BUFFER_MAX];    int len;    int fd;    fd = open("/sys/class/gpio/export", O_WRONLY);    if (fd < 0) {        fprintf(stderr, "Failed to open export for writing!\n");        return(-1);    }    len = snprintf(buffer, BUFFER_MAX, "%d", pin);    if (write(fd, buffer, len) < 0) {        fprintf(stderr, "Fail to export gpio!");        return -1;    }       close(fd);    return 0;}

2 隱藏GPIO操作介面
static int gpio_unexport(int pin){    char buffer[BUFFER_MAX];    int len;    int fd;    fd = open("/sys/class/gpio/unexport", O_WRONLY);    if (fd < 0) {        fprintf(stderr, "Failed to open unexport for writing!\n");        return -1;    }    len = snprintf(buffer, BUFFER_MAX, "%d", pin);    if (write(fd, buffer, len) < 0) {        fprintf(stderr, "Fail to unexport gpio!");        return -1;    }       close(fd);    return 0;}

3 配置GPIO方向
static int gpio_direction(int pin, int dir){    static const char dir_str[] = "in\0out";    char path[DIRECTION_MAX];    int fd;    snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);    fd = open(path, O_WRONLY);    if (fd < 0) {        fprintf(stderr, "failed to open gpio direction for writing!\n");        return -1;    }    if (write(fd, &dir_str[dir == IN ? 0 : 3], dir == IN ? 2 : 3) < 0) {        fprintf(stderr, "failed to set direction!\n");        return -1;    }    close(fd);    return 0;}
    【簡單說明】    【1】dir_str[dir == IN ? 0 : 3], dir == IN ? 2 : 3 如果輸入為常數宏IN, 取dir_str[0]=“in”;若輸入常數宏為OUT,取dir_str[0]=“out”。此處巧妙的使用了在數組中的“\0”。
4 控制GPIO輸出
static int gpio_write(int pin, int value){    static const char values_str[] = "01";    char path[DIRECTION_MAX];    int fd;    snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", pin);    fd = open(path, O_WRONLY);    if (fd < 0) {        fprintf(stderr, "failed to open gpio value for writing!\n");        return -1;    }    if (write(fd, &values_str[value == LOW ? 0 : 1], 1) < 0) {        fprintf(stderr, "failed to write value!\n");        return -1;    }    close(fd);    return 0;}

5 獲得GPIO輸入
static int gpio_read(int pin){    char path[DIRECTION_MAX];    char value_str[3];    int fd;    snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", pin);    fd = open(path, O_RDONLY);    if (fd < 0) {        fprintf(stderr, "failed to open gpio value for reading!\n");        return -1;    }    if (read(fd, value_str, 3) < 0) {        fprintf(stderr, "failed to read value!\n");        return -1;    }    close(fd);    return (atoi(value_str));}

6 GPIO翻轉操作    【main函數】
int main(int argc, char *argv[]){    int i = 0;        GPIOExport(POUT);    GPIODirection(POUT, OUT);        for (i = 0; i < 20; i++) {        GPIOWrite(POUT, i % 2);        usleep(500 * 1000);    }    GPIOUnexport(POUT);    return(0);}
    【makefile】——此處的代碼tab顯示可能存在問題,請以代碼倉庫為主。
# 可執行檔TARGET=test# 依賴目標SRCS=gpio-sysfs.c# 目標檔案OBJS = $(SRCS:.c=.o)# 指令編譯器和選項CC=gccCFLAGS=-Wall -std=gnu99$(TARGET):$(OBJS) $(CC) -o [email protected] $^clean: rm -rf $(TARGET) $(OBJS)# 連續動作,先清除再編譯連結,最後執行exec:clean $(TARGET) @echo 開始執行 sudo ./$(TARGET) @echo 執行結束# 編譯規則 [email protected]代表目標檔案 $< 代表第一個依賴檔案%.o:%.c $(CC) $(CFLAGS) -o [email protected] -c $<

    【上傳樹莓派中 編譯連結並執行】    make exec    makefile中exec目標包括以下一個過程,先清除目標檔案和可執行檔,然後進行交叉編譯,最後使用超級許可權運行可執行檔。    makefile的使用詳見【 Linux學習筆記——例說makefile 索引博文】
7 總結【1】樹莓派和其他嵌入式Linux開發板存在差別和聯絡,樹莓派同樣可以使用sysfs控制GPIO。【2】樹莓派即在其他助劑中交叉編譯,也可在平台直接編譯。
8 參考資料【1】RPi Low-level peripherals

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.