信号量有两种类型:一种是只有0和1两种值的信号量,称为二值信号量,主要用于“独占式共享资源”的管理(例如:串行端口、打印机等);另一种是可以有多种值的信号量,称为计数式信号量。计数式信号量的值的大小取决于信号量的数据类型,如若是8位整型变量,则其值可以是0~255;若是16位整型变量,则其值可以是0~65535。
μC/OS-II的信号量由两个部分组成:一个是信号量的计数值,范围是0~65535;另一个是由等待该信号量的任务组成的等待任务列表。当一个“事件”被占用时,其他请求该事件的任务暂时得不到事件的服务,处于等待状态。μC/OS-II使用“等待任务表”来管理“事件”;即:使用“等待任务表”对那些等待该事件的各个任务进行管理(记录等待该事件的任务并排序,任务等待事件的超时等)。每个事件都有一个“等待任务表”,用于完成事件对任务的驱动、超时等管理,其原理类似于任务就续表。任务等待事件的超时记录在TCB的OSTCBDly成员中,每个时钟节拍都会对其进行维护,当超时时间到时μC/OS-II强行将其转入就续状态。
信号量可以使用在如下场合:
●允许一个任务与其他任务或中断同步。
●取得共享资源的使用权。
●标志事件的发生。
μC/OS-II提供6个信号量管理函数,如表6-4所列,信号量管理函数定义在OS_SEM.C文件中。
表6-4 信号量管理函数
在使用信号量管理函数之前,必须将OS_CFG.H文件中相应的配置常量OS_SEM_EN设置为1或0,以确定是编译还是裁剪该函数。原则上,中断服务子程序和任务可以共享信号量,但并不推荐这样使用,因为信号量一般用于任务级。如果非这样做不可,则中断服务子程序只能用来发送信号量。
信号量管理函数中,创建信号量、请求信号量和发送信号量最为重要。
1.创建信号量函数OSSemCreate()
在使用信号量之前,必须先创建信号量。创建信号量的系统函数原型如下:
OSSemCreate()函数用于建立一个信号量,并对信号量赋予计数初值。这个初值就是函数的参数cnt,它可以是0~65535中的任何值。信号量初值的设置规则如下:
●如果信号量用来表示一个或多个事件的发生,那么该信号量的初值通常赋为0。
●如果信号量用于对共享资源的访问,那么该信号量的初值应赋为1。
●如果信号量用来表示允许访问n个相同的资源,那么该信号量的初值应赋为n,并把
信号量作为一个可计数的信号量使用。
OSSemCreate()函数返回的是分配给所建立的信号量的事件控制块的指针,如果没有可用的事件控制块,则OSSemCreate()函数返回空指针。
2.请求信号量函数OSSemPend()(www.daowen.com)
OSSemPend()函数请求信号量,函数原型如下:
OSSemPend()函数挂起当前任务,直到有其他的任务、中断置位信号量或者信号量超出等待的预期时间。如果在预期的时钟节拍内信号量被置位,那么μC/OS-II默认最高优先级的任务取得信号量并转入就绪。一个被OSTaskSuspend()函数挂起的任务也可以接收信号量,但这个任务将一直保持挂起状态,直到通过调用OSTaskResume()函数恢复任务的运行。
OSSemPend()函数有如下3个参数:
1)pevent:指向信号量的指针。指针的值可以在建立该信号量时得到。
2)timeout:指定的超时时钟节拍数。如果一个任务在经过了timeout参数指定的时钟节拍后还没有得到需要的信号量时,则转入就绪状态。如果timeout为0,则表示任务将无限期地等待信号量。最大的超时等待时间为65535个时钟节拍。
3)err:指向包含错误代码的变量指针。
OSSemPend()函数没有返回值。
3.发送信号量函数OSSemPost()
OSSemPost()函数用于发送信号量,函数原型如下:
OSSemPost()函数用于发送信号量。如果没有任务在等待信号量,那么OSSem Post()函数使该信号量加1并返回;如果有任务在等待信号量,那么最高优先级的任务将得到信号量并进入就绪状态。任务调度函数将进行任务调度,决定当前运行的任务是否仍然为最高优先级的任务。从中断调用发送信号量的系统函数,不会发生任务切换,这是因为必须等到中断嵌套的最外层的ISR调用OSIntExit()函数后,任务切换才能发生。
OSSemPost()函数只有1个参数pevent,它是指向信号量的指针,指针的值可以在建立该信号量时得到。
OSSemPost()函数的返回值为下述内容之一:
●OS_NO_ERR:信号量成功置位,或者说成功发送。
●OS_SEM_OVF:信号量的值溢出。
●OS_ERR_EVENT_TYPE:pevent不是指向信号量的指针。
●OS_ERR_PEVENT_NULL:pevent是空指针。
通常请求信号量函数和发送信号量函数应该成对使用。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。