test_efuse.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include "unity.h"
  7. #include "esp_log.h"
  8. #include <string.h>
  9. #include "esp_efuse.h"
  10. #include "esp_efuse_table.h"
  11. #include "../src/esp_efuse_utility.h"
  12. #include "esp_efuse_test_table.h"
  13. #include "esp32/rom/efuse.h"
  14. #include "bootloader_random.h"
  15. #include "sdkconfig.h"
  16. static const char* TAG = "efuse_test";
  17. static void test_read_blob(void)
  18. {
  19. esp_efuse_utility_update_virt_blocks();
  20. esp_efuse_utility_debug_dump_blocks();
  21. uint8_t mac[6];
  22. ESP_LOGI(TAG, "1. Read MAC address");
  23. memset(mac, 0, sizeof(mac));
  24. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  25. TEST_ASSERT_EQUAL_INT(sizeof(mac) * 8, esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY));
  26. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  27. ESP_LOGI(TAG, "2. Check CRC by MAC");
  28. uint8_t crc;
  29. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY_CRC, &crc, 8));
  30. TEST_ASSERT_EQUAL_HEX8(crc, esp_crc8(mac, sizeof(mac)));
  31. ESP_LOGI(TAG, "3. Test check args");
  32. uint32_t test_var;
  33. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, NULL, 1));
  34. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &test_var, 0));
  35. uint8_t half_byte;
  36. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &half_byte, 4));
  37. TEST_ASSERT_EQUAL_HEX8(mac[0]&0x0F, half_byte);
  38. uint8_t buff[7] = {0x59};
  39. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &buff, sizeof(buff) * 8));
  40. TEST_ASSERT_TRUE_MESSAGE(memcmp(mac, buff, sizeof(mac)) == 0, "Operation read blob is not success");
  41. TEST_ASSERT_EQUAL_HEX8(0, buff[6]);
  42. }
  43. TEST_CASE("efuse test read_field_blob", "[efuse]")
  44. {
  45. test_read_blob();
  46. }
  47. static void test_read_cnt(void)
  48. {
  49. esp_efuse_utility_update_virt_blocks();
  50. esp_efuse_utility_debug_dump_blocks();
  51. ESP_LOGI(TAG, "1. Test check args");
  52. size_t cnt;
  53. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, NULL));
  54. ESP_LOGI(TAG, "2. Read MAC address");
  55. uint8_t mac[6];
  56. memset(mac, 0, sizeof(mac));
  57. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, 48));
  58. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, &cnt));
  59. size_t cnt_summ = 0;
  60. for (int i = 0; i < sizeof(mac); ++i) {
  61. cnt_summ += __builtin_popcount(mac[i]);
  62. }
  63. TEST_ASSERT_EQUAL_INT(cnt_summ, cnt);
  64. }
  65. TEST_CASE("efuse test read_field_cnt", "[efuse]")
  66. {
  67. test_read_cnt();
  68. }
  69. // If using efuse is real, then turn off writing tests.
  70. #ifdef CONFIG_EFUSE_VIRTUAL
  71. static void test_write_blob(void)
  72. {
  73. esp_efuse_utility_erase_virt_blocks();
  74. esp_efuse_utility_debug_dump_blocks();
  75. ESP_LOGI(TAG, "1. Test check args");
  76. uint16_t test1_len_8 = 0x5FAA;
  77. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &test1_len_8, 0));
  78. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, NULL, 8));
  79. TEST_ASSERT_EQUAL_HEX16(0x5FAA, test1_len_8);
  80. ESP_LOGI(TAG, "2. Test write operation");
  81. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 7));
  82. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 9));
  83. uint16_t val_read1 = 0;
  84. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 8));
  85. TEST_ASSERT_EQUAL_HEX16(test1_len_8&((1 << 7) - 1), val_read1);
  86. uint16_t test1_len_8_hi = test1_len_8 & ~((1 << 7) - 1);
  87. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  88. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 8));
  89. val_read1 = 0;
  90. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 16));
  91. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x00FF, val_read1);
  92. uint16_t test2_len_16 = 0xAA55;
  93. uint32_t val_32 = test2_len_16;
  94. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &val_32, 17));
  95. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  96. uint16_t test_16 = 0;
  97. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test_16, 16));
  98. TEST_ASSERT_EQUAL_HEX16(test2_len_16, test_16);
  99. ESP_LOGI(TAG, "3. Test field with one bit");
  100. uint8_t test5_len_1;
  101. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  102. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  103. test5_len_1 = 0;
  104. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  105. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  106. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  107. test5_len_1 = 1;
  108. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  109. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  110. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  111. test5_len_1 = 1;
  112. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  113. esp_efuse_utility_debug_dump_blocks();
  114. }
  115. TEST_CASE("efuse test write_field_blob", "[efuse]")
  116. {
  117. test_write_blob();
  118. }
  119. static void test_write_cnt(void)
  120. {
  121. esp_efuse_utility_erase_virt_blocks();
  122. esp_efuse_utility_debug_dump_blocks();
  123. ESP_LOGI(TAG, "1. Test check args");
  124. size_t test3_len_6 = 5;
  125. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_MAC_FACTORY, 0));
  126. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(NULL, 5));
  127. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 0));
  128. ESP_LOGI(TAG, "2. Test write operation");
  129. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  130. TEST_ASSERT_EQUAL_INT(0, test3_len_6);
  131. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  132. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  133. TEST_ASSERT_EQUAL_INT(1, test3_len_6);
  134. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  135. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  136. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  137. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 3));
  138. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  139. TEST_ASSERT_EQUAL_INT(5, test3_len_6);
  140. esp_efuse_utility_debug_dump_blocks();
  141. ESP_LOGI(TAG, "3. Test field is full set");
  142. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_TEST4_LEN_182);
  143. size_t test4_len_182;
  144. esp_efuse_utility_debug_dump_blocks();
  145. for (int i = 0; i < max_bits / 26; ++i) {
  146. ESP_LOGD(TAG, "# %d", i);
  147. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 26));
  148. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST4_LEN_182, &test4_len_182));
  149. esp_efuse_utility_debug_dump_blocks();
  150. TEST_ASSERT_EQUAL_INT((i + 1) * 26, test4_len_182);
  151. }
  152. esp_efuse_utility_debug_dump_blocks();
  153. ESP_LOGI(TAG, "4. Test field ESP_EFUSE_TEST4_LEN_182 is full");
  154. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 1));
  155. ESP_LOGI(TAG, "3. Test field with one bit");
  156. size_t test5_len_1;
  157. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  158. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  159. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  160. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  161. test5_len_1 = 1;
  162. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  163. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  164. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  165. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  166. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  167. test5_len_1 = 1;
  168. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  169. esp_efuse_utility_debug_dump_blocks();
  170. ESP_LOGI(TAG, "4. Test field test2_len_16");
  171. size_t test2_len_16 = 11;
  172. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST2_LEN_16, test2_len_16));
  173. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST2_LEN_16, &test2_len_16));
  174. TEST_ASSERT_EQUAL_HEX16(11, test2_len_16);
  175. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  176. TEST_ASSERT_EQUAL_HEX16(0x07FF, test2_len_16);
  177. esp_efuse_utility_debug_dump_blocks();
  178. }
  179. TEST_CASE("efuse test write_field_cnt", "[efuse]")
  180. {
  181. test_write_cnt();
  182. }
  183. TEST_CASE("efuse test single bit functions", "[efuse]")
  184. {
  185. esp_efuse_utility_erase_virt_blocks();
  186. esp_efuse_utility_debug_dump_blocks();
  187. uint8_t test_bit;
  188. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
  189. TEST_ASSERT_EQUAL_HEX8(0, test_bit);
  190. test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
  191. TEST_ASSERT_EQUAL_HEX8(0, test_bit);
  192. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
  193. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
  194. TEST_ASSERT_EQUAL_HEX8(1, test_bit);
  195. test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
  196. TEST_ASSERT_EQUAL_HEX8(1, test_bit);
  197. // Can write the bit again and it's a no-op
  198. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
  199. TEST_ASSERT_EQUAL_HEX8(1, esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1));
  200. esp_efuse_utility_debug_dump_blocks();
  201. }
  202. void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
  203. {
  204. if ((num_used_bits + count_bits) % 8) {
  205. int start_used_item = (num_used_bits - 1) / 8;
  206. int last_used_item = ((num_used_bits + count_bits) - 1) / 8;
  207. int shift = 0;
  208. int mask = num_used_bits + count_bits;
  209. if (last_used_item == start_used_item) {
  210. shift = (num_used_bits) % 8;
  211. mask = count_bits;
  212. }
  213. arr[last_used_item] &= ((1 << (mask % 8)) - 1) << shift;
  214. }
  215. }
  216. void cut_start_arr(uint8_t *arr, size_t num_used_bits)
  217. {
  218. if (num_used_bits % 8) {
  219. int start_used_item = (num_used_bits - 1) / 8;
  220. arr[start_used_item] &= ~((1 << (num_used_bits % 8)) - 1);
  221. }
  222. }
  223. void get_part_arr(uint8_t *arr_in, uint8_t *arr_out, int num_used_bits, int count_bits)
  224. {
  225. int num_items = esp_efuse_utility_get_number_of_items(num_used_bits + count_bits, 8);
  226. memcpy(arr_out, arr_in, num_items);
  227. memset(arr_out, 0, num_used_bits / 8);
  228. cut_start_arr(arr_out, num_used_bits);
  229. cut_tail_arr(arr_out, num_used_bits, count_bits);
  230. }
  231. void fill_part_arr(uint8_t *arr_in, uint8_t *arr_out, int count_bits)
  232. {
  233. int num_items = esp_efuse_utility_get_number_of_items(count_bits, 8);
  234. memcpy(arr_out, arr_in, num_items);
  235. cut_tail_arr(arr_out, 0, count_bits);
  236. }
  237. // Writes a random array to efuse, then reads and compares it.
  238. void test_blob(const esp_efuse_desc_t* field[], uint8_t *arr_w, uint8_t *arr_r, uint8_t *arr_temp, int arr_size, size_t field_size)
  239. {
  240. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  241. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_w, field_size));
  242. memset(arr_r, 0, arr_size);
  243. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  244. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  245. esp_efuse_utility_debug_dump_blocks();
  246. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_w, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  247. int count_once = 0;
  248. for (int i = 0; i < arr_size; ++i) {
  249. count_once += __builtin_popcount(arr_w[i]);
  250. }
  251. size_t num_bits_r = 0;
  252. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  253. TEST_ASSERT_EQUAL_INT(count_once, num_bits_r);
  254. size_t num_bits_w = field_size - count_once;
  255. if (num_bits_w == 0) {
  256. esp_efuse_utility_erase_virt_blocks();
  257. num_bits_w = field_size;
  258. }
  259. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  260. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  261. esp_efuse_utility_debug_dump_blocks();
  262. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  263. memset(arr_r, 0, arr_size);
  264. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  265. memset(arr_temp, 0xFF, arr_size);
  266. cut_tail_arr(arr_temp, 0, field_size);
  267. esp_efuse_utility_debug_dump_blocks();
  268. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  269. }
  270. // Records a random number of bits (as "1") in the efuse field, then reads and compares.
  271. void test_cnt_part(const esp_efuse_desc_t* field[], uint8_t *arr_r, int arr_size, size_t field_size)
  272. {
  273. size_t num_bits_r = 0;
  274. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  275. TEST_ASSERT_EQUAL_INT(0, num_bits_r);
  276. TEST_ESP_OK(esp_efuse_write_field_cnt(field, field_size));
  277. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  278. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  279. esp_efuse_utility_erase_virt_blocks();
  280. int num_bits_summ_r = 0;
  281. int num_bits_w = 0;
  282. while(field_size > num_bits_summ_r) {
  283. num_bits_w = 0;
  284. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  285. bootloader_random_enable();
  286. bootloader_fill_random(&num_bits_w, 1);
  287. bootloader_random_disable();
  288. num_bits_w = num_bits_w * field_size / 255;
  289. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  290. break;
  291. }
  292. }
  293. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  294. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  295. num_bits_summ_r += num_bits_w;
  296. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, num_bits_r);
  297. memset(arr_r, 0, arr_size);
  298. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  299. int count_once = 0;
  300. for (int i = 0; i < arr_size; ++i) {
  301. count_once += __builtin_popcount(arr_r[i]);
  302. }
  303. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, count_once);
  304. ESP_LOGI(TAG, "Once bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  305. }
  306. esp_efuse_utility_debug_dump_blocks();
  307. }
  308. // From a random array takes a random number of bits and write to efuse, it repeats until the entire length of the field is written down.
  309. void test_blob_part(const esp_efuse_desc_t* field[], uint8_t *arr_w, uint8_t *arr_r, uint8_t *arr_temp, int arr_size, size_t field_size)
  310. {
  311. esp_efuse_utility_debug_dump_blocks();
  312. int num_bits_summ_r = 0;
  313. int num_bits_w = 0;
  314. memset(arr_w, 0, arr_size);
  315. bootloader_random_enable();
  316. bootloader_fill_random(arr_w, arr_size);
  317. bootloader_random_disable();
  318. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  319. while(field_size > num_bits_summ_r) {
  320. num_bits_w = 0;
  321. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  322. bootloader_random_enable();
  323. bootloader_fill_random(&num_bits_w, 1);
  324. bootloader_random_disable();
  325. num_bits_w = num_bits_w * field_size / 255;
  326. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  327. break;
  328. }
  329. }
  330. ESP_LOGI(TAG, "Summ bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  331. memset(arr_temp, 0, arr_size);
  332. get_part_arr(arr_w, arr_temp, num_bits_summ_r, num_bits_w);
  333. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  334. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_temp, field_size));
  335. memset(arr_r, 0, arr_size);
  336. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  337. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  338. esp_efuse_utility_debug_dump_blocks();
  339. num_bits_summ_r += num_bits_w;
  340. memset(arr_temp, 0, arr_size);
  341. fill_part_arr(arr_w, arr_temp, num_bits_summ_r);
  342. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  343. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  344. }
  345. }
  346. void check_efuse_table_test(int cycle)
  347. {
  348. int num_test = 0;
  349. while(1) {
  350. const esp_efuse_desc_t** field;
  351. switch (num_test++) {
  352. case 0: field = ESP_EFUSE_TEST1_LEN_8; break;
  353. case 1: field = ESP_EFUSE_TEST2_LEN_16; break;
  354. case 2: field = ESP_EFUSE_TEST3_LEN_6; break;
  355. case 3: field = ESP_EFUSE_TEST4_LEN_182; break;
  356. case 4: field = ESP_EFUSE_TEST5_LEN_1; break;
  357. case 5: field = ESP_EFUSE_TEST6_LEN_17; break;
  358. default:
  359. return;
  360. break;
  361. }
  362. size_t field_size = esp_efuse_get_field_size(field);
  363. int arr_size = esp_efuse_utility_get_number_of_items(field_size, 8);
  364. uint8_t *arr_w = (uint8_t *) malloc(arr_size);
  365. uint8_t *arr_r = (uint8_t *) malloc(arr_size);
  366. uint8_t *arr_temp = (uint8_t *) malloc(arr_size);
  367. ESP_LOGI(TAG, "Test#%d", num_test);
  368. for (int c = 1; c <= cycle; ++c) {
  369. ESP_LOGI(TAG, "Cycle#%d/%d", c, cycle);
  370. memset(arr_w, 0, arr_size);
  371. bootloader_random_enable();
  372. bootloader_fill_random(arr_w, arr_size);
  373. bootloader_random_disable();
  374. cut_tail_arr(arr_w, 0, field_size);
  375. esp_efuse_utility_erase_virt_blocks();
  376. ESP_LOGI(TAG, "1) blob write/read");
  377. test_blob(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  378. esp_efuse_utility_erase_virt_blocks();
  379. ESP_LOGI(TAG, "2) cnt part write/read");
  380. test_cnt_part(field, arr_r, arr_size, field_size);
  381. esp_efuse_utility_erase_virt_blocks();
  382. ESP_LOGI(TAG, "3) blob part write/read");
  383. test_blob_part(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  384. }
  385. free(arr_temp);
  386. free(arr_r);
  387. free(arr_w);
  388. }
  389. }
  390. TEST_CASE("efuse esp_efuse_table_test", "[efuse]")
  391. {
  392. check_efuse_table_test(2);
  393. }
  394. TEST_CASE("Test esp_efuse_read_block esp_efuse_write_block functions", "[efuse]")
  395. {
  396. int count_useful_reg = 0;
  397. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  398. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  399. printf("EFUSE_CODING_SCHEME_NONE\n");
  400. count_useful_reg = 8;
  401. } else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  402. printf("EFUSE_CODING_SCHEME_3_4\n");
  403. count_useful_reg = 6;
  404. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  405. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  406. count_useful_reg = 4;
  407. }
  408. esp_efuse_utility_reset();
  409. esp_efuse_utility_erase_virt_blocks();
  410. uint8_t src_key[32] = { 0 };
  411. uint8_t dst_key[32] = { 0 };
  412. int offset_in_bits = 0;
  413. for (int i = 0; i < count_useful_reg * 4; ++i) {
  414. src_key[i] = 0xAB + i;
  415. }
  416. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32));
  417. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32));
  418. esp_efuse_utility_debug_dump_blocks();
  419. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, sizeof(src_key));
  420. esp_efuse_utility_erase_virt_blocks();
  421. memset(src_key, 0, sizeof(src_key));
  422. memset(dst_key, 0, sizeof(dst_key));
  423. offset_in_bits = count_useful_reg * 32 / 2;
  424. for (int i = 0; i < count_useful_reg * 4 / 2; ++i) {
  425. src_key[i] = 0xCD + i;
  426. }
  427. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32 / 2));
  428. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32 / 2));
  429. esp_efuse_utility_debug_dump_blocks();
  430. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, count_useful_reg * 4 / 2);
  431. esp_efuse_utility_erase_virt_blocks();
  432. }
  433. TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
  434. {
  435. esp_efuse_utility_update_virt_blocks();
  436. esp_efuse_utility_debug_dump_blocks();
  437. int count_useful_reg = 0;
  438. uint8_t r_buff[32];
  439. int st_offset = -1;
  440. int num_block;
  441. for (num_block = EFUSE_BLK1; num_block < 4; ++num_block) {
  442. memset(r_buff, 0, sizeof(r_buff));
  443. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(num_block);
  444. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  445. printf("EFUSE_CODING_SCHEME_NONE. The test is not applicable.\n");
  446. count_useful_reg = 8;
  447. return;
  448. } else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  449. printf("EFUSE_CODING_SCHEME_3_4\n");
  450. count_useful_reg = 6;
  451. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  452. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  453. count_useful_reg = 4;
  454. }
  455. TEST_ESP_OK(esp_efuse_read_block(num_block, r_buff, 0, count_useful_reg * 32));
  456. for (int i = 0; i < count_useful_reg * 4; ++i) {
  457. if (r_buff[i] != 0) {
  458. // found used byte
  459. for (int j = 0; j < 8; ++j) {
  460. if ((r_buff[i] & (1 << j)) == 0) {
  461. // found empty bit into this byte
  462. st_offset = i * 8 + j;
  463. printf("Byte = 0x%02x. offset is = %d\n", r_buff[i], st_offset);
  464. break;
  465. }
  466. }
  467. if (st_offset != -1) {
  468. break;
  469. }
  470. }
  471. }
  472. if (st_offset != -1) {
  473. break;
  474. }
  475. }
  476. if (st_offset != -1) {
  477. // write 1 bit to empty place.
  478. uint8_t val = 1;
  479. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_block(num_block, &val, st_offset, 1));
  480. } else {
  481. printf("Test skipped. It is not applicable, the device has no written bits.");
  482. }
  483. }
  484. TEST_CASE("Test a write/read protection", "[efuse]")
  485. {
  486. esp_efuse_utility_reset();
  487. esp_efuse_utility_erase_virt_blocks();
  488. esp_efuse_utility_debug_dump_blocks();
  489. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
  490. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
  491. size_t out_cnt;
  492. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
  493. TEST_ASSERT_EQUAL_INT(0, out_cnt);
  494. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
  495. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
  496. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  497. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
  498. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK2));
  499. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK2, &out_cnt);
  500. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  501. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK3));
  502. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK3, &out_cnt);
  503. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  504. esp_efuse_utility_debug_dump_blocks();
  505. esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS_BLK1, &out_cnt);
  506. TEST_ASSERT_EQUAL_INT(0, out_cnt);
  507. TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK1));
  508. esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS_BLK1, &out_cnt);
  509. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  510. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(EFUSE_BLK1));
  511. TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK2));
  512. esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS_BLK2, &out_cnt);
  513. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  514. TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK3));
  515. esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS_BLK3, &out_cnt);
  516. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  517. esp_efuse_utility_debug_dump_blocks();
  518. esp_efuse_utility_reset();
  519. esp_efuse_utility_erase_virt_blocks();
  520. }
  521. #endif // #ifdef CONFIG_EFUSE_VIRTUAL