Kursy • Poradniki • Inspirujące DIY • Forum
Takie rozwiązanie, co prawda jakoś działa, ale poza tym ma same wady. Zajmuje dużo miejsca, kompilacja jest powolna, a kod wynikowy zajmuje jeszcze więcej miejsca niż powinien. W skrócie – to złe rozwiązanie.
Pierwszy program będzie do bólu prosty i chyba wszystkim znany:
#include <stdio.h>
int main()
{
printf(„Hello world!\n”);
return 0;
}
Zacznijmy od kompilacji i uruchomienia na PC. Jest to wbrew pozorom częsta praktyka – program opracowywany jest na PC, a dopiero na koniec przenoszony na platformę docelową. Często o wiele łatwiej i wygodniej programuje się na PC. Wrócimy do tego omawiając OpenCV.
Kompilujemy program:
gcc -o hello hello.c
i uruchamiamy:
./hello
Czas wykorzystać kompilator zbudowany za pomocą buildroota i wykonać kompilację. Najpierw skasujmy program w wersji dla PC, żeby nam się nic nie pomyliło (rm hello).
Wcześniej wspominałem, że w katalogu buildroota po kompilacji powstanie folder output. W nim interesują nas dwa podfoldery:
- images – w nim znajduje się obraz systemu, który poprzednio skopiowaliśmy na kartę SD
- host – tutaj znajdziemy gotowe narzędzia takie jak kompilator, czy debugger. Działają one na hoście, czyli komputrze PC
Wewnątrz katalogu host, znajduje się struktura folderów nieco podobna do drzewa plików Linuxa. Zobaczmy zawartość katalogu: buildroot/output/host/usr/bin
Pliki zaczynające się od “arm-buildroot-linux-gnueabihf-” to nasz kompilator, debugger i pozostałe narzędzia tworzące tzw. toolchain. Nazwa może nie jest najpiękniejsza, ale tak przyjęło się nazywać kross-kompilatory.
W poprzedniej części wykorzystaliśmy kompilator dostarczany przez Ubuntu. Miał on przedrostek „arm-linux-gnueabi-”. To co utworzył buildroot to po prostu kolejna wersja kompilatora. Czym różni się od poprzedniej? Po pierwsze „automatycznie” jest połączona z wybranymi przez nas bibliotekami (np. OpenCV), po drugie jest zoptymalizowana do wybranego przez nas modelu procesora.
Warto więc korzystać z tej wersji, zamiast domyślnej. Aby ułatwić sobie życie i uniknąć ciągłego wpisywania ścieżki do naszego toolchaina, można po prostu dodać go do zmiennej PATH.
export PATH=$PATH:/home/elvis/netbook/buildroot/output/host/usr/bin/
Od tej chwili można wykorzystać kompilator arm-buildroot-linux-gnueabihf-gcc dokładnie tak jak wcześniej używaliśmy gcc.
arm-buildroot-linux-gnueabihf-gcc -o hello hello.c
Podobnie jak poprzednio, zobaczymy program skompilowany do pliku „hello”. Jednak jeśli spróbujemy go uruchomić, pojawi się błąd:
bash: ./hello: cannot execute binary file: Exec format error
Nie powinniśmy być zaskoczeni, w końcu program miał działać na procesorze ARM. Czas przenieść nasz program na docelową płytkę. Użyjmy najłatwiejszej, ale niewygodnej opcji – po prostu skopiujmy plik wynikowy „hello” na kartę SD. Polecam umieścić ją w katalogu root, łatwo będzie odszukać w systemie docelowym.
Wykonujemy polecenie:
sudo cp hello /media/elvis/linuxfs/root/
Następnie upewniamy się, że odmontowaliśmy kartę przed wyjęciem z czytnika i umieszczamy ją w płytce docelowej. Uruchamiamy system, logujemy się jako root i możemy uruchomić nasz program (identycznie jak wcześniej na PC):
Program działa i to dokładnie tak samo jak wcześniej na PC. Tylko pracy mieliśmy więcej z przenoszeniem plików.
Kopiowanie plików przez sieć
Teoretycznie możliwe byłoby napisanie programu przenosząc pliki na karcie SD, ale takie rozwiązanie nie jest ani wygodne, ani szybkie. Nie mamy też możliwości debugowania programu.
Czas jakoś ułatwić sobie życie. Programując na małe procesorki, np. AVR najczęściej program wgrywaliśmy dedykowanym programatorem. W przypadku naszego systemu moglibyśmy wykorzystać interfejs JTAG, ale nie jest to łatwe. Dodatkowo musielibyśmy zainwestować w drogi sprzęt. Jest jeszcze jeden problem, nasza płytka nie ma wyprowadzeń pod JTAG (albo ma, ale nie mamy do niej dokumentacji).
Pozostaje poszukać innego rozwiązania!
W przypadku Linuxa, niemal standardem jest wykorzystywanie protokołów sieciowych oraz sieci Ethernet. Nasza płytka posiada taki interfejs (podobnie jak większość płytek ewaluacyjnych Rpi, czy BeagleBone), wykorzystamy go do kopiowania plików, a później nawet do debugowania.
Do podłączenia potrzebny nam będzie standardowy kabel ethernetowy. Można połączyć nawet bezpośrednio komputer z płytką (bez huba). Jeśli mamy skonfigurowaną sieć domową, możemy płytkę przyłączyć do tej sieci. Ja łączę bezpośrednio płytkę z laptopem za pomocą kabla z wtykami RJ-45.
Nie wykorzystuję routera, więc muszę skonfigurować interfejs sieciowy mojego komputera. Edytuję plik /etc/network/interfeces i dopisuję ustawienia:
iface eth0 inet static
address 192.168.7.10
netmask 255.255.255.0
network 192.168.7.0
broadcast 192.168.7.255
Adres wybrałem zupełnie arbitralnie, można używać innych – w każdym razie mój host (PC) będzie miał adres 192.168.7.10.
Teraz czas skonfigurować płykę. Robię to analogicznie, edytując plik /etc/network/interfaces. Można to zrobić na dwa sposoby:
- łącząc się z płytką przez RS-232 i pracując na płytce
- przekładając kartę SD do komputera i zmieniając plik na niej
Ważne, żeby do pliku dodać wpis:
iface eth0 inet static
address 192.168.7.101
netmask 255.255.255.0
network 192.168.7.0
broadcast 192.168.7.255
gateway 192.168.7.10
Po podłączeniu możemy sprawdzić, czy wszystko działa wysyłając „ping” (jeśli interfejs eth0 jest wyłączony, uruchamiamy go pisząc: ifup eth0).
Teraz małe wytłumaczenie – budując buildroota wybieramy jakie pakiety mają zostać przygotowane. Jeśli wybraliśmy dropbear (a był wybrany w przykładowej konfiguracji), nasz system posiada serwer ssh. Hasło roota nie może być puste, więc musimy je zmienić poleceniem passwd. Następnie możemy się już połączyć zdalenie pisząc na PC:
ssh root@192.168.7.101
Mając działające ssh właściwie nie musimy już korzystać z RS232 (przyda się do pracy z uboot-em, ale Linuxa możemy obsługiwać przez ssh). Możemy również za pomocą programu scp kopiować pliki z PC na płytkę. Skasujmy nasz program i spróbujmy wgrać go jeszcze raz.
Kasujemy standardowo: rm hello
Następnie na PC piszemy:
scp hello root@192.168.7.101:.
Podajemy hasło i gotowe!
Bez przekładania karty SD, wgraliśmy plik hello (do katalogu domowego użytkownika root). Jest to dużo łatwiejsza i wygodniejsza opcja niż poprzednio.
Eclipse
Teraz gdy już wiemy jak wykorzystywać nasz toolchain, potrafimy skopiować przygotowany program, czas sprawić, żeby programowanie było naprawdę łatwe miłe i przyjemne.
Potrzebujemy do tego Eclipse w wersji zgodnej z buildrootem. W chwili pisania tego tekstu najnowszy Eclipse miał numer 4.4, ale wtyczki buildroota obsługiwały wersję poprzednią czyli 4.3 (Kepler SR2).
Opis całej procedury konfiguracji dostępny jest pod adresem:
https://github.com/mbats/eclipse-buildroot-bundle/wiki
Pierwszy etap, czyli włączenie obsługi Eclipse w buildroocie mamy już zrobiony – wybraliśmy odpowiednią opcję wcześniej. Pozostaje pobrać i zainstalować Eclipse, a następnie dodać wtyczkę. Wszystko jest opisane bardzo przystępnie pod podanym adresem.
Po ponownym uruchomieniu Eclipse, tworzymy nowy projekt C. Nasz toolchain jest utomatycznie widoczny, wystarczy go wybrać:
Po utworzeniu projektu dodajemy do niego pliki źródłowe. Dla przykładu dodajmy program podobny do poprzedniego:
#include <stdio.h>
int main()
{
printf("Hello Eclipse!\n");
return 0;
}
Teraz wystarczy nacisnąć ctrl+b i program zostanie skompilowany, od razu za pomocą naszego toolchaina. Właściwie to nie musimy nic naciskać o ile wybrana jest opcja: „Build automatically”.
Program wynikowy moglibyśmy podobnie jak poprzednio przenieść na naszą płytkę za pomocą karty SD lub ssh. Można to jednak zrobić jeszcze łatwiej z poziomu Eclipse. Wybieramy opcję „Run configurations”, a następnie tworzymy nową konfigurację typu „C/C++ Remote Application”. Musimy utworzyć nowe połączenie, więc przy polu Connection naciskamy przycisk „New...”.
Wybieramy „SSH Only”
Następnie podajemy adres płytki (u mnie 192.168.7.101) oraz nazwę połączenia (dowolną).
Po naciśnięciu Finish wracamy do konfiguracji i wypełniamy pole „Remote Absolute File Path”.
Teraz program jest gotowy do uruchomienia. Naciskamy Run i widzimy rezultat:
Na dole ekranu, w zakładce „Console” pojawił się komunikat wygenerowany przez nasz program.
Debugger
Konfigurując buildroota wybraliśmy dwie ważne opcje:
- dodanie debuggera (gdb) do naszego toolchaina
- dodanie gdbserver-a do pakietów zainstalowanych na płytce
Takie zmiany to właściwie większość pracy potrzebnej, aby umożliwić debugowanie. Ponieważ opcje wybraliśmy wcześniej, teraz wystarczy uruchomić debugger z poziomu Eclipse-a.
Wybieramy opcję „Debug configurations” i do konfiguracji utworzonej poprzednio dodajemy opcje debuggera. Musimy podać nazwę naszego debuggera. Domyślnie jest to gdb, czyli debugger dla komputerów PC. Zmieniamy na naszą wersję, czyli „arm-buildroot-linux-gnueabihf-gdb”.
Jeśli nie ustawiliśmy zmiennej PATH, podajemy ścieżkę do pliku z debuggerem (tak jest w moim przypadku). Naciskamy Debug, przełączamy Eclipse do perspektywy debuggera i możemy zdalnie śledzić pracę naszego programu:
Artykuł zgłoszony do VII edycji konkursu (po)wakacyjnego!
Nagrody ufundował sponsor główny:
oraz sponsorzy:
To nie koniec, sprawdź również
Przeczytaj powiązane artykuły oraz aktualnie popularne wpisy lub losuj inny artykuł »
debuger, eclipse, linux, programowanie, sieć, zdalnie
Trwa ładowanie komentarzy...