⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wvlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
* In addition to this separate header, this routine also logs all tasks* active in the system to the event buffer for uploading along with the* other events.** This routine should be called after wvEvtLogInit() is called.  If uploading* events continuously to the host, this routine should be called after the * upload task is started.  This ensures that the upload task is included in * the snapshot of active tasks.  If upload will occur after event logging has * stopped (deferred upload), this routine can be called any time before event * logging is turned on.** RETURNS: A valid WV_LOG_HEADER_ID, or NULL if memory can not be allocated.*/WV_LOG_HEADER_ID wvLogHeaderCreate     (    PART_ID   memPart		/* partition where header should be stored */    )    {    WV_LOG_HEADER *pHead;	/* local copy of the log header struct */    int		  *pIntCur;	/* integer pointer into buf */    short	  *pShortCur;	/* short pointer into buf */    char	  *pByteCur;	/* char pointer into buf */    UINT32	   tmp;		/* get around alignment problem */    short cfgEventId;           /* EVENT_CONIG */    int   cfgProtocolRev;    int   cfgTimestampFreq;    int   cfgTimestampPeriod;    int   cfgAutoRollover;    int   cfgClkRate;    int   cfgCollectionMode;    int   cfgProcessorNum;    short bufEventId;           /* EVENT_BUFFER */    int   bufTaskIdCurrent;    short begEventId;           /* EVENT_BEGIN */    int   begCpu;    int   begBspSize;           /* char *begBspName copied directly to buf */    int   begTaskIdCurrent;    int   begCollectionMode;    int   begRevision;    /*      * Get the actual log header structure first, and then figure out how     * big to make it, considering the variable-length bspName field.     */    pHead = (WV_LOG_HEADER *) memPartAlloc (memPart, sizeof (WV_LOG_HEADER));    if (pHead == NULL)	return (NULL);    pHead->len = (EVENT_BEGIN_SIZE + EVENT_CONFIG_SIZE + EVENT_BUFFER_SIZE +		  strlen (sysModel ()));    if (pHead->len & 1)	++pHead->len;        pHead->header = memPartAlloc (memPart, pHead->len);    if (pHead->header == NULL)	{	memPartFree (memPart, (char *) pHead);	return (NULL);	}    pHead->memPart = memPart;    /*     * Get memory for an EVENT_CONFIG buffer from the event buffer, using     * the writeReserve interface.  Then fill in that memory.     */    cfgEventId         = EVENT_CONFIG;    cfgProtocolRev     = WV_REV_ID | WV_EVT_PROTO_REV;    cfgTimestampFreq   = (* _func_tmrFreq) ();    cfgTimestampPeriod = (* _func_tmrPeriod) ();    cfgAutoRollover    = ((* _func_tmrConnect) ((FUNCPTR) _func_evtLogT0,                                                EVENT_TIMER_ROLLOVER)) + 1;    cfgClkRate         = sysClkRateGet ();    cfgCollectionMode  = ((wvEvtClass & WV_CLASS_3) == WV_CLASS_1) ? 1 : 0;    cfgProcessorNum    = sysProcNumGet ();    pShortCur = (short *) pHead->header;    EVT_STORE_UINT16 (pShortCur, cfgEventId);    pIntCur   = (int *) pShortCur;    EVT_STORE_UINT32 (pIntCur, cfgProtocolRev);    EVT_STORE_UINT32 (pIntCur, cfgTimestampFreq);    EVT_STORE_UINT32 (pIntCur, cfgTimestampPeriod);    EVT_STORE_UINT32 (pIntCur, cfgAutoRollover);    EVT_STORE_UINT32 (pIntCur, cfgClkRate);    EVT_STORE_UINT32 (pIntCur, cfgCollectionMode);    EVT_STORE_UINT32 (pIntCur, cfgProcessorNum);    /*     * Do the same for an EVENT_BUFFER.  Reserve memory for the event from     * the event buffer, and then fill in that memory.     */    bufEventId       = EVENT_BUFFER;    bufTaskIdCurrent = (kernelIsIdle) ? (int) ERROR : (int) taskIdCurrent;    pShortCur = (short *) pIntCur;    EVT_STORE_UINT16 (pShortCur, bufEventId);    pIntCur   = (int *) pShortCur;    EVT_STORE_UINT32 (pIntCur, bufTaskIdCurrent);    /*     * Log the EVENT_BEGIN event to the buffer.  The cpu-type member is     * tricky because it has to be of even length to transfer to the host.     * Also the memory reserved has to vary by its length.     */    begEventId        = EVENT_BEGIN;    begCpu            = sysCpu;    tmp = strlen (sysModel ());    if (tmp & 1)        tmp++;    begBspSize        = tmp;    begTaskIdCurrent  = (int) taskIdCurrent;    begCollectionMode  = ((wvEvtClass & WV_CLASS_3) == WV_CLASS_1) ? 1 : 0;    begRevision       = WV_EVT_PROTO_REV;    pShortCur = (short *) pIntCur;    EVT_STORE_UINT16 (pShortCur, begEventId);    pIntCur   = (int *) pShortCur;    EVT_STORE_UINT32 (pIntCur, begCpu);    EVT_STORE_UINT32 (pIntCur, begBspSize);    pByteCur = (char *) pIntCur;    strncpy (pByteCur, sysModel(), begBspSize);    pByteCur += begBspSize;    pIntCur   = (int *) pByteCur;    EVT_STORE_UINT32 (pIntCur, begTaskIdCurrent);    EVT_STORE_UINT32 (pIntCur, begCollectionMode);    EVT_STORE_UINT32 (pIntCur, begRevision);    /* Log a snapshot of active tasks to the event buffer. */    evtLogTasks ();    return (pHead);    }/********************************************************************************* wvLogHeaderUpload - transfer the log header to the host (WindView)** This functions transfers the log header events (EVENT_BEGIN, EVENT_CONFIG,* EVENT_BUFFER) to the host.  These events were saved to a local buffer* with the call to wvLogHeaderCreate().  This routine should be called before* any events or tasknames are uploaded to the host.  The events in the * header buffer must be the first things the parser sees.** If continuously uploading events, it is best to start the uploader, and * then call this routine.  If deferring upload until after event logging* is stopped, this should be called before the uploader is started.** RETURNS: OK, or ERROR if there is trouble with the upload path.*/STATUS wvLogHeaderUpload    (    WV_LOG_HEADER_ID pHeader,		/* pointer to the header */    UPLOAD_ID pathId			/* path by which to upload to host */    )    {    int 	   res;			/* partly notice write errors */    if (pHeader == NULL || pathId == NULL)	return (ERROR);    res = pathId->writeRtn (pathId, pHeader->header, pHeader->len);    if (res < 0)	return (ERROR);    if (pmPartId != NULL)        {    	/* Free the header. */    	memPartFree (pHeader->memPart, (char *) pHeader->header);    	memPartFree (pHeader->memPart, (char *) pHeader);	}    return (OK);    }/********************************************************************************* wvEvtBufferGet - return the ID of the WindView event buffer (WindView)** RETURNS: The event buffer ID if one exists, otherwise NULL.*/BUFFER_ID wvEvtBufferGet (void)    {    return ((wvEvtBufferId == 0) ? (BUFFER_ID) NULL : wvEvtBufferId);    }/********************************************************************************* wvTaskNamesPreserve - preserve an extra copy of task name events (WindView)** This routine initializes the data structures and instrumentation necessary* to allow WindView to store an extra copy of each EVENT_TASKNAME event,* which is necessary for post-mortem analysis.  This routine should be called* after wvEvtLogInit() has been called, and before event logging is started.** If this routine is called before event logging is started, all* EVENT_TASKNAME events that are produced by VxWorks are logged into the* standard event buffer, and a copy of each is logged automatically to the* task name buffer created by this routine.  All tasks running when this * routine is called are also added to the buffer.  The events in this buffer* can be uploaded after the other events have been uploaded, to provide the* task names for any events in the log which no longer have a corresponding* task name event due to wrapping of data in the buffers.  Because there* may be two copies of some of the task name events after the buffer data* wraps around, the resultant log may have two task name events for the same* task.  This is not a problem for the parser.** Occasionally the task ID of a task is reused, and in this case, only* the last instance of the task name event with a particular task ID is* maintained.** The buffer size must be a power of two.** This routine sets the event class WV_CLASS_TASKNAMES_PRESERVE, which can* be turned off by calling wvEvtClassClear() or wvEvtClassSet().** INTERNAL* This routine returns the buffer's ID, which is required later to* destroy and upload the buffer.  The ID is not required to add an event* to the buffer.  That is because additions to the buffer will be done* from an event point, and the event point will not have access to the* buffer's ID.  This is exactly how the event buffer is accessed in * evtLogLib.** The buffer used to store the reserved taskname events is a hash table that * is implemented in wvLib.  All functions associated with this hash table are* prefixed with tnHashTbl.  The implementation of the reserved taskname buffer* has been hidden (albeit barely) from this function, so that any implemen-* tation of a buffer can be used.  The type of the buffer is identified as * a TASKBUF_ID.  The specific implementation of the hash-table buffer is * a TN_HASH_TBL.* * A hash table has been used because, given very specific circumstances, the* task IDs of tasks with different names may be reused.  A hash table allows* easy and fast replacement of the names, so that there is only one name per* tid in the table at any time.  As new names, corresponding to a given tid,* are added, the event is replaced with the newest event.** The hash table was used to avoid multiple taskname events with the same tid,* however there may be a copy of the same event still in the buffer, providing* it has not been overwritten.  In this case there will be two of the same* events anyway, so the hash table is overkill.  Oh well.** RETURNS: A valid TASKBUF_ID to be used for later uploading, or NULL if * not enough memory exists to create the task buffer.*/TASKBUF_ID wvTaskNamesPreserve    (    PART_ID memPart,		/* memory where preserved names are stored */    int	    size 		/* must be a power of 2 */    )    {    int 	   nTasks;			/* number of active tasks */    int		   idList [MAX_WV_TASKS]; 	/* list of active task IDs */    int		   ix;				/* counting index */    TN_HASH_TBL   *pTbl;			/* the taskname buffer */    /* Create the buffer where names will be stored. */    if ((pTbl = tnHashTblCreate (memPart, size)) == NULL)	return (NULL);    /*      * Stash a copy of the the buffer id for table adds, directly from     * event points later.   This has to be done before we add any names.     */    tnHashTbl   = pTbl;    /* Store a copy of each taskname already running in the system. */    nTasks = taskIdListGet (idList, NELEMENTS (idList));    for (ix = 0; ix < nTasks; ++ix)	{	if (taskIdVerify (idList [ix]) == OK)	    {	    wvTaskNamesBufAdd (EVENT_TASKNAME,			       ((WIND_TCB *)idList[ix])->status,			       ((WIND_TCB *)idList[ix])->priority,			       ((WIND_TCB *)idList[ix])->lockCnt,			       idList [ix], taskName (idList [ix]));            }        }    /*      * Let the event point know that it should reserve a copy of each      * future event. It will be turned off when event loggin is turned      * off or reset.     */    WV_EVTCLASS_SET (WV_CLASS_TASKNAMES_PRESERVE);    return ((TASKBUF_ID) pTbl);    }/********************************************************************************* wvTaskNamesUpload - upload preserved task name events (WindView)** This routine uploads task name events, saved after calling * wvTaskNamesPreserve(), to the host by the specified upload path.  There * is no particular order to the events uploaded.  All the events contained * in the buffer are uploaded in one pass.  After all have been uploaded, the * buffer used to store the events is destroyed.** RETURNS: OK, or ERROR if the upload path or task name buffer is invalid.*/STATUS wvTaskNamesUpload     (    TASKBUF_ID taskBufId, 		/* taskname event buffer to upload */    UPLOAD_ID pathId			/* upload path id */    )    {    TN_ITER_KEY   *pIterKey;		/* key to iterate over buffer */    TN_EVENT      *pEvent;		/* event to upload */    int            res = OK;		/* to track errors uploading */    TN_HASH_TBL   *pTbl;		/* just in case a taskbuf is not a 					   taskname hash table */    if (taskBufId == NULL || pathId == NULL)	return (ERROR);     /*      * If the buffer implemented to store taskname events is not a TN_HASH_TBL     * then we need to do the casting here.  It usually is.     */    pTbl = (TN_HASH_TBL *) taskBufId;    /* Create an iterator key to use to access all events in buffer. */    if ((pIterKey = tnHashTblIterInit (pTbl)) == NULL)	return (ERROR);    while ((pEvent = tnHashTblIterNextEvent (taskBufId, pIterKey)) != NULL)	{        /* Write the values one at a time to eliminate padding in the log. */        res = pathId->writeRtn (pathId, & pEvent->eventId, sizeof (short));        res = pathId->writeRtn (pathId, & pEvent->status, sizeof (int));        res = pathId->writeRtn (pathId, & pEvent->priority, sizeof (int));        res = pathId->writeRtn (pathId, & pEvent->taskLockCount, sizeof (int));        res = pathId->writeRtn (pathId, & pEvent->tid, sizeof (int));        res = pathId->writeRtn (pathId, & pEvent->nameSize, sizeof (int));        res = pathId-

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -