]> git.sur5r.net Git - freertos/commitdiff
Update FreeRTOS+Trace recorder library to v3.0.2
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 9 Oct 2015 13:30:09 +0000 (13:30 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 9 Oct 2015 13:30:09 +0000 (13:30 +0000)
Add streaming version of the FreeRTOS+Trace recorder, also V3.0.2

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2385 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

32 files changed:
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/Demo.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/Release notes.txt [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT_Conf.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT_Printf.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcConfig.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcHardwarePort.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcKernelPort.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcKernelPort.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBuffer.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBuffer.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBufferConfig.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcRecorder.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcRecorder.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcStreamPort.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIP.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIP.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIPConfig.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/ConfigurationTemplate/trcConfig.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcBase.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernel.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTypes.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcUser.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/readme.txt
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcBase.c
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHardwarePort.c
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernel.c
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcUser.c

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/Demo.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/Demo.c
new file mode 100644 (file)
index 0000000..39f7ff8
--- /dev/null
@@ -0,0 +1,566 @@
+/*******************************************************************************\r
+ * Tracealyzer v3.0.0 Demo Application\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * traceDemoApp.c\r
+ *\r
+ * Demo application for Tracealyzer demo project.\r
+ *\r
+ * Terms of Use\r
+ * This software is copyright Percepio AB. The recorder library is free for\r
+ * use together with Percepio products. You may distribute the recorder library\r
+ * in its original form, including modifications in trcHardwarePort.c/.h\r
+ * given that these modification are clearly marked as your own modifications\r
+ * and documented in the initial comment section of these source files.\r
+ * This software is the intellectual property of Percepio AB and may not be\r
+ * sold or in other ways commercially redistributed without explicit written\r
+ * permission by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2014.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+#include <stdint.h>\r
+\r
+/* Kernel includes. */\r
+#include <FreeRTOS.h>\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+#if (configUSE_TIMERS == 1)\r
+       #include "timers.h"\r
+#endif\r
+\r
+#include "trcRecorder.h"\r
+\r
+#define ISR3_PERIOD 18\r
+#define ISR2_PERIOD 24\r
+#define ISR1_PERIOD 30\r
+\r
+#define EXECTIME_CONTROLLER 1\r
+#define EXECTIME_SUPERV 2\r
+#define EXECTIME_SENSOR 1\r
+\r
+typedef struct\r
+{\r
+       int32_t code;\r
+       int32_t value;\r
+       char data[512]; // Makes the Memory Heap Utilization graph more interresting!\r
+} QueueMessage;\r
+\r
+#define MSGCODE_SENSOR_VALUE 1\r
+#define MSGCODE_CONTROL_VALUE 10\r
+#define MSGCODE_CONTROL_DEFAULT_VALUE 99\r
+\r
+static portTASK_FUNCTION_PROTO( trcDemoTaskSensor, pvParameters );\r
+static portTASK_FUNCTION_PROTO( trcDemoTaskActuator, pvParameters );\r
+static portTASK_FUNCTION_PROTO( trcDemoTaskController, pvParameters );\r
+static portTASK_FUNCTION( trcDemoTaskSuperv, pvParameters );\r
+static portTASK_FUNCTION( trcDemoISR, pvParameters );\r
+\r
+#if (configUSE_TIMERS == 1)\r
+xTimerHandle timer;\r
+void myTimerHandler(xTimerHandle tmr);\r
+#endif\r
+\r
+xQueueHandle sensorQ, actuatorQ;\r
+xSemaphoreHandle Sem1, Sem2, Sem3;\r
+\r
+void doSomeWork(uint32_t n);\r
+\r
+int readSensor(int i);\r
+\r
+/******************************************************************************\r
+* doSomeWork\r
+*\r
+* Performs a busy wait for X milliseconds. Used to generate suitable execution\r
+* times in the demo application, in a portable way.\r
+******************************************************************************/\r
+void doSomeWork(uint32_t ms)\r
+{\r
+       portTickType old = xTaskGetTickCount();\r
+       portTickType new = 0;\r
+       while (ms > 0)\r
+       {\r
+               new = xTaskGetTickCount();\r
+               if (old < new)\r
+               {\r
+                       /* If uiTraceTickCount has changed, we only reduce 1ms of the wait\r
+                               time. This way we do not count time that this task has waited\r
+                               for other tasks. This will result in somewhat correct execution\r
+                               times. */\r
+                       old = new;\r
+                       ms--;\r
+               }\r
+       }\r
+}\r
+\r
+/******************************************************************************\r
+* readSensor\r
+*\r
+* Simulates a set of sensors/inputs, using a simple physics simulation.\r
+* The values are intentionally ints (rather than floats) to avoid very slow\r
+* execution times on chips without hardware floating point support.\r
+******************************************************************************/\r
+int readSensor(int i)\r
+{\r
+       static int pos[3] = {40, 80, 120};\r
+       static int speed[3] = {0, 0, -3};\r
+       static int acc[3] = {0, 0, 0};\r
+\r
+       i--;\r
+\r
+       acc[i] = (-pos[i] >> 3);\r
+       speed[i] += acc[i];\r
+       pos[i] += speed[i];\r
+\r
+       return (int)pos[i];\r
+}\r
+\r
+/******************************************************************************\r
+* trcDemoTaskSensor\r
+*\r
+* The "Sensor" tasks (three instances of this code). Reads data using\r
+* "readSensor" when trigged by the timer interrupt through a semaphore.\r
+******************************************************************************/\r
+static portTASK_FUNCTION( trcDemoTaskSensor, pvParameters )\r
+{\r
+       char name[30] = "SensorX\0";\r
+       QueueMessage sensorReading;\r
+       unsigned char idx = (unsigned char)(*(int*)pvParameters);\r
+       xSemaphoreHandle mySem = NULL;\r
+\r
+       /* Change 'X' to the index */\r
+       name[6] = '0' + idx;\r
+\r
+       switch (idx)\r
+       {\r
+               case 1: mySem = Sem1; break;\r
+               case 2: mySem = Sem2; break;\r
+               case 3: mySem = Sem3; break;\r
+       }\r
+\r
+       vTraceStoreUserEventChannelName(name);\r
+\r
+       /* Initialize xNextWakeTime - this only needs to be done once. */\r
+\r
+       sensorReading.value = 0;\r
+       sensorReading.code = 0;\r
+\r
+       for( ;; )\r
+       {\r
+\r
+               xSemaphoreTake(mySem, 0xFFFFFFFF);\r
+\r
+               sensorReading.code = idx;\r
+               sensorReading.value = readSensor(idx);\r
+\r
+               doSomeWork(EXECTIME_SENSOR);\r
+\r
+               vTracePrintF(name , "Sending msg %d", sensorReading.value);\r
+\r
+               if (xQueueSend(sensorQ, &sensorReading, 1) != pdTRUE)\r
+               {\r
+                       vTracePrint(name, "Sensor queue full. Sample dropped!");\r
+               }\r
+               vTraceInstanceFinishedNow();\r
+       }\r
+}\r
+\r
+\r
+\r
+/******************************************************************************\r
+* trcDemoTaskSuperv\r
+*\r
+* The "Supervisor" task. Performs no action in the simulation, apart from\r
+* preempting other tasks in the scheduling.\r
+******************************************************************************/\r
+static portTASK_FUNCTION( trcDemoTaskSuperv, pvParameters )\r
+{\r
+       int counter = 0;\r
+       \r
+       #if (configUSE_TIMERS == 1)\r
+       static int timerState = 0;\r
+       #endif\r
+\r
+       portTickType xNextWakeTime;\r
+       (void)pvParameters;\r
+\r
+       xNextWakeTime = xTaskGetTickCount();\r
+\r
+       #if (configUSE_TIMERS == 1)\r
+       timer = xTimerCreate("Tmr5", 5, 1, (void*)42, myTimerHandler);\r
+       xTimerChangePeriod(timer, 10, 0);\r
+       #endif\r
+\r
+       for( ;; )\r
+       {               \r
+               vTaskDelayUntil( &xNextWakeTime, 40);\r
+               \r
+               counter = (counter + 1) % 16;\r
+               \r
+               if (counter == 8) vTaskPrioritySet(NULL, 2);\r
+               \r
+               if (counter == 0) vTaskPrioritySet(NULL, 3);\r
+                               \r
+               doSomeWork(EXECTIME_SUPERV);\r
+\r
+               #if (configUSE_TIMERS == 1)\r
+               if (timerState == 0)\r
+               {\r
+                       xTimerStart(timer, 0);\r
+                       timerState = 1;\r
+               }\r
+               else if (timerState == 1)\r
+               {\r
+                       xTimerStop(timer, 0);\r
+                       timerState = 0;\r
+               }\r
+               #endif\r
+       }\r
+}\r
+\r
+/******************************************************************************\r
+* trcDemoTaskController\r
+*\r
+* The "Controller" task. Periodically reads all accumulated messages in SensorQ\r
+* (i.e., those produced by the Sensor tasks since the last execution of\r
+* the Controller task). Calculates their mean value and send this to Actuator.\r
+******************************************************************************/\r
+static portTASK_FUNCTION( trcDemoTaskController, pvParameters )\r
+{\r
+       portTickType xNextWakeTime;\r
+       QueueMessage* sensorReading;\r
+       QueueMessage actuatorMessage;\r
+       int32_t sum[4];\r
+       int32_t count[4];\r
+\r
+       (void)pvParameters;\r
+\r
+       vTraceStoreUserEventChannelName("UE TEST");\r
+\r
+       /* Initialize xNextWakeTime - this only needs to be done once. */\r
+       xNextWakeTime = xTaskGetTickCount();\r
+       for(;;)\r
+       {\r
+               sum[1] = 0;\r
+               sum[2] = 0;\r
+               sum[3] = 0;\r
+               count[1] = 0;\r
+               count[2] = 0;\r
+               count[3] = 0;\r
+\r
+               vTaskDelayUntil(&xNextWakeTime, 60);\r
+\r
+               for(;;)\r
+               {\r
+                       // To demostrate malloc/free tracing\r
+                       sensorReading = ( QueueMessage * ) pvPortMalloc( sizeof( QueueMessage ) );\r
+\r
+                       if (xQueueReceive(sensorQ, sensorReading, 0) != pdTRUE)\r
+                       {\r
+                               vPortFree(sensorReading);\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (sensorReading->code >= 1 && sensorReading->code <= 3)\r
+                               {\r
+                                       sum[sensorReading->code] += sensorReading->value;\r
+                                       count[sensorReading->code]++;\r
+                               }\r
+                       }\r
+                       doSomeWork(EXECTIME_CONTROLLER);\r
+                       \r
+                       //vTracePrintF(0, "0x%4x", 111);\r
+                       //vTracePrintF(0, "0x%04x", 111);\r
+                       //vTracePrintF(0, "0x%4X", 111);\r
+                       //vTracePrintF(0, "0x%04X", 111);\r
+                       //\r
+                       //vTracePrint(0, "123456789012345678901234567890123456789012345678901234567890");\r
+                       //vTracePrint("UE TEST", "1234567890123456789012345678901234567890123456789012345");\r
+                       //vTracePrint("UE TEST", "12345678901234567890123456789012345678901234567890123456");\r
+                       //vTracePrint("UE TEST", "123456789012345678901234567890123456789012345678901234567");\r
+                       //vTracePrint("UE TEST", "12345678901234567890123456789012345678901234567890");\r
+                       //\r
+                       //vTracePrintF("UE TEST", "%5d", 42);\r
+                       //vTracePrintF("UE TEST", "%05d", 42);\r
+                       //vTracePrintF("UE TEST", "%5d", -42);\r
+                       //vTracePrintF("UE TEST", "%05d", -42);\r
+                       //vTracePrintF("UE TEST", "%05d", -1042);\r
+                       //vTracePrintF("UE TEST", "%05d", -11042);\r
+                       //\r
+                       //vTracePrintF("UE TEST", "%5u", -1);\r
+                       //vTracePrintF("UE TEST", "%05u", -1);\r
+                       //vTracePrintF("UE TEST", "%5u", 10);\r
+                       //vTracePrintF("UE TEST", "%05u", 10);\r
+                       //\r
+                       //vTracePrintF("UE TEST", "%5u", 11042);\r
+                       //vTracePrintF("UE TEST", "%05u", 11042);\r
+                       //\r
+                       //vTracePrintF("UE TEST", "%5u", 111042);\r
+                       //vTracePrintF("UE TEST", "%05u", 111042);\r
+                       //\r
+                       //vTracePrintF("UE TEST", "%15d", 111042);\r
+                       //vTracePrintF("UE TEST", "%015d", 111042);\r
+\r
+                       vPortFree(sensorReading);\r
+                       vTraceInstanceFinishedNow();\r
+\r
+               }\r
+\r
+               actuatorMessage.code = MSGCODE_CONTROL_VALUE;\r
+               actuatorMessage.value = 0;\r
+\r
+               if (count[1] > 0)\r
+                       actuatorMessage.value += (int32_t)(0.5 * sum[1]/count[1]);\r
+               if (count[2] > 0)\r
+                       actuatorMessage.value += (int32_t)(0.25 * sum[2]/count[2]);\r
+               if (count[3] > 0)\r
+                       actuatorMessage.value += (int32_t)(0.25 * sum[3]/count[3]);\r
+\r
+               xQueueSend(actuatorQ, &actuatorMessage, 10000);\r
+       }\r
+}\r
+\r
+/******************************************************************************\r
+* trcDemoISR\r
+*\r
+* The "FakeISR" task, that simulates the ISRTimer interrupts, which triggers\r
+* the Sensor tasks.\r
+******************************************************************************/\r
+static portTASK_FUNCTION( trcDemoISR, pvParameters )\r
+{\r
+       portTickType xNextWakeTime;\r
+       portBASE_TYPE dummy;\r
+       int i = 0;\r
+\r
+       (void)pvParameters;\r
+\r
+       /* Initialize xNextWakeTime - this only needs to be done once. */\r
+       xNextWakeTime = xTaskGetTickCount();\r
+       vTraceSetISRProperties("ISRTimer1", 3);\r
+       vTraceSetISRProperties("ISRTimer2", 2);\r
+       vTraceSetISRProperties("ISRTimer3", 1);\r
+       vTaskDelayUntil( &xNextWakeTime, 1);\r
+\r
+       for( ;; )\r
+       {\r
+               i++;\r
+\r
+               if (i % ISR3_PERIOD == 0)\r
+               {\r
+                       portENTER_CRITICAL();\r
+                       vTraceStoreISRBegin((void*)"ISRTimer3");\r
+                       xSemaphoreGiveFromISR(Sem3, &dummy);\r
+                       vTraceStoreISREndManual(dummy);\r
+                       portEXIT_CRITICAL();\r
+               }\r
+\r
+               if (i % ISR2_PERIOD == 0)\r
+               {\r
+                       portENTER_CRITICAL();\r
+                       vTraceStoreISRBegin((void*)"ISRTimer2");\r
+                       xSemaphoreGiveFromISR(Sem2, &dummy);\r
+                       vTraceStoreISREndManual(dummy);\r
+                       portEXIT_CRITICAL();\r
+               }\r
+\r
+               if (i % ISR1_PERIOD == 0)\r
+               {\r
+                       portENTER_CRITICAL();\r
+                       vTraceStoreISRBegin((void*)"ISRTimer1");\r
+                       xSemaphoreGiveFromISR(Sem1, &dummy);\r
+                       vTraceStoreISREndManual(dummy);\r
+                       portEXIT_CRITICAL();\r
+\r
+\r
+               }\r
+\r
+               vTaskDelayUntil( &xNextWakeTime, 1);\r
+       }\r
+}\r
+\r
+/******************************************************************************\r
+* trcDemoTaskActuator\r
+*\r
+* The "Actuator" task, just reads the data from Controller and logs it in a\r
+* User Event (i.e., the "vTracePrintF" calls).\r
+******************************************************************************/\r
+static portTASK_FUNCTION( trcDemoTaskActuator, pvParameters )\r
+{\r
+       QueueMessage inMessage;\r
+       (void)pvParameters;\r
+       vTraceStoreUserEventChannelName("Actuator Out Signal");\r
+\r
+       for( ;; )\r
+       {\r
+               vTraceInstanceFinishedNow();\r
+               /* Place this task in blocked state until it is time to run again. */\r
+               if (xQueueReceive(actuatorQ, &inMessage, 35) != pdTRUE)\r
+               {\r
+                       vTracePrintF("Actuator Out Signal", "No data...");\r
+               }\r
+               else\r
+               {\r
+                       if (inMessage.code == MSGCODE_CONTROL_VALUE)\r
+                       {\r
+                               vTracePrintF("Actuator Out Signal", "Out: %d",\r
+                                                        inMessage.value);\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+#if (configUSE_TIMERS == 1)\r
+void myTimerHandler(xTimerHandle tmr)\r
+{\r
+       (void) tmr;\r
+       vTracePrintF("Timer", "Timer handler!");\r
+}\r
+#endif\r
+\r
+int sensorTaskID1 = 1;\r
+int sensorTaskID2 = 2;\r
+int sensorTaskID3 = 3;\r
+\r
+#define vTaskCreateNotTraced( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority ) \\r
+       { void* this_pxCreatedTask; \\r
+       vTraceSetReadyEventsEnabled(0); \\r
+       xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( &this_pxCreatedTask ), ( NULL ), ( NULL ) ); \\r
+       vTraceSetReadyEventsEnabled(1); \\r
+       if (this_pxCreatedTask != NULL){ vTraceExcludeTaskFromTrace(this_pxCreatedTask); }else{ return -42;} }\r
+\r
+/******************************************************************************\r
+* trcDemoTaskActuator\r
+*\r
+* The "Actuator" task, just reads the data from Controller and logs it in a\r
+* User Event (i.e., the "vTracePrintF" calls).\r
+******************************************************************************/\r
+int vStartDemoApplication(void)\r
+{\r
+       void* objectHandle = NULL;\r
+\r
+       vTraceStoreUserEventChannelName("Messages");\r
+\r
+       vTracePrint("Messages", "Demo starting...");\r
+       vTracePrint("Messages", "vTraceUserEvent creates basic User Events.");\r
+       vTracePrint("Messages", "vTracePrintF creates advanced user events, like printf");\r
+       //vTracePrintF("Messages", "A float: %f (should be 1)", (float)1.0);\r
+       //vTracePrintF("Messages", "A double: %lf (should be 1)", (double)1.0);\r
+       //vTracePrintF("Messages", "A signed 8-bit value: %bd (should be -1)", -1);\r
+\r
+       vTraceStoreUserEventChannelName("Timer");\r
+       \r
+       sensorQ = xQueueCreate(15, sizeof(QueueMessage) );\r
+       if( sensorQ == 0 )\r
+       {\r
+               vTracePrint("Messages", "Could not create SensorQ!\n");\r
+               return -1;\r
+       }\r
+       vTraceSetQueueName(sensorQ, "SensorQueue");\r
+\r
+       actuatorQ = xQueueCreate(3, sizeof(QueueMessage) );\r
+       if( actuatorQ == 0 )\r
+       {\r
+               vTracePrint("Messages", "Could not create ActuatorQ!\n");\r
+               return -2;\r
+       }\r
+       vTraceSetQueueName(actuatorQ, "ActuatorQueue");\r
+\r
+       vSemaphoreCreateBinary(Sem1);\r
+       if( Sem1 == NULL )\r
+       {\r
+               vTracePrint("Messages", "Could not create Sem1!\n");\r
+               return -3;\r
+       }\r
+       vTraceSetSemaphoreName(Sem1, "SemaphSenX");\r
+\r
+       vSemaphoreCreateBinary(Sem2);\r
+       if( Sem2 == NULL )\r
+       {\r
+               vTracePrint("Messages", "Could not create Sem2!\n");\r
+               return -4;\r
+       }\r
+       vTraceSetSemaphoreName(Sem2, "SemaphSenY");\r
+\r
+       vSemaphoreCreateBinary(Sem3);\r
+       if( Sem3 == NULL )\r
+       {\r
+               vTracePrint("Messages", "Could not create Sem3!\n");\r
+               return -5;\r
+       }\r
+       vTraceSetSemaphoreName(Sem3, "SemaphSenZ");\r
+\r
+       xTaskCreate( trcDemoTaskSensor, "SensorX",\r
+                               configMINIMAL_STACK_SIZE*2, &sensorTaskID1, 8, &objectHandle );\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -6;\r
+       }\r
+\r
+       xTaskCreate( trcDemoTaskSensor, "SensorY",\r
+                               configMINIMAL_STACK_SIZE*2, &sensorTaskID2, 7, &objectHandle );\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -7;\r
+       }\r
+\r
+       xTaskCreate( trcDemoTaskSensor, "SensorZ",\r
+                               configMINIMAL_STACK_SIZE*2, &sensorTaskID3, 6, &objectHandle );\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -8;\r
+       }\r
+\r
+       xTaskCreate( trcDemoTaskController, "Control",\r
+                               configMINIMAL_STACK_SIZE*2, NULL, 4, &objectHandle );\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -9;\r
+       }\r
+\r
+       xTaskCreate( trcDemoTaskActuator, "Actuator",\r
+                               configMINIMAL_STACK_SIZE*2, NULL, 5, &objectHandle );\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -10;\r
+       }\r
+\r
+       xTaskCreate( trcDemoTaskSuperv, "Superv",\r
+                               configMINIMAL_STACK_SIZE*2, NULL, 3, &objectHandle );\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -11;\r
+       }\r
+       \r
+       xTaskCreate( trcDemoISR, "(Hide)FakeISR",\r
+                               configMINIMAL_STACK_SIZE*2, NULL, configMAX_PRIORITIES-1, &objectHandle);\r
+       if (objectHandle == NULL)\r
+       {\r
+               return -12;\r
+       }\r
+       \r
+       return 0;\r
+}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/Release notes.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/Release notes.txt
new file mode 100644 (file)
index 0000000..dae3b94
--- /dev/null
@@ -0,0 +1,45 @@
+Release notes, Trace Recorder Library for Tracealyzer v3.0.2\r
+September 29, 2015. Percepio AB.\r
+\r
+Changes:\r
+v3.0.2\r
+- Fixed bug in tracing of nested interrupts.\r
+- Made locally used variables and functions static.\r
+v3.0.1\r
+- Added vTraceOnTraceBegin()/vTraceOnTraceEnd() in trcKernelPort.c to allow custom cleanup via macros TRC_STREAM_PORT_ON_TRACE_BEGIN()/TRC_STREAM_PORT_ON_TRACE_END().\r
+v3.0.0\r
+- Modified trcTCPIP functions to take bytes written/read as parameters and instead return potential errors.\r
+- Added vTraceOnTraceBegin()/vTraceOnTraceEnd() in trcKernelPort that in turn uses macros from trcStreamPort.h to allow transfer method defined (as well as user defined) actions where appropriate. Currently only used by TCP/IP to re-initialize the paged event buffer so no old data is sent on trace start.\r
+v2.8.6\r
+- Changed void* to uint32_t to ensure 32bit for vTraceStoreEvent1(), vTraceStoreEvent2() and vTraceStoreEvent3().\r
+- Added prefix TRC to most macros to avoid conflicts.\r
+- Moved all trace stream macros to trcStreamPort.h.\r
+- Now allows users to define their own trace stream macros. First specify TRC_RECORDER_TRANSFER_METHOD_CUSTOM and then modify the TRC_STREAM_CUSTOM_XXXXXXXXX macros.\r
+- Added trcPagedEventBuffer that can be used to avoid endless recursion for trace stream methods that use kernel objects (semaphores, mutexes) when sending data.\r
+- Added trcTCPIP/trcTCPIPConfig for easy trace stream integration with custom TCP/IP stacks.\r
+v2.8.5\r
+- Added internal OS tick counter that can be used by certain kernel ports to keep track of the actual OS tick, in case it can be delayed.\r
+- Updated generic macro names.\r
+- Removed usage of strlen().
+\r
+- Added support for width and padding formats for %d, %u, %x and %X.\r
+- Reduced RAM usage for certain cases by redefining unused buffers.\r
+- Fixed traceTAKE_MUTEX_RECURSIVE_FAILED being called traceTAKE_MUTEX_RECURSIVE resulting in duplicate defines.\r
+- Implemented fix for missing parameter "xCopyPosition" when using "xSemaphoreGiveFromISR()" in FreeRTOS v8.\r
+- Added prefix to internal defines to avoid conflicts.\r
+- Fixed possible memory alignment issue which could cause hard fault.\r
+- Made sure TzCtrl runs every 100ms instead of every 100 OS ticks.\r
+- Moved project specific includes to trcConfig.h.\r
+- Added a few backwards compatibility macros.\r
+v2.8.2\r
+- Improved vTracePrintF() parsing.\r
+- Added vTracePrint() that performs no formatting.\r
+- Removed need for passing parameter to vTraceStoreISREnd() on embOS port. This parameter is detected automatically.\r
+- Added vTraceStoreISREndManual(param) that can be used on kernel ports that doesn't automatically detect pending task switches after interrupts.\r
+v2.8.1\r
+- New J-Link drivers fixes the RTT Buffer Index != 0 issue.\r
+- trcRecorder.c hotfixed to handle missing defines in embOS that haven't made it to release yet.\r
+v2.8.0\r
+- Initial release. Only RTT Buffer Index 0 works in this version.\r
+\r
+For questions, contact support@percepio.com or sales@percepio.com\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT.c
new file mode 100644 (file)
index 0000000..74ce144
--- /dev/null
@@ -0,0 +1,591 @@
+/*********************************************************************\r
+*              SEGGER MICROCONTROLLER GmbH & Co. KG                  *\r
+*        Solutions for real time microcontroller applications        *\r
+**********************************************************************\r
+*                                                                    *\r
+*        (c) 2014-2014 SEGGER Microcontroller GmbH & Co. KG          *\r
+*                                                                    *\r
+*       Internet: www.segger.com Support: support@segger.com         *\r
+*                                                                    *\r
+**********************************************************************\r
+----------------------------------------------------------------------\r
+File    : SEGGER_RTT.c\r
+Date    : 17 Dec 2014\r
+Purpose : Implementation of SEGGER real-time terminal (RTT) which allows\r
+          real-time terminal communication on targets which support\r
+          debugger memory accesses while the CPU is running.\r
+\r
+          Type "int" is assumed to be 32-bits in size\r
+          H->T    Host to target communication\r
+          T->H    Target to host communication\r
+\r
+          RTT channel 0 is always present and reserved for Terminal usage.\r
+          Name is fixed to "Terminal"\r
+\r
+---------------------------END-OF-HEADER------------------------------\r
+*/\r
+\r
+#include "SEGGER_RTT_Conf.h"\r
+#include "SEGGER_RTT.h"\r
+\r
+#include <string.h>                 // for memcpy\r
+\r
+/*********************************************************************\r
+*\r
+*       Defines, configurable\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+#ifndef   BUFFER_SIZE_UP\r
+  #define BUFFER_SIZE_UP                                  (1024)  // Size of the buffer for terminal output of target, up to host\r
+#endif\r
+\r
+#ifndef   BUFFER_SIZE_DOWN\r
+  #define BUFFER_SIZE_DOWN                                (16)    // Size of the buffer for terminal input to target from host (Usually keyboard input)\r
+#endif\r
+\r
+#ifndef   SEGGER_RTT_MAX_NUM_UP_BUFFERS\r
+  #define SEGGER_RTT_MAX_NUM_UP_BUFFERS                   (1)     // Number of up-buffers (T->H) available on this target\r
+#endif\r
+\r
+#ifndef   SEGGER_RTT_MAX_NUM_DOWN_BUFFERS\r
+  #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS                 (1)     // Number of down-buffers (H->T) available on this target\r
+#endif\r
+\r
+#ifndef   SEGGER_RTT_LOCK\r
+  #define SEGGER_RTT_LOCK()\r
+#endif\r
+\r
+#ifndef   SEGGER_RTT_UNLOCK\r
+  #define SEGGER_RTT_UNLOCK()\r
+#endif\r
+\r
+#ifndef   SEGGER_RTT_IN_RAM\r
+  #define SEGGER_RTT_IN_RAM                               (0)\r
+#endif\r
+\r
+/*********************************************************************\r
+*\r
+*       Defines, fixed\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+#define MIN(a, b)        (((a) < (b)) ? (a) : (b))\r
+#define MAX(a, b)        (((a) > (b)) ? (a) : (b))\r
+\r
+#define MEMCPY(a, b, c)  memcpy((a),(b),(c))\r
+\r
+//\r
+// For some environments, NULL may not be defined until certain headers are included\r
+//\r
+#ifndef NULL\r
+  #define NULL 0\r
+#endif\r
+\r
+/*********************************************************************\r
+*\r
+*       Types\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+//\r
+// Description for a circular buffer (also called "ring buffer")\r
+// which is used as up- (T->H) or down-buffer (H->T)\r
+//\r
+typedef struct {\r
+  const char* sName;                     // Optional name. Standard names so far are: "Terminal", "VCom"\r
+  char*  pBuffer;                        // Pointer to start of buffer\r
+  int    SizeOfBuffer;                   // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.\r
+  volatile int WrOff;                    // Position of next item to be written by either host (down-buffer) or target (up-buffer). Must be volatile since it may be modified by host (down-buffer)\r
+  volatile int RdOff;                    // Position of next item to be read by target (down-buffer) or host (up-buffer). Must be volatile since it may be modified by host (up-buffer)\r
+  int    Flags;                          // Contains configuration flags\r
+} RING_BUFFER;\r
+\r
+//\r
+// RTT control block which describes the number of buffers available\r
+// as well as the configuration for each buffer\r
+//\r
+//\r
+typedef struct {\r
+  char        acID[16];                                 // Initialized to "SEGGER RTT"\r
+  int         MaxNumUpBuffers;                          // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)\r
+  int         MaxNumDownBuffers;                        // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)\r
+  RING_BUFFER aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS];       // Up buffers, transferring information up from target via debug probe to host\r
+  RING_BUFFER aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS];   // Down buffers, transferring information down from host via debug probe to target\r
+} SEGGER_RTT_CB;\r
+\r
+/*********************************************************************\r
+*\r
+*       Static data\r
+*\r
+**********************************************************************\r
+*/\r
+//\r
+// Allocate buffers for channel 0\r
+//\r
+static char _acUpBuffer  [BUFFER_SIZE_UP];\r
+static char _acDownBuffer[BUFFER_SIZE_DOWN];\r
+//\r
+// Initialize SEGGER Real-time-Terminal control block (CB)\r
+//\r
+static SEGGER_RTT_CB _SEGGER_RTT = {\r
+#if SEGGER_RTT_IN_RAM\r
+  "SEGGER RTTI",\r
+#else\r
+  "SEGGER RTT",\r
+#endif\r
+  SEGGER_RTT_MAX_NUM_UP_BUFFERS,\r
+  SEGGER_RTT_MAX_NUM_DOWN_BUFFERS,\r
+  {{ "Terminal", &_acUpBuffer[0],   sizeof(_acUpBuffer),   0, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP }},\r
+  {{ "Terminal", &_acDownBuffer[0], sizeof(_acDownBuffer), 0, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP }},\r
+};\r
+\r
+static char _ActiveTerminal;\r
+\r
+/*********************************************************************\r
+*\r
+*       Static code\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+/*********************************************************************\r
+*\r
+*       _strlen\r
+*\r
+*  Function description\r
+*    ANSI compatible function to determine the length of a string\r
+*\r
+*  Return value\r
+*    Length of string in bytes.\r
+*\r
+*  Parameters\r
+*    s         Pointer to \0 terminated string.\r
+*\r
+*  Notes\r
+*    (1) s needs to point to an \0 terminated string. Otherwise proper functionality of this function is not guaranteed.\r
+*/\r
+static int _strlen(const char* s) {\r
+  int Len;\r
+\r
+  Len = 0;\r
+  if (s == NULL) {\r
+    return 0;\r
+  }\r
+  do {\r
+    if (*s == 0) {\r
+      break;\r
+    }\r
+    Len++;\r
+    s++;\r
+  } while (1);\r
+  return Len;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       _Init\r
+*\r
+*  Function description\r
+*    In case SEGGER_RTT_IN_RAM is defined,\r
+*    _Init() modifies the ID of the RTT CB to allow identifying the\r
+*    RTT Control Block Structure in the data segment.\r
+*/\r
+static void _Init(void) {\r
+#if SEGGER_RTT_IN_RAM\r
+  if (_SEGGER_RTT.acID[10] == 'I') {\r
+    _SEGGER_RTT.acID[10] = '\0';\r
+  }\r
+#endif\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       Public code\r
+*\r
+**********************************************************************\r
+*/\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_Read\r
+*\r
+*  Function description\r
+*    Reads characters from SEGGER real-time-terminal control block\r
+*    which have been previously stored by the host.\r
+*\r
+*  Parameters\r
+*    BufferIndex  Index of Down-buffer to be used. (e.g. 0 for "Terminal")\r
+*    pBuffer      Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.\r
+*    BufferSize   Size of the target application buffer\r
+*\r
+*  Return values\r
+*    Number of bytes that have been read\r
+*/\r
+int SEGGER_RTT_Read(unsigned BufferIndex, char* pBuffer, unsigned BufferSize) {\r
+  int NumBytesRem;\r
+  unsigned NumBytesRead;\r
+  int RdOff;\r
+  int WrOff;\r
+\r
+  SEGGER_RTT_LOCK();\r
+  _Init();\r
+  RdOff = _SEGGER_RTT.aDown[BufferIndex].RdOff;\r
+  WrOff = _SEGGER_RTT.aDown[BufferIndex].WrOff;\r
+  NumBytesRead = 0;\r
+  //\r
+  // Read from current read position to wrap-around of buffer, first\r
+  //\r
+  if (RdOff > WrOff) {\r
+    NumBytesRem = _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer - RdOff;\r
+    NumBytesRem = MIN(NumBytesRem, (int)BufferSize);\r
+    MEMCPY(pBuffer, _SEGGER_RTT.aDown[BufferIndex].pBuffer + RdOff, NumBytesRem);\r
+    NumBytesRead += NumBytesRem;\r
+    pBuffer      += NumBytesRem;\r
+    BufferSize   -= NumBytesRem;\r
+    RdOff        += NumBytesRem;\r
+    //\r
+    // Handle wrap-around of buffer\r
+    //\r
+    if (RdOff == _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer) {\r
+      RdOff = 0;\r
+    }\r
+  }\r
+  //\r
+  // Read remaining items of buffer\r
+  //\r
+  NumBytesRem = WrOff - RdOff;\r
+  NumBytesRem = MIN(NumBytesRem, (int)BufferSize);\r
+  if (NumBytesRem > 0) {\r
+    MEMCPY(pBuffer, _SEGGER_RTT.aDown[BufferIndex].pBuffer + RdOff, NumBytesRem);\r
+    NumBytesRead += NumBytesRem;\r
+    pBuffer      += NumBytesRem;\r
+    BufferSize   -= NumBytesRem;\r
+    RdOff        += NumBytesRem;\r
+  }\r
+  if (NumBytesRead) {\r
+    _SEGGER_RTT.aDown[BufferIndex].RdOff = RdOff;\r
+  }\r
+  SEGGER_RTT_UNLOCK();\r
+  return NumBytesRead;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_Write\r
+*\r
+*  Function description\r
+*    Stores a specified number of characters in SEGGER RTT\r
+*    control block which is then read by the host.\r
+*\r
+*  Parameters\r
+*    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")\r
+*    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.\r
+*    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.\r
+*\r
+*  Return values\r
+*    Number of bytes which have been stored in the "Up"-buffer.\r
+*\r
+*  Notes\r
+*    (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.\r
+*/\r
+int SEGGER_RTT_Write(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes) {\r
+  int NumBytesToWrite;\r
+  unsigned NumBytesWritten;\r
+  int RdOff;\r
+  //\r
+  // Target is not allowed to perform other RTT operations while string still has not been stored completely.\r
+  // Otherwise we would probably end up with a mixed string in the buffer.\r
+  //\r
+  SEGGER_RTT_LOCK();\r
+  _Init();\r
+  //\r
+  // In case we are not in blocking mode,\r
+  // we need to calculate, how many bytes we can put into the buffer at all.\r
+  //\r
+  if ((_SEGGER_RTT.aUp[BufferIndex].Flags & SEGGER_RTT_MODE_MASK) != SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {\r
+    RdOff = _SEGGER_RTT.aUp[BufferIndex].RdOff;\r
+    NumBytesToWrite =  RdOff - _SEGGER_RTT.aUp[BufferIndex].WrOff - 1;\r
+    if (NumBytesToWrite < 0) {\r
+      NumBytesToWrite += _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer;\r
+    }\r
+    //\r
+    // If the complete data does not fit in the buffer, check if we have to skip it completely or trim the data\r
+    //\r
+    if ((int)NumBytes > NumBytesToWrite) {\r
+      if ((_SEGGER_RTT.aUp[BufferIndex].Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_NO_BLOCK_SKIP) {\r
+        SEGGER_RTT_UNLOCK();\r
+        return 0;\r
+      } else {\r
+        NumBytes = NumBytesToWrite;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Early out if nothing is to do\r
+  //\r
+  if (NumBytes == 0) {\r
+    SEGGER_RTT_UNLOCK();\r
+    return 0;\r
+  }\r
+  //\r
+  // Write data to buffer and handle wrap-around if necessary\r
+  //\r
+  NumBytesWritten = 0;\r
+  do {\r
+    RdOff = _SEGGER_RTT.aUp[BufferIndex].RdOff;                          // May be changed by host (debug probe) in the meantime\r
+    NumBytesToWrite = RdOff - _SEGGER_RTT.aUp[BufferIndex].WrOff - 1;\r
+    if (NumBytesToWrite < 0) {\r
+      NumBytesToWrite += _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer;\r
+    }\r
+    NumBytesToWrite = MIN(NumBytesToWrite, (_SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer - _SEGGER_RTT.aUp[BufferIndex].WrOff));    // Number of bytes that can be written until buffer wrap-around\r
+    NumBytesToWrite = MIN(NumBytesToWrite, (int)NumBytes);\r
+    MEMCPY(_SEGGER_RTT.aUp[BufferIndex].pBuffer + _SEGGER_RTT.aUp[BufferIndex].WrOff, pBuffer, NumBytesToWrite);\r
+    NumBytesWritten     += NumBytesToWrite;\r
+    pBuffer             += NumBytesToWrite;\r
+    NumBytes            -= NumBytesToWrite;\r
+    _SEGGER_RTT.aUp[BufferIndex].WrOff += NumBytesToWrite;\r
+    if (_SEGGER_RTT.aUp[BufferIndex].WrOff == _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer) {\r
+      _SEGGER_RTT.aUp[BufferIndex].WrOff = 0;\r
+    }\r
+  } while (NumBytes);\r
+  SEGGER_RTT_UNLOCK();\r
+  return NumBytesWritten;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_WriteString\r
+*\r
+*  Function description\r
+*    Stores string in SEGGER RTT control block.\r
+*    This data is read by the host.\r
+*\r
+*  Parameters\r
+*    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")\r
+*    s            Pointer to string.\r
+*\r
+*  Return values\r
+*    Number of bytes which have been stored in the "Up"-buffer.\r
+*\r
+*  Notes\r
+*    (1) If there is not enough space in the "Up"-buffer, depending on configuration,\r
+*        remaining characters may be dropped or RTT module waits until there is more space in the buffer.\r
+*    (2) String passed to this function has to be \0 terminated\r
+*    (3) \0 termination character is *not* stored in RTT buffer\r
+*/\r
+int SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {\r
+  int Len;\r
+\r
+  Len = _strlen(s);\r
+  return SEGGER_RTT_Write(BufferIndex, s, Len);\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_GetKey\r
+*\r
+*  Function description\r
+*    Reads one character from the SEGGER RTT buffer.\r
+*    Host has previously stored data there.\r
+*\r
+*  Return values\r
+*    <  0    No character available (buffer empty).\r
+*    >= 0    Character which has been read. (Possible values: 0 - 255)\r
+*\r
+*  Notes\r
+*    (1) This function is only specified for accesses to RTT buffer 0.\r
+*/\r
+int SEGGER_RTT_GetKey(void) {\r
+  char c;\r
+  int r;\r
+\r
+  r = SEGGER_RTT_Read(0, &c, 1);\r
+  if (r == 1) {\r
+    return (int)(unsigned char)c;\r
+  }\r
+  return -1;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_WaitKey\r
+*\r
+*  Function description\r
+*    Waits until at least one character is avaible in the SEGGER RTT buffer.\r
+*    Once a character is available, it is read and this function returns.\r
+*\r
+*  Return values\r
+*    >=0    Character which has been read.\r
+*\r
+*  Notes\r
+*    (1) This function is only specified for accesses to RTT buffer 0\r
+*    (2) This function is blocking if no character is present in RTT buffer\r
+*/\r
+int SEGGER_RTT_WaitKey(void) {\r
+  int r;\r
+\r
+  do {\r
+    r = SEGGER_RTT_GetKey();\r
+  } while (r < 0);\r
+  return r;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_HasKey\r
+*\r
+*  Function description\r
+*    Checks if at least one character for reading is available in the SEGGER RTT buffer.\r
+*\r
+*  Return values\r
+*    0      No characters are available to read.\r
+*    1      At least one character is available.\r
+*\r
+*  Notes\r
+*    (1) This function is only specified for accesses to RTT buffer 0\r
+*/\r
+int SEGGER_RTT_HasKey(void) {\r
+  int RdOff;\r
+\r
+  _Init();\r
+  RdOff = _SEGGER_RTT.aDown[0].RdOff;\r
+  if (RdOff != _SEGGER_RTT.aDown[0].WrOff) {\r
+    return 1;\r
+  }\r
+  return 0;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_ConfigUpBuffer\r
+*\r
+*  Function description\r
+*    Run-time configuration of a specific up-buffer (T->H).\r
+*    Buffer to be configured is specified by index.\r
+*    This includes: Buffer address, size, name, flags, ...\r
+*\r
+*  Return value\r
+*    >= 0  O.K.\r
+*     < 0  Error\r
+*/\r
+int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) {\r
+  _Init();\r
+  if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {\r
+    SEGGER_RTT_LOCK();\r
+    if (BufferIndex > 0) {\r
+      _SEGGER_RTT.aUp[BufferIndex].sName        = sName;\r
+      _SEGGER_RTT.aUp[BufferIndex].pBuffer      = pBuffer;\r
+      _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;\r
+      _SEGGER_RTT.aUp[BufferIndex].RdOff        = 0;\r
+      _SEGGER_RTT.aUp[BufferIndex].WrOff        = 0;\r
+    }\r
+    _SEGGER_RTT.aUp[BufferIndex].Flags          = Flags;\r
+    SEGGER_RTT_UNLOCK();\r
+    return 0;\r
+  }\r
+  return -1;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_ConfigDownBuffer\r
+*\r
+*  Function description\r
+*    Run-time configuration of a specific down-buffer (H->T).\r
+*    Buffer to be configured is specified by index.\r
+*    This includes: Buffer address, size, name, flags, ...\r
+*\r
+*  Return value\r
+*    >= 0  O.K.\r
+*     < 0  Error\r
+*/\r
+int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) {\r
+  _Init();\r
+  if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {\r
+    SEGGER_RTT_LOCK();\r
+    if (BufferIndex > 0) {\r
+      _SEGGER_RTT.aDown[BufferIndex].sName        = sName;\r
+      _SEGGER_RTT.aDown[BufferIndex].pBuffer      = pBuffer;\r
+      _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;\r
+      _SEGGER_RTT.aDown[BufferIndex].RdOff        = 0;\r
+      _SEGGER_RTT.aDown[BufferIndex].WrOff        = 0;\r
+    }\r
+    _SEGGER_RTT.aDown[BufferIndex].Flags          = Flags;\r
+    SEGGER_RTT_UNLOCK();\r
+    return 0;\r
+  }\r
+  return -1;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_Init\r
+*\r
+*  Function description\r
+*    Initializes the RTT Control Block.\r
+*    Should be used in RAM targets, at start of the application.\r
+*\r
+*/\r
+void SEGGER_RTT_Init (void) {\r
+  _Init();\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_SetTerminal\r
+*\r
+*  Function description\r
+*    Sets the terminal to be used for output on channel 0.\r
+*\r
+*/\r
+void SEGGER_RTT_SetTerminal (char TerminalId) {\r
+  char ac[2];\r
+\r
+  ac[0] = 0xFF;\r
+  if (TerminalId < 10) {\r
+    ac[1] = '0' + TerminalId;\r
+  } else if (TerminalId < 16) {\r
+    ac[1] = 'A' + (TerminalId - 0x0A);\r
+  } else {\r
+    return; // RTT only supports up to 16 virtual terminals.\r
+  }\r
+  _ActiveTerminal = TerminalId;\r
+  SEGGER_RTT_Write(0, ac, 2);\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_TerminalOut\r
+*\r
+*  Function description\r
+*    Writes a string to the given terminal\r
+*     without changing the terminal for channel 0.\r
+*\r
+*/\r
+int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {\r
+  char ac[2];\r
+  int  r;\r
+\r
+  ac[0] = 0xFF;\r
+  if (TerminalId < 10) {\r
+    ac[1] = '0' + TerminalId;\r
+  } else if (TerminalId < 16) {\r
+    ac[1] = 'A' + (TerminalId - 0x0A);\r
+  } else {\r
+    return -1; // RTT only supports up to 16 virtual terminals.\r
+  }\r
+  SEGGER_RTT_Write(0, ac, 2);\r
+  r = SEGGER_RTT_WriteString(0, s);\r
+  if (TerminalId < 10) {\r
+    ac[1] = '0' + _ActiveTerminal;\r
+  } else if (TerminalId < 16) {\r
+    ac[1] = 'A' + (_ActiveTerminal - 0x0A);\r
+  }\r
+  SEGGER_RTT_Write(0, ac, 2);\r
+  return r;\r
+}\r
+\r
+/*************************** End of file ****************************/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT.h
new file mode 100644 (file)
index 0000000..987354e
--- /dev/null
@@ -0,0 +1,110 @@
+/*********************************************************************\r
+*              SEGGER MICROCONTROLLER SYSTEME GmbH                   *\r
+*        Solutions for real time microcontroller applications        *\r
+**********************************************************************\r
+*                                                                    *\r
+*        (c) 1996-2014 SEGGER Microcontroller Systeme GmbH           *\r
+*                                                                    *\r
+* Internet: www.segger.com Support: support@segger.com               *\r
+*                                                                    *\r
+**********************************************************************\r
+----------------------------------------------------------------------\r
+File    : SEGGER_RTT.h\r
+Date    : 17 Dec 2014\r
+Purpose : Implementation of SEGGER real-time terminal which allows\r
+          real-time terminal communication on targets which support\r
+          debugger memory accesses while the CPU is running.\r
+---------------------------END-OF-HEADER------------------------------\r
+*/\r
+\r
+/*********************************************************************\r
+*\r
+*       Defines\r
+*\r
+**********************************************************************\r
+*/\r
+#define SEGGER_RTT_MODE_MASK                  (3 << 0)\r
+\r
+#define SEGGER_RTT_MODE_NO_BLOCK_SKIP         (0)\r
+#define SEGGER_RTT_MODE_NO_BLOCK_TRIM         (1 << 0)\r
+#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL    (1 << 1)\r
+\r
+#define RTT_CTRL_RESET                "\e[0m"\r
+\r
+#define RTT_CTRL_CLEAR                "\e[2J"\r
+\r
+#define RTT_CTRL_TEXT_BLACK           "\e[2;30m"\r
+#define RTT_CTRL_TEXT_RED             "\e[2;31m"\r
+#define RTT_CTRL_TEXT_GREEN           "\e[2;32m"\r
+#define RTT_CTRL_TEXT_YELLOW          "\e[2;33m"\r
+#define RTT_CTRL_TEXT_BLUE            "\e[2;34m"\r
+#define RTT_CTRL_TEXT_MAGENTA         "\e[2;35m"\r
+#define RTT_CTRL_TEXT_CYAN            "\e[2;36m"\r
+#define RTT_CTRL_TEXT_WHITE           "\e[2;37m"\r
+\r
+#define RTT_CTRL_TEXT_BRIGHT_BLACK    "\e[1;30m"\r
+#define RTT_CTRL_TEXT_BRIGHT_RED      "\e[1;31m"\r
+#define RTT_CTRL_TEXT_BRIGHT_GREEN    "\e[1;32m"\r
+#define RTT_CTRL_TEXT_BRIGHT_YELLOW   "\e[1;33m"\r
+#define RTT_CTRL_TEXT_BRIGHT_BLUE     "\e[1;34m"\r
+#define RTT_CTRL_TEXT_BRIGHT_MAGENTA  "\e[1;35m"\r
+#define RTT_CTRL_TEXT_BRIGHT_CYAN     "\e[1;36m"\r
+#define RTT_CTRL_TEXT_BRIGHT_WHITE    "\e[1;37m"\r
+\r
+#define RTT_CTRL_BG_BLACK             "\e[24;40m"\r
+#define RTT_CTRL_BG_RED               "\e[24;41m"\r
+#define RTT_CTRL_BG_GREEN             "\e[24;42m"\r
+#define RTT_CTRL_BG_YELLOW            "\e[24;43m"\r
+#define RTT_CTRL_BG_BLUE              "\e[24;44m"\r
+#define RTT_CTRL_BG_MAGENTA           "\e[24;45m"\r
+#define RTT_CTRL_BG_CYAN              "\e[24;46m"\r
+#define RTT_CTRL_BG_WHITE             "\e[24;47m"\r
+\r
+#define RTT_CTRL_BG_BRIGHT_BLACK      "\e[4;40m"\r
+#define RTT_CTRL_BG_BRIGHT_RED        "\e[4;41m"\r
+#define RTT_CTRL_BG_BRIGHT_GREEN      "\e[4;42m"\r
+#define RTT_CTRL_BG_BRIGHT_YELLOW     "\e[4;43m"\r
+#define RTT_CTRL_BG_BRIGHT_BLUE       "\e[4;44m"\r
+#define RTT_CTRL_BG_BRIGHT_MAGENTA    "\e[4;45m"\r
+#define RTT_CTRL_BG_BRIGHT_CYAN       "\e[4;46m"\r
+#define RTT_CTRL_BG_BRIGHT_WHITE      "\e[4;47m"\r
+\r
+\r
+/*********************************************************************\r
+*\r
+*       RTT API functions\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+int     SEGGER_RTT_Read             (unsigned BufferIndex,       char* pBuffer, unsigned BufferSize);\r
+int     SEGGER_RTT_Write            (unsigned BufferIndex, const char* pBuffer, unsigned NumBytes);\r
+int     SEGGER_RTT_WriteString      (unsigned BufferIndex, const char* s);\r
+\r
+int     SEGGER_RTT_GetKey           (void);\r
+int     SEGGER_RTT_WaitKey          (void);\r
+int     SEGGER_RTT_HasKey           (void);\r
+\r
+int     SEGGER_RTT_ConfigUpBuffer   (unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags);\r
+int     SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags);\r
+\r
+void    SEGGER_RTT_Init             (void);\r
+\r
+/*********************************************************************\r
+*\r
+*       RTT "Terminal" API functions\r
+*\r
+**********************************************************************\r
+*/\r
+void    SEGGER_RTT_SetTerminal        (char TerminalId);\r
+int     SEGGER_RTT_TerminalOut        (char TerminalId, const char* s);\r
+\r
+/*********************************************************************\r
+*\r
+*       RTT printf functions (require SEGGER_RTT_printf.c)\r
+*\r
+**********************************************************************\r
+*/\r
+int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);\r
+\r
+/*************************** End of file ****************************/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT_Conf.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT_Conf.h
new file mode 100644 (file)
index 0000000..c9845c6
--- /dev/null
@@ -0,0 +1,57 @@
+/*********************************************************************\r
+*              SEGGER MICROCONTROLLER SYSTEME GmbH                   *\r
+*        Solutions for real time microcontroller applications        *\r
+**********************************************************************\r
+*                                                                    *\r
+*        (c) 1996-2014 SEGGER Microcontroller Systeme GmbH           *\r
+*                                                                    *\r
+* Internet: www.segger.com Support: support@segger.com               *\r
+*                                                                    *\r
+**********************************************************************\r
+----------------------------------------------------------------------\r
+File    : SEGGER_RTT_Conf.h\r
+Date    : 17 Dec 2014\r
+Purpose : Implementation of SEGGER real-time terminal which allows\r
+          real-time terminal communication on targets which support\r
+          debugger memory accesses while the CPU is running.\r
+---------------------------END-OF-HEADER------------------------------\r
+*/\r
+\r
+/*********************************************************************\r
+*\r
+*       Defines, configurable\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+#define SEGGER_RTT_MAX_NUM_UP_BUFFERS             (2)     // Max. number of up-buffers (T->H) available on this target    (Default: 2)\r
+#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS           (2)     // Max. number of down-buffers (H->T) available on this target  (Default: 2)\r
+\r
+#define BUFFER_SIZE_UP                            (10 * 1024)  // Size of the buffer for terminal output of target, up to host (Default: 1k)\r
+#define BUFFER_SIZE_DOWN                          (32)    // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)\r
+\r
+#define SEGGER_RTT_PRINTF_BUFFER_SIZE             (64)    // Size of buffer for RTT printf to bulk-send chars via RTT     (Default: 64)\r
+\r
+//\r
+// Target is not allowed to perform other RTT operations while string still has not been stored completely.\r
+// Otherwise we would probably end up with a mixed string in the buffer.\r
+// If using  RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.\r
+//\r
+#define SEGGER_RTT_LOCK()\r
+#define SEGGER_RTT_UNLOCK()\r
+\r
+//\r
+// Define SEGGER_RTT_IN_RAM as 1\r
+// when using RTT in RAM targets (init and data section both in RAM).\r
+// This prevents the host to falsly identify the RTT Callback Structure\r
+// in the init segment as the used Callback Structure.\r
+//\r
+// When defined as 1,\r
+// the first call to an RTT function will modify the ID of the RTT Callback Structure.\r
+// To speed up identifying on the host,\r
+// especially when RTT functions are not called at the beginning of execution,\r
+// SEGGER_RTT_Init() should be called at the start of the application.\r
+//\r
+#define SEGGER_RTT_IN_RAM                         (0)\r
+\r
+/*************************** End of file ****************************/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT_Printf.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/SEGGER_RTT_Printf.c
new file mode 100644 (file)
index 0000000..f68c105
--- /dev/null
@@ -0,0 +1,443 @@
+/*********************************************************************\r
+*              SEGGER MICROCONTROLLER GmbH & Co. KG                  *\r
+*        Solutions for real time microcontroller applications        *\r
+**********************************************************************\r
+*                                                                    *\r
+*        (c) 2014-2014 SEGGER Microcontroller GmbH & Co. KG          *\r
+*                                                                    *\r
+*       Internet: www.segger.com Support: support@segger.com         *\r
+*                                                                    *\r
+**********************************************************************\r
+----------------------------------------------------------------------\r
+File    : SEGGER_RTT_printf.c\r
+Date    : 17 Dec 2014\r
+Purpose : Replacement for printf to write formatted data via RTT\r
+---------------------------END-OF-HEADER------------------------------\r
+*/\r
+#include "SEGGER_RTT.h"\r
+#include "SEGGER_RTT_Conf.h"\r
+\r
+/*********************************************************************\r
+*\r
+*       Defines, configurable\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE\r
+  #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)\r
+#endif\r
+\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+\r
+\r
+#define FORMAT_FLAG_LEFT_JUSTIFY   (1 << 0)\r
+#define FORMAT_FLAG_PAD_ZERO       (1 << 1)\r
+#define FORMAT_FLAG_PRINT_SIGN     (1 << 2)\r
+#define FORMAT_FLAG_ALTERNATE      (1 << 3)\r
+\r
+/*********************************************************************\r
+*\r
+*       Types\r
+*\r
+**********************************************************************\r
+*/\r
+\r
+typedef struct {\r
+  char* pBuffer;\r
+  int   BufferSize;\r
+  int   Cnt;\r
+\r
+  int   ReturnValue;\r
+\r
+  unsigned RTTBufferIndex;\r
+} SEGGER_RTT_PRINTF_DESC;\r
+\r
+/*********************************************************************\r
+*\r
+*       Function prototypes\r
+*\r
+**********************************************************************\r
+*/\r
+int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);\r
+\r
+/*********************************************************************\r
+*\r
+*       Static code\r
+*\r
+**********************************************************************\r
+*/\r
+/*********************************************************************\r
+*\r
+*       _StoreChar\r
+*/\r
+static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {\r
+  int Cnt;\r
+\r
+  Cnt = p->Cnt;\r
+  if ((Cnt + 1) <= p->BufferSize) {\r
+    *(p->pBuffer + Cnt) = c;\r
+    p->Cnt = Cnt + 1;\r
+    p->ReturnValue++;\r
+  }\r
+  //\r
+  // Write part of string, when the buffer is full\r
+  //\r
+  if (p->Cnt == p->BufferSize) {\r
+    if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {\r
+      p->ReturnValue = -1;\r
+    } else {\r
+      p->Cnt = 0;\r
+    }\r
+  }\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       _PrintUnsigned\r
+*/\r
+static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, int NumDigits, unsigned FieldWidth, unsigned FormatFlags) {\r
+  static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\r
+  unsigned Div;\r
+  unsigned Digit = 1;\r
+  unsigned Number;\r
+  unsigned Width;\r
+  char c;\r
+\r
+  Number = v;\r
+\r
+  //\r
+  // Get actual field width\r
+  //\r
+  Width = 1;\r
+  while (Number >= Base) {\r
+    Number = (Number / Base);\r
+    Width++;\r
+  }\r
+  if ((unsigned)NumDigits > Width) {\r
+    Width = NumDigits;\r
+  }\r
+  //\r
+  // Print leading chars if necessary\r
+  //\r
+  if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0) {\r
+    if (FieldWidth != 0) {\r
+      if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0)) {\r
+        c = '0';\r
+      } else {\r
+        c = ' ';\r
+      }\r
+      while ((FieldWidth != 0) && (Width < FieldWidth--)) {\r
+        _StoreChar(pBufferDesc, c);\r
+        if (pBufferDesc->ReturnValue < 0) {\r
+          return;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Count how many digits are required by precision\r
+  //\r
+  while (((v / Digit) >= Base) | (NumDigits-- > 1)) {\r
+    Digit *= Base;\r
+  }\r
+  //\r
+  // Output digits\r
+  //\r
+  do {\r
+    Div = v / Digit;\r
+    v -= Div * Digit;\r
+    _StoreChar(pBufferDesc, _aV2C[Div]);\r
+    if (pBufferDesc->ReturnValue < 0) {\r
+      break;\r
+    }\r
+    Digit /= Base;\r
+  } while (Digit);\r
+  //\r
+  // Print trailing spaces if necessary\r
+  //\r
+  if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {\r
+    if (FieldWidth != 0) {\r
+      while ((FieldWidth != 0) && (Width < FieldWidth--)) {\r
+        _StoreChar(pBufferDesc, ' ');\r
+        if (pBufferDesc->ReturnValue < 0) {\r
+          return;\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       _PrintInt\r
+*/\r
+static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {\r
+  unsigned Width;\r
+  unsigned Number;\r
+\r
+  Number = (v < 0) ? -v : v;\r
+\r
+  //\r
+  // Get actual field width\r
+  //\r
+  Width = 1;\r
+  while (Number >= Base) {\r
+    Number = (Number / Base);\r
+    Width++;\r
+  }\r
+  if (NumDigits > Width) {\r
+    Width = NumDigits;\r
+  }\r
+  if ((FieldWidth > 0) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {\r
+    FieldWidth--;\r
+  }\r
+\r
+  //\r
+  // Print leading spaces if necessary\r
+  //\r
+  if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0) || (NumDigits != 0)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0)) {\r
+    if (FieldWidth != 0) {\r
+      while ((FieldWidth != 0) && (Width < FieldWidth--)) {\r
+        _StoreChar(pBufferDesc, ' ');\r
+        if (pBufferDesc->ReturnValue < 0) {\r
+          return;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Print sign if necessary\r
+  //\r
+  if (v < 0) {\r
+    v = -v;\r
+    _StoreChar(pBufferDesc, '-');\r
+    if (pBufferDesc->ReturnValue < 0) {\r
+      return;\r
+    }\r
+  } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {\r
+    _StoreChar(pBufferDesc, '+');\r
+    if (pBufferDesc->ReturnValue < 0) {\r
+      return;\r
+    }\r
+  }\r
+  //\r
+  // Print leading zeros if necessary\r
+  //\r
+  if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0) && (NumDigits == 0)) {\r
+    if (FieldWidth != 0) {\r
+      while ((FieldWidth != 0) && (Width < FieldWidth--)) {\r
+        _StoreChar(pBufferDesc, '0');\r
+        if (pBufferDesc->ReturnValue < 0) {\r
+          return;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Print number without sign\r
+  //\r
+  _PrintUnsigned(pBufferDesc, v, Base, NumDigits, FieldWidth, FormatFlags);\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       Public code\r
+*\r
+**********************************************************************\r
+*/\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_vprintf\r
+*\r
+*  Function description\r
+*    Stores a formatted string in SEGGER RTT control block.\r
+*    This data is read by the host.\r
+*\r
+*  Parameters\r
+*    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")\r
+*    sFormat      Pointer to format string\r
+*    pParamList   Pointer to the list of arguments for the format string\r
+*\r
+*  Return values\r
+*    >= 0:  Number of bytes which have been stored in the "Up"-buffer.\r
+*     < 0:  Error\r
+*/\r
+int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {\r
+  char c;\r
+  SEGGER_RTT_PRINTF_DESC BufferDesc;\r
+  int v;\r
+  unsigned NumDigits;\r
+  unsigned FormatFlags;\r
+  unsigned FieldWidth;\r
+  char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];\r
+\r
+  BufferDesc.pBuffer        = acBuffer;\r
+  BufferDesc.BufferSize     = SEGGER_RTT_PRINTF_BUFFER_SIZE;\r
+  BufferDesc.Cnt            = 0;\r
+  BufferDesc.RTTBufferIndex = BufferIndex;\r
+  BufferDesc.ReturnValue    = 0;\r
+\r
+  do {\r
+    c = *sFormat++;\r
+    if (c == 0) {\r
+      break;\r
+    }\r
+    if (c == '%') {\r
+      //\r
+      // Filter out flags\r
+      //\r
+      FormatFlags = 0;\r
+      do {\r
+        c = *sFormat;\r
+        switch (c) {\r
+        case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;\r
+        case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO;     sFormat++; break;\r
+        case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN;   sFormat++; break;\r
+        case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE;    sFormat++; break;\r
+        default:  goto FilterFieldWidth;                   break;\r
+        }\r
+      } while (1);\r
+      //\r
+      // filter out field with\r
+      //\r
+FilterFieldWidth:\r
+      FieldWidth = 0;\r
+      do {\r
+        c = *sFormat;\r
+        if (c < '0' || c > '9') {\r
+          break;\r
+        }\r
+        sFormat++;\r
+        FieldWidth = FieldWidth * 10 + (c - '0');\r
+      } while (1);\r
+\r
+      //\r
+      // Filter out precision (number of digits to display)\r
+      //\r
+      NumDigits = 0;\r
+      c = *sFormat;\r
+      if (c == '.') {\r
+        sFormat++;\r
+        do {\r
+          c = *sFormat;\r
+          if (c < '0' || c > '9') {\r
+            break;\r
+          }\r
+          sFormat++;\r
+          NumDigits = NumDigits * 10 + (c - '0');\r
+        } while (1);\r
+      }\r
+      //\r
+      // Filter out length modifier\r
+      //\r
+      c = *sFormat;\r
+      do {\r
+        if (c == 'l' || c == 'h') {\r
+          c = *sFormat++;\r
+          continue;\r
+        }\r
+        break;\r
+      } while (1);\r
+      //\r
+      // Handle specifiers\r
+      //\r
+      switch (c) {\r
+      case 'c': {\r
+        char c0;\r
+        v = va_arg(*pParamList, int);\r
+        c0 = (char)v;\r
+        _StoreChar(&BufferDesc, c0);\r
+        break;\r
+      }\r
+      case 'd':\r
+        v = va_arg(*pParamList, int);\r
+        _PrintInt(&BufferDesc, v, 10, NumDigits, FieldWidth, FormatFlags);\r
+        break;\r
+      case 'u':\r
+        v = va_arg(*pParamList, int);\r
+        _PrintUnsigned(&BufferDesc, v, 10, NumDigits, FieldWidth, FormatFlags);\r
+        break;\r
+      case 'x':\r
+      case 'X':\r
+        v = va_arg(*pParamList, int);\r
+        _PrintUnsigned(&BufferDesc, v, 16, NumDigits, FieldWidth, FormatFlags);\r
+        break;\r
+      case 's':\r
+        {\r
+          const char * s = va_arg(*pParamList, const char *);\r
+          do {\r
+            c = *s++;\r
+            if (c == 0) {\r
+              break;\r
+            }\r
+           _StoreChar(&BufferDesc, c);\r
+          } while (BufferDesc.ReturnValue >= 0);\r
+        }\r
+        break;\r
+      case 'p':\r
+        v = va_arg(*pParamList, int);\r
+        _PrintUnsigned(&BufferDesc, v, 16, 8, 8, 0);\r
+        break;\r
+      case '%':\r
+        _StoreChar(&BufferDesc, '%');\r
+        break;\r
+      }\r
+      sFormat++;\r
+    } else {\r
+      _StoreChar(&BufferDesc, c);\r
+    }\r
+  } while (BufferDesc.ReturnValue >= 0);\r
+\r
+  if (BufferDesc.ReturnValue > 0) {\r
+    //\r
+    // Write remaining data, if any\r
+    //\r
+    if (BufferDesc.Cnt != 0) {\r
+      SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);\r
+    }\r
+    BufferDesc.ReturnValue += BufferDesc.Cnt;\r
+  }\r
+  return BufferDesc.ReturnValue;\r
+}\r
+\r
+/*********************************************************************\r
+*\r
+*       SEGGER_RTT_printf\r
+*\r
+*  Function description\r
+*    Stores a formatted string in SEGGER RTT control block.\r
+*    This data is read by the host.\r
+*\r
+*  Parameters\r
+*    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")\r
+*    sFormat      Pointer to format string, followed by the arguments for conversion\r
+*\r
+*  Return values\r
+*    >= 0:  Number of bytes which have been stored in the "Up"-buffer.\r
+*     < 0:  Error\r
+*\r
+*  Notes\r
+*    (1) Conversion specifications have following syntax:\r
+*          %[flags][FieldWidth][.Precision]ConversionSpecifier\r
+*    (2) Supported flags:\r
+*          -: Left justify within the field width\r
+*          +: Always print sign extension for signed conversions\r
+*          0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision\r
+*        Supported conversion specifiers:\r
+*          c: Print the argument as one char\r
+*          d: Print the argument as a signed integer\r
+*          u: Print the argument as an unsigned integer\r
+*          x: Print the argument as an hexadecimal integer\r
+*          s: Print the string pointed to by the argument\r
+*          p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)\r
+*/\r
+int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {\r
+  va_list ParamList;\r
+\r
+  va_start(ParamList, sFormat);\r
+  return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);\r
+}\r
+/*************************** End of file ****************************/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcConfig.h
new file mode 100644 (file)
index 0000000..3ada261
--- /dev/null
@@ -0,0 +1,326 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcConfig.h\r
+ *\r
+ * Configuration parameters for the streaming version trace recorder library.\r
+ * Before using the trace recorder library, please check that the default\r
+ * settings are appropriate for your system, and if necessary adjust these.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef TRC_CONFIG_H\r
+#define TRC_CONFIG_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_RECORDER_HARDWARE_PORT\r
+ *\r
+ * Specify what hardware is used.\r
+ *\r
+ * See trcHardwarePort.h for available ports, or to define your own.\r
+ ******************************************************************************/\r
+#define TRC_RECORDER_HARDWARE_PORT TRC_PORT_ARM_Cortex_M\r
+\r
+/******************************************************************************\r
+ * BSP and other project specific includes\r
+ * \r
+ * Include the necessary header files.\r
+ *****************************************************************************/\r
+#include "board.h"\r
+\r
+/******************************************************************************\r
+ * TRC_FREERTOS_VERSION\r
+ * \r
+ * Specify what version of FreeRTOS that is used. This is necessary compensate \r
+ * for renamed symbols in the FreeRTOS kernel (does not build if incorrect).\r
+ * \r
+ * TRC_FREERTOS_VERSION_7_3_OR_7_4 (= 1)               If using FreeRTOS v7.3.0 - v7.4.2\r
+ * TRC_FREERTOS_VERSION_7_5_OR_7_6 (= 2)               If using FreeRTOS v7.5.0 - v7.6.0\r
+ * TRC_FREERTOS_VERSION_8_0_OR_LATER (= 3)             If using FreeRTOS v8.0.0 or later\r
+ *****************************************************************************/\r
+#define TRC_FREERTOS_VERSION_NOT_SET                   0\r
+#define TRC_FREERTOS_VERSION_7_3_OR_7_4                        1\r
+#define TRC_FREERTOS_VERSION_7_5_OR_7_6                        2\r
+#define TRC_FREERTOS_VERSION_8_0_OR_LATER              3\r
+\r
+#define TRC_FREERTOS_VERSION   TRC_FREERTOS_VERSION_8_0_OR_LATER\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_SYMBOL_TABLE_SLOTS\r
+ *\r
+ * The maximum number of symbols names that can be stored. This includes:\r
+ * - Task names\r
+ * - Named ISRs (vTraceSetISRProperties)\r
+ * - Named kernel objects (vTraceStoreKernelObjectName)\r
+ * - User event channels (vTraceStoreUserEventChannelName)\r
+ *\r
+ * If this value is too small, not all symbol names will be stored and the\r
+ * trace display will be affected. In that case, there will be warnings\r
+ * (as User Events) from TzCtrl task, that monitors this.\r
+ ******************************************************************************/\r
+#define TRC_SYMBOL_TABLE_SLOTS 30\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_SYMBOL_MAX_LENGTH\r
+ *\r
+ * The maximum length of symbol names, including:\r
+ * - Task names\r
+ * - Named ISRs (vTraceSetISRProperties)\r
+ * - Named kernel objects (vTraceStoreKernelObjectName)\r
+ * - User event channel names (vTraceStoreUserEventChannelName)\r
+ *\r
+ * If longer symbol names are used, they will be truncated by the recorder,\r
+ * which will affect the trace display. In that case, there will be warnings\r
+ * (as User Events) from TzCtrl task, that monitors this.\r
+ ******************************************************************************/\r
+#define TRC_SYMBOL_MAX_LENGTH 25\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_OBJECT_DATA_SLOTS\r
+ *\r
+ * The maximum number of object data entries (used for task priorities) that can\r
+ * be stored at the same time. Must be sufficient for all tasks, otherwise there\r
+ * will be warnings (as User Events) from TzCtrl task, that monitors this.\r
+ ******************************************************************************/\r
+#define TRC_OBJECT_DATA_SLOTS 20\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_RTT_UP_BUFFER_INDEX\r
+ *\r
+ * Defines the RTT buffer to use for writing the trace data. Make sure that\r
+ * the PC application has the same setting (File->Settings).\r
+ *\r
+ ******************************************************************************/\r
+#define TRC_RTT_UP_BUFFER_INDEX 0\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_RTT_DOWN_BUFFER_INDEX\r
+ *\r
+ * Defines the RTT buffer to use for reading the trace data. Make sure that\r
+ * the PC application has the same setting (File->Settings).\r
+ *\r
+ ******************************************************************************/\r
+#define TRC_RTT_DOWN_BUFFER_INDEX 0\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_CTRL_TASK_STACK_SIZE\r
+ *\r
+ * The stack size of the TzCtrl task, that receive commands.\r
+ * We are aiming to remove this extra task in future versions.\r
+ ******************************************************************************/\r
+#define TRC_CTRL_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 2)\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_CTRL_TASK_PRIORITY\r
+ *\r
+ * The priority of the TzCtrl task, that receive commands from.\r
+ * We are aiming to remove this extra task in future versions.\r
+ ******************************************************************************/\r
+#define TRC_CTRL_TASK_PRIORITY 1\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_CTRL_TASK_DELAY\r
+ *\r
+ * The delay between every loop of the TzCtrl task. A high delay will reduce the\r
+ * CPU load, but may cause missed events if the TzCtrl task is performing the \r
+ * trace transfer.\r
+ ******************************************************************************/\r
+#define TRC_CTRL_TASK_DELAY ((10 * configTICK_RATE_HZ) / 1000)\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_MEASURE_BLOCKING_TIME\r
+ *\r
+ * If using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL, this activates detection and\r
+ * warnings in case of blocking in SEGGER_RTT_Write (if too small buffer).\r
+ *\r
+ * If enabling this option (set to 1) warnings are given as User Events if\r
+ * blocking occurs, including the longest blocking time. These warnings are\r
+ * given on the channel "Blocking on trace buffer".\r
+ *\r
+ * Note: If you get such warnings, you can study the blocking time in the User\r
+ * Event Signal Plot to get an overview of the magnitude of the blocking and\r
+ * decide if acceptable.\r
+ *\r
+ * To eliminate or at least reduce occurrences of blocking:\r
+ *\r
+ * - Verify the J-Link Speed in the Settings dialog of the PC application.\r
+ *   Default is 4 MHz, but can be increased a lot depending on your J-Link.\r
+ *\r
+ *   Note: If you set the speed higher than your J-Link can manage, the J-Link\r
+ *   driver will instead use the fastest supported speed. The actual speed used\r
+ *   is shown in the title of the trace receiver window.\r
+ *\r
+ * - Increase the buffer size (BUFFER_SIZE_UP in SEGGER_RTT_Conf.h).\r
+ *\r
+ * - Reduce the amount of data produced, e.g., by removing frequent User Events.\r
+ ******************************************************************************/\r
+#define TRC_MEASURE_BLOCKING_TIME 0\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_BLOCKING_MIN_CYCLES\r
+ *\r
+ * Threshold value for deciding if SEGGER_RTT_Write has blocked. Most events\r
+ * take 200-300 cycles on ARM Cortex-M MCUs, so anything above 500 cycles should\r
+ * be due to blocking on a full buffer (i.e., waiting for the debugger to read\r
+ * the RTT buffer data and make room for more...).\r
+ ******************************************************************************/\r
+#define TRC_BLOCKING_MIN_CYCLES 500\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_RECORDER_BUFFER_ALLOCATION\r
+ *\r
+ * Specifies how the recorder buffer is allocated.\r
+ *\r
+ * Values:\r
+ * TRC_RECORDER_BUFFER_ALLOCATION_STATIC\r
+ * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC\r
+ ******************************************************************************/\r
+#define TRC_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_RECORDER_TRANSFER_METHOD\r
+ *\r
+ * Specifies what type of transfer method is used.\r
+ *\r
+ * Values:\r
+ * TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK\r
+ * TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK\r
+ * TRC_RECORDER_TRANSFER_METHOD_TCPIP\r
+ * TRC_RECORDER_TRANSFER_METHOD_CUSTOM\r
+ ******************************************************************************/\r
+#define TRC_RECORDER_TRANSFER_METHOD TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK\r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_BLOCKING_TRANSFER\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Specifies how the custom transfer method handles full buffers.\r
+ *\r
+ * Values:\r
+ * 0 - The custom transfer method skips sending the data if the buffer is full.\r
+ * 1 - The custom transfer method blocks on send if the buffer is full.\r
+ ******************************************************************************/\r
+ #define TRC_STREAM_CUSTOM_BLOCKING_TRANSFER \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_ALLOCATE_FIELDS\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Macro that should allocate any buffers needed for the transfer method.\r
+ * See trcStreamPort.h for examples.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_ALLOCATE_FIELDS() \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_INIT\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Used to initialize and set up the transfer method.\r
+ * See trcStreamPort.h for examples.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_INIT() \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_ALLOCATE_EVENT\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Specifies how the trace events that should be sent using the transfer method\r
+ * are allocated first.\r
+ * See trcStreamPort.h for examples.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_ALLOCATE_EVENT(_type, _ptr, _size) \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_COMMIT_EVENT\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Specifies how trace events are sent/written.\r
+ * See trcStreamPort.h for examples.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_COMMIT_EVENT(_ptr, _size) \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_READ_DATA\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Specifies how data is read using the transfer method.\r
+ * See trcStreamPort.h for examples.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_READ_DATA(_ptrData, _size, _ptrBytesRead) \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_PERIODIC_SEND_DATA\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Specifies how data is sent periodically. Used by certain transfer methods.\r
+ * See trcStreamPort.h for examples.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_PERIODIC_SEND_DATA(_ptrBytesSent) \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_ON_TRACE_BEGIN\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Called on tracing is started. Use this to perform any necessary steps to \r
+ * properly start the trace, such as clearing buffers.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_ON_TRACE_BEGIN() \r
+\r
+/*******************************************************************************\r
+ * Configuration Macro: TRC_STREAM_CUSTOM_ON_TRACE_END\r
+ *\r
+ * Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.\r
+ *\r
+ * Called when tracing is disabled. Use this to perform any necessary steps to \r
+ * properly shut down the tracing, such as clearing buffers.\r
+ ******************************************************************************/\r
+#define TRC_STREAM_CUSTOM_ON_TRACE_END() \r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* TRC_CONFIG_H */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcHardwarePort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcHardwarePort.h
new file mode 100644 (file)
index 0000000..1133944
--- /dev/null
@@ -0,0 +1,194 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcHardwarePort.h\r
+ *\r
+ * The hardware abstraction layer for the trace recorder library.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef TRC_HARDWARE_PORT_H\r
+#define TRC_HARDWARE_PORT_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+#include <stdint.h>\r
+\r
+/******************************************************************************\r
+ * Hardware ports\r
+ * To get accurate timestamping, a hardware timer is necessary. Below are the\r
+ * available ports. Some of these are "unofficial", meaning that\r
+ * they have not yet been verified by Percepio but have been contributed by\r
+ * external developers. They should work, otherwise let us know by emailing\r
+ * support@percepio.com. Some work on any OS platform, while other are specific\r
+ * to a certain operating system.\r
+ *****************************************************************************/\r
+\r
+\r
+/****** Port Name ***************************** Code */\r
+#define TRC_PORT_APPLICATION_DEFINED                   -1\r
+#define TRC_PORT_NOT_SET                                               0\r
+#define TRC_PORT_ARM_Cortex_M                                  1\r
+#define TRC_PORT_ARM_CORTEX_A9                                 2\r
+#define TRC_PORT_Renesas_RX600                                 3\r
+#define TRC_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 4\r
+#define TRC_PORT_MICROCHIP_PIC32_MX_MZ                 5\r
+\r
+/*******************************************************************************\r
+ *\r
+ * HWTC Macros - Hardware Timer/Counter Isolation Layer\r
+ *\r
+ * These two HWTC macros provides a hardware isolation layer representing a\r
+ * generic hardware timer/counter used for the timestamping.\r
+ *\r
+ * HWTC_COUNT: The current value of the counter. This is expected to be reset\r
+ * a each tick interrupt. Thus, when the tick handler starts, the counter has\r
+ * already wrapped.\r
+ *\r
+ * HWTC_TYPE: Defines the type of timer/counter used for HWTC_COUNT:\r
+ *\r
+ * - FREE_RUNNING_32BIT_INCR:\r
+ *   Free-running 32-bit timer, counting upwards from 0 - > 0xFFFFFFFF\r
+ *\r
+ * - FREE_RUNNING_32BIT_DECR\r
+ *   Free-running 32-bit counter, counting downwards from 0xFFFFFFFF -> 0\r
+ *\r
+ * - OS_TIMER_INCR\r
+ *      Interrupt timer, counts upwards from 0 until HWTC_PERIOD-1\r
+ *\r
+ * - OS_TIMER_DECR\r
+ *   Interrupt timer, counts downwards from HWTC_PERIOD-1 until 0\r
+ *\r
+ *******************************************************************************\r
+ *\r
+ * IRQ_PRIORITY_ORDER\r
+ *\r
+ * Macro which should be defined as an integer of 0 or 1.\r
+ *\r
+ * It is only used only to sort and colorize the interrupts in priority order,\r
+ * in case you record interrupts using the vTraceStoreISRBegin and\r
+ * vTraceStoreISREnd routines. 1 indicates higher value is more important.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#define TRC_FREE_RUNNING_32BIT_INCR 1\r
+#define TRC_FREE_RUNNING_32BIT_DECR 2\r
+#define TRC_OS_TIMER_INCR 3\r
+#define TRC_OS_TIMER_DECR 4\r
+\r
+#if (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_ARM_Cortex_M)\r
+\r
+       #define HWTC_TYPE TRC_OS_TIMER_DECR\r
+    #define HWTC_COUNT (*((uint32_t*)0xE000E018)) /* SysTick counter */\r
+       #define IRQ_PRIORITY_ORDER 0\r
+\r
+#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_Renesas_RX600)\r
+\r
+       #include "iodefine.h"\r
+\r
+       #define HWTC_TYPE TRC_OS_TIMER_INCR\r
+       #define HWTC_COUNT (CMT0.CMCNT)\r
+       #define IRQ_PRIORITY_ORDER 1\r
+\r
+#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_MICROCHIP_PIC32_MX_MZ)\r
+\r
+       #define HWTC_TYPE TRC_OS_TIMER_INCR\r
+       #define HWTC_COUNT (TMR1)\r
+       #define IRQ_PRIORITY_ORDER 0\r
+\r
+#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)\r
+\r
+       #define RTIFRC0 *((uint32_t *)0xFFFFFC10)\r
+       #define RTICOMP0 *((uint32_t *)0xFFFFFC50)\r
+       #define RTIUDCP0 *((uint32_t *)0xFFFFFC54)\r
+\r
+       #define HWTC_TYPE TRC_OS_TIMER_INCR\r
+       #define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))\r
+       #define IRQ_PRIORITY_ORDER 0\r
+\r
+#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_ARM_CORTEX_A9)\r
+       /* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */\r
+       #define CA9_MPCORE_PERIPHERAL_BASE_ADDRESS      0xSOMETHING\r
+       \r
+       #define CA9_MPCORE_PRIVATE_MEMORY_OFFSET        0x0600\r
+       #define CA9_MPCORE_PRIVCTR_PERIOD_REG   (*(volatile uint32_t*)(CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00))\r
+       #define CA9_MPCORE_PRIVCTR_COUNTER_REG  (*(volatile uint32_t*)(CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04))\r
+       #define CA9_MPCORE_PRIVCTR_CONTROL_REG  (*(volatile uint32_t*)(CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08))\r
+       \r
+       #define CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK    0x0000FF00\r
+       #define CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT   8\r
+       #define CA9_MPCORE_PRIVCTR_PRESCALER        (((CA9_MPCORE_PRIVCTR_CONTROL_REG & CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)\r
+\r
+    #define HWTC_TYPE                                                  TRC_OS_TIMER_DECR\r
+    #define HWTC_COUNT                          CA9_MPCORE_PRIVCTR_COUNTER_REG\r
+    #define IRQ_PRIORITY_ORDER 0\r
+\r
+#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_APPLICATION_DEFINED)\r
+\r
+       #if !( defined (HWTC_TYPE) && defined (HWTC_COUNT) && defined (IRQ_PRIORITY_ORDER))\r
+               #error RECORDER_HARDWARE_PORT is PORT_APPLICATION_DEFINED but not all of the necessary constants have been defined.\r
+       #endif\r
+\r
+#elif (TRC_RECORDER_HARDWARE_PORT != TRC_PORT_NOT_SET)\r
+\r
+       #error "RECORDER_HARDWARE_PORT had unsupported value!"\r
+       #define TRC_RECORDER_HARDWARE_PORT PORT_NOT_SET\r
+\r
+#endif\r
+\r
+#if (TRC_RECORDER_HARDWARE_PORT != TRC_PORT_NOT_SET)\r
+\r
+       #ifndef HWTC_COUNT\r
+       #error "HWTC_COUNT is not set!"\r
+       #endif\r
+\r
+       #ifndef HWTC_TYPE\r
+       #error "HWTC_TYPE is not set!"\r
+       #endif\r
+\r
+       #ifndef IRQ_PRIORITY_ORDER\r
+       #error "IRQ_PRIORITY_ORDER is not set!"\r
+       #elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)\r
+       #error "IRQ_PRIORITY_ORDER has bad value!"\r
+       #endif\r
+\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* TRC_HARDWARE_PORT_H */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcKernelPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcKernelPort.c
new file mode 100644 (file)
index 0000000..e3a9c46
--- /dev/null
@@ -0,0 +1,267 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcKernelPort.c\r
+ *\r
+ * The kernel-specific code for integration with FreeRTOS.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#include "trcKernelPort.h"\r
+\r
+#if (USE_TRACEALYZER_RECORDER == 1)\r
+\r
+#include <stdint.h>\r
+#include "trcRecorder.h"\r
+#include "trcStreamPort.h"\r
+#include "task.h"\r
+\r
+/* TzCtrl task TCB */\r
+static xTaskHandle HandleTzCtrl;\r
+\r
+/* Called by TzCtrl task periodically (every 100 ms) */\r
+static void CheckRecorderStatus(void);\r
+\r
+/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */\r
+static portTASK_FUNCTION( TzCtrl, pvParameters );\r
+\r
+/* Monitored by TzCtrl task, that give warnings as User Events */\r
+extern volatile uint32_t NoRoomForSymbol;\r
+extern volatile uint32_t NoRoomForObjectData;\r
+extern volatile uint32_t LongestSymbolName;\r
+extern volatile uint32_t MaxBytesTruncated;\r
+\r
+#define TRC_PORT_MALLOC(size) pvPortMalloc(size)\r
+#if ((TRC_STREAM_PORT_BLOCKING_TRANSFER == 1) && (TRC_MEASURE_BLOCKING_TIME == 1))\r
+\r
+/*** Used in blocking transfer mode, if enabled TRC_MEASURE_BLOCKING_TIME **************/\r
+\r
+/* The highest number of cycles used by SEGGER_RTT_Write. */\r
+static volatile int32_t blockingCyclesMax;\r
+\r
+/* The number of times SEGGER_RTT_Write has blocked due to a full buffer. */\r
+static volatile uint32_t blockingCount;\r
+\r
+/* User Event Channel for giving warnings regarding blocking */\r
+static char* trcDiagnosticsChannel;\r
+\r
+#endif /*((TRC_STREAM_PORT_BLOCKING_TRANSFER==1) && (TRC_MEASURE_BLOCKING_TIME))*/\r
+\r
+TRC_STREAM_PORT_ALLOCATE_FIELDS()\r
+\r
+/* User Event Channel for giving warnings regarding NoRoomForSymbol etc. */\r
+char* trcWarningChannel;\r
+\r
+/* Keeps track of previous values, to only react on changes. */\r
+static uint32_t NoRoomForSymbol_last = 0;\r
+static uint32_t NoRoomForObjectData_last = 0;\r
+static uint32_t LongestSymbolName_last = 0;\r
+static uint32_t MaxBytesTruncated_last = 0;\r
+\r
+/*******************************************************************************\r
+ * prvTraceGetCurrentTaskHandle\r
+ *\r
+ * Function that returns the handle to the currently executing task.\r
+ *\r
+ ******************************************************************************/\r
+void* prvTraceGetCurrentTaskHandle(void)\r
+{\r
+       return xTaskGetCurrentTaskHandle();\r
+}\r
+\r
+/*******************************************************************************\r
+ * prvIsNewTCB\r
+ *\r
+ * Function that returns the handle to the currently executing task.\r
+ *\r
+ ******************************************************************************/\r
+static void* pCurrentTCB = NULL;\r
+uint32_t prvIsNewTCB(void* pNewTCB)\r
+{\r
+       if (pCurrentTCB != pNewTCB)\r
+       {\r
+               pCurrentTCB = pNewTCB;\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+/*******************************************************************************\r
+ * CheckRecorderStatus\r
+ *\r
+ * Called by TzCtrl task periodically (every 100 ms - seems reasonable).\r
+ * Checks a number of diagnostic variables and give warnings as user events,\r
+ * in most cases including a suggested solution.\r
+ ******************************************************************************/\r
+static void CheckRecorderStatus(void)\r
+{\r
+       if (NoRoomForSymbol > NoRoomForSymbol_last)\r
+       {\r
+               vTracePrintF(trcWarningChannel, "TRC_SYMBOL_TABLE_SLOTS too small. Add %d slots.",\r
+                       NoRoomForSymbol);\r
+\r
+               NoRoomForSymbol_last = NoRoomForSymbol;\r
+       }\r
+\r
+       if (NoRoomForObjectData > NoRoomForObjectData_last)\r
+       {\r
+               vTracePrintF(trcWarningChannel, "TRC_OBJECT_DATA_SLOTS too small. Add %d slots.",\r
+                       NoRoomForObjectData);\r
+\r
+               NoRoomForObjectData_last = NoRoomForObjectData;\r
+       }\r
+\r
+       if (LongestSymbolName > LongestSymbolName_last)\r
+       {\r
+               if (LongestSymbolName > TRC_SYMBOL_MAX_LENGTH)\r
+               {\r
+                       vTracePrintF(trcWarningChannel, "TRC_SYMBOL_MAX_LENGTH too small. Add %d chars.",\r
+                               LongestSymbolName);\r
+               }\r
+               LongestSymbolName_last = LongestSymbolName;\r
+       }\r
+\r
+       if (MaxBytesTruncated > MaxBytesTruncated_last)\r
+       {\r
+               /* Some string event generated a too long string that was truncated.\r
+               This may happen for the following functions:\r
+               - vTracePrintF\r
+               - vTracePrintF\r
+               - vTraceStoreKernelObjectName\r
+               - vTraceStoreUserEventChannelName\r
+               - vTraceSetISRProperties\r
+\r
+               A PSF event may store maximum 60 bytes payload, including data arguments\r
+               and string characters. For User Events, also the User Event Channel ptr\r
+               must be squeezed in, if a channel is specified. */\r
+\r
+               vTracePrintF(trcWarningChannel, "String event too long, up to %d bytes truncated.",\r
+                       MaxBytesTruncated);\r
+\r
+               MaxBytesTruncated_last = MaxBytesTruncated;\r
+       }\r
+\r
+#if ((TRC_STREAM_PORT_BLOCKING_TRANSFER==1) && (TRC_MEASURE_BLOCKING_TIME))\r
+       if (blockingCount > 0)\r
+       {\r
+               /* At least one case of blocking since the last check and this is\r
+               the longest case. */\r
+               vTracePrintF(trcDiagnosticsChannel, "Longest since last: %d us",\r
+                       (uint32_t)blockingCyclesMax/(TRACE_CPU_CLOCK_HZ/1000000));\r
+\r
+               blockingCyclesMax = 0;\r
+       }\r
+#endif\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceOnTraceBegin\r
+ *\r
+ * Called on trace begin.\r
+ ******************************************************************************/\r
+void vTraceOnTraceBegin(void)\r
+{\r
+       TRC_STREAM_PORT_ON_TRACE_BEGIN();\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceOnTraceEnd\r
+ *\r
+ * Called on trace end.\r
+ ******************************************************************************/\r
+void vTraceOnTraceEnd(void)\r
+{\r
+       TRC_STREAM_PORT_ON_TRACE_END();\r
+}\r
+\r
+/*******************************************************************************\r
+ * TzCtrl\r
+ *\r
+ * Task for receiving commands from Tracealyzer and for recorder diagnostics.\r
+ *\r
+ ******************************************************************************/\r
+static portTASK_FUNCTION( TzCtrl, pvParameters )\r
+{\r
+       TracealyzerCommandType msg;\r
+       int bytes = 0;\r
+\r
+       while (1)\r
+       {\r
+               bytes = 0;\r
+               TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), &bytes);\r
+               if (bytes != 0)\r
+               {\r
+                       if (bytes == sizeof(TracealyzerCommandType))\r
+                       {\r
+                               if (isValidCommand(&msg))\r
+                               {\r
+                                       processCommand(&msg); /* Start or Stop currently... */\r
+                               }\r
+                       }\r
+               }\r
+\r
+               do\r
+               {\r
+                       bytes = 0;\r
+                       TRC_STREAM_PORT_PERIODIC_SEND_DATA(&bytes);\r
+               }\r
+               while (bytes != 0);\r
+\r
+               CheckRecorderStatus();\r
+               vTaskDelay(TRC_CTRL_TASK_DELAY);        /* 10ms */\r
+       }\r
+}\r
+\r
+/*******************************************************************************\r
+ * Trace_Init\r
+ *\r
+ * The main initialization routine for the trace recorder. Configures the stream\r
+ * and activates the TzCtrl task.\r
+ * Also sets up the diagnostic User Event channels used by TzCtrl task.\r
+ *\r
+ ******************************************************************************/\r
+void Trace_Init(void)\r
+{\r
+       TRC_STREAM_PORT_INIT();\r
+\r
+       trcWarningChannel = vTraceStoreUserEventChannelName("Warnings from Recorder");\r
+\r
+#if ((TRC_STREAM_PORT_BLOCKING_TRANSFER==1) && (TRC_MEASURE_BLOCKING_TIME))\r
+       trcDiagnosticsChannel = vTraceStoreUserEventChannelName("Blocking on trace buffer");\r
+#endif\r
+\r
+       /* Creates the TzCtrl task - receives trace commands (start, stop, ...) */\r
+       xTaskCreate( TzCtrl, "TzCtrl", configMINIMAL_STACK_SIZE, NULL, TRC_CTRL_TASK_PRIORITY, &HandleTzCtrl );\r
+}\r
+\r
+#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcKernelPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcKernelPort.h
new file mode 100644 (file)
index 0000000..554cabc
--- /dev/null
@@ -0,0 +1,929 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcKernelPort.h\r
+ *\r
+ * The kernel-specific definitions for FreeRTOS.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+\r
+#ifndef TRC_KERNEL_PORT_H\r
+#define TRC_KERNEL_PORT_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+#include "FreeRTOS.h"  /* Defines configUSE_TRACE_FACILITY */\r
+#include "trcConfig.h"\r
+#include "trcHardwarePort.h"\r
+\r
+extern int uiInEventGroupSetBitsFromISR;\r
+\r
+#define USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY\r
+\r
+#if (USE_TRACEALYZER_RECORDER == 1)\r
+\r
+/*******************************************************************************\r
+ * Trace_Init\r
+ *\r
+ * The main initalization routine for the embOS-Trace recorder. Configures RTT,\r
+ * activates the PTRACE instrumentation in embOS and the TzCtrl task.\r
+ * Also sets up the diagnostic User Event channels used by TzCtrl task.\r
+ *\r
+ * Settings used by the trace recorder are found in these header files:\r
+ *  - SEGGER_RTT_Conf.h: settings for SEGGER Real-Time Terminal (RTT) which is\r
+ *    used for the trace streaming.\r
+ *  - trcKernelPort.h: RTT related settings for the trace streaming.\r
+ *  - trcRecorder.h - settings for allocation of internal recorder tables.\r
+ *  - trcHardwarePort.h - hardware-specific configuration (timestamping).\r
+ ******************************************************************************/\r
+void Trace_Init(void);\r
+\r
+/*******************************************************************************\r
+ * vTraceOnTraceBegin\r
+ *\r
+ * Called on trace begin.\r
+ ******************************************************************************/\r
+void vTraceOnTraceBegin(void);\r
+\r
+/*******************************************************************************\r
+ * vTraceOnTraceEnd\r
+ *\r
+ * Called on trace end.\r
+ ******************************************************************************/\r
+void vTraceOnTraceEnd(void);\r
+\r
+#include "trcRecorder.h"\r
+\r
+/* Defines that must be set for the recorder to work properly */\r
+#define KERNEL_ID 0x1AA1\r
+#define TRACE_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */\r
+#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */\r
+\r
+#if (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_ARM_Cortex_M)\r
+       \r
+       /* Uses CMSIS API. Must be #included in trcConfig.h. */\r
+       #define TRACE_ALLOC_CRITICAL_SECTION() int __irq_status;\r
+       #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);}\r
+       #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);}\r
+\r
+#endif\r
+\r
+#if ((TRC_RECORDER_HARDWARE_PORT == TRC_PORT_ARM_CORTEX_A9) || (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_Renesas_RX600))\r
+       #define TRACE_ALLOC_CRITICAL_SECTION() int __irq_status;\r
+       #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}\r
+       #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}\r
+#endif\r
+\r
+#ifndef TRACE_ENTER_CRITICAL_SECTION\r
+       #error "This port has no valid definition for critical sections! See http://percepio.com/2014/10/27/how-to-define-critical-sections-for-the-recorder/"\r
+#endif\r
+\r
+void* prvTraceGetCurrentTaskHandle(void);\r
+uint32_t prvIsNewTCB(void* pNewTCB);\r
+\r
+#define OS_IS_SWITCH_FROM_INT_REQUIRED() 0\r
+#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle()\r
+\r
+/*************************************************************************/\r
+/* KERNEL SPECIFIC OBJECT CONFIGURATION                                                                         */\r
+/*************************************************************************/\r
+\r
+/*******************************************************************************\r
+ * The event codes - should match the offline config file.\r
+ *\r
+ * Some sections below are encoded to allow for constructions like:\r
+ *\r
+ * vTraceStoreKernelCall(EVENTGROUP_CREATE + objectclass, ...\r
+ *\r
+ * The object class ID is given by the three LSB bits, in such cases. Since each\r
+ * object class has a separate object property table, the class ID is needed to\r
+ * know what section in the object table to use for getting an object name from\r
+ * an object handle.\r
+ ******************************************************************************/\r
+\r
+#define PSF_EVENT_NULL_EVENT                                                           0x00\r
+\r
+/* PSF event codes */\r
+#define PSF_EVENT_TRACE_START                                                          0x01\r
+#define PSF_EVENT_TS_CONFIG                                                                    0x02\r
+#define PSF_EVENT_OBJ_NAME                                                                     0x03\r
+#define PSF_EVENT_TASK_PRIORITY                                                                0x04\r
+#define PSF_EVENT_TASK_PRIO_INHERIT                                                    0x05\r
+#define PSF_EVENT_TASK_PRIO_DISINHERIT                                         0x06\r
+#define PSF_EVENT_DEFINE_ISR                                                           0x07\r
+\r
+#define PSF_EVENT_TASK_CREATE                                                          0x10\r
+#define PSF_EVENT_QUEUE_CREATE                                                         0x11\r
+#define PSF_EVENT_SEMAPHORE_BINARY_CREATE                                      0x12\r
+#define PSF_EVENT_MUTEX_CREATE                                                         0x13\r
+#define PSF_EVENT_TIMER_CREATE                                                         0x14\r
+#define PSF_EVENT_EVENTGROUP_CREATE                                                    0x15\r
+#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE                                    0x16\r
+#define PSF_EVENT_MUTEX_RECURSIVE_CREATE                                       0x17\r
+\r
+#define PSF_EVENT_TASK_DELETE                                                          0x20\r
+#define PSF_EVENT_QUEUE_DELETE                                                         0x21\r
+#define PSF_EVENT_SEMAPHORE_DELETE                                                     0x22\r
+#define PSF_EVENT_MUTEX_DELETE                                                         0x23\r
+#define PSF_EVENT_TIMER_DELETE                                                         0x24\r
+#define PSF_EVENT_EVENTGROUP_DELETE                                                    0x25\r
+\r
+#define PSF_EVENT_TASK_READY                                                           0x30\r
+#define PSF_EVENT_NEW_TIME                                                                     0x31\r
+#define PSF_EVENT_NEW_TIME_SCHEDULER_SUSPENDED                         0x32\r
+#define PSF_EVENT_ISR_BEGIN                                                                    0x33\r
+#define PSF_EVENT_ISR_RESUME                                                           0x34\r
+#define PSF_EVENT_TS_BEGIN                                                                     0x35\r
+#define PSF_EVENT_TS_RESUME                                                                    0x36\r
+#define PSF_EVENT_TASK_ACTIVATE                                                                0x37\r
+\r
+#define PSF_EVENT_MALLOC                                                                       0x38\r
+#define PSF_EVENT_FREE                                                                         0x39\r
+\r
+#define PSF_EVENT_LOWPOWER_BEGIN                                                       0x3A\r
+#define PSF_EVENT_LOWPOWER_END                                                         0x3B\r
+\r
+#define PSF_EVENT_IFE_NEXT                                                                     0x3C\r
+#define PSF_EVENT_IFE_DIRECT                                                           0x3D\r
+\r
+#define PSF_EVENT_TASK_CREATE_FAILED                                           0x40\r
+#define PSF_EVENT_QUEUE_CREATE_FAILED                                          0x41\r
+#define PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED                       0x42\r
+#define PSF_EVENT_MUTEX_CREATE_FAILED                                          0x43\r
+#define PSF_EVENT_TIMER_CREATE_FAILED                                          0x44\r
+#define PSF_EVENT_EVENTGROUP_CREATE_FAILED                                     0x45\r
+#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED                     0x46\r
+#define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED                                0x47\r
+\r
+#define PSF_EVENT_TIMER_DELETE_FAILED                                          0x48\r
+\r
+#define PSF_EVENT_QUEUE_SEND                                                           0x50\r
+#define PSF_EVENT_SEMAPHORE_GIVE                                                       0x51\r
+#define PSF_EVENT_MUTEX_GIVE                                                           0x52\r
+\r
+#define PSF_EVENT_QUEUE_SEND_FAILED                                                    0x53\r
+#define PSF_EVENT_SEMAPHORE_GIVE_FAILED                                                0x54\r
+#define PSF_EVENT_MUTEX_GIVE_FAILED                                                    0x55\r
+\r
+#define PSF_EVENT_QUEUE_SEND_BLOCK                                                     0x56\r
+#define PSF_EVENT_SEMAPHORE_GIVE_BLOCK                                         0x57\r
+#define PSF_EVENT_MUTEX_GIVE_BLOCK                                                     0x58\r
+\r
+#define PSF_EVENT_QUEUE_SEND_FROMISR                                           0x59\r
+#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR                                       0x5A\r
+\r
+#define PSF_EVENT_QUEUE_SEND_FROMISR_FAILED                                    0x5C\r
+#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED                                0x5D\r
+\r
+#define PSF_EVENT_QUEUE_RECEIVE                                                                0x60\r
+#define PSF_EVENT_SEMAPHORE_TAKE                                                       0x61\r
+#define PSF_EVENT_MUTEX_TAKE                                                           0x62\r
+\r
+#define PSF_EVENT_QUEUE_RECEIVE_FAILED                                         0x63\r
+#define PSF_EVENT_SEMAPHORE_TAKE_FAILED                                                0x64\r
+#define PSF_EVENT_MUTEX_TAKE_FAILED                                                    0x65\r
+\r
+#define PSF_EVENT_QUEUE_RECEIVE_BLOCK                                          0x66\r
+#define PSF_EVENT_SEMAPHORE_TAKE_BLOCK                                         0x67\r
+#define PSF_EVENT_MUTEX_TAKE_BLOCK                                                     0x68\r
+\r
+#define PSF_EVENT_QUEUE_RECEIVE_FROMISR                                                0x69\r
+#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR                                       0x6A\r
+\r
+#define PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED                         0x6C\r
+#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED                                0x6D\r
+\r
+#define PSF_EVENT_QUEUE_PEEK                                                           0x70\r
+#define PSF_EVENT_SEMAPHORE_PEEK                                                       0x71    /* Will never be used */\r
+#define PSF_EVENT_MUTEX_PEEK                                                           0x72    /* Will never be used */\r
+\r
+#define PSF_EVENT_QUEUE_PEEK_FAILED                                                    0x73\r
+#define PSF_EVENT_SEMAPHORE_PEEK_FAILED                                                0x74    /* Will never be used */\r
+#define PSF_EVENT_MUTEX_PEEK_FAILED                                                    0x75    /* Will never be used */\r
+\r
+#define PSF_EVENT_QUEUE_PEEK_BLOCK                                                     0x76\r
+#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK                                         0x77    /* Will never be used */\r
+#define PSF_EVENT_MUTEX_PEEK_BLOCK                                                     0x78    /* Will never be used */\r
+\r
+#define PSF_EVENT_TASK_DELAY_UNTIL                                                     0x79\r
+#define PSF_EVENT_TASK_DELAY                                                           0x7A\r
+#define PSF_EVENT_TASK_SUSPEND                                                         0x7B\r
+#define PSF_EVENT_TASK_RESUME                                                          0x7C\r
+#define PSF_EVENT_TASK_RESUME_FROMISR                                          0x7D\r
+\r
+#define PSF_EVENT_TIMER_PENDFUNCCALL                                           0x80\r
+#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR                           0x81\r
+#define PSF_EVENT_TIMER_PENDFUNCCALL_FAILED                                    0x82\r
+#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED                    0x83\r
+\r
+#define PSF_EVENT_USER_EVENT                                                           0x90\r
+\r
+#define PSF_EVENT_TIMER_START                                                          0xA0\r
+#define PSF_EVENT_TIMER_RESET                                                          0xA1\r
+#define PSF_EVENT_TIMER_STOP                                                           0xA2\r
+#define PSF_EVENT_TIMER_CHANGEPERIOD                                           0xA3\r
+#define PSF_EVENT_TIMER_START_FROMISR                                          0xA4\r
+#define PSF_EVENT_TIMER_RESET_FROMISR                                          0xA5\r
+#define PSF_EVENT_TIMER_STOP_FROMISR                                           0xA6\r
+#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR                           0xA7\r
+#define PSF_EVENT_TIMER_START_FAILED                                           0xA8\r
+#define PSF_EVENT_TIMER_RESET_FAILED                                           0xA9\r
+#define PSF_EVENT_TIMER_STOP_FAILED                                                    0xAA\r
+#define PSF_EVENT_TIMER_CHANGEPERIOD_FAILED                                    0xAB\r
+#define PSF_EVENT_TIMER_START_FROMISR_FAILED                           0xAC\r
+#define PSF_EVENT_TIMER_RESET_FROMISR_FAILED                           0xAD\r
+#define PSF_EVENT_TIMER_STOP_FROMISR_FAILED                                    0xAE\r
+#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED                    0xAF\r
+\r
+#define PSF_EVENT_EVENTGROUP_SYNC                                                      0xB0\r
+#define PSF_EVENT_EVENTGROUP_WAITBITS                                          0xB1\r
+#define PSF_EVENT_EVENTGROUP_CLEARBITS                                         0xB2\r
+#define PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR                         0xB3\r
+#define PSF_EVENT_EVENTGROUP_SETBITS                                           0xB4\r
+#define PSF_EVENT_EVENTGROUP_SETBITS_FROMISR                           0xB5\r
+#define PSF_EVENT_EVENTGROUP_SYNC_BLOCK                                                0xB6\r
+#define PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK                                    0xB7\r
+#define PSF_EVENT_EVENTGROUP_SYNC_FAILED                                       0xB8\r
+#define PSF_EVENT_EVENTGROUP_WAITBITS_FAILED                           0xB9\r
+\r
+#define PSF_EVENT_QUEUE_SEND_FRONT                                                     0xC0\r
+#define PSF_EVENT_QUEUE_SEND_FRONT_FAILED                                      0xC1\r
+#define PSF_EVENT_QUEUE_SEND_FRONT_BLOCK                                       0xC2\r
+#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR                                     0xC3\r
+#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED                      0xC4\r
+#define PSF_EVENT_MUTEX_GIVE_RECURSIVE                                         0xC5\r
+#define PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED                          0xC6\r
+#define PSF_EVENT_MUTEX_TAKE_RECURSIVE                                         0xC7\r
+#define PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED                          0xC8\r
+\r
+#define PSF_EVENT_TASK_NOTIFY                                                          0xC9\r
+#define PSF_EVENT_TASK_NOTIFY_TAKE                                                     0xCA\r
+#define PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK                                       0xCB\r
+#define PSF_EVENT_TASK_NOTIFY_TAKE_FAILED                                      0xCC\r
+#define PSF_EVENT_TASK_NOTIFY_WAIT                                                     0xCD\r
+#define PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK                                       0xCE\r
+#define PSF_EVENT_TASK_NOTIFY_WAIT_FAILED                                      0xCF\r
+#define PSF_EVENT_TASK_NOTIFY_FROM_ISR                                         0xD0\r
+#define PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR                                    0xD1\r
+\r
+#define TRACE_GET_OS_TICKS() (uiTraceTickCount)\r
+\r
+/************************************************************************/\r
+/* KERNEL SPECIFIC DATA AND FUNCTIONS NEEDED TO PROVIDE THE                            */\r
+/* FUNCTIONALITY REQUESTED BY THE TRACE RECORDER                                               */\r
+/************************************************************************/\r
+\r
+#if (configUSE_TIMERS == 1)\r
+#undef INCLUDE_xTimerGetTimerDaemonTaskHandle\r
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1\r
+#endif\r
+\r
+/************************************************************************/\r
+/* KERNEL SPECIFIC MACROS USED BY THE TRACE RECORDER                                   */\r
+/************************************************************************/\r
+\r
+#define TRACE_MALLOC(size) pvPortMalloc(size)\r
+\r
+/************************************************************************/\r
+/* KERNEL SPECIFIC WRAPPERS THAT SHOULD BE CALLED BY THE KERNEL                 */\r
+/************************************************************************/\r
+\r
+#if (configUSE_TICKLESS_IDLE != 0)\r
+\r
+#undef traceLOW_POWER_IDLE_BEGIN\r
+#define traceLOW_POWER_IDLE_BEGIN() \\r
+       { \\r
+               vTraceStoreEvent0(PSF_EVENT_LOWPOWER_BEGIN); \\r
+       }\r
+\r
+#undef traceLOW_POWER_IDLE_END\r
+#define traceLOW_POWER_IDLE_END() \\r
+       { \\r
+               vTraceStoreEvent0(PSF_EVENT_LOWPOWER_END); \\r
+       }\r
+\r
+#endif\r
+\r
+/* A macro that will update the tick count when returning from tickless idle */\r
+#undef traceINCREASE_TICK_COUNT\r
+/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/\r
+#define traceINCREASE_TICK_COUNT( xCount ) \r
+\r
+/* Called for each task that becomes ready */\r
+#undef traceMOVED_TASK_TO_READY_STATE\r
+#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_READY, (uint32_t)pxTCB);\r
+\r
+/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */\r
+#undef traceTASK_INCREMENT_TICK\r
+#if (TRC_FREERTOS_VERSION == TRC_FREERTOS_VERSION_7_3_OR_7_4)\r
+\r
+#define traceTASK_INCREMENT_TICK( xTickCount ) \\r
+       if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \\r
+       if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { vTraceStoreEvent1(PSF_EVENT_NEW_TIME, (xTickCount + 1)); }\r
+\r
+#else\r
+\r
+#define traceTASK_INCREMENT_TICK( xTickCount ) \\r
+       if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \\r
+       if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { vTraceStoreEvent1(PSF_EVENT_NEW_TIME, (xTickCount + 1)); }\r
+\r
+#endif\r
+\r
+/* Called on each task-switch */\r
+#undef traceTASK_SWITCHED_IN\r
+#define traceTASK_SWITCHED_IN() \\r
+       if (prvIsNewTCB(pxCurrentTCB)) \\r
+       { \\r
+               vTraceStoreEvent2(PSF_EVENT_TASK_ACTIVATE, (uint32_t)pxCurrentTCB, pxCurrentTCB->uxPriority); \\r
+       }\r
+\r
+/* Called on vTaskSuspend */\r
+#undef traceTASK_SUSPEND\r
+#define traceTASK_SUSPEND( pxTaskToSuspend ) \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_SUSPEND, (uint32_t)pxTaskToSuspend);\r
+\r
+/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */\r
+#undef traceTASK_DELAY\r
+#define traceTASK_DELAY() \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_DELAY, xTicksToDelay);\r
+\r
+/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */\r
+#undef traceTASK_DELAY_UNTIL\r
+#define traceTASK_DELAY_UNTIL() \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, xTimeToWake);\r
+\r
+/* Called on vTaskDelete */\r
+#undef traceTASK_DELETE\r
+#define traceTASK_DELETE( pxTaskToDelete ) \\r
+       vTraceStoreEvent2(PSF_EVENT_TASK_DELETE, (uint32_t)pxTaskToDelete, (pxTaskToDelete != NULL) ? (pxTaskToDelete->uxPriority) : 0);\r
+\r
+/* Called on vQueueDelete */\r
+#undef traceQUEUE_DELETE\r
+#define traceQUEUE_DELETE( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_QUEUE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent2(PSF_EVENT_MUTEX_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \\r
+                       break; \\r
+       }\r
+\r
+/* Called on vTaskCreate */\r
+#undef traceTASK_CREATE\r
+#define traceTASK_CREATE(pxNewTCB) \\r
+       if (pxNewTCB != NULL) \\r
+       { \\r
+               vTraceSaveSymbol(pxNewTCB, (const char*)pcName); \\r
+               vTraceSaveObjectData(pxNewTCB, uxPriority); \\r
+               vTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, pcName, pxNewTCB); \\r
+               vTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, uxPriority); \\r
+       }\r
+\r
+/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */\r
+#undef traceTASK_CREATE_FAILED\r
+#define traceTASK_CREATE_FAILED() \\r
+       vTraceStoreEvent0(PSF_EVENT_TASK_CREATE_FAILED);\r
+\r
+/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */\r
+#undef traceQUEUE_CREATE\r
+#define traceQUEUE_CREATE( pxNewQueue )\\r
+       switch (pxNewQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE, (uint32_t)pxNewQueue, pxNewQueue->uxLength); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+                       vTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (uint32_t)pxNewQueue); \\r
+                       break; \\r
+       }\r
+\r
+/* Called in xQueueCreate, if the queue creation fails */\r
+#undef traceQUEUE_CREATE_FAILED\r
+#define traceQUEUE_CREATE_FAILED( queueType ) \\r
+       switch (queueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent0(PSF_EVENT_QUEUE_CREATE_FAILED); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+                       vTraceStoreEvent0(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED); \\r
+                       break; \\r
+       }\r
+\r
+/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */\r
+#undef traceCREATE_COUNTING_SEMAPHORE\r
+#if TRC_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_0_OR_LATER\r
+#define traceCREATE_COUNTING_SEMAPHORE() \\r
+       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, ((Queue_t *) xHandle)->uxMessagesWaiting);\r
+#else\r
+#define traceCREATE_COUNTING_SEMAPHORE() \\r
+       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)pxHandle, pxHandle->uxMessagesWaiting);\r
+#endif\r
+\r
+#undef traceCREATE_COUNTING_SEMAPHORE_FAILED\r
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \\r
+       vTraceStoreEvent0(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED);\r
+\r
+/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */\r
+#undef traceCREATE_MUTEX\r
+#define traceCREATE_MUTEX( pxNewQueue ) \\r
+       switch (ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+                       vTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \\r
+                       break; \\r
+       }\r
+\r
+/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */\r
+#undef traceCREATE_MUTEX_FAILED\r
+#define traceCREATE_MUTEX_FAILED() \\r
+       switch (ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+                       vTraceStoreEvent0(PSF_EVENT_MUTEX_CREATE_FAILED); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent0(PSF_EVENT_MUTEX_CREATE_FAILED); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when a message is sent to a queue */ /* CS IS NEW ! */\r
+#undef traceQUEUE_SEND\r
+#define traceQUEUE_SEND( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE, (uint32_t)pxQueue); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when a message failed to be sent to a queue (timeout) */\r
+#undef traceQUEUE_SEND_FAILED\r
+#define traceQUEUE_SEND_FAILED( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_FAILED, (uint32_t)pxQueue); \\r
+                       break; \\r
+       }\r
+\r
+       /*trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, FAILED, UNUSED, pxQueue);*/\r
+\r
+/* Called when the task is blocked due to a send operation on a full queue */\r
+#undef traceBLOCKING_ON_QUEUE_SEND\r
+#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_BLOCK, (uint32_t)pxQueue); \\r
+                       break; \\r
+       }\r
+\r
+/* Called for Recursive Mutex */\r
+#undef traceGIVE_MUTEX_RECURSIVE\r
+#define traceGIVE_MUTEX_RECURSIVE( pxMutex ) \\r
+       vTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_RECURSIVE, (uint32_t)pxMutex);\r
+\r
+/* Called for Recursive Mutex */\r
+#undef traceGIVE_MUTEX_RECURSIVE_FAILED\r
+#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \\r
+       vTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED, (uint32_t)pxMutex);\r
+\r
+/**************************************************************************/\r
+/* Hack to make sure xQueueGiveFromISR also has a xCopyPosition parameter */\r
+/**************************************************************************/\r
+/* Helpers needed to correctly expand names */\r
+#define TZ__CAT2(a,b) a ## b\r
+#define TZ__CAT(a,b) TZ__CAT2(a, b)\r
+\r
+/* Expands name if this header is included... uxQueueType must be a macro that only exists in queue.c or whatever, and it must expand to nothing or to something that's valid in identifiers */\r
+#define xQueueGiveFromISR(a,b) TZ__CAT(xQueueGiveFromISR__, uxQueueType) (a,b)\r
+\r
+/* If in queue.c, the "uxQueueType" macro expands to "pcHead". queueSEND_TO_BACK is the value we need to send in */\r
+#define xQueueGiveFromISR__pcHead(__a, __b) MyWrapper(__a, __b, const BaseType_t xCopyPosition); \\r
+BaseType_t xQueueGiveFromISR(__a, __b) { return MyWrapper(xQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK); } \\r
+BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)\r
+\r
+/* If not in queue.c, "uxQueueType" isn't expanded */\r
+#define xQueueGiveFromISR__uxQueueType(__a, __b) xQueueGiveFromISR(__a,__b)\r
+\r
+/**************************************************************************/\r
+/* End of xQueueGiveFromISR hack                                          */\r
+/**************************************************************************/\r
+\r
+/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */\r
+#undef traceQUEUE_SEND_FROM_ISR\r
+#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when a message send from interrupt context fails (since the queue was full) */\r
+#undef traceQUEUE_SEND_FROM_ISR_FAILED\r
+#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when a message is received from a queue */\r
+#undef traceQUEUE_RECEIVE\r
+#define traceQUEUE_RECEIVE( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent3(PSF_EVENT_QUEUE_RECEIVE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent3(PSF_EVENT_SEMAPHORE_TAKE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE, (uint32_t)pxQueue, xTicksToWait); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when a receive operation on a queue fails (timeout) */\r
+#undef traceQUEUE_RECEIVE_FAILED\r
+#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_QUEUE_RECEIVE_FAILED : PSF_EVENT_QUEUE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_SEMAPHORE_TAKE_FAILED : PSF_EVENT_SEMAPHORE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent2(xJustPeeking == pdFALSE ? PSF_EVENT_MUTEX_TAKE_FAILED : PSF_EVENT_MUTEX_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when the task is blocked due to a receive operation on an empty queue */\r
+#undef traceBLOCKING_ON_QUEUE_RECEIVE\r
+#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_QUEUE_RECEIVE_BLOCK : PSF_EVENT_QUEUE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_SEMAPHORE_TAKE_BLOCK : PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent2(xJustPeeking == pdFALSE ? PSF_EVENT_MUTEX_TAKE_BLOCK : PSF_EVENT_MUTEX_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait); \\r
+                       break; \\r
+       }\r
+               \r
+#undef traceTAKE_MUTEX_RECURSIVE\r
+#if TRC_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_0_OR_LATER\r
+#define traceTAKE_MUTEX_RECURSIVE( pxQueue ) \\r
+       vTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE, (uint32_t)pxQueue, xTicksToWait);\r
+#else\r
+#define traceTAKE_MUTEX_RECURSIVE( pxQueue ) \\r
+       vTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE, (uint32_t)pxQueue, xBlockTime);\r
+#endif\r
+\r
+#undef traceTAKE_MUTEX_RECURSIVE_FAILED\r
+#if TRC_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_0_OR_LATER\r
+#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxQueue ) \\r
+vTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED, (uint32_t)pxQueue, xTicksToWait);\r
+#else\r
+#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxQueue ) \\r
+vTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED, (uint32_t)pxQueue, xBlockTime);\r
+#endif\r
+\r
+/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */\r
+#undef traceQUEUE_RECEIVE_FROM_ISR\r
+#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \\r
+switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \\r
+                       break; \\r
+       }\r
+\r
+/* Called when a message receive from interrupt context fails (since the queue was empty) */\r
+#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED\r
+#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+       }\r
+\r
+/* Called on xQueuePeek */\r
+#undef traceQUEUE_PEEK\r
+#define traceQUEUE_PEEK( pxQueue ) \\r
+       switch (pxQueue->ucQueueType) \\r
+       { \\r
+               case queueQUEUE_TYPE_BASE: \\r
+                       vTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_BINARY_SEMAPHORE: \\r
+               case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \\r
+                       vTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \\r
+                       break; \\r
+               case queueQUEUE_TYPE_MUTEX: \\r
+               case queueQUEUE_TYPE_RECURSIVE_MUTEX: \\r
+                       vTraceStoreEvent1(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue); \\r
+                       break; \\r
+       }\r
+\r
+/* Called in vTaskPrioritySet */\r
+#undef traceTASK_PRIORITY_SET\r
+#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \\r
+       vTraceStoreEvent2(PSF_EVENT_TASK_PRIORITY, (uint32_t)pxTask, uxNewPriority);\r
+       \r
+/* Called in vTaskPriorityInherit, which is called by Mutex operations */\r
+#undef traceTASK_PRIORITY_INHERIT\r
+#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \\r
+       vTraceStoreEvent2(PSF_EVENT_TASK_PRIO_INHERIT, (uint32_t)pxTask, uxNewPriority);\r
+\r
+/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */\r
+#undef traceTASK_PRIORITY_DISINHERIT\r
+#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \\r
+       vTraceStoreEvent2(PSF_EVENT_TASK_PRIO_DISINHERIT, (uint32_t)pxTask, uxNewPriority);\r
+\r
+/* Called in vTaskResume */\r
+#undef traceTASK_RESUME\r
+#define traceTASK_RESUME( pxTaskToResume ) \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_RESUME, (uint32_t)pxTaskToResume);\r
+\r
+/* Called in vTaskResumeFromISR */\r
+#undef traceTASK_RESUME_FROM_ISR\r
+#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_RESUME_FROMISR, (uint32_t)pxTaskToResume);\r
+\r
+#undef traceMALLOC\r
+#define traceMALLOC( pvAddress, uiSize ) \\r
+       vTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, (int32_t)uiSize);\r
+\r
+#undef traceFREE\r
+#define traceFREE( pvAddress, uiSize ) \\r
+       vTraceStoreEvent2(PSF_EVENT_FREE, (uint32_t)pvAddress, (int32_t)(-uiSize));\r
+\r
+/* Called in timer.c - xTimerCreate */\r
+#undef traceTIMER_CREATE\r
+#define traceTIMER_CREATE(tmr) \\r
+       vTraceStoreEvent2(PSF_EVENT_TIMER_CREATE, (uint32_t)tmr, tmr->xTimerPeriodInTicks);\r
+\r
+#undef traceTIMER_CREATE_FAILED\r
+#define traceTIMER_CREATE_FAILED() \\r
+       vTraceStoreEvent0(PSF_EVENT_TIMER_CREATE_FAILED);\r
+\r
+#if TRC_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_0_OR_LATER\r
+#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \\r
+       case tmrCOMMAND_RESET: \\r
+               vTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (uint32_t)tmr, xOptionalValue); \\r
+               break; \\r
+       case tmrCOMMAND_START_FROM_ISR: \\r
+               vTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \\r
+               break; \\r
+       case tmrCOMMAND_RESET_FROM_ISR: \\r
+               vTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \\r
+               break; \\r
+       case tmrCOMMAND_STOP_FROM_ISR: \\r
+               vTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \\r
+               break; \\r
+       case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \\r
+               vTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \\r
+               break;\r
+#else\r
+#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \r
+#endif\r
+\r
+/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */\r
+#undef traceTIMER_COMMAND_SEND\r
+#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \\r
+       switch(xCommandID) \\r
+       { \\r
+               case tmrCOMMAND_START: \\r
+                       break; \\r
+               case tmrCOMMAND_STOP: \\r
+                       break; \\r
+               case tmrCOMMAND_CHANGE_PERIOD: \\r
+                       vTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (uint32_t)tmr, xOptionalValue); \\r
+                       break; \\r
+               case tmrCOMMAND_DELETE: \\r
+                       vTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (uint32_t)tmr); \\r
+                       break; \\r
+               traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \\r
+       }\r
+\r
+#undef tracePEND_FUNC_CALL\r
+#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \\r
+       vTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL : PSF_EVENT_TIMER_PENDFUNCCALL_FAILED, (uint32_t)func);\r
+\r
+#undef tracePEND_FUNC_CALL_FROM_ISR\r
+#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \\r
+       vTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, (uint32_t)func);\r
+\r
+#undef traceEVENT_GROUP_CREATE\r
+#define traceEVENT_GROUP_CREATE(eg) \\r
+       vTraceStoreEvent1(PSF_EVENT_EVENTGROUP_CREATE, (uint32_t)eg);\r
+\r
+#undef traceEVENT_GROUP_DELETE\r
+#define traceEVENT_GROUP_DELETE(eg) \\r
+       vTraceStoreEvent1(PSF_EVENT_EVENTGROUP_DELETE, (uint32_t)eg);\r
+\r
+#undef traceEVENT_GROUP_CREATE_FAILED\r
+#define traceEVENT_GROUP_CREATE_FAILED() \\r
+       vTraceStoreEvent0(PSF_EVENT_EVENTGROUP_CREATE_FAILED);\r
+\r
+#undef traceEVENT_GROUP_SYNC_BLOCK\r
+#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \\r
+       vTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (uint32_t)eg, bitsToWaitFor);\r
+\r
+#undef traceEVENT_GROUP_SYNC_END\r
+#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \\r
+       vTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (uint32_t)eg, bitsToWaitFor);\r
+\r
+#undef traceEVENT_GROUP_WAIT_BITS_BLOCK\r
+#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \\r
+       vTraceStoreEvent2(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (uint32_t)eg, bitsToWaitFor);\r
+\r
+#undef traceEVENT_GROUP_WAIT_BITS_END\r
+#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \\r
+       vTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (uint32_t)eg, bitsToWaitFor);\r
+\r
+#undef traceEVENT_GROUP_CLEAR_BITS\r
+#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \\r
+       vTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS, (uint32_t)eg, bitsToClear);\r
+\r
+#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR\r
+#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \\r
+       vTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (uint32_t)eg, bitsToClear);\r
+\r
+#undef traceEVENT_GROUP_SET_BITS\r
+#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \\r
+       vTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS, (uint32_t)eg, bitsToSet);\r
+\r
+#undef traceEVENT_GROUP_SET_BITS_FROM_ISR\r
+#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \\r
+       vTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (uint32_t)eg, bitsToSet);\r
+\r
+#undef traceTASK_NOTIFY_TAKE\r
+#define traceTASK_NOTIFY_TAKE() \\r
+       if (pxCurrentTCB->eNotifyState == eNotified) \\r
+               vTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \\r
+       else \\r
+               vTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);\r
+\r
+#undef traceTASK_NOTIFY_TAKE_BLOCK\r
+#define traceTASK_NOTIFY_TAKE_BLOCK() \\r
+       vTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);\r
+\r
+#undef traceTASK_NOTIFY_WAIT\r
+#define traceTASK_NOTIFY_WAIT() \\r
+       if (pxCurrentTCB->eNotifyState == eNotified) \\r
+               vTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \\r
+       else \\r
+               vTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);\r
+\r
+#undef traceTASK_NOTIFY_WAIT_BLOCK\r
+#define traceTASK_NOTIFY_WAIT_BLOCK() \\r
+       vTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);\r
+\r
+#undef traceTASK_NOTIFY\r
+#define traceTASK_NOTIFY() \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify);\r
+\r
+#undef traceTASK_NOTIFY_FROM_ISR\r
+#define traceTASK_NOTIFY_FROM_ISR() \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify);\r
+       \r
+#undef traceTASK_NOTIFY_GIVE_FROM_ISR\r
+#define traceTASK_NOTIFY_GIVE_FROM_ISR() \\r
+       vTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify);\r
+\r
+/************************************************************************/\r
+/* KERNEL SPECIFIC MACROS TO NAME OBJECTS, IF NECESSARY                                 */\r
+/************************************************************************/\r
+#define vTraceSetQueueName(object, name) \\r
+vTraceStoreKernelObjectName(object, name);\r
+\r
+#define vTraceSetSemaphoreName(object, name) \\r
+vTraceStoreKernelObjectName(object, name);\r
+\r
+#define vTraceSetMutexName(object, name) \\r
+vTraceStoreKernelObjectName(object, name);\r
+\r
+#define vTraceSetEventGroupName(object, name) \\r
+vTraceStoreKernelObjectName(object, name);\r
+\r
+#else /*(USE_TRACEALYZER_RECORDER == 1)*/\r
+\r
+#define vTraceSetQueueName(object, name)\r
+\r
+#define vTraceSetSemaphoreName(object, name)\r
+\r
+#define vTraceSetMutexName(object, name)\r
+\r
+#define vTraceSetEventGroupName(object, name)\r
+\r
+#define Trace_Init() \r
+\r
+#endif /*(USE_TRACEALYZER_RECORDER == 1)*/\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* TRC_KERNEL_PORT_H */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBuffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBuffer.c
new file mode 100644 (file)
index 0000000..c15dee4
--- /dev/null
@@ -0,0 +1,302 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcPagedEventBuffer.c\r
+ *\r
+ * Implements a paged buffer that can be used by TCP/IP or custom transfer\r
+ * methods.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#include <stdio.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+#include "trcConfig.h"\r
+#include "trcPagedEventBuffer.h"\r
+#include "trcPagedEventBufferConfig.h"\r
+#include "trcKernelPort.h"\r
+\r
+uint32_t DroppedEventCounter = 0;      // Total number of dropped events (failed allocations)\r
+uint32_t TotalBytesRemaining_LowWaterMark = TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;\r
+\r
+#if (USE_TRACEALYZER_RECORDER == 1)\r
+\r
+#define PAGE_STATUS_FREE 0\r
+#define PAGE_STATUS_WRITE 1\r
+#define PAGE_STATUS_READ 2\r
+\r
+uint32_t TotalBytesRemaining = TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;\r
+\r
+typedef struct{\r
+       uint8_t Status;\r
+       uint16_t BytesRemaining;\r
+       char* WritePointer;\r
+} PageType;\r
+\r
+PageType PageInfo[TRC_PAGED_EVENT_BUFFER_PAGE_COUNT];\r
+\r
+char* EventBuffer = NULL;\r
+\r
+static void prvPageReadComplete(int pageIndex);\r
+static int prvAllocateBufferPage(int prevPage);\r
+\r
+static int prvAllocateBufferPage(int prevPage)\r
+{\r
+       int index;\r
+       int count = 0;\r
+\r
+       index = (prevPage + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;\r
+\r
+       while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < TRC_PAGED_EVENT_BUFFER_PAGE_COUNT))\r
+       {\r
+               index = (index + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;\r
+       }\r
+\r
+       if (PageInfo[index].Status == PAGE_STATUS_FREE)\r
+       {\r
+               return index;\r
+       }\r
+\r
+       return -1;\r
+}\r
+\r
+static void prvPageReadComplete(int pageIndex)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+       PageInfo[pageIndex].BytesRemaining = TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;\r
+       PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE];\r
+       PageInfo[pageIndex].Status = PAGE_STATUS_FREE;\r
+\r
+       TotalBytesRemaining += TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;\r
+\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+static int prvGetBufferPage(int32_t* bytesUsed)\r
+{\r
+       static int8_t lastPage = -1;\r
+       int count = 0;\r
+       int8_t index = (lastPage + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;\r
+\r
+       while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < TRC_PAGED_EVENT_BUFFER_PAGE_COUNT))\r
+       {\r
+               index = (index + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;\r
+       }\r
+\r
+       if (PageInfo[index].Status == PAGE_STATUS_READ)\r
+       {\r
+               *bytesUsed = TRC_PAGED_EVENT_BUFFER_PAGE_SIZE - PageInfo[index].BytesRemaining;\r
+               lastPage = index;\r
+               return index;\r
+       }\r
+\r
+       *bytesUsed = 0;\r
+\r
+       return -1;\r
+}\r
+\r
+/*******************************************************************************\r
+\r
+int32_t vPagedEventBufferTransfer(int32_t (*writeFunc)(void* data,\r
+                                                        uint32_t size),\r
+                                            int32_t* nofBytes)\r
+\r
+Transfers one block of trace data, if available for reading. Returns the number\r
+of bytes transfered, or a negative error code. If data was transferred (return\r
+value > 0), it can be good to call this function again until all data available\r
+has been transfered.\r
+\r
+This function is intended to be called by a periodic task with a suitable\r
+delay (e.g. 10-100 ms).\r
+\r
+Example:\r
+\r
+       TickType_t lastWakeTime = xTaskGetTickCount();\r
+\r
+       while(1)\r
+       {\r
+\r
+               do{\r
+                       // Transfer all available data\r
+                       status = vPagedEventBufferTransfer(MyWrite, ptrBytes);\r
+               }while(status > 0);\r
+\r
+               if (status < 0)\r
+               {\r
+                       // A negative return value is an error code...\r
+               }\r
+\r
+               vTraceDelayUntil(lastWakeTime, 50); // 50 ms -> 20 times/sec\r
+       }\r
+\r
+Return value: returnvalue of writeFunc (0 == OK)\r
+\r
+Parameters:\r
+\r
+- writeFunc\r
+Function pointer (example: int32_t write(void* data, uint32_t size))\r
+The function passed as writeFunc should write "size" bytes from "data" to the\r
+socket/file/channel, and return a status code where 0 means OK,\r
+and any other non-zero value means an error.\r
+\r
+- int32_t* nofBytes\r
+Pointer to an integer assigned the number of bytes that was transfered.\r
+\r
+*******************************************************************************/\r
+\r
+int32_t vPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes)\r
+{\r
+       static int firstTime = 1;\r
+       int8_t pageToTransfer = -1;\r
+\r
+       pageToTransfer = prvGetBufferPage(nofBytes);\r
+\r
+       if (firstTime)\r
+       {\r
+               firstTime = 0;\r
+       }\r
+\r
+       if (pageToTransfer > -1)\r
+       {\r
+               if (writeFunc(&EventBuffer[pageToTransfer * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE], *nofBytes, nofBytes) == 0)\r
+               {\r
+                       prvPageReadComplete(pageToTransfer);\r
+            \r
+            return 0;\r
+               }\r
+        else\r
+        {\r
+            return 1;\r
+        }\r
+       }\r
+       return 0;\r
+}\r
+\r
+/*******************************************************************************\r
+\r
+void* vPagedEventBufferGetWritePointer(int sizeOfEvent)\r
+\r
+Returns a pointer to an available location in the buffer able to store the\r
+requested size.\r
+\r
+Return value: The pointer.\r
+\r
+Parameters:\r
+\r
+- sizeOfEvent\r
+The size of the event that is to be placed in the buffer.\r
+\r
+*******************************************************************************/\r
+void* vPagedEventBufferGetWritePointer(int sizeOfEvent)\r
+{\r
+       void* ret;\r
+       static int currentWritePage = -1;\r
+\r
+       if (currentWritePage == -1)\r
+       {\r
+           currentWritePage = prvAllocateBufferPage(currentWritePage);\r
+               if (currentWritePage == -1)\r
+               {\r
+                       DroppedEventCounter++;\r
+                       return NULL;\r
+               }\r
+       }\r
+\r
+    if (PageInfo[currentWritePage].BytesRemaining - sizeOfEvent < 0)\r
+       {\r
+               PageInfo[currentWritePage].Status = PAGE_STATUS_READ;\r
+\r
+               TotalBytesRemaining -= PageInfo[currentWritePage].BytesRemaining; // Last trailing bytes\r
+\r
+               if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)\r
+                 TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;\r
+\r
+               currentWritePage = prvAllocateBufferPage(currentWritePage);\r
+               if (currentWritePage == -1)\r
+               {\r
+                 DroppedEventCounter++;\r
+                 return NULL;\r
+               }\r
+       }\r
+       ret = PageInfo[currentWritePage].WritePointer;\r
+       PageInfo[currentWritePage].WritePointer += sizeOfEvent;\r
+       PageInfo[currentWritePage].BytesRemaining -= sizeOfEvent;\r
+\r
+       TotalBytesRemaining -= sizeOfEvent;\r
+\r
+       if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)\r
+               TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;\r
+\r
+       return ret;\r
+}\r
+\r
+/*******************************************************************************\r
+\r
+void vPagedEventBufferInit(char* buffer)\r
+\r
+Assigns the buffer to use and initializes the PageInfo structure.\r
+\r
+Return value: void\r
+\r
+Parameters:\r
+\r
+- buffer\r
+Pointer to the buffer location that is dynamically or statically allocated by\r
+the caller.\r
+\r
+*******************************************************************************/\r
+void vPagedEventBufferInit(char* buffer)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+       int i;\r
+    \r
+    EventBuffer = buffer;\r
+    \r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+       for (i = 0; i < TRC_PAGED_EVENT_BUFFER_PAGE_COUNT; i++)\r
+       {\r
+               PageInfo[i].BytesRemaining = TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;\r
+               PageInfo[i].WritePointer = &EventBuffer[i * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE];\r
+               PageInfo[i].Status = PAGE_STATUS_FREE;\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBuffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBuffer.h
new file mode 100644 (file)
index 0000000..be4a754
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcPagedEventBuffer.h\r
+ *\r
+ * Implements a paged buffer that can be used by TCP/IP or custom transfer\r
+ * methods.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef TRC_PAGED_EVENT_BUFFER_H\r
+#define TRC_PAGED_EVENT_BUFFER_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+void vPagedEventBufferInit(char* buffer);\r
+\r
+void* vPagedEventBufferGetWritePointer(int sizeOfEvent);\r
+\r
+int32_t vPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes);\r
+\r
+void vPagedEventBufferReset(void);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*TRC_PAGED_EVENT_BUFFER_H*/
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBufferConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcPagedEventBufferConfig.h
new file mode 100644 (file)
index 0000000..f50652a
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcPagedEventBuffer.h\r
+ *\r
+ * Configuration for the paged event buffer that can be used by TCP/IP or \r
+ * custom transfer methods.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef TRC_PAGED_EVENT_BUFFER_CONFIG_H\r
+#define TRC_PAGED_EVENT_BUFFER_CONFIG_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+#define TRC_PAGED_EVENT_BUFFER_PAGE_COUNT 5\r
+#define TRC_PAGED_EVENT_BUFFER_PAGE_SIZE 1440\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*TRC_PAGED_EVENT_BUFFER_CONFIG_H*/
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcRecorder.c
new file mode 100644 (file)
index 0000000..4768176
--- /dev/null
@@ -0,0 +1,1126 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcRecorder.c\r
+ *\r
+ * The trace recorder core functions (portable).\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#include <stdarg.h>\r
+#include <stdint.h>\r
+\r
+#include "trcRecorder.h"\r
+#include "trcStreamPort.h"\r
+\r
+#if (USE_TRACEALYZER_RECORDER == 1)\r
+\r
+uint32_t uiTraceTickCount = 0;\r
+\r
+typedef struct{\r
+       int16_t EventID;\r
+       uint16_t EventCount;\r
+       uint32_t TS;\r
+} BaseEvent;\r
+\r
+typedef struct{\r
+  BaseEvent base;\r
+  uint32_t param1;\r
+} EventWithParam_1;\r
+\r
+typedef struct{\r
+  BaseEvent base;\r
+  uint32_t param1;\r
+  uint32_t param2;\r
+} EventWithParam_2;\r
+\r
+typedef struct{\r
+  BaseEvent base;\r
+  uint32_t param1;\r
+  uint32_t param2;\r
+  uint32_t param3;\r
+} EventWithParam_3;\r
+\r
+/* Used in event functions with variable number of parameters. */\r
+typedef struct\r
+{\r
+  BaseEvent base;\r
+  char data[60]; /* maximum payload size */\r
+} largestEventType;\r
+\r
+typedef struct{\r
+  uint32_t psf;\r
+  uint16_t version;\r
+  uint16_t platform;\r
+  uint32_t options;\r
+  uint16_t symbolSize;\r
+  uint16_t symbolCount;\r
+  uint16_t objectDataSize;\r
+  uint16_t objectDataCount;\r
+} PSFHeaderInfo;\r
+\r
+/* The size of each slot in the Symbol Table */\r
+#define SYMBOL_TABLE_SLOT_SIZE (sizeof(uint32_t) + (((TRC_SYMBOL_MAX_LENGTH)+(sizeof(uint32_t)-1))/sizeof(uint32_t))*sizeof(uint32_t))\r
+\r
+#define OBJECT_DATA_SLOT_SIZE (sizeof(uint32_t) + sizeof(uint32_t))\r
+\r
+/* The total size of the Symbol Table */\r
+#define SYMBOL_TABLE_BUFFER_SIZE (TRC_SYMBOL_TABLE_SLOTS * SYMBOL_TABLE_SLOT_SIZE)\r
+\r
+/* The total size of the Object Data Table */\r
+#define OBJECT_DATA_TABLE_BUFFER_SIZE (TRC_OBJECT_DATA_SLOTS * OBJECT_DATA_SLOT_SIZE)\r
+\r
+/* The Symbol Table type - just a byte array */\r
+typedef struct{\r
+  uint8_t pSymbolTableBuffer[SYMBOL_TABLE_BUFFER_SIZE];\r
+} SymbolTable;\r
+\r
+/* The Object Data Table type - just a byte array */\r
+typedef struct{\r
+  uint8_t pObjectDataTableBuffer[OBJECT_DATA_TABLE_BUFFER_SIZE];\r
+} ObjectDataTable;\r
+\r
+/* The Symbol Table instance - keeps names of tasks and other named objects. */\r
+static SymbolTable symbolTable = { { 0 } };\r
+\r
+/* The Object Data Table instance - keeps initial priorities of tasks. */\r
+static ObjectDataTable objectDataTable = { { 0 } };\r
+\r
+/* Code used for "task address" when no task has started. (NULL = idle task) */\r
+#define HANDLE_NO_TASK 2\r
+\r
+/* The maximum number of nested ISRs */\r
+#define MAX_ISR_NESTING 8\r
+\r
+/* Keeps track of ISR nesting */\r
+static uint32_t ISR_stack[MAX_ISR_NESTING];\r
+\r
+/* Keeps track of ISR nesting */\r
+static int8_t ISR_stack_index = -1;\r
+\r
+/* Any error that occured in the recorder (also creates User Event) */\r
+static int errorCode = 0;\r
+\r
+/* The user event channel for recorder warnings, defined in trcKernelPort.c */\r
+extern char* trcWarningChannel;\r
+\r
+/* Performs timestamping using definitions in trcHardwarePort.h */\r
+static uint32_t prvGetTimestamp32(void);\r
+\r
+/* Counts the number of trace sessions (not yet used) */\r
+static uint32_t SessionCounter = 0;\r
+\r
+/* Master switch for recording (0 => Disabled, 1 => Enabled) */\r
+static uint32_t RecorderEnabled = 0;\r
+\r
+/* Used to determine endian of data (big/little) */\r
+static uint32_t PSFEndianessIdentifier = 0x50534600;\r
+\r
+/* Used to interpret the data format */\r
+static uint16_t FormatVersion = 0x0002;\r
+\r
+/* The number of events stored. Used as event sequence number. */\r
+static uint32_t eventCounter = 0;\r
+\r
+/* Keeps track of if the current ISR chain has triggered a context switch that will be performed once all ISRs have returned. */\r
+int32_t isPendingContextSwitch = 0;\r
+\r
+/*******************************************************************************\r
+ * NoRoomForSymbol\r
+ *\r
+ * Incremented on vTraceSaveSymbol if no room for saving the symbol name. This\r
+ * is used for storing the names of:\r
+ * - Tasks\r
+ * - Named ISRs (vTraceSetISRProperties)\r
+ * - Named kernel objects (vTraceStoreKernelObjectName)\r
+ * - User event channels (vTraceStoreUserEventChannelName)\r
+ *\r
+ * This variable should be zero. If not, it shows the number of missing slots so\r
+ * far. In that case, increment SYMBOL_TABLE_SLOTS with (at least) this value.\r
+ ******************************************************************************/\r
+volatile uint32_t NoRoomForSymbol = 0;\r
+\r
+/*******************************************************************************\r
+ * NoRoomForObjectData\r
+ *\r
+ * Incremented on vTraceSaveObjectData if no room for saving the object data,\r
+ * i.e., the base priorities of tasks. There must be one slot for each task.\r
+ * If not, this variable will show the difference.\r
+ *\r
+ * This variable should be zero. If not, it shows the number of missing slots so\r
+ * far. In that case, increment OBJECT_DATA_SLOTS with (at least) this value.\r
+ ******************************************************************************/\r
+volatile uint32_t NoRoomForObjectData = 0;\r
+\r
+/*******************************************************************************\r
+ * LongestSymbolName\r
+ *\r
+ * Updated in vTraceSaveSymbol. Should not exceed SYMBOL_MAX_LENGTH, otherwise\r
+ * symbol names will be truncated. In that case, set SYMBOL_MAX_LENGTH to (at\r
+ * least) this value.\r
+ ******************************************************************************/\r
+volatile uint32_t LongestSymbolName = 0;\r
+\r
+/*******************************************************************************\r
+ * MaxBytesTruncated\r
+ *\r
+ * Set in prvTraceStoreStringEvent if the total data payload exceeds 60 bytes,\r
+ * including data arguments and the string. For user events, that is 52 bytes\r
+ * for string and data arguments. In that is exceeded, the event is  truncated\r
+ * (usually only the string, unless more than 15 parameters) and this variable\r
+ * holds the maximum number of truncated bytes, from any event.\r
+ ******************************************************************************/\r
+volatile uint32_t MaxBytesTruncated = 0;\r
+\r
+/* Internal common function for storing string events */\r
+static void prvTraceStoreStringEvent(  int nArgs,\r
+                                                                               uint16_t eventID,\r
+                                                                               const char* userEvtChannel,\r
+                                                                               const char* str,\r
+                                                                               va_list vl);\r
+\r
+/* Stores the header information on Start */\r
+static void vTraceStoreHeader(void);\r
+\r
+/* Stores the symbol table on Start */\r
+static void vTraceStoreSymbolTable(void);\r
+\r
+/* Stores the object table on Start */\r
+static void vTraceStoreObjectDataTable(void);\r
+\r
+/* Store the Timestamp Config on Start */\r
+static void vTraceStoreTSConfig(void);\r
+\r
+/* Internal function for starting/stopping the recorder. */\r
+static void intSetRecorderEnabled(int isEnabled);\r
+\r
+/* Command codes for TzCtrl task (sent on Start/Stop). */\r
+#define CMD_SET_ACTIVE 1\r
+\r
+/* The final command code, used to validate commands. Only one command yet. */\r
+#define CMD_LAST_COMMAND 1\r
+\r
+/* Part of the PSF format - encodes the number of 32-bit params in an event */\r
+#define PARAM_COUNT(n) ((n & 0xF) << 12)\r
+\r
+/* Temporary fix since embOS sources aren't yet updated to contain them */\r
+#ifndef OS_TRACE_ID_IFE\r
+#define OS_TRACE_ID_IFE (4000u)\r
+#endif\r
+\r
+#ifndef OS_TRACE_ID_IFE_NEXT\r
+#define OS_TRACE_ID_IFE_NEXT (4001u)\r
+#endif\r
+\r
+/******************************************************************************\r
+ * vTraceInstanceFinishNow\r
+ *\r
+ * Creates an event that ends the current task instance at this very instant.\r
+ * This makes the viewer to splits the current fragment at this point and begin\r
+ * a new actor instance, even if no task-switch has occurred.\r
+ *****************************************************************************/\r
+void vTraceInstanceFinishedNow(void)\r
+{\r
+       vTraceStoreEvent0(PSF_EVENT_IFE_DIRECT);\r
+}\r
+\r
+/******************************************************************************\r
+ * vTraceInstanceFinishedNext\r
+ *\r
+ * Marks the current "task instance" as finished on the next kernel call.\r
+ *\r
+ * If that kernel call is blocking, the instance ends after the blocking event\r
+ * and the corresponding return event is then the start of the next instance.\r
+ * If the kernel call is not blocking, the viewer instead splits the current\r
+ * fragment right before the kernel call, which makes this call the first event\r
+ * of the next instance.\r
+ *****************************************************************************/\r
+void vTraceInstanceFinishedNext(void)\r
+{\r
+       vTraceStoreEvent0(PSF_EVENT_IFE_NEXT);\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreUserEventChannelName\r
+ *\r
+ * Stores a name for a user event channel, returns the handle (just a pointer\r
+ * to the const char*.\r
+ * The returned channel handle\r
+ ******************************************************************************/\r
+char* vTraceStoreUserEventChannelName(const char* name)\r
+{\r
+    vTraceSaveSymbol((void*)name, name);\r
+\r
+       /* Always save in symbol table, if the recording has not yet started */\r
+       vTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, (uint32_t)name);\r
+\r
+       return (char*)name;\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreKernelObjectName\r
+ *\r
+ * Stores a name for kernel objects (Semaphore, Mailbox, etc.).\r
+ ******************************************************************************/\r
+void vTraceStoreKernelObjectName(void* object, const char* name)\r
+{\r
+    vTraceSaveSymbol(object, name);\r
+\r
+       /* Always save in symbol table, if the recording has not yet started */\r
+       vTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, (uint32_t)object);\r
+}\r
+\r
+/******************************************************************************\r
+ * vTracePrint\r
+ *\r
+ * Generates "User Events", with unformatted text.\r
+ *\r
+ * User Events can be used for very efficient application logging, and are shown\r
+ * as yellow labels in the main trace view.\r
+ *\r
+ * You may group User Events into User Event Channels. The yellow User Event \r
+ * labels shows the logged string, preceeded by the channel  name within \r
+ * brackets. For example:\r
+ *\r
+ *  "[MyChannel] Hello World!"\r
+ *\r
+ * The User Event Channels are shown in the View Filter, which makes it easy to\r
+ * select what User Events you wish to display. User Event Channels are created\r
+ * using vTraceStoreUserEventChannelName().\r
+ *\r
+ * Example:\r
+ *\r
+ *      char* error_uechannel = vTraceStoreUserEventChannelName("Errors");\r
+ *      ...\r
+ *      vTracePrint(error_uechannel, "Shouldn't reach this code!");\r
+ *\r
+ ******************************************************************************/\r
+void vTracePrint(const char* chn, const char* str)\r
+{\r
+  va_list vl = { 0 };\r
+  \r
+  if (chn != NULL)\r
+  {\r
+    prvTraceStoreStringEvent(0, PSF_EVENT_USER_EVENT + 1, chn, str, vl);\r
+  }\r
+  else\r
+  {\r
+    prvTraceStoreStringEvent(0, PSF_EVENT_USER_EVENT, chn, str, vl);\r
+  }\r
+}\r
+\r
+/******************************************************************************\r
+ * vTracePrintF\r
+ *\r
+ * Generates "User Events", with formatted text and data, similar to a "printf".\r
+ * It is very fast since the actual formatting is done on the host side when the\r
+ * trace is displayed.\r
+ *\r
+ * User Events can be used for very efficient application logging, and are shown\r
+ * as yellow labels in the main trace view.\r
+ * An advantage of User Events is that data can be plotted in the "User Event\r
+ * Signal Plot" view, visualizing any data you log as User Events, discrete\r
+ * states or control system signals (e.g. system inputs or outputs).\r
+ *\r
+ * You may group User Events into User Event Channels. The yellow User Event \r
+ * labels show the logged string, preceeded by the channel name within brackets.\r
+ * \r
+ * Example:\r
+ *\r
+ *  "[MyChannel] Hello World!"\r
+ *\r
+ * The User Event Channels are shown in the View Filter, which makes it easy to\r
+ * select what User Events you wish to display. User Event Channels are created\r
+ * using vTraceStoreUserEventChannelName().\r
+ *\r
+ * Example:\r
+ *\r
+ *      char* adc_uechannel = vTraceStoreUserEventChannelName("ADC User Events");\r
+ *      ...\r
+ *      vTracePrint(adc_uechannel,\r
+ *                              "ADC channel %d: %lf volts",\r
+ *                              ch, (double)adc_reading/(double)scale);\r
+ *\r
+ * All data arguments are assumed to be 32 bt wide. The following formats are\r
+ * supported in v2.8:\r
+ * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> "  -42"\r
+ * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> "   42"\r
+ * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> "  2A"\r
+ * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> "  2a"\r
+ * %s - string (currently, this must be an earlier stored symbol name)\r
+ *\r
+ * Up to 15 data arguments are allowed, with a total size of maximum 60 byte\r
+ * including 8 byte for the base event fields and the format string. So with\r
+ * one data argument, the maximum string length is 48 chars. If this is exceeded\r
+ * the string is truncated (4 bytes at a time).\r
+ *\r
+ ******************************************************************************/\r
+void vTracePrintF(const char* chn, const char* fmt, ...)\r
+{\r
+  int i = 0;\r
+  va_list vl;\r
+\r
+  int nArgs = 0;\r
+\r
+  int len = 0;\r
+  for (len = 0; fmt[len] != 0; len++)\r
+  {\r
+         // Empty\r
+  }\r
+  if (len > 52)\r
+    len = 52;\r
+  \r
+  while (i < len)\r
+  {\r
+    if (fmt[i] == '%')\r
+    {\r
+      if (fmt[i+1] != '%')\r
+        nArgs++;        /* Found an argument */\r
+      \r
+      i++;      /* Move past format specifier or non-argument '%' */\r
+    }\r
+    \r
+    i++;\r
+  }\r
+\r
+  va_start(vl, fmt);\r
+  if (chn != NULL)\r
+  {\r
+    prvTraceStoreStringEvent(nArgs, PSF_EVENT_USER_EVENT + nArgs + 1, chn, fmt, vl);\r
+  }\r
+  else\r
+  {\r
+    prvTraceStoreStringEvent(nArgs, PSF_EVENT_USER_EVENT + nArgs, chn, fmt, vl);\r
+  }\r
+  va_end(vl);\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceSetISRProperties\r
+ *\r
+ * Stores a name and priority level for an Interrupt Service Routine, to allow\r
+ * for better visualization. The string address is used as a unique handle.\r
+ *\r
+ * Example:\r
+ *      #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt\r
+ *      ...\r
+ *      vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREnd(0);\r
+ *      }\r
+ *\r
+ ******************************************************************************/\r
+void vTraceSetISRProperties(const char* name, char priority)\r
+{\r
+       /* Save object data in object data table */\r
+       vTraceSaveObjectData((void*)name, priority);\r
+        \r
+       /* Note: "name" is used both as a string argument, and the address as ID */\r
+       vTraceStoreStringEvent(2, PSF_EVENT_DEFINE_ISR, name, name, priority);\r
+        \r
+       /* Always save in symbol table, if the recording has not yet started */\r
+       vTraceSaveSymbol((void*)name, name);\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreISRBegin\r
+ *\r
+ * Registers the beginning of an Interrupt Service Routine.\r
+ *\r
+ * Example:\r
+ *      #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt\r
+ *      ...\r
+ *      vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREnd(0);\r
+ *      }\r
+ *\r
+ ******************************************************************************/\r
+void vTraceStoreISRBegin(void* handle)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (ISR_stack_index == -1)\r
+               isPendingContextSwitch = 0; /* We are at the start of a possible ISR chain. No context switches should have been triggered now. */\r
+\r
+       if (ISR_stack_index < MAX_ISR_NESTING - 1)\r
+       {\r
+               ISR_stack_index++;\r
+               ISR_stack[ISR_stack_index] = (uint32_t)handle;\r
+               vTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle);\r
+               TRACE_EXIT_CRITICAL_SECTION();\r
+       }\r
+       else\r
+       {\r
+               TRACE_EXIT_CRITICAL_SECTION();\r
+               psfError(PSF_ERROR_ISR_NESTING_OVERFLOW);\r
+       }\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreISREnd\r
+ *\r
+ * Registers the end of an Interrupt Service Routine.\r
+ *\r
+ * This function will automatically detect if a task switch will take place \r
+ * when interrupt ends. If this is possible depends on the kernel port.\r
+ *\r
+ * Example:\r
+ *      #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt\r
+ *      ...\r
+ *      vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREnd();\r
+ *      }\r
+ *\r
+ ******************************************************************************/\r
+void vTraceStoreISREnd()\r
+{\r
+       vTraceStoreISREndManual(OS_IS_SWITCH_FROM_INT_REQUIRED());\r
+}\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreISREndManual\r
+ *\r
+ * Registers the end of an Interrupt Service Routine.\r
+ *\r
+ * The parameter taskSwitchRequested indicates if the interrupt has requested a\r
+ * task-switch (= 1) or if the interrupt returns to the earlier context (= 0)\r
+ *\r
+ * Example:\r
+ *      #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt\r
+ *      ...\r
+ *      vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREndManual(0);\r
+ *      }\r
+ *\r
+ ******************************************************************************/\r
+void vTraceStoreISREndManual(int isTaskSwitchRequired)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       isPendingContextSwitch |= isTaskSwitchRequired; /* Is there a pending context switch right now? */\r
+       if (ISR_stack_index > 0)\r
+       {\r
+               ISR_stack_index--;\r
+\r
+               /* Store return to interrupted ISR (if nested ISRs)*/\r
+               vTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]);\r
+       }\r
+       else\r
+       {\r
+               ISR_stack_index--;\r
+               \r
+               /* Store return to interrupted task, if a task switch has not been triggered by any interrupt */\r
+               if (isPendingContextSwitch == 0)\r
+               {\r
+                       vTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK());\r
+               }\r
+       }\r
+\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+\r
+/******************************************************************************/\r
+/*** INTERNAL FUNCTIONS *******************************************************/\r
+/******************************************************************************/\r
+\r
+/* Internal function for starting/stopping the recorder. */\r
+static void intSetRecorderEnabled(int isEnabled)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       void* currentTask = TRACE_GET_CURRENT_TASK();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+    RecorderEnabled = isEnabled;\r
+\r
+    if (currentTask == NULL)\r
+    {\r
+               currentTask = (void*)HANDLE_NO_TASK;\r
+       }\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+        vTraceOnTraceBegin();\r
+        \r
+       eventCounter = 0;\r
+        ISR_stack_index = -1;\r
+        vTraceStoreHeader();\r
+               vTraceStoreSymbolTable();\r
+       vTraceStoreObjectDataTable();\r
+        vTraceStoreEvent3(     PSF_EVENT_TRACE_START,\r
+                                                       (uint32_t)TRACE_GET_OS_TICKS(),\r
+                                                       (uint32_t)currentTask,\r
+                                                       SessionCounter++);\r
+        vTraceStoreTSConfig();\r
+       }\r
+    else\r
+    {\r
+        vTraceOnTraceEnd();\r
+    }\r
+\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Stores the symbol table on Start */\r
+static void vTraceStoreSymbolTable()\r
+{\r
+       uint32_t i = 0;\r
+        uint32_t j = 0;\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               for (i = 0; i < sizeof(SymbolTable); i += SYMBOL_TABLE_SLOT_SIZE)\r
+               {\r
+            TRC_STREAM_PORT_ALLOCATE_EVENT(uint8_t, data, SYMBOL_TABLE_SLOT_SIZE);\r
+            for (j = 0; j < SYMBOL_TABLE_SLOT_SIZE; j++)\r
+            {\r
+                    data[j] = symbolTable.pSymbolTableBuffer[i+j];\r
+            }\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(data, SYMBOL_TABLE_SLOT_SIZE);\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Stores the object table on Start */\r
+static void vTraceStoreObjectDataTable()\r
+{\r
+       uint32_t i = 0;\r
+        uint32_t j = 0;\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               for (i = 0; i < sizeof(ObjectDataTable); i += OBJECT_DATA_SLOT_SIZE)\r
+        {\r
+            TRC_STREAM_PORT_ALLOCATE_EVENT(uint8_t, data, OBJECT_DATA_SLOT_SIZE);\r
+            for (j = 0; j < OBJECT_DATA_SLOT_SIZE; j++)\r
+            {\r
+                    data[j] = objectDataTable.pObjectDataTableBuffer[i+j];\r
+            }\r
+            TRC_STREAM_PORT_COMMIT_EVENT(data, OBJECT_DATA_SLOT_SIZE);\r
+        }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Stores the header information on Start */\r
+static void vTraceStoreHeader()\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(PSFHeaderInfo, header, sizeof(PSFHeaderInfo));\r
+               if (header != NULL)\r
+               {\r
+                       header->psf = PSFEndianessIdentifier;\r
+                       header->version = FormatVersion;\r
+                       header->platform = KERNEL_ID;\r
+            header->options = 0;\r
+            /* Lowest bit used for IRQ_PRIORITY_ORDER */\r
+            header->options = header->options | (IRQ_PRIORITY_ORDER << 0);\r
+                       header->symbolSize = SYMBOL_TABLE_SLOT_SIZE;\r
+                       header->symbolCount = TRC_SYMBOL_TABLE_SLOTS;\r
+                       header->objectDataSize = 8;\r
+                       header->objectDataCount = TRC_OBJECT_DATA_SLOTS;\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(header, sizeof(PSFHeaderInfo));\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Store an event with zero parameters (event ID only) */\r
+void vTraceStoreEvent0(uint16_t eventID)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               eventCounter++;\r
+\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(BaseEvent, event, sizeof(BaseEvent));\r
+               if (event != NULL)\r
+               {\r
+                       event->EventID = eventID | PARAM_COUNT(0);\r
+                       event->EventCount = eventCounter;\r
+                       event->TS = prvGetTimestamp32();\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(BaseEvent));\r
+               }\r
+\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Store an event with one 32-bit parameter (pointer address or an int) */\r
+void vTraceStoreEvent1(uint16_t eventID, uint32_t param1)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               eventCounter++;\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_1, event, sizeof(EventWithParam_1));\r
+               if (event != NULL)\r
+               {\r
+                       event->base.EventID = eventID | PARAM_COUNT(1);\r
+                       event->base.EventCount = eventCounter;\r
+                       event->base.TS = prvGetTimestamp32();\r
+                       event->param1 = (uint32_t)param1;\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_1));\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Store an event with two 32-bit parameters */\r
+void vTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               eventCounter++;\r
+\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_2, event, sizeof(EventWithParam_2));\r
+               if (event != NULL)\r
+               {\r
+                       event->base.EventID = eventID | PARAM_COUNT(2);\r
+                       event->base.EventCount = eventCounter;\r
+                       event->base.TS = prvGetTimestamp32();\r
+                       event->param1 = (uint32_t)param1;\r
+                       event->param2 = param2;\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_2));\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Store an event with three 32-bit parameters */\r
+void vTraceStoreEvent3(        uint16_t eventID,\r
+                                               uint32_t param1,\r
+                                               uint32_t param2,\r
+                                               uint32_t param3)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+\r
+       PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               eventCounter++;\r
+\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_3, event, sizeof(EventWithParam_3));\r
+               if (event != NULL)\r
+               {\r
+                       event->base.EventID = eventID | PARAM_COUNT(3);\r
+                       event->base.EventCount = eventCounter;\r
+                       event->base.TS = prvGetTimestamp32();\r
+                       event->param1 = (uint32_t)param1;\r
+                       event->param2 = param2;\r
+                       event->param3 = param3;\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_3));\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Stores an event with <nParam> 32-bit integer parameters */\r
+void vTraceStoreEvent(int nParam, uint16_t eventID, ...)\r
+{\r
+    TRACE_ALLOC_CRITICAL_SECTION();\r
+       va_list vl;\r
+       int i;\r
+\r
+       PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               int eventSize = sizeof(BaseEvent) + nParam * sizeof(uint32_t);\r
+\r
+               eventCounter++;\r
+\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(largestEventType, event, eventSize);\r
+               if (event != NULL)\r
+               {\r
+                       event->base.EventID = eventID | PARAM_COUNT(nParam);\r
+                       event->base.EventCount = eventCounter;\r
+                       event->base.TS = prvGetTimestamp32();\r
+\r
+                       va_start(vl, eventID);\r
+                       for (i = 0; i < nParam; i++)\r
+                       {\r
+                               uint32_t* tmp = (uint32_t*) &(event->data[i * 4]);\r
+                               *tmp = va_arg(vl, uint32_t);\r
+                       }\r
+                       va_end(vl);\r
+\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(event, eventSize);\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Stories an event with a string and <nParam> 32-bit integer parameters */\r
+void vTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...)\r
+{\r
+       va_list vl;\r
+\r
+       va_start(vl, str);\r
+       prvTraceStoreStringEvent(nArgs, eventID, NULL, str, vl);\r
+       va_end(vl);\r
+}\r
+\r
+/* Internal common function for storing string events */\r
+static void prvTraceStoreStringEvent(  int nArgs,\r
+                                                                               uint16_t eventID,\r
+                                                                               const char* userEvtChannel,\r
+                                                                               const char* str, va_list vl)\r
+{\r
+       TRACE_ALLOC_CRITICAL_SECTION();\r
+       int len;\r
+       int nParam;\r
+       int strParam;\r
+       int i;\r
+\r
+       PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);\r
+\r
+       len = 0;\r
+       for (len = 0; str[len] != 0; len++)\r
+       {\r
+               // Empty\r
+       }\r
+  \r
+       /* The string length in multiples of 32 bit words (+1 for null character) */\r
+       strParam = (len+1+3)/4;\r
+\r
+       /* If a user event channel is specified, add in the list */\r
+       if (userEvtChannel) nArgs++;\r
+\r
+       /* The total number of 32-bit words needed for the whole payload */\r
+       nParam = strParam + nArgs;\r
+\r
+       if (nParam > 15) /* if attempting to store more than 60 byte (= max) */\r
+       {\r
+               /* Truncate event if too large. The     string characters are stored\r
+               last, so usually only the string is truncated, unless there a lot\r
+               of parameters... */\r
+\r
+               /* Diagnostics ... */\r
+               uint32_t bytesTrucated = (nParam - 15) * 4;\r
+\r
+               if (bytesTrucated > MaxBytesTruncated)\r
+               {\r
+                       MaxBytesTruncated = bytesTrucated;\r
+               }\r
+\r
+               nParam = 15;\r
+       }\r
+\r
+       TRACE_ENTER_CRITICAL_SECTION();\r
+\r
+       if (RecorderEnabled)\r
+       {\r
+               int eventSize = sizeof(BaseEvent) + nParam * sizeof(uint32_t);\r
+\r
+               eventCounter++;\r
+\r
+               TRC_STREAM_PORT_ALLOCATE_EVENT(largestEventType, event, eventSize);\r
+               if (event != NULL)\r
+               {\r
+                       event->base.EventID = (eventID) | PARAM_COUNT(nParam);\r
+                       event->base.EventCount = eventCounter;\r
+                       event->base.TS = prvGetTimestamp32();\r
+\r
+                       /* 32-bit write-pointer for the data argument */\r
+                       uint32_t* data32 = (uint32_t*) &(event->data[0]);\r
+\r
+                       for (i = 0; i < nArgs; i++)\r
+                       {\r
+                               if ((userEvtChannel != NULL) && (i == 0))\r
+                               {\r
+                                       /* First, add the User Event Channel if not NULL */\r
+                                       data32[i] = (uint32_t)userEvtChannel;\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* Add data arguments... */\r
+                                       data32[i] = va_arg(vl, uint32_t);\r
+                               }\r
+                       }\r
+\r
+                       for (i = 0; i < len; i++)\r
+                       {\r
+                               event->data[nArgs * 4 + i] = str[i];\r
+                       }\r
+\r
+                       event->data[nArgs * 4 + len] = 0;\r
+                       TRC_STREAM_PORT_COMMIT_EVENT(event, eventSize);\r
+               }\r
+       }\r
+       TRACE_EXIT_CRITICAL_SECTION();\r
+}\r
+\r
+/* Saves a symbol name (task name etc.) in symbol table */\r
+void vTraceSaveSymbol(void *address, const char *name)\r
+{\r
+       uint32_t i = 0;\r
+       uint32_t foundSlot = SYMBOL_TABLE_BUFFER_SIZE;\r
+       void *ptr;\r
+\r
+       for (i = 0; i < SYMBOL_TABLE_BUFFER_SIZE; i += SYMBOL_TABLE_SLOT_SIZE)\r
+       {\r
+               ptr = *((void**)&symbolTable.pSymbolTableBuffer[i]);\r
+               if (ptr == 0 && foundSlot == SYMBOL_TABLE_BUFFER_SIZE)\r
+               {\r
+                       foundSlot = i;\r
+               }\r
+               else if (ptr == address)\r
+               {\r
+                       foundSlot = i;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if (foundSlot != SYMBOL_TABLE_BUFFER_SIZE)\r
+       {\r
+               *((uint32_t*)&symbolTable.pSymbolTableBuffer[foundSlot]) =\r
+                       (uint32_t)address;\r
+\r
+               for (i = 0; i < TRC_SYMBOL_MAX_LENGTH; i++)\r
+        {\r
+                       if (name[i] == 0)\r
+                               break;\r
+\r
+                       symbolTable.pSymbolTableBuffer[foundSlot + sizeof(uint32_t) + i] =\r
+                               name[i];\r
+               }\r
+\r
+               /* Check the length of "name", if longer than SYMBOL_MAX_LENGTH */\r
+               while ((name[i] != 0) && i < 128)\r
+               {\r
+                       i++;\r
+               }\r
+\r
+               /* Remember the longest symbol name, for diagnostic purposes */\r
+               if (i > LongestSymbolName)\r
+               {\r
+                       LongestSymbolName = i;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               NoRoomForSymbol++;\r
+       }\r
+}\r
+\r
+/* Deletes a symbol name (task name etc.) from symbol table */\r
+void vTraceDeleteSymbol(void *address)\r
+{\r
+       uint32_t i = 0;\r
+       void **ptr;\r
+\r
+       for (i = 0; i < SYMBOL_TABLE_BUFFER_SIZE; i += SYMBOL_TABLE_SLOT_SIZE)\r
+       {\r
+               ptr = ((void**)&symbolTable.pSymbolTableBuffer[i]);\r
+               if (*ptr == address)\r
+               {\r
+                       *ptr = 0;\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+/* Saves an object data entry (task base priority) in object data table */\r
+void vTraceSaveObjectData(void *address, uint32_t data)\r
+{\r
+       uint32_t i = 0;\r
+       uint32_t foundSlot = OBJECT_DATA_TABLE_BUFFER_SIZE;\r
+       void *ptr;\r
+\r
+       for (i = 0; i < OBJECT_DATA_TABLE_BUFFER_SIZE; i += OBJECT_DATA_SLOT_SIZE)\r
+       {\r
+               ptr = *((void**)&objectDataTable.pObjectDataTableBuffer[i]);\r
+               if (ptr == 0 && foundSlot == OBJECT_DATA_TABLE_BUFFER_SIZE)\r
+               {\r
+                       foundSlot = i;\r
+               }\r
+               else if (ptr == address)\r
+               {\r
+                       foundSlot = i;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if (foundSlot != OBJECT_DATA_TABLE_BUFFER_SIZE)\r
+       {\r
+               *(uint32_t*)&objectDataTable.pObjectDataTableBuffer[foundSlot] = (uint32_t)address;\r
+               *(uint32_t*)&objectDataTable.pObjectDataTableBuffer[foundSlot + sizeof(uint32_t)] = data;\r
+       }\r
+       else\r
+       {\r
+               NoRoomForObjectData++;\r
+       }\r
+}\r
+\r
+/* Removes an object data entry (task base priority) from object data table */\r
+void vTraceDeleteObjectData(void *address)\r
+{\r
+       uint32_t i = 0;\r
+       void **ptr;\r
+\r
+       for (i = 0; i < OBJECT_DATA_TABLE_BUFFER_SIZE; i += OBJECT_DATA_SLOT_SIZE)\r
+       {\r
+               ptr = (void**)&objectDataTable.pObjectDataTableBuffer[i];\r
+               if (*ptr == address)\r
+               {\r
+                       *ptr = 0;\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+/* Checks if the provided command is a valid command */\r
+int isValidCommand(TracealyzerCommandType* cmd)\r
+{\r
+       uint16_t checksum = (uint16_t)(0xFFFF - (       cmd->cmdCode +\r
+                                                                                               cmd->param1 +\r
+                                                                                               cmd->param2 +\r
+                                                                                               cmd->param3 +\r
+                                                                                               cmd->param4 +\r
+                                                                                               cmd->param5));\r
+\r
+       if (cmd->checksumMSB != (unsigned char)(checksum >> 8))\r
+               return 0;\r
+\r
+       if (cmd->checksumLSB != (unsigned char)(checksum & 0xFF))\r
+               return 0;\r
+\r
+       if (cmd->cmdCode > CMD_LAST_COMMAND)\r
+               return 0;\r
+\r
+       return 1;\r
+}\r
+\r
+/* Executed the received command (Start or Stop) */\r
+void processCommand(TracealyzerCommandType* cmd)\r
+{\r
+       switch(cmd->cmdCode)\r
+       {\r
+               case CMD_SET_ACTIVE:\r
+                       intSetRecorderEnabled(cmd->param1);\r
+                       break;\r
+\r
+               default:\r
+                       break;\r
+       }\r
+}\r
+\r
+/* Called on critical errors in the recorder. Stops the recorder! */\r
+void psfError(int errCode)\r
+{\r
+       if (! errorCode)\r
+       {\r
+               errorCode = errCode;\r
+               vTracePrintF(trcWarningChannel, "Error %d. Stopped recorder.", errorCode);\r
+\r
+               intSetRecorderEnabled(0);\r
+       }\r
+}\r
+\r
+/* Performs timestamping using definitions in trcHardwarePort.h */\r
+static uint32_t prvGetTimestamp32(void)\r
+{\r
+       int ticks = TRACE_GET_OS_TICKS();\r
+       return (HWTC_COUNT & 0x00FFFFFF) + ((ticks & 0x000000FF) << 24);\r
+}\r
+\r
+/* Store the Timestamp Config event */\r
+static void vTraceStoreTSConfig(void)\r
+{\r
+       vTraceStoreEvent3(      PSF_EVENT_TS_CONFIG,\r
+                                               (uint32_t)TRACE_CPU_CLOCK_HZ,\r
+                                               (uint32_t)TRACE_TICK_RATE_HZ,\r
+                                               (int32_t)HWTC_TYPE);\r
+}\r
+\r
+#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcRecorder.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcRecorder.h
new file mode 100644 (file)
index 0000000..3cec07b
--- /dev/null
@@ -0,0 +1,363 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcRecorder.c\r
+ *\r
+ * Public interface and configurations for the trace recorder library.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef _TRC_RECORDER_H\r
+#define _TRC_RECORDER_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+#include "trcConfig.h"\r
+#include "trcKernelPort.h"\r
+#include "trcHardwarePort.h"\r
+\r
+#if (USE_TRACEALYZER_RECORDER == 1)\r
+\r
+/*** User API *****************************************************************/\r
+\r
+/******************************************************************************\r
+ * vTracePrint\r
+ *\r
+ * Generates "User Events", with unformatted text.\r
+ *\r
+ * User Events can be used for very efficient application logging, and are shown\r
+ * as yellow labels in the main trace view.\r
+ *\r
+ * You may group User Events into User Event Channels. The yellow User Event \r
+ * labels shows the logged string, preceeded by the channel  name within \r
+ * brackets. For example:\r
+ *\r
+ *  "[MyChannel] Hello World!"\r
+ *\r
+ * The User Event Channels are shown in the View Filter, which makes it easy to\r
+ * select what User Events you wish to display. User Event Channels are created\r
+ * using vTraceStoreUserEventChannelName().\r
+ *\r
+ * Example:\r
+ *\r
+ *      char* error_uechannel = vTraceStoreUserEventChannelName("Errors");\r
+ *      ...\r
+ *      vTracePrint(error_uechannel, "Shouldn't reach this code!");\r
+ *\r
+ ******************************************************************************/\r
+void vTracePrint(const char* chn, const char* str);\r
+\r
+/******************************************************************************\r
+ * vTracePrintF\r
+ *\r
+ * Generates "User Events", with formatted text and data, similar to a "printf".\r
+ * It is very fast since the actual formatting is done on the host side when the\r
+ * trace is displayed.\r
+ *\r
+ * User Events can be used for very efficient application logging, and are shown\r
+ * as yellow labels in the main trace view.\r
+ * An advantage of User Events is that data can be plotted in the "User Event\r
+ * Signal Plot" view, visualizing any data you log as User Events, discrete\r
+ * states or control system signals (e.g. system inputs or outputs).\r
+ *\r
+ * You may group User Events into User Event Channels. The yellow User Event \r
+ * labels show the logged string, preceeded by the channel name within brackets.\r
+ * \r
+ * Example:\r
+ *\r
+ *  "[MyChannel] Hello World!"\r
+ *\r
+ * The User Event Channels are shown in the View Filter, which makes it easy to\r
+ * select what User Events you wish to display. User Event Channels are created\r
+ * using vTraceStoreUserEventChannelName().\r
+ *\r
+ * Example:\r
+ *\r
+ *      char* adc_uechannel = vTraceStoreUserEventChannelName("ADC User Events");\r
+ *      ...\r
+ *      vTracePrint(adc_uechannel,\r
+ *                              "ADC channel %d: %lf volts",\r
+ *                              ch, (double)adc_reading/(double)scale);\r
+ *\r
+ * All data arguments are assumed to be 32 bt wide. The following formats are\r
+ * supported in v2.8:\r
+ * %d - signed integer\r
+ * %u - unsigned integer\r
+ * %X - hexadecimal (uppercase)\r
+ * %x - hexadecimal (lowercase)\r
+ * %s - string (currently, this must be an earlier stored symbol name)\r
+ *\r
+ * Up to 15 data arguments are allowed, with a total size of maximum 60 byte\r
+ * including 8 byte for the base event fields and the format string. So with\r
+ * one data argument, the maximum string length is 48 chars. If this is exceeded\r
+ * the string is truncated (4 bytes at a time).\r
+ *\r
+ ******************************************************************************/\r
+void vTracePrintF(const char* chn, const char* fmt, ...);\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreUserEventChannelName(const char* name)\r
+ *\r
+ * Parameter name: the channel name to store (const string literal)\r
+ *\r
+ * Stores a name for a user event channel, returns the handle (just a pointer\r
+ * to the provided string). Typically assigned to a "channel" variable that\r
+ * keeps it for later calls to vTracePrintF();\r
+ ******************************************************************************/\r
+char* vTraceStoreUserEventChannelName(const char* name);\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreKernelObjectName(void* object, const char* name)\r
+ *\r
+ * Parameter object: pointer to the kernel object that shall be named\r
+ * Parameter name: the name to store (const string literal)\r
+ *\r
+ * Stores a name for kernel objects (Semaphore, Mailbox, etc.).\r
+ ******************************************************************************/\r
+void vTraceStoreKernelObjectName(void* object, const char* name);\r
+\r
+/*******************************************************************************\r
+ * vTraceSetISRProperties(const char* name, char priority)\r
+ *\r
+ * Parameter name: the name to give the the ISR, also serves as handle.\r
+ * Parameter priority: the priority level of the ISR.\r
+ *\r
+ * Stores a name and priority level for an Interrupt Service Routine, to allow\r
+ * for better visualization. The string address is used as a unique handle.\r
+ *\r
+ * Example:\r
+ *\r
+ *      vTraceSetISRProperties("ISRTimer1", ISRPriorityTimer1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREnd(0);\r
+ *      }\r
+ ******************************************************************************/\r
+void vTraceSetISRProperties(const char* name, char priority);\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreISRBegin(void* handle);\r
+ *\r
+ * Parameter handle: ID of the ISR, which is "name" in vTraceSetISRProperties\r
+ *\r
+ * Registers the beginning of an Interrupt Service Routine (ISR), i.e., or an\r
+ * exception handler.\r
+ *\r
+ * Example:\r
+ *\r
+ *      vTraceSetISRProperties("ISRTimer1", ISRPriorityTimer1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREnd(0);\r
+ *      }\r
+ ******************************************************************************/\r
+void vTraceStoreISRBegin(void* handle);\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreISREnd\r
+ *\r
+ * Registers the end of an Interrupt Service Routine.\r
+ *\r
+ * This function attempts to automatically detect if a task switch will take\r
+ * place when interrupt ends. If this is possible depends on the kernel port.\r
+ *\r
+ * Example:\r
+ *      #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt\r
+ *      ...\r
+ *      vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREnd();\r
+ *      }\r
+ *\r
+ ******************************************************************************/\r
+void vTraceStoreISREnd(void);\r
+\r
+/*******************************************************************************\r
+ * vTraceStoreISREndManual\r
+ *\r
+ * Registers the end of an Interrupt Service Routine.\r
+ *\r
+ * The parameter isTaskSwitchRequired indicates if the interrupt has requested a\r
+ * task-switch (= 1) or if the interrupt returns to the earlier context (= 0)\r
+ *\r
+ * Example:\r
+ *      #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt\r
+ *      ...\r
+ *      vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);\r
+ *      ...\r
+ *      void ISR_handler()\r
+ *      {\r
+ *              vTraceStoreISRBegin("ISRTimer1");\r
+ *              ...\r
+ *              vTraceStoreISREndManual(0);\r
+ *      }\r
+ *\r
+ ******************************************************************************/\r
+void vTraceStoreISREndManual(int isTaskSwitchRequired);\r
+\r
+/*******************************************************************************\r
+ * vTraceInstanceFinishNow\r
+ *\r
+ * Creates an event that ends the current task instance at this very instant.\r
+ * This makes the viewer to splits the current fragment at this point and begin\r
+ * a new actor instance, even if no task-switch has occurred.\r
+ *****************************************************************************/\r
+void vTraceInstanceFinishedNow(void);\r
+\r
+/*******************************************************************************\r
+ * vTraceInstanceFinishedNext\r
+ *\r
+ * Marks the current "task instance" as finished on the next kernel call.\r
+ *\r
+ * If that kernel call is blocking, the instance ends after the blocking event\r
+ * and the corresponding return event is then the start of the next instance.\r
+ * If the kernel call is not blocking, the viewer instead splits the current\r
+ * fragment right before the kernel call, which makes this call the first event\r
+ * of the next instance.\r
+ *****************************************************************************/\r
+void vTraceInstanceFinishedNext(void);\r
+\r
+\r
+/******************************************************************************/\r
+/*** INTERNAL FUNCTIONS *******************************************************/\r
+/******************************************************************************/\r
+\r
+/* Saves a symbol name (task name etc.) in symbol table */\r
+void vTraceSaveSymbol(void *address, const char *name);\r
+\r
+/* Deletes a symbol name (task name etc.) from symbol table */\r
+void vTraceDeleteSymbol(void *address);\r
+\r
+/* Saves an object data entry (task base priority) in object data table */\r
+void vTraceSaveObjectData(void *address, uint32_t data);\r
+\r
+/* Removes an object data entry (task base priority) from object data table */\r
+void vTraceDeleteObjectData(void *address);\r
+\r
+/* Store an event with zero parameters (event ID only) */\r
+void vTraceStoreEvent0(uint16_t eventID);\r
+\r
+/* Store an event with one 32-bit parameter (pointer address or an int) */\r
+void vTraceStoreEvent1(uint16_t eventID, uint32_t param1);\r
+\r
+/* Store an event with two 32-bit parameters */\r
+void vTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2);\r
+\r
+/* Store an event with three 32-bit parameters */\r
+void vTraceStoreEvent3(        uint16_t eventID,\r
+                                               uint32_t param1,\r
+                                               uint32_t param2,\r
+                                               uint32_t param3);\r
+\r
+/* Stores an event with <nParam> 32-bit integer parameters */\r
+void vTraceStoreEvent(int nParam, uint16_t EventID, ...);\r
+\r
+/* Stories an event with a string and <nParam> 32-bit integer parameters */\r
+void vTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...);\r
+\r
+/* The data structure for commands (a bit overkill) */\r
+typedef struct\r
+{\r
+  unsigned char cmdCode;\r
+  unsigned char param1;\r
+  unsigned char param2;\r
+  unsigned char param3;\r
+  unsigned char param4;\r
+  unsigned char param5;\r
+  unsigned char checksumLSB;\r
+  unsigned char checksumMSB;\r
+} TracealyzerCommandType;\r
+\r
+/* Checks if the provided command is a valid command */\r
+int isValidCommand(TracealyzerCommandType* cmd);\r
+\r
+/* Executed the received command (Start or Stop) */\r
+void processCommand(TracealyzerCommandType* cmd);\r
+\r
+/* Backwards compatibility macros with old recorder */\r
+#define vTraceInitTraceData() Trace_Init()\r
+#define uiTraceStart() (1)\r
+#define vTraceStart()\r
+#define vTraceStop()\r
+\r
+#else /*(USE_TRACEALYZER_RECORDER == 1)*/\r
+\r
+#define vTraceStoreEvent0(e)\r
+#define vTraceStoreEvent1(e, param1)\r
+#define vTraceStoreEvent2(e, param1, param2)\r
+#define vTraceStoreEvent3(e, param1, param2, param3)\r
+#define vTraceStoreUserEventChannelName(x) 0\r
+#define vTracePrint(chn, ...) \r
+#define vTracePrintF(chn, ...) \r
+#define vTraceInstanceFinishedNow()\r
+#define vTraceInstanceFinishedNext()\r
+#define vTraceStoreISRBegin(x)\r
+#define vTraceStoreISREnd()\r
+#define vTraceStoreISREndManual(x)\r
+#define vTraceSetISRProperties(a, b) \r
+#define vTraceStoreKernelObjectName(a, b) \r
+\r
+/* Backwards compatibility macros with old recorder */\r
+#define vTraceInitTraceData()  \r
+#define uiTraceStart() (1)\r
+#define vTraceStart()\r
+#define vTraceStop()\r
+\r
+#endif /*(USE_TRACEALYZER_RECORDER == 1)*/\r
+\r
+extern void psfError(int errCode);\r
+\r
+#define PSF_ASSERT(_assert, _err) if (! (_assert)){ psfError(_err); return; }\r
+\r
+#define PSF_ERROR_NONE 0\r
+#define PSF_ERROR_EVENT_CODE_TOO_LARGE 1\r
+#define PSF_ERROR_ISR_NESTING_OVERFLOW 2\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _TRC_RECORDER_H */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcStreamPort.h
new file mode 100644 (file)
index 0000000..fd6d2e9
--- /dev/null
@@ -0,0 +1,219 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcStreamPort.h\r
+ *\r
+ * This file defines the trace streaming interface used by the \r
+ * Trace Recorder Library. It comes preconfigured for use with SEGGER's RTT and\r
+ * a TCP/IP (needs additional configuration in trcTCPIPConfig.h).\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef _TRC_STREAM_PORT_H\r
+#define _TRC_STREAM_PORT_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+#if (USE_TRACEALYZER_RECORDER == 1)\r
+\r
+#define TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK   (0x01)\r
+#define TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK (0x02)\r
+#define TRC_RECORDER_TRANSFER_METHOD_TCPIP             (0x03)\r
+#define TRC_RECORDER_TRANSFER_METHOD_CUSTOM            (0xFF)\r
+\r
+#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC   (0x00)\r
+#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC  (0x01)\r
+\r
+/*******************************************************************************\r
+ *   TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK / NOBLOCK\r
+ ******************************************************************************/\r
+#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK || TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK\r
+\r
+#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK\r
+#define TRC_STREAM_PORT_BLOCKING_TRANSFER 1\r
+#define RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL\r
+#else\r
+#define TRC_STREAM_PORT_BLOCKING_TRANSFER 0\r
+#define RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP\r
+#endif\r
+\r
+#include "SEGGER_RTT_Conf.h"\r
+#include "SEGGER_RTT.h"\r
+\r
+/* Up-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \\r
+#if TRC_RTT_UP_BUFFER_INDEX == 0\r
+#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL;    /* Not actually used. Ignore allocation method. */\r
+#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */\r
+#else\r
+#if TRC_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC\r
+#define TRC_RTT_ALLOC_UP() static char _TzTraceData[BUFFER_SIZE_UP];    /* Static allocation */\r
+#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */\r
+#else\r
+#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL;    /* Dynamic allocation */\r
+#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(BUFFER_SIZE_UP);\r
+#endif\r
+#endif\r
+\r
+/* Down-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \\r
+#if TRC_RTT_DOWN_BUFFER_INDEX == 0\r
+#define TRC_RTT_ALLOC_DOWN() static char* _TzCtrlData = NULL;           /* Not actually used. Ignore allocation method. */\r
+#else\r
+#define TRC_RTT_ALLOC_DOWN() static char _TzCtrlData[BUFFER_SIZE_DOWN]; /* This buffer should be ~32bytes. Ignore allocation method. */\r
+#endif\r
+  \r
+#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \\r
+       TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \\r
+       TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */\r
+\r
+#define TRC_STREAM_PORT_INIT() \\r
+        TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \\r
+       SEGGER_RTT_ConfigUpBuffer(TRC_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, sizeof(_TzTraceData), RTT_MODE ); \\r
+       SEGGER_RTT_ConfigDownBuffer(TRC_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, sizeof(_TzCtrlData), 0);\r
+\r
+#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) uint8_t tmpEvt[_size]; _type* _ptrData = (_type*)tmpEvt;\r
+#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) SEGGER_RTT_Write(TRC_RTT_UP_BUFFER_INDEX, (const char*)_ptrData, _size);\r
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) *_ptrBytesRead = SEGGER_RTT_Read(TRC_RTT_DOWN_BUFFER_INDEX, (char*)_ptrData, _size);\r
+#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent)\r
+\r
+#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */\r
+#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */\r
+    \r
+#endif /*TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK || TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK*/\r
+\r
+/*******************************************************************************\r
+ *   TRC_RECORDER_TRANSFER_METHOD_TCPIP\r
+ * \r
+ * This TCP/IP implementation is using a secondary buffer consisting of multiple \r
+ * pages to avoid the endless recursive calls that occurr when "socket_send" \r
+ * uses kernel objects such as mutexes and semaphores, which in turn needs to be\r
+ * traced. To use your own TCP/IP stack, modify the functions declared in\r
+ * trcTCPIPConfig.h.\r
+ ******************************************************************************/\r
+#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_TCPIP\r
+\r
+#include "trcTCPIP.h"\r
+#include "trcPagedEventBuffer.h"\r
+#include "trcPagedEventBufferConfig.h"\r
+#define TRC_STREAM_PORT_BLOCKING_TRANSFER 0\r
+\r
+#if TRC_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC\r
+#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char _TzTraceData[TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE];       /* Static allocation. */\r
+#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */\r
+#else\r
+#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char* _TzTraceData = NULL;     /* Dynamic allocation. */\r
+#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE);\r
+#endif\r
+\r
+#define TRC_STREAM_PORT_INIT() \\r
+        TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \\r
+        vPagedEventBufferInit(_TzTraceData);\r
+\r
+#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)vPagedEventBufferGetWritePointer(_size);\r
+#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not needed since we write immediately into the buffer received above by TRC_STREAM_PORT_ALLOCATE_EVENT, and the TRC_STREAM_PORT_PERIODIC_SEND_DATA defined below will take care of the actual trace transfer. */\r
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead);\r
+#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) vPagedEventBufferTransfer(trcTcpWrite, _ptrBytesSent);\r
+\r
+#define TRC_STREAM_PORT_ON_TRACE_BEGIN() vPagedEventBufferInit(_TzTraceData);\r
+#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */\r
+\r
+#endif /*TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_TCPIP*/\r
+\r
+/*******************************************************************************\r
+ *   TRC_RECORDER_TRANSFER_METHOD_CUSTOM\r
+ *\r
+ * Implement the following macros in trcConfig.h. If your transfer method uses\r
+ * kernel objects when sending data you will need to use a secondary buffer to \r
+ * store the trace data before sending it. For this reason we provide \r
+ * trcPagedEventBuffer. Look at the TCP/IP macros above to see how to use it.\r
+ ******************************************************************************/\r
+#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_CUSTOM\r
+\r
+/* When using the custom transfer method, define TRC_STREAM_CUSTOM_XXXXXXXXXXXXX in trcConfig.h */\r
+#define TRC_STREAM_PORT_BLOCKING_TRANSFER TRC_STREAM_CUSTOM_BLOCKING_TRANSFER\r
+#define TRC_STREAM_PORT_ALLOCATE_FIELDS() TRC_STREAM_CUSTOM_ALLOCATE_FIELDS()\r
+#define TRC_STREAM_PORT_INIT() TRC_STREAM_CUSTOM_INIT()\r
+#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptr, _size) TRC_STREAM_CUSTOM_ALLOCATE_EVENT(_type, _ptr, _size)\r
+#define TRC_STREAM_PORT_COMMIT_EVENT(_ptr, _size) TRC_STREAM_CUSTOM_COMMIT_EVENT(_ptr, _size)\r
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) TRC_STREAM_CUSTOM_READ_DATA(_ptrData, _size, _ptrBytesRead)\r
+#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) TRC_STREAM_CUSTOM_PERIODIC_SEND_DATA(_ptrBytesSent)\r
+#define TRC_STREAM_PORT_ON_TRACE_BEGIN() TRC_STREAM_CUSTOM_ON_TRACE_BEGIN()\r
+#define TRC_STREAM_PORT_ON_TRACE_END() TRC_STREAM_CUSTOM_ON_TRACE_END()\r
+\r
+#endif /*TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_CUSTOM*/\r
+\r
+#ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ALLOCATE_FIELDS!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_ALLOCATE_EVENT\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ALLOCATE_EVENT!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_COMMIT_EVENT\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_COMMIT_EVENT!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_INIT\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_INIT!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_BLOCKING_TRANSFER\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_BLOCKING_TRANSFER!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_READ_DATA\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_READ_DATA!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_PERIODIC_SEND_DATA\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_PERIODIC_SEND_DATA!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_ON_TRACE_BEGIN\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ON_TRACE_BEGIN!"\r
+#endif\r
+\r
+#ifndef TRC_STREAM_PORT_ON_TRACE_END\r
+#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ON_TRACE_END!"\r
+#endif\r
+\r
+#endif /*(USE_TRACEALYZER_RECORDER == 1)*/\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _TRC_STREAM_PORT_H */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIP.c
new file mode 100644 (file)
index 0000000..0f782be
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcTCPIP.c\r
+ *\r
+ * Simple generic TCP/IP layer. Modify trcTCPIPConfig.h to adapt it to any \r
+ * custom stack.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#include <stdint.h>\r
+#include "trcTCPIP.h"\r
+#include "trcTCPIPConfig.h"\r
+\r
+int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten)\r
+{\r
+    return trcSocketSend(data, size, ptrBytesWritten);\r
+}\r
+\r
+int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead)\r
+{\r
+    trcSocketInitializeListener();\r
+        \r
+    trcSocketAccept();\r
+      \r
+    return trcSocketReceive(data, size, ptrBytesRead);\r
+}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIP.h
new file mode 100644 (file)
index 0000000..fa9a777
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcTCPIP.h\r
+ *\r
+ * Simple generic TCP/IP layer. Modify trcTCPIPConfig.h to adapt it to any \r
+ * custom stack.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef TRC_TCPIP_H\r
+#define TRC_TCPIP_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);\r
+int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*TRC_TCPIP_H*/
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIPConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace(streaming)/trcTCPIPConfig.h
new file mode 100644 (file)
index 0000000..be0b553
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************\r
+ * Trace Recorder Library for Tracealyzer v3.0.2\r
+ * Percepio AB, www.percepio.com\r
+ *\r
+ * trcTCPIPConfig.h\r
+ *\r
+ * Trace TCP/IP configuration. Modify these includes and functions to perform \r
+ * the same functionality using your specific TCP/IP stack.\r
+ * Will only be included by trcTCPIP.c.\r
+ *\r
+ * Terms of Use\r
+ * This software (the "Tracealyzer Recorder Library") is the intellectual\r
+ * property of Percepio AB and may not be sold or in other ways commercially\r
+ * redistributed without explicit written permission by Percepio AB.\r
+ *\r
+ * Separate conditions applies for the SEGGER branded source code included.\r
+ *\r
+ * The recorder library is free for use together with Percepio products.\r
+ * You may distribute the recorder library in its original form, but public\r
+ * distribution of modified versions require approval by Percepio AB.\r
+ *\r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
+ * implied warranty may last, so the above limitations may not apply to you.\r
+ *\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2015.\r
+ * www.percepio.com\r
+ ******************************************************************************/\r
+\r
+#ifndef TRC_TCPIP_CONFIG_H\r
+#define TRC_TCPIP_CONFIG_H\r
+\r
+#ifdef __cplusplus\r
+extern \93C\94 {\r
+#endif\r
+\r
+/* TCP/IP includes*/\r
+#include "tcpip.h"\r
+\r
+#define TRC_TCPIP_PORT 12000\r
+\r
+socket* sock = NULL;\r
+socket* listenerSocket = NULL;\r
+\r
+int32_t trcSocketSend(void* data, int32_t size, int32_t* bytesWritten)\r
+{\r
+  int32_t error;\r
+  if (sock == NULL)\r
+    return 1;\r
+  \r
+  error = socket_send(sock, data, size, (size_t*)bytesWritten, 0);\r
+  if (error)\r
+  {\r
+    socket_close(sock);\r
+    sock = NULL;\r
+  }\r
+  \r
+  return (int32_t)error;\r
+}\r
+\r
+int32_t trcSocketReceive(void* data, int32_t size, int32_t* bytesRead)\r
+{\r
+  int32_t error;\r
+  if (sock == NULL)\r
+    return 1;\r
+  \r
+  error = socket_receive(sock, data, size, (size_t*)bytesRead, SOCKET_WAIT_ALL);\r
+  if (error != ERROR_NONE && error != ERROR_TIMEOUT) /* Timeout may be expected when there is no data */\r
+  {\r
+    socket_close(sock);\r
+    sock = NULL;\r
+    return error;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+int32_t trcSocketInitializeListener()\r
+{\r
+  int32_t error;\r
+  \r
+  if (listenerSocket)\r
+    return 0;\r
+  \r
+  //Start of exception handling block\r
+  do\r
+  {\r
+    listenerSocket = socket_open(SOCKET_STREAM, SOCKET_TCP);\r
+    if(listenerSocket == NULL)\r
+    {\r
+       error = 1;\r
+       break;\r
+    }\r
+\r
+    error = socket_set_timeout(listenerSocket, INFINITE);\r
+    if(error) break;\r
+\r
+    error = socket_set_tx_buffer_size(listenerSocket, 1440 * 2);\r
+    if(error) break;\r
+\r
+    error = socket_set_rx_buffer_size(listenerSocket, 128);\r
+    if(error) break;\r
+\r
+    error = socket_bind_to_interface(listenerSocket, pNetInterface);\r
+    if(error) break;\r
+\r
+    error = socket_bind(listenerSocket, ADDR_ANY, TRC_TCPIP_PORT);\r
+    if(error) break;\r
+\r
+    error = socket_listen(listenerSocket);\r
+    if(error) break;\r
+    } while(0);\r
+\r
+    if(error)\r
+    {\r
+        socket_close(listenerSocket);\r
+        listenerSocket = NULL;\r
+    }\r
+   \r
+    return error;\r
+}\r
+\r
+int32_t trcSocketAccept()\r
+{\r
+  ip_addr clientIpAddr;\r
+  uint16_t clientPort;\r
+  \r
+  if (sock != NULL)\r
+    return 0;\r
+\r
+  if (listenerSocket == NULL)\r
+    return 1;\r
+  \r
+  /* Wait for connection */\r
+  sock = socket_accept(listenerSocket, &clientIpAddr, &clientPort);\r
+  if(sock != NULL)\r
+  {\r
+    socket_set_timeout(sock, 20);\r
+  }\r
+  else\r
+    return 1;\r
+  \r
+  return 0;\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*TRC_TCPIP_CONFIG_H*/
\ No newline at end of file
index 4a08f47f96040d380ec5c7136b8bb77589a76b94..a7ec05be4f4c18b76cc82f330bed92158795abf5 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcConfig.h\r
@@ -38,7 +38,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
  * recording is stopped when the buffer becomes full. This is useful for\r
  * recording events following a specific state, e.g., the startup sequence.\r
  *****************************************************************************/\r
-#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_STOP_WHEN_FULL\r
+#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER\r
 \r
 /*******************************************************************************\r
  * TRACE_SCHEDULING_ONLY\r
  * If this setting is enabled (= 1), only scheduling events are recorded.\r
  * If disabled (= 0), all events are recorded.\r
  *\r
- * Users of FreeRTOS+Trace Free Edition only displays scheduling events, so this\r
- * option can be used to avoid storing unsupported events.\r
+ * For users of "Free Edition", that only  displays scheduling events, this\r
+ * option can be used to avoid storing other events.\r
  *\r
  * Default value is 0 (store all enabled events).\r
  *\r
index ba86f5ce147dcc71910a7357770361ad08d9ff07..85a6c9c4ba19ab693c96f2847e39d2d2dc4f51d0 100644 (file)
@@ -1,10 +1,10 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
- * trcKernel.c\r
+ * trcBase.h\r
  *\r
- * Functions used by trcKernelHooks.h for storing various kernel events.\r
+ * Core functionality of the Tracealyzer recorder library.\r
  *\r
  * Terms of Use\r
  * This software is copyright Percepio AB. The recorder library is free for\r
@@ -33,7 +33,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
 /* Max number of event codes supported */\r
 #define NEventCodes 0x100\r
 \r
-extern volatile int recorder_busy; // This is used to keep track of the recorder's critical sections, to determine if it is busy\r
-// Our local critical sections for the recorder - updates an internal busy flag\r
+/* Keeps track of the recorder's critical sections */\r
+extern volatile int recorder_busy;\r
+\r
+/* Our local critical sections for the recorder */\r
 #define trcCRITICAL_SECTION_BEGIN() {TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++;}\r
 #define trcCRITICAL_SECTION_END() {recorder_busy--; TRACE_EXIT_CRITICAL_SECTION();}\r
 \r
@@ -145,7 +147,7 @@ typedef struct
 \r
        /* This is used to calculate the index in the dynamic object table\r
        (handle - 1 - nofStaticObjects = index)*/\r
-#if (USE_16BIT_OBJECT_HANDLES == 1)    \r
+#if (USE_16BIT_OBJECT_HANDLES == 1)\r
        objectHandleType NumberOfObjectsPerClass[2*((TRACE_NCLASSES+1)/2)];\r
 #else\r
        objectHandleType NumberOfObjectsPerClass[4*((TRACE_NCLASSES+3)/4)];\r
@@ -242,7 +244,7 @@ typedef struct
        uint8_t type;\r
        uint8_t unused1;\r
        uint8_t unused2;\r
-       uint8_t dts;    \r
+       uint8_t dts;\r
 } TaskInstanceStatusEvent;\r
 \r
 typedef struct\r
@@ -335,7 +337,7 @@ typedef struct
        /* Used to determine Kernel and Endianess */\r
        uint16_t version;\r
 \r
-       /* Currently 3, since v2.6.0 */\r
+       /* Currently 3 */\r
        uint8_t minor_version;\r
 \r
        /* This should be 0 if lower IRQ priority values implies higher priority\r
@@ -374,7 +376,7 @@ typedef struct
 \r
        /* Not used, remains for compatibility and future use */\r
        uint8_t notused[28];\r
-       \r
+\r
        /* The amount of heap memory remaining at the last malloc or free event */\r
        uint32_t heapMemUsage;\r
 \r
index e307a01a6205bc51a29e7f86f231fd15050a42ab..ecbf4975212e6236ee0b08f69c4102fcd07628b7 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcHardwarePort.h\r
@@ -34,7 +34,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
index 7be8770706f18cd8abb60cd1b98105d396f988a5..3506f615ef5ec50726f17401c5e472cb01e93e17 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcKernel.h\r
@@ -31,7 +31,7 @@
  * damages, or the exclusion of implied warranties or limitations on how long an\r
  * implied warranty may last, so the above limitations may not apply to you.\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2013.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
index 53dc78d280a71245f5ce4301c86214fb3910da81..7b94a106f520c33003b8bd8ad3e0c6bae4a7ce31 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
-* Tracealyzer v2.7.7 Recorder Library\r
+* Tracealyzer v3.0.2 Recorder Library\r
 * Percepio AB, www.percepio.com\r
 *\r
 * trcKernelHooks.h\r
@@ -40,7 +40,7 @@
 * damages, or the exclusion of implied warranties or limitations on how long an\r
 * implied warranty may last, so the above limitations may not apply to you.\r
 *\r
-* Copyright Percepio AB, 2012-2015.\r
+* Copyright Percepio AB, 2013.\r
 * www.percepio.com\r
 ******************************************************************************/\r
 \r
index 904258606e731f25283cc07cac391c86ce8ff3d9..c5d25d9216589d054ef556c66f72b29e2458d41b 100644 (file)
@@ -1,8 +1,8 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
- * trcKernelPortFreeRTOS.h\r
+ * trcKernelPort.h\r
  *\r
  * Kernel-specific functionality for FreeRTOS, used by the recorder library.\r
  *\r
@@ -33,7 +33,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
@@ -56,16 +56,21 @@ extern int uiInEventGroupSetBitsFromISR;
 #define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */\r
 \r
 #if (SELECTED_PORT == PORT_ARM_CortexM)\r
-               \r
-    /* If you get warnings regarding __get_PRIMASK and __set_PRIMASK, make sure that ARM's CMSIS API is included \r
-       by the recorder using your chip vendor header file (e.g., "board.h", "stm32f4xx.h", "lpc17xx.h") */\r
        \r
-       #define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status; \r
+       /* Uses CMSIS API */\r
+\r
+       #define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;\r
        #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);}\r
        #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);}\r
 \r
 #endif\r
 \r
+#if (SELECTED_PORT == PORT_ARM_CORTEX_M0)\r
+       #define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;\r
+       #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}\r
+       #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}\r
+#endif\r
+\r
 #if ((SELECTED_PORT == PORT_ARM_CORTEX_A9) || (SELECTED_PORT == PORT_Renesas_RX600) || (SELECTED_PORT == PORT_MICROCHIP_PIC32MX) || (SELECTED_PORT == PORT_MICROCHIP_PIC32MZ))\r
        #define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;\r
        #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}\r
@@ -471,7 +476,6 @@ void* prvTraceGetCurrentTaskHandle(void);
 #define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TraceObjectClassTable[kernelClass]\r
 #define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_CLASS_TRACE_CLASS(CLASS, prvTraceGetObjectType(pxObject))\r
 \r
-/* Note: Timer tracing only supported on FreeRTOS v8 or later, so "Timer_t" is safe to use! */\r
 #define TRACE_GET_TIMER_NUMBER(tmr) ( ( objectHandleType ) ((Timer_t*)tmr)->uxTimerNumber )\r
 #define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = xTraceGetObjectHandle(TRACE_CLASS_TIMER);\r
 #define TRACE_GET_TIMER_NAME(pxTimer) pxTimer->pcTimerName\r
@@ -553,6 +557,12 @@ void* prvTraceGetCurrentTaskHandle(void);
 #define traceTASK_SUSPEND( pxTaskToSuspend ) \\r
        trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend);\r
 \r
+/* Called from special case with timer only */\r
+#undef traceTASK_DELAY_SUSPEND\r
+#define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \\r
+       trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); \\r
+       trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();\r
+\r
 /* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */\r
 #undef traceTASK_DELAY\r
 #define traceTASK_DELAY() \\r
@@ -1064,11 +1074,3 @@ vTraceSetObjectName(TRACE_CLASS_EVENTGROUP, (objectHandleType)uxEventGroupGetNum
 #endif\r
 \r
 #endif /* TRCKERNELPORTFREERTOS_H_ */\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
index 83794dc3b098c8199ae8a83916c8161f92fa247d..a89e10a51366c8360629d2994eadf8858e63b5cc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcTypes.h\r
@@ -33,7 +33,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
index 6b99c970c26e8d1c446af23a81acadd5663a2cad..56445211e5021e0d55431daf8c2452ee27d72ef9 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcUser.h\r
@@ -32,7 +32,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
@@ -385,7 +385,7 @@ void vTraceUserEvent(traceLabel eventLabel);
  *\r
  * Calling xTraceOpenLabel multiple times will not create duplicate entries, but\r
  * it is of course faster to just do it once, and then keep the handle for later\r
- * use. If you don´t have any data arguments, only a text label/string, it is\r
+ * use. If you dont have any data arguments, only a text label/string, it is\r
  * better to use vTraceUserEvent - it is faster.\r
  *\r
  * Format specifiers supported:\r
index 44b321fefc1bd69ced64984b7d104b1de865ba79..734a7e1a2c1014e7cd309bd2d72e3b22931c54ab 100644 (file)
@@ -4,10 +4,10 @@ Tracealyzer Trace Recorder Library
 Percepio AB\r
 www.percepio.com\r
 \r
-This directory contains the a generic trace recorder library for Tracealyzer v2.7. \r
+This directory contains the a generic trace recorder library for Tracealyzer v3.0.2.\r
 \r
 For information on how to upload the trace data from your target system RAM to \r
-Tracealyzer, see the User Manual (e.g., http://percepio.com/docs/FreeRTOS/manual/Recorder.html)\r
+Tracealyzer, see the User Manual.\r
 \r
 Files included\r
 --------------\r
index b772478fd1c7efd7c73a2b0f431fe3a7b8ddbafe..7ffa8161109a76693896d4a1de4986edb842464c 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcBase.c\r
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
- #include "trcBase.h"\r
+#include "trcBase.h"\r
 \r
 #if (USE_TRACEALYZER_RECORDER == 1)\r
 \r
@@ -48,7 +48,7 @@
  ******************************************************************************/\r
 \r
 /* Tasks and kernel objects can be explicitly excluded from the trace to reduce\r
-buffer usage. This structure handles the exclude flags for all objects and tasks.\r
+buffer usage. This structure handles the exclude flags for all objects and tasks. \r
 Note that slot 0 is not used, since not a valid handle. */\r
 uint8_t excludedObjects[(TRACE_KERNEL_OBJECT_COUNT + TRACE_NCLASSES) / 8 + 1] = { 0 };\r
 \r
@@ -58,43 +58,43 @@ This structure handle the exclude flags for all event codes */
 uint8_t excludedEventCodes[NEventCodes / 8 + 1] = { 0 };\r
 \r
 /* A set of stacks that keeps track of available object handles for each class.\r
-The stacks are empty initially, meaning that allocation of new handles will be\r
+The stacks are empty initially, meaning that allocation of new handles will be \r
 based on a counter (for each object class). Any delete operation will\r
 return the handle to the corresponding stack, for reuse on the next allocate.*/\r
 objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };\r
 \r
-/* Initial HWTC_COUNT value, for detecting if the time-stamping source is\r
-enabled. If using the OS periodic timer for time-stamping, this might not\r
+/* Initial HWTC_COUNT value, for detecting if the time-stamping source is \r
+enabled. If using the OS periodic timer for time-stamping, this might not \r
 have been configured on the earliest events during the startup. */\r
 uint32_t init_hwtc_count;\r
 \r
 /*******************************************************************************\r
  * RecorderData\r
  *\r
- * The main data structure. This is the data read by the Tracealyzer tools,\r
- * typically through a debugger RAM dump. The recorder uses the pointer\r
+ * The main data structure. This is the data read by the Tracealyzer tools, \r
+ * typically through a debugger RAM dump. The recorder uses the pointer \r
  * RecorderDataPtr for accessing this, to allow for dynamic allocation.\r
  *\r
  * On the NXP LPC17xx you may use the secondary RAM bank (AHB RAM) for this\r
  * purpose. For instance, the LPC1766 has 32 KB AHB RAM which allows for\r
  * allocating a buffer size of at least 7500 events without affecting the main\r
- * RAM. To place RecorderData in this RAM bank using IAR Embedded Workbench\r
+ * RAM. To place RecorderData in this RAM bank using IAR Embedded Workbench \r
  * for ARM, use this pragma right before the declaration:\r
  *\r
  *      #pragma location="AHB_RAM_MEMORY"\r
  *\r
  * This of course works for other hardware architectures with additional RAM\r
- * banks as well, just replace "AHB_RAM_MEMORY" with the section name from the\r
+ * banks as well, just replace "AHB_RAM_MEMORY" with the section name from the \r
  * linker .map file, or simply the desired address.\r
  *\r
- * For portability reasons, we don't add the pragma directly in trcBase.c, but\r
+ * For portability reasons, we don't add the pragma directly in trcBase.c, but \r
  * in a header file included below. To include this header, you need to enable\r
  * USE_LINKER_PRAGMA, defined in trcConfig.h.\r
  *\r
  * If using GCC, you need to modify the declaration as follows:\r
  *\r
  *      RecorderDataType RecorderData __attribute__ ((section ("name"))) = ...\r
- *\r
+ * \r
  * Remember to replace "name" with the correct section name.\r
  ******************************************************************************/\r
 \r
@@ -113,9 +113,9 @@ RecorderDataType* RecorderDataPtr = NULL;
 \r
 /* This version of the function dynamically allocates the trace data */\r
 void prvTraceInitTraceData()\r
-{\r
+{              \r
        init_hwtc_count = HWTC_COUNT;\r
-\r
+       \r
 #if TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_STATIC\r
        RecorderDataPtr = &RecorderData;\r
 #elif TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_DYNAMIC\r
@@ -132,7 +132,7 @@ void prvTraceInitTraceData()
                vTraceError("No recorder data structure allocated!");\r
                return;\r
        }\r
-\r
+               \r
        (void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType));\r
 \r
        RecorderDataPtr->startmarker0 = 0x00;\r
@@ -166,7 +166,7 @@ void prvTraceInitTraceData()
        RecorderDataPtr->SymbolTable.symTableSize = SYMBOL_TABLE_SIZE;\r
        RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;\r
 #if (INCLUDE_FLOAT_SUPPORT == 1)\r
-       RecorderDataPtr->exampleFloatEncoding = (float)1.0; /* otherwise already zero */\r
+       RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */\r
 #endif\r
        RecorderDataPtr->debugMarker2 = 0xF2F2F2F2;\r
        (void)strncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80);\r
@@ -196,7 +196,7 @@ void prvTraceInitTraceData()
 \r
        /* Fix the start markers of the trace data structure */\r
        vInitStartMarkers();\r
-\r
+       \r
        #ifdef PORT_SPECIFIC_INIT\r
        PORT_SPECIFIC_INIT();\r
        #endif\r
@@ -242,15 +242,15 @@ void* xTraceNextFreeEventBufferSlot(void)
 \r
 uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)\r
 {\r
-       TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
+       TRACE_ASSERT(objectclass < TRACE_NCLASSES, \r
                "uiIndexOfObject: Invalid value for objectclass", 0);\r
-       TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
+       TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], \r
                "uiIndexOfObject: Invalid value for objecthandle", 0);\r
 \r
-       if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) &&\r
+       if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) && \r
                (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))\r
        {\r
-               return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] +\r
+               return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] + \r
                        (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));\r
        }\r
 \r
