/********************************************************************** * Return the TCB of the next task ready to run. According to OSEK * specification, the next running task is the task in READY state * with the highest priority. * * @param void * @return ptrTCB Addresse of the TCB **********************************************************************/ ptrTCB GetNextRunningTCB(void) { ptrTCB parserTCB; parserTCB = firstTCB; SuspendOSInterrupts(); while (1) { if ((parserTCB->State & READY) && (parserTCB->State != WAITING)) { if ((parserTCB->Type & ROUND_ROBIN) && !(parserTCB->State & RR_RUNNING)) { if (parserTCB == parserTCB->next) break; else parserTCB = parserTCB->next; continue; } currentTCB = parserTCB; ResumeOSInterrupts(); return(parserTCB); } if (parserTCB == parserTCB->next) break; else parserTCB = parserTCB->next; } ResumeOSInterrupts(); return (NULL); }
/********************************************************************** * Restore CTX and call another task. * * @return void **********************************************************************/ void TaskLauncher(void) { ptrTCB nextTask; /* we are in KERNEL mode : done by SCHEDULE macro */ nextTask = NULL; while (nextTask == NULL) nextTask = GetNextRunningTCB(); if (kernelState & RUN) { SuspendOSInterrupts(); id_tsk_run = nextTask->TaskID; #ifdef PRETASKHOOK PreTaskHook(); #endif WREG15 = (unsigned int)(nextTask->Stack_register); Nop(); SPLIM = (unsigned int)(nextTask->StackAddress); SPLIM += (unsigned int)(nextTask->StackSize); Nop(); WREG14 = (unsigned int)(nextTask->Frame_register); asm ("mov.w [--w15],w0" : : ); asm ("mov.w w0,SR" : : ); asm ("mov.w [--w15],w13" : : ); asm ("mov.w [--w15],w12" : : ); asm ("mov.w [--w15],w11" : : ); asm ("mov.w [--w15],w10" : : ); asm ("mov.w [--w15],w9" : : ); asm ("mov.w [--w15],w8" : : ); asm ("mov.w [--w15],w7" : : ); asm ("mov.w [--w15],w6" : : ); asm ("mov.w [--w15],w5" : : ); asm ("mov.w [--w15],w4" : : ); asm ("mov.w [--w15],w3" : : ); asm ("mov.w [--w15],w2" : : ); asm ("mov.w [--w15],w1" : : ); asm ("mov.w [--w15],w0" : : ); /* Enable interrupts */ asm ("bclr _kernelState, #3" : : ); // Exit KERNEL mode asm ("bset _kernelState, #2" : : ); // Enter USER mode asm volatile ("disi #0x3"); asm ("bclr SR, #5" : : ); // Enable interrupts asm ("bclr SR, #6" : : ); // Enable interrupts asm ("bclr SR, #7" : : ); // Enable interrupts asm ("return" : : ); }
/********************************************************************** * Force a scheduler action * * @return Status E_OK * In fact the function never return **********************************************************************/ StatusType Schedule(void) { SuspendOSInterrupts(); kernelState |= SERVICES; if (kernelState & ISR) // Service called from ISR return (E_OK); kernelState &= ~SERVICES; /* Never return... */ if (kernelState & USER) { #ifdef PRETASKHOOK PostTaskHook(); #endif SCHEDULE(); } return (E_OK); }
/*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); }