Ucos_II2.52 源码中文译注
作者: 钟常慰
Ucos_II2.52 是一份非常完美的嵌入式开发系统,在学习ARM 的基础上,嵌入ucos 系统
并增加自己的源码是一件不错的选择,目前在市面上已经有了大量的ucos 嵌入案例,特别
是在arm 和dsp 的应用当中,已经成为一种主流,虽然和其它的嵌入式系统相比,ucos 不
是很完善,如没有内存分配、任务级别不多;但却是一个代码简短、条理清晰、实时性及安
全性能很高的嵌入式操作系统。
Ucos_II2.52 对比2.8 版的256 个任务而言,任务数量相比过少,但却是目前应用量最大
的一个版本,相对而言,能够满足我们的基本要求,而且增加了很多消息处理,特别是在优
先级别方面,具有不可比拟的优势;我曾试图阅读ecos 的源码,但还是失败了,还有挑战
linux0.01 版源码的想法,最终我不能不被屈服;对于Ucos 而言,很多入门者是一个福音,
因为它的代码非常的少,而且能够对应贝贝老师的书本直接参考,他的书本对结构方面讲解
的极为xian 详细。
在学习Ucos 的整个过程中,E 文的理解是一个致命的打击,原因是我的E 文水平很差,
不过Ucos 还是给了我尝试的动力,在作者的原基础上增加中文译码,也许是一件非常不错
的选择,相信在中国和我这种水平的人多不胜数,中文的注解对源码而言,能够具有极高的
理解价值,可以在极短的时间内,能够充分了解ucos 的真正含义。
整个翻译过程历时4 个月,每每在寒冬腊月坐在计算机前面,不断的查阅贝贝老师的书来对
整个Ucos 进行理解,对每个源码进行逐条翻译,也是一件非常需要勇气的事情,但E 文的
翻译过程中很多变量是不能完全理解的,所以在翻译过程中不乏错误译文很多,于此带来的
错误还请读者纠正,相信克服种种困难一定会有所了解的。
对于经济窘迫的我来说,曾试图希望卖一点资料来养家糊口,但这种做法根本不现实,
很多的读者可能和我一样,习惯了拿不收费的资料,并对变相收费有一种深恶痛绝的感觉;
想了很多决定还是把它贡献出来,让更多的人来(更容易)了解ucos,贡献自己的一点力
量。
希望更多的人能加入这种高尚的学习氛围当中来,共同的来把一套完整的U 系列源码译文
早一日与我们分享,祝愿大家能够早日实现自己的梦想。
=====================
文件已经上传。
====================
按说消息队列是存放消息的,消息队列维护两个指针,消息队列头和尾部,而且构成了循环的队列。
还要记录插入和取出消息的位置。
记录消息队列中消息的数目。
还有个单元数目,这个把我搞晕了。队列中到底存放的是啥?
/*
309 *********************************************************************************************************
310 * 消息队列数据 (MESSAGE QUEUE DATA)
311 *********************************************************************************************************
312 */
313 /*
314 队列控制块是一个用于维护消息队列信息的数据结构,它包含了以下的一些域。这里,仍然在各个变量前加入
315 * 一个[.]来表示它们是数据结构中的一个域。
316 * 1).OSQPtr: 在空闲队列控制块中链接所有的队列控制块。一旦建立了消息队列,该域就不再有用了。
317 * 2).OSQStart: 是指向消息队列的指针数组的起始地址的指针。用户应用程序在使用消息队列之前必须先定义该数组
。
318 * 3).OSQEnd: 是指向消息队列结束单元的下一个地址的指针。该指针使得消息队列构成一个循环的缓冲区。
319 * 4).OSQIn: 是指向消息队列中插入下一条消息的位置的指针。当.OSQIn和.OSQEnd相等时,.OSQIn被调整指向
320 * 消息队列的起始单元。
321 * 5).OSQOut: 是指向消息队列中下一个取出消息的位置的指针。当.OSQOut和.OSQEnd相等时,.OSQOut被调整指
322 * 向消息队列的起始单元。
323 * 6).OSQSize: 是消息队列中总的单元数。该值是在建立消息队列时由用户应用程序决定的。在uC/OS-II中,该值最
324 * 大可以是65,535。
325 * 7).OSQEntries: 是消息队列中当前的消息数量。当消息队列是空的时,该值为0。当消息队列满了以后,该值和
326 * .OSQSize值一样。 在消息队列刚刚建立时,该值为0。
327 */
328 #if OS_Q_EN > 0
329 typedef struct os_q { // 定义一个OS_Q队列控制块
330 struct os_q *OSQPtr; // 1)
331 void **OSQStart; // 2)
332 void **OSQEnd; // 3)
333 void **OSQIn; // 4)
334 void **OSQOut; // 5)
335 INT16U OSQSize; // 6)
336 INT16U OSQEntries; // 7)
337 } OS_Q;
338
339
340 typedef struct { // 定义一个消息队列数据(OS_Q_DATA)结构
341 void *OSMsg; // 如果消息队列中有消息,它包含指针
342 INT16U OSNMsgs; // 是消息队列中的消息数
343 INT16U OSQSize; // 是消息队列的总的容量
344 INT8U OSEventTbl[OS_EVENT_TBL_SIZE];
345 INT8U OSEventGrp; //和OSEventTbl[]一起结合,是消息队列的等待任务列表
346 } OS_Q_DATA;
347 #endif
任务控制块,TCB和TCB是按照双向链表存储的,TCB栈顶和栈底都有指针。
堆栈的容量。其他的关于任务的细节,貌似TCB中并没有涉及。
/*
378 *********************************************************************************************************
379 * 任务控制块 (TASK CONTROL BLOCK)
380 *********************************************************************************************************
381 */
382
383 typedef struct os_tcb {
384 OS_STK *OSTCBStkPtr; //当前TCB的栈顶指针
385
386 #if OS_TASK_CREATE_EXT_EN > 0 //允许生成OSTaskCreateExt()函数
387 void *OSTCBExtPtr; //指向用户定义的任务控制块(扩展指针)
388 OS_STK *OSTCBStkBottom; //指向指向栈底的指针
389 INT32U OSTCBStkSize; //设定堆栈的容量
390 INT16U OSTCBOpt; //保存OS_TCB的选择项
391 INT16U OSTCBId; //否则使用旧的参数
392 #endif
393
394 struct os_tcb *OSTCBNext; //定义指向TCB的双向链接的后链接
395 struct os_tcb *OSTCBPrev; //定义指向TCB的双向链接的前链接
396
397 #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)
398 //当以上各种事件允许时
399 OS_EVENT *OSTCBEventPtr; //定义指向事件控制块的指针
400 #endif
401
402 #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
403 void *OSTCBMsg; //满足以上条件,定义传递给任务的消息指针
404 #endif
405
406 #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
407 #if OS_TASK_DEL_EN > 0
408 OS_FLAG_NODE *OSTCBFlagNode; //定义事件标志节点的指针
409 #endif
410 OS_FLAGS OSTCBFlagsRdy; //定义运行准备完毕的任务控制块中的任务?
411 #endif
412
413 INT16U OSTCBDly; //定义允许任务等待时的最多节拍数
414 INT8U OSTCBStat; //定义任务的状态字
415 INT8U OSTCBPrio; //定义任务的优先级
416
417 INT8U OSTCBX; //定义指向任务优先级的低3位,即=priority&0x07
418 INT8U OSTCBY; //定义指向任务优先级的高3位,即=priority>>3 右移三位,前三位是0,就能指向前三位了?
419 INT8U OSTCBBitX; //定义低3位就绪表对应值(0~7),即=OSMapTbl[priority&0x07]
420 INT8U OSTCBBitY; //定义高3位就绪表对应值(0~7),即=OSMapTbl[priority>>3]
421
422 #if OS_TASK_DEL_EN > 0 //允许生成 OSTaskDel() 函数代码函数
423 BOOLEAN OSTCBDelReq; //定义用于表示该任务是否须删除
424 #endif
425 } OS_TCB;