@@ -286,7 +286,7 @@ objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass)
        objectHandleType handle;\r
        static int indexOfHandle;\r
 \r
-       TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
+       TRACE_ASSERT(objectclass < TRACE_NCLASSES, \r
                "xTraceGetObjectHandle: Invalid value for objectclass", (objectHandleType)0);\r
 \r
        indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];\r
@@ -335,9 +335,9 @@ void vTraceFreeObjectHandle(traceObjectClass objectclass, objectHandleType handl
 {\r
        int indexOfHandle;\r
 \r
-       TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
+       TRACE_ASSERT(objectclass < TRACE_NCLASSES, \r
                "vTraceFreeObjectHandle: Invalid value for objectclass", );\r
-       TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
+       TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], \r
                "vTraceFreeObjectHandle: Invalid value for handle", );\r
 \r
        /* Check that there is room to push the handle on the stack */\r
@@ -421,10 +421,10 @@ traceLabel prvTraceOpenSymbol(const char* name, traceLabel userEventChannel)
        uint8_t len;\r
        uint8_t crc;\r
        TRACE_SR_ALLOC_CRITICAL_SECTION();\r
-\r
+       \r
        len = 0;\r
        crc = 0;\r
-\r
+       \r
        TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceLabel)0);\r
 \r
        prvTraceGetChecksum(name, &crc, &len);\r
