1616#include "memfault/core/debug_log.h"
1717#include "memfault/core/event_storage.h"
1818#include "memfault/core/math.h"
19+ #include "memfault/core/platform/core.h"
1920#include "memfault/core/platform/device_info.h"
2021#include "memfault/core/reboot_tracking.h"
2122#include "memfault/core/self_test.h"
2425#include "memfault/panics/coredump_impl.h"
2526#include "memfault_self_test_private.h"
2627
28+ #if !defined(MEMFAULT_UNITTEST_SELF_TEST )
29+
2730typedef enum {
2831 kDeviceInfoField_DeviceSerial = 0 ,
2932 kDeviceInfoField_SoftwareType ,
@@ -130,8 +133,6 @@ static uint32_t prv_validate_build_id(void) {
130133}
131134
132135static void prv_device_info_test_describe (uint32_t results ) {
133- MEMFAULT_SELF_TEST_PRINT_HEADER ("Device Info Test" );
134-
135136 if (results == 0 ) {
136137 MEMFAULT_LOG_INFO ("All fields valid" );
137138 return ;
@@ -144,17 +145,19 @@ static void prv_device_info_test_describe(uint32_t results) {
144145 MEMFAULT_LOG_ERROR ("%s invalid" , s_device_info_field_names [i ]);
145146 }
146147 }
147- MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
148148}
149149
150150uint32_t memfault_self_test_device_info_test (void ) {
151151 uint32_t results = 0 ;
152+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Device Info Test" );
153+
152154 // Validate the build ID
153155 results |= prv_validate_build_id ();
154156 // Valid device info fields
155157 results |= prv_validate_device_info ();
156158
157159 prv_device_info_test_describe (results );
160+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
158161 return results ;
159162}
160163
@@ -192,15 +195,24 @@ static const struct {
192195 },
193196};
194197
195- void memfault_self_test_component_boot_test (void ) {
198+ uint32_t memfault_self_test_component_boot_test (void ) {
199+ uint32_t result = 0 ;
196200 MEMFAULT_SELF_TEST_PRINT_HEADER ("Component Boot Test" );
197201 MEMFAULT_LOG_INFO ("%-16s|%8s|" , "Component" , "Booted?" );
198202 MEMFAULT_LOG_INFO ("-----------------------------" );
199203 for (size_t i = 0 ; i < MEMFAULT_ARRAY_SIZE (s_boot_components ); i ++ ) {
200204 bool booted = s_boot_components [i ].booted ();
201- MEMFAULT_LOG_INFO ("%-16s|%8s|" , s_boot_components [i ].component_name , booted ? "yes" : "no" );
205+ if (!booted ) {
206+ MEMFAULT_LOG_ERROR ("%-16s|%8s|" , s_boot_components [i ].component_name , "no" );
207+ result |= (1 << i );
208+ }
209+ }
210+
211+ if (result == 0 ) {
212+ MEMFAULT_LOG_INFO ("All components booted" );
202213 }
203214 MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
215+ return result ;
204216}
205217
206218void memfault_self_test_data_export_test (void ) {
@@ -271,10 +283,59 @@ uint32_t memfault_self_test_coredump_regions_test(void) {
271283 return result ;
272284}
273285
274- int memfault_self_test_run (void ) {
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 ();
279- return (memfault_self_test_device_info_test () != 0 );
286+ MEMFAULT_NORETURN void memfault_self_test_reboot_reason_test (void ) {
287+ // Set a known reason and allow the device to reboot
288+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Reboot Reason Test" );
289+ MEMFAULT_LOG_INFO ("This test will now reboot the device to test reboot reason tracking" );
290+ MEMFAULT_LOG_INFO ("After the device reboots, please run with reboot_verify argument" );
291+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
292+ MEMFAULT_REBOOT_MARK_RESET_IMMINENT (kMfltRebootReason_SelfTest );
293+ memfault_platform_reboot ();
294+ }
295+
296+ uint32_t memfault_self_test_reboot_reason_test_verify (void ) {
297+ // Use explicit initializer to avoid ti-armcl warning
298+ sMfltRebootReason reboot_reason = {
299+ .prior_stored_reason = kMfltRebootReason_Unknown ,
300+ .reboot_reg_reason = kMfltRebootReason_Unknown ,
301+ };
302+ int result = memfault_reboot_tracking_get_reboot_reason (& reboot_reason );
303+
304+ bool success = (result == 0 ) && (reboot_reason .prior_stored_reason == kMfltRebootReason_SelfTest );
305+ MEMFAULT_SELF_TEST_PRINT_HEADER ("Reboot Reason Test" );
306+ if (success ) {
307+ MEMFAULT_LOG_INFO ("Reboot reason test successful" );
308+ } else {
309+ MEMFAULT_LOG_ERROR ("Reboot reason test failed:" );
310+ MEMFAULT_LOG_ERROR ("get_reboot_reason result: %d, "
311+ "prior_stored_reason: 0x%08" PRIx32 ,
312+ result , (uint32_t )reboot_reason .prior_stored_reason );
313+ }
314+ MEMFAULT_LOG_INFO (MEMFAULT_SELF_TEST_END_OUTPUT );
315+ return success ? 0 : 1 ;
316+ }
317+
318+ #endif // defined(MEMFAULT_UNITTEST_SELF_TEST)
319+
320+ int memfault_self_test_run (uint32_t run_flags ) {
321+ uint32_t result = 0 ;
322+ if (run_flags & kMemfaultSelfTestFlag_DeviceInfo ) {
323+ result |= memfault_self_test_device_info_test ();
324+ }
325+ if (run_flags & kMemfaultSelfTestFlag_ComponentBoot ) {
326+ result |= memfault_self_test_component_boot_test ();
327+ }
328+ if (run_flags & kMemfaultSelfTestFlag_CoredumpRegions ) {
329+ result |= memfault_self_test_coredump_regions_test ();
330+ }
331+ if (run_flags & kMemfaultSelfTestFlag_DataExport ) {
332+ memfault_self_test_data_export_test ();
333+ }
334+ if (run_flags & kMemfaultSelfTestFlag_RebootReason ) {
335+ memfault_self_test_reboot_reason_test ();
336+ }
337+ if (run_flags & kMemfaultSelfTestFlag_RebootReasonVerify ) {
338+ result = memfault_self_test_reboot_reason_test_verify ();
339+ }
340+ return (result == 0 ) ? 0 : 1 ;
280341}
0 commit comments