μCOSII系统基础嵌入式开发编程教程.doc

上传人:sccc 文档编号:4854820 上传时间:2023-05-20 格式:DOC 页数:16 大小:67.50KB
返回 下载 相关 举报
μCOSII系统基础嵌入式开发编程教程.doc_第1页
第1页 / 共16页
μCOSII系统基础嵌入式开发编程教程.doc_第2页
第2页 / 共16页
μCOSII系统基础嵌入式开发编程教程.doc_第3页
第3页 / 共16页
μCOSII系统基础嵌入式开发编程教程.doc_第4页
第4页 / 共16页
μCOSII系统基础嵌入式开发编程教程.doc_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《μCOSII系统基础嵌入式开发编程教程.doc》由会员分享,可在线阅读,更多相关《μCOSII系统基础嵌入式开发编程教程.doc(16页珍藏版)》请在三一办公上搜索。

1、C/OS-II系统基础嵌入式开发编程教程C/OS-II 通过 uCOS_II.H 中定义的 OS_EVENT 数据结构来维护一个事件控制块的所有信息程序清单 L6.1,也就是本章开篇讲到的事件控制块 ECB。该结构中除了包含了事件本身的定义,如用于信号量的计数器,用于指向邮箱的指针,以及指向消息队列的指针数组等,还定义了等待该事件的所有任务的列表。typedef struct void *OSEventPtr; /* 指向消息或者消息队列的指针 */INT8U OSEventTblOS_EVENT_TBL_SIZE; /* 等待任务列表 */INT16U OSEventCnt; /* 计数器(

2、当事件是信号量时) */INT8U OSEventType; /* 时间类型 */INT8U OSEventGrp; /* 等待任务所在的组 */ OS_EVENT;.OSEventPtr 指针,只有在所定义的事件是邮箱或者消息队列时才使用。 当所定义的事件是邮箱时,它指向一个消息,而当所定义的事件是消息队列时,它指向一个数据结构,详见 6.06节消息邮箱和 6.07 节消息队列。.OSEventTbl 和 .OSEventGrp 很像前面讲到的 OSRdyTbl和 OSRdyGrp,只不过前两者包含的是等待某事件的任务,而后两者包含的是系统中处于就绪状态的任务。(见 3.04 节 就绪表).

3、OSEventCnt 当事件是一个信号量时,.OSEventCnt 是用于信号量的计数器,(见 6.05 节信号量)。e .OSEventType 定义了事件的具体类型。它可以是信号量(OS_EVENT_SEM)、邮箱(OS_EVENT_TYPE_MBOX)或消息队列(OS_EVENT_TYPE_Q)中的一种。用户要根据该域的具体值来调用相应的系统函数,以保证对其进行的操作的正确性。下面的代码将一个任务放到事件的等待任务列表中。程序清单 L6.2 将一个任务插入到事件的等待任务列表中pevent-OSEventGrp |= OSMapTblprio 3;pevent-OSEventTblpri

