LWIP双网口,LPC2294,移植总结,cs8900


  • 空间

 我公司产品是双网口,原来的程序是自己写的TCP/IP协议栈,因为只是简单实现了ARP和TCP、UDP的最简单情况,所以有时候在公网上会遇到问题。

后来在单网口的产品中移植了LWIP,轻量级TCP/IP协议栈,觉得一定程度上解决了问题,所以双网卡的产品也要用LWIP这个协议栈来实现。这个工作就落到了我的头上。

单网卡的移植我不赘述,只描述从单网卡向双网卡移植过程中遇到的问题以及解决方法。

首先,我看了下单网卡移植中所作的改动。

硬件启动时初始化硬件,调用my_lwip_init(),这个函数中创建任务,添加网卡配置。
low_level_init()函数中设置本网卡初始化时MAC地址的设置。
low_level_output()函数处理输出信息。
low_level_input()函数处理输入信息。
ethernetif_input()函数是区分接受到的数据包怎么处理。
由此,可以知道我所需要做的主要改动就是针对这几个函数,及其相关的函数。

多创建一个netif块,硬件初始化时在mylwip_init()函数中多添加一个netif_add,并调用netif_set_up().
在low_level_init()中,区分两个网卡的MAC地址并且填充到netif块中。[由此代码可见,硬件mac地址修改后程序必须重新设置netif链表才能正确执行。]
在low_level_output()中,判断返回的数据是要发送到哪个网卡,将数据拷贝到网卡发送缓冲区,然后发送。
在low_level_input()中,判断是哪个网卡接受到了数据,并将网卡接受缓冲区中的数据拷贝到netif块的payload数据处。
在进行完这几步骤以后,ping程序已经可以通了,但是出现了一些奇怪的现象,同一个网口竟然能通讯两个Ip地址的内容[在一个网口ping两个网卡都能通],所以又在ethernetif_input()函数中判断加入目标地址是本网卡再进入TCP/IP的处理。到这时也解决了。

然后出现了一个让人啼笑皆非的问题,ping net1 OK,ping net 2 OK,TCP net1 Error,TCP net2 OK。而且只有一个网卡时,net1和net2都正常。所以怀疑是路由这块出了问题,查看lwip的文档才发现,ip_route()函数的规则是目标地址处于本网卡的网段则认为本网卡的数据,否则走默认路由配置。由于我们的模块是为了做数据热备或者多通讯口才设置的双网卡,所以两个网卡都是一个网段的配置,这时ip_route()函数找到默认的一个路由表中的第一个路由就直接返回了。无奈之下,我写了ip_route2(),以比较源地址的方式来确定是由哪个网卡来发送数据。

到此为止,测试OK,开心之极,赶紧记录下来

我的处理更为简单,也更为有效,如果有两个网卡芯片,无论是一样的芯片,还是不一样的芯片,直接建两个驱动文件,ethernetif.c,添加到工程中去,当然两个文件名是不能一样的,另外文件里面的函数名如果是外部函数的话,也应该起不同的函数名,但是我的经验是大部分都可以是一样的,因为它们都是静态函数(stctic),还有一些static静态变量,这些变量名也不用修改,估计只需要修改的是ethernetif_init(),ethernetif_input(),了,很简单吧,
为什么会想这样做呢?两个原因,既然是两个网卡,那么肯定要建立两套缓冲区,两套地址空间,相当于把给每一个网卡分配了两个不同的运行空间。如果硬要把它们放在一起,那需要解决参数传递的问题,通过参数传递来判断正在操作的是哪一个网卡,我是用中断来接收网卡收到的数据的,两个网卡当然也是两个中断服务函数了,如果硬要用一个中断处理函数,还是上面的问题,还要判断是哪个网卡产生的中断。不是不能处理,也能处理,就是太麻烦,干脆做两套完全独立的系统,两个文件,更有效些。
另一个原因,如果是电脑的话,别说加两个网卡就是三个四个,问题也不大,它是怎么实现的呢?估计给给每一个网卡设置了一个线程,这个线程专门两处理与这个网卡相关的数据接收与发送。这样做要做的就是要处理好函数的重入,我这嵌入式程序本来就是没有多头考虑过函数重入的问题,更何况我这还是裸跑的,无系统。如果这样的话,我宁愿做两个功能完全一样的文件来实现两上同样的网卡的驱动。

你可能感兴趣的:(LWIP双网口,LPC2294,移植总结,cs8900)