test_efuse.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  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 "esp_efuse_utility.h"
  12. #include "esp_efuse_test_table.h"
  13. #include "esp32/rom/efuse.h"
  14. #include "bootloader_random.h"
  15. #include "freertos/FreeRTOS.h"
  16. #include "freertos/task.h"
  17. #include "freertos/semphr.h"
  18. #include "test_utils.h"
  19. #include "sdkconfig.h"
  20. //#define MANUAL_FPGA_TEST
  21. static const char* TAG = "efuse_test";
  22. static void test_read_blob(void)
  23. {
  24. esp_efuse_utility_update_virt_blocks();
  25. esp_efuse_utility_debug_dump_blocks();
  26. uint8_t mac[6];
  27. ESP_LOGI(TAG, "1. Read MAC address");
  28. memset(mac, 0, sizeof(mac));
  29. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  30. TEST_ASSERT_EQUAL_INT(sizeof(mac) * 8, esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY));
  31. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  32. #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
  33. ESP_LOGI(TAG, "2. Check CRC by MAC");
  34. uint8_t crc;
  35. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY_CRC, &crc, 8));
  36. TEST_ASSERT_EQUAL_HEX8(crc, esp_crc8(mac, sizeof(mac)));
  37. #endif // CONFIG_IDF_TARGET_ESP32
  38. ESP_LOGI(TAG, "3. Test check args");
  39. uint32_t test_var;
  40. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, NULL, 1));
  41. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &test_var, 0));
  42. uint8_t half_byte;
  43. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &half_byte, 4));
  44. TEST_ASSERT_EQUAL_HEX8(mac[0]&0x0F, half_byte);
  45. uint8_t buff[7] = {0x59};
  46. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &buff, sizeof(buff) * 8));
  47. TEST_ASSERT_TRUE_MESSAGE(memcmp(mac, buff, sizeof(mac)) == 0, "Operation read blob is not success");
  48. TEST_ASSERT_EQUAL_HEX8(0, buff[6]);
  49. }
  50. TEST_CASE("efuse test read_field_blob", "[efuse]")
  51. {
  52. test_read_blob();
  53. }
  54. static void test_read_cnt(void)
  55. {
  56. esp_efuse_utility_update_virt_blocks();
  57. esp_efuse_utility_debug_dump_blocks();
  58. ESP_LOGI(TAG, "1. Test check args");
  59. size_t cnt;
  60. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, NULL));
  61. ESP_LOGI(TAG, "2. Read MAC address");
  62. uint8_t mac[6];
  63. memset(mac, 0, sizeof(mac));
  64. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, 48));
  65. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, &cnt));
  66. size_t cnt_summ = 0;
  67. for (int i = 0; i < sizeof(mac); ++i) {
  68. cnt_summ += __builtin_popcount(mac[i]);
  69. }
  70. TEST_ASSERT_EQUAL_INT(cnt_summ, cnt);
  71. }
  72. TEST_CASE("efuse test read_field_cnt", "[efuse]")
  73. {
  74. test_read_cnt();
  75. }
  76. // If using efuse is real, then turn off writing tests.
  77. #ifdef CONFIG_EFUSE_VIRTUAL
  78. static void test_write_blob(void)
  79. {
  80. esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
  81. esp_efuse_utility_erase_virt_blocks();
  82. esp_efuse_utility_debug_dump_blocks();
  83. ESP_LOGI(TAG, "1. Test check args");
  84. uint16_t test1_len_8 = 0x5FAA;
  85. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &test1_len_8, 0));
  86. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, NULL, 8));
  87. TEST_ASSERT_EQUAL_HEX16(0x5FAA, test1_len_8);
  88. ESP_LOGI(TAG, "2. Test write operation");
  89. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 7));
  90. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 9));
  91. uint16_t val_read1 = 0;
  92. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 8));
  93. TEST_ASSERT_EQUAL_HEX16(test1_len_8&((1 << 7) - 1), val_read1);
  94. uint16_t test1_len_8_hi = test1_len_8 & ~((1 << 7) - 1);
  95. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  96. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  97. } else {
  98. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  99. }
  100. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 8));
  101. val_read1 = 0;
  102. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 16));
  103. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  104. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x00FF, val_read1);
  105. } else {
  106. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x007F, val_read1);
  107. }
  108. if (scheme != EFUSE_CODING_SCHEME_NONE) {
  109. esp_efuse_utility_erase_virt_blocks();
  110. ESP_LOGI(TAG, "erase virt blocks");
  111. }
  112. uint16_t test2_len_16 = 0xAA55;
  113. uint32_t val_32 = test2_len_16;
  114. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &val_32, 17));
  115. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  116. uint16_t test_16 = 0;
  117. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test_16, 16));
  118. TEST_ASSERT_EQUAL_HEX16(test2_len_16, test_16);
  119. ESP_LOGI(TAG, "3. Test field with one bit");
  120. uint8_t test5_len_1;
  121. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  122. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  123. test5_len_1 = 0;
  124. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  125. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  126. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  127. test5_len_1 = 1;
  128. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  129. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  130. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  131. test5_len_1 = 1;
  132. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  133. esp_efuse_utility_debug_dump_blocks();
  134. }
  135. TEST_CASE("efuse test write_field_blob", "[efuse]")
  136. {
  137. test_write_blob();
  138. }
  139. static void test_write_cnt(void)
  140. {
  141. esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
  142. esp_efuse_utility_erase_virt_blocks();
  143. esp_efuse_utility_debug_dump_blocks();
  144. ESP_LOGI(TAG, "1. Test check args");
  145. size_t test3_len_6 = 5;
  146. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_MAC_FACTORY, 0));
  147. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(NULL, 5));
  148. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 0));
  149. ESP_LOGI(TAG, "2. Test write operation");
  150. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  151. TEST_ASSERT_EQUAL_INT(0, test3_len_6);
  152. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  153. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  154. TEST_ASSERT_EQUAL_INT(1, test3_len_6);
  155. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  156. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  157. } else {
  158. esp_efuse_utility_erase_virt_blocks();
  159. ESP_LOGI(TAG, "erase virt blocks");
  160. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 2));
  161. }
  162. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  163. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  164. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  165. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 3));
  166. } else {
  167. esp_efuse_utility_erase_virt_blocks();
  168. ESP_LOGI(TAG, "erase virt blocks");
  169. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 5));
  170. }
  171. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  172. TEST_ASSERT_EQUAL_INT(5, test3_len_6);
  173. esp_efuse_utility_debug_dump_blocks();
  174. ESP_LOGI(TAG, "3. Test field is full set");
  175. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_TEST4_LEN_182);
  176. size_t test4_len_182;
  177. esp_efuse_utility_debug_dump_blocks();
  178. for (int i = 0; i < max_bits / 26; ++i) {
  179. ESP_LOGD(TAG, "# %d", i);
  180. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  181. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 26));
  182. } else {
  183. esp_efuse_utility_erase_virt_blocks();
  184. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, (i + 1) * 26));
  185. }
  186. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST4_LEN_182, &test4_len_182));
  187. esp_efuse_utility_debug_dump_blocks();
  188. TEST_ASSERT_EQUAL_INT((i + 1) * 26, test4_len_182);
  189. }
  190. esp_efuse_utility_debug_dump_blocks();
  191. ESP_LOGI(TAG, "4. Test field ESP_EFUSE_TEST4_LEN_182 is full");
  192. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 1));
  193. ESP_LOGI(TAG, "3. Test field with one bit");
  194. size_t test5_len_1;
  195. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  196. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  197. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  198. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  199. if (scheme != EFUSE_CODING_SCHEME_NONE) {
  200. esp_efuse_utility_erase_virt_blocks();
  201. ESP_LOGI(TAG, "erase virt blocks");
  202. }
  203. test5_len_1 = 1;
  204. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  205. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  206. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  207. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  208. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  209. test5_len_1 = 1;
  210. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  211. esp_efuse_utility_debug_dump_blocks();
  212. ESP_LOGI(TAG, "4. Test field test2_len_16");
  213. size_t test2_len_16 = 11;
  214. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST2_LEN_16, test2_len_16));
  215. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST2_LEN_16, &test2_len_16));
  216. TEST_ASSERT_EQUAL_HEX16(11, test2_len_16);
  217. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  218. TEST_ASSERT_EQUAL_HEX16(0x07FF, test2_len_16);
  219. esp_efuse_utility_debug_dump_blocks();
  220. }
  221. TEST_CASE("efuse test write_field_cnt", "[efuse]")
  222. {
  223. test_write_cnt();
  224. }
  225. void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
  226. {
  227. if ((num_used_bits + count_bits) % 8) {
  228. int start_used_item = (num_used_bits - 1) / 8;
  229. int last_used_item = ((num_used_bits + count_bits) - 1) / 8;
  230. int shift = 0;
  231. int mask = num_used_bits + count_bits;
  232. if (last_used_item == start_used_item) {
  233. shift = (num_used_bits) % 8;
  234. mask = count_bits;
  235. }
  236. arr[last_used_item] &= ((1 << (mask % 8)) - 1) << shift;
  237. }
  238. }
  239. void cut_start_arr(uint8_t *arr, size_t num_used_bits)
  240. {
  241. if (num_used_bits % 8) {
  242. int start_used_item = (num_used_bits - 1) / 8;
  243. arr[start_used_item] &= ~((1 << (num_used_bits % 8)) - 1);
  244. }
  245. }
  246. void get_part_arr(uint8_t *arr_in, uint8_t *arr_out, int num_used_bits, int count_bits)
  247. {
  248. int num_items = esp_efuse_utility_get_number_of_items(num_used_bits + count_bits, 8);
  249. memcpy(arr_out, arr_in, num_items);
  250. memset(arr_out, 0, num_used_bits / 8);
  251. cut_start_arr(arr_out, num_used_bits);
  252. cut_tail_arr(arr_out, num_used_bits, count_bits);
  253. }
  254. void fill_part_arr(uint8_t *arr_in, uint8_t *arr_out, int count_bits)
  255. {
  256. int num_items = esp_efuse_utility_get_number_of_items(count_bits, 8);
  257. memcpy(arr_out, arr_in, num_items);
  258. cut_tail_arr(arr_out, 0, count_bits);
  259. }
  260. // Writes a random array to efuse, then reads and compares it.
  261. 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)
  262. {
  263. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  264. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_w, field_size));
  265. memset(arr_r, 0, arr_size);
  266. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  267. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  268. esp_efuse_utility_debug_dump_blocks();
  269. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_w, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  270. int count_once = 0;
  271. for (int i = 0; i < arr_size; ++i) {
  272. count_once += __builtin_popcount(arr_w[i]);
  273. }
  274. size_t num_bits_r = 0;
  275. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  276. TEST_ASSERT_EQUAL_INT(count_once, num_bits_r);
  277. size_t num_bits_w = field_size - count_once;
  278. if (num_bits_w == 0) {
  279. esp_efuse_utility_erase_virt_blocks();
  280. num_bits_w = field_size;
  281. }
  282. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  283. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  284. esp_efuse_utility_debug_dump_blocks();
  285. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  286. memset(arr_r, 0, arr_size);
  287. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  288. memset(arr_temp, 0xFF, arr_size);
  289. cut_tail_arr(arr_temp, 0, field_size);
  290. esp_efuse_utility_debug_dump_blocks();
  291. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  292. }
  293. // Records a random number of bits (as "1") in the efuse field, then reads and compares.
  294. void test_cnt_part(const esp_efuse_desc_t* field[], uint8_t *arr_r, int arr_size, size_t field_size)
  295. {
  296. size_t num_bits_r = 0;
  297. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  298. TEST_ASSERT_EQUAL_INT(0, num_bits_r);
  299. TEST_ESP_OK(esp_efuse_write_field_cnt(field, field_size));
  300. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  301. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  302. esp_efuse_utility_erase_virt_blocks();
  303. int num_bits_summ_r = 0;
  304. int num_bits_w = 0;
  305. while(field_size > num_bits_summ_r) {
  306. num_bits_w = 0;
  307. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  308. bootloader_random_enable();
  309. bootloader_fill_random(&num_bits_w, 1);
  310. bootloader_random_disable();
  311. num_bits_w = num_bits_w * field_size / 255;
  312. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  313. break;
  314. }
  315. }
  316. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  317. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  318. num_bits_summ_r += num_bits_w;
  319. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, num_bits_r);
  320. memset(arr_r, 0, arr_size);
  321. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  322. int count_once = 0;
  323. for (int i = 0; i < arr_size; ++i) {
  324. count_once += __builtin_popcount(arr_r[i]);
  325. }
  326. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, count_once);
  327. ESP_LOGI(TAG, "Once bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  328. }
  329. esp_efuse_utility_debug_dump_blocks();
  330. }
  331. // 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.
  332. 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)
  333. {
  334. esp_efuse_utility_debug_dump_blocks();
  335. int num_bits_summ_r = 0;
  336. int num_bits_w = 0;
  337. memset(arr_w, 0, arr_size);
  338. bootloader_random_enable();
  339. bootloader_fill_random(arr_w, arr_size);
  340. bootloader_random_disable();
  341. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  342. while(field_size > num_bits_summ_r) {
  343. num_bits_w = 0;
  344. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  345. bootloader_random_enable();
  346. bootloader_fill_random(&num_bits_w, 1);
  347. bootloader_random_disable();
  348. num_bits_w = num_bits_w * field_size / 255;
  349. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  350. break;
  351. }
  352. }
  353. ESP_LOGI(TAG, "Summ bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  354. memset(arr_temp, 0, arr_size);
  355. get_part_arr(arr_w, arr_temp, num_bits_summ_r, num_bits_w);
  356. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  357. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_temp, field_size));
  358. memset(arr_r, 0, arr_size);
  359. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  360. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  361. esp_efuse_utility_debug_dump_blocks();
  362. num_bits_summ_r += num_bits_w;
  363. memset(arr_temp, 0, arr_size);
  364. fill_part_arr(arr_w, arr_temp, num_bits_summ_r);
  365. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  366. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  367. }
  368. }
  369. void check_efuse_table_test(int cycle)
  370. {
  371. int num_test = 0;
  372. while(1) {
  373. const esp_efuse_desc_t** field;
  374. switch (num_test++) {
  375. case 0: field = ESP_EFUSE_TEST1_LEN_8; break;
  376. case 1: field = ESP_EFUSE_TEST2_LEN_16; break;
  377. case 2: field = ESP_EFUSE_TEST3_LEN_6; break;
  378. case 3: field = ESP_EFUSE_TEST4_LEN_182; break;
  379. case 4: field = ESP_EFUSE_TEST5_LEN_1; break;
  380. case 5: field = ESP_EFUSE_TEST6_LEN_17; break;
  381. default:
  382. return;
  383. break;
  384. }
  385. size_t field_size = esp_efuse_get_field_size(field);
  386. int arr_size = esp_efuse_utility_get_number_of_items(field_size, 8);
  387. uint8_t *arr_w = (uint8_t *) malloc(arr_size);
  388. uint8_t *arr_r = (uint8_t *) malloc(arr_size);
  389. uint8_t *arr_temp = (uint8_t *) malloc(arr_size);
  390. ESP_LOGI(TAG, "Test#%d", num_test);
  391. for (int c = 1; c <= cycle; ++c) {
  392. ESP_LOGI(TAG, "Cycle#%d/%d", c, cycle);
  393. memset(arr_w, 0, arr_size);
  394. bootloader_random_enable();
  395. bootloader_fill_random(arr_w, arr_size);
  396. bootloader_random_disable();
  397. cut_tail_arr(arr_w, 0, field_size);
  398. esp_efuse_utility_erase_virt_blocks();
  399. ESP_LOGI(TAG, "1) blob write/read");
  400. test_blob(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  401. esp_efuse_utility_erase_virt_blocks();
  402. ESP_LOGI(TAG, "2) cnt part write/read");
  403. test_cnt_part(field, arr_r, arr_size, field_size);
  404. esp_efuse_utility_erase_virt_blocks();
  405. ESP_LOGI(TAG, "3) blob part write/read");
  406. test_blob_part(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  407. }
  408. free(arr_temp);
  409. free(arr_r);
  410. free(arr_w);
  411. }
  412. }
  413. TEST_CASE("efuse esp_efuse_table_test", "[efuse]")
  414. {
  415. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  416. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  417. check_efuse_table_test(2);
  418. } else {
  419. ESP_LOGI(TAG, "This test is applicable only to the EFUSE_CODING_SCHEME_NONE. Skip this test.");
  420. }
  421. }
  422. TEST_CASE("Test esp_efuse_read_block esp_efuse_write_block functions", "[efuse]")
  423. {
  424. int count_useful_reg = 0;
  425. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  426. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  427. printf("EFUSE_CODING_SCHEME_NONE\n");
  428. count_useful_reg = 8;
  429. }
  430. #if CONFIG_IDF_TARGET_ESP32
  431. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  432. printf("EFUSE_CODING_SCHEME_3_4\n");
  433. count_useful_reg = 6;
  434. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  435. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  436. count_useful_reg = 4;
  437. }
  438. #elif CONFIG_IDF_TARGET_ESP32S2
  439. if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  440. printf("EFUSE_CODING_SCHEME_RS\n");
  441. count_useful_reg = 8;
  442. }
  443. #endif
  444. esp_efuse_utility_reset();
  445. esp_efuse_utility_erase_virt_blocks();
  446. uint8_t src_key[32] = { 0 };
  447. uint8_t dst_key[32] = { 0 };
  448. int offset_in_bits = 0;
  449. for (int i = 0; i < count_useful_reg * 4; ++i) {
  450. src_key[i] = 0xAB + i;
  451. }
  452. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32));
  453. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32));
  454. esp_efuse_utility_debug_dump_blocks();
  455. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, sizeof(src_key));
  456. esp_efuse_utility_erase_virt_blocks();
  457. memset(src_key, 0, sizeof(src_key));
  458. memset(dst_key, 0, sizeof(dst_key));
  459. offset_in_bits = count_useful_reg * 32 / 2;
  460. for (int i = 0; i < count_useful_reg * 4 / 2; ++i) {
  461. src_key[i] = 0xCD + i;
  462. }
  463. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32 / 2));
  464. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32 / 2));
  465. esp_efuse_utility_debug_dump_blocks();
  466. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, count_useful_reg * 4 / 2);
  467. esp_efuse_utility_erase_virt_blocks();
  468. }
  469. TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
  470. {
  471. esp_efuse_utility_update_virt_blocks();
  472. esp_efuse_utility_debug_dump_blocks();
  473. int count_useful_reg = 0;
  474. uint8_t r_buff[32];
  475. int st_offset = -1;
  476. int num_block;
  477. for (num_block = EFUSE_BLK1; num_block < 4; ++num_block) {
  478. memset(r_buff, 0, sizeof(r_buff));
  479. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(num_block);
  480. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  481. printf("EFUSE_CODING_SCHEME_NONE. The test is not applicable.\n");
  482. count_useful_reg = 8;
  483. return;
  484. }
  485. #if CONFIG_IDF_TARGET_ESP32
  486. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  487. printf("EFUSE_CODING_SCHEME_3_4\n");
  488. count_useful_reg = 6;
  489. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  490. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  491. count_useful_reg = 4;
  492. }
  493. #elif CONFIG_IDF_TARGET_ESP32S2
  494. if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  495. printf("EFUSE_CODING_SCHEME_RS\n");
  496. if (num_block == EFUSE_BLK1) {
  497. count_useful_reg = 6;
  498. } else {
  499. count_useful_reg = 8;
  500. }
  501. }
  502. #endif
  503. TEST_ESP_OK(esp_efuse_read_block(num_block, r_buff, 0, count_useful_reg * 32));
  504. for (int i = 0; i < count_useful_reg * 4; ++i) {
  505. if (r_buff[i] != 0) {
  506. // found used byte
  507. for (int j = 0; j < 8; ++j) {
  508. if ((r_buff[i] & (1 << j)) == 0) {
  509. // found empty bit into this byte
  510. st_offset = i * 8 + j;
  511. printf("Byte = 0x%02x. offset is = %d\n", r_buff[i], st_offset);
  512. break;
  513. }
  514. }
  515. if (st_offset != -1) {
  516. break;
  517. }
  518. }
  519. }
  520. if (st_offset != -1) {
  521. break;
  522. }
  523. }
  524. if (st_offset != -1) {
  525. // write 1 bit to empty place.
  526. uint8_t val = 1;
  527. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_block(num_block, &val, st_offset, 1));
  528. } else {
  529. printf("Test skipped. It is not applicable, the device has no written bits.");
  530. }
  531. }
  532. #ifndef CONFIG_FREERTOS_UNICORE
  533. static const int delay_ms = 2000;
  534. static xSemaphoreHandle sema;
  535. static void task1(void* arg)
  536. {
  537. TEST_ESP_OK(esp_efuse_batch_write_begin());
  538. ESP_LOGI(TAG, "Start work in batch mode");
  539. xSemaphoreGive(sema);
  540. vTaskDelay((delay_ms + 100) / portTICK_PERIOD_MS);
  541. ESP_LOGI(TAG, "Finish work in batch mode");
  542. TEST_ESP_OK(esp_efuse_batch_write_cancel());
  543. vTaskDelete(NULL);
  544. }
  545. static void task2(void* arg)
  546. {
  547. xSemaphoreTake(sema, portMAX_DELAY);
  548. uint8_t mac[6];
  549. int64_t t1 = esp_timer_get_time();
  550. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  551. int64_t t2 = esp_timer_get_time();
  552. int diff_ms = (t2 - t1) / 1000;
  553. TEST_ASSERT_GREATER_THAN(delay_ms, diff_ms);
  554. ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  555. xSemaphoreGive(sema);
  556. vTaskDelete(NULL);
  557. }
  558. static void task3(void* arg)
  559. {
  560. xSemaphoreTake(sema, portMAX_DELAY);
  561. size_t test3_len_6 = 2;
  562. int64_t t1 = esp_timer_get_time();
  563. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
  564. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  565. int64_t t2 = esp_timer_get_time();
  566. ESP_LOGI(TAG, "write&read test3_len_6: %d", test3_len_6);
  567. int diff_ms = (t2 - t1) / 1000;
  568. TEST_ASSERT_GREATER_THAN(delay_ms, diff_ms);
  569. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  570. xSemaphoreGive(sema);
  571. vTaskDelete(NULL);
  572. }
  573. TEST_CASE("Batch mode is thread-safe", "[efuse]")
  574. {
  575. // Batch mode blocks work with efuse on other tasks.
  576. esp_efuse_utility_update_virt_blocks();
  577. esp_efuse_utility_debug_dump_blocks();
  578. sema = xSemaphoreCreateBinary();
  579. printf("\n");
  580. xTaskCreatePinnedToCore(task1, "task1", 2048, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
  581. xTaskCreatePinnedToCore(task2, "task2", 2048, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  582. vTaskDelay(3000 / portTICK_PERIOD_MS);
  583. xSemaphoreTake(sema, portMAX_DELAY);
  584. esp_efuse_utility_reset();
  585. esp_efuse_utility_erase_virt_blocks();
  586. printf("\n");
  587. xTaskCreatePinnedToCore(task1, "task1", 2048, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
  588. xTaskCreatePinnedToCore(task3, "task3", 2048, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  589. vTaskDelay(3000 / portTICK_PERIOD_MS);
  590. xSemaphoreTake(sema, portMAX_DELAY);
  591. printf("\n");
  592. vSemaphoreDelete(sema);
  593. esp_efuse_utility_reset();
  594. esp_efuse_utility_erase_virt_blocks();
  595. }
  596. #endif // #ifndef CONFIG_FREERTOS_UNICORE
  597. static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
  598. {
  599. size_t out_cnt;
  600. TEST_ESP_OK(esp_efuse_set_write_protect(blk));
  601. esp_efuse_read_field_cnt(field, &out_cnt);
  602. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  603. }
  604. static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
  605. {
  606. size_t out_cnt;
  607. if (read_first) {
  608. esp_efuse_read_field_cnt(field, &out_cnt);
  609. TEST_ASSERT_EQUAL_INT(0, out_cnt);
  610. }
  611. TEST_ESP_OK(esp_efuse_set_read_protect(blk));
  612. esp_efuse_read_field_cnt(field, &out_cnt);
  613. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  614. if (read_first) {
  615. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
  616. }
  617. }
  618. TEST_CASE("Test a write/read protection", "[efuse]")
  619. {
  620. esp_efuse_utility_reset();
  621. esp_efuse_utility_erase_virt_blocks();
  622. esp_efuse_utility_debug_dump_blocks();
  623. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
  624. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
  625. size_t out_cnt;
  626. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
  627. TEST_ASSERT_EQUAL_INT(0, out_cnt);
  628. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
  629. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
  630. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  631. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
  632. #ifdef CONFIG_IDF_TARGET_ESP32
  633. test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_BLK2);
  634. test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_BLK3);
  635. esp_efuse_utility_debug_dump_blocks();
  636. test_rp(EFUSE_BLK1, ESP_EFUSE_RD_DIS_BLK1, true);
  637. test_rp(EFUSE_BLK2, ESP_EFUSE_RD_DIS_BLK2, false);
  638. test_rp(EFUSE_BLK3, ESP_EFUSE_RD_DIS_BLK3, false);
  639. #elif defined(CONFIG_IDF_TARGET_ESP32S2)
  640. test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_SYS_DATA_PART1);
  641. test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_USER_DATA);
  642. esp_efuse_utility_debug_dump_blocks();
  643. test_rp(EFUSE_BLK4, ESP_EFUSE_RD_DIS_KEY0, true);
  644. test_rp(EFUSE_BLK5, ESP_EFUSE_RD_DIS_KEY1, false);
  645. test_rp(EFUSE_BLK6, ESP_EFUSE_RD_DIS_KEY2, false);
  646. #else
  647. #error New chip not supported!
  648. #endif
  649. esp_efuse_utility_debug_dump_blocks();
  650. esp_efuse_utility_reset();
  651. esp_efuse_utility_erase_virt_blocks();
  652. }
  653. #endif // #ifdef CONFIG_EFUSE_VIRTUAL
  654. #if defined(MANUAL_FPGA_TEST) && !defined(CONFIG_EFUSE_VIRTUAL)
  655. #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32)
  656. TEST_CASE("Test a real write (FPGA)", "[efuse]")
  657. {
  658. ESP_LOGI(TAG, "1. Write MAC address");
  659. esp_efuse_utility_debug_dump_blocks();
  660. uint8_t mac[6];
  661. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  662. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  663. uint8_t new_mac[6];
  664. if (mac[0] == 0) {
  665. new_mac[0] = 0x71;
  666. new_mac[1] = 0x62;
  667. new_mac[2] = 0x53;
  668. new_mac[3] = 0x44;
  669. new_mac[4] = 0x35;
  670. new_mac[5] = 0x26;
  671. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
  672. ESP_LOGI(TAG, "new MAC: %02x:%02x:%02x:%02x:%02x:%02x", new_mac[0], new_mac[1], new_mac[2], new_mac[3], new_mac[4], new_mac[5]);
  673. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  674. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_mac, mac, sizeof(new_mac));
  675. esp_efuse_utility_debug_dump_blocks();
  676. }
  677. ESP_LOGI(TAG, "2. Write KEY3");
  678. uint8_t key[32] = {0};
  679. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
  680. for (int i = 0; i < sizeof(key); ++i) {
  681. TEST_ASSERT_EQUAL_INT(0, key[i]);
  682. }
  683. uint8_t new_key[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  684. 10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
  685. 20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
  686. 30, 31};
  687. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY3, &new_key, 256));
  688. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
  689. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(new_mac));
  690. esp_efuse_utility_debug_dump_blocks();
  691. ESP_LOGI(TAG, "3. Set a read protection for KEY3");
  692. TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK7));
  693. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
  694. for (int i = 0; i < sizeof(key); ++i) {
  695. TEST_ASSERT_EQUAL_INT(0, key[i]);
  696. }
  697. esp_efuse_utility_debug_dump_blocks();
  698. ESP_LOGI(TAG, "4. Write SECURE_VERSION");
  699. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
  700. size_t read_sec_version;
  701. esp_efuse_utility_debug_dump_blocks();
  702. for (int i = 0; i < max_bits; ++i) {
  703. ESP_LOGI(TAG, "# %d", i);
  704. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_SECURE_VERSION, 1));
  705. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_SECURE_VERSION, &read_sec_version));
  706. esp_efuse_utility_debug_dump_blocks();
  707. TEST_ASSERT_EQUAL_INT(i + 1, read_sec_version);
  708. }
  709. }
  710. #endif // DISABLED_FOR_TARGETS(ESP32)
  711. #endif // FPGA_TEST