曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 10058|回复: 0
打印 上一主题 下一主题

实例:信号量的使用

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
跳转到指定楼层
楼主
发表于 2009-4-14 01:59:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
功能:任务一和任务二都可以调用函数Fun(),但不能同时调用
目的:熟悉信号量的使用
代码:
#include "includes.h"

  

#define  TASK_STK_SIZE                 512

#define Task_Hold       0x01
#define Task_Post       0x00

OS_STK        DispCharMStk[TASK_STK_SIZE];        /*任务堆栈*/
OS_STK    DispCharYStk[TASK_STK_SIZE];
OS_STK    StartTaskStk[TASK_STK_SIZE];

   INT16S key;
   INT8U  y1 = 0;
   INT8U  y2 = 0;
   INT8U  TaskID = 0;
   INT8U  err;
   INT8U  Flag;                                        /*信号量是否放开标志*/
   OS_EVENT *Fun_Sem;
   

  void  DispCharM(void *data);                  /*函数声明*/
  void  DispCharY(void *data);
  void StartTask(void *data);
  void Fun(INT8U *id);

void  main (void)
{

  PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);      /*清屏*/

  OSInit();                                              /* 初始化 uC/OS-II */

  Fun_Sem = OSSemCreate(1);     /*建立只有一个资源的信号量*/

  PC_DOSSaveReturn();                                    /*保存DOS的返回环境*/
  PC_VectSet(uCOS, OSCtxSw);                             /*安装ucos的任务切换向量*/

  

  OSTaskCreate(StartTask, (void *)0, &StartTaskStk[TASK_STK_SIZE - 1], 0);
  OSStart();                                             /*多任务开始*/
}


void StartTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3                               

  OS_CPU_SR  cpu_sr;
#endif


  pdata = pdata;                                         /*防止编译警告*/

  OS_ENTER_CRITICAL();
  PC_VectSet(0x08, OSTickISR);                           /*安装ucos的时钟向量*/
  PC_SetTickRate(OS_TICKS_PER_SEC);                      /*设置时钟频率*/
  OS_EXIT_CRITICAL();

  OSStatInit();                                          /*初始化 uC/OS-II's 统计任务 */

  OSTaskCreate(DispCharM,(void *)0, &DispCharMStk[TASK_STK_SIZE - 1], 2);

  OSTaskCreate(DispCharY,(void *)0, &DispCharYStk[TASK_STK_SIZE - 1], 3);  /*建立两个任务*/

  for(;;)
  {
  if( Flag == Task_Hold)                    /*信号量是否被 hold 住*/
   {
   if( TaskID == 2 )                             /*是否被2#任务 hold 住*/
   {
    PC_DispStr(10,12,"Warning: DispCharM hold the semaphore for 15s",DISP_BGND_BLACK + DISP_FGND_WHITE);                        /* 显示警告信息:2#任务 hold 住信号量 15s*/
   }else if( TaskID == 3 )
   {
    PC_DispStr(10,12,"Warning: DispCharY hold the semaphore for 6s ",DISP_BGND_BLACK + DISP_FGND_WHITE);                         /* 显示警告信息:3#任务 hold 住信号量 6s*/
   }
   }else{
    PC_DispStr(10,12,"                                             ",DISP_BGND_BLACK + DISP_FGND_WHITE);
    }                                                         /*清除警告信息*/


  if( PC_GetKey(&key) == TRUE )
  {
   if( key == 0x1B )
   {
    PC_DOSReturn();
    }


  }
     OSTimeDly(5);
  }

}
void  DispCharM (void *pdata)
{
#if OS_CRITICAL_METHOD == 3                               
  OS_CPU_SR  cpu_sr;
#endif


  pdata = pdata;                                       

  for (;;)
   {

    OSSemPend(Fun_Sem,0,&err);

    PC_DispStr(10,0,"DispCharM have got the semaphore",DISP_BGND_BLACK + DISP_FGND_WHITE);          /*显示已得到信号量*/
  

    PC_DispStr(10,8,"                                ",DISP_BGND_BLACK + DISP_FGND_WHITE);

    TaskID = OSPrioCur;       /*传送任务优先级号*/

    Fun(&TaskID);                  /*调用 Fun() 函数*/

    Flag = Task_Hold;

    OSTimeDlyHMSM(0,0,15,0);              /* hold 住信号量 15s */

    Flag = Task_Post;                               /*释放*/

    OSSemPost(Fun_Sem);

    if( PC_GetKey(&key) == TRUE )
  {
   if( key == 0x1B )
   {
    PC_DOSReturn();
    }


  }
     OSTimeDlyHMSM(0,0,2,0);


   }

}

void DispCharY(void *pdata)
{
#if OS_CRITICAL_METHOD == 3                              

  OS_CPU_SR  cpu_sr;
#endif

  pdata = pdata;

  for (;;)
   {
    OSSemPend(Fun_Sem,0,&err);

  PC_DispStr(10,8,"DispCharY have got the semaphore",DISP_BGND_BLACK + DISP_FGND_WHITE);
  PC_DispStr(10,0,"                                ",DISP_BGND_BLACK + DISP_FGND_WHITE);

    TaskID = OSPrioCur;

    Fun(&TaskID);

    Flag = Task_Hold;

    OSTimeDlyHMSM(0,0,6,0);

        Flag = Task_Post;
    OSSemPost(Fun_Sem);


  if( PC_GetKey(&key) == TRUE )
  {
   if( key == 0x1B )
   {
    PC_DOSReturn();
    }

  }

   OSTimeDlyHMSM(0,0,1,0);
  }
}

void Fun(INT8U *id)
{
  char *S_Fun = "# task is calling the Fun()";
  char s[50];

  sprintf(s, "%d", *id);
  strcat(s,S_Fun);
  if(*id == 2)
  {
  PC_DispStr(10,1,s,DISP_BGND_BLACK + DISP_FGND_WHITE);
  PC_DispStr(10,7,"                                ",DISP_BGND_BLACK + DISP_FGND_WHITE);
  }else if( *id == 3 ){
  PC_DispStr(10,7,s,DISP_BGND_BLACK + DISP_FGND_WHITE);
  PC_DispStr(10,1,"                                ",DISP_BGND_BLACK + DISP_FGND_WHITE);
  }

}
注:程序在 windows 的虚拟环境下有时会产生错误,可能是和某些驱动程序相冲突了。在纯DOS环境下可以稳定运行。运行效果图:


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-19 08:09 , Processed in 0.078398 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表