czwartek, 5 września 2019

Som Labs - IMx6 ULL - Debian - Obsługa portu GPIO na przykładzie diody oraz przycisku

W tym poście chciałbym opisać obsługę portów GPIO na przykładzie diody oraz przycisku zamontowanych na płycie

Znalezione obrazy dla zapytania som labs 6ull
[Źródło: https://somlabs.com/product/visionsom-6ull/]

Obsługa portów GPIO możliwa jest dzięki sterownikom jądra systemu Linux. Do dyspozycji są piny zdefiniowane jako Led Class Driver jako wyjście, oraz piny wejściowe GPIO Buttons. 

Zamiast sterownika dedykowanego dla wejścia lub wyjścia można wykorzystać ogólny sterownik pinów GPIO.

Diody led zostały podłączone pod wyprowadzenia GPIO10 (Dioda niebieska), GPIO11 (Dioda zielona), GPIO12 (Dioda żółta), GPIO13 (Dioda czerwona). Przyciski natomiast to piny GPIO3, GPIO4, GPIO8, GPIO9.

Zmiany w Device Tree [1]:


W celu uzyskania dostępu do diod należy wprowadzić zmiany w Device Tree. W tym celu najlepiej
posłużyć się systemem obsługiwanym z Linuxa.

Na samym początku należy pobrać obrazVisionSom-6ULL:

  1. sudo apt install qemu-user-static
  2. wget http://ftp.somlabs.com/somlabs-visionsom-6ull-debian-rootfs-qemu.tar.xz
  3. sudo tar -xvf somlabs-visionsom-6ull-debian-rootfs-qemu.tar.xz
  4. sudo cp /etc/hostname ~/somlabs-debian/etc/hostname
  5. sudo cp /etc/hosts ~/somlabs-debian/etc/hosts
  6. sudo ./somlabs-debian/chtoolchain

Kolejnym elementem jest zbudowanie jądra systemu oraz wykonanie komendy make. W tym celu należy przejść do odpowiedniego folderu:

  1. cd /home/developer/source/kernel/linux-rel_imx_4.1.15_2.1.0_ga

Po czym wykonać operację kopiowania domyślnej konfiguracji do folderu z jądrem systemu:

  1. cp /home/developer/source/somlabs-dts-1.0/visionsom-6ull-linux_defconfig /home/developer/source/kernel/linux-rel_imx_4.1.15_2.1.0_ga/.config

Teraz można już uruchomić polecenie make z folderu do którego została skopiowana konfiguracja (/home/developer/source/kernel/linux-rel_imx_4.1.15_2.1.0_ga):

  1. make deb-pkg -j8 CFLAGS_MODULE = -fno-pic

Po poprawnym wykonaniu powyższej czynności można przejść do modyfikacji Device Tree:

  1. nano /home/developer/source/somlabs-dts-1.0/somlabs-visionsom-6ull.dts

Poniżej opiszę tylko udostępnienie dla użytkownika  pinów odpowiedzialnych za diody. Ponieważ domyślnie są one niedostępne. Inne sterowniki obsługą je do wyświetlania informacji np. o działającej transmisji danych.

Przyciski są automatycznie udostępnione wiec ich nie trzeba modyfikować.

W pliku należy znaleźć następujące informacje:

  1. leds{
  2.     compatible = "gpio-leds";
  3.     usr0 {
  4.         label = "usr0";
  5.         gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
  6.         linux,default-trigger = "heartbeat";
  7.     };
  8.     usr1 {
  9.         label = "usr1";
  10.         gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
  11.         linux,default-trigger = "mmc0";
  12.     };
  13.     usr2 {
  14.         label = "usr2";
  15.         gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
  16.         linux,default-trigger = "mmc1";
  17.     };
  18.     usr3 {
  19.         label = "usr3";
  20.         gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
  21.     };
  22. };

Aby udostępnić sterowanie pinami dla użytkownika to należy zakomentować odpowiednie części (usr0...usr3) znajdujące się wewnątrz nawiasów klamrowych dla definicji leds. Domyślnie są one przypisane do podsystemu, sterownika gpio-leds i sterowanie jest przeprowadzane przez domyślny trigger.

W celu sprawdzenia pozostałych definicji odpowiednich pinów oraz funkcji jakie są udostępnione poszczególnym pinom można sprawdzić w poniższym pliku:

  1. /home/developer/source/kernel/linux-rel_imx_4.1.15_2.1.0_ga/arch/arm/boot/dts/imx6ul-pinfunc.h

Następnym elementem jest stworzenie pakietu Debiana:

  1. cd /home/developer/source/somlabs-dts-1.0/
  2. /home/developer/source/somlabs-dts-1.0# dpkg-buildpackage -us -uc

Teraz należy przesłać plik na urządzenie:

  1. scp /home/developer/source/somlabs-dts_1.0.0_armhf.deb root@<IP_ADDR_SOMLABS>:/root/

W celu sprawdzeniu adresu IP urządzenia można skorzystać z jednej z dwóch komend:

  1. hostname -I
  2. //lub
  3. ip a

Po przesłaniu pliku na płytkę należy zainstalować pakiet następującym poleceniem (tą komendę należy wywołać na płycie somlabs a nie na ubuntu jak wcześniejsze):

  1. dpkg -i /root/somlabs-dts_1.0.0_armhf.deb

Gdy już operacja zostanie zakończona to w celu załadowania ustawień należy ponownie uruchomić system (np. polecenie reboot). Po ponownym uruchomieniu systemu można przejść do konfiguracji.

Sterowanie pinami polecenia konsoli:


Poniżej chciałbym opisać sposobu konfiguracji i obsługi pinów przez polecenia skryptowe. Na samym początku obsługa diod czyli gpio jako wyjście.

Dostęp do danych udostępnianych przez sterownik GPIO należy szukać w folderze:

  1. cd /sys/class/gpio/

W opisanym folderze znajdują się dwa ważne pliki tzn. export oraz unexport. Dzięki nim można zająć lub zwolnić podane wyprowadzenie dla przestrzeni użytkownika. Oczywiście dane wyprowadzenie nie może być już wykorzystywane przez inny sterownik. Dlatego należało wykonać zmiany wyprowadzeń w Device Tree.

Aby wyeksportować dane wyprowadzenie należy wywołać polecenie:

  1. echo 12 > /sys/class/gpio/export
  2. //lub jesli wskaźnik jest juz w folderze gpio to
  3. echo 12 > export

Po tej operacji zostaje stworzony folder z opisem danego wyprowadzenia (dla gpio 12 będzie to folder gpio12 itp. itd.).


Teraz można przejść do utworzonego folderu wykorzystując następującą komendę:

  1. cd /sys/class/gpio/gpio12

Po tej operacji można wyświetlić informację z dostępnymi parametrami:


Najważniejsze z udostępnionych przez system plików to direction, value oraz edge. Poniżej krótki opis każdego z nich:

plik direction - odpowiada za kierunek działania danego wyprowadzenia (in/out)

plik value - odpowiada za ustawienie odpowiedniego stanu na pinie wyjściowym. W przypadku ustawienia jako wejścia ten plik będzie przechowywał aktualny stan na linii.

plik edge - pozwala na określenie jakie zbocze będzie wyzwalało zmianę stanu na linii. Dopuszczalne parametry do wpisania to none, rising, falling lub both.

Wobec tego w celu wybrania kierunku należy wprowadzić w konsoli następującą komendę:

  1. //Jako wejście (np. przyciski)
  2. echo in > /sys/class/gpio/gpio12/direction
  3. //Jako wyjście (np. diody)
  4. echo out > /sys/class/gpio/gpio12/direction

Po ustawieniu kierunku należy wprowadzić odpowiedni stan:

  1. //Ustawienie stanu wysokiego
  2. echo 1 > /sys/class/gpio/gpio12/direction
  3. //Ustawienie stanu niskiego
  4. echo 0 > /sys/class/gpio/gpio12/direction

Gdy ustawiony jest pin jako wyjściowy to stan linii można odczytać następującą komendą:

  1. cat /sys/class/gpio/gpio12/value

W celu wywołania poniższych skryptów wystarczy wpisać:

  1. /root/blink.sh

Prosty skrypt pozwalający na obsługę dostępnych diod może wyglądać następująco:

  1. #!/bin/sh
  2. SLEEP="/bin/sleep"
  3. GpioData=/sys/class/gpio/gpio12
  4. while true ; do
  5.         echo 1 > $GpioData/value
  6.         $SLEEP 1
  7.         echo 0 > $GpioData/value
  8.         $SLEEP 1
  9. done

W celu obsługi większej liczby wyprowadzeń wystarczy rozbudować nieco skrypt dodając pozostałe wartości:

  1. #!/bin/sh
  2. LED1=10
  3. LED2=11
  4. LED3=12
  5. LED4=13
  6. SLEEP="/bin/sleep"
  7. GPIOVALUE_1=/sys/class/gpio/gpio$LED1
  8. GPIOVALUE_2=/sys/class/gpio/gpio$LED2
  9. GPIOVALUE_3=/sys/class/gpio/gpio$LED3
  10. GPIOVALUE_4=/sys/class/gpio/gpio$LED4
  11. echo 0 > $GPIOVALUE_1/value
  12. echo 0 > $GPIOVALUE_2/value
  13. echo 0 > $GPIOVALUE_3/value
  14. echo 0 > $GPIOVALUE_4/value
  15. while true ; do
  16.         echo 1 > $GPIOVALUE_1/value
  17.         $SLEEP 1
  18.         echo 1 > $GPIOVALUE_2/value
  19.         $SLEEP 1
  20.         echo 1 > $GPIOVALUE_3/value
  21.         $SLEEP 1
  22.         echo 1 > $GPIOVALUE_4/value
  23.         $SLEEP 1
  24.         echo 0 > $GPIOVALUE_4/value
  25.         $SLEEP 1
  26.         echo 0 > $GPIOVALUE_3/value
  27.         $SLEEP 1
  28.         echo 0 > $GPIOVALUE_2/value
  29.         $SLEEP 1
  30.         echo 0 > $GPIOVALUE_1/value
  31.         $SLEEP 1
  32. done

Przed użyciem powyższych dwóch skryptów należy uruchomić wyprowadzenia poleceniem export, oraz ustawić kierunek jako wyjściowy.

Tutaj należy pamiętać, że po ponownym uruchomieniu komputera zmiany zapisane w plikach /sys/class/gpio/ ulegną usunięciu. Wobec tego lepiej stosować skrypt ustawiający dane wyprowadzenia w odpowiednim stanie.

Nieco rozbudowana wersja uruchamiająca dane wyprowadzenie oraz ustawiająca kierunek działania:

  1. #!/bin/sh
  2. SLEEP="/bin/sleep"
  3. GPIO_EXPORT=/sys/class/gpio/export
  4. LED1=10
  5. LED2=11
  6. LED3=12
  7. LED4=13
  8. GPIOVALUE_1=/sys/class/gpio/gpio$LED1
  9. GPIOVALUE_2=/sys/class/gpio/gpio$LED2
  10. GPIOVALUE_3=/sys/class/gpio/gpio$LED3
  11. GPIOVALUE_4=/sys/class/gpio/gpio$LED4
  12. if [ ! -d "$GPIOVALUE_1" ]then
  13.         echo "Export GPIO$LED1"
  14.         echo $LED1 > $GPIO_EXPORT
  15. else
  16.         echo "GPIO$LED1 exported"
  17. fi
  18. if [ ! -d "$GPIOVALUE_2" ]then
  19.         echo "Export GPIO$LED2"
  20.         echo $LED2 > $GPIO_EXPORT
  21. else
  22.         echo "GPIO$LED2 exported"
  23. fi
  24. if [ ! -d "$GPIOVALUE_3" ]then
  25.         echo "Export GPIO$LED3"
  26.         echo $LED3 > $GPIO_EXPORT
  27. else
  28.         echo "GPIO$LED3 exported"
  29. fi
  30. if [ ! -d "$GPIOVALUE_4" ]then
  31.         echo "Export GPIO$LED4"
  32.         echo $LED4 > $GPIO_EXPORT
  33. else
  34.         echo "GPIO$LED4 exported"
  35. fi
  36. echo "Set pin as output"
  37. echo out > $GPIOVALUE_1/direction
  38. echo out > $GPIOVALUE_2/direction
  39. echo out > $GPIOVALUE_3/direction
  40. echo out > $GPIOVALUE_4/direction
  41. echo "Set pin state to low"
  42. echo 0 > $GPIOVALUE_1/value
  43. echo 0 > $GPIOVALUE_2/value
  44. echo 0 > $GPIOVALUE_3/value
  45. echo 0 > $GPIOVALUE_4/value
  46. echo "Enter into while loop"
  47. while true ; do
  48.         echo 1 > $GPIOVALUE_1/value
  49.         $SLEEP 1
  50.         echo 1 > $GPIOVALUE_2/value
  51.         $SLEEP 1
  52.         echo 1 > $GPIOVALUE_3/value
  53.         $SLEEP 1
  54.         echo 1 > $GPIOVALUE_4/value
  55.         $SLEEP 1
  56.         echo 0 > $GPIOVALUE_4/value
  57.         $SLEEP 1
  58.         echo 0 > $GPIOVALUE_3/value
  59.         $SLEEP 1
  60.         echo 0 > $GPIOVALUE_2/value
  61.         $SLEEP 1
  62.         echo 0 > $GPIOVALUE_1/value
  63.         $SLEEP 1
  64. done

Na samym początku skrypt sprawdza czy dane wyprowadzenie zostało już wyeksportowane, jeśli to to następuje wyeksportowanie danego wyprowadzenia. Po przejściu przez cztery piny dla diod ustawiany jest kierunek działania jako wyjście. Następnie piny ustawione zostają w stan niski i następuje wejście do pętli while wykonującej zapalanie oraz gaszenie diod.


Takie rozwiązanie pozwoli na uruchomienie skryptów zaraz po starcie systemu, dzięki temu nie będzie konieczności wprowadzania ręcznie informacji do sterownika gpio.

W celu obsługi przycisku należy wykonać następujące operacje:

  1. echo 4 > /sys/class/gpio/export
  2. echo in > /sys/class/gpio/gpio4/direction

Po takiej operacji ustawianą wartość przez przycisk można sprawdzić za pomocą polecenia cat. I tak przy nie wciśniętym przycisku wartość jest 1. Po jego kliknięciu wartość zmienia się na 0:


Teraz do skryptu dołożę obsługę przycisku tak aby po kliknięciu został przesłany tekst na wyświetlacz:

  1. #!/bin/sh
  2. SLEEP="/bin/sleep"
  3. GPIO_EXPORT=/sys/class/gpio/export
  4. BUTTONPIN=4
  5. INPUTVALUE=/sys/class/gpio/gpio$BUTTONPIN
  6. if [ ! -d "$INPUTVALUE" ]then
  7.         echo "Export Button on GPIO$BUTTONPIN"
  8.         echo $BUTTONPIN > $GPIO_EXPORT
  9. else
  10.         echo "Button on GPIO$BUTTONPIN exported"
  11. fi
  12. echo "Button config"
  13. echo in > $INPUTVALUE/direction
  14. echo "Enter into while loop"
  15. while true ; do
  16.         var="$(cat $INPUTVALUE/value)"
  17.         if [ $var -eq 0 ]then
  18.                 echo "Button Clicked"
  19.         fi
  20. done

Sterowanie pinami w c:


Poniżej przejdę do przedstawienia prostego programu pozwalającego na obsługę wyprowadzeń GPIO jako in/out.

Tutaj operacje wyglądają podobnie co przy plikach skryptowych. To znaczy dalej trzeba wyeksportować dane wyprowadzenie dla użytkownika, następnie trzeba ustawić kierunek i dopiero wtedy można przejść do zmiany wartości na pinie.

Poniżej przykład pozwalający na sterowanie diodami:

Funkcja odpowiedzialna za włączenie danego wyprowadzenia do przestrzeni użytkownika:

  1. static int gpioExportPin(unsigned int gpioPinNumber)
  2. {
  3.         int fileDesc = -1;
  4.         int writeBufferSize = -1;
  5.         char buf[50] = {0x00};
  6.         //Open file
  7.         fileDesc = open(GPIO_MAIN_DIR "/export", O_WRONLY);
  8.         //Check if operation error
  9.         if(fileDesc < 0)
  10.         {
  11.                 perror("File gpio - export Error");
  12.                 return fileDesc; //-1
  13.         }
  14.         //Prepare buffer
  15.         writeBufferSize = snprintf(buf, sizeof(buf), "%d", gpioPinNumber);
  16.         write(fileDesc, buf, writeBufferSize);
  17.         close(fileDesc);
  18.         return 0;
  19. }

Operacje jak już wspomniałem wcześniej dotyczą operacji na plikach. Tym razem tylko nie są one wykonywane przez bash a przez instrukcję w języku C. Na samym początku zostaje otwarty plik export do którego zostaje wprowadzony numer pinu jaki ma być dostępny dla użytkownika.

Kolejna niezbędna funkcja pozwala na ustawienie kierunku działania danego wyprowadzenia:

  1. static int gpioSelectDirection(unsigned int gpioPinNumber,  unsigned int gpioDi$
  2. {
  3.         int fileDesc = -1;
  4.         char buf[100] = {0x00};
  5.         snprintf(buf, sizeof(buf), GPIO_PIN_DIR "%d/direction", gpioPinNumber);
  6.         fileDesc = open(buf, O_WRONLY);
  7.         //Check FileDesc
  8.         if (fileDesc < 0)
  9.         {
  10.                 perror("Write gpio - direction Error");
  11.                 return fileDesc; //-1
  12.         }
  13.         //Write Direction to file
  14.         if(gpioDirection == GPIO_OUT)
  15.         {
  16.                 write(fileDesc, "out", sizeof("out"));
  17.         }
  18.         else
  19.         {
  20.                 write(fileDesc, "in", sizeof("in"));
  21.         }
  22.         close(fileDesc);
  23.         return 0;
  24. }

Funkcja pozwalająca na ustawienie stanu wysokiego lub niskiego:

  1. static int gpioSetValue(unsigned int gpioPinNumber, unsigned int gpioPinValue)
  2. {
  3.         int fileDesc = -1;
  4.         char buf[100] = {0x00};
  5.         snprintf(buf, sizeof(buf), GPIO_PIN_DIR "%d/value", gpioPinNumber);
  6.         fileDesc = open(buf, O_WRONLY);
  7.         if(fileDesc < 0)
  8.         {
  9.                 perror ("FileDescriptor gpio set value ERROR");
  10.                 return fileDesc;
  11.         }
  12.         if (gpioPinValue == 1) //high
  13.         {
  14.                 write(fileDesc, "1", sizeof("1"));
  15.         }
  16.         else    //low
  17.         {
  18.                 write(fileDesc, "0", sizeof("0"));
  19.         }
  20.         close(fileDesc);
  21.         return 0;
  22. }

Poniżej sterowanie wszystkimi pinami z podłączonymi diodami (od IO10 do IO13):

  1. int main (void)
  2. {
  3.         if((gpioExportPin(GPIO_PIN_10) < 0) ||
  4.            (gpioExportPin(GPIO_PIN_11) < 0) ||
  5.            (gpioExportPin(GPIO_PIN_12) < 0) ||
  6.            (gpioExportPin(GPIO_PIN_13) < 0))
  7.         {
  8.                 exit (EXIT_FAILURE);
  9.         }
  10.         if((gpioSelectDirection(GPIO_PIN_10, GPIO_OUT) < 0) ||
  11.            (gpioSelectDirection(GPIO_PIN_11, GPIO_OUT) < 0) ||
  12.            (gpioSelectDirection(GPIO_PIN_12, GPIO_OUT) < 0) ||
  13.            (gpioSelectDirection(GPIO_PIN_13, GPIO_OUT) < 0))
  14.         {
  15.                 exit (EXIT_FAILURE);
  16.         }
  17.         while (1)
  18.         {
  19.                 gpioSetValue(GPIO_PIN_10, 1);
  20.                 gpioSetValue(GPIO_PIN_11, 1);
  21.                 gpioSetValue(GPIO_PIN_12, 1);
  22.                 gpioSetValue(GPIO_PIN_13, 1);
  23.                 sleep (5);
  24.                 gpioSetValue(GPIO_PIN_10, 0);
  25.                 gpioSetValue(GPIO_PIN_11, 0);
  26.                 gpioSetValue(GPIO_PIN_12, 0);
  27.                 gpioSetValue(GPIO_PIN_13, 0);
  28.                 sleep (5);
  29.         }
  30.         return EXIT_SUCCESS;
  31. }

Teraz przejdę do opisu obsługi przycisku. Tutaj podobnie jak w przypadku wersji dla bash należy odczytać dane z pliku value gdzie sprawdzany będzie aktualny stan pinu. W przykładzie wykorzystam przycisk podłączony pod pin 4.

Sprawdzanie przycisku będzie polegało na sprawdzaniu stanu zbocza w oparciu o funkcję asynchronicznego wejścia/wyjścia zdefiniowane w bibliotece poll.h.

Na samym początku należy ustawić zbocze jakim będzie wyzwalane przerwanie:

  1. static int gpioSelectEdge(unsigned int gpioPinNumber, char *gpioEdge)
  2. {
  3.         int fileDesc;
  4.         char buf[70];
  5.         snprintf(buf, sizeof(buf), GPIO_PIN_DIR "%d/edge", gpioPinNumber);
  6.         fileDesc = open(buf, O_WRONLY);
  7.         if(fileDesc < 0)
  8.         {
  9.                 perror ("Set gpio - edge ERROR");
  10.                 return fileDesc;
  11.         }
  12.         if(gpioEdge == 1) //RISING
  13.         {
  14.                 write(fileDesc, "rising", sizeof("rising"));
  15.         }
  16.         else if(gpioEdge == 2) //FALLING
  17.         {
  18.                 write(fileDesc, "falling", sizeof("falling"));
  19.         }
  20.         else //BOTH
  21.         {
  22.                 write(fileDesc, "both", sizeof("both"));
  23.         }
  24.         close(fileDesc);
  25.         return 0;
  26. }

Tutaj następuje edycja pliku edge. Dla przypomnienia jako parametr można wprowadzić rising, falling lub both.

W celu uzyskania wartości z pliku value wykorzystam funkcję przekazującą deskryptor do otwartego pliku value.

  1. static int gpioValueFileDesc(unsigned int gpioPinNumber)
  2. {
  3.         int fileDesc;
  4.         char buf[60];
  5.         snprintf(buf, sizeof(buf), GPIO_MAIN_DIR "%d/value", gpioPinNumber);
  6.         fileDesc = open(buf, O_RDONLY | O_NONBLOCK);
  7.         if(fileDesc < 0)
  8.         {
  9.                 perror("Open value file Error");
  10.         }
  11.         return fileDesc;
  12. }

Plik należy odczytać tylko do odczytu, ponieważ będzie z niego pobierana wartość dla pinu. Dodatkowo należy umieścić flagę O_NONBLOCK otwierająca plik w trybie nieblokującym.

Funkcja main do pętli while wygląda następująco:

  1. int main(void)
  2. {
  3.         struct pollfd pollFdStruct[1];
  4.         int structNumbers = 1;
  5.         int fileDesc = -1;
  6.         int pollOperStat = 0;
  7.         char buf[2] = {0x00};
  8.         if (gpioExportPin(GPIO_PIN_BTN_4) < 0) {
  9.                 exit(EXIT_FAILURE);
  10.         }
  11.         if (gpioSelectDirection(GPIO_PIN_BTN_4, GPIO_IN) < 0) {
  12.                 exit(EXIT_FAILURE);
  13.         }
  14.         if (gpioSelectEdge(GPIO_PIN_BTN_4, 1) < 0) {
  15.                 exit(EXIT_FAILURE);
  16.         }
  17.         fileDesc = gpioValueFileDesc(GPIO_PIN_BTN_4);
  18.         if (fileDesc < 0){
  19.                 exit(EXIT_FAILURE);
  20.         }
  21.         //Set offset
  22.         lseek(fileDesc, 0, SEEK_SET);
  23.        
  24.         //ReadFile
  25.         read(fileDesc, &buf, 2);
  26.         printf(&buf);
  27.         //Struct Descriptor
  28.         //Write file descriptor to file
  29.         pollFdStruct[0].fd = fileDesc;
  30.         //Set event flag
  31.         //High priority data may be read without blocking
  32.         pollFdStruct[0].events = POLLPRI;
  33.         pollFdStruct[0].revents = -1;
  34.         //...
  35.         //...
  36. }

Po deklaracji pinu oraz odczycie deskryptora dla pliku value należy przygotować dane dla struktury pollfd.

Do niej wprowadzany jest deskryptor  do pliku value, rodzaj zdarzenia oraz jak długo nastąpi oczekiwanie na zdarzenie.

W pętli while następuje wywołanie funkcji poll po czym następuje sprawdzenie czy przycisk został wciśnięty po aktualizacji flagi w strukturze pollfd.

  1. while (1)
  2. {
  3.     //Enable Poll, if success number > 0
  4.     //if 0 then timeout
  5.     pollOperStat = poll(pollFdStruct, structNumbers, 2000);
  6.      //Check if Error occure
  7.      if(pollOperStat < 0)
  8.      {
  9.         printf("poll function ERROR\n");
  10.         break;
  11.      }
  12.      else if(pollOperStat == 0)
  13.      {
  14.          printf("poll function timeout\n");
  15.      }
  16.    
  17.      if (pollFdStruct[0].revents & POLLPRI)
  18.      {
  19.         printf ("poll(): GPIO_%d interrupt occurred\n", GPIO_PI$
  20.         lseek(pollFdStruct[0].fd, 0, SEEK_SET);
  21.         read(pollFdStruct[0].fd, &buf, 2);
  22.      }
  23. }//close while

  24. close(fileDesc);
  25. return EXIT_FAILURE;

  26. } //close main

Po wciśnięciu przycisku nastąpi aktualizacja danych w pliku value.

Programy opisane w tym poście dotyczące części języka C można pobrać z dysku Google pod tym linkiem.