@@ -470,9 +470,9 @@ void vTraceError(const char* msg)
        {\r
                traceErrorMessage = (char*)msg;\r
                (void)strncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);\r
-               RecorderDataPtr->internalErrorOccured = 1;\r
+               RecorderDataPtr->internalErrorOccured = 1;               \r
        }\r
-\r
+       \r
 }\r
 \r
 /******************************************************************************\r
@@ -496,7 +496,7 @@ void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
        unsigned int i = 0;\r
        unsigned int e = 0;\r
 \r
-       TRACE_ASSERT(nofEntriesToCheck != 0,\r
+       TRACE_ASSERT(nofEntriesToCheck != 0, \r
                "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", );\r
 \r
        while (i < nofEntriesToCheck)\r
@@ -535,12 +535,12 @@ void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
  * Updates the index of the event buffer.\r
  ******************************************************************************/\r
 void prvTraceUpdateCounters(void)\r
-{\r
+{      \r
        if (RecorderDataPtr->recorderActive == 0)\r
        {\r
                return;\r
        }\r
-\r
+       \r
        RecorderDataPtr->numEvents++;\r
 \r
        RecorderDataPtr->nextFreeIndex++;\r
@@ -584,9 +584,9 @@ uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
        if (RecorderDataPtr->frequency == 0 && init_hwtc_count != HWTC_COUNT)\r
        {\r
                /* If HWTC_PERIOD is mapped to the timer reload register,\r
-               it might not be initialized     before the scheduler has been started.\r
+               it might not be initialized     before the scheduler has been started. \r
                We therefore store the frequency of the timer when the counter\r
-               register has changed from its initial value.\r
+               register has changed from its initial value. \r
                (Note that this function is called also by vTraceStart and\r
                uiTraceStart, which might be called before the scheduler\r
                has been started.) */\r
@@ -605,9 +605,9 @@ uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
        * If necessary, whole seconds are extracted using division while the rest\r
        * comes from the modulo operation.\r
        **************************************************************************/\r
-\r
-       vTracePortGetTimeStamp(&timestamp);\r
-\r
+       \r
+       vTracePortGetTimeStamp(&timestamp);     \r
+       \r
        /***************************************************************************\r
        * Since dts is unsigned the result will be correct even if timestamp has\r
        * wrapped around.\r
@@ -818,14 +818,14 @@ void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
 \r
 #if (USE_16BIT_OBJECT_HANDLES == 1)\r
 \r
-void prvTraceStoreXID(objectHandleType handle);\r
+void prvTraceStoreXID(objectHandleType handle); \r
 \r
 /******************************************************************************\r
  * prvTraceStoreXID\r
  *\r
  * Stores an XID (eXtended IDentifier) event.\r
  * This is used if an object/task handle is larger than 255.\r
- * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or\r
+ * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or \r
  * larger. Handles below 256 should not use this function.\r
  *\r
  * NOTE: this function MUST be called from within a critical section.\r
@@ -844,7 +844,7 @@ void prvTraceStoreXID(objectHandleType handle)
                xid->type = XID;\r
 \r
                /* This function is (only) used when objectHandleType is 16 bit... */\r
-               xid->xps_16 = handle;\r
+               xid->xps_16 = handle; \r
 \r
                prvTraceUpdateCounters();\r
        }\r
@@ -853,11 +853,11 @@ void prvTraceStoreXID(objectHandleType handle)
 unsigned char prvTraceGet8BitHandle(objectHandleType handle)\r
 {\r
        if (handle > 255)\r
-       {\r
+       {               \r
                prvTraceStoreXID(handle);\r
-               /* The full handle (16 bit) is stored in the XID event.\r
+               /* The full handle (16 bit) is stored in the XID event. \r
                This code (255) is used instead of zero (which is an error code).*/\r
-               return 255;\r
+               return 255; \r
        }\r
        return (unsigned char)(handle & 0xFF);\r
 }\r
index 632327ed30ec11a8ede1df8b104468f541506097..f3a164643633b7316867b8fb2d3c538699d73c14 100644 (file)
@@ -1,15 +1,16 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
- * trcBase.c\r
+ * trcHardwarePort.c\r
  *\r
- * Core functionality of the trace recorder library.\r
+ * Contains together with trcHardwarePort.h all hardware portability issues of\r
+ * the trace recorder library.\r
  *\r
  * Terms of Use\r
  * This software is copyright Percepio AB. The recorder library is free for\r
  * use together with Percepio products. You may distribute the recorder library\r
- * in its original form, including modifications in trcHardwarePort.c/.h\r
+ * in its original form, including modifications in trcPort.c and trcPort.h\r
  * given that these modification are clearly marked as your own modifications\r
  * and documented in the initial comment section of these source files.\r
  * This software is the intellectual property of Percepio AB and may not be\r
@@ -33,7 +34,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
index cf624c850b07b89a842cec2676c9f6e96578a50f..30d405cbe34b311e8b2e97ecbac684426a3d6236 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcKernel.c\r
@@ -33,7 +33,7 @@
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
 \r
@@ -48,9 +48,9 @@ int8_t nISRactive = 0;
 objectHandleType handle_of_last_logged_task = 0;\r
 uint8_t inExcludedTask = 0;\r
 \r
-#if (INCLUDE_MEMMANG_EVENTS == 1)\r
-/* Current heap usage. Always updated. */\r
-static uint32_t heapMemUsage = 0;\r
+#if (INCLUDE_MEMMANG_EVENTS == 1) && (TRACE_SCHEDULING_ONLY == 0)\r
+ /* Current heap usage. Always updated. */\r
+ static uint32_t heapMemUsage = 0;\r
 #endif\r
 \r
 #if (TRACE_SCHEDULING_ONLY == 0)\r
@@ -639,9 +639,9 @@ void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t
 uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)\r
 {\r
        TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
-               "uiTraceGetPriorityProperty: Invalid objectclass number (>= TRACE_NCLASSES)", 0);\r
+               "uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);\r
        TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
-               "uiTraceGetPriorityProperty: Task handle exceeds NTask. You may need to increase this constant in trcConfig.h.", 0);\r
+               "uiTraceGetPriorityProperty: Invalid value for id", 0);\r
 \r
        return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);\r
 }\r
