init
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed.h" 00017 #include "greentea-client/test_env.h" 00018 #include "unity.h" 00019 #include "utest.h" 00020 00021 #include "HeapBlockDevice.h" 00022 #include <stdlib.h> 00023 00024 using namespace utest::v1; 00025 00026 // TODO HACK, replace with available ram/heap property 00027 #if defined(TARGET_MTB_MTS_XDOT) 00028 #error [NOT_SUPPORTED] Insufficient heap for heap block device tests 00029 #endif 00030 00031 #define TEST_BLOCK_SIZE 128 00032 #define TEST_BLOCK_DEVICE_SIZE 32*TEST_BLOCK_SIZE 00033 #define TEST_BLOCK_COUNT 10 00034 #define TEST_ERROR_MASK 16 00035 00036 const struct { 00037 const char *name; 00038 bd_size_t (BlockDevice::*method)() const; 00039 } ATTRS[] = { 00040 {"read size", &BlockDevice::get_read_size}, 00041 {"program size", &BlockDevice::get_program_size}, 00042 {"erase size", &BlockDevice::get_erase_size}, 00043 {"total size", &BlockDevice::size}, 00044 }; 00045 00046 00047 // Simple test that read/writes random set of blocks 00048 void test_read_write() { 00049 HeapBlockDevice bd(TEST_BLOCK_DEVICE_SIZE, TEST_BLOCK_SIZE); 00050 00051 int err = bd.init(); 00052 TEST_ASSERT_EQUAL(0, err); 00053 00054 for (unsigned a = 0; a < sizeof(ATTRS)/sizeof(ATTRS[0]); a++) { 00055 static const char *prefixes[] = {"", "k", "M", "G"}; 00056 for (int i = 3; i >= 0; i--) { 00057 bd_size_t size = (bd.*ATTRS[a].method)(); 00058 if (size >= (1ULL << 10*i)) { 00059 printf("%s: %llu%sbytes (%llubytes)\n", 00060 ATTRS[a].name, size >> 10*i, prefixes[i], size); 00061 break; 00062 } 00063 } 00064 } 00065 00066 bd_size_t block_size = bd.get_erase_size(); 00067 uint8_t *write_block = new uint8_t[block_size]; 00068 uint8_t *read_block = new uint8_t[block_size]; 00069 uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; 00070 unsigned addrwidth = ceil(log(float(bd.size()-1)) / log(float(16)))+1; 00071 00072 for (int b = 0; b < TEST_BLOCK_COUNT; b++) { 00073 // Find a random block 00074 bd_addr_t block = (rand()*block_size) % bd.size(); 00075 00076 // Use next random number as temporary seed to keep 00077 // the address progressing in the pseudorandom sequence 00078 unsigned seed = rand(); 00079 00080 // Fill with random sequence 00081 srand(seed); 00082 for (bd_size_t i = 0; i < block_size; i++) { 00083 write_block[i] = 0xff & rand(); 00084 } 00085 00086 // erase, program, and read the block 00087 printf("test %0*llx:%llu...\n", addrwidth, block, block_size); 00088 00089 err = bd.erase(block, block_size); 00090 TEST_ASSERT_EQUAL(0, err); 00091 00092 err = bd.program(write_block, block, block_size); 00093 TEST_ASSERT_EQUAL(0, err); 00094 00095 printf("write %0*llx:%llu ", addrwidth, block, block_size); 00096 for (int i = 0; i < 16; i++) { 00097 printf("%02x", write_block[i]); 00098 } 00099 printf("...\n"); 00100 00101 err = bd.read(read_block, block, block_size); 00102 TEST_ASSERT_EQUAL(0, err); 00103 00104 printf("read %0*llx:%llu ", addrwidth, block, block_size); 00105 for (int i = 0; i < 16; i++) { 00106 printf("%02x", read_block[i]); 00107 } 00108 printf("...\n"); 00109 00110 // Find error mask for debugging 00111 memset(error_mask, 0, TEST_ERROR_MASK); 00112 bd_size_t error_scale = block_size / (TEST_ERROR_MASK*8); 00113 00114 srand(seed); 00115 for (bd_size_t i = 0; i < TEST_ERROR_MASK*8; i++) { 00116 for (bd_size_t j = 0; j < error_scale; j++) { 00117 if ((0xff & rand()) != read_block[i*error_scale + j]) { 00118 error_mask[i/8] |= 1 << (i%8); 00119 } 00120 } 00121 } 00122 00123 printf("error %0*llx:%llu ", addrwidth, block, block_size); 00124 for (int i = 0; i < 16; i++) { 00125 printf("%02x", error_mask[i]); 00126 } 00127 printf("\n"); 00128 00129 // Check that the data was unmodified 00130 srand(seed); 00131 for (bd_size_t i = 0; i < block_size; i++) { 00132 TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); 00133 } 00134 } 00135 00136 err = bd.deinit(); 00137 TEST_ASSERT_EQUAL(0, err); 00138 } 00139 00140 00141 // Test setup 00142 utest::v1::status_t test_setup(const size_t number_of_cases) { 00143 GREENTEA_SETUP(30, "default_auto"); 00144 return verbose_test_setup_handler(number_of_cases); 00145 } 00146 00147 Case cases[] = { 00148 Case("Testing read write random blocks", test_read_write), 00149 }; 00150 00151 Specification specification(test_setup, cases); 00152 00153 int main() { 00154 return !Harness::run(specification); 00155 }
Generated on Tue Jul 12 2022 13:24:53 by
1.7.2