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