/********************************************************************** * Chain a task by setting the calling task in a SUSPENDED state and * the called taks in the READY state. * Call the scheduler to jump the chained task. * * @param TaskID IN ID of the next task to chain * @return Status E_OK if ID is not correct * In fact the function never return **********************************************************************/ StatusType ChainTask (TaskType TaskID) { ptrTCB thisTCB; unsigned int * ptrRAM; thisTCB = GetCurrentTCB(); thisTCB->State = SUSPENDED; thisTCB = GetSpecificTCB(TaskID); if (thisTCB == NULL) return (E_OS_ID); thisTCB->State = READY; ptrRAM = thisTCB->StackAddress; if (ptrRAM != NULL) { *ptrRAM++ = (unsigned int)(thisTCB->StartAddress); *ptrRAM = 0; thisTCB->Stack_register = SREG(thisTCB->StackAddress); thisTCB->Frame_register = FREG(thisTCB->StackAddress); } DisableAllInterrupts(); kernelState |= KERNEL; kernelState &= ~USER; EnableAllInterrupts(); TaskLauncher(); return (E_OK); }
/********************************************************************** * Allow a task to terminate itself. Cannot terminate another task. * To prepare a new activation of the task, we need first to store in * stack the start adress of the task * * @param dest OUT Destination buffer * @param src IN The byte to copy * @return Status E_OK if ID is not correct * In fact the function never return **********************************************************************/ StatusType TerminateTask (void) { ptrTCB thisTCB; unsigned int * ptrRAM; thisTCB = GetCurrentTCB(); if (thisTCB->State & 0xF0) thisTCB->State -= 0x10; else thisTCB->State = SUSPENDED; ptrRAM = thisTCB->StackAddress; if (ptrRAM != NULL) { *ptrRAM++ = (unsigned int)(thisTCB->StartAddress); *ptrRAM = 0; thisTCB->Stack_register = SREG(thisTCB->StackAddress); thisTCB->Frame_register = FREG(thisTCB->StackAddress); } DisableAllInterrupts(); kernelState |= KERNEL; kernelState &= ~USER; EnableAllInterrupts(); TaskLauncher(); return (E_OK); }
/***************************************************************************************************** * Function: Dispatcher * * Description: Only run on Background task * * Caveats: Non Reentrant *****************************************************************************************************/ void Dispatcher(void) { u16 IndexPriority = MAX_PRIORITY; u16 NoTaskExecuted = TRUE; u16 DispatcherDone = FALSE; while(!DispatcherDone) { do { IndexPriority--; if(DispacherArray[IndexPriority][0U] != 0xFFFF) { TaskExecuted_ID = DispacherArray[IndexPriority][0U]; if(TaskControlBlock[TaskExecuted_ID].Task_Interrupted == TASK_PREEMPTED) { DisableAllInterrupts(); /* Return Context to the Interrupted Task */ TaskControlBlock[TaskExecuted_ID].Task_Interrupted = TASK_NOPREEMPTED; PPAGE_ContextRestore_u8 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.PPAGE_TaskContext_u16; PC_ContextRestore_u16 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.PC_TaskContext_u16; IY_ContextRestore_u16 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.X_TaskContext_u16; IX_ContextRestore_u16 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.Y_TaskContext_u16; D_ContextRestore_u16 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.D_TaskContext_u16; CCR_ContextRestore_u16 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.CCR_TaskContext_u16; SP_ContextRestore_u16 = TaskControlBlock[TaskExecuted_ID].Task_ContextSave.SP_TaskContext_u16; __asm { SEI LDAA #0; TFR A,CCRH; LDS SP_ContextRestore_u16 ; (SP) Load from fixed memory location to SP LDAA PPAGE_ContextRestore_u8 ; (P_PAGE) Load from a fixed memory location to Register A PSHA ; Push the CPU Register A value into the Stack LDD PC_ContextRestore_u16 ; (PC) Load from a fixed memory location to Register D PSHD ; Push the CPU Register D value into the Stack LDD IY_ContextRestore_u16 ; (IY) Load from a fixed memory location to Register D PSHD ; Push the CPU Register D value into the Stack LDD IX_ContextRestore_u16 ; (IX) Load from a fixed memory location to Register D PSHD ; Push the CPU Register D value into the Stack LDD D_ContextRestore_u16 ; (D || BA) Load from a fixed memory location to Register D PSHD ; Push the CPU Register D value into the Stack LDD CCR_ContextRestore_u16 ; (CCR) Load from a fixed memory location to Register D PSHD ; Push the CPU Register D value into the Stack } EnableAllInterrupts(); asm(RTI); } else { TaskControlBlock[TaskExecuted_ID].Task_State = RUNNING; asm(CLI); asm("LDAA #0"); asm("TFR A,CCRH"); TaskConfigInitial->ptr_Task[TaskExecuted_ID].TaskCallback(); NoTaskExecuted = FALSE; } } }
/********************************************************************** * Restore the kernel state and enable the Schedule function: * if a service like SetEvent has been called by an ISR then the service * didn't schedule when it's called but at the end of the ISR, thanks to * the LeaveISR function. * * @param void * @return void **********************************************************************/ void LeaveISR(void) { if (kernelState & USER) { if (kernelState & SERVICES) { kernelState = currentTCB->kernelState_copy; Schedule(); } kernelState = currentTCB->kernelState_copy; } else kernelState &= ~ISR; EnableAllInterrupts(); }
EXTERN_C void StartupHook(void) { EnableAllInterrupts(); }
/*test case:test the reaction of the system called with an activation of a task*/ static void test_t1_instance(void) { ApplicationType ApplicationType_inst_1, ApplicationType_inst_2; ISRType ISRType_inst_1; ObjectAccessType ObjectAccessType_inst_1; ScheduleTableStatusType ScheduleTableStatusType_inst_1; StatusType result_inst_1, result_inst_2, result_inst_3, result_inst_4, result_inst_5, result_inst_6, result_inst_7, result_inst_8, result_inst_9, result_inst_10, result_inst_11, result_inst_12; TickType TickType_inst_1, TickType_inst_2; SCHEDULING_CHECK_STEP(1); DisableAllInterrupts(); SCHEDULING_CHECK_INIT(2); ApplicationType_inst_1 = GetApplicationID(); SCHEDULING_CHECK_AND_EQUAL_INT(3, app1, ApplicationType_inst_1); SCHEDULING_CHECK_INIT(4); ISRType_inst_1 = GetISRID(); SCHEDULING_CHECK_AND_EQUAL_INT(5, INVALID_ISR, ISRType_inst_1); SCHEDULING_CHECK_INIT(6); ObjectAccessType_inst_1 = CheckObjectAccess(app1, OBJECT_TASK, t1); SCHEDULING_CHECK_AND_EQUAL_INT(7, ACCESS, ObjectAccessType_inst_1); SCHEDULING_CHECK_INIT(8); ApplicationType_inst_2 = CheckObjectOwnership(OBJECT_TASK, t1); SCHEDULING_CHECK_AND_EQUAL_INT(9, app1, ApplicationType_inst_2); SCHEDULING_CHECK_INIT(10); result_inst_1 = StartScheduleTableRel(sched1, 1); SCHEDULING_CHECK_AND_EQUAL_INT(11, E_OS_DISABLEDINT, result_inst_1); SCHEDULING_CHECK_INIT(12); result_inst_2 = StartScheduleTableAbs(sched1, 0); SCHEDULING_CHECK_AND_EQUAL_INT(13, E_OS_DISABLEDINT, result_inst_2); SCHEDULING_CHECK_INIT(14); result_inst_3 = StopScheduleTable(sched1); SCHEDULING_CHECK_AND_EQUAL_INT(15, E_OS_DISABLEDINT, result_inst_3); SCHEDULING_CHECK_INIT(16); result_inst_4 = NextScheduleTable(sched1, sched2); SCHEDULING_CHECK_AND_EQUAL_INT(17, E_OS_DISABLEDINT, result_inst_4); SCHEDULING_CHECK_INIT(18); result_inst_5 = StartScheduleTableSynchron(sched1); SCHEDULING_CHECK_AND_EQUAL_INT(19, E_OS_DISABLEDINT, result_inst_5); SCHEDULING_CHECK_INIT(20); result_inst_6 = SyncScheduleTable(sched1, 0); SCHEDULING_CHECK_AND_EQUAL_INT(21, E_OS_DISABLEDINT, result_inst_6); SCHEDULING_CHECK_INIT(22); result_inst_7 = GetScheduleTableStatus(sched1, &ScheduleTableStatusType_inst_1); SCHEDULING_CHECK_AND_EQUAL_INT(23, E_OS_DISABLEDINT, result_inst_7); SCHEDULING_CHECK_INIT(24); result_inst_8 = SetScheduleTableAsync(sched1); SCHEDULING_CHECK_AND_EQUAL_INT(25, E_OS_DISABLEDINT, result_inst_8); SCHEDULING_CHECK_INIT(26); result_inst_9 = IncrementCounter(Software_Counter1); SCHEDULING_CHECK_AND_EQUAL_INT(27, E_OS_DISABLEDINT, result_inst_9); SCHEDULING_CHECK_INIT(28); result_inst_10 = GetCounterValue(Software_Counter1, &TickType_inst_1); SCHEDULING_CHECK_AND_EQUAL_INT(29, E_OS_DISABLEDINT, result_inst_10); SCHEDULING_CHECK_INIT(30); result_inst_11 = GetElapsedCounterValue(Software_Counter1, &TickType_inst_1, &TickType_inst_2); SCHEDULING_CHECK_AND_EQUAL_INT(31, E_OS_DISABLEDINT, result_inst_11); SCHEDULING_CHECK_INIT(32); result_inst_12 = TerminateApplication(app1, NO_RESTART); SCHEDULING_CHECK_AND_EQUAL_INT(33, E_OS_DISABLEDINT, result_inst_12); SCHEDULING_CHECK_STEP(34); EnableAllInterrupts(); /* Missing : - CallTrustedFunction - CheckISRMemoryAccess - CheckTaskMemoryAccess - GetActiveApplicationMode (OS tests) Ok but not tested : - StartOS (OS tests) - ShutdownOS (OS tests) */ }
/*test case:test the reaction of the system called with an activation of a task*/ static void test_t1_instance(void) { StatusType result_inst_1, result_inst_2, result_inst_3; SCHEDULING_CHECK_STEP(1); SuspendAllInterrupts(); SCHEDULING_CHECK_INIT(2); result_inst_1 = ActivateTask(t2); SCHEDULING_CHECK_AND_EQUAL_INT(2,E_OS_DISABLEDINT, result_inst_1); SCHEDULING_CHECK_STEP(3); sendSoftwareIt(0, SOFT_IRQ0); SCHEDULING_CHECK_STEP(4); ResumeOSInterrupts(); SCHEDULING_CHECK_STEP(5); EnableAllInterrupts(); SCHEDULING_CHECK_STEP(6); ResumeAllInterrupts(); SCHEDULING_CHECK_STEP(8); SuspendOSInterrupts(); SCHEDULING_CHECK_INIT(9); result_inst_2 = ActivateTask(t2); SCHEDULING_CHECK_AND_EQUAL_INT(9,E_OS_DISABLEDINT, result_inst_2); SCHEDULING_CHECK_STEP(10); sendSoftwareIt(0, SOFT_IRQ0); SCHEDULING_CHECK_STEP(11); ResumeAllInterrupts(); SCHEDULING_CHECK_STEP(12); EnableAllInterrupts(); SCHEDULING_CHECK_STEP(13); DisableAllInterrupts(); SCHEDULING_CHECK_STEP(14); EnableAllInterrupts(); SCHEDULING_CHECK_STEP(15); ResumeOSInterrupts(); SCHEDULING_CHECK_STEP(17); DisableAllInterrupts(); SCHEDULING_CHECK_INIT(18); result_inst_3 = ActivateTask(t2); SCHEDULING_CHECK_AND_EQUAL_INT(18,E_OS_DISABLEDINT, result_inst_3); SCHEDULING_CHECK_STEP(19); sendSoftwareIt(0, SOFT_IRQ0); SCHEDULING_CHECK_STEP(20); ResumeAllInterrupts(); SCHEDULING_CHECK_STEP(21); ResumeOSInterrupts(); SCHEDULING_CHECK_STEP(22); EnableAllInterrupts(); SCHEDULING_CHECK_STEP(24); }