efuse: Migrate efuse unit tests from unit-test-app to component test app

This commit is contained in:
KonstantinKondrashov
2022-10-21 23:48:03 +08:00
parent db9caf4354
commit beba771031
26 changed files with 78 additions and 28 deletions

View File

@@ -0,0 +1,7 @@
#This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(efuse_test)

View File

@@ -0,0 +1,3 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |

View File

@@ -0,0 +1,18 @@
idf_build_get_property(target IDF_TARGET)
if(CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD)
set(dir "with_key_purposes")
else()
if(CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK)
set(dir "one_key_block")
else()
set(dir "three_key_blocks")
endif()
endif()
set(src_dirs "." "${dir}")
idf_component_register(SRC_DIRS "${src_dirs}"
PRIV_INCLUDE_DIRS "." "${dir}/include" "../../private_include" "../../${target}/private_include"
PRIV_REQUIRES cmock efuse bootloader_support esp_timer
WHOLE_ARCHIVE)

View File

@@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_efuse.h"
#include <assert.h>
#include "esp_efuse_test_table.h"
// md5_digest_table df1ecf346aec29cf593e2f81dc4cd5e4
// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
// To show efuse_table run the command 'show_efuse_table'.
#define MAX_BLK_LEN CONFIG_EFUSE_MAX_BLK_LEN
// The last free bit in the block is counted over the entire file.
#define LAST_FREE_BIT_BLK1 88
#define LAST_FREE_BIT_BLK2 167
#define LAST_FREE_BIT_BLK3 88
_Static_assert(LAST_FREE_BIT_BLK1 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
_Static_assert(LAST_FREE_BIT_BLK2 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
_Static_assert(LAST_FREE_BIT_BLK3 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
static const esp_efuse_desc_t TEST1_LEN_8[] = {
{EFUSE_BLK3, 0, 8}, // TEST field,
};
static const esp_efuse_desc_t TEST2_LEN_16[] = {
{EFUSE_BLK3, 10, 8}, // TEST field,
{EFUSE_BLK3, 80, 8}, // TEST field,
};
static const esp_efuse_desc_t TEST3_LEN_6[] = {
{EFUSE_BLK3, 22, 6}, // TEST field,
};
static const esp_efuse_desc_t TEST4_LEN_182[] = {
{EFUSE_BLK1, 22, 49}, // TEST field,
{EFUSE_BLK2, 128, 39}, // TEST field,
{EFUSE_BLK1, 71, 17}, // TEST field,
{EFUSE_BLK1, 19, 1}, // TEST field,
{EFUSE_BLK1, 0, 16}, // TEST field,
{EFUSE_BLK2, 0, 17}, // TEST field,
{EFUSE_BLK2, 60, 43}, // TEST field,
};
static const esp_efuse_desc_t TEST5_LEN_1[] = {
{EFUSE_BLK1, 16, 1}, // TEST field,
};
static const esp_efuse_desc_t TEST6_LEN_17[] = {
{EFUSE_BLK1, 17, 1}, // TEST field,
{EFUSE_BLK2, 17, 2}, // TEST field,
{EFUSE_BLK3, 29, 4}, // TEST field,
{EFUSE_BLK2, 31, 3}, // TEST field,
{EFUSE_BLK3, 60, 6}, // TEST field,
{EFUSE_BLK2, 127, 1}, // TEST field,
};
const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[] = {
&TEST1_LEN_8[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[] = {
&TEST2_LEN_16[0], // TEST field
&TEST2_LEN_16[1], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[] = {
&TEST3_LEN_6[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[] = {
&TEST4_LEN_182[0], // TEST field
&TEST4_LEN_182[1], // TEST field
&TEST4_LEN_182[2], // TEST field
&TEST4_LEN_182[3], // TEST field
&TEST4_LEN_182[4], // TEST field
&TEST4_LEN_182[5], // TEST field
&TEST4_LEN_182[6], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[] = {
&TEST5_LEN_1[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[] = {
&TEST6_LEN_17[0], // TEST field
&TEST6_LEN_17[1], // TEST field
&TEST6_LEN_17[2], // TEST field
&TEST6_LEN_17[3], // TEST field
&TEST6_LEN_17[4], // TEST field
&TEST6_LEN_17[5], // TEST field
NULL
};

View File

@@ -0,0 +1,34 @@
# field_name, | efuse_block, | bit_start, | bit_count, |comment #
# | (EFUSE_BLK0 | (0..255) | (1..256) | #
# | EFUSE_BLK1 | | | #
# | EFUSE_BLK2 | | | #
# | EFUSE_BLK3) | | | #
##########################################################################
# To generate a new source files. Run two commands:
# cd ~/esp/esp-idf/components/efuse/
# ./efuse_table_gen.py test/esp_efuse_test_table.csv
TEST1_LEN_8, EFUSE_BLK3, 0, 8, TEST field
TEST2_LEN_16, EFUSE_BLK3, 10, 8, TEST field
, EFUSE_BLK3, 80, 8, TEST field
TEST3_LEN_6, EFUSE_BLK3, 22, 6, TEST field
TEST4_LEN_182, EFUSE_BLK1, 22, 49, TEST field
, EFUSE_BLK2, 128, 39, TEST field
, EFUSE_BLK1, 71, 17, TEST field
, EFUSE_BLK1, 19, 1, TEST field
, EFUSE_BLK1, 0, 16, TEST field
, EFUSE_BLK2, 0, 17, TEST field
, EFUSE_BLK2, 60, 43, TEST field
TEST5_LEN_1, EFUSE_BLK1, 16, 1, TEST field
TEST6_LEN_17, EFUSE_BLK1, 17, 1, TEST field
, EFUSE_BLK2, 17, 2, TEST field
, EFUSE_BLK3, 29, 4, TEST field
, EFUSE_BLK2, 31, 3, TEST field
, EFUSE_BLK3, 60, 6, TEST field
, EFUSE_BLK2, 127, 1, TEST field
1 # field_name, | efuse_block, | bit_start, | bit_count, |comment #
2 # | (EFUSE_BLK0 | (0..255) | (1..256) | #
3 # | EFUSE_BLK1 | | | #
4 # | EFUSE_BLK2 | | | #
5 # | EFUSE_BLK3) | | | #
6 ##########################################################################
7 # To generate a new source files. Run two commands:
8 # cd ~/esp/esp-idf/components/efuse/
9 # ./efuse_table_gen.py test/esp_efuse_test_table.csv
10 TEST1_LEN_8, EFUSE_BLK3, 0, 8, TEST field
11 TEST2_LEN_16, EFUSE_BLK3, 10, 8, TEST field
12 , EFUSE_BLK3, 80, 8, TEST field
13 TEST3_LEN_6, EFUSE_BLK3, 22, 6, TEST field
14 TEST4_LEN_182, EFUSE_BLK1, 22, 49, TEST field
15 , EFUSE_BLK2, 128, 39, TEST field
16 , EFUSE_BLK1, 71, 17, TEST field
17 , EFUSE_BLK1, 19, 1, TEST field
18 , EFUSE_BLK1, 0, 16, TEST field
19 , EFUSE_BLK2, 0, 17, TEST field
20 , EFUSE_BLK2, 60, 43, TEST field
21 TEST5_LEN_1, EFUSE_BLK1, 16, 1, TEST field
22 TEST6_LEN_17, EFUSE_BLK1, 17, 1, TEST field
23 , EFUSE_BLK2, 17, 2, TEST field
24 , EFUSE_BLK3, 29, 4, TEST field
25 , EFUSE_BLK2, 31, 3, TEST field
26 , EFUSE_BLK3, 60, 6, TEST field
27 , EFUSE_BLK2, 127, 1, TEST field

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
// md5_digest_table df1ecf346aec29cf593e2f81dc4cd5e4
// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
// To show efuse_table run the command 'show_efuse_table'.
extern const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[];
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "unity.h"
#include "esp_log.h"
#include <string.h>
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_test_table.h"
#include "bootloader_random.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "sdkconfig.h"
#include "esp_rom_efuse.h"
#include "bootloader_common.h"
__attribute__((unused)) static const char* TAG = "efuse_test";
#ifdef CONFIG_EFUSE_VIRTUAL
TEST_CASE("Test a write protection", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
size_t out_cnt;
esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY0));
esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK_KEY0));
esp_efuse_utility_debug_dump_blocks();
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
TEST_CASE("Test a read protection", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
size_t out_cnt;
esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK_KEY0));
esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(2, out_cnt);
esp_efuse_utility_debug_dump_blocks();
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
TEST_CASE("Test a key read protection 1", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
size_t out_cnt;
esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
TEST_ESP_OK(esp_efuse_set_key_dis_read(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
esp_efuse_utility_debug_dump_blocks();
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
TEST_CASE("Test a key read protection 2", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
size_t out_cnt;
esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
TEST_ESP_OK(esp_efuse_set_key_dis_read(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0));
esp_efuse_read_field_cnt(ESP_EFUSE_RD_DIS, &out_cnt);
TEST_ASSERT_EQUAL_INT(2, out_cnt);
esp_efuse_utility_debug_dump_blocks();
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
#endif // CONFIG_EFUSE_VIRTUAL
#ifdef CONFIG_IDF_ENV_FPGA
TEST_CASE("Test a real write (FPGA)2", "[efuse]")
{
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "1. Write KEY3");
uint8_t key[32] = {0};
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, 256));
for (int i = 0; i < sizeof(key); ++i) {
TEST_ASSERT_EQUAL_INT(0, key[i]);
}
uint8_t new_key[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
30, 31};
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY0, &new_key, 256));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, 256));
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "2. Set a read protection for KEY0");
TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK_KEY0));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, 256));
#ifndef CONFIG_EFUSE_VIRTUAL
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
#else
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
#endif // CONFIG_EFUSE_VIRTUAL
esp_efuse_utility_debug_dump_blocks();
}
#endif // CONFIG_IDF_ENV_FPGA

View File

