当前位置:首页 > 单片机 > 单片机
[导读] 内容摘要:结合ez80和ARM7两种系统上的具体实现,说明了如何在嵌入式实时操作系统uC/0SII上移植实现LwIP这套TCP/IP协议栈,使uC/0S II成为支持网络的RTOS。 1 引言 随着嵌入式系统与网络的日益结合,

内容摘要:结合ez80和ARM7两种系统上的具体实现,说明了如何在嵌入式实时操作系统uC/0SII移植实现LwIP这套TCP/IP协议栈,使uC/0S II成为支持网络的RTOS。

1 引言

随着嵌入式系统与网络的日益结合,在嵌入式实时操作系统中引入TCP/IP协议栈,以支持嵌入式设备接入网络,成为嵌入式领域重要的研究方向。uC/0S II是近年来发展迅速的一个开放源码实时操作系统,但它只是一个实时的任务调度及通信内核,缺少对外围设备和接口的支持,如没有文件系统、网络协议、图形界面。笔者在多个嵌入式项目的开发过程中,以开源TCP/IP协议栈LwIP为基础,给uC/0S II加上了网络支持。下面就以uC/0S II +LwIP分别在8位MCU ez80和32位MCU ARM7TDMI上的实现为例进行说明。

需要说明的是,笔者使用的ez80系统是Zilog公司的ez80190开发板,自带网络芯片。而ARM7系统是使用笔者参与开发的Skyeye,一个基于GDB的ARM7TDMI指令级软件仿真器。Skyeye小组最近为Skyeye加上了软件模拟的Ne2k兼容网络芯片,可以运行带网络支持的μcLinux和uC/0S II。以下的全部相关程序和代码都可以在Skyeye网站(hpclab.cs.tsinghua.edu.cn/~skyeye/)下载。

2 基于uC/0S II的网络平台概述

嵌入式操作系统uC/0S II是一个公开源代码的占先式多任务的微内核RTOS,其性能和安全性可以与商业产品竞争。uC/0S II的特点可以概括为以下几个方面:公开源代码,代码结构清晰、明了,注释详尽,组织有条理,可移植性好。可裁剪,可固化。内核属于抢占式,最多可以管理60个任务。uC/0S II自1992年的第一版(uC/0S)以来已经有好几百个应用,是一个经实践证明好用且稳定可靠的内核。目前国内对uC/0S II的研究和应用都很多。

TCP/IP是Internet的基本协议,以其实用性、高效性已经成为事实上的工业标准。嵌入式设备要与Internet网络直接交换信息,就必须支持TCP/IP协议。目前嵌入式设备上TCP/IP方案有很多种,但面向低端应用的开源嵌入式网络平台还很少见。

uC/0S II是一个富有开放色彩的RTOS,只要买一本书就可获得源代码,对学校和教育的使用完全免费,商业应用的费用相对也很低。但是它目前的一些第三方TCP/IP支持都是完全商业化的,用户需要付费才能获得,很少给出源代码,这影响了uC/0S II的研究和推广。通过把开放源代码的TCP/IP协议栈LwIP移植到uC/0S II上来,就获得了一套可免费研究、学习的嵌入式网络软件平台。

3 开源TCP/IP协议栈LwIP简介

LwIP是瑞士计算机科学院(Swedish InSTitute of Computer Science)的Adam Dunkels等开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。LwIP的含义是Light Weight(轻型)IP协议。LwIP可以移植到操作系统上,也可以在无操作系统的情况下独立运行。LwIP TCP/IP实现的重点是在保持TCP协议主要功能的基础上减少对RAM的占用,一般它只需要几十K的RAM和40K左右的ROM就可以运行,这使LwIP协议栈适合在低端嵌入式系统中使用。

LwIP的特性如下:

(1) 支持多网络接口下的IP转发

(2) 支持ICMP协议

(3) 包括实验性扩展的的UDP(用户数据报协议)

(4) 包括阻塞控制,RTT估算和快速恢复和快速转发的TCP(传输控制协议)

(5) 提供专门的内部回调接口(Raw API)用于提高应用程序性能

(6) 可选择的Berkeley接口API(多线程情况下)

我们目前使用的是LwIP的最新稳定版V0.5.3。有关LwIP的详细内容,可以参考其代码和网站上的文档。

4 LwIP在uC/0S II下的实现

4.1 概述

LwIP协议栈在设计时就考虑到了将来的移植问题,因此把所有与硬件、OS、编译器相关的部份独立出来,放在/SRC/arch目录下。因此LwIP在uC/0S II上的实现就是修改这个目录下的文件,其它的文件一般不应该修改。下面分几部份分别说明相应文件的实现原理和过程。具体的代码限于篇幅没有给出,Skyeye网站上有完整的代码和说明。

4.2 与CPU或编译器相关的include文件

