Elektroda.pl
Elektroda.pl
X
Computer ControlsComputer Controls
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60

DjExit 18 Gru 2014 23:23 11040 7
  • Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60

    Witam, niedawno Raspberry Pi fundation wypuściło na rynek nowe wersje swojego miniaturowego komputera A+ i B+. Czym różnią się poszczególne wersje można znaleźć bez problemu w internecie, także nie będę się na ten temat rozpisywał. Zaznaczę tylko, że wersja A+ jest uproszczoną i (teoretycznie) tańszą wersją maliny pozbawianą układu smsc95xx (Hub 4xUSB 2.0 + Ethernet), posiadającą tylko jeden port USB i pozbawioną karty sieciowej. Opracowany przez mnie tutorial jest przeznaczony dla posiadaczy wszystkich wersji RPI, jeśli posiadamy wersję B lub B+ to uzyskamy dodatkowy interfejs sieciowy, dzięki któremu możemy zbudować na naszej malinie np Router. Natomiast posiadacze wersji A i A+ zyskają interfejs sieciowy którego wcześniej brakowało, więc korzyści z jego posiadania są oczywiste :D

    Cel: Uruchomić popularny moduł ethernet (przeznaczony dla Arduino) oparty na układzie ENC28J60 w systemie Raspberry Pi.

    Słowem wstępu: Uruchomienie enc28j60 w raspberry pi (Raspbian) wymaga przekompilowania kernela, z uwagi na fakt, że kompilacja kernela na samej malinie może trwać godzinami, to my zrealizujemy to na dowolnej maszynie x86/64 z użyciem cross-kompilacji dzięki czemu uwiniemy się dość szybko (ok 30 minut), a przy okazji przybliżę Wam proces cross-kompilacji, który na pewno nie raz się przyda gdy trzeba będzie dołożyć nowy moduł do kernela ;) Ok, zaczynamy!

    Na początek co potrzebujemy:
    1. Raspberry Pi (dowolny model) z najnowszym firmwarem (Raspbian). Możemy go pobrać z oficjalnej strony raspberry: http://www.raspberrypi.org/downloads/
    Natomiast jeśli posiadamy starszą wersję musimy ją zaktalizować do najnowszej poleceniami rpi-update, apt-get update, apt-get upgrade, apt-get dist-upgrade aż do skutku..

    2. Moduł ethernet oparty o układ enc28j60. Można bez problemu kupić go na naszym rodzimym portalu aukcyjnym za bardzo rozsądne pieniądze. Moduł ten zwykle sprzedawany jest z przeznaczeniem dla platformy Arduino. Można też samodzielnie zaprojektować płytkę lub złożyć układ na płytce prototypowej z pomocą noty katalogowej tego układu, który jest bardzo prosty.
    UWAGA: Układ (i moduł też) enc28j60 zasilany jest napięciem 3.3V. Należy o tym pamiętać podłączając moduł do raspberry lub projektując samemu układ!

    3. System linux (ja zalecam Debiano-podobne, w tutorialu korzystam z Ubuntu 14.04 LTS). System zainstalowany bezpośrednio na komputerze lub w formie wirtualnej maszyny lub jako zdalny serwer przez ssh - Ważne jest, żeby był aktualny i żebyśmy posiadali do niego dostęp na wysokich prawach. Kolejną ważną rzeczą jest posiadanie odpowiednich bibliotek wymaganych do kompilacji kernela (Nie jestem ich pewien):
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    TUTORIAL:
    I) Kroki wykonujemy na komputerze:
    1. Przygotowujemy katalog roboczy, najlepiej w katalogu użytkownika ( U mnie "pi") :
    Kod: bash
    Zaloguj się, aby zobaczyć kod

    2. Wchodzimy do katalogu i pobieramy źródła najnowszego kernela dla raspberry (W chwili pisania tutoriala 3.12.34), najnowszą wersję kompilatorów i narzędzi do cross-kompilacji (tzw. toolchain) i tworzymy katalog dla przyszłych modułów:
    Kod: bash
    Zaloguj się, aby zobaczyć kod

    3. Ustawiamy zmienne środowiskowe na czas kompilacji (UWAGA: wylogowanie się z terminala spowoduje skasowanie ustawionych zmiennych, więc trzeba je ponownie ustawić jeśli przerwiemy pracę w trakcie tutoriala!):
    Kod: bash
    Zaloguj się, aby zobaczyć kod

    4. Wchodzimy do katalogu ze źródłami kernela. Musimy pobrać i wypakować plik config.gz z działającej maliny. W tym celu łączymy się z naszym raspberry albo przez ssh albo kopiujemy lokalnie plik
    "/proc/config.gz" z maliny na nasz komputer do katalogu ze źródłami kernela "/home/pi/rpi_kernel/linux/". Następnie wypakowujemy config poleceniem:
    Kod: bash
    Zaloguj się, aby zobaczyć kod

    5. Musimy teraz zmodyfikować kilka plików aby wskazać, że do portu SPI naszej maliny będzie podłączony układ enc28j60 o określonych parametrach, że moduł enc28j60 ma reagować na przerwanie wywołanie zboczem opadającym na określonym pinie GPIO i w końcu, że w ogóle chcemy kompilować taki moduł:

    - Edytujemy plik /home/pi/rpi_kernel/linux/arch/arm/mach-bcm2708/bcm2708.c Szukamy w pliku ciągu "bcm2708_spi_devices[]" i zmieniamy tak, by wyglądało jak poniżej:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    - Edytujemy plik /home/pi/rpi_kernel/linux/drivers/net/ethernet/microchip/enc28j60.c i szukamy w nim linijki z ciągiem "request_irq" i zmieniamy tak jak poniżej:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    - Edytujemy wypakowany wcześniej przez nas plik ".config" /home/pi/rpi_kernel/linux/.config i szukamy ciągu "enc28j60". Powinniśmy znaleźć wyremowaną linijkę "# CONFIG_ENC28J60 is not set" lub coś w ten deseń. Zmieniamy tą linijkę na dwie:
    Code:
    CONFIG_ENC28J60=m
    
    CONFIG_ENC28J60_WRITEVERIFY=y


    6. Czyścimy dla pewności źródła kernela wydając polecenie (będąc w głównym katalogu ze źródłami /home/pi/rpi_kernel/linux/)
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    7. Konfigurujemy nasze źródła pod dyktando pliku .config:
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    8. Kompilujemy kernela! Może to potrwać trochę czasu w zależności od tego na jakim sprzęcie pracujemy, ale polecam po wydaniu następujących poleceń zrobić sobie kawę ;). Jeśli pracujemy na maszynie wielordzeniowej (a pewnie tak jest) dodajemy parametr "-j ilość_rdzeni+1"
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    9. Jeśli kompilacja zakończyła się bez błędów a w katalogu /home/pi/rpi_kernel/linux/arch/arm/boot/ znajduje się plik "zImage" to możemy "zainstalować" skompilowane moduły do przygotowanego wcześniej katalogu:
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    10. Przechodzimy do katalogu z tool-chainem i używając skryptu "imagetool-uncompressed.py" generujemy sobie plik obrazu kernela:
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    11. Przygotowujemy i kopiujemy powstałe pliki do naszej maliny, możemy po prostu wyjąć kartę SD i zamontować ją w naszym komputerze, możemy kopiować przez scp albo mc lub przenieść za pomocą pendriva. Najpierw jednak usuwamy niepotrzebne symlinki z katalogu "modules":
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    Kopiujemy z komputera do raspberry nadpisując pliki i katalogi (dla bezpieczeństwa dobrze stare skopiować gdzieś na bok):
    /home/pi/rpi_kernel/tools/mkimage/kernel.img -------> /boot/kernel.img
    /home/pi/rpi_kernel/modules/lib/firmware -------> /lib/firmware
    /home/pi/rpi_kernel/modules/lib/modules -------> /lib/modules


    12. Wyłączamy malinę i przystępujemy do przyłączenia modułu enc28j60 do odpowiednich pinów GPIO:
    Code:
    ENC - RPi
    
    =======
    VCC   -   3v3 (np pin 1)
    GND   -   GND (np pin 9)
    CS    -   CE0 (gpio 8 / pin 24)
    SI    -   MOSI (gpio 10 / pin 19)
    SCK   -   SCKL (gpio 11 / pin 23)
    SO    -   MISO (gpio 9 / pin 21)
    INT   -   GPIO25 (pin 22)


    Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60

    13. Podłączamy kabel sieciowy do modułu i włączamy malinę. Jeśli wszytko jest w porządku diody od ethernetu powinny się zaświecić a po załadowaniu systemu ukaże się nam nowy świeży i pachnący interfejs sieciowy :D :
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    W pliku /proc/interrupts powinna być linijka potwierdzająca istnienie przerwania z enc28j60:
    Code:
    195:      10968      GPIO  enc28j60


    A w logach powinniśmy zobaczyć coś takiego:
    Code:
    Dec 18 13:41:05 rpi-devdev kernel: [    7.830397] enc28j60 spi0.0: enc28j60 Ethernet driver 1.01 loaded
    
    Dec 18 13:41:05 rpi-devdev kernel: [    7.854188] net eth0: enc28j60 driver registered
    Dec 18 13:41:05 rpi-devdev kernel: [   23.929625] net eth0: link down
    Dec 18 13:41:05 rpi-devdev kernel: [   23.929682] net eth0: normal mode
    Dec 18 13:41:05 rpi-devdev kernel: [   23.929748] net eth0: normal mode
    Dec 18 13:41:05 rpi-devdev kernel: [   23.929907] net eth0: multicast mode
    Dec 18 13:53:09 rpi-devdev kernel: [  733.122972] net eth0: link up - Half duplex


    UWAGA: Jeśli enc28j60 dołączamy do Raspberry Pi w wersjach z wbudowaną kartą sieciową to zobaczymy nowy interfejs jako eth1 a nie eth0!

    Podsumowanie:
    Moduł enc28j60 przetestowałem przez kilka dni jako karta sieciowa i sprawuje się bardzo dobrze i stabilnie. Pingi są niskie a transfer danych przetestowany za pomocą narzędzia iperf wykazał przepustowość tej karty na ok 3Mbps w obydwu kierunkach. Nie jest to powalająca wartość, ale po podstawowych zadań wystarczająca.

    Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60 Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60 Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60 Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60 Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60

    Mam nadzieję, że tutorial się komuś przyda, a Wy dacie mi znać czy się udało :) Na koniec jeszcze źródła którymi się posiłkowałem:

    http://elinux.org/Raspberry_Pi_Kernel_Compilation
    http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=18397
    http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=57157

    Pozdrawiam,
    DjExit

    Fajne! Ranking DIY
    Potrafisz napisać podobny artykuł? Wyślij do mnie a otrzymasz kartę SD 64GB.
    O autorze
    DjExit
    Poziom 23  
    Offline 
    Specjalizuje się w: elektronika & komputery
    DjExit napisał 763 postów o ocenie 69, pomógł 10 razy. Mieszka w mieście Boguszów-Gorce. Jest z nami od 2004 roku.
  • Computer ControlsComputer Controls
  • #2
    MK-dugi
    Poziom 8  
    Dziękuję, artykuł odpowiada na dwa moje pytania.
    Czy da się na RPi zrobić router, i jaką może mieć wydajność.

    Ale trafiłem tutaj, bo szukam czegoś innego.

    Czy da się zrobić daleką komunikację z urządzeniem SPI?

    RPi <-ethernet->Switch<-ethernet->enc28j60<-SPI->urządzenie.

    Może Autor spotał się z czymś takim?

    Pozdrawiam
  • Computer ControlsComputer Controls
  • #4
    MK-dugi
    Poziom 8  
    Ten mój problem trochę nie w temacie tego tutoriala.

    Ale znalazłem coś takiego:
    SR01E12

    W/g opisów robi to, co potrzebuję.

    Pewnym minusem jest binarna biblioteka. Nie wiadomo jak się zachowa z przyszłymi wersjami GNU/Linuksa na RPi.

    Szukam dalej. Pozdrawiam!
  • #5
    GZK
    Poziom 11  
    Witam,
    czy komuś udało się uruchomić na malinie ten moduł, w opisany wyżej sposób?
    Ja próbowałem kroskompilacji i kompilowałem całość bezpośrednio na malinie, ale niestety efektów brak :(
  • #6
    rft_polska
    Poziom 6  
    Tak udało się, swoją drogą bardzo fajny opis.
  • #7
    DARK$$
    Poziom 12  
    Piękny opis. Wszystko działa.

    :arrow: GZK Włącz SPI i odłącz wszystkie inne karty sieciowe przed uruchomieniem. U mnie moduł jądra nie startuje kiedy mam podłączoną kartę np. USB WiFi.

    Zrealizowałem też kartę jako moduł wpinany bezpośrednio w złącze goldpin. Wygląda on tak:

    Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60

    Mam jeszcze trzy PCB. Pinout taki jak w tutorialu. Dodatkowo możliwość podłączenia sygnału WOL poprzez solder jumper. Może ktoś jest zainteresowany budową własnego modułu?
  • #8
    xboomx
    Poziom 2  
    Dodam, że tutorial nie uwzględnia bibliotek pozwalających kompilować malinę na 64 bitowym systemie. Nie wiem też jakie dokładnie paczki na to pozwalają więc u siebie kompiluję na Ubuntu 32 bit.

    Druga sprawa - czy aby "make mrproper" jest użyte w odpowiednim momencie? Jak tego używam to tracę rozpakowany plik ".config" i kolejne polecenie każe mi z palca parametry ustalać.