Skip to content

Commit 9e94070

Browse files
authored
Merge pull request #9362 from davidsaada/david_bd_test_low_mem
Fix the general block device for better support of low memory boards
2 parents f4aaebd + d6382bb commit 9e94070

File tree

1 file changed

+58
-45
lines changed
  • features/storage/TESTS/blockdevice/general_block_device

1 file changed

+58
-45
lines changed

features/storage/TESTS/blockdevice/general_block_device/main.cpp

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void basic_erase_program_read_test(BlockDevice *block_device, bd_size_t block_si
6565
write_block[i_ind] = 0xff & rand();
6666
}
6767
// Write, sync, and read the block
68-
utest_printf("\ntest %0*llx:%llu...", addrwidth, block, block_size);
68+
utest_printf("test %0*llx:%llu...\n", addrwidth, block, block_size);
6969
_mutex->unlock();
7070

7171
err = block_device->erase(block, block_size);
@@ -100,7 +100,7 @@ void test_random_program_read_erase()
100100

101101
BlockDevice *block_device = BlockDevice::get_default_instance();
102102

103-
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
103+
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
104104

105105
int err = block_device->init();
106106
TEST_ASSERT_EQUAL(0, err);
@@ -123,7 +123,7 @@ void test_random_program_read_erase()
123123
uint8_t *write_block = new (std::nothrow) uint8_t[block_size];
124124
uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
125125
if (!write_block || !read_block) {
126-
utest_printf("\n Not enough memory for test");
126+
utest_printf("Not enough memory for test\n");
127127
goto end;
128128
}
129129

@@ -152,7 +152,7 @@ static void test_thread_job(void *block_device_ptr)
152152
uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
153153

154154
if (!write_block || !read_block) {
155-
utest_printf("\n Not enough memory for test");
155+
utest_printf("Not enough memory for test\n");
156156
goto end;
157157
}
158158

@@ -173,6 +173,10 @@ void test_multi_threads()
173173

174174
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
175175

176+
char *dummy = new (std::nothrow) char[TEST_NUM_OF_THREADS * OS_STACK_SIZE];
177+
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test.\n");
178+
delete[] dummy;
179+
176180
int err = block_device->init();
177181
TEST_ASSERT_EQUAL(0, err);
178182

@@ -196,7 +200,7 @@ void test_multi_threads()
196200
for (i_ind = 0; i_ind < TEST_NUM_OF_THREADS; i_ind++) {
197201
threadStatus = bd_thread[i_ind].start(callback(test_thread_job, (void *)block_device));
198202
if (threadStatus != 0) {
199-
utest_printf("\n Thread %d Start Failed!", i_ind + 1);
203+
utest_printf("Thread %d Start Failed!\n", i_ind + 1);
200204
}
201205
}
202206

@@ -219,15 +223,15 @@ void test_get_erase_value()
219223
// 3. Read erased region and compare with get_erase_value()
220224

221225
BlockDevice *block_device = BlockDevice::get_default_instance();
222-
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
226+
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
223227

224228
int err = block_device->init();
225229
TEST_ASSERT_EQUAL(0, err);
226230

227231
// Check erase value
228232
int erase_value_int = block_device->get_erase_value();
229-
utest_printf("\nblock_device->get_erase_value()=%d", erase_value_int);
230-
TEST_SKIP_UNLESS_MESSAGE(erase_value_int >= 0, "\nerase value is negative which means the erase value is unknown\n");
233+
utest_printf("block_device->get_erase_value()=%d\n", erase_value_int);
234+
TEST_SKIP_UNLESS_MESSAGE(erase_value_int >= 0, "Erase not supported in this block device. Test skipped.");
231235

232236
// Assuming that get_erase_value() returns byte value as documentation mentions
233237
// "If get_erase_value() returns a non-negative byte value" for unknown case.
@@ -245,33 +249,33 @@ void test_get_erase_value()
245249
start_address %= block_device->size() - data_buf_size - erase_size; // fit all data + alignment reserve
246250
start_address += erase_size; // add alignment reserve
247251
start_address -= start_address % erase_size; // align with erase_block
248-
utest_printf("\nstart_address=0x%016" PRIx64, start_address);
252+
utest_printf("start_address=0x%016" PRIx64 "\n", start_address);
249253

