Kernel中GPIO的Sysfs介面的使用
阿新 • • 發佈:2019-02-15
今天想寫一個gpio的驅動,用於控制SoC上的一個電源控制io。看了一會兒,覺得對於gpio這種標準裝置,kernel中應該有通用的驅動,甚至應該有Sysfs的介面可供使用者空間程式使用。
於是先看了下driver目錄,發現果然有gpio這個目錄,不過裡面的東西太多,一時沒有頭緒。又想起Documents目錄,找到一個gpio.txt,果然Kernel提供了一個gpiolib的模組,用於向用戶空間提供控制介面,使用上在這裡簡單做個說明:
1. 開啟gpiolib支援,在menuconfig中,
Device Drivers->GPIO Support,選擇:
[*] /sys/class/gpio/… (sysfs interface)
<*> Generic memory-mapped GPIO controller support (MMIO platform device)
2. 載入新的kernel之後,在/sys/class/下,多出gpio這個目錄,其中有export與unexport倆個檔案,輸入echo N > /sys/class/gpio/export,則該目錄下會再出現以gpioN為名字的目錄,這就是我們要控制的gpio的對映,可以控制其方向、高低及觸發方式。N是由n*32 + m得來,n是第n個gpio模組,m是暫存器第m位。
3. 不過,對於已經被系統分配的GPIO,echo操作會失敗,這是一種保護機制,為了測試,可以修改下程式碼來遮蔽(3.10.35核心):
1393 static int gpiod_request(struct gpio_desc *desc, const char *label)
1394 {
1395 struct gpio_chip *chip;
1396 int status = -EPROBE_DEFER;
1397 unsigned long flags;
...
1410 if (!try_module_get(chip->owner))
1411 goto done;
1412
1413 /* NOTE: gpio_request() can be called in early boot,
1414 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
1415 */
1416
1417 desc->flags = 0;//重置flags值,僅供測試
1418 if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
1419 desc_set_label(desc, label ? : "?");
1420 status = 0;
1421 } else {
1422 status = -EBUSY;
1423 module_put(chip->owner);
1424 goto done;
1425 }
...
1452 }
至此,我們就可以在user space中,操作gpio了。