Compare commits

..

1 Commits

Author SHA1 Message Date
Wei Yuhan
d9ad0ad50b change(version): Update version to 6.0.0 2025-11-05 16:25:23 +08:00
2716 changed files with 46555 additions and 492173 deletions

View File

@@ -26,7 +26,7 @@ body:
id: chip_revision
attributes:
label: Espressif SoC revision.
description: On which Espressif SoC revision does your application run on? Run `esptool chip-id` (or `esptool.py chip_id` for ESP-IDF v5.5 and older) to find it.
description: On which Espressif SoC revision does your application run on? Run `esptool chip-id` to find it.
placeholder: ex. ESP32-C3 (QFN32) (revision v0.3)
validations:
required: true

View File

@@ -16,17 +16,18 @@ workflow:
# Place the default settings in `.gitlab/ci/common.yml` instead
include:
- ".gitlab/ci/danger.yml"
- ".gitlab/ci/common.yml"
- ".gitlab/ci/rules.yml"
- ".gitlab/ci/upload_cache.yml"
- ".gitlab/ci/docs.yml"
- ".gitlab/ci/static-code-analysis.yml"
- ".gitlab/ci/pre_commit.yml"
- ".gitlab/ci/pre_check.yml"
- ".gitlab/ci/build.yml"
- ".gitlab/ci/integration_test.yml"
- ".gitlab/ci/host-test.yml"
- ".gitlab/ci/deploy.yml"
- ".gitlab/ci/post_deploy.yml"
- ".gitlab/ci/test-win.yml"
- '.gitlab/ci/danger.yml'
- '.gitlab/ci/common.yml'
- '.gitlab/ci/rules.yml'
- '.gitlab/ci/upload_cache.yml'
- '.gitlab/ci/docs.yml'
- '.gitlab/ci/static-code-analysis.yml'
- '.gitlab/ci/pre_commit.yml'
- '.gitlab/ci/pre_check.yml'
- '.gitlab/ci/build.yml'
- '.gitlab/ci/integration_test.yml'
- '.gitlab/ci/host-test.yml'
- '.gitlab/ci/deploy.yml'
- '.gitlab/ci/post_deploy.yml'
- '.gitlab/ci/retry_failed_jobs.yml'
- '.gitlab/ci/test-win.yml'

View File

@@ -122,7 +122,6 @@
/components/esp_tee/ @esp-idf-codeowners/security
/components/esp_timer/ @esp-idf-codeowners/system
/components/esp-tls/ @esp-idf-codeowners/app-utilities
/components/esp_trace/ @esp-idf-codeowners/debugging
/components/esp_usb_cdc_rom_console/ @esp-idf-codeowners/system @esp-idf-codeowners/peripherals/usb
/components/esp_wifi/ @esp-idf-codeowners/wifi
/components/espcoredump/ @esp-idf-codeowners/debugging
@@ -166,7 +165,6 @@
/docs/ @esp-idf-codeowners/docs
/docs/docs_not_updated/ @esp-idf-codeowners/all-maintainers
/docs/**/api-guides/tools/ @esp-idf-codeowners/tools
/docs/**/api-guides/kconfig/ @esp-idf-codeowners/tools
/docs/en/api-guides/core_dump.rst @esp-idf-codeowners/debugging
/docs/**/api-guides/wifi* @esp-idf-codeowners/wifi
/docs/**/api-guides/esp-wifi-mesh.rst @esp-idf-codeowners/wifi
@@ -215,7 +213,6 @@
/tools/ci/ @esp-idf-codeowners/ci
/tools/cmake/ @esp-idf-codeowners/build-config
/tools/cmake/toolchain-*.cmake @esp-idf-codeowners/toolchain
/tools/cmakev2/ @esp-idf-codeowners/build-config
/tools/esp_app_trace/ @esp-idf-codeowners/debugging
/tools/gdb_panic_server.py @esp-idf-codeowners/debugging
/tools/kconfig*/ @esp-idf-codeowners/build-config

View File

@@ -1,66 +1,20 @@
.build_template:
stage: build
extends:
- .before_script:build
- .after_script:build
- .after_script:build:ccache-show-stats:upload-failed-job-logs
image: $ESP_ENV_IMAGE
tags: [build, shiny]
variables:
# Enable ccache for all build jobs. See configure_ci_environment.sh for more ccache related settings.
IDF_CCACHE_ENABLE: "1"
dependencies: # set dependencies to null to avoid missing artifacts issue
dependencies: []
######################
# build_template_app #
######################
.build_template_app_template:
extends:
- .build_template
artifacts:
paths:
- log_template_app/*
- size_info.txt
- build_template_app/**/size*.json
expire_in: 1 week
when: always
script:
# Set the variable for 'esp-idf-template' testing
- ESP_IDF_TEMPLATE_GIT=${ESP_IDF_TEMPLATE_GIT:-"https://github.com/espressif/esp-idf-template.git"}
- retry_failed git clone ${ESP_IDF_TEMPLATE_GIT}
# Try to use the same branch name for esp-idf-template that we're
# using on esp-idf. If it doesn't exist then just stick to the default branch
- python $CHECKOUT_REF_SCRIPT esp-idf-template esp-idf-template
- export PATH="$IDF_PATH/tools:$PATH"
# Only do the default cmake build for each target, remaining part are done in the build_template_app job
- tools/ci/build_template_app.sh ${BUILD_COMMAND_ARGS}
# Build at least one project for each target at earliest stage to reduce build cost for obvious failing commits
fast_template_app:
extends:
- .build_template_app_template
- .rules:build
stage: pre_check
tags: [fast_run, shiny]
variables:
BUILD_COMMAND_ARGS: "-p"
# This job builds template app with permutations of targets and optimization levels
build_template_app:
extends:
- .build_template_app_template
- .rules:build
stage: host_test
needs:
- job: fast_template_app
artifacts: false
########################################
# Clang Build Apps Without Tests Cases #
########################################
.build_cmake_clang_template:
extends:
- .build_template
- .rules:build
- .before_script:build
- .after_script:build:ccache-show-stats
dependencies: # set dependencies to null to avoid missing artifacts issue
needs:
- job: fast_template_app
artifacts: false
@@ -74,7 +28,7 @@ build_template_app:
- "**/build*/build_log.txt"
# keep the size info to help track the binary size
- size_info.txt
- "**/build*/size*.json"
- "**/build*/size.json"
expire_in: 1 week
when: always
variables:
@@ -91,14 +45,92 @@ build_template_app:
--modified-files ${MR_MODIFIED_FILES}
$TEST_BUILD_OPTS_EXTRA
build_clang_test_apps_xtensa:
extends: .build_cmake_clang_template
parallel:
matrix:
- IDF_TARGET: [esp32, esp32s2, esp32s3]
######################
# build_template_app #
######################
.build_template_app_template:
extends:
- .build_template
- .before_script:build
variables:
LOG_PATH: "${CI_PROJECT_DIR}/log_template_app"
BUILD_PATH: "${CI_PROJECT_DIR}/build_template_app"
BUILD_DIR: "${BUILD_PATH}/@t/@w"
BUILD_LOG_CMAKE: "${LOG_PATH}/cmake_@t_@w.txt"
BUILD_COMMAND_ARGS: ""
artifacts:
paths:
- log_template_app/*
- size_info.txt
- build_template_app/**/size.json
expire_in: 1 week
when: always
script:
# Set the variable for 'esp-idf-template' testing
- ESP_IDF_TEMPLATE_GIT=${ESP_IDF_TEMPLATE_GIT:-"https://github.com/espressif/esp-idf-template.git"}
- retry_failed git clone ${ESP_IDF_TEMPLATE_GIT}
# Try to use the same branch name for esp-idf-template that we're
# using on esp-idf. If it doesn't exist then just stick to the default branch
- python $CHECKOUT_REF_SCRIPT esp-idf-template esp-idf-template
- export PATH="$IDF_PATH/tools:$PATH"
# Only do the default cmake build for each target, remaining part are done in the build_template_app job
- tools/ci/build_template_app.sh ${BUILD_COMMAND_ARGS}
build_clang_test_apps_riscv:
extends: .build_cmake_clang_template
# build-related-pre-check-jobs ------------------------------------------------
# Build at least one project for each target at earliest stage to reduce build cost for obvious failing commits
fast_template_app:
extends:
- .build_template_app_template
- .rules:build:target_test
stage: pre_check
tags: [fast_run, shiny]
variables:
BUILD_COMMAND_ARGS: "-p"
#------------------------------------------------------------------------------
#######################
# gnu_static_analyzer #
#######################
gcc_static_analyzer:
extends:
- .build_template_app_template
- .rules:build:target_test
stage: pre_check
tags: [build, shiny]
variables:
CI_CCACHE_DISABLE: 1
ANALYZING_APP: "examples/get-started/hello_world"
script:
- echo "CONFIG_COMPILER_STATIC_ANALYZER=y" >> ${ANALYZING_APP}/sdkconfig.defaults
- idf-build-apps build -p ${ANALYZING_APP}
########################################
# Clang Build Apps Without Tests Cases #
########################################
build_clang_test_apps_esp32:
extends:
- .build_cmake_clang_template
- .rules:build
variables:
IDF_TARGET: esp32
build_clang_test_apps_esp32s2:
extends:
- .build_cmake_clang_template
- .rules:build
variables:
IDF_TARGET: esp32s2
build_clang_test_apps_esp32s3:
extends:
- .build_cmake_clang_template
- .rules:build
variables:
IDF_TARGET: esp32s3
.build_clang_test_apps_riscv:
extends:
- .build_cmake_clang_template
variables:
# https://reviews.llvm.org/D90108.
# GNU 'as' lets .weak override .globl since binutils-gdb
@@ -106,9 +138,173 @@ build_clang_test_apps_riscv:
# while MC lets the last directive win (PR38921).
# For RISCV chips we use integrated assembler by default, so suppress this warning to pass CI pipeline.
TEST_BUILD_OPTS_EXTRA: "--ignore-warning-str 'changed binding to STB_WEAK'"
parallel:
matrix:
- IDF_TARGET: [esp32c3, esp32c2, esp32c6, esp32c5, esp32h2, esp32p4]
build_clang_test_apps_esp32c3:
extends:
- .build_clang_test_apps_riscv
- .rules:build
variables:
IDF_TARGET: esp32c3
build_clang_test_apps_esp32c2:
extends:
- .build_clang_test_apps_riscv
- .rules:build
variables:
IDF_TARGET: esp32c2
build_clang_test_apps_esp32c6:
extends:
- .build_clang_test_apps_riscv
- .rules:build
variables:
IDF_TARGET: esp32c6
build_clang_test_apps_esp32c5:
extends:
- .build_clang_test_apps_riscv
- .rules:build
variables:
IDF_TARGET: esp32c5
build_clang_test_apps_esp32h2:
extends:
- .build_clang_test_apps_riscv
- .rules:build
variables:
IDF_TARGET: esp32h2
build_clang_test_apps_esp32p4:
extends:
- .build_clang_test_apps_riscv
- .rules:build
variables:
IDF_TARGET: esp32p4
######################
# Build System Tests #
######################
.test_build_system_template:
stage: host_test
extends:
- .build_template
- .rules:build:check
dependencies: # set dependencies to null to avoid missing artifacts issue
needs:
- job: fast_template_app
artifacts: false
optional: true
artifacts:
reports:
junit: XUNIT_RESULT.xml
paths:
- XUNIT_RESULT.xml
- test_build_system
expire_in: 1 week
when: always
script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- cd ${IDF_PATH}/tools/test_build_system
- run_cmd idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest
--cleanup-idf-copy
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
--work-dir ${CI_PROJECT_DIR}/test_build_system
--junitxml ${CI_PROJECT_DIR}/XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
.test_build_system_macos_template_extension:
tags:
- macos
variables:
PYENV_VERSION: "3.10"
# CCACHE_DIR: "/cache/idf_ccache". On macOS, you cannot write to this folder due to insufficient permissions.
CCACHE_DIR: "" # ccache will use "$HOME/Library/Caches/ccache".
# Workaround for a bug in Parallels executor where CI_PROJECT_DIR is not an absolute path,
# but a relative path to the build directory (builds/espressif/esp-idf instead of ~/builds/espressif/esp-idf.
# GitLab sets the project dir to this template `<builds_dir>/<namespace>/<project_name>`
IDF_PATH: "/Users/espressif/builds/espressif/esp-idf"
.test_build_system_minimal_cmake_template:
extends: .test_build_system_template
variables:
INSTALL_EXTRA_TOOLS: cmake@3.22.1
script:
- MINIMAL_SUPPORTED_CMAKE_VERSION=$(echo "${INSTALL_EXTRA_TOOLS}" | sed -n 's/.*cmake@\([0-9.]*\).*/\1/p')
- export PATH=$(echo "$PATH" | sed -E "s|/tools/cmake/[0-9.]+|/tools/cmake/${MINIMAL_SUPPORTED_CMAKE_VERSION}|")
- ACTUAL_CMAKE_VERSION=$(cmake --version | head -n1 | awk '{print $3}')
- |
if [ "${ACTUAL_CMAKE_VERSION}" != "${MINIMAL_SUPPORTED_CMAKE_VERSION}" ]; then
echo "ERROR: Wrong minimal CMake version! Detected: ${ACTUAL_CMAKE_VERSION}, but should be: ${MINIMAL_SUPPORTED_CMAKE_VERSION}"
exit 1
fi
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- cd ${IDF_PATH}/tools/test_build_system
- run_cmd idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest
-k cmake
--cleanup-idf-copy
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
--work-dir ${CI_PROJECT_DIR}/test_build_system
--junitxml ${CI_PROJECT_DIR}/XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
pytest_build_system:
extends: .test_build_system_template
parallel: 3
pytest_build_system_macos:
extends:
- .test_build_system_template
- .test_build_system_macos_template_extension
- .before_script:build:macos
- .after_script:build:macos:upload-failed-job-logs:ccache-show-stats
- .rules:build:macos
parallel: 3
pytest_build_system_minimal_cmake:
extends: .test_build_system_minimal_cmake_template
pytest_build_system_macos_minimal_cmake:
extends:
- .test_build_system_minimal_cmake_template
- .test_build_system_macos_template_extension
- .before_script:build:macos
- .after_script:build:macos:upload-failed-job-logs:ccache-show-stats
- .rules:build:macos
variables:
INSTALL_EXTRA_TOOLS: ninja cmake@3.22.1
build_docker:
extends:
- .before_script:minimal
- .rules:build:docker
stage: host_test
needs: []
image: espressif/docker-builder:1
tags: [shiny, dind]
variables:
DOCKER_TMP_IMAGE_NAME: "idf_tmp_image"
script:
- export DOCKER_BUILD_ARGS="--build-arg IDF_CLONE_URL=${CI_REPOSITORY_URL} --build-arg IDF_CLONE_BRANCH_OR_TAG=${CI_COMMIT_REF_NAME} --build-arg IDF_CHECKOUT_REF=${CI_COMMIT_TAG:-$CI_COMMIT_SHA} --build-arg IDF_CLONE_SHALLOW=1 --build-arg IDF_GITHUB_ASSETS=${INTERNAL_GITHUB_ASSETS}"
- docker build --tag ${DOCKER_TMP_IMAGE_NAME} ${DOCKER_BUILD_ARGS} tools/docker/
# We can't mount $PWD/examples/get-started/blink into the container, see https://gitlab.com/gitlab-org/gitlab-ce/issues/41227.
# The workaround mentioned there works, but leaves around directories which need to be cleaned up manually.
# Therefore, build a copy of the example located inside the container.
- docker run --rm --workdir /opt/esp/idf/examples/get-started/blink ${DOCKER_TMP_IMAGE_NAME} idf.py build
# This job builds template app with permutations of targets and optimization levels
build_template_app:
extends:
- .build_template_app_template
- .rules:build
stage: host_test
dependencies: # set dependencies to null to avoid missing artifacts issue
needs:
- job: fast_template_app
artifacts: false
####################
# Dynamic Pipeline #
@@ -130,11 +326,7 @@ generate_build_child_pipeline:
expire_in: 1 week
when: always
script:
- run_cmd idf-ci --debug gitlab build-child-pipeline
-p components
-p examples
-p tools/test_apps
--modified-files $MR_MODIFIED_FILES
- run_cmd python tools/ci/dynamic_pipelines/scripts/generate_build_child_pipeline.py
build_child_pipeline:
stage: build

View File

@@ -12,6 +12,7 @@ stages:
- test_deploy
- deploy
- post_deploy
- retry_failed_jobs
variables:
# System environment
@@ -36,7 +37,7 @@ variables:
GIT_FETCH_EXTRA_FLAGS: "--no-recurse-submodules --prune --prune-tags"
# we're using .cache folder for caches
GIT_CLEAN_FLAGS: -ffdx -e .cache/
LATEST_GIT_TAG: v6.1-dev
LATEST_GIT_TAG: v6.0-beta1
SUBMODULE_FETCH_TOOL: "tools/ci/ci_fetch_submodule.py"
# by default we will fetch all submodules
@@ -51,9 +52,9 @@ variables:
CHECKOUT_REF_SCRIPT: "$CI_PROJECT_DIR/tools/ci/checkout_project_ref.py"
# Docker images
ESP_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-env-v6.1:1"
ESP_IDF_DOC_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-idf-doc-env-v6.1:1-1"
TARGET_TEST_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/target-test-env-v6.1:1"
ESP_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-env-v6.0:3"
ESP_IDF_DOC_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-idf-doc-env-v6.0:2-1"
TARGET_TEST_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/target-test-env-v6.0:2"
SONARQUBE_SCANNER_IMAGE: "${CI_DOCKER_REGISTRY}/sonarqube-scanner:5"
# cache python dependencies
@@ -65,7 +66,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.v6.1.txt"
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v6.0.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.
@@ -121,13 +122,18 @@ variables:
# add extra python packages
export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci:$IDF_PATH/tools/esp_app_trace:$IDF_PATH/components/partition_table:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
# minio configuration
# added here since the precedence of variables in gitlab-ci.yml is lower than project settings
export IDF_S3_SERVER="$IDF_S3_NEW_SERVER"
export IDF_S3_ACCESS_KEY="$IDF_S3_NEW_ACCESS_KEY"
.setup_tools_and_idf_python_venv: &setup_tools_and_idf_python_venv |
# must use after setup_tools_except_target_test
# otherwise the export.sh won't work properly
# 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}"
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
@@ -160,40 +166,20 @@ variables:
section_end "install_python_env"
fi
section_start "source_export" "Source export.sh"
source ./export.sh
section_end "source_export"
# Eager upgrade of CI dependencies
# Done after sourcing export.sh so that we could easily invoke the right pip
section_start "upgrade_ci_dependencies" "Upgrading CI dependencies"
pip install --upgrade --upgrade-strategy=eager -r $IDF_PATH/tools/requirements/requirements.ci.txt -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
if [[ "${CI_JOB_STAGE}" == "target_test" ]]; then
pip install --upgrade --upgrade-strategy=eager -r $IDF_PATH/tools/requirements/requirements.test-specific.txt -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
fi
section_end "upgrade_ci_dependencies"
REEXPORT_NEEDED=0
if [[ ! -z "$INSTALL_EXTRA_TOOLS" ]]; then
section_start "installing_optional_tools" "Install optional tools ${INSTALL_EXTRA_TOOLS}"
run_cmd $IDF_PATH/tools/idf_tools.py --non-interactive install $INSTALL_EXTRA_TOOLS
$IDF_PATH/tools/idf_tools.py --non-interactive install $INSTALL_EXTRA_TOOLS
section_end "installing_optional_tools"
REEXPORT_NEEDED=1
fi
# Install esp-clang if necessary (esp-clang is separately installed)
if [[ "$IDF_TOOLCHAIN" == "clang" && -z "$CI_CLANG_DISTRO_URL" ]]; then
$IDF_PATH/tools/idf_tools.py --non-interactive install esp-clang
REEXPORT_NEEDED=1
fi
if [[ $REEXPORT_NEEDED -eq 1 ]]; then
section_start "re_source_export" "Re-source export.sh"
source ./export.sh
section_end "re_source_export"
fi
section_start "source_export" "Source export.sh"
source ./export.sh
section_end "source_export"
# Custom clang toolchain
if [[ "$IDF_TOOLCHAIN" == "clang" && ! -z "$CI_CLANG_DISTRO_URL" ]]; then
@@ -232,9 +218,7 @@ variables:
.show_ccache_statistics: &show_ccache_statistics |
# Show ccache statistics if enabled globally
section_start "ccache_show_stats" "Show ccache statistics"
test "$CI_CCACHE_STATS" == 1 && test -n "$(which ccache)" && ccache --show-stats -vv || true
section_end "ccache_show_stats"
.upload_failed_job_log_artifacts: &upload_failed_job_log_artifacts |
if [ $CI_JOB_STATUS = "failed" ]; then
@@ -245,6 +229,30 @@ variables:
before_script:
- *common-before_scripts
.before_script:build: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
# remove idf-env.json, since it may contains enabled "features"
- rm -f $IDF_TOOLS_PATH/idf-env.json
# This adds tools (compilers) and the version-specific Python environment to PATH
- *setup_tools_and_idf_python_venv
- fetch_submodules
variables:
INSTALL_EXTRA_TOOLS: cmake ninja
.after_script:build:macos:upload-failed-job-logs:ccache-show-stats:
after_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 -)"
- *upload_failed_job_log_artifacts
- *show_ccache_statistics
.before_script:build:
before_script:
- *common-before_scripts
@@ -254,10 +262,19 @@ variables:
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS}
.after_script:build:
.after_script:build:ccache-show-stats:
after_script:
- source tools/ci/utils.sh
- section_start "ccache_show_stats" "Show ccache statistics"
- *show_ccache_statistics
- section_end "ccache_show_stats"
.after_script:build:ccache-show-stats:upload-failed-job-logs:
after_script:
- source tools/ci/utils.sh
- section_start "ccache_show_stats" "Show ccache statistics"
- *show_ccache_statistics
- section_end "ccache_show_stats"
- *upload_failed_job_log_artifacts
##############################
@@ -296,7 +313,7 @@ variables:
.git_checkout_ci_commit_sha: &git_checkout_ci_commit_sha |
git checkout $CI_COMMIT_SHA
eval "git clean ${GIT_CLEAN_FLAGS}"
git clean ${GIT_CLEAN_FLAGS}
# git diff requires two commits, with different CI env var
#
@@ -355,48 +372,13 @@ variables:
before_script:
- *git_init
- *git_fetch_from_mirror_url_if_exists
- eval "git fetch --depth=1 ${GIT_FETCH_EXTRA_FLAGS} origin ${CI_COMMIT_SHA}"
- git fetch origin "${CI_COMMIT_SHA}" --depth=1 ${GIT_FETCH_EXTRA_FLAGS}
- *git_checkout_ci_commit_sha
- *common-before_scripts
- *setup_tools_and_idf_python_venv
- add_gitlab_ssh_keys
# no submodules
.brew-macos-settings:
variables:
GIT_STRATEGY: none # we do manual git clone to use local mirror
IDF_CCACHE_ENABLE: "0"
CCACHE_DIR: "/var/tmp/cache/idf_ccache"
tags:
- macos-tart
image: macos-sequoia-idf-v6.1
cache: [] # pip cache is created under amd64, and submodules are downloaded with brew mirror, so disable cache here
before_script:
# assert LOCAL_GIT_MIRROR is set
- echo -e "section_start:`date +%s`:check_out\r\e[0Kchecking out from local git mirror, then reset to CI_COMMIT_SHA"
- |
if [ -z "${LOCAL_GIT_MIRROR:-}" ]; then
echo "Error: LOCAL_GIT_MIRROR not set, cannot clone from mirror."
exit 1
fi
- MIRROR_REPO_URL="${LOCAL_GIT_MIRROR}/${CI_PROJECT_PATH}"
- cd "${CI_PROJECT_DIR}"
# since .cache exists in CI_PROJECT_DIR, so can't direct `git clone .`
- git clone -b ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_COMMIT_BRANCH}} --depth=1 --recursive --shallow-submodules "${MIRROR_REPO_URL}" tmp
- mv tmp/.git ./
- rm -rf tmp
- git reset --hard
# set remote url back
- git remote set-url origin "${CI_REPOSITORY_URL}"
- eval "git fetch --depth=1 ${GIT_FETCH_EXTRA_FLAGS} origin ${CI_COMMIT_SHA}"
- git checkout FETCH_HEAD
- git submodule update --init --recursive --depth=1
- echo -e "section_end:`date +%s`:check_out\r\e[0K"
- *common-before_scripts
- *setup_tools_and_idf_python_venv
after_script: [] # ccache now is disabled for macos brew runners
timeout: 30m
#############
# `default` #
#############

View File

@@ -9,6 +9,7 @@
- build_system
- downloadable-tools
included_in:
- build:target_test
- build:check
# -------------------
@@ -40,6 +41,8 @@
"patterns:template-app":
patterns:
- build_template-app
included_in:
- build:target_test
"patterns:build-check":
patterns:
@@ -73,7 +76,3 @@
- if-schedule-test-build-system-windows
patterns:
- build_system_win
"labels:buildv2":
labels:
- buildv2

View File

@@ -3,27 +3,6 @@
image: $ESP_ENV_IMAGE
tags: [ deploy ]
.metrics_template:
stage: deploy
tags: [ fast_run, shiny ]
image: python:3.13-slim
dependencies: []
needs: []
variables:
PIP_CACHE_DIR: ".cache/pip"
# Metrics - related env vars
ESP_METRICS_PROJECT_URL: "$CI_PROJECT_URL"
ESP_METRICS_PROJECT_ID: "$CI_PROJECT_ID"
ESP_METRICS_COMMIT_SHA: "$PIPELINE_COMMIT_SHA"
ESP_METRICS_BRANCH_NAME: "$CI_COMMIT_REF_NAME"
cache:
key: metrics-pip
paths:
- .cache/pip
before_script:
- echo "Installing esp-metrics-cli tool"
- pip install "esp-metrics-cli>=0.3,<1"
check_submodule_sync:
extends:
- .deploy_job_template
@@ -85,31 +64,3 @@ deploy_update_SHA_in_esp-dockerfiles:
environment:
name: deploy_update_SHA_in_esp-dockerfiles_production
deployment_tier: production
upload_junit_report:
extends:
- .deploy_job_template
tags: [ fast_run, shiny ]
needs:
- pipeline_variables
- job: build_child_pipeline
artifacts: false
script:
- run_cmd idf-ci gitlab download-artifacts --type junit
rules:
- when: always
artifacts:
reports:
junit: XUNIT_RESULT_*.xml
expire_in: 1 week
when: always
target-examples-count-metrics:
extends:
- .metrics_template
allow_failure: true
script:
- echo "Generating ESP-IDF examples count metrics"
- cd tools/ci/metrics/examples_count
- python3 generate_metrics.py
- esp-metrics-cli upload -d schema.yaml -i metrics.json

View File

@@ -6,16 +6,13 @@
dependencies: # set dependencies to null to avoid missing artifacts issue
# run host_test jobs immediately, only after upload cache
needs:
- pipeline_variables
- job: upload-pip-cache
optional: true
artifacts: false
- job: upload-submodules-cache
optional: true
artifacts: false
- job: fast_template_app
optional: true
artifacts: false
- pipeline_variables
artifacts:
expire_in: 1 week
when: always
@@ -55,14 +52,14 @@ test_partition_table_on_host:
extends: .host_test_template
script:
- cd components/partition_table/test_gen_esp32part_host
- pytest_for_ut ./gen_esp32part_tests.py
- ./gen_esp32part_tests.py
test_ldgen_on_host:
extends: .host_test_template
script:
- cd tools/ldgen/test
- export PYTHONPATH=$PYTHONPATH:..
- pytest_for_ut .
- python -m unittest
variables:
LC_ALL: C.UTF-8
@@ -70,19 +67,21 @@ test_spiffs_on_host:
extends: .host_test_template
script:
- cd components/spiffs/test_spiffsgen/
- pytest_for_ut ./test_spiffsgen.py
- ./test_spiffsgen.py
test_fatfsgen_on_host:
extends: .host_test_template
script:
- cd components/fatfs/test_fatfsgen/
- pytest_for_ut ./test_fatfsgen.py ./test_wl_fatfsgen.py ./test_fatfsparse.py
- ./test_fatfsgen.py
- ./test_wl_fatfsgen.py
- ./test_fatfsparse.py
test_certificate_bundle_on_host:
extends: .host_test_template
script:
- cd components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/
- pytest_for_ut ./test_gen_crt_bundle.py
- ./test_gen_crt_bundle.py
# Test for create virtualenv. It must be invoked from Python, not from virtualenv.
# Use docker image system python without any extra dependencies
@@ -105,17 +104,15 @@ test_cli_installer:
- python3 ${IDF_PATH}/tools/idf_tools.py download required qemu-riscv32 qemu-xtensa cmake cmake@3.22.1
- cd ${IDF_PATH}/tools/test_idf_tools
- python3 -m pip install jsonschema
# Testing with system python3, so don't use any third-party packages
- python3 ./test_idf_tools.py -v
- python3 ./test_idf_tools_python_env.py
# It runs at the end because it modifies dependencies
- IDF_TEST_MAY_BREAK_DEPENDENCIES=1 python3 ./test_idf_tools.py -v TestSystemDependencies.test_commands_when_nodeps
test_efuse_table_on_host:
.test_efuse_table_on_host_template:
extends: .host_test_template
parallel:
matrix:
- IDF_TARGET: [esp32, esp32s2, esp32c3, esp32s3, esp32c2, esp32c6, esp32h2, esp32p4, esp32c5, esp32c61]
variables:
IDF_TARGET: "esp32"
artifacts:
when: on_failure
paths:
@@ -125,7 +122,35 @@ test_efuse_table_on_host:
- ./efuse_table_gen.py -t "${IDF_TARGET}" ${IDF_PATH}/components/efuse/${IDF_TARGET}/esp_efuse_table.csv
- git diff --exit-code -- ${IDF_TARGET}/esp_efuse_table.c || { echo 'Differences found for ${IDF_TARGET} target. Please run idf.py efuse-common-table and commit the changes.'; exit 1; }
- cd ${IDF_PATH}/components/efuse/test_efuse_host
- pytest_for_ut ./efuse_tests.py
- ./efuse_tests.py
test_efuse_table_on_host_esp32:
extends: .test_efuse_table_on_host_template
test_efuse_table_on_host_esp32s2:
extends: .test_efuse_table_on_host_template
variables:
IDF_TARGET: esp32s2
test_efuse_table_on_host_esp32s3:
extends: .test_efuse_table_on_host_template
variables:
IDF_TARGET: esp32s3
test_efuse_table_on_host_esp32c3:
extends: .test_efuse_table_on_host_template
variables:
IDF_TARGET: esp32c3
test_efuse_table_on_host_esp32h2:
extends: .test_efuse_table_on_host_template
variables:
IDF_TARGET: esp32h2
test_efuse_table_on_host_esp32c6:
extends: .test_efuse_table_on_host_template
variables:
IDF_TARGET: esp32c6
test_logtrace_proc:
extends: .host_test_template
@@ -192,7 +217,7 @@ test_split_path_by_spaces:
extends: .host_test_template
script:
- cd ${IDF_PATH}/tools
- pytest_for_ut ./split_paths_by_spaces.py
- python -m unittest split_paths_by_spaces.py
test_transport_on_host:
extends: .host_test_template
@@ -231,78 +256,8 @@ test_gen_soc_caps_kconfig:
extends: .host_test_template
script:
- cd ${IDF_PATH}/tools/gen_soc_caps_kconfig/
- pytest_for_ut ./test/test_gen_soc_caps_kconfig.py
- ./test/test_gen_soc_caps_kconfig.py
test_idf_build_apps_load_soc_caps:
extends: .host_test_template
script:
- cd tools/ci
- pytest_for_ut ./test_soc_headers_load_in_idf_build_apps.py
test_nvs_gen_check:
extends: .host_test_template
artifacts:
paths:
- XUNIT_RESULT.xml
- components/nvs_flash/nvs_partition_tool
reports:
junit: XUNIT_RESULT.xml
variables:
LC_ALL: C.UTF-8
script:
- cd ${IDF_PATH}/components/nvs_flash/nvs_partition_tool
- pytest_for_ut test_nvs_gen_check.py
test_esp_rom:
extends: .host_test_template
artifacts:
paths:
- XUNIT_RESULT.xml
reports:
junit: XUNIT_RESULT.xml
script:
- cd ${IDF_PATH}/components/esp_rom/
- pytest_for_ut test_esp_rom.py
make_sure_soc_caps_compatible_in_idf_build_apps:
extends:
- .host_test_template
- .rules:dev-push
artifacts:
paths:
- new.json
- base.json
when: always
when: manual
script:
- python tools/ci/idf_build_apps_dump_soc_caps.py new.json
- git fetch --depth=1 origin $CI_MERGE_REQUEST_DIFF_BASE_SHA
- git checkout -f $CI_MERGE_REQUEST_DIFF_BASE_SHA
- git checkout $CI_COMMIT_SHA -- tools/ci/idf_build_apps_dump_soc_caps.py
- python tools/ci/idf_build_apps_dump_soc_caps.py base.json
- diff new.json base.json
build_docker:
extends:
- .before_script:minimal
- .rules:build:docker
stage: host_test
needs: []
image: espressif/docker-builder:1
tags: [shiny, dind]
variables:
DOCKER_TMP_IMAGE_NAME: "idf_tmp_image"
script:
- export DOCKER_BUILD_ARGS="--build-arg IDF_CLONE_URL=${CI_REPOSITORY_URL} --build-arg IDF_CLONE_BRANCH_OR_TAG=${CI_COMMIT_REF_NAME} --build-arg IDF_CHECKOUT_REF=${CI_COMMIT_TAG:-$CI_COMMIT_SHA} --build-arg IDF_CLONE_SHALLOW=1 --build-arg IDF_GITHUB_ASSETS=${INTERNAL_GITHUB_ASSETS}"
- docker build --tag ${DOCKER_TMP_IMAGE_NAME} ${DOCKER_BUILD_ARGS} tools/docker/
# We can't mount $PWD/examples/get-started/blink into the container, see https://gitlab.com/gitlab-org/gitlab-ce/issues/41227.
# The workaround mentioned there works, but leaves around directories which need to be cleaned up manually.
# Therefore, build a copy of the example located inside the container.
- docker run --rm --workdir /opt/esp/idf/examples/get-started/blink ${DOCKER_TMP_IMAGE_NAME} idf.py build
############################
# Host test with test apps #
############################
test_pytest_qemu:
extends:
- .host_test_template
@@ -366,7 +321,9 @@ test_pytest_linux:
test_pytest_macos:
extends:
- .host_test_template
- .brew-macos-settings
- .before_script:build:macos
tags:
- macos
artifacts:
paths:
- XUNIT_RESULT.xml
@@ -374,6 +331,12 @@ test_pytest_macos:
- "**/build*/build_log.txt"
reports:
junit: XUNIT_RESULT.xml
variables:
PYENV_VERSION: "3.10"
# Workaround for a bug in Parallels executor where CI_PROJECT_DIR is not an absolute path,
# but a relative path to the build directory (builds/espressif/esp-idf instead of ~/builds/espressif/esp-idf.
# GitLab sets the project dir to this template `<builds_dir>/<namespace>/<project_name>`
IDF_PATH: "/Users/espressif/builds/espressif/esp-idf"
script:
- run_cmd idf-ci build run
-p components -p examples -p tools/test_apps
@@ -389,116 +352,50 @@ test_pytest_macos:
--junitxml=XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
######################
# Build System Tests #
######################
.test_build_system_template:
stage: host_test
extends:
- .build_template
- .rules:build:check
dependencies: # set dependencies to null to avoid missing artifacts issue
needs:
- job: fast_template_app
artifacts: false
optional: true
test_idf_build_apps_load_soc_caps:
extends: .host_test_template
script:
- python tools/ci/check_soc_headers_load_in_idf_build_apps.py
test_nvs_gen_check:
extends: .host_test_template
artifacts:
reports:
junit: XUNIT_RESULT.xml
paths:
- XUNIT_RESULT.xml
- test_build_system
expire_in: 1 week
when: always
script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- cd ${IDF_PATH}/tools/test_build_system
- run_cmd idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest
--cleanup-idf-copy
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
--work-dir ${CI_PROJECT_DIR}/test_build_system
--junitxml ${CI_PROJECT_DIR}/XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
.test_build_system_minimal_cmake_template:
extends: .test_build_system_template
- components/nvs_flash/nvs_partition_tool
reports:
junit: XUNIT_RESULT.xml
variables:
INSTALL_EXTRA_TOOLS: cmake@3.22.1
LC_ALL: C.UTF-8
script:
- MINIMAL_SUPPORTED_CMAKE_VERSION=$(echo "${INSTALL_EXTRA_TOOLS}" | sed -n 's/.*cmake@\([0-9.]*\).*/\1/p')
- export PATH=$(echo "$PATH" | sed -E "s|/tools/cmake/[0-9.]+|/tools/cmake/${MINIMAL_SUPPORTED_CMAKE_VERSION}|")
- ACTUAL_CMAKE_VERSION=$(cmake --version | head -n1 | awk '{print $3}')
- |
if [ "${ACTUAL_CMAKE_VERSION}" != "${MINIMAL_SUPPORTED_CMAKE_VERSION}" ]; then
echo "ERROR: Wrong minimal CMake version! Detected: ${ACTUAL_CMAKE_VERSION}, but should be: ${MINIMAL_SUPPORTED_CMAKE_VERSION}"
exit 1
fi
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- cd ${IDF_PATH}/tools/test_build_system
- run_cmd idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest
-k cmake
--cleanup-idf-copy
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
--work-dir ${CI_PROJECT_DIR}/test_build_system
--junitxml ${CI_PROJECT_DIR}/XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
- cd ${IDF_PATH}/components/nvs_flash/nvs_partition_tool
- pytest --noconftest test_nvs_gen_check.py --junitxml=XUNIT_RESULT.xml
pytest_build_system:
extends: .test_build_system_template
parallel: 3
pytest_buildv2_system:
extends:
- .test_build_system_template
- .rules:labels:buildv2
parallel: 3
test_esp_rom:
extends: .host_test_template
artifacts:
paths:
- XUNIT_RESULT.xml
reports:
junit: XUNIT_RESULT.xml
script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- cd ${IDF_PATH}/tools/test_build_system
- run_cmd idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest
--buildv2
--cleanup-idf-copy
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
--work-dir ${CI_PROJECT_DIR}/test_build_system
--junitxml ${CI_PROJECT_DIR}/XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
--
test_non_default_target.py
test_component_manager.py
test_build.py
test_bootloader.py
test_git.py
test_kconfig.py
test_partition.py
test_reproducible_build.py
test_sdkconfig.py
test_versions.py
test_common.py
test_components.py
test_cmake.py
test_idf_extension.py
test_rebuild.py
- cd ${IDF_PATH}/components/esp_rom/
- pytest --noconftest test_esp_rom.py --junitxml=XUNIT_RESULT.xml
pytest_build_system_macos:
extends:
- .test_build_system_template
- .brew-macos-settings
- .rules:build:macos
parallel: 3
pytest_build_system_minimal_cmake:
extends: .test_build_system_minimal_cmake_template
pytest_build_system_macos_minimal_cmake:
extends:
- .test_build_system_minimal_cmake_template
- .brew-macos-settings
- .rules:build:macos
variables:
INSTALL_EXTRA_TOOLS: ninja cmake@3.22.1
make_sure_soc_caps_compatible_in_idf_build_apps:
extends:
- .host_test_template
- .rules:dev-push
artifacts:
paths:
- new.json
- base.json
when: always
when: manual
script:
- python tools/ci/idf_build_apps_dump_soc_caps.py new.json
- git fetch --depth=1 origin $CI_MERGE_REQUEST_DIFF_BASE_SHA
- git checkout -f $CI_MERGE_REQUEST_DIFF_BASE_SHA
- git checkout $CI_COMMIT_SHA -- tools/ci/idf_build_apps_dump_soc_caps.py
- python tools/ci/idf_build_apps_dump_soc_caps.py base.json
- diff new.json base.json