@@ -0,0 +1,291 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "esp_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_utility.h"
#include "sdkconfig.h"
__attribute__((unused)) static const char* TAG = "efuse_key_test";
#ifdef CONFIG_EFUSE_VIRTUAL
TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial state", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... \n", num_key - EFUSE_BLK_KEY0);
uint8_t key[32] = { 0xEE };
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, sizeof(key) * 8));
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_write(num_key));
TEST_ASSERT_EQUAL(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, esp_efuse_get_key_purpose(num_key));
esp_efuse_block_t key_block = EFUSE_BLK_MAX;
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, NULL));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... OK\n", num_key - EFUSE_BLK_KEY0);
}
}
#endif // CONFIG_EFUSE_VIRTUAL
// If using efuse is real, then turn off writing tests.
#if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key, esp_efuse_purpose_t purpose)
{
size_t offset_in_bits = 0;
uint8_t key_size = 32;
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS || purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
key_size = 16;
}
if (purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
offset_in_bits = 16 * 8;
}
uint8_t rd_key[32] = { 0xEE };
TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK_KEY0, &rd_key, offset_in_bits, key_size * 8));
#ifndef CONFIG_IDF_ENV_FPGA
TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, key_size);
#endif // not CONFIG_IDF_ENV_FPGA
TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(num_key));
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS) {
TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(num_key));
#if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
TEST_ASSERT_EACH_EQUAL_HEX8(0, rd_key, key_size);
#endif // CONFIG_IDF_ENV_FPGA && ! CONFIG_EFUSE_VIRTUAL
} else {
TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, key_size);
}
return ESP_OK;
}
void test_write_key(esp_efuse_block_t num_key, esp_efuse_purpose_t purpose) {
int id = num_key - EFUSE_BLK_KEY0;
printf("EFUSE_BLK_KEY%d, purpose=%d ... \n", id, purpose);
uint8_t wr_key[32];
for (int i = 0; i < sizeof(wr_key); i++) {
wr_key[i] = id + 1 + i;
}
uint8_t key_size = sizeof(wr_key);
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS || purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
key_size = 16;
}
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(num_key));
TEST_ESP_OK(esp_efuse_write_key(num_key, purpose, &wr_key, key_size));
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_key(num_key, purpose, &wr_key, key_size));
TEST_ESP_OK(s_check_key(num_key, wr_key, purpose));
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(num_key));
printf("EFUSE_BLK_KEY%d, purpose=%d ... OK\n", id, purpose);
}
#ifndef CONFIG_IDF_ENV_FPGA
TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]")
{
uint8_t rd_key[32] = { 0xEE };
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_USER, &rd_key, 33));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK3, ESP_EFUSE_KEY_PURPOSE_USER, NULL, sizeof(rd_key)));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_USER, &rd_key, sizeof(rd_key)));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, &rd_key, sizeof(rd_key)));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2, &rd_key, sizeof(rd_key)));
for (esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_USER; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) {
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
}
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
test_write_key(EFUSE_BLK_KEY0, purpose);
TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
esp_efuse_utility_debug_dump_blocks();
}
}
#endif // not CONFIG_IDF_ENV_FPGA
TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, NULL));
test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS);
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
#ifdef CONFIG_IDF_ENV_FPGA
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
#else
TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
#endif
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test 2 esp_efuse_write_key for FPGA", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, NULL));
test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2);
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test 3 esp_efuse_write_key for FPGA", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL));
test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY);
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
#ifdef CONFIG_IDF_ENV_FPGA
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
#else
TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
#endif
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test esp_efuse_write_keys", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, NULL));
esp_efuse_block_t key_block = EFUSE_BLK_MAX;
enum { BLOCKS_NEEDED1 = 2 };
esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
};
uint8_t keys1[BLOCKS_NEEDED1][32] = {{0xEE}};
for (int num_key = 0; num_key < BLOCKS_NEEDED1; ++num_key) {
for (int i = 0; i < 32; ++i) {
keys1[num_key][i] = purpose1[num_key] + i + 1;
}
}
TEST_ESP_OK(esp_efuse_write_keys(purpose1, keys1, BLOCKS_NEEDED1));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[0], &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
TEST_ESP_OK(s_check_key(EFUSE_BLK_KEY0, keys1[0], ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS));
TEST_ESP_OK(s_check_key(EFUSE_BLK_KEY0, keys1[1], ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
enum { BLOCKS_NEEDED2 = 1 };
esp_efuse_purpose_t purpose2[BLOCKS_NEEDED2] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
};
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_keys(purpose2, keys1, BLOCKS_NEEDED2));
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test esp_efuse_write_keys for returned errors", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
enum { BLOCKS_NEEDED = 2 };
esp_efuse_purpose_t purpose[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS,
ESP_EFUSE_KEY_PURPOSE_MAX, // it leads ESP_ERR_INVALID_ARG in esp_efuse_write_keys
};
uint8_t keys[BLOCKS_NEEDED][32];
for (int num_key = 0; num_key < BLOCKS_NEEDED; ++num_key) {
for (int i = 0; i < 32; ++i) {
keys[num_key][i] = purpose[num_key] + i + 1;
}
}
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(NULL, keys, BLOCKS_NEEDED));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, NULL, BLOCKS_NEEDED));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED)); // ESP_EFUSE_KEY_PURPOSE_MAX is not a valid purpose.
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, 3));
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
TEST_ESP_OK(esp_efuse_write_keys(purpose, keys, 1));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
#ifdef CONFIG_IDF_ENV_FPGA
TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
#else
TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
#endif
}
#endif // CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA

View File

@@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "unity.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void app_main(void)
{
vTaskPrioritySet(NULL, 5);
unity_run_menu();
}

View File

