|
20 | 20 | #endif
|
21 | 21 |
|
22 | 22 | #include "utest/utest.h"
|
| 23 | +#include "utest/utest_serial.h" |
23 | 24 | #include "unity/unity.h"
|
24 | 25 | #include "greentea-client/test_env.h"
|
25 | 26 | #include <algorithm>
|
@@ -178,15 +179,95 @@ void flashiap_program_error_test()
|
178 | 179 | TEST_ASSERT_EQUAL_INT32(0, ret);
|
179 | 180 | }
|
180 | 181 |
|
| 182 | +void flashiap_timing_test() |
| 183 | +{ |
| 184 | + FlashIAP flash_device; |
| 185 | + uint32_t ret = flash_device.init(); |
| 186 | + TEST_ASSERT_EQUAL_INT32(0, ret); |
| 187 | + mbed::Timer timer; |
| 188 | + int num_write_sizes; |
| 189 | + unsigned int curr_time, byte_usec_ratio; |
| 190 | + unsigned int avg_erase_time = 0; |
| 191 | + unsigned int max_erase_time = 0, min_erase_time = (unsigned int) -1; |
| 192 | + const unsigned int max_writes = 128; |
| 193 | + const unsigned int max_write_sizes = 6; |
| 194 | + const unsigned int max_byte_usec_ratio = 200; |
| 195 | + |
| 196 | + uint32_t page_size = flash_device.get_page_size(); |
| 197 | + uint32_t write_size = page_size; |
| 198 | + |
| 199 | + uint32_t end_address = flash_device.get_flash_start() + flash_device.get_flash_size(); |
| 200 | + |
| 201 | + utest_printf("\nFlash timing:\n"); |
| 202 | + uint32_t sector_size = flash_device.get_sector_size(end_address - 1UL); |
| 203 | + uint32_t base_address = end_address - sector_size; |
| 204 | + timer.start(); |
| 205 | + for (num_write_sizes = 0; num_write_sizes < max_write_sizes; num_write_sizes++) { |
| 206 | + if (write_size > sector_size) { |
| 207 | + break; |
| 208 | + } |
| 209 | + uint8_t *buf = new (std::nothrow) uint8_t[write_size]; |
| 210 | + if (!buf) { |
| 211 | + // Don't fail the test on lack of heap memory for the buffer |
| 212 | + break; |
| 213 | + } |
| 214 | + memset(buf, 0x5A, write_size); |
| 215 | + timer.reset(); |
| 216 | + ret = flash_device.erase(base_address, sector_size); |
| 217 | + curr_time = timer.read_us(); |
| 218 | + avg_erase_time += curr_time; |
| 219 | + TEST_ASSERT_EQUAL_INT32(0, ret); |
| 220 | + max_erase_time = std::max(max_erase_time, curr_time); |
| 221 | + min_erase_time = std::min(min_erase_time, curr_time); |
| 222 | + uint32_t address = base_address; |
| 223 | + unsigned int avg_write_time = 0; |
| 224 | + unsigned int max_write_time = 0, min_write_time = (unsigned int) -1; |
| 225 | + int num_writes; |
| 226 | + for (num_writes = 0; num_writes < max_writes; num_writes++) { |
| 227 | + if ((address + write_size) > end_address) { |
| 228 | + break; |
| 229 | + } |
| 230 | + timer.reset(); |
| 231 | + ret = flash_device.program(buf, address, write_size); |
| 232 | + curr_time = timer.read_us(); |
| 233 | + avg_write_time += curr_time; |
| 234 | + TEST_ASSERT_EQUAL_INT32(0, ret); |
| 235 | + max_write_time = std::max(max_write_time, curr_time); |
| 236 | + min_write_time = std::min(min_write_time, curr_time); |
| 237 | + address += write_size; |
| 238 | + } |
| 239 | + delete[] buf; |
| 240 | + avg_write_time /= num_writes; |
| 241 | + utest_printf("Write size %6u bytes: avg %10u, min %10u, max %10u (usec)\n", |
| 242 | + write_size, avg_write_time, min_write_time, max_write_time); |
| 243 | + byte_usec_ratio = write_size / avg_write_time; |
| 244 | + TEST_ASSERT(byte_usec_ratio < max_byte_usec_ratio); |
| 245 | + write_size *= 4; |
| 246 | + } |
| 247 | + |
| 248 | + if (num_write_sizes) { |
| 249 | + avg_erase_time /= num_write_sizes; |
| 250 | + utest_printf("\nErase size %6u bytes: avg %10u, min %10u, max %10u (usec)\n\n", |
| 251 | + sector_size, avg_erase_time, min_erase_time, max_erase_time); |
| 252 | + byte_usec_ratio = sector_size / avg_erase_time; |
| 253 | + TEST_ASSERT(byte_usec_ratio < max_byte_usec_ratio); |
| 254 | + } |
| 255 | + |
| 256 | + ret = flash_device.deinit(); |
| 257 | + TEST_ASSERT_EQUAL_INT32(0, ret); |
| 258 | +} |
| 259 | + |
| 260 | + |
181 | 261 | Case cases[] = {
|
182 | 262 | Case("FlashIAP - init", flashiap_init_test),
|
183 | 263 | Case("FlashIAP - program", flashiap_program_test),
|
184 | 264 | Case("FlashIAP - program across sectors", flashiap_cross_sector_program_test),
|
185 | 265 | Case("FlashIAP - program errors", flashiap_program_error_test),
|
| 266 | + Case("FlashIAP - timing", flashiap_timing_test), |
186 | 267 | };
|
187 | 268 |
|
188 | 269 | utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
|
189 |
| - GREENTEA_SETUP(20, "default_auto"); |
| 270 | + GREENTEA_SETUP(120, "default_auto"); |
190 | 271 | return greentea_test_setup_handler(number_of_cases);
|
191 | 272 | }
|
192 | 273 |
|
|
0 commit comments