搜索
bottom↓
回复: 9

请问下谁知道UCOS2任务控制块结构,被弄晕了,它到底有几个链表的,都是如何的,望高手们指

[复制链接]

出0入0汤圆

发表于 2010-5-11 09:54:09 | 显示全部楼层 |阅读模式
本人最近刚学习UCOS2,看邵贝贝翻译的那本书,看任务控制块部分被搞晕了,以为比较容易上手的,结果一来就受到沉重的打击,哪位高手指导下

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2010-5-11 10:01:06 | 显示全部楼层
979 //初始化任务控制块TCB(优先级指针、栈顶指针、栈底指针、任务标志符、堆栈容量、扩展指针、选择项)
980 INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size,
981 void *pext, INT16U opt)
982 {
983 #if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3
984 OS_CPU_SR cpu_sr;
985 #endif
OS_TCB *ptcb; //定义一个PCB变量
987
988
989 OS_ENTER_CRITICAL(); //关闭中断
990 ptcb = OSTCBFreeList; //分配一个空任务控制块给ptcb
991 if (ptcb != (OS_TCB *)0) { //如果缓冲池有空余TCB,这个TCB被初始化
992 OSTCBFreeList = ptcb->OSTCBNext; //指向TCB的双向链接的后链接
993 OS_EXIT_CRITICAL(); //打开中断
994 ptcb->OSTCBStkPtr = ptos; //指向当前TCB的栈顶指针(输入的数据)
995 ptcb->OSTCBPrio = (INT8U)prio; //保存当前TCB的优先级别(输入的数据)
996 ptcb->OSTCBStat = OS_STAT_RDY; //设定当前TCB的状态字(内容为(准备完毕))
997 ptcb->OSTCBDly = 0; //允许任务等待的最大字节节拍为0
998
999 #if OS_TASK_CREATE_EXT_EN > 0 //允许生成OSTaskCreateExt()函数
1000 ptcb->OSTCBExtPtr = pext; //指向用户定义的任务控制块(扩展指针)
1001 ptcb->OSTCBStkSize = stk_size; //设定堆栈的容量
1002 ptcb->OSTCBStkBottom = pbos; //指向指向栈底的指针
1003 ptcb->OSTCBOpt = opt; //保存OS_TCB的选择项
1004 ptcb->OSTCBId = id; //保存任务标志符
1005 #else //否则使用旧的参数
1006 pext = pext; //扩展指针
1007 stk_size = stk_size; //堆栈的容量
1008 pbos = pbos; //栈底的指针
1009 opt = opt; //选择项
1010 id = id; //任务标志符
1011 #endif
1012
1013 #if OS_TASK_DEL_EN > 0 //允许生成 OSTaskDel() 函数代码函数
1014 ptcb->OSTCBDelReq = OS_NO_ERR; //如果可以删除任务本身,可以从每个
1015 //OS_TCB中节省出一个布尔量
1016 #endif
1017 //对一些参数提前运算,为了节省CPU的操作事件
1018 ptcb->OSTCBY = prio >> 3;
1019 ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
1020 ptcb->OSTCBX = prio & 0x07;
1021 ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
1022
1023 #if OS_EVENT_EN > 0 //如果不打算在应用程序中使用各类事件
1024 ptcb->OSTCBEventPtr = (OS_EVENT *)0; //OS_TCB中OSTCBEventPt就不会出现
1025 #endif //针对的事件为信号量,互斥型信号量、消息邮箱、消息队列
1026 //当满足 版本大于2.51 且 事件标志允许 且 有最大事件标志 及 允许删除任务
1027 #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0)
1028 ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;//则向事件标志节点的指针被初始化为空指针
1029 #endif
1030
1031 #if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
1032 ptcb->OSTCBMsg = (void *)0; //满足以上条件,指向传递给任务的消息指针为0空指针
1033 #endif
1034
1035 #if OS_VERSION >= 204 //如果版本大于2.04
1036 OSTCBInitHook(ptcb); //允许使用OSTCBInitHook(ptcb)函数,可对其加代码
1037 #endif //主要增加OS_TCB扩展,浮点运算、MMU寄存器、与任务相关内容,调用此程序时中断开着的
1038
1039 OSTaskCreateHook(ptcb); //调用户建立任务钩子程序
1040 //该函数能够扩展[OSTaskCreate()或OSTaskCreateExt()函数]
1041 //当OS_CPU_HOOKS_EN为1时,OSTaskCreateHook()可以在OS_CPU.C中定义
1042 //若OS_CPU_HOOKS_EN为0时,则可以在任何其它地方定义
1043 //调用此程序时中断开着的。
1044 OS_ENTER_CRITICAL();////////////////////////////////////////////////
1045 OSTCBPrioTbl[prio] = ptcb;
1046 ptcb->OSTCBNext = OSTCBList;
ptcb->OSTCBPrev = (OS_TCB *)0;
1048 if (OSTCBList != (OS_TCB *)0) {//这中间理解不了,觉得是任务控制块链表太多了,不知道结构如何的,被弄晕了
1049 OSTCBList->OSTCBPrev = ptcb;   //HelpHelpHelpHelpHelpHelpHelpHelpHelpHelpHelpHelpHelpHelpHelpHelp
1050 }
1051 OSTCBList = ptcb; //让该任务进入就绪态/////////////////////////////
1052 OSRdyGrp |= ptcb->OSTCBBitY;
1053 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
1054 OS_EXIT_CRITICAL(); //打开中断
1055 return (OS_NO_ERR); //调用成功,最后让此函数返回到调用函数[OSTaskCreate()或
1056 } //OSTaskCreateExt()函数],返回值表示分配到任务控块,并初始化了
1057 OS_EXIT_CRITICAL(); //打开中断
1058 return (OS_NO_MORE_TCB); //没有更多的任务控制块被分配,将无法创建新的任务
1059 }

