summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcCounter.c
blob: 4c9f455d3001bdce65002cb4af68e4e8d8255c97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of intervals.
*/

#include <trcRecorder.h>

#if (TRC_USE_TRACEALYZER_RECORDER == 1)

#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)

#define TRC_COUNTER_VALUE_INDEX 0
#define TRC_COUNTER_LOWER_LIMIT_INDEX 1
#define TRC_COUNTER_UPPER_LIMIT_INDEX 2

static TraceCounterCallback_t xCallbackFunction;

traceResult xTraceCounterSetCallback(TraceCounterCallback_t xCallback)
{
	TRC_ASSERT(xCallback != 0);

	xCallbackFunction = xCallback;

	/* We only set this component as initialized when the callback has been set */
	xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER);

	return TRC_SUCCESS;
}

traceResult xTraceCounterCreate(const char *szName, TraceBaseType_t xInitialValue, TraceBaseType_t xLowerLimit, TraceBaseType_t xUpperLimit, TraceCounterHandle_t *pxCounterHandle)
{
	TraceObjectHandle_t xObjectHandle;
	TraceUnsignedBaseType_t uxStates[3];

	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	/* This should never fail */
	TRC_ASSERT(pxCounterHandle != 0);

	TRC_ASSERT(xInitialValue >= xLowerLimit && xInitialValue <= xUpperLimit);

	uxStates[TRC_COUNTER_VALUE_INDEX] = xInitialValue;
	uxStates[TRC_COUNTER_LOWER_LIMIT_INDEX] = xLowerLimit;
	uxStates[TRC_COUNTER_UPPER_LIMIT_INDEX] = xUpperLimit;

	/* We need to check this */
	if (xTraceObjectRegisterInternal(PSF_EVENT_COUNTER_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_COUNTER, &xObjectHandle) == TRC_FAIL)
	{
		return TRC_FAIL;
	}

	*pxCounterHandle = (TraceIntervalHandle_t)xObjectHandle;
	
	return TRC_SUCCESS;
}

traceResult xTraceCounterIncrease(TraceCounterHandle_t xCounterHandle)
{
	return xTraceCounterAdd(xCounterHandle, 1);
}
traceResult xTraceCounterDecrease(TraceCounterHandle_t xCounterHandle)
{
	return xTraceCounterAdd(xCounterHandle, -1);
}

traceResult xTraceCounterAdd(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue)
{
	TraceBaseType_t xCurrent;

	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	/* This should never fail */
	TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGet(xCounterHandle, &xCurrent) == TRC_SUCCESS);

	/* This should never fail */
	TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterSet(xCounterHandle, xCurrent + xValue) == TRC_SUCCESS);

	return TRC_SUCCESS;
}

traceResult xTraceCounterSet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue)
{
	TraceEventHandle_t xEventHandle = 0;
	TraceBaseType_t xLowerLimit;
	TraceBaseType_t xUpperLimit;

	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	/* This should never fail */
	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_VALUE_INDEX, (TraceUnsignedBaseType_t)xValue) == TRC_SUCCESS);

	/* We need to check this */
	if (xTraceEventBegin(PSF_EVENT_COUNTER_CHANGE, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
	{
		xTraceEventAddPointer(xEventHandle, (void*)xCounterHandle);
		xTraceEventAdd32(xEventHandle, (TraceUnsignedBaseType_t)xValue);
		xTraceEventEnd(xEventHandle);
	}

	/* This should never fail */
	TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGetLowerLimit(xCounterHandle, &xLowerLimit) == TRC_SUCCESS);

	if (xValue < xLowerLimit)
	{
		xCallbackFunction(xCounterHandle);
	}

	/* This should never fail */
	TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGetUpperLimit(xCounterHandle, &xUpperLimit) == TRC_SUCCESS);

	if (xValue > xUpperLimit)
	{
		xCallbackFunction(xCounterHandle);
	}

	return TRC_SUCCESS;
}

traceResult xTraceCounterGet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue)
{
	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	return xTraceEntryGetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_VALUE_INDEX, (TraceUnsignedBaseType_t*)pxValue);
}

traceResult xTraceCounterGetUpperLimit(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue)
{
	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	return xTraceEntryGetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_UPPER_LIMIT_INDEX, (TraceUnsignedBaseType_t*)pxValue);
}

traceResult xTraceCounterGetLowerLimit(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue)
{
	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	return xTraceEntryGetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_LOWER_LIMIT_INDEX, (TraceUnsignedBaseType_t*)pxValue);
}

traceResult xTraceCounterGetName(TraceCounterHandle_t xCounterHandle, const char** pszName)
{
	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER));

	return xTraceEntryGetSymbol((TraceEntryHandle_t)xCounterHandle, pszName);
}

#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */

#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */