这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 关于Vxworks函数kernelInit()

共4条 1/1 1 跳转至

关于Vxworks函数kernelInit()

菜鸟
2005-08-18 23:23:31     打赏

由于kernelInit()函数起着关键作用,所以本人很想知道该函数的源代码,恳请高人指点!




关键词: 关于     Vxworks     函数     kernelInit    

菜鸟
2005-08-18 23:26:00     打赏
2楼

本人安装的是tornado for arm,在安装目录下根本找不到kernelInit()函数的定义


菜鸟
2005-08-19 16:45:00     打赏
3楼

我想只有在Vxworks操作系统的源代码中才能找到


菜鸟
2005-08-19 19:28:00     打赏
4楼


/*******************************************************************************
*
* 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 */

}


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]