SylixOS网络协议栈数据收发流程

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

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

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

2. pbuf 结构介绍

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

程序清单2.1

/* Main packet buffer struct */struct pbuf {2
    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()处理流程

原文地址:http://blog.51cto.com/7199226/2150125

时间: 2024-08-02 10:42:03

SylixOS网络协议栈数据收发流程的相关文章

TCP/IP 协议数据收发流程

先弄清楚重要的数据结构 两个全局的变量 struct socket* socket[NR_SOCKET];  struct proto_ops* pops[NR_PROTOCOL]; bsd socket 层 struct socket *sock  /  struct proto_ops *ops =========================== inet 层  struct proto_ops inet_proto_ops = { inet_creat, inet_read, ....

linux内核网络协议栈架构分析,全流程分析-干货

https://download.csdn.net/download/wuhuacai/10157233 https://blog.csdn.net/zxorange321/article/details/75676063 LINUX内核协议栈分析 目  录 1      说明...4 2      TCP协议...4 2.1       分层...4 2.2       TCP/IP的分层...5 2.3       互联网的地址...6 2.4       封装...7 2.5       

linux 内核网络协议栈阅读理解--带详尽注释以及相关流程调用注释,附 github 注释后源码

linux 内核网络协议栈阅读理解--带详尽注释以及相关流程调用注释,对理解内核协议栈源码很有帮助 对理解阅读 linux 协议栈源码很用帮助 github 地址: https://github.com/y123456yz/Reading-and-comprehense-linux-Kernel-network-protocol-stack

linux网络协议栈--路由流程分析

转:http://blog.csdn.net/hsly_support/article/details/8797976 来吧,路由 路由是网络的核心,是linux网络协议栈的核心,我们找个入口进去看看 还记得在笔记5-IP层的处理1中ip_rcv_finish走到过一个岔口 ->ip_rcv_finish() ->ip_route_input()  查找路由信息 ->if (iph->ihl > 5 && ip_rcv_options(skb)) 如果IP头部

java网络编程——多线程数据收发并行

基本介绍与思路 收发并行 前一篇博客中,完成了客户端与服务端的简单TCP交互,但这种交互是触发式的:客户端发送一条消息,服务端收到后再回送一条.没有做到收发并行.收发并行的字面意思很容易理解,即数据的发送与接收互相不干扰,相互独立.当然,要保证服务端和客户端都能做到收发并行. 业务逻辑 脱离业务逻辑的实践是毫无意义的,先描述一下本实践中的业务逻辑:一个服务端接受多个客户端的连接,连接后,向各个客户端定时发送时间戳数据,同时在并行条件下,接受各个客户端发送来的数据并显示:客户端键盘输入字符串,发送

理解 Linux 网络栈 (Linux networking stack)(1):Linux 网络协议栈简单总结

本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM虚拟化 Linux 环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO 1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的.Linux Socket 是从

SylixOS 网络零拷贝技术

SylixOS 网络零拷贝技术 1.   网络零拷贝介绍 网络零拷贝技术指的是在数据报文从网络设备到用户程序传递的过程中,一种减少数据拷贝次数,减少系统调用,实现CPU的零参与,从而减轻 CPU负载的技术. 1.1 SylixOS网络现状 SylixOS网络使用的是Lwip协议栈,其数据报文从网络设备到用户程序只需要一次拷贝即可实现.产生这次拷贝的原因是数据报文从网络设备往协议栈传输时,数据格式不一样.网络协议栈需要专门的数据结构(pbuf)来管理报文,而设备层只会将数据本身存放在一块内存缓冲区

Android短信彩信收发流程(应用层)

下图为ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息发送流程.主要以接收者有效性的确认为主,然后转向sendMessage方法进行发送. ComposeMessageActivity.sendMessage从下图可以看出,在这个方法中,主要做的事是确认手机状态的有效性.最终调用WorkingMessage的send方法进行信息的发送.  WorkingMessage.send从下图可以看出,在本方法中,对于不同类型的消息,分别调用不同

RDP协议概述、协议栈以及连接流程

从本文开始,我们将介绍一系列RDP协议的相关实现技术. 一.RDP协议的诞生 网络上存在着大量关于RDP协议是如何产生的话题和历史论述,有人说RDP协议是微软自家自研的协议,有人说这是微软从国际电信联盟收购而来的基于T.share协议进行改进的协议,有人说是微软公司从思杰公司收购而来等等不一而足.那么真实的RDP协议到底最初是如何产生的? 实际上,微软RDP协议在诞生之初,是基于ITU-T(国际电信联盟)的T.120协议集中T.128应用程序共享协议(在设计之初,国际电信联盟对其的名称为T.sh