1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.8.1
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for the event buffer.
9 */
10 
11 #include <trcRecorder.h>
12 
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1)
14 
15 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
16 
xTraceEventBufferInitialize(TraceEventBuffer_t * pxTraceEventBuffer,uint32_t uiOptions,uint8_t * puiBuffer,uint32_t uiSize)17 traceResult xTraceEventBufferInitialize(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiOptions,
18 	uint8_t* puiBuffer, uint32_t uiSize)
19 {
20 	/* This should never fail */
21 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
22 
23 	/* This should never fail */
24 	TRC_ASSERT(puiBuffer != (void*)0);
25 
26 	/* This should never fail */
27 	TRC_ASSERT(uiSize != 0u);
28 
29 	pxTraceEventBuffer->uiOptions = uiOptions;
30 	pxTraceEventBuffer->uiHead = 0u;
31 	pxTraceEventBuffer->uiTail = 0u;
32 	pxTraceEventBuffer->uiSize = uiSize;
33 	pxTraceEventBuffer->uiFree = uiSize;
34 	pxTraceEventBuffer->puiBuffer = puiBuffer;
35 	pxTraceEventBuffer->uiSlack = 0u;
36 	pxTraceEventBuffer->uiNextHead = 0u;
37 	pxTraceEventBuffer->uiTimerWraparounds = 0u;
38 
39 	xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT_BUFFER);
40 
41 	return TRC_SUCCESS;
42 }
43 
44 /**
45  * @brief Pops the oldest event from the Event Buffer.
46  *
47  * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
48  *
49  * @retval TRC_FAIL Failure
50  * @retval TRC_SUCCESS Success
51  */
prvTraceEventBufferPop(TraceEventBuffer_t * pxTraceEventBuffer)52 static traceResult prvTraceEventBufferPop(TraceEventBuffer_t *pxTraceEventBuffer)
53 {
54 	uint32_t uiFreeSize = 0u;
55 
56 	/* Get size of event we are freeing */
57 	/* This should never fail */
58 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
59 
60 	pxTraceEventBuffer->uiFree += uiFreeSize;
61 
62 	/* Update tail to point to the new last event */
63 	pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
64 
65 	return TRC_SUCCESS;
66 }
67 
prvTraceEventBufferAllocPop(TraceEventBuffer_t * pxTraceEventBuffer)68 static traceResult prvTraceEventBufferAllocPop(TraceEventBuffer_t *pxTraceEventBuffer)
69 {
70 	uint32_t uiFreeSize = 0u;
71 
72 	/* Check if tail is in, or at the start of the slack area. We do not want to call
73 	 * a free when in the slack area since it would read garbage data and free would
74 	 * become undefined.
75 	 */
76 	if (pxTraceEventBuffer->uiTail >= (pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiSlack))
77 	{
78 		/* Tail was in the slack area, wrap back to the start of the buffer. */
79 		pxTraceEventBuffer->uiTail = 0u;
80 	}
81 	else
82 	{
83 		/* Get size of event we are freeing (this should never fail) */
84 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
85 
86 		/* Update tail to point to the new last event */
87 		pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
88 	}
89 
90 	return TRC_SUCCESS;
91 }
92 
xTraceEventBufferAlloc(TraceEventBuffer_t * pxTraceEventBuffer,uint32_t uiSize,void ** ppvData)93 traceResult xTraceEventBufferAlloc(TraceEventBuffer_t *pxTraceEventBuffer, uint32_t uiSize, void **ppvData)
94 {
95 	uint32_t uiFreeSpace;
96 	uint32_t uiHead;
97 	uint32_t uiTail;
98 	uint32_t uiBufferSize;
99 
100 	/* This should never fail */
101 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
102 
103 	/* This should never fail */
104 	TRC_ASSERT(ppvData != (void*)0);
105 
106 	uiBufferSize = pxTraceEventBuffer->uiSize;
107 
108 	TRC_ASSERT(uiBufferSize != 0u);
109 
110 	/* Check if the data size is larger than the buffer */
111 	/* This should never fail */
112 	TRC_ASSERT(uiSize <= uiBufferSize);
113 
114 	/* Handle overwrite buffer allocation, since this kind of allocation modifies
115 	 * both head and tail it should only be used for internal buffers without any
116 	 * flushing calls (Streaming Ringbuffer)
117 	 */
118 	if (pxTraceEventBuffer->uiOptions == TRC_EVENT_BUFFER_OPTION_OVERWRITE)
119 	{
120 		if (pxTraceEventBuffer->uiHead >= pxTraceEventBuffer->uiTail)
121 		{
122 			/* Do we have enough space to directly allocate from the buffer? */
123 			if ((uiBufferSize - pxTraceEventBuffer->uiHead) > uiSize)
124 			{
125 				*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
126 				pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead  + uiSize) % uiBufferSize;
127 			}
128 			/* There wasn't enough space for a direct alloc, handle freeing up
129 			 * space and wrapping. */
130 			else
131 			{
132 				/* Free space until there is enough space for a contiguous
133 				 * allocation */
134 				do
135 				{
136 					(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
137 					uiFreeSpace = pxTraceEventBuffer->uiTail - sizeof(uint32_t);
138 				} while (uiFreeSpace < uiSize);
139 
140 				/* Calculate slack from the wrapping */
141 				pxTraceEventBuffer->uiSlack = uiBufferSize - pxTraceEventBuffer->uiHead;
142 
143 				/* Wrap head */
144 				pxTraceEventBuffer->uiHead = 0u;
145 
146 				/* Allocate data */
147 				*ppvData = pxTraceEventBuffer->puiBuffer;
148 
149 				pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead  + uiSize) % uiBufferSize;
150 			}
151 		}
152 		else
153 		{
154 			uiFreeSpace = pxTraceEventBuffer->uiTail - pxTraceEventBuffer->uiHead - sizeof(uint32_t);
155 
156 			/* Check if we have to free space */
157 			if (uiFreeSpace < uiSize)
158 			{
159 				/* Check if this is a wrapping alloc */
160 				if ((pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiHead) < uiSize)
161 				{
162 					/* To avoid uiHead and uiTail from becoming the same we want to
163 					 * pop any events that would make uiTail equal uiHead before
164 					 * wrapping the head. */
165 					do
166 					{
167 						(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
168 					} while (pxTraceEventBuffer->uiTail == 0u);
169 
170 					pxTraceEventBuffer->uiSlack = pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiHead;
171 					pxTraceEventBuffer->uiHead = 0u;
172 				}
173 
174 				do
175 				{
176 					(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
177 					uiFreeSpace = pxTraceEventBuffer->uiTail - pxTraceEventBuffer->uiHead - sizeof(uint32_t);
178 				} while (uiFreeSpace < uiSize);
179 
180 				if (pxTraceEventBuffer->uiTail == 0u)
181 				{
182 					*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
183 				}
184 			}
185 
186 			/* Alloc data */
187 			*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
188 
189 			pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead + uiSize);
190 		}
191 	}
192 	else
193 	{
194 		/* Since a consumer could potentially update tail (free) during the procedure
195 		 * we have to save it here to avoid problems with it changing during this call.
196 		 */
197 		uiHead = pxTraceEventBuffer->uiHead;
198 		uiTail = pxTraceEventBuffer->uiTail;
199 
200 		if (uiHead >= uiTail)
201 		{
202 			uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
203 
204 			if (uiFreeSpace < uiSize)
205 			{
206 				*ppvData = 0;
207 
208 				return TRC_FAIL;
209 			}
210 
211 			/* Copy data */
212 			if ((uiBufferSize - uiHead) > uiSize)
213 			{
214 				*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
215 
216 				pxTraceEventBuffer->uiNextHead = (uiHead + uiSize) % uiBufferSize;
217 			}
218 			else
219 			{
220 				uiFreeSpace = uiTail;
221 
222 				if (uiFreeSpace < uiSize)
223 				{
224 					*ppvData = 0;
225 
226 					return TRC_FAIL;
227 				}
228 
229 				/* Calculate slack */
230 				pxTraceEventBuffer->uiSlack = uiBufferSize - uiHead;
231 
232 				*ppvData = pxTraceEventBuffer->puiBuffer;
233 
234 				pxTraceEventBuffer->uiNextHead = (uiHead + pxTraceEventBuffer->uiSlack + uiSize) % uiBufferSize;
235 			}
236 		}
237 		else
238 		{
239 			uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
240 
241 			if (uiFreeSpace < uiSize)
242 			{
243 				*ppvData = 0;
244 
245 				return TRC_FAIL;
246 			}
247 
248 			/* Alloc data */
249 			*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
250 
251 			pxTraceEventBuffer->uiNextHead = (uiHead + uiSize);
252 		}
253 	}
254 
255 	return TRC_SUCCESS;
256 }
257 
xTraceEventBufferAllocCommit(TraceEventBuffer_t * pxTraceEventBuffer,const void * pvData,uint32_t uiSize,int32_t * piBytesWritten)258 traceResult xTraceEventBufferAllocCommit(TraceEventBuffer_t *pxTraceEventBuffer, const void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
259 {
260 	(void)pvData;
261 
262 	/* This should never fail */
263 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
264 
265 	/* Advance head location */
266 	pxTraceEventBuffer->uiHead = pxTraceEventBuffer->uiNextHead;
267 
268 	/* Update bytes written */
269 	*piBytesWritten = (int32_t)uiSize;
270 
271 	return TRC_SUCCESS;
272 }
273 
xTraceEventBufferPush(TraceEventBuffer_t * pxTraceEventBuffer,void * pvData,uint32_t uiSize,int32_t * piBytesWritten)274 traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
275 {
276 	uint32_t uiBufferSize;
277 	uint32_t uiHead;
278 	uint32_t uiTail;
279 	uint32_t uiFreeSpace;
280 
281 	/* This should never fail */
282 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
283 
284 	/* This should never fail */
285 	TRC_ASSERT(pvData != (void*)0);
286 
287 	uiBufferSize = pxTraceEventBuffer->uiSize;
288 
289 	TRC_ASSERT(uiBufferSize != 0u);
290 
291 	/* Check if the data size is larger than the buffer */
292 	/* This should never fail */
293 	TRC_ASSERT(uiSize <= uiBufferSize);
294 
295 	/* Check byte alignment */
296 	/* This should never fail */
297 	TRC_ASSERT((uiSize % 4u) == 0u);
298 
299 	/* Ensure bytes written start at 0 */
300 	/* This should never fail */
301 	TRC_ASSERT(piBytesWritten != (void*)0);
302 
303 	*piBytesWritten = 0;
304 
305 	/* This should never fail */
306 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
307 
308 	/* In ring buffer mode we cannot provide lock free access since the producer modified
309 	 * the head and tail variables in the same call. This option is only safe when used
310 	 * with an internal buffer (streaming snapshot) which no consumer accesses.
311 	 */
312 	switch (pxTraceEventBuffer->uiOptions)
313 	{
314 		case TRC_EVENT_BUFFER_OPTION_OVERWRITE:
315 			uiHead = pxTraceEventBuffer->uiHead;
316 
317 			/* If there isn't enough space in the buffer pop events until there is */
318 			while (pxTraceEventBuffer->uiFree < uiSize)
319 			{
320 				(void)prvTraceEventBufferPop(pxTraceEventBuffer);
321 			}
322 
323 			/* Copy data */
324 			if ((uiBufferSize - uiHead) > uiSize)
325 			{
326 				TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
327 			}
328 			else
329 			{
330 				TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, (uiBufferSize - uiHead)); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
331 				TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, (void*)(&((uint8_t*)pvData)[(uiBufferSize - uiHead)]), (uiSize - (uiBufferSize - uiHead))); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/ /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
332 			}
333 
334 			pxTraceEventBuffer->uiFree -= uiSize;
335 
336 			pxTraceEventBuffer->uiHead = (uiHead + uiSize) % uiBufferSize;
337 
338 			*piBytesWritten = (int32_t)uiSize;
339 			break;
340 		case TRC_EVENT_BUFFER_OPTION_SKIP:
341 			/* Since a consumer could potentially update tail (free) during the procedure
342 			 * we have to save it here to avoid problems with the push algorithm.
343 			 */
344 			uiHead = pxTraceEventBuffer->uiHead;
345 			uiTail = pxTraceEventBuffer->uiTail;
346 
347 			if (uiHead >= uiTail)
348 			{
349 				uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
350 
351 				if (uiFreeSpace < uiSize)
352 				{
353 					*piBytesWritten = 0;
354 
355 					return TRC_SUCCESS;
356 				}
357 
358 				/* Copy data */
359 				if ((uiBufferSize - uiHead) > uiSize)
360 				{
361 					TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
362 				}
363 				else
364 				{
365 					TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, (uiBufferSize - uiHead)); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
366 					TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, (void*)(&((uint8_t*)pvData)[(uiBufferSize - uiHead)]), (uiSize - (uiBufferSize - uiHead)));  /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/ /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
367 				}
368 
369 				pxTraceEventBuffer->uiHead = (uiHead + uiSize) % uiBufferSize;
370 			}
371 			else
372 			{
373 				uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
374 
375 				if (uiFreeSpace < uiSize)
376 				{
377 					*piBytesWritten = 0;
378 
379 					return TRC_SUCCESS;
380 				}
381 
382 				/* Copy data */
383 				TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
384 
385 				pxTraceEventBuffer->uiHead = (uiHead + uiSize);
386 			}
387 
388 			*piBytesWritten = (int32_t)uiSize;
389 			break;
390 		default:
391 			return TRC_FAIL;
392 			break;
393 	}
394 
395 	return TRC_SUCCESS;
396 }
397 
xTraceEventBufferTransferAll(TraceEventBuffer_t * pxTraceEventBuffer,int32_t * piBytesWritten)398 traceResult xTraceEventBufferTransferAll(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten)
399 {
400 	int32_t iBytesWritten = 0;
401 	int32_t iSumBytesWritten = 0;
402 	uint32_t uiHead;
403 	uint32_t uiTail;
404 	uint32_t uiSlack;
405 
406 	/* This should never fail */
407 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
408 
409 	/* This should never fail */
410 	TRC_ASSERT(piBytesWritten != (void*)0);
411 
412 	uiHead = pxTraceEventBuffer->uiHead;
413 	uiTail = pxTraceEventBuffer->uiTail;
414 	uiSlack = pxTraceEventBuffer->uiSlack;
415 
416 	/* Check if core event buffer is empty */
417 	if (uiHead == uiTail)
418 	{
419 		/* Make sure this value is set in case it was passed uninitialized. */
420 		*piBytesWritten = 0;
421 
422 		return TRC_SUCCESS;
423 	}
424 
425 	/* Check if we can do a direct write or if we have to handle wrapping */
426 	if (uiHead > uiTail)
427 	{
428 		/* No wrapping */
429 		xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (uiHead - uiTail), &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
430 	}
431 	else
432 	{
433 		/* Wrapping */
434 
435 		/* Try to write: tail -> end of buffer */
436 		xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (pxTraceEventBuffer->uiSize - uiTail - uiSlack), &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
437 
438 		/* Did we manage to write all bytes? */
439 		if ((uint32_t)iBytesWritten == (pxTraceEventBuffer->uiSize - uiTail - uiSlack))
440 		{
441 			/* uiTail is moved to start of buffer */
442 			pxTraceEventBuffer->uiTail = 0u;
443 
444 			iSumBytesWritten = iBytesWritten;
445 
446 			/* We zero this here in case it does not get zeroed by the streamport. This isn't really a problem with our
447 			 * streamports, but there has been cases with custom streamport forgetting to set this to 0 if there is no
448 			 * data to write. */
449 			iBytesWritten = 0;
450 
451 			/* Try to write: start of buffer -> head */
452 			xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[0], uiHead, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
453 		}
454 	}
455 
456 	/* Move tail */
457 	pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
458 
459 	iSumBytesWritten += iBytesWritten;
460 
461 	*piBytesWritten = iSumBytesWritten;
462 
463 	return TRC_SUCCESS;
464 }
465 
xTraceEventBufferTransferChunk(TraceEventBuffer_t * pxTraceEventBuffer,uint32_t uiChunkSize,int32_t * piBytesWritten)466 traceResult xTraceEventBufferTransferChunk(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten)
467 {
468 	int32_t iBytesWritten = 0;
469 	uint32_t uiHead;
470 	uint32_t uiTail;
471 	uint32_t uiSlack;
472 	uint32_t uiBytesToWrite;
473 
474 	/* This should never fail */
475 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
476 
477 	/* This should never fail */
478 	TRC_ASSERT(piBytesWritten != (void*)0);
479 
480 	uiHead = pxTraceEventBuffer->uiHead;
481 	uiTail = pxTraceEventBuffer->uiTail;
482 	uiSlack = pxTraceEventBuffer->uiSlack;
483 
484 	/* Check if core event buffer is empty */
485 	if (uiHead == uiTail)
486 	{
487 		/* Make sure this value is set in case it was passed uninitialized. */
488 		*piBytesWritten = 0;
489 
490 		return TRC_SUCCESS;
491 	}
492 
493 	/* Check if we can do a direct write or if we have to handle wrapping */
494 	if (uiHead > uiTail)
495 	{
496 		uiBytesToWrite = uiHead - uiTail;
497 		if (uiBytesToWrite > uiChunkSize)
498 		{
499 			uiBytesToWrite = uiChunkSize;
500 		}
501 
502 		(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], uiBytesToWrite, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
503 
504 		pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
505 	}
506 	else
507 	{
508 		uiBytesToWrite = pxTraceEventBuffer->uiSize - uiTail - uiSlack;
509 		if (uiBytesToWrite > uiChunkSize)
510 		{
511 			uiBytesToWrite = uiChunkSize;
512 		}
513 
514 		(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], uiBytesToWrite, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
515 
516 		/* Check if we managed to write until the end or not, if we didn't we
517 		 * add the number of bytes written. If we managed to write the last
518 		 * segment, reset tail to 0. */
519 		if ((uiTail + (uint32_t)iBytesWritten) == (pxTraceEventBuffer->uiSize - uiSlack))
520 		{
521 			pxTraceEventBuffer->uiTail = 0u;
522 		}
523 		else
524 		{
525 			pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
526 		}
527 	}
528 
529 	*piBytesWritten = iBytesWritten;
530 
531 	return TRC_SUCCESS;
532 }
533 
xTraceEventBufferClear(TraceEventBuffer_t * pxTraceEventBuffer)534 traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer)
535 {
536 	/* This should never fail */
537 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
538 
539 	pxTraceEventBuffer->uiHead = 0u;
540 	pxTraceEventBuffer->uiTail = 0u;
541 	pxTraceEventBuffer->uiFree = pxTraceEventBuffer->uiSize;
542 	pxTraceEventBuffer->uiSlack = 0u;
543 	pxTraceEventBuffer->uiNextHead = 0u;
544 
545 	return TRC_SUCCESS;
546 }
547 
548 #endif
549 
550 #endif
551