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
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; }
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 }
//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// ///// 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; }
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; } }
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; } }