Linux如何進行GPIO讀寫操作的?
摘要:本文介紹GPIO的讀寫,介紹基本原理,以及不同讀寫方式的效能。
本文分享自華為雲社群《Linux 基於sysfs的GPIO讀寫操作》,作者:一顆小樹x 。
前言
最近接觸到Linux系統中的GPIO開發,這裡做個小總結,也分享一下;本文會介紹GPIO的讀寫,介紹基本原理,以及不同讀寫方式的效能。
一、GPIO sysfs interface 基本原理
在Linux中,最常見的讀寫GPIO方式就是用GPIO sysfs interface,是通過操作/sys/class/gpio目錄下的export、unexport、gpio{N}/direction, gpio{N}/value(用實際引腳號替代{N})等檔案實現的,經常出現shell腳本里面。
首先宣告GPIO口,比如GPIO258:(這個命令需要root許可權)
echo 258 > /sys/class/gpio/export
然後在/sys/class/gpio,會生成一個新目錄,其名字叫gpio258
比如:GPIO258,N對應是258;進入其目錄:cd /sys/class/gpio/gpio258
依次能看到:active_low 、device、 direction 、edge 、power 、subsystem 、uevent 、value
其中比較常用的是value檔案,它存放GPIO的值;範圍是:0或1。我們可以直接對它讀寫,達到讀寫GPIO的效果。
二、定義GPIO為輸入
比如定義GPIO258為輸入,命令如下:(這個命令需要root許可權)
echo in > /sys/class/gpio/gpio258/direction
三、定義GPIO為輸出
比如定義GPIO258為輸出,命令如下:(這個命令需要root許可權)
echo out > /sys/class/gpio/gpio258/direction
四、讀GPIO的值
我們可以直接對/sys/class/gpio/gpio258 目錄下的value檔案(存放GPIO的值),進行讀取。
可以用cat 檢視讀GPIO的值,比如檢視GPIO258的值:
cat /sys/class/gpio/gpio258/value
value 只是一個檔案,可以通過其他方式讀取;寫一個python程式,實現讀取GPIO的值:
# 定義一個函式,用於讀取GPIO258的值。 def read_258(): with open('/sys/class/gpio/gpio258/value', 'r') as f: io_258 = int(f.read()) print("read_258:%d"%io_258) # 呼叫函式 read_258()
五、寫GPIO的值
我們可以直接對/sys/class/gpio/gpio258 目錄下的value檔案(存放GPIO的值),進行寫值。
可以用ehco 寫GPIO的值,比如寫GPIO258的值:
echo 1 > /sys/class/gpio/gpio258/value # output logic 1 level echo 0 > /sys/class/gpio/gpio258/value # output logic 0 level
寫一個python程式,實現寫GPIO的值:
# 定義一個函式,用於寫GPIO258的值。 def write_258(io_str): with open('/sys/class/gpio/gpio258/value', 'w+') as f: f.write(io_str) print("write_258:%s"%(io_str)) # 呼叫函式 write_258()
經過測試,程式進行一次寫操作,耗時0.6ms左右;ehco方式就比較久了,10ms左右。
六、小案例——設定GPIO為輸入,並讀取IO值
方式一: 純shell命令
# 設定GPIO20為輸入 echo 20 > /sys/class/gpio/export echo in > /sys/class/gpio/gpio20/direction # 讀取IO值 cat /sys/class/gpio/gpio20/value
方式二:shell命令 + Python程式(效率更高)
# 設定GPIO20為輸入 echo 20 > /sys/class/gpio/export echo in > /sys/class/gpio/gpio20/direction
讀取IO值:
# 定義一個函式,用於讀取GPIO258的值。 def read_20(): with open('/sys/class/gpio/gpio20/value', 'r') as f: io_20 = int(f.read()) print("read_20:%d"%io_20) # 呼叫函式 read_20()
七、小案例——設定GPIO為輸出,並讀寫取IO值
方式一: 純shell命令
# 設定GPIO40為輸出 echo 40 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio40/direction # 寫IO值,高電平 echo 1 > /sys/class/gpio/gpio40/value # 寫IO值,低電平 echo 0 > /sys/class/gpio/gpio40/value
方式二:shell命令 + Python程式(效率更高)
# 設定GPIO40為輸出 echo 40 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio40/direction
讀寫IO值:
import time def read_40(): with open('/sys/class/gpio/gpio40/value', 'r') as f: io_40 = int(f.read()) print("read_40:%d"%io_40) def write_40(io_str): with open('/sys/class/gpio/gpio40/value', 'w') as f: f.write(io_str) print("write_40:%s"%(io_str)) start = time.time() read_40() write_40("1") read_40() end = time.time() print("讀寫IO的時間", end-start)
效果:耗時0.6ms。