Example #1
0
INT8U OSSemPost(BRTOS_Sem *pont_event)
{
  OS_SR_SAVE_VAR  
  INT8U iPriority = (INT8U)0;
  #if (VERBOSE == 1)
  INT8U TaskSelect = 0;
  #endif
  
  #if (ERROR_CHECK == 1)    
    // Verifies if the pointer is NULL
    if(pont_event == NULL)
    {
      return(NULL_EVENT_POINTER);
    }
  #endif

  // Enter Critical Section
  #if (NESTING_INT == 0)
  if (!iNesting)
  #endif
     OSEnterCritical();
     
  #if (ERROR_CHECK == 1)        
    // Verifies if the event is allocated
    if(pont_event->OSEventAllocated != TRUE)
    {
      // Exit Critical Section
      #if (NESTING_INT == 0)
      if (!iNesting)
      #endif
         OSExitCritical();
      return(ERR_EVENT_NO_CREATED);
    }
  #endif
     
  // BRTOS TRACE SUPPORT
  #if (OSTRACE == 1)  
    if(!iNesting){ 
      #if(OS_TRACE_BY_TASK == 1)
      Update_OSTrace(currentTask, SEMPOST);
      #else
      Update_OSTrace(ContextTask[currentTask].Priority, SEMPOST);
      #endif
    }else{
      Update_OSTrace(0, SEMPOST);
    }
  #endif      
  
  // See if any task is waiting for semaphore
  if (pont_event->OSEventWait != 0)
  {
    // Selects the highest priority task
    iPriority = SAScheduler(pont_event->OSEventWaitList);    

    // Remove the selected task from the semaphore wait list
    pont_event->OSEventWaitList = pont_event->OSEventWaitList & ~(PriorityMask[iPriority]);
    
    // Decreases the semaphore wait list counter
    pont_event->OSEventWait--;
    
    // Put the selected task into Ready List
    #if (VERBOSE == 1)
    TaskSelect = PriorityVector[iPriority];
    ContextTask[TaskSelect].State = READY;
    #endif
    
    OSReadyList = OSReadyList | (PriorityMask[iPriority]);
    
    // If outside of an interrupt service routine, change context to the highest priority task
    // If inside of an interrupt, the interrupt itself will change the context to the highest priority task
    if (!iNesting)
    {
      // Verify if there is a higher priority task ready to run
      ChangeContext();      
    }

    // Exit Critical Section
    #if (NESTING_INT == 0)
    if (!iNesting)
    #endif
      OSExitCritical();
    
    return OK;
  }
    
  // Make sure semaphore will not overflow
  if (pont_event->OSEventCount < 255)
  {
    // Increment semaphore count
    pont_event->OSEventCount++;
                         
    // Exit Critical Section
    #if (NESTING_INT == 0)
    if (!iNesting)
    #endif
       OSExitCritical();
    return OK;
  }
  else
  {
    // Exit Critical Section             
    #if (NESTING_INT == 0)
    if (!iNesting)
    #endif
       OSExitCritical();
    
    // Indicates semaphore overflow
    return ERR_SEM_OVF;
  }
}
Example #2
0
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;
}
Example #3
0
File: BRTOS.c Project: brtos/brtos
// Atraso em passos de TickCount
uint8_t OSDelayTask(ostick_t time_wait)
{
  OS_SR_SAVE_VAR
  osdtick_t timeout;
  ContextType *Task = (ContextType*)&ContextTask[currentTask];
   
  if (iNesting > 0) {                                // See if caller is an interrupt
     return(IRQ_PEND_ERR);                           // Can't be blocked by interrupt
  }

  if (currentTask)
  {
    
    if (time_wait > 0)
    {
        OSEnterCritical();
        
        // BRTOS TRACE SUPPORT
        #if (OSTRACE == 1) 
            #if(OS_TRACE_BY_TASK == 1)
            Update_OSTrace(currentTask, DELAYTASK);
            #else
            Update_OSTrace(Task->Priority, DELAYTASK);
            #endif
        #endif    

        timeout = (osdtick_t)((osdtick_t)OSTickCounter + (osdtick_t)time_wait);
        
        if (sizeof_ostick_t < 8){
        	if (timeout >= TICK_COUNT_OVERFLOW)
        	{
        		Task->TimeToWait = (ostick_t)(timeout - TICK_COUNT_OVERFLOW);
        	}
        	else
        	{
        		Task->TimeToWait = (ostick_t)timeout;
        	}
        }else{
        	Task->TimeToWait = (ostick_t)timeout;
        }
        
        // Put task into delay list
        IncludeTaskIntoDelayList();
        
        #if (VERBOSE == 1)
        Task->State = SUSPENDED;
        Task->SuspendedType = DELAY;
        #endif
        
        OSReadyList = OSReadyList & ~(PriorityMask[Task->Priority]);
        
        // Change context
        // Return to task when occur delay overflow
        ChangeContext();
        
        OSExitCritical();
        
        return OK;
    }
    else
    {
        return NO_TASK_DELAY;
    }
  }
  else
  {
    return NOT_VALID_TASK;
  }
}
Example #4
0
INT8U OSMutexRelease(BRTOS_Mutex *pont_event)
{
  OS_SR_SAVE_VAR
  INT8U iPriority = (INT8U)0;
  #if (VERBOSE == 1)
  INT8U TaskSelect = 0;
  #endif
  
  #if (ERROR_CHECK == 1)      
    /// Can not use mutex 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(!iNesting){  
      #if(OS_TRACE_BY_TASK == 1)
      Update_OSTrace(currentTask, MUTEXPOST);
      #else
      Update_OSTrace(ContextTask[currentTask].Priority, MUTEXPOST);
      #endif 
    }else{
      Update_OSTrace(0, MUTEXPOST);
    }
  #endif     

  // Verify Mutex Owner
  if (pont_event->OSEventOwner != currentTask)
  {   
    OSExitCritical();
    return ERR_EVENT_OWNER;
  }  
  
  
  // Returns to the original priority, if needed
  // Copy backuped original priority to the task context
  iPriority = ContextTask[currentTask].Priority;
  if (iPriority != pont_event->OSOriginalPriority)
  {              
    // Since current task is executing with another priority, reallocate its priority to the original
    // into the Ready List
    // Remove "max priority current task" from the Ready List
    OSReadyList = OSReadyList & ~(PriorityMask[iPriority]);
    // Put the "original priority current task" into Ready List
    OSReadyList = OSReadyList | (PriorityMask[pont_event->OSOriginalPriority]);
    
    ContextTask[currentTask].Priority = pont_event->OSOriginalPriority;
  }

  // See if any task is waiting for mutex release
  if (pont_event->OSEventWait != 0)
  {
    // Selects the highest priority task
    iPriority = SAScheduler(pont_event->OSEventWaitList);

    // Remove the selected task from the mutex wait list
    pont_event->OSEventWaitList = pont_event->OSEventWaitList & ~(PriorityMask[iPriority]);
    
    // Decreases the mutex wait list counter
    pont_event->OSEventWait--;
         
    // Indicates that selected task is ready to run
    #if (VERBOSE == 1)
    TaskSelect = PriorityVector[iPriority];
    ContextTask[TaskSelect].State = READY;    
    #endif    
    
    // Put the selected task into Ready List
    OSReadyList = OSReadyList | (PriorityMask[iPriority]);
        
    // Verify if there is a higher priority task ready to run
    ChangeContext();

    // Exit Critical Section
    OSExitCritical();
      
    return OK;
  }
      
  // Release Mutex
  pont_event->OSEventState = AVAILABLE_RESOURCE;
  PriorityVector[pont_event->OSMaxPriority] = MUTEX_PRIO;
      
  // Exit Critical Section
  OSExitCritical();      
  
  return OK;
}
Example #5
0
INT8U OSMutexAcquire(BRTOS_Mutex *pont_event)
{
  OS_SR_SAVE_VAR
  INT8U  iPriority = 0;

  
  #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    
  
  // 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
      ContextTask[currentTask].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
  {
    // Copy task priority to local scope
    iPriority = ContextTask[currentTask].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]);
            
    // Change Context - Returns on mutex release
    ChangeContext();
    
    // Exit Critical Section
    OSExitCritical();
    // Enter Critical Section
    OSEnterCritical();    
    
    // 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 = iPriority;
    
    if (pont_event->OSMaxPriority > iPriority)
    {
      // Receives the priority ceiling temporarily
      ContextTask[currentTask].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;
  }
}
Example #6
0
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;
    }
}