[修改] 增加freeRTOS
1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
256
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEventBuffer.c
Normal file
256
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEventBuffer.c
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Percepio Trace Recorder for Tracealyzer v4.6.0
|
||||
* Copyright 2021 Percepio AB
|
||||
* www.percepio.com
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* The implementation for the event buffer.
|
||||
*/
|
||||
|
||||
#include <trcRecorder.h>
|
||||
|
||||
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
||||
|
||||
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||||
|
||||
traceResult xTraceEventBufferInitialize(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiOptions,
|
||||
uint8_t* puiBuffer, uint32_t uiSize)
|
||||
{
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(pxTraceEventBuffer != 0);
|
||||
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(puiBuffer != 0);
|
||||
|
||||
pxTraceEventBuffer->uiOptions = uiOptions;
|
||||
pxTraceEventBuffer->uiHead = 0;
|
||||
pxTraceEventBuffer->uiTail = 0;
|
||||
pxTraceEventBuffer->uiSize = uiSize;
|
||||
pxTraceEventBuffer->uiFree = uiSize;
|
||||
pxTraceEventBuffer->puiBuffer = puiBuffer;
|
||||
pxTraceEventBuffer->uiTimerWraparounds = 0;
|
||||
|
||||
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT_BUFFER);
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pops the oldest event from the Event Buffer.
|
||||
*
|
||||
* @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
|
||||
*
|
||||
* @retval TRC_FAIL Failure
|
||||
* @retval TRC_SUCCESS Success
|
||||
*/
|
||||
static traceResult prvTraceEventBufferPop(TraceEventBuffer_t *pxTraceEventBuffer)
|
||||
{
|
||||
uint32_t uiFreeSize = 0;
|
||||
|
||||
/* Get size of event we are freeing */
|
||||
/* This should never fail */
|
||||
TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS);
|
||||
|
||||
pxTraceEventBuffer->uiFree += uiFreeSize;
|
||||
|
||||
/* Update tail to point to the new last event */
|
||||
pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pxData, uint32_t uiDataSize, int32_t *piBytesWritten)
|
||||
{
|
||||
uint32_t uiBufferSize;
|
||||
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(pxTraceEventBuffer != 0);
|
||||
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(pxData != 0);
|
||||
|
||||
uiBufferSize = pxTraceEventBuffer->uiSize;
|
||||
|
||||
/* Check if the data size is larger than the buffer */
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(uiDataSize <= uiBufferSize);
|
||||
|
||||
/* Check byte alignment */
|
||||
/* This should never fail */
|
||||
TRC_ASSERT((uiDataSize % 4) == 0);
|
||||
|
||||
/* Ensure bytes written start at 0 */
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(piBytesWritten != 0);
|
||||
|
||||
*piBytesWritten = 0;
|
||||
|
||||
/* This should never fail */
|
||||
TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
|
||||
|
||||
/* In ring buffer mode we cannot provide lock free access since the producer modified
|
||||
* the head and tail variables in the same call. This option is only safe when used
|
||||
* with an internal buffer (streaming snapshot) which no consumer accesses.
|
||||
*/
|
||||
switch (pxTraceEventBuffer->uiOptions)
|
||||
{
|
||||
case TRC_EVENT_BUFFER_OPTION_OVERWRITE:
|
||||
{
|
||||
uint32_t uiHead = pxTraceEventBuffer->uiHead;
|
||||
|
||||
/* If there isn't enough space in the buffer pop events until there is */
|
||||
while (pxTraceEventBuffer->uiFree < uiDataSize)
|
||||
{
|
||||
prvTraceEventBufferPop(pxTraceEventBuffer);
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
if ((uiBufferSize - uiHead) > uiDataSize)
|
||||
{
|
||||
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pxData, uiDataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pxData, uiBufferSize - uiHead);
|
||||
TRC_MEMCPY(pxTraceEventBuffer->puiBuffer,
|
||||
(void*)(&((uint8_t*)pxData)[(uiBufferSize - uiHead)]),
|
||||
uiDataSize - (uiBufferSize - uiHead));
|
||||
}
|
||||
|
||||
pxTraceEventBuffer->uiFree -= uiDataSize;
|
||||
|
||||
pxTraceEventBuffer->uiHead = (uiHead + uiDataSize) % uiBufferSize;
|
||||
|
||||
*piBytesWritten = uiDataSize;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TRC_EVENT_BUFFER_OPTION_SKIP:
|
||||
{
|
||||
/* Since a consumer could potentially update tail (free) during the procedure
|
||||
* we have to save it here to avoid problems with the push algorithm.
|
||||
*/
|
||||
uint32_t uiHead = pxTraceEventBuffer->uiHead;
|
||||
uint32_t uiTail = pxTraceEventBuffer->uiTail;
|
||||
|
||||
if (uiHead >= uiTail)
|
||||
{
|
||||
uint32_t uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
|
||||
|
||||
if (uiFreeSpace < uiDataSize)
|
||||
{
|
||||
*piBytesWritten = 0;
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
if ((uiBufferSize - uiHead) > uiDataSize)
|
||||
{
|
||||
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pxData, uiDataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pxData, uiBufferSize - uiHead);
|
||||
TRC_MEMCPY(pxTraceEventBuffer->puiBuffer,
|
||||
(void*)(&((uint8_t*)pxData)[(uiBufferSize - uiHead)]),
|
||||
uiDataSize - (uiBufferSize - uiHead));
|
||||
}
|
||||
|
||||
pxTraceEventBuffer->uiHead = (uiHead + uiDataSize) % uiBufferSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
|
||||
|
||||
if (uiFreeSpace < uiDataSize)
|
||||
{
|
||||
*piBytesWritten = 0;
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pxData, uiDataSize);
|
||||
|
||||
pxTraceEventBuffer->uiHead = (uiHead + uiDataSize);
|
||||
}
|
||||
|
||||
*piBytesWritten = uiDataSize;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return TRC_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
traceResult xTraceEventBufferTransfer(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten)
|
||||
{
|
||||
int32_t iBytesWritten = 0;
|
||||
int32_t iSumBytesWritten = 0;
|
||||
uint32_t uiHead;
|
||||
uint32_t uiTail;
|
||||
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(pxTraceEventBuffer != 0);
|
||||
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(piBytesWritten != 0);
|
||||
|
||||
uiHead = pxTraceEventBuffer->uiHead;
|
||||
uiTail = pxTraceEventBuffer->uiTail;
|
||||
|
||||
/* Check if core event buffer is empty */
|
||||
if (uiHead == uiTail)
|
||||
{
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check if we can do a direct write or if we have to handle wrapping */
|
||||
if (uiHead > uiTail)
|
||||
{
|
||||
xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (uiHead - uiTail), &iBytesWritten);
|
||||
|
||||
pxTraceEventBuffer->uiTail = uiHead;
|
||||
}
|
||||
else
|
||||
{
|
||||
xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (pxTraceEventBuffer->uiSize - uiTail), &iBytesWritten);
|
||||
|
||||
iSumBytesWritten += iBytesWritten;
|
||||
|
||||
xTraceStreamPortWriteData(pxTraceEventBuffer->puiBuffer, uiHead, &iBytesWritten);
|
||||
|
||||
pxTraceEventBuffer->uiTail = uiHead;
|
||||
}
|
||||
|
||||
iSumBytesWritten += iBytesWritten;
|
||||
|
||||
*piBytesWritten = iSumBytesWritten;
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer)
|
||||
{
|
||||
/* This should never fail */
|
||||
TRC_ASSERT(pxTraceEventBuffer != 0);
|
||||
|
||||
pxTraceEventBuffer->uiHead = 0;
|
||||
pxTraceEventBuffer->uiTail = 0;
|
||||
pxTraceEventBuffer->uiFree = pxTraceEventBuffer->uiSize;
|
||||
|
||||
return TRC_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
|
||||
|
||||
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
|
||||
Reference in New Issue
Block a user