5
5
//!
6
6
//! @brief
7
7
//! Memfault SDK self test functions to verify SDK integration
8
+
8
9
#include <ctype.h>
10
+ #include <inttypes.h>
9
11
#include <stdbool.h>
10
12
#include <string.h>
11
13
12
14
#include "memfault/core/build_info.h"
15
+ #include "memfault/core/data_export.h"
13
16
#include "memfault/core/debug_log.h"
17
+ #include "memfault/core/event_storage.h"
14
18
#include "memfault/core/math.h"
15
19
#include "memfault/core/platform/device_info.h"
20
+ #include "memfault/core/reboot_tracking.h"
16
21
#include "memfault/core/self_test.h"
17
- #include "memfault_reboot_tracking_private.h"
22
+ #include "memfault/core/trace_event.h"
23
+ #include "memfault/panics/coredump.h"
24
+ #include "memfault/panics/coredump_impl.h"
18
25
#include "memfault_self_test_private.h"
19
26
20
27
typedef enum {
@@ -112,7 +119,7 @@ static uint32_t prv_validate_device_info(void) {
112
119
}
113
120
114
121
static uint32_t prv_validate_build_id (void ) {
115
- char build_id_str [(MEMFAULT_BUILD_ID_LEN * 2 ) + 1 ] = {0 };
122
+ char build_id_str [(MEMFAULT_BUILD_ID_LEN * 2 ) + 1 ] = { 0 };
116
123
uint32_t result = 0 ;
117
124
118
125
if (!memfault_build_id_get_string (build_id_str , MEMFAULT_ARRAY_SIZE (build_id_str ))) {
@@ -123,8 +130,7 @@ static uint32_t prv_validate_build_id(void) {
123
130
}
124
131
125
132
static void prv_device_info_test_describe (uint32_t results ) {
126
- MEMFAULT_LOG_INFO ("Device Info Test Results" );
127
- MEMFAULT_LOG_INFO ("------------------------" );
133
+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Device Info Test" );
128
134
129
135
if (results == 0 ) {
130
136
MEMFAULT_LOG_INFO ("All fields valid" );
@@ -138,6 +144,7 @@ static void prv_device_info_test_describe(uint32_t results) {
138
144
MEMFAULT_LOG_ERROR ("%s invalid" , s_device_info_field_names [i ]);
139
145
}
140
146
}
147
+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
141
148
}
142
149
143
150
uint32_t memfault_self_test_device_info_test (void ) {
@@ -151,7 +158,123 @@ uint32_t memfault_self_test_device_info_test(void) {
151
158
return results ;
152
159
}
153
160
161
+ typedef enum MfltBootComponent {
162
+ kMfltBootComponent_EventStorage = 0 ,
163
+ kMfltBootComponent_Logging ,
164
+ kMfltBootComponent_RebootTracking ,
165
+ kMfltBootComponent_TraceEvent ,
166
+ kMfltBootComponent_NumTypes ,
167
+ } eMfltBootComponent ;
168
+
169
+ static const struct {
170
+ char * component_name ;
171
+ bool (* booted )(void );
172
+ } s_boot_components [kMfltBootComponent_NumTypes ] = {
173
+ [kMfltBootComponent_EventStorage ] =
174
+ {
175
+ .component_name = "Event Storage" ,
176
+ memfault_event_storage_booted ,
177
+ },
178
+ [kMfltBootComponent_Logging ] =
179
+ {
180
+ .component_name = "Logging" ,
181
+ memfault_log_booted ,
182
+ },
183
+ [kMfltBootComponent_RebootTracking ] =
184
+ {
185
+ .component_name = "Reboot Tracking" ,
186
+ memfault_reboot_tracking_booted ,
187
+ },
188
+ [kMfltBootComponent_TraceEvent ] =
189
+ {
190
+ .component_name = "Trace Event" ,
191
+ memfault_trace_event_booted ,
192
+ },
193
+ };
194
+
195
+ void memfault_self_test_component_boot_test (void ) {
196
+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Component Boot Test" );
197
+ MEMFAULT_LOG_INFO ("%-16s|%8s|" , "Component" , "Booted?" );
198
+ MEMFAULT_LOG_INFO ("-----------------------------" );
199
+ for (size_t i = 0 ; i < MEMFAULT_ARRAY_SIZE (s_boot_components ); i ++ ) {
200
+ bool booted = s_boot_components [i ].booted ();
201
+ MEMFAULT_LOG_INFO ("%-16s|%8s|" , s_boot_components [i ].component_name , booted ? "yes" : "no" );
202
+ }
203
+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
204
+ }
205
+
206
+ void memfault_self_test_data_export_test (void ) {
207
+ char test_line [MEMFAULT_DATA_EXPORT_BASE64_CHUNK_MAX_LEN ] = { 0 };
208
+ // Set every char to '+' except for the last char before null terminator
209
+ memset (test_line , '+' , MEMFAULT_ARRAY_SIZE (test_line ) - 2 );
210
+ // Last character before null should be '1'
211
+ test_line [MEMFAULT_DATA_EXPORT_BASE64_CHUNK_MAX_LEN - 2 ] = '1' ;
212
+
213
+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Data Export Line Test" );
214
+ MEMFAULT_LOG_INFO ("Printing %u characters, confirm line ends with '1' and is not split" ,
215
+ (unsigned )(MEMFAULT_DATA_EXPORT_BASE64_CHUNK_MAX_LEN - 1 ));
216
+ MEMFAULT_LOG_INFO ("%s" , test_line );
217
+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
218
+ }
219
+
220
+ static void prv_print_region_group_info (const char * group_name , const sMfltCoredumpRegion * regions ,
221
+ const size_t num_regions ) {
222
+ MEMFAULT_LOG_INFO ("Coredump group: %s" , group_name );
223
+ MEMFAULT_LOG_INFO ("-----------------------------" );
224
+ MEMFAULT_LOG_INFO ("%10s|%10s|%6s|" , "Address" , "Length" , "Type" );
225
+ MEMFAULT_LOG_INFO ("-----------------------------" );
226
+ for (size_t i = 0 ; i < num_regions ; i ++ ) {
227
+ sMfltCoredumpRegion region = regions [i ];
228
+ MEMFAULT_LOG_INFO ("0x%08" PRIxPTR "|%10" PRIu32 "|%6u|" , (uintptr_t )region .region_start ,
229
+ region .region_size , region .type );
230
+ }
231
+ MEMFAULT_LOG_INFO ("-----------------------------" );
232
+ }
233
+
234
+ uint32_t memfault_self_test_coredump_regions_test (void ) {
235
+ uint32_t result = 0 ;
236
+ const sMfltCoredumpRegion * platform_regions = NULL ;
237
+ size_t num_platform_regions = 0 ;
238
+
239
+ // Set stack address to current sp and unknown reboot reason
240
+ // These are dummy values so we can get as close as possible to the regions
241
+ // that memfault_platform_coredump_get_regions will return
242
+ sCoredumpCrashInfo info = {
243
+ .stack_address = & num_platform_regions ,
244
+ .trace_reason = kMfltRebootReason_Unknown ,
245
+ };
246
+
247
+ // Call memfault_platform_coredump_get_regions
248
+ platform_regions = memfault_platform_coredump_get_regions (& info , & num_platform_regions );
249
+
250
+ // Get arch and SDK regions
251
+ size_t num_arch_regions = 0 ;
252
+ const sMfltCoredumpRegion * arch_regions = memfault_coredump_get_arch_regions (& num_arch_regions );
253
+ size_t num_sdk_regions = 0 ;
254
+ const sMfltCoredumpRegion * sdk_regions = memfault_coredump_get_sdk_regions (& num_sdk_regions );
255
+
256
+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Coredump Regions Test" );
257
+ if (num_platform_regions == 0 ) {
258
+ MEMFAULT_LOG_ERROR ("Number of platform regions = 0" );
259
+ result = 1 ;
260
+ }
261
+
262
+ if (platform_regions == NULL ) {
263
+ MEMFAULT_LOG_ERROR ("Platform regions was NULL" );
264
+ result = 1 ;
265
+ }
266
+
267
+ prv_print_region_group_info ("Platform Regions" , platform_regions , num_platform_regions );
268
+ prv_print_region_group_info ("Arch Regions" , arch_regions , num_arch_regions );
269
+ prv_print_region_group_info ("SDK Regions" , sdk_regions , num_sdk_regions );
270
+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
271
+ return result ;
272
+ }
273
+
154
274
int memfault_self_test_run (void ) {
155
275
// Run each test one at a time and return result of all runs OR'd together
276
+ memfault_self_test_component_boot_test ();
277
+ memfault_self_test_data_export_test ();
278
+ memfault_self_test_coredump_regions_test ();
156
279
return (memfault_self_test_device_info_test () != 0 );
157
280
}
0 commit comments