Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
flush.cpp
00001 /* 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2006-2016 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /** @file flush.cpp Test cases to flush KVs in the CFSTORE using the drv->Flush() interface. 00019 * 00020 * Please consult the documentation under the test-case functions for 00021 * a description of the individual test case. 00022 */ 00023 00024 #if defined __MBED__ && ! defined TOOLCHAIN_GCC_ARM 00025 00026 00027 #include "mbed.h" 00028 #include "cfstore_config.h" 00029 #include "Driver_Common.h" 00030 #include "cfstore_debug.h" 00031 #include "cfstore_test.h" 00032 #include "configuration_store.h" 00033 #include "utest/utest.h" 00034 #include "unity/unity.h" 00035 #include "greentea-client/test_env.h" 00036 #ifdef YOTTA_CFG_CFSTORE_UVISOR 00037 #include "uvisor-lib/uvisor-lib.h" 00038 #include "cfstore_uvisor.h" 00039 #endif /* YOTTA_CFG_CFSTORE_UVISOR */ 00040 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 #include <string.h> 00044 #include <inttypes.h> 00045 00046 using namespace utest::v1; 00047 00048 static control_t cfstore_flush_test_00(const size_t call_count) 00049 { 00050 (void) call_count; 00051 CFSTORE_LOG("%s:Not implemented for ARM toolchain\n", __func__); 00052 return CaseNext; 00053 } 00054 00055 00056 utest::v1::status_t greentea_setup(const size_t number_of_cases) 00057 { 00058 GREENTEA_SETUP(100, "default_auto"); 00059 return greentea_test_setup_handler(number_of_cases); 00060 } 00061 00062 Case cases[] = { 00063 /* 1 2 3 4 5 6 7 */ 00064 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ 00065 Case("FLUSH_test_00", cfstore_flush_test_00), 00066 }; 00067 00068 00069 /* Declare your test specification with a custom setup handler */ 00070 Specification specification(greentea_setup, cases); 00071 00072 int main() 00073 { 00074 return !Harness::run(specification); 00075 } 00076 00077 00078 #else 00079 00080 00081 00082 #include "mbed.h" 00083 #include "cfstore_config.h" 00084 #include "cfstore_test.h" 00085 #include "cfstore_debug.h" 00086 #include "Driver_Common.h" 00087 #include "configuration_store.h" 00088 #include "utest/utest.h" 00089 #include "unity/unity.h" 00090 #include "greentea-client/test_env.h" 00091 #ifdef YOTTA_CFG_CFSTORE_UVISOR 00092 #include "uvisor-lib/uvisor-lib.h" 00093 #endif /* YOTTA_CFG_CFSTORE_UVISOR */ 00094 00095 #include <stdio.h> 00096 #include <stdlib.h> 00097 #include <string.h> 00098 #include <inttypes.h> 00099 00100 using namespace utest::v1; 00101 00102 /* 00103 * Defines 00104 */ 00105 /// @cond CFSTORE_DOXYGEN_DISABLE 00106 #define CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE 256 00107 #define cfstore_flush_fsm_null NULL 00108 #define CFSTORE_FLUSH_CASE_TIMEOUT_MS 10000 00109 #define CFSTORE_FLUSH_FSM_LOOPS 20 00110 00111 #ifdef CFSTORE_DEBUG 00112 #define CFSTORE_FLUSH_GREENTEA_TIMEOUT_S 360 00113 #else 00114 #define CFSTORE_FLUSH_GREENTEA_TIMEOUT_S 60 00115 #endif 00116 00117 /* 00118 * Globals 00119 * 00120 * cfstore_flush_utest_msg_g 00121 * buffer for storing TEST_ASSERT_xxx_MESSAGE messages 00122 */ 00123 char cfstore_flush_utest_msg_g[CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE]; 00124 00125 /* Configure secure box. */ 00126 #ifdef YOTTA_CFG_CFSTORE_UVISOR 00127 UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.flush.box1"); 00128 UVISOR_BOX_CONFIG(cfstore_flush_box1, UVISOR_BOX_STACK_SIZE); 00129 #endif /* YOTTA_CFG_CFSTORE_UVISOR */ 00130 00131 00132 00133 00134 #ifdef TARGET_LIKE_X86_LINUX_NATIVE 00135 00136 /** @brief basic Flush() test 00137 * 00138 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00139 */ 00140 int32_t cfstore_flush_test_01_x86_sync(void) 00141 { 00142 int32_t ret = ARM_DRIVER_ERROR; 00143 ARM_CFSTORE_DRIVER* drv = &cfstore_driver; 00144 00145 ret = drv->Initialize(NULL, NULL); 00146 if(ret != ARM_DRIVER_OK){ 00147 CFSTORE_ERRLOG("%s:Initialize() call failed (ret=%d).\r\n", __func__, (int) ret); 00148 goto out0; 00149 } 00150 ret = drv->Flush(); 00151 if(ret != ARM_DRIVER_OK){ 00152 CFSTORE_ERRLOG("%s:Flush() call failed (ret=%d).\r\n", __func__, (int) ret); 00153 } 00154 ret = drv->Uninitialize(); 00155 if(ret != ARM_DRIVER_OK){ 00156 CFSTORE_ERRLOG("%s:Initialize() call failed to Uninitialise(ret=%d).\r\n", __func__, (int) ret); 00157 goto out0; 00158 } 00159 out0: 00160 return ret; 00161 } 00162 #endif /* TARGET_LIKE_X86_LINUX_NATIVE */ 00163 00164 /* KV data for test_03 */ 00165 static cfstore_kv_data_t cfstore_flush_test_02_kv_data[] = { 00166 { "com.arm.mbed.configurationstore.test.flush.cfstoreflushtest02", "1"}, 00167 /* 1 2 3 4 5 6 7 */ 00168 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ 00169 { NULL, NULL}, 00170 }; 00171 00172 00173 /* async test version */ 00174 00175 /* @brief test fsm states and events */ 00176 typedef enum cfstore_flush_fsm_state_t { 00177 cfstore_flush_fsm_state_stopped = 0, 00178 cfstore_flush_fsm_state_initializing, 00179 cfstore_flush_fsm_state_flushing, 00180 cfstore_flush_fsm_state_uninitializing, 00181 cfstore_flush_fsm_state_max 00182 } cfstore_flush_fsm_state_t; 00183 00184 /* @brief test fsm events */ 00185 typedef enum cfstore_flush_fsm_event_t { 00186 cfstore_flush_fsm_event_init_done = 0, 00187 cfstore_flush_fsm_event_flush_done, 00188 cfstore_flush_fsm_event_uninit_done, 00189 cfstore_flush_fsm_event_max, 00190 } cfstore_flush_fsm_event_t; 00191 00192 typedef void (*cfstore_flush_fsm_handler)(void* ctx); 00193 00194 /// @cond CFSTORE_DOXYGEN_DISABLE 00195 typedef struct cfstore_fsm_t 00196 { 00197 cfstore_flush_fsm_state_t state; 00198 cfstore_flush_fsm_event_t event; 00199 } cfstore_fsm_t; 00200 /// @endcond 00201 00202 /// @cond CFSTORE_DOXYGEN_DISABLE 00203 typedef struct cfstore_flush_ctx_t 00204 { 00205 int32_t loops_done; 00206 cfstore_fsm_t fsm; 00207 int32_t status; 00208 ARM_CFSTORE_OPCODE cmd_code; 00209 } cfstore_flush_ctx_t; 00210 /// @endcond 00211 00212 00213 /* 00214 * Globals 00215 */ 00216 static cfstore_flush_ctx_t cfstore_flush_ctx_g; 00217 00218 #ifdef CFSTORE_DEBUG 00219 static const char* cfstore_flush_state_str[] = 00220 { 00221 "stopped", 00222 "initializing", 00223 "flushing", 00224 "uninitializing", 00225 "unknown" 00226 }; 00227 00228 static const char* cfstore_flush_event_str[] = 00229 { 00230 "init_done", 00231 "flush_done", 00232 "uninit_done", 00233 "unknown" 00234 }; 00235 #endif 00236 00237 /// @endcond 00238 00239 /* 00240 * Forward decl 00241 */ 00242 static void cfstore_flush_fsm_state_handle_event(cfstore_fsm_t* fsm, cfstore_flush_fsm_event_t event, void* context); 00243 static void cfstore_flush_fsm_state_set(cfstore_fsm_t* fsm, cfstore_flush_fsm_state_t new_state, void* ctx); 00244 /* 00245 * context related methods 00246 */ 00247 00248 /* @brief get a pointer to the global context data structure */ 00249 static cfstore_flush_ctx_t* cfstore_flush_ctx_get(void) 00250 { 00251 return &cfstore_flush_ctx_g; 00252 } 00253 00254 /* @brief initialize global context data structure */ 00255 static void cfstore_flush_ctx_init(cfstore_flush_ctx_t* ctx) 00256 { 00257 TEST_ASSERT_MESSAGE(ctx != NULL, "ctx is NULL"); 00258 00259 CFSTORE_FENTRYLOG("%s:entered\r\n", __func__); 00260 memset(&cfstore_flush_ctx_g, 0, sizeof(cfstore_flush_ctx_g)); 00261 } 00262 00263 00264 /* @brief cfstore asynchronous callback handler */ 00265 void cfstore_flush_test_01_callback(int32_t status, ARM_CFSTORE_OPCODE cmd_code, void *client_context, ARM_CFSTORE_HANDLE handle) 00266 { 00267 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) client_context; 00268 00269 CFSTORE_FENTRYLOG("%s:entered: status=%d, cmd_code=%d (%s) ctx=%p, handle=%p\r\n", __func__, (int) status, (int) cmd_code, cfstore_test_opcode_str[cmd_code], ctx, handle); 00270 (void) handle; 00271 switch(cmd_code) 00272 { 00273 case CFSTORE_OPCODE_INITIALIZE: 00274 ctx->fsm.event = cfstore_flush_fsm_event_init_done; 00275 break; 00276 case CFSTORE_OPCODE_FLUSH: 00277 ctx->fsm.event = cfstore_flush_fsm_event_flush_done; 00278 break; 00279 case CFSTORE_OPCODE_UNINITIALIZE: 00280 ctx->fsm.event = cfstore_flush_fsm_event_uninit_done; 00281 break; 00282 case CFSTORE_OPCODE_CLOSE: 00283 case CFSTORE_OPCODE_CREATE: 00284 case CFSTORE_OPCODE_DELETE: 00285 case CFSTORE_OPCODE_FIND: 00286 case CFSTORE_OPCODE_GET_KEY_NAME: 00287 case CFSTORE_OPCODE_GET_STATUS: 00288 case CFSTORE_OPCODE_GET_VALUE_LEN: 00289 case CFSTORE_OPCODE_OPEN: 00290 case CFSTORE_OPCODE_POWER_CONTROL: 00291 case CFSTORE_OPCODE_READ: 00292 case CFSTORE_OPCODE_RSEEK: 00293 case CFSTORE_OPCODE_WRITE: 00294 default: 00295 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:WARN: received asynchronous notification for opcode=%d (%s) when api call should have been synchronous", __func__, cmd_code, cmd_code < CFSTORE_OPCODE_MAX ? cfstore_test_opcode_str[cmd_code] : "unknown"); 00296 CFSTORE_DBGLOG("%s:WARN: received asynchronous notification for opcode=%d (%s) when api call should have been synchronous", __func__, cmd_code, cmd_code < CFSTORE_OPCODE_MAX ? cfstore_test_opcode_str[cmd_code] : "unknown"); 00297 /* TEST_ASSERT_MESSAGE(false, cfstore_flush_utest_msg_g) */ 00298 return; 00299 } 00300 ctx->status = status; 00301 ctx->cmd_code = cmd_code; 00302 cfstore_flush_fsm_state_handle_event(&ctx->fsm, ctx->fsm.event, client_context); 00303 return; 00304 } 00305 00306 /* @brief fsm handler called on entry to stopping state */ 00307 static void cfstore_flush_fsm_stop_on_entry(void* context) 00308 { 00309 (void) context; 00310 CFSTORE_FENTRYLOG("%s:entered:\r\n", __func__); 00311 Harness::validate_callback(); 00312 return; 00313 } 00314 00315 /* @brief fsm handler called on entry to initializing state */ 00316 static void cfstore_flush_fsm_init_on_entry(void* context) 00317 { 00318 int32_t ret = ARM_DRIVER_ERROR; 00319 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00320 const ARM_CFSTORE_DRIVER* drv = &cfstore_driver; 00321 00322 /* check that the mtd is in synchronous mode */ 00323 CFSTORE_FENTRYLOG("%s:entered: callback=%p, ctx=%p\r\n", __func__, cfstore_flush_test_01_callback, ctx); 00324 ret = drv->Initialize(cfstore_flush_test_01_callback, ctx); 00325 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: failed to initialize CFSTORE (ret=%d)\r\n", __func__, (int) ret); 00326 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00327 CFSTORE_DBGLOG("%s:debug: ret=%d\r\n", __func__, (int) ret); 00328 return; 00329 } 00330 00331 /* brief callback handler when in state initializing */ 00332 static void cfstore_flush_fsm_initializing(void* context) 00333 { 00334 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00335 00336 CFSTORE_FENTRYLOG("%s:entered\r\n", __func__); 00337 CFSTORE_FENTRYLOG("%s:entered: status = %d\r\n", __func__, (int) ctx->status); 00338 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: entered handler(%s) but not in initializing state (fsm->state=%d)\r\n", __func__, __func__, (int) ctx->fsm.state); 00339 TEST_ASSERT_MESSAGE(ctx->fsm.state == cfstore_flush_fsm_state_initializing, cfstore_flush_utest_msg_g); 00340 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: cmd_code code (%d) is not as expected (%d)\r\n", __func__, ctx->cmd_code, CFSTORE_OPCODE_INITIALIZE); 00341 TEST_ASSERT_MESSAGE(ctx->cmd_code == CFSTORE_OPCODE_INITIALIZE, cfstore_flush_utest_msg_g); 00342 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: status=%d\r\n", __func__, (int) ctx->status); 00343 TEST_ASSERT_MESSAGE(ctx->status >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00344 /* only change state if status >= 0*/ 00345 if(ctx->status >= 0){ 00346 cfstore_flush_fsm_state_set(&ctx->fsm, cfstore_flush_fsm_state_flushing, ctx); 00347 } 00348 return; 00349 } 00350 00351 /* static void cfstore_flush_fsm_init_on_exit(void* context){ (void) context;} */ 00352 00353 00354 /* @brief fsm handler called on entry to flushing state */ 00355 static void cfstore_flush_fsm_flush_on_entry(void* context) 00356 { 00357 bool bfound = false; 00358 int32_t ivalue = 0; 00359 int32_t ret = ARM_DRIVER_ERROR; 00360 ARM_CFSTORE_DRIVER* drv = &cfstore_driver; 00361 const char* key_name_query = "*"; 00362 char value[CFSTORE_KEY_NAME_MAX_LENGTH+1]; 00363 ARM_CFSTORE_SIZE len = CFSTORE_KEY_NAME_MAX_LENGTH+1; 00364 ARM_CFSTORE_HANDLE_INIT(next); 00365 ARM_CFSTORE_HANDLE_INIT(prev); 00366 ARM_CFSTORE_KEYDESC kdesc; 00367 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00368 00369 /* check that the mtd is in synchronous mode */ 00370 CFSTORE_FENTRYLOG("%s:entered: \r\n", __func__); 00371 memset(&kdesc, 0, sizeof(kdesc)); 00372 00373 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: entered handler(%s) but not in flushing state (fsm->state=%d)\r\n", __func__, __func__, (int) ctx->fsm.state); 00374 TEST_ASSERT_MESSAGE(ctx->fsm.state == cfstore_flush_fsm_state_flushing, cfstore_flush_utest_msg_g); 00375 /* try to read key; should not be found */ 00376 ret = cfstore_test_kv_is_found(cfstore_flush_test_02_kv_data->key_name, &bfound); 00377 if(ret != ARM_DRIVER_OK && ret != ARM_CFSTORE_DRIVER_ERROR_KEY_NOT_FOUND){ 00378 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: cfstore_test_kv_is_found() call failed (ret=%d).\r\n", __func__, (int) ret); 00379 TEST_ASSERT_MESSAGE(false, cfstore_flush_utest_msg_g); 00380 } 00381 00382 if(!bfound) 00383 { 00384 /* first time start up. nothing is stored in cfstore flash. check this is the case */ 00385 while(drv->Find(key_name_query, prev, next) == ARM_DRIVER_OK) 00386 { 00387 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: have found an entry in cfstore when none should be present", __func__); 00388 TEST_ASSERT_MESSAGE(false, cfstore_flush_utest_msg_g); 00389 } 00390 /* no entries found, which is correct. 00391 * store a value */ 00392 len = strlen(cfstore_flush_test_02_kv_data->value); 00393 ret = cfstore_test_create(cfstore_flush_test_02_kv_data->key_name, cfstore_flush_test_02_kv_data->value, &len, &kdesc); 00394 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error:1: failed to write kv data (ret=%d).\r\n", __func__, (int) ret); 00395 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00396 /* flush to flash */ 00397 ret = drv->Flush(); 00398 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: failed to flush data to cfstore flash (ret=%d).\r\n", __func__, (int) ret); 00399 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00400 /* revert to CFSTORE_LOG if more trace required */ 00401 CFSTORE_DBGLOG("FLUSH: Success pending for new KV creation (name=%s, value=%s)\n", cfstore_flush_test_02_kv_data->key_name, cfstore_flush_test_02_kv_data->value); 00402 } else { 00403 /*read the value, increment by 1 and write value back */ 00404 len = CFSTORE_KEY_NAME_MAX_LENGTH+1; 00405 ret = cfstore_test_read(cfstore_flush_test_02_kv_data->key_name, value, &len); 00406 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: failed to read kv data (ret=%d).\r\n", __func__, (int) ret); 00407 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00408 00409 ivalue = atoi(value); 00410 /* revert to CFSTORE_LOG if more trace required */ 00411 CFSTORE_DBGLOG("FLUSH: Read KV from flash (name=%s, value=%d)\n", cfstore_flush_test_02_kv_data->key_name, (int) ivalue); 00412 /* increment value */ 00413 ++ivalue; 00414 snprintf(value, CFSTORE_KEY_NAME_MAX_LENGTH+1, "%d", (int) ivalue); 00415 len = strlen(value); 00416 ret = cfstore_test_write(cfstore_flush_test_02_kv_data->key_name, value, &len); 00417 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: failed to write kv data (ret=%d).\r\n", __func__, (int) ret); 00418 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00419 00420 /* flush to flash */ 00421 ret = drv->Flush(); 00422 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: failed to flush data to cfstore flash (ret=%d).\r\n", __func__, (int) ret); 00423 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00424 /* revert to CFSTORE_LOG if more trace required */ 00425 CFSTORE_DBGLOG("FLUSH: Success pending for new KV value to flash (name=%s, value=%d)\n", cfstore_flush_test_02_kv_data->key_name, (int) ivalue); 00426 } 00427 return; 00428 } 00429 00430 00431 /* brief callback handler when in state flushing */ 00432 static void cfstore_flush_fsm_flushing(void* context) 00433 { 00434 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00435 00436 CFSTORE_FENTRYLOG("%s:entered\r\n", __func__); 00437 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: entered handler(%s) but not in flushing state (fsm->state=%d)\r\n", __func__, __func__, (int) ctx->fsm.state); 00438 TEST_ASSERT_MESSAGE(ctx->fsm.state == cfstore_flush_fsm_state_flushing, cfstore_flush_utest_msg_g); 00439 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: cmd_code code (%d) is not as expected (%d)\r\n", __func__, ctx->cmd_code, CFSTORE_OPCODE_FLUSH); 00440 TEST_ASSERT_MESSAGE(ctx->cmd_code == CFSTORE_OPCODE_FLUSH, cfstore_flush_utest_msg_g); 00441 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: status=%d\r\n", __func__, (int) ctx->status); 00442 TEST_ASSERT_MESSAGE(ctx->status >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00443 /* only change state if status >= 0*/ 00444 if(ctx->status >= 0){ 00445 /* revert to CFSTORE_LOG if more trace required */ 00446 CFSTORE_DBGLOG("FLUSH: Successfully flushed data to flash.%s", "\n"); 00447 cfstore_flush_fsm_state_set(&ctx->fsm, cfstore_flush_fsm_state_uninitializing, ctx); 00448 } 00449 return; 00450 } 00451 00452 /* static void cfstore_flush_fsm_flush_on_exit(void* context){ (void) context;} */ 00453 00454 00455 /* @brief fsm handler called on entry to uninitializing state */ 00456 static void cfstore_flush_fsm_uninit_on_entry(void* context) 00457 { 00458 int32_t ret = ARM_DRIVER_ERROR; 00459 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00460 const ARM_CFSTORE_DRIVER* drv = &cfstore_driver; 00461 00462 /* check that the mtd is in synchronous mode */ 00463 CFSTORE_FENTRYLOG("%s:entered: \r\n", __func__); 00464 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: entered handler(%s) but not in uninitializing state (fsm->state=%d)\r\n", __func__, __func__, (int) ctx->fsm.state); 00465 TEST_ASSERT_MESSAGE(ctx->fsm.state == cfstore_flush_fsm_state_uninitializing, cfstore_flush_utest_msg_g); 00466 ret = drv->Uninitialize(); 00467 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: failed to uninitialize CFSTORE (ret=%d)\r\n", __func__, (int) ret); 00468 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00469 return; 00470 } 00471 00472 /* brief callback handler when in state uninitializing */ 00473 static void cfstore_flush_fsm_uninitializing(void* context) 00474 { 00475 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00476 00477 CFSTORE_FENTRYLOG("%s:entered\r\n", __func__); 00478 CFSTORE_DBGLOG("%s:ctx->status=%d, ctx->loops_done=%d\r\n", __func__, (int) ctx->status, (int) ctx->loops_done); 00479 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: entered handler(%s) but not in uninitializing state (fsm->state=%d)\r\n", __func__, __func__, (int) ctx->fsm.state); 00480 TEST_ASSERT_MESSAGE(ctx->fsm.state == cfstore_flush_fsm_state_uninitializing, cfstore_flush_utest_msg_g); 00481 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: cmd_code code (%d) is not as expected (%d)\r\n", __func__, ctx->cmd_code, CFSTORE_OPCODE_UNINITIALIZE); 00482 TEST_ASSERT_MESSAGE(ctx->cmd_code == CFSTORE_OPCODE_UNINITIALIZE, cfstore_flush_utest_msg_g); 00483 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: status=%d\r\n", __func__, (int) ctx->status); 00484 TEST_ASSERT_MESSAGE(ctx->status >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00485 /* only change state if status >= 0*/ 00486 if(ctx->status >= ARM_DRIVER_OK){ 00487 ++ctx->loops_done; 00488 if(ctx->loops_done < CFSTORE_FLUSH_FSM_LOOPS){ 00489 cfstore_flush_fsm_state_set(&ctx->fsm, cfstore_flush_fsm_state_initializing, ctx); 00490 } else { 00491 /* move to init state */ 00492 cfstore_flush_fsm_state_set(&ctx->fsm, cfstore_flush_fsm_state_stopped, ctx); 00493 } 00494 } 00495 return; 00496 } 00497 00498 /* static void cfstore_flush_fsm_uninit_on_exit(void* context) {(void)context;} */ 00499 00500 00501 00502 /* handler functions while in state */ 00503 static cfstore_flush_fsm_handler cfstore_flush_fsm[cfstore_flush_fsm_state_max][cfstore_flush_fsm_event_max] = 00504 { 00505 /* state\event: init_done flush_done unint_done */ 00506 /* stopped */ {cfstore_flush_fsm_null, cfstore_flush_fsm_null, cfstore_flush_fsm_null }, 00507 /* initialising */ {cfstore_flush_fsm_initializing, cfstore_flush_fsm_null, cfstore_flush_fsm_null }, 00508 /* flushing */ {cfstore_flush_fsm_null, cfstore_flush_fsm_flushing, cfstore_flush_fsm_null }, 00509 /* uninitializing */ {cfstore_flush_fsm_null, cfstore_flush_fsm_null, cfstore_flush_fsm_uninitializing } 00510 }; 00511 00512 00513 /* handler functions for entering the state*/ 00514 static cfstore_flush_fsm_handler cfstore_flush_fsm_on_entry[cfstore_flush_fsm_state_max] = 00515 { 00516 cfstore_flush_fsm_stop_on_entry, 00517 cfstore_flush_fsm_init_on_entry, 00518 cfstore_flush_fsm_flush_on_entry, 00519 cfstore_flush_fsm_uninit_on_entry 00520 }; 00521 00522 /* handler functions for exiting state, currently none used */ 00523 static cfstore_flush_fsm_handler cfstore_flush_fsm_on_exit[cfstore_flush_fsm_state_max] = 00524 { 00525 cfstore_flush_fsm_null, 00526 cfstore_flush_fsm_null, 00527 cfstore_flush_fsm_null, 00528 cfstore_flush_fsm_null 00529 }; 00530 00531 00532 /* @brief inject event into fsm */ 00533 static void cfstore_flush_fsm_state_handle_event(cfstore_fsm_t* fsm, cfstore_flush_fsm_event_t event, void* context) 00534 { 00535 cfstore_flush_ctx_t* ctx = (cfstore_flush_ctx_t*) context; 00536 00537 CFSTORE_FENTRYLOG("%s:entered: fsm=%p, state=(%s), event=%d (%s), ctx=%p\r\n", __func__, fsm, cfstore_flush_state_str[fsm->state], (int) event, cfstore_flush_event_str[event], ctx); 00538 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE, "%s:Error: invalid event (%d)\r\n", __func__, (int) event); 00539 TEST_ASSERT_MESSAGE(event < cfstore_flush_fsm_event_max, cfstore_flush_utest_msg_g); 00540 fsm->event = event; 00541 if(cfstore_flush_fsm[fsm->state][fsm->event] != NULL){ 00542 cfstore_flush_fsm[fsm->state][fsm->event](ctx); 00543 } 00544 00545 /* do not clear context data set by caller as it may be used later 00546 * fsm->event = cfstore_flush_fsm_event_max; 00547 * ctx->status = 0; 00548 * ctx->cmd_code = (FlashJournal_OpCode_t)((int) FLASH_JOURNAL_OPCODE_RESET+1); 00549 */ 00550 return; 00551 } 00552 00553 00554 /* @brief function to move to new fsm state, calling state exit function for old state and entry function for new state */ 00555 static void cfstore_flush_fsm_state_set(cfstore_fsm_t* fsm, cfstore_flush_fsm_state_t new_state, void* ctx) 00556 { 00557 #ifdef CFSTORE_DEBUG 00558 cfstore_flush_fsm_state_t old_state = fsm->state; 00559 #endif 00560 00561 CFSTORE_FENTRYLOG("%s:entered: fsm=%p, ctx=%p\r\n", __func__, fsm, ctx); 00562 #ifdef CFSTORE_DEBUG 00563 CFSTORE_DBGLOG("%s:FSM:REQ RX:%s:%s\r\n", __func__, cfstore_flush_state_str[fsm->state], cfstore_flush_state_str[new_state]); 00564 #endif 00565 TEST_ASSERT_MESSAGE(fsm != NULL, "fsm is not a valid pointer"); 00566 TEST_ASSERT_MESSAGE(new_state < cfstore_flush_fsm_state_max, "new_state is not a valid state"); 00567 TEST_ASSERT_MESSAGE(ctx != NULL, "ctx is not a valid pointer"); 00568 TEST_ASSERT_MESSAGE(fsm->state < cfstore_flush_fsm_state_max, "fsm->state is not a valid state"); 00569 00570 if(cfstore_flush_fsm_on_exit[fsm->state] != NULL){ 00571 cfstore_flush_fsm_on_exit[fsm->state](ctx); 00572 } 00573 fsm->state = new_state; 00574 if(cfstore_flush_fsm_on_entry[new_state] != NULL){ 00575 cfstore_flush_fsm_on_entry[new_state](ctx); 00576 } 00577 #ifdef CFSTORE_DEBUG 00578 CFSTORE_DBGLOG("%s:FSM:REQ DONE fsm=%p, fsm->state (old_state)=%s, new_state=%s, ctx=%p\r\n", __func__, fsm, cfstore_flush_state_str[old_state], cfstore_flush_state_str[new_state], ctx); 00579 #endif 00580 return; 00581 } 00582 00583 00584 /* @brief asynchronous test 01 */ 00585 static control_t cfstore_flush_test_02_k64f(void) 00586 { 00587 cfstore_flush_ctx_t* ctx = cfstore_flush_ctx_get(); 00588 ARM_CFSTORE_CAPABILITIES caps; 00589 const ARM_CFSTORE_DRIVER* drv = &cfstore_driver; 00590 00591 CFSTORE_FENTRYLOG("%s:entered: \r\n", __func__); 00592 memset(&caps, 0, sizeof(caps)); 00593 caps = drv->GetCapabilities(); 00594 if(caps.asynchronous_ops == false){ 00595 /* This is a async mode only test. If this test is not built for sync mode, then skip testing return true 00596 * This means the test will conveniently pass when run in CI as part of async mode testing */ 00597 CFSTORE_LOG("*** Skipping test as binary built for flash journal sync mode, and this test is async-only%s", "\n"); 00598 return CaseNext; 00599 } 00600 00601 cfstore_flush_ctx_init(ctx); 00602 cfstore_flush_fsm_state_set(&ctx->fsm, cfstore_flush_fsm_state_initializing, ctx); 00603 return CaseTimeout(CFSTORE_FLUSH_GREENTEA_TIMEOUT_S*1000); 00604 } 00605 00606 /* report whether built/configured for flash sync or async mode */ 00607 static control_t cfstore_flush_test_00(const size_t call_count) 00608 { 00609 int32_t ret = ARM_DRIVER_ERROR; 00610 00611 (void) call_count; 00612 ret = cfstore_test_startup(); 00613 CFSTORE_TEST_UTEST_MESSAGE(cfstore_flush_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to perform test startup (ret=%d).\n", __func__, (int) ret); 00614 TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_flush_utest_msg_g); 00615 return CaseNext; 00616 } 00617 00618 /// @cond CFSTORE_DOXYGEN_DISABLE 00619 utest::v1::status_t greentea_setup(const size_t number_of_cases) 00620 { 00621 GREENTEA_SETUP(CFSTORE_FLUSH_GREENTEA_TIMEOUT_S, "default_auto"); 00622 return greentea_test_setup_handler(number_of_cases); 00623 } 00624 00625 Case cases[] = { 00626 Case("FLUSH_test_00", cfstore_flush_test_00), 00627 Case("FLUSH_test_01", cfstore_flush_test_02_k64f), 00628 }; 00629 00630 00631 /* Declare your test specification with a custom setup handler */ 00632 Specification specification(greentea_setup, cases); 00633 00634 int main() 00635 { 00636 return !Harness::run(specification); 00637 } 00638 /// @endcond 00639 00640 00641 #endif // __MBED__ && ! defined TOOLCHAIN_GCC_ARM
Generated on Tue Jul 12 2022 14:23:47 by