4、o 3 |= OSMapTblprio 程序清单 L6.3 从等待任务列表中删除一个任务if (pevent-OSEventTblprio 3 pevent-OSEventGrp 程序清单 L6.4 在等待任务列表中查找最高优先级的任务y = OSUnMapTblpevent-OSEventGrp;x = OSUnMapTblpevent-OSEventTbly;prio = (y aitListInit (OS_EVENT *pevent)INT8U i;pevent-OSEventGrp = 0x00;for (i = 0; i OSEventTbli = 0x00;程序清单 L6.6 使

5、一个任务进入就绪状态void OSEventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)OS_TCB *ptcb;INT8U x;INT8U y;INT8U bitx;INT8U bity;INT8U prio;y = OSUnMapTblpevent-OSEventGrp; (1)bity = OSMapTbly; (2)x = OSUnMapTblpevent-OSEventTbly; (3)bitx = OSMapTblx; (4)prio = (INT8U)(y OSEventTbly pevent-OSEventGrp ptcb =

6、 OSTCBPrioTblprio; (7)ptcb-OSTCBDly = 0; (8)ptcb-OSTCBEventPtr = (OS_EVENT *)0; (9)#if (OS_Q_EN ptcb-OSTCBMsg = msg; (10)#elsemsg = msg;#endifptcb-OSTCBStat (11)if (ptcb-OSTCBStat = OS_STAT_RDY) (12)OSRdyGrp |= bity; (13)OSRdyTbly |= bitx;程序清单 L6.7 使一个任务进入等待状态void OSEventTaskWait (OS_EVENT *pevent)O

7、STCBCur-OSTCBEventPtr = pevent; (1)if (OSRdyTblOSTCBCur-OSTCBY OSRdyGrp pevent-OSEventTblOSTCBCur-OSTCBY |= OSTCBCur-OSTCBBitX; (3)pevent-OSEventGrp |= OSTCBCur-OSTCBBitY;程序清单 L6.8 因为等待超时将任务置为就绪状态void OSEventTO (OS_EVENT *pevent)if (pevent-OSEventTblOSTCBCur-OSTCBY (1)pevent-OSEventGrp OSTCBCur-OSTC

8、BStat = OS_STAT_RDY; (2)OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0; (3)信号量C/OS-II 中的信号量由两部分组成:一个是信号量的计数值,它是一个 16 位的无符号整数 (0 到 65,535 之间) ; 另一个是由等待该信号量的任务组成的等待任务表。 用户要在 OS_CFG.H中将 OS_SEM_EN 开关量常数置成 1,这样C/OS-II 才能支持信号量。信号量C/OS-II 中的信号量由两部分组成:一个是信号量的计数值,它是一个 16 位的无符号整数 (0 到 65,535 之间) ; 另一个是由等待该信号量的任务组成的等待

9、任务表。 用户要在 OS_CFG.H中将 OS_SEM_EN 开关量常数置成 1,这样C/OS-II 才能支持信号量。程序清单 L6.9 建立一个信号量OS_EVENT *OSSemCreate (INT16U cnt)OS_EVENT *pevent;OS_ENTER_CRITICAL();pevent = OSEventFreeList; (1)if (OSEventFreeList != (OS_EVENT *)0) (2)OSEventFreeList = (OS_EVENT *)OSEventFreeList-OSEventPtr;OS_EXIT_CRITICAL();if (pev

10、ent != (OS_EVENT *)0) (3)pevent-OSEventType = OS_EVENT_TYPE_SEM; (4)pevent-OSEventCnt = cnt; (5)OSEventWaitListInit(pevent); (6)return (pevent); (7)程序清单 L6.10 等待一个信号量void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_SEM) (1)OS_EX

11、IT_CRITICAL();*err = OS_ERR_EVENT_TYPE;if (pevent-OSEventCnt 0) (2)pevent-OSEventCnt-; (3)OS_EXIT_CRITICAL();*err = OS_NO_ERR;6-15 else if (OSIntNesting 0) (4)OS_EXIT_CRITICAL();*err = OS_ERR_PEND_ISR; else OSTCBCur-OSTCBStat |= OS_STAT_SEM; (5)OSTCBCur-OSTCBDly = timeout; (6)OSEventTaskWait(pevent)

12、; (7)OS_EXIT_CRITICAL();OSSched(); (8)OS_ENTER_CRITICAL();if (OSTCBCur-OSTCBStat OSEventTO(pevent); (10)OS_EXIT_CRITICAL();*err = OS_TIMEOUT; else OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0; (11)OS_EXIT_CRITICAL();*err = OS_NO_ERR;程序清单 L6.11 发出一个信号量INT8U OSSemPost (OS_EVENT *pevent)OS_ENTER_CRITICAL();i

13、f (pevent-OSEventType != OS_EVENT_TYPE_SEM) (1)OS_EXIT_CRITICAL();return (OS_ERR_EVENT_TYPE);if (pevent-OSEventGrp) (2)OSEventTaskRdy(pevent, (void *)0, OS_STAT_SEM); (3)OS_EXIT_CRITICAL();OSSched(); (4)return (OS_NO_ERR); else if (pevent-OSEventCnt OSEventCnt+; (5)OS_EXIT_CRITICAL();return (OS_NO_E

14、RR); else OS_EXIT_CRITICAL();return (OS_SEM_OVF);程序清单 L6.12 无等待地请求一个信号量INT16U OSSemAccept (OS_EVENT *pevent)INT16U cnt;OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_SEM) (1)OS_EXIT_CRITICAL();return (0);cnt = pevent-OSEventCnt; (2)if (cnt 0) (3)pevent-OSEventCnt-; (4)OS_EXIT_CRITICAL()

15、;return (cnt); (5)程序清单 L6.13 查询一个信号量的状态INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)INT8U i;INT8U *psrc;INT8U *pdest;OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_SEM) (1)OS_EXIT_CRITICAL();return (OS_ERR_EVENT_TYPE);pdata-OSEventGrp = pevent-OSEventGrp; (2)psrc = pdest = for

16、 (i = 0; i c+;pdata-OSCnt = pevent-OSEventCnt; (3)OS_EXIT_CRITICAL();return (OS_NO_ERR);程序清单 L6.14 建立一个邮箱OS_EVENT *OSMboxCreate (void *msg)6-20OS_EVENT *pevent;OS_ENTER_CRITICAL();pevent = OSEventFreeList;if (OSEventFreeList != (OS_EVENT *)0) OSEventFreeList = (OS_EVENT *)OSEventFreeList-OSEventPtr;

17、OS_EXIT_CRITICAL();if (pevent != (OS_EVENT *)0) pevent-OSEventType = OS_EVENT_TYPE_MBOX; (1)pevent-OSEventPtr = msg; (2)OSEventWaitListInit(pevent);return (pevent); (3)程序清单 L6.15 等待一个邮箱中的消息void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)void *msg;OS_ENTER_CRITICAL();if (pevent-OSEvent

18、Type != OS_EVENT_TYPE_MBOX) (1)OS_EXIT_CRITICAL();*err = OS_ERR_EVENT_TYPE;return (void *)0);msg = pevent-OSEventPtr;if (msg != (void *)0) (2)pevent-OSEventPtr = (void *)0; (3)OS_EXIT_CRITICAL();*err = OS_NO_ERR; else if (OSIntNesting 0) (4)OS_EXIT_CRITICAL();*err = OS_ERR_PEND_ISR; else OSTCBCur-OS

19、TCBStat |= OS_STAT_MBOX; (5)OSTCBCur-OSTCBDly = timeout;OSEventTaskWait(pevent);OS_EXIT_CRITICAL();OSSched();OS_ENTER_CRITICAL();if (msg = OSTCBCur-OSTCBMsg) != (void *)0) (6)OSTCBCur-OSTCBMsg = (void *)0;OSTCBCur-OSTCBStat = OS_STAT_RDY;OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0;OS_EXIT_CRITICAL();*err

20、 = OS_NO_ERR; else if (OSTCBCur-OSTCBStat OSEventTO(pevent); (8)OS_EXIT_CRITICAL();msg = (void *)0; (9)*err = OS_TIMEOUT; else 6-22msg = pevent-OSEventPtr; (10)pevent-OSEventPtr = (void *)0;(11)OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0; (12)OS_EXIT_CRITICAL();*err = OS_NO_ERR;return (msg);程序清单 L6.16 向邮

21、箱中发送一条消息INT8U OSMboxPost (OS_EVENT *pevent, void *msg)OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_MBOX) (1)OS_EXIT_CRITICAL();return (OS_ERR_EVENT_TYPE);if (pevent-OSEventGrp) (2)OSEventTaskRdy(pevent, msg, OS_STAT_MBOX); (3)OS_EXIT_CRITICAL();OSSched(); (4)return (OS_NO_ERR); else i

22、f (pevent-OSEventPtr != (void *)0) (5)OS_EXIT_CRITICAL();return (OS_MBOX_FULL); else pevent-OSEventPtr = msg; (6)OS_EXIT_CRITICAL();return (OS_NO_ERR);程序清单 L6.16 向邮箱中发送一条消息INT8U OSMboxPost (OS_EVENT *pevent, void *msg)OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_MBOX) (1)OS_EXIT_CRITI

