コード例 #1
0
ファイル: timers.c プロジェクト: barriquello/proj-simone
/**
  \fn TIMER_CNT BRTOS_TimerGet (BRTOS_TIMER p)
  \brief public function to get remaining time of a soft timer
  \param p  soft timer
  \return timeout value or "0" as error code
*/
TIMER_CNT OSTimerGet (BRTOS_TIMER p)
{
     
     OS_SR_SAVE_VAR
     TIMER_CNT timeout;
     TIMER_CNT tickcount;
     
     if((p!= NULL) && (p->state == TIMER_RUNNING))
     {
     
        if (currentTask)
            OSEnterCritical();                      
             
            tickcount =  OSGetCount();  
            if(p->timeout >= tickcount)
            {                
                timeout = (TIMER_CNT)(p->timeout - tickcount);                   
            }
            else
            {
                timeout =  (TIMER_CNT)(TIMER_MAX_COUNTER - tickcount +  p->timeout + 1); 
            }  
                          
        if (currentTask)               
            OSExitCritical(); 
        
        return timeout;
      } 
      return 0;  /* "0" null event pointer or timer not running */
    
}
コード例 #2
0
ファイル: timers.c プロジェクト: barriquello/proj-simone
INT8U OSTimerStop (BRTOS_TIMER p, INT8U del){
  
  OS_SR_SAVE_VAR
  BRTOS_TMR_T* list;
  INT8U pos_timer = 0;
  
  if(p != NULL)
  {
  
      if (currentTask)
          OSEnterCritical();
     
        
        if(p->timeout >= OSGetCount())
        {                
           list = BRTOS_TIMER_VECTOR.current;  // remove from current list   
        }
        else
        {
           list = BRTOS_TIMER_VECTOR.future;   // remove from future list
        }  
        
        /* search timer index */
        p->state = TIMER_SEARCH;
        for(pos_timer = 1; pos_timer <= list->count; pos_timer++)
        {
        	if(list->timers[pos_timer]->state == TIMER_SEARCH)
        	{
        		break;
        	}
        }
        
        p->timeout = 0;
        Subir (list->timers, pos_timer); // order it 
        list->timers[1]=list->timers[list->count]; // remove from current list
        list->timers[list->count] = NULL;
        list->count--; 
        Descer (list->timers, 1, list->count); // order it
        
        if(del > 0)
        {                     
          p->state = TIMER_NOT_ALLOCATED; 
          p->func_cb = NULL; 
        }
        else
        {
          p->state = TIMER_STOPPED; 
        }
         
      if (currentTask)               
          OSExitCritical();
      
      return OK;
  }
  return NULL_EVENT_POINTER;
}
コード例 #3
0
ファイル: timers.c プロジェクト: barriquello/proj-simone
/**
  \fn INT8U BRTOS_TimerStart (BRTOS_TIMER p, TIMER_CNT time_wait)
  \brief public function to start or restart a soft timer
  \param p  soft timer
  \param time_wait soft timer expiration time
  \return OK success
  \return NULL_EVENT_POINTER error code
*/
INT8U OSTimerStart (BRTOS_TIMER p, TIMER_CNT time_wait){
 
  OS_SR_SAVE_VAR
  INT32U timeout;
  BRTOS_TMR_T* list;
  
  if(p!= NULL && time_wait != 0)
  {
      
      if(time_wait> TIMER_MAX_COUNTER) time_wait = TIMER_MAX_COUNTER;
      
      if (currentTask)
          OSEnterCritical();      
        
      if(time_wait > 0)
      {      
    
        timeout = (INT32U)((INT32U)OSGetCount() + (INT32U)time_wait);
        
        if (timeout >= TICK_COUNT_OVERFLOW)
        {
          p->timeout = (TIMER_CNT)(timeout - TICK_COUNT_OVERFLOW);
          list = BRTOS_TIMER_VECTOR.future;   // add into future list
          list->timers[++list->count] = p; // insert in the end                            
          Subir (list->timers, list->count); // order it 
        }
        else
        {
          p->timeout = (TIMER_CNT)timeout;
          list = BRTOS_TIMER_VECTOR.current;  // add into current list
          list->timers[++list->count] = p; // insert in the end                            
          Subir (list->timers, list->count); // order it 
          
          // may need to change wake time of timer task
          if(currentTask)
          {          
            if(p->timeout == (list->timers[1])->timeout)
            {
              ContextTask[BRTOS_TIMER_VECTOR.handling_task].TimeToWait = p->timeout;
            }
          }
                           
        }      
                
        p->state = TIMER_RUNNING;     
                                              
      }                                       
             
      if (currentTask)               
          OSExitCritical();  
      
      return OK;
  } 
  return NULL_EVENT_POINTER; /* any error number */
}
コード例 #4
0
ファイル: semaphore.c プロジェクト: barriquello/brtos-gpsnet
INT8U OSSemPend (BRTOS_Sem *pont_event, INT16U time_wait)
{
  OS_SR_SAVE_VAR
  INT8U  iPriority = 0;
  INT32U timeout;
  ContextType *Task;
  
  #if (ERROR_CHECK == 1)
    // Can not use semaphore pend function from interrupt handling code
    if(iNesting > 0)
    {
      return(IRQ_PEND_ERR);
    }
    
    // Verifies if the pointer is NULL
    if(pont_event == NULL)
    {
      return(NULL_EVENT_POINTER);
    }
  #endif
    
  // Enter Critical Section
  OSEnterCritical();

  #if (ERROR_CHECK == 1)
    // Verifies if the event is allocated
    if(pont_event->OSEventAllocated != TRUE)
    {
      // Exit Critical Section
      OSExitCritical();
      return(ERR_EVENT_NO_CREATED);
    }
  #endif
  
  // BRTOS TRACE SUPPORT
  #if (OSTRACE == 1)     
      #if(OS_TRACE_BY_TASK == 1)
      Update_OSTrace(currentTask, SEMPEND);
      #else
      Update_OSTrace(ContextTask[currentTask].Priority, SEMPEND);
      #endif
  #endif    

  // Verify if there was a post
  if (pont_event->OSEventCount > 0)
  {        
    // Decreases semaphore count
    pont_event->OSEventCount--;
    
    // Exit Critical Section
    OSExitCritical();
    return OK;
  } 
 
  Task = (ContextType*)&ContextTask[currentTask];
    
  // Copy task priority to local scope
  iPriority = Task->Priority;
  // Increases the semaphore wait list counter
  pont_event->OSEventWait++;
  
  // Allocates the current task on the semaphore wait list
  pont_event->OSEventWaitList = pont_event->OSEventWaitList | (PriorityMask[iPriority]);
  
  // Task entered suspended state, waiting for semaphore post
  #if (VERBOSE == 1)
  Task->State = SUSPENDED;
  Task->SuspendedType = SEMAPHORE;
  #endif
  
  // Remove current task from the Ready List
  OSReadyList = OSReadyList & ~(PriorityMask[iPriority]);
  
  // Set timeout overflow
  if (time_wait)
  {  
    timeout = (INT32U)((INT32U)OSGetCount() + (INT32U)time_wait);
    
    if (timeout >= TICK_COUNT_OVERFLOW)
    {
      Task->TimeToWait = (INT16U)(timeout - TICK_COUNT_OVERFLOW);
    }
    else
    {
      Task->TimeToWait = (INT16U)timeout;
    }
    
    // Put task into delay list
    IncludeTaskIntoDelayList();
  } else
  {
    Task->TimeToWait = NO_TIMEOUT;
  }
  
  // Change Context - Returns on time overflow or semaphore post
  ChangeContext();

  
  if (time_wait)
  {   
      /* Edited by Carlos H. Barriquello */
      
      /* Moved critical region to inside test region */
      // Exit Critical Section
      OSExitCritical();
      // Enter Critical Section
      OSEnterCritical();
      
      /* End of edition */
   
      // Verify if the reason of task wake up was queue timeout
      if(Task->TimeToWait == EXIT_BY_TIMEOUT)
      {
          // Test if both timeout and post have occured before arrive here
          if ((pont_event->OSEventWaitList & PriorityMask[iPriority]))
          {
            // Remove the task from the queue wait list
            pont_event->OSEventWaitList = pont_event->OSEventWaitList & ~(PriorityMask[iPriority]);
            
            // Decreases the queue wait list counter
            pont_event->OSEventWait--;
            
            // Exit Critical Section
            OSExitCritical();
            
            // Indicates queue timeout
            return TIMEOUT;
          }
      }
      else
      {
          // Remove the time to wait condition
          Task->TimeToWait = NO_TIMEOUT;
          
          // Remove from delay list
          RemoveFromDelayList();
      }
     
  }    
  // Exit Critical Section
  OSExitCritical();
  
  return OK;
}
コード例 #5
0
ファイル: mbox.c プロジェクト: GBeckerRS/brtos
INT8U OSMboxPend (BRTOS_Mbox *pont_event, void **Mail, INT16U time_wait)
{
  OS_SR_SAVE_VAR
  INT8U  iPriority = 0;
  INT32U  timeout;
  ContextType *Task;  
  
  #if (ERROR_CHECK == 1)
    /// Can not use mailbox pend function from interrupt handling code
    if(iNesting > 0)
    {
      // Return NULL message
      *Mail = (void *)NULL;
      return(IRQ_PEND_ERR);
    }
    
    // Verifies if the pointer is NULL
    if(pont_event == NULL)
    {
      return(NULL_EVENT_POINTER);
    }
  #endif
    
  // Enter Critical Section
  OSEnterCritical();

  #if (ERROR_CHECK == 1)
    // Verifies if the event is allocated
    if(pont_event->OSEventAllocated != TRUE)
    {
      // Exit Critical Section
      OSExitCritical();
      return(ERR_EVENT_NO_CREATED);
    }
  #endif
  
  // Verify if there was a message post
  if (pont_event->OSEventState == AVAILABLE_MESSAGE)
  {
    // Copy message pointer
    *Mail = pont_event->OSEventPointer;
    
    // Free message slot
    pont_event->OSEventState = NO_MESSAGE;
    
    // Exit Critical Section
    OSExitCritical();
    return OK;
  }
  else
  {
    Task = (ContextType*)&ContextTask[currentTask];
      
    // Copy task priority to local scope
    iPriority = Task->Priority;
    
    // Increases the semaphore wait list counter
    pont_event->OSEventWait++;
    
    // Allocates the current task on the mailbox wait list
    pont_event->OSEventWaitList = pont_event->OSEventWaitList | (PriorityMask[iPriority]);
    
    // Task entered suspended state, waiting for mailbox post
    #if (VERBOSE == 1)
    Task->State = SUSPENDED;
    Task->SuspendedType = MAILBOX;
    #endif
    
    // Remove current task from the Ready List
    OSReadyList = OSReadyList & ~(PriorityMask[iPriority]);

    // Set timeout overflow
    if (time_wait)
    {  
      timeout = (INT32U)((INT32U)OSGetCount() + (INT32U)time_wait);
      
      if (timeout >= TICK_COUNT_OVERFLOW)
      {
        Task->TimeToWait = (INT16U)(timeout - TICK_COUNT_OVERFLOW);
      }
      else
      {
        Task->TimeToWait = (INT16U)timeout;
      }
      
      // Put task into delay list
      IncludeTaskIntoDelayList();
    } else
    {
      Task->TimeToWait = NO_TIMEOUT;
    }
    
    // Change Context - Returns on time overflow or mailbox post
    ChangeContext();

    // Exit Critical Section
    OSExitCritical();
    // Enter Critical Section
    OSEnterCritical();
    
    if (time_wait)
    {    
        // Verify if the reason of task wake up was queue timeout
        if(Task->TimeToWait == EXIT_BY_TIMEOUT)
        {
            // Test if both timeout and post have occured before arrive here
            if ((pont_event->OSEventWaitList & PriorityMask[iPriority]))
            {
              // Remove the task from the queue wait list
              pont_event->OSEventWaitList = pont_event->OSEventWaitList & ~(PriorityMask[iPriority]);
              
              // Decreases the queue wait list counter
              pont_event->OSEventWait--;
              
              // Return NULL message
              *Mail = (void *)NULL;              
              
              // Exit Critical Section
              OSExitCritical();
              
              // Indicates queue timeout
              return TIMEOUT;
            }
        }
        else
        {
            // Remove the time to wait condition
            Task->TimeToWait = NO_TIMEOUT;
            
            // Remove from delay list
            RemoveFromDelayList();
        }
       
    }
    
    // Copy message pointer
    *Mail = pont_event->OSEventPointer;
    
    // Free message slot
    pont_event->OSEventState = NO_MESSAGE;
    
    // Exit Critical Section
    OSExitCritical();  
    return OK;    
  }
}
コード例 #6
0
ファイル: mutex.c プロジェクト: andrecurvello/brtos
INT8U OSMutexAcquire(BRTOS_Mutex *pont_event, INT16U time_wait)
{
    OS_SR_SAVE_VAR
    INT8U  iPriority = 0;
    INT32U timeout;
    ContextType *Task;


#if (ERROR_CHECK == 1)
    /// Can not use mutex acquire function from interrupt handling code
    if(iNesting > 0)
    {
        return(IRQ_PEND_ERR);
    }

    // Verifies if the pointer is NULL
    if(pont_event == NULL)
    {
        return(NULL_EVENT_POINTER);
    }
#endif

    // Enter Critical Section
    OSEnterCritical();

#if (ERROR_CHECK == 1)
    // Verifies if the event is allocated
    if(pont_event->OSEventAllocated != TRUE)
    {
        // Exit Critical Section
        OSExitCritical();
        return(ERR_EVENT_NO_CREATED);
    }
#endif

    // BRTOS TRACE SUPPORT
#if (OSTRACE == 1)
#if(OS_TRACE_BY_TASK == 1)
    Update_OSTrace(currentTask, MUTEXPEND);
#else
    Update_OSTrace(ContextTask[currentTask].Priority, MUTEXPEND);
#endif
#endif


    // Verifies if the task is trying to acquire the mutex again
    if (currentTask == pont_event->OSEventOwner)
    {
        // It is already the mutex owner
        OSExitCritical();
        return OK;
    }

    Task = (ContextType*)&ContextTask[currentTask];

    // Verify if the shared resource is available
    if (pont_event->OSEventState == AVAILABLE_RESOURCE)
    {
        // Set shared resource busy
        pont_event->OSEventState = BUSY_RESOURCE;

        // Current task becomes the temporary owner of the mutex
        pont_event->OSEventOwner = currentTask;

        ///////////////////////////////////////////////////////////////////////////////
        // Performs the temporary exchange of mutex owner priority, if needed        //
        ///////////////////////////////////////////////////////////////////////////////

        // Backup the original task priority
        pont_event->OSOriginalPriority = ContextTask[currentTask].Priority;

        if (pont_event->OSMaxPriority > ContextTask[currentTask].Priority)
        {
            // Receives the priority ceiling temporarily
            Task->Priority = pont_event->OSMaxPriority;

            // Priority vector change
            PriorityVector[pont_event->OSMaxPriority] = currentTask;

            // Remove "original priority current task" from the Ready List
            OSReadyList = OSReadyList & ~(PriorityMask[pont_event->OSOriginalPriority]);
            // Put the "max priority current task" into Ready List
            OSReadyList = OSReadyList | (PriorityMask[pont_event->OSMaxPriority]);
        }

        OSExitCritical();
        return OK;
    }
    else
    {
        // If no timeout is used and the mutex is not available, exit the mutex with an error
        if (time_wait == NO_TIMEOUT) {
            // Exit Critical Section
            OSExitCritical();
            return EXIT_BY_NO_RESOURCE_AVAILABLE;
        }

        // Copy task priority to local scope
        iPriority = Task->Priority;
        // Increases the mutex wait list counter
        pont_event->OSEventWait++;

        // Allocates the current task on the mutex wait list
        pont_event->OSEventWaitList = pont_event->OSEventWaitList | (PriorityMask[iPriority]);

        // Task entered suspended state, waiting for mutex release
#if (VERBOSE == 1)
        ContextTask[currentTask].State = SUSPENDED;
        ContextTask[currentTask].SuspendedType = MUTEX;
#endif

        // Remove current task from the Ready List
        OSReadyList = OSReadyList & ~(PriorityMask[iPriority]);

        // Set timeout overflow
        if (time_wait)
        {
            timeout = (INT32U)((INT32U)OSGetCount() + (INT32U)time_wait);

            if (timeout >= TICK_COUNT_OVERFLOW)
            {
                Task->TimeToWait = (INT16U)(timeout - TICK_COUNT_OVERFLOW);
            }
            else
            {
                Task->TimeToWait = (INT16U)timeout;
            }

            // Put task into delay list
            IncludeTaskIntoDelayList();
        } else
        {
            Task->TimeToWait = NO_TIMEOUT;
        }

        // Change Context - Returns on mutex release
        ChangeContext();

        // Exit Critical Section
        OSExitCritical();
        // Enter Critical Section
        OSEnterCritical();

        if (time_wait) {
            // Verify if the reason of task wake up was queue timeout
            if(Task->TimeToWait == EXIT_BY_TIMEOUT)
            {
                // Test if both timeout and post have occured before arrive here
                if ((pont_event->OSEventWaitList & PriorityMask[iPriority]))
                {
                    // Remove the task from the queue wait list
                    pont_event->OSEventWaitList = pont_event->OSEventWaitList & ~(PriorityMask[iPriority]);

                    // Decreases the queue wait list counter
                    pont_event->OSEventWait--;

                    // Exit Critical Section
                    OSExitCritical();

                    // Indicates resource not available
                    return EXIT_BY_NO_RESOURCE_AVAILABLE;
                }
            }
            else
            {
                // Remove the time to wait condition
                Task->TimeToWait = NO_TIMEOUT;

                // Remove from delay list
                RemoveFromDelayList();
            }

        }

        // Backup the original task priority
        pont_event->OSOriginalPriority = iPriority;

        if (pont_event->OSMaxPriority > iPriority)
        {
            // Receives the priority ceiling temporarily
            Task->Priority = pont_event->OSMaxPriority;

            // Priority vector change
            PriorityVector[pont_event->OSMaxPriority] = currentTask;

            // Remove "original priority current task" from the Ready List
            OSReadyList = OSReadyList & ~(PriorityMask[iPriority]);
            // Put the "max priority current task" into Ready List
            OSReadyList = OSReadyList | (PriorityMask[pont_event->OSMaxPriority]);
        }

        OSExitCritical();
        return OK;
    }
}
コード例 #7
0
ファイル: timers.c プロジェクト: barriquello/proj-simone
INT8U OSTimerSet (BRTOS_TIMER *cbp, FCN_CALLBACK cb, TIMER_CNT time_wait)
{
    
    OS_SR_SAVE_VAR
    
    INT8U i;     
    BRTOS_TIMER p;
    INT32U timeout;
    BRTOS_TMR_T* list;
    
    if((cb == NULL) || (cbp == NULL)) return NULL_EVENT_POINTER;    /* return error code */        
    
    if (currentTask)     
     OSEnterCritical();  
    
    // Search available timer control block
    for(i=0;i<=BRTOS_MAX_TIMER;i++)
    {
      
      if(i >= BRTOS_MAX_TIMER)
      {        
        // Exit critical Section
        if (currentTask)
           OSExitCritical();
        
        // Return error code
        return(NO_AVAILABLE_EVENT);
      }
      if(BRTOS_TIMER_VECTOR.mem[i].state == TIMER_NOT_ALLOCATED){
        
        // Exit critical Section
        if (currentTask)
           OSExitCritical();
        
        // Return error code
        return(ERR_EVENT_NO_CREATED);
      }
      
      if(BRTOS_TIMER_VECTOR.mem[i].state == TIMER_NOT_USED)
      {        
        p = &BRTOS_TIMER_VECTOR.mem[i];
        break;      
      }
    }
    
    p->state = TIMER_STOPPED;
    p->func_cb = cb;  // store callback function
    
       
    if(time_wait > 0)
    {      
    
      timeout = (INT32U)((INT32U)OSGetCount() + (INT32U)time_wait);
      
      if (timeout >= TICK_COUNT_OVERFLOW)
      {
        p->timeout = (INT16U)(timeout - TICK_COUNT_OVERFLOW);
        list = BRTOS_TIMER_VECTOR.future;   // add into future list
        list->timers[++list->count] = p; // insert in the end                            
        Subir (list->timers, list->count); // order it 
      }
      else
      {
        p->timeout = (INT16U)timeout;
        list = BRTOS_TIMER_VECTOR.current;  // add into current list
        list->timers[++list->count] = p; // insert in the end                            
        Subir (list->timers, list->count); // order it 
        
        // may need to change wake time of timer task
        if(currentTask)
        {          
          if(p->timeout == (list->timers[1])->timeout)
          {
            ContextTask[BRTOS_TIMER_VECTOR.handling_task].TimeToWait = p->timeout;
          }
        }
                         
      }      
              
      p->state = TIMER_RUNNING;      
                                            
    }
    
    *cbp = p;  
                
    if (currentTask)
        OSExitCritical(); 
    
    return OK;
}