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.
Fork of 352 by
basic.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 /* The following copyright notice is reproduced from the glibc project 00020 * REF_LICENCE_GLIBC 00021 * 00022 * Copyright (C) 1991, 1992 Free Software Foundation, Inc. 00023 * This file is part of the GNU C Library. 00024 * 00025 * The GNU C Library is free software; you can redistribute it and/or 00026 * modify it under the terms of the GNU Library General Public License as 00027 * published by the Free Software Foundation; either version 2 of the 00028 * License, or (at your option) any later version. 00029 * 00030 * The GNU C Library is distributed in the hope that it will be useful, 00031 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00032 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00033 * Library General Public License for more details. 00034 * 00035 * You should have received a copy of the GNU Library General Public 00036 * License along with the GNU C Library; see the file COPYING.LIB. If 00037 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 00038 * Cambridge, MA 02139, USA. 00039 */ 00040 00041 00042 /** @file main.cpp Basic SD Driver Test 00043 */ 00044 #include "mbed.h" 00045 #include "greentea-client/test_env.h" 00046 #include "unity.h" 00047 #include "utest.h" 00048 00049 #include "SDBlockDevice.h" 00050 #include <stdlib.h> 00051 00052 using namespace utest::v1; 00053 00054 #define TEST_BLOCK_COUNT 10 00055 #define TEST_ERROR_MASK 16 00056 #define TEST_BLOCK_SIZE 2048 00057 00058 const struct { 00059 const char *name; 00060 bd_size_t (BlockDevice::*method)() const; 00061 } ATTRS[] = { 00062 {"read size", &BlockDevice::get_read_size}, 00063 {"program size", &BlockDevice::get_program_size}, 00064 {"erase size", &BlockDevice::get_erase_size}, 00065 {"total size", &BlockDevice::size}, 00066 }; 00067 00068 void test_read_write() { 00069 SDBlockDevice sd(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_SPI_CS); 00070 00071 int err = sd.init(); 00072 TEST_ASSERT_EQUAL(0, err); 00073 00074 err = sd.frequency(25000000); 00075 TEST_ASSERT_EQUAL(0, err); 00076 00077 for (unsigned a = 0; a < sizeof(ATTRS)/sizeof(ATTRS[0]); a++) { 00078 static const char *prefixes[] = {"", "k", "M", "G"}; 00079 for (int i = 3; i >= 0; i--) { 00080 bd_size_t size = (sd.*ATTRS[a].method)(); 00081 if (size >= (1ULL << 10*i)) { 00082 printf("%s: %llu%sbytes (%llubytes)\n", 00083 ATTRS[a].name, size >> 10*i, prefixes[i], size); 00084 break; 00085 } 00086 } 00087 } 00088 00089 bd_size_t erase_size = sd.get_erase_size(); 00090 bd_size_t block_size = erase_size > TEST_BLOCK_SIZE ? erase_size : TEST_BLOCK_SIZE; 00091 00092 uint8_t *write_block = new uint8_t[block_size]; 00093 uint8_t *read_block = new uint8_t[block_size]; 00094 uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; 00095 unsigned addrwidth = ceil(log(float(sd.size()-1)) / log(float(16)))+1; 00096 00097 for (int b = 0; b < TEST_BLOCK_COUNT; b++) { 00098 // Find a random block 00099 bd_addr_t block = (rand()*block_size) % sd.size(); 00100 00101 // Use next random number as temporary seed to keep 00102 // the address progressing in the pseudorandom sequence 00103 unsigned seed = rand(); 00104 00105 // Fill with random sequence 00106 srand(seed); 00107 for (bd_size_t i = 0; i < block_size; i++) { 00108 write_block[i] = 0xff & rand(); 00109 } 00110 00111 // Write, sync, and read the block 00112 printf("test %0*llx:%llu...\n", addrwidth, block, block_size); 00113 00114 err = sd.erase(block, block_size); 00115 TEST_ASSERT_EQUAL(0, err); 00116 00117 err = sd.program(write_block, block, block_size); 00118 TEST_ASSERT_EQUAL(0, err); 00119 00120 printf("write %0*llx:%llu ", addrwidth, block, block_size); 00121 for (int i = 0; i < 16; i++) { 00122 printf("%02x", write_block[i]); 00123 } 00124 printf("...\n"); 00125 00126 err = sd.read(read_block, block, block_size); 00127 TEST_ASSERT_EQUAL(0, err); 00128 00129 printf("read %0*llx:%llu ", addrwidth, block, block_size); 00130 for (int i = 0; i < 16; i++) { 00131 printf("%02x", read_block[i]); 00132 } 00133 printf("...\n"); 00134 00135 // Find error mask for debugging 00136 memset(error_mask, 0, TEST_ERROR_MASK); 00137 bd_size_t error_scale = block_size / (TEST_ERROR_MASK*8); 00138 00139 srand(seed); 00140 for (bd_size_t i = 0; i < TEST_ERROR_MASK*8; i++) { 00141 for (bd_size_t j = 0; j < error_scale; j++) { 00142 if ((0xff & rand()) != read_block[i*error_scale + j]) { 00143 error_mask[i/8] |= 1 << (i%8); 00144 } 00145 } 00146 } 00147 00148 printf("error %0*llx:%llu ", addrwidth, block, block_size); 00149 for (int i = 0; i < 16; i++) { 00150 printf("%02x", error_mask[i]); 00151 } 00152 printf("\n"); 00153 00154 // Check that the data was unmodified 00155 srand(seed); 00156 for (bd_size_t i = 0; i < block_size; i++) { 00157 TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); 00158 } 00159 } 00160 00161 err = sd.deinit(); 00162 TEST_ASSERT_EQUAL(0, err); 00163 } 00164 00165 // Test setup 00166 utest::v1::status_t test_setup(const size_t number_of_cases) { 00167 GREENTEA_SETUP(120, "default_auto"); 00168 return verbose_test_setup_handler(number_of_cases); 00169 } 00170 00171 Case cases[] = { 00172 Case("Testing read write random blocks", test_read_write), 00173 }; 00174 00175 Specification specification(test_setup, cases); 00176 00177 int main() { 00178 return !Harness::run(specification); 00179 }
Generated on Tue Jul 12 2022 21:51:18 by
