DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

一、摘要

Altera 软件 NIOS II 低版本(7.2 版本以下,本例程中使用的是 6.0 版本)中实现 TCP/IP 所用的协议栈为 LWIP,常用的例程有 2 个,web_server 和 simple_socket_server,这篇文章将叙述这 2 个例程实现的过程。这两个例程参考了友晶科技的 DE2_WEB 例程。

二、实验平台

软件平台:Quartus II 6.0 + Nios II 6.0

硬件平台:DIY_DE2

三、实验内容 1——>实现 web_server

1、采用 SOPC 定制软核

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

定制软核的详细步骤不再赘述,以上为定制的软核。

cpu_0 需要设置的地方:

Reset Vector:cfi_flash_0、

Exception Vector:sdram_0

必须要添加 timer_0,供 uC/OS 系统所使用

第二个标签页:Data Master 处,Data Cache 设置为 None

之后分配地址,分配中断号,生成即可。

2、硬件电路

采用原理图的形式,创建顶层文件。

(1)添加生成的软核;

(2)调用锁相环 IP 核;

(3)连线、分配管脚;

(4)编译、综合,生成配置文件。

最后原理图如下图所示。

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

需要注意的问题:

(1)软核程序在 SDRAM 里面运行,为了使软核的速度提升,因此 SDRAM 的频率和 cpu 的频率都设置为 100M。cpu 时钟 clk_100 和 sdram 操作时钟 clk_50 都接 PLL 的 c0,100M,无相位偏移;SDRAM 的时钟管脚 SDRAM_CLK 连接 PLL 的 c1,100M,偏移-3ns。

(2)DM9000A 的时钟管脚接 50M,直接连接晶振的输入端即可。

(3)复位管脚接高电平 VCC 即可。

(4)CFI_FLASH 的复位管脚 FLASH_RESET 接高电平 VCC 即可。

3、软件方面

(1)打开 NIOS II,新建工程,调用 web_server 工程模板。

(2)添加 DM9000A 驱动:dm9000a.h 和 dm9000a.c,将上述两个文件复制到上步建立的工程文件夹下。

(3)打开文件 network_utilities.c,赋予静态 IP。

(4)编译、下载、运行,之前要先将.sof 的配置文件下载到 FPGA 内。在 DOS 下输入 ping 命令:ping 192.168.2.1,如下图所示,则可以正常 ping 通。

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

如果事先将网页数据烧录到 FLASH 中,在 PC 打开浏览器,则可以在浏览器上看到 FLASH 中的网页内容。这个实验之前在 DE2 板子上做过,这里就不再重复了。

4、工程文件解读

(1)http.c、http.h:网页相关文件;

(2)Dm9000a.h、dm9000a.c:DM9000A 的驱动;

(3)User.h:任务调度优先级、缺省 IP 设置等等;

(4)network_utilities.c:设置 IP,设置 MAC;

(5)Web_server:主函数所在文件。

四、实验内容 2——>实现 simple_socket_server

1、建立工程及文件解读

在上一步的基础上,直接在 NIOS II 中新建工程,调用 simple_socket_server 工程模板。添加 DM9000A 的驱动,将 dm9000a.h、dm9000a.c 添加到建立的工程文件夹下。工程文件主要包括以下几个:

(1)alt_error_handler.h、alt_error_handler.c:错误类型句柄文件;

(2)dm9000a.h、dm9000a.c:DM9000A 的驱动;

(3)network_utilities.c:设置 IP,设置 MAC;

(4)simple_socket_server.h、simple_socket_server.c:工程的主体程序,包括任务调度优先级、缺省 IP 设置、套接字、各种任务调度等等工作;

(5)led.c:LED、七段数码管显示程序;

(6)lwip_init.c:程序主函数。

2、需要修改的地方

依照 web_server 例程,对 simple_socket_server 例程进行部分修改:

(1)simple_socket_server.h 文件,

添加分配 DHCP 优先级:#define DHCP_TMR_PRIO 8

添加语句:void die_with_error(char err_msg[]);

添加 DHCP 超时任务函数:void dhcp_timeout_task();

添加语句:#define DIE_WITH_ERROR_BUFFER 256

(2)lwip_init.c 文件

添加 DM9000A 驱动:#include “dm9000.h”

添加 DM9000A 接口语句:ALTERA_AVALON_DM9K_INSTANCE(DM9000A, dm9k);

添加语句:OS_EVENT *attained_ip_address_sem;

在 static void init_done_func(void *arg)添加以下语句:

