test_spi_flash_emulation.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "catch.hpp"
  7. #include "spi_flash_mmap.h"
  8. #include "esp_partition.h"
  9. #include "spi_flash_emulation.h"
  10. #include <functional>
  11. using namespace std;
  12. template <typename Tit>
  13. bool range_empty_n(Tit it_begin, size_t n)
  14. {
  15. return all_of(it_begin, it_begin + n, bind(equal_to<uint32_t>(), placeholders::_1, 0xffffffff));
  16. }
  17. struct FlashEmuFixture {
  18. FlashEmuFixture(size_t sectors) : esp_part(), emu(sectors) { }
  19. esp_partition_t esp_part;
  20. SpiFlashEmulator emu;
  21. };
  22. TEST_CASE("flash starts with all bytes == 0xff", "[spi_flash_emu]")
  23. {
  24. FlashEmuFixture f(4);
  25. uint8_t sector[SPI_FLASH_SEC_SIZE];
  26. for (int i = 0; i < 4; ++i) {
  27. CHECK(esp_partition_read(&f.esp_part, 0, sector, sizeof(sector)) == ESP_OK);
  28. for (auto v: sector) {
  29. CHECK(v == 0xff);
  30. }
  31. }
  32. }
  33. TEST_CASE("invalid writes are checked", "[spi_flash_emu]")
  34. {
  35. FlashEmuFixture f(1);
  36. uint32_t val = 0;
  37. CHECK(esp_partition_write(&f.esp_part, 0, &val, 4) == ESP_OK);
  38. val = 1;
  39. CHECK(esp_partition_write(&f.esp_part, 0, &val, 4) == ESP_ERR_FLASH_OP_FAIL);
  40. }
  41. TEST_CASE("out of bounds writes fail", "[spi_flash_emu]")
  42. {
  43. FlashEmuFixture f(4);
  44. uint32_t vals[8];
  45. std::fill_n(vals, 8, 0);
  46. CHECK(esp_partition_write(&f.esp_part, 0, &vals, sizeof(vals)) == ESP_OK);
  47. CHECK(esp_partition_write(&f.esp_part, 4*4096 - sizeof(vals), &vals, sizeof(vals)) == ESP_OK);
  48. CHECK(esp_partition_write(&f.esp_part, 4*4096 - sizeof(vals) + 4, &vals, sizeof(vals)) == ESP_ERR_FLASH_OP_FAIL);
  49. }
  50. TEST_CASE("after erase the sector is set to 0xff", "[spi_flash_emu]")
  51. {
  52. FlashEmuFixture f(4);
  53. uint32_t val1 = 0xab00cd12;
  54. CHECK(esp_partition_write(&f.esp_part, 0, &val1, sizeof(val1)) == ESP_OK);
  55. uint32_t val2 = 0x5678efab;
  56. CHECK(esp_partition_write(&f.esp_part, 4096 - 4, &val2, sizeof(val2)) == ESP_OK);
  57. CHECK(f.emu.words()[0] == val1);
  58. CHECK(range_empty_n(f.emu.words() + 1, 4096 / 4 - 2));
  59. CHECK(f.emu.words()[4096 / 4 - 1] == val2);
  60. CHECK(esp_partition_erase_range(&f.esp_part, 0, SPI_FLASH_SEC_SIZE) == ESP_OK);
  61. CHECK(f.emu.words()[0] == 0xffffffff);
  62. CHECK(range_empty_n(f.emu.words() + 1, 4096 / 4 - 2));
  63. CHECK(f.emu.words()[4096 / 4 - 1] == 0xffffffff);
  64. }
  65. TEST_CASE("EMU raw read function works", "[spi_flash_emu]")
  66. {
  67. FlashEmuFixture f(4);
  68. uint32_t value = 0xdeadbeef;
  69. uint32_t read_value = 0;
  70. CHECK(esp_partition_write(&f.esp_part, 0, &value, sizeof(value)) == ESP_OK);
  71. CHECK(esp_partition_read_raw(&f.esp_part, 0, &read_value, sizeof(&read_value)) == ESP_OK);
  72. CHECK(read_value == 0xdeadbeef);
  73. }
  74. TEST_CASE("EMU raw write function works", "[spi_flash_emu]")
  75. {
  76. FlashEmuFixture f(4);
  77. uint32_t value = 0xdeadbeef;
  78. uint32_t read_value = 0;
  79. CHECK(esp_partition_write_raw(&f.esp_part, 0, &value, sizeof(value)) == ESP_OK);
  80. CHECK(esp_partition_read(&f.esp_part, 0, &read_value, sizeof(&read_value)) == ESP_OK);
  81. CHECK(read_value == 0xdeadbeef);
  82. }
  83. TEST_CASE("read/write/erase operation times are calculated correctly", "[spi_flash_emu]")
  84. {
  85. FlashEmuFixture f(1);
  86. uint8_t data[512];
  87. esp_partition_read(&f.esp_part, 0, data, 4);
  88. CHECK(f.emu.getTotalTime() == 7);
  89. CHECK(f.emu.getReadOps() == 1);
  90. CHECK(f.emu.getReadBytes() == 4);
  91. f.emu.clearStats();
  92. esp_partition_read(&f.esp_part, 0, data, 8);
  93. CHECK(f.emu.getTotalTime() == 5);
  94. CHECK(f.emu.getReadOps() == 1);
  95. CHECK(f.emu.getReadBytes() == 8);
  96. f.emu.clearStats();
  97. esp_partition_read(&f.esp_part, 0, data, 16);
  98. CHECK(f.emu.getTotalTime() == 6);
  99. CHECK(f.emu.getReadOps() == 1);
  100. CHECK(f.emu.getReadBytes() == 16);
  101. f.emu.clearStats();
  102. esp_partition_read(&f.esp_part, 0, data, 128);
  103. CHECK(f.emu.getTotalTime() == 18);
  104. CHECK(f.emu.getReadOps() == 1);
  105. CHECK(f.emu.getReadBytes() == 128);
  106. f.emu.clearStats();
  107. esp_partition_read(&f.esp_part, 0, data, 256);
  108. CHECK(f.emu.getTotalTime() == 32);
  109. f.emu.clearStats();
  110. esp_partition_read(&f.esp_part, 0, data, (128+256)/2);
  111. CHECK(f.emu.getTotalTime() == (18+32)/2);
  112. f.emu.clearStats();
  113. esp_partition_write(&f.esp_part, 0, data, 4);
  114. CHECK(f.emu.getTotalTime() == 19);
  115. CHECK(f.emu.getWriteOps() == 1);
  116. CHECK(f.emu.getWriteBytes() == 4);
  117. f.emu.clearStats();
  118. CHECK(f.emu.getWriteOps() == 0);
  119. CHECK(f.emu.getWriteBytes() == 0);
  120. esp_partition_write(&f.esp_part, 0, data, 8);
  121. CHECK(f.emu.getTotalTime() == 23);
  122. f.emu.clearStats();
  123. esp_partition_write(&f.esp_part, 0, data, 16);
  124. CHECK(f.emu.getTotalTime() == 35);
  125. CHECK(f.emu.getWriteOps() == 1);
  126. CHECK(f.emu.getWriteBytes() == 16);
  127. f.emu.clearStats();
  128. esp_partition_write(&f.esp_part, 0, data, 128);
  129. CHECK(f.emu.getTotalTime() == 205);
  130. f.emu.clearStats();
  131. esp_partition_write(&f.esp_part, 0, data, 256);
  132. CHECK(f.emu.getTotalTime() == 417);
  133. f.emu.clearStats();
  134. esp_partition_write(&f.esp_part, 0, data, (128+256)/2);
  135. CHECK(f.emu.getTotalTime() == (205+417)/2);
  136. f.emu.clearStats();
  137. esp_partition_erase_range(&f.esp_part, 0, SPI_FLASH_SEC_SIZE);
  138. CHECK(f.emu.getEraseOps() == 1);
  139. CHECK(f.emu.getTotalTime() == 37142);
  140. }
  141. TEST_CASE("data is randomized predictably", "[spi_flash_emu]")
  142. {
  143. SpiFlashEmulator emu1(3);
  144. emu1.randomize(0x12345678);
  145. SpiFlashEmulator emu2(3);
  146. emu2.randomize(0x12345678);
  147. CHECK(std::equal(emu1.bytes(), emu1.bytes() + emu1.size(), emu2.bytes()));
  148. }