/* |------------------+---------------------------------------------------------| */ StatusType ClearEvent ( EventMaskType Mask ) { StatusType ercd = E_OK; ID flgid; FLGCB *flgcb; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); flgid = knl_ctxtsk - knl_tcb_table; flgid = knl_gtsk_table[flgid].flgid; OS_CHECK_EXT((flgid != INVALID_EVENT),E_OS_ACCESS); flgcb = &knl_flgcb_table[flgid]; BEGIN_DISABLE_INTERRUPT; flgcb->flgptn &= ~Mask; END_DISABLE_INTERRUPT; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_ClearEvent; _errorhook_par1.mask = Mask; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+--------------------------------------------------------------| */ StatusType GetEvent ( TaskType TaskID , EventMaskRefType Event ) { StatusType ercd = E_OK; ID flgid; FLGCB *flgcb; TCB* tcb; OS_CHECK_EXT((TaskID < cfgOSEK_TASK_NUM),E_OS_ID); flgid = knl_gtsk_table[TaskID].flgid; OS_CHECK_EXT((flgid != INVALID_EVENT),E_OS_ACCESS); tcb = &knl_tcb_table[TaskID]; OS_CHECK_EXT(((tcb->state & (TS_READY | TS_WAIT)) != 0),E_OS_STATE); flgcb = &knl_flgcb_table[flgid]; BEGIN_DISABLE_INTERRUPT; *Event = flgcb->flgptn; END_DISABLE_INTERRUPT; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_GetEvent; _errorhook_par1.tskid = TaskID; _errorhook_par2.p_mask = Event; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-------------------------------------------------------------| */ StatusType Schedule ( void ) { StatusType ercd = E_OK; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE); BEGIN_CRITICAL_SECTION; //if task has internal resource or task is non-premtable if(knl_ready_queue.top_priority <= knl_ctxtsk->itskpri) { //release internal resource or for Non-Preemtable Task knl_ctxtsk->priority = knl_ctxtsk->itskpri; knl_reschedule(); } END_CRITICAL_SECTION; //re-get internal resource or for Non-Preemtable task knl_ctxtsk->priority = knl_ctxtsk->runpri; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_Schedule; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-----------------------------------------------------------| */ StatusType GetResource (ResourceType ResID) { StatusType ercd = E_OK; RESCB *rescb; PRI ceilpri,oldpri; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); //add as share resource with ISR was not supported OS_CHECK_EXT((ResID < cfgOSEK_RESOURCE_NUM),E_OS_ID); rescb = &knl_rescb_table[ResID]; OS_CHECK_EXT((isQueEmpty(&rescb->resque)),E_OS_ACCESS); oldpri = knl_ctxtsk->priority; ceilpri = knl_gres_table[ResID]; OS_CHECK_EXT((ceilpri <= knl_ctxtsk->itskpri),E_OS_ACCESS); BEGIN_DISABLE_INTERRUPT; if(ceilpri < oldpri) { knl_ctxtsk->priority = ceilpri; } rescb->tskpri = oldpri; QueInsert(&rescb->resque,&knl_ctxtsk->resque); END_DISABLE_INTERRUPT; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_GetResource; _errorhook_par1.resid = ResID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+------------------------------------------------------------| */ StatusType ReleaseResource ( ResourceType ResID ) { StatusType ercd = E_OK; RESCB *rescb; PRI ceilpri,oldpri; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); //add as share resource with ISR was not supported OS_CHECK_EXT((ResID < cfgOSEK_RESOURCE_NUM),E_OS_ID); rescb = &knl_rescb_table[ResID]; OS_CHECK_EXT((knl_ctxtsk->resque.prev == &rescb->resque),E_OS_NOFUNC); oldpri = rescb->tskpri; ceilpri = knl_gres_table[ResID]; OS_CHECK_EXT((ceilpri <= knl_ctxtsk->itskpri),E_OS_ACCESS); BEGIN_CRITICAL_SECTION; knl_ctxtsk->priority = oldpri; QueRemove(&rescb->resque); QueInit(&rescb->resque); if(oldpri > knl_ready_queue.top_priority) { knl_preempt(); } END_CRITICAL_SECTION; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_ReleaseResource; _errorhook_par1.resid = ResID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-------------------------------------------------------------| */ StatusType CancelAlarm ( AlarmType AlarmID ) { StatusType ercd = E_OK; ALMCB* almcb; OS_CHECK_EXT((AlarmID < cfgOSEK_ALARM_NUM),E_OS_ID); almcb = &knl_almcb_table[AlarmID]; OS_CHECK((!isQueEmpty(&almcb->almque)),E_OS_NOFUNC); BEGIN_DISABLE_INTERRUPT; QueRemove(&almcb->almque); QueInit(&almcb->almque); END_DISABLE_INTERRUPT; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_CancelAlarm; _errorhook_par1.almid = AlarmID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+------------------------------------------------------------| */ StatusType ReleaseResource ( ResourceType ResID ) { StatusType ercd = E_OK; RESCB *rescb; PRI newpri,oldpri; OS_CHECK_EXT((ResID < cfgOSEK_RESOURCE_NUM),E_OS_ID); rescb = &knl_rescb_table[ResID]; if(in_indp()) /* Interrupt level */ { /* not supported */ } else { OS_CHECK_EXT((knl_ctxtsk->resque.prev == &rescb->resque),E_OS_NOFUNC); oldpri = knl_gres_table[ResID]; newpri = rescb->tskpri; OS_CHECK_EXT((newpri > oldpri),E_OS_ACCESS); BEGIN_CRITICAL_SECTION; if(oldpri < 0) { /* Task share resource with ISR */ /* should change IPL */ /* not supported */ } else { knl_ctxtsk->priority = newpri; QueRemove(&rescb->resque); QueInit(&rescb->resque); if(newpri > knl_ready_queue.top_priority) { knl_preempt(); } } END_CRITICAL_SECTION; } Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_ReleaseResource; _errorhook_par1.resid = ResID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-----------------------------------------------------------| */ StatusType GetResource (ResourceType ResID) { StatusType ercd = E_OK; RESCB *rescb; PRI newpri,oldpri; OS_CHECK_EXT((ResID < cfgOSEK_RESOURCE_NUM),E_OS_ID); rescb = &knl_rescb_table[ResID]; OS_CHECK_EXT((isQueEmpty(&rescb->resque)),E_OS_ACCESS); if(in_indp()) /* Interrupt level */ { /* not supported */ } else { oldpri = knl_ctxtsk->priority; newpri = knl_gres_table[ResID]; OS_CHECK_EXT((newpri < oldpri),E_OS_ACCESS); BEGIN_DISABLE_INTERRUPT; if(newpri < 0) { //TODO: share resourse with ISR /* Task share resource with ISR */ /* should change IPL */ /* not supported */ } else { knl_ctxtsk->priority = newpri; rescb->tskpri = oldpri; QueInsert(&rescb->resque,&knl_ctxtsk->resque); } END_DISABLE_INTERRUPT; } Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_GetResource; _errorhook_par1.resid = ResID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-------------------------------------------------------| */ StatusType GetTaskState ( TaskType TaskID,TaskStateRefType State ) { StatusType ercd = E_OK; TCB* tcb; TSTAT state; OS_CHECK((TaskID<cfgOSEK_TASK_NUM),E_OS_ID); tcb = &knl_tcb_table[TaskID]; state = (TSTAT)tcb->state; if(TS_READY== state) { if(knl_ctxtsk == tcb) { *State = RUNNING; } else { *State = READY; } } else if(TS_WAIT == state) { *State = WAITING; } else { *State = SUSPENDED; } Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_GetTaskState; _errorhook_par1.tskid = TaskID; _errorhook_par2.p_state = State; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+------------------------------------------------------------| */ StatusType ActivateTask ( TaskType TaskID ) { StatusType ercd = E_OK; TCB *tcb; TSTAT state; OS_CHECK((TaskID<cfgOSEK_TASK_NUM),E_OS_ID); tcb = &knl_tcb_table[TaskID]; BEGIN_CRITICAL_SECTION; state = (TSTAT)tcb->state; if (TS_DORMANT == state) { knl_make_active(tcb); } else { #if((cfgOS_CONFORMANCE_CLASS == ECC2) || (cfgOS_CONFORMANCE_CLASS == BCC2)) if(tcb->actcnt < knl_gtsk_table[TaskID].maxact) { tcb->actcnt += 1; #if(cfgOSEK_FIFO_QUEUE_PER_PRIORITY == STD_ON) knl_ready_queue_insert(&knl_ready_queue, tcb); #endif } else #endif { ercd = E_OS_LIMIT; } } END_CRITICAL_SECTION; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_ActivateTask; _errorhook_par1.tskid = TaskID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+--------------------------------------------------------------| */ StatusType TerminateTask ( void ) { StatusType ercd = E_NOT_OK; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE); DISABLE_INTERRUPT; #if(cfgOS_POST_TASK_HOOK == STD_ON) PostTaskHook(); #endif knl_ctxtsk->state = TS_DORMANT; //release internal resource or for non-preemtable task ReleaseInternalResource(); knl_ctxtsk->priority = knl_ctxtsk->itskpri; knl_search_schedtsk(); #if((cfgOS_CONFORMANCE_CLASS == ECC2) || (cfgOS_CONFORMANCE_CLASS == BCC2)) if(knl_ctxtsk->actcnt > 0) { knl_ctxtsk->actcnt -= 1; #if(cfgOSEK_FIFO_QUEUE_PER_PRIORITY == STD_OFF) knl_make_active(knl_ctxtsk); #else knl_make_ready(knl_ctxtsk); #endif } #endif knl_force_dispatch(); /* No return */ Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_TerminateTask; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+------------------------------------------------------------------| */ StatusType GetAlarm ( AlarmType AlarmID ,TickRefType Tick ) { StatusType ercd = E_OK; ALMCB* almcb; CCB *ccb; CounterType cntid; TickType max; OS_CHECK_EXT((AlarmID < cfgOSEK_ALARM_NUM),E_OS_ID); almcb = &knl_almcb_table[AlarmID]; OS_CHECK((!isQueEmpty(&almcb->almque)),E_OS_NOFUNC); cntid = knl_galm_table[AlarmID].owner; ccb = &knl_ccb_table[cntid]; max = knl_almbase_table[cntid].maxallowedvalue; BEGIN_DISABLE_INTERRUPT; if(ccb->curvalue < almcb->time) { *Tick = almcb->time - ccb->curvalue; } else { *Tick = max*2 + 1- ccb->curvalue + almcb->time; } END_DISABLE_INTERRUPT; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_GetAlarm; _errorhook_par1.almid = AlarmID; _errorhook_par2.p_tick = Tick; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+------------------------------------------------------------| */ StatusType WaitEvent( EventMaskType Mask ) { StatusType ercd = E_OK; ID flgid; FLGCB *flgcb; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE); flgid = knl_ctxtsk - knl_tcb_table; flgid = knl_gtsk_table[flgid].flgid; OS_CHECK_EXT((flgid != INVALID_EVENT),E_OS_ACCESS); flgcb = &knl_flgcb_table[flgid]; BEGIN_CRITICAL_SECTION; if((flgcb->flgptn & Mask) == NO_EVENT) { flgcb->waipth = Mask; knl_ctxtsk->state = TS_WAIT; //release internal resource or for Non-Preemtable Task ReleaseInternalResource(); knl_search_schedtsk(); } END_CRITICAL_SECTION; //re-get internal resource or for Non-Preemtable task GetInternalResource(); Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_WaitEvent; _errorhook_par1.mask = Mask; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-----------------------------------------------------------------| */ StatusType SetRelAlarm ( AlarmType AlarmID , TickType Increment ,TickType Cycle ) { StatusType ercd = E_OK; ALMCB *almcb; CCB *ccb; CounterType cntid; TickType max; OS_CHECK_EXT((AlarmID < cfgOSEK_ALARM_NUM),E_OS_ID); almcb = &knl_almcb_table[AlarmID]; OS_CHECK((isQueEmpty(&almcb->almque)),E_OS_STATE); cntid = knl_galm_table[AlarmID].owner; max = knl_almbase_table[cntid].maxallowedvalue; OS_CHECK_EXT((max >= Increment),E_OS_VALUE); OS_CHECK_EXT((max >= Cycle),E_OS_VALUE); OS_CHECK_EXT(((knl_almbase_table[cntid].mincycle <= Cycle) || (0 == Cycle)),E_OS_VALUE); ccb = &knl_ccb_table[cntid]; BEGIN_DISABLE_INTERRUPT; almcb->time = knl_add_ticks(ccb->curvalue,Increment,max*2); almcb->cycle = Cycle; knl_alm_insert(almcb,ccb); END_DISABLE_INTERRUPT; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_SetRelAlarm; _errorhook_par1.almid = AlarmID; _errorhook_par2.incr = Increment; _errorhook_par3.cycle = Cycle; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+----------------------------------------------------------| */ StatusType SetEvent ( TaskType TaskID , EventMaskType Mask ) { StatusType ercd = E_OK; ID flgid; FLGCB *flgcb; TCB *tcb; OS_CHECK_EXT((TaskID < cfgOSEK_TASK_NUM),E_OS_ID); flgid = knl_gtsk_table[TaskID].flgid; OS_CHECK_EXT((flgid != INVALID_EVENT),E_OS_ACCESS); tcb = &knl_tcb_table[TaskID]; OS_CHECK_EXT(((tcb->state & (TS_READY | TS_WAIT)) != 0),E_OS_STATE); flgcb = &knl_flgcb_table[flgid]; BEGIN_CRITICAL_SECTION; flgcb->flgptn |= Mask; if((flgcb->flgptn & flgcb->waipth) != NO_EVENT) { flgcb->waipth = NO_EVENT; tcb->state = TS_READY; knl_make_runnable(tcb); } END_CRITICAL_SECTION; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_SetEvent; _errorhook_par1.tskid = TaskID; _errorhook_par2.mask = Mask; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+------------------------------------------------------------------| */ StatusType GetAlarmBase ( AlarmType AlarmID, AlarmBaseRefType Info ) { StatusType ercd = E_OK; CounterType cntid; OS_CHECK_EXT((AlarmID < cfgOSEK_ALARM_NUM),E_OS_ID); cntid = knl_galm_table[AlarmID].owner; Info->maxallowedvalue = knl_almbase_table[cntid].maxallowedvalue; Info->mincycle = knl_almbase_table[cntid].mincycle; Info->ticksperbase = knl_almbase_table[cntid].ticksperbase; Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_GetAlarmBase; _errorhook_par1.almid = AlarmID; _errorhook_par2.p_info = Info; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
/* |------------------+-------------------------------------------------------------| */ StatusType ChainTask ( TaskType TaskID ) { StatusType ercd = E_NOT_OK; TCB * tcb; TSTAT state; OS_CHECK((TaskID<cfgOSEK_TASK_NUM),E_OS_ID); OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE); DISABLE_INTERRUPT; if(TaskID == knl_ctxtsk->tskid){ /* chain to itself */ knl_search_schedtsk(); knl_make_active(knl_ctxtsk); } else{ /* firstly terminate current running task knl_ctxtsk, * and then activate TaskID */ tcb = &knl_tcb_table[TaskID]; state = (TSTAT)tcb->state; if (TS_DORMANT != state) { #if((cfgOS_CONFORMANCE_CLASS == ECC2) || (cfgOS_CONFORMANCE_CLASS == BCC2)) if(tcb->actcnt < knl_gtsk_table[TaskID].maxact) { tcb->actcnt += 1; #if(cfgOSEK_FIFO_QUEUE_PER_PRIORITY == STD_ON) knl_ready_queue_insert(&knl_ready_queue, tcb); #endif } else #endif { ercd = E_OS_LIMIT; goto Error_Exit; } } #if(cfgOS_POST_TASK_HOOK == STD_ON) PostTaskHook(); #endif knl_ctxtsk->state = TS_DORMANT; knl_search_schedtsk(); #if((cfgOS_CONFORMANCE_CLASS == ECC2) || (cfgOS_CONFORMANCE_CLASS == BCC2)) if(knl_ctxtsk->actcnt > 0) { knl_ctxtsk->actcnt -= 1; #if(cfgOSEK_FIFO_QUEUE_PER_PRIORITY == STD_OFF) knl_make_active(knl_ctxtsk); #else knl_make_ready(knl_ctxtsk); #endif } #endif if (TS_DORMANT == state) { knl_make_active(tcb); } } knl_force_dispatch(); /* No return */ Error_Exit: ENABLE_INTERRUPT; #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_ChainTask; _errorhook_par1.tskid = TaskID; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }