Rtos API example

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