1 /*
2 * Percepio DFM v2.1.0
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * DFM Retained Memory
9 */
10
11 #include <dfm.h>
12
13 #if (defined(DFM_CFG_ENABLED) && (DFM_CFG_ENABLED >= 1)) && (defined(DFM_CFG_RETAINED_MEMORY) && (DFM_CFG_RETAINED_MEMORY >= 1))
14
15 #include <dfmRetainedMemoryPort.h>
16
17 #define DFM_RETAINED_MEMORY_TYPE_ALERT 0x341562AB
18 #define DFM_RETAINED_MEMORY_TYPE_PAYLOAD 0xE78BAC01
19
20 static DfmRetainedMemoryData_t* pxRetainedMemoryData;
21
22 typedef struct DfmRetainedMemoryMetaData
23 {
24 uint32_t ulType;
25 uint32_t ulSize;
26 } DfmRetainedMemoryMetaData_t;
27
28 static DfmResult_t prvRetainedMemoryWrite(uint32_t ulType, DfmEntryHandle_t xEntryHandle);
29 static DfmResult_t prvRetainedMemoryRead(uint32_t ulType, void* pvBuffer, uint32_t ulBufferSize);
30
prvRetainedMemoryWrite(uint32_t ulType,DfmEntryHandle_t xEntryHandle)31 static DfmResult_t prvRetainedMemoryWrite(uint32_t ulType, DfmEntryHandle_t xEntryHandle)
32 {
33 DfmRetainedMemoryMetaData_t xRetainedMemoryMetaData;
34
35 if (pxRetainedMemoryData == (void*) 0)
36 {
37 return DFM_FAIL;
38 }
39
40 if (pxRetainedMemoryData->ulInitialized == 0)
41 {
42 return DFM_FAIL;
43 }
44
45 if (xEntryHandle == 0)
46 {
47 return DFM_FAIL;
48 }
49
50 xRetainedMemoryMetaData.ulType = ulType;
51 if (xDfmEntryGetSize(xEntryHandle, &xRetainedMemoryMetaData.ulSize) == DFM_FAIL)
52 {
53 return DFM_FAIL;
54 }
55
56 if (xRetainedMemoryMetaData.ulSize == 0)
57 {
58 return DFM_FAIL;
59 }
60
61 /* Write the meta data */
62 if (xDfmRetainedMemoryPortWrite((uint8_t*)&xRetainedMemoryMetaData, sizeof(DfmRetainedMemoryMetaData_t), pxRetainedMemoryData->ulWriteOffset) == DFM_FAIL)
63 {
64 return DFM_FAIL;
65 }
66
67 pxRetainedMemoryData->ulWriteOffset += sizeof(DfmRetainedMemoryMetaData_t);
68
69 /* Write the data */
70 if (xDfmRetainedMemoryPortWrite((uint8_t*)xEntryHandle, xRetainedMemoryMetaData.ulSize, pxRetainedMemoryData->ulWriteOffset) == DFM_FAIL)
71 {
72 return DFM_FAIL;
73 }
74
75 pxRetainedMemoryData->ulWriteOffset += xRetainedMemoryMetaData.ulSize;
76
77 return DFM_SUCCESS;
78 }
79
prvRetainedMemoryRead(uint32_t ulType,void * pvBuffer,uint32_t ulBufferSize)80 static DfmResult_t prvRetainedMemoryRead(uint32_t ulType, void* pvBuffer, uint32_t ulBufferSize)
81 {
82 DfmRetainedMemoryMetaData_t xRetainedMemoryMetaData;
83
84 /* Read the metadata */
85 if (xDfmRetainedMemoryPortRead(&xRetainedMemoryMetaData, sizeof(DfmRetainedMemoryMetaData_t), pxRetainedMemoryData->ulReadOffset) == DFM_FAIL)
86 {
87 return DFM_FAIL;
88 }
89
90 if (xRetainedMemoryMetaData.ulType != ulType)
91 {
92 return DFM_FAIL;
93 }
94
95 if (xRetainedMemoryMetaData.ulSize <= 0)
96 {
97 return DFM_FAIL;
98 }
99
100 if (xRetainedMemoryMetaData.ulSize > ulBufferSize)
101 {
102 return DFM_FAIL;
103 }
104
105 pxRetainedMemoryData->ulReadOffset += sizeof(DfmRetainedMemoryMetaData_t);
106
107 /* Read the data */
108 if (xDfmRetainedMemoryPortRead(pvBuffer, xRetainedMemoryMetaData.ulSize, pxRetainedMemoryData->ulReadOffset) != 0)
109 {
110 return DFM_FAIL;
111 }
112
113 pxRetainedMemoryData->ulReadOffset += xRetainedMemoryMetaData.ulSize;
114
115 return DFM_SUCCESS;
116 }
117
xDfmRetainedMemoryInitialize(DfmRetainedMemoryData_t * pxBuffer)118 DfmResult_t xDfmRetainedMemoryInitialize(DfmRetainedMemoryData_t *pxBuffer)
119 {
120 pxRetainedMemoryData = pxBuffer;
121
122 pxRetainedMemoryData->ulWriteOffset = 0;
123 pxRetainedMemoryData->ulReadOffset = 0;
124
125 if (xDfmRetainedMemoryPortInitialize(&pxRetainedMemoryData->xRetainedMemoryPortData) == DFM_FAIL)
126 {
127 return DFM_FAIL;
128 }
129
130 pxRetainedMemoryData->ulInitialized = 1;
131
132 return DFM_SUCCESS;
133 }
134
xDfmRetainedMemoryWriteAlert(DfmEntryHandle_t xEntryHandle)135 DfmResult_t xDfmRetainedMemoryWriteAlert(DfmEntryHandle_t xEntryHandle)
136 {
137 pxRetainedMemoryData->ulWriteOffset = 0;
138 pxRetainedMemoryData->ulReadOffset = 0;
139
140 if (xDfmRetainedMemoryPortClear() == DFM_FAIL)
141 {
142 return DFM_FAIL;
143 }
144
145 return prvRetainedMemoryWrite(DFM_RETAINED_MEMORY_TYPE_ALERT, xEntryHandle);
146 }
147
xDfmRetainedMemoryReadAlert(void * pvBuffer,uint32_t ulBufferSize)148 DfmResult_t xDfmRetainedMemoryReadAlert(void* pvBuffer, uint32_t ulBufferSize)
149 {
150 pxRetainedMemoryData->ulWriteOffset = 0;
151 pxRetainedMemoryData->ulReadOffset = 0;
152
153 /* We only check this on Read Alert since Read Payload will not be called if there is no Alert */
154 if (xDfmRetainedMemoryPortHasData() == 0)
155 {
156 return DFM_FAIL;
157 }
158
159 return prvRetainedMemoryRead(DFM_RETAINED_MEMORY_TYPE_ALERT, pvBuffer, ulBufferSize);
160 }
161
xDfmRetainedMemoryWritePayloadChunk(DfmEntryHandle_t xEntryHandle)162 DfmResult_t xDfmRetainedMemoryWritePayloadChunk(DfmEntryHandle_t xEntryHandle)
163 {
164 return prvRetainedMemoryWrite(DFM_RETAINED_MEMORY_TYPE_PAYLOAD, xEntryHandle);
165 }
166
xDfmRetainedMemoryReadPayloadChunk(char * szSessionId,uint32_t ulAlertId,void * pvBuffer,uint32_t ulBufferSize)167 DfmResult_t xDfmRetainedMemoryReadPayloadChunk(char* szSessionId, uint32_t ulAlertId, void* pvBuffer, uint32_t ulBufferSize)
168 {
169 (void)szSessionId;
170 (void)ulAlertId;
171
172 return prvRetainedMemoryRead(DFM_RETAINED_MEMORY_TYPE_PAYLOAD, pvBuffer, ulBufferSize);
173 }
174
xDfmRetainedMemoryClear(void)175 DfmResult_t xDfmRetainedMemoryClear(void)
176 {
177 return xDfmRetainedMemoryPortClear();
178 }
179
180 #endif
181