Intel Galileo: jak rozpocząć?

Intel Galileo Getting Started Guide oraz Intel Galileo 101

galileo 

Aktualne wprowadzenie do platformy Intel Galileo (zarówno Gen 1 jak i Gen 2) można znaleźć pod adresem: https://communities.intel.com/docs/DOC-22872. Należy również zapoznać się z instrukcją Intel Galileo Board User Manual. W dalszej części tekstu znajdują się jedynie informacje wykraczające, bądź rozszerzające zakres dokumentów przygotowanych przez firmę Intel, m.in.:

  • sposoby, w jaki możemy uzyskać dostęp do płyty,
  • proces kompletowania niezbędnych narzędzi,
  • metody programowania GPIO i pozostałych peryferiów.

Dostęp do platformy Intel Galileo

Podstawowy obraz systemu Linux znajdujący się we wbudowanej pamieci Flash (ze względu na b. mały rozmiar) zapewnia jedynie dostęp do konsoli przez port szeregowy. W praktyce tak okrojona dystrybucja jest jednak zupełnie nieużyteczna - już na samym początku zalecamy załadowanie obrazu systemu dostarczanego przez f. Intel (plik SD-Card Linux Image na stronie Software Downloads - brak w nim jednak np kompilatora gcc).

Update 10/2014:

Sprawdzony obraz (zawierający gcc) można pobrać ze strony: http://ph0b.com/adding-dev-tools-gcc-make-to-galileo-sd-image/. Plik znajduje się pod adresem: http://ph0b.com/wp-content/uploads/2014/01/linux_image_for_sd_with_dev_tools.zip.

Obecnie python, gcc oraz inne narzędzia developerskie są częścią oficjalnych obrazów dostarczanych przez firmę Intel w ramach Intel IoT Developer Zone.

Konsola systemu Linux - port szeregowy

Poniższe informacje dot. platformy Intel Galileo Gen 1. Intel Galileo Gen 2 ma zupełnie inaczej zorganizowany port szeregowy.

