ucos+lwip应用心得
邮箱中的消息 sys_sem_t sys_sem_new(u8_t count)//创建一个信号量 void sys_sem_free(sys_sem_t sem)//释放并删除一个信号量 void sys_sem_signal(sys_sem_t sem)//发送一个信号量 void sys_sem_wait(sys_sem_t sem)//等待一个信号量 void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)//设置一个超时事件 void sys_untimeout(sys_timeout_handler h, void *arg)//删除一个超时事件 … 关于操作系统封装层的信息可以阅读lwip的doc目录下面的sys_arch.txt.文件. 2.2 Lwip在ucos上的移植. 2.2.1 系统初始化 sys_int必须在tcpip协议栈任务tcpip_thread创建前被调用. #define MAX_QUEUES 20 #define MAX_QUEUE_ENTRIES 20 typedef struct { OS_EVENT* pQ;//ucos中指向事件控制块的指针 void* pvQEntries[MAX_QUEUE_ENTRIES];//消息队列 //MAX_QUEUE_ENTRIES消息队列中最多消息数 } TQ_DESCR, *PQ_DESCR; typedef PQ_DESCR sys_mbox_t;//可见lwip中的mbox其实是ucos的消息队列 static char pcQueueMemoryPool[MAX_QUEUES * sizeof(TQ_DESCR) ]; void sys_init(void) { u8_t i; s8_t ucErr; pQueueMem = OSMemCreate( (void*)pcQueueMemoryPool, MAX_QUEUES, sizeof(TQ_DESCR), %26;amp;ucErr );//为消息队列创建内存分区 //init lwip task prio offset curr_prio_offset = 0; //init lwip_timeouts for every lwip task //初始化lwip定时事件表,具体实现参考下面章节 for(i=0;i 函数sys_arch_timeouts返回对应于当前任务的指向定时事件链表的起始指针.该指针存在 lwip_timeouts[MAX_LWIP_TASKS]中. struct sys_timeouts null_timeouts; struct sys_timeouts * sys_arch_timeouts(void) { u8_t curr_prio; s16_t err,offset; OS_TCB curr_task_pcb; null_timeouts.next = NULL; //获取当前任务的优先级 err = OSTaskQuery(OS_PRIO_SELF,%26;amp;curr_task_pcb); curr_prio = curr_task_pcb.OSTCBPrio; offset = curr_prio - LWIP_START_PRIO; //判断当前任务优先级是不是tcp/ip相关任务,优先级5-9 if(offset 0 || offset >= LWIP_TASK_MAX) { return %26;amp;null_timeouts; } return %26;amp;lwip_timeouts[offset]; } 注意:杨晔大侠移植的代码在本函数有一个bug.杨晔大侠的移植把上面函数中的OS_TCB curr_task_tcb定义成了全局变量,使本函数成为了一个不可重入函数.我也是在进行如下测试时发现了这个bug.我的开发板上设置的ip地址是 192.168.1.95.我在windows的dos窗口内运行 ping 192.168.1.95 –l 2000 –t,不间断用长度为2000的数据报进行ping测试,同时使用tftp客户端软件给192.168.1.95下载一个十几兆程序,同时再使用 telnet连接192.168.1.95端口7(echo端口),往该端口写数测试echo功能. 在运行一段时间以后,开发板进入不再响应.我当时也是经过长时间的分析才发现是因为在低优先级任务运行ys_arch_timeouts()时被高优先级任务打断改写了curr_task_tcb的值,从而使sys_arch_timeouts返回的指针错误,进而导致系统死锁.函数 sys_timeout给当前任务增加一个定时事件: void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg) { struct sys_timeouts *timeouts; struct sys_timeout *timeout, *t; timeout = memp_malloc(MEMP_SYS_TIMEOUT);//为定时事件分配内存 if (timeout == NULL) { return; } timeout->next = NULL; timeout->h = h; timeout->arg = arg; timeout->time = msecs; timeouts = sys_arch_timeouts();//返回当前任务定时事件链表起始指针 if (timeouts->next == NULL) {//如果链表为空直接增加该定时事件 timeouts->next = timeout; return; } //如果链表不为空,对定时事件进行排序.注意定时事件中的time存储的是本事件 //时间相对于前一事件的时间的差值 if (timeouts->next->time > msecs) { timeouts->next->time -= msecs; timeout->next = timeouts->next; timeouts->next = timeout; } else { for(t = timeouts->next; t != NULL; t = t->next) { timeout->time -= t->time; if (t->nex
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
