μCOS-II中OS_SEM.C源码中文注释版.doc_第1页
μCOS-II中OS_SEM.C源码中文注释版.doc_第2页
μCOS-II中OS_SEM.C源码中文注释版.doc_第3页
μCOS-II中OS_SEM.C源码中文注释版.doc_第4页
μCOS-II中OS_SEM.C源码中文注释版.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

xilentz的网络文摘博客园 首页 新随笔 联系 订阅 管理 随笔 - 204 文章 - 0评论 - 10trackbacks - 0 OS_SEM.C/* uC/OS-II* The Real-Time Kernel* SEMAPHORE MANAGEMENT* (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL* All Rights Reserved* File : OS_SEM.C* By : Jean J. Labrosse*/ #ifndef OS_MASTER_FILE#include includes.h#endif #if OS_SEM_EN 0/* ACCEPT SEMAPHORE接受信号量* Description: This function checks the semaphore to see if a resource is available or, if an event* occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the* resource is not available or the event did not occur.* Arguments : pevent is a pointer to the event control block* Returns : 0 if the resource is available or the event did not occur the semaphore is* decremented to obtain the resource.* = 0 if the resource is not available or the event did not occur or,* if pevent is a NULL pointer or,* if you didnt pass a pointer to a semaphore*/ #if OS_SEM_ACCEPT_EN 0INT16U OSSemAccept (OS_EVENT *pevent)#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif INT16U cnt; #if OS_ARG_CHK_EN 0 if (pevent = (OS_EVENT *)0) /* Validate pevent */ return (0); if (pevent-OSEventType != OS_EVENT_TYPE_SEM) /* Validate event block type */ return (0); #endif OS_ENTER_CRITICAL(); cnt = pevent-OSEventCnt; if (cnt 0) /* See if resource is available */ pevent-OSEventCnt-; /* Yes, decrement semaphore and notify caller */ OS_EXIT_CRITICAL(); return (cnt); /* Return semaphore count */#endif /*$PAGE*/ /* CREATE A SEMAPHORE* Description: This function creates a semaphore.* Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is* available (or no event has occurred). You initialize the semaphore to a* non-zero value to specify how many resources are available (e.g. if you have* 10 resources, you would initialize the semaphore to 10).* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the* created semaphore* = (void *)0 if no event control blocks were available 建立一个信号量描述:建立一个信号量参数:cnt:信号量的初始化值,如果为零,则没有信号量可用(或者没有事件发生) 用非零值初始化信号量则显示它有多少可用资源,如果你有十个 资源,则初始化信号量为10返回:!= (void *)0 指向事件控制块结合建立的信号量的指针* = (void *)0 如果没有可用事件控制块*/ OS_EVENT *OSSemCreate (INT16U cnt)#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif OS_EVENT *pevent; if (OSIntNesting 0) /* See if called from ISR . */ return (OS_EVENT *)0); /* . cant CREATE from an ISR */ /中断服务子程序不能调用此函数,所有建立信号弹量的工作必须在任务级 /代码中或者多任务启动前完成 OS_ENTER_CRITICAL(); pevent = OSEventFreeList; /* Get next free event control block */ /从空余事件控制块链表中获得一个事件控制块ECB if (OSEventFreeList != (OS_EVENT *)0) /* See if pool of free ECB pool was empty */如果成功获得,则调整空余事件控制块链表。使之指向下一个空余的事件控制块 OSEventFreeList = (OS_EVENT *)OSEventFreeList-OSEventPtr; OS_EXIT_CRITICAL(); if (pevent != (OS_EVENT *)0) /* Get an event control block */ /如果得到的事件控制块可用,就将其的事件类型设置成信号量, pevent-OSEventType = OS_EVENT_TYPE_SEM; pevent-OSEventCnt = cnt; /* Set semaphore value */ /将信号量的初始值存入事件控制块ECB中。 pevent-OSEventPtr = (void *)0; /* Unlink from ECB free list */ /将.OSEventPtr初始化为NULL,因为它不于属于空余事件控制块链表了。 OS_EventWaitListInit(pevent); /* Initialize to nobody waiting on sem. */ /对等待任务列表进行初始化,因为信号量正在初始化,这时没有任何 /任务等待该信号量,所以函数将.OSEventGrp()和.OSEventTbl清零 return (pevent);/返回调用函数一个指向事件控制块ECB的指针 /*$PAGE*/ /* DELETE A SEMAPHORE* Description: This function deletes a semaphore and readies all tasks pending on the semaphore.* Arguments : pevent is a pointer to the event control block associated with the desired* semaphore.* opt determines delete options as follows:* opt = OS_DEL_NO_PEND Delete semaphore ONLY if no task pending* opt = OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting.* In this case, all the tasks pending will be readied.* err is a pointer to an error code that can contain one of the following values:* OS_NO_ERR The call was successful and the semaphore was deleted* OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR* OS_ERR_INVALID_OPT An invalid option was specified* OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore* OS_ERR_EVENT_TYPE If you didnt pass a pointer to a semaphore* OS_ERR_PEVENT_NULL If pevent is a NULL pointer.* Returns : pevent upon error* (OS_EVENT *)0 if the semaphore was successfully deleted.* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of* the semaphore MUST check the return code of OSSemPend().* 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless* they check pevent to see that its a NULL pointer.* 3) This call can potentially disable interrupts for a long time. The interrupt disable* time is directly proportional to the number of tasks waiting on the semaphore.* 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in* applications where the semaphore is used for mutual exclusion because the resource(s)* will no longer be guarded by the semaphore. 删除一个信号量描述:删除一个信号量参数:pevent:指向事件控制块结合目标信号量的指针 opt:决定删除选项:* opt = OS_DEL_NO_PEND 没有任务挂起的时候才删除。* opt = OS_DEL_ALWAYS 即使有任务等待也删除信号量,这种情况下, 所有挂起的任务将就绪* err 可能包含指下信息的错误代码的指针* OS_NO_ERR 调用成功,信号量删除* OS_ERR_DEL_ISR 如果想从中断服务子程序中删除信号量* OS_ERR_INVALID_OPT 指定了不合理的选项* OS_ERR_TASK_WAITING 一个或者多个任务在信号量中等待* OS_ERR_EVENT_TYPE 没有传递指针到信号量* OS_ERR_PEVENT_NULL 如果 pevent是一个空指针*备注:删除信号量之前,必须首先删除操作该信号量的所有任务*/ #if OS_SEM_DEL_EN 0OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif BOOLEAN tasks_waiting; if (OSIntNesting 0) /* See if called from ISR . */ *err = OS_ERR_DEL_ISR; /* . cant DELETE from an ISR */ return (pevent); /是不是在ISR中调用#if OS_ARG_CHK_EN 0 if (pevent = (OS_EVENT *)0) /* Validate pevent */ *err = OS_ERR_PEVENT_NULL; return (pevent);/非法的pevent if (pevent-OSEventType != OS_EVENT_TYPE_SEM) /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return (pevent);/不是事件块类型 #endif OS_ENTER_CRITICAL(); if (pevent-OSEventGrp != 0x00) /* See if any tasks waiting on semaphore */ /如果有任务在等待 tasks_waiting = TRUE; /* Yes */ else tasks_waiting = FALSE; /* No */ switch (opt) /删除选项 case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */如果只有没有任务等待的时候才删除 if (tasks_waiting = FALSE) /真没有任务等待 pevent-OSEventType = OS_EVENT_TYPE_UNUSED;/将事件控制块标记为未用,并退回到 /空余ECB中,此操作允许该事件控制块用于建立另一信号量 pevent-OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ /原空闲表头变成老二了。 OSEventFreeList = pevent; /* Get next free event control block */ /pevent指向新的空闲表头 OS_EXIT_CRITICAL(); *err = OS_NO_ERR;/返回无错 return (OS_EVENT *)0); /* Semaphore has been deleted */ else /如果有任务等待 OS_EXIT_CRITICAL(); *err = OS_ERR_TASK_WAITING; return (pevent); case OS_DEL_ALWAYS: /* Always delete the semaphore */ /无论如何都要删除 while (pevent-OSEventGrp != 0x00) /* Ready ALL tasks waiting for semaphore */ OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /使所有等待的任务就绪 pevent-OSEventType = OS_EVENT_TYPE_UNUSED;/标记为未用 pevent-OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ /原空闲表头变成老二了。 OSEventFreeList = pevent; /* Get next free event control block */ /pevent指向新的空闲表头 OS_EXIT_CRITICAL(); if (tasks_waiting = TRUE) /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ /有任务等待的话,因为有任务就绪,所以要任务调度 *err = OS_NO_ERR; return (OS_EVENT *)0); /* Semaphore has been deleted */ default:/其它非法选项 OS_EXIT_CRITICAL(); *err = OS_ERR_INVALID_OPT; return (pevent); #endif /*$PAGE*/ /* PEND ON SEMAPHORE* Description: This function waits for a semaphore.* Arguments : pevent is a pointer to the event control block associated with the desired* semaphore.* timeout is an optional timeout period (in clock ticks). If non-zero, your task will* wait for the resource up to the amount of time specified by this argument.* If you specify 0, however, your task will wait forever at the specified* semaphore or, until the resource becomes available (or the event occurs).* err is a pointer to where an error message will be deposited. Possible error* messages are:* OS_NO_ERR The call was successful and your task owns the resource* or, the event you are waiting for occurred.* OS_TIMEOUT The semaphore was not received within the specified* timeout.* OS_ERR_EVENT_TYPE If you didnt pass a pointer to a semaphore.* OS_ERR_PEND_ISR If you called this function from an ISR and the result* would lead to a suspension.* OS_ERR_PEVENT_NULL If pevent is a NULL pointer.* Returns : none 等待一个信号量描述:等待一个信号量参数:pevent:指向事件控制块结合目标信号量的指针 timeout:定时超时选项(以时钟节拍为单位),如果非零,你的任务将等待 /资源的时间值就是这个参数,如果为零,将永远等待直到资源变成可用(或者其它事件发生) err 指向错误代码的消息指针 * 消息为: * * OS_NO_ERR 调用成功,任务拥有资源或者目标事件发生 * OS_TIMEOUT 规定时间内信号量没有发生 * OS_ERR_EVENT_TYPE 如果没有传递指针到信号量 * OS_ERR_PEND_ISR 如果ISR调用此函数,结果将异常 * OS_ERR_PEVENT_NULL 如果 pevent 是一个空指针 */ void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif if (OSIntNesting 0) /* See if called from ISR . */ *err = OS_ERR_PEND_ISR; /* . cant PEND from an ISR */ return; /是不是在ISR中调用#if OS_ARG_CHK_EN 0 if (pevent = (OS_EVENT *)0) /* Validate pevent */ *err = OS_ERR_PEVENT_NULL; return; /非法的pevent if (pevent-OSEventType != OS_EVENT_TYPE_SEM) /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return; /不是事件块类型#endif OS_ENTER_CRITICAL(); if (pevent-OSEventCnt 0) /* If sem. is positive, resource available . */ pevent-OSEventCnt-; /* . decrement semaphore only if positive. */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return; /如果信号量有效,则信号量计数值递减,返回无错给调用它的函数,如果此/函数用于等待一共享资源的信号量,那么通过返回此值,知道代码是否正确运行。/如果信号量的计数值为0,则调用此函数的任务将进入睡眠状态,等待另一个任务/或者ISR发出信号量。 /* Otherwise, must wait until event occurs */ OSTCBCur-OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */资源不可用,挂起任务 OSTCBCur-OSTCBDly = timeout; /* Store pend timeout in TCB */保存挂起定时到TCB OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */使任务等待事件发生(将任务挂起) OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready */ /由于得不到信号量,当前任务不再处于就绪状态,任务调度,让下一个 /优先级最高的任务运行。这样,调用此函数的任务被挂起,直到信号量出现, /才能继续运行。 OS_ENTER_CRITICAL(); if (OSTCBCur-OSTCBStat & OS_STAT_SEM) /* Must have timed out if still waiting for event*/再次检查任务控制块中的状态标志,是否仍处于等待信号量的状态,如果是,/则说明该任务并没有被此函数发出的信号量唤醒;而实际上该任务是因为等待/超时,而被TimeTick()函数置为就绪态。 OS_EventTO(pevent);/等待事件超时,将任务从等待列表中删除,让任务继续运行。 OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* Indicate that didnt get event within TO */返回超时错误代码 return;/超时了 OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0;/将指向信号量ECB的指针从该任务的任务控制块中删除 OS_EXIT_CRITICAL(); *err = OS_NO_ERR;/*$PAGE*/ /* POST TO A SEMAPHORE* Description: This function signals a semaphore* Arguments : pevent is a pointer to the event control block associated with the desired* semaphore.* Returns : OS_NO_ERR The call was success

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论