5. Tracing User Events

 
 
User events are a trace recorder feature that pretty works like a printf() function, directly into the recorder. It's worth knowing how to use it as it may be helpful for debugging.
 
First, declare the user event channels you want to use as global variables. Here, we will use two channels ue1 and ue2.
  • ue1 will be used to monitor the count value in Task_1
  • ue2 will be used for general purpose messages from Task_2
// Trace User Events Channels
traceString ue1, ue2;

 

Then, in the body of main(), before the scheduler is started, we need to register the user event channels:

...
	// Register the Trace User Event Channels
	 ue1 = xTraceRegisterString("count");
	 ue2 = xTraceRegisterString("msg");
...

 

Now we can use ue1 and ue2 channel to issue printf-like messages into the recorder.

Let us print out the value of count in Task_1:

/*
 *	Task_1 toggles LED every 10ms
 */
void vTask1 (void *pvParameters)
{
	portTickType	xLastWakeTime;

	uint16_t	count;
	count = 0;

	// Initialize timing
	xLastWakeTime = xTaskGetTickCount();

	while(1)
	{
		// Toggle LED only if button is released
		if (!BSP_PB_GetState())
		{
			BSP_LED_Toggle();
			count++;
		}

		// Release semaphore every 10 count
		if (count == 10)
		{
			xSemaphoreGive(xSem);
			count = 0;
		}

		// Send count value into trace UEC
		vTracePrintF(ue1, "%d", count);

		// Wait here for 10ms since last wakeup
		vTaskDelayUntil (&xLastWakeTime, (10/portTICK_RATE_MS));
	}
}

 

And display a cool message whenever the semaphore was successfully taken in Task_2:

/*
 *	Task_2 sends a message to console when xSem semaphore is given
 */
void vTask2 (void *pvParameters)
{
	portBASE_TYPE	xStatus;
	uint16_t 		count;

	count = 0;

	// Take the semaphore once to make sure it is empty
	xSemaphoreTake(xSem, 0);

	while(1)
	{
		// Wait here for Semaphore with 2s timeout
		xStatus = xSemaphoreTake(xSem, 2000);

		// Test the result of the take attempt
		if (xStatus == pdPASS)
		{
			// The semaphore was taken as expected
			vTracePrint(ue2, "Yep!");

			// Display console message
			my_printf("Hello %2d from task2\r\n", count);
			count++;
		}

		else
		{
			// The 2s timeout elapsed without Semaphore being taken

			// Display another message
			my_printf("Hey! Where is my semaphore?\r\n");
		}
	}
}

Note that we used both vTracePrint() and vTracePrintF() functions. vTracePrint() is faster but it doesn't format numbers.

 

And now the result (yellow tags):

image_000.png
 
Nice!
 
Open View → User Event Signal Plot
 
image_001.png
 
Nice!
 
Now, it's up to you to make good use of this opportunity.