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.
example3.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 00019 /** @file example3.cpp Test case to demonstrate each API function works correctly. 00020 * 00021 * \par Example 3 Notes 00022 * 00023 * Example3 is a synchronous mode example for creating key-values in the persistent storage. 00024 * 00025 * The flash-journal synchronous mode example test does the following CFSTORE operations: 00026 * - initialises 00027 * - creates a key-value pair (KV). 00028 * - writes the data for the KV 00029 * - closes KV. 00030 * - flushes the KV to flash 00031 * - opens KV for reading. 00032 * - reads KV and checks the value blob was the same as previously written. 00033 * - closes KV. 00034 * - finds a KV (there is only 1 to find). 00035 * - for the KV returned, get the key name. 00036 * - for the KV returned, get the value length. 00037 * - for the KV returned, delete the KV. 00038 * - find another KV (which fails as there are no more keys to find). 00039 * - flushes the updated state to flash to store the removal of the deleted KV. 00040 * - uninitialises 00041 * - stops 00042 * 00043 * This test is coded so as to work only in flash journal sync mode 00044 * i.e. with caps.asynchronous_ops == false 00045 * 00046 * The test leaves the flash in the same state as at the beginning of the test so 00047 * it can be run a second time on the device without flashing, and the test should 00048 * still work. 00049 * 00050 * \par How to Build Example3 as a Stand-alone Application 00051 * 00052 * This example can be build as a stand-alone application as follows: 00053 * - Create a new mbed application using the `mbed new .` command. 00054 * - Copy this file example3.cpp from the to the top level application directory and rename the file to main.cpp. 00055 * - Build the application with `mbed compile -v -m <target> -t <toolchain> -DCFSTORE_EXAMPLE3_APP` e.g. `mbed compile -v -m K64F -t GCC_ARM -DCFSTORE_EXAMPLE3_APP`. 00056 * 00057 */ 00058 #include "mbed.h" 00059 #ifndef CFSTORE_EXAMPLE3_APP 00060 /* when built as Configuration-Store example, include greentea support otherwise omit */ 00061 #include "utest/utest.h" 00062 #include "unity/unity.h" 00063 #include "greentea-client/test_env.h" 00064 #else // CFSTORE_EXAMPLE3_APP 00065 /* map utest types for building as stand alone example */ 00066 #define control_t void 00067 #define CaseNext 00068 #endif // CFSTORE_EXAMPLE3_APP 00069 00070 #include "cfstore_config.h" 00071 #include "cfstore_test.h" 00072 #include "configuration_store.h" 00073 00074 #ifdef YOTTA_CFG_CONFIG_UVISOR 00075 #include "uvisor-lib/uvisor-lib.h" 00076 #endif /* YOTTA_CFG_CONFIG_UVISOR */ 00077 00078 #include <stdio.h> 00079 #include <stdlib.h> 00080 #include <string.h> 00081 00082 #ifndef CFSTORE_EXAMPLE3_APP 00083 using namespace utest::v1; 00084 #endif 00085 00086 00087 /// @cond CFSTORE_DOXYGEN_DISABLE 00088 #define CFSTORE_EX1_TEST_ASSERT(Expr) if (!(Expr)) { printf("%s:%u: assertion failure\r\n", __FUNCTION__, __LINE__); while (1) ;} 00089 #define CFSTORE_EX1_TEST_ASSERT_EQUAL(expected, actual) if ((expected) != (actual)) {printf("%s:%u: assertion failure\r\n", __FUNCTION__, __LINE__); while (1) ;} 00090 #define CFSTORE_EX1_TEST_ASSERT_NOT_EQUAL(expected, actual) if ((expected) == (actual)) {printf("%s:%u: assertion failure\r\n", __FUNCTION__, __LINE__); while (1) ;} 00091 00092 #define CFSTORE_EX1_TEST_ASSERT_MSG(Expr, _fmt, ...) \ 00093 do \ 00094 { \ 00095 if (!(Expr)) \ 00096 { \ 00097 printf(_fmt, __VA_ARGS__); \ 00098 while (1) ; \ 00099 } \ 00100 }while(0); 00101 00102 #define CFSTORE_EX1_LOG(_fmt, ...) \ 00103 do \ 00104 { \ 00105 printf(_fmt, __VA_ARGS__); \ 00106 }while(0); 00107 00108 00109 const char* cfstore_ex3_opcode_str[] = 00110 { 00111 "UNDEFINED", 00112 "CFSTORE_OPCODE_CLOSE", 00113 "CFSTORE_OPCODE_CREATE", 00114 "CFSTORE_OPCODE_DELETE", 00115 "CFSTORE_OPCODE_FIND", 00116 "CFSTORE_OPCODE_FLUSH", 00117 "CFSTORE_OPCODE_GET_KEY_NAME", 00118 "CFSTORE_OPCODE_GET_STATUS", 00119 "CFSTORE_OPCODE_GET_VALUE_LEN", 00120 "CFSTORE_OPCODE_INITIALIZE", 00121 "CFSTORE_OPCODE_OPEN", 00122 "CFSTORE_OPCODE_POWER_CONTROL", 00123 "CFSTORE_OPCODE_READ", 00124 "CFSTORE_OPCODE_RSEEK", 00125 "CFSTORE_OPCODE_UNINITIALIZE", 00126 "CFSTORE_OPCODE_WRITE", 00127 "CFSTORE_OPCODE_MAX" 00128 }; 00129 00130 const char* cfstore_ex3_kv_name = "basement.medicine.pavement.government.trenchcoat.off.cough.off.kid.did.when.again.alleyway.friend.cap.pen.dollarbills.ten.foot.soot.put.but.anyway.say.May.DA.kid.did.toes.bows.those.hose.nose.clothes.man.blows.well.well"; 00131 const char* cfstore_ex3_kv_value = "TheRollingStone"; 00132 #define CFSTORE_EX1_RSEEK_OFFSET 10 /* offset to S of Stone */ 00133 00134 typedef struct cfstore_example3_ctx_t 00135 { 00136 ARM_CFSTORE_CAPABILITIES caps; 00137 uint8_t hkey[CFSTORE_HANDLE_BUFSIZE]; 00138 uint8_t hkey_next_buf[CFSTORE_HANDLE_BUFSIZE]; 00139 uint8_t hkey_prev_buf[CFSTORE_HANDLE_BUFSIZE]; 00140 ARM_CFSTORE_HANDLE hkey_next; 00141 ARM_CFSTORE_HANDLE hkey_prev; 00142 ARM_CFSTORE_SIZE len; 00143 ARM_CFSTORE_KEYDESC kdesc; 00144 ARM_CFSTORE_FMODE flags; 00145 char value[CFSTORE_KEY_NAME_MAX_LENGTH+1]; 00146 } cfstore_example3_ctx_t; 00147 00148 static cfstore_example3_ctx_t cfstore_example3_ctx_g; 00149 00150 extern ARM_CFSTORE_DRIVER cfstore_driver; 00151 ARM_CFSTORE_DRIVER *cfstore_drv = &cfstore_driver; 00152 /// @endcond 00153 00154 00155 static void cfstore_ex3_test_01(cfstore_example3_ctx_t* ctx) 00156 { 00157 int32_t ret; 00158 00159 CFSTORE_EX1_LOG("INITIALIZING%s", "\r\n"); 00160 ret = cfstore_drv->Initialize(NULL, NULL); 00161 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Initialize() should return ret >= 0 for async/synch modes(ret=%ld)\r\n", __func__, ret); 00162 00163 CFSTORE_EX1_LOG("CREATING%s", "\r\n"); 00164 memset(&ctx->kdesc, 0, sizeof(ARM_CFSTORE_KEYDESC)); 00165 ctx->kdesc.drl = ARM_RETENTION_NVM; 00166 ctx->len = strlen(cfstore_ex3_kv_value); 00167 ret = cfstore_drv->Create(cfstore_ex3_kv_name, ctx->len, &ctx->kdesc, ctx->hkey); 00168 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Create() failed (ret=%ld)\r\n", __func__, ret); 00169 00170 CFSTORE_EX1_LOG("WRITING%s", "\r\n"); 00171 ctx->len = strlen(cfstore_ex3_kv_value); 00172 ret = cfstore_drv->Write(ctx->hkey, cfstore_ex3_kv_value, &ctx->len); 00173 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Write() failed (ret=%ld)\r\n", __func__, ret); 00174 00175 CFSTORE_EX1_TEST_ASSERT_MSG(ret == (int32_t) strlen(cfstore_ex3_kv_value), "%s:Error: Write() number of octets written (i.e. completion status (%ld)) != strlen(ctx->value)(%ld)\r\n", __func__, ret, (int32_t) strlen(cfstore_ex3_kv_value)); 00176 CFSTORE_EX1_TEST_ASSERT_MSG(ret == (int32_t) ctx->len, "%s:Error: Write() number of octets written (i.e. completion status (%ld)) != updated value of len parameter (%ld)\r\n", __func__, ret, (int32_t) ctx->len); 00177 00178 CFSTORE_EX1_LOG("CLOSING1%s", "\r\n"); 00179 ret = cfstore_drv->Close(ctx->hkey); 00180 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Close() failed (ret=%ld)\r\n", __func__, ret); 00181 00182 CFSTORE_EX1_LOG("FLUSHING1%s", "\r\n"); 00183 ret = cfstore_drv->Flush(); 00184 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Flush() failed (ret=%ld)\r\n", __func__, ret); 00185 00186 CFSTORE_EX1_LOG("OPENING%s", "\r\n"); 00187 memset(&ctx->flags, 0, sizeof(ctx->flags)); 00188 memset(&ctx->hkey, 0, CFSTORE_HANDLE_BUFSIZE); 00189 ret = cfstore_drv->Open(cfstore_ex3_kv_name, ctx->flags, ctx->hkey); 00190 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Open() failed (ret=%ld)\r\n", __func__, ret); 00191 00192 CFSTORE_EX1_LOG("READING1%s", "\r\n"); 00193 ctx->len = CFSTORE_KEY_NAME_MAX_LENGTH; 00194 memset(ctx->value, 0, CFSTORE_KEY_NAME_MAX_LENGTH+1); 00195 ret = cfstore_drv->Read(ctx->hkey, ctx->value, &ctx->len); 00196 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Read() failed (ret=%ld)\r\n", __func__, ret); 00197 00198 CFSTORE_EX1_TEST_ASSERT_MSG(ret == (int32_t) strlen(cfstore_ex3_kv_value), "%s:Error: Read() number of octets read (i.e. completion status (%ld)) != strlen(ctx->value)(%ld)\r\n", __func__, ret, (int32_t) strlen(cfstore_ex3_kv_value)); 00199 CFSTORE_EX1_TEST_ASSERT_MSG(ret == (int32_t) ctx->len, "%s:Error: Read() number of octets read (i.e. completion status (%ld)) != updated value of len parameter (%ld)\r\n", __func__, ret, (int32_t) ctx->len); 00200 CFSTORE_EX1_TEST_ASSERT_MSG(strncmp(ctx->value, cfstore_ex3_kv_value, strlen(cfstore_ex3_kv_value)) == 0, "%s:Error: the read value (%s) is not as expected (%s)\r\n", __func__, ctx->value, cfstore_ex3_kv_value); 00201 00202 CFSTORE_EX1_LOG("RSEEKING%s", "\r\n"); 00203 ret = cfstore_drv->Rseek(ctx->hkey, CFSTORE_EX1_RSEEK_OFFSET); 00204 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Rseek() failed (ret=%ld)\r\n", __func__, ret); 00205 00206 CFSTORE_EX1_LOG("READING2%s", "\r\n"); 00207 ctx->len = CFSTORE_KEY_NAME_MAX_LENGTH; 00208 memset(ctx->value, 0, CFSTORE_KEY_NAME_MAX_LENGTH+1); 00209 ret = cfstore_drv->Read(ctx->hkey, ctx->value, &ctx->len); 00210 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Read() failed (ret=%ld)\r\n", __func__, ret); 00211 CFSTORE_EX1_TEST_ASSERT_MSG(ret == (int32_t) strlen(&cfstore_ex3_kv_value[CFSTORE_EX1_RSEEK_OFFSET]), "%s:Error: Read() number of octets read (i.e. completion status (%ld)) != strlen(ctx->value)(%ld)\r\n", __func__, ret, (int32_t) strlen(&cfstore_ex3_kv_value[CFSTORE_EX1_RSEEK_OFFSET])); 00212 CFSTORE_EX1_TEST_ASSERT_MSG(ret == (int32_t) ctx->len, "%s:Error: Read() number of octets read (i.e. completion status (%ld)) != updated value of len parameter (%ld)\r\n", __func__, ret, (int32_t) ctx->len); 00213 CFSTORE_EX1_TEST_ASSERT_MSG(strncmp(ctx->value, &cfstore_ex3_kv_value[CFSTORE_EX1_RSEEK_OFFSET], strlen(&cfstore_ex3_kv_value[CFSTORE_EX1_RSEEK_OFFSET])) == 0, "%s:Error: the read value (%s) is not as expected (%s)\r\n", __func__, ctx->value, &cfstore_ex3_kv_value[CFSTORE_EX1_RSEEK_OFFSET]); 00214 00215 CFSTORE_EX1_LOG("CLOSING2%s", "\r\n"); 00216 ret = cfstore_drv->Close(ctx->hkey); 00217 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Close() failed (ret=%ld)\r\n", __func__, ret); 00218 00219 CFSTORE_EX1_LOG("FINDING1%s", "\r\n"); 00220 ret = cfstore_drv->Find("*", ctx->hkey_next, ctx->hkey_prev); 00221 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Find() failed (ret=%ld)\r\n", __func__, ret); 00222 00223 CFSTORE_EX1_LOG("GETTING_KEY_NAME%s", "\r\n"); 00224 ctx->len = CFSTORE_KEY_NAME_MAX_LENGTH; 00225 memset(ctx->value, 0, CFSTORE_KEY_NAME_MAX_LENGTH+1); 00226 ret = cfstore_drv->GetKeyName(ctx->hkey_prev, ctx->value, (uint8_t*) &ctx->len); 00227 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: GetKeyName() failed (ret=%ld)\r\n", __func__, ret); 00228 CFSTORE_EX1_TEST_ASSERT_MSG( ((int32_t) ctx->len == ((int32_t) strlen(cfstore_ex3_kv_name)+1)), "%s:Error: GetKeyName() updated value of len parameter (%ld) != strlen(cfstore_ex3_kv_name) (%ld) (\r\n", __func__, (int32_t) ctx->len, (int32_t) strlen(cfstore_ex3_kv_name)); 00229 CFSTORE_EX1_TEST_ASSERT_MSG(strncmp(ctx->value, cfstore_ex3_kv_name, strlen(cfstore_ex3_kv_name)) == 0, "%s:Error: the key name (%s) is not as expected (%s)\r\n", __func__, ctx->value, cfstore_ex3_kv_name); 00230 00231 CFSTORE_EX1_LOG("GETTING_VALUE_LEN%s", "\r\n"); 00232 ctx->len = CFSTORE_KEY_NAME_MAX_LENGTH; 00233 ret = cfstore_drv->GetValueLen(ctx->hkey_prev, &ctx->len); 00234 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: GetValueLen() failed (ret=%ld)\r\n", __func__, ret); 00235 CFSTORE_EX1_TEST_ASSERT_MSG((int32_t) ctx->len == (int32_t) strlen(cfstore_ex3_kv_value), "%s:Error: GetValueLen() updated value of len parameter (%ld) != strlen(cfstore_ex3_kv_value)(%ld) \r\n", __func__, (int32_t) ctx->len, (int32_t) strlen(cfstore_ex3_kv_value)); 00236 00237 CFSTORE_EX1_LOG("DELETING%s", "\r\n"); 00238 ret = cfstore_drv->Delete(ctx->hkey_prev); 00239 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Close() failed (ret=%ld)\r\n", __func__, ret); 00240 CFSTORE_HANDLE_SWAP(ctx->hkey_prev, ctx->hkey_next); 00241 00242 CFSTORE_EX1_LOG("FINDING2%s", "\r\n"); 00243 ret = cfstore_drv->Find("*", ctx->hkey_next, ctx->hkey_prev); 00244 CFSTORE_EX1_TEST_ASSERT_MSG(ret == ARM_CFSTORE_DRIVER_ERROR_KEY_NOT_FOUND, "%s:Error: Find() failed to return expected value of ARM_CFSTORE_DRIVER_ERROR_KEY_NOT_FOUND (ret=%ld)\r\n", __func__, ret); 00245 00246 CFSTORE_EX1_LOG("FLUSHING2%s", "\r\n"); 00247 ret = cfstore_drv->Flush(); 00248 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error:2: Flush() failed (ret=%ld)\r\n", __func__, ret); 00249 00250 CFSTORE_EX1_LOG("UNINITIALIZING%s", "\r\n"); 00251 ret = cfstore_drv->Uninitialize(); 00252 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: Uninitialize() should return ret >= 0 for synch mode(ret=%ld)\r\n", __func__, ret); 00253 CFSTORE_EX1_LOG("***************%s", "\r\n"); 00254 CFSTORE_EX1_LOG("*** SUCCESS ***%s", "\r\n"); 00255 CFSTORE_EX1_LOG("***************%s", "\r\n"); 00256 return; 00257 } 00258 00259 static control_t cfstore_example3_app_start(const size_t call_count) 00260 { 00261 cfstore_example3_ctx_t* ctx = &cfstore_example3_ctx_g; 00262 00263 (void) call_count; 00264 00265 /* initialise the context */ 00266 memset(ctx, 0, sizeof(cfstore_example3_ctx_t)); 00267 ctx->hkey_next = ctx->hkey_next_buf; 00268 ctx->hkey_prev = ctx->hkey_prev_buf; 00269 ctx->caps = cfstore_drv->GetCapabilities(); 00270 CFSTORE_EX1_LOG("%s:INITIALIZING: caps.asynchronous_ops=%lu\n", __func__, ctx->caps.asynchronous_ops); 00271 if(ctx->caps.asynchronous_ops == 1){ 00272 /* This is a sync mode only test. If this test is not built for sync mode, then skip testing return true 00273 * This means the test will conveniently pass when run in CI as part of async mode testing */ 00274 CFSTORE_EX1_LOG("*** Skipping test as binary built for flash journal async mode, and this test is sync-only%s", "\n"); 00275 return CaseNext; 00276 } 00277 cfstore_ex3_test_01(ctx); 00278 return CaseNext; 00279 } 00280 00281 #ifndef CFSTORE_EXAMPLE3_APP 00282 /* when built as Configuration-Store example, include greentea support otherwise omit */ 00283 00284 /* report whether built/configured for flash sync or async mode */ 00285 static control_t cfstore_example3_test_00(const size_t call_count) 00286 { 00287 int32_t ret = ARM_DRIVER_ERROR; 00288 00289 (void) call_count; 00290 ret = cfstore_test_startup(); 00291 CFSTORE_EX1_TEST_ASSERT_MSG(ret >= ARM_DRIVER_OK, "%s:Error: failed to perform test startup (ret=%d).\n", __func__, (int) ret); 00292 return CaseNext; 00293 } 00294 00295 /// @cond CFSTORE_DOXYGEN_DISABLE 00296 utest::v1::status_t greentea_setup(const size_t number_of_cases) 00297 { 00298 GREENTEA_SETUP(100, "default_auto"); 00299 return greentea_test_setup_handler(number_of_cases); 00300 } 00301 00302 Case cases[] = { 00303 /* 1 2 3 4 5 6 7 */ 00304 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ 00305 Case("EXAMPLE3_test_00", cfstore_example3_test_00), 00306 Case("EXAMPLE3_test_01_start", cfstore_example3_app_start), 00307 }; 00308 00309 00310 /* Declare your test specification with a custom setup handler */ 00311 Specification specification(greentea_setup, cases); 00312 00313 int main() 00314 { 00315 return !Harness::run(specification); 00316 } 00317 /// @endcond 00318 00319 00320 #else // CFSTORE_EXAMPLE3_APP 00321 00322 // stand alone Configuration-Store-Example 00323 void app_start(int argc __unused, char** argv __unused) 00324 { 00325 cfstore_example3_app_start(0); 00326 } 00327 00328 00329 #endif // CFSTORE_EXAMPLE3_APP
Generated on Tue Jul 12 2022 14:23:41 by
