当前位置:文档之家› CycloneTCP协议栈移植与使用简介

CycloneTCP协议栈移植与使用简介

Arda TechnologyArda Tech P.F.FU 2014-12-19 Ver 0.1#elif defined(USE_XXXXXX)#include "os_port_xxxxxx.h"NicType type;//控制器类型。

0:以太网接口,1:PPP接口,2:6LowPan接口NicInit init;//控制器初始化函数指针NicTick tick;//控制器周期性事务处理函数指针NicEnableIrq enableIrq;//打开控制器中断函数指针NicDisableIrq disableIrq;//关闭控制器中断函数指针NicEventHandler eventHandler;//控制器中断响应函数指针,这个是下半段的中断处理部分。

NicSetMacFilter setMacFilter;//配置多播MAC地址过滤函数指针NicSendPacket sendPacket;//发送包函数指针NicWritePhyReg writePhyReg;//写PHY寄存器函数指针NicReadPhyReg readPhyReg;//读PHY寄存器函数指针bool_t autoPadding;//是否支持自动填充bool_t autoCrcGen;//是否支持自动生成CRC校验码bool_t autoCrcCheck;//是否支持自动检查CRC错误NicSendControlFrame sendControlFrame;//发送控制帧函数指针NicReceiveControlFrame receiveControlFrame;//接收控制帧函数指针NicPurgeTxBuffer purgeTxBuffer;//清除发送缓冲函数指针NicPurgeRxBuffer purgeRxBuffer;//清除接受缓存函数指针xxxxEthInitGpio(...)//用于在init中初始化GPIO。

xxxxEthInitDmaDesc(...)//用于在init中初始化DMA任务描述符列表。

XXXX_Handler(...)//用于MAC中断的上半段处理。

xxxxEthReceivePacket(...)//用于在eventHandler中收包,把数据从dma的缓冲复制到外部缓冲。

xxxxEthCalcCrc(...)//计算CRC值,这个函数基本上是固定的。

xxxxEthDumpPhyReg(...)//用于调试的打印PHY寄存器列表值。