View File

@@ -7,9 +7,7 @@ generate_failed_jobs_report:
- .post_deploy_template
tags: [build, shiny]
when: always
dependencies: # Do not download artifacts from the previous stages
needs:
- pipeline_variables
dependencies: [] # Do not download artifacts from the previous stages
artifacts:
expire_in: 2 week
when: always

View File

@@ -191,24 +191,13 @@ baseline_manifest_sha:
expire_in: 1 week
when: always
gcc_static_analyzer:
redundant_pass_job:
extends:
- .pre_check_template
- .rules:build
variables:
CI_CCACHE_DISABLE: 1
ANALYZING_APP: "examples/get-started/hello_world"
script:
- echo "CONFIG_COMPILER_STATIC_ANALYZER=y" >> ${ANALYZING_APP}/sdkconfig.defaults
- idf-build-apps build -p ${ANALYZING_APP}
retry_failed_jobs:
extends:
- .pre_check_template
- .rules:dev-push
tags: [shiny, fast_run]
allow_failure: true
cache: []
variables:
GIT_STRATEGY: none
before_script: []
script:
- echo "Retrieving and retrying all failed jobs for the pipeline..."
- python tools/ci/python_packages/gitlab_api.py retry_failed_jobs $CI_MERGE_REQUEST_PROJECT_ID --pipeline_id $CI_PIPELINE_ID
when: manual
- echo "This job is redundant to ensure the 'retry_failed_jobs' job can exist and not be skipped"

View File

@@ -0,0 +1,15 @@
retry_failed_jobs:
stage: retry_failed_jobs
tags: [shiny, fast_run]
allow_failure: true
image: $ESP_ENV_IMAGE
dependencies: null
before_script: []
cache: []
extends: []
script:
- echo "Retrieving and retrying all failed jobs for the pipeline..."
- python tools/ci/python_packages/gitlab_api.py retry_failed_jobs $CI_MERGE_REQUEST_PROJECT_ID --pipeline_id $CI_PIPELINE_ID
when: manual
needs:
- redundant_pass_job

View File

@@ -41,9 +41,11 @@
- "tools/idf_tools.py"
- "tools/tools.json"
.patterns-build_template-app: &patterns-build_template-app
- "tools/ci/build_template_app.sh"
.patterns-build_system: &patterns-build_system
- "tools/cmake/**/*"
- "tools/cmakev2/**/*"
- "tools/kconfig_new/**/*"
- "tools/idf.py"
- "tools/idf_py_actions/**/*"
@@ -51,12 +53,14 @@
- "tools/ci/ignore_build_warnings.txt"
- "tools/ci/test_build_system*.sh"
- "tools/ci/test_build_system*.py"
- "tools/ci/build_template_app.sh"
- "tools/test_build_system/**/*"
.patterns-build_system_win: &patterns-build_system_win
- "tools/test_build_system/**/*"
.patterns-build_macos: &patterns-build_macos
- "tools/ci/test_configure_ci_environment.sh"
.patterns-build_check: &patterns-build_check
- "tools/test_build_system/**/*"
- "tools/ci/test_configure_ci_environment.sh"
@@ -129,8 +133,6 @@
- "tools/bsasm.py"
- "tools/test_bsasm/**/*"
- "tools/ci/test_soc_headers_load_in_idf_build_apps.py"
.patterns-docker: &patterns-docker
- "tools/docker/**/*"
@@ -147,6 +149,7 @@
- "components/esp_coex/lib"
- "components/lwip/lwip"
- "components/mbedtls/mbedtls"
- "components/mqtt/esp-mqtt"
- "components/openthread/lib"
- "components/openthread/openthread"
- "components/protobuf-c/protobuf-c"
@@ -272,9 +275,6 @@
.if-label-build: &if-label-build
if: '$BOT_LABEL_BUILD || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build(?:,[^,\n\r]+)*$/i'
.if-label-buildv2: &if-label-buildv2
if: '$BOT_LABEL_BUILDV2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*buildv2(?:,[^,\n\r]+)*$/i'
.if-label-docker: &if-label-docker
if: '$BOT_LABEL_DOCKER || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*docker(?:,[^,\n\r]+)*$/i'
@@ -348,11 +348,20 @@
- <<: *if-label-macos
- <<: *if-label-macos_test
.rules:labels:buildv2:
.rules:build:target_test:
rules:
- <<: *if-revert-branch
when: never
- <<: *if-label-buildv2
- <<: *if-protected-check
- <<: *if-label-build
- <<: *if-dev-push
changes: *patterns-build_components
- <<: *if-dev-push
changes: *patterns-build_system
- <<: *if-dev-push
changes: *patterns-build_template-app
- <<: *if-dev-push
changes: *patterns-downloadable-tools
.rules:labels:nvs_coverage:
rules:

View File

@@ -136,47 +136,3 @@ pytest_build_system_win_minimal_cmake:
- cd ${IDF_PATH}\tools\test_build_system
- idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest -k cmake --junitxml=${CI_PROJECT_DIR}\XUNIT_RESULT.xml --ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
pytest_buildv2_system_win:
extends:
- .test_build_system_template_win
- .rules:labels:buildv2
parallel: 2
needs: []
tags: [windows-build, brew]
artifacts:
paths:
- XUNIT_RESULT.xml
- test_build_system
expire_in: 2 days
reports:
junit: XUNIT_RESULT.xml
when: always
script:
- .\install.ps1 --enable-ci
- . .\export.ps1
- python "${SUBMODULE_FETCH_TOOL}" -s "all"
- cd ${IDF_PATH}\tools\test_build_system
- idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- pytest
--buildv2
--parallel-count ${CI_NODE_TOTAL}
--parallel-index ${CI_NODE_INDEX}
--junitxml=${CI_PROJECT_DIR}\XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
--
test_non_default_target.py
test_component_manager.py
test_build.py
test_bootloader.py
test_git.py
test_kconfig.py
test_partition.py
test_reproducible_build.py
test_sdkconfig.py
test_versions.py
test_common.py
test_components.py
test_cmake.py
test_idf_extension.py
test_rebuild.py

4
.gitmodules vendored
View File

@@ -54,6 +54,10 @@
path = components/lwip/lwip
url = ../../espressif/esp-lwip.git
[submodule "components/mqtt/esp-mqtt"]
path = components/mqtt/esp-mqtt
url = ../../espressif/esp-mqtt.git
[submodule "components/protobuf-c/protobuf-c"]
path = components/protobuf-c/protobuf-c
url = ../../protobuf-c/protobuf-c.git

View File

@@ -48,6 +48,7 @@ pre_yaml_jinja = """
include:
- .gitlab/ci/common.yml
- tools/ci/dynamic_pipelines/templates/.dynamic_jobs.yml
- tools/ci/dynamic_pipelines/templates/generate_target_test_report.yml
"""
[gitlab.artifacts.s3.debug]
@@ -88,19 +89,18 @@ patterns = [
[gitlab.artifacts.s3.junit]
bucket = "idf-artifacts"
patterns = [
'**/XUNIT_RESULT_*.xml',
'**/build_summary_*.xml',
'XUNIT_RESULT_*.xml',
]
[gitlab.artifacts.s3.env]
bucket = "idf-artifacts"
patterns = [
'**/pipeline.env',
'pipeline.env',
]
[gitlab.artifacts.s3.longterm]
bucket = "longterm"
if_clause = '"$CI_COMMIT_REF_NAME" == "master"'
patterns = [
'**/build*/size*.json',
'**/build*/size.json',
]

View File

@@ -159,10 +159,6 @@ if(CONFIG_COMPILER_NO_MERGE_CONSTANTS)
list(APPEND compile_options "-fno-merge-constants")
endif()
if(CONFIG_COMPILER_ENABLE_TEXT_SECTION_LITERALS)
list(APPEND compile_options "-mtext-section-literals")
endif()
if(CONFIG_COMPILER_STACK_CHECK_MODE_NORM)
list(APPEND compile_options "-fstack-protector")
elseif(CONFIG_COMPILER_STACK_CHECK_MODE_STRONG)

View File

@@ -140,12 +140,6 @@ Supported since ESP-IDF v5.1.
| release/v5.4 | v5.4.1+ | v5.4.1 |
| release/v5.5 and above | v5.5+ | v5.5 |
### ESP32-P4
#### v1.0, v1.3
Supported since ESP-IDF v5.3.
## What If the ESP-IDF Version Is Lower than the `Required` Version?
Latest ESP-IDF versions can prevent from downloading to, or even execute binaries on unsupported chips. ESP-IDF of versions v4.4.5+, v5.0.1+, v5.1 and above have both esptool download check and bootloader loading check against the chip revision. While ESP-IDF v4.3.5 has only esptool downloading check.

View File

@@ -140,11 +140,6 @@
| release/v5.4 | v5.4.1+ | v5.4.1 |
| release/v5.5 及以上 | v5.5+ | v5.5 |
### ESP32-P4
#### v1.0, v1.3
从 ESP-IDF v5.3 开始支持。
## 如果 ESP-IDF 版本低于 `需求版本` 会出现什么情况?

56
Kconfig
View File

@@ -151,13 +151,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
select IDF_ENV_BRINGUP
select IDF_ENV_FPGA if ESP32H4_SELECTS_REV_MP
config IDF_TARGET_ESP32S31
bool
default "y" if IDF_TARGET="esp32s31"
select IDF_TARGET_ARCH_RISCV
select IDF_ENV_FPGA
select IDF_ENV_BRINGUP
config IDF_TARGET_LINUX
bool
default "y" if IDF_TARGET="linux"
@@ -176,7 +169,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
default 0x0014 if IDF_TARGET_ESP32C61
default 0x0019 if IDF_TARGET_ESP32H21
default 0x001C if IDF_TARGET_ESP32H4
default 0x0020 if IDF_TARGET_ESP32S31
default 0xFFFF
@@ -378,27 +370,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
endchoice
config COMPILER_ENABLE_RISCV_ZCMP
bool "Enable RISCV ZCMP extension"
depends on SOC_CPU_ZCMP_WORKAROUND
default n
help
Enable the RISC-V ZCMP (Compressed Macro) extension to reduce binary size
by optimizing function prologue and epilogue sequences.
Note: Due to a hardware issue on some ESP32 chips (e.g., ESP32C5, ESP32C61,
ESP32H4), executing "cm.push" may re-enable interrupts even when global
interrupts are disabled (mstatus.mie = 0). This can cause unexpected interrupts
during CPU retention or within critical sections.
Workarounds are implemented in the IDF codebase. However, if user code
directly disables interrupts, additional actions may be required. Refer
to code examples under the SOC_CPU_ZCMP_WORKAROUND macro, or disable
the ZCMP extension for source files that contain functions which may
execute while mstatus.mie = 0.
Even with these workarounds, the issue may still affect dual-core variants.
choice COMPILER_OPTIMIZATION_ASSERTION_LEVEL
prompt "Assertion level"
default COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE
@@ -576,20 +547,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
distribution is more uniform across libraries. On downside, it may increase
the binary size and hence should be used during development phase only.
config COMPILER_ENABLE_TEXT_SECTION_LITERALS
bool
depends on IDF_TOOLCHAIN_GCC
depends on IDF_TARGET_ARCH_XTENSA
default y if ESPTOOLPY_FAST_REFLASHING
help
Intersperse Xtensa literals within the text section to keep
them as close as possible to their references. This prevents
literals from being placed into a separate section in the
output file and prevents the linker from combining literal
pools from different object files. Enabling this is necessary
for fast reflashing to prevent mixing code from mutable and
immutable libraries.
config COMPILER_WARN_WRITE_STRINGS
bool "Enable -Wwrite-strings warning flag"
default "n"
@@ -764,17 +721,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
depends on "${IDF_MINIMAL_BUILD}"
source "$COMPONENT_KCONFIGS_SOURCE_FILE"
menu "Configuration for components not included in the build"
depends on "${IDF_BUILD_V2}"
osource "$COMPONENT_KCONFIGS_EXCLUDED_SOURCE_FILE"
endmenu
endmenu
menu "Project configuration for components not included in the build"
depends on "${IDF_BUILD_V2}"
osource "$COMPONENT_KCONFIGS_PROJBUILD_EXCLUDED_SOURCE_FILE"
endmenu
config IDF_EXPERIMENTAL_FEATURES
@@ -797,5 +743,3 @@ mainmenu "Espressif IoT Development Framework Configuration"
- CONFIG_LIBC_PICOLIBC
- CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
- CONFIG_I3C_MASTER_ENABLED
- CONFIG_MBEDTLS_ESP_IDF_USE_PSA_CRYPTO
- CONFIG_ESPTOOLPY_FAST_REFLASHING

View File

@@ -4,14 +4,14 @@ if(${target} STREQUAL "linux")
return() # This component is not supported by the POSIX/Linux simulator
endif()
if(CONFIG_ESP_TRACE_TRANSPORT_APPTRACE)
if(CONFIG_APPTRACE_ENABLE)
set(srcs
"app_trace.c"
"app_trace_util.c"
"host_file_io.c"
)
if(NOT CONFIG_APPTRACE_DEST_UART) # JTAG or None
if(NOT CONFIG_APPTRACE_DEST_UART) # JTAG or ALL
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
list(APPEND srcs "port/xtensa/port_jtag.c")
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
@@ -20,7 +20,7 @@ if(CONFIG_ESP_TRACE_TRANSPORT_APPTRACE)
list(APPEND srcs "app_trace_membufs_proto.c")
endif()
if(NOT CONFIG_APPTRACE_DEST_JTAG) # UART or None
if(NOT CONFIG_APPTRACE_DEST_JTAG) # UART or ALL
list(APPEND srcs "port/port_uart.c")
endif()
endif()
@@ -33,6 +33,28 @@ set(include_dirs "include")
set(priv_include_dirs "private_include" "port/include")
if(CONFIG_APPTRACE_SV_ENABLE)
list(APPEND include_dirs
sys_view/Config
sys_view/SEGGER
sys_view/Sample/FreeRTOSV10.4)
list(APPEND srcs
"sys_view/SEGGER/SEGGER_SYSVIEW.c"
"sys_view/Sample/FreeRTOSV10.4/Config/esp/SEGGER_SYSVIEW_Config_FreeRTOS.c"
"sys_view/Sample/FreeRTOSV10.4/SEGGER_SYSVIEW_FreeRTOS.c"
"sys_view/esp/SEGGER_RTT_esp.c"
"sys_view/ext/heap_trace_module.c"
"sys_view/ext/logging.c")
endif()
if(CONFIG_HEAP_TRACING_TOHOST)
list(APPEND srcs "heap_trace_tohost.c")
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
set_source_files_properties(heap_trace_tohost.c PROPERTIES COMPILE_FLAGS -Wno-frame-address)
endif()
endif()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}"

View File

@@ -0,0 +1,330 @@
menu "Application Level Tracing"
config APPTRACE_ENABLE
bool "Enable Application Level Tracing"
default n
help
Enables/disable application tracing module.
This must be enabled to use any tracing library.
choice APPTRACE_DESTINATION
prompt "Data Destination"
default APPTRACE_DEST_JTAG if !PM_ENABLE
default APPTRACE_DEST_UART if PM_ENABLE
depends on APPTRACE_ENABLE
help
Select destination for application trace: JTAG or UART.
When SystemView is enabled, this also controls the SystemView destination.
config APPTRACE_DEST_JTAG
bool "JTAG"
select APPTRACE_TRAX_ENABLE if IDF_TARGET_ARCH_XTENSA
depends on !PM_ENABLE
config APPTRACE_DEST_UART
bool "UART"
config APPTRACE_DEST_NONE
bool "None (runtime selection)"
help
Compile both JTAG and UART interfaces. Increases IRAM usage.
Allows runtime selection via esp_apptrace_get_user_params().
With this option, destination and configuration must be provided
at runtime. Default JTAG and UART settings are defined in
components/app_trace/include/esp_app_trace_config.h.
Override these by implementing esp_apptrace_get_user_params()
in your application.
endchoice
config APPTRACE_BUF_SIZE
int "Size of the apptrace buffer"
depends on APPTRACE_DEST_JTAG && !APPTRACE_TRAX_ENABLE
default 16384
help
Size of the memory buffer for trace data in bytes.
config APPTRACE_DEST_UART_NUM
int "UART port number"
depends on APPTRACE_DEST_UART
range 0 1 if (SOC_UART_NUM <= 2)
range 0 2 if (SOC_UART_NUM <= 3)
range 0 5 if (SOC_UART_NUM <= 6)
default 1
help
UART communication port number for the apptrace destination.
See UART documentation for available port numbers.
config APPTRACE_UART_TX_GPIO
int "UART TX on GPIO<num>"
depends on APPTRACE_DEST_UART
range 0 46
default 12
help
This GPIO is used for UART TX pin.
config APPTRACE_UART_RX_GPIO
int "UART RX on GPIO<num>"
depends on APPTRACE_DEST_UART
range 0 46
default 13
help
This GPIO is used for UART RX pin.
config APPTRACE_UART_BAUDRATE
int
prompt "UART baud rate" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 1000000
range 1200 8000000
range 1200 1000000
help
This baud rate is used for UART.
The app's maximum baud rate depends on the UART clock source. If Power Management is disabled,
the UART clock source is the APB clock and all baud rates in the available range will be sufficiently
accurate. If Power Management is enabled, REF_TICK clock source is used so the baud rate is divided
from 1MHz. Baud rates above 1Mbps are not possible and values between 500Kbps and 1Mbps may not be
accurate.
config APPTRACE_UART_RX_BUFF_SIZE
int
prompt "UART RX ring buffer size" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 128
range 64 32768
help
Size of the UART input ring buffer.
This size related to the baudrate, system tick frequency and amount of data to transfer.
The data placed to this buffer before sent out to the interface.
config APPTRACE_UART_TX_BUFF_SIZE
int
prompt "UART TX ring buffer size" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 4096
range 2048 32768
help
Size of the UART output ring buffer.
This size related to the baudrate, system tick frequency and amount of data to transfer.
config APPTRACE_UART_TX_MSG_SIZE
int
prompt "UART TX message size" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 128
range 64 32768
help
Maximum size of the single message to transfer.
config APPTRACE_UART_TASK_PRIO
int
prompt "UART Task Priority" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 1
range 1 32
help
UART task priority. In case of high events rate,
this parameter could be changed up to (configMAX_PRIORITIES-1).
config APPTRACE_TRAX_ENABLE
bool
depends on IDF_TARGET_ARCH_XTENSA && !ESP32_TRAX && !ESP32S2_TRAX && !ESP32S3_TRAX
select ESP32_MEMMAP_TRACEMEM
select ESP32S2_MEMMAP_TRACEMEM
select ESP32S3_MEMMAP_TRACEMEM
select ESP32_MEMMAP_TRACEMEM_TWOBANKS
select ESP32S2_MEMMAP_TRACEMEM_TWOBANKS
select ESP32S3_MEMMAP_TRACEMEM_TWOBANKS
default n
help
Enables/disable TRAX tracing HW.
config APPTRACE_LOCK_ENABLE
bool "Internal Sync Lock Enable"
depends on APPTRACE_ENABLE
default n
help
Enables/disable application tracing module internal sync lock.
Keep in mind this will slow down the trace data transfer to the host.
config APPTRACE_ONPANIC_HOST_FLUSH_TMO
int "Timeout for flushing last trace data to host on panic"
depends on APPTRACE_ENABLE
range -1 5000
default -1
help
Timeout for flushing last trace data to host in case of panic. In ms.
Use -1 to disable timeout and wait forever.
config APPTRACE_POSTMORTEM_FLUSH_THRESH
int "Threshold for flushing last trace data to host on panic"
depends on APPTRACE_ENABLE
range 0 16384
default 0
help
Threshold for flushing last trace data to host on panic in post-mortem mode.
This is minimal amount of data needed to perform flush. In bytes.
menu "FreeRTOS SystemView Tracing"
depends on APPTRACE_ENABLE
config APPTRACE_SV_ENABLE
bool "SystemView Tracing Enable"
depends on APPTRACE_ENABLE
default n
help
Enables support for SEGGER SystemView tracing functionality.
choice APPTRACE_SV_CPU
prompt "CPU to trace"
depends on APPTRACE_SV_ENABLE && APPTRACE_DEST_UART && !ESP_SYSTEM_SINGLE_CORE_MODE
default APPTRACE_SV_DEST_CPU_0
help
Define the CPU to trace by SystemView.
config APPTRACE_SV_DEST_CPU_0
bool "CPU0"
help
Send SEGGER SystemView events for Pro CPU.
config APPTRACE_SV_DEST_CPU_1
bool "CPU1"
help
Send SEGGER SystemView events for App CPU.
endchoice
choice APPTRACE_SV_TS_SOURCE
prompt "Timer to use as timestamp source"
depends on APPTRACE_SV_ENABLE
default APPTRACE_SV_TS_SOURCE_CCOUNT if ESP_SYSTEM_SINGLE_CORE_MODE && !PM_ENABLE && !IDF_TARGET_ESP32C3
default APPTRACE_SV_TS_SOURCE_GPTIMER if !ESP_SYSTEM_SINGLE_CORE_MODE && !PM_ENABLE && !IDF_TARGET_ESP32C3
default APPTRACE_SV_TS_SOURCE_ESP_TIMER if PM_ENABLE || IDF_TARGET_ESP32C3
help
SystemView needs to use a hardware timer as the source of timestamps
when tracing. This option selects the timer for it.
config APPTRACE_SV_TS_SOURCE_CCOUNT
bool "CPU cycle counter (CCOUNT)"
depends on ESP_SYSTEM_SINGLE_CORE_MODE && !PM_ENABLE && !IDF_TARGET_ESP32C3
config APPTRACE_SV_TS_SOURCE_GPTIMER
bool "General Purpose Timer (Timer Group)"
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
config APPTRACE_SV_TS_SOURCE_ESP_TIMER
bool "esp_timer high resolution timer"
endchoice
config APPTRACE_SV_MAX_TASKS
int "Maximum supported tasks"
depends on APPTRACE_SV_ENABLE
range 1 64
default 16
help
Configures maximum supported tasks in sysview debug
config APPTRACE_SV_BUF_WAIT_TMO
int "Trace buffer wait timeout"
depends on APPTRACE_SV_ENABLE
default 500
help
Configures timeout (in us) to wait for free space in trace buffer.
Set to -1 to wait forever and avoid lost events.
config APPTRACE_SV_EVT_OVERFLOW_ENABLE
bool "Trace Buffer Overflow Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Trace Buffer Overflow" event.
config APPTRACE_SV_EVT_ISR_ENTER_ENABLE
bool "ISR Enter Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "ISR Enter" event.
config APPTRACE_SV_EVT_ISR_EXIT_ENABLE
bool "ISR Exit Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "ISR Exit" event.
config APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
bool "ISR Exit to Scheduler Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "ISR to Scheduler" event.
config APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
bool "Task Start Execution Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Task Start Execution" event.
config APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
bool "Task Stop Execution Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Task Stop Execution" event.
config APPTRACE_SV_EVT_TASK_START_READY_ENABLE
bool "Task Start Ready State Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Task Start Ready State" event.
config APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
bool "Task Stop Ready State Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Task Stop Ready State" event.
config APPTRACE_SV_EVT_TASK_CREATE_ENABLE
bool "Task Create Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Task Create" event.
config APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
bool "Task Terminate Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Task Terminate" event.
config APPTRACE_SV_EVT_IDLE_ENABLE
bool "System Idle Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "System Idle" event.
config APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
bool "Timer Enter Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Timer Enter" event.
config APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
bool "Timer Exit Event"
depends on APPTRACE_SV_ENABLE
default y
help
Enables "Timer Exit" event.
endmenu
endmenu

View File

@@ -1,134 +0,0 @@
menu "Application Level Tracing"
depends on ESP_TRACE_TRANSPORT_APPTRACE
choice APPTRACE_DESTINATION
prompt "Data Destination"
default APPTRACE_DEST_JTAG if !PM_ENABLE
default APPTRACE_DEST_UART if PM_ENABLE
help
Select destination for application trace: JTAG, UART, or both.
config APPTRACE_DEST_JTAG
bool "JTAG"
select APPTRACE_TRAX_ENABLE if IDF_TARGET_ARCH_XTENSA
depends on !PM_ENABLE
config APPTRACE_DEST_UART
bool "UART"
config APPTRACE_DEST_ALL
bool "All (runtime selection)"
help
Compile both JTAG and UART interfaces in advance (higher IRAM usage).
Allows runtime switching between JTAG and UART via esp_apptrace_get_user_params().
If esp_apptrace_get_user_params() is not provided by the
application, JTAG is used by default with the default
configuration defined in components/app_trace/include/esp_app_trace_config.h.
endchoice
config APPTRACE_BUF_SIZE
int "Size of the apptrace buffer"
depends on APPTRACE_DEST_JTAG && !APPTRACE_TRAX_ENABLE
default 16384
help
Size of the memory buffer for trace data in bytes.
config APPTRACE_DEST_UART_NUM
int "UART port number"
depends on APPTRACE_DEST_UART
range 0 1 if (SOC_UART_HP_NUM <= 2)
range 0 2 if (SOC_UART_HP_NUM <= 3)
range 0 4 if (SOC_UART_HP_NUM <= 5)
default 1
help
UART communication port number for the apptrace destination.
See UART documentation for available port numbers.
config APPTRACE_UART_TX_GPIO
int "UART TX on GPIO<num>"
depends on APPTRACE_DEST_UART
range 0 46
default 12
help
This GPIO is used for UART TX pin.
config APPTRACE_UART_RX_GPIO
int "UART RX on GPIO<num>"
depends on APPTRACE_DEST_UART
range 0 46
default 13
help
This GPIO is used for UART RX pin.
config APPTRACE_UART_BAUDRATE
int
prompt "UART baud rate" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 1000000
range 1200 8000000
range 1200 1000000
help
This baud rate is used for UART.
The app's maximum baud rate depends on the UART clock source. If Power Management is disabled,
the UART clock source is the APB clock and all baud rates in the available range will be sufficiently
accurate. If Power Management is enabled, REF_TICK clock source is used so the baud rate is divided
from 1MHz. Baud rates above 1Mbps are not possible and values between 500Kbps and 1Mbps may not be
accurate.
config APPTRACE_UART_TX_BUFF_SIZE
int
prompt "UART TX ring buffer size" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 4096
range 2048 32768
help
Size of the UART output ring buffer. Must be power of two.
This size related to the baudrate, system tick frequency and amount of data to transfer.
config APPTRACE_UART_TX_MSG_SIZE
int
prompt "UART TX message size" if APPTRACE_DEST_UART
depends on APPTRACE_DEST_UART
default 128
range 64 32768
help
Maximum size of the single message to transfer.
config APPTRACE_TRAX_ENABLE
bool
depends on IDF_TARGET_ARCH_XTENSA && !ESP32_TRAX && !ESP32S2_TRAX && !ESP32S3_TRAX
select ESP32_MEMMAP_TRACEMEM
select ESP32S2_MEMMAP_TRACEMEM
select ESP32S3_MEMMAP_TRACEMEM
select ESP32_MEMMAP_TRACEMEM_TWOBANKS
select ESP32S2_MEMMAP_TRACEMEM_TWOBANKS
select ESP32S3_MEMMAP_TRACEMEM_TWOBANKS
default n
help
Enables/disable TRAX tracing HW.
config APPTRACE_LOCK_ENABLE
bool "Internal Sync Lock Enable"
default n
help
Enables/disable application tracing module internal sync lock to prevent data corruption
when multiple tasks are writing to the same trace buffer.
Keep in mind this will slow down the trace data transfer to the host.
config APPTRACE_ONPANIC_HOST_FLUSH_TMO
int "Timeout for flushing last trace data to host on panic"
range -1 5000
default -1
help
Timeout for flushing last trace data to host in case of panic. In ms.
Use -1 to disable timeout and wait forever.
config APPTRACE_POSTMORTEM_FLUSH_THRESH
int "Threshold for flushing last trace data to host on panic"
range 0 16384
default 0
help
Threshold for flushing last trace data to host on panic in post-mortem mode.
This is minimal amount of data needed to perform flush. In bytes.
endmenu

View File