出0入0汤圆

发表于 2010-5-11 11:42:36 | 显示全部楼层
看这本书吧(任哲《嵌入式实时操作系统μC\OS-Ⅱ原理及应用》),讲得非常详细,适合初学者看。

       贝贝翻译的那本书适合有一定基础并且了解的OS-II的读者。


http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3894112&bbs_page_no=1&search_mode=3&search_text=BA_WANG_MAO&bbs_id=3004

出0入0汤圆

 楼主| 发表于 2010-5-11 13:05:27 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2010-5-11 13:36:55 | 显示全部楼层
学习ucos暂时告一段落了,
以前一直以为邵贝贝的那本是最佳教程,现在看来  邵的那本更像是一本UC/OS的白皮书,不适合初学者当教材的
书中大段大段的都是源码分析,初学者却不知道这些内容究竟是用来干什么的,所以有些糊里糊涂的感觉


任哲的那本初学要好一点,都是实例,学过后你清除的明白了OS是干什么的,该怎么用,此时如果你要想知道OS是如何实现这些操作的,
这时候邵的那本书就派上用场了(本人手头又邵的那本也有英文第一版的,觉得个别语言翻译的很生硬,有些专有名词翻译的不统一
比如睡眠态--休眠态,等待态---挂起态,还有一些地方我对比这原文分析了下,不知道是个人理解问题还是他翻译的有些问题,看前言中该书大部分是其研究生翻译的,还是有些怀疑的,尽信书不如无书嘛)

出0入0汤圆

 楼主| 发表于 2010-5-14 10:24:41 | 显示全部楼层
谢谢4楼的经验之谈,我也去买任哲编写的那本书

出0入0汤圆

 楼主| 发表于 2010-5-14 10:49:08 | 显示全部楼层
