GroupU - 05012018 1543
Fork of 352 by
sd-driver/TESTS/block_device/basic/basic.cpp@1:84581acd1333, 2018-01-09 (annotated)
- Committer:
- mslade
- Date:
- Tue Jan 09 14:53:07 2018 +0000
- Revision:
- 1:84581acd1333
Final Version - Group U
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mslade | 1:84581acd1333 | 1 | /* |
mslade | 1:84581acd1333 | 2 | * mbed Microcontroller Library |
mslade | 1:84581acd1333 | 3 | * Copyright (c) 2006-2016 ARM Limited |
mslade | 1:84581acd1333 | 4 | * |
mslade | 1:84581acd1333 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
mslade | 1:84581acd1333 | 6 | * you may not use this file except in compliance with the License. |
mslade | 1:84581acd1333 | 7 | * You may obtain a copy of the License at |
mslade | 1:84581acd1333 | 8 | * |
mslade | 1:84581acd1333 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
mslade | 1:84581acd1333 | 10 | * |
mslade | 1:84581acd1333 | 11 | * Unless required by applicable law or agreed to in writing, software |
mslade | 1:84581acd1333 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
mslade | 1:84581acd1333 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mslade | 1:84581acd1333 | 14 | * See the License for the specific language governing permissions and |
mslade | 1:84581acd1333 | 15 | * limitations under the License. |
mslade | 1:84581acd1333 | 16 | * |
mslade | 1:84581acd1333 | 17 | */ |
mslade | 1:84581acd1333 | 18 | |
mslade | 1:84581acd1333 | 19 | /* The following copyright notice is reproduced from the glibc project |
mslade | 1:84581acd1333 | 20 | * REF_LICENCE_GLIBC |
mslade | 1:84581acd1333 | 21 | * |
mslade | 1:84581acd1333 | 22 | * Copyright (C) 1991, 1992 Free Software Foundation, Inc. |
mslade | 1:84581acd1333 | 23 | * This file is part of the GNU C Library. |
mslade | 1:84581acd1333 | 24 | * |
mslade | 1:84581acd1333 | 25 | * The GNU C Library is free software; you can redistribute it and/or |
mslade | 1:84581acd1333 | 26 | * modify it under the terms of the GNU Library General Public License as |
mslade | 1:84581acd1333 | 27 | * published by the Free Software Foundation; either version 2 of the |
mslade | 1:84581acd1333 | 28 | * License, or (at your option) any later version. |
mslade | 1:84581acd1333 | 29 | * |
mslade | 1:84581acd1333 | 30 | * The GNU C Library is distributed in the hope that it will be useful, |
mslade | 1:84581acd1333 | 31 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
mslade | 1:84581acd1333 | 32 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
mslade | 1:84581acd1333 | 33 | * Library General Public License for more details. |
mslade | 1:84581acd1333 | 34 | * |
mslade | 1:84581acd1333 | 35 | * You should have received a copy of the GNU Library General Public |
mslade | 1:84581acd1333 | 36 | * License along with the GNU C Library; see the file COPYING.LIB. If |
mslade | 1:84581acd1333 | 37 | * not, write to the Free Software Foundation, Inc., 675 Mass Ave, |
mslade | 1:84581acd1333 | 38 | * Cambridge, MA 02139, USA. |
mslade | 1:84581acd1333 | 39 | */ |
mslade | 1:84581acd1333 | 40 | |
mslade | 1:84581acd1333 | 41 | |
mslade | 1:84581acd1333 | 42 | /** @file main.cpp Basic SD Driver Test |
mslade | 1:84581acd1333 | 43 | */ |
mslade | 1:84581acd1333 | 44 | #include "mbed.h" |
mslade | 1:84581acd1333 | 45 | #include "greentea-client/test_env.h" |
mslade | 1:84581acd1333 | 46 | #include "unity.h" |
mslade | 1:84581acd1333 | 47 | #include "utest.h" |
mslade | 1:84581acd1333 | 48 | |
mslade | 1:84581acd1333 | 49 | #include "SDBlockDevice.h" |
mslade | 1:84581acd1333 | 50 | #include <stdlib.h> |
mslade | 1:84581acd1333 | 51 | |
mslade | 1:84581acd1333 | 52 | using namespace utest::v1; |
mslade | 1:84581acd1333 | 53 | |
mslade | 1:84581acd1333 | 54 | #define TEST_BLOCK_COUNT 10 |
mslade | 1:84581acd1333 | 55 | #define TEST_ERROR_MASK 16 |
mslade | 1:84581acd1333 | 56 | #define TEST_BLOCK_SIZE 2048 |
mslade | 1:84581acd1333 | 57 | |
mslade | 1:84581acd1333 | 58 | const struct { |
mslade | 1:84581acd1333 | 59 | const char *name; |
mslade | 1:84581acd1333 | 60 | bd_size_t (BlockDevice::*method)() const; |
mslade | 1:84581acd1333 | 61 | } ATTRS[] = { |
mslade | 1:84581acd1333 | 62 | {"read size", &BlockDevice::get_read_size}, |
mslade | 1:84581acd1333 | 63 | {"program size", &BlockDevice::get_program_size}, |
mslade | 1:84581acd1333 | 64 | {"erase size", &BlockDevice::get_erase_size}, |
mslade | 1:84581acd1333 | 65 | {"total size", &BlockDevice::size}, |
mslade | 1:84581acd1333 | 66 | }; |
mslade | 1:84581acd1333 | 67 | |
mslade | 1:84581acd1333 | 68 | void test_read_write() { |
mslade | 1:84581acd1333 | 69 | SDBlockDevice sd(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_SPI_CS); |
mslade | 1:84581acd1333 | 70 | |
mslade | 1:84581acd1333 | 71 | int err = sd.init(); |
mslade | 1:84581acd1333 | 72 | TEST_ASSERT_EQUAL(0, err); |
mslade | 1:84581acd1333 | 73 | |
mslade | 1:84581acd1333 | 74 | err = sd.frequency(25000000); |
mslade | 1:84581acd1333 | 75 | TEST_ASSERT_EQUAL(0, err); |
mslade | 1:84581acd1333 | 76 | |
mslade | 1:84581acd1333 | 77 | for (unsigned a = 0; a < sizeof(ATTRS)/sizeof(ATTRS[0]); a++) { |
mslade | 1:84581acd1333 | 78 | static const char *prefixes[] = {"", "k", "M", "G"}; |
mslade | 1:84581acd1333 | 79 | for (int i = 3; i >= 0; i--) { |
mslade | 1:84581acd1333 | 80 | bd_size_t size = (sd.*ATTRS[a].method)(); |
mslade | 1:84581acd1333 | 81 | if (size >= (1ULL << 10*i)) { |
mslade | 1:84581acd1333 | 82 | printf("%s: %llu%sbytes (%llubytes)\n", |
mslade | 1:84581acd1333 | 83 | ATTRS[a].name, size >> 10*i, prefixes[i], size); |
mslade | 1:84581acd1333 | 84 | break; |
mslade | 1:84581acd1333 | 85 | } |
mslade | 1:84581acd1333 | 86 | } |
mslade | 1:84581acd1333 | 87 | } |
mslade | 1:84581acd1333 | 88 | |
mslade | 1:84581acd1333 | 89 | bd_size_t erase_size = sd.get_erase_size(); |
mslade | 1:84581acd1333 | 90 | bd_size_t block_size = erase_size > TEST_BLOCK_SIZE ? erase_size : TEST_BLOCK_SIZE; |
mslade | 1:84581acd1333 | 91 | |
mslade | 1:84581acd1333 | 92 | uint8_t *write_block = new uint8_t[block_size]; |
mslade | 1:84581acd1333 | 93 | uint8_t *read_block = new uint8_t[block_size]; |
mslade | 1:84581acd1333 | 94 | uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; |
mslade | 1:84581acd1333 | 95 | unsigned addrwidth = ceil(log(float(sd.size()-1)) / log(float(16)))+1; |
mslade | 1:84581acd1333 | 96 | |
mslade | 1:84581acd1333 | 97 | for (int b = 0; b < TEST_BLOCK_COUNT; b++) { |
mslade | 1:84581acd1333 | 98 | // Find a random block |
mslade | 1:84581acd1333 | 99 | bd_addr_t block = (rand()*block_size) % sd.size(); |
mslade | 1:84581acd1333 | 100 | |
mslade | 1:84581acd1333 | 101 | // Use next random number as temporary seed to keep |
mslade | 1:84581acd1333 | 102 | // the address progressing in the pseudorandom sequence |
mslade | 1:84581acd1333 | 103 | unsigned seed = rand(); |
mslade | 1:84581acd1333 | 104 | |
mslade | 1:84581acd1333 | 105 | // Fill with random sequence |
mslade | 1:84581acd1333 | 106 | srand(seed); |
mslade | 1:84581acd1333 | 107 | for (bd_size_t i = 0; i < block_size; i++) { |
mslade | 1:84581acd1333 | 108 | write_block[i] = 0xff & rand(); |
mslade | 1:84581acd1333 | 109 | } |
mslade | 1:84581acd1333 | 110 | |
mslade | 1:84581acd1333 | 111 | // Write, sync, and read the block |
mslade | 1:84581acd1333 | 112 | printf("test %0*llx:%llu...\n", addrwidth, block, block_size); |
mslade | 1:84581acd1333 | 113 | |
mslade | 1:84581acd1333 | 114 | err = sd.erase(block, block_size); |
mslade | 1:84581acd1333 | 115 | TEST_ASSERT_EQUAL(0, err); |
mslade | 1:84581acd1333 | 116 | |
mslade | 1:84581acd1333 | 117 | err = sd.program(write_block, block, block_size); |
mslade | 1:84581acd1333 | 118 | TEST_ASSERT_EQUAL(0, err); |
mslade | 1:84581acd1333 | 119 | |
mslade | 1:84581acd1333 | 120 | printf("write %0*llx:%llu ", addrwidth, block, block_size); |
mslade | 1:84581acd1333 | 121 | for (int i = 0; i < 16; i++) { |
mslade | 1:84581acd1333 | 122 | printf("%02x", write_block[i]); |
mslade | 1:84581acd1333 | 123 | } |
mslade | 1:84581acd1333 | 124 | printf("...\n"); |
mslade | 1:84581acd1333 | 125 | |
mslade | 1:84581acd1333 | 126 | err = sd.read(read_block, block, block_size); |
mslade | 1:84581acd1333 | 127 | TEST_ASSERT_EQUAL(0, err); |
mslade | 1:84581acd1333 | 128 | |
mslade | 1:84581acd1333 | 129 | printf("read %0*llx:%llu ", addrwidth, block, block_size); |
mslade | 1:84581acd1333 | 130 | for (int i = 0; i < 16; i++) { |
mslade | 1:84581acd1333 | 131 | printf("%02x", read_block[i]); |
mslade | 1:84581acd1333 | 132 | } |
mslade | 1:84581acd1333 | 133 | printf("...\n"); |
mslade | 1:84581acd1333 | 134 | |
mslade | 1:84581acd1333 | 135 | // Find error mask for debugging |
mslade | 1:84581acd1333 | 136 | memset(error_mask, 0, TEST_ERROR_MASK); |
mslade | 1:84581acd1333 | 137 | bd_size_t error_scale = block_size / (TEST_ERROR_MASK*8); |
mslade | 1:84581acd1333 | 138 | |
mslade | 1:84581acd1333 | 139 | srand(seed); |
mslade | 1:84581acd1333 | 140 | for (bd_size_t i = 0; i < TEST_ERROR_MASK*8; i++) { |
mslade | 1:84581acd1333 | 141 | for (bd_size_t j = 0; j < error_scale; j++) { |
mslade | 1:84581acd1333 | 142 | if ((0xff & rand()) != read_block[i*error_scale + j]) { |
mslade | 1:84581acd1333 | 143 | error_mask[i/8] |= 1 << (i%8); |
mslade | 1:84581acd1333 | 144 | } |
mslade | 1:84581acd1333 | 145 | } |
mslade | 1:84581acd1333 | 146 | } |
mslade | 1:84581acd1333 | 147 | |
mslade | 1:84581acd1333 | 148 | printf("error %0*llx:%llu ", addrwidth, block, block_size); |
mslade | 1:84581acd1333 | 149 | for (int i = 0; i < 16; i++) { |
mslade | 1:84581acd1333 | 150 | printf("%02x", error_mask[i]); |
mslade | 1:84581acd1333 | 151 | } |
mslade | 1:84581acd1333 | 152 | printf("\n"); |
mslade | 1:84581acd1333 | 153 | |
mslade | 1:84581acd1333 | 154 | // Check that the data was unmodified |
mslade | 1:84581acd1333 | 155 | srand(seed); |
mslade | 1:84581acd1333 | 156 | for (bd_size_t i = 0; i < block_size; i++) { |
mslade | 1:84581acd1333 | 157 | TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); |
mslade | 1:84581acd1333 | 158 | } |
mslade | 1:84581acd1333 | 159 | } |
mslade | 1:84581acd1333 | 160 | |
mslade | 1:84581acd1333 | 161 | err = sd.deinit(); |
mslade | 1:84581acd1333 | 162 | TEST_ASSERT_EQUAL(0, err); |
mslade | 1:84581acd1333 | 163 | } |
mslade | 1:84581acd1333 | 164 | |
mslade | 1:84581acd1333 | 165 | // Test setup |
mslade | 1:84581acd1333 | 166 | utest::v1::status_t test_setup(const size_t number_of_cases) { |
mslade | 1:84581acd1333 | 167 | GREENTEA_SETUP(120, "default_auto"); |
mslade | 1:84581acd1333 | 168 | return verbose_test_setup_handler(number_of_cases); |
mslade | 1:84581acd1333 | 169 | } |
mslade | 1:84581acd1333 | 170 | |
mslade | 1:84581acd1333 | 171 | Case cases[] = { |
mslade | 1:84581acd1333 | 172 | Case("Testing read write random blocks", test_read_write), |
mslade | 1:84581acd1333 | 173 | }; |
mslade | 1:84581acd1333 | 174 | |
mslade | 1:84581acd1333 | 175 | Specification specification(test_setup, cases); |
mslade | 1:84581acd1333 | 176 | |
mslade | 1:84581acd1333 | 177 | int main() { |
mslade | 1:84581acd1333 | 178 | return !Harness::run(specification); |
mslade | 1:84581acd1333 | 179 | } |