接下来需要完成任务间的同步和通信。

  任务间同步,为什么需要任务间同步,比如对公共资源的访问,如果不同步,一个任务正在访问资源,另一个任务不知道这个资源正在被访问,也去访问了,这出现问题了。还有是任务再等待某一事件的触发,触发后才能运行。实现的一种同步方法是信号量。何为信号量?举个简单的例子来说,像是资源的标识,如停车位,当还有停车位时,车才可以停进来,但没有停车位时,外面的车必须等待,等到有停车位时再进来。下面是一个信号量的简单实现,原理是用一个全局变量代表可用的资源。当有资源时,这个变量加一,当这个变量为0时代表没有资源了,任务开始挂起,同时开始切换到其它任务。

/*当前信号量列表*/
OS_SEM Sem[MAX_SEM_NUM];   
/*
 * 创建信号量
*/
OS_SEM* OSSemCreate(int32 conuter)
{
     OS_CPU_SR  cpu_sr = 0;
     uint32  index;
    if (conuter < 0)
    {
       return (OS_SEM*)NULL;
    }
 
     OS_ENTER_CRITICAL();
    for(index=0;index<MAX_SEM_NUM;index++)
    {
      if(Sem[index]==-1)
      {
         Sem[index]=conuter;
         OS_EXIT_CRITICAL();
         return(Sem[index]);
      }
    }
 
   OS_EXIT_CRITICAL();
   return (OS_SEM*)NULL;
}
int8 OSSemDelete(OS_SEM* pSem)
{
 OS_CPU_SR  cpu_sr = 0;
 OS_ENTER_CRITICAL();
 /*当且仅当信号量计数为0的时候,才能释放该信号量*/
 if ((*pSem) != 0)
 {
  OS_EXIT_CRITICAL();
  return OS_Err;
 }
 else
 {
  (*pSem) = (OS_SEM)-1;
  OS_EXIT_CRITICAL();
  return OS_OK;
 }
}
/*这个是一个不完全精确的实现*/
/*申请信号量*/
/*其超时时间不会非常精确*/
int8 OSSemPend(OS_SEM* pSem,uint32 timeout)
{
 uint32  index;
 OS_CPU_SR  cpu_sr = 0;
 for (index = 0;index < timeout;index++)
 {
  OS_ENTER_CRITICAL();
  if ((*pSem) > 0)
  {
   (*pSem)--;
   OS_EXIT_CRITICAL();
   return OS_OK;/*获取到了信号量*/
  }
  else
  {
   /*等待一个时间片*/
   OS_EXIT_CRITICAL();
   OSTimeDly(1);
  }
 }
 
 return OS_Err;
}
/*不等待,立即返回是否信号量能否获取*/
int8 OSSemGet(OS_SEM* pSem)
{
 OS_CPU_SR  cpu_sr = 0;
 OS_ENTER_CRITICAL();
 if ((*pSem) > 0)
 {
  (*pSem)--;
  OS_EXIT_CRITICAL();
  return OS_OK;/*获取到了信号量*/
 }
 OS_EXIT_CRITICAL();
 return OS_Err;
}
/*释放(发送)一个信号量*/
int8 OSSemPost(OS_SEM* pSem)
{
 OS_CPU_SR  cpu_sr = 0;
 OS_ENTER_CRITICAL();
 (*pSem)++;
 OS_EXIT_CRITICAL();
 return OS_OK;
}
 信号量如何使用?如何使用信号量来进行同步?下面是一个简单的应用例子。

  我们知道printf函数不可重入,在调用这个函数时,必须保证不能被其他任务占用。所以不同任务需要保持同步,当一个任务释放了信号量后另一个任务方可使用。

OS_SEM*   testSem;
void  task6(void * arg)
{
    testSem=OSSemCreate(1); //创建一个信号量
    while(1 )
    {
         OSSemPend(testSem, 0);
         printf("task 6  Running! 27 ");
         OSSemPost(testSem);
         OSTimeDly(100);/*100毫秒10个*/
    }
}