Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
flush.cpp
Go to the documentation of this file.
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 Sun Jul 17 2022 08:25:23 by 1.7.2