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.
basicAPI.cpp
00001 /* 00002 * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * 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, WITHOUT 00013 * 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 #ifdef TARGET_LIKE_POSIX 00019 #define AVOID_GREENTEA 00020 #endif 00021 00022 #ifndef AVOID_GREENTEA 00023 #include "greentea-client/test_env.h" 00024 #endif 00025 #include "utest/utest.h" 00026 #include "unity/unity.h" 00027 00028 #include "storage-volume-manager/storage_volume_manager.h" 00029 #include <string.h> 00030 #include <inttypes.h> 00031 00032 using namespace utest::v1; 00033 00034 /* redefine tr_info() to a printf() equivalent to emit trace */ 00035 #define tr_info(...) ((void) 0) 00036 #define mbed_trace_init(...) ((void) 0) 00037 #define mbed_trace_config_set(...) ((void) 0) 00038 00039 #ifdef TARGET_LIKE_X86_LINUX_NATIVE 00040 extern ARM_DRIVER_STORAGE ARM_Driver_Storage_MTD_RAM; 00041 ARM_DRIVER_STORAGE *drv = &ARM_Driver_Storage_MTD_RAM; 00042 #elif defined TARGET_LIKE_FRDM_K64F 00043 extern ARM_DRIVER_STORAGE ARM_Driver_Storage_MTD_K64F; 00044 ARM_DRIVER_STORAGE *drv = &ARM_Driver_Storage_MTD_K64F; 00045 #else 00046 extern ARM_DRIVER_STORAGE ARM_Driver_Storage_MTD_K64F; 00047 ARM_DRIVER_STORAGE *drv = &ARM_Driver_Storage_MTD_K64F; 00048 #endif 00049 00050 /* temporary buffer to hold data for testing. */ 00051 static const unsigned BUFFER_SIZE = 16384; 00052 static uint8_t buffer[BUFFER_SIZE]; 00053 00054 static int32_t callbackStatus; 00055 static int32_t virtualVolumeCallbackStatus; 00056 00057 #ifndef AVOID_GREENTEA 00058 // Custom setup handler required for proper Greentea support 00059 utest::v1::status_t greentea_setup(const size_t number_of_cases) 00060 { 00061 GREENTEA_SETUP(30, "default_auto"); 00062 // Call the default reporting function 00063 return greentea_test_setup_handler(number_of_cases); 00064 } 00065 #endif 00066 00067 /* used only for the initialization of the volume-manager. */ 00068 void initializeCallbackHandler(int32_t status) 00069 { 00070 tr_info("in initializeCallbackHandler\r\n"); 00071 Harness::validate_callback(); 00072 } 00073 00074 /* used only when accessing MTD directly (for verification) */ 00075 void mtdCallbackHandler(int32_t status, ARM_STORAGE_OPERATION operation) 00076 { 00077 tr_info("in mtdCallbackHandler"); 00078 callbackStatus = status; 00079 Harness::validate_callback(); 00080 } 00081 00082 /* the normal callback handler for the virtual volume */ 00083 void virtualMTDCallbackHandler(int32_t status, ARM_STORAGE_OPERATION operation) 00084 { 00085 tr_info("in virtualMTDCallbackHandler"); 00086 virtualVolumeCallbackStatus = status; 00087 Harness::validate_callback(); 00088 } 00089 00090 control_t test_initialize(const size_t call_count) 00091 { 00092 tr_info("test_initialize: called with call_count %lu", call_count); 00093 static StorageVolumeManager volumeManager; 00094 00095 if (call_count == 1) { 00096 int32_t rc = volumeManager.initialize(drv, initializeCallbackHandler); 00097 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00098 if (rc == ARM_DRIVER_OK) { 00099 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00100 return CaseTimeout(200) + CaseRepeatAll; 00101 } 00102 00103 /* synchronous completion */ 00104 TEST_ASSERT(rc == 1); 00105 } 00106 00107 TEST_ASSERT_EQUAL(true, volumeManager.isInitialized()); 00108 TEST_ASSERT(volumeManager.getStorageInfo().total_storage > 0); 00109 for (size_t index = 0; index < MAX_VOLUMES; index++) { 00110 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 00111 } 00112 00113 return CaseNext; 00114 } 00115 00116 template <uint64_t OFFSET> 00117 control_t test_againstSingleVolumeAtOffset(const size_t call_count) 00118 { 00119 tr_info("test_againstSingleVolumeAtOffset: called with call_count %lu", call_count); 00120 static StorageVolumeManager volumeManager; 00121 static StorageVolume *volumeP = NULL; 00122 static ARM_STORAGE_INFO info; 00123 static size_t sizeofDataOperation; 00124 00125 const uint8_t PATTERN_FOR_PROGRAM_DATA = 0xAA; 00126 00127 static enum { 00128 VOLUME_MANAGER_INITIALIZE = 1, 00129 BASIC_SYNCHRONOUS_API_TESTING, 00130 READ_DATA, 00131 ERASE, 00132 READ_AFTER_ERASE, 00133 PROGRAM_DATA, 00134 READ_AFTER_PROGRAM_DATA, 00135 VERIFY_PROGRAM_DATA, 00136 DISCONNECT_VOLUME_MANAGER_CALLBACK, 00137 READ_FROM_DRV_AFTER_PROGRAM_DATA, 00138 VERIFY_PROGRAM_DATA2, 00139 } state = VOLUME_MANAGER_INITIALIZE; 00140 tr_info("came in with state %u", state); 00141 00142 int32_t rc; 00143 ARM_STORAGE_BLOCK firstBlock; 00144 rc = drv->GetNextBlock(NULL, &firstBlock); 00145 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00146 TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); 00147 00148 switch (state) { 00149 case VOLUME_MANAGER_INITIALIZE: 00150 rc = volumeManager.initialize(drv, initializeCallbackHandler); 00151 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00152 if (rc == ARM_DRIVER_OK) { 00153 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00154 state = BASIC_SYNCHRONOUS_API_TESTING; 00155 return CaseTimeout(200) + CaseRepeatAll; 00156 } 00157 00158 /* synchronous completion */ 00159 TEST_ASSERT(rc == 1); 00160 00161 /* intentional fall-through */ 00162 00163 case BASIC_SYNCHRONOUS_API_TESTING: 00164 TEST_ASSERT_EQUAL(true, volumeManager.isInitialized()); 00165 00166 rc = drv->GetInfo(&info); 00167 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00168 TEST_ASSERT(info.total_storage > 0); 00169 00170 { /* add volume */ 00171 rc = volumeManager.addVolume(firstBlock.addr + OFFSET /*addr*/, info.total_storage - OFFSET /*size*/ , &volumeP); 00172 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00173 00174 TEST_ASSERT_EQUAL(true, volumeManager.volumeAtIndex(0)->isAllocated()); 00175 for (size_t index = 1; index < MAX_VOLUMES; index++) { 00176 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 00177 } 00178 } 00179 00180 { /* GetVersion */ 00181 TEST_ASSERT_EQUAL(drv->GetVersion().api, volumeP->GetVersion().api); 00182 TEST_ASSERT_EQUAL(drv->GetVersion().drv, volumeP->GetVersion().drv); 00183 } 00184 00185 { /* GetCapabilities */ 00186 TEST_ASSERT_EQUAL(drv->GetCapabilities().asynchronous_ops, volumeP->GetCapabilities().asynchronous_ops); 00187 TEST_ASSERT_EQUAL(drv->GetCapabilities().erase_all, volumeP->GetCapabilities().erase_all); 00188 } 00189 00190 { /* Initialize */ 00191 rc = volumeP->Initialize(virtualMTDCallbackHandler); 00192 TEST_ASSERT_EQUAL(1, rc); 00193 } 00194 00195 { /* GetStatus */ 00196 ARM_STORAGE_STATUS status = volumeP->GetStatus(); 00197 TEST_ASSERT_EQUAL(0, status.busy); 00198 TEST_ASSERT_EQUAL(0, status.error); 00199 } 00200 00201 { /* GetInfo */ 00202 ARM_STORAGE_INFO volumeInfo; 00203 rc = volumeP->GetInfo(&volumeInfo); 00204 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00205 00206 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, volumeInfo.total_storage); 00207 TEST_ASSERT_EQUAL(info.program_unit, volumeInfo.program_unit); 00208 TEST_ASSERT_EQUAL(info.optimal_program_unit, volumeInfo.optimal_program_unit); 00209 TEST_ASSERT_EQUAL(info.program_cycles, volumeInfo.program_cycles); 00210 TEST_ASSERT_EQUAL(info.erased_value, volumeInfo.erased_value); 00211 TEST_ASSERT_EQUAL(info.memory_mapped, volumeInfo.memory_mapped); 00212 TEST_ASSERT_EQUAL(info.programmability, volumeInfo.programmability); 00213 TEST_ASSERT_EQUAL(info.retention_level, volumeInfo.retention_level); 00214 TEST_ASSERT_EQUAL(info.reserved, volumeInfo.reserved); 00215 TEST_ASSERT_EQUAL(0, memcmp(&info.security, &volumeInfo.security, sizeof(ARM_STORAGE_SECURITY_FEATURES))); 00216 } 00217 00218 { /* resolve address */ 00219 TEST_ASSERT_EQUAL(firstBlock.addr + OFFSET, volumeP->ResolveAddress(0)); 00220 TEST_ASSERT_EQUAL(firstBlock.addr + OFFSET + info.total_storage, volumeP->ResolveAddress(info.total_storage)); 00221 TEST_ASSERT_EQUAL(firstBlock.addr + OFFSET + info.total_storage / 2, volumeP->ResolveAddress(info.total_storage / 2)); 00222 } 00223 00224 { /* GetNextBlock */ 00225 rc = volumeP->GetNextBlock(NULL, NULL); 00226 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00227 ARM_STORAGE_BLOCK block; 00228 rc = volumeP->GetNextBlock(NULL, &block); 00229 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00230 TEST_ASSERT_EQUAL(0, block.addr); 00231 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, block.size); 00232 00233 rc = volumeP->GetNextBlock(&block, NULL); 00234 TEST_ASSERT(rc < ARM_DRIVER_OK); 00235 rc = volumeP->GetNextBlock(&block, &block); 00236 TEST_ASSERT(rc < ARM_DRIVER_OK); 00237 } 00238 00239 { /* GetBlock */ 00240 ARM_STORAGE_BLOCK block; 00241 rc = volumeP->GetBlock(0, &block); 00242 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00243 TEST_ASSERT_EQUAL(0, block.addr); 00244 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, block.size); 00245 00246 rc = volumeP->GetBlock((info.total_storage / 2), &block); 00247 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00248 TEST_ASSERT_EQUAL(0, block.addr); 00249 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, block.size); 00250 00251 rc = volumeP->GetBlock(info.total_storage, &block); 00252 TEST_ASSERT(rc < ARM_DRIVER_OK); 00253 } 00254 00255 state = READ_DATA; 00256 /* intentional fallthrough */ 00257 00258 case READ_DATA: 00259 sizeofDataOperation = ((info.total_storage - OFFSET) > BUFFER_SIZE) ? BUFFER_SIZE : (info.total_storage - OFFSET); 00260 TEST_ASSERT(sizeofDataOperation <= BUFFER_SIZE); 00261 00262 /* ReadData */ 00263 rc = volumeP->ReadData(0, buffer, sizeofDataOperation); 00264 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00265 if (rc == ARM_DRIVER_OK) { 00266 TEST_ASSERT_EQUAL(1, volumeP->GetCapabilities().asynchronous_ops); 00267 state = ERASE; 00268 return CaseTimeout(200) + CaseRepeatAll; 00269 } 00270 00271 virtualVolumeCallbackStatus = rc; 00272 /* intentional fallthrough */ 00273 00274 case ERASE: 00275 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00276 00277 /* Erase */ 00278 rc = volumeP->Erase(0, sizeofDataOperation); 00279 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00280 if (rc == ARM_DRIVER_OK) { 00281 TEST_ASSERT_EQUAL(1, volumeP->GetCapabilities().asynchronous_ops); 00282 state = READ_AFTER_ERASE; 00283 return CaseTimeout(200) + CaseRepeatAll; 00284 } 00285 00286 virtualVolumeCallbackStatus = rc; 00287 /* intentional fallthrough */ 00288 00289 case READ_AFTER_ERASE: 00290 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00291 00292 /* Read after Erase */ 00293 rc = volumeP->ReadData(0, buffer, sizeofDataOperation); 00294 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00295 if (rc == ARM_DRIVER_OK) { 00296 TEST_ASSERT_EQUAL(1, volumeP->GetCapabilities().asynchronous_ops); 00297 state = PROGRAM_DATA; 00298 return CaseTimeout(200) + CaseRepeatAll; 00299 } 00300 00301 virtualVolumeCallbackStatus = rc; 00302 /* intentional fallthrough */ 00303 00304 case PROGRAM_DATA: 00305 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00306 for (size_t index = 0; index < sizeofDataOperation; index++) { 00307 // if (bytePattern != (buffer)[index]) { 00308 // tr_info("%u: expected %x, found %x", index, bytePattern, buffer[index]); 00309 // } 00310 TEST_ASSERT_EQUAL(info.erased_value ? (uint8_t)0xFF : (uint8_t)0, buffer[index]); 00311 } 00312 00313 /* ProgramData */ 00314 memset(buffer, PATTERN_FOR_PROGRAM_DATA, sizeofDataOperation); 00315 rc = volumeP->ProgramData(0, buffer, sizeofDataOperation); 00316 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00317 if (rc == ARM_DRIVER_OK) { 00318 TEST_ASSERT_EQUAL(1, volumeP->GetCapabilities().asynchronous_ops); 00319 state = READ_AFTER_PROGRAM_DATA; 00320 return CaseTimeout(200) + CaseRepeatAll; 00321 } 00322 00323 virtualVolumeCallbackStatus = rc; 00324 /* intentional fallthrough */ 00325 00326 case READ_AFTER_PROGRAM_DATA: 00327 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00328 00329 /* Read after Program */ 00330 rc = volumeP->ReadData(0, buffer, sizeofDataOperation); 00331 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00332 if (rc == ARM_DRIVER_OK) { 00333 TEST_ASSERT_EQUAL(1, volumeP->GetCapabilities().asynchronous_ops); 00334 state = VERIFY_PROGRAM_DATA; 00335 return CaseTimeout(200) + CaseRepeatAll; 00336 } 00337 00338 virtualVolumeCallbackStatus = rc; 00339 /* intentional fallthrough */ 00340 00341 case VERIFY_PROGRAM_DATA: 00342 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00343 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 00344 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 00345 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00346 } 00347 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00348 } 00349 /* intentional fallthrough */ 00350 00351 case DISCONNECT_VOLUME_MANAGER_CALLBACK: 00352 rc = drv->Initialize(mtdCallbackHandler); 00353 TEST_ASSERT_EQUAL(1, rc); /* expect synchronous completion */ 00354 /* intentional fallthrough */ 00355 00356 case READ_FROM_DRV_AFTER_PROGRAM_DATA: 00357 /* Read after Program */ 00358 rc = drv->ReadData(firstBlock.addr + OFFSET, buffer, sizeofDataOperation); 00359 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00360 if (rc == ARM_DRIVER_OK) { 00361 TEST_ASSERT_EQUAL(1, volumeP->GetCapabilities().asynchronous_ops); 00362 state = VERIFY_PROGRAM_DATA2; 00363 return CaseTimeout(200) + CaseRepeatAll; 00364 } 00365 00366 callbackStatus = rc; 00367 /* intentional fallthrough */ 00368 00369 case VERIFY_PROGRAM_DATA2: 00370 TEST_ASSERT_EQUAL(sizeofDataOperation, callbackStatus); 00371 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 00372 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 00373 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00374 } 00375 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00376 } 00377 break; 00378 00379 default: 00380 TEST_ASSERT(false); 00381 } 00382 00383 return CaseNext; 00384 } 00385 00386 template <uint64_t OFFSET> 00387 control_t test_againstSingleCStorageAtOffset(const size_t call_count) 00388 { 00389 tr_info("test_againstSingleCStorageAtOffset: called with call_count %lu", call_count); 00390 static StorageVolumeManager volumeManager; 00391 static _ARM_DRIVER_STORAGE mtd = {}; 00392 static ARM_STORAGE_INFO info; 00393 static size_t sizeofDataOperation; 00394 00395 const uint8_t PATTERN_FOR_PROGRAM_DATA = 0xAA; 00396 00397 static enum { 00398 VOLUME_MANAGER_INITIALIZE = 1, 00399 BASIC_SYNCHRONOUS_API_TESTING, 00400 READ_DATA, 00401 ERASE, 00402 READ_AFTER_ERASE, 00403 PROGRAM_DATA, 00404 READ_AFTER_PROGRAM_DATA, 00405 VERIFY_PROGRAM_DATA, 00406 DISCONNECT_VOLUME_MANAGER_CALLBACK, 00407 READ_FROM_DRV_AFTER_PROGRAM_DATA, 00408 VERIFY_PROGRAM_DATA2, 00409 } state = VOLUME_MANAGER_INITIALIZE; 00410 tr_info("came in with state %u", state); 00411 00412 int32_t rc; 00413 rc = drv->GetNextBlock(NULL, NULL); 00414 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00415 ARM_STORAGE_BLOCK firstBlock; 00416 rc = drv->GetNextBlock(NULL, &firstBlock); 00417 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00418 TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); 00419 00420 switch (state) { 00421 case VOLUME_MANAGER_INITIALIZE: 00422 rc = volumeManager.initialize(drv, initializeCallbackHandler); 00423 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00424 if (rc == ARM_DRIVER_OK) { 00425 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00426 state = BASIC_SYNCHRONOUS_API_TESTING; 00427 return CaseTimeout(200) + CaseRepeatAll; 00428 } 00429 00430 /* synchronous completion */ 00431 TEST_ASSERT(rc == 1); 00432 00433 /* intentional fall-through */ 00434 00435 case BASIC_SYNCHRONOUS_API_TESTING: 00436 TEST_ASSERT_EQUAL(true, volumeManager.isInitialized()); 00437 00438 rc = drv->GetInfo(&info); 00439 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00440 TEST_ASSERT(info.total_storage > 0); 00441 00442 { /* add volume */ 00443 rc = volumeManager.addVolume_C(firstBlock.addr + OFFSET /*addr*/, info.total_storage - OFFSET /*size*/ , &mtd); 00444 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00445 00446 TEST_ASSERT_EQUAL(true, volumeManager.volumeAtIndex(0)->isAllocated()); 00447 for (size_t index = 1; index < MAX_VOLUMES; index++) { 00448 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 00449 } 00450 } 00451 00452 { /* GetVersion */ 00453 TEST_ASSERT_EQUAL(drv->GetVersion().api, mtd.GetVersion().api); 00454 TEST_ASSERT_EQUAL(drv->GetVersion().drv, mtd.GetVersion().drv); 00455 } 00456 00457 { /* GetCapabilities */ 00458 TEST_ASSERT_EQUAL(drv->GetCapabilities().asynchronous_ops, mtd.GetCapabilities().asynchronous_ops); 00459 TEST_ASSERT_EQUAL(drv->GetCapabilities().erase_all, mtd.GetCapabilities().erase_all); 00460 } 00461 00462 { /* Initialize */ 00463 rc = mtd.Initialize(virtualMTDCallbackHandler); 00464 TEST_ASSERT_EQUAL(1, rc); 00465 } 00466 00467 { /* GetStatus */ 00468 ARM_STORAGE_STATUS status = mtd.GetStatus(); 00469 TEST_ASSERT_EQUAL(0, status.busy); 00470 TEST_ASSERT_EQUAL(0, status.error); 00471 } 00472 00473 { /* GetInfo */ 00474 ARM_STORAGE_INFO volumeInfo; 00475 rc = mtd.GetInfo(&volumeInfo); 00476 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00477 00478 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, volumeInfo.total_storage); 00479 TEST_ASSERT_EQUAL(info.program_unit, volumeInfo.program_unit); 00480 TEST_ASSERT_EQUAL(info.optimal_program_unit, volumeInfo.optimal_program_unit); 00481 TEST_ASSERT_EQUAL(info.program_cycles, volumeInfo.program_cycles); 00482 TEST_ASSERT_EQUAL(info.erased_value, volumeInfo.erased_value); 00483 TEST_ASSERT_EQUAL(info.memory_mapped, volumeInfo.memory_mapped); 00484 TEST_ASSERT_EQUAL(info.programmability, volumeInfo.programmability); 00485 TEST_ASSERT_EQUAL(info.retention_level, volumeInfo.retention_level); 00486 TEST_ASSERT_EQUAL(info.reserved, volumeInfo.reserved); 00487 TEST_ASSERT_EQUAL(0, memcmp(&info.security, &volumeInfo.security, sizeof(ARM_STORAGE_SECURITY_FEATURES))); 00488 } 00489 00490 { /* resolve address */ 00491 TEST_ASSERT_EQUAL(firstBlock.addr + OFFSET, mtd.ResolveAddress(0)); 00492 TEST_ASSERT_EQUAL(firstBlock.addr + OFFSET + info.total_storage, mtd.ResolveAddress(info.total_storage)); 00493 TEST_ASSERT_EQUAL(firstBlock.addr + OFFSET + info.total_storage / 2, mtd.ResolveAddress(info.total_storage / 2)); 00494 } 00495 00496 { /* GetNextBlock */ 00497 rc = mtd.GetNextBlock(NULL, NULL); 00498 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00499 ARM_STORAGE_BLOCK block; 00500 rc = mtd.GetNextBlock(NULL, &block); 00501 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00502 TEST_ASSERT_EQUAL(0, block.addr); 00503 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, block.size); 00504 00505 rc = mtd.GetNextBlock(&block, NULL); 00506 TEST_ASSERT(rc < ARM_DRIVER_OK); 00507 rc = mtd.GetNextBlock(&block, &block); 00508 TEST_ASSERT(rc < ARM_DRIVER_OK); 00509 } 00510 00511 { /* GetBlock */ 00512 rc = mtd.GetBlock(0, NULL); 00513 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00514 ARM_STORAGE_BLOCK block; 00515 rc = mtd.GetBlock(0, &block); 00516 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00517 TEST_ASSERT_EQUAL(0, block.addr); 00518 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, block.size); 00519 00520 rc = mtd.GetBlock((info.total_storage / 2), NULL); 00521 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00522 rc = mtd.GetBlock((info.total_storage / 2), &block); 00523 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00524 TEST_ASSERT_EQUAL(0, block.addr); 00525 TEST_ASSERT_EQUAL(info.total_storage - OFFSET, block.size); 00526 00527 rc = mtd.GetBlock(info.total_storage, NULL); 00528 TEST_ASSERT(rc < ARM_DRIVER_OK); 00529 rc = mtd.GetBlock(info.total_storage, &block); 00530 TEST_ASSERT(rc < ARM_DRIVER_OK); 00531 } 00532 00533 state = READ_DATA; 00534 /* intentional fallthrough */ 00535 00536 case READ_DATA: 00537 sizeofDataOperation = ((info.total_storage - OFFSET) > BUFFER_SIZE) ? BUFFER_SIZE : (info.total_storage - OFFSET); 00538 TEST_ASSERT(sizeofDataOperation <= BUFFER_SIZE); 00539 00540 /* ReadData */ 00541 rc = mtd.ReadData(0, buffer, sizeofDataOperation); 00542 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00543 if (rc == ARM_DRIVER_OK) { 00544 TEST_ASSERT_EQUAL(1, mtd.GetCapabilities().asynchronous_ops); 00545 state = ERASE; 00546 return CaseTimeout(200) + CaseRepeatAll; 00547 } 00548 00549 virtualVolumeCallbackStatus = rc; 00550 /* intentional fallthrough */ 00551 00552 case ERASE: 00553 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00554 00555 /* Erase */ 00556 rc = mtd.Erase(0, sizeofDataOperation); 00557 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00558 if (rc == ARM_DRIVER_OK) { 00559 TEST_ASSERT_EQUAL(1, mtd.GetCapabilities().asynchronous_ops); 00560 state = READ_AFTER_ERASE; 00561 return CaseTimeout(200) + CaseRepeatAll; 00562 } 00563 00564 virtualVolumeCallbackStatus = rc; 00565 /* intentional fallthrough */ 00566 00567 case READ_AFTER_ERASE: 00568 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00569 00570 /* Read after Erase */ 00571 rc = mtd.ReadData(0, buffer, sizeofDataOperation); 00572 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00573 if (rc == ARM_DRIVER_OK) { 00574 TEST_ASSERT_EQUAL(1, mtd.GetCapabilities().asynchronous_ops); 00575 state = PROGRAM_DATA; 00576 return CaseTimeout(200) + CaseRepeatAll; 00577 } 00578 00579 virtualVolumeCallbackStatus = rc; 00580 /* intentional fallthrough */ 00581 00582 case PROGRAM_DATA: 00583 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00584 for (size_t index = 0; index < sizeofDataOperation; index++) { 00585 // if (bytePattern != (buffer)[index]) { 00586 // tr_info("%u: expected %x, found %x", index, bytePattern, buffer[index]); 00587 // } 00588 TEST_ASSERT_EQUAL(info.erased_value ? (uint8_t)0xFF : (uint8_t)0, buffer[index]); 00589 } 00590 00591 /* ProgramData */ 00592 memset(buffer, PATTERN_FOR_PROGRAM_DATA, sizeofDataOperation); 00593 rc = mtd.ProgramData(0, buffer, sizeofDataOperation); 00594 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00595 if (rc == ARM_DRIVER_OK) { 00596 TEST_ASSERT_EQUAL(1, mtd.GetCapabilities().asynchronous_ops); 00597 state = READ_AFTER_PROGRAM_DATA; 00598 return CaseTimeout(200) + CaseRepeatAll; 00599 } 00600 00601 virtualVolumeCallbackStatus = rc; 00602 /* intentional fallthrough */ 00603 00604 case READ_AFTER_PROGRAM_DATA: 00605 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00606 00607 /* Read after Program */ 00608 rc = mtd.ReadData(0, buffer, sizeofDataOperation); 00609 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00610 if (rc == ARM_DRIVER_OK) { 00611 TEST_ASSERT_EQUAL(1, mtd.GetCapabilities().asynchronous_ops); 00612 state = VERIFY_PROGRAM_DATA; 00613 return CaseTimeout(200) + CaseRepeatAll; 00614 } 00615 00616 virtualVolumeCallbackStatus = rc; 00617 /* intentional fallthrough */ 00618 00619 case VERIFY_PROGRAM_DATA: 00620 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00621 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 00622 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 00623 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00624 } 00625 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00626 } 00627 /* intentional fallthrough */ 00628 00629 case DISCONNECT_VOLUME_MANAGER_CALLBACK: 00630 rc = drv->Initialize(mtdCallbackHandler); 00631 TEST_ASSERT_EQUAL(1, rc); /* expect synchronous completion */ 00632 /* intentional fallthrough */ 00633 00634 case READ_FROM_DRV_AFTER_PROGRAM_DATA: 00635 /* Read after Program */ 00636 rc = drv->ReadData(firstBlock.addr + OFFSET, buffer, sizeofDataOperation); 00637 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00638 if (rc == ARM_DRIVER_OK) { 00639 TEST_ASSERT_EQUAL(1, mtd.GetCapabilities().asynchronous_ops); 00640 state = VERIFY_PROGRAM_DATA2; 00641 return CaseTimeout(200) + CaseRepeatAll; 00642 } 00643 00644 callbackStatus = rc; 00645 /* intentional fallthrough */ 00646 00647 case VERIFY_PROGRAM_DATA2: 00648 TEST_ASSERT_EQUAL(sizeofDataOperation, callbackStatus); 00649 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 00650 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 00651 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00652 } 00653 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00654 } 00655 break; 00656 00657 default: 00658 TEST_ASSERT(false); 00659 } 00660 00661 return CaseNext; 00662 } 00663 00664 template <uint64_t OFFSET1, uint64_t SIZE1, uint64_t OFFSET2, uint64_t SIZE2> 00665 control_t test_concurrentAccessFromTwoVolumes(const size_t call_count) 00666 { 00667 tr_info("test_concurrentAccessFromTwoVolumes: called with call_count %lu", call_count); 00668 00669 if (MAX_VOLUMES <= 1) { 00670 return CaseNext; 00671 } 00672 00673 static StorageVolumeManager volumeManager; 00674 static StorageVolume *volume1P = NULL; 00675 static StorageVolume *volume2P = NULL; 00676 static ARM_STORAGE_INFO info; 00677 static size_t sizeofDataOperation; 00678 00679 const uint8_t PATTERN_FOR_PROGRAM_DATA = 0xAA; 00680 00681 static enum { 00682 VOLUME_MANAGER_INITIALIZE = 1, 00683 ADD_VOLUMES, 00684 ERASE1, 00685 PROGRAM_DATA1, 00686 ERASE2, 00687 PROGRAM_DATA2, 00688 DISCONNECT_VOLUME_MANAGER_CALLBACK, 00689 READ_FROM_DRV_AFTER_PROGRAM_DATA1, 00690 VERIFY_PROGRAM_DATA1, 00691 READ_FROM_DRV_AFTER_PROGRAM_DATA2, 00692 VERIFY_PROGRAM_DATA2, 00693 } state = VOLUME_MANAGER_INITIALIZE; 00694 tr_info("came in with state %u", state); 00695 00696 int32_t rc; 00697 switch (state) { 00698 case VOLUME_MANAGER_INITIALIZE: 00699 rc = volumeManager.initialize(drv, initializeCallbackHandler); 00700 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00701 if (rc == ARM_DRIVER_OK) { 00702 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00703 state = ADD_VOLUMES; 00704 return CaseTimeout(200) + CaseRepeatAll; 00705 } 00706 00707 /* synchronous completion */ 00708 TEST_ASSERT(rc == 1); 00709 00710 /* intentional fall-through */ 00711 00712 case ADD_VOLUMES: 00713 TEST_ASSERT_EQUAL(true, volumeManager.isInitialized()); 00714 00715 rc = drv->GetInfo(&info); 00716 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00717 TEST_ASSERT(info.total_storage > 0); 00718 00719 { /* add volume1 */ 00720 rc = drv->GetBlock(OFFSET1, NULL); 00721 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00722 ARM_STORAGE_BLOCK block1; 00723 rc = drv->GetBlock(OFFSET1, &block1); 00724 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00725 rc = drv->GetBlock(OFFSET1 + SIZE1 - 1, NULL); 00726 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00727 rc = drv->GetBlock(OFFSET1 + SIZE1 - 1, &block1); 00728 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00729 00730 rc = volumeManager.addVolume(OFFSET1 /*addr*/, SIZE1 /*size*/ , &volume1P); 00731 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00732 00733 TEST_ASSERT_EQUAL(true, volumeManager.volumeAtIndex(0)->isAllocated()); 00734 for (size_t index = 1; index < MAX_VOLUMES; index++) { 00735 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 00736 } 00737 00738 { /* Initialize */ 00739 rc = volume1P->Initialize(virtualMTDCallbackHandler); 00740 TEST_ASSERT_EQUAL(1, rc); 00741 } 00742 } 00743 { /* add volume2 */ 00744 rc = drv->GetBlock(OFFSET2, NULL); 00745 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00746 ARM_STORAGE_BLOCK block2; 00747 rc = drv->GetBlock(OFFSET2, &block2); 00748 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00749 rc = drv->GetBlock(OFFSET2 + SIZE2 - 2, NULL); 00750 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00751 rc = drv->GetBlock(OFFSET2 + SIZE2 - 2, &block2); 00752 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00753 00754 rc = volumeManager.addVolume(OFFSET2 /*addr*/, SIZE2 /*size*/ , &volume2P); 00755 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00756 00757 TEST_ASSERT_EQUAL(true, volumeManager.volumeAtIndex(1)->isAllocated()); 00758 for (size_t index = 2; index < MAX_VOLUMES; index++) { 00759 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 00760 } 00761 00762 { /* Initialize */ 00763 rc = volume2P->Initialize(virtualMTDCallbackHandler); 00764 TEST_ASSERT_EQUAL(1, rc); 00765 } 00766 } 00767 00768 sizeofDataOperation = (SIZE1 > BUFFER_SIZE) ? BUFFER_SIZE : SIZE1; 00769 sizeofDataOperation = (SIZE2 > sizeofDataOperation) ? sizeofDataOperation : SIZE2; 00770 TEST_ASSERT((sizeofDataOperation > 0) && (sizeofDataOperation <= BUFFER_SIZE)); 00771 memset(buffer, PATTERN_FOR_PROGRAM_DATA, sizeofDataOperation); 00772 00773 /* intentional fall-through */ 00774 00775 case ERASE1: 00776 rc = volume1P->Erase(0, sizeofDataOperation); 00777 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00778 if (rc == ARM_DRIVER_OK) { 00779 TEST_ASSERT_EQUAL(1, volume1P->GetCapabilities().asynchronous_ops); 00780 state = PROGRAM_DATA1; 00781 return CaseTimeout(200) + CaseRepeatAll; 00782 } 00783 00784 virtualVolumeCallbackStatus = rc; 00785 /* intentional fallthrough */ 00786 00787 case PROGRAM_DATA1: 00788 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00789 00790 tr_info("PROGRAM_DATA1"); 00791 rc = volume1P->ProgramData(0, buffer, sizeofDataOperation); 00792 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00793 if (rc == ARM_DRIVER_OK) { 00794 TEST_ASSERT_EQUAL(1, volume1P->GetCapabilities().asynchronous_ops); 00795 00796 ARM_STORAGE_STATUS status; 00797 status = drv->GetStatus(); 00798 TEST_ASSERT_EQUAL(1, status.busy); 00799 TEST_ASSERT_EQUAL(0, status.error); 00800 status = volume1P->GetStatus(); 00801 TEST_ASSERT_EQUAL(1, status.busy); 00802 TEST_ASSERT_EQUAL(0, status.error); 00803 status = volume2P->GetStatus(); 00804 TEST_ASSERT_EQUAL(1, status.busy); 00805 TEST_ASSERT_EQUAL(0, status.error); 00806 00807 rc = volume2P->ProgramData(0, buffer, sizeofDataOperation); 00808 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00809 rc = volume1P->ProgramData(0, buffer, sizeofDataOperation); 00810 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00811 rc = volume1P->ReadData(0, buffer, sizeofDataOperation); 00812 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00813 rc = volume1P->Erase(0, sizeofDataOperation); 00814 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00815 00816 state = ERASE2; 00817 return CaseTimeout(200) + CaseRepeatAll; 00818 } 00819 00820 virtualVolumeCallbackStatus = rc; 00821 /* intentional fallthrough */ 00822 00823 case ERASE2: 00824 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00825 00826 rc = volume2P->Erase(0, sizeofDataOperation); 00827 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00828 if (rc == ARM_DRIVER_OK) { 00829 TEST_ASSERT_EQUAL(1, volume2P->GetCapabilities().asynchronous_ops); 00830 state = PROGRAM_DATA2; 00831 return CaseTimeout(200) + CaseRepeatAll; 00832 } 00833 00834 virtualVolumeCallbackStatus = rc; 00835 /* intentional fallthrough */ 00836 00837 case PROGRAM_DATA2: 00838 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00839 00840 tr_info("PROGRAM_DATA2"); 00841 rc = volume2P->ProgramData(0, buffer, sizeofDataOperation); 00842 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00843 if (rc == ARM_DRIVER_OK) { 00844 TEST_ASSERT_EQUAL(1, volume2P->GetCapabilities().asynchronous_ops); 00845 00846 ARM_STORAGE_STATUS status; 00847 status = drv->GetStatus(); 00848 TEST_ASSERT_EQUAL(1, status.busy); 00849 TEST_ASSERT_EQUAL(0, status.error); 00850 status = volume2P->GetStatus(); 00851 TEST_ASSERT_EQUAL(1, status.busy); 00852 TEST_ASSERT_EQUAL(0, status.error); 00853 status = volume1P->GetStatus(); 00854 TEST_ASSERT_EQUAL(1, status.busy); 00855 TEST_ASSERT_EQUAL(0, status.error); 00856 00857 rc = volume1P->ProgramData(0, buffer, sizeofDataOperation); 00858 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00859 rc = volume2P->ProgramData(0, buffer, sizeofDataOperation); 00860 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00861 rc = volume2P->ReadData(0, buffer, sizeofDataOperation); 00862 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00863 rc = volume2P->Erase(0, sizeofDataOperation); 00864 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 00865 00866 state = DISCONNECT_VOLUME_MANAGER_CALLBACK; 00867 return CaseTimeout(200) + CaseRepeatAll; 00868 } 00869 00870 virtualVolumeCallbackStatus = rc; 00871 /* intentional fallthrough */ 00872 00873 case DISCONNECT_VOLUME_MANAGER_CALLBACK: 00874 tr_info("DISCONNECT_VOLUME_MANAGER_CALLBACK"); 00875 rc = drv->Initialize(mtdCallbackHandler); 00876 TEST_ASSERT_EQUAL(1, rc); /* expect synchronous completion */ 00877 /* intentional fallthrough */ 00878 00879 case READ_FROM_DRV_AFTER_PROGRAM_DATA1: 00880 tr_info("verifying state"); 00881 /* Read after Program */ 00882 rc = drv->ReadData(OFFSET1, buffer, sizeofDataOperation); 00883 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00884 if (rc == ARM_DRIVER_OK) { 00885 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00886 state = VERIFY_PROGRAM_DATA1; 00887 return CaseTimeout(200) + CaseRepeatAll; 00888 } 00889 00890 virtualVolumeCallbackStatus = rc; 00891 /* intentional fallthrough */ 00892 00893 case VERIFY_PROGRAM_DATA1: 00894 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00895 00896 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 00897 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 00898 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00899 } 00900 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00901 } 00902 /* intentional fallthrough */ 00903 00904 case READ_FROM_DRV_AFTER_PROGRAM_DATA2: 00905 /* Read after Program */ 00906 rc = drv->ReadData(OFFSET2, buffer, sizeofDataOperation); 00907 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00908 if (rc == ARM_DRIVER_OK) { 00909 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00910 state = VERIFY_PROGRAM_DATA2; 00911 return CaseTimeout(200) + CaseRepeatAll; 00912 } 00913 00914 virtualVolumeCallbackStatus = rc; 00915 /* intentional fallthrough */ 00916 00917 case VERIFY_PROGRAM_DATA2: 00918 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 00919 00920 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 00921 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 00922 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00923 } 00924 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 00925 } 00926 break; 00927 00928 default: 00929 TEST_ASSERT(false); 00930 } 00931 00932 return CaseNext; 00933 } 00934 00935 template <uint64_t OFFSET1, uint64_t SIZE1, uint64_t OFFSET2, uint64_t SIZE2> 00936 control_t test_concurrentAccessFromTwoCStorageDevices(const size_t call_count) 00937 { 00938 tr_info("test_concurrentAccessFromTwoCStorageDevices: called with call_count %lu", call_count); 00939 00940 if (MAX_VOLUMES <= 1) { 00941 return CaseNext; 00942 } 00943 00944 static StorageVolumeManager volumeManager; 00945 static _ARM_DRIVER_STORAGE mtd1 = {}; 00946 static _ARM_DRIVER_STORAGE mtd2 = {}; 00947 static ARM_STORAGE_INFO info; 00948 static size_t sizeofDataOperation; 00949 00950 const uint8_t PATTERN_FOR_PROGRAM_DATA = 0xAA; 00951 00952 static enum { 00953 VOLUME_MANAGER_INITIALIZE = 1, 00954 ADD_VOLUMES, 00955 ERASE1, 00956 PROGRAM_DATA1, 00957 ERASE2, 00958 PROGRAM_DATA2, 00959 DISCONNECT_VOLUME_MANAGER_CALLBACK, 00960 READ_FROM_DRV_AFTER_PROGRAM_DATA1, 00961 VERIFY_PROGRAM_DATA1, 00962 READ_FROM_DRV_AFTER_PROGRAM_DATA2, 00963 VERIFY_PROGRAM_DATA2, 00964 } state = VOLUME_MANAGER_INITIALIZE; 00965 tr_info("came in with state %u", state); 00966 00967 int32_t rc; 00968 switch (state) { 00969 case VOLUME_MANAGER_INITIALIZE: 00970 rc = volumeManager.initialize(drv, initializeCallbackHandler); 00971 TEST_ASSERT(rc >= ARM_DRIVER_OK); 00972 if (rc == ARM_DRIVER_OK) { 00973 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 00974 state = ADD_VOLUMES; 00975 return CaseTimeout(200) + CaseRepeatAll; 00976 } 00977 00978 /* synchronous completion */ 00979 TEST_ASSERT(rc == 1); 00980 00981 /* intentional fall-through */ 00982 00983 case ADD_VOLUMES: 00984 TEST_ASSERT_EQUAL(true, volumeManager.isInitialized()); 00985 00986 rc = drv->GetInfo(&info); 00987 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00988 TEST_ASSERT(info.total_storage > 0); 00989 00990 { /* add C_Storage device 1 */ 00991 ARM_STORAGE_BLOCK block1; 00992 rc = drv->GetBlock(OFFSET1, &block1); 00993 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00994 rc = drv->GetBlock(OFFSET1 + SIZE1 - 1, &block1); 00995 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00996 00997 rc = volumeManager.addVolume_C(OFFSET1 /*addr*/, SIZE1 /*size*/ , &mtd1); 00998 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 00999 01000 TEST_ASSERT_EQUAL(true, volumeManager.volumeAtIndex(0)->isAllocated()); 01001 for (size_t index = 1; index < MAX_VOLUMES; index++) { 01002 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 01003 } 01004 01005 { /* Initialize */ 01006 rc = mtd1.Initialize(virtualMTDCallbackHandler); 01007 TEST_ASSERT_EQUAL(1, rc); 01008 } 01009 } 01010 { /* add C_Storage device 2 */ 01011 ARM_STORAGE_BLOCK block2; 01012 rc = drv->GetBlock(OFFSET2, &block2); 01013 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 01014 rc = drv->GetBlock(OFFSET2 + SIZE2 - 2, &block2); 01015 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 01016 01017 rc = volumeManager.addVolume_C(OFFSET2 /*addr*/, SIZE2 /*size*/ , &mtd2); 01018 TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); 01019 01020 TEST_ASSERT_EQUAL(true, volumeManager.volumeAtIndex(1)->isAllocated()); 01021 for (size_t index = 2; index < MAX_VOLUMES; index++) { 01022 TEST_ASSERT_EQUAL(false, volumeManager.volumeAtIndex(index)->isAllocated()); 01023 } 01024 01025 { /* Initialize */ 01026 rc = mtd2.Initialize(virtualMTDCallbackHandler); 01027 TEST_ASSERT_EQUAL(1, rc); 01028 } 01029 } 01030 01031 sizeofDataOperation = (SIZE1 > BUFFER_SIZE) ? BUFFER_SIZE : SIZE1; 01032 sizeofDataOperation = (SIZE2 > sizeofDataOperation) ? sizeofDataOperation : SIZE2; 01033 TEST_ASSERT((sizeofDataOperation > 0) && (sizeofDataOperation <= BUFFER_SIZE)); 01034 memset(buffer, PATTERN_FOR_PROGRAM_DATA, sizeofDataOperation); 01035 01036 /* intentional fall-through */ 01037 01038 case ERASE1: 01039 rc = mtd1.Erase(0, sizeofDataOperation); 01040 TEST_ASSERT(rc >= ARM_DRIVER_OK); 01041 if (rc == ARM_DRIVER_OK) { 01042 TEST_ASSERT_EQUAL(1, mtd1.GetCapabilities().asynchronous_ops); 01043 state = PROGRAM_DATA1; 01044 return CaseTimeout(200) + CaseRepeatAll; 01045 } 01046 01047 virtualVolumeCallbackStatus = rc; 01048 /* intentional fallthrough */ 01049 01050 case PROGRAM_DATA1: 01051 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 01052 01053 tr_info("PROGRAM_DATA1"); 01054 rc = mtd1.ProgramData(0, buffer, sizeofDataOperation); 01055 TEST_ASSERT(rc >= ARM_DRIVER_OK); 01056 if (rc == ARM_DRIVER_OK) { 01057 TEST_ASSERT_EQUAL(1, mtd1.GetCapabilities().asynchronous_ops); 01058 01059 ARM_STORAGE_STATUS status; 01060 status = drv->GetStatus(); 01061 TEST_ASSERT_EQUAL(1, status.busy); 01062 TEST_ASSERT_EQUAL(0, status.error); 01063 status = mtd1.GetStatus(); 01064 TEST_ASSERT_EQUAL(1, status.busy); 01065 TEST_ASSERT_EQUAL(0, status.error); 01066 status = mtd2.GetStatus(); 01067 TEST_ASSERT_EQUAL(1, status.busy); 01068 TEST_ASSERT_EQUAL(0, status.error); 01069 01070 rc = mtd2.ProgramData(0, buffer, sizeofDataOperation); 01071 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01072 rc = mtd1.ProgramData(0, buffer, sizeofDataOperation); 01073 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01074 rc = mtd1.ReadData(0, buffer, sizeofDataOperation); 01075 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01076 rc = mtd1.Erase(0, sizeofDataOperation); 01077 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01078 01079 state = ERASE2; 01080 return CaseTimeout(200) + CaseRepeatAll; 01081 } 01082 01083 virtualVolumeCallbackStatus = rc; 01084 /* intentional fallthrough */ 01085 01086 case ERASE2: 01087 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 01088 01089 rc = mtd2.Erase(0, sizeofDataOperation); 01090 TEST_ASSERT(rc >= ARM_DRIVER_OK); 01091 if (rc == ARM_DRIVER_OK) { 01092 TEST_ASSERT_EQUAL(1, mtd2.GetCapabilities().asynchronous_ops); 01093 state = PROGRAM_DATA2; 01094 return CaseTimeout(200) + CaseRepeatAll; 01095 } 01096 01097 virtualVolumeCallbackStatus = rc; 01098 /* intentional fallthrough */ 01099 01100 case PROGRAM_DATA2: 01101 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 01102 01103 tr_info("PROGRAM_DATA2"); 01104 rc = mtd2.ProgramData(0, buffer, sizeofDataOperation); 01105 TEST_ASSERT(rc >= ARM_DRIVER_OK); 01106 if (rc == ARM_DRIVER_OK) { 01107 TEST_ASSERT_EQUAL(1, mtd2.GetCapabilities().asynchronous_ops); 01108 01109 ARM_STORAGE_STATUS status; 01110 status = drv->GetStatus(); 01111 TEST_ASSERT_EQUAL(1, status.busy); 01112 TEST_ASSERT_EQUAL(0, status.error); 01113 status = mtd2.GetStatus(); 01114 TEST_ASSERT_EQUAL(1, status.busy); 01115 TEST_ASSERT_EQUAL(0, status.error); 01116 status = mtd1.GetStatus(); 01117 TEST_ASSERT_EQUAL(1, status.busy); 01118 TEST_ASSERT_EQUAL(0, status.error); 01119 01120 rc = mtd1.ProgramData(0, buffer, sizeofDataOperation); 01121 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01122 rc = mtd2.ProgramData(0, buffer, sizeofDataOperation); 01123 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01124 rc = mtd2.ReadData(0, buffer, sizeofDataOperation); 01125 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01126 rc = mtd2.Erase(0, sizeofDataOperation); 01127 TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_BUSY, rc); 01128 01129 state = DISCONNECT_VOLUME_MANAGER_CALLBACK; 01130 return CaseTimeout(200) + CaseRepeatAll; 01131 } 01132 01133 virtualVolumeCallbackStatus = rc; 01134 /* intentional fallthrough */ 01135 01136 case DISCONNECT_VOLUME_MANAGER_CALLBACK: 01137 tr_info("DISCONNECT_VOLUME_MANAGER_CALLBACK"); 01138 rc = drv->Initialize(mtdCallbackHandler); 01139 TEST_ASSERT_EQUAL(1, rc); /* expect synchronous completion */ 01140 /* intentional fallthrough */ 01141 01142 case READ_FROM_DRV_AFTER_PROGRAM_DATA1: 01143 tr_info("verifying state"); 01144 /* Read after Program */ 01145 rc = drv->ReadData(OFFSET1, buffer, sizeofDataOperation); 01146 TEST_ASSERT(rc >= ARM_DRIVER_OK); 01147 if (rc == ARM_DRIVER_OK) { 01148 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 01149 state = VERIFY_PROGRAM_DATA1; 01150 return CaseTimeout(200) + CaseRepeatAll; 01151 } 01152 01153 virtualVolumeCallbackStatus = rc; 01154 /* intentional fallthrough */ 01155 01156 case VERIFY_PROGRAM_DATA1: 01157 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 01158 01159 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 01160 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 01161 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 01162 } 01163 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 01164 } 01165 /* intentional fallthrough */ 01166 01167 case READ_FROM_DRV_AFTER_PROGRAM_DATA2: 01168 /* Read after Program */ 01169 rc = drv->ReadData(OFFSET2, buffer, sizeofDataOperation); 01170 TEST_ASSERT(rc >= ARM_DRIVER_OK); 01171 if (rc == ARM_DRIVER_OK) { 01172 TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops); 01173 state = VERIFY_PROGRAM_DATA2; 01174 return CaseTimeout(200) + CaseRepeatAll; 01175 } 01176 01177 virtualVolumeCallbackStatus = rc; 01178 /* intentional fallthrough */ 01179 01180 case VERIFY_PROGRAM_DATA2: 01181 TEST_ASSERT_EQUAL(sizeofDataOperation, virtualVolumeCallbackStatus); 01182 01183 for (uint32_t index = 0; index < sizeofDataOperation; index++) { 01184 if ((buffer)[index] != PATTERN_FOR_PROGRAM_DATA) { 01185 tr_info("%s:%u: %" PRIu32 ": expected 0x%02x, found 0x%02x", __FUNCTION__, __LINE__, index, PATTERN_FOR_PROGRAM_DATA, buffer[index]); 01186 } 01187 TEST_ASSERT_EQUAL(PATTERN_FOR_PROGRAM_DATA, buffer[index]); 01188 } 01189 break; 01190 01191 default: 01192 TEST_ASSERT(false); 01193 } 01194 01195 return CaseNext; 01196 } 01197 01198 // Specify all your test cases here 01199 Case cases[] = { 01200 Case("initialize", test_initialize), 01201 Case("Against a single volume at offset", test_againstSingleVolumeAtOffset<0>), 01202 Case("Against a single volume at offset", test_againstSingleVolumeAtOffset<4096>), 01203 Case("Against a single volume at offset", test_againstSingleVolumeAtOffset<8192>), 01204 Case("Against a single volume at offset", test_againstSingleVolumeAtOffset<65536>), 01205 Case("Against a single C_Storage at offset", test_againstSingleCStorageAtOffset<0>), 01206 Case("Against a single C_Storage at offset", test_againstSingleCStorageAtOffset<4096>), 01207 Case("Against a single C_Storage at offset", test_againstSingleCStorageAtOffset<8192>), 01208 Case("Against a single C_Storage at offset", test_againstSingleCStorageAtOffset<65536>), 01209 01210 /* note: the following tests are unportable in the sense that they require the underlying storage device to support certain address ranges. */ 01211 Case("Concurrent accesss from two volumes", test_concurrentAccessFromTwoVolumes<512*1024, 128*1024, (512+128)*1024, 128*1024>), 01212 Case("Concurrent accesss from two volumes", test_concurrentAccessFromTwoVolumes<512*1024, 128*1024, (512+128)*1024, 128*1024>), 01213 Case("Concurrent accesss from two volumes", test_concurrentAccessFromTwoVolumes<512*1024, 128*1024, (512+256)*1024, 128*1024>), 01214 Case("Concurrent accesss from two volumes", test_concurrentAccessFromTwoVolumes<512*1024, 128*1024, (512+384)*1024, 128*1024>), 01215 Case("Concurrent accesss from two C_Storage devices", test_concurrentAccessFromTwoCStorageDevices<512*1024, 128*1024, (512+128)*1024, 128*1024>), 01216 Case("Concurrent accesss from two C_Storage devices", test_concurrentAccessFromTwoCStorageDevices<512*1024, 128*1024, (512+256)*1024, 128*1024>), 01217 Case("Concurrent accesss from two C_Storage devices", test_concurrentAccessFromTwoCStorageDevices<512*1024, 128*1024, (512+384)*1024, 128*1024>), 01218 }; 01219 01220 // Declare your test specification with a custom setup handler 01221 #ifndef AVOID_GREENTEA 01222 Specification specification(greentea_setup, cases); 01223 #else 01224 Specification specification([](const size_t) {return STATUS_CONTINUE;}, cases); 01225 #endif 01226 01227 int main(int argc, char** argv) 01228 { 01229 mbed_trace_init(); // initialize the trace library 01230 mbed_trace_config_set(TRACE_MODE_COLOR | TRACE_ACTIVE_LEVEL_INFO | TRACE_CARRIAGE_RETURN); 01231 01232 // Run the test specification 01233 Harness::run(specification); 01234 }
Generated on Tue Aug 9 2022 00:37:03 by
1.7.2