@@ -0,0 +1,868 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "unity.h"
#include "esp_log.h"
#include <string.h>
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_test_table.h"
#include "esp_timer.h"
#include "bootloader_random.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "sdkconfig.h"
#include "esp_rom_efuse.h"
#include "bootloader_common.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#define MAC_FACTORY_HAS_CRC 1
#endif
#define TASK_PRIORITY (5)
__attribute__((unused)) static const char* TAG = "efuse_test";
static void test_read_blob(void)
{
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
uint8_t mac[6];
ESP_LOGI(TAG, "1. Read MAC address");
memset(mac, 0, sizeof(mac));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
TEST_ASSERT_EQUAL_INT(sizeof(mac) * 8, esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY));
ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#ifdef MAC_FACTORY_HAS_CRC
ESP_LOGI(TAG, "2. Check CRC by MAC");
uint8_t crc;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY_CRC, &crc, 8));
TEST_ASSERT_EQUAL_HEX8(crc, esp_rom_efuse_mac_address_crc8(mac, sizeof(mac)));
#endif
ESP_LOGI(TAG, "3. Test check args");
uint32_t test_var;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, NULL, 1));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &test_var, 0));
uint8_t half_byte;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &half_byte, 4));
TEST_ASSERT_EQUAL_HEX8(mac[0]&0x0F, half_byte);
uint8_t buff[7] = {0x59};
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &buff, sizeof(buff) * 8));
TEST_ASSERT_TRUE_MESSAGE(memcmp(mac, buff, sizeof(mac)) == 0, "Operation read blob is not success");
TEST_ASSERT_EQUAL_HEX8(0, buff[6]);
}
TEST_CASE("efuse test read_field_blob", "[efuse]")
{
test_read_blob();
}
static void test_read_cnt(void)
{
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "1. Test check args");
size_t cnt;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, NULL));
ESP_LOGI(TAG, "2. Read MAC address");
uint8_t mac[6];
memset(mac, 0, sizeof(mac));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, 48));
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, &cnt));
size_t cnt_summ = 0;
for (int i = 0; i < sizeof(mac); ++i) {
cnt_summ += __builtin_popcount(mac[i]);
}
TEST_ASSERT_EQUAL_INT(cnt_summ, cnt);
}
TEST_CASE("efuse test read_field_cnt", "[efuse]")
{
test_read_cnt();
}
// If using efuse is real, then turn off writing tests.
#ifdef CONFIG_EFUSE_VIRTUAL
static void test_write_blob(void)
{
esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "1. Test check args");
uint16_t test1_len_8 = 0x5FAA;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &test1_len_8, 0));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, NULL, 8));
TEST_ASSERT_EQUAL_HEX16(0x5FAA, test1_len_8);
ESP_LOGI(TAG, "2. Test write operation");
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 7));
TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 9));
uint16_t val_read1 = 0;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 8));
TEST_ASSERT_EQUAL_HEX16(test1_len_8&((1 << 7) - 1), val_read1);
uint16_t test1_len_8_hi = test1_len_8 & ~((1 << 7) - 1);
if (scheme == EFUSE_CODING_SCHEME_NONE) {
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
} else {
TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
}
TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 8));
val_read1 = 0;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 16));
if (scheme == EFUSE_CODING_SCHEME_NONE) {
TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x00FF, val_read1);
} else {
TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x007F, val_read1);
}
if (scheme != EFUSE_CODING_SCHEME_NONE) {
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "erase virt blocks");
}
uint16_t test2_len_16 = 0xAA55;
uint32_t val_32 = test2_len_16;
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &val_32, 17));
TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
uint16_t test_16 = 0;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test_16, 16));
TEST_ASSERT_EQUAL_HEX16(test2_len_16, test_16);
ESP_LOGI(TAG, "3. Test field with one bit");
uint8_t test5_len_1;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
test5_len_1 = 0;
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
test5_len_1 = 1;
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
test5_len_1 = 1;
TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
esp_efuse_utility_debug_dump_blocks();
}
TEST_CASE("efuse test write_field_blob", "[efuse]")
{
test_write_blob();
}
static void test_write_cnt(void)
{
esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "1. Test check args");
size_t test3_len_6 = 5;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_MAC_FACTORY, 0));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(NULL, 5));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 0));
ESP_LOGI(TAG, "2. Test write operation");
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
TEST_ASSERT_EQUAL_INT(0, test3_len_6);
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
TEST_ASSERT_EQUAL_INT(1, test3_len_6);
if (scheme == EFUSE_CODING_SCHEME_NONE) {
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
} else {
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "erase virt blocks");
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 2));
}
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
TEST_ASSERT_EQUAL_INT(2, test3_len_6);
if (scheme == EFUSE_CODING_SCHEME_NONE) {
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 3));
} else {
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "erase virt blocks");
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 5));
}
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
TEST_ASSERT_EQUAL_INT(5, test3_len_6);
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "3. Test field is full set");
int max_bits = esp_efuse_get_field_size(ESP_EFUSE_TEST4_LEN_182);
size_t test4_len_182;
esp_efuse_utility_debug_dump_blocks();
for (int i = 0; i < max_bits / 26; ++i) {
ESP_LOGD(TAG, "# %d", i);
if (scheme == EFUSE_CODING_SCHEME_NONE) {
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 26));
} else {
esp_efuse_utility_erase_virt_blocks();
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, (i + 1) * 26));
}
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST4_LEN_182, &test4_len_182));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_INT((i + 1) * 26, test4_len_182);
}
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "4. Test field ESP_EFUSE_TEST4_LEN_182 is full");
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 1));
ESP_LOGI(TAG, "3. Test field with one bit");
size_t test5_len_1;
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
if (scheme != EFUSE_CODING_SCHEME_NONE) {
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "erase virt blocks");
}
test5_len_1 = 1;
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
test5_len_1 = 1;
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "4. Test field test2_len_16");
size_t test2_len_16 = 11;
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST2_LEN_16, test2_len_16));
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST2_LEN_16, &test2_len_16));
TEST_ASSERT_EQUAL_HEX16(11, test2_len_16);
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
TEST_ASSERT_EQUAL_HEX16(0x07FF, test2_len_16);
esp_efuse_utility_debug_dump_blocks();
}
TEST_CASE("efuse test write_field_cnt", "[efuse]")
{
test_write_cnt();
}
TEST_CASE("efuse test single bit functions", "[efuse]")
{
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
uint8_t test_bit;
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
TEST_ASSERT_EQUAL_HEX8(0, test_bit);
test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
TEST_ASSERT_EQUAL_HEX8(0, test_bit);
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
TEST_ASSERT_EQUAL_HEX8(1, test_bit);
test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
TEST_ASSERT_EQUAL_HEX8(1, test_bit);
// Can write the bit again and it's a no-op
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
TEST_ASSERT_EQUAL_HEX8(1, esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1));
esp_efuse_utility_debug_dump_blocks();
}
void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
{
if ((num_used_bits + count_bits) % 8) {
int start_used_item = (num_used_bits - 1) / 8;
int last_used_item = ((num_used_bits + count_bits) - 1) / 8;
int shift = 0;
int mask = num_used_bits + count_bits;
if (last_used_item == start_used_item) {
shift = (num_used_bits) % 8;
mask = count_bits;
}
arr[last_used_item] &= ((1 << (mask % 8)) - 1) << shift;
}
}
void cut_start_arr(uint8_t *arr, size_t num_used_bits)
{
if (num_used_bits % 8) {
int start_used_item = (num_used_bits - 1) / 8;
arr[start_used_item] &= ~((1 << (num_used_bits % 8)) - 1);
}
}
void get_part_arr(uint8_t *arr_in, uint8_t *arr_out, int num_used_bits, int count_bits)
{
int num_items = esp_efuse_utility_get_number_of_items(num_used_bits + count_bits, 8);
memcpy(arr_out, arr_in, num_items);
memset(arr_out, 0, num_used_bits / 8);
cut_start_arr(arr_out, num_used_bits);
cut_tail_arr(arr_out, num_used_bits, count_bits);
}
void fill_part_arr(uint8_t *arr_in, uint8_t *arr_out, int count_bits)
{
int num_items = esp_efuse_utility_get_number_of_items(count_bits, 8);
memcpy(arr_out, arr_in, num_items);
cut_tail_arr(arr_out, 0, count_bits);
}
// Writes a random array to efuse, then reads and compares it.
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)
{
ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_w, field_size));
memset(arr_r, 0, arr_size);
TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_w, arr_r, arr_size) == 0, "Operation write/read blob is not success");
int count_once = 0;
for (int i = 0; i < arr_size; ++i) {
count_once += __builtin_popcount(arr_w[i]);
}
size_t num_bits_r = 0;
TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
TEST_ASSERT_EQUAL_INT(count_once, num_bits_r);
size_t num_bits_w = field_size - count_once;
if (num_bits_w == 0) {
esp_efuse_utility_erase_virt_blocks();
num_bits_w = field_size;
}
TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
memset(arr_r, 0, arr_size);
TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
memset(arr_temp, 0xFF, arr_size);
cut_tail_arr(arr_temp, 0, field_size);
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
}
// Records a random number of bits (as "1") in the efuse field, then reads and compares.
void test_cnt_part(const esp_efuse_desc_t* field[], uint8_t *arr_r, int arr_size, size_t field_size)
{
size_t num_bits_r = 0;
TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
TEST_ASSERT_EQUAL_INT(0, num_bits_r);
TEST_ESP_OK(esp_efuse_write_field_cnt(field, field_size));
TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
esp_efuse_utility_erase_virt_blocks();
int num_bits_summ_r = 0;
int num_bits_w = 0;
while(field_size > num_bits_summ_r) {
num_bits_w = 0;
while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
bootloader_random_enable();
bootloader_fill_random(&num_bits_w, 1);
bootloader_random_disable();
num_bits_w = num_bits_w * field_size / 255;
if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
break;
}
}
TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
num_bits_summ_r += num_bits_w;
TEST_ASSERT_EQUAL_INT(num_bits_summ_r, num_bits_r);
memset(arr_r, 0, arr_size);
TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
int count_once = 0;
for (int i = 0; i < arr_size; ++i) {
count_once += __builtin_popcount(arr_r[i]);
}
TEST_ASSERT_EQUAL_INT(num_bits_summ_r, count_once);
ESP_LOGI(TAG, "Once bits=%d, step=%d", num_bits_summ_r, num_bits_w);
}
esp_efuse_utility_debug_dump_blocks();
}
// 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.
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)
{
esp_efuse_utility_debug_dump_blocks();
int num_bits_summ_r = 0;
int num_bits_w = 0;
memset(arr_w, 0, arr_size);
bootloader_random_enable();
bootloader_fill_random(arr_w, arr_size);
bootloader_random_disable();
ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
while(field_size > num_bits_summ_r) {
num_bits_w = 0;
while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
bootloader_random_enable();
bootloader_fill_random(&num_bits_w, 1);
bootloader_random_disable();
num_bits_w = num_bits_w * field_size / 255;
if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
break;
}
}
ESP_LOGI(TAG, "Summ bits=%d, step=%d", num_bits_summ_r, num_bits_w);
memset(arr_temp, 0, arr_size);
get_part_arr(arr_w, arr_temp, num_bits_summ_r, num_bits_w);
ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_temp, field_size));
memset(arr_r, 0, arr_size);
TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
esp_efuse_utility_debug_dump_blocks();
num_bits_summ_r += num_bits_w;
memset(arr_temp, 0, arr_size);
fill_part_arr(arr_w, arr_temp, num_bits_summ_r);
ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
}
}
void check_efuse_table_test(int cycle)
{
int num_test = 0;
while(1) {
const esp_efuse_desc_t** field;
switch (num_test++) {
case 0: field = ESP_EFUSE_TEST1_LEN_8; break;
case 1: field = ESP_EFUSE_TEST2_LEN_16; break;
case 2: field = ESP_EFUSE_TEST3_LEN_6; break;
case 3: field = ESP_EFUSE_TEST4_LEN_182; break;
case 4: field = ESP_EFUSE_TEST5_LEN_1; break;
case 5: field = ESP_EFUSE_TEST6_LEN_17; break;
default:
return;
break;
}
size_t field_size = esp_efuse_get_field_size(field);
int arr_size = esp_efuse_utility_get_number_of_items(field_size, 8);
uint8_t *arr_w = (uint8_t *) malloc(arr_size);
uint8_t *arr_r = (uint8_t *) malloc(arr_size);
uint8_t *arr_temp = (uint8_t *) malloc(arr_size);
ESP_LOGI(TAG, "Test#%d", num_test);
for (int c = 1; c <= cycle; ++c) {
ESP_LOGI(TAG, "Cycle#%d/%d", c, cycle);
memset(arr_w, 0, arr_size);
bootloader_random_enable();
bootloader_fill_random(arr_w, arr_size);
bootloader_random_disable();
cut_tail_arr(arr_w, 0, field_size);
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "1) blob write/read");
test_blob(field, arr_w, arr_r, arr_temp, arr_size, field_size);
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "2) cnt part write/read");
test_cnt_part(field, arr_r, arr_size, field_size);
esp_efuse_utility_erase_virt_blocks();
ESP_LOGI(TAG, "3) blob part write/read");
test_blob_part(field, arr_w, arr_r, arr_temp, arr_size, field_size);
}
free(arr_temp);
free(arr_r);
free(arr_w);
}
}
TEST_CASE("efuse esp_efuse_table_test", "[efuse]")
{
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
check_efuse_table_test(2);
} else {
ESP_LOGI(TAG, "This test is applicable only to the EFUSE_CODING_SCHEME_NONE. Skip this test.");
}
}
TEST_CASE("Test esp_efuse_read_block esp_efuse_write_block functions", "[efuse]")
{
int count_useful_reg = 0;
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
printf("EFUSE_CODING_SCHEME_NONE\n");
count_useful_reg = 8;
}
#if CONFIG_IDF_TARGET_ESP32
if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
printf("EFUSE_CODING_SCHEME_3_4\n");
count_useful_reg = 6;
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
printf("EFUSE_CODING_SCHEME_REPEAT\n");
count_useful_reg = 4;
}
#else
if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
printf("EFUSE_CODING_SCHEME_RS\n");
count_useful_reg = 8;
}
#endif
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
uint8_t src_key[32] = { 0 };
uint8_t dst_key[32] = { 0 };
int offset_in_bits = 0;
for (int i = 0; i < count_useful_reg * 4; ++i) {
src_key[i] = 0xAB + i;
}
TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32));
TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, sizeof(src_key));
esp_efuse_utility_erase_virt_blocks();
memset(src_key, 0, sizeof(src_key));
memset(dst_key, 0, sizeof(dst_key));
offset_in_bits = count_useful_reg * 32 / 2;
for (int i = 0; i < count_useful_reg * 4 / 2; ++i) {
src_key[i] = 0xCD + i;
}
TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32 / 2));
TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32 / 2));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, count_useful_reg * 4 / 2);
esp_efuse_utility_erase_virt_blocks();
}
TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
{
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
int count_useful_reg = 0;
uint8_t r_buff[32];
int st_offset = -1;
int num_block;
for (num_block = EFUSE_BLK_KEY0; num_block < EFUSE_BLK_KEY_MAX; ++num_block) {
memset(r_buff, 0, sizeof(r_buff));
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(num_block);
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
printf("EFUSE_CODING_SCHEME_NONE. The test is not applicable.\n");
count_useful_reg = 8;
return;
}
#if CONFIG_IDF_TARGET_ESP32
if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
printf("EFUSE_CODING_SCHEME_3_4\n");
count_useful_reg = 6;
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
printf("EFUSE_CODING_SCHEME_REPEAT\n");
count_useful_reg = 4;
}
#else
if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
printf("EFUSE_CODING_SCHEME_RS\n");
if (num_block == EFUSE_BLK_KEY0) {
count_useful_reg = 6;
} else {
count_useful_reg = 8;
}
}
#endif
TEST_ESP_OK(esp_efuse_read_block(num_block, r_buff, 0, count_useful_reg * 32));
for (int i = 0; i < count_useful_reg * 4; ++i) {
if (r_buff[i] != 0) {
// found used byte
for (int j = 0; j < 8; ++j) {
if ((r_buff[i] & (1 << j)) == 0) {
// found empty bit into this byte
st_offset = i * 8 + j;
printf("Byte = 0x%02x. offset is = %d\n", r_buff[i], st_offset);
break;
}
}
if (st_offset != -1) {
break;
}
}
}
if (st_offset != -1) {
break;
}
}
if (st_offset != -1) {
// write 1 bit to empty place.
uint8_t val = 1;
TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_block(num_block, &val, st_offset, 1));
} else {
printf("Test skipped. It is not applicable, the device has no written bits.\n");
}
}
#ifndef CONFIG_FREERTOS_UNICORE
static const int delay_ms = 2000;
static SemaphoreHandle_t sema;
static void task1(void* arg)
{
TEST_ESP_OK(esp_efuse_batch_write_begin());
ESP_LOGI(TAG, "Start work in batch mode");
xSemaphoreGive(sema);
vTaskDelay((delay_ms + 100) / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Finish work in batch mode");
TEST_ESP_OK(esp_efuse_batch_write_cancel());
vTaskDelete(NULL);
}
static void task2(void* arg)
{
xSemaphoreTake(sema, portMAX_DELAY);
uint8_t mac[6];
int64_t t1 = esp_timer_get_time();
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
int64_t t2 = esp_timer_get_time();
int diff_ms = (t2 - t1) / 1000;
TEST_ASSERT_GREATER_THAN(diff_ms, delay_ms);
ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
xSemaphoreGive(sema);
vTaskDelete(NULL);
}
static void task3(void* arg)
{
xSemaphoreTake(sema, portMAX_DELAY);
size_t test3_len_6 = 2;
int64_t t1 = esp_timer_get_time();
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
int64_t t2 = esp_timer_get_time();
ESP_LOGI(TAG, "write&read test3_len_6: %d", test3_len_6);
int diff_ms = (t2 - t1) / 1000;
TEST_ASSERT_GREATER_THAN(delay_ms, diff_ms);
TEST_ASSERT_EQUAL_INT(2, test3_len_6);
xSemaphoreGive(sema);
vTaskDelete(NULL);
}
TEST_CASE("Batch mode is thread-safe", "[efuse]")
{
// Batch mode blocks work with efuse on other tasks.
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
sema = xSemaphoreCreateBinary();
printf("\n");
xTaskCreatePinnedToCore(task1, "task1", 3072, NULL, TASK_PRIORITY - 1, NULL, 0);
xTaskCreatePinnedToCore(task2, "task2", 3072, NULL, TASK_PRIORITY - 1, NULL, 1);
vTaskDelay(3000 / portTICK_PERIOD_MS);
xSemaphoreTake(sema, portMAX_DELAY);
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
printf("\n");
xTaskCreatePinnedToCore(task1, "task1", 3072, NULL, TASK_PRIORITY - 1, NULL, 0);
xTaskCreatePinnedToCore(task3, "task3", 3072, NULL, TASK_PRIORITY - 1, NULL, 1);
vTaskDelay(3000 / portTICK_PERIOD_MS);
xSemaphoreTake(sema, portMAX_DELAY);
printf("\n");
vSemaphoreDelete(sema);
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
#endif // #ifndef CONFIG_FREERTOS_UNICORE
static volatile bool cmd_stop_reset_task1;
static void efuse_burn_task(void* arg)
{
SemaphoreHandle_t sema = (SemaphoreHandle_t) arg;
ESP_LOGI(TAG, "Start burn task");
size_t test3_len_6 = 2;
while (!cmd_stop_reset_task1) {
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_reset();
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
}
xSemaphoreGive(sema);
ESP_LOGI(TAG, "Stop burn task");
vTaskDelete(NULL);
}
static void efuse_read_task(void* arg)
{
SemaphoreHandle_t sema = (SemaphoreHandle_t) arg;
ESP_LOGI(TAG, "Start read task");
size_t test3_len_6 = 0;
while (!cmd_stop_reset_task1) {
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST3_LEN_6, &test3_len_6, 6));
}
xSemaphoreGive(sema);
ESP_LOGI(TAG, "Stop read task");
vTaskDelete(NULL);
}
TEST_CASE("Check a case when ESP_ERR_DAMAGED_READING occurs and read and burn are not blocked", "[efuse]")
{
cmd_stop_reset_task1 = false;
TaskHandle_t read_task_hdl;
SemaphoreHandle_t sema[2];
sema[0] = xSemaphoreCreateBinary();
sema[1] = xSemaphoreCreateBinary();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
xTaskCreatePinnedToCore(efuse_burn_task, "efuse_burn_task", 3072, sema[0], 2, NULL, 0);
xTaskCreatePinnedToCore(efuse_read_task, "efuse_read_task", 3072, sema[1], 2, &read_task_hdl, 0);
vTaskDelay(10 / portTICK_PERIOD_MS);
for (unsigned i = 1; i < 30; ++i) {
vTaskPrioritySet(read_task_hdl, 2 + i % 2);
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
cmd_stop_reset_task1 = true;
vTaskDelay(10 / portTICK_PERIOD_MS);
TEST_ASSERT_EQUAL(pdPASS, xSemaphoreTake(sema[0], 1000 / portTICK_PERIOD_MS));
TEST_ASSERT_EQUAL(pdPASS, xSemaphoreTake(sema[1], 1000 / portTICK_PERIOD_MS));
vSemaphoreDelete(sema[0]);
vSemaphoreDelete(sema[1]);
}
#endif // #ifdef CONFIG_EFUSE_VIRTUAL
#ifndef CONFIG_FREERTOS_UNICORE
static volatile bool cmd_stop_reset_task;
static void reset_task(void* arg)
{
ESP_LOGI(TAG, "Start reset task");
while (!cmd_stop_reset_task) {
esp_efuse_utility_reset();
vTaskDelay(2);
}
vTaskDelete(NULL);
}
TEST_CASE("Check a case when ESP_ERR_DAMAGED_READING occurs during reading efuses", "[efuse]")
{
cmd_stop_reset_task = false;
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
uint8_t mac[6];
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
xTaskCreatePinnedToCore(reset_task, "reset_task", 3072, NULL, TASK_PRIORITY - 1, NULL, 1);
uint8_t new_mac[6];
for (int i = 0; i < 1000; ++i) {
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
TEST_ASSERT_EQUAL_HEX8_ARRAY(mac, new_mac, sizeof(mac));
}
cmd_stop_reset_task = true;
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]);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
#endif // if not CONFIG_FREERTOS_UNICORE
#ifdef CONFIG_IDF_ENV_FPGA
TEST_CASE("Test a real write (FPGA)", "[efuse]")
{
ESP_LOGI(TAG, "1. Write MAC address");
esp_efuse_utility_debug_dump_blocks();
uint8_t mac[6];
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
uint8_t new_mac[6];
if (mac[0] == 0) {
new_mac[0] = 0x71;
new_mac[1] = 0x62;
new_mac[2] = 0x53;
new_mac[3] = 0x44;
new_mac[4] = 0x35;
new_mac[5] = 0x26;
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
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]);
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_mac, mac, sizeof(new_mac));
esp_efuse_utility_debug_dump_blocks();
}
ESP_LOGI(TAG, "4. Write SECURE_VERSION");
int max_bits = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
size_t read_sec_version;
esp_efuse_utility_debug_dump_blocks();
for (int i = 0; i < max_bits; ++i) {
ESP_LOGI(TAG, "# %d", i);
TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_SECURE_VERSION, 1));
TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_SECURE_VERSION, &read_sec_version));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_INT(i + 1, read_sec_version);
}
}
#endif // CONFIG_IDF_ENV_FPGA
TEST_CASE("Test chip_ver_pkg APIs return the same value", "[efuse]")
{
esp_efuse_utility_update_virt_blocks();
TEST_ASSERT_EQUAL_INT(esp_efuse_get_pkg_ver(), bootloader_common_get_chip_ver_pkg());
}

