From feb1023849dda695e2a9030a4bbaa1234b5e4bf2 Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Fri, 4 Sep 2020 15:08:12 +0100 Subject: [PATCH 1/2] test_program_read_small_data_sizes: get erase size specific to the sector we use The test case only uses one specific sector, but the erase size is obtained for the whole block device instead. This doesn't work if different regions of the flash don't have a common erase size. Fix the issue by getting the erase size at the address we use. --- .../tests/TESTS/blockdevice/general_block_device/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp index 6acd399f856..d464adbc85b 100644 --- a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp +++ b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp @@ -584,7 +584,6 @@ void test_program_read_small_data_sizes() TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found."); - bd_size_t erase_size = block_device->get_erase_size(); bd_size_t program_size = block_device->get_program_size(); bd_size_t read_size = block_device->get_read_size(); TEST_ASSERT(program_size > 0); @@ -606,6 +605,7 @@ void test_program_read_small_data_sizes() // Determine starting address bd_addr_t start_address = 0; + bd_size_t erase_size = block_device->get_erase_size(start_address); for (int i = 1; i <= 7; i++) { err = buff_block_device->erase(start_address, erase_size); From 3b9335055b9317820689e14fee89f5ff93239dce Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Fri, 4 Sep 2020 15:57:43 +0100 Subject: [PATCH 2/2] general_block_device test: allocate buffers enough for the largest sector Previously we get the common erase size of the whole flash, which may or may not exists if there are multiple regions. In this case the size returned is zero and the test fails. Fix this by allocating read and write buffers that are large enough for all sectors. The test itself already supports non-uniform erase sizes, and the erase size at any address can be smaller than our buffers. --- .../blockdevice/general_block_device/main.cpp | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp index d464adbc85b..236db4f5eef 100644 --- a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp +++ b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp @@ -68,6 +68,7 @@ using namespace utest::v1; uint8_t num_of_sectors = TEST_NUM_OF_THREADS * TEST_BLOCK_COUNT; uint32_t sectors_addr[TEST_NUM_OF_THREADS * TEST_BLOCK_COUNT] = {0}; +bd_size_t max_sector_size = 0; const struct { const char *name; @@ -261,11 +262,16 @@ void test_init_bd() TEST_ASSERT_EQUAL(0, err); bd_addr_t start_address = 0; + bd_size_t curr_sector_size = 0; uint8_t i = 0; for (; i < num_of_sectors && start_address < block_device->size(); i++) { sectors_addr[i] = start_address; - DEBUG_PRINTF("start_address = 0x%llx, sector_size = %d\n", start_address, block_device->get_erase_size(start_address)); - start_address += block_device->get_erase_size(start_address); + curr_sector_size = block_device->get_erase_size(start_address); + DEBUG_PRINTF("start_address = 0x%llx, sector_size = %d\n", start_address, curr_sector_size); + if (curr_sector_size > max_sector_size) { + max_sector_size = curr_sector_size; + } + start_address += curr_sector_size; } num_of_sectors = i; } @@ -288,24 +294,25 @@ void test_random_program_read_erase() } } - bd_size_t block_size = block_device->get_erase_size(); unsigned addrwidth = ceil(log(float(block_device->size() - 1)) / log(float(16))) + 1; - uint8_t *write_block = new (std::nothrow) uint8_t[block_size]; - uint8_t *read_block = new (std::nothrow) uint8_t[block_size]; + uint8_t *write_buffer = new (std::nothrow) uint8_t[max_sector_size]; + uint8_t *read_buffer = new (std::nothrow) uint8_t[max_sector_size]; - if (!write_block || !read_block) { + if (!write_buffer || !read_buffer) { utest_printf("Not enough memory for test\n"); goto end; } for (int b = 0; b < std::min((uint8_t)TEST_BLOCK_COUNT, num_of_sectors); b++) { - basic_erase_program_read_test(block_device, block_size, write_block, read_block, addrwidth, b); + // basic_erase_program_read_test() can handle non-uniform sector sizes + // and use only part of the buffers if the sector is smaller + basic_erase_program_read_test(block_device, max_sector_size, write_buffer, read_buffer, addrwidth, b); } end: - delete[] read_block; - delete[] write_block; + delete[] read_buffer; + delete[] write_buffer; } #if defined(MBED_CONF_RTOS_PRESENT) @@ -318,24 +325,27 @@ static void test_thread_job() uint8_t sector_per_thread = (num_of_sectors / TEST_NUM_OF_THREADS); - bd_size_t block_size = block_device->get_erase_size(); unsigned addrwidth = ceil(log(float(block_device->size() - 1)) / log(float(16))) + 1; - uint8_t *write_block = new (std::nothrow) uint8_t[block_size]; - uint8_t *read_block = new (std::nothrow) uint8_t[block_size]; + uint8_t *write_buffer = new (std::nothrow) uint8_t[max_sector_size]; + uint8_t *read_buffer = new (std::nothrow) uint8_t[max_sector_size]; - if (!write_block || !read_block) { - utest_printf("Not enough memory for test\n"); + if (!write_buffer || !read_buffer) { + // Some targets have sectors up to 256KB each and a relatively small RAM. + // This test may not be able to run in this case. + utest_printf("Not enough memory for test, is the sector size (%llu) too big?\n", max_sector_size); goto end; } for (int b = 0; b < sector_per_thread; b++) { - basic_erase_program_read_test(block_device, block_size, write_block, read_block, addrwidth, block_num * sector_per_thread + b); + // basic_erase_program_read_test() can handle non-uniform sector sizes + // and use only part of the buffers if the sector is smaller + basic_erase_program_read_test(block_device, max_sector_size, write_buffer, read_buffer, addrwidth, block_num * sector_per_thread + b); } end: - delete[] read_block; - delete[] write_block; + delete[] read_buffer; + delete[] write_buffer; } void test_multi_threads()