基于32位处理器的网络驱动及协议栈研究

时间:2022-09-03 03:03:27

基于32位处理器的网络驱动及协议栈研究

摘 要: 随着嵌入式Web的飞速发展,以Internet为中间环节使不同嵌入式设备进行通信的需求日益强烈,特别是在工业监控领域。采用项目组自行研发的内嵌有MAC模块的定制版32位处理器作为硬件平台,以此为基础设计了基于描述符的DMA传输机制的网络驱动。同时,为了实现稳定数据通信及Web浏览器功能,对嵌入式TCP/IP协议栈LwIP进行了无操作系统移植,并对协议栈内部的数据管理方式及底层接口进行详细分析。测试结果表明,LwIP协议栈适用于工业远程监控,能够在实现稳定通信的同时兼顾速度与小内存消耗。

关键词: LwIP 协议栈; 网络驱动; 嵌入式系统; 片上可编程系统

中图分类号: TN915.04?34; TM417 文献标识码: A 文章编号: 1004?373X(2016)19?0011?05

Abstract: With the rapid development of the embedded Web, the communication demand among different embedded devices through the Internet becomes increasingly intense, especially in the industrial monitoring field. The customized 32?bit processor embedding MAC module was taken as the hardware platform, which was developed by the project group itself. And on this basis, the network drive of descriptor?based DMA transfer mechanism was designed. In order to realize the functions of stable data communication and Web browser, the protocol stack LwIP of the embedded TCP/IP was performed with transplantation without operating system. The data management method and bottom?layer port inside the protocol stack are analyzed in detail. The test results show that the LwIP is suitable for the the industrial remote monitoring, and can realize stable communication while ensuring the high speed and low memory consumption.

Keywords: LwIP; network drive; embedded system; programmble system on chip

0 引 言

嵌入式设备正在深度改变人们的日常生活与社会生产,小到生活中的各式智能家电,大到国防军用航空航天设备。嵌入式Internet正在覆盖更多的终端设备,而在众多Internet通信协议中TCP/IP协议是目前运用次数最多,应用范围最广的一种标准协议[1]。基于上述特点,本文旨在为某研究所定制一款具有自主知识产权的定制版32位处理器,要求具备网络访问功能,能实现实时通信。此款处理器主要用于远程工业控制,有低功耗、实时通信的特点[2]。

1 硬件验证板卡设计

系统采用32位处理器,工作在100 MHz主频,拥有256 KB的指令和数据内存以及32 KB的系统内存。它还包括:片上PLL,16通道、12位、5 MSPS ADC,10M/100M RMII接口的MAC,定时器,看门狗,64个GPIO,UART,SPI,I2C,LPC等多种功能丰富的外设,本芯片采用SMIC 0.13 μm工艺,144TQFP封装。

为了验证SoC芯片的性能和各个功能模块,设计了一个硬件验证板卡,如图1所示。该板卡拥有完备的电源解决方案、复位管理和外设支持,满足系统工作需求;设计有基于SPI总线的FLASH存储器,基于I2C总线的E2PROM;拥有温度测量模块、以太网模块,对外的串口通信模块,用于验证各个模块的功能;另外,测试板卡将处理器的各个管脚引出,能够同时满足裸片测试和封装后的成品芯片测试。

处理器内部集成有MAC模块,需要一个PHY接口与以太网进行连接。在硬件板卡设计中,使用RMII接口进行通信的LAN8720搭建以太网通信模块。

2 协议层网络接口设计

底层网络接口的设计包括协议层与驱动层两部分内容,其中协议层的设计与协议本身的关系较为密切,包括了协议栈的初始化及网络接口相关内容的初始化,这一部分的编写具有可移植性,而驱动层的设计则与硬件驱动更为接近,需根据不同网络设备分别进行设计[3]。协议栈的入口函数为lwip_init_task,所有与协议栈移植相关的文件都由此开始,此函数结构如图2所示。

网络接口的设置,首先需要设置网关、IP地址及子网掩码,而后根据网络接口情况通过nerif_add函数设置网络接口信息。在本工程中只使用一个网络接口,因此只需添加一个netif即可。函数netif_add的主要功能就是添加新的接口并设置该接口的netif信息,指定注册函数,因此首先为当前网口申请全局netif结构体[4]。

3 驱动层LwIP接口的设计与实现

3.1 网卡驱动设计实现

3.1.1 网卡的数据存储

