📄 kernellib.c
字号:
* ~ FREE MEMORY POOL ~ pool initialized in kernelRoot()* | |* ------------------------ <--- pMemPoolStart + intStackSize; vxIntStackBase* | |* | INTERRUPT STACK |* | |* ------------------------ <--- pMemPoolStart; vxIntStackEnd* - LOW MEMORY -* .CE** For _STACK_GROWS_UP:** .CS* - HIGH MEMORY -* ------------------------ <--- pMemPoolEnd;* | | We have to leave room for this block header* | 1 BLOCK_HDR | so we can add the root task memory to the pool.* | |* ------------------------ <--- pRootStackEnd;* | |* | ROOT STACK |* | |* ------------------------ <--- pRootStackBase;* | |* | WIND_TCB |* | |* ------------------------* | | We have to leave room for these block headers* | 1 FREE_BLOCK | so we can add the root task memory to the pool.* | 1 BLOCK_HDR |* | |* ------------------------ <--- pRootMemStart;* ------------------------* | |* ~ FREE MEMORY POOL ~ pool initialized in kernelRoot()* | |* ------------------------ <--- pMemPoolStart + intStackSize; vxIntStackEnd* | |* | INTERRUPT STACK |* | |* ------------------------ <--- pMemPoolStart; vxIntStackBase* - LOW MEMORY -* .CE** RETURNS: N/A** SEE ALSO: intLockLevelSet()*/void kernelInit ( FUNCPTR rootRtn, /* user start-up routine */ unsigned rootMemSize, /* memory for TCB and root stack */ char * pMemPoolStart, /* beginning of memory pool */ char * pMemPoolEnd, /* end of memory pool */ unsigned intStackSize, /* interrupt stack size */ int lockOutLevel /* interrupt lock-out level (1-7) */ ) { union { double align8; /* 8-byte alignment dummy */ WIND_TCB initTcb; /* context from which to activate root */ } tcbAligned; WIND_TCB * pTcb; /* pTcb for root task */ unsigned rootStackSize; /* actual stacksize of root task */ unsigned memPoolSize; /* initial size of mem pool */ char * pRootStackBase; /* base of root task's stack */ /* align input size and address parameters */ rootMemNBytes = STACK_ROUND_UP(rootMemSize); pMemPoolStart = (char *) STACK_ROUND_UP(pMemPoolStart); pMemPoolEnd = (char *) STACK_ROUND_DOWN(pMemPoolEnd); intStackSize = STACK_ROUND_UP(intStackSize); /* initialize VxWorks interrupt lock-out level */ intLockLevelSet (lockOutLevel); /* round-robin mode is disabled by default */ roundRobinOn = FALSE; /* initialize the time to zero */ vxTicks = 0; /* good morning */ /* If the architecture supports a separate interrupt stack, * carve the interrupt stack from the beginning of the memory pool * and fill it with 0xee for checkStack (). The MC680[016]0, I960, and * I80X86 not do support a separate interrupt stack. I80X86, however, * allocate the stack for checkStack () which is not used. */#if (_STACK_DIR == _STACK_GROWS_DOWN)#if (CPU != MC68000 && CPU != MC68010 && CPU != MC68060) vxIntStackBase = pMemPoolStart + intStackSize; vxIntStackEnd = pMemPoolStart; bfill (vxIntStackEnd, (int) intStackSize, 0xee);#if (CPU != SH7750 && CPU != SH7729 && CPU != SH7700) windIntStackSet (vxIntStackBase); pMemPoolStart = vxIntStackBase;#else /* CPU == SH7750 || CPU == SH7729 || CPU == SH7700 */ /* If mmu is enabled, emulated SH7700 interrupt stack needs to be relocated * on a fixed physical address space (P1/P2). If mmu is disabled, it is * also possible to put the interrupt stack on copy-back cache (P0/P3). * Note that cache flush is necessary, since above bfill() might be done * on copy-back cache and we may use the area from its behind. */ { pMemPoolStart = vxIntStackBase; /* push out 0xee's on copy-back cache to memory (nop if write-through) */ CACHE_DRV_FLUSH (&cacheLib, vxIntStackEnd, (int) intStackSize); /* relocate interrupt stack to same address space to vector base */ vxIntStackBase = (char *)(((UINT32)vxIntStackBase & 0x1fffffff) | ((UINT32)intVecBaseGet() & 0xe0000000)); vxIntStackEnd = (char *)(((UINT32)vxIntStackEnd & 0x1fffffff) | ((UINT32)intVecBaseGet() & 0xe0000000)); /* load vxIntStackBase to P1/P2 */ windIntStackSet (vxIntStackBase); }#endif /* CPU == SH7750 || CPU == SH7729 || CPU == SH7700 */#if (CPU_FAMILY == ARM) /* * The ARM family uses 3 interrupt stacks. The ratio of the sizes of * these stacks is dependent on the interrupt structure of the board * and so is handled in the BSP code. Note that FIQ is now external to * VxWorks. */ if (_func_armIntStackSplit != NULL) (_func_armIntStackSplit)(vxIntStackBase, intStackSize);#endif /* (CPU_FAMILY == ARM) */#endif /* (CPU != MC68000 && CPU != MC68010 && CPU != MC68060) */#else /* _STACK_DIR == _STACK_GROWS_UP */#if CPU_FAMILY != I960 vxIntStackBase = pMemPoolStart; vxIntStackEnd = pMemPoolStart + intStackSize; bfill (vxIntStackBase, intStackSize, 0xee); windIntStackSet (vxIntStackBase); pMemPoolStart = vxIntStackEnd;#endif /* CPU_FAMILY != I960 */#endif /* (_STACK_DIR == _STACK_GROWS_UP) */ /* Carve the root stack and tcb from the end of the memory pool. We have * to leave room at the very top and bottom of the root task memory for * the memory block headers that are put at the end and beginning of a * free memory block by memLib's memAddToPool() routine. The root stack * is added to the memory pool with memAddToPool as the root task's * dieing breath. */ rootStackSize = rootMemNBytes - WIND_TCB_SIZE - MEM_TOT_BLOCK_SIZE; pRootMemStart = pMemPoolEnd - rootMemNBytes;#if (_STACK_DIR == _STACK_GROWS_DOWN) pRootStackBase = pRootMemStart + rootStackSize + MEM_BASE_BLOCK_SIZE; pTcb = (WIND_TCB *) pRootStackBase;#else /* _STACK_GROWS_UP */ pTcb = (WIND_TCB *) (pRootMemStart + MEM_BASE_BLOCK_SIZE); pRootStackBase = pRootMemStart + WIND_TCB_SIZE + MEM_BASE_BLOCK_SIZE;#endif /* _STACK_GROWS_UP */ /* We initialize the root task with taskIdCurrent == 0. This only works * because when taskInit calls windExit (), the ready queue will be * empty and thus the comparison of taskIdCurrent to the head of the * ready queue will result in equivalence. In this case windExit () * just returns to the caller, without changing anybody's context. */ taskIdCurrent = (WIND_TCB *) NULL; /* initialize taskIdCurrent */ bfill ((char *) &tcbAligned.initTcb, sizeof (WIND_TCB), 0); memPoolSize = (unsigned) ((int) pRootMemStart - (int) pMemPoolStart); taskInit (pTcb, "tRootTask", 0, VX_UNBREAKABLE | VX_DEALLOC_STACK, pRootStackBase, (int) rootStackSize, (FUNCPTR) rootRtn, (int) pMemPoolStart, (int)memPoolSize, 0, 0, 0, 0, 0, 0, 0, 0); rootTaskId = (int) pTcb; /* fill in the root task ID */ /* Now taskIdCurrent needs to point at a context so when we switch into * the root task, we have some place for windExit () to store the old * context. We just use a local stack variable to save memory. */ taskIdCurrent = &tcbAligned.initTcb; /* update taskIdCurrent */ taskActivate ((int) pTcb); /* activate root task */ }/********************************************************************************* kernelVersion - return the kernel revision string** This routine returns a string which contains the current revision of the* kernel. The string is of the form "WIND version x.y", where "x"* corresponds to the kernel major revision, and "y" corresponds to the* kernel minor revision.** RETURNS: A pointer to a string of format "WIND version x.y".*/char *kernelVersion (void) { return ("WIND version 2.6"); }/********************************************************************************* kernelTimeSlice - enable round-robin selection** This routine enables round-robin selection among tasks of same priority* and sets the system time-slice to <ticks>. Round-robin scheduling is* disabled by default. A time-slice of zero ticks disables round-robin* scheduling.** For more information about round-robin scheduling, see the manual entry* for kernelLib.** RETURNS: OK, always.*/STATUS kernelTimeSlice ( int ticks /* time-slice in ticks or 0 to disable round-robin */ ) { if (ticks == 0) /* 0 means turn off round-robin mode */ roundRobinOn = FALSE; else { roundRobinSlice = ticks; /* set new time-slice */ roundRobinOn = TRUE; /* enable round-robin scheduling mode */ } return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -