• lwip 移植


    一、源码目录结构

           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()之后调用


  • 相关阅读:
    2021.9.15 单一职责原则
    2021.9.21 Hive元数据
    2021.9.22 抽象工厂方法模式(人与肤色)
    2021.9.25 Hive安装
    1021每日博客
    1027每日博客
    1018每日博客
    1028每日博客
    1026每日博客
    1025每日博客
  • 原文地址:https://www.cnblogs.com/alan666/p/8312146.html
Copyright © 2020-2023  润新知