欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > DOC文档下载  

    μC-OS-II系统基础嵌入式开发编程教程.doc

    • 资源ID:3275602       资源大小:67.50KB        全文页数:16页
    • 资源格式: DOC        下载积分:4
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要4
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    μC-OS-II系统基础嵌入式开发编程教程.doc

    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; /* 计数器(当事件是信号量时) */INT8U OSEventType; /* 时间类型 */INT8U OSEventGrp; /* 等待任务所在的组 */ OS_EVENT;.OSEventPtr 指针,只有在所定义的事件是邮箱或者消息队列时才使用。 当所定义的事件是邮箱时,它指向一个消息,而当所定义的事件是消息队列时,它指向一个数据结构,详见 6.06节消息邮箱和 6.07 节消息队列。.OSEventTbl 和 .OSEventGrp 很像前面讲到的 OSRdyTbl和 OSRdyGrp,只不过前两者包含的是等待某事件的任务,而后两者包含的是系统中处于就绪状态的任务。(见 3.04 节 就绪表).OSEventCnt 当事件是一个信号量时,.OSEventCnt 是用于信号量的计数器,(见 6.05 节信号量)。e .OSEventType 定义了事件的具体类型。它可以是信号量(OS_EVENT_SEM)、邮箱(OS_EVENT_TYPE_MBOX)或消息队列(OS_EVENT_TYPE_Q)中的一种。用户要根据该域的具体值来调用相应的系统函数,以保证对其进行的操作的正确性。下面的代码将一个任务放到事件的等待任务列表中。程序清单 L6.2 将一个任务插入到事件的等待任务列表中pevent->OSEventGrp |= OSMapTblprio >> 3;pevent->OSEventTblprio >> 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 使一个任务进入就绪状态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 = 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)OSTCBCur->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->OSTCBStat = 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 之间) ; 另一个是由等待该信号量的任务组成的等待任务表。 用户要在 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 (pevent != (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_EXIT_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); (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();if (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_ERR); 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();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 (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;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->OSEventType != 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->OSTCBStat |= 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 = 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 向邮箱中发送一条消息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 if (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_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 if (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.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();return (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 (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 *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)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(pevent); (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.ASM中的四个函数:OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()9.04.01 OSStartHighRdy()该函数由SStart()函数调用,功能是运行优先级最高的就绪任务,在调用OSStart()之前,用户必须先调用OSInit(),并且已经至少创建了一个任务(请参考OSTaskCreate()和OSTaskCreateExt()函数)。OSStartHighRdy()默认指针OSTCBHighRdy指向优先级最高就绪任务的任务控制块(OS_TCB)(在这之前OSTCBHighRdy已由OSStart()设置好了)。图F9.3给出了由函 数 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:BX+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。

    注意事项

    本文(μC-OS-II系统基础嵌入式开发编程教程.doc)为本站会员(白大夫)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开