@@ -32,7 +32,7 @@ typedef struct {
static esp_apptrace_channel_t s_trace_ch;
static volatile int s_trace_ch_hw_initialized = 0;
esp_err_t esp_apptrace_init(const esp_apptrace_config_t *config)
static esp_err_t esp_apptrace_init(const esp_apptrace_config_t *config)
{
__attribute__((unused)) void *hw_data = NULL;
@@ -44,7 +44,7 @@ esp_err_t esp_apptrace_init(const esp_apptrace_config_t *config)
const esp_apptrace_uart_config_t *uart_config = &config->dest_cfg.uart;
s_trace_ch.hw = esp_apptrace_uart_hw_get(uart_config->uart_num, &hw_data);
s_trace_ch.hw_data = hw_data;
#else // CONFIG_APPTRACE_DEST_ALL allows runtime selection between destinations
#else // CONFIG_APPTRACE_DEST_NONE allows runtime selection
if (config->dest == ESP_APPTRACE_DEST_JTAG) {
s_trace_ch.hw = esp_apptrace_jtag_hw_get(&hw_data);
s_trace_ch.hw_data = hw_data;
@@ -363,11 +363,6 @@ esp_err_t esp_apptrace_set_header_size(esp_apptrace_header_size_t header_size)
return ESP_OK;
}
/* If any trace library (sysview or external) is selected with the apptrace transport,
* initialization will be handled by the esp_trace component
*/
#if CONFIG_ESP_TRACE_LIB_NONE && CONFIG_ESP_TRACE_TRANSPORT_APPTRACE
esp_apptrace_config_t __attribute__((weak)) esp_apptrace_get_user_params(void)
{
esp_apptrace_config_t default_config = APPTRACE_CONFIG_DEFAULT();
@@ -379,4 +374,3 @@ ESP_SYSTEM_INIT_FN(apptrace_early_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 11
esp_apptrace_config_t config = esp_apptrace_get_user_params();
return esp_apptrace_init(&config);
}
#endif

View File

@@ -0,0 +1,113 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "esp_heap_trace.h"
#include "esp_heap_caps.h"
#if CONFIG_APPTRACE_SV_ENABLE
#include "esp_app_trace.h"
#include "esp_sysview_trace.h"
#endif
#define STACK_DEPTH CONFIG_HEAP_TRACING_STACK_DEPTH
#if CONFIG_HEAP_TRACING_TOHOST
#if !CONFIG_APPTRACE_SV_ENABLE
#error None of the heap tracing backends is enabled! You must enable SystemView compatible tracing to use this feature.
#endif
static bool s_tracing;
esp_err_t heap_trace_init_tohost(void)
{
if (s_tracing) {
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
}
esp_err_t heap_trace_start(heap_trace_mode_t mode_param)
{
#if CONFIG_APPTRACE_SV_ENABLE
esp_err_t ret = esp_sysview_heap_trace_start((uint32_t) -1);
if (ret != ESP_OK) {
return ret;
}
#endif
s_tracing = true;
return ESP_OK;
}
esp_err_t heap_trace_stop(void)
{
esp_err_t ret = ESP_ERR_NOT_SUPPORTED;
#if CONFIG_APPTRACE_SV_ENABLE
ret = esp_sysview_heap_trace_stop();
#endif
s_tracing = false;
return ret;
}
esp_err_t heap_trace_resume(void)
{
return heap_trace_start(HEAP_TRACE_ALL);
}
size_t heap_trace_get_count(void)
{
return 0;
}
esp_err_t heap_trace_get(size_t index, heap_trace_record_t *record)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t heap_trace_summary(heap_trace_summary_t *summary)
{
return ESP_ERR_NOT_SUPPORTED;
}
void heap_trace_dump(void)
{
return;
}
void heap_trace_dump_caps(__attribute__((unused)) const uint32_t caps)
{
return;
}
/* Add a new allocation to the heap trace records */
static HEAP_IRAM_ATTR void record_allocation(const heap_trace_record_t *record)
{
if (!s_tracing) {
return;
}
#if CONFIG_APPTRACE_SV_ENABLE
esp_sysview_heap_trace_alloc(record->address, record->size, record->alloced_by);
#endif
}
/* record a free event in the heap trace log
For HEAP_TRACE_ALL, this means filling in the freed_by pointer.
For HEAP_TRACE_LEAKS, this means removing the record from the log.
*/
static HEAP_IRAM_ATTR void record_free(void *p, void **callers)
{
if (!s_tracing) {
return;
}
#if CONFIG_APPTRACE_SV_ENABLE
esp_sysview_heap_trace_free(p, callers);
#endif
}
#include "heap_trace.inc"
#endif /*CONFIG_HEAP_TRACING_TOHOST*/

View File

@@ -16,19 +16,22 @@ extern "C" {
#endif
/**
* @brief Initializes application tracing module for the selected destination and configuration.
* @brief Get custom trace initialization parameters (optional callback)
*
* @note Should be called before any esp_apptrace_xxx call.
* This is an optional callback function that user applications can implement to provide
* custom trace configuration. A weak default implementation exists in the app_trace component
* that returns menuconfig defaults (APPTRACE_CONFIG_DEFAULT()). User applications can override
* this by providing their own implementation.
*
* This function is called during early system initialization (before app_main) on all cores.
*
* @return ESP_OK on success, otherwise see esp_err_t
*/
esp_err_t esp_apptrace_init(const esp_apptrace_config_t *config);
esp_apptrace_config_t esp_apptrace_get_user_params(void);
/**
* @brief Configures down buffer.
*
* @note Needs to be called before attempting to receive any data using esp_apptrace_down_buffer_get and
* esp_apptrace_read. This function does not protect internal data by lock.
* @note Needs to be called before attempting to receive any data using esp_apptrace_down_buffer_get and esp_apptrace_read.
* This function does not protect internal data by lock.
*
* @param buf Address of buffer to use for down channel (host to target) data.
* @param size Size of the buffer.
@@ -259,8 +262,8 @@ int esp_apptrace_feof(void *stream);
#define APPTRACE_JTAG_CONFIG_DEFAULT() { \
.dest = ESP_APPTRACE_DEST_JTAG, \
.dest_cfg.jtag = {0}, \
.flush_tmo = CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO, \
.flush_thresh = CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, \
.panic_flush_tmo = CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO, \
.panic_flush_thresh = CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, \
}
#endif
@@ -272,11 +275,13 @@ int esp_apptrace_feof(void *stream);
.tx_pin_num = CONFIG_APPTRACE_UART_TX_GPIO, \
.rx_pin_num = CONFIG_APPTRACE_UART_RX_GPIO, \
.baud_rate = CONFIG_APPTRACE_UART_BAUDRATE, \
.rx_buff_size = CONFIG_APPTRACE_UART_RX_BUFF_SIZE, \
.tx_buff_size = CONFIG_APPTRACE_UART_TX_BUFF_SIZE, \
.tx_msg_size = CONFIG_APPTRACE_UART_TX_MSG_SIZE, \
.task_prio = CONFIG_APPTRACE_UART_TASK_PRIO, \
}, \
.flush_tmo = CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO, \
.flush_thresh = CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, \
.panic_flush_tmo = CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO, \
.panic_flush_thresh = CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, \
}
#endif

View File

@@ -8,12 +8,10 @@
#include "sdkconfig.h"
/* Default configurations for runtime selection (APPTRACE_DEST_ALL)
* These values are used when building with both JTAG and UART enabled
* to allow runtime selection. You can switch between destinations
* via esp_apptrace_get_user_params(). If this function is
* not provided by the application, JTAG is used by default with the
* configuration defined below. See esp_app_trace.h for details.
/* Default configurations for runtime selection (CONFIG_APPTRACE_DEST_NONE)
* These values are used when CONFIG_APPTRACE_DEST_NONE is selected in menuconfig.
* To customize at runtime, implement esp_apptrace_get_user_params()
* in your application. See esp_app_trace.h for details.
*/
#if !defined(CONFIG_APPTRACE_UART_TX_GPIO) || !defined(CONFIG_APPTRACE_UART_RX_GPIO)
@@ -24,6 +22,10 @@
#define CONFIG_APPTRACE_BUF_SIZE 16384
#endif
#ifndef CONFIG_APPTRACE_UART_RX_BUFF_SIZE
#define CONFIG_APPTRACE_UART_RX_BUFF_SIZE 128
#endif
#ifndef CONFIG_APPTRACE_UART_TX_BUFF_SIZE
#define CONFIG_APPTRACE_UART_TX_BUFF_SIZE 4096
#endif
@@ -36,6 +38,10 @@
#define CONFIG_APPTRACE_UART_BAUDRATE 1000000
#endif
#ifndef CONFIG_APPTRACE_UART_TASK_PRIO
#define CONFIG_APPTRACE_UART_TASK_PRIO 1
#endif
#ifndef CONFIG_APPTRACE_UART_TX_GPIO
#define CONFIG_APPTRACE_UART_TX_GPIO U1TXD_GPIO_NUM
#endif
@@ -48,4 +54,8 @@
#define CONFIG_APPTRACE_DEST_UART_NUM 1
#endif
#ifndef CONFIG_APPTRACE_SV_DEST_CPU_0
#define CONFIG_APPTRACE_SV_DEST_CPU_0 1
#endif
#endif /* ESP_APP_TRACE_CONFIG_H_ */

View File

@@ -27,7 +27,7 @@ typedef struct {
/** Tracing module synchronization lock */
typedef struct {
spinlock_t mux;
unsigned int int_state;
unsigned int_state;
} esp_apptrace_lock_t;
/** Ring buffer control structure.
@@ -59,8 +59,10 @@ typedef struct {
int tx_pin_num; ///< TX pin number
int rx_pin_num; ///< RX pin number
int baud_rate; ///< Baud rate
uint32_t rx_buff_size; ///< RX ring buffer size
uint32_t tx_buff_size; ///< TX ring buffer size
uint32_t tx_msg_size; ///< Maximum size of the single message to transfer.
int task_prio; ///< Task priority
} esp_apptrace_uart_config_t;
/**
@@ -84,8 +86,8 @@ typedef struct {
} jtag;
} dest_cfg; ///< Destination-specific configuration
uint32_t flush_tmo; ///< Flush timeout in milliseconds
uint32_t flush_thresh; ///< Flush threshold in bytes
uint32_t panic_flush_tmo; ///< Panic flush timeout in milliseconds
uint32_t panic_flush_thresh; ///< Panic flush threshold in bytes
} esp_apptrace_config_t;
#ifdef __cplusplus

View File

@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_SYSVIEW_TRACE_H_
#define ESP_SYSVIEW_TRACE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include "esp_err.h"
#include "SEGGER_RTT.h" // SEGGER_RTT_ESP_Flush
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
/**
* @brief Flushes remaining data in SystemView trace buffer to host.
*
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
*
* @return ESP_OK.
*/
static inline esp_err_t esp_sysview_flush(uint32_t tmo)
{
SEGGER_RTT_ESP_Flush(0, tmo);
return ESP_OK;
}
/**
* @brief vprintf-like function to sent log messages to the host.
*
* @param format Address of format string.
* @param args List of arguments.
*
* @return Number of bytes written.
*/
int esp_sysview_vprintf(const char * format, va_list args);
/**
* @brief Starts SystemView heap tracing.
*
* @param tmo Timeout (in us) to wait for the host to be connected. Use -1 to wait forever.
*
* @return ESP_OK on success, ESP_ERR_TIMEOUT if operation has been timed out.
*/
esp_err_t esp_sysview_heap_trace_start(uint32_t tmo);
/**
* @brief Stops SystemView heap tracing.
*
* @return ESP_OK.
*/
esp_err_t esp_sysview_heap_trace_stop(void);
/**
* @brief Sends heap allocation event to the host.
*
* @param addr Address of allocated block.
* @param size Size of allocated block.
* @param callers Pointer to array with callstack addresses.
* Array size must be CONFIG_HEAP_TRACING_STACK_DEPTH.
*/
void esp_sysview_heap_trace_alloc(void *addr, uint32_t size, const void *callers);
/**
* @brief Sends heap de-allocation event to the host.
*
* @param addr Address of de-allocated block.
* @param callers Pointer to array with callstack addresses.
* Array size must be CONFIG_HEAP_TRACING_STACK_DEPTH.
*/
void esp_sysview_heap_trace_free(void *addr, const void *callers);
#ifdef __cplusplus
}
#endif
#endif //ESP_SYSVIEW_TRACE_H_

View File

@@ -1,11 +1,24 @@
[mapping:app_trace]
archive: libapp_trace.a
entries:
if ESP_TRACE_TRANSPORT_APPTRACE = y:
if APPTRACE_ENABLE = y:
app_trace (noflash)
app_trace_util (noflash)
if APPTRACE_DEST_JTAG = y || APPTRACE_DEST_ALL = y:
if APPTRACE_DEST_JTAG = y || APPTRACE_DEST_NONE = y:
port_jtag (noflash)
app_trace_membufs_proto (noflash)
if APPTRACE_DEST_UART = y || APPTRACE_DEST_ALL = y:
if APPTRACE_DEST_UART = y || APPTRACE_DEST_NONE = y:
port_uart (noflash)
if APPTRACE_SV_ENABLE = y:
SEGGER_SYSVIEW (noflash)
SEGGER_RTT_esp (noflash)
SEGGER_SYSVIEW_Config_FreeRTOS (noflash)
SEGGER_SYSVIEW_FreeRTOS (noflash)
[mapping:app_trace_driver]
archive: libesp_driver_gptimer.a
entries:
if APPTRACE_SV_TS_SOURCE_GPTIMER = y:
gptimer: gptimer_get_raw_count (noflash)
else:
* (default)

View File

@@ -3,118 +3,45 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include "esp_err.h"
#include "soc/soc.h"
#include "esp_log.h"
#include "esp_cpu.h"
#include "esp_attr.h"
#include "esp_private/uart_share_hw_ctrl.h"
#include "hal/uart_hal.h"
#include "hal/gpio_hal.h"
#include "driver/uart.h"
#include "soc/uart_periph.h"
#include "esp_clk_tree.h"
#include "esp_private/esp_clk_tree_common.h"
#include "soc/gpio_periph.h"
#include "esp_rom_gpio.h"
#include "hal/uart_ll.h"
#include "esp_intr_alloc.h"
#include "esp_heap_caps.h"
#include "esp_private/esp_gpio_reserve.h"
#include "esp_app_trace_config.h"
#include "esp_app_trace_port.h"
#include "esp_app_trace_util.h"
#include "esp_app_trace_types.h"
static const char *TAG = "esp_apptrace_uart";
#include "driver/uart.h"
#include "hal/uart_ll.h"
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
/** UART HW transport data */
typedef struct {
uint8_t inited;
#if CONFIG_APPTRACE_LOCK_ENABLE
esp_apptrace_lock_t lock; // sync lock
#endif
uart_port_t port_num;
typedef struct {
uint8_t *buffer; ///< Ring buffer data
uint32_t max_size; ///< Ring buffer maximum size (must be power of 2)
volatile uint32_t count; ///< Number of bytes currently in the buffer
volatile uint32_t head; ///< Write pointer index
volatile uint32_t tail; ///< Read pointer index
} esp_apptrace_uart_rb_t;
typedef struct {
int inited;
volatile bool tx_busy; ///< TX busy flag
uart_hal_context_t hal_ctx; ///< UART HAL context
esp_apptrace_uart_rb_t tx_ring; ///< TX ring buffer
intr_handle_t intr_handle; ///< Interrupt handle
/* TX data ring buffer */
uint8_t *tx_data_buff;
uint32_t tx_data_buff_size;
int32_t tx_data_buff_in;
int32_t tx_data_buff_out;
/* TX message buffer */
uint8_t *tx_msg_buff; ///< TX message buffer to provide with get_up_buffer
uint32_t tx_msg_buff_size; ///< TX message buffer size & maximum size of the single message to transfer.
uint32_t tx_pending_msg_size; ///< Pending message size to send with put_up_buffer
uint8_t *tx_msg_buff;
uint32_t tx_msg_buff_size;
uint32_t tx_pending_msg_size;
/* RX message buffer */
uint8_t *rx_msg_buff; ///< RX message buffer provided with down_buffer_config function
uint32_t rx_msg_buff_size; ///< RX message buffer size provided with down_buffer_config function
#if CONFIG_APPTRACE_LOCK_ENABLE
esp_apptrace_lock_t lock; ///< Sync lock
#endif
uint8_t *down_buffer;
uint32_t down_buffer_size;
/* Buffer overflow flags */
bool message_buff_overflow;
bool circular_buff_overflow;
} esp_apptrace_uart_data_t;
static inline bool is_power_of_two(uint32_t n)
{
return n != 0 && (n & (n - 1)) == 0;
}
static inline uint32_t ring_buffer_mask(const esp_apptrace_uart_rb_t *rb)
{
return rb->max_size - 1;
}
/* Get the length of the data in the ring buffer */
static inline uint32_t ring_buffer_data_len(const esp_apptrace_uart_rb_t *rb)
{
return rb->count;
}
/* Get the length of the free space in the ring buffer */
static inline uint32_t ring_buffer_free_len(const esp_apptrace_uart_rb_t *rb)
{
return rb->max_size - rb->count;
}
static inline void ring_buffer_advance_tail(esp_apptrace_uart_rb_t *rb, uint32_t count)
{
rb->tail = (rb->tail + count) & ring_buffer_mask(rb);
rb->count -= count;
}
static inline void ring_buffer_advance_head(esp_apptrace_uart_rb_t *rb, uint32_t count)
{
rb->head = (rb->head + count) & ring_buffer_mask(rb);
rb->count += count;
}
static inline uint32_t ring_buffer_calc_to_send(const esp_apptrace_uart_rb_t *rb, uint32_t tx_msg_size)
{
uint32_t used = ring_buffer_data_len(rb);
if (used == 0) {
return 0;
}
uint32_t cont = rb->max_size - rb->tail;
uint32_t n = MIN(used, cont);
/* Apply message size limit if specified */
if (tx_msg_size && tx_msg_size < n) {
return tx_msg_size;
}
return n;
}
const static char *TAG = "esp_apptrace_uart";
static esp_err_t esp_apptrace_uart_lock(void *hw_data, esp_apptrace_tmo_t *tmo)
{
@@ -134,320 +61,271 @@ static esp_err_t esp_apptrace_uart_unlock(void *hw_data)
#if CONFIG_APPTRACE_LOCK_ENABLE
esp_apptrace_uart_data_t *uart_data = hw_data;
ret = esp_apptrace_lock_give(&uart_data->lock);
assert(ret == ESP_OK && "Failed to unlock apptrace uart lock!");
#endif
return ret;
}
static esp_err_t ring_buffer_put(esp_apptrace_uart_rb_t *rb, const uint8_t *data, uint32_t len)
static inline void esp_apptrace_uart_hw_init(void)
{
/* Drop oldest. Make available space if needed */
uint32_t free_len = ring_buffer_free_len(rb);
if (len > free_len) {
uint32_t need = len - free_len;
ring_buffer_advance_tail(rb, need);
ESP_APPTRACE_LOGI("Initialized UART on CPU%d", esp_cpu_get_core_id());
}
/*****************************************************************************************/
/***************************** Apptrace HW iface *****************************************/
/*****************************************************************************************/
static esp_err_t esp_apptrace_send_uart_data(void *hw_data, const char *data, uint32_t size, esp_apptrace_tmo_t *tmo)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
if (res != ESP_OK) {
return res;
}
// We store current out position to handle it without lock
volatile int32_t out_position = uart_data->tx_data_buff_out;
uint32_t head = rb->head;
uint32_t space_to_end = rb->max_size - head;
if (len <= space_to_end) {
memcpy(&rb->buffer[head], data, len);
int len_free = uart_data->tx_data_buff_size - (uart_data->tx_data_buff_in - out_position);
if (out_position > uart_data->tx_data_buff_in) {
len_free = out_position - uart_data->tx_data_buff_in;
}
int check_len = uart_data->tx_data_buff_size - uart_data->tx_data_buff_in;
if (size <= len_free) {
if (check_len >= size) {
memcpy(&uart_data->tx_data_buff[uart_data->tx_data_buff_in], data, size);
uart_data->tx_data_buff_in += size;
} else {
memcpy(&uart_data->tx_data_buff[uart_data->tx_data_buff_in],
data,
uart_data->tx_data_buff_size - uart_data->tx_data_buff_in);
memcpy(&uart_data->tx_data_buff[0],
&data[uart_data->tx_data_buff_size - uart_data->tx_data_buff_in],
size - (uart_data->tx_data_buff_size - uart_data->tx_data_buff_in));
uart_data->tx_data_buff_in = size - (uart_data->tx_data_buff_size - uart_data->tx_data_buff_in);
}
if (uart_data->tx_data_buff_in >= uart_data->tx_data_buff_size) {
uart_data->tx_data_buff_in = 0;
}
} else {
memcpy(&rb->buffer[head], data, space_to_end);
memcpy(&rb->buffer[0], &data[space_to_end], len - space_to_end);
uart_data->circular_buff_overflow = true;
}
ring_buffer_advance_head(rb, len);
if (esp_apptrace_uart_unlock(uart_data) != ESP_OK) {
assert(false && "Failed to unlock apptrace data!");
}
return ESP_OK;
}
static esp_err_t ring_buffer_init(esp_apptrace_uart_rb_t *rb, uint32_t size)
static void send_buff_data(void *hw_data, esp_apptrace_tmo_t *tmo)
{
rb->buffer = heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (!rb->buffer) {
return ESP_ERR_NO_MEM;
esp_apptrace_uart_data_t *uart_data = hw_data;
if (uart_data->tx_data_buff_in == uart_data->tx_data_buff_out) {
return;
}
// We store current in position to handle it without lock
volatile int32_t in_position = uart_data->tx_data_buff_in;
if (in_position > uart_data->tx_data_buff_out) {
int bytes_sent = uart_write_bytes(uart_data->port_num,
&uart_data->tx_data_buff[uart_data->tx_data_buff_out],
in_position - uart_data->tx_data_buff_out);
uart_data->tx_data_buff_out += bytes_sent;
} else {
int bytes_sent = uart_write_bytes(uart_data->port_num,
&uart_data->tx_data_buff[uart_data->tx_data_buff_out],
uart_data->tx_data_buff_size - uart_data->tx_data_buff_out);
uart_data->tx_data_buff_out += bytes_sent;
if (uart_data->tx_data_buff_out >= uart_data->tx_data_buff_size) {
uart_data->tx_data_buff_out = 0;
}
}
rb->max_size = size;
rb->count = 0;
rb->head = 0;
rb->tail = 0;
return ESP_OK;
}
static void IRAM_ATTR esp_apptrace_uart_isr_handler(void *arg)
#define APP_TRACE_UART_STOP_WAIT_TMO 1000000 //us
static void esp_apptrace_send_uart_tx_task(void *arg)
{
esp_apptrace_uart_data_t *uart_data = arg;
esp_apptrace_uart_rb_t *rb = &uart_data->tx_ring;
esp_apptrace_tmo_t tmo;
uint32_t intr_status = uart_hal_get_intsts_mask(&uart_data->hal_ctx);
esp_apptrace_tmo_init(&tmo, APP_TRACE_UART_STOP_WAIT_TMO);
if (intr_status & UART_INTR_TXFIFO_EMPTY) {
uart_hal_clr_intsts_mask(&uart_data->hal_ctx, UART_INTR_TXFIFO_EMPTY);
uint32_t to_send = ring_buffer_calc_to_send(rb, uart_data->tx_msg_buff_size);
if (to_send > 0) {
uint32_t written = 0;
uart_hal_write_txfifo(&uart_data->hal_ctx, &rb->buffer[rb->tail], to_send, &written);
ring_buffer_advance_tail(rb, written);
vTaskDelay(10);
while (1) {
send_buff_data(uart_data, &tmo);
vTaskDelay(10);
if (uart_data->circular_buff_overflow == true) {
uart_data->circular_buff_overflow = false;
ESP_LOGE(TAG, "Buffer overflow. Please increase UART baudrate, or increase UART TX ring buffer size in menuconfig.");
}
/* If ring buffer is empty, disable TX interrupt */
if (ring_buffer_data_len(rb) == 0) {
uart_ll_disable_intr_mask(uart_data->hal_ctx.dev, UART_INTR_TXFIFO_EMPTY);
uart_data->tx_busy = false;
if (uart_data->message_buff_overflow == true) {
uart_data->message_buff_overflow = false;
ESP_LOGE(TAG, "Message size more then message buffer!");
}
}
}
static const int APP_TRACE_UART_RX_BUF_SIZE = 4024;
static esp_err_t esp_apptrace_uart_init(void *hw_data, const esp_apptrace_config_t *config)
{
esp_err_t ret = ESP_ERR_INVALID_ARG;
uint64_t gpio_mask = 0;
esp_apptrace_uart_data_t *uart_data = hw_data;
const esp_apptrace_uart_config_t *uart_config = &config->dest_cfg.uart;
const esp_apptrace_uart_config_t *apptrace_uart_config = &config->dest_cfg.uart;
/* Init function is called on every core, so ensure to do main setup only once */
/* esp_apptrace_uart_init() is called on every core, so ensure to do main initialization only once */
int core_id = esp_cpu_get_core_id();
if (core_id == 0) {
if (uart_config->uart_num == CONFIG_ESP_CONSOLE_UART_NUM) {
ESP_APPTRACE_LOGE("Application trace UART and console UART cannot use the same port number");
return ESP_ERR_INVALID_ARG;
uart_data->tx_data_buff_size = apptrace_uart_config->tx_buff_size;
uart_data->tx_data_buff = heap_caps_malloc(uart_data->tx_data_buff_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (uart_data->tx_data_buff == NULL) {
return ESP_ERR_NO_MEM;
}
if (uart_config->uart_num >= SOC_UART_HP_NUM) {
ESP_APPTRACE_LOGE("UART port number %d is not supported!", uart_config->uart_num);
return ESP_ERR_NOT_SUPPORTED;
}
if (GPIO_IS_VALID_GPIO(uart_config->tx_pin_num)) {
gpio_mask |= BIT64(uart_config->tx_pin_num);
}
if (GPIO_IS_VALID_GPIO(uart_config->rx_pin_num)) {
gpio_mask |= BIT64(uart_config->rx_pin_num);
}
if (gpio_mask == 0) {
ESP_LOGE(TAG, "No valid GPIOs to reserve");
return ESP_ERR_INVALID_STATE;
}
uint64_t r = esp_gpio_reserve(gpio_mask);
if (r & gpio_mask) {
ESP_LOGE(TAG, "GPIO(s) are already reserved: 0x%"PRIx64, r & gpio_mask);
return ESP_ERR_INVALID_STATE;
}
uart_data->hal_ctx.dev = UART_LL_GET_HW(uart_config->uart_num);
HP_UART_BUS_CLK_ATOMIC() {
uart_ll_enable_bus_clock(uart_config->uart_num, true);
uart_ll_reset_register(uart_config->uart_num);
}
HP_UART_SRC_CLK_ATOMIC() {
uart_ll_sclk_enable(uart_data->hal_ctx.dev);
}
uint32_t sclk_hz;
esp_clk_tree_src_get_freq_hz(UART_SCLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_hz);
/* Enable the default clock source */
esp_clk_tree_enable_src(UART_SCLK_DEFAULT, true);
/* Initialize UART HAL (sets default 8N1 mode) */
uart_hal_init(&uart_data->hal_ctx, uart_config->uart_num);
ESP_LOGI(TAG, "uart_hal_init: %d", uart_config->uart_num);
HP_UART_SRC_CLK_ATOMIC() {
uart_hal_set_sclk(&uart_data->hal_ctx, UART_SCLK_DEFAULT);
uart_hal_set_baudrate(&uart_data->hal_ctx, uart_config->baud_rate, sclk_hz);
}
/* Configure FIFO thresholds */
uart_hal_set_txfifo_empty_thr(&uart_data->hal_ctx, 16); /* Slow down IRQ rate */
uart_hal_set_rxfifo_full_thr(&uart_data->hal_ctx, 1);
/* Initialize TX ring buffer */
if (uart_config->tx_buff_size == 0 || !is_power_of_two(uart_config->tx_buff_size)) {
ESP_APPTRACE_LOGE("TX ring buffer size (%u) must be a power of two and greater than 0",
uart_config->tx_buff_size);
goto err_init_ring_buff;
}
ret = ring_buffer_init(&uart_data->tx_ring, uart_config->tx_buff_size);
if (ret != ESP_OK) {
ESP_APPTRACE_LOGE("Failed to initialize TX ring buffer");
goto err_init_ring_buff;
}
/* Initialize TX message buffer for providing with get_up_buffer */
uart_data->tx_msg_buff_size = uart_config->tx_msg_size;
uart_data->tx_data_buff_in = 0;
uart_data->tx_data_buff_out = 0;
uart_data->tx_msg_buff_size = apptrace_uart_config->tx_msg_size;
uart_data->tx_msg_buff = heap_caps_malloc(uart_data->tx_msg_buff_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (uart_data->tx_msg_buff == NULL) {
ESP_APPTRACE_LOGE("Failed to initialize TX message buffer");
ret = ESP_ERR_NO_MEM;
goto err_alloc_msg_buff;
return ESP_ERR_NO_MEM;
}
uart_data->tx_pending_msg_size = 0;
uart_data->down_buffer_size = 0;
uart_data->message_buff_overflow = false;
uart_data->circular_buff_overflow = false;
/* Disable all interrupts and clear status */
uart_ll_disable_intr_mask(uart_data->hal_ctx.dev, UART_LL_INTR_MASK);
uart_ll_clr_intsts_mask(uart_data->hal_ctx.dev, UART_LL_INTR_MASK);
assert((uart_data->port_num <= SOC_UART_NUM) && "Not possible to configure UART. Please check selected UART port");
/* Install interrupt handler */
int intr_alloc_flags = 0;
ret = esp_intr_alloc(uart_periph_signal[uart_config->uart_num].irq, intr_alloc_flags,
esp_apptrace_uart_isr_handler, uart_data, &uart_data->intr_handle);
if (ret != ESP_OK) {
ESP_APPTRACE_LOGE("Failed to allocate interrupt: %s", esp_err_to_name(ret));
goto err_alloc_intr;
int source_clk = UART_SCLK_DEFAULT;
#if SOC_UART_LP_NUM > 0
if (uart_data->port_num >= SOC_UART_HP_NUM) {
source_clk = LP_UART_SCLK_DEFAULT;
}
#endif
/* Reset FIFOs */
uart_hal_rxfifo_rst(&uart_data->hal_ctx);
uart_hal_txfifo_rst(&uart_data->hal_ctx);
const uart_config_t uart_config = {
.baud_rate = apptrace_uart_config->baud_rate,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = source_clk,
};
ESP_LOGI(TAG, "UART baud rate: %i", apptrace_uart_config->baud_rate);
// We won't use a buffer for sending data.
esp_err_t __attribute__((unused)) err = uart_driver_install(uart_data->port_num,
APP_TRACE_UART_RX_BUF_SIZE,
APP_TRACE_UART_RX_BUF_SIZE,
0,
NULL,
0);
assert((err == ESP_OK) && "Not possible to install UART. Please check and change uart parameters!");
err = uart_param_config(uart_data->port_num, &uart_config);
assert((err == ESP_OK) && "Not possible to configure UART. Please check and change uart parameters!");
err = uart_set_pin(uart_data->port_num,
apptrace_uart_config->tx_pin_num,
apptrace_uart_config->rx_pin_num,
UART_PIN_NO_CHANGE,
UART_PIN_NO_CHANGE);
assert((err == ESP_OK) && "Not possible to configure UART RX/TX pins. Please check and change the uart pins!");
/* Configure GPIO pins for RX and TX */
const uint32_t tx_idx = UART_PERIPH_SIGNAL(uart_config->uart_num, SOC_UART_PERIPH_SIGNAL_TX);
const uint32_t rx_idx = UART_PERIPH_SIGNAL(uart_config->uart_num, SOC_UART_PERIPH_SIGNAL_RX);
/* Configure TX pin */
gpio_ll_func_sel(&GPIO, uart_config->tx_pin_num, PIN_FUNC_GPIO);
esp_rom_gpio_pad_pullup_only(uart_config->tx_pin_num);
esp_rom_gpio_connect_out_signal(uart_config->tx_pin_num, tx_idx, 0, 0);
/* Configure RX pin */
gpio_ll_input_enable(&GPIO, uart_config->rx_pin_num);
esp_rom_gpio_pad_pullup_only(uart_config->rx_pin_num);
esp_rom_gpio_connect_in_signal(uart_config->rx_pin_num, rx_idx, 0);
int uart_prio = apptrace_uart_config->task_prio;
if (uart_prio >= (configMAX_PRIORITIES - 1)) {
uart_prio = configMAX_PRIORITIES - 1;
}
err = xTaskCreate(esp_apptrace_send_uart_tx_task, "app_trace_uart_tx_task", 2500, uart_data, uart_prio, NULL);
assert((err == pdPASS) && "Not possible to configure UART. Not possible to create task!");
#if CONFIG_APPTRACE_LOCK_ENABLE
esp_apptrace_lock_init(&uart_data->lock);
#endif
}
// init UART on this CPU
esp_apptrace_uart_hw_init();
uart_data->inited |= 1 << core_id;
uart_data->tx_busy = false;
return ESP_OK;
err_alloc_intr:
heap_caps_free(uart_data->tx_msg_buff);
err_alloc_msg_buff:
heap_caps_free(uart_data->tx_ring.buffer);
err_init_ring_buff:
esp_clk_tree_enable_src(UART_SCLK_DEFAULT, false);
HP_UART_SRC_CLK_ATOMIC() {
uart_ll_sclk_disable(uart_data->hal_ctx.dev);
}
HP_UART_BUS_CLK_ATOMIC() {
uart_ll_enable_bus_clock(uart_config->uart_num, false);
}
esp_gpio_revoke(gpio_mask);
return ret;
}
static uint8_t *esp_apptrace_uart_up_buffer_get(void *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
if (size == 0 || size > uart_data->tx_msg_buff_size) {
if (size > uart_data->tx_msg_buff_size) {
uart_data->message_buff_overflow = true;
return NULL;
}
if (esp_apptrace_uart_lock(uart_data, tmo) != ESP_OK) {
return NULL;
}
if (uart_data->tx_pending_msg_size != 0) {
// A previous message was not sent.
esp_apptrace_uart_unlock(uart_data);
return NULL;
}
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
if (res != ESP_OK) {
return NULL;
}
uint8_t *ptr = uart_data->tx_msg_buff;
// Set the amount of data to send
uart_data->tx_pending_msg_size = size;
esp_apptrace_uart_unlock(uart_data);
return uart_data->tx_msg_buff;
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
if (esp_apptrace_uart_unlock(uart_data) != ESP_OK) {
assert(false && "Failed to unlock apptrace data!");
}
return ptr;
}
static esp_err_t esp_apptrace_uart_up_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
esp_apptrace_uart_rb_t *rb = &uart_data->tx_ring;
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
if (res != ESP_OK) {
return res;
}
/* Add data to ring buffer */
ring_buffer_put(rb, ptr, uart_data->tx_pending_msg_size);
esp_err_t res = esp_apptrace_send_uart_data(uart_data, (const char *)ptr, uart_data->tx_pending_msg_size, tmo);
// Clear size to indicate that we've sent data
uart_data->tx_pending_msg_size = 0;
esp_apptrace_uart_unlock(uart_data);
// Trigger transmission if not already in progress
if (!uart_data->tx_busy) {
uart_data->tx_busy = true;
/* Enable TX interrupt */
uart_ll_clr_intsts_mask(uart_data->hal_ctx.dev, UART_INTR_TXFIFO_EMPTY);
uart_ll_ena_intr_mask(uart_data->hal_ctx.dev, UART_INTR_TXFIFO_EMPTY);
}
return ESP_OK;
return res;
}
static void esp_apptrace_uart_down_buffer_config(void *hw_data, uint8_t *buf, uint32_t size)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
assert(buf != NULL && "Down buffer cannot be NULL");
assert(size > 0 && "Down buffer size must be greater than 0");
uart_data->rx_msg_buff = buf;
uart_data->rx_msg_buff_size = size;
uart_data->down_buffer = (uint8_t *)malloc(size);
if (uart_data->down_buffer == NULL) {
assert(false && "Failed to allocate apptrace uart down buffer!");
}
uart_data->down_buffer_size = size;
}
static uint8_t *esp_apptrace_uart_down_buffer_get(void *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
if (!size || *size == 0) {
uint8_t *ptr = NULL;
if (*size > uart_data->down_buffer_size) {
return NULL;
}
if (!uart_data->rx_msg_buff) {
ESP_APPTRACE_LOGE("RX message buffer is not configured. Call down_buffer_config() first.");
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
if (res != ESP_OK) {
return NULL;
}
if (esp_apptrace_uart_lock(uart_data, tmo) != ESP_OK) {
return NULL;
size_t uart_fifolen = 0;
uart_get_buffered_data_len(uart_data->port_num, &uart_fifolen);
if (uart_fifolen > 0) {
if (*size < uart_fifolen) {
uart_fifolen = *size;
}
*size = uart_fifolen;
ptr = uart_data->down_buffer;
*size = uart_read_bytes(uart_data->port_num, ptr, uart_fifolen, 0);
}
uint32_t rx_len = uart_ll_get_rxfifo_len(uart_data->hal_ctx.dev);
int to_read = MIN(rx_len, MIN(uart_data->rx_msg_buff_size, *size));
if (to_read) {
uart_hal_read_rxfifo(&uart_data->hal_ctx, uart_data->rx_msg_buff, &to_read);
if (esp_apptrace_uart_unlock(uart_data) != ESP_OK) {
assert(false && "Failed to unlock apptrace data!");
}
*size = to_read;
esp_apptrace_uart_unlock(uart_data);
return (*size > 0) ? uart_data->rx_msg_buff : NULL;
return ptr;
}
static esp_err_t esp_apptrace_uart_down_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
{
(void)hw_data;
(void)ptr;
(void)tmo;
/* No action needed - data was already read in get function */
return ESP_OK;
}
@@ -460,50 +338,17 @@ static bool esp_apptrace_uart_host_is_connected(void *hw_data)
static esp_err_t esp_apptrace_uart_flush_nolock(void *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
esp_apptrace_uart_rb_t *rb = &uart_data->tx_ring;
uint32_t pending = ring_buffer_data_len(rb);
if (pending < min_sz) {
ESP_APPTRACE_LOGD("Ignore UART flush request for min %" PRIu32 " bytes. Pending bytes: %" PRIu32, min_sz, pending);
return ESP_OK;
}
/* Trigger transmission if there's data but not busy */
if (pending > 0 && !uart_data->tx_busy) {
uart_data->tx_busy = true;
uart_ll_clr_intsts_mask(uart_data->hal_ctx.dev, UART_INTR_TXFIFO_EMPTY);
uart_ll_ena_intr_mask(uart_data->hal_ctx.dev, UART_INTR_TXFIFO_EMPTY);
}
while (uart_data->tx_busy || ring_buffer_data_len(rb) > 0) {
if (esp_apptrace_tmo_check(tmo) != ESP_OK) {
return ESP_ERR_TIMEOUT;
}
esp_rom_delay_us(100);
}
return ESP_OK;
}
static esp_err_t esp_apptrace_uart_flush(void *hw_data, esp_apptrace_tmo_t *tmo)
{
esp_apptrace_uart_data_t *uart_data = hw_data;
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
if (res != ESP_OK) {
return res;
}
esp_err_t ret = esp_apptrace_uart_flush_nolock(hw_data, 0, tmo);
esp_apptrace_uart_unlock(uart_data);
return ret;
return ESP_OK;
}
esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
{
ESP_APPTRACE_LOGD("esp_apptrace_uart_hw_get - %i", num);
ESP_LOGD(TAG, "esp_apptrace_uart_hw_get - %i", num);
static esp_apptrace_uart_data_t s_uart_hw_data;
static esp_apptrace_hw_t s_uart_hw = {
@@ -517,6 +362,7 @@ esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
.put_down_buffer = esp_apptrace_uart_down_buffer_put,
.host_is_connected = esp_apptrace_uart_host_is_connected,
};
s_uart_hw_data.port_num = num;
*data = &s_uart_hw_data;
return &s_uart_hw;
}

View File

@@ -3,10 +3,27 @@
CONFIG_ESP32_APPTRACE_DESTINATION CONFIG_APPTRACE_DESTINATION
CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_JTAG
CONFIG_ESP32_APPTRACE_ENABLE CONFIG_ESP_TRACE_TRANSPORT_APPTRACE
CONFIG_ESP32_APPTRACE_ENABLE CONFIG_APPTRACE_ENABLE
CONFIG_ESP32_APPTRACE_LOCK_ENABLE CONFIG_APPTRACE_LOCK_ENABLE
CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO
CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH
CONFIG_SYSVIEW_TS_SOURCE_CCOUNT CONFIG_ESP_TRACE_TS_SOURCE_CCOUNT
CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER CONFIG_ESP_TRACE_TS_SOURCE_ESP_TIMER
CONFIG_SYSVIEW_ENABLE CONFIG_APPTRACE_SV_ENABLE
CONFIG_SYSVIEW_TS_SOURCE CONFIG_APPTRACE_SV_TS_SOURCE
CONFIG_SYSVIEW_TS_SOURCE_CCOUNT CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
CONFIG_SYSVIEW_MAX_TASKS CONFIG_APPTRACE_SV_MAX_TASKS
CONFIG_SYSVIEW_BUF_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE
CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE
CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE
CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE
CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE
CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
CONFIG_SYSVIEW_EVT_IDLE_ENABLE CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE
CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE

View File

@@ -0,0 +1,118 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.42 *
* *
**********************************************************************
----------------------------------------------------------------------
File : Global.h
Purpose : Global types
In case your application already has a Global.h, you should
merge the files. In order to use Segger code, the types
U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
additional definitions do not hurt.
Revision: $Rev: 12501 $
---------------------------END-OF-HEADER------------------------------
*/
#ifndef GLOBAL_H // Guard against multiple inclusion
#define GLOBAL_H
#define U8 unsigned char
#define I8 signed char
#define U16 unsigned short
#define I16 signed short
#ifdef __x86_64__
#define U32 unsigned
#define I32 int
#else
#define U32 unsigned long
#define I32 signed long
#endif
//
// CC_NO_LONG_SUPPORT can be defined to compile test
// without long support for compilers that do not
// support C99 and its long type.
//
#ifdef CC_NO_LONG_SUPPORT
#define PTR_ADDR U32
#else // Supports long type.
#if defined(_WIN32) && !defined(__clang__) && !defined(__MINGW32__)
//
// Microsoft VC6 compiler related
//
#define U64 unsigned __int64
#define U128 unsigned __int128
#define I64 __int64
#define I128 __int128
#if _MSC_VER <= 1200
#define U64_C(x) x##UI64
#else
#define U64_C(x) x##ULL
#endif
#else
//
// C99 compliant compiler
//
#define U64 unsigned long long
#define I64 signed long long
#define U64_C(x) x##ULL
#endif
#if (defined(_WIN64) || defined(__LP64__)) // 64-bit symbols used by Visual Studio and GCC, maybe others as well.
#define PTR_ADDR U64
#else
#define PTR_ADDR U32
#endif
#endif // Supports long type.
#endif // Avoid multiple inclusion
/*************************** End of file ****************************/

View File

@@ -0,0 +1,433 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.42 *
* *
**********************************************************************
---------------------------END-OF-HEADER------------------------------
File : SEGGER_RTT_Conf.h
Purpose : Implementation of SEGGER real-time transfer (RTT) which
allows real-time communication on targets which support
debugger memory accesses while the CPU is running.
Revision: $Rev: 24316 $
*/
#ifndef SEGGER_RTT_CONF_H
#define SEGGER_RTT_CONF_H
#ifdef __IAR_SYSTEMS_ICC__
#include <intrinsics.h>
#endif
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
//
// Take in and set to correct values for Cortex-A systems with CPU cache
//
//#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (32) // Largest cache line size (in bytes) in the current system
//#define SEGGER_RTT_UNCACHED_OFF (0xFB000000) // Address alias where RTT CB and buffers can be accessed uncached
//
// Most common case:
// Up-channel 0: RTT
// Up-channel 1: SystemView
//
#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
#endif
//
// Most common case:
// Down-channel 0: RTT
// Down-channel 1: SystemView
//
#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
#endif
#ifndef BUFFER_SIZE_UP
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
#endif
#ifndef BUFFER_SIZE_DOWN
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
#endif
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
#endif
#ifndef SEGGER_RTT_MODE_DEFAULT
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
#endif
/*********************************************************************
*
* RTT memcpy configuration
*
* memcpy() is good for large amounts of data,
* but the overhead is big for small amounts, which are usually stored via RTT.
* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead.
*
* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions.
* This is may be required with memory access restrictions,
* such as on Cortex-A devices with MMU.
*/
#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop
#endif
//
// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets
//
//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__))
// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes))
//#endif
//
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
// Otherwise we would probably end up with a mixed string in the buffer.
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
//
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
// (Higher priority = lower priority number)
// Default value for embOS: 128u
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
//
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
#endif
/*********************************************************************
*
* RTT lock configuration for SEGGER Embedded Studio,
* Rowley CrossStudio and GCC
*/
#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32))
#if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
__asm volatile ("mrs %0, primask \n\t" \
"movs r1, #1 \n\t" \
"msr primask, r1 \n\t" \
: "=r" (_SEGGER_RTT__LockState) \
: \
: "r1", "cc" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
: \
: "r" (_SEGGER_RTT__LockState) \
: \
); \
}
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
__asm volatile ("mrs %0, basepri \n\t" \
"mov r1, %1 \n\t" \
"msr basepri, r1 \n\t" \
: "=r" (_SEGGER_RTT__LockState) \
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
: "r1", "cc" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
: \
: "r" (_SEGGER_RTT__LockState) \
: \
); \
}
#elif (defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__))
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
__asm volatile ("mrs r1, CPSR \n\t" \
"mov %0, r1 \n\t" \
"orr r1, r1, #0xC0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: "=r" (_SEGGER_RTT__LockState) \
: \
: "r1", "cc" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
"mrs r1, CPSR \n\t" \
"bic r1, r1, #0xC0 \n\t" \
"and r0, r0, #0xC0 \n\t" \
"orr r1, r1, r0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: \
: "r" (_SEGGER_RTT__LockState) \
: "r0", "r1", "cc" \
); \
}
#elif defined(__riscv) || defined(__riscv_xlen)
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
__asm volatile ("csrr %0, mstatus \n\t" \
"csrci mstatus, 8 \n\t" \
"andi %0, %0, 8 \n\t" \
: "=r" (_SEGGER_RTT__LockState) \
: \
: \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \
"or %0, %0, a1 \n\t" \
"csrs mstatus, %0 \n\t" \
: \
: "r" (_SEGGER_RTT__LockState) \
: "a1" \
); \
}
#else
#define SEGGER_RTT_LOCK()
#define SEGGER_RTT_UNLOCK()
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for IAR EWARM
*/
#ifdef __ICCARM__
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \
(defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__))
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = __get_PRIMASK(); \
__set_PRIMASK(1);
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \
}
#elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \
(defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \
(defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \
(defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = __get_BASEPRI(); \
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(_SEGGER_RTT__LockState); \
}
#elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__)) || \
(defined (__ARM7R__) && (__CORE__ == __ARM7R__))
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
__asm volatile ("mrs r1, CPSR \n\t" \
"mov %0, r1 \n\t" \
"orr r1, r1, #0xC0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: "=r" (_SEGGER_RTT__LockState) \
: \
: "r1", "cc" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
"mrs r1, CPSR \n\t" \
"bic r1, r1, #0xC0 \n\t" \
"and r0, r0, #0xC0 \n\t" \
"orr r1, r1, r0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: \
: "r" (_SEGGER_RTT__LockState) \
: "r0", "r1", "cc" \
); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for IAR RX
*/
#ifdef __ICCRX__
#define SEGGER_RTT_LOCK() { \
unsigned long _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = __get_interrupt_state(); \
__disable_interrupt();
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \
}
#endif
/*********************************************************************
*
* RTT lock configuration for IAR RL78
*/
#ifdef __ICCRL78__
#define SEGGER_RTT_LOCK() { \
__istate_t _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = __get_interrupt_state(); \
__disable_interrupt();
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \
}
#endif
/*********************************************************************
*
* RTT lock configuration for KEIL ARM
*/
#ifdef __CC_ARM
#if (defined __TARGET_ARCH_6S_M)
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask"); \
_SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK; \
_SEGGER_RTT__PRIMASK = 1u; \
__schedule_barrier();
#define SEGGER_RTT_UNLOCK() _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState; \
__schedule_barrier(); \
}
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
register unsigned char BASEPRI __asm( "basepri"); \
_SEGGER_RTT__LockState = BASEPRI; \
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
__schedule_barrier();
#define SEGGER_RTT_UNLOCK() BASEPRI = _SEGGER_RTT__LockState; \
__schedule_barrier(); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for TI ARM
*/
#ifdef __TI_ARM__
#if defined (__TI_ARM_V6M0__)
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = __get_PRIMASK(); \
__set_PRIMASK(1);
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \
}
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
#define SEGGER_RTT_UNLOCK() _set_interrupt_priority(_SEGGER_RTT__LockState); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for CCRX
*/
#ifdef __RX
#include <machine.h>
#define SEGGER_RTT_LOCK() { \
unsigned long _SEGGER_RTT__LockState; \
_SEGGER_RTT__LockState = get_psw() & 0x010000; \
clrpsw_i();
#define SEGGER_RTT_UNLOCK() set_psw(get_psw() | _SEGGER_RTT__LockState); \
}
#endif
/*********************************************************************
*
* RTT lock configuration for embOS Simulation on Windows
* (Can also be used for generic RTT locking with embOS)
*/
#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS)
void OS_SIM_EnterCriticalSection(void);
void OS_SIM_LeaveCriticalSection(void);
#define SEGGER_RTT_LOCK() { \
OS_SIM_EnterCriticalSection();
#define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \
}
#endif
/*********************************************************************
*
* RTT lock configuration fallback
*/
#ifndef SEGGER_RTT_LOCK
#define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts)
#endif
#ifndef SEGGER_RTT_UNLOCK
#define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
#endif
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,90 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.42 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Conf.h
Purpose : SEGGER SystemView configuration file.
Set defines which deviate from the defaults (see SEGGER_SYSVIEW_ConfDefaults.h) here.
Revision: $Rev: 21292 $
Additional information:
Required defines which must be set are:
SEGGER_SYSVIEW_GET_TIMESTAMP
SEGGER_SYSVIEW_GET_INTERRUPT_ID
For known compilers and cores, these might be set to good defaults
in SEGGER_SYSVIEW_ConfDefaults.h.
SystemView needs a (nestable) locking mechanism.
If not defined, the RTT locking mechanism is used,
which then needs to be properly configured.
*/
#ifndef SEGGER_SYSVIEW_CONF_H
#define SEGGER_SYSVIEW_CONF_H
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
/*********************************************************************
* TODO: Add your defines here. *
**********************************************************************
*/
#endif // SEGGER_SYSVIEW_CONF_H
/*************************** End of file ****************************/

View File

@@ -0,0 +1,255 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*
* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2024 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.56 *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER.h
Purpose : Global types etc & general purpose utility functions
Revision: $Rev: 18102 $
---------------------------END-OF-HEADER------------------------------
*/
#ifndef SEGGER_H // Guard against multiple inclusion
#define SEGGER_H
#include <stdarg.h> // For va_list.
#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
#if defined(__cplusplus)
extern "C" { /* Make sure we have C-declarations in C++ programs */
#endif
/*********************************************************************
*
* Keywords/specifiers
*
**********************************************************************
*/
#ifndef INLINE
#if (defined(__ICCARM__) || defined(__RX) || defined(__ICCRX__))
//
// Other known compilers.
//
#define INLINE inline
#else
#if (defined(_WIN32) && !defined(__clang__))
//
// Microsoft VC6 and newer.
// Force inlining without cost checking.
//
#define INLINE __forceinline
#elif defined(__GNUC__) || defined(__clang__)
//
// Force inlining with GCC + clang
//
#define INLINE inline __attribute__((always_inline))
#elif (defined(__CC_ARM))
//
// Force inlining with ARMCC (Keil)
//
#define INLINE __inline
#else
//
// Unknown compilers.
//
#define INLINE
#endif
#endif
#endif
/*********************************************************************
*
* Function-like macros
*
**********************************************************************
*/
#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
#ifndef SEGGER_USE_PARA // Some compiler complain about unused parameters.
#define SEGGER_USE_PARA(Para) (void)Para // This works for most compilers.
#endif
#define SEGGER_ADDR2PTR(Type, Addr) (/*lint -e(923) -e(9078)*/((Type*)((PTR_ADDR)(Addr)))) // Allow cast from address to pointer.
#define SEGGER_PTR2ADDR(p) (/*lint -e(923) -e(9078)*/((PTR_ADDR)(p))) // Allow cast from pointer to address.
#define SEGGER_PTR2PTR(Type, p) (/*lint -e(740) -e(826) -e(9079) -e(9087)*/((Type*)(p))) // Allow cast from one pointer type to another (ignore different size).
#define SEGGER_PTR_DISTANCE(p0, p1) (SEGGER_PTR2ADDR(p0) - SEGGER_PTR2ADDR(p1))
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define SEGGER_PRINTF_FLAG_ADJLEFT (1 << 0)
#define SEGGER_PRINTF_FLAG_SIGNFORCE (1 << 1)
#define SEGGER_PRINTF_FLAG_SIGNSPACE (1 << 2)
#define SEGGER_PRINTF_FLAG_PRECEED (1 << 3)
#define SEGGER_PRINTF_FLAG_ZEROPAD (1 << 4)
#define SEGGER_PRINTF_FLAG_NEGATIVE (1 << 5)
/*********************************************************************
*
* Types
*
**********************************************************************
*/
typedef struct {
char* pBuffer;
int BufferSize;
int Cnt;
} SEGGER_BUFFER_DESC;
typedef struct {
unsigned int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
void (*pfClean) (void *p, unsigned long NumBytes); // Optional clean function for cached memory.
void (*pfInvalidate)(void *p, unsigned long NumBytes); // Optional invalidate function for cached memory.
} SEGGER_CACHE_CONFIG;
typedef struct SEGGER_SNPRINTF_CONTEXT_struct SEGGER_SNPRINTF_CONTEXT;
struct SEGGER_SNPRINTF_CONTEXT_struct {
void* pContext; // Application specific context.
SEGGER_BUFFER_DESC* pBufferDesc; // Buffer descriptor to use for output.
void (*pfFlush)(SEGGER_SNPRINTF_CONTEXT* pContext); // Callback executed once the buffer is full. Callback decides if the buffer gets cleared to store more or not.
};
typedef struct {
void (*pfStoreChar) (SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, char c);
int (*pfPrintUnsigned) (SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, U32 v, unsigned Base, char Flags, int Width, int Precision);
int (*pfPrintInt) (SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, I32 v, unsigned Base, char Flags, int Width, int Precision);
} SEGGER_PRINTF_API;
typedef void (*SEGGER_pFormatter)(SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, const SEGGER_PRINTF_API* pApi, va_list* pParamList, char Lead, int Width, int Precision);
typedef struct SEGGER_PRINTF_FORMATTER {
struct SEGGER_PRINTF_FORMATTER* pNext; // Pointer to next formatter.
SEGGER_pFormatter pfFormatter; // Formatter function.
char Specifier; // Format specifier.
} SEGGER_PRINTF_FORMATTER;
typedef struct {
U32 (*pfGetHPTimestamp)(void); // Mandatory, pfGetHPTimestamp
int (*pfGetUID) (U8 abUID[16]); // Optional, pfGetUID
} SEGGER_BSP_API;
/*********************************************************************
*
* Utility functions
*
**********************************************************************
*/
//
// Memory operations.
//
void SEGGER_ARM_memcpy(void* pDest, const void* pSrc, int NumBytes);
void SEGGER_memcpy (void* pDest, const void* pSrc, unsigned NumBytes);
void SEGGER_memxor (void* pDest, const void* pSrc, unsigned NumBytes);
//
// String functions.
//
int SEGGER_atoi (const char* s);
int SEGGER_isalnum (int c);
int SEGGER_isalpha (int c);
unsigned SEGGER_strlen (const char* s);
int SEGGER_tolower (int c);
int SEGGER_strcasecmp (const char* sText1, const char* sText2);
int SEGGER_strncasecmp(const char *sText1, const char *sText2, unsigned Count);
//
// Buffer/printf related.
//
void SEGGER_StoreChar (SEGGER_BUFFER_DESC* pBufferDesc, char c);
void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC* pBufferDesc, U32 v, unsigned Base, int Precision);
void SEGGER_PrintInt (SEGGER_BUFFER_DESC* pBufferDesc, I32 v, unsigned Base, int Precision);
int SEGGER_snprintf (char* pBuffer, int BufferSize, const char* sFormat, ...);
int SEGGER_vsnprintf (char* pBuffer, int BufferSize, const char* sFormat, va_list ParamList);
int SEGGER_vsnprintfEx (SEGGER_SNPRINTF_CONTEXT* pContext, const char* sFormat, va_list ParamList);
int SEGGER_PRINTF_AddFormatter (SEGGER_PRINTF_FORMATTER* pFormatter, SEGGER_pFormatter pfFormatter, char c);
void SEGGER_PRINTF_AddDoubleFormatter (void);
void SEGGER_PRINTF_AddIPFormatter (void);
void SEGGER_PRINTF_AddBLUEFormatter (void);
void SEGGER_PRINTF_AddCONNECTFormatter(void);
void SEGGER_PRINTF_AddSSLFormatter (void);
void SEGGER_PRINTF_AddSSHFormatter (void);
void SEGGER_PRINTF_AddHTMLFormatter (void);
//
// BSP abstraction API.
//
int SEGGER_BSP_GetUID (U8 abUID[16]);
int SEGGER_BSP_GetUID32(U32* pUID);
void SEGGER_BSP_SetAPI (const SEGGER_BSP_API* pAPI);
void SEGGER_BSP_SeedUID (void);
//
// Other API.
//
void SEGGER_VERSION_GetString(char acText[8], unsigned Version);
#if defined(__cplusplus)
} /* Make sure we have C-declarations in C++ programs */
#endif
#endif // Avoid multiple inclusion
/*************************** End of file ****************************/

View File

@@ -0,0 +1,515 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2024 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.56 *
* *
**********************************************************************
---------------------------END-OF-HEADER------------------------------
File : SEGGER_RTT.h
Purpose : Implementation of SEGGER real-time transfer which allows
real-time communication on targets which support debugger
memory accesses while the CPU is running.
Revision: $Rev: 25842 $
----------------------------------------------------------------------
*/
#ifndef SEGGER_RTT_H
#define SEGGER_RTT_H
#include "../Config/SEGGER_RTT_Conf.h"
/*********************************************************************
*
* Defines, defaults
*
**********************************************************************
*/
#ifndef RTT_USE_ASM
//
// Some cores support out-of-order memory accesses (reordering of memory accesses in the core)
// For such cores, we need to define a memory barrier to guarantee the order of certain accesses to the RTT ring buffers.
// Needed for:
// Cortex-M7 (ARMv7-M)
// Cortex-M23 (ARM-v8M)
// Cortex-M33 (ARM-v8M)
// Cortex-A/R (ARM-v7A/R)
//
// We do not explicitly check for "Embedded Studio" as the compiler in use determines what we support.
// You can use an external toolchain like IAR inside ES. So there is no point in checking for "Embedded Studio"
//
#if (defined __CROSSWORKS_ARM) // Rowley Crossworks
#define _CC_HAS_RTT_ASM_SUPPORT 1
#if (defined __ARM_ARCH_7M__) // Cortex-M3
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined(__ARM_ARCH_8_1M_MAIN__)) // Cortex-M85
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#else
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#endif
#elif (defined __ARMCC_VERSION)
//
// ARM compiler
// ARM compiler V6.0 and later is clang based.
// Our ASM part is compatible to clang.
//
#if (__ARMCC_VERSION >= 6000000)
#define _CC_HAS_RTT_ASM_SUPPORT 1
#else
#define _CC_HAS_RTT_ASM_SUPPORT 0
#endif
#if (defined __ARM_ARCH_6M__) // Cortex-M0 / M1
#define _CORE_HAS_RTT_ASM_SUPPORT 0 // No ASM support for this architecture
#elif (defined __ARM_ARCH_7M__) // Cortex-M3
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) // Cortex-A/R 32-bit ARMv7-A/R
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#else
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#endif
#elif ((defined __GNUC__) || (defined __clang__))
//
// GCC / Clang
//
#define _CC_HAS_RTT_ASM_SUPPORT 1
// ARM 7/9: __ARM_ARCH_5__ / __ARM_ARCH_5E__ / __ARM_ARCH_5T__ / __ARM_ARCH_5T__ / __ARM_ARCH_5TE__
#if (defined __ARM_ARCH_7M__) // Cortex-M3
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1 // Only Cortex-M7 needs a DMB but we cannot distinguish M4 and M7 here...
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) // Cortex-A/R 32-bit ARMv7-A/R
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
#else
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#endif
#elif ((defined __IASMARM__) || (defined __ICCARM__))
//
// IAR assembler/compiler
//
#define _CC_HAS_RTT_ASM_SUPPORT 1
#if (__VER__ < 6300000)
#define VOLATILE
#else
#define VOLATILE volatile
#endif
#if (defined __ARM7M__) // Needed for old versions that do not know the define yet
#if (__CORE__ == __ARM7M__) // Cortex-M3
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#endif
#endif
#if (defined __ARM7EM__)
#if (__CORE__ == __ARM7EM__) // Cortex-M4/M7
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() asm VOLATILE ("DMB");
#endif
#endif
#if (defined __ARM8M_BASELINE__)
#if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() asm VOLATILE ("DMB");
#endif
#endif
#if (defined __ARM8M_MAINLINE__)
#if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() asm VOLATILE ("DMB");
#endif
#endif
#if (defined __ARM8EM_MAINLINE__)
#if (__CORE__ == __ARM8EM_MAINLINE__) // Cortex-???
#define _CORE_HAS_RTT_ASM_SUPPORT 1
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() asm VOLATILE ("DMB");
#endif
#endif
#if (defined __ARM7A__)
#if (__CORE__ == __ARM7A__) // Cortex-A 32-bit ARMv7-A
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() asm VOLATILE ("DMB");
#endif
#endif
#if (defined __ARM7R__)
#if (__CORE__ == __ARM7R__) // Cortex-R 32-bit ARMv7-R
#define _CORE_NEEDS_DMB 1
#define RTT__DMB() asm VOLATILE ("DMB");
#endif
#endif
// TBD: __ARM8A__ => Cortex-A 64-bit ARMv8-A
// TBD: __ARM8R__ => Cortex-R 64-bit ARMv8-R
#else
//
// Other compilers
//
#define _CC_HAS_RTT_ASM_SUPPORT 0
#define _CORE_HAS_RTT_ASM_SUPPORT 0
#endif
//
// If IDE and core support the ASM version, enable ASM version by default
//
#ifndef _CORE_HAS_RTT_ASM_SUPPORT
#define _CORE_HAS_RTT_ASM_SUPPORT 0 // Default for unknown cores
#endif
#if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT)
#define RTT_USE_ASM (1)
#else
#define RTT_USE_ASM (0)
#endif
#endif
#ifndef _CORE_NEEDS_DMB
#define _CORE_NEEDS_DMB 0
#endif
#ifndef RTT__DMB
#if _CORE_NEEDS_DMB
#error "Don't know how to place inline assembly for DMB"
#else
#define RTT__DMB()
#endif
#endif
#ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE
#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (0) // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here
#endif
#ifndef SEGGER_RTT_UNCACHED_OFF
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE
#error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
#else
#define SEGGER_RTT_UNCACHED_OFF (0)
#endif
#endif
#if RTT_USE_ASM
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE
#error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
#endif
#endif
#ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
//
// Determine how much we must pad the control block to make it a multiple of a cache line in size
// Assuming: U8 = 1B
// U16 = 2B
// U32 = 4B
// U8/U16/U32* = 4B
//
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE // Avoid division by zero in case we do not have any cache
#define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * SEGGER_RTT_CPU_CACHE_LINE_SIZE)
#else
#define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes)
#endif
#define SEGGER_RTT__CB_SIZE (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24))
#define SEGGER_RTT__CB_PADDING (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE)
/*********************************************************************
*
* Types
*
**********************************************************************
*/
//
// Description for a circular buffer (also called "ring buffer")
// which is used as up-buffer (T->H)
//
typedef struct {
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
char* pBuffer; // Pointer to start of buffer
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
unsigned WrOff; // Position of next item to be written by either target.
volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host.
unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
} SEGGER_RTT_BUFFER_UP;
//
// Description for a circular buffer (also called "ring buffer")
// which is used as down-buffer (H->T)
//
typedef struct {
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
char* pBuffer; // Pointer to start of buffer
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host.
unsigned RdOff; // Position of next item to be read by target (down-buffer).
unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
} SEGGER_RTT_BUFFER_DOWN;
//
// RTT control block which describes the number of buffers available
// as well as the configuration for each buffer
//
//
typedef struct {
char acID[16]; // Initialized to "SEGGER RTT"
int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host
SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target
#if SEGGER_RTT__CB_PADDING
unsigned char aDummy[SEGGER_RTT__CB_PADDING];
#endif
} SEGGER_RTT_CB;
/*********************************************************************
*
* Global data
*
**********************************************************************
*/
extern SEGGER_RTT_CB _SEGGER_RTT;
/*********************************************************************
*
* RTT API functions
*
**********************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_GetKey (void);
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
int SEGGER_RTT_HasKey (void);
unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex);
void SEGGER_RTT_Init (void);
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName);
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags);
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags);
int SEGGER_RTT_WaitKey (void);
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_ASM_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c);
unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c);
unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c);
unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex);
unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex);
void SEGGER_RTT_ESP_FlushNoLock (unsigned long min_sz, unsigned long tmo);
void SEGGER_RTT_ESP_Flush (unsigned long min_sz, unsigned long tmo);
//
// Function macro for performance optimization
//
// @AGv: This macro is used inside SEGGER SystemView code.
// For ESP32 we use our own implementation of RTT, so this macro should not check SEGGER's RTT buffer state.
#define SEGGER_RTT_HASDATA(n) (1)
#if RTT_USE_ASM
#define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock
#endif
/*********************************************************************
*
* RTT transfer functions to send RTT data via other channels.
*
**********************************************************************
*/
unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
#define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
/*********************************************************************
*
* RTT "Terminal" API functions
*
**********************************************************************
*/
int SEGGER_RTT_SetTerminal (unsigned char TerminalId);
int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s);
/*********************************************************************
*
* RTT printf functions (require SEGGER_RTT_printf.c)
*
**********************************************************************
*/
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
#ifdef __cplusplus
}
#endif
#endif // ifndef(SEGGER_RTT_ASM)
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
//
// Operating modes. Define behavior if buffer is full (not enough space for entire message)
//
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default)
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits.
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer.
#define SEGGER_RTT_MODE_MASK (3)
//
// Control sequences, based on ANSI.
// Can be used to control color, and clear the screen
//
#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors
#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left
#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m"
#define RTT_CTRL_TEXT_RED "\x1B[2;31m"
#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m"
#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m"
#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m"
#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m"
#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m"
#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m"
#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m"
#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m"
#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m"
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m"
#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m"
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m"
#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m"
#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m"
#define RTT_CTRL_BG_BLACK "\x1B[24;40m"
#define RTT_CTRL_BG_RED "\x1B[24;41m"
#define RTT_CTRL_BG_GREEN "\x1B[24;42m"
#define RTT_CTRL_BG_YELLOW "\x1B[24;43m"
#define RTT_CTRL_BG_BLUE "\x1B[24;44m"
#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m"
#define RTT_CTRL_BG_CYAN "\x1B[24;46m"
#define RTT_CTRL_BG_WHITE "\x1B[24;47m"
#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m"
#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m"
#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m"
#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m"
#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m"
#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m"
#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m"
#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m"
#endif
/*************************** End of file ****************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,436 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*
* SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2024 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.56 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW.h
Purpose : System visualization API.
Revision: $Rev: 28768 $
*/
#ifndef SEGGER_SYSVIEW_H
#define SEGGER_SYSVIEW_H
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "SEGGER.h"
#include "SEGGER_SYSVIEW_ConfDefaults.h"
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
#define SEGGER_SYSVIEW_MAJOR 3
#define SEGGER_SYSVIEW_MINOR 32
#define SEGGER_SYSVIEW_REV 0
#define SEGGER_SYSVIEW_VERSION ((SEGGER_SYSVIEW_MAJOR * 10000) + (SEGGER_SYSVIEW_MINOR * 100) + SEGGER_SYSVIEW_REV)
#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
#define SEGGER_SYSVIEW_LOG (0u)
#define SEGGER_SYSVIEW_WARNING (1u)
#define SEGGER_SYSVIEW_ERROR (2u)
#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
//
// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
//
#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
#define SYSVIEW_EVTID_OVERFLOW 1
#define SYSVIEW_EVTID_ISR_ENTER 2
#define SYSVIEW_EVTID_ISR_EXIT 3
#define SYSVIEW_EVTID_TASK_START_EXEC 4
#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
#define SYSVIEW_EVTID_TASK_START_READY 6
#define SYSVIEW_EVTID_TASK_STOP_READY 7
#define SYSVIEW_EVTID_TASK_CREATE 8
#define SYSVIEW_EVTID_TASK_INFO 9
#define SYSVIEW_EVTID_TRACE_START 10
#define SYSVIEW_EVTID_TRACE_STOP 11
#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
#define SYSVIEW_EVTID_SYSTIME_US 13
#define SYSVIEW_EVTID_SYSDESC 14
#define SYSVIEW_EVTID_MARK_START 15
#define SYSVIEW_EVTID_MARK_STOP 16
#define SYSVIEW_EVTID_IDLE 17
#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
#define SYSVIEW_EVTID_TIMER_ENTER 19
#define SYSVIEW_EVTID_TIMER_EXIT 20
#define SYSVIEW_EVTID_STACK_INFO 21
#define SYSVIEW_EVTID_MODULEDESC 22
#define SYSVIEW_EVTID_DATA_SAMPLE 23
#define SYSVIEW_EVTID_INIT 24
#define SYSVIEW_EVTID_NAME_RESOURCE 25
#define SYSVIEW_EVTID_PRINT_FORMATTED 26
#define SYSVIEW_EVTID_NUMMODULES 27
#define SYSVIEW_EVTID_END_CALL 28
#define SYSVIEW_EVTID_TASK_TERMINATE 29
#define SYSVIEW_EVTID_EX 31
//
// SystemView extended events. Sent with ID 31.
//
#define SYSVIEW_EVTID_EX_MARK 0
#define SYSVIEW_EVTID_EX_NAME_MARKER 1
#define SYSVIEW_EVTID_EX_HEAP_DEFINE 2
#define SYSVIEW_EVTID_EX_HEAP_ALLOC 3
#define SYSVIEW_EVTID_EX_HEAP_ALLOC_EX 4
#define SYSVIEW_EVTID_EX_HEAP_FREE 5
#define SYSVIEW_EVTID_EX_REGISTER_DATA 6
//
// Event masks to disable/enable events
//
#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
#define SYSVIEW_EVTMASK_DATA_SAMPLE (1 << SYSVIEW_EVTID_DATA_SAMPLE)
#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
| SYSVIEW_EVTMASK_ISR_EXIT \
| SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
| SYSVIEW_EVTMASK_TASK_STOP_EXEC \
| SYSVIEW_EVTMASK_TASK_START_READY \
| SYSVIEW_EVTMASK_TASK_STOP_READY \
| SYSVIEW_EVTMASK_TASK_CREATE \
| SYSVIEW_EVTMASK_TASK_INFO \
| SYSVIEW_EVTMASK_STACK_INFO \
| SYSVIEW_EVTMASK_TASK_TERMINATE)
/*********************************************************************
*
* Structures
*
**********************************************************************
*/
typedef struct {
U32 TaskID;
const char* sName;
U32 Prio;
U32 StackBase;
U32 StackSize;
U32 StackUsage;
} SEGGER_SYSVIEW_TASKINFO;
typedef struct {
U32 TaskID;
U32 StackBase;
U32 StackSize;
U32 StackUsage;
} SEGGER_SYSVIEW_STACKINFO;
typedef struct {
U32 ID;
union {
U32* pU32_Value;
I32* pI32_Value;
float* pFloat_Value;
};
} SEGGER_SYSVIEW_DATA_SAMPLE;
typedef enum {
SEGGER_SYSVIEW_TYPE_U32 = 0,
SEGGER_SYSVIEW_TYPE_I32 = 1,
SEGGER_SYSVIEW_TYPE_FLOAT = 2
} SEGGER_SYSVIEW_DATA_TYPE;
typedef struct {
U32 ID;
SEGGER_SYSVIEW_DATA_TYPE DataType;
I32 Offset;
I32 RangeMin;
I32 RangeMax;
float ScalingFactor;
const char* sName;
const char* sUnit;
} SEGGER_SYSVIEW_DATA_REGISTER;
typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
struct SEGGER_SYSVIEW_MODULE_STRUCT {
const char* sModule;
U32 NumEvents;
U32 EventOffset;
void (*pfSendModuleDesc)(void);
SEGGER_SYSVIEW_MODULE* pNext;
};
typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
/*********************************************************************
*
* Global data
*
**********************************************************************
*/
#ifdef EXTERN
#undef EXTERN
#endif
#ifndef SEGGER_SYSVIEW_C // Defined in SEGGER_SYSVIEW.c which includes this header beside other C-files
#define EXTERN extern
#else
#define EXTERN
#endif
EXTERN unsigned int SEGGER_SYSVIEW_TickCnt;
EXTERN unsigned int SEGGER_SYSVIEW_InterruptId;
#undef EXTERN
/*********************************************************************
*
* API functions
*
**********************************************************************
*/
typedef struct {
U64 (*pfGetTime) (void);
void (*pfSendTaskList) (void);
} SEGGER_SYSVIEW_OS_API;
/*********************************************************************
*
* Control and initialization functions
*/
void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
void SEGGER_SYSVIEW_Start (void);
void SEGGER_SYSVIEW_Stop (void);
void SEGGER_SYSVIEW_GetSysDesc (void);
void SEGGER_SYSVIEW_SendTaskList (void);
void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
void SEGGER_SYSVIEW_SendStackInfo (const SEGGER_SYSVIEW_STACKINFO* pInfo);
void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
int SEGGER_SYSVIEW_IsStarted (void);
int SEGGER_SYSVIEW_GetChannelID (void);
void SEGGER_SYSVIEW_SampleData (const SEGGER_SYSVIEW_DATA_SAMPLE *pInfo);
// Checks whether tracing has been started
U8 SEGGER_SYSVIEW_Started(void);
/*********************************************************************
*
* Event recording functions
*/
void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
void SEGGER_SYSVIEW_RecordSystime (void);
void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
void SEGGER_SYSVIEW_RecordExitISR (void);
void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
void SEGGER_SYSVIEW_RecordExitTimer (void);
void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
void SEGGER_SYSVIEW_OnIdle (void);
void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskStopExec (void);
void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
void SEGGER_SYSVIEW_MarkStart (unsigned int MarkerId);
void SEGGER_SYSVIEW_MarkStop (unsigned int MarkerId);
void SEGGER_SYSVIEW_Mark (unsigned int MarkerId);
void SEGGER_SYSVIEW_NameMarker (unsigned int MarkerId, const char* sName);
void SEGGER_SYSVIEW_HeapDefine (void* pHeap, void* pBase, unsigned int HeapSize, unsigned int MetadataSize);
void SEGGER_SYSVIEW_HeapAlloc (void* pHeap, void* pUserData, unsigned int UserDataLen);
void SEGGER_SYSVIEW_HeapAllocEx (void* pHeap, void* pUserData, unsigned int UserDataLen, unsigned int Tag);
void SEGGER_SYSVIEW_HeapFree (void* pHeap, void* pUserData);
void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
void SEGGER_SYSVIEW_RegisterData ( SEGGER_SYSVIEW_DATA_REGISTER* pInfo);
int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
/*********************************************************************
*
* Event parameter encoding functions
*/
U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
/*********************************************************************
*
* Middleware module registration
*/
void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
void SEGGER_SYSVIEW_SendModuleDescription (void);
void SEGGER_SYSVIEW_SendNumModules (void);
/*********************************************************************
*
* printf-Style functions
*/
#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
void SEGGER_SYSVIEW_VPrintfHostEx (const char* s, U32 Options, va_list* pParamList);
void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
void SEGGER_SYSVIEW_VPrintfTargetEx (const char* s, U32 Options, va_list* pParamList);
void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
void SEGGER_SYSVIEW_VPrintfHost (const char* s, va_list* pParamList);
void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
void SEGGER_SYSVIEW_VPrintfTarget (const char* s, va_list* pParamList);
void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
void SEGGER_SYSVIEW_VWarnfHost (const char* s, va_list* pParamList);
void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
void SEGGER_SYSVIEW_VWarnfTarget (const char* s, va_list* pParamList);
void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
void SEGGER_SYSVIEW_VErrorfHost (const char* s, va_list* pParamList);
void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
void SEGGER_SYSVIEW_VErrorfTarget (const char* s, va_list* pParamList);
#endif
void SEGGER_SYSVIEW_Print (const char* s);
void SEGGER_SYSVIEW_Warn (const char* s);
void SEGGER_SYSVIEW_Error (const char* s);
/*********************************************************************
*
* Run-time configuration functions
*/
void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
/*********************************************************************
*
* Application-provided functions
*/
void SEGGER_SYSVIEW_Conf (void);
U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
void SEGGER_SYSVIEW_X_StartComm (void);
void SEGGER_SYSVIEW_X_OnEventRecorded (unsigned NumBytes);
#ifdef __cplusplus
}
#endif
/*********************************************************************
*
* Compatibility API defines
*/
#define SEGGER_SYSVIEW_OnUserStart SEGGER_SYSVIEW_MarkStart
#define SEGGER_SYSVIEW_OnUserStop SEGGER_SYSVIEW_MarkStop
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,592 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*
* SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2024 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.56 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_ConfDefaults.h
Purpose : Defines defaults for configurable defines used in
SEGGER SystemView.
Revision: $Rev: 26230 $
*/
#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
#define SEGGER_SYSVIEW_CONFDEFAULTS_H
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "SEGGER_SYSVIEW_Conf.h"
#include "SEGGER_RTT_Conf.h"
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
//
// Use auto-detection for SEGGER_SYSVIEW_CORE define
// based on compiler-/toolchain-specific defines
// to define SEGGER_SYSVIEW_GET_INTERRUPT_ID and SEGGER_SYSVIEW_GET_TIMESTAMP
//
#define SEGGER_SYSVIEW_CORE_OTHER 0
#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
#ifndef SEGGER_SYSVIEW_CORE
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __SEGGER_CC__) || (defined __GNUC__) || (defined __clang__)
#if (defined __ARM_ARCH_6M__) || (defined __ARM_ARCH_8M_BASE__)
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif
#elif defined(__ICCARM__)
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) \
|| (defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) \
|| (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) \
|| (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) \
|| (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif
#elif defined(__CC_ARM)
#if (defined(__TARGET_ARCH_6S_M))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif
#elif defined(__TI_ARM__)
#ifdef __TI_ARM_V6M0__
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif
#elif defined(__ICCRX__)
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
#elif defined(__RX)
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
#endif
#ifndef SEGGER_SYSVIEW_CORE
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
#endif
#endif
/*********************************************************************
*
* Defines, defaults
*
**********************************************************************
*/
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_APP_NAME
*
* Description
* The application name to be displayed in SystemView.
* Default
* "SystemView-enabled Application"
* Notes
* Convenience define to be used for SEGGER_SYSVIEW_SendSysDesc().
*/
#ifndef SEGGER_SYSVIEW_APP_NAME
#define SEGGER_SYSVIEW_APP_NAME "SystemView-enabled Application"
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_DEVICE_NAME
*
* Description
* The target device name to be displayed in SystemView.
* Default
* "undefined device"
* Notes
* Convenience define to be used for SEGGER_SYSVIEW_SendSysDesc().
*/
#ifndef SEGGER_SYSVIEW_DEVICE_NAME
#define SEGGER_SYSVIEW_DEVICE_NAME "undefined device"
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_GET_INTERRUPT_ID()
*
* Description
* Function macro to retrieve the Id of the currently active
* interrupt.
* Default
* Call user-supplied function SEGGER_SYSVIEW_X_GetInterruptId().
* Notes
* For some known compilers and cores, a ready-to-use, core-specific
* default is set.
* ARMv7M: Read ICSR[8:0] (active vector)
* ARMv6M: Read ICSR[5:0] (active vector)
*/
#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32*)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
#if defined(__ICCARM__)
#if (__VER__ > 6010000)
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
#else
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32*)(0xE000ED04)) & 0x3F) // Older versions of IAR do not include __get_IPSR, but might also not optimize to byte-access.
#endif
#else
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32*)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
#endif
#else
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
#endif
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_GET_TIMESTAMP()
*
* Description
* Function macro to retrieve a system timestamp for SYSVIEW events.
* Default
* Call user-supplied function SEGGER_SYSVIEW_X_GetTimestamp().
* Notes
* For some known compilers and cores, a ready-to-use, core-specific
* default is set.
* ARMv7M: Read Cortex-M Cycle Count register.
*
* The system timestamp clock frequency has to be passed in
* SEGGER_SYSVIEW_Init().
*/
#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
#if defined (SEGGER_SYSVIEW_CORE) && (SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3)
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
#else
#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
#endif
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_TIMESTAMP_BITS
*
* Description
* Number of valid (low-order) bits delivered in system timestamp.
* Default
* 32
* Notes
* Value has to match system timestamp clock source.
*/
// Define number of valid bits low-order delivered by clock source.
#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_RTT_CHANNEL
*
* Description
* The RTT channel that SystemView will use.
* Default
* 0: Auto selection.
* Notes
* Value has to be lower than SEGGER_RTT_MAX_NUM_UP_BUFFERS.
*/
#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
#define SEGGER_SYSVIEW_RTT_CHANNEL 1
#endif
// Sanity check of RTT channel
#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_RTT_BUFFER_SIZE
*
* Description
* Number of bytes that SystemView uses for the RTT buffer.
* Default
* 1024
*/
#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_SECTION
*
* Description
* Section to place the SystemView RTT Buffer into.
* Default
* undefined: Do not place into a specific section.
* Notes
* If SEGGER_RTT_SECTION is defined, the default changes to use
* this section for the SystemView RTT Buffer, too.
*/
#if !(defined SEGGER_SYSVIEW_SECTION) && (defined SEGGER_RTT_SECTION)
#define SEGGER_SYSVIEW_SECTION SEGGER_RTT_SECTION
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE
*
* Description
* Largest cache line size (in bytes) in the target system.
* Default
* 0
* Notes
* Required in systems with caches to make sure that the SystemView
* RTT buffer can be aligned accordingly.
*/
#ifndef SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE
#define SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_ID_BASE
*
* Description
* Lowest Id reported by the application.
* Default
* 0
* Notes
* Value is usually subtracted from mailboxes, semaphores, tasks,
* .... addresses, to compress event parameters.
* Should be the lowest RAM address of the system.
*/
#ifndef SEGGER_SYSVIEW_ID_BASE
#define SEGGER_SYSVIEW_ID_BASE 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_ID_SHIFT
*
* Description
* Number of bits to shift Ids.
* Default
* 0
* Notes
* Ids are shifted to compress event parameters.
* Should match the alignment of Ids (addresses),
* e.g. 2 when Ids are 4 byte aligned.
*/
#ifndef SEGGER_SYSVIEW_ID_SHIFT
#define SEGGER_SYSVIEW_ID_SHIFT 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_MAX_ARGUMENTS
*
* Description
* Maximum number of arguments which are handled with SystemView
* print routines or may be encoded in one recording function.
* routines.
* Default
* 16
*/
#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
#define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_MAX_STRING_LEN
*
* Description
* Maximum string length which can be used in SystemView print and
* system description routines.
* Default
* 128
*/
#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
#define SEGGER_SYSVIEW_MAX_STRING_LEN 128
#endif
ESP_STATIC_ASSERT(SEGGER_SYSVIEW_MAX_STRING_LEN < 255, "SEGGER Sysview string length must be less than 255.");
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_SUPPORT_LONG_ID
*
* Description
* It set, support encoding Evend Ids longer than 14 bit.
* Default
* 1
*/
#ifndef SEGGER_SYSVIEW_SUPPORT_LONG_ID
#define SEGGER_SYSVIEW_SUPPORT_LONG_ID 1
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_SUPPORT_LONG_DATA
*
* Description
* It set, support encoding event data longer than 14 bit.
* Default
* 0
*/
#ifndef SEGGER_SYSVIEW_SUPPORT_LONG_DATA
#define SEGGER_SYSVIEW_SUPPORT_LONG_DATA 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
*
* Description
* If enabled, on SEGGER_SYSVIEW_PrintHost, check the format string
* and if it includes unsupported formatters, use formatting on the
* target instead.
* Default
* 0: Disabled.
*/
#ifndef SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
#define SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_USE_INTERNAL_RECORDER
*
* Description
* If set, an internal recorder, such as UART or IP is used.
* Default
* 0: Disabled.
* Notes
* Convenience define to be used by SEGGER_SYSVIEW_Conf(),
* such as in embOS configuration to enable Cortex-M cycle counter.
*/
#ifndef SEGGER_SYSVIEW_USE_INTERNAL_RECORDER
#define SEGGER_SYSVIEW_USE_INTERNAL_RECORDER 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_CAN_RESTART
*
* Description
* If enabled, send the SystemView start sequence on every start
* command, not just on the first one.
* Enables restart when SystemView disconnected unexpectedly.
* Default
* 1: Enabled
*/
#ifndef SEGGER_SYSVIEW_CAN_RESTART
#define SEGGER_SYSVIEW_CAN_RESTART 1
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_START_ON_INIT
*
* Description
* Enable calling SEGGER_SYSVIEW_Start() after initialization.
* Default
* 0: Disabled.
* Notes
* Convenience define to be used by SEGGER_SYSVIEW_Conf(),
* such as in embOS configuration.
*/
#ifndef SEGGER_SYSVIEW_START_ON_INIT
#define SEGGER_SYSVIEW_START_ON_INIT 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_USE_STATIC_BUFFER
*
* Description
* If enabled, use a static buffer instead of a buffer on the stack
* for SystemView event packets.
* Default
* 1: Enabled.
* Notes
* If enabled, the static memory use by SystemView is increased by
* the maximum packet size. SystemView is locked on entry of a
* recording function.
* If disabled, the stack usage by SystemView recording functions
* might be increased by up to the maximum packet size. SystemView
* is locked when writing the packet to the RTT buffer.
*/
#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_MAX_PACKET_SIZE
*
* Description
* Maximum packet size for a SystemView event.
* Default
* Automatically calculated.
* Notes
* The maximum packet size is mainly defined by the maximum string
* length and the maximum number of arguments.
*/
#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
#define SEGGER_SYSVIEW_MAX_PACKET_SIZE (SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32)
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_POST_MORTEM_MODE
*
* Description
* If enabled, SystemView records for post-mortem analysis instead
* of real-time analysis.
* Default
* 0: Disabled.
* Notes
* For more information refer to
* https://www.segger.com/products/development-tools/systemview/technology/post-mortem-mode
*/
#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
*
* Description
* Configure how frequently synchronization is sent in post-mortem
* mode.
* Default
* 8: (1 << 8) = Every 256 Events.
* Notes
* In post-mortem mode, at least one sync has to be in the RTT buffer.
* Recommended sync frequency: Buffer Size / 16
* For more information refer to
* https://www.segger.com/products/development-tools/systemview/technology/post-mortem-mode
*/
#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
#define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_ON_EVENT_RECORDED()
*
* Description
* Function macro to notify recorder about a new event in buffer.
* Default
* undefined: Do not notify recorder.
* Notes
* Used for non-J-Link recorder,
* such as to enable transmission via UART or notify IP task.
*/
#ifndef SEGGER_SYSVIEW_ON_EVENT_RECORDED
#define SEGGER_SYSVIEW_ON_EVENT_RECORDED(NumBytes)
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_LOCK()
*
* Description
* Function macro to (nestable) lock SystemView recording.
* Default
* Use RTT Locking mechanism (defined by SEGGER_RTT_LOCK()).
* Notes
* If SystemView recording is not locked, recording events from
* interrupts and tasks may lead to unpredictable, undefined, event
* data.
*/
#ifndef SEGGER_SYSVIEW_LOCK
unsigned SEGGER_SYSVIEW_X_SysView_Lock(void);
#define SEGGER_SYSVIEW_LOCK() unsigned _SYSVIEW_int_state = SEGGER_SYSVIEW_X_SysView_Lock()
#endif
/*********************************************************************
*
* Define: SEGGER_SYSVIEW_UNLOCK
*
* Description
* Function macro to unlock SystemView recording.
* Default
* Use RTT Unlocking mechanism (defined by SEGGER_RTT_UNLOCK()).
*/
#ifndef SEGGER_SYSVIEW_UNLOCK
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state);
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock(_SYSVIEW_int_state)
#endif
#ifdef __cplusplus
}
#endif
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,104 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2024 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.56 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Int.h
Purpose : SEGGER SystemView internal header.
Revision: $Rev: 21281 $
*/
#ifndef SEGGER_SYSVIEW_INT_H
#define SEGGER_SYSVIEW_INT_H
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "SEGGER_SYSVIEW.h"
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
*
* Private data types
*
**********************************************************************
*/
//
// Commands that Host can send to target
//
typedef enum {
SEGGER_SYSVIEW_COMMAND_ID_START = 1,
SEGGER_SYSVIEW_COMMAND_ID_STOP,
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
SEGGER_SYSVIEW_COMMAND_ID_HEARTBEAT = 127,
// Extended commands: Commands >= 128 have a second parameter
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
} SEGGER_SYSVIEW_COMMAND_ID;
#ifdef __cplusplus
}
#endif
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,6 @@
name: 'SystemView'
version: '3.56'
cpe: cpe:2.3:a:segger:systemview:{}:*:*:*:*:*:*:*
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
originator: 'Organization: SEGGER Microcontroller GmbH'
description: Real-time recording and visualization tool for embedded systems.

View File

@@ -0,0 +1,287 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*
* SPDX-FileContributor: 2017-2025 Espressif Systems (Shanghai) CO LTD
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.42 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Config_FreeRTOS.c
Purpose : Sample setup configuration of SystemView with FreeRTOS.
Revision: $Rev: 7745 $
*/
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "SEGGER_SYSVIEW.h"
#include "esp_app_trace.h"
#include "esp_app_trace_util.h"
#include "esp_intr_alloc.h"
#include "esp_clk_tree.h"
#include "esp_cpu.h"
#include "soc/soc.h"
#include "soc/interrupts.h"
#include "esp_private/esp_clk.h"
extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
// The application name to be displayed in SystemViewer
#define SYSVIEW_APP_NAME "FreeRTOS Application"
// The target device name
#define SYSVIEW_DEVICE_NAME CONFIG_IDF_TARGET
// The target core name
#define SYSVIEW_CORE_NAME "core0" // In dual core, this will be renamed by OpenOCD as core1
// Determine which timer to use as timestamp source
#if CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
#define TS_USE_CCOUNT 1
#elif CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
#define TS_USE_ESP_TIMER 1
#else
#define TS_USE_TIMERGROUP 1
#endif
#if TS_USE_TIMERGROUP
#include "driver/gptimer.h"
// Timer group timer divisor
#define SYSVIEW_TIMER_DIV 2
// GPTimer handle
gptimer_handle_t s_sv_gptimer;
#endif // TS_USE_TIMERGROUP
#if TS_USE_ESP_TIMER
// esp_timer provides 1us resolution
#define SYSVIEW_TIMESTAMP_FREQ (1000000)
#endif // TS_USE_ESP_TIMER
#if TS_USE_CCOUNT
// CCOUNT is incremented at CPU frequency
#define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ * 1000000)
#endif // TS_USE_CCOUNT
// System Frequency.
#define SYSVIEW_CPU_FREQ (esp_clk_cpu_freq())
// The lowest RAM address used for IDs (pointers)
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
#ifdef CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
#if CONFIG_FREERTOS_CORETIMER_0
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#if CONFIG_FREERTOS_CORETIMER_1
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_INTR_SOURCE)
#endif // CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
// SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
// disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
// in case of expiration, because error will not be handled and SEGGER's code will go further implying that
// everything is fine, so for multi-core env we have to wait on underlying lock forever
#define SEGGER_LOCK_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKED, .int_state = 0};
/*********************************************************************
*
* _cbSendSystemDesc()
*
* Function description
* Sends SystemView description strings.
*/
static void _cbSendSystemDesc(void) {
char irq_str[32] = "I#";
SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C="SYSVIEW_CORE_NAME",O=FreeRTOS");
strcat(itoa(SYSTICK_INTR_ID, irq_str + 2, 10), "=SysTick");
SEGGER_SYSVIEW_SendSysDesc(irq_str);
size_t isr_count = sizeof(esp_isr_names)/sizeof(esp_isr_names[0]);
for (size_t i = 0; i < isr_count; ++i) {
if (esp_isr_names[i] == NULL || (ETS_INTERNAL_INTR_SOURCE_OFF + i) == SYSTICK_INTR_ID)
continue;
strcat(itoa(ETS_INTERNAL_INTR_SOURCE_OFF + i, irq_str + 2, 10), "=");
strncat(irq_str, esp_isr_names[i], sizeof(irq_str) - strlen(irq_str) - 1);
SEGGER_SYSVIEW_SendSysDesc(irq_str);
}
}
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
static int SEGGER_SYSVIEW_TS_Init(void)
{
/* We only need to initialize something if we use Timer Group.
* esp_timer and ccount can be used as is.
*/
#if TS_USE_TIMERGROUP
// get clock source frequency
uint32_t counter_src_hz = 0;
ESP_ERROR_CHECK(esp_clk_tree_src_get_freq_hz(
(soc_module_clk_t)GPTIMER_CLK_SRC_DEFAULT,
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz));
gptimer_config_t config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = counter_src_hz / SYSVIEW_TIMER_DIV,
};
// pick any free GPTimer instance
ESP_ERROR_CHECK(gptimer_new_timer(&config, &s_sv_gptimer));
/* Start counting */
gptimer_enable(s_sv_gptimer);
gptimer_start(s_sv_gptimer);
return config.resolution_hz;
#else
return SYSVIEW_TIMESTAMP_FREQ;
#endif // TS_USE_TIMERGROUP
}
void SEGGER_SYSVIEW_Conf(void) {
U32 disable_evts = 0;
int timestamp_freq = SEGGER_SYSVIEW_TS_Init();
SEGGER_SYSVIEW_Init(timestamp_freq, SYSVIEW_CPU_FREQ,
&SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc);
SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE);
#if !CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE
disable_evts |= SYSVIEW_EVTMASK_OVERFLOW;
#endif
#if !CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE
disable_evts |= SYSVIEW_EVTMASK_ISR_ENTER;
#endif
#if !CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE
disable_evts |= SYSVIEW_EVTMASK_ISR_EXIT;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TASK_START_EXEC;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_EXEC;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TASK_START_READY;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_READY;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TASK_CREATE;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TASK_TERMINATE;
#endif
#if !CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE
disable_evts |= SYSVIEW_EVTMASK_IDLE;
#endif
#if !CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
disable_evts |= SYSVIEW_EVTMASK_ISR_TO_SCHEDULER;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TIMER_ENTER;
#endif
#if !CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
disable_evts |= SYSVIEW_EVTMASK_TIMER_EXIT;
#endif
SEGGER_SYSVIEW_DisableEvents(disable_evts);
}
U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
{
#if TS_USE_TIMERGROUP
uint64_t ts = 0;
gptimer_get_raw_count(s_sv_gptimer, &ts);
return (U32) ts; // return lower part of counter value
#elif TS_USE_CCOUNT
return esp_cpu_get_cycle_count();
#elif TS_USE_ESP_TIMER
return (U32) esp_timer_get_time(); // return lower part of counter value
#endif
}
void SEGGER_SYSVIEW_X_RTT_Lock(void)
{
}
void SEGGER_SYSVIEW_X_RTT_Unlock(void)
{
}
unsigned SEGGER_SYSVIEW_X_SysView_Lock(void)
{
esp_apptrace_tmo_t tmo;
esp_apptrace_tmo_init(&tmo, SEGGER_LOCK_WAIT_TMO);
esp_apptrace_lock_take(&s_sys_view_lock, &tmo);
// to be recursive save IRQ status on the stack of the caller to keep it from overwriting
return s_sys_view_lock.int_state;
}
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)
{
s_sys_view_lock.int_state = int_state;
esp_apptrace_lock_give(&s_sys_view_lock);
}
/*************************** End of file ****************************/