void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
321 {
322 #if OS_CRITICAL_METHOD == 3
323 OS_CPU_SR cpu_sr;
324 #endif
void *msg; //定义消息队列的指针、取出的暂存指针
326 OS_Q *pq; //定义一个队列事件
327
328
329 if (OSIntNesting > 0) { //中断嵌套数>0时,表示还有中断任务在运行
330 *err = OS_ERR_PEND_ISR; //试图从中断调用该函数
331 return ((void *)0); //返回空(0)
332 }
333 #if OS_ARG_CHK_EN > 0 //所有参数在指定的范围之内
334 if (pevent == (OS_EVENT *)0) { //当信号量指针为NULL,即0(空)
335 *err = OS_ERR_PEVENT_NULL; //pevent是空指针
336 return ((void *)0); //返回
337 }
338 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { //当事件类型不否是消息队列类型
339 *err = OS_ERR_EVENT_TYPE; //'pevent'不是指向消息队列的指针
340 return ((void *)0); //返回空(0)
341 }
342 #endif
343 OS_ENTER_CRITICAL(); //关闭中断
pq = (OS_Q *)pevent->OSEventPtr; //队列指针=当前事件指针
345 if (pq->OSQEntries != 0) { //当前消息队列中消息数 > 0,有消息
346 msg = *pq->OSQOut++; //OSQOut将对应的地址的消息复制到msg
347 pq->OSQEntries--; //当前队列消息数减1
348 if (pq->OSQOut == pq->OSQEnd) { //当取出指针=最高消息队列单元时
349 pq->OSQOut = pq->OSQStart; //取出指针跳转到起始单元
350 }
351 OS_EXIT_CRITICAL(); //打开中断
352 *err = OS_NO_ERR; //消息被正确的接受
353 return (msg); //返回消息暂存(数据)指针
354 } // 无消息
355 OSTCBCur->OSTCBStat |= OS_STAT_Q; //将事件进入睡眠状态,由消息队列唤醒
356 OSTCBCur->OSTCBDly = timeout; //等待时间置入任务控制中
357 OS_EventTaskWait(pevent); //使任务进入等待消息队列状态
358 OS_EXIT_CRITICAL(); //打开中断
359 OS_Sched(); //任务调度函数,调用一个就绪的高优先级任务运行
360 OS_ENTER_CRITICAL(); //关闭中断
361 msg = OSTCBCur->OSTCBMsg; //接收消息=指向当前任务的消息指针
362 if (msg != (void *)0) { //检查消息是否为空
363 OSTCBCur->OSTCBMsg = (void *)0; //传递给消息的指针为空
364 OSTCBCur->OSTCBStat = OS_STAT_RDY; //表示任务处于就绪状态
365 OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; //指向事件控制块的指针=0
366 OS_EXIT_CRITICAL(); //打开中断
367 *err = OS_NO_ERR; //成功等待消息队列
368 return (msg); //返回消息暂存(数据)指针
369 }
370 OS_EventTO(pevent); //如果没有获得消息,由于等待起始时间
371 OS_EXIT_CRITICAL(); //打开中断
372 *err = OS_TIMEOUT; //消息没有在指定的时间送到
373 return ((void *)0); //返回0
374 }
375 /*$PAGE*/􀀀
376 /*
377 *************************************************************************************************

出0入0汤圆

 楼主| 发表于 2010-5-14 10:50:39 | 显示全部楼层
346 msg = *pq->OSQOut++; //OSQOut将对应的地址的消息复制到msg
谁能解释下pq前面为什么还要加个*,pq本来就是个消息队列指针,觉得不应该加*,
谁能解释下

出0入0汤圆

 楼主| 发表于 2010-5-14 15:09:43 | 显示全部楼层
那么多点击怎么没有人回答

出0入0汤圆

发表于 2010-5-28 10:49:15 | 显示全部楼层
我的经验是首先是全局把握,像一些语法方面的问题可以先放放,我也是年初才开始接触uCOS,现在已经成功移植到F2812,正在完善控制程序。
源码一定要读,这样才能理解uCOS的精髓。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 17:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表