250254
// Allocate buffer for read test data
251255
uint8_t *data_buf = (uint8_t *)malloc(data_buf_size);
252-
TEST_ASSERT_NOT_NULL(data_buf);
256+
TEST_SKIP_UNLESS_MESSAGE(data_buf, "Not enough memory for test.\n");
253257

254258
// Write random data to selected region to make sure data is not accidentally set to "erased" value.
255259
// With this pre-write, the test case will fail even if block_device->erase() is broken.
256260
for (bd_size_t i = 0; i < data_buf_size; i++) {
257261
data_buf[i] = (uint8_t) rand();
258262
}
259-
utest_printf("\nwriting given memory region");
263+
utest_printf("writing given memory region\n");
260264
err = block_device->program((const void *)data_buf, start_address, data_buf_size);
261265
TEST_ASSERT_EQUAL(0, err);
262266

263267
// Erase given memory region
264-
utest_printf("\nerasing given memory region");
268+
utest_printf("erasing given memory region\n");
265269
err = block_device->erase(start_address, data_buf_size);
266270
TEST_ASSERT_EQUAL(0, err);
267271

268272
// Read erased memory region
269-
utest_printf("\nreading erased memory region");
273+
utest_printf("reading erased memory region\n");
270274
err = block_device->read((void *)data_buf, start_address, data_buf_size);
271275
TEST_ASSERT_EQUAL(0, err);
272276

273277
// Verify erased memory region
274-
utest_printf("\nverifying erased memory region");
278+
utest_printf("verifying erased memory region\n");
275279
for (bd_size_t i = 0; i < data_buf_size; i++) {
276280
TEST_ASSERT_EQUAL(erase_value, data_buf[i]);
277281
}
@@ -295,7 +299,7 @@ void test_contiguous_erase_write_read()
295299
// 3. Return step 2 for whole erase region
296300

297301
BlockDevice *block_device = BlockDevice::get_default_instance();
298-
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
302+
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
299303

300304
// Initialize BlockDevice
301305
int err = block_device->init();
@@ -306,9 +310,9 @@ void test_contiguous_erase_write_read()
306310
TEST_ASSERT(erase_size > 0);
307311
bd_size_t program_size = block_device->get_program_size();
308312
TEST_ASSERT(program_size > 0);
309-
utest_printf("\nerase_size=%d", erase_size);
310-
utest_printf("\nprogram_size=%d", program_size);
311-
utest_printf("\nblock_device->size()=%" PRId64, block_device->size());
313+
utest_printf("erase_size=%" PRId64 "\n", erase_size);
314+
utest_printf("program_size=%" PRId64 "\n", program_size);
315+
utest_printf("block_device->size()=%" PRId64 "\n", block_device->size());
312316

313317
// Determine write/read buffer size
314318
// start write_read_buf_size from 1% block_device->size()
@@ -324,18 +328,18 @@ void test_contiguous_erase_write_read()
324328
bd_size_t contiguous_write_read_blocks_per_region = write_read_buf_size /
325329
program_size; // 2 is minimum to test contiguous write
326330
write_read_buf_size = contiguous_write_read_blocks_per_region * program_size;
327-
utest_printf("\ncontiguous_write_read_blocks_per_region=%" PRIu64, contiguous_write_read_blocks_per_region);
328-
utest_printf("\nwrite_read_buf_size=%" PRIu64, write_read_buf_size);
331+
utest_printf("contiguous_write_read_blocks_per_region=%" PRIu64 "\n", contiguous_write_read_blocks_per_region);
332+
utest_printf("write_read_buf_size=%" PRIu64 "\n", write_read_buf_size);
329333

