La licence utilisée par le projet LwIP est du même type que la licence BSD, ce qui dans notre cas nous permet de créer un produit propriétaire sans être obligé de redistribuer les sources. Attention, il existe tout de même des clauses à respecter, et j'invite donc le lecteur à en prendre connaissance.
Il faut savoir que LwIP est utilisé par un très grand nombre de projets libres et propriétaires, et que des améliorations sont donc constamment apportées. De plus, elle a été conçue de telle manière qu'elle soit extrêmement portable ce qui la rend idéale pour la réutilisation de projet.
Toutes ces raisons font que nous avons choisi de développer nos applications réseau avec LwIP plutôt qu'avec Xilnet. De plus Xilnet ne possède pas de fonctions TCP "client" ce qui nous conforte dans notre choix.
LwIP possède trois API de programmation :
En ce qui concerne le client, il ne fait rien d'autre que d'envoyer le nom de l'entreprise "SMP". Pour voir facilement le résultat, il suffit de configurer un serveur sur notre ordinateur. Prenons par exemple NetCat :
nc.exe -s 149.199.6.132 -p 1302 -l
Attention à ne pas confondre le serveur et le client dans le code...
Voici les étapes que nous avons suivi pour mettre en oeuvre ce projet :
Dans un premier temps, copiez le répertoire $XILINX_EDK/sw/lib/sw_services/Lwip_v2_00_a/ vers le répertoire $XILINX_EDK/sw/lib/sw_services/Lwip_v2_00_b/ , pour différentier la bibliothèque LwIP modifiée de celle d'origine.
Modifiez le fichier $XILINX_EDK/sw/lib/sw_services/Lwip_v2_00_a/src/Makefile_ppc de la manière suivante :
# NETIFFILES: Files implementing various generic network interface functions. NETIFFILES=$(LWIPDIR)/netif/etharp.c \ $(LWIPDIR)/netif/loopif.c
Ainsi que le fichier $XILINX_EDK/sw/lib/sw_services/Lwip_v0_00_a/src/contrib/ports/v2pro/lwipopts.h :
Support loop interface (127.0.0.1) #define LWIP_HAVE_LOOPIF 1
Pour que l'interface LoopBack fonctionne correctement, nous avons besoin de la fonction sys_timeout qui n'est malheureusement pas définie en mode RAW. Pour remédier à ce problème, il suffit de modifier le fichier $XILINX_EDK/sw/lib/sw_services/Lwip_v2_00_b/src/Lwip/src/netif/loopif.c de la manière suivante :
* * workaround (patch #1779) to try to prevent bug #2595: * When connecting to "localhost" with the loopif interface, * tcp_output doesn't get the opportunity to finnish sending the * segment before tcp_process gets it, resulting in tcp_process * referencing pcb->unacked-> which still is NULL. * * TODO: Is there still a race condition here? Leon //sys_timeout( 1, loopif_input, arg ); loopif_input(arg);
En ce qui concerne ce problème de "race-condition", nous le contournons simplement en utilisant un PCB différent entre le serveur et le client.
Enfin, il ne reste plus qu'à adapter le code pour utiliser l'interface LoopBack à la place de l'interface Xemac. Il faut alors enlever les appels de fonctions relatifs à l'ancienne interface :
//xemacif_setmac(0, (u8_t *)mac); //xemacif_input(netif); //etharp_tmr();
Puis configurer correctement l'interface LoobBack :
//netif = netif_add(netif, &ipaddr, &netmask, &gw, &XEmacIf_ConfigTable[0], xemacif_init, netif = netif_add(netif, &ipaddr, &netmask, &gw, NULL, loopif_init, ip_input);
Dans l'exemple fourni, l'interface Xemac n'est pas utilisable en même temps que l'interface LoopBack, mais ce n'est uniquement pour simplifier la compréhension du code ! En effet, il est tout à fait envisageable de les utiliser en même temps à partir du moment où elles sont configurer avec des adresses IP/Mask différentes !
Il est à noter que si l'on teste cette exemple du LoopBack, il va s'arrêter automatiquement au bout d'un certain temps. En effet la file d'envoie est limiter en taille...
# NETIFFILES: Files implementing various generic network interface functions. NETIFFILES=$(LWIPDIR)/netif/loopif.c # ARCHFILES: Archiecture specific files. ARCHFILES=$(ARCHDIR)/lib_arch.c \ $(ARCHDIR)/perf.c
journal de XPS :
LibGen Done. powerpc-eabi-gcc (...) powerpc-eabi-size LwIP/executable.elf text data bss dec hex filename 99476 1252 826564 927292 e263c LwIP/executable.elf Done.
fichier Makefile:
program: cd ../..; powerpc-eabi-gcc (...)
Ensuite, il suffit de lancer un terminal (bouton Xygwin Shell), d'aller dans le répertoire où ce trouvent les sources, et de lancer la commande "make".
ERROR:MDT - xget_handle 39406316 ipinst Ethernet_MAC peripheral : xget_handle: Ip instance Ethernet_MAC not found ERROR:MDT - ERROR FROM TCL:- Lwip () - while executing "xget_handle $processor_handle "ipinst" $ipinst_name "peripheral"" (procedure "xget_sw_ipinst_handle_from_processor" line 2) invoked from within "xget_sw_ipinst_handle_from_processor $sw_proc_handle $inst" (procedure "::sw_Lwip_v2_00_a::Lwip_drc" line 21) invoked from within "::sw_Lwip_v2_00_a::Lwip_drc 39441932" ERROR:MDT - Error while running DRC for processor ppc405_1... make: *** [ppc405_1/lib/libxil.a] Error 2 Done.
La solution consiste à commenter les informations concernant le processeur non utilisé :
# BEGIN OS # PARAMETER OS_NAME = standalone # PARAMETER OS_VER = 1.00.a # PARAMETER PROC_INSTANCE = ppc405_1 # END
Une solution consiste à forcer la non-optimisation. Cela s'effectue en plaçant l'option "-O0" dans la boite de dialogue "Software Platform Setting" à l'onglet "Processor, Driver Parameters, Interrupt Handlers" dans le champ "EXTRA_COMPILER_FLAGS".
Check if the queue length exceeds the configured maximum queue * length. If so, we return an error. queuelen = pcb->snd_queuelen; if (queuelen >= TCP_SND_QUEUELEN) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %u (max %u)\n", queuelen, TCP_SND_QUEUELEN)); goto memerr; }