zoukankan      html  css  js  c++  java
  • uCOS-II 学习笔记之事件管理--------信号量管理的学习

      今天将卢有亮老师基于VC的信号量管理的代码移植到STM32中,并通过串口打印在串口终端。

      假设有共享资源R,允许2个任务分时访问R,那么信号量应该设置为2,系统中有三个任务(A、B、C)分别访问资源R,任务的优先级分别为7、6、5. 3个任务在操作系统的初始化和启动多任务之前被创建。任务A运行后创建信号量,并访问R,访问完成后任务将自己阻塞1000个时钟周期。任务B先阻塞自己300个时钟周期,任何操作步骤同任务A。任务C先阻塞400个时钟周期,然后操作步骤同任务A。

      1 //=========================================================================================
      2 //uCOS-II 学习例子
      3 //=========================================================================================
      4 //信号量管理的例子
      5 void UserTaskSemA(void *pParam)
      6 {
      7     /*任务SemA创建信号量,然后周期性访问资源R*/
      8     /*创建信号量*/
      9     INT8U     *perr;
     10     INT8U err;
     11     //INT8U i;
     12     OS_SEM_DATA mySemData;
     13     err=0;
     14     perr=&err;
     15     MyEventSem=OSSemCreate(2);
     16     if (MyEventSem==(OS_EVENT *)0)
     17     {
     18         printf("任务A创建信号量失败!
    ");
     19         OSTaskDel(OS_PRIO_SELF);
     20         return;
     21     }
     22     OSSemQuery(MyEventSem,&mySemData); 
     23     printf("时间:%d, 任务A创建信号量。当前信号量值=%d
    ",OSTimeGet(),mySemData.OSCnt);
     24     while(1)
     25     {
     26         OSSemQuery(MyEventSem,&mySemData); 
     27         printf("时间:%d,任务A开始请求信号量!当前信号量值=%d
    ",OSTimeGet(),mySemData.OSCnt);
     28         OSSemPend(MyEventSem,0,perr);
     29         if (err!=OS_ERR_NONE)
     30         {
     31              printf("任务A请求信号量失败
    ");
     32              printf("错误号%d
    ",err);
     33              continue;
     34         }
     35         OSSemQuery(MyEventSem,&mySemData); 
     36                 printf("时间:%d,任务A获得信号量。当前信号量值=%d,任务A开始对R操作
    ",OSTimeGet(),mySemData.OSCnt);
     37                 OSTimeDly(1000); /*模拟操作资源,需要10秒,1000个时钟嘀嗒*/
     38         printf("时间:%d,任务A结束资源操作,提交信号量!
    ",OSTimeGet());
     39         OSSemPost(MyEventSem);
     40         OSSemQuery(MyEventSem,&mySemData); 
     41                 printf("时间:%d,任务A提交信号量完成,当前信号量值=%d,任务A将延时阻塞1000嘀嗒
    ",OSTimeGet(),mySemData.OSCnt);
     42         OSTimeDly(1000);
     43     }
     44 }
     45 void UserTaskSemB(void *pParam)
     46 {
     47     /*任务SemA创建信号量,然后周期性访问资源R*/
     48     INT8U     *perr;
     49     INT8U err;
     50     OS_SEM_DATA mySemData;
     51     err=0;
     52     perr=&err;
     53     printf("时间:%d,任务B开始延时300个时钟嘀嗒",OSTimeGet());
     54     OSTimeDly(300);/*任务B先延时3秒*/
     55     if (MyEventSem==(OS_EVENT *)0)
     56     {
     57         printf("任务A创建信号量失败!
    ");
     58         OSTaskDel(OS_PRIO_SELF);
     59         return;
     60     }
     61     while(1)
     62     {
     63         OSSemQuery(MyEventSem,&mySemData); 
     64         printf("时间:%d,任务B开始请求信号量!当前信号量值=%d
    ",OSTimeGet(),mySemData.OSCnt);
     65         OSSemPend(MyEventSem,0,perr);
     66         if (err!=OS_ERR_NONE)
     67         {
     68              printf("任务B请求信号量失败
    ");
     69              printf("错误号%d
    ",err);
     70              continue;
     71         }
     72         OSSemQuery(MyEventSem,&mySemData); 
     73                 printf("时间:%d,任务B获得信号量。当前信号量值=%d,任务B开始对R操作,需1000个时钟嘀嗒
    ",OSTimeGet(),mySemData.OSCnt);
     74                 OSTimeDly(1000); /*模拟操作资源,需要10秒,1000个时钟嘀嗒*/
     75         printf("时间:%d,任务B结束资源操作,提交信号量!
    ",OSTimeGet());
     76         OSSemPost(MyEventSem);
     77         OSSemQuery(MyEventSem,&mySemData); 
     78                 printf("时间:%d,任务B提交信号量完成,当前信号量值=%d,任务B将延时阻塞1000嘀嗒
    ",OSTimeGet(),mySemData.OSCnt);
     79         OSTimeDly(1000);
     80     }
     81 }
     82 
     83 
     84 void UserTaskSemC(void *pParam)
     85 {
     86     /*任务SemA创建信号量,然后周期性访问资源R*/
     87     INT8U     *perr;
     88     INT8U err;
     89     //INT8U i;
     90     OS_SEM_DATA mySemData;
     91     err=0;
     92     perr=&err;
     93     printf("时间:%d,任务C开始延时400个时钟嘀嗒",OSTimeGet());
     94     OSTimeDly(400);/*任务C先延时4秒*/
     95     if (MyEventSem==(OS_EVENT *)0)
     96     {
     97         printf("任务A创建信号量失败!
    ");
     98         OSTaskDel(OS_PRIO_SELF);
     99         return;
    100     }
    101     while(1)
    102     {
    103         OSSemQuery(MyEventSem,&mySemData); 
    104         printf("时间:%d,任务C开始请求信号量!当前信号量值=%d
    ",OSTimeGet(),mySemData.OSCnt);
    105         OSSemPend(MyEventSem,0,perr);
    106         if (err!=OS_ERR_NONE)
    107         {
    108              printf("任务C请求信号量失败
    ");
    109              printf("错误号%d
    ",err);
    110              continue;
    111         }
    112         OSSemQuery(MyEventSem,&mySemData); 
    113             printf("时间:%d,任务C获得信号量。当前信号量值=%d,任务C开始对R操作,需1000个时钟嘀嗒
    ",OSTimeGet(),mySemData.OSCnt);
    114              OSTimeDly(1000); /*模拟操作资源,需要10秒,1000个时钟嘀嗒*/
    115         printf("时间:%d,任务C结束资源操作,提交信号量!
    ",OSTimeGet());
    116         OSSemPost(MyEventSem);
    117         OSSemQuery(MyEventSem,&mySemData); 
    118         printf("时间:%d,任务C提交信号量完成,当前信号量值=%d,任务C将延时阻塞1000嘀嗒
    ",OSTimeGet(),mySemData.OSCnt);
    119         OSTimeDly(1000);
    120     }
    121 }

     运行结果如下所示:

     1 时间:0,任务C开始延时400个时钟嘀嗒时间:0,任务B开始延时300个时钟嘀嗒时间:0, 任务A创建信号量。当前信号量值=2
     2 时间:1,任务A开始请求信号量!当前信号量值=2
     3 时间:1,任务A获得信号量。当前信号量值=1,任务A开始对R操作
     4 时间:300,任务B开始请求信号量!当前信号量值=1
     5 时间:300,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
     6 时间:400,任务C开始请求信号量!当前信号量值=0
     7 时间:1002,任务A结束资源操作,提交信号量!
     8 时间:1002,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
     9 时间:1003,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
    10 时间:1301,任务B结束资源操作,提交信号量!
    11 时间:1301,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
    12 时间:2003,任务C结束资源操作,提交信号量!
    13 时间:2003,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
    14 时间:2004,任务A开始请求信号量!当前信号量值=2
    15 时间:2004,任务A获得信号量。当前信号量值=1,任务A开始对R操作
    16 时间:2302,任务B开始请求信号量!当前信号量值=1
    17 时间:2302,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
    18 时间:3004,任务C开始请求信号量!当前信号量值=0
    19 时间:3005,任务A结束资源操作,提交信号量!
    20 时间:3005,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
    21 时间:3006,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
    22 时间:3303,任务B结束资源操作,提交信号量!
    23 时间:3303,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
    24 时间:4006,任务C结束资源操作,提交信号量!
    25 时间:4006,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
    26 时间:4007,任务A开始请求信号量!当前信号量值=2
    27 时间:4007,任务A获得信号量。当前信号量值=1,任务A开始对R操作
    28 时间:4304,任务B开始请求信号量!当前信号量值=1
    29 时间:4304,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
    30 时间:5007,任务C开始请求信号量!当前信号量值=0
    31 时间:5008,任务A结束资源操作,提交信号量!
    32 时间:5008,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
    33 时间:5009,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
    34 时间:5305,任务B结束资源操作,提交信号量!
    35 时间:5305,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
    36 时间:6009,任务C结束资源操作,提交信号量!
    37 时间:6009,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
    38 时间:6010,任务A开始请求信号量!当前信号量值=2
    39 时间:6010,任务A获得信号量。当前信号量值=1,任务A开始对R操作
    40 时间:6306,任务B开始请求信号量!当前信号量值=1
    41 时间:6306,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
    42 时间:7010,任务C开始请求信号量!当前信号量值=0
    43 时间:7011,任务A结束资源操作,提交信号量!
    44 时间:7011,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
    45 时间:7012,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
    46 时间:7307,任务B结束资源操作,提交信号量!
    47 时间:7307,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
    48 时间:8012,任务C结束资源操作,提交信号量!
    49 时间:8012,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
    50 时间:8013,任务A开始请求信号量!当前信号量值=2
    51 时间:8013,任务A获得信号量。当前信号量值=1,任务A开始对R操作
    52 时间:8308,任务B开始请求信号量!当前信号量值=1
    53 时间:8308,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
    54 时间:9013,任务C开始请求信号量!当前信号量值=0
    55 时间:9014,任务A结束资源操作,提交信号量!
    56 时间:9014,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
    57 时间:9015,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
    58 时间:9309,任务B结束资源操作,提交信号量!
    59 时间:9309,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒

     由于串口打印函数需要一定的时间,显示结果未能像PC机运行那样,细看打印结果,基本上都是根据设计来的。

  • 相关阅读:
    redis应用场景
    使用Nginx+Lua+Redis构建灰度发布环境
    Comparison method violates its general contract
    mysql+redis
    缓存技术PK:选择Memcached还是Redis?
    缓存技术PK
    菜鸟教程之工具使用(九)——Git如何进行分支的merge操作
    菜鸟教程之工具使用(八)——EGit禁止自动转换回车换行符
    菜鸟教程之工具使用(七)——从GIt上导出Maven项目
    菜鸟教程之工具使用(六)——让Maven项目直接在eclipse内部的Tomcat中运行
  • 原文地址:https://www.cnblogs.com/xiaofeng6636/p/3511371.html
Copyright © 2011-2022 走看看