View File

@@ -0,0 +1,94 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_efuse.h"
#include "esp_efuse_test_table.h"
// md5_digest_table 7d587827a6f6134241dce7d3713b3edc
// This file was generated automatically from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file then build system will generate this header file
// To show efuse_table run the command 'make show_efuse_table'.
static const esp_efuse_desc_t TEST1_LEN_8[] = {
{EFUSE_BLK3, 0, 8}, // TEST field,
};
static const esp_efuse_desc_t TEST2_LEN_16[] = {
{EFUSE_BLK3, 10, 8}, // TEST field,
{EFUSE_BLK3, 80, 8}, // TEST field,
};
static const esp_efuse_desc_t TEST3_LEN_6[] = {
{EFUSE_BLK3, 22, 6}, // TEST field,
};
static const esp_efuse_desc_t TEST4_LEN_182[] = {
{EFUSE_BLK1, 22, 49}, // TEST field,
{EFUSE_BLK1, 89, 39}, // TEST field,
{EFUSE_BLK1, 71, 18}, // TEST field,
{EFUSE_BLK1, 0, 16}, // TEST field,
{EFUSE_BLK2, 0, 17}, // TEST field,
{EFUSE_BLK2, 60, 43}, // TEST field,
};
static const esp_efuse_desc_t TEST5_LEN_1[] = {
{EFUSE_BLK1, 16, 1}, // TEST field,
};
static const esp_efuse_desc_t TEST6_LEN_17[] = {
{EFUSE_BLK1, 17, 1}, // TEST field,
{EFUSE_BLK2, 17, 2}, // TEST field,
{EFUSE_BLK3, 29, 4}, // TEST field,
{EFUSE_BLK2, 31, 3}, // TEST field,
{EFUSE_BLK3, 60, 6}, // TEST field,
{EFUSE_BLK2, 127, 1}, // TEST field,
};
const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[] = {
&TEST1_LEN_8[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[] = {
&TEST2_LEN_16[0], // TEST field
&TEST2_LEN_16[1], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[] = {
&TEST3_LEN_6[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[] = {
&TEST4_LEN_182[0], // TEST field
&TEST4_LEN_182[1], // TEST field
&TEST4_LEN_182[2], // TEST field
&TEST4_LEN_182[3], // TEST field
&TEST4_LEN_182[4], // TEST field
&TEST4_LEN_182[5], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[] = {
&TEST5_LEN_1[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[] = {
&TEST6_LEN_17[0], // TEST field
&TEST6_LEN_17[1], // TEST field
&TEST6_LEN_17[2], // TEST field
&TEST6_LEN_17[3], // TEST field
&TEST6_LEN_17[4], // TEST field
&TEST6_LEN_17[5], // TEST field
NULL
};

View File

@@ -0,0 +1,33 @@
# field_name, | efuse_block, | bit_start, | bit_count, |comment #
# | (EFUSE_BLK0 | (0..255) | (1..256) | #
# | EFUSE_BLK1 | | | #
# | EFUSE_BLK2 | | | #
# | EFUSE_BLK3) | | | #
##########################################################################
# To generate a new source files. Run two commands:
# cd ~/esp/esp-idf/components/efuse/
# ./efuse_table_gen.py test/esp_efuse_test_table.csv
TEST1_LEN_8, EFUSE_BLK3, 0, 8, TEST field
TEST2_LEN_16, EFUSE_BLK3, 10, 8, TEST field
, EFUSE_BLK3, 80, 8, TEST field
TEST3_LEN_6, EFUSE_BLK3, 22, 6, TEST field
TEST4_LEN_182, EFUSE_BLK1, 22, 49, TEST field
, EFUSE_BLK1, 89, 39, TEST field
, EFUSE_BLK1, 71, 18, TEST field
, EFUSE_BLK1, 0, 16, TEST field
, EFUSE_BLK2, 0, 17, TEST field
, EFUSE_BLK2, 60, 43, TEST field
TEST5_LEN_1, EFUSE_BLK1, 16, 1, TEST field
TEST6_LEN_17, EFUSE_BLK1, 17, 1, TEST field
, EFUSE_BLK2, 17, 2, TEST field
, EFUSE_BLK3, 29, 4, TEST field
, EFUSE_BLK2, 31, 3, TEST field
, EFUSE_BLK3, 60, 6, TEST field
, EFUSE_BLK2, 127, 1, TEST field
1 # field_name, | efuse_block, | bit_start, | bit_count, |comment #
2 # | (EFUSE_BLK0 | (0..255) | (1..256) | #
3 # | EFUSE_BLK1 | | | #
4 # | EFUSE_BLK2 | | | #
5 # | EFUSE_BLK3) | | | #
6 ##########################################################################
7 # To generate a new source files. Run two commands:
8 # cd ~/esp/esp-idf/components/efuse/
9 # ./efuse_table_gen.py test/esp_efuse_test_table.csv
10 TEST1_LEN_8, EFUSE_BLK3, 0, 8, TEST field
11 TEST2_LEN_16, EFUSE_BLK3, 10, 8, TEST field
12 , EFUSE_BLK3, 80, 8, TEST field
13 TEST3_LEN_6, EFUSE_BLK3, 22, 6, TEST field
14 TEST4_LEN_182, EFUSE_BLK1, 22, 49, TEST field
15 , EFUSE_BLK1, 89, 39, TEST field
16 , EFUSE_BLK1, 71, 18, TEST field
17 , EFUSE_BLK1, 0, 16, TEST field
18 , EFUSE_BLK2, 0, 17, TEST field
19 , EFUSE_BLK2, 60, 43, TEST field
20 TEST5_LEN_1, EFUSE_BLK1, 16, 1, TEST field
21 TEST6_LEN_17, EFUSE_BLK1, 17, 1, TEST field
22 , EFUSE_BLK2, 17, 2, TEST field
23 , EFUSE_BLK3, 29, 4, TEST field
24 , EFUSE_BLK2, 31, 3, TEST field
25 , EFUSE_BLK3, 60, 6, TEST field
26 , EFUSE_BLK2, 127, 1, TEST field

View File

@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
// md5_digest_table 7d587827a6f6134241dce7d3713b3edc
// This file was generated automatically from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file then build system will generate this header file
// To show efuse_table run the command 'make show_efuse_table'.
extern const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[];
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,85 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "unity.h"
#include "esp_log.h"
#include <string.h>
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_test_table.h"
#include "bootloader_random.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "sdkconfig.h"
#include "esp_rom_efuse.h"
#include "bootloader_common.h"
__attribute__((unused)) static const char* TAG = "efuse_test";
#ifdef CONFIG_EFUSE_VIRTUAL
static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
{
size_t out_cnt;
TEST_ESP_OK(esp_efuse_set_write_protect(blk));
esp_efuse_read_field_cnt(field, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
}
static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
{
size_t out_cnt;
if (read_first) {
esp_efuse_read_field_cnt(field, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
}
TEST_ESP_OK(esp_efuse_set_read_protect(blk));
esp_efuse_read_field_cnt(field, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
if (read_first) {
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
}
}
TEST_CASE("Test a write/read protection", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
size_t out_cnt;
esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_BLK2);
test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_BLK3);
esp_efuse_utility_debug_dump_blocks();
test_rp(EFUSE_BLK1, ESP_EFUSE_RD_DIS_BLK1, true);
test_rp(EFUSE_BLK2, ESP_EFUSE_RD_DIS_BLK2, false);
test_rp(EFUSE_BLK3, ESP_EFUSE_RD_DIS_BLK3, false);
esp_efuse_utility_debug_dump_blocks();
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
#endif // #ifdef CONFIG_EFUSE_VIRTUAL

View File

@@ -0,0 +1,210 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <strings.h>
#include "esp_efuse.h"
#include "esp_efuse_utility.h"
#include "soc/efuse_periph.h"
#include "unity.h"
#include "bootloader_random.h"
typedef struct {
uint8_t unencoded[24];
uint32_t encoded[8];
} coding_scheme_test_t;
/* Randomly generated byte strings, encoded and written to ESP32
using espefuse algorithm, then verified to have no encoding errors
and correct readback.
*/
static const coding_scheme_test_t coding_scheme_data[] = {
{
.unencoded = { 0x96, 0xa9, 0xab, 0xb2, 0xda, 0xdd, 0x21, 0xd2, 0x35, 0x22, 0xd3, 0x30, 0x3b, 0xf8, 0xcb, 0x77, 0x8d, 0x8d, 0xf4, 0x96, 0x25, 0xc4, 0xb9, 0x94 },
.encoded = { 0xb2aba996, 0x6821ddda, 0x2235d221, 0x430730d3, 0x77cbf83b, 0x627f8d8d, 0xc42596f4, 0x4dae94b9 },
},
{
.unencoded = { 0x0e, 0x6b, 0x1a, 0x1d, 0xa5, 0x9f, 0x24, 0xcf, 0x91, 0x5b, 0xe7, 0xe1, 0x7c, 0x0a, 0x6e, 0xdc, 0x5e, 0x8e, 0xb1, 0xec, 0xd1, 0xf3, 0x75, 0x48 },
.encoded = { 0x1d1a6b0e, 0x5e589fa5, 0x5b91cf24, 0x6127e1e7, 0xdc6e0a7c, 0x5d148e5e, 0xf3d1ecb1, 0x57424875 },
},
{
.unencoded = { 0x0a, 0x79, 0x5a, 0x1c, 0xb1, 0x45, 0x71, 0x2c, 0xb3, 0xda, 0x9e, 0xdc, 0x76, 0x27, 0xf5, 0xca, 0xe7, 0x00, 0x39, 0x95, 0x6c, 0x53, 0xc2, 0x07 },
.encoded = { 0x1c5a790a, 0x4ac145b1, 0xdab32c71, 0x6476dc9e, 0xcaf52776, 0x4d8900e7, 0x536c9539, 0x495607c2 },
},
{
.unencoded = { 0x76, 0x46, 0x88, 0x2d, 0x4c, 0xe1, 0x50, 0x5d, 0xd6, 0x7c, 0x41, 0x15, 0xc6, 0x1f, 0xd4, 0x60, 0x10, 0x15, 0x2a, 0x72, 0x2d, 0x89, 0x93, 0x13 },
.encoded = { 0x2d884676, 0x4838e14c, 0x7cd65d50, 0x4bf31541, 0x60d41fc6, 0x39681510, 0x892d722a, 0x497c1393 },
},
{
.unencoded = { 0x32, 0xbc, 0x40, 0x92, 0x13, 0x37, 0x1a, 0xae, 0xb6, 0x00, 0xed, 0x30, 0xb8, 0x82, 0xee, 0xfc, 0xcf, 0x6d, 0x7f, 0xc5, 0xfa, 0x0e, 0xdd, 0x84 },
.encoded = { 0x9240bc32, 0x49783713, 0x00b6ae1a, 0x46df30ed, 0xfcee82b8, 0x6e8a6dcf, 0x0efac57f, 0x571784dd },
},
{
.unencoded = { 0x29, 0xb3, 0x04, 0x95, 0xf2, 0x3c, 0x81, 0xe6, 0x5a, 0xf3, 0x42, 0x82, 0xd1, 0x79, 0xe2, 0x12, 0xbe, 0xc3, 0xd4, 0x10, 0x63, 0x66, 0x9f, 0xe3 },
.encoded = { 0x9504b329, 0x51c53cf2, 0xf35ae681, 0x460e8242, 0x12e279d1, 0x5825c3be, 0x666310d4, 0x5ebde39f },
},
{
.unencoded = { 0xda, 0xda, 0x71, 0x4a, 0x62, 0x33, 0xdd, 0x31, 0x87, 0xf3, 0x70, 0x12, 0x33, 0x3b, 0x3b, 0xe9, 0xed, 0xc4, 0x6e, 0x6a, 0xc7, 0xd5, 0x85, 0xfc },
.encoded = { 0x4a71dada, 0x4e6a3362, 0xf38731dd, 0x4bfa1270, 0xe93b3b33, 0x61f3c4ed, 0xd5c76a6e, 0x636ffc85 },
},
{
.unencoded = { 0x45, 0x64, 0x51, 0x34, 0x1c, 0x82, 0x81, 0x77, 0xf8, 0x89, 0xb1, 0x15, 0x82, 0x94, 0xdd, 0x64, 0xa2, 0x46, 0x0e, 0xfb, 0x1a, 0x70, 0x4b, 0x9f },
.encoded = { 0x34516445, 0x39da821c, 0x89f87781, 0x4f2315b1, 0x64dd9482, 0x474b46a2, 0x701afb0e, 0x5e4b9f4b },
},
{
.unencoded = { 0x89, 0x87, 0x15, 0xb6, 0x66, 0x34, 0x49, 0x18, 0x8b, 0x7b, 0xb2, 0xf6, 0x96, 0x1e, 0x2e, 0xf1, 0x03, 0x9d, 0x4e, 0x16, 0x32, 0xd6, 0x23, 0x22 },
.encoded = { 0xb6158789, 0x4eff3466, 0x7b8b1849, 0x63e5f6b2, 0xf12e1e96, 0x54c99d03, 0xd632164e, 0x42bd2223 },
},
{
.unencoded = { 0xa7, 0xa0, 0xb5, 0x21, 0xd2, 0xa3, 0x9f, 0x65, 0xa9, 0xeb, 0x72, 0xa2, 0x2e, 0xa6, 0xfb, 0x9c, 0x48, 0x7e, 0x68, 0x08, 0x7a, 0xb1, 0x4f, 0xbc },
.encoded = { 0x21b5a0a7, 0x4ce2a3d2, 0xeba9659f, 0x5868a272, 0x9cfba62e, 0x5fd97e48, 0xb17a0868, 0x5b58bc4f },
},
{
.unencoded = { 0xf7, 0x05, 0xe3, 0x6c, 0xb1, 0x55, 0xcb, 0x2f, 0x8d, 0x3e, 0x0b, 0x2e, 0x3e, 0xb7, 0x02, 0xf5, 0x91, 0xb1, 0xfe, 0x8b, 0x58, 0x50, 0xb2, 0x40 },
.encoded = { 0x6ce305f7, 0x569955b1, 0x3e8d2fcb, 0x56722e0b, 0xf502b73e, 0x535eb191, 0x50588bfe, 0x3a8f40b2 },
},
{
.unencoded = { 0x0f, 0x93, 0xb0, 0xd5, 0x60, 0xba, 0x40, 0x2a, 0x62, 0xa6, 0x92, 0x82, 0xb8, 0x91, 0x2c, 0xd7, 0x23, 0xdc, 0x6f, 0x7f, 0x2f, 0xbe, 0x41, 0xf5 },
.encoded = { 0xd5b0930f, 0x5123ba60, 0xa6622a40, 0x3bbe8292, 0xd72c91b8, 0x582ddc23, 0xbe2f7f6f, 0x6935f541 },
},
{
.unencoded = { 0x7f, 0x0c, 0x99, 0xde, 0xff, 0x2e, 0xd2, 0x1c, 0x48, 0x98, 0x70, 0x85, 0x15, 0x01, 0x2a, 0xfb, 0xcd, 0xf2, 0xa0, 0xf9, 0x0e, 0xbc, 0x9f, 0x0c },
.encoded = { 0xde990c7f, 0x6fe52eff, 0x98481cd2, 0x3deb8570, 0xfb2a0115, 0x61faf2cd, 0xbc0ef9a0, 0x55780c9f },
},
{
.unencoded = { 0x9a, 0x10, 0x92, 0x03, 0x81, 0xfe, 0x41, 0x57, 0x77, 0x02, 0xcb, 0x20, 0x67, 0xa4, 0x97, 0xf3, 0xf8, 0xc7, 0x0d, 0x65, 0xcd, 0xfc, 0x15, 0xef },
.encoded = { 0x0392109a, 0x4b64fe81, 0x02775741, 0x418820cb, 0xf397a467, 0x6998c7f8, 0xfccd650d, 0x6ba3ef15 },
},
};
TEST_CASE("Test 3/4 Coding Scheme Algorithm", "[efuse]")
{
const int num_tests = sizeof(coding_scheme_data)/sizeof(coding_scheme_test_t);
for (int i = 0; i < num_tests; i++) {
uint32_t result[8];
const coding_scheme_test_t *t = &coding_scheme_data[i];
printf("Test case %d...\n", i);
esp_err_t r = esp_efuse_utility_apply_34_encoding(t->unencoded, result, sizeof(t->unencoded));
TEST_ASSERT_EQUAL_HEX(ESP_OK, r);
TEST_ASSERT_EQUAL_HEX32_ARRAY(t->encoded, result, 8);
// Do the same, 6 bytes at a time
for (int offs = 0; offs < sizeof(t->unencoded); offs += 6) {
bzero(result, sizeof(result));
r = esp_efuse_utility_apply_34_encoding(t->unencoded + offs, result, 6);
TEST_ASSERT_EQUAL_HEX(ESP_OK, r);
TEST_ASSERT_EQUAL_HEX32_ARRAY(t->encoded + (offs / 6 * 2), result, 2);
}
}
}
TEST_CASE("Test Coding Scheme for efuse manager", "[efuse]")
{
int count_useful_reg = 0;
int useful_data_in_byte;
uint8_t buf[32];
uint32_t encoded[8];
bootloader_random_enable();
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
printf("EFUSE_CODING_SCHEME_NONE\n");
count_useful_reg = 8;
} else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
printf("EFUSE_CODING_SCHEME_3_4\n");
count_useful_reg = 6;
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
printf("EFUSE_CODING_SCHEME_REPEAT\n");
count_useful_reg = 4;
}
useful_data_in_byte = count_useful_reg * 4;
for (int i = 0; i < 10; ++i) {
esp_efuse_utility_erase_virt_blocks();
printf("Test case %d...\n", i);
memset(buf, 0, sizeof(buf));
memset(encoded, 0, sizeof(encoded));
// get test data
bootloader_fill_random(buf, useful_data_in_byte);
memset(buf, 0, i);
esp_efuse_utility_reset();
for (int j = 0; j < count_useful_reg; ++j) {
REG_WRITE(EFUSE_BLK2_WDATA0_REG + j * 4, *((uint32_t*)buf + j));
}
TEST_ESP_OK(esp_efuse_utility_apply_new_coding_scheme());
uint32_t w_data_after_coding[8] = { 0 };
for (int j = 0; j < 8; ++j) {
w_data_after_coding[j] = REG_READ(EFUSE_BLK2_WDATA0_REG + j * 4);
}
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
memcpy((uint8_t*)encoded, buf, sizeof(buf));
} else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
TEST_ESP_OK(esp_efuse_utility_apply_34_encoding(buf, encoded, useful_data_in_byte));
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
for (int j = 0; j < count_useful_reg; ++j) {
encoded[j] = *((uint32_t*)buf + j);
encoded[j + 4] = encoded[j];
}
}
#ifdef CONFIG_EFUSE_VIRTUAL
printf("Data from W reg\n");
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_burn_efuses();
esp_efuse_utility_debug_dump_blocks();
printf("Data from encoded\n");
for (int j = 0; j < 8; ++j) {
printf("0x%08lx ", encoded[j]);
}
printf("\nData from w_data_after_coding\n");
for (int j = 0; j < 8; ++j) {
printf("0x%08lx ", w_data_after_coding[j]);
}
printf("\nData from buf\n");
for (int j = 0; j < 8; ++j) {
printf("0x%08lx ", *((uint32_t*)buf + j));
}
printf("\n");
#endif
TEST_ASSERT_EQUAL_HEX32_ARRAY(buf, w_data_after_coding, 8);
}
esp_efuse_utility_reset();
bootloader_random_disable();
}
TEST_CASE("Test data does not match the coding scheme", "[efuse]")
{
int count_useful_reg = 0;
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
printf("EFUSE_CODING_SCHEME_NONE\n");
count_useful_reg = 8;
} else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
printf("EFUSE_CODING_SCHEME_3_4\n");
count_useful_reg = 6 + 1;
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
printf("EFUSE_CODING_SCHEME_REPEAT\n");
count_useful_reg = 4 + 1;
}
esp_efuse_utility_reset();
for (int i = 0; i < count_useful_reg; ++i) {
TEST_ESP_OK(esp_efuse_utility_write_reg(2, i, 0xABCDEF01 + i));
}
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
TEST_ESP_OK(esp_efuse_utility_apply_new_coding_scheme());
} else {
TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_utility_apply_new_coding_scheme());
}
esp_efuse_utility_reset();
}

View File

@@ -0,0 +1,107 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_efuse.h"
#include <assert.h>
#include "esp_efuse_test_table.h"
// md5_digest_table 7d587827a6f6134241dce7d3713b3edc
// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
// To show efuse_table run the command 'show_efuse_table'.
#define MAX_BLK_LEN CONFIG_EFUSE_MAX_BLK_LEN
// The last free bit in the block is counted over the entire file.
#define LAST_FREE_BIT_BLK1 128
#define LAST_FREE_BIT_BLK2 128
#define LAST_FREE_BIT_BLK3 88
_Static_assert(LAST_FREE_BIT_BLK1 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
_Static_assert(LAST_FREE_BIT_BLK2 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
_Static_assert(LAST_FREE_BIT_BLK3 <= MAX_BLK_LEN, "The eFuse table does not match the coding scheme. Edit the table and restart the efuse_common_table or efuse_custom_table command to regenerate the new files.");
static const esp_efuse_desc_t TEST1_LEN_8[] = {
{EFUSE_BLK3, 0, 8}, // TEST field,
};
static const esp_efuse_desc_t TEST2_LEN_16[] = {
{EFUSE_BLK3, 10, 8}, // TEST field,
{EFUSE_BLK3, 80, 8}, // TEST field,
};
static const esp_efuse_desc_t TEST3_LEN_6[] = {
{EFUSE_BLK3, 22, 6}, // TEST field,
};
static const esp_efuse_desc_t TEST4_LEN_182[] = {
{EFUSE_BLK1, 22, 49}, // TEST field,
{EFUSE_BLK1, 89, 39}, // TEST field,
{EFUSE_BLK1, 71, 18}, // TEST field,
{EFUSE_BLK1, 0, 16}, // TEST field,
{EFUSE_BLK2, 0, 17}, // TEST field,
{EFUSE_BLK2, 60, 43}, // TEST field,
};
static const esp_efuse_desc_t TEST5_LEN_1[] = {
{EFUSE_BLK1, 16, 1}, // TEST field,
};
static const esp_efuse_desc_t TEST6_LEN_17[] = {
{EFUSE_BLK1, 17, 1}, // TEST field,
{EFUSE_BLK2, 17, 2}, // TEST field,
{EFUSE_BLK3, 29, 4}, // TEST field,
{EFUSE_BLK2, 31, 3}, // TEST field,
{EFUSE_BLK3, 60, 6}, // TEST field,
{EFUSE_BLK2, 127, 1}, // TEST field,
};
const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[] = {
&TEST1_LEN_8[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[] = {
&TEST2_LEN_16[0], // TEST field
&TEST2_LEN_16[1], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[] = {
&TEST3_LEN_6[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[] = {
&TEST4_LEN_182[0], // TEST field
&TEST4_LEN_182[1], // TEST field
&TEST4_LEN_182[2], // TEST field
&TEST4_LEN_182[3], // TEST field
&TEST4_LEN_182[4], // TEST field
&TEST4_LEN_182[5], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[] = {
&TEST5_LEN_1[0], // TEST field
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[] = {
&TEST6_LEN_17[0], // TEST field
&TEST6_LEN_17[1], // TEST field
&TEST6_LEN_17[2], // TEST field
&TEST6_LEN_17[3], // TEST field
&TEST6_LEN_17[4], // TEST field
&TEST6_LEN_17[5], // TEST field
NULL
};

View File

@@ -0,0 +1,33 @@
# field_name, | efuse_block, | bit_start, | bit_count, |comment #
# | (EFUSE_BLK0 | (0..255) | (1..256) | #
# | EFUSE_BLK1 | | | #
# | EFUSE_BLK2 | | | #
# | EFUSE_BLK3) | | | #
##########################################################################
# To generate a new source files. Run two commands:
# cd ~/esp/esp-idf/components/efuse/
# ./efuse_table_gen.py test/esp_efuse_test_table.csv
TEST1_LEN_8, EFUSE_BLK3, 0, 8, TEST field
TEST2_LEN_16, EFUSE_BLK3, 10, 8, TEST field
, EFUSE_BLK3, 80, 8, TEST field
TEST3_LEN_6, EFUSE_BLK3, 22, 6, TEST field
TEST4_LEN_182, EFUSE_BLK1, 22, 49, TEST field
, EFUSE_BLK1, 89, 39, TEST field
, EFUSE_BLK1, 71, 18, TEST field
, EFUSE_BLK1, 0, 16, TEST field
, EFUSE_BLK2, 0, 17, TEST field
, EFUSE_BLK2, 60, 43, TEST field
TEST5_LEN_1, EFUSE_BLK1, 16, 1, TEST field
TEST6_LEN_17, EFUSE_BLK1, 17, 1, TEST field
, EFUSE_BLK2, 17, 2, TEST field
, EFUSE_BLK3, 29, 4, TEST field
, EFUSE_BLK2, 31, 3, TEST field
, EFUSE_BLK3, 60, 6, TEST field
, EFUSE_BLK2, 127, 1, TEST field
1 # field_name, | efuse_block, | bit_start, | bit_count, |comment #
2 # | (EFUSE_BLK0 | (0..255) | (1..256) | #
3 # | EFUSE_BLK1 | | | #
4 # | EFUSE_BLK2 | | | #
5 # | EFUSE_BLK3) | | | #
6 ##########################################################################
7 # To generate a new source files. Run two commands:
8 # cd ~/esp/esp-idf/components/efuse/
9 # ./efuse_table_gen.py test/esp_efuse_test_table.csv
10 TEST1_LEN_8, EFUSE_BLK3, 0, 8, TEST field
11 TEST2_LEN_16, EFUSE_BLK3, 10, 8, TEST field
12 , EFUSE_BLK3, 80, 8, TEST field
13 TEST3_LEN_6, EFUSE_BLK3, 22, 6, TEST field
14 TEST4_LEN_182, EFUSE_BLK1, 22, 49, TEST field
15 , EFUSE_BLK1, 89, 39, TEST field
16 , EFUSE_BLK1, 71, 18, TEST field
17 , EFUSE_BLK1, 0, 16, TEST field
18 , EFUSE_BLK2, 0, 17, TEST field
19 , EFUSE_BLK2, 60, 43, TEST field
20 TEST5_LEN_1, EFUSE_BLK1, 16, 1, TEST field
21 TEST6_LEN_17, EFUSE_BLK1, 17, 1, TEST field
22 , EFUSE_BLK2, 17, 2, TEST field
23 , EFUSE_BLK3, 29, 4, TEST field
24 , EFUSE_BLK2, 31, 3, TEST field
25 , EFUSE_BLK3, 60, 6, TEST field
26 , EFUSE_BLK2, 127, 1, TEST field

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
// md5_digest_table 7d587827a6f6134241dce7d3713b3edc
// This file was generated from the file esp_efuse_test_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_test_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
// To show efuse_table run the command 'show_efuse_table'.
extern const esp_efuse_desc_t* ESP_EFUSE_TEST1_LEN_8[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST2_LEN_16[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST3_LEN_6[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST4_LEN_182[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST5_LEN_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEST6_LEN_17[];
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,194 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "unity.h"
#include "esp_log.h"
#include <string.h>
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_test_table.h"
#include "bootloader_random.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "sdkconfig.h"
#include "esp_rom_efuse.h"
#include "bootloader_common.h"
__attribute__((unused)) static const char* TAG = "efuse_test";
#ifdef CONFIG_EFUSE_VIRTUAL
static void test_wp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[])
{
size_t out_cnt;
TEST_ESP_OK(esp_efuse_set_write_protect(blk));
esp_efuse_read_field_cnt(field, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
}
static void test_rp(esp_efuse_block_t blk, const esp_efuse_desc_t* field[], bool read_first)
{
size_t out_cnt;
if (read_first) {
esp_efuse_read_field_cnt(field, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
}
TEST_ESP_OK(esp_efuse_set_read_protect(blk));
esp_efuse_read_field_cnt(field, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
if (read_first) {
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_read_protect(blk));
}
}
TEST_CASE("Test a write/read protection", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_write_protect(EFUSE_BLK0));
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_set_read_protect(EFUSE_BLK0));
size_t out_cnt;
esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
TEST_ASSERT_EQUAL_INT(0, out_cnt);
TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK1));
esp_efuse_read_field_cnt(ESP_EFUSE_WR_DIS_BLK1, &out_cnt);
TEST_ASSERT_EQUAL_INT(1, out_cnt);
TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_set_write_protect(EFUSE_BLK1));
test_wp(EFUSE_BLK2, ESP_EFUSE_WR_DIS_SYS_DATA_PART1);
test_wp(EFUSE_BLK3, ESP_EFUSE_WR_DIS_USER_DATA);
esp_efuse_utility_debug_dump_blocks();
test_rp(EFUSE_BLK4, ESP_EFUSE_RD_DIS_KEY0, true);
test_rp(EFUSE_BLK5, ESP_EFUSE_RD_DIS_KEY1, false);
test_rp(EFUSE_BLK6, ESP_EFUSE_RD_DIS_KEY2, false);
esp_efuse_utility_debug_dump_blocks();
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
}
#endif // CONFIG_EFUSE_VIRTUAL
#ifdef CONFIG_IDF_ENV_FPGA
TEST_CASE("Test a real write (FPGA)2", "[efuse]")
{
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "1. Write KEY3");
uint8_t key[32] = {0};
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
for (int i = 0; i < sizeof(key); ++i) {
TEST_ASSERT_EQUAL_INT(0, key[i]);
}
uint8_t new_key[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
30, 31};
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY3, &new_key, 256));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "2. Set a read protection for KEY3");
TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK_KEY3));
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY3, &key, 256));
#ifndef CONFIG_EFUSE_VIRTUAL
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
#else
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
#endif // CONFIG_EFUSE_VIRTUAL
esp_efuse_utility_debug_dump_blocks();
}
#endif // CONFIG_IDF_ENV_FPGA
#if CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL
TEST_CASE("Test writing order is BLK_MAX->BLK0", "[efuse]")
{
uint8_t new_key[32] = {33, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
30, 31};
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY4, &new_key, 256));
// If the order of writing blocks is wrong (ex. BLK0 -> BLK_MAX)
// then the write protection bit will be set early and the key was left un-updated.
TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY4));
TEST_ESP_OK(esp_efuse_batch_write_commit());
esp_efuse_utility_debug_dump_blocks();
uint8_t key[32] = { 0xEE };
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY4, &key, 256));
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
}
TEST_CASE("Test reading inside of batch mode in a nested way", "[efuse]")
{
uint8_t new_key[32] = {44, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 12, 14, 15, 16, 17, 18, 19,
20, 21, 22, 22, 24, 25, 26, 27, 28, 29,
30, 31};
uint8_t key[32] = { 0xEE };
esp_efuse_utility_reset();
esp_efuse_utility_erase_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY5, &new_key, 256));
TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY5));
ESP_LOGI(TAG, "Reading inside Batch mode, the key was not burn yet and it is empty");
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_batch_write_begin());
ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY5, &key, 256));
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_batch_write_commit());
esp_efuse_utility_debug_dump_blocks();
ESP_LOGI(TAG, "Reading inside Batch mode, the key is already set");
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_commit());
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_batch_write_cancel());
TEST_ESP_OK(esp_efuse_batch_write_begin());
TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_KEY2, &new_key, 256));
TEST_ESP_OK(esp_efuse_batch_write_commit());
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY2, &key, 256));
TEST_ASSERT_EQUAL_HEX8_ARRAY(new_key, key, sizeof(key));
esp_efuse_utility_debug_dump_blocks();
}
#endif // CONFIG_IDF_ENV_FPGA || CONFIG_EFUSE_VIRTUAL

View File

@@ -0,0 +1,388 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "esp_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_utility.h"
#include "sdkconfig.h"
__attribute__((unused)) static const char* TAG = "efuse_key_test";
#ifdef CONFIG_EFUSE_VIRTUAL
TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial state", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... \n", num_key - EFUSE_BLK_KEY0);
uint8_t key[32] = { 0xEE };
TEST_ESP_OK(esp_efuse_read_field_blob(esp_efuse_get_key(num_key), &key, sizeof(key) * 8));
TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_write(num_key));
TEST_ASSERT_EQUAL(ESP_EFUSE_KEY_PURPOSE_USER, esp_efuse_get_key_purpose(num_key));
TEST_ASSERT_FALSE(esp_efuse_get_keypurpose_dis_write(num_key));
esp_efuse_block_t key_block = EFUSE_BLK_MAX;
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, NULL));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, esp_efuse_find_unused_key_block());
printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... OK\n", num_key - EFUSE_BLK_KEY0);
}
}
#endif // CONFIG_EFUSE_VIRTUAL
// If using efuse is real, then turn off writing tests.
#if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key)
{
uint8_t rd_key[32] = { 0xEE };
esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(num_key);
TEST_ESP_OK(esp_efuse_read_field_blob(esp_efuse_get_key(num_key), &rd_key, sizeof(rd_key) * 8));
#ifndef CONFIG_IDF_ENV_FPGA
TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, sizeof(wr_key));
#endif // not CONFIG_IDF_ENV_FPGA
TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(num_key));
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 ||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 ||
#endif
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL ||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG ||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE ||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(num_key));
#if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
TEST_ASSERT_EACH_EQUAL_HEX8(0, rd_key, sizeof(rd_key));
#endif // CONFIG_IDF_ENV_FPGA && ! CONFIG_EFUSE_VIRTUAL
} else {
TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, sizeof(wr_key));
}
TEST_ASSERT_EQUAL(purpose, esp_efuse_get_key_purpose(num_key));
esp_efuse_purpose_t purpose2 = 0;
TEST_ESP_OK(esp_efuse_read_field_blob(esp_efuse_get_purpose_field(num_key), &purpose2, 4));
TEST_ASSERT_EQUAL(purpose, purpose2);
TEST_ASSERT_TRUE(esp_efuse_get_keypurpose_dis_write(num_key));
return ESP_OK;
}
void test_write_key(esp_efuse_block_t num_key, esp_efuse_purpose_t purpose) {
int id = num_key - EFUSE_BLK_KEY0;
printf("EFUSE_BLK_KEY%d, purpose=%d ... \n", id, purpose);
uint8_t wr_key[32];
for (int i = 0; i < sizeof(wr_key); i++) {
wr_key[i] = id + 1 + i;
}
TEST_ASSERT_TRUE(esp_efuse_key_block_unused(num_key));
TEST_ESP_OK(esp_efuse_write_key(num_key, purpose, &wr_key, sizeof(wr_key)));
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_key(num_key, purpose, &wr_key, sizeof(wr_key)));
TEST_ESP_OK(s_check_key(num_key, wr_key));
TEST_ASSERT_FALSE(esp_efuse_key_block_unused(num_key));
printf("EFUSE_BLK_KEY%d, purpose=%d ... OK\n", id, purpose);
}
#ifndef CONFIG_IDF_ENV_FPGA
TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]")
{
uint8_t rd_key[32] = { 0xEE };
int tmp_purpose = 0;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK3, tmp_purpose, &rd_key, sizeof(rd_key)));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK_KEY0, tmp_purpose, &rd_key, 33));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK10, tmp_purpose, &rd_key, sizeof(rd_key)));
for (esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_RESERVED; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) {
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_find_purpose(purpose, NULL));
for (esp_efuse_block_t num_key = (EFUSE_BLK_KEY_MAX - 1); num_key >= EFUSE_BLK_KEY0; --num_key) {
int id = num_key - EFUSE_BLK_KEY0;
TEST_ASSERT_EQUAL(id + 1, esp_efuse_count_unused_key_blocks());
test_write_key(num_key, purpose);
TEST_ASSERT_EQUAL(id, esp_efuse_count_unused_key_blocks());
esp_efuse_block_t key_block = EFUSE_BLK_KEY_MAX;
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose, &key_block));
TEST_ASSERT_EQUAL(num_key, key_block);
}
esp_efuse_utility_debug_dump_blocks();
}
}
#endif // not CONFIG_IDF_ENV_FPGA
TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
esp_efuse_purpose_t purpose [] = {
ESP_EFUSE_KEY_PURPOSE_USER,
ESP_EFUSE_KEY_PURPOSE_RESERVED,
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
#else
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
#endif
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL,
};
int max_keys = EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0;
for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
int id = num_key - EFUSE_BLK_KEY0;
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key, esp_efuse_count_unused_key_blocks());
test_write_key(num_key, purpose[id]);
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key - 1, esp_efuse_count_unused_key_blocks());
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose[id], NULL));
TEST_ASSERT_EQUAL(--max_keys, esp_efuse_count_unused_key_blocks());
}
esp_efuse_utility_debug_dump_blocks();
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test 2 esp_efuse_write_key for FPGA", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
esp_efuse_purpose_t purpose [] = {
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG,
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE,
ESP_EFUSE_KEY_PURPOSE_HMAC_UP,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
};
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, esp_efuse_find_unused_key_block());
int max_keys = EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0;
for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
int id = num_key - EFUSE_BLK_KEY0;
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key, esp_efuse_count_unused_key_blocks());
test_write_key(num_key, purpose[id]);
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key - 1, esp_efuse_count_unused_key_blocks());
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose[id], NULL));
TEST_ASSERT_EQUAL(--max_keys, esp_efuse_count_unused_key_blocks());
if (esp_efuse_count_unused_key_blocks()) {
TEST_ASSERT_EQUAL(num_key + 1, esp_efuse_find_unused_key_block());
} else {
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX, esp_efuse_find_unused_key_block());
}
}
esp_efuse_utility_debug_dump_blocks();
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test esp_efuse_write_keys", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
esp_efuse_block_t key_block = EFUSE_BLK_MAX;
enum { BLOCKS_NEEDED1 = 2 };
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
};
#else
esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
ESP_EFUSE_KEY_PURPOSE_RESERVED
};
#endif
uint8_t keys1[BLOCKS_NEEDED1][32] = {{0xEE}};
for (int num_key = 0; num_key < BLOCKS_NEEDED1; ++num_key) {
for (int i = 0; i < 32; ++i) {
keys1[num_key][i] = purpose1[num_key] + i + 1;
}
}
TEST_ESP_OK(esp_efuse_write_keys(purpose1, keys1, BLOCKS_NEEDED1));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[0], &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
TEST_ESP_OK(s_check_key(key_block, keys1[0]));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[1], &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY1, key_block);
TEST_ESP_OK(s_check_key(key_block, keys1[1]));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0 - 2, esp_efuse_count_unused_key_blocks());
enum { BLOCKS_NEEDED2 = 3 };
esp_efuse_purpose_t purpose2[BLOCKS_NEEDED2] = {
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
};
uint8_t keys2[BLOCKS_NEEDED2][32] = {{0xDD}};
for (int num_key = 0; num_key < BLOCKS_NEEDED2; ++num_key) {
for (int i = 0; i < 32; ++i) {
keys2[num_key][i] = purpose2[num_key] + i + 1;
}
}
TEST_ESP_OK(esp_efuse_write_keys(purpose2, keys2, BLOCKS_NEEDED2));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose2[0], &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY2, key_block);
TEST_ESP_OK(s_check_key(key_block, keys2[0]));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose2[1], &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY3, key_block);
TEST_ESP_OK(s_check_key(key_block, keys2[1]));
TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose2[2], &key_block));
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY4, key_block);
TEST_ESP_OK(s_check_key(key_block, keys2[2]));
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0 - 2 - 3, esp_efuse_count_unused_key_blocks());
printf("reset efuses on the FPGA board for the next test\n");
}
TEST_CASE("Test esp_efuse_write_keys for returned errors", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
enum { BLOCKS_NEEDED = 4 };
esp_efuse_purpose_t purpose[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
ESP_EFUSE_KEY_PURPOSE_MAX, // it leads ESP_ERR_INVALID_ARG in esp_efuse_write_keys
};
uint8_t keys[BLOCKS_NEEDED][32] = {{0xEE}};
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(NULL, keys, BLOCKS_NEEDED));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, NULL, BLOCKS_NEEDED));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) + 1));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED)); // ESP_EFUSE_KEY_PURPOSE_MAX is not a valid purpose.
TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks());
TEST_ESP_OK(esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED - 1));
TEST_ASSERT_EQUAL((EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) - (BLOCKS_NEEDED - 1), esp_efuse_count_unused_key_blocks());
unsigned unused_keys = esp_efuse_count_unused_key_blocks();
TEST_ESP_ERR(ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS, esp_efuse_write_keys(purpose, keys, unused_keys + 1));
}
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
TEST_CASE("Test revocation APIs", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(0));
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(1));
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(2));
TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(0));
TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(1));
TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(2));
// esp_efuse_get_digest_revoke(3); // assert
TEST_ESP_OK(esp_efuse_set_digest_revoke(0));
TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(0));
TEST_ESP_OK(esp_efuse_set_digest_revoke(1));
TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(1));
TEST_ESP_OK(esp_efuse_set_digest_revoke(2));
TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(2));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_set_digest_revoke(3));
TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(0));
TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(0));
TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(1));
TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(1));
TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(2));
TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(2));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_set_write_protect_of_digest_revoke(3));
}
TEST_CASE("Test set_write_protect_of_digest_revoke", "[efuse]")
{
esp_efuse_utility_reset();
esp_efuse_utility_update_virt_blocks();
esp_efuse_utility_debug_dump_blocks();
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(0));
TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(0));
TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(0));
TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(0));
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(1));
TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(1));
TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(1));
TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(1));
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(2));
TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(2));
TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(2));
TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(2));
TEST_ESP_OK(esp_efuse_set_digest_revoke(0));
TEST_ESP_OK(esp_efuse_set_digest_revoke(1));
TEST_ESP_OK(esp_efuse_set_digest_revoke(2));
#if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
// the write protection bits are set and the revocation bits will not be changed.
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(0));
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(1));
TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(2));
#else
TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(0));
TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(1));
TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(2));
#endif // CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
}
#endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
#endif // CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA

View File

@@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.generic
def test_efuse(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('*')
dut.expect_unity_test_output(timeout=200)

View File

@@ -0,0 +1,11 @@
# General options for additional checks
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
CONFIG_COMPILER_WARN_WRITE_STRINGS=y
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
CONFIG_COMPILER_STACK_CHECK=y
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_EFUSE_VIRTUAL=y