/src/arch/include/arch目录下CC.h、CPU.h、perf.h中有一些与CPU或编译器相关的定义,如数据长度,字的高低位顺序等。这应该与用户实现uC/0S II时定义的数据长度等参数是一致的。

#define BYTE_ORDER LITTLE_ENDIAN //ARM7默认为小端存储系统

//数据类型长度的定义

typedef unsigned char u8_t;

typedef signed char s8_t;

typedef unsigned short u16_t;

typedef signed short s16_t;

typedef unsigned int u32_t;

typedef signed int s32_t;

此外还有一点:一般情况下C语言的结构体struct是4字节对齐的,但是在处理数据包的时候,LwIP使用的是通过结构体中不同数据的长度来读取相应的数据的,所以,一定要在定义struct的时候使用_PACked关键字,让编译器放弃struct的字节对齐。LwIP也考虑到了这个问题,所以,在它的结构体定义中有几个PACKED_FIELD_xxx宏,默认的时候这几个宏都是空的,可以在移植的时候添加不同的编译器所对应的_packed关键字。比如在Skyeye(ARM7)上对应gcc编译器的定义:

#define PACK_STRUCT_FIELD(x) x __attribute__((packed))

#define PACK_STRUCT_STRUCT __attribute__((packed))

#define PACK_STRUCT_BEGIN

#define PACK_STRUCT_END

4.3 sys_arch操作系统相关部份

sys_arch.[ch]中的内容是与OS相关的一些结构和函数,主要可以分为四个部份:

(1) sys_sem_t 信号量

LwIP中需要使用信号量通信,所以在sys_arch中应实现信号量结构体和处理函数:

struct sys_sem_t

sys_sem_new() //创建一个信号量结构

sys_ sem _free() //释放一个信号量结构

sys_ sem _signal() //发送信号量

sys_ arch_sem _wait() //请求信号量

由于uC/0SII已经实现了信号量OS_EVENT的各种操作,并且功能和LwIP上面几个函数的目的功能是完全一样的,所以只要把uC/0SII的函数重新包装成上面的函数,就可以直接使用了。

(2) sys_mbox_t 消息

LwIP使用消息队列来缓冲、传递数据报文,因此要在sys_arch中实现消息队列结构sys_mbox_t,以及相应的操作函数:


sys_mbox_new() //创建一个消息队列

sys_mbox_free() //释放一个消息队列

sys_mbox_post() //向消息队列发送消息

sys_arch_mbox_fetch() //从消息队列中获取消息


uC/0SII同样实现了消息队列结构OSQ及其操作,但是uC/0SII没有对消息队列中的消息进行管理,因此不能直接使用,必须在uC/0SII的基础上重新实现。为了实现对消息的管理,我们定义了以下结构:

typedef struct {

OS_EVENT* pQ;

void* pvQEntries[MAX_QUEUE_ENTRIES];

} sys_mbox_t;

在以上结构中,包括OS_EVENT类型的队列指针(pQ)和队列内的消息(pvQEntries)两部分,对队列本身的管理利用uC/0SII自己的OSQ操作完成,然后使用uC/0SII中的内存管理模块实现对消息的创建、使用、删除回收,两部分综合起来形成了LwIP的消息队列功能。

(3) sys_arch_timeout 函数

LwIP中每个与外界网络连接的线程都有自己的timeout属性,即等待超时时间。这个属性表现为每个线程都对应一个sys_timeout结构体队列,包括这个线程的timeout时间长度,以及超时后应调用的timeout函数,该函数会做一些释放连接,回收资源的工作。如果一个线程对应的sys_timeout为空(NULL),说明该线程对连接做永久的等待。

timeout结构体已经由LwIP自己在sys.h中定义好了,而且对结构体队列的数据操作也由LwIP负责,我们所要实现的是如下函数:

struct sys_timeouts * sys_arch_timeouts(void)

这个函数的功能是返回目前正处于运行态的线程所对应的timeout队列指针。timeout队列属于线程的属性,因此是OS相关的函数,只能由用户实现。

(4) sys_thread_new 创建新线程

LwIP可以是单线程运行,即只有一个tcpip线程(tcpip_thread),负责处理所有的tcp/ucp连接,各种网络程序都通过tcpip线程与网络交互。但LwIP也可以多线程运行,以提高效率,降低编程复杂度。这时就需要用户实现创建新线程的函数:

void sys_thread_new(void (* thread)(void *arg), void *arg);

在uC/0S II中,没有线程(thread)的概念,只有任务(Task)。它已经提供了创建新任务的系统API调用OSTaskCreate,因此只要把OSTaskCreate封装一下,就可以实现sys_thread_new。需要注意的是LwIP中的thread并没有uC/0S II中优先级的概念,实现时要由用户事先为LwIP中创建的线程分配好优先级。

4.4 lib_arch中库函数的实现

LwIP协议栈中用到了8个外部函数,这些函数通常与用户使用的系统或编

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