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