转载 基于NicheStack协议栈的TCP/IP实现
一、摘要
Altera软件NIOS II高版本(7.2版本以上,本例程中使用的是9.0版本)中实现TCP/IP所用的协议栈为NicheStack,常用的例程有2个,web_server和simple_socket_server,这篇文章只叙述simple_socket_server例程实现的过程。这里DM9000A的驱动和上篇博文中基于LWIP的驱动不同。
二、实验平台
软件平台:Quartus II 9.0 + Nios II 9.0
硬件平台:DIY_DE2
三、实验内容——>实现simple_socket_server
1、采用SOPC定制软核

定制软核的详细步骤不再赘述,以上为定制的软核。
cpu_0需要设置的地方:
Reset Vector:cfi_flash_0、
Exception Vector:sram_16bit_512k_0
必须要添加sys_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,新建工程,调用simple_socket_server工程模板。
(2)添加DM9000A驱动:dm9000a.h和dm9000a.c,将上述两个文件复制到上步建立的工程文件夹下。
(3)打开network_utilities.c文件,将附录代码覆盖原始代码,这里采用的是使用静态IP的方法(IP的值将在后面给出说明),并且赋给MAC值。
(4)打开iniche_init.c文件,
添加头文件#include"dm9000a.h",
添加DM9000A接口语句DM9000A_INSTANCE(DM9000A_0, dm9000a_0);
在函数void SSSInitialTask(void *task_data)中,
添加DM9000A的初始化语句DM9000A_INIT(DM9000A_0, dm9000a_0);
(5)编译、下载、运行,之前要先将.sof的配置文件下载到FPGA内。在DOS下输入ping命令:ping 192.168.2.1,如下图所示,则可以正常ping通。

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

在PC键盘输入0-7数字,则DIY_DE2上的8个LED就会相应的亮或者灭。至此,说明,telnet正常。
4、工程文件解读
(1)alt_error_handler.h、alt_error_handler.c:错误类型句柄文件;
(2)dm9000a_regs.h、dm9000a.h、dm9000a.c:DM9000A的驱动;
(3)network_utilities.h、network_utilities.c:设置IP,设置MAC;
(4)simple_socket_server.h、simple_socket_server.c:工程的主体程序,包括任务调度优先级、缺省IP设置、套接字、各种任务调度等等工作;
(5)led.c:LED、七段数码管显示程序;
(6)iniche_init.c:程序主函数。
四、实验结果分析
NIOS II运行结果:

稍过2分钟后,得到如下结果:

实验现象,程序一开始运行,先赋给静态IP,这时候ping能够跑通,但telnet却不能跑通。稍过2分钟之后(这个默认时间在LWIP协议栈实现的时候可以调整,但在NicheStack协议栈中不能调整,至少在工程文件里是这样),出现上面第二幅结果图的时候,能够ping正常,telnet正常。
分析可得,虽赋予静态IP,但是系统仍是先通过DHCP获取IP,获取超时,使用缺省IP,缺省IP的设置在simple_socket_server.h中。而真正能够ping正常,telnet正常的却是事先赋予的静态IP。
注:取消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中原装的器件。
附录:
network_utilities.c文件

