由于kernelInit()函数起着关键作用,所以本人很想知道该函数的源代码,恳请高人指点!
关于Vxworks函数kernelInit()
/*******************************************************************************
*
* kernelInit - initialize the kernel
*
* This routine initializes and starts the kernel. It should be called only
* once. The parameter <rootRtn> specifies the entry point of the user's
* start-up code that subsequently initializes system facilities (i.e., the
* I/O system, network). Typically, <rootRtn> is set to usrRoot().
*
* Interrupts are enabled for the first time after kernelInit() exits.
* VxWorks will not exceed the specified interrupt lock-out level during any
* of its brief uses of interrupt locking as a means of mutual exclusion.
*
* The system memory partition is initialized by kernelInit() with the size
* set by <pMemPoolStart> and <pMemPoolEnd>. Architectures that support a
* separate interrupt stack allocate a portion of memory for this
* purpose, of <intStackSize> bytes starting at <pMemPoolStart>.
*
* NOTE SH77XX:
* The interrupt stack is emulated by software, and it has to be located in
* a fixed physical address space (P1 or P2) if the on-chip MMU is enabled.
* If <pMemPoolStart> is in a logical address space (P0 or P3), the interrupt
* stack area is reserved on the same logical address space. The actual
* interrupt stack is relocated to a fixed physical space pointed by VBR.
*
* INTERNAL
* The routine kernelRoot() is called before the user's root routine so that
* memory management can be initialized. The memory setup is as follows:
*
* For _STACK_GROWS_DOWN:
*
* .CS
* - HIGH MEMORY -
* ------------------------ <--- pMemPoolEnd
* | | We have to leave room for this block headers
* | 1 BLOCK_HDR | so we can add the root task memory to the pool.
* | |
* ------------------------
* | |
* | WIND_TCB |
* | |
* ------------------------ <--- pRootStackBase;
* | |
* | ROOT STACK |
* | |
* ------------------------
* | | 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; 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 ALS 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 */
}
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |