📄 tasklib.c
字号:
* execute with floating-point coprocessor support.* .iP "VX_PRIVATE_ENV (0x0080)"* include private environment support (see envLib).* .iP "VX_NO_STACK_FILL (0x0100)"* do not fill the stack for use by checkStack().* .iP "VX_UNBREAKABLE (0x0002)"* do not allow breakpoint debugging.* .LP* See the definitions in taskLib.h.** RETURNS: The task ID, or ERROR if memory is insufficient or the task* cannot be created.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_ID_ERROR,* S_smObjLib_NOT_INITIALIZED, S_memLib_NOT_ENOUGH_MEMORY,* S_memLib_BLOCK_ERROR** SEE ALSO: taskInit(), taskActivate(), sp(),* .pG "Basic OS"** VARARGS5*/int taskSpawn ( char *name, /* name of new task (stored at pStackBase) */ int priority, /* priority of new task */ int options, /* task option word */ int stackSize, /* size (bytes) of stack needed plus name */ FUNCPTR entryPt, /* entry point of new task */ int arg1, /* 1st of 10 req'd task args to pass to func */ int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10 ) { int tid = taskCreat (name, priority, options, stackSize, entryPt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); if (tid == NULL) /* create failed */ return (ERROR); taskActivate (tid); /* activate task */ return (tid); /* return task ID */ }/********************************************************************************* taskCreat - allocate and initialize a task without activation** This routine allocates and initializes a new task with the given priority,* ID, and options. If the task name is specified as NULL, an ASCII name will* be given to the task of the form `task<n>' where <n> is number which* increments as tasks are spawned.** Bits in the options argument may be set to run with the following modes.* .iP VX_UNBREAKABLE 21* do not allow break-point debugging* .iP VX_FP_TASK* execute with coprocessor support* .iP VX_STDIO* execute with standard I/O support* .LP* See the definitions in taskLib.h.** The entry address is the address of the main routine of the task.* This routine will be called with the specified arguments (up to 10).* A stack of the specified size will be allocated from the memory pool.* Stack size should be even. Every byte of this stack is initialized to 0xEE,* as a debugging aid. See checkStack () for stack size checking aids.** Tasks in VxWorks always run in the supervisor mode of the CPU.** See taskInit() for initializing tasks with pre-allocated stacks.** See taskSpawn() for creating tasks with activation.** RETURNS: Task ID, or NULL if out of memory or unable to create task.** SEE ALSO: taskActivate()** This routine creates a new task with the given priority, ID,* and options. The task is not activated. Task creation is the time* consuming portion of taskSpawn(). This routine decouples taskSpawn() into* creation, which this routine handles, and activation which taskActivate()* handles. See taskSpawn() for combined task creation and activation.** A task may be given a name as a debugging aid. This name will show up in* various system information facilities suchas i(). The name may be of* arbitrary length and content, but the current VxWorks convention is to limit* task names to ten characters and prefix them with a `t'. If the task name* is specified as NULL, an ASCII name will be given to the task of the form* `t<n>' where <n> is number which increments as tasks are spawned.** VxWorks schedules tasks on the basis of priority. Tasks may have priorities* ranging from 0, the highest priority, to 255, the lowest priority. VxWorks* system tasks execute with priorities in the range 0 to 50. The priority* of a task in VxWorks in dynamic and one may change an existing task's priority* with taskPrioritySet().** The only resource allocated to a spawned task is a stack of the specified* size which is allocated from the memory pool. Stack size should be even.* A task control block (TCB) is carved from the stack, as well as any memory* required by the task's name. The remaining memory is the task's stack and* every byte is filled with the value 0xEE for the checkStack() facility.* See checkStack () for stack size checking aids.** The entry address is the address of the `main' routine of the task. The* routine will be called once the C environment has been set up by* vxTaskEntry(). Should the specified main routine return, vxTaskEntry() will* automatically call exit(). The specified routine will be called with the* ten given arguments.** Tasks in VxWorks always run in the most privileged mode of the CPU. In* a shared address space, processor privilege offers no protection advantages* and actually hinders performance.** Bits in the options argument may be set to run with the following modes.* .CS* VX_UNBREAKABLE - don't allow break point debugging* VX_FP_TASK - execute with coprocessor support* VX_STDIO - execute with standard I/O support* .CE* See definitions in taskLib.h.** RETURNS: Task ID, or ERROR if out of memory or unable to create task.** SEE ALSO: "Basic OS", taskInit(), taskActivate(), taskSpawn()** VARARGS5* NOMANUAL*/int taskCreat ( char *name, /* name of new task (stored at pStackBase) */ int priority, /* priority of new task */ int options, /* task option word */ int stackSize, /* size (bytes) of stack needed */ FUNCPTR entryPt, /* entry point of new task */ int arg1, /* task argument one */ int arg2, /* task argument two */ int arg3, /* task argument three */ int arg4, /* task argument four */ int arg5, /* task argument five */ int arg6, /* task argument six */ int arg7, /* task argument seven */ int arg8, /* task argument eight */ int arg9, /* task argument nine */ int arg10 /* task argument ten */ ) { char newName[20]; /* place to keep name for nameless tasks */ char * pTaskMem; /* pointer to task memory */ char * pStackBase; /* bottom of stack (higher memory address) */ WIND_TCB * pTcb; /* tcb pointer */ char * pBufStart; /* points to temp name buffer start */ char * pBufEnd; /* points to temp name buffer end */ char temp; /* working character */ int value; /* working value to convert to ascii */ int nPreBytes; /* nameless prefix string length */ int nBytes = 0; /* working nameless name string length */ static char digits [] = "0123456789"; if (name == NULL) /* name nameless w/o sprintf */ { strcpy (newName, namelessPrefix); /* copy in prefix */ nBytes = strlen (newName); /* calculate prefix length */ nPreBytes = nBytes; /* remember prefix strlen() */ value = ++ nameForNameless; /* bump the nameless count */ do /* crank out digits backwards */ { newName [nBytes++] = digits [value % 10]; value /= 10; /* next digit */ } while (value != 0); /* until no more digits */ pBufStart = newName + nPreBytes; /* start reverse after prefix */ pBufEnd = newName + nBytes - 1; /* end reverse at EOS */ while (pBufStart < pBufEnd) /* reverse the digits */ { temp = *pBufStart; *pBufStart = *pBufEnd; *pBufEnd = temp; pBufEnd--; pBufStart++; } newName[nBytes] = EOS; /* EOS terminate string */ name = newName; /* taskInit copies to task */ }#if CPU==SIMSPARCSUNOS || CPU==SIMHPPA || CPU==SIMSPARCSOLARIS if (sysFlags & SYSFLG_DEBUG) stackSize *= 2;#endif /* CPU==SIMSPARCSUNOS || CPU==SIMHPPA || CPU==SIMSPARCSOLARIS */#if (CPU==SIMNT || CPU==SIMHPPA || CPU==SIMSPARCSOLARIS) /* * SIMHPPA and SIMSPARCSOLARIS take interrupts on the current task stack. * Bump all task stack sizes here to compensate, this way * when new vxWorks system tasks are added we won't need * to constantly readjust their default stack sizes. */ stackSize += 8000;#endif /* CPU==SIMHPPA || CPU==SIMSPARCSOLARIS */ /* round stacksize up */ stackSize = STACK_ROUND_UP (stackSize); /* allocate WIND_TCB and stack from task memory partition */ pTaskMem = (char *) objAllocExtra (taskClassId, (unsigned) stackSize, (void **) NULL); if (pTaskMem == NULL) return (NULL); /* allocation failed */#if (_STACK_DIR == _STACK_GROWS_DOWN) /* * A portion of the very top of the stack is clobbered with a FREE_BLOCK * in the objFree() associated with taskDestroy(). There is no adverse * consequence of this, and is thus not accounted for. */ pStackBase = pTaskMem + stackSize; /* grows down from WIND_TCB */ pTcb = (WIND_TCB *) pStackBase; /* WIND_TCB is after stack */#else /* _STACK_GROWS_UP */ /* * To protect a portion of the WIND_TCB that is clobbered with a FREE_BLOCK * in the objFree() associated with taskDestroy(), we goose the base of * tcb by 16 bytes. */ pStackBase = pTaskMem + STACK_ROUND_UP (sizeof (WIND_TCB) + 16); pTcb = (WIND_TCB *) (pTaskMem + 16);#endif options |= VX_DEALLOC_STACK; /* set dealloc option bit */ if (taskInit (pTcb, name, priority, options, pStackBase, stackSize, entryPt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) != OK) { objFree (taskClassId, pTaskMem); return (NULL); } return ((int) pTcb); /* return task ID */ }/********************************************************************************* taskInit - initialize a task with a stack at a specified address** This routine initializes user-specified regions of memory for a task stack* and control block instead of allocating them from memory as taskSpawn()* does. This routine will utilize the specified pointers to the WIND_TCB* and stack as the components of the task. This allows, for example, the* initialization of a static WIND_TCB variable. It also allows for special* stack positioning as a debugging aid.** As in taskSpawn(), a task may be given a name. While taskSpawn()* automatically names unnamed tasks, taskInit() permits the existence of* tasks without names. The task ID required by other task routines* is simply the address <pTcb>, cast to an integer.** Note that the task stack may grow up or down from pStackBase, depending on* the target architecture.** Other arguments are the same as in taskSpawn(). Unlike taskSpawn(),* taskInit() does not activate the task. This must be done by calling* taskActivate() after calling taskInit().** Normally, tasks should be started using taskSpawn() rather than taskInit(),* except when additional control is required for task memory allocation or* a separate task activation is desired.** RETURNS: OK, or ERROR if the task cannot be initialized.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: taskActivate(), taskSpawn()** VARARGS7*/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 ((!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==ARM7TDMI_T pTcb->entry = (FUNCPTR)((UINT32)entryPt & ~1); /* entry address */#else pTcb->entry = entryPt; /* entry address */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -