lwip的架构分析(基于LPC17xx)

终于开始这部分的工作,计划了很久,但一直都没有实施。以前一直只使用TCP/IP但对其处理的流程确一知半解。计划拿出几天的时间好好的学习下,理解其运行的基本原理。

一个嵌入式的网络架构一般都由3部分构成:1、应用层。2、协议层。3、网卡层驱动。为了较好的理解lwip的架构。我们从应用层开始一层一层的剥开整个过程,了解整个系统时怎样串联起来的,

首先是应用层,这里会初始化网络参数。参见下面用户初始化网络的代码:

tcpip_init(tcpip_init_done_signal,(void *) &tcpipdone);

IP4_ADDR(&gw, 10, 1, 10, 1);

IP4_ADDR(&ipaddr,10, 1, 10, 234);

IP4_ADDR(&netmask,255, 255, 255, 0);

/* Add netif interfacefor lpc17xx_8x */

if(!netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL,lpc_enetif_init,

tcpip_input)) {

LWIP_ASSERT("Netinterface failed to initialize\r\n", 0);

}

netif_set_default(&lpc_netif);

netif_set_up(&lpc_netif);

这是初始化网络代码的一部分。其中最重要的是tcpip_init()和net_add()函数。

串联其中的就是lpc_netif变量,它是一个struct netif结构体,一般一个网卡对应一个struct netif结构,并用一个list将所有网卡链接起来构成一个链表。首先先看看这个接口的定义:

struct netif {

struct netif *next; /** pointer to next in linked list;指向下一个网卡 */

ip_addr_t ip_addr;/**网卡的配置参数**/

ip_addr_t netmask;

ip_addr_t gw;

/** This function iscalled by the network device driver

*  to pass a packet up the TCP/IP stack. */

netif_input_fn input;//这是个函数指针,由设备驱动程序调用,传递一个网络数据包到TCP/IP层。

/** This functionis called by the IP module when it wants

*  to send a packet on the interface. Thisfunction typically

*  first resolves the hardware address, thensends the packet. */

netif_output_fn output; //这也是一个函数指针,由IP模块调用发送一个网卡。

/** This function is called by the ARP modulewhen it wants

*  to send a packet on the interface. Thisfunction outputs

*  the pbuf as-is on the link medium. */

netif_linkoutput_fn linkoutput;//这个函数由ARP协议调用

};

在tcpip_init()中会有一个重要的调用既创建了tcpip_thread()的线程。 我们来看看这个函数到底做了些什么呢?

void   tcpip_init(tcpip_init_done_fninitfunc, void *arg)

{

lwip_init();

if(sys_mbox_new(&mbox,TCPIP_MBOX_SIZE) != ERR_OK) {

LWIP_ASSERT("failedto create tcpip_thread mbox", 0);

}

#if LWIP_TCPIP_CORE_LOCKING

if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {

LWIP_ASSERT("failed to createlock_tcpip_core", 0);

}

#endif /* LWIP_TCPIP_CORE_LOCKING */

sys_thread_new(TCPIP_THREAD_NAME ,tcpip_thread,NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);

}

我从中可以看到调用了3个函数:

1、lwip_init();初始化了lwip需要要用到的一些参数。

2、sys_mutex_new()创建了一个新的互斥锁。

3 sys_thread_new()新建了一个线程处理tcpip协议栈。在这个线程中你会看到线程会阻塞在读mbox的函数上,直到网卡接收到数据才会继续执行下去。详细的代码请参看tcpip.c文件。

下面我们在来看看另一函数net_add(),我们先看它的第六个参数:lpc_enetif_init(),这个参数是一个函数指针,它是lpc mac层的驱动程序中的一个函数。我们在来看看这个函数中到底干了些什么。