index f2d212c3ec81098c199e8df0de2efb344f944bcb..5391789716b2ed1d98319a5d851bdd6a80fde1db 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
  * Percepio AB, www.percepio.com\r
  *\r
  * trcUser.c\r
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
  *\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
  * www.percepio.com\r
  ******************************************************************************/\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
 #include "trcUser.h"\r
 \r
 #if (USE_TRACEALYZER_RECORDER == 1)\r
@@ -367,6 +364,7 @@ void vTraceTaskInstanceFinishDirect(void)
 \r
 #define MAX_ISR_NESTING 16\r
 static uint8_t isrstack[MAX_ISR_NESTING];\r
+int32_t isPendingContextSwitch = 0;\r
 \r
 /*******************************************************************************\r
  * vTraceSetISRProperties\r
@@ -572,11 +570,15 @@ void vTraceStoreISRBegin(objectHandleType handle)
         return;\r
        }\r
        trcCRITICAL_SECTION_BEGIN();\r
+       \r
+       if (nISRactive == 0)\r
+               isPendingContextSwitch = 0;     /* We are at the start of a possible ISR chain. No context switches should have been triggered now. */\r
+       \r
        if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)\r
        {\r
 \r
                TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid value for handle", );\r
-\r
+               \r
                dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
 \r
                if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
@@ -632,6 +634,8 @@ void vTraceStoreISREnd(int pendingISR)
 {\r
        TSEvent* ts;\r
        uint16_t dts5;\r
+       uint8_t hnd8 = 0, type = 0;\r
+       \r
        TRACE_SR_ALLOC_CRITICAL_SECTION();\r
 \r
        if (! RecorderDataPtr->recorderActive ||  ! handle_of_last_logged_task)\r
@@ -652,24 +656,28 @@ void vTraceStoreISREnd(int pendingISR)
        }\r
 \r
        trcCRITICAL_SECTION_BEGIN();\r
-       if (pendingISR == 0)\r
+       isPendingContextSwitch |= pendingISR;   /* Is there a pending context switch right now? */\r
+       nISRactive--;\r
+       if (nISRactive > 0)\r
        {\r
-               uint8_t hnd8, type;\r
-               dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
-\r
-               if (nISRactive > 1)\r
-               {\r
-                       /* return to another isr */\r
-                       type = TS_ISR_RESUME;\r
-                       hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive]);\r
-               }\r
-               else\r
-               {\r
-                       /* return to task */\r
-                       type = TS_TASK_RESUME;\r
-                       hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);\r
-               }\r
+               /* Return to another isr */\r
+               type = TS_ISR_RESUME;\r
+               hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */\r
+       }\r
+       else if (isPendingContextSwitch == 0)\r
+       {\r
+               /* No context switch has been triggered by any ISR in the chain. Return to task */\r
+               type = TS_TASK_RESUME;\r
+               hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);\r
+       }\r
+       else\r
+       {\r
+               /* Context switch has been triggered by some ISR. We expect a proper context switch event shortly so we do nothing. */\r
+       }\r
 \r
+       if (type != 0)\r
+       {\r
+               dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
                ts = (TSEvent*)xTraceNextFreeEventBufferSlot();\r
                if (ts != NULL)\r
                {\r
@@ -684,7 +692,6 @@ void vTraceStoreISREnd(int pendingISR)
                ptrLastISRExitEvent = (uint8_t*)ts;\r
                #endif          \r
        }\r
-       nISRactive--;\r
 \r
        #if (SELECTED_PORT == PORT_ARM_CortexM)\r
        DWTCycleCountAtLastISRExit = REG_DWT_CYCCNT;\r
@@ -1251,7 +1258,7 @@ void vTraceChannelUserEvent(UserEventChannel channelPair)
  *\r
  * Calling xTraceOpenLabel multiple times will not create duplicate entries, but\r
  * it is of course faster to just do it once, and then keep the handle for later\r
- * use. If you don´t have any data arguments, only a text label/string, it is\r
+ * use. If you dont have any data arguments, only a text label/string, it is\r
  * better to use vTraceUserEvent - it is faster.\r
  *\r
  * Format specifiers supported:\r