1.透過修改/sys/class/gpio/gpioxx/Value來變更,此種方法好處是可以在多種程式語言,
單純透過讀寫檔案的方式就可以改變GPIO,亦不需要知道實際GPIO所對應的記憶體位置。
缺點則是速度較慢。
Ex:切換系統LED
echo "27" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio27/direction
echo "1" > /sys/class/gpio/gpio27/valueor
echo "0" > /sys/class/gpio/gpio27/value2. Direct Access GPIO Register,這種方式需要知道GPIO所對應的暫存器位置 ,適合以C語言開發,並對切換GPIO腳位速度有需求的使用者,例如RS 485應用。
以AR9331為例,參考它的DataSheet ,可以得知GPIO的位置為18040000。
讓GPIO 27 閃爍的範例程碼
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <string.h> #include <time.h> #define GPIO_ADDR 0x18040000 // base address #define GPIO_BLOCK 48 // memory block size volatile unsigned long *gpioAddress; //Read GPIO Status //return 0 -->Low //return >0 -->High int gpioRead(int gpio) { unsigned long value = *(gpioAddress + 1); return (value & (1 << gpio)); } // "1" (output) or "0" (input) void gpioDirection(int gpio, int direction) { // obtain current GPIO settings unsigned long value = *(gpioAddress + 0); if (direction == 1) { value |= (1 << gpio); // set bit to 1 (output) } else { value &= ~(1 << gpio); // clear bit (input) } *(gpioAddress + 0) = value; } //Set GPIO void gpioSet(int gpio, int data) { // obtain current GPIO settings unsigned long value = *(gpioAddress + 2); if (data == 1) { value |= (1 << gpio); // set bit to 1 (High) } else { value &= ~(1 << gpio); // clear bit (Low) } *(gpioAddress + 2) = value; } //Init GPIO Address, if /dev/mem not foud, you need to rebuild Image and add this module int gpioSetup() { int m_mfd; if ((m_mfd = open("/dev/mem", O_RDWR)) < 0) { return -1; } gpioAddress = (unsigned long*)mmap(NULL, GPIO_BLOCK, PROT_READ|PROT_WRITE, MAP_SHARED, m_mfd, GPIO_ADDR); close(m_mfd); if (gpioAddress == MAP_FAILED) { return -2; } return 0; } int main(int argc, char **argv) { int pin=27; int ms=500; gpioSetup(); sscanf(argv[1], "%d", &pin); gpioDirection(pin,1);//set pin output for (int i=0;i<100;i++) //blink system led { gpioSet(pin,1); //set syteme led high usleep(1000*ms); //sleep 500ms gpioSet(pin,0); //set system led low usleep(1000*ms); //sleep 500ms } }
參考來源:
Working with GPIOs (C/C++)
AR9331 Datasheet