Domyślnie konsola systemu Linux dostępna jest na złączu UART (w formie złącza 3,5mm JACK TRS). Dostęp uzyskamy po wykonaniu odpowiedniego przewodu 3,5mm JACK TRS <=> żeńskie DB9 wg poniższego schematu (źródło: https://communities.intel.com/message/208514#208514, schemat użytkownika Luc):

serial-cable-galileo IntelGalileo UART

Wbrew oznaczeniu 'UART' na płytce drukowanej poziomy napięć na opisywanym złączu to standard EIA232 (do +/- 15V). Dołączenie tutaj układu np. mikrokontrolera bez konwetera napięć gwarantuje jego uszkodzenie.

Domyślne parametry połączenia szeregowego to 115200, 8, N, 1. W dowolnym programie terminala (np. TeraTerm na platformie Windows), po skonfiguowaniu parametrów portu, jego otwarciu i podłączeniu zasilania do płyty rozwojowej powinniśmy zobaczyć komunikaty związane z ładowaniem systemu operacyjnego.

Komunikaty związane z ładowaniem systemu operacyjnego.

Po załadowaniu systemu zostaniemy powitani pytaniem o login konta (domyślnie root, brak hasła) a po zalogowaniu pojawi sie znak zachęty systemu.

Konsola systemu po zalogowaniu

Konsola systemu Linux - ssh

Dostęp do konsoli systemu Linux można uzyskać poprzez ssh (wykorzystując np. darmowy program putty). Konieczna jest oczywiście połączenie z siecią Ethernet oraz znajomość adresu IP jaki router przydzielił w czasie sesji DHCP (lub jaki został skonfigurowany statycznie). Numer IP uzyskamy wywołując w konsoli polecenie:

ifconfig eth0

Przykładowa odpowiedź:

eth0    Link encap:Ethernet HWaddr 98:4F:EE:00:32:AE
        inet addr:192.168.0.104 Bcast:192.168.0.255 Mask:255.255.255.0
        inet6 addr: fe80::9a4f:eeff:fe00:32ae/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
        RX packets:3952 errors:0 dropped:0 overruns:0 frame:0
        TX packets:2518 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000
        RX bytes:531109 (518.6 KiB) TX bytes:258271 (252.2 KiB)
        Interrupt:40 Base address:0x8000
putty  putty2 

Ładowanie plików - scp

Ładowanie plików źródłowych, driverów i innych najwygodniej realizwać poprzez (leciwy już) protokół scp (secure copy) oraz darmowy program WinSCP, który wspiera ten rodzaj trnasferu plików. Ponownie konieczna jest znajomość numeru IP z jakim pracuje Galileo.

Konfiguracja WinSCP do połączenia z Intel Galileo Okno główne po połączeniu (listing katalogu użytkownika root)

Wstępna konfiguracja systemu do pracy

Problemy z konsolą systemu dostępną na porcie szeregowym

Update 10/2014:

Po załadowaniu systemu na konsoli pojawia się:

/etc/init.d/clloader.sh: line 3: /dev/ttyGS0: No such file or directory

Rozwiązanie opisano w wątku: https://communities.intel.com/thread/48024?start=0&tstart=0

Należy usunąć lub zakomentować w pliku /etc/inittab dwie linie związne z uruchamianiem skryptów Arduino:

#grst:5:respawn:/opt/cln/galileo/galileo_sketch_reset -v
#clld:5:respawn:/etc/init.d/clloader.sh

Probelmy te nie występują w oficjalnch obrazach dostarczanych przez firmę Intel.

Edytor nano

Zarówno oryginalny obraz systemu dostarczany przez f. Intel jak i obrazy alternatywne (w tym zalecany) zawierają jedynie 'specyficzny' editor 'vi'. W większości przypadków (dla użytkowników nie znających skrótów i konwencji narzucanych przez vi) lepszym pomysłem jest instalacja prostego edytora tekstowego 'nano' (wymagane aby w obrazie obecny był kompilator gcc). Proces instalacji (przy okazji również sprawdzenie konfiguracji gcc) wg http://www.spider-e.com/wp/?p=187:

  1. logujemy sie jako uzytkownik root
  2. w katalogu domowym (cd ~) tworzymy katalog nano-src:
    mkdir nano-src
  3. przechodzimy do nowo utworzonego katalogu
    cd nano-src
  4. pobieramy archowum tar zawierające źródła edytora nano:
    curl http://www.nano-editor.org/dist/v2.2/nano-2.2.6.tar.gz >nano-2.2.6.tar.gz
  5. rozpakowujemy pobrane archiwum:
    tar zxvf nano-2.2.6.tar.gz
  6. przechodzimy do folderu:
    cd nano-2.2.6
  7. konfigurujemy oraz budujemy edytor z pobranych źródeł za pomocą serii poleceń:
    ./configure
    make install
  8. możemy sprawdzić działanie edytora poleceniem:
    nano <nazwa pliku tekstowego>

Sterowanie wyprowadzeń

Intel Galileo Gen1 dysponuje zestawem wyprowadzeń zgodnym ze standardem Arduino Uno rev3. Mogą być one skonfigurowane jako GPIO, a wybrane z nich mogą alternatywnie pełnić rolę wejść analogowych lub wyjść PWM. Informację o tym jak skonfigurowane są porty GPIO uzyskamy poprzez wydanie polecenia:

root@quark0032ae:~# cat /sys/kernel/debug/gpio
GPIOs 0-1, platform/sch_gpio.2398, sch_gpio_core:
GPIOs 2-7, platform/sch_gpio.2398, sch_gpio_resume:
gpio-2 (cy8c9540a-int-s3 ) in hi
gpio-7 (cy8c9540a-a0 ) in hi
GPIOs 8-15, intel_qrk_gip_gpio:
gpio-8 (SPI_CS ) out hi
gpio-10 (SPI_CS ) out hi
gpio-13 (cy8c9540a-int-s0 ) in hi
GPIOs 16-55, cy8c9540a, can sleep:

Jak widać w systemie znajduje się znacznie więcej GPIO niż fizycznie wyprowadzono na płytce drukowanej. Są one podzielone na kilka grup (m.in. sterowane bezpośrednio z procesora Quark oraz sterowane z pośrednictwem ekspandera CY8C9540A) oraz dodatkowo multipleksowane (część z GPIO steruje multiplekserami mapującymi różne funkcje na fizyczne wyprowadzenia płyty). Kompletna tabela z listą wyprowadzeń GPIO oraz ich mapowania do systemu Sysfs znajduje się w dokumencie Galileo I/O Mappings oraz pod linkiem: http://www.malinov.com/Home/sergey-s-blog/intelgalileo-programminggpiofromlinux.

Z linii komed

Po wydaniu serii komend (http://wiki.ros.org/IntelGalileo/IntelGalileoGPIO):

echo -n "3" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio3/direction
echo "1" > /sys/class/gpio/gpio3/value

Zielona dioda LED oznaczona na płytce GP (pomiędzy kartą uSD a dolnym złączem szpilkowym systemu Arduino) powinna się włączyć.

echo "0" > /sys/class/gpio/gpio3/value

Zielona dioda LED oznaczona na płycie GP powinna się wyłaczyć.

Jest to najprostsze z GPIO - jest podłączone bezpośrednio do procesora Quark i nie wymaga multipleksowania. Analogiczne sterowanie linią IO10 (do której można podłączyć multimetr lub zewnętrzną diodę LED) wymaga już przełączenia multipleksera:

echo -n "42" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio42/direction
echo "1" > /sys/class/gpio/gpio42/value

Dopiero po tej konfiguracji sens ma ustawienie wartości gpio16, która steruje pracą wyprowadzenia po przełączeniu multipleksera:

echo -n "16" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio16/direction
echo "1" > /sys/class/gpio/gpio16/value

Spowoduje ustawienie stanu wysokiego na IO10.

echo "0" > /sys/class/gpio/gpio16/value

Spowoduje ustawienie stanu niskiego na IO10.

Aktualną konfigurację wyprowadzeń można zawsze sprawdzić poleceniem:

root@quark0032ae:~# cat /sys/kernel/debug/gpio
GPIOs 0-1, platform/sch_gpio.2398, sch_gpio_core:
GPIOs 2-7, platform/sch_gpio.2398, sch_gpio_resume:
gpio-2 (cy8c9540a-int-s3 ) in hi
gpio-3 (sysfs ) out hi
gpio-7 (cy8c9540a-a0 ) in hi
GPIOs 8-15, intel_qrk_gip_gpio:
gpio-8 (SPI_CS ) out hi
gpio-10 (SPI_CS ) out hi
gpio-13 (cy8c9540a-int-s0 ) in hi
GPIOs 16-55, cy8c9540a, can sleep:
gpio-16 (sysfs ) out lo
gpio-42 (sysfs ) out hi

Python

Prosty skrypt (http://wiki.ros.org/IntelGalileo/IntelGalileoGPIO) nieprzerwanie (do czasu użycia kombinacji Ctrl+Z - sygnał SIGSTOP w systemach Unix) włącza i wyłącza diodę LED (oznaczenie GP na druku):

#!/usr/bin/python
import sys
import time
def pins_export():
  try:
    pin1export = open("/sys/class/gpio/export","w")
    pin1export.write("3")
    pin1export.close()
  except IOError:
    print "INFO: GPIO 3 already exists, skipping export"
	
  fp1 = open( "/sys/class/gpio/gpio3/direction", "w" )
  fp1.write( "out" )
  fp1.close()
  
def write_led( value ):
  fp2 = open( "/sys/class/gpio/gpio3/value", "w" )
  fp2.write( str( value ) )
  fp2.close()
  
pins_export()
while True:
  print "on"
  write_led( 1 )
  time.sleep( 1 )
  print "off"
  write_led( 0 )
  time.sleep( 1 )

Wywołanie programu:

python nazwa_skryptu.py

Język C

Równoważny powyższemu program w języku C:

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

void setGPIOPin(char* pin, char* dir, char* drive, char* val) {
char buf[256];
int fd;

// Open the GPIO Export file
fd = open("/sys/class/gpio/export",O_WRONLY);
if(fd == -1)
exit(-1);

// Export chosen pin
write(fd, pin, strlen(pin)); // Export GPIO pin
close(fd);

// Open exported pin DIRECTION file
sprintf(buf,"/sys/class/gpio/gpio%s/direction",pin);
fd = open(buf,O_WRONLY); // open GPIOxx direction file

if(fd==-1)
exit(-1);

// write out the direction
write(fd,dir,strlen(dir)); // set GPIOxx direction to ouy
close(fd);

// open the drive file
sprintf(buf,"/sys/class/gpio/gpio%s/drive",pin);
fd = open(buf,O_WRONLY); // open GPIO drive strength file

if(fd==-1)
exit(-1);

write(fd,drive,strlen(drive)); // set GPIO drive
close(fd);

sprintf(buf,"/sys/class/gpio/gpio%s/value",pin);
fd = open(buf,O_WRONLY);

if(fd==-1)
exit(-1);

write(fd,val,strlen(val)); // set GPIO value
close(fd);
}

int main(int argc, char *argv[]) {
int fd;
setGPIOPin("3", "out", "pullup", "1");

fd = open("/sys/class/gpio/gpio3/value",O_WRONLY);
if (fd==-1) {
printf("Failed to open GPIO On pin 13\n");
exit(-1);
}

while(1) {
write(fd,"1",1);
sleep(1);
write(fd,"0",1);
sleep(1);
}

return 0;
}

Kompilacja i uruchomienie po wydaniu poleceń:

gcc nazwa_pliku.c -o nazwa_pliku
./nazwa_pliku