/* Periodic Interrupt Timer, included in all Cortex-M4 processors */ void SysTick_Handler(void) { #if (ALARMS_COUNT != 0) /* to save the context during the interrupt */ ContextType context; /* counter increment */ static CounterIncrementType CounterIncrement = 1; (void)CounterIncrement; /* TODO remove me */ /* increment the disable interrupt conter to avoid enable the interrupts */ IntSecure_Start(); /* save actual context */ context = GetCallingContext(); /* set context to CONTEXT_DBG */ SetActualContext(CONTEXT_DBG); /* call counter interrupt handler */ CounterIncrement = IncrementCounter(0, 1 /* CounterIncrement */); /* TODO FIXME */ /* interrupt has to be called first after so many CounterIncrement */ /* SetCounterTime(CounterIncrement); */ /* TODO FIXME */ /* set context back */ SetActualContext(context); /* set the disable interrupt counter back */ IntSecure_End(); #endif /* #if (ALARMS_COUNT != 0) */ /* clear timer interrupt flag */ //not necessary for Cortex-M3 //ClearTimerInterrupt_Cpu(); #if 0 /* TODO */ #if (NON_PREEMPTIVE == DISABLE) /* check if interrupt a Task Context */ if ( GetCallingContext() == CONTEXT_TASK ) { if ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) { /* \req TODO Rescheduling shall take place only if interrupt a * preemptable task. */ (void)Schedule(); } } #endif /* #if (NON_PREEMPTIVE == ENABLE) */ #endif }
/* Cortex-M0 core of LPC4337 uses RIT Timer for periodic IRQ */ void RIT_IRQHandler(void) { if(Chip_RIT_GetIntStatus(LPC_RITIMER) == SET) { /* Store the calling context in a variable. */ ContextType actualContext = GetCallingContext(); /* Set ISR2 context. */ SetActualContext(CONTEXT_ISR2); #if (ALARMS_COUNT != 0) /* Counter increment. */ static CounterIncrementType CounterIncrement = 1; /* TODO remove me. */ (void)CounterIncrement; /* This avoids a compiler warning because the variable is not being used. */ /* * Enter critical section. * */ IntSecure_Start(); /* * The the RTOS counter increment handler. * */ CounterIncrement = IncrementCounter(0, 1 /* CounterIncrement */); /* TODO FIXME */ /* * Exit the critical section. * */ IntSecure_End(); #endif /* #if (ALARMS_COUNT != 0) */ /* reset context */ SetActualContext(actualContext); #if (NON_PREEMPTIVE == OSEK_DISABLE) /* * Check if the currently active task is preemptive; * if it is, call schedule(). * */ if ( ( CONTEXT_TASK == actualContext ) && ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) ) { /* This shall force a call to the scheduler. */ PostIsr2_Arch(isr); } #endif /* #if (NON_PREEMPTIVE == OSEK_DISABLE) */ Chip_RIT_ClearInt(LPC_RITIMER); NVIC_ClearPendingIRQ(RITIMER_IRQn); } }
StatusType ClearEvent ( EventMaskType Mask ) { /* \req OSEK_SYS_3.16 The system service StatusType * ClearEvent ( EventMaskType Mask ) shall be defined */ /* \req OSEK_SYS_3.16.2 Possible return values in Standard mode is E_OK */ StatusType ret = E_OK; #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) if ( GetCallingContext() != CONTEXT_TASK ) { /* \req OSEK_SYS_3.16.3-2/2 Extra possible return values in Extended * mode are E_OS_ACCESS, E_OS_CALLEVEL */ ret = E_OS_CALLEVEL; } else if ( !TasksConst[GetRunningTask()].ConstFlags.Extended ) { /* \req OSEK_SYS_3.16.3-1/2 Extra possible return values in Extended * mode are E_OS_ACCESS, E_OS_CALLEVEL */ ret = E_OS_ACCESS; } else #endif { /* enter to critical code */ IntSecure_Start(); /* \req OSEK_SYS_3.16.1 The events of the extended task calling ClearEvent * are cleared according to the event mask Mask */ TasksVar[GetRunningTask()].Events &= (EventMaskType)~( Mask & TasksConst[GetRunningTask()].EventsMask ); /* finish cirtical code */ IntSecure_End(); } #if ( (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) && \ (HOOK_ERRORHOOK == OSEK_ENABLE) ) /* \req OSEK_ERR_1.3-9/xx The ErrorHook hook routine shall be called if a * system service returns a StatusType value not equal to E_OK.*/ /* \req OSEK_ERR_1.3.1-9/xx The hook routine ErrorHook is not called if a * system service is called from the ErrorHook itself. */ if ( ( ret != E_OK ) && (ErrorHookRunning != 1)) { SetError_Api(OSServiceId_ClearEvent); SetError_Param1(Mask); SetError_Ret(ret); SetError_Msg("ClearEvent returns != than E_OK"); SetError_ErrorHook(); } #endif return ret; }
/* Periodic Interrupt Timer, included in all Cortex-M4 processors */ void SysTick_Handler(void) { /* store the calling context in a variable */ ContextType actualContext = GetCallingContext(); /* set isr 2 context */ SetActualContext(CONTEXT_ISR2); #if (ALARMS_COUNT != 0) /* counter increment */ static CounterIncrementType CounterIncrement = 1; (void)CounterIncrement; /* TODO remove me */ /* increment the disable interrupt conter to avoid enable the interrupts */ IntSecure_Start(); /* call counter interrupt handler */ CounterIncrement = IncrementCounter(0, 1 /* CounterIncrement */); /* TODO FIXME */ /* set the disable interrupt counter back */ IntSecure_End(); #endif /* #if (ALARMS_COUNT != 0) */ /* reset context */ SetActualContext(actualContext); #if (NON_PREEMPTIVE == OSEK_DISABLE) /* check if the actual task is preemptive */ if ( ( CONTEXT_TASK == actualContext ) && ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) ) { /* indicate that the scheduler will be called from isr2 */ // OSEK_ISR2_SchedulerCall = 1; OSEK_ISR2_SchedulerCall++; /* this shall force a call to the scheduler */ PostIsr2_Arch(isr); } #endif /* #if (NON_PREEMPTIVE == OSEK_DISABLE) */ }
/*==================[external functions definition]==========================*/ void OSEK_ISR2_ISRtec(void) { /* store the calling context in a variable */ ContextType actualContext = GetCallingContext(); /* set isr 2 context */ SetActualContext(CONTEXT_ISR2); /* trigger isr 2 */ OSEK_ISR_ISRtec(); /* reset context */ SetActualContext(actualContext); #if (NON_PREEMPTIVE == OSEK_DISABLE) /* check if the actual task is preemptive */ if ( ( CONTEXT_TASK == actualContext ) && ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) ) { /* this shall force a call to the scheduler */ PostIsr2_Arch(isr); } #endif /* #if (NON_PREEMPTIVE == OSEK_ENABLE) */ }
extern StatusType Schedule ( void ) #endif { /* \req OSEK_SYS_3.4 The system service StatusType Schedule ( void ) shall ** be defined */ /* \req OSEK_SYS_3.4.4 Possible return values in Standard mode is E_OK */ StatusType ret = E_OK; TaskType nextTask; TaskType actualTask; #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) ContextType actualContext; #endif IntSecure_Start(); /* get actual running task */ actualTask = GetRunningTask(); /* \req OSEK_SYS_3.3.5 Extra possible return values in Extended mode are E_OS ** CALLEVEL, E_OS_RESOURCE */ #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) /* get actual context */ actualContext = GetCallingContext(); /* if called from scheduler no checks shall be performed */ if (FALSE == PerformChecks) { /* no checks shall be performed */ } else if ( ( CONTEXT_TASK != actualContext ) && ( CONTEXT_SYS != actualContext ) ) { /* \req OSEK_SYS_3.3.5 Extra possible return values in Extended mode ** are E_OS_CALLEVEL, E_OS_RESOURCE */ ret = E_OS_CALLEVEL; } else if ( ( INVALID_TASK != actualTask ) && ( CONTEXT_TASK == actualContext ) ) { if ( TasksVar[actualTask].Resources != 0 ) { /* \req OSEK_SYS_3.3.5 Extra possible return values in Extended mode ** are E_OS_CALLEVEL, E_OS_RESOURCE */ ret = E_OS_RESOURCE; } } else { /* nothing to check Runngin Task is invalid */ } if (ret == E_OK) #endif { /* get next task */ nextTask = GetNextTask(); /* while until one or boths are not more invalid tasks */ while ( ( actualTask == INVALID_TASK ) && ( nextTask == INVALID_TASK) ) { IntSecure_End(); /* macro used to indicate the processor that we are in idle time */ osekpause(); IntSecure_Start(); /* get next task */ nextTask = GetNextTask(); }; /* if the actual task is invalid */ if ( actualTask == INVALID_TASK ) { /* set task state to running */ TasksVar[nextTask].Flags.State = TASK_ST_RUNNING; /* set as running task */ SetRunningTask(nextTask); /* set actual context task */ SetActualContext(CONTEXT_TASK); IntSecure_End(); #if (HOOK_PRETASKHOOK == OSEK_ENABLE) PreTaskHook(); #endif /* #if (HOOK_PRETASKHOOK == OSEK_ENABLE) */ /* jmp tp the next task */ JmpTask(nextTask); } else { /* check priorities */ /* \req OSEK_SYS_3.4.1 If a task with a lower or equal priority than the ** ceiling priority of the internal resource and higher priority than ** the priority of the calling task is ready */ if ( TasksConst[nextTask].StaticPriority > TasksVar[actualTask].ActualPriority ) { #if (HOOK_POSTTASKHOOK == OSEK_ENABLE) PostTaskHook(); #endif /* #if (HOOK_POSTTASKHOOK == OSEK_ENABLE) */ /* \req OSEK_SYS_3.4.1.1 the internal resource of the task shall be ** released */ ReleaseInternalResources(); /* \req OSEK_SYS_3.4.1.2 the current task is put into the ready state */ TasksVar[actualTask].Flags.State = TASK_ST_READY; /* set the new task to running */ TasksVar[nextTask].Flags.State = TASK_ST_RUNNING; /* set as running task */ SetRunningTask(nextTask); /* set actual context task */ SetActualContext(CONTEXT_TASK); IntSecure_End(); #if (HOOK_PRETASKHOOK == OSEK_ENABLE) PreTaskHook(); #endif /* #if (HOOK_PRETASKHOOK == OSEK_ENABLE) */ /* \req OSEK_SYS_3.4.1.3 its context is saved */ /* \req OSEK_SYS_3.4.1.4 and the higher-priority task is executed */ CallTask(actualTask, nextTask); } else { IntSecure_End(); /* \req OSEK_SYS_3.4.2 Otherwise the calling task is continued */ } } } #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) else { IntSecure_End(); } #endif /* #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) */ #if (HOOK_ERRORHOOK == OSEK_ENABLE) /* \req OSEK_ERR_1.3-4/xx The ErrorHook hook routine shall be called if a ** system service returns a StatusType value not equal to E_OK.*/ /* \req OSEK_ERR_1.3.1-4/xx The hook routine ErrorHook is not called if a ** system service is called from the ErrorHook itself. */ if ( ( ret != E_OK ) && (ErrorHookRunning != 1)) { SetError_Api(OSServiceId_Schedule); SetError_Ret(ret); SetError_Msg("Schedule Task returns != than E_OK"); SetError_ErrorHook(); } #endif return ret; }
StatusType ReleaseResource ( ResourceType ResID ) { /* \req OSEK_SYS_3.13 The system service StatusType * ReleaseResource ( ResourceType ResID ) shall be defined */ /* \req OSEK_SYS_3.14.2: Possible return values in Standard mode is * E_OK */ StatusType ret = E_OK; #if (RESOURCES_COUNT != 0) uint8 loopi; #endif /* #if (RESOURCES_COUNT != 0) */ /* asign the static priority to the task */ TaskPriorityType priority = TasksConst[GetRunningTask()].StaticPriority; #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) if ( /* only if one or more resources were defined */ #if (RESOURCES_COUNT != 0) ( ResID >= RESOURCES_COUNT ) #endif /* #if (RESOURCES_COUNT != 0) */ #if ( (RESOURCES_COUNT != 0) && (NO_RES_SCHEDULER == OSEK_DISABLE) ) && #endif /* #if ( (RESOURCES_COUNT != 0) && (NO_RES_SCHEDULER == OSEK_DISABLE) ) */ /* check RES_SCHEDULER only if used */ #if (NO_RES_SCHEDULER == OSEK_DISABLE) ( ResID != RES_SCHEDULER ) #endif /* #if (NO_RES_SCHEDULER == OSEK_DISABLE) */ ) { /* \req OSEK_SYS_3.14.3-1/2 Extra possible return values in Extended mode are * E_OS_ID, E_OS_NOFUNC, E_OS_ACCESS */ ret = E_OS_ID; } else #if (NO_RES_SCHEDULER == OSEK_DISABLE) if ( ResID != RES_SCHEDULER ) #endif /* #if (NO_RES_SCHEDULER == OSEK_DISABLE) */ { if ( ( TasksVar[GetRunningTask()].Resources & ( 1 << ResID ) ) == 0 ) { /* \req OSEK_SYS_3.14.3-2/2 Extra possible return values in Extended mode are ** E_OS_ID, E_OS_NOFUNC, E_OS_ACCESS */ ret = E_OS_NOFUNC; } } #if (NO_RES_SCHEDULER == OSEK_DISABLE) else { /* nothing to do */ } #endif /* #if (NO_RES_SCHEDULER == OSEK_DISABLE) */ if ( ret == E_OK ) #endif /* #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) */ { IntSecure_Start(); #if (RESOURCES_COUNT != 0) #if (NO_RES_SCHEDULER == OSEK_DISABLE) if ( ResID != RES_SCHEDULER ) #endif /* #if (NO_RES_SCHEDULER == OSEK_DISABLE) */ { /* clear resource */ TasksVar[GetRunningTask()].Resources &= ~( 1 << ResID ); } for (loopi = 0; loopi < RESOURCES_COUNT; loopi++) { if ( TasksVar[GetRunningTask()].Resources & ( 1 << loopi ) ) { if ( priority < ResourcesPriority[loopi] ) { priority = ResourcesPriority[loopi]; } } } #endif /* #if (RESOURCES_COUNT != 0) */ /* \req OSEK_SYS_3.14.1 ReleaseResource is the counterpart of GetResource * and serves to leave critical sections in the code that are assigned to * the resource referenced by ResID */ TasksVar[GetRunningTask()].ActualPriority = priority; IntSecure_End(); #if (NON_PREEMPTIVE == OSEK_DISABLE) /* check if called from a Task Context */ if ( GetCallingContext() == CONTEXT_TASK ) { if ( ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) && ( ret == E_OK ) ) { /* \req OSEK_SYS_3.14.4 Rescheduling shall take place only if called from a * preemptable task. */ (void)Schedule(); } } #endif /* #if (NON_PREEMPTIVE == OSEK_DISABLE) */ } #if ( (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) && \ (HOOK_ERRORHOOK == OSEK_ENABLE) ) /* \req OSEK_ERR_1.3-7/xx The ErrorHook hook routine shall be called if a * system service returns a StatusType value not equal to E_OK.*/ /* \req OSEK_ERR_1.3.1-7/xx The hook routine ErrorHook is not called if a * system service is called from the ErrorHook itself. */ if ( ( ret != E_OK ) && (ErrorHookRunning != 1)) { SetError_Api(OSServiceId_ReleaseResource); SetError_Param1(ResID); SetError_Ret(ret); SetError_Msg("ReleaseResource returns != E_OK"); SetError_ErrorHook(); } #endif return ret; }
/*==================[external functions definition]==========================*/ StatusType ActivateTask ( TaskType TaskID ) { /* \req OSEK_SYS_3.1 The system service StatusType * ActivateTask ( TaskType TaskID ) shall be defined. */ /* \req OSEK_SYS_3.1.3 The service may be called from interrupt category 2 * level and from task level. */ /* nothing to do for this req. */ /* \req OSEK_SYS_3.1.7-1/3 Possible return values in Standard mode are E_OK or E_OS_LIMIT */ StatusType ret = E_OK; #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) /* check if the task id is valid */ if ( TaskID >= TASKS_COUNT ) { /* if an invalid task id return E_OS_ID */ /* \req OSEK_SYS_3.1.5-1/3 If other than E_OK is returned the activation * is ignored */ /* \req OSEK_SYS_3.1.8 Added possible return values in Extended mode is * E_OS_ID */ ret = E_OS_ID; } else #endif { IntSecure_Start(); /* check if the task is susspended */ /* \req OSEK_SYS_3.1.1-1/2 The task TaskID shall be transferred from the * suspended state into the ready state. */ if ( TasksVar[TaskID].Flags.State == TASK_ST_SUSPENDED ) { /* increment activation counter */ TasksVar[TaskID].Activations++; /* if the task was suspended set it to ready */ /* OSEK_SYS_3.1.1-2/2 The task TaskID shall be transferred from the * suspended state into the ready state.*/ TasksVar[TaskID].Flags.State = TASK_ST_READY; /* clear all events */ /* \req OSEK_SYS_3.1.6 When an extended task is transferred from * suspended state into ready state all its events are cleared. */ TasksVar[TaskID].Events = 0; /* add the task to the ready list */ AddReady(TaskID); } else { /* task is not suspended */ /* check if the task is a extended task */ if ( TasksConst[TaskID].ConstFlags.Extended ) { /* return E_OS_LIMIT */ /* \req OSEK_SYS_3.1.5-2/3 If other than E_OK is returned the activation * is ignored */ /* \req OSEK_SYS_3.1.7-2/3 Possible return values in Standard mode are * E_OK or E_OS_LIMIT */ ret = E_OS_LIMIT; } else { /* check if more activations are allowed */ if ( TasksVar[TaskID].Activations < TasksConst[TaskID].MaxActivations ) { /* increment activation counter */ TasksVar[TaskID].Activations++; /* add the task to the ready list */ AddReady(TaskID); } else { /* maximal activation reached, return E_OS_LIMIT */ /* \req OSEK_SYS_3.1.5-3/3 If other than E_OK is returned the * activation is ignored */ /* \req OSEK_SYS_3.1.7-3/3 Possible return values in Standard mode are * E_OK or E_OS_LIMIT */ ret = E_OS_LIMIT; } } } IntSecure_End(); #if (NON_PREEMPTIVE == OSEK_DISABLE) /* check if called from a Task Context */ if ( GetCallingContext() == CONTEXT_TASK ) { if ( ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) && ( ret == E_OK ) ) { /* This is needed to avoid Schedule to perform standard checks * which are done when normally called from the application * the actual context has to be task so is not need to store it */ SetActualContext(CONTEXT_SYS); /* \req OSEK_SYS_3.1.4 Rescheduling shall take place only if called from a * preemptable task. */ (void)Schedule(); /* restore the old context */ SetActualContext(CONTEXT_TASK); } } #endif /* #if (NON_PREEMPTIVE == OSEK_DISABLE) */ } #if (HOOK_ERRORHOOK == OSEK_ENABLE) /* \req OSEK_ERR_1.3-1/xx The ErrorHook hook routine shall be called if a * system service returns a StatusType value not equal to E_OK.*/ /* \req OSEK_ERR_1.3.1-1/xx The hook routine ErrorHook is not called if a * system service is called from the ErrorHook itself. */ if ( ( ret != E_OK ) && (ErrorHookRunning != 1U)) { SetError_Api(OSServiceId_ActivateTask); SetError_Param1(TaskID); SetError_Ret(ret); SetError_Msg("ActivateTask returns != than E_OK"); SetError_ErrorHook(); } #endif return ret; }
StatusType SetEvent ( TaskType TaskID, EventMaskType Mask ) { /* \req OSEK_SYS_3.15 The system service StatusType * SetEvent ( TaskType TaskID, EventMaskType Mask ) shall be defined */ /* \req OSEK_SYS_3.15.2: Possible return values in Standard mode is E_OK */ StatusType ret = E_OK; #if (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) if ( TaskID >= TASKS_COUNT ) { /* \req OSEK_SYS_3.15.3-1/3 Extra possible return values in Extended mode * are E_OS_ID, E_OS_ACCESS, E_OS_STATE */ ret = E_OS_ID; } else if ( !TasksConst[TaskID].ConstFlags.Extended ) { /* \req OSEK_SYS_3.15.3-2/3 Extra possible return values in Extended mode * are E_OS_ID, E_OS_ACCESS, E_OS_STATE */ ret = E_OS_ACCESS; } else if ( TasksVar[TaskID].Flags.State == TASK_ST_SUSPENDED ) { /* \req OSEK_SYS_3.15.3-3/3 Extra possible return values in Extended mode * are E_OS_ID, E_OS_ACCESS, E_OS_STATE */ ret = E_OS_STATE; } else #endif { /* enter to critical code */ IntSecure_Start(); /* the event shall be set only if the task is running ready or waiting */ if ( ( TasksVar[TaskID].Flags.State == TASK_ST_RUNNING ) || ( TasksVar[TaskID].Flags.State == TASK_ST_READY ) || ( TasksVar[TaskID].Flags.State == TASK_ST_WAITING) ) { /* set the events */ /* \req OSEK_SYS_3.15.1-1/3 The events of task TaskID are set according to the * event mask Mask. Calling SetEvent causes the task TaskID to be * transferred to the ready state, if it was waiting for at least one * of the events specified in Mask */ TasksVar[TaskID].Events |= ( Mask & TasksConst[TaskID].EventsMask ); /* if the task is waiting and one waiting event occurrs set it to ready */ if ( ( TasksVar[TaskID].Flags.State == TASK_ST_WAITING ) && ( TasksVar[TaskID].EventsWait & TasksVar[TaskID].Events ) ) { /* \req OSEK_SYS_3.15.1-2/3 The events of task TaskID are set according to the * event mask Mask. Calling SetEvent causes the task TaskID to be * transferred to the ready state, if it was waiting for at least one * of the events specified in Mask */ AddReady(TaskID); /* \req OSEK_SYS_3.15.1-3/3 The events of task TaskID are set according to the * event mask Mask. Calling SetEvent causes the task TaskID to be * transferred to the ready state, if it was waiting for at least one * of the events specified in Mask */ TasksVar[TaskID].Flags.State = TASK_ST_READY; IntSecure_End(); #if (NON_PREEMPTIVE == OSEK_DISABLE) /* check if called from a Task Context */ if ( GetCallingContext() == CONTEXT_TASK ) { if ( ( TasksConst[GetRunningTask()].ConstFlags.Preemtive ) && ( ret == E_OK ) ) { /* \req OSEK_SYS_3.15.4 Rescheduling shall take place only if called from a * preemptable task. */ (void)Schedule(); } } #endif /* #if (NON_PREEMPTIVE == OSEK_DISABLE) */ } else { IntSecure_End(); } } else { IntSecure_End(); } } #if ( (ERROR_CHECKING_TYPE == ERROR_CHECKING_EXTENDED) && \ (HOOK_ERRORHOOK == OSEK_ENABLE) ) /* \req OSEK_ERR_1.3-8/xx The ErrorHook hook routine shall be called if a * system service returns a StatusType value not equal to E_OK.*/ /* \req OSEK_ERR_1.3.1-8/xx The hook routine ErrorHook is not called if a * system service is called from the ErrorHook itself. */ if ( ( ret != E_OK ) && (ErrorHookRunning != 1)) { SetError_Api(OSServiceId_SetEvent); SetError_Param1(TaskID); SetError_Param2(Mask); SetError_Ret(ret); SetError_Msg("ActivateTask returns != than E_OK"); SetError_ErrorHook(); } #endif return ret; }