View File

@@ -0,0 +1,270 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*
* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.42 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_FreeRTOS.c
Purpose : Interface between FreeRTOS and SystemView.
Revision: $Rev: 7947 $
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_FreeRTOS.h"
#include "string.h" // Required for memset
typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
struct SYSVIEW_FREERTOS_TASK_STATUS {
U32 xHandle;
const char* pcTaskName;
unsigned uxCurrentPriority;
U32 pxStack;
unsigned uStackHighWaterMark;
};
static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
static unsigned _NumTasks;
/*********************************************************************
*
* _cbSendTaskList()
*
* Function description
* This function is part of the link between FreeRTOS and SYSVIEW.
* Called from SystemView when asked by the host, it uses SYSVIEW
* functions to send the entire task list to the host.
*/
static void _cbSendTaskList(void) {
unsigned n;
for (n = 0; n < _NumTasks; n++) {
#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
_aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
#endif
SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
}
}
/*********************************************************************
*
* _cbGetTime()
*
* Function description
* This function is part of the link between FreeRTOS and SYSVIEW.
* Called from SystemView when asked by the host, returns the
* current system time in micro seconds.
*/
__attribute__((unused)) static U64 _cbGetTime(void) {
U64 Time;
Time = xTaskGetTickCountFromISR();
Time *= portTICK_PERIOD_MS;
Time *= 1000;
return Time;
}
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* SYSVIEW_AddTask()
*
* Function description
* Add a task to the internal list and record its information.
*/
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
/* 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) {
return;
}
if (_NumTasks >= SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
return;
}
_aTasks[_NumTasks].xHandle = xHandle;
_aTasks[_NumTasks].pcTaskName = pcTaskName;
_aTasks[_NumTasks].uxCurrentPriority = uxCurrentPriority;
_aTasks[_NumTasks].pxStack = pxStack;
_aTasks[_NumTasks].uStackHighWaterMark = uStackHighWaterMark;
_NumTasks++;
SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
}
/*********************************************************************
*
* SYSVIEW_UpdateTask()
*
* Function description
* Update a task in the internal list and record its information.
*/
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) {
return;
}
for (n = 0; n < _NumTasks; n++) {
if (_aTasks[n].xHandle == xHandle) {
break;
}
}
if (n < _NumTasks) {
_aTasks[n].pcTaskName = pcTaskName;
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
_aTasks[n].pxStack = pxStack;
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
} else {
SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
}
}
/*********************************************************************
*
* SYSVIEW_DeleteTask()
*
* Function description
* Delete a task from the internal list.
*/
void SYSVIEW_DeleteTask(U32 xHandle) {
unsigned n;
if (_NumTasks == 0) {
return; // Early out
}
for (n = 0; n < _NumTasks; n++) {
if (_aTasks[n].xHandle == xHandle) {
break;
}
}
if (n == (_NumTasks - 1)) {
//
// Task is last item in list.
// Simply zero the item and decrement number of tasks.
//
memset(&_aTasks[n], 0, sizeof(_aTasks[n]));
_NumTasks--;
} else if (n < _NumTasks) {
//
// Task is in the middle of the list.
// Move last item to current position and decrement number of tasks.
// Order of tasks does not really matter, so no need to move all following items.
//
_aTasks[n].xHandle = _aTasks[_NumTasks - 1].xHandle;
_aTasks[n].pcTaskName = _aTasks[_NumTasks - 1].pcTaskName;
_aTasks[n].uxCurrentPriority = _aTasks[_NumTasks - 1].uxCurrentPriority;
_aTasks[n].pxStack = _aTasks[_NumTasks - 1].pxStack;
_aTasks[n].uStackHighWaterMark = _aTasks[_NumTasks - 1].uStackHighWaterMark;
memset(&_aTasks[_NumTasks - 1], 0, sizeof(_aTasks[_NumTasks - 1]));
_NumTasks--;
}
}
/*********************************************************************
*
* SYSVIEW_SendTaskInfo()
*
* Function description
* Record task information.
*/
void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
SEGGER_SYSVIEW_TASKINFO TaskInfo;
memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
TaskInfo.TaskID = TaskID;
TaskInfo.sName = sName;
TaskInfo.Prio = Prio;
TaskInfo.StackBase = StackBase;
TaskInfo.StackSize = StackSize;
SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
}
/*********************************************************************
*
* Public API structures
*
**********************************************************************
*/
// Callbacks provided to SYSTEMVIEW by FreeRTOS
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
/* Callback _cbGetTime locks xKernelLock inside xTaskGetTickCountFromISR, this can cause deadlock on multi-core.
To prevent deadlock, always lock xKernelLock before s_sys_view_lock. Omitting the callback here results in sending
SYSVIEW_EVTID_SYSTIME_CYCLES events instead of SYSVIEW_EVTID_SYSTIME_US */
NULL,
_cbSendTaskList,
};
/*************************** End of file ****************************/

View File

