Homepage Wiki Forum Buy

Ethernet über SPI

Aus GNUBLIN

Schwierigkeitsgrad Voraussetzung Gnublin Familie
Gnublin logo easy.png Kernel Modul laden, Netzwerk Grundkentnisse Alle

Inhaltsverzeichnis


Quickstart

Es ist auch möglich LAN am GNUBLIN über die SPI Schnittstelle zu realisieren.

MODULE-LAN SCHRAEGBILD 001.jpg

Dazu benötigt man einfach einen SPI-Ethernet Adapter aus dem Embedded Projects Shop.

http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=2292


Das Datenblatt des ENC28J60 ist unter folgendem Link zu finden:

http://ww1.microchip.com/downloads/en/devicedoc/39662a.pdf

Hinweis: Das Flachbandkabel hat auf einer Seite eine rote Markierung. Diese muss beim Gnublin Board dort sein, wo GPA0 steht.

Los gehts im Bereich Für Anfänger.

Für Anfänger

Als erstes muss man den ENC28J60 mit Gnublin verbinden.

Zu Beginn muss man natürlich wieder den passenden Treiber laden.

Hinweis: Alle SPI Treiber wie CAN, ENC28J60, etc. müssen zuvor entladen sein! (z.B. modprobe -r enc28j60 oder modprobe -r spidev)

modprobe enc28j60

Als Ausgabe erscheint:

enc28j60 spi0.0: enc28j60 Ethernet driver 1.01 loaded net eth0: enc28j60 driver registered

Dann kann man eine IP-Adresse manuell vergeben

ifconfig eth0 up

Als Ausgabe erhält man:

net eth0: link down net eth0: multicast mode net eth0: multicast mode ADDRCONF(NETDEV_UP): eth0: link is not ready net eth0: multicast mode root@gnublin:~# net eth0: link up - Half duplex ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready net eth0: multicast mode

Bzw. kann man sich per DHCP eine IP-Adresse geben lassen:

dhclient eth0

Ist man mit einer IP-Adresse versorgt kann man seinen Router an pingen (Eigene Router IP-Adresse ersetzen):

ping 192.168.1.1

Als Ausgabe erhält man wieder:

PING 192.168.1.1 (192.168.1.1): 56 data bytes 64 bytes from 192.168.1.1: seq=0 ttl=64 time=19.572 ms 64 bytes from 192.168.1.1: seq=1 ttl=64 time=7.373 ms 64 bytes from 192.168.1.1: seq=2 ttl=64 time=7.395 ms 64 bytes from 192.168.1.1: seq=3 ttl=64 time=7.306 ms --- 192.168.1.1 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 7.306/10.411/19.572 ms

Sobald man einen Ping zum host erfolgreich durchgeführt hat, kann man davon ausgehen der ENC28J60 erfolgreich angeschlossen und initalisiert wurde.

Nameserver manuell einrichten

In der Datei /etc/resolv.conf muss man einen Eintrag eingeben

nameserver 8.8.8.8

Die IP-Adresse 8.8.8.8 ist der DNS-Server von Google der wohl immer geht :-).

Standard Route manuell setzten um in das Internet zu kommen

Um alle Netzwerkpakete die für das Internet sind in das Internet zu routen setzt man eine Standardroute:

route add default gw 192.168.1.1

bzw. gibt man wieder die richtige IP-Adresse an.


Für Fortgeschrittene

ACHTUNG Dieser Abschnitt bezieht sich auf einen Kernel vor 11.2012 In jedem neueren Kernel wurde alles bereits ergänzt und optimiert.



Vorbereitungen

Zum Anschließen des Adapters sind nur 7 Leitungen nötig. Die folgende Zeichnung erläutert dies mitsamt den Pinbezeichnungen.

Schaltung draw2.png

Ist man mit dem Aufbau von Hardware nicht vertraut, so kann man sich auch das [ fertige Modul ] aus dem Shop zulegen. Dies wird einfach über ein 14-Pol Flachbandkabel mit GNUBLIN verbunden.


Für alle die noch nie etwas am Kernel modifiziert haben wäre dies der perfekte Anfang. Da der anzuschließende Adapter einen Interrupt erzeugt, auf den das Board reagieren soll, und diese Funktion im normalen LPC3131 Kernel nicht vorhanden ist, muss man ein bisschen am Kernel "rumbasteln". Der Folgende Abschnitt beschreibt SCHRITT für SCHRITT wie man diesen Interrupt im Kernel initialisiert!

Da noch ein Chipselect Pin benötigt wird und das Löten bei der normalen GNUBLIN Version sehr riskant ist(da der Testpunkt sehr klein ist), wäre es momentan besser die Extended Version zu benutzen, da hier alle Pins nach außen geführt sind. Jedoch wurden auch für die normale GNUBLIN Version kleine Testpunkte angelegt wie man im folgendem Bild sehen kann.

250px‎



Modifikationen am Kernel

Wie man auf der Zeichnung sehen konnte, besitzt der SPI Chip eine Interrupt Leitung (5 - INT). Der Interrupt wird verwendet um dem GNUBLIN Board zu sagen, dass nun Daten per Ethernet eingetroffen und zum Abhohlen bereit sind. Der Linux Kernel von Gnublin besitzt jedoch nur Interrupt Resourcen für die wichtigsten Dinge (z.B. USB, MMC und serial Interrupts). Somit wird standardmäßig kein Interrupt am Gnublin ausgelöst. Rein theoretisch kann eine Interrupt Resource für jeden PIN vom GNUBLIN eingerichtet werden. In meinem Beispiel wird der GPIO11 PIN verwendet.

Event Router

Der LPC3131 besitzt einen Interrupt Controller und einen Event Router (etwas anders als bei vielen Architekturen, bei denen nur ein Interrupt Controller zu finden ist). Die meiste Peripherie (außer Timer, I2C, DMA, MCI und andere) geht direkt in den Event Router hinein (Events) und dieser generiert dann auf einem seiner vier Ausgänge ein Signal für den Interrupt Controller. Der Event Router ist sozusagen dem Interrupt Controller vorgeschaltet, sodass dieser weniger (nicht ganz) mit dem Verarbeiten der Prioritäten beschäftigt ist.

Interrupt im Kernel initialisieren

Hier müssen nur 4 änderungen vorgenommen werden, um dem Kernel zu sagen, dass es hier nun einen Interrupt Pin gibt.

Als erstes muss man in dem folgenden Abschnitt (in der Datei arch/arm/mach-lpc313x/include/mach/irqs.h) folgende Zeile ergänzen:

.
.
.
#define IRQ_WDT        30  /* Watchdog interrupt */
#define IRQ_VBUS_EN    31  /* VBUS power enable  */
#define IRQ_VBUS_OVRC  32  /* Detect VBUS over current - Host mode */
#define IRQ_USB_ID     33  /* Detect ID pin change - OTG */
#define IRQ_PIN11      34  				     <--------DIESE ZEILE ERGÄNZEN--------|
.
.
.

Dann folgendes Makro ergänzen:

.
.
.
#define _INTERNAL_IRQ_EVENT_MAP	\
	{IRQ_WDT, EVT_wdog_m0, EVT_RISING_EDGE}, \
	{IRQ_VBUS_EN, EVT_usb_otg_vbus_pwr_en, EVT_FALLING_EDGE}, \
	{IRQ_VBUS_OVRC, EVT_USB_VBUS, EVT_FALLING_EDGE}, \
	{IRQ_USB_ID, EVT_USB_ID, EVT_ACTIVE_LOW}, \
	{IRQ_PIN11,EVT_GPIO11,EVT_FALLING_EDGE}, \		<--------DIESE ZEILE ERGÄNZEN--------|
.
.
.

Als nächstes wird im folgendem Abschnitt noch eine Ziffer geändert:

.
.
.
#else
#define CHIP_IRQ_EVENT_MAP   _INTERNAL_IRQ_EVENT_MAP
#define NR_IRQ_CHIP_EVT	     5    			 <--------DIESE ZEILE ÄNDERN--------|      
#endif
.
.
.

Nach diesem Schritt muss man in der Datei arch/arm/mach-lpc313x/ea313x.c folgende Struktur

struct spi_board_info info =
	{
		.modalias = "spidev",
		.max_speed_hz = 1000000,
		.bus_num = 0,
		.chip_select = 0,
	};

zu dieser Struktur abändern


struct spi_board_info info =
	{
		.modalias = "enc28j60",
		.max_speed_hz = 25000000,
		.bus_num = 0,
		.irq = IRQ_PIN11,
		.chip_select = 0,
	};

Diese Struktur ist wichtig damit der Treiber des ENC28J60 über die Hardware, die er ansteuern muss, informiert wird. Der modalias dient als information um vom Treiber gefunden zu werden. Ich arbeite gerade an einer Methode, diese ganzen Konfigurationen später vom "User space" ausführen zu können.

Kernel Modul einbinden

Natürlich ist es auch wichtig, zu guter letzt, den Treiber des ENC28J60 zu kompilieren.

make menuconfig

Dann unter device drivers --> network device support --> ethernet (10 or 100mbit) --> ENC28J60 support den Treiber auswählen.

make modules && make modules_install INSTALL_MOD_PATH=/[gewünschten pfad angeben]/

Wie man die Module auf das Root Filesystem kopiert werden können ist hier erklärt Kernel kompilieren + Module installieren.

GNUBLIN Booten

Nachdem alle Konfigurationen am Kernel durchgeführt und der Adapter angeschlossen worden ist, kann man Linux booten und folgendes durchführen:

root@gnublin:~# modprobe enc28j60 enc28j60 spi0.0: enc28j60 Ethernet driver 1.01 loaded net eth0: enc28j60 driver registered root@gnublin:~# ifconfig eth0 192.168.1.2 net eth0: link down net eth0: multicast mode net eth0: multicast mode ADDRCONF(NETDEV_UP): eth0: link is not ready net eth0: multicast mode root@gnublin:~# net eth0: link up - Half duplex ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready net eth0: multicast mode root@gnublin:~# ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1): 56 data bytes 64 bytes from 192.168.1.1: seq=0 ttl=64 time=19.572 ms 64 bytes from 192.168.1.1: seq=1 ttl=64 time=7.373 ms 64 bytes from 192.168.1.1: seq=2 ttl=64 time=7.395 ms 64 bytes from 192.168.1.1: seq=3 ttl=64 time=7.306 ms --- 192.168.1.1 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 7.306/10.411/19.572 ms

Sobald man einen Ping zum host erfolgreich durchgeführt hat, kann man davon ausgehen der ENC28J60 erfolgreich angeschlossen und initalisiert wurde.

Messung

Messungen der Datenrate ergaben bei SSH ca. 165,8 kB/s.


Fehlerbehandlung

Es kann sein, dass der enc28j60 keine IP vom DHCP Server bekommt. In diesem Fall sollte man zuerst einmal versuchen die IP manuell zu vergeben.

ifconfig eth0 192.168.1.99
ping <Netzwerkadresse eines anderen Computers im Netzwerk>

Bekommt man eine Antwort von dem anderen PC, so könnte der Fehler auch im Zusammenhang mit dem verwendeten HUB/SWITCH auftreten.

Verbindet man den enc28j60 direkt mit einem Router bzw. PC, so konnte bisher noch kein Fehlverhalten festgestellt werden.

In anderen Sprachen