一、摘要
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 定制软核
定制软核的详细步骤不再赘述,以上为定制的软核。
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)编译、综合,生成配置文件。
最后原理图如下图所示。
需要注意的问题:
(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 通。
如果事先将网页数据烧录到 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 通。
再输入 telnet 命令:telnet 192.168.2.1,则得到如下图所示:
在 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 运行结果
未设定静态 IP 时,需等待 2 分钟(DHCP 超时可在 simple_socket_server.h 中设定),NIOS II 运行结果
注:可以在 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