Skip to content

Commit f9550bc

Browse files
author
Deepika
authored
Merge pull request ARMmbed#37 from deepikabhavnani/test_block
Added block device test for SD driver
2 parents 2986196 + 566f455 commit f9550bc

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

TESTS/block_device/basic/basic.cpp

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

0 commit comments

Comments
 (0)