void prvTraceInitCortexM()
{
	/* Make sure DWT is enabled is enabled, if supported */
	REG_DEMCR |= DEMCR_TRCENA;

	do{
		/* Verify that DWT is supported */
		if (REG_DEMCR == 0)
		{
			vTraceError("DWT not supported by this chip!");
			break;
		}

		/* Verify that DWT_CYCCNT is supported */
		if (REG_DWT_CTRL & DWT_CTRL_NOCYCCNT)
		{
			vTraceError("DWT_CYCCNT not supported by this chip!");
			break;
		}

		/* Reset the cycle counter */
		REG_DWT_CYCCNT = 0;

		/* Enable the cycle counter */
		REG_DWT_CTRL |= DWT_CTRL_CYCCNTENA;

	}while(0);	/* breaks above jump here */

	if (RecorderDataPtr->frequency == 0)
	{
		RecorderDataPtr->frequency = TRACE_CPU_CLOCK_HZ / HWTC_DIVISOR;
	}
}
/* Returns the exclude state of the object */
uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType handle)
{
	TRACE_ASSERT(objectclass < TRACE_NCLASSES, "prvTraceIsObjectExcluded: objectclass >= TRACE_NCLASSES", 1);
	TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceIsObjectExcluded: Invalid value for handle", 1);
	
	switch(objectclass)
	{
	case TRACE_CLASS_TASK:
		return TRACE_GET_TASK_FLAG_ISEXCLUDED(handle);
	case TRACE_CLASS_SEMAPHORE:
		return TRACE_GET_SEMAPHORE_FLAG_ISEXCLUDED(handle);
	case TRACE_CLASS_MUTEX:
		return TRACE_GET_MUTEX_FLAG_ISEXCLUDED(handle);
	case TRACE_CLASS_QUEUE:
		return TRACE_GET_QUEUE_FLAG_ISEXCLUDED(handle);
	case TRACE_CLASS_TIMER:
		return TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle);		
	case TRACE_CLASS_EVENTGROUP:
		return TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle);				
	}
	
	vTraceError("Invalid object class ID in uiTraceIsObjectExcluded!");
	
	/* Must never reach */
	return 1;
}
Beispiel #3
0
void* xTraceNextFreeEventBufferSlot(void)
{
    if (RecorderDataPtr->nextFreeIndex >= EVENT_BUFFER_SIZE)
    {
        vTraceError("Attempt to index outside event buffer!");
        return NULL;
    }
    return (void*)(&RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex*4]);
}
/*******************************************************************************
 * vTraceSetObjectName
 *
 * Registers the names of queues, semaphores and other kernel objects in the
 * recorder's Object Property Table, at the given handle and object class.
 ******************************************************************************/