//++sunev
  ALTERA_AVALON_DM9K_INIT(dm9k);
  /*
   * At this point lwIP has been initialized, but the Ethernet interface has
   * not; the lwip_devices_init() call does so, adding in MicroC-OS/II
   * threads for low-level Ethernet MAC interface and TCP protocol timer.
   */
//++sunev  
   attained_ip_address_sem = OSSemCreate(1);
   
   if (!lwip_devices_init(LWIP_RX_ETHER_TASK_PRIORITY))
   {
      alt_lwIPErrorHandler(EXPANDED_DIAGNOSIS_CODE,
"[init_done_func] Fatal: lwip_devices_init failed, perhaps ethernet interface.");
   }
//++sunev
#if LWIP_DHCP == 1
  if(!(IORD(0, 0) & (1<<17))) sys_thread_new(dhcp_timeout_task, NULL, DHCP_TMR_PRIO);
  /*
   * If DHCP is enabled, activate a thread for the 120-second long time period
   * that will set a static IP address if acquisistion via DHCP times out.
   */
//--sunev
/*   if (!sys_thread_new(NETUTILSDHCPTimeoutTask, NULL,
                       NETUTILS_DHCP_TIMEOUT_TASK_PRIORITY))
   {
      alt_lwIPErrorHandler(EXPANDED_DIAGNOSIS_CODE,
                 "[init_done_func] Fatal: Can't add NETUTILSDHCPTimeoutTask!");
   }*/

(3)将 web_server 中的 network_utilities.c 文件直接替换掉 simple_socket_server 中的 network_utilities.c 文件。

3、编译、下载、运行

之前要先将.sof 的配置文件下载到 FPGA 内。在 DOS 下输入 ping 命令:ping 192.168.2.1,如下图所示,则可以正常 ping 通。

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

再输入 telnet 命令:telnet 192.168.2.1,则得到如下图所示:

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

在 PC 键盘输入 0-7 数字,则 DIY_DE2 上的 8 个 LED 就会相应的亮或者灭。至此,说明,telnet 正常。

五、实验结果分析

这个实验结果分析,对上述 2 个实验内容均为一致。

解读上述程序,在 network_utilities.c 文件中,可以得知,设置 IP 的 3 种方法:第一种,程序设定静态 IP;第二种,DHCP 获得动态 IP;第三种,缺省 IP。其优先级及顺序如下:

(1)当设定静态 IP 之后,DHCP 能获得一个动态 IP,但以设置的静态 IP 为有效 IP。

(2)当未设定静态 IP 之后,DHCP 则不能获得一个动态 IP,但过了设定的 DHCP 超时时间后(以上 2 个例程中的超时时间为 120s),使用的是缺省 IP,缺省 IP 为有效 IP。

设定静态 IP 时,NIOS II 运行结果

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

未设定静态 IP 时,需等待 2 分钟(DHCP 超时可在 simple_socket_server.h 中设定),NIOS II 运行结果

DIY_DE2之DM9000A网卡调试系列例程(三)——基于LWIP协议栈的TCP/IP实现

注:可以在 network_utilities.c 文件中将

#if LWIP_DHCP == 1
*use_dhcp = 1;

中的

*use_dhcp = 1;

设置为

*use_dhcp = 0;

来取消 DHCP 功能。

六、实验的几点说明

1、IP 值设置:

因为是采用局域网通信,所以要将 PC 和 DIY_DE2 的 IP 的前 3 位设置为相同,最后一位不同。

2、MAC 值设置:

直接采用程序设定即可,或者是将 MAC 值存储在 FLASH 中,上电读取即可。本例采用的是前一种方法。

3、端口设定:

telnet 的时候,需要侦听端口,当侦听的端口号和 DIY_DE2 中设定的相同的时候,才能正常通信。方法:telnet 192.168.2.1 时,会有一个专用的端口 23,将 DIY_DE2 中设定的端口号改为 23 即可(在文件 simple_socket_server.h 中#define SSS_PORT 23)。

4、关于这个例程在 NIOS II 方面:

关于 Software Components 这个按钮下 Lightweight TCP/IP Stack 下选项为灰色的原因,其实这个不必理他。这一点也得到了友晶科技的证实。如果用 LAN91c111 这个网卡,上述位置的选项则可以正常使用,这说明 NIOS II 软件只认 SOPC 中原装的器件。

扫码关注尚为网微信公众号

尚为网微信公众号
每天学习电路设计嵌入式系统的专业知识,关注一波,没准就用上了。

原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/22.html

(1)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2012年3月12日 21:46
下一篇 2012年3月14日 21:42

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注