#include <alt_types.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <sys/alt_flash.h>
#include "includes.h"
#include "io.h"
#include "simple_socket_server.h" #include <alt_iniche_dev.h> #include "ipport.h"
#include "tcpport.h"
#include "network_utilities.h" #define IP4_ADDR(ipaddr, a,b,c,d) ipaddr = \
htonl((((alt_u32)(a & 0xff) << 24) | ((alt_u32)(b & 0xff) << 16) | \
((alt_u32)(c & 0xff) << 8) | (alt_u32)(d & 0xff))) /*
* get_mac_addr
*
* Read the MAC address in a board specific way
*
*/
static unsigned char macaddr[6] = { 0x00, 0x07, 0xed, 0xff, 0x06, 0x00 }; int get_mac_addr(NET net, unsigned char mac_addr[6])
{
int rv = -1; /* first 3 bytes are altera's vendor id */
/* last 3 bytes are picked from serial number sticker */
mac_addr[0] = macaddr[0];
mac_addr[1] = macaddr[1];
mac_addr[2] = macaddr[2];
mac_addr[3] = macaddr[3];
mac_addr[4] = macaddr[4];
mac_addr[5] = macaddr[5]; /* return the mac address in the array */
rv = 0; return rv;
} /*
* get_ip_addr()
*
* This routine is called by InterNiche to obtain an IP address for the
* specified network adapter. Like the MAC address, obtaining an IP address is
* very system-dependant and therefore this function is exported for the
* developer to control.
*
* In our system, we are either attempting DHCP auto-negotiation of IP address,
* or we are setting our own static IP, Gateway, and Subnet Mask addresses our
* self. This routine is where that happens.
*/
int get_ip_addr(alt_iniche_dev *p_dev,
ip_addr* ipaddr,
ip_addr* netmask,
ip_addr* gw,
int* use_dhcp)
{ IP4_ADDR(*ipaddr, 192, 168, 2, 1);
IP4_ADDR(*gw, 192, 168, 2, 1);
IP4_ADDR(*netmask, 255, 255, 255, 0); #ifdef DHCP_CLIENT
*use_dhcp = 1;
#else /* not DHCP_CLIENT */
*use_dhcp = 0; printf("Static IP Address is %d.%d.%d.%d\n",
ip4_addr1(*ipaddr),
ip4_addr2(*ipaddr),
ip4_addr3(*ipaddr),
ip4_addr4(*ipaddr));
#endif /* not DHCP_CLIENT */ /* Non-standard API: return 1 for success */
return 1;
}
转载 基于NicheStack协议栈的TCP/IP实现的更多相关文章
- 基于tcpdump实例讲解TCP/IP协议
前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...
- [计算机网络] 互联网协议栈(TCP/IP参考模型)各层的主要功能及相应协议
应用层:提供用户与网络间的接口.----HTTP.FTP.SMTP 运输层:进程到进程间的数据传输.---TCP.UDP 网络层:主机到主机之间的数据传输.---IP.选路协议 数据链路层:相邻结点之 ...
- TCP/IP协议栈概述及各层包头分析
TCP/IP协议栈中各层包头的分析 Protocol列表示的是该数据包最高层对应的协议,Length列表示该包的长度(包括从底层的协议到最高层的协议,其中包头一般是,链路层14字节,IP20字节,TC ...
- UNIX/Linux网络编程基础:图解TCP/IP协议栈
目录 1.主机到网络层协议:以太网协议 2.IP协议 3.网际控制报文协议(ICMP) 4.传输控制协议(TCP) 5.用户数据报文协议(UDP) 6.流控制传输协议(SCTP) 7.地址解析协议(A ...
- TCP/IP协议——TCP/IP协议栈及框架
TCP/IP协议同ISO/OSI模型一样,也可以安排成栈形式.但这个栈不同于ISO/OSI版本,比ISO/OSI栈少,所以又称之为短栈.另外,需要知道的是:TCP/IP协议栈只是许多支持ISO/OSI ...
- TCP/IP协议三次握手与四次握手流程解析(转载及总结)
原文地址:http://www.2cto.com/net/201310/251896.html,转载请注明出处: TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详 ...
- linux OSI七层模型、TCP/IP协议栈及每层结构大揭秘
学习Linux,就算是像小编我这样的小萌新,也知道OSI模型.什么?!你不知道!!! 好吧,这篇秘籍拿走,不谢~~~ 一.两个协议 (1)OSI 协议模型(7层)国际协议 PDU:协议数据单元对 ...
- TCP/IP/UDP 协议
互连网早期的时候,主机间的互连使用的是NCP协议.这种协议本身有很多缺陷,如:不能互连不同的主机,不能互连不同的操作系统,没有纠错功能.为了改善这种缺点,大牛弄出了TCP/IP协议.现在几乎所有的操作 ...
- 以太网接口TCP/IP协议介绍,说的很容易懂了
以太网接口TCP/IP协议介绍,说的很容易懂了 TCP/IP协议,或称为TCP/IP协议栈,或互联网协议系列. TCP/IP协议栈(按TCP/IP参考模型划分) 应用层 FTP SMTP HTT ...
随机推荐
- Django---自定义admin组件思维导图
- 关于JS解析编历JSON数组(含多维数组)
第一部分: ].xing) 第二部分: } 解释: countryObj 为value对象的一个属性明 value[coun ...
- Qt性能问题
使用Qt库开发通信上位机软件,如串口.CAN总线等,涉及到接收界面高速刷新,会使CPU消耗率过高(20%以上),可能还会卡顿. 具体原因不知道,突然想放弃Qt了 ps: 1.问题出在界面刷新,会占据C ...
- mongoose@4.5.2的eachAsync bug
自称踩坑大王,幸好没有地雷,哈哈哈哈哈哈,今天用了mongoose的 eachAsync() 方法,没想到,会出现 Trace: [RangeError: Maximum call stack siz ...
- [mongodb] MMAPv1 Storage Engine
MMAPv1 是mongodb 在3.2以前默认的存储引擎,在3.2 之后默认的存储引擎为WiredTiger,MMAPv1存储引擎基于内存映射文件,它擅长高容量的插入,读取和更新. Journal ...
- Introspector内省和反射的区别.
Introspector 是一个专门处理bean的工具类.用来获取Bean体系里的 propertiesDescriptor,methodDescriptor. 要理解这个,就要理解下面几个议题. ...
- ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。
阿里巴巴技术大牛黄勇的经验分享,感觉很受用. 关于IT 职场经验 1. 把技术当成工具 技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单. 我们每天在面 ...
- static变量的作用
在C语言中,关键字static的意思是静态的,有3个明显的作用: 1. 在函数体内,静态变量具有记忆作用,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变. 2. 在模块内(但在函数体外) ...
- Git迁移 从SVN到Git
Migrating from SVN to Git 首先我们需要在Stach或者GitHub上新建一个Repository, 拿到它的URL. 接下来参照如下步骤 : At first we shou ...
- 绝对布局absoluteLayout
绝对布局absoluteLayout 一.简介 二.实例 绝对布局我们是指定的横纵坐标,所以可以这样直接拖 绝对布局实际中用的少