{

err= low_level_init(netif);//初始化MAC以及Phy芯片

netif->output= lpc_etharp_output;//设置网卡arp输出函数到网卡接口

netif->linkoutput= lpc_low_level_output;//设置网卡IP数据输出函数网卡接口

sys_thread_new("receive_thread",vPacketReceiveTask, netif->state,

DEFAULT_THREAD_STACKSIZE,tskRECPKT_PRIORITY);

//底层的接收线程

sys_thread_new("txclean_thread",vTransmitCleanupTask, netif->state,

DEFAULT_THREAD_STACKSIZE,tskTXCLEAN_PRIORITY);

//底层的发送线程

}

我们再看看接收线程:

首先线程信号量:/* Wait for receive task to wakeup*/

sys_arch_sem_wait(&lpc_netifdata->RxSem,0);

然后读取网卡数据:

lpc_enetif_input(lpc_netifdata->netif);  à pbuf * p=lpc_low_level_input(netif);//读一个包到pbuf包中  à  netif->input(p, netif)//将数据传递给注册的input函数(即tcpip_input()函数)。

看完上面的,我们在看看我们在netif_add注册的tcpip_input();

lpc_netif.input=tcpip_input() 及网卡收到网络数据包调用该input函数指针。tcpip_input()函数会根据协议调用sys_mbox_trypost(&mbox, msg)邮箱发送函数,这个函数会将接收到的pbuf数据发给TCP/IP协议栈的处理进程处理(即阻塞的tcpip_thread进程);

