test_efuse.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. /*
  2. * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <errno.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include "unity.h"
  12. #include "esp_log.h"
  13. #include <string.h>
  14. #include "esp_efuse.h"
  15. #include "esp_efuse_table.h"
  16. #include "esp_efuse_utility.h"
  17. #include "esp_efuse_test_table.h"
  18. #include "bootloader_random.h"
  19. #include "freertos/FreeRTOS.h"
  20. #include "freertos/task.h"
  21. #include "freertos/semphr.h"
  22. #include "test_utils.h"
  23. #include "sdkconfig.h"
  24. #include "esp_rom_efuse.h"
  25. #include "bootloader_common.h"
  26. static const char* TAG = "efuse_test";
  27. static void test_read_blob(void)
  28. {
  29. esp_efuse_utility_update_virt_blocks();
  30. esp_efuse_utility_debug_dump_blocks();
  31. uint8_t mac[6];
  32. ESP_LOGI(TAG, "1. Read MAC address");
  33. memset(mac, 0, sizeof(mac));
  34. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  35. TEST_ASSERT_EQUAL_INT(sizeof(mac) * 8, esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY));
  36. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  37. #ifdef CONFIG_IDF_TARGET_ESP32
  38. ESP_LOGI(TAG, "2. Check CRC by MAC");
  39. uint8_t crc;
  40. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY_CRC, &crc, 8));
  41. TEST_ASSERT_EQUAL_HEX8(crc, esp_rom_efuse_mac_address_crc8(mac, sizeof(mac)));
  42. #endif // CONFIG_IDF_TARGET_ESP32
  43. ESP_LOGI(TAG, "3. Test check args");
  44. uint32_t test_var;
  45. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, NULL, 1));
  46. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &test_var, 0));
  47. uint8_t half_byte;
  48. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &half_byte, 4));
  49. TEST_ASSERT_EQUAL_HEX8(mac[0]&0x0F, half_byte);
  50. uint8_t buff[7] = {0x59};
  51. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &buff, sizeof(buff) * 8));
  52. TEST_ASSERT_TRUE_MESSAGE(memcmp(mac, buff, sizeof(mac)) == 0, "Operation read blob is not success");
  53. TEST_ASSERT_EQUAL_HEX8(0, buff[6]);
  54. }
  55. TEST_CASE("efuse test read_field_blob", "[efuse]")
  56. {
  57. test_read_blob();
  58. }
  59. static void test_read_cnt(void)
  60. {
  61. esp_efuse_utility_update_virt_blocks();
  62. esp_efuse_utility_debug_dump_blocks();
  63. ESP_LOGI(TAG, "1. Test check args");
  64. size_t cnt;
  65. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, NULL));
  66. ESP_LOGI(TAG, "2. Read MAC address");
  67. uint8_t mac[6];
  68. memset(mac, 0, sizeof(mac));
  69. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, 48));
  70. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, &cnt));
  71. size_t cnt_summ = 0;
  72. for (int i = 0; i < sizeof(mac); ++i) {
  73. cnt_summ += __builtin_popcount(mac[i]);
  74. }
  75. TEST_ASSERT_EQUAL_INT(cnt_summ, cnt);
  76. }
  77. TEST_CASE("efuse test read_field_cnt", "[efuse]")
  78. {
  79. test_read_cnt();
  80. }
  81. // If using efuse is real, then turn off writing tests.
  82. #ifdef CONFIG_EFUSE_VIRTUAL
  83. static void test_write_blob(void)
  84. {
  85. esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
  86. esp_efuse_utility_erase_virt_blocks();
  87. esp_efuse_utility_debug_dump_blocks();
  88. ESP_LOGI(TAG, "1. Test check args");
  89. uint16_t test1_len_8 = 0x5FAA;
  90. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &test1_len_8, 0));
  91. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, NULL, 8));
  92. TEST_ASSERT_EQUAL_HEX16(0x5FAA, test1_len_8);
  93. ESP_LOGI(TAG, "2. Test write operation");
  94. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 7));
  95. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 9));
  96. uint16_t val_read1 = 0;
  97. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 8));
  98. TEST_ASSERT_EQUAL_HEX16(test1_len_8&((1 << 7) - 1), val_read1);
  99. uint16_t test1_len_8_hi = test1_len_8 & ~((1 << 7) - 1);
  100. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  101. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  102. } else {
  103. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  104. }
  105. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 8));
  106. val_read1 = 0;
  107. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 16));
  108. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  109. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x00FF, val_read1);
  110. } else {
  111. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x007F, val_read1);
  112. }
  113. if (scheme != EFUSE_CODING_SCHEME_NONE) {
  114. esp_efuse_utility_erase_virt_blocks();
  115. ESP_LOGI(TAG, "erase virt blocks");
  116. }
  117. uint16_t test2_len_16 = 0xAA55;
  118. uint32_t val_32 = test2_len_16;
  119. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &val_32, 17));
  120. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  121. uint16_t test_16 = 0;
  122. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test_16, 16));
  123. TEST_ASSERT_EQUAL_HEX16(test2_len_16, test_16);
  124. ESP_LOGI(TAG, "3. Test field with one bit");
  125. uint8_t test5_len_1;
  126. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  127. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  128. test5_len_1 = 0;
  129. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  130. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  131. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  132. test5_len_1 = 1;
  133. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  134. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  135. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  136. test5_len_1 = 1;
  137. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  138. esp_efuse_utility_debug_dump_blocks();
  139. }
  140. TEST_CASE("efuse test write_field_blob", "[efuse]")
  141. {
  142. test_write_blob();
  143. }
  144. static void test_write_cnt(void)
  145. {
  146. esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
  147. esp_efuse_utility_erase_virt_blocks();
  148. esp_efuse_utility_debug_dump_blocks();
  149. ESP_LOGI(TAG, "1. Test check args");
  150. size_t test3_len_6 = 5;
  151. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_MAC_FACTORY, 0));
  152. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(NULL, 5));
  153. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 0));
  154. ESP_LOGI(TAG, "2. Test write operation");
  155. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  156. TEST_ASSERT_EQUAL_INT(0, test3_len_6);
  157. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  158. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  159. TEST_ASSERT_EQUAL_INT(1, test3_len_6);
  160. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  161. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  162. } else {
  163. esp_efuse_utility_erase_virt_blocks();
  164. ESP_LOGI(TAG, "erase virt blocks");
  165. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 2));
  166. }
  167. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  168. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  169. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  170. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 3));
  171. } else {
  172. esp_efuse_utility_erase_virt_blocks();
  173. ESP_LOGI(TAG, "erase virt blocks");
  174. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 5));
  175. }
  176. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  177. TEST_ASSERT_EQUAL_INT(5, test3_len_6);
  178. esp_efuse_utility_debug_dump_blocks();
  179. ESP_LOGI(TAG, "3. Test field is full set");
  180. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_TEST4_LEN_182);
  181. size_t test4_len_182;
  182. esp_efuse_utility_debug_dump_blocks();
  183. for (int i = 0; i < max_bits / 26; ++i) {
  184. ESP_LOGD(TAG, "# %d", i);
  185. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  186. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 26));
  187. } else {
  188. esp_efuse_utility_erase_virt_blocks();
  189. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, (i + 1) * 26));
  190. }
  191. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST4_LEN_182, &test4_len_182));
  192. esp_efuse_utility_debug_dump_blocks();
  193. TEST_ASSERT_EQUAL_INT((i + 1) * 26, test4_len_182);
  194. }
  195. esp_efuse_utility_debug_dump_blocks();
  196. ESP_LOGI(TAG, "4. Test field ESP_EFUSE_TEST4_LEN_182 is full");
  197. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 1));
  198. ESP_LOGI(TAG, "3. Test field with one bit");
  199. size_t test5_len_1;
  200. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  201. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  202. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  203. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  204. if (scheme != EFUSE_CODING_SCHEME_NONE) {
  205. esp_efuse_utility_erase_virt_blocks();
  206. ESP_LOGI(TAG, "erase virt blocks");
  207. }
  208. test5_len_1 = 1;
  209. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  210. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  211. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  212. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  213. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  214. test5_len_1 = 1;
  215. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  216. esp_efuse_utility_debug_dump_blocks();
  217. ESP_LOGI(TAG, "4. Test field test2_len_16");
  218. size_t test2_len_16 = 11;
  219. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST2_LEN_16, test2_len_16));
  220. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST2_LEN_16, &test2_len_16));
  221. TEST_ASSERT_EQUAL_HEX16(11, test2_len_16);
  222. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  223. TEST_ASSERT_EQUAL_HEX16(0x07FF, test2_len_16);
  224. esp_efuse_utility_debug_dump_blocks();
  225. }
  226. TEST_CASE("efuse test write_field_cnt", "[efuse]")
  227. {
  228. test_write_cnt();
  229. }
  230. TEST_CASE("efuse test single bit functions", "[efuse]")
  231. {
  232. esp_efuse_utility_erase_virt_blocks();
  233. esp_efuse_utility_debug_dump_blocks();
  234. uint8_t test_bit;
  235. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
  236. TEST_ASSERT_EQUAL_HEX8(0, test_bit);
  237. test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
  238. TEST_ASSERT_EQUAL_HEX8(0, test_bit);
  239. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
  240. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
  241. TEST_ASSERT_EQUAL_HEX8(1, test_bit);
  242. test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
  243. TEST_ASSERT_EQUAL_HEX8(1, test_bit);
  244. // Can write the bit again and it's a no-op
  245. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
  246. TEST_ASSERT_EQUAL_HEX8(1, esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1));
  247. esp_efuse_utility_debug_dump_blocks();
  248. }
  249. void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
  250. {
  251. if ((num_used_bits + count_bits) % 8) {
  252. int start_used_item = (num_used_bits - 1) / 8;
  253. int last_used_item = ((num_used_bits + count_bits) - 1) / 8;
  254. int shift = 0;
  255. int mask = num_used_bits + count_bits;
  256. if (last_used_item == start_used_item) {
  257. shift = (num_used_bits) % 8;
  258. mask = count_bits;
  259. }
  260. arr[last_used_item] &= ((1 << (mask % 8)) - 1) << shift;
  261. }
  262. }
  263. void cut_start_arr(uint8_t *arr, size_t num_used_bits)
  264. {
  265. if (num_used_bits % 8) {
  266. int start_used_item = (num_used_bits - 1) / 8;
  267. arr[start_used_item] &= ~((1 << (num_used_bits % 8)) - 1);
  268. }
  269. }
  270. void get_part_arr(uint8_t *arr_in, uint8_t *arr_out, int num_used_bits, int count_bits)
  271. {
  272. int num_items = esp_efuse_utility_get_number_of_items(num_used_bits + count_bits, 8);
  273. memcpy(arr_out, arr_in, num_items);
  274. memset(arr_out, 0, num_used_bits / 8);
  275. cut_start_arr(arr_out, num_used_bits);
  276. cut_tail_arr(arr_out, num_used_bits, count_bits);
  277. }
  278. void fill_part_arr(uint8_t *arr_in, uint8_t *arr_out, int count_bits)
  279. {
  280. int num_items = esp_efuse_utility_get_number_of_items(count_bits, 8);
  281. memcpy(arr_out, arr_in, num_items);
  282. cut_tail_arr(arr_out, 0, count_bits);
  283. }
  284. // Writes a random array to efuse, then reads and compares it.
  285. 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)
  286. {
  287. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  288. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_w, field_size));
  289. memset(arr_r, 0, arr_size);
  290. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  291. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  292. esp_efuse_utility_debug_dump_blocks();
  293. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_w, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  294. int count_once = 0;
  295. for (int i = 0; i < arr_size; ++i) {
  296. count_once += __builtin_popcount(arr_w[i]);
  297. }
  298. size_t num_bits_r = 0;
  299. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  300. TEST_ASSERT_EQUAL_INT(count_once, num_bits_r);
  301. size_t num_bits_w = field_size - count_once;
  302. if (num_bits_w == 0) {
  303. esp_efuse_utility_erase_virt_blocks();
  304. num_bits_w = field_size;
  305. }
  306. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  307. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  308. esp_efuse_utility_debug_dump_blocks();
  309. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  310. memset(arr_r, 0, arr_size);
  311. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  312. memset(arr_temp, 0xFF, arr_size);
  313. cut_tail_arr(arr_temp, 0, field_size);
  314. esp_efuse_utility_debug_dump_blocks();
  315. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  316. }
  317. // Records a random number of bits (as "1") in the efuse field, then reads and compares.
  318. void test_cnt_part(const esp_efuse_desc_t* field[], uint8_t *arr_r, int arr_size, size_t field_size)
  319. {
  320. size_t num_bits_r = 0;
  321. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  322. TEST_ASSERT_EQUAL_INT(0, num_bits_r);
  323. TEST_ESP_OK(esp_efuse_write_field_cnt(field, field_size));
  324. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  325. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  326. esp_efuse_utility_erase_virt_blocks();
  327. int num_bits_summ_r = 0;
  328. int num_bits_w = 0;
  329. while(field_size > num_bits_summ_r) {
  330. num_bits_w = 0;
  331. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  332. bootloader_random_enable();
  333. bootloader_fill_random(&num_bits_w, 1);
  334. bootloader_random_disable();
  335. num_bits_w = num_bits_w * field_size / 255;
  336. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  337. break;
  338. }
  339. }
  340. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  341. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  342. num_bits_summ_r += num_bits_w;
  343. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, num_bits_r);
  344. memset(arr_r, 0, arr_size);
  345. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  346. int count_once = 0;
  347. for (int i = 0; i < arr_size; ++i) {
  348. count_once += __builtin_popcount(arr_r[i]);
  349. }
  350. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, count_once);
  351. ESP_LOGI(TAG, "Once bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  352. }
  353. esp_efuse_utility_debug_dump_blocks();
  354. }
  355. // 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.
  356. 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)
  357. {
  358. esp_efuse_utility_debug_dump_blocks();
  359. int num_bits_summ_r = 0;
  360. int num_bits_w = 0;
  361. memset(arr_w, 0, arr_size);
  362. bootloader_random_enable();
  363. bootloader_fill_random(arr_w, arr_size);
  364. bootloader_random_disable();
  365. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  366. while(field_size > num_bits_summ_r) {
  367. num_bits_w = 0;
  368. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  369. bootloader_random_enable();
  370. bootloader_fill_random(&num_bits_w, 1);
  371. bootloader_random_disable();
  372. num_bits_w = num_bits_w * field_size / 255;
  373. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  374. break;
  375. }
  376. }
  377. ESP_LOGI(TAG, "Summ bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  378. memset(arr_temp, 0, arr_size);
  379. get_part_arr(arr_w, arr_temp, num_bits_summ_r, num_bits_w);
  380. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  381. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_temp, field_size));
  382. memset(arr_r, 0, arr_size);
  383. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  384. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  385. esp_efuse_utility_debug_dump_blocks();
  386. num_bits_summ_r += num_bits_w;
  387. memset(arr_temp, 0, arr_size);
  388. fill_part_arr(arr_w, arr_temp, num_bits_summ_r);
  389. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  390. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  391. }
  392. }
  393. void check_efuse_table_test(int cycle)
  394. {
  395. int num_test = 0;
  396. while(1) {
  397. const esp_efuse_desc_t** field;
  398. switch (num_test++) {
  399. case 0: field = ESP_EFUSE_TEST1_LEN_8; break;
  400. case 1: field = ESP_EFUSE_TEST2_LEN_16; break;
  401. case 2: field = ESP_EFUSE_TEST3_LEN_6; break;
  402. case 3: field = ESP_EFUSE_TEST4_LEN_182; break;
  403. case 4: field = ESP_EFUSE_TEST5_LEN_1; break;
  404. case 5: field = ESP_EFUSE_TEST6_LEN_17; break;
  405. default:
  406. return;
  407. break;
  408. }
  409. size_t field_size = esp_efuse_get_field_size(field);
  410. int arr_size = esp_efuse_utility_get_number_of_items(field_size, 8);
  411. uint8_t *arr_w = (uint8_t *) malloc(arr_size);
  412. uint8_t *arr_r = (uint8_t *) malloc(arr_size);
  413. uint8_t *arr_temp = (uint8_t *) malloc(arr_size);
  414. ESP_LOGI(TAG, "Test#%d", num_test);
  415. for (int c = 1; c <= cycle; ++c) {
  416. ESP_LOGI(TAG, "Cycle#%d/%d", c, cycle);
  417. memset(arr_w, 0, arr_size);
  418. bootloader_random_enable();
  419. bootloader_fill_random(arr_w, arr_size);
  420. bootloader_random_disable();
  421. cut_tail_arr(arr_w, 0, field_size);
  422. esp_efuse_utility_erase_virt_blocks();
  423. ESP_LOGI(TAG, "1) blob write/read");
  424. test_blob(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  425. esp_efuse_utility_erase_virt_blocks();
  426. ESP_LOGI(TAG, "2) cnt part write/read");
  427. test_cnt_part(field, arr_r, arr_size, field_size);
  428. esp_efuse_utility_erase_virt_blocks();
  429. ESP_LOGI(TAG, "3) blob part write/read");
  430. test_blob_part(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  431. }
  432. free(arr_temp);
  433. free(arr_r);
  434. free(arr_w);
  435. }
  436. }
  437. TEST_CASE("efuse esp_efuse_table_test", "[efuse]")
  438. {
  439. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  440. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  441. check_efuse_table_test(2);
  442. } else {
  443. ESP_LOGI(TAG, "This test is applicable only to the EFUSE_CODING_SCHEME_NONE. Skip this test.");
  444. }
  445. }
  446. TEST_CASE("Test esp_efuse_read_block esp_efuse_write_block functions", "[efuse]")
  447. {
  448. int count_useful_reg = 0;
  449. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  450. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  451. printf("EFUSE_CODING_SCHEME_NONE\n");
  452. count_useful_reg = 8;
  453. }
  454. #if CONFIG_IDF_TARGET_ESP32
  455. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  456. printf("EFUSE_CODING_SCHEME_3_4\n");
  457. count_useful_reg = 6;
  458. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  459. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  460. count_useful_reg = 4;
  461. }
  462. #else
  463. if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  464. printf("EFUSE_CODING_SCHEME_RS\n");
  465. count_useful_reg = 8;
  466. }
  467. #endif
  468. esp_efuse_utility_reset();
  469. esp_efuse_utility_erase_virt_blocks();
  470. uint8_t src_key[32] = { 0 };
  471. uint8_t dst_key[32] = { 0 };
  472. int offset_in_bits = 0;
  473. for (int i = 0; i < count_useful_reg * 4; ++i) {
  474. src_key[i] = 0xAB + i;
  475. }
  476. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32));
  477. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32));
  478. esp_efuse_utility_debug_dump_blocks();
  479. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, sizeof(src_key));
  480. esp_efuse_utility_erase_virt_blocks();
  481. memset(src_key, 0, sizeof(src_key));
  482. memset(dst_key, 0, sizeof(dst_key));
  483. offset_in_bits = count_useful_reg * 32 / 2;
  484. for (int i = 0; i < count_useful_reg * 4 / 2; ++i) {
  485. src_key[i] = 0xCD + i;
  486. }
  487. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32 / 2));
  488. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32 / 2));
  489. esp_efuse_utility_debug_dump_blocks();
  490. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, count_useful_reg * 4 / 2);
  491. esp_efuse_utility_erase_virt_blocks();
  492. }
  493. TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
  494. {
  495. esp_efuse_utility_update_virt_blocks();
  496. esp_efuse_utility_debug_dump_blocks();
  497. int count_useful_reg = 0;
  498. uint8_t r_buff[32];
  499. int st_offset = -1;
  500. int num_block;
  501. for (num_block = EFUSE_BLK1; num_block < 4; ++num_block) {
  502. memset(r_buff, 0, sizeof(r_buff));
  503. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(num_block);
  504. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  505. printf("EFUSE_CODING_SCHEME_NONE. The test is not applicable.\n");
  506. count_useful_reg = 8;
  507. return;
  508. }
  509. #if CONFIG_IDF_TARGET_ESP32
  510. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  511. printf("EFUSE_CODING_SCHEME_3_4\n");
  512. count_useful_reg = 6;
  513. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  514. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  515. count_useful_reg = 4;
  516. }
  517. #else
  518. if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  519. printf("EFUSE_CODING_SCHEME_RS\n");
  520. if (num_block == EFUSE_BLK1) {
  521. count_useful_reg = 6;
  522. } else {
  523. count_useful_reg = 8;
  524. }
  525. }
  526. #endif
  527. TEST_ESP_OK(esp_efuse_read_block(num_block, r_buff, 0, count_useful_reg * 32));
  528. for (int i = 0; i < count_useful_reg * 4; ++i) {
  529. if (r_buff[i] != 0) {
  530. // found used byte
  531. for (int j = 0; j < 8; ++j) {
  532. if ((r_buff[i] & (1 << j)) == 0) {
  533. // found empty bit into this byte
  534. st_offset = i * 8 + j;
  535. printf("Byte = 0x%02x. offset is = %d\n", r_buff[i], st_offset);
  536. break;
  537. }
  538. }
  539. if (st_offset != -1) {
  540. break;
  541. }
  542. }
  543. }
  544. if (st_offset != -1) {
  545. break;
  546. }
  547. }
  548. if (st_offset != -1) {
  549. // write 1 bit to empty place.
  550. uint8_t val = 1;
  551. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_block(num_block, &val, st_offset, 1));
  552. } else {
  553. printf("Test skipped. It is not applicable, the device has no written bits.");
  554. }
  555. }
  556. #ifndef CONFIG_FREERTOS_UNICORE
  557. static const int delay_ms = 2000;
  558. static xSemaphoreHandle sema;
  559. static void task1(void* arg)
  560. {
  561. TEST_ESP_OK(esp_efuse_batch_write_begin());
  562. ESP_LOGI(TAG, "Start work in batch mode");
  563. xSemaphoreGive(sema);
  564. vTaskDelay((delay_ms + 100) / portTICK_PERIOD_MS);
  565. ESP_LOGI(TAG, "Finish work in batch mode");
  566. TEST_ESP_OK(esp_efuse_batch_write_cancel());
  567. vTaskDelete(NULL);
  568. }
  569. static void task2(void* arg)
  570. {
  571. xSemaphoreTake(sema, portMAX_DELAY);
  572. uint8_t mac[6];
  573. int64_t t1 = esp_timer_get_time();
  574. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  575. int64_t t2 = esp_timer_get_time();
  576. int diff_ms = (t2 - t1) / 1000;
  577. TEST_ASSERT_GREATER_THAN(diff_ms, delay_ms);
  578. ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  579. xSemaphoreGive(sema);
  580. vTaskDelete(NULL);
  581. }
  582. static void task3(void* arg)
  583. {
  584. xSemaphoreTake(sema, portMAX_DELAY);
  585. size_t test3_len_6 = 2;
  586. int64_t t1 = esp_timer_get_time();
  587. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
  588. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  589. int64_t t2 = esp_timer_get_time();
  590. ESP_LOGI(TAG, "write&read test3_len_6: %d", test3_len_6);
  591. int diff_ms = (t2 - t1) / 1000;
  592. TEST_ASSERT_GREATER_THAN(delay_ms, diff_ms);
  593. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  594. xSemaphoreGive(sema);
  595. vTaskDelete(NULL);
  596. }
  597. TEST_CASE("Batch mode is thread-safe", "[efuse]")
  598. {
  599. // Batch mode blocks work with efuse on other tasks.
  600. esp_efuse_utility_update_virt_blocks();
  601. esp_efuse_utility_debug_dump_blocks();
  602. sema = xSemaphoreCreateBinary();
  603. printf("\n");
  604. xTaskCreatePinnedToCore(task1, "task1", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
  605. xTaskCreatePinnedToCore(task2, "task2", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  606. vTaskDelay(3000 / portTICK_PERIOD_MS);
  607. xSemaphoreTake(sema, portMAX_DELAY);
  608. esp_efuse_utility_reset();
  609. esp_efuse_utility_erase_virt_blocks();
  610. printf("\n");
  611. xTaskCreatePinnedToCore(task1, "task1", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
  612. xTaskCreatePinnedToCore(task3, "task3", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  613. vTaskDelay(3000 / portTICK_PERIOD_MS);
  614. xSemaphoreTake(sema, portMAX_DELAY);
  615. printf("\n");
  616. vSemaphoreDelete(sema);
  617. esp_efuse_utility_reset();
  618. esp_efuse_utility_erase_virt_blocks();
  619. }
  620. #endif // #ifndef CONFIG_FREERTOS_UNICORE
  621. static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
  622. {
  623. size_t out_cnt;
  624. TEST_ESP_OK(esp_efuse_set_write_protect(blk));
  625. esp_efuse_read_field_cnt(field, &out_cnt);
  626. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  627. }
  628. static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
  629. {
  630. size_t out_cnt;
  631. if (read_first) {
  632. esp_efuse_read_field_cnt(field, &out_cnt);
  633. TEST_ASSERT_EQUAL_INT(0, out_cnt);
  634. }
  635. TEST_ESP_OK(esp_efuse_set_read_protect(blk));
  636. esp_efuse_read_field_cnt(field, &out_cnt);
  637. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  638. if (read_first) {
  639. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
  640. }
  641. }
  642. TEST_CASE("Test a write/read protection", "[efuse]")
  643. {
  644. esp_efuse_utility_reset();
  645. esp_efuse_utility_erase_virt_blocks();
  646. esp_efuse_utility_debug_dump_blocks();
  647. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
  648. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
  649. size_t out_cnt;
  650. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
  651. TEST_ASSERT_EQUAL_INT(0, out_cnt);
  652. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
  653. esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
  654. TEST_ASSERT_EQUAL_INT(1, out_cnt);
  655. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
  656. #ifdef CONFIG_IDF_TARGET_ESP32
  657. test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_BLK2);
  658. test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_BLK3);
  659. esp_efuse_utility_debug_dump_blocks();
  660. test_rp(EFUSE_BLK1, ESP_EFUSE_RD_DIS_BLK1, true);
  661. test_rp(EFUSE_BLK2, ESP_EFUSE_RD_DIS_BLK2, false);
  662. test_rp(EFUSE_BLK3, ESP_EFUSE_RD_DIS_BLK3, false);
  663. #else
  664. test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_SYS_DATA_PART1);
  665. test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_USER_DATA);
  666. esp_efuse_utility_debug_dump_blocks();
  667. test_rp(EFUSE_BLK4, ESP_EFUSE_RD_DIS_KEY0, true);
  668. test_rp(EFUSE_BLK5, ESP_EFUSE_RD_DIS_KEY1, false);
  669. test_rp(EFUSE_BLK6, ESP_EFUSE_RD_DIS_KEY2, false);
  670. #endif
  671. esp_efuse_utility_debug_dump_blocks();
  672. esp_efuse_utility_reset();
  673. esp_efuse_utility_erase_virt_blocks();
  674. }
  675. static volatile bool cmd_stop_reset_task1;
  676. static void efuse_burn_task(void* arg)
  677. {
  678. SemaphoreHandle_t sema = (SemaphoreHandle_t) arg;
  679. ESP_LOGI(TAG, "Start burn task");
  680. size_t test3_len_6 = 2;
  681. while (!cmd_stop_reset_task1) {
  682. esp_efuse_utility_update_virt_blocks();
  683. esp_efuse_utility_reset();
  684. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
  685. }
  686. xSemaphoreGive(sema);
  687. ESP_LOGI(TAG, "Stop burn task");
  688. vTaskDelete(NULL);
  689. }
  690. static void efuse_read_task(void* arg)
  691. {
  692. SemaphoreHandle_t sema = (SemaphoreHandle_t) arg;
  693. ESP_LOGI(TAG, "Start read task");
  694. size_t test3_len_6 = 0;
  695. while (!cmd_stop_reset_task1) {
  696. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST3_LEN_6, &test3_len_6, 6));
  697. }
  698. xSemaphoreGive(sema);
  699. ESP_LOGI(TAG, "Stop read task");
  700. vTaskDelete(NULL);
  701. }
  702. TEST_CASE("Check a case when ESP_ERR_DAMAGED_READING occurs and read and burn are not blocked", "[efuse]")
  703. {
  704. cmd_stop_reset_task1 = false;
  705. TaskHandle_t read_task_hdl;
  706. xSemaphoreHandle sema[2];
  707. sema[0] = xSemaphoreCreateBinary();
  708. sema[1] = xSemaphoreCreateBinary();
  709. esp_efuse_utility_update_virt_blocks();
  710. esp_efuse_utility_debug_dump_blocks();
  711. xTaskCreatePinnedToCore(efuse_burn_task, "efuse_burn_task", 3072, sema[0], 2, NULL, 0);
  712. xTaskCreatePinnedToCore(efuse_read_task, "efuse_read_task", 3072, sema[1], 2, &read_task_hdl, 0);
  713. vTaskDelay(10 / portTICK_PERIOD_MS);
  714. for (unsigned i = 1; i < 30; ++i) {
  715. vTaskPrioritySet(read_task_hdl, 2 + i % 2);
  716. vTaskDelay(10 / portTICK_PERIOD_MS);
  717. }
  718. vTaskDelay(10 / portTICK_PERIOD_MS);
  719. cmd_stop_reset_task1 = true;
  720. vTaskDelay(10 / portTICK_PERIOD_MS);
  721. TEST_ASSERT_EQUAL(pdPASS, xSemaphoreTake(sema[0], 1000 / portTICK_PERIOD_MS));
  722. TEST_ASSERT_EQUAL(pdPASS, xSemaphoreTake(sema[1], 1000 / portTICK_PERIOD_MS));
  723. vSemaphoreDelete(sema[0]);
  724. vSemaphoreDelete(sema[1]);
  725. }
  726. #endif // #ifdef CONFIG_EFUSE_VIRTUAL
  727. #ifndef CONFIG_FREERTOS_UNICORE
  728. static volatile bool cmd_stop_reset_task;
  729. static void reset_task(void* arg)
  730. {
  731. ESP_LOGI(TAG, "Start reset task");
  732. while (!cmd_stop_reset_task) {
  733. esp_efuse_utility_reset();
  734. vTaskDelay(2);
  735. }
  736. vTaskDelete(NULL);
  737. }
  738. TEST_CASE("Check a case when ESP_ERR_DAMAGED_READING occurs during reading efuses", "[efuse]")
  739. {
  740. cmd_stop_reset_task = false;
  741. esp_efuse_utility_update_virt_blocks();
  742. esp_efuse_utility_debug_dump_blocks();
  743. uint8_t mac[6];
  744. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  745. ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  746. xTaskCreatePinnedToCore(reset_task, "reset_task", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  747. uint8_t new_mac[6];
  748. for (int i = 0; i < 1000; ++i) {
  749. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
  750. TEST_ASSERT_EQUAL_HEX8_ARRAY(mac, new_mac, sizeof(mac));
  751. }
  752. cmd_stop_reset_task = true;
  753. ESP_LOGI(TAG, "read new MAC address: %02x:%02x:%02x:%02x:%02x:%02x", new_mac[0], new_mac[1], new_mac[2], new_mac[3], new_mac[4], new_mac[5]);
  754. vTaskDelay(100 / portTICK_PERIOD_MS);
  755. }
  756. #endif // if not CONFIG_FREERTOS_UNICORE
  757. #ifdef CONFIG_IDF_ENV_FPGA
  758. TEST_CASE("Test a real write (FPGA)", "[efuse]")
  759. {
  760. ESP_LOGI(TAG, "1. Write MAC address");
  761. esp_efuse_utility_debug_dump_blocks();
  762. uint8_t mac[6];
  763. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  764. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  765. uint8_t new_mac[6];
  766. if (mac[0] == 0) {
  767. new_mac[0] = 0x71;
  768. new_mac[1] = 0x62;
  769. new_mac[2] = 0x53;
  770. new_mac[3] = 0x44;
  771. new_mac[4] = 0x35;
  772. new_mac[5] = 0x26;
  773. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
  774. 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]);
  775. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  776. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_mac, mac, sizeof(new_mac));
  777. esp_efuse_utility_debug_dump_blocks();
  778. }
  779. #ifndef CONFIG_IDF_TARGET_ESP32
  780. ESP_LOGI(TAG, "2. Write KEY3");
  781. uint8_t key[32] = {0};
  782. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
  783. for (int i = 0; i < sizeof(key); ++i) {
  784. TEST_ASSERT_EQUAL_INT(0, key[i]);
  785. }
  786. uint8_t new_key[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  787. 10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
  788. 20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
  789. 30, 31};
  790. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY3, &new_key, 256));
  791. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
  792. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
  793. esp_efuse_utility_debug_dump_blocks();
  794. ESP_LOGI(TAG, "3. Set a read protection for KEY3");
  795. TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK7));
  796. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
  797. #ifndef CONFIG_EFUSE_VIRTUAL
  798. TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
  799. #else
  800. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
  801. #endif // CONFIG_EFUSE_VIRTUAL
  802. esp_efuse_utility_debug_dump_blocks();
  803. #endif // not CONFIG_IDF_TARGET_ESP32
  804. ESP_LOGI(TAG, "4. Write SECURE_VERSION");
  805. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
  806. size_t read_sec_version;
  807. esp_efuse_utility_debug_dump_blocks();
  808. for (int i = 0; i < max_bits; ++i) {
  809. ESP_LOGI(TAG, "# %d", i);
  810. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_SECURE_VERSION, 1));
  811. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_SECURE_VERSION, &read_sec_version));
  812. esp_efuse_utility_debug_dump_blocks();
  813. TEST_ASSERT_EQUAL_INT(i + 1, read_sec_version);
  814. }
  815. }
  816. #endif // CONFIG_IDF_ENV_FPGA
  817. TEST_CASE("Test chip_ver_pkg APIs return the same value", "[efuse]")
  818. {
  819. esp_efuse_utility_update_virt_blocks();
  820. TEST_ASSERT_EQUAL_INT(esp_efuse_get_pkg_ver(), bootloader_common_get_chip_ver_pkg());
  821. }
  822. TEST_CASE("Test chip_revision APIs return the same value", "[efuse]")
  823. {
  824. esp_efuse_utility_update_virt_blocks();
  825. TEST_ASSERT_EQUAL_INT(esp_efuse_get_chip_ver(), bootloader_common_get_chip_revision());
  826. }
  827. #ifndef CONFIG_IDF_TARGET_ESP32
  828. #if CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
  829. TEST_CASE("Test writing order is BLK_MAX->BLK0", "[efuse]")
  830. {
  831. uint8_t new_key[32] = {33, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  832. 10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
  833. 20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
  834. 30, 31};
  835. esp_efuse_utility_erase_virt_blocks();
  836. esp_efuse_utility_debug_dump_blocks();
  837. TEST_ESP_OK(esp_efuse_batch_write_begin());
  838. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY4, &new_key, 256));
  839. // If the order of writing blocks is wrong (ex. BLK0 -> BLK_MAX)
  840. // then the write protection bit will be set early and the key was left un-updated.
  841. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY4));
  842. TEST_ESP_OK(esp_efuse_batch_write_commit());
  843. esp_efuse_utility_debug_dump_blocks();
  844. uint8_t key[32] = { 0xEE };
  845. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY4, &key, 256));
  846. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
  847. }
  848. TEST_CASE("Test reading inside of batch mode in a nested way", "[efuse]")
  849. {
  850. uint8_t new_key[32] = {44, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  851. 10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
  852. 20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
  853. 30, 31};
  854. uint8_t key[32] = { 0xEE };
  855. esp_efuse_utility_reset();
  856. esp_efuse_utility_erase_virt_blocks();
  857. esp_efuse_utility_debug_dump_blocks();
  858. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
  859. TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
  860. TEST_ESP_OK(esp_efuse_batch_write_begin());
  861. TEST_ESP_OK(esp_efuse_batch_write_begin());
  862. TEST_ESP_OK(esp_efuse_batch_write_begin());
  863. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY5, &new_key, 256));
  864. TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY5));
  865. ESP_LOGI(TAG, "Reading inside Batch mode, the key was not burn yet and it is empty");
  866. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
  867. TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
  868. TEST_ESP_OK(esp_efuse_batch_write_commit());
  869. TEST_ESP_OK(esp_efuse_batch_write_commit());
  870. TEST_ESP_OK(esp_efuse_batch_write_commit());
  871. TEST_ESP_OK(esp_efuse_batch_write_begin());
  872. TEST_ESP_OK(esp_efuse_batch_write_begin());
  873. TEST_ESP_OK(esp_efuse_batch_write_begin());
  874. TEST_ESP_OK(esp_efuse_batch_write_begin());
  875. ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
  876. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
  877. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
  878. TEST_ESP_OK(esp_efuse_batch_write_commit());
  879. TEST_ESP_OK(esp_efuse_batch_write_commit());
  880. TEST_ESP_OK(esp_efuse_batch_write_commit());
  881. TEST_ESP_OK(esp_efuse_batch_write_commit());
  882. esp_efuse_utility_debug_dump_blocks();
  883. ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
  884. TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_commit());
  885. TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_cancel());
  886. TEST_ESP_OK(esp_efuse_batch_write_begin());
  887. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY2, &new_key, 256));
  888. TEST_ESP_OK(esp_efuse_batch_write_commit());
  889. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY2, &key, 256));
  890. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
  891. esp_efuse_utility_debug_dump_blocks();
  892. }
  893. #endif // CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
  894. #endif // not CONFIG_IDF_TARGET_ESP32