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