@@ -0,0 +1,367 @@
/*
* SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
*
* SPDX-License-Identifier: BSD-1-Clause
*
* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD
*/
/*********************************************************************
* SEGGER Microcontroller GmbH *
* The Embedded Experts *
**********************************************************************
* *
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER SystemView * Real-time application analysis *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay *
* compatible with the SystemView and RTT protocol, and J-Link. *
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* condition is met: *
* *
* o Redistributions of source code must retain the above copyright *
* notice, this condition and the following disclaimer. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* SystemView version: 3.42 *
* *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_FreeRTOS.h
Purpose : Interface between FreeRTOS and SystemView.
Tested with FreeRTOS V10.4.3
Revision: $Rev: 7745 $
Notes:
(1) Include this file at the end of FreeRTOSConfig.h
*/
#ifndef SYSVIEW_FREERTOS_H
#define SYSVIEW_FREERTOS_H
#include "SEGGER_SYSVIEW.h"
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_APPTRACE_SV_MAX_TASKS
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
// for dual-core targets we use event ID to keep core ID bit (0 or 1)
// use the highest - 1 bit of event ID to indicate core ID
// the highest bit can not be used due to event ID encoding method
// this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
// so original continuous event IDs range is split into two sub-ranges for 1-bytes IDs and 2-bytes ones
// events which use apiFastID_OFFSET will have 1 byte ID,
// so for the sake of bandwidth economy events which are generated more frequently should use this ID offset
// currently all used events fall into this range
#define apiFastID_OFFSET (32u)
#define apiID_VTASKDELETE (1u)
#define apiID_VTASKDELAY (2u)
#define apiID_VTASKDELAYUNTIL (3u)
#define apiID_VTASKSUSPEND (4u)
#define apiID_ULTASKNOTIFYTAKE (5u)
#define apiID_VTASKNOTIFYGIVEFROMISR (6u)
#define apiID_VTASKPRIORITYINHERIT (7u)
#define apiID_VTASKRESUME (8u)
#define apiID_VTASKSTEPTICK (9u)
#define apiID_XTASKPRIORITYDISINHERIT (10u)
#define apiID_XTASKRESUMEFROMISR (11u)
#define apiID_XTASKGENERICNOTIFY (12u)
#define apiID_XTASKGENERICNOTIFYFROMISR (13u)
#define apiID_XTASKNOTIFYWAIT (14u)
#define apiID_XQUEUEGENERICCREATE (15u)
#define apiID_VQUEUEDELETE (16u)
#define apiID_XQUEUEGENERICRECEIVE (17u)
#define apiID_XQUEUEPEEKFROMISR (18u)
#define apiID_XQUEUERECEIVEFROMISR (19u)
#define apiID_VQUEUEADDTOREGISTRY (20u)
#define apiID_XQUEUEGENERICSEND (21u)
#define apiID_XQUEUEGENERICSENDFROMISR (22u)
#define apiID_VTASKPRIORITYSET (23u)
#define apiID_UXTASKPRIORITYGETFROMISR (24u)
#define apiID_XTASKGETTICKCOUNTFROMISR (25u)
#define apiID_XEVENTGROUPCLEARBITSFROMISR (26u)
#define apiID_XEVENTGROUPSETBITSFROMISR (27u)
#define apiID_XEVENTGROUPGETBITSFROMISR (28u)
#define apiID_XQUEUEGIVEFROMISR (29u)
#define apiID_XQUEUEISQUEUEEMPTYFROMISR (30u)
#define apiID_XQUEUEISQUEUEFULLFROMISR (31u) // the maximum allowed apiID for the first ID range
// events which use apiSlowID_OFFSET will have 2-bytes ID
#define apiSlowID_OFFSET (127u)
#define apiID_VTASKALLOCATEMPUREGIONS (1u)
#define apiID_UXTASKPRIORITYGET (2u)
#define apiID_ETASKGETSTATE (3u)
#define apiID_VTASKSTARTSCHEDULER (4u)
#define apiID_VTASKENDSCHEDULER (5u)
#define apiID_VTASKSUSPENDALL (6u)
#define apiID_XTASKRESUMEALL (7u)
#define apiID_XTASKGETTICKCOUNT (8u)
#define apiID_UXTASKGETNUMBEROFTASKS (9u)
#define apiID_PCTASKGETTASKNAME (10u)
#define apiID_UXTASKGETSTACKHIGHWATERMARK (11u)
#define apiID_VTASKSETAPPLICATIONTASKTAG (12u)
#define apiID_XTASKGETAPPLICATIONTASKTAG (13u)
#define apiID_VTASKSETTHREADLOCALSTORAGEPOINTER (14u)
#define apiID_PVTASKGETTHREADLOCALSTORAGEPOINTER (15u)
#define apiID_XTASKCALLAPPLICATIONTASKHOOK (16u)
#define apiID_XTASKGETIDLETASKHANDLE (17u)
#define apiID_UXTASKGETSYSTEMSTATE (18u)
#define apiID_VTASKLIST (19u)
#define apiID_VTASKGETRUNTIMESTATS (20u)
#define apiID_XTASKNOTIFYSTATECLEAR (21u)
#define apiID_XTASKGETCURRENTTASKHANDLE (22u)
#define apiID_VTASKSETTIMEOUTSTATE (23u)
#define apiID_XTASKCHECKFORTIMEOUT (24u)
#define apiID_VTASKMISSEDYIELD (25u)
#define apiID_XTASKGETSCHEDULERSTATE (26u)
#define apiID_XTASKGENERICCREATE (27u)
#define apiID_UXTASKGETTASKNUMBER (28u)
#define apiID_VTASKSETTASKNUMBER (29u)
#define apiID_ETASKCONFIRMSLEEPMODESTATUS (30u)
#define apiID_XTIMERCREATE (31u)
#define apiID_PVTIMERGETTIMERID (32u)
#define apiID_VTIMERSETTIMERID (33u)
#define apiID_XTIMERISTIMERACTIVE (34u)
#define apiID_XTIMERGETTIMERDAEMONTASKHANDLE (35u)
#define apiID_XTIMERPENDFUNCTIONCALLFROMISR (36u)
#define apiID_XTIMERPENDFUNCTIONCALL (37u)
#define apiID_PCTIMERGETTIMERNAME (38u)
#define apiID_XTIMERCREATETIMERTASK (39u)
#define apiID_XTIMERGENERICCOMMAND (40u)
#define apiID_UXQUEUEMESSAGESWAITING (41u)
#define apiID_UXQUEUESPACESAVAILABLE (42u)
#define apiID_UXQUEUEMESSAGESWAITINGFROMISR (43u)
#define apiID_XQUEUEALTGENERICSEND (44u)
#define apiID_XQUEUEALTGENERICRECEIVE (45u)
#define apiID_XQUEUECRSENDFROMISR (46u)
#define apiID_XQUEUECRRECEIVEFROMISR (47u)
#define apiID_XQUEUECRSEND (48u)
#define apiID_XQUEUECRRECEIVE (49u)
#define apiID_XQUEUECREATEMUTEX (50u)
#define apiID_XQUEUECREATECOUNTINGSEMAPHORE (51u)
#define apiID_XQUEUEGETMUTEXHOLDER (52u)
#define apiID_XQUEUETAKEMUTEXRECURSIVE (53u)
#define apiID_XQUEUEGIVEMUTEXRECURSIVE (54u)
#define apiID_VQUEUEUNREGISTERQUEUE (55u)
#define apiID_XQUEUECREATESET (56u)
#define apiID_XQUEUEADDTOSET (57u)
#define apiID_XQUEUEREMOVEFROMSET (58u)
#define apiID_XQUEUESELECTFROMSET (59u)
#define apiID_XQUEUESELECTFROMSETFROMISR (60u)
#define apiID_XQUEUEGENERICRESET (61u)
#define apiID_VLISTINITIALISE (62u)
#define apiID_VLISTINITIALISEITEM (63u)
#define apiID_VLISTINSERT (64u)
#define apiID_VLISTINSERTEND (65u)
#define apiID_UXLISTREMOVE (66u)
#define apiID_XEVENTGROUPCREATE (67u)
#define apiID_XEVENTGROUPWAITBITS (68u)
#define apiID_XEVENTGROUPCLEARBITS (69u)
#define apiID_XEVENTGROUPSETBITS (70u)
#define apiID_XEVENTGROUPSYNC (71u)
#define apiID_VEVENTGROUPDELETE (72u)
#define apiID_UXEVENTGROUPGETNUMBER (73u)
#define apiID_XSTREAMBUFFERCREATE (74u)
#define apiID_VSTREAMBUFFERDELETE (75u)
#define apiID_XSTREAMBUFFERRESET (76u)
#define apiID_XSTREAMBUFFERSEND (77u)
#define apiID_XSTREAMBUFFERSENDFROMISR (78u)
#define apiID_XSTREAMBUFFERRECEIVE (79u)
#define apiID_XSTREAMBUFFERRECEIVEFROMISR (80u)
#ifdef CONFIG_FREERTOS_SMP
#define traceQUEUE_SEND( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), 0u, 0u, 0u)
#else // CONFIG_FREERTOS_SMP
#if ( configUSE_QUEUE_SETS != 1 )
#define traceQUEUE_SEND( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, xTicksToWait, xCopyPosition)
#else
#define traceQUEUE_SEND( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), 0u, 0u, 0u)
#endif
#endif // CONFIG_FREERTOS_SMP
#define traceSTART() SEGGER_SYSVIEW_Conf()
#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_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))
#define traceINCREASE_TICK_COUNT( xTicksToJump ) SEGGER_SYSVIEW_RecordU32 (apiFastID_OFFSET + apiID_VTASKSTEPTICK, xTicksToJump)
#define traceTASK_SUSPEND( pxTCB ) SEGGER_SYSVIEW_RecordU32 (apiFastID_OFFSET + apiID_VTASKSUSPEND, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
#define traceTASK_PRIORITY_DISINHERIT( pxTCB, uxBasePriority ) SEGGER_SYSVIEW_RecordU32 (apiFastID_OFFSET + apiID_XTASKPRIORITYDISINHERIT, (U32)pxMutexHolder)
#define traceTASK_RESUME_FROM_ISR( pxTCB ) SEGGER_SYSVIEW_RecordU32 (apiFastID_OFFSET + apiID_XTASKRESUMEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
#define traceTASK_NOTIFY(uxIndexToNotify) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFY, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue)
#define traceTASK_NOTIFY_FROM_ISR(uxIndexToWait) SEGGER_SYSVIEW_RecordU32x5(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFYFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue, (U32)pxHigherPriorityTaskWoken)
#define traceTASK_NOTIFY_WAIT(uxIndexToWait) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKNOTIFYWAIT, ulBitsToClearOnEntry, ulBitsToClearOnExit, (U32)pulNotificationValue, xTicksToWait)
#define traceQUEUE_CREATE( pxNewQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUEGENERICCREATE, uxQueueLength, uxItemSize, ucQueueType)
#define traceQUEUE_DELETE( pxQueue ) SEGGER_SYSVIEW_RecordU32 (apiFastID_OFFSET + apiID_VQUEUEDELETE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue))
#define traceQUEUE_PEEK( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, 1)
#define traceQUEUE_PEEK_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEPEEKFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer))
#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEPEEKFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer))
#define traceQUEUE_RECEIVE( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 1)
#define traceQUEUE_RECEIVE_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 1)
#define traceQUEUE_SEMAPHORE_RECEIVE( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 0)
#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)
#define traceQUEUE_SEND_FAILED( pxQueue ) SEGGER_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)
#define traceQUEUE_GIVE_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pxHigherPriorityTaskWoken)
#define traceQUEUE_GIVE_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pxHigherPriorityTaskWoken)
#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERCREATE, (U32)xIsMessageBuffer, (U32)pxStreamBuffer)
#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERCREATE, (U32)xIsMessageBuffer, 0u)
#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) SEGGER_SYSVIEW_RecordU32 (apiSlowID_OFFSET + apiID_VSTREAMBUFFERDELETE, (U32)xStreamBuffer)
#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) SEGGER_SYSVIEW_RecordU32 (apiSlowID_OFFSET + apiID_XSTREAMBUFFERRESET, (U32)xStreamBuffer)
#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERSEND, (U32)xStreamBuffer, (U32)xBytesSent)
#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERSEND, (U32)xStreamBuffer, 0u)
#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERSENDFROMISR, (U32)xStreamBuffer, (U32)xBytesSent)
#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERRECEIVE, (U32)xStreamBuffer, (U32)xReceivedLength)
#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERRECEIVE, (U32)xStreamBuffer, 0u)
#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) SEGGER_SYSVIEW_RecordU32x2(apiSlowID_OFFSET + apiID_XSTREAMBUFFERRECEIVEFROMISR, (U32)xStreamBuffer, (U32)xReceivedLength)
#define traceTASK_DELETE( pxTCB ) do { \
SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKDELETE, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB)); \
SYSVIEW_DeleteTask((U32)pxTCB); \
} while(0)
#if( portSTACK_GROWTH < 0 )
#define traceTASK_CREATE(pxNewTCB) if (pxNewTCB != NULL) { \
SEGGER_SYSVIEW_OnTaskCreate((U32)pxNewTCB); \
SYSVIEW_AddTask((U32)pxNewTCB, \
&(pxNewTCB->pcTaskName[0]), \
pxNewTCB->uxPriority, \
(U32)pxNewTCB->pxStack, \
((U32)pxNewTCB->pxTopOfStack - (U32)pxNewTCB->pxStack) \
); \
}
#else
#define traceTASK_CREATE(pxNewTCB) if (pxNewTCB != NULL) { \
SEGGER_SYSVIEW_OnTaskCreate((U32)pxNewTCB); \
SYSVIEW_AddTask((U32)pxNewTCB, \
&(pxNewTCB->pcTaskName[0]), \
pxNewTCB->uxPriority, \
(U32)pxNewTCB->pxStack, \
(U32)(pxNewTCB->pxStack-pxNewTCB->pxTopOfStack) \
); \
}
#endif
#define traceTASK_PRIORITY_SET(pxTask, uxNewPriority) { \
SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET+apiID_VTASKPRIORITYSET, \
SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), \
uxNewPriority \
); \
SYSVIEW_UpdateTask((U32)pxTask, \
&(pxTask->pcTaskName[0]), \
uxNewPriority, \
(U32)pxTask->pxStack, \
0 \
); \
}
//
// 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))
#define traceTASK_SWITCHED_IN() if(prvGetTCBFromHandle(NULL) == xTaskGetIdleTaskHandle()) { \
SEGGER_SYSVIEW_OnIdle(); \
} else { \
SEGGER_SYSVIEW_OnTaskStartExec((U32)prvGetTCBFromHandle(NULL)); \
}
#else
#define traceTASK_SWITCHED_IN() { \
if (memcmp(prvGetTCBFromHandle(NULL)->pcTaskName, "IDLE", 4) != 0) { \
SEGGER_SYSVIEW_OnTaskStartExec((U32)prvGetTCBFromHandle(NULL)); \
} 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_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)
/*********************************************************************
*
* API functions
*
**********************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
void SYSVIEW_AddTask (U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark);
void SYSVIEW_UpdateTask (U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark);
void SYSVIEW_DeleteTask (U32 xHandle);
void SYSVIEW_SendTaskInfo (U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize);
#ifdef __cplusplus
}
#endif
#endif
/*************************** End of file ****************************/

View File

@@ -0,0 +1,300 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "string.h"
#include "freertos/FreeRTOS.h"
#include "SEGGER_RTT.h"
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_Conf.h"
#include "esp_app_trace.h"
#include "esp_log.h"
#include "esp_cpu.h"
#include "esp_private/startup_internal.h"
const static char *TAG = "segger_rtt";
#define SYSVIEW_EVENTS_BUF_SZ 255U
// size of down channel data buf
#define SYSVIEW_DOWN_BUF_SIZE 32
#define SEGGER_STOP_WAIT_TMO 1000000 //us
#if CONFIG_APPTRACE_SV_BUF_WAIT_TMO == -1
#define SEGGER_HOST_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
#else
#define SEGGER_HOST_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
#endif
static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ];
static uint16_t s_events_buf_filled;
static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
#if CONFIG_APPTRACE_SV_DEST_CPU_0 || CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
#define APPTRACE_SV_DEST_CPU 0
#else
#define APPTRACE_SV_DEST_CPU 1
#endif // CONFIG_APPTRACE_SV_DEST_CPU_0
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* SEGGER_RTT_ESP_FlushNoLock()
*
* Function description
* Flushes buffered events.
*
* Parameters
* min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. JTAG destinations only.
* tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
*
* Return value
* None.
*/
void SEGGER_RTT_ESP_FlushNoLock(unsigned long min_sz, unsigned long tmo)
{
esp_err_t res;
if (s_events_buf_filled > 0) {
res = esp_apptrace_write(s_events_buf, s_events_buf_filled, tmo);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Failed to flush buffered events (%d)!", res);
}
}
// flush even if we failed to write buffered events, because no new events will be sent after STOP
res = esp_apptrace_flush_nolock(min_sz, tmo);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Failed to flush apptrace data (%d)!", res);
}
s_events_buf_filled = 0;
}
/*********************************************************************
*
* SEGGER_RTT_ESP_Flush()
*
* Function description
* Flushes buffered events.
*
* Parameters
* min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. JTAG destinations only.
* tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
*
* Return value
* None.
*/
void SEGGER_RTT_ESP_Flush(unsigned long min_sz, unsigned long tmo)
{
SEGGER_SYSVIEW_LOCK();
SEGGER_RTT_ESP_FlushNoLock(min_sz, tmo);
SEGGER_SYSVIEW_UNLOCK();
}
/*********************************************************************
*
* SEGGER_RTT_ReadNoLock()
*
* Function description
* Reads characters from SEGGER real-time-terminal control block
* which have been previously stored by the host.
* Do not lock against interrupts and multiple access.
*
* Parameters
* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
* BufferSize Size of the target application buffer.
*
* Return value
* Number of bytes that have been read.
*/
unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize)
{
uint32_t size = BufferSize;
esp_err_t res = esp_apptrace_read(pData, &size, 0);
if (res != ESP_OK) {
return 0;
}
return size;
}
/*********************************************************************
*
* SEGGER_RTT_WriteSkipNoLock
*
* Function description
* Stores a specified number of characters in SEGGER RTT
* control block which is then read by the host.
* SEGGER_RTT_WriteSkipNoLock does not lock the application and
* skips all data, if the data does not fit into the buffer.
*
* Parameters
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
* pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
* NumBytes Number of bytes to be stored in the SEGGER RTT control block.
*
* Return value
* Number of bytes which have been stored in the "Up"-buffer.
*
* Notes
* (1) If there is not enough space in the "Up"-buffer, all data is dropped.
* (2) For performance reasons this function does not call Init()
* and may only be called after RTT has been initialized.
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
*/
unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes)
{
uint8_t *pbuf = (uint8_t *)pBuffer;
uint8_t event_id = *pbuf;
if (esp_apptrace_get_destination() == ESP_APPTRACE_DEST_UART) {
if (
(APPTRACE_SV_DEST_CPU != esp_cpu_get_core_id()) &&
(
(event_id == SYSVIEW_EVTID_ISR_ENTER) ||
(event_id == SYSVIEW_EVTID_ISR_EXIT) ||
(event_id == SYSVIEW_EVTID_TASK_START_EXEC) ||
(event_id == SYSVIEW_EVTID_TASK_STOP_EXEC) ||
(event_id == SYSVIEW_EVTID_TASK_START_READY) ||
(event_id == SYSVIEW_EVTID_TASK_STOP_READY) ||
(event_id == SYSVIEW_EVTID_MARK_START) ||
(event_id == SYSVIEW_EVTID_MARK_STOP) ||
(event_id == SYSVIEW_EVTID_TIMER_ENTER) ||
(event_id == SYSVIEW_EVTID_TIMER_EXIT) ||
(event_id == SYSVIEW_EVTID_STACK_INFO) ||
(event_id == SYSVIEW_EVTID_MODULEDESC)
)
) {
return NumBytes;
}
// This is workaround for SystemView!
// Without this line SystemView will hangs on when heap tracing enabled.
if (event_id == SYSVIEW_EVTID_MODULEDESC) {
return NumBytes;
}
}
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
return 0;
}
if (esp_apptrace_get_destination() == ESP_APPTRACE_DEST_JTAG) {
if (esp_cpu_get_core_id()) { // dual core specific code
// use the highest - 1 bit of event ID to indicate core ID
// the highest bit can not be used due to event ID encoding method
// this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
if (*pbuf & 0x80) { // 2 bytes ID
*(pbuf + 1) |= (1 << 6);
} else if (NumBytes != 10 || *pbuf != 0) { // ignore sync sequence
*pbuf |= (1 << 6);
}
}
if (s_events_buf_filled + NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
esp_err_t res = esp_apptrace_write(s_events_buf, s_events_buf_filled, SEGGER_HOST_WAIT_TMO);
if (res != ESP_OK) {
return 0; // skip current data buffer only, accumulated events are kept
}
s_events_buf_filled = 0;
}
}
memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes);
s_events_buf_filled += NumBytes;
if (esp_apptrace_get_destination() == ESP_APPTRACE_DEST_UART) {
esp_err_t res = esp_apptrace_write(pBuffer, NumBytes, SEGGER_HOST_WAIT_TMO);
if (res != ESP_OK) {
return 0; // skip current data buffer only, accumulated events are kept
}
s_events_buf_filled = 0;
}
if (event_id == SYSVIEW_EVTID_TRACE_STOP) {
SEGGER_RTT_ESP_FlushNoLock(0, SEGGER_STOP_WAIT_TMO);
}
return NumBytes;
}
/*********************************************************************
*
* SEGGER_RTT_ConfigUpBuffer
*
* Function description
* Run-time configuration of a specific up-buffer (T->H).
* Buffer to be configured is specified by index.
* This includes: Buffer address, size, name, flags, ...
*
* Parameters
* BufferIndex Index of the buffer to configure.
* sName Pointer to a constant name string.
* pBuffer Pointer to a buffer to be used.
* BufferSize Size of the buffer.
* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
*
* Return value
* >= 0 - O.K.
* < 0 - Error
*
* Additional information
* Buffer 0 is configured on compile-time.
* May only be called once per buffer.
* Buffer name and flags can be reconfigured using the appropriate functions.
*/
int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags)
{
s_events_buf_filled = 0;
return 0;
}
/*********************************************************************
*
* SEGGER_RTT_ConfigDownBuffer
*
* Function description
* Run-time configuration of a specific down-buffer (H->T).
* Buffer to be configured is specified by index.
* This includes: Buffer address, size, name, flags, ...
*
* Parameters
* BufferIndex Index of the buffer to configure.
* sName Pointer to a constant name string.
* pBuffer Pointer to a buffer to be used.
* BufferSize Size of the buffer.
* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
*
* Return value
* >= 0 O.K.
* < 0 Error
*
* Additional information
* Buffer 0 is configured on compile-time.
* May only be called once per buffer.
* Buffer name and flags can be reconfigured using the appropriate functions.
*/
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags)
{
return esp_apptrace_down_buffer_config(s_down_buf, sizeof(s_down_buf));
}
/*************************** Init hook ****************************
*
* This init function is placed here because this port file will be linked whenever SystemView is used.
* It is used to initialize SystemView and app trace configuration by the init hook function.
* Otherwise, SystemView and app trace initialization needs to be done later in the app_main.
*/
ESP_SYSTEM_INIT_FN(sysview_early_init, SECONDARY, BIT(0), 120)
{
esp_apptrace_set_header_size(ESP_APPTRACE_HEADER_SIZE_16);
SEGGER_SYSVIEW_Conf();
return ESP_OK;
}
/*************************** End of file ****************************/

View File

@@ -0,0 +1,91 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <sdkconfig.h>
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_RTT.h"
#include "esp_app_trace.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
const static char *TAG = "sysview_heap_trace";
#ifdef CONFIG_HEAP_TRACING_STACK_DEPTH
#define CALLSTACK_SIZE CONFIG_HEAP_TRACING_STACK_DEPTH
#else
#define CALLSTACK_SIZE 0
#endif
static SEGGER_SYSVIEW_MODULE s_esp_sysview_heap_module = {
.sModule = "M=ESP32 SystemView Heap Tracing Module",
.NumEvents = 2,
};
static bool s_mod_registered;
esp_err_t esp_sysview_heap_trace_start(uint32_t tmo)
{
uint32_t tmo_ticks = tmo / (1000 * portTICK_PERIOD_MS);
ESP_EARLY_LOGV(TAG, "%s", __func__);
do {
if (tmo != (uint32_t) -1) {
// Currently timeout implementation is simple and has granularity of 1 OS tick,
// so just count down the number of times to call vTaskDelay
if (tmo_ticks-- == 0) {
return ESP_ERR_TIMEOUT;
}
}
vTaskDelay(1);
} while (!SEGGER_SYSVIEW_Started());
SEGGER_SYSVIEW_RegisterModule(&s_esp_sysview_heap_module);
s_mod_registered = true;
return ESP_OK;
}
esp_err_t esp_sysview_heap_trace_stop(void)
{
ESP_EARLY_LOGV(TAG, "%s", __func__);
SEGGER_RTT_ESP_Flush(0, ESP_APPTRACE_TMO_INFINITE);
return ESP_OK;
}
void esp_sysview_heap_trace_alloc(const void *addr, uint32_t size, const void *callers)
{
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (2 + CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
U32 *calls = (U32 *)callers;
if (!s_mod_registered) {
return;
}
ESP_EARLY_LOGV(TAG, "%s %p %lu", __func__, addr, size);
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, size);
for (int i = 0; i < CALLSTACK_SIZE; i++) {
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
}
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 0);
}
void esp_sysview_heap_trace_free(const void *addr, const void *callers)
{
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (1 + CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
U32 *calls = (U32 *)callers;
if (!s_mod_registered) {
return;
}
ESP_EARLY_LOGV(TAG, "%s %p", __func__, addr);
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
for (int i = 0; i < CALLSTACK_SIZE; i++) {
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
}
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 1);
}

View File

@@ -0,0 +1,26 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdarg.h>
#include <sdkconfig.h>
#include "SEGGER_SYSVIEW_Int.h"
#include "freertos/FreeRTOS.h"
static portMUX_TYPE s_log_mutex = portMUX_INITIALIZER_UNLOCKED;
int esp_sysview_vprintf(const char * format, va_list args)
{
static char log_buffer[SEGGER_SYSVIEW_MAX_STRING_LEN];
portENTER_CRITICAL(&s_log_mutex);
size_t len = vsnprintf(log_buffer, sizeof(log_buffer), format, args);
if (len > sizeof(log_buffer) - 1) {
log_buffer[sizeof(log_buffer) - 1] = 0;
}
SEGGER_SYSVIEW_Print(log_buffer);
portEXIT_CRITICAL(&s_log_mutex);
return len;
}

View File

@@ -2,7 +2,11 @@
components/app_trace/test_apps:
depends_components:
- esp_trace
- app_trace
- esp_timer
- soc
- esp_hw_support
- esp_driver_uart
- esp_driver_gptimer
disable:
- if: IDF_TARGET in ["esp32h21", "esp32h4"]

View File

@@ -8,4 +8,9 @@ To build and run this test app for app_trace related tests:
IDF_TARGET=esp32 idf.py @app_trace build flash monitor
```
`@app_trace` argument apply additional `idf.py` options, from [app_trace](app_trace) and file.
To build and run this test app for SystemView related tests:
```bash
IDF_TARGET=esp32 idf.py @sysview build flash monitor
```
`@app_trace` and `@sysview` arguments apply additional `idf.py` options, from [app_trace](app_trace) and [sysview](sysview) files.

View File

@@ -1,4 +1,4 @@
idf_component_register(SRCS "test_app_trace_main.c" "test_trace.c"
INCLUDE_DIRS "."
PRIV_REQUIRES esp_trace unity esp_driver_gptimer
PRIV_REQUIRES app_trace unity esp_driver_gptimer
WHOLE_ARCHIVE)

View File

@@ -16,10 +16,10 @@
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "esp_app_trace.h"
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "esp_log.h"
#include "esp_app_trace.h"
#define ESP_APPTRACE_TEST_USE_PRINT_LOCK 0
#define ESP_APPTRACE_TEST_PRN_WRERR_MAX 5
@@ -65,6 +65,7 @@ const static char *TAG = "esp_apptrace_test";
#define ESP_APPTRACE_TEST_LOGV( format, ... ) ESP_APPTRACE_TEST_LOG_LEVEL(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__)
#define ESP_APPTRACE_TEST_LOGO( format, ... ) ESP_APPTRACE_TEST_LOG_LEVEL(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
#if CONFIG_APPTRACE_SV_ENABLE == 0
#define ESP_APPTRACE_TEST_WRITE(_b_, _s_) esp_apptrace_write(_b_, _s_, ESP_APPTRACE_TMO_INFINITE)
#define ESP_APPTRACE_TEST_WRITE_FROM_ISR(_b_, _s_) esp_apptrace_write(_b_, _s_, 0UL)
#define ESP_APPTRACE_TEST_WRITE_NOWAIT(_b_, _s_) esp_apptrace_write(_b_, _s_, 0)
@@ -692,3 +693,233 @@ TEST_CASE("Log trace test (2 tasks)", "[trace][ignore]")
xSemaphoreTake(arg2.done, portMAX_DELAY);
vSemaphoreDelete(arg2.done);
}
#else // #if CONFIG_APPTRACE_SV_ENABLE == 0
typedef struct {
gptimer_handle_t gptimer;
uint32_t period;
int flags;
uint32_t id;
} esp_sysviewtrace_timer_arg_t;
typedef struct {
SemaphoreHandle_t done;
SemaphoreHandle_t *sync;
esp_sysviewtrace_timer_arg_t *timer;
uint32_t work_count;
uint32_t sleep_tmo;
uint32_t id;
} esp_sysviewtrace_task_arg_t;
static bool esp_sysview_test_timer_isr(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
esp_sysviewtrace_timer_arg_t *tim_arg = (esp_sysviewtrace_timer_arg_t *)user_ctx;
(void) tim_arg;
return false;
}
static void esp_sysviewtrace_test_task(void *p)
{
esp_sysviewtrace_task_arg_t *arg = (esp_sysviewtrace_task_arg_t *) p;
volatile uint32_t tmp = 0;
printf("%p: run sysview task\n", xTaskGetCurrentTaskHandle());
if (arg->timer) {
gptimer_alarm_config_t alarm_config = {
.reload_count = 0,
.alarm_count = arg->timer->period,
.flags.auto_reload_on_alarm = true,
};
gptimer_event_callbacks_t cbs = {
.on_alarm = esp_sysview_test_timer_isr,
};
TEST_ESP_OK(gptimer_register_event_callbacks(arg->timer->gptimer, &cbs, arg->timer));
TEST_ESP_OK(gptimer_enable(arg->timer->gptimer));
TEST_ESP_OK(gptimer_set_alarm_action(arg->timer->gptimer, &alarm_config));
TEST_ESP_OK(gptimer_start(arg->timer->gptimer));
}
int i = 0;
while (1) {
static uint32_t count;
printf("%" PRIu32, arg->id);
if ((++count % 80) == 0) {
printf("\n");
}
if (arg->sync) {
xSemaphoreTake(*arg->sync, portMAX_DELAY);
}
for (uint32_t k = 0; k < arg->work_count; k++) {
tmp++;
}
vTaskDelay(arg->sleep_tmo / portTICK_PERIOD_MS);
i++;
if (arg->sync) {
xSemaphoreGive(*arg->sync);
}
}
ESP_APPTRACE_TEST_LOGI("%p: finished", xTaskGetCurrentTaskHandle());
xSemaphoreGive(arg->done);
vTaskDelay(1);
vTaskDelete(NULL);
}
TEST_CASE("SysView trace test 1", "[trace][ignore]")
{
TaskHandle_t thnd;
esp_sysviewtrace_timer_arg_t tim_arg1 = {
.flags = ESP_INTR_FLAG_SHARED,
.id = 0,
.period = 500,
};
esp_sysviewtrace_task_arg_t arg1 = {
.done = xSemaphoreCreateBinary(),
.sync = NULL,
.work_count = 10000,
.sleep_tmo = 1,
.timer = &tim_arg1,
.id = 0,
};
esp_sysviewtrace_timer_arg_t tim_arg2 = {
.flags = 0,
.id = 1,
.period = 100,
};
esp_sysviewtrace_task_arg_t arg2 = {
.done = xSemaphoreCreateBinary(),
.sync = NULL,
.work_count = 10000,
.sleep_tmo = 1,
.timer = &tim_arg2,
.id = 1,
};
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000,
};
timer_config.flags.intr_shared = (tim_arg1.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg1.gptimer));
timer_config.flags.intr_shared = (tim_arg2.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg2.gptimer));
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace0", 2048, &arg1, 3, &thnd, 0);
ESP_APPTRACE_TEST_LOGI("Created task %p", thnd);
#if CONFIG_FREERTOS_UNICORE == 0
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace1", 2048, &arg2, 5, &thnd, 1);
#else
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace1", 2048, &arg2, 5, &thnd, 0);
#endif
ESP_APPTRACE_TEST_LOGI("Created task %p", thnd);
xSemaphoreTake(arg1.done, portMAX_DELAY);
vSemaphoreDelete(arg1.done);
xSemaphoreTake(arg2.done, portMAX_DELAY);
vSemaphoreDelete(arg2.done);
TEST_ESP_OK(gptimer_stop(tim_arg1.gptimer));
TEST_ESP_OK(gptimer_disable(tim_arg1.gptimer));
TEST_ESP_OK(gptimer_del_timer(tim_arg1.gptimer));
TEST_ESP_OK(gptimer_stop(tim_arg2.gptimer));
TEST_ESP_OK(gptimer_disable(tim_arg2.gptimer));
TEST_ESP_OK(gptimer_del_timer(tim_arg2.gptimer));
}
TEST_CASE("SysView trace test 2", "[trace][ignore]")
{
TaskHandle_t thnd;
esp_sysviewtrace_timer_arg_t tim_arg1 = {
.flags = ESP_INTR_FLAG_SHARED,
.id = 0,
.period = 500,
};
esp_sysviewtrace_task_arg_t arg1 = {
.done = xSemaphoreCreateBinary(),
.sync = NULL,
.work_count = 10000,
.sleep_tmo = 1,
.timer = &tim_arg1,
.id = 0,
};
esp_sysviewtrace_timer_arg_t tim_arg2 = {
.flags = 0,
.id = 1,
.period = 100,
};
esp_sysviewtrace_task_arg_t arg2 = {
.done = xSemaphoreCreateBinary(),
.sync = NULL,
.work_count = 10000,
.sleep_tmo = 1,
.timer = &tim_arg2,
.id = 1,
};
SemaphoreHandle_t test_sync = xSemaphoreCreateBinary();
xSemaphoreGive(test_sync);
esp_sysviewtrace_task_arg_t arg3 = {
.done = xSemaphoreCreateBinary(),
.sync = &test_sync,
.work_count = 1000,
.sleep_tmo = 1,
.timer = NULL,
.id = 2,
};
esp_sysviewtrace_task_arg_t arg4 = {
.done = xSemaphoreCreateBinary(),
.sync = &test_sync,
.work_count = 10000,
.sleep_tmo = 1,
.timer = NULL,
.id = 3,
};
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000,
};
timer_config.flags.intr_shared = (tim_arg1.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg1.gptimer));
timer_config.flags.intr_shared = (tim_arg2.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg2.gptimer));
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace0", 2048, &arg1, 3, &thnd, 0);
printf("Created task %p\n", thnd);
#if CONFIG_FREERTOS_UNICORE == 0
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace1", 2048, &arg2, 4, &thnd, 1);
#else
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace1", 2048, &arg2, 4, &thnd, 0);
#endif
printf("Created task %p\n", thnd);
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svsync0", 2048, &arg3, 3, &thnd, 0);
printf("Created task %p\n", thnd);
#if CONFIG_FREERTOS_UNICORE == 0
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svsync1", 2048, &arg4, 5, &thnd, 1);
#else
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svsync1", 2048, &arg4, 5, &thnd, 0);
#endif
printf("Created task %p\n", thnd);
xSemaphoreTake(arg1.done, portMAX_DELAY);
vSemaphoreDelete(arg1.done);
xSemaphoreTake(arg2.done, portMAX_DELAY);
vSemaphoreDelete(arg2.done);
xSemaphoreTake(arg3.done, portMAX_DELAY);
vSemaphoreDelete(arg3.done);
xSemaphoreTake(arg4.done, portMAX_DELAY);
vSemaphoreDelete(arg4.done);
vSemaphoreDelete(test_sync);
TEST_ESP_OK(gptimer_stop(tim_arg1.gptimer));
TEST_ESP_OK(gptimer_disable(tim_arg1.gptimer));
TEST_ESP_OK(gptimer_del_timer(tim_arg1.gptimer));
TEST_ESP_OK(gptimer_stop(tim_arg2.gptimer));
TEST_ESP_OK(gptimer_disable(tim_arg2.gptimer));
TEST_ESP_OK(gptimer_del_timer(tim_arg2.gptimer));
}
#endif // #if CONFIG_APPTRACE_SV_ENABLE == 0

View File

@@ -1,3 +1 @@
CONFIG_ESP_TRACE_LIB_NONE=y
CONFIG_ESP_TRACE_TRANSPORT_APPTRACE=y
CONFIG_APPTRACE_DEST_JTAG=y
# app_trace is already enabled by sdkconfig.defaults, so no options are needed here

View File

@@ -0,0 +1 @@
CONFIG_APPTRACE_SV_ENABLE=y

View File

@@ -1,2 +1,3 @@
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
CONFIG_ESP_TRACE_ENABLE=y
CONFIG_APPTRACE_ENABLE=y
CONFIG_APPTRACE_DEST_JTAG=y

View File

@@ -0,0 +1 @@
-DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.ci.sysview" -B build/sysview -DSDKCONFIG=build/sysview/sdkconfig

View File

@@ -15,9 +15,6 @@ components/app_update/test_apps:
- if: IDF_TARGET == "esp32c61" and CONFIG_NAME == "xip_psram_with_rom_impl"
temporary: true
reason: not supported yet # TODO: [ESP32C61] IDF-12784
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: p4 rev3 migration # TODO: IDF-14401
disable_test:
- if: CONFIG_NAME == "recovery_bootloader" and SOC_RECOVERY_BOOTLOADER_SUPPORTED == 1 and IDF_TARGET == "esp32c61"
temporary: true

View File

@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |

View File

@@ -139,7 +139,7 @@ TEST_CASE_MULTIPLE_STAGES("OTA update of partition_table via primary partition",
TEST_CASE("OTA update of NVS partition", "[nvs_ota]")
{
// initialize "nvs" partition and define a var (magic_value).
// intilaize "nvs" partition and define a var (magic_value).
TEST_ESP_OK(nvs_flash_erase());
TEST_ESP_OK(nvs_flash_init());
nvs_handle_t my_handle;
@@ -220,7 +220,7 @@ TEST_CASE_MULTIPLE_STAGES("OTA update of partition_table via a free ota partitio
TEST_CASE("OTA update of NVS partition via a free ota partition", "[nvs_ota]")
{
// initialize "nvs" partition and define a var (magic_value).
// intilaize "nvs" partition and define a var (magic_value).
const esp_partition_t *nvs_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, "nvs");
TEST_ESP_OK(nvs_flash_erase());
TEST_ESP_OK(nvs_flash_init());

View File

@@ -35,9 +35,4 @@ if(NOT CONFIG_SECURE_BOOT OR CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT)
# Add bootloader as a dependency to the flash target
add_dependencies(flash bootloader)
if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
# Also add bootloader as a dependency to the encrypted-flash target
add_dependencies(encrypted-flash bootloader)
endif()
endif()

View File

@@ -839,26 +839,6 @@ menu "Security features"
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html
before enabling.
choice SECURE_FLASH_ENCRYPTION_KEY_SOURCE
bool "Flash Encryption Key Source"
depends on SECURE_FLASH_ENC_ENABLED
default SECURE_FLASH_ENCRYPTION_KEY_SOURCE_EFUSES
help
Specify the key source for the Flash Encryption Key
config SECURE_FLASH_ENCRYPTION_KEY_SOURCE_EFUSES
bool "eFuse Key Block"
help
Use a key that is stored in the eFuses key blocks.
config SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR
bool "Key Manager"
depends on SOC_KEY_MANAGER_SUPPORTED && SOC_KEY_MANAGER_FE_KEY_DEPLOY && \
!(IDF_TARGET_ESP32P4 && ESP32P4_SELECTS_REV_LESS_V3)
help
Use a key that is deployed using the Key Manager
endchoice
choice SECURE_FLASH_ENCRYPTION_KEYSIZE
bool "Size of generated XTS-AES key"
default SECURE_FLASH_ENCRYPTION_AES128
@@ -880,16 +860,11 @@ menu "Security features"
config SECURE_FLASH_ENCRYPTION_AES128
bool "AES-128 (256-bit key)"
depends on SOC_FLASH_ENCRYPTION_XTS_AES_128 && \
((SECURE_FLASH_ENCRYPTION_KEY_SOURCE_EFUSES && SOC_EFUSE_XTS_AES_KEY_128) || \
(SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR && SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_128)) && \
!(IDF_TARGET_ESP32C2 && SECURE_BOOT)
depends on SOC_FLASH_ENCRYPTION_XTS_AES_128 && !(IDF_TARGET_ESP32C2 && SECURE_BOOT)
config SECURE_FLASH_ENCRYPTION_AES256
bool "AES-256 (512-bit key)"
depends on SOC_FLASH_ENCRYPTION_XTS_AES_256 && \
((SECURE_FLASH_ENCRYPTION_KEY_SOURCE_EFUSES && SOC_EFUSE_XTS_AES_KEY_256) || \
(SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR && SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_256))
depends on SOC_FLASH_ENCRYPTION_XTS_AES_256
endchoice
choice SECURE_FLASH_ENCRYPTION_MODE
@@ -999,7 +974,7 @@ menu "Security features"
config SECURE_BOOT_SKIP_WRITE_PROTECTION_SCA
bool "Skip write-protection of SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH"
default y if SECURE_FLASH_PSEUDO_ROUND_FUNC && !SECURE_FLASH_ENCRYPTION_MODE_RELEASE
default y if SECURE_FLASH_PSEUDO_ROUND_FUNC
default n
depends on SOC_ECDSA_SUPPORT_CURVE_P384 && SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
help

View File

@@ -91,11 +91,6 @@ SECTIONS
*libhal.a:cache_hal.*(.literal .text .literal.* .text.*)
*libhal.a:efuse_hal.*(.literal .text .literal.* .text.*)
*libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
*libhal.a:huk_hal.*(.literal .text .literal.* .text.*)
*libhal.a:key_mgr_hal.*(.literal .text .literal.* .text.*)
*libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*)
*libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*)
*libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*)

View File

@@ -90,7 +90,6 @@ SECTIONS
*libhal.a:cache_hal.*(.literal .text .literal.* .text.*)
*libhal.a:efuse_hal.*(.literal .text .literal.* .text.*)
*libhal.a:key_mgr_hal.*(.literal.key_mgr_hal_set_key_usage .text.key_mgr_hal_set_key_usage)
*libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*)
*libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*)

View File

@@ -89,12 +89,8 @@ SECTIONS
*libhal.a:mmu_hal.*(.literal .text .literal.* .text.*)
*libhal.a:cache_hal.*(.literal .text .literal.* .text.*)
*libhal.a:efuse_hal.*(.literal .text .literal.* .text.*)
*libhal.a:key_mgr_hal.*(.literal.key_mgr_hal_set_key_usage .text.key_mgr_hal_set_key_usage)
*libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
*libhal.a:huk_hal.*(.literal .text .literal.* .text.*)
*libhal.a:key_mgr_hal.*(.literal .text .literal.* .text.*)
*libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*)
*libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*)
*libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*)

View File

@@ -93,8 +93,6 @@ endif()
if(BOOTLOADER_BUILD)
list(APPEND srcs "src/bootloader_panic.c")
list(APPEND priv_requires esp_security)
if(CONFIG_SECURE_FLASH_ENC_ENABLED)
list(APPEND srcs "src/flash_encryption/flash_encrypt.c"
"src/${IDF_TARGET}/flash_encryption_secure_features.c")

View File

@@ -217,10 +217,13 @@ static uint32_t current_mapped_size;
// Current bootloader mapping (ab)used for bootloader_read()
static uint32_t current_read_mapping = UINT32_MAX;
#if ESP_TEE_BUILD
/* [ESP-TEE] Workarounds for the ROM SPI flash APIs */
/*
* TODO: The esp_rom_spiflash_read API requires two workarounds on ESP32-C6 ECO0 -
#if ESP_TEE_BUILD && CONFIG_IDF_TARGET_ESP32C6
extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode);
extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
/* TODO: [ESP-TEE] Workarounds for the ROM read API
*
* The esp_rom_spiflash_read API requires two workarounds on ESP32-C6 ECO0:
*
* 1. [IDF-7199] Call esp_rom_spiflash_write API once before reading.
* Without this, reads return corrupted data.
@@ -228,14 +231,10 @@ static uint32_t current_read_mapping = UINT32_MAX;
* 2. Configure ROM flash parameters before each read using the function below.
* Without this, the first byte read is corrupted.
*
* NOTE: These workarounds are not needed for ESP32-C6 ECO1 and later versions.
* Note: These workarounds are not needed for ESP32-C6 ECO1 and later versions.
*/
static void rom_read_api_workaround(void)
{
#if CONFIG_ESP32C6_REV_MIN_0
extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode);
extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
static bool is_first_call = true;
if (is_first_call) {
uint32_t dummy_val = UINT32_MAX;
@@ -269,43 +268,6 @@ static void rom_read_api_workaround(void)
spi_dummy_len_fix(1, freqdiv);
esp_rom_spiflash_config_readmode(read_mode);
spi_common_set_dummy_output(read_mode);
#endif
}
/*
* TODO: [IDF-13582]
*
* When `esp_flash_read()` is invoked from REE, it enables SPI1 WB (write-back) mode
* via `spi_flash_ll_wb_mode_enable()`. The ROM flash APIs used by TEE do not support
* WB mode, causing failures when TEE later accesses flash.
*
* Workaround applied in TEE flash layer:
* 1. Save the current WB mode state.
* 2. Temporarily disable WB mode before calling ROM flash APIs.
* 3. Restore WB mode state after the ROM API call completes.
*
* NOTE: This workaround will become removed once IDF-13582 is implemented.
*/
static inline bool spi1_wb_mode_save_and_disable(void)
{
#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
if (REG_GET_BIT(SPI_MEM_RD_STATUS_REG(1), SPI_MEM_WB_MODE_EN)) {
REG_CLR_BIT(SPI_MEM_RD_STATUS_REG(1), SPI_MEM_WB_MODE_EN);
return true;
}
#endif
return false;
}
static inline void spi1_wb_mode_restore(bool saved_state)
{
#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
if (saved_state) {
REG_SET_BIT(SPI_MEM_RD_STATUS_REG(1), SPI_MEM_WB_MODE_EN);
}
#else
(void)saved_state;
#endif
}
#endif
@@ -454,9 +416,8 @@ static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, s
#else
#if !ESP_TEE_BUILD
cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
#else
#elif CONFIG_ESP32C6_REV_MIN_0
rom_read_api_workaround();
bool is_wb_saved = spi1_wb_mode_save_and_disable();
#endif
#endif
@@ -467,8 +428,6 @@ static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, s
#else
#if !ESP_TEE_BUILD
cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
#else
spi1_wb_mode_restore(is_wb_saved);
#endif
#endif
@@ -591,10 +550,6 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool
return err;
}
#if ESP_TEE_BUILD
bool is_wb_saved = spi1_wb_mode_save_and_disable();
#endif
esp_rom_spiflash_result_t rc = ESP_ROM_SPIFLASH_RESULT_OK;
if (write_encrypted && !ENCRYPTION_IS_VIRTUAL) {
@@ -609,7 +564,6 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool
* from being read from already memory-mapped addresses that were modified.
*/
#if ESP_TEE_BUILD
spi1_wb_mode_restore(is_wb_saved);
spi_flash_check_and_flush_cache(dest_addr, size);
#endif

View File

@@ -382,6 +382,13 @@ static void IRAM_ATTR bootloader_init_flash_configure(void)
esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {
ESP_EARLY_LOGD(TAG, "Using overridden bootloader_flash_unlock");

View File

@@ -101,10 +101,10 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
if (hd_gpio_num < SOC_GPIO_PIN_COUNT) {
if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
}
if (wp_gpio_num < SOC_GPIO_PIN_COUNT) {
if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
}
}

View File

@@ -112,10 +112,10 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
if (hd_gpio_num < SOC_GPIO_PIN_COUNT) {
if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
}
if (wp_gpio_num < SOC_GPIO_PIN_COUNT) {
if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
}
}
@@ -256,6 +256,13 @@ static void bootloader_spi_flash_resume(void)
esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
bootloader_spi_flash_resume();
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {

View File

@@ -237,12 +237,6 @@ esp_err_t bootloader_init_spi_flash(void)
bootloader_init_mspi_clock();
bootloader_init_flash_configure();
#if CONFIG_BOOTLOADER_FLASH_DC_AWARE
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
bootloader_spi_flash_reset();
#endif
bootloader_spi_flash_resume();
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {
ESP_EARLY_LOGD(TAG, "Using overridden bootloader_flash_unlock");

View File

@@ -114,10 +114,10 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
if (hd_gpio_num < SOC_GPIO_PIN_COUNT) {
if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
}
if (wp_gpio_num < SOC_GPIO_PIN_COUNT) {
if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
}
}
@@ -254,6 +254,13 @@ static void IRAM_ATTR bootloader_init_flash_configure(void)
esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {
ESP_EARLY_LOGD(TAG, "Using overridden bootloader_flash_unlock");

View File

@@ -125,10 +125,10 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
if (hd_gpio_num < SOC_GPIO_PIN_COUNT) {
if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
}
if (wp_gpio_num < SOC_GPIO_PIN_COUNT) {
if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
}
}
@@ -272,6 +272,13 @@ static void bootloader_spi_flash_resume(void)
esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
#if CONFIG_BOOTLOADER_FLASH_DC_AWARE
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,6 +9,7 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "soc/soc_caps.h"
#include "hal/efuse_ll.h"
#include "sdkconfig.h"
#ifdef __cplusplus
@@ -183,14 +184,14 @@ void esp_flash_encryption_init_checks(void);
*/
esp_err_t esp_flash_encryption_enable_secure_features(void);
#if SOC_KEY_MANAGER_FE_KEY_DEPLOY
#if CONFIG_SOC_KEY_MANAGER_FE_KEY_DEPLOY
/** @brief Enable the key manager for flash encryption
*
* @return
* - ESP_OK - On success
*/
esp_err_t esp_flash_encryption_use_efuse_key(void);
#endif // SOC_KEY_MANAGER_FE_KEY_DEPLOY
esp_err_t esp_flash_encryption_enable_key_mgr(void);
#endif // CONFIG_SOC_KEY_MANAGER_FE_KEY_DEPLOY
#endif /* BOOTLOADER_BUILD && CONFIG_SECURE_FLASH_ENC_ENABLED */

View File

@@ -263,11 +263,7 @@ rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
#ifdef BOOTLOADER_BUILD
#if ESP_ROM_HAS_LP_ROM
#if CONFIG_IDF_TARGET_ESP32P4
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_LOW + CONFIG_P4_REV3_MSPI_WORKAROUND_SIZE)
#else
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_LOW)
#endif
#else
/* Since the structure containing the retain_mem_t is aligned on 8 by the linker, make sure we align this
* structure size here too */

View File

@@ -30,7 +30,6 @@ static void __attribute__((unused)) release_default_console_io(void)
{
// Default console is UART0 with TX and RX on their IOMUX pins
gpio_ll_output_disable(&GPIO, U0TXD_GPIO_NUM);
gpio_ll_func_sel(&GPIO, U0TXD_GPIO_NUM, PIN_FUNC_GPIO); // Set TX pin to GPIO function to truly disable output
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(UART_NUM_0, SOC_UART_PERIPH_SIGNAL_RX), 0);
}

View File

@@ -9,8 +9,7 @@
#include "soc/sens_reg.h"
#include "soc/syscon_reg.h"
#include "soc/dport_reg.h"
#include "soc/i2s_reg.h"
#include "soc/periph_defs.h"
#include "soc/i2s_periph.h"
#include "esp_log.h"
#include "soc/io_mux_reg.h"

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,60 +12,56 @@
#include "soc/system_reg.h"
#include "esp_private/regi2c_ctrl.h"
#include "soc/regi2c_saradc.h"
#include "hal/adc_ll.h"
#include "hal/sar_ctrl_ll.h"
#include "hal/clk_gate_ll.h"
#define ADC_RNG_CLKM_DIV_NUM 15
#define ADC_RNG_CLKM_DIV_B 0
#define ADC_RNG_CLKM_DIV_A 0
void bootloader_random_enable(void)
{
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
/* RNG module is always clock enabled */
REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0x3);
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M);
#ifndef BOOTLOADER_BUILD
regi2c_saradc_enable();
#else
regi2c_ctrl_ll_i2c_sar_periph_enable();
#endif
ANALOG_CLOCK_ENABLE();
adc_ll_regi2c_init();
// Bridging sar2 internal reference voltage
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
_adc_ll_enable_bus_clock(true);
_adc_ll_reset_register();
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_PLL_F80M);
adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A);
adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON);
adc_ll_digi_set_clk_div(1);
// Enable SAR ADC2 internal channel to read adc2 ref voltage for additional entropy
SET_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M);
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M);
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_REG_CLK_SEL, 0x2);
SET_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M);
SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M);
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE, 0x3);
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_DIV, 1);
adc_ll_digi_set_fsm_time(ADC_LL_FSM_RSTB_WAIT_DEFAULT, ADC_LL_FSM_START_WAIT_DEFAULT,
ADC_LL_FSM_STANDBY_WAIT_DEFAULT);
REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_RSTB_WAIT, 8);
REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_XPD_WAIT, 5);
REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_STANDBY_WAIT, 100);
adc_digi_pattern_config_t pattern_config = {};
pattern_config.unit = ADC_UNIT_2;
pattern_config.atten = ADC_ATTEN_DB_12;
pattern_config.channel = ADC_CHANNEL_1; //Use reserved channel 1 to get internal voltage
adc_ll_digi_set_pattern_table(ADC_UNIT_2, 0, pattern_config);
adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, 1);
adc_ll_digi_set_trigger_interval(100);
adc_ll_digi_convert_limit_enable(false);
adc_ll_digi_dma_enable();
adc_ll_digi_trigger_enable();
SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M);
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M);
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_LEN, 0);
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1, 0x9cffff);// Set adc2 internal channel & atten
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2, 0xffffff);
// Set ADC sampling frequency
REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_TARGET, 100);
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_REG_CLKM_DIV_NUM, 15);
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT);
SET_PERI_REG_MASK(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M);
SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN);
}
void bootloader_random_disable(void)
{
_adc_ll_enable_bus_clock(false);
adc_ll_digi_trigger_disable();
adc_ll_digi_reset_pattern_table();
adc_ll_regi2c_adc_deinit();
#ifndef BOOTLOADER_BUILD
regi2c_saradc_disable();
#endif
// disable analog i2c master clock
ANALOG_CLOCK_DISABLE();
/* Restore internal I2C bus state */
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
/* Restore SARADC to default mode */
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN);
CLEAR_PERI_REG_MASK(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M);
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1, 0xffffff);
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2, 0xffffff);
CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M);
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE, 0);
REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0);
}

View File

@@ -8,16 +8,11 @@
#include "hal/regi2c_ctrl_ll.h"
#include "hal/adc_ll.h"
#include "hal/adc_types.h"
#include "hal/config.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/sar_periph_ctrl.h"
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
#include "hal/trng_ll.h"
#endif
#define I2C_SAR_ADC_INIT_CODE_VAL 2166
#define ADC_RNG_CLKM_DIV_NUM 0
#define ADC_RNG_CLKM_DIV_B 0
@@ -65,9 +60,6 @@ void bootloader_random_enable(void)
adc_ll_digi_set_clk_div(15);
adc_ll_digi_set_trigger_interval(100);
adc_ll_digi_trigger_enable();
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
trng_ll_enable();
#endif
}
void bootloader_random_disable(void)
@@ -88,8 +80,4 @@ void bootloader_random_disable(void)
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL);
adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_ULP);
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
trng_ll_disable();
#endif
}

View File

@@ -9,6 +9,7 @@
#include "soc/sens_reg.h"
#include "soc/dport_reg.h"
#include "soc/syscon_reg.h"
#include "soc/i2s_periph.h"
#include "esp_log.h"
#include "soc/io_mux_reg.h"
#include "soc/apb_saradc_reg.h"

View File

@@ -11,13 +11,10 @@
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "esp_crypto_periph_clk.h"
#include "esp_key_mgr.h"
#include "hal/key_mgr_hal.h"
#include "hal/key_mgr_ll.h"
#include "hal/mspi_ll.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "hal/key_mgr_ll.h"
ESP_LOG_ATTR_TAG(TAG, "flash_encrypt");
@@ -72,12 +69,18 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
return ESP_OK;
}
esp_err_t esp_flash_encryption_use_efuse_key(void)
esp_err_t esp_flash_encryption_enable_key_mgr(void)
{
esp_crypto_key_mgr_enable_periph_clk(true);
_key_mgr_ll_enable_bus_clock(true);
_key_mgr_ll_enable_peripheral_clock(true);
_key_mgr_ll_reset_register();
while (key_mgr_ll_get_state() != ESP_KEY_MGR_STATE_IDLE) {
};
// Force Key Manager to use eFuse key for XTS-AES operation
key_mgr_hal_set_key_usage(ESP_KEY_MGR_FLASH_XTS_AES_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
key_mgr_ll_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
_mspi_timing_ll_reset_mspi();
return ESP_OK;
}

View File

@@ -108,6 +108,7 @@ static inline void bootloader_config_dcache(void)
static inline void bootloader_config_icache1(void)
{
// TODO: [ESP32H4] IDF-12289
#if CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
REG_CLR_BIT(LP_AON_SRAM_USAGE_CONF_REG, LP_AON_ICACHE1_USAGE);
#else

View File

@@ -11,9 +11,6 @@
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_crypto_periph_clk.h"
#include "esp_key_mgr.h"
#include "hal/key_mgr_hal.h"
#include "hal/key_mgr_ll.h"
#include "hal/mspi_ll.h"
@@ -54,12 +51,18 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
return ESP_OK;
}
esp_err_t esp_flash_encryption_use_efuse_key(void)
esp_err_t esp_flash_encryption_enable_key_mgr(void)
{
esp_crypto_key_mgr_enable_periph_clk(true);
_key_mgr_ll_enable_bus_clock(true);
_key_mgr_ll_enable_peripheral_clock(true);
_key_mgr_ll_reset_register();
while (key_mgr_ll_get_state() != ESP_KEY_MGR_STATE_IDLE) {
};
// Force Key Manager to use eFuse key for XTS-AES operation
key_mgr_hal_set_key_usage(ESP_KEY_MGR_FLASH_XTS_AES_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
key_mgr_ll_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
_mspi_timing_ll_reset_mspi();
return ESP_OK;
}

View File

@@ -24,7 +24,6 @@
#include "hal/cache_ll.h"
#include "spi_flash_mmap.h"
#include "hal/efuse_hal.h"
#include "sdkconfig.h"
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
@@ -142,22 +141,6 @@ static bool is_bootloader(uint32_t offset)
);
}
#if BOOTLOADER_BUILD && (SECURE_BOOT_CHECK_SIGNATURE == 1)
#if CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
static bool skip_verify(esp_image_load_mode_t mode, bool verify_sha)
{
// Multi level check to ensure that its a legit exit from deep sleep case
return (esp_rom_get_reset_reason(0) == RESET_REASON_CORE_DEEP_SLEEP &&
mode == ESP_IMAGE_LOAD_NO_VALIDATE &&
!verify_sha) ? true : false;
}
#else
#define skip_verify(mode, verify_sha) (false)
#endif
#endif // BOOTLOADER_BUILD && (SECURE_BOOT_CHECK_SIGNATURE == 1)
static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
@@ -253,9 +236,9 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
"only verify signature in bootloader" into the macro so it's tested multiple times.
*/
#if CONFIG_SECURE_BOOT_V2_ENABLED
ESP_FAULT_ASSERT(!esp_secure_boot_enabled() || skip_verify(mode, verify_sha) || memcmp(image_digest, verified_digest, ESP_SECURE_BOOT_DIGEST_LEN) == 0);
ESP_FAULT_ASSERT(!esp_secure_boot_enabled() || memcmp(image_digest, verified_digest, ESP_SECURE_BOOT_DIGEST_LEN) == 0);
#else // Secure Boot V1 on ESP32, only verify signatures for apps not bootloaders
ESP_FAULT_ASSERT(is_bootloader(data->start_addr) || skip_verify(mode, verify_sha) || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
ESP_FAULT_ASSERT(is_bootloader(data->start_addr) || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
#endif
#endif // SECURE_BOOT_CHECK_SIGNATURE

View File

@@ -16,10 +16,6 @@
#include "hal/spi_flash_encrypt_hal.h"
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include "esp_key_mgr.h"
#endif /* SOC_KEY_MANAGER_SUPPORTED */
#if CONFIG_IDF_TARGET_ESP32
#define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT
#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT
@@ -448,13 +444,12 @@ bool esp_flash_encryption_cfg_verify_release_mode(void)
}
#endif
#if CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_EFUSES
esp_efuse_purpose_t purposes[] = {
#if SOC_EFUSE_XTS_AES_KEY_256
#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_EFUSE_XTS_AES_KEY_128
#if SOC_FLASH_ENCRYPTION_XTS_AES_128
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
#endif
};
@@ -487,23 +482,6 @@ bool esp_flash_encryption_cfg_verify_release_mode(void)
}
}
result &= secure;
#elif CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR
#if CONFIG_SECURE_FLASH_ENCRYPTION_AES128
secure = esp_efuse_read_field_bit(ESP_EFUSE_KM_XTS_KEY_LENGTH_256);
result &= secure;
if (!secure) {
ESP_LOGW(TAG, "Not enabled Key Manager XTS-AES-128 key (set KM_XTS_KEY_LENGTH_256->1)");
}
#endif
const uint32_t force_key_mgr_key = esp_efuse_read_field_bit(ESP_EFUSE_FORCE_USE_KEY_MANAGER_KEY);
secure = (force_key_mgr_key & (1 << ESP_KEY_MGR_FORCE_USE_KM_XTS_AES_KEY));
result &= secure;
if (!secure) {
ESP_LOGW(TAG, "Not forcing Key Manager to use XTS-AES key (set FORCE_USE_KEY_MANAGER_KEY->1)");
}
#endif
#if SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) {

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -16,14 +16,6 @@
#include "esp_log.h"
#include "hal/wdt_hal.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include "esp_key_mgr.h"
#include "hal/key_mgr_ll.h"
#include "rom/key_mgr.h"
#include "esp_rom_crc.h"
#endif
#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
#include "soc/sensitive_reg.h"
@@ -132,158 +124,8 @@ esp_err_t esp_flash_encrypt_check_and_update(void)
return ESP_OK;
}
#if CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR
static esp_err_t key_manager_read_key_recovery_info(esp_key_mgr_key_recovery_info_t *key_recovery_info)
{
esp_err_t err = ESP_FAIL;
uint32_t crc = 0;
for (int i = 0; i < 2; i++) {
err = bootloader_flash_read(KEY_HUK_SECTOR_OFFSET(i), (uint32_t *)key_recovery_info, sizeof(esp_key_mgr_key_recovery_info_t), false);
if (err != ESP_OK) {
ESP_LOGD(TAG, "Failed to read key recovery info from Key Manager sector %d: %x", i, err);
continue;
}
// check Key Recovery Info magic
if (key_recovery_info->magic != KEY_HUK_SECTOR_MAGIC) {
ESP_LOGD(TAG, "Key Manager sector %d Magic %08x failed", i, key_recovery_info->magic);
continue;
}
if (key_recovery_info->key_type != ESP_KEY_MGR_FLASH_XTS_AES_KEY) {
ESP_LOGD(TAG, "Key Manager sector %d has incorrect key type %d", i, key_recovery_info->key_type);
continue;
}
#if CONFIG_SECURE_FLASH_ENCRYPTION_AES256
if (key_recovery_info->key_len != ESP_KEY_MGR_XTS_AES_LEN_256) {
ESP_LOGD(TAG, "Key Manager sector %d has incorrect key length %d", i, key_recovery_info->key_len);
continue;
}
#else
if (key_recovery_info->key_len != ESP_KEY_MGR_XTS_AES_LEN_128) {
ESP_LOGD(TAG, "Key Manager sector %d has incorrect key length %d", i, key_recovery_info->key_len);
continue;
}
#endif
// check HUK Info CRC
crc = esp_rom_crc32_le(0, key_recovery_info->huk_info.info, HUK_INFO_LEN);
if (crc != key_recovery_info->huk_info.crc) {
ESP_LOGD(TAG, "Key Manager sector %d HUK Info CRC error", i);
continue;
}
// check Key Info 0 CRC
crc = esp_rom_crc32_le(0, key_recovery_info->key_info[0].info, KEY_INFO_LEN);
if (crc != key_recovery_info->key_info[0].crc) {
ESP_LOGD(TAG, "Key Manager sector %d Key Info 0 CRC error", i);
continue;
}
#if CONFIG_SECURE_FLASH_ENCRYPTION_AES256
// check Key Info 1 CRC
crc = esp_rom_crc32_le(0, key_recovery_info->key_info[1].info, KEY_INFO_LEN);
if (crc != key_recovery_info->key_info[1].crc) {
ESP_LOGD(TAG, "Key Manager sector %d Key Info 1 CRC error", i);
continue;
}
#endif
ESP_LOGI(TAG, "Valid Key Manager key recovery info found in sector %d", i);
return ESP_OK;
}
ESP_LOGD(TAG, "No valid key recovery info found");
return ESP_ERR_NOT_FOUND;
}
static esp_err_t key_manager_generate_key(esp_key_mgr_key_recovery_info_t *key_recovery_info)
{
ESP_LOGI(TAG, "Deploying new flash encryption key using Key Manager");
esp_key_mgr_random_key_config_t key_config;
memset(&key_config, 0, sizeof(esp_key_mgr_random_key_config_t));
key_config.key_type = ESP_KEY_MGR_FLASH_XTS_AES_KEY;
#if CONFIG_SECURE_FLASH_ENCRYPTION_AES256
key_config.key_len = ESP_KEY_MGR_XTS_AES_LEN_256;
#else
key_config.key_len = ESP_KEY_MGR_XTS_AES_LEN_128;
#endif
// Generate a new key and load it into Key Manager
esp_err_t err = esp_key_mgr_deploy_key_in_random_mode(&key_config, key_recovery_info);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate key for Key Manager: %x", err);
return err;
}
ESP_LOGV(TAG, "Successfully deployed new flash encryption key using Key Manager");
// Write the key recovery info of the newly generated key into the flash
for (int i = 0; i < 2; i++) {
err = bootloader_flash_erase_sector(i);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to erase sector %d: %x", i, err);
return err;
}
}
// Write the key recovery info of the newly generated key into the flash
err = bootloader_flash_write(KEY_HUK_SECTOR_OFFSET(0), (uint32_t *)key_recovery_info, sizeof(esp_key_mgr_key_recovery_info_t), false);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write key recovery info to flash: %x", err);
return err;
}
ESP_LOGV(TAG, "Successfully wrote the newly generated Flash Encryption key recovery info into the flash");
return ESP_OK;
}
static esp_err_t key_manager_check_and_generate_key(void)
{
/*
1. Check if we have a valid key info in the first two sectors of the flash
2. If we have a valid key info, check if it is valid
1. If the key is valid, use it
2. If the key is not valid, generate a new key and load it into key manager
3. If not, generate a new key and load it into key manager
*/
esp_key_mgr_key_recovery_info_t key_recovery_info;
memset(&key_recovery_info, 0, sizeof(esp_key_mgr_key_recovery_info_t));
esp_err_t err = key_manager_read_key_recovery_info(&key_recovery_info);
if (err == ESP_ERR_NOT_FOUND) {
// No valid key recovery info found, generate a new key
err = key_manager_generate_key(&key_recovery_info);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate key for Key Manager: %x", err);
return err;
}
} else {
// Valid key recovery info found, use it
ESP_LOGI(TAG, "Using pre-deployed Key Manager key for flash encryption");
}
// Recover key using the key recovery info
err = esp_key_mgr_activate_key(&key_recovery_info);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to activate Key Manager key: %x", err);
return err;
}
return ESP_OK;
}
#endif
static esp_err_t check_and_generate_encryption_keys(void)
{
#if CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_EFUSES
size_t key_size = 32;
#ifdef CONFIG_IDF_TARGET_ESP32
enum { BLOCKS_NEEDED = 1 };
@@ -372,60 +214,12 @@ static esp_err_t check_and_generate_encryption_keys(void)
ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse");
}
#if SOC_KEY_MANAGER_FE_KEY_DEPLOY
// In the case of Key Manager supported targets, the default XTS-AES key source is set to Key Manager.
esp_flash_encryption_use_efuse_key();
#endif
#elif CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR
esp_err_t err = key_manager_check_and_generate_key();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to check and generate key using Key Manager: %x", err);
return err;
}
#if CONFIG_SECURE_FLASH_ENCRYPTION_AES128
err = esp_efuse_write_field_bit(ESP_EFUSE_KM_XTS_KEY_LENGTH_256);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to set the efuse bit KM_XTS_KEY_LENGTH_256: %x", err);
return err;
}
#endif
const uint32_t force_key_mgr_key_for_fe = 1 << ESP_KEY_MGR_FORCE_USE_KM_XTS_AES_KEY;
err = esp_efuse_write_field_blob(ESP_EFUSE_FORCE_USE_KEY_MANAGER_KEY, &force_key_mgr_key_for_fe, ESP_EFUSE_FORCE_USE_KEY_MANAGER_KEY[0]->bit_count);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to set the efuse bit %d (XTS-AES key) of FORCE_USE_KEY_MANAGER_KEY: %x", ESP_KEY_MGR_FORCE_USE_KM_XTS_AES_KEY, err);
return err;
}
ESP_LOGV(TAG, "Successfully activated the flash encryption key using Key Manager");
#endif
return ESP_OK;
}
esp_err_t esp_flash_encrypt_init(void)
{
if (esp_flash_encryption_enabled()) {
return ESP_OK;
}
#if CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR
if (!(key_mgr_ll_is_supported() && key_mgr_ll_flash_encryption_supported())) {
ESP_LOGE(TAG, "Flash Encryption using Key Manager is not supported, please use efuses instead");
return ESP_ERR_NOT_SUPPORTED;
}
#endif
if (esp_flash_encrypt_initialized_once()) {
#if CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE_KEY_MGR
// Allow generating a new key if the key recovery info is not present in the flash
esp_err_t err = key_manager_check_and_generate_key();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to recover key using Key Manager: %x", err);
return err;
}
#endif
if (esp_flash_encryption_enabled() || esp_flash_encrypt_initialized_once()) {
return ESP_OK;
}
@@ -466,6 +260,10 @@ esp_err_t esp_flash_encrypt_contents(void)
REG_WRITE(SENSITIVE_XTS_AES_KEY_UPDATE_REG, 1);
#endif
#if CONFIG_SOC_KEY_MANAGER_FE_KEY_DEPLOY
esp_flash_encryption_enable_key_mgr();
#endif
err = encrypt_bootloader(); // PART_SUBTYPE_BOOTLOADER_PRIMARY
if (err != ESP_OK) {
return err;

View File

@@ -562,6 +562,7 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/core/storage/settings.c"
"esp_ble_mesh/core/access.c"
"esp_ble_mesh/core/adv_common.c"
"esp_ble_mesh/core/ble_adv.c"
"esp_ble_mesh/core/beacon.c"
"esp_ble_mesh/core/cfg_cli.c"
"esp_ble_mesh/core/cfg_srv.c"
@@ -618,7 +619,6 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/common/tinycrypt/src/sha256.c"
"esp_ble_mesh/common/tinycrypt/src/utils.c")
endif()
if(CONFIG_BLE_MESH_V11_SUPPORT)
list(APPEND include_dirs ${ble_mesh_v11_include_dirs})
@@ -655,27 +655,24 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/v1.1/dfu/dfu_slot.c"
"esp_ble_mesh/v1.1/dfu/dfu_metadata.c"
"esp_ble_mesh/lib/ext.c")
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
list(APPEND srcs "esp_ble_mesh/core/transport.enh.c")
else()
list(APPEND srcs "esp_ble_mesh/core/transport.c")
endif()
else()
list(APPEND srcs "esp_ble_mesh/core/transport.c")
list(APPEND srcs
"esp_ble_mesh/core/transport.c")
endif()
if(CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
list(APPEND srcs "esp_ble_mesh/core/ext_adv.c")
else()
list(APPEND srcs "esp_ble_mesh/core/adv.c")
endif()
if(CONFIG_BLE_MESH_SUPPORT_BLE_ADV)
list(APPEND srcs "esp_ble_mesh/core/ble_adv.c")
endif()
endif()
if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
list(APPEND srcs
"porting/npl/freertos/src/npl_os_freertos.c"
@@ -983,7 +980,7 @@ set(bt_priv_requires
)
if(CONFIG_BLE_COMPRESSED_LOG_ENABLE)
set(CODE_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
set(BT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
# When log compression is enabled, selected logs are replaced
# by auto-generated macros that emit pre-encoded data.
# This eliminates the original format strings, reducing firmware size and

View File

@@ -5,14 +5,6 @@ config BLE_LOG_ENABLED
Enable BLE Log Module
if BLE_LOG_ENABLED
config BLE_LOG_TASK_STACK_SIZE
int "Stack size for BLE Log Task"
default 1024 if IDF_TARGET_ARCH_RISCV
default 2048 if IDF_TARGET_ARCH_XTENSA
default 1024
help
Stack size for BLE Log Task
config BLE_LOG_LBM_TRANS_SIZE
int "Buffer size for each peripheral transport"
default 512

View File

@@ -41,14 +41,7 @@
#define SPI_OUT_LOG_STR_BUF_SIZE (100)
#define SPI_OUT_MALLOC(size) heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#define SPI_OUT_TASK_PRIORITY (ESP_TASK_PRIO_MAX - 1)
#if CONFIG_IDF_TARGET_ARCH_RISCV
#define SPI_OUT_TASK_STACK_SIZE (1024)
#elif CONFIG_IDF_TARGET_ARCH_XTENSA
#define SPI_OUT_TASK_STACK_SIZE (2048)
#else
static_assert(false, "BLE Log SPI Out: Unsupported target architecture");
#endif /* CONFIG_IDF_TARGET_ARCH_RISCV */
#if SPI_OUT_TS_SYNC_ENABLED
#define SPI_OUT_TS_SYNC_TIMEOUT_MS (1000)
@@ -254,9 +247,9 @@ extern uint32_t r_ble_lll_timer_current_tick_get(void);
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
extern uint32_t r_os_cputime_get32(void);
#define SPI_OUT_GET_LC_TIME r_os_cputime_get32()
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
extern uint32_t lld_read_clock_us(void);
#define SPI_OUT_GET_LC_TIME lld_read_clock_us()
// #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
// extern uint32_t lld_read_clock_us(void);
// #define SPI_OUT_GET_LC_TIME lld_read_clock_us()
#else
#define SPI_OUT_GET_LC_TIME esp_timer_get_time()
#endif
@@ -1372,13 +1365,12 @@ int ble_log_spi_out_hci_write(uint8_t source, const uint8_t *addr, uint16_t len)
return -1;
}
#if SPI_OUT_LL_ENABLED
if (source == BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM) {
#if SPI_OUT_LL_ENABLED
ble_log_spi_out_ll_write(len, addr, 0, NULL, BIT(LL_LOG_FLAG_HCI_UPSTREAM));
#endif // SPI_OUT_LL_ENABLED
}
if (source == BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM)
#endif /* SPI_OUT_LL_ENABLED */
{
if (source == BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM) {
spi_out_log_cb_t *log_cb;
bool fallback = false;
if (!spi_out_get_task_mapping(LOG_MODULE_TASK_MAP(hci),

View File

@@ -1,6 +1,6 @@
set(LOG_COMPRESSED_MODULE "")
set(LOG_COMPRESSED_MODULE_CODE_PATH "")
set(BT_ROOT_PATH $ENV{IDF_PATH}/components/bt)
set(LOG_COMPRESSED_SRCS_DIR "${CMAKE_BINARY_DIR}/ble_log/.compressed_srcs")
# default config value for ble mesh module
@@ -17,62 +17,32 @@ set(BLE_HOST_TAGS_PRESERVE "")
if(CONFIG_BLE_MESH_COMPRESSED_LOG_ENABLE)
list(APPEND LOG_COMPRESSED_MODULE "BLE_MESH")
if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/mesh_log_index.h")
file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/mesh_log_index.h" "")
endif()
list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH "esp_ble_mesh")
# update config file
set(BLE_MESH_CODE_PATH "esp_ble_mesh")
set(BLE_MESH_LOG_INDEX_HEADER "mesh_log_index.h")
set(BLE_MESH_LOG_SCRIPT_PATH
"${CMAKE_CURRENT_LIST_DIR}/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py")
# update BLE_MESH_TAGS and BLE_MESH_TAGS_PRESERVE
include(${CMAKE_CURRENT_LIST_DIR}/cmake/ble_mesh_log_tags.cmake)
if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_MESH_LOG_INDEX_HEADER}")
file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_MESH_LOG_INDEX_HEADER}" "")
endif()
list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${BLE_MESH_CODE_PATH})
endif()
endif()
if(CONFIG_BLE_HOST_COMPRESSED_LOG_ENABLE AND CONFIG_BT_BLUEDROID_ENABLED)
list(APPEND LOG_COMPRESSED_MODULE "BLE_HOST")
list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH "host/bluedroid/stack")
if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/host_log_index.h")
file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/host_log_index.h" "")
endif()
# update config file
set(HOST_CODE_PATH "host/bluedroid/stack")
set(HOST_LOG_INDEX_HEADER "host_log_index.h")
set(BLE_HOST_LOG_SCRIPT_PATH
"${CMAKE_CURRENT_LIST_DIR}/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py")
include(${CMAKE_CURRENT_LIST_DIR}/cmake/ble_host_bluedroid_tags.cmake)
if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${HOST_LOG_INDEX_HEADER}")
file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${HOST_LOG_INDEX_HEADER}" "")
endif()
list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${HOST_CODE_PATH})
endif()
if(BLE_COMPRESSED_LIB_LOG_BUILD)
if(NOT (BLE_COMPRESSED_LIB_NAME AND BLE_COMPRESSED_LIB_CODE_DIR AND BLE_COMPRESSED_LIB_LOG_TAGS))
message(FATAL_ERROR "Invalid settings")
else()
message("Building compressed log for ${BLE_COMPRESSED_LIB_NAME}")
endif()
list(APPEND LOG_COMPRESSED_MODULE ${BLE_COMPRESSED_LIB_NAME})
if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_COMPRESSED_LIB_LOG_INDEX_HEADER}")
file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_COMPRESSED_LIB_LOG_INDEX_HEADER}" "")
endif()
list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${BLE_COMPRESSED_LIB_CODE_DIR})
string(REPLACE ";" "," BLE_COMPRESSED_LIB_CODE_DIR "${BLE_COMPRESSED_LIB_CODE_DIR}")
string(REPLACE ";" "," BLE_COMPRESSED_LIB_LOG_TAGS "${BLE_COMPRESSED_LIB_LOG_TAGS}")
string(REPLACE ";" "," BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE "${BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE}")
else()
set(BLE_COMPRESSED_LIB_NAME "placeholder")
endif()
if(LOG_COMPRESSED_MODULE)
# When building the library, ble_log_compression.c and its dependencies are not needed
if(NOT BLE_COMPRESSED_LIB_LOG_BUILD)
list(APPEND srcs "common/ble_log/extension/log_compression/ble_log_compression.c")
list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include")
endif()
list(APPEND srcs "common/ble_log/extension/log_compression/ble_log_compression.c")
list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include")
if(NOT CMAKE_VERSION VERSION_LESS 3.15.0)
set(Python3_FIND_STRATEGY LOCATION)
find_package(Python3 COMPONENTS Interpreter)
@@ -141,39 +111,19 @@ if(LOG_COMPRESSED_MODULE)
"host/nimble/nimble/nimble/host/store/config/src")
endif()
if(BLE_COMPRESSED_LIB_LOG_BUILD)
execute_process(COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT}
compress
--compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}"
--build_path "${CMAKE_BINARY_DIR}"
--module "${LOG_COMPRESSED_MODULE}"
--code_base_path "${CODE_BASE_PATH}"
--srcs "${compressed_srcs}"
RESULT_VARIABLE result
OUTPUT_VARIABLE out
ERROR_VARIABLE err)
if(NOT ${result} EQUAL 0)
message(WARNING "${err}")
message(WARNING "Exit this log compression due to failure of compression")
set(LOG_COMPRESS_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE)
set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE)
return()
endif()
else()
add_custom_target(ble_log_compression ALL
COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT}
compress
--compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}"
--build_path "${CMAKE_BINARY_DIR}"
--module "'${LOG_COMPRESSED_MODULE}'"
--code_base_path "${CODE_BASE_PATH}"
--srcs "'${compressed_srcs}'"
DEPENDS ${compressed_srcs_with_abs_path} ${PYTHON_SCRIPT}
COMMENT "Log compression is being performed, please wait..."
WORKING_DIRECTORY ${BT_ROOT_PATH}
USES_TERMINAL
)
endif()
add_custom_target(ble_log_compression ALL
COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT}
compress
--compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}"
--build_path "${CMAKE_BINARY_DIR}"
--module "'${LOG_COMPRESSED_MODULE}'"
--bt_path "${BT_ROOT_PATH}"
--srcs "'${compressed_srcs}'"
DEPENDS ${compressed_srcs_with_abs_path} ${PYTHON_SCRIPT}
COMMENT "Log compression is being performed, please wait..."
WORKING_DIRECTORY ${BT_ROOT_PATH}
USES_TERMINAL
)
function(add_flags_if_in_list file file_list compile_flags)
set(PROCESSED OFF PARENT_SCOPE)
@@ -240,10 +190,7 @@ if(LOG_COMPRESSED_MODULE)
set(LOG_COMPRESSION_TARGET ble_log_compression PARENT_SCOPE)
# set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE)
set(LOG_COMPRESS_SRCS "${compressed_srcs_with_abs_path};${uncompressed_srcs}" PARENT_SCOPE)
if(NOT BLE_COMPRESSED_LIB_LOG_BUILD)
list(APPEND include_dirs "common/ble_log/extension/log_compression/include")
endif()
list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include")
list(APPEND include_dirs "common/ble_log/extension/log_compression/include")
set(LOG_COMPRESS_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE)
else()
set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE)

View File

@@ -19,7 +19,6 @@ This script processes Bluetooth source files to compress logging statements.
import argparse
import enum
import importlib.util
import logging
import os
import re
@@ -34,7 +33,6 @@ from typing import Dict
from typing import List
from typing import Tuple
from typing import Union
from typing import cast
import tree_sitter_c as tsc
import yaml
@@ -74,16 +72,10 @@ CLANG_PARSER: Union[Parser, None] = None
SOURCE_ENUM_MAP = {
'BLE_HOST': 0,
'BLE_MESH': 1,
'BLE_MESH_LIB': 2,
}
# Functions that require hex formatting
HEX_FUNCTIONS = {
# func_name: (arg_cnt, buf_idx, buf_len)
# Negative buf_len indicates constant buffer size
'bt_hex': (2, 0, 1), # Used in Mesh and Audio modules
'MAC2STR': (1, 0, -6), # Used in Bluedroid Host
}
HEX_FUNCTIONS = ['bt_hex'] # Used in Mesh and Audio modules
# C keywords to exclude from function names
C_KEYWORDS = {
@@ -127,6 +119,15 @@ LINE_MACROS = {
'__LINE__',
}
BLUEDROID_LOG_MODE_LEVEL_GET = {
'BTM': 'btm_cb.trace_level',
'L2CAP': 'l2cb.l2cap_trace_level',
'GAP': 'gap_cb.trace_level',
'GATT': 'gatt_cb.trace_level',
'SMP': 'smp_cb.trace_level',
'APPL': 'appl_trace_level',
}
class ARG_SIZE_TYPE(enum.IntEnum):
U32 = 0
@@ -173,12 +174,11 @@ class LogCompressor:
"""Main class for BLE log compression."""
def __init__(self) -> None:
self.code_base_path = Path()
self.bt_component_path = Path()
self.build_dir = Path()
self.bt_compressed_srcs_path = Path()
self.config: dict[str, Any] = {}
self.module_info: dict[str, Any] = {}
self.module_mod: dict[str, Any] = {}
def init_parser(self) -> Parser:
"""Initialize tree-sitter parser for C."""
@@ -371,20 +371,15 @@ class LogCompressor:
if (
arg_node.type == 'call_expression'
and arg_node.child_by_field_name('function')
and arg_node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS.keys()
and arg_node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS
):
# Extract arguments of the hex function
hex_func_name = arg_node.child_by_field_name('function').text.decode('utf-8')
hex_args = arg_node.child_by_field_name('arguments')
hex_func_info = HEX_FUNCTIONS[hex_func_name]
if hex_args and hex_args.named_child_count == hex_func_info[0]:
buf_node = hex_args.named_children[hex_func_info[1]].text.decode('utf-8')
if hex_func_info[2] < 0:
len_node = abs(hex_func_info[2])
else:
len_node = hex_args.named_children[hex_func_info[2]].text.decode('utf-8')
if hex_args and hex_args.named_child_count >= 2:
buf_node = hex_args.named_children[0]
len_node = hex_args.named_children[1]
token_list = list(token)
token_list[6] = f'@hex_func@{buf_node}@{len_node}'
token_list[6] = f'@hex_func@{buf_node.text.decode("utf-8")}@{len_node.text.decode("utf-8")}'
tokens[tokens_tuple_map[i]] = tuple(token_list)
log_info['argu_tokens'] = tokens
@@ -424,7 +419,7 @@ class LogCompressor:
if (
node.type == 'call_expression'
and node.child_by_field_name('function')
and node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS.keys()
and node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS
):
return True
@@ -467,6 +462,53 @@ class LogCompressor:
if not log_idx:
return ''
def generate_mesh_log_prefix(source: str, tag: str, print_statm: str) -> str:
level = tag.split('_')[-1]
mod = tag.split('_')[0]
if level == 'ERR':
level = 'ERROR'
log_level = 'BLE_MESH_LOG_LEVEL_ERROR'
elif level == 'WARN':
level = 'WARN'
log_level = 'BLE_MESH_LOG_LEVEL_WARN'
elif level == 'INFO':
level = 'INFO'
log_level = 'BLE_MESH_LOG_LEVEL_INFO'
elif level == 'DBG':
level = 'DEBUG'
log_level = 'BLE_MESH_LOG_LEVEL_DEBUG'
else:
LOGGER.error(f'Invalid log level {level}')
return ''
if mod == 'NET':
used_log_levl = 'BLE_MESH_NET_BUF_LOG_LEVEL'
used_log_mod = 'BLE_MESH_NET_BUF'
else:
used_log_levl = 'BLE_MESH_LOG_LEVEL'
used_log_mod = 'BLE_MESH'
return (
f'{{do {{ if (({used_log_levl} >= {log_level}) &&'
f' BLE_MESH_LOG_LEVEL_CHECK({used_log_mod}, {level})) {print_statm};}} while (0);}}\\\n'
)
def generate_bluedroid_log_prefix(source: str, tag: str, print_statm: str) -> str:
tag_info = tag.split('_')
mod = tag_info[0]
return (
f'{{if ({BLUEDROID_LOG_MODE_LEVEL_GET[mod]} >= BT_TRACE_LEVEL_{tag_info[-1]} &&'
f' BT_LOG_LEVEL_CHECK({mod}, {tag_info[-1]})) {print_statm};}}\\\n'
)
def generate_log_lvl_prefix(source: str, tag: str, print_statm: str) -> str:
if source == 'BLE_MESH':
return ' ' + generate_mesh_log_prefix(source, tag, print_statm)
elif source == 'BLE_HOST': # only bluedroid host supported for now
return ' ' + generate_bluedroid_log_prefix(source, tag, print_statm)
else:
LOGGER.error(f'Unknown source {source}')
return ''
source_value = SOURCE_ENUM_MAP.get(source.upper())
if source_value is None:
raise ValueError(f'Invalid source: {source}')
@@ -509,22 +551,41 @@ class LogCompressor:
else:
sizes.append(f'{int(ARG_SIZE_TYPE.U32)}')
stmt = self.module_mod[source].gen_compressed_stmt(
log_idx,
source_value,
tag,
log_info['arguments'][0],
[{'name': arg, 'size_type': size_type} for arg, size_type in zip(arguments, sizes)],
[
{
'buffer': hex_str.split('@')[2],
'length': hex_str.split('@')[3],
}
for hex_str in hex_func
],
)
macro += cast(str, stmt)
if arg_count > 0:
size_str = ', '.join(sizes)
arg_str = ', '.join(arguments).replace('\n', '')
macro += generate_log_lvl_prefix(
source,
tag,
(f'BLE_LOG_COMPRESSED_HEX_PRINT({source_value}, {log_idx}, {arg_count}, {size_str}, {arg_str})'),
)
for idx, item in enumerate(hex_func):
# hex_func format: @hex_func@buf@len
parts = item.split('@')
if len(parts) >= 4:
buf = parts[2]
buf_len = parts[3]
macro += generate_log_lvl_prefix(
source,
tag,
(f'BLE_LOG_COMPRESSED_HEX_PRINT_BUF({source_value}, {log_idx}, {idx}, {buf}, {buf_len})'),
)
else:
macro += generate_log_lvl_prefix(
source, tag, f'BLE_LOG_COMPRESSED_HEX_PRINT_WITH_ZERO_ARGUMENTS({source_value}, {log_idx})'
)
for idx, item in enumerate(hex_func):
# hex_func format: @hex_func@buf@len
parts = item.split('@')
if len(parts) >= 4:
buf = parts[2]
buf_len = parts[3]
macro += generate_log_lvl_prefix(
source,
tag,
(f'BLE_LOG_COMPRESSED_HEX_PRINT_BUF({source_value}, {log_idx}, {idx}, {buf}, {buf_len})'),
)
if (
'tags_with_preserve' in self.module_info[source]
and tag in self.module_info[source]['tags_with_preserve']
@@ -532,7 +593,8 @@ class LogCompressor:
macro += f' {tag}(fmt, ##__VA_ARGS__);\\\n'
else:
# Non-hexified log
raise ValueError('Hexify convert failed')
print_fmt = print_fmt or 'NULL'
macro += f' BLE_LOG_COMPRESSED_PRINT({source_value}, {log_idx}, "{print_fmt}", ##__VA_ARGS__); \\\n'
macro += '}\n'
return macro
@@ -654,7 +716,7 @@ class LogCompressor:
total_cnt = 0
for src in srcs:
if pattern.match(src):
src_path = self.code_base_path / src
src_path = self.bt_component_path / src
dest_path = self.bt_compressed_srcs_path / src
temp_path = f'{dest_path}.tmp'
total_cnt += 1
@@ -692,7 +754,7 @@ class LogCompressor:
module: Module name
macros: List of (log_id, macro_definition)
"""
# header_path = self.code_base_path / self.module_info[module]['log_index_path']
# header_path = self.bt_component_path / self.module_info[module]['log_index_path']
header_path = self.build_dir / Path('ble_log') / Path('include') / self.module_info[module]['log_index_file']
# Create directory if needed
header_path.parent.mkdir(parents=True, exist_ok=True)
@@ -702,7 +764,8 @@ class LogCompressor:
return
elif update_state == self.db_manager.SOURCE_LOG_UPDATE_FULL:
# Header template
header_content = textwrap.dedent(f"""
header_content = (
textwrap.dedent(f"""
/*
* SPDX-FileCopyrightText: {datetime.now().year} Espressif Systems (Shanghai) CO LTD
*
@@ -715,11 +778,22 @@ class LogCompressor:
#include <stddef.h>
#include <stdlib.h>
// Compression function declarations
extern int ble_log_compressed_hex_print
(uint32_t source, uint32_t log_index, size_t args_size_cnt, ...);
extern int ble_log_compressed_hex_print_buf
(uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len);
// Compression macros
#define BLE_LOG_COMPRESSED_HEX_PRINT(source, log_index, args_cnt, ...) \\
ble_log_compressed_hex_print(source, log_index, args_cnt, ##__VA_ARGS__)
#define BLE_LOG_COMPRESSED_HEX_PRINT_BUF(source, log_index, buf_idx, buf, len) \\
ble_log_compressed_hex_print_buf(source, log_index, buf_idx, (const uint8_t *)buf, len)
#define BLE_LOG_COMPRESSED_HEX_PRINT_WITH_ZERO_ARGUMENTS(source, log_index) \\
ble_log_compressed_hex_print(source, log_index, 0)
""").strip()
header_content += self.module_mod[module].gen_header_head()
header_content += '\n\n'
+ '\n\n'
)
# Add sorted macros
for log_id, macro_def in sorted(macros, key=lambda x: x[0]):
header_content += macro_def + '\n'
@@ -778,14 +852,6 @@ class LogCompressor:
for module in module_names:
if module in modules:
self.module_info[module] = modules[module]
module_script_path = self.module_info[module]['script']
spec = self.module_mod[module] = importlib.util.spec_from_file_location(module, module_script_path)
if spec and spec.loader:
self.module_mod[module] = importlib.util.module_from_spec(spec)
spec.loader.exec_module(self.module_mod[module])
else:
LOGGER.error(f"Failed to load module '{module}' script")
raise ImportError(' Failed to load module script')
print(f'Found module {module} for compression\n', flush=True, end='', file=sys.stdout)
else:
LOGGER.warning(f"Skipping module '{module}' - config not found")
@@ -797,7 +863,7 @@ class LogCompressor:
compress_parser = subparsers.add_parser('compress')
compress_parser.add_argument('--srcs', required=True, help='Semicolon-separated source file paths')
compress_parser.add_argument('--code_base_path', required=True, help='Component base path')
compress_parser.add_argument('--bt_path', required=True, help='Bluetooth component root path')
compress_parser.add_argument('--module', required=True, help='Semicolon-separated module names')
compress_parser.add_argument('--build_path', required=True, help='Build output directory')
compress_parser.add_argument('--compressed_srcs_path', required=True, help='Directory for processed sources')
@@ -805,7 +871,7 @@ class LogCompressor:
args = parser.parse_args()
# Setup paths
self.code_base_path = Path(args.code_base_path)
self.bt_component_path = Path(args.bt_path)
self.build_dir = Path(args.build_path)
self.bt_compressed_srcs_path = Path(args.compressed_srcs_path)
@@ -881,7 +947,7 @@ class LogCompressor:
# Mark files as processed
for module, info in self.module_info.items():
for temp_path in info['files_to_process']:
src_path = self.code_base_path / os.path.relpath(temp_path[:-4], self.bt_compressed_srcs_path)
src_path = self.bt_component_path / os.path.relpath(temp_path[:-4], self.bt_compressed_srcs_path)
db_manager.mark_file_processed(module, src_path, temp_path)
for root, _, files in os.walk(self.bt_compressed_srcs_path):
for name in files:

View File

@@ -6,7 +6,6 @@ log_config:
description: "BLE Mesh"
code_path: [@BLE_MESH_CODE_PATH@]
log_index_file: @BLE_MESH_LOG_INDEX_HEADER@
script: @BLE_MESH_LOG_SCRIPT_PATH@
tags: [@BLE_MESH_TAGS@]
tags_with_preserve: [@BLE_MESH_TAGS_PRESERVE@]
@@ -14,14 +13,5 @@ log_config:
description: "BLE Host"
code_path: [@HOST_CODE_PATH@]
log_index_file: @HOST_LOG_INDEX_HEADER@
script: @BLE_HOST_LOG_SCRIPT_PATH@
tags: [@BLE_HOST_TAGS@]
tags_with_preserve: [@BLE_HOST_TAGS_PRESERVE@]
@BLE_COMPRESSED_LIB_NAME@:
description: "@BLE_COMPRESSED_LIB_DESC@"
code_path: [@BLE_COMPRESSED_LIB_CODE_DIR@]
log_index_file: @BLE_COMPRESSED_LIB_LOG_INDEX_HEADER@
script: @BLE_COMPRESSED_LIB_LOG_SCRIPT_PATH@
tags: [@BLE_COMPRESSED_LIB_LOG_TAGS@]
tags_with_preserve: [@BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE@]

View File

@@ -163,5 +163,4 @@ TYPES_MACRO_MAP = {
'SCNoPTR': __PRIPTR_PREFIX + 'o',
'SCNuPTR': __PRIPTR_PREFIX + 'u',
'SCNxPTR': __PRIPTR_PREFIX + 'x',
'MACSTR': '%s',
}

View File

@@ -1,71 +0,0 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import textwrap
def generate_mesh_log_prefix(tag: str, print_statm: str) -> str:
level = tag.split('_')[-1]
mod = tag.split('_')[0]
if level == 'ERR':
level = 'ERROR'
log_level = 'BLE_MESH_LOG_LEVEL_ERROR'
elif level == 'WARN':
level = 'WARN'
log_level = 'BLE_MESH_LOG_LEVEL_WARN'
elif level == 'INFO':
level = 'INFO'
log_level = 'BLE_MESH_LOG_LEVEL_INFO'
elif level == 'DBG':
level = 'DEBUG'
log_level = 'BLE_MESH_LOG_LEVEL_DEBUG'
else:
return ''
if mod == 'NET':
used_log_levl = 'BLE_MESH_NET_BUF_LOG_LEVEL'
used_log_mod = 'BLE_MESH_NET_BUF'
else:
used_log_levl = 'BLE_MESH_LOG_LEVEL'
used_log_mod = 'BLE_MESH'
return (
f'{{do {{ if (({used_log_levl} >= {log_level}) &&'
f' BLE_MESH_LOG_LEVEL_CHECK({used_log_mod}, {level})) {print_statm};}} while (0);}}\\\n'
)
def gen_header_head() -> str:
head = textwrap.dedent("""
// Compression function declarations
extern int ble_log_compressed_hex_print
(uint8_t source, uint32_t log_index, size_t args_size_cnt, ...);
extern int ble_log_compressed_hex_print_buf
(uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len);
""")
return head
def gen_compressed_stmt(
log_index: int, module_id: int, func_name: str, fmt: str, args: list[dict], buffer_args: list[dict]
) -> str:
if len(args) == 0:
stmt = f' ble_log_compressed_hex_print({module_id}, {log_index}, 0);'
for idx, buffer_arg in enumerate(buffer_args):
stmt += '\\\n'
stmt += (
f' ble_log_compressed_hex_print_buf('
f'{module_id}, {log_index}, {idx}, '
f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});'
)
stmt += '\\\n'
return ' ' + generate_mesh_log_prefix(func_name, stmt)
size_str = ', '.join([arg['size_type'] for arg in args])
args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '')
stmt = f' ble_log_compressed_hex_print({module_id}, {log_index}, {len(args)}, {size_str}, {args_str});'
for idx, buffer_arg in enumerate(buffer_args):
stmt += '\\\n'
stmt += (
f' ble_log_compressed_hex_print_buf('
f'{module_id}, {log_index}, {idx}, '
f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});'
)
stmt += '\\\n'
return ' ' + generate_mesh_log_prefix(func_name, stmt)

View File

@@ -1,61 +0,0 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import textwrap
BLUEDROID_LOG_MODE_LEVEL_GET = {
'BTM': 'btm_cb.trace_level',
'L2CAP': 'l2cb.l2cap_trace_level',
'GAP': 'gap_cb.trace_level',
'GATT': 'gatt_cb.trace_level',
'SMP': 'smp_cb.trace_level',
'APPL': 'appl_trace_level',
}
def generate_bluedroid_log_prefix(tag: str, print_statm: str) -> str:
tag_info = tag.split('_')
mod = tag_info[0]
return (
f'{{if ({BLUEDROID_LOG_MODE_LEVEL_GET[mod]} >= BT_TRACE_LEVEL_{tag_info[-1]} &&'
f' BT_LOG_LEVEL_CHECK({mod}, {tag_info[-1]})) {print_statm};}}\\\n'
)
def gen_header_head() -> str:
head = textwrap.dedent("""
// Compression function declarations
extern int ble_log_compressed_hex_print
(uint8_t source, uint32_t log_index, size_t args_size_cnt, ...);
extern int ble_log_compressed_hex_print_buf
(uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len);
""")
return head
def gen_compressed_stmt(
log_index: int, module_id: int, func_name: str, fmt: str, args: list[dict], buffer_args: list[dict]
) -> str:
if len(args) == 0:
stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, 0);'
for idx, buffer_arg in enumerate(buffer_args):
stmt += '\\\n'
stmt += (
f' ble_log_compressed_hex_print_buf('
f'{module_id}, {log_index}, {idx}, '
f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});'
)
stmt += '\\\n'
return ' ' + generate_bluedroid_log_prefix(func_name, stmt)
size_str = ', '.join([arg['size_type'] for arg in args])
args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '')
stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, {len(args)}, {size_str}, {args_str});'
for idx, buffer_arg in enumerate(buffer_args):
stmt += '\\\n'
stmt += (
f' ble_log_compressed_hex_print_buf('
f'{module_id}, {log_index}, {idx}, '
f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});'
)
stmt += '\\\n'
return ' ' + generate_bluedroid_log_prefix(func_name, stmt)

View File

@@ -21,7 +21,7 @@
/* MACRO */
#define BLE_LOG_TASK_PRIO (ESP_TASK_PRIO_MAX - 1)
#define BLE_LOG_TASK_STACK_SIZE CONFIG_BLE_LOG_TASK_STACK_SIZE
#define BLE_LOG_TASK_STACK_SIZE (1024)
#define BLE_LOG_TASK_HOOK_TIMEOUT_MS (1000)
/* INTERFACE */

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,7 +32,6 @@
#include "esp_bt_device.h"
#include "esp_err.h"
#include "esp_blufi.h"
#include <esp_gap_ble_api.h>
#if (BLUFI_INCLUDED == TRUE)
@@ -71,155 +70,12 @@ static esp_ble_adv_params_t blufi_adv_params = {
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
static char *esp_auth_req_to_str(esp_ble_auth_req_t auth_req)
{
char *auth_str = NULL;
switch(auth_req) {
case ESP_LE_AUTH_NO_BOND:
auth_str = "ESP_LE_AUTH_NO_BOND";
break;
case ESP_LE_AUTH_BOND:
auth_str = "ESP_LE_AUTH_BOND";
break;
case ESP_LE_AUTH_REQ_MITM:
auth_str = "ESP_LE_AUTH_REQ_MITM";
break;
case ESP_LE_AUTH_REQ_BOND_MITM:
auth_str = "ESP_LE_AUTH_REQ_BOND_MITM";
break;
case ESP_LE_AUTH_REQ_SC_ONLY:
auth_str = "ESP_LE_AUTH_REQ_SC_ONLY";
break;
case ESP_LE_AUTH_REQ_SC_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_BOND";
break;
case ESP_LE_AUTH_REQ_SC_MITM:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM";
break;
case ESP_LE_AUTH_REQ_SC_MITM_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM_BOND";
break;
default:
auth_str = "INVALID BLE AUTH REQ";
break;
}
return auth_str;
}
static char *esp_key_type_to_str(esp_ble_key_type_t key_type)
{
char *key_str = NULL;
switch(key_type) {
case ESP_LE_KEY_NONE:
key_str = "ESP_LE_KEY_NONE";
break;
case ESP_LE_KEY_PENC:
key_str = "ESP_LE_KEY_PENC";
break;
case ESP_LE_KEY_PID:
key_str = "ESP_LE_KEY_PID";
break;
case ESP_LE_KEY_PCSRK:
key_str = "ESP_LE_KEY_PCSRK";
break;
case ESP_LE_KEY_PLK:
key_str = "ESP_LE_KEY_PLK";
break;
case ESP_LE_KEY_LLK:
key_str = "ESP_LE_KEY_LLK";
break;
case ESP_LE_KEY_LENC:
key_str = "ESP_LE_KEY_LENC";
break;
case ESP_LE_KEY_LID:
key_str = "ESP_LE_KEY_LID";
break;
case ESP_LE_KEY_LCSRK:
key_str = "ESP_LE_KEY_LCSRK";
break;
default:
key_str = "INVALID BLE KEY TYPE";
break;
}
return key_str;
}
#endif
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
BLUFI_TRACE_DEBUG("GAP_EVT, event %d", event);
switch (event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&blufi_adv_params);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//advertising start complete event to indicate advertising start successfully or failed
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("Advertising start failed, status %x", param->adv_start_cmpl.status);
break;
}
BLUFI_TRACE_API("Advertising start successfully");
break;
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
case ESP_GAP_BLE_PASSKEY_REQ_EVT: /* passkey request event */
BLUFI_TRACE_API("Passkey request");
break;
case ESP_GAP_BLE_OOB_REQ_EVT: {
BLUFI_TRACE_API("OOB request");
uint8_t tk[16] = {1}; //If you paired with OOB, both devices need to use the same tk
esp_ble_oob_req_reply(param->ble_security.ble_req.bd_addr, tk, sizeof(tk));
break;
}
case ESP_GAP_BLE_LOCAL_IR_EVT: /* BLE local IR event */
BLUFI_TRACE_API("Local identity root");
break;
case ESP_GAP_BLE_LOCAL_ER_EVT: /* BLE local ER event */
BLUFI_TRACE_API("Local encryption root");
break;
case ESP_GAP_BLE_NC_REQ_EVT:
/* The app will receive this evt when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
show the passkey number to the user to confirm it with the number displayed by peer device. */
esp_ble_confirm_reply(param->ble_security.ble_req.bd_addr, true);
BLUFI_TRACE_WARNING("Numeric Comparison request, passkey %" PRIu32, param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_SEC_REQ_EVT:
/* send the positive(true) security response to the peer device to accept the security request.
If not accept the security request, should send the security response with negative(false) accept value*/
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer device.
BLUFI_TRACE_WARNING("Passkey notify, passkey %06" PRIu32, param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
BLUFI_TRACE_API("Key exchanged, key_type %s", esp_key_type_to_str(param->ble_security.ble_key.key_type));
break;
case ESP_GAP_BLE_AUTH_CMPL_EVT: {
esp_bd_addr_t bd_addr;
memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
BLUFI_TRACE_API("Authentication complete, addr_type %u, addr "ESP_BD_ADDR_STR"",
param->ble_security.auth_cmpl.addr_type, ESP_BD_ADDR_HEX(bd_addr));
if(!param->ble_security.auth_cmpl.success) {
BLUFI_TRACE_WARNING("Pairing failed, reason 0x%x",param->ble_security.auth_cmpl.fail_reason);
} else {
BLUFI_TRACE_WARNING("Pairing successfully, auth_mode %s",esp_auth_req_to_str(param->ble_security.auth_cmpl.auth_mode));
}
break;
}
case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
BLUFI_TRACE_DEBUG("Bond device remove, status %d, device "ESP_BD_ADDR_STR"",
param->remove_bond_dev_cmpl.status, ESP_BD_ADDR_HEX(param->remove_bond_dev_cmpl.bd_addr));
break;
}
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){
BLUFI_TRACE_WARNING("Local privacy config failed, status %x", param->local_privacy_cmpl.status);
}
break;
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
default:
break;
}
@@ -395,16 +251,10 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
break;
case BTA_GATTS_CREATE_EVT:
blufi_env.handle_srvc = p_data->create.service_id;
#if CONFIG_BT_BLUFI_BLE_SMP_ENABLE
BLUFI_TRACE_WARNING("BLE SMP support in BLUFI is ENABLED!");
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
//add the first blufi characteristic --> write characteristic
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
#if CONFIG_BT_BLUFI_BLE_SMP_ENABLE
GATT_PERM_WRITE_ENC_MITM,
#else
GATT_PERM_WRITE,
#endif
(GATT_PERM_WRITE),
(GATT_CHAR_PROP_BIT_WRITE),
NULL, NULL);
break;
@@ -548,16 +398,6 @@ void esp_blufi_adv_stop(void)
esp_ble_gap_stop_advertising();
}
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda)
{
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
return esp_ble_set_encryption(remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
#else
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
}
void esp_blufi_send_encap(void *arg)
{
struct blufi_hdr *hdr = (struct blufi_hdr *)arg;

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -90,22 +90,6 @@ void esp_blufi_adv_start_with_name(const char *name);
void esp_blufi_send_encap(void *arg);
/*
* @brief Initiate BLE security request with the connected peer device.
*
* This function triggers the BLE Security Manager Protocol (SMP) procedure
* to establish a secure, encrypted connection with the specified remote device.
* It should be called after a BLE connection is established.
*
* @param[in] remote_bda Bluetooth device address of the connected peer.
*
* @return
* - ESP_OK: Security request initiated successfully
* - ESP_FAIL: Security request failed
* - ESP_ERR_INVALID_STATE: BluFi BLE SMP is not enabled
*/
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda);
#ifdef CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Handle gap event for BluFi.

View File

@@ -61,16 +61,6 @@
#define HEAP_MEMORY_DEBUG FALSE
#endif
#if UC_BT_BLUEDROID_THREAD_DEBUG
#define OSI_THREAD_DEBUG TRUE
#else
#define OSI_THREAD_DEBUG FALSE
#endif
#define OSI_THREAD_BLOCK_TIME UC_BT_BLUEDROID_THREAD_BLOCK_TIME
#define OSI_THREAD_BLOCK_MSG UC_BT_BLUEDROID_THREAD_BLOCK_MSG
#ifndef BT_BLE_DYNAMIC_ENV_MEMORY
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
#endif
@@ -250,7 +240,6 @@ typedef uint64_t UINT64;
typedef bool BOOLEAN;
/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
#define MAX_UUID_SIZE 16
#define MAX_UUID_NUM 32
typedef struct {
#define LEN_UUID_16 2

View File

@@ -107,24 +107,6 @@
#define UC_BT_BLUEDROID_MEM_DEBUG FALSE
#endif
#ifdef CONFIG_BT_BLUEDROID_THREAD_DEBUG
#define UC_BT_BLUEDROID_THREAD_DEBUG TRUE
#else
#define UC_BT_BLUEDROID_THREAD_DEBUG FALSE
#endif
#ifdef CONFIG_BT_BLUEDROID_THREAD_BLOCK_TIME
#define UC_BT_BLUEDROID_THREAD_BLOCK_TIME CONFIG_BT_BLUEDROID_THREAD_BLOCK_TIME
#else
#define UC_BT_BLUEDROID_THREAD_BLOCK_TIME 1000
#endif
#ifdef CONFIG_BT_BLUEDROID_THREAD_BLOCK_MSG
#define UC_BT_BLUEDROID_THREAD_BLOCK_MSG CONFIG_BT_BLUEDROID_THREAD_BLOCK_MSG
#else
#define UC_BT_BLUEDROID_THREAD_BLOCK_MSG 50
#endif
#ifdef CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
#else

View File

@@ -216,9 +216,7 @@ void *osi_malloc_func(size_t size)
void *p = osi_malloc_base(size);
if (size != 0 && p == NULL) {
OSI_TRACE_ERROR("malloc failed (caller=%p size=%u)", __builtin_return_address(0), size);
OSI_TRACE_ERROR("heap info: free=%d, largest_block=%d",
heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT));
OSI_TRACE_ERROR("malloc failed (caller=%p size=%u)\n", __builtin_return_address(0), size);
#if HEAP_ALLOCATION_FAILS_ABORT
assert(0);
#endif
@@ -232,9 +230,7 @@ void *osi_calloc_func(size_t size)
void *p = osi_calloc_base(size);
if (size != 0 && p == NULL) {
OSI_TRACE_ERROR("calloc failed (caller=%p size=%u)", __builtin_return_address(0), size);
OSI_TRACE_ERROR("heap info: free=%d, largest_block=%d",
heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT));
OSI_TRACE_ERROR("calloc failed (caller=%p size=%u)\n", __builtin_return_address(0), size);
#if HEAP_ALLOCATION_FAILS_ABORT
assert(0);
#endif
@@ -245,5 +241,8 @@ void *osi_calloc_func(size_t size)
void osi_free_func(void *ptr)
{
osi_free(ptr);
#if HEAP_MEMORY_DEBUG
osi_mem_dbg_clean(ptr, __func__, __LINE__);
#endif
free(ptr);
}

View File

@@ -21,7 +21,6 @@
#include <stddef.h>
#include <stdlib.h>
#include "bt_common.h"
#include "esp_heap_caps.h"
char *osi_strdup(const char *str);

Some files were not shown because too many files have changed in this diff Show More