void vTraceSetObjectName(traceObjectClass objectclass, 
                         objectHandleType handle, 
                         const char* name)
{
    static uint32_t idx;

    if (handle == 0)
    {
        vTraceError("Illegal handle (0) in vTraceSetObjectName.");   
        return;
    }
    
    switch(objectclass)
    {
        case TRACE_CLASS_TASK:
        case TRACE_CLASS_ISR:
        case TRACE_CLASS_SEMAPHORE:
        case TRACE_CLASS_MUTEX:
        case TRACE_CLASS_QUEUE:
        break;
    default:
        vTraceError("Illegal object class in vTraceSetObjectName");   
        break;            
    }

    if (handle > 
        RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])
    {
        switch(objectclass)
        {
            case TRACE_CLASS_TASK:
            vTraceError("Not enough TASK handles - increase NTask in trcConfig.h");         
            break;
            case TRACE_CLASS_ISR:
            vTraceError("Not enough ISR handles - increase NISR in trcConfig.h");       
            break;
            case TRACE_CLASS_SEMAPHORE:
            vTraceError("Not enough SEMAPHORE handles - increase NSemaphore in trcConfig.h");
            break;
            case TRACE_CLASS_MUTEX:
            vTraceError("Not enough MUTEX handles - increase NMutex in trcConfig.h");
            break;
            case TRACE_CLASS_QUEUE:
            vTraceError("Not enough QUEUE handles - increase NQueue in trcConfig.h");
            break;
        }
    }
    else
    {
        idx = uiIndexOfObject(handle, objectclass);

        if (traceErrorMessage == NULL)
        {
            (void)strncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]),
                    name,
                    RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] );
        }
    }
}
Beispiel #5
0
uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)
{
	TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiIndexOfObject: Invalid value for objectclass", 0);
	TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiIndexOfObject: Invalid value for objecthandle", 0);

    if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) && (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
    {
        return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] + (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));
    }

    vTraceError("Object table lookup with invalid object handle or object class!");
    return 0;
}
/*******************************************************************************
 * prvTraceCreateSymbolTableEntry
 *
 * Creates an entry in the symbol table, independent if it exists already.
 *
 * The strings are stored in a byte pool, with four bytes of "meta-data" for
 * every string.
 * byte 0-1: index of next entry with same checksum (for fast lookup).
 * byte 2-3: reference to a symbol table entry, a label for vTracePrintF
 * format strings only (the handle of the destination channel).
 * byte 4..(4 + length): the string (object name or user event label), with
 * zero-termination
 ******************************************************************************/
uint16_t prvTraceCreateSymbolTableEntry(const char* name, 
                                        uint8_t crc6, 
                                        uint8_t len, 
                                        traceLabel channel)
{
    uint16_t ret = 0;
    if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= SYMBOL_TABLE_SIZE)
    {
        vTraceError("Symbol table full. Increase SYMBOL_TABLE_SIZE in trcConfig.h");
        ret = 0;        
    }
    else
    {

        RecorderDataPtr->SymbolTable.symbytes
            [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex] = 
            (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF);

        RecorderDataPtr->SymbolTable.symbytes
            [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1] = 
            (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100);

        RecorderDataPtr->SymbolTable.symbytes
            [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2] = 
            (uint8_t)(channel & 0x00FF);

        RecorderDataPtr->SymbolTable.symbytes
            [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3] = 
            (uint8_t)(channel / 0x100);

        /* set name (bytes 4...4+len-1) */
        (void)strncpy((char*)&( RecorderDataPtr->SymbolTable.symbytes
            [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4] ), name, len);

        /* Set zero termination (at offest 4+len) */
        RecorderDataPtr->SymbolTable.symbytes
            [RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len] = '\0';

        /* store index of entry (for return value, and as head of LL[crc6]) */
        RecorderDataPtr->SymbolTable.latestEntryOfChecksum
            [ crc6 ] = (uint16_t)RecorderDataPtr->SymbolTable.nextFreeSymbolIndex;
        
        RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += (len + 5);
        
        ret = (uint16_t)(RecorderDataPtr->SymbolTable.nextFreeSymbolIndex - 
            (len + 5));
    }
    
    return ret;
}
Beispiel #7
0
/*******************************************************************************
 * vTraceSetObjectName
 *
 * Registers the names of queues, semaphores and other kernel objects in the
 * recorder's Object Property Table, at the given handle and object class.
 ******************************************************************************/
