/* * �v���^�X�N�t�b�N�̌Ăяo�� */ void call_pretaskhook(void) { callevel = TCL_PREPOST; set_ipl(ipl_maxisr2); unlock_cpu(); PreTaskHook(); lock_cpu(); set_ipl(IPL_ENA_ALL); callevel = TCL_TASK; }
//when task start to run EXPORT void knl_activate_r(void) { #if(cfgOS_PRE_TASK_HOOK == STD_ON) PreTaskHook(); #endif /* This is the most easiest Way to get Internal Resourse and * to make a task non-preemtable I think */ GetInternalResource(); __asm CLI; // enable interrupt knl_ctxtsk->task(); }
//when task resume to run EXPORT void knl_dispatch_r(void) { #if(cfgOS_SHARE_SYSTEM_STACK == STD_ON) /* Context restore */ //asm ldx knl_ctxtsk; asm lds SP_OFFSET,x; /* Restore 'ssp' from TCB */ #endif #if(cfgOS_PRE_TASK_HOOK == STD_ON) PreTaskHook(); #endif asm pula; asm staa tk_ppage; /* restore PPAGE */ //asm puld; //asm std knl_taskmode /* restore knl_taskmode */ asm rti; }
/********************************************************************** * 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" : : ); }
void vPortPreActivateTask(void) { #if(cfgOS_USE_INTERNAL_RESOURCE == STD_TRUE) if(OSCurTsk < cfgOS_TASK_WITH_IN_RES_NUM) { /* Do Get The Internal Resource */ GetInResource(); } #endif #if(cfgOS_PRE_TASK_HOOK == 1) OS_ENTER_CRITICAL(); PreTaskHook(); OS_EXIT_CRITICAL(); #endif OSTaskEntryTable[OSCurTsk](); OS_ASSERT(STD_FALSE); }
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; }