云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > 李晨曦 - 嵌入式系统开发毕业论文

李晨曦 - 嵌入式系统开发毕业论文

  • 62 次阅读
  • 3 次下载
  • 2025/5/4 10:58:46

第1章 绪论

图4-2 Lwip中的定时事件表的结构

函数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,&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 &null_timeouts; }

return &lwip_timeouts[offset]; }

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的值,

-21-

第1章 绪论 从而使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; }

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->next == NULL ||

t->next->time > timeout->time) { if (t->next != NULL) {

t->next->time -= timeout->time; }

timeout->next = t->next; t->next = timeout; break; } } } }

函数sys_untimeout从当前任务定时事件链表中删除一个定时事件 void sys_untimeout(sys_timeout_handler h, void *arg) {

struct sys_timeouts *timeouts; struct sys_timeout *prev_t, *t; timeouts = sys_arch_timeouts(); if (timeouts->next == NULL) {

-22-

第1章 绪论 return; }

for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {

if ((t->h == h) && (t->arg == arg)) {

/* We have a match */

/* Unlink from previous in list */ if (prev_t == NULL)

timeouts->next = t->next; else

prev_t->next = t->next;

/* If not the last one, add time of this one back to next */ if (t->next != NULL)

t->next->time += t->time;

memp_free(MEMP_SYS_TIMEOUT, t); return; } }

return; }

4.“mbox”的实现: mbox的创建

sys_mbox_t sys_mbox_new(void) {

u8_t ucErr;

PQ_DESCR pQDesc;

//从消息队列内存分区中得到一个内存块

pQDesc = OSMemGet( pQueueMem, &ucErr ); if( ucErr == OS_NO_ERR ) { //创建一个消息队列

pQDesc->pQ=OSQCreate(&(pQDesc->pvQEntries[0]), MAX_QUEUE_ENTRIES ); if( pQDesc->pQ != NULL ) { return pQDesc; } }

return SYS_MBOX_NULL; }

发一条消息给”mbox”

const void * const pvNullPointer = 0xffffffff;

void sys_mbox_post(sys_mbox_t mbox, void *data) {

INT8U err; if( !data )

data = (void*)&pvNullPointer; err= OSQPost( mbox->pQ, data);

-23-

第1章 绪论 }

在ucos中,如果OSQPost (OS_EVENT *pevent, void *msg)中的msg==NULL 会返回一条OS_ERR_POST_NULL_PTR错误.而在lwip中会调用sys_mbox_post(mbox,NULL)发送一条空消息,我们在本函数中把NULL变成一个常量指针0xffffffff. 从”mbox”中读取一条消息

#define SYS_ARCH_TIMEOUT 0xffffffff

void sys_mbox_fetch(sys_mbox_t mbox, void **msg) {

u32_t time;

struct sys_timeouts *timeouts; struct sys_timeout *tmptimeout; sys_timeout_handler h; void *arg; again:

timeouts = sys_arch_timeouts(); //返回当前任务定时事件链表起始指针 if (!timeouts || !timeouts->next) { //如果定时事件链表为空 sys_arch_mbox_fetch(mbox, msg, 0); //无超时等待消息 } else {

if (timeouts->next->time > 0) {

//如果超时事件链表不为空,而且第一个超时事件的time !=0

//带超时等待消息队列,超时时间等于超时事件链表中第一个超时事件的time, time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);

/*在后面分析中可以看到sys_arch_mbox_fetch调用了ucos中的OSQPend系统调用从消息队列中读取消息.*/

//如果”mbox”消息队列不为空,任务立刻返回,否则任务进入阻塞态.

/*需要重点说明的是sys_arch_mbox_fetch的返回值time:如果sys_arch_mbox_fetch*/ //因为超时返回,time=SYS_ARCH_TIMEOUT, //如果sys_arch_mbox_fetch因为收到消息而返回,

//time = 收到消息时刻的时间-执行sys_arch_mbox_fetch时刻的时间,单位是毫秒 //由于在ucos中任务调用OSQPend系统调用进入阻塞态,到收到消息重新开始执行 //这段时间没有记录下来,所以我们要简单修改ucos的源代码.(后面我们会看到). } else {

/*如果定时事件链表不为空,而且第一个定时事件的time ==0,表示该事件的定时*/ //时间到

time = SYS_ARCH_TIMEOUT; }

if (time == SYS_ARCH_TIMEOUT) { //一个定时事件的定时时间到 tmptimeout = timeouts->next;

timeouts->next = tmptimeout->next; h = tmptimeout->h; arg = tmptimeout->arg;

memp_free(MEMP_SYS_TIMEOUT, tmptimeout);

//从内存中释放该定时事件,并执行该定时事件中的函数 if (h != NULL) { h(arg);

-24-

搜索更多关于: 李晨曦 - 嵌入式系统开发毕业论文 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

第1章 绪论 图4-2 Lwip中的定时事件表的结构 函数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;

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com