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 ISR tagging.
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 TraceISRInfo_t* pxTraceISRInfo;
18
xTraceISRInitialize(TraceISRInfoBuffer_t * pxBuffer)19 traceResult xTraceISRInitialize(TraceISRInfoBuffer_t *pxBuffer)
20 {
21 uint32_t uiCoreIndex;
22 uint32_t uiStackIndex;
23
24 TRC_ASSERT_EQUAL_SIZE(TraceISRInfoBuffer_t, TraceISRInfo_t);
25
26 /* This should never fail */
27 TRC_ASSERT(pxBuffer != 0);
28
29 pxTraceISRInfo = (TraceISRInfo_t*)pxBuffer;
30
31 for (uiCoreIndex = 0; uiCoreIndex < (TRC_CFG_CORE_COUNT); uiCoreIndex++)
32 {
33 TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[uiCoreIndex];
34
35 /* Initialize ISR stack */
36 for (uiStackIndex = 0; uiStackIndex < (TRC_CFG_MAX_ISR_NESTING); uiStackIndex++)
37 {
38 pxCoreInfo->handleStack[uiStackIndex] = 0;
39 }
40
41 pxCoreInfo->stackIndex = -1;
42 pxCoreInfo->isPendingContextSwitch = 0;
43 }
44
45 xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ISR);
46
47 return TRC_SUCCESS;
48 }
49
xTraceISRRegister(const char * szName,uint32_t uiPriority,TraceISRHandle_t * pxISRHandle)50 traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t *pxISRHandle)
51 {
52 TraceEntryHandle_t xEntryHandle;
53 TraceEventHandle_t xEventHandle = 0;
54 uint32_t i = 0, uiLength = 0, uiValue = 0;
55
56 /* We need to check this */
57 if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR))
58 {
59 return TRC_FAIL;
60 }
61
62 /* This should never fail */
63 TRC_ASSERT(pxISRHandle != 0);
64
65 if (szName == 0)
66 {
67 szName = "";
68 }
69
70 /* Always save in symbol table, in case the recording has not yet started */
71 /* We need to check this */
72 if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
73 {
74 return TRC_FAIL;
75 }
76
77 /* This should never fail */
78 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szName) == TRC_SUCCESS);
79
80 /* This should never fail */
81 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, 0, (TraceUnsignedBaseType_t)uiPriority) == TRC_SUCCESS);
82
83 *pxISRHandle = (TraceISRHandle_t)xEntryHandle;
84
85 for (i = 0; (szName[i] != 0) && (i < 128); i++) {}
86
87 uiLength = i;
88
89 /* We need to check this */
90 if (xTraceEventBegin(PSF_EVENT_DEFINE_ISR, uiLength + sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
91 {
92 xTraceEventAddPointer(xEventHandle, (void*)xEntryHandle);
93 xTraceEventAdd32(xEventHandle, uiPriority);
94 xTraceEventAddData(xEventHandle, (void*)szName, uiLength);
95
96 /* Check if we can truncate */
97 xTraceEventPayloadRemaining(xEventHandle, &uiValue);
98 if (uiValue > 0)
99 {
100 xTraceEventAdd8(xEventHandle, 0);
101 }
102
103 xTraceEventEnd(xEventHandle);
104 }
105
106 return TRC_SUCCESS;
107 }
108
xTraceISRBegin(TraceISRHandle_t xISRHandle)109 traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle)
110 {
111 TraceEventHandle_t xEventHandle = 0;
112 TraceISRCoreInfo_t* pxCoreInfo;
113 TRACE_ALLOC_CRITICAL_SECTION();
114
115 (void)xEventHandle;
116
117 /* This should never fail */
118 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
119
120 TRACE_ENTER_CRITICAL_SECTION();
121
122 /* We are at the start of a possible ISR chain.
123 * No context switches should have been triggered now.
124 */
125 pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
126
127 if (pxCoreInfo->stackIndex == -1)
128 {
129 pxCoreInfo->isPendingContextSwitch = 0;
130 }
131
132 if (pxCoreInfo->stackIndex < (TRC_CFG_MAX_ISR_NESTING) - 1)
133 {
134 pxCoreInfo->stackIndex++;
135 pxCoreInfo->handleStack[pxCoreInfo->stackIndex] = xISRHandle;
136
137 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
138 /* We need to check this */
139 if (xTraceEventBegin(PSF_EVENT_ISR_BEGIN, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
140 {
141 xTraceEventAddPointer(xEventHandle, (void*)xISRHandle);
142 xTraceEventEnd(xEventHandle);
143 }
144 #endif
145 }
146 else
147 {
148 TRACE_EXIT_CRITICAL_SECTION();
149
150 xTraceError(TRC_ERROR_ISR_NESTING_OVERFLOW);
151
152 return TRC_FAIL;
153 }
154
155 TRACE_EXIT_CRITICAL_SECTION();
156
157 return TRC_SUCCESS;
158 }
159
xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)160 traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)
161 {
162 TraceEventHandle_t xEventHandle = 0;
163 TraceISRCoreInfo_t* pxCoreInfo;
164 TRACE_ALLOC_CRITICAL_SECTION();
165
166 (void)xEventHandle;
167
168 /* This should never fail */
169 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
170
171 TRACE_ENTER_CRITICAL_SECTION();
172
173 pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
174
175 /* Is there a pending task-switch? (perhaps from an earlier ISR) */
176 pxCoreInfo->isPendingContextSwitch |= xIsTaskSwitchRequired;
177
178 if (pxCoreInfo->stackIndex > 0)
179 {
180 pxCoreInfo->stackIndex--;
181
182 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
183 /* Store return to interrupted ISR (if nested ISRs)*/
184 /* We need to check this */
185 if (xTraceEventBegin(PSF_EVENT_ISR_RESUME, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
186 {
187 xTraceEventAddPointer(xEventHandle, (void*)pxCoreInfo->handleStack[pxCoreInfo->stackIndex]);
188 xTraceEventEnd(xEventHandle);
189 }
190 #endif
191 }
192 else
193 {
194 pxCoreInfo->stackIndex--;
195
196 /* Store return to interrupted task, if no context switch will occur in between. */
197 if ((pxCoreInfo->isPendingContextSwitch == 0) || (xTraceKernelPortIsSchedulerSuspended()))
198 {
199 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
200 /* We need to check this */
201 if (xTraceEventBegin(PSF_EVENT_TASK_ACTIVATE, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
202 {
203 void *pvCurrentTask = 0;
204
205 xTraceTaskGetCurrent(&pvCurrentTask);
206 xTraceEventAddPointer(xEventHandle, pvCurrentTask);
207 xTraceEventEnd(xEventHandle);
208 }
209 #endif
210 }
211 }
212
213 TRACE_EXIT_CRITICAL_SECTION();
214
215 return TRC_SUCCESS;
216 }
217
218 #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
219
xTraceISRGetCurrentNesting(int32_t * puiValue)220 traceResult xTraceISRGetCurrentNesting(int32_t* puiValue)
221 {
222 /* This should never fail */
223 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
224
225 /* This should never fail */
226 TRC_ASSERT(puiValue != 0);
227
228 TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
229 *puiValue = pxCoreInfo->stackIndex;
230
231 return TRC_SUCCESS;
232 }
233
xTraceISRGetCurrentNestingReturned(void)234 int32_t xTraceISRGetCurrentNestingReturned(void)
235 {
236 /* This should never fail */
237 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
238
239 return pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()].stackIndex;
240 }
241
xTraceISRGetCurrent(TraceISRHandle_t * pxISRHandle)242 traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle)
243 {
244 /* This should never fail */
245 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
246
247 /* This should never fail */
248 TRC_ASSERT(pxISRHandle != 0);
249
250 TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
251
252 if (pxCoreInfo->stackIndex < 0)
253 {
254 return TRC_FAIL;
255 }
256
257 *pxISRHandle = pxCoreInfo->handleStack[pxCoreInfo->stackIndex];
258
259 return TRC_SUCCESS;
260 }
261
262 #endif
263
264 /* DEPRECATED */
xTraceSetISRProperties(const char * szName,uint32_t uiPriority)265 TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority)
266 {
267 TraceISRHandle_t xISRHandle = 0;
268
269 xTraceISRRegister(szName, uiPriority, &xISRHandle);
270
271 return xISRHandle;
272 }
273
274 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
275
276 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
277