mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'feature/adds_funcs_to_read_efuses_from_cmake' into 'master'
esptool_py: Adds funcs to read eFuses from Cmake during a build stage Closes IDFGH-8890 See merge request espressif/esp-idf!21585
This commit is contained in:
commit
708a9047e8
47
components/esptool_py/espefuse.cmake
Normal file
47
components/esptool_py/espefuse.cmake
Normal file
@ -0,0 +1,47 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# Executes a espefuse.py command and returns a cleaned log
|
||||
function(espefuse_cmd cmd output_log)
|
||||
set(SERIAL_TOOL ${ESPEFUSEPY})
|
||||
if(${ESPEFUSEPY_OFFLINE})
|
||||
set(VIRT_OPTION "--virt")
|
||||
endif()
|
||||
set(SERIAL_TOOL_ARGS ${VIRT_OPTION} "--chip;${IDF_TARGET};${cmd}")
|
||||
set(SERIAL_TOOL_SILENT 1)
|
||||
include(${esptool_py_dir}/run_serial_tool.cmake)
|
||||
set(log ${SERIAL_TOOL_OUTPUT_LOG})
|
||||
|
||||
set(prefix_str " command ===")
|
||||
string(FIND ${log} ${prefix_str} pos)
|
||||
if(${pos} GREATER -1)
|
||||
string(LENGTH ${prefix_str} len_of_prefix_str)
|
||||
math(EXPR pos "${pos} + ${len_of_prefix_str}")
|
||||
string(SUBSTRING ${log} ${pos} -1 final_log)
|
||||
else()
|
||||
set(final_log ${log})
|
||||
endif()
|
||||
|
||||
set(${output_log} ${final_log} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Reads efuses "espefuse.py summary" and returns JSON string
|
||||
function(espefuse_get_json_summary json_str)
|
||||
espefuse_cmd("summary;--format;json" output_log)
|
||||
set(${json_str} ${output_log} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# See the esp-idf/docs/en/api-reference/system/efuse.rst "Get eFuses During Build".
|
||||
#
|
||||
# It takes the efuse json string and returns a value of property for a given efuse name
|
||||
function(espefuse_get_efuse result efuse_json efuse_name efuse_property)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.19.0")
|
||||
string(REGEX MATCH "\"${efuse_name}\":[ \t\n\r]*\{[^\}]*\}" cur_efuse ${efuse_json})
|
||||
string(REGEX MATCH "\"${efuse_property}\":[ \t\n\r]*\"?([^,\"]*)\"?," ret_value ${cur_efuse})
|
||||
set(${result} ${CMAKE_MATCH_1} PARENT_SCOPE)
|
||||
else()
|
||||
# The JSON feature has been supported by Cmake since 3.19.0
|
||||
string(JSON cur_efuse GET ${efuse_json} ${efuse_name})
|
||||
string(JSON ret_value GET ${cur_efuse} ${efuse_property})
|
||||
set(${result} ${ret_value} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
@ -494,3 +494,7 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
esptool_py_custom_target(flash project "${flash_deps}")
|
||||
endif()
|
||||
|
||||
# Adds espefuse functions for global use
|
||||
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
|
||||
include(${esptool_py_dir}/espefuse.cmake)
|
||||
|
@ -45,12 +45,20 @@ endif()
|
||||
|
||||
list(APPEND serial_tool_cmd ${SERIAL_TOOL_ARGS})
|
||||
|
||||
execute_process(COMMAND ${serial_tool_cmd}
|
||||
WORKING_DIRECTORY "${WORKING_DIRECTORY}"
|
||||
RESULT_VARIABLE result
|
||||
if(${SERIAL_TOOL_SILENT})
|
||||
execute_process(COMMAND ${serial_tool_cmd}
|
||||
WORKING_DIRECTORY "${WORKING_DIRECTORY}"
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE SERIAL_TOOL_OUTPUT_LOG
|
||||
)
|
||||
else()
|
||||
execute_process(COMMAND ${serial_tool_cmd}
|
||||
WORKING_DIRECTORY "${WORKING_DIRECTORY}"
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
endif()
|
||||
|
||||
if(${result})
|
||||
# No way to have CMake silently fail, unfortunately
|
||||
message(FATAL_ERROR "${SERIAL_TOOL} failed")
|
||||
message(FATAL_ERROR "${SERIAL_TOOL} failed. \n${SERIAL_TOOL_OUTPUT_LOG}")
|
||||
endif()
|
||||
|
@ -401,6 +401,53 @@ Thus, reading the eFuse ``USER_DATA`` block written as above gives the following
|
||||
// id = 0x01
|
||||
// b'001
|
||||
|
||||
Get eFuses During Build
|
||||
-----------------------
|
||||
|
||||
There is a way to get the state of eFuses at the build stage of the project. There are two cmake functions for this:
|
||||
|
||||
* ``espefuse_get_json_summary()`` - It calls the ``espefuse.py summary --format json`` command and returns a json string (it is not stored in a file).
|
||||
* ``espefuse_get_efuse()`` - It finds a given eFuse name in the json string and returns its property.
|
||||
|
||||
The json string has the following properties:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"MAC": {
|
||||
"bit_len": 48,
|
||||
"block": 0,
|
||||
"category": "identity",
|
||||
"description": "Factory MAC Address",
|
||||
"efuse_type": "bytes:6",
|
||||
"name": "MAC",
|
||||
"pos": 0,
|
||||
"readable": true,
|
||||
"value": "94:b9:7e:5a:6e:58 (CRC 0xe2 OK)",
|
||||
"word": 1,
|
||||
"writeable": true
|
||||
},
|
||||
}
|
||||
|
||||
These functions can be used from a top-level project ``CMakeLists.txt`` (:example_file:`get-started/hello_world/CMakeLists.txt`):
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# ...
|
||||
project(hello_world)
|
||||
|
||||
espefuse_get_json_summary(efuse_json)
|
||||
espefuse_get_efuse(ret_data ${efuse_json} "MAC" "value")
|
||||
message("MAC:" ${ret_data})
|
||||
|
||||
The format of the ``value`` property is the same as shown in ``espefuse.py summary``.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
MAC:94:b9:7e:5a:6e:58 (CRC 0xe2 OK)
|
||||
|
||||
There is an example test :example_file:`system/efuse/CMakeLists.txt` which adds a custom target ``efuse-summary``. This allows you to run the ``idf.py efuse-summary`` command to read the required eFuses (specified in the ``efuse_names`` list) at any time, not just at project build time.
|
||||
|
||||
Debug eFuse & Unit tests
|
||||
------------------------
|
||||
|
||||
|
@ -4,3 +4,19 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(efuse)
|
||||
|
||||
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
|
||||
set(efuse_names "MAC" "WR_DIS")
|
||||
add_custom_target(efuse-summary
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D "IDF_PATH=${IDF_PATH}"
|
||||
-D "esptool_py_dir=${esptool_py_dir}"
|
||||
-D "ESPEFUSEPY=${ESPEFUSEPY}"
|
||||
-D "ESPEFUSEPY_OFFLINE=${CONFIG_IDF_CI_BUILD}" # Only for CI tests. Do not establish a connection with the chip
|
||||
-D "IDF_TARGET=${IDF_TARGET}"
|
||||
-D "efuse_names=${efuse_names}"
|
||||
-P get_efuse_summary.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
USES_TERMINAL
|
||||
VERBATIM
|
||||
)
|
||||
|
8
examples/system/efuse/get_efuse_summary.cmake
Normal file
8
examples/system/efuse/get_efuse_summary.cmake
Normal file
@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include(${esptool_py_dir}/espefuse.cmake)
|
||||
espefuse_get_json_summary(efuse_json)
|
||||
foreach(name ${efuse_names})
|
||||
espefuse_get_efuse(ret_data ${efuse_json} ${name} "value")
|
||||
message(STATUS "FROM_CMAKE: ${name}: ${ret_data}")
|
||||
endforeach()
|
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import shutil
|
||||
import subprocess
|
||||
@ -71,3 +71,15 @@ def test_idf_build_with_env_var_sdkconfig_defaults(
|
||||
|
||||
with open(test_app_copy / 'sdkconfig') as fr:
|
||||
assert 'CONFIG_BT_ENABLED=y' in fr.read()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
@pytest.mark.test_app_copy('examples/system/efuse')
|
||||
def test_efuse_symmary_cmake_functions(
|
||||
idf_py: IdfPyFunc,
|
||||
monkeypatch: MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setenv('IDF_CI_BUILD', '1')
|
||||
output = idf_py('efuse-summary')
|
||||
assert 'FROM_CMAKE: MAC: 00:00:00:00:00:00' in output.stdout
|
||||
assert 'FROM_CMAKE: WR_DIS: 0' in output.stdout
|
||||
|
Loading…
x
Reference in New Issue
Block a user