ucos中关于信号量的使用总结

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

一、ucos中关于信号量的使用总结在ucos-II中,为了实现任务之间的同步,用到的同步机制有:信号量,邮箱和消息队列。其中这里我主要说下对信号量的使用经验。信号量在创建时,调用OSSemCreate(INT16Ucnt)函数。cnt为信号量的初始值。对cnt赋予不同的值,所起到的作用不同。1、Semp=OSSemCreate(0),该信号量表示等待一个事件或者多个事件的发生。例如:我们现在想实现这样一个功能:当有按键按下时,PWM蜂鸣器响起;无按键时,蜂鸣器不响。这是我们就可以分别建立两个任务,Task1和Task2,在Task1中处理按键的按下与否,一旦按下,则调用OSSemPost(Semp)发送这里信号量。在Task2中调用OSSemPend(Semp,0,&err)请求此信号量,如果信号量可用,则调用蜂鸣器程序蜂鸣,否则无限等待,任务自动进行切换。2、Semp=OSSemCreate(1)如果我们想对一个公共资源进行互斥访问,例如:如果我们想让两个任务Task1和Task2都可以调用Fun()函数,但不能同时调用,最好定义Semp=OSSemCreate(1),然后在各自的任务中都需要调用OSSemPend(Semp,0,&err)请求此信号量,如果可用,则调用Fun(),然后再调用OSSemPost(Semp)释放该信号量。这里就实现了一个资源的互斥访问。3、Semp=OSSemCreate(n)如果一个任务要等待n个事件发生后才能执行,则应定义为Semp=OSSemCreate(n)。然后在这n个任务分别运行时调用OSSemPost(Semp),直到这n个事件均发生后,这个任务才能运行。OSSemPost一次,cnt++加一次。voidOSSemPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err)timeout等待时限,允许任务在经过指定数目的时钟节拍后还没有得到需要的信号量时恢复运行状态。如果该值为0表示任务无限等待(将持续地等待信号量),最长等待时间为65535个时钟节拍。这个时间长度并不是严格的,可能存在一个时间节拍的误差,因为自由一个时钟节拍结束后,才会给定义的等待超时时钟节拍减1。二、OSSemCreate(cnt)赋初始值cnt,OSSemPend一次,cnt--减一次;OSSemPost一次,cnt++加一次。1、OSSemCreate(0);......OS_EVENT*Fun_Semp;......Fun_Semp=OSSemCreate(0);......voidMyTask(void*pdata){.....for(;;){OSSemPend(Fun_Semp,0,&err);//请求信号量PC_DispStr(0,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);OSTimeDlyHMSM(0,0,1,0);//等待1秒}}......voidYouTask(void*pdata){......for(;;){PC_DispStr(0,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);if(YouTaskRun==5)OSSemPost(Fun_Semp);//发送信号量YouTaskRun++;OSTimeDlyHMSM(0,0,2,0);//等待2秒}}在上例中,MyTask一直在等待信号量,在信号量没有到来之前无法执行。只有在YouTask运行了5次,YouTaskRun==5之后,OSSemPost(Fun_Semp);//发送信号量,MyTask才得以执行。如果按上例所示,MyTask只能执行一次,因为YouTask以后再也不可能使得YouTaskRun==5了。MyTask也就因为无法得到信号量而不能运行。2、OSSemCreate(1);.....OS_EVENT*Fun_Semp;.....Fun_Semp=OSSemCreate(1);.....voidMyTask(void*pdata){.....for(;;){OSSemPend(Fun_Semp,0,&err);//请求信号量(失去CPU)PC_DispStr(0,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);//获得了信号量,有数据需要处理OSSemPost(Fun_Semp);//发送信号量OSTimeDlyHMSM(0,0,1,0);//等待1秒}}voidYouTask(void*pdata){for(;;){OSSemPend(Fun_Semp,0,&err);//请求信号量PC_DispStr(0,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);OSSemPost(Fun_Semp);//发送信号量(让PEND信号量的处理就绪)OSTimeDlyHMSM(0,0,2,0);//等待2秒(进行任务切换)}}在上例中,MyTask、YouTask都在等待信号量,由于MyTask优先级高,首先得到信号量开始执行。此时YouTask还在等待信号量。MyTask执行完毕,OSSemPost(Fun_Semp);//发送信号量。YouTask得到信号量运行后发送信号量,如此反复三、需要注意的是删除信号量之前,必须首先删除操作该信号量的所有任务。四、对于信号量,uCOSII中共提供了六个函数:OSSemCreate、OSSemDel、OSSemPend、OSSemPost、OSSemAccept、OSSemQuery。其中我们常用的只有三个即OSSemCreate、OSSemPend、OSSemPost。信号量的结构为:typedefstruct{INT8UOSEventType;INT8UOSEventGrp;INT16UOSEventCnt;void*OSEventPtr;INT8UOSEventTbl[OS_EVENT_TBL_SIZE];}OS_EVENT;OSSemCreate的函数原型为:OS_EVENT*OSSemCreate(INT16Ucnt),cnt表示在实际使用中有多少个相同的资源,cnt的值就是OSEventCnt的值。OSSemPend的函数原型为:voidOSSemPend(OS_EVENT*pevent,INT16Utimeout,INT8Uerr),pevent:就是要请求的信号量地址;timeout:请求的超时时间,如果为0表示无限时等待;err:用来返回是否出错。每执行一次OSSemPend,OSEventCnt就会减1。如果OSEventCnt值为0,执行OSSemPend时,当时任务将因为无法得到相应的资源而被挂起。OSSemPost的函数原型为:INT8UOSSemPost(OS_EVENT*pevent),pevent就是要发送的信号量地址;每执行一次OSSemPost,OSEventCnt就会加1。六、信号量(这里仅说互斥)就两个操作,一个请求,一个释放。一个任务请求信号量时:如果被其它任务占用,则该任务等待,同时导致任务切换;如果没有被其它任务占用,则获得,继续执行。释放信号量时,如果其它高优先级任务正在请求并等待该信号量,则导致任务切换。OSTimeDly之类,并不导致信号量的释放。只有获取信号量的那个任务调用释放功能时,信号量才会释放。信号量程序dj:#includeINCLUDES.Htypedefunsignedcharu8;typedefunsignedintu16;typedefunsignedlongu32;OS_STKTaskStk[3][MaxStkSize];//定义3个堆栈voidtask0(void*dat);//定义任务0voidtask1(void*dat);longcon1=0;longcon2=0;OS_EVENT*sem;u8err;main(){OSInit();InitTimer0();sem=OSSemCreate(1);//建立信号量OSTaskCreate(task0,(void*)0,&TaskStk[0][0],5);//建立任务定义好它的优先级等参数OSTaskCreate(task1,(void*)0,&TaskStk[1][0],6);OSStart();}voidtask0(void*dat)//任务0{while(1){con1++;OSSemPost(sem);//发送信号量OSTimeDly(2);}}voidtask1(void*dat)//任务1{u16value;u16vison;while(1){value=OSSemAccept(sem);//查看资源是否可以使用OSSemPend(sem,0,&err);//等待接收信号才往下执行任务con2++;}OSTimeDly(2);//延时}}心得:信号量的建立必须是在任务级中建立,信号量类型为OS_EVENT,信号量值可以为1,0,0~65535的值,不同的值代表不同的意义。OSSemAccept(信号量)起查询信号量作用,返回信号量的值。OSSemPend(sem,0,&err);将暂停当前任务,等待信号量的到来。如果接收到一个信号量(如果信号量大于0),该信号量会自动减1,在例子中,信号量开始定义为1,在任务1接收后,信号量会变为0;七、正在阅读uC/OSII的源码,看到有关信号量的问题,不是太理解。上网搜索资料的时候发现有段比较精彩的解释,摘录如下:一间屋子,只能一人进去。门口箱子里放着一把钥匙。当有钥匙时箱子上显示1,无钥匙时显示0。来人看见1就打开箱子取出钥匙进屋,同时显示减一为0,再来人时看见0,就知道有人在屋里,于是在外等待,屋里人出来时,把钥匙放回箱中,显示加1。后面的人看见1又可以进入。这里钥匙相当于信号量,根据钥匙的有无取0,1两个值。屋子相当于公用资源,同一时间只能由一人使用它。使用信号量保证不会有两人同时使用公用资源。对于与硬件设计相关的公共资源,比如说SPI,I2C,UART接口,都是独占类型的,也就说一个任务在使用这些资源的时候,其余的申请使用该资源的任务只能处于等待状态。这就需要互斥型的信号量,正如例子所示。

1 / 5
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功