看到这儿,我都感觉有点凌乱了。在重新的串一下整个流程:首先在主函数中,调用了tcpip_init()函数建立了tcpip的协议栈线程。接着又调用了net_add()函数,特别需要注意的是其两个传入的函数指针(这两个函数是在网卡驱动中实现的(在这里驱动与tcpip栈建立了联系)init参数和input参数。init()函数会调用网卡驱动的初始化函数err_t lpc_enetif_init(struct netif *netif)。在这个函数会新建两个线程,一个是网卡的接收线程(从网卡中读取一个数据包,并调用我们在netif中注册的input函数将数据包交给tcpip协议栈线程处理了),一个是网卡的发送线程(它会阻塞在一个信号量上,当有数据需要发送时,将数据发送出去)。讲到这里应该大概明白了lwip的驱动基本架构了吧!。

时间: 2024-11-09 18:14:30

lwip的架构分析(基于LPC17xx)的相关文章

lwip驱动的分析(基于LPC17XX)

首先需要说明的是这个驱动是基于LPC17XX 的芯片.很多代码会涉及到lpc17xx mac寄存器的操作. 驱动文件名:LPC18xx_43xx_emac.c 先看下结构体lpc_enetdata_t信息: /* LPC EMAC driver data structure*/ typedef struct { /* prxs must be 8 bytealigned! */ ENET_RXSTAT_Tprxs[LPC_NUM_BUFF_RXDESCS];   /*< Pointer to R

分布式MySQL数据库TDSQL架构分析

摘要:腾讯计费平台部为了解决基于内存的NoSQL解决方式HOLD平台在应对多种业务接入时的不足.结合团队在MySQL领域多年应用和优化经验,终于在MySQL存储引擎基础上,打造一套分布式SQL系统TDSQL.本文是对该系统架构分析. 腾讯计费平台部托管着公司90%以上的虚拟账户.如QB.Q点.包月服务.游戏的二级账户等,为了保证能顺畅支撑公司各大业务的实时在线交易.而且在各种灾难场景下数据是一致而且可用的,对系统的可用性.一致性切换要求很高,因此计费团队历来都很重视高一致性存储系统的建设. 到眼

人人网张铁安:Feed系统架构分析(转)

原文:http://www.csdn.net/article/2010-07-26/277273 继成功举办首期TUP活动后,日前在北京丽亭华苑酒店鸿运二厅,由CSDN和<程序员> 杂志联合策划组织的TUP第二次活动如期而至,本次活动以Web 2.0技术为主题,聚焦当下火热的社交网.微博架构与实时搜索领域.就相关领域及产品研发背后的技术.产品设计及用户体验话题为与会者提供全开放式的交流 平台.即使是付费沙龙,参会报名人数仍在不断上升,本次活动有超过300人来到现场. 人人网技术经理张铁安 以下

二、OpenStack入门 之 架构分析

OpenStack入门 之 架构分析 写在前面 学习目标: 了解 OpenStack 各组件的逻辑关系: 了解 OpenStack 的各组件的通信和部署关系: 了解 OpenStack 的工作流程: 接下来我会掌握: OpenStack 组件间的逻辑关系: OpenStack 的API: OpenStack 组件间的通信关系: OpenStack 中几种不同的存储: OpenStack 工作流程: OpenStack 的部署架构: OpenStack 各组件之间的关系有:逻辑关系,通信关系,部署

企业架构分析&设计模式 课程

高焕堂的招牌课程 企业架构分析.设计模式和App Framework/SDK开发方法 by 高焕堂 亚太地区Android技术大会 主席 洞庭国际智能硬件检测基地 & 中云企业大数据中心(IDC) 首席架构师 微博:@高焕堂_台北                                课程简介: 本课程依据企业软件开发流程里的先后环节来作教学.主要目标在于介绍和阐述各环节的思想.模式.技术和实践要点.让学员能熟悉当今云计算&大数据潮流下,终端与云端的(业务)架构分析.API设计.框

angularJS搭建简单应用程序的基本架构分析

本文以一个基于angularJS框架的简单应用分析angularJS应用的基本架构 1.理解几个基本概念 1.1 angularJS控制器 对于刚入门的童鞋来说,提到控制器可能想到了就是电器上的一些开关或者控制设备等,实际上,在JavaScript编程中也有控制器这一概念,angularJS控制器(以下简称控制器)指的是附加在文档对象模型(DOM)节点上的函数,用来驱动应用程序的逻辑.通俗的说就是把一部分的JavaScript功能(方法)封装在一个js文件中,在html文件中进行调用来实现一些功

软件开发架构分析和架构模式一

架构分析: 架构分析工作主要从宏观上考虑一个软件系统应该如何组织.通常,在架构分析工作中,我们需要确定一些策略性的设计方针,原则和基本模式.在它们的指导下,我们可以高屋建瓴地分析软件系统的宏观结构,认识软件系统由哪些组件构成,了解组件之间的接口和协作关系.架构分析的结果对于后续的面向对象设计工作也是一种约束,有助于消除设计和实现过程中的随意性.因此,架构分析有时也被称为策略设计 组件指的是一组对象构成的,有固定接口的有机体,当设计者的观察视角不同,组件的规模不同或者组件内部的封装度程度不同时,这

软件架构设计学习总结(22):软件架构——分层架构、事件驱动架构、微内核架构、微服务架构、基于空间的架构

分层架构 (Layered Architecture) 分层架构是最常见的架构,也被称为n层架构.多年以来,许多企业和公司都在他们的项目中使用这种架构,它已经几乎成为事实标准,因此被大多数架构师.开发者和软件设计者所熟知.比如MVC. 分层架构的一个特性就是 关注分离(separation of concerns) .在层中的组件只负责本层的逻辑.组件的划分很容易让它们实现自己的角色和职责,也比较容易地开发,测试管理和维护. 我们需要这样的冗余,即使业务层没有处理业务规则,也要通过业务层来调用数

OpenDaylight架构分析

基本介绍 OpenDaylight(ODL) 是一个基于SDN开发的模块化.可扩展.可升级.支持多协议的控制器框架.北向接口可扩展性强,REST型API用于松耦合应用,OSGI型用于紧耦合应用.引入SAL屏蔽不同协议的差异性.南向支持多种协议插件,如OpenFlow 1.0. OpenFlow 1.3.OVSDB.NETCONF.LISP.BGP.PCEP和SNMP等.底层支持传统交换机.纯Openflow交换机.混合模式的交换机.ODL控制平台采用了OSGI框架,实现了模块化和可扩展化,为OS