lwip 移植

2019-07-14 11:13发布

http://blog.csdn.net/xxu0123456789/article/details/8463828
一、源码目录结构        api 、 core、netif、 include       core下又有IPV4 、 IPV6 、 SNMP 和.c文件       include下又有IPV4、IPV6、LWIP、netif       netif下的文件有       1. ethernetif.c这里主要涉及到具体的硬件       2.etharp.c 这里有个函数ethernet_input在初始化时被赋给netif 接口卡的input,功能为处理到来的数据,然后分发给arp  ip等等。里面还有就是完成arp方面的更新arp 缓冲什么的。      3.loopif.c      4.slipif.c      5. ppp文件夹 二、开始移植     1、在keil里新建文件夹,将文件包含进去,然后设置include路径,ok
    2、首先修改opt.h里的 NO_SYS为1,表示无系统,SYS_LIGHTWEIGHT_PROT为0,表示不保护临界区域,开始编译根据错误提示修改           最终在include文件加下建立arch文件夹里面包含cc.h, arch.h , perf.h, sys_arch.h       cc.h里包含的内容为 #ifndef __CC_H__
#define __CC_H__
#include "stdio.h"

typedef signed char s8_t;
typedef unsigned char u8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned int u32_t;
typedef signed int s32_t;                       // 定义数据类型

typedef u32_t mem_ptr_t;            /* Unsigned 32 bit quantity        */ 定义指针大小

#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT 
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x      //预编译器有关,为了实现对齐

#define BYTE_ORDER LITTLE_ENDIAN   //定义小端模式

#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234     //定义小端
#endif

#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321         //定义大端
#endif

#ifndef LWIP_PLATFORM_ASSERT      //调试用
#define LWIP_PLATFORM_ASSERT(x)
    do
    {   printf("Assertion "%s" failed at line %d in %s ", x, __LINE__, __FILE__);
    } while(0)
#endif

#ifndef LWIP_PLATFORM_DIAG     //调试用
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
#endif

#endif /* __CC_H__ */

perf.h里包含的内容为 #ifndef __PERF_H__
#define __PERF_H__

#define PERF_START    /* null definition */   // 没深去弄,你看看,不难
#define PERF_STOP(x)  /* null definition */

#endif /* __PERF_H__ */  我arch.h sys_arch.h里为空
      3,编译,如果没有问题者开始修改ethernetif.c文件,#if 1 打开底层接口修改low_level_init,  low_level_output,  low_level_input, ethernetif_init函数,        编译无误,OK忘了,还要修改opt.h里
       #define MEM_ALIGNMENT                   4       //内存对齐
       #define MEM_SIZE                        8*1204        #define ETHARP_TRUST_IP_MAC             1  //更新arp缓冲列表
三、定时部分     1,设置一个定时器约为250ms调用tcp.c里的tcp_tmr函数。         tcp_tmr该函数完成了 连接超时,延迟ACK(捎带确认),持续(persist),保鲜(keep alive),  FIN_WAIT_2,  TIME_WAIT定时功能
    2,如果开启了arp缓冲功能ETHARP_TRUST_IP_MAC ,则需要5s定时调用etharp.c里的etharp_tmr()函数来删除arp表。 四、到这里就是移植完成了,下面写一个简单的例子tcp    1、首先定义一个struct netif接口,然后调用mem_init(); memp_init(); pbuf_init(); netif_add()初始化,然后调用netif_set_default 和netif_set_up搞定。    2、 struct tcp_pcb *tcppcb = NULL;
void tcp_app(void)
{
    err_t err = 0;
    struct ip_addr ipaddr;
    IP4_ADDR(&ipaddr, 192,168,1,15);
     tcppcb = tcp_new();
    if(tcppcb == NULL)
        return;
    err = tcp_bind(tcppcb, &ipaddr, 80);
    tcppcb = tcp_listen(tcppcb);    tcp_accept(tcppcb, tcppcb_accept);
}
static err_t  tcppcb_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct http_state *hs;

  /* Allocate memory for the structure that holds the state of the connection */
  hs = mem_malloc(sizeof(struct http_state));

  if (hs == NULL)
  {
    return ERR_MEM;
  }

  /* Initialize the structure. */
  hs->file = NULL;
  hs->left = 0;

  /* Tell TCP that this is the structure we wish to be passed for our
     callbacks. */
  //tcp_arg(pcb, hs);

  /* Tell TCP that we wish to be informed of incoming data by a call
     to the http_recv() function. */
  tcp_recv(pcb, tcppcb_recv); //数据接收完毕之后,调用tcppcb_recv函数

  //tcp_err(pcb, conn_err);

 // tcp_poll(pcb, http_poll, 10);
  return ERR_OK;
} static err_t tcppcb_recv(void *arg, struct tcp_pcb *pcb,  struct pbuf *p, err_t err) //处理接收到得数据
{ char *data; int32_t ,len=0;
  if (err == ERR_OK && p != NULL)
  {
    /* Inform TCP that we have taken the data */
    tcp_recved(pcb, p->tot_len);       data = p->payload;
      len = p->tot_len;
}
tcp_write() LwIP通过调用函数tcp_write()来发送TCP数据。当数据被成功地发送到远程主机后,应用程序将会收到应答从而去调用一个指定的回调函数 tcp_sndbuf()
返回发送队列中可用字节的大小 tcp_sent ()
该函数用于设定远程主机成功接收到数据后调用的回调函数,通常也在函数tcp_listen()之后调用

热门文章