23、CAL();return (OS_ERR_EVENT_TYPE);if (pevent-OSEventGrp) (2)OSEventTaskRdy(pevent, msg, OS_STAT_MBOX); (3)OS_EXIT_CRITICAL();OSSched(); (4)return (OS_NO_ERR); else if (pevent-OSEventPtr != (void *)0) (5)OS_EXIT_CRITICAL();return (OS_MBOX_FULL); else pevent-OSEventPtr = msg; (6)OS_EXIT_CRITICAL();retu

24、rn (OS_NO_ERR);程序清单 L6.17 无等待地从邮箱中得到消息void *OSMboxAccept (OS_EVENT *pevent)void *msg;OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_MBOX) (1)OS_EXIT_CRITICAL();return (void *)0);msg = pevent-OSEventPtr; (2)if (msg != (void *)0) (3)pevent-OSEventPtr = (void *)0; (4)OS_EXIT_CRITICAL();ret

25、urn (msg); (5)程序清单 L6.18 查询邮箱的状态INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *pdata)INT8U i;6-25INT8U *psrc;INT8U *pdest;OS_ENTER_CRITICAL();if (pevent-OSEventType != OS_EVENT_TYPE_MBOX) (1)OS_EXIT_CRITICAL();return (OS_ERR_EVENT_TYPE);pdata-OSEventGrp = pevent-OSEventGrp; (2)psrc = pdest = for

