1. 程式人生 > >Kernel中GPIO的Sysfs介面的使用

Kernel中GPIO的Sysfs介面的使用

今天想寫一個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了。