1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.6.6
3 * Copyright 2021 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for tasks.
9 */
10
11 #include <trcRecorder.h>
12
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1)
14
15 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
16
17 /* Code used for "task address" when no task has started, to indicate "(startup)".
18 * This value was used since NULL/0 was already reserved for the idle task. */
19 #define TRACE_HANDLE_NO_TASK ((void*)2)
20
21 #define TRC_TASK_STATE_INDEX_PRIORITY 0
22 #define TRC_TASK_STATE_INDEX_UNUSED_STACK 1
23
24 TraceTaskInfo_t* pxTraceTaskInfo;
25
xTraceTaskInitialize(TraceTaskInfoBuffer_t * pxBuffer)26 traceResult xTraceTaskInitialize(TraceTaskInfoBuffer_t *pxBuffer)
27 {
28 uint32_t i;
29
30 TRC_ASSERT_EQUAL_SIZE(TraceTaskInfoBuffer_t, TraceTaskInfo_t);
31
32 /* This should never fail */
33 TRC_ASSERT(pxBuffer != 0);
34
35 pxTraceTaskInfo = (TraceTaskInfo_t*)pxBuffer;
36
37 for (i = 0; i < TRC_CFG_CORE_COUNT; i++)
38 {
39 pxTraceTaskInfo->coreTasks[i] = TRACE_HANDLE_NO_TASK;
40 }
41
42 xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_TASK);
43
44 return TRC_SUCCESS;
45 }
46
xTraceTaskUnregister(TraceTaskHandle_t xTaskHandle,TraceUnsignedBaseType_t uxPriority)47 traceResult xTraceTaskUnregister(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority)
48 {
49 void* pvTask;
50
51 /* This should never fail */
52 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xTaskHandle, &pvTask) == TRC_SUCCESS);
53
54 xTraceStackMonitorRemove(pvTask);
55
56 return xTraceObjectUnregister((TraceObjectHandle_t)xTaskHandle, PSF_EVENT_TASK_DELETE, uxPriority);
57 }
58
xTraceTaskSetPriority(TraceTaskHandle_t xTaskHandle,TraceUnsignedBaseType_t uxPriority)59 traceResult xTraceTaskSetPriority(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority)
60 {
61 TraceEventHandle_t xEventHandle = 0;
62 void *pvTask;
63
64 /* This should never fail */
65 TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetState((TraceObjectHandle_t)xTaskHandle, uxPriority) == TRC_SUCCESS);
66
67 /* This should never fail */
68 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xTaskHandle, &pvTask) == TRC_SUCCESS);
69
70 /* We need to check this */
71 if (xTraceEventBegin(PSF_EVENT_TASK_PRIORITY, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
72 {
73 xTraceEventAddPointer(xEventHandle, pvTask);
74 xTraceEventAdd32(xEventHandle, (uint32_t)uxPriority);
75 xTraceEventEnd(xEventHandle);
76 }
77
78 return TRC_SUCCESS;
79 }
80
xTraceTaskSetPriorityWithoutHandle(void * pvTask,TraceUnsignedBaseType_t uxPriority)81 traceResult xTraceTaskSetPriorityWithoutHandle(void* pvTask, TraceUnsignedBaseType_t uxPriority)
82 {
83 TraceEventHandle_t xEventHandle = 0;
84 TraceEntryHandle_t xEntryHandle;
85
86 if (xTraceEntryFind(pvTask, &xEntryHandle) == TRC_FAIL)
87 {
88 return TRC_FAIL;
89 }
90
91 /* This should never fail */
92 TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetState((TraceObjectHandle_t)xEntryHandle, uxPriority) == TRC_SUCCESS);
93
94 /* We need to check this */
95 if (xTraceEventBegin(PSF_EVENT_TASK_PRIORITY, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
96 {
97 xTraceEventAddPointer(xEventHandle, pvTask);
98 xTraceEventAdd32(xEventHandle, (uint32_t)uxPriority);
99 xTraceEventEnd(xEventHandle);
100 }
101
102 return TRC_SUCCESS;
103 }
104
xTraceTaskSwitch(void * pvTask,TraceUnsignedBaseType_t uxPriority)105 traceResult xTraceTaskSwitch(void *pvTask, TraceUnsignedBaseType_t uxPriority)
106 {
107 traceResult xResult = TRC_FAIL;
108 TraceEventHandle_t xEventHandle = 0;
109 void* pvCurrent = 0;
110
111 TRACE_ALLOC_CRITICAL_SECTION();
112
113 (void)pvTask;
114 (void)uxPriority;
115
116 if (xTraceIsRecorderEnabled() == 0)
117 {
118 return xResult;
119 }
120
121 TRACE_ENTER_CRITICAL_SECTION();
122
123 xTraceStateSet(TRC_STATE_IN_TASKSWITCH);
124
125 xTraceTaskGetCurrent(&pvCurrent);
126 if (pvCurrent != pvTask)
127 {
128 xTraceTaskSetCurrent(pvTask);
129
130 if (xTraceEventBegin(PSF_EVENT_TASK_ACTIVATE, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
131 {
132 xTraceEventAddPointer(xEventHandle, pvTask);
133 xTraceEventAdd32(xEventHandle, (uint32_t)uxPriority);
134 xTraceEventEnd(xEventHandle);
135 xResult = TRC_SUCCESS;
136 }
137 }
138
139 xTraceStateSet(TRC_STATE_IN_APPLICATION);
140
141 TRACE_EXIT_CRITICAL_SECTION();
142
143 return xResult;
144 }
145
146 #if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
xTraceTaskReady(void * pvTask)147 traceResult xTraceTaskReady(void *pvTask)
148 {
149 traceResult xResult = TRC_FAIL;
150 TraceEventHandle_t xEventHandle = 0;
151
152 if (xTraceEventBegin(PSF_EVENT_TASK_READY, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
153 {
154 xTraceEventAddPointer(xEventHandle, pvTask);
155 xTraceEventEnd(xEventHandle);
156 xResult = TRC_SUCCESS;
157 }
158
159 return xResult;
160 }
161 #endif /* (TRC_CFG_INCLUDE_READY_EVENTS == 1) */
162
xTraceTaskInstanceFinishedNow(void)163 traceResult xTraceTaskInstanceFinishedNow(void)
164 {
165 TraceEventHandle_t xEventHandle = 0;
166
167 if (xTraceEventBegin(PSF_EVENT_IFE_DIRECT, 0, &xEventHandle) == TRC_FAIL)
168 {
169 return TRC_FAIL;
170 }
171
172 xTraceEventEnd(xEventHandle);
173
174 return TRC_SUCCESS;
175 }
176
xTraceTaskInstanceFinishedNext(void)177 traceResult xTraceTaskInstanceFinishedNext(void)
178 {
179 TraceEventHandle_t xEventHandle = 0;
180
181 if (xTraceEventBegin(PSF_EVENT_IFE_NEXT, 0, &xEventHandle) == TRC_FAIL)
182 {
183 return TRC_FAIL;
184 }
185
186 xTraceEventEnd(xEventHandle);
187
188 return TRC_SUCCESS;
189 }
190
191 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
192
193 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
194