mirror of https://github.com/ARMmbed/mbed-os.git
Fix the general block device to support better low memory boards
In addition, fix prints and warnings.pull/9370/head
parent
05eb6c59bd
commit
e57c9f35a8
|
@ -65,7 +65,7 @@ void basic_erase_program_read_test(BlockDevice *block_device, bd_size_t block_si
|
|||
write_block[i_ind] = 0xff & rand();
|
||||
}
|
||||
// Write, sync, and read the block
|
||||
utest_printf("\ntest %0*llx:%llu...", addrwidth, block, block_size);
|
||||
utest_printf("test %0*llx:%llu...\n", addrwidth, block, block_size);
|
||||
_mutex->unlock();
|
||||
|
||||
err = block_device->erase(block, block_size);
|
||||
|
@ -100,7 +100,7 @@ void test_random_program_read_erase()
|
|||
|
||||
BlockDevice *block_device = BlockDevice::get_default_instance();
|
||||
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
|
||||
|
||||
int err = block_device->init();
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
@ -123,7 +123,7 @@ void test_random_program_read_erase()
|
|||
uint8_t *write_block = new (std::nothrow) uint8_t[block_size];
|
||||
uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
|
||||
if (!write_block || !read_block) {
|
||||
utest_printf("\n Not enough memory for test");
|
||||
utest_printf("Not enough memory for test\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ static void test_thread_job(void *block_device_ptr)
|
|||
uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
|
||||
|
||||
if (!write_block || !read_block) {
|
||||
utest_printf("\n Not enough memory for test");
|
||||
utest_printf("Not enough memory for test\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -173,6 +173,10 @@ void test_multi_threads()
|
|||
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
|
||||
|
||||
char *dummy = new (std::nothrow) char[TEST_NUM_OF_THREADS * OS_STACK_SIZE];
|
||||
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test.\n");
|
||||
delete[] dummy;
|
||||
|
||||
int err = block_device->init();
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
|
@ -196,7 +200,7 @@ void test_multi_threads()
|
|||
for (i_ind = 0; i_ind < TEST_NUM_OF_THREADS; i_ind++) {
|
||||
threadStatus = bd_thread[i_ind].start(callback(test_thread_job, (void *)block_device));
|
||||
if (threadStatus != 0) {
|
||||
utest_printf("\n Thread %d Start Failed!", i_ind + 1);
|
||||
utest_printf("Thread %d Start Failed!\n", i_ind + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,15 +223,15 @@ void test_get_erase_value()
|
|||
// 3. Read erased region and compare with get_erase_value()
|
||||
|
||||
BlockDevice *block_device = BlockDevice::get_default_instance();
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
|
||||
|
||||
int err = block_device->init();
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Check erase value
|
||||
int erase_value_int = block_device->get_erase_value();
|
||||
utest_printf("\nblock_device->get_erase_value()=%d", erase_value_int);
|
||||
TEST_SKIP_UNLESS_MESSAGE(erase_value_int >= 0, "\nerase value is negative which means the erase value is unknown\n");
|
||||
utest_printf("block_device->get_erase_value()=%d\n", erase_value_int);
|
||||
TEST_SKIP_UNLESS_MESSAGE(erase_value_int >= 0, "Erase not supported in this block device. Test skipped.");
|
||||
|
||||
// Assuming that get_erase_value() returns byte value as documentation mentions
|
||||
// "If get_erase_value() returns a non-negative byte value" for unknown case.
|
||||
|
@ -245,33 +249,33 @@ void test_get_erase_value()
|
|||
start_address %= block_device->size() - data_buf_size - erase_size; // fit all data + alignment reserve
|
||||
start_address += erase_size; // add alignment reserve
|
||||
start_address -= start_address % erase_size; // align with erase_block
|
||||
utest_printf("\nstart_address=0x%016" PRIx64, start_address);
|
||||
utest_printf("start_address=0x%016" PRIx64 "\n", start_address);
|
||||
|
||||
// Allocate buffer for read test data
|
||||
uint8_t *data_buf = (uint8_t *)malloc(data_buf_size);
|
||||
TEST_ASSERT_NOT_NULL(data_buf);
|
||||
TEST_SKIP_UNLESS_MESSAGE(data_buf, "Not enough memory for test.\n");
|
||||
|
||||
// Write random data to selected region to make sure data is not accidentally set to "erased" value.
|
||||
// With this pre-write, the test case will fail even if block_device->erase() is broken.
|
||||
for (bd_size_t i = 0; i < data_buf_size; i++) {
|
||||
data_buf[i] = (uint8_t) rand();
|
||||
}
|
||||
utest_printf("\nwriting given memory region");
|
||||
utest_printf("writing given memory region\n");
|
||||
err = block_device->program((const void *)data_buf, start_address, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Erase given memory region
|
||||
utest_printf("\nerasing given memory region");
|
||||
utest_printf("erasing given memory region\n");
|
||||
err = block_device->erase(start_address, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Read erased memory region
|
||||
utest_printf("\nreading erased memory region");
|
||||
utest_printf("reading erased memory region\n");
|
||||
err = block_device->read((void *)data_buf, start_address, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Verify erased memory region
|
||||
utest_printf("\nverifying erased memory region");
|
||||
utest_printf("verifying erased memory region\n");
|
||||
for (bd_size_t i = 0; i < data_buf_size; i++) {
|
||||
TEST_ASSERT_EQUAL(erase_value, data_buf[i]);
|
||||
}
|
||||
|
@ -295,7 +299,7 @@ void test_contiguous_erase_write_read()
|
|||
// 3. Return step 2 for whole erase region
|
||||
|
||||
BlockDevice *block_device = BlockDevice::get_default_instance();
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
|
||||
|
||||
// Initialize BlockDevice
|
||||
int err = block_device->init();
|
||||
|
@ -306,9 +310,9 @@ void test_contiguous_erase_write_read()
|
|||
TEST_ASSERT(erase_size > 0);
|
||||
bd_size_t program_size = block_device->get_program_size();
|
||||
TEST_ASSERT(program_size > 0);
|
||||
utest_printf("\nerase_size=%d", erase_size);
|
||||
utest_printf("\nprogram_size=%d", program_size);
|
||||
utest_printf("\nblock_device->size()=%" PRId64, block_device->size());
|
||||
utest_printf("erase_size=%" PRId64 "\n", erase_size);
|
||||
utest_printf("program_size=%" PRId64 "\n", program_size);
|
||||
utest_printf("block_device->size()=%" PRId64 "\n", block_device->size());
|
||||
|
||||
// Determine write/read buffer size
|
||||
// start write_read_buf_size from 1% block_device->size()
|
||||
|
@ -324,18 +328,18 @@ void test_contiguous_erase_write_read()
|
|||
bd_size_t contiguous_write_read_blocks_per_region = write_read_buf_size /
|
||||
program_size; // 2 is minimum to test contiguous write
|
||||
write_read_buf_size = contiguous_write_read_blocks_per_region * program_size;
|
||||
utest_printf("\ncontiguous_write_read_blocks_per_region=%" PRIu64, contiguous_write_read_blocks_per_region);
|
||||
utest_printf("\nwrite_read_buf_size=%" PRIu64, write_read_buf_size);
|
||||
utest_printf("contiguous_write_read_blocks_per_region=%" PRIu64 "\n", contiguous_write_read_blocks_per_region);
|
||||
utest_printf("write_read_buf_size=%" PRIu64 "\n", write_read_buf_size);
|
||||
|
||||
// Determine test region count
|
||||
int contiguous_write_read_regions = TEST_BLOCK_COUNT;
|
||||
utest_printf("\ncontiguous_write_read_regions=%d", contiguous_write_read_regions);
|
||||
utest_printf("contiguous_write_read_regions=%d\n", contiguous_write_read_regions);
|
||||
|
||||
// Determine whole erase size
|
||||
bd_size_t contiguous_erase_size = write_read_buf_size * contiguous_write_read_regions;
|
||||
contiguous_erase_size -= contiguous_erase_size % erase_size; // aligned to erase_size
|
||||
contiguous_erase_size += erase_size; // but larger than write/read size * regions
|
||||
utest_printf("\ncontiguous_erase_size=%" PRIu64, contiguous_erase_size);
|
||||
utest_printf("contiguous_erase_size=%" PRIu64 "\n", contiguous_erase_size);
|
||||
|
||||
// Determine starting address
|
||||
bd_addr_t start_address = rand(); // low 32 bytes
|
||||
|
@ -344,16 +348,16 @@ void test_contiguous_erase_write_read()
|
|||
start_address += erase_size; // add alignment reserve
|
||||
start_address -= start_address % erase_size; // align with erase_block
|
||||
bd_addr_t stop_address = start_address + write_read_buf_size * contiguous_write_read_regions;
|
||||
utest_printf("\nstart_address=0x%016" PRIx64, start_address);
|
||||
utest_printf("\nstop_address=0x%016" PRIx64, stop_address);
|
||||
utest_printf("start_address=0x%016" PRIx64 "\n", start_address);
|
||||
utest_printf("stop_address=0x%016" PRIx64 "\n", stop_address);
|
||||
|
||||
// Allocate write/read buffer
|
||||
uint8_t *write_read_buf = (uint8_t *)malloc(write_read_buf_size);
|
||||
if (write_read_buf == NULL) {
|
||||
block_device->deinit();
|
||||
TEST_SKIP_MESSAGE("\nnot enough memory for test");
|
||||
TEST_SKIP_MESSAGE("not enough memory for test");
|
||||
}
|
||||
utest_printf("\nwrite_read_buf_size=%" PRIu64 "", (uint64_t)write_read_buf_size);
|
||||
utest_printf("write_read_buf_size=%" PRIu64 "\n", (uint64_t)write_read_buf_size);
|
||||
|
||||
// Pre-fill the to-be-erased region. By pre-filling the region,
|
||||
// we can be sure the test will not pass if the erase doesn't work.
|
||||
|
@ -361,53 +365,53 @@ void test_contiguous_erase_write_read()
|
|||
for (size_t i = 0; i < write_read_buf_size; i++) {
|
||||
write_read_buf[i] = (uint8_t)rand();
|
||||
}
|
||||
utest_printf("\npre-filling memory, from 0x%" PRIx64 " of size 0x%" PRIx64, start_address + offset,
|
||||
utest_printf("pre-filling memory, from 0x%" PRIx64 " of size 0x%" PRIx64 "\n", start_address + offset,
|
||||
write_read_buf_size);
|
||||
err = block_device->program((const void *)write_read_buf, start_address + offset, write_read_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
}
|
||||
|
||||
// Erase the whole region first
|
||||
utest_printf("\nerasing memory, from 0x%" PRIx64 " of size 0x%" PRIx64, start_address, contiguous_erase_size);
|
||||
utest_printf("erasing memory, from 0x%" PRIx64 " of size 0x%" PRIx64 "\n", start_address, contiguous_erase_size);
|
||||
err = block_device->erase(start_address, contiguous_erase_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Loop through all write/read regions
|
||||
int region = 0;
|
||||
for (; start_address < stop_address; start_address += write_read_buf_size) {
|
||||
utest_printf("\n\nregion #%d start_address=0x%016" PRIx64, region++, start_address);
|
||||
utest_printf("\nregion #%d start_address=0x%016" PRIx64 "\n", region++, start_address);
|
||||
|
||||
// Generate test data
|
||||
unsigned int seed = rand();
|
||||
utest_printf("\ngenerating test data, seed=%u", seed);
|
||||
utest_printf("generating test data, seed=%u\n", seed);
|
||||
srand(seed);
|
||||
for (size_t i = 0; i < write_read_buf_size; i++) {
|
||||
write_read_buf[i] = (uint8_t)rand();
|
||||
}
|
||||
|
||||
// Write test data
|
||||
utest_printf("\nwriting test data");
|
||||
utest_printf("writing test data\n");
|
||||
err = block_device->program((const void *)write_read_buf, start_address, write_read_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Read test data
|
||||
memset(write_read_buf, 0, (size_t)write_read_buf_size);
|
||||
utest_printf("\nreading test data");
|
||||
utest_printf("reading test data\n");
|
||||
err = block_device->read(write_read_buf, start_address, write_read_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Verify read data
|
||||
utest_printf("\nverifying test data");
|
||||
utest_printf("verifying test data\n");
|
||||
srand(seed);
|
||||
for (size_t i = 0; i < write_read_buf_size; i++) {
|
||||
uint8_t expected_value = (uint8_t)rand();
|
||||
if (write_read_buf[i] != expected_value) {
|
||||
utest_printf("\ndata verify failed, write_read_buf[%d]=%" PRIu8 " and not %" PRIu8 "\n",
|
||||
utest_printf("data verify failed, write_read_buf[%d]=%" PRIu8 " and not %" PRIu8 "\n",
|
||||
i, write_read_buf[i], expected_value);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(write_read_buf[i], expected_value);
|
||||
}
|
||||
utest_printf("\nverify OK");
|
||||
utest_printf("verify OK\n");
|
||||
}
|
||||
|
||||
free(write_read_buf);
|
||||
|
@ -423,22 +427,34 @@ void test_program_read_small_data_sizes()
|
|||
|
||||
BlockDevice *bd = BlockDevice::get_default_instance();
|
||||
|
||||
TEST_SKIP_UNLESS_MESSAGE(bd != NULL, "\nno block device found.\n");
|
||||
TEST_SKIP_UNLESS_MESSAGE(bd != NULL, "no block device found.");
|
||||
|
||||
int err = bd->init();
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
bd_size_t erase_size = bd->get_erase_size();
|
||||
bd_size_t program_size = bd->get_program_size();
|
||||
bd_size_t read_size = bd->get_read_size();
|
||||
TEST_ASSERT(program_size > 0);
|
||||
|
||||
err = bd->deinit();
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// See that we have enough memory for buffered block device
|
||||
char *dummy = new (std::nothrow) char[program_size + read_size];
|
||||
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test.\n");
|
||||
delete[] dummy;
|
||||
|
||||
// use BufferedBlockDevice for better handling of block devices program and read
|
||||
BufferedBlockDevice *block_device = new BufferedBlockDevice(bd);
|
||||
|
||||
// BlockDevice initialization
|
||||
int err = block_device->init();
|
||||
err = block_device->init();
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
const char write_buffer[] = "1234567";
|
||||
char read_buffer[7] = {};
|
||||
|
||||
bd_size_t erase_size = block_device->get_erase_size();
|
||||
bd_size_t program_size = block_device->get_program_size();
|
||||
TEST_ASSERT(program_size > 0);
|
||||
|
||||
// Determine starting address
|
||||
bd_addr_t start_address = 0;
|
||||
|
||||
|
@ -469,10 +485,7 @@ void test_program_read_small_data_sizes()
|
|||
void test_get_type_functionality()
|
||||
{
|
||||
BlockDevice *block_device = BlockDevice::get_default_instance();
|
||||
if (block_device == NULL) {
|
||||
TEST_SKIP_MESSAGE("No block device component is defined for this target");
|
||||
return;
|
||||
}
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device, "No block device component is defined for this target");
|
||||
const char *bd_type = block_device->get_type();
|
||||
TEST_ASSERT_NOT_EQUAL(0, bd_type);
|
||||
|
||||
|
|
Loading…
Reference in New Issue