在网卡驱动编写时最核心的部分是数据的存储与传输方式。在SoC设计中,根据需求MAC被集成在处理器中。但在实际编程设置过程中仍可将MAC部分看做一个独立芯片,其同CPU之间的数据交换也与其他网卡芯片和主机间的数据传递并无太大出入[5]。在MAC同CPU进行数据交换时,不论是发送还是接收都需要使用到描述符链表及数据缓冲区。以发送为例,描述符与数据缓冲区被同时存储在系统共享RAM中,数据缓冲区储存着需要被发送的数据,而描述符则相当于一个指针指向被描述的数据缓冲区。

描述符有两种不同的构造形式,即链型与环形。但不论是哪种构造形式,在RAM中都以相同的特殊寄存器形式存在,且一帧数据可占用多个描述符,但一个描述符仅能描述一帧数据。对于链型描述符而言,其第二个数据缓冲区用作指针指向下一个描述符。在环形结构中,相邻两个描述符之间的距离是在状态寄存器CSR0中提前设置的,因此第二个缓冲区也能够存储数据。但由于环形结构的自身特点,当使用这种形式描述数据时,主机必须提供至少两个串联好的描述符以供识别。描述符的首地址需存储在状态寄存器中,CSR3存放接收描述符地址,CSR4则用于发送。本文中接收与发送数据缓冲区都是用链型描述符。

发送与接收数据的过程有一些不同,在发送过程中,主机通过改变OWN位将第一个描述符交给MAC,由MAC发送其所指向的数据。同时主机依然保持对下一个描述符的所有权,这样可以给主机准备第二包数据的时间。而在接收过程中则相对简单,通常来说描述符都由MAC掌握,除非此时主机为挂起状态。

发送数据FIFO最多可存放两帧的数据,这两帧中包括当前正在等待发送的那一帧。而接收数据FIFO最多可存放四帧数据,这四帧中包括正在传输的那一帧[6]。不论是发送还是接收数据的流向总是在数据接口、FIFO及MII接口之间进行,只是方向相反。实际上在向PHY发送或接收数据时使用的接口为RMII,但作为MII的子分类,本文统一使用MII进行描述。

3.1.2 内部操作流程

(1) DMA控制器

数据在网卡与主机间通过DMA传输,这样可以有效地避免多次内存拷贝带来的时间及内存开销,大大提高了数据的传输效率。同时DMA可以通过CSR0.1位被设置为两种模式:当此位置1时,接收与发送享有同等的优先级,DMA以轮询的方式交替服务于二者之间;当设置为0时,若非当前正在发送则接收的优先级将高于发送,但不论接收还是发送进程阻塞时间都不得多于两次。每次通过DMA传输时的数据传输量也可以设为单字传输或自定义宽度传输,这里使用初始化设置,不定义最大宽度,因此由传输FIFO的大小来决定。

(2) 发送流程

发送过程共有三种状态,包括运行、暂停及挂起。停止状态只在软件及硬件复位或收到暂停命令时才会发生。在发送正常运行时,会按描述符指向的数据顺序进行传输,此时若发送进程被挂起,发送流程将停留在下一描述符的位置,当再次运行时会从当前指向的描述符继续进行。而一旦进入发送流程,除非主机改写了CSR4,即保存发送链表基地址的寄存器,则基地址寄存器将保持为提取下一个描述符地址的状态。因此对CSR4进行改写时MAC必须为暂停状态。

(3) 接收流程

与发送过程类似,接收过程也分为三种状态,包括运行、暂停及挂起。在软、硬件复位及收到暂停命令时,发送将会暂停直到下次运行命令到来。当进入发送状态时,MAC从接收描述符列表上获取描述符且无论是否在链路上有等待被接收的数据。若当前没有任何一帧数据待接收,则MAC保持等待状态,一旦有效帧出现接收过程则正式开始将数据填入当前描述符所指向的缓冲区。当此帧数据传输结束或数据缓冲区已满,当前描述符中的OWN位将被清零用来表示当前描述符已被关闭。与此同时,下一个准备好的描述符将被获取,数据会继续填充缓冲区。

3.1.3 网卡驱动设计

在开始实际的网卡驱动程序编写前,首先需要进行头文件Nmac.h的编写。这个文件规范了后续所有寄存器的操作,将所涉及到的寄存器编写为结构体[7]。其中每个寄存器的每一位被独立定义,这样一来在后续的寄存器操作中,可隐藏按位读写带来的程序不易读不易改等问题。