void vTraceSetObjectName(traceObjectClass objectclass,
                         objectHandleType handle,
                         const char* name)
{
    static uint16_t idx;

	TRACE_ASSERT(name != NULL, "vTraceSetObjectName: name == NULL", );

    if (objectclass >= TRACE_NCLASSES)
    {
        vTraceError("Illegal object class in vTraceSetObjectName");
        return;
    }

    if (handle == 0)
    {
        vTraceError("Illegal handle (0) in vTraceSetObjectName.");
        return;
    }

    if (handle > RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])
    {
	    /* ERROR */
	    vTraceError(pszTraceGetErrorNotEnoughHandles(objectclass));
    }
    else
    {
        idx = uiIndexOfObject(handle, objectclass);

        if (traceErrorMessage == NULL)
        {
            (void)strncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]),
                    name,
                    RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ]);
        }
    }
}
Beispiel #8
0
objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass)
{
	objectHandleType handle;
	static int indexOfHandle;

	TRACE_ASSERT(objectclass < TRACE_NCLASSES, 
		"xTraceGetObjectHandle: Invalid value for objectclass", (objectHandleType)0);

	indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
	if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
	{
		/* Zero is used to indicate a never before used handle, i.e.,
			new slots in the handle stack. The handle slot needs to
			be initialized here (starts at 1). */
		objectHandleStacks.objectHandles[indexOfHandle] =
			(objectHandleType)(1 + indexOfHandle -
			objectHandleStacks.lowestIndexOfClass[objectclass]);
	}

	handle = objectHandleStacks.objectHandles[indexOfHandle];

	if (objectHandleStacks.indexOfNextAvailableHandle[objectclass]
		> objectHandleStacks.highestIndexOfClass[objectclass])
	{
		/* ERROR */
		vTraceError(pszTraceGetErrorNotEnoughHandles(objectclass));

		handle = 0; /* an invalid/anonymous handle - but the recorder is stopped now... */
	}
	else
	{
		int hndCount;
		objectHandleStacks.indexOfNextAvailableHandle[objectclass]++;

		hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] -
			objectHandleStacks.lowestIndexOfClass[objectclass];

		if (hndCount >
			objectHandleStacks.handleCountWaterMarksOfClass[objectclass])
		{
			objectHandleStacks.handleCountWaterMarksOfClass[objectclass] =
				(objectHandleType)hndCount;
		}

		TRACE_CLEAR_OBJECT_FLAG_ISEXCLUDED(objectclass, handle);
	}

	return handle;
}
uint32_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)
{
    if ((objectclass < NCLASSES) && (objecthandle > 0) && (objecthandle <= 
    RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
    {
        return (uint32_t)(RecorderDataPtr->
            ObjectPropertyTable.StartIndexOfClass[objectclass] + 
            (RecorderDataPtr->
            ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * 
            (objecthandle-1)));
    }
    
    vTraceError("Object table lookup with invalid object handle or object class!");    
    return 0;
}
Beispiel #10
0
void* xTraceNextFreeEventBufferSlot(void)
{
	if (! RecorderDataPtr->recorderActive)
	{
		// If the associated XTS or XPS event prio to the main event has filled the buffer and store mode "stop when full".
		return NULL;
	}

	if (RecorderDataPtr->nextFreeIndex >= EVENT_BUFFER_SIZE)
	{
		vTraceError("Attempt to index outside event buffer!");
		return NULL;
	}
	return (void*)(&RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex*4]);
}
Beispiel #11
0
static void vInitStartMarkers()
{
	uint32_t i;
	uint8_t *ptr = (uint8_t*)&(RecorderDataPtr->startmarker0);
	if ((*ptr) == 0)
	{
		for (i = 0; i < 12; i++)
		{
			ptr[i] += 1;
		}
	}
	else
	{
		vTraceError("Trace start markers already initialized!");
	}
}
Beispiel #12
0
void vTraceFreeObjectHandle(traceObjectClass objectclass, objectHandleType handle)
{
    uint32_t indexOfHandle;

    /* Check that there is room to push the handle on the stack */
    if ( (objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) < 
        objectHandleStacks.lowestIndexOfClass[objectclass] )
    {
        /* Error */
        vTraceError("Attempt to free more handles than allocated! (duplicate xTaskDelete or xQueueDelete?)");
    }
    else
    {
        objectHandleStacks.indexOfNextAvailableHandle[objectclass]--;
        indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
        objectHandleStacks.objectHandles[indexOfHandle] = handle;
    }

}
Beispiel #13
0
void vTraceFreeObjectHandle(traceObjectClass objectclass, objectHandleType handle)
{
    int indexOfHandle;

    TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceFreeObjectHandle: Invalid value for objectclass", );
    TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceFreeObjectHandle: Invalid value for handle", );

    /* Check that there is room to push the handle on the stack */
    if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) <
        objectHandleStacks.lowestIndexOfClass[objectclass])
    {
        /* Error */
        vTraceError("Attempt to free more handles than allocated!");
    }
    else
    {
        objectHandleStacks.indexOfNextAvailableHandle[objectclass]--;
        indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
        objectHandleStacks.objectHandles[indexOfHandle] = handle;
    }

}
Beispiel #14
0
RecorderDataType* xTraceInitTraceData(void)
{
    RecorderDataType* tmp = (RecorderDataType*)pvPortMalloc(sizeof(RecorderDataType));

    if (! tmp)
    {
        vTraceError("Malloc failed in xTraceInitTraceData! Reduce size constants in trcConfig.h");
        return NULL;
    }
    
    (void)memset(tmp, 0, sizeof(RecorderDataType));

    tmp->startmarker0 = 0x01;
    tmp->startmarker1 = 0x02;
    tmp->startmarker2 = 0x03;
    tmp->startmarker3 = 0x04;
    tmp->startmarker4 = 0x71;
    tmp->startmarker5 = 0x72;
    tmp->startmarker6 = 0x73;
    tmp->startmarker7 = 0x74;
    tmp->startmarker8 = 0xF1;
    tmp->startmarker9 = 0xF2;
    tmp->startmarker10 = 0xF3;
    tmp->startmarker11 = 0xF4;
    tmp->version = VERSION;
    tmp->minor_version = MINOR_VERSION;
    tmp->irq_priority_order = IRQ_PRIORITY_ORDER;
    tmp->filesize = sizeof(RecorderDataType);
    
    tmp->maxEvents = EVENT_BUFFER_SIZE;
    
    tmp->debugMarker0 = 0xF0F0F0F0;
    tmp->ObjectPropertyTable.NumberOfObjectClasses = NCLASSES;
    tmp->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = DynObjTableSize;
    tmp->ObjectPropertyTable.NumberOfObjectsPerClass[0] = NQueue;
    tmp->ObjectPropertyTable.NumberOfObjectsPerClass[1] = NSemaphore;
    tmp->ObjectPropertyTable.NumberOfObjectsPerClass[2] = NMutex;
    tmp->ObjectPropertyTable.NumberOfObjectsPerClass[3] = NTask;
    tmp->ObjectPropertyTable.NumberOfObjectsPerClass[4] = NISR;
    tmp->ObjectPropertyTable.NameLengthPerClass[0] = NameLenQueue;
    tmp->ObjectPropertyTable.NameLengthPerClass[1] = NameLenSemaphore;
    tmp->ObjectPropertyTable.NameLengthPerClass[2] = NameLenMutex;
    tmp->ObjectPropertyTable.NameLengthPerClass[3] = NameLenTask;
    tmp->ObjectPropertyTable.NameLengthPerClass[4] = NameLenISR;
    tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
    tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
    tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
    tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask;
    tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
    tmp->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
    tmp->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
    tmp->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
    tmp->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask;
    tmp->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;    
    tmp->debugMarker1 = 0xF1F1F1F1;
    tmp->SymbolTable.symTableSize = SYMBOL_TABLE_SIZE;
    tmp->SymbolTable.nextFreeSymbolIndex = 1;
#if (INCLUDE_FLOAT_SUPPORT == 1)
    tmp->exampleFloatEncoding = (float)1.0; /* otherwize already zero */
#endif
    tmp->debugMarker2 = 0xF2F2F2F2;    
    (void)strncpy(tmp->systemInfo, TRACE_DESCRIPTION, TRACE_DESCRIPTION_MAX_LENGTH);
    tmp->debugMarker3 = 0xF3F3F3F3;
    tmp->endmarker0 = 0x0A;
    tmp->endmarker1 = 0x0B;
    tmp->endmarker2 = 0x0C;
    tmp->endmarker3 = 0x0D;
    tmp->endmarker4 = 0x71;
    tmp->endmarker5 = 0x72;
    tmp->endmarker6 = 0x73;
    tmp->endmarker7 = 0x74;
    tmp->endmarker8 = 0xF1;
    tmp->endmarker9 = 0xF2;
    tmp->endmarker10 = 0xF3;
    tmp->endmarker11 = 0xF4;
    
    RecorderDataPtr = tmp;

    return (RecorderDataType*)RecorderDataPtr;
}
Beispiel #15
0
objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass)
{
    static objectHandleType handle;
    static uint32_t indexOfHandle;

    indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
    if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
    {
        /* Zero is used to indicate a never before used handle, i.e.,
           new slots in the handle stack. The handle slot needs to 
           be initialized here (starts at 1). */
        objectHandleStacks.objectHandles[indexOfHandle] = 
            (objectHandleType)(1 + indexOfHandle - 
            objectHandleStacks.lowestIndexOfClass[objectclass]);
    }

    handle = objectHandleStacks.objectHandles[indexOfHandle];
    
    if ( objectHandleStacks.indexOfNextAvailableHandle[objectclass] 
        > objectHandleStacks.highestIndexOfClass[objectclass] )
    {
        /* ERROR */
        switch(objectclass)
        {
            case TRACE_CLASS_TASK:
            vTraceError("Not enough TASK handles - increase NTask in trcConfig.h");         
            break;
            case TRACE_CLASS_ISR:
            vTraceError("Not enough ISR handles - increase NISR in trcConfig.h");         
            break;
            case TRACE_CLASS_SEMAPHORE:
            vTraceError("Not enough SEMAPHORE handles - increase NSemaphore in trcConfig.h");         
            break;
            case TRACE_CLASS_MUTEX:
            vTraceError("Not enough MUTEX handles - increase NMutex in trcConfig.h");         
            break;
            case TRACE_CLASS_QUEUE:
            vTraceError("Not enough QUEUE handles - increase NQueue in trcConfig.h");         
            break;
        }
        
        handle = 0; /* an invalid/anonymous handle - but the recorder is stopped now... */
    }
    else
    {
        int32_t hndCount;
        objectHandleStacks.indexOfNextAvailableHandle[objectclass]++;
        
        hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 
            objectHandleStacks.lowestIndexOfClass[objectclass];
        
        if (hndCount > 
            objectHandleStacks.handleCountWaterMarksOfClass[objectclass])
        {
            objectHandleStacks.handleCountWaterMarksOfClass[objectclass] = 
                (objectHandleType)hndCount;
        }
    }

    return handle;
}
Beispiel #16
0
/******************************************************************************
 * prvTraceGetDTS
 *
 * Returns a differential timestamp (DTS), i.e., the time since
 * last event, and creates an XTS event if the DTS does not fit in the
 * number of bits given. The XTS event holds the MSB bytes of the DTS.
 *
 * The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for
 * events with 16-bit dts fields.
 *****************************************************************************/
