Hi, hat jemand eine Ahnung warum beim laden dieses Moduls(mit insmod) sofort nach der probe-Funktion die open-Funktion aufgerufen wird? Es ist ja sonst eig. üblich dass die open-Funktion per Konsole mit "ifconfig eth1 up" aufgerufen wird! Danke für jeden Hinweis! Gruß Markus
Läuft irgendein network manager, der automatisch alle verfügbaren Netzwerk interfaces konfigurieren will?
Außerdem hast du noch ein memory leak wenn register_netdev() fehlschlägt. Dein
1 | #define DRV_NAME my
|
sollte vermutlich ein
1 | #define DRV_NAME "my"
|
sein. Allerdings wird das ganze define nirgends verwendet. Ein pointer wie dein 'static struct my_net *my' ist unüblich, da du dir den Pointer jederzeit mit netdev_priv() holen kannst. Dann kannst du später u.U. auch mehrere NICs gleichzeitig betreiben. Und anstatt den ganzen 'my' wäre vielleicht ein anderes Prefix treffender.
>Läuft irgendein network manager, der automatisch alle verfügbaren >Netzwerk interfaces konfigurieren will? Nein. Denn bei einem Treiber ohne SPI Anbindung wie in(Seite 272): ftp://ftp.tm.informatik.uni-frankfurt.de/pub/papers/ir/kernelbook.pdf ..kann ich das Interfaces bequem per Konsole (de)aktivieren, dort ist es aber kein Ethernettreiber, und die netdev_ops werden anders gehandhabt, nicht mit einem struct sondern mit einer setup-Methode, die dann alloc_netdev übergeben wird. Wo liegen hier die Unterschiede/Vorteile? Was ist zu bevorzugen? Ich habe mich bis jetzt an dem enc28j60 Treiber orientiert. thomil danke für die Hinweise! Bin für Literaturvorschlage speziell für Netzwerktreiber sehr dankbar, ich hab bisher leider nur allgemeine Treiberbücher gefunden.
Suche mal nach LDD3e.pdf Das ist "Linux Device Drivers" von einigen Kernelentwicklern. Einige Anregungen : Zeile 19
1 | static struct my_net *my; |
das ist falsch. Was machst du wenn noch ein Device dazu kommt auch ist das verwirrend mit der Funktion static int __devinit my_probe(struct spi_device *spi) richtig ist es so
1 | static int __devinit my_probe(struct spi_device *spi) |
2 | {
|
3 | struct net_device *dev; |
4 | struct my_net *priv; |
5 | |
6 | int ret; |
7 | |
8 | dev = alloc_etherdev(sizeof(struct my_net)); |
9 | if(!dev){ |
10 | printk("Unable to alloc new ethernet\n"); |
11 | }
|
12 | else{ |
13 | printk("Ethernet allocated!\n"); |
14 | }
|
15 | |
16 | pric = netdev_priv(dev); |
Du willst ja in zu deinem privaten (priv) Treiberbereich referenzieren. Schau mal den Code in drivers/net/ethernet/microchip/enc28j60.c an. Da hast du einen Netzwerktreiber mit SPI Gefunden mit git grep -w spi drivers/net in den Kernel Sourcen
>richtig ist es so
Genauso habe ich es implementiert. Es funktioniert ja, nur wird
open-Funktion direkt beim laden aufgerufen, und die close-Funktion beim
entladen. Ich will die Funktionen aber manuell mit ifconfig eth1 up
aufrufen.
Der enc28j60 ist bei mir leiider nicht verfügbar, den habe ich beim
Kernelkomp. in der config nicht aktiviert. Kann der enc29j60 mit
ifconfig eth1 up aktiviert werden??
Hast du NetworkManager am laufen? Wenn Debian oder ähnliches trag mal in /etc/network/interfaces eth1 aus der auto Liste aus und sag iface eth1 inet manual
Markus R. schrieb: >>richtig ist es so > > Genauso habe ich es implementiert. Es funktioniert ja, nur wird > open-Funktion direkt beim laden aufgerufen, und die close-Funktion beim > entladen. Ich will die Funktionen aber manuell mit ifconfig eth1 up > aufrufen. Seltsam ... > Der enc28j60 ist bei mir leiider nicht verfügbar, den habe ich beim > Kernelkomp. in der config nicht aktiviert. Kann der enc29j60 mit > ifconfig eth1 up aktiviert werden?? Nein. Du musst den Treiber schon im Kernel haben. Wenn du einen Kernel mit Modulunterstüzung hast kannst du diesen ja laden.
Wenn nach dem laden ifconfig eth1 down aufrufe sehe folgenden Output auf der Konsole: [ 114.163546] tps1_init called! [ 114.167567] Ethernet allocated! [ 114.177484] tps1 driver registered [ 114.271174] open called! [ 149.145411] close called! [ 149.214344] open called! Es wird direkt nach dem Aufruf von close wieder open aufgerufen! ??? Anbei nochmal den aktuellen C Code. In /etc/network/interface steht für eth1 folgendes: iface eth1 inet manual
Thomas Miletich schrieb: >Ein pointer wie dein 'static struct my_net *my' ist unüblich, da du dir >den Pointer jederzeit mit netdev_priv() holen kannst. Dann kannst du >später u.U. auch mehrere NICs gleichzeitig betreiben. Gibt es sonst noch Vorzüge es mit netdev_priv() zu implementieren?
Markus R. schrieb: > Thomas Miletich schrieb: >>Ein pointer wie dein 'static struct my_net *my' ist unüblich, da du dir >>den Pointer jederzeit mit netdev_priv() holen kannst. Dann kannst du >>später u.U. auch mehrere NICs gleichzeitig betreiben. > > Gibt es sonst noch Vorzüge es mit netdev_priv() zu implementieren? Es hat sonst noch den Vorteil, dass das jeder andere Treiber in Linux, *BSD, etc so macht. Wenn jemand Anderes also schon mal so einen Treiber gesehen hat, wird er sich fragen "Nanu, wo kommt den eigentlich der pointer her, ich habe am Anfang der Funktion gar kein netdev_priv() gesehen?". Wenn du aus irgendwelchen Gründen bei deinem static pointer bleiben willst, solltest du sicherheitshalber in probe() sicherstellen, dass probe() nur für 1 device aufgerufen werden kann. Um dies zuverlässig ausschließen zu können ist u.U. ein Mutex nötig, was für mich schon Grund genug wäre, um es mit netdev_priv() zu machen.
Thomas Miletich schrieb: > Wenn du aus irgendwelchen Gründen bei deinem static pointer bleiben > willst, solltest du sicherheitshalber in probe() sicherstellen, dass > probe() nur für 1 device aufgerufen werden kann. Um dies zuverlässig > ausschließen zu können ist u.U. ein Mutex nötig, was für mich schon > Grund genug wäre, um es mit netdev_priv() zu machen. Flascher Ansatz. Wenn der static pointer benutzt wird, würde ich ihn gegen NULL prüfen und dabei ggf. ein Mutex benutzen. Beides ist aber FALSCH Wenn irgendwann die probes parallel ablaufen brauchst du einen spinlock. Also wenn irgendwelche Pointer, Zähler usw. für dein Device verwenden willst kommt es in den privaten Teil.
Hans Ulli Kroll schrieb: > Thomas Miletich schrieb: > >> Wenn du aus irgendwelchen Gründen bei deinem static pointer bleiben >> willst, solltest du sicherheitshalber in probe() sicherstellen, dass >> probe() nur für 1 device aufgerufen werden kann. Um dies zuverlässig >> ausschließen zu können ist u.U. ein Mutex nötig, was für mich schon >> Grund genug wäre, um es mit netdev_priv() zu machen. > > Flascher Ansatz. > Wenn der static pointer benutzt wird, würde ich ihn gegen NULL prüfen > und dabei ggf. ein Mutex benutzen. Genau so habe ich das gemeint. > Beides ist aber *FALSCH* > Wenn irgendwann die probes parallel ablaufen brauchst du einen spinlock. > > Also wenn irgendwelche Pointer, Zähler usw. für dein Device verwenden > willst kommt es in den privaten Teil. War von mir ebenfalls so gemeint. Alle Informationen über den Treiber state und die hardware kommen in eine Struktur, die im private pointer des struct net_device gespeichert ist. Was mir im Moment nicht ganz klar ist, wo ich nun den spinlock in probe() benötige? Es gibt mehrere devices, für jedes ein struct net_device, mit eigenem private pointer. Somit ist jeder probe() thread unabhängig vom anderen. Vielleicht stehe ich aber gerade nur auf dem Schlauch.
Erstmal danke für die ganzes Infos, bin noch sehr neu auf dem Gebiet. Es handelt sich um einen SPI-Treiber, wobei die SPpins des Boards fest mit dem Netzwerkchip verdrahtet sind, es wird also immer eine Instanz des Treibers erzeugt werden.
Hi, noch ne Frage wieso wird bei dem obigen Netzwerkmodul nicht die send-Methode durch das NetzwerkSubsystem aufgerufen?? Muss man über ifconfig irgendetwas aktivieren oder in etc/network/interfaces irgendwas einstellen ?? eth1 ist auf jeden Fall aktiv!
Aktiv sagt nur aus das die Schnittstelle genutzt werden kann. Mit ping kannst du ja ein Paket senden.
Auch mit ping wird eth1 nicht angesprochen, standart Schnittstelle ist eth0, ich kann sie aber nicht deaktivieren weil über sie (ssh) das RaspberryPi steuere..
Hmmm. Was ich erstnal machen würde ist, deinen Treiber zu erweitern. Folgende Funktionen fehlen da noch: .ndo_change_mtu .ndo_set_mac_address Was mich aber immer noch stört warum machst du die Arbeit und schreibst einen neuen Treiber. Wie ich mal sagte in drivers/net/ethernet/microchip/enc28j60.c ist ein entsprechender Treiber, der muss halt nur auf deine Platform angepasst werden. Und zu dem GPIO Problem was ich in einem anderen Thread von dir gefunden habe, schau mal nach pinctrl (Pincontrol). So wie ich es gelesen habe ist es die "neue" Schnittstelle um GPIOs anzubinden.
Gib dem Interface ein andere IP Subnetz und Pinge eine IP aus diesem Subnetz an, dann gehts über dein zweites IF.
elektroman schrieb: >Was ich erstnal machen würde ist, deinen Treiber zu erweitern. >Folgende Funktionen fehlen da noch: >.ndo_change_mtu >.ndo_set_mac_address Ich habe ihn jetzt mit random_ether_addr(dev->dev_addr); erweitert, heißt jetzt hat er eine zuf. macadresse und eine MTU=1500. >Was mich aber immer noch stört warum machst du die Arbeit und >schreibst einen neuen Treiber. >Wie ich mal sagte in >drivers/net/ethernet/microchip/enc28j60.c >ist ein entsprechender Treiber, der muss halt nur auf deine Platform >angepasst werden. Ich habe vor einen Treiber zu bauen(BA Arbeit) für einen Netzwerkchip der schon eine fertige API zu Verfügung stellt. Das heißt die SPI-Kommunikation ist schon so gut wie fertig. Jetzt muss ich nur noch Ethernetframes vom Kernel entgegennehmen können und mit einer Methode der API (Send_EthernetFrame(...)) versenden. Die Eigenschaften der NICs wie zB die Mac adresse werden über die API gesetzt, dh. mein Treiber unterscheidet bis auf die Anbindung an das Netzwerksubsystem komplett von dem enc28j60-Treiber. >Und zu dem GPIO Problem was ich in einem anderen Thread von dir gefunden >habe, schau mal nach pinctrl (Pincontrol). >So wie ich es gelesen habe ist es die "neue" Schnittstelle um GPIOs >anzubinden. Da die GPIOs einwandfrei funktionieren denk ich mal das die printk-Ausgabe falsch programmiert wurde, und das fälschlicher Weise "Invalid GPIO" ausgegeben wird. >Gib dem Interface ein andere IP Subnetz und Pinge eine IP aus diesem >Subnetz an, dann gehts über dein zweites IF. eth1 ist von außen noch nicht erreichbar. Ich hab es einmal hinbekommen dass die send-Funktion aufgerufen wurde, im jetzt funkioniert es iwie nicht nicht(musste Raspbian neu installieren weil sich das Linuxdateisystem zerschießt wenn man zu oft den Strom wegnimmt, war leider nötig..).
kruemeltee schrieb: >>Gib dem Interface ein andere IP Subnetz und Pinge eine IP aus diesem >>Subnetz an, dann gehts über dein zweites IF. Habs erst falsch verstanden, bin jetz aber von selbst drauf gekommen. So funktionierts!! Danke!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.