网卡的所有控制状态寄存器,如表1所示。可直接由主机进行操作,且每个寄存器都为32位,4字节对齐,因此在头文件中首先将这12个寄存器集合成结构体。

接收描述符被分为4个32位数RDES0~RDES3,其中RDES2与RDES3存放接收缓冲区的地址。但根据选用链式或环形结构的不同选择,RDES3分别存放下一个描述符的地址或接收缓冲区地址。RDES0的最高位是所有权位,其他位为状态控制位。

与接收描述符相同,发送描述符同样以4个32位数存放,其定义与接收描述符一起在初始化MAC时完成,但区别于接收描述符,为了节省内存发送描述符仅定义一个,循环使用。描述符在程序中的描述方式与寄存器及每位的操作与之前提到的寄存器相同,但在接收描述符中增加了pbuf项,方便存储,MAC从PHY中接收到数据包后就直接将被发送至主机。由于使用的芯片为定制芯片,因此需要先对网卡进行测试,在测试正常后再进行LwIP的后续移植。

网卡驱动的编写主要有两个部分包括初始化函数和中断处理函数。初始化函数MAC_Init首先分别初始化收发描述符,均使用链型结构。其中接收描述符设为一个数组,其中包含两个描述符,互为首尾,为了节省内存,发送描述符只设置一个。在描述符初始化时,需同时设置好数据缓冲区,并将缓冲区的地址赋值给RDES3,RDES2则指向下一个描述符或置0,其流程如图3所示。

由于接收与发送共用一个中断,因此当中断产生时需先对其类型进行判断。CSR5为状态寄存器,其中CSR5.7为接收中断状态位表示有一帧数据已被接收,而CSR5.0则为发送中断状态位代表数据已发送完成。其流程如图4所示。

3.2 头文件移植与数据准备

3.2.1 内部数据类型定义

头文件cc.h最主要的功能在于它需要根据编译器和处理器定义协议栈中所需的数据类型。此外,也会完成一些相关的宏及大小端等的定义。通常来说,在C语言的语言体系下,struct会自动4字节对齐。然而在协议栈中这一做法却会导致无法读取对应长度的数据,因此需要增加关键词packed取消对齐[8],这里值得注意的是,在不同编译器版本下此关键词可能会有变化。此外,还需定义大小端及错误代码,这里根据处理器选择小端,使用arch.h中LwIP内核自带的错误代码。

3.2.2 配置文件

LwIP在设计之初就为用户提供了便捷的配置方案,这个文件位于LwIP的源码目录下,即“opt.h”。在“opt.h”中定义了包括buffer大小、数量、TCP窗口大小等一系列关键配置数据作为默认选项。当然为方便起见用户也可根据自身的需求进行更改,因此就有了“lwipopts.h”文件,在这个文件中定义的数据将会覆盖“opt.h”中的默认设置,其他位在“lwipopts.h”中的设置项则会沿用“opt.h”中的配置。由于“opt.h”中的默认设置采取了能使LwIP正常运行的最小值。所以当硬件平台性能相对较弱时可直接沿用“opt.h”作为配置文件,这也就是选用默认配置的主要原因,但实际上可保留“lwipopts.h”用做选项开关便于调试。

3.3 LwIP底层移植

3.3.1 网络接口初始化

low_level_init是LwIP在文件ethernetif.c中给出的第一个函数框架,它主要完成对网卡的初始化定义,此外还根据网卡的特点,对LwIP中的网络接口管理结构体netif中一些与网卡有关的参数进行定义。其中设置的参数包括网卡MAC地址长度,网卡MAC地址,最大传输包大小,广播、ARP、网络接口链路使能。

同时还在函数中引用Mac_Init对网卡进行初始化,由于加入了LwIP的内存管理内容,因此还需对测试版的Mac_Init函数进行修改。用数组代替的收发内存替换为动态申请的数据包pBuf中的payload,这样在程序开始运行后,首先就为接收数据申请出了两块缓冲区。同时,由于需要对接收到的数据进行一些必要的预处理,还在原有的描述符中增加了Pbuf,即指向缓冲区的指针。

3.3.2 数据发送数据

low_level_output函数接收由IP层传入的数据,并将数据传入MAC。此时并不需要确认数据长度是否大于64 B,网卡会根据其长度自动调节。由于需要增加pbuf的引用次数,因此为了防止在计数时发生中断导致计数错误,需将中断进行临时关闭,计数后开启。low_level_output会将承载有数据的数据缓冲区指针传递给网卡发送函数Mac_Copyout,并将数据写入已在初始化时就申请好的描述符中进行发送。发送结束时会触发发送中断,使程序继续执行。中断结束后将当前的缓冲区pbuf释放,则发送流程结束。

