Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Tutorial: RaspberryPi + moduł SPI Ethernet enc28j60

DjExit 18 Dec 2014 23:23 12192 8
  • 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):
    Code: bash
    Log in, to see the code


    TUTORIAL:
    I) Kroki wykonujemy na komputerze:
    1. Przygotowujemy katalog roboczy, najlepiej w katalogu użytkownika ( U mnie "pi") :
    Code: bash
    Log in, to see the code

    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:
    Code: bash
    Log in, to see the code

    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!):
    Code: bash
    Log in, to see the code

    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:
    Code: bash
    Log in, to see the code

    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:
    Code: cpp
    Log in, to see the code


    - 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:
    Code: cpp
    Log in, to see the code


    - 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/)
    Code: bash
    Log in, to see the code


    7. Konfigurujemy nasze źródła pod dyktando pliku .config:
    Code: bash
    Log in, to see the code


    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"
    Code: bash
    Log in, to see the code


    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:
    Code: bash
    Log in, to see the code


    10. Przechodzimy do katalogu z tool-chainem i używając skryptu "imagetool-uncompressed.py" generujemy sobie plik obrazu kernela:
    Code: bash
    Log in, to see the code


    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":
    Code: bash
    Log in, to see the code


    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 :
    Code: bash
    Log in, to see the code


    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

    Cool! Ranking DIY
    Can you write similar article? Send message to me and you will get SD card 64GB.
    About Author
    DjExit
    Level 23  
    Offline 
    Has specialization in: elektronika & komputery
    DjExit wrote 765 posts with rating 75, helped 10 times. Live in city Boguszów-Gorce. Been with us since 2004 year.
  • Farnell IoTFarnell IoT
  • #2
    MK-dugi
    Level 9  
    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
  • Farnell IoTFarnell IoT
  • #4
    MK-dugi
    Level 9  
    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
    Level 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
    Level 7  
    Tak udało się, swoją drogą bardzo fajny opis.
  • #7
    DARK$$

    Level 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
    Level 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ć.
  • #9
    bigrom
    Level 14  
    Na obecną chwilę wystarczy na karcie w pliku config.txt na końcu dopisać (Uwaga na kodowanie pliku)
    dtoverlay=enc28j60

    i działa