PhyInit init ;//物理层初始化函数指针PhyTick tick ;//周期性事务处理函数指针 PhyEnableIrq enableIrq ;//打开物理层中断 PhyDisableIrq disableIrq ;//关闭物理层中断 PhyEventHandler eventHandler ;//物理层中断处理函数#include"core/tcp_ip_stack.h"//必须要有的协议栈头文件#include"drivers/tm4c129x_eth.h"//MAC驱动头文件,如果用了片外PHY,还要包含PHY的驱动头文件#include"dhcp/dhcp_client.h"//使用DHCP的话需要此头文件#include"ipv6/slaac.h"//使用IPV6本地短地址的话需要此头文件#include"common/debug.h"//如果你用了CycloneTCP的调试输出函数,则需要包含此头文件//Application configuration#define APP_MAC_ADDR"00-11-22-33-44-55"//定义MAC地址#define APP_USE_DHCP ENABLED//DHCP开关,使用DHCP#define APP_IPV4_HOST_ADDR"192.168.1.20"//静态地址时的IPV4 IP#define APP_IPV4_SUBNET_MASK"255.255.255.0"//静态地址时的IPV4 子网掩码#define APP_IPV4_DEFAULT_GATEWAY"192.168.1.1"//静态地址时的IPV4 网关IP#define APP_IPV4_PRIMARY_DNS"8.8.8.8"//静态地址时的IPV4 主DNS IP#define APP_IPV4_SECONDARY_DNS"8.8.4.4"//静态地址时的IPV4 从DNS IP#define APP_USE_SLAAC DISABLED//SLAAC开关,禁用SLAAC#define APP_IPV6_LINK_LOCAL_ADDR"fe80::407"#define APP_IPV6_PREFIX"2001:db8::"#define APP_IPV6_PREFIX_LENGTH 64#define APP_IPV6_GLOBAL_ADDR"2001:db8::407"#define APP_IPV6_ROUTER"fe80::1"#define APP_IPV6_PRIMARY_DNS"2001:4860:4860::8888"#define APP_IPV6_SECONDARY_DNS"2001:4860:4860::8844"//Constant definitions#define APP_SERVER_NAME""//应用层访问的地址#define APP_SERVER_PORT 80//应用层访问的端口#define APP_REQUEST_URI"/test.php"//应用层访问的远端文件路径DhcpClientSettings dhcpClientSettings;//DHCP客户端配置DhcpClientCtx dhcpClientContext;//DHCP客户端上下文,运行时变量SlaacSettings slaacSettings;//短地址配置SlaacContext slaacContext;//短地址上下文,运行时变量error_t error;NetInterface *interface;//网络接口结构指针MacAddr macAddr;//MAC地址变量#if (APP_USE_DHCP == DISABLED)Ipv4Addr ipv4Addr;//IPV4地址变量#endif#if (APP_USE_SLAAC == DISABLED)Ipv6Addr ipv6Addr;//IPV6地址变量#endif//Start-up messageTRACE_INFO("\r\n");TRACE_INFO("***********************************\r\n");TRACE_INFO("*** CycloneTCP HTTP Client Demo ***\r\n");TRACE_INFO("***********************************\r\n");TRACE_INFO("Copyright: 2010-2014 Oryx Embedded\r\n");TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__);TRACE_INFO("Target: EK-TM4C1294XL\r\n");TRACE_INFO("\r\n");printf("HTTP Client Demo");//TCP/IP stack initialization 初始化协议栈error =tcpIpStackInit();//Any error to report?if(error){//Debug messageTRACE_ERROR("Failed to initialize TCP/IP stack!\r\n");}//Configure the first Ethernet interface 配置首个网络接口interface = &netInterface[0];//Set interface name 设定网络接口名称tcpIpStackSetInterfaceName(interface,"eth0");//Set host name 设定主机名称tcpIpStackSetHostname(interface,"HTTPClientDemo");//Select the relevant network adapter 设定网络适配器nic驱动tcpIpStackSetDriver(interface, &tm4c129xEthDriver);//Set host MAC address 设定主机MAC地址macStringToAddr(APP_MAC_ADDR, &macAddr);tcpIpStackSetMacAddr(interface, &macAddr);//Initialize network interface 初始化网络接口error =tcpIpStackConfigInterface(interface);//Any error to report?if(error){//Debug messageTRACE_ERROR("Failed to configure interface %s!\r\n", interface->name);}#if (IPV4_SUPPORT == ENABLED)//当使能IPV4时#if (APP_USE_DHCP == ENABLED)//当使用DHCP时//Get default settings 载入默认的DHCP参数dhcpClientGetDefaultSettings(&dhcpClientSettings);//Set the network interface to be configured by DHCP 设定DHCP线程操作的网口 dhcpClientSettings.interface = interface;//Disable rapid commit option 禁用快速提交dhcpClientSettings.rapidCommit = FALSE;//DHCP client initialization 初始化DHCP客户端error =dhcpClientInit(&dhcpClientContext, &dhcpClientSettings);//Failed to initialize DHCP client?if(error){//Debug messageTRACE_ERROR("Failed to initialize DHCP client!\r\n");}//Start DHCP client 启动DHCP客户端error =dhcpClientStart(&dhcpClientContext);//Failed to start DHCP client?if(error){//Debug messageTRACE_ERROR("Failed to start DHCP client!\r\n");}#else//如果不使用DHCP时//Set IPv4 host address 转换并设定主机IPipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr);ipv4SetHostAddr(interface, ipv4Addr);//Set subnet mask 转换并设定网络掩码ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr);ipv4SetSubnetMask(interface, ipv4Addr);//Set default gateway 转换并设定网关ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr);ipv4SetDefaultGateway(interface, ipv4Addr);//Set primary and secondary DNS servers 转换并设定主从DNSipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr);ipv4SetDnsServer(interface,0, ipv4Addr);ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr);ipv4SetDnsServer(interface,1, ipv4Addr);#endif#endif#if (IPV6_SUPPORT == ENABLED)//如果使用IPV6#if (APP_USE_SLAAC == ENABLED)//如果使用SLAAC//Get default settings 加载默认SLAAC参数slaacGetDefaultSettings(&slaacSettings);//Set the network interface to be configured 设定SLAAC使用的网络接口 slaacSettings.interface = interface;//SLAAC initialization 初始化SLAACerror =slaacInit(&slaacContext, &slaacSettings);//Failed to initialize SLAAC?if(error){//Debug messageTRACE_ERROR("Failed to initialize SLAAC!\r\n");}//Start IPv6 address autoconfiguration process 启动IPV6地址自动获取进程 error =slaacStart(&slaacContext);//Failed to start SLAAC process?if(error){//Debug messageTRACE_ERROR("Failed to start SLAAC!\r\n");}#else//不使用SLAAC时//Set link-local address 转换并设定主机IPipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr);ipv6SetLinkLocalAddr(interface, &ipv6Addr, IPV6_ADDR_STATE_VALID);//Set IPv6 prefixipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr);ipv6SetPrefix(interface, &ipv6Addr, APP_IPV6_PREFIX_LENGTH);//Set global addressipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr);ipv6SetGlobalAddr(interface, &ipv6Addr, IPV6_ADDR_STATE_VALID);//Set routeripv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr);ipv6SetRouter(interface, &ipv6Addr);//Set primary and secondary DNS serversipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr);ipv6SetDnsServer(interface,0, &ipv6Addr);ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr);ipv6SetDnsServer(interface,1, &ipv6Addr);#endif#endiferror_t error;size_t length;IpAddr ipAddr;//DNS解析得到的地址Socket *socket;//Socket套接字static char_t buffer[256];//Debug messageTRACE_INFO("\r\n\r\n Resolving server name...\r\n");//Resolve HTTP server name 解析地址error =getHostByName(NULL, APP_SERVER_NAME, &ipAddr,0);//Any error to report?if(error){//Debug messageTRACE_INFO("Failed to resolve server name!\r\n");//Exit immediatelyreturn error;}//Create a new socket to handle the request 创建新的socket连接socket =socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP);//Any error to report?if(!socket){//Debug messageTRACE_INFO("Failed to open socket!\r\n");//Exit immediatelyreturn ERROR_OPEN_FAILED;}//Start of exception handling block 此处的do/while用于快速跳过错误后面的代码do{//Debug messageTRACE_INFO("Connecting to HTTP server %s\r\n",ipAddrToString(&ipAddr, NULL));//Connect to the HTTP server 连接到HTTP服务器error =socketConnect(socket, &ipAddr, APP_SERVER_PORT);//Any error to report?if(error)break;//Debug messageTRACE_INFO("Successful connection\r\n");//Format HTTP request 生成HTTP请求字符串length =sprintf(buffer,"GET %s HTTP/1.0\r\n Host: %s:%u\r\n\r\n",APP_REQUEST_URI, APP_SERVER_NAME, APP_SERVER_PORT);//Debug messageTRACE_INFO("\r\n HTTP request:\r\n%s", buffer);//Send HTTP request 发送HTTP请求error =socketSend(socket, buffer, length, NULL,0);//Any error to report?if(error)break;//Debug messageTRACE_INFO("HTTP response header:\r\n");//Parse HTTP response header 解析HTTP服务器响应头while(1){//Read the header line by line 从socket中读取一行error =socketReceive(socket, buffer,sizeof(buffer) -1, &length,SOCKET_FLAG_BREAK_CRLF);//End of stream?if(error)break;//Properly terminate the string with a NULL character 缓冲结尾填充0buffer[length] ='\0';//Dump current dataTRACE_INFO("%s", buffer);//The end of the header has been reached? 检查是http响应头否结束if(!strcmp(buffer,"\r\n"))break;}//Debug messageTRACE_INFO("HTTP response body:\r\n");//Parse HTTP response body 解析响应数据while(1){//Read response body 读取响应数据error =socketReceive(socket, buffer,sizeof(buffer) -1, &length,0);//End of stream?if(error)break;//Properly terminate the string with a NULL character 缓冲结尾填充0buffer[length] ='\0';//Dump current dataTRACE_INFO("%s", buffer);}//End of exception handling block}while(0);//Close the connection 关闭socket链接socketClose(socket);//Debug messageTRACE_INFO("\r\n Connection closed...\r\n");GPLv2RF/。

相关主题