uip协议栈入门

  • Post author:
  • Post category:其他


uip协议栈是一个简单的嵌入式网络协议栈,其不需要操作系统的支持,以事件驱动的方式编程,占用的RAM以及ROM都符合嵌入式的需求,实现了四个基本协议 arp,ip,icmp,tcp。传统的TCP/IP协议栈,比如LInux,windows上的使用的API接口是标准的socket api。由于嵌入式MCU的RAM大小和CPU性能有限,能以运行这种套接字的API占用资源过大,使用这种基于事件驱动方式编程的以太网协议栈符合嵌入式MCU的需求

uIP事件状态机

uIP在任何事件发生时,都会调用 UIP_APPCALL(),而这个函数可以被用户重定义,然后在这个函数中处理这些事件,以下列出的是事件和对应的测试函数

一个数据包到达,确认数据已经发出

uip_acked()

应用程序的新数据包已经到达

uip_newdata()

一个远程主机连接到监听端口

uip_connected()

一个到达远程主机的连接成功建立

uip_connected()

计时时间满需要重发

uip_rexmit()

计时时间满周期性轮询

uip_poll()

远程主机关闭连接

uip_closed()

远程主机中断连接

uip_aborted()

太多重传,导致连接中断

uip_timedout()

UIP协议栈的调用过程

uip_init() 初始化uip协议栈,

uip_input() 当网络设备读到一个IP包到缓冲区

uip_periodic() 代表1s一次

uip_input() //读一个IP包到缓冲区 uip_process(UIP_DATA) //处理事件 UIP_APPCALL();//回调接口 tcp_demo_appcall //应用程序的回调接口

tcp_demo_appcall

/TCP应用回调接口(UIP_APPCALL) void tcp_demo_appcall(void) { switch(uip_conn->lport)//本地监听端口 { case HTONS(8080): break; case HTONS(1200): break; default: break; } switch(uip_conn->rport) //远程连接服务器的80端口 { case HTONS(80): tcp_client_appcall(); break; default: break; } }

uip实现一个get请求 服务器

www.shilei.club

void tcp_client_appcall() { if(uip_connected())//连接上了? { // uip_send(“GET / HTTP/1.1\r\nHost:www.shilei.club\r\n\r\n”,48); uip_sock_flag =CLIENT_CONNECT; uip_log(“tcp_client connected!\r\n”);//TCP已经连接 } if(uip_aborted())//ÒâÍâÖÕÖ¹? { uip_sock_flag =CLIENT_DISCONNECT; uip_log(“tcp_client aborted!\r\n”);// tcp_client_reconnect(); } if(uip_timedout())//超时 { uip_sock_flag =CLIENT_TIMEOUT; uip_log(“tcp_client timeout!\r\n”); tcp_client_reconnect();//重连 } if(uip_acked())//确认发出数据 { uip_ack_flag=1; uip_log(“tcp_client acked!\r\n”);// } if(uip_newdata())//应用程序的新数据包已经到达 { if(uip_ack_flag) { uip_ack_flag=0; uip_log(“tcp_client recv data!\r\n”);// printf(“\r\n%s\r\n”,uip_appdata); } } if(uip_rexmit())//需要重发 { uip_log(“tcp_client rexmit!\r\n”); } if(uip_poll())//应用程序循环运行 { if(uip_sock_flag!=CLIENT_CONNECT) { uip_abort(); } if(uip_send_flag) { uip_send_flag=0; uip_send(“GET / HTTP/1.1\r\nHost:www.shilei.club\r\n\r\n”,48); } } if(uip_closed())//关闭连接 { //uip_abort(); uip_sock_flag=CLIENT_DISCONNECT; uip_log(“tcp_client closed!\r\n”);// tcp_client_reconnect(); } }

GET请求的周期可以通过stm32的定时器3来控制,这里设为1S,设置发送标志位为1,uip_poll时间发生时,就会发送get请求

void TIM3_IRQHandler(void) { static u8 tcnt; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) // { GPIOE->ODR ^= GPIO_Pin_8; if(uip_sock_flag == CLIENT_CONNECT)// { uip_send_flag=1; } } TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); // }



版权声明:本文为qq_18737805原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。