예제 #1
0
void OS_TICK_HANDLER(void)
{
  OS_SR_SAVE_VAR
  INT8U  iPrio = 0;  
  ContextType *Task = Head;  
   
  ////////////////////////////////////////////////////
  // Put task with delay overflow in the ready list //
  ////////////////////////////////////////////////////  
  while(Task != NULL)
  {      
      if (Task->TimeToWait == counter)
      {

        iPrio = Task->Priority;
        
        #if (NESTING_INT == 1)
        OSEnterCritical();
        #endif        

        // Put the task into the ready list
        OSReadyList = OSReadyList | (PriorityMask[iPrio]);
        
        #if (VERBOSE == 1)
            Task->State = READY;        
        #endif
        
        Task->TimeToWait = EXIT_BY_TIMEOUT;
        
        #if (NESTING_INT == 1)
        OSExitCritical();
        #endif                  
          
        // Remove from delay list
        RemoveFromDelayList();
      }
 
      Task = Task->Next;
  }

  //////////////////////////////////////////
  // System Load                          //
  //////////////////////////////////////////
  
  #if (COMPUTES_CPU_LOAD == 1)
  #if(DEBUG == 1)
     if (DutyCnt >= 1024)
     {
       DutyCnt = 0;
       OSDuty = (INT32U)((INT32U)OSDuty + (INT32U)OSDutyTmp);
       LastOSDuty = (INT16U)(OSDuty >> 10);
       OSDuty = 0;
     }else
예제 #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;
}
예제 #3
0
파일: BRTOS.c 프로젝트: brtos/brtos
void OS_TICK_HANDLER(void)
{
  OS_SR_SAVE_VAR
  uint8_t  iPrio = 0;  
  ContextType *Task = Head;  
   
  ////////////////////////////////////////////////////
  // Put task with delay overflow in the ready list //
  ////////////////////////////////////////////////////  
  while(Task != NULL)
  {      
      if (Task->TimeToWait == OSTickCounter)
      {

        iPrio = Task->Priority;
        
        #if (NESTING_INT == 1)
        OSEnterCritical();
        #endif        

        // Put the task into the ready list
        OSReadyList = OSReadyList | (PriorityMask[iPrio]);
        
        #if (VERBOSE == 1)
            Task->State = READY;        
        #endif
        
        Task->TimeToWait = EXIT_BY_TIMEOUT;
        
        #if (NESTING_INT == 1)
        OSExitCritical();
        #endif                  
          
        // Remove from delay list
        RemoveFromDelayList();

		#if ((PROCESSOR == ARM_Cortex_M0) || (PROCESSOR == ARM_Cortex_M3) || (PROCESSOR == ARM_Cortex_M4) || (PROCESSOR == ARM_Cortex_M4F))
		OS_INT_EXIT_EXT();
		#endif
      }
 
      Task = Task->Next;
  }

  //////////////////////////////////////////
  // System Load                          //
  //////////////////////////////////////////  
  #if (COMPUTES_CPU_LOAD == 1)
     if (DutyCnt >= 1000)
     {
       DutyCnt = 0;
       LastOSDuty = OSDuty;
       OSDuty = 0;
     }else
     {    
       if (!OSDutyTmp) OSDuty++;
       OSDutyTmp = 0;
       DutyCnt++;
     }
  #endif
  //////////////////////////////////////////
	
  #if (TIMER_HOOK_EN == 1)
    BRTOS_TimerHook();
  #endif
}
예제 #4
0
파일: BRTOS.c 프로젝트: brtos/brtos
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/////  Tasks Uninstall Function             		   /////
/////                                                  /////
/////  Parameters:                                     /////
/////  Task handler									   /////
/////  Turn off of the safety option				   /////
/////                                                  /////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
uint8_t OSUninstallTask(BRTOS_TH TaskHandle, OS_CPU_TYPE safety_off){
	  OS_SR_SAVE_VAR
	  ContextType *Task;
	  ContextType *Task_timer = Head;

	  if (currentTask)
		  // Enter Critical Section
		  OSEnterCritical();

	  // Checks whether the task is uninstalling itself
	  if (!TaskHandle){
		  // If so, verify if the currentTask is valid
		  if (currentTask){
			  //If true, currentTask is the task being uninstall
			  TaskHandle = currentTask;
		  }else{
			  // If not, not valid task
			  // Exit Critical Section
			  OSExitCritical();

			  return NOT_VALID_TASK;
		  }
	  }

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

	  // Verify if is trying to uninstall the idle task
	  if (!(Task->Priority)){
		  if (currentTask)
			  // Exit Critical Section
			  OSExitCritical();

		  return CANNOT_UNINSTALL_IDLE_TASK;
	  }

	  // Checks whether the task handler is valid
	  if (Task != NULL){
		  // Verify if the task is waiting for an event
		  if ((OSReadyList & PriorityMask[Task->Priority]) != PriorityMask[Task->Priority]){
			  // if so, verify if the user ensures that all system objects were deleted
			  if (safety_off == TRUE){
				  // Search the task into timer wait list
				  while(Task_timer != NULL)
				  {
					  if (Task_timer == Task)
					  {
						// Remove from delay list
						RemoveFromDelayList();
						break;
					  }

					  Task_timer = Task_timer->Next;
				  }
			  }else{
				  if (currentTask)
					  // Exit Critical Section
					  OSExitCritical();

				  return TASK_WAITING_EVENT;
			  }
		  }else{
			  // if not, remove the task from the ready list
			  OSReadyList = OSReadyList & ~(PriorityMask[Task->Priority]);
		  }

		  // Proceed with the uninstall
		  TaskAlloc = TaskAlloc & ~(1 << (TaskHandle-1));
		  PriorityVector[Task->Priority] = EMPTY_PRIO;

		  BRTOS_DEALLOC((void*)Task->StackInit);

		  Task->StackInit = 0;
		  Task->StackPoint = 0;
		  Task->StackSize = 0;
		  Task->Priority = EMPTY_PRIO;
		  Task->TimeToWait = NO_TIMEOUT;
		  Task->Next     =  NULL;
		  Task->Previous =  NULL;

		  NumberOfInstalledTasks--;

		  // If uninstalled task if the current task, change context
		  /* OBS.: In the switch context, the context of the uninstalled task will be
		  saved at the deallocated memory. That is not a problem, because the memory will be
		  reused by another task and the current task will never be called again by the system */
		  if (TaskHandle == currentTask) ChangeContext();

		  if (currentTask)
			  // Exit Critical Section
			  OSExitCritical();

		  return OK;
	  }

	  if (currentTask)
		  // Exit Critical Section
		  OSExitCritical();

	  return NOT_VALID_TASK;
}
예제 #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;
    }
}