uint32_t prvTraceGetDTS(uint32_t param_maxDTS)
{
    XTSEvent* xts;    
    int32_t dts = 0;
    uint32_t old_ts = RecorderDataPtr->absTimeLastEvent;

    if (RecorderDataPtr->frequency == 0)
    {
        /* If HWTC_PERIOD is mapped to the timer reload register,
        such as in the Cortex M port, it is not initialized before
        FreeRTOS has been started. We therefore store the frequency
        of the timer at the first timestamped event after the 
        scheduler has started. (Note that this function is called
        also by vTraceStart and uiTraceStart, which might be
        called before the scheduler has been started.) */

#if (SELECTED_PORT == PORT_Win32)    
        RecorderDataPtr->frequency = 100000;
#elif (SELECTED_PORT == PORT_HWIndependent)    
        RecorderDataPtr->frequency = configTICK_RATE_HZ;
#else        
        if (xTaskGetSchedulerState() != 0) /* Has the scheduler started? */
        {            
            RecorderDataPtr->frequency = 
                 HWTC_PERIOD * configTICK_RATE_HZ / HWTC_DIVISOR; 
        }
#endif
    }

    /**************************************************************************
    * The below statement reads the timestamp from the timer port module. Note 
    * the modulo operation on RecorderDataPtr->frequency, which makes the overflow 
    * case (if (dts < 0)) occur every 1 sec.
    * This is to make it easier to test. The overflow will happen sooner
    * or later anyway.
    **************************************************************************/

    if (RecorderDataPtr->frequency > 0)
    {
        RecorderDataPtr->absTimeLastEvent = 
            uiTracePortGetTimeStamp() % RecorderDataPtr->frequency;
    }
    else
    {
        /* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero)
        The modulo operation is not necessary on the first events, since it is surely much less than 
        one second since startup. */
        RecorderDataPtr->absTimeLastEvent = uiTracePortGetTimeStamp(); 
    }

    dts = (int32_t)(RecorderDataPtr->absTimeLastEvent - old_ts);

    if (dts < 0) /* when the modulo operation wraps around (after 1 second) */
    {
        if (RecorderDataPtr->frequency == 0)
        {
            /* Frequency should normally be initialized on the first logged event after
            the FreeRTOS scheduler has started. In this case, it has not yet been 
            initialized (frequency is 0) and the dts (time since last event) was 
            negative. This is an illegal combination that indicates a problem in 
            uiTracePortGetTimeStamp, probably due to incorrect HWTC macros in trcPort.h.

            The dts variable normally becomes negative when the modulo operation wraps
            around, but since the modulo operation is not used in this case (only used 
            if frequency has been set), dts only becomes negative if
            uiTracePortGetTimeStamp returned a smaller value than last time.
            This is an error. The values returned by uiTracePortGetTimeStamp should be
            monotonically incresing (since it is a timestamp). */

            vTraceError("Timestamping error, see comment in prvTraceGetDTS (trcBase.c)");
            return 0;
        }
        dts = (int32_t)(RecorderDataPtr->frequency - old_ts + RecorderDataPtr->absTimeLastEvent);

        /* This is good for 136 years (incremented every 1 second) */
        RecorderDataPtr->absTimeLastEventSecond++; 
    }

    /* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */
    if (dts > (int32_t)param_maxDTS)
    {
        /* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/
        xts = (XTSEvent*) xTraceNextFreeEventBufferSlot();

        if (xts != NULL)
        {
            if (param_maxDTS == 0xFFFF)
            {
                xts->type = XTS16;
                xts->xts_16 = (uint16_t)((dts / 0x10000) & 0xFFFF);
                xts->xts_8 = 0;
            }
            else if (param_maxDTS == 0xFF)
            {
                xts->type = XTS8;
                xts->xts_16 = (uint16_t)((dts / 0x100) & 0xFFFF);
                xts->xts_8 = (uint8_t)((dts / 0x1000000) & 0xFF);
            }
            else
            {
                vTraceError("Bad param_maxDTS in prvTraceGetDTS");
            }
            prvTraceUpdateCounters();
        }
    }

    return dts % (param_maxDTS + 1);
}
Beispiel #17
0
/* This version of the function dynamically allocates the trace data */
void prvTraceInitTraceData()
{
	init_hwtc_count = HWTC_COUNT;
	
#if TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_STATIC
	RecorderDataPtr = &RecorderData;
#elif TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_DYNAMIC
	RecorderDataPtr = (RecorderDataType*)TRACE_MALLOC(sizeof(RecorderDataType));
#elif TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_CUSTOM
	/* DO NOTHING */
#endif


	TRACE_ASSERT(RecorderDataPtr != NULL, "prvTraceInitTraceData, RecorderDataPtr == NULL", );

    if (! RecorderDataPtr)
    {
        vTraceError("No recorder data structure allocated!");
        return;
    }
		
    (void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType));

    RecorderDataPtr->startmarker0 = 0x00;
    RecorderDataPtr->startmarker1 = 0x01;
    RecorderDataPtr->startmarker2 = 0x02;
    RecorderDataPtr->startmarker3 = 0x03;
    RecorderDataPtr->startmarker4 = 0x70;
    RecorderDataPtr->startmarker5 = 0x71;
    RecorderDataPtr->startmarker6 = 0x72;
    RecorderDataPtr->startmarker7 = 0x73;
    RecorderDataPtr->startmarker8 = 0xF0;
    RecorderDataPtr->startmarker9 = 0xF1;
    RecorderDataPtr->startmarker10 = 0xF2;
    RecorderDataPtr->startmarker11 = 0xF3;

    RecorderDataPtr->version = TRACE_KERNEL_VERSION;
    RecorderDataPtr->minor_version = TRACE_MINOR_VERSION;
    RecorderDataPtr->irq_priority_order = IRQ_PRIORITY_ORDER;
    RecorderDataPtr->filesize = sizeof(RecorderDataType);

    RecorderDataPtr->maxEvents = EVENT_BUFFER_SIZE;

    RecorderDataPtr->debugMarker0 = 0xF0F0F0F0;

	RecorderDataPtr->isUsing16bitHandles = USE_16BIT_OBJECT_HANDLES;

	/* This function is kernel specific */
	vTraceInitObjectPropertyTable();

    RecorderDataPtr->debugMarker1 = 0xF1F1F1F1;
    RecorderDataPtr->SymbolTable.symTableSize = SYMBOL_TABLE_SIZE;
    RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;
#if (INCLUDE_FLOAT_SUPPORT == 1)
    RecorderDataPtr->exampleFloatEncoding = (float)1.0; /* otherwise already zero */
#endif
    RecorderDataPtr->debugMarker2 = 0xF2F2F2F2;
    (void)strncpy(RecorderDataPtr->systemInfo, TRACE_DESCRIPTION, TRACE_DESCRIPTION_MAX_LENGTH);
    RecorderDataPtr->debugMarker3 = 0xF3F3F3F3;
    RecorderDataPtr->endmarker0 = 0x0A;
    RecorderDataPtr->endmarker1 = 0x0B;
    RecorderDataPtr->endmarker2 = 0x0C;
    RecorderDataPtr->endmarker3 = 0x0D;
    RecorderDataPtr->endmarker4 = 0x71;
    RecorderDataPtr->endmarker5 = 0x72;
    RecorderDataPtr->endmarker6 = 0x73;
    RecorderDataPtr->endmarker7 = 0x74;
    RecorderDataPtr->endmarker8 = 0xF1;
    RecorderDataPtr->endmarker9 = 0xF2;
    RecorderDataPtr->endmarker10 = 0xF3;
    RecorderDataPtr->endmarker11 = 0xF4;

#if USE_SEPARATE_USER_EVENT_BUFFER
	RecorderDataPtr->userEventBuffer.bufferID = 1;
	RecorderDataPtr->userEventBuffer.version = 0;
	RecorderDataPtr->userEventBuffer.numberOfSlots = USER_EVENT_BUFFER_SIZE;
	RecorderDataPtr->userEventBuffer.numberOfChannels = CHANNEL_FORMAT_PAIRS + 1;
#endif

	/* Kernel specific initialization of the objectHandleStacks variable */
	vTraceInitObjectHandleStack();

	/* Fix the start markers of the trace data structure */
	vInitStartMarkers();
	
	#ifdef PORT_SPECIFIC_INIT
	PORT_SPECIFIC_INIT();
	#endif
}