Pierwsze kroki z Raspberry Pi: pierwszy program w języku C
Artykuł opracowaliśmy z myślą o programistach mających przynajmniej niewielką znajomość języka C, którzy nigdy nie mieli okazji programować w systemie Linux i nie wiedzą jak się za to zabrać. Dystrybucja Raspbian zawiera wszystko co jest potrzebne do rozpoczęcia programowania, czyli edytor i kompilator.
Zakładam, że komputer Raspberry Pi jest już uruchomiony i jesteśmy zalogowani. Uruchamiamy ulubiony edytor plików tekstowych, ja użyję edytora nano, wpisuję więc polecenie
nano simpleprg.c
simpleprg.c to nazwa pliku w którym umieścimy kod programu – tradycyjnego „Hello world!”:
#include main() { printf("Hello world!\n "); }
Żeby skompilować program wywołujemy kompilator gcc poleceniem:
gcc -o simpleprg simpleprg.c
Parametr -o simpleprg informuje kompilator, że kod wynikowy ma być umieszczony w pliku o nazwie simpleprg, ostatni parametr to nazwa pliku z kodem źródłowym. O ile nie popełniliśmy żadnej pomyłki przy wprowadzaniu kodu i program skompilował się poprawnie, to możemy go uruchomić wykonując polecenie:
./simpleprg
Jeśli po uruchomieniu programu pojawi się na ekranie napis Hello world! to wszystko poszło jak trzeba.
Teraz przystąpimy do trudniejszej rzeczy, stworzymy program, który na podstawie parametru podanego w linii poleceń będzie włączał odpowiednie diody modułu KAmodLED8 (sposób dołączenia modułu do Raspberry znajduje się tu), wykorzystując do tego bibliotekę wiringPi (opis instalacji biblioteki znajduje się tutaj). Biblioteka zawiera trzy funkcje inicjalizujące:
- int wiringPiSetup (void)
- int wiringPiSetupGpio (void)
- int wiringPiSetupSys (void)
Tylko ostatnia funkcja umożliwia sterowanie liniami bez uprawnień roota, dlatego skorzystamy właśnie z niej, ale przed uruchomieniem programu musimy skonfigurować te linie, w tym celu stworzyłem w pliku initGPIOs.sh skrypt:
gpio export 2 out gpio export 3 out gpio export 4 out gpio export 7 out gpio export 9 out gpio export 10 out gpio export 11 out gpio export 15 out
Po jego uruchomieniu linie GPIO będą dostępne dla naszego programu.
W pierwszej kolejności program sprawdza liczbę argumentów, jeśli zmienna argc ma wartość 2, to program otrzymał jeden argument (2, bo pierwszym argumentem jest nazwa programu), następnie program próbuje przekonwertować argument na liczbę korzystając z funkcji HexToNum. Funkcja HexToNum przyjmuje jako pierwszy argument ciąg znaków, który zostaje zinterpretowany jako liczba szesnastkowa, jej wartość jest zapisywana w zmiennej wskazywanej przez drugi parametr. Jeśli wszystko do tej pory się udało, to wywołujemy funkcję inicjalizującą wiringPiSetupSys. Teraz w pętli for sprawdzamy osiem najmłodszych bitów liczby przekazanej w argumencie i dla bitów o wartości 1 zapalamy diody, dla bitów o wartości 0 – gasimy.
#include #include int HexToNum(char *s, unsigned int *res) { int pos = 1; *res = 0; while(*s) { if ( (*s)>='0' && (*s)<='9' ) *res += pos * ((*s) - 48); else if ( (*s)>='a' && (*s)<='f') *res += pos * ((*s) - 87); else if ( (*s)>='A' && (*s)<='F') *res += pos * ((*s) - 55); else return 0; pos <<= 4; s++; } return 1; } int main(int argc, char *argv[]) { char gpioPins[]={2,3,4,7,9,10,11,15}; unsigned int value; int i; if ((argc != 2) || (HexToNum(argv[1], &value) == 0)) { printf("Usage: simpleprg \n"); printf(" LEDS: hexadecimal value (i.e. 0xAA)\n"); return 0; } if (wiringPiSetupSys() != -1) for (i = 0; i < 8; i++) digitalWrite(gpioPins[i], (value & (1 << i)) ? HIGH : LOW); else return 1; printf("KAmodLED8 leds set to 0x%X\n", value); }
Ze względu na dołączenie biblioteki wiringPi kompilację programu wykonamy w dwóch etapach, najpierw skompilujemy nasz program, następnie dołączymy do niego biblioteki i utworzymy program wynikowy:
gcc -c -o spimpleprg.o simpleprg.c gcc -o simpleprg simpleprg.o -L/usr/local/lib -lwiringPi
Jeśli kompilacja przebiegła pomyślnie, to możemy wywołać teraz nasz program i sprawdzić czy wszystko działa jak trzeba, dla argumentu 0 wszystkie diody powinny zostać zgaszone, dla FF – wszystkie zapalone, dla AA oraz 55 co druga dioda powinna swiecić.