📄 tasklib.c
字号:
*/STATUS taskInit ( FAST WIND_TCB *pTcb, /* address of new task's TCB */ char *name, /* name of new task (stored at pStackBase) */ int priority, /* priority of new task */ int options, /* task option word */ char *pStackBase, /* base of new task's stack */ int stackSize, /* size (bytes) of stack needed */ FUNCPTR entryPt, /* entry point of new task */ int arg1, /* first of ten task args to pass to func */ int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10 ) { FAST int ix; /* index for create hooks */ int pArgs [MAX_TASK_ARGS]; /* 10 arguments to new task */ unsigned taskNameLen; /* string length of task name */ char *taskName = NULL; /* assume nameless */ if (INT_RESTRICT () != OK) /* restrict ISR from calling */ return (ERROR); if (taskPriRangeCheck) { if ((priority & 0xffffff00) != 0) /* ! (0 <= x <= 255) */ { errno = S_taskLib_ILLEGAL_PRIORITY; return (ERROR); } } if ((!taskLibInstalled) && (taskLibInit () != OK)) return (ERROR); /* package init problem */ /* get arguments into indigenous variables */ pArgs[0] = arg1; pArgs[1] = arg2; pArgs[2] = arg3; pArgs[3] = arg4; pArgs[4] = arg5; pArgs[5] = arg6; pArgs[6] = arg7; pArgs[7] = arg8; pArgs[8] = arg9; pArgs[9] = arg10; /* initialize task control block (in order) */ pTcb->options = options; /* options */ pTcb->status = WIND_SUSPEND; /* initially suspended */ pTcb->priority = priority; /* set priority */ pTcb->priNormal = priority; /* set standard priority */ pTcb->priMutexCnt = 0; /* no mutex owned */ pTcb->pPriMutex = NULL; /* not blocked on pri mutex */ pTcb->lockCnt = 0; /* task w/o preemption lock */ pTcb->tslice = 0; /* no round robin */ pTcb->swapInMask = 0; /* no swap-in hooks */ pTcb->swapOutMask = 0; /* no swap-out hooks */ pTcb->pPendQ = NULL; /* initialize ptr to pend q */ pTcb->safeCnt = 0; /* initialize safe count */ /* initialize safety q head */ qInit (&pTcb->safetyQHead, Q_PRI_LIST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);#if ((CPU_FAMILY == ARM) && ARM_THUMB) pTcb->entry = (FUNCPTR)((UINT32)entryPt & ~1); /* entry address */#else pTcb->entry = entryPt; /* entry address */#endif pTcb->pStackBase = pStackBase; /* initialize stack base */ pTcb->pStackLimit = pStackBase + stackSize*_STACK_DIR; pTcb->pStackEnd = pTcb->pStackLimit; if (!(options & VX_NO_STACK_FILL)) /* fill w/ 0xee for checkStack*/#if (_STACK_DIR == _STACK_GROWS_DOWN) bfill (pTcb->pStackLimit, stackSize, 0xee);#else /* (_STACK_DIR == _STACK_GROWS_UP) */ bfill (pTcb->pStackBase, stackSize, 0xee);#endif /* (_STACK_DIR == _STACK_GROWS_UP) */ taskRegsInit (pTcb, pStackBase); /* initialize register set */ pTcb->errorStatus = OK; /* errorStatus */ pTcb->exitCode = OK; /* field for exit () */ pTcb->pSignalInfo = NULL; /* ptr to signal context */ pTcb->pSelectContext= NULL; /* context not allocated yet */ pTcb->ppEnviron = NULL; /* global environment vars */ pTcb->taskTicks = 0; /* profiling for spyLib */ pTcb->taskIncTicks = 0; /* profiling for spyLib */#if CPU_FAMILY!=I960 pTcb->excInfo.valid = 0; /* exception info is invalid */#else /* CPU_FAMILY == I960 */ pTcb->excInfo.eiType = 0;#endif /* CPU_FAMILY!=I960 */ pTcb->pTaskVar = NULL; /* list of task variables */ pTcb->pRPCModList = NULL; /* rpc module statics context */ pTcb->pFpContext = NULL; /* floating point context */ pTcb->pDspContext = NULL; /* dsp context */ for (ix = 0; ix < 3; ++ix) { pTcb->taskStd[ix] = ix; /* stdin/stdout/stderr fds */ pTcb->taskStdFp[ix] = NULL; /* stdin/stdout/stderr fps */ } pTcb->pSmObjTcb = NULL; /* no shared TCB for now */ pTcb->windxLock = (int)NULL; pTcb->pComLocal = NULL; pTcb->pExcRegSet = NULL; bzero ((char*)&(pTcb->events), sizeof(EVENTS));/* clear events structure */ pTcb->reserved1 = (int)NULL; pTcb->reserved2 = (int)NULL; pTcb->spare1 = (int)NULL; pTcb->spare2 = (int)NULL; pTcb->spare3 = (int)NULL; pTcb->spare4 = (int)NULL; pTcb->pPthread = NULL; pTcb->wdbInfo.wdbState = 0; pTcb->wdbInfo.bpAddr = 0; pTcb->wdbInfo.wdbExitHook = NULL; taskArgsSet (pTcb, pStackBase, pArgs); /* initialize task arguments */#ifdef WV_INSTRUMENTATION /* windview instrumentation */ /* windview - level 1 event logging * The objCore has not been initialised yet so this must be done * by hand. */ EVT_OBJ_TASKSPAWN (EVENT_TASKSPAWN, (int) pTcb, priority, stackSize, (int) entryPt, options); /* windview - The parser must be able to link a name with a task id. */ EVT_CTX_TASKINFO (EVENT_TASKNAME, WIND_SUSPEND, pTcb->priority, pTcb->lockCnt, (int) pTcb, name);#endif kernelState = TRUE; /* KERNEL ENTER */ windSpawn (pTcb); /* spawn the task */#ifdef WV_INSTRUMENTATION /* windview - connect the instrumented class for level 1 event logging */ if (wvObjIsEnabled) objCoreInit (&pTcb->objCore, taskInstClassId); else#endif objCoreInit (&pTcb->objCore, taskClassId); /* validate task ID */ windExit (); /* KERNEL EXIT */ if (name != NULL) /* copy name if not nameless */ { taskNameLen = (unsigned) (strlen (name) + 1); taskName = (char *) taskStackAllot ((int) pTcb, taskNameLen); strcpy (taskName, name); /* copy the name onto stack */ } pTcb->name = taskName; /* name of this task */ for (ix = 0; ix < VX_MAX_TASK_CREATE_RTNS; ++ix) { if (taskCreateTable[ix] != NULL) (*taskCreateTable[ix]) (pTcb); } return (OK); /* return task ID */ }/********************************************************************************* taskActivate - activate a task that has been initialized** This routine activates tasks created by taskInit(). Without activation, a* task is ineligible for CPU allocation by the scheduler.* * The <tid> (task ID) argument is simply the address of the WIND_TCB* for the task (the taskInit() <pTcb> argument), cast to an integer:* .CS* tid = (int) pTcb;* .CE** The taskSpawn() routine is built from taskActivate() and taskInit().* Tasks created by taskSpawn() do not require explicit task activation.** RETURNS: OK, or ERROR if the task cannot be activated.** SEE ALSO: taskInit()*/STATUS taskActivate ( int tid /* task ID of task to activate */ ) { return (taskResume (tid)); /* taskActivate == taskResume */ }/********************************************************************************* exit - exit a task (ANSI)** This routine is called by a task to cease to exist as a task. It is* called implicitly when the "main" routine of a spawned task is exited.* The <code> parameter will be stored in the WIND_TCB for* possible use by the delete hooks, or post-mortem debugging.** ERRNO: N/A** SEE ALSO: taskDelete(),* .I "American National Standard for Information Systems -"* .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdlib.h),"* .pG "Basic OS"*/void exit ( int code /* code stored in TCB for delete hooks */ ) { taskIdCurrent->exitCode = code; /* store the exit code */ taskLock (); /* LOCK PREEMPTION */ taskIdCurrent->options |= VX_UNBREAKABLE; /* mark as unbreakable */ if (taskBpHook != NULL) /* call the debugger hook */ (* taskBpHook) (taskIdCurrent); /* to remove all breakpoints */ taskUnlock (); /* UNLOCK PREEMPTION */ taskDestroy (0, TRUE, WAIT_FOREVER, FALSE); /* self destruct */ }/********************************************************************************* taskDelete - delete a task** This routine causes a specified task to cease to exist and deallocates the* stack and WIND_TCB memory resources. Upon deletion, all routines specified* by taskDeleteHookAdd() will be called in the context of the deleting task.* This routine is the companion routine to taskSpawn().** RETURNS: OK, or ERROR if the task cannot be deleted.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: excLib, taskDeleteHookAdd(), taskSpawn(),* .pG "Basic OS"*/STATUS taskDelete ( int tid /* task ID of task to delete */ ) { return (taskDestroy (tid, TRUE, WAIT_FOREVER, FALSE)); }/********************************************************************************* taskDeleteForce - delete a task without restriction** This routine deletes a task even if the task is protected from deletion. * It is similar to taskDelete(). Upon deletion, all routines* specified by taskDeleteHookAdd() will be called in the context of the* deleting task.** CAVEATS* This routine is intended as a debugging aid, and is generally inappropriate* for applications. Disregarding a task's deletion protection could leave the* the system in an unstable state or lead to system deadlock.** The system does not protect against simultaneous taskDeleteForce() calls.* Such a situation could leave the system in an unstable state.** RETURNS: OK, or ERROR if the task cannot be deleted.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED,* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: taskDeleteHookAdd(), taskDelete()*/STATUS taskDeleteForce ( int tid /* task ID of task to delete */ ) { return (taskDestroy (tid, TRUE, WAIT_FOREVER, TRUE)); }/********************************************************************************* taskTerminate - terminate a task** This routine causes a task to cease to exist but does not deallocate the* stack or WIND_TCB memory. During termination, all routines specified by* taskDeleteHookAdd() will be called in the context of the deleting task.* This routine serves as the companion routine to taskInit(). To delete a* task created by taskSpawn(), see taskDelete().** If a task attempts to terminate itself, the termination and the delete hooks* are performed in the context of the exception task.** RETURNS: OK, or ERROR if task cannot be terminated.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED,* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: excLib, taskDeleteHookAdd(), taskDelete(),* .pG "Basic OS"** NOMANUAL*/STATUS taskTerminate ( int tid /* task ID of task to delete */ ) { return (taskDestroy (tid, FALSE, WAIT_FOREVER, FALSE)); }/********************************************************************************* taskDestroy - destroy a task** This routine causes the specified task to cease to exist and, if successful,* optionally frees the memory associated with the task's stack and* WIND_TCB. This call forms the foundation to the routines taskDelete() and* taskTerminate(). Upon destruction, all routines specified by* taskDeleteHookAdd() will be called in the context of the destroying task.** If a task attempts to destroy itself, the destruction and the delete hooks* are performed in the context of the exception task.** RETURNS: OK, or ERROR if task cannot be destroyed.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED,* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: excLib, taskDeleteHookAdd(), taskTerminate(), taskDelete()** NOMANUAL*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -