takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers example2.cpp Source File

example2.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 
00019 /** @file example2.cpp Test case to demonstrate a subset of the API functions each work correctly.
00020  *
00021  *  Overview of test:
00022  * - initialises cfstore
00023  * - creates a key called "com.arm.mbed.spv.assets.asset2.payload" with value blob length = 15 = strlen("Grumpy old man")+1.
00024  * - writes the data for the key to be "Grumpy old man"
00025  * - closes kv.
00026  * - opens kv for reading/writing
00027  * - reads the value blob and checks its == "Grumpy old man"
00028  * - writes the first 11 chars of the value blob to be "Grumpy man" plus a NULL;
00029  * - reads the value blob back and checks its as expected
00030  *
00031  * This test is coded so as to work in the following modes:
00032  * - flash sync mode i.e. with caps.asynchronous_ops == false
00033  * - flash async mode i.e. with caps.asynchronous_ops == true
00034  */
00035 #include "mbed.h"
00036 #include "cfstore_config.h"
00037 #include "cfstore_test.h"
00038 #include "cfstore_debug.h"
00039 #include "Driver_Common.h"
00040 #include "configuration_store.h"
00041 #include "utest/utest.h"
00042 #include "unity/unity.h"
00043 #include "greentea-client/test_env.h"
00044 
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include <assert.h>
00049 #include <inttypes.h>
00050 
00051 using namespace utest::v1;
00052 
00053 static char cfstore_example2_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
00054 
00055 /* defines */
00056 /// @cond CFSTORE_DOXYGEN_DISABLE
00057 #define PvMemSet memset
00058 #define PvStrLen strlen
00059 /// @endcond
00060 
00061 /* report whether built/configured for flash sync or async mode */
00062 static control_t cfstore_example2_test_00(const size_t call_count)
00063 {
00064     int32_t ret = ARM_DRIVER_ERROR;
00065 
00066     (void) call_count;
00067     ret = cfstore_test_startup();
00068     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to perform test startup (ret=%d).\n", __func__, (int) ret);
00069     TEST_ASSERT_MESSAGE(ret >= ARM_DRIVER_OK, cfstore_example2_utest_msg_g);
00070     return CaseNext;
00071 }
00072 
00073 /// @cond CFSTORE_DOXYGEN_DISABLE
00074 ARM_CFSTORE_DRIVER *drv = &cfstore_driver;
00075 /// @endcond
00076 
00077 
00078 static int32_t CreateKeyValueStore(
00079     const char *keyName,
00080     const char *data,
00081     ARM_CFSTORE_SIZE *dataLength,
00082     ARM_CFSTORE_KEYDESC *keyDesc)
00083 {
00084     int32_t cfsStatus = ARM_DRIVER_ERROR;
00085     ARM_CFSTORE_SIZE valueLength = 0;
00086     ARM_CFSTORE_HANDLE_INIT(hkey);
00087 
00088     valueLength = *dataLength;
00089     cfsStatus = drv->Create(keyName, valueLength, keyDesc, hkey);
00090     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, cfsStatus);
00091 
00092     valueLength = *dataLength;
00093     cfsStatus = drv->Write(hkey, data, &valueLength);
00094     /*
00095      * (1) Note the following:
00096      * - if cfsStatus > 0 then Write() has completed synchronously and returned the number of bytes written (irrespective of the caps.asynchronous_ops attribute).
00097      * - if cfsStatus == ARM_DRIVER_OK then:
00098      *      - if caps.asynchronous_ops == true then the operation will be completed with registered client callback passed to Initialize().
00099      *      - if caps.asynchronous_ops == false then the operation has completed synchronously and no bytes were written.
00100      * - if cfsStatus < ARM_DRIVER_OK then an error has occurred
00101      */
00102     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: failed to write key (rc=%d)\n", __func__, (int) cfsStatus);
00103     TEST_ASSERT_MESSAGE(cfsStatus >= ARM_DRIVER_OK, cfstore_example2_utest_msg_g);
00104 
00105     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%sError: valueLength(%d) does not match the expected dataLength(%d)\n", __func__, (int) valueLength, (int) *dataLength);
00106     TEST_ASSERT_MESSAGE(*dataLength == valueLength, cfstore_example2_utest_msg_g);
00107 
00108     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%sError: Write() return value cfsStatus(%d) does not match the expected dataLength(%d)\n", __func__, (int) cfsStatus, (int) *dataLength);
00109     TEST_ASSERT_MESSAGE((int32_t) *dataLength == cfsStatus, cfstore_example2_utest_msg_g);
00110 
00111     drv->Close(hkey);
00112     /* CreateKeyValueStore() returns what was returned from Write(). See (1) above for description. */
00113     return cfsStatus;
00114 }
00115 
00116 static control_t cfstore_example2_test_01(const size_t call_count)
00117 {
00118     int32_t cfsStatus;
00119     ARM_CFSTORE_HANDLE_INIT(hkey);
00120     ARM_CFSTORE_HANDLE_INIT(updatedKeyH);
00121     ARM_CFSTORE_FMODE flags;
00122     ARM_CFSTORE_KEYDESC kdesc;
00123     ARM_CFSTORE_SIZE valueLen;
00124     char* ptr = NULL;
00125     
00126     const char key[]   = "com.arm.mbed.spv.assets.asset2.payload";
00127     const char value[] = "Grumpy old man";
00128 
00129     (void) call_count;
00130 
00131     // It must not exceed the value_len field specified when the Key-Value pair was created
00132     const char newDataToWrite[] = "Grumpy man";
00133     
00134     char readBuf[CFSTORE_KEY_NAME_MAX_LENGTH + 1];
00135     ARM_CFSTORE_SIZE len = 0;
00136 
00137     // Write a key-value pair
00138 
00139     PvMemSet(&kdesc, 0, sizeof(kdesc));
00140     PvMemSet(&flags, 0, sizeof(flags));
00141     PvMemSet(readBuf, 0, CFSTORE_KEY_NAME_MAX_LENGTH + 1);
00142 
00143     kdesc.drl = ARM_RETENTION_WHILE_DEVICE_ACTIVE;
00144     /* The length supplied to Write() is the number of octets to store in the blob.
00145      * Specifying the following value for valueLen will store the terminating null to
00146      * a string, for example.
00147      */
00148     valueLen = PvStrLen(value) + 1;
00149 
00150     cfsStatus = drv->Initialize(NULL, NULL);
00151     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Initialize() failed (cfsStatus=%d)\n", __func__, (int) cfsStatus);
00152     TEST_ASSERT_MESSAGE(cfsStatus >= ARM_DRIVER_OK, cfstore_example2_utest_msg_g);
00153 
00154     cfsStatus = CreateKeyValueStore(key, value, &valueLen, &kdesc);
00155 
00156     /* CreateKeyValueStore() returns the number of characters written, which can vary between 0 and the supplied arg valueLen
00157      * - in the case that this example is compiled for flash mode sync, CreateKeyValueStore(), on success should always return valueLen
00158      * - in the case that this example is compiled for flash mode async, CreateKeyValueStore() on success may return a value 0 to valueLen
00159      *   with async notification of the completed transaction.
00160      */
00161     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%sError: valueLen(%d) does not match the expected returned value from CreateKeyValueStore(%d)\n", __func__, (int) valueLen, (int) cfsStatus);
00162     TEST_ASSERT_MESSAGE(cfsStatus == (int32_t) valueLen, cfstore_example2_utest_msg_g);
00163 
00164     // Read key-value pair with 'Write' permission
00165 
00166     flags.read = true;
00167     flags.write = true;
00168     cfsStatus = drv->Open(key, flags, hkey);
00169     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, cfsStatus);
00170 
00171     len = sizeof(readBuf);
00172     cfsStatus = drv->Read(hkey, readBuf, &len);
00173     /* Read() returns the number of characters read, which can vary between 0 and the size of the value blob, and the size of the supplied buffer  */
00174     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Read() returned value (%d) does not match the created length of the value blob(%d)\n", __func__, (int) cfsStatus, (int) PvStrLen(value) + 1);
00175     TEST_ASSERT_MESSAGE(cfsStatus == (int32_t) (PvStrLen(value) + 1), cfstore_example2_utest_msg_g);
00176 
00177     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Read() returned len value (%d) does not match the created length of the value blob(%d)\n", __func__, (int) len, (int) PvStrLen(value) + 1);
00178     TEST_ASSERT_MESSAGE(len == PvStrLen(value) + 1, cfstore_example2_utest_msg_g);
00179 
00180     /* Note:
00181      * - original data = "Grumpy old man", which is 14+1 chars inc NULL
00182      * - New data = "Grumpy man" which is 10+1 chars inc NULL
00183      * - when the key "com.arm.mbed.spv.assets.asset2.payload"; was created, it was created with a value blob size of 14+1=15 chars.
00184      * - The new data is shorter that the old data so it will be accommodated in the value blob
00185      * - The size of the value blob will stay the same.
00186      */
00187     // Update the value and value length
00188     /* note len set to sizeof(newDataToWrite) which includes the terminating null of the string */
00189     len = sizeof(newDataToWrite);
00190     cfsStatus = drv->Write(hkey, newDataToWrite, &len);
00191     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Write() returned cfsStatus value (%d) does not match the length of new data written(%d)\n", __func__, (int) cfsStatus, (int)  sizeof(newDataToWrite));
00192     TEST_ASSERT_MESSAGE(cfsStatus == (int32_t) sizeof(newDataToWrite), cfstore_example2_utest_msg_g);
00193     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Write() returned len (%d) does not match the length of new data written(%d)\n", __func__, (int) len, (int) sizeof(newDataToWrite));
00194     TEST_ASSERT_MESSAGE((int32_t) len == (int32_t) sizeof(newDataToWrite), cfstore_example2_utest_msg_g);
00195 
00196     drv->Close(hkey);
00197 
00198     // Check that the value was updated
00199     flags.write = false;
00200     cfsStatus = drv->Open(key, flags, updatedKeyH);
00201     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, cfsStatus);
00202 
00203     len = CFSTORE_KEY_NAME_MAX_LENGTH;
00204     PvMemSet(readBuf, 0, len);
00205     cfsStatus = drv->Read(updatedKeyH, readBuf, &len);
00206     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Read() returned value (%d) does not match the created length of the value blob(%d)\n", __func__, (int) cfsStatus, (int) PvStrLen(value) + 1);
00207     TEST_ASSERT_MESSAGE(cfsStatus == (int32_t) (PvStrLen(value) + 1), cfstore_example2_utest_msg_g);
00208 
00209     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Read() returned len value (%d) does not match the created length of the value blob(%d)\n", __func__, (int) len, (int) PvStrLen(value) + 1);
00210     TEST_ASSERT_MESSAGE(len == (PvStrLen(value) + 1), cfstore_example2_utest_msg_g);
00211 
00212     /* convert any terminating nulls to '=' */
00213     while( (ptr = (char*) memchr(readBuf, 0, (PvStrLen(value) + 1))) != NULL)
00214     {
00215         *ptr = '=';
00216     }
00217     /* check the data is as expected */
00218     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Read() returned unexpected string (%s) where nulls have been converted to '=' chars\n", __func__, readBuf);
00219     TEST_ASSERT_MESSAGE(strncmp(readBuf, "Grumpy man=man=", (PvStrLen(value) + 1)) == 0, cfstore_example2_utest_msg_g);
00220 
00221     /* revert to CFSTORE_LOG if more trace required */
00222     CFSTORE_DBGLOG("Success: New value of KV (%s) value blob (with nulls converted to '=') = (%s)\n", key, readBuf);
00223 
00224     drv->Close(updatedKeyH);
00225 
00226     cfsStatus = drv->Uninitialize();
00227     CFSTORE_TEST_UTEST_MESSAGE(cfstore_example2_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, "%s:Error: Uninitialize() failed (cfsStatus=%d)\n", __func__, (int) cfsStatus);
00228     TEST_ASSERT_MESSAGE(cfsStatus >= ARM_DRIVER_OK, cfstore_example2_utest_msg_g);
00229 
00230     return CaseNext;
00231 }
00232 
00233 
00234 /// @cond CFSTORE_DOXYGEN_DISABLE
00235 utest::v1::status_t greentea_setup(const size_t number_of_cases)
00236 {
00237     GREENTEA_SETUP(400, "default_auto");
00238     return greentea_test_setup_handler(number_of_cases);
00239 }
00240 
00241 Case cases[] = {
00242            /*          1         2         3         4         5         6        7  */
00243            /* 1234567890123456789012345678901234567890123456789012345678901234567890 */
00244         Case("EXAMPLE2_test_00", cfstore_example2_test_00),
00245         Case("EXAMPLE2_test_01", cfstore_example2_test_01),
00246 };
00247 
00248 
00249 /* Declare your test specification with a custom setup handler */
00250 Specification specification(greentea_setup, cases);
00251 
00252 int main()
00253 {
00254     return !Harness::run(specification);
00255 }
00256 /// @endcond