📄 tasklib.c
字号:
* them with a "t". If <name> is specified as NULL, an ASCII name will be* assigned to the task of the form "t<n>" where <n> is an integer which* increments as new tasks are spawned.** The only resource allocated to a spawned task is a stack of a specified* size <stackSize>, which is allocated from the system memory partition.* Stack size should be an even integer. A task control block (TCB) is* carved from the stack, as well as any memory required by the task name.* The remaining memory is the task's stack and every byte is filled with the* value 0xEE for the checkStack() facility. See the manual entry for* checkStack() for stack-size checking aids.** The entry address <entryPt> is the address of the "main" routine of the task.* The routine will be called once the C environment has been set up.* The specified routine will be called with the ten given arguments.* Should the specified main routine return, a call to exit() will* automatically be made.** Note that ten (and only ten) arguments must be passed for the* spawned function.** Bits in the options argument may be set to run with the following modes:* .iP "VX_FP_TASK (0x0008)" 8* execute with floating-point coprocessor support. A task which performs* floating point operations or calls any functions which either return* or take a floating point value as arguments must be created with this * option. Some routines perform floating point operations internally.* The VxWorks documentation for these clearly state the need to use* the VX_FP_TASK option.* .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, S_taskLib_ILLEGAL_PRIORITY** 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 == (int)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.** argument <name>* 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.** argument <priority>* 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().** 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.** argument <options>* 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_DSP_TASK - execute with dsp support* VX_ALTIVEC_TASK - execute with Alitvec support* VX_STDIO - execute with standard I/O support* .CE* See definitions in taskLib.h.** argument <stackSize>* 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 a task* debug structure WDB_INFO and any memory required by the task's name.* The remaining memory is the task's stack. Every byte of the stack is * filled with the value 0xEE for the checkStack() facility. See checkStack()* for stack size checking aids.** The task stack memory map is: ** For _STACK_GROWS_DOWN:** .CS* - HIGH MEMORY -* ------------------------* | |* | WIND_TCB |* | |* ------------------------ <--- pStackBase, pTcb* |////// 16 bytes //////| * | | (16 bytes clobbered during objFree()* | | in taskDestroy are not accounted for)* | |* | TASK STACK |* | |* | |* | |* ------------------------ <--- pTaskMem* - LOW MEMORY -* .CE** For _STACK_GROWS_UP:** .CS* - HIGH MEMORY -* ------------------------* | |* | |* | |* | TASK STACK |* | |* | |* | |* ------------------------ <--- pStackBase* | |* | WIND_TCB |* | |* ------------------------ <--- pTcb* |////// 16 bytes //////| (clobbered during objFree of taskDestroy)* ------------------------ <--- pTaskMem* - LOW MEMORY -* .CE** argument <entryPt>* 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.** See taskSpawn() for creating tasks with activation.** See taskInit() for initializing tasks with pre-allocated stacks.** RETURNS: Task ID, or NULL 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. * Moreover SIMNT and SIMSPARCSOLARIS use the current task stack for * WINDOWS/UNIX system calls. * 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. * Set this value to 12k which seems enough to prevent stackoverflow. */ stackSize += 0x3000;#endif /* CPU == SIMNT || CPU==SIMHPPA || CPU==SIMSPARCSOLARIS */ /* round stacksize up */ stackSize = STACK_ROUND_UP (stackSize); /* * Allocate the WIND_TCB object, plus additional bytes for * the task stack from the task memory partition. * The 16 bytes of clobbered data is accounted for in the WIND_TCB object. */ pTaskMem = (char *) objAllocExtra ( taskClassId, (unsigned) (stackSize), (void **) NULL ); if (pTaskMem == NULL) return ((int)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;#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. */ pTcb = (WIND_TCB *) (pTaskMem + 16); pStackBase = STACK_ROUND_UP (pTaskMem + 16 + sizeof(WIND_TCB));#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 ((int)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,* S_taskLib_ILLEGAL_PRIORITY** SEE ALSO: taskActivate(), taskSpawn()** VARARGS7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -