forked from espressif/esp-idf
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
012fafb827 |
@@ -19,6 +19,14 @@ trim_trailing_whitespace = false
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
|
||||
[*/freertos/**]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[{*/freertos/**.S,**/FreeRTOSConfig.h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.pem]
|
||||
insert_final_newline = false
|
||||
|
||||
|
||||
2
.flake8
2
.flake8
@@ -146,8 +146,10 @@ exclude =
|
||||
components/json/cJSON,
|
||||
components/mbedtls/mbedtls,
|
||||
components/openthread/openthread,
|
||||
components/tinyusb,
|
||||
components/unity/unity,
|
||||
components/spiffs/spiffs,
|
||||
examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib,
|
||||
# autogenerated scripts
|
||||
components/protocomm/python/constants_pb2.py,
|
||||
components/protocomm/python/sec0_pb2.py,
|
||||
|
||||
197
.gitlab-ci.yml
197
.gitlab-ci.yml
@@ -13,7 +13,7 @@ stages:
|
||||
workflow:
|
||||
rules:
|
||||
# Disable those non-protected push triggered pipelines
|
||||
- if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_COMMIT_TAG !~ /^qa-test/ && $CI_PIPELINE_SOURCE == "push"'
|
||||
- if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_PIPELINE_SOURCE == "push"'
|
||||
when: never
|
||||
# when running merged result pipelines, it would create a temp commit id. use $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA instead of $CI_COMMIT_SHA.
|
||||
# Please use PIPELINE_COMMIT_SHA at all places that require a commit sha
|
||||
@@ -54,23 +54,31 @@ variables:
|
||||
BATCH_BUILD: "1"
|
||||
V: "0"
|
||||
CHECKOUT_REF_SCRIPT: "$CI_PROJECT_DIR/tools/ci/checkout_project_ref.py"
|
||||
PYTHON_VER: 3.7.10
|
||||
|
||||
CLANG_TIDY_RUNNER_PROJ: 2107 # idf/clang-tidy-runner
|
||||
IDF_BUILD_APPS_PROJ: 2818 # fuhanxi/idf-build-apps
|
||||
|
||||
# Docker images
|
||||
BOT_DOCKER_IMAGE_TAG: ":latest"
|
||||
|
||||
ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env-v5.0:4"
|
||||
AFL_FUZZER_TEST_IMAGE: "$CI_DOCKER_REGISTRY/afl-fuzzer-test-v5.0:4-2"
|
||||
CLANG_STATIC_ANALYSIS_IMAGE: "${CI_DOCKER_REGISTRY}/clang-static-analysis-v5.0:4-2"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.0:4-4"
|
||||
QEMU_IMAGE: "${CI_DOCKER_REGISTRY}/qemu-v5.0:4-20220802"
|
||||
TARGET_TEST_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.0:3"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.0:2-3"
|
||||
ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env-v5.0:2"
|
||||
AFL_FUZZER_TEST_IMAGE: "$CI_DOCKER_REGISTRY/afl-fuzzer-test-v5.0:2-1"
|
||||
CLANG_STATIC_ANALYSIS_IMAGE: "${CI_DOCKER_REGISTRY}/clang-static-analysis-v5.0:2-1"
|
||||
TARGET_TEST_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.0:2"
|
||||
QEMU_IMAGE: "${CI_DOCKER_REGISTRY}/qemu-v5.0:2-20210826"
|
||||
|
||||
SONARQUBE_SCANNER_IMAGE: "${CI_DOCKER_REGISTRY}/sonarqube-scanner:3"
|
||||
LINUX_SHELL_IMAGE: "${CI_DOCKER_REGISTRY}/linux-shells-v5.0:2"
|
||||
|
||||
PRE_COMMIT_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-pre-commit:1"
|
||||
# target test config file, used by assign test job
|
||||
CI_TARGET_TEST_CONFIG_FILE: "$CI_PROJECT_DIR/.gitlab/ci/target-test.yml"
|
||||
|
||||
# target test repo parameters
|
||||
TEST_ENV_CONFIG_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/qa/ci-test-runner-configs.git"
|
||||
CI_AUTO_TEST_SCRIPT_REPO_URL: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/qa/auto_test_script.git"
|
||||
CI_AUTO_TEST_SCRIPT_REPO_BRANCH: "ci/v4.1"
|
||||
|
||||
# cache python dependencies
|
||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||
@@ -81,7 +89,7 @@ variables:
|
||||
CI_PYTHON_CONSTRAINT_BRANCH: ""
|
||||
|
||||
# Update the filename for a specific ESP-IDF release. It is used only with CI_PYTHON_CONSTRAINT_BRANCH.
|
||||
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.0.txt"
|
||||
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.1.txt"
|
||||
|
||||
# Set this variable to repository name of a Python tool you wish to install and test in the context of ESP-IDF CI.
|
||||
# Keep the variable empty when not used.
|
||||
@@ -92,11 +100,6 @@ variables:
|
||||
# This is used only if CI_PYTHON_TOOL_REPO is not empty.
|
||||
CI_PYTHON_TOOL_BRANCH: ""
|
||||
|
||||
# Set this variable to specify the file name for the known failure cases.
|
||||
KNOWN_FAILURE_CASES_FILE_NAME: "5.0.txt"
|
||||
|
||||
IDF_CI_BUILD: 1
|
||||
|
||||
cache:
|
||||
# pull only for most of the use cases since it's cache dir.
|
||||
# Only set "push" policy for "upload_cache" stage jobs
|
||||
@@ -109,105 +112,140 @@ cache:
|
||||
- .cache/submodule_archives
|
||||
policy: pull
|
||||
|
||||
.common_before_scripts: &common-before_scripts |
|
||||
source tools/ci/utils.sh
|
||||
is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
|
||||
.setup_tools_unless_target_test: &setup_tools_unless_target_test |
|
||||
if [[ -n "$IDF_DONT_USE_MIRRORS" ]]; then
|
||||
export IDF_MIRROR_PREFIX_MAP=
|
||||
export IDF_MIRROR_PREFIX_MAP=
|
||||
fi
|
||||
|
||||
if echo "$CI_MERGE_REQUEST_LABELS" | egrep "^([^,\n\r]+,)*include_nightly_run(,[^,\n\r]+)*$"; then
|
||||
export INCLUDE_NIGHTLY_RUN="1"
|
||||
fi
|
||||
|
||||
# configure cmake related flags
|
||||
source tools/ci/configure_ci_environment.sh
|
||||
|
||||
# add extra python packages
|
||||
export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/esp_app_trace:$IDF_PATH/components/partition_table:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
|
||||
|
||||
.setup_tools_and_idf_python_venv: &setup_tools_and_idf_python_venv |
|
||||
# Since the version 3.21 CMake passes source files and include dirs to ninja using absolute paths.
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install cmake
|
||||
|
||||
# download constraint file for dev
|
||||
if [[ -n "$CI_PYTHON_CONSTRAINT_BRANCH" ]]; then
|
||||
wget -O /tmp/constraint.txt --header="Authorization:Bearer ${ESPCI_TOKEN}" ${GITLAB_HTTP_SERVER}/api/v4/projects/2581/repository/files/${CI_PYTHON_CONSTRAINT_FILE}/raw?ref=${CI_PYTHON_CONSTRAINT_BRANCH}
|
||||
mkdir -p ~/.espressif
|
||||
mv /tmp/constraint.txt ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
|
||||
fi
|
||||
|
||||
# Mirror
|
||||
if [[ -n "$IDF_DONT_USE_MIRRORS" ]]; then
|
||||
export IDF_MIRROR_PREFIX_MAP=
|
||||
fi
|
||||
|
||||
# install latest python packages
|
||||
# target test jobs
|
||||
if [[ "${CI_JOB_STAGE}" == "target_test" ]]; then
|
||||
# ttfw jobs
|
||||
if ! echo "${CI_JOB_NAME}" | egrep ".+_pytest_.+"; then
|
||||
run_cmd bash install.sh --enable-ci --enable-ttfw
|
||||
else
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest
|
||||
fi
|
||||
elif [[ "${CI_JOB_STAGE}" == "build_doc" ]]; then
|
||||
run_cmd bash install.sh --enable-ci --enable-docs
|
||||
elif [[ "${CI_JOB_STAGE}" == "build" ]]; then
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest
|
||||
else
|
||||
run_cmd bash install.sh --enable-ci
|
||||
fi
|
||||
|
||||
source ./export.sh
|
||||
|
||||
# Custom OpenOCD
|
||||
if [[ ! -z "$OOCD_DISTRO_URL" && "$CI_JOB_STAGE" == "target_test" ]]; then
|
||||
if [[ "$SETUP_TOOLS" == "1" || "$CI_JOB_STAGE" != "target_test" ]]; then
|
||||
tools/idf_tools.py --non-interactive install ${SETUP_TOOLS_LIST:-} && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1
|
||||
if [[ ! -z "$OOCD_DISTRO_URL" && "$CI_JOB_STAGE" == "target_test" ]]; then
|
||||
echo "Using custom OpenOCD from ${OOCD_DISTRO_URL}"
|
||||
wget $OOCD_DISTRO_URL
|
||||
ARCH_NAME=$(basename $OOCD_DISTRO_URL)
|
||||
tar -x -f $ARCH_NAME
|
||||
export OPENOCD_SCRIPTS=$PWD/openocd-esp32/share/openocd/scripts
|
||||
export PATH=$PWD/openocd-esp32/bin:$PATH
|
||||
fi
|
||||
fi
|
||||
|
||||
.download_test_python_contraint_file: &download_test_python_contraint_file |
|
||||
if [[ -n "$CI_PYTHON_CONSTRAINT_BRANCH" ]]; then
|
||||
wget -O /tmp/constraint.txt --header="Authorization:Bearer ${ESPCI_TOKEN}" ${GITLAB_HTTP_SERVER}/api/v4/projects/2581/repository/files/${CI_PYTHON_CONSTRAINT_FILE}/raw?ref=${CI_PYTHON_CONSTRAINT_BRANCH}
|
||||
mkdir -p ~/.espressif
|
||||
mv /tmp/constraint.txt ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
|
||||
fi
|
||||
|
||||
.download_test_python_tool: &download_test_python_tool |
|
||||
if [[ -n "$CI_PYTHON_TOOL_REPO" ]]; then
|
||||
git clone --quiet --depth=1 -b ${CI_PYTHON_TOOL_BRANCH} https://gitlab-ci-token:${ESPCI_TOKEN}@${GITLAB_HTTPS_HOST}/espressif/${CI_PYTHON_TOOL_REPO}.git
|
||||
pip install ./${CI_PYTHON_TOOL_REPO}
|
||||
rm -rf ${CI_PYTHON_TOOL_REPO}
|
||||
fi
|
||||
|
||||
.set_include_nightly_run: &set_include_nightly_run |
|
||||
if echo "$CI_MERGE_REQUEST_LABELS" | egrep "^([^,\n\r]+,)*include_nightly_run(,[^,\n\r]+)*$"; then
|
||||
export INCLUDE_NIGHTLY_RUN="1"
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- *common-before_scripts
|
||||
- *setup_tools_and_idf_python_venv
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
- source tools/ci/setup_python.sh
|
||||
- add_gitlab_ssh_keys
|
||||
- source tools/ci/configure_ci_environment.sh
|
||||
- *setup_tools_unless_target_test
|
||||
- fetch_submodules
|
||||
- *download_test_python_contraint_file
|
||||
- $IDF_PATH/tools/idf_tools.py install-python-env
|
||||
# install esptool globally, TODO: remove this, IDFCI-1207
|
||||
- pip install esptool -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
|
||||
- *download_test_python_tool
|
||||
|
||||
# used for check scripts which we want to run unconditionally
|
||||
.before_script_no_sync_submodule:
|
||||
before_script:
|
||||
- echo "Not setting up GitLab key, not fetching submodules"
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
- source tools/ci/setup_python.sh
|
||||
- source tools/ci/configure_ci_environment.sh
|
||||
- *download_test_python_contraint_file
|
||||
- $IDF_PATH/tools/idf_tools.py install-python-env
|
||||
|
||||
.before_script_minimal:
|
||||
before_script:
|
||||
- *common-before_scripts
|
||||
- echo "Only load utils.sh"
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
|
||||
.before_script_integration_test:
|
||||
before_script:
|
||||
# need to install esptool, needn't install idf python env
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
- source tools/ci/setup_python.sh
|
||||
- add_gitlab_ssh_keys
|
||||
- fetch_submodules
|
||||
# download the constraint file manually
|
||||
- mkdir -p ~/.espressif
|
||||
- wget -O ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE} --header="Authorization:Bearer ${ESPCI_TOKEN}" ${GITLAB_HTTP_SERVER}/api/v4/projects/2581/repository/files/${CI_PYTHON_CONSTRAINT_FILE}/raw
|
||||
- *download_test_python_contraint_file
|
||||
# TODO: remove this, IDFCI-1207
|
||||
- pip install esptool -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
|
||||
- *download_test_python_tool
|
||||
|
||||
.before_script_macos:
|
||||
before_script:
|
||||
# macos is running shell executor, which means it would use
|
||||
# the system installed /usr/local/bin/python3 by default.
|
||||
# Ensure pyenv and PYENV_VERSION installed
|
||||
- eval "$(pyenv init -)"
|
||||
- *common-before_scripts
|
||||
# On macOS, these tools need to be installed
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
- export IDF_TOOLS_PATH="${HOME}/.espressif_runner_${CI_RUNNER_ID}_${CI_CONCURRENT_ID}"
|
||||
- *download_test_python_contraint_file
|
||||
- $IDF_PATH/tools/idf_tools.py install-python-env
|
||||
# On macOS, these tools need to be installed
|
||||
- $IDF_PATH/tools/idf_tools.py --non-interactive install cmake ninja
|
||||
# This adds tools (compilers) and the version-specific Python environment to PATH
|
||||
- *setup_tools_and_idf_python_venv
|
||||
- *setup_tools_unless_target_test
|
||||
# Install packages required by CI scripts into IDF Python environment
|
||||
- pip install -r $IDF_PATH/tools/requirements/requirements.ci.txt
|
||||
- source tools/ci/configure_ci_environment.sh
|
||||
# Part of tools/ci/setup_python.sh; we don't use pyenv on macOS, so can't run the rest of the script.
|
||||
- export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
|
||||
- fetch_submodules
|
||||
|
||||
.before_script_pytest:
|
||||
before_script:
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
- source tools/ci/setup_python.sh
|
||||
- add_gitlab_ssh_keys
|
||||
- source tools/ci/configure_ci_environment.sh
|
||||
- *setup_tools_unless_target_test
|
||||
- fetch_submodules
|
||||
- *download_test_python_contraint_file
|
||||
# only need ci and pytest related packages, ttfw requirements would be mocked if not installed
|
||||
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest,ci
|
||||
- eval "$($IDF_PATH/tools/idf_tools.py export)" # use idf venv instead
|
||||
|
||||
.before_script_build_jobs:
|
||||
before_script:
|
||||
- *common-before_scripts
|
||||
- *setup_tools_and_idf_python_venv
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- *set_include_nightly_run
|
||||
- source tools/ci/setup_python.sh
|
||||
- add_gitlab_ssh_keys
|
||||
- source tools/ci/configure_ci_environment.sh
|
||||
- *setup_tools_unless_target_test
|
||||
- fetch_submodules
|
||||
- *download_test_python_contraint_file
|
||||
# only need ci and pytest related packages, ttfw requirements would be mocked if not installed
|
||||
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest,ci
|
||||
- eval "$($IDF_PATH/tools/idf_tools.py export)" # use idf venv instead
|
||||
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
|
||||
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS}
|
||||
|
||||
@@ -228,7 +266,6 @@ include:
|
||||
- '.gitlab/ci/pre_check.yml'
|
||||
- '.gitlab/ci/build.yml'
|
||||
- '.gitlab/ci/assign-test.yml'
|
||||
- '.gitlab/ci/integration_test.yml'
|
||||
- '.gitlab/ci/host-test.yml'
|
||||
- '.gitlab/ci/target-test.yml'
|
||||
- '.gitlab/ci/deploy.yml'
|
||||
|
||||
@@ -2,5 +2,208 @@
|
||||
#
|
||||
# https://docs.gitlab.com/ee/user/project/code_owners.html#the-syntax-of-code-owners-files
|
||||
#
|
||||
# If more than one rule matches a given file, the latest rule is used.
|
||||
# The file should be generally kept sorted, except when it is necessary
|
||||
# to use a different order due to the fact above. In that case, use
|
||||
# '# sort-order-reset' comment line to reset the sort order.
|
||||
#
|
||||
# Recipes for a few common cases:
|
||||
#
|
||||
# 1. Specific directory with all its contents:
|
||||
#
|
||||
# /components/app_trace/
|
||||
#
|
||||
# Note the trailing slash!
|
||||
#
|
||||
# 2. File with certain extension in any subdirectory of a certain directory:
|
||||
#
|
||||
# /examples/**/*.py
|
||||
#
|
||||
# This includes an *.py files in /examples/ directory as well.
|
||||
#
|
||||
# 3. Contents of a directory with a certain name, anywhere in the tree:
|
||||
#
|
||||
# test_*_host/
|
||||
#
|
||||
# Will match everything under components/efuse/test_efuse_host/,
|
||||
# components/heap/test_multi_heap_host/, components/lwip/test_afl_host/, etc.
|
||||
#
|
||||
# 4. Same as above, except limited to a specific place in the tree:
|
||||
#
|
||||
# /components/esp32*/
|
||||
#
|
||||
# Matches everything under /components/esp32, /components/esp32s2, etc.
|
||||
# Doesn't match /tools/some-test/components/esp32s5.
|
||||
#
|
||||
# 5. Specific file:
|
||||
#
|
||||
# /tools/tools.json
|
||||
#
|
||||
# 6. File with a certain name anywhere in the tree
|
||||
#
|
||||
# .gitignore
|
||||
#
|
||||
|
||||
* @esp-idf-codeowners/all-maintainers
|
||||
* @esp-idf-codeowners/other
|
||||
|
||||
/.* @esp-idf-codeowners/tools
|
||||
/.github/workflows/ @esp-idf-codeowners/ci
|
||||
/.gitlab-ci.yml @esp-idf-codeowners/ci
|
||||
/.gitlab/ci/ @esp-idf-codeowners/ci
|
||||
/.pre-commit-config.yaml @esp-idf-codeowners/ci
|
||||
/.readthedocs.yml @esp-idf-codeowners/docs
|
||||
/CMakeLists.txt @esp-idf-codeowners/build-config
|
||||
/CONTRIBUTING.md @esp-idf-codeowners/docs
|
||||
/Kconfig @esp-idf-codeowners/build-config
|
||||
/README*.md @esp-idf-codeowners/docs
|
||||
/SUPPORT_POLICY*.md @esp-idf-codeowners/docs
|
||||
/add_path.sh @esp-idf-codeowners/tools
|
||||
/conftest.py @esp-idf-codeowners/ci
|
||||
/export.* @esp-idf-codeowners/tools
|
||||
/install.* @esp-idf-codeowners/tools
|
||||
/pytest.ini @esp-idf-codeowners/ci
|
||||
/sdkconfig.rename @esp-idf-codeowners/build-config
|
||||
/sonar-project.properties @esp-idf-codeowners/ci
|
||||
|
||||
# sort-order-reset
|
||||
|
||||
/components/app_trace/ @esp-idf-codeowners/tools
|
||||
/components/app_update/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||
/components/bootloader*/ @esp-idf-codeowners/system @esp-idf-codeowners/security
|
||||
/components/bootloader_support/bootloader_flash/ @esp-idf-codeowners/peripherals
|
||||
/components/bt/ @esp-idf-codeowners/bluetooth
|
||||
/components/cmock/ @esp-idf-codeowners/system
|
||||
/components/console/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities/console
|
||||
/components/cxx/ @esp-idf-codeowners/system
|
||||
/components/driver/ @esp-idf-codeowners/peripherals
|
||||
/components/efuse/ @esp-idf-codeowners/system
|
||||
/components/esp_adc/ @esp-idf-codeowners/peripherals
|
||||
/components/esp_common/ @esp-idf-codeowners/system
|
||||
/components/esp_eth/ @esp-idf-codeowners/network
|
||||
/components/esp_event/ @esp-idf-codeowners/system
|
||||
/components/esp_gdbstub/ @esp-idf-codeowners/tools
|
||||
/components/esp_hid/ @esp-idf-codeowners/bluetooth
|
||||
/components/esp_http_client/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_http_server/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_https_ota/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_https_server/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_hw_support/ @esp-idf-codeowners/system @esp-idf-codeowners/peripherals
|
||||
/components/esp_lcd/ @esp-idf-codeowners/peripherals
|
||||
/components/esp_local_ctrl/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_netif/ @esp-idf-codeowners/network
|
||||
/components/esp_phy/ @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi @esp-idf-codeowners/ieee802154
|
||||
/components/esp_pm/ @esp-idf-codeowners/power-management @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi
|
||||
/components/esp_psram/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/system
|
||||
/components/esp_ringbuf/ @esp-idf-codeowners/system
|
||||
/components/esp_rom/ @esp-idf-codeowners/system @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi
|
||||
/components/esp_serial_slave_link/ @esp-idf-codeowners/peripherals
|
||||
/components/esp_system/ @esp-idf-codeowners/system
|
||||
/components/esp_timer/ @esp-idf-codeowners/system
|
||||
/components/esp-tls/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_wifi/ @esp-idf-codeowners/wifi
|
||||
/components/espcoredump/ @esp-idf-codeowners/tools
|
||||
/components/esptool_py/ @esp-idf-codeowners/tools
|
||||
/components/fatfs/ @esp-idf-codeowners/storage
|
||||
/components/fatfs/**/*.py @esp-idf-codeowners/tools
|
||||
/components/freertos/ @esp-idf-codeowners/system
|
||||
/components/hal/ @esp-idf-codeowners/peripherals
|
||||
/components/heap/ @esp-idf-codeowners/system
|
||||
/components/http_parser/ @esp-idf-codeowners/app-utilities
|
||||
/components/idf_test/ @esp-idf-codeowners/ci
|
||||
/components/ieee802154/ @esp-idf-codeowners/ieee802154
|
||||
/components/json/ @esp-idf-codeowners/app-utilities
|
||||
/components/linux/ @esp-idf-codeowners/system
|
||||
/components/log/ @esp-idf-codeowners/system
|
||||
/components/lwip/ @esp-idf-codeowners/lwip
|
||||
/components/mbedtls/ @esp-idf-codeowners/app-utilities/mbedtls @esp-idf-codeowners/security
|
||||
/components/mqtt/ @esp-idf-codeowners/network
|
||||
/components/newlib/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
||||
/components/nvs_flash/ @esp-idf-codeowners/storage
|
||||
/components/openthread/ @esp-idf-codeowners/ieee802154
|
||||
/components/partition_table/ @esp-idf-codeowners/system
|
||||
/components/perfmon/ @esp-idf-codeowners/tools
|
||||
/components/protobuf-c/ @esp-idf-codeowners/app-utilities
|
||||
/components/protocomm/ @esp-idf-codeowners/app-utilities/provisioning
|
||||
/components/pthread/ @esp-idf-codeowners/system
|
||||
/components/riscv/ @esp-idf-codeowners/system
|
||||
/components/sdmmc/ @esp-idf-codeowners/storage
|
||||
/components/soc/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/system
|
||||
/components/spi_flash/ @esp-idf-codeowners/peripherals
|
||||
/components/spiffs/ @esp-idf-codeowners/storage
|
||||
/components/tcp_transport/ @esp-idf-codeowners/network
|
||||
/components/tinyusb/ @esp-idf-codeowners/peripherals/usb
|
||||
/components/touch_element/ @esp-idf-codeowners/peripherals
|
||||
/components/ulp/ @esp-idf-codeowners/system
|
||||
/components/unity/ @esp-idf-codeowners/ci
|
||||
/components/usb/ @esp-idf-codeowners/peripherals/usb
|
||||
/components/vfs/ @esp-idf-codeowners/storage
|
||||
/components/wear_levelling/ @esp-idf-codeowners/storage
|
||||
/components/wifi_provisioning/ @esp-idf-codeowners/app-utilities/provisioning
|
||||
/components/wpa_supplicant/ @esp-idf-codeowners/wifi
|
||||
/components/xtensa/ @esp-idf-codeowners/system
|
||||
|
||||
/docs/ @esp-idf-codeowners/docs
|
||||
/docs/**/api-reference/bluetooth/ @esp-idf-codeowners/bluetooth
|
||||
/docs/**/api-reference/network/ @esp-idf-codeowners/network
|
||||
/docs/**/api-reference/peripherals/ @esp-idf-codeowners/peripherals
|
||||
/docs/**/api-reference/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
/docs/**/api-reference/provisioning/ @esp-idf-codeowners/app-utilities/provisioning
|
||||
/docs/**/api-reference/storage/ @esp-idf-codeowners/storage
|
||||
/docs/**/api-reference/system/ @esp-idf-codeowners/system
|
||||
/docs/**/security/ @esp-idf-codeowners/security
|
||||
/docs/**/migration-guides/ @esp-idf-codeowners/docs @esp-idf-codeowners/all-maintainers
|
||||
|
||||
/examples/README.md @esp-idf-codeowners/docs @esp-idf-codeowners/ci
|
||||
/examples/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||
/examples/bluetooth/ @esp-idf-codeowners/bluetooth
|
||||
/examples/build_system/ @esp-idf-codeowners/build-config
|
||||
/examples/common_components/ @esp-idf-codeowners/system
|
||||
/examples/custom_bootloader/ @esp-idf-codeowners/system
|
||||
/examples/cxx/ @esp-idf-codeowners/system
|
||||
/examples/ethernet/ @esp-idf-codeowners/network
|
||||
/examples/get-started/ @esp-idf-codeowners/system
|
||||
/examples/mesh/ @esp-idf-codeowners/wifi
|
||||
/examples/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi
|
||||
/examples/openthread/ @esp-idf-codeowners/ieee802154
|
||||
/examples/peripherals/ @esp-idf-codeowners/peripherals
|
||||
/examples/peripherals/usb/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/peripherals/usb
|
||||
/examples/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
/examples/provisioning/ @esp-idf-codeowners/app-utilities/provisioning
|
||||
/examples/security/ @esp-idf-codeowners/security
|
||||
/examples/storage/ @esp-idf-codeowners/storage
|
||||
/examples/system/ @esp-idf-codeowners/system
|
||||
/examples/system/ota/ @esp-idf-codeowners/app-utilities
|
||||
/examples/wifi/ @esp-idf-codeowners/wifi
|
||||
/examples/zigbee/ @esp-idf-codeowners/ieee802154
|
||||
|
||||
/tools/ @esp-idf-codeowners/tools
|
||||
/tools/ble/ @esp-idf-codeowners/app-utilities
|
||||
/tools/catch/ @esp-idf-codeowners/ci
|
||||
/tools/ci/ @esp-idf-codeowners/ci
|
||||
/tools/cmake/ @esp-idf-codeowners/build-config
|
||||
/tools/esp_prov/ @esp-idf-codeowners/app-utilities
|
||||
/tools/idf_size_yaml/ @esp-idf-codeowners/peripherals
|
||||
/tools/kconfig*/ @esp-idf-codeowners/build-config
|
||||
/tools/ldgen/ @esp-idf-codeowners/build-config
|
||||
/tools/mass_mfg/ @esp-idf-codeowners/app-utilities
|
||||
/tools/mocks/ @esp-idf-codeowners/system
|
||||
/tools/test_apps/README.md @esp-idf-codeowners/docs @esp-idf-codeowners/ci
|
||||
|
||||
## Note: owners here should be the same as the owners for the same example subdir, above
|
||||
/tools/test_apps/build_system/ @esp-idf-codeowners/build-config
|
||||
/tools/test_apps/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
/tools/test_apps/security/ @esp-idf-codeowners/security
|
||||
/tools/test_apps/system/ @esp-idf-codeowners/system
|
||||
|
||||
/tools/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||
|
||||
/tools/unit-test-app/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
||||
|
||||
# sort-order-reset
|
||||
|
||||
/components/**/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||
|
||||
# ignore lists
|
||||
/tools/ci/check_copyright_config.yaml @esp-idf-codeowners/all-maintainers
|
||||
/tools/ci/check_copyright_ignore.txt @esp-idf-codeowners/all-maintainers
|
||||
/tools/ci/mypy_ignore_list.txt @esp-idf-codeowners/tools
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
- [Shell Script Related](#shell-script-related)
|
||||
- [Manifest File to Control the Build/Test apps](#manifest-file-to-control-the-buildtest-apps)
|
||||
- [Grammar](#grammar)
|
||||
- [Operands](#operands)
|
||||
- [Operators](#operators)
|
||||
- [Limitation:](#limitation)
|
||||
- [How does it work?](#how-does-it-work)
|
||||
- [Example](#example)
|
||||
|
||||
## General Workflow
|
||||
|
||||
@@ -111,7 +116,7 @@ curl -X POST --header "PRIVATE-TOKEN: [YOUR PERSONAL ACCESS TOKEN]" [GITLAB_SERV
|
||||
```yaml
|
||||
check_docs_lang_sync:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
- .rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
@@ -139,11 +144,10 @@ check if there's a suitable `.if-<if-anchor-you-need>` anchor
|
||||
1. if there is, create a rule following [`rules` Template Naming Rules](#rules-template-naming-rules).For detail information, please refer to [GitLab Documentation `rules-if`](https://docs.gitlab.com/ee/ci/yaml/README.html#rulesif). Here's an example.
|
||||
|
||||
```yaml
|
||||
.rules:patterns:python-files:
|
||||
.rules:dev:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-trigger
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-python-files
|
||||
```
|
||||
|
||||
2. if there isn't
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
- assign_test
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "none"
|
||||
CI_TARGET_TEST_CONFIG_FILE: "$CI_PROJECT_DIR/.gitlab/ci/target-test.yml"
|
||||
artifacts:
|
||||
paths:
|
||||
- ${TEST_DIR}/test_configs/
|
||||
@@ -81,3 +80,30 @@ assign_unit_test:
|
||||
variables:
|
||||
TEST_TYPE: unit_test
|
||||
TEST_DIR: components/idf_test/unit_test
|
||||
|
||||
assign_integration_test:
|
||||
extends:
|
||||
- .assign_test_template
|
||||
- .rules:test:integration_test
|
||||
needs:
|
||||
- build_ssc_esp32
|
||||
- build_ssc_esp32c3
|
||||
artifacts:
|
||||
paths:
|
||||
- $TEST_DIR/test_configs
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
TEST_DIR: ${CI_PROJECT_DIR}/tools/ci/integration_test
|
||||
BUILD_DIR: ${CI_PROJECT_DIR}/SSC/ssc_bin
|
||||
INTEGRATION_TEST_CASE_PATH: "${CI_PROJECT_DIR}/auto_test_script/TestCaseFiles"
|
||||
ASSIGN_TEST_CASE_SCRIPT: "${CI_PROJECT_DIR}/auto_test_script/bin/CIAssignTestCases.py"
|
||||
PYTHONPATH: ${CI_PROJECT_DIR}/auto_test_script/packages
|
||||
PYTHON_VER: 3.7.7
|
||||
script:
|
||||
# clone test script to assign tests
|
||||
# can not retry if downing git lfs files failed, so using empty_branch first.
|
||||
- retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch
|
||||
- retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH}
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only
|
||||
# assign integration test cases
|
||||
- python ${ASSIGN_TEST_CASE_SCRIPT} -t ${INTEGRATION_TEST_CASE_PATH} -c $CI_TARGET_TEST_CONFIG_FILE -b ${BUILD_DIR} -o $TEST_DIR/test_configs
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
tags:
|
||||
- build
|
||||
variables:
|
||||
SIZE_INFO_LOCATION: "$CI_PROJECT_DIR/size_info.txt"
|
||||
# Enable ccache for all build jobs. See configure_ci_environment.sh for more ccache related settings.
|
||||
IDF_CCACHE_ENABLE: "1"
|
||||
after_script:
|
||||
@@ -11,105 +12,35 @@
|
||||
- test "$CI_CCACHE_STATS" == 1 && test -n "$(which ccache)" && ccache --show-stats || true
|
||||
dependencies: []
|
||||
|
||||
.build_cmake_template:
|
||||
.build_pytest_template:
|
||||
extends:
|
||||
- .build_template
|
||||
- .before_script_build_jobs
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
tags:
|
||||
- build
|
||||
# build only on shiny servers since shiny storage server is at the same location
|
||||
- shiny
|
||||
artifacts:
|
||||
paths:
|
||||
- "**/build*/size.json"
|
||||
- "**/build*/build_log.txt"
|
||||
- "**/build*/*.bin"
|
||||
# upload to s3 server to save the artifacts size
|
||||
# - "**/build*/*.map"
|
||||
# ttfw tests require elf files
|
||||
- "**/build*/*.elf"
|
||||
- "**/build*/flasher_args.json"
|
||||
- "**/build*/flash_project_args"
|
||||
- "**/build*/config/sdkconfig.json"
|
||||
# ttfw tests require sdkconfig file
|
||||
- "**/build*/sdkconfig"
|
||||
- "**/build*/bootloader/*.bin"
|
||||
- "**/build*/partition_table/*.bin"
|
||||
- list_job_*.json
|
||||
- size_info.txt
|
||||
# unit test specific
|
||||
- components/idf_test/unit_test/*.yml
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
after_script:
|
||||
# Show ccache statistics if enabled globally
|
||||
- test "$CI_CCACHE_STATS" == 1 && test -n "$(which ccache)" && ccache --show-stats || true
|
||||
# upload the binary files to s3 server
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:upload_binaries_to_s3_server[collapsed=true]\r\e[0KUploading binaries to s3 Server"
|
||||
- shopt -s globstar
|
||||
# use || true to bypass the no-file error
|
||||
- zip ${CI_JOB_ID}.zip **/build*/*.bin || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/*.elf || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/*.map || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/flasher_args.json || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/flash_project_args || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/config/sdkconfig.json || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/sdkconfig || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/bootloader/*.bin || true
|
||||
- zip ${CI_JOB_ID}.zip **/build*/partition_table/*.bin || true
|
||||
- mc alias set shiny-s3 ${SHINY_S3_SERVER} ${SHINY_S3_ACCESS_KEY} ${SHINY_S3_SECRET_KEY}
|
||||
- mc cp ${CI_JOB_ID}.zip shiny-s3/idf-artifacts/${CI_PIPELINE_ID}/${CI_JOB_ID}.zip
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:upload_binaries_to_s3_server\r\e[0K"
|
||||
- echo "Please download the full binary files (including *.elf and *.map files) from the following share link"
|
||||
# would be clean up after 4 days
|
||||
- mc share download shiny-s3/idf-artifacts/${CI_PIPELINE_ID}/${CI_JOB_ID}.zip --expire=96h
|
||||
script:
|
||||
# CI specific options start from "--collect-size-info xxx". could ignore when running locally
|
||||
- run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v
|
||||
-t $IDF_TARGET
|
||||
--copy-sdkconfig
|
||||
--collect-size-info size_info.txt
|
||||
--collect-app-info list_job_${CI_NODE_INDEX:-1}.json
|
||||
--parallel-count ${CI_NODE_TOTAL:-1}
|
||||
--parallel-index ${CI_NODE_INDEX:-1}
|
||||
--extra-preserve-dirs
|
||||
examples/bluetooth/esp_ble_mesh/ble_mesh_console
|
||||
examples/bluetooth/hci/controller_hci_uart_esp32
|
||||
examples/wifi/iperf
|
||||
|
||||
.build_pytest_template:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .before_script_build_jobs
|
||||
artifacts:
|
||||
paths:
|
||||
- "**/build*/size.json"
|
||||
- "**/build*/build_log.txt"
|
||||
- "**/build*/*.bin"
|
||||
# upload to s3 server to save the artifacts size
|
||||
# - "**/build*/*.map"
|
||||
# - "**/build*/*.elf"
|
||||
- "**/build*/*.map"
|
||||
- "**/build*/flasher_args.json"
|
||||
- "**/build*/flash_project_args"
|
||||
- "**/build*/config/sdkconfig.json"
|
||||
- "**/build*/bootloader/*.bin"
|
||||
- "**/build*/bootloader/*.elf"
|
||||
- "**/build*/partition_table/*.bin"
|
||||
- "**/build*/project_description.json"
|
||||
- list_job_*.json
|
||||
- size_info.txt
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
expire_in: 3 days
|
||||
script:
|
||||
# CI specific options start from "--collect-size-info xxx". could ignore when running locally
|
||||
- run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v
|
||||
-t $IDF_TARGET
|
||||
--pytest-apps
|
||||
--collect-size-info size_info.txt
|
||||
--collect-size-info $SIZE_INFO_LOCATION
|
||||
--parallel-count ${CI_NODE_TOTAL:-1}
|
||||
--parallel-index ${CI_NODE_INDEX:-1}
|
||||
|
||||
@@ -117,7 +48,7 @@ build_pytest_examples_esp32:
|
||||
extends:
|
||||
- .build_pytest_template
|
||||
- .rules:build:example_test-esp32
|
||||
parallel: 4
|
||||
parallel: 3
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
TEST_DIR: examples
|
||||
@@ -135,7 +66,7 @@ build_pytest_examples_esp32s3:
|
||||
extends:
|
||||
- .build_pytest_template
|
||||
- .rules:build:example_test-esp32s3
|
||||
parallel: 4
|
||||
parallel: 3
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
TEST_DIR: examples
|
||||
@@ -170,7 +101,6 @@ build_pytest_components_esp32s2:
|
||||
extends:
|
||||
- .build_pytest_template
|
||||
- .rules:build:component_ut-esp32s2
|
||||
parallel: 2
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
TEST_DIR: components
|
||||
@@ -179,7 +109,6 @@ build_pytest_components_esp32s3:
|
||||
extends:
|
||||
- .build_pytest_template
|
||||
- .rules:build:component_ut-esp32s3
|
||||
parallel: 2
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
TEST_DIR: components
|
||||
@@ -188,7 +117,6 @@ build_pytest_components_esp32c3:
|
||||
extends:
|
||||
- .build_pytest_template
|
||||
- .rules:build:component_ut-esp32c3
|
||||
parallel: 2
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
TEST_DIR: components
|
||||
@@ -210,35 +138,14 @@ build_non_test_components_apps:
|
||||
# CI specific options start from "--collect-size-info xxx". could ignore when running locally
|
||||
- run_cmd python tools/ci/ci_build_apps.py $COMPONENT_UT_DIRS -v
|
||||
-t all
|
||||
--collect-size-info size_info.txt
|
||||
--collect-size-info $SIZE_INFO_LOCATION
|
||||
--collect-app-info list_job_${CI_NODE_INDEX:-1}.json
|
||||
--parallel-count ${CI_NODE_TOTAL:-1}
|
||||
--parallel-index ${CI_NODE_INDEX:-1}
|
||||
|
||||
.build_pytest_test_apps_template:
|
||||
extends: .build_pytest_template
|
||||
artifacts:
|
||||
paths:
|
||||
- "**/build*/size.json"
|
||||
- "**/build*/build_log.txt"
|
||||
- "**/build*/*.bin"
|
||||
# upload to s3 server to save the artifacts size
|
||||
# - "**/build*/*.map"
|
||||
# pytest test apps requires elf files for coredump tests
|
||||
- "**/build*/*.elf"
|
||||
- "**/build*/flasher_args.json"
|
||||
- "**/build*/flash_project_args"
|
||||
- "**/build*/config/sdkconfig.json"
|
||||
- "**/build*/bootloader/*.bin"
|
||||
- "**/build*/partition_table/*.bin"
|
||||
- list_job_*.json
|
||||
- size_info.txt
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
|
||||
build_pytest_test_apps_esp32:
|
||||
extends:
|
||||
- .build_pytest_test_apps_template
|
||||
- .build_pytest_template
|
||||
- .rules:build:custom_test-esp32
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
@@ -246,7 +153,7 @@ build_pytest_test_apps_esp32:
|
||||
|
||||
build_pytest_test_apps_esp32s2:
|
||||
extends:
|
||||
- .build_pytest_test_apps_template
|
||||
- .build_pytest_template
|
||||
- .rules:build:custom_test-esp32s2
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
@@ -254,7 +161,7 @@ build_pytest_test_apps_esp32s2:
|
||||
|
||||
build_pytest_test_apps_esp32s3:
|
||||
extends:
|
||||
- .build_pytest_test_apps_template
|
||||
- .build_pytest_template
|
||||
- .rules:build:custom_test-esp32s3
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
@@ -262,7 +169,7 @@ build_pytest_test_apps_esp32s3:
|
||||
|
||||
build_pytest_test_apps_esp32c3:
|
||||
extends:
|
||||
- .build_pytest_test_apps_template
|
||||
- .build_pytest_template
|
||||
- .rules:build:custom_test-esp32c3
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
@@ -270,7 +177,7 @@ build_pytest_test_apps_esp32c3:
|
||||
|
||||
build_pytest_test_apps_esp32c2:
|
||||
extends:
|
||||
- .build_pytest_test_apps_template
|
||||
- .build_pytest_template
|
||||
- .rules:build:custom_test-esp32c2
|
||||
variables:
|
||||
IDF_TARGET: esp32c2
|
||||
@@ -315,19 +222,65 @@ fast_template_app:
|
||||
BUILD_COMMAND_ARGS: "-p"
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
.build_ssc_template:
|
||||
extends:
|
||||
- .build_template
|
||||
- .rules:build:integration_test
|
||||
artifacts:
|
||||
paths:
|
||||
- SSC/ssc_bin
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- retry_failed git clone $SSC_REPOSITORY
|
||||
- python $CHECKOUT_REF_SCRIPT SSC SSC
|
||||
- cd SSC
|
||||
- MAKEFLAGS= ./ci_build_ssc.sh $TARGET_NAME
|
||||
|
||||
build_ssc_esp32:
|
||||
extends: .build_ssc_template
|
||||
parallel: 3
|
||||
variables:
|
||||
TARGET_NAME: "ESP32"
|
||||
|
||||
build_ssc_esp32s2:
|
||||
extends: .build_ssc_template
|
||||
parallel: 2
|
||||
variables:
|
||||
TARGET_NAME: "ESP32S2"
|
||||
|
||||
build_ssc_esp32c2:
|
||||
extends: .build_ssc_template
|
||||
parallel: 2
|
||||
variables:
|
||||
TARGET_NAME: "ESP32C2"
|
||||
|
||||
build_ssc_esp32c3:
|
||||
extends: .build_ssc_template
|
||||
parallel: 3
|
||||
variables:
|
||||
TARGET_NAME: "ESP32C3"
|
||||
|
||||
build_ssc_esp32s3:
|
||||
extends: .build_ssc_template
|
||||
parallel: 3
|
||||
variables:
|
||||
TARGET_NAME: "ESP32S3"
|
||||
|
||||
.build_esp_idf_tests_cmake_template:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .build_template
|
||||
- .before_script_build_jobs
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
artifacts:
|
||||
paths:
|
||||
- "**/build*/size.json"
|
||||
- "**/build*/build_log.txt"
|
||||
- "**/build*/*.bin"
|
||||
# upload to s3 server to save the artifacts size
|
||||
# - "**/build*/*.map"
|
||||
# ttfw tests require elf files
|
||||
- "**/build*/*.elf"
|
||||
- "**/build*/*.map"
|
||||
- "**/build*/flasher_args.json"
|
||||
- "**/build*/flash_project_args"
|
||||
- "**/build*/config/sdkconfig.json"
|
||||
@@ -335,10 +288,12 @@ fast_template_app:
|
||||
- "**/build*/bootloader/*.bin"
|
||||
- "**/build*/partition_table/*.bin"
|
||||
- list_job_*.json
|
||||
- size_info.txt
|
||||
- $SIZE_INFO_LOCATION
|
||||
- components/idf_test/unit_test/*.yml
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
LDGEN_CHECK_MAPPING: 1
|
||||
script:
|
||||
# CI specific options start from "--collect-size-info xxx". could ignore when running locally
|
||||
- run_cmd python tools/ci/ci_build_apps.py tools/unit-test-app -v
|
||||
@@ -346,7 +301,7 @@ fast_template_app:
|
||||
--config "configs/*="
|
||||
--copy-sdkconfig
|
||||
--preserve-all
|
||||
--collect-size-info size_info.txt
|
||||
--collect-size-info $SIZE_INFO_LOCATION
|
||||
--collect-app-info list_job_${CI_NODE_INDEX:-1}.json
|
||||
--parallel-count ${CI_NODE_TOTAL:-1}
|
||||
--parallel-index ${CI_NODE_INDEX:-1}
|
||||
@@ -389,11 +344,52 @@ build_esp_idf_tests_cmake_esp32c3:
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
|
||||
.build_cmake_template:
|
||||
extends:
|
||||
- .build_template
|
||||
- .before_script_build_jobs
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
variables:
|
||||
LDGEN_CHECK_MAPPING: 1
|
||||
artifacts:
|
||||
paths:
|
||||
- "**/build*/size.json"
|
||||
- "**/build*/build_log.txt"
|
||||
- "**/build*/*.bin"
|
||||
- "**/build*/*.elf"
|
||||
- "**/build*/*.map"
|
||||
- "**/build*/flasher_args.json"
|
||||
- "**/build*/flash_project_args"
|
||||
- "**/build*/config/sdkconfig.json"
|
||||
- "**/build*/sdkconfig"
|
||||
- "**/build*/bootloader/*.bin"
|
||||
- "**/build*/partition_table/*.bin"
|
||||
- list_job_*.json
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
script:
|
||||
# CI specific options start from "--collect-size-info xxx". could ignore when running locally
|
||||
- run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v
|
||||
-t $IDF_TARGET
|
||||
--copy-sdkconfig
|
||||
--collect-size-info $SIZE_INFO_LOCATION
|
||||
--collect-app-info list_job_${CI_NODE_INDEX:-1}.json
|
||||
--parallel-count ${CI_NODE_TOTAL:-1}
|
||||
--parallel-index ${CI_NODE_INDEX:-1}
|
||||
--extra-preserve-dirs
|
||||
examples/bluetooth/esp_ble_mesh/ble_mesh_console
|
||||
examples/bluetooth/hci/controller_hci_uart_esp32
|
||||
examples/wifi/iperf
|
||||
|
||||
build_examples_cmake_esp32:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32
|
||||
parallel: 9
|
||||
parallel: 12
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
TEST_DIR: examples
|
||||
@@ -402,7 +398,7 @@ build_examples_cmake_esp32s2:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32s2
|
||||
parallel: 6
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
TEST_DIR: examples
|
||||
@@ -411,7 +407,7 @@ build_examples_cmake_esp32s3:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32s3
|
||||
parallel: 7
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
TEST_DIR: examples
|
||||
@@ -420,7 +416,7 @@ build_examples_cmake_esp32c2:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32c2
|
||||
parallel: 4
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32c2
|
||||
TEST_DIR: examples
|
||||
@@ -429,11 +425,19 @@ build_examples_cmake_esp32c3:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32c3
|
||||
parallel: 6
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
TEST_DIR: examples
|
||||
|
||||
build_examples_cmake_esp32h2:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32h2
|
||||
variables:
|
||||
IDF_TARGET: esp32h2
|
||||
TEST_DIR: examples
|
||||
|
||||
build_test_apps_esp32:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
@@ -486,7 +490,6 @@ build_test_apps_esp32c2:
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
optional: true
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
|
||||
- rm -rf test_build_system
|
||||
@@ -508,19 +511,6 @@ test_build_system_cmake_macos:
|
||||
- macos_shell
|
||||
variables:
|
||||
SHELL_TEST_SCRIPT: test_build_system_cmake.sh
|
||||
PYENV_VERSION: "3.7"
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
|
||||
- rm -rf test_build_system
|
||||
- mkdir test_build_system
|
||||
- cd test_build_system
|
||||
# copy-paste the script from .test_build_system_template
|
||||
# since `ESP_IDF_TEMPLATE_GIT` is a group variable and has higher precedence than job variable
|
||||
# export here to override the group variable
|
||||
#
|
||||
# Clone the template app from github for macos runners
|
||||
- export ESP_IDF_TEMPLATE_GIT="https://github.com/espressif/esp-idf-template.git"
|
||||
- ${IDF_PATH}/tools/ci/${SHELL_TEST_SCRIPT}
|
||||
|
||||
test_build_system_spaces:
|
||||
extends: .test_build_system_template
|
||||
|
||||
@@ -68,6 +68,55 @@
|
||||
- "build:{0}"
|
||||
- build:target_test
|
||||
|
||||
build:integration_test:
|
||||
labels:
|
||||
- build
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
included_in:
|
||||
- build:target_test
|
||||
|
||||
# -------------
|
||||
# Special Cases
|
||||
# -------------
|
||||
"build:{0}-esp32s3":
|
||||
matrix:
|
||||
- *target_test
|
||||
labels:
|
||||
- build
|
||||
- "{0}"
|
||||
- target_test
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
- build_target_test
|
||||
- "{0}"
|
||||
- "build-{0}"
|
||||
included_in:
|
||||
- "build:{0}"
|
||||
- build:target_test
|
||||
|
||||
"build:component_ut-esp32s3":
|
||||
matrix:
|
||||
- *target_test
|
||||
labels:
|
||||
- build
|
||||
- component_ut
|
||||
- unit_test
|
||||
- target_test
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
- build_target_test
|
||||
- component_ut
|
||||
- unit_test
|
||||
- build-component_ut
|
||||
- build-unit_test
|
||||
included_in:
|
||||
- "build:{0}"
|
||||
- build:target_test
|
||||
|
||||
####################
|
||||
# Target Test Jobs #
|
||||
####################
|
||||
@@ -118,8 +167,6 @@
|
||||
- wifi # example_test_002, example_test*wifi*
|
||||
- ethernet # example_test*ethernet*
|
||||
- sdio # UT_044, UT_045
|
||||
- usb # USB Device & Host tests
|
||||
- adc # component_ut_pytest_esp32x_adc
|
||||
patterns:
|
||||
- "{0}-{1}-{2}"
|
||||
- "{0}-{2}"
|
||||
@@ -146,6 +193,58 @@
|
||||
- "build:example_test"
|
||||
- build:target_test
|
||||
|
||||
# due to the lack of runners, c2 tests will only be triggered by label
|
||||
"test:{0}-esp32c2":
|
||||
matrix:
|
||||
- *target_test
|
||||
labels:
|
||||
- "{0}_esp32c2"
|
||||
included_in:
|
||||
- "build:{0}"
|
||||
- "build:{0}-esp32c2"
|
||||
- build:target_test
|
||||
|
||||
# overwrite the esp32c2 component ut again
|
||||
"test:component_ut-esp32c2": # component_ut will trigger by unit_test as well, since now we have 2 kinds of UT
|
||||
labels:
|
||||
- "component_ut_esp32c2"
|
||||
- "unit_test_esp32c2"
|
||||
included_in:
|
||||
- build:component_ut
|
||||
- "build:component_ut-esp32c2"
|
||||
- build:target_test
|
||||
|
||||
# due to the lack of runners, s3 tests will only be triggered by label
|
||||
"test:{0}-esp32s3":
|
||||
matrix:
|
||||
- *target_test
|
||||
labels:
|
||||
- "{0}_esp32s3"
|
||||
included_in:
|
||||
- "build:{0}"
|
||||
- "build:{0}-esp32s3"
|
||||
- build:target_test
|
||||
|
||||
# overwrite the esp32s3 component ut again
|
||||
"test:component_ut-esp32s3": # component_ut will trigger by unit_test as well, since now we have 2 kinds of UT
|
||||
labels:
|
||||
- "component_ut_esp32s3"
|
||||
- "unit_test_esp32s3"
|
||||
included_in:
|
||||
- build:component_ut
|
||||
- "build:component_ut-esp32s3"
|
||||
- build:target_test
|
||||
|
||||
"test:integration_test":
|
||||
labels:
|
||||
- integration_test
|
||||
- target_test
|
||||
patterns:
|
||||
- integration_test
|
||||
included_in:
|
||||
- build:integration_test
|
||||
- build:target_test
|
||||
|
||||
"test:host_test":
|
||||
labels:
|
||||
- host_test
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.deploy_job_template:
|
||||
extends: .before_script_no_sync_submodule
|
||||
stage: deploy
|
||||
image: $ESP_ENV_IMAGE
|
||||
tags:
|
||||
@@ -32,11 +33,50 @@ push_to_github:
|
||||
extends:
|
||||
- .deploy_job_template
|
||||
- .before_script_minimal
|
||||
- .rules:push_to_github
|
||||
needs:
|
||||
- check_submodule_sync
|
||||
- .rules:protected-no_label
|
||||
dependencies: []
|
||||
script:
|
||||
- add_github_ssh_keys
|
||||
- git remote remove github &>/dev/null || true
|
||||
- git remote add github git@github.com:espressif/esp-idf.git
|
||||
- tools/ci/push_to_github.sh
|
||||
|
||||
deploy_test_result:
|
||||
extends:
|
||||
- .deploy_job_template
|
||||
- .before_script_minimal
|
||||
- .rules:ref:master-always
|
||||
image: $CI_DOCKER_REGISTRY/bot-env:1
|
||||
dependencies: []
|
||||
tags:
|
||||
- deploy_test
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- ${CI_PROJECT_DIR}/test-management/*.log
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
BOT_ACCOUNT_CONFIG_FILE: "${CI_PROJECT_DIR}/test-management/Config/Account.local.yml"
|
||||
TEST_RESULTS_PATH: "${CI_PROJECT_DIR}/TEST_RESULTS"
|
||||
script:
|
||||
- add_gitlab_ssh_keys
|
||||
- export GIT_SHA=$(echo ${CI_COMMIT_SHA} | cut -c 1-8)
|
||||
- export REV_COUNT=$(git rev-list --count ${GIT_SHA} --)
|
||||
- export SUMMARY="IDF CI test result for $GIT_SHA (r${REV_COUNT})"
|
||||
# Download test result
|
||||
- export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
|
||||
- python3 ${IDF_PATH}/tools/ci/get_all_test_results.py --path ${TEST_RESULTS_PATH} --include_retried
|
||||
- if [[ -z $(find ${TEST_RESULTS_PATH} -name "*.xml") ]]; then exit 0; fi
|
||||
# Clone test-management repo
|
||||
- retry_failed git clone $TEST_MANAGEMENT_REPO
|
||||
- python3 $CHECKOUT_REF_SCRIPT test-management test-management
|
||||
- cd test-management
|
||||
- echo $BOT_JIRA_ACCOUNT > ${BOT_ACCOUNT_CONFIG_FILE}
|
||||
# Make sure all requirements are installed
|
||||
- pip3 install -r requirements.txt
|
||||
# Update test cases
|
||||
- python3 ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT from_xml -d ${TEST_RESULTS_PATH} -r $GIT_SHA -l IDFCI
|
||||
# update test results
|
||||
- python3 ImportTestResult.py -r "$GIT_SHA (r${REV_COUNT})" -j $JIRA_TEST_MANAGEMENT_PROJECT -s "$SUMMARY" -l IDFCI -p ${TEST_RESULTS_PATH} --pipeline_url ${CI_PIPELINE_URL}
|
||||
# May need a long time to upload all test results.
|
||||
timeout: 4 hours
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
.if-protected-no_label: &if-protected-no_label
|
||||
if: '($CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/ || $CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/) && $BOT_TRIGGER_WITH_LABEL == null'
|
||||
|
||||
.if-qa-test-tag: &if-qa-test-tag
|
||||
if: '$CI_COMMIT_TAG =~ /^qa-test/'
|
||||
|
||||
.if-label-build_docs: &if-label-build_docs
|
||||
if: '$BOT_LABEL_BUILD_DOCS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build_docs(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
@@ -30,12 +27,10 @@
|
||||
if: '$BOT_LABEL_DOCS_FAST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*docs_fast(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-dev-push: &if-dev-push
|
||||
if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_COMMIT_TAG !~ /^qa-test/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
|
||||
.doc-rules:build:docs:
|
||||
rules:
|
||||
- <<: *if-qa-test-tag
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build_docs
|
||||
- <<: *if-label-docs
|
||||
@@ -46,7 +41,7 @@
|
||||
# stage: pre_check
|
||||
check_readme_links:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
tags: ["build", "amd64", "internet"]
|
||||
allow_failure: true
|
||||
script:
|
||||
@@ -54,7 +49,7 @@ check_readme_links:
|
||||
|
||||
check_docs_lang_sync:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
- .doc-rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
@@ -67,6 +62,7 @@ check_docs_lang_sync:
|
||||
dependencies: []
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
|
||||
- build-docs -t $DOCTGT -bs $DOC_BUILDERS -l $DOCLANG build
|
||||
parallel:
|
||||
matrix:
|
||||
@@ -76,10 +72,11 @@ check_docs_lang_sync:
|
||||
check_docs_gh_links:
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
- .doc-rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
|
||||
- build-docs gh-linkcheck
|
||||
|
||||
# stage: build_doc
|
||||
@@ -151,6 +148,8 @@ build_docs_pdf:
|
||||
DOC_BUILDERS: "latex"
|
||||
|
||||
.deploy_docs_template:
|
||||
extends:
|
||||
- .before_script_no_sync_submodule
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
variables:
|
||||
DOCS_BUILD_DIR: "${IDF_PATH}/docs/_build/"
|
||||
@@ -162,6 +161,7 @@ build_docs_pdf:
|
||||
script:
|
||||
- add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
|
||||
- export GIT_VER=$(git describe --always ${PIPELINE_COMMIT_SHA} --)
|
||||
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
|
||||
- deploy-docs
|
||||
|
||||
# stage: test_deploy
|
||||
@@ -227,4 +227,5 @@ check_doc_links:
|
||||
allow_failure: true
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
|
||||
- build-docs -t $DOCTGT -l $DOCLANG linkcheck
|
||||
|
||||
@@ -204,26 +204,19 @@ test_idf_py:
|
||||
- cd ${IDF_PATH}/tools/test_idf_py
|
||||
- ./test_idf_py.py
|
||||
|
||||
# Test for create virtualenv. It must be invoked from Python, not from virtualenv.
|
||||
# Use docker image system python without any extra dependencies
|
||||
test_idf_tools:
|
||||
extends:
|
||||
- .host_test_template
|
||||
- .before_script_minimal
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- tools/tools.new.json
|
||||
expire_in: 1 week
|
||||
image:
|
||||
name: $ESP_ENV_IMAGE
|
||||
entrypoint: [""] # use system python3. no extra pip package installed
|
||||
script:
|
||||
# Tools must be downloaded for testing
|
||||
- python3 ${IDF_PATH}/tools/idf_tools.py download
|
||||
# Remove Xtensa and ULP toolchains from the PATH, tests will expect a clean environment
|
||||
- export PATH=$(p=$(echo $PATH | tr ":" "\n" | grep -v "/root/.espressif/tools\|/opt/espressif" | tr "\n" ":"); echo ${p%:})
|
||||
- cd ${IDF_PATH}/tools/test_idf_tools
|
||||
- python3 -m pip install jsonschema
|
||||
- python3 ./test_idf_tools.py
|
||||
- ./test_idf_tools.py
|
||||
# Test for create virtualenv. It must be invoked from Python, not from virtualenv.
|
||||
- python3 ./test_idf_tools_python_env.py
|
||||
|
||||
.test_efuse_table_on_host_template:
|
||||
@@ -265,6 +258,25 @@ test_efuse_table_on_host_esp32h2:
|
||||
variables:
|
||||
IDF_TARGET: esp32h2
|
||||
|
||||
test_espcoredump:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- components/espcoredump/test/**/.coverage
|
||||
- components/espcoredump/test/**/output
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
IDF_COREDUMP_ELF_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/idf/idf-coredump-elf.git"
|
||||
IDF_COREDUMP_ELF_TAG: idf-20210915
|
||||
# install CMake version specified in tools.json
|
||||
SETUP_TOOLS_LIST: "all"
|
||||
script:
|
||||
- eval $($IDF_PATH/tools/idf_tools.py export)
|
||||
- retry_failed git clone ${IDF_COREDUMP_ELF_REPO} -b $IDF_COREDUMP_ELF_TAG
|
||||
- cd ${IDF_PATH}/components/espcoredump/test/
|
||||
- ./test_espcoredump.sh ${CI_PROJECT_DIR}/idf-coredump-elf
|
||||
|
||||
test_logtrace_proc:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
@@ -304,8 +316,8 @@ test_mkuf2:
|
||||
- ./test_mkuf2.py
|
||||
|
||||
test_autocomplete:
|
||||
extends:
|
||||
- .host_test_template
|
||||
extends: .host_test_template
|
||||
image: $LINUX_SHELL_IMAGE
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
@@ -315,8 +327,8 @@ test_autocomplete:
|
||||
- ${IDF_PATH}/tools/ci/test_autocomplete.py
|
||||
|
||||
test_detect_python:
|
||||
extends:
|
||||
- .host_test_template
|
||||
extends: .host_test_template
|
||||
image: $LINUX_SHELL_IMAGE
|
||||
script:
|
||||
- cd ${IDF_PATH}
|
||||
- shellcheck -s sh tools/detect_python.sh
|
||||
@@ -361,6 +373,13 @@ test_esp_event:
|
||||
- idf.py build
|
||||
- build/test_esp_event_host.elf
|
||||
|
||||
test_esp_timer_cxx:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer
|
||||
- idf.py build
|
||||
- build/test_esp_timer_cxx_host.elf
|
||||
|
||||
test_eh_frame_parser:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
@@ -375,6 +394,34 @@ test_rom_on_linux_works:
|
||||
- idf.py build
|
||||
- build/test_rom_host.elf
|
||||
|
||||
test_cxx_gpio:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/gpio
|
||||
- idf.py build
|
||||
- build/test_gpio_cxx_host.elf
|
||||
|
||||
test_i2c_cxx:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/i2c
|
||||
- idf.py build
|
||||
- build/test_i2c_cxx_host.elf
|
||||
|
||||
test_spi_cxx:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/spi
|
||||
- idf.py build
|
||||
- build/test_spi_cxx_host.elf
|
||||
|
||||
test_system_cxx:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/system
|
||||
- idf.py build
|
||||
- build/test_system_cxx_host.elf
|
||||
|
||||
test_linux_example:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
@@ -383,14 +430,6 @@ test_linux_example:
|
||||
- timeout 5 ./build/linux_host_app.elf >test.log || true
|
||||
- grep "Restarting" test.log
|
||||
|
||||
test_partition_api_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_partition/host_test/partition_api_test
|
||||
- idf.py build
|
||||
- timeout 5 ./build/partition_api_test.elf >test.log
|
||||
- grep " 0 Failures" test.log
|
||||
|
||||
test_gen_soc_caps_kconfig:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
# generate dynamic integration pipeline by `idf-integration-ci` project
|
||||
|
||||
.patterns-integration_test: &patterns-integration_test
|
||||
# add all possible patterns to make sure `gen_integration_pipeline` can be triggered.
|
||||
# fine-grained control will be done while generating the pipeline
|
||||
# find `patterns` in `idf-integration-ci` project
|
||||
- "components/**/*"
|
||||
- "tools/**/*"
|
||||
- ".gitlab-ci.yml"
|
||||
- ".gitlab/ci/common.yml"
|
||||
- ".gitlab/ci/integration_test.yml"
|
||||
- ".gitmodules"
|
||||
- "CMakeLists.txt"
|
||||
- "install.sh"
|
||||
- "export.sh"
|
||||
- "Kconfig"
|
||||
- "sdkconfig.rename"
|
||||
|
||||
# Simplify the rules
|
||||
.integration_test_rules:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "merge_request_event"'
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes: *patterns-integration_test
|
||||
# support trigger by ci labels
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*target_test(?:,[^,\n\r]+)*$/i'
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test(?:,[^,\n\r]+)*$/i'
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
gen_integration_pipeline:
|
||||
extends:
|
||||
- .before_script_minimal
|
||||
- .integration_test_rules
|
||||
image: ${CI_INTEGRATION_ASSIGN_ENV}
|
||||
stage: assign_test
|
||||
cache: []
|
||||
tags:
|
||||
- assign_test
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "none"
|
||||
GIT_LFS_SKIP_SMUDGE: 1
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
optional: true
|
||||
artifacts:
|
||||
paths:
|
||||
- idf-integration-ci/child_pipeline/
|
||||
expire_in: 2 weeks
|
||||
script:
|
||||
- add_gitlab_ssh_keys
|
||||
- retry_failed git clone ${CI_GEN_INTEGRATION_PIPELINE_REPO} idf-integration-ci
|
||||
- python $CHECKOUT_REF_SCRIPT idf-integration-ci idf-integration-ci
|
||||
- cd idf-integration-ci
|
||||
- python tools/generate_child_pipeline.py -o child_pipeline/
|
||||
|
||||
child_integration_test_pipeline:
|
||||
extends:
|
||||
- .integration_test_rules
|
||||
stage: assign_test
|
||||
needs:
|
||||
- gen_integration_pipeline
|
||||
trigger:
|
||||
include:
|
||||
- artifact: idf-integration-ci/child_pipeline/pipeline.yml
|
||||
job: gen_integration_pipeline
|
||||
forward:
|
||||
yaml_variables: false
|
||||
strategy: depend
|
||||
@@ -1,15 +1,21 @@
|
||||
.pre_check_template:
|
||||
.pre_check_base_template:
|
||||
stage: pre_check
|
||||
image: $ESP_ENV_IMAGE
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: []
|
||||
|
||||
.check_pre_commit_template:
|
||||
.pre_check_job_template:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .before_script_minimal
|
||||
image: $PRE_COMMIT_IMAGE
|
||||
- .pre_check_base_template
|
||||
- .before_script_no_sync_submodule
|
||||
|
||||
.check_pre_commit_template:
|
||||
extends: .pre_check_job_template
|
||||
image: "$CI_DOCKER_REGISTRY/esp-idf-pre-commit:1"
|
||||
before_script:
|
||||
- source tools/ci/utils.sh
|
||||
- export PYTHONPATH="$CI_PROJECT_DIR/tools:$CI_PROJECT_DIR/tools/ci/python_packages:$PYTHONPATH"
|
||||
|
||||
check_pre_commit_master_release:
|
||||
extends:
|
||||
@@ -17,34 +23,44 @@ check_pre_commit_master_release:
|
||||
- .rules:protected
|
||||
script:
|
||||
- git diff-tree --no-commit-id --name-only -r $PIPELINE_COMMIT_SHA | xargs pre-commit run --files
|
||||
- pre-commit run --hook-stage post-commit validate-sbom-manifest
|
||||
|
||||
check_pre_commit_MR:
|
||||
extends:
|
||||
- .check_pre_commit_template
|
||||
- .rules:mr
|
||||
- .rules:dev
|
||||
script:
|
||||
- python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | xargs pre-commit run --files
|
||||
- pre-commit run --hook-stage post-commit validate-sbom-manifest
|
||||
|
||||
check_version:
|
||||
# Don't run this for feature/bugfix branches, so that it is possible to modify
|
||||
# esp_idf_version.h in a branch before tagging the next version.
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
- .rules:protected
|
||||
script:
|
||||
- export IDF_PATH=$PWD
|
||||
- tools/ci/check_idf_version.sh
|
||||
|
||||
check_rom_api_header:
|
||||
extends: .pre_check_template
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
- tools/ci/check_examples_rom_header.sh
|
||||
- tools/ci/check_api_violation.sh
|
||||
|
||||
check_python_style:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:python-files
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- flake8_output.txt
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- python -m flake8 --config=$IDF_PATH/.flake8 --output-file=flake8_output.txt --tee --benchmark $IDF_PATH
|
||||
|
||||
test_check_kconfigs:
|
||||
extends: .pre_check_template
|
||||
extends: .pre_check_job_template
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
@@ -59,7 +75,7 @@ test_check_kconfigs:
|
||||
- python ${IDF_PATH}/tools/ci/test_check_kconfigs.py
|
||||
|
||||
check_blobs:
|
||||
extends: .pre_check_template
|
||||
extends: .pre_check_base_template
|
||||
tags:
|
||||
- build
|
||||
variables:
|
||||
@@ -70,12 +86,11 @@ check_blobs:
|
||||
- IDF_TARGET=esp32s2 $IDF_PATH/components/esp_wifi/test_md5/test_md5.sh
|
||||
- IDF_TARGET=esp32s3 $IDF_PATH/components/esp_wifi/test_md5/test_md5.sh
|
||||
- IDF_TARGET=esp32c3 $IDF_PATH/components/esp_wifi/test_md5/test_md5.sh
|
||||
- IDF_TARGET=esp32c2 $IDF_PATH/components/esp_wifi/test_md5/test_md5.sh
|
||||
# Check if Wi-Fi, PHY, BT blobs contain references to specific symbols
|
||||
- bash $IDF_PATH/tools/ci/check_blobs.sh
|
||||
|
||||
check_fuzzer_compilation:
|
||||
extends: .pre_check_template
|
||||
extends: .pre_check_base_template
|
||||
image: $AFL_FUZZER_TEST_IMAGE
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/lwip/test_afl_host
|
||||
@@ -85,7 +100,7 @@ check_fuzzer_compilation:
|
||||
|
||||
check_public_headers:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
@@ -98,7 +113,7 @@ check_public_headers:
|
||||
|
||||
check_chip_support_components:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
@@ -115,7 +130,7 @@ check_chip_support_components:
|
||||
|
||||
check_esp_err_to_name:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
@@ -131,7 +146,7 @@ check_esp_err_to_name:
|
||||
|
||||
check_esp_system:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
@@ -142,19 +157,19 @@ check_esp_system:
|
||||
# the version returned by 'git describe'
|
||||
check_version_tag:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
- .rules:tag:release
|
||||
script:
|
||||
- (git cat-file -t $CI_COMMIT_REF_NAME | grep tag) || (echo "ESP-IDF versions must be annotated tags." && exit 1)
|
||||
|
||||
check_artifacts_expire_time:
|
||||
extends: .pre_check_template
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
# check if we have set expire time for all artifacts
|
||||
- python tools/ci/check_artifacts_expire_time.py
|
||||
|
||||
check_commit_msg:
|
||||
extends: .pre_check_template
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
- git status
|
||||
- git log -n10 --oneline ${PIPELINE_COMMIT_SHA}
|
||||
@@ -163,9 +178,7 @@ check_commit_msg:
|
||||
|
||||
check_test_scripts_build_test_rules:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_job_template
|
||||
- .before_script_build_jobs
|
||||
script:
|
||||
# required pytest related packages
|
||||
- run_cmd bash install.sh --enable-pytest
|
||||
- python tools/ci/check_build_test_rules.py check-test-scripts examples/ tools/test_apps components
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +1,32 @@
|
||||
# pre_check stage
|
||||
clang_tidy_check:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:clang_tidy
|
||||
image: ${CLANG_STATIC_ANALYSIS_IMAGE}
|
||||
artifacts:
|
||||
paths:
|
||||
- clang_tidy_reports/
|
||||
- $OUTPUT_DIR
|
||||
when: always
|
||||
expire_in: 1 day
|
||||
variables:
|
||||
IDF_TOOLCHAIN: clang
|
||||
CLANG_TIDY_DIRS_TXT: ${CI_PROJECT_DIR}/tools/ci/clang_tidy_dirs.txt
|
||||
RULES_FILE: ${CI_PROJECT_DIR}/tools/ci/static-analysis-rules.yml
|
||||
OUTPUT_DIR: ${CI_PROJECT_DIR}/clang_tidy_reports
|
||||
script:
|
||||
- run_cmd idf_clang_tidy $(cat tools/ci/clang_tidy_dirs.txt | xargs)
|
||||
--output-path clang_tidy_reports
|
||||
--limit-file tools/ci/static-analysis-rules.yml
|
||||
- python -m pip install -U pip
|
||||
- internal_pip_install $CLANG_TIDY_RUNNER_PROJ pyclang
|
||||
- export PATH=$PATH:$(python -c "import sys; print(sys.executable.rsplit('/', 1)[0])")
|
||||
- dirs=$(cat ${CLANG_TIDY_DIRS_TXT} | while read line; do echo ${CI_PROJECT_DIR}/${line}; done | xargs)
|
||||
- run_cmd idf_clang ${dirs}
|
||||
--output-path ${OUTPUT_DIR}
|
||||
--limit-file ${RULES_FILE}
|
||||
--xtensa-include-dir
|
||||
--run-clang-tidy-py ${RUN_CLANG_TIDY_PY}
|
||||
|
||||
check_pylint:
|
||||
extends:
|
||||
- .pre_check_template
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:python-files
|
||||
- .before_script_minimal
|
||||
image: $SONARQUBE_SCANNER_IMAGE
|
||||
@@ -38,3 +44,87 @@ check_pylint:
|
||||
export files=$(find . -iname "*.py" -print);
|
||||
fi
|
||||
- pylint --rcfile=.pylintrc $files -r n --output-format=parseable > pylint-report.txt || exit 0
|
||||
|
||||
# build stage
|
||||
# Sonarqube related jobs put here for this reason:
|
||||
# Here we have two jobs. code_quality_check and code_quality_report.
|
||||
#
|
||||
# code_quality_check will analyze the code changes between your MR and
|
||||
# code repo stored in sonarqube server. The analysis result is only shown in
|
||||
# the comments under this MR and won't be transferred to the server.
|
||||
#
|
||||
# code_quality_report will analyze and transfer both of the newly added code
|
||||
# and the analysis result to the server.
|
||||
#
|
||||
# Put in the front to ensure that the newly merged code can be stored in
|
||||
# sonarqube server ASAP, in order to avoid reporting unrelated code issues
|
||||
.sonar_scan_template:
|
||||
stage: build
|
||||
image:
|
||||
name: $SONARQUBE_SCANNER_IMAGE
|
||||
before_script:
|
||||
- source tools/ci/utils.sh
|
||||
- export PYTHONPATH="$CI_PROJECT_DIR/tools:$CI_PROJECT_DIR/tools/ci/python_packages:$PYTHONPATH"
|
||||
- fetch_submodules
|
||||
# Exclude the submodules, all paths ends with /**
|
||||
- submodules=$(get_all_submodules)
|
||||
# get all exclude paths specified in tools/ci/sonar_exclude_list.txt | ignore lines start with # | xargs | replace all <space> to <comma>
|
||||
- custom_excludes=$(cat $CI_PROJECT_DIR/tools/ci/sonar_exclude_list.txt | grep -v '^#' | xargs | sed -e 's/ /,/g')
|
||||
# Exclude the report dir as well
|
||||
- export EXCLUSIONS="$custom_excludes,$submodules"
|
||||
- export SONAR_SCANNER_OPTS="-Xmx2048m"
|
||||
|
||||
variables:
|
||||
GIT_DEPTH: 0
|
||||
REPORT_PATTERN: clang_tidy_reports/*.txt
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORT_PATTERN
|
||||
expire_in: 1 week
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: # Here is not a hard dependency relationship, could be skipped when only python files changed. so we do not use "needs" here.
|
||||
- clang_tidy_check
|
||||
- check_pylint
|
||||
|
||||
code_quality_check:
|
||||
extends:
|
||||
- .sonar_scan_template
|
||||
- .rules:patterns:static-code-analysis-preview
|
||||
allow_failure: true # since now it's using exit code to indicate the code analysis result,
|
||||
# we don't want to block ci when critical issues founded
|
||||
script:
|
||||
- export CI_MERGE_REQUEST_COMMITS=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py commits ${CI_COMMIT_REF_NAME} | tr '\n' ',')
|
||||
# test if this branch have merge request, if not, exit 0
|
||||
- test -n "$CI_MERGE_REQUEST_IID" || exit 0
|
||||
- test -n "$CI_MERGE_REQUEST_COMMITS" || exit 0
|
||||
- sonar-scanner
|
||||
-Dsonar.analysis.mode=preview
|
||||
-Dsonar.branch.name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
|
||||
-Dsonar.exclusions=$EXCLUSIONS
|
||||
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
|
||||
-Dsonar.gitlab.commit_sha=$CI_MERGE_REQUEST_COMMITS
|
||||
-Dsonar.gitlab.merge_request_discussion=true
|
||||
-Dsonar.gitlab.ref_name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
-Dsonar.host.url=$SONAR_HOST_URL
|
||||
-Dsonar.login=$SONAR_LOGIN
|
||||
-Dsonar.python.pylint.reportPath=pylint-report.txt
|
||||
|
||||
code_quality_report:
|
||||
extends:
|
||||
- .sonar_scan_template
|
||||
- .rules:protected
|
||||
allow_failure: true # since now it's using exit code to indicate the code analysis result,
|
||||
# we don't want to block ci when critical issues founded
|
||||
script:
|
||||
- sonar-scanner
|
||||
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
|
||||
-Dsonar.exclusions=$EXCLUSIONS
|
||||
-Dsonar.gitlab.commit_sha=$PIPELINE_COMMIT_SHA
|
||||
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.host.url=$SONAR_HOST_URL
|
||||
-Dsonar.login=$SONAR_LOGIN
|
||||
-Dsonar.python.pylint.reportPath=pylint-report.txt
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
.pytest_template:
|
||||
extends:
|
||||
- .target_test_template
|
||||
- .before_script_pytest
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
@@ -24,7 +25,7 @@
|
||||
junit: XUNIT_RESULT.xml
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- python tools/ci/get_known_failure_cases_file.py
|
||||
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
||||
# get runner env config file
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
@@ -32,7 +33,7 @@
|
||||
# Runner tags are comma separated, replace the comma with " and " for markers
|
||||
- job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID)
|
||||
- markers=$(echo $job_tags | sed -e "s/,/ and /g")
|
||||
- run_cmd pytest $TEST_DIR -m \"${markers}\" --junitxml=XUNIT_RESULT.xml --known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
|
||||
- run_cmd pytest $TEST_DIR -m \"${markers}\" --junitxml=XUNIT_RESULT.xml --known-failure-cases-file known_failure_cases/known_failure_cases.txt
|
||||
|
||||
.pytest_examples_dir_template:
|
||||
extends: .pytest_template
|
||||
@@ -79,6 +80,14 @@ example_test_pytest_esp32c2_generic:
|
||||
- build_pytest_examples_esp32c2
|
||||
tags: [ esp32c2, generic, xtal_40mhz ]
|
||||
|
||||
example_test_pytest_esp32c2_26mhz:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32c2
|
||||
needs:
|
||||
- build_pytest_examples_esp32c2
|
||||
tags: [ esp32c2, xtal_26mhz ]
|
||||
|
||||
example_test_pytest_esp32c3_generic:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
@@ -135,14 +144,6 @@ example_test_pytest_esp32_ethernet:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, ethernet]
|
||||
|
||||
pytest_examples_esp32_ethernet_httpbin:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32-ethernet
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, httpbin]
|
||||
|
||||
example_test_pytest_esp32_8mb_flash:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
@@ -181,7 +182,7 @@ example_test_pytest_esp32_ethernet_ip101:
|
||||
- .rules:test:example_test-esp32
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, eth_ip101 ]
|
||||
tags: [ esp32, ip101 ]
|
||||
|
||||
example_test_pytest_esp32_flash_encryption:
|
||||
extends:
|
||||
@@ -191,29 +192,13 @@ example_test_pytest_esp32_flash_encryption:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, flash_encryption ]
|
||||
|
||||
example_test_pytest_esp32_wifi_two_dut:
|
||||
example_test_pytest_esp32_multi_dut_generic:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32-wifi
|
||||
- .rules:test:example_test-esp32
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, wifi_two_dut ]
|
||||
|
||||
example_test_pytest_esp32c3eco7_wifi_two_dut:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32c3-wifi
|
||||
needs:
|
||||
- build_pytest_examples_esp32c3
|
||||
tags: [ esp32c3eco7, wifi_two_dut ]
|
||||
|
||||
example_test_pytest_esp32c2eco4_wifi_two_dut:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32c2-wifi
|
||||
needs:
|
||||
- build_pytest_examples_esp32c2
|
||||
tags: [ esp32c2eco4, wifi_two_dut, xtal_26mhz]
|
||||
tags: [ esp32, multi_dut_generic ]
|
||||
|
||||
example_test_pytest_esp32c3_flash_encryption:
|
||||
extends:
|
||||
@@ -223,86 +208,6 @@ example_test_pytest_esp32c3_flash_encryption:
|
||||
- build_pytest_examples_esp32c3
|
||||
tags: [ esp32c3, flash_encryption ]
|
||||
|
||||
example_test_pytest_esp32_sdmmc:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, sdcard_sdmode ]
|
||||
|
||||
example_test_pytest_esp32_sdspi:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, sdcard_spimode ]
|
||||
|
||||
example_test_pytest_esp32s2_sdspi:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32s2
|
||||
needs:
|
||||
- build_pytest_examples_esp32s2
|
||||
tags: [ esp32s2, sdcard_spimode ]
|
||||
|
||||
example_test_pytest_esp32c3_sdspi:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32c3
|
||||
needs:
|
||||
- build_pytest_examples_esp32c3
|
||||
tags: [ esp32c3, sdcard_spimode ]
|
||||
|
||||
example_test_pytest_esp32_extflash:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, external_flash ]
|
||||
|
||||
example_test_pytest_esp32_adc:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32-adc
|
||||
needs:
|
||||
- build_pytest_examples_esp32
|
||||
tags: [ esp32, adc ]
|
||||
|
||||
example_test_pytest_esp32s2_adc:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32s2-adc
|
||||
needs:
|
||||
- build_pytest_examples_esp32s2
|
||||
tags: [ esp32s2, adc ]
|
||||
|
||||
example_test_pytest_esp32s3_adc:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32s3-adc
|
||||
needs:
|
||||
- build_pytest_examples_esp32s3
|
||||
tags: [ esp32s3, adc ]
|
||||
|
||||
example_test_pytest_esp32c3_adc:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32c3-adc
|
||||
needs:
|
||||
- build_pytest_examples_esp32c3
|
||||
tags: [ esp32c3, adc ]
|
||||
|
||||
example_test_pytest_esp32c2_adc:
|
||||
extends:
|
||||
- .pytest_examples_dir_template
|
||||
- .rules:test:example_test-esp32c2-adc
|
||||
needs:
|
||||
- build_pytest_examples_esp32c2
|
||||
tags: [ esp32c2, adc, xtal_26mhz]
|
||||
|
||||
.pytest_components_dir_template:
|
||||
extends: .pytest_template
|
||||
variables:
|
||||
@@ -316,21 +221,13 @@ component_ut_pytest_esp32_generic:
|
||||
- build_pytest_components_esp32
|
||||
tags: [ esp32, generic ]
|
||||
|
||||
component_ut_pytest_esp32_adc:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32-adc
|
||||
needs:
|
||||
- build_pytest_components_esp32
|
||||
tags: [ esp32, adc ]
|
||||
|
||||
component_ut_pytest_esp32_ip101:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32
|
||||
needs:
|
||||
- build_pytest_components_esp32
|
||||
tags: [ esp32, eth_ip101 ]
|
||||
tags: [ esp32, ip101 ]
|
||||
|
||||
component_ut_pytest_esp32_lan8720:
|
||||
extends:
|
||||
@@ -338,7 +235,7 @@ component_ut_pytest_esp32_lan8720:
|
||||
- .rules:labels-protected:lan8720 # FIXME: IDFCI-1176
|
||||
needs:
|
||||
- build_pytest_components_esp32
|
||||
tags: [ esp32, eth_lan8720 ]
|
||||
tags: [ esp32, lan8720 ]
|
||||
|
||||
component_ut_pytest_esp32_flash_encryption:
|
||||
extends:
|
||||
@@ -356,14 +253,6 @@ component_ut_pytest_esp32s2_generic:
|
||||
- build_pytest_components_esp32s2
|
||||
tags: [ esp32s2, generic ]
|
||||
|
||||
component_ut_pytest_esp32s2_adc:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s2-adc
|
||||
needs:
|
||||
- build_pytest_components_esp32s2
|
||||
tags: [ esp32s2, adc ]
|
||||
|
||||
component_ut_pytest_esp32s3_generic:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
@@ -372,14 +261,6 @@ component_ut_pytest_esp32s3_generic:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, generic ]
|
||||
|
||||
component_ut_pytest_esp32s3_adc:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s3-adc
|
||||
needs:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, adc ]
|
||||
|
||||
component_ut_pytest_esp32s3_octal_psram:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
@@ -412,21 +293,13 @@ component_ut_pytest_esp32c2_generic:
|
||||
- build_pytest_components_esp32c2
|
||||
tags: [ esp32c2, generic, xtal_40mhz ]
|
||||
|
||||
component_ut_pytest_esp32c2_adc:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32c2-adc
|
||||
needs:
|
||||
- build_pytest_components_esp32c2
|
||||
tags: [ esp32c2, adc, xtal_26mhz ]
|
||||
|
||||
component_ut_pytest_esp32c2_xtal_26mhz:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32c2
|
||||
needs:
|
||||
- build_pytest_components_esp32c2
|
||||
tags: [ esp32c2, generic, xtal_26mhz ]
|
||||
tags: [ esp32c2, xtal_26mhz ]
|
||||
|
||||
component_ut_pytest_esp32c3_generic:
|
||||
extends:
|
||||
@@ -436,14 +309,6 @@ component_ut_pytest_esp32c3_generic:
|
||||
- build_pytest_components_esp32c3
|
||||
tags: [ esp32c3, generic ]
|
||||
|
||||
component_ut_pytest_esp32c3_adc:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32c3-adc
|
||||
needs:
|
||||
- build_pytest_components_esp32c3
|
||||
tags: [ esp32c3, adc ]
|
||||
|
||||
component_ut_pytest_esp32c3_flash_encryption:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
@@ -452,14 +317,6 @@ component_ut_pytest_esp32c3_flash_encryption:
|
||||
- build_pytest_components_esp32c3
|
||||
tags: [ esp32c3, flash_encryption ]
|
||||
|
||||
component_ut_pytest_esp32s3_usb_host:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s3-usb
|
||||
needs:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, usb_host_flash_disk ]
|
||||
|
||||
.pytest_test_apps_dir_template:
|
||||
extends: .pytest_template
|
||||
variables:
|
||||
@@ -501,6 +358,14 @@ test_app_test_pytest_esp32c2_generic:
|
||||
- build_pytest_test_apps_esp32c2
|
||||
tags: [ esp32c2, generic, xtal_40mhz ]
|
||||
|
||||
test_app_test_pytest_esp32c2_26mhz:
|
||||
extends:
|
||||
- .pytest_test_apps_dir_template
|
||||
- .rules:test:custom_test-esp32c2
|
||||
needs:
|
||||
- build_pytest_test_apps_esp32c2
|
||||
tags: [ esp32c2, xtal_26mhz ]
|
||||
|
||||
test_app_test_pytest_esp32c3_generic:
|
||||
extends:
|
||||
- .pytest_test_apps_dir_template
|
||||
@@ -509,6 +374,14 @@ test_app_test_pytest_esp32c3_generic:
|
||||
- build_pytest_test_apps_esp32c3
|
||||
tags: [ esp32c3, generic ]
|
||||
|
||||
test_app_test_pytest_esp32s2_usb_host:
|
||||
extends:
|
||||
- .pytest_test_apps_dir_template
|
||||
- .rules:test:custom_test-esp32s2
|
||||
needs:
|
||||
- build_pytest_test_apps_esp32s2
|
||||
tags: [ esp32s2, usb_host ]
|
||||
|
||||
test_app_test_pytest_esp32s3_mspi_f8r8:
|
||||
extends:
|
||||
- .pytest_test_apps_dir_template
|
||||
@@ -566,10 +439,10 @@ test_app_test_pytest_esp32s3_mspi_f4r4:
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# git clone the known failure cases repo, run test
|
||||
- python tools/ci/get_known_failure_cases_file.py
|
||||
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
||||
# run test
|
||||
- cd tools/ci/python_packages/tiny_test_fw/bin
|
||||
- run_cmd python Runner.py $TEST_CASE_PATH -c $CONFIG_FILE -e $ENV_FILE --known_failure_cases_file $CI_PROJECT_DIR/${KNOWN_FAILURE_CASES_FILE_NAME}
|
||||
- run_cmd python Runner.py $TEST_CASE_PATH -c $CONFIG_FILE -e $ENV_FILE --known_failure_cases_file $CI_PROJECT_DIR/known_failure_cases/known_failure_cases.txt
|
||||
|
||||
.example_test_template:
|
||||
extends: .target_test_job_template
|
||||
@@ -703,6 +576,30 @@ example_test_009:
|
||||
SETUP_TOOLS: "1"
|
||||
PYTHON_VER: 3
|
||||
|
||||
example_test_010:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_ExtFlash
|
||||
|
||||
example_test_011:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_T2_RS485
|
||||
|
||||
example_test_013:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- UT_T1_SDMODE
|
||||
|
||||
example_test_016:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_Modbus_TCP
|
||||
|
||||
example_test_017:
|
||||
extends: .example_test_esp32s2_template
|
||||
tags:
|
||||
@@ -716,11 +613,23 @@ example_test_C3_GENERIC:
|
||||
- ESP32C3
|
||||
- Example_GENERIC
|
||||
|
||||
example_test_C2_GENERIC:
|
||||
extends: .example_test_esp32c2_template
|
||||
example_test_ESP32_SDSPI:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32C2
|
||||
- Example_GENERIC
|
||||
- ESP32
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
example_test_ESP32S2_SDSPI:
|
||||
extends: .example_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
example_test_ESP32C3_SDSPI:
|
||||
extends: .example_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
.test_app_template:
|
||||
extends: .target_test_job_template
|
||||
@@ -906,6 +815,12 @@ UT_014:
|
||||
- UT_T2_RS485
|
||||
- psram
|
||||
|
||||
UT_017:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- EMMC
|
||||
|
||||
UT_018:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 2
|
||||
@@ -1028,7 +943,7 @@ UT_S2_SDSPI:
|
||||
|
||||
UT_C2:
|
||||
extends: .unit_test_esp32c2_template
|
||||
parallel: 24
|
||||
parallel: 21
|
||||
tags:
|
||||
- ESP32C2_IDF
|
||||
- UT_T1_1
|
||||
@@ -1106,3 +1021,200 @@ UT_S3_FLASH:
|
||||
tags:
|
||||
- ESP32S3_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
|
||||
.integration_test_template:
|
||||
extends:
|
||||
- .target_test_job_template
|
||||
- .rules:test:integration_test
|
||||
# needn't install idf python env
|
||||
- .before_script_integration_test
|
||||
needs: # the assign already needs all the build jobs
|
||||
- assign_integration_test
|
||||
variables:
|
||||
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
|
||||
LOG_PATH: "${CI_PROJECT_DIR}/TEST_LOGS"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/auto_test_script/TestCaseFiles"
|
||||
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/tools/ci/integration_test/test_configs"
|
||||
KNOWN_ISSUE_FILE: "${CI_PROJECT_DIR}/tools/ci/integration_test/KnownIssues"
|
||||
CI_RUNNER_SCRIPT: "${CI_PROJECT_DIR}/auto_test_script/bin/CIRunner.py"
|
||||
PREPARE_TEST_BIN_SCRIPT: "${CI_PROJECT_DIR}/tools/ci/integration_test/prepare_test_bins.py"
|
||||
PYTHONPATH: "${CI_PROJECT_DIR}/auto_test_script/packages:${PYTHONPATH}"
|
||||
INITIAL_CONDITION_RETRY_COUNT: "1"
|
||||
# auto_test_script only supports python 3.7.x
|
||||
PYTHON_VER: 3.7.7
|
||||
script:
|
||||
- *define_config_file_name
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- test -e $CONFIG_FILE || exit 0
|
||||
# clone local test env configs
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# clone test bench
|
||||
# can not retry if downing git lfs files failed, so using empty_branch first.
|
||||
- retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch
|
||||
- retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH}
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only
|
||||
- cat ${KNOWN_ISSUE_FILE} >> ${TEST_CASE_FILE_PATH}/KnownIssues
|
||||
# run test
|
||||
- python ${PREPARE_TEST_BIN_SCRIPT} $CONFIG_FILE
|
||||
- python ${CI_RUNNER_SCRIPT} -l "$LOG_PATH/$JOB_FULL_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH
|
||||
|
||||
.integration_test_esp32c3_template:
|
||||
extends:
|
||||
- .integration_test_template
|
||||
variables:
|
||||
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32C3_IDF"
|
||||
|
||||
nvs_compatible_test:
|
||||
extends: .integration_test_template
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
- nvs_wifi.bin
|
||||
expire_in: 1 mos
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- NVS_Compatible
|
||||
script:
|
||||
- *define_config_file_name
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- test -e $CONFIG_FILE || exit 0
|
||||
# prepare test utilities
|
||||
- source tools/ci/setup_python.sh
|
||||
- add_gitlab_ssh_keys
|
||||
- fetch_submodules
|
||||
# clone local test env configs
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# clone test bench
|
||||
# can not retry if downing git lfs files failed, so using empty_branch first.
|
||||
- retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch
|
||||
- retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH}
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only
|
||||
# prepare nvs bins
|
||||
- cd auto_test_script
|
||||
- ./tools/prepare_nvs_bin.sh
|
||||
# run test
|
||||
- python ${PREPARE_TEST_BIN_SCRIPT} $CONFIG_FILE
|
||||
- python ${CI_RUNNER_SCRIPT} -l "$LOG_PATH/$JOB_FULL_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH
|
||||
|
||||
IT_001:
|
||||
extends: .integration_test_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_4
|
||||
|
||||
IT_002:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_2
|
||||
|
||||
IT_003:
|
||||
extends: .integration_test_template
|
||||
parallel: 9
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_5
|
||||
|
||||
IT_005:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_5
|
||||
|
||||
IT_006:
|
||||
extends: .integration_test_template
|
||||
parallel: 5
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_6
|
||||
|
||||
IT_007:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_7
|
||||
|
||||
IT_008:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_8
|
||||
|
||||
IT_011:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_MESH1
|
||||
|
||||
IT_012:
|
||||
extends: .integration_test_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_MESH1
|
||||
|
||||
IT_013:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_MESH1
|
||||
|
||||
IT_014:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T6_MESH1
|
||||
|
||||
IT_015:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T12_MESH1
|
||||
|
||||
IT_016:
|
||||
extends: .integration_test_template
|
||||
allow_failure: true
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T50_MESH1
|
||||
|
||||
IT_017:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_MESH2
|
||||
|
||||
IT_018:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_9
|
||||
|
||||
IT_019:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_2
|
||||
|
||||
IT_020:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_3
|
||||
|
||||
IT_022:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_2
|
||||
|
||||
IT_C3_001:
|
||||
extends: .integration_test_esp32c3_template
|
||||
parallel: 6
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- SSC_T2_5
|
||||
|
||||
@@ -9,19 +9,22 @@
|
||||
upload-pip-cache:
|
||||
extends:
|
||||
- .upload_cache_template
|
||||
- .before_script_minimal
|
||||
- .rules:patterns:python-cache
|
||||
tags:
|
||||
- $GEO
|
||||
- cache
|
||||
- build
|
||||
cache:
|
||||
key: pip-cache
|
||||
paths:
|
||||
- .cache/pip
|
||||
policy: push
|
||||
before_script: []
|
||||
script:
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- source tools/ci/setup_python.sh
|
||||
- rm -rf .cache/pip # clear old packages
|
||||
- bash install.sh --enable-ci --enable-pytest
|
||||
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest,ci
|
||||
parallel:
|
||||
matrix:
|
||||
- GEO: [ 'shiny', 'brew' ]
|
||||
@@ -29,21 +32,21 @@ upload-pip-cache:
|
||||
upload-submodules-cache:
|
||||
extends:
|
||||
- .upload_cache_template
|
||||
- .before_script_minimal
|
||||
- .rules:patterns:submodule
|
||||
tags:
|
||||
- $GEO
|
||||
- cache
|
||||
- build
|
||||
cache:
|
||||
key: submodule-cache
|
||||
paths:
|
||||
- .cache/submodule_archives
|
||||
policy: push
|
||||
before_script: []
|
||||
script:
|
||||
# use the default gitlab server
|
||||
- unset LOCAL_GITLAB_HTTPS_HOST
|
||||
- source tools/ci/utils.sh
|
||||
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
|
||||
- source tools/ci/setup_python.sh
|
||||
- rm -rf .cache/submodule_archives # clear old submodule archives
|
||||
- add_gitlab_ssh_keys
|
||||
- fetch_submodules
|
||||
parallel:
|
||||
matrix:
|
||||
|
||||
66
.gitmodules
vendored
66
.gitmodules
vendored
@@ -2,26 +2,6 @@
|
||||
# All the relative URL paths are intended to be GitHub ones
|
||||
# For Espressif's public projects please use '../../espressif/proj', not a '../proj'
|
||||
#
|
||||
# Submodules SBOM information
|
||||
# ---------------------------
|
||||
# Submodules, which are used directly and not forked into espressif namespace should
|
||||
# contain SBOM information here. Other submodules should have the SBOM manifest file
|
||||
# included in the root of their project's repository.
|
||||
#
|
||||
# The sbom-hash entry records the submodule's checkout SHA as presented in git-tree
|
||||
# commit object. For example spiffs submodule
|
||||
#
|
||||
# $ git ls-tree HEAD components/spiffs/spiffs
|
||||
# 160000 commit 0dbb3f71c5f6fae3747a9d935372773762baf852 components/spiffs/spiffs
|
||||
#
|
||||
# The hash can be also obtained with git submodule command
|
||||
#
|
||||
# $ git submodule status components/spiffs/spiffs
|
||||
# 0dbb3f71c5f6fae3747a9d935372773762baf852 components/spiffs/spiffs (0.2-255-g0dbb3f71c5f6)
|
||||
#
|
||||
# The submodule SHA recorded here has to match with SHA, which is presented in git-tree.
|
||||
# This is checked by CI. Also please don't forget to update the submodule version
|
||||
# if you are changing the sbom-hash. This is important for SBOM generation.
|
||||
|
||||
[submodule "components/bt/controller/lib_esp32"]
|
||||
path = components/bt/controller/lib_esp32
|
||||
@@ -30,32 +10,14 @@
|
||||
[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"]
|
||||
path = components/bootloader/subproject/components/micro-ecc/micro-ecc
|
||||
url = ../../kmackay/micro-ecc.git
|
||||
sbom-version = 1.1
|
||||
sbom-cpe = cpe:2.3:a:micro-ecc_project:micro-ecc:{}:*:*:*:*:*:*:*
|
||||
sbom-supplier = Person: Ken MacKay
|
||||
sbom-url = https://github.com/kmackay/micro-ecc
|
||||
sbom-description = A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors
|
||||
sbom-hash = 24c60e243580c7868f4334a1ba3123481fe1aa48
|
||||
|
||||
[submodule "components/spiffs/spiffs"]
|
||||
path = components/spiffs/spiffs
|
||||
url = ../../pellepl/spiffs.git
|
||||
sbom-version = 0.2-255-g0dbb3f71c5f6
|
||||
sbom-supplier = Person: Peter Andersson
|
||||
sbom-url = https://github.com/pellepl/spiffs
|
||||
sbom-description = Wear-leveled SPI flash file system for embedded devices
|
||||
sbom-hash = 0dbb3f71c5f6fae3747a9d935372773762baf852
|
||||
|
||||
[submodule "components/json/cJSON"]
|
||||
path = components/json/cJSON
|
||||
url = ../../DaveGamble/cJSON.git
|
||||
sbom-version = 1.7.18
|
||||
sbom-cpe = cpe:2.3:a:cjson_project:cjson:{}:*:*:*:*:*:*:*
|
||||
sbom-supplier = Person: Dave Gamble
|
||||
sbom-url = https://github.com/DaveGamble/cJSON
|
||||
sbom-description = Ultralightweight JSON parser in ANSI C
|
||||
sbom-hash = acc76239bee01d8e9c858ae2cab296704e52d916
|
||||
sbom-cve-exclude-list = CVE-2024-31755 Resolved in v1.7.18
|
||||
|
||||
[submodule "components/mbedtls/mbedtls"]
|
||||
path = components/mbedtls/mbedtls
|
||||
@@ -72,21 +34,10 @@
|
||||
[submodule "components/protobuf-c/protobuf-c"]
|
||||
path = components/protobuf-c/protobuf-c
|
||||
url = ../../protobuf-c/protobuf-c.git
|
||||
sbom-version = 1.4.1
|
||||
sbom-cpe = cpe:2.3:a:protobuf-c_project:protobuf-c:{}:*:*:*:*:*:*:*
|
||||
sbom-supplier = Organization: protobuf-c community <https://groups.google.com/g/protobuf-c>
|
||||
sbom-url = https://github.com/protobuf-c/protobuf-c
|
||||
sbom-description = Protocol Buffers implementation in C
|
||||
sbom-hash = abc67a11c6db271bedbb9f58be85d6f4e2ea8389
|
||||
|
||||
[submodule "components/unity/unity"]
|
||||
path = components/unity/unity
|
||||
url = ../../ThrowTheSwitch/Unity.git
|
||||
sbom-version = v2.4.3-51-g7d2bf62b7e6a
|
||||
sbom-supplier = Organization: ThrowTheSwitch community <http://www.throwtheswitch.org>
|
||||
sbom-url = https://github.com/ThrowTheSwitch/Unity
|
||||
sbom-description = Simple Unit Testing for C
|
||||
sbom-hash = 7d2bf62b7e6afaf38153041a9d53c21aeeca9a25
|
||||
|
||||
[submodule "components/bt/host/nimble/nimble"]
|
||||
path = components/bt/host/nimble/nimble
|
||||
@@ -96,14 +47,17 @@
|
||||
path = components/esp_wifi/lib
|
||||
url = ../../espressif/esp32-wifi-lib.git
|
||||
|
||||
[submodule "components/tinyusb/tinyusb"]
|
||||
path = components/tinyusb/tinyusb
|
||||
url = ../../espressif/tinyusb.git
|
||||
|
||||
[submodule "examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib"]
|
||||
path = examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib
|
||||
url = ../../espressif/esp-cryptoauthlib.git
|
||||
|
||||
[submodule "components/cmock/CMock"]
|
||||
path = components/cmock/CMock
|
||||
url = ../../ThrowTheSwitch/CMock.git
|
||||
sbom-version = v2.5.2-2-geeecc49ce8af
|
||||
sbom-supplier = Organization: ThrowTheSwitch community <http://www.throwtheswitch.org>
|
||||
sbom-url = https://github.com/ThrowTheSwitch/CMock
|
||||
sbom-description = CMock - Mock/stub generator for C
|
||||
sbom-hash = eeecc49ce8af123cf8ad40efdb9673e37b56230f
|
||||
|
||||
[submodule "components/openthread/openthread"]
|
||||
path = components/openthread/openthread
|
||||
@@ -132,7 +86,3 @@
|
||||
[submodule "components/bt/controller/lib_esp32c2/esp32c2-bt-lib"]
|
||||
path = components/bt/controller/lib_esp32c2/esp32c2-bt-lib
|
||||
url = ../../espressif/esp32c2-bt-lib.git
|
||||
|
||||
[submodule "components/heap/tlsf"]
|
||||
path = components/heap/tlsf
|
||||
url = ../../espressif/tlsf.git
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
|
||||
default_stages: [commit]
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
# note: whitespace exclusions use multiline regex, see https://pre-commit.com/#regular-expressions
|
||||
@@ -23,8 +21,7 @@ repos:
|
||||
.+test_idf_monitor\/tests\/.+|
|
||||
.*_pb2.py|
|
||||
.*.pb-c.h|
|
||||
.*.pb-c.c|
|
||||
.*.yuv
|
||||
.*.pb-c.c
|
||||
)$
|
||||
- id: end-of-file-fixer
|
||||
exclude: *whitespace_excludes
|
||||
@@ -32,17 +29,16 @@ repos:
|
||||
- id: mixed-line-ending
|
||||
args: ['-f=lf']
|
||||
- id: double-quote-string-fixer
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 5.0.4
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: ['--config=.flake8', '--tee', '--benchmark']
|
||||
- repo: https://github.com/asottile/reorder-python-imports
|
||||
rev: v3.12.0
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.9.3
|
||||
hooks:
|
||||
- id: reorder-python-imports
|
||||
name: Reorder Python imports
|
||||
args: [--py37-plus]
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
exclude: >
|
||||
(?x)^(
|
||||
.*_pb2.py
|
||||
@@ -144,10 +140,9 @@ repos:
|
||||
name: Check if all apps readme files match given .build-test-rules.yml files. Modify the supported target tables
|
||||
entry: tools/ci/check_build_test_rules.py check-readmes
|
||||
language: python
|
||||
require_serial: true
|
||||
files: 'tools/test_apps/.+|examples/.+|components/.+'
|
||||
additional_dependencies:
|
||||
- idf_build_apps~=1.0
|
||||
- idf_build_apps
|
||||
- id: sort-build-test-rules-ymls
|
||||
name: sort .build-test-rules.yml files
|
||||
entry: tools/ci/check_build_test_rules.py sort-yaml
|
||||
@@ -161,12 +156,7 @@ repos:
|
||||
- id: file-contents-sorter
|
||||
files: 'tools\/ci\/(executable-list\.txt|mypy_ignore_list\.txt|check_copyright_ignore\.txt)'
|
||||
- repo: https://github.com/espressif/check-copyright/
|
||||
rev: v1.0.3
|
||||
rev: v1.0.1
|
||||
hooks:
|
||||
- id: check-copyright
|
||||
args: ['--ignore', 'tools/ci/check_copyright_ignore.txt', '--config', 'tools/ci/check_copyright_config.yaml']
|
||||
- repo: https://github.com/espressif/esp-idf-sbom.git
|
||||
rev: v0.13.0
|
||||
hooks:
|
||||
- id: validate-sbom-manifest
|
||||
stages: [post-commit]
|
||||
|
||||
@@ -183,35 +183,8 @@ endif()
|
||||
list(APPEND link_options "-fno-lto")
|
||||
|
||||
if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
# Not all versions of the MacOS linker support the -warn_commons flag.
|
||||
# ld version 1053.12 (and above) have been tested to support it.
|
||||
# Hence, we extract the version string from the linker output
|
||||
# before including the flag.
|
||||
|
||||
# Get the ld version, capturing both stdout and stderr
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_LINKER} -v
|
||||
OUTPUT_VARIABLE LD_VERSION_OUTPUT
|
||||
ERROR_VARIABLE LD_VERSION_ERROR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Combine stdout and stderr
|
||||
set(LD_VERSION_OUTPUT "${LD_VERSION_OUTPUT}\n${LD_VERSION_ERROR}")
|
||||
|
||||
# Extract the version string
|
||||
string(REGEX MATCH "PROJECT:(ld|dyld)-([0-9]+)\\.([0-9]+)" LD_VERSION_MATCH "${LD_VERSION_OUTPUT}")
|
||||
set(LD_VERSION_MAJOR_MINOR "${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
|
||||
|
||||
message(STATUS "Linker Version: ${LD_VERSION_MAJOR_MINOR}")
|
||||
|
||||
# Compare the version with 1053.12
|
||||
if(LD_VERSION_MAJOR_MINOR VERSION_GREATER_EQUAL "1053.12")
|
||||
list(APPEND link_options "-Wl,-warn_commons")
|
||||
endif()
|
||||
|
||||
list(APPEND link_options "-Wl,-dead_strip")
|
||||
list(APPEND link_options "-Wl,-warn_commons")
|
||||
else()
|
||||
list(APPEND link_options "-Wl,--gc-sections")
|
||||
list(APPEND link_options "-Wl,--warn-common")
|
||||
|
||||
5
Kconfig
5
Kconfig
@@ -15,10 +15,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
bool
|
||||
option env="IDF_ENV_FPGA"
|
||||
|
||||
config IDF_CI_BUILD
|
||||
bool
|
||||
default y if "$(IDF_CI_BUILD)" = "y" || "$(IDF_CI_BUILD)" = 1
|
||||
|
||||
config IDF_TARGET_ARCH_RISCV
|
||||
bool
|
||||
default "n"
|
||||
@@ -86,6 +82,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
config IDF_TARGET_ESP32H2_BETA_VERSION_2
|
||||
bool
|
||||
prompt "ESP32-H2 beta2"
|
||||
select ESPTOOLPY_NO_STUB # TODO: IDF-4288
|
||||
endchoice
|
||||
|
||||
config IDF_TARGET_ESP32C2
|
||||
|
||||
@@ -42,7 +42,7 @@ This can also contain files provided by the architecture vendor.
|
||||
Example:
|
||||
|
||||
- `xt_set_exception_handler`
|
||||
- `rv_utils_intr_enable`
|
||||
- `riscv_global_interrupts_enable`
|
||||
- `ERI_PERFMON_MAX`
|
||||
|
||||
#### `esp_common`
|
||||
|
||||
@@ -54,15 +54,13 @@ idf_component_register(SRCS "${srcs}"
|
||||
REQUIRES esp_timer
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
if(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
# disable --coverage for this component, as it is used as transport
|
||||
# for gcov
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
|
||||
# Force app_trace to also appear later than gcov in link line
|
||||
idf_component_get_property(app_trace app_trace COMPONENT_LIB)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE
|
||||
"-Wl,--undefined=gcov_rtio_atexit" $<TARGET_FILE:${app_trace}> gcov $<TARGET_FILE:${app_trace}> c)
|
||||
endif()
|
||||
# disable --coverage for this component, as it is used as transport
|
||||
# for gcov
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
|
||||
|
||||
# Force app_trace to also appear later than gcov in link line
|
||||
idf_component_get_property(app_trace app_trace COMPONENT_LIB)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${app_trace}> gcov $<TARGET_FILE:${app_trace}> c)
|
||||
|
||||
# This function adds a dependency on the given component if the component is included into the build.
|
||||
function(maybe_add_component component_name)
|
||||
|
||||
@@ -389,11 +389,4 @@ menu "Application Level Tracing"
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
|
||||
config APPTRACE_GCOV_DUMP_TASK_STACK_SIZE
|
||||
int "Gcov dump task stack size"
|
||||
depends on APPTRACE_GCOV_ENABLE
|
||||
default 2048
|
||||
help
|
||||
Configures stack size of Gcov dump task
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
#include "esp_private/esp_ipc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/libc_stubs.h"
|
||||
@@ -77,15 +76,14 @@ gcov_exit:
|
||||
void gcov_create_task(void *arg)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", CONFIG_APPTRACE_GCOV_DUMP_TASK_STACK_SIZE,
|
||||
(void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, (void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
}
|
||||
|
||||
static IRAM_ATTR
|
||||
void gcov_create_task_tick_hook(void)
|
||||
{
|
||||
extern esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
if (s_create_gcov_task) {
|
||||
if (esp_ipc_call_nonblocking(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) {
|
||||
if (esp_ipc_start_gcov_from_isr(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) {
|
||||
s_create_gcov_task = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,11 +142,7 @@ static U64 _cbGetTime(void) {
|
||||
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
/* On multi-core we have several idle tasks with 'IDLEx' names
|
||||
Not best solution, because we can filter out user tasks starting with 'IDLE'.
|
||||
But we can not use 'xTaskGetIdleTaskHandle' because at the moment when this
|
||||
function is called array of idle tasks handles are not initialized yet. */
|
||||
if (memcmp(pcTaskName, "IDLE", 4) == 0) {
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -180,11 +176,7 @@ void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPrio
|
||||
void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
/* On multi-core we have several idle tasks with 'IDLEx' names
|
||||
Not best solution, because we can filter out user tasks starting with 'IDLE'.
|
||||
But we can not use 'xTaskGetIdleTaskHandle' because at the moment when this
|
||||
function is called array of idle tasks handles are not initialized yet. */
|
||||
if (memcmp(pcTaskName, "IDLE", 4) == 0) {
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -212,27 +212,63 @@ Notes:
|
||||
#define apiID_UXEVENTGROUPGETNUMBER (73u)
|
||||
|
||||
#ifdef CONFIG_FREERTOS_SMP
|
||||
|
||||
#define traceQUEUE_SEND( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), 0, 0, 0)
|
||||
/*
|
||||
FreeRTOS SMP has diverged from ESP-IDF FreeRTOS source quite a bit, thus Sysview is out of sync. For now, we just
|
||||
define away all of the tracing macros.
|
||||
*/
|
||||
#define traceTASK_NOTIFY_TAKE( uxIndexToWait )
|
||||
#define traceTASK_DELAY()
|
||||
#define traceTASK_DELAY_UNTIL( xTimeToWake )
|
||||
#define traceTASK_DELETE( pxTCB )
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify )
|
||||
#define traceTASK_PRIORITY_INHERIT( pxTCB, uxPriority )
|
||||
#define traceTASK_RESUME( pxTCB )
|
||||
#define traceINCREASE_TICK_COUNT( xTicksToJump )
|
||||
#define traceTASK_SUSPEND( pxTCB )
|
||||
#define traceTASK_PRIORITY_DISINHERIT( pxTCB, uxBasePriority )
|
||||
#define traceTASK_RESUME_FROM_ISR( pxTCB )
|
||||
#define traceTASK_NOTIFY( uxIndexToNotify )
|
||||
#define traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify )
|
||||
#define traceTASK_NOTIFY_WAIT( uxIndexToWait )
|
||||
#define traceQUEUE_CREATE( pxNewQueue )
|
||||
#define traceQUEUE_DELETE( pxQueue )
|
||||
#define traceQUEUE_PEEK( pxQueue )
|
||||
#define traceQUEUE_PEEK_FROM_ISR( pxQueue )
|
||||
#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue )
|
||||
#define traceQUEUE_RECEIVE( pxQueue )
|
||||
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
|
||||
#define traceQUEUE_SEMAPHORE_RECEIVE( pxQueue )
|
||||
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
|
||||
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
|
||||
#define traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName )
|
||||
#define traceQUEUE_SEND( pxQueue )
|
||||
#define traceQUEUE_SEND_FAILED( pxQueue )
|
||||
#define traceQUEUE_SEND_FROM_ISR( pxQueue )
|
||||
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
|
||||
#define traceQUEUE_GIVE_FROM_ISR( pxQueue )
|
||||
#define traceQUEUE_GIVE_FROM_ISR_FAILED( pxQueue )
|
||||
#define traceTASK_CREATE(pxNewTCB)
|
||||
#define traceTASK_PRIORITY_SET(pxTask, uxNewPriority)
|
||||
#define traceTASK_SWITCHED_IN()
|
||||
#define traceMOVED_TASK_TO_READY_STATE(pxTCB)
|
||||
#define traceREADDED_TASK_TO_READY_STATE(pxTCB)
|
||||
#define traceMOVED_TASK_TO_DELAYED_LIST()
|
||||
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST()
|
||||
#define traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB)
|
||||
#define traceISR_EXIT_TO_SCHEDULER()
|
||||
#define traceISR_EXIT()
|
||||
#define traceISR_ENTER(_n_)
|
||||
|
||||
#else // CONFIG_FREERTOS_SMP
|
||||
|
||||
#if ( configUSE_QUEUE_SETS != 1 )
|
||||
#define traceQUEUE_SEND( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, xTicksToWait, xCopyPosition)
|
||||
#else
|
||||
#define traceQUEUE_SEND( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), 0, 0, xCopyPosition)
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_FREERTOS_SMP
|
||||
|
||||
#define traceTASK_NOTIFY_TAKE( uxIndexToWait ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_ULTASKNOTIFYTAKE, xClearCountOnExit, xTicksToWait)
|
||||
#define traceTASK_DELAY() SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKDELAY, xTicksToDelay)
|
||||
#define traceTASK_DELAY_UNTIL( xTimeToWake ) SEGGER_SYSVIEW_RecordVoid(apiFastID_OFFSET + apiID_VTASKDELAYUNTIL)
|
||||
#define traceTASK_DELETE( pxTCB ) do { \
|
||||
SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKDELETE, \
|
||||
SEGGER_SYSVIEW_ShrinkId((U32)pxTCB)); \
|
||||
SYSVIEW_DeleteTask((U32)pxTCB); \
|
||||
} while(0)
|
||||
#define traceTASK_DELAY_UNTIL() SEGGER_SYSVIEW_RecordVoid(apiFastID_OFFSET + apiID_VTASKDELAYUNTIL)
|
||||
#define traceTASK_DELETE( pxTCB ) if (pxTCB != NULL) { \
|
||||
SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKDELETE, \
|
||||
SEGGER_SYSVIEW_ShrinkId((U32)pxTCB)); \
|
||||
SYSVIEW_DeleteTask((U32)pxTCB); \
|
||||
}
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VTASKNOTIFYGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_PRIORITY_INHERIT( pxTCB, uxPriority ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKPRIORITYINHERIT, (U32)pxMutexHolder)
|
||||
#define traceTASK_RESUME( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKRESUME, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
@@ -255,6 +291,11 @@ Notes:
|
||||
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUERECEIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUERECEIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VQUEUEADDTOREGISTRY, SEGGER_SYSVIEW_ShrinkId((U32)xQueue), (U32)pcQueueName)
|
||||
#if ( configUSE_QUEUE_SETS != 1 )
|
||||
#define traceQUEUE_SEND( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, xTicksToWait, xCopyPosition)
|
||||
#else
|
||||
#define traceQUEUE_SEND( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), 0, 0, xCopyPosition)
|
||||
#endif
|
||||
#define traceQUEUE_SEND_FAILED( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, xTicksToWait, xCopyPosition)
|
||||
#define traceQUEUE_SEND_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSENDFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, (U32)pxHigherPriorityTaskWoken, xCopyPosition)
|
||||
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSENDFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, (U32)pxHigherPriorityTaskWoken, xCopyPosition)
|
||||
@@ -297,37 +338,35 @@ Notes:
|
||||
//
|
||||
// Define INCLUDE_xTaskGetIdleTaskHandle as 1 in FreeRTOSConfig.h to allow identification of Idle state.
|
||||
//
|
||||
// SMP FreeRTOS uses unpinned IDLE tasks, so sometimes IDEL0 runs on CPU1, IDLE1 runs on CPU0 and so on.
|
||||
// So IDLE state detection based on 'xTaskGetIdleTaskHandle' does not work for SMP kernel.
|
||||
// We could compare current task handle with every element of the array returned by 'xTaskGetIdleTaskHandle',
|
||||
// but it deos not seem to be efficient enough to be worth of making code more complex and less readabl.
|
||||
// So always use task name comparison mechanism for SMP kernel.
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 && !defined(CONFIG_FREERTOS_SMP))
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
#define traceTASK_SWITCHED_IN() if(prvGetTCBFromHandle(NULL) == xTaskGetIdleTaskHandle()) { \
|
||||
SEGGER_SYSVIEW_OnIdle(); \
|
||||
} else { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)prvGetTCBFromHandle(NULL)); \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[esp_cpu_get_core_id()]); \
|
||||
}
|
||||
#else
|
||||
#define traceTASK_SWITCHED_IN() { \
|
||||
if (memcmp(prvGetTCBFromHandle(NULL)->pcTaskName, "IDLE", 4) != 0) { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)prvGetTCBFromHandle(NULL)); \
|
||||
if (memcmp(pxCurrentTCB[esp_cpu_get_core_id()]->pcTaskName, "IDLE", 5) != 0) { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[esp_cpu_get_core_id()]); \
|
||||
} else { \
|
||||
SEGGER_SYSVIEW_OnIdle(); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define traceMOVED_TASK_TO_READY_STATE(pxTCB) SEGGER_SYSVIEW_OnTaskStartReady((U32)pxTCB)
|
||||
#define traceREADDED_TASK_TO_READY_STATE(pxTCB)
|
||||
|
||||
#define traceMOVED_TASK_TO_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)prvGetTCBFromHandle(NULL)], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)prvGetTCBFromHandle(NULL)], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[esp_cpu_get_core_id()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[esp_cpu_get_core_id()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB) SEGGER_SYSVIEW_OnTaskStopReady((U32)pxTCB, ((3u << 3) | 3))
|
||||
|
||||
#define traceISR_EXIT_TO_SCHEDULER() SEGGER_SYSVIEW_RecordExitISRToScheduler()
|
||||
#define traceISR_EXIT() SEGGER_SYSVIEW_RecordExitISR()
|
||||
#define traceISR_ENTER(_n_) SEGGER_SYSVIEW_RecordEnterISR(_n_)
|
||||
|
||||
#endif // CONFIG_FREERTOS_SMP
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* API functions
|
||||
|
||||
@@ -21,7 +21,7 @@ const static char *TAG = "sysview_heap_trace";
|
||||
#endif
|
||||
|
||||
static SEGGER_SYSVIEW_MODULE s_esp_sysview_heap_module = {
|
||||
.sModule = "M=ESP32 SystemView Heap Tracing Module",
|
||||
.sModule = "ESP32 SystemView Heap Tracing Module",
|
||||
.NumEvents = 2,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,30 @@
|
||||
idf_component_register(SRCS "esp_ota_ops.c" "esp_ota_app_desc.c"
|
||||
idf_component_register(SRCS "esp_ota_ops.c"
|
||||
"esp_app_desc.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES partition_table bootloader_support esp_app_format esp_partition
|
||||
PRIV_REQUIRES esptool_py efuse spi_flash)
|
||||
REQUIRES spi_flash partition_table bootloader_support
|
||||
PRIV_REQUIRES esptool_py efuse)
|
||||
|
||||
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
||||
# linker will ignore this structure as it has no other files depending on it.
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
|
||||
|
||||
if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
|
||||
# Ignore current PROJECT_VER (which was set in __project_get_revision()).
|
||||
# Gets the version from the CONFIG_APP_PROJECT_VER.
|
||||
idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
|
||||
endif()
|
||||
|
||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||
idf_build_get_property(project_ver PROJECT_VER)
|
||||
idf_build_get_property(project_name PROJECT_NAME)
|
||||
string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
|
||||
string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
|
||||
message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")
|
||||
|
||||
set_source_files_properties(
|
||||
SOURCE "esp_app_desc.c"
|
||||
PROPERTIES COMPILE_DEFINITIONS
|
||||
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
partition_table_get_partition_info(otadata_offset "--partition-type data --partition-subtype ota" "offset")
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_app_desc.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
// Application version info
|
||||
const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
.magic_word = ESP_APP_DESC_MAGIC_WORD,
|
||||
@@ -51,7 +50,7 @@ _Static_assert(sizeof(IDF_VER) <= sizeof(esp_app_desc.idf_ver), "IDF_VER is long
|
||||
_Static_assert(sizeof(PROJECT_NAME) <= sizeof(esp_app_desc.project_name), "PROJECT_NAME is longer than project_name field in structure");
|
||||
#endif
|
||||
|
||||
const esp_app_desc_t *esp_app_get_description(void)
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void)
|
||||
{
|
||||
return &esp_app_desc;
|
||||
}
|
||||
@@ -65,18 +64,18 @@ static inline char IRAM_ATTR to_hex_digit(unsigned val)
|
||||
return (val < 10) ? ('0' + val) : ('a' + val - 10);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void esp_init_app_elf_sha256(void)
|
||||
__attribute__((constructor)) void esp_ota_init_app_elf_sha256(void)
|
||||
{
|
||||
esp_app_get_elf_sha256(NULL, 0);
|
||||
esp_ota_get_app_elf_sha256(NULL, 0);
|
||||
}
|
||||
|
||||
/* The esp_app_desc.app_elf_sha256 should be possible to print in panic handler during cache is disabled.
|
||||
* But because the cache is disabled the reading esp_app_desc.app_elf_sha256 is not right and
|
||||
* can lead to a complete lock-up of the CPU.
|
||||
* For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_init_app_elf_sha256()
|
||||
* For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_ota_init_app_elf_sha256()
|
||||
* and keep it in the static s_app_elf_sha256 value.
|
||||
*/
|
||||
int IRAM_ATTR esp_app_get_elf_sha256(char* dst, size_t size)
|
||||
int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
|
||||
{
|
||||
static char s_app_elf_sha256[CONFIG_APP_RETRIEVE_LEN_ELF_SHA / 2];
|
||||
static bool first_call = true;
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void)
|
||||
{
|
||||
return esp_app_get_description();
|
||||
}
|
||||
|
||||
int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
|
||||
{
|
||||
return esp_app_get_elf_sha256(dst, size);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
@@ -83,16 +84,16 @@ static const esp_partition_t *read_otadata(esp_ota_select_entry_t *two_otadata)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_partition_mmap_handle_t ota_data_map;
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
esp_err_t err = esp_partition_mmap(otadata_partition, 0, otadata_partition->size, ESP_PARTITION_MMAP_DATA, &result, &ota_data_map);
|
||||
esp_err_t err = esp_partition_mmap(otadata_partition, 0, otadata_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "mmap otadata filed. Err=0x%8x", err);
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&two_otadata[0], result, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&two_otadata[1], result + SPI_FLASH_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
esp_partition_munmap(ota_data_map);
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
return otadata_partition;
|
||||
}
|
||||
@@ -193,18 +194,13 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
ESP_LOGD(TAG, "write data size is 0");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// find ota handle in linked list
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
if (it->need_erase) {
|
||||
// must erase the partition before writing to it
|
||||
uint32_t first_sector = it->wrote_size / SPI_FLASH_SEC_SIZE; // first affected sector
|
||||
uint32_t last_sector = (it->wrote_size + size - 1) / SPI_FLASH_SEC_SIZE; // last affected sector
|
||||
uint32_t first_sector = it->wrote_size / SPI_FLASH_SEC_SIZE;
|
||||
uint32_t last_sector = (it->wrote_size + size) / SPI_FLASH_SEC_SIZE;
|
||||
|
||||
ret = ESP_OK;
|
||||
if ((it->wrote_size % SPI_FLASH_SEC_SIZE) == 0) {
|
||||
@@ -655,14 +651,8 @@ esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, es
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
static esp_err_t esp_ota_set_anti_rollback(void) {
|
||||
const esp_partition_t* partition = esp_ota_get_running_partition();
|
||||
esp_app_desc_t app_desc = {0};
|
||||
|
||||
esp_err_t err = esp_ota_get_partition_description(partition, &app_desc);
|
||||
if (err == ESP_OK) {
|
||||
return esp_efuse_update_secure_version(app_desc.secure_version);
|
||||
}
|
||||
return err;
|
||||
const esp_app_desc_t *app_desc = esp_ota_get_app_description();
|
||||
return esp_efuse_update_secure_version(app_desc->secure_version);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -899,27 +889,9 @@ esp_err_t esp_ota_erase_last_boot_app_partition(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index) {
|
||||
|
||||
// Validates the image at "app_pos" with the secure boot digests other than "revoked_key_index"
|
||||
static bool validate_img(esp_ota_secure_boot_public_key_index_t revoked_key_index, esp_partition_pos_t *app_pos)
|
||||
{
|
||||
bool verified = false;
|
||||
for (int i = 0; i < SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS; i++) {
|
||||
if (i == revoked_key_index) {
|
||||
continue;
|
||||
}
|
||||
if (esp_secure_boot_verify_with_efuse_digest_index(i, app_pos) == ESP_OK) {
|
||||
verified = true;
|
||||
ESP_LOGI(TAG, "Application successfully verified with public key digest %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return verified;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index)
|
||||
{
|
||||
if (!esp_secure_boot_enabled()) {
|
||||
ESP_LOGE(TAG, "Secure boot v2 has not been enabled.");
|
||||
return ESP_FAIL;
|
||||
@@ -932,21 +904,14 @@ esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_i
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const esp_partition_t *running_app_part = esp_ota_get_running_partition();
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
esp_ota_img_states_t running_app_state;
|
||||
ret = esp_ota_get_state_partition(running_app_part, &running_app_state);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ota_get_state_partition returned: %s", esp_err_to_name(ret));
|
||||
esp_image_sig_public_key_digests_t app_digests = { 0 };
|
||||
esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(true, &app_digests);
|
||||
if (err != ESP_OK || app_digests.num_digests == 0) {
|
||||
ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (running_app_state != ESP_OTA_IMG_VALID) {
|
||||
ESP_LOGE(TAG, "The current running application is not marked as a valid image. Aborting..");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t ret;
|
||||
esp_secure_boot_key_digests_t trusted_keys;
|
||||
ret = esp_secure_boot_read_key_digests(&trusted_keys);
|
||||
if (ret != ESP_OK) {
|
||||
@@ -955,38 +920,55 @@ esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_i
|
||||
}
|
||||
|
||||
if (trusted_keys.key_digests[index] == NULL) {
|
||||
ESP_LOGI(TAG, "Given public key digest(%d) is already revoked.", index);
|
||||
ESP_LOGI(TAG, "Trusted Key block(%d) already revoked.", index);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Check if the application can be verified with a key other than the one being revoked */
|
||||
esp_partition_pos_t running_app_pos = {
|
||||
.offset = running_app_part->address,
|
||||
.size = running_app_part->size,
|
||||
};
|
||||
esp_image_sig_public_key_digests_t trusted_digests = { 0 };
|
||||
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
|
||||
if (i == index) {
|
||||
continue; // omitting - to find if there is a valid key after revoking this digest
|
||||
}
|
||||
|
||||
if (!validate_img(index, &running_app_pos)) {
|
||||
ESP_LOGE(TAG, "Application cannot be verified with any key other than the one being revoked");
|
||||
if (trusted_keys.key_digests[i] != NULL) {
|
||||
bool all_zeroes = true;
|
||||
for (unsigned j = 0; j < ESP_SECURE_BOOT_DIGEST_LEN; j++) {
|
||||
all_zeroes = all_zeroes && (*(uint8_t *)(trusted_keys.key_digests[i] + j) == 0);
|
||||
}
|
||||
if (!all_zeroes) {
|
||||
memcpy(trusted_digests.key_digests[trusted_digests.num_digests++], (uint8_t *)trusted_keys.key_digests[i], ESP_SECURE_BOOT_DIGEST_LEN);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Empty trusted key block (%d).", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool match = false;
|
||||
for (unsigned i = 0; i < trusted_digests.num_digests; i++) {
|
||||
if (match == true) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < app_digests.num_digests; j++) {
|
||||
if (memcmp(trusted_digests.key_digests[i], app_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN) == 0) {
|
||||
ESP_LOGI(TAG, "App key block(%d) matches Trusted key block(%d)[%d -> Next active trusted key block].", j, i, i);
|
||||
esp_err_t err = esp_efuse_set_digest_revoke(index);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to revoke digest (0x%x).", err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Revoked signature block %d.", index);
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match == false) {
|
||||
ESP_LOGE(TAG, "Running app doesn't have another valid secure boot key. Cannot revoke current key(%d).", index);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Check if bootloder can be verified with any key other than the one being revoked */
|
||||
esp_partition_pos_t bootloader_pos = {
|
||||
.offset = ESP_BOOTLOADER_OFFSET,
|
||||
.size = (ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET),
|
||||
};
|
||||
|
||||
if (!validate_img(index, &bootloader_pos)) {
|
||||
ESP_LOGE(TAG, "Bootloader cannot be verified with any key other than the one being revoked");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_efuse_set_digest_revoke(index);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to revoke digest (0x%x).", err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Revoked signature block %d.", index);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_app_desc.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
@@ -44,27 +44,20 @@ typedef uint32_t esp_ota_handle_t;
|
||||
/**
|
||||
* @brief Return esp_app_desc structure. This structure includes app version.
|
||||
*
|
||||
* @note This API is present for backward compatibility reasons. Alternative function
|
||||
* with the same functionality is `esp_app_get_description`
|
||||
*
|
||||
* Return description for running app.
|
||||
* @return Pointer to esp_app_desc structure.
|
||||
*/
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void) __attribute__((deprecated("Please use esp_app_get_description instead")));
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void);
|
||||
|
||||
/**
|
||||
* @brief Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
|
||||
* If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
|
||||
* the largest possible number of bytes will be written followed by a null.
|
||||
*
|
||||
* @note This API is present for backward compatibility reasons. Alternative function
|
||||
* with the same functionality is `esp_app_get_elf_sha256`
|
||||
*
|
||||
* @param dst Destination buffer
|
||||
* @param size Size of the buffer
|
||||
* @return Number of bytes written to dst (including null terminator)
|
||||
*/
|
||||
int esp_ota_get_app_elf_sha256(char* dst, size_t size) __attribute__((deprecated("Please use esp_app_get_elf_sha256 instead")));
|
||||
int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Commence an OTA update writing to the specified partition.
|
||||
@@ -110,7 +103,7 @@ esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp
|
||||
* @param size Size of data buffer in bytes.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Data was written to flash successfully, or size = 0
|
||||
* - ESP_OK: Data was written to flash successfully.
|
||||
* - ESP_ERR_INVALID_ARG: handle is invalid.
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid app image magic byte.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
@@ -332,10 +325,10 @@ typedef enum {
|
||||
} esp_ota_secure_boot_public_key_index_t;
|
||||
|
||||
/**
|
||||
* @brief Revokes the signature digest denoted by the given index. This should be called in the application only after the rollback logic otherwise the device may end up in unrecoverable state.
|
||||
* @brief Revokes the old signature digest. To be called in the application after the rollback logic.
|
||||
*
|
||||
* Relevant for Secure boot v2 on ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6, ESP32-H2 where up to 3 key digests can be stored (Key \#N-1, Key \#N, Key \#N+1).
|
||||
* When a key used to sign an app is invalidated, an OTA update is to be sent with an app signed with at least one of the other two keys which has not been revoked already.
|
||||
* Relevant for Secure boot v2 on ESP32-S2, ESP32-S3, ESP32-C3, ESP32-H2 where upto 3 key digests can be stored (Key \#N-1, Key \#N, Key \#N+1).
|
||||
* When key \#N-1 used to sign an app is invalidated, an OTA update is to be sent with an app signed with key \#N-1 & Key \#N.
|
||||
* After successfully booting the OTA app should call this function to revoke Key \#N-1.
|
||||
*
|
||||
* @param index - The index of the signature block to be revoked
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash driver spi_flash
|
||||
PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash driver
|
||||
)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
|
||||
@@ -1,26 +1,13 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_app_desc.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "unity.h"
|
||||
#include "unity_fixture.h"
|
||||
|
||||
TEST_GROUP(esp_app_format);
|
||||
|
||||
TEST_SETUP(esp_app_format)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(esp_app_format)
|
||||
{
|
||||
}
|
||||
|
||||
TEST(esp_app_format, esp_app_get_elf_sha256_test)
|
||||
TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
|
||||
{
|
||||
const int sha256_hex_len = CONFIG_APP_RETRIEVE_LEN_ELF_SHA;
|
||||
char dst[sha256_hex_len + 2];
|
||||
@@ -29,17 +16,17 @@ TEST(esp_app_format, esp_app_get_elf_sha256_test)
|
||||
size_t len;
|
||||
|
||||
char ref_sha256[sha256_hex_len + 1];
|
||||
const esp_app_desc_t* desc = esp_app_get_description();
|
||||
const esp_app_desc_t* desc = esp_ota_get_app_description();
|
||||
for (int i = 0; i < sizeof(ref_sha256) / 2; ++i) {
|
||||
snprintf(ref_sha256 + 2*i, 3, "%02x", desc->app_elf_sha256[i]);
|
||||
}
|
||||
ref_sha256[sha256_hex_len] = 0;
|
||||
|
||||
printf("\nRef: %s\n", ref_sha256);
|
||||
printf("Ref: %s\n", ref_sha256);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = sizeof(dst);
|
||||
res = esp_app_get_elf_sha256(dst, len);
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
TEST_ASSERT_EQUAL(sha256_hex_len + 1, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
@@ -48,7 +35,7 @@ TEST(esp_app_format, esp_app_get_elf_sha256_test)
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = 9;
|
||||
res = esp_app_get_elf_sha256(dst, len);
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
TEST_ASSERT_EQUAL(9, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
@@ -57,7 +44,7 @@ TEST(esp_app_format, esp_app_get_elf_sha256_test)
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = 8;
|
||||
res = esp_app_get_elf_sha256(dst, len);
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
// should output even number of characters plus '\0'
|
||||
TEST_ASSERT_EQUAL(7, res);
|
||||
@@ -66,13 +53,3 @@ TEST(esp_app_format, esp_app_get_elf_sha256_test)
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[7]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[8]);
|
||||
}
|
||||
|
||||
TEST_GROUP_RUNNER(esp_app_format)
|
||||
{
|
||||
RUN_TEST_CASE(esp_app_format, esp_app_get_elf_sha256_test)
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
UNITY_MAIN(esp_app_format);
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
@@ -14,6 +13,7 @@
|
||||
#include <unity.h>
|
||||
#include <test_utils.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include "bootloader_common.h"
|
||||
|
||||
/* These OTA tests currently don't assume an OTA partition exists
|
||||
on the device, so they're a bit limited
|
||||
@@ -91,8 +91,6 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
|
||||
|
||||
TEST_CASE("esp_ota_get_partition_description", "[ota]")
|
||||
{
|
||||
extern esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
|
||||
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
TEST_ASSERT_NOT_NULL(running);
|
||||
esp_app_desc_t app_desc1, app_desc2;
|
||||
@@ -114,11 +112,3 @@ TEST_CASE("esp_ota_get_partition_description", "[ota]")
|
||||
};
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, bootloader_common_get_partition_description(¬_app_pos, &app_desc1));
|
||||
}
|
||||
|
||||
TEST_CASE("esp_ota_get_running_partition points to correct address", "[spi_flash]")
|
||||
{
|
||||
const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "factory");
|
||||
const esp_partition_t* part = esp_ota_get_running_partition();
|
||||
ESP_LOGI("running bin", "0x%p", (void*)part->address);
|
||||
TEST_ASSERT_EQUAL_HEX32(factory->address, part->address);
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ static const char *TAG = "ota_test";
|
||||
static void copy_app_partition(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
esp_partition_mmap_handle_t data_map;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
ESP_LOGI(TAG, "start the copy process");
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, 0, curr_app->size, ESP_PARTITION_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, 0, curr_app->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_ota_write(update_handle, (const void *)partition_bin, curr_app->size));
|
||||
esp_partition_munmap(data_map);
|
||||
spi_flash_munmap(data_map);
|
||||
ESP_LOGI(TAG, "finish the copy process");
|
||||
}
|
||||
|
||||
@@ -65,15 +65,15 @@ static void copy_app_partition(esp_ota_handle_t update_handle, const esp_partiti
|
||||
static void copy_app_partition_with_offset(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
esp_partition_mmap_handle_t data_map;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
ESP_LOGI(TAG, "start the copy process");
|
||||
uint32_t offset = 0, bytes_to_write = curr_app->size;
|
||||
uint32_t write_bytes;
|
||||
while (bytes_to_write > 0) {
|
||||
write_bytes = (bytes_to_write > (4 * 1024)) ? (4 * 1024) : bytes_to_write;
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, offset, write_bytes, ESP_PARTITION_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, offset, write_bytes, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_ota_write_with_offset(update_handle, (const void *)partition_bin, write_bytes, offset));
|
||||
esp_partition_munmap(data_map);
|
||||
spi_flash_munmap(data_map);
|
||||
bytes_to_write -= write_bytes;
|
||||
offset += write_bytes;
|
||||
}
|
||||
@@ -90,11 +90,11 @@ static void copy_app_partition_with_offset(esp_ota_handle_t update_handle, const
|
||||
static void copy_partition(const esp_partition_t *dst_partition, const esp_partition_t *src_partition)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
esp_partition_mmap_handle_t data_map;
|
||||
TEST_ESP_OK(esp_partition_mmap(src_partition, 0, src_partition->size, ESP_PARTITION_MMAP_DATA, &partition_bin, &data_map));
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
TEST_ESP_OK(esp_partition_mmap(src_partition, 0, src_partition->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_partition_erase_range(dst_partition, 0, dst_partition->size));
|
||||
TEST_ESP_OK(esp_partition_write(dst_partition, 0, (const void *)partition_bin, dst_partition->size));
|
||||
esp_partition_munmap(data_map);
|
||||
spi_flash_munmap(data_map);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -62,66 +62,34 @@ menu "Bootloader config"
|
||||
default 4 if BOOTLOADER_LOG_LEVEL_DEBUG
|
||||
default 5 if BOOTLOADER_LOG_LEVEL_VERBOSE
|
||||
|
||||
menu "Serial Flash Configurations"
|
||||
config BOOTLOADER_SPI_CUSTOM_WP_PIN
|
||||
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
|
||||
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
||||
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
|
||||
default n
|
||||
help
|
||||
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
|
||||
SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT.
|
||||
config BOOTLOADER_SPI_CUSTOM_WP_PIN
|
||||
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
|
||||
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
||||
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
|
||||
default n
|
||||
help
|
||||
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
|
||||
SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT.
|
||||
|
||||
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
|
||||
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used
|
||||
for external SPIRAM if it is enabled.
|
||||
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
|
||||
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used
|
||||
for external SPIRAM if it is enabled.
|
||||
|
||||
If this config item is set to N (default), the correct WP pin will be automatically used for any
|
||||
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to
|
||||
Y and specify the GPIO number connected to the WP.
|
||||
If this config item is set to N (default), the correct WP pin will be automatically used for any
|
||||
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to
|
||||
Y and specify the GPIO number connected to the WP.
|
||||
|
||||
config BOOTLOADER_SPI_WP_PIN
|
||||
int "Custom SPI Flash WP Pin"
|
||||
range 0 33
|
||||
default 7
|
||||
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
||||
#depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5
|
||||
help
|
||||
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored
|
||||
config BOOTLOADER_SPI_WP_PIN
|
||||
int "Custom SPI Flash WP Pin"
|
||||
range 0 33
|
||||
default 7
|
||||
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
||||
#depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5
|
||||
help
|
||||
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored
|
||||
|
||||
If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this
|
||||
value to the GPIO number of the SPI flash WP pin.
|
||||
|
||||
config BOOTLOADER_FLASH_DC_AWARE
|
||||
bool "Allow app adjust Dummy Cycle bits in SPI Flash for higher frequency (READ HELP FIRST)"
|
||||
help
|
||||
This will force 2nd bootloader to be loaded by DOUT mode, and will restore Dummy Cycle setting by
|
||||
resetting the Flash
|
||||
|
||||
config BOOTLOADER_FLASH_XMC_SUPPORT
|
||||
bool "Enable the support for flash chips of XMC (READ DOCS FIRST)"
|
||||
default y
|
||||
help
|
||||
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
|
||||
XMC chips will be forbidden to be used, when this option is disabled.
|
||||
|
||||
DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
|
||||
comment "Features below require specific hardware (READ DOCS FIRST!)"
|
||||
|
||||
config BOOTLOADER_FLASH_32BIT_ADDR
|
||||
bool
|
||||
default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
|
||||
default n
|
||||
help
|
||||
This is a helper config for 32bits address flash. Invisible for users.
|
||||
|
||||
config BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||
bool
|
||||
default y if ESPTOOLPY_OCT_FLASH && BOOTLOADER_FLASH_32BIT_ADDR
|
||||
default n
|
||||
|
||||
endmenu
|
||||
If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this
|
||||
value to the GPIO number of the SPI flash WP pin.
|
||||
|
||||
choice BOOTLOADER_VDDSDIO_BOOST
|
||||
bool "VDDSDIO LDO voltage"
|
||||
@@ -398,7 +366,7 @@ menu "Bootloader config"
|
||||
# only available if both Secure Boot and Check Signature on Boot are disabled
|
||||
depends on !SECURE_SIGNED_ON_BOOT
|
||||
default n
|
||||
select BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP if SOC_RTC_FAST_MEM_SUPPORTED
|
||||
select BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
|
||||
select BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
|
||||
help
|
||||
Selecting this option prevents the bootloader from ever validating the app image before
|
||||
@@ -433,23 +401,9 @@ menu "Bootloader config"
|
||||
(The application and bootoloader must be compiled with the same option).
|
||||
The RTC FAST memory has access only through PRO_CPU.
|
||||
|
||||
config BOOTLOADER_CUSTOM_RESERVE_RTC_IN_CRC
|
||||
bool "Include custom memory in the CRC calculation"
|
||||
depends on BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||
default n
|
||||
help
|
||||
This option allows the customer to use the legacy bootloader behavior when the
|
||||
RTC FAST memory CRC calculation takes place. When this option is enabled, the
|
||||
allocated user custom data will be taken into account in the CRC calculcation.
|
||||
This means that any change to the custom data would need a CRC update to prevent
|
||||
the bootloader from marking this data as corrupted.
|
||||
If this option is disabled, the custom data will not be taken into account when
|
||||
calculating the RTC FAST memory CRC. The user custom data can be changed freely,
|
||||
without the need to update the CRC.
|
||||
THIS OPTION MUST BE THE SAME FOR BOTH THE BOOTLOADER AND THE APPLICATION BUILDS.
|
||||
|
||||
config BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE
|
||||
hex "Size in bytes for custom purposes"
|
||||
range 0 0x10
|
||||
default 0
|
||||
depends on BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||
help
|
||||
@@ -458,6 +412,14 @@ menu "Bootloader config"
|
||||
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
|
||||
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.
|
||||
|
||||
config BOOTLOADER_FLASH_XMC_SUPPORT
|
||||
bool "Enable the support for flash chips of XMC (READ HELP FIRST)"
|
||||
default y
|
||||
help
|
||||
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
|
||||
XMC chips will be forbidden to be used, when this option is disabled.
|
||||
|
||||
DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
|
||||
endmenu # Bootloader
|
||||
|
||||
@@ -488,8 +450,8 @@ menu "Security features"
|
||||
config SECURE_BOOT_V2_RSA_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
# RSA secure boot is supported in ESP32 revision >= v3.0
|
||||
depends on (IDF_TARGET_ESP32 && ESP32_REV_MIN_FULL >= 300) || SOC_SECURE_BOOT_V2_RSA
|
||||
# RSA secure boot is supported in ESP32 revision >= ECO3
|
||||
depends on (IDF_TARGET_ESP32 && ESP32_REV_MIN >= 3) || SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
config SECURE_BOOT_V2_ECC_SUPPORTED
|
||||
bool
|
||||
@@ -504,7 +466,7 @@ menu "Security features"
|
||||
config SECURE_BOOT_V2_PREFERRED
|
||||
bool
|
||||
default y
|
||||
depends on ESP32_REV_MIN_FULL >= 300
|
||||
depends on ESP32_REV_MIN >= 3
|
||||
|
||||
config SECURE_BOOT_V2_ECDSA_ENABLED
|
||||
bool
|
||||
@@ -625,8 +587,8 @@ menu "Security features"
|
||||
config SECURE_BOOT
|
||||
bool "Enable hardware Secure Boot in bootloader (READ DOCS FIRST)"
|
||||
default n
|
||||
# Secure boot is not supported for ESP32-C3 revision < v0.3
|
||||
depends on SOC_SECURE_BOOT_SUPPORTED && !(IDF_TARGET_ESP32C3 && ESP32C3_REV_MIN_FULL < 3)
|
||||
# Secure boot is not supported for ESP32-C3 revision < ECO3
|
||||
depends on SOC_SECURE_BOOT_SUPPORTED && !(IDF_TARGET_ESP32C3 && ESP32C3_REV_MIN < 3)
|
||||
select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2
|
||||
help
|
||||
Build a bootloader which enables Secure Boot on first boot.
|
||||
@@ -730,12 +692,14 @@ menu "Security features"
|
||||
|
||||
config SECURE_BOOT_VERIFICATION_KEY
|
||||
string "Secure boot public signature verification key"
|
||||
depends on SECURE_SIGNED_APPS && SECURE_SIGNED_APPS_ECDSA_SCHEME && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
depends on SECURE_SIGNED_APPS && !SECURE_BOOT_BUILD_SIGNED_BINARIES && !SECURE_SIGNED_APPS_RSA_SCHEME
|
||||
default "signature_verification_key.bin"
|
||||
help
|
||||
Path to a public key file used to verify signed images.
|
||||
Secure Boot V1: This ECDSA public key is compiled into the bootloader and/or
|
||||
app, to verify app images.
|
||||
Secure Boot V2: This RSA public key is compiled into the signature block at
|
||||
the end of the bootloader/app.
|
||||
|
||||
Key file is in raw binary format, and can be extracted from a
|
||||
PEM formatted private key using the espsecure.py
|
||||
@@ -987,22 +951,6 @@ menu "Security features"
|
||||
|
||||
endmenu # Potentially Insecure
|
||||
|
||||
config SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART
|
||||
bool "Encrypt only the app image that is present in the partition of type app"
|
||||
depends on SECURE_FLASH_ENC_ENABLED && !SECURE_FLASH_REQUIRE_ALREADY_ENABLED
|
||||
default n
|
||||
help
|
||||
If set, optimise encryption time for the partition of type APP,
|
||||
by only encrypting the app image that is present in the partition,
|
||||
instead of the whole partition.
|
||||
The image length used for encryption is derived from the image metadata, which
|
||||
includes the size of the app image, checksum, hash and also the signature sector
|
||||
when secure boot is enabled.
|
||||
|
||||
If not set (default), the whole partition of type APP would be encrypted,
|
||||
which increases the encryption time but might be useful if there
|
||||
is any custom data appended to the firmware image.
|
||||
|
||||
config SECURE_FLASH_CHECK_ENC_EN_IN_APP
|
||||
bool "Check Flash Encryption enabled on app startup"
|
||||
depends on SECURE_FLASH_ENC_ENABLED
|
||||
@@ -1024,7 +972,7 @@ menu "Security features"
|
||||
default SECURE_ENABLE_SECURE_ROM_DL_MODE if SECURE_ROM_DL_MODE_ENABLED # NOERROR
|
||||
default SECURE_INSECURE_ALLOW_DL_MODE
|
||||
depends on SECURE_BOOT_V2_ENABLED || SECURE_FLASH_ENC_ENABLED
|
||||
depends on !(IDF_TARGET_ESP32 && ESP32_REV_MIN_FULL < 300)
|
||||
depends on !IDF_TARGET_ESP32 || ESP32_REV_MIN_3
|
||||
|
||||
config SECURE_DISABLE_ROM_DL_MODE
|
||||
bool "UART ROM download mode (Permanently disabled (recommended))"
|
||||
@@ -1050,9 +998,9 @@ menu "Security features"
|
||||
Download Mode into a separate Secure Download mode. This option can only work if
|
||||
Download Mode is not already disabled by eFuse.
|
||||
|
||||
Secure Download mode limits the use of Download Mode functions to update SPI config,
|
||||
changing baud rate, basic flash write and a command to return a summary of currently
|
||||
enabled security features (`get_security_info`).
|
||||
Secure Download mode limits the use of Download Mode functions to simple flash read,
|
||||
write and erase operations, plus a command to return a summary of currently enabled
|
||||
security features.
|
||||
|
||||
Secure Download mode is not compatible with the esptool.py flasher stub feature,
|
||||
espefuse.py, read/writing memory or registers, encrypted download, or any other
|
||||
|
||||
@@ -11,9 +11,8 @@ endif()
|
||||
#
|
||||
idf_build_get_property(build_dir BUILD_DIR)
|
||||
set(BOOTLOADER_BUILD_DIR "${build_dir}/bootloader")
|
||||
set(BOOTLOADER_ELF_FILE "${BOOTLOADER_BUILD_DIR}/bootloader.elf")
|
||||
set(bootloader_binary_files
|
||||
"${BOOTLOADER_ELF_FILE}"
|
||||
"${BOOTLOADER_BUILD_DIR}/bootloader.elf"
|
||||
"${BOOTLOADER_BUILD_DIR}/bootloader.bin"
|
||||
"${BOOTLOADER_BUILD_DIR}/bootloader.map"
|
||||
)
|
||||
@@ -148,5 +147,5 @@ endif()
|
||||
#
|
||||
# So for now we just have the top-level build remove the final build products...
|
||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
|
||||
ADDITIONAL_CLEAN_FILES
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
${bootloader_binary_files})
|
||||
|
||||
@@ -23,5 +23,3 @@ CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_
|
||||
|
||||
# Secure Boot Scheme
|
||||
CONFIG_SECURE_BOOT_ENABLED CONFIG_SECURE_BOOT_V1_ENABLED
|
||||
|
||||
CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||
|
||||
@@ -42,14 +42,6 @@ MEMORY
|
||||
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
|
||||
}
|
||||
|
||||
/* The app may use RAM for static allocations up to the start of iram_loader_seg.
|
||||
* If you have changed something above and this assert fails:
|
||||
* 1. Check what the new value of bootloader_iram_loader_seg start is.
|
||||
* 2. Update the value in this assert.
|
||||
* 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value.
|
||||
*/
|
||||
ASSERT(bootloader_iram_loader_seg_start == 0x403aeb70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
|
||||
|
||||
/* Default entry point: */
|
||||
ENTRY(call_start_cpu0);
|
||||
|
||||
|
||||
@@ -42,14 +42,6 @@ MEMORY
|
||||
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
|
||||
}
|
||||
|
||||
/* The app may use RAM for static allocations up to the start of iram_loader_seg.
|
||||
* If you have changed something above and this assert fails:
|
||||
* 1. Check what the new value of bootloader_iram_loader_seg start is.
|
||||
* 2. Update the value in this assert.
|
||||
* 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c3/memory.ld.in to the same value.
|
||||
*/
|
||||
ASSERT(bootloader_iram_loader_seg_start == 0x403ce710, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
|
||||
|
||||
/* Default entry point: */
|
||||
ENTRY(call_start_cpu0);
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/bootloader_support/test_apps/rtc_custom_section:
|
||||
disable:
|
||||
- if: IDF_TARGET == "esp32c2"
|
||||
temporary: false
|
||||
reason: esp32c2 does not have RTC memory
|
||||
@@ -19,7 +19,7 @@ set(srcs
|
||||
if(BOOTLOADER_BUILD)
|
||||
set(include_dirs "include" "bootloader_flash/include"
|
||||
"private_include")
|
||||
set(priv_requires micro-ecc spi_flash efuse esp_app_format)
|
||||
set(priv_requires micro-ecc spi_flash efuse)
|
||||
list(APPEND srcs
|
||||
"src/bootloader_init.c"
|
||||
"src/bootloader_clock_loader.c"
|
||||
@@ -37,7 +37,7 @@ else()
|
||||
set(include_dirs "include" "bootloader_flash/include")
|
||||
set(priv_include_dirs "private_include")
|
||||
# heap is required for `heap_memory_layout.h` header
|
||||
set(priv_requires spi_flash mbedtls efuse heap esp_app_format)
|
||||
set(priv_requires spi_flash mbedtls efuse app_update heap)
|
||||
endif()
|
||||
|
||||
if(BOOTLOADER_BUILD)
|
||||
@@ -86,15 +86,6 @@ idf_component_register(SRCS "${srcs}"
|
||||
REQUIRES "${requires}"
|
||||
PRIV_REQUIRES "${priv_requires}")
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
if(CONFIG_SECURE_SIGNED_ON_UPDATE)
|
||||
if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR
|
||||
CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE idf::app_update)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_SECURE_SIGNED_APPS AND (CONFIG_SECURE_BOOT_V1_ENABLED OR CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME))
|
||||
if(BOOTLOADER_BUILD)
|
||||
# Whether CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES or not, we need verification key to embed
|
||||
@@ -150,7 +141,7 @@ if(CONFIG_SECURE_SIGNED_APPS AND (CONFIG_SECURE_BOOT_V1_ENABLED OR CONFIG_SECURE
|
||||
target_add_binary_data(${COMPONENT_LIB} "${secure_boot_verification_key}" "BINARY"
|
||||
RENAME_TO signature_verification_key_bin)
|
||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
APPEND PROPERTY ADDITIONAL_CLEAN_FILES
|
||||
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${secure_boot_verification_key}")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -57,13 +57,6 @@ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
|
||||
*/
|
||||
esp_err_t bootloader_flash_reset_chip(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the spi flash working mode.
|
||||
*
|
||||
* @return The mode of flash working mode, see `esp_rom_spiflash_read_mode_t`
|
||||
*/
|
||||
esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -109,17 +109,6 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup
|
||||
*/
|
||||
esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
|
||||
|
||||
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||
/**
|
||||
* @brief Enable 32bits address flash(larger than 16MB) can map to cache.
|
||||
*
|
||||
* @param flash_mode SPI flash working mode.
|
||||
*
|
||||
* @note This can be overridden because it's attribute weak.
|
||||
*/
|
||||
void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
#define FLASH_BLOCK_SIZE 0x10000
|
||||
#define MMAP_ALIGNED_MASK (SPI_FLASH_MMU_PAGE_SIZE - 1)
|
||||
#define MMAP_ALIGNED_MASK 0x0000FFFF
|
||||
#define MMU_FLASH_MASK (~(SPI_FLASH_MMU_PAGE_SIZE - 1))
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,6 @@ extern "C" {
|
||||
#define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */
|
||||
#define CMD_RESETEN 0x66
|
||||
#define CMD_RESET 0x99
|
||||
#define CMD_FASTRD_4B 0x0C
|
||||
#define CMD_SLOWRD_4B 0x13
|
||||
|
||||
|
||||
/* Provide a Flash API for bootloader_support code,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <esp_flash_encrypt.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
# include "soc/spi_struct.h"
|
||||
@@ -30,7 +29,7 @@
|
||||
#include "esp_rom_spiflash.h"
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
#define ENCRYPTION_IS_VIRTUAL (!efuse_hal_flash_encryption_enabled())
|
||||
#define ENCRYPTION_IS_VIRTUAL 1
|
||||
#else
|
||||
#define ENCRYPTION_IS_VIRTUAL 0
|
||||
#endif
|
||||
@@ -122,9 +121,6 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/mmu_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/opi_flash.h"
|
||||
#endif
|
||||
static const char *TAG = "bootloader_flash";
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@@ -415,33 +411,6 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
return spi_to_esp_err(rc);
|
||||
}
|
||||
|
||||
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||
void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode)
|
||||
{
|
||||
esp_rom_opiflash_spi0rd_t cache_rd = {};
|
||||
switch (flash_mode) {
|
||||
case ESP_ROM_SPIFLASH_FASTRD_MODE:
|
||||
cache_rd.addr_bit_len = 32;
|
||||
cache_rd.dummy_bit_len = 8;
|
||||
cache_rd.cmd = CMD_FASTRD_4B;
|
||||
cache_rd.cmd_bit_len = 8;
|
||||
break;
|
||||
case ESP_ROM_SPIFLASH_SLOWRD_MODE:
|
||||
cache_rd.addr_bit_len = 32;
|
||||
cache_rd.dummy_bit_len = 0;
|
||||
cache_rd.cmd = CMD_SLOWRD_4B;
|
||||
cache_rd.cmd_bit_len = 8;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
cache_hal_disable(CACHE_TYPE_ALL);
|
||||
esp_rom_opiflash_cache_mode_config(flash_mode, &cache_rd);
|
||||
cache_hal_enable(CACHE_TYPE_ALL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
|
||||
@@ -677,7 +646,7 @@ esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode)
|
||||
******************************************************************************/
|
||||
|
||||
#define XMC_SUPPORT CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT
|
||||
#define XMC_VENDOR_ID_1 0x20
|
||||
#define XMC_VENDOR_ID 0x20
|
||||
|
||||
#if BOOTLOADER_BUILD
|
||||
#define BOOTLOADER_FLASH_LOG(level, ...) ESP_LOG##level(TAG, ##__VA_ARGS__)
|
||||
@@ -694,7 +663,7 @@ static IRAM_ATTR bool is_xmc_chip_strict(uint32_t rdid)
|
||||
uint32_t mfid = BYTESHIFT(rdid, 1);
|
||||
uint32_t cpid = BYTESHIFT(rdid, 0);
|
||||
|
||||
if (vendor_id != XMC_VENDOR_ID_1) {
|
||||
if (vendor_id != XMC_VENDOR_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -727,7 +696,7 @@ esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void)
|
||||
// Check the Manufacturer ID in SFDP registers (JEDEC standard). If not XMC chip, no need to run the flow
|
||||
const int sfdp_mfid_addr = 0x10;
|
||||
uint8_t mf_id = (bootloader_flash_read_sfdp(sfdp_mfid_addr, 1) & 0xff);
|
||||
if (mf_id != XMC_VENDOR_ID_1) {
|
||||
if (mf_id != XMC_VENDOR_ID) {
|
||||
BOOTLOADER_FLASH_LOG(D, "non-XMC chip detected by SFDP Read (%02X), skip.", mf_id);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -759,7 +728,7 @@ esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void)
|
||||
static IRAM_ATTR bool is_xmc_chip(uint32_t rdid)
|
||||
{
|
||||
uint32_t vendor_id = (rdid >> 16) & 0xFF;
|
||||
return (vendor_id == XMC_VENDOR_ID_1);
|
||||
return (vendor_id == XMC_VENDOR_ID);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void)
|
||||
@@ -813,40 +782,3 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void)
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void)
|
||||
{
|
||||
esp_rom_spiflash_read_mode_t spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
|
||||
if (spi_ctrl & SPI_FREAD_QIO) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_QIO_MODE;
|
||||
} else if (spi_ctrl & SPI_FREAD_QUAD) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
|
||||
} else if (spi_ctrl & SPI_FREAD_DIO) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_DIO_MODE;
|
||||
} else if (spi_ctrl & SPI_FREAD_DUAL) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
|
||||
} else if (spi_ctrl & SPI_FASTRD_MODE) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
|
||||
} else {
|
||||
spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
|
||||
}
|
||||
#else
|
||||
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
|
||||
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_QIO_MODE;
|
||||
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
|
||||
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_DIO_MODE;
|
||||
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
|
||||
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
|
||||
spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
|
||||
} else {
|
||||
spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
|
||||
}
|
||||
#endif
|
||||
return spi_mode;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_pins.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "flash_qio_mode.h"
|
||||
@@ -169,13 +168,16 @@ int bootloader_flash_get_wp_pin(void)
|
||||
return CONFIG_SPIRAM_SPIWP_SD3_PIN; // can be set for app when DIO or DOUT config used for PSRAM only
|
||||
#else
|
||||
// no custom value, find it based on the package eFuse value
|
||||
switch(bootloader_common_get_chip_ver_pkg()) {
|
||||
uint8_t chip_ver;
|
||||
uint32_t pkg_ver = bootloader_common_get_chip_ver_pkg();
|
||||
switch(pkg_ver) {
|
||||
case EFUSE_RD_CHIP_VER_PKG_ESP32U4WDH:
|
||||
case EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5:
|
||||
return ESP32_D2WD_WP_GPIO;
|
||||
case EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4:
|
||||
/* Same package IDs are used for ESP32-PICO-V3 and ESP32-PICO-D4, silicon version differentiates */
|
||||
return !ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 300) ? ESP32_D2WD_WP_GPIO : ESP32_PICO_V3_GPIO;
|
||||
chip_ver = efuse_hal_get_major_chip_version();
|
||||
return (chip_ver < 3) ? ESP32_D2WD_WP_GPIO : ESP32_PICO_V3_GPIO;
|
||||
case EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302:
|
||||
return ESP32_PICO_V3_GPIO;
|
||||
default:
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_rom_spiflash.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "flash_qio_mode.h"
|
||||
@@ -160,47 +159,47 @@ static esp_err_t enable_qio_mode(bootloader_flash_read_status_fn_t read_status_f
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
IRAM_ATTR unsigned bootloader_read_status_8b_rdsr(void)
|
||||
unsigned bootloader_read_status_8b_rdsr(void)
|
||||
{
|
||||
return bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
|
||||
}
|
||||
|
||||
IRAM_ATTR unsigned bootloader_read_status_8b_rdsr2(void)
|
||||
unsigned bootloader_read_status_8b_rdsr2(void)
|
||||
{
|
||||
return bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8);
|
||||
}
|
||||
|
||||
IRAM_ATTR unsigned bootloader_read_status_8b_rdsr3(void)
|
||||
unsigned bootloader_read_status_8b_rdsr3(void)
|
||||
{
|
||||
return bootloader_execute_flash_command(CMD_RDSR3, 0, 0, 8);
|
||||
}
|
||||
|
||||
IRAM_ATTR unsigned bootloader_read_status_16b_rdsr_rdsr2(void)
|
||||
unsigned bootloader_read_status_16b_rdsr_rdsr2(void)
|
||||
{
|
||||
return bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8) | (bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8);
|
||||
}
|
||||
|
||||
IRAM_ATTR void bootloader_write_status_8b_wrsr(unsigned new_status)
|
||||
void bootloader_write_status_8b_wrsr(unsigned new_status)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_WRSR, new_status, 8, 0);
|
||||
}
|
||||
|
||||
IRAM_ATTR void bootloader_write_status_8b_wrsr2(unsigned new_status)
|
||||
void bootloader_write_status_8b_wrsr2(unsigned new_status)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_WRSR2, new_status, 8, 0);
|
||||
}
|
||||
|
||||
IRAM_ATTR void bootloader_write_status_8b_wrsr3(unsigned new_status)
|
||||
void bootloader_write_status_8b_wrsr3(unsigned new_status)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_WRSR3, new_status, 8, 0);
|
||||
}
|
||||
|
||||
IRAM_ATTR void bootloader_write_status_16b_wrsr(unsigned new_status)
|
||||
void bootloader_write_status_16b_wrsr(unsigned new_status)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_WRSR, new_status, 16, 0);
|
||||
}
|
||||
|
||||
IRAM_ATTR unsigned bootloader_read_status_8b_xmc25qu64a(void)
|
||||
unsigned bootloader_read_status_8b_xmc25qu64a(void)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
@@ -209,7 +208,7 @@ IRAM_ATTR unsigned bootloader_read_status_8b_xmc25qu64a(void)
|
||||
return read_status;
|
||||
}
|
||||
|
||||
IRAM_ATTR void bootloader_write_status_8b_xmc25qu64a(unsigned new_status)
|
||||
void bootloader_write_status_8b_xmc25qu64a(unsigned new_status)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_app_format.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -150,6 +151,20 @@ int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata);
|
||||
*/
|
||||
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max);
|
||||
|
||||
/**
|
||||
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
||||
*
|
||||
* Returns a description for the requested app partition.
|
||||
* @param[in] partition App partition description.
|
||||
* @param[out] app_desc Structure of info about app.
|
||||
* @return
|
||||
* - ESP_OK: Successful.
|
||||
* - ESP_ERR_INVALID_ARG: The arguments passed are not valid.
|
||||
* - ESP_ERR_NOT_FOUND: app_desc structure is not found. Magic word is incorrect.
|
||||
* - ESP_FAIL: mapping is fail.
|
||||
*/
|
||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
|
||||
|
||||
/**
|
||||
* @brief Get chip package
|
||||
*
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "esp_assert.h"
|
||||
|
||||
/**
|
||||
* @brief ESP chip ID
|
||||
@@ -27,7 +26,7 @@ typedef enum {
|
||||
} __attribute__((packed)) esp_chip_id_t;
|
||||
|
||||
/** @cond */
|
||||
ESP_STATIC_ASSERT(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
|
||||
_Static_assert(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
@@ -84,15 +83,8 @@ typedef struct {
|
||||
* pin and sets this field to 0xEE=disabled) */
|
||||
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
|
||||
esp_chip_id_t chip_id; /*!< Chip identification number */
|
||||
uint8_t min_chip_rev; /*!< Minimal chip revision supported by image
|
||||
* After the Major and Minor revision eFuses were introduced into the chips, this field is no longer used.
|
||||
* But for compatibility reasons, we keep this field and the data in it.
|
||||
* Use min_chip_rev_full instead.
|
||||
* The software interprets this as a Major version for most of the chips and as a Minor version for the ESP32-C3.
|
||||
*/
|
||||
uint16_t min_chip_rev_full; /*!< Minimal chip revision supported by image, in format: major * 100 + minor */
|
||||
uint16_t max_chip_rev_full; /*!< Maximal chip revision supported by image, in format: major * 100 + minor */
|
||||
uint8_t reserved[4]; /*!< Reserved bytes in additional header space, currently unused */
|
||||
uint8_t min_chip_rev; /*!< Minimum chip revision supported by image */
|
||||
uint8_t reserved[8]; /*!< Reserved bytes in additional header space, currently unused */
|
||||
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
|
||||
* Included in image length. This digest
|
||||
* is separate to secure boot and only used for detecting corruption.
|
||||
@@ -101,7 +93,7 @@ typedef struct {
|
||||
} __attribute__((packed)) esp_image_header_t;
|
||||
|
||||
/** @cond */
|
||||
ESP_STATIC_ASSERT(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
|
||||
_Static_assert(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
|
||||
/** @endcond */
|
||||
|
||||
|
||||
@@ -114,3 +106,25 @@ typedef struct {
|
||||
} esp_image_segment_header_t;
|
||||
|
||||
#define ESP_IMAGE_MAX_SEGMENTS 16 /*!< Max count of segments in the image. */
|
||||
|
||||
#define ESP_APP_DESC_MAGIC_WORD 0xABCD5432 /*!< The magic word for the esp_app_desc structure that is in DROM. */
|
||||
|
||||
/**
|
||||
* @brief Description about application.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t magic_word; /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
|
||||
uint32_t secure_version; /*!< Secure version */
|
||||
uint32_t reserv1[2]; /*!< reserv1 */
|
||||
char version[32]; /*!< Application version */
|
||||
char project_name[32]; /*!< Project name */
|
||||
char time[16]; /*!< Compile time */
|
||||
char date[16]; /*!< Compile date*/
|
||||
char idf_ver[32]; /*!< Version IDF */
|
||||
uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
|
||||
uint32_t reserv2[20]; /*!< reserv2 */
|
||||
} esp_app_desc_t;
|
||||
|
||||
/** @cond */
|
||||
_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
|
||||
/** @endcond */
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <stdbool.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "spi_flash_mmap.h"
|
||||
#endif
|
||||
@@ -185,19 +184,6 @@ void esp_flash_encryption_init_checks(void);
|
||||
*/
|
||||
esp_err_t esp_flash_encryption_enable_secure_features(void);
|
||||
|
||||
/** @brief Returns the verification status for all physical security features of flash encryption in release mode
|
||||
*
|
||||
* If the device has flash encryption feature configured in the release mode,
|
||||
* then it is highly recommended to call this API in the application startup code.
|
||||
* This API verifies the sanity of the eFuse configuration against
|
||||
* the release (production) mode of the flash encryption feature.
|
||||
*
|
||||
* @return
|
||||
* - True - all eFuses are configured correctly
|
||||
* - False - not all eFuses are configured correctly.
|
||||
*/
|
||||
bool esp_flash_encryption_cfg_verify_release_mode(void);
|
||||
|
||||
/** @brief Switches Flash Encryption from "Development" to "Release"
|
||||
*
|
||||
* If already in "Release" mode, the function will do nothing.
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <esp_err.h>
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_app_format.h"
|
||||
#include "esp_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -33,7 +32,6 @@ typedef struct {
|
||||
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
|
||||
uint32_t image_len; /* Length of image on flash, in bytes */
|
||||
uint8_t image_digest[32]; /* appended SHA-256 digest */
|
||||
uint32_t secure_version; /* secure version for anti-rollback, it is covered by sha256 (set if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y) */
|
||||
} esp_image_metadata_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -55,18 +53,12 @@ typedef struct {
|
||||
uint32_t crc; /*!< Check sum crc32 */
|
||||
} rtc_retain_mem_t;
|
||||
|
||||
|
||||
ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, crc) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t), "CRC field must be the last field of rtc_retain_mem_t structure");
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
|
||||
/* The custom field must be the penultimate field */
|
||||
ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, custom) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t) - CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE,
|
||||
"custom field in rtc_retain_mem_t structure must be the field before the CRC one");
|
||||
_Static_assert(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
|
||||
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
|
||||
_Static_assert(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||
@@ -76,7 +68,7 @@ ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADE
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
|
||||
ESP_STATIC_ASSERT(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
|
||||
_Static_assert(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -191,7 +191,7 @@ typedef struct {
|
||||
*/
|
||||
esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest);
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
|
||||
#if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_3
|
||||
/**
|
||||
* @brief Structure to hold public key digests calculated from the signature blocks of a single image.
|
||||
*
|
||||
@@ -202,7 +202,7 @@ typedef struct {
|
||||
unsigned num_digests; /* Number of valid digests, starting at index 0 */
|
||||
} esp_image_sig_public_key_digests_t;
|
||||
|
||||
#endif // !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
|
||||
#endif // !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_3
|
||||
|
||||
/** @brief Legacy ECDSA verification function
|
||||
*
|
||||
@@ -269,36 +269,6 @@ esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_publi
|
||||
*/
|
||||
esp_err_t esp_secure_boot_enable_secure_features(void);
|
||||
|
||||
/** @brief Returns the verification status for all physical security features of secure boot in release mode
|
||||
*
|
||||
* If the device has secure boot feature configured in the release mode,
|
||||
* then it is highly recommended to call this API in the application startup code.
|
||||
* This API verifies the sanity of the eFuse configuration against
|
||||
* the release (production) mode of the secure boot feature.
|
||||
*
|
||||
* @return
|
||||
* - True - all eFuses are configured correctly
|
||||
* - False - not all eFuses are configured correctly.
|
||||
*/
|
||||
bool esp_secure_boot_cfg_verify_release_mode(void);
|
||||
|
||||
|
||||
#if !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
|
||||
/** @brief Returns the verification status of the image pointed by the part_pos argument against the public key digest present at index `efuse_digest_index`
|
||||
*
|
||||
* @param index[in] Index of public key digest present in efuse against which the image is to be verified
|
||||
* @param part_pos[in] It is a pointer to the bootloader/app partition.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK - if the image can be verified by the key at efuse_index.
|
||||
* - ESP_FAIL - if the image cannot be verified by the key at efuse_index.
|
||||
* - ESP_ERR_INVALID_ARG: Error in the passed arguments.
|
||||
*/
|
||||
esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos);
|
||||
|
||||
#endif // !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "esp32c2/rom/secure_boot.h"
|
||||
#endif
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
|
||||
#if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_3
|
||||
|
||||
/** @brief Verify the secure boot signature block for Secure Boot V2.
|
||||
*
|
||||
|
||||
@@ -45,7 +45,7 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
|
||||
* @param[in] bs Bootloader state structure.
|
||||
* @param[in] start_index The index from which the search for images begins.
|
||||
*/
|
||||
__attribute__((__noreturn__)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
|
||||
__attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ void bootloader_utility_load_boot_image_from_deep_sleep(void);
|
||||
*
|
||||
* It is not recommended to call this function from an app (if called, the app will abort).
|
||||
*/
|
||||
__attribute__((__noreturn__)) void bootloader_reset(void);
|
||||
__attribute__((noreturn)) void bootloader_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Do any cleanup before exiting the bootloader, before starting the app or resetting
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@@ -33,7 +32,7 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
* document). For rev. 0, switch to 240 instead if it has been enabled
|
||||
* previously.
|
||||
*/
|
||||
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100) &&
|
||||
if (efuse_hal_get_major_chip_version() == 0 &&
|
||||
clk_ll_cpu_get_freq_mhz_from_pll() == CLK_LL_PLL_240M_FREQ_MHZ) {
|
||||
cpu_freq_mhz = 240;
|
||||
}
|
||||
@@ -43,6 +42,13 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
|
||||
if (esp_rom_get_reset_reason(0) != RESET_REASON_CPU0_SW || rtc_clk_apb_freq_get() < APB_CLK_FREQ) {
|
||||
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32C2
|
||||
clk_cfg.xtal_freq = CONFIG_ESP32C2_XTAL_FREQ;
|
||||
#endif
|
||||
/* For other chips, there is no XTAL_FREQ choice */
|
||||
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
||||
clk_cfg.slow_clk_src = rtc_clk_slow_src_get();
|
||||
if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) {
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/efuse_ll.h"
|
||||
#include "hal/gpio_ll.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "bootloader_sha.h"
|
||||
@@ -27,7 +25,6 @@
|
||||
#include "bootloader_flash_priv.h"
|
||||
|
||||
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
|
||||
#define IS_MAX_REV_SET(max_chip_rev_full) (((max_chip_rev_full) != 65535) && ((max_chip_rev_full) != 0))
|
||||
|
||||
static const char* TAG = "boot_comm";
|
||||
|
||||
@@ -57,39 +54,35 @@ int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata)
|
||||
return bootloader_common_select_otadata(two_otadata, valid_two_otadata, true);
|
||||
}
|
||||
|
||||
esp_err_t __attribute__((optimize("-Os"))) bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
|
||||
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
|
||||
if (chip_id != img_hdr->chip_id) {
|
||||
ESP_LOGE(TAG, "mismatch chip ID, expected %d, found %d", chip_id, img_hdr->chip_id);
|
||||
err = ESP_FAIL;
|
||||
} else {
|
||||
#ifndef CONFIG_IDF_ENV_FPGA
|
||||
unsigned revision = efuse_hal_chip_revision();
|
||||
unsigned int major_rev = revision / 100;
|
||||
unsigned int minor_rev = revision % 100;
|
||||
unsigned min_rev = img_hdr->min_chip_rev_full;
|
||||
if (type == ESP_IMAGE_BOOTLOADER || type == ESP_IMAGE_APPLICATION) {
|
||||
if (!ESP_CHIP_REV_ABOVE(revision, min_rev)) {
|
||||
ESP_LOGE(TAG, "Image requires chip rev >= v%d.%d, but chip is v%d.%d",
|
||||
min_rev / 100, min_rev % 100,
|
||||
major_rev, minor_rev);
|
||||
err = ESP_FAIL;
|
||||
}
|
||||
}
|
||||
if (type == ESP_IMAGE_APPLICATION) {
|
||||
unsigned max_rev = img_hdr->max_chip_rev_full;
|
||||
if ((IS_MAX_REV_SET(max_rev) && (revision > max_rev) && !efuse_ll_get_disable_wafer_version_major())) {
|
||||
ESP_LOGE(TAG, "Image requires chip rev <= v%d.%d, but chip is v%d.%d",
|
||||
max_rev / 100, max_rev % 100,
|
||||
major_rev, minor_rev);
|
||||
err = ESP_FAIL;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_IDF_ENV_FPGA
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IDF_ENV_FPGA
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32H2)
|
||||
uint8_t revision = efuse_hal_get_major_chip_version();
|
||||
// min_chip_rev keeps the MAJOR wafer version for these chips
|
||||
#else
|
||||
uint8_t revision = efuse_hal_get_minor_chip_version();
|
||||
// min_chip_rev keeps the MINOR wafer version for these chips
|
||||
#endif
|
||||
if (revision < img_hdr->min_chip_rev) {
|
||||
/* To fix this error, please update mininum supported chip revision from configuration,
|
||||
* located in TARGET (e.g. ESP32) specific options under "Component config" menu */
|
||||
ESP_LOGE(TAG, "This chip is revision %d but the application is configured for minimum revision %d. Can't run.", revision, img_hdr->min_chip_rev);
|
||||
err = ESP_FAIL;
|
||||
} else if (revision != img_hdr->min_chip_rev) {
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
ESP_LOGI(TAG, "chip revision: %d, min. %s chip revision: %d", revision, type == ESP_IMAGE_BOOTLOADER ? "bootloader" : "application", img_hdr->min_chip_rev);
|
||||
#endif
|
||||
}
|
||||
#endif // CONFIG_IDF_ENV_FPGA
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -119,44 +112,69 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
|
||||
return active_otadata;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
|
||||
{
|
||||
if (partition == NULL || app_desc == NULL || partition->offset == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
|
||||
const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
|
||||
const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
|
||||
if (image == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
|
||||
bootloader_munmap(image);
|
||||
|
||||
if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
|
||||
|
||||
static uint32_t rtc_retain_mem_size(void) {
|
||||
#if CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC && !CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_IN_CRC
|
||||
/* A custom memory has been reserved by the user, do not consider this memory into CRC calculation as it may change without
|
||||
* the have the user updating the CRC. Return the offset of the custom field, which is equivalent to size of the structure
|
||||
* minus the size of everything after (including) `custom` */
|
||||
return offsetof(rtc_retain_mem_t, custom);
|
||||
#else
|
||||
return sizeof(rtc_retain_mem_t) - sizeof(bootloader_common_get_rtc_retain_mem()->crc);
|
||||
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
|
||||
|
||||
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "heap_memory_layout.h"
|
||||
/* The app needs to be told this memory is reserved, important if configured to use RTC memory as heap.
|
||||
|
||||
Note that keeping this macro here only works when other symbols in this file are referenced by the app, as
|
||||
this feature is otherwise 100% part of the bootloader. However this seems to happen in all apps.
|
||||
*/
|
||||
SOC_RESERVE_MEMORY_REGION(RTC_RETAIN_MEM_ADDR, RTC_RETAIN_MEM_ADDR + sizeof(rtc_retain_mem_t), rtc_retain_mem);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool check_rtc_retain_mem(void)
|
||||
{
|
||||
rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
|
||||
return esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, rtc_retain_mem_size()) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
|
||||
return esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc)) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
|
||||
}
|
||||
|
||||
static void update_rtc_retain_mem_crc(void)
|
||||
{
|
||||
rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
|
||||
rtc_retain_mem->crc = esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, rtc_retain_mem_size());
|
||||
rtc_retain_mem->crc = esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc));
|
||||
}
|
||||
|
||||
NOINLINE_ATTR void bootloader_common_reset_rtc_retain_mem(void)
|
||||
void bootloader_common_reset_rtc_retain_mem(void)
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
memset(bootloader_common_get_rtc_retain_mem(), 0, sizeof(rtc_retain_mem_t));
|
||||
memset(rtc_retain_mem, 0, sizeof(rtc_retain_mem_t));
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
|
||||
{
|
||||
if (check_rtc_retain_mem()) {
|
||||
return bootloader_common_get_rtc_retain_mem()->reboot_counter;
|
||||
return rtc_retain_mem->reboot_counter;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -164,14 +182,13 @@ uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
|
||||
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
|
||||
{
|
||||
if (check_rtc_retain_mem()) {
|
||||
return &bootloader_common_get_rtc_retain_mem()->partition;
|
||||
return &rtc_retain_mem->partition;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
|
||||
{
|
||||
rtc_retain_mem_t* rtc_retain_mem = bootloader_common_get_rtc_retain_mem();
|
||||
if (reboot_counter) {
|
||||
if (!check_rtc_retain_mem()) {
|
||||
bootloader_common_reset_rtc_retain_mem();
|
||||
@@ -193,13 +210,6 @@ void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, boo
|
||||
|
||||
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
|
||||
{
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
|
||||
static rtc_retain_mem_t *const s_bootloader_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
|
||||
return s_bootloader_retain_mem;
|
||||
#else
|
||||
static __attribute__((section(".bootloader_data_rtc_mem"))) rtc_retain_mem_t s_bootloader_retain_mem;
|
||||
return &s_bootloader_retain_mem;
|
||||
#endif // !BOOTLOADER_BUILD
|
||||
return rtc_retain_mem;
|
||||
}
|
||||
#endif // defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -29,9 +29,6 @@
|
||||
#include "esp32c2/rom/ets_sys.h"
|
||||
#include "esp32c2/rom/uart.h"
|
||||
#endif
|
||||
#if SOC_USB_SERIAL_JTAG_SUPPORTED
|
||||
#include "hal/usb_phy_ll.h"
|
||||
#endif
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
@@ -50,7 +47,12 @@ void bootloader_console_init(void)
|
||||
{
|
||||
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
|
||||
|
||||
#if !ESP_ROM_SUPPORT_MULTIPLE_UART
|
||||
/* esp_rom_install_channel_put is not available unless multiple UARTs are supported */
|
||||
esp_rom_install_uart_printf();
|
||||
#else
|
||||
esp_rom_install_channel_putc(1, esp_rom_uart_putc);
|
||||
#endif
|
||||
|
||||
// Wait for UART FIFO to be empty.
|
||||
esp_rom_uart_tx_wait_idle(0);
|
||||
@@ -59,10 +61,10 @@ void bootloader_console_init(void)
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
|
||||
|
||||
// Switch to the new UART (this just changes UART number used for esp_rom_printf in ROM code).
|
||||
#if ESP_ROM_SUPPORT_MULTIPLE_UART
|
||||
esp_rom_uart_set_as_console(uart_num);
|
||||
|
||||
#endif
|
||||
// If console is attached to UART1 or if non-default pins are used,
|
||||
// need to reconfigure pins using GPIO matrix
|
||||
if (uart_num != 0 ||
|
||||
@@ -108,12 +110,8 @@ void bootloader_console_init(void)
|
||||
#endif
|
||||
|
||||
esp_rom_uart_usb_acm_init(s_usb_cdc_buf, sizeof(s_usb_cdc_buf));
|
||||
esp_rom_uart_set_as_console(ESP_ROM_USB_OTG_NUM);
|
||||
esp_rom_uart_set_as_console(ESP_ROM_UART_USB);
|
||||
esp_rom_install_channel_putc(1, bootloader_console_write_char_usb);
|
||||
#if SOC_USB_SERIAL_JTAG_SUPPORTED
|
||||
usb_phy_ll_usb_wrap_pad_enable(&USB_WRAP, true);
|
||||
usb_phy_ll_int_otg_enable(&USB_WRAP);
|
||||
#endif
|
||||
}
|
||||
#endif //CONFIG_ESP_CONSOLE_USB_CDC
|
||||
|
||||
|
||||
@@ -41,10 +41,7 @@ esp_err_t bootloader_read_bootloader_header(void)
|
||||
|
||||
esp_err_t bootloader_check_bootloader_validity(void)
|
||||
{
|
||||
unsigned int revision = efuse_hal_chip_revision();
|
||||
unsigned int major = revision / 100;
|
||||
unsigned int minor = revision % 100;
|
||||
ESP_LOGI(TAG, "chip revision: v%d.%d", major, minor);
|
||||
ESP_LOGI(TAG, "chip revision: V%03d", efuse_hal_chip_revision());
|
||||
/* compare with the one set in bootloader image header */
|
||||
if (bootloader_common_check_chip_validity(&bootloader_image_hdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
@@ -96,12 +93,4 @@ void bootloader_print_banner(void)
|
||||
#ifndef CONFIG_APP_REPRODUCIBLE_BUILD
|
||||
ESP_LOGI(TAG, "compile time " __TIME__);
|
||||
#endif
|
||||
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
#if (SOC_CPU_CORES_NUM > 1)
|
||||
ESP_EARLY_LOGW(TAG, "Unicore bootloader");
|
||||
#endif
|
||||
#else
|
||||
ESP_EARLY_LOGI(TAG, "Multicore bootloader");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@
|
||||
|
||||
void __assert_func(const char *file, int line, const char *func, const char *expr)
|
||||
{
|
||||
|
||||
#if !CONFIG_OPTIMIZATION_ASSERTIONS_SILENT
|
||||
esp_rom_printf("Assert failed in %s, %s:%d (%s)\r\n", func, file, line, expr);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -26,11 +22,9 @@ void abort(void)
|
||||
#if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
|
||||
esp_rom_printf("abort() was called at PC 0x%08x\r\n", (intptr_t)__builtin_return_address(0) - 3);
|
||||
#endif
|
||||
#if CONFIG_ESP_DEBUG_OCDAWARE
|
||||
if (esp_cpu_dbgr_is_attached()) {
|
||||
esp_cpu_dbgr_break();
|
||||
}
|
||||
#endif
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_app_desc.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
@@ -120,31 +119,6 @@ static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_selec
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
|
||||
{
|
||||
if (partition == NULL || app_desc == NULL || partition->offset == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
|
||||
const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
|
||||
const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
|
||||
if (image == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
|
||||
bootloader_munmap(image);
|
||||
|
||||
if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
|
||||
{
|
||||
const esp_partition_info_t *partitions;
|
||||
|
||||
@@ -129,7 +129,7 @@ static esp_err_t bootloader_check_rated_cpu_clock(void)
|
||||
{
|
||||
int rated_freq = bootloader_clock_get_rated_freq_mhz();
|
||||
if (rated_freq < CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) {
|
||||
ESP_LOGE(TAG, "Chip CPU freq rated for %dMHz, configured for %dMHz. Modify CPU freq in menuconfig",
|
||||
ESP_LOGE(TAG, "Chip CPU frequency rated for %dMHz, configured for %dMHz. Modify CPU frequency in menuconfig",
|
||||
rated_freq, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,18 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
//Not supported but common bootloader calls the function. Do nothing
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "bootloader_mem.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/cache_hal.h"
|
||||
@@ -241,19 +240,10 @@ static void bootloader_super_wdt_auto_feed(void)
|
||||
REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
|
||||
}
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
//Enable super WDT reset.
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
//Enable BOD reset
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_init(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
bootloader_ana_reset_config();
|
||||
bootloader_super_wdt_auto_feed();
|
||||
// protect memory region
|
||||
bootloader_init_mem();
|
||||
|
||||
@@ -3,34 +3,19 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
(void)enable; // ESP32-C2 has none of these features.
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOD_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
}
|
||||
(void)enable; // ESP32-C2 has none of these features.
|
||||
}
|
||||
|
||||
//Not supported but common bootloader calls the function. Do nothing
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
(void)enable; // ESP32-C2 has none of these features.
|
||||
}
|
||||
|
||||
@@ -45,17 +45,5 @@ esp_err_t esp_secure_boot_enable_secure_features(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
// Secure boot and Flash encryption share one eFuse key block so they can not be set separately.
|
||||
// CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER option is used to burn SB and FE at the same time.
|
||||
// SB key is readable, the corresponding bit in RD_DIS is unset.
|
||||
// We set write-protection for RD_DIS to ensure that the SB key is always readable.
|
||||
// FE key is read-protected, the corresponding bit in RD_DIS is set.
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "soc/extmem_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "esp32c3/rom/efuse.h"
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "bootloader_common.h"
|
||||
@@ -253,7 +252,7 @@ static inline void bootloader_hardware_init(void)
|
||||
{
|
||||
// This check is always included in the bootloader so it can
|
||||
// print the minimum revision error message later in the boot
|
||||
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 3)) {
|
||||
if (efuse_hal_get_minor_chip_version() < 3) {
|
||||
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 1);
|
||||
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
|
||||
}
|
||||
@@ -261,29 +260,30 @@ static inline void bootloader_hardware_init(void)
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
//Enable super WDT reset.
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
|
||||
/*
|
||||
For origin chip & ECO1: brownout & clock glitch reset not available
|
||||
For ECO2: fix brownout reset bug
|
||||
For ECO3: fix clock glitch reset bug
|
||||
For origin chip & ECO1: only support swt reset;
|
||||
For ECO2: fix brownout reset bug, support swt & brownout reset;
|
||||
For ECO3: fix clock glitch reset bug, support all reset, include: swt & brownout & clock glitch reset.
|
||||
*/
|
||||
switch (efuse_hal_chip_revision()) {
|
||||
uint8_t chip_version = efuse_hal_get_minor_chip_version();
|
||||
switch (chip_version) {
|
||||
case 0:
|
||||
case 1:
|
||||
//Disable BOD and GLITCH reset
|
||||
//Enable WDT reset. Disable BOR and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(false);
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
break;
|
||||
case 2:
|
||||
//Enable BOD reset. Disable GLITCH reset
|
||||
//Enable WDT and BOR reset. Disable GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
//Enable BOD, and GLITCH reset
|
||||
//Enable WDT, BOR, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
break;
|
||||
|
||||
@@ -12,15 +12,15 @@ void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOD_RST);
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOR_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
|
||||
@@ -3,10 +3,18 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
//Not supported but common bootloader calls the function. Do nothing
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
|
||||
@@ -210,7 +210,7 @@ static esp_err_t bootloader_init_spi_flash(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_BOOTLOADER_FLASH_DC_AWARE
|
||||
#if CONFIG_SPI_FLASH_HPM_ENABLE
|
||||
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
|
||||
bootloader_spi_flash_reset();
|
||||
#endif
|
||||
@@ -220,9 +220,7 @@ static esp_err_t bootloader_init_spi_flash(void)
|
||||
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
|
||||
bootloader_enable_qio_mode();
|
||||
#endif
|
||||
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||
bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
|
||||
#endif
|
||||
|
||||
print_flash_info(&bootloader_image_hdr);
|
||||
update_flash_config(&bootloader_image_hdr);
|
||||
//ensure the flash is write-protected
|
||||
@@ -316,7 +314,7 @@ static void bootloader_super_wdt_auto_feed(void)
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
//Enable WDT, BOD, and GLITCH reset
|
||||
//Enable WDT, BOR, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
|
||||
@@ -12,15 +12,15 @@ void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOD_RST);
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOR_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -19,8 +19,6 @@
|
||||
#include "bootloader_util.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_app_desc.h"
|
||||
#include "bootloader_memory_utils.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@@ -38,8 +36,6 @@
|
||||
#include "esp32c2/rom/secure_boot.h"
|
||||
#endif
|
||||
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
/* Checking signatures as part of verifying images is necessary:
|
||||
- Always if secure boot is enabled
|
||||
- Differently in bootloader and/or app, depending on kconfig
|
||||
@@ -83,10 +79,10 @@ static bool should_map(uint32_t load_addr);
|
||||
|
||||
static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
|
||||
/* Load or verify a segment */
|
||||
static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata);
|
||||
static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
|
||||
|
||||
/* split segment and verify if data_len is too long */
|
||||
static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata);
|
||||
static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
|
||||
|
||||
/* Verify the main image header */
|
||||
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent);
|
||||
@@ -111,7 +107,7 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
|
||||
while(0)
|
||||
|
||||
static esp_err_t process_image_header(esp_image_metadata_t *data, uint32_t part_offset, bootloader_sha256_handle_t *sha_handle, bool do_verify, bool silent);
|
||||
static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint32_t part_offset, uint32_t part_len, bool do_verify, bool silent);
|
||||
static esp_err_t process_appended_hash(esp_image_metadata_t *data, uint32_t part_len, bool do_verify, bool silent);
|
||||
static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data, bool silent, bool skip_check_checksum);
|
||||
|
||||
static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest);
|
||||
@@ -163,7 +159,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
CHECK_ERR(process_segments(data, silent, do_load, sha_handle, checksum));
|
||||
bool skip_check_checksum = !do_verify || esp_cpu_dbgr_is_attached();
|
||||
CHECK_ERR(process_checksum(sha_handle, checksum_word, data, silent, skip_check_checksum));
|
||||
CHECK_ERR(process_appended_hash_and_sig(data, part->offset, part->size, do_verify, silent));
|
||||
CHECK_ERR(process_appended_hash(data, part->size, do_verify, silent));
|
||||
if (verify_sha) {
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1)
|
||||
// secure boot images have a signature appended
|
||||
@@ -231,21 +227,6 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
/* For anti-rollback case, reconfirm security version of the application to prevent FI attacks */
|
||||
bool sec_ver = false;
|
||||
if (do_load) {
|
||||
sec_ver = esp_efuse_check_secure_version(data->secure_version);
|
||||
if (!sec_ver) {
|
||||
err = ESP_FAIL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/* Ensure that the security version check passes for image loading scenario */
|
||||
ESP_FAULT_ASSERT(!do_load || sec_ver == true);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
// Success!
|
||||
@@ -318,7 +299,7 @@ esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_meta
|
||||
CHECK_ERR(process_segments(metadata, silent, do_load, NULL, NULL));
|
||||
bool skip_check_checksum = true;
|
||||
CHECK_ERR(process_checksum(NULL, 0, metadata, silent, skip_check_checksum));
|
||||
CHECK_ERR(process_appended_hash_and_sig(metadata, part->offset, part->size, true, silent));
|
||||
CHECK_ERR(process_appended_hash(metadata, part->size, true, silent));
|
||||
return ESP_OK;
|
||||
err:
|
||||
return err;
|
||||
@@ -521,8 +502,8 @@ static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool
|
||||
uint32_t next_addr = start_segments;
|
||||
for (int i = 0; i < data->image.segment_count; i++) {
|
||||
esp_image_segment_header_t *header = &data->segments[i];
|
||||
ESP_LOGV(TAG, "loading segment header %d at offset 0x%"PRIx32, i, next_addr);
|
||||
CHECK_ERR(process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum, data));
|
||||
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
|
||||
CHECK_ERR(process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum));
|
||||
next_addr += sizeof(esp_image_segment_header_t);
|
||||
data->segment_data[i] = next_addr;
|
||||
next_addr += header->data_len;
|
||||
@@ -543,7 +524,7 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata)
|
||||
static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
|
||||
{
|
||||
esp_err_t err;
|
||||
|
||||
@@ -601,7 +582,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||
data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||
CHECK_ERR(process_segment_data(index, load_addr, data_addr, data_len, do_load, sha_handle, checksum, metadata));
|
||||
CHECK_ERR(process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum));
|
||||
data_addr += data_len;
|
||||
data_len_remain -= data_len;
|
||||
}
|
||||
@@ -616,42 +597,7 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
/* The __attribute__((optimize("O0"))) is used to disable optimizations for this function,
|
||||
* preventing the compiler from potentially optimizing data_buffer and reading data directly from src.
|
||||
* This is crucial as we want to read from Flash only once, ensuring the integrity of the data.
|
||||
*/
|
||||
__attribute__((optimize("O0")))
|
||||
static size_t process_esp_app_desc_data(const uint32_t *src, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata)
|
||||
{
|
||||
/* Using data_buffer here helps to securely read secure_version
|
||||
* (for anti-rollback) from esp_app_desc_t, preventing FI attack.
|
||||
* We read data from Flash into this buffer, which is covered by sha256.
|
||||
* Therefore, if the flash is under attackers control and contents are modified
|
||||
* the sha256 comparison will fail.
|
||||
*
|
||||
* The esp_app_desc_t structure is located in DROM and is always in segment #0.
|
||||
*
|
||||
* esp_app_desc_t is always at #0 segment (index==0).
|
||||
* secure_version field of esp_app_desc_t is located at #2 word (w_i==1).
|
||||
*/
|
||||
uint32_t data_buffer[2];
|
||||
memcpy(data_buffer, src, sizeof(data_buffer));
|
||||
assert(data_buffer[0] == ESP_APP_DESC_MAGIC_WORD);
|
||||
metadata->secure_version = data_buffer[1];
|
||||
if (checksum != NULL) {
|
||||
*checksum ^= data_buffer[0] ^ data_buffer[1];
|
||||
}
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_data(sha_handle, data_buffer, sizeof(data_buffer));
|
||||
}
|
||||
ESP_FAULT_ASSERT(memcmp(data_buffer, src, sizeof(data_buffer)) == 0);
|
||||
ESP_FAULT_ASSERT(memcmp(&metadata->secure_version, &src[1], sizeof(uint32_t)) == 0);
|
||||
return sizeof(data_buffer);
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
|
||||
static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata)
|
||||
static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
|
||||
{
|
||||
// If we are not loading, and the checksum is empty, skip processing this
|
||||
// segment for data
|
||||
@@ -684,24 +630,10 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
|
||||
#endif
|
||||
}
|
||||
uint32_t *dest = (uint32_t *)load_addr;
|
||||
#endif // BOOTLOADER_BUILD
|
||||
#endif
|
||||
|
||||
const uint32_t *src = data;
|
||||
|
||||
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
// Case I: Bootloader verifying application
|
||||
// Case II: Bootloader verifying bootloader
|
||||
// Anti-rollback check should handle only Case I from above.
|
||||
if (segment == 0 && metadata->start_addr != ESP_BOOTLOADER_OFFSET) {
|
||||
ESP_LOGD(TAG, "additional anti-rollback check 0x%"PRIx32, data_addr);
|
||||
// The esp_app_desc_t structure is located in DROM and is always in segment #0.
|
||||
size_t len = process_esp_app_desc_data(src, sha_handle, checksum, metadata);
|
||||
data_len -= len;
|
||||
src += len / 4;
|
||||
// In BOOTLOADER_BUILD, for DROM (segment #0) we do not load it into dest (only map it), do_load = false.
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
|
||||
for (size_t i = 0; i < data_len; i += 4) {
|
||||
int w_i = i / 4; // Word index
|
||||
uint32_t w = src[w_i];
|
||||
@@ -830,7 +762,7 @@ esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
|
||||
data);
|
||||
}
|
||||
|
||||
static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint32_t part_offset, uint32_t part_len, bool do_verify, bool silent)
|
||||
static esp_err_t process_appended_hash(esp_image_metadata_t *data, uint32_t part_len, bool do_verify, bool silent)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (data->image.hash_appended) {
|
||||
@@ -841,34 +773,8 @@ static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint3
|
||||
data->image_len += HASH_LEN;
|
||||
}
|
||||
|
||||
uint32_t sig_block_len = 0;
|
||||
const uint32_t end = data->image_len;
|
||||
#if CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
|
||||
// Case I: Bootloader part
|
||||
if (part_offset == ESP_BOOTLOADER_OFFSET) {
|
||||
// For bootloader with secure boot v1, signature stays in an independant flash
|
||||
// sector (offset 0x0) and does not get appended to the image.
|
||||
#if CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
// Sanity check - secure boot v2 signature block starts on 4K boundary
|
||||
sig_block_len = ALIGN_UP(end, FLASH_SECTOR_SIZE) - end;
|
||||
sig_block_len += sizeof(ets_secure_boot_signature_t);
|
||||
#endif
|
||||
} else {
|
||||
// Case II: Application part
|
||||
#if CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
|
||||
sig_block_len = sizeof(esp_secure_boot_sig_block_t);
|
||||
#else
|
||||
// Sanity check - secure boot v2 signature block starts on 4K boundary
|
||||
sig_block_len = ALIGN_UP(end, FLASH_SECTOR_SIZE) - end;
|
||||
sig_block_len += sizeof(ets_secure_boot_signature_t);
|
||||
#endif
|
||||
}
|
||||
#endif // CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
|
||||
const uint32_t full_image_len = end + sig_block_len;
|
||||
if (full_image_len > part_len) {
|
||||
FAIL_LOAD("Image length %d doesn't fit in partition length %d", full_image_len, part_len);
|
||||
if (data->image_len > part_len) {
|
||||
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part_len);
|
||||
}
|
||||
return err;
|
||||
err:
|
||||
@@ -926,17 +832,17 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
|
||||
bootloader_munmap(simple_hash);
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
||||
#if CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
// End of the image needs to be padded all the way to a 4KB boundary, after the simple hash
|
||||
// (for apps they are usually already padded due to --secure-pad-v2, only a problem if this option was not used.)
|
||||
uint32_t padded_end = ALIGN_UP(end, FLASH_SECTOR_SIZE);
|
||||
uint32_t padded_end = (end + FLASH_SECTOR_SIZE - 1) & ~(FLASH_SECTOR_SIZE-1);
|
||||
if (padded_end > end) {
|
||||
const void *padding = bootloader_mmap(end, padded_end - end);
|
||||
bootloader_sha256_data(sha_handle, padding, padded_end - end);
|
||||
bootloader_munmap(padding);
|
||||
end = padded_end;
|
||||
}
|
||||
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
||||
#endif
|
||||
|
||||
bootloader_sha256_finish(sha_handle, image_digest);
|
||||
|
||||
@@ -976,13 +882,9 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
// Adjust image length result to include the appended signature
|
||||
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
||||
// Adjust image length result to include the appended signature
|
||||
data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t);
|
||||
#elif defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
|
||||
if (data->start_addr != ESP_BOOTLOADER_OFFSET) {
|
||||
data->image_len = end - data->start_addr + sizeof(esp_secure_boot_sig_block_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SECURE_BOOT_CHECK_SIGNATURE
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT
|
||||
@@ -82,14 +81,15 @@ void esp_flash_encryption_init_checks()
|
||||
*/
|
||||
bool IRAM_ATTR esp_flash_encryption_enabled(void)
|
||||
{
|
||||
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
return efuse_hal_flash_encryption_enabled();
|
||||
#else
|
||||
uint32_t flash_crypt_cnt = 0;
|
||||
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt();
|
||||
#else
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_FLASH_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count);
|
||||
#else
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count);
|
||||
#endif
|
||||
#endif
|
||||
/* __builtin_parity is in flash, so we calculate parity inline */
|
||||
bool enabled = false;
|
||||
@@ -100,7 +100,6 @@ bool IRAM_ATTR esp_flash_encryption_enabled(void)
|
||||
flash_crypt_cnt >>= 1;
|
||||
}
|
||||
return enabled;
|
||||
#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
}
|
||||
|
||||
void esp_flash_write_protect_crypt_cnt(void)
|
||||
@@ -205,12 +204,7 @@ void esp_flash_encryption_set_release_mode(void)
|
||||
ESP_LOGE(TAG, "Flash Encryption support not added, abort..");
|
||||
abort();
|
||||
#endif
|
||||
|
||||
#if CONFIG_SOC_SUPPORTS_SECURE_DL_MODE
|
||||
esp_efuse_enable_rom_secure_download_mode();
|
||||
#else
|
||||
esp_efuse_disable_rom_download_mode();
|
||||
#endif
|
||||
esp_efuse_batch_write_commit();
|
||||
|
||||
if (esp_get_flash_encryption_mode() != ESP_FLASH_ENC_MODE_RELEASE) {
|
||||
@@ -219,206 +213,3 @@ void esp_flash_encryption_set_release_mode(void)
|
||||
}
|
||||
ESP_LOGI(TAG, "Flash encryption mode is RELEASE");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
bool esp_flash_encryption_cfg_verify_release_mode(void)
|
||||
{
|
||||
bool result = false;
|
||||
bool secure;
|
||||
|
||||
secure = esp_flash_encryption_enabled();
|
||||
result = secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not enabled Flash Encryption (FLASH_CRYPT_CNT->1 or max)");
|
||||
}
|
||||
|
||||
uint8_t crypt_config = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_ENCRYPT_CONFIG, &crypt_config, 4);
|
||||
if (crypt_config != EFUSE_FLASH_CRYPT_CONFIG) {
|
||||
result &= false;
|
||||
ESP_LOGW(TAG, "ENCRYPT_CONFIG must be set 0xF (set ENCRYPT_CONFIG->0xF)");
|
||||
}
|
||||
|
||||
uint8_t flash_crypt_cnt = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_FLASH_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count);
|
||||
if (flash_crypt_cnt != (1 << (ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count)) - 1) {
|
||||
if (!esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT)) {
|
||||
result &= false;
|
||||
ESP_LOGW(TAG, "Not release mode of Flash Encryption (set FLASH_CRYPT_CNT->max or WR_DIS_FLASH_CRYPT_CNT->1)");
|
||||
}
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART bootloader encryption (set DISABLE_DL_ENCRYPT->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_DECRYPT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART bootloader decryption (set DISABLE_DL_DECRYPT->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_CACHE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART bootloader MMU cache (set DISABLE_DL_CACHE->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled JTAG (set DISABLE_JTAG->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_CONSOLE_DEBUG_DISABLE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled ROM BASIC interpreter fallback (set CONSOLE_DEBUG_DISABLE->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_BLK1);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not read-protected flash ecnryption key (set RD_DIS_BLK1->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_BLK1);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not write-protected flash ecnryption key (set WR_DIS_BLK1->1)");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#else // not CONFIG_IDF_TARGET_ESP32
|
||||
bool esp_flash_encryption_cfg_verify_release_mode(void)
|
||||
{
|
||||
bool result = false;
|
||||
bool secure;
|
||||
|
||||
secure = esp_flash_encryption_enabled();
|
||||
result = secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not enabled Flash Encryption (SPI_BOOT_CRYPT_CNT->1 or max)");
|
||||
}
|
||||
|
||||
uint8_t flash_crypt_cnt = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count);
|
||||
if (flash_crypt_cnt != (1 << (ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count)) - 1) {
|
||||
if (!esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT)) {
|
||||
result &= false;
|
||||
ESP_LOGW(TAG, "Not release mode of Flash Encryption (set SPI_BOOT_CRYPT_CNT->max or WR_DIS_SPI_BOOT_CRYPT_CNT->1)");
|
||||
}
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART bootloader encryption (set DIS_DOWNLOAD_MANUAL_ENCRYPT->1)");
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_DIS_DOWNLOAD_DCACHE
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART bootloader Dcache (set DIS_DOWNLOAD_DCACHE->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART bootloader cache (set DIS_DOWNLOAD_ICACHE->1)");
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_DIS_PAD_JTAG
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled JTAG PADs (set DIS_PAD_JTAG->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_USB_JTAG
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled USB JTAG (set DIS_USB_JTAG->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_DIRECT_BOOT
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled direct boot mode (set DIS_DIRECT_BOOT->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_HARD_DIS_JTAG
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled JTAG (set HARD_DIS_JTAG->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_BOOT_REMAP
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled boot from RAM (set DIS_BOOT_REMAP->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_LEGACY_SPI_BOOT
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled Legcy SPI boot (set DIS_LEGACY_SPI_BOOT->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_efuse_purpose_t purposes[] = {
|
||||
#if SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
|
||||
#endif
|
||||
#if SOC_FLASH_ENCRYPTION_XTS_AES_128
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
|
||||
#endif
|
||||
};
|
||||
// S2 and S3 chips have both XTS_AES_128_KEY and XTS_AES_256_KEY_1/2.
|
||||
// The check below does not take into account that XTS_AES_128_KEY and XTS_AES_256_KEY_1/2
|
||||
// are mutually exclusive because this will make the chip not functional.
|
||||
// Only one type key must be configured in eFuses.
|
||||
secure = false;
|
||||
for (unsigned i = 0; i < sizeof(purposes) / sizeof(esp_efuse_purpose_t); i++) {
|
||||
esp_efuse_block_t block;
|
||||
if (esp_efuse_find_purpose(purposes[i], &block)) {
|
||||
secure = esp_efuse_get_key_dis_read(block);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not read-protected Flash encryption key in BLOCK%d (set RD_DIS_KEY%d->1)", block, block - EFUSE_BLK_KEY0);
|
||||
}
|
||||
secure = esp_efuse_get_key_dis_write(block);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not write-protected Flash encryption key in BLOCK%d (set WR_DIS_KEY%d->1)", block, block - EFUSE_BLK_KEY0);
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_KEY_PURPOSE_FIELD
|
||||
secure = esp_efuse_get_keypurpose_dis_write(block);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not write-protected KEY_PURPOSE for BLOCK%d (set WR_DIS_KEY_PURPOSE%d->1)", block, block - EFUSE_BLK_KEY0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
result &= secure;
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif // not CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
@@ -389,21 +389,14 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit
|
||||
{
|
||||
esp_err_t err;
|
||||
bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED);
|
||||
uint32_t size = partition->pos.size;
|
||||
|
||||
if (partition->type == PART_TYPE_APP) {
|
||||
/* check if the partition holds a valid unencrypted app */
|
||||
esp_image_metadata_t image_data = {};
|
||||
esp_image_metadata_t data_ignored;
|
||||
err = esp_image_verify(ESP_IMAGE_VERIFY,
|
||||
&partition->pos,
|
||||
&image_data);
|
||||
&data_ignored);
|
||||
should_encrypt = (err == ESP_OK);
|
||||
#ifdef CONFIG_SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART
|
||||
if (should_encrypt) {
|
||||
// Encrypt only the app image instead of encrypting the whole partition
|
||||
size = image_data.image_len;
|
||||
}
|
||||
#endif
|
||||
} else if ((partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA)
|
||||
|| (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_NVS_KEYS)) {
|
||||
/* check if we have ota data partition and the partition should be encrypted unconditionally */
|
||||
@@ -414,9 +407,9 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit
|
||||
return ESP_OK;
|
||||
} else {
|
||||
/* should_encrypt */
|
||||
ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, size);
|
||||
ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size);
|
||||
|
||||
err = esp_flash_encrypt_region(partition->pos.offset, size);
|
||||
err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size);
|
||||
ESP_LOGI(TAG, "Done encrypting");
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt partition %d", index);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
static __attribute__((unused)) const char *TAG = "secure_boot";
|
||||
@@ -144,9 +143,9 @@ static esp_err_t secure_boot_v2_check(bool *need_fix)
|
||||
#endif
|
||||
#endif // CONFIG_SECURE_BOOT
|
||||
|
||||
#if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
static void check_signature_on_update_check(void)
|
||||
static void rsa_check_signature_on_update_check(void)
|
||||
{
|
||||
// We rely on the keys used to sign this app to verify the next app on OTA, so make sure there is at
|
||||
// least one to avoid a stuck firmware
|
||||
@@ -164,7 +163,7 @@ static void check_signature_on_update_check(void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
void esp_secure_boot_init_checks(void)
|
||||
{
|
||||
@@ -184,229 +183,9 @@ void esp_secure_boot_init_checks(void)
|
||||
#endif // CONFIG_SECURE_BOOT
|
||||
|
||||
|
||||
#if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
check_signature_on_update_check();
|
||||
#endif // (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
rsa_check_signature_on_update_check();
|
||||
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
bool esp_secure_boot_cfg_verify_release_mode(void)
|
||||
{
|
||||
bool result = false;
|
||||
bool secure;
|
||||
|
||||
bool secure_boot_v1 = esp_efuse_read_field_bit(ESP_EFUSE_ABS_DONE_0);
|
||||
bool chip_supports_sbv2 = efuse_hal_chip_revision() >= 300;
|
||||
bool secure_boot_v2 = (chip_supports_sbv2) ? esp_efuse_read_field_bit(ESP_EFUSE_ABS_DONE_1) : false;
|
||||
result = secure_boot_v1 || secure_boot_v2;
|
||||
if (secure_boot_v1 && secure_boot_v2) {
|
||||
ESP_LOGI(TAG, "ABS_DONE_0=1 (V1) and ABS_DONE_1=1 (V2)");
|
||||
ESP_LOGI(TAG, "Secure boot V2 shall take the precedence");
|
||||
} else if (!secure_boot_v1 && !secure_boot_v2) {
|
||||
result = false;
|
||||
ESP_LOGE(TAG, "Not enabled Secure Boot V1 (set ABS_DONE_0->1)");
|
||||
if (chip_supports_sbv2) {
|
||||
ESP_LOGE(TAG, "Not enabled Secure Boot V2 (set ABS_DONE_1->1)");
|
||||
}
|
||||
}
|
||||
|
||||
if (secure_boot_v1 && !secure_boot_v2) {
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_BLK2);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not read-protected secure boot key (set RD_DIS_BLK2->1)");
|
||||
}
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_BLK2);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not write-protected secure boot key (set WR_DIS_BLK2->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled JTAG (set DISABLE_JTAG->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_CONSOLE_DEBUG_DISABLE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled ROM BASIC interpreter fallback (set CONSOLE_DEBUG_DISABLE->1)");
|
||||
}
|
||||
|
||||
if (secure_boot_v2) {
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_UART_DOWNLOAD_DIS);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled UART ROM Download mode (set UART_DOWNLOAD_DIS->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_EFUSE_RD_DISABLE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled write-protection for read-protection (set WR_DIS_EFUSE_RD_DISABLE->1)");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#else // not CONFIG_IDF_TARGET_ESP32
|
||||
bool esp_secure_boot_cfg_verify_release_mode(void)
|
||||
{
|
||||
bool result = false;
|
||||
bool secure;
|
||||
|
||||
secure = esp_secure_boot_enabled();
|
||||
result = secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not enabled Secure Boot (SECURE_BOOT_EN->1)");
|
||||
}
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE);
|
||||
bool en_secure_download = esp_efuse_read_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
|
||||
if (!secure && !en_secure_download) {
|
||||
result &= false;
|
||||
ESP_LOGW(TAG, "Download mode has not been changed, disable it or set security mode:");
|
||||
ESP_LOGW(TAG, "Not disabled ROM Download mode (DIS_DOWNLOAD_MODE->1)");
|
||||
ESP_LOGW(TAG, "Not enabled Security download mode (ENABLE_SECURITY_DOWNLOAD->1)");
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_DIS_BOOT_REMAP
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled boot from RAM (set DIS_BOOT_REMAP->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_LEGACY_SPI_BOOT
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled Legcy SPI boot (set DIS_LEGACY_SPI_BOOT->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_DIRECT_BOOT
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled direct boot mode (set DIS_DIRECT_BOOT->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_HARD_DIS_JTAG
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled JTAG (set HARD_DIS_JTAG->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_SOFT_DIS_JTAG
|
||||
size_t soft_dis_jtag_cnt_val = 0;
|
||||
esp_efuse_read_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, &soft_dis_jtag_cnt_val);
|
||||
if (soft_dis_jtag_cnt_val != ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count) {
|
||||
result &= secure;
|
||||
ESP_LOGW(TAG, "Not disabled JTAG in the soft way (set SOFT_DIS_JTAG->max)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_PAD_JTAG
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled JTAG PADs (set DIS_PAD_JTAG->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_DIS_USB_JTAG
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled USB JTAG (set DIS_USB_JTAG->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not enabled AGGRESSIVE KEY REVOKE (set SECURE_BOOT_AGGRESSIVE_REVOKE->1)");
|
||||
}
|
||||
#endif
|
||||
|
||||
secure = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not disabled write-protection for read-protection (set WR_DIS_RD_DIS->1)");
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1
|
||||
unsigned purpose = ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2;
|
||||
#else
|
||||
unsigned purpose = ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0; // DIGEST0, DIGEST1 and DIGEST2
|
||||
#endif
|
||||
secure = false;
|
||||
unsigned num_keys = 0;
|
||||
for (unsigned i = 0; i < SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS; ++i) {
|
||||
esp_efuse_block_t block;
|
||||
if (esp_efuse_find_purpose(purpose + i, &block)) {
|
||||
// if chip has a few secure boot slots then we check all
|
||||
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
|
||||
bool revoke = esp_efuse_get_digest_revoke(i);
|
||||
if (revoke) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
++num_keys;
|
||||
#if SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
secure = !esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_KEY0_HI);
|
||||
#else
|
||||
secure = !esp_efuse_get_key_dis_read(block);
|
||||
#endif // !SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGE(TAG, "Secure boot key in BLOCK%d must NOT be read-protected (can not be used)", block);
|
||||
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
|
||||
ESP_LOGE(TAG, "Revoke this secure boot key (set SECURE_BOOT_KEY_REVOKE%d->1)", i);
|
||||
#endif
|
||||
}
|
||||
secure = !esp_efuse_block_is_empty(block);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGE(TAG, "Secure boot key in BLOCK%d must NOT be empty (can not be used)", block);
|
||||
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
|
||||
ESP_LOGE(TAG, "Revoke this secure boot key (set SECURE_BOOT_KEY_REVOKE%d->1)", i);
|
||||
#endif
|
||||
}
|
||||
secure = esp_efuse_get_key_dis_write(block);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not write-protected secure boot key in BLOCK%d (set WR_DIS_KEY%d->1)", block, block - EFUSE_BLK_KEY0);
|
||||
}
|
||||
#if SOC_EFUSE_KEY_PURPOSE_FIELD
|
||||
secure = esp_efuse_get_keypurpose_dis_write(block);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGW(TAG, "Not write-protected KEY_PURPOSE for BLOCK%d (set WR_DIS_KEY_PURPOSE%d->1)", block, block - EFUSE_BLK_KEY0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
result &= secure;
|
||||
|
||||
secure = (num_keys != 0);
|
||||
result &= secure;
|
||||
if (!secure) {
|
||||
ESP_LOGE(TAG, "No secure boot key found");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif // not CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#endif // not BOOTLOADER_BUILD
|
||||
|
||||
@@ -277,7 +277,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
|
||||
|
||||
ESP_LOGI(TAG, "%d signature block(s) found appended to the app.", app_key_digests.num_digests);
|
||||
if (app_key_digests.num_digests > boot_key_digests.num_digests) {
|
||||
ESP_LOGW(TAG, "App has %d signature blocks but bootloader only has %d. Some keys missing from bootloader?", app_key_digests.num_digests, boot_key_digests.num_digests);
|
||||
ESP_LOGW(TAG, "App has %d signature blocks but bootloader only has %d. Some keys missing from bootloader?");
|
||||
}
|
||||
|
||||
/* Confirm if at least one public key from the application matches a public key in the bootloader
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_chip.h"
|
||||
|
||||
#include "secure_boot_signature_priv.h"
|
||||
|
||||
@@ -47,32 +46,31 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t calculate_image_public_key_digests(bool verify_image_digest, bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests, esp_partition_pos_t *part_pos)
|
||||
esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests)
|
||||
{
|
||||
esp_image_metadata_t img_metadata = {0};
|
||||
esp_err_t ret = esp_image_get_metadata(part_pos, &img_metadata);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", ret);
|
||||
esp_image_metadata_t metadata;
|
||||
const esp_partition_t* running_app_part = esp_ota_get_running_partition();
|
||||
if (running_app_part == NULL) {
|
||||
ESP_LOGE(TAG, "Cannot get running partition");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
const esp_partition_pos_t part_pos = {
|
||||
.offset = running_app_part->address,
|
||||
.size = running_app_part->size,
|
||||
};
|
||||
esp_err_t err = esp_image_get_metadata(&part_pos, &metadata);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
|
||||
uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
|
||||
size_t sig_block_addr = img_metadata.start_addr + ALIGN_UP(img_metadata.image_len, FLASH_SECTOR_SIZE);
|
||||
memset(public_key_digests, 0, sizeof(esp_image_sig_public_key_digests_t));
|
||||
|
||||
ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%"PRIu32" (sig block offset 0x%u)", img_metadata.start_addr, sig_block_addr);
|
||||
// Generating the SHA of the public key components in the signature block
|
||||
|
||||
bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
|
||||
|
||||
if (verify_image_digest) {
|
||||
ret = bootloader_sha256_flash_contents(img_metadata.start_addr, sig_block_addr - img_metadata.start_addr, image_digest);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "error generating image digest, %d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "reading signature(s)");
|
||||
// metadata.image_len doesn't include any padding to start of the signature sector, so pad it here
|
||||
size_t sig_block_addr = metadata.start_addr + ALIGN_UP(metadata.image_len, FLASH_SECTOR_SIZE);
|
||||
ESP_LOGD(TAG, "reading signatures for app address 0x%x sig block address 0x%x", part_pos.offset, sig_block_addr);
|
||||
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
|
||||
ets_secure_boot_sig_block_t block;
|
||||
size_t addr = sig_block_addr + sizeof(ets_secure_boot_sig_block_t) * i;
|
||||
@@ -86,59 +84,20 @@ static esp_err_t calculate_image_public_key_digests(bool verify_image_digest, bo
|
||||
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
||||
bootloader_sha256_data(sig_block_sha, &block.ecdsa.key, sizeof(block.ecdsa.key));
|
||||
#endif
|
||||
bootloader_sha256_finish(sig_block_sha, key_digest);
|
||||
if (verify_image_digest) {
|
||||
// Check we can verify the image using this signature and this key
|
||||
uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
|
||||
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
|
||||
bool verified = ets_rsa_pss_verify(&block.key, block.signature, image_digest, temp_verified_digest);
|
||||
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
||||
bool verified = ets_ecdsa_verify(&block.ecdsa.key.point[0], block.ecdsa.signature, block.ecdsa.key.curve_id, image_digest, temp_verified_digest);
|
||||
#endif
|
||||
if (!verified) {
|
||||
ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(TAG, "Signature block (%d) is verified", i);
|
||||
}
|
||||
/* Copy the key digest to the buffer provided by the caller */
|
||||
memcpy((void *)public_key_digests->key_digests[public_key_digests->num_digests], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
|
||||
bootloader_sha256_finish(sig_block_sha, public_key_digests->key_digests[i]);
|
||||
}
|
||||
public_key_digests->num_digests++;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from image at %lx (err=0x%x)", part_pos->offset, err);
|
||||
ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from a running app (err=0x%x)", err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == ESP_OK && public_key_digests->num_digests > 0) {
|
||||
ESP_LOGD(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%"PRIu32")",
|
||||
public_key_digests->num_digests, img_metadata.start_addr);
|
||||
if (public_key_digests->num_digests > 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (public_key_digests->num_digests == 0) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests)
|
||||
{
|
||||
esp_partition_pos_t part_pos;
|
||||
const esp_partition_t* running_app_part = esp_ota_get_running_partition();
|
||||
if (running_app_part == NULL) {
|
||||
ESP_LOGE(TAG, "Cannot get running partition");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
part_pos.offset = running_app_part->address;
|
||||
part_pos.size = running_app_part->size;
|
||||
|
||||
esp_err_t err = calculate_image_public_key_digests(false, digest_public_keys, public_key_digests, &part_pos);
|
||||
if (public_key_digests->num_digests == 0) {
|
||||
ESP_LOGE(TAG, "No signatures were found for the running app");
|
||||
}
|
||||
return err;
|
||||
ESP_LOGE(TAG, "No signatures were found for the running app");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t *public_key_digests)
|
||||
@@ -277,33 +236,3 @@ esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signa
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME || CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
|
||||
esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos)
|
||||
{
|
||||
if (!part_pos || (efuse_digest_index < 0 || efuse_digest_index >= SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_image_sig_public_key_digests_t img_key_digests = {0};
|
||||
esp_err_t ret = calculate_image_public_key_digests(true, true, &img_key_digests, part_pos);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (esp_efuse_get_digest_revoke(efuse_digest_index)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Read key digests from efuse
|
||||
esp_secure_boot_key_digests_t efuse_key_digests;
|
||||
memset(&efuse_key_digests, 0, sizeof(esp_secure_boot_key_digests_t));
|
||||
esp_secure_boot_read_key_digests(&efuse_key_digests);
|
||||
|
||||
for (int i = 0; i < img_key_digests.num_digests; i++) {
|
||||
if (!memcmp(img_key_digests.key_digests[i], efuse_key_digests.key_digests[efuse_digest_index], ESP_SECURE_BOOT_KEY_DIGEST_LEN)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(test_rtc_custom_section)
|
||||
@@ -1,2 +0,0 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- |
|
||||
@@ -1,2 +0,0 @@
|
||||
idf_component_register(SRCS "test_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "bootloader_common.h"
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#define TEST_MAGIC_VALUE 0x42987561
|
||||
|
||||
extern rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);
|
||||
|
||||
void app_main(void) {
|
||||
rtc_retain_mem_t* mem = bootloader_common_get_rtc_retain_mem();
|
||||
uint32_t* _rtc_vars = (uint32_t*) mem->custom;
|
||||
|
||||
if (_rtc_vars[0] != TEST_MAGIC_VALUE) {
|
||||
/* On the first boot, set the data inside the array */
|
||||
_rtc_vars[0] = TEST_MAGIC_VALUE;
|
||||
} else {
|
||||
/* Second boot, the data was saved saved, success */
|
||||
printf("SUCCESS: data were saved across reboot\n");
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
esp_restart();
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
def test_rtc_reserved_memory(dut: Dut) -> None:
|
||||
dut.expect_exact('SUCCESS: data were saved across reboot', timeout=10)
|
||||
@@ -1,3 +0,0 @@
|
||||
CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0x10
|
||||
CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC=y
|
||||
CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE=0x200
|
||||
@@ -2,39 +2,28 @@ if(CONFIG_BT_ENABLED)
|
||||
|
||||
set(srcs "")
|
||||
set(include_dirs "")
|
||||
set(ldscripts "linker_common.lf")
|
||||
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
list(APPEND srcs "controller/esp32/bt.c"
|
||||
"controller/esp32/hli_api.c"
|
||||
"controller/esp32/hli_vectors.S")
|
||||
list(APPEND include_dirs include/esp32/include)
|
||||
list(APPEND ldscripts "linker_rw_bt_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
list(APPEND srcs "controller/esp32c3/bt.c")
|
||||
list(APPEND include_dirs include/esp32c3/include)
|
||||
list(APPEND ldscripts "linker_rw_bt_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
list(APPEND srcs "controller/esp32c3/bt.c")
|
||||
list(APPEND include_dirs include/esp32c3/include)
|
||||
list(APPEND ldscripts "linker_rw_bt_controller.lf")
|
||||
list(APPEND srcs "controller/esp32s3/bt.c")
|
||||
list(APPEND include_dirs include/esp32s3/include)
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
list(APPEND srcs "controller/esp32h2/bt.c")
|
||||
list(APPEND include_dirs include/esp32h2/include)
|
||||
list(APPEND ldscripts "linker_esp_ble_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
list(APPEND srcs "controller/esp32c2/bt.c"
|
||||
"controller/esp32c2/ble.c")
|
||||
list(APPEND srcs "controller/esp32c2/bt.c")
|
||||
list(APPEND include_dirs include/esp32c2/include)
|
||||
set(ldscripts "linker_esp32c2.lf")
|
||||
|
||||
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
|
||||
list(APPEND srcs "controller/esp32c2/dummy.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -50,14 +39,11 @@ if(CONFIG_BT_ENABLED)
|
||||
common/api/include/api
|
||||
common/btc/profile/esp/blufi/include
|
||||
common/btc/profile/esp/include
|
||||
common/hci_log/include
|
||||
common/ble_log/include
|
||||
)
|
||||
|
||||
|
||||
list(APPEND srcs "common/btc/core/btc_alarm.c"
|
||||
"common/api/esp_blufi_api.c"
|
||||
"common/hci_log/bt_hci_log.c"
|
||||
"common/btc/core/btc_manage.c"
|
||||
"common/btc/core/btc_task.c"
|
||||
"common/btc/profile/esp/blufi/blufi_prf.c"
|
||||
@@ -78,7 +64,6 @@ if(CONFIG_BT_ENABLED)
|
||||
"common/osi/osi.c"
|
||||
"common/osi/semaphore.c"
|
||||
"porting/mem/bt_osi_mem.c"
|
||||
"common/ble_log/ble_log_spi_out.c"
|
||||
)
|
||||
|
||||
# Host Bluedroid
|
||||
@@ -336,7 +321,6 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/stack/gatt/gatt_db.c"
|
||||
"host/bluedroid/stack/gatt/gatt_main.c"
|
||||
"host/bluedroid/stack/gatt/gatt_sr.c"
|
||||
"host/bluedroid/stack/gatt/gatt_sr_hash.c"
|
||||
"host/bluedroid/stack/gatt/gatt_utils.c"
|
||||
"host/bluedroid/stack/hcic/hciblecmds.c"
|
||||
"host/bluedroid/stack/hcic/hcicmds.c"
|
||||
@@ -489,27 +473,19 @@ if(CONFIG_BT_ENABLED)
|
||||
if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
|
||||
list(APPEND srcs
|
||||
"porting/npl/freertos/src/npl_os_freertos.c"
|
||||
"porting/mem/os_msys_init.c"
|
||||
"porting/transport/src/hci_transport.c"
|
||||
"porting/nimble/src/os_msys_init.c"
|
||||
)
|
||||
|
||||
list(APPEND include_dirs
|
||||
porting/include
|
||||
porting/nimble/include
|
||||
porting/npl/freertos/include
|
||||
porting/transport/include
|
||||
)
|
||||
|
||||
if(CONFIG_BT_LE_HCI_INTERFACE_USE_RAM)
|
||||
if(CONFIG_BT_LE_HCI_INTERFACE_USE_UART)
|
||||
list(APPEND srcs
|
||||
"porting/transport/driver/vhci/hci_driver_standard.c"
|
||||
)
|
||||
elseif(CONFIG_BT_LE_HCI_INTERFACE_USE_UART)
|
||||
list(APPEND srcs
|
||||
"porting/transport/driver/common/hci_driver_util.c"
|
||||
"porting/transport/driver/common/hci_driver_h4.c"
|
||||
"porting/transport/driver/common/hci_driver_mem.c"
|
||||
"porting/transport/driver/uart/hci_driver_uart_config.c"
|
||||
"porting/transport/driver/uart/hci_driver_uart.c"
|
||||
"porting/transport/uart/hci_uart.c"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -517,25 +493,23 @@ if(CONFIG_BT_ENABLED)
|
||||
|
||||
if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS))
|
||||
list(APPEND include_dirs
|
||||
common/tinycrypt/include
|
||||
common/tinycrypt/port
|
||||
porting/ext/tinycrypt/include
|
||||
)
|
||||
list(APPEND srcs "common/tinycrypt/src/utils.c"
|
||||
"common/tinycrypt/src/sha256.c"
|
||||
"common/tinycrypt/src/ecc.c"
|
||||
"common/tinycrypt/src/ctr_prng.c"
|
||||
"common/tinycrypt/src/ctr_mode.c"
|
||||
"common/tinycrypt/src/aes_decrypt.c"
|
||||
"common/tinycrypt/src/aes_encrypt.c"
|
||||
"common/tinycrypt/src/ccm_mode.c"
|
||||
"common/tinycrypt/src/ecc_dsa.c"
|
||||
"common/tinycrypt/src/cmac_mode.c"
|
||||
"common/tinycrypt/src/ecc_dh.c"
|
||||
"common/tinycrypt/src/hmac_prng.c"
|
||||
"common/tinycrypt/src/ecc_platform_specific.c"
|
||||
"common/tinycrypt/src/hmac.c"
|
||||
"common/tinycrypt/src/cbc_mode.c"
|
||||
"common/tinycrypt/port/esp_tinycrypt_port.c")
|
||||
list(APPEND srcs "porting/ext/tinycrypt/src/utils.c"
|
||||
"porting/ext/tinycrypt/src/sha256.c"
|
||||
"porting/ext/tinycrypt/src/ecc.c"
|
||||
"porting/ext/tinycrypt/src/ctr_prng.c"
|
||||
"porting/ext/tinycrypt/src/ctr_mode.c"
|
||||
"porting/ext/tinycrypt/src/aes_decrypt.c"
|
||||
"porting/ext/tinycrypt/src/aes_encrypt.c"
|
||||
"porting/ext/tinycrypt/src/ccm_mode.c"
|
||||
"porting/ext/tinycrypt/src/ecc_dsa.c"
|
||||
"porting/ext/tinycrypt/src/cmac_mode.c"
|
||||
"porting/ext/tinycrypt/src/ecc_dh.c"
|
||||
"porting/ext/tinycrypt/src/hmac_prng.c"
|
||||
"porting/ext/tinycrypt/src/ecc_platform_specific.c"
|
||||
"porting/ext/tinycrypt/src/hmac.c"
|
||||
"porting/ext/tinycrypt/src/cbc_mode.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_NIMBLE_ENABLED)
|
||||
@@ -543,19 +517,15 @@ if(CONFIG_BT_ENABLED)
|
||||
list(APPEND include_dirs
|
||||
|
||||
host/nimble/nimble/nimble/host/include
|
||||
host/nimble/nimble/nimble/include
|
||||
host/nimble/nimble/nimble/host/services/ans/include
|
||||
host/nimble/nimble/nimble/host/services/bas/include
|
||||
host/nimble/nimble/nimble/host/services/dis/include
|
||||
host/nimble/nimble/nimble/host/services/gap/include
|
||||
host/nimble/nimble/nimble/host/services/gatt/include
|
||||
host/nimble/nimble/nimble/host/services/htp/include
|
||||
host/nimble/nimble/nimble/host/services/ias/include
|
||||
host/nimble/nimble/nimble/host/services/ipss/include
|
||||
host/nimble/nimble/nimble/host/services/lls/include
|
||||
host/nimble/nimble/nimble/host/services/tps/include
|
||||
host/nimble/nimble/nimble/host/services/hid/include
|
||||
host/nimble/nimble/nimble/host/services/sps/include
|
||||
host/nimble/nimble/nimble/host/util/include
|
||||
host/nimble/nimble/nimble/host/store/ram/include
|
||||
host/nimble/nimble/nimble/host/store/config/include
|
||||
@@ -567,13 +537,10 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c"
|
||||
"host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c"
|
||||
"host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c"
|
||||
"host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c"
|
||||
"host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c"
|
||||
"host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c"
|
||||
"host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c"
|
||||
"host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c"
|
||||
"host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c"
|
||||
"host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_conn.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_store_util.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm.c"
|
||||
@@ -592,8 +559,6 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_mqueue.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_periodic_sync.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_att.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_ead.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_aes_ccm.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gattc.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_store.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm_lgcy.c"
|
||||
@@ -623,17 +588,14 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c"
|
||||
"host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c"
|
||||
"host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gattc_cache.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_eatt.c"
|
||||
)
|
||||
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/nimble_port.c"
|
||||
"host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c"
|
||||
"host/nimble/port/src/nvs_port.c"
|
||||
)
|
||||
list(APPEND include_dirs
|
||||
porting/include
|
||||
host/nimble/nimble/porting/nimble/include
|
||||
host/nimble/port/include
|
||||
)
|
||||
@@ -648,8 +610,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c"
|
||||
)
|
||||
list(APPEND include_dirs
|
||||
porting/include
|
||||
host/nimble/nimble/porting/npl/freertos/include
|
||||
host/nimble/nimble/porting/nimble/include
|
||||
host/nimble/nimble/nimble/include
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -713,12 +676,13 @@ if(CONFIG_BT_ENABLED)
|
||||
|
||||
endif()
|
||||
|
||||
# requirements can't depend on config
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
REQUIRES esp_timer esp_wifi
|
||||
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy mbedtls driver vfs
|
||||
LDFRAGMENTS "${ldscripts}")
|
||||
LDFRAGMENTS "linker.lf")
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||
@@ -730,37 +694,20 @@ if(CONFIG_BT_ENABLED)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE
|
||||
"-L${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32c3")
|
||||
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app_flash)
|
||||
else()
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
endif()
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE
|
||||
"-L${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3")
|
||||
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app_flash)
|
||||
else()
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
endif()
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2 AND CONFIG_BT_CONTROLLER_ENABLED)
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
if(CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_1)
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32h2/esp32h2-bt-lib/beta1/libble_app.a"
|
||||
REQUIRES esp_phy)
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32h2/esp32h2-bt-lib/beta1/libble_app.a")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_2)
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32h2/esp32h2-bt-lib/beta2/libble_app.a"
|
||||
REQUIRES esp_phy)
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32h2/esp32h2-bt-lib/beta2/libble_app.a")
|
||||
endif()
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE nimblelib)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2 AND CONFIG_BT_CONTROLLER_ENABLED)
|
||||
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32c2/esp32c2-bt-lib/libble_app_flash.a"
|
||||
REQUIRES esp_phy)
|
||||
else()
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a"
|
||||
REQUIRES esp_phy)
|
||||
endif()
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
add_prebuilt_library(nimblelib "controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE nimblelib)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -68,48 +68,6 @@ menu "Bluetooth"
|
||||
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
config BT_RELEASE_IRAM
|
||||
depends on BT_ENABLED && BT_LE_RELEASE_IRAM_SUPPORTED
|
||||
bool "Release Bluetooth text (READ DOCS FIRST)"
|
||||
default n
|
||||
help
|
||||
This option release Bluetooth text section and merge Bluetooth data, bss & text into
|
||||
a large free heap region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM.
|
||||
ESP32-C2 only 3 configurable PMP entries available, rest of them are hard-coded.
|
||||
We cannot split the memory into 3 different regions (IRAM, BLE-IRAM, DRAM).
|
||||
So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT)
|
||||
|
||||
config BT_HCI_LOG_DEBUG_EN
|
||||
depends on BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED
|
||||
bool "Enable Bluetooth HCI debug mode"
|
||||
default n
|
||||
help
|
||||
This option is used to enable bluetooth debug mode, which saves the hci layer data stream.
|
||||
|
||||
config BT_HCI_LOG_DATA_BUFFER_SIZE
|
||||
depends on BT_HCI_LOG_DEBUG_EN
|
||||
int "Size of the cache used for HCI data in Bluetooth HCI debug mode (N*1024 bytes)"
|
||||
range 1 100
|
||||
default 5
|
||||
help
|
||||
This option is to configure the buffer size of the hci data steam cache in hci debug mode.
|
||||
This is a ring buffer, the new data will overwrite the oldest data if the buffer is full.
|
||||
|
||||
config BT_HCI_LOG_ADV_BUFFER_SIZE
|
||||
depends on BT_HCI_LOG_DEBUG_EN
|
||||
int "Size of the cache used for adv report in Bluetooth HCI debug mode (N*1024 bytes)"
|
||||
range 1 100
|
||||
default 8
|
||||
help
|
||||
This option is to configure the buffer size of the hci adv report cache in hci debug mode.
|
||||
This is a ring buffer, the new data will overwrite the oldest data if the buffer is full.
|
||||
|
||||
menu "Common Options"
|
||||
visible if (BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED)
|
||||
|
||||
source "$IDF_PATH/components/bt/common/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
||||
menuconfig BLE_MESH
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
config BT_ALARM_MAX_NUM
|
||||
int "Maximum number of Bluetooth alarms"
|
||||
default 50
|
||||
help
|
||||
This option decides the maximum number of alarms which
|
||||
could be used by Bluetooth host.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
bool "Output ble logs to SPI bus (Experimental)"
|
||||
default n
|
||||
help
|
||||
Output ble logs to SPI bus
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_UL_TASK_BUF_SIZE
|
||||
int "SPI transaction buffer size for upper layer task logs"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default 512
|
||||
help
|
||||
SPI transaction buffer size for upper layer task logs.
|
||||
There will be 2 SPI DMA buffers with the same size.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_HCI_ENABLED
|
||||
bool "Enable HCI log output to SPI"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default n
|
||||
help
|
||||
Enable logging of HCI packets to the SPI bus when BLE SPI log output is enabled.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_HOST_ENABLED
|
||||
bool "Enable Host log output to SPI"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default n
|
||||
help
|
||||
This configuration applies to the logs of both Bluedroid Host and NimBLE Host.
|
||||
When BLE SPI log output is enabled, this option allows host logs to be transmitted via SPI.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
bool "Enable Controller log output to SPI"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
depends on BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
|
||||
default n
|
||||
help
|
||||
Enable controller log output to SPI bus.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_LL_TASK_BUF_SIZE
|
||||
int "SPI transaction buffer size for lower layer task logs"
|
||||
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
default 1024
|
||||
help
|
||||
SPI transaction buffer size for upper layer task logs.
|
||||
There will be 2 SPI DMA buffers with the same size.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_LL_ISR_BUF_SIZE
|
||||
int "SPI transaction buffer size for lower layer ISR logs"
|
||||
depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
default 512
|
||||
help
|
||||
SPI transaction buffer size for upper layer ISR logs.
|
||||
There will be 2 SPI DMA buffers with the same size.
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_MOSI_IO_NUM
|
||||
int "GPIO number of SPI MOSI"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default 0
|
||||
help
|
||||
GPIO number of SPI MOSI
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_SCLK_IO_NUM
|
||||
int "GPIO number of SPI SCLK"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default 1
|
||||
help
|
||||
GPIO number of SPI SCLK
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_CS_IO_NUM
|
||||
int "GPIO number of SPI CS"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default 2
|
||||
help
|
||||
GPIO number of SPI CS
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
bool "Enable ble log & logic analyzer log time sync"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable ble log & logic analyzer log time sync
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM
|
||||
int "GPIO number of SYNC IO"
|
||||
depends on BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
default 3
|
||||
help
|
||||
GPIO number of SYNC IO
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
bool "Enable periodic buffer flush out"
|
||||
depends on BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default n
|
||||
help
|
||||
Enable periodic buffer flush out
|
||||
Not recommended when SPI receiver is unavailable
|
||||
|
||||
config BT_BLE_LOG_SPI_OUT_FLUSH_TIMEOUT
|
||||
int "Buffer flush out period in unit of ms"
|
||||
depends on BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
default 1000
|
||||
help
|
||||
Buffer flush out period in unit of ms
|
||||
@@ -38,8 +38,7 @@ esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn
|
||||
arg.wifi_conn_report.softap_conn_num = softap_conn_num;
|
||||
arg.wifi_conn_report.extra_info = extra_info;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy,
|
||||
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
|
||||
@@ -55,8 +54,7 @@ esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list
|
||||
arg.wifi_list.apCount = apCount;
|
||||
arg.wifi_list.list = list;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy,
|
||||
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_profile_init(void)
|
||||
@@ -69,7 +67,7 @@ esp_err_t esp_blufi_profile_init(void)
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_INIT;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_profile_deinit(void)
|
||||
@@ -82,7 +80,7 @@ esp_err_t esp_blufi_profile_deinit(void)
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_DEINIT;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint16_t esp_blufi_get_version(void)
|
||||
@@ -102,7 +100,7 @@ esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state)
|
||||
msg.act = BTC_BLUFI_ACT_SEND_ERR_INFO;
|
||||
arg.blufi_err_infor.state = state;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len)
|
||||
@@ -120,7 +118,6 @@ esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len)
|
||||
arg.custom_data.data = data;
|
||||
arg.custom_data.data_len = data_len;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy,
|
||||
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
|
||||
@@ -49,8 +49,6 @@ typedef enum {
|
||||
typedef enum {
|
||||
ESP_BLUFI_STA_CONN_SUCCESS = 0x00,
|
||||
ESP_BLUFI_STA_CONN_FAIL = 0x01,
|
||||
ESP_BLUFI_STA_CONNECTING = 0x02,
|
||||
ESP_BLUFI_STA_NO_IP = 0x03,
|
||||
} esp_blufi_sta_conn_state_t;
|
||||
|
||||
/// BLUFI init status
|
||||
@@ -77,8 +75,6 @@ typedef enum {
|
||||
ESP_BLUFI_MAKE_PUBLIC_ERROR,
|
||||
ESP_BLUFI_DATA_FORMAT_ERROR,
|
||||
ESP_BLUFI_CALC_MD5_ERROR,
|
||||
ESP_BLUFI_WIFI_SCAN_FAIL,
|
||||
ESP_BLUFI_MSG_STATE_ERROR,
|
||||
} esp_blufi_error_state_t;
|
||||
|
||||
/**
|
||||
@@ -102,12 +98,6 @@ typedef struct {
|
||||
bool softap_max_conn_num_set; /*!< is max connection number of softap interface set */
|
||||
uint8_t softap_channel; /*!< channel of softap interface */
|
||||
bool softap_channel_set; /*!< is channel of softap interface set */
|
||||
uint8_t sta_max_conn_retry; /*!< max retry of sta establish connection */
|
||||
bool sta_max_conn_retry_set; /*!< is max retry of sta establish connection set */
|
||||
uint8_t sta_conn_end_reason; /*!< reason of sta connection end */
|
||||
bool sta_conn_end_reason_set; /*!< is reason of sta connection end set */
|
||||
int8_t sta_conn_rssi; /*!< rssi of sta connection */
|
||||
bool sta_conn_rssi_set; /*!< is rssi of sta connection set */
|
||||
} esp_blufi_extra_info_t;
|
||||
|
||||
/** @brief Description of an WiFi AP */
|
||||
|
||||
@@ -1,983 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "ble_log/ble_log_spi_out.h"
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
|
||||
// Private defines
|
||||
#define BLE_LOG_TAG "BLE_LOG"
|
||||
#define SPI_OUT_BUS SPI2_HOST
|
||||
#define SPI_OUT_MAX_TRANSFER_SIZE 10240
|
||||
#define SPI_OUT_FRAME_HEAD_LEN 4
|
||||
#define SPI_OUT_FRAME_TAIL_LEN 4
|
||||
#define SPI_OUT_FRAME_OVERHEAD (SPI_OUT_FRAME_HEAD_LEN + SPI_OUT_FRAME_TAIL_LEN)
|
||||
#define SPI_OUT_RECYCLE_TIMEOUT_MS 10
|
||||
#define SPI_OUT_TRANS_CB_FLAG_AVAILABLE 0
|
||||
#define SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE 1
|
||||
#define SPI_OUT_TRANS_CB_FLAG_IN_QUEUE 2
|
||||
#define SPI_OUT_FLUSHOUT_TIMEOUT (CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMEOUT * 1000)
|
||||
#define SPI_OUT_PACKET_LOSS_UL 0
|
||||
#define SPI_OUT_PACKET_LOSS_LL_TASK 1
|
||||
#define SPI_OUT_PACKET_LOSS_LL_ISR 2
|
||||
#define SPI_OUT_PACKET_LOSS_FRAME_SIZE 6
|
||||
#define SPI_OUT_INTERFACE_FLAG_IN_ISR (1 << 3)
|
||||
#define SPI_OUT_TRANS_ITVL_MIN_US 30
|
||||
#define SPI_OUT_SPI_MASTER_QUEUE_SIZE 6
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
#define SPI_OUT_TS_SYNC_TIMEOUT (1000 * 1000)
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
// Private typedefs
|
||||
typedef struct {
|
||||
// CRITICAL: 0 for available, 1 for need queue (ISR), 2 for in queue
|
||||
// This flag is for multithreading, must be a word, do not modify
|
||||
volatile uint32_t flag;
|
||||
uint16_t buf_size;
|
||||
uint16_t length;
|
||||
spi_transaction_t trans;
|
||||
} spi_out_trans_cb_t;
|
||||
|
||||
typedef struct {
|
||||
spi_out_trans_cb_t *trans_cb[2];
|
||||
uint8_t trans_cb_idx;
|
||||
uint8_t frame_cnt;
|
||||
uint32_t bytes_loss_cnt;
|
||||
uint8_t trans_loss_cnt;
|
||||
} spi_out_log_cb_t;
|
||||
|
||||
// Private variables
|
||||
static bool spi_out_inited = false;
|
||||
static spi_device_handle_t spi_handle = NULL;
|
||||
static uint32_t last_tx_done_ts = 0;
|
||||
|
||||
static bool ul_log_inited = false;
|
||||
static SemaphoreHandle_t ul_log_mutex = NULL;
|
||||
static spi_out_log_cb_t *ul_log_cb = NULL;
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
static esp_timer_handle_t ul_log_flushout_timer = NULL;
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
static bool ll_log_inited = false;
|
||||
static spi_out_log_cb_t *ll_task_log_cb = NULL;
|
||||
static spi_out_log_cb_t *ll_isr_log_cb = NULL;
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
static esp_timer_handle_t ll_log_flushout_timer = NULL;
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
static bool ts_sync_inited = false;
|
||||
static bool sync_io_level = false;
|
||||
static esp_timer_handle_t ts_sync_timer = NULL;
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
// Extern function declarations
|
||||
extern void esp_panic_handler_feed_wdts(void);
|
||||
|
||||
// Private function declarations
|
||||
static int spi_out_init_trans(spi_out_trans_cb_t **trans_cb, uint16_t buf_size);
|
||||
static void spi_out_deinit_trans(spi_out_trans_cb_t **trans_cb);
|
||||
static void spi_out_tx_done_cb(spi_transaction_t *ret_trans);
|
||||
static inline int spi_out_append_trans(spi_out_trans_cb_t *trans_cb);
|
||||
|
||||
static int spi_out_log_cb_init(spi_out_log_cb_t **log_cb, uint16_t buf_size);
|
||||
static void spi_out_log_cb_deinit(spi_out_log_cb_t **log_cb);
|
||||
static inline int spi_out_log_cb_check_trans(spi_out_log_cb_t *log_cb, uint16_t len);
|
||||
static inline void spi_out_log_cb_append_trans(spi_out_log_cb_t *log_cb);
|
||||
static inline void spi_out_log_cb_flush_trans(spi_out_log_cb_t *log_cb);
|
||||
static void spi_out_log_cb_write(spi_out_log_cb_t *log_cb, const uint8_t *addr, uint16_t len, \
|
||||
const uint8_t *addr_append, uint16_t len_append, uint8_t source);
|
||||
static void spi_out_log_cb_write_packet_loss(spi_out_log_cb_t *log_cb, uint8_t flag);
|
||||
static void spi_out_log_cb_dump(spi_out_log_cb_t *log_cb);
|
||||
|
||||
static int spi_out_ul_log_init(void);
|
||||
static void spi_out_ul_log_deinit(void);
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
static void esp_timer_cb_ul_log_flushout(void);
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
static int spi_out_ll_log_init(void);
|
||||
static void spi_out_ll_log_deinit(void);
|
||||
static void spi_out_ll_log_ev_proc(void);
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
static void esp_timer_cb_ll_log_flushout(void);
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\
|
||||
defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21)
|
||||
extern void r_ble_log_simple_put_ev(void);
|
||||
#define BLE_LOG_LL_PUT_EV r_ble_log_simple_put_ev()
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
|
||||
extern void ble_log_simple_put_ev(void);
|
||||
#define BLE_LOG_LL_PUT_EV ble_log_simple_put_ev()
|
||||
#else
|
||||
#define BLE_LOG_LL_PUT_EV
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
static int spi_out_ts_sync_init(void);
|
||||
static void spi_out_ts_sync_deinit(void);
|
||||
static void esp_timer_cb_ts_sync(void);
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\
|
||||
defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21)
|
||||
extern uint32_t r_ble_lll_timer_current_tick_get(void);
|
||||
#define SPI_OUT_GET_LC_TIME r_ble_lll_timer_current_tick_get()
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
|
||||
extern uint32_t r_os_cputime_get32(void);
|
||||
#define SPI_OUT_GET_LC_TIME r_os_cputime_get32()
|
||||
#else
|
||||
#define SPI_OUT_GET_LC_TIME 0
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
// Private functions
|
||||
static int spi_out_init_trans(spi_out_trans_cb_t **trans_cb, uint16_t buf_size)
|
||||
{
|
||||
// Memory allocations
|
||||
*trans_cb = (spi_out_trans_cb_t *)malloc(sizeof(spi_out_trans_cb_t));
|
||||
if (!(*trans_cb)) {
|
||||
return -1;
|
||||
}
|
||||
memset(*trans_cb, 0, sizeof(spi_out_trans_cb_t));
|
||||
|
||||
uint8_t *buf = (uint8_t *)heap_caps_malloc(buf_size, MALLOC_CAP_DMA);
|
||||
if (!buf) {
|
||||
free(*trans_cb);
|
||||
*trans_cb = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialization
|
||||
(*trans_cb)->buf_size = buf_size;
|
||||
(*trans_cb)->trans.tx_buffer = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spi_out_deinit_trans(spi_out_trans_cb_t **trans_cb)
|
||||
{
|
||||
if (!(*trans_cb)) {
|
||||
return;
|
||||
}
|
||||
if ((*trans_cb)->trans.tx_buffer) {
|
||||
free((uint8_t *)(*trans_cb)->trans.tx_buffer);
|
||||
(*trans_cb)->trans.tx_buffer = NULL;
|
||||
}
|
||||
|
||||
free(*trans_cb);
|
||||
*trans_cb = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
IRAM_ATTR static void spi_out_tx_done_cb(spi_transaction_t *ret_trans)
|
||||
{
|
||||
last_tx_done_ts = esp_timer_get_time();
|
||||
spi_out_trans_cb_t *trans_cb = __containerof(ret_trans, spi_out_trans_cb_t, trans);
|
||||
trans_cb->length = 0;
|
||||
trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_AVAILABLE;
|
||||
}
|
||||
|
||||
IRAM_ATTR static void spi_out_pre_tx_cb(spi_transaction_t *ret_trans)
|
||||
{
|
||||
// SPI slave continuous transaction workaround
|
||||
while (esp_timer_get_time() - last_tx_done_ts < SPI_OUT_TRANS_ITVL_MIN_US) {}
|
||||
}
|
||||
|
||||
IRAM_ATTR static inline int spi_out_append_trans(spi_out_trans_cb_t *trans_cb)
|
||||
{
|
||||
if (trans_cb->flag != SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE || !trans_cb->length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// CRITICAL: Length unit conversion from bytes to bits
|
||||
trans_cb->trans.length = trans_cb->length * 8;
|
||||
trans_cb->trans.rxlength = 0;
|
||||
if (spi_device_queue_trans(spi_handle, &(trans_cb->trans), 0) == ESP_OK) {
|
||||
trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_IN_QUEUE;
|
||||
return 0;
|
||||
} else {
|
||||
trans_cb->length = 0;
|
||||
trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_AVAILABLE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_out_log_cb_init(spi_out_log_cb_t **log_cb, uint16_t buf_size)
|
||||
{
|
||||
// Initialize log control block
|
||||
*log_cb = (spi_out_log_cb_t *)malloc(sizeof(spi_out_log_cb_t));
|
||||
if (!(*log_cb)) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control block!");
|
||||
return -1;
|
||||
}
|
||||
memset(*log_cb, 0, sizeof(spi_out_log_cb_t));
|
||||
|
||||
// Initialize transactions
|
||||
int ret = 0;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
ret |= spi_out_init_trans(&((*log_cb)->trans_cb[i]), buf_size);
|
||||
}
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize SPI transactions!");
|
||||
spi_out_log_cb_deinit(log_cb);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spi_out_log_cb_deinit(spi_out_log_cb_t **log_cb)
|
||||
{
|
||||
if (!(*log_cb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
if ((*log_cb)->trans_cb[i]) {
|
||||
spi_out_deinit_trans(&((*log_cb)->trans_cb[i]));
|
||||
}
|
||||
}
|
||||
free(*log_cb);
|
||||
*log_cb = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
IRAM_ATTR static inline int spi_out_log_cb_check_trans(spi_out_log_cb_t *log_cb, uint16_t len)
|
||||
{
|
||||
spi_out_trans_cb_t *trans_cb;
|
||||
uint16_t frame_len = len + SPI_OUT_FRAME_OVERHEAD;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
|
||||
if (frame_len > trans_cb->buf_size) {
|
||||
goto failed;
|
||||
}
|
||||
if (trans_cb->flag == SPI_OUT_TRANS_CB_FLAG_AVAILABLE) {
|
||||
if ((trans_cb->buf_size - trans_cb->length) >= (len + SPI_OUT_FRAME_OVERHEAD)) {
|
||||
return 0;
|
||||
} else {
|
||||
trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE;
|
||||
}
|
||||
}
|
||||
log_cb->trans_cb_idx = !(log_cb->trans_cb_idx);
|
||||
}
|
||||
failed:
|
||||
log_cb->bytes_loss_cnt += len + SPI_OUT_FRAME_OVERHEAD;
|
||||
log_cb->frame_cnt++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// CRITICAL: Shall not be called from ISR!
|
||||
IRAM_ATTR static inline void spi_out_log_cb_append_trans(spi_out_log_cb_t *log_cb)
|
||||
{
|
||||
spi_out_trans_cb_t *trans_cb;
|
||||
uint8_t idx = !log_cb->trans_cb_idx;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
trans_cb = log_cb->trans_cb[idx];
|
||||
if (trans_cb->flag == SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE) {
|
||||
if (spi_out_append_trans(trans_cb) != 0) {
|
||||
log_cb->trans_loss_cnt++;
|
||||
}
|
||||
}
|
||||
idx = !idx;
|
||||
}
|
||||
}
|
||||
|
||||
IRAM_ATTR static inline void spi_out_log_cb_flush_trans(spi_out_log_cb_t *log_cb)
|
||||
{
|
||||
spi_out_trans_cb_t *trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
|
||||
if (trans_cb->length && (trans_cb->flag == SPI_OUT_TRANS_CB_FLAG_AVAILABLE)) {
|
||||
trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE;
|
||||
}
|
||||
}
|
||||
|
||||
IRAM_ATTR static void spi_out_log_cb_write(spi_out_log_cb_t *log_cb, const uint8_t *addr, uint16_t len, \
|
||||
const uint8_t *addr_append, uint16_t len_append, uint8_t source)
|
||||
{
|
||||
spi_out_trans_cb_t *trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
|
||||
|
||||
uint8_t *buf = (uint8_t *)trans_cb->trans.tx_buffer + trans_cb->length;
|
||||
uint16_t total_length = len + len_append;
|
||||
const uint8_t head[4] = {total_length & 0xFF, (total_length >> 8) & 0xFF, source, log_cb->frame_cnt};
|
||||
uint32_t checksum = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
checksum += addr[i];
|
||||
}
|
||||
for (int i = 0; i < len_append; i++) {
|
||||
checksum += addr_append[i];
|
||||
}
|
||||
|
||||
memcpy(buf, head, SPI_OUT_FRAME_HEAD_LEN);
|
||||
memcpy(buf + SPI_OUT_FRAME_HEAD_LEN, addr, len);
|
||||
if (len_append) {
|
||||
memcpy(buf + SPI_OUT_FRAME_HEAD_LEN + len, addr_append, len_append);
|
||||
}
|
||||
memcpy(buf + SPI_OUT_FRAME_HEAD_LEN + total_length, &checksum, SPI_OUT_FRAME_TAIL_LEN);
|
||||
|
||||
trans_cb->length += total_length + SPI_OUT_FRAME_OVERHEAD;
|
||||
log_cb->frame_cnt++;
|
||||
if ((trans_cb->buf_size - trans_cb->length) <= SPI_OUT_FRAME_OVERHEAD) {
|
||||
trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
IRAM_ATTR static void spi_out_log_cb_write_packet_loss(spi_out_log_cb_t *log_cb, uint8_t flag)
|
||||
{
|
||||
if (!log_cb->bytes_loss_cnt && !log_cb->trans_loss_cnt) {
|
||||
return;
|
||||
}
|
||||
if (spi_out_log_cb_check_trans(log_cb, SPI_OUT_PACKET_LOSS_FRAME_SIZE) == 0) {
|
||||
uint8_t packet_loss_frame[SPI_OUT_PACKET_LOSS_FRAME_SIZE];
|
||||
packet_loss_frame[0] = flag;
|
||||
memcpy(packet_loss_frame + 1, (uint8_t *)&log_cb->bytes_loss_cnt, 4);
|
||||
packet_loss_frame[5] = log_cb->trans_loss_cnt;
|
||||
spi_out_log_cb_write(log_cb, packet_loss_frame, SPI_OUT_PACKET_LOSS_FRAME_SIZE, NULL, 0, BLE_LOG_SPI_OUT_SOURCE_LOSS);
|
||||
|
||||
log_cb->bytes_loss_cnt = 0;
|
||||
log_cb->trans_loss_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_out_log_cb_dump(spi_out_log_cb_t *log_cb)
|
||||
{
|
||||
spi_out_trans_cb_t *trans_cb;
|
||||
uint8_t *buf;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
// Dump the last transaction before dumping the current transaction
|
||||
log_cb->trans_cb_idx = !(log_cb->trans_cb_idx);
|
||||
trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx];
|
||||
buf = (uint8_t *)trans_cb->trans.tx_buffer;
|
||||
for (uint16_t j = 0; j < trans_cb->buf_size; j++) {
|
||||
esp_rom_printf("%02x ", buf[j]);
|
||||
|
||||
// Feed watchdogs periodically to avoid wdts timeout
|
||||
if ((j % 100) == 0) {
|
||||
esp_panic_handler_feed_wdts();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_out_ul_log_init(void)
|
||||
{
|
||||
if (ul_log_inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize mutex
|
||||
ul_log_mutex = xSemaphoreCreateMutex();
|
||||
if (!ul_log_mutex) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to create mutex for upper layer task log!");
|
||||
goto mutex_init_failed;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
// Initialize flushout timer
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = (esp_timer_cb_t)esp_timer_cb_ul_log_flushout,
|
||||
.dispatch_method = ESP_TIMER_TASK
|
||||
};
|
||||
if (esp_timer_create(&timer_args, &ul_log_flushout_timer) != ESP_OK) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize flushout timer upper layer task log!");
|
||||
goto timer_init_failed;
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
// Initialize log control block
|
||||
if (spi_out_log_cb_init(&ul_log_cb, CONFIG_BT_BLE_LOG_SPI_OUT_UL_TASK_BUF_SIZE) != 0) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control blocks for upper layer task log!");
|
||||
goto log_cb_init_failed;
|
||||
}
|
||||
|
||||
// Initialization done
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize upper layer task log!");
|
||||
ul_log_inited = true;
|
||||
return 0;
|
||||
|
||||
log_cb_init_failed:
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
esp_timer_delete(ul_log_flushout_timer);
|
||||
timer_init_failed:
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
vSemaphoreDelete(ul_log_mutex);
|
||||
mutex_init_failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void spi_out_ul_log_deinit(void)
|
||||
{
|
||||
if (!ul_log_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
esp_timer_stop(ul_log_flushout_timer);
|
||||
esp_timer_delete(ul_log_flushout_timer);
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
xSemaphoreTake(ul_log_mutex, portMAX_DELAY);
|
||||
spi_out_log_cb_deinit(&ul_log_cb);
|
||||
xSemaphoreGive(ul_log_mutex);
|
||||
|
||||
vSemaphoreDelete(ul_log_mutex);
|
||||
ul_log_mutex = NULL;
|
||||
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to deinitialize upper layer log!");
|
||||
ul_log_inited = false;
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
IRAM_ATTR static void esp_timer_cb_ul_log_flushout(void)
|
||||
{
|
||||
xSemaphoreTake(ul_log_mutex, portMAX_DELAY);
|
||||
spi_out_log_cb_flush_trans(ul_log_cb);
|
||||
spi_out_log_cb_append_trans(ul_log_cb);
|
||||
xSemaphoreGive(ul_log_mutex);
|
||||
|
||||
esp_timer_start_once(ul_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT);
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
static int spi_out_ll_log_init(void)
|
||||
{
|
||||
if (ll_log_inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
// Initialize flushout timer
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = (esp_timer_cb_t)esp_timer_cb_ll_log_flushout,
|
||||
.dispatch_method = ESP_TIMER_TASK
|
||||
};
|
||||
if (esp_timer_create(&timer_args, &ll_log_flushout_timer) != ESP_OK) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize flushout timer for controller log!");
|
||||
goto timer_init_failed;
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
// Initialize log control blocks for controller task & ISR logs
|
||||
if (spi_out_log_cb_init(&ll_task_log_cb, CONFIG_BT_BLE_LOG_SPI_OUT_LL_TASK_BUF_SIZE) != 0) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control blocks for controller task!");
|
||||
goto task_log_cb_init_failed;
|
||||
}
|
||||
if (spi_out_log_cb_init(&ll_isr_log_cb, CONFIG_BT_BLE_LOG_SPI_OUT_LL_ISR_BUF_SIZE) != 0) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control blocks for controller ISR!");
|
||||
goto isr_log_cb_init_failed;
|
||||
}
|
||||
|
||||
// Initialization done
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize log control blocks for controller task & ISR!");
|
||||
ll_log_inited = true;
|
||||
return 0;
|
||||
|
||||
isr_log_cb_init_failed:
|
||||
spi_out_log_cb_deinit(&ll_task_log_cb);
|
||||
task_log_cb_init_failed:
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
esp_timer_delete(ll_log_flushout_timer);
|
||||
timer_init_failed:
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void spi_out_ll_log_deinit(void)
|
||||
{
|
||||
if (!ll_log_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
esp_timer_stop(ll_log_flushout_timer);
|
||||
esp_timer_delete(ll_log_flushout_timer);
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
|
||||
spi_out_log_cb_deinit(&ll_isr_log_cb);
|
||||
spi_out_log_cb_deinit(&ll_task_log_cb);
|
||||
|
||||
// Deinitialization done
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to deinitialize controller log!");
|
||||
ll_log_inited = false;
|
||||
return;
|
||||
}
|
||||
|
||||
IRAM_ATTR static void spi_out_ll_log_ev_proc(void)
|
||||
{
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
// Request from flushout timer
|
||||
spi_out_log_cb_flush_trans(ll_isr_log_cb);
|
||||
spi_out_log_cb_append_trans(ll_isr_log_cb);
|
||||
|
||||
spi_out_log_cb_flush_trans(ll_task_log_cb);
|
||||
spi_out_log_cb_append_trans(ll_task_log_cb);
|
||||
|
||||
esp_timer_start_once(ll_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT);
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
IRAM_ATTR static void esp_timer_cb_ll_log_flushout(void)
|
||||
{
|
||||
BLE_LOG_LL_PUT_EV;
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
static int spi_out_ts_sync_init(void)
|
||||
{
|
||||
if (ts_sync_inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize sync timer
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = (esp_timer_cb_t)esp_timer_cb_ts_sync,
|
||||
.dispatch_method = ESP_TIMER_TASK
|
||||
};
|
||||
if (esp_timer_create(&timer_args, &ts_sync_timer) != ESP_OK) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize timestamp synchronizer timer!");
|
||||
goto timer_init_failed;
|
||||
}
|
||||
|
||||
// Initialize sync IO
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = (1UL << CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM),
|
||||
.pull_down_en = 0,
|
||||
.pull_up_en = 0
|
||||
};
|
||||
if (gpio_config(&io_conf) != ESP_OK) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize timestamp synchronizer IO!");
|
||||
goto gpio_init_failed;
|
||||
}
|
||||
|
||||
// Initialization done
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize timestamp synchronizer!");
|
||||
sync_io_level = false;
|
||||
gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, sync_io_level);
|
||||
ts_sync_inited = true;
|
||||
return 0;
|
||||
|
||||
gpio_init_failed:
|
||||
esp_timer_delete(ts_sync_timer);
|
||||
timer_init_failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void spi_out_ts_sync_deinit(void)
|
||||
{
|
||||
if (!ts_sync_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Deinitialize timestamp synchronizer
|
||||
esp_timer_stop(ts_sync_timer);
|
||||
esp_timer_delete(ts_sync_timer);
|
||||
|
||||
// Deinitialize sync IO
|
||||
sync_io_level = false;
|
||||
gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, sync_io_level);
|
||||
gpio_reset_pin(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM);
|
||||
|
||||
// Deinitialization done
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to deinitialize timestamp synchronizer!");
|
||||
ts_sync_inited = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// CRITICAL: This function is called in ESP Timer task
|
||||
static void esp_timer_cb_ts_sync(void)
|
||||
{
|
||||
// Initialize variables
|
||||
uint32_t lc_ts = 0;
|
||||
uint32_t esp_ts = 0;
|
||||
|
||||
// Toggle sync IO
|
||||
sync_io_level = !sync_io_level;
|
||||
|
||||
// Enter critical
|
||||
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
portENTER_CRITICAL(&spinlock);
|
||||
|
||||
// Get LC timestamp
|
||||
lc_ts = SPI_OUT_GET_LC_TIME;
|
||||
|
||||
// Set sync IO level
|
||||
gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level);
|
||||
|
||||
// Get ESP timestamp
|
||||
esp_ts = esp_timer_get_time();
|
||||
portEXIT_CRITICAL(&spinlock);
|
||||
// Exit critical
|
||||
|
||||
// Write timestamp sync log
|
||||
uint8_t sync_frame[9];
|
||||
sync_frame[0] = ((uint8_t)sync_io_level & 0xFF);
|
||||
memcpy(sync_frame + 1, &lc_ts, sizeof(lc_ts));
|
||||
memcpy(sync_frame + 5, &esp_ts, sizeof(esp_ts));
|
||||
ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_SYNC, sync_frame, 9);
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
// Public functions
|
||||
int ble_log_spi_out_init(void)
|
||||
{
|
||||
// Avoid double init
|
||||
if (spi_out_inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize SPI
|
||||
spi_bus_config_t bus_config = {
|
||||
.miso_io_num = -1,
|
||||
.mosi_io_num = CONFIG_BT_BLE_LOG_SPI_OUT_MOSI_IO_NUM,
|
||||
.sclk_io_num = CONFIG_BT_BLE_LOG_SPI_OUT_SCLK_IO_NUM,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = SPI_OUT_MAX_TRANSFER_SIZE,
|
||||
#if CONFIG_SPI_MASTER_ISR_IN_IRAM
|
||||
.intr_flags = ESP_INTR_FLAG_IRAM
|
||||
#endif // CONFIG_SPI_MASTER_ISR_IN_IRAM
|
||||
};
|
||||
spi_device_interface_config_t dev_config = {
|
||||
.clock_speed_hz = SPI_MASTER_FREQ_20M,
|
||||
.mode = 0,
|
||||
.spics_io_num = CONFIG_BT_BLE_LOG_SPI_OUT_CS_IO_NUM,
|
||||
.queue_size = SPI_OUT_SPI_MASTER_QUEUE_SIZE,
|
||||
.post_cb = spi_out_tx_done_cb,
|
||||
.pre_cb = spi_out_pre_tx_cb
|
||||
};
|
||||
if (spi_bus_initialize(SPI_OUT_BUS, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to initialize SPI bus!");
|
||||
goto spi_bus_init_failed;
|
||||
}
|
||||
if (spi_bus_add_device(SPI_OUT_BUS, &dev_config, &spi_handle) != ESP_OK) {
|
||||
ESP_LOGE(BLE_LOG_TAG, "Failed to add device to SPI bus!");
|
||||
goto spi_device_add_failed;
|
||||
}
|
||||
|
||||
if (spi_out_ul_log_init() != 0) {
|
||||
goto ul_log_init_failed;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
if (spi_out_ll_log_init() != 0) {
|
||||
goto ll_log_init_failed;
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
if (spi_out_ts_sync_init() != 0) {
|
||||
goto ts_sync_init_failed;
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
// Initialization done
|
||||
ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize BLE log SPI output interface!");
|
||||
spi_out_inited = true;
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
// Start flushout timer
|
||||
esp_timer_start_once(ul_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT);
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
esp_timer_start_once(ll_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT);
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_FLUSH_TIMER_ENABLED
|
||||
return 0;
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
ts_sync_init_failed:
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
spi_out_ll_log_deinit();
|
||||
ll_log_init_failed:
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
spi_out_ul_log_deinit();
|
||||
ul_log_init_failed:
|
||||
spi_bus_remove_device(spi_handle);
|
||||
spi_handle = NULL;
|
||||
spi_device_add_failed:
|
||||
spi_bus_free(SPI_OUT_BUS);
|
||||
spi_bus_init_failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ble_log_spi_out_deinit(void)
|
||||
{
|
||||
// Avoid double deinit
|
||||
if (!spi_out_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Drain all queued transactions
|
||||
assert(spi_device_acquire_bus(spi_handle, portMAX_DELAY) == ESP_OK);
|
||||
spi_device_release_bus(spi_handle);
|
||||
|
||||
// Remove SPI master
|
||||
spi_bus_remove_device(spi_handle);
|
||||
spi_handle = NULL;
|
||||
spi_bus_free(SPI_OUT_BUS);
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
spi_out_ts_sync_deinit();
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
spi_out_ll_log_deinit();
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
spi_out_ul_log_deinit();
|
||||
|
||||
// Reset init flag
|
||||
spi_out_inited = false;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
void ble_log_spi_out_ts_sync_start(void)
|
||||
{
|
||||
// Check if SPI out is initialized
|
||||
if (!spi_out_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start timestamp sync timer
|
||||
if (ts_sync_timer) {
|
||||
if (!esp_timer_is_active(ts_sync_timer)) {
|
||||
esp_timer_start_periodic(ts_sync_timer, SPI_OUT_TS_SYNC_TIMEOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ble_log_spi_out_ts_sync_stop(void)
|
||||
{
|
||||
// Check if SPI out is initialized
|
||||
if (!spi_out_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop timestamp sync timer
|
||||
if (ts_sync_timer) {
|
||||
if (esp_timer_is_active(ts_sync_timer)) {
|
||||
esp_timer_stop(ts_sync_timer);
|
||||
}
|
||||
|
||||
// Set sync IO to low level
|
||||
sync_io_level = 0;
|
||||
gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
// Only LL task has access to this API
|
||||
IRAM_ATTR void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,\
|
||||
const uint8_t *addr_append, uint32_t flag)
|
||||
{
|
||||
if (!ll_log_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool in_isr = (bool)(flag & SPI_OUT_INTERFACE_FLAG_IN_ISR);
|
||||
uint8_t source = in_isr ? BLE_LOG_SPI_OUT_SOURCE_ESP_ISR : BLE_LOG_SPI_OUT_SOURCE_ESP;
|
||||
spi_out_log_cb_t *log_cb = in_isr ? ll_isr_log_cb : ll_task_log_cb;
|
||||
uint16_t total_length = (uint16_t)(len + len_append);
|
||||
if (spi_out_log_cb_check_trans(log_cb, total_length) == 0) {
|
||||
spi_out_log_cb_write(log_cb, addr, (uint16_t)len, addr_append, (uint16_t)len_append, source);
|
||||
if (in_isr) {
|
||||
spi_out_log_cb_write_packet_loss(log_cb, SPI_OUT_PACKET_LOSS_LL_ISR);
|
||||
} else {
|
||||
spi_out_log_cb_append_trans(ll_isr_log_cb);
|
||||
spi_out_log_cb_append_trans(ll_task_log_cb);
|
||||
spi_out_log_cb_write_packet_loss(log_cb, SPI_OUT_PACKET_LOSS_LL_TASK);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
IRAM_ATTR void ble_log_spi_out_ll_log_ev_proc(void)
|
||||
{
|
||||
if (!ll_log_inited) {
|
||||
return;
|
||||
}
|
||||
return spi_out_ll_log_ev_proc();
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
int ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len)
|
||||
{
|
||||
if (!ul_log_inited) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
xSemaphoreTake(ul_log_mutex, portMAX_DELAY);
|
||||
if (spi_out_log_cb_check_trans(ul_log_cb, len) == 0) {
|
||||
spi_out_log_cb_write(ul_log_cb, addr, len, NULL, 0, source);
|
||||
spi_out_log_cb_append_trans(ul_log_cb);
|
||||
|
||||
spi_out_log_cb_write_packet_loss(ul_log_cb, SPI_OUT_PACKET_LOSS_UL);
|
||||
}
|
||||
xSemaphoreGive(ul_log_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_log_spi_out_printf(uint8_t source, const char *format, ...)
|
||||
{
|
||||
if (!ul_log_inited) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get arguments
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
// Get len as ref to allocate heap memory
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int len = vsnprintf(NULL, 0, format, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
// Length validation
|
||||
if ((len < 0) || (len > 0xFFFF)) {
|
||||
va_end(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allocate memory
|
||||
uint8_t *buffer = malloc(len + 1);
|
||||
if (!buffer) {
|
||||
va_end(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Generate string
|
||||
vsnprintf((char *)buffer, len + 1, format, args);
|
||||
va_end(args);
|
||||
|
||||
uint32_t esp_ts = esp_timer_get_time();
|
||||
xSemaphoreTake(ul_log_mutex, portMAX_DELAY);
|
||||
if (spi_out_log_cb_check_trans(ul_log_cb, sizeof(uint32_t) + len) == 0) {
|
||||
spi_out_log_cb_write(ul_log_cb, (const uint8_t *)&esp_ts, sizeof(uint32_t), (const uint8_t *)buffer, len, source);
|
||||
spi_out_log_cb_append_trans(ul_log_cb);
|
||||
|
||||
spi_out_log_cb_write_packet_loss(ul_log_cb, SPI_OUT_PACKET_LOSS_UL);
|
||||
}
|
||||
xSemaphoreGive(ul_log_mutex);
|
||||
|
||||
// Release
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...)
|
||||
{
|
||||
if (!ul_log_inited) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create log prefix in the format: "[level][tag] "
|
||||
char prefix[32];
|
||||
int prefix_len = snprintf(prefix, sizeof(prefix), "[%d][%s] ", level, tag ? tag : "NULL");
|
||||
|
||||
// Compute the length of the formatted log message
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int log_len = vsnprintf(NULL, 0, format, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
// Validate length
|
||||
if (log_len < 0 || log_len > 0xFFFF) {
|
||||
va_end(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compute total log length (prefix + formatted message)
|
||||
int total_len = prefix_len + log_len;
|
||||
|
||||
// Allocate memory for the complete log message
|
||||
uint8_t *buffer = malloc(total_len + 1);
|
||||
if (!buffer) {
|
||||
va_end(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Construct the final log message
|
||||
memcpy(buffer, prefix, prefix_len); // Copy the prefix
|
||||
vsnprintf((char *)(buffer + prefix_len), log_len + 1, format, args);
|
||||
va_end(args);
|
||||
|
||||
uint32_t esp_ts = esp_timer_get_time();
|
||||
xSemaphoreTake(ul_log_mutex, portMAX_DELAY);
|
||||
if (spi_out_log_cb_check_trans(ul_log_cb, sizeof(uint32_t) + total_len) == 0) {
|
||||
spi_out_log_cb_write(ul_log_cb, (const uint8_t *)&esp_ts, sizeof(uint32_t), (const uint8_t *)buffer, total_len, source);
|
||||
spi_out_log_cb_append_trans(ul_log_cb);
|
||||
|
||||
spi_out_log_cb_write_packet_loss(ul_log_cb, SPI_OUT_PACKET_LOSS_UL);
|
||||
}
|
||||
xSemaphoreGive(ul_log_mutex);
|
||||
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len)
|
||||
{
|
||||
if (!ul_log_inited) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t esp_ts = esp_timer_get_time();
|
||||
xSemaphoreTake(ul_log_mutex, portMAX_DELAY);
|
||||
if (spi_out_log_cb_check_trans(ul_log_cb, sizeof(uint32_t) + len) == 0) {
|
||||
spi_out_log_cb_write(ul_log_cb, (const uint8_t *)&esp_ts, sizeof(uint32_t), addr, len, source);
|
||||
spi_out_log_cb_append_trans(ul_log_cb);
|
||||
|
||||
spi_out_log_cb_write_packet_loss(ul_log_cb, SPI_OUT_PACKET_LOSS_UL);
|
||||
}
|
||||
xSemaphoreGive(ul_log_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ble_log_spi_out_dump_all(void)
|
||||
{
|
||||
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
portENTER_CRITICAL_SAFE(&spinlock);
|
||||
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
if (ll_log_inited) {
|
||||
// Dump lower layer log buffer
|
||||
esp_rom_printf("[LL_ISR_LOG_DUMP_START:\n");
|
||||
spi_out_log_cb_dump(ll_isr_log_cb);
|
||||
esp_rom_printf("\n:LL_ISR_LOG_DUMP_END]\n\n");
|
||||
|
||||
esp_rom_printf("[LL_TASK_LOG_DUMP_START:\n");
|
||||
spi_out_log_cb_dump(ll_task_log_cb);
|
||||
esp_rom_printf("\n:LL_TASK_LOG_DUMP_END]\n\n");
|
||||
}
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED
|
||||
|
||||
if (ul_log_inited) {
|
||||
// Dump upper layer log buffer
|
||||
esp_rom_printf("[UL_LOG_DUMP_START:\n");
|
||||
spi_out_log_cb_dump(ul_log_cb);
|
||||
esp_rom_printf("\n:UL_LOG_DUMP_END]\n\n");
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&spinlock);
|
||||
}
|
||||
|
||||
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef __BT_SPI_OUT_H__
|
||||
#define __BT_SPI_OUT_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
// Public typedefs
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_ESP 0
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY 1
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_BLUEDROID 2
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_NIMBLE 3
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM 4
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM 5
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_ESP_ISR 6
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY_ISR 7
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_USER 0x10
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_SYNC 0xFE
|
||||
#define BLE_LOG_SPI_OUT_SOURCE_LOSS 0xFF
|
||||
|
||||
// SPI Log Level Definitions
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_NONE 0 /*!< No log output */
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_ERROR 1 /*!< Critical errors that SPI driver cannot recover from */
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_WARN 2 /*!< Recoverable error conditions in SPI communication */
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_INFO 3 /*!< Informational messages about SPI transactions */
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_DEBUG 4 /*!< Detailed debug information, such as SPI register values */
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_VERBOSE 5 /*!< Very detailed debugging logs, potentially flooding output */
|
||||
#define BLE_LOG_SPI_OUT_LEVEL_MAX 6 /*!< Number of SPI log levels supported */
|
||||
|
||||
// Public functions
|
||||
int ble_log_spi_out_init(void);
|
||||
void ble_log_spi_out_deinit(void);
|
||||
void ble_log_spi_out_timer_control(bool enable);
|
||||
int ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len);
|
||||
void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,\
|
||||
const uint8_t *addr_append, uint32_t flag);
|
||||
void ble_log_spi_out_ll_log_ev_proc(void);
|
||||
void ble_log_spi_out_ts_sync_start(void);
|
||||
void ble_log_spi_out_ts_sync_stop(void);
|
||||
int ble_log_spi_out_printf(uint8_t source, const char *format, ...);
|
||||
int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...);
|
||||
int ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len);
|
||||
void ble_log_spi_out_dump_all(void);
|
||||
|
||||
#endif // __BT_SPI_OUT_H__
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -16,12 +16,6 @@ void **btc_profile_cb_tab;
|
||||
|
||||
void esp_profile_cb_reset(void)
|
||||
{
|
||||
#if BTC_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_profile_cb_tab == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTC_PID_NUM; i++) {
|
||||
@@ -31,12 +25,6 @@ void esp_profile_cb_reset(void)
|
||||
|
||||
int btc_profile_cb_set(btc_pid_t profile_id, void *cb)
|
||||
{
|
||||
#if BTC_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_profile_cb_tab == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (profile_id < 0 || profile_id >= BTC_PID_NUM) {
|
||||
return -1;
|
||||
}
|
||||
@@ -48,12 +36,6 @@ int btc_profile_cb_set(btc_pid_t profile_id, void *cb)
|
||||
|
||||
void *btc_profile_cb_get(btc_pid_t profile_id)
|
||||
{
|
||||
#if BTC_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_profile_cb_tab == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (profile_id < 0 || profile_id >= BTC_PID_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -210,12 +210,24 @@ static void btc_thread_handler(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg->arg) {
|
||||
osi_free(msg->arg);
|
||||
}
|
||||
osi_free(msg);
|
||||
}
|
||||
|
||||
static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout)
|
||||
{
|
||||
if (osi_thread_post(btc_thread, btc_thread_handler, msg, 0, timeout) == false) {
|
||||
btc_msg_t *lmsg;
|
||||
|
||||
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t));
|
||||
if (lmsg == NULL) {
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
memcpy(lmsg, msg, sizeof(btc_msg_t));
|
||||
|
||||
if (osi_thread_post(btc_thread, btc_thread_handler, lmsg, 0, timeout) == false) {
|
||||
return BT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
@@ -225,64 +237,55 @@ static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout)
|
||||
/**
|
||||
* transfer an message to another module in the different task.
|
||||
* @param msg message
|
||||
* @param arg parameter
|
||||
* @param arg_len length of parameter
|
||||
* @param arg paramter
|
||||
* @param arg_len length of paramter
|
||||
* @param copy_func deep copy function
|
||||
* @param free_func deep free function
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func,
|
||||
btc_arg_deep_free_t free_func)
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
|
||||
{
|
||||
btc_msg_t* lmsg;
|
||||
bt_status_t ret;
|
||||
// arg XOR arg_len
|
||||
if ((msg == NULL) || ((arg == NULL) == !(arg_len == 0))) {
|
||||
BTC_TRACE_WARNING("%s Invalid parameters\n", __func__);
|
||||
btc_msg_t lmsg;
|
||||
|
||||
if (msg == NULL) {
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
}
|
||||
|
||||
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
|
||||
|
||||
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t) + arg_len);
|
||||
if (lmsg == NULL) {
|
||||
BTC_TRACE_WARNING("%s No memory\n", __func__);
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
memcpy(lmsg, msg, sizeof(btc_msg_t));
|
||||
memcpy(&lmsg, msg, sizeof(btc_msg_t));
|
||||
if (arg) {
|
||||
memset(lmsg->arg, 0x00, arg_len); //important, avoid arg which have no length
|
||||
memcpy(lmsg->arg, arg, arg_len);
|
||||
lmsg.arg = (void *)osi_malloc(arg_len);
|
||||
if (lmsg.arg == NULL) {
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
memset(lmsg.arg, 0x00, arg_len); //important, avoid arg which have no length
|
||||
memcpy(lmsg.arg, arg, arg_len);
|
||||
if (copy_func) {
|
||||
copy_func(lmsg, lmsg->arg, arg);
|
||||
copy_func(&lmsg, lmsg.arg, arg);
|
||||
}
|
||||
} else {
|
||||
lmsg.arg = NULL;
|
||||
}
|
||||
|
||||
ret = btc_task_post(lmsg, OSI_THREAD_MAX_TIMEOUT);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
if (copy_func && free_func) {
|
||||
free_func(lmsg);
|
||||
}
|
||||
osi_free(lmsg);
|
||||
}
|
||||
return btc_task_post(&lmsg, OSI_THREAD_MAX_TIMEOUT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer an message to another module in the same task.
|
||||
* transfer an message to another module in tha same task.
|
||||
* @param msg message
|
||||
* @param arg paramter
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_inter_profile_call(btc_msg_t *msg)
|
||||
bt_status_t btc_inter_profile_call(btc_msg_t *msg, void *arg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
}
|
||||
|
||||
msg->arg = arg;
|
||||
switch (msg->sig) {
|
||||
case BTC_SIG_API_CALL:
|
||||
profile_tab[msg->pid].btc_call(msg);
|
||||
@@ -310,7 +313,7 @@ static void btc_deinit_mem(void) {
|
||||
btc_profile_cb_tab = NULL;
|
||||
}
|
||||
|
||||
#if (BLE_42_FEATURE_SUPPORT == TRUE)
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
if (gl_bta_adv_data_ptr) {
|
||||
osi_free(gl_bta_adv_data_ptr);
|
||||
gl_bta_adv_data_ptr = NULL;
|
||||
@@ -320,7 +323,7 @@ static void btc_deinit_mem(void) {
|
||||
osi_free(gl_bta_scan_rsp_data_ptr);
|
||||
gl_bta_scan_rsp_data_ptr = NULL;
|
||||
}
|
||||
#endif // BLE_42_FEATURE_SUPPORT
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
|
||||
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_creat_tab_env_ptr) {
|
||||
@@ -335,13 +338,6 @@ static void btc_deinit_mem(void) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BTC_HF_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||
if (hf_local_param_ptr) {
|
||||
osi_free(hf_local_param_ptr);
|
||||
hf_local_param_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||
if (hf_client_local_param_ptr) {
|
||||
osi_free(hf_client_local_param_ptr);
|
||||
@@ -372,8 +368,7 @@ static bt_status_t btc_init_mem(void) {
|
||||
}
|
||||
memset((void *)btc_profile_cb_tab, 0, sizeof(void *) * BTC_PID_NUM);
|
||||
|
||||
#if BTC_DYNAMIC_MEMORY == TRUE
|
||||
#if (BLE_42_FEATURE_SUPPORT == TRUE)
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
if ((gl_bta_adv_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
@@ -383,8 +378,7 @@ static bt_status_t btc_init_mem(void) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)gl_bta_scan_rsp_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
|
||||
#endif // (BLE_42_FEATURE_SUPPORT == TRUE)
|
||||
#endif // BTC_DYNAMIC_MEMORY == TRUE
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
|
||||
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
|
||||
if ((btc_creat_tab_env_ptr = (esp_btc_creat_tab_t *)osi_malloc(sizeof(esp_btc_creat_tab_t))) == NULL) {
|
||||
@@ -399,13 +393,6 @@ static bt_status_t btc_init_mem(void) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BTC_HF_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||
if ((hf_local_param_ptr = (hf_local_param_t *)osi_malloc(BTC_HF_NUM_CB * sizeof(hf_local_param_t))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)hf_local_param_ptr, 0, BTC_HF_NUM_CB * sizeof(hf_local_param_t));
|
||||
#endif
|
||||
|
||||
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||
if ((hf_client_local_param_ptr = (hf_client_local_param_t *)osi_malloc(sizeof(hf_client_local_param_t))) == NULL) {
|
||||
goto error_exit;
|
||||
|
||||
@@ -20,7 +20,7 @@ typedef struct btc_msg {
|
||||
uint8_t aid; //application id
|
||||
uint8_t pid; //profile id
|
||||
uint8_t act; //profile action, defined in seprerate header files
|
||||
UINT8 arg[0]; //param for btc function or function param
|
||||
void *arg; //param for btc function or function param
|
||||
} btc_msg_t;
|
||||
|
||||
typedef struct btc_adv_packet {
|
||||
@@ -94,7 +94,6 @@ typedef struct {
|
||||
} btc_func_t;
|
||||
|
||||
typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src);
|
||||
typedef void (* btc_arg_deep_free_t)(btc_msg_t *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -106,20 +105,19 @@ extern "C" {
|
||||
* @param arg paramter
|
||||
* @param arg_len length of paramter
|
||||
* @param copy_func deep copy function
|
||||
* @param free_func deep free function
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func,
|
||||
btc_arg_deep_free_t free_func);
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func);
|
||||
|
||||
/**
|
||||
* transfer an message to another module in tha same task.
|
||||
* @param msg message
|
||||
* @param arg paramter
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_inter_profile_call(btc_msg_t *msg);
|
||||
bt_status_t btc_inter_profile_call(btc_msg_t *msg, void *arg);
|
||||
|
||||
bt_status_t btc_init(void);
|
||||
void btc_deinit(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -144,7 +144,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
msg.act = ESP_BLUFI_EVENT_DEINIT_FINISH;
|
||||
param.deinit_finish.state = ESP_BLUFI_DEINIT_OK;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -160,31 +160,20 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
if (p_data->req_data.p_data->write_req.is_prep) {
|
||||
tBTA_GATT_STATUS status = GATT_SUCCESS;
|
||||
|
||||
do {
|
||||
if (p_data->req_data.p_data->write_req.offset > BLUFI_PREPARE_BUF_MAX_SIZE) {
|
||||
status = ESP_GATT_INVALID_OFFSET;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((p_data->req_data.p_data->write_req.offset + p_data->req_data.p_data->write_req.len) > BLUFI_PREPARE_BUF_MAX_SIZE) {
|
||||
status = ESP_GATT_INVALID_ATTR_LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (blufi_env.prepare_buf == NULL) {
|
||||
blufi_env.prepare_buf = osi_malloc(BLUFI_PREPAIR_BUF_MAX_SIZE);
|
||||
blufi_env.prepare_len = 0;
|
||||
if (blufi_env.prepare_buf == NULL) {
|
||||
if (p_data->req_data.p_data->write_req.offset != 0) {
|
||||
status = GATT_INVALID_OFFSET;
|
||||
break;
|
||||
}
|
||||
blufi_env.prepare_buf = osi_malloc(BLUFI_PREPARE_BUF_MAX_SIZE);
|
||||
blufi_env.prepare_len = 0;
|
||||
if (blufi_env.prepare_buf == NULL) {
|
||||
BLUFI_TRACE_ERROR("Blufi prep no mem\n");
|
||||
status = GATT_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
BLUFI_TRACE_ERROR("Blufi prep no mem\n");
|
||||
status = GATT_NO_RESOURCES;
|
||||
}
|
||||
} while (0);
|
||||
} else {
|
||||
if (p_data->req_data.p_data->write_req.offset > BLUFI_PREPAIR_BUF_MAX_SIZE) {
|
||||
status = GATT_INVALID_OFFSET;
|
||||
} else if ((p_data->req_data.p_data->write_req.offset + p_data->req_data.p_data->write_req.len) > BLUFI_PREPAIR_BUF_MAX_SIZE) {
|
||||
status = GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&rsp, 0, sizeof(tGATTS_RSP));
|
||||
rsp.attr_value.handle = p_data->req_data.p_data->write_req.handle;
|
||||
@@ -294,7 +283,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
msg.act = ESP_BLUFI_EVENT_INIT_FINISH;
|
||||
param.init_finish.state = ESP_BLUFI_INIT_OK;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_CONNECT_EVT: {
|
||||
@@ -318,7 +307,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
param.connect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);
|
||||
conn_id = param.connect.conn_id;
|
||||
server_if = p_data->conn.server_if;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_DISCONNECT_EVT: {
|
||||
@@ -346,7 +335,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT;
|
||||
memcpy(param.disconnect.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_OPEN_EVT:
|
||||
@@ -396,6 +385,8 @@ void esp_blufi_send_encap(void *arg)
|
||||
retry:
|
||||
if (blufi_env.is_connected == false) {
|
||||
BTC_TRACE_WARNING("%s ble connection is broken\n", __func__);
|
||||
osi_free(hdr);
|
||||
hdr = NULL;
|
||||
return;
|
||||
}
|
||||
if (esp_ble_get_cur_sendable_packets_num(BTC_GATT_GET_CONN_ID(blufi_env.conn_id)) > 0) {
|
||||
@@ -419,7 +410,7 @@ esp_err_t esp_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CLOSE;
|
||||
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL)
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -90,34 +90,12 @@ void btc_blufi_report_error(esp_blufi_error_state_t state)
|
||||
msg.act = ESP_BLUFI_EVENT_REPORT_ERROR;
|
||||
esp_blufi_cb_param_t param;
|
||||
param.report_error.state = state;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
}
|
||||
|
||||
void btc_blufi_recv_handler(uint8_t *data, int len)
|
||||
{
|
||||
if (len < sizeof(struct blufi_hdr)) {
|
||||
BTC_TRACE_ERROR("%s invalid data length: %d", __func__, len);
|
||||
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
struct blufi_hdr *hdr = (struct blufi_hdr *)data;
|
||||
|
||||
// Verify if the received data length matches the expected length based on the BLUFI protocol
|
||||
int target_data_len;
|
||||
|
||||
if (BLUFI_FC_IS_CHECK(hdr->fc)) {
|
||||
target_data_len = hdr->data_len + 4 + 2; // Data + (Type + Frame Control + Sequence Number + Data Length) + Checksum
|
||||
} else {
|
||||
target_data_len = hdr->data_len + 4; // Data + (Type + Frame Control + Sequence Number + Data Length)
|
||||
}
|
||||
|
||||
if (len != target_data_len) {
|
||||
BTC_TRACE_ERROR("%s: Invalid data length: %d, expected: %d", __func__, len, target_data_len);
|
||||
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t checksum, checksum_pkt;
|
||||
int ret;
|
||||
|
||||
@@ -158,16 +136,6 @@ void btc_blufi_recv_handler(uint8_t *data, int len)
|
||||
|
||||
if (BLUFI_FC_IS_FRAG(hdr->fc)) {
|
||||
if (blufi_env.offset == 0) {
|
||||
/*
|
||||
blufi_env.aggr_buf should be NULL if blufi_env.offset is 0.
|
||||
It is possible that the process of sending fragment packet
|
||||
has not been completed
|
||||
*/
|
||||
if (blufi_env.aggr_buf) {
|
||||
BTC_TRACE_ERROR("%s msg error, blufi_env.aggr_buf is not freed\n", __func__);
|
||||
btc_blufi_report_error(ESP_BLUFI_MSG_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
blufi_env.total_len = hdr->data[0] | (((uint16_t) hdr->data[1]) << 8);
|
||||
blufi_env.aggr_buf = osi_malloc(blufi_env.total_len);
|
||||
if (blufi_env.aggr_buf == NULL) {
|
||||
@@ -187,18 +155,6 @@ void btc_blufi_recv_handler(uint8_t *data, int len)
|
||||
|
||||
} else {
|
||||
if (blufi_env.offset > 0) { /* if previous pkt is frag */
|
||||
/* blufi_env.aggr_buf should not be NULL */
|
||||
if (blufi_env.aggr_buf == NULL) {
|
||||
BTC_TRACE_ERROR("%s buffer is NULL\n", __func__);
|
||||
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
|
||||
return;
|
||||
}
|
||||
/* payload length should be equal to total_len */
|
||||
if ((blufi_env.offset + hdr->data_len) != blufi_env.total_len) {
|
||||
BTC_TRACE_ERROR("%s payload is longer than packet length, len %d \n", __func__, blufi_env.total_len);
|
||||
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
|
||||
return;
|
||||
}
|
||||
memcpy(blufi_env.aggr_buf + blufi_env.offset, hdr->data, hdr->data_len);
|
||||
|
||||
btc_blufi_protocol_handler(hdr->type, blufi_env.aggr_buf, blufi_env.total_len);
|
||||
@@ -357,21 +313,6 @@ static void btc_blufi_wifi_conn_report(uint8_t opmode, uint8_t sta_conn_state, u
|
||||
*p++ = 1;
|
||||
*p++ = info->softap_channel;
|
||||
}
|
||||
if (info->sta_max_conn_retry_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY;
|
||||
*p++ = 1;
|
||||
*p++ = info->sta_max_conn_retry;
|
||||
}
|
||||
if (info->sta_conn_end_reason_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON;
|
||||
*p++ = 1;
|
||||
*p++ = info->sta_conn_end_reason;
|
||||
}
|
||||
if (info->sta_conn_rssi_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI;
|
||||
*p++ = 1;
|
||||
*p++ = info->sta_conn_rssi;
|
||||
}
|
||||
}
|
||||
if (p - data > data_len) {
|
||||
BTC_TRACE_ERROR("%s len error %d %d\n", __func__, (int)(p - data), data_len);
|
||||
@@ -388,7 +329,7 @@ void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
|
||||
int data_len;
|
||||
uint8_t *p;
|
||||
// malloc size: (len + RSSI + ssid buffer) * apCount;
|
||||
uint32_t malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount;
|
||||
uint malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount;
|
||||
p = data = osi_malloc(malloc_size);
|
||||
if (data == NULL) {
|
||||
BTC_TRACE_ERROR("malloc error\n");
|
||||
@@ -397,7 +338,7 @@ void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
|
||||
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST);
|
||||
for (int i = 0; i < apCount; ++i)
|
||||
{
|
||||
uint32_t len = strlen((const char *)list[i].ssid);
|
||||
uint len = strlen((const char *)list[i].ssid);
|
||||
data_len = (p - data);
|
||||
//current_len + ssid + rssi + total_len_value
|
||||
if((data_len + len + 1 + 1) > malloc_size) {
|
||||
@@ -765,21 +706,6 @@ void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
dst->wifi_conn_report.extra_info->softap_channel = src_info->softap_channel;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->sta_max_conn_retry_set) {
|
||||
dst->wifi_conn_report.extra_info->sta_max_conn_retry_set = src_info->sta_max_conn_retry_set;
|
||||
dst->wifi_conn_report.extra_info->sta_max_conn_retry = src_info->sta_max_conn_retry;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->sta_conn_end_reason_set) {
|
||||
dst->wifi_conn_report.extra_info->sta_conn_end_reason_set = src_info->sta_conn_end_reason_set;
|
||||
dst->wifi_conn_report.extra_info->sta_conn_end_reason = src_info->sta_conn_end_reason;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->sta_conn_rssi_set) {
|
||||
dst->wifi_conn_report.extra_info->sta_conn_rssi_set = src_info->sta_conn_rssi_set;
|
||||
dst->wifi_conn_report.extra_info->sta_conn_rssi = src_info->sta_conn_rssi;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
|
||||
|
||||
@@ -42,35 +42,35 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.act = ESP_BLUFI_EVENT_SET_WIFI_OPMODE;
|
||||
param.wifi_mode.op_mode = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_GET_WIFI_STATUS;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_DEAUTHENTICATE_STA;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL,NULL);
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION: {
|
||||
uint8_t type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION);
|
||||
@@ -85,13 +85,13 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_GET_WIFI_LIST;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type);
|
||||
@@ -116,7 +116,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_STA_BSSID;
|
||||
memcpy(param.sta_bssid.bssid, &data[0], 6);
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_STA_SSID:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -125,7 +125,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.sta_ssid.ssid = &data[0];
|
||||
param.sta_ssid.ssid_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -134,7 +134,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.sta_passwd.passwd = &data[0];
|
||||
param.sta_passwd.passwd_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -143,7 +143,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.softap_ssid.ssid = &data[0];
|
||||
param.softap_ssid.ssid_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -152,7 +152,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.softap_passwd.passwd = &data[0];
|
||||
param.softap_passwd.passwd_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -160,7 +160,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM;
|
||||
param.softap_max_conn_num.max_conn_num = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -168,7 +168,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE;
|
||||
param.softap_auth_mode.auth_mode = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -176,7 +176,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL;
|
||||
param.softap_channel.channel = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_USERNAME:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -185,7 +185,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.username.name = &data[0];
|
||||
param.username.name_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CA:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -194,7 +194,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.ca.cert = &data[0];
|
||||
param.ca.cert_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -203,7 +203,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.client_cert.cert = &data[0];
|
||||
param.client_cert.cert_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -212,7 +212,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.client_cert.cert = &data[0];
|
||||
param.client_cert.cert_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -221,7 +221,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.client_pkey.pkey = &data[0];
|
||||
param.client_pkey.pkey_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -230,7 +230,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
param.client_pkey.pkey = &data[0];
|
||||
param.client_pkey.pkey_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
@@ -238,7 +238,7 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_CUSTOM_DATA;
|
||||
param.custom_data.data = &data[0];
|
||||
param.custom_data.data_len = len;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user