3.3.3 数据接收

接收线程的起始点由接收中断开始,由于不能长期占用中断,当发现为接收中断时就会立即跳出中断进入数据处理函数RX_Processing,其流程如图5所示。

4 协议栈功能测试

4.1 Ping测试

Ping程序是一个专门测试主机是否可正常通信的测试程序,此程序首先向主机发送ARP请求,若得到正常响应后再向主机发送ICMP报文并请求应答,因此Ping命令若能够得到正常响应,则代表ARP,ICMP及IP协议工作正常。

4.2 Echo协议测试

Echo协议即应答协议,该协议作用于应用层,主要用于对TCP协议进行测试。首先需要在LwIP协议栈初始化后增加Echo的初始化,对TCP进行监听,此后使用telnet命令,测试端口为自定义端口,端口号为2000。通过实验可得telnet命令的输出结果,给键盘输入任意字母并显示,屏幕中将输出该字母,即TCP正常工作,Echo协议可以正常运行。

4.3 Web测试

该测试板在投入使用后可能需要增加Web浏览功能,还需进行Web功能的测试。在此次测试中使用了由LwIP提供的socket接口编写的HTTP程序进行测试,建立一个Web服务器。在浏览器中输入测试板的IP地址后若能够正常显示测试页面则具备Web浏览功能。通过对该测试板进行简单的网页浏览,表明测试板具备Web浏览功能。

4.4 速度及内存占用测试

网络通信速度达到2.19 MB/s,即17.52 Mb/s符合速度要求。实际上本芯片的MAC核能够实现百兆网的技术指标,但受限于处理器的响应速度,因此仅能达到2.19 MB/s。

由于测试板内存有限,需对程序进行结构优化,删除部分不常用的如SNMP,DNS,DHCP等功能。同时通过减少如pbuf预留个数等自定义项,以达到减少内存消耗的目的。其量化结果可在当前工程的编译记录文件tb.map中获得。其中P1显示的数值为程序代码所占用空间的大小,而P2为程序的内存消耗总值。同时,还可以根据该文件查看各部分内存消耗的大小,以此进行程序的剪裁。

程序的内存消耗情况中标出的部分即为总消耗值约13 KB,小于要求数值。其中消耗内存最多的为memp,这部分的内存消耗主要由数据存储产生,在程序中pbuf大小及个数的申请留有大量余量,因此在实际工作中可根据数据传输量的大小做出相应调整,内存消耗还有很大的减少空间。

5 结 论

通过移植研究TCP/IP协议栈LwIP,将TCP/IP协议栈与嵌入式设备结合起来,使项目组自行开发的32位定制处理器实现了网络通信功能,并提出了一种基于无操作系统移植LwIP的方法,为使用自制处理器为内核的硬件平台提供了技术方案。

参考文献

[1] 厉鲁卫,包建荣,蒋苗林,等.基于ARM嵌入式Web服务器的研究与设计[J].计算机工程与设计,2004,25(5):757?760.

[2] 张毅,赵国锋.嵌入式Internet的几种接入方式比较[J].重庆邮电学院学报(自然科学版),2002,14(4):83?86.

[3] 孔栋,郑建宏.嵌入式TCP/IP协议栈LwIP在ARM平台上的移植与应用[J].通信技术,2008,41(6):38?40.

[4] 张旭,高强,张芳.TCP/IP协议栈在嵌入式系统中的移植实现[J].科技资讯,2008(12):93.

[5] 张翠,邓志良.LwIP协议栈在μC/OS?Ⅱ上的移植和应用[J].微计算机信息,2010,26(8):84?85.

[6] 陈鹏.基于通用架构的一体化红外图像信息处理器设计[J].现代电子技术,2016,39(3):39?42.

[7] 苏勇辉.基于ARM微处理器TCP/IP协议栈LwIP实现[J].国外电子测量技术,2009,28(10):76?78.

[8] 钟达,郭伟,习勇,等.基于SB3500多核处理器的软件无线电系统设计[J].现代电子技术,2014,37(21):5?8.

上一篇:关于高职院校《ERP沙盘模拟》课程教学的几点思... 下一篇:浅析经济新常态下邮政企业内部审计的职能作用