26、 (i = 0; i OSMsg = pevent-OSEventPtr; (3)OS_EXIT_CRITICAL();return (OS_NO_ERR);程序清单 L6.19 使用邮箱作为二值信号量OS_EVENT *MboxSem;void Task1 (void *pdata)INT8U err;for (;) OSMboxPend(MboxSem, 0, /* 获得对资源的访问权 */6-26. /* 任务获得信号量,对资源进行访问 */.OSMboxPost(MboxSem, (void*)1); /* 释放对资源的访问权 */程序清单 L6.21 建立一个消息队列OS_EVENT

27、 *OSQCreate (void *start, INT16U size)OS_EVENT *pevent;OS_Q *pq;OS_ENTER_CRITICAL();pevent = OSEventFreeList; (1)if (OSEventFreeList != (OS_EVENT *)0) OSEventFreeList = (OS_EVENT *)OSEventFreeList-OSEventPtr; (2)OS_EXIT_CRITICAL();if (pevent != (OS_EVENT *)0) OS_ENTER_CRITICAL();pq = OSQFreeList; (3

28、)if (OSQFreeList != (OS_Q *)0) OSQFreeList = OSQFreeList-OSQPtr;OS_EXIT_CRITICAL();if (pq != (OS_Q *)0) pq-OSQStart = start; (4)pq-OSQEnd = pq-OSQIn = start;pq-OSQOut = start;pq-OSQSize = size;pq-OSQEntries = 0;pevent-OSEventType = OS_EVENT_TYPE_Q; (5)pevent-OSEventPtr = pq; (6)OSEventWaitListInit(p

29、event); (7) else OS_ENTER_CRITICAL();pevent-OSEventPtr = (void *)OSEventFreeList; (8)6-33OSEventFreeList = pevent;OS_EXIT_CRITICAL();pevent = (OS_EVENT *)0;return (pevent); (9)9.03 OS_CPU.H 文件OS_CPU.H 文件中包含与处理器相关的常量,宏和结构体的定义。程序清单L9.2是为80x86编写的OS_CPU.H文件的内容。9.04 OS_CPU_A.ASMC/OS-II 的移植需要用户改写OS_CPU_A.

30、ASM中的四个函数:OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()9.04.01 OSStartHighRdy()该函数由SStart()函数调用,功能是运行优先级最高的就绪任务,在调用OSStart()之前,用户必须先调用OSInit(),并且已经至少创建了一个任务(请参考OSTaskCreate()和OSTaskCreateExt()函数)。OSStartHighRdy()默认指针OSTCBHighRdy指向优先级最高就绪任务的任务控制块(OS_TCB)(在这之前OSTCBHighRdy已由OSStart()设置好了)。图F9.3给出了由函

31、 数 OSTaskCreate() 或 OSTaskCreateExt() 创 建 的 任 务 的 堆 栈 结 构 。 很 明 显 ,OSTCBHighRdy-OSTCBStkPtr指向的是任务堆栈的顶端。程序清单L 9.3 OSStartHighRdy()._OSStartHighRdy PROC FARMOV AX, SEG _OSTCBHighRdy ; 载入 DSMOV DS, AX ;LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy-OSTCBStkPtr(1)MOV SS, ES:BX+2 ;MOV SP, ES:B

32、X+0 ;POP DS ; 恢复任务环境 (2)POP ES ; (3)POPA ; (4);IRET ; 运行任务 (5)_OSStartHighRdy ENDP9.05 OS_CPU_C.CC/OS-II 的移植需要用户改写OS_CPU_C.C中的六个函数:OSTaskStkInit()OSTaskCreateHook()OSTaskDelHook()OSTaskSwHook()OSTaskStatHook()OSTimeTickHook()OSTaskResume ()的返回值为下述之一:? OS_NO_ERR:函数调用成功。? OS_TASK_RESUME_PRIO:要唤醒的任务不存在。? OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。? OS_PRIO_INVALID:参数指定的优先级大于或等于 OS_LOWEST_PRIO。OS_MAX_EVENTS 定义系统中最大的事件控制块的数量。系统中的每一个消息邮箱,消息队列,信号量都需要一个事件控制块。例如,系统中有 10 个消息邮箱,5 个消息队列,3 个信号量,则 OS_MAX_EVENTS 最小应该为 18。只要程序中用到了消息邮箱,消息队列或是信号量,则 OS_MAX_EVENTS 最小应该设置为 2。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号