330334
// Determine test region count
331335
int contiguous_write_read_regions = TEST_BLOCK_COUNT;
332-
utest_printf("\ncontiguous_write_read_regions=%d", contiguous_write_read_regions);
336+
utest_printf("contiguous_write_read_regions=%d\n", contiguous_write_read_regions);
333337

334338
// Determine whole erase size
335339
bd_size_t contiguous_erase_size = write_read_buf_size * contiguous_write_read_regions;
336340
contiguous_erase_size -= contiguous_erase_size % erase_size; // aligned to erase_size
337341
contiguous_erase_size += erase_size; // but larger than write/read size * regions
338-
utest_printf("\ncontiguous_erase_size=%" PRIu64, contiguous_erase_size);
342+
utest_printf("contiguous_erase_size=%" PRIu64 "\n", contiguous_erase_size);
339343

340344
// Determine starting address
341345
bd_addr_t start_address = rand(); // low 32 bytes
@@ -344,70 +348,70 @@ void test_contiguous_erase_write_read()
344348
start_address += erase_size; // add alignment reserve
345349
start_address -= start_address % erase_size; // align with erase_block
346350
bd_addr_t stop_address = start_address + write_read_buf_size * contiguous_write_read_regions;
347-
utest_printf("\nstart_address=0x%016" PRIx64, start_address);
348-
utest_printf("\nstop_address=0x%016" PRIx64, stop_address);
351+
utest_printf("start_address=0x%016" PRIx64 "\n", start_address);
352+
utest_printf("stop_address=0x%016" PRIx64 "\n", stop_address);
349353

350354
// Allocate write/read buffer
351355
uint8_t *write_read_buf = (uint8_t *)malloc(write_read_buf_size);
352356
if (write_read_buf == NULL) {
353357
block_device->deinit();
354-
TEST_SKIP_MESSAGE("\nnot enough memory for test");
358+
TEST_SKIP_MESSAGE("not enough memory for test");
355359
}
356-
utest_printf("\nwrite_read_buf_size=%" PRIu64 "", (uint64_t)write_read_buf_size);
360+
utest_printf("write_read_buf_size=%" PRIu64 "\n", (uint64_t)write_read_buf_size);
357361

358362
// Pre-fill the to-be-erased region. By pre-filling the region,
359363
// we can be sure the test will not pass if the erase doesn't work.
360364
for (bd_size_t offset = 0; start_address + offset < stop_address; offset += write_read_buf_size) {
361365
for (size_t i = 0; i < write_read_buf_size; i++) {
362366
write_read_buf[i] = (uint8_t)rand();
363367
}
364-
utest_printf("\npre-filling memory, from 0x%" PRIx64 " of size 0x%" PRIx64, start_address + offset,
368+
utest_printf("pre-filling memory, from 0x%" PRIx64 " of size 0x%" PRIx64 "\n", start_address + offset,
365369
write_read_buf_size);
366370
err = block_device->program((const void *)write_read_buf, start_address + offset, write_read_buf_size);
367371
TEST_ASSERT_EQUAL(0, err);
368372
}
369373

370374
// Erase the whole region first
371-
utest_printf("\nerasing memory, from 0x%" PRIx64 " of size 0x%" PRIx64, start_address, contiguous_erase_size);
375+
utest_printf("erasing memory, from 0x%" PRIx64 " of size 0x%" PRIx64 "\n", start_address, contiguous_erase_size);
372376
err = block_device->erase(start_address, contiguous_erase_size);
373377
TEST_ASSERT_EQUAL(0, err);
374378

375379
// Loop through all write/read regions
376380
int region = 0;
377381
for (; start_address < stop_address; start_address += write_read_buf_size) {
378-
utest_printf("\n\nregion #%d start_address=0x%016" PRIx64, region++, start_address);
382+
utest_printf("\nregion #%d start_address=0x%016" PRIx64 "\n", region++, start_address);
379383

380384
// Generate test data
381385
unsigned int seed = rand();
382-
utest_printf("\ngenerating test data, seed=%u", seed);
386+
utest_printf("generating test data, seed=%u\n", seed);
383387
srand(seed);
384388
for (size_t i = 0; i < write_read_buf_size; i++) {
385389
write_read_buf[i] = (uint8_t)rand();
386390
}
387391

388392
// Write test data
389-
utest_printf("\nwriting test data");
393+
utest_printf("writing test data\n");
390394
err = block_device->program((const void *)write_read_buf, start_address, write_read_buf_size);
391395
TEST_ASSERT_EQUAL(0, err);
392396

393397
// Read test data
394398
memset(write_read_buf, 0, (size_t)write_read_buf_size);
395-
utest_printf("\nreading test data");
399+
utest_printf("reading test data\n");
396400
err = block_device->read(write_read_buf, start_address, write_read_buf_size);
397401
TEST_ASSERT_EQUAL(0, err);
398402

399403
// Verify read data
400-
utest_printf("\nverifying test data");
404+
utest_printf("verifying test data\n");
401405
srand(seed);
402406
for (size_t i = 0; i < write_read_buf_size; i++) {
403407
uint8_t expected_value = (uint8_t)rand();
404408
if (write_read_buf[i] != expected_value) {
405-
utest_printf("\ndata verify failed, write_read_buf[%d]=%" PRIu8 " and not %" PRIu8 "\n",
409+
utest_printf("data verify failed, write_read_buf[%d]=%" PRIu8 " and not %" PRIu8 "\n",
406410
i, write_read_buf[i], expected_value);
407411
}
408412
TEST_ASSERT_EQUAL(write_read_buf[i], expected_value);
409413
}
410-
utest_printf("\nverify OK");
414+
utest_printf("verify OK\n");
411415
}
412416

413417
free(write_read_buf);
@@ -423,22 +427,34 @@ void test_program_read_small_data_sizes()
423427

424428
BlockDevice *bd = BlockDevice::get_default_instance();
425429

426-
TEST_SKIP_UNLESS_MESSAGE(bd != NULL, "\nno block device found.\n");
430+
TEST_SKIP_UNLESS_MESSAGE(bd != NULL, "no block device found.");
431+
432+
int err = bd->init();
433+
TEST_ASSERT_EQUAL(0, err);
434+
435+
bd_size_t erase_size = bd->get_erase_size();
436+
bd_size_t program_size = bd->get_program_size();
437+
bd_size_t read_size = bd->get_read_size();
438+
TEST_ASSERT(program_size > 0);
439+
440+
err = bd->deinit();
441+
TEST_ASSERT_EQUAL(0, err);
442+
443+
// See that we have enough memory for buffered block device
444+
char *dummy = new (std::nothrow) char[program_size + read_size];
445+
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test.\n");
446+
delete[] dummy;
427447

428448
// use BufferedBlockDevice for better handling of block devices program and read
429449
BufferedBlockDevice *block_device = new BufferedBlockDevice(bd);
430450

431451
// BlockDevice initialization
432-
int err = block_device->init();
452+
err = block_device->init();
433453
TEST_ASSERT_EQUAL(0, err);
434454

435455
const char write_buffer[] = "1234567";
436456
char read_buffer[7] = {};
437457

438-
bd_size_t erase_size = block_device->get_erase_size();
439-
bd_size_t program_size = block_device->get_program_size();
440-
TEST_ASSERT(program_size > 0);
441-
442458
// Determine starting address
443459
bd_addr_t start_address = 0;
444460

@@ -469,10 +485,7 @@ void test_program_read_small_data_sizes()
469485
void test_get_type_functionality()
470486
{
471487
BlockDevice *block_device = BlockDevice::get_default_instance();
472-
if (block_device == NULL) {
473-
TEST_SKIP_MESSAGE("No block device component is defined for this target");
474-
return;
475-
}
488+
TEST_SKIP_UNLESS_MESSAGE(block_device, "No block device component is defined for this target");
476489
const char *bd_type = block_device->get_type();
477490
TEST_ASSERT_NOT_EQUAL(0, bd_type);
478491

0 commit comments

Comments
 (0)