没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
uC/OS-II 平台下的 LwIP 移植笔记――作者:焦海波 2006-9-1
1 下载LwIP................................................................................................................................................................. 2
2 建立一个最基本的工程.........................................................................................................................................2
3 把LwIP加入工程.....................................................................................................................................................2
4 编写操作系统模拟层相关代码.............................................................................................................................3
4.1 操作系统模拟层移植说明――中文翻译 .................................................................................................3
4.2 编写操作系统模拟层.................................................................................................................................6
4.2.1 准备工作――建立文件、定义数据类型及其它 .........................................................................6
4.2.2 信号量操作函数.............................................................................................................................8
4.2.3 邮箱操作函数...............................................................................................................................13
4.2.4 实现sys_thread_new()函数 .......................................................................................................20
4.2.5 实现sys_arch_timeouts()函数 .................................................................................................22
4.2.6 实现临界保护函数.......................................................................................................................25
4.2.7 扫尾――结束操作系统模拟层的编写 .......................................................................................26
5 LwIP接口――初始设置及网络驱动...................................................................................................................28
5.1 准备工作――建立LwIP入口函数文件 ...................................................................................................28
5.2 __ilvInitLwIP().....................................................................................................................................29
5.3 __ilvSetLwIP().......................................................................................................................................30
5.4 ethernetif_init()――初始化底层接口 .............................................................................................35
5.4.1 ethernetif_init()函数分析.....................................................................................................35
5.4.2 low_level_output()――链路层发送函数 ...............................................................................36
5.4.3 low_level_init()――网卡初始化函数 ...................................................................................38
5.4.4 EMACInit()――网卡初始化工作的实际完成者 .......................................................................40
5.4.5 ethernetif_input()――实现接收线程 ...................................................................................47
5.4.6 low_level_input()――得到一整帧数据 .................................................................................49
5.4.7 GetInputPacketLen()――获得帧长 .........................................................................................50
5.4.8 EMACReadPacket()――复制,从接收缓冲区到pbuf ...............................................................53
5.4.9 EMACSendPacket()――发送一帧数据 .......................................................................................55
5.4.10 编译――ethernetif.c及lib_emac.c ......................................................................................56
6 ping――结束LwIP的移植...................................................................................................................................57
6.1 编译、链接整个工程...............................................................................................................................57
6.2 ping测试...................................................................................................................................................59
后记...............................................................................................................................................................................62
- 1 -
uC/OS-II 平台下的 LwIP 移植笔记――作者:焦海波 2006-9-1
本文将指导读者一步步完成 LwIP 在 ADS1.2 开发环境下的移植工作,包括底层驱动的编写。本文使用的
硬件平台是 AT91SAM7X256 + RTL8201BL(PHY),至于软件平台,读者从本文标题即可看出。我们使用 uC/OS-II
作为底层操作系统,而 LwIP 的移植亦将主要围绕 uC/OS-II 展开。好了,不再多说,开始吧……
1 下载 LwIP
很简单,到LwIP的官方网站即可:http://savannah.nongnu.org/projects/lwip/。如果你不想看看
其它内容(可能对你会很重要),就只是想得到源码,好的,直接到这个地址下载:
http://download.savannah.nongnu.org/releases/lwip/。目前官方发布的最新版本是 1.1.1,找到
lwip-1.1.1.zip,然后下载、解压缩,第一项工作完成。
2 建立一个最基本的工程
要想完成移植工作,我们必须要有一个包含 uC/OS-II 的工程才行,这一步我们就是要建立这个工程。
工程建立完毕后,编译链接没有问题,那么,第二项工作也完成了。关于如何建立一个包含 uC/OS-II 的
ADS 工程的问题,不在本文描述范围之内,这里不做讲述。随本笔记一同发布的源码文档中
LwIPPortingTest_2 文件夹下包含了这个最基本工程的源码,读者可以直接使用。我的基本工程建立的
路径是 D:\work\LwIPPortingTest,下文将以相对路径进行讲述,不再提供绝对路径。
3 把 LwIP 加入工程
首先,在\src\文件夹下,建立 LwIP 文件夹,即:\src\LwIP;然后将下载的 LwIP 源码文件中 api、
core、include、netif 文件复制到\src\LwIP\文件夹下,如下图所示:
图 3.1
然后,用 ADS 打开工程文件,按照 LwIP 源码文件的实际存放路径建立 LwIP 的工程结构,如下图所示:
- 2 -
uC/OS-II 平台下的 LwIP 移植笔记――作者:焦海波 2006-9-1
图 3.2
这里需要特别说明的是,源码中的 IP V6、SLIP 及 PPP 部分我们没有添加进来,主要是考虑我及大多数
读者的网络还是 V4,而 SLIP、PPP 暂时不在我的考虑范围之内。另外,在移植层面 V6 也和 V4 相差不多,
这里就不再讲解这部分内容了。现在基础工程结构建立完毕,可以把 LwIP 源码添加进来了。这一步很容
易,按照文件存放路径,将源码文件添加到相应的工程结构下即可。源码添加完成后的工程参见所附源
码文件的 LwIPPortingTest_3 文件夹。
4 编写操作系统模拟层相关代码
LwIP 的作者为操作系统模拟层提供了较为详细的说明,文件名为 sys_arch.txt,在 LwIP 的 doc 文
件夹下。我们的编写工作根据这个说明进行。
4.1 操作系统模拟层移植说明――中文翻译
事先声明,之所以笔者要翻译该文档,主要是笔者在撰写这篇笔记时亦没有通读该文档。笔者先前
使用的模拟层源码是杨晔大侠的。为了真正弄懂 LwIP,笔者决定自己重新实现 LwIP 的移植,本笔
记是跟随移植同步进行的,因此,翻译的文档也放在了这篇笔记中,使读者能够真正了解笔者的移
植历程。另外再说一句,这个文档是为 LwIP 0.6++版编写,笔者搜遍了整个 LwIP 官方网站,没有
发现比这更新的,笔者只好认为操作系统模拟层在 0.6++之后没有任何改动,如果有谁发现了更新
的,一定通知笔者,先谢谢了。好的,言归正传,下面就是译文:
- 3 -
uC/OS-II 平台下的 LwIP 移植笔记――作者:焦海波 2006-9-1
LwIP 0.6++ sys_arch 接口
作者:Adam Dunkels
操作系统模拟层(sys_arch)存在的目的主要是为了方便 LwIP 的移植,它在底层操作系统和
LwIP 之间提供了一个接口。这样,我们在移植 LwIP 到一个新的目标系统时,只需修改这个接口即
可。不过,不依赖底层操作系统的支持也可以实现这个接口。
sys_arch 需要为 LwIP 提供信号量(semaphores)和邮箱(mailboxes)两种进程间通讯方式(IPC)。
如果想获得 LwIP 的完整功能,sys_arch 还必须支持多线程。当然,对于仅需要基本功能的用户来
说,可以不去实现多线程。LwIP 以前的版本还要求 sys_arch 实现定时器调度,不过,从 LwIP0.5
开始,这一需求在更高一层实现。除了上文所述的 sys_arch 源文件需要实现的功能外,LwIP 还要
求用户提供几个头文件,这几个头文件包含 LwIP 使用的宏定义。下文将详细讲述 sys_arch 及头文
件的实现。
信号量即可以是计数信号量,也可以是二值信号量――LwIP 都可以正常工作。邮箱用于消息传
递,用户即可以将其实现为一个队列,允许多条消息投递到这个邮箱,也可以每次只允许投递一个
消息。这两种方式 LwIP 都可以正常运作。不过,前者更加有效。需要用户特别注意的是――投递到
邮箱中的消息只能是一个指针。
在 sys_arch.h 文件中,我们指定数据类型“sys_sem_t”表示信号量,“sys_mbox_t”表示邮箱。
至于 sys_sem_t 和 sys_mbox_t 如何表示这两种不同类型,LwIP 没有任何限制。
以下函数必须在 sys_arch 中实现:
- void sys_init(void)
初始化 sys_arch 层。
- sys_sem_t sys_sem_new(u8_t count)
建立并返回一个新的信号量。参数 count 指定信号量的初始状态。
- void sys_sem_free(sys_sem_t sem)
释放信号量。
- void sys_sem_signal(sys_sem_t sem)
发送一个信号。
- u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
等待指定的信号并阻塞线程。timeout 参数为 0,线程会一直被阻塞至收到指定的信号;非 0,
则线程仅被阻塞至指定的 timeout 时间(单位为毫秒)。在 timeout 参数值非 0 的情况下,返回值为
等待指定的信号所消耗的毫秒数。如果在指定的时间内并没有收到信号,返回值为
SYS_ARCH_TIMEOUT。如果线程不必再等待这个信号(也就是说,已经收到信号),返回值也可以为 0。
注意,LwIP 实现了一个名称与之相似的函数来调用这个函数,sys_sem_wait(),注意区别。
- sys_mbox_t sys_mbox_new(void)
建立一个空的邮箱。
- void sys_mbox_free(sys_mbox_t mbox)
释放一个邮箱。如果释放时邮箱中还有消息,它表明 LwIP 中存在一个编程错误,应该通知开发
者(原文如此,这句话很费解。个人理解的意思是:当执行 sys_mbox_free()这个函数时,按道理邮箱中不应该再
存在任何消息,如果用户使用 LwIP 时发现邮箱中还存在消息,说明 LwIP 的开发者存在一个编程错误,不能把邮箱
中的消息全部取出并处理掉。遇到这种情况,用户应该告诉 LwIP 的作者,纠正这个 bug,译注)。
- 4 -
uC/OS-II 平台下的 LwIP 移植笔记――作者:焦海波 2006-9-1
- void sys_mbox_post(sys_mbox_t mbox, void *msg)
投递消息“msg”到指定的邮箱“mbox”。
- u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
阻塞线程直至邮箱收到至少一条消息。最长阻塞时间由 timeout 参数指定(与
sys_arch_sem_wait()函数类似)。msg 是一个结果参数,用来保存邮箱中的消息指针(即*msg = ptr),
它的值由这个函数设置。“msg”参数有可能为空,这表明当前这条消息应该被丢弃。
返回值与 sys_arch_sem_wait()函数相同:等待的毫秒数或者 SYS_ARCH_TIMEOUT――如果时间溢出
的话。LwIP 实现的函数中,有一个名称与之相似的――sys_mbox_fetch(),注意区分。
- struct sys_timeouts *sys_arch_timeouts(void)
返回一个指向当前线程使用的 sys_timeouts 结构的指针。LwIP 中,每一个线程都有一个
timeouts 链表,这个链表由 sys_timeout 结构组成,sys_timeouts 结构则保存了指向这个链表的指
针。这个函数由 LwIP 的超时调度程序调用,并且不能返回一个空(NULL)值。
单线程 sys_arch 实现中,这个函数只需简单返回一个指针即可。这个指针指向保存在 sys_arch 模
块中的 sys_timeouts 全局变量。
如果底层操作系统支持多线程并且 LwIP 中需要这样的功能,那么,下面的函数必须实现:
- sys_thread_t sys_thread_new(void(*thread)(void *arg), void *arg, int prio)
启动一个由函数指针 thread 指定的新线程,arg 将作为参数传递给 thread()函数,prio 指定
这个新线程的优先级。返回值为这个新线程的 ID,ID 和优先级由底层操作系统决定。
- sys_prot_t sys_arch_protect(void)
这是一个可选函数,它负责完成临界区域保护并返回先前的保护状态。该函数只有在小的临界
区域需要保护时才会被调用。基于 ISR 驱动的嵌入式系统可以通过禁止中断来实现这个函数。基于
任务的系统可以通过互斥量或禁止任务来实现这个函数。该函数应该支持来自于同一个任务或中断
的递归调用。换句话说,当该区域已经被保护,sys_arch_protect()函数依然能被调用。这时,函
数的返回值会通知调用者该区域已经被保护。
如果你的移植正在支持一个操作系统,sys_arch_protect()函数仅仅是一个需要。
- void sys_arch_unprotect(sys_prot_t pval)
该函数同样是一个可选函数。它的功能就是恢复受保护区域的先前保护状态,先前是受到保护
还是没有受到保护由参数 pval 指定。它与 sys_arch_protect()函数配套使用,详细信息参看
sys_arch_protect()函数。
该函数的说明是按照译者个人理解的意思翻译,原文讲述不是很清楚,如有错误,欢迎批评指正,译注。
--------------------------------------------------------------------------------------
OS 支持的模拟层需要添加的头文件说明
-------------------------------------------------------------------------------------
- cc.h 与硬件平台及编译器相关的环境变量及数据类型声明文件(一些或许应该移到 sys_arch.h
文件)。
LwIP 使用的数据类型定义――u8_t, s8_t, u16_t,s16_t,u32_t,s32_t,mem_ptr_t。
- 5 -
剩余61页未读,继续阅读
fly19890114
- 粉丝: 9
- 资源: 68
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
前往页