zoukankan      html  css  js  c++  java
  • UCOS 信号量

    uCOS-II信号量OSSemCreate(0)和OSSemCreate(1)详解

     (2014-04-22 18:04:18)
    标签: 

    it

    分类: 操作系统

    在ucos-II中,为了实现任务之间的同步,用到的同步机制有:信号量,邮箱和消息队列。其中这里我主要说下对信号量的使用经验。信号量在创建时,      调用OSSemCreate(INT16U cnt)函数。cnt为信号量的初始值。对cnt赋予不同的值,所起到的作用不同。如果Semp = OSSemCreate(0), 该信号量表示等待一个事件或者多个事件的发生。

          如果我们想对一个公共资源进行互斥访问,例如:如果我们想让两个任务Task1和Task2都可以调用Fun()函数,但不能同时调用,最好定义Semp = OSSemCreate(1),同理在各自的任务中都需要调用OSSemPend(Semp,0,&err)请求此信号量,如果可用,则调用Fun(),然后再调用OSSemPost(Semp)释放该信号量。这里就实现了一个资源的互斥访问。(注:初始化OSSemCreate(1),那么一个任务中有OSSemPend,那么可以执行,执行之后cnt==0,其他任务的OSSemPend无法获得sem,只能等待,除非任务一有OSSemPost,使其cnt++,这样其他任务的Pend可以执行。)同理,如果一个任务要等待n个事件发生后才能执行,则应定义为Semp = OSSemCreate(n)。然后在这n个任务分别运行时调用OSSemPost(Semp),直到这n个事件均发生后,这个任务才能运行。

    OSSemCreate(cnt)赋初始值cntOSSemPend(请求)一次,cnt-- 一次,OSSemPost(释放)一次,cnt++一次。

    1、OSSemCreate (0);

    ......

    OS_EVENT *Fun_Semp;

    ......

    Fun_Semp = OSSemCreate (0);

    ......

    void  MyTask (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秒
        }
    }

    ......

    void  YouTask (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);

    .....

    void  MyTask (void *pdata)
    {

    ..... 
        for (;;) 
        {                                           
            OSSemPend(Fun_Semp,0,&err); //请求信号量
       PC_DispStr(0,++y,  s1,  DISP_BGND_BLACK+DISP_FGND_WHITE );
       OSSemPost(Fun_Semp);  //发送信号量
            OSTimeDlyHMSM(0, 0, 1, 0);    //等待1秒
        }
    }

    void  YouTask (void *pdata)
    {

        for (;;) 
        {                                           
            OSSemPend(Fun_Semp,0,&err); //请求信号量
       PC_DispStr(0,++y,  s2,  DISP_BGND_BLACK+DISP_FGND_WHITE );

       OSSemPost(Fun_Semp);  //发送信号量            
            OSTimeDlyHMSM(0, 0, 2, 0);    //等待2秒
        }
    }

    在上例中,MyTask、YouTask 都在 等待信号量,由于MyTask优先级高,首先得到信号量开始执行。此时YouTask 还在等待信号量。MyTask 执行完毕,OSSemPost(Fun_Semp);  //发送信号量。YouTask 得到信号量运行后发送信号量,如此反复

     

  • 相关阅读:
    C# 在 8.0 对比 string 和 string? 的类型
    C# 在 8.0 对比 string 和 string? 的类型
    C# 使用反射获取私有属性的方法
    C# 使用反射获取私有属性的方法
    win10 uwp 发布旁加载自动更新
    win10 uwp 发布旁加载自动更新
    安装 Sureface Hub 系统 Windows 10 team PPIPro 系统
    安装 Sureface Hub 系统 Windows 10 team PPIPro 系统
    PHP FILTER_SANITIZE_EMAIL 过滤器
    PHP FILTER_SANITIZE_SPECIAL_CHARS 过滤器
  • 原文地址:https://www.cnblogs.com/locean/p/5314774.html
Copyright © 2011-2022 走看看