曲径通幽论坛

标题: 实例:信号量的使用 [打印本页]

作者: beyes    时间: 2009-4-14 01:59
标题: 实例:信号量的使用
功能:任务一和任务二都可以调用函数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环境下可以稳定运行。运行效果图:







欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2