]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/FreeRTOS-Plus-Trace/Include/trcHooks.h
544c4e37cfb7b81b156491511a2535d922b794fe
[freertos] / FreeRTOS-Plus / FreeRTOS-Plus-Trace / Include / trcHooks.h
1 /*******************************************************************************\r
2  * FreeRTOS+Trace v2.2.3 Recorder Library\r
3  * Percepio AB, www.percepio.se\r
4  *\r
5  * trcHooks.h\r
6  *\r
7  * The kernel integration hooks for FreeRTOS (v7.1.0 or later). This file should\r
8  * be included in the end of FreeRTOSConfig.h, together with:\r
9  *\r
10  * #define configUSE_TRACE_FACILITY 1\r
11  *\r
12  * NOTE: \r
13  * For IAR Embedded Workbench for ARM, you need to have a preprocessor condition\r
14  * on the include, to except it from the assembler step which otherwise give\r
15  * compile-time errors.\r
16  *\r
17  * #ifdef __ICCARM__\r
18  *       #include "percepio/Include/trcHooks.h"\r
19  * #endif\r
20  * \r
21  * Terms of Use\r
22  * This software is copyright Percepio AB. The recorder library is free for\r
23  * use together with Percepio products. You may distribute the recorder library\r
24  * in its original form, including modifications in trcPort.c and trcPort.h\r
25  * given that these modification are clearly marked as your own modifications\r
26  * and documented in the initial comment section of these source files. \r
27  * This software is the intellectual property of Percepio AB and may not be \r
28  * sold or in other ways commercially redistributed without explicit written \r
29  * permission by Percepio AB.\r
30  *\r
31  * Disclaimer \r
32  * The trace tool and recorder library is being delivered to you AS IS and \r
33  * Percepio AB makes no warranty as to its use or performance. Percepio AB does \r
34  * not and cannot warrant the performance or results you may obtain by using the \r
35  * software or documentation. Percepio AB make no warranties, express or \r
36  * implied, as to noninfringement of third party rights, merchantability, or \r
37  * fitness for any particular purpose. In no event will Percepio AB, its \r
38  * technology partners, or distributors be liable to you for any consequential, \r
39  * incidental or special damages, including any lost profits or lost savings, \r
40  * even if a representative of Percepio AB has been advised of the possibility \r
41  * of such damages, or for any claim by any third party. Some jurisdictions do \r
42  * not allow the exclusion or limitation of incidental, consequential or special \r
43  * damages, or the exclusion of implied warranties or limitations on how long an \r
44  * implied warranty may last, so the above limitations may not apply to you.\r
45  *\r
46  * FreeRTOS+Trace is available as Free Edition and in two premium editions.\r
47  * You may use the premium features during 30 days for evaluation.\r
48  * Download FreeRTOS+Trace at http://www.percepio.se/index.php?page=downloads\r
49  *\r
50  * Copyright Percepio AB, 2012.\r
51  * www.percepio.se\r
52  ******************************************************************************/\r
53 \r
54 #ifndef TRCHOOKS_H\r
55 #define TRCHOOKS_H\r
56 \r
57 #include "trcKernel.h"\r
58 \r
59 #if (configUSE_TRACE_FACILITY == 1)\r
60 \r
61     #define INCLUDE_xTaskGetSchedulerState 1\r
62     #define INCLUDE_xTaskGetCurrentTaskHandle 1\r
63 \r
64     /* Called on each OS tick */\r
65     #undef traceTASK_INCREMENT_TICK\r
66     #define traceTASK_INCREMENT_TICK( xTickCount ) \\r
67       {extern uint32_t uiTraceTickCount; uiTraceTickCount = xTickCount;}\r
68 \r
69     /* Called on each task-switch */\r
70     #undef traceTASK_SWITCHED_IN\r
71     #define traceTASK_SWITCHED_IN() \\r
72       vTraceStoreTaskswitch();\r
73 \r
74     /* Called on vTaskSuspend */\r
75     #undef traceTASK_SUSPEND\r
76     #define traceTASK_SUSPEND( pxTaskToSuspend ) \\r
77       vTraceStoreKernelCall(TASK_SUSPEND, pxTaskToSuspend->uxTaskNumber); \\r
78       vTraceSetTaskInstanceFinished((uint8_t)pxTaskToSuspend->uxTaskNumber);\r
79 \r
80     /* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */\r
81     #undef traceTASK_DELAY\r
82     #define traceTASK_DELAY() \\r
83       portENTER_CRITICAL(); \\r
84       vTraceStoreKernelCallWithNumericParamOnly(TASK_DELAY, (uint16_t)xTicksToDelay);\\r
85       vTraceSetTaskInstanceFinished((uint8_t)pxCurrentTCB->uxTaskNumber);\\r
86       portEXIT_CRITICAL();\r
87 \r
88     /* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */\r
89     #undef traceTASK_DELAY_UNTIL\r
90     #define traceTASK_DELAY_UNTIL() \\r
91       portENTER_CRITICAL(); \\r
92       vTraceStoreKernelCallWithNumericParamOnly(TASK_DELAY_UNTIL, (uint16_t)xTimeToWake); \\r
93       vTraceSetTaskInstanceFinished((uint8_t)pxCurrentTCB->uxTaskNumber); \\r
94       portEXIT_CRITICAL();\r
95 \r
96 #if (INCLUDE_OBJECT_DELETE == 1)\r
97     /* Called on vTaskDelete */\r
98     #undef traceTASK_DELETE\r
99     #define traceTASK_DELETE( pxTaskToDelete ) \\r
100       vTraceStoreKernelCall(EVENTGROUP_DELETE + TRACE_CLASS_TASK, pxTaskToDelete->uxTaskNumber); \\r
101       vTraceStoreObjectNameOnCloseEvent((objectHandleType)pxTaskToDelete->uxTaskNumber, TRACE_CLASS_TASK); \\r
102       vTraceStoreObjectPropertiesOnCloseEvent((objectHandleType)pxTaskToDelete->uxTaskNumber, TRACE_CLASS_TASK); \\r
103       vTraceSetPriorityProperty(TRACE_CLASS_TASK, (objectHandleType)pxTaskToDelete->uxTaskNumber, (uint8_t)pxTaskToDelete->uxPriority); \\r
104       vTraceSetObjectState(TRACE_CLASS_TASK, (objectHandleType)pxTaskToDelete->uxTaskNumber, TASK_STATE_INSTANCE_NOT_ACTIVE); \\r
105       vTraceFreeObjectHandle(TRACE_CLASS_TASK, (objectHandleType)pxTaskToDelete->uxTaskNumber);\r
106 #endif\r
107 \r
108     /* Called on vTaskCreate */\r
109     #undef traceTASK_CREATE\r
110     #define traceTASK_CREATE( pxNewTCB ) \\r
111       if (pxNewTCB != NULL){ \\r
112           pxNewTCB->uxTaskNumber = xTraceGetObjectHandle(TRACE_CLASS_TASK); \\r
113           vTraceSetObjectName(TRACE_CLASS_TASK, (objectHandleType)pxNewTCB->uxTaskNumber, (char*)pxNewTCB->pcTaskName); \\r
114           vTraceSetPriorityProperty(TRACE_CLASS_TASK, (objectHandleType)pxNewTCB->uxTaskNumber, (uint8_t)pxNewTCB->uxPriority); \\r
115           vTraceStoreKernelCall(EVENTGROUP_CREATE + TRACE_CLASS_TASK, (objectHandleType)pxNewTCB->uxTaskNumber);\\r
116       }\r
117 \r
118     /* Called in vTaskCreate, if it fails (typically if the stack fails can not be allocated) */\r
119     #undef traceTASK_CREATE_FAILED\r
120     #define traceTASK_CREATE_FAILED() \\r
121       portENTER_CRITICAL();\\r
122       vTraceStoreKernelCall(EVENTGROUP_FAILED_CREATE + TRACE_CLASS_TASK, 0); \\r
123       portEXIT_CRITICAL();\r
124 \r
125     /* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */\r
126     #undef traceQUEUE_CREATE\r
127     #define traceQUEUE_CREATE( pxNewQueue )\\r
128         portENTER_CRITICAL(); \\r
129         pxNewQueue->ucQueueNumber = xTraceGetObjectHandle(TraceObjectClassTable[pxNewQueue->ucQueueType]);\\r
130         vTraceSetObjectState(TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber, 0); \\r
131         vTraceStoreKernelCall(EVENTGROUP_CREATE + TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber); \\r
132         portEXIT_CRITICAL();\r
133 \r
134     /* Called in xQueueCreate, if the queue creation fails */\r
135     #undef traceQUEUE_CREATE_FAILED\r
136     #define traceQUEUE_CREATE_FAILED( queueType ) \\r
137         portENTER_CRITICAL();\\r
138         vTraceStoreKernelCall((uint8_t)(EVENTGROUP_FAILED_CREATE + TraceObjectClassTable[queueType]), (objectHandleType)0); \\r
139         portEXIT_CRITICAL();\r
140     \r
141     /* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */\r
142     #undef traceCREATE_MUTEX\r
143     #define traceCREATE_MUTEX( pxNewQueue ) \\r
144       portENTER_CRITICAL();\\r
145       pxNewQueue->ucQueueNumber = xTraceGetObjectHandle(TRACE_CLASS_MUTEX); \\r
146       vTraceStoreKernelCall(EVENTGROUP_CREATE + TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber); \\r
147       vTraceSetObjectState(TRACE_CLASS_MUTEX, pxNewQueue->ucQueueNumber, 0); \\r
148       portEXIT_CRITICAL();\r
149 \r
150     /* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */\r
151     #undef traceCREATE_MUTEX_FAILED\r
152     #define traceCREATE_MUTEX_FAILED() \\r
153         portENTER_CRITICAL();\\r
154         vTraceStoreKernelCall(EVENTGROUP_FAILED_CREATE + TRACE_CLASS_MUTEX, 0);\\r
155         portEXIT_CRITICAL();\r
156 \r
157     /* Called when the Mutex can not be given, since not holder */\r
158     #undef traceGIVE_MUTEX_RECURSIVE_FAILED\r
159     #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \\r
160         portENTER_CRITICAL();\\r
161         vTraceStoreKernelCall(EVENTGROUP_FAILED_SEND + TRACE_CLASS_MUTEX, pxMutex->ucQueueNumber); \\r
162         portEXIT_CRITICAL();\r
163 \r
164     /* Called when a message is sent to a queue */\r
165     #undef traceQUEUE_SEND\r
166     #define traceQUEUE_SEND( pxQueue ) \\r
167       vTraceStoreKernelCall(EVENTGROUP_SEND + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
168       if (TraceObjectClassTable[pxQueue->ucQueueType] == TRACE_CLASS_MUTEX){\\r
169           vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (uint8_t)pxQueue->ucQueueNumber, (uint8_t)0); \\r
170       }else{\\r
171           vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (uint8_t)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); \\r
172       }\r
173 \r
174     /* Called when a message failed to be sent to a queue (timeout) */\r
175     #undef traceQUEUE_SEND_FAILED\r
176     #define traceQUEUE_SEND_FAILED( pxQueue ) \\r
177       portENTER_CRITICAL();\\r
178       vTraceStoreKernelCall(EVENTGROUP_FAILED_SEND + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
179       portEXIT_CRITICAL();\r
180 \r
181     /* Called when the task is blocked due to a send operation on a full queue */\r
182     #undef traceBLOCKING_ON_QUEUE_SEND\r
183     #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \\r
184       portENTER_CRITICAL();\\r
185       vTraceStoreKernelCall(EVENTGROUP_BLOCK_ON_SEND + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
186       portEXIT_CRITICAL();\r
187                 \r
188     /* Called when a message is received from a queue */\r
189     #undef traceQUEUE_RECEIVE\r
190     #define traceQUEUE_RECEIVE( pxQueue ) \\r
191       vTraceStoreKernelCall(EVENTGROUP_RECEIVE + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
192       if (TraceObjectClassTable[pxQueue->ucQueueType] == TRACE_CLASS_MUTEX){\\r
193           extern volatile void * volatile pxCurrentTCB; \\r
194           vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (objectHandleType)uxTaskGetTaskNumber((xTaskHandle)pxCurrentTCB)); /*For mutex, store the new owner rather than queue length */ \\r
195       }else{\\r
196           vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting - 1)); \\r
197       }\r
198         \r
199     /* Called when the task is blocked due to a receive operation on an empty queue */\r
200     #undef traceBLOCKING_ON_QUEUE_RECEIVE\r
201     #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \\r
202       portENTER_CRITICAL(); \\r
203       vTraceStoreKernelCall(EVENTGROUP_BLOCK_ON_RECEIVE + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
204       if (TraceObjectClassTable[pxQueue->ucQueueType] != TRACE_CLASS_MUTEX){\\r
205           extern volatile void * volatile pxCurrentTCB; \\r
206           vTraceSetTaskInstanceFinished((objectHandleType)uxTaskGetTaskNumber((xTaskHandle)pxCurrentTCB)); \\r
207       }\\r
208       portEXIT_CRITICAL();\r
209 \r
210     /* Called on xQueuePeek */\r
211     #undef traceQUEUE_PEEK\r
212     #define traceQUEUE_PEEK( pxQueue ) \\r
213         vTraceStoreKernelCall(EVENTGROUP_PEEK + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber);\r
214 \r
215     /* Called when a receive operation on a queue fails (timeout) */\r
216     #undef traceQUEUE_RECEIVE_FAILED\r
217     #define traceQUEUE_RECEIVE_FAILED( pxQueue ) \\r
218       portENTER_CRITICAL(); \\r
219       vTraceStoreKernelCall(EVENTGROUP_FAILED_RECEIVE + TraceObjectClassTable[pxQueue->ucQueueType],  pxQueue->ucQueueNumber); \\r
220       portEXIT_CRITICAL();\r
221         \r
222     /* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */\r
223     #undef traceQUEUE_SEND_FROM_ISR\r
224     #define traceQUEUE_SEND_FROM_ISR( pxQueue ) \\r
225       vTraceStoreKernelCall(EVENTGROUP_SEND_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
226       vTraceSetObjectState(TRACE_CLASS_QUEUE, (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting + 1));\r
227 \r
228     /* Called when a message send from interrupt context fails (since the queue was full) */\r
229     #undef traceQUEUE_SEND_FROM_ISR_FAILED\r
230     #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \\r
231       vTraceStoreKernelCall(EVENTGROUP_FAILED_SEND_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber);\r
232 \r
233     /* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */\r
234     #undef traceQUEUE_RECEIVE_FROM_ISR\r
235     #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \\r
236       vTraceStoreKernelCall(EVENTGROUP_RECEIVE_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
237       vTraceSetObjectState(TRACE_CLASS_QUEUE, (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting - 1));\r
238     \r
239     /* Called when a message receive from interrupt context fails (since the queue was empty) */\r
240     #undef traceQUEUE_RECEIVE_FROM_ISR_FAILED\r
241     #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \\r
242       vTraceStoreKernelCall(EVENTGROUP_FAILED_RECEIVE_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber);\r
243 \r
244 #if (INCLUDE_OBJECT_DELETE == 1)\r
245     /* Called on vQueueDelete */\r
246     #undef traceQUEUE_DELETE\r
247     #define traceQUEUE_DELETE( pxQueue ) \\r
248     { \\r
249         portENTER_CRITICAL();\\r
250         vTraceStoreKernelCall(EVENTGROUP_DELETE + TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \\r
251         vTraceStoreObjectNameOnCloseEvent((objectHandleType)pxQueue->ucQueueNumber, TraceObjectClassTable[pxQueue->ucQueueType]); \\r
252         vTraceStoreObjectPropertiesOnCloseEvent((objectHandleType)pxQueue->ucQueueNumber, TraceObjectClassTable[pxQueue->ucQueueType]); \\r
253         if (TraceObjectClassTable[pxQueue->ucQueueType] == TRACE_CLASS_MUTEX){ \\r
254             vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (objectHandleType)uxTaskGetTaskNumber((xTaskHandle)pxQueue->pxMutexHolder)); \\r
255         }else{ \\r
256             vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)uxQueueMessagesWaiting(pxQueue)); \\r
257         } \\r
258         vTraceFreeObjectHandle(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber); \\r
259         portEXIT_CRITICAL();\\r
260     }\r
261 #endif\r
262     \r
263     /* Called in vTaskPrioritySet */\r
264     #undef traceTASK_PRIORITY_SET\r
265     #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \\r
266       vTraceStoreKernelCallWithParam(TASK_PRIORITY_SET, pxTask->uxTaskNumber, uiTraceGetPriorityProperty(TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber));\\r
267       vTraceSetPriorityProperty( TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber, (uint8_t)uxNewPriority);\r
268 \r
269     /* Called in vTaskPriorityInherit, which is called by Mutex operations */\r
270     #undef traceTASK_PRIORITY_INHERIT\r
271     #define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \\r
272       vTraceStoreKernelCallWithParam(TASK_PRIORITY_INHERIT, pxTask->uxTaskNumber, uiTraceGetPriorityProperty(TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber));\\r
273       vTraceSetPriorityProperty( TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber, (uint8_t)uxNewPriority );\r
274 \r
275     /* Called in vTaskPriorityDisinherit, which is called by Mutex operations */\r
276     #undef traceTASK_PRIORITY_DISINHERIT\r
277     #define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \\r
278       vTraceStoreKernelCallWithParam(TASK_PRIORITY_DISINHERIT, pxTask->uxTaskNumber, uiTraceGetPriorityProperty(TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber));\\r
279       vTraceSetPriorityProperty( TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber, (uint8_t)uxNewPriority );\r
280 \r
281     /* Called in vTaskResume */\r
282     #undef traceTASK_RESUME\r
283     #define traceTASK_RESUME( pxTaskToResume ) \\r
284       vTraceStoreKernelCall(TASK_RESUME, pxTaskToResume->uxTaskNumber);\r
285 \r
286     /* Called in vTaskResumeFromISR */\r
287     #undef traceTASK_RESUME_FROM_ISR\r
288     #define traceTASK_RESUME_FROM_ISR( pxTaskToResume )\\r
289       vTraceStoreKernelCall(TASK_RESUME_FROM_ISR, pxTaskToResume->uxTaskNumber);\r
290 \r
291 #endif\r
292 #endif