我是靠谱客的博主 等待背包,最近开发中收集的这篇文章主要介绍SylixOS网络协议栈数据收发流程1. SylixOS网络协议栈基本介绍2. pbuf 结构介绍3. UDP 数据包发送流程4. UDP 数据包接收流程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. SylixOS网络协议栈基本介绍

    SylixOS网络协议栈使用目前非常流行的嵌入式TCP/IP协议栈lwiplwip是瑞典计算机科学院(SICS)Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。lwip特点是对RAMROM的占用非常少,只需十几KBRAM40K左右的ROM就可以运行,非常适合嵌入式系统使用。

    本文将会介绍基于dm9000网卡的数据包收发流程。

 

2. pbuf 结构介绍

        pbuf是lwip中用来表示数据包的结构体,数据包在协议栈各层的流动也是通过pbuf来实现的,基本结构如程序清单 2.1所示。

                                                                                  程序清单2.1

/* Main packet buffer struct */
    struct pbuf {
    struct pbuf *next;                  /* 下一个pbuf结构                            */
    void *payload;                      /* 实际数据起始地址                           */
    u16_t tot_len;                      /* pbuf链总长度                              */
    u16_t len;                          /* 当前pbuf长度                              */
    u8_t type_internal;                 /* pbuf类型                                  */
    u8_t flags;
    LWIP_PBUF_REF_T ref;                /* 初始化为1,pbuf->next指向自己时ref加1       */
    u8_t if_idx;
    void *if_out; 
};

    pbuf的字段type_internal表示pbuf类型,lwip中有四种类型PBUF_RAM、PBUF_ROM、PBUF_REF和PBUF_POOL:

    1) PBUF_RAM类型的pbuf结构是一块很大的内存空间,内存首部是pbuf结构,实际数据接在后面,发送数据时常使用这种类型。如图 2.1所示;

                                                                            图 2.1 PBUF_RAM类型的pbuf结构

    2) PBUF_POOL类型是由多个pbuf结构组合而成,使用next字段将这些pbuf结构连接起来。其中tot_len表示此节点和next之后所有节点的长度和,len表示当前节点的数据长度。接收数据时常使用这类型的pbuf结构。如图 2.2所示;

                                                                     图 2.2 BUF_POOL类型的pbuf结构

    3) PBUF_REF与PBUF_ROM类似,pbuf结构是单独的一块内存空间,而data是另一块内存,二者并不相连,如图 2.3所示;

                                                              图 2.3 BUF_REF和PBUF_ROM类型的pbuf结构

    Lwip协议栈使用pbuf结构在各层之间传递数据包,通过移动payload指针的方式在数据中添加报文头和剔除报文头,从而实现“零拷贝”机制,提高报文处理效率。

 

3. UDP 数据包发送流程

UDP数据包的发送是通过sendto()发起的(其他接口类似),整体实现流程如下:

    1) 通过文件描述符fd获取文件结构并提取lwipfd,再通过lwipfd从socket表中获取socket结构。Socket结构中包含了此udp链接中的connect信息;

    2) 使用netbuf_alloc()创建netbuf结构,这其中包含了pbuf结构。向这个结构导入需要发送的数据;

    3) Netbuf结构最终会传入udp_send()或udp_sendto(),这其中会通过ip_route()确定最终需要发送的网卡结构netif;

    4) Udp_sendto_if_src()添加udp包头;

    5) If_output_if_src()添加IP包头;

    6) 根据网卡结构netif获取发送接口netdev_netif_linkoutput(),最终调用网卡发送函数dm9000_transmit();

发送流程图如图 3.1所示;

                                                                                   图 3.1 发送流程图

 

4. UDP 数据包接收流程

    数据包接收包括两个部分。首先网卡获取一个数据包并使用中断通知系统,系统解析这个数据包放入缓冲队列中。再由应用层调用接口recv()或recvfrom()获取这个数据包。

4.1 中断接收

    1) 系统在初始化时会注册网卡中断,处理函数为dm9000IntIsr()。当接收到一个数据包时会执行中断处理,中断处理内容很简短,仅添加一个接收处理函数dm9000_receive()到任务队列中,数据包主要在接受处理函数中被处理,减少了中断开销;

    2) 在dm9000_receive()中首先会创建一个POOL类型的pbuf结构,再调用驱动接口priv->inblk()从网卡中提取报文放入pbuf结构中,执行tcpip_input()处理这个数据包;

    3)通过消息队列发送数据到网络线程“t_netproto”,使用一个单独的线程处理此数据包;

    4) 进入线程后执行ip4_input()进行网络层处理,提取出运输层数据再通过udp_input()进行udp数据包处理;

    5) 根据ip与port找到对应的udp链接信息即udp_pcb结构,提取pcb中对应的接收处理函数pcb->recv()即recv_udp()和链接结构connect,recv_udp()中会将此数据包发送到此udp链接的消息队列中,等待用户层提取;

网卡中断接收流程如图 4.1所示;

                                                                            图 4.1 网卡中断接收流程

4.2 recvfrom()

    1) 过文件描述符fd获取文件结构,并提取lwipfd。再通过lwipfd从socket表中获取socket结构。Socket结构中包含了此udp链接中的connect信息;

    2) 根据connect信息获取对应UDP链接的接收消息队列,并通过调用netconn_recv_data()从消息队列中获取一条报文;

recvfrom()处理流程如图 4.2所示;

                                                                           图 4.2 recvfrom()处理流程

 

最后

以上就是等待背包为你收集整理的SylixOS网络协议栈数据收发流程1. SylixOS网络协议栈基本介绍2. pbuf 结构介绍3. UDP 数据包发送流程4. UDP 数据包接收流程的全部内容,希望文章能够帮你解决SylixOS网络协议栈数据收发流程1. SylixOS网络协议栈基本介绍2. pbuf 结构介绍3. UDP 数据包发送流程4. UDP 数据包接收流程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(88)

评论列表共有 0 条评论

立即
投稿
返回
顶部