第五篇:uCOS-II 信号量及其…

1.信号量

 使用信号量之前首先要对信号量有一个本质的认识

(1)信号量的含义:信号量是一类事件,使用信号量的最初目的是为了给共享资源

    立一个标志,该标志表示共享资源的占用情况,这样,当一个任务在访问共

     享资源之前,就可以对这个标志进行查询,从而在了解资源被占用的情况之后

     ,再来决定自己的行为。

(2)UCOS-II的信号量里面有一个OSEventCnt,正确的认识这个,是使用信号量的关

     键。

     OSSemCreate(0)  :这种情况下可以用任务的同步。

     OSSemCreate(1)  :这种情况类似于互斥信号量,有一个名字就是二值信号

                         量,可用于一个资源的使用

     OSSemCreate(>1) :这种情况表示有>1个资源可以使用。

(3)OSEventCnt的初始数据代表可用的资源数,1就是一个可用资源,n就是n可用资

     源。

(4)OSTimeTick 函数里面有一个需要注意的地方。

     a如果事件中设置了0SxxxPend的延时的话,会进到下面函数的这个地方。

     b如果设置的是一直等到的话,将通过OSXXXPost释放。

     在延迟的时间里面没有就绪的话,任务OSTCBStatPend被设置成超时,并

     清除相应的标志位。

     if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
      ptcb->OSTCBStat  &= (INT8U)~(INT8U)OS_STAT_PEND_ANY;       
      ptcb->OSTCBStatPend = OS_STAT_PEND_TO;              
      }

     在延迟的时间里面任务收到信息,任务OSTCBStatPend被设置成OK

      else

     {
         ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
      }
    如果任务没有被挂起的话,任务将加入到就绪列表。
    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {
         OSRdyGrp               |= ptcb->OSTCBBitY;          
         OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
     }

(5)下面分两种情况进行详细的讨论 
  A. OSSemCreate(0) 这种情况下用于信号的同步     

  •   OSSemPen(xx, 0, xx) 设置为0的话,任务将被一直挂起直到收到OSSem

       Post信号。    

  •   OSSemPen(xx, >0, xx) 设置为>0的话,任务将被挂起相应的时间.

       a)如果在规定的时间内收到信号,那么任务将通过OSSemPend将其从等待

          列表删除,继续运行。

       b)如果延时超时,那么将通过OSSemPend函数本身将其从事件等待列表删除
  B. OSSemCreate(1) 这种情况下用于互斥信号量,但不能防止优先级翻转。

   详细实现同上。
  C. OSSemCreate(>1) 这种情况下用多个资源共享

   详细实现同上。

   OS_EventTaskRemove(OSTCBCur, pevent); 

   只是把任务从任务就绪列表里面移除,加入到事件等待列表

1

2.信号量的创建

  信号量的初始值的设置有三种作用已经在下面的图中有说明

2 

3

下面是一个信号量被初始化以后事件列表的情况

4

3.请求信号量

5

6

7

4.发送信号量

8

9

信号量的使用还是很简单的

我现在主要将其用在两个方面

(1)用来触发一个事件的发生。

    Semp        OSSemCreate(0);         //创建一个信号量

static void AppTaskCom(void *p_arg) //这个任务用来申请一个信号量,在500毫秒里面可以 
                             //得到信号量的话输出成功,否则失败。
   INT8U err;
   (void)p_arg;
    while(1){
             OSSemPend(Semp, 500, &err);
             if(err == OS_ERR_NONE)
             {
                printf("SUCCESSrn");
             }
             else
             {
                   printf("failedrn");
             }
   }
}

      err = OSSemPost(Semp);           //这个函数用来释放一个信号量
               if (err == OS_ERR_NONE) //也就是触发上面的那个函数
               {
                     printf("OSSemPostrn");
               }

(2)用来独占一个资源,这个的使用要小心,防止优先级的反转,所以最好使用这两个资源的任务之间不要有别的优先级,有的话就容易发生优先级的反转情况,这种情况是不允许的。

  OSSemPend(Semp, 500, &err);

//在这里添加需要使用的资源

  OSSemPost(Semp);          

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值