diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000000..3a733a042bc7 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,75 @@ +name: docker + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + +on: + push: + branches: + - 'master' + - 'release/*' + tags: + - 'v*.*' + +env: + # Platforms to build the image for + BUILD_PLATFORMS: linux/amd64,linux/arm64 + DOCKERHUB_REPO: ${{ github.repository_owner }}/idf + +jobs: + docker: + # Disable the job in forks + if: ${{ github.repository_owner == 'espressif' }} + + runs-on: ubuntu-latest + steps: + # Depending on the branch/tag, set CLONE_BRANCH_OR_TAG variable (used in the Dockerfile + # as a build arg) and TAG_NAME (used when tagging the image). + # + # The following 3 steps cover the alternatives (tag, release branch, master branch): + - name: Set variables (tags) + if: ${{ github.ref_type == 'tag' }} + run: | + echo "CLONE_BRANCH_OR_TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV + echo "TAG_NAME=$GITHUB_REF_NAME" >> $GITHUB_ENV + - name: Set variables (release branches) + if: ${{ github.ref_type == 'branch' && startsWith(github.ref_name, 'release/') }} + run: | + echo "CLONE_BRANCH_OR_TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV + echo "TAG_NAME=release-${GITHUB_REF_NAME##release/}" >> $GITHUB_ENV + - name: Set variables (main branch) + if: ${{ github.ref_type == 'branch' && github.ref_name == 'master' }} + run: | + echo "CLONE_BRANCH_OR_TAG=master" >> $GITHUB_ENV + echo "TAG_NAME=latest" >> $GITHUB_ENV + + # Display the variables set above, just in case. + - name: Check variables + run: | + echo "CLONE_BRANCH_OR_TAG: $CLONE_BRANCH_OR_TAG" + echo "CHECKOUT_REF: $CHECKOUT_REF" + echo "TAG_NAME: $TAG_NAME" + + # The following steps are the standard boilerplate from + # https://github.com/marketplace/actions/build-and-push-docker-images + - name: Checkout + uses: actions/checkout@v3 + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up QEMU for multiarch builds + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: tools/docker + push: true + tags: ${{ env.DOCKERHUB_REPO }}:${{ env.TAG_NAME }} + platforms: ${{ env.BUILD_PLATFORMS }} + build-args: | + IDF_CLONE_URL=${{ github.server_url }}/${{ github.repository }}.git + IDF_CLONE_BRANCH_OR_TAG=${{ env.CLONE_BRANCH_OR_TAG }} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b229577bd7ee..13fc4a248a99 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,7 @@ variables: # target test repo parameters TEST_ENV_CONFIG_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/qa/ci-test-runner-configs.git" CI_AUTO_TEST_SCRIPT_REPO_URL: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/qa/auto_test_script.git" - CI_AUTO_TEST_SCRIPT_REPO_BRANCH: "ci/v3.1" + CI_AUTO_TEST_SCRIPT_REPO_BRANCH: "ci/v4.1" # Versioned esp-idf-doc env image to use for all document building jobs ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env:v10" @@ -70,7 +70,7 @@ variables: export IDF_MIRROR_PREFIX_MAP= fi if [[ "$SETUP_TOOLS" == "1" || "$CI_JOB_STAGE" != "target_test" ]]; then - tools/idf_tools.py --non-interactive install && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1 + tools/idf_tools.py --non-interactive install ${SETUP_TOOLS_LIST:-} && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1 fi before_script: diff --git a/components/app_trace/CMakeLists.txt b/components/app_trace/CMakeLists.txt index aafb87e25941..4c655d531cc8 100644 --- a/components/app_trace/CMakeLists.txt +++ b/components/app_trace/CMakeLists.txt @@ -6,7 +6,23 @@ set(srcs set(include_dirs "include") -if(CONFIG_SYSVIEW_ENABLE) +set(priv_include_dirs "private_include" "port/include") + +if(CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE) + list(APPEND srcs + "app_trace_membufs_proto.c") + + if(CONFIG_IDF_TARGET_ARCH_XTENSA) + list(APPEND srcs + "port/xtensa/port.c") + endif() + if(CONFIG_IDF_TARGET_ARCH_RISCV) + list(APPEND srcs + "port/riscv/port.c") + endif() +endif() + +if(CONFIG_APPTRACE_SV_ENABLE) list(APPEND include_dirs sys_view/Config sys_view/SEGGER @@ -16,7 +32,7 @@ if(CONFIG_SYSVIEW_ENABLE) "sys_view/SEGGER/SEGGER_SYSVIEW.c" "sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c" "sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c" - "sys_view/esp32/SEGGER_RTT_esp32.c" + "sys_view/esp/SEGGER_RTT_esp.c" "sys_view/ext/heap_trace_module.c" "sys_view/ext/logging.c") endif() @@ -30,7 +46,8 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" - PRIV_REQUIRES soc esp_ipc + PRIV_INCLUDE_DIRS "${priv_include_dirs}" + PRIV_REQUIRES soc LDFRAGMENTS linker.lf) diff --git a/components/app_trace/Kconfig b/components/app_trace/Kconfig index e0a39f092b4d..60f60d9aa749 100644 --- a/components/app_trace/Kconfig +++ b/components/app_trace/Kconfig @@ -4,29 +4,44 @@ menu "Application Level Tracing" prompt "Data Destination" default APPTRACE_DEST_NONE help - Select destination for application trace: trace memory or none (to disable). + Select destination for application trace: JTAG or none (to disable). - config APPTRACE_DEST_TRAX - bool "Trace memory" + config APPTRACE_DEST_JTAG + bool "JTAG" + select APPTRACE_DEST_TRAX if IDF_TARGET_ARCH_XTENSA + select APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE select APPTRACE_ENABLE + config APPTRACE_DEST_NONE bool "None" endchoice - config APPTRACE_ENABLE + config APPTRACE_DEST_TRAX bool - depends on !ESP32_TRAX && !ESP32S2_TRAX + depends on IDF_TARGET_ARCH_XTENSA && !ESP32_TRAX && !ESP32S2_TRAX select ESP32_MEMMAP_TRACEMEM select ESP32S2_MEMMAP_TRACEMEM select ESP32_MEMMAP_TRACEMEM_TWOBANKS select ESP32S2_MEMMAP_TRACEMEM_TWOBANKS default n + help + Enables/disable TRAX tracing HW. + + config APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE + bool + default n + help + Enables/disable swapping memory buffers tracing protocol. + + config APPTRACE_ENABLE + bool + default n help Enables/disable application tracing module. config APPTRACE_LOCK_ENABLE bool - default !SYSVIEW_ENABLE + default !APPTRACE_SV_ENABLE help Enables/disable application tracing module internal sync lock. @@ -41,16 +56,23 @@ menu "Application Level Tracing" config APPTRACE_POSTMORTEM_FLUSH_THRESH int "Threshold for flushing last trace data to host on panic" - depends on APPTRACE_DEST_TRAX + 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. + config APPTRACE_BUF_SIZE + int "Size of the apptrace buffer" + depends on APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE && !APPTRACE_DEST_TRAX + default 16384 + help + Size of the memory buffer for trace data in bytes. + config APPTRACE_PENDING_DATA_SIZE_MAX int "Size of the pending data buffer" - depends on APPTRACE_DEST_TRAX + depends on APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE default 0 help Size of the buffer for events in bytes. It is useful for buffering events from @@ -59,151 +81,151 @@ menu "Application Level Tracing" menu "FreeRTOS SystemView Tracing" depends on APPTRACE_ENABLE - config SYSVIEW_ENABLE + config APPTRACE_SV_ENABLE bool "SystemView Tracing Enable" depends on APPTRACE_ENABLE default n help Enables supporrt for SEGGER SystemView tracing functionality. - choice SYSVIEW_TS_SOURCE + choice APPTRACE_SV_TS_SOURCE prompt "Timer to use as timestamp source" - depends on SYSVIEW_ENABLE - default SYSVIEW_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE - default SYSVIEW_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE - default SYSVIEW_TS_SOURCE_ESP_TIMER if PM_ENABLE + depends on APPTRACE_SV_ENABLE + default APPTRACE_SV_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3 + default APPTRACE_SV_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !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 SYSVIEW_TS_SOURCE_CCOUNT + config APPTRACE_SV_TS_SOURCE_CCOUNT bool "CPU cycle counter (CCOUNT)" - depends on FREERTOS_UNICORE && !PM_ENABLE + depends on FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3 - config SYSVIEW_TS_SOURCE_TIMER_00 + config APPTRACE_SV_TS_SOURCE_TIMER_00 bool "Timer 0, Group 0" - depends on !PM_ENABLE + depends on !PM_ENABLE && !IDF_TARGET_ESP32C3 - config SYSVIEW_TS_SOURCE_TIMER_01 + config APPTRACE_SV_TS_SOURCE_TIMER_01 bool "Timer 1, Group 0" - depends on !PM_ENABLE + depends on !PM_ENABLE && !IDF_TARGET_ESP32C3 - config SYSVIEW_TS_SOURCE_TIMER_10 + config APPTRACE_SV_TS_SOURCE_TIMER_10 bool "Timer 0, Group 1" - depends on !PM_ENABLE + depends on !PM_ENABLE && !IDF_TARGET_ESP32C3 - config SYSVIEW_TS_SOURCE_TIMER_11 + config APPTRACE_SV_TS_SOURCE_TIMER_11 bool "Timer 1, Group 1" - depends on !PM_ENABLE + depends on !PM_ENABLE && !IDF_TARGET_ESP32C3 - config SYSVIEW_TS_SOURCE_ESP_TIMER + config APPTRACE_SV_TS_SOURCE_ESP_TIMER bool "esp_timer high resolution timer" endchoice - config SYSVIEW_MAX_TASKS + config APPTRACE_SV_MAX_TASKS int "Maximum supported tasks" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE range 1 64 default 16 help Configures maximum supported tasks in sysview debug - config SYSVIEW_BUF_WAIT_TMO + config APPTRACE_SV_BUF_WAIT_TMO int "Trace buffer wait timeout" - depends on SYSVIEW_ENABLE + 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 SYSVIEW_EVT_OVERFLOW_ENABLE + config APPTRACE_SV_EVT_OVERFLOW_ENABLE bool "Trace Buffer Overflow Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Trace Buffer Overflow" event. - config SYSVIEW_EVT_ISR_ENTER_ENABLE + config APPTRACE_SV_EVT_ISR_ENTER_ENABLE bool "ISR Enter Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "ISR Enter" event. - config SYSVIEW_EVT_ISR_EXIT_ENABLE + config APPTRACE_SV_EVT_ISR_EXIT_ENABLE bool "ISR Exit Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "ISR Exit" event. - config SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE + config APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE bool "ISR Exit to Scheduler Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "ISR to Scheduler" event. - config SYSVIEW_EVT_TASK_START_EXEC_ENABLE + config APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE bool "Task Start Execution Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Task Start Execution" event. - config SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE + config APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE bool "Task Stop Execution Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Task Stop Execution" event. - config SYSVIEW_EVT_TASK_START_READY_ENABLE + config APPTRACE_SV_EVT_TASK_START_READY_ENABLE bool "Task Start Ready State Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Task Start Ready State" event. - config SYSVIEW_EVT_TASK_STOP_READY_ENABLE + config APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE bool "Task Stop Ready State Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Task Stop Ready State" event. - config SYSVIEW_EVT_TASK_CREATE_ENABLE + config APPTRACE_SV_EVT_TASK_CREATE_ENABLE bool "Task Create Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Task Create" event. - config SYSVIEW_EVT_TASK_TERMINATE_ENABLE + config APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE bool "Task Terminate Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Task Terminate" event. - config SYSVIEW_EVT_IDLE_ENABLE + config APPTRACE_SV_EVT_IDLE_ENABLE bool "System Idle Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "System Idle" event. - config SYSVIEW_EVT_TIMER_ENTER_ENABLE + config APPTRACE_SV_EVT_TIMER_ENTER_ENABLE bool "Timer Enter Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Timer Enter" event. - config SYSVIEW_EVT_TIMER_EXIT_ENABLE + config APPTRACE_SV_EVT_TIMER_EXIT_ENABLE bool "Timer Exit Event" - depends on SYSVIEW_ENABLE + depends on APPTRACE_SV_ENABLE default y help Enables "Timer Exit" event. @@ -212,7 +234,7 @@ menu "Application Level Tracing" config APPTRACE_GCOV_ENABLE bool "GCOV to Host Enable" - depends on APPTRACE_ENABLE && !SYSVIEW_ENABLE + depends on APPTRACE_ENABLE && !APPTRACE_SV_ENABLE select ESP_DEBUG_STUBS_ENABLE default n help diff --git a/components/app_trace/app_trace.c b/components/app_trace/app_trace.c index 152746f893c5..3bba3dc8fc01 100644 --- a/components/app_trace/app_trace.c +++ b/components/app_trace/app_trace.c @@ -1,981 +1,179 @@ -// Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Hot It Works -// ************ - -// 1. Components Overview -// ====================== - -// Xtensa has useful feature: TRAX debug module. It allows recording program execution flow at run-time without disturbing CPU. -// Exectution flow data are written to configurable Trace RAM block. Besides accessing Trace RAM itself TRAX module also allows to read/write -// trace memory via its registers by means of JTAG, APB or ERI transactions. -// ESP32 has two Xtensa cores with separate TRAX modules on them and provides two special memory regions to be used as trace memory. -// Chip allows muxing access to those trace memory blocks in such a way that while one block is accessed by CPUs another one can be accessed by host -// by means of reading/writing TRAX registers via JTAG. Blocks muxing is configurable at run-time and allows switching trace memory blocks between -// accessors in round-robin fashion so they can read/write separate memory blocks without disturbing each other. -// This module implements application tracing feature based on above mechanisms. It allows to transfer arbitrary user data to/from -// host via JTAG with minimal impact on system performance. This module is implied to be used in the following tracing scheme. - -// ------>------ ----- (host components) ----- -// | | | | -// ------------------- ----------------------- ----------------------- ---------------- ------ --------- ----------------- -// |trace data source|-->|target tracing module|<--->|TRAX_MEM0 | TRAX_MEM1|---->|TRAX_DATA_REGS|<-->|JTAG|<--->|OpenOCD|-->|trace data sink| -// ------------------- ----------------------- ----------------------- ---------------- ------ --------- ----------------- -// | | | | -// | ------<------ ---------------- | -// |<------------------------------------------->|TRAX_CTRL_REGS|<---->| -// ---------------- - -// In general tracing goes in the following way. User application requests tracing module to send some data by calling esp_apptrace_buffer_get(), -// module allocates necessary buffer in current input trace block. Then user fills received buffer with data and calls esp_apptrace_buffer_put(). -// When current input trace block is filled with app data it is exposed to host and the second block becomes input one and buffer filling restarts. -// While target application fills one TRAX block host reads another one via JTAG. -// This module also allows communication in the opposite direction: from host to target. As it was said ESP32 and host can access different TRAX blocks -// simultaneously, so while target writes trace data to one block host can write its own data (e.g. tracing commands) to another one then when -// blocks are switched host receives trace data and target receives data written by host application. Target user application can read host data -// by calling esp_apptrace_read() API. -// To control buffer switching and for other communication purposes this implementation uses some TRAX registers. It is safe since HW TRAX tracing -// can not be used along with application tracing feature so these registers are freely readable/writeable via JTAG from host and via ERI from ESP32 cores. -// Overhead of this implementation on target CPU is produced only by allocating/managing buffers and copying of data. -// On the host side special OpenOCD command must be used to read trace data. - -// 2. TRAX Registers layout -// ======================== - -// This module uses two TRAX HW registers to communicate with host SW (OpenOCD). -// - Control register uses TRAX_DELAYCNT as storage. Only lower 24 bits of TRAX_DELAYCNT are writable. Control register has the following bitfields: -// | 31..XXXXXX..24 | 23 .(host_connect). 23| 22..(block_id)..15 | 14..(block_len)..0 | -// 14..0 bits - actual length of user data in trace memory block. Target updates it every time it fills memory block and exposes it to host. -// Host writes zero to this field when it finishes reading exposed block; -// 21..15 bits - trace memory block transfer ID. Block counter. It can overflow. Updated by target, host should not modify it. Actually can be 2 bits; -// 22 bit - 'host data present' flag. If set to one there is data from host, otherwise - no host data; -// 23 bit - 'host connected' flag. If zero then host is not connected and tracing module works in post-mortem mode, otherwise in streaming mode; -// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then current CPU is changing TRAX registers and -// this register holds address of the instruction which application will execute when it finishes with those registers modifications. -// See 'Targets Connection' setion for details. - -// 3. Modes of operation -// ===================== - -// This module supports two modes of operation: -// - Post-mortem mode. This is the default mode. In this mode application tracing module does not check whether host has read all the data from block -// exposed to it and switches block in any case. The mode does not need host interaction for operation and so can be useful when only the latest -// trace data are necessary, e.g. for analyzing crashes. On panic the latest data from current input block are exposed to host and host can read them. -// It can happen that system panic occurs when there are very small amount of data which are not exposed to host yet (e.g. crash just after the -// TRAX block switch). In this case the previous 16KB of collected data will be dropped and host will see the latest, but very small piece of trace. -// It can be insufficient to diagnose the problem. To avoid such situations there is menuconfig option -// CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH -// which controls the threshold for flushing data in case of panic. -// - Streaming mode. Tracing module enters this mode when host connects to target and sets respective bits in control registers (per core). -// In this mode before switching the block tracing module waits for the host to read all the data from the previously exposed block. -// On panic tracing module also waits (timeout is configured via menuconfig via CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO) for the host to read all data. - -// 4. Communication Protocol -// ========================= - -// 4.1 Trace Memory Blocks -// ----------------------- - -// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data available. -// When current input memory block is filled it is exposed to host and 'block_len' and 'block_id' fields are updated in the control register. -// Host reads new register value and according to it's value starts reading data from exposed block. Meanwhile target starts filling another trace block. -// When host finishes reading the block it clears 'block_len' field in control register indicating to the target that it is ready to accept the next one. -// If the host has some data to transfer to the target it writes them to trace memory block before clearing 'block_len' field. Then it sets -// 'host_data_present' bit and clears 'block_len' field in control register. Upon every block switch target checks 'host_data_present' bit and if it is set -// reads them to down buffer before writing any trace data to switched TRAX block. - -// 4.2 User Data Chunks Level -// -------------------------- - -// Since trace memory block is shared between user data chunks and data copying is performed on behalf of the API user (in its normal context) in -// multithreading environment it can happen that task/ISR which copies data is preempted by another high prio task/ISR. So it is possible situation -// that task/ISR will fail to complete filling its data chunk before the whole trace block is exposed to the host. To handle such conditions tracing -// module prepends all user data chunks with header which contains allocated buffer size and actual data length within it. OpenOCD command -// which reads application traces reports error when it reads incomplete user data block. -// Data which are transffered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field -// containing length of host data following the header. - -// 4.3 Data Buffering -// ------------------ - -// It takes some time for the host to read TRAX memory block via JTAG. In streaming mode it can happen that target has filled its TRAX block, but host -// has not completed reading of the previous one yet. So in this case time critical tracing calls (which can not be delayed for too long time due to -// the lack of free memory in TRAX block) can be dropped. To avoid such scenarios tracing module implements data buffering. Buffered data will be sent -// to the host later when TRAX block switch occurs. The maximum size of the buffered data is controlled by menuconfig option -// CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX. - -// 4.4 Target Connection/Disconnection -// ----------------------------------- - -// When host is going to start tracing in streaming mode it needs to put both ESP32 cores into initial state when 'host connected' bit is set -// on both cores. To accomplish this host halts both cores and sets this bit in TRAX registers. But target code can be halted in state when it has read control -// register but has not updated its value. To handle such situations target code indicates to the host that it is updating control register by writing -// non-zero value to status register. Actually it writes address of the instruction which it will execute when it finishes with -// the registers update. When target is halted during control register update host sets breakpoint at the address from status register and resumes CPU. -// After target code finishes with register update it is halted on breakpoint, host detects it and safely sets 'host connected' bit. When both cores -// are set up they are resumed. Tracing starts without further intrusion into CPUs work. -// When host is going to stop tracing in streaming mode it needs to disconnect targets. Disconnection process is done using the same algorithm -// as for connecting, but 'host connected' bits are cleared on ESP32 cores. - -// 5. Module Access Synchronization -// ================================ - -// Access to internal module's data is synchronized with custom mutex. Mutex is a wrapper for portMUX_TYPE and uses almost the same sync mechanism as in -// vPortCPUAcquireMutex/vPortCPUReleaseMutex. The mechanism uses S32C1I Xtensa instruction to implement exclusive access to module's data from tasks and -// ISRs running on both cores. Also custom mutex allows specifying timeout for locking operation. Locking routine checks underlaying mutex in cycle until -// it gets its ownership or timeout expires. The differences of application tracing module's mutex implementation from vPortCPUAcquireMutex/vPortCPUReleaseMutex are: -// - Support for timeouts. -// - Local IRQs for CPU which owns the mutex are disabled till the call to unlocking routine. This is made to avoid possible task's prio inversion. -// When low prio task takes mutex and enables local IRQs gets preempted by high prio task which in its turn can try to acquire mutex using infinite timeout. -// So no local task switch occurs when mutex is locked. But this does not apply to tasks on another CPU. -// WARNING: Priority inversion can happen when low prio task works on one CPU and medium and high prio tasks work on another. -// WARNING: Care must be taken when selecting timeout values for trace calls from ISRs. Tracing module does not care about watchdogs when waiting -// on internal locks and for host to complete previous block reading, so if timeout value exceeds watchdog's one it can lead to the system reboot. - -// 6. Timeouts -// =========== - -// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in microseconds. -// There are two situations when task/ISR can be delayed by tracing API call. Timeout mechanism takes into account both conditions: -// - Trace data are locked by another task/ISR. When wating on trace data lock. -// - Current TRAX memory input block is full when working in streaming mode (host is connected). When waiting for host to complete previous block reading. -// When wating for any of above conditions xthal_get_ccount() is called periodically to calculate time elapsed from trace API routine entry. When elapsed -// time exceeds specified timeout value operation is canceled and ESP_ERR_TIMEOUT code is returned. +/* + * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include -#include -#include "sdkconfig.h" -#include "soc/soc.h" -#include "soc/dport_access.h" -#if CONFIG_IDF_TARGET_ESP32 -#include "soc/dport_reg.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "soc/sensitive_reg.h" -#endif -#if __XTENSA__ -#include "eri.h" -#include "trax.h" -#endif -#include "soc/timer_periph.h" -#include "freertos/FreeRTOS.h" +#include "esp_log.h" #include "esp_app_trace.h" -#include "esp_rom_sys.h" +#include "esp_app_trace_port.h" -#if CONFIG_APPTRACE_ENABLE #define ESP_APPTRACE_MAX_VPRINTF_ARGS 256 #define ESP_APPTRACE_HOST_BUF_SIZE 256 #define ESP_APPTRACE_PRINT_LOCK 0 -#include "esp_log.h" const static char *TAG = "esp_apptrace"; -#if ESP_APPTRACE_PRINT_LOCK -#define ESP_APPTRACE_LOG( format, ... ) \ - do { \ - esp_apptrace_log_lock(); \ - esp_rom_printf(format, ##__VA_ARGS__); \ - esp_apptrace_log_unlock(); \ - } while(0) -#else -#define ESP_APPTRACE_LOG( format, ... ) \ - do { \ - esp_rom_printf(format, ##__VA_ARGS__); \ - } while(0) -#endif - -#define ESP_APPTRACE_LOG_LEV( _L_, level, format, ... ) \ - do { \ - if (LOG_LOCAL_LEVEL >= level) { \ - ESP_APPTRACE_LOG(LOG_FORMAT(_L_, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); \ - } \ - } while(0) - -#define ESP_APPTRACE_LOGE( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_ERROR, format, ##__VA_ARGS__) -#define ESP_APPTRACE_LOGW( format, ... ) ESP_APPTRACE_LOG_LEV(W, ESP_LOG_WARN, format, ##__VA_ARGS__) -#define ESP_APPTRACE_LOGI( format, ... ) ESP_APPTRACE_LOG_LEV(I, ESP_LOG_INFO, format, ##__VA_ARGS__) -#define ESP_APPTRACE_LOGD( format, ... ) ESP_APPTRACE_LOG_LEV(D, ESP_LOG_DEBUG, format, ##__VA_ARGS__) -#define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__) -#define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__) - -// TODO: move these (and same definitions in trax.c to dport_reg.h) -#if CONFIG_IDF_TARGET_ESP32 -#define TRACEMEM_MUX_PROBLK0_APPBLK1 0 -#define TRACEMEM_MUX_BLK0_ONLY 1 -#define TRACEMEM_MUX_BLK1_ONLY 2 -#define TRACEMEM_MUX_PROBLK1_APPBLK0 3 -#elif CONFIG_IDF_TARGET_ESP32S2 -#define TRACEMEM_MUX_BLK0_NUM 19 -#define TRACEMEM_MUX_BLK1_NUM 20 -#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4)) -#endif - -// TRAX is disabled, so we use its registers for our own purposes -// | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 | -#define ESP_APPTRACE_TRAX_CTRL_REG ERI_TRAX_DELAYCNT -#define ESP_APPTRACE_TRAX_STAT_REG ERI_TRAX_TRIGGERPC - -#define ESP_APPTRACE_TRAX_BLOCK_LEN_MSK 0x7FFFUL -#define ESP_APPTRACE_TRAX_BLOCK_LEN(_l_) ((_l_) & ESP_APPTRACE_TRAX_BLOCK_LEN_MSK) -#define ESP_APPTRACE_TRAX_BLOCK_LEN_GET(_v_) ((_v_) & ESP_APPTRACE_TRAX_BLOCK_LEN_MSK) -#define ESP_APPTRACE_TRAX_BLOCK_ID_MSK 0x7FUL -#define ESP_APPTRACE_TRAX_BLOCK_ID(_id_) (((_id_) & ESP_APPTRACE_TRAX_BLOCK_ID_MSK) << 15) -#define ESP_APPTRACE_TRAX_BLOCK_ID_GET(_v_) (((_v_) >> 15) & ESP_APPTRACE_TRAX_BLOCK_ID_MSK) -#define ESP_APPTRACE_TRAX_HOST_DATA (1 << 22) -#define ESP_APPTRACE_TRAX_HOST_CONNECT (1 << 23) - -#if CONFIG_SYSVIEW_ENABLE -#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) (0) -#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (_v_) -#else -#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) ((_cid_) << 15) -#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (~(1 << 15) & (_v_)) -#endif -#define ESP_APPTRACE_USR_BLOCK_RAW_SZ(_s_) ((_s_) + sizeof(esp_tracedata_hdr_t)) - -#if CONFIG_IDF_TARGET_ESP32 -static volatile uint8_t *s_trax_blocks[] = { - (volatile uint8_t *) 0x3FFFC000, - (volatile uint8_t *) 0x3FFF8000 -}; -#elif CONFIG_IDF_TARGET_ESP32S2 -static volatile uint8_t *s_trax_blocks[] = { - (volatile uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK0_NUM), - (volatile uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK1_NUM) -}; -#endif - -#define ESP_APPTRACE_TRAX_BLOCKS_NUM (sizeof(s_trax_blocks)/sizeof(s_trax_blocks[0])) - -#define ESP_APPTRACE_TRAX_INBLOCK_START 0 - -#define ESP_APPTRACE_TRAX_INBLOCK_MARKER() (s_trace_buf.trax.state.markers[s_trace_buf.trax.state.in_block % 2]) -#define ESP_APPTRACE_TRAX_INBLOCK_MARKER_UPD(_v_) do {s_trace_buf.trax.state.markers[s_trace_buf.trax.state.in_block % 2] += (_v_);}while(0) -#define ESP_APPTRACE_TRAX_INBLOCK_GET() (&s_trace_buf.trax.blocks[s_trace_buf.trax.state.in_block % 2]) - -#define ESP_APPTRACE_TRAX_BLOCK_SIZE (0x4000UL) -#if CONFIG_SYSVIEW_ENABLE -#define ESP_APPTRACE_USR_DATA_LEN_MAX 255UL -#else -#define ESP_APPTRACE_USR_DATA_LEN_MAX (ESP_APPTRACE_TRAX_BLOCK_SIZE - sizeof(esp_tracedata_hdr_t)) -#endif - -#define ESP_APPTRACE_HW_TRAX 0 -#define ESP_APPTRACE_HW_MAX 1 -#define ESP_APPTRACE_HW(_i_) (&s_trace_hw[_i_]) - -/** Trace data header. Every user data chunk is prepended with this header. - * User allocates block with esp_apptrace_buffer_get and then fills it with data, - * in multithreading environment it can happen that tasks gets buffer and then gets interrupted, - * so it is possible that user data are incomplete when TRAX memory block is exposed to the host. - * In this case host SW will see that wr_sz < block_sz and will report error. - */ -typedef struct { -#if CONFIG_SYSVIEW_ENABLE - uint8_t block_sz; // size of allocated block for user data - uint8_t wr_sz; // size of actually written data -#else - uint16_t block_sz; // size of allocated block for user data - uint16_t wr_sz; // size of actually written data -#endif -} esp_tracedata_hdr_t; - -/** TODO: docs - */ -typedef struct { - uint16_t block_sz; // size of allocated block for user data -} esp_hostdata_hdr_t; - -/** TRAX HW transport state */ -typedef struct { - uint32_t in_block; // input block ID - // TODO: change to uint16_t - uint32_t markers[ESP_APPTRACE_TRAX_BLOCKS_NUM]; // block filling level markers -} esp_apptrace_trax_state_t; - -/** memory block parameters */ -typedef struct { - uint8_t *start; // start address - uint16_t sz; // size -} esp_apptrace_mem_block_t; - -/** TRAX HW transport data */ -typedef struct { - volatile esp_apptrace_trax_state_t state; // state - esp_apptrace_mem_block_t blocks[ESP_APPTRACE_TRAX_BLOCKS_NUM]; // memory blocks -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - // ring buffer control struct for pending user blocks - esp_apptrace_rb_t rb_pend; - // storage for pending user blocks - uint8_t pending_data[CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX + 1]; -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - // ring buffer control struct for pending user data chunks sizes, - // every chunk contains whole number of user blocks and fit into TRAX memory block - esp_apptrace_rb_t rb_pend_chunk_sz; - // storage for above ring buffer data - uint16_t pending_chunk_sz[CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX/ESP_APPTRACE_TRAX_BLOCK_SIZE + 2]; - // current (accumulated) pending user data chunk size - uint16_t cur_pending_chunk_sz; -#endif -#endif -} esp_apptrace_trax_data_t; - /** tracing module internal data */ typedef struct { - esp_apptrace_lock_t lock; // sync lock - uint8_t inited; // module initialization state flag - // ring buffer control struct for data from host (down buffer) - esp_apptrace_rb_t rb_down; - // storage for above ring buffer data - esp_apptrace_trax_data_t trax; // TRAX HW transport data -} esp_apptrace_buffer_t; - -static esp_apptrace_buffer_t s_trace_buf; - -#if ESP_APPTRACE_PRINT_LOCK -static esp_apptrace_lock_t s_log_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED}; -#endif - -typedef struct { - uint8_t *(*get_up_buffer)(uint32_t, esp_apptrace_tmo_t *); - esp_err_t (*put_up_buffer)(uint8_t *, esp_apptrace_tmo_t *); - esp_err_t (*flush_up_buffer)(uint32_t, esp_apptrace_tmo_t *); - uint8_t *(*get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *); - esp_err_t (*put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *); - bool (*host_is_connected)(void); - esp_err_t (*status_reg_set)(uint32_t val); - esp_err_t (*status_reg_get)(uint32_t *val); -} esp_apptrace_hw_t; - -static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32_t size); -static esp_err_t esp_apptrace_trax_flush(uint32_t min_sz, esp_apptrace_tmo_t *tmo); -static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *tmo); -static esp_err_t esp_apptrace_trax_put_buffer(uint8_t *ptr, esp_apptrace_tmo_t *tmo); -static bool esp_apptrace_trax_host_is_connected(void); -static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_tmo_t *tmo); -static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo); -static esp_err_t esp_apptrace_trax_status_reg_set(uint32_t val); -static esp_err_t esp_apptrace_trax_status_reg_get(uint32_t *val); + esp_apptrace_hw_t * hw; + void * hw_data; +} esp_apptrace_channel_t; -static esp_apptrace_hw_t s_trace_hw[ESP_APPTRACE_HW_MAX] = { - { - .get_up_buffer = esp_apptrace_trax_get_buffer, - .put_up_buffer = esp_apptrace_trax_put_buffer, - .flush_up_buffer = esp_apptrace_trax_flush, - .get_down_buffer = esp_apptrace_trax_down_buffer_get, - .put_down_buffer = esp_apptrace_trax_down_buffer_put, - .host_is_connected = esp_apptrace_trax_host_is_connected, - .status_reg_set = esp_apptrace_trax_status_reg_set, - .status_reg_get = esp_apptrace_trax_status_reg_get - } -}; - -static inline int esp_apptrace_log_lock(void) -{ -#if ESP_APPTRACE_PRINT_LOCK - esp_apptrace_tmo_t tmo; - esp_apptrace_tmo_init(&tmo, ESP_APPTRACE_TMO_INFINITE); - int ret = esp_apptrace_lock_take(&s_log_lock, &tmo); - return ret; -#else - return 0; -#endif -} +static esp_apptrace_channel_t s_trace_channels[ESP_APPTRACE_DEST_NUM]; +static bool s_inited; -static inline void esp_apptrace_log_unlock(void) -{ - #if ESP_APPTRACE_PRINT_LOCK - esp_apptrace_lock_give(&s_log_lock); -#endif -} - -static inline esp_err_t esp_apptrace_lock_initialize(esp_apptrace_lock_t *lock) -{ -#if CONFIG_APPTRACE_LOCK_ENABLE - esp_apptrace_lock_init(lock); -#endif - return ESP_OK; -} - -static inline esp_err_t esp_apptrace_lock_cleanup(void) -{ - return ESP_OK; -} - -esp_err_t esp_apptrace_lock(esp_apptrace_tmo_t *tmo) -{ -#if CONFIG_APPTRACE_LOCK_ENABLE - esp_err_t ret = esp_apptrace_lock_take(&s_trace_buf.lock, tmo); - if (ret != ESP_OK) { - return ESP_FAIL; - } -#endif - return ESP_OK; -} - -esp_err_t esp_apptrace_unlock(void) -{ - esp_err_t ret = ESP_OK; -#if CONFIG_APPTRACE_LOCK_ENABLE - ret = esp_apptrace_lock_give(&s_trace_buf.lock); -#endif - return ret; -} - -#if CONFIG_APPTRACE_DEST_TRAX - -static inline void esp_apptrace_trax_select_memory_block(int block_num) -{ - // select memory block to be exposed to the TRAX module (accessed by host) -#if CONFIG_IDF_TARGET_ESP32 - DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY); -#elif CONFIG_IDF_TARGET_ESP32S2 - DPORT_WRITE_PERI_REG(DPORT_PMS_OCCUPY_3_REG, block_num ? BIT(TRACEMEM_MUX_BLK0_NUM-4) : BIT(TRACEMEM_MUX_BLK1_NUM-4)); -#endif -} - -static void esp_apptrace_trax_init(void) -{ - // Stop trace, if any (on the current CPU) - eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TRSTP); - eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TMEN); - eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(ESP_APPTRACE_TRAX_INBLOCK_START)); - // this is for OpenOCD to let him know where stub entries vector is resided - // must be read by host before any transfer using TRAX - eri_write(ESP_APPTRACE_TRAX_STAT_REG, 0); - - ESP_APPTRACE_LOGI("Initialized TRAX on CPU%d", xPortGetCoreID()); -} - -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE -// keep the size of buffered data for copying to TRAX mem block. -// Only whole user blocks should be copied from buffer to TRAX block upon the switch -static void esp_apptrace_trax_pend_chunk_sz_update(uint16_t size) -{ - ESP_APPTRACE_LOGD("Update chunk enter %d/%d w-r-s %d-%d-%d", s_trace_buf.trax.cur_pending_chunk_sz, size, - s_trace_buf.trax.rb_pend_chunk_sz.wr, s_trace_buf.trax.rb_pend_chunk_sz.rd, s_trace_buf.trax.rb_pend_chunk_sz.cur_size); - - if ((uint32_t)s_trace_buf.trax.cur_pending_chunk_sz + (uint32_t)size <= ESP_APPTRACE_TRAX_BLOCK_SIZE) { - ESP_APPTRACE_LOGD("Update chunk %d/%d", s_trace_buf.trax.cur_pending_chunk_sz, size); - s_trace_buf.trax.cur_pending_chunk_sz += size; - } else { - uint16_t *chunk_sz = (uint16_t *)esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend_chunk_sz, sizeof(uint16_t)); - if (!chunk_sz) { - assert(false && "Failed to alloc pended chunk sz slot!"); - } else { - ESP_APPTRACE_LOGD("Update new chunk %d/%d", s_trace_buf.trax.cur_pending_chunk_sz, size); - *chunk_sz = s_trace_buf.trax.cur_pending_chunk_sz; - s_trace_buf.trax.cur_pending_chunk_sz = size; - } - } -} - -static uint16_t esp_apptrace_trax_pend_chunk_sz_get(void) -{ - uint16_t ch_sz; - ESP_APPTRACE_LOGD("Get chunk enter %d w-r-s %d-%d-%d", s_trace_buf.trax.cur_pending_chunk_sz, - s_trace_buf.trax.rb_pend_chunk_sz.wr, s_trace_buf.trax.rb_pend_chunk_sz.rd, s_trace_buf.trax.rb_pend_chunk_sz.cur_size); - - uint16_t *chunk_sz = (uint16_t *)esp_apptrace_rb_consume(&s_trace_buf.trax.rb_pend_chunk_sz, sizeof(uint16_t)); - if (!chunk_sz) { - ch_sz = s_trace_buf.trax.cur_pending_chunk_sz; - s_trace_buf.trax.cur_pending_chunk_sz = 0; - } else { - ch_sz = *chunk_sz; - } - return ch_sz; -} -#endif - -// assumed to be protected by caller from multi-core/thread access -static __attribute__((noinline)) esp_err_t esp_apptrace_trax_block_switch(void) -{ - int prev_block_num = s_trace_buf.trax.state.in_block % 2; - int new_block_num = prev_block_num ? (0) : (1); - int res = ESP_OK; - extern uint32_t __esp_apptrace_trax_eri_updated; - - // indicate to host that we are about to update. - // this is used only to place CPU into streaming mode at tracing startup - // before starting streaming host can halt us after we read ESP_APPTRACE_TRAX_CTRL_REG and before we updated it - // HACK: in this case host will set breakpoint just after ESP_APPTRACE_TRAX_CTRL_REG update, - // here we set address to set bp at - // enter ERI update critical section - eri_write(ESP_APPTRACE_TRAX_STAT_REG, (uint32_t)&__esp_apptrace_trax_eri_updated); - - uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); - uint32_t host_connected = ESP_APPTRACE_TRAX_HOST_CONNECT & ctrl_reg; - if (host_connected) { - uint32_t acked_block = ESP_APPTRACE_TRAX_BLOCK_ID_GET(ctrl_reg); - uint32_t host_to_read = ESP_APPTRACE_TRAX_BLOCK_LEN_GET(ctrl_reg); - if (host_to_read != 0 || acked_block != (s_trace_buf.trax.state.in_block & ESP_APPTRACE_TRAX_BLOCK_ID_MSK)) { - ESP_APPTRACE_LOGD("HC[%d]: Can not switch %x %d %x %x/%lx, m %d", xPortGetCoreID(), ctrl_reg, host_to_read, acked_block, - s_trace_buf.trax.state.in_block & ESP_APPTRACE_TRAX_BLOCK_ID_MSK, s_trace_buf.trax.state.in_block, - s_trace_buf.trax.state.markers[prev_block_num]); - res = ESP_ERR_NO_MEM; - goto _on_func_exit; - } - } - s_trace_buf.trax.state.markers[new_block_num] = 0; - // switch to new block - s_trace_buf.trax.state.in_block++; - - esp_apptrace_trax_select_memory_block(new_block_num); - // handle data from host - esp_hostdata_hdr_t *hdr = (esp_hostdata_hdr_t *)s_trace_buf.trax.blocks[new_block_num].start; - if (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA && hdr->block_sz > 0) { - // TODO: add support for multiple blocks from host, currently there is no need for that - uint8_t *p = s_trace_buf.trax.blocks[new_block_num].start + s_trace_buf.trax.blocks[new_block_num].sz; - ESP_APPTRACE_LOGD("Recvd %d bytes from host [%x %x %x %x %x %x %x %x .. %x %x %x %x %x %x %x %x]", hdr->block_sz, - *(s_trace_buf.trax.blocks[new_block_num].start+0), *(s_trace_buf.trax.blocks[new_block_num].start+1), - *(s_trace_buf.trax.blocks[new_block_num].start+2), *(s_trace_buf.trax.blocks[new_block_num].start+3), - *(s_trace_buf.trax.blocks[new_block_num].start+4), *(s_trace_buf.trax.blocks[new_block_num].start+5), - *(s_trace_buf.trax.blocks[new_block_num].start+6), *(s_trace_buf.trax.blocks[new_block_num].start+7), - *(p-8), *(p-7), *(p-6), *(p-5), *(p-4), *(p-3), *(p-2), *(p-1)); - uint32_t sz = esp_apptrace_trax_down_buffer_write_nolock((uint8_t *)(hdr+1), hdr->block_sz); - if (sz != hdr->block_sz) { - ESP_APPTRACE_LOGE("Failed to write %d bytes to down buffer (%d %d)!", hdr->block_sz - sz, hdr->block_sz, sz); - } - hdr->block_sz = 0; - } -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - // copy pending data to TRAX block if any -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - uint16_t max_chunk_sz = esp_apptrace_trax_pend_chunk_sz_get(); -#else - uint16_t max_chunk_sz = s_trace_buf.trax.blocks[new_block_num].sz; -#endif - while (s_trace_buf.trax.state.markers[new_block_num] < max_chunk_sz) { - uint32_t read_sz = esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend); - if (read_sz == 0) { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - /* theres is a bug: esp_apptrace_trax_pend_chunk_sz_get returned wrong value, - it must be greater or equal to one returned by esp_apptrace_rb_read_size_get */ - ESP_APPTRACE_LOGE("No pended bytes, must be > 0 and <= %d!", max_chunk_sz); -#endif - break; - } - if (read_sz > max_chunk_sz - s_trace_buf.trax.state.markers[new_block_num]) { - read_sz = max_chunk_sz - s_trace_buf.trax.state.markers[new_block_num]; - } - uint8_t *ptr = esp_apptrace_rb_consume(&s_trace_buf.trax.rb_pend, read_sz); - if (!ptr) { - assert(false && "Failed to consume pended bytes!!"); - break; - } - if (host_connected) { - ESP_APPTRACE_LOGD("Pump %d pend bytes [%x %x %x %x : %x %x %x %x : %x %x %x %x : %x %x...%x %x]", - read_sz, *(ptr+0), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), - *(ptr+5), *(ptr+6), *(ptr+7), *(ptr+8), *(ptr+9), *(ptr+10), *(ptr+11), *(ptr+12), *(ptr+13), *(ptr+read_sz-2), *(ptr+read_sz-1)); - } - memcpy(s_trace_buf.trax.blocks[new_block_num].start + s_trace_buf.trax.state.markers[new_block_num], ptr, read_sz); - s_trace_buf.trax.state.markers[new_block_num] += read_sz; - } -#endif - eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(s_trace_buf.trax.state.in_block) | - host_connected | ESP_APPTRACE_TRAX_BLOCK_LEN(s_trace_buf.trax.state.markers[prev_block_num])); - -_on_func_exit: - // exit ERI update critical section - eri_write(ESP_APPTRACE_TRAX_STAT_REG, 0x0); - // TODO: currently host sets breakpoint, use break instruction to stop; - // it will allow to use ESP_APPTRACE_TRAX_STAT_REG for other purposes - asm volatile ( - " .global __esp_apptrace_trax_eri_updated\n" - "__esp_apptrace_trax_eri_updated:\n"); // host will set bp here to resolve collision at streaming start - return res; -} - -static esp_err_t esp_apptrace_trax_block_switch_waitus(esp_apptrace_tmo_t *tmo) +esp_err_t esp_apptrace_init(void) { int res; - - while ((res = esp_apptrace_trax_block_switch()) != ESP_OK) { - res = esp_apptrace_tmo_check(tmo); - if (res != ESP_OK) { - break; + esp_apptrace_hw_t *hw = NULL; + void *hw_data = NULL; + + // 'esp_apptrace_init()' is called on every core, so ensure to do main initialization only once + if (cpu_hal_get_core_id() == 0) { + memset(&s_trace_channels, 0, sizeof(s_trace_channels)); + hw = esp_apptrace_jtag_hw_get(&hw_data); + ESP_APPTRACE_LOGD("HW interface %p", hw); + if (hw != NULL) { + s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw = hw; + s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw_data = hw_data; + } + hw = esp_apptrace_uart_hw_get(0, &hw_data); + if (hw != NULL) { + s_trace_channels[ESP_APPTRACE_DEST_UART0].hw = hw; + s_trace_channels[ESP_APPTRACE_DEST_UART0].hw_data = hw_data; } + s_inited = true; } - return res; -} -static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_tmo_t *tmo) -{ - uint8_t *ptr = NULL; - - int res = esp_apptrace_lock(tmo); - if (res != ESP_OK) { - return NULL; - } - while (1) { - uint32_t sz = esp_apptrace_rb_read_size_get(&s_trace_buf.rb_down); - if (sz != 0) { - *size = MIN(*size, sz); - ptr = esp_apptrace_rb_consume(&s_trace_buf.rb_down, *size); - if (!ptr) { - assert(false && "Failed to consume bytes from down buffer!"); - } - break; - } - // may need to flush - uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); - if (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA) { - ESP_APPTRACE_LOGD("force flush"); - res = esp_apptrace_trax_block_switch_waitus(tmo); - if (res != ESP_OK) { - ESP_APPTRACE_LOGE("Failed to switch to another block to recv data from host!"); - /*do not return error because data can be in down buffer already*/ - } - } else { - // check tmo only if there is no data from host - res = esp_apptrace_tmo_check(tmo); + // esp_apptrace_init() is called on every core, so initialize trace channel on every core + for (int i = 0; i < sizeof(s_trace_channels)/sizeof(s_trace_channels[0]); i++) { + esp_apptrace_channel_t *ch = &s_trace_channels[i]; + if (ch->hw) { + res = ch->hw->init(ch->hw_data); if (res != ESP_OK) { - return NULL; + ESP_APPTRACE_LOGE("Failed to init trace channel HW interface (%d)!", res); + return res; } } } - if (esp_apptrace_unlock() != ESP_OK) { - assert(false && "Failed to unlock apptrace data!"); - } - return ptr; -} -static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo) -{ - /* nothing todo */ return ESP_OK; } -static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32_t size) +void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size) { - uint32_t total_sz = 0; + esp_apptrace_channel_t *ch; - while (total_sz < size) { - ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", s_trace_buf.rb_down.wr, s_trace_buf.rb_down.rd, - s_trace_buf.rb_down.cur_size, size); - uint32_t wr_sz = esp_apptrace_rb_write_size_get(&s_trace_buf.rb_down); - if (wr_sz == 0) { - break; - } - - if (wr_sz > size - total_sz) { - wr_sz = size - total_sz; - } - ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz); - uint8_t *ptr = esp_apptrace_rb_produce(&s_trace_buf.rb_down, wr_sz); - if (!ptr) { - assert(false && "Failed to produce bytes to down buffer!"); - } - ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz); - memcpy(ptr, data + total_sz, wr_sz); - total_sz += wr_sz; - ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz); + if (!s_inited) { + return; } - return total_sz; -} - -static inline uint8_t *esp_apptrace_data_header_init(uint8_t *ptr, uint16_t usr_size) -{ - // it is safe to use xPortGetCoreID() in macro call because arg is used only once inside it - ((esp_tracedata_hdr_t *)ptr)->block_sz = ESP_APPTRACE_USR_BLOCK_CORE(xPortGetCoreID()) | usr_size; - ((esp_tracedata_hdr_t *)ptr)->wr_sz = 0; - return ptr + sizeof(esp_tracedata_hdr_t); -} - -static inline uint8_t *esp_apptrace_trax_wait4buf(uint16_t size, esp_apptrace_tmo_t *tmo, int *pended) -{ - uint8_t *ptr = NULL; - - int res = esp_apptrace_trax_block_switch_waitus(tmo); - if (res != ESP_OK) { - return NULL; + // currently down buffer is supported for JTAG interface only + // TODO: one more argument should be added to this function to specify HW inteface: JTAG, UART0 etc + ch = &s_trace_channels[ESP_APPTRACE_DEST_JTAG]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination not supported!"); + return; } - // check if we still have pending data -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - if (esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend) > 0) { - // if after TRAX block switch still have pending data (not all pending data have been pumped to TRAX block) - // alloc new pending buffer - *pended = 1; - ptr = esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend, size); - if (!ptr) { - ESP_APPTRACE_LOGE("Failed to alloc pend buf 1: w-r-s %d-%d-%d!", s_trace_buf.trax.rb_pend.wr, s_trace_buf.trax.rb_pend.rd, s_trace_buf.trax.rb_pend.cur_size); - } - } else -#endif - { - // update block pointers - if (ESP_APPTRACE_TRAX_INBLOCK_MARKER() + size > ESP_APPTRACE_TRAX_INBLOCK_GET()->sz) { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - *pended = 1; - ptr = esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend, size); - if (ptr == NULL) { - ESP_APPTRACE_LOGE("Failed to alloc pend buf 2: w-r-s %d-%d-%d!", s_trace_buf.trax.rb_pend.wr, s_trace_buf.trax.rb_pend.rd, s_trace_buf.trax.rb_pend.cur_size); - } -#endif - } else { - *pended = 0; - ptr = ESP_APPTRACE_TRAX_INBLOCK_GET()->start + ESP_APPTRACE_TRAX_INBLOCK_MARKER(); - } + if (ch->hw->down_buffer_config == NULL) { + return; } - return ptr; + ch->hw->down_buffer_config(ch->hw_data, buf, size); } -static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *tmo) +uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t user_tmo) { - uint8_t *buf_ptr = NULL; + esp_apptrace_tmo_t tmo; + esp_apptrace_channel_t *ch; - if (size > ESP_APPTRACE_USR_DATA_LEN_MAX) { - ESP_APPTRACE_LOGE("Too large user data size %d!", size); + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { return NULL; } - - int res = esp_apptrace_lock(tmo); - if (res != ESP_OK) { + if (size == NULL || *size == 0) { return NULL; } - // check for data in the pending buffer -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - if (esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend) > 0) { - // if we have buffered data try to switch TRAX block - esp_apptrace_trax_block_switch(); - // if switch was successful, part or all pended data have been copied to TRAX block - } - if (esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend) > 0) { - // if we have buffered data alloc new pending buffer - ESP_APPTRACE_LOGD("Get %d bytes from PEND buffer", size); - buf_ptr = esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); - if (buf_ptr == NULL) { - int pended_buf; - buf_ptr = esp_apptrace_trax_wait4buf(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf); - if (buf_ptr) { - if (pended_buf) { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); -#endif - } else { - ESP_APPTRACE_LOGD("Get %d bytes from TRAX buffer", size); - // update cur block marker - ESP_APPTRACE_TRAX_INBLOCK_MARKER_UPD(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); - } - } - } else { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); -#endif - } - } else -#endif - if (ESP_APPTRACE_TRAX_INBLOCK_MARKER() + ESP_APPTRACE_USR_BLOCK_RAW_SZ(size) > ESP_APPTRACE_TRAX_INBLOCK_GET()->sz) { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - ESP_APPTRACE_LOGD("TRAX full. Get %d bytes from PEND buffer", size); - buf_ptr = esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); - if (buf_ptr) { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); -#endif - } -#endif - if (buf_ptr == NULL) { - int pended_buf; - ESP_APPTRACE_LOGD("TRAX full. Get %d bytes from pend buffer", size); - buf_ptr = esp_apptrace_trax_wait4buf(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf); - if (buf_ptr) { - if (pended_buf) { -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); -#endif - } else { - ESP_APPTRACE_LOGD("Got %d bytes from TRAX buffer", size); - // update cur block marker - ESP_APPTRACE_TRAX_INBLOCK_MARKER_UPD(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); - } - } - } - } else { - ESP_APPTRACE_LOGD("Get %d bytes from TRAX buffer", size); - // fit to curr TRAX nlock - buf_ptr = ESP_APPTRACE_TRAX_INBLOCK_GET()->start + ESP_APPTRACE_TRAX_INBLOCK_MARKER(); - // update cur block marker - ESP_APPTRACE_TRAX_INBLOCK_MARKER_UPD(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); + if (!s_inited) { + return NULL; } - if (buf_ptr) { - buf_ptr = esp_apptrace_data_header_init(buf_ptr, size); + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return NULL; } - - // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data - if (esp_apptrace_unlock() != ESP_OK) { - assert(false && "Failed to unlock apptrace data!"); + if (ch->hw->get_down_buffer == NULL) { + return NULL; } - return buf_ptr; -} - -static esp_err_t esp_apptrace_trax_put_buffer(uint8_t *ptr, esp_apptrace_tmo_t *tmo) -{ - int res = ESP_OK; - esp_tracedata_hdr_t *hdr = (esp_tracedata_hdr_t *)(ptr - sizeof(esp_tracedata_hdr_t)); - - // update written size - hdr->wr_sz = hdr->block_sz; - - // TODO: mark block as busy in order not to re-use it for other tracing calls until it is completely written - // TODO: avoid potential situation when all memory is consumed by low prio tasks which can not complete writing due to - // higher prio tasks and the latter can not allocate buffers at all - // this is abnormal situation can be detected on host which will receive only uncompleted buffers - // workaround: use own memcpy which will kick-off dead tracing calls - - return res; + esp_apptrace_tmo_init(&tmo, user_tmo); + return ch->hw->get_down_buffer(ch->hw_data, size, &tmo); } -static esp_err_t esp_apptrace_trax_flush(uint32_t min_sz, esp_apptrace_tmo_t *tmo) +esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo) { - int res = ESP_OK; + esp_apptrace_tmo_t tmo; + esp_apptrace_channel_t *ch; - if (ESP_APPTRACE_TRAX_INBLOCK_MARKER() < min_sz) { - ESP_APPTRACE_LOGI("Ignore flush request for min %d bytes. Bytes in TRAX block: %d.", min_sz, ESP_APPTRACE_TRAX_INBLOCK_MARKER()); - return ESP_OK; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return ESP_ERR_INVALID_ARG; } - // switch TRAX block while size of data is more than min size - while (ESP_APPTRACE_TRAX_INBLOCK_MARKER() > 0) { - ESP_APPTRACE_LOGD("Try to flush %d bytes. Wait until block switch for %u us", ESP_APPTRACE_TRAX_INBLOCK_MARKER(), tmo->tmo); - res = esp_apptrace_trax_block_switch_waitus(tmo); - if (res != ESP_OK) { - ESP_APPTRACE_LOGE("Failed to switch to another block!"); - return res; - } + if (ptr == NULL) { + return ESP_ERR_INVALID_ARG; } - - return res; -} - -static bool esp_apptrace_trax_host_is_connected(void) -{ - return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false; -} - -static esp_err_t esp_apptrace_trax_status_reg_set(uint32_t val) -{ - eri_write(ESP_APPTRACE_TRAX_STAT_REG, val); - return ESP_OK; -} - -static esp_err_t esp_apptrace_trax_status_reg_get(uint32_t *val) -{ - *val = eri_read(ESP_APPTRACE_TRAX_STAT_REG); - return ESP_OK; -} - -static esp_err_t esp_apptrace_trax_dest_init(void) -{ - for (size_t i = 0; i < ESP_APPTRACE_TRAX_BLOCKS_NUM; i++) { - s_trace_buf.trax.blocks[i].start = (uint8_t *)s_trax_blocks[i]; - s_trace_buf.trax.blocks[i].sz = ESP_APPTRACE_TRAX_BLOCK_SIZE; - s_trace_buf.trax.state.markers[i] = 0; + if (!s_inited) { + return ESP_ERR_INVALID_STATE; } - s_trace_buf.trax.state.in_block = ESP_APPTRACE_TRAX_INBLOCK_START; -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 - esp_apptrace_rb_init(&s_trace_buf.trax.rb_pend, s_trace_buf.trax.pending_data, - sizeof(s_trace_buf.trax.pending_data)); -#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE - s_trace_buf.trax.cur_pending_chunk_sz = 0; - esp_apptrace_rb_init(&s_trace_buf.trax.rb_pend_chunk_sz, (uint8_t *)s_trace_buf.trax.pending_chunk_sz, - sizeof(s_trace_buf.trax.pending_chunk_sz)); -#endif -#endif - -#if CONFIG_IDF_TARGET_ESP32 - DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, DPORT_PRO_TRACEMEM_ENA_M); -#if CONFIG_FREERTOS_UNICORE == 0 - DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_M); -#endif -#endif - esp_apptrace_trax_select_memory_block(0); - - return ESP_OK; -} -#endif - -esp_err_t esp_apptrace_init(void) -{ - int res; - - if (!s_trace_buf.inited) { - memset(&s_trace_buf, 0, sizeof(s_trace_buf)); - // disabled by default - esp_apptrace_rb_init(&s_trace_buf.rb_down, NULL, 0); - res = esp_apptrace_lock_initialize(&s_trace_buf.lock); - if (res != ESP_OK) { - ESP_APPTRACE_LOGE("Failed to init log lock (%d)!", res); - return res; - } -#if CONFIG_APPTRACE_DEST_TRAX - res = esp_apptrace_trax_dest_init(); - if (res != ESP_OK) { - ESP_APPTRACE_LOGE("Failed to init TRAX dest data (%d)!", res); - esp_apptrace_lock_cleanup(); - return res; - } -#endif + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return ESP_ERR_NOT_SUPPORTED; + } + if (ch->hw->get_down_buffer == NULL) { + return ESP_ERR_NOT_SUPPORTED; } -#if CONFIG_APPTRACE_DEST_TRAX - // init TRAX on this CPU - esp_apptrace_trax_init(); -#endif - - s_trace_buf.inited |= 1 << xPortGetCoreID(); // global and this CPU-specific data are inited - - return ESP_OK; -} - -void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size) -{ - esp_apptrace_rb_init(&s_trace_buf.rb_down, buf, size); + esp_apptrace_tmo_init(&tmo, user_tmo); + return ch->hw->put_down_buffer(ch->hw_data, ptr, &tmo); } esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size, uint32_t user_tmo) { int res = ESP_OK; esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return ESP_ERR_NOT_SUPPORTED; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return ESP_ERR_INVALID_ARG; } if (buf == NULL || size == NULL || *size == 0) { return ESP_ERR_INVALID_ARG; } + if (!s_inited) { + return ESP_ERR_INVALID_STATE; + } + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return ESP_ERR_NOT_SUPPORTED; + } + if (ch->hw->get_down_buffer == NULL || ch->hw->put_down_buffer == NULL) { + return ESP_ERR_NOT_SUPPORTED; + } //TODO: callback system esp_apptrace_tmo_init(&tmo, user_tmo); uint32_t act_sz = *size; *size = 0; - uint8_t * ptr = hw->get_down_buffer(&act_sz, &tmo); + uint8_t * ptr = ch->hw->get_down_buffer(ch->hw_data, &act_sz, &tmo); if (ptr && act_sz > 0) { ESP_APPTRACE_LOGD("Read %d bytes from host", act_sz); memcpy(buf, ptr, act_sz); - res = hw->put_down_buffer(ptr, &tmo); + res = ch->hw->put_down_buffer(ch->hw_data, ptr, &tmo); *size = act_sz; } else { res = ESP_ERR_TIMEOUT; @@ -984,77 +182,89 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size, return res; } -uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t user_tmo) +uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t user_tmo) { esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { return NULL; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); + } + if (size == 0) { return NULL; } - if (size == NULL || *size == 0) { + if (!s_inited) { + return NULL; + } + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return NULL; + } + if (ch->hw->get_up_buffer == NULL) { return NULL; } esp_apptrace_tmo_init(&tmo, user_tmo); - return hw->get_down_buffer(size, &tmo); + return ch->hw->get_up_buffer(ch->hw_data, size, &tmo); } -esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo) +esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo) { esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return ESP_ERR_NOT_SUPPORTED; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return ESP_ERR_INVALID_ARG; } if (ptr == NULL) { return ESP_ERR_INVALID_ARG; } + if (!s_inited) { + return ESP_ERR_INVALID_STATE; + } + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return ESP_ERR_NOT_SUPPORTED; + } + if (ch->hw->put_up_buffer == NULL) { + return ESP_ERR_NOT_SUPPORTED; + } esp_apptrace_tmo_init(&tmo, user_tmo); - return hw->put_down_buffer(ptr, &tmo); + return ch->hw->put_up_buffer(ch->hw_data, ptr, &tmo); } esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t user_tmo) { uint8_t *ptr = NULL; esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return ESP_ERR_NOT_SUPPORTED; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return ESP_ERR_INVALID_ARG; } if (data == NULL || size == 0) { return ESP_ERR_INVALID_ARG; } + if (!s_inited) { + return ESP_ERR_INVALID_STATE; + } + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return ESP_ERR_NOT_SUPPORTED; + } + if (ch->hw->get_up_buffer == NULL || ch->hw->put_up_buffer == NULL) { + return ESP_ERR_NOT_SUPPORTED; + } esp_apptrace_tmo_init(&tmo, user_tmo); - ptr = hw->get_up_buffer(size, &tmo); + ptr = ch->hw->get_up_buffer(ch->hw_data, size, &tmo); if (ptr == NULL) { return ESP_ERR_NO_MEM; } @@ -1064,7 +274,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_ memcpy(ptr, data, size); // now indicate that this buffer is ready to be sent off to host - return hw->put_up_buffer(ptr, &tmo); + return ch->hw->put_up_buffer(ch->hw_data, ptr, &tmo); } int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const char *fmt, va_list ap) @@ -1072,21 +282,25 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c uint16_t nargs = 0; uint8_t *pout, *p = (uint8_t *)fmt; esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return ESP_ERR_NOT_SUPPORTED; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return -1; } if (fmt == NULL) { - return ESP_ERR_INVALID_ARG; + return -1; + } + if (!s_inited) { + return -1; + } + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return -1; + } + if (ch->hw->get_up_buffer == NULL || ch->hw->put_up_buffer == NULL) { + return -1; } esp_apptrace_tmo_init(&tmo, user_tmo); @@ -1102,7 +316,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c ESP_APPTRACE_LOGE("Failed to store all printf args!"); } - pout = hw->get_up_buffer(1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo); + pout = ch->hw->get_up_buffer(ch->hw_data, 1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo); if (pout == NULL) { ESP_APPTRACE_LOGE("Failed to get buffer!"); return -1; @@ -1119,7 +333,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c ESP_APPTRACE_LOGD("arg %x", arg); } - int ret = hw->put_up_buffer(p, &tmo); + int ret = ch->hw->put_up_buffer(ch->hw_data, p, &tmo); if (ret != ESP_OK) { ESP_APPTRACE_LOGE("Failed to put printf buf (%d)!", ret); return -1; @@ -1130,154 +344,78 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c int esp_apptrace_vprintf(const char *fmt, va_list ap) { - return esp_apptrace_vprintf_to(ESP_APPTRACE_DEST_TRAX, /*ESP_APPTRACE_TMO_INFINITE*/0, fmt, ap); + return esp_apptrace_vprintf_to(ESP_APPTRACE_DEST_JTAG, 0, fmt, ap); } -uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t user_tmo) +esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t usr_tmo) { esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return NULL; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return NULL; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return ESP_ERR_INVALID_ARG; } - if (size == 0) { - return NULL; + if (!s_inited) { + return ESP_ERR_INVALID_STATE; } - - esp_apptrace_tmo_init(&tmo, user_tmo); - return hw->get_up_buffer(size, &tmo); -} - -esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo) -{ - esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; - - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); return ESP_ERR_NOT_SUPPORTED; } - if (ptr == NULL) { - return ESP_ERR_INVALID_ARG; - } - - esp_apptrace_tmo_init(&tmo, user_tmo); - return hw->put_up_buffer(ptr, &tmo); -} - -esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t usr_tmo) -{ - esp_apptrace_tmo_t tmo; - esp_apptrace_hw_t *hw = NULL; - - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); + if (ch->hw->flush_up_buffer_nolock == NULL) { return ESP_ERR_NOT_SUPPORTED; } esp_apptrace_tmo_init(&tmo, usr_tmo); - return hw->flush_up_buffer(min_sz, &tmo); + return ch->hw->flush_up_buffer_nolock(ch->hw_data, min_sz, &tmo); } esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t usr_tmo) { - int res; esp_apptrace_tmo_t tmo; + esp_apptrace_channel_t *ch; - esp_apptrace_tmo_init(&tmo, usr_tmo); - res = esp_apptrace_lock(&tmo); - if (res != ESP_OK) { - ESP_APPTRACE_LOGE("Failed to lock apptrace data (%d)!", res); - return res; + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { + return ESP_ERR_INVALID_ARG; } - - res = esp_apptrace_flush_nolock(dest, 0, esp_apptrace_tmo_remaining_us(&tmo)); - if (res != ESP_OK) { - ESP_APPTRACE_LOGE("Failed to flush apptrace data (%d)!", res); + if (!s_inited) { + return ESP_ERR_INVALID_STATE; } - - if (esp_apptrace_unlock() != ESP_OK) { - assert(false && "Failed to unlock apptrace data!"); + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return ESP_ERR_NOT_SUPPORTED; + } + if (ch->hw->flush_up_buffer == NULL) { + return ESP_ERR_NOT_SUPPORTED; } - return res; + esp_apptrace_tmo_init(&tmo, usr_tmo); + return ch->hw->flush_up_buffer(ch->hw_data, &tmo); } bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest) { - esp_apptrace_hw_t *hw = NULL; + esp_apptrace_channel_t *ch; - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); + ESP_APPTRACE_LOGV("%s(): enter", __func__); + if (dest >= ESP_APPTRACE_DEST_MAX) { return false; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); + } + if (!s_inited) { return false; } - return hw->host_is_connected(); -} - -esp_err_t esp_apptrace_status_reg_set(esp_apptrace_dest_t dest, uint32_t val) -{ - esp_apptrace_hw_t *hw = NULL; - - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return ESP_ERR_NOT_SUPPORTED; + ch = &s_trace_channels[dest]; + if (ch->hw == NULL) { + ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest); + return false; } - return hw->status_reg_set(val); -} - -esp_err_t esp_apptrace_status_reg_get(esp_apptrace_dest_t dest, uint32_t *val) -{ - esp_apptrace_hw_t *hw = NULL; - - if (dest == ESP_APPTRACE_DEST_TRAX) { -#if CONFIG_APPTRACE_DEST_TRAX - hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX); -#else - ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!"); - return ESP_ERR_NOT_SUPPORTED; -#endif - } else { - ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!"); - return ESP_ERR_NOT_SUPPORTED; + if (ch->hw->host_is_connected == NULL) { + return false; } - return hw->status_reg_get(val); -} -#endif + return ch->hw->host_is_connected(ch->hw_data); +} diff --git a/components/app_trace/app_trace_membufs_proto.c b/components/app_trace/app_trace_membufs_proto.c new file mode 100644 index 000000000000..daa2d8cc412c --- /dev/null +++ b/components/app_trace/app_trace_membufs_proto.c @@ -0,0 +1,364 @@ +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_app_trace_membufs_proto.h" + +/** Trace data header. Every user data chunk is prepended with this header. + * User allocates block with esp_apptrace_buffer_get and then fills it with data, + * in multithreading environment it can happen that tasks gets buffer and then gets interrupted, + * so it is possible that user data are incomplete when memory block is exposed to the host. + * In this case host SW will see that wr_sz < block_sz and will report error. + */ +typedef struct { +#if CONFIG_APPTRACE_SV_ENABLE + uint8_t block_sz; // size of allocated block for user data + uint8_t wr_sz; // size of actually written data +#else + uint16_t block_sz; // size of allocated block for user data + uint16_t wr_sz; // size of actually written data +#endif +} esp_tracedata_hdr_t; + +/** TODO: docs + */ +typedef struct { + uint16_t block_sz; // size of allocated block for user data +} esp_hostdata_hdr_t; + +#if CONFIG_APPTRACE_SV_ENABLE +#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) (0) +#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (_v_) +#define ESP_APPTRACE_USR_DATA_LEN_MAX(_hw_data_) 255UL +#else +#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) ((_cid_) << 15) +#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (~(1 << 15) & (_v_)) +#define ESP_APPTRACE_USR_DATA_LEN_MAX(_hw_data_) (ESP_APPTRACE_INBLOCK(_hw_data_)->sz - sizeof(esp_tracedata_hdr_t)) +#endif +#define ESP_APPTRACE_USR_BLOCK_RAW_SZ(_s_) ((_s_) + sizeof(esp_tracedata_hdr_t)) + +#define ESP_APPTRACE_INBLOCK_MARKER(_hw_data_) ((_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2]) +#define ESP_APPTRACE_INBLOCK_MARKER_UPD(_hw_data_, _v_) do {(_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2] += (_v_);}while(0) +#define ESP_APPTRACE_INBLOCK(_hw_data_) (&(_hw_data_)->blocks[(_hw_data_)->state.in_block % 2]) + +const static char *TAG = "esp_apptrace"; + +static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto, uint8_t *data, uint32_t size); + + +esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto, const esp_apptrace_mem_block_t blocks_cfg[2]) +{ + // disabled by default + esp_apptrace_rb_init(&proto->rb_down, NULL, 0); + // membufs proto init + for (unsigned i = 0; i < 2; i++) { + proto->blocks[i].start = blocks_cfg[i].start; + proto->blocks[i].sz = blocks_cfg[i].sz; + proto->state.markers[i] = 0; + } + proto->state.in_block = 0; +#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + esp_apptrace_rb_init(&proto->rb_pend, proto->pending_data, + sizeof(proto->pending_data)); +#endif + return ESP_OK; +} + +void esp_apptrace_membufs_down_buffer_config(esp_apptrace_membufs_proto_data_t *data, uint8_t *buf, uint32_t size) +{ + esp_apptrace_rb_init(&data->rb_down, buf, size); +} + +// assumed to be protected by caller from multi-core/thread access +static esp_err_t esp_apptrace_membufs_swap(esp_apptrace_membufs_proto_data_t *proto) +{ + int prev_block_num = proto->state.in_block % 2; + int new_block_num = prev_block_num ? (0) : (1); + esp_err_t res = ESP_OK; + + res = proto->hw->swap_start(proto->state.in_block); + if (res != ESP_OK) { + return res; + } + + proto->state.markers[new_block_num] = 0; + // switch to new block + proto->state.in_block++; + + proto->hw->swap(new_block_num); + + // handle data from host + esp_hostdata_hdr_t *hdr = (esp_hostdata_hdr_t *)proto->blocks[new_block_num].start; + // ESP_APPTRACE_LOGV("Host data %d, sz %d @ %p", proto->hw->host_data_pending(), hdr->block_sz, hdr); + if (proto->hw->host_data_pending() && hdr->block_sz > 0) { + // TODO: add support for multiple blocks from host, currently there is no need for that + uint8_t *p = proto->blocks[new_block_num].start + proto->blocks[new_block_num].sz; + ESP_APPTRACE_LOGD("Recvd %d bytes from host [%x %x %x %x %x %x %x %x .. %x %x %x %x %x %x %x %x]", hdr->block_sz, + *(proto->blocks[new_block_num].start+0), *(proto->blocks[new_block_num].start+1), + *(proto->blocks[new_block_num].start+2), *(proto->blocks[new_block_num].start+3), + *(proto->blocks[new_block_num].start+4), *(proto->blocks[new_block_num].start+5), + *(proto->blocks[new_block_num].start+6), *(proto->blocks[new_block_num].start+7), + *(p-8), *(p-7), *(p-6), *(p-5), *(p-4), *(p-3), *(p-2), *(p-1)); + uint32_t sz = esp_apptrace_membufs_down_buffer_write_nolock(proto, (uint8_t *)(hdr+1), hdr->block_sz); + if (sz != hdr->block_sz) { + ESP_APPTRACE_LOGE("Failed to write %d bytes to down buffer (%d %d)!", hdr->block_sz - sz, hdr->block_sz, sz); + } + hdr->block_sz = 0; + } +#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + // copy pending data to block if any + while (proto->state.markers[new_block_num] < proto->blocks[new_block_num].sz) { + uint32_t read_sz = esp_apptrace_rb_read_size_get(&proto->rb_pend); + if (read_sz == 0) { + break; // no more data in pending buffer + } + if (read_sz > proto->blocks[new_block_num].sz - proto->state.markers[new_block_num]) { + read_sz = proto->blocks[new_block_num].sz - proto->state.markers[new_block_num]; + } + uint8_t *ptr = esp_apptrace_rb_consume(&proto->rb_pend, read_sz); + if (!ptr) { + assert(false && "Failed to consume pended bytes!!"); + break; + } + ESP_APPTRACE_LOGD("Pump %d pend bytes [%x %x %x %x : %x %x %x %x : %x %x %x %x : %x %x...%x %x]", + read_sz, *(ptr+0), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), + *(ptr+5), *(ptr+6), *(ptr+7), *(ptr+8), *(ptr+9), *(ptr+10), *(ptr+11), *(ptr+12), *(ptr+13), *(ptr+read_sz-2), *(ptr+read_sz-1)); + memcpy(proto->blocks[new_block_num].start + proto->state.markers[new_block_num], ptr, read_sz); + proto->state.markers[new_block_num] += read_sz; + } +#endif + proto->hw->swap_end(proto->state.in_block, proto->state.markers[prev_block_num]); + return res; +} + +static esp_err_t esp_apptrace_membufs_swap_waitus(esp_apptrace_membufs_proto_data_t *proto, esp_apptrace_tmo_t *tmo) +{ + int res; + + while ((res = esp_apptrace_membufs_swap(proto)) != ESP_OK) { + res = esp_apptrace_tmo_check(tmo); + if (res != ESP_OK) { + break; + } + } + return res; +} + +uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t *size, esp_apptrace_tmo_t *tmo) +{ + uint8_t *ptr = NULL; + + while (1) { + uint32_t sz = esp_apptrace_rb_read_size_get(&proto->rb_down); + if (sz != 0) { + *size = MIN(*size, sz); + ptr = esp_apptrace_rb_consume(&proto->rb_down, *size); + if (!ptr) { + assert(false && "Failed to consume bytes from down buffer!"); + } + break; + } + // may need to flush + if (proto->hw->host_data_pending()) { + ESP_APPTRACE_LOGD("force flush"); + int res = esp_apptrace_membufs_swap_waitus(proto, tmo); + if (res != ESP_OK) { + ESP_APPTRACE_LOGE("Failed to switch to another block to recv data from host!"); + /*do not return error because data can be in down buffer already*/ + } + } else { + // check tmo only if there is no data from host + int res = esp_apptrace_tmo_check(tmo); + if (res != ESP_OK) { + return NULL; + } + } + } + return ptr; +} + +esp_err_t esp_apptrace_membufs_down_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo) +{ + /* nothing todo */ + return ESP_OK; +} + +static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto, uint8_t *data, uint32_t size) +{ + uint32_t total_sz = 0; + + while (total_sz < size) { + ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", proto->rb_down.wr, proto->rb_down.rd, + proto->rb_down.cur_size, size); + uint32_t wr_sz = esp_apptrace_rb_write_size_get(&proto->rb_down); + if (wr_sz == 0) { + break; + } + + if (wr_sz > size - total_sz) { + wr_sz = size - total_sz; + } + ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz); + uint8_t *ptr = esp_apptrace_rb_produce(&proto->rb_down, wr_sz); + if (!ptr) { + assert(false && "Failed to produce bytes to down buffer!"); + } + ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz); + memcpy(ptr, data + total_sz, wr_sz); + total_sz += wr_sz; + ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz); + } + return total_sz; +} + +static inline uint8_t *esp_apptrace_membufs_wait4buf(esp_apptrace_membufs_proto_data_t *proto, uint16_t size, esp_apptrace_tmo_t *tmo, int *pended) +{ + uint8_t *ptr = NULL; + + int res = esp_apptrace_membufs_swap_waitus(proto, tmo); + if (res != ESP_OK) { + return NULL; + } +#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + // check if we still have pending data + if (esp_apptrace_rb_read_size_get(&proto->rb_pend) > 0) { + // if after block switch we still have pending data (not all pending data have been pumped to block) + // alloc new pending buffer + *pended = 1; + ptr = esp_apptrace_rb_produce(&proto->rb_pend, size); + if (!ptr) { + ESP_APPTRACE_LOGE("Failed to alloc pend buf 1: w-r-s %d-%d-%d!", proto->rb_pend.wr, proto->rb_pend.rd, proto->rb_pend.cur_size); + } + } else +#endif + { + // update block pointers + if (ESP_APPTRACE_INBLOCK_MARKER(proto) + size > ESP_APPTRACE_INBLOCK(proto)->sz) { +#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + *pended = 1; + ptr = esp_apptrace_rb_produce(&proto->rb_pend, size); + if (ptr == NULL) { + ESP_APPTRACE_LOGE("Failed to alloc pend buf 2: w-r-s %d-%d-%d!", proto->rb_pend.wr, proto->rb_pend.rd, proto->rb_pend.cur_size); + } +#endif + } else { + *pended = 0; + ptr = ESP_APPTRACE_INBLOCK(proto)->start + ESP_APPTRACE_INBLOCK_MARKER(proto); + } + } + + return ptr; +} + +static inline uint8_t *esp_apptrace_membufs_pkt_start(uint8_t *ptr, uint16_t size) +{ + // it is safe to use cpu_hal_get_core_id() in macro call because arg is used only once inside it + ((esp_tracedata_hdr_t *)ptr)->block_sz = ESP_APPTRACE_USR_BLOCK_CORE(cpu_hal_get_core_id()) | size; + ((esp_tracedata_hdr_t *)ptr)->wr_sz = 0; + return ptr + sizeof(esp_tracedata_hdr_t); +} + +static inline void esp_apptrace_membufs_pkt_end(uint8_t *ptr) +{ + esp_tracedata_hdr_t *hdr = (esp_tracedata_hdr_t *)(ptr - sizeof(esp_tracedata_hdr_t)); + // update written size + hdr->wr_sz = hdr->block_sz; +} + +uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t size, esp_apptrace_tmo_t *tmo) +{ + uint8_t *buf_ptr = NULL; + + if (size > ESP_APPTRACE_USR_DATA_LEN_MAX(proto)) { + ESP_APPTRACE_LOGE("Too large user data size %d!", size); + return NULL; + } + + // check for data in the pending buffer +#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + if (esp_apptrace_rb_read_size_get(&proto->rb_pend) > 0) { + // if we have buffered data try to switch block + esp_apptrace_membufs_swap(proto); + // if switch was successful, part or all pended data have been copied to block + } + if (esp_apptrace_rb_read_size_get(&proto->rb_pend) > 0) { + // if we have buffered data alloc new pending buffer + ESP_APPTRACE_LOGD("Get %d bytes from PEND buffer", size); + buf_ptr = esp_apptrace_rb_produce(&proto->rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); + if (buf_ptr == NULL) { + int pended_buf; + buf_ptr = esp_apptrace_membufs_wait4buf(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf); + if (buf_ptr && !pended_buf) { + ESP_APPTRACE_LOGD("Get %d bytes from block", size); + // update cur block marker + ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); + } + } + } else { +#else + if (1) { +#endif + if (ESP_APPTRACE_INBLOCK_MARKER(proto) + ESP_APPTRACE_USR_BLOCK_RAW_SZ(size) > ESP_APPTRACE_INBLOCK(proto)->sz) { + #if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + ESP_APPTRACE_LOGD("Block full. Get %d bytes from PEND buffer", size); + buf_ptr = esp_apptrace_rb_produce(&proto->rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); + #endif + if (buf_ptr == NULL) { + int pended_buf; + ESP_APPTRACE_LOGD(" full. Get %d bytes from pend buffer", size); + buf_ptr = esp_apptrace_membufs_wait4buf(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf); + if (buf_ptr && !pended_buf) { + ESP_APPTRACE_LOGD("Got %d bytes from block", size); + // update cur block marker + ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); + } + } + } else { + ESP_APPTRACE_LOGD("Get %d bytes from buffer", size); + // fit to curr nlock + buf_ptr = ESP_APPTRACE_INBLOCK(proto)->start + ESP_APPTRACE_INBLOCK_MARKER(proto); + // update cur block marker + ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size)); + } + } + if (buf_ptr) { + buf_ptr = esp_apptrace_membufs_pkt_start(buf_ptr, size); + } + + return buf_ptr; +} + +esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo) +{ + esp_apptrace_membufs_pkt_end(ptr); + // TODO: mark block as busy in order not to re-use it for other tracing calls until it is completely written + // TODO: avoid potential situation when all memory is consumed by low prio tasks which can not complete writing due to + // higher prio tasks and the latter can not allocate buffers at all + // this is abnormal situation can be detected on host which will receive only uncompleted buffers + // workaround: use own memcpy which will kick-off dead tracing calls + return ESP_OK; +} + +esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *proto, uint32_t min_sz, esp_apptrace_tmo_t *tmo) +{ + int res = ESP_OK; + + if (ESP_APPTRACE_INBLOCK_MARKER(proto) < min_sz) { + ESP_APPTRACE_LOGI("Ignore flush request for min %d bytes. Bytes in block: %d.", min_sz, ESP_APPTRACE_INBLOCK_MARKER(proto)); + return ESP_OK; + } + // switch block while size of data (including that in pending buffer) is more than min size + while (ESP_APPTRACE_INBLOCK_MARKER(proto) > min_sz) { + ESP_APPTRACE_LOGD("Try to flush %d bytes. Wait until block switch for %lld us", ESP_APPTRACE_INBLOCK_MARKER(proto), tmo->tmo); + res = esp_apptrace_membufs_swap_waitus(proto, tmo); + if (res != ESP_OK) { + if (tmo->tmo != ESP_APPTRACE_TMO_INFINITE) + ESP_APPTRACE_LOGW("Failed to switch to another block in %lld us!", tmo->tmo); + else + ESP_APPTRACE_LOGE("Failed to switch to another block in %lld us!", tmo->tmo); + return res; + } + } + + return res; +} diff --git a/components/app_trace/app_trace_util.c b/components/app_trace/app_trace_util.c index 4fe94de89ef1..d71114f4aaa0 100644 --- a/components/app_trace/app_trace_util.c +++ b/components/app_trace/app_trace_util.c @@ -16,33 +16,42 @@ #include "freertos/task.h" #include "esp_app_trace_util.h" #include "sdkconfig.h" -#if CONFIG_IDF_TARGET_ESP32 -#include "esp32/clk.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/clk.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/clk.h" -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/clk.h" + +/////////////////////////////////////////////////////////////////////////////// +///////////////////////////////// Locks ///////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#if ESP_APPTRACE_PRINT_LOCK +static esp_apptrace_lock_t s_log_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED}; +#endif + +int esp_apptrace_log_lock(void) +{ +#if ESP_APPTRACE_PRINT_LOCK + esp_apptrace_tmo_t tmo; + esp_apptrace_tmo_init(&tmo, ESP_APPTRACE_TMO_INFINITE); + int ret = esp_apptrace_lock_take(&s_log_lock, &tmo); + return ret; +#else + return 0; #endif +} + +void esp_apptrace_log_unlock(void) +{ + #if ESP_APPTRACE_PRINT_LOCK + esp_apptrace_lock_give(&s_log_lock); +#endif +} /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// TIMEOUT ///////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -#define ESP_APPTRACE_CPUTICKS2US(_t_, _cpu_freq_) ((_t_)/(_cpu_freq_/1000000)) -#define ESP_APPTRACE_US2CPUTICKS(_t_, _cpu_freq_) ((_t_)*(_cpu_freq_/1000000)) - esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo) { - int cpu_freq = esp_clk_cpu_freq(); - if (tmo->tmo != ESP_APPTRACE_TMO_INFINITE) { - unsigned cur = portGET_RUN_TIME_COUNTER_VALUE(); - if (tmo->start <= cur) { - tmo->elapsed = ESP_APPTRACE_CPUTICKS2US(cur - tmo->start, cpu_freq); - } else { - tmo->elapsed = ESP_APPTRACE_CPUTICKS2US(0xFFFFFFFF - tmo->start + cur, cpu_freq); - } + if (tmo->tmo != (int64_t)-1) { + tmo->elapsed = esp_timer_get_time() - tmo->start; if (tmo->elapsed >= tmo->tmo) { return ESP_ERR_TIMEOUT; } diff --git a/components/app_trace/component.mk b/components/app_trace/component.mk index 5dd08322d3dd..8caf746e7272 100644 --- a/components/app_trace/component.mk +++ b/components/app_trace/component.mk @@ -4,11 +4,19 @@ COMPONENT_SRCDIRS := . +ifdef CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE +COMPONENT_SRCDIRS += port/xtensa +endif + COMPONENT_ADD_INCLUDEDIRS = include +COMPONENT_PRIV_INCLUDEDIRS = private_include \ + port/include + COMPONENT_ADD_LDFLAGS = -lapp_trace -ifdef CONFIG_SYSVIEW_ENABLE +ifdef CONFIG_APPTRACE_SV_ENABLE + COMPONENT_ADD_INCLUDEDIRS += \ sys_view/Config \ sys_view/SEGGER \ @@ -19,7 +27,7 @@ COMPONENT_SRCDIRS += \ sys_view/SEGGER \ sys_view/Sample/OS \ sys_view/Sample/Config \ - sys_view/esp32 \ + sys_view/esp \ sys_view/ext else ifdef CONFIG_APPTRACE_GCOV_ENABLE diff --git a/components/app_trace/heap_trace_tohost.c b/components/app_trace/heap_trace_tohost.c index d1d2495571a4..a7040961c72e 100644 --- a/components/app_trace/heap_trace_tohost.c +++ b/components/app_trace/heap_trace_tohost.c @@ -17,7 +17,7 @@ #include "esp_heap_trace.h" #undef HEAP_TRACE_SRCFILE -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE #include "esp_app_trace.h" #include "esp_sysview_trace.h" #endif @@ -26,7 +26,7 @@ #ifdef CONFIG_HEAP_TRACING_TOHOST -#if !CONFIG_SYSVIEW_ENABLE +#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 @@ -42,7 +42,7 @@ esp_err_t heap_trace_init_tohost(void) esp_err_t heap_trace_start(heap_trace_mode_t mode_param) { -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE esp_err_t ret = esp_sysview_heap_trace_start((uint32_t)-1); if (ret != ESP_OK) { return ret; @@ -55,7 +55,7 @@ esp_err_t heap_trace_start(heap_trace_mode_t mode_param) esp_err_t heap_trace_stop(void) { esp_err_t ret = ESP_ERR_NOT_SUPPORTED; -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE ret = esp_sysview_heap_trace_stop(); #endif s_tracing = false; @@ -88,7 +88,7 @@ static IRAM_ATTR void record_allocation(const heap_trace_record_t *record) if (!s_tracing) { return; } -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE esp_sysview_heap_trace_alloc(record->address, record->size, record->alloced_by); #endif } @@ -103,7 +103,7 @@ static IRAM_ATTR void record_free(void *p, void **callers) if (!s_tracing) { return; } -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE esp_sysview_heap_trace_free(p, callers); #endif } diff --git a/components/app_trace/include/esp_app_trace.h b/components/app_trace/include/esp_app_trace.h index b8374ae0e9a2..20a3756242ce 100644 --- a/components/app_trace/include/esp_app_trace.h +++ b/components/app_trace/include/esp_app_trace.h @@ -26,8 +26,11 @@ extern "C" { * Application trace data destinations bits. */ typedef enum { - ESP_APPTRACE_DEST_TRAX = 0x1, ///< JTAG destination - ESP_APPTRACE_DEST_UART0 = 0x2, ///< UART destination + ESP_APPTRACE_DEST_JTAG = 1, ///< JTAG destination + ESP_APPTRACE_DEST_TRAX = ESP_APPTRACE_DEST_JTAG, ///< xxx_TRAX name is obsolete, use more common xxx_JTAG + ESP_APPTRACE_DEST_UART0, ///< UART0 destination + ESP_APPTRACE_DEST_MAX = ESP_APPTRACE_DEST_UART0, + ESP_APPTRACE_DEST_NUM } esp_apptrace_dest_t; /** diff --git a/components/app_trace/include/esp_app_trace_util.h b/components/app_trace/include/esp_app_trace_util.h index 57c4f94fb996..2cdadb19ba81 100644 --- a/components/app_trace/include/esp_app_trace_util.h +++ b/components/app_trace/include/esp_app_trace_util.h @@ -20,6 +20,7 @@ extern "C" { #include "freertos/FreeRTOS.h" #include "esp_err.h" +#include "esp_timer.h" /** Infinite waiting timeout */ #define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1) @@ -30,9 +31,9 @@ extern "C" { * periodically to check timeout for expiration. */ typedef struct { - uint32_t start; ///< time interval start (in CPU ticks) - uint32_t tmo; ///< timeout value (in us) - uint32_t elapsed; ///< elapsed time (in us) + int64_t start; ///< time interval start (in us) + int64_t tmo; ///< timeout value (in us) + int64_t elapsed; ///< elapsed time (in us) } esp_apptrace_tmo_t; /** @@ -43,23 +44,23 @@ typedef struct { */ static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo) { - tmo->start = portGET_RUN_TIME_COUNTER_VALUE(); - tmo->tmo = user_tmo; + tmo->start = esp_timer_get_time(); + tmo->tmo = user_tmo == ESP_APPTRACE_TMO_INFINITE ? (int64_t)-1 : (int64_t)user_tmo; tmo->elapsed = 0; } /** * @brief Checks timeout for expiration. * - * @param tmo Pointer to timeout structure to be initialized. + * @param tmo Pointer to timeout structure. * - * @return ESP_OK on success, otherwise \see esp_err_t + * @return number of remaining us till tmo. */ esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo); static inline uint32_t esp_apptrace_tmo_remaining_us(esp_apptrace_tmo_t *tmo) { - return tmo->tmo != ESP_APPTRACE_TMO_INFINITE ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE; + return tmo->tmo != (int64_t)-1 ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE; } /** Tracing module synchronization lock */ @@ -168,6 +169,30 @@ uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb); */ uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb); +int esp_apptrace_log_lock(void); +void esp_apptrace_log_unlock(void); + +#define ESP_APPTRACE_LOG( format, ... ) \ + do { \ + esp_apptrace_log_lock(); \ + esp_rom_printf(format, ##__VA_ARGS__); \ + esp_apptrace_log_unlock(); \ + } while(0) + +#define ESP_APPTRACE_LOG_LEV( _L_, level, format, ... ) \ + do { \ + if (LOG_LOCAL_LEVEL >= level) { \ + ESP_APPTRACE_LOG(LOG_FORMAT(_L_, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); \ + } \ + } while(0) + +#define ESP_APPTRACE_LOGE( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_ERROR, format, ##__VA_ARGS__) +#define ESP_APPTRACE_LOGW( format, ... ) ESP_APPTRACE_LOG_LEV(W, ESP_LOG_WARN, format, ##__VA_ARGS__) +#define ESP_APPTRACE_LOGI( format, ... ) ESP_APPTRACE_LOG_LEV(I, ESP_LOG_INFO, format, ##__VA_ARGS__) +#define ESP_APPTRACE_LOGD( format, ... ) ESP_APPTRACE_LOG_LEV(D, ESP_LOG_DEBUG, format, ##__VA_ARGS__) +#define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__) +#define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__) + #ifdef __cplusplus } #endif diff --git a/components/app_trace/include/esp_sysview_trace.h b/components/app_trace/include/esp_sysview_trace.h index 7a1bd5fd2222..a44b7a6f9348 100644 --- a/components/app_trace/include/esp_sysview_trace.h +++ b/components/app_trace/include/esp_sysview_trace.h @@ -20,7 +20,7 @@ extern "C" { #include #include "esp_err.h" -#include "SEGGER_RTT.h" // SEGGER_RTT_ESP32_Flush +#include "SEGGER_RTT.h" // SEGGER_RTT_ESP_Flush #include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE /** @@ -32,7 +32,7 @@ extern "C" { */ static inline esp_err_t esp_sysview_flush(uint32_t tmo) { - SEGGER_RTT_ESP32_Flush(0, tmo); + SEGGER_RTT_ESP_Flush(0, tmo); return ESP_OK; } diff --git a/components/app_trace/linker.lf b/components/app_trace/linker.lf index c3d2aecc1bfd..3358ce10beae 100644 --- a/components/app_trace/linker.lf +++ b/components/app_trace/linker.lf @@ -3,17 +3,17 @@ archive: libapp_trace.a entries: app_trace (noflash) app_trace_util (noflash) - if SYSVIEW_ENABLE = y: + if APPTRACE_SV_ENABLE = y: SEGGER_SYSVIEW (noflash) - SEGGER_RTT_esp32 (noflash) + SEGGER_RTT_esp (noflash) SEGGER_SYSVIEW_Config_FreeRTOS (noflash) SEGGER_SYSVIEW_FreeRTOS (noflash) [mapping:app_trace_driver] archive: libdriver.a entries: - if SYSVIEW_TS_SOURCE_TIMER_00 = y || SYSVIEW_TS_SOURCE_TIMER_01 = y - || SYSVIEW_TS_SOURCE_TIMER_10 = y || SYSVIEW_TS_SOURCE_TIMER_11 = y: + if APPTRACE_SV_TS_SOURCE_TIMER_00 = y || APPTRACE_SV_TS_SOURCE_TIMER_01 = y + || APPTRACE_SV_TS_SOURCE_TIMER_10 = y || APPTRACE_SV_TS_SOURCE_TIMER_11 = y: timer (noflash) else: * (default) diff --git a/components/app_trace/port/include/esp_app_trace_port.h b/components/app_trace/port/include/esp_app_trace_port.h new file mode 100644 index 000000000000..a463105e7a85 --- /dev/null +++ b/components/app_trace/port/include/esp_app_trace_port.h @@ -0,0 +1,43 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef ESP_APP_TRACE_PORT_H_ +#define ESP_APP_TRACE_PORT_H_ + +#include "esp_app_trace_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Apptrace HW interface. */ +typedef struct { + esp_err_t (*init)(void *hw_data); + uint8_t *(*get_up_buffer)(void *hw_data, uint32_t, esp_apptrace_tmo_t *); + esp_err_t (*put_up_buffer)(void *hw_data, uint8_t *, esp_apptrace_tmo_t *); + esp_err_t (*flush_up_buffer_nolock)(void *hw_data, uint32_t, esp_apptrace_tmo_t *); + esp_err_t (*flush_up_buffer)(void *hw_data, esp_apptrace_tmo_t *); + void (*down_buffer_config)(void *hw_data, uint8_t *buf, uint32_t size); + uint8_t *(*get_down_buffer)(void *hw_data, uint32_t *, esp_apptrace_tmo_t *); + esp_err_t (*put_down_buffer)(void *hw_data, uint8_t *, esp_apptrace_tmo_t *); + bool (*host_is_connected)(void *hw_data); +} esp_apptrace_hw_t; + +esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data); +esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/app_trace/port/riscv/port.c b/components/app_trace/port/riscv/port.c new file mode 100644 index 000000000000..119154ded5b4 --- /dev/null +++ b/components/app_trace/port/riscv/port.c @@ -0,0 +1,374 @@ +#include "esp_log.h" +#include "esp_app_trace_membufs_proto.h" +#include "esp_app_trace_port.h" + +/** RISCV HW transport data */ +typedef struct { + uint8_t inited; // initialization state flags for every core +#if CONFIG_APPTRACE_LOCK_ENABLE + esp_apptrace_lock_t lock; // sync lock +#endif + esp_apptrace_membufs_proto_data_t membufs; +} esp_apptrace_riscv_data_t; + +/** RISCV memory host iface control block */ +typedef struct { + uint32_t ctrl; + // - Guard field. If this register is not zero then CPU is changing this struct and + // this guard field holds address of the instruction which application will execute when CPU finishes with those modifications. + uint32_t stat; + esp_apptrace_mem_block_t * mem_blocks; +} esp_apptrace_riscv_ctrl_block_t; + +#define RISCV_APPTRACE_SYSNR 0x64 + +#define ESP_APPTRACE_RISCV_BLOCK_LEN_MSK 0x7FFFUL +#define ESP_APPTRACE_RISCV_BLOCK_LEN(_l_) ((_l_) & ESP_APPTRACE_RISCV_BLOCK_LEN_MSK) +#define ESP_APPTRACE_RISCV_BLOCK_LEN_GET(_v_) ((_v_) & ESP_APPTRACE_RISCV_BLOCK_LEN_MSK) +#define ESP_APPTRACE_RISCV_BLOCK_ID_MSK 0x7FUL +#define ESP_APPTRACE_RISCV_BLOCK_ID(_id_) (((_id_) & ESP_APPTRACE_RISCV_BLOCK_ID_MSK) << 15) +#define ESP_APPTRACE_RISCV_BLOCK_ID_GET(_v_) (((_v_) >> 15) & ESP_APPTRACE_RISCV_BLOCK_ID_MSK) +#define ESP_APPTRACE_RISCV_HOST_DATA (1 << 22) +#define ESP_APPTRACE_RISCV_HOST_CONNECT (1 << 23) + +#define ESP_APPTRACE_RISCV_INITED(_hw_) ((_hw_)->inited & (1 << 0/*cpu_hal_get_core_id()*/)) + +static esp_err_t esp_apptrace_riscv_init(esp_apptrace_riscv_data_t *hw_data); +static esp_err_t esp_apptrace_riscv_flush(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo); +static esp_err_t esp_apptrace_riscv_flush_nolock(esp_apptrace_riscv_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo); +static uint8_t *esp_apptrace_riscv_up_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo); +static esp_err_t esp_apptrace_riscv_up_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo); +static void esp_apptrace_riscv_down_buffer_config(esp_apptrace_riscv_data_t *hw_data, uint8_t *buf, uint32_t size); +static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo); +static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo); +static bool esp_apptrace_riscv_host_is_connected(esp_apptrace_riscv_data_t *hw_data); +static esp_err_t esp_apptrace_riscv_buffer_swap_start(uint32_t curr_block_id); +static esp_err_t esp_apptrace_riscv_buffer_swap(uint32_t new_block_id); +static esp_err_t esp_apptrace_riscv_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len); +static bool esp_apptrace_riscv_host_data_pending(void); + + +const static char *TAG = "esp_apptrace"; + +static esp_apptrace_riscv_ctrl_block_t s_tracing_ctrl[portNUM_PROCESSORS]; + +esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data) +{ + return NULL; +} + +esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data) +{ +#if CONFIG_APPTRACE_DEST_JTAG + static esp_apptrace_membufs_proto_hw_t s_trace_proto_hw = { + .swap_start = esp_apptrace_riscv_buffer_swap_start, + .swap = esp_apptrace_riscv_buffer_swap, + .swap_end = esp_apptrace_riscv_buffer_swap_end, + .host_data_pending = esp_apptrace_riscv_host_data_pending, + }; + static esp_apptrace_riscv_data_t s_trace_hw_data = { + .membufs = { + .hw = &s_trace_proto_hw, + }, + }; + static esp_apptrace_hw_t s_trace_hw = { + .init = (esp_err_t (*)(void *))esp_apptrace_riscv_init, + .get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_get, + .put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_put, + .flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush_nolock, + .flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush, + .down_buffer_config = (void (*)(void *, uint8_t *, uint32_t ))esp_apptrace_riscv_down_buffer_config, + .get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_get, + .put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_put, + .host_is_connected = (bool (*)(void *))esp_apptrace_riscv_host_is_connected, + }; + *data = &s_trace_hw_data; + return &s_trace_hw; +#else + return NULL; +#endif +} + +/* Advertises apptrace control block address to host. + This function can be overriden with custom implementation, + e.g. OpenOCD flasher stub use own implementation of it. */ +__attribute__((weak)) int esp_apptrace_advertise_ctrl_block(void *ctrl_block_addr) +{ + register int sys_nr = RISCV_APPTRACE_SYSNR; + register int host_ret = 0; + + if (!esp_cpu_in_ocd_debug_mode()) { + return 0; + } + __asm__ volatile ( \ + ".option push\n" \ + ".option norvc\n" \ + "mv a0, %[sys_nr]\n" \ + "mv a1, %[arg1]\n" \ + "slli zero,zero,0x1f\n" \ + "ebreak\n" \ + "srai zero,zero,0x7\n" \ + "mv %[host_ret], a0\n" \ + ".option pop\n" \ + :[host_ret]"=r"(host_ret) + :[sys_nr]"r"(sys_nr),[arg1]"r"(ctrl_block_addr):"a0","a1"); + return host_ret; +} + +/* Returns up buffers config. + This function can be overriden with custom implementation, + e.g. OpenOCD flasher stub use own implementation of it. */ +__attribute__((weak)) void esp_apptrace_get_up_buffers(esp_apptrace_mem_block_t mem_blocks_cfg[2]) +{ + static uint8_t s_mem_blocks[2][CONFIG_APPTRACE_BUF_SIZE]; + + mem_blocks_cfg[0].start = s_mem_blocks[0]; + mem_blocks_cfg[0].sz = CONFIG_APPTRACE_BUF_SIZE; + mem_blocks_cfg[1].start = s_mem_blocks[1]; + mem_blocks_cfg[1].sz = CONFIG_APPTRACE_BUF_SIZE; +} + +static esp_err_t esp_apptrace_riscv_lock(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo) +{ +#if CONFIG_APPTRACE_LOCK_ENABLE + esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo); + if (ret != ESP_OK) { + return ESP_FAIL; + } +#endif + return ESP_OK; +} + +static esp_err_t esp_apptrace_riscv_unlock(esp_apptrace_riscv_data_t *hw_data) +{ + esp_err_t ret = ESP_OK; +#if CONFIG_APPTRACE_LOCK_ENABLE + ret = esp_apptrace_lock_give(&hw_data->lock); +#endif + return ret; +} + +/*****************************************************************************************/ +/***************************** Apptrace HW iface *****************************************/ +/*****************************************************************************************/ + +static esp_err_t esp_apptrace_riscv_init(esp_apptrace_riscv_data_t *hw_data) +{ + int core_id = cpu_hal_get_core_id(); + + if (hw_data->inited == 0) { + esp_apptrace_mem_block_t mem_blocks_cfg[2]; + esp_apptrace_get_up_buffers(mem_blocks_cfg); + esp_err_t res = esp_apptrace_membufs_init(&hw_data->membufs, mem_blocks_cfg); + if (res != ESP_OK) { + ESP_APPTRACE_LOGE("Failed to init membufs proto (%d)!", res); + return res; + } +#if CONFIG_APPTRACE_LOCK_ENABLE + esp_apptrace_lock_init(&hw_data->lock); +#endif + } + hw_data->inited |= 1 << core_id; + ESP_APPTRACE_LOGI("Apptrace initialized on CPU%d. Tracing control block @ %p.", core_id, &s_tracing_ctrl[core_id]); + s_tracing_ctrl[core_id].mem_blocks = hw_data->membufs.blocks; + for (int i = 0; i < 2; i++) { + ESP_APPTRACE_LOGD("Mem buf[%d] %d bytes @ %p (%p/%p)", i, + s_tracing_ctrl[core_id].mem_blocks[i].sz, s_tracing_ctrl[core_id].mem_blocks[i].start, + &(s_tracing_ctrl[core_id].mem_blocks[i].start), &(s_tracing_ctrl[core_id].mem_blocks[i].sz)); + } + // notify host about control block address + int res = esp_apptrace_advertise_ctrl_block(&s_tracing_ctrl[core_id]); + assert(res == 0 && "Falied to send config to host!"); + + return ESP_OK; +} + +static uint8_t *esp_apptrace_riscv_up_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo) +{ + uint8_t *ptr; + + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return NULL; + } + esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo); + if (res != ESP_OK) { + return NULL; + } + + ptr = esp_apptrace_membufs_up_buffer_get(&hw_data->membufs, size, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + } + return ptr; +} + +static esp_err_t esp_apptrace_riscv_up_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + // Can avoid locking because esp_apptrace_membufs_up_buffer_put() just modifies buffer's header + esp_err_t res = esp_apptrace_membufs_up_buffer_put(&hw_data->membufs, ptr, tmo); + return res; +} + +static void esp_apptrace_riscv_down_buffer_config(esp_apptrace_riscv_data_t *hw_data, uint8_t *buf, uint32_t size) +{ + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return; + } + esp_apptrace_membufs_down_buffer_config(&hw_data->membufs, buf, size); +} + +static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo) +{ + uint8_t *ptr; + + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return NULL; + } + esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo); + if (res != ESP_OK) { + return NULL; + } + + ptr = esp_apptrace_membufs_down_buffer_get(&hw_data->membufs, size, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + } + return ptr; +} + +static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + // Can avoid locking because esp_apptrace_membufs_down_buffer_put() does nothing + /*esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo); + if (res != ESP_OK) { + return res; + }*/ + + esp_err_t res = esp_apptrace_membufs_down_buffer_put(&hw_data->membufs, ptr, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + /*if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + }*/ + return res; +} + +static bool esp_apptrace_riscv_host_is_connected(esp_apptrace_riscv_data_t *hw_data) +{ + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return false; + } + return s_tracing_ctrl[cpu_hal_get_core_id()].ctrl & ESP_APPTRACE_RISCV_HOST_CONNECT ? true : false; +} + +static esp_err_t esp_apptrace_riscv_flush_nolock(esp_apptrace_riscv_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + return esp_apptrace_membufs_flush_nolock(&hw_data->membufs, min_sz, tmo); +} + +static esp_err_t esp_apptrace_riscv_flush(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_RISCV_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo); + if (res != ESP_OK) { + return res; + } + + res = esp_apptrace_membufs_flush_nolock(&hw_data->membufs, 0, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + } + return res; +} + +/*****************************************************************************************/ +/************************** Membufs proto HW iface ***************************************/ +/*****************************************************************************************/ + +static inline void esp_apptrace_riscv_buffer_swap_lock(void) +{ + extern uint32_t __esp_apptrace_riscv_updated; + + // indicate to host that we are about to update. + // this is used only to place CPU into streaming mode at tracing startup + // before starting streaming host can halt us after we read ESP_APPTRACE_RISCV_CTRL_REG and before we updated it + // HACK: in this case host will set breakpoint just after ESP_APPTRACE_RISCV_CTRL_REG update, + // here we set address to set bp at + // enter ERI update critical section + s_tracing_ctrl[cpu_hal_get_core_id()].stat = (uint32_t)&__esp_apptrace_riscv_updated; +} + +static __attribute__((noinline)) void esp_apptrace_riscv_buffer_swap_unlock(void) +{ + // exit ERI update critical section + s_tracing_ctrl[cpu_hal_get_core_id()].stat = 0; + // TODO: currently host sets breakpoint, use break instruction to stop; + // it will allow to use ESP_APPTRACE_RISCV_STAT_REG for other purposes + asm volatile ( + " .global __esp_apptrace_riscv_updated\n" + "__esp_apptrace_riscv_updated:\n"); // host will set bp here to resolve collision at streaming start +} + +static esp_err_t esp_apptrace_riscv_buffer_swap_start(uint32_t curr_block_id) +{ + esp_err_t res = ESP_OK; + + esp_apptrace_riscv_buffer_swap_lock(); + + uint32_t ctrl_reg = s_tracing_ctrl[cpu_hal_get_core_id()].ctrl; + uint32_t host_connected = ESP_APPTRACE_RISCV_HOST_CONNECT & ctrl_reg; + if (host_connected) { + uint32_t acked_block = ESP_APPTRACE_RISCV_BLOCK_ID_GET(ctrl_reg); + uint32_t host_to_read = ESP_APPTRACE_RISCV_BLOCK_LEN_GET(ctrl_reg); + if (host_to_read != 0 || acked_block != (curr_block_id & ESP_APPTRACE_RISCV_BLOCK_ID_MSK)) { + ESP_APPTRACE_LOGD("[%d]: Can not switch %x %d %x %x/%lx", cpu_hal_get_core_id(), ctrl_reg, host_to_read, acked_block, + curr_block_id & ESP_APPTRACE_RISCV_BLOCK_ID_MSK, curr_block_id); + res = ESP_ERR_NO_MEM; + goto _on_err; + } + } + return ESP_OK; +_on_err: + esp_apptrace_riscv_buffer_swap_unlock(); + return res; +} + +static esp_err_t esp_apptrace_riscv_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len) +{ + uint32_t ctrl_reg = s_tracing_ctrl[cpu_hal_get_core_id()].ctrl; + uint32_t host_connected = ESP_APPTRACE_RISCV_HOST_CONNECT & ctrl_reg; + s_tracing_ctrl[cpu_hal_get_core_id()].ctrl = ESP_APPTRACE_RISCV_BLOCK_ID(new_block_id) | + host_connected | ESP_APPTRACE_RISCV_BLOCK_LEN(prev_block_len); + esp_apptrace_riscv_buffer_swap_unlock(); + return ESP_OK; +} + +static esp_err_t esp_apptrace_riscv_buffer_swap(uint32_t new_block_id) +{ + /* do nothing */ + return ESP_OK; +} + +static bool esp_apptrace_riscv_host_data_pending(void) +{ + uint32_t ctrl_reg = s_tracing_ctrl[cpu_hal_get_core_id()].ctrl; + // ESP_APPTRACE_LOGV("%s() 0x%x", __func__, ctrl_reg); + return (ctrl_reg & ESP_APPTRACE_RISCV_HOST_DATA) ? true : false; +} diff --git a/components/app_trace/port/xtensa/port.c b/components/app_trace/port/xtensa/port.c new file mode 100644 index 000000000000..b0dcaa1b2127 --- /dev/null +++ b/components/app_trace/port/xtensa/port.c @@ -0,0 +1,543 @@ +// +// How It Works +// ************ + +// 1. Components Overview +// ====================== + +// Xtensa has useful feature: TRAX debug module. It allows recording program execution flow at run-time without disturbing CPU. +// Exectution flow data are written to configurable Trace RAM block. Besides accessing Trace RAM itself TRAX module also allows to read/write +// trace memory via its registers by means of JTAG, APB or ERI transactions. +// ESP32 has two Xtensa cores with separate TRAX modules on them and provides two special memory regions to be used as trace memory. +// Chip allows muxing access to those trace memory blocks in such a way that while one block is accessed by CPUs another one can be accessed by host +// by means of reading/writing TRAX registers via JTAG. Blocks muxing is configurable at run-time and allows switching trace memory blocks between +// accessors in round-robin fashion so they can read/write separate memory blocks without disturbing each other. +// This module implements application tracing feature based on above mechanisms. It allows to transfer arbitrary user data to/from +// host via JTAG with minimal impact on system performance. This module is implied to be used in the following tracing scheme. + +// ------>------ ----- (host components) ----- +// | | | | +// ------------------- ----------------------- ----------------------- ---------------- ------ --------- ----------------- +// |trace data source|-->|target tracing module|<--->|TRAX_MEM0 | TRAX_MEM1|---->|TRAX_DATA_REGS|<-->|JTAG|<--->|OpenOCD|-->|trace data sink| +// ------------------- ----------------------- ----------------------- ---------------- ------ --------- ----------------- +// | | | | +// | ------<------ ---------------- | +// |<------------------------------------------->|TRAX_CTRL_REGS|<---->| +// ---------------- + +// In general tracing goes in the following way. User application requests tracing module to send some data by calling esp_apptrace_buffer_get(), +// module allocates necessary buffer in current input trace block. Then user fills received buffer with data and calls esp_apptrace_buffer_put(). +// When current input trace block is filled with app data it is exposed to host and the second block becomes input one and buffer filling restarts. +// While target application fills one TRAX block host reads another one via JTAG. +// This module also allows communication in the opposite direction: from host to target. As it was said ESP32 and host can access different TRAX blocks +// simultaneously, so while target writes trace data to one block host can write its own data (e.g. tracing commands) to another one then when +// blocks are switched host receives trace data and target receives data written by host application. Target user application can read host data +// by calling esp_apptrace_read() API. +// To control buffer switching and for other communication purposes this implementation uses some TRAX registers. It is safe since HW TRAX tracing +// can not be used along with application tracing feature so these registers are freely readable/writeable via JTAG from host and via ERI from ESP32 cores. +// Overhead of this implementation on target CPU is produced only by allocating/managing buffers and copying of data. +// On the host side special OpenOCD command must be used to read trace data. + +// 2. TRAX Registers layout +// ======================== + +// This module uses two TRAX HW registers to communicate with host SW (OpenOCD). +// - Control register uses TRAX_DELAYCNT as storage. Only lower 24 bits of TRAX_DELAYCNT are writable. Control register has the following bitfields: +// | 31..XXXXXX..24 | 23 .(host_connect). 23| 22..(block_id)..15 | 14..(block_len)..0 | +// 14..0 bits - actual length of user data in trace memory block. Target updates it every time it fills memory block and exposes it to host. +// Host writes zero to this field when it finishes reading exposed block; +// 21..15 bits - trace memory block transfer ID. Block counter. It can overflow. Updated by target, host should not modify it. Actually can be 2 bits; +// 22 bit - 'host data present' flag. If set to one there is data from host, otherwise - no host data; +// 23 bit - 'host connected' flag. If zero then host is not connected and tracing module works in post-mortem mode, otherwise in streaming mode; +// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then current CPU is changing TRAX registers and +// this register holds address of the instruction which application will execute when it finishes with those registers modifications. +// See 'Targets Connection' setion for details. + +// 3. Modes of operation +// ===================== + +// This module supports two modes of operation: +// - Post-mortem mode. This is the default mode. In this mode application tracing module does not check whether host has read all the data from block +// exposed to it and switches block in any case. The mode does not need host interaction for operation and so can be useful when only the latest +// trace data are necessary, e.g. for analyzing crashes. On panic the latest data from current input block are exposed to host and host can read them. +// It can happen that system panic occurs when there are very small amount of data which are not exposed to host yet (e.g. crash just after the +// TRAX block switch). In this case the previous 16KB of collected data will be dropped and host will see the latest, but very small piece of trace. +// It can be insufficient to diagnose the problem. To avoid such situations there is menuconfig option +// CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH +// which controls the threshold for flushing data in case of panic. +// - Streaming mode. Tracing module enters this mode when host connects to target and sets respective bits in control registers (per core). +// In this mode before switching the block tracing module waits for the host to read all the data from the previously exposed block. +// On panic tracing module also waits (timeout is configured via menuconfig via CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO) for the host to read all data. + +// 4. Communication Protocol +// ========================= + +// 4.1 Trace Memory Blocks +// ----------------------- + +// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data available. +// When current input memory block is filled it is exposed to host and 'block_len' and 'block_id' fields are updated in the control register. +// Host reads new register value and according to it's value starts reading data from exposed block. Meanwhile target starts filling another trace block. +// When host finishes reading the block it clears 'block_len' field in control register indicating to the target that it is ready to accept the next one. +// If the host has some data to transfer to the target it writes them to trace memory block before clearing 'block_len' field. Then it sets +// 'host_data_present' bit and clears 'block_len' field in control register. Upon every block switch target checks 'host_data_present' bit and if it is set +// reads them to down buffer before writing any trace data to switched TRAX block. + +// 4.2 User Data Chunks Level +// -------------------------- + +// Since trace memory block is shared between user data chunks and data copying is performed on behalf of the API user (in its normal context) in +// multithreading environment it can happen that task/ISR which copies data is preempted by another high prio task/ISR. So it is possible situation +// that task/ISR will fail to complete filling its data chunk before the whole trace block is exposed to the host. To handle such conditions tracing +// module prepends all user data chunks with header which contains allocated buffer size and actual data length within it. OpenOCD command +// which reads application traces reports error when it reads incomplete user data block. +// Data which are transffered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field +// containing length of host data following the header. + +// 4.3 Data Buffering +// ------------------ + +// It takes some time for the host to read TRAX memory block via JTAG. In streaming mode it can happen that target has filled its TRAX block, but host +// has not completed reading of the previous one yet. So in this case time critical tracing calls (which can not be delayed for too long time due to +// the lack of free memory in TRAX block) can be dropped. To avoid such scenarios tracing module implements data buffering. Buffered data will be sent +// to the host later when TRAX block switch occurs. The maximum size of the buffered data is controlled by menuconfig option +// CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX. + +// 4.4 Target Connection/Disconnection +// ----------------------------------- + +// When host is going to start tracing in streaming mode it needs to put both ESP32 cores into initial state when 'host connected' bit is set +// on both cores. To accomplish this host halts both cores and sets this bit in TRAX registers. But target code can be halted in state when it has read control +// register but has not updated its value. To handle such situations target code indicates to the host that it is updating control register by writing +// non-zero value to status register. Actually it writes address of the instruction which it will execute when it finishes with +// the registers update. When target is halted during control register update host sets breakpoint at the address from status register and resumes CPU. +// After target code finishes with register update it is halted on breakpoint, host detects it and safely sets 'host connected' bit. When both cores +// are set up they are resumed. Tracing starts without further intrusion into CPUs work. +// When host is going to stop tracing in streaming mode it needs to disconnect targets. Disconnection process is done using the same algorithm +// as for connecting, but 'host connected' bits are cleared on ESP32 cores. + +// 5. Module Access Synchronization +// ================================ + +// Access to internal module's data is synchronized with custom mutex. Mutex is a wrapper for portMUX_TYPE and uses almost the same sync mechanism as in +// vPortCPUAcquireMutex/vPortCPUReleaseMutex. The mechanism uses S32C1I Xtensa instruction to implement exclusive access to module's data from tasks and +// ISRs running on both cores. Also custom mutex allows specifying timeout for locking operation. Locking routine checks underlaying mutex in cycle until +// it gets its ownership or timeout expires. The differences of application tracing module's mutex implementation from vPortCPUAcquireMutex/vPortCPUReleaseMutex are: +// - Support for timeouts. +// - Local IRQs for CPU which owns the mutex are disabled till the call to unlocking routine. This is made to avoid possible task's prio inversion. +// When low prio task takes mutex and enables local IRQs gets preempted by high prio task which in its turn can try to acquire mutex using infinite timeout. +// So no local task switch occurs when mutex is locked. But this does not apply to tasks on another CPU. +// WARNING: Priority inversion can happen when low prio task works on one CPU and medium and high prio tasks work on another. +// WARNING: Care must be taken when selecting timeout values for trace calls from ISRs. Tracing module does not care about watchdogs when waiting +// on internal locks and for host to complete previous block reading, so if timeout value exceeds watchdog's one it can lead to the system reboot. + +// 6. Timeouts +// =========== + +// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in microseconds. +// There are two situations when task/ISR can be delayed by tracing API call. Timeout mechanism takes into account both conditions: +// - Trace data are locked by another task/ISR. When wating on trace data lock. +// - Current TRAX memory input block is full when working in streaming mode (host is connected). When waiting for host to complete previous block reading. +// When wating for any of above conditions xthal_get_ccount() is called periodically to calculate time elapsed from trace API routine entry. When elapsed +// time exceeds specified timeout value operation is canceled and ESP_ERR_TIMEOUT code is returned. +#include "sdkconfig.h" +#include "soc/soc.h" +#include "soc/dport_access.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "soc/dport_reg.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "soc/sensitive_reg.h" +#endif +#include "eri.h" +#include "trax.h" +#include "esp_log.h" +#include "esp_app_trace_membufs_proto.h" +#include "esp_app_trace_port.h" + +// TODO: move these (and same definitions in trax.c to dport_reg.h) +#if CONFIG_IDF_TARGET_ESP32 +#define TRACEMEM_MUX_PROBLK0_APPBLK1 0 +#define TRACEMEM_MUX_BLK0_ONLY 1 +#define TRACEMEM_MUX_BLK1_ONLY 2 +#define TRACEMEM_MUX_PROBLK1_APPBLK0 3 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define TRACEMEM_MUX_BLK0_NUM 19 +#define TRACEMEM_MUX_BLK1_NUM 20 +#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4)) +#endif + +// TRAX is disabled, so we use its registers for our own purposes +// | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 | +#define ESP_APPTRACE_TRAX_CTRL_REG ERI_TRAX_DELAYCNT +#define ESP_APPTRACE_TRAX_STAT_REG ERI_TRAX_TRIGGERPC + +#define ESP_APPTRACE_TRAX_BLOCK_LEN_MSK 0x7FFFUL +#define ESP_APPTRACE_TRAX_BLOCK_LEN(_l_) ((_l_) & ESP_APPTRACE_TRAX_BLOCK_LEN_MSK) +#define ESP_APPTRACE_TRAX_BLOCK_LEN_GET(_v_) ((_v_) & ESP_APPTRACE_TRAX_BLOCK_LEN_MSK) +#define ESP_APPTRACE_TRAX_BLOCK_ID_MSK 0x7FUL +#define ESP_APPTRACE_TRAX_BLOCK_ID(_id_) (((_id_) & ESP_APPTRACE_TRAX_BLOCK_ID_MSK) << 15) +#define ESP_APPTRACE_TRAX_BLOCK_ID_GET(_v_) (((_v_) >> 15) & ESP_APPTRACE_TRAX_BLOCK_ID_MSK) +#define ESP_APPTRACE_TRAX_HOST_DATA (1 << 22) +#define ESP_APPTRACE_TRAX_HOST_CONNECT (1 << 23) + +#define ESP_APPTRACE_TRAX_INITED(_hw_) ((_hw_)->inited & (1 << cpu_hal_get_core_id())) + +#if CONFIG_IDF_TARGET_ESP32 +static uint8_t * const s_trax_blocks[] = { + (uint8_t *) 0x3FFFC000, + (uint8_t *) 0x3FFF8000 +}; +#elif CONFIG_IDF_TARGET_ESP32S2 +static uint8_t * const s_trax_blocks[] = { + (uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK0_NUM), + (uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK1_NUM) +}; +#endif + +#define ESP_APPTRACE_TRAX_BLOCK_SIZE (0x4000UL) + +/** TRAX HW transport data */ +typedef struct { + uint8_t inited; +#if CONFIG_APPTRACE_LOCK_ENABLE + esp_apptrace_lock_t lock; // sync lock +#endif + esp_apptrace_membufs_proto_data_t membufs; +} esp_apptrace_trax_data_t; + + +static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data); +static esp_err_t esp_apptrace_trax_flush(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo); +static esp_err_t esp_apptrace_trax_flush_nolock(esp_apptrace_trax_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo); +static uint8_t *esp_apptrace_trax_up_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo); +static esp_err_t esp_apptrace_trax_up_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo); +static void esp_apptrace_trax_down_buffer_config(esp_apptrace_trax_data_t *hw_data, uint8_t *buf, uint32_t size); +static uint8_t *esp_apptrace_trax_down_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo); +static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo); +static bool esp_apptrace_trax_host_is_connected(esp_apptrace_trax_data_t *hw_data); +static esp_err_t esp_apptrace_trax_buffer_swap_start(uint32_t curr_block_id); +static esp_err_t esp_apptrace_trax_buffer_swap(uint32_t new_block_id); +static esp_err_t esp_apptrace_trax_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len); +static bool esp_apptrace_trax_host_data_pending(void); + + +const static char *TAG = "esp_apptrace"; + +esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data) +{ + return NULL; +} + +esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data) +{ +#if CONFIG_APPTRACE_DEST_JTAG + static esp_apptrace_membufs_proto_hw_t s_trax_proto_hw = { + .swap_start = esp_apptrace_trax_buffer_swap_start, + .swap = esp_apptrace_trax_buffer_swap, + .swap_end = esp_apptrace_trax_buffer_swap_end, + .host_data_pending = esp_apptrace_trax_host_data_pending, + }; + static esp_apptrace_trax_data_t s_trax_hw_data = { + .membufs = { + .hw = &s_trax_proto_hw, + }, + }; + static esp_apptrace_hw_t s_trax_hw = { + .init = (esp_err_t (*)(void *))esp_apptrace_trax_init, + .get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_get, + .put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_put, + .flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_flush_nolock, + .flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_trax_flush, + .down_buffer_config = (void (*)(void *, uint8_t *, uint32_t ))esp_apptrace_trax_down_buffer_config, + .get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_get, + .put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_put, + .host_is_connected = (bool (*)(void *))esp_apptrace_trax_host_is_connected, + }; + *data = &s_trax_hw_data; + return &s_trax_hw; +#else + return NULL; +#endif +} + +static esp_err_t esp_apptrace_trax_lock(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo) +{ +#if CONFIG_APPTRACE_LOCK_ENABLE + esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo); + if (ret != ESP_OK) { + return ESP_FAIL; + } +#endif + return ESP_OK; +} + +static esp_err_t esp_apptrace_trax_unlock(esp_apptrace_trax_data_t *hw_data) +{ + esp_err_t ret = ESP_OK; +#if CONFIG_APPTRACE_LOCK_ENABLE + ret = esp_apptrace_lock_give(&hw_data->lock); +#endif + return ret; +} + +static inline void esp_apptrace_trax_hw_init(void) +{ + // Stop trace, if any (on the current CPU) + eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TRSTP); + eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TMEN); + eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(0)); + // this is for OpenOCD to let him know where stub entries vector is resided + // must be read by host before any transfer using TRAX + eri_write(ESP_APPTRACE_TRAX_STAT_REG, 0); + + ESP_APPTRACE_LOGI("Initialized TRAX on CPU%d", cpu_hal_get_core_id()); +} + +static inline void esp_apptrace_trax_select_memory_block(int block_num) +{ + // select memory block to be exposed to the TRAX module (accessed by host) +#if CONFIG_IDF_TARGET_ESP32 + DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY); +#elif CONFIG_IDF_TARGET_ESP32S2 + WRITE_PERI_REG(DPORT_PMS_OCCUPY_3_REG, block_num ? BIT(TRACEMEM_MUX_BLK0_NUM-4) : BIT(TRACEMEM_MUX_BLK1_NUM-4)); +#endif +} + +static inline void esp_apptrace_trax_memory_enable(void) +{ +#if CONFIG_IDF_TARGET_ESP32 + /* Enable trace memory on PRO CPU */ + DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, DPORT_PRO_TRACEMEM_ENA_M); +#if CONFIG_FREERTOS_UNICORE == 0 + /* Enable trace memory on APP CPU */ + DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_M); +#endif +#endif +} + +/*****************************************************************************************/ +/***************************** Apptrace HW iface *****************************************/ +/*****************************************************************************************/ + +static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data) +{ + int core_id = cpu_hal_get_core_id(); + + // 'esp_apptrace_trax_init()' is called on every core, so ensure to do main initialization only once + if (core_id == 0) { + esp_apptrace_mem_block_t mem_blocks_cfg[2] = { + { + .start = s_trax_blocks[0], + .sz = ESP_APPTRACE_TRAX_BLOCK_SIZE + }, + { + .start = s_trax_blocks[1], + .sz = ESP_APPTRACE_TRAX_BLOCK_SIZE + }, + }; + esp_err_t res = esp_apptrace_membufs_init(&hw_data->membufs, mem_blocks_cfg); + if (res != ESP_OK) { + ESP_APPTRACE_LOGE("Failed to init membufs proto (%d)!", res); + return res; + } +#if CONFIG_APPTRACE_LOCK_ENABLE + esp_apptrace_lock_init(&hw_data->lock); +#endif + esp_apptrace_trax_memory_enable(); + esp_apptrace_trax_select_memory_block(0); + } + // init TRAX on this CPU + esp_apptrace_trax_hw_init(); + hw_data->inited |= 1 << core_id; + + return ESP_OK; +} + +static uint8_t *esp_apptrace_trax_up_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo) +{ + uint8_t *ptr; + + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return NULL; + } + esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo); + if (res != ESP_OK) { + return NULL; + } + + ptr = esp_apptrace_membufs_up_buffer_get(&hw_data->membufs, size, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + } + return ptr; +} + +static esp_err_t esp_apptrace_trax_up_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + // Can avoid locking because esp_apptrace_membufs_up_buffer_put() just modifies buffer's header + esp_err_t res = esp_apptrace_membufs_up_buffer_put(&hw_data->membufs, ptr, tmo); + return res; +} + +static void esp_apptrace_trax_down_buffer_config(esp_apptrace_trax_data_t *hw_data, uint8_t *buf, uint32_t size) +{ + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return; + } + esp_apptrace_membufs_down_buffer_config(&hw_data->membufs, buf, size); +} + +static uint8_t *esp_apptrace_trax_down_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo) +{ + uint8_t *ptr; + + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return NULL; + } + esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo); + if (res != ESP_OK) { + return NULL; + } + + ptr = esp_apptrace_membufs_down_buffer_get(&hw_data->membufs, size, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + } + return ptr; +} + +static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + // Can avoid locking because esp_apptrace_membufs_down_buffer_put() does nothing + /*esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo); + if (res != ESP_OK) { + return res; + }*/ + + esp_err_t res = esp_apptrace_membufs_down_buffer_put(&hw_data->membufs, ptr, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + /*if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + }*/ + return res; +} + +static bool esp_apptrace_trax_host_is_connected(esp_apptrace_trax_data_t *hw_data) +{ + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return false; + } + return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false; +} + +static esp_err_t esp_apptrace_trax_flush_nolock(esp_apptrace_trax_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + return esp_apptrace_membufs_flush_nolock(&hw_data->membufs, min_sz, tmo); +} + +static esp_err_t esp_apptrace_trax_flush(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo) +{ + if (!ESP_APPTRACE_TRAX_INITED(hw_data)) { + return ESP_ERR_INVALID_STATE; + } + esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo); + if (res != ESP_OK) { + return res; + } + + res = esp_apptrace_membufs_flush_nolock(&hw_data->membufs, 0, tmo); + + // now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data + if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) { + assert(false && "Failed to unlock apptrace data!"); + } + return res; +} + +/*****************************************************************************************/ +/************************** Membufs proto HW iface ***************************************/ +/*****************************************************************************************/ + +static inline void esp_apptrace_trax_buffer_swap_lock(void) +{ + extern uint32_t __esp_apptrace_trax_eri_updated; + + // indicate to host that we are about to update. + // this is used only to place CPU into streaming mode at tracing startup + // before starting streaming host can halt us after we read ESP_APPTRACE_TRAX_CTRL_REG and before we updated it + // HACK: in this case host will set breakpoint just after ESP_APPTRACE_TRAX_CTRL_REG update, + // here we set address to set bp at + // enter ERI update critical section + eri_write(ESP_APPTRACE_TRAX_STAT_REG, (uint32_t)&__esp_apptrace_trax_eri_updated); +} + +static __attribute__((noinline)) void esp_apptrace_trax_buffer_swap_unlock(void) +{ + // exit ERI update critical section + eri_write(ESP_APPTRACE_TRAX_STAT_REG, 0x0); + // TODO: currently host sets breakpoint, use break instruction to stop; + // it will allow to use ESP_APPTRACE_TRAX_STAT_REG for other purposes + asm volatile ( + " .global __esp_apptrace_trax_eri_updated\n" + "__esp_apptrace_trax_eri_updated:\n"); // host will set bp here to resolve collision at streaming start +} + +static esp_err_t esp_apptrace_trax_buffer_swap_start(uint32_t curr_block_id) +{ + esp_err_t res = ESP_OK; + + esp_apptrace_trax_buffer_swap_lock(); + + uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); + uint32_t host_connected = ESP_APPTRACE_TRAX_HOST_CONNECT & ctrl_reg; + if (host_connected) { + uint32_t acked_block = ESP_APPTRACE_TRAX_BLOCK_ID_GET(ctrl_reg); + uint32_t host_to_read = ESP_APPTRACE_TRAX_BLOCK_LEN_GET(ctrl_reg); + if (host_to_read != 0 || acked_block != (curr_block_id & ESP_APPTRACE_TRAX_BLOCK_ID_MSK)) { + ESP_APPTRACE_LOGD("HC[%d]: Can not switch %x %d %x %x/%lx", cpu_hal_get_core_id(), ctrl_reg, host_to_read, acked_block, + curr_block_id & ESP_APPTRACE_TRAX_BLOCK_ID_MSK, curr_block_id); + res = ESP_ERR_NO_MEM; + goto _on_err; + } + } + return ESP_OK; +_on_err: + esp_apptrace_trax_buffer_swap_unlock(); + return res; +} + +static esp_err_t esp_apptrace_trax_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len) +{ + uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); + uint32_t host_connected = ESP_APPTRACE_TRAX_HOST_CONNECT & ctrl_reg; + eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(new_block_id) | + host_connected | ESP_APPTRACE_TRAX_BLOCK_LEN(prev_block_len)); + esp_apptrace_trax_buffer_swap_unlock(); + return ESP_OK; +} + +static esp_err_t esp_apptrace_trax_buffer_swap(uint32_t new_block_id) +{ + esp_apptrace_trax_select_memory_block(new_block_id); + return ESP_OK; +} + +static bool esp_apptrace_trax_host_data_pending(void) +{ + uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); + return (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA) ? true : false; +} diff --git a/components/app_trace/private_include/esp_app_trace_membufs_proto.h b/components/app_trace/private_include/esp_app_trace_membufs_proto.h new file mode 100644 index 000000000000..55865616ca9a --- /dev/null +++ b/components/app_trace/private_include/esp_app_trace_membufs_proto.h @@ -0,0 +1,70 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef ESP_APP_TRACE_MEMBUFS_PROTO_H_ +#define ESP_APP_TRACE_MEMBUFS_PROTO_H_ + +#include "esp_app_trace_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** TRAX HW transport state */ +typedef struct { + uint32_t in_block; // input block ID + // TODO: change to uint16_t + uint32_t markers[2]; // block filling level markers +} esp_apptrace_membufs_state_t; + +/** memory block parameters, + * should be packed, because it is read from the host */ +typedef struct { + uint8_t *start; // start address + uint32_t sz; // size +} esp_apptrace_mem_block_t; + +typedef struct { + esp_err_t (*swap_start)(uint32_t curr_block_id); + esp_err_t (*swap)(uint32_t new_block_id); + esp_err_t (*swap_end)(uint32_t new_block_id, uint32_t prev_block_len); + bool (*host_data_pending)(void); +} esp_apptrace_membufs_proto_hw_t; + +typedef struct { + esp_apptrace_membufs_proto_hw_t * hw; + volatile esp_apptrace_membufs_state_t state; // state + esp_apptrace_mem_block_t blocks[2]; // memory blocks +#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0 + // ring buffer control struct for pending user blocks + esp_apptrace_rb_t rb_pend; + // storage for pending user blocks + uint8_t pending_data[CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX + 1]; +#endif + // ring buffer control struct for data from host (down buffer) + esp_apptrace_rb_t rb_down; +} esp_apptrace_membufs_proto_data_t; + +esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto, const esp_apptrace_mem_block_t blocks_cfg[2]); +void esp_apptrace_membufs_down_buffer_config(esp_apptrace_membufs_proto_data_t *data, uint8_t *buf, uint32_t size); +uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t *size, esp_apptrace_tmo_t *tmo); +esp_err_t esp_apptrace_membufs_down_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo); +uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t size, esp_apptrace_tmo_t *tmo); +esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo); +esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *proto, uint32_t min_sz, esp_apptrace_tmo_t *tmo); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/app_trace/sdkconfig.rename b/components/app_trace/sdkconfig.rename index 61c71a933f28..4fda22e1f6ff 100644 --- a/components/app_trace/sdkconfig.rename +++ b/components/app_trace/sdkconfig.rename @@ -3,10 +3,34 @@ CONFIG_ESP32_APPTRACE_DESTINATION CONFIG_APPTRACE_DESTINATION CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE -CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_TRAX +CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_JTAG 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_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX CONFIG_ESP32_GCOV_ENABLE CONFIG_APPTRACE_GCOV_ENABLE + +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_TIMER_00 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00 +CONFIG_SYSVIEW_TS_SOURCE_TIMER_01 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01 +CONFIG_SYSVIEW_TS_SOURCE_TIMER_10 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10 +CONFIG_SYSVIEW_TS_SOURCE_TIMER_11 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_11 +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 diff --git a/components/app_trace/sys_view/SEGGER/SEGGER_RTT.h b/components/app_trace/sys_view/SEGGER/SEGGER_RTT.h index 50916223df25..4cb95c221295 100644 --- a/components/app_trace/sys_view/SEGGER/SEGGER_RTT.h +++ b/components/app_trace/sys_view/SEGGER/SEGGER_RTT.h @@ -159,8 +159,8 @@ unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const voi unsigned SEGGER_RTT_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); -void SEGGER_RTT_ESP32_FlushNoLock (unsigned long min_sz, unsigned long tmo); -void SEGGER_RTT_ESP32_Flush (unsigned long min_sz, unsigned long tmo); +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 // diff --git a/components/app_trace/sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c b/components/app_trace/sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c index 9bbc4b2a66fa..ff02ae1905f3 100644 --- a/components/app_trace/sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c +++ b/components/app_trace/sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c @@ -73,6 +73,8 @@ Revision: $Rev: 3734 $ #include "esp32/clk.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/clk.h" #endif @@ -89,11 +91,17 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI; // The target device name #define SYSVIEW_DEVICE_NAME CONFIG_IDF_TARGET +// The target core name +#if CONFIG_IDF_TARGET_ARCH_XTENSA +#define SYSVIEW_CORE_NAME "xtensa" +#elif CONFIG_IDF_TARGET_ARCH_RISCV +#define SYSVIEW_CORE_NAME "riscv" +#endif // Determine which timer to use as timestamp source -#if CONFIG_SYSVIEW_TS_SOURCE_CCOUNT +#if CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT #define TS_USE_CCOUNT 1 -#elif CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER +#elif CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER #define TS_USE_ESP_TIMER 1 #else #define TS_USE_TIMERGROUP 1 @@ -109,13 +117,13 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI; #define SYSVIEW_TIMESTAMP_FREQ (esp_clk_apb_freq() / SYSVIEW_TIMER_DIV) // Timer ID and group ID -#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_01) +#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01) #define TS_TIMER_ID 0 #else #define TS_TIMER_ID 1 #endif // TIMER_00 || TIMER_01 -#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_10) +#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10) #define TS_TIMER_GROUP 0 #else #define TS_TIMER_GROUP 1 @@ -143,12 +151,16 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI; // The lowest RAM address used for IDs (pointers) #define SYSVIEW_RAM_BASE (SOC_DROM_LOW) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #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_IDF_TARGET_ESP32C3 + #define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF) +#endif // 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 @@ -167,11 +179,13 @@ static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKE */ static void _cbSendSystemDesc(void) { char irq_str[32]; - SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C=Xtensa,O=FreeRTOS"); + SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C="SYSVIEW_CORE_NAME",O=FreeRTOS"); snprintf(irq_str, sizeof(irq_str), "I#%d=SysTick", SYSTICK_INTR_ID); 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; snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, esp_isr_names[i]); SEGGER_SYSVIEW_SendSysDesc(irq_str); } @@ -213,43 +227,43 @@ void SEGGER_SYSVIEW_Conf(void) { &SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc); SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE); -#if !CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE disable_evts |= SYSVIEW_EVTMASK_OVERFLOW; #endif -#if !CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE disable_evts |= SYSVIEW_EVTMASK_ISR_ENTER; #endif -#if !CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE disable_evts |= SYSVIEW_EVTMASK_ISR_EXIT; #endif -#if !CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE disable_evts |= SYSVIEW_EVTMASK_TASK_START_EXEC; #endif -#if !CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_EXEC; #endif -#if !CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE disable_evts |= SYSVIEW_EVTMASK_TASK_START_READY; #endif -#if !CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_READY; #endif -#if !CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE disable_evts |= SYSVIEW_EVTMASK_TASK_CREATE; #endif -#if !CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE disable_evts |= SYSVIEW_EVTMASK_TASK_TERMINATE; #endif -#if !CONFIG_SYSVIEW_EVT_IDLE_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE disable_evts |= SYSVIEW_EVTMASK_IDLE; #endif -#if !CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE disable_evts |= SYSVIEW_EVTMASK_ISR_TO_SCHEDULER; #endif -#if !CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE disable_evts |= SYSVIEW_EVTMASK_TIMER_ENTER; #endif -#if !CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE +#if !CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE disable_evts |= SYSVIEW_EVTMASK_TIMER_EXIT; #endif SEGGER_SYSVIEW_DisableEvents(disable_evts); diff --git a/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h b/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h index 5607bdb4b653..47624de25893 100644 --- a/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h +++ b/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h @@ -80,7 +80,7 @@ Revision: $Rev: 3734 $ #define portSTACK_GROWTH ( -1 ) #endif -#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_SYSVIEW_MAX_TASKS +#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_APPTRACE_SV_MAX_TASKS /********************************************************************* * @@ -290,12 +290,12 @@ Revision: $Rev: 3734 $ #define traceTASK_SWITCHED_IN() if(prvGetTCBFromHandle(NULL) == xTaskGetIdleTaskHandle()) { \ SEGGER_SYSVIEW_OnIdle(); \ } else { \ - SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[xPortGetCoreID()]); \ + SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[cpu_hal_get_core_id()]); \ } #else #define traceTASK_SWITCHED_IN() { \ - if (memcmp(pxCurrentTCB[xPortGetCoreID()]->pcTaskName, "IDLE", 5) != 0) { \ - SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[xPortGetCoreID()]); \ + if (memcmp(pxCurrentTCB[cpu_hal_get_core_id()]->pcTaskName, "IDLE", 5) != 0) { \ + SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[cpu_hal_get_core_id()]); \ } else { \ SEGGER_SYSVIEW_OnIdle(); \ } \ @@ -305,14 +305,15 @@ Revision: $Rev: 3734 $ #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)pxCurrentTCB[xPortGetCoreID()], (1u << 2)) -#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[xPortGetCoreID()], (1u << 2)) +#define traceMOVED_TASK_TO_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[cpu_hal_get_core_id()], (1u << 2)) +#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[cpu_hal_get_core_id()], (1u << 2)) #define traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB) SEGGER_SYSVIEW_OnTaskStopReady((U32)pxTCB, ((3u << 3) | 3)) #define traceISR_EXIT_TO_SCHEDULER() SEGGER_SYSVIEW_RecordExitISRToScheduler() #define traceISR_EXIT() SEGGER_SYSVIEW_RecordExitISR() #define traceISR_ENTER(_n_) SEGGER_SYSVIEW_RecordEnterISR(_n_) + /********************************************************************* * * API functions diff --git a/components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c b/components/app_trace/sys_view/esp/SEGGER_RTT_esp.c similarity index 94% rename from components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c rename to components/app_trace/sys_view/esp/SEGGER_RTT_esp.c index c73e8876ac74..eb87dcf8628d 100644 --- a/components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c +++ b/components/app_trace/sys_view/esp/SEGGER_RTT_esp.c @@ -28,10 +28,10 @@ const static char *TAG = "segger_rtt"; // size of down channel data buf #define SYSVIEW_DOWN_BUF_SIZE 32 #define SEGGER_STOP_WAIT_TMO 1000000 //us -#if CONFIG_SYSVIEW_BUF_WAIT_TMO == -1 +#if CONFIG_APPTRACE_SV_BUF_WAIT_TMO == -1 #define SEGGER_HOST_WAIT_TMO ESP_APPTRACE_TMO_INFINITE #else -#define SEGGER_HOST_WAIT_TMO CONFIG_SYSVIEW_BUF_WAIT_TMO +#define SEGGER_HOST_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO #endif static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ]; @@ -47,7 +47,7 @@ static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE]; /********************************************************************* * -* SEGGER_RTT_ESP32_FlushNoLock() +* SEGGER_RTT_ESP_FlushNoLock() * * Function description * Flushes buffered events. @@ -59,7 +59,7 @@ static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE]; * Return value * None. */ -void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo) +void SEGGER_RTT_ESP_FlushNoLock(unsigned long min_sz, unsigned long tmo) { esp_err_t res; if (s_events_buf_filled > 0) { @@ -78,7 +78,7 @@ void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo) /********************************************************************* * -* SEGGER_RTT_ESP32_Flush() +* SEGGER_RTT_ESP_Flush() * * Function description * Flushes buffered events. @@ -90,10 +90,10 @@ void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo) * Return value * None. */ -void SEGGER_RTT_ESP32_Flush(unsigned long min_sz, unsigned long tmo) +void SEGGER_RTT_ESP_Flush(unsigned long min_sz, unsigned long tmo) { SEGGER_SYSVIEW_LOCK(); - SEGGER_RTT_ESP32_FlushNoLock(min_sz, tmo); + SEGGER_RTT_ESP_FlushNoLock(min_sz, tmo); SEGGER_SYSVIEW_UNLOCK(); } @@ -155,7 +155,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes); return 0; } - if (xPortGetCoreID()) { // dual core specific code + if (cpu_hal_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) @@ -175,7 +175,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes); s_events_buf_filled += NumBytes; if (event_id == SYSVIEW_EVTID_TRACE_STOP) { - SEGGER_RTT_ESP32_FlushNoLock(0, SEGGER_STOP_WAIT_TMO); + SEGGER_RTT_ESP_FlushNoLock(0, SEGGER_STOP_WAIT_TMO); } return NumBytes; } diff --git a/components/app_trace/sys_view/ext/heap_trace_module.c b/components/app_trace/sys_view/ext/heap_trace_module.c index 3d86f2e6478b..9aacc61a118a 100644 --- a/components/app_trace/sys_view/ext/heap_trace_module.c +++ b/components/app_trace/sys_view/ext/heap_trace_module.c @@ -60,7 +60,7 @@ esp_err_t esp_sysview_heap_trace_start(uint32_t tmo) esp_err_t esp_sysview_heap_trace_stop(void) { ESP_EARLY_LOGV(TAG, "%s", __func__); - SEGGER_RTT_ESP32_Flush(0, ESP_APPTRACE_TMO_INFINITE); + SEGGER_RTT_ESP_Flush(0, ESP_APPTRACE_TMO_INFINITE); return ESP_OK; } diff --git a/components/app_trace/test/test_trace.c b/components/app_trace/test/test_trace.c index 04d4ee956ee7..30788f0a2fa6 100644 --- a/components/app_trace/test/test_trace.c +++ b/components/app_trace/test/test_trace.c @@ -83,7 +83,7 @@ static void esp_apptrace_test_timer_init(int timer_group, int timer_idx, uint32_ timer_enable_intr(timer_group, timer_idx); } -#if CONFIG_SYSVIEW_ENABLE == 0 +#if CONFIG_APPTRACE_SV_ENABLE == 0 #define ESP_APPTRACE_TEST_WRITE(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, ESP_APPTRACE_TMO_INFINITE) #define ESP_APPTRACE_TEST_WRITE_FROM_ISR(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, 0UL) #define ESP_APPTRACE_TEST_WRITE_NOWAIT(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, 0) @@ -209,7 +209,7 @@ static void esp_apptrace_dummy_task(void *p) i = 0; while (!arg->stop) { - ESP_APPTRACE_TEST_LOGD("%x: dummy task work %d.%d", xTaskGetCurrentTaskHandle(), xPortGetCoreID(), i++); + ESP_APPTRACE_TEST_LOGD("%x: dummy task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i++); if (tmo_ticks) { vTaskDelay(tmo_ticks); } @@ -254,7 +254,7 @@ static void esp_apptrace_test_task(void *p) ESP_APPTRACE_TEST_LOGE("Failed to timer_isr_register (%d)!", res); goto on_fail; } - *(uint32_t *)arg->timers[i].data.buf = ((uint32_t)inth[i]) | (1 << 31) | (xPortGetCoreID() ? 0x1 : 0); + *(uint32_t *)arg->timers[i].data.buf = ((uint32_t)inth[i]) | (1 << 31) | (cpu_hal_get_core_id() ? 0x1 : 0); ESP_APPTRACE_TEST_LOGI("%x: start timer %x period %u us", xTaskGetCurrentTaskHandle(), inth[i], arg->timers[i].data.period); res = timer_start(arg->timers[i].group, arg->timers[i].id); if (res != ESP_OK) { @@ -264,7 +264,7 @@ static void esp_apptrace_test_task(void *p) } } - *(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (xPortGetCoreID() ? 0x1 : 0); + *(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (cpu_hal_get_core_id() ? 0x1 : 0); arg->data.wr_cnt = 0; arg->data.wr_err = 0; while (!arg->stop) { @@ -744,7 +744,7 @@ static void esp_logtrace_task(void *p) ESP_LOGI(TAG, "%p: sample print 4 %c", xTaskGetCurrentTaskHandle(), ((i & 0xFF) % 95) + 32); ESP_LOGI(TAG, "%p: sample print 5 %f", xTaskGetCurrentTaskHandle(), 1.0); ESP_LOGI(TAG, "%p: sample print 6 %f", xTaskGetCurrentTaskHandle(), 3.45); - ESP_LOGI(TAG, "%p: logtrace task work %d.%d", xTaskGetCurrentTaskHandle(), xPortGetCoreID(), i); + ESP_LOGI(TAG, "%p: logtrace task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i); if (++i == 10000) { break; } diff --git a/components/app_update/test/test_switch_ota.c b/components/app_update/test/test_switch_ota.c index 98192b9fe390..8793e6d1c7a9 100644 --- a/components/app_update/test/test_switch_ota.c +++ b/components/app_update/test/test_switch_ota.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /* * Tests for switching between partitions: factory, OTAx, test. */ @@ -821,3 +826,25 @@ static void test_flow6(void) // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//-- // 3 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0 using esp_ota_write_with_offset", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow6, test_flow6); + +TEST_CASE("Test bootloader_common_get_sha256_of_partition returns ESP_ERR_IMAGE_INVALID when image is ivalid", "[partitions]") +{ + const esp_partition_t *cur_app = esp_ota_get_running_partition(); + ESP_LOGI(TAG, "copy current app to next part"); + const esp_partition_t *other_app = get_next_update_partition(); + copy_current_app_to_next_part(cur_app, other_app); + erase_ota_data(); + + uint8_t sha_256_cur_app[32]; + uint8_t sha_256_other_app[32]; + TEST_ESP_OK(bootloader_common_get_sha256_of_partition(cur_app->address, cur_app->size, cur_app->type, sha_256_cur_app)); + TEST_ESP_OK(bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app)); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same"); + + uint32_t data = 0; + bootloader_flash_write(other_app->address + 0x50, &data, sizeof(data), false); + + TEST_ESP_ERR(ESP_ERR_IMAGE_INVALID, bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app)); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same"); +} diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index e6f0e99a7a7b..085ddba2f9e7 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -480,7 +480,7 @@ menu "Security features" config SECURE_BOOT bool "Enable hardware Secure Boot in bootloader (READ DOCS FIRST)" default n - depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN_3 + depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN >= 3 select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2 help Build a bootloader which enables Secure Boot on first boot. diff --git a/components/bootloader_support/include_bootloader/bootloader_utility.h b/components/bootloader_support/include_bootloader/bootloader_utility.h index 8e534756c6d9..6ad9f1ddf45f 100644 --- a/components/bootloader_support/include_bootloader/bootloader_utility.h +++ b/components/bootloader_support/include_bootloader/bootloader_utility.h @@ -104,9 +104,10 @@ void bootloader_atexit(void); esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len); /** - * @brief Debug log contents of a buffer as hexadecimal + * @brief Debug log contents of a buffer as hexadecimal. * - * @note Only works if component log level is DEBUG or higher. + * @note - Only works if component log level is DEBUG or higher. + * - It will print at most 128 bytes from @c buffer. * * @param buffer Buffer to log * @param length Length of buffer in bytes. Maximum length 128 bytes. diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 0fb2a48bb254..d30b3b9d1212 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -169,6 +169,12 @@ esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t } if (data.image.hash_appended) { memcpy(out_sha_256, data.image_digest, ESP_PARTITION_HASH_LEN); + uint8_t calc_sha256[ESP_PARTITION_HASH_LEN]; + // The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID. + esp_err_t error = bootloader_sha256_flash_contents(address, data.image_len - ESP_PARTITION_HASH_LEN, calc_sha256); + if (error || memcmp(data.image_digest, calc_sha256, ESP_PARTITION_HASH_LEN) != 0) { + return ESP_ERR_IMAGE_INVALID; + } return ESP_OK; } // If image doesn't have a appended hash then hash calculates for entire image. diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index a5afc11f313b..7007fdc836f5 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -76,10 +76,12 @@ void bootloader_console_init(void) // Route GPIO signals to/from pins const uint32_t tx_idx = uart_periph_signal[uart_num].tx_sig; const uint32_t rx_idx = uart_periph_signal[uart_num].rx_sig; + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[uart_rx_gpio], PIN_FUNC_GPIO); PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]); esp_rom_gpio_pad_pullup_only(uart_rx_gpio); esp_rom_gpio_connect_out_signal(uart_tx_gpio, tx_idx, 0, 0); esp_rom_gpio_connect_in_signal(uart_rx_gpio, rx_idx, 0); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[uart_tx_gpio], PIN_FUNC_GPIO); // Enable the peripheral periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + uart_num); } diff --git a/components/bootloader_support/src/bootloader_efuse_esp32.c b/components/bootloader_support/src/bootloader_efuse_esp32.c index 945d482f30e9..8fde53691506 100644 --- a/components/bootloader_support/src/bootloader_efuse_esp32.c +++ b/components/bootloader_support/src/bootloader_efuse_esp32.c @@ -16,8 +16,9 @@ #include "bootloader_clock.h" #include "soc/efuse_reg.h" #include "soc/apb_ctrl_reg.h" +#include "esp_attr.h" -uint8_t bootloader_common_get_chip_revision(void) +IRAM_ATTR uint8_t bootloader_common_get_chip_revision(void) { uint8_t eco_bit0, eco_bit1, eco_bit2; eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) & 0xF000) >> 15; @@ -45,7 +46,7 @@ uint8_t bootloader_common_get_chip_revision(void) return chip_ver; } -uint32_t bootloader_common_get_chip_ver_pkg(void) +IRAM_ATTR uint32_t bootloader_common_get_chip_ver_pkg(void) { uint32_t pkg_version = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); uint32_t pkg_version_4bit = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG_4BIT); diff --git a/components/bootloader_support/src/bootloader_efuse_esp32c3.c b/components/bootloader_support/src/bootloader_efuse_esp32c3.c index df0fa290d3f8..504c7e62be9b 100644 --- a/components/bootloader_support/src/bootloader_efuse_esp32c3.c +++ b/components/bootloader_support/src/bootloader_efuse_esp32c3.c @@ -14,14 +14,15 @@ #include #include "soc/efuse_reg.h" +#include "esp_attr.h" -uint8_t bootloader_common_get_chip_revision(void) +IRAM_ATTR uint8_t bootloader_common_get_chip_revision(void) { // should return the same value as esp_efuse_get_chip_ver() return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_WAFER_VERSION); } -uint32_t bootloader_common_get_chip_ver_pkg(void) +IRAM_ATTR uint32_t bootloader_common_get_chip_ver_pkg(void) { // should return the same value as esp_efuse_get_pkg_ver() return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); diff --git a/components/bootloader_support/src/bootloader_efuse_esp32s2.c b/components/bootloader_support/src/bootloader_efuse_esp32s2.c index 6108efc1916e..f05463362346 100644 --- a/components/bootloader_support/src/bootloader_efuse_esp32s2.c +++ b/components/bootloader_support/src/bootloader_efuse_esp32s2.c @@ -16,15 +16,16 @@ #include "bootloader_clock.h" #include "bootloader_common.h" #include "soc/efuse_reg.h" +#include "esp_attr.h" -uint8_t bootloader_common_get_chip_revision(void) +IRAM_ATTR uint8_t bootloader_common_get_chip_revision(void) { // should return the same value as esp_efuse_get_chip_ver() - /* No other revisions for ESP32-S2 */ + return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_WAFER_VERSION); return 0; } -uint32_t bootloader_common_get_chip_ver_pkg(void) +IRAM_ATTR uint32_t bootloader_common_get_chip_ver_pkg(void) { // should return the same value as esp_efuse_get_pkg_ver() return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_4_REG, EFUSE_PKG_VERSION); diff --git a/components/bootloader_support/src/bootloader_efuse_esp32s3.c b/components/bootloader_support/src/bootloader_efuse_esp32s3.c index 19b1056be46d..8a816ec7112c 100644 --- a/components/bootloader_support/src/bootloader_efuse_esp32s3.c +++ b/components/bootloader_support/src/bootloader_efuse_esp32s3.c @@ -13,15 +13,16 @@ // limitations under the License. #include +#include "esp_attr.h" -uint8_t bootloader_common_get_chip_revision(void) +IRAM_ATTR uint8_t bootloader_common_get_chip_revision(void) { // should return the same value as esp_efuse_get_chip_ver() /* No other revisions for ESP32-S3 */ return 0; } -uint32_t bootloader_common_get_chip_ver_pkg(void) +IRAM_ATTR uint32_t bootloader_common_get_chip_ver_pkg(void) { // should return the same value as esp_efuse_get_pkg_ver() return 0; diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index cc61c3f4d0ad..235a48872db7 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -43,15 +43,15 @@ #define BYTESHIFT(VAR, IDX) (((VAR) >> ((IDX) * 8)) & 0xFF) #define ISSI_ID 0x9D +#define MXIC_ID 0xC2 #define GD_Q_ID_HIGH 0xC8 #define GD_Q_ID_MID 0x40 #define GD_Q_ID_LOW 0x16 #define ESP_BOOTLOADER_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2) -#define ESP_BOOTLOADER_SPIFLASH_QE_16B BIT9 // QE position when you write 16 bits at one time. -#define ESP_BOOTLOADER_SPIFLASH_QE_8B BIT1 // QE position when you write 8 bits(for SR2) at one time. -#define ESP_BOOTLOADER_SPIFLASH_WRITE_8B (8) -#define ESP_BOOTLOADER_SPIFLASH_WRITE_16B (16) +#define ESP_BOOTLOADER_SPIFLASH_QE_GD_SR2 BIT1 // QE position when you write 8 bits(for SR2) at one time. +#define ESP_BOOTLOADER_SPIFLASH_QE_SR1_2BYTE BIT9 // QE position when you write 16 bits at one time. + #ifndef BOOTLOADER_BUILD /* Normal app version maps to esp_spi_flash.h operations... @@ -466,72 +466,77 @@ FORCE_INLINE_ATTR bool is_gd_q_chip(const esp_rom_spiflash_chip_t* chip) return BYTESHIFT(chip->device_id, 2) == GD_Q_ID_HIGH && BYTESHIFT(chip->device_id, 1) == GD_Q_ID_MID && BYTESHIFT(chip->device_id, 0) >= GD_Q_ID_LOW; } +FORCE_INLINE_ATTR bool is_mxic_chip(const esp_rom_spiflash_chip_t* chip) +{ + return BYTESHIFT(chip->device_id, 2) == MXIC_ID; +} + esp_err_t IRAM_ATTR __attribute__((weak)) bootloader_flash_unlock(void) { + // At the beginning status == new_status == status_sr2 == new_status_sr2 == 0. + // If the register doesn't need to be updated, keep them the same (0), so that no command will be actually sent. uint16_t status = 0; // status for SR1 or SR1+SR2 if writing SR with 01H + 2Bytes. uint16_t new_status = 0; uint8_t status_sr2 = 0; // status_sr2 for SR2. uint8_t new_status_sr2 = 0; - uint8_t write_sr_bit = 0; + uint8_t sr1_bit_num = 0; esp_err_t err = ESP_OK; esp_rom_spiflash_wait_idle(&g_rom_flashchip); - if (is_issi_chip(&g_rom_flashchip)) { - write_sr_bit = ESP_BOOTLOADER_SPIFLASH_WRITE_8B; - // ISSI chips have different QE position - + if (is_issi_chip(&g_rom_flashchip) || is_mxic_chip(&g_rom_flashchip)) { + // Currently ISSI & MXIC share the same command and register layout, which is different from the default model. + // If any code here needs to be modified, check both chips. status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8); /* Clear all bits in the mask. (This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.) */ + sr1_bit_num = 8; new_status = status & (~ESP_BOOTLOADER_SPIFLASH_BP_MASK_ISSI); - // Skip if nothing needs to be cleared. Otherwise will waste time waiting for the flash to clear nothing. } else if (is_gd_q_chip(&g_rom_flashchip)) { /* The GD chips behaviour is to clear all bits in SR1 and clear bits in SR2 except QE bit. Use 01H to write SR1 and 31H to write SR2. */ - write_sr_bit = ESP_BOOTLOADER_SPIFLASH_WRITE_8B; - status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8); + sr1_bit_num = 8; new_status = 0; status_sr2 = bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8); - new_status_sr2 = status_sr2 & ESP_BOOTLOADER_SPIFLASH_QE_8B; + new_status_sr2 = status_sr2 & ESP_BOOTLOADER_SPIFLASH_QE_GD_SR2; } else { /* For common behaviour, like XMC chips, Use 01H+2Bytes to write both SR1 and SR2*/ - write_sr_bit = ESP_BOOTLOADER_SPIFLASH_WRITE_16B; status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8) | (bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8); /* Clear all bits except QE, if it is set. (This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.) */ - new_status = status & ESP_BOOTLOADER_SPIFLASH_QE_16B; + sr1_bit_num = 16; + new_status = status & ESP_BOOTLOADER_SPIFLASH_QE_SR1_2BYTE; } + // When SR is written, set to true to indicate that WRDI need to be sent to ensure the protection is ON before return. + bool status_written = false; + // Skip if nothing needs to be changed. Meaningless writing to SR increases the risk during write and wastes time. if (status != new_status) { - /* if the status in SR not equal to the ideal status, the status need to be updated */ esp_rom_spiflash_wait_idle(&g_rom_flashchip); bootloader_execute_flash_command(CMD_WREN, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); - bootloader_execute_flash_command(CMD_WRSR, new_status, write_sr_bit, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); + bootloader_execute_flash_command(CMD_WRSR, new_status, sr1_bit_num, 0); + status_written = true; } if (status_sr2 != new_status_sr2) { - /* If the status in SR2 not equal to the ideal status, the status need to be updated. - It doesn't need to be updated if status in SR2 is 0. - Note: if we need to update both SR1 and SR2, the `CMD_WREN` needs to be sent again. - */ esp_rom_spiflash_wait_idle(&g_rom_flashchip); bootloader_execute_flash_command(CMD_WREN, 0, 0, 0); + bootloader_execute_flash_command(CMD_WRSR2, new_status_sr2, 8, 0); + status_written = true; + } + + if (status_written) { + //Call esp_rom_spiflash_wait_idle to make sure previous WRSR is completed. esp_rom_spiflash_wait_idle(&g_rom_flashchip); - bootloader_execute_flash_command(CMD_WRSR2, new_status_sr2, write_sr_bit, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); + bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); } - bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); - esp_rom_spiflash_wait_idle(&g_rom_flashchip); return err; } diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 0d32623f2ae8..c8fd7af83c22 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -79,6 +79,7 @@ #include "bootloader_console.h" #include "bootloader_soc.h" #include "esp_efuse.h" +#include "esp_fault.h" static const char *TAG = "boot"; @@ -270,9 +271,16 @@ static esp_err_t write_otadata(esp_ota_select_entry_t *otadata, uint32_t offset, static bool check_anti_rollback(const esp_partition_pos_t *partition) { #ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK - esp_app_desc_t app_desc; + esp_app_desc_t app_desc = {}; esp_err_t err = bootloader_common_get_partition_description(partition, &app_desc); - return err == ESP_OK && esp_efuse_check_secure_version(app_desc.secure_version) == true; + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to get partition description %d", err); + return false; + } + bool sec_ver = esp_efuse_check_secure_version(app_desc.secure_version); + /* Anti FI check */ + ESP_FAULT_ASSERT(sec_ver == esp_efuse_check_secure_version(app_desc.secure_version)); + return sec_ver; #else return true; #endif @@ -285,6 +293,8 @@ static void update_anti_rollback(const esp_partition_pos_t *partition) esp_err_t err = bootloader_common_get_partition_description(partition, &app_desc); if (err == ESP_OK) { esp_efuse_update_secure_version(app_desc.secure_version); + } else { + ESP_LOGE(TAG, "Failed to get partition description %d", err); } } @@ -850,22 +860,19 @@ esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_he void bootloader_debug_buffer(const void *buffer, size_t length, const char *label) { -#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG - assert(length <= 128); // Avoid unbounded VLA size +#if CONFIG_BOOTLOADER_LOG_LEVEL >= 4 const uint8_t *bytes = (const uint8_t *)buffer; - char hexbuf[length * 2 + 1]; - hexbuf[length * 2] = 0; - for (size_t i = 0; i < length; i++) { - for (int shift = 0; shift < 2; shift++) { - uint8_t nibble = (bytes[i] >> (shift ? 0 : 4)) & 0x0F; - if (nibble < 10) { - hexbuf[i * 2 + shift] = '0' + nibble; - } else { - hexbuf[i * 2 + shift] = 'a' + nibble - 10; - } - } - } + const size_t output_len = MIN(length, 128); + char hexbuf[128 * 2 + 1]; + + bootloader_sha256_hex_to_str(hexbuf, bytes, output_len); + + hexbuf[output_len * 2] = '\0'; ESP_LOGD(TAG, "%s: %s", label, hexbuf); +#else + (void) buffer; + (void) length; + (void) label; #endif } diff --git a/components/bootloader_support/src/esp32/secure_boot.c b/components/bootloader_support/src/esp32/secure_boot.c index bb293ccb0677..76d31ceef650 100644 --- a/components/bootloader_support/src/esp32/secure_boot.c +++ b/components/bootloader_support/src/esp32/secure_boot.c @@ -436,7 +436,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag return ESP_FAIL; } #else - ESP_LOGW(TAG, "Not disabling ROM Download mode - SECURITY COMPROMISED"); + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); #endif #ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS diff --git a/components/bootloader_support/src/esp32c3/flash_encrypt.c b/components/bootloader_support/src/esp32c3/flash_encrypt.c index 12cd48ac09ec..e67288860db9 100644 --- a/components/bootloader_support/src/esp32c3/flash_encrypt.c +++ b/components/bootloader_support/src/esp32c3/flash_encrypt.c @@ -150,7 +150,7 @@ static esp_err_t initialise_flash_encryption(void) ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); #endif - esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); #if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS) // This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot diff --git a/components/bootloader_support/src/esp32c3/secure_boot.c b/components/bootloader_support/src/esp32c3/secure_boot.c index ce058aaca331..fc8c02f675c7 100644 --- a/components/bootloader_support/src/esp32c3/secure_boot.c +++ b/components/bootloader_support/src/esp32c3/secure_boot.c @@ -256,13 +256,25 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag return key_state; } - esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + esp_err_t err = ESP_FAIL; #ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE ESP_LOGI(TAG, "Enabling Security download mode..."); - esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD); + err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } +#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } #else - ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED"); + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); #endif #ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG @@ -295,7 +307,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED"); #endif - esp_err_t err = esp_efuse_batch_write_commit(); + err = esp_efuse_batch_write_commit(); if (err != ESP_OK) { ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err); return err; diff --git a/components/bootloader_support/src/esp32s2/secure_boot.c b/components/bootloader_support/src/esp32s2/secure_boot.c index cfdf755376c5..9cc784ee6dc2 100644 --- a/components/bootloader_support/src/esp32s2/secure_boot.c +++ b/components/bootloader_support/src/esp32s2/secure_boot.c @@ -28,6 +28,8 @@ #include "esp32s2/rom/efuse.h" #include "esp32s2/rom/secure_boot.h" +#include "esp_flash_encrypt.h" + static const char *TAG = "secure_boot_v2"; #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) @@ -261,11 +263,23 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag esp_efuse_write_field_bit(ESP_EFUSE_DIS_BOOT_REMAP); esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + esp_err_t err = ESP_FAIL; #ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE ESP_LOGI(TAG, "Enabling Security download mode..."); - esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD); + err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } +#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } #else - ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED"); + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); #endif #ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG @@ -297,7 +311,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED"); #endif - esp_err_t err = esp_efuse_batch_write_commit(); + err = esp_efuse_batch_write_commit(); if (err != ESP_OK) { ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err); return err; diff --git a/components/bootloader_support/src/esp32s3/flash_encrypt.c b/components/bootloader_support/src/esp32s3/flash_encrypt.c index 99ba1e41fe68..2c86947ed86d 100644 --- a/components/bootloader_support/src/esp32s3/flash_encrypt.c +++ b/components/bootloader_support/src/esp32s3/flash_encrypt.c @@ -172,7 +172,7 @@ static esp_err_t initialise_flash_encryption(void) ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); #endif - esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); esp_err_t err = esp_efuse_batch_write_commit(); if (err != ESP_OK) { diff --git a/components/bootloader_support/src/esp32s3/secure_boot.c b/components/bootloader_support/src/esp32s3/secure_boot.c index dbe2364e7eea..22319b0ce6f2 100644 --- a/components/bootloader_support/src/esp32s3/secure_boot.c +++ b/components/bootloader_support/src/esp32s3/secure_boot.c @@ -258,13 +258,25 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag __attribute__((unused)) static const uint8_t enable = 1; - esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + esp_err_t err = ESP_FAIL; #ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE ESP_LOGI(TAG, "Enabling Security download mode..."); - esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD); + err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } +#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } #else - ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED"); + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); #endif #ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG @@ -281,7 +293,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN); - esp_err_t err = esp_efuse_batch_write_commit(); + err = esp_efuse_batch_write_commit(); if (err != ESP_OK) { ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err); return err; diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 6d83b506f14a..ad81bc544379 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -259,7 +259,11 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad #if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS mode = ESP_IMAGE_LOAD_NO_VALIDATE; #elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON - if (rtc_get_reset_reason(0) == POWERON_RESET) { + if (rtc_get_reset_reason(0) == POWERON_RESET +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + || rtc_get_reset_reason(0) == EFUSE_RESET +#endif + ) { mode = ESP_IMAGE_LOAD_NO_VALIDATE; } #endif // CONFIG_BOOTLOADER_SKIP_... diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c index 0566a4aefbbd..4aa887c77768 100644 --- a/components/bootloader_support/src/flash_qio_mode.c +++ b/components/bootloader_support/src/flash_qio_mode.c @@ -88,6 +88,7 @@ const static qio_info_t chip_data[] = { { "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 }, { "GD", 0xC8, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 }, { "XM25QU64A", 0x20, 0x3817, 0xFFFF, read_status_8b_xmc25qu64a, write_status_8b_xmc25qu64a, 6 }, + { "TH", 0xcd, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 }, /* Final entry is default entry, if no other IDs have matched. diff --git a/components/bt/Kconfig b/components/bt/Kconfig index ca04f51b4ba0..8a15de6b86a7 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -7,42 +7,16 @@ menu "Bluetooth" help Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices. - config BT_CTRL_ESP32 - bool - depends on BT_ENABLED && IDF_TARGET_ESP32 - default y - - config BT_CTRL_ESP32C3 - bool - depends on BT_ENABLED && IDF_TARGET_ESP32C3 - default y - config BT_CTRL_ESP32S3 - bool - depends on BT_ENABLED && IDF_TARGET_ESP32S3 - default y - config BT_SOC_SUPPORT_5_0 bool depends on BT_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3) default y if BT_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3) default n - menu "Bluetooth controller(ESP32 Dual Mode Bluetooth)" - visible if BT_CTRL_ESP32 - - source "$IDF_PATH/components/bt/controller/esp32/Kconfig.in" - endmenu - - menu "Bluetooth controller(ESP32C3 Bluetooth Low Energy)" - visible if BT_CTRL_ESP32C3 - - source "$IDF_PATH/components/bt/controller/esp32c3/Kconfig.in" - endmenu - - menu "Bluetooth controller(ESP32S3 Bluetooth Low Energy)" - visible if BT_CTRL_ESP32S3 + menu "Bluetooth controller" + depends on BT_ENABLED - source "$IDF_PATH/components/bt/controller/esp32s3/Kconfig.in" + source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in" endmenu choice BT_HOST @@ -73,12 +47,12 @@ menu "Bluetooth" endchoice menu "Bluedroid Options" - visible if BT_BLUEDROID_ENABLED + depends on BT_BLUEDROID_ENABLED source "$IDF_PATH/components/bt/host/bluedroid/Kconfig.in" endmenu menu "NimBLE Options" - visible if BT_NIMBLE_ENABLED + depends on BT_NIMBLE_ENABLED source "$IDF_PATH/components/bt/host/nimble/Kconfig.in" endmenu diff --git a/components/bt/common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c b/components/bt/common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c index 071046dce9f6..fe6f96c73d7d 100644 --- a/components/bt/common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c +++ b/components/bt/common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c @@ -324,6 +324,12 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) blufi_env.conn_id = p_data->conn.conn_id; blufi_env.recv_seq = blufi_env.send_seq = 0; blufi_env.sec_mode = 0x0; + blufi_env.offset = 0; + + if (blufi_env.aggr_buf != NULL) { + osi_free(blufi_env.aggr_buf); + blufi_env.aggr_buf = NULL; + } msg.sig = BTC_SIG_API_CB; msg.pid = BTC_PID_BLUFI; diff --git a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c index 5538357b9451..37cae9fd8f2c 100644 --- a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c +++ b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c @@ -274,6 +274,13 @@ esp_blufi_gap_event(struct ble_gap_event *event, void *arg) blufi_env.is_connected = false; blufi_env.recv_seq = blufi_env.send_seq = 0; blufi_env.sec_mode = 0x0; + blufi_env.offset = 0; + + if (blufi_env.aggr_buf != NULL) { + osi_free(blufi_env.aggr_buf); + blufi_env.aggr_buf = NULL; + } + btc_msg_t msg; esp_blufi_cb_param_t param; diff --git a/components/bt/common/osi/config.c b/components/bt/common/osi/config.c index b3b8816037d7..9e3dc89a3cc6 100644 --- a/components/bt/common/osi/config.c +++ b/components/bt/common/osi/config.c @@ -550,10 +550,12 @@ static void config_parse(nvs_handle_t fp, config_t *config) const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i)) char *keyname = osi_calloc(keyname_bufsz); int buf_size = get_config_size_from_flash(fp); - char *buf = osi_calloc(buf_size); + char *buf = NULL; + if(buf_size == 0) { //First use nvs goto error; } + buf = osi_calloc(buf_size); if (!line || !section || !buf || !keyname) { err_code |= 0x01; goto error; diff --git a/components/bt/controller/esp32/Kconfig.in b/components/bt/controller/esp32/Kconfig.in index d12712862d7d..445df2316b8b 100644 --- a/components/bt/controller/esp32/Kconfig.in +++ b/components/bt/controller/esp32/Kconfig.in @@ -1,6 +1,5 @@ choice BTDM_CTRL_MODE prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)" - depends on BT_CTRL_ESP32 help Specify the bluetooth controller mode (BR/EDR, BLE or dual mode). @@ -152,7 +151,7 @@ config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF choice BTDM_CTRL_PINNED_TO_CORE_CHOICE prompt "The cpu core which bluetooth controller run" - depends on BT_CTRL_ESP32 && !FREERTOS_UNICORE + depends on !FREERTOS_UNICORE help Specify the cpu core to run bluetooth controller. Can not specify no-affinity. @@ -172,7 +171,6 @@ config BTDM_CTRL_PINNED_TO_CORE choice BTDM_CTRL_HCI_MODE_CHOICE prompt "HCI mode" - depends on BT_CTRL_ESP32 help Speicify HCI mode as VHCI or UART(H4) @@ -210,11 +208,8 @@ menu "HCI UART(H4) Options" endmenu menu "MODEM SLEEP Options" - visible if BT_CTRL_ESP32 - config BTDM_CTRL_MODEM_SLEEP bool "Bluetooth modem sleep" - depends on BT_CTRL_ESP32 default y help Enable/disable bluetooth controller low power mode. @@ -413,5 +408,10 @@ config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD help When adv report flow control is enabled, The ADV lost event will be generated when the number of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. - If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it + If you set it to a small value or printf every adv lost event, it may cause adv packets lost more. + +config BTDM_RESERVE_DRAM + hex + default 0xdb5c if BT_ENABLED + default 0 diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index 904cc968f4d4..2356a09e43d3 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -42,6 +42,7 @@ #include "soc/soc_memory_layout.h" #include "esp32/clk.h" #include "esp_coexist_internal.h" +#include "esp_timer.h" #if !CONFIG_FREERTOS_UNICORE #include "esp_ipc.h" #endif @@ -97,7 +98,7 @@ do{\ /* SPIRAM Configuration */ #if CONFIG_SPIRAM_USE_MALLOC -#define BTDM_MAX_QUEUE_NUM (5) +#define BTDM_MAX_QUEUE_NUM (6) #endif /* Types definition diff --git a/components/bt/controller/esp32c3/Kconfig.in b/components/bt/controller/esp32c3/Kconfig.in index c30f80bc451d..caa0d65328d4 100644 --- a/components/bt/controller/esp32c3/Kconfig.in +++ b/components/bt/controller/esp32c3/Kconfig.in @@ -66,6 +66,13 @@ config BT_CTRL_HW_CCA help It enables HW CCA feature in controller +config BT_CTRL_HW_CCA_VAL + int "CCA threshold value" + range 20 60 + default 20 + help + It is the threshold value of HW CCA, if the value is 30, it means CCA threshold is -30 dBm. + config BT_CTRL_HW_CCA_EFF int default 1 if BT_CTRL_HW_CCA diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index 440e90cab958..8615c4935e38 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -246,6 +246,7 @@ extern bool btdm_deep_sleep_mem_init(void); extern void btdm_deep_sleep_mem_deinit(void); extern void btdm_ble_power_down_dma_copy(bool copy); extern uint8_t btdm_sleep_clock_sync(void); +extern void sdk_config_extend_set_pll_track(bool enable); #if CONFIG_MAC_BB_PD extern void esp_mac_bb_power_down(void); @@ -894,25 +895,21 @@ void esp_release_wifi_and_coex_mem(void) ESP_ERROR_CHECK(try_heap_caps_add_region((intptr_t)ets_rom_layout_p->data_start_interface_coexist,(intptr_t)ets_rom_layout_p->bss_end_interface_pp)); } -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_MAC_BB_PD static void IRAM_ATTR btdm_mac_bb_power_down_cb(void) { if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd == 0) { -#if (CONFIG_MAC_BB_PD) btdm_ble_power_down_dma_copy(true); -#endif s_lp_stat.mac_bb_pd = 1; } } static void IRAM_ATTR btdm_mac_bb_power_up_cb(void) { -#if (CONFIG_MAC_BB_PD) if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd) { btdm_ble_power_down_dma_copy(false); s_lp_stat.mac_bb_pd = 0; } -#endif } #endif @@ -956,6 +953,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) // overwrite some parameters cfg->magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL; + sdk_config_extend_set_pll_track(false); + btdm_controller_mem_init(); #if CONFIG_MAC_BB_PD @@ -995,7 +994,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) s_lp_cntl.no_light_sleep = 1; if (s_lp_cntl.enable) { -#if (CONFIG_MAC_BB_PD) +#if CONFIG_MAC_BB_PD if (!btdm_deep_sleep_mem_init()) { err = ESP_ERR_NO_MEM; goto error; @@ -1040,7 +1039,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n" "light sleep mode will not be able to apply when bluetooth is enabled"); } -#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW) +#elif CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW // check whether or not EXT_CRYS is working if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_RTC) { s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator @@ -1141,7 +1140,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) s_btdm_slp_tmr = NULL; } -#if (CONFIG_MAC_BB_PD) +#if CONFIG_MAC_BB_PD if (s_lp_cntl.mac_bb_pd) { btdm_deep_sleep_mem_deinit(); s_lp_cntl.mac_bb_pd = 0; @@ -1187,7 +1186,7 @@ esp_err_t esp_bt_controller_deinit(void) // deinit low power control resources do { -#if (CONFIG_MAC_BB_PD) +#if CONFIG_MAC_BB_PD btdm_deep_sleep_mem_deinit(); #endif diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/bt/controller/esp32s2/Kconfig.in b/components/bt/controller/esp32s2/Kconfig.in new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 54a69e53616c..b877f7e1fc98 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 54a69e53616cbd3e3f3bbf150e42930a7912349a +Subproject commit b877f7e1fc98dccfcf4dbf31f215c5cb44ec3f0d diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index a8099f0c7f19..fa1c19100651 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit a8099f0c7f1976c3a6ccd44a106728c87a78b1aa +Subproject commit fa1c19100651dd9528ae551892d7de9598810b12 diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index 964f52b13f62..c333e7768914 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -9,10 +9,10 @@ if BLE_MESH config BLE_MESH_USE_DUPLICATE_SCAN bool "Support Duplicate Scan in BLE Mesh" depends on BT_BLUEDROID_ENABLED - select BTDM_BLE_SCAN_DUPL if BT_CTRL_ESP32 - select BTDM_BLE_MESH_SCAN_DUPL_EN if BT_CTRL_ESP32 - select BT_CTRL_BLE_SCAN_DUPL if BT_CTRL_ESP32C3 - select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if BT_CTRL_ESP32C3 + select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32 + select BTDM_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32 + select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3 + select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3 default y help Enable this option to allow using specific duplicate scan filter @@ -1094,6 +1094,13 @@ if BLE_MESH lets the state to be changed at any time. If IV Update test mode is going to be used, this option should be enabled. + config BLE_MESH_DISCARD_OLD_SEQ_AUTH + bool + default y + help + This option is used to decide whether discarding the old SeqAuth when + receiving a segmented message. + menu "BLE Mesh specific test option" config BLE_MESH_SELF_TEST diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 66dccf307cb5..a4676c2a9076 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -885,6 +885,8 @@ typedef enum { ESP_BLE_MESH_PROXY_CLIENT_SET_FILTER_TYPE_COMP_EVT, /*!< Proxy Client set filter type completion event */ ESP_BLE_MESH_PROXY_CLIENT_ADD_FILTER_ADDR_COMP_EVT, /*!< Proxy Client add filter address completion event */ ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT, /*!< Proxy Client remove filter address completion event */ + ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT, /*!< Proxy Server establishes connection successfully event */ + ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT, /*!< Proxy Server terminates connection successfully event */ ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT, /*!< Local model subscribes group address completion event */ ESP_BLE_MESH_MODEL_UNSUBSCRIBE_GROUP_ADDR_COMP_EVT, /*!< Local model unsubscribes group address completion event */ ESP_BLE_MESH_DEINIT_MESH_COMP_EVT, /*!< De-initialize BLE Mesh stack completion event */ @@ -1467,6 +1469,19 @@ typedef union { uint8_t conn_handle; /*!< Proxy connection handle */ uint16_t net_idx; /*!< Corresponding NetKey Index */ } proxy_client_remove_filter_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT + */ + struct ble_mesh_proxy_server_connected_param { + uint8_t conn_handle; /*!< Proxy connection handle */ + } proxy_server_connected; /*!< Event parameter of ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT */ + /** + * @brief ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT + */ + struct ble_mesh_proxy_server_disconnected_param { + uint8_t conn_handle; /*!< Proxy connection handle */ + uint8_t reason; /*!< Proxy disconnect reason */ + } proxy_server_disconnected; /*!< Event parameter of ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT */ /** * @brief ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT */ diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 6fe3da8b7ee7..0361595b5f63 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -1010,6 +1010,41 @@ static void btc_ble_mesh_proxy_client_filter_status_recv_cb(uint8_t conn_handle, } #endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ +#if CONFIG_BLE_MESH_GATT_PROXY_SERVER +static void btc_ble_mesh_proxy_server_connect_cb(uint8_t conn_handle) +{ + esp_ble_mesh_prov_cb_param_t mesh_param = {0}; + + if (conn_handle >= BLE_MESH_MAX_CONN) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + BT_DBG("%s", __func__); + + mesh_param.proxy_server_connected.conn_handle = conn_handle; + + btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT); +} + +static void btc_ble_mesh_proxy_server_disconnect_cb(uint8_t conn_handle, uint8_t reason) +{ + esp_ble_mesh_prov_cb_param_t mesh_param = {0}; + + if (conn_handle >= BLE_MESH_MAX_CONN) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + BT_DBG("%s", __func__); + + mesh_param.proxy_server_disconnected.conn_handle = conn_handle; + mesh_param.proxy_server_disconnected.reason = reason; + + btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT); +} +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ + int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model) { if (!bt_mesh_is_initialized()) { @@ -1777,6 +1812,10 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) bt_mesh_proxy_client_set_disconn_cb(btc_ble_mesh_proxy_client_disconnect_cb); bt_mesh_proxy_client_set_filter_status_cb(btc_ble_mesh_proxy_client_filter_status_recv_cb); #endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ +#if CONFIG_BLE_MESH_GATT_PROXY_SERVER + bt_mesh_proxy_server_set_conn_cb(btc_ble_mesh_proxy_server_connect_cb); + bt_mesh_proxy_server_set_disconn_cb(btc_ble_mesh_proxy_server_disconnect_cb); +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ int err_code = bt_mesh_init((struct bt_mesh_prov *)arg->mesh_init.prov, (struct bt_mesh_comp *)arg->mesh_init.comp); /* Give the semaphore when BLE Mesh initialization is finished. */ diff --git a/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c b/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c index 8602f7cd876c..055c969dd888 100644 --- a/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c +++ b/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c @@ -539,7 +539,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg) } } } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) { - if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL) { + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL && + bt_mesh_gattc_info[i].wr_desc_done) { len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn, notif_data, notif_len); if (len < 0) { diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index dcc7a0daf0fd..9e001e0a8b6c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -74,6 +74,7 @@ #define START_PAYLOAD_MAX 20 #define CONT_PAYLOAD_MAX 23 +#define START_LAST_SEG_MAX 2 #define START_LAST_SEG(gpc) (gpc >> 2) #define CONT_SEG_INDEX(gpc) (gpc >> 2) @@ -1563,6 +1564,12 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) return; } + if (START_LAST_SEG(rx->gpc) > START_LAST_SEG_MAX) { + BT_ERR("Invalid SegN 0x%02x", START_LAST_SEG(rx->gpc)); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + return; + } + if (link.rx.buf->len > link.rx.buf->size) { BT_ERR("Too large provisioning PDU (%u bytes)", link.rx.buf->len); diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c index be549ee40ee1..62f6dea53814 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -82,6 +82,7 @@ _Static_assert(BLE_MESH_MAX_CONN >= CONFIG_BLE_MESH_PBG_SAME_TIME, #define START_PAYLOAD_MAX 20 #define CONT_PAYLOAD_MAX 23 +#define START_LAST_SEG_MAX 2 #define START_LAST_SEG(gpc) (gpc >> 2) #define CONT_SEG_INDEX(gpc) (gpc >> 2) @@ -2988,6 +2989,12 @@ static void gen_prov_start(const uint8_t idx, struct prov_rx *rx, struct net_buf return; } + if (START_LAST_SEG(rx->gpc) > START_LAST_SEG_MAX) { + BT_ERR("Invalid SegN 0x%02x", START_LAST_SEG(rx->gpc)); + close_link(idx, CLOSE_REASON_FAILED); + return; + } + if (link[idx].rx.buf->len > link[idx].rx.buf->size) { BT_ERR("Too large provisioning PDU (%u bytes)", link[idx].rx.buf->len); diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c index 4d84c9a5b8ec..e9ecc885cfba 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c @@ -159,6 +159,23 @@ static void proxy_sar_timeout(struct k_work *work) } #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) +/** + * The following callbacks are used to notify proper information + * to the application layer. + */ +static proxy_server_connect_cb_t proxy_server_connect_cb; +static proxy_server_disconnect_cb_t proxy_server_disconnect_cb; + +void bt_mesh_proxy_server_set_conn_cb(proxy_server_connect_cb_t cb) +{ + proxy_server_connect_cb = cb; +} + +void bt_mesh_proxy_server_set_disconn_cb(proxy_server_disconnect_cb_t cb) +{ + proxy_server_disconnect_cb = cb; +} + /* Next subnet in queue to be advertised */ static int next_idx; @@ -605,6 +622,10 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err) client->filter_type = NONE; #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) (void)memset(client->filter, 0, sizeof(client->filter)); + + if (proxy_server_connect_cb) { + proxy_server_connect_cb(conn->handle); + } #endif net_buf_simple_reset(&client->buf); } @@ -621,6 +642,11 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason) struct bt_mesh_proxy_client *client = &clients[i]; if (client->conn == conn) { +#if CONFIG_BLE_MESH_GATT_PROXY_SERVER + if (proxy_server_disconnect_cb) { + proxy_server_disconnect_cb(conn->handle, reason); + } +#endif if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && client->filter_type == PROV) { bt_mesh_pb_gatt_close(conn); diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.h b/components/bt/esp_ble_mesh/mesh_core/proxy_server.h index e473306027ed..bfa292ca0c2a 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.h +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.h @@ -38,6 +38,9 @@ extern "C" { #define DEVICE_NAME_SIZE (BLE_MESH_GAP_ADV_MAX_LEN - 2) #endif +typedef void (*proxy_server_connect_cb_t)(uint8_t conn_handle); +typedef void (*proxy_server_disconnect_cb_t)(uint8_t conn_handle, uint8_t reason); + int bt_mesh_set_device_name(const char *name); int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type, @@ -46,6 +49,9 @@ int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type, int bt_mesh_proxy_server_prov_enable(void); int bt_mesh_proxy_server_prov_disable(bool disconnect); +void bt_mesh_proxy_server_set_conn_cb(proxy_server_connect_cb_t cb); +void bt_mesh_proxy_server_set_disconn_cb(proxy_server_disconnect_cb_t cb); + int bt_mesh_proxy_server_gatt_enable(void); int bt_mesh_proxy_server_gatt_disable(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index faac12dc3b0b..faabb6224c6a 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -1396,13 +1396,14 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, continue; } - /* Return newer RX context in addition to an exact match, so - * the calling function can properly discard an old SeqAuth. - * Note: in Zephyr v1.14.0, ">=" is used here which does not - * seem to be a right operation, hence we still use the original - * "==" here. + /* When ">=" is used, return newer RX context in addition to an exact match, + * so the calling function can properly discard an old SeqAuth. */ +#if CONFIG_BLE_MESH_DISCARD_OLD_SEQ_AUTH + if (rx->seq_auth >= *seq_auth) { +#else if (rx->seq_auth == *seq_auth) { +#endif return rx; } diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 3e4079954a0c..79a712905605 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -42,7 +42,7 @@ config BT_BLUEDROID_MEM_DEBUG config BT_CLASSIC_ENABLED bool "Classic Bluetooth" - depends on BT_BLUEDROID_ENABLED && BT_CTRL_ESP32 + depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32 default n help For now this option needs "SMP_ENABLE" to be set to yes @@ -1066,8 +1066,3 @@ config BT_BLE_42_FEATURES_SUPPORTED default n help This enables BLE 4.2 features. - -config BT_RESERVE_DRAM - hex - default 0xdb5c if BT_ENABLED - default 0 diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h index 73c8605e0784..686ad1c63e88 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h @@ -236,7 +236,7 @@ typedef enum { #define ESP_BT_GAP_MIN_INQ_LEN (0x01) /*!< Minimum inquiry duration, unit is 1.28s */ #define ESP_BT_GAP_MAX_INQ_LEN (0x30) /*!< Maximum inquiry duration, unit is 1.28s */ -/// A2DP state callback parameters +/// GAP state callback parameters typedef union { /** * @brief ESP_BT_GAP_DISC_RES_EVT @@ -347,6 +347,7 @@ typedef union { struct read_rmt_name_param { esp_bt_status_t stat; /*!< read Remote Name status */ uint8_t rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< Remote device name */ + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ } read_rmt_name; /*!< read Remote Name parameter struct */ /** diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h index 3d4999f8a7e0..8637d74a3127 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h @@ -34,6 +34,10 @@ extern "C" { #define ESP_HF_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */ #define ESP_HF_PEER_FEAT_EXTERR 0x100 /* Extended error codes */ #define ESP_HF_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */ +/* HFP 1.7+ */ +#define ESP_HF_PEER_FEAT_HF_IND 0x400 /* HF Indicators */ +#define ESP_HF_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */ + /* CHLD feature masks of HF AG */ #define ESP_HF_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */ diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h index 3c5c05b178c3..55569bc5c84a 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h @@ -60,6 +60,9 @@ typedef enum { #define ESP_HF_CLIENT_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */ #define ESP_HF_CLIENT_PEER_FEAT_EXTERR 0x100 /* Extended error codes */ #define ESP_HF_CLIENT_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */ +/* HFP 1.7+ */ +#define ESP_HF_CLIENT_PEER_FEAT_HF_IND 0x400 /* HF Indicators */ +#define ESP_HF_CLIENT_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */ /* CHLD feature masks of AG */ #define ESP_HF_CLIENT_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */ diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c index 3b7c91e501d8..c7ed0ce6fec3 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c @@ -491,14 +491,14 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) UINT16 lcid; int i; tBTA_AG_SCB *ag_scb, *other_scb; - BD_ADDR dev_addr; + BD_ADDR dev_addr = {0}; int status; /* set role */ p_scb->role = BTA_AG_ACP; APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d", p_scb->serv_handle[0], p_scb->serv_handle[1]); /* get bd addr of peer */ - if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) { + if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, FALSE, dev_addr, &lcid))) { APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status); } /* Collision Handling */ diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c index 2470c6008bc9..a517725d9f57 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c @@ -272,7 +272,7 @@ const tBTA_AG_ST_TBL bta_ag_st_tbl[] = /***************************************************************************** ** Global data *****************************************************************************/ -const char *bta_ag_version = "1.6"; +const uint16_t bta_ag_version = HFP_VERSION_1_7; /* AG control block */ #if BTA_DYNAMIC_MEMORY == FALSE tBTA_AG_CB bta_ag_cb; @@ -758,7 +758,7 @@ static void bta_ag_api_enable(tBTA_AG_DATA *p_data) bta_ag_cb.p_cback = p_data->api_enable.p_cback; bta_ag_cb.parse_mode = p_data->api_enable.parse_mode; /* check if mSBC support enabled */ - if (strcmp(bta_ag_version, "1.6") == 0) { + if (bta_ag_version >= HFP_VERSION_1_6) { bta_ag_cb.msbc_enabled = TRUE; bta_ag_cb.scb->negotiated_codec = BTM_SCO_CODEC_MSBC; } else{ diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c index 8869f846c386..49ca54af0e9b 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c @@ -47,9 +47,9 @@ void bta_ag_port_cback_1(UINT32 code, UINT16 port_handle); void bta_ag_port_cback_2(UINT32 code, UINT16 port_handle); void bta_ag_port_cback_3(UINT32 code, UINT16 port_handle); -void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle); -void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle); -void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle); +void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle, void* data); +void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle, void* data); +void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle, void* data); int bta_ag_data_cback_1(UINT16 port_handle, void *p_data, UINT16 len); int bta_ag_data_cback_2(UINT16 port_handle, void *p_data, UINT16 len); @@ -64,7 +64,8 @@ const tBTA_AG_PORT_CBACK bta_ag_port_cback_tbl[] = bta_ag_port_cback_3 }; -const tBTA_AG_PORT_CBACK bta_ag_mgmt_cback_tbl[] = +typedef tPORT_MGMT_CALLBACK *tBTA_AG_MGMT_CBACK; +const tBTA_AG_MGMT_CBACK bta_ag_mgmt_cback_tbl[] = { bta_ag_mgmt_cback_1, bta_ag_mgmt_cback_2, @@ -206,9 +207,9 @@ static int bta_ag_data_cback(UINT16 port_handle, void *p_data, UINT16 len, UINT1 ** Returns void ** *******************************************************************************/ -void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 1);} -void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 2);} -void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 3);} +void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 1);} +void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 2);} +void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 3);} void bta_ag_port_cback_1(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 1);} void bta_ag_port_cback_2(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 2);} void bta_ag_port_cback_3(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 3);} diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c index bdeb2188d0fd..a4263dde8fb1 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c @@ -70,10 +70,11 @@ enum }; #if (BTM_WBS_INCLUDED == TRUE) -#define BTA_AG_NUM_CODECS 3 -#define BTA_AG_ESCO_SETTING_IDX_CVSD 0 /* eSCO setting for CVSD */ +#define BTA_AG_NUM_CODECS 4 +#define BTA_AG_ESCO_SETTING_IDX_CVSD 0 /* eSCO setting for CVSD */ #define BTA_AG_ESCO_SETTING_IDX_T1 1 /* eSCO setting for mSBC T1 */ #define BTA_AG_ESCO_SETTING_IDX_T2 2 /* eSCO setting for mSBC T2 */ +#define BTA_AG_ESCO_SETTING_IDX_S4 3 /* eSCO setting for CVSD S4 */ static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] = { @@ -81,9 +82,9 @@ static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] = { BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ - 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ + 10, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ BTM_VOICE_SETTING_CVSD, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ - (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ + (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ BTM_SCO_PKT_TYPES_MASK_HV2 + BTM_SCO_PKT_TYPES_MASK_HV3 + BTM_SCO_PKT_TYPES_MASK_EV3 + @@ -91,7 +92,7 @@ static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] = BTM_SCO_PKT_TYPES_MASK_EV5 + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), - BTM_ESCO_RETRANS_POWER /* Retransmission effort */ + BTM_ESCO_RETRANS_POWER /* Retransmission effort */ }, /* mSBC T1 */ { @@ -104,7 +105,7 @@ static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] = BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 ), - BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ + BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ }, /* mSBC T2*/ { @@ -116,26 +117,56 @@ static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] = BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), - BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ + BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ + }, + /* HFP 1.7+ */ + /* eSCO CVSD S4 */ + { + BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ + BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ + 12, /* 12 ms (HS/HF can use EV3, 2-EV3) */ + BTM_VOICE_SETTING_CVSD, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ + (BTM_SCO_LINK_ALL_PKT_MASK | + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), + BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ } }; #else +#define BTA_AG_NUM_CODECS 2 +#define BTA_AG_ESCO_SETTING_IDX_CVSD 0 /* eSCO setting for CVSD S3 */ +#define BTA_AG_ESCO_SETTING_IDX_S4 1 /* eSCO setting for CVSD S4 */ + /* WBS not included, CVSD by default */ -static const tBTM_ESCO_PARAMS bta_ag_esco_params = +static const tBTM_ESCO_PARAMS bta_ag_esco_params[] = { - BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ - BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ - 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ - 0x0060, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ - (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ - BTM_SCO_PKT_TYPES_MASK_HV2 + - BTM_SCO_PKT_TYPES_MASK_HV3 + - BTM_SCO_PKT_TYPES_MASK_EV3 + - BTM_SCO_PKT_TYPES_MASK_EV4 + - BTM_SCO_PKT_TYPES_MASK_EV5 + - BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 + - BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), - BTM_ESCO_RETRANS_POWER /* Retransmission effort */ + { + BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ + BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ + 10, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ + BTM_VOICE_SETTING_CVSD, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ + (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ + BTM_SCO_PKT_TYPES_MASK_HV2 + + BTM_SCO_PKT_TYPES_MASK_HV3 + + BTM_SCO_PKT_TYPES_MASK_EV3 + + BTM_SCO_PKT_TYPES_MASK_EV4 + + BTM_SCO_PKT_TYPES_MASK_EV5 + + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 + + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), + BTM_ESCO_RETRANS_POWER /* Retransmission effort */ + }, + /* HFP 1.7+ */ + /* eSCO CVSD S4 */ + { + BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ + BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ + 12, /* 12 ms (HS/HF can use EV3, 2-EV3) */ + BTM_VOICE_SETTING_CVSD, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ + (BTM_SCO_LINK_ALL_PKT_MASK | + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), + BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ + } }; #endif @@ -470,9 +501,9 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig) tBTM_STATUS status; UINT8 *p_bd_addr = NULL; tBTM_ESCO_PARAMS params; + UINT8 codec_index = BTA_AG_ESCO_SETTING_IDX_CVSD; #if (BTM_WBS_INCLUDED == TRUE) tBTA_AG_PEER_CODEC esco_codec = BTM_SCO_CODEC_CVSD; - int codec_index = 0; #endif #if (BTM_SCO_HCI_INCLUDED == TRUE) tBTM_SCO_ROUTE_TYPE sco_route; @@ -513,11 +544,20 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig) codec_index = BTA_AG_ESCO_SETTING_IDX_T1; } } - params = bta_ag_esco_params[codec_index]; + /* If eSCO codec is CVSD and eSC0 S4 is supported, index is S4 */ + else if ((esco_codec == BTM_SCO_CODEC_CVSD) && (p_scb->features & BTA_AG_FEAT_ESCO_S4) + && (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) + { + codec_index = BTA_AG_ESCO_SETTING_IDX_S4; + } + #else - /* When WBS is not included, use CVSD by default */ - params = bta_ag_esco_params; + if ((p_scb->features & BTA_AG_FEAT_ESCO_S4) && (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) + { + codec_index = BTA_AG_ESCO_SETTING_IDX_S4; + } #endif + params = bta_ag_esco_params[codec_index]; if(bta_ag_cb.sco.param_updated) /* If we do not use the default parameters */ params = bta_ag_cb.sco.params; @@ -528,10 +568,13 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig) if (esco_codec == BTM_SCO_CODEC_CVSD) /* For CVSD */ #endif { - /* Use the application packet types (5 slot EV packets not allowed) */ - params.packet_types = p_bta_ag_cfg->sco_pkt_types | - BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | - BTM_SCO_PKT_TYPES_MASK_NO_3_EV5; + if (codec_index == BTA_AG_ESCO_SETTING_IDX_CVSD) + { + /* Use the application packet types (5 slot EV packets not allowed) */ + params.packet_types = p_bta_ag_cfg->sco_pkt_types | + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5; + } } } @@ -1615,6 +1658,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data if (p_data->link_type == BTM_LINK_TYPE_SCO) { + resp.retrans_effort = BTM_ESCO_RETRANS_OFF; resp.packet_types = (BTM_SCO_LINK_ONLY_MASK | BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | @@ -1623,6 +1667,13 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data } else /* Allow controller to use all types available except 5-slot EDR */ { + if ((p_scb->features & BTA_AG_FEAT_ESCO_S4) && + (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) + { + resp.max_latency = 12; + resp.retrans_effort = BTM_ESCO_RETRANS_QUALITY; + } + resp.packet_types = (BTM_SCO_LINK_ALL_PKT_MASK | BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5); diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c index 3884a7d34cce..60688c49241d 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c @@ -157,7 +157,7 @@ BOOLEAN bta_ag_add_record(UINT16 service_uuid, char *p_service_name, UINT8 scn, /* add profile descriptor list */ if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) { profile_uuid = UUID_SERVCLASS_HF_HANDSFREE; - version = HFP_VERSION_1_6; + version = HFP_VERSION_1_7; } else { profile_uuid = UUID_SERVCLASS_HEADSET; version = HSP_VERSION_1_2; diff --git a/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h b/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h index 5381c66433d5..4956916d7d5e 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h +++ b/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h @@ -48,6 +48,7 @@ #define HFP_VERSION_1_1 0x0101 #define HFP_VERSION_1_5 0x0105 #define HFP_VERSION_1_6 0x0106 +#define HFP_VERSION_1_7 0x0107 #define HSP_VERSION_1_0 0x0100 #define HSP_VERSION_1_2 0x0102 @@ -75,12 +76,12 @@ #define BTA_AG_INT 1 /* initiating connection */ /* feature mask that matches spec */ -#define BTA_AG_BSRF_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ - BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ - BTA_AG_FEAT_VTAG | BTA_AG_FEAT_REJECT | \ - BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \ - BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_CODEC | \ - BTA_AG_FEAT_VOIP) +#define BTA_AG_BSRF_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ + BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ + BTA_AG_FEAT_VTAG | BTA_AG_FEAT_REJECT | \ + BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \ + BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_CODEC | \ + BTA_AG_FEAT_ESCO_S4| BTA_AG_FEAT_VOIP) #define BTA_AG_SDP_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c index 3adaad23eed9..0e0c43addf66 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c @@ -267,7 +267,7 @@ void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data) void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data) { UINT16 lcid; - BD_ADDR dev_addr; + BD_ADDR dev_addr = {0}; int status; /* set role */ @@ -277,7 +277,7 @@ void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data) bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle); /* get bd addr of peer */ - if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) { + if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, FALSE, dev_addr, &lcid))) { APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status); } diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c index 4158f015f67f..b47ffcac6e61 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c @@ -232,7 +232,7 @@ const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = { bta_hf_client_st_closing }; -const char *bta_hf_client_version = "1.6"; +const int bta_hf_client_version = HFP_HF_VERSION_1_7; /* HF Client control block */ #if BTA_DYNAMIC_MEMORY == FALSE @@ -387,7 +387,7 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data) bta_hf_client_cb.p_cback = p_data->api_enable.p_cback; /* check if mSBC support enabled */ - if (strcmp(bta_hf_client_version, "1.6") == 0) { + if (bta_hf_client_version >= HFP_HF_VERSION_1_6) { bta_hf_client_cb.msbc_enabled = TRUE; } else{ bta_hf_client_cb.msbc_enabled = FALSE; diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_rfc.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_rfc.c index 1b140dbd9626..b64b6237027c 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_rfc.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_rfc.c @@ -70,7 +70,7 @@ static void bta_hf_client_port_cback(UINT32 code, UINT16 port_handle) ** Returns void ** *******************************************************************************/ -static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle) +static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle, void* data) { tBTA_HF_CLIENT_RFC *p_buf; UINT16 event; diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c index a6c2e45cb206..9a7c4b7bfd10 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c @@ -18,6 +18,7 @@ ******************************************************************************/ #include "bta_hf_client_int.h" +#include "bta/bta_hf_client_api.h" #include "common/bt_trace.h" #include #include "common/bt_defs.h" @@ -34,6 +35,11 @@ BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \ BTM_SCO_PKT_TYPES_MASK_NO_3_EV5) +#define BTA_HF_CLIENT_SCO_PARAM_IDX_CVSD 0 /* SCO setting for CVSD */ +#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3 1 /* eSCO setting for CVSD S3 */ +#define BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2 2 /* eSCO setting for mSBC T2 */ +#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4 3 /* eSCO setting for CVSD S4 */ + static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = { /* SCO CVSD */ { @@ -72,6 +78,19 @@ static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = { BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), .retrans_effort = BTM_ESCO_RETRANS_QUALITY, + }, + /* HFP 1.7+ */ + /* ESCO CVSD S4 */ + { + .rx_bw = BTM_64KBITS_RATE, + .tx_bw = BTM_64KBITS_RATE, + .max_latency = 12, + .voice_contfmt = BTM_VOICE_SETTING_CVSD, + /* Allow controller to use all types available except 5-slot EDR */ + .packet_types = (BTM_SCO_LINK_ALL_PKT_MASK | + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), + .retrans_effort = BTM_ESCO_RETRANS_QUALITY, } }; @@ -178,18 +197,27 @@ static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data) { tBTM_ESCO_PARAMS resp; UINT8 hci_status = HCI_SUCCESS; + UINT8 index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3; #if (BTM_SCO_HCI_INCLUDED == TRUE ) tBTA_HFP_CODEC_INFO codec_info = {BTA_HFP_SCO_CODEC_PCM}; UINT32 pcm_sample_rate; #endif - APPL_TRACE_DEBUG("%s", __FUNCTION__); + + APPL_TRACE_DEBUG("%s: negotiated codec = %d", __FUNCTION__, bta_hf_client_cb.scb.negotiated_codec); if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_LISTEN_ST) { if (p_data->link_type == BTM_LINK_TYPE_SCO) { - resp = bta_hf_client_esco_params[0]; + index = BTA_HF_CLIENT_SCO_PARAM_IDX_CVSD; } else { - resp = bta_hf_client_esco_params[bta_hf_client_cb.scb.negotiated_codec]; + if ((bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_CVSD) && + (bta_hf_client_cb.scb.features && BTA_HF_CLIENT_FEAT_ESCO_S4) && + (bta_hf_client_cb.scb.peer_features && BTA_HF_CLIENT_PEER_ESCO_S4)) { + index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4; + } else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) { + index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2; + } } + resp = bta_hf_client_esco_params[index]; /* tell sys to stop av if any */ bta_sys_sco_use(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr); @@ -350,6 +378,7 @@ static void bta_hf_client_sco_create(BOOLEAN is_orig) tBTM_STATUS status; UINT8 *p_bd_addr = NULL; tBTM_ESCO_PARAMS params; + UINT8 index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3; #if (BTM_SCO_HCI_INCLUDED == TRUE ) tBTM_SCO_ROUTE_TYPE sco_route; tBTA_HFP_CODEC_INFO codec_info = {BTA_HFP_SCO_CODEC_PCM}; @@ -364,7 +393,15 @@ static void bta_hf_client_sco_create(BOOLEAN is_orig) return; } - params = bta_hf_client_esco_params[1]; + if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_CVSD) { + if ((bta_hf_client_cb.scb.features && BTA_HF_CLIENT_FEAT_ESCO_S4) && + (bta_hf_client_cb.scb.peer_features && BTA_HF_CLIENT_PEER_ESCO_S4)) { + index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4; + } + } else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) { + index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2; + } + params = bta_hf_client_esco_params[index]; /* if initiating set current scb and peer bd addr */ if (is_orig) { diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sdp.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sdp.c index 920fcc9526e7..d21555bce014 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sdp.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sdp.c @@ -114,7 +114,7 @@ BOOLEAN bta_hf_client_add_record(char *p_service_name, UINT8 scn, /* add profile descriptor list */ profile_uuid = UUID_SERVCLASS_HF_HANDSFREE; - version = HFP_VERSION_1_6; + version = HFP_VERSION_1_7; result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version); diff --git a/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h b/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h index fd52b3aef7fe..ddfc62442d88 100644 --- a/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h +++ b/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h @@ -29,6 +29,7 @@ #define HFP_VERSION_1_1 0x0101 #define HFP_VERSION_1_5 0x0105 #define HFP_VERSION_1_6 0x0106 +#define HFP_VERSION_1_7 0x0107 /* RFCOMM MTU SIZE */ #define BTA_HF_CLIENT_MTU 256 diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h index f7c6dd6a39b2..aff63a26eabf 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h @@ -45,12 +45,16 @@ #define BTA_AG_FEAT_ECC 0x00000080 /* Enhanced Call Control */ #define BTA_AG_FEAT_EXTERR 0x00000100 /* Extended error codes */ #define BTA_AG_FEAT_CODEC 0x00000200 /* Codec Negotiation */ -#define BTA_AG_FEAT_VOIP 0x00000400 /* VoIP call */ +/* HFP 1.7+ */ +#define BTA_AG_FEAT_HF_IND 0x00000400 /* HF Indicators */ +#define BTA_AG_FEAT_ESCO_S4 0x00000800 /* eSCO S4 Setting Supported */ + /* Proprietary features: using 31 ~ 16 bits */ #define BTA_AG_FEAT_BTRH 0x00010000 /* CCAP incoming call hold */ #define BTA_AG_FEAT_UNAT 0x00020000 /* Pass unknown AT commands to application */ #define BTA_AG_FEAT_NOSCO 0x00040000 /* No SCO control performed by BTA AG */ #define BTA_AG_FEAT_NO_ESCO 0x00080000 /* Do not allow or use eSCO */ +#define BTA_AG_FEAT_VOIP 0x00100000 /* VoIP call */ typedef UINT32 tBTA_AG_FEAT; /* HFP peer features */ @@ -62,9 +66,16 @@ typedef UINT32 tBTA_AG_FEAT; #define BTA_AG_PEER_FEAT_ECS 0x0020 /* Enhanced Call Status */ #define BTA_AG_PEER_FEAT_ECC 0x0040 /* Enhanced Call Control */ #define BTA_AG_PEER_FEAT_CODEC 0x0080 /* Codec Negotiation */ -#define BTA_AG_PEER_FEAT_VOIP 0x0100 /* VoIP call */ +/* HFP 1.7+ */ +#define BTA_AG_PEER_FEAT_HF_IND 0x0100 /* HF Indicators */ +#define BTA_AG_PEER_FEAT_ESCO_S4 0x0200 /* eSCO S4 Setting Supported */ typedef UINT16 tBTA_AG_PEER_FEAT; +/* Proprietary features: using bits after 12 */ +/* Pass unknown AT command responses to application */ +#define BTA_AG_PEER_FEAT_UNAT 0x1000 +#define BTA_AG_PEER_FEAT_VOIP 0x2000 /* VoIP call */ + /* AG extended call handling - masks not related to any spec */ #define BTA_AG_CLIENT_CHLD_REL 0x00000001 /* 0 Release waiting call or held calls */ #define BTA_AG_CLIENT_CHLD_REL_ACC 0x00000002 /* 1 Release active calls and accept other (waiting or held) cal */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h index d2e760b224c0..e01b7a1c7580 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h @@ -33,6 +33,10 @@ ** Constants and data types *****************************************************************************/ +/* Hands-Free unit(HF) version */ +#define HFP_HF_VERSION_1_6 0x0106 /* v1.6 */ +#define HFP_HF_VERSION_1_7 0x0107 /* v1.7 */ + /* HFP peer (AG) features*/ #define BTA_HF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */ #define BTA_HF_CLIENT_PEER_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */ @@ -44,6 +48,9 @@ #define BTA_HF_CLIENT_PEER_ECC 0x00000080 /* Enhanced Call Control */ #define BTA_HF_CLIENT_PEER_EXTERR 0x00000100 /* Extended error codes */ #define BTA_HF_CLIENT_PEER_CODEC 0x00000200 /* Codec Negotiation */ +/* HFP 1.7+ */ +#define BTA_HF_CLIENT_PEER_HF_IND 0x00000400 /* HF Indicators */ +#define BTA_HF_CLIENT_PEER_ESCO_S4 0x00000800 /* eSCO S4 Setting Supported */ typedef UINT16 tBTA_HF_CLIENT_PEER_FEAT; @@ -56,6 +63,8 @@ typedef UINT16 tBTA_HF_CLIENT_PEER_FEAT; #define BTA_HF_CLIENT_FEAT_ECS 0x00000020 /* Enhanced Call Status */ #define BTA_HF_CLIENT_FEAT_ECC 0x00000040 /* Enhanced Call Control */ #define BTA_HF_CLIENT_FEAT_CODEC 0x00000080 /* Codec Negotiation */ +#define BTA_HF_CLIENT_FEAT_HF_IND 0x00000100 /* HF indicators */ +#define BTA_HF_CLIENT_FEAT_ESCO_S4 0x00000200 /* eSCO S4 Setting Supported */ /* HFP HF extended call handling - masks not related to any spec */ #define BTA_HF_CLIENT_CHLD_REL 0x00000001 /* 0 Release waiting call or held calls */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h index b83a9df5c565..e2d5dd53c4c5 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h @@ -299,6 +299,7 @@ typedef struct { UINT32 port_status; /* PORT status */ UINT32 handle; /* The connection handle */ BOOLEAN async; /* FALSE, if local initiates disconnect */ + void * user_data; /* piggyback caller's private data */ } tBTA_JV_RFCOMM_CLOSE; /* data associated with BTA_JV_RFCOMM_START_EVT */ diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c index f4106bbecde9..5f5217627032 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c @@ -115,7 +115,7 @@ static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE new_st); static int find_rfc_pcb(void *user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb); -static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle); +static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void* data); static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle); static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, int type); /******************************************************************************* @@ -285,7 +285,7 @@ tBTA_JV_RFC_CB *bta_jv_rfc_port_to_cb(UINT16 port_handle) return p_cb; } -static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb) +static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server) { tBTA_JV_STATUS status = BTA_JV_SUCCESS; BOOLEAN remove_server = FALSE; @@ -295,7 +295,7 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc tPORT_STATE port_state; UINT32 event_mask = BTA_JV_RFC_EV_MASK; UINT32 scn_num = (UINT32)p_cb->scn; - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; if (!p_cb || !p_pcb) { APPL_TRACE_ERROR("bta_jv_free_sr_rfc_cb, p_cb or p_pcb cannot be null"); @@ -373,10 +373,8 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc p_pcb->handle = 0; p_cb->curr_sess--; - if ((p_cb->max_sess > 1) && - (p_cb->scn != 0) && - (p_cb->curr_sess == p_cb->max_sess - 1)) { - + /* only needs a listening port when has a server */ + if (!close_server && (p_cb->max_sess > 1) && (p_cb->scn != 0)) { for (i = 0; i < p_cb->max_sess; i++) { if (p_cb->rfc_hdl[i] != 0) { p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1]; @@ -386,8 +384,8 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc used++; } } - APPL_TRACE_DEBUG("%s max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", - __func__, p_cb->max_sess, used, p_cb->curr_sess, listen, si); + APPL_TRACE_DEBUG("%s max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", __func__, p_cb->max_sess, used, + p_cb->curr_sess, listen, si); if (used < p_cb->max_sess && listen == 0 && 0 <= si && @@ -430,9 +428,6 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc p_cb->handle = 0; p_cb->curr_sess = -1; } - if (remove_server) { - bta_jv_free_sec_id(&p_cb->sec_id); - } } return status; } @@ -592,8 +587,8 @@ static tBTA_JV_PM_CB *bta_jv_alloc_set_pm_profile_cb(UINT32 jv_handle, tBTA_JV_P for (j = 0; j < BTA_JV_MAX_RFC_CONN; j++) { if (jv_handle == bta_jv_cb.port_cb[j].handle) { pp_cb = &bta_jv_cb.port_cb[j].p_pm_cb; - if (PORT_SUCCESS != PORT_CheckConnection( - bta_jv_cb.port_cb[j].port_handle, peer_bd_addr, NULL)) { + if (PORT_SUCCESS != + PORT_CheckConnection(bta_jv_cb.port_cb[j].port_handle, FALSE, peer_bd_addr, NULL)) { i = BTA_JV_PM_MAX_NUM; } break; @@ -1205,7 +1200,7 @@ void bta_jv_delete_record(tBTA_JV_MSG *p_data) static void bta_jv_l2cap_client_cback(UINT16 gap_handle, UINT16 event) { tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) { return; @@ -1360,7 +1355,7 @@ void bta_jv_l2cap_close(tBTA_JV_MSG *p_data) static void bta_jv_l2cap_server_cback(UINT16 gap_handle, UINT16 event) { tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; tBTA_JV_L2CAP_CBACK *p_cback; void *user_data; @@ -1666,12 +1661,12 @@ static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, ** Returns void ** *******************************************************************************/ -static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle) +static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* data) { tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle); tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); - tBTA_JV evt_data; - BD_ADDR rem_bda; + tBTA_JV evt_data = {0}; + BD_ADDR rem_bda = {0}; UINT16 lcid; tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */ @@ -1683,7 +1678,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle) APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback code=%d port_handle:%d handle:%d", code, port_handle, p_cb->handle); - PORT_CheckConnection(port_handle, rem_bda, &lcid); + PORT_CheckConnection(port_handle, FALSE, rem_bda, &lcid); if (code == PORT_SUCCESS) { evt_data.rfc_open.handle = p_pcb->handle; @@ -1722,7 +1717,7 @@ static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle) { tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle); tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) { @@ -1863,7 +1858,7 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data) tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close); tBTA_JV_RFC_CB *p_cb = NULL; tBTA_JV_PCB *p_pcb = NULL; - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; APPL_TRACE_DEBUG("%s, rfc handle:%d",__func__, cc->handle); if (!cc->handle) { APPL_TRACE_ERROR("%s, rfc handle is null", __func__); @@ -1887,7 +1882,7 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data) } cc->p_cback(BTA_JV_RFCOMM_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data); } - bta_jv_free_rfc_cb(p_cb, p_pcb); + bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE); APPL_TRACE_DEBUG("%s: sec id in use:%d, rfc_cb in use:%d",__func__, get_sec_id_used(), get_rfc_cb_used()); } @@ -1930,39 +1925,89 @@ static UINT8 __attribute__((unused)) bta_jv_get_num_rfc_listen(tBTA_JV_RFC_CB *p ** Returns void ** *******************************************************************************/ -static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle) +static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *data) { tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle); - tBTA_JV evt_data; - BD_ADDR rem_bda; + tBTA_JV evt_data = {0}; + BD_ADDR rem_bda = {0}; UINT16 lcid; + tPORT_MGMT_SR_CALLBACK_ARG *p_mgmt_cb_arg = (tPORT_MGMT_SR_CALLBACK_ARG *)data; + void *user_data = NULL; + void *new_user_data = NULL; + int status; + int failed = TRUE; + // APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:0x%x, port_handle:%d", code, (uint16_t)port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) { // APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p", // p_cb, p_cb ? p_cb->p_cback : NULL); return; } - void *user_data = p_pcb->user_data; + user_data = p_pcb->user_data; // APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%p port_handle:0x%x handle:0x%x, p_pcb:%p, user:%p", // code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data); - PORT_CheckConnection(port_handle, rem_bda, &lcid); - int failed = TRUE; + if (p_mgmt_cb_arg) { + if ((status = PORT_CheckConnection(port_handle, p_mgmt_cb_arg->ignore_rfc_state, rem_bda, &lcid)) != + PORT_SUCCESS) { + APPL_TRACE_WARNING("PORT_CheckConnection status:%d", status); + } + } else { + PORT_CheckConnection(port_handle, FALSE, rem_bda, &lcid); + } + if (code == PORT_SUCCESS) { + failed = FALSE; + /* accept the connection defaulted */ + if (p_mgmt_cb_arg) { + p_mgmt_cb_arg->accept = TRUE; + } evt_data.rfc_srv_open.handle = p_pcb->handle; evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda); tBTA_JV_PCB *p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb); if (p_pcb_new_listen) { evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle; - p_pcb_new_listen->user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data); - APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess); - failed = FALSE; + new_user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data); + if (new_user_data) { + p_pcb_new_listen->user_data = new_user_data; + APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, + p_cb->max_sess); + } else { + /** + * new_user_data is NULL, which means the upper layer runs out of slot source. + * Tells the caller to reject this connection. + */ + APPL_TRACE_ERROR("create new listen port, but upper layer reject connection"); + p_pcb_new_listen->user_data = NULL; + p_pcb->state = BTA_JV_ST_SR_LISTEN; + bta_jv_free_rfc_cb(p_cb, p_pcb_new_listen, FALSE); + if (p_mgmt_cb_arg) { + p_mgmt_cb_arg->accept = FALSE; + } + } } else { + evt_data.rfc_srv_open.new_listen_handle = 0; + new_user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data); + if (new_user_data) { + APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, + p_cb->max_sess); + } else { + /** + * new_user_data is NULL, which means the upper layer runs out of slot source. + * Tells the caller to reject this connection. + */ + APPL_TRACE_ERROR("no listen port, and upper layer reject connection"); + p_pcb->state = BTA_JV_ST_SR_LISTEN; + if (p_mgmt_cb_arg) { + p_mgmt_cb_arg->accept = FALSE; + } + } APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port"); } } + if (failed) { evt_data.rfc_close.handle = p_pcb->handle; evt_data.rfc_close.status = BTA_JV_FAILURE; @@ -1999,7 +2044,7 @@ static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle) { tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle); - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; if (NULL == p_cb || NULL == p_cb->p_cback) { return; @@ -2067,6 +2112,7 @@ static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb } } + p_pcb = NULL; APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", p_cb->max_sess, used, p_cb->curr_sess, listen, si); if (used < p_cb->max_sess && listen == 1 && si) { @@ -2094,7 +2140,6 @@ static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb } } else { /* avoid p_pcb always points to the last element of rfc_hdl */ - p_pcb = p_pcb_open; APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port"); } } @@ -2214,7 +2259,7 @@ void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data) } APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d", p_pcb, p_pcb->port_handle); - bta_jv_free_rfc_cb(p_cb, p_pcb); + bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE); APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d", get_sec_id_used(), get_rfc_cb_used()); } @@ -2750,7 +2795,7 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf) { - tBTA_JV evt_data; + tBTA_JV evt_data = {0}; // tBTA_JV evt_open; struct fc_channel *tc; struct fc_client *t = NULL; diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c index 732ab503f840..814b408c9fbb 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /***************************************************************************** * @@ -33,7 +25,7 @@ #if BTC_AV_INCLUDED typedef struct { - BOOLEAN data_channel_open; + BOOLEAN data_channel_open; /* used only by A2DP sink */ UINT8 a2dp_cmd_pending; /* we can have max one command pending */ } tBTC_AA_CTRL_CB; @@ -83,7 +75,9 @@ static void btc_a2dp_datapath_open(void) btc_a2dp_source_encoder_update(); } #endif +#if (BTC_AV_SINK_INCLUDED == TRUE) btc_aa_ctrl_cb.data_channel_open = TRUE; +#endif } BOOLEAN btc_a2dp_control_get_datachnl_stat(void) @@ -96,22 +90,6 @@ void btc_a2dp_control_set_datachnl_stat(BOOLEAN open) btc_aa_ctrl_cb.data_channel_open = open; } -static void btc_a2dp_dispatch_datapath_evt(uint32_t dp_evt) -{ - btc_msg_t msg; - msg.sig = BTC_SIG_API_CALL; - msg.pid = BTC_PID_A2DP; - msg.act = BTC_AV_DATAPATH_CTRL_EVT; - - btc_av_args_t arg; - memset(&arg, 0, sizeof(btc_av_args_t)); - arg.dp_evt = dp_evt; - - /* Switch to BTC context */ - APPL_TRACE_DEBUG("%s sig %u act %u, dp_evt %u\n", __func__, msg.sig, msg.act, arg.dp_evt); - btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL); -} - void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl) { APPL_TRACE_DEBUG("BTC MEDIA (A2DP-DATA) EVENT %u", ctrl); @@ -146,17 +124,14 @@ void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl) break; case ESP_A2D_MEDIA_CTRL_START: if (btc_av_stream_ready() == TRUE ) { - /* post start event and wait for audio path to open */ + /* post start event */ btc_dispatch_sm_event(BTC_AV_START_STREAM_REQ_EVT, NULL, 0); - - btc_a2dp_dispatch_datapath_evt(BTC_AV_DATAPATH_OPEN_EVT); #if (BTC_AV_SINK_INCLUDED == TRUE) if (btc_av_get_peer_sep() == AVDT_TSEP_SRC && btc_av_get_service_id() == BTA_A2DP_SINK_SERVICE_ID) { btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS); } #endif } else if (btc_av_stream_started_ready()) { - btc_a2dp_dispatch_datapath_evt(BTC_AV_DATAPATH_OPEN_EVT); btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS); } else { btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE); diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c index 1316bbfb496f..999796732a0e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c @@ -110,12 +110,18 @@ typedef struct { UINT32 sample_rate; } tBTC_A2DP_SINK_CB; +typedef struct { + uint16_t expected_seq_num; + bool seq_num_recount; +} a2dp_sink_media_pkt_seq_num_t; + typedef struct { tBTC_A2DP_SINK_CB btc_aa_snk_cb; osi_thread_t *btc_aa_snk_task_hdl; OI_CODEC_SBC_DECODER_CONTEXT context; OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)]; OI_INT16 pcmData[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS]; + a2dp_sink_media_pkt_seq_num_t media_pkt_seq_num; } a2dp_sink_local_param_t; static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context); @@ -319,6 +325,10 @@ static BOOLEAN btc_a2dp_sink_clear_track(void) void btc_a2dp_sink_set_rx_flush(BOOLEAN enable) { APPL_TRACE_EVENT("## DROP RX %d ##\n", enable); + if (enable == FALSE) { + a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num = 0x1; + a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount = true; + } a2dp_sink_local_param.btc_aa_snk_cb.rx_flush = enable; } @@ -549,6 +559,18 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg) return; } + if (p_msg->layer_specific != a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num) { + /* Because the sequence number of some devices is not recounted */ + if (!a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount || + a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num != 0x1) { + APPL_TRACE_WARNING("Sequence numbers error, recv:0x%x, expect:0x%x, recount:0x%x", + p_msg->layer_specific, a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num, + a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount); + } + } + a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num = p_msg->layer_specific + 1; + a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount = false; + APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d\n", num_sbc_frames, sbc_frame_len); for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++) { diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c index 8accd9b55074..b35ac83fa555 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /****************************************************************************** ** @@ -1579,7 +1571,6 @@ static void btc_a2dp_source_thread_init(UNUSED_ATTR void *context) static void btc_a2dp_source_thread_cleanup(UNUSED_ATTR void *context) { - btc_a2dp_control_set_datachnl_stat(FALSE); /* Clear media task flag */ btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF; diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c index 52003751a29b..f198294d50bc 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /***************************************************************************** * @@ -681,6 +673,9 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) /* pending start flag will be cleared when exit current state */ } #endif /* BTC_AV_SRC_INCLUDED */ + /* wait for audio path to open */ + btc_a2dp_control_datapath_ctrl(BTC_AV_DATAPATH_OPEN_EVT); + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_STARTED); } break; @@ -1509,10 +1504,6 @@ void btc_a2dp_call_handler(btc_msg_t *msg) btc_a2dp_control_media_ctrl(arg->ctrl); break; } - case BTC_AV_DATAPATH_CTRL_EVT: { - btc_a2dp_control_datapath_ctrl(arg->dp_evt); - break; - } case BTC_AV_CONNECT_REQ_EVT: btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (char *)msg->arg); break; diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c index ae4ba15fc098..cad83abf4a9b 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -743,6 +743,7 @@ static void btc_gap_bt_read_remote_name_cmpl_callback(void *p_data) msg.pid = BTC_PID_GAP_BT; msg.act = BTC_GAP_BT_READ_REMOTE_NAME_EVT; + memcpy(param.read_rmt_name.bda,result->bd_addr,BD_ADDR_LEN); param.read_rmt_name.stat = btc_btm_status_to_esp_status(result->status); memcpy(param.read_rmt_name.rmt_name,result->remote_bd_name,ESP_BT_GAP_MAX_BDNAME_LEN); diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c index caffc76c0870..ef04498bc8ec 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c @@ -1,20 +1,8 @@ -/****************************************************************************** +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * - * Copyright (C) 2009-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ + * SPDX-License-Identifier: Apache-2.0 + */ /************************************************************************************ * @@ -68,6 +56,7 @@ static hf_local_param_t *hf_local_param; BTA_AG_FEAT_VREC | \ BTA_AG_FEAT_INBAND | \ BTA_AG_FEAT_CODEC | \ + BTA_AG_FEAT_ESCO_S4| \ BTA_AG_FEAT_UNAT) #endif #else @@ -78,6 +67,7 @@ static hf_local_param_t *hf_local_param; BTA_AG_FEAT_EXTERR | \ BTA_AG_FEAT_VREC | \ BTA_AG_FEAT_INBAND | \ + BTA_AG_FEAT_ESCO_S4| \ BTA_AG_FEAT_UNAT) #endif #endif diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c index 21c92c8c5453..d06f26172b9d 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c @@ -51,13 +51,13 @@ #endif #ifndef BTC_HF_CLIENT_FEATURES -#define BTC_HF_CLIENT_FEATURES ( BTA_HF_CLIENT_FEAT_ECNR | \ - BTA_HF_CLIENT_FEAT_3WAY | \ - BTA_HF_CLIENT_FEAT_CLI | \ - BTA_HF_CLIENT_FEAT_VREC | \ - BTA_HF_CLIENT_FEAT_VOL | \ - BTA_HF_CLIENT_FEAT_ECS | \ - BTA_HF_CLIENT_FEAT_ECC | \ +#define BTC_HF_CLIENT_FEATURES ( BTA_HF_CLIENT_FEAT_ECNR | \ + BTA_HF_CLIENT_FEAT_3WAY | \ + BTA_HF_CLIENT_FEAT_CLI | \ + BTA_HF_CLIENT_FEAT_VREC | \ + BTA_HF_CLIENT_FEAT_VOL | \ + BTA_HF_CLIENT_FEAT_ECS | \ + BTA_HF_CLIENT_FEAT_ECC | \ BTA_HF_CLIENT_FEAT_CODEC) #endif @@ -66,7 +66,7 @@ /************************************************************************************ ** Static variables ************************************************************************************/ -const char *btc_hf_client_version = "1.6"; +const int btc_hf_client_version = HFP_HF_VERSION_1_7; #if HFP_DYNAMIC_MEMORY == FALSE static hf_client_local_param_t hf_client_local_param; @@ -200,7 +200,7 @@ static bt_status_t connect_int( bt_bdaddr_t *bd_addr, uint16_t uuid ) bt_status_t btc_hf_client_connect( bt_bdaddr_t *bd_addr ) { - BTC_TRACE_EVENT("HFP Client version is %s", btc_hf_client_version); + BTC_TRACE_EVENT("HFP Client version is 0x%04x", btc_hf_client_version); CHECK_HF_CLIENT_INIT(); return btc_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int); } @@ -690,33 +690,36 @@ bt_status_t btc_hf_client_execute_service(BOOLEAN b_enable) { BTC_TRACE_EVENT("%s enable:%d", __FUNCTION__, b_enable); - if (b_enable) - { - /* Enable and register with BTA-HFClient */ - BTA_HfClientEnable(bte_hf_client_evt); - if (strcmp(btc_hf_client_version, "1.6") == 0) - { - BTC_TRACE_EVENT("Support Codec Nego. %d ", BTC_HF_CLIENT_FEATURES); - BTA_HfClientRegister(BTC_HF_CLIENT_SECURITY, BTC_HF_CLIENT_FEATURES, - BTC_HF_CLIENT_SERVICE_NAME); - } - else - { - BTC_TRACE_EVENT("No Codec Nego Supported"); - hf_client_local_param.btc_hf_client_features = BTC_HF_CLIENT_FEATURES; - hf_client_local_param.btc_hf_client_features = hf_client_local_param.btc_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC); - BTC_TRACE_EVENT("hf_client_local_param.btc_hf_client_features is %d", hf_client_local_param.btc_hf_client_features); - BTA_HfClientRegister(BTC_HF_CLIENT_SECURITY, hf_client_local_param.btc_hf_client_features, - BTC_HF_CLIENT_SERVICE_NAME); - } - - } - else - { - BTA_HfClientDeregister(hf_client_local_param.btc_hf_client_cb.handle); - BTA_HfClientDisable(); - } - return BT_STATUS_SUCCESS; + if (b_enable) + { + /* Enable and register with BTA-HFClient */ + BTA_HfClientEnable(bte_hf_client_evt); + hf_client_local_param.btc_hf_client_features = BTC_HF_CLIENT_FEATURES; + if (btc_hf_client_version >= HFP_HF_VERSION_1_7) + { + hf_client_local_param.btc_hf_client_features |= BTA_HF_CLIENT_FEAT_ESCO_S4; + BTC_TRACE_EVENT("eSCO S4 Setting Supported"); + + } + else if (btc_hf_client_version >= HFP_HF_VERSION_1_6) + { + BTC_TRACE_EVENT("No eSCO S4 Setting Supported"); + } + else + { + BTC_TRACE_EVENT("No Codec Nego Supported"); + hf_client_local_param.btc_hf_client_features = hf_client_local_param.btc_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC); + } + BTC_TRACE_EVENT("hf_client_local_param.btc_hf_client_features is %d", hf_client_local_param.btc_hf_client_features); + BTA_HfClientRegister(BTC_HF_CLIENT_SECURITY, hf_client_local_param.btc_hf_client_features, + BTC_HF_CLIENT_SERVICE_NAME); + } + else + { + BTA_HfClientDeregister(hf_client_local_param.btc_hf_client_cb.handle); + BTA_HfClientDisable(); + } + return BT_STATUS_SUCCESS; } static void process_ind_evt(tBTA_HF_CLIENT_IND *ind) diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h index 553f0ddec756..c4fd1ac16b28 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* @@ -79,7 +71,6 @@ typedef enum { BTC_AV_SRC_API_REG_DATA_CB_EVT, #endif /* BTC_AV_SRC_INCLUDED */ BTC_AV_API_MEDIA_CTRL_EVT, - BTC_AV_DATAPATH_CTRL_EVT, } btc_av_act_t; /* btc_av_args_t */ @@ -104,8 +95,6 @@ typedef union { #endif /* BTC_AV_SRC_INCLUDED */ // BTC_AV_API_MEDIA_CTRL_EVT esp_a2d_media_ctrl_t ctrl; - // BTC_AV_DATAPATH_CTRL_EVT - uint32_t dp_evt; } btc_av_args_t; /******************************************************************************* diff --git a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c index 89b80b4be1ca..025500407f00 100644 --- a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c +++ b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include @@ -55,8 +47,9 @@ typedef struct { } slot_data_t; typedef struct { - uint8_t serial; bool connected; + bool is_server; + uint8_t serial; uint8_t scn; uint8_t max_session; uint32_t id; @@ -137,29 +130,39 @@ static spp_slot_t *spp_malloc_slot(void) (*slot)->sdp_handle = 0; (*slot)->rfc_handle = 0; (*slot)->rfc_port_handle = 0; - (*slot)->connected = FALSE; + (*slot)->fd = -1; + (*slot)->connected = false; + (*slot)->is_server = false; (*slot)->write_data = NULL; (*slot)->close_alarm = NULL; + /* clear the old event bits */ + if (spp_local_param.tx_event_group) { + xEventGroupClearBits(spp_local_param.tx_event_group, SLOT_WRITE_BIT(i) | SLOT_CLOSE_BIT(i)); + } + if (init_slot_data(&(*slot)->rx, QUEUE_SIZE_MAX)) { BTC_TRACE_ERROR("%s unable to malloc rx queue!", __func__); err_no = 1; - break; + goto err; } if (init_slot_data(&(*slot)->tx, SLOT_TX_QUEUE_SIZE)) { BTC_TRACE_ERROR("%s unable to malloc tx queue!", __func__); err_no = 2; - break; + goto err; } if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) { if (esp_vfs_register_fd(spp_local_param.spp_vfs_id, &(*slot)->fd) != ESP_OK) { BTC_TRACE_ERROR("%s unable to register fd!", __func__); err_no = 3; - break; + goto err; } } return (*slot); } } + + return NULL; +err: switch (err_no) { case 3: free_slot_data(&(*slot)->tx); @@ -177,9 +180,11 @@ static spp_slot_t *spp_malloc_slot(void) static spp_slot_t *spp_find_slot_by_id(uint32_t id) { + spp_slot_t *slot = NULL; for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->id == id) { - return spp_local_param.spp_slots[i]; + slot = spp_local_param.spp_slots[i]; + if (slot != NULL && slot->id == id) { + return slot; } } return NULL; @@ -187,9 +192,11 @@ static spp_slot_t *spp_find_slot_by_id(uint32_t id) static spp_slot_t *spp_find_slot_by_handle(uint32_t handle) { + spp_slot_t *slot = NULL; for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->rfc_handle == handle) { - return spp_local_param.spp_slots[i]; + slot = spp_local_param.spp_slots[i]; + if (slot != NULL && slot->rfc_handle == handle) { + return slot; } } return NULL; @@ -197,9 +204,11 @@ static spp_slot_t *spp_find_slot_by_handle(uint32_t handle) static spp_slot_t *spp_find_slot_by_fd(int fd) { + spp_slot_t *slot = NULL; for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->fd == fd) { - return spp_local_param.spp_slots[i]; + slot = spp_local_param.spp_slots[i]; + if (slot != NULL && slot->fd == fd) { + return slot; } } return NULL; @@ -207,9 +216,11 @@ static spp_slot_t *spp_find_slot_by_fd(int fd) static spp_slot_t *spp_find_slot_by_scn(uint32_t scn) { + spp_slot_t *slot = NULL; for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->scn == (uint8_t)scn) { - return spp_local_param.spp_slots[i]; + slot = spp_local_param.spp_slots[i]; + if (slot != NULL && slot->is_server && slot->scn == (uint8_t)scn) { + return slot; } } return NULL; @@ -277,9 +288,9 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u bt_status_t status; btc_msg_t msg; void *new_user_data = NULL; - - uint32_t id = (uintptr_t)user_data; + uint32_t id = (uintptr_t)user_data, id_temp = 0; spp_slot_t *slot = NULL, *slot_new = NULL; + if (!is_spp_init()) { BTC_TRACE_WARNING("%s SPP have been deinit, incoming events ignore!\n", __func__); return new_user_data; @@ -289,7 +300,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u case BTA_JV_RFCOMM_START_EVT: slot = spp_find_slot_by_id(id); if (!slot) { - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); p_data->rfc_start.status = ESP_SPP_NO_CONNECTION; break; } @@ -299,46 +310,70 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u case BTA_JV_RFCOMM_SRV_OPEN_EVT: slot = p_data->rfc_srv_open.handle ? spp_find_slot_by_id(id) : spp_find_slot_by_scn((uint32_t)user_data); if (!slot) { - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); p_data->rfc_srv_open.status = ESP_SPP_NO_CONNECTION; break; } - if (p_data->rfc_srv_open.handle) { - new_user_data = (void *)(uintptr_t)slot->id; - memcpy(slot->addr, p_data->rfc_srv_open.rem_bda, ESP_BD_ADDR_LEN); - slot->connected = TRUE; - slot->rfc_handle = p_data->rfc_srv_open.handle; - slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.handle); - BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN); - } - - if (p_data->rfc_srv_open.handle != p_data->rfc_srv_open.new_listen_handle) { + if (!p_data->rfc_srv_open.handle) { + /* match with the exist server solt */ + slot->rfc_handle = p_data->rfc_srv_open.new_listen_handle; + slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot->rfc_handle); + } else { slot_new = spp_malloc_slot(); if (!slot_new) { BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__); p_data->rfc_srv_open.status = ESP_SPP_NO_RESOURCE; break; } - new_user_data = (void *)(uintptr_t)slot_new->id; + slot_new->connected = true; slot_new->security = slot->security; slot_new->role = slot->role; slot_new->scn = slot->scn; slot_new->max_session = slot->max_session; strcpy(slot_new->service_name, slot->service_name); slot_new->sdp_handle = slot->sdp_handle; - slot_new->rfc_handle = p_data->rfc_srv_open.new_listen_handle; - slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.new_listen_handle); + slot_new->rfc_handle = p_data->rfc_srv_open.handle; + slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle); + BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN); + + if (p_data->rfc_srv_open.new_listen_handle) { + slot->rfc_handle = p_data->rfc_srv_open.new_listen_handle; + slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot->rfc_handle); + } else { + /* means lower layer can alloc port */ + slot->rfc_handle = 0; + slot->rfc_port_handle = 0; + } + /* swap slot id */ + id_temp = slot->id; + slot->id = slot_new->id; + slot_new->id = id_temp; + } + new_user_data = (void *)(uintptr_t)slot->id; + break; + case BTA_JV_RFCOMM_CL_INIT_EVT: + slot = spp_find_slot_by_id(id); + if (!slot) { + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); + p_data->rfc_cl_init.status = ESP_SPP_FAILURE; + break; + } + + if (p_data->rfc_cl_init.status == BTA_JV_SUCCESS) { + slot->rfc_handle = p_data->rfc_cl_init.handle; + } else { + spp_free_slot(slot); } break; case BTA_JV_RFCOMM_OPEN_EVT: slot = spp_find_slot_by_id(id); if (!slot) { - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); p_data->rfc_open.status = ESP_SPP_NO_CONNECTION; break; } - slot->connected = TRUE; + slot->connected = true; slot->rfc_handle = p_data->rfc_open.handle; slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle); BTA_JvSetPmProfile(p_data->rfc_open.handle, BTA_JV_PM_ID_1, BTA_JV_CONN_OPEN); @@ -346,14 +381,15 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u case BTA_JV_RFCOMM_CLOSE_EVT: slot = spp_find_slot_by_id(id); if (!slot) { - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); p_data->rfc_close.status = ESP_SPP_NO_CONNECTION; break; } - if (slot->connected && p_data->rfc_close.port_status != PORT_LOCAL_CLOSED) { + if (slot->rfc_handle && p_data->rfc_close.port_status != PORT_LOCAL_CLOSED) { BTA_JvRfcommClose(slot->rfc_handle, NULL, (void *)slot->id); } p_data->rfc_close.status = BTA_JV_SUCCESS; + p_data->rfc_close.user_data = (void *)(uintptr_t)slot->id; break; case BTA_JV_RFCOMM_DATA_IND_EVT: break; @@ -364,7 +400,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u if (slot) { spp_free_slot(slot); } else { - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); p_data->free_scn.status = ESP_SPP_NO_CONNECTION; } osi_free(user_data); @@ -401,7 +437,7 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d slot = spp_find_slot_by_id(id); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } if (p_data->scn == 0) { @@ -421,7 +457,7 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d slot = spp_find_slot_by_id(id); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } if (p_data->create_rec.status == BTA_JV_SUCCESS) { @@ -483,6 +519,7 @@ static void btc_spp_init(btc_spp_args_t *arg) } if ((spp_local_param.tx_event_group = xEventGroupCreate()) == NULL) { BTC_TRACE_ERROR("%s create tx_event_group failed\n", __func__); + osi_mutex_free(&spp_local_param.spp_slot_mutex); ret = ESP_SPP_NO_RESOURCE; break; } @@ -510,14 +547,14 @@ static void btc_spp_uninit(void) osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); // first, remove all connection for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) { + if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server) { BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)spp_local_param.spp_slots[i]->id); } } // second, remove all server for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected) { + if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server) { if (spp_local_param.spp_slots[i]->sdp_handle > 0) { BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle); } @@ -546,11 +583,6 @@ static void btc_spp_uninit(void) osi_mutex_unlock(&spp_local_param.spp_slot_mutex); } while(0); - if (spp_local_param.tx_event_group) { - vEventGroupDelete(spp_local_param.tx_event_group); - spp_local_param.tx_event_group = NULL; - } - if (ret != ESP_SPP_SUCCESS) { esp_spp_cb_param_t param; param.uninit.status = ret; @@ -669,6 +701,10 @@ static void btc_spp_start_srv(btc_spp_args_t *arg) ret = ESP_SPP_NO_RESOURCE; break; } + /** + * make this slot become a listening slot + */ + slot->is_server = true; slot->security = arg->start_srv.sec_mask; slot->role = arg->start_srv.role; slot->scn = arg->start_srv.local_scn; @@ -738,7 +774,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg) // [2] remove all local related connection for (j = 0; j < srv_cnt; j++) { for (i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected && + if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server && spp_local_param.spp_slots[i]->sdp_handle > 0 && spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, @@ -751,7 +787,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg) // [3] remove all server for (j = 0; j < srv_cnt; j++) { for (i = 1; i <= MAX_RFC_PORTS; i++) { - if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected && + if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server && spp_local_param.spp_slots[i]->sdp_handle > 0 && spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { if (spp_local_param.spp_slots[i]->sdp_handle > 0) { @@ -933,7 +969,9 @@ void btc_spp_cb_handler(btc_msg_t *msg) tBTA_JV *p_data = (tBTA_JV *)msg->arg; spp_slot_t *slot = NULL; uint8_t serial = 0; - switch (msg->act) { + uint8_t event = msg->act; + + switch (event) { case BTA_JV_ENABLE_EVT: param.init.status = p_data->status; btc_spp_cb_to_app(ESP_SPP_INIT_EVT, ¶m); @@ -960,12 +998,14 @@ void btc_spp_cb_handler(btc_msg_t *msg) slot = spp_find_slot_by_handle(p_data->rfc_open.handle); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); param.open.status = ESP_SPP_NO_CONNECTION; break; } param.open.fd = slot->fd; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); + } else { + param.open.fd = -1; } param.open.status = p_data->rfc_open.status; } while (0); @@ -989,12 +1029,14 @@ void btc_spp_cb_handler(btc_msg_t *msg) slot = spp_find_slot_by_handle(p_data->rfc_srv_open.handle); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); param.srv_open.status = ESP_SPP_NO_CONNECTION; break; } param.srv_open.fd = slot->fd; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); + } else { + param.srv_open.fd = -1; } param.srv_open.status = p_data->rfc_srv_open.status; } while (0); @@ -1024,6 +1066,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) BT_HDR *p_buf; serial = slot->serial; if ((p_buf = fixed_queue_try_peek_first(slot->tx.queue)) == NULL) { + osi_mutex_unlock(&spp_local_param.spp_slot_mutex); break; } if (p_data->rfc_write.status == BTA_JV_SUCCESS) { @@ -1065,10 +1108,11 @@ void btc_spp_cb_handler(btc_msg_t *msg) if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) { btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m); osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - slot = spp_find_slot_by_handle(p_data->rfc_close.handle); + uint32_t id = (uintptr_t)p_data->rfc_close.user_data; + slot = spp_find_slot_by_id(id); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } spp_free_slot(slot); @@ -1077,11 +1121,12 @@ void btc_spp_cb_handler(btc_msg_t *msg) bool need_call = true; do { osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - slot = spp_find_slot_by_handle(p_data->rfc_close.handle); + uint32_t id = (uintptr_t)p_data->rfc_close.user_data; + slot = spp_find_slot_by_id(id); if (!slot) { param.close.status = ESP_SPP_NO_CONNECTION; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } // if rx still has data, delay free slot @@ -1110,8 +1155,8 @@ void btc_spp_cb_handler(btc_msg_t *msg) BTC_TRACE_ERROR("%s set slot close_alarm failed!", __func__); break; } - BTC_TRACE_WARNING("%s slot rx data will be discard in %d seconds!", __func__, - VFS_CLOSE_TIMEOUT / 1000); + BTC_TRACE_WARNING("%s slot rx data will be discard in %d milliseconds!", + __func__, VFS_CLOSE_TIMEOUT); slot->connected = false; need_call = false; } @@ -1137,7 +1182,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) slot = spp_find_slot_by_handle(p_data->rfc_cong.handle); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } if (!p_data->rfc_cong.cong) { @@ -1159,7 +1204,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) slot = spp_find_slot_by_handle(p_data->data_ind.handle); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } serial = slot->serial; @@ -1207,6 +1252,10 @@ void btc_spp_cb_handler(btc_msg_t *msg) param.uninit.status = ESP_SPP_SUCCESS; BTA_JvFree(); osi_mutex_free(&spp_local_param.spp_slot_mutex); + if (spp_local_param.tx_event_group) { + vEventGroupDelete(spp_local_param.tx_event_group); + spp_local_param.tx_event_group = NULL; + } #if SPP_DYNAMIC_MEMORY == TRUE osi_free(spp_local_param_ptr); spp_local_param_ptr = NULL; @@ -1416,7 +1465,7 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size) slot = spp_find_slot_by_fd(fd); if (!slot) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); - BTC_TRACE_ERROR("%s unable to find RFCOMM slot!\n", __func__); + BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); errno = ENOENT; return -1; } @@ -1441,6 +1490,14 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size) break; } } else { + /** + * If close_alarm is not NULL, it means that we have received the BTA_JV_RFCOMM_CLOSE_EVT. + * And we can trigger close_alarm immediately. + */ + if (slot->close_alarm && osi_alarm_is_active(slot->close_alarm)) { + osi_alarm_cancel(slot->close_alarm); + osi_alarm_set(slot->close_alarm, 0); + } osi_mutex_unlock(&spp_local_param.spp_slot_mutex); break; } diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index d652ead5fbe7..85732cd06e33 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -178,9 +178,9 @@ #define UC_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD 20 #endif -#endif //CONFIG_BT_CTRL_ESP32 +#endif //CONFIG_IDF_TARGET_ESP32 -#if (CONFIG_BT_CTRL_ESP32C3 || CONFIG_BT_CTRL_ESP32S3) +#if (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) //BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP #ifdef CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP #define UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP @@ -202,7 +202,7 @@ #define UC_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD 20 #endif -#endif //(CONFIG_BT_CTRL_ESP32C3 || CONFIG_BT_CTRL_ESP32S3) +#endif //(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) //BT ACL CONNECTIONS #ifdef CONFIG_BT_ACL_CONNECTIONS diff --git a/components/bt/host/bluedroid/hci/hci_packet_parser.c b/components/bt/host/bluedroid/hci/hci_packet_parser.c index 40c736fe982a..7ce0728712f4 100644 --- a/components/bt/host/bluedroid/hci/hci_packet_parser.c +++ b/components/bt/host/bluedroid/hci/hci_packet_parser.c @@ -209,7 +209,8 @@ static void parse_ble_read_adv_max_len_response( { uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */); - STREAM_TO_UINT8(*adv_max_len_ptr, stream); + // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length + STREAM_TO_UINT16(*adv_max_len_ptr, stream); osi_free(response); } diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_msg.c b/components/bt/host/bluedroid/stack/avdt/avdt_msg.c index 4ebca9a06366..a049eee925a1 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_msg.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_msg.c @@ -1586,8 +1586,8 @@ void avdt_msg_send_grej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params) p_buf->len = (UINT16) (p - p_start); /* stash sig, label, and message type in buf */ - p_buf->event = 0; - AVDT_BLD_LAYERSPEC(p_buf->layer_specific, 0, p_params->hdr.label); + p_buf->event = sig_id; + AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_GRJ, p_params->hdr.label); AVDT_TRACE_DEBUG("avdt_msg_send_grej"); /* queue message and trigger ccb to send it */ diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 44de14065deb..201694250b84 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -689,23 +689,16 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data { tBTM_STATUS status = BTM_SUCCESS; tHCI_STATUS err = HCI_SUCCESS; - uint16_t rem_len; + uint16_t rem_len = len; UINT8 operation = 0; UINT16 data_offset = 0; tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; if ((status = btm_ble_ext_adv_set_data_validate(instance, len, data)) != BTM_SUCCESS) { BTM_TRACE_ERROR("%s, invalid extend adv data.", __func__); + goto end; } - if (len > controller_get_interface()->ble_get_ext_adv_data_max_len()) { - BTM_TRACE_ERROR("%s, The adv data len(%d) is longer then the controller adv max len(%d)", - __func__, len, controller_get_interface()->ble_get_ext_adv_data_max_len()); - status = BTM_ILLEGAL_VALUE; - } - - rem_len = len; - do { UINT8 send_data_len = (rem_len > BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) ? BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX : rem_len; @@ -729,8 +722,8 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data data_offset += send_data_len; } while(rem_len); +end: cb_params.status = status; - BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; @@ -1108,6 +1101,12 @@ static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, BTM_TRACE_ERROR("%s, for the legacy adv, the adv data length can't exceed 31. line %d", __func__, __LINE__); return BTM_ILLEGAL_VALUE; } + } else { + if (len > controller_get_interface()->ble_get_ext_adv_data_max_len()) { + BTM_TRACE_ERROR("%s, The adv data len(%d) is longer then the controller adv max len(%d)", + __func__, len, controller_get_interface()->ble_get_ext_adv_data_max_len()); + return BTM_ILLEGAL_VALUE; + } } return BTM_SUCCESS; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 3da5317dcd48..4ef3a960ff45 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -108,7 +108,7 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* init */ {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* master */ {HCI_SUPP_LE_STATES_SLAVE_MASK, HCI_SUPP_LE_STATES_SLAVE_OFF}, /* slave */ - {0, 0}, /* todo: lo du dir adv, not covered ? */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_OFF}, /* lo du dir adv */ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF}, /* hi duty dir adv */ {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF}, /* non connectable adv */ {HCI_SUPP_LE_STATES_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_OFF}, /* passive scan */ @@ -174,8 +174,8 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { {0, 0}, /* lo duty cycle adv 40 */ {0, 0}, /* hi duty cycle adv 39 */ {0, 0}, /* non connectable adv */ - {0, 0}, /* TODO: passive scan, not covered? */ - {0, 0}, /* TODO: active scan, not covered? */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* active scan */ {0, 0} /* scanable adv */ }, { /* hi duty cycle adv */ diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index cc8e2d9a050b..d83da09907f7 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -314,25 +314,60 @@ BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *context) tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) { tBTM_SEC_DEV_REC *p_dev_rec = NULL; + tBTM_SEC_DEV_REC *p_dev_new_rec = NULL; + tBTM_SEC_DEV_REC *p_dev_old_rec = NULL; tBTM_INQ_INFO *p_inq_info; + list_node_t *p_node = NULL; + BOOLEAN new_entry_found = FALSE; + BOOLEAN old_entry_found = FALSE; + BOOLEAN malloc_new_entry = FALSE; BTM_TRACE_EVENT ("btm_sec_alloc_dev\n"); - - /* Old devices which are not in use are deleted already */ - /* Allocate new device or reuse the oldest device */ - if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { - //Max number of devices is not exceeded, allocate new device - p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); - if (p_dev_rec) { - list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); - } else { - return NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_old_rec = list_node(p_node); + /* look for old entry which match the bd_addr and the BTM_SEC_IN_USE is cleared */ + if (!(p_dev_old_rec->sec_flags & BTM_SEC_IN_USE) && + (!memcmp (p_dev_old_rec->bd_addr, bd_addr, BD_ADDR_LEN))) { + old_entry_found = TRUE; + BTM_TRACE_EVENT ("btm_sec_alloc_dev old device found\n"); + break; + } + } + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_new_rec = list_node(p_node); + /* find the first entry whose BTM_SEC_IN_USE is cleared */ + if (!(p_dev_new_rec->sec_flags & BTM_SEC_IN_USE)) { + new_entry_found = TRUE; + break; } } - else { - //Find and reuse the oldest device + if (!new_entry_found) { + /* We can not find new device. We need malloc a new one if p_sec_dev_rec_list is not full */ + if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS){ + p_dev_new_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if (p_dev_new_rec) { + new_entry_found = TRUE; + malloc_new_entry = TRUE; + } else { + return NULL; + } + } + } + if (!new_entry_found) { p_dev_rec = btm_find_oldest_dev(); + } else { + /* if the old device entry not present go with new entry */ + if (old_entry_found) { + p_dev_rec = p_dev_old_rec; + if (malloc_new_entry) { + osi_free(p_dev_new_rec); + } + } else { + if (malloc_new_entry) { + list_append(btm_cb.p_sec_dev_rec_list, p_dev_new_rec); + } + p_dev_rec = p_dev_new_rec; + } } - memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */ diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 7b4edc879199..154b9e1e04b6 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -2306,6 +2306,7 @@ void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hc rem_name.length = 0; rem_name.remote_bd_name[0] = 0; } + memcpy(rem_name.bd_addr, p_inq->remname_bda, BD_ADDR_LEN); /* Reset the remote BAD to zero and call callback if possible */ memset(p_inq->remname_bda, 0, BD_ADDR_LEN); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index e8b1157afe82..a64d5da0f818 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -111,12 +111,15 @@ static void btu_hcif_rem_oob_request_evt (UINT8 *p); #if (SMP_INCLUDED == TRUE) static void btu_hcif_simple_pair_complete_evt (UINT8 *p); #endif ///SMP_INCLUDED == TRUE +static void btu_hcif_link_supv_to_changed_evt (UINT8 *p); #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE static void btu_hcif_enhanced_flush_complete_evt (void); #endif #if (BTM_SSR_INCLUDED == TRUE) static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len); +#else +static void btu_hcif_ssr_evt_dump (UINT8 *p, UINT16 evt_len); #endif /* BTM_SSR_INCLUDED == TRUE */ #if BLE_INCLUDED == TRUE @@ -300,11 +303,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_ESCO_CONNECTION_CHANGED_EVT: btu_hcif_esco_connection_chg_evt (p); break; -#if (BTM_SSR_INCLUDED == TRUE) case HCI_SNIFF_SUB_RATE_EVT: +#if (BTM_SSR_INCLUDED == TRUE) btu_hcif_ssr_evt (p, hci_evt_len); - break; +#else + btu_hcif_ssr_evt_dump (p, hci_evt_len); #endif /* BTM_SSR_INCLUDED == TRUE */ + break; case HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT: btu_hcif_host_support_evt (p); break; @@ -338,6 +343,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_hcif_keypress_notif_evt (p); break; #endif ///SMP_INCLUDED == TRUE + case HCI_LINK_SUPER_TOUT_CHANGED_EVT: + btu_hcif_link_supv_to_changed_evt (p); + break; #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE case HCI_ENHANCED_FLUSH_COMPLETE_EVT: btu_hcif_enhanced_flush_complete_evt (); @@ -651,6 +659,7 @@ static void btu_hcif_connection_comp_evt (UINT8 *p) btm_sco_connected (status, bda, handle, &esco_data); } #endif /* BTM_SCO_INCLUDED */ + HCI_TRACE_WARNING("hcif conn complete: hdl 0x%x, st 0x%x", handle, status); } @@ -707,9 +716,7 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p) handle = HCID_GET_HANDLE (handle); - if (reason != HCI_ERR_PEER_USER && reason != HCI_ERR_CONN_CAUSE_LOCAL_HOST) { - HCI_TRACE_WARNING("DiscCmpl evt: hdl=%d, rsn=0x%x", handle, reason); - } + HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x", handle, reason); #if BTM_SCO_INCLUDED == TRUE /* If L2CAP doesn't know about it, send it to SCO */ @@ -1554,6 +1561,8 @@ static void btu_hcif_mode_change_evt (UINT8 *p) btm_sco_chk_pend_unpark (status, handle); #endif btm_pm_proc_mode_change (status, handle, current_mode, interval); + HCI_TRACE_WARNING("hcif mode change: hdl 0x%x, mode %d, intv %d, status 0x%x", + handle, current_mode, interval, status); /* #if (HID_DEV_INCLUDED == TRUE) && (HID_DEV_PM_INCLUDED == TRUE) @@ -1576,6 +1585,26 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len) { btm_pm_proc_ssr_evt(p, evt_len); } +#else +static void btu_hcif_ssr_evt_dump (UINT8 *p, UINT16 evt_len) +{ + UINT8 status; + UINT16 handle; + UINT16 max_tx_lat; + UINT16 max_rx_lat; + + STREAM_TO_UINT8 (status, p); + STREAM_TO_UINT16 (handle, p); + STREAM_TO_UINT16 (max_tx_lat, p); + STREAM_TO_UINT16 (max_rx_lat, p); + + UNUSED(status); + UNUSED(handle); + UNUSED(max_tx_lat); + UNUSED(max_rx_lat); + + HCI_TRACE_WARNING("hcif ssr evt: st 0x%x, hdl 0x%x, tx_lat %d rx_lat %d", status, handle, max_tx_lat, max_rx_lat); +} #endif /******************************************************************************* @@ -1920,6 +1949,30 @@ static void btu_hcif_simple_pair_complete_evt (UINT8 *p) btm_simple_pair_complete(p); } #endif ///SMP_INCLUDED == TRUE + +/******************************************************************************* +** +** Function btu_hcif_link_supv_to_changed_evt +** +** Description Process event HCI_LINK_SUPER_TOUT_CHANGED_EVT +** +** Returns void +** +*******************************************************************************/ +static void btu_hcif_link_supv_to_changed_evt (UINT8 *p) +{ + UINT16 handle; + UINT16 supv_to; + + STREAM_TO_UINT16(handle, p); + STREAM_TO_UINT16(supv_to, p); + + UNUSED(handle); + UNUSED(supv_to); + + HCI_TRACE_WARNING("hcif link supv_to changed: hdl 0x%x, supv_to %d", handle, supv_to); +} + /******************************************************************************* ** ** Function btu_hcif_enhanced_flush_complete_evt @@ -2065,14 +2118,41 @@ static void btu_ble_phy_update_complete_evt(UINT8 *p) btm_ble_update_phy_evt(&update_phy); } +#if BLE_PRIVACY_SPT == TRUE +/******************************************************************************* +** +** Function btm_ble_resolve_random_addr_adv_ext +** +** Description resolve random address complete callback. +** +** Returns void +** +*******************************************************************************/ +static void btm_ble_resolve_random_addr_adv_ext(void *p_rec, void *p) +{ + tBTM_SEC_DEV_REC *match_rec = (tBTM_SEC_DEV_REC *) p_rec; + BD_ADDR bda; + UINT8 *pp = (UINT8 *)p+4; //jump to the location of bd addr + if (match_rec) { + // Assign the original address to be the current report address + memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN); + BDADDR_TO_STREAM(pp,bda); + } +} +#endif + static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) { tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0}; UINT8 num_reports = {0}; + UINT8 *pp = p; //UINT8 legacy_event_type = 0; UINT16 evt_type = 0; uint8_t addr_type; BD_ADDR bda; + #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) + BOOLEAN match = FALSE; + #endif if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -2106,12 +2186,17 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) STREAM_TO_UINT8(addr_type, p); STREAM_TO_BDADDR(bda, p); - // If it is an anonymous adv, skip address resolution - if(addr_type != 0xFF) { #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - btm_identity_addr_to_random_pseudo(bda, &addr_type, FALSE); -#endif + if(addr_type != 0xFF) { + match = btm_identity_addr_to_random_pseudo(bda, &addr_type, FALSE); + if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) { + btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_adv_ext, pp); + //the BDADDR may be updated, so read it again + p = p - sizeof(bda); + STREAM_TO_BDADDR(bda, p); + } } +#endif ext_adv_report.addr_type = addr_type; memcpy(ext_adv_report.addr, bda, 6); STREAM_TO_UINT8(ext_adv_report.primary_phy, p); diff --git a/components/bt/host/bluedroid/stack/hcic/hcicmds.c b/components/bt/host/bluedroid/stack/hcic/hcicmds.c index 80517dcdb226..3b52804408c9 100644 --- a/components/bt/host/bluedroid/stack/hcic/hcicmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hcicmds.c @@ -191,6 +191,7 @@ BOOLEAN btsnd_hcic_disconnect (UINT16 handle, UINT8 reason) UINT8_TO_STREAM (pp, reason); btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + HCI_TRACE_WARNING("hci cmd send: disconnect: hdl 0x%x, rsn:0x%x", handle, reason); return (TRUE); } @@ -776,6 +777,8 @@ BOOLEAN btsnd_hcic_sniff_mode (UINT16 handle, UINT16 max_sniff_period, UINT16_TO_STREAM (pp, sniff_timeout); btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + HCI_TRACE_WARNING("hci cmd send: sniff: hdl 0x%x, intv(%d %d)", + handle, min_sniff_period, max_sniff_period); return (TRUE); } @@ -799,6 +802,7 @@ BOOLEAN btsnd_hcic_exit_sniff_mode (UINT16 handle) UINT16_TO_STREAM (pp, handle); btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + HCI_TRACE_WARNING("hci cmd send: unsniff: hdl 0x%x", handle); return TRUE; } diff --git a/components/bt/host/bluedroid/stack/include/stack/port_api.h b/components/bt/host/bluedroid/stack/include/stack/port_api.h index 9bab34c3cc49..fb9e7574ba88 100644 --- a/components/bt/host/bluedroid/stack/include/stack/port_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/port_api.h @@ -105,6 +105,16 @@ typedef int (tPORT_DATA_CO_CALLBACK) (UINT16 port_handle, UINT8 *p_buf, UINT16 typedef void (tPORT_CALLBACK) (UINT32 code, UINT16 port_handle); +typedef void (tPORT_MGMT_CALLBACK) (UINT32 code, UINT16 port_handle, void* data); + +/** + * Define the server port manage callback function argument + */ +typedef struct { + BOOLEAN accept; /* If upper layer accepts the incoming connection */ + BOOLEAN ignore_rfc_state; /* If need to ignore rfc state for PORT_CheckConnection */ +} tPORT_MGMT_SR_CALLBACK_ARG; + /* ** Define events that registered application can receive in the callback */ @@ -219,7 +229,7 @@ extern "C" extern int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server, UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle, - tPORT_CALLBACK *p_mgmt_cb); + tPORT_MGMT_CALLBACK *p_mgmt_cb); /******************************************************************************* @@ -310,11 +320,12 @@ extern int PORT_SetEventMask (UINT16 port_handle, UINT32 mask); ** by handle is up and running ** ** Parameters: handle - Handle of the port returned in the Open +** ignore_rfc_state - If need to ignore rfc state ** bd_addr - OUT bd_addr of the peer ** p_lcid - OUT L2CAP's LCID ** *******************************************************************************/ -extern int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, +extern int PORT_CheckConnection (UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr, UINT16 *p_lcid); /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 3112e2a507f0..696d29b68b8e 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -363,7 +363,10 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) /* If we don't have one, maybe an SCO link. Send to MM */ if (!p_lcb) { #if (BLE_INCLUDED == TRUE) - BTM_Recovery_Pre_State(); + /* The Directed Advertising Timeout error code indicates that directed advertising completed */ + if (reason != HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT) { + BTM_Recovery_Pre_State(); + } #endif ///BLE_INCLUDED == TRUE status = FALSE; } else { diff --git a/components/bt/host/bluedroid/stack/rfcomm/include/port_int.h b/components/bt/host/bluedroid/stack/rfcomm/include/port_int.h index a2e0e152788b..596181169858 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/include/port_int.h +++ b/components/bt/host/bluedroid/stack/rfcomm/include/port_int.h @@ -188,7 +188,7 @@ struct t_port_info { UINT32 ev_mask; /* Event mask for the callback */ tPORT_CALLBACK *p_callback; /* Pointer to users callback function */ - tPORT_CALLBACK *p_mgmt_callback; /* Callback function to receive connection up/down */ + tPORT_MGMT_CALLBACK *p_mgmt_callback; /* Callback function to receive connection up/down */ tPORT_DATA_CALLBACK *p_data_callback; /* Callback function to receive data indications */ tPORT_DATA_CO_CALLBACK *p_data_co_callback; /* Callback function with callouts and flowctrl */ UINT16 credit_tx; /* Flow control credits for tx path */ diff --git a/components/bt/host/bluedroid/stack/rfcomm/port_api.c b/components/bt/host/bluedroid/stack/rfcomm/port_api.c index d42bbabdf2aa..99d469c96bbf 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/port_api.c +++ b/components/bt/host/bluedroid/stack/rfcomm/port_api.c @@ -103,7 +103,7 @@ static const char *result_code_strings[] = { *******************************************************************************/ int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server, UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle, - tPORT_CALLBACK *p_mgmt_cb) + tPORT_MGMT_CALLBACK *p_mgmt_cb) { tPORT *p_port; int i; @@ -464,11 +464,12 @@ int PORT_SetEventMask (UINT16 port_handle, UINT32 mask) ** by handle is up and running ** ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection +** ignore_rfc_state - If need to ignore rfc state ** bd_addr - OUT bd_addr of the peer ** p_lcid - OUT L2CAP's LCID ** *******************************************************************************/ -int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid) +int PORT_CheckConnection(UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr, UINT16 *p_lcid) { tPORT *p_port; @@ -485,9 +486,8 @@ int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid) return (PORT_NOT_OPENED); } - if (!p_port->rfc.p_mcb - || !p_port->rfc.p_mcb->peer_ready - || (p_port->rfc.state != RFC_STATE_OPENED)) { + if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready || + (!ignore_rfc_state ? (p_port->rfc.state != RFC_STATE_OPENED) : false)) { return (PORT_LINE_ERR); } diff --git a/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c b/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c index 5dfd1b7e54ad..ddcef1bb7c65 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c +++ b/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c @@ -175,7 +175,7 @@ void port_start_close (tPORT *p_port) if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED)) { /* Call management callback function before calling port_release_port() to clear tPort */ if (p_port->p_mgmt_callback) { - p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx); + p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx, NULL); } port_release_port (p_port); @@ -230,7 +230,7 @@ void PORT_StartCnf (tRFC_MCB *p_mcb, UINT16 result) } if (p_port->p_mgmt_callback) { - p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx); + p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx, NULL); } port_release_port (p_port); @@ -427,6 +427,10 @@ void PORT_ParNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k) void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) { tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); + tPORT_MGMT_SR_CALLBACK_ARG mgmt_cb_arg = { + .accept = TRUE, + .ignore_rfc_state = FALSE, + }; RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port); RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x", @@ -451,7 +455,7 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) /* If there was an inactivity timer running for MCB stop it */ rfc_timer_stop (p_mcb); - RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); + // RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); /* This is the server side. If application wants to know when connection */ /* is established, thats the place */ @@ -460,10 +464,22 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) } if (p_port->p_mgmt_callback) { - p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx); + /** + * @note + * 1. The manage callback function may change the value of accept in mgmt_cb_arg. + * 2. Use mgmt_cb_arg.ignore_rfc_state to work around the issue caused by sending + * RFCOMM establish response after the manage callback function. + */ + mgmt_cb_arg.ignore_rfc_state = TRUE; + p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &mgmt_cb_arg); } - p_port->state = PORT_STATE_OPENED; + if (mgmt_cb_arg.accept) { + RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); + p_port->state = PORT_STATE_OPENED; + } else { + RFCOMM_DlcEstablishRsp(p_mcb, dlci, 0, RFCOMM_LOW_RESOURCES); + } } @@ -506,7 +522,7 @@ void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 resul } if (p_port->p_mgmt_callback) { - p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx); + p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, NULL); } p_port->state = PORT_STATE_OPENED; @@ -1063,14 +1079,15 @@ void port_rfc_closed (tPORT *p_port, UINT8 res) p_port->p_callback (events, p_port->inx); } - if (p_port->p_mgmt_callback) { - p_port->p_mgmt_callback (res, p_port->inx); + if (p_port->p_mgmt_callback && !(p_port->state == PORT_STATE_CLOSED && p_port->is_server)) { + p_port->p_mgmt_callback(res, p_port->inx, NULL); } p_port->rfc.state = RFC_STATE_CLOSED; - RFCOMM_TRACE_WARNING ("%s RFCOMM connection in state %d closed: %s (res: %d)", - __func__, p_port->state, PORT_GetResultString(res), res); + RFCOMM_TRACE_WARNING("%s RFCOMM connection in server:%d state %d closed: %s (res: %d)", + __func__, p_port->is_server, p_port->state, PORT_GetResultString(res), + res); port_release_port (p_port); } diff --git a/components/bt/host/bluedroid/stack/rfcomm/rfc_mx_fsm.c b/components/bt/host/bluedroid/stack/rfcomm/rfc_mx_fsm.c index 6afd6ae6901e..4ed65fc94535 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/rfc_mx_fsm.c +++ b/components/bt/host/bluedroid/stack/rfcomm/rfc_mx_fsm.c @@ -69,6 +69,8 @@ static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg); *******************************************************************************/ void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data) { + RFCOMM_TRACE_DEBUG("%s st:%d, evt:%d\n", __func__, p_mcb->state, event); + switch (p_mcb->state) { case RFC_MX_STATE_IDLE: rfc_mx_sm_state_idle (p_mcb, event, p_data); diff --git a/components/bt/host/bluedroid/stack/rfcomm/rfc_port_fsm.c b/components/bt/host/bluedroid/stack/rfcomm/rfc_port_fsm.c index b496937058ec..8d8fe3cac667 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/rfc_port_fsm.c +++ b/components/bt/host/bluedroid/stack/rfcomm/rfc_port_fsm.c @@ -62,6 +62,8 @@ static void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame); *******************************************************************************/ void rfc_port_sm_execute (tPORT *p_port, UINT16 event, void *p_data) { + RFCOMM_TRACE_DEBUG("%s st:%d, evt:%d\n", __func__, p_port->rfc.state, event); + if (!p_port) { RFCOMM_TRACE_WARNING ("NULL port event %d", event); return; @@ -296,6 +298,11 @@ void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data) if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) { if (p_port->rfc.p_mcb) { rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE); + if (*((UINT8 *)p_data) == RFCOMM_LOW_RESOURCES) { + port_rfc_closed(p_port, PORT_NO_RESOURCES); + } else { + port_rfc_closed(p_port, PORT_UNKNOWN_ERROR); + } } } else { rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci); diff --git a/components/bt/host/bluedroid/stack/rfcomm/rfc_utils.c b/components/bt/host/bluedroid/stack/rfcomm/rfc_utils.c index 0d1fbdcb3918..5ab3ac3e2295 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/rfc_utils.c +++ b/components/bt/host/bluedroid/stack/rfcomm/rfc_utils.c @@ -201,7 +201,6 @@ void osi_free_fun(void *p){ *******************************************************************************/ void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb) { - rfc_timer_free (p_mcb); fixed_queue_free(p_mcb->cmd_q, osi_free_fun); diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index f5e6ef3ce885..353ee9c9b61c 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -1539,13 +1539,12 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { -#if (BT_MULTI_CONNECTION_ENBALE == FALSE) if(p_cb->role == BTM_ROLE_MASTER) { +#if (BT_MULTI_CONNECTION_ENBALE == FALSE) L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE); - } #endif + } else { #if (SMP_SLAVE_CON_PARAMS_UPD_ENABLE == TRUE) - else { tBTM_SEC_DEV_REC *p_rec = btm_find_dev (p_cb->pairing_bda); if(p_rec && p_rec->ble.skip_update_conn_param) { //do nothing @@ -1558,8 +1557,8 @@ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) #if (BT_MULTI_CONNECTION_ENBALE == FALSE) L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE); #endif - } #endif + } } /******************************************************************************* diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index a4f3ace1e776..1dc1ec6e76b0 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit a4f3ace1e776b2c3edc5421e0c222f2ead94792b +Subproject commit 1dc1ec6e76b0ab3bf93cc9f1ff7a2a09141e7c61 diff --git a/components/bt/include/esp32c3/include/esp_bt.h b/components/bt/include/esp32c3/include/esp_bt.h index 45e5c3fa52bb..a1f2551e2cd0 100644 --- a/components/bt/include/esp32c3/include/esp_bt.h +++ b/components/bt/include/esp32c3/include/esp_bt.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_BT_H__ #define __ESP_BT_H__ @@ -26,7 +18,7 @@ extern "C" { #endif #define ESP_BT_CTRL_CONFIG_MAGIC_VAL 0x5A5AA5A5 -#define ESP_BT_CTRL_CONFIG_VERSION 0x02104270 +#define ESP_BT_CTRL_CONFIG_VERSION 0x02112280 #define ESP_BT_HCI_TL_MAGIC_VALUE 0xfadebead #define ESP_BT_HCI_TL_VERSION 0x00010000 @@ -93,6 +85,13 @@ enum { ESP_BT_COEX_PHY_CODED_TX_RX_TIME_LIMIT_FORCE_ENABLE, /*!< Always Enable the limit */ }; +#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */ + +/** + * @brief callback function for HCI Transport Layer send/receive operations + */ +typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); + #ifdef CONFIG_BT_ENABLED #define BT_CTRL_BLE_MAX_ACT_LIMIT 10 //Maximum BLE activity limitation @@ -164,7 +163,9 @@ enum { .ble_st_acl_tx_buf_nb = CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB, \ .ble_hw_cca_check = CONFIG_BT_CTRL_HW_CCA_EFF, \ .ble_adv_dup_filt_max = CONFIG_BT_CTRL_ADV_DUP_FILT_MAX, \ + .coex_param_en = false, \ .ce_len_type = CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF, \ + .coex_use_hooks = false, \ .hci_tl_type = CONFIG_BT_CTRL_HCI_TL_EFF, \ .hci_tl_funcs = NULL, \ .txant_dft = CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF, \ @@ -179,6 +180,7 @@ enum { .hw_target_code = BLE_HW_TARGET_CODE_ESP32C3_CHIP_ECO0, \ .slave_ce_len_min = SLAVE_CE_LEN_MIN_DEFAULT, \ .hw_recorrect_en = AGC_RECORRECT_EN, \ + .cca_thresh = CONFIG_BT_CTRL_HW_CCA_VAL, \ }; #else @@ -196,8 +198,8 @@ typedef struct { int (* _open)(void); /* hci tl open */ void (* _close)(void); /* hci tl close */ void (* _finish_transfers)(void); /* hci tl finish trasnfers */ - void (* _recv)(uint8_t *buf, uint32_t len, void (*callback) (void*, uint8_t), void* dummy); /* hci tl recv */ - void (* _send)(uint8_t *buf, uint32_t len, void (*callback) (void*, uint8_t), void* dummy); /* hci tl send */ + void (* _recv)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl recv */ + void (* _send)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl send */ bool (* _flow_off)(void); /* hci tl flow off */ void (* _flow_on)(void); /* hci tl flow on */ } esp_bt_hci_tl_t; @@ -245,6 +247,7 @@ typedef struct { uint32_t hw_target_code; /*!< hardware target */ uint8_t slave_ce_len_min; uint8_t hw_recorrect_en; + uint8_t cca_thresh; /*!< cca threshold*/ } esp_bt_controller_config_t; /** diff --git a/components/bt/sdkconfig.rename b/components/bt/sdkconfig.rename index ee3e0f86b29e..dae070eda5db 100644 --- a/components/bt/sdkconfig.rename +++ b/components/bt/sdkconfig.rename @@ -1,37 +1,6 @@ # sdkconfig replacement configurations for deprecated options formatted as # CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION -CONFIG_BTDM_CONTROLLER_MODE CONFIG_BTDM_CTRL_MODE -CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY CONFIG_BTDM_CTRL_MODE_BLE_ONLY -CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY -CONFIG_BTDM_CONTROLLER_MODE_BTDM CONFIG_BTDM_CTRL_MODE_BTDM -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN CONFIG_BTDM_CTRL_BLE_MAX_CONN -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_CHOICE CONFIG_BTDM_CTRL_PINNED_TO_CORE_CHOICE -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE CONFIG_BTDM_CTRL_PINNED_TO_CORE -CONFIG_BTDM_CONTROLLER_HCI_MODE_CHOICE CONFIG_BTDM_CTRL_HCI_MODE_CHOICE -CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI CONFIG_BTDM_CTRL_HCI_MODE_VHCI -CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 - -CONFIG_BTDM_CONTROLLER_MODEM_SLEEP CONFIG_BTDM_CTRL_MODEM_SLEEP - -CONFIG_BLE_SCAN_DUPLICATE CONFIG_BTDM_BLE_SCAN_DUPL -CONFIG_SCAN_DUPLICATE_TYPE CONFIG_BTDM_SCAN_DUPL_TYPE -CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE -CONFIG_SCAN_DUPLICATE_BY_ADV_DATA CONFIG_BTDM_SCAN_DUPL_TYPE_DATA -CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE -CONFIG_DUPLICATE_SCAN_CACHE_SIZE CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE -CONFIG_BLE_MESH_SCAN_DUPLICATE_EN CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN -CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_BTDM_MESH_DUPL_SCAN_CACHE_SIZE -CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM -CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD - CONFIG_BLUEDROID_ENABLED CONFIG_BT_BLUEDROID_ENABLED CONFIG_BLUEDROID_PINNED_TO_CORE_CHOICE CONFIG_BT_BLUEDROID_PINNED_TO_CORE_CHOICE CONFIG_BLUEDROID_PINNED_TO_CORE CONFIG_BT_BLUEDROID_PINNED_TO_CORE diff --git a/components/console/esp_console.h b/components/console/esp_console.h index 29aab8b4fb76..fb4a67fc9e7c 100644 --- a/components/console/esp_console.h +++ b/components/console/esp_console.h @@ -114,6 +114,21 @@ typedef struct { { \ } +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +/** + * @brief Parameters for console device: USB-SERIAL-JTAG + * + * @note It's an empty structure for now, reserved for future + * + */ +typedef struct { + +} esp_console_dev_usb_serial_jtag_config_t; + +#define ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT() {} + +#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + /** * @brief initialize console module * @param config console configuration @@ -339,6 +354,29 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con */ esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl); +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +/** + * @brief Establish a console REPL (Read-eval-print loop) environment over USB-SERIAL-JTAG + * + * @param[in] dev_config USB-SERIAL-JTAG configuration + * @param[in] repl_config REPL configuration + * @param[out] ret_repl return REPL handle after initialization succeed, return NULL otherwise + * + * @note This is a all-in-one function to establish the environment needed for REPL, includes: + * - Initializes linenoise + * - Spawn new thread to run REPL in the background + * + * @attention This function is meant to be used in the examples to make the code more compact. + * Applications which use console functionality should be based on + * the underlying linenoise and esp_console functions. + * + * @return + * - ESP_OK on success + * - ESP_FAIL Parameter error + */ +esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl); +#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + /** * @brief Start REPL environment * @param[in] repl REPL handle returned from esp_console_new_repl_xxx diff --git a/components/console/esp_console_repl.c b/components/console/esp_console_repl.c index 1bf1704e409c..09929931b584 100644 --- a/components/console/esp_console_repl.c +++ b/components/console/esp_console_repl.c @@ -22,9 +22,11 @@ #include "esp_console.h" #include "esp_vfs_dev.h" #include "esp_vfs_cdcacm.h" +#include "esp_vfs_usb_serial_jtag.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/uart.h" +#include "driver/usb_serial_jtag.h" #include "linenoise/linenoise.h" static const char *TAG = "console.repl"; @@ -54,6 +56,9 @@ typedef struct { static void esp_console_repl_task(void *args); static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl); static esp_err_t esp_console_repl_usb_cdc_delete(esp_console_repl_t *repl); +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +static esp_err_t esp_console_repl_usb_serial_jtag_delete(esp_console_repl_t *repl); +#endif //CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG static esp_err_t esp_console_common_init(esp_console_repl_com_t *repl_com); static esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com); static esp_err_t esp_console_setup_history(const char *history_path, uint32_t max_history_len, esp_console_repl_com_t *repl_com); @@ -122,6 +127,84 @@ esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *d return ret; } +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl) +{ + esp_console_repl_universal_t *usb_serial_jtag_repl = NULL; + if (!repl_config | !dev_config | !ret_repl) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t ret = ESP_OK; + // allocate memory for console REPL context + usb_serial_jtag_repl = calloc(1, sizeof(esp_console_repl_universal_t)); + if (!usb_serial_jtag_repl) { + ret = ESP_ERR_NO_MEM; + goto _exit; + } + + /* Disable buffering on stdin */ + setvbuf(stdin, NULL, _IONBF, 0); + + /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ + esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + /* Move the caret to the beginning of the next line on '\n' */ + esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); + + /* Enable non-blocking mode on stdin and stdout */ + fcntl(fileno(stdout), F_SETFL, 0); + fcntl(fileno(stdin), F_SETFL, 0); + + usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(); + + /* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */ + ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config); + if (ret != ESP_OK) { + goto _exit; + } + + // initialize console, common part + ret = esp_console_common_init(&usb_serial_jtag_repl->repl_com); + if (ret != ESP_OK) { + goto _exit; + } + + /* Tell vfs to use usb-serial-jtag driver */ + esp_vfs_usb_serial_jtag_use_driver(); + + // setup history + ret = esp_console_setup_history(repl_config->history_save_path, repl_config->max_history_len, &usb_serial_jtag_repl->repl_com); + if (ret != ESP_OK) { + goto _exit; + } + + // setup prompt + esp_console_setup_prompt(repl_config->prompt, &usb_serial_jtag_repl->repl_com); + + /* spawn a single thread to run REPL */ + if (xTaskCreate(esp_console_repl_task, "console_repl", repl_config->task_stack_size, + &usb_serial_jtag_repl->repl_com, repl_config->task_priority, &usb_serial_jtag_repl->repl_com.task_hdl) != pdTRUE) { + ret = ESP_FAIL; + goto _exit; + } + + usb_serial_jtag_repl->uart_channel = CONFIG_ESP_CONSOLE_UART_NUM; + usb_serial_jtag_repl->repl_com.state = CONSOLE_REPL_STATE_INIT; + usb_serial_jtag_repl->repl_com.repl_core.del = esp_console_repl_usb_serial_jtag_delete; + *ret_repl = &usb_serial_jtag_repl->repl_com.repl_core; + return ESP_OK; +_exit: + if (usb_serial_jtag_repl) { + esp_console_deinit(); + free(usb_serial_jtag_repl); + } + if (ret_repl) { + *ret_repl = NULL; + } + return ret; +} +#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl) { esp_err_t ret = ESP_OK; @@ -285,6 +368,8 @@ static esp_err_t esp_console_common_init(esp_console_repl_com_t *repl_com) esp_console_config_t console_config = ESP_CONSOLE_CONFIG_DEFAULT(); #if CONFIG_LOG_COLORS console_config.hint_color = atoi(LOG_COLOR_CYAN); +#else + console_config.hint_color = -1; #endif ret = esp_console_init(&console_config); if (ret != ESP_OK) { @@ -347,6 +432,28 @@ static esp_err_t esp_console_repl_usb_cdc_delete(esp_console_repl_t *repl) return ret; } +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +static esp_err_t esp_console_repl_usb_serial_jtag_delete(esp_console_repl_t *repl) +{ + esp_err_t ret = ESP_OK; + esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core); + esp_console_repl_universal_t *usb_serial_jtag_repl = __containerof(repl_com, esp_console_repl_universal_t, repl_com); + // check if already de-initialized + if (repl_com->state == CONSOLE_REPL_STATE_DEINIT) { + ESP_LOGE(TAG, "already de-initialized"); + ret = ESP_ERR_INVALID_STATE; + goto _exit; + } + repl_com->state = CONSOLE_REPL_STATE_DEINIT; + esp_console_deinit(); + esp_vfs_usb_serial_jtag_use_nonblocking(); + usb_serial_jtag_driver_uninstall(); + free(usb_serial_jtag_repl); +_exit: + return ret; +} +#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + static void esp_console_repl_task(void *args) { esp_console_repl_universal_t *repl_conf = (esp_console_repl_universal_t *) args; diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index e09719dad281..8edebb60db6a 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -498,9 +498,10 @@ void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) { int hintmaxlen = l->cols-(plen+l->len); if (hintlen > hintmaxlen) hintlen = hintmaxlen; if (bold == 1 && color == -1) color = 37; - if (color != -1 || bold != 0) + if (color != -1 || bold != 0) { snprintf(seq,64,"\033[%d;%d;49m",bold,color); - abAppend(ab,seq,strlen(seq)); + abAppend(ab,seq,strlen(seq)); + } abAppend(ab,hint,hintlen); if (color != -1 || bold != 0) abAppend(ab,"\033[0m",4); diff --git a/components/cxx/test/test_cxx.cpp b/components/cxx/test/test_cxx.cpp index 03ee89075e3f..de61845c3daf 100644 --- a/components/cxx/test/test_cxx.cpp +++ b/components/cxx/test/test_cxx.cpp @@ -57,7 +57,7 @@ TEST_CASE("can use std::vector", "[cxx]") #elif CONFIG_IDF_TARGET_ESP32S2 #define LEAKS "800" #elif CONFIG_IDF_TARGET_ESP32C3 -#define LEAKS "600" +#define LEAKS "700" #else #error "unknown target in CXX tests, can't set leaks threshold" #endif diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index b516b255ebd7..372b2ace91c7 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -67,6 +67,7 @@ if(IDF_TARGET STREQUAL "esp32c3") list(APPEND srcs "gdma.c" "spi_slave_hd.c" "adc_common.c" + "usb_serial_jtag.c" "esp32c3/adc.c" "esp32c3/adc2_init_cal.c" "esp32c3/rtc_tempsensor.c") diff --git a/components/driver/component.mk b/components/driver/component.mk index 02d0a8e647f1..dd6959ef5066 100644 --- a/components/driver/component.mk +++ b/components/driver/component.mk @@ -2,7 +2,7 @@ # Component Makefile # COMPONENT_SRCDIRS := . $(IDF_TARGET) -COMPONENT_OBJEXCLUDE += spi_slave_hd.o dedic_gpio.o gdma.o +COMPONENT_OBJEXCLUDE += spi_slave_hd.o dedic_gpio.o gdma.o usb_serial_jtag.o COMPONENT_ADD_INCLUDEDIRS := include $(IDF_TARGET)/include $(IDF_TARGET)/include/driver diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index ffcf09c15855..b2312b176790 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -229,8 +229,10 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) }; adc_hal_context_config(&s_adc_digi_ctx->hal, &config); - //enable SARADC module clock + //enable ADC digital part periph_module_enable(PERIPH_SARADC_MODULE); + //reset ADC digital part + periph_module_reset(PERIPH_SARADC_MODULE); adc_hal_calibration_init(ADC_NUM_1); adc_hal_calibration_init(ADC_NUM_2); diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 3054bdaf9679..bfab49563487 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -502,15 +502,21 @@ esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num) void gpio_uninstall_isr_service(void) { + gpio_isr_func_t *gpio_isr_func_free = NULL; + gpio_isr_handle_t gpio_isr_handle_free = NULL; + portENTER_CRITICAL(&gpio_context.gpio_spinlock); if (gpio_context.gpio_isr_func == NULL) { + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return; } - portENTER_CRITICAL(&gpio_context.gpio_spinlock); - esp_intr_free(gpio_context.gpio_isr_handle); - free(gpio_context.gpio_isr_func); + gpio_isr_func_free = gpio_context.gpio_isr_func; gpio_context.gpio_isr_func = NULL; + gpio_isr_handle_free = gpio_context.gpio_isr_handle; + gpio_context.gpio_isr_handle = NULL; gpio_context.isr_core_id = GPIO_ISR_CORE_ID_UNINIT; portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + esp_intr_free(gpio_isr_handle_free); + free(gpio_isr_func_free); return; } @@ -543,7 +549,12 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, #else /* CONFIG_FREERTOS_UNICORE */ ret = esp_ipc_call_blocking(gpio_context.isr_core_id, gpio_isr_register_on_core_static, (void *)&p); #endif /* !CONFIG_FREERTOS_UNICORE */ - if(ret != ESP_OK || p.ret != ESP_OK) { + if (ret != ESP_OK) { + ESP_LOGE(GPIO_TAG, "esp_ipc_call_blocking failed (0x%x)", ret); + return ESP_ERR_NOT_FOUND; + } + if (p.ret != ESP_OK) { + ESP_LOGE(GPIO_TAG, "esp_intr_alloc failed (0x%x)", p.ret); return ESP_ERR_NOT_FOUND; } return ESP_OK; diff --git a/components/driver/i2c.c b/components/driver/i2c.c index 06c512ea8bae..f02254a0fe46 100644 --- a/components/driver/i2c.c +++ b/components/driver/i2c.c @@ -48,7 +48,7 @@ static const char *I2C_TAG = "i2c"; #define I2C_DRIVER_ERR_STR "i2c driver install error" #define I2C_DRIVER_MALLOC_ERR_STR "i2c driver malloc error" #define I2C_NUM_ERROR_STR "i2c number error" -#define I2C_TIMEING_VAL_ERR_STR "i2c timing value error" +#define I2C_TIMING_VAL_ERR_STR "i2c timing value error" #define I2C_ADDR_ERROR_STR "i2c null address error" #define I2C_DRIVER_NOT_INSTALL_ERR_STR "i2c driver not installed" #define I2C_SLAVE_BUFFER_LEN_ERR_STR "i2c buffer size too small for slave mode" @@ -200,7 +200,7 @@ static i2c_clk_alloc_t i2c_clk_alloc[I2C_SCLK_MAX] = { static i2c_obj_t *p_i2c_obj[I2C_NUM_MAX] = {0}; static void i2c_isr_handler_default(void *arg); static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num); -static esp_err_t IRAM_ATTR i2c_hw_fsm_reset(i2c_port_t i2c_num); +static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num); static void i2c_hw_disable(i2c_port_t i2c_num) { @@ -468,6 +468,14 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg) { i2c_obj_t *p_i2c = (i2c_obj_t *) arg; int i2c_num = p_i2c->i2c_num; + // Interrupt protection. + // On C3 and S3 targets, the I2C may trigger a spurious interrupt, + // in order to detect these false positive, check the I2C's hardware interrupt mask + uint32_t int_mask; + i2c_hal_get_intsts_mask(&(i2c_context[i2c_num].hal), &int_mask); + if (int_mask == 0) { + return; + } i2c_intr_event_t evt_type = I2C_INTR_EVENT_ERR; portBASE_TYPE HPTaskAwoken = pdFALSE; if (p_i2c->mode == I2C_MODE_MASTER) { @@ -491,6 +499,9 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg) if (p_i2c->status != I2C_STATUS_ACK_ERROR && p_i2c->status != I2C_STATUS_IDLE) { i2c_master_cmd_begin_static(i2c_num); } + } else { + // Do nothing if there is no proper event. + return; } i2c_cmd_evt_t evt = { .type = I2C_CMD_EVT_ALIVE @@ -587,6 +598,8 @@ static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num) **/ static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num) { +// A workaround for avoiding cause timeout issue when using +// hardware reset. #if !SOC_I2C_SUPPORT_HW_FSM_RST int scl_low_period, scl_high_period; int scl_start_hold, scl_rstart_setup; @@ -679,8 +692,8 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period) { I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((high_period <= I2C_SCL_HIGH_PERIOD_V) && (high_period > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((low_period <= I2C_SCL_LOW_PERIOD_V) && (low_period > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((high_period <= I2C_SCL_HIGH_PERIOD_V) && (high_period > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((low_period <= I2C_SCL_LOW_PERIOD_V) && (low_period > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_scl_timing(&(i2c_context[i2c_num].hal), high_period, low_period); @@ -719,8 +732,8 @@ esp_err_t i2c_filter_disable(i2c_port_t i2c_num) esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time) { I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((hold_time <= I2C_SCL_START_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((setup_time <= I2C_SCL_RSTART_SETUP_TIME_V) && (setup_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((hold_time <= I2C_SCL_START_HOLD_TIME_V) && (hold_time > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((setup_time <= I2C_SCL_RSTART_SETUP_TIME_V) && (setup_time > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_start_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time); @@ -740,8 +753,8 @@ esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int *setup_time, int *hold_ti esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time) { I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((setup_time <= I2C_SCL_STOP_SETUP_TIME_V) && (setup_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((hold_time <= I2C_SCL_STOP_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((setup_time <= I2C_SCL_STOP_SETUP_TIME_V) && (setup_time > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((hold_time <= I2C_SCL_STOP_HOLD_TIME_V) && (hold_time > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_stop_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time); @@ -761,8 +774,8 @@ esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int *setup_time, int *hold_tim esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time) { I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((sample_time <= I2C_SDA_SAMPLE_TIME_V) && (sample_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((hold_time <= I2C_SDA_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((sample_time <= I2C_SDA_SAMPLE_TIME_V) && (sample_time > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((hold_time <= I2C_SDA_HOLD_TIME_V) && (hold_time > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_sda_timing(&(i2c_context[i2c_num].hal), sample_time, hold_time); @@ -782,7 +795,7 @@ esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int *sample_time, int *hold_ti esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout) { I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG); - I2C_CHECK((timeout <= I2C_TIME_OUT_REG_V) && (timeout > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + I2C_CHECK((timeout <= I2C_TIME_OUT_REG_V) && (timeout > 0), I2C_TIMING_VAL_ERR_STR, ESP_ERR_INVALID_ARG); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_tout(&(i2c_context[i2c_num].hal), timeout); diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 2d8b481fdae3..092b981400a4 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -496,7 +496,8 @@ esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP -#define GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num) ((gpio_num & ~SOC_GPIO_DEEP_SLEEP_WAKEUP_VALID_GPIO_MASK) == 0) +#define GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num) ((gpio_num >= 0) && \ + (((1ULL << (gpio_num)) & SOC_GPIO_DEEP_SLEEP_WAKEUP_VALID_GPIO_MASK) != 0)) /** * @brief Enable GPIO deep-sleep wake-up function. diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h index 2ffcbd74c87c..58f858b7e87e 100644 --- a/components/driver/include/driver/ledc.h +++ b/components/driver/include/driver/ledc.h @@ -61,6 +61,7 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf); * @brief LEDC update channel parameters * @note Call this function to activate the LEDC updated parameters. * After ledc_set_duty, we need to call this function to update the settings. + * And the new LEDC parameters don't take effect until the next PWM cycle. * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to * control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_duty_and_update @@ -178,6 +179,9 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t /** * @brief LEDC get duty + * This function returns the duty at the present PWM cycle. + * You shouldn't expect the function to return the new duty in the same cycle of calling ledc_update_duty, + * because duty update doesn't take effect until the next cycle. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0-7), select from ledc_channel_t @@ -360,7 +364,8 @@ void ledc_fade_func_uninstall(void); * Other duty operations will have to wait until the fade operation has finished. * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel number - * @param fade_mode Whether to block until fading done. + * @param fade_mode Whether to block until fading done. See ledc_types.h ledc_fade_mode_t for more info. + * Note that this function will not return until fading to the target duty if LEDC_FADE_WAIT_DONE mode is selected. * * @return * - ESP_OK Success diff --git a/components/driver/include/driver/spi_common.h b/components/driver/include/driver/spi_common.h index 5fee265c0adb..2c11e8c477a7 100644 --- a/components/driver/include/driver/spi_common.h +++ b/components/driver/include/driver/spi_common.h @@ -152,7 +152,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * * @param host_id SPI peripheral to free * @return * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_INVALID_STATE if not all devices on the bus are freed + * - ESP_ERR_INVALID_STATE if bus hasn't been initialized before, or not all devices on the bus are freed * - ESP_OK on success */ esp_err_t spi_bus_free(spi_host_device_t host_id); diff --git a/components/driver/include/driver/spi_master.h b/components/driver/include/driver/spi_master.h index e6ed8c5a0af6..176d4e6ccf1e 100644 --- a/components/driver/include/driver/spi_master.h +++ b/components/driver/include/driver/spi_master.h @@ -112,7 +112,6 @@ typedef struct { #define SPI_TRANS_VARIABLE_CMD (1<<5) ///< Use the ``command_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``. #define SPI_TRANS_VARIABLE_ADDR (1<<6) ///< Use the ``address_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``. #define SPI_TRANS_VARIABLE_DUMMY (1<<7) ///< Use the ``dummy_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``. -#define SPI_TRANS_SET_CD (1<<7) ///< Set the CD pin /** * This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes. diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 02dbe459e5ee..e1e9104a8c4e 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -333,7 +333,7 @@ esp_err_t uart_enable_rx_intr(uart_port_t uart_num); esp_err_t uart_disable_rx_intr(uart_port_t uart_num); /** - * @brief Disable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT) + * @brief Disable UART TX interrupt (TXFIFO_EMPTY INTERRUPT) * * @param uart_num UART port number * @@ -344,7 +344,7 @@ esp_err_t uart_disable_rx_intr(uart_port_t uart_num); esp_err_t uart_disable_tx_intr(uart_port_t uart_num); /** - * @brief Enable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT) + * @brief Enable UART TX interrupt (TXFIFO_EMPTY INTERRUPT) * * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). * @param enable 1: enable; 0: disable diff --git a/components/driver/include/driver/usb_serial_jtag.h b/components/driver/include/driver/usb_serial_jtag.h new file mode 100644 index 000000000000..e9c253b0a52a --- /dev/null +++ b/components/driver/include/driver/usb_serial_jtag.h @@ -0,0 +1,93 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "esp_err.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configuration structure for the usb-serial-jtag-driver. Can be expanded in the future + * + * @note tx_buffer_size and rx_buffer_size must be > 0 + */ +typedef struct { + uint32_t tx_buffer_size; /* Size of the buffer (in bytes) for the TX direction */ + uint32_t rx_buffer_size; /* Size of the buffer (in bytes) for the RX direction */ +} usb_serial_jtag_driver_config_t; + +#define USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT() (usb_serial_jtag_driver_config_t) {\ + .rx_buffer_size = 256,\ + .tx_buffer_size = 256,\ +} + +/** + * @brief Install USB-SERIAL-JTAG driver and set the USB-SERIAL-JTAG to the default configuration. + * + * USB-SERIAL-JTAG driver's ISR will be attached to the same CPU core that calls this function. Thus, users + * should ensure that the same core is used when calling `usb_serial_jtag_driver_uninstall()`. + * + * @note Blocking mode will result in usb_serial_jtag_write_bytes() blocking until all bytes have been written to the TX FIFO. + * + * @param usb_serial_jtag_driver_config_t Configuration for usb_serial_jtag driver. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Failed for some reason. + */ +esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_serial_jtag_config); + +/** + * @brief USB_SERIAL_JTAG read bytes from USB_SERIAL_JTAG buffer + * + * @param buf pointer to the buffer. + * @param length data length + * @param ticks_to_wait Timeout in RTOS ticks + * + * @return + * - The number of bytes read from USB_SERIAL FIFO + */ +int usb_serial_jtag_read_bytes(void* buf, uint32_t length, TickType_t ticks_to_wait); + +/** + * @brief Send data to the USB-UART port from a given buffer and length, + * + * Please ensure the `tx_buffer_size is larger than 0`, if the 'tx_buffer_size' > 0, this function will return after copying all the data to tx ring buffer, + * USB_SERIAL_JTAG ISR will then move data from the ring buffer to TX FIFO gradually. + * + * @param src data buffer address + * @param size data length to send + * @param ticks_to_wait Timeout in RTOS ticks + * + * @return + * - The number of bytes pushed to the TX FIFO + */ +int usb_serial_jtag_write_bytes(const void* src, size_t size, TickType_t ticks_to_wait); + +/** + * @brief Uninstall USB-SERIAL-JTAG driver. + * + * @return + * - ESP_OK Success + */ +esp_err_t usb_serial_jtag_driver_uninstall(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 79e942b6d9f5..515d9335ef0c 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -193,7 +193,7 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_ static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel_t channel, int hpoint_val, int duty_val, ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t duty_cycle, uint32_t duty_scale) { - portENTER_CRITICAL(&ledc_spinlock); + portENTER_CRITICAL_SAFE(&ledc_spinlock); if (hpoint_val >= 0) { ledc_hal_set_hpoint(&(p_ledc_obj[speed_mode]->ledc_hal), channel, hpoint_val); } @@ -205,7 +205,7 @@ static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel ledc_hal_set_duty_cycle(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_cycle); ledc_hal_set_duty_scale(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_scale); ledc_ls_channel_update(speed_mode, channel); - portEXIT_CRITICAL(&ledc_spinlock); + portEXIT_CRITICAL_SAFE(&ledc_spinlock); return ESP_OK; } @@ -474,8 +474,8 @@ esp_err_t ledc_set_duty_with_hpoint(ledc_mode_t speed_mode, ledc_channel_t chann hpoint, //uint32_t hpoint_val, duty, //uint32_t duty_val, 1, //uint32_t increase, - 1, //uint32_t duty_num, - 1, //uint32_t duty_cycle, + 0, //uint32_t duty_num, + 0, //uint32_t duty_cycle, 0 //uint32_t duty_scale ); _ledc_fade_hw_release(speed_mode, channel); @@ -494,8 +494,8 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t LEDC_VAL_NO_CHANGE, duty, //uint32_t duty_val, 1, //uint32_t increase, - 1, //uint32_t duty_num, - 1, //uint32_t duty_cycle, + 0, //uint32_t duty_num, + 0, //uint32_t duty_cycle, 0 //uint32_t duty_scale ); _ledc_fade_hw_release(speed_mode, channel); @@ -575,9 +575,9 @@ void IRAM_ATTR ledc_fade_isr(void* arg) ledc_calc_fade_end_channel(&intr_status, &channel); // clear interrupt - portENTER_CRITICAL(&ledc_spinlock); + portENTER_CRITICAL_ISR(&ledc_spinlock); ledc_hal_clear_fade_end_intr_status(&(p_ledc_obj[speed_mode]->ledc_hal), channel); - portEXIT_CRITICAL(&ledc_spinlock); + portEXIT_CRITICAL_ISR(&ledc_spinlock); if (s_ledc_fade_rec[speed_mode][channel] == NULL) { //fade object not initialized yet. @@ -623,9 +623,9 @@ void IRAM_ATTR ledc_fade_isr(void* arg) 1, 0); } - portENTER_CRITICAL(&ledc_spinlock); + portENTER_CRITICAL_ISR(&ledc_spinlock); ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true); - portEXIT_CRITICAL(&ledc_spinlock); + portEXIT_CRITICAL_ISR(&ledc_spinlock); } } } @@ -765,7 +765,10 @@ static void _ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, led ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_FADE_END); ledc_update_duty(speed_mode, channel); if (fade_mode == LEDC_FADE_WAIT_DONE) { - xSemaphoreTake(s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem, portMAX_DELAY); + // Waiting for fade done + _ledc_fade_hw_acquire(speed_mode, channel); + // Release hardware to support next time fade configure + _ledc_fade_hw_release(speed_mode, channel); } } @@ -807,7 +810,6 @@ esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_f LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE); _ledc_fade_hw_acquire(speed_mode, channel); _ledc_fade_start(speed_mode, channel, fade_mode); - _ledc_fade_hw_release(speed_mode, channel); return ESP_OK; } @@ -844,14 +846,13 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode"); LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel"); LEDC_ARG_CHECK(duty <= ledc_get_max_duty(speed_mode, channel), "target_duty"); + LEDC_ARG_CHECK(hpoint <= LEDC_HPOINT_VAL_MAX, "hpoint"); LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE); - LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL); - _ledc_op_lock_acquire(speed_mode, channel); + LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK, LEDC_FADE_INIT_ERROR_STR, ESP_FAIL); _ledc_fade_hw_acquire(speed_mode, channel); - _ledc_set_fade_with_step(speed_mode, channel, duty, 0, 1); - _ledc_fade_start(speed_mode, channel, LEDC_FADE_WAIT_DONE); + ledc_duty_config(speed_mode, channel, hpoint, duty, 1, 0, 0, 0); + ledc_update_duty(speed_mode, channel); _ledc_fade_hw_release(speed_mode, channel); - _ledc_op_lock_release(speed_mode, channel); return ESP_OK; } @@ -867,9 +868,6 @@ esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t ch _ledc_fade_hw_acquire(speed_mode, channel); _ledc_set_fade_with_time(speed_mode, channel, target_duty, max_fade_time_ms); _ledc_fade_start(speed_mode, channel, fade_mode); - if (fade_mode == LEDC_FADE_WAIT_DONE) { - _ledc_fade_hw_release(speed_mode, channel); - } _ledc_op_lock_release(speed_mode, channel); return ESP_OK; } @@ -888,9 +886,6 @@ esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t ch _ledc_fade_hw_acquire(speed_mode, channel); _ledc_set_fade_with_step(speed_mode, channel, target_duty, scale, cycle_num); _ledc_fade_start(speed_mode, channel, fade_mode); - if (fade_mode == LEDC_FADE_WAIT_DONE) { - _ledc_fade_hw_release(speed_mode, channel); - } _ledc_op_lock_release(speed_mode, channel); return ESP_OK; } diff --git a/components/driver/periph_ctrl.c b/components/driver/periph_ctrl.c index 80b37853266d..39c946df7af4 100644 --- a/components/driver/periph_ctrl.c +++ b/components/driver/periph_ctrl.c @@ -72,10 +72,14 @@ IRAM_ATTR void wifi_bt_common_module_disable(void) void wifi_module_enable(void) { + portENTER_CRITICAL_SAFE(&periph_spinlock); periph_ll_wifi_module_enable_clk_clear_rst(); + portEXIT_CRITICAL_SAFE(&periph_spinlock); } void wifi_module_disable(void) { + portENTER_CRITICAL_SAFE(&periph_spinlock); periph_ll_wifi_module_disable_clk_set_rst(); + portEXIT_CRITICAL_SAFE(&periph_spinlock); } diff --git a/components/driver/sdio_slave.c b/components/driver/sdio_slave.c index 8083159ebfd1..7bb255c58a88 100644 --- a/components/driver/sdio_slave.c +++ b/components/driver/sdio_slave.c @@ -241,7 +241,7 @@ static esp_err_t init_context(const sdio_slave_config_t *config) sdio_ringbuf_t *buf = &(context.hal->send_desc_queue); //one item is not used. buf->size = SDIO_SLAVE_SEND_DESC_SIZE * (config->send_queue_size+1); - buf->data = (uint8_t*)heap_caps_malloc(buf->size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + buf->data = (uint8_t*)heap_caps_malloc(buf->size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); if (buf->data == NULL) goto no_mem; sdio_slave_hal_init(context.hal); @@ -662,7 +662,8 @@ static esp_err_t recv_flush_data(void) static void sdio_intr_recv(void* arg) { portBASE_TYPE yield = 0; - while (sdio_slave_hal_recv_done(context.hal)) { + bool triggered = sdio_slave_hal_recv_done(context.hal); + while (triggered) { portENTER_CRITICAL_ISR(&context.recv_spinlock); bool has_next_item = sdio_slave_hal_recv_has_next_item(context.hal); portEXIT_CRITICAL_ISR(&context.recv_spinlock); @@ -671,8 +672,9 @@ static void sdio_intr_recv(void* arg) xSemaphoreGiveFromISR(context.recv_event, &yield); continue; //check the linked list again skip the interrupt checking } - // if no more items on the list, go back and check again the interrupt, + // if no more items on the list, check the interrupt again, // will loop until the interrupt bit is kept cleared. + triggered = sdio_slave_hal_recv_done(context.hal); } if (yield) portYIELD_FROM_ISR(); } @@ -695,7 +697,7 @@ sdio_slave_buf_handle_t sdio_slave_recv_register_buf(uint8_t *start) { SDIO_SLAVE_CHECK(esp_ptr_dma_capable(start) && (uint32_t)start%4==0, "buffer to register should be DMA capable and 32-bit aligned", NULL); - recv_desc_t *desc = (recv_desc_t*)heap_caps_malloc(sizeof(recv_desc_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + recv_desc_t *desc = (recv_desc_t*)heap_caps_malloc(sizeof(recv_desc_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); if (desc == NULL) { SDIO_SLAVE_LOGE("cannot allocate lldesc for new buffer"); return NULL; diff --git a/components/driver/spi_bus_lock.c b/components/driver/spi_bus_lock.c index 8308aa9b5141..299e080184df 100644 --- a/components/driver/spi_bus_lock.c +++ b/components/driver/spi_bus_lock.c @@ -172,7 +172,7 @@ typedef struct spi_bus_lock_t spi_bus_lock_t; #define REQUEST_BIT(mask) ((mask) << REQ_SHIFT) #define PENDING_BIT(mask) ((mask) << PENDING_SHIFT) #define DEV_MASK(id) (LOCK_BIT(1<bus_attr; diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index 43e11d43f1e1..5b05192b2a3f 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -77,7 +77,7 @@ typedef struct { static spi_slave_t *spihost[SOC_SPI_PERIPH_NUM]; -static void IRAM_ATTR spi_intr(void *arg); +static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg); static inline bool is_valid_host(spi_host_device_t host) { @@ -91,19 +91,19 @@ static inline bool is_valid_host(spi_host_device_t host) #endif } -static inline bool bus_is_iomux(spi_slave_t *host) +static inline bool SPI_SLAVE_ISR_ATTR bus_is_iomux(spi_slave_t *host) { return host->flags&SPICOMMON_BUSFLAG_IOMUX_PINS; } -static void freeze_cs(spi_slave_t *host) +static void SPI_SLAVE_ISR_ATTR freeze_cs(spi_slave_t *host) { esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, spi_periph_signal[host->id].spics_in, false); } // Use this function instead of cs_initial to avoid overwrite the output config // This is used in test by internal gpio matrix connections -static inline void restore_cs(spi_slave_t *host) +static inline void SPI_SLAVE_ISR_ATTR restore_cs(spi_slave_t *host) { if (bus_is_iomux(host)) { gpio_iomux_in(host->cfg.spics_io_num, spi_periph_signal[host->id].spics_in); diff --git a/components/driver/test/test_gpio.c b/components/driver/test/test_gpio.c index 792421838b3b..7a78f9255b6a 100644 --- a/components/driver/test/test_gpio.c +++ b/components/driver/test/test_gpio.c @@ -15,6 +15,7 @@ #include "sdkconfig.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" +#include "test_utils.h" #define WAKE_UP_IGNORE 1 // gpio_wakeup function development is not completed yet, set it deprecated. @@ -39,12 +40,12 @@ #define TEST_GPIO_EXT_IN_IO 20 // default input GPIO #define TEST_GPIO_OUTPUT_PIN 12 #define TEST_GPIO_INPUT_ONLY_PIN 46 -#define TEST_GPIO_OUTPUT_MAX GPIO_NUM_47 +#define TEST_GPIO_OUTPUT_MAX GPIO_NUM_MAX #elif CONFIG_IDF_TARGET_ESP32C3 #define TEST_GPIO_EXT_OUT_IO 2 // default output GPIO #define TEST_GPIO_EXT_IN_IO 3 // default input GPIO #define TEST_GPIO_OUTPUT_PIN 1 -#define TEST_GPIO_OUTPUT_MAX GPIO_NUM_21 +#define TEST_GPIO_OUTPUT_MAX GPIO_NUM_MAX #endif // define public test io on all boards(esp32, esp32s2, esp32s3, esp32c3) @@ -76,16 +77,16 @@ static gpio_config_t init_io(gpio_num_t num) return io_conf; } -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3) -//No runners // edge interrupt event -static void gpio_isr_edge_handler(void* arg) +__attribute__((unused)) static void gpio_isr_edge_handler(void* arg) { uint32_t gpio_num = (uint32_t) arg; - esp_rom_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num)); + esp_rom_printf("GPIO[%d] intr on core %d, val: %d\n", gpio_num, cpu_hal_get_core_id(), gpio_get_level(gpio_num)); edge_intr_times++; } +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3) +//No runners // level interrupt event with "gpio_intr_disable" static void gpio_isr_level_handler(void* arg) { @@ -388,6 +389,42 @@ TEST_CASE("GPIO enable and disable interrupt test", "[gpio][test_env=UT_T1_GPIO] } #endif //DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3) +#if !CONFIG_FREERTOS_UNICORE +static void install_isr_service_task(void *arg) +{ + uint32_t gpio_num = (uint32_t) arg; + //rising edge intr + TEST_ESP_OK(gpio_set_intr_type(gpio_num, GPIO_INTR_POSEDGE)); + TEST_ESP_OK(gpio_install_isr_service(0)); + gpio_isr_handler_add(gpio_num, gpio_isr_edge_handler, (void *) gpio_num); + vTaskSuspend(NULL); +} + +TEST_CASE("GPIO interrupt on other CPUs test", "[gpio]") +{ + TaskHandle_t gpio_task_handle; + gpio_config_t input_output_io = init_io(TEST_GPIO_EXT_OUT_IO); + input_output_io.mode = GPIO_MODE_INPUT_OUTPUT; + input_output_io.pull_up_en = 1; + TEST_ESP_OK(gpio_config(&input_output_io)); + + for (int cpu_num = 1; cpu_num < portNUM_PROCESSORS; ++cpu_num) { + // We assume unit-test task is running on core 0, so we install gpio interrupt on other cores + edge_intr_times = 0; + TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0)); + xTaskCreatePinnedToCore(install_isr_service_task, "install_isr_service_task", 2048, (void *) TEST_GPIO_EXT_OUT_IO, 1, &gpio_task_handle, cpu_num); + + vTaskDelay(200 / portTICK_RATE_MS); + TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1)); + vTaskDelay(100 / portTICK_RATE_MS); + TEST_ASSERT_EQUAL_INT(edge_intr_times, 1); + gpio_isr_handler_remove(TEST_GPIO_EXT_OUT_IO); + gpio_uninstall_isr_service(); + test_utils_task_delete(gpio_task_handle); + } +} +#endif //!CONFIG_FREERTOS_UNICORE + // ESP32 Connect GPIO18 with GPIO19, ESP32-S2 Connect GPIO17 with GPIO21, // ESP32-S3 Connect GPIO19 with GPIO20, ESP32C3 Connect GPIO2 with GPIO3 // use multimeter to test the voltage, so it is ignored in CI @@ -744,11 +781,11 @@ static void gpio_isr_handler(void* arg) */ TEST_CASE("GPIO ISR service test", "[gpio][ignore]") { - static gpio_isr_param_t io9_param = { + gpio_isr_param_t io9_param = { .gpio_num = TEST_IO_9, .isr_cnt = 0, }; - static gpio_isr_param_t io10_param = { + gpio_isr_param_t io10_param = { .gpio_num = TEST_IO_10, .isr_cnt = 0, }; diff --git a/components/driver/test/test_ledc.c b/components/driver/test/test_ledc.c index d17f1d475c47..988204da110f 100644 --- a/components/driver/test/test_ledc.c +++ b/components/driver/test/test_ledc.c @@ -63,12 +63,26 @@ static ledc_timer_config_t create_default_timer_config(void) return ledc_time_config; } +static void fade_setup(void) +{ + ledc_channel_config_t ledc_ch_config = initialize_channel_config(); + ledc_ch_config.duty = 0; + ledc_timer_config_t ledc_time_config = create_default_timer_config(); + + TEST_ESP_OK(ledc_channel_config(&ledc_ch_config)); + TEST_ESP_OK(ledc_timer_config(&ledc_time_config)); + vTaskDelay(5 / portTICK_PERIOD_MS); + + //initialize fade service + TEST_ESP_OK(ledc_fade_func_install(0)); +} + static void timer_duty_set_get(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty) { TEST_ESP_OK(ledc_set_duty(speed_mode, channel, duty)); TEST_ESP_OK(ledc_update_duty(speed_mode, channel)); - vTaskDelay(1000 / portTICK_RATE_MS); - TEST_ASSERT_EQUAL_INT32(ledc_get_duty(speed_mode, channel), duty); + vTaskDelay(100 / portTICK_RATE_MS); + TEST_ASSERT_EQUAL_INT32(duty, ledc_get_duty(speed_mode, channel)); } // use logic analyzer to view @@ -297,9 +311,9 @@ TEST_CASE("LEDC memory leak test", "[ledc]") TEST_ESP_OK(ledc_stop(ledc_time_config.speed_mode, LEDC_CHANNEL_0, 0)); } -// the duty need to be detected by waveform given by the logic analyzer -// can't get it directly, so set it "ignore" -TEST_CASE("LEDC set and get dut(with logic analyzer)", "[ledc][ignore]") +// duty should be manually checked from the waveform using a logic analyzer +// this test is enabled only for testting the settings +TEST_CASE("LEDC set and get duty", "[ledc]") { ledc_timer_t timer_list[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3}; ledc_mode_t speed_mode_list[LEDC_SPEED_MODE_MAX] = SPEED_MODE_LIST; @@ -310,61 +324,111 @@ TEST_CASE("LEDC set and get dut(with logic analyzer)", "[ledc][ignore]") } } -TEST_CASE("LEDC fade with time(logic analyzer)", "[ledc][ignore]") +TEST_CASE("LEDC fade with time", "[ledc]") { const ledc_mode_t test_speed_mode = TEST_SPEED_MODE; - ledc_channel_config_t ledc_ch_config = initialize_channel_config(); - ledc_ch_config.duty = 0; - ledc_timer_config_t ledc_time_config = create_default_timer_config(); - - TEST_ESP_OK(ledc_channel_config(&ledc_ch_config)); - TEST_ESP_OK(ledc_timer_config(&ledc_time_config)); + fade_setup(); - //initialize fade service - TEST_ESP_OK(ledc_fade_func_install(0)); - - TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 1000)); + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200)); TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE)); - // TODO: allows for 5% deviation here due to driver code (IDF-2099) - vTaskDelay(1050 / portTICK_RATE_MS); - TEST_ASSERT_EQUAL_INT32(ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0), 4000); + TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); - TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 0, 1000)); + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 0, 200)); TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT)); - vTaskDelay(1050 / portTICK_RATE_MS); - TEST_ASSERT_EQUAL_INT32(ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0), 0); + // duty should not be too far from initial value + TEST_ASSERT_INT32_WITHIN(20, 4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + vTaskDelay(210 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL_INT32(0, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); - //deinitial fade service + //deinitialize fade service ledc_fade_func_uninstall(); } -TEST_CASE("LEDC fade with step(logic analyzer)", "[ledc][ignore]") +TEST_CASE("LEDC fade with step", "[ledc]") { const ledc_mode_t test_speed_mode = TEST_SPEED_MODE; - ledc_channel_config_t ledc_ch_config = initialize_channel_config(); - ledc_ch_config.duty = 0; - ledc_timer_config_t ledc_time_config = create_default_timer_config(); + fade_setup(); - TEST_ESP_OK(ledc_channel_config(&ledc_ch_config)); - TEST_ESP_OK(ledc_timer_config(&ledc_time_config)); - - //initialize fade service. - TEST_ESP_OK(ledc_fade_func_install(0)); - - TEST_ESP_OK(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 4000, 2, 1)); + TEST_ESP_OK(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 4000, 4, 1)); TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE)); - vTaskDelay(1050 / portTICK_RATE_MS); - TEST_ASSERT_EQUAL_INT32(ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0), 4000); + TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); - TEST_ESP_OK(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 0, 4, 2)); + TEST_ESP_OK(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 0, 4, 1)); TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT)); - vTaskDelay(1050 / portTICK_RATE_MS); - TEST_ASSERT_EQUAL_INT32(ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0), 0); + // duty should not be too far from initial value + TEST_ASSERT_INT32_WITHIN(20, 4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + vTaskDelay(525 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL_INT32(0, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); //scaler=0 check TEST_ASSERT(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 4000, 0, 1) == ESP_ERR_INVALID_ARG); - //deinitial fade service + //deinitialize fade service + ledc_fade_func_uninstall(); +} + +TEST_CASE("LEDC fast switching duty with fade_wait_done", "[ledc]") +{ + const ledc_mode_t test_speed_mode = TEST_SPEED_MODE; + fade_setup(); + + // fade function will block until fading to the target duty + int64_t fade_start, fade_stop; + fade_start = esp_timer_get_time(); + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200)); + TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE)); + TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 1000, 150)); + TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE)); + TEST_ASSERT_EQUAL_INT32(1000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + fade_stop = esp_timer_get_time(); + int time_ms = (fade_stop - fade_start) / 1000; + TEST_ASSERT_TRUE(fabs(time_ms - 350) < 20); + + // next duty update will not take place until last fade reaches its target duty + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200)); + TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE)); + TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + TEST_ESP_OK(ledc_set_duty(test_speed_mode, LEDC_CHANNEL_0, 500)); + TEST_ESP_OK(ledc_update_duty(test_speed_mode, LEDC_CHANNEL_0)); + vTaskDelay(5 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL_INT32(500, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + + //deinitialize fade service + ledc_fade_func_uninstall(); +} + +TEST_CASE("LEDC fast switching duty with fade_no_wait", "[ledc]") +{ + const ledc_mode_t test_speed_mode = TEST_SPEED_MODE; + fade_setup(); + + // fade function returns immediately, but next fade still needs to wait for last fade ends + int64_t fade_start, first_fade_complete; + fade_start = esp_timer_get_time(); + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200)); + TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT)); + TEST_ASSERT_LESS_THAN(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 1000, 150)); + TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT)); + first_fade_complete = esp_timer_get_time(); + // duty should not be too far from first fade target duty + TEST_ASSERT_INT32_WITHIN(20, 4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + int time_ms = (first_fade_complete - fade_start) / 1000; + TEST_ASSERT_TRUE(fabs(time_ms - 200) < 20); + vTaskDelay(158 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL_INT32(1000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + + // next duty update will not take place until last fade reaches its target duty + TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200)); + TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT)); + TEST_ASSERT_LESS_THAN(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + TEST_ESP_OK(ledc_set_duty(test_speed_mode, LEDC_CHANNEL_0, 500)); + TEST_ESP_OK(ledc_update_duty(test_speed_mode, LEDC_CHANNEL_0)); + vTaskDelay(5 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL_INT32(500, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0)); + + //deinitialize fade service ledc_fade_func_uninstall(); } diff --git a/components/driver/test/test_rmt.c b/components/driver/test/test_rmt.c index d4db7e911984..e62e88b22274 100644 --- a/components/driver/test/test_rmt.c +++ b/components/driver/test/test_rmt.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // RMT driver unit test is based on extended NEC protocol #include #include @@ -17,7 +22,7 @@ #define RMT_TX_CHANNEL_ENCODING_END (SOC_RMT_TX_CHANNELS_NUM-1) // CI ONLY: Don't connect any other signals to this GPIO -#define RMT_DATA_IO (4) // bind signal RMT_SIG_OUT0_IDX and RMT_SIG_IN0_IDX on the same GPIO +#define RMT_DATA_IO (0) // bind signal RMT_SIG_OUT0_IDX and RMT_SIG_IN0_IDX on the same GPIO #define RMT_TESTBENCH_FLAGS_ALWAYS_ON (1<<0) #define RMT_TESTBENCH_FLAGS_CARRIER_ON (1<<1) diff --git a/components/driver/test/test_spi_slave_hd.c b/components/driver/test/test_spi_slave_hd.c index dde6448c24af..1408264e1b62 100644 --- a/components/driver/test/test_spi_slave_hd.c +++ b/components/driver/test/test_spi_slave_hd.c @@ -137,7 +137,7 @@ static void init_slave_hd(int mode, bool append_mode, const spi_slave_hd_callbac static void test_hd_init(void** arg) { TEST_ASSERT(*arg==NULL); - *arg = malloc(sizeof(testhd_context_t)); + *arg = heap_caps_malloc(sizeof(testhd_context_t), MALLOC_CAP_DMA); assert(((int)arg%4)==0); testhd_context_t* context = (testhd_context_t*)*arg; TEST_ASSERT(context!=NULL); diff --git a/components/driver/test/test_timer.c b/components/driver/test/test_timer.c index e52569a05b1a..f4203aece4b6 100644 --- a/components/driver/test/test_timer.c +++ b/components/driver/test/test_timer.c @@ -955,8 +955,8 @@ TEST_CASE("Timer memory test", "[hw_timer]") // This case will check under this fix, whether the interrupt status is cleared after timer_group initialization. static void timer_group_test_init(void) { - static const uint32_t time_ms = 100; //Alarm value 100ms. - static const uint16_t timer_div = 10; //Timer prescaler + static const uint32_t time_ms = 100; // Alarm value 100ms. + static const uint16_t timer_div = TIMER_DIVIDER; // Timer prescaler static const uint32_t ste_val = time_ms * (TIMER_BASE_CLK / timer_div / 1000); timer_config_t config = { .divider = timer_div, @@ -993,6 +993,9 @@ static void timer_group_test_second_stage(void) { TEST_ASSERT_EQUAL(ESP_RST_SW, esp_reset_reason()); timer_group_test_init(); + TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0); + // After enable the interrupt, timer alarm should not trigger immediately + TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); //After the timer_group is initialized, TIMERG0.int_raw.t0 should be cleared. TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0); } @@ -1001,3 +1004,34 @@ TEST_CASE_MULTIPLE_STAGES("timer_group software reset test", "[intr_status][intr_status = 0]", timer_group_test_first_stage, timer_group_test_second_stage); + +// +// Timer check reinitialization sequence +// +TEST_CASE("Timer check reinitialization sequence", "[hw_timer]") +{ + // 1. step - install driver + timer_group_test_init(); + // 2 - register interrupt and start timer + TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); + TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); + // Do some work + vTaskDelay(80 / portTICK_PERIOD_MS); + // 3 - deinit timer driver + TEST_ESP_OK(timer_deinit(TIMER_GROUP_0, TIMER_0)); + timer_config_t config = { + .divider = TIMER_DIVIDER, + .counter_dir = TIMER_COUNT_UP, + .counter_en = TIMER_START, + .alarm_en = TIMER_ALARM_EN, + .intr_type = TIMER_INTR_LEVEL, + .auto_reload = TIMER_AUTORELOAD_EN, + }; + // 4 - reinstall driver + TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config)); + // 5 - enable interrupt + TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); + vTaskDelay(30 / portTICK_PERIOD_MS); + // The pending timer interrupt should not be triggered + TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0); +} diff --git a/components/driver/test/test_uart.c b/components/driver/test/test_uart.c index 4ec10c2a0039..8f4d3412a1ee 100644 --- a/components/driver/test/test_uart.c +++ b/components/driver/test/test_uart.c @@ -7,6 +7,8 @@ #include "esp_system.h" // for uint32_t esp_random() #include "esp_rom_gpio.h" #include "soc/uart_periph.h" +#include "hal/uart_ll.h" +#include "hal/uart_hal.h" #define UART_TAG "Uart" #define UART_NUM1 (UART_NUM_1) @@ -354,3 +356,176 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]") free(rd_data); free(wr_data); } + +TEST_CASE("uart int state restored after flush", "[uart]") +{ + /** + * The first goal of this test is to make sure that when our RX FIFO is full, + * we can continue receiving back data after flushing + * For more details, check IDF-4374 + */ + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_APB, + }; + + const uart_port_t uart_echo = UART_NUM_1; + const int uart_tx_signal = U1TXD_OUT_IDX; + const int uart_tx = 4; + const int uart_rx = 5; + const int buf_size = 256; + const int intr_alloc_flags = 0; + + TEST_ESP_OK(uart_driver_install(uart_echo, buf_size * 2, 0, 0, NULL, intr_alloc_flags)); + TEST_ESP_OK(uart_param_config(uart_echo, &uart_config)); + TEST_ESP_OK(uart_set_pin(uart_echo, uart_tx, uart_rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + + /* Make sure UART1's RX signal is connected to TX pin + * This creates a loop that lets us receive anything we send on the UART */ + esp_rom_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false); + + uint8_t *data = (uint8_t *) malloc(buf_size); + TEST_ASSERT_NOT_NULL(data); + uart_write_bytes(uart_echo, (const char *) data, buf_size); + + /* As we set up a loopback, we can read them back on RX */ + int len = uart_read_bytes(uart_echo, data, buf_size, 1000 / portTICK_RATE_MS); + TEST_ASSERT_EQUAL(len, buf_size); + + /* Fill the RX buffer, this should disable the RX interrupts */ + int written = uart_write_bytes(uart_echo, (const char *) data, buf_size); + TEST_ASSERT_NOT_EQUAL(-1, written); + written = uart_write_bytes(uart_echo, (const char *) data, buf_size); + TEST_ASSERT_NOT_EQUAL(-1, written); + written = uart_write_bytes(uart_echo, (const char *) data, buf_size); + TEST_ASSERT_NOT_EQUAL(-1, written); + + /* Flush the input buffer, RX interrupts should be re-enabled */ + uart_flush_input(uart_echo); + written = uart_write_bytes(uart_echo, (const char *) data, buf_size); + TEST_ASSERT_NOT_EQUAL(-1, written); + len = uart_read_bytes(uart_echo, data, buf_size, 1000 / portTICK_RATE_MS); + /* len equals buf_size bytes if interrupts were indeed re-enabled */ + TEST_ASSERT_EQUAL(len, buf_size); + + /** + * Second test, make sure that if we explicitly disable the RX interrupts, + * they are NOT re-enabled after flushing + * To do so, start by cleaning the RX FIFO, disable the RX interrupts, + * flush again, send data to the UART and check that we haven't received + * any of the bytes */ + uart_flush_input(uart_echo); + uart_disable_rx_intr(uart_echo); + uart_flush_input(uart_echo); + written = uart_write_bytes(uart_echo, (const char *) data, buf_size); + TEST_ASSERT_NOT_EQUAL(-1, written); + len = uart_read_bytes(uart_echo, data, buf_size, 250 / portTICK_RATE_MS); + TEST_ASSERT_EQUAL(len, 0); + + TEST_ESP_OK(uart_driver_delete(uart_echo)); + free(data); +} + +/* Global variable shared between the ISR and the test function */ +volatile uint32_t uart_isr_happened = 0; + +static void uart_custom_isr(void* arg) { + (void) arg; + + /* Clear interrupt status and disable TX interrupt here in order to + * prevent an infinite call loop. Use the LL function to prevent + * entering a critical section from an interrupt. */ + uart_ll_disable_intr_mask(UART_LL_GET_HW(1), UART_INTR_TXFIFO_EMPTY); + uart_clear_intr_status(UART_NUM_1, UART_INTR_TXFIFO_EMPTY); + + /* Mark the interrupt as serviced */ + uart_isr_happened = 1; +} + + +/** + * This function shall always be executed by core 0. + * This is required by `uart_isr_free`. + */ +static void uart_test_custom_isr_core0(void* param) { + /** + * Setup the UART1 and make sure we can register and free a custom ISR + */ + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_APB, + }; + + const uart_port_t uart_echo = UART_NUM_1; + const int uart_tx = 4; + const int uart_rx = 5; + const int buf_size = 256; + const int intr_alloc_flags = 0; + const char msg[] = "hello world\n"; + uart_isr_handle_t handle = NULL; + + TEST_ESP_OK(uart_driver_install(uart_echo, buf_size * 2, 0, 0, NULL, intr_alloc_flags)); + TEST_ESP_OK(uart_param_config(uart_echo, &uart_config)); + TEST_ESP_OK(uart_set_pin(uart_echo, uart_tx, uart_rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + + /* Prevent the custom ISR handler from being called if UART_INTR_BRK_DET interrupt occurs. + * It shall only be called for TX interrupts. */ + uart_disable_intr_mask(uart_echo, UART_INTR_BRK_DET); + + /* Unregister the default ISR setup by the function call above */ + TEST_ESP_OK(uart_isr_free(uart_echo)); + TEST_ESP_OK(uart_isr_register(uart_echo, uart_custom_isr, NULL, intr_alloc_flags, &handle)); + /* Set the TX FIFO empty threshold to the size of the message we are sending, + * make sure it is never 0 in any case */ + TEST_ESP_OK(uart_enable_tx_intr(uart_echo, true, MAX(sizeof(msg), 1))); + uart_write_bytes(uart_echo, msg, sizeof(msg)); + + /* 10ms will be enough to receive the interrupt */ + vTaskDelay(10 / portTICK_PERIOD_MS); + + /* Make sure the ISR occured */ + TEST_ASSERT_EQUAL(uart_isr_happened, 1); + esp_rom_printf("ISR happened: %d\n", uart_isr_happened); + TEST_ESP_OK(uart_isr_free(uart_echo)); + TEST_ESP_OK(uart_driver_delete(uart_echo)); + +#if !CONFIG_FREERTOS_UNICORE + TaskHandle_t* parent_task = (TaskHandle_t*) param; + esp_rom_printf("Notifying caller\n"); + TEST_ASSERT(xTaskNotify(*parent_task, 0, eNoAction)); + vTaskDelete(NULL); +#else + (void) param; +#endif //!CONFIG_FREERTOS_UNICORE +} + + +TEST_CASE("uart can register and free custom ISRs", "[uart]") +{ +#if !CONFIG_FREERTOS_UNICORE + TaskHandle_t task_handle; + TaskHandle_t current_handler = xTaskGetCurrentTaskHandle(); + /* Run the test on a determianted core, do not allow the core to be changed + * as we will manipulate ISRs. */ + BaseType_t ret = xTaskCreatePinnedToCore(uart_test_custom_isr_core0, + "uart_test_custom_isr_core0_task", + 2048, + ¤t_handler, + 5, + &task_handle, + 0); + TEST_ASSERT(ret); + TEST_ASSERT(xTaskNotifyWait(0, 0, NULL, 1000 / portTICK_PERIOD_MS)); + (void) task_handle; +#else + uart_test_custom_isr_core0(NULL); +#endif //!CONFIG_FREERTOS_UNICORE +} diff --git a/components/driver/timer.c b/components/driver/timer.c index c04607dcdab4..c20548c365df 100644 --- a/components/driver/timer.c +++ b/components/driver/timer.c @@ -213,15 +213,17 @@ static void IRAM_ATTR timer_isr_default(void *arg) uint32_t intr_status = 0; timer_hal_get_intr_status(&(timer_obj->hal), &intr_status); if (intr_status & BIT(timer_obj->hal.idx)) { - is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args); - //Clear intrrupt status + // Clear intrrupt status timer_hal_clear_intr_status(&(timer_obj->hal)); - //If the timer is set to auto reload, we need enable it again, so it is triggered the next time. - if (timer_hal_get_auto_reload(&timer_obj->hal)) { - timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_EN); - } else { - timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_DIS); - } + uint64_t old_alarm_value = 0; + timer_hal_get_alarm_value(&(timer_obj->hal), &old_alarm_value); + // call user registered callback + is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args); + // reenable alarm if required + uint64_t new_alarm_value = 0; + timer_hal_get_alarm_value(&(timer_obj->hal), &new_alarm_value); + bool reenable_alarm = (new_alarm_value != old_alarm_value) || timer_hal_get_auto_reload(&timer_obj->hal); + timer_hal_set_alarm_enable(&(timer_obj->hal), reenable_alarm); } } TIMER_EXIT_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]); @@ -295,13 +297,13 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); timer_hal_init(&(p_timer_obj[group_num][timer_num]->hal), group_num, timer_num); - timer_hal_intr_disable(&(p_timer_obj[group_num][timer_num]->hal)); + timer_hal_reset_periph(&(p_timer_obj[group_num][timer_num]->hal)); timer_hal_clear_intr_status(&(p_timer_obj[group_num][timer_num]->hal)); timer_hal_set_auto_reload(&(p_timer_obj[group_num][timer_num]->hal), config->auto_reload); timer_hal_set_divider(&(p_timer_obj[group_num][timer_num]->hal), config->divider); timer_hal_set_counter_increase(&(p_timer_obj[group_num][timer_num]->hal), config->counter_dir); timer_hal_set_alarm_enable(&(p_timer_obj[group_num][timer_num]->hal), config->alarm_en); - timer_hal_set_level_int_enable(&(p_timer_obj[group_num][timer_num]->hal), true); + timer_hal_set_level_int_enable(&(p_timer_obj[group_num][timer_num]->hal), config->intr_type == TIMER_INTR_LEVEL); if (config->intr_type != TIMER_INTR_LEVEL) { ESP_LOGW(TIMER_TAG, "only support Level Interrupt, switch to Level Interrupt instead"); } diff --git a/components/driver/uart.c b/components/driver/uart.c index 513635571c71..34fdaae019ff 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #include +#include #include "esp_types.h" #include "esp_attr.h" #include "esp_intr_alloc.h" @@ -74,6 +75,9 @@ static const char *UART_TAG = "uart"; | (UART_INTR_BRK_DET) \ | (UART_INTR_PARITY_ERR)) + +#define UART_ENTER_CRITICAL_SAFE(mux) portENTER_CRITICAL_SAFE(mux) +#define UART_EXIT_CRITICAL_SAFE(mux) portEXIT_CRITICAL_SAFE(mux) #define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux) #define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux) #define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) @@ -124,6 +128,7 @@ typedef struct { uint8_t *rx_head_ptr; /*!< pointer to the head of RX item*/ uint8_t rx_data_buf[SOC_UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/ uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */ + uint32_t rx_int_usr_mask; /*!< RX interrupt status. Valid at any time, regardless of RX buffer status. */ uart_pat_rb_t rx_pattern_pos; int tx_buf_size; /*!< TX ring buffer size */ bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/ @@ -367,16 +372,45 @@ esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + /* Keep track of the interrupt toggling. In fact, without such variable, + * once the RX buffer is full and the RX interrupts disabled, it is + * impossible what was the previous state (enabled/disabled) of these + * interrupt masks. Thus, this will be very particularly handy when + * emptying a filled RX buffer. */ + p_uart_obj[uart_num]->rx_int_usr_mask |= enable_mask; uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), enable_mask); uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), enable_mask); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); return ESP_OK; } +/** + * @brief Function re-enabling the given interrupts (mask) if and only if + * they have not been disabled by the user. + * + * @param uart_num UART number to perform the operation on + * @param enable_mask Interrupts (flags) to be re-enabled + * + * @return ESP_OK in success, ESP_FAIL if uart_num is incorrect + */ +static esp_err_t uart_reenable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + /* Mask will only contain the interrupt flags that needs to be re-enabled + * AND which have NOT been explicitly disabled by the user. */ + uint32_t mask = p_uart_obj[uart_num]->rx_int_usr_mask & enable_mask; + uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), mask); + uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), mask); + UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); + return ESP_OK; +} + esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + p_uart_obj[uart_num]->rx_int_usr_mask &= ~disable_mask; uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), disable_mask); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); return ESP_OK; @@ -581,6 +615,9 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num) esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) { + if (enable == 0) { + return uart_disable_tx_intr(uart_num); + } UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_CHECK((thresh < SOC_UART_FIFO_LEN), "empty intr threshold error", ESP_FAIL); uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TXFIFO_EMPTY); @@ -597,6 +634,9 @@ esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg, UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); ret = esp_intr_alloc(uart_periph_signal[uart_num].irq, intr_alloc_flags, fn, arg, handle); + if (ret == ESP_OK) { + p_uart_obj[uart_num]->intr_handle = *handle; + } UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); return ret; } @@ -747,6 +787,19 @@ static int UART_ISR_ATTR uart_find_pattern_from_last(uint8_t *buf, int length, u return len; } +static uint32_t UART_ISR_ATTR uart_enable_tx_write_fifo(uart_port_t uart_num, const uint8_t *pbuf, uint32_t len) +{ + uint32_t sent_len = 0; + UART_ENTER_CRITICAL_SAFE(&(uart_context[uart_num].spinlock)); + if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { + uart_hal_set_rts(&(uart_context[uart_num].hal), 0); + uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); + } + uart_hal_write_txfifo(&(uart_context[uart_num].hal), pbuf, len, &sent_len); + UART_EXIT_CRITICAL_SAFE(&(uart_context[uart_num].spinlock)); + return sent_len; +} + //internal isr handler for default driver code. static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param) { @@ -816,19 +869,9 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param) } } if (p_uart->tx_len_tot > 0 && p_uart->tx_ptr && p_uart->tx_len_cur > 0) { - //To fill the TX FIFO. - uint32_t send_len = 0; - // Set RS485 RTS pin before transmission if the half duplex mode is enabled - if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { - UART_ENTER_CRITICAL_ISR(&(uart_context[uart_num].spinlock)); - uart_hal_set_rts(&(uart_context[uart_num].hal), 0); - uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); - UART_EXIT_CRITICAL_ISR(&(uart_context[uart_num].spinlock)); - } - uart_hal_write_txfifo(&(uart_context[uart_num].hal), - (const uint8_t *)p_uart->tx_ptr, - (p_uart->tx_len_cur > tx_fifo_rem) ? tx_fifo_rem : p_uart->tx_len_cur, - &send_len); + // To fill the TX FIFO. + uint32_t send_len = uart_enable_tx_write_fifo(uart_num, (const uint8_t *) p_uart->tx_ptr, + MIN(p_uart->tx_len_cur, tx_fifo_rem)); p_uart->tx_ptr += send_len; p_uart->tx_len_tot -= send_len; p_uart->tx_len_cur -= send_len; @@ -1032,6 +1075,7 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param) // Workaround for RS485: If the RS485 half duplex mode is active // and transmitter is in idle state then reset received buffer and reset RTS pin // skip this behavior for other UART modes + uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); UART_ENTER_CRITICAL_ISR(&(uart_context[uart_num].spinlock)); uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { @@ -1039,7 +1083,6 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param) uart_hal_set_rts(&(uart_context[uart_num].hal), 1); } UART_EXIT_CRITICAL_ISR(&(uart_context[uart_num].spinlock)); - uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); xSemaphoreGiveFromISR(p_uart_obj[uart_num]->tx_done_sem, &HPTaskAwoken); } } else { @@ -1111,13 +1154,7 @@ int uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len) } int tx_len = 0; xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); - if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_set_rts(&(uart_context[uart_num].hal), 0); - uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - } - uart_hal_write_txfifo(&(uart_context[uart_num].hal), (const uint8_t *) buffer, len, (uint32_t *)&tx_len); + tx_len = (int)uart_enable_tx_write_fifo(uart_num, (const uint8_t *) buffer, len); xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return tx_len; } @@ -1165,14 +1202,7 @@ static int uart_tx(uart_port_t uart_num, bool write_all, const char *src, size_t while (size) { //semaphore for tx_fifo available if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { - uint32_t sent = 0; - if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_set_rts(&(uart_context[uart_num].hal), 0); - uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - } - uart_hal_write_txfifo(&(uart_context[uart_num].hal), (const uint8_t *)src, size, &sent); + uint32_t sent = uart_enable_tx_write_fifo(uart_num, (const uint8_t *) src, size); if (sent < size) { p_uart_obj[uart_num]->tx_waiting_fifo = true; uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); @@ -1243,7 +1273,9 @@ static bool uart_check_buf_full(uart_port_t uart_num) p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len; p_uart_obj[uart_num]->rx_buffer_full_flg = false; UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); + /* Only re-activate UART_INTR_RXFIFO_TOUT or UART_INTR_RXFIFO_FULL + * interrupts if they were NOT explicitly disabled by the user. */ + uart_reenable_intr_mask(p_uart_obj[uart_num]->uart_num, UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL); return true; } } @@ -1321,16 +1353,6 @@ esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t *size) esp_err_t uart_flush(uart_port_t uart_num) __attribute__((alias("uart_flush_input"))); -static esp_err_t uart_disable_intr_mask_and_return_prev(uart_port_t uart_num, uint32_t disable_mask, uint32_t *prev_mask) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - *prev_mask = uart_hal_get_intr_ena_status(&uart_context[uart_num].hal) & disable_mask; - uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), disable_mask); - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - return ESP_OK; -} - esp_err_t uart_flush_input(uart_port_t uart_num) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); @@ -1338,11 +1360,12 @@ esp_err_t uart_flush_input(uart_port_t uart_num) uart_obj_t *p_uart = p_uart_obj[uart_num]; uint8_t *data; size_t size; - uint32_t prev_mask; //rx sem protect the ring buffer read related functions xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY); - uart_disable_intr_mask_and_return_prev(uart_num, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT, &prev_mask); + UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT); + UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); while (true) { if (p_uart->rx_head_ptr) { vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr); @@ -1390,7 +1413,9 @@ esp_err_t uart_flush_input(uart_port_t uart_num) p_uart->rx_cur_remain = 0; p_uart->rx_head_ptr = NULL; uart_hal_rxfifo_rst(&(uart_context[uart_num].hal)); - uart_enable_intr_mask(uart_num, prev_mask); + /* Only re-enable UART_INTR_RXFIFO_TOUT or UART_INTR_RXFIFO_FULL if they + * were explicitly enabled by the user. */ + uart_reenable_intr_mask(uart_num, UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL); xSemaphoreGive(p_uart->rx_mux); return ESP_OK; } @@ -1566,6 +1591,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b p_uart_obj[uart_num]->tx_waiting_fifo = false; p_uart_obj[uart_num]->rx_ptr = NULL; p_uart_obj[uart_num]->rx_cur_remain = 0; + p_uart_obj[uart_num]->rx_int_usr_mask = UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT; p_uart_obj[uart_num]->rx_head_ptr = NULL; p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; p_uart_obj[uart_num]->uart_select_notif_callback = NULL; diff --git a/components/driver/usb_serial_jtag.c b/components/driver/usb_serial_jtag.c new file mode 100644 index 000000000000..6d84152b2dd9 --- /dev/null +++ b/components/driver/usb_serial_jtag.c @@ -0,0 +1,213 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "esp_log.h" +#include "hal/usb_serial_jtag_ll.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/ringbuf.h" +#include "esp_intr_alloc.h" +#include "driver/usb_serial_jtag.h" +#include "soc/periph_defs.h" + +// The hardware buffer max size is 64 +#define USB_SER_JTAG_ENDP_SIZE (64) +#define USB_SER_JTAG_RX_MAX_SIZE (64) + +typedef struct{ + intr_handle_t intr_handle; /*!< USB-SERIAL-JTAG interrupt handler */ + + // RX parameters + RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler */ + uint32_t rx_buf_size; /*!< TX buffer size */ + uint8_t rx_data_buf[64]; /*!< Data buffer to stash FIFO data */ + + // TX parameters + uint32_t tx_buf_size; /*!< TX buffer size */ + RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler */ +} usb_serial_jtag_obj_t; + +static usb_serial_jtag_obj_t *p_usb_serial_jtag_obj = NULL; + +static const char* USB_SERIAL_JTAG_TAG = "usb_serial_jtag"; + +static void usb_serial_jtag_write_and_flush(const uint8_t *buf, uint32_t wr_len) +{ + usb_serial_jtag_ll_write_txfifo(buf, wr_len); + usb_serial_jtag_ll_txfifo_flush(); +} + +static void usb_serial_jtag_isr_handler_default(void *arg) { + portBASE_TYPE xTaskWoken = 0; + uint32_t usbjtag_intr_status = 0; + usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask(); + + if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) { + // Interrupt tells us the host picked up the data we sent. If we have more data, we can put it in the buffer and the host will pick that up next. + // Send data in isr. + if (usb_serial_jtag_ll_txfifo_writable() == 1) { + // We disable the interrupt here so that the interrupt won't be triggered if there is no data to send. + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + size_t queued_size; + uint8_t *queued_buff = (uint8_t *)xRingbufferReceiveUpToFromISR(p_usb_serial_jtag_obj->tx_ring_buf, &queued_size, 64); + // If the hardware fifo is avaliable, write in it. Otherwise, do nothing. + if (queued_buff != NULL) { //Although tx_queued_bytes may be larger than 0. We may have interrupt before xRingbufferSend() was called. + //Copy the queued buffer into the TX FIFO + usb_serial_jtag_ll_clr_intr_sts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + usb_serial_jtag_write_and_flush(queued_buff, queued_size); + vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buff, &xTaskWoken); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + } + } else { + usb_serial_jtag_ll_clr_intr_sts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + } + } + + if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) { + // read rx buffer(max length is 64), and send avaliable data to ringbuffer. + // Ensure the rx buffer size is larger than RX_MAX_SIZE. + usb_serial_jtag_ll_clr_intr_sts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(p_usb_serial_jtag_obj->rx_data_buf, USB_SER_JTAG_RX_MAX_SIZE); + xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, p_usb_serial_jtag_obj->rx_data_buf, rx_fifo_len, &xTaskWoken); + } + + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_serial_jtag_config) +{ + esp_err_t err = ESP_OK; + if (p_usb_serial_jtag_obj != NULL) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "Driver already installed"); + return ESP_ERR_INVALID_STATE; + } + if (usb_serial_jtag_config->rx_buffer_size <= USB_SER_JTAG_RX_MAX_SIZE) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "RX buffer is not prepared or is perpared so small"); + return ESP_ERR_INVALID_ARG; + } + if (usb_serial_jtag_config->tx_buffer_size <= 0) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "TX buffer is not prepared"); + return ESP_ERR_INVALID_ARG; + } + p_usb_serial_jtag_obj = (usb_serial_jtag_obj_t*) heap_caps_calloc(1, sizeof(usb_serial_jtag_obj_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); + p_usb_serial_jtag_obj->rx_buf_size = usb_serial_jtag_config->rx_buffer_size; + p_usb_serial_jtag_obj->tx_buf_size = usb_serial_jtag_config->tx_buffer_size; + if (p_usb_serial_jtag_obj == NULL) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "memory allocate error"); + err = ESP_ERR_NO_MEM; + goto _exit; + } + + p_usb_serial_jtag_obj->rx_ring_buf = xRingbufferCreate(p_usb_serial_jtag_obj->rx_buf_size, RINGBUF_TYPE_BYTEBUF); + if (p_usb_serial_jtag_obj->rx_ring_buf == NULL) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "ringbuffer create error"); + err = ESP_ERR_NO_MEM; + goto _exit; + } + + p_usb_serial_jtag_obj->tx_ring_buf = xRingbufferCreate(usb_serial_jtag_config->tx_buffer_size, RINGBUF_TYPE_BYTEBUF); + if (p_usb_serial_jtag_obj->rx_ring_buf == NULL) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "ringbuffer create error"); + err = ESP_ERR_NO_MEM; + goto _exit; + } + + usb_serial_jtag_ll_clr_intr_sts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY| + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY| + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + + err = esp_intr_alloc(ETS_USB_INTR_SOURCE, 0, usb_serial_jtag_isr_handler_default, NULL, &p_usb_serial_jtag_obj->intr_handle); + if (err != ESP_OK) { + goto _exit; + } + return ESP_OK; + +_exit: + usb_serial_jtag_driver_uninstall(); + return err; +} + +int usb_serial_jtag_read_bytes(void* buf, uint32_t length, TickType_t ticks_to_wait) +{ + uint8_t *data = NULL; + size_t data_read_len = 0; + + if (length == 0) { + return 0; + } + + // Recieve new data from ISR + data = (uint8_t*) xRingbufferReceiveUpTo(p_usb_serial_jtag_obj->rx_ring_buf, &data_read_len, (portTickType) ticks_to_wait, length); + if (data == NULL) { + // If there is no data received from ringbuffer, return 0 directly. + return 0; + } + + memcpy((uint8_t*)buf, data, data_read_len); + vRingbufferReturnItem(p_usb_serial_jtag_obj->rx_ring_buf, data); + data = NULL; + + return data_read_len; +} + +int usb_serial_jtag_write_bytes(const void* src, size_t size, TickType_t ticks_to_wait) +{ + if (size == 0) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "size should be larger than 0"); + return ESP_ERR_INVALID_ARG; + } + if (src == NULL) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "Invalid buffer pointer"); + return ESP_ERR_INVALID_ARG; + } + if (p_usb_serial_jtag_obj == NULL) { + ESP_LOGE(USB_SERIAL_JTAG_TAG, "The driver hasn't been initialized"); + } + + const uint8_t *buff = (const uint8_t *)src; + // Blocking method, Sending data to ringbuffer, and handle the data in ISR. + xRingbufferSend(p_usb_serial_jtag_obj->tx_ring_buf, (void*) (buff), size, ticks_to_wait); + // Now trigger the ISR to read data from the ring buffer. + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + return size; +} + +esp_err_t usb_serial_jtag_driver_uninstall(void) +{ + if(p_usb_serial_jtag_obj == NULL) { + ESP_LOGI(USB_SERIAL_JTAG_TAG, "ALREADY NULL"); + return ESP_OK; + } + + //Disable tx/rx interrupt. + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + esp_intr_free(p_usb_serial_jtag_obj->intr_handle); + + if(p_usb_serial_jtag_obj->rx_ring_buf) { + vRingbufferDelete(p_usb_serial_jtag_obj->rx_ring_buf); + p_usb_serial_jtag_obj->rx_ring_buf = NULL; + } + if(p_usb_serial_jtag_obj->tx_ring_buf) { + vRingbufferDelete(p_usb_serial_jtag_obj->tx_ring_buf); + p_usb_serial_jtag_obj->tx_ring_buf = NULL; + } + heap_caps_free(p_usb_serial_jtag_obj); + p_usb_serial_jtag_obj = NULL; + return ESP_OK; +} diff --git a/components/efuse/efuse_table_gen.py b/components/efuse/efuse_table_gen.py index 5b66f73ab136..7f729d95b8b8 100755 --- a/components/efuse/efuse_table_gen.py +++ b/components/efuse/efuse_table_gen.py @@ -112,9 +112,11 @@ def expand_vars(f): # fill group names = [p.field_name for p in res] duplicates = set(n for n in names if names.count(n) > 1) - if len(duplicates) != 0: + for dname in duplicates: i_count = 0 for p in res: + if p.field_name != dname: + continue if len(duplicates.intersection([p.field_name])) != 0: p.group = str(i_count) i_count += 1 diff --git a/components/efuse/esp32c3/esp_efuse_table.c b/components/efuse/esp32c3/esp_efuse_table.c index a9bf09331584..aae1f0b383be 100644 --- a/components/efuse/esp32c3/esp_efuse_table.c +++ b/components/efuse/esp32c3/esp_efuse_table.c @@ -17,7 +17,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table fe80e03d1417e5757ef89923f8d01d33 +// md5_digest_table 1e8e57d0ae14e863954678b88fe4c99f // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -84,7 +84,7 @@ static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { }; static const esp_efuse_desc_t WR_DIS_GROUP_3[] = { - {EFUSE_BLK0, 18, 1}, // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_LEGACY_SPI_BOOT UART_PRINT_CHANNEL DIS_TINY_BASIC DIS_USB_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION, + {EFUSE_BLK0, 18, 1}, // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT DIS_USB_SERIAL_JTAG_ROM_PRINT DIS_TINY_BASIC DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION, }; static const esp_efuse_desc_t WR_DIS_BLK1[] = { @@ -175,10 +175,6 @@ static const esp_efuse_desc_t DIS_FORCE_DOWNLOAD[] = { {EFUSE_BLK0, 44, 1}, // Disable force chip go to download mode function, }; -static const esp_efuse_desc_t DIS_USB[] = { - {EFUSE_BLK0, 45, 1}, // Disable USB function, -}; - static const esp_efuse_desc_t DIS_CAN[] = { {EFUSE_BLK0, 46, 1}, // Disable CAN function, }; @@ -287,20 +283,16 @@ static const esp_efuse_desc_t DIS_DOWNLOAD_MODE[] = { {EFUSE_BLK0, 128, 1}, // Disble download mode include boot_mode[3:0] is 0 1 2 3 6 7, }; -static const esp_efuse_desc_t DIS_LEGACY_SPI_BOOT[] = { - {EFUSE_BLK0, 129, 1}, // Disable_Legcy_SPI_boot mode include boot_mode[3:0] is 4, +static const esp_efuse_desc_t DIS_DIRECT_BOOT[] = { + {EFUSE_BLK0, 129, 1}, // Disable direct boot mode, }; -static const esp_efuse_desc_t UART_PRINT_CHANNEL[] = { - {EFUSE_BLK0, 130, 1}, // 0: UART0. 1: UART1, +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + {EFUSE_BLK0, 130, 1}, // Disable usb serial jtag print during rom boot, }; -static const esp_efuse_desc_t FLASH_ECC_MODE[] = { - {EFUSE_BLK0, 131, 1}, // Set this bit to set flsah ecc mode. 0:flash ecc 16to18 byte mode. 1:flash ecc 16to17 byte mode, -}; - -static const esp_efuse_desc_t DIS_USB_DOWNLOAD_MODE[] = { - {EFUSE_BLK0, 132, 1}, // Disable download through USB, +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 132, 1}, // Disable download through USB-Serial-JTAG, }; static const esp_efuse_desc_t ENABLE_SECURITY_DOWNLOAD[] = { @@ -311,22 +303,6 @@ static const esp_efuse_desc_t UART_PRINT_CONTROL[] = { {EFUSE_BLK0, 134, 2}, // b00:force print. b01:control by GPIO8 - low level print. b10:control by GPIO8 - high level print. b11:force disable print., }; -static const esp_efuse_desc_t PIN_POWER_SELECTION[] = { - {EFUSE_BLK0, 136, 1}, // GPIO33-GPIO37 power supply selection in ROM code. 0:VDD3P3_CPU. 1:VDD_SPI., -}; - -static const esp_efuse_desc_t FLASH_TYPE[] = { - {EFUSE_BLK0, 137, 1}, // Connected Flash interface type. 0: 4 data line. 1: 8 data line, -}; - -static const esp_efuse_desc_t FLASH_PAGE_SIZE[] = { - {EFUSE_BLK0, 138, 2}, // Flash page size, -}; - -static const esp_efuse_desc_t FLASH_ECC_EN[] = { - {EFUSE_BLK0, 140, 1}, // Enable ECC for flash boot, -}; - static const esp_efuse_desc_t FORCE_SEND_RESUME[] = { {EFUSE_BLK0, 141, 1}, // Force ROM code to send a resume command during SPI boot, }; @@ -335,6 +311,10 @@ static const esp_efuse_desc_t SECURE_VERSION[] = { {EFUSE_BLK0, 142, 16}, // Secure version for anti-rollback, }; +static const esp_efuse_desc_t ERR_RST_ENABLE[] = { + {EFUSE_BLK0, 159, 1}, // Use BLOCK0 to check error record registers, +}; + static const esp_efuse_desc_t MAC_FACTORY[] = { {EFUSE_BLK1, 40, 8}, // Factory MAC addr [0], {EFUSE_BLK1, 32, 8}, // Factory MAC addr [1], @@ -584,7 +564,7 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { }; const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_3[] = { - &WR_DIS_GROUP_3[0], // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_LEGACY_SPI_BOOT UART_PRINT_CHANNEL DIS_TINY_BASIC DIS_USB_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION + &WR_DIS_GROUP_3[0], // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT DIS_USB_SERIAL_JTAG_ROM_PRINT DIS_TINY_BASIC DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION NULL }; @@ -698,11 +678,6 @@ const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[] = { NULL }; -const esp_efuse_desc_t* ESP_EFUSE_DIS_USB[] = { - &DIS_USB[0], // Disable USB function - NULL -}; - const esp_efuse_desc_t* ESP_EFUSE_DIS_CAN[] = { &DIS_CAN[0], // Disable CAN function NULL @@ -838,23 +813,18 @@ const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[] = { NULL }; -const esp_efuse_desc_t* ESP_EFUSE_DIS_LEGACY_SPI_BOOT[] = { - &DIS_LEGACY_SPI_BOOT[0], // Disable_Legcy_SPI_boot mode include boot_mode[3:0] is 4 +const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[] = { + &DIS_DIRECT_BOOT[0], // Disable direct boot mode NULL }; -const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[] = { - &UART_PRINT_CHANNEL[0], // 0: UART0. 1: UART1 +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + &DIS_USB_SERIAL_JTAG_ROM_PRINT[0], // Disable usb serial jtag print during rom boot NULL }; -const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[] = { - &FLASH_ECC_MODE[0], // Set this bit to set flsah ecc mode. 0:flash ecc 16to18 byte mode. 1:flash ecc 16to17 byte mode - NULL -}; - -const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DOWNLOAD_MODE[] = { - &DIS_USB_DOWNLOAD_MODE[0], // Disable download through USB +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + &DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[0], // Disable download through USB-Serial-JTAG NULL }; @@ -868,26 +838,6 @@ const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[] = { NULL }; -const esp_efuse_desc_t* ESP_EFUSE_PIN_POWER_SELECTION[] = { - &PIN_POWER_SELECTION[0], // GPIO33-GPIO37 power supply selection in ROM code. 0:VDD3P3_CPU. 1:VDD_SPI. - NULL -}; - -const esp_efuse_desc_t* ESP_EFUSE_FLASH_TYPE[] = { - &FLASH_TYPE[0], // Connected Flash interface type. 0: 4 data line. 1: 8 data line - NULL -}; - -const esp_efuse_desc_t* ESP_EFUSE_FLASH_PAGE_SIZE[] = { - &FLASH_PAGE_SIZE[0], // Flash page size - NULL -}; - -const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_EN[] = { - &FLASH_ECC_EN[0], // Enable ECC for flash boot - NULL -}; - const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[] = { &FORCE_SEND_RESUME[0], // Force ROM code to send a resume command during SPI boot NULL @@ -898,6 +848,11 @@ const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_ERR_RST_ENABLE[] = { + &ERR_RST_ENABLE[0], // Use BLOCK0 to check error record registers + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[] = { &MAC_FACTORY[0], // Factory MAC addr [0] &MAC_FACTORY[1], // Factory MAC addr [1] diff --git a/components/efuse/esp32c3/esp_efuse_table.csv b/components/efuse/esp32c3/esp_efuse_table.csv index 90d301295280..5851ab064956 100644 --- a/components/efuse/esp32c3/esp_efuse_table.csv +++ b/components/efuse/esp32c3/esp_efuse_table.csv @@ -29,7 +29,7 @@ WR_DIS_KEY5_PURPOSE, EFUSE_BLK0, 13, 1, Write protection for key_purpose. KEY5 WR_DIS_SECURE_BOOT_EN, EFUSE_BLK0, 15, 1, Write protection for SECURE_BOOT_EN WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE,EFUSE_BLK0, 16, 1, Write protection for SECURE_BOOT_AGGRESSIVE_REVOKE - WR_DIS_GROUP_3, EFUSE_BLK0, 18, 1, Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_LEGACY_SPI_BOOT UART_PRINT_CHANNEL DIS_TINY_BASIC DIS_USB_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION + WR_DIS_GROUP_3, EFUSE_BLK0, 18, 1, Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT DIS_USB_SERIAL_JTAG_ROM_PRINT DIS_TINY_BASIC DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION WR_DIS_BLK1, EFUSE_BLK0, 20, 1, Write protection for EFUSE_BLK1. MAC_SPI_8M_SYS WR_DIS_SYS_DATA_PART1, EFUSE_BLK0, 21, 1, Write protection for EFUSE_BLK2. SYS_DATA_PART1 WR_DIS_USER_DATA, EFUSE_BLK0, 22, 1, Write protection for EFUSE_BLK3. USER_DATA @@ -55,7 +55,6 @@ DIS_DOWNLOAD_ICACHE, EFUSE_BLK0, 42, 1, Disable Icache in download mode DIS_USB_DEVICE, EFUSE_BLK0, 43, 1, Disable USB_DEVICE DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 44, 1, Disable force chip go to download mode function - DIS_USB, EFUSE_BLK0, 45, 1, Disable USB function DIS_CAN, EFUSE_BLK0, 46, 1, Disable CAN function JTAG_SEL_ENABLE, EFUSE_BLK0, 47, 1, Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio10 when both reg_dis_usb_jtag and reg_dis_pad_jtag are equal to 0. SOFT_DIS_JTAG, EFUSE_BLK0, 48, 3, Set these bits to disable JTAG in the soft way (odd number 1 means disable). JTAG can be enabled in HMAC module. @@ -89,18 +88,14 @@ # EFUSE_RD_REPEAT_DATA3_REG # DIS_DOWNLOAD_MODE, EFUSE_BLK0, 128, 1, Disble download mode include boot_mode[3:0] is 0 1 2 3 6 7 - DIS_LEGACY_SPI_BOOT, EFUSE_BLK0, 129, 1, Disable_Legcy_SPI_boot mode include boot_mode[3:0] is 4 - UART_PRINT_CHANNEL, EFUSE_BLK0, 130, 1, 0: UART0. 1: UART1 - FLASH_ECC_MODE, EFUSE_BLK0, 131, 1, Set this bit to set flsah ecc mode. 0:flash ecc 16to18 byte mode. 1:flash ecc 16to17 byte mode - DIS_USB_DOWNLOAD_MODE, EFUSE_BLK0, 132, 1, Disable download through USB + DIS_DIRECT_BOOT, EFUSE_BLK0, 129, 1, Disable direct boot mode + DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 130, 1, Disable usb serial jtag print during rom boot + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE,EFUSE_BLK0, 132, 1, Disable download through USB-Serial-JTAG ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 133, 1, Enable security download mode UART_PRINT_CONTROL, EFUSE_BLK0, 134, 2, b00:force print. b01:control by GPIO8 - low level print. b10:control by GPIO8 - high level print. b11:force disable print. - PIN_POWER_SELECTION, EFUSE_BLK0, 136, 1, GPIO33-GPIO37 power supply selection in ROM code. 0:VDD3P3_CPU. 1:VDD_SPI. - FLASH_TYPE, EFUSE_BLK0, 137, 1, Connected Flash interface type. 0: 4 data line. 1: 8 data line - FLASH_PAGE_SIZE, EFUSE_BLK0, 138, 2, Flash page size - FLASH_ECC_EN, EFUSE_BLK0, 140, 1, Enable ECC for flash boot FORCE_SEND_RESUME, EFUSE_BLK0, 141, 1, Force ROM code to send a resume command during SPI boot SECURE_VERSION, EFUSE_BLK0, 142, 16, Secure version for anti-rollback + ERR_RST_ENABLE, EFUSE_BLK0, 159, 1, Use BLOCK0 to check error record registers, 0 - without check. # EFUSE_RD_REPEAT_DATA4_REG # diff --git a/components/efuse/esp32c3/include/esp_efuse_table.h b/components/efuse/esp32c3/include/esp_efuse_table.h index 2ecdf5c46d68..fe6e76673e90 100644 --- a/components/efuse/esp32c3/include/esp_efuse_table.h +++ b/components/efuse/esp32c3/include/esp_efuse_table.h @@ -17,7 +17,7 @@ extern "C" { #endif -// md5_digest_table fe80e03d1417e5757ef89923f8d01d33 +// md5_digest_table 1e8e57d0ae14e863954678b88fe4c99f // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -62,7 +62,6 @@ extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[]; extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_ICACHE[]; extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DEVICE[]; extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[]; -extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB[]; extern const esp_efuse_desc_t* ESP_EFUSE_DIS_CAN[]; extern const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[]; extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[]; @@ -90,18 +89,14 @@ extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[]; extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[]; extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[]; extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[]; -extern const esp_efuse_desc_t* ESP_EFUSE_DIS_LEGACY_SPI_BOOT[]; -extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[]; -extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[]; -extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DOWNLOAD_MODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[]; extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[]; extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[]; -extern const esp_efuse_desc_t* ESP_EFUSE_PIN_POWER_SELECTION[]; -extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TYPE[]; -extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_PAGE_SIZE[]; -extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_EN[]; extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[]; extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ERR_RST_ENABLE[]; extern const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[]; extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CLK[]; extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_Q_D1[]; diff --git a/components/efuse/esp32s3/esp_efuse_table.c b/components/efuse/esp32s3/esp_efuse_table.c index cca177cdf35a..d9b5fe941633 100644 --- a/components/efuse/esp32s3/esp_efuse_table.c +++ b/components/efuse/esp32s3/esp_efuse_table.c @@ -17,7 +17,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 32d4e5502110edd26bdad463b5ac1d2d +// md5_digest_table 9295c8aa9c48d48dc42c78456bd02645 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -84,7 +84,7 @@ static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { }; static const esp_efuse_desc_t WR_DIS_GROUP_3[] = { - {EFUSE_BLK0, 18, 1}, // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_LEGACY_SPI_BOOT UART_PRINT_CHANNEL DIS_USB_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION, + {EFUSE_BLK0, 18, 1}, // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT DIS_USB_SERIAL_JTAG_ROM_PRINT DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION, }; static const esp_efuse_desc_t WR_DIS_BLK1[] = { @@ -287,20 +287,20 @@ static const esp_efuse_desc_t DIS_DOWNLOAD_MODE[] = { {EFUSE_BLK0, 128, 1}, // Disble download mode include boot_mode[3:0] is 0 1 2 3 6 7, }; -static const esp_efuse_desc_t DIS_LEGACY_SPI_BOOT[] = { - {EFUSE_BLK0, 129, 1}, // Disable_Legcy_SPI_boot mode include boot_mode[3:0] is 4, +static const esp_efuse_desc_t DIS_DIRECT_BOOT[] = { + {EFUSE_BLK0, 129, 1}, // Disable direct boot mode, }; -static const esp_efuse_desc_t UART_PRINT_CHANNEL[] = { - {EFUSE_BLK0, 130, 1}, // 0: UART0. 1: UART1, +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + {EFUSE_BLK0, 130, 1}, // Disable usb serial jtag print during rom boot, }; static const esp_efuse_desc_t FLASH_ECC_MODE[] = { {EFUSE_BLK0, 131, 1}, // Configures the ECC mode for SPI flash. 0:16-byte to 18-byte mode. 1:16-byte to 17-byte mode, }; -static const esp_efuse_desc_t DIS_USB_DOWNLOAD_MODE[] = { - {EFUSE_BLK0, 132, 1}, // Disable download through USB, +static const esp_efuse_desc_t DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 132, 1}, // Set this bit to disable download through USB-Serial-JTAG, }; static const esp_efuse_desc_t ENABLE_SECURITY_DOWNLOAD[] = { @@ -335,6 +335,10 @@ static const esp_efuse_desc_t SECURE_VERSION[] = { {EFUSE_BLK0, 142, 16}, // Secure version for anti-rollback, }; +static const esp_efuse_desc_t DIS_USB_OTG_DOWNLOAD_MODE[] = { + {EFUSE_BLK0, 159, 1}, // Set this bit to disable download through USB-OTG, +}; + static const esp_efuse_desc_t MAC_FACTORY[] = { {EFUSE_BLK1, 40, 8}, // Factory MAC addr [0], {EFUSE_BLK1, 32, 8}, // Factory MAC addr [1], @@ -524,7 +528,7 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = { }; const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_GROUP_3[] = { - &WR_DIS_GROUP_3[0], // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_LEGACY_SPI_BOOT UART_PRINT_CHANNEL DIS_USB_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION + &WR_DIS_GROUP_3[0], // Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT DIS_USB_SERIAL_JTAG_ROM_PRINT DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION NULL }; @@ -778,13 +782,13 @@ const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[] = { NULL }; -const esp_efuse_desc_t* ESP_EFUSE_DIS_LEGACY_SPI_BOOT[] = { - &DIS_LEGACY_SPI_BOOT[0], // Disable_Legcy_SPI_boot mode include boot_mode[3:0] is 4 +const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[] = { + &DIS_DIRECT_BOOT[0], // Disable direct boot mode NULL }; -const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[] = { - &UART_PRINT_CHANNEL[0], // 0: UART0. 1: UART1 +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[] = { + &DIS_USB_SERIAL_JTAG_ROM_PRINT[0], // Disable usb serial jtag print during rom boot NULL }; @@ -793,8 +797,8 @@ const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[] = { NULL }; -const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DOWNLOAD_MODE[] = { - &DIS_USB_DOWNLOAD_MODE[0], // Disable download through USB +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[] = { + &DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[0], // Set this bit to disable download through USB-Serial-JTAG NULL }; @@ -838,6 +842,11 @@ const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_OTG_DOWNLOAD_MODE[] = { + &DIS_USB_OTG_DOWNLOAD_MODE[0], // Set this bit to disable download through USB-OTG + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[] = { &MAC_FACTORY[0], // Factory MAC addr [0] &MAC_FACTORY[1], // Factory MAC addr [1] diff --git a/components/efuse/esp32s3/esp_efuse_table.csv b/components/efuse/esp32s3/esp_efuse_table.csv index ae9163c70303..55559ad6ca8f 100644 --- a/components/efuse/esp32s3/esp_efuse_table.csv +++ b/components/efuse/esp32s3/esp_efuse_table.csv @@ -28,7 +28,7 @@ WR_DIS_KEY5_PURPOSE, EFUSE_BLK0, 13, 1, Write protection for key_purpose. KEY5 WR_DIS_SECURE_BOOT_EN, EFUSE_BLK0, 15, 1, Write protection for SECURE_BOOT_EN WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE,EFUSE_BLK0, 16, 1, Write protection for SECURE_BOOT_AGGRESSIVE_REVOKE - WR_DIS_GROUP_3, EFUSE_BLK0, 18, 1, Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_LEGACY_SPI_BOOT UART_PRINT_CHANNEL DIS_USB_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION + WR_DIS_GROUP_3, EFUSE_BLK0, 18, 1, Write protection for FLASH_TPUW DIS_DOWNLOAD_MODE DIS_DIRECT_BOOT DIS_USB_SERIAL_JTAG_ROM_PRINT DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL PIN_POWER_SELECTION FLASH_TYPE FORCE_SEND_RESUME SECURE_VERSION WR_DIS_BLK1, EFUSE_BLK0, 20, 1, Write protection for EFUSE_BLK1. MAC_SPI_8M_SYS WR_DIS_SYS_DATA_PART1, EFUSE_BLK0, 21, 1, Write protection for EFUSE_BLK2. SYS_DATA_PART1 WR_DIS_USER_DATA, EFUSE_BLK0, 22, 1, Write protection for EFUSE_BLK3. USER_DATA @@ -88,10 +88,10 @@ # EFUSE_RD_REPEAT_DATA3_REG # DIS_DOWNLOAD_MODE, EFUSE_BLK0, 128, 1, Disble download mode include boot_mode[3:0] is 0 1 2 3 6 7 - DIS_LEGACY_SPI_BOOT, EFUSE_BLK0, 129, 1, Disable_Legcy_SPI_boot mode include boot_mode[3:0] is 4 - UART_PRINT_CHANNEL, EFUSE_BLK0, 130, 1, 0: UART0. 1: UART1 + DIS_DIRECT_BOOT, EFUSE_BLK0, 129, 1, Disable direct boot mode + DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 130, 1, Disable usb serial jtag print during rom boot FLASH_ECC_MODE, EFUSE_BLK0, 131, 1, Configures the ECC mode for SPI flash. 0:16-byte to 18-byte mode. 1:16-byte to 17-byte mode - DIS_USB_DOWNLOAD_MODE, EFUSE_BLK0, 132, 1, Disable download through USB + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE,EFUSE_BLK0, 132, 1, Set this bit to disable download through USB-Serial-JTAG ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 133, 1, Enable security download mode UART_PRINT_CONTROL, EFUSE_BLK0, 134, 2, b00:force print. b01:control by GPIO46 - low level print. b10:control by GPIO46 - high level print. b11:force disable print. PIN_POWER_SELECTION, EFUSE_BLK0, 136, 1, GPIO33-GPIO37 power supply selection in ROM code. 0:VDD3P3_CPU. 1:VDD_SPI. @@ -100,6 +100,7 @@ FLASH_ECC_EN, EFUSE_BLK0, 140, 1, Enables ECC in Flash boot mode FORCE_SEND_RESUME, EFUSE_BLK0, 141, 1, Force ROM code to send a resume command during SPI boot SECURE_VERSION, EFUSE_BLK0, 142, 16, Secure version for anti-rollback + DIS_USB_OTG_DOWNLOAD_MODE, EFUSE_BLK0, 159, 1, Set this bit to disable download through USB-OTG # EFUSE_RD_REPEAT_DATA4_REG # diff --git a/components/efuse/esp32s3/include/esp_efuse_table.h b/components/efuse/esp32s3/include/esp_efuse_table.h index 9b1733d51fcf..5e470450f244 100644 --- a/components/efuse/esp32s3/include/esp_efuse_table.h +++ b/components/efuse/esp32s3/include/esp_efuse_table.h @@ -17,7 +17,7 @@ extern "C" { #endif -// md5_digest_table 32d4e5502110edd26bdad463b5ac1d2d +// md5_digest_table 9295c8aa9c48d48dc42c78456bd02645 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -90,10 +90,10 @@ extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[]; extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[]; extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[]; extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[]; -extern const esp_efuse_desc_t* ESP_EFUSE_DIS_LEGACY_SPI_BOOT[]; -extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CHANNEL[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[]; extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_MODE[]; -extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_DOWNLOAD_MODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[]; extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[]; extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[]; extern const esp_efuse_desc_t* ESP_EFUSE_PIN_POWER_SELECTION[]; @@ -102,6 +102,7 @@ extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_PAGE_SIZE[]; extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_ECC_EN[]; extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[]; extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_OTG_DOWNLOAD_MODE[]; extern const esp_efuse_desc_t* ESP_EFUSE_MAC_FACTORY[]; extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_CLK[]; extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_Q_D1[]; diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 5e0d3d12774f..0413801fab8e 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -763,6 +763,20 @@ esp_err_t esp_efuse_write_keys(esp_efuse_purpose_t purposes[], uint8_t keys[][32 #endif // not CONFIG_IDF_TARGET_ESP32 +/** + * @brief Checks eFuse errors in BLOCK0. + * + * @note Refers to ESP32-C3 only. + * + * It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set. + * If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart. + * + * @return + * - ESP_OK: No errors in BLOCK0. + * - ESP_FAIL: Error in BLOCK0 requiring reboot. + */ +esp_err_t esp_efuse_check_errors(void); + #ifdef __cplusplus } #endif diff --git a/components/efuse/private_include/esp32/esp_efuse_utility.h b/components/efuse/private_include/esp32/esp_efuse_utility.h index 0208c82d7d03..7925ddaafe4a 100644 --- a/components/efuse/private_include/esp32/esp_efuse_utility.h +++ b/components/efuse/private_include/esp32/esp_efuse_utility.h @@ -18,6 +18,9 @@ extern "C" { #endif +#define ESP_EFUSE_LEN_OF_3_4_SCHEME_BLOCK_IN_BYTES (24) +#define ESP_EFUSE_LEN_OF_REPEAT_BLOCK_IN_BYTES (16) + #define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */ #define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK3 diff --git a/components/efuse/private_include/esp_efuse_utility.h b/components/efuse/private_include/esp_efuse_utility.h index 5345b0bbab50..3dcab77a8e1a 100644 --- a/components/efuse/private_include/esp_efuse_utility.h +++ b/components/efuse/private_include/esp_efuse_utility.h @@ -101,8 +101,12 @@ esp_err_t esp_efuse_utility_fill_buff(unsigned int num_reg, esp_efuse_block_t ef * * If CONFIG_EFUSE_VIRTUAL is set, writing will not be performed. * After the function is completed, the writing registers are cleared. + * + * @return + * - ESP_OK: The operation was successfully completed. + * - ESP_FAIL: The operation was not successfully completed. */ -void esp_efuse_utility_burn_efuses(void); +esp_err_t esp_efuse_utility_burn_efuses(void); /** * @brief Returns the number of array elements for placing these "bits" in an array with the length of each element equal to "size_of_base". @@ -150,11 +154,38 @@ void esp_efuse_utility_erase_virt_blocks(void); */ esp_err_t esp_efuse_utility_apply_new_coding_scheme(void); +/** + * @brief Checks eFuse errors in BLOCK0. + * + * @note Refers to ESP32-C3 only. + * + * It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set. + * If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart. + * + * @return + * - ESP_OK: No errors in BLOCK0. + * - ESP_FAIL: Error in BLOCK0 requiring reboot. + */ +esp_err_t esp_efuse_utility_check_errors(void); + /** * @brief Efuse read operation: copies data from physical efuses to efuse read registers. */ void esp_efuse_utility_clear_program_registers(void); +/** + * @brief Checks the correctness of burned data in the given block. + * + * @note Internal use. Do not call it. + * + * @param[in] block Index of efuse block. + * @param[in] r_data_len Block length for reading data in bytes (multiple of 4). + * + * @return True - written data are correct. + * False - written data are incorrect. + */ +bool esp_efuse_utility_is_correct_written_data(esp_efuse_block_t block, unsigned r_data_len); + #ifdef __cplusplus } #endif diff --git a/components/efuse/src/esp32/esp_efuse_utility.c b/components/efuse/src/esp32/esp_efuse_utility.c index 7d95f09cc078..d4f67a72e1fd 100644 --- a/components/efuse/src/esp32/esp_efuse_utility.c +++ b/components/efuse/src/esp32/esp_efuse_utility.c @@ -22,6 +22,8 @@ static const char *TAG = "efuse"; +#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x0F << (4 * (block)))) + #ifdef CONFIG_EFUSE_VIRTUAL extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK]; #endif // CONFIG_EFUSE_VIRTUAL @@ -34,12 +36,14 @@ const esp_efuse_range_addr_t range_read_addr_blocks[] = { {EFUSE_BLK3_RDATA0_REG, EFUSE_BLK3_RDATA7_REG} // range address of EFUSE_BLK3 }; -/*Range addresses to write blocks*/ +static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 }; + +/*Range addresses to write blocks (it is not real regs, it is a buffer) */ const esp_efuse_range_addr_t range_write_addr_blocks[] = { - {EFUSE_BLK0_WDATA0_REG, EFUSE_BLK0_WDATA6_REG}, // range address of EFUSE_BLK0 - {EFUSE_BLK1_WDATA0_REG, EFUSE_BLK1_WDATA7_REG}, // range address of EFUSE_BLK1 - {EFUSE_BLK2_WDATA0_REG, EFUSE_BLK2_WDATA7_REG}, // range address of EFUSE_BLK2 - {EFUSE_BLK3_WDATA0_REG, EFUSE_BLK3_WDATA7_REG} // range address of EFUSE_BLK3 + {(uint32_t) &write_mass_blocks[EFUSE_BLK0][0], (uint32_t) &write_mass_blocks[EFUSE_BLK0][6]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK1][0], (uint32_t) &write_mass_blocks[EFUSE_BLK1][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK2][0], (uint32_t) &write_mass_blocks[EFUSE_BLK2][7]}, + {(uint32_t) &write_mass_blocks[EFUSE_BLK3][0], (uint32_t) &write_mass_blocks[EFUSE_BLK3][7]}, }; #define EFUSE_CONF_WRITE 0x5A5A /* eFuse_pgm_op_ena, force no rd/wr disable. */ @@ -48,6 +52,16 @@ const esp_efuse_range_addr_t range_write_addr_blocks[] = { #define EFUSE_CMD_READ 0x01 /* Command to read. */ #ifndef CONFIG_EFUSE_VIRTUAL +/* Addresses to write blocks*/ +const uint32_t start_write_addr[] = { + EFUSE_BLK0_WDATA0_REG, + EFUSE_BLK1_WDATA0_REG, + EFUSE_BLK2_WDATA0_REG, + EFUSE_BLK3_WDATA0_REG, +}; + +static void apply_repeat_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len); + // Update Efuse timing configuration static esp_err_t esp_efuse_set_timing(void) { @@ -71,52 +85,151 @@ static esp_err_t esp_efuse_set_timing(void) REG_SET_FIELD(EFUSE_CLK_REG, EFUSE_CLK_SEL1, clk_sel1); return ESP_OK; } + +__attribute__((always_inline)) static inline bool efuse_ll_get_dec_warnings(unsigned block) +{ + if (block == 0 || block > 4) { + return false; + } + uint32_t error_reg = REG_GET_FIELD(EFUSE_DEC_STATUS_REG, EFUSE_DEC_WARNINGS); + return ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block - 1) != 0; +} + +bool efuse_hal_is_coding_error_in_block(unsigned block) +{ + return block > 0 && + esp_efuse_get_coding_scheme(block) == EFUSE_CODING_SCHEME_3_4 && + efuse_ll_get_dec_warnings(block); +} + #endif // ifndef CONFIG_EFUSE_VIRTUAL +static void efuse_hal_clear_program_registers(void) +{ + for (uint32_t r = EFUSE_BLK0_WDATA0_REG; r <= EFUSE_BLK0_WDATA6_REG; r += 4) { + REG_WRITE(r, 0); + } + for (uint32_t r = EFUSE_BLK1_WDATA0_REG; r <= EFUSE_BLK1_WDATA7_REG; r += 4) { + REG_WRITE(r, 0); + } + for (uint32_t r = EFUSE_BLK2_WDATA0_REG; r <= EFUSE_BLK2_WDATA7_REG; r += 4) { + REG_WRITE(r, 0); + } + for (uint32_t r = EFUSE_BLK3_WDATA0_REG; r <= EFUSE_BLK3_WDATA7_REG; r += 4) { + REG_WRITE(r, 0); + } +} + // Efuse read operation: copies data from physical efuses to efuse read registers. void esp_efuse_utility_clear_program_registers(void) { - REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ); + efuse_hal_clear_program_registers(); +} + +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; } // Burn values written to the efuse write registers -void esp_efuse_utility_burn_efuses(void) +esp_err_t esp_efuse_utility_burn_efuses(void) { + esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); - for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) { - esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(num_block); - if (scheme == EFUSE_CODING_SCHEME_3_4) { - uint8_t buf[COUNT_EFUSE_REG_PER_BLOCK * 4] = { 0 }; - int i = 0; - for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4, ++i) { - *((uint32_t*)buf + i) = REG_READ(addr_wr_block); - } - int j = 0; - uint32_t out_buf[COUNT_EFUSE_REG_PER_BLOCK] = { 0 }; - for (int k = 0; k < 4; ++k, ++j) { - memcpy((uint8_t*)out_buf + j * 6, &buf[k * 8], 6); - } - for (int k = 0; k < COUNT_EFUSE_REG_PER_BLOCK; ++k) { - REG_WRITE(range_write_addr_blocks[num_block].start + k * 4, out_buf[k]); - } - } + for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block); } } -#else - esp_efuse_set_timing(); - // Permanently update values written to the efuse write registers - REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_WRITE); - REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_PGM); - while (REG_READ(EFUSE_CMD_REG) != 0) {}; - REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ); - REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_READ); - while (REG_READ(EFUSE_CMD_REG) != 0) {}; +#else // CONFIG_EFUSE_VIRTUAL + if (esp_efuse_set_timing() != ESP_OK) { + ESP_LOGE(TAG, "Efuse fields are not burnt"); + } else { + // Permanently update values written to the efuse write registers + // It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks. + for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { + esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(num_block); + bool need_burn_block = false; + for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { + if (REG_READ(addr_wr_block) != 0) { + need_burn_block = true; + break; + } + } + if (!need_burn_block) { + continue; + } + if (error) { + // It is done for a use case: BLOCK2 (Flash encryption key) could have an error (incorrect written data) + // in this case we can not burn any data into BLOCK0 because it might set read/write protections of BLOCK2. + ESP_LOGE(TAG, "BLOCK%d can not be burned because a previous block got an error, skipped.", num_block); + continue; + } + efuse_hal_clear_program_registers(); + unsigned w_data_len; + unsigned r_data_len; + if (scheme == EFUSE_CODING_SCHEME_3_4) { + esp_efuse_utility_apply_34_encoding((void *)range_write_addr_blocks[num_block].start, (uint32_t *)start_write_addr[num_block], ESP_EFUSE_LEN_OF_3_4_SCHEME_BLOCK_IN_BYTES); + r_data_len = ESP_EFUSE_LEN_OF_3_4_SCHEME_BLOCK_IN_BYTES; + w_data_len = 32; + } else if (scheme == EFUSE_CODING_SCHEME_REPEAT) { + apply_repeat_encoding((void *)range_write_addr_blocks[num_block].start, (uint32_t *)start_write_addr[num_block], ESP_EFUSE_LEN_OF_REPEAT_BLOCK_IN_BYTES); + r_data_len = ESP_EFUSE_LEN_OF_REPEAT_BLOCK_IN_BYTES; + w_data_len = 32; + } else { + r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t); + w_data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); + memcpy((void *)start_write_addr[num_block], (void *)range_write_addr_blocks[num_block].start, w_data_len); + } + + uint32_t backup_write_data[8]; + memcpy(backup_write_data, (void *)start_write_addr[num_block], w_data_len); + int repeat_burn_op = 1; + bool correct_written_data; + bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_before) { + ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); + } + bool coding_error_occurred; + + do { + ESP_LOGI(TAG, "BURN BLOCK%d", num_block); + // BURN a block + REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_WRITE); + REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_PGM); + while (REG_READ(EFUSE_CMD_REG) != 0) {}; + REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ); + REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_READ); + while (REG_READ(EFUSE_CMD_REG) != 0) {}; + + bool coding_error_after = efuse_hal_is_coding_error_in_block(num_block); + coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + if (coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); + } + + correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + if (!correct_written_data || coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); + memcpy((void *)start_write_addr[num_block], (void *)backup_write_data, w_data_len); + } + + } while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3); + + if (coding_error_occurred) { + ESP_LOGW(TAG, "Coding error was not fixed"); + } + if (!correct_written_data) { + ESP_LOGE(TAG, "Written data are incorrect"); + error = ESP_FAIL; + } + } + } #endif // CONFIG_EFUSE_VIRTUAL esp_efuse_utility_reset(); + return error; } esp_err_t esp_efuse_utility_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len) @@ -148,19 +261,15 @@ esp_err_t esp_efuse_utility_apply_34_encoding(const uint8_t *in_bytes, uint32_t return ESP_OK; } -static bool read_w_data_and_check_fill(esp_efuse_block_t num_block, uint32_t *buf_w_data) +#ifndef CONFIG_EFUSE_VIRTUAL + +static void apply_repeat_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len) { - bool blk_is_filled = false; - int i = 0; - for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4, ++i) { - buf_w_data[i] = REG_READ(addr_wr_block); - if (buf_w_data[i] != 0) { - REG_WRITE(addr_wr_block, 0); - blk_is_filled = true; - } + for (unsigned i = 0; i < 2; i++) { + memcpy(&out_words[i * 4], (uint32_t *)in_bytes, in_bytes_len); } - return blk_is_filled; } +#endif // CONFIG_EFUSE_VIRTUAL static void read_r_data(esp_efuse_block_t num_block, uint32_t* buf_r_data) { @@ -170,27 +279,30 @@ static void read_r_data(esp_efuse_block_t num_block, uint32_t* buf_r_data) } } -// After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values. -// This function reads EFUSE_BLKx_WDATAx_REG registers, applies coding scheme and writes encoded values back to EFUSE_BLKx_WDATAx_REG. +// This function just checkes that given data for blocks will not rise a coding issue during the burn operation. +// Encoded data will be set during the burn operation. esp_err_t esp_efuse_utility_apply_new_coding_scheme() { - uint8_t buf_w_data[COUNT_EFUSE_REG_PER_BLOCK * 4]; uint8_t buf_r_data[COUNT_EFUSE_REG_PER_BLOCK * 4]; - uint32_t reg[COUNT_EFUSE_REG_PER_BLOCK]; // start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE. for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) { esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(num_block); - // check and apply a new coding scheme. if (scheme != EFUSE_CODING_SCHEME_NONE) { - memset(buf_w_data, 0, sizeof(buf_w_data)); - memset((uint8_t*)reg, 0, sizeof(reg)); - if (read_w_data_and_check_fill(num_block, (uint32_t*)buf_w_data) == true) { + bool is_write_data = false; + for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { + if (REG_READ(addr_wr_block)) { + is_write_data = true; + break; + } + } + if (is_write_data) { read_r_data(num_block, (uint32_t*)buf_r_data); + uint8_t* buf_w_data = (uint8_t*)range_write_addr_blocks[num_block].start; if (scheme == EFUSE_CODING_SCHEME_3_4) { if (*((uint32_t*)buf_w_data + 6) != 0 || *((uint32_t*)buf_w_data + 7) != 0) { return ESP_ERR_CODING; } - for (int i = 0; i < 24; ++i) { + for (int i = 0; i < ESP_EFUSE_LEN_OF_3_4_SCHEME_BLOCK_IN_BYTES; ++i) { if (buf_w_data[i] != 0) { int st_offset_buf = (i / 6) * 6; // check that place is free. @@ -200,32 +312,14 @@ esp_err_t esp_efuse_utility_apply_new_coding_scheme() return ESP_ERR_CODING; } } - - esp_err_t err = esp_efuse_utility_apply_34_encoding(&buf_w_data[st_offset_buf], reg, 6); - if (err != ESP_OK) { - return err; - } - - int num_reg = (st_offset_buf / 6) * 2; - for (int r = 0; r < 2; r++) { - REG_WRITE(range_write_addr_blocks[num_block].start + (num_reg + r) * 4, reg[r]); - } - i = st_offset_buf + 5; } } } else if (scheme == EFUSE_CODING_SCHEME_REPEAT) { - uint32_t* buf_32 = (uint32_t*)buf_w_data; for (int i = 4; i < 8; ++i) { - if (*(buf_32 + i) != 0) { + if (*((uint32_t*)buf_w_data + i) != 0) { return ESP_ERR_CODING; } } - for (int i = 0; i < 4; ++i) { - if (buf_32[i] != 0) { - REG_WRITE(range_write_addr_blocks[num_block].start + i * 4, buf_32[i]); - REG_WRITE(range_write_addr_blocks[num_block].start + (i + 4) * 4, buf_32[i]); - } - } } } } diff --git a/components/efuse/src/esp32c3/esp_efuse_utility.c b/components/efuse/src/esp32c3/esp_efuse_utility.c index 71532881f7ed..bf4b6d12cd3a 100644 --- a/components/efuse/src/esp32c3/esp_efuse_utility.c +++ b/components/efuse/src/esp32c3/esp_efuse_utility.c @@ -1,16 +1,8 @@ -// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "sdkconfig.h" @@ -23,6 +15,9 @@ static const char *TAG = "efuse"; +#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x08 << (4 * (block)))) +#define ESP_EFUSE_BLOCK_ERROR_NUM_BITS(error_reg, block) ((error_reg) & (0x07 << (4 * (block)))) + #ifdef CONFIG_EFUSE_VIRTUAL extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK]; #endif // CONFIG_EFUSE_VIRTUAL @@ -59,31 +54,97 @@ const esp_efuse_range_addr_t range_write_addr_blocks[] = { {(uint32_t) &write_mass_blocks[EFUSE_BLK10][0], (uint32_t) &write_mass_blocks[EFUSE_BLK10][7]}, }; -#ifndef CONFIG_EFUSE_VIRTUAL // Update Efuse timing configuration static esp_err_t esp_efuse_set_timing(void) { - // efuse clock is fixed in ESP32-C3, so the ets_efuse_set_timing() function - // takes an argument for compatibility with older ROM functions but it's ignored. - int res = ets_efuse_set_timing(0); - assert(res == 0); + REG_SET_FIELD(EFUSE_WR_TIM_CONF2_REG, EFUSE_PWR_OFF_NUM, 0x190); + return ESP_OK; +} - REG_SET_FIELD(EFUSE_WR_TIM_CONF2_REG, EFUSE_PWR_OFF_NUM, 0x60); +static void efuse_read(void) +{ + esp_efuse_set_timing(); + REG_WRITE(EFUSE_CONF_REG, EFUSE_READ_OP_CODE); + REG_WRITE(EFUSE_CMD_REG, EFUSE_READ_CMD); - return ESP_OK; + while (REG_GET_BIT(EFUSE_CMD_REG, EFUSE_READ_CMD) != 0) { } + /*Due to a hardware error, we have to read READ_CMD again to make sure the efuse clock is normal*/ + while (REG_GET_BIT(EFUSE_CMD_REG, EFUSE_READ_CMD) != 0) { } } + +#ifndef CONFIG_EFUSE_VIRTUAL +static void efuse_program(esp_efuse_block_t block) +{ + esp_efuse_set_timing(); + + REG_WRITE(EFUSE_CONF_REG, EFUSE_WRITE_OP_CODE); + + REG_WRITE(EFUSE_CMD_REG, ((block << EFUSE_BLK_NUM_S) & EFUSE_BLK_NUM_M) | EFUSE_PGM_CMD); + + while (REG_GET_BIT(EFUSE_CMD_REG, EFUSE_PGM_CMD) != 0) { }; + + ets_efuse_clear_program_registers(); + efuse_read(); +} + +static bool efuse_hal_is_coding_error_in_block(unsigned block) +{ + if (block == 0) { + for (unsigned i = 0; i < 5; i++) { + if (REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4)) { + return true; + } + } + } else if (block <= 10) { + // The order of error in these regs is different only for the C3 chip. + // Fail bit (mask=0x8): + // EFUSE_RD_RS_ERR0_REG: (hi) BLOCK7, BLOCK6, BLOCK5, BLOCK4, BLOCK3, BLOCK2, BLOCK1, ------ (low) + // EFUSE_RD_RS_ERR1_REG: BLOCK9, BLOCK8 + // Error num bits (mask=0x7): + // EFUSE_RD_RS_ERR0_REG: (hi) BLOCK8, BLOCK7, BLOCK6, BLOCK5, BLOCK4, BLOCK3, BLOCK2, BLOCK1 (low) + // EFUSE_RD_RS_ERR1_REG: BLOCK10, BLOCK9 + // BLOCK10 is not presented in the error regs. + uint32_t err_fail_reg = REG_READ(EFUSE_RD_RS_ERR0_REG + (block / 8) * 4); + uint32_t err_num_reg = REG_READ(EFUSE_RD_RS_ERR0_REG + ((block - 1) / 8) * 4); + return (ESP_EFUSE_BLOCK_ERROR_BITS(err_fail_reg, block % 8) != 0) || (ESP_EFUSE_BLOCK_ERROR_NUM_BITS(err_num_reg, (block - 1) % 8) != 0); + } + return false; +} + #endif // ifndef CONFIG_EFUSE_VIRTUAL // Efuse read operation: copies data from physical efuses to efuse read registers. void esp_efuse_utility_clear_program_registers(void) { - ets_efuse_read(); + efuse_read(); ets_efuse_clear_program_registers(); } + +esp_err_t esp_efuse_utility_check_errors(void) +{ + if (REG_GET_BIT(EFUSE_RD_REPEAT_DATA3_REG, EFUSE_ERR_RST_ENABLE)) { + for (unsigned i = 0; i < 5; i++) { + uint32_t error_reg = REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4); + if (error_reg) { + uint32_t data_reg = REG_READ(EFUSE_RD_REPEAT_DATA0_REG + i * 4); + if (error_reg & data_reg) { + // For 0001 situation (4x coding scheme): + // an error bit points that data bit is wrong in case the data bit equals 1. (need to reboot in this case). + ESP_EARLY_LOGE(TAG, "Error in EFUSE_RD_REPEAT_DATA%d_REG of BLOCK0 (error_reg=0x%08x, data_reg=0x%08x). Need to reboot", i, error_reg, data_reg); + efuse_read(); + return ESP_FAIL; + } + } + } + } + return ESP_OK; +} + // Burn values written to the efuse write registers -void esp_efuse_utility_burn_efuses(void) +esp_err_t esp_efuse_utility_burn_efuses(void) { + esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { @@ -92,30 +153,90 @@ void esp_efuse_utility_burn_efuses(void) virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block); } } -#else +#else // CONFIG_EFUSE_VIRTUAL if (esp_efuse_set_timing() != ESP_OK) { ESP_LOGE(TAG, "Efuse fields are not burnt"); } else { // Permanently update values written to the efuse write registers // It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks. for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { + bool need_burn_block = false; for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { if (REG_READ(addr_wr_block) != 0) { - if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { - uint8_t block_rs[12]; - ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); - memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); - } - int data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); - memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); - ets_efuse_program(num_block); + need_burn_block = true; break; } } + if (!need_burn_block) { + continue; + } + if (error) { + // It is done for a use case: BLOCK2 (Flash encryption key) could have an error (incorrect written data) + // in this case we can not burn any data into BLOCK0 because it might set read/write protections of BLOCK2. + ESP_LOGE(TAG, "BLOCK%d can not be burned because a previous block got an error, skipped.", num_block); + continue; + } + ets_efuse_clear_program_registers(); + if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { + uint8_t block_rs[12]; + ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); + memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); + } + unsigned r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t); + unsigned data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); + + uint32_t backup_write_data[8 + 3]; // 8 words are data and 3 words are RS coding data + memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); + int repeat_burn_op = 1; + bool correct_written_data; + bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_before) { + ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); + } + bool coding_error_occurred; + + do { + ESP_LOGI(TAG, "BURN BLOCK%d", num_block); + efuse_program(num_block); // BURN a block + + bool coding_error_after; + for (unsigned i = 0; i < 5; i++) { + efuse_read(); + coding_error_after = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_after == true) { + break; + } + } + coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + if (coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); + } + + correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + if (!correct_written_data || coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); + } + + } while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3); + + if (coding_error_occurred) { + ESP_LOGW(TAG, "Coding error was not fixed"); + if (num_block == 0) { + ESP_LOGE(TAG, "BLOCK0 got a coding error, which might be critical for security"); + error = ESP_FAIL; + } + } + if (!correct_written_data) { + ESP_LOGE(TAG, "Written data are incorrect"); + error = ESP_FAIL; + } } } #endif // CONFIG_EFUSE_VIRTUAL esp_efuse_utility_reset(); + return error; } // After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values. diff --git a/components/efuse/src/esp32s2/esp_efuse_fields.c b/components/efuse/src/esp32s2/esp_efuse_fields.c index f9174ca9e288..e85eb2b1d7af 100644 --- a/components/efuse/src/esp32s2/esp_efuse_fields.c +++ b/components/efuse/src/esp32s2/esp_efuse_fields.c @@ -33,7 +33,7 @@ uint8_t esp_efuse_get_chip_ver(void) { // should return the same value as bootloader_common_get_chip_revision() uint32_t chip_ver = 0; - // TODO: ESP32S2 does not have this field + esp_efuse_read_field_blob(ESP_EFUSE_WAFER_VERSION, &chip_ver, ESP_EFUSE_WAFER_VERSION[0]->bit_count); return chip_ver; } diff --git a/components/efuse/src/esp32s2/esp_efuse_utility.c b/components/efuse/src/esp32s2/esp_efuse_utility.c index 5dd43b64b1e4..d179586b889d 100644 --- a/components/efuse/src/esp32s2/esp_efuse_utility.c +++ b/components/efuse/src/esp32s2/esp_efuse_utility.c @@ -23,6 +23,8 @@ static const char *TAG = "efuse"; +#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x0F << (4 * (block)))) + #ifdef CONFIG_EFUSE_VIRTUAL extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK]; #endif // CONFIG_EFUSE_VIRTUAL @@ -66,6 +68,25 @@ static esp_err_t esp_efuse_set_timing(void) uint32_t clock_hz = esp_clk_apb_freq(); return ets_efuse_set_timing(clock_hz) ? ESP_FAIL : ESP_OK; } + +static bool efuse_hal_is_coding_error_in_block(unsigned block) +{ + if (block == 0) { + for (unsigned i = 0; i < 5; i++) { + if (REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4)) { + return true; + } + } + } else if (block <= 10) { + // EFUSE_RD_RS_ERR0_REG: (hi) BLOCK8, BLOCK7, BLOCK6, BLOCK5, BLOCK4, BLOCK3, BLOCK2, BLOCK1 (low) + // EFUSE_RD_RS_ERR1_REG: BLOCK10, BLOCK9 + block--; + uint32_t error_reg = REG_READ(EFUSE_RD_RS_ERR0_REG + (block / 8) * 4); + return ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block % 8) != 0; + } + return false; +} + #endif // ifndef CONFIG_EFUSE_VIRTUAL // Efuse read operation: copies data from physical efuses to efuse read registers. @@ -75,9 +96,15 @@ void esp_efuse_utility_clear_program_registers(void) ets_efuse_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers -void esp_efuse_utility_burn_efuses(void) +esp_err_t esp_efuse_utility_burn_efuses(void) { + esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { @@ -86,30 +113,90 @@ void esp_efuse_utility_burn_efuses(void) virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block); } } -#else +#else // CONFIG_EFUSE_VIRTUAL if (esp_efuse_set_timing() != ESP_OK) { ESP_LOGE(TAG, "Efuse fields are not burnt"); } else { // Permanently update values written to the efuse write registers // It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks. for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { + bool need_burn_block = false; for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { if (REG_READ(addr_wr_block) != 0) { - if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { - uint8_t block_rs[12]; - ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); - memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); - } - int data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); - memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); - ets_efuse_program(num_block); + need_burn_block = true; break; } } + if (!need_burn_block) { + continue; + } + if (error) { + // It is done for a use case: BLOCK2 (Flash encryption key) could have an error (incorrect written data) + // in this case we can not burn any data into BLOCK0 because it might set read/write protections of BLOCK2. + ESP_LOGE(TAG, "BLOCK%d can not be burned because a previous block got an error, skipped.", num_block); + continue; + } + ets_efuse_clear_program_registers(); + if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { + uint8_t block_rs[12]; + ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); + memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); + } + unsigned r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t); + unsigned data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); + + uint32_t backup_write_data[8 + 3]; // 8 words are data and 3 words are RS coding data + memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); + int repeat_burn_op = 1; + bool correct_written_data; + bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_before) { + ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); + } + bool coding_error_occurred; + + do { + ESP_LOGI(TAG, "BURN BLOCK%d", num_block); + ets_efuse_program(num_block); // BURN a block + + bool coding_error_after; + for (unsigned i = 0; i < 5; i++) { + ets_efuse_read(); + coding_error_after = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_after == true) { + break; + } + } + coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + if (coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); + } + + correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + if (!correct_written_data || coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); + } + + } while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3); + + if (coding_error_occurred) { + ESP_LOGW(TAG, "Coding error was not fixed"); + if (num_block == 0) { + ESP_LOGE(TAG, "BLOCK0 got a coding error, which might be critical for security"); + error = ESP_FAIL; + } + } + if (!correct_written_data) { + ESP_LOGE(TAG, "Written data are incorrect"); + error = ESP_FAIL; + } } } #endif // CONFIG_EFUSE_VIRTUAL esp_efuse_utility_reset(); + return error; } // After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values. diff --git a/components/efuse/src/esp32s3/esp_efuse_utility.c b/components/efuse/src/esp32s3/esp_efuse_utility.c index 697ad87f303e..6c3482e61b5e 100644 --- a/components/efuse/src/esp32s3/esp_efuse_utility.c +++ b/components/efuse/src/esp32s3/esp_efuse_utility.c @@ -23,6 +23,8 @@ static const char *TAG = "efuse"; +#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x0F << (4 * (block)))) + #ifdef CONFIG_EFUSE_VIRTUAL extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK]; #endif // CONFIG_EFUSE_VIRTUAL @@ -66,6 +68,25 @@ static esp_err_t esp_efuse_set_timing(void) uint32_t clock_hz = esp_clk_apb_freq(); return ets_efuse_set_timing(clock_hz) ? ESP_FAIL : ESP_OK; } + +static bool efuse_hal_is_coding_error_in_block(unsigned block) +{ + if (block == 0) { + for (unsigned i = 0; i < 5; i++) { + if (REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4)) { + return true; + } + } + } else if (block <= 10) { + // EFUSE_RD_RS_ERR0_REG: (hi) BLOCK8, BLOCK7, BLOCK6, BLOCK5, BLOCK4, BLOCK3, BLOCK2, BLOCK1 (low) + // EFUSE_RD_RS_ERR1_REG: BLOCK10, BLOCK9 + block--; + uint32_t error_reg = REG_READ(EFUSE_RD_RS_ERR0_REG + (block / 8) * 4); + return ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block % 8) != 0; + } + return false; +} + #endif // ifndef CONFIG_EFUSE_VIRTUAL // Efuse read operation: copies data from physical efuses to efuse read registers. @@ -75,9 +96,15 @@ void esp_efuse_utility_clear_program_registers(void) ets_efuse_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers -void esp_efuse_utility_burn_efuses(void) +esp_err_t esp_efuse_utility_burn_efuses(void) { + esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { @@ -86,30 +113,90 @@ void esp_efuse_utility_burn_efuses(void) virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block); } } -#else +#else // CONFIG_EFUSE_VIRTUAL if (esp_efuse_set_timing() != ESP_OK) { ESP_LOGE(TAG, "Efuse fields are not burnt"); } else { // Permanently update values written to the efuse write registers // It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks. for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { + bool need_burn_block = false; for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) { if (REG_READ(addr_wr_block) != 0) { - if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { - uint8_t block_rs[12]; - ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); - memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); - } - int data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); - memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); - ets_efuse_program(num_block); + need_burn_block = true; break; } } + if (!need_burn_block) { + continue; + } + if (error) { + // It is done for a use case: BLOCK2 (Flash encryption key) could have an error (incorrect written data) + // in this case we can not burn any data into BLOCK0 because it might set read/write protections of BLOCK2. + ESP_LOGE(TAG, "BLOCK%d can not be burned because a previous block got an error, skipped.", num_block); + continue; + } + ets_efuse_clear_program_registers(); + if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) { + uint8_t block_rs[12]; + ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs); + memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs)); + } + unsigned r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t); + unsigned data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len); + + uint32_t backup_write_data[8 + 3]; // 8 words are data and 3 words are RS coding data + memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); + int repeat_burn_op = 1; + bool correct_written_data; + bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_before) { + ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); + } + bool coding_error_occurred; + + do { + ESP_LOGI(TAG, "BURN BLOCK%d", num_block); + ets_efuse_program(num_block); // BURN a block + + bool coding_error_after; + for (unsigned i = 0; i < 5; i++) { + ets_efuse_read(); + coding_error_after = efuse_hal_is_coding_error_in_block(num_block); + if (coding_error_after == true) { + break; + } + } + coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + if (coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); + } + + correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + if (!correct_written_data || coding_error_occurred) { + ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); + memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); + } + + } while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3); + + if (coding_error_occurred) { + ESP_LOGW(TAG, "Coding error was not fixed"); + if (num_block == 0) { + ESP_LOGE(TAG, "BLOCK0 got a coding error, which might be critical for security"); + error = ESP_FAIL; + } + } + if (!correct_written_data) { + ESP_LOGE(TAG, "Written data are incorrect"); + error = ESP_FAIL; + } } } #endif // CONFIG_EFUSE_VIRTUAL esp_efuse_utility_reset(); + return error; } // After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values. diff --git a/components/efuse/src/esp_efuse_api.c b/components/efuse/src/esp_efuse_api.c index ce01213dede1..db62019f9cfa 100644 --- a/components/efuse/src/esp_efuse_api.c +++ b/components/efuse/src/esp_efuse_api.c @@ -90,7 +90,7 @@ esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t* field[], const void if (err == ESP_OK) { err = esp_efuse_utility_apply_new_coding_scheme(); if (err == ESP_OK) { - esp_efuse_utility_burn_efuses(); + err = esp_efuse_utility_burn_efuses(); } } esp_efuse_utility_reset(); @@ -125,7 +125,7 @@ esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt) if (err == ESP_OK) { err = esp_efuse_utility_apply_new_coding_scheme(); if (err == ESP_OK) { - esp_efuse_utility_burn_efuses(); + err = esp_efuse_utility_burn_efuses(); } } esp_efuse_utility_reset(); @@ -189,7 +189,7 @@ esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint3 if (err == ESP_OK) { err = esp_efuse_utility_apply_new_coding_scheme(); if (err == ESP_OK) { - esp_efuse_utility_burn_efuses(); + err = esp_efuse_utility_burn_efuses(); } } esp_efuse_utility_reset(); @@ -272,7 +272,7 @@ esp_err_t esp_efuse_batch_write_commit(void) if (--s_batch_writing_mode == 0) { esp_err_t err = esp_efuse_utility_apply_new_coding_scheme(); if (err == ESP_OK) { - esp_efuse_utility_burn_efuses(); + err = esp_efuse_utility_burn_efuses(); ESP_LOGI(TAG, "Batch mode. Prepared fields are committed"); } else { esp_efuse_utility_reset(); @@ -283,6 +283,10 @@ esp_err_t esp_efuse_batch_write_commit(void) return ESP_OK; } +esp_err_t esp_efuse_check_errors(void) +{ + return esp_efuse_utility_check_errors(); +} #ifndef CONFIG_IDF_TARGET_ESP32 diff --git a/components/efuse/src/esp_efuse_fields.c b/components/efuse/src/esp_efuse_fields.c index ef57c6a084ab..85a5da05c38c 100644 --- a/components/efuse/src/esp_efuse_fields.c +++ b/components/efuse/src/esp_efuse_fields.c @@ -20,6 +20,7 @@ #include "esp_types.h" #include "assert.h" #include "esp_err.h" +#include "esp_fault.h" #include "esp_log.h" #include "soc/efuse_periph.h" #include "bootloader_random.h" @@ -123,7 +124,16 @@ static void write_anti_rollback(uint32_t new_bits) bool esp_efuse_check_secure_version(uint32_t secure_version) { uint32_t sec_ver_hw = esp_efuse_read_secure_version(); - return secure_version >= sec_ver_hw; + /* Additional copies for Anti FI check */ + uint32_t sec_ver_hw_c1 = esp_efuse_read_secure_version(); + uint32_t sec_ver_hw_c2 = esp_efuse_read_secure_version(); + ESP_FAULT_ASSERT(sec_ver_hw == sec_ver_hw_c1); + ESP_FAULT_ASSERT(sec_ver_hw == sec_ver_hw_c2); + + bool ret_status = (secure_version >= sec_ver_hw); + /* Anti FI check */ + ESP_FAULT_ASSERT(ret_status == (secure_version >= sec_ver_hw)); + return ret_status; } esp_err_t esp_efuse_update_secure_version(uint32_t secure_version) diff --git a/components/efuse/src/esp_efuse_utility.c b/components/efuse/src/esp_efuse_utility.c index be590a61f10c..cada3fa1434b 100644 --- a/components/efuse/src/esp_efuse_utility.c +++ b/components/efuse/src/esp_efuse_utility.c @@ -354,3 +354,29 @@ static bool check_range_of_bits(esp_efuse_block_t blk, int offset_in_bits, int s } return true; } + +bool esp_efuse_utility_is_correct_written_data(esp_efuse_block_t block, unsigned r_data_len) +{ + uint32_t* w_data = (uint32_t*)range_write_addr_blocks[block].start; + uint32_t* r_data = (uint32_t*)range_read_addr_blocks[block].start; + + bool correct_written_data = memcmp(w_data, r_data, r_data_len) == 0; + if (correct_written_data) { + ESP_LOGI(TAG, "BURN BLOCK%d - OK (write block == read block)", block); + return true; + } + + correct_written_data = true; + for (unsigned i = 0; i < r_data_len / 4; i++) { + if ((*(r_data + i) & *(w_data + i)) != *(w_data + i)) { + correct_written_data = false; + break; + } + } + if (correct_written_data) { + ESP_LOGI(TAG, "BURN BLOCK%d - OK (all write block bits are set)", block); + } else { + ESP_LOGE(TAG, "BURN BLOCK%d - ERROR (written bits != read bits)", block); + } + return correct_written_data; +} diff --git a/components/efuse/test/test_efuse_coding_scheme.c b/components/efuse/test/test_efuse_coding_scheme.c index f85cbe511d24..201ef4828318 100644 --- a/components/efuse/test/test_efuse_coding_scheme.c +++ b/components/efuse/test/test_efuse_coding_scheme.c @@ -169,7 +169,7 @@ TEST_CASE("Test Coding Scheme for efuse manager", "[efuse]") } printf("\n"); #endif - TEST_ASSERT_EQUAL_HEX32_ARRAY(encoded, w_data_after_coding, 8); + TEST_ASSERT_EQUAL_HEX32_ARRAY(buf, w_data_after_coding, 8); } esp_efuse_utility_reset(); bootloader_random_disable(); @@ -193,7 +193,7 @@ TEST_CASE("Test data does not match the coding scheme", "[efuse]") esp_efuse_utility_reset(); for (int i = 0; i < count_useful_reg; ++i) { - REG_WRITE(EFUSE_BLK2_WDATA0_REG + i * 4, 0xABCDEF01 + i); + TEST_ESP_OK(esp_efuse_utility_write_reg(2, i, 0xABCDEF01 + i)); } if (coding_scheme == EFUSE_CODING_SCHEME_NONE) { diff --git a/components/efuse/test_efuse_host/efuse_tests.py b/components/efuse/test_efuse_host/efuse_tests.py index ec5a17acac6a..12470bc2e7c3 100755 --- a/components/efuse/test_efuse_host/efuse_tests.py +++ b/components/efuse/test_efuse_host/efuse_tests.py @@ -337,6 +337,73 @@ def test_common_and_custom_table_use_the_same_bits(self): with self.assertRaisesRegex(efuse_table_gen.InputError, 'overlaps'): two_tables.verify() + def test_two_fields_with_lists(self): + csv = """ +MAC_FACTORY, EFUSE_BLK1, 40, 8, Factory MAC addr [0] +, EFUSE_BLK1, 32, 8, Factory MAC addr [1] +, EFUSE_BLK1, 24, 8, Factory MAC addr [2] +, EFUSE_BLK1, 16, 8, Factory MAC addr [3] +, EFUSE_BLK1, 8, 8, Factory MAC addr [4] +, EFUSE_BLK1, 0, 8, Factory MAC addr [5] +MAC_EXT, EFUSE_BLK1, 123, 8, Extend MAC addr [0] +, EFUSE_BLK1, 131, 8, Extend MAC addr [1] + """ + t = efuse_table_gen.FuseTable.from_csv(csv) + t.verify() + + self.assertEqual(t[0].field_name, 'MAC_FACTORY') + self.assertEqual(t[0].group, str(0)) + self.assertEqual(t[1].field_name, 'MAC_FACTORY') + self.assertEqual(t[1].group, str(1)) + self.assertEqual(t[2].field_name, 'MAC_FACTORY') + self.assertEqual(t[2].group, str(2)) + self.assertEqual(t[3].field_name, 'MAC_FACTORY') + self.assertEqual(t[3].group, str(3)) + self.assertEqual(t[4].field_name, 'MAC_FACTORY') + self.assertEqual(t[4].group, str(4)) + self.assertEqual(t[5].field_name, 'MAC_FACTORY') + self.assertEqual(t[5].group, str(5)) + + self.assertEqual(t[6].field_name, 'MAC_EXT') + self.assertEqual(t[6].group, str(0)) + self.assertEqual(t[7].field_name, 'MAC_EXT') + self.assertEqual(t[7].group, str(1)) + + def test_two_fields_with_lists_and_field_between(self): + csv = """ +MAC_FACTORY, EFUSE_BLK1, 40, 8, Factory MAC addr [0] +, EFUSE_BLK1, 32, 8, Factory MAC addr [1] +, EFUSE_BLK1, 24, 8, Factory MAC addr [2] +, EFUSE_BLK1, 16, 8, Factory MAC addr [3] +, EFUSE_BLK1, 8, 8, Factory MAC addr [4] +, EFUSE_BLK1, 0, 8, Factory MAC addr [5] +name2, EFUSE_BLK3, 5, 1, comment +MAC_EXT, EFUSE_BLK1, 123, 8, Extend MAC addr [0] +, EFUSE_BLK1, 131, 8, Extend MAC addr [1] + """ + t = efuse_table_gen.FuseTable.from_csv(csv) + t.verify() + + self.assertEqual(t[0].field_name, 'MAC_FACTORY') + self.assertEqual(t[0].group, str(0)) + self.assertEqual(t[1].field_name, 'MAC_FACTORY') + self.assertEqual(t[1].group, str(1)) + self.assertEqual(t[2].field_name, 'MAC_FACTORY') + self.assertEqual(t[2].group, str(2)) + self.assertEqual(t[3].field_name, 'MAC_FACTORY') + self.assertEqual(t[3].group, str(3)) + self.assertEqual(t[4].field_name, 'MAC_FACTORY') + self.assertEqual(t[4].group, str(4)) + self.assertEqual(t[5].field_name, 'MAC_FACTORY') + self.assertEqual(t[5].group, str(5)) + + self.assertEqual(t[6].field_name, 'name2') + + self.assertEqual(t[7].field_name, 'MAC_EXT') + self.assertEqual(t[7].group, str(0)) + self.assertEqual(t[8].field_name, 'MAC_EXT') + self.assertEqual(t[8].group, str(1)) + if __name__ == '__main__': unittest.main() diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 0f1fcb114925..e59c2361f945 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -31,10 +31,6 @@ #endif #ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT - -#define ATECC608A_TNG_SLAVE_ADDR 0x6A -#define ATECC608A_TFLEX_SLAVE_ADDR 0x6C -#define ATECC608A_TCUSTOM_SLAVE_ADDR 0xC0 /* cryptoauthlib includes */ #include "mbedtls/atca_mbedtls_wrap.h" #include "tng_atca.h" @@ -689,12 +685,12 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, esp_tls_cfg_t *cf (void)cert_def; #if defined(CONFIG_ATECC608A_TNG) || defined(CONFIG_ATECC608A_TFLEX) #ifdef CONFIG_ATECC608A_TNG - esp_ret = esp_init_atecc608a(ATECC608A_TNG_SLAVE_ADDR); + esp_ret = esp_init_atecc608a(CONFIG_ATCA_I2C_ADDRESS); if (ret != ESP_OK) { return ESP_ERR_ESP_TLS_SE_FAILED; } #elif CONFIG_ATECC608A_TFLEX /* CONFIG_ATECC608A_TNG */ - esp_ret = esp_init_atecc608a(ATECC608A_TFLEX_SLAVE_ADDR); + esp_ret = esp_init_atecc608a(CONFIG_ATCA_I2C_ADDRESS); if (ret != ESP_OK) { return ESP_ERR_ESP_TLS_SE_FAILED; } @@ -713,7 +709,7 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, esp_tls_cfg_t *cf return ESP_ERR_ESP_TLS_SE_FAILED; } #elif CONFIG_ATECC608A_TCUSTOM - esp_ret = esp_init_atecc608a(ATECC608A_TCUSTOM_SLAVE_ADDR); + esp_ret = esp_init_atecc608a(CONFIG_ATCA_I2C_ADDRESS); if (ret != ESP_OK) { return ESP_ERR_ESP_TLS_SE_FAILED; } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index e98b5321f5fc..d7a400feb7b0 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -766,7 +766,7 @@ menu "ESP32-specific" depends on ESP32_USE_FIXED_STATIC_RAM_SIZE help RAM size dedicated for static variables (.data & .bss sections). - Please note that the actual length will be reduced by BT_RESERVE_DRAM if Bluetooth + Please note that the actual length will be reduced by BTDM_RESERVE_DRAM if Bluetooth controller is enabled. config ESP32_DPORT_DIS_INTERRUPT_LVL diff --git a/components/esp32/ld/esp32.ld b/components/esp32/ld/esp32.ld index 2d0e3996474f..a4faade9eb37 100644 --- a/components/esp32/ld/esp32.ld +++ b/components/esp32/ld/esp32.ld @@ -17,8 +17,8 @@ #include "sdkconfig.h" /* If BT is not built at all */ -#ifndef CONFIG_BT_RESERVE_DRAM -#define CONFIG_BT_RESERVE_DRAM 0 +#ifndef CONFIG_BTDM_RESERVE_DRAM +#define CONFIG_BTDM_RESERVE_DRAM 0 #endif #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC @@ -73,8 +73,8 @@ MEMORY in heap at runtime. However due to static ROM memory usage at this 176KB mark, the additional static memory temporarily cannot be used. */ - dram0_0_seg (RW) : org = 0x3FFB0000 + CONFIG_BT_RESERVE_DRAM, - len = DRAM0_0_SEG_LEN - CONFIG_BT_RESERVE_DRAM + dram0_0_seg (RW) : org = 0x3FFB0000 + CONFIG_BTDM_RESERVE_DRAM, + len = DRAM0_0_SEG_LEN - CONFIG_BTDM_RESERVE_DRAM #ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* Flash mapped constant data */ diff --git a/components/esp32/project_include.cmake b/components/esp32/project_include.cmake index 91c0f8af463a..472d8c7ebd8a 100644 --- a/components/esp32/project_include.cmake +++ b/components/esp32/project_include.cmake @@ -1,4 +1,4 @@ -if(CONFIG_SPIRAM_CACHE_WORKAROUND) +if(CONFIG_SPIRAM_CACHE_WORKAROUND AND NOT BOOTLOADER_BUILD) # We do this here as well as in CMakeLists.txt, because targets that # are not part of the ESP-IDF build system (for cases where a generic # non-IDF CMakeLists.txt file is imported into a component) don't depend diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index 8a289c174bd0..36de52a03519 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -119,6 +119,11 @@ typedef enum { #define D2WD_PSRAM_CLK_IO CONFIG_D2WD_PSRAM_CLK_IO // Default value is 9 #define D2WD_PSRAM_CS_IO CONFIG_D2WD_PSRAM_CS_IO // Default value is 10 +// There is no reason to change the pin of an embedded psram. +// So define the number of pin directly, instead of configurable. +#define D0WDR2_V3_PSRAM_CLK_IO 6 +#define D0WDR2_V3_PSRAM_CS_IO 16 + // For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6. #define PICO_PSRAM_CLK_IO 6 #define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10 @@ -847,6 +852,16 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad ESP_EARLY_LOGI(TAG, "This chip is ESP32-D0WD"); psram_io.psram_clk_io = D0WD_PSRAM_CLK_IO; psram_io.psram_cs_io = D0WD_PSRAM_CS_IO; + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDR2V3) { + ESP_EARLY_LOGI(TAG, "This chip is ESP32-D0WDR2-V3"); + rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); + if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) { + ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V"); + return ESP_FAIL; + } + s_clk_mode = PSRAM_CLK_MODE_NORM; + psram_io.psram_clk_io = D0WDR2_V3_PSRAM_CLK_IO; + psram_io.psram_cs_io = D0WDR2_V3_PSRAM_CS_IO; } else { ESP_EARLY_LOGE(TAG, "Not a valid or known package id: %d", pkg_ver); abort(); diff --git a/components/esp32/system_api_esp32.c b/components/esp32/system_api_esp32.c index 2ed2e9b7a12a..759d29e73e48 100644 --- a/components/esp32/system_api_esp32.c +++ b/components/esp32/system_api_esp32.c @@ -52,7 +52,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM); wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); // Reset and stall the other CPU. // CPU must be reset before stalling, in case it was running a s32c1i diff --git a/components/esp32c3/Kconfig b/components/esp32c3/Kconfig index 296427721a7b..72e7bfa5c965 100644 --- a/components/esp32c3/Kconfig +++ b/components/esp32c3/Kconfig @@ -39,6 +39,8 @@ menu "ESP32C3-Specific" bool "Rev 2" config ESP32C3_REV_MIN_3 bool "Rev 3" + config ESP32C3_REV_MIN_4 + bool "Rev 4" endchoice config ESP32C3_REV_MIN @@ -47,6 +49,7 @@ menu "ESP32C3-Specific" default 1 if ESP32C3_REV_MIN_1 default 2 if ESP32C3_REV_MIN_2 default 3 if ESP32C3_REV_MIN_3 + default 4 if ESP32C3_REV_MIN_4 choice ESP32C3_UNIVERSAL_MAC_ADDRESSES bool "Number of universally administered (by IEEE) MAC address" diff --git a/components/esp32c3/ld/esp32c3.project.ld.in b/components/esp32c3/ld/esp32c3.project.ld.in index 21d5845b365d..b36c4cbcb27a 100644 --- a/components/esp32c3/ld/esp32c3.project.ld.in +++ b/components/esp32c3/ld/esp32c3.project.ld.in @@ -10,25 +10,19 @@ SECTIONS .rtc.text : { . = ALIGN(4); + _rtc_fast_start = ABSOLUTE(.); mapping[rtc_text] *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + + /* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */ + . += 16; + . = ALIGN(4); + _rtc_text_end = ABSOLUTE(.); } > rtc_iram_seg - /** - * This section is required to skip rtc.text area because rtc_iram_seg and - * rtc_data_seg are reflect the same address space on different buses. - */ - .rtc.dummy : - { - _rtc_dummy_start = ABSOLUTE(.); - _rtc_fast_start = ABSOLUTE(.); - . = SIZEOF(.rtc.text); - _rtc_dummy_end = ABSOLUTE(.); - } > rtc_data_seg - /** * This section located in RTC FAST Memory area. * It holds data marked with RTC_FAST_ATTR attribute. @@ -392,11 +386,11 @@ SECTIONS /* Marks the end of IRAM code segment */ .iram0.text_end (NOLOAD) : { + /* iram_end_test section exists for use by memprot unit tests only */ + *(.iram_end_test) /* C3 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */ . += 16; . = ALIGN (0x200); - /* iram_end_test section exists for use by memprot unit tests only */ - *(.iram_end_test) _iram_text_end = ABSOLUTE(.); } > iram0_0_seg diff --git a/components/esp_adc_cal/CMakeLists.txt b/components/esp_adc_cal/CMakeLists.txt index 61d15d185f66..2d1f824147e1 100644 --- a/components/esp_adc_cal/CMakeLists.txt +++ b/components/esp_adc_cal/CMakeLists.txt @@ -1,17 +1,12 @@ idf_build_get_property(target IDF_TARGET) -if(${target} STREQUAL "esp32") - idf_component_register(SRCS "esp_adc_cal_esp32.c" - INCLUDE_DIRS "include" - REQUIRES driver efuse) - -elseif(${target} STREQUAL "esp32s2") - idf_component_register(SRCS "esp_adc_cal_esp32s2.c" - INCLUDE_DIRS "include" - REQUIRES driver efuse) - -elseif(${target} STREQUAL "esp32c3") - idf_component_register(SRCS "esp_adc_cal_esp32c3.c" - INCLUDE_DIRS "include" - REQUIRES driver efuse) +set(srcs "esp_adc_cal_common.c") +set(src_target "${target}/esp_adc_cal.c") +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${src_target}") + list(APPEND srcs ${src_target}) endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS include + REQUIRES driver + PRIV_REQUIRES efuse) diff --git a/components/esp_adc_cal/component.mk b/components/esp_adc_cal/component.mk index b12080ce87d0..99bda1cb2600 100644 --- a/components/esp_adc_cal/component.mk +++ b/components/esp_adc_cal/component.mk @@ -2,5 +2,5 @@ # Component Makefile # +COMPONENT_SRCDIRS := . $(IDF_TARGET) COMPONENT_ADD_INCLUDEDIRS := include -COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o esp_adc_cal_esp32c3.o diff --git a/components/esp_adc_cal/esp_adc_cal_esp32.c b/components/esp_adc_cal/esp32/esp_adc_cal.c similarity index 88% rename from components/esp_adc_cal/esp_adc_cal_esp32.c rename to components/esp_adc_cal/esp32/esp_adc_cal.c index 43b08c14612d..8f0dde798051 100644 --- a/components/esp_adc_cal/esp_adc_cal_esp32.c +++ b/components/esp_adc_cal/esp32/esp_adc_cal.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "esp_types.h" @@ -82,12 +74,6 @@ #define LUT_HIGH_THRESH (LUT_LOW_THRESH + LUT_ADC_STEP_SIZE) #define ADC_12_BIT_RES 4096 -#define ADC_CAL_CHECK(cond, ret) ({ \ - if(!(cond)){ \ - return ret; \ - } \ -}) - /* ------------------------ Characterization Constants ---------------------- */ static const uint32_t adc1_tp_atten_scale[4] = {65504, 86975, 120389, 224310}; static const uint32_t adc2_tp_atten_scale[4] = {65467, 86861, 120416, 224708}; @@ -366,27 +352,3 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_char return calculate_voltage_linear(adc_reading, chars->coeff_a, chars->coeff_b); } } - -esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, - const esp_adc_cal_characteristics_t *chars, - uint32_t *voltage) -{ - //Check parameters - ADC_CAL_CHECK(chars != NULL, ESP_ERR_INVALID_ARG); - ADC_CAL_CHECK(voltage != NULL, ESP_ERR_INVALID_ARG); - - int adc_reading; - if (chars->adc_num == ADC_UNIT_1) { - //Check channel is valid on ADC1 - ADC_CAL_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, ESP_ERR_INVALID_ARG); - adc_reading = adc1_get_raw(channel); - } else { - //Check channel is valid on ADC2 - ADC_CAL_CHECK((adc2_channel_t)channel < ADC2_CHANNEL_MAX, ESP_ERR_INVALID_ARG); - if (adc2_get_raw(channel, chars->bit_width, &adc_reading) != ESP_OK) { - return ESP_ERR_TIMEOUT; //Timed out waiting for ADC2 - } - } - *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); - return ESP_OK; -} diff --git a/components/esp_adc_cal/esp_adc_cal_esp32c3.c b/components/esp_adc_cal/esp32c3/esp_adc_cal.c similarity index 58% rename from components/esp_adc_cal/esp_adc_cal_esp32c3.c rename to components/esp_adc_cal/esp32c3/esp_adc_cal.c index f7e4495e034d..8f3debb3f0dc 100644 --- a/components/esp_adc_cal/esp_adc_cal_esp32c3.c +++ b/components/esp_adc_cal/esp32c3/esp_adc_cal.c @@ -1,16 +1,8 @@ -// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -22,6 +14,7 @@ #include "hal/adc_ll.h" #include "esp32c3/esp_efuse_rtc_calib.h" #include "esp_adc_cal.h" +#include "../esp_adc_cal_internal.h" #define ADC_CALIB_CHECK(cond, err_msg, ret) do {\ @@ -36,10 +29,40 @@ const static char LOG_TAG[] = "adc_calib"; /* ------------------------ Characterization Constants ---------------------- */ -// coeff_a and coeff_b are actually floats -// they are scaled to put them into uint32_t so that the headers do not have to be changed +// coeff_a is actually a float number +// it is scaled to put them into uint32_t so that the headers do not have to be changed static const int coeff_a_scaling = 65536; -static const int coeff_b_scaling = 1024; + +/** + * @note Error Calculation + * Coefficients for calculating the reading voltage error. + * Four sets of coefficients for atten0 ~ atten3 respectively. + * + * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. + * + * @note {0,0} stands for unused item + * @note In case of the overflow, these coeffcients are recorded as Absolute Value + * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); + * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. + * @note ADC1 and ADC2 use same coeffients + */ +const static uint64_t adc_error_coef_atten[4][5][2] = { + {{225966470500043, 1e15}, {7265418501948, 1e16}, {109410402681, 1e16}, {0, 0}, {0, 0}}, //atten0 + {{4229623392600516, 1e16}, {731527490903, 1e16}, {88166562521, 1e16}, {0, 0}, {0, 0}}, //atten1 + {{1017859239236435, 1e15}, {97159265299153, 1e16}, {149794028038, 1e16}, {0, 0}, {0, 0}}, //atten2 + {{14912262772850453, 1e16}, {228549975564099, 1e16}, {356391935717, 1e16}, {179964582, 1e16}, {42046, 1e16}} //atten3 + }; +/** + * Term sign + * @note ADC1 and ADC2 use same coeffients + */ +const static int32_t adc_error_sign[4][5] = { + {-1, -1, 1, 0, 0}, //atten0 + { 1, -1, 1, 0, 0}, //atten1 + {-1, -1, 1, 0, 0}, //atten2 + {-1, -1, 1, -1, 1} //atten3 + }; + /* -------------------- Characterization Helper Data Types ------------------ */ typedef struct { uint32_t voltage; @@ -53,9 +76,9 @@ typedef struct { union { adc_calib_data_ver1 ver1; } efuse_data; -} adc_calib_parsed_info; +} adc_calib_parsed_info_t; -static esp_err_t prepare_calib_data_for(int version_num, adc_unit_t adc_num, adc_atten_t atten, adc_calib_parsed_info *parsed_data_storage) +static esp_err_t prepare_calib_data_for(int version_num, adc_unit_t adc_num, adc_atten_t atten, adc_calib_parsed_info_t *parsed_data_storage) { assert(version_num == 1); esp_err_t ret; @@ -79,7 +102,7 @@ static esp_err_t prepare_calib_data_for(int version_num, adc_unit_t adc_num, adc * Estimate the (assumed) linear relationship btwn the measured raw value and the voltage * with the previously done measurement when the chip was manufactured. */ -static void calculate_characterization_coefficients(const adc_calib_parsed_info *parsed_data, esp_adc_cal_characteristics_t *chars) +static void calculate_characterization_coefficients(const adc_calib_parsed_info_t *parsed_data, esp_adc_cal_characteristics_t *chars) { ESP_LOGD(LOG_TAG, "Calib V1, Cal Voltage = %d, Digi out = %d\n", parsed_data->efuse_data.ver1.voltage, parsed_data->efuse_data.ver1.digi); @@ -108,7 +131,7 @@ esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, esp_adc_cal_characteristics_t *chars) { esp_err_t ret; - adc_calib_parsed_info efuse_parsed_data = {0}; + adc_calib_parsed_info_t efuse_parsed_data = {0}; // Check parameters ADC_CALIB_CHECK(adc_num == ADC_UNIT_1 || adc_num == ADC_UNIT_2, "Invalid unit num", ESP_ADC_CAL_VAL_NOT_SUPPORTED); ADC_CALIB_CHECK(chars != NULL, "Invalid characteristic", ESP_ADC_CAL_VAL_NOT_SUPPORTED); @@ -140,31 +163,17 @@ esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) { - ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG); - - return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; -} - -esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, - const esp_adc_cal_characteristics_t *chars, - uint32_t *voltage) -{ - // Check parameters - ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG); - ADC_CALIB_CHECK(voltage != NULL, "No output buffer.", ESP_ERR_INVALID_ARG); - - int adc_reading; - if (chars->adc_num == ADC_UNIT_1) { - //Check if channel is valid on ADC1 - ADC_CALIB_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, "Invalid channel", ESP_ERR_INVALID_ARG); - adc_reading = adc1_get_raw(channel); - } else { - //Check if channel is valid on ADC2 - ADC_CALIB_CHECK((adc2_channel_t)channel < ADC2_CHANNEL_MAX, "Invalid channel", ESP_ERR_INVALID_ARG); - if (adc2_get_raw(channel, chars->bit_width, &adc_reading) != ESP_OK) { - return ESP_ERR_TIMEOUT; //Timed out waiting for ADC2 - } - } - *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); - return ESP_OK; + assert(chars != NULL); + + int32_t error = 0; + uint64_t v_cali_1 = adc_reading * chars->coeff_a / coeff_a_scaling; + esp_adc_error_calc_param_t param = { + .v_cali_input = v_cali_1, + .term_num = (chars->atten == 3) ? 5 : 3, + .coeff = &adc_error_coef_atten, + .sign = &adc_error_sign, + }; + error = esp_adc_cal_get_reading_error(¶m, chars->atten); + + return (int32_t)v_cali_1 - error; } diff --git a/components/esp_adc_cal/esp_adc_cal_esp32s2.c b/components/esp_adc_cal/esp32s2/esp_adc_cal.c similarity index 83% rename from components/esp_adc_cal/esp_adc_cal_esp32s2.c rename to components/esp_adc_cal/esp32s2/esp_adc_cal.c index 4230eea66c92..cf22474cbc00 100644 --- a/components/esp_adc_cal/esp_adc_cal_esp32s2.c +++ b/components/esp_adc_cal/esp32s2/esp_adc_cal.c @@ -1,16 +1,8 @@ -// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "esp_types.h" @@ -211,27 +203,3 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_char return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; } - -esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, - const esp_adc_cal_characteristics_t *chars, - uint32_t *voltage) -{ - // Check parameters - ADC_CAL_CHECK(chars != NULL, ESP_ERR_INVALID_ARG); - ADC_CAL_CHECK(voltage != NULL, ESP_ERR_INVALID_ARG); - - int adc_reading; - if (chars->adc_num == ADC_UNIT_1) { - //Check if channel is valid on ADC1 - ADC_CAL_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, ESP_ERR_INVALID_ARG); - adc_reading = adc1_get_raw(channel); - } else { - //Check if channel is valid on ADC2 - ADC_CAL_CHECK((adc2_channel_t)channel < ADC2_CHANNEL_MAX, ESP_ERR_INVALID_ARG); - if (adc2_get_raw(channel, chars->bit_width, &adc_reading) != ESP_OK) { - return ESP_ERR_TIMEOUT; //Timed out waiting for ADC2 - } - } - *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); - return ESP_OK; -} diff --git a/components/esp_adc_cal/esp_adc_cal_common.c b/components/esp_adc_cal/esp_adc_cal_common.c new file mode 100644 index 000000000000..af99efe93ff8 --- /dev/null +++ b/components/esp_adc_cal/esp_adc_cal_common.c @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_types.h" +#include "esp_err.h" +#include "esp_log.h" +#include "driver/adc.h" +#include "hal/adc_types.h" +#include "esp_adc_cal.h" +#include "esp_adc_cal_internal.h" + +#define ADC_CAL_CHECK(cond, ret) ({ \ + if(!(cond)){ \ + return ret; \ + } \ +}) + +const __attribute__((unused)) static char *TAG = "ADC_CALI"; + +esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, + const esp_adc_cal_characteristics_t *chars, + uint32_t *voltage) +{ + // Check parameters + ADC_CAL_CHECK(chars != NULL, ESP_ERR_INVALID_ARG); + ADC_CAL_CHECK(voltage != NULL, ESP_ERR_INVALID_ARG); + + esp_err_t ret = ESP_OK; + int adc_reading; + if (chars->adc_num == ADC_UNIT_1) { + ADC_CAL_CHECK(channel < SOC_ADC_CHANNEL_NUM(0), ESP_ERR_INVALID_ARG); + adc_reading = adc1_get_raw(channel); + } else { + ADC_CAL_CHECK(channel < SOC_ADC_CHANNEL_NUM(1), ESP_ERR_INVALID_ARG); + ret = adc2_get_raw(channel, chars->bit_width, &adc_reading); + } + + if (ret == ESP_OK) { + *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); + } + return ret; +} + +#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED +/*------------------------------------------------------------------------------ + * Private API + *----------------------------------------------------------------------------*/ +int32_t esp_adc_cal_get_reading_error(const esp_adc_error_calc_param_t *param, uint8_t atten) +{ + if (param->v_cali_input == 0) { + return 0; + } + + uint64_t v_cali_1 = param->v_cali_input; + uint8_t term_num = param->term_num; + int32_t error = 0; + uint64_t coeff = 0; + uint64_t variable[term_num]; + uint64_t term[term_num]; + memset(variable, 0, term_num * sizeof(uint64_t)); + memset(term, 0, term_num * sizeof(uint64_t)); + + /** + * For atten0 ~ 2: + * error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); + * + * For atten3: + * error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); + */ + variable[0] = 1; + coeff = (*param->coeff)[atten][0][0]; + term[0] = variable[0] * coeff / (*param->coeff)[atten][0][1]; + error = (int32_t)term[0] * (*param->sign)[atten][0]; + + for (int i = 1; i < term_num; i++) { + variable[i] = variable[i-1] * v_cali_1; + coeff = (*param->coeff)[atten][i][0]; + term[i] = variable[i] * coeff; + ESP_LOGV(TAG, "big coef is %llu, big term%d is %llu, coef_id is %d", coeff, i, term[i], i); + + term[i] = term[i] / (*param->coeff)[atten][i][1]; + error += (int32_t)term[i] * (*param->sign)[atten][i]; + ESP_LOGV(TAG, "term%d is %llu, error is %d", i, term[i], error); + } + + return error; +} +#endif //#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED diff --git a/components/esp_adc_cal/esp_adc_cal_internal.h b/components/esp_adc_cal/esp_adc_cal_internal.h new file mode 100644 index 000000000000..518c397f5b40 --- /dev/null +++ b/components/esp_adc_cal/esp_adc_cal_internal.h @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#define ESP_ADC_CAL_CURVE_FITTING_SUPPORTED 1 + +#define COEFF_GROUP_NUM 4 +#define TERM_MAX 5 +#endif + +#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED +/** + * Calculation parameters used for curve fitting calibration algorithm error + * + * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); + * Where X is the `v_cali_input`. + */ +typedef struct { + uint64_t v_cali_input; //Input to calculate the error + uint8_t term_num; //Term number of the algorithm formula + const uint64_t (*coeff)[COEFF_GROUP_NUM][TERM_MAX][2]; //Coeff of each term. See `adc_error_coef_atten` for details (and the magic number 2) + const int32_t (*sign)[COEFF_GROUP_NUM][TERM_MAX]; //Sign of each term +} esp_adc_error_calc_param_t; + +/** + * Calculate the curve fitting error + * + * @param param see `esp_adc_error_calc_param_t` + * @param atten ADC attenuation + */ +int32_t esp_adc_cal_get_reading_error(const esp_adc_error_calc_param_t *param, uint8_t atten); + +#endif //#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_adc_cal/include/esp_adc_cal.h b/components/esp_adc_cal/include/esp_adc_cal.h index 9adf28078de6..a50c2edebaaa 100644 --- a/components/esp_adc_cal/include/esp_adc_cal.h +++ b/components/esp_adc_cal/include/esp_adc_cal.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_ADC_CAL_H__ #define __ESP_ADC_CAL_H__ diff --git a/components/esp_common/Kconfig b/components/esp_common/Kconfig index 39fa9ae6b67a..2192710887df 100644 --- a/components/esp_common/Kconfig +++ b/components/esp_common/Kconfig @@ -95,8 +95,30 @@ menu "Common ESP-related" bool "None" endchoice - # Internal option, indicates that console UART is used (and not USB, for example) + choice ESP_CONSOLE_SECONDARY + depends on IDF_TARGET_ESP32C3 + prompt "Channel for console secondary output" + default ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + help + This secondary option supports output through other specific port like USB_SERIAL_JTAG + when UART0 port as a primary is selected but not connected. This secondary output currently only supports + non-blocking mode without using REPL. If you want to output in blocking mode with REPL or + input through this secondary port, please change the primary config to this port + in `Channel for console output` menu. + config ESP_CONSOLE_SECONDARY_NONE + bool "No secondary console" + config ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + bool "USB_SERIAL_JTAG PORT" + depends on !ESP_CONSOLE_USB_SERIAL_JTAG + help + This option supports output through USB_SERIAL_JTAG port when the UART0 port is not connected. + The output currently only supports non-blocking mode without using the console. + If you want to output in blocking mode with REPL or input through USB_SERIAL_JTAG port, + please change the primary config to ESP_CONSOLE_USB_SERIAL_JTAG above. + endchoice + config ESP_CONSOLE_UART + # Internal option, indicates that console UART is used (and not USB, for example) bool default y if ESP_CONSOLE_UART_DEFAULT || ESP_CONSOLE_UART_CUSTOM diff --git a/components/esp_common/include/esp_idf_version.h b/components/esp_common/include/esp_idf_version.h index e4b0a9ee85c5..3ee058039e04 100644 --- a/components/esp_common/include/esp_idf_version.h +++ b/components/esp_common/include/esp_idf_version.h @@ -23,7 +23,7 @@ extern "C" { /** Minor version number (x.X.x) */ #define ESP_IDF_VERSION_MINOR 3 /** Patch version number (x.x.X) */ -#define ESP_IDF_VERSION_PATCH 2 +#define ESP_IDF_VERSION_PATCH 3 /** * Macro to convert IDF version number into an integer diff --git a/components/esp_common/src/task_wdt.c b/components/esp_common/src/task_wdt.c index 5c73e20774ef..6cbf8ab72f20 100644 --- a/components/esp_common/src/task_wdt.c +++ b/components/esp_common/src/task_wdt.c @@ -224,9 +224,9 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic) wdt_hal_init(&twdt_context, TWDT_INSTANCE, TWDT_PRESCALER, true); wdt_hal_write_protect_disable(&twdt_context); //Configure 1st stage timeout and behavior - wdt_hal_config_stage(&twdt_context, WDT_STAGE0, twdt_config->timeout * 1000000 / TWDT_TICKS_PER_US, WDT_STAGE_ACTION_INT); + wdt_hal_config_stage(&twdt_context, WDT_STAGE0, twdt_config->timeout * (1000000 / TWDT_TICKS_PER_US), WDT_STAGE_ACTION_INT); //Configure 2nd stage timeout and behavior - wdt_hal_config_stage(&twdt_context, WDT_STAGE1, 2*twdt_config->timeout * 1000000 / TWDT_TICKS_PER_US, WDT_STAGE_ACTION_RESET_SYSTEM); + wdt_hal_config_stage(&twdt_context, WDT_STAGE1, twdt_config->timeout * (2 * 1000000 / TWDT_TICKS_PER_US), WDT_STAGE_ACTION_RESET_SYSTEM); //Enable the WDT wdt_hal_enable(&twdt_context); wdt_hal_write_protect_enable(&twdt_context); @@ -238,8 +238,8 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic) //Reconfigure hardware timer wdt_hal_write_protect_disable(&twdt_context); wdt_hal_disable(&twdt_context); - wdt_hal_config_stage(&twdt_context, WDT_STAGE0, twdt_config->timeout*1000*1000/TWDT_TICKS_PER_US, WDT_STAGE_ACTION_INT); - wdt_hal_config_stage(&twdt_context, WDT_STAGE1, 2*twdt_config->timeout*1000*1000/TWDT_TICKS_PER_US, WDT_STAGE_ACTION_RESET_SYSTEM); + wdt_hal_config_stage(&twdt_context, WDT_STAGE0, twdt_config->timeout * (1000 * 1000 / TWDT_TICKS_PER_US), WDT_STAGE_ACTION_INT); + wdt_hal_config_stage(&twdt_context, WDT_STAGE1, twdt_config->timeout * (2 * 1000 * 1000 / TWDT_TICKS_PER_US), WDT_STAGE_ACTION_RESET_SYSTEM); wdt_hal_enable(&twdt_context); wdt_hal_write_protect_enable(&twdt_context); } diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index 307f51b7b56f..48a25093dbfb 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -262,7 +262,6 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl) esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); esp_eth_phy_t *phy = eth_driver->phy; - esp_eth_mac_t *mac = eth_driver->mac; // check if driver has started esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_STOP; if (!atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_START)) { @@ -271,7 +270,6 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl) goto err; } ETH_CHECK(phy->negotiate(phy) == ESP_OK, "phy negotiation failed", err, ESP_FAIL); - ETH_CHECK(mac->start(mac) == ESP_OK, "start mac failed", err, ESP_FAIL); ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, ð_driver, sizeof(esp_eth_driver_t *), 0) == ESP_OK, "send ETHERNET_EVENT_START event failed", err, ESP_FAIL); ETH_CHECK(phy->get_link(phy) == ESP_OK, "phy get link status failed", err, ESP_FAIL); @@ -323,6 +321,13 @@ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length) { esp_err_t ret = ESP_OK; esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; + + if (atomic_load(ð_driver->fsm) != ESP_ETH_FSM_START) { + ret = ESP_ERR_INVALID_STATE; + ESP_LOGD(TAG, "Ethernet is not started"); + goto err; + } + ETH_CHECK(buf, "can't set buf to null", err, ESP_ERR_INVALID_ARG); ETH_CHECK(length, "buf length can't be zero", err, ESP_ERR_INVALID_ARG); ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); diff --git a/components/esp_eth/src/esp_eth_mac_dm9051.c b/components/esp_eth/src/esp_eth_mac_dm9051.c index 2f17ddf993b0..9ac8193464fa 100644 --- a/components/esp_eth/src/esp_eth_mac_dm9051.c +++ b/components/esp_eth/src/esp_eth_mac_dm9051.c @@ -1,16 +1,9 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #include #include #include @@ -19,6 +12,7 @@ #include "esp_attr.h" #include "esp_log.h" #include "esp_eth.h" +#include "esp_timer.h" #include "esp_system.h" #include "esp_intr_alloc.h" #include "esp_heap_caps.h" @@ -648,16 +642,24 @@ static esp_err_t emac_dm9051_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); /* Check if last transmit complete */ uint8_t tcr = 0; - MAC_CHECK(dm9051_register_read(emac, DM9051_TCR, &tcr) == ESP_OK, "read TCR failed", err, ESP_FAIL); - MAC_CHECK(!(tcr & TCR_TXREQ), "last transmit still in progress", err, ESP_ERR_INVALID_STATE); + + int64_t wait_time = esp_timer_get_time(); + do { + MAC_CHECK(dm9051_register_read(emac, DM9051_TCR, &tcr) == ESP_OK, "read TCR failed", err, ESP_FAIL); + } while((tcr & TCR_TXREQ) && ((esp_timer_get_time() - wait_time) < 100)); + + if (tcr & TCR_TXREQ) { + ESP_LOGE(TAG, "last transmit still in progress, cannot send."); + return ESP_ERR_INVALID_STATE; + } + /* set tx length */ MAC_CHECK(dm9051_register_write(emac, DM9051_TXPLL, length & 0xFF) == ESP_OK, "write TXPLL failed", err, ESP_FAIL); MAC_CHECK(dm9051_register_write(emac, DM9051_TXPLH, (length >> 8) & 0xFF) == ESP_OK, "write TXPLH failed", err, ESP_FAIL); /* copy data to tx memory */ MAC_CHECK(dm9051_memory_write(emac, buf, length) == ESP_OK, "write memory failed", err, ESP_FAIL); /* issue tx polling command */ - tcr |= TCR_TXREQ; - MAC_CHECK(dm9051_register_write(emac, DM9051_TCR, tcr) == ESP_OK, "write TCR failed", err, ESP_FAIL); + MAC_CHECK(dm9051_register_write(emac, DM9051_TCR, TCR_TXREQ) == ESP_OK, "write TCR failed", err, ESP_FAIL); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_mac_esp32.c b/components/esp_eth/src/esp_eth_mac_esp32.c index 9569a7fabe9f..e72d6897d212 100644 --- a/components/esp_eth/src/esp_eth_mac_esp32.c +++ b/components/esp_eth/src/esp_eth_mac_esp32.c @@ -47,7 +47,7 @@ static const char *TAG = "emac_esp32"; } while (0) #define PHY_OPERATION_TIMEOUT_US (1000) - +#define MAC_STOP_TIMEOUT_US (250) #define FLOW_CONTROL_LOW_WATER_MARK (CONFIG_ETH_DMA_RX_BUFFER_NUM / 3) #define FLOW_CONTROL_HIGH_WATER_MARK (FLOW_CONTROL_LOW_WATER_MARK * 2) @@ -77,6 +77,8 @@ typedef struct { static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl, void **out_descriptors); static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors); +static esp_err_t emac_esp32_start(esp_eth_mac_t *mac); +static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac); static esp_err_t emac_esp32_set_mediator(esp_eth_mac_t *mac, esp_eth_mediator_t *eth) { @@ -163,11 +165,11 @@ static esp_err_t emac_esp32_set_link(esp_eth_mac_t *mac, eth_link_t link) switch (link) { case ETH_LINK_UP: MAC_CHECK(esp_intr_enable(emac->intr_hdl) == ESP_OK, "enable interrupt failed", err, ESP_FAIL); - emac_hal_start(&emac->hal); + emac_esp32_start(mac); break; case ETH_LINK_DOWN: MAC_CHECK(esp_intr_disable(emac->intr_hdl) == ESP_OK, "disable interrupt failed", err, ESP_FAIL); - emac_hal_stop(&emac->hal); + emac_esp32_stop(mac); break; default: MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG); @@ -388,6 +390,7 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac) static esp_err_t emac_esp32_start(esp_eth_mac_t *mac) { emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); + emac_hal_reset_desc_chain(&emac->hal); emac_hal_start(&emac->hal); return ESP_OK; } @@ -395,8 +398,16 @@ static esp_err_t emac_esp32_start(esp_eth_mac_t *mac) static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac) { emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); - emac_hal_stop(&emac->hal); - return ESP_OK; + esp_err_t ret = ESP_OK; + int32_t to = 0; + do { + if ((ret = emac_hal_stop(&emac->hal)) == ESP_OK) { + break; + } + to += 25; + esp_rom_delay_us(25); + } while (to < MAC_STOP_TIMEOUT_US); + return ret; } static esp_err_t emac_esp32_del(esp_eth_mac_t *mac) diff --git a/components/esp_eth/src/esp_eth_phy_lan8720.c b/components/esp_eth/src/esp_eth_phy_lan8720.c index d0dc378a5690..34dc87a71f39 100644 --- a/components/esp_eth/src/esp_eth_phy_lan8720.c +++ b/components/esp_eth/src/esp_eth_phy_lan8720.c @@ -280,7 +280,8 @@ static esp_err_t lan8720_reset_hw(esp_eth_phy_t *phy) esp_rom_gpio_pad_select_gpio(lan8720->reset_gpio_num); gpio_set_direction(lan8720->reset_gpio_num, GPIO_MODE_OUTPUT); gpio_set_level(lan8720->reset_gpio_num, 0); - esp_rom_delay_us(100); // insert min input assert time + /* assert nRST signal on LAN8720 a little longer than the minimum specified in datasheet */ + esp_rom_delay_us(150); gpio_set_level(lan8720->reset_gpio_num, 1); } return ESP_OK; diff --git a/components/esp_hid/src/ble_hidd.c b/components/esp_hid/src/ble_hidd.c index b62ce623a2e6..f3e1a97b39fd 100644 --- a/components/esp_hid/src/ble_hidd.c +++ b/components/esp_hid/src/ble_hidd.c @@ -1,16 +1,8 @@ -// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -55,6 +47,7 @@ static const uint8_t s_char_prop_write_nr = ESP_GATT_CHAR_PROP_BIT_WRITE_NR; static const uint8_t s_char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_NOTIFY; static const uint8_t s_char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_READ; static const uint8_t s_char_prop_read_write_nr = ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_READ; +static const uint8_t s_char_prop_read_write_write_nr = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_READ; //static const uint8_t s_char_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_WRITE|ESP_GATT_CHAR_PROP_BIT_NOTIFY; // Service UUIDs @@ -331,8 +324,13 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) report->index = index; add_db_record(_last_db, index++, (uint8_t *)&s_hid_report_uuid, ESP_GATT_PERM_READ, report->value_len, 0, NULL); add_db_record(_last_db, index++, (uint8_t *)&s_character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 2, 0, NULL); + } else if (report->report_type == ESP_HID_REPORT_TYPE_OUTPUT) { + //Output Report + add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write_write_nr); + report->index = index; + add_db_record(_last_db, index++, (uint8_t *)&s_hid_report_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, report->value_len, 0, NULL); } else { - //Output or Feature Report + //Feature Report add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write); report->index = index; add_db_record(_last_db, index++, (uint8_t *)&s_hid_report_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, report->value_len, 0, NULL); @@ -349,7 +347,7 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) } add_db_record(_last_db, index++, (uint8_t *)&s_character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 2, 0, NULL); } else { //Boot Keyboard Output - add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write); + add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write_write_nr); report->index = index; add_db_record(_last_db, index++, (uint8_t *)&s_hid_boot_kb_output_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, HIDD_LE_BOOT_REPORT_MAX_LEN, 0, NULL); } diff --git a/components/esp_hid/src/esp_hidh.c b/components/esp_hid/src/esp_hidh.c index 3d318427f458..8bc38165c62e 100644 --- a/components/esp_hid/src/esp_hidh.c +++ b/components/esp_hid/src/esp_hidh.c @@ -1,16 +1,8 @@ -// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "sys/queue.h" #include "esp_hidh_private.h" @@ -361,7 +353,7 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_id_and_proto(esp_hidh_de { esp_hidh_dev_report_t *r = dev->reports; while (r) { - if (r->report_id == report_id && (r->report_type & 1) && r->protocol_mode == protocol_mode) { + if (r->report_id == report_id && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && r->protocol_mode == protocol_mode) { return r; } r = r->next; diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 056e04df2ae0..9359bd447d90 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -40,6 +40,7 @@ typedef struct { char *data; /*!< The HTTP data received from the server */ int len; /*!< The HTTP data len received from the server */ char *raw_data; /*!< The HTTP data after decoding */ + char *orig_raw_data;/*!< The Original pointer to HTTP data after decoding */ int raw_len; /*!< The HTTP data len after decoding */ char *output_ptr; /*!< The destination address of the data to be copied to after decoding */ } esp_http_buffer_t; @@ -82,6 +83,7 @@ typedef enum { HTTP_STATE_REQ_COMPLETE_HEADER, HTTP_STATE_REQ_COMPLETE_DATA, HTTP_STATE_RES_COMPLETE_HEADER, + HTTP_STATE_RES_ON_DATA_START, HTTP_STATE_RES_COMPLETE_DATA, HTTP_STATE_CLOSE } esp_http_state_t; @@ -122,6 +124,7 @@ struct esp_http_client { int header_index; bool is_async; esp_transport_keep_alive_t keep_alive_cfg; + unsigned cache_data_in_fetch_hdr: 1; }; typedef struct esp_http_client esp_http_client_t; @@ -272,10 +275,24 @@ static int http_on_body(http_parser *parser, const char *at, size_t length) { esp_http_client_t *client = parser->data; ESP_LOGD(TAG, "http_on_body %d", length); - client->response->buffer->raw_data = (char *)at; + if (client->response->buffer->output_ptr) { memcpy(client->response->buffer->output_ptr, (char *)at, length); client->response->buffer->output_ptr += length; + } else { + /* Do not cache body when http_on_body is called from esp_http_client_perform */ + if (client->state < HTTP_STATE_RES_ON_DATA_START && client->cache_data_in_fetch_hdr) { + ESP_LOGI(TAG, "Body received in fetch header state, %p, %d", at, length); + esp_http_buffer_t *res_buffer = client->response->buffer; + assert(res_buffer->orig_raw_data == res_buffer->raw_data); + res_buffer->orig_raw_data = (char *)realloc(res_buffer->orig_raw_data, res_buffer->raw_len + length); + if (!res_buffer->orig_raw_data) { + ESP_LOGE(TAG, "Failed to allocate memory for storing decoded data"); + return -1; + } + memcpy(res_buffer->orig_raw_data + res_buffer->raw_len, at, length); + res_buffer->raw_data = res_buffer->orig_raw_data; + } } client->response->data_process += length; @@ -510,6 +527,16 @@ static esp_err_t esp_http_client_prepare(esp_http_client_handle_t client) client->process_again = 0; client->response->data_process = 0; client->first_line_prepared = false; + /** + * Clear location field before making a new HTTP request. Location + * field should not be cleared in http_on_header* callbacks because + * callbacks can be invoked multiple times for same header, and + * hence can lead to data corruption. + */ + if (client->location != NULL) { + free(client->location); + client->location = NULL; + } http_parser_init(client->parser, HTTP_RESPONSE); if (client->connection_info.username) { char *auth_response = NULL; @@ -603,7 +630,13 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co goto error; } - if (config->use_global_ca_store == true) { + if (config->crt_bundle_attach != NULL) { +#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + esp_transport_ssl_crt_bundle_attach(ssl, config->crt_bundle_attach); +#else //CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + ESP_LOGE(TAG, "use_crt_bundle configured but not enabled in menuconfig: Please enable MBEDTLS_CERTIFICATE_BUNDLE option"); +#endif + } else if (config->use_global_ca_store == true) { esp_transport_ssl_enable_global_ca_store(ssl); } else if (config->cert_pem) { esp_transport_ssl_set_cert_data(ssl, config->cert_pem, strlen(config->cert_pem)); @@ -647,6 +680,10 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co const char *user_agent = config->user_agent == NULL ? DEFAULT_HTTP_USER_AGENT : config->user_agent; if (config->host != NULL && config->path != NULL) { + if (client->connection_info.host == NULL) { + ESP_LOGE(TAG, "invalid host"); + goto error; + } host_name = _get_host_header(client->connection_info.host, client->connection_info.port); if (host_name == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for host header"); @@ -666,6 +703,10 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co ESP_LOGE(TAG, "Failed to set URL"); goto error; } + if (client->connection_info.host == NULL) { + ESP_LOGE(TAG, "invalid host"); + goto error; + } host_name = _get_host_header(client->connection_info.host, client->connection_info.port); if (host_name == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for host header"); @@ -687,6 +728,11 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co goto error; } + /* As default behavior, cache data received in fetch header state. This will be + * used in esp_http_client_read API only. For esp_http_perform we shall disable + * this as data will be processed by event handler */ + client->cache_data_in_fetch_hdr = 1; + client->parser_settings->on_message_begin = http_on_message_begin; client->parser_settings->on_url = http_on_url; client->parser_settings->on_status = http_on_status; @@ -726,6 +772,11 @@ esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client) http_header_destroy(client->response->headers); if (client->response->buffer) { free(client->response->buffer->data); + if (client->response->buffer->orig_raw_data) { + free(client->response->buffer->orig_raw_data); + client->response->buffer->orig_raw_data = NULL; + client->response->buffer->raw_data = NULL; + } } free(client->response->buffer); free(client->response); @@ -767,7 +818,9 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client) switch (client->response->status_code) { case HttpStatus_MovedPermanently: case HttpStatus_Found: + case HttpStatus_SeeOther: case HttpStatus_TemporaryRedirect: + case HttpStatus_PermanentRedirect: esp_http_client_set_redirection(client); client->redirect_counter ++; client->process_again = 1; @@ -891,7 +944,7 @@ esp_err_t esp_http_client_set_method(esp_http_client_handle_t client, esp_http_c static int esp_http_client_get_data(esp_http_client_handle_t client) { - if (client->state < HTTP_STATE_RES_COMPLETE_HEADER) { + if (client->state < HTTP_STATE_RES_ON_DATA_START) { return ESP_FAIL; } @@ -940,6 +993,11 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len) res_buffer->raw_len -= remain_len; res_buffer->raw_data += remain_len; ridx = remain_len; + if (res_buffer->raw_len == 0) { + free(res_buffer->orig_raw_data); + res_buffer->orig_raw_data = NULL; + res_buffer->raw_data = NULL; + } } int need_read = len - ridx; bool is_data_remain = true; @@ -1036,14 +1094,23 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client) } /* falls through */ case HTTP_STATE_REQ_COMPLETE_DATA: + /* Disable caching response body, as data should + * be handled by application event handler */ + client->cache_data_in_fetch_hdr = 0; if (esp_http_client_fetch_headers(client) < 0) { if (client->is_async && errno == EAGAIN) { return ESP_ERR_HTTP_EAGAIN; } + /* Enable caching after error condition because next + * request could be performed using native APIs */ + client->cache_data_in_fetch_hdr = 1; return ESP_ERR_HTTP_FETCH_HEADER; } /* falls through */ - case HTTP_STATE_RES_COMPLETE_HEADER: + case HTTP_STATE_RES_ON_DATA_START: + /* Enable caching after fetch headers state because next + * request could be performed using native APIs */ + client->cache_data_in_fetch_hdr = 1; if ((err = esp_http_check_response(client)) != ESP_OK) { ESP_LOGE(TAG, "Error response"); return err; @@ -1103,6 +1170,7 @@ int esp_http_client_fetch_headers(esp_http_client_handle_t client) } http_parser_execute(client->parser, client->parser_settings, buffer->data, buffer->len); } + client->state = HTTP_STATE_RES_ON_DATA_START; ESP_LOGD(TAG, "content_length = %d", client->response->content_length); if (client->response->content_length <= 0) { client->response->is_chunked = true; @@ -1395,7 +1463,7 @@ void esp_http_client_add_auth(esp_http_client_handle_t client) if (client == NULL) { return; } - if (client->state != HTTP_STATE_RES_COMPLETE_HEADER) { + if (client->state != HTTP_STATE_RES_ON_DATA_START) { return; } if (client->redirect_counter >= client->max_authorization_retries) { diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index e559b61939b7..f5f8eee13dce 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -133,6 +133,8 @@ typedef struct { bool is_async; /*!< Set asynchronous mode, only supported with HTTPS for now */ bool use_global_ca_store; /*!< Use a global ca_store for all the connections in which this bool is set. */ bool skip_cert_common_name_check; /*!< Skip any validation of server certificate CN field */ + esp_err_t (*crt_bundle_attach)(void *conf); /*!< Function pointer to esp_crt_bundle_attach. Enables the use of certification + bundle for server verification, must be enabled in menuconfig */ bool keep_alive_enable; /*!< Enable keep-alive timeout */ int keep_alive_idle; /*!< Keep-alive idle time. Default is 5 (second) */ int keep_alive_interval; /*!< Keep-alive interval time. Default is 5 (second) */ @@ -150,7 +152,9 @@ typedef enum { HttpStatus_MultipleChoices = 300, HttpStatus_MovedPermanently = 301, HttpStatus_Found = 302, + HttpStatus_SeeOther = 303, HttpStatus_TemporaryRedirect = 307, + HttpStatus_PermanentRedirect = 308, /* 4xx - Client Error */ HttpStatus_BadRequest = 400, diff --git a/components/esp_http_client/test/test_http_client.c b/components/esp_http_client/test/test_http_client.c index 504c42e1a984..d68741a9e53a 100644 --- a/components/esp_http_client/test/test_http_client.c +++ b/components/esp_http_client/test/test_http_client.c @@ -140,3 +140,16 @@ TEST_CASE("Username and password will not reset if new absolute URL doesnot spec TEST_ASSERT_NOT_NULL(value); esp_http_client_cleanup(client); } + +/** + * Test case to verify that, esp_http_client_init() should return NULL if configuration has url with empty hostname. + **/ +TEST_CASE("esp_http_client_init() should return NULL if configured with wrong url", "[ESP HTTP CLIENT]") +{ + esp_http_client_config_t config = { + .url = "//httpbin.org/post", + }; + esp_http_client_handle_t client = esp_http_client_init(&config); + TEST_ASSERT_NULL(client); + esp_http_client_cleanup(client); +} diff --git a/components/esp_http_server/src/httpd_parse.c b/components/esp_http_server/src/httpd_parse.c index cc328a9e665f..b420a9a30d81 100644 --- a/components/esp_http_server/src/httpd_parse.c +++ b/components/esp_http_server/src/httpd_parse.c @@ -758,16 +758,19 @@ esp_err_t httpd_req_new(struct httpd_data *hd, struct sock_db *sd) sd->ws_handler != NULL ? "Yes" : "No", sd->ws_close ? "Yes" : "No"); if (sd->ws_handshake_done && sd->ws_handler != NULL) { + if (sd->ws_close == true) { + /* WS was marked as close state, do not deal with this socket */ + ESP_LOGD(TAG, LOG_FMT("WS was marked close")); + return ESP_OK; + } + ret = httpd_ws_get_frame_type(r); ESP_LOGD(TAG, LOG_FMT("New WS request from existing socket, ws_type=%d"), ra->ws_type); - /* Stop and return here immediately if it's a CLOSE frame */ if (ra->ws_type == HTTPD_WS_TYPE_CLOSE) { + /* Only mark ws_close to true if it's a CLOSE frame */ sd->ws_close = true; - return ret; - } - - if (ra->ws_type == HTTPD_WS_TYPE_PONG) { + } else if (ra->ws_type == HTTPD_WS_TYPE_PONG) { /* Pass the PONG frames to the handler as well, as user app might send PINGs */ ESP_LOGD(TAG, LOG_FMT("Received PONG frame")); } diff --git a/components/esp_http_server/src/httpd_ws.c b/components/esp_http_server/src/httpd_ws.c index 7afbd4afb00c..ff6cbd2a86f5 100644 --- a/components/esp_http_server/src/httpd_ws.c +++ b/components/esp_http_server/src/httpd_ws.c @@ -472,6 +472,25 @@ esp_err_t httpd_ws_get_frame_type(httpd_req_t *req) /* Now turn the frame to PONG */ frame.type = HTTPD_WS_TYPE_PONG; return httpd_ws_send_frame(req, &frame); + } else if (aux->ws_type == HTTPD_WS_TYPE_CLOSE) { + ESP_LOGD(TAG, LOG_FMT("Got a WS CLOSE frame, Replying CLOSE...")); + + /* Read the rest of the CLOSE frame and response */ + /* Please refer to RFC6455 Section 5.5.1 for more details */ + httpd_ws_frame_t frame; + uint8_t frame_buf[128] = { 0 }; + memset(&frame, 0, sizeof(httpd_ws_frame_t)); + frame.payload = frame_buf; + + if (httpd_ws_recv_frame(req, &frame, 126) != ESP_OK) { + ESP_LOGD(TAG, LOG_FMT("Cannot receive the full CLOSE frame")); + return ESP_ERR_INVALID_STATE; + } + + frame.len = 0; + frame.type = HTTPD_WS_TYPE_CLOSE; + frame.payload = NULL; + return httpd_ws_send_frame(req, &frame); } return ESP_OK; diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c index f685a9d6e6a4..91fdfaaa889c 100644 --- a/components/esp_https_ota/src/esp_https_ota.c +++ b/components/esp_https_ota/src/esp_https_ota.c @@ -45,12 +45,29 @@ struct esp_https_ota_handle { typedef struct esp_https_ota_handle esp_https_ota_t; +static bool redirection_required(int status_code) +{ + switch (status_code) { + case HttpStatus_MovedPermanently: + case HttpStatus_Found: + case HttpStatus_SeeOther: + case HttpStatus_TemporaryRedirect: + case HttpStatus_PermanentRedirect: + return true; + default: + return false; + } + return false; +} + static bool process_again(int status_code) { switch (status_code) { case HttpStatus_MovedPermanently: case HttpStatus_Found: + case HttpStatus_SeeOther: case HttpStatus_TemporaryRedirect: + case HttpStatus_PermanentRedirect: case HttpStatus_Unauthorized: return true; default: @@ -62,7 +79,7 @@ static bool process_again(int status_code) static esp_err_t _http_handle_response_code(esp_http_client_handle_t http_client, int status_code) { esp_err_t err; - if (status_code == HttpStatus_MovedPermanently || status_code == HttpStatus_Found || status_code == HttpStatus_TemporaryRedirect) { + if (redirection_required(status_code)) { err = esp_http_client_set_redirection(http_client); if (err != ESP_OK) { ESP_LOGE(TAG, "URL redirection Failed"); @@ -143,6 +160,12 @@ static esp_err_t _ota_write(esp_https_ota_t *https_ota_handle, const void *buffe return err; } +static bool is_server_verification_enabled(esp_https_ota_config_t *ota_config) { + return (ota_config->http_config->cert_pem + || ota_config->http_config->use_global_ca_store + || !(ota_config->http_config->crt_bundle_attach == NULL)); +} + esp_err_t esp_https_ota_begin(esp_https_ota_config_t *ota_config, esp_https_ota_handle_t *handle) { esp_err_t err; @@ -156,8 +179,8 @@ esp_err_t esp_https_ota_begin(esp_https_ota_config_t *ota_config, esp_https_ota_ } #if !CONFIG_OTA_ALLOW_HTTP - if (!ota_config->http_config->cert_pem) { - ESP_LOGE(TAG, "Server certificate not found in esp_http_client config"); + if (!is_server_verification_enabled(ota_config)) { + ESP_LOGE(TAG, "No option for server verification is enabled in esp_http_client config."); *handle = NULL; return ESP_ERR_INVALID_ARG; } @@ -182,7 +205,7 @@ esp_err_t esp_https_ota_begin(esp_https_ota_config_t *ota_config, esp_https_ota_ err = ota_config->http_client_init_cb(https_ota_handle->http_client); if (err != ESP_OK) { ESP_LOGE(TAG, "http_client_init_cb returned 0x%x", err); - goto failure; + goto http_cleanup; } } @@ -225,17 +248,8 @@ esp_err_t esp_https_ota_begin(esp_https_ota_config_t *ota_config, esp_https_ota_ return err; } -esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, esp_app_desc_t *new_app_info) +static esp_err_t read_header(esp_https_ota_t *handle) { - esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; - if (handle == NULL || new_app_info == NULL) { - ESP_LOGE(TAG, "esp_https_ota_read_img_desc: Invalid argument"); - return ESP_ERR_INVALID_ARG; - } - if (handle->state < ESP_HTTPS_OTA_BEGIN) { - ESP_LOGE(TAG, "esp_https_ota_read_img_desc: Invalid state"); - return ESP_FAIL; - } /* * `data_read_size` holds number of bytes needed to read complete header. * `bytes_read` holds number of bytes read. @@ -246,7 +260,7 @@ esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, es * while loop is added to download complete image headers, even if the headers * are not sent in a single packet. */ - while (data_read_size > 0 && !esp_https_ota_is_complete_data_received(https_ota_handle)) { + while (data_read_size > 0 && !esp_https_ota_is_complete_data_received((esp_https_ota_handle_t)handle)) { data_read = esp_http_client_read(handle->http_client, (handle->ota_upgrade_buf + bytes_read), data_read_size); @@ -266,10 +280,37 @@ esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, es return ESP_FAIL; } handle->binary_file_len = bytes_read; + return ESP_OK; +} + +esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, esp_app_desc_t *new_app_info) +{ + esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; + if (handle == NULL || new_app_info == NULL) { + ESP_LOGE(TAG, "esp_https_ota_read_img_desc: Invalid argument"); + return ESP_ERR_INVALID_ARG; + } + if (handle->state < ESP_HTTPS_OTA_BEGIN) { + ESP_LOGE(TAG, "esp_https_ota_read_img_desc: Invalid state"); + return ESP_FAIL; + } + if (read_header(handle) != ESP_OK) { + return ESP_FAIL; + } memcpy(new_app_info, &handle->ota_upgrade_buf[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t)); return ESP_OK; } +static esp_err_t esp_ota_verify_chip_id(void *arg) +{ + esp_image_header_t *data = (esp_image_header_t*)(arg); + if (data->chip_id != CONFIG_IDF_FIRMWARE_CHIP_ID) { + ESP_LOGE(TAG, "Mismatch chip id, expected %d, found %d", CONFIG_IDF_FIRMWARE_CHIP_ID, data->chip_id); + return ESP_ERR_INVALID_VERSION; + } + return ESP_OK; +} + esp_err_t esp_https_ota_perform(esp_https_ota_handle_t https_ota_handle) { esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; @@ -296,10 +337,25 @@ esp_err_t esp_https_ota_perform(esp_https_ota_handle_t https_ota_handle) /* In case `esp_https_ota_read_img_desc` was invoked first, then the image data read there should be written to OTA partition */ + int binary_file_len = 0; if (handle->binary_file_len) { - return _ota_write(handle, (const void *)handle->ota_upgrade_buf, handle->binary_file_len); + /* + * Header length gets added to handle->binary_file_len in _ota_write + * Clear handle->binary_file_len to avoid additional 289 bytes in binary_file_len + */ + binary_file_len = handle->binary_file_len; + handle->binary_file_len = 0; + } else { + if (read_header(handle) != ESP_OK) { + return ESP_FAIL; + } + binary_file_len = IMAGE_HEADER_SIZE; } - /* falls through */ + err = esp_ota_verify_chip_id(handle->ota_upgrade_buf); + if (err != ESP_OK) { + return err; + } + return _ota_write(handle, (const void *)handle->ota_upgrade_buf, binary_file_len); case ESP_HTTPS_OTA_IN_PROGRESS: data_read = esp_http_client_read(handle->http_client, handle->ota_upgrade_buf, diff --git a/components/esp_hw_support/port/esp32/CMakeLists.txt b/components/esp_hw_support/port/esp32/CMakeLists.txt index 9d568ed92629..ae6dfd219d2f 100644 --- a/components/esp_hw_support/port/esp32/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32/CMakeLists.txt @@ -1,5 +1,5 @@ target_include_directories(${COMPONENT_LIB} PUBLIC .) -target_include_directories(${COMPONENT_LIB} PRIVATE private_include) +target_include_directories(${COMPONENT_LIB} PUBLIC private_include) set(srcs "rtc_clk.c" diff --git a/components/esp_hw_support/port/esp32/regi2c_ctrl.h b/components/esp_hw_support/port/esp32/regi2c_ctrl.h index 69f2919207f4..e4a81c19109b 100644 --- a/components/esp_hw_support/port/esp32/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32/regi2c_ctrl.h @@ -60,6 +60,10 @@ uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_ad void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +/* enter the critical section that protects internal registers. Don't use it in SDK. Use the functions above. */ +void regi2c_enter_critical(void); +void regi2c_exit_critical(void); + #endif // BOOTLOADER_BUILD /* Convenience macros for the above functions, these use register definitions diff --git a/components/esp_hw_support/port/esp32/rtc_time.c b/components/esp_hw_support/port/esp32/rtc_time.c index 99539e0d558d..80e2ae2ccba8 100644 --- a/components/esp_hw_support/port/esp32/rtc_time.c +++ b/components/esp_hw_support/port/esp32/rtc_time.c @@ -143,8 +143,14 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) uint64_t rtc_time_get(void) { SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE); + int attempts = 1000; while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) { esp_rom_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus + if (attempts) { + if (--attempts == 0 && REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN)) { + SOC_LOGE(TAG, "rtc_time_get() 32kHz xtal has been stopped"); + } + } } SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR); uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG); @@ -163,8 +169,14 @@ void rtc_clk_wait_for_slow_cycle(void) REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, 0); REG_SET_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); esp_rom_delay_us(1); /* RDY needs some time to go low */ + int attempts = 1000; while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { esp_rom_delay_us(1); + if (attempts) { + if (--attempts == 0 && REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN)) { + SOC_LOGE(TAG, "32kHz xtal has been stopped"); + } + } } } diff --git a/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h b/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h index e9def9583d1a..255ed52e3311 100644 --- a/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h +++ b/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h @@ -1,16 +1,8 @@ -// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -85,3 +77,10 @@ #define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_LSB 0 + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround, and is fixed on later chips + */ +#define REGI2C_ANA_CALI_PD_WORKAROUND 1 +#define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h b/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h index 95f2626656eb..93a7e94a4325 100644 --- a/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h @@ -87,6 +87,10 @@ uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_ad void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +/* enter the critical section that protects internal registers. Don't use it in SDK. Use the functions above. */ +void regi2c_enter_critical(void); +void regi2c_exit_critical(void); + #endif // BOOTLOADER_BUILD /* Convenience macros for the above functions, these use register definitions @@ -104,6 +108,16 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, #define REGI2C_READ(block, reg_add) \ regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround, and is fixed on later chips + */ +#if REGI2C_ANA_CALI_PD_WORKAROUND +void regi2c_analog_cali_reg_read(void); +void regi2c_analog_cali_reg_write(void); +#endif //#if ADC_CALI_PD_WORKAROUND + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk.c b/components/esp_hw_support/port/esp32c3/rtc_clk.c index 735a45d8c6bf..b34f9c642ae8 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c3/rtc_clk.c @@ -31,6 +31,7 @@ #include "soc_log.h" #include "rtc_clk_common.h" #include "esp_rom_sys.h" +#include "hal/usb_serial_jtag_ll.h" static const char *TAG = "rtc_clk"; @@ -42,6 +43,7 @@ static const char *TAG = "rtc_clk"; static int s_cur_pll_freq; static void rtc_clk_cpu_freq_to_8m(void); +static bool rtc_clk_set_bbpll_always_on(void); void rtc_clk_32k_enable_internal(x32k_config_t cfg) { @@ -342,7 +344,8 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); if (config->source == RTC_CPU_FREQ_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) { + if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) { + // We don't turn off the bbpll if some consumers only depends on bbpll rtc_clk_bbpll_disable(); } } else if (config->source == RTC_CPU_FREQ_SRC_PLL) { @@ -353,7 +356,8 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); } else if (config->source == RTC_CPU_FREQ_SRC_8M) { rtc_clk_cpu_freq_to_8m(); - if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) { + if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) { + // We don't turn off the bbpll if some consumers only depends on bbpll rtc_clk_bbpll_disable(); } } @@ -428,7 +432,10 @@ void rtc_clk_cpu_freq_set_xtal(void) int freq_mhz = (int) rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); - rtc_clk_bbpll_disable(); + // We don't turn off the bbpll if some consumers only depends on bbpll + if (!rtc_clk_set_bbpll_always_on()) { + rtc_clk_bbpll_disable(); + } } /** @@ -509,6 +516,21 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +static bool rtc_clk_set_bbpll_always_on(void) +{ + /* We just keep the rtc bbpll clock on just under the case that + user selects the `RTC_CLOCK_BBPLL_POWER_ON_WITH_USB` as well as + the USB_SERIAL_JTAG is connected with PC. + */ + bool is_bbpll_on = false; +#if CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB + if (usb_serial_jtag_ll_txfifo_writable() == 1) { + is_bbpll_on = true; + } +#endif + return is_bbpll_on; +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c3/rtc_init.c b/components/esp_hw_support/port/esp32c3/rtc_init.c index d6ed8f4d87c0..1dbca83e546a 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_init.c +++ b/components/esp_hw_support/port/esp32c3/rtc_init.c @@ -154,6 +154,7 @@ void rtc_init(rtc_config_t cfg) REG_WRITE(RTC_CNTL_INT_ENA_REG, 0); REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX); + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 1); } rtc_vddsdio_config_t rtc_vddsdio_get_config(void) diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index dc4794d6134b..cbaa4b689e4b 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -67,6 +67,8 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } + /* mem force pu */ + SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU); if (cfg.wifi_pd_en) { SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN); } else { diff --git a/components/esp_hw_support/port/esp32c3/rtc_time.c b/components/esp_hw_support/port/esp32c3/rtc_time.c index 18694a4f5bba..e3ba461b19e3 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_time.c +++ b/components/esp_hw_support/port/esp32c3/rtc_time.c @@ -65,6 +65,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) * so we should wait the last process is done. */ if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) { + /** + * Set a small timeout threshold to accelerate the generation of timeout. + * The internal circuit will be reset when the timeout occurs and will not affect the next calibration. + */ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1); while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)); } diff --git a/components/esp_hw_support/port/esp32s2/private_include/regi2c_saradc.h b/components/esp_hw_support/port/esp32s2/private_include/regi2c_saradc.h index 2345e0a5aaea..2c3738a2210a 100644 --- a/components/esp_hw_support/port/esp32s2/private_include/regi2c_saradc.h +++ b/components/esp_hw_support/port/esp32s2/private_include/regi2c_saradc.h @@ -1,16 +1,8 @@ -// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -81,3 +73,10 @@ #define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_LSB 0 + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround, and is fixed on later chips + */ +#define REGI2C_ANA_CALI_PD_WORKAROUND 1 +#define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h b/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h index 51a0a22dcbb9..90695d01595f 100644 --- a/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h @@ -68,6 +68,10 @@ uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_ad void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +/* enter the critical section that protects internal registers. Don't use it in SDK. Use the functions above. */ +void regi2c_enter_critical(void); +void regi2c_exit_critical(void); + #endif // BOOTLOADER_BUILD /* Convenience macros for the above functions, these use register definitions @@ -85,6 +89,16 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, #define REGI2C_READ(block, reg_add) \ regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround, and is fixed on later chips + */ +#if REGI2C_ANA_CALI_PD_WORKAROUND +void regi2c_analog_cali_reg_read(void); +void regi2c_analog_cali_reg_write(void); +#endif //#if ADC_CALI_PD_WORKAROUND + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/port/esp32s2/rtc_time.c b/components/esp_hw_support/port/esp32s2/rtc_time.c index af0bb602ba39..b96a2b23d6dd 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_time.c +++ b/components/esp_hw_support/port/esp32s2/rtc_time.c @@ -42,6 +42,11 @@ static uint32_t rtc_clk_cal_internal_oneoff(rtc_cal_sel_t cal_clk, uint32_t slow * so we should wait the last process is done. */ if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) { + /** + * Set a small timeout threshold to accelerate the generation of timeout. + * The internal circuit will be reset when the timeout occurs and will not affect the next calibration. + */ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1); while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)); } diff --git a/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h b/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h index b8507917a788..bc4cdc9df54b 100644 --- a/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -18,6 +10,10 @@ #include "regi2c_bbpll.h" #include "regi2c_dig_reg.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Analog function control register */ #define ANA_CONFIG_REG 0x6000E044 #define ANA_CONFIG_S (8) @@ -61,6 +57,10 @@ uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_ad void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +/* enter the critical section that protects internal registers. Don't use it in SDK. Use the functions above. */ +void regi2c_enter_critical(void); +void regi2c_exit_critical(void); + #endif // BOOTLOADER_BUILD /* Convenience macros for the above functions, these use register definitions @@ -77,3 +77,17 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, #define REGI2C_READ(block, reg_add) \ regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) + + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround, and is fixed on later chips + */ +#if REGI2C_ANA_CALI_PD_WORKAROUND +void regi2c_analog_cali_reg_read(void); +void regi2c_analog_cali_reg_write(void); +#endif //#if ADC_CALI_PD_WORKAROUND + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32s3/rtc_time.c b/components/esp_hw_support/port/esp32s3/rtc_time.c index 0247c636985c..4323b479d87e 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_time.c +++ b/components/esp_hw_support/port/esp32s3/rtc_time.c @@ -64,6 +64,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) * so we should wait the last process is done. */ if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) { + /** + * Set a small timeout threshold to accelerate the generation of timeout. + * The internal circuit will be reset when the timeout occurs and will not affect the next calibration. + */ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1); while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)); } diff --git a/components/esp_hw_support/regi2c_ctrl.c b/components/esp_hw_support/regi2c_ctrl.c index 77a22ae6628f..6ce93cc5c1a5 100644 --- a/components/esp_hw_support/regi2c_ctrl.c +++ b/components/esp_hw_support/regi2c_ctrl.c @@ -1,18 +1,11 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "regi2c_ctrl.h" +#include "esp_attr.h" #include #include #include @@ -21,30 +14,64 @@ static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; uint8_t IRAM_ATTR regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add) { - portENTER_CRITICAL_ISR(&mux); + portENTER_CRITICAL_SAFE(&mux); uint8_t value = i2c_read_reg_raw(block, host_id, reg_add); - portEXIT_CRITICAL_ISR(&mux); + portEXIT_CRITICAL_SAFE(&mux); return value; } uint8_t IRAM_ATTR regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) { - portENTER_CRITICAL_ISR(&mux); + portENTER_CRITICAL_SAFE(&mux); uint8_t value = i2c_read_reg_mask_raw(block, host_id, reg_add, msb, lsb); - portEXIT_CRITICAL_ISR(&mux); + portEXIT_CRITICAL_SAFE(&mux); return value; } void IRAM_ATTR regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) { - portENTER_CRITICAL_ISR(&mux); + portENTER_CRITICAL_SAFE(&mux); i2c_write_reg_raw(block, host_id, reg_add, data); - portEXIT_CRITICAL_ISR(&mux); + portEXIT_CRITICAL_SAFE(&mux); } void IRAM_ATTR regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) { - portENTER_CRITICAL_ISR(&mux); + portENTER_CRITICAL_SAFE(&mux); i2c_write_reg_mask_raw(block, host_id, reg_add, msb, lsb, data); - portEXIT_CRITICAL_ISR(&mux); + portEXIT_CRITICAL_SAFE(&mux); } + +void IRAM_ATTR regi2c_enter_critical(void) +{ + portENTER_CRITICAL_SAFE(&mux); +} + +void IRAM_ATTR regi2c_exit_critical(void) +{ + portEXIT_CRITICAL_SAFE(&mux); +} + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround, and is fixed on later chips + */ +#if REGI2C_ANA_CALI_PD_WORKAROUND + +static DRAM_ATTR uint8_t reg_val[REGI2C_ANA_CALI_BYTE_NUM]; + +void IRAM_ATTR regi2c_analog_cali_reg_read(void) +{ + for (int i = 0; i < REGI2C_ANA_CALI_BYTE_NUM; i++) { + reg_val[i] = regi2c_ctrl_read_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i); + } +} + +void IRAM_ATTR regi2c_analog_cali_reg_write(void) +{ + for (int i = 0; i < REGI2C_ANA_CALI_BYTE_NUM; i++) { + regi2c_ctrl_write_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i, reg_val[i]); + } +} + +#endif //#if ADC_CALI_PD_WORKAROUND diff --git a/components/esp_ipc/ipc.c b/components/esp_ipc/ipc.c index 98331077e56a..41659105d9e7 100644 --- a/components/esp_ipc/ipc.c +++ b/components/esp_ipc/ipc.c @@ -65,14 +65,17 @@ static void IRAM_ATTR ipc_task(void* arg) } #endif if (s_func[cpuid]) { + // we need to cache s_func, s_func_arg and s_ipc_wait variables locally because they can be changed by a subsequent IPC call. esp_ipc_func_t func = s_func[cpuid]; + s_func[cpuid] = NULL; void* arg = s_func_arg[cpuid]; + esp_ipc_wait_t ipc_wait = s_ipc_wait[cpuid]; - if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_START) { + if (ipc_wait == IPC_WAIT_FOR_START) { xSemaphoreGive(s_ipc_ack[cpuid]); } (*func)(arg); - if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_END) { + if (ipc_wait == IPC_WAIT_FOR_END) { xSemaphoreGive(s_ipc_ack[cpuid]); } } @@ -141,7 +144,6 @@ static esp_err_t esp_ipc_call_and_wait(uint32_t cpu_id, esp_ipc_func_t func, voi s_ipc_wait[cpu_id] = wait_for; xSemaphoreGive(s_ipc_sem[cpu_id]); xSemaphoreTake(s_ipc_ack[cpu_id], portMAX_DELAY); - s_func[cpu_id] = NULL; #ifdef CONFIG_ESP_IPC_USES_CALLERS_PRIORITY xSemaphoreGive(s_ipc_mutex[cpu_id]); #else diff --git a/components/esp_ipc/test/test_ipc.c b/components/esp_ipc/test/test_ipc.c index 9369b2524d9f..de19814b826c 100644 --- a/components/esp_ipc/test/test_ipc.c +++ b/components/esp_ipc/test/test_ipc.c @@ -125,4 +125,30 @@ TEST_CASE("Test multiple ipc_calls", "[ipc]") } #endif /* CONFIG_ESP_IPC_USE_CALLERS_PRIORITY */ +static void test_func_ipc_cb2(void *arg) +{ + vTaskDelay(100 / portTICK_PERIOD_MS); + int *val = (int *)arg; + *val = *val + 1; +} + +static void test_func_ipc_cb3(void *arg) +{ + vTaskDelay(500 / portTICK_PERIOD_MS); + int *val = (int *)arg; + *val = *val + 1; +} + +TEST_CASE("Test ipc_task can not wake up blocking task early", "[ipc]") +{ + int val1 = 20; + esp_ipc_call(1, test_func_ipc_cb2, &val1); + TEST_ASSERT_EQUAL(20, val1); + + int val2 = 30; + esp_ipc_call_blocking(1, test_func_ipc_cb3, &val2); + TEST_ASSERT_EQUAL(21, val1); + TEST_ASSERT_EQUAL(31, val2); +} + #endif /* !CONFIG_FREERTOS_UNICORE */ diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 63316e643ecd..ce051090dd42 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -109,8 +109,6 @@ static portMUX_TYPE s_switch_lock = portMUX_INITIALIZER_UNLOCKED; static pm_mode_t s_mode = PM_MODE_CPU_MAX; /* True when switch is in progress */ static volatile bool s_is_switching; -/* When switch is in progress, this is the mode we are switching into */ -static pm_mode_t s_new_mode = PM_MODE_CPU_MAX; /* Number of times each mode was locked */ static size_t s_mode_lock_counts[PM_MODE_COUNT]; /* Bit mask of locked modes. BIT(i) is set iff s_mode_lock_counts[i] > 0. */ @@ -395,7 +393,7 @@ void IRAM_ATTR esp_pm_impl_switch_mode(pm_mode_t mode, #endif // WITH_PROFILING } portEXIT_CRITICAL_SAFE(&s_switch_lock); - if (need_switch && new_mode != s_mode) { + if (need_switch) { do_switch(new_mode); } } @@ -470,10 +468,6 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) if (!s_is_switching) { break; } - if (s_new_mode <= new_mode) { - portEXIT_CRITICAL_ISR(&s_switch_lock); - return; - } #if __XTENSA__ if (s_need_update_ccompare[core_id]) { s_need_update_ccompare[core_id] = false; @@ -481,7 +475,10 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) #endif portEXIT_CRITICAL_ISR(&s_switch_lock); } while (true); - s_new_mode = new_mode; + if (new_mode == s_mode) { + portEXIT_CRITICAL_ISR(&s_switch_lock); + return; + } s_is_switching = true; bool config_changed = s_config_changed; s_config_changed = false; @@ -821,8 +818,8 @@ void esp_pm_impl_waiti(void) * the lock so that vApplicationSleep can attempt to enter light sleep. */ esp_pm_impl_idle_hook(); - s_skipped_light_sleep[core_id] = false; } + s_skipped_light_sleep[core_id] = true; #else cpu_hal_waiti(); #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE diff --git a/components/esp_ringbuf/ringbuf.c b/components/esp_ringbuf/ringbuf.c index f8c62d03c7b5..2b83678adae4 100644 --- a/components/esp_ringbuf/ringbuf.c +++ b/components/esp_ringbuf/ringbuf.c @@ -1,4 +1,4 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ #define rbITEM_FREE_FLAG ( ( UBaseType_t ) 1 ) //Item has been retrieved and returned by application, free to overwrite #define rbITEM_DUMMY_DATA_FLAG ( ( UBaseType_t ) 2 ) //Data from here to end of the ring buffer is dummy data. Restart reading at start of head of the buffer #define rbITEM_SPLIT_FLAG ( ( UBaseType_t ) 4 ) //Valid for RINGBUF_TYPE_ALLOWSPLIT, indicating that rest of the data is wrapped around -#define rbITEM_WRITTEN_FLAG ( ( UBaseType_t ) 8 ) //Item has been written to by the application, thus it is free to be read +#define rbITEM_WRITTEN_FLAG ( ( UBaseType_t ) 8 ) //Item has been written to by the application, thus can be read //Static allocation related #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) @@ -143,16 +143,41 @@ static BaseType_t prvCheckItemFitsDefault( Ringbuffer_t *pxRingbuffer, size_t xI //Checks if an item will currently fit in a byte buffer static BaseType_t prvCheckItemFitsByteBuffer( Ringbuffer_t *pxRingbuffer, size_t xItemSize); -//Copies an item to a no-split ring buffer. Only call this function after calling prvCheckItemFitsDefault() +/* +Copies an item to a no-split ring buffer +Entry: + - Must have already guaranteed there is sufficient space for item by calling prvCheckItemFitsDefault() +Exit: + - New item copied into ring buffer + - pucAcquire and pucWrite updated. + - Dummy item added if necessary +*/ static void prvCopyItemNoSplit(Ringbuffer_t *pxRingbuffer, const uint8_t *pucItem, size_t xItemSize); -//Copies an item to a allow-split ring buffer. Only call this function after calling prvCheckItemFitsDefault() +/* +Copies an item to a allow-split ring buffer +Entry: + - Must have already guaranteed there is sufficient space for item by calling prvCheckItemFitsDefault() +Exit: + - New item copied into ring buffer + - pucAcquire and pucWrite updated + - Item may be split +*/ static void prvCopyItemAllowSplit(Ringbuffer_t *pxRingbuffer, const uint8_t *pucItem, size_t xItemSize); //Copies an item to a byte buffer. Only call this function after calling prvCheckItemFitsByteBuffer() static void prvCopyItemByteBuf(Ringbuffer_t *pxRingbuffer, const uint8_t *pucItem, size_t xItemSize); //Retrieve item from no-split/allow-split ring buffer. *pxIsSplit is set to pdTRUE if the retrieved item is split +/* +Entry: + - Must have already guaranteed that there is an item available for retrieval by calling prvCheckItemAvail() + - Guaranteed that pucREAD points to a valid item (i.e., not a dummy item) +Exit: + - Item is returned. Only first half returned if split + - pucREAD updated to point to next valid item to read, or equals to pucWrite if there are no more valid items to read + - pucREAD update must skip over dummy items +*/ static void *prvGetItemDefault(Ringbuffer_t *pxRingbuffer, BaseType_t *pxIsSplit, size_t xUnusedParam, @@ -164,7 +189,12 @@ static void *prvGetItemByteBuf(Ringbuffer_t *pxRingbuffer, size_t xMaxSize, size_t *pxItemSize); -//Return an item to a split/no-split ring buffer +/* +Return an item to a split/no-split ring buffer +Exit: + - Item is marked free rbITEM_FREE_FLAG + - pucFree is progressed as far as possible, skipping over already freed items or dummy items +*/ static void prvReturnItemDefault(Ringbuffer_t *pxRingbuffer, uint8_t *pucItem); //Return data to a byte buffer @@ -392,7 +422,7 @@ static void prvSendItemDoneNoSplit(Ringbuffer_t *pxRingbuffer, uint8_t* pucItem) //Redundancy check to ensure write pointer has not overshot buffer bounds configASSERT(pxRingbuffer->pucWrite <= pxRingbuffer->pucHead + pxRingbuffer->xSize); } - //Check if pucAcquire requires wrap around + //Check if pucWrite requires wrap around if ((pxRingbuffer->pucTail - pxRingbuffer->pucWrite) < rbHEADER_SIZE) { pxRingbuffer->pucWrite = pxRingbuffer->pucHead; } @@ -533,7 +563,7 @@ static void *prvGetItemDefault(Ringbuffer_t *pxRingbuffer, //Inclusive of pucTail for special case where item of zero length just fits at the end of the buffer configASSERT(pcReturn >= pxRingbuffer->pucHead && pcReturn <= pxRingbuffer->pucTail); } else { - //Exclusive of pucTali if length is larger than zero, pcReturn should never point to pucTail + //Exclusive of pucTail if length is larger than zero, pcReturn should never point to pucTail configASSERT(pcReturn >= pxRingbuffer->pucHead && pcReturn < pxRingbuffer->pucTail); } *pxItemSize = pxHeader->xItemLen; //Get length of item @@ -623,7 +653,7 @@ static void prvReturnItemDefault(Ringbuffer_t *pxRingbuffer, uint8_t *pucItem) //Redundancy check to ensure free pointer has not overshot buffer bounds configASSERT(pxRingbuffer->pucFree <= pxRingbuffer->pucHead + pxRingbuffer->xSize); } - //Check if pucRead requires wrap around + //Check if pucFree requires wrap around if ((pxRingbuffer->pucTail - pxRingbuffer->pucFree) < rbHEADER_SIZE) { pxRingbuffer->pucFree = pxRingbuffer->pucHead; } @@ -674,12 +704,15 @@ static size_t prvGetCurMaxSizeNoSplit(Ringbuffer_t *pxRingbuffer) //No-split ring buffer items need space for a header xFreeSize -= rbHEADER_SIZE; - //Limit free size to be within bounds - if (xFreeSize > pxRingbuffer->xMaxItemSize) { - xFreeSize = pxRingbuffer->xMaxItemSize; - } else if (xFreeSize < 0) { + + //Check for xFreeSize < 0 before checking xFreeSize > pxRingbuffer->xMaxItemSize + //to avoid incorrect comparison operation when xFreeSize is negative + if (xFreeSize < 0) { //Occurs when free space is less than header size xFreeSize = 0; + } else if (xFreeSize > pxRingbuffer->xMaxItemSize) { + //Limit free size to be within bounds + xFreeSize = pxRingbuffer->xMaxItemSize; } return xFreeSize; } @@ -704,11 +737,13 @@ static size_t prvGetCurMaxSizeAllowSplit(Ringbuffer_t *pxRingbuffer) (rbHEADER_SIZE * 2); } - //Limit free size to be within bounds - if (xFreeSize > pxRingbuffer->xMaxItemSize) { - xFreeSize = pxRingbuffer->xMaxItemSize; - } else if (xFreeSize < 0) { + //Check for xFreeSize < 0 before checking xFreeSize > pxRingbuffer->xMaxItemSize + //to avoid incorrect comparison operation when xFreeSize is negative + if (xFreeSize < 0) { xFreeSize = 0; + } else if (xFreeSize > pxRingbuffer->xMaxItemSize) { + //Limit free size to be within bounds + xFreeSize = pxRingbuffer->xMaxItemSize; } return xFreeSize; } @@ -1041,13 +1076,13 @@ BaseType_t xRingbufferSend(RingbufHandle_t xRingbuffer, */ } + if (xReturnSemaphore == pdTRUE) { + xSemaphoreGive(rbGET_TX_SEM_HANDLE(pxRingbuffer)); //Give back semaphore so other tasks can send + } if (xReturn == pdTRUE) { //Indicate item was successfully sent xSemaphoreGive(rbGET_RX_SEM_HANDLE(pxRingbuffer)); } - if (xReturnSemaphore == pdTRUE) { - xSemaphoreGive(rbGET_TX_SEM_HANDLE(pxRingbuffer)); //Give back semaphore so other tasks can send - } return xReturn; } @@ -1083,13 +1118,13 @@ BaseType_t xRingbufferSendFromISR(RingbufHandle_t xRingbuffer, } portEXIT_CRITICAL_ISR(&pxRingbuffer->mux); + if (xReturnSemaphore == pdTRUE) { + xSemaphoreGiveFromISR(rbGET_TX_SEM_HANDLE(pxRingbuffer), pxHigherPriorityTaskWoken); //Give back semaphore so other tasks can send + } if (xReturn == pdTRUE) { //Indicate item was successfully sent xSemaphoreGiveFromISR(rbGET_RX_SEM_HANDLE(pxRingbuffer), pxHigherPriorityTaskWoken); } - if (xReturnSemaphore == pdTRUE) { - xSemaphoreGiveFromISR(rbGET_TX_SEM_HANDLE(pxRingbuffer), pxHigherPriorityTaskWoken); //Give back semaphore so other tasks can send - } return xReturn; } diff --git a/components/esp_ringbuf/test/test_ringbuf.c b/components/esp_ringbuf/test/test_ringbuf.c index 77f4b5235a13..f84bcd885577 100644 --- a/components/esp_ringbuf/test/test_ringbuf.c +++ b/components/esp_ringbuf/test/test_ringbuf.c @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #include #include #include "freertos/FreeRTOS.h" @@ -17,7 +23,8 @@ #define NO_OF_RB_TYPES 3 #define ITEM_HDR_SIZE 8 #define SMALL_ITEM_SIZE 8 -#define LARGE_ITEM_SIZE (2 * SMALL_ITEM_SIZE) +#define MEDIUM_ITEM_SIZE ((3 * SMALL_ITEM_SIZE) >> 1) //12 bytes +#define LARGE_ITEM_SIZE (2 * SMALL_ITEM_SIZE) //16 bytes #define BUFFER_SIZE 160 //4Byte aligned size static const uint8_t small_item[SMALL_ITEM_SIZE] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; @@ -37,6 +44,17 @@ static void send_item_and_check(RingbufHandle_t handle, const uint8_t *item, si TEST_ASSERT_MESSAGE(ret == pdTRUE, "Failed to send item"); } +static void send_item_and_check_failure(RingbufHandle_t handle, const uint8_t *item, size_t item_size, TickType_t ticks_to_wait, bool in_isr) +{ + BaseType_t ret; + if (in_isr) { + ret = xRingbufferSendFromISR(handle, (void *)item, item_size, NULL); + } else { + ret = xRingbufferSend(handle, (void *)item, item_size, ticks_to_wait); + } + TEST_ASSERT_MESSAGE(ret == pdFALSE, "Sent an item to a full buffer"); +} + static void receive_check_and_return_item_no_split(RingbufHandle_t handle, const uint8_t *expected_data, size_t expected_size, TickType_t ticks_to_wait, bool in_isr) { //Receive item from no-split buffer @@ -73,7 +91,6 @@ static void receive_check_and_return_item_allow_split(RingbufHandle_t handle, co } else { ret = xRingbufferReceiveSplit(handle, (void**)&item1, (void **)&item2, &item_size1, &item_size2, ticks_to_wait); } - //= xRingbufferReceiveSplit(handle, (void**)&item1, (void **)&item2, &item_size1, &item_size2, ticks_to_wait); TEST_ASSERT_MESSAGE(ret == pdTRUE, "Failed to receive item"); TEST_ASSERT_MESSAGE(item1 != NULL, "Failed to receive item"); @@ -159,19 +176,37 @@ static void receive_check_and_return_item_byte_buffer(RingbufHandle_t handle, co } /* ----------------- Basic ring buffer behavior tests cases -------------------- - * The following test cases will test basic send, receive, and wrap around - * behavior of each type of ring buffer. Each test case will do the following - * 1) Send multiple items (nearly fill the buffer) - * 2) Receive and check the sent items (also prepares the buffer for a wrap around - * 3) Send a final item that causes a wrap around - * 4) Receive and check the wrapped item + * The following set of test cases will test basic send, receive, wrap around and buffer full + * behavior of each type of ring buffer. + * Test Case 1: + * 1) Send multiple items (nearly fill the buffer) + * 2) Receive and check the sent items (also prepares the buffer for a wrap around) + * 3) Send a final item that causes a wrap around + * 4) Receive and check the wrapped item + * + * Test Case 2: + * 1) Send multiple items (completely fill the buffer) + * 2) Send another item and verify that send failure occurs + * 3) Receive one item and verify that space is freed up in the buffer + * 4) Receive and check the remaining sent items + * + * Test Case 3: + * 1) Send multiple items (nearly fill the buffer) + * 2) Send another small sized item to fill the buffer without causing a wrap around (not needed in case of byte buffer) + * 2) Send another item and verify that send failure occurs + * 4) Receive and check the sent items */ -TEST_CASE("Test ring buffer No-Split", "[esp_ringbuf]") +TEST_CASE("TC#1: No-Split", "[esp_ringbuf]") { //Create buffer RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT); TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE/2 - ITEM_HDR_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect max item size received"); + //Calculate number of items to send. Aim to almost fill buffer to setup for wrap around int no_of_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + SMALL_ITEM_SIZE)) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE); @@ -179,11 +214,21 @@ TEST_CASE("Test ring buffer No-Split", "[esp_ringbuf]") for (int i = 0; i < no_of_items; i++) { send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); } + + //Verify items waiting matches with the number of items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting"); + //Test receiving items for (int i = 0; i < no_of_items; i++) { receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); } + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + //Write pointer should be near the end, test wrap around UBaseType_t write_pos_before, write_pos_after; vRingbufferGetInfo(buffer_handle, NULL, NULL, &write_pos_before, NULL, NULL); @@ -198,11 +243,112 @@ TEST_CASE("Test ring buffer No-Split", "[esp_ringbuf]") vRingbufferDelete(buffer_handle); } -TEST_CASE("Test ring buffer Allow-Split", "[esp_ringbuf]") +TEST_CASE("TC#2: No-Split", "[esp_ringbuf]") +{ + //Create buffer + RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT); + TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE/2 - ITEM_HDR_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect max item size received"); + + //Calculate number of items to send. Aim to fill the buffer + int no_of_items = (BUFFER_SIZE) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE); + + //Test sending items + for (int i = 0; i < no_of_items; i++) { + send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify items waiting matches with the number of items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting"); + + //At this point, the buffer should be full. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved"); + + //Send an item. The item should not be sent to a full buffer. + send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Receive one item + receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //At this point, the buffer should not be full any more + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) > 0, "Buffer should have free space"); + + //Test receiving remaining items + for (int i = 0; i < no_of_items - 1; i++) { + receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + + //Cleanup + vRingbufferDelete(buffer_handle); +} + +TEST_CASE("TC#3: No-Split", "[esp_ringbuf]") +{ + //Create buffer + RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT); + TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE/2 - ITEM_HDR_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == ((BUFFER_SIZE >> 1) - ITEM_HDR_SIZE), "Incorrect max item size received"); + + //Calculate number of medium items to send. Aim to almost fill the buffer + int no_of_medium_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE)) / (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE); + + //Test sending items + for (int i = 0; i < no_of_medium_items; i++) { + send_item_and_check(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify items waiting matches with the number of medium items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_medium_items, "Incorrect items waiting"); + + //Send one small sized item. This will ensure that the item fits at the end of the buffer without causing the write pointer to wrap around. + send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //The buffer should not have any free space as the number of bytes remaining should be < ITEM_HDR_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved"); + + //Send an item. The item should not be sent to a full buffer. + send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Test receiving medium items + for (int i = 0; i < no_of_medium_items; i++) { + receive_check_and_return_item_no_split(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Test receiving small item + receive_check_and_return_item_no_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + + //Cleanup + vRingbufferDelete(buffer_handle); +} + +TEST_CASE("TC#1: Allow-Split", "[esp_ringbuf]") { //Create buffer RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT); TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE - (ITEM_HDR_SIZE * 2). + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect max item size received"); + //Calculate number of items to send. Aim to almost fill buffer to setup for wrap around int no_of_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + SMALL_ITEM_SIZE)) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE); @@ -210,11 +356,21 @@ TEST_CASE("Test ring buffer Allow-Split", "[esp_ringbuf]") for (int i = 0; i < no_of_items; i++) { send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); } + + //Verify items waiting matches with the number of items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting"); + //Test receiving items for (int i = 0; i < no_of_items; i++) { receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); } + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + //Write pointer should be near the end, test wrap around UBaseType_t write_pos_before, write_pos_after; vRingbufferGetInfo(buffer_handle, NULL, NULL, &write_pos_before, NULL, NULL); @@ -229,11 +385,112 @@ TEST_CASE("Test ring buffer Allow-Split", "[esp_ringbuf]") vRingbufferDelete(buffer_handle); } -TEST_CASE("Test ring buffer Byte Buffer", "[esp_ringbuf]") +TEST_CASE("TC#2: Allow-Split", "[esp_ringbuf]") +{ + //Create buffer + RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT); + TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE - (ITEM_HDR_SIZE * 2). + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect max item size received"); + + //Calculate number of items to send. Aim to fill the buffer + int no_of_items = (BUFFER_SIZE) / (ITEM_HDR_SIZE + SMALL_ITEM_SIZE); + + //Test sending items + for (int i = 0; i < no_of_items; i++) { + send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify items waiting matches with the number of items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_items, "Incorrect items waiting"); + + //At this point, the buffer should be full. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved"); + + //Send an item. The item should not be sent to a full buffer. + send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Receive one item + receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //At this point, the buffer should not be full any more + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) > 0, "Buffer should have free space"); + + //Test receiving remaining items + for (int i = 0; i < no_of_items - 1; i++) { + receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + + //Cleanup + vRingbufferDelete(buffer_handle); +} + +TEST_CASE("TC#3: Allow-Split", "[esp_ringbuf]") +{ + //Create buffer + RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT); + TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE - (ITEM_HDR_SIZE * 2). + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == (BUFFER_SIZE - (ITEM_HDR_SIZE * 2)), "Incorrect max item size received"); + + //Calculate number of medium items to send. Aim to almost fill the buffer + int no_of_medium_items = (BUFFER_SIZE - (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE)) / (ITEM_HDR_SIZE + MEDIUM_ITEM_SIZE); + + //Test sending items + for (int i = 0; i < no_of_medium_items; i++) { + send_item_and_check(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify items waiting matches with the number of medium items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_medium_items, "Incorrect items waiting"); + + //Send one small sized item. This will ensure that the item fits at the end of the buffer without causing the write pointer to wrap around. + send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //The buffer should not have any free space as the number of bytes remaining should be < ITEM_HDR_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved"); + + //Send an item. The item should not be sent to a full buffer. + send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Test receiving medium items + for (int i = 0; i < no_of_medium_items; i++) { + receive_check_and_return_item_allow_split(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Test receiving small item + receive_check_and_return_item_allow_split(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + + //Cleanup + vRingbufferDelete(buffer_handle); +} + +TEST_CASE("TC#1: Byte buffer", "[esp_ringbuf]") { //Create buffer RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF); TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == BUFFER_SIZE, "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == BUFFER_SIZE, "Incorrect max item size received"); + //Calculate number of items to send. Aim to almost fill buffer to setup for wrap around int no_of_items = (BUFFER_SIZE - SMALL_ITEM_SIZE) / SMALL_ITEM_SIZE; @@ -241,11 +498,21 @@ TEST_CASE("Test ring buffer Byte Buffer", "[esp_ringbuf]") for (int i = 0; i < no_of_items; i++) { send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); } + + //Verify items waiting matches with the number of items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_items * SMALL_ITEM_SIZE, "Incorrect number of bytes waiting"); + //Test receiving items for (int i = 0; i < no_of_items; i++) { receive_check_and_return_item_byte_buffer(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); } + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect number of bytes waiting"); + //Write pointer should be near the end, test wrap around UBaseType_t write_pos_before, write_pos_after; vRingbufferGetInfo(buffer_handle, NULL, NULL, &write_pos_before, NULL, NULL); @@ -260,6 +527,96 @@ TEST_CASE("Test ring buffer Byte Buffer", "[esp_ringbuf]") vRingbufferDelete(buffer_handle); } +TEST_CASE("TC#2: Byte buffer", "[esp_ringbuf]") +{ + //Create buffer + RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF); + TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == BUFFER_SIZE, "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == BUFFER_SIZE, "Incorrect max item size received"); + + //Calculate number of items to send. Aim to fill the buffer + int no_of_items = BUFFER_SIZE / SMALL_ITEM_SIZE; + + //Test sending items + for (int i = 0; i < no_of_items; i++) { + send_item_and_check(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify items waiting matches with the number of items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_items * SMALL_ITEM_SIZE, "Incorrect number of bytes waiting"); + + //At this point, the buffer should be full. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == 0, "Buffer full not achieved"); + + //Send an item. The item should not be sent to a full buffer. + send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Receive one item + receive_check_and_return_item_byte_buffer(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //At this point, the buffer should not be full any more + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) > 0, "Buffer should have free space"); + + //Test receiving remaining items + for (int i = 0; i < no_of_items - 1; i++) { + receive_check_and_return_item_byte_buffer(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + + //Cleanup + vRingbufferDelete(buffer_handle); +} + +TEST_CASE("TC#3: Byte buffer", "[esp_ringbuf]") +{ + //Create buffer + RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF); + TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer"); + + //Check buffer free size and max item size upon buffer creation. Should be BUFFER_SIZE. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) == BUFFER_SIZE, "Incorrect buffer free size received"); + TEST_ASSERT_MESSAGE(xRingbufferGetMaxItemSize(buffer_handle) == BUFFER_SIZE, "Incorrect max item size received"); + + //Calculate number of medium items to send. Aim to almost fill the buffer + int no_of_medium_items = BUFFER_SIZE / MEDIUM_ITEM_SIZE; + + //Test sending items + for (int i = 0; i < no_of_medium_items; i++) { + send_item_and_check(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify items waiting matches with the number of medium items sent + UBaseType_t items_waiting; + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == no_of_medium_items * MEDIUM_ITEM_SIZE, "Incorrect number of bytes waiting"); + + //The buffer should not have any free space for one small item. + TEST_ASSERT_MESSAGE(xRingbufferGetCurFreeSize(buffer_handle) < SMALL_ITEM_SIZE, "Buffer full not achieved"); + + //Send an item. The item should not be sent to a full buffer. + send_item_and_check_failure(buffer_handle, small_item, SMALL_ITEM_SIZE, TIMEOUT_TICKS, false); + + //Test receiving medium items + for (int i = 0; i < no_of_medium_items; i++) { + receive_check_and_return_item_byte_buffer(buffer_handle, large_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS, false); + } + + //Verify that no items are waiting + vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting); + TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting"); + + //Cleanup + vRingbufferDelete(buffer_handle); +} + /* ----------------------- Ring buffer queue sets test ------------------------ * The following test case will test receiving from ring buffers that have been * added to a queue set. The test case will do the following... diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 667ab7f557f7..0f6c38afc2dd 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -25,6 +25,9 @@ rom_linker_script("libgcc") if(BOOTLOADER_BUILD) if(target STREQUAL "esp32") rom_linker_script("newlib-funcs") + if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) + rom_linker_script("spiflash") + endif() if(CONFIG_ESP32_REV_MIN_3) rom_linker_script("eco3") endif() @@ -53,13 +56,14 @@ else() # Regular app build # then all time functions from the ROM memory will not be linked. # Instead, those functions can be used from the toolchain by ESP-IDF. rom_linker_script("newlib-time") - endif() - # Include in newlib nano from ROM only if SPIRAM cache workaround is disabled - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") - endif() + # Include in newlib nano from ROM only if SPIRAM cache workaround is disabled + # and sizeof(time_t) == 4 + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + endif() endif() if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) @@ -75,10 +79,19 @@ else() # Regular app build rom_linker_script("newlib-data") rom_linker_script("spiflash") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined + # then all time functions from the ROM memory will not be linked. + # Instead, those functions can be used from the toolchain by ESP-IDF. + + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + + rom_linker_script("newlib-time") endif() + # descirptors used by ROM code target_sources(${COMPONENT_LIB} PRIVATE "esp32s2/usb_descriptors.c") @@ -95,11 +108,19 @@ else() # Regular app build rom_linker_script("newlib") rom_linker_script("version") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined + # then all time functions from the ROM memory will not be linked. + # Instead, those functions can be used from the toolchain by ESP-IDF. + + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + + rom_linker_script("newlib-time") endif() - if(CONFIG_ESP32C3_REV_MIN_3) + if(CONFIG_ESP32C3_REV_MIN_3 OR CONFIG_ESP32C3_REV_MIN_4) rom_linker_script("eco3") endif() endif() diff --git a/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld b/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld index d38e44527496..79d5c5be0d80 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld @@ -43,7 +43,6 @@ _getenv_r = 0x40001fbc; isalnum = 0x40000f04; isalpha = 0x40000f18; isascii = 0x4000c20c; -_isatty_r = 0x40000ea0; isblank = 0x40000f2c; iscntrl = 0x40000f50; isdigit = 0x40000f64; @@ -77,14 +76,11 @@ __sfmoreglue = 0x40001dc8; __sfp = 0x40001e90; __sfp_lock_acquire = 0x40001e08; __sfp_lock_release = 0x40001e14; -__sfvwrite_r = 0x4005893c; __sinit = 0x40001e38; __sinit_lock_acquire = 0x40001e20; __sinit_lock_release = 0x40001e2c; -__smakebuf_r = 0x40059108; srand = 0x40001004; __sread = 0x40001118; -__srefill_r = 0x400593d4; __sseek = 0x40001184; strcasecmp = 0x400011cc; strcasestr = 0x40001210; @@ -122,7 +118,6 @@ __submore = 0x40058f3c; __swbuf = 0x40058cb4; __swbuf_r = 0x40058bec; __swrite = 0x40001150; -__swsetup_r = 0x40058cc8; toascii = 0x4000c720; tolower = 0x40001868; toupper = 0x40001884; diff --git a/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld b/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld index f6b222eb10ce..50ec64882d7b 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld @@ -27,3 +27,12 @@ _timezone = 0x3ffae0a0; _tzname = 0x3ffae030; _daylight = 0x3ffae0a4; __month_lengths = 0x3ff9609c; + +/* These functions don't use time_t, but use other structures which include time_t. + * For example, 'struct stat' contains time_t. + */ +_isatty_r = 0x40000ea0; +__sfvwrite_r = 0x4005893c; +__smakebuf_r = 0x40059108; +__srefill_r = 0x400593d4; +__swsetup_r = 0x40058cc8; diff --git a/components/esp_rom/esp32c3/esp_rom_caps.h b/components/esp_rom/esp32c3/esp_rom_caps.h index 1a3c8cc58f8e..df212a64ec27 100644 --- a/components/esp_rom/esp32c3/esp_rom_caps.h +++ b/components/esp_rom/esp32c3/esp_rom_caps.h @@ -20,3 +20,4 @@ #define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM #define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking #define ESP_ROM_USB_SERIAL_DEVICE_NUM (3) // UART uses USB_SERIAL_JTAG port in ROM. +#define ESP_ROM_HAS_ERASE_0_REGION_BUG (1) // ROM has esp_flash_erase_region(size=0) bug diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 6ca50990e5d1..74bb30a1254c 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -260,7 +260,7 @@ PROVIDE( esp_flash_chip_driver_initialized = 0x400002fc ); PROVIDE( esp_flash_read_id = 0x40000300 ); PROVIDE( esp_flash_get_size = 0x40000304 ); PROVIDE( esp_flash_erase_chip = 0x40000308 ); -PROVIDE( esp_flash_erase_region = 0x4000030c ); +PROVIDE( rom_esp_flash_erase_region = 0x4000030c ); PROVIDE( esp_flash_get_chip_write_protect = 0x40000310 ); PROVIDE( esp_flash_set_chip_write_protect = 0x40000314 ); PROVIDE( esp_flash_get_protectable_regions = 0x40000318 ); @@ -482,7 +482,8 @@ ets_efuse_get_flash_delay_us = 0x40000714; ets_efuse_get_mac = 0x40000718; ets_efuse_get_spiconfig = 0x4000071c; ets_efuse_usb_print_is_disabled = 0x40000720; -ets_efuse_get_uart_print_channel = 0x40000724; +/*ets_efuse_get_uart_print_channel = 0x40000724;*/ +ets_efuse_usb_serial_jtag_print_is_disabled = 0x40000724; ets_efuse_get_uart_print_control = 0x40000728; ets_efuse_get_wp_pad = 0x4000072c; ets_efuse_legacy_spi_boot_mode_disabled = 0x40000730; @@ -1551,7 +1552,7 @@ pm_parse_beacon = 0x40001688; pm_process_tim = 0x4000168c; pm_rx_beacon_process = 0x40001690; pm_rx_data_process = 0x40001694; -pm_sleep = 0x40001698; +/*pm_sleep = 0x40001698;*/ pm_sleep_for = 0x4000169c; pm_tbtt_process = 0x400016a0; ppAMPDU2Normal = 0x400016a4; @@ -1639,7 +1640,7 @@ wDev_ProcessRxSucData = 0x400017f4; wdevProcessRxSucDataAll = 0x400017f8; wdev_csi_len_align = 0x400017fc; ppDequeueTxDone_Locked = 0x40001800; -pm_tx_data_done_process = 0x40001808; +/*pm_tx_data_done_process = 0x40001808;*/ config_is_cache_tx_buf_enabled = 0x4000180c; ppMapWaitTxq = 0x40001810; ppProcessWaitingQueue = 0x40001814; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld new file mode 100644 index 000000000000..27734ced890a --- /dev/null +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* These are the newlib functions and the .bss/.data symbols which are related to 'time_t' + or other structures which include 'time_t' (like 'struct stat'). + These ROM functions were compiled with sizeof(time_t) == 4. + When compiling with sizeof(time_t) == 8, these functions should be excluded from the build. + */ + +_isatty_r = 0x40000380; +PROVIDE( __smakebuf_r = 0x4000046c ); +PROVIDE( __swhatbuf_r = 0x40000470 ); +PROVIDE( __swsetup_r = 0x4000047c ); diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld index c086e8151caa..257a919f3e35 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld @@ -25,7 +25,6 @@ strncmp = 0x40000370; strlen = 0x40000374; strstr = 0x40000378; bzero = 0x4000037c; -_isatty_r = 0x40000380; sbrk = 0x40000384; isalnum = 0x40000388; isalpha = 0x4000038c; @@ -84,11 +83,8 @@ PROVIDE( fflush = 0x4000045c ); PROVIDE( _fflush_r = 0x40000460 ); PROVIDE( _fwalk = 0x40000464 ); PROVIDE( _fwalk_reent = 0x40000468 ); -PROVIDE( __smakebuf_r = 0x4000046c ); -PROVIDE( __swhatbuf_r = 0x40000470 ); PROVIDE( __swbuf_r = 0x40000474 ); __swbuf = 0x40000478; -PROVIDE( __swsetup_r = 0x4000047c ); /* Data (.data, .bss, .rodata) */ syscall_table_ptr = 0x3fcdffe0; _global_impure_ptr = 0x3fcdffdc; diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld index fc976bbbafee..899997df46df 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld @@ -29,7 +29,6 @@ _fwalk_reent = 0x4001bd24; isalnum = 0x400078d8; isalpha = 0x400078e8; isascii = 0x4001aaec; -_isatty_r = 0x400078a0; isblank = 0x400078f8; iscntrl = 0x40007918; isdigit = 0x40007930; @@ -66,11 +65,9 @@ __sfmoreglue = 0x4001a4c8; __sfp = 0x4001a590; __sfp_lock_acquire = 0x4001a508; __sfp_lock_release = 0x4001a514; -__sfvwrite_r = 0x40001310; __sinit = 0x4001a538; __sinit_lock_acquire = 0x4001a520; __sinit_lock_release = 0x4001a52c; -__smakebuf_r = 0x40001954; srand = 0x40007a24; __sread = 0x4001a660; __sseek = 0x4001a6cc; @@ -104,9 +101,7 @@ strtok_r = 0x4001af7c; strupr = 0x40008084; __swbuf = 0x4000167c; __swbuf_r = 0x400015bc; -__swhatbuf_r = 0x400018f8; __swrite = 0x4001a698; -__swsetup_r = 0x40001690; toascii = 0x4001af90; tolower = 0x40008158; toupper = 0x40008174; diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld new file mode 100644 index 000000000000..1e705c698b57 --- /dev/null +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* These are the newlib functions and the .bss/.data symbols which are related to 'time_t' + or other structures which include 'time_t' (like 'struct stat'). + These ROM functions were compiled with sizeof(time_t) == 4. + When compiling with sizeof(time_t) == 8, these functions should be excluded from the build. + */ + +__swsetup_r = 0x40001690; +__smakebuf_r = 0x40001954; +__swhatbuf_r = 0x400018f8; +__sfvwrite_r = 0x40001310; +_isatty_r = 0x400078a0; diff --git a/components/esp_rom/esp32s3/esp_rom_caps.h b/components/esp_rom/esp32s3/esp_rom_caps.h index 7a235e4e98b9..e471c0f1e9b2 100644 --- a/components/esp_rom/esp32s3/esp_rom_caps.h +++ b/components/esp_rom/esp32s3/esp_rom_caps.h @@ -20,3 +20,4 @@ #define ESP_ROM_SUPPORT_MULTIPLE_UART (1) // ROM has multiple UARTs available for logging #define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM #define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking +#define ESP_ROM_HAS_ERASE_0_REGION_BUG (1) // ROM has esp_flash_erase_region(size=0) bug diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 6fe65f54fba3..15eb10216b52 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -470,7 +470,7 @@ PROVIDE ( em_base_reg_lut = 0x3ff08258 ); PROVIDE ( esp_crc8 = 0x40047854 ); PROVIDE ( esp_flash_chip_driver_initialized = 0x4004e88c ); PROVIDE ( esp_flash_erase_chip = 0x4004e998 ); -PROVIDE ( esp_flash_erase_region = 0x4004ea00 ); +PROVIDE ( rom_esp_flash_erase_region = 0x4004ea00 ); PROVIDE ( esp_flash_get_chip_write_protect = 0x4004eb70 ); PROVIDE ( esp_flash_get_io_mode = 0x4004efa4 ); PROVIDE ( esp_flash_get_protectable_regions = 0x4004ec00 ); @@ -576,7 +576,8 @@ PROVIDE ( ets_efuse_get_mac = 0x40043d24 ); PROVIDE ( ets_efuse_get_opiconfig = 0x40043ac8 ); PROVIDE ( ets_efuse_get_read_register_address = 0x4004374c ); PROVIDE ( ets_efuse_get_spiconfig = 0x40043a6c ); -PROVIDE ( ets_efuse_get_uart_print_channel = 0x40043bb4 ); +/*PROVIDE ( ets_efuse_get_uart_print_channel = 0x40043bb4 );*/ +PROVIDE ( ets_efuse_usb_serial_jtag_print_is_disabled = 0x40043bb4 ); PROVIDE ( ets_efuse_get_uart_print_control = 0x40043ba4 ); PROVIDE ( ets_efuse_get_wp_pad = 0x40043a10 ); PROVIDE ( ets_efuse_jtag_disabled = 0x40043b5c ); diff --git a/components/esp_rom/include/esp32c3/rom/efuse.h b/components/esp_rom/include/esp32c3/rom/efuse.h index 9da1525f969b..d1412c461107 100644 --- a/components/esp_rom/include/esp32c3/rom/efuse.h +++ b/components/esp_rom/include/esp32c3/rom/efuse.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ROM_EFUSE_H_ #define _ROM_EFUSE_H_ @@ -236,13 +228,13 @@ bool ets_efuse_legacy_spi_boot_mode_disabled(void); uint32_t ets_efuse_get_uart_print_control(void); /** - * @brief Read which channel will used by ROM to print + * @brief Read if USB-Serial-JTAG print during rom boot is disabled from Efuse * * @return - * - 0 for UART0. - * - 1 for UART1. + * - 1 for efuse disable USB-Serial-JTAG print during rom boot. + * - 0 for efuse doesn't disable USB-Serial-JTAG print during rom boot. */ -uint32_t ets_efuse_get_uart_print_channel(void); +uint32_t ets_efuse_usb_serial_jtag_print_is_disabled(void); /** * @brief Read if usb download mode disabled from Efuse diff --git a/components/esp_rom/include/esp32c3/rom/rtc.h b/components/esp_rom/include/esp32c3/rom/rtc.h index 8c9be5ea2661..85241bf83f39 100644 --- a/components/esp_rom/include/esp32c3/rom/rtc.h +++ b/components/esp_rom/include/esp32c3/rom/rtc.h @@ -82,8 +82,7 @@ typedef enum { NO_MEAN = 0, POWERON_RESET = 1, /**<1, Vbat power on reset*/ RTC_SW_SYS_RESET = 3, /**<3, Software reset digital core*/ - DEEPSLEEP_RESET = 5, /**<3, Deep Sleep reset digital core*/ - SDIO_RESET = 6, /**<6, Reset by SLC module, reset digital core*/ + DEEPSLEEP_RESET = 5, /**<5, Deep Sleep reset digital core*/ TG0WDT_SYS_RESET = 7, /**<7, Timer Group0 Watch dog reset digital core*/ TG1WDT_SYS_RESET = 8, /**<8, Timer Group1 Watch dog reset digital core*/ RTCWDT_SYS_RESET = 9, /**<9, RTC Watch dog Reset digital core*/ @@ -95,6 +94,11 @@ typedef enum { RTCWDT_RTC_RESET = 16, /**<16, RTC Watch dog reset digital core and rtc module*/ TG1WDT_CPU_RESET = 17, /**<17, Time Group1 reset CPU*/ SUPER_WDT_RESET = 18, /**<18, super watchdog reset digital core and rtc module*/ + GLITCH_RTC_RESET = 19, /**<19, glitch reset digital core and rtc module*/ + EFUSE_RESET = 20, /**<20, efuse reset digital core*/ + USB_UART_CHIP_RESET = 21, /**<21, usb uart reset digital core */ + USB_JTAG_CHIP_RESET = 22, /**<22, usb jtag reset digital core */ + POWER_GLITCH_RESET = 23, /**<23, power glitch reset digital core and rtc module*/ } RESET_REASON; typedef enum { diff --git a/components/esp_rom/include/esp32s2/rom/rtc.h b/components/esp_rom/include/esp32s2/rom/rtc.h index 535dc64a9a23..dcbce7f7a0a4 100644 --- a/components/esp_rom/include/esp32s2/rom/rtc.h +++ b/components/esp_rom/include/esp32s2/rom/rtc.h @@ -94,6 +94,7 @@ typedef enum { TG1WDT_CPU_RESET = 17, /**<17, Time Group1 reset CPU*/ SUPER_WDT_RESET = 18, /**<18, super watchdog reset digital core and rtc module*/ GLITCH_RTC_RESET = 19, /**<19, glitch reset digital core and rtc module*/ + EFUSE_RESET = 20, /**<20, efuse reset digital core*/ } RESET_REASON; typedef enum { diff --git a/components/esp_rom/include/esp32s3/rom/efuse.h b/components/esp_rom/include/esp32s3/rom/efuse.h index cbe38e6a55ed..3d347f483307 100644 --- a/components/esp_rom/include/esp32s3/rom/efuse.h +++ b/components/esp_rom/include/esp32s3/rom/efuse.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -237,13 +229,13 @@ bool ets_efuse_legacy_spi_boot_mode_disabled(void); uint32_t ets_efuse_get_uart_print_control(void); /** - * @brief Read which channel will used by ROM to print + * @brief Read if USB-Serial-JTAG print during rom boot is disabled from Efuse * * @return - * - 0 for UART0. - * - 1 for UART1. + * - 1 for efuse disable USB-Serial-JTAG print during rom boot. + * - 0 for efuse doesn't disable USB-Serial-JTAG print during rom boot. */ -uint32_t ets_efuse_get_uart_print_channel(void); +uint32_t ets_efuse_usb_serial_jtag_print_is_disabled(void); /** * @brief Read if usb download mode disabled from Efuse diff --git a/components/esp_rom/include/esp32s3/rom/rtc.h b/components/esp_rom/include/esp32s3/rom/rtc.h index a5a1ecb6a120..34b0affe10bb 100644 --- a/components/esp_rom/include/esp32s3/rom/rtc.h +++ b/components/esp_rom/include/esp32s3/rom/rtc.h @@ -90,6 +90,9 @@ typedef enum { SUPER_WDT_RESET = 18, /**<18, super watchdog reset digital core and rtc module*/ GLITCH_RTC_RESET = 19, /**<19, glitch reset digital core and rtc module*/ EFUSE_RESET = 20, /**<20, efuse reset digital core*/ + USB_UART_CHIP_RESET = 21, /**<21, usb uart reset digital core */ + USB_JTAG_CHIP_RESET = 22, /**<22, usb jtag reset digital core */ + POWER_GLITCH_RESET = 23, /**<23, power glitch reset digital core and rtc module*/ } RESET_REASON; typedef enum { diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index b7f681e45cc0..6521ab2a181c 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -117,6 +117,21 @@ menu "ESP System Settings" pull-up, you do not need to select this option, otherwise, you should enable this option. + menu "RTC Clock Config" + # This is used for configure the RTC clock. + config RTC_CLOCK_BBPLL_POWER_ON_WITH_USB + bool "Keep BBPLL clock always work" + depends on ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + default y + help + When the chip goes sleep or software reset, the clock source would change to XTAL + and switch off the BBPLL clock for saving power. However, this might make the + USB_SERIAL_JTAG down which depends on BBPLL as its unique clock source. + Therefore, this is used for keeping bbpll clock always on when USB_SERIAL_JTAG PORT is using. + If you want to use USB_SERIAL_JTAG under sw_reset case or sleep-wakeup case, you shoule select + this option. But be aware that this might increase the power consumption. + endmenu + menu "Memory protection" config ESP_SYSTEM_MEMPROT_FEATURE diff --git a/components/esp_system/intr_alloc.c b/components/esp_system/intr_alloc.c index 7e7de6dbe9e5..b18f97e24503 100644 --- a/components/esp_system/intr_alloc.c +++ b/components/esp_system/intr_alloc.c @@ -107,10 +107,6 @@ static uint32_t non_iram_int_mask[SOC_CPU_CORES_NUM]; static uint32_t non_iram_int_disabled[SOC_CPU_CORES_NUM]; static bool non_iram_int_disabled_flag[SOC_CPU_CORES_NUM]; -#if CONFIG_SYSVIEW_ENABLE -extern uint32_t port_switch_flag[]; -#endif - static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; //Inserts an item into vector_desc list so that the list is sorted @@ -415,16 +411,12 @@ static void IRAM_ATTR shared_intr_isr(void *arg) while(sh_vec) { if (!sh_vec->disabled) { if ((sh_vec->statusreg == NULL) || (*sh_vec->statusreg & sh_vec->statusmask)) { -#if CONFIG_SYSVIEW_ENABLE traceISR_ENTER(sh_vec->source+ETS_INTERNAL_INTR_SOURCE_OFF); -#endif sh_vec->isr(sh_vec->arg); -#if CONFIG_SYSVIEW_ENABLE // check if we will return to scheduler or to interrupted task after ISR - if (!port_switch_flag[cpu_hal_get_core_id()]) { + if (!os_task_switch_is_pended(cpu_hal_get_core_id())) { traceISR_EXIT(); } -#endif } } sh_vec=sh_vec->next; @@ -432,18 +424,18 @@ static void IRAM_ATTR shared_intr_isr(void *arg) portEXIT_CRITICAL_ISR(&spinlock); } -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE //Common non-shared isr handler wrapper. static void IRAM_ATTR non_shared_intr_isr(void *arg) { non_shared_isr_arg_t *ns_isr_arg=(non_shared_isr_arg_t*)arg; portENTER_CRITICAL_ISR(&spinlock); traceISR_ENTER(ns_isr_arg->source+ETS_INTERNAL_INTR_SOURCE_OFF); - // FIXME: can we call ISR and check port_switch_flag after releasing spinlock? - // when CONFIG_SYSVIEW_ENABLE = 0 ISRs for non-shared IRQs are called without spinlock + // FIXME: can we call ISR and check os_task_switch_is_pended() after releasing spinlock? + // when CONFIG_APPTRACE_SV_ENABLE = 0 ISRs for non-shared IRQs are called without spinlock ns_isr_arg->isr(ns_isr_arg->isr_arg); // check if we will return to scheduler or to interrupted task after ISR - if (!port_switch_flag[cpu_hal_get_core_id()]) { + if (!os_task_switch_is_pended(cpu_hal_get_core_id())) { traceISR_EXIT(); } portEXIT_CRITICAL_ISR(&spinlock); @@ -539,7 +531,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre //Mark as unusable for other interrupt sources. This is ours now! vd->flags=VECDESC_FL_NONSHARED; if (handler) { -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE non_shared_isr_arg_t *ns_isr_arg=malloc(sizeof(non_shared_isr_arg_t)); if (!ns_isr_arg) { portEXIT_CRITICAL(&spinlock); @@ -688,7 +680,7 @@ esp_err_t esp_intr_free(intr_handle_t handle) if ((handle->vector_desc->flags&VECDESC_FL_NONSHARED) || free_shared_vector) { ESP_EARLY_LOGV(TAG, "esp_intr_free: Disabling int, killing handler"); -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE if (!free_shared_vector) { void *isr_arg = interrupt_controller_hal_get_int_handler_arg(handle->vector_desc->intno); if (isr_arg) { diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index e150f36307e8..92d3e2778a53 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -42,7 +42,7 @@ #if CONFIG_APPTRACE_ENABLE #include "esp_app_trace.h" -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE #include "SEGGER_RTT.h" #endif @@ -280,8 +280,8 @@ void esp_panic_handler(panic_info_t *info) panic_print_str(" and returning...\r\n"); disable_all_wdts(); #if CONFIG_APPTRACE_ENABLE -#if CONFIG_SYSVIEW_ENABLE - SEGGER_RTT_ESP32_FlushNoLock(CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); +#if CONFIG_APPTRACE_SV_ENABLE + SEGGER_RTT_ESP_FlushNoLock(CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); @@ -320,8 +320,8 @@ void esp_panic_handler(panic_info_t *info) #if CONFIG_APPTRACE_ENABLE disable_all_wdts(); -#if CONFIG_SYSVIEW_ENABLE - SEGGER_RTT_ESP32_FlushNoLock(CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); +#if CONFIG_APPTRACE_SV_ENABLE + SEGGER_RTT_ESP_FlushNoLock(CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); @@ -393,8 +393,8 @@ void IRAM_ATTR __attribute__((noreturn)) panic_abort(const char *details) s_panic_abort_details = (char *) details; #if CONFIG_APPTRACE_ENABLE -#if CONFIG_SYSVIEW_ENABLE - SEGGER_RTT_ESP32_FlushNoLock(CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); +#if CONFIG_APPTRACE_SV_ENABLE + SEGGER_RTT_ESP_FlushNoLock(CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 16cc30c9fa09..f34e6d68f340 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -23,7 +23,7 @@ #include "esp_system.h" #include "esp_rom_uart.h" - +#include "esp_efuse.h" #include "esp_clk_internal.h" #include "esp_rom_efuse.h" #include "esp_rom_sys.h" @@ -259,6 +259,13 @@ void IRAM_ATTR call_start_cpu0(void) #endif #ifdef __riscv + if (cpu_hal_is_debugger_attached()) { + /* Let debugger some time to detect that target started, halt it, enable ebreaks and resume. + 500ms should be enough. */ + for (uint32_t ms_num = 0; ms_num < 2; ms_num++) { + esp_rom_delay_us(100000); + } + } // Configure the global pointer register // (This should be the first thing IDF app does, as any other piece of code could be // relaxed by the linker to access something relative to __global_pointer$) @@ -333,6 +340,10 @@ void IRAM_ATTR call_start_cpu0(void) Cache_Resume_DCache(0); #endif // CONFIG_IDF_TARGET_ESP32S3 + if (esp_efuse_check_errors() != ESP_OK) { + esp_restart(); + } + #if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 /* Configure the Cache MMU size for instruction and rodata in flash. */ extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size); diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index d3b63ef5e73b..2cad1cc9fc5f 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -77,7 +77,11 @@ static const char *TAG = "clk"; rtc_config_t cfg = RTC_CONFIG_DEFAULT(); RESET_REASON rst_reas; rst_reas = rtc_get_reset_reason(0); - if (rst_reas == POWERON_RESET) { + if (rst_reas == POWERON_RESET +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + || rst_reas == EFUSE_RESET +#endif + ) { cfg.cali_ocode = 1; } rtc_init(cfg); diff --git a/components/esp_system/port/soc/esp32c3/reset_reason.c b/components/esp_system/port/soc/esp32c3/reset_reason.c index 98e93d593464..e962ed38b26a 100644 --- a/components/esp_system/port/soc/esp32c3/reset_reason.c +++ b/components/esp_system/port/soc/esp32c3/reset_reason.c @@ -25,6 +25,9 @@ static esp_reset_reason_t get_reset_reason(RESET_REASON rtc_reset_reason, esp_re { switch (rtc_reset_reason) { case POWERON_RESET: +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + case EFUSE_RESET: +#endif return ESP_RST_POWERON; case RTC_SW_CPU_RESET: diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index d39dc0d03af4..72075313e370 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -27,6 +27,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "soc/soc_caps.h" +#include "regi2c_ctrl.h" #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" #include "bootloader_common.h" @@ -138,7 +139,7 @@ typedef struct { uint64_t sleep_duration; uint32_t wakeup_triggers : 15; uint32_t ext1_trigger_mode : 1; - uint32_t ext1_rtc_gpio_mask : 18; + uint32_t ext1_rtc_gpio_mask : 22; //22 is the maximum RTCIO number in all chips uint32_t ext0_trigger_level : 1; uint32_t ext0_rtc_gpio_num : 5; uint32_t gpio_wakeup_mask : 6; @@ -153,6 +154,8 @@ typedef struct { #endif } sleep_config_t; +_Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size"); + static sleep_config_t s_config = { .pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, @@ -499,16 +502,27 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) } #endif -#ifdef CONFIG_IDF_TARGET_ESP32 +#if CONFIG_ULP_COPROC_ENABLED // Enable ULP wakeup if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { +#ifdef CONFIG_IDF_TARGET_ESP32 rtc_hal_ulp_wakeup_enable(); +#else + rtc_hal_ulp_int_clear(); +#endif } +#endif + +#ifdef CONFIG_IDF_TARGET_ESP32 #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL gpio_sleep_mode_config_apply(); #endif #endif +#if REGI2C_ANA_CALI_PD_WORKAROUND + regi2c_analog_cali_reg_read(); +#endif + #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (deep_sleep) { if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) { @@ -596,6 +610,10 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) #if CONFIG_MAC_BB_PD mac_bb_power_up_cb_execute(); #endif +#if REGI2C_ANA_CALI_PD_WORKAROUND + regi2c_analog_cali_reg_write(); +#endif + // re-enable UART output resume_uarts(); @@ -699,7 +717,7 @@ esp_err_t esp_light_sleep_start(void) s_config.rtc_ticks_at_sleep_start = rtc_time_get(); uint32_t ccount_at_sleep_start = cpu_ll_get_cycle_count(); - uint64_t frc_time_at_start = esp_system_get_time(); + uint64_t frc_time_at_start = esp_timer_get_time(); uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); DPORT_STALL_OTHER_CPU_START(); @@ -802,14 +820,14 @@ esp_err_t esp_light_sleep_start(void) // FRC1 has been clock gated for the duration of the sleep, correct for that. #ifdef CONFIG_IDF_TARGET_ESP32C3 /** - * On esp32c3, rtc_time_get() is non-blocking, esp_system_get_time() is + * On esp32c3, rtc_time_get() is non-blocking, esp_timer_get_time() is * blocking, and the measurement data shows that this order is better. */ - uint64_t frc_time_at_end = esp_system_get_time(); + uint64_t frc_time_at_end = esp_timer_get_time(); uint64_t rtc_ticks_at_end = rtc_time_get(); #else uint64_t rtc_ticks_at_end = rtc_time_get(); - uint64_t frc_time_at_end = esp_system_get_time(); + uint64_t frc_time_at_end = esp_timer_get_time(); #endif uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period); @@ -1269,10 +1287,14 @@ static uint32_t get_power_down_flags(void) #if SOC_RTC_SLOW_MEM_SUPPORTED && SOC_ULP_SUPPORTED // Labels are defined in the linker script extern int _rtc_slow_length; + /** + * Compiler considers "(size_t) &_rtc_slow_length > 0" to always be true. + * So use a volatile variable to prevent compiler from doing this optimization. + */ + volatile size_t rtc_slow_mem_used = (size_t)&_rtc_slow_length; if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) && - ((size_t) &_rtc_slow_length > 0 || - (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) { + (rtc_slow_mem_used > 0 || (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) { s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON; } #endif diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 2bc73478a099..7a66a3fc9510 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -53,9 +53,7 @@ #include "esp_pm.h" #include "esp_private/pm_impl.h" #include "esp_pthread.h" -#include "esp_private/usb_console.h" -#include "esp_vfs_cdcacm.h" -#include "esp_vfs_usb_serial_jtag.h" +#include "esp_vfs_console.h" #include "esp_rom_sys.h" @@ -86,9 +84,6 @@ #error "System has been configured to run on multiple cores, but target SoC only has a single core." #endif -#define STRINGIFY(s) STRINGIFY2(s) -#define STRINGIFY2(s) #s - uint64_t g_startup_time = 0; #if SOC_APB_BACKUP_DMA @@ -280,23 +275,14 @@ static void do_core_init(void) esp_timer_early_init(); esp_newlib_time_init(); -#ifdef CONFIG_VFS_SUPPORT_IO -#ifdef CONFIG_ESP_CONSOLE_UART - esp_vfs_dev_uart_register(); - const char *default_stdio_dev = "/dev/uart/" STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM); -#endif // CONFIG_ESP_CONSOLE_UART -#ifdef CONFIG_ESP_CONSOLE_USB_CDC - ESP_ERROR_CHECK(esp_usb_console_init()); - ESP_ERROR_CHECK(esp_vfs_dev_cdcacm_register()); - const char *default_stdio_dev = "/dev/cdcacm"; -#endif // CONFIG_ESP_CONSOLE_USB_CDC -#ifdef CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG - ESP_ERROR_CHECK(esp_vfs_dev_usb_serial_jtag_register()); - const char *default_stdio_dev = "/dev/usbserjtag"; -#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG -#endif // CONFIG_VFS_SUPPORT_IO +#if CONFIG_VFS_SUPPORT_IO + // VFS console register. + esp_err_t vfs_err = esp_vfs_console_register(); + assert(vfs_err == ESP_OK && "Failed to register vfs console"); +#endif #if defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE) + const static char *default_stdio_dev = "/dev/console/"; esp_reent_init(_GLOBAL_REENT); _GLOBAL_REENT->_stdin = fopen(default_stdio_dev, "r"); _GLOBAL_REENT->_stdout = fopen(default_stdio_dev, "w"); @@ -321,19 +307,6 @@ static void do_core_init(void) esp_efuse_disable_basic_rom_console(); #endif - // [refactor-todo] move this to secondary init -#if CONFIG_APPTRACE_ENABLE - err = esp_apptrace_init(); - assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!"); -#endif -#if CONFIG_SYSVIEW_ENABLE - SEGGER_SYSVIEW_Conf(); -#endif - -#if CONFIG_ESP_DEBUG_STUBS_ENABLE - esp_dbg_stubs_init(); -#endif - err = esp_pthread_init(); assert(err == ESP_OK && "Failed to init pthread module!"); @@ -450,6 +423,18 @@ IRAM_ATTR ESP_SYSTEM_INIT_FN(init_components0, BIT(0)) esp_sleep_enable_gpio_switch(true); #endif +#if CONFIG_APPTRACE_ENABLE + esp_err_t err = esp_apptrace_init(); + assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!"); +#endif +#if CONFIG_APPTRACE_SV_ENABLE + SEGGER_SYSVIEW_Conf(); +#endif + +#if CONFIG_ESP_DEBUG_STUBS_ENABLE + esp_dbg_stubs_init(); +#endif + #if defined(CONFIG_PM_ENABLE) esp_pm_impl_init(); #endif diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index 5ae2b0b99946..791d906cc893 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -24,45 +24,33 @@ if(CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN) endif() if(CONFIG_ESP32_MULTIPLE_PHY_DATA_BIN_EMBEDDED) - idf_component_register(SRCS "src/coexist.c" - "src/lib_printf.c" - "src/mesh_event.c" - "src/phy_init.c" - "src/smartconfig.c" - "src/smartconfig_ack.c" - "src/wifi_init.c" - "src/wifi_default.c" - "src/wifi_netif.c" - "${idf_target}/esp_adapter.c" - INCLUDE_DIRS "include" "${idf_target}/include" - PRIV_REQUIRES wpa_supplicant nvs_flash esp_netif driver ${extra_priv_requires} - REQUIRES esp_event - PRIV_REQUIRES esp_timer esp_pm wpa_supplicant nvs_flash esp_netif ${extra_priv_requires} - LDFRAGMENTS "${ldfragments}" - EMBED_FILES "${build_dir}/phy_multiple_init_data.bin" - ) -else() - idf_component_register(SRCS "src/coexist.c" - "src/lib_printf.c" - "src/mesh_event.c" - "src/phy_init.c" - "src/smartconfig.c" - "src/smartconfig_ack.c" - "src/wifi_init.c" - "src/wifi_default.c" - "src/wifi_netif.c" - "${idf_target}/esp_adapter.c" - INCLUDE_DIRS "include" "${idf_target}/include" - PRIV_REQUIRES wpa_supplicant nvs_flash esp_netif driver ${extra_priv_requires} - REQUIRES esp_event - PRIV_REQUIRES esp_timer esp_pm wpa_supplicant nvs_flash esp_netif ${extra_priv_requires} - LDFRAGMENTS "${ldfragments}" - ) + set(embed_files "${build_dir}/phy_multiple_init_data.bin") endif() +idf_component_register(SRCS "src/coexist.c" + "src/lib_printf.c" + "src/mesh_event.c" + "src/phy_init.c" + "src/smartconfig.c" + "src/smartconfig_ack.c" + "src/wifi_init.c" + "src/wifi_default.c" + "src/wifi_netif.c" + "${idf_target}/esp_adapter.c" + "src/phy_override.c" + INCLUDE_DIRS "include" "${idf_target}/include" + PRIV_REQUIRES wpa_supplicant nvs_flash esp_netif driver esp_timer esp_pm ${extra_priv_requires} + REQUIRES esp_event + LDFRAGMENTS "${ldfragments}" + EMBED_FILES ${embed_files} + ) + set(target_name "${idf_target}") target_link_libraries(${COMPONENT_LIB} PUBLIC "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib/${target_name}") +# Override functions in PHY lib with the functions in 'phy_override.c' +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u include_esp_phy_override") + if(link_binary_libs) set(phy phy) set(blobs coexist core espnow mesh net80211 pp smartconfig wapi ${phy}) diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index bc73ea8168c5..e32158072a97 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -415,10 +415,11 @@ menu "PHY" config ESP_PHY_ENABLE_USB bool "Enable USB when phy init" - depends on ESP_CONSOLE_USB_SERIAL_JTAG - default y + depends on USB_OTG_SUPPORTED || ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 + default n help - When using USB Serial/JTAG controller, PHY should enable USB, otherwise log will - not be displayed. But working with USB, the RF performance may be affected. + When using USB Serial/JTAG/OTG/CDC, PHY should enable USB, otherwise USB module + can not work properly. Notice: Enabling this configuration option will slightly impact wifi performance. endmenu # PHY diff --git a/components/esp_wifi/esp32/include/phy_init_data.h b/components/esp_wifi/esp32/include/phy_init_data.h index 6c725fa41517..3d633a9084ce 100644 --- a/components/esp_wifi/esp32/include/phy_init_data.h +++ b/components/esp_wifi/esp32/include/phy_init_data.h @@ -83,7 +83,7 @@ static const esp_phy_init_data_t phy_init_data= { { 0x18, 0x18, 0x18, - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 84), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 78), LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 72), LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 66), LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 60), diff --git a/components/esp_wifi/esp32c3/include/phy_init_data.h b/components/esp_wifi/esp32c3/include/phy_init_data.h index bc5d1edd2a80..6e5d089f1bfe 100644 --- a/components/esp_wifi/esp32c3/include/phy_init_data.h +++ b/components/esp_wifi/esp32c3/include/phy_init_data.h @@ -28,8 +28,8 @@ extern "C" { // define the lowest tx power as LOWEST_PHY_TX_POWER #define PHY_TX_POWER_LOWEST LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 52) -#define PHY_TX_POWER_OFFSET 44 -#define PHY_TX_POWER_NUM 5 +#define PHY_TX_POWER_OFFSET 2 +#define PHY_TX_POWER_NUM 14 #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN #define PHY_CRC_ALGORITHM 1 diff --git a/components/esp_wifi/esp32s2/include/phy_init_data.h b/components/esp_wifi/esp32s2/include/phy_init_data.h index a17b7b910bc4..b4bbdd7e46d6 100644 --- a/components/esp_wifi/esp32s2/include/phy_init_data.h +++ b/components/esp_wifi/esp32s2/include/phy_init_data.h @@ -28,8 +28,8 @@ extern "C" { // define the lowest tx power as LOWEST_PHY_TX_POWER #define PHY_TX_POWER_LOWEST LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 52) -#define PHY_TX_POWER_OFFSET 44 -#define PHY_TX_POWER_NUM 5 +#define PHY_TX_POWER_OFFSET 2 +#define PHY_TX_POWER_NUM 14 #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN #define PHY_CRC_ALGORITHM 1 @@ -44,64 +44,84 @@ static const char phy_init_magic_pre[] = PHY_INIT_MAGIC; * @brief Structure containing default recommended PHY initialization parameters. */ static const esp_phy_init_data_t phy_init_data= { { - 3, - 0, - 0x04, - 0x05, - 0x04, - 0x05, - 0x05, - 0x04, - 0x06, - 0x06, - 0x06, - 0x05, - 0x06, + 0x80, 0x00, + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4E), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4E), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x44), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x44), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x44), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x42), 0x00, 0x00, 0x00, - 0x05, - 0x09, - 0x06, - 0x05, - 0x03, - 0x06, - 0x05, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xf4, - 0xf8, - 0xf8, - 0xf0, - 0xf0, - 0xf0, - 0xe0, - 0xe0, - 0xe0, - 0x18, - 0x18, - 0x18, - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 84), - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 72), - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 66), - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 60), - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 56), - LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 52), + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, - 1, - 1, - 2, - 2, - 3, - 4, - 5, 0, 0, 0, @@ -151,6 +171,7 @@ static const esp_phy_init_data_t phy_init_data= { { 0, 0, 0, + 0xf1 } }; static const char phy_init_magic_post[] = PHY_INIT_MAGIC; diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 51e03234841d..ca926bfd0003 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -236,21 +236,21 @@ extern uint64_t g_wifi_feature_caps; .feature_caps = g_wifi_feature_caps, \ .sta_disconnected_pm = WIFI_STA_DISCONNECTED_PM_ENABLED, \ .magic = WIFI_INIT_CONFIG_MAGIC\ -}; +} /** - * @brief Init WiFi - * Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer, - * WiFi NVS structure etc, this WiFi also start WiFi task + * @brief Initialize WiFi + * Allocate resource for WiFi driver, such as WiFi control structure, RX/TX buffer, + * WiFi NVS structure etc. This WiFi also starts WiFi task * * @attention 1. This API must be called before all other WiFi API can be called - * @attention 2. Always use WIFI_INIT_CONFIG_DEFAULT macro to init the config to default values, this can - * guarantee all the fields got correct value when more fields are added into wifi_init_config_t - * in future release. If you want to set your owner initial values, overwrite the default values - * which are set by WIFI_INIT_CONFIG_DEFAULT, please be notified that the field 'magic' of + * @attention 2. Always use WIFI_INIT_CONFIG_DEFAULT macro to initialize the configuration to default values, this can + * guarantee all the fields get correct value when more fields are added into wifi_init_config_t + * in future release. If you want to set your own initial values, overwrite the default values + * which are set by WIFI_INIT_CONFIG_DEFAULT. Please be notified that the field 'magic' of * wifi_init_config_t should always be WIFI_INIT_CONFIG_MAGIC! * - * @param config pointer to WiFi init configuration structure; can point to a temporary variable. + * @param config pointer to WiFi initialized configuration structure; can point to a temporary variable. * * @return * - ESP_OK: succeed @@ -1303,6 +1303,19 @@ esp_err_t esp_wifi_get_country_code(char *country); */ esp_err_t esp_wifi_config_80211_tx_rate(wifi_interface_t ifx, wifi_phy_rate_t rate); +/** + * @brief Disable PMF configuration for specified interface + * + * @attention This API should be called after esp_wifi_set_config() and before esp_wifi_start(). + * + * @param ifx Interface to be configured. + * + * @return + * - ESP_OK: succeed + * - others: failed + */ +esp_err_t esp_wifi_disable_pmf_config(wifi_interface_t ifx); + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 503e8d7bb05b..199de4376643 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -218,7 +218,7 @@ typedef enum { /** Configuration structure for Protected Management Frame */ typedef struct { - bool capable; /**< Advertizes support for Protected Management Frame. Device will prefer to connect in PMF mode if other device also advertizes PMF capability. */ + bool capable; /**< Deprecated variable. Device will always connect in PMF mode if other device also advertizes PMF capability. */ bool required; /**< Advertizes that Protected Management Frame is required. Device will not associate to non-PMF capable devices. */ } wifi_pmf_config_t; diff --git a/components/esp_wifi/include/phy.h b/components/esp_wifi/include/phy.h index 14e1286db024..40c3a1d49904 100644 --- a/components/esp_wifi/include/phy.h +++ b/components/esp_wifi/include/phy.h @@ -101,6 +101,13 @@ void phy_freq_mem_backup(bool backup_en, uint32_t *mem); void phy_bbpll_en_usb(bool en); #endif +#if CONFIG_IDF_TARGET_ESP32S2 +/** + * @brief Phy version select for ESP32S2 + */ +void phy_eco_version_sel(uint8_t chip_ver); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index f09ae075526f..1ef842d0efff 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit f09ae075526f3a6ac816940d3d258922028c4165 +Subproject commit 1ef842d0efff1d7a6e1ff072fa1fb4cdedb1a908 diff --git a/components/esp_wifi/src/phy_init.c b/components/esp_wifi/src/phy_init.c index 9e1cf4aaf5c1..bb5c0625f5e6 100644 --- a/components/esp_wifi/src/phy_init.c +++ b/components/esp_wifi/src/phy_init.c @@ -25,6 +25,7 @@ #include "esp_log.h" #include "nvs.h" #include "nvs_flash.h" +#include "esp_efuse.h" #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/portmacro.h" @@ -331,8 +332,6 @@ IRAM_ATTR void esp_mac_bb_power_down(void) const esp_phy_init_data_t* esp_phy_get_init_data(void) { - esp_err_t err = ESP_OK; - const esp_partition_t* partition = NULL; #if CONFIG_ESP32_MULTIPLE_PHY_DATA_BIN_EMBEDDED size_t init_data_store_length = sizeof(phy_init_magic_pre) + sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post); @@ -344,7 +343,7 @@ const esp_phy_init_data_t* esp_phy_get_init_data(void) memcpy(init_data_store, multi_phy_init_data_bin_start, init_data_store_length); ESP_LOGI(TAG, "loading embedded multiple PHY init data"); #else - partition = esp_partition_find_first( + const esp_partition_t* partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_PHY, NULL); if (partition == NULL) { ESP_LOGE(TAG, "PHY data partition not found"); @@ -358,7 +357,7 @@ const esp_phy_init_data_t* esp_phy_get_init_data(void) ESP_LOGE(TAG, "failed to allocate memory for PHY init data"); return NULL; } - err = esp_partition_read(partition, 0, init_data_store, init_data_store_length); + esp_err_t err = esp_partition_read(partition, 0, init_data_store, init_data_store_length); if (err != ESP_OK) { ESP_LOGE(TAG, "failed to read PHY data partition (0x%x)", err); free(init_data_store); @@ -577,6 +576,10 @@ void esp_phy_load_cal_and_init(void) char * phy_version = get_phy_version_str(); ESP_LOGI(TAG, "phy_version %s", phy_version); +#if CONFIG_IDF_TARGET_ESP32S2 + phy_eco_version_sel(esp_efuse_get_chip_ver()); +#endif + esp_phy_calibration_data_t* cal_data = (esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1); if (cal_data == NULL) { diff --git a/components/esp_wifi/src/phy_override.c b/components/esp_wifi/src/phy_override.c new file mode 100644 index 000000000000..ce7c0f8512ba --- /dev/null +++ b/components/esp_wifi/src/phy_override.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_attr.h" +#include "driver/adc.h" + +/* + * This file is used to override the hooks provided by the PHY lib for some system features. + * Call phy_override() so that this file will be linked. + */ + +static bool s_wifi_adc_xpd_flag; + +void include_esp_phy_override(void) +{ + /* When this empty function is called, all functions below will be linked. */ +} + +/* Coordinate ADC power with other modules. */ +// It seems that it is only required on ESP32, but we still compile it for all chips, in case it is +// called by PHY unexpectedly. +void set_xpd_sar(bool en) +{ + if (s_wifi_adc_xpd_flag == en) { + /* ignore repeated calls to set_xpd_sar when the state is already correct */ + return; + } + + s_wifi_adc_xpd_flag = en; + if (en) { + adc_power_acquire(); + } else { + adc_power_release(); + } +} + +//add spinlock protection +extern void regi2c_enter_critical(void); +extern void regi2c_exit_critical(void); + +IRAM_ATTR void phy_i2c_enter_critical(void) +{ + regi2c_enter_critical(); +} + +IRAM_ATTR void phy_i2c_exit_critical(void) +{ + regi2c_exit_critical(); +} diff --git a/components/esp_wifi/src/smartconfig_ack.c b/components/esp_wifi/src/smartconfig_ack.c index 76d1c618a8ed..1fd64b0a5869 100644 --- a/components/esp_wifi/src/smartconfig_ack.c +++ b/components/esp_wifi/src/smartconfig_ack.c @@ -127,7 +127,15 @@ static void sc_ack_send_task(void *pvParameters) goto _end; } - setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &optval, sizeof(int)); + if (setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(int)) < 0) { + ESP_LOGE(TAG, "setsockopt SO_BROADCAST failed"); + goto _end; + } + + if (setsockopt(send_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) < 0) { + ESP_LOGE(TAG, "setsockopt SO_REUSEADDR failed"); + goto _end; + } if (ack->type == SC_TYPE_AIRKISS) { char data = 0; diff --git a/components/esp_wifi/src/wifi_default.c b/components/esp_wifi/src/wifi_default.c index bc494857c486..bdf3f74432af 100644 --- a/components/esp_wifi/src/wifi_default.c +++ b/components/esp_wifi/src/wifi_default.c @@ -236,6 +236,8 @@ esp_err_t esp_wifi_clear_default_wifi_driver_and_handlers(void *esp_netif) if (s_wifi_netifs[i] == esp_netif) { s_wifi_netifs[i] = NULL; } + } + for (i = 0; i< MAX_WIFI_IFS; ++i) { // check if all netifs are cleared to delete default handlers if (s_wifi_netifs[i] != NULL) { break; diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 2fd667eab7ac..0e4a6aed2d5a 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -23,7 +23,6 @@ #include "esp_wpa.h" #include "esp_netif.h" #include "tcpip_adapter_compatible/tcpip_adapter_compat.h" -#include "driver/adc.h" #include "driver/adc2_wifi_private.h" #include "esp_coexist_internal.h" #include "esp_phy_init.h" @@ -64,7 +63,6 @@ uint64_t g_wifi_feature_caps = #endif 0; -static bool s_wifi_adc_xpd_flag; static const char* TAG = "wifi_init"; @@ -109,6 +107,11 @@ esp_err_t esp_wifi_deinit(void) return ESP_ERR_WIFI_NOT_STOPPED; } + if (esp_wifi_internal_reg_rxcb(WIFI_IF_STA, NULL) != ESP_OK || + esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL) != ESP_OK) { + ESP_LOGW(TAG, "Failed to unregister Rx callbacks"); + } + esp_supplicant_deinit(); err = esp_wifi_deinit_internal(); if (err != ESP_OK) { @@ -285,24 +288,6 @@ void wifi_apb80m_release(void) } #endif //CONFIG_PM_ENABLE -/* Coordinate ADC power with other modules. This overrides the function from PHY lib. */ -// It seems that it is only required on ESP32, but we still compile it for all chips, in case it is -// called by PHY unexpectedly. -void set_xpd_sar(bool en) -{ - if (s_wifi_adc_xpd_flag == en) { - /* ignore repeated calls to set_xpd_sar when the state is already correct */ - return; - } - - s_wifi_adc_xpd_flag = en; - if (en) { - adc_power_acquire(); - } else { - adc_power_release(); - } -} - #ifndef CONFIG_ESP_WIFI_FTM_ENABLE void ieee80211_ftm_attach(void) { diff --git a/components/esp_wifi/src/wifi_netif.c b/components/esp_wifi/src/wifi_netif.c index ba92759b4f48..6484cf1aa51f 100644 --- a/components/esp_wifi/src/wifi_netif.c +++ b/components/esp_wifi/src/wifi_netif.c @@ -89,6 +89,11 @@ static esp_err_t wifi_driver_start(esp_netif_t * esp_netif, void * args) void esp_wifi_destroy_if_driver(wifi_netif_driver_t h) { + if (h) { + esp_wifi_internal_reg_rxcb(h->wifi_if, NULL); // ignore the potential error + // as the wifi might have been already uninitialized + s_wifi_netifs[h->wifi_if] = NULL; + } free(h); } diff --git a/components/espcoredump/CMakeLists.txt b/components/espcoredump/CMakeLists.txt index 110e2d955416..b5cc82410c05 100644 --- a/components/espcoredump/CMakeLists.txt +++ b/components/espcoredump/CMakeLists.txt @@ -5,20 +5,23 @@ "src/core_dump_elf.c" "src/core_dump_binary.c") +set(includes "include") set(priv_includes "include_core_dump") idf_build_get_property(target IDF_TARGET) if(CONFIG_IDF_TARGET_ARCH_XTENSA) - set(srcs ${srcs} "src/port/xtensa/core_dump_port.c") - set(priv_includes ${priv_includes} "include_core_dump/port/xtensa") + list(APPEND srcs "src/port/xtensa/core_dump_port.c") + list(APPEND includes "include/port/xtensa") + list(APPEND priv_includes "include_core_dump/port/xtensa") elseif(CONFIG_IDF_TARGET_ARCH_RISCV) - set(srcs ${srcs} "src/port/riscv/core_dump_port.c") - set(priv_includes ${priv_includes} "include_core_dump/port/riscv") + list(APPEND srcs "src/port/riscv/core_dump_port.c") + list(APPEND includes "include/port/riscv") + list(APPEND priv_includes "include_core_dump/port/riscv") endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS "include" + INCLUDE_DIRS ${includes} PRIV_INCLUDE_DIRS ${priv_includes} LDFRAGMENTS linker.lf PRIV_REQUIRES spi_flash app_update mbedtls esp_rom soc) diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index 913441383270..28a54a02a600 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -90,6 +90,15 @@ menu "Core dump" To ensure that core dump itself will not overflow task/ISR stack set this to the value above 800. NOTE: It eats DRAM. + config ESP_COREDUMP_SUMMARY_STACKDUMP_SIZE + int "Size of the stack dump buffer" + depends on ESP_COREDUMP_DATA_FORMAT_ELF && ESP_COREDUMP_ENABLE_TO_FLASH && IDF_TARGET_ARCH_RISCV + range 512 4096 + default 1024 + help + Size of the buffer that would be reserved for extracting backtrace info summary. + This buffer will contain the stack dump of the crashed task. This dump is useful in generating backtrace + choice ESP_COREDUMP_DECODE prompt "Handling of UART core dumps in IDF Monitor" depends on ESP_COREDUMP_ENABLE_TO_UART diff --git a/components/espcoredump/component.mk b/components/espcoredump/component.mk index 8a2c1d439fb8..439f80a44d97 100644 --- a/components/espcoredump/component.mk +++ b/components/espcoredump/component.mk @@ -5,10 +5,12 @@ COMPONENT_ADD_LDFRAGMENTS += linker.lf ifdef CONFIG_IDF_TARGET_ARCH_XTENSA COMPONENT_SRCDIRS += src/port/xtensa + COMPONENT_ADD_INCLUDEDIRS += include/port/xtensa COMPONENT_PRIV_INCLUDEDIRS += include_core_dump/port/xtensa endif ifdef CONFIG_IDF_TARGET_ARCH_RISCV COMPONENT_SRCDIRS += src/port/riscv + COMPONENT_ADD_INCLUDEDIRS += include/port/riscv COMPONENT_PRIV_INCLUDEDIRS += include_core_dump/port/riscv endif diff --git a/components/espcoredump/corefile/__init__.py b/components/espcoredump/corefile/__init__.py index 5eb0a3313ad8..ae523c796c1e 100644 --- a/components/espcoredump/corefile/__init__.py +++ b/components/espcoredump/corefile/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2021 Espressif Systems (Shanghai) PTE LTD +# Copyright 2021 Espressif Systems (Shanghai) CO., LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,7 +16,22 @@ __version__ = '0.4-dev' +import abc +import os from abc import abstractmethod +from importlib import import_module + +from future.utils import with_metaclass + +try: + from typing import Optional, Tuple +except ImportError: + pass + +IDF_PATH = os.path.normpath(os.getenv('IDF_PATH', '.')) +XTENSA_TARGETS = ['esp32', 'esp32s2'] +RISCV_TARGETS = ['esp32c3'] +SUPPORTED_TARGETS = XTENSA_TARGETS + RISCV_TARGETS class ESPCoreDumpError(RuntimeError): @@ -27,42 +42,84 @@ class ESPCoreDumpLoaderError(ESPCoreDumpError): pass -class _TargetMethodsBase(object): +class BaseArchMethodsMixin(with_metaclass(abc.ABCMeta)): # type: ignore @staticmethod @abstractmethod - def tcb_is_sane(tcb_addr, tcb_size): + def get_registers_from_stack(data, grows_down): + # type: (bytes, bool) -> Tuple[list[int], Optional[dict[int, int]]] """ - Check tcb address if it is correct + Parse stack data, growing up stacks are not supported for now. + :param data: stack data + :param grows_down: stack grow direction + :return: return tuple (regs, exception_regs) """ - return False + pass @staticmethod @abstractmethod - def stack_is_sane(sp): + def build_prstatus_data(tcb_addr, task_regs): # type: (int, list[int]) -> str """ - Check stack address if it is correct + Build PrStatus note section + :param tcb_addr: tcb addr + :param task_regs: registers + :return: str """ - return False + pass - @staticmethod - @abstractmethod - def addr_is_fake(addr): - """ - Check if address is in fake area - """ + +class BaseTargetMethods(with_metaclass(abc.ABCMeta, BaseArchMethodsMixin)): # type: ignore + UNKNOWN = 'unknown' + TARGET = UNKNOWN + + COREDUMP_FAKE_STACK_START = 0x20000000 + COREDUMP_FAKE_STACK_LIMIT = 0x30000000 + COREDUMP_MAX_TASK_STACK_SIZE = 64 * 1024 + + def __init__(self): # type: () -> None + if self.TARGET == self.UNKNOWN: + raise ValueError('Please use the derived child-class with valid TARGET') + + self._set_attr_from_soc_header() + + def _set_attr_from_soc_header(self): # type: () -> None + module = import_module('corefile.soc_headers.{}'.format(self.TARGET)) + for k, v in module.__dict__.items(): + if k.startswith('SOC_'): + setattr(self, k, v) + + def _esp_ptr_in_dram(self, addr): # type: (int) -> bool + return self.SOC_DRAM_LOW <= addr < self.SOC_DRAM_HIGH # type: ignore + + def _esp_ptr_in_iram(self, addr): # type: (int) -> bool + return self.SOC_IRAM_LOW <= addr < self.SOC_IRAM_HIGH # type: ignore + + def _esp_ptr_in_rtc_slow(self, addr): # type: (int) -> bool + return self.SOC_RTC_DATA_LOW <= addr < self.SOC_RTC_DATA_HIGH # type: ignore + + def _esp_ptr_in_rtc_dram_fast(self, addr): # type: (int) -> bool + return self.SOC_RTC_DRAM_LOW <= addr < self.SOC_RTC_DRAM_HIGH # type: ignore + + def tcb_is_sane(self, tcb_addr, tcb_size): # type: (int, int) -> bool + for func in [self._esp_ptr_in_dram, + self._esp_ptr_in_iram, + self._esp_ptr_in_rtc_slow, + self._esp_ptr_in_rtc_dram_fast]: + res = func(tcb_addr) and func(tcb_addr + tcb_size - 1) + if res: + return True return False + def _esp_stack_ptr_in_dram(self, addr): # type: (int) -> bool + return not (addr < self.SOC_DRAM_LOW + 0x10 + or addr > self.SOC_DRAM_HIGH - 0x10 + or (addr & 0xF) != 0) -class _ArchMethodsBase(object): - @staticmethod - @abstractmethod - def get_registers_from_stack(data, grows_down): - """ - Returns list of registers (in GDB format) from stack frame - """ - return [], {} + def stack_is_sane(self, stack_start, stack_end): # type: (int, int) -> bool + return (self._esp_stack_ptr_in_dram(stack_start) + and self._esp_ptr_in_dram(stack_end) + and stack_start < stack_end + and (stack_end - stack_start) < self.COREDUMP_MAX_TASK_STACK_SIZE) - @staticmethod - @abstractmethod - def build_prstatus_data(tcb_addr, task_regs): - return b'' + def addr_is_fake(self, addr): # type: (int) -> bool + return (self.COREDUMP_FAKE_STACK_START <= addr < self.COREDUMP_FAKE_STACK_LIMIT + or addr > 2 ** 31 - 1) diff --git a/components/espcoredump/corefile/_parse_soc_header.py b/components/espcoredump/corefile/_parse_soc_header.py new file mode 100644 index 000000000000..1e0fe309c9fb --- /dev/null +++ b/components/espcoredump/corefile/_parse_soc_header.py @@ -0,0 +1,44 @@ +""" +This file is used to generate soc header constants into sub-package soc_headers +""" +import os +from ast import literal_eval + +from . import IDF_PATH, SUPPORTED_TARGETS + + +def main(): # type: () -> None + constants = [ + 'SOC_DRAM_LOW', + 'SOC_DRAM_HIGH', + 'SOC_IRAM_LOW', + 'SOC_IRAM_HIGH', + 'SOC_RTC_DATA_LOW', + 'SOC_RTC_DATA_HIGH', + 'SOC_RTC_DRAM_LOW', + 'SOC_RTC_DRAM_HIGH', + ] + + for target in SUPPORTED_TARGETS: + target_constants = {} + soc_header_fp = os.path.join(IDF_PATH, 'components/soc/{}/include/soc/soc.h'.format(target)) + module_fp = os.path.join(IDF_PATH, 'components', 'espcoredump', 'corefile', 'soc_headers', + '{}.py'.format(target)) + + with open(soc_header_fp) as fr: + for line in fr.readlines(): + for attr in constants: + if '#define {}'.format(attr) in line: + target_constants[attr] = literal_eval(line.strip().split()[-1]) + + for attr in constants: + if attr not in target_constants: + raise ValueError('ERROR: Attr {} is missing in {}'.format(attr, soc_header_fp)) + + with open(module_fp, 'w') as fw: + for k, v in target_constants.items(): + fw.write('{} = {}\n'.format(k, hex(v))) + + +if __name__ == '__main__': + main() diff --git a/components/espcoredump/corefile/elf.py b/components/espcoredump/corefile/elf.py index f0e381b2c2ec..17e3189eb17e 100644 --- a/components/espcoredump/corefile/elf.py +++ b/components/espcoredump/corefile/elf.py @@ -1,5 +1,5 @@ # -# Copyright 2021 Espressif Systems (Shanghai) PTE LTD +# Copyright 2021 Espressif Systems (Shanghai) CO., LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,8 +17,13 @@ import hashlib import os -from construct import (AlignedStruct, Bytes, Const, GreedyRange, Int16ul, Int32ul, Padding, Pointer, Sequence, Struct, - this) +from construct import (AlignedStruct, Bytes, Const, Container, GreedyRange, Int16ul, Int32ul, Padding, Pointer, + Sequence, Struct, this) + +try: + from typing import Optional +except ImportError: + pass # Following structs are based on spec # https://refspecs.linuxfoundation.org/elf/elf.pdf @@ -110,12 +115,13 @@ class ElfFile(object): EV_CURRENT = 0x01 def __init__(self, elf_path=None, e_type=None, e_machine=None): + # type: (Optional[str], Optional[int], Optional[int]) -> None self.e_type = e_type self.e_machine = e_machine - self._struct = None # construct Struct - self._model = None # construct Container - self._section_names = [] # type: list[str] + self._struct = None # type: Optional[Struct] + self._model = None # type: Optional[Container] + self._section_names = {} # type: dict[int, str] self.sections = [] # type: list[ElfSection] self.load_segments = [] # type: list[ElfSegment] @@ -171,7 +177,7 @@ def _parse_string_table(byte_str): # type: (bytes) -> dict name += c return res - def _generate_struct_from_headers(self, header_tables): + def _generate_struct_from_headers(self, header_tables): # type: (Container) -> Struct """ Generate ``construct`` Struct for this file :param header_tables: contains elf_header, program_headers, section_headers @@ -219,12 +225,12 @@ def _generate_struct_from_headers(self, header_tables): return Struct(*args) @property - def sha256(self): + def sha256(self): # type: () -> bytes """ :return: SHA256 hash of the input ELF file """ sha256 = hashlib.sha256() - sha256.update(self._struct.build(self._model)) + sha256.update(self._struct.build(self._model)) # type: ignore return sha256.digest() @@ -234,13 +240,13 @@ class ElfSection(object): SHF_EXECINSTR = 0x04 SHF_MASKPROC = 0xf0000000 - def __init__(self, name, addr, data, flags): + def __init__(self, name, addr, data, flags): # type: (str, int, bytes, int) -> None self.name = name self.addr = addr self.data = data self.flags = flags - def attr_str(self): + def attr_str(self): # type: () -> str if self.flags & self.SHF_MASKPROC: return 'MS' @@ -250,7 +256,7 @@ def attr_str(self): res += 'A' if self.flags & self.SHF_ALLOC else ' ' return res - def __repr__(self): + def __repr__(self): # type: () -> str return '{:>32} [Addr] 0x{:>08X}, [Size] 0x{:>08X} {:>4}' \ .format(self.name, self.addr, len(self.data), self.attr_str()) @@ -260,13 +266,13 @@ class ElfSegment(object): PF_W = 0x02 PF_R = 0x04 - def __init__(self, addr, data, flags): + def __init__(self, addr, data, flags): # type: (int, bytes, int) -> None self.addr = addr self.data = data self.flags = flags self.type = ElfFile.PT_LOAD - def attr_str(self): + def attr_str(self): # type: () -> str res = '' res += 'R' if self.flags & self.PF_R else ' ' res += 'W' if self.flags & self.PF_W else ' ' @@ -274,22 +280,22 @@ def attr_str(self): return res @staticmethod - def _type_str(): + def _type_str(): # type: () -> str return 'LOAD' - def __repr__(self): + def __repr__(self): # type: () -> str return '{:>8} Addr 0x{:>08X}, Size 0x{:>08X} Flags {:4}' \ .format(self._type_str(), self.addr, len(self.data), self.attr_str()) class ElfNoteSegment(ElfSegment): - def __init__(self, addr, data, flags): + def __init__(self, addr, data, flags): # type: (int, bytes, int) -> None super(ElfNoteSegment, self).__init__(addr, data, flags) self.type = ElfFile.PT_NOTE self.note_secs = NoteSections.parse(self.data) @staticmethod - def _type_str(): + def _type_str(): # type: () -> str return 'NOTE' @@ -316,13 +322,15 @@ class ESPCoreDumpElfFile(ElfFile): # ELF file machine type EM_XTENSA = 0x5E + EM_RISCV = 0xF3 def __init__(self, elf_path=None, e_type=None, e_machine=None): + # type: (Optional[str], Optional[int], Optional[int]) -> None _e_type = e_type or self.ET_CORE _e_machine = e_machine or self.EM_XTENSA super(ESPCoreDumpElfFile, self).__init__(elf_path, _e_type, _e_machine) - def add_segment(self, addr, data, seg_type, flags): + def add_segment(self, addr, data, seg_type, flags): # type: (int, bytes, int, int) -> None if seg_type != self.PT_NOTE: self.load_segments.append(ElfSegment(addr, data, flags)) else: @@ -352,7 +360,7 @@ def dump(self, output_path): # type: (str) -> None }) offset = ElfHeader.sizeof() + (len(self.load_segments) + len(self.note_segments)) * ProgramHeader.sizeof() - _segments = self.load_segments + self.note_segments + _segments = self.load_segments + self.note_segments # type: ignore for seg in _segments: res += ProgramHeader.build({ 'p_type': seg.type, diff --git a/components/espcoredump/corefile/gdb.py b/components/espcoredump/corefile/gdb.py index df93eea2b05b..d0c0467c7744 100644 --- a/components/espcoredump/corefile/gdb.py +++ b/components/espcoredump/corefile/gdb.py @@ -1,5 +1,5 @@ # -# Copyright 2021 Espressif Systems (Shanghai) PTE LTD +# Copyright 2021 Espressif Systems (Shanghai) CO., LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,19 +18,14 @@ import re import time -from . import ESPCoreDumpError - -try: - import typing -except ImportError: - pass - from pygdbmi.gdbcontroller import DEFAULT_GDB_TIMEOUT_SEC, GdbController +from . import ESPCoreDumpError + class EspGDB(object): def __init__(self, gdb_path, gdb_cmds, core_filename, prog_filename, timeout_sec=DEFAULT_GDB_TIMEOUT_SEC): - # type: (str, typing.List[str], str, str, int) -> None + """ Start GDB and initialize a GdbController instance """ @@ -59,7 +54,7 @@ def __del__(self): def _gdbmi_run_cmd_get_responses(self, cmd, resp_message, resp_type, multiple=True, done_message=None, done_type=None): - # type: (str, typing.Optional[str], str, bool, typing.Optional[str], typing.Optional[str]) -> list + self.p.write(cmd, read_response=False) t_end = time.time() + self.timeout filtered_response_list = [] @@ -80,15 +75,15 @@ def _gdbmi_run_cmd_get_responses(self, cmd, resp_message, resp_type, multiple=Tr return filtered_response_list def _gdbmi_run_cmd_get_one_response(self, cmd, resp_message, resp_type): - # type: ( str, typing.Optional[str], str) -> dict + return self._gdbmi_run_cmd_get_responses(cmd, resp_message, resp_type, multiple=False)[0] - def _gdbmi_data_evaluate_expression(self, expr): # type: (str) -> str + def _gdbmi_data_evaluate_expression(self, expr): """ Get the value of an expression, similar to the 'print' command """ return self._gdbmi_run_cmd_get_one_response("-data-evaluate-expression \"%s\"" % expr, 'done', 'result')['payload']['value'] - def get_freertos_task_name(self, tcb_addr): # type: (int) -> str + def get_freertos_task_name(self, tcb_addr): """ Get FreeRTOS task name given the TCB address """ try: val = self._gdbmi_data_evaluate_expression('(char*)((TCB_t *)0x%x)->pcTaskName' % tcb_addr) @@ -102,7 +97,7 @@ def get_freertos_task_name(self, tcb_addr): # type: (int) -> str return result.group(1) return '' - def run_cmd(self, gdb_cmd): # type: (str) -> str + def run_cmd(self, gdb_cmd): """ Execute a generic GDB console command via MI2 """ filtered_responses = self._gdbmi_run_cmd_get_responses(cmd="-interpreter-exec console \"%s\"" % gdb_cmd, @@ -113,14 +108,14 @@ def run_cmd(self, gdb_cmd): # type: (str) -> str .replace('\\t', '\t') \ .rstrip('\n') - def get_thread_info(self): # type: () -> (typing.List[dict], str) + def get_thread_info(self): """ Get information about all threads known to GDB, and the current thread ID """ result = self._gdbmi_run_cmd_get_one_response('-thread-info', 'done', 'result')['payload'] current_thread_id = result['current-thread-id'] threads = result['threads'] return threads, current_thread_id - def switch_thread(self, thr_id): # type: (int) -> None + def switch_thread(self, thr_id): """ Tell GDB to switch to a specific thread, given its ID """ self._gdbmi_run_cmd_get_one_response('-thread-select %s' % thr_id, 'done', 'result') @@ -129,6 +124,6 @@ def _gdbmi_filter_responses(responses, resp_message, resp_type): return list(filter(lambda rsp: rsp['message'] == resp_message and rsp['type'] == resp_type, responses)) @staticmethod - def gdb2freertos_thread_id(gdb_target_id): # type: (str) -> int + def gdb2freertos_thread_id(gdb_target_id): """ Convert GDB 'target ID' to the FreeRTOS TCB address """ return int(gdb_target_id.replace('process ', ''), 0) diff --git a/components/espcoredump/corefile/loader.py b/components/espcoredump/corefile/loader.py index 64349f92abca..2cd3e474087a 100644 --- a/components/espcoredump/corefile/loader.py +++ b/components/espcoredump/corefile/loader.py @@ -1,5 +1,5 @@ # -# Copyright 2021 Espressif Systems (Shanghai) PTE LTD +# Copyright 2021 Espressif Systems (Shanghai) CO., LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,12 +25,18 @@ from construct import AlignedStruct, Bytes, GreedyRange, Int32ul, Padding, Struct, abs_, this -from . import ESPCoreDumpLoaderError, _ArchMethodsBase, _TargetMethodsBase +from . import ESPCoreDumpLoaderError from .elf import (TASK_STATUS_CORRECT, TASK_STATUS_TCB_CORRUPTED, ElfFile, ElfSegment, ESPCoreDumpElfFile, EspTaskStatus, NoteSection) -from .xtensa import _ArchMethodsXtensa, _TargetMethodsESP32 +from .riscv import Esp32c3Methods +from .xtensa import Esp32Methods, Esp32S2Methods -IDF_PATH = os.getenv('IDF_PATH') +try: + from typing import Optional, Tuple +except ImportError: + pass + +IDF_PATH = os.getenv('IDF_PATH', '') PARTTOOL_PY = os.path.join(IDF_PATH, 'components', 'partition_table', 'parttool.py') ESPTOOL_PY = os.path.join(IDF_PATH, 'components', 'esptool_py', 'esptool', 'esptool.py') @@ -74,12 +80,14 @@ class EspCoreDumpVersion(object): # This class contains all version-dependent params ESP32 = 0 ESP32S2 = 2 - XTENSA_CHIPS = [ESP32, ESP32S2] - ESP_COREDUMP_TARGETS = XTENSA_CHIPS + ESP32C3 = 5 + RISCV_CHIPS = [ESP32C3] - def __init__(self, version=None): + COREDUMP_SUPPORTED_TARGETS = XTENSA_CHIPS + RISCV_CHIPS + + def __init__(self, version=None): # type: (int) -> None """Constructor for core dump version """ super(EspCoreDumpVersion, self).__init__() @@ -89,26 +97,26 @@ def __init__(self, version=None): self.set_version(version) @staticmethod - def make_dump_ver(major, minor): + def make_dump_ver(major, minor): # type: (int, int) -> int return ((major & 0xFF) << 8) | ((minor & 0xFF) << 0) - def set_version(self, version): + def set_version(self, version): # type: (int) -> None self.version = version @property - def chip_ver(self): + def chip_ver(self): # type: () -> int return (self.version & 0xFFFF0000) >> 16 @property - def dump_ver(self): + def dump_ver(self): # type: () -> int return self.version & 0x0000FFFF @property - def major(self): + def major(self): # type: () -> int return (self.version & 0x0000FF00) >> 8 @property - def minor(self): + def minor(self): # type: () -> int return self.version & 0x000000FF @@ -119,42 +127,37 @@ class EspCoreDumpLoader(EspCoreDumpVersion): ELF_CRC32 = EspCoreDumpVersion.make_dump_ver(1, 0) ELF_SHA256 = EspCoreDumpVersion.make_dump_ver(1, 1) - def __init__(self): + def __init__(self): # type: () -> None super(EspCoreDumpLoader, self).__init__() - self.core_src_file = None + self.core_src_file = None # type: Optional[str] self.core_src_struct = None self.core_src = None - self.core_elf_file = None + self.core_elf_file = None # type: Optional[str] self.header = None self.header_struct = EspCoreDumpV1Header self.checksum_struct = CRC - # These two method classes will be assigned in ``reload_coredump`` - self.target_method_cls = _TargetMethodsBase - self.arch_method_cls = _ArchMethodsBase + # target classes will be assigned in ``_reload_coredump`` + self.target_methods = Esp32Methods() - self._temp_files = [] + self.temp_files = [] # type: list[str] - def __del__(self): - if self.core_src_file: - self.core_src_file.close() - if self.core_elf_file: - self.core_elf_file.close() - for f in self._temp_files: - try: - os.remove(f) - except OSError: - pass - - def _create_temp_file(self): + def _create_temp_file(self): # type: () -> str t = tempfile.NamedTemporaryFile('wb', delete=False) - self._temp_files.append(t.name) - return t + # Here we close this at first to make sure the read/write is wrapped in context manager + # Otherwise the result will be wrong if you read while open in another session + t.close() + self.temp_files.append(t.name) + return t.name - def _reload_coredump(self): - with open(self.core_src_file.name, 'rb') as fr: + def _load_core_src(self): # type: () -> str + """ + Write core elf into ``self.core_src``, + Return the target str by reading core elf + """ + with open(self.core_src_file, 'rb') as fr: # type: ignore coredump_bytes = fr.read() _header = EspCoreDumpV1Header.parse(coredump_bytes) # first we use V1 format to get version @@ -179,23 +182,28 @@ def _reload_coredump(self): 'data' / Bytes(this.header.tot_len - self.header_struct.sizeof() - self.checksum_struct.sizeof()), 'checksum' / self.checksum_struct, ) - self.core_src = self.core_src_struct.parse(coredump_bytes) + self.core_src = self.core_src_struct.parse(coredump_bytes) # type: ignore # Reload header if header struct changes after parsing if self.header_struct != EspCoreDumpV1Header: self.header = EspCoreDumpV2Header.parse(coredump_bytes) - if self.chip_ver in self.ESP_COREDUMP_TARGETS: + if self.chip_ver in self.COREDUMP_SUPPORTED_TARGETS: if self.chip_ver == self.ESP32: - self.target_method_cls = _TargetMethodsESP32 - - if self.chip_ver in self.XTENSA_CHIPS: - self.arch_method_cls = _ArchMethodsXtensa + self.target_methods = Esp32Methods() # type: ignore + elif self.chip_ver == self.ESP32S2: + self.target_methods = Esp32S2Methods() # type: ignore + elif self.chip_ver == self.ESP32C3: + self.target_methods = Esp32c3Methods() # type: ignore + else: + raise NotImplementedError else: raise ESPCoreDumpLoaderError('Core dump chip "0x%x" is not supported!' % self.chip_ver) - def _validate_dump_file(self): - if self.chip_ver not in self.ESP_COREDUMP_TARGETS: + return self.target_methods.TARGET # type: ignore + + def _validate_dump_file(self): # type: () -> None + if self.chip_ver not in self.COREDUMP_SUPPORTED_TARGETS: raise ESPCoreDumpLoaderError('Invalid core dump chip version: "{}", should be <= "0x{:X}"' .format(self.chip_ver, self.ESP32S2)) @@ -204,20 +212,24 @@ def _validate_dump_file(self): elif self.checksum_struct == SHA256: self._sha256_validate() - def _crc_validate(self): - data_crc = binascii.crc32(EspCoreDumpV2Header.build(self.core_src.header) + self.core_src.data) & 0xffffffff - if data_crc != self.core_src.checksum: - raise ESPCoreDumpLoaderError('Invalid core dump CRC %x, should be %x' % (data_crc, self.core_src.crc)) + def _crc_validate(self): # type: () -> None + data_crc = binascii.crc32( + EspCoreDumpV2Header.build(self.core_src.header) + self.core_src.data) & 0xffffffff # type: ignore + if data_crc != self.core_src.checksum: # type: ignore + raise ESPCoreDumpLoaderError( + 'Invalid core dump CRC %x, should be %x' % (data_crc, self.core_src.crc)) # type: ignore - def _sha256_validate(self): - data_sha256 = hashlib.sha256(EspCoreDumpV2Header.build(self.core_src.header) + self.core_src.data) + def _sha256_validate(self): # type: () -> None + data_sha256 = hashlib.sha256( + EspCoreDumpV2Header.build(self.core_src.header) + self.core_src.data) # type: ignore data_sha256_str = data_sha256.hexdigest() - sha256_str = binascii.hexlify(self.core_src.checksum).decode('ascii') + sha256_str = binascii.hexlify(self.core_src.checksum).decode('ascii') # type: ignore if data_sha256_str != sha256_str: raise ESPCoreDumpLoaderError('Invalid core dump SHA256 "{}", should be "{}"' .format(data_sha256_str, sha256_str)) - def create_corefile(self, exe_name=None): # type: (str) -> None + def create_corefile(self, exe_name=None, e_machine=ESPCoreDumpElfFile.EM_XTENSA): + # type: (Optional[str], int) -> None """ Creates core dump ELF file """ @@ -226,22 +238,21 @@ def create_corefile(self, exe_name=None): # type: (str) -> None if self.dump_ver in [self.ELF_CRC32, self.ELF_SHA256]: - self._extract_elf_corefile(exe_name) + self._extract_elf_corefile(exe_name, e_machine) elif self.dump_ver in [self.BIN_V1, self.BIN_V2]: - self._extract_bin_corefile() + self._extract_bin_corefile(e_machine) else: raise NotImplementedError - def _extract_elf_corefile(self, exe_name=None): + def _extract_elf_corefile(self, exe_name=None, e_machine=ESPCoreDumpElfFile.EM_XTENSA): # type: (str, int) -> None """ Reads the ELF formatted core dump image and parse it """ - self.core_elf_file.write(self.core_src.data) - # Need to be closed before read. Otherwise the result will be wrong - self.core_elf_file.close() + with open(self.core_elf_file, 'wb') as fw: # type: ignore + fw.write(self.core_src.data) # type: ignore - core_elf = ESPCoreDumpElfFile(self.core_elf_file.name) + core_elf = ESPCoreDumpElfFile(self.core_elf_file, e_machine=e_machine) # type: ignore # Read note segments from core file which are belong to tasks (TCB or stack) for seg in core_elf.note_segments: @@ -259,7 +270,7 @@ def _extract_elf_corefile(self, exe_name=None): coredump_sha256 = coredump_sha256_struct.parse(note_sec.desc[:coredump_sha256_struct.sizeof()]) if coredump_sha256.sha256 != app_sha256: raise ESPCoreDumpLoaderError( - 'Invalid application image for coredump: coredump SHA256({}) != app SHA256({}).' + 'Invalid application image for coredump: coredump SHA256({!r}) != app SHA256({!r}).' .format(coredump_sha256, app_sha256)) if coredump_sha256.ver != self.version: raise ESPCoreDumpLoaderError( @@ -267,46 +278,43 @@ def _extract_elf_corefile(self, exe_name=None): .format(coredump_sha256.ver, self.version)) @staticmethod - def _get_aligned_size(size, align_with=4): + def _get_aligned_size(size, align_with=4): # type: (int, int) -> int if size % align_with: return align_with * (size // align_with + 1) return size @staticmethod - def _build_note_section(name, sec_type, desc): - name = bytearray(name, encoding='ascii') + b'\0' - return NoteSection.build({ - 'namesz': len(name), + def _build_note_section(name, sec_type, desc): # type: (str, int, str) -> bytes + b_name = bytearray(name, encoding='ascii') + b'\0' + return NoteSection.build({ # type: ignore + 'namesz': len(b_name), 'descsz': len(desc), 'type': sec_type, - 'name': name, + 'name': b_name, 'desc': desc, }) - def _extract_bin_corefile(self): + def _extract_bin_corefile(self, e_machine=ESPCoreDumpElfFile.EM_XTENSA): # type: (int) -> None """ Creates core dump ELF file """ - tcbsz_aligned = self._get_aligned_size(self.header.tcbsz) - coredump_data_struct = Struct( 'tasks' / GreedyRange( AlignedStruct( 4, 'task_header' / TaskHeader, - 'tcb' / Bytes(self.header.tcbsz), - 'stack' / Bytes(abs_(this.task_header.stack_top - this.task_header.stack_end)), + 'tcb' / Bytes(self.header.tcbsz), # type: ignore + 'stack' / Bytes(abs_(this.task_header.stack_top - this.task_header.stack_end)), # type: ignore ) ), - 'mem_seg_headers' / MemSegmentHeader[self.core_src.header.segs_num] + 'mem_seg_headers' / MemSegmentHeader[self.core_src.header.segs_num] # type: ignore ) - - core_elf = ESPCoreDumpElfFile() + core_elf = ESPCoreDumpElfFile(e_machine=e_machine) notes = b'' core_dump_info_notes = b'' task_info_notes = b'' - coredump_data = coredump_data_struct.parse(self.core_src.data) + coredump_data = coredump_data_struct.parse(self.core_src.data) # type: ignore for i, task in enumerate(coredump_data.tasks): stack_len_aligned = self._get_aligned_size(abs(task.task_header.stack_top - task.task_header.stack_end)) task_status_kwargs = { @@ -314,32 +322,34 @@ def _extract_bin_corefile(self): 'task_flags': TASK_STATUS_CORRECT, 'task_tcb_addr': task.task_header.tcb_addr, 'task_stack_start': min(task.task_header.stack_top, task.task_header.stack_end), + 'task_stack_end': max(task.task_header.stack_top, task.task_header.stack_end), 'task_stack_len': stack_len_aligned, 'task_name': Padding(16).build({}) # currently we don't have task_name, keep it as padding } # Write TCB try: - if self.target_method_cls.tcb_is_sane(task.task_header.tcb_addr, tcbsz_aligned): + if self.target_methods.tcb_is_sane(task.task_header.tcb_addr, self.header.tcbsz): # type: ignore core_elf.add_segment(task.task_header.tcb_addr, task.tcb, ElfFile.PT_LOAD, ElfSegment.PF_R | ElfSegment.PF_W) - elif task.task_header.tcb_addr and self.target_method_cls.addr_is_fake(task.task_header.tcb_addr): + elif task.task_header.tcb_addr and self.target_methods.addr_is_fake(task.task_header.tcb_addr): task_status_kwargs['task_flags'] |= TASK_STATUS_TCB_CORRUPTED except ESPCoreDumpLoaderError as e: logging.warning('Skip TCB {} bytes @ 0x{:x}. (Reason: {})' - .format(tcbsz_aligned, task.task_header.tcb_addr, e)) + .format(self.header.tcbsz, task.task_header.tcb_addr, e)) # type: ignore # Write stack try: - if self.target_method_cls.stack_is_sane(task_status_kwargs['task_stack_start']): + if self.target_methods.stack_is_sane(task_status_kwargs['task_stack_start'], + task_status_kwargs['task_stack_end']): core_elf.add_segment(task_status_kwargs['task_stack_start'], task.stack, ElfFile.PT_LOAD, ElfSegment.PF_R | ElfSegment.PF_W) - elif task_status_kwargs['task_stack_start'] \ - and self.target_method_cls.addr_is_fake(task_status_kwargs['task_stack_start']): + elif (task_status_kwargs['task_stack_start'] + and self.target_methods.addr_is_fake(task_status_kwargs['task_stack_start'])): task_status_kwargs['task_flags'] |= TASK_STATUS_TCB_CORRUPTED core_elf.add_segment(task_status_kwargs['task_stack_start'], task.stack, @@ -355,7 +365,7 @@ def _extract_bin_corefile(self): try: logging.debug('Stack start_end: 0x{:x} @ 0x{:x}' .format(task.task_header.stack_top, task.task_header.stack_end)) - task_regs, extra_regs = self.arch_method_cls.get_registers_from_stack( + task_regs, extra_regs = self.target_methods.get_registers_from_stack( task.stack, task.task_header.stack_end > task.task_header.stack_top ) @@ -367,23 +377,24 @@ def _extract_bin_corefile(self): EspTaskStatus.build(task_status_kwargs)) notes += self._build_note_section('CORE', ElfFile.PT_LOAD, - self.arch_method_cls.build_prstatus_data(task.task_header.tcb_addr, - task_regs)) + self.target_methods.build_prstatus_data(task.task_header.tcb_addr, + task_regs)) - if extra_regs and len(core_dump_info_notes) == 0: - # actually there will be only one such note - for crashed task + if len(core_dump_info_notes) == 0: # the first task is the crashed task core_dump_info_notes += self._build_note_section('ESP_CORE_DUMP_INFO', ESPCoreDumpElfFile.PT_INFO, - Int32ul.build(self.header.ver)) + Int32ul.build(self.header.ver)) # type: ignore + _regs = [task.task_header.tcb_addr] + + # For xtensa, we need to put the exception registers into the extra info as well + if e_machine == ESPCoreDumpElfFile.EM_XTENSA and extra_regs: + for reg_id in extra_regs: + _regs.extend([reg_id, extra_regs[reg_id]]) - exc_regs = [] - for reg_id in extra_regs: - exc_regs.extend([reg_id, extra_regs[reg_id]]) - _regs = [task.task_header.tcb_addr] + exc_regs core_dump_info_notes += self._build_note_section( 'EXTRA_INFO', ESPCoreDumpElfFile.PT_EXTRA_INFO, - Int32ul[1 + len(exc_regs)].build(_regs) + Int32ul[len(_regs)].build(_regs) ) if self.dump_ver == self.BIN_V2: @@ -409,30 +420,29 @@ def _extract_bin_corefile(self): .format(len(task_info_notes), 0, e)) # dump core ELF core_elf.e_type = ElfFile.ET_CORE - core_elf.e_machine = ESPCoreDumpElfFile.EM_XTENSA - core_elf.dump(self.core_elf_file.name) + core_elf.dump(self.core_elf_file) # type: ignore class ESPCoreDumpFlashLoader(EspCoreDumpLoader): ESP_COREDUMP_PART_TABLE_OFF = 0x8000 - def __init__(self, offset, target='esp32', port=None, baud=None): + def __init__(self, offset, target=None, port=None, baud=None): + # type: (int, Optional[str], Optional[str], Optional[int]) -> None super(ESPCoreDumpFlashLoader, self).__init__() self.port = port self.baud = baud - self.target = target - self._get_coredump(offset) - self._reload_coredump() + self._get_core_src(offset, target) + self.target = self._load_core_src() - def _get_coredump(self, off): + def _get_core_src(self, off, target=None): # type: (int, Optional[str]) -> None """ Loads core dump from flash using parttool or elftool (if offset is set) """ try: if off: logging.info('Invoke esptool to read image.') - self._invoke_esptool(off=off) + self._invoke_esptool(off=off, target=target) else: logging.info('Invoke parttool to read image.') self._invoke_parttool() @@ -440,15 +450,14 @@ def _get_coredump(self, off): if e.output: logging.info(e.output) logging.error('Error during the subprocess execution') - else: - # Need to be closed before read. Otherwise the result will be wrong - self.core_src_file.close() - def _invoke_esptool(self, off=None): + def _invoke_esptool(self, off=None, target=None): # type: (Optional[int], Optional[str]) -> None """ Loads core dump from flash using elftool """ - tool_args = [sys.executable, ESPTOOL_PY, '-c', self.target] + if target is None: + target = 'auto' + tool_args = [sys.executable, ESPTOOL_PY, '-c', target] if self.port: tool_args.extend(['-p', self.port]) if self.baud: @@ -466,14 +475,14 @@ def _invoke_esptool(self, off=None): # Here we use V1 format to locate the size tool_args.extend(['read_flash', str(off), str(EspCoreDumpV1Header.sizeof())]) - tool_args.append(self.core_src_file.name) + tool_args.append(self.core_src_file) # type: ignore # read core dump length et_out = subprocess.check_output(tool_args) if et_out: logging.info(et_out.decode('utf-8')) - header = EspCoreDumpV1Header.parse(open(self.core_src_file.name, 'rb').read()) + header = EspCoreDumpV1Header.parse(open(self.core_src_file, 'rb').read()) # type: ignore if not header or not 0 < header.tot_len <= part_size: logging.error('Incorrect size of core dump image: {}, use partition size instead: {}' .format(header.tot_len, part_size)) @@ -492,7 +501,7 @@ def _invoke_esptool(self, off=None): logging.debug(e.output) raise e - def _invoke_parttool(self): + def _invoke_parttool(self): # type: () -> None """ Loads core dump from flash using parttool """ @@ -503,7 +512,7 @@ def _invoke_parttool(self): self.core_src_file = self._create_temp_file() try: - tool_args.append(self.core_src_file.name) + tool_args.append(self.core_src_file) # type: ignore # read core dump partition et_out = subprocess.check_output(tool_args) if et_out: @@ -515,7 +524,7 @@ def _invoke_parttool(self): logging.debug(e.output) raise e - def _get_core_dump_partition_info(self, part_off=None): + def _get_core_dump_partition_info(self, part_off=None): # type: (Optional[int]) -> Tuple[int, int] """ Get core dump partition info using parttool """ @@ -545,28 +554,27 @@ def _get_core_dump_partition_info(self, part_off=None): class ESPCoreDumpFileLoader(EspCoreDumpLoader): - def __init__(self, path, is_b64=False): + def __init__(self, path, is_b64=False): # type: (str, bool) -> None super(ESPCoreDumpFileLoader, self).__init__() self.is_b64 = is_b64 - self._get_coredump(path) - self._reload_coredump() + self._get_core_src(path) + self.target = self._load_core_src() - def _get_coredump(self, path): + def _get_core_src(self, path): # type: (str) -> None """ Loads core dump from (raw binary or base64-encoded) file """ logging.debug('Load core dump from "%s", %s format', path, 'b64' if self.is_b64 else 'raw') if not self.is_b64: - self.core_src_file = open(path, mode='rb') + self.core_src_file = path else: self.core_src_file = self._create_temp_file() - with open(path, 'rb') as fb64: - while True: - line = fb64.readline() - if len(line) == 0: - break - data = base64.standard_b64decode(line.rstrip(b'\r\n')) - self.core_src_file.write(data) - self.core_src_file.flush() - self.core_src_file.seek(0) + with open(self.core_src_file, 'wb') as fw: + with open(path, 'rb') as fb64: + while True: + line = fb64.readline() + if len(line) == 0: + break + data = base64.standard_b64decode(line.rstrip(b'\r\n')) + fw.write(data) # type: ignore diff --git a/components/espcoredump/corefile/riscv.py b/components/espcoredump/corefile/riscv.py new file mode 100644 index 000000000000..bbc83a1c8456 --- /dev/null +++ b/components/espcoredump/corefile/riscv.py @@ -0,0 +1,63 @@ +# +# Copyright 2021 Espressif Systems (Shanghai) CO., LTD +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from construct import Int16ul, Int32ul, Padding, Struct + +from . import BaseArchMethodsMixin, BaseTargetMethods, ESPCoreDumpLoaderError + +try: + from typing import Any, Optional, Tuple +except ImportError: + pass + +RISCV_GP_REGS_COUNT = 32 +PRSTATUS_SIZE = 204 +PRSTATUS_OFFSET_PR_CURSIG = 12 +PRSTATUS_OFFSET_PR_PID = 24 +PRSTATUS_OFFSET_PR_REG = 72 +ELF_GREGSET_T_SIZE = 128 + +PrStruct = Struct( + Padding(PRSTATUS_OFFSET_PR_CURSIG), + 'pr_cursig' / Int16ul, + Padding(PRSTATUS_OFFSET_PR_PID - PRSTATUS_OFFSET_PR_CURSIG - Int16ul.sizeof()), + 'pr_pid' / Int32ul, + Padding(PRSTATUS_OFFSET_PR_REG - PRSTATUS_OFFSET_PR_PID - Int32ul.sizeof()), + 'regs' / Int32ul[RISCV_GP_REGS_COUNT], + Padding(PRSTATUS_SIZE - PRSTATUS_OFFSET_PR_REG - ELF_GREGSET_T_SIZE) +) + + +class RiscvMethodsMixin(BaseArchMethodsMixin): + @staticmethod + def get_registers_from_stack(data, grows_down): + # type: (bytes, bool) -> Tuple[list[int], Optional[dict[int, int]]] + regs = Int32ul[RISCV_GP_REGS_COUNT].parse(data) + if not grows_down: + raise ESPCoreDumpLoaderError('Growing up stacks are not supported for now!') + return regs, None + + @staticmethod + def build_prstatus_data(tcb_addr, task_regs): # type: (int, list[int]) -> Any + return PrStruct.build({ + 'pr_cursig': 0, + 'pr_pid': tcb_addr, + 'regs': task_regs, + }) + + +class Esp32c3Methods(BaseTargetMethods, RiscvMethodsMixin): + TARGET = 'esp32c3' diff --git a/components/espcoredump/corefile/soc_headers/__init__.py b/components/espcoredump/corefile/soc_headers/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/espcoredump/corefile/soc_headers/esp32.py b/components/espcoredump/corefile/soc_headers/esp32.py new file mode 100644 index 000000000000..88953e136b70 --- /dev/null +++ b/components/espcoredump/corefile/soc_headers/esp32.py @@ -0,0 +1,8 @@ +SOC_DRAM_LOW = 0x3ffae000 +SOC_DRAM_HIGH = 0x40000000 +SOC_IRAM_LOW = 0x40080000 +SOC_IRAM_HIGH = 0x400a0000 +SOC_RTC_DRAM_LOW = 0x3ff80000 +SOC_RTC_DRAM_HIGH = 0x3ff82000 +SOC_RTC_DATA_LOW = 0x50000000 +SOC_RTC_DATA_HIGH = 0x50002000 diff --git a/components/espcoredump/corefile/soc_headers/esp32c3.py b/components/espcoredump/corefile/soc_headers/esp32c3.py new file mode 100644 index 000000000000..9f828e296288 --- /dev/null +++ b/components/espcoredump/corefile/soc_headers/esp32c3.py @@ -0,0 +1,8 @@ +SOC_IRAM_LOW = 0x4037c000 +SOC_IRAM_HIGH = 0x403e0000 +SOC_DRAM_LOW = 0x3fc80000 +SOC_DRAM_HIGH = 0x3fce0000 +SOC_RTC_DRAM_LOW = 0x50000000 +SOC_RTC_DRAM_HIGH = 0x50002000 +SOC_RTC_DATA_LOW = 0x50000000 +SOC_RTC_DATA_HIGH = 0x50002000 diff --git a/components/espcoredump/corefile/soc_headers/esp32s2.py b/components/espcoredump/corefile/soc_headers/esp32s2.py new file mode 100644 index 000000000000..521faf2d7c3f --- /dev/null +++ b/components/espcoredump/corefile/soc_headers/esp32s2.py @@ -0,0 +1,8 @@ +SOC_IRAM_LOW = 0x40020000 +SOC_IRAM_HIGH = 0x40070000 +SOC_DRAM_LOW = 0x3ffb0000 +SOC_DRAM_HIGH = 0x40000000 +SOC_RTC_DRAM_LOW = 0x3ff9e000 +SOC_RTC_DRAM_HIGH = 0x3ffa0000 +SOC_RTC_DATA_LOW = 0x50000000 +SOC_RTC_DATA_HIGH = 0x50002000 diff --git a/components/espcoredump/corefile/xtensa.py b/components/espcoredump/corefile/xtensa.py index 10c5fbaed9be..1c038e38193f 100644 --- a/components/espcoredump/corefile/xtensa.py +++ b/components/espcoredump/corefile/xtensa.py @@ -1,5 +1,5 @@ # -# Copyright 2021 Espressif Systems (Shanghai) PTE LTD +# Copyright 2021 Espressif Systems (Shanghai) CO., LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,12 +16,16 @@ from construct import Int16ul, Int32ul, Int64ul, Struct -from . import ESPCoreDumpLoaderError, _ArchMethodsBase, _TargetMethodsBase +from . import BaseArchMethodsMixin, BaseTargetMethods, ESPCoreDumpLoaderError + +try: + from typing import Any, Optional, Tuple +except ImportError: + pass INVALID_CAUSE_VALUE = 0xFFFF XCHAL_EXCCAUSE_NUM = 64 - # Exception cause dictionary to get translation of exccause register # From 4.4.1.5 table 4-64 Exception Causes of Xtensa # Instruction Set Architecture (ISA) Reference Manual @@ -81,7 +85,7 @@ } -class XtensaRegisters(object): +class ExceptionRegisters(object): # extra regs IDs used in EXTRA_INFO note EXCCAUSE_IDX = 0 EXCVADDR_IDX = 1 @@ -100,14 +104,14 @@ class XtensaRegisters(object): EPS7_IDX = 199 @property - def registers(self): + def registers(self): # type: () -> dict[str, int] return {k: v for k, v in self.__class__.__dict__.items() if not k.startswith('__') and isinstance(v, int)} # Following structs are based on source code # IDF_PATH/components/espcoredump/src/core_dump_port.c -XtensaPrStatus = Struct( +PrStatus = Struct( 'si_signo' / Int32ul, 'si_code' / Int32ul, 'si_errno' / Int32ul, @@ -126,28 +130,28 @@ def registers(self): ) -def print_exc_regs_info(extra_info): +def print_exc_regs_info(extra_info): # type: (list[int]) -> None """ Print the register info by parsing extra_info :param extra_info: extra info data str :return: None """ - exccause = extra_info[1 + 2 * XtensaRegisters.EXCCAUSE_IDX + 1] + exccause = extra_info[1 + 2 * ExceptionRegisters.EXCCAUSE_IDX + 1] exccause_str = XTENSA_EXCEPTION_CAUSE_DICT.get(exccause) if not exccause_str: exccause_str = ('Invalid EXCCAUSE code', 'Invalid EXCAUSE description or not found.') print('exccause 0x%x (%s)' % (exccause, exccause_str[0])) - print('excvaddr 0x%x' % extra_info[1 + 2 * XtensaRegisters.EXCVADDR_IDX + 1]) + print('excvaddr 0x%x' % extra_info[1 + 2 * ExceptionRegisters.EXCVADDR_IDX + 1]) # skip crashed_task_tcb, exccause, and excvaddr for i in range(5, len(extra_info), 2): - if (extra_info[i] >= XtensaRegisters.EPC1_IDX and extra_info[i] <= XtensaRegisters.EPC7_IDX): - print('epc%d 0x%x' % ((extra_info[i] - XtensaRegisters.EPC1_IDX + 1), extra_info[i + 1])) + if (extra_info[i] >= ExceptionRegisters.EPC1_IDX and extra_info[i] <= ExceptionRegisters.EPC7_IDX): + print('epc%d 0x%x' % ((extra_info[i] - ExceptionRegisters.EPC1_IDX + 1), extra_info[i + 1])) # skip crashed_task_tcb, exccause, and excvaddr for i in range(5, len(extra_info), 2): - if (extra_info[i] >= XtensaRegisters.EPS2_IDX and extra_info[i] <= XtensaRegisters.EPS7_IDX): - print('eps%d 0x%x' % ((extra_info[i] - XtensaRegisters.EPS2_IDX + 2), extra_info[i + 1])) + if (extra_info[i] >= ExceptionRegisters.EPS2_IDX and extra_info[i] <= ExceptionRegisters.EPS7_IDX): + print('eps%d 0x%x' % ((extra_info[i] - ExceptionRegisters.EPS2_IDX + 2), extra_info[i + 1])) # from "gdb/xtensa-tdep.h" @@ -200,24 +204,11 @@ def print_exc_regs_info(extra_info): XT_STK_FRMSZ = 25 -class _TargetMethodsESP32(_TargetMethodsBase): - @staticmethod - def tcb_is_sane(tcb_addr, tcb_size): - return not (tcb_addr < 0x3ffae000 or (tcb_addr + tcb_size) > 0x40000000) - - @staticmethod - def stack_is_sane(sp): - return not (sp < 0x3ffae010 or sp > 0x3fffffff) - - @staticmethod - def addr_is_fake(addr): - return (0x20000000 <= addr < 0x3f3fffff) or addr >= 0x80000000 - - -class _ArchMethodsXtensa(_ArchMethodsBase): +class XtensaMethodsMixin(BaseArchMethodsMixin): @staticmethod def get_registers_from_stack(data, grows_down): - extra_regs = {v: 0 for v in XtensaRegisters().registers.values()} + # type: (bytes, bool) -> Tuple[list[int], Optional[dict[int, int]]] + extra_regs = {v: 0 for v in ExceptionRegisters().registers.values()} regs = [0] * REG_NUM # TODO: support for growing up stacks if not grows_down: @@ -245,10 +236,10 @@ def get_registers_from_stack(data, grows_down): if regs[REG_PS_IDX] & (1 << 5): regs[REG_PS_IDX] &= ~(1 << 4) if stack[XT_STK_EXCCAUSE] in XTENSA_EXCEPTION_CAUSE_DICT: - extra_regs[XtensaRegisters.EXCCAUSE_IDX] = stack[XT_STK_EXCCAUSE] + extra_regs[ExceptionRegisters.EXCCAUSE_IDX] = stack[XT_STK_EXCCAUSE] else: - extra_regs[XtensaRegisters.EXCCAUSE_IDX] = INVALID_CAUSE_VALUE - extra_regs[XtensaRegisters.EXCVADDR_IDX] = stack[XT_STK_EXCVADDR] + extra_regs[ExceptionRegisters.EXCCAUSE_IDX] = INVALID_CAUSE_VALUE + extra_regs[ExceptionRegisters.EXCVADDR_IDX] = stack[XT_STK_EXCVADDR] else: regs[REG_PC_IDX] = stack[XT_SOL_PC] regs[REG_PS_IDX] = stack[XT_SOL_PS] @@ -258,8 +249,8 @@ def get_registers_from_stack(data, grows_down): return regs, extra_regs @staticmethod - def build_prstatus_data(tcb_addr, task_regs): - return XtensaPrStatus.build({ + def build_prstatus_data(tcb_addr, task_regs): # type: (int, list[int]) -> Any + return PrStatus.build({ 'si_signo': 0, 'si_code': 0, 'si_errno': 0, @@ -276,3 +267,11 @@ def build_prstatus_data(tcb_addr, task_regs): 'pr_cutime': 0, 'pr_cstime': 0, }) + Int32ul[len(task_regs)].build(task_regs) + + +class Esp32Methods(BaseTargetMethods, XtensaMethodsMixin): + TARGET = 'esp32' + + +class Esp32S2Methods(BaseTargetMethods, XtensaMethodsMixin): + TARGET = 'esp32s2' diff --git a/components/espcoredump/espcoredump.py b/components/espcoredump/espcoredump.py index 00192650405c..fecb8370aa12 100755 --- a/components/espcoredump/espcoredump.py +++ b/components/espcoredump/espcoredump.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# ESP32 core dump Utility +# ESP-IDF Core Dump Utility import argparse import logging @@ -10,7 +10,7 @@ from shutil import copyfile from construct import GreedyRange, Int32ul, Struct -from corefile import __version__, xtensa +from corefile import RISCV_TARGETS, SUPPORTED_TARGETS, XTENSA_TARGETS, __version__, xtensa from corefile.elf import TASK_STATUS_CORRECT, ElfFile, ElfSegment, ESPCoreDumpElfFile, EspTaskStatus from corefile.gdb import EspGDB from corefile.loader import ESPCoreDumpFileLoader, ESPCoreDumpFlashLoader @@ -28,32 +28,40 @@ sys.stderr.write('esptool is not found!\n') sys.exit(2) +try: + from typing import Optional, Tuple +except ImportError: + pass + if os.name == 'nt': CLOSE_FDS = False else: CLOSE_FDS = True -def load_aux_elf(elf_path): # type: (str) -> (ElfFile, str) +def load_aux_elf(elf_path): # type: (str) -> str """ Loads auxiliary ELF file and composes GDB command to read its symbols. """ - elf = None sym_cmd = '' if os.path.exists(elf_path): elf = ElfFile(elf_path) for s in elf.sections: if s.name == '.text': sym_cmd = 'add-symbol-file %s 0x%x' % (elf_path, s.addr) - return elf, sym_cmd + return sym_cmd -def core_prepare(): +def get_core_dump_elf(e_machine=ESPCoreDumpFileLoader.ESP32): + # type: (int) -> Tuple[str, Optional[str], Optional[list[str]]] loader = None core_filename = None + target = None + temp_files = None + if not args.core: # Core file not specified, try to read core dump from flash. - loader = ESPCoreDumpFlashLoader(args.off, port=args.port, baud=args.baud) + loader = ESPCoreDumpFlashLoader(args.off, args.chip, port=args.port, baud=args.baud) elif args.core_format != 'elf': # Core file specified, but not yet in ELF format. Convert it from raw or base64 into ELF. loader = ESPCoreDumpFileLoader(args.core, args.core_format == 'b64') @@ -63,51 +71,86 @@ def core_prepare(): # Load/convert the core file if loader: - loader.create_corefile(exe_name=args.prog) - core_filename = loader.core_elf_file.name + loader.create_corefile(exe_name=args.prog, e_machine=e_machine) + core_filename = loader.core_elf_file if args.save_core: # We got asked to save the core file, make a copy - copyfile(loader.core_elf_file.name, args.save_core) + copyfile(loader.core_elf_file, args.save_core) + target = loader.target + temp_files = loader.temp_files + + return core_filename, target, temp_files # type: ignore + + +def get_target(): # type: () -> str + if args.chip != 'auto': + return args.chip # type: ignore + + inst = esptool.ESPLoader.detect_chip(args.port, args.baud) + return inst.CHIP_NAME.lower().replace('-', '') # type: ignore + + +def get_gdb_path(target=None): # type: (Optional[str]) -> str + if args.gdb: + return args.gdb # type: ignore + + if target is None: + target = get_target() + + if target in XTENSA_TARGETS: + # For some reason, xtensa-esp32s2-elf-gdb will report some issue. + # Use xtensa-esp32-elf-gdb instead. + return 'xtensa-esp32-elf-gdb' + if target in RISCV_TARGETS: + return 'riscv32-esp-elf-gdb' + raise ValueError('Invalid value: {}. For now we only support {}'.format(target, SUPPORTED_TARGETS)) - return core_filename, loader +def get_rom_elf_path(target=None): # type: (Optional[str]) -> str + if args.rom_elf: + return args.rom_elf # type: ignore -def dbg_corefile(): + if target is None: + target = get_target() + + return '{}_rom.elf'.format(target) + + +def dbg_corefile(): # type: () -> Optional[list[str]] """ Command to load core dump from file or flash and run GDB debug session with it """ - rom_elf, rom_sym_cmd = load_aux_elf(args.rom_elf) - core_filename, loader = core_prepare() + exe_elf = ESPCoreDumpElfFile(args.prog) + core_elf_path, target, temp_files = get_core_dump_elf(e_machine=exe_elf.e_machine) + rom_elf_path = get_rom_elf_path(target) + rom_sym_cmd = load_aux_elf(rom_elf_path) + + gdb_tool = get_gdb_path(target) p = subprocess.Popen(bufsize=0, - args=[args.gdb, + args=[gdb_tool, '--nw', # ignore .gdbinit - '--core=%s' % core_filename, # core file, + '--core=%s' % core_elf_path, # core file, '-ex', rom_sym_cmd, args.prog], stdin=None, stdout=None, stderr=None, close_fds=CLOSE_FDS) p.wait() print('Done!') + return temp_files -def info_corefile(): +def info_corefile(): # type: () -> Optional[list[str]] """ Command to load core dump from file or flash and print it's data in user friendly form """ - core_filename, loader = core_prepare() - - exe_elf = ElfFile(args.prog) - core_elf = ESPCoreDumpElfFile(core_filename) + exe_elf = ESPCoreDumpElfFile(args.prog) + core_elf_path, target, temp_files = get_core_dump_elf(e_machine=exe_elf.e_machine) + core_elf = ESPCoreDumpElfFile(core_elf_path) if exe_elf.e_machine != core_elf.e_machine: raise ValueError('The arch should be the same between core elf and exe elf') - if core_elf.e_machine == ESPCoreDumpElfFile.EM_XTENSA: - exception_registers_info = xtensa.print_exc_regs_info - else: - raise NotImplementedError - extra_note = None task_info = [] for seg in core_elf.note_segments: @@ -119,8 +162,11 @@ def info_corefile(): task_info.append(task_info_struct) print('===============================================================') print('==================== ESP32 CORE DUMP START ====================') - rom_elf, rom_sym_cmd = load_aux_elf(args.rom_elf) - gdb = EspGDB(args.gdb, [rom_sym_cmd], core_filename, args.prog, timeout_sec=args.gdb_timeout_sec) + rom_elf_path = get_rom_elf_path(target) + rom_sym_cmd = load_aux_elf(rom_elf_path) + + gdb_tool = get_gdb_path(target) + gdb = EspGDB(gdb_tool, [rom_sym_cmd], core_elf_path, args.prog, timeout_sec=args.gdb_timeout_sec) extra_info = None if extra_note: @@ -132,10 +178,12 @@ def info_corefile(): task_name = gdb.get_freertos_task_name(marker) print("\nCrashed task handle: 0x%x, name: '%s', GDB name: 'process %d'" % (marker, task_name, marker)) print('\n================== CURRENT THREAD REGISTERS ===================') - if extra_note and extra_info: - exception_registers_info(extra_info) - else: - print('Exception registers have not been found!') + # Only xtensa have exception registers + if exe_elf.e_machine == ESPCoreDumpElfFile.EM_XTENSA: + if extra_note and extra_info: + xtensa.print_exc_regs_info(extra_info) + else: + print('Exception registers have not been found!') print(gdb.run_cmd('info registers')) print('\n==================== CURRENT THREAD STACK =====================') print(gdb.run_cmd('bt')) @@ -235,10 +283,14 @@ def info_corefile(): del gdb print('Done!') + return temp_files if __name__ == '__main__': parser = argparse.ArgumentParser(description='espcoredump.py v%s - ESP32 Core Dump Utility' % __version__) + parser.add_argument('--chip', default=os.environ.get('ESPTOOL_CHIP', 'auto'), + choices=['auto'] + SUPPORTED_TARGETS, + help='Target chip type') parser.add_argument('--port', '-p', default=os.environ.get('ESPTOOL_PORT', esptool.ESPLoader.DEFAULT_PORT), help='Serial port device') parser.add_argument('--baud', '-b', type=int, @@ -250,20 +302,20 @@ def info_corefile(): common_args = argparse.ArgumentParser(add_help=False) common_args.add_argument('--debug', '-d', type=int, default=3, help='Log level (0..3)') - common_args.add_argument('--gdb', '-g', default='xtensa-esp32-elf-gdb', + common_args.add_argument('--gdb', '-g', help='Path to gdb') common_args.add_argument('--core', '-c', help='Path to core dump file (if skipped core dump will be read from flash)') common_args.add_argument('--core-format', '-t', choices=['b64', 'elf', 'raw'], default='elf', - help='(elf, raw or b64). File specified with "-c" is an ELF ("elf"), ' + help='File specified with "-c" is an ELF ("elf"), ' 'raw (raw) or base64-encoded (b64) binary') common_args.add_argument('--off', '-o', type=int, help='Offset of coredump partition in flash (type "make partition_table" to see).') common_args.add_argument('--save-core', '-s', help='Save core to file. Otherwise temporary core file will be deleted. ' 'Does not work with "-c"', ) - common_args.add_argument('--rom-elf', '-r', default='esp32_rom.elf', - help='Path to ROM ELF file.') + common_args.add_argument('--rom-elf', '-r', + help='Path to ROM ELF file. Will use "_rom.elf" if not specified') common_args.add_argument('prog', help='Path to program\'s ELF binary') operations = parser.add_subparsers(dest='operation') @@ -291,9 +343,18 @@ def info_corefile(): logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level) print('espcoredump.py v%s' % __version__) - if args.operation == 'info_corefile': - info_corefile() - elif args.operation == 'dbg_corefile': - dbg_corefile() - else: - raise ValueError('Please specify action, should be info_corefile or dbg_corefile') + temp_core_files = None + try: + if args.operation == 'info_corefile': + temp_core_files = info_corefile() + elif args.operation == 'dbg_corefile': + temp_core_files = dbg_corefile() + else: + raise ValueError('Please specify action, should be info_corefile or dbg_corefile') + finally: + if temp_core_files: + for f in temp_core_files: + try: + os.remove(f) + except OSError: + pass diff --git a/components/espcoredump/include/esp_core_dump.h b/components/espcoredump/include/esp_core_dump.h index 7854d4a51d77..40fd90d8b26c 100644 --- a/components/espcoredump/include/esp_core_dump.h +++ b/components/espcoredump/include/esp_core_dump.h @@ -14,14 +14,36 @@ #ifndef ESP_CORE_DUMP_H_ #define ESP_CORE_DUMP_H_ +#include "sdkconfig.h" #include #include "esp_err.h" #include "esp_private/panic_internal.h" +#include "esp_core_dump_summary_port.h" #ifdef __cplusplus extern "C" { #endif +#define APP_ELF_SHA256_SZ (CONFIG_APP_RETRIEVE_LEN_ELF_SHA + 1) + +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +/** + * @brief Core dump summary, Most meaningful contents of the core dump + * are accommodated in this structure + */ +typedef struct { + uint32_t exc_tcb; /*!< TCB pointer to the task causing exception */ + char exc_task[16]; /*!< Name of the task that caused exception */ + uint32_t exc_pc; /*!< Program counter for exception */ + esp_core_dump_bt_info_t exc_bt_info; /*!< Backtrace information for task causing exception */ + uint32_t core_dump_version; /*!< Core dump version */ + uint8_t app_elf_sha256[APP_ELF_SHA256_SZ]; /*!< Crashing application's SHA256 sum as a string */ + esp_core_dump_summary_extra_info_t ex_info; /*!< Architecture specific extra data */ +} esp_core_dump_summary_t; + +#endif /* CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + /**************************************************************************************/ /******************************** EXCEPTION MODE API **********************************/ /**************************************************************************************/ @@ -111,6 +133,32 @@ esp_err_t esp_core_dump_image_get(size_t* out_addr, size_t *out_size); */ esp_err_t esp_core_dump_image_erase(void); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +/** + * @brief Get the summary of a core dump. + * + * @param summary Summary of the core dump + * + * @return ESP_OK on success, otherwise \see esp_err_t + * + * @note This function works only if coredump is stored in flash and in ELF format + * + * Example usage: + * @code{c} + * esp_core_dump_summary_t *summary = malloc(sizeof(esp_core_dump_summary_t)); + * if (summary) { + * if (esp_core_dump_get_summary(summary) == ESP_OK) { + * // Do stuff + * } + * } + * free(summary); + * @endcode + */ +esp_err_t esp_core_dump_get_summary(esp_core_dump_summary_t *summary); + +#endif /* CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + #ifdef __cplusplus } #endif diff --git a/components/espcoredump/include/port/riscv/esp_core_dump_summary_port.h b/components/espcoredump/include/port/riscv/esp_core_dump_summary_port.h new file mode 100644 index 000000000000..f2b5d0d9e618 --- /dev/null +++ b/components/espcoredump/include/port/riscv/esp_core_dump_summary_port.h @@ -0,0 +1,55 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once +#include "sdkconfig.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +/** + * @brief Backtrace information + * + * For RISCV, backtrace cannot be generated on device without including and parsing + * DWARF sections. Including these sections would increase the binary size so provide + * the stackdump that can be later used to generate backtrace with the help of GDB or by parsing the ELF file + * on the host machine + */ +typedef struct { + uint8_t stackdump[CONFIG_ESP_COREDUMP_SUMMARY_STACKDUMP_SIZE]; /*!< Stack dump of the crashing task. */ + uint32_t dump_size; /*!< Size (in bytes) of the stack dump */ +} esp_core_dump_bt_info_t; + +/** + * @brief RISC-V architecture specific extra information + */ +typedef struct { + uint32_t mstatus; /* Machine Status */ + uint32_t mtvec; /* Machine Trap-Vector Base Address */ + uint32_t mcause; /* Machine Trap Cause */ + uint32_t mtval; /* Machine Trap Value */ + uint32_t ra; /* Return Address */ + uint32_t sp; /* Stack pointer */ + uint32_t exc_a[8]; /* A0-A7 registers when the exception caused */ +} esp_core_dump_summary_extra_info_t; + +#endif /* CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + +#ifdef __cplusplus +} +#endif diff --git a/components/espcoredump/include/port/xtensa/esp_core_dump_summary_port.h b/components/espcoredump/include/port/xtensa/esp_core_dump_summary_port.h new file mode 100644 index 000000000000..815c1fff702b --- /dev/null +++ b/components/espcoredump/include/port/xtensa/esp_core_dump_summary_port.h @@ -0,0 +1,54 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once +#include "sdkconfig.h" +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +#define EPCx_REGISTER_COUNT XCHAL_NUM_INTLEVELS + +/** + * @brief Backtrace information. + * + * For Xtensa, backtrace can be generated on device due to windowed register ABI. + */ +typedef struct { + uint32_t bt[16]; /*!< Backtrace (array of PC) */ + uint32_t depth; /*!< Number of backtrace entries */ + bool corrupted; /*!< Status flag for backtrace is corrupt or not */ +} esp_core_dump_bt_info_t; + +/** + * @brief Xtensa architecture specific extra information + */ +typedef struct { + uint32_t exc_cause; /*!< Cause of exception */ + uint32_t exc_vaddr; /*!< Virtual address of exception */ + uint32_t exc_a[16]; /*!< a register set when the exception caused */ + uint32_t epcx[EPCx_REGISTER_COUNT]; /*!< PC register address at exception level(1 to 7) */ + uint8_t epcx_reg_bits; /*!< Bit mask of available EPCx registers */ +} esp_core_dump_summary_extra_info_t; + +#endif /* CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + +#ifdef __cplusplus +} +#endif diff --git a/components/espcoredump/include_core_dump/esp_core_dump_port.h b/components/espcoredump/include_core_dump/esp_core_dump_port.h index 1dd6cd7ab9a6..b99beb32ecd0 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_port.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_port.h @@ -24,12 +24,14 @@ * both Xtensa and RISC-V architecture. */ +#include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "soc/cpu.h" #include "esp_debug_helpers.h" #include "esp_app_format.h" #include "esp_core_dump_types.h" #include "esp_core_dump_port_impl.h" +#include "esp_core_dump.h" #ifdef __cplusplus extern "C" { @@ -164,6 +166,36 @@ void esp_core_dump_port_set_crashed_tcb(uint32_t handle); */ uint32_t esp_core_dump_get_extra_info(void **info); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +/** + * @brief Parse extra information into summary + * + * @param summary Pointer to core dump summary structure + * @param ei_data Pointer to data of EXTRA_INFO note read from flash + */ +void esp_core_dump_summary_parse_extra_info(esp_core_dump_summary_t *summary, void *ei_data); + +/** + * @brief Parse exception registers into summary + * + * @param summary Pointer to core dump summary structure + * @param stack_data Pointer to data of crashed task's stack read from flash + */ +void esp_core_dump_summary_parse_exc_regs(esp_core_dump_summary_t *summary, void *stack_data); + +/** + * @brief Parse backtrace into bt_info + * + * @param bt_info Pointer to store backtrace info + * @param vaddr Pointer to crashed task's stack vaddr + * @param paddr Pointe to crashed task's stack paddr + * @param stack_size Stack size + */ +void esp_core_dump_summary_parse_backtrace_info(esp_core_dump_bt_info_t *bt_info, const void *vaddr, + const void *paddr, uint32_t stack_size); +#endif /* CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + #ifdef __cplusplus } #endif diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index 5c6bf1eb85c4..58bd691ecf03 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -15,6 +15,8 @@ #include "esp_attr.h" #include "esp_partition.h" #include "esp_ota_ops.h" +#include "esp_spi_flash.h" +#include "esp_flash_encrypt.h" #include "sdkconfig.h" #include "core_dump_checksum.h" #include "core_dump_elf.h" @@ -644,4 +646,135 @@ esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg) return err; } +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH + +/* Below are the helper function to parse the core dump ELF stored in flash */ + +static esp_err_t elf_core_dump_image_mmap(spi_flash_mmap_handle_t* core_data_handle, const void **map_addr) +{ + size_t out_size; + assert (core_data_handle); + assert(map_addr); + + /* Find the partition that could potentially contain a (previous) core dump. */ + const esp_partition_t *core_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_DATA_COREDUMP, + NULL); + if (!core_part) { + ESP_COREDUMP_LOGE("Core dump partition not found!"); + return ESP_ERR_NOT_FOUND; + } + if (core_part->size < sizeof(uint32_t)) { + ESP_COREDUMP_LOGE("Core dump partition too small!"); + return ESP_ERR_INVALID_SIZE; + } + /* Data read from the mmapped core dump partition will be garbage if flash + * encryption is enabled in hardware and core dump partition is not encrypted + */ + if (esp_flash_encryption_enabled() && !core_part->encrypted) { + ESP_COREDUMP_LOGE("Flash encryption enabled in hardware and core dump partition is not encrypted!"); + return ESP_ERR_NOT_SUPPORTED; + } + /* Read the size of the core dump file from the partition */ + esp_err_t ret = esp_partition_read(core_part, 0, &out_size, sizeof(uint32_t)); + if (ret != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to read core dump data size"); + return ret; + } + /* map the full core dump parition, including the checksum. */ + return esp_partition_mmap(core_part, 0, out_size, SPI_FLASH_MMAP_DATA, + map_addr, core_data_handle); +} + +static void elf_parse_version_info(esp_core_dump_summary_t *summary, void *data) +{ + core_dump_elf_version_info_t *version = (core_dump_elf_version_info_t *)data; + summary->core_dump_version = version->version; + memcpy(summary->app_elf_sha256, version->app_elf_sha256, ELF_APP_SHA256_SIZE); + ESP_COREDUMP_LOGD("Core dump version 0x%x", summary->core_dump_version); + ESP_COREDUMP_LOGD("App ELF SHA2 %s", (char *)summary->app_elf_sha256); +} + +static void elf_parse_exc_task_name(esp_core_dump_summary_t *summary, void *tcb_data) +{ + StaticTask_t *tcb = (StaticTask_t *) tcb_data; + /* An ugly way to get the task name. We could possibly use pcTaskGetTaskName here. + * But that has assumption that TCB pointer can be used as TaskHandle. So let's + * keep it this way. */ + memset(summary->exc_task, 0, sizeof(summary->exc_task)); + strlcpy(summary->exc_task, (char *)tcb->ucDummy7, sizeof(summary->exc_task)); + ESP_COREDUMP_LOGD("Crashing task %s", summary->exc_task); +} + +esp_err_t esp_core_dump_get_summary(esp_core_dump_summary_t *summary) +{ + int i; + elf_phdr *ph; + elf_note *note; + const void *map_addr; + size_t consumed_note_sz; + spi_flash_mmap_handle_t core_data_handle; + + if (!summary) { + return ESP_ERR_INVALID_ARG; + } + esp_err_t err = elf_core_dump_image_mmap(&core_data_handle, &map_addr); + if (err != ESP_OK) { + return err; + } + uint8_t *ptr = (uint8_t *) map_addr + sizeof(core_dump_header_t); + elfhdr *eh = (elfhdr *)ptr; + + ESP_COREDUMP_LOGD("ELF ident %02x %c %c %c", eh->e_ident[0], eh->e_ident[1], eh->e_ident[2], eh->e_ident[3]); + ESP_COREDUMP_LOGD("Ph_num %d offset %x", eh->e_phnum, eh->e_phoff); + + for (i = 0; i < eh->e_phnum; i++) { + ph = (elf_phdr *)((ptr + i * sizeof(*ph)) + eh->e_phoff); + ESP_COREDUMP_LOGD("PHDR type %d off %x vaddr %x paddr %x filesz %x memsz %x flags %x align %x", + ph->p_type, ph->p_offset, ph->p_vaddr, ph->p_paddr, ph->p_filesz, ph->p_memsz, + ph->p_flags, ph->p_align); + if (ph->p_type == PT_NOTE) { + consumed_note_sz = 0; + while(consumed_note_sz < ph->p_memsz) { + note = (elf_note *)(ptr + ph->p_offset + consumed_note_sz); + char *nm = (char *)(ptr + ph->p_offset + consumed_note_sz + sizeof(elf_note)); + ESP_COREDUMP_LOGD("Note NameSZ %x DescSZ %x Type %x name %s", note->n_namesz, + note->n_descsz, note->n_type, nm); + if (strncmp(nm, "EXTRA_INFO", note->n_namesz) == 0 ) { + esp_core_dump_summary_parse_extra_info(summary, (void *)(nm + note->n_namesz)); + } + if (strncmp(nm, "ESP_CORE_DUMP_INFO", note->n_namesz) == 0 ) { + elf_parse_version_info(summary, (void *)(nm + note->n_namesz)); + } + consumed_note_sz += note->n_namesz + note->n_descsz + sizeof(elf_note); + ALIGN(4, consumed_note_sz); + } + } + } + /* Following code assumes that task stack segment follows the TCB segment for the respective task. + * In general ELF does not impose any restrictions on segments' order so this can be changed without impacting core dump version. + * More universal and flexible way would be to retrieve stack start address from crashed task TCB segment and then look for the stack segment with that address. + */ + int flag = 0; + for (i = 0; i < eh->e_phnum; i++) { + ph = (elf_phdr *)((ptr + i * sizeof(*ph)) + eh->e_phoff); + if (ph->p_type == PT_LOAD) { + if (flag) { + esp_core_dump_summary_parse_exc_regs(summary, (void *)(ptr + ph->p_offset)); + esp_core_dump_summary_parse_backtrace_info(&summary->exc_bt_info, (void *) ph->p_vaddr, + (void *)(ptr + ph->p_offset), ph->p_memsz); + break; + } + if (ph->p_vaddr == summary->exc_tcb) { + elf_parse_exc_task_name(summary, (void *)(ptr + ph->p_offset)); + flag = 1; + } + } + } + spi_flash_munmap(core_data_handle); + return ESP_OK; +} + +#endif // CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH + #endif //CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF diff --git a/components/espcoredump/src/port/riscv/core_dump_port.c b/components/espcoredump/src/port/riscv/core_dump_port.c index cbe20e0d4ed4..3336cbbc37b4 100644 --- a/components/espcoredump/src/port/riscv/core_dump_port.c +++ b/components/espcoredump/src/port/riscv/core_dump_port.c @@ -115,7 +115,7 @@ typedef union { /* We can determine the padding thank to the previous macros */ #define PRSTATUS_SIG_PADDING (PRSTATUS_OFFSET_PR_CURSIG) -#define PRSTATUS_PID_PADDING (PRSTATUS_OFFSET_PR_PID - PRSTATUS_OFFSET_PR_CURSIG - sizeof(uint32_t)) +#define PRSTATUS_PID_PADDING (PRSTATUS_OFFSET_PR_PID - PRSTATUS_OFFSET_PR_CURSIG - sizeof(uint16_t)) #define PRSTATUS_REG_PADDING (PRSTATUS_OFFSET_PR_REG - PRSTATUS_OFFSET_PR_PID - sizeof(uint32_t)) #define PRSTATUS_END_PADDING (PRSTATUS_SIZE - PRSTATUS_OFFSET_PR_REG - ELF_GREGSET_T_SIZE) @@ -381,4 +381,74 @@ uint32_t esp_core_dump_get_extra_info(void **info) return size; } +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +void esp_core_dump_summary_parse_extra_info(esp_core_dump_summary_t *summary, void *ei_data) +{ + riscv_extra_info_t *ei = (riscv_extra_info_t *)ei_data; + summary->exc_tcb = ei->crashed_task_tcb; + ESP_COREDUMP_LOGD("Crash TCB 0x%x", summary->exc_tcb); +} + +void esp_core_dump_summary_parse_exc_regs(esp_core_dump_summary_t *summary, void *stack_data) +{ + int i; + long *a_reg; + RvExcFrame *stack = (RvExcFrame *)stack_data; + summary->exc_pc = stack->mepc; + ESP_COREDUMP_LOGD("Crashing PC 0x%x", summary->exc_pc); + + summary->ex_info.mstatus = stack->mstatus; + summary->ex_info.mtvec = stack->mtvec; + summary->ex_info.mcause = stack->mcause; + summary->ex_info.mtval = stack->mtval; + summary->ex_info.ra = stack->ra; + summary->ex_info.sp = stack->sp; + ESP_COREDUMP_LOGD("mstatus:0x%x mtvec:0x%x mcause:0x%x mval:0x%x RA: 0x%x SP: 0x%x", + stack->mstatus, stack->mtvec, stack->mcause, stack->mtval, stack->ra, stack->sp); + a_reg = &stack->a0; + for (i = 0; i < 8; i++) { + summary->ex_info.exc_a[i] = a_reg[i]; + ESP_COREDUMP_LOGD("A[%d] 0x%x", i, summary->ex_info.exc_a[i]); + } +} + +void esp_core_dump_summary_parse_backtrace_info(esp_core_dump_bt_info_t *bt_info, const void *vaddr, + const void *paddr, uint32_t stack_size) +{ + if (!vaddr || !paddr || !bt_info) { + bt_info->dump_size = 0; + return; + } + + /* Check whether the stack is a fake stack created during coredump generation + * If its a fake stack, we don't have any actual stack dump + */ + if (vaddr >= COREDUMP_FAKE_STACK_START && vaddr < COREDUMP_FAKE_STACK_LIMIT) { + bt_info->dump_size = 0; + return; + } + + /* Top of the stack consists of the context registers saved after crash, + * extract the value of stack pointer (SP) at the time of crash + */ + RvExcFrame *stack = (RvExcFrame *) paddr; + uint32_t *sp = (uint32_t *)stack->sp; + + /* vaddr is actual stack address when crash occurred. However that stack is now saved + * in the flash at a different location. Hence, we need to adjust the offset + * to point to correct data in the flash */ + int offset = (uint32_t)stack - (uint32_t)vaddr; + + // Skip the context saved register frame + uint32_t regframe_size = (uint32_t)sp - (uint32_t)vaddr; + + uint32_t dump_size = MIN(stack_size - regframe_size, CONFIG_ESP_COREDUMP_SUMMARY_STACKDUMP_SIZE); + + memcpy(&bt_info->stackdump[0], (uint8_t *)sp + offset, dump_size); + bt_info->dump_size = dump_size; +} + +#endif /* #if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + #endif diff --git a/components/espcoredump/src/port/xtensa/core_dump_port.c b/components/espcoredump/src/port/xtensa/core_dump_port.c index deb7f313b9d4..47c038565400 100644 --- a/components/espcoredump/src/port/xtensa/core_dump_port.c +++ b/components/espcoredump/src/port/xtensa/core_dump_port.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /** * @file @@ -26,6 +18,7 @@ #include "esp_rom_sys.h" #include "esp_core_dump_common.h" #include "esp_core_dump_port.h" +#include "esp_debug_helpers.h" const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_port"; @@ -472,4 +465,99 @@ uint32_t esp_core_dump_get_extra_info(void **info) return sizeof(s_extra_info); } +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + +void esp_core_dump_summary_parse_extra_info(esp_core_dump_summary_t *summary, void *ei_data) +{ + int i; + xtensa_extra_info_t *ei = (xtensa_extra_info_t *) ei_data; + summary->exc_tcb = ei->crashed_task_tcb; + summary->ex_info.exc_vaddr = ei->excvaddr.reg_val; + summary->ex_info.exc_cause = ei->exccause.reg_val; + ESP_COREDUMP_LOGD("Crash TCB 0x%x", summary->exc_tcb); + ESP_COREDUMP_LOGD("excvaddr 0x%x", summary->ex_info.exc_vaddr); + ESP_COREDUMP_LOGD("exccause 0x%x", summary->ex_info.exc_cause); + + memset(summary->ex_info.epcx, 0, sizeof(summary->ex_info.epcx)); + summary->ex_info.epcx_reg_bits = 0; + for (i = 0; i < COREDUMP_EXTRA_REG_NUM; i++ ) { + if (ei->extra_regs[i].reg_index >= EPC_1 + && ei->extra_regs[i].reg_index < (EPC_1 + XCHAL_NUM_INTLEVELS)) { + summary->ex_info.epcx[ei->extra_regs[i].reg_index - EPC_1] = ei->extra_regs[i].reg_val; + summary->ex_info.epcx_reg_bits |= (1 << (ei->extra_regs[i].reg_index - EPC_1)); + } + } +} + +void esp_core_dump_summary_parse_exc_regs(esp_core_dump_summary_t *summary, void *stack_data) +{ + int i; + long *a_reg; + XtExcFrame *stack = (XtExcFrame *) stack_data; + summary->exc_pc = esp_cpu_process_stack_pc(stack->pc); + ESP_COREDUMP_LOGD("Crashing PC 0x%x", summary->exc_pc); + + a_reg = &stack->a0; + for (i = 0; i < 16; i++) { + summary->ex_info.exc_a[i] = a_reg[i]; + ESP_COREDUMP_LOGD("A[%d] 0x%x", i, summary->ex_info.exc_a[i]); + } +} + +void esp_core_dump_summary_parse_backtrace_info(esp_core_dump_bt_info_t *bt_info, const void *vaddr, + const void *paddr, uint32_t stack_size) +{ + if (!vaddr || !paddr || !bt_info) { + return; + } + + int offset; + bool corrupted; + esp_backtrace_frame_t frame; + XtExcFrame *stack = (XtExcFrame *) paddr; + int max_depth = (int) (sizeof(bt_info->bt) / sizeof(bt_info->bt[0])); + int index = 0; + + frame.pc = stack->pc; + frame.sp = stack->a1; + frame.next_pc = stack->a0; + + corrupted = !(esp_stack_ptr_is_sane(frame.sp) && + (esp_ptr_executable((void *)esp_cpu_process_stack_pc(frame.pc)) || + stack->exccause == EXCCAUSE_INSTR_PROHIBITED)); /* Ignore the first corrupted PC in case of InstrFetchProhibited */ + + /* vaddr is actual stack address when crash occurred. However that stack is now saved + * in the flash at a different location. Hence for each SP, we need to adjust the offset + * to point to next frame in the flash */ + offset = (uint32_t) stack - (uint32_t) vaddr; + + ESP_COREDUMP_LOGD("Crash Backtrace"); + bt_info->bt[index] = esp_cpu_process_stack_pc(frame.pc); + ESP_COREDUMP_LOGD(" 0x%x", bt_info->bt[index]); + index++; + + while (max_depth-- > 0 && frame.next_pc && !corrupted) { + /* Check if the Stack Pointer is in valid address range */ + if (!((uint32_t)frame.sp >= (uint32_t)vaddr && + ((uint32_t)frame.sp <= (uint32_t)vaddr + stack_size))) { + corrupted = true; + break; + } + /* Adjusting the SP to address in flash than in actual RAM */ + frame.sp += offset; + if (!esp_backtrace_get_next_frame(&frame)) { + corrupted = true; + } + if (corrupted == false) { + bt_info->bt[index] = esp_cpu_process_stack_pc(frame.pc); + ESP_COREDUMP_LOGD(" 0x%x", bt_info->bt[index]); + index++; + } + } + bt_info->depth = index; + bt_info->corrupted = corrupted; +} + +#endif /* #if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF */ + #endif diff --git a/components/espcoredump/test/coredump.b64 b/components/espcoredump/test/coredump.b64 deleted file mode 100644 index f6ad3cd75822..000000000000 --- a/components/espcoredump/test/coredump.b64 +++ /dev/null @@ -1,369 +0,0 @@ -ID0AAAABAAAKAAAAfAEAAAAAAAA= -f0VMRgEBAQAAAAAAAAAAAAQAXgABAAAAAAAAADQAAAAAAAAAAAAAADQAIAAWACgA -AAAAAA== -BAAAAPQCAAAAAAAAAAAAAMAXAADAFwAABgAAAAAAAAA= -AQAAALQaAABgYvs/YGL7P3wBAAB8AQAABgAAAAAAAAA= -AQAAADAcAAAQqvs/EKr7P/ABAADwAQAABgAAAAAAAAA= -AQAAACAeAAB4ovs/eKL7P3wBAAB8AQAABgAAAAAAAAA= -AQAAAJwfAABgn/s/YJ/7PwQDAAAEAwAABgAAAAAAAAA= -AQAAAKAiAAA0dvs/NHb7P3wBAAB8AQAABgAAAAAAAAA= -AQAAABwkAACAdPs/gHT7P6ABAACgAQAABgAAAAAAAAA= -AQAAALwlAACYbvs/mG77P3wBAAB8AQAABgAAAAAAAAA= -AQAAADgnAADgbPs/4Gz7P6QBAACkAQAABgAAAAAAAAA= -AQAAANwoAADUYPs/1GD7P3wBAAB8AQAABgAAAAAAAAA= -AQAAAFgqAAAgX/s/IF/7P6ABAACgAQAABgAAAAAAAAA= -AQAAAPgrAABYZPs/WGT7P3wBAAB8AQAABgAAAAAAAAA= -AQAAAHQtAABwsvs/cLL7P6ABAACgAQAABgAAAAAAAAA= -AQAAABQvAADcgPs/3ID7P3wBAAB8AQAABgAAAAAAAAA= -AQAAAJAwAAAAf/s/AH/7P8gBAADIAQAABgAAAAAAAAA= -AQAAAFgyAAA0+/o/NPv6P3wBAAB8AQAABgAAAAAAAAA= -AQAAANQzAABg+fo/YPn6P8ABAADAAQAABgAAAAAAAAA= -AQAAAJQ1AABYUPs/WFD7P3wBAAB8AQAABgAAAAAAAAA= -AQAAABA3AACgTvs/oE77P6QBAACkAQAABgAAAAAAAAA= -AQAAALQ4AAB4Sfs/eEn7P3wBAAB8AQAABgAAAAAAAAA= -AQAAADA6AACgR/s/oEf7P8QBAADEAQAABgAAAAAAAAA= -BAAAAPQ7AAAAAAAAAAAAABQBAAAUAQAABgAAAAAAAAA= -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYGL7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARQ4NQCAIBgD9FABADRUAQP////8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAODYDQqvs/ -AgAAAByr+z8Qq/s/cOn6PwAAAAAAAAAABQAAAK3///8gAAAA4GL7PwEAAACAAAAA -AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeKL7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3JIAQCAFBgD9FABADRUAQP////8XAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+TAIAgoPs/ -nKD7PwAAAAAAAAAA0hQBAFcAAAA3AAAA9D8AAAAAAAAAAAAAAAAAAHiDCIDAXvs/ -AAAAAICC+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHb7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsoUOQCAABgBsxABAd8QAQP////8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFI4DYBAdfs/ -AAAAAAAAAAABAAAAAQAAgAMAAAAjAAYAeJcIgDB1+z8DAAAAIwgGACAIBgABAAAA -IAgGANCE+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmG77PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsoUOQCAFBgBsxABAd8QAQP////8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFI4DYCgbfs/ -AAAAAAMAAAABAAAAAQAAgAMAAAAjCgYAHpEIgIBt+z/8Zvs/SB0AQCAEBgABAAAA -IAQGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1GD7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQIQCADBgD9FABADRUAQPn///8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF6bCIDgX/s/ -AAAAAGwcAQB4lwiA8E77PwMAAAAjCAYAFBQIgMBf+z/cAPA/AQAAADgA+z8BAAAA -IAMGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWGT7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQIQCABBgD9FABADRUAQPj///8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF6bCIAws/s/ -AAAAAGwcAQBxWA2A0J/7PwAIAAAEAPs/FBQIgBCz+z/cAPA/AQAAADgA+z8BAAAA -IAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3ID7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQIQCAABgAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpCIDAf/s/ -AAAAAAAAAAAUePs/AAAAAAAAAABQVPs/FBQIgKB/+z/cAPA/AQAAADgA+z9gVPs/ -UCsNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANPv6PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQIQCAGBgAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADSNCIAg+vo/ -AAAAAAAAAADQOfs/FQAAAFUAAADQSPs/FBQIgAD6+j/cAPA/AQAAADgA+z8BAAAA -IAYGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFD7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANI0IQCAIBgAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8dCIBgT/s/ -3Ev7PwAAAAAwTPs/AAAAAAEAAAAAAAAANI0IgEBP+z8BAAAABAAAANQ5+z8KAAAA -AACAABwA9D8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -CAAAAEwCAAABAAAA -Q09SRQAAAAA= -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeEn7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQIQCAOBgAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADSNCIBgSPs/ -AAAAAAAAAADQOfs/zc0AAAEAAAAAAAAAFBQIgEBI+z/cAPA/AQAAADgA+z8BAAAA -IAAGAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA -gKr7P6Cr+z+EGAEAcDj7P3A4+z9gYvs/aDj7PxIAAAAYZPs/GGT7P2Bi+z8AAAAA -BwAAAASk+z91bmFsaWduZWRfcHRyX3QAAQAAAACs+z8AAAAAIAwGAA8AAADOzs7O -BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -776t3kUODUAwCAYAIA4NgNCq+z8CAAAAHKv7PxCr+z9w6fo/AAAAAAAAAAAFAAAA -rf///yAAAADgYvs/AQAAAIAAAAABAAAAAAAAAAAAAAAdAAAABQAAAP0UAEANFQBA -/////wEAAACAAAAABCQIQNw++z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAEAAACAAAAAAQAAAAAAAAAgDg2AAKv7PwEAAABw6fo/ -vLUNgACr+z8KAAAAAwAAABCr+z9w6fo/AAAAAAAAAABoDg2AMKv7PwoAAACUDPs/ -lAJAPx4AAADmV0A/AwAAAKSNCIAQX/s/AQAAAO8BvNBggQiAYKv7PwAAAAAAAAAA -YIEIgGCr+z8AAAAAAwAAACAAAAAAAACAIQAGAAEAAAAAAAAAgKv7P1AODUAAAAAA -IwAGAHA4+z9gYvs/AAAAAAAAAACgq/s/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArKv7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAA== -YJ/7PwCi+z+hFAEASDj7P0g4+z94ovs/QDj7PxQAAACcS/s/nEv7P3ii+z8AAAAA -BQAAAGiC+z91bml0eVRhc2sAzs7Ozs4AAAAAAGSi+z8AAAAAIQAGAAwAAADOzs7O -BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQNySAEAwBQYAD5MAgCCg+z+coPs/AAAAAAAAAADSFAEAVwAAADcAAAD0PwAA -AAAAAAAAAAAAAAAAeIMIgMBe+z8AAAAAgIL7PxcAAAD//wAAAAAAAP0UAEANFQBA -/////2gmCEDAXvs/oIMIQDw1+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAP//P7MAAAAAAAAAAAAAAAC3YA2AQKD7P5yg+z//AAAA -PDX7PwAAAAAAAAAAAAAAALpcDYBgoPs/nKD7P/8AAABlXwTAAP8AAAAA/wAAAAD/ -J2ENgJCg+z8BAAAAoKH7PydhDYCQoPs/AQAAAO8BvND+AAAAnKH7PwAAAAAQAAAA -YIEIgMCh+z8AAAAAAAAAAKWlpaWlpaWlpaWlpQAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADvAbzQ -nKD7PwAAAIAhAAYAAFf7PwAAAADgofs/HGENQAAAAAAjAAYASDj7P3ii+z8AAAAA -AAAAAACi+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAMovs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAA== -gHT7P8B1+z/Ozs7O5Df7P6Bu+z80dvs/3Df7PxkAAADOzs7Ozs7OzjR2+z8AAAAA -AAAAACRw+z9JRExFMQDOzs7Ozs7Ozs4AAQAAACB2+z8AAAAAIQAGAAcAAADOzs7O -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQLKFDkAwAAYAUjgNgEB1+z8AAAAAAAAAAAEAAAABAACAAwAAACMABgB4lwiA -MHX7PwMAAAAjCAYAIAgGAAEAAAAgCAYA0IT7PwAAAAD//wAAAAAAAGzEAEB3xABA -/////2gmCEABAAAAoIMIQPwI+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAACAnQhAAAAAAAAAAACJnQiAYHX7PwgAAAABAAAA -AAAAAAAAAAAAAAAAAAAAAGCBCICAdfs/AAAAAAAAAAABAAAAAAAAgCEABgAAAAAA -AAAAAKB1+z+AnQhAAAAAACMABgDkN/s/mG77PwAAAAAAAAAAwHX7PwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMx1+z8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= -4Gz7PyBu+z/Ozs7OPHb7P+Q3+z+Ybvs/3Df7PxkAAADOzs7Ozs7Ozphu+z8AAAAA -AAAAAIho+z9JRExFMADOzs7Ozs7Ozs4AAAAAAIRu+z8AAAAAIQAGAAYAAADOzs7O -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQLKFDkAwBQYAUjgNgKBt+z8AAAAAAwAAAAEAAAABAACAAwAAACMKBgAekQiA -gG37P/xm+z9IHQBAIAQGAAEAAAAgBAYAAAAAAAAAAAD//wAAAAAAAGzEAEB3xABA -/////2gmCEABAAAAoIMIQFwB+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAACAnQhAAAAAAAAAAACJnQiAwG37PwgAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAGCBCIDgbfs/AAAAAAAAAAABAAAAAAAAgCEABgAjCwYA -AAAAAABu+z+AnQhAAAAAACMABgDkN/s/NHb7PwAAAAAAAAAAIG77PwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxu+z8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -IF/7P2Bg+z9sHAEA0Df7P2Bk+z/UYPs/yDf7PxQAAADOzs7Ozs7OztRg+z8AAAAA -BQAAAMRY+z9iYWRfcHRyX3Rhc2sAzs4A////f8Bg+z8AAAAAIQAGAA4AAADOzs7O -BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQBQUCEAwAwYAXpsIgOBf+z8AAAAAbBwBAHiXCIDwTvs/AwAAACMIBgAUFAiA -wF/7P9wA8D8BAAAAOAD7PwEAAAAgAwYAAAAAAAAAAAD//wAAAAAAAP0UAEANFQBA -+f///2gmCEABAAAAoIMIQJzz+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAADACQD8YAAAA5ldAPwEAAADjDQ2AAGD7P2wcAQCUDPs/ -eJcIgPBO+z8DAAAAIwgGAGCBCIAgYPs/AAAAAAAAAAAgAAAAAAAAgCEABgAAAAAA -AAAAAEBg+z/UDQ1AAAAAACMABgBIOPs/eKL7PwAAAAAAAAAAYGD7PwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxg+z8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= -cLL7P7Cz+z9sHAEA3GD7P9A3+z9YZPs/yDf7Pw8AAADOzs7Ozs7Ozlhk+z8AAAAA -CgAAABSs+z9mYWlsZWRfYXNzZXJ0X3QAAAAAABC0+z8AAAAAIQAGABAAAADOzs7O -CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQBQUCEAwAQYAXpsIgDCz+z8AAAAAbBwBAHFYDYDQn/s/AAgAAAQA+z8UFAiA -ELP7P9wA8D8BAAAAOAD7PwEAAAAgAQYAAAAAAAAAAAD//wAAAAAAAP0UAEANFQBA -+P///2gmCEABAAAAoIMIQOxG+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAEQBQD8eAAAA5ldAPwEAAAAjDQ2AULP7P2wcAQCUDPs/ -cVgNgNCf+z8ACAAABAD7P2CBCIBws/s/AAAAAAAAAAAgAAAAAAAAgCEABgAAAAAA -AAAAAJCz+z8UDQ1AAAAAACMABgCsOPs/WGT7PwAAAAAAAAAAsLP7PwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyz+z8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= -AH/7P2CA+z8AAAAAvDf7P7w3+z/cgPs/tDf7PxgAAADsd/s/7Hf7P9yA+z/kd/s/ -AQAAAMx4+z9UbXIgU3ZjAM7Ozs7Ozs4AAAAAAMiA+z8AAAAAIQAGAAgAAADOzs7O -AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQBQUCEAwAAYAAakIgMB/+z8AAAAAAAAAABR4+z8AAAAAAAAAAFBU+z8UFAiA -oH/7P9wA8D8BAAAAOAD7P2BU+z9QKw1AAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA -AAAAAGgmCEBgVPs/oIMIQJwT+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAGgkCEBYgQhAMAAFAO8BvNAzqgiA4H/7P9w5+z8AAAAA -AAAAABiqCEAAAAAAAAAAAGCBCIAQgPs/AAAAAAAAAAAAAAAAAAAAAAAAAADvAbzQ -AQAAAAAAAIAhAAYAIwAGAAAAAABAgPs/GKoIQAAAAACcE/s/AAAAAAEAAADvAbzQ -IwAGAPg3+z/8Zvs/AAAAAAAAAABggPs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbID7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -YPn6P8D6+j/Ozs7OYFD7P4BJ+z80+/o/WDf7PwMAAADk6vo/5Or6PzT7+j/c6vo/ -FgAAACTr+j9lc3BfdGltZXIAzs7Ozs4AAAAAACD7+j8AAAAAIQAGAAEAAADOzs7O -FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQBQUCEAwBgYANI0IgCD6+j8AAAAAAAAAANA5+z8VAAAAVQAAANBI+z8UFAiA -APr6P9wA8D8BAAAAOAD7PwEAAAAgBgYAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA -AAAAAGgmCEABAAAAoIMIQPyN+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAGgkCEBYgQhAMAAFAAAAAACLNw2AQPr6P7jq+j8AAAAA -AAAAAHg3DUAAAAAAAAAAAGCBCICA+vo/AAAAAAAAAAAAAAAAAAAAAAAAAAD///// -AAAAAAAAAACMxAAA7wG80Azr+j8AAAAAAQAAACMOBgAAAAAAoPr6P3g3DUAAAAAA -IwAGAJw5+z80+/o/AAAAAAAAAADA+vo/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzPr6PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAA== -oE77P+BP+z/Ozs7OYDf7Pzz7+j9YUPs/WDf7PwEAAAAITPs/CEz7P1hQ+z8ATPs/ -GAAAAEhM+z9pcGMxAM7Ozs7Ozs7Ozs4AAQAAAERQ+z8AAAAAIQAGAAMAAADOzs7O -GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQDSNCEAwCAYADx0IgGBP+z/cS/s/AAAAADBM+z8AAAAAAQAAAAAAAAA0jQiA -QE/7PwEAAAAEAAAA1Dn7PwoAAAAAAIAAHAD0PwAAAAD//wAAAAAAAAAAAAAAAAAA -AAAAAGgmCEAKAAAAoIMIQBzj+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAANQ5+z8KAAAAAACAABwA9D9ggQiAoE/7PwEAAAAAAAAA -gKL7PwoAAAAAAIAA/////2CBCIAAAAAAnBQBAO8BvNAwTPs/AAAAAAEAAAAAAAAA -AAAAAMBP+z/cHAhAAQAAAAEAAADEOfs/WFD7PwAAAAAAAAAA4E/7PwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAKwRCICAff4/KAAAACgAAAAAAAAAAAAAAOxP+z8AAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -oEf7PwBJ+z/Ozs7OPPv6P2A3+z94Sfs/WDf7PwEAAAAoRfs/KEX7P3hJ+z8gRfs/ -GAAAAGhF+z9pcGMwAM7Ozs7Ozs7Ozs4AAAAAAGRJ+z8AAAAAIQAGAAIAAADOzs7O -GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOn6P3Dp+j/Y6fo/ -AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAASB0AQAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOzs4= -aCQIQBQUCEAwDgYANI0IgGBI+z8AAAAAAAAAANA5+z/NzQAAAQAAAAAAAAAUFAiA -QEj7P9wA8D8BAAAAOAD7PwEAAAAgAAYAAQAAAAAAAAD//wAAAAAAAAAAAAAAAAAA -AAAAAGgmCEABAAAAoIMIQDzc+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAGgkCEBYgQhAMAAFAAAAAAAPHQiAgEj7P/xE+z8AAAAA -AAAAANwcCEAAAAAAAAAAAGCBCIDASPs/AAAAAAAAAAAAAAAAAAAAAAAAAAD///// -AAAAAAAAAAAAAAAA7wG80FBF+z8AAAAAAQAAAAIAAAAAAAAA4Ej7P9wcCEAAAAAA -IwMGAMQ5+z94Sfs/AQAAAAAAAAAASfs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -KREIgFA7/j9AN/s/7wG80AAAAAAAAAAADEn7PwAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAA= -FAAAAEgAAABKIAAA -RVNQX0NPUkVfRFVNUF9JTkZPAAA= -AAEAADYxNTFkNThkNGUzNmJmYWI5MmM4ZTYzYzgzYTEzOThlZDdhNjFkYzFhYjk0 -NWQxNzI5ZTY3MDUxNmY5N2NiZjQAAAAA -DAAAAJQAAAClAgAA -RVhUUkFfSU5GTwAA -YGL7P+gAAAAdAAAA7gAAAAUAAADCAAAAAAAAAMMAAAAAAAAAxAAAACAIBgDFAAAA -AAAAAMYAAAAAAAAAxwAAAAAAAACxAAAAR4UOQLIAAAAAAAAAswAAAAAAAAC0AAAA -QCwIQLUAAAAAAAAAtgAAAAAAAAC3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAA== -hvIqKg== diff --git a/components/espcoredump/test/esp32/coredump.b64 b/components/espcoredump/test/esp32/coredump.b64 new file mode 100644 index 000000000000..2452952abec1 --- /dev/null +++ b/components/espcoredump/test/esp32/coredump.b64 @@ -0,0 +1,293 @@ +EC8AAAABAAAAAAAAAAAAAAAAAAA= +f0VMRgEBAQAAAAAAAAAAAAQAXgABAAAAAAAAADQAAAAAAAAAAAAAADQAIAASACgA +AAAAAA== +BAAAAHQCAAAAAAAAAAAAAAATAAAAEwAABgAAAAAAAAA= +AQAAAHQVAAA4kPs/OJD7P1gBAABYAQAABgAAAAAAAAA= +AQAAAMwWAABAjvs/QI77P/ABAADwAQAABgAAAAAAAAA= +AQAAALwYAABsdPs/bHT7P1gBAABYAQAABgAAAAAAAAA= +AQAAABQaAADAcvs/wHL7P6QBAACkAQAABgAAAAAAAAA= +AQAAALgbAADMe/s/zHv7P1gBAABYAQAABgAAAAAAAAA= +AQAAABAdAAAgevs/IHr7P6QBAACkAQAABgAAAAAAAAA= +AQAAALQeAACYmfs/mJn7P1gBAABYAQAABgAAAAAAAAA= +AQAAAAwgAADwl/s/8Jf7P6ABAACgAQAABgAAAAAAAAA= +AQAAAKwhAADYhvs/2Ib7P1gBAABYAQAABgAAAAAAAAA= +AQAAAAQjAAAwhfs/MIX7P6ABAACgAQAABgAAAAAAAAA= +AQAAAKQkAAAk/fo/JP36P1gBAABYAQAABgAAAAAAAAA= +AQAAAPwlAACARPs/gET7P8ABAADAAQAABgAAAAAAAAA= +AQAAALwnAACsW/s/rFv7P1gBAABYAQAABgAAAAAAAAA= +AQAAABQpAADwWfs/8Fn7P7QBAAC0AQAABgAAAAAAAAA= +AQAAAMgqAABMSvs/TEr7P1gBAABYAQAABgAAAAAAAAA= +AQAAACAsAACASPs/gEj7P8QBAADEAQAABgAAAAAAAAA= +BAAAAOQtAAAAAAAAAAAAABQBAAAUAQAABgAAAAAAAAA= +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJD7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUwNQCACBgD9FABADRUAQP////8aAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANxLDYAAj/s/ +AgAAAEyP+z9Aj/s/bO/6PwAAAAAAAAAABQAAAK3///8gAAAAmJD7PwEAAACAAAAA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbHT7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZnsOQCAHBgAAAAAAAAAAAAAAAAAeAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEIaDYCAc/s/ +AAAAAAEAAAABAAAAAQAAgHAx+z9kLwhA/pwNgFBz+z8AAAAASB0AQCAJBgAjCQYA +AQAAACg2+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzHv7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZnsOQCAMBgAAAAAAAAAAAAAAAAAeAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEIaDYDgevs/ +AAAAAAAAAAABAAAAAQAAgAMAAAAjAAYA/pwNgLB6+z8AAAAAIwoGACAKBgAjCgYA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmJn7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnEIIQCAFBgD9FABADRUAQPj///8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKplCICwmPs/ +AAAAAMwAAABENPs/4Gv7PwAIAAAAAAAAnEIIgJCY+z/cAPA/AQAAAMwX+z8jBQYA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2Ib7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnEIIQCAHBgD9FABADRUAQPn///8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKplCIDwhfs/ +AAAAAMwAAABENPs/XC/7PwMAAAAjAAYAnEIIgNCF+z/cAPA/AQAAAMwX+z8jBwYA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJP36PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnEIIQCAMBgAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVeCIBARfs/ +AAAAAP////8Y/fo/EDv+PwMAAAAjDwYAnEIIgCBF+z/cAPA/AQAAAMwX+z8jAAYA +AQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArFv7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8L8AQCAABgAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5/CICwWvs/ +AAAAACMABgAgAAYAIwAGAAEAAAAAAAAAdUIIgIBa+z9wMfs/AAAAAMBF+z+gRfs/ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATEr7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnEIIQCAKBgAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVeCIBASfs/ +AQAAAP////98//o/FG37PwEAAAAcAPQ/nEIIgCBJ+z/gAPA/AQAAAMwX+z8jCgYA +AQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +kI77P9CP+z9oAAAA5DL7P+Qy+z84kPs/3DL7PxIAAABAgm/brox/kDiQ+z8AAAAA +BwAAADSI+z91bmFsaWduZWRfcHRyX3QAAQAAADCQ+z8HAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+z8= +776t3gFMDUAwAgYA3EsNgACP+z8CAAAATI/7P0CP+z9s7/o/AAAAAAAAAAAFAAAA +rf///yAAAACYkPs/AQAAAIAAAAABAAAAAAAAABoAAAAdAAAABQAAAP0UAEANFQBA +/////wEAAACAAAAAlB8IQChZ+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAEAAACAAAAAAQAAAAAAAADcSw2AMI/7PwEAAABs7/o/ +AwAAAAAAAAABAAAAAQAAAECP+z9s7/o/AAAAAAAAAAAkTA2AYI/7PwoAAAAYFvs/ +AwAAAB4AAAAAJEA/AQAAAEQ0+z9Qhvs/kEsNQAAAAAD8fAiAkI/7PwAAAAAAAAAA +AwAAAJCP+z8AAAAAAAAAACEABgAjAAYAAQAAAAAAAAAAAAAAsI/7PwxMDUAAAAAA +IwAGAOQy+z84kPs/AAAAAAAAAADQj/s/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3I/7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAA== +wHL7PwB0+z+m2kRd1Hv7P1gy+z9sdPs/UDL7PxkAAABcy2uvr5MueWx0+z8AAAAA +AAAAAGhu+z9JRExFAMbL04ZFuPBSHv4AAAAAAGR0+z8AAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+z8= ++B8IQGZ7DkAwBwYAQhoNgIBz+z8AAAAAAQAAAAEAAAABAACAcDH7P2QvCED+nA2A +UHP7PwAAAABIHQBAIAkGACMJBgABAAAAKDb7Px4AAAD//wAAAAAAAAAAAAAAAAAA +AAAAAPwhCEAjCQYA4FEIQFg9+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAG9iCICAc/s/aDH7PwAAAABRYwiAoHP7PwgAAAAAAAAA +AQAAAAEAAIBwMfs/ZC8IQPx8CIDAc/s/AAAAAAAAAAABAAAAIwAGAAEAAAABAAAA +AAAAAOBz+z9IYwhAAAAAACMABgBYMvs/zHv7PwAAAAAAAAAAAHT7PwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx0+z8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +IHr7P2B7+z9reJJRWDL7P3R0+z/Me/s/UDL7PxkAAACZX8oHrFqw3Mx7+z8AAAAA +AAAAAMh1+z9JRExFAAxeE8+k8EEsAjAAAQAAAMR7+z8AAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+z8= ++B8IQGZ7DkAwDAYAQhoNgOB6+z8AAAAAAAAAAAEAAAABAACAAwAAACMABgD+nA2A +sHr7PwAAAAAjCgYAIAoGACMKBgABAAAAAAAAAB4AAAD//wAAAAAAAAAAAAAAAAAA +AAAAAPwhCEAjCgYA4FEIQLhE+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAG9iCIDgevs/aDH7PwAAAABRYwiAAHv7PwgAAAABAAAA +AQAAAAEAAIADAAAAIwAGAPx8CIAge/s/AAAAAAAAAAABAAAAIwAGAAEAAAAAAAAA +AAAAAEB7+z9IYwhAAAAAACMABgBYMvs/bHT7PwAAAAAAAAAAYHv7PwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGx7+z8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +8Jf7PzCZ+z/MAAAA4Ib7P0Qy+z+Ymfs/PDL7Pw8AAAD0hvs/LPH6P5iZ+z8AAAAA +CgAAAJSR+z9mYWlsZWRfYXNzZXJ0X3QAAAAAAJCZ+z8KAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+z8= ++B8IQJxCCEAwBQYAqmUIgLCY+z8AAAAAzAAAAEQ0+z/ga/s/AAgAAAAAAACcQgiA +kJj7P9wA8D8BAAAAzBf7PyMFBgABAAAAAAAAAAAAAAD//wAAAAAAAP0UAEANFQBA ++P////whCEAjBQYA4FEIQIhi+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAIwUQD8eAAAAACRAPwEAAADfSg2A0Jj7P2QAAAAYFvs/ +RDT7P+Br+z8ACAAAAAAAAPx8CIDwmPs/AAAAAAAAAAAhAAYAIwAGAAEAAAAAAAAA +AAAAABCZ+z/QSg1AAAAAACMABgAgM/s/mJn7PwAAAAAAAAAAMJn7PwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyZ+z8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= +MIX7P3CG+z/MAAAARDL7P6CZ+z/Yhvs/PDL7PxQAAAAs8fo/LPH6P9iG+z8AAAAA +BQAAANR++z9iYWRfcHRyX3Rhc2sALfIA////f9CG+z8FAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+z8= ++B8IQJxCCEAwBwYAqmUIgPCF+z8AAAAAzAAAAEQ0+z9cL/s/AwAAACMABgCcQgiA +0IX7P9wA8D8BAAAAzBf7PyMHBgABAAAAAAAAAAAAAAD//wAAAAAAAP0UAEANFQBA ++f////whCEAjBwYA4FEIQMhP+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAACgVQD8YAAAAACRAPwEAAACfSw2AEIb7P2QAAAAYFvs/ +RDT7P1wv+z8DAAAAIwAGAPx8CIAwhvs/AAAAAAAAAAAhAAYAIwAGAAEAAAAjCgYA +AAAAAFCG+z+QSw1AAAAAACMABgC8Mvs/2Ib7PwAAAAAAAAAAcIb7PwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHyG+z8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= +gET7P+BF+z/I+EKptFv7P9Qx+z8k/fo/zDH7PwEAAAD4/Po/+Pz6PyT9+j/w/Po/ +GAAAAERC+z9pcGMwADo8s+3XPVxsABcAAAAAAEBG+z8YAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+j8= ++B8IQJxCCEAwDAYAVV4IgEBF+z8AAAAA/////xj9+j8QO/4/AwAAACMPBgCcQgiA +IEX7P9wA8D8BAAAAzBf7PyMABgABAAAABAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA +AAAAAPwhCEAjAAYA4FEIQDgP+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAPgfCED0fAhAMAAFAAAAAADzJgiAYEX7P8z8+j8Y/fo/ +AAAAAMgmCEAAAAAAAAAAAPx8CICgRfs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +/////wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAACMPBgAAAAAAwEX7P8gmCEAAAAAA +Iw8GADg0+z8k/fo/AQAAAAAAAADgRfs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +X4IOgMA7/j/EMfs/AAAAAAAAAAAAAAAA7EX7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAA== +8Fn7P0Bb+z+hEsOqVEr7Pyz9+j+sW/s/zDH7PwMAAABSWdk3vcUY2Kxb+z8AAAAA +FgAAAKhL+z9lc3BfdGltZXIA+VivHhkAAAAAAKRb+z8WAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAEA+z8= ++B8IQPC/AEAwAAYADn8IgLBa+z8AAAAAIwAGACAABgAjAAYAAQAAAAAAAAB1QgiA +gFr7P3Ax+z8AAAAAwEX7P6BF+z8AAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA +AAAAAPwhCECgRfs/4FEIQJgk+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAEBb+z8AAAAAAAAAAAAAAACSdgiAwFr7P2gx+z8AAAAA +f0UNgOBa+z8AAAAAAQAAAAAAAADQAAAAIAFAP5A7/j/8fAiAAFv7PwAAAAAAAAAA +GBb7PyMABgABAAAAIwwGAAAAAAAgW/s/cEUNQAAAAAAjAAYAEDT7P6xb+z8AAAAA +AAAAAEBb+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAABMW/s/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA== +gEj7P+BJ+z/ohsDC1DH7P7Rb+z9MSvs/zDH7PwEAAABc//o/XP/6P0xK+z9U//o/ +GAAAAEhG+z9pcGMxAE0z6cVZGyYdUCMAAQAAAERK+z8YAAAAAAAAAAAAAAAAAAAA +AAAAAATv+j9s7/o/1O/6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA+z8= ++B8IQJxCCEAwCgYAVV4IgEBJ+z8BAAAA/////3z/+j8Ubfs/AQAAABwA9D+cQgiA +IEn7P+AA8D8BAAAAzBf7PyMKBgABAAAAAQAAAAAAAAD//wAAAAAAAAAAAAAAAAAA +AAAAAPwhCEAjCgYA4FEIQDgT+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAP//P7MAAAAAAAAAAAAAAADzJgiAYEn7PzD/+j98//o/ +AAAAAMgmCEABAAAAAAAAAPx8CICgSfs/AQAAAAAAAAAAAAAABAAAAAAAAAAAAAAA +/////wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAAAAAAAwEn7P8gmCEABAAAA +AQAAADg0+z9MSvs/AAAAAAAAAADgSfs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +Nw8IgGB9/j+APgAAEDr7AAAAAAAAAAAA7En7PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAA= +FAAAAEgAAABKIAAA +RVNQX0NPUkVfRFVNUF9JTkZPAAA= +AAEAAGY2YTg2NjAxNDY2YjI5ZmIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +DAAAAJQAAAClAgAA +RVhUUkFfSU5GTwAA +OJD7P+gAAAAdAAAA7gAAAAUAAADCAAAAAAAAAMMAAAAAAAAAxAAAACAKBgDFAAAA +AAAAAMYAAAAAAAAAsQAAAFuWDUCyAAAAAAAAALMAAAAAAAAAtAAAAIsvCEC1AAAA +AAAAALYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA== +wDjTmg== diff --git a/components/espcoredump/test/esp32/expected_output b/components/espcoredump/test/esp32/expected_output new file mode 100644 index 000000000000..ff8de49c2d56 --- /dev/null +++ b/components/espcoredump/test/esp32/expected_output @@ -0,0 +1,584 @@ +espcoredump.py v0.4-dev +=============================================================== +==================== ESP32 CORE DUMP START ==================== + +Crashed task handle: 0x3ffb9038, name: 'unaligned_ptr_t', GDB name: 'process 1073451064' + +================== CURRENT THREAD REGISTERS =================== +exccause 0x1d (StoreProhibitedCause) +excvaddr 0x5 +epc1 0x400d965b +epc2 0x0 +epc3 0x0 +epc4 0x40082f8b +epc5 0x0 +epc6 0x0 +eps2 0x0 +eps3 0x0 +eps4 0x60a20 +eps5 0x0 +eps6 0x0 +pc 0x400d4c01 0x400d4c01 +lbeg 0x400014fd 1073747197 +lend 0x4000150d 1073747213 +lcount 0xffffffff 4294967295 +sar 0x1a 26 +ps 0x60220 393760 +threadptr +br +scompare1 +acclo +acchi +m0 +m1 +m2 +m3 +expstate +f64r_lo +f64r_hi +f64s +fcr +fsr +a0 0x800d4bdc -2146612260 +a1 0x3ffb8f00 1073450752 +a2 0x2 2 +a3 0x3ffb8f4c 1073450828 +a4 0x3ffb8f40 1073450816 +a5 0x3ffaef6c 1073409900 +a6 0x0 0 +a7 0x0 0 +a8 0x5 5 +a9 0xffffffad -83 +a10 0x20 32 +a11 0x3ffb9098 1073451160 +a12 0x1 1 +a13 0x80 128 +a14 0x1 1 +a15 0x0 0 + +==================== CURRENT THREAD STACK ===================== +#0 0x400d4c01 in recur_func () at ../main/test_core_dump.c:70 +#1 0x400d4bdc in recur_func () at ../main/test_core_dump.c:63 +#2 0x400d4bdc in recur_func () at ../main/test_core_dump.c:63 +#3 0x400d4c24 in unaligned_ptr_task (pvParameter=0x0) at ../main/test_core_dump.c:80 +#4 0x40087cfc in vPortTaskWrapper (pxCode=0x400d4c0c , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +======================== THREADS INFO ========================= + Id Target Id Frame +* 1 process 1073451064 0x400d4c01 in recur_func () at ../main/test_core_dump.c:70 + 2 process 1073443948 0x400e7b66 in esp_pm_impl_waiti () at ../../../hal/esp32/include/hal/cpu_ll.h:183 + 3 process 1073445836 0x400e7b66 in esp_pm_impl_waiti () at ../../../hal/esp32/include/hal/cpu_ll.h:183 + 4 process 1073453464 0x4008429c in esp_crosscore_int_send_yield (core_id=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 + 5 process 1073448664 0x4008429c in esp_crosscore_int_send_yield (core_id=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 + 6 process 1073413412 0x4008429c in esp_crosscore_int_send_yield (core_id=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 + 7 process 1073437612 0x4000bff0 in ?? () + 8 process 1073433164 0x4008429c in esp_crosscore_int_send_yield (core_id=1) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 + +==================== THREAD 1 (TCB: 0x3ffb9038, name: 'unaligned_ptr_t') ===================== +#0 0x400d4c01 in recur_func () at ../main/test_core_dump.c:70 +#1 0x400d4bdc in recur_func () at ../main/test_core_dump.c:63 +#2 0x400d4bdc in recur_func () at ../main/test_core_dump.c:63 +#3 0x400d4c24 in unaligned_ptr_task (pvParameter=0x0) at ../main/test_core_dump.c:80 +#4 0x40087cfc in vPortTaskWrapper (pxCode=0x400d4c0c , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 2 (TCB: 0x3ffb746c, name: 'IDLE') ===================== +#0 0x400e7b66 in esp_pm_impl_waiti () at ../../../hal/esp32/include/hal/cpu_ll.h:183 +#1 0x400d1a42 in esp_vApplicationIdleHook () at /builds/espressif/esp-idf/components/esp_system/freertos_hooks.c:63 +#2 0x40086351 in prvIdleTask (pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/tasks.c:3959 +#3 0x40087cfc in vPortTaskWrapper (pxCode=0x40086348 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 3 (TCB: 0x3ffb7bcc, name: 'IDLE') ===================== +#0 0x400e7b66 in esp_pm_impl_waiti () at ../../../hal/esp32/include/hal/cpu_ll.h:183 +#1 0x400d1a42 in esp_vApplicationIdleHook () at /builds/espressif/esp-idf/components/esp_system/freertos_hooks.c:63 +#2 0x40086351 in prvIdleTask (pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/tasks.c:3959 +#3 0x40087cfc in vPortTaskWrapper (pxCode=0x40086348 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 4 (TCB: 0x3ffb9998, name: 'failed_assert_t') ===================== +#0 0x4008429c in esp_crosscore_int_send_yield (core_id=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 +#1 0x400865aa in vTaskDelay (xTicksToDelay=100) at ../../../hal/esp32/include/hal/cpu_ll.h:39 +#2 0x400d4adf in failed_assert_task (pvParameter=0x0) at ../main/test_core_dump.c:89 +#3 0x40087cfc in vPortTaskWrapper (pxCode=0x400d4ad0 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 5 (TCB: 0x3ffb86d8, name: 'bad_ptr_task') ===================== +#0 0x4008429c in esp_crosscore_int_send_yield (core_id=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 +#1 0x400865aa in vTaskDelay (xTicksToDelay=100) at ../../../hal/esp32/include/hal/cpu_ll.h:39 +#2 0x400d4b9f in bad_ptr_task (pvParameter=0x0) at ../main/test_core_dump.c:43 +#3 0x40087cfc in vPortTaskWrapper (pxCode=0x400d4b90 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 6 (TCB: 0x3ffafd24, name: 'ipc0') ===================== +#0 0x4008429c in esp_crosscore_int_send_yield (core_id=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 +#1 0x40085e55 in xQueueSemaphoreTake (xQueue=0x3ffafccc, xTicksToWait=) at ../../../hal/esp32/include/hal/cpu_ll.h:39 +#2 0x400826f3 in ipc_task (arg=0x0) at /builds/espressif/esp-idf/components/esp_ipc/src/esp_ipc.c:59 +#3 0x40087cfc in vPortTaskWrapper (pxCode=0x400826c8 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 7 (TCB: 0x3ffb5bac, name: 'esp_timer') ===================== +#0 0x4000bff0 in ?? () +#1 0x40087f0e in vPortExitCritical (mux=) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:447 +#2 0x40087692 in ulTaskGenericNotifyTake (uxIndexToWait=0, xClearCountOnExit=1, xTicksToWait=) at /builds/espressif/esp-idf/components/freertos/tasks.c:5370 +#3 0x400d457f in timer_task (arg=0x0) at /builds/espressif/esp-idf/components/esp_timer/src/esp_timer.c:392 +#4 0x40087cfc in vPortTaskWrapper (pxCode=0x400d4570 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 8 (TCB: 0x3ffb4a4c, name: 'ipc1') ===================== +#0 0x4008429c in esp_crosscore_int_send_yield (core_id=1) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 +#1 0x40085e55 in xQueueSemaphoreTake (xQueue=0x3ffaff30, xTicksToWait=) at ../../../hal/esp32/include/hal/cpu_ll.h:39 +#2 0x400826f3 in ipc_task (arg=0x1) at /builds/espressif/esp-idf/components/esp_ipc/src/esp_ipc.c:59 +#3 0x40087cfc in vPortTaskWrapper (pxCode=0x400826c8 , pvParameters=0x1) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + + +======================= ALL MEMORY REGIONS ======================== +Name Address Size Attrs +.rtc.text 0x400c0000 0x0 RW +.rtc.dummy 0x3ff80000 0x0 RW +.rtc.force_fast 0x3ff80000 0x0 RW +.rtc.data 0x50000000 0x10 RW A +.rtc_noinit 0x50000010 0x0 RW +.rtc.force_slow 0x50000010 0x0 RW +.iram0.vectors 0x40080000 0x403 R XA +.iram0.text 0x40080404 0xae63 R XA +.dram0.data 0x3ffb0000 0x2efc RW A +.ext_ram_noinit 0x3f800000 0x0 RW +.noinit 0x3ffb2efc 0x0 RW +.ext_ram.bss 0x3f800000 0x0 RW +.flash.appdesc 0x3f400020 0x100 R A +.flash.rodata 0x3f400120 0x3698 RW A +.flash.rodata_noload 0x3f4037b8 0x0 RW +.flash.text 0x400d0020 0x1849f R XA +.iram0.data 0x4008b268 0x0 RW +.iram0.bss 0x4008b268 0x0 RW +.dram0.heap_start 0x3ffb3be8 0x0 RW +.coredump.tasks.data 0x3ffb9038 0x158 RW +.coredump.tasks.data 0x3ffb8e40 0x1f0 RW +.coredump.tasks.data 0x3ffb746c 0x158 RW +.coredump.tasks.data 0x3ffb72c0 0x1a4 RW +.coredump.tasks.data 0x3ffb7bcc 0x158 RW +.coredump.tasks.data 0x3ffb7a20 0x1a4 RW +.coredump.tasks.data 0x3ffb9998 0x158 RW +.coredump.tasks.data 0x3ffb97f0 0x1a0 RW +.coredump.tasks.data 0x3ffb86d8 0x158 RW +.coredump.tasks.data 0x3ffb8530 0x1a0 RW +.coredump.tasks.data 0x3ffafd24 0x158 RW +.coredump.tasks.data 0x3ffb4480 0x1c0 RW +.coredump.tasks.data 0x3ffb5bac 0x158 RW +.coredump.tasks.data 0x3ffb59f0 0x1b4 RW +.coredump.tasks.data 0x3ffb4a4c 0x158 RW +.coredump.tasks.data 0x3ffb4880 0x1c4 RW + +====================== CORE DUMP MEMORY CONTENTS ======================== +.coredump.tasks.data 0x3ffb9038 0x158 RW +0x3ffb9038: 0x3ffb8e90 0x3ffb8fd0 0x00000068 0x3ffb32e4 +0x3ffb9048: 0x3ffb32e4 0x3ffb9038 0x3ffb32dc 0x00000012 +0x3ffb9058: 0xdb6f8240 0x907f8cae 0x3ffb9038 0x00000000 +0x3ffb9068: 0x00000007 0x3ffb8834 0x6c616e75 0x656e6769 +0x3ffb9078: 0x74705f64 0x00745f72 0x00000001 0x3ffb9030 +0x3ffb9088: 0x00000007 0x00000000 0x00000000 0x00000000 +0x3ffb9098: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb90a8: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb90b8: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb90c8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb90d8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb90e8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb90f8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9108: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9118: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9128: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9138: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9148: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9158: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9168: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9178: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9188: 0x00000000 0x3ffb0000 +.coredump.tasks.data 0x3ffb8e40 0x1f0 RW +0x3ffb8e40: 0xdeadbeef 0x400d4c01 0x00060230 0x800d4bdc +0x3ffb8e50: 0x3ffb8f00 0x00000002 0x3ffb8f4c 0x3ffb8f40 +0x3ffb8e60: 0x3ffaef6c 0x00000000 0x00000000 0x00000005 +0x3ffb8e70: 0xffffffad 0x00000020 0x3ffb9098 0x00000001 +0x3ffb8e80: 0x00000080 0x00000001 0x00000000 0x0000001a +0x3ffb8e90: 0x0000001d 0x00000005 0x400014fd 0x4000150d +0x3ffb8ea0: 0xffffffff 0x00000001 0x00000080 0x40081f94 +0x3ffb8eb0: 0x3ffb5928 0x00000000 0x00000000 0x00000000 +0x3ffb8ec0: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb8ed0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8ee0: 0x00000001 0x00000080 0x00000001 0x00000000 +0x3ffb8ef0: 0x800d4bdc 0x3ffb8f30 0x00000001 0x3ffaef6c +0x3ffb8f00: 0x00000003 0x00000000 0x00000001 0x00000001 +0x3ffb8f10: 0x3ffb8f40 0x3ffaef6c 0x00000000 0x00000000 +0x3ffb8f20: 0x800d4c24 0x3ffb8f60 0x0000000a 0x3ffb1618 +0x3ffb8f30: 0x00000003 0x0000001e 0x3f402400 0x00000001 +0x3ffb8f40: 0x3ffb3444 0x3ffb8650 0x400d4b90 0x00000000 +0x3ffb8f50: 0x80087cfc 0x3ffb8f90 0x00000000 0x00000000 +0x3ffb8f60: 0x00000003 0x3ffb8f90 0x00000000 0x00000000 +0x3ffb8f70: 0x00060021 0x00060023 0x00000001 0x00000000 +0x3ffb8f80: 0x00000000 0x3ffb8fb0 0x400d4c0c 0x00000000 +0x3ffb8f90: 0x00060023 0x3ffb32e4 0x3ffb9038 0x00000000 +0x3ffb8fa0: 0x00000000 0x3ffb8fd0 0x00000000 0x00000000 +0x3ffb8fb0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8fc0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8fd0: 0x00000000 0x00000000 0x3ffb8fdc 0x00000000 +0x3ffb8fe0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8ff0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9000: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9010: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9020: 0x00000000 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffb746c 0x158 RW +0x3ffb746c: 0x3ffb72c0 0x3ffb7400 0x5d44daa6 0x3ffb7bd4 +0x3ffb747c: 0x3ffb3258 0x3ffb746c 0x3ffb3250 0x00000019 +0x3ffb748c: 0xaf6bcb5c 0x792e93af 0x3ffb746c 0x00000000 +0x3ffb749c: 0x00000000 0x3ffb6e68 0x454c4449 0xd3cbc600 +0x3ffb74ac: 0xf0b84586 0x00fe1e52 0x00000000 0x3ffb7464 +0x3ffb74bc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb74cc: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb74dc: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb74ec: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb74fc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb750c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb751c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb752c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb753c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb754c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb755c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb756c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb757c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb758c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb759c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb75ac: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb75bc: 0x00000000 0x3ffb0000 +.coredump.tasks.data 0x3ffb72c0 0x1a4 RW +0x3ffb72c0: 0x40081ff8 0x400e7b66 0x00060730 0x800d1a42 +0x3ffb72d0: 0x3ffb7380 0x00000000 0x00000001 0x00000001 +0x3ffb72e0: 0x80000001 0x3ffb3170 0x40082f64 0x800d9cfe +0x3ffb72f0: 0x3ffb7350 0x00000000 0x40001d48 0x00060920 +0x3ffb7300: 0x00060923 0x00000001 0x3ffb3628 0x0000001e +0x3ffb7310: 0x0000ffff 0x00000000 0x00000000 0x00000000 +0x3ffb7320: 0x00000000 0x400821fc 0x00060923 0x400851e0 +0x3ffb7330: 0x3ffb3d58 0x00000000 0x00000000 0x00000000 +0x3ffb7340: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb7350: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7360: 0x8008626f 0x3ffb7380 0x3ffb3168 0x00000000 +0x3ffb7370: 0x80086351 0x3ffb73a0 0x00000008 0x00000000 +0x3ffb7380: 0x00000001 0x80000001 0x3ffb3170 0x40082f64 +0x3ffb7390: 0x80087cfc 0x3ffb73c0 0x00000000 0x00000000 +0x3ffb73a0: 0x00000001 0x00060023 0x00000001 0x00000001 +0x3ffb73b0: 0x00000000 0x3ffb73e0 0x40086348 0x00000000 +0x3ffb73c0: 0x00060023 0x3ffb3258 0x3ffb7bcc 0x00000000 +0x3ffb73d0: 0x00000000 0x3ffb7400 0x00000000 0x00000000 +0x3ffb73e0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb73f0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7400: 0x00000000 0x00000000 0x3ffb740c 0x00000000 +0x3ffb7410: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7420: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7430: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7440: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7450: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7460: 0x00000000 +.coredump.tasks.data 0x3ffb7bcc 0x158 RW +0x3ffb7bcc: 0x3ffb7a20 0x3ffb7b60 0x5192786b 0x3ffb3258 +0x3ffb7bdc: 0x3ffb7474 0x3ffb7bcc 0x3ffb3250 0x00000019 +0x3ffb7bec: 0x07ca5f99 0xdcb05aac 0x3ffb7bcc 0x00000000 +0x3ffb7bfc: 0x00000000 0x3ffb75c8 0x454c4449 0x135e0c00 +0x3ffb7c0c: 0x41f0a4cf 0x0030022c 0x00000001 0x3ffb7bc4 +0x3ffb7c1c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7c2c: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb7c3c: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb7c4c: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb7c5c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7c6c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7c7c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7c8c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7c9c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7cac: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7cbc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7ccc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7cdc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7cec: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7cfc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7d0c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7d1c: 0x00000000 0x3ffb0000 +.coredump.tasks.data 0x3ffb7a20 0x1a4 RW +0x3ffb7a20: 0x40081ff8 0x400e7b66 0x00060c30 0x800d1a42 +0x3ffb7a30: 0x3ffb7ae0 0x00000000 0x00000000 0x00000001 +0x3ffb7a40: 0x80000001 0x00000003 0x00060023 0x800d9cfe +0x3ffb7a50: 0x3ffb7ab0 0x00000000 0x00060a23 0x00060a20 +0x3ffb7a60: 0x00060a23 0x00000001 0x00000000 0x0000001e +0x3ffb7a70: 0x0000ffff 0x00000000 0x00000000 0x00000000 +0x3ffb7a80: 0x00000000 0x400821fc 0x00060a23 0x400851e0 +0x3ffb7a90: 0x3ffb44b8 0x00000000 0x00000000 0x00000000 +0x3ffb7aa0: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb7ab0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7ac0: 0x8008626f 0x3ffb7ae0 0x3ffb3168 0x00000000 +0x3ffb7ad0: 0x80086351 0x3ffb7b00 0x00000008 0x00000001 +0x3ffb7ae0: 0x00000001 0x80000001 0x00000003 0x00060023 +0x3ffb7af0: 0x80087cfc 0x3ffb7b20 0x00000000 0x00000000 +0x3ffb7b00: 0x00000001 0x00060023 0x00000001 0x00000000 +0x3ffb7b10: 0x00000000 0x3ffb7b40 0x40086348 0x00000000 +0x3ffb7b20: 0x00060023 0x3ffb3258 0x3ffb746c 0x00000000 +0x3ffb7b30: 0x00000000 0x3ffb7b60 0x00000000 0x00000000 +0x3ffb7b40: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7b50: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7b60: 0x00000000 0x00000000 0x3ffb7b6c 0x00000000 +0x3ffb7b70: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7b80: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7b90: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7ba0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7bb0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb7bc0: 0x00000000 +.coredump.tasks.data 0x3ffb9998 0x158 RW +0x3ffb9998: 0x3ffb97f0 0x3ffb9930 0x000000cc 0x3ffb86e0 +0x3ffb99a8: 0x3ffb3244 0x3ffb9998 0x3ffb323c 0x0000000f +0x3ffb99b8: 0x3ffb86f4 0x3ffaf12c 0x3ffb9998 0x00000000 +0x3ffb99c8: 0x0000000a 0x3ffb9194 0x6c696166 0x615f6465 +0x3ffb99d8: 0x72657373 0x00745f74 0x00000000 0x3ffb9990 +0x3ffb99e8: 0x0000000a 0x00000000 0x00000000 0x00000000 +0x3ffb99f8: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb9a08: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb9a18: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb9a28: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a38: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a48: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a58: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a68: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a78: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a88: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9a98: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9aa8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9ab8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9ac8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9ad8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9ae8: 0x00000000 0x3ffb0000 +.coredump.tasks.data 0x3ffb97f0 0x1a0 RW +0x3ffb97f0: 0x40081ff8 0x4008429c 0x00060530 0x800865aa +0x3ffb9800: 0x3ffb98b0 0x00000000 0x000000cc 0x3ffb3444 +0x3ffb9810: 0x3ffb6be0 0x00000800 0x00000000 0x8008429c +0x3ffb9820: 0x3ffb9890 0x3ff000dc 0x00000001 0x3ffb17cc +0x3ffb9830: 0x00060523 0x00000001 0x00000000 0x00000000 +0x3ffb9840: 0x0000ffff 0x00000000 0x400014fd 0x4000150d +0x3ffb9850: 0xfffffff8 0x400821fc 0x00060523 0x400851e0 +0x3ffb9860: 0x3ffb6288 0x00000000 0x00000000 0x00000000 +0x3ffb9870: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb9880: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9890: 0x3f40148c 0x0000001e 0x3f402400 0x00000001 +0x3ffb98a0: 0x800d4adf 0x3ffb98d0 0x00000064 0x3ffb1618 +0x3ffb98b0: 0x3ffb3444 0x3ffb6be0 0x00000800 0x00000000 +0x3ffb98c0: 0x80087cfc 0x3ffb98f0 0x00000000 0x00000000 +0x3ffb98d0: 0x00060021 0x00060023 0x00000001 0x00000000 +0x3ffb98e0: 0x00000000 0x3ffb9910 0x400d4ad0 0x00000000 +0x3ffb98f0: 0x00060023 0x3ffb3320 0x3ffb9998 0x00000000 +0x3ffb9900: 0x00000000 0x3ffb9930 0x00000000 0x00000000 +0x3ffb9910: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9920: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9930: 0x00000000 0x00000000 0x3ffb993c 0x00000000 +0x3ffb9940: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9950: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9960: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9970: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb9980: 0x00000000 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffb86d8 0x158 RW +0x3ffb86d8: 0x3ffb8530 0x3ffb8670 0x000000cc 0x3ffb3244 +0x3ffb86e8: 0x3ffb99a0 0x3ffb86d8 0x3ffb323c 0x00000014 +0x3ffb86f8: 0x3ffaf12c 0x3ffaf12c 0x3ffb86d8 0x00000000 +0x3ffb8708: 0x00000005 0x3ffb7ed4 0x5f646162 0x5f727470 +0x3ffb8718: 0x6b736174 0x00f22d00 0x7fffffff 0x3ffb86d0 +0x3ffb8728: 0x00000005 0x00000000 0x00000000 0x00000000 +0x3ffb8738: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb8748: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb8758: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb8768: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8778: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8788: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8798: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb87a8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb87b8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb87c8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb87d8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb87e8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb87f8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8808: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8818: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8828: 0x00000000 0x3ffb0000 +.coredump.tasks.data 0x3ffb8530 0x1a0 RW +0x3ffb8530: 0x40081ff8 0x4008429c 0x00060730 0x800865aa +0x3ffb8540: 0x3ffb85f0 0x00000000 0x000000cc 0x3ffb3444 +0x3ffb8550: 0x3ffb2f5c 0x00000003 0x00060023 0x8008429c +0x3ffb8560: 0x3ffb85d0 0x3ff000dc 0x00000001 0x3ffb17cc +0x3ffb8570: 0x00060723 0x00000001 0x00000000 0x00000000 +0x3ffb8580: 0x0000ffff 0x00000000 0x400014fd 0x4000150d +0x3ffb8590: 0xfffffff9 0x400821fc 0x00060723 0x400851e0 +0x3ffb85a0: 0x3ffb4fc8 0x00000000 0x00000000 0x00000000 +0x3ffb85b0: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb85c0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb85d0: 0x3f401528 0x00000018 0x3f402400 0x00000001 +0x3ffb85e0: 0x800d4b9f 0x3ffb8610 0x00000064 0x3ffb1618 +0x3ffb85f0: 0x3ffb3444 0x3ffb2f5c 0x00000003 0x00060023 +0x3ffb8600: 0x80087cfc 0x3ffb8630 0x00000000 0x00000000 +0x3ffb8610: 0x00060021 0x00060023 0x00000001 0x00060a23 +0x3ffb8620: 0x00000000 0x3ffb8650 0x400d4b90 0x00000000 +0x3ffb8630: 0x00060023 0x3ffb32bc 0x3ffb86d8 0x00000000 +0x3ffb8640: 0x00000000 0x3ffb8670 0x00000000 0x00000000 +0x3ffb8650: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8660: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8670: 0x00000000 0x00000000 0x3ffb867c 0x00000000 +0x3ffb8680: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb8690: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb86a0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb86b0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb86c0: 0x00000000 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffafd24 0x158 RW +0x3ffafd24: 0x3ffb4480 0x3ffb45e0 0xa942f8c8 0x3ffb5bb4 +0x3ffafd34: 0x3ffb31d4 0x3ffafd24 0x3ffb31cc 0x00000001 +0x3ffafd44: 0x3ffafcf8 0x3ffafcf8 0x3ffafd24 0x3ffafcf0 +0x3ffafd54: 0x00000018 0x3ffb4244 0x30637069 0xb33c3a00 +0x3ffafd64: 0x5c3dd7ed 0x0017006c 0x00000000 0x3ffb4640 +0x3ffafd74: 0x00000018 0x00000000 0x00000000 0x00000000 +0x3ffafd84: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffafd94: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffafda4: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffafdb4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafdc4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafdd4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafde4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafdf4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe04: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe14: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe24: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe34: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe44: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe54: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe64: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffafe74: 0x00000000 0x3ffa0000 +.coredump.tasks.data 0x3ffb4480 0x1c0 RW +0x3ffb4480: 0x40081ff8 0x4008429c 0x00060c30 0x80085e55 +0x3ffb4490: 0x3ffb4540 0x00000000 0xffffffff 0x3ffafd18 +0x3ffb44a0: 0x3ffe3b10 0x00000003 0x00060f23 0x8008429c +0x3ffb44b0: 0x3ffb4520 0x3ff000dc 0x00000001 0x3ffb17cc +0x3ffb44c0: 0x00060023 0x00000001 0x00000004 0x00000000 +0x3ffb44d0: 0x0000ffff 0x00000000 0x00000000 0x00000000 +0x3ffb44e0: 0x00000000 0x400821fc 0x00060023 0x400851e0 +0x3ffb44f0: 0x3ffb0f38 0x00000000 0x00000000 0x00000000 +0x3ffb4500: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb4510: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4520: 0x40081ff8 0x40087cf4 0x00050030 0x00000000 +0x3ffb4530: 0x800826f3 0x3ffb4560 0x3ffafccc 0x3ffafd18 +0x3ffb4540: 0x00000000 0x400826c8 0x00000000 0x00000000 +0x3ffb4550: 0x80087cfc 0x3ffb45a0 0x00000000 0x00000000 +0x3ffb4560: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4570: 0xffffffff 0x00000000 0x00000000 0x00000000 +0x3ffb4580: 0x00000001 0x00000001 0x00000000 0x00060f23 +0x3ffb4590: 0x00000000 0x3ffb45c0 0x400826c8 0x00000000 +0x3ffb45a0: 0x00060f23 0x3ffb3438 0x3ffafd24 0x00000001 +0x3ffb45b0: 0x00000000 0x3ffb45e0 0x00000000 0x00000000 +0x3ffb45c0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb45d0: 0x800e825f 0x3ffe3bc0 0x3ffb31c4 0x00000000 +0x3ffb45e0: 0x00000000 0x00000000 0x3ffb45ec 0x00000000 +0x3ffb45f0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4600: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4610: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4620: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4630: 0x00000000 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffb5bac 0x158 RW +0x3ffb5bac: 0x3ffb59f0 0x3ffb5b40 0xaac312a1 0x3ffb4a54 +0x3ffb5bbc: 0x3ffafd2c 0x3ffb5bac 0x3ffb31cc 0x00000003 +0x3ffb5bcc: 0x37d95952 0xd818c5bd 0x3ffb5bac 0x00000000 +0x3ffb5bdc: 0x00000016 0x3ffb4ba8 0x5f707365 0x656d6974 +0x3ffb5bec: 0x58f90072 0x00191eaf 0x00000000 0x3ffb5ba4 +0x3ffb5bfc: 0x00000016 0x00000000 0x00000000 0x00000000 +0x3ffb5c0c: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb5c1c: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb5c2c: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb5c3c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5c4c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5c5c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5c6c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5c7c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5c8c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5c9c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5cac: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5cbc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5ccc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5cdc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5cec: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5cfc: 0x00000000 0x3ffb0001 +.coredump.tasks.data 0x3ffb59f0 0x1b4 RW +0x3ffb59f0: 0x40081ff8 0x4000bff0 0x00060030 0x80087f0e +0x3ffb5a00: 0x3ffb5ab0 0x00000000 0x00060023 0x00060020 +0x3ffb5a10: 0x00060023 0x00000001 0x00000000 0x80084275 +0x3ffb5a20: 0x3ffb5a80 0x3ffb3170 0x00000000 0x3ffb45c0 +0x3ffb5a30: 0x3ffb45a0 0x00000000 0x00000000 0x00000000 +0x3ffb5a40: 0x0000ffff 0x00000000 0x00000000 0x00000000 +0x3ffb5a50: 0x00000000 0x400821fc 0x3ffb45a0 0x400851e0 +0x3ffb5a60: 0x3ffb2498 0x00000000 0x00000000 0x00000000 +0x3ffb5a70: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb5a80: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5a90: 0x3ffb5b40 0x00000000 0x00000000 0x00000000 +0x3ffb5aa0: 0x80087692 0x3ffb5ac0 0x3ffb3168 0x00000000 +0x3ffb5ab0: 0x800d457f 0x3ffb5ae0 0x00000000 0x00000001 +0x3ffb5ac0: 0x00000000 0x000000d0 0x3f400120 0x3ffe3b90 +0x3ffb5ad0: 0x80087cfc 0x3ffb5b00 0x00000000 0x00000000 +0x3ffb5ae0: 0x3ffb1618 0x00060023 0x00000001 0x00060c23 +0x3ffb5af0: 0x00000000 0x3ffb5b20 0x400d4570 0x00000000 +0x3ffb5b00: 0x00060023 0x3ffb3410 0x3ffb5bac 0x00000000 +0x3ffb5b10: 0x00000000 0x3ffb5b40 0x00000000 0x00000000 +0x3ffb5b20: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5b30: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5b40: 0x00000000 0x00000000 0x3ffb5b4c 0x00000000 +0x3ffb5b50: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5b60: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5b70: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5b80: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5b90: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb5ba0: 0x00000000 +.coredump.tasks.data 0x3ffb4a4c 0x158 RW +0x3ffb4a4c: 0x3ffb4880 0x3ffb49e0 0xc2c086e8 0x3ffb31d4 +0x3ffb4a5c: 0x3ffb5bb4 0x3ffb4a4c 0x3ffb31cc 0x00000001 +0x3ffb4a6c: 0x3ffaff5c 0x3ffaff5c 0x3ffb4a4c 0x3ffaff54 +0x3ffb4a7c: 0x00000018 0x3ffb4648 0x31637069 0xe9334d00 +0x3ffb4a8c: 0x261b59c5 0x0023501d 0x00000001 0x3ffb4a44 +0x3ffb4a9c: 0x00000018 0x00000000 0x00000000 0x00000000 +0x3ffb4aac: 0x00000000 0x3ffaef04 0x3ffaef6c 0x3ffaefd4 +0x3ffb4abc: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3ffb4acc: 0x00000000 0x00000000 0x40001d48 0x00000000 +0x3ffb4adc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4aec: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4afc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b0c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b1c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b2c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b3c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b4c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b5c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b6c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b7c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b8c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4b9c: 0x00000000 0x3ffb0000 +.coredump.tasks.data 0x3ffb4880 0x1c4 RW +0x3ffb4880: 0x40081ff8 0x4008429c 0x00060a30 0x80085e55 +0x3ffb4890: 0x3ffb4940 0x00000001 0xffffffff 0x3ffaff7c +0x3ffb48a0: 0x3ffb6d14 0x00000001 0x3ff4001c 0x8008429c +0x3ffb48b0: 0x3ffb4920 0x3ff000e0 0x00000001 0x3ffb17cc +0x3ffb48c0: 0x00060a23 0x00000001 0x00000001 0x00000000 +0x3ffb48d0: 0x0000ffff 0x00000000 0x00000000 0x00000000 +0x3ffb48e0: 0x00000000 0x400821fc 0x00060a23 0x400851e0 +0x3ffb48f0: 0x3ffb1338 0x00000000 0x00000000 0x00000000 +0x3ffb4900: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb4910: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4920: 0xb33fffff 0x00000000 0x00000000 0x00000000 +0x3ffb4930: 0x800826f3 0x3ffb4960 0x3ffaff30 0x3ffaff7c +0x3ffb4940: 0x00000000 0x400826c8 0x00000001 0x00000000 +0x3ffb4950: 0x80087cfc 0x3ffb49a0 0x00000001 0x00000000 +0x3ffb4960: 0x00000000 0x00000004 0x00000000 0x00000000 +0x3ffb4970: 0xffffffff 0x00000000 0x00000000 0x00000000 +0x3ffb4980: 0x00000001 0x00000001 0x00000000 0x00000001 +0x3ffb4990: 0x00000000 0x3ffb49c0 0x400826c8 0x00000001 +0x3ffb49a0: 0x00000001 0x3ffb3438 0x3ffb4a4c 0x00000000 +0x3ffb49b0: 0x00000000 0x3ffb49e0 0x00000000 0x00000000 +0x3ffb49c0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb49d0: 0x80080f37 0x3ffe7d60 0x00003e80 0x00fb3a10 +0x3ffb49e0: 0x00000000 0x00000000 0x3ffb49ec 0x00000000 +0x3ffb49f0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4a00: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4a10: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4a20: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4a30: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffb4a40: 0x00000000 + +===================== ESP32 CORE DUMP END ===================== +=============================================================== +Done! diff --git a/components/espcoredump/test/esp32c3/coredump.b64 b/components/espcoredump/test/esp32c3/coredump.b64 new file mode 100644 index 000000000000..0694e1896e48 --- /dev/null +++ b/components/espcoredump/test/esp32c3/coredump.b64 @@ -0,0 +1,135 @@ +NBQAAAABBQAAAAAAAAAAAAAAAAA= +f0VMRgEBAQAAAAAAAAAAAAQA8wABAAAAAAAAADQAAAAAAAAAAAAAADQAIAAMACgA +AAAAAA== +BAAAALQBAAAAAAAAAAAAAGAEAABgBAAABgAAAAAAAAA= +AQAAABQGAACgGsk/oBrJP1QBAABUAQAABgAAAAAAAAA= +AQAAAGgHAADgGMk/4BjJP7ABAACwAQAABgAAAAAAAAA= +AQAAABgJAADsEMk/7BDJP1QBAABUAQAABgAAAAAAAAA= +AQAAAGwKAACQD8k/kA/JP1ABAABQAQAABgAAAAAAAAA= +AQAAALwLAABAA8k/QAPJP1QBAABUAQAABgAAAAAAAAA= +AQAAABANAADwAck/8AHJP0ABAABAAQAABgAAAAAAAAA= +AQAAAFAOAAD8I8k//CPJP1QBAABUAQAABgAAAAAAAAA= +AQAAAKQPAACgIsk/oCLJP1ABAABQAQAABgAAAAAAAAA= +AQAAAPQQAABI6sg/SOrIP1QBAABUAQAABgAAAAAAAAA= +AQAAAEgSAADw6Mg/8OjIP1ABAABQAQAABgAAAAAAAAA= +BAAAAJgTAAAAAAAAAAAAAIQAAACEAAAABgAAAAAAAAA= +CAAAAMwAAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoBrJPwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPFgAQjZYAEKAGck/AKbIP8znyD8AAAAA +3BXJPwAAAAAAAAAAAAAAACAAAAC4Fck/AAAAAAcAAACt////BQAAADAuAEIAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAMwAAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7BDJPwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAui04QB5gOEDcD8k/VhY4QBzeyD8AAAAA +AAAAAAAAAABkAAAAAAAAAAEAAAABAAAAZAAAAAQAAAABAAAAAAAMYDAuAEIAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAMwAAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAPJPwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIsAAQna0AEKlpaWlpaWlpWzQyD8AAAAA +AAAAAAAAAAAIAAAAAQAAAAEAAABPAsk/AAAAAEADyT+Eycg/AAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAMwAAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/CPJPwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAui04QB5gOEDsIsk/VhY4QCzxyD8AAAAA +AAAAAAAAAABkAAAAAAAAAAEAAAABAAAAyAAAAAQAAAABAAAAAAAMYDAuAEIAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAMwAAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASOrIPwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtF44QN5eOEClpaWlpaWlpXy3yD8AAAAA +AAAAAAAAAAAAAAAA/////wEAAAABAAAA/////wQAAAAA0Mg/ACAMYAAAAAAAAAAA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +QBnJP2QAAAA0xMg/NMTIP6AayT8sxMg/EgAAAL+v+xmQVwBQoBrJPwAAAAAHAAAA +nBLJP3VuYWxpZ25lZF9wdHJfdAAAAAAAkBrJPwcAAAAAAAAAAAAAAAAAAAAAAAAA +DNXIP3TVyD/c1cg/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA3MsAQgAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AADJPw== +PFgAQjZYAEKAGck/AKbIP8znyD8AAAAA3BXJPwAAAAAAAAAAAAAAACAAAAC4Fck/ +AAAAAAcAAACt////BQAAADAuAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBGAAAAQA4QAcAAAAFAAAA +AAAAAAIAAAAwLgBCAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAA/BrJP3TVyD8aWABC +AAAAAAAAAAAAAAAAAwAAAAAAAADAGck/AgAAABpYAEJoEwI8HgAAADgFAjwDAAAA +AAAAAAAAAAAAAAAAdFgAQgAAAAAAAAAAAAAAACpfOEAAAAAAAAAAAAAAAAAAAAAA +AAAAAKWlpaWlpaWlpaWlpRRkFCcHAQEBAQAAAP///////+9/AAAAAAAAwD8AAAAA +AAAwQAAAAAAAAOA/AAAAAAAA+D9hQ29jp4fSP7PIYIsoisY/+3mfUBNE0z8AAAAA +AADwPwAAAAAAACRAAAAAAAAAHEAAAAAAAAAUQAAAAAAAAFBDEAAAAAAAAAADelIA +kA/JP2QAAAAMxMg/DMTIP+wQyT8ExMg/FAAAAMG1RPMBAHFl7BDJPwAAAAAFAAAA +6AjJP2JhZF9wdHJfdGFzawAgOgAAAAAA4BDJPwUAAAAAAAAAAAAAAAAAAAAAAAAA +DNXIP3TVyD/c1cg/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA3MsAQgAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AADJPw== +ui04QB5gOEDcD8k/VhY4QBzeyD8AAAAAAAAAAAAAAABkAAAAAAAAAAEAAAABAAAA +ZAAAAAQAAAABAAAAAAAMYDAuAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAAAuTThA +AAAAAAAAAAAAAAAA1FcAQgAAAAAAAAAAAAAAACpfOEAAAAAAAAAAAAAAAAAAAAAA +AAAAAKWlpaWlpaWlpaWlpRRkFCcHAQEBAQAAAP///////+9/AAAAAAAAwD8AAAAA +AAAwQAAAAAAAAOA/AAAAAAAA+D9hQ29jp4fSP7PIYIsoisY/+3mfUBNE0z8AAAAA +AADwPwAAAAAAACRAAAAAAAAAHEAAAAAAAAAUQAAAAAAAAFBDEAAAAAAAAAADelIA +8AHJP/TMyD+ow8g/qMPIP0ADyT+gw8g/GQAAAPyUf70KtQxjQAPJPwAAAAAAAAAA +PP3IP0lETEUA913xcw28qfJwbQAAAAAAMAPJPwAAAAAAAAAAAAAAAAAAAAAAAAAA +DNXIP3TVyD/c1cg/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA3MsAQgAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AADJPw== +IsAAQna0AEKlpaWlpaWlpWzQyD8AAAAAAAAAAAAAAAAIAAAAAQAAAAEAAABPAsk/ +AAAAAEADyT+Eycg/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeTDhA +AAAAAAAAAAAAAAAAKl84QAAAAAAAAAAAAAAAAAAAAAAAAAAApaWlpaWlpaWlpaWl +FGQUJwcBAQEBAAAA////////738AAAAAAADAPwAAAAAAADBAAAAAAAAA4D8AAAAA +AAD4P2FDb2Onh9I/s8hgiyiKxj/7eZ9QE0TTPwAAAAAAAPA/AAAAAAAAJEAAAAAA +AAAcQAAAAAAAABRAAAAAAAAAUEMQAAAAAAAAAAN6UgA= +oCLJP8gAAACcxcg/nMXIP/wjyT+Uxcg/DwAAAPxhtrxVvv3m/CPJPwAAAAAKAAAA ++BvJP2ZhaWxlZF9hc3NlcnRfdAAAAAAA8CPJPwoAAAAAAAAAAAAAAAAAAAAAAAAA +DNXIP3TVyD/c1cg/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA3MsAQgAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AADJPw== +ui04QB5gOEDsIsk/VhY4QCzxyD8AAAAAAAAAAAAAAABkAAAAAAAAAAEAAAABAAAA +yAAAAAQAAAABAAAAAAAMYDAuAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAAAuTThA +AAAAAAAAAAAAAAAAvlYAQgAAAAAAAAAAAAAAACpfOEAAAAAAAAAAAAAAAAAAAAAA +AAAAAKWlpaWlpaWlpaWlpRRkFCcHAQEBAQAAAP///////+9/AAAAAAAAwD8AAAAA +AAAwQAAAAAAAAOA/AAAAAAAA+D9hQ29jp4fSP7PIYIsoisY/+3mfUBNE0z8AAAAA +AADwPwAAAAAAACRAAAAAAAAAHEAAAAAAAAAUQAAAAAAAAFBDEAAAAAAAAAADelIA +8OjIP/TMyD/Yxcg/2MXIP0jqyD/Qxcg/AwAAALyhUSAAAka9SOrIPwAAAAAWAAAA +RNrIP2VzcF90aW1lcgCCNNIiAQAAAAAAQOrIPxYAAAAAAAAAAAAAAAAAAAAAAAAA +DNXIP3TVyD/c1cg/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA3MsAQgAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AQDIPw== +tF44QN5eOEClpaWlpaWlpXy3yD8AAAAAAAAAAAAAAAAAAAAA/////wEAAAABAAAA +/////wQAAAAA0Mg/ACAMYAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA/////wAAAAC6WThA +AAAAAAAAAAAAAAAAVkwAQgAAAAAAAAAAAAAAACpfOEAAAAAAAAAAAAAAAAAAAAAA +AAAAAKWlpaWlpaWlpaWlpRRkFCcHAQEBAQAAAP///////+9/AAAAAAAAwD8AAAAA +AAAwQAAAAAAAAOA/AAAAAAAA+D9hQ29jp4fSP7PIYIsoisY/+3mfUBNE0z8AAAAA +AADwPwAAAAAAACRAAAAAAAAAHEAAAAAAAAAUQAAAAAAAAFBDEAAAAAAAAAADelIA +FAAAAEgAAABKIAAA +RVNQX0NPUkVfRFVNUF9JTkZPAAA= +AAEFAGJkMWUxNzRhOGY5NmQ4NDIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +DAAAAAQAAAClAgAA +RVhUUkFfSU5GTwAA +oBrJPw== +fWX0jg== diff --git a/components/espcoredump/test/esp32c3/expected_output b/components/espcoredump/test/esp32c3/expected_output new file mode 100644 index 000000000000..c66fcd1e4cf4 --- /dev/null +++ b/components/espcoredump/test/esp32c3/expected_output @@ -0,0 +1,354 @@ +espcoredump.py v0.4-dev +=============================================================== +==================== ESP32 CORE DUMP START ==================== + +Crashed task handle: 0x3fc91aa0, name: 'unaligned_ptr_t', GDB name: 'process 1070144160' + +================== CURRENT THREAD REGISTERS =================== +ra 0x42005836 0x42005836 +sp 0x3fc91980 0x3fc91980 +gp 0x3fc8a600 0x3fc8a600 <__c.5484+32> +tp 0x3fc8e7cc 0x3fc8e7cc +t0 0x0 0 +t1 0x3fc915dc 1070142940 +t2 0x0 0 +fp 0x0 0x0 +s1 0x0 0 +a0 0x20 32 +a1 0x3fc915b8 1070142904 +a2 0x0 0 +a3 0x7 7 +a4 0xffffffad -83 +a5 0x5 5 +a6 0x42002e30 1107308080 +a7 0x0 0 +s2 0x0 0 +s3 0x0 0 +s4 0x0 0 +s5 0x0 0 +s6 0x0 0 +s7 0x0 0 +s8 0x0 0 +s9 0x0 0 +s10 0x0 0 +s11 0x0 0 +t3 0x0 0 +t4 0x0 0 +t5 0x0 0 +t6 0x0 0 +pc 0x4200583c 0x4200583c + +==================== CURRENT THREAD STACK ===================== +#0 0x4200583c in recur_func () at ../main/test_core_dump.c:70 +#1 0x4200581a in recur_func () at ../main/test_core_dump.c:63 +#2 0x4200581a in recur_func () at ../main/test_core_dump.c:63 +#3 0x42005874 in unaligned_ptr_task (pvParameter=) at ../main/test_core_dump.c:80 +#4 0x40385f2a in vPortEnterCritical () at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:129 +#5 0x00000000 in ?? () +Backtrace stopped: frame did not save the PC + +======================== THREADS INFO ========================= + Id Target Id Frame +* 1 process 1070144160 0x4200583c in recur_func () at ../main/test_core_dump.c:70 + 2 process 1070141676 0x40382dba in esp_crosscore_int_send_yield (core_id=core_id@entry=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 + 3 process 1070138176 0x4200c022 in esp_pm_impl_waiti () at ../../../hal/esp32c3/include/hal/cpu_ll.h:168 + 4 process 1070146556 0x40382dba in esp_crosscore_int_send_yield (core_id=core_id@entry=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 + 5 process 1070131784 0x40385eb4 in vPortClearInterruptMask (mask=1) at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:177 + +==================== THREAD 1 (TCB: 0x3fc91aa0, name: 'unaligned_ptr_t') ===================== +#0 0x4200583c in recur_func () at ../main/test_core_dump.c:70 +#1 0x4200581a in recur_func () at ../main/test_core_dump.c:63 +#2 0x4200581a in recur_func () at ../main/test_core_dump.c:63 +#3 0x42005874 in unaligned_ptr_task (pvParameter=) at ../main/test_core_dump.c:80 +#4 0x40385f2a in vPortEnterCritical () at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:129 +#5 0x00000000 in ?? () +Backtrace stopped: frame did not save the PC + +==================== THREAD 2 (TCB: 0x3fc910ec, name: 'bad_ptr_task') ===================== +#0 0x40382dba in esp_crosscore_int_send_yield (core_id=core_id@entry=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 +#1 0x4038601e in vPortYield () at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:316 +#2 0x00000000 in ?? () +Backtrace stopped: frame did not save the PC + +==================== THREAD 3 (TCB: 0x3fc90340, name: 'IDLE') ===================== +#0 0x4200c022 in esp_pm_impl_waiti () at ../../../hal/esp32c3/include/hal/cpu_ll.h:168 +#1 0x4200b476 in esp_vApplicationIdleHook () at /builds/espressif/esp-idf/components/esp_system/freertos_hooks.c:63 +Backtrace stopped: Cannot access memory at address 0xa5a5a5b1 + +==================== THREAD 4 (TCB: 0x3fc923fc, name: 'failed_assert_t') ===================== +#0 0x40382dba in esp_crosscore_int_send_yield (core_id=core_id@entry=0) at /builds/espressif/esp-idf/components/esp_system/crosscore_int.c:144 +#1 0x4038601e in vPortYield () at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:316 +#2 0x00000000 in ?? () +Backtrace stopped: frame did not save the PC + +==================== THREAD 5 (TCB: 0x3fc8ea48, name: 'esp_timer') ===================== +#0 0x40385eb4 in vPortClearInterruptMask (mask=1) at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:177 +#1 0x40385ede in vPortExitCritical () at /builds/espressif/esp-idf/components/freertos/port/riscv/port.c:138 +Backtrace stopped: Cannot access memory at address 0xa5a5a5b1 + + +======================= ALL MEMORY REGIONS ======================== +Name Address Size Attrs +.rtc.text 0x50000000 0x0 RW +.rtc.dummy 0x50000000 0x0 RW +.rtc.force_fast 0x50000000 0x0 RW +.rtc.data 0x50000000 0x10 RW A +.rtc_noinit 0x50000010 0x0 RW +.rtc.force_slow 0x50000010 0x0 RW +.iram0.text 0x40380000 0x9d00 R XA +.dram0.data 0x3fc89e00 0x1b34 RW A +.noinit 0x3fc8b934 0x0 RW +.flash.text 0x42000020 0x168a0 R XA +.flash.appdesc 0x3c020020 0x100 R A +.flash.rodata 0x3c020120 0x32b8 RW A +.eh_frame 0x3c0233d8 0x708 R A +.flash.rodata_noload 0x3c023ae0 0x0 RW +.iram0.data 0x40389e00 0x0 RW +.iram0.bss 0x40389e00 0x0 RW +.dram0.heap_start 0x3fc8cce0 0x0 RW +.coredump.tasks.data 0x3fc91aa0 0x154 RW +.coredump.tasks.data 0x3fc918e0 0x1b0 RW +.coredump.tasks.data 0x3fc910ec 0x154 RW +.coredump.tasks.data 0x3fc90f90 0x150 RW +.coredump.tasks.data 0x3fc90340 0x154 RW +.coredump.tasks.data 0x3fc901f0 0x140 RW +.coredump.tasks.data 0x3fc923fc 0x154 RW +.coredump.tasks.data 0x3fc922a0 0x150 RW +.coredump.tasks.data 0x3fc8ea48 0x154 RW +.coredump.tasks.data 0x3fc8e8f0 0x150 RW + +====================== CORE DUMP MEMORY CONTENTS ======================== +.coredump.tasks.data 0x3fc91aa0 0x154 RW +0x3fc91aa0: 0x3fc91940 0x00000064 0x3fc8c434 0x3fc8c434 +0x3fc91ab0: 0x3fc91aa0 0x3fc8c42c 0x00000012 0x19fbafbf +0x3fc91ac0: 0x50005790 0x3fc91aa0 0x00000000 0x00000007 +0x3fc91ad0: 0x3fc9129c 0x6c616e75 0x656e6769 0x74705f64 +0x3fc91ae0: 0x00745f72 0x00000000 0x3fc91a90 0x00000007 +0x3fc91af0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b00: 0x3fc8d50c 0x3fc8d574 0x3fc8d5dc 0x00000000 +0x3fc91b10: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3fc91b20: 0x00000000 0x4200cbdc 0x00000000 0x00000000 +0x3fc91b30: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b40: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b50: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b60: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b70: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b80: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91b90: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91ba0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91bb0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91bc0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91bd0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91be0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91bf0: 0x3fc90000 +.coredump.tasks.data 0x3fc918e0 0x1b0 RW +0x3fc918e0: 0x4200583c 0x42005836 0x3fc91980 0x3fc8a600 +0x3fc918f0: 0x3fc8e7cc 0x00000000 0x3fc915dc 0x00000000 +0x3fc91900: 0x00000000 0x00000000 0x00000020 0x3fc915b8 +0x3fc91910: 0x00000000 0x00000007 0xffffffad 0x00000005 +0x3fc91920: 0x42002e30 0x00000000 0x00000000 0x00000000 +0x3fc91930: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91940: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91950: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91960: 0x00001881 0x40380001 0x00000007 0x00000005 +0x3fc91970: 0x00000000 0x00000002 0x42002e30 0x00000000 +0x3fc91980: 0x00000000 0x00000000 0x00000000 0x00000003 +0x3fc91990: 0x00000000 0x3fc91afc 0x3fc8d574 0x4200581a +0x3fc919a0: 0x00000000 0x00000000 0x00000000 0x00000003 +0x3fc919b0: 0x00000000 0x3fc919c0 0x00000002 0x4200581a +0x3fc919c0: 0x3c021368 0x0000001e 0x3c020538 0x00000003 +0x3fc919d0: 0x00000000 0x00000000 0x00000000 0x42005874 +0x3fc919e0: 0x00000000 0x00000000 0x00000000 0x40385f2a +0x3fc919f0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91a00: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3fc91a10: 0x27146414 0x01010107 0x00000001 0xffffffff +0x3fc91a20: 0x7fefffff 0x00000000 0x3fc00000 0x00000000 +0x3fc91a30: 0x40300000 0x00000000 0x3fe00000 0x00000000 +0x3fc91a40: 0x3ff80000 0x636f4361 0x3fd287a7 0x8b60c8b3 +0x3fc91a50: 0x3fc68a28 0x509f79fb 0x3fd34413 0x00000000 +0x3fc91a60: 0x3ff00000 0x00000000 0x40240000 0x00000000 +0x3fc91a70: 0x401c0000 0x00000000 0x40140000 0x00000000 +0x3fc91a80: 0x43500000 0x00000010 0x00000000 0x00527a03 +.coredump.tasks.data 0x3fc910ec 0x154 RW +0x3fc910ec: 0x3fc90f90 0x00000064 0x3fc8c40c 0x3fc8c40c +0x3fc910fc: 0x3fc910ec 0x3fc8c404 0x00000014 0xf344b5c1 +0x3fc9110c: 0x65710001 0x3fc910ec 0x00000000 0x00000005 +0x3fc9111c: 0x3fc908e8 0x5f646162 0x5f727470 0x6b736174 +0x3fc9112c: 0x003a2000 0x00000000 0x3fc910e0 0x00000005 +0x3fc9113c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9114c: 0x3fc8d50c 0x3fc8d574 0x3fc8d5dc 0x00000000 +0x3fc9115c: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3fc9116c: 0x00000000 0x4200cbdc 0x00000000 0x00000000 +0x3fc9117c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9118c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9119c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc911ac: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc911bc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc911cc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc911dc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc911ec: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc911fc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9120c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9121c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9122c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9123c: 0x3fc90000 +.coredump.tasks.data 0x3fc90f90 0x150 RW +0x3fc90f90: 0x40382dba 0x4038601e 0x3fc90fdc 0x40381656 +0x3fc90fa0: 0x3fc8de1c 0x00000000 0x00000000 0x00000000 +0x3fc90fb0: 0x00000064 0x00000000 0x00000001 0x00000001 +0x3fc90fc0: 0x00000064 0x00000004 0x00000001 0x600c0000 +0x3fc90fd0: 0x42002e30 0x00000000 0x00000000 0x00000000 +0x3fc90fe0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90ff0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91000: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91010: 0x00000000 0x00000000 0x00000064 0x40384d2e +0x3fc91020: 0x00000000 0x00000000 0x00000000 0x420057d4 +0x3fc91030: 0x00000000 0x00000000 0x00000000 0x40385f2a +0x3fc91040: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc91050: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3fc91060: 0x27146414 0x01010107 0x00000001 0xffffffff +0x3fc91070: 0x7fefffff 0x00000000 0x3fc00000 0x00000000 +0x3fc91080: 0x40300000 0x00000000 0x3fe00000 0x00000000 +0x3fc91090: 0x3ff80000 0x636f4361 0x3fd287a7 0x8b60c8b3 +0x3fc910a0: 0x3fc68a28 0x509f79fb 0x3fd34413 0x00000000 +0x3fc910b0: 0x3ff00000 0x00000000 0x40240000 0x00000000 +0x3fc910c0: 0x401c0000 0x00000000 0x40140000 0x00000000 +0x3fc910d0: 0x43500000 0x00000010 0x00000000 0x00527a03 +.coredump.tasks.data 0x3fc90340 0x154 RW +0x3fc90340: 0x3fc901f0 0x3fc8ccf4 0x3fc8c3a8 0x3fc8c3a8 +0x3fc90350: 0x3fc90340 0x3fc8c3a0 0x00000019 0xbd7f94fc +0x3fc90360: 0x630cb50a 0x3fc90340 0x00000000 0x00000000 +0x3fc90370: 0x3fc8fd3c 0x454c4449 0xf15df700 0xa9bc0d73 +0x3fc90380: 0x006d70f2 0x00000000 0x3fc90330 0x00000000 +0x3fc90390: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc903a0: 0x3fc8d50c 0x3fc8d574 0x3fc8d5dc 0x00000000 +0x3fc903b0: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3fc903c0: 0x00000000 0x4200cbdc 0x00000000 0x00000000 +0x3fc903d0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc903e0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc903f0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90400: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90410: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90420: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90430: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90440: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90450: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90460: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90470: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90480: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90490: 0x3fc90000 +.coredump.tasks.data 0x3fc901f0 0x140 RW +0x3fc901f0: 0x4200c022 0x4200b476 0xa5a5a5a5 0xa5a5a5a5 +0x3fc90200: 0x3fc8d06c 0x00000000 0x00000000 0x00000000 +0x3fc90210: 0x00000008 0x00000001 0x00000001 0x3fc9024f +0x3fc90220: 0x00000000 0x3fc90340 0x3fc8c984 0x00000000 +0x3fc90230: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90240: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90250: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90260: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc90270: 0x00000000 0x00000000 0x00000000 0x40384c1e +0x3fc90280: 0x00000000 0x00000000 0x00000000 0x40385f2a +0x3fc90290: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc902a0: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3fc902b0: 0x27146414 0x01010107 0x00000001 0xffffffff +0x3fc902c0: 0x7fefffff 0x00000000 0x3fc00000 0x00000000 +0x3fc902d0: 0x40300000 0x00000000 0x3fe00000 0x00000000 +0x3fc902e0: 0x3ff80000 0x636f4361 0x3fd287a7 0x8b60c8b3 +0x3fc902f0: 0x3fc68a28 0x509f79fb 0x3fd34413 0x00000000 +0x3fc90300: 0x3ff00000 0x00000000 0x40240000 0x00000000 +0x3fc90310: 0x401c0000 0x00000000 0x40140000 0x00000000 +0x3fc90320: 0x43500000 0x00000010 0x00000000 0x00527a03 +.coredump.tasks.data 0x3fc923fc 0x154 RW +0x3fc923fc: 0x3fc922a0 0x000000c8 0x3fc8c59c 0x3fc8c59c +0x3fc9240c: 0x3fc923fc 0x3fc8c594 0x0000000f 0xbcb661fc +0x3fc9241c: 0xe6fdbe55 0x3fc923fc 0x00000000 0x0000000a +0x3fc9242c: 0x3fc91bf8 0x6c696166 0x615f6465 0x72657373 +0x3fc9243c: 0x00745f74 0x00000000 0x3fc923f0 0x0000000a +0x3fc9244c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9245c: 0x3fc8d50c 0x3fc8d574 0x3fc8d5dc 0x00000000 +0x3fc9246c: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3fc9247c: 0x00000000 0x4200cbdc 0x00000000 0x00000000 +0x3fc9248c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9249c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc924ac: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc924bc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc924cc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc924dc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc924ec: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc924fc: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9250c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9251c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9252c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9253c: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc9254c: 0x3fc90000 +.coredump.tasks.data 0x3fc922a0 0x150 RW +0x3fc922a0: 0x40382dba 0x4038601e 0x3fc922ec 0x40381656 +0x3fc922b0: 0x3fc8f12c 0x00000000 0x00000000 0x00000000 +0x3fc922c0: 0x00000064 0x00000000 0x00000001 0x00000001 +0x3fc922d0: 0x000000c8 0x00000004 0x00000001 0x600c0000 +0x3fc922e0: 0x42002e30 0x00000000 0x00000000 0x00000000 +0x3fc922f0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc92300: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc92310: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc92320: 0x00000000 0x00000000 0x00000064 0x40384d2e +0x3fc92330: 0x00000000 0x00000000 0x00000000 0x420056be +0x3fc92340: 0x00000000 0x00000000 0x00000000 0x40385f2a +0x3fc92350: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc92360: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3fc92370: 0x27146414 0x01010107 0x00000001 0xffffffff +0x3fc92380: 0x7fefffff 0x00000000 0x3fc00000 0x00000000 +0x3fc92390: 0x40300000 0x00000000 0x3fe00000 0x00000000 +0x3fc923a0: 0x3ff80000 0x636f4361 0x3fd287a7 0x8b60c8b3 +0x3fc923b0: 0x3fc68a28 0x509f79fb 0x3fd34413 0x00000000 +0x3fc923c0: 0x3ff00000 0x00000000 0x40240000 0x00000000 +0x3fc923d0: 0x401c0000 0x00000000 0x40140000 0x00000000 +0x3fc923e0: 0x43500000 0x00000010 0x00000000 0x00527a03 +.coredump.tasks.data 0x3fc8ea48 0x154 RW +0x3fc8ea48: 0x3fc8e8f0 0x3fc8ccf4 0x3fc8c5d8 0x3fc8c5d8 +0x3fc8ea58: 0x3fc8ea48 0x3fc8c5d0 0x00000003 0x2051a1bc +0x3fc8ea68: 0xbd460200 0x3fc8ea48 0x00000000 0x00000016 +0x3fc8ea78: 0x3fc8da44 0x5f707365 0x656d6974 0x34820072 +0x3fc8ea88: 0x000122d2 0x00000000 0x3fc8ea40 0x00000016 +0x3fc8ea98: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eaa8: 0x3fc8d50c 0x3fc8d574 0x3fc8d5dc 0x00000000 +0x3fc8eab8: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3fc8eac8: 0x00000000 0x4200cbdc 0x00000000 0x00000000 +0x3fc8ead8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eae8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eaf8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb08: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb18: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb28: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb38: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb48: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb58: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb68: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb78: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb88: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8eb98: 0x3fc80001 +.coredump.tasks.data 0x3fc8e8f0 0x150 RW +0x3fc8e8f0: 0x40385eb4 0x40385ede 0xa5a5a5a5 0xa5a5a5a5 +0x3fc8e900: 0x3fc8b77c 0x00000000 0x00000000 0x00000000 +0x3fc8e910: 0x00000000 0xffffffff 0x00000001 0x00000001 +0x3fc8e920: 0xffffffff 0x00000004 0x3fc8d000 0x600c2000 +0x3fc8e930: 0x00000000 0x00000000 0x00000001 0x00000000 +0x3fc8e940: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8e950: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8e960: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8e970: 0x00000001 0xffffffff 0x00000000 0x403859ba +0x3fc8e980: 0x00000000 0x00000000 0x00000000 0x42004c56 +0x3fc8e990: 0x00000000 0x00000000 0x00000000 0x40385f2a +0x3fc8e9a0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3fc8e9b0: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3fc8e9c0: 0x27146414 0x01010107 0x00000001 0xffffffff +0x3fc8e9d0: 0x7fefffff 0x00000000 0x3fc00000 0x00000000 +0x3fc8e9e0: 0x40300000 0x00000000 0x3fe00000 0x00000000 +0x3fc8e9f0: 0x3ff80000 0x636f4361 0x3fd287a7 0x8b60c8b3 +0x3fc8ea00: 0x3fc68a28 0x509f79fb 0x3fd34413 0x00000000 +0x3fc8ea10: 0x3ff00000 0x00000000 0x40240000 0x00000000 +0x3fc8ea20: 0x401c0000 0x00000000 0x40140000 0x00000000 +0x3fc8ea30: 0x43500000 0x00000010 0x00000000 0x00527a03 + +===================== ESP32 CORE DUMP END ===================== +=============================================================== +Done! diff --git a/components/espcoredump/test/esp32s2/coredump.b64 b/components/espcoredump/test/esp32s2/coredump.b64 new file mode 100644 index 000000000000..608457e1ab65 --- /dev/null +++ b/components/espcoredump/test/esp32s2/coredump.b64 @@ -0,0 +1,173 @@ +9BoAAAABAgAAAAAAAAAAAAAAAAA= +f0VMRgEBAQAAAAAAAAAAAAQAXgABAAAAAAAAADQAAAAAAAAAAAAAADQAIAAMACgA +AAAAAA== +BAAAALQBAAAAAAAAAAAAAOALAADgCwAABgAAAAAAAAA= +AQAAAJQNAACYNfw/mDX8P1QBAABUAQAABgAAAAAAAAA= +AQAAAOgOAAAwNPw/MDT8P2ABAABgAQAABgAAAAAAAAA= +AQAAAEgQAADkK/w/5Cv8P1QBAABUAQAABgAAAAAAAAA= +AQAAAJwRAADgKvw/4Cr8P/wAAAD8AAAABgAAAAAAAAA= +AQAAAJgSAAAAHvw/AB78P1QBAABUAQAABgAAAAAAAAA= +AQAAAOwTAADgHPw/4Bz8PxgBAAAYAQAABgAAAAAAAAA= +AQAAAAQVAAD0Pvw/9D78P1QBAABUAQAABgAAAAAAAAA= +AQAAAFgWAADwPfw/8D38P/wAAAD8AAAABgAAAAAAAAA= +AQAAAFQXAABo/fk/aP35P1QBAABUAQAABgAAAAAAAAA= +AQAAAKgYAABA/Pk/QPz5PyABAAAgAQAABgAAAAAAAAA= +BAAAAMgZAAAAAAAAAAAAABQBAAAUAQAABgAAAAAAAAA= +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmDX8PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJVgIQCANBgAAAAAAAAAAAAAAAAAZAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYCIDANPw/ +AgAAAAw1/D8ANfw/AAAAAJTo+T8AAAAABQAAAK3///8gAAAA9DX8P7fr+T+AAAAA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5Cv8PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj3wCQCACBgAAAAAAAAAAAAAAAAAbAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMNXCIBwK/w/ +ZAAAAMjZ+z8hAAYA6PT7PyMLBgB+AAAAj3wCgFAr/D8AAAAAZQAAAIz3+z/QFfw/ +AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB78PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvlgJQCAFBgAAAAAAAAAAAAAAAAAeAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPqgCIBwHfw/ +AAAAAAEAAAABAAAAAQAAgCMABgAAAAAA4qUIgEAd/D8AAAAAgKQBQCAABgAAwABg +AAAAAEsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9D78PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj3wCQCAHBgAAAAAAAAAAAAAAAAAWAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANXCICAPvw/ +ZAAAAMjZ+z8hAAYA0DT8PzDb+z9lAAAAj3wCgGA+/D8AAAAAyQAAAIz3+z/QFfw/ +AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +CAAAAEwCAAABAAAA +Q09SRQAAAAA= +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaP35PwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1KgBQCAOBgAAAAAAAAAAAAAAAAAKAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCPAoDQ/Pk/ +Iw4GAAAAAAAgDgYAcN7/P8De/z8EAAAAXVcCgKD8+T8w2/s/AAAAANDi/z+w4v8/ +AIBAP3ACAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +oDT8P2UAAAAs9vs/LPb7P5g1/D8k9vs/EgAAACQtCxmAeZ+mmDX8PwAAAAAHAAAA +lC38P3VuYWxpZ25lZF9wdHJfdAAAAAAAkDX8PwcAAAAAAAAAAAAAAAAAAAAAAAAA +LOj5P5To+T/86Pk/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgKQBQAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAD8Pw== +776t3iVYCEAwDQYAAFgIgMA0/D8CAAAADDX8PwA1/D8AAAAAlOj5PwAAAAAFAAAA +rf///yAAAAD0Nfw/t+v5P4AAAAABAAAAAAAAABkAAAAdAAAABQAAALfr+T+AAAAA +KT8CQAz9+z8o6vk/AAAAALfr+T+AAAAAAQAAAAAAAAAAWAiA8DT8PwEAAACU6Pk/ +AwAAADDb+z8BAAAAAQAAAAA1/D8AAAAAlOj5PwAAAABIWAiAIDX8PwoAAADI2fs/ +AwAAAB4AAADIJAA/AQAAAIz3+z/QFfw/AAgAAAAAAACojgKAUDX8PwAAAAAAAAAA +AwAAAFA1/D8AAAAAAAAAACEABgAQK/w/MNv7P2UAAAAAAAAAcDX8PzBYCEAAAAAA +IwAGAOj0+z8jDAYAAQAAAAAAAACQNfw/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAA== +4Cr8P2UAAAAE9vs/BPb7P+Qr/D/89fs/FAAAAK2y+dxPd59C5Cv8PwAAAAAFAAAA +4CP8P2JhZF9wdHJfdGFzawBL8gAAAAAA3Cv8PwUAAAAAAAAAAAAAAAAAAAAAAAAA +LOj5P5To+T/86Pk/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgKQBQAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAD8Pw== +hD8CQI98AkAwAgYAw1cIgHAr/D9kAAAAyNn7PyEABgDo9Ps/IwsGAH4AAACPfAKA +UCv8PwAAAABlAAAAjPf7P9AV/D8ACAAAAAAAABsAAAD//wAAAAAAAOw/AkDQFfw/ +mGoCQEzz+z8AAAAAAAAAAAAW/D/QFfw/AAgAAAAAAACojgKAkCv8PwAAAAAAAAAA +IQAGAOj0+z8jCwYAfgAAAAAAAACwK/w/tFcIQAAAAAAjAAYA6PT7PyMHBgDwFPw/ +AAAAANAr/D8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +4Bz8P9T/+z+g9fs/oPX7PwAe/D+Y9fs/GQAAAN+unk0KCuwxAB78PwAAAAAAAAAA +/Bf8P0lETEUAUS3dFKUJQJUKzwAAAAAA+B38PwAAAAAAAAAAAAAAAAAAAAAAAAAA +LOj5P5To+T/86Pk/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgKQBQAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAD8Pw== +hD8CQL5YCUAwBQYA+qAIgHAd/D8AAAAAAQAAAAEAAAABAACAIwAGAAAAAADipQiA +QB38PwAAAACApAFAIAAGAADAAGAAAAAASwAAAB4AAAD//wAAAAAAAOw/AkAAwABg +mGoCQGzl+z+lpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWZewKAkB38PwgAAAABAAAA +8B38PwAAAAAAAAAAAAAAAKiOAoCwHfw/AAAAAAAAAAAhAAYA0BX8PzDb+z8BAAAA +AAAAANAd/D+QewJAAAAAACMABgDwFfw/WABMPwEAAAAAAAAA8B38PwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== +8D38P8kAAACM9fs/jPX7P/Q+/D+E9fs/DwAAACVcbuqY9yko9D78PwAAAAAKAAAA +8Db8P2ZhaWxlZF9hc3NlcnRfdAAAAAAA7D78PwoAAAAAAAAAAAAAAAAAAAAAAAAA +LOj5P5To+T/86Pk/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgKQBQAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAD8Pw== +hD8CQI98AkAwBwYAA1cIgIA+/D9kAAAAyNn7PyEABgDQNPw/MNv7P2UAAACPfAKA +YD78PwAAAADJAAAAjPf7P9AV/D8ACAAAAAAAABYAAAD//wAAAAAAAOw/AkDQFfw/ +mGoCQFwG/D8AAAAAAAAAAIz3+z/QFfw/AAgAAAAAAACojgKAoD78PwAAAAAAAAAA +IQAGANA0/D8w2/s/ZQAAAAAAAADAPvw/9FYIQAAAAAAjAAYA6PT7PyMBBgABAAAA +AAAAAOA+/D8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA +QPz5PxTg+T8w9fs/MPX7P2j9+T8o9fs/AwAAAH09zTkyjGvQaP35PwAAAAAWAAAA +ZO35P2VzcF90aW1lcgCBZQYAyQAAAAAAYP35PxYAAAAAAAAAAAAAAAAAAAAAAAAA +LOj5P5To+T/86Pk/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgKQBQAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AQD5Pw== +hD8CQNSoAUAwDgYAwI8CgND8+T8jDgYAAAAAACAOBgBw3v8/wN7/PwQAAABdVwKA +oPz5PzDb+z8AAAAA0OL/P7Di/z8AgEA/cAIAPwoAAAD//wAAAAAAAOw/AkCw4v8/ +mGoCQNzE+T+lpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaUWiAKA4Pz5P8jZ+z8AAAAA +C08IgAD9+T8AAAAAAQAAAAAAAADQ4f8/IwEGAAAAAACojgKAIP35PwAAAAAAAAAA +yNn7P/D0+z8AAAAAAAAAAAAAAABA/fk//E4IQAAAAAAjAQYAMOL/PwvqoQHIzQJA +AAAAAGD9+T8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLXwmAgOL/PyD1+z8AAAAA +FAAAAEgAAABKIAAA +RVNQX0NPUkVfRFVNUF9JTkZPAAA= +AAECADI3Y2E4NGVhMmZiMzIwMGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +DAAAAJQAAAClAgAA +RVhUUkFfSU5GTwAA +mDX8P+gAAAAdAAAA7gAAAAUAAADCAAAAAAAAAMMAAAAAAAAAxAAAAAAAAADFAAAA +AAAAAMYAAAAAAAAAsQAAAEueCECyAAAAAAAAALMAAAAAAAAAtAAAAAAAAAC1AAAA +AAAAALYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA== +StKw0w== diff --git a/components/espcoredump/test/esp32s2/expected_output b/components/espcoredump/test/esp32s2/expected_output new file mode 100644 index 000000000000..bded19305728 --- /dev/null +++ b/components/espcoredump/test/esp32s2/expected_output @@ -0,0 +1,349 @@ +espcoredump.py v0.4-dev +=============================================================== +==================== ESP32 CORE DUMP START ==================== + +Crashed task handle: 0x3ffc3598, name: 'unaligned_ptr_t', GDB name: 'process 1073493400' + +================== CURRENT THREAD REGISTERS =================== +exccause 0x1d (StoreProhibitedCause) +excvaddr 0x5 +epc1 0x40089e4b +epc2 0x0 +epc3 0x0 +epc4 0x0 +epc5 0x0 +epc6 0x0 +eps2 0x0 +eps3 0x0 +eps4 0x0 +eps5 0x0 +eps6 0x0 +pc 0x40085825 0x40085825 +lbeg 0x0 0 +lend 0x0 0 +lcount 0x0 0 +sar 0x19 25 +ps 0x60d20 396576 +threadptr +br +scompare1 +acclo +acchi +m0 +m1 +m2 +m3 +expstate +f64r_lo +f64r_hi +f64s +fcr +fsr +a0 0x80085800 -2146936832 +a1 0x3ffc34c0 1073493184 +a2 0x2 2 +a3 0x3ffc350c 1073493260 +a4 0x3ffc3500 1073493248 +a5 0x0 0 +a6 0x3ff9e894 1073342612 +a7 0x0 0 +a8 0x5 5 +a9 0xffffffad -83 +a10 0x20 32 +a11 0x3ffc35f4 1073493492 +a12 0x3ff9ebb7 1073343415 +a13 0x80 128 +a14 0x1 1 +a15 0x0 0 + +==================== CURRENT THREAD STACK ===================== +#0 0x40085825 in recur_func () at ../main/test_core_dump.c:70 +#1 0x40085800 in recur_func () at ../main/test_core_dump.c:63 +#2 0x40085800 in recur_func () at ../main/test_core_dump.c:63 +#3 0x40085848 in unaligned_ptr_task (pvParameter=0x0) at ../main/test_core_dump.c:80 +#4 0x40028ea8 in vPortTaskWrapper (pxCode=0x40085830 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +======================== THREADS INFO ========================= + Id Target Id Frame +* 1 process 1073493400 0x40085825 in recur_func () at ../main/test_core_dump.c:70 + 2 process 1073490916 0x40027c8f in vTaskDelay (xTicksToDelay=100) at ../../../hal/esp32s2/include/hal/cpu_ll.h:33 + 3 process 1073487360 0x400958be in esp_pm_impl_waiti () at ../../../hal/esp32s2/include/hal/cpu_ll.h:202 + 4 process 1073495796 0x40027c8f in vTaskDelay (xTicksToDelay=100) at ../../../hal/esp32s2/include/hal/cpu_ll.h:33 + 5 process 1073347944 0x4001a8d4 in ?? () + +==================== THREAD 1 (TCB: 0x3ffc3598, name: 'unaligned_ptr_t') ===================== +#0 0x40085825 in recur_func () at ../main/test_core_dump.c:70 +#1 0x40085800 in recur_func () at ../main/test_core_dump.c:63 +#2 0x40085800 in recur_func () at ../main/test_core_dump.c:63 +#3 0x40085848 in unaligned_ptr_task (pvParameter=0x0) at ../main/test_core_dump.c:80 +#4 0x40028ea8 in vPortTaskWrapper (pxCode=0x40085830 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 2 (TCB: 0x3ffc2be4, name: 'bad_ptr_task') ===================== +#0 0x40027c8f in vTaskDelay (xTicksToDelay=100) at ../../../hal/esp32s2/include/hal/cpu_ll.h:33 +#1 0x400857c3 in bad_ptr_task (pvParameter=0x0) at ../main/test_core_dump.c:43 +#2 0x40028ea8 in vPortTaskWrapper (pxCode=0x400857b4 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 3 (TCB: 0x3ffc1e00, name: 'IDLE') ===================== +#0 0x400958be in esp_pm_impl_waiti () at ../../../hal/esp32s2/include/hal/cpu_ll.h:202 +#1 0x4008a0fa in esp_vApplicationIdleHook () at /builds/espressif/esp-idf/components/esp_system/freertos_hooks.c:63 +#2 0x40027b99 in prvIdleTask (pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/tasks.c:3959 +#3 0x40028ea8 in vPortTaskWrapper (pxCode=0x40027b90 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 4 (TCB: 0x3ffc3ef4, name: 'failed_assert_t') ===================== +#0 0x40027c8f in vTaskDelay (xTicksToDelay=100) at ../../../hal/esp32s2/include/hal/cpu_ll.h:33 +#1 0x40085703 in failed_assert_task (pvParameter=0x0) at ../main/test_core_dump.c:89 +#2 0x40028ea8 in vPortTaskWrapper (pxCode=0x400856f4 , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + +==================== THREAD 5 (TCB: 0x3ff9fd68, name: 'esp_timer') ===================== +#0 0x4001a8d4 in ?? () +#1 0x40028fc0 in vPortExitCritical (mux=0x3ffbd9c8 ) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:447 +#2 0x40028816 in ulTaskGenericNotifyTake (uxIndexToWait=0, xClearCountOnExit=1, xTicksToWait=) at /builds/espressif/esp-idf/components/freertos/tasks.c:5370 +#3 0x40084f0b in timer_task (arg=0x0) at /builds/espressif/esp-idf/components/esp_timer/src/esp_timer.c:392 +#4 0x40028ea8 in vPortTaskWrapper (pxCode=0x40084efc , pvParameters=0x0) at /builds/espressif/esp-idf/components/freertos/port/xtensa/port.c:159 + + +======================= ALL MEMORY REGIONS ======================== +Name Address Size Attrs +.rtc.text 0x40070000 0x0 RW +.rtc.dummy 0x3ff9e000 0x0 RW +.rtc.force_fast 0x3ff9e000 0x0 RW +.rtc.data 0x50000000 0x10 RW A +.rtc_noinit 0x50000010 0x0 RW +.rtc.force_slow 0x50000010 0x0 RW +.iram0.vectors 0x40022000 0x403 R XA +.iram0.text 0x40022404 0xaa08 R XA +.dram0.data 0x3ffbce10 0x2520 RW A +.noinit 0x3ffbf330 0x0 RW +.ext_ram.bss 0x3f500000 0x0 RW +.flash.appdesc 0x3f000020 0x100 R A +.flash.rodata 0x3f000120 0x3874 RW A +.flash.rodata_noload 0x3f003994 0x0 RW +.flash.text 0x40080020 0x1612b R XA +.iram0.text_end 0x4002ce0c 0x0 RW +.dram0.heap_start 0x3ffbffc0 0x0 RW +.coredump.tasks.data 0x3ffc3598 0x154 RW +.coredump.tasks.data 0x3ffc3430 0x160 RW +.coredump.tasks.data 0x3ffc2be4 0x154 RW +.coredump.tasks.data 0x3ffc2ae0 0xfc RW +.coredump.tasks.data 0x3ffc1e00 0x154 RW +.coredump.tasks.data 0x3ffc1ce0 0x118 RW +.coredump.tasks.data 0x3ffc3ef4 0x154 RW +.coredump.tasks.data 0x3ffc3df0 0xfc RW +.coredump.tasks.data 0x3ff9fd68 0x154 RW +.coredump.tasks.data 0x3ff9fc40 0x120 RW + +====================== CORE DUMP MEMORY CONTENTS ======================== +.coredump.tasks.data 0x3ffc3598 0x154 RW +0x3ffc3598: 0x3ffc34a0 0x00000065 0x3ffbf62c 0x3ffbf62c +0x3ffc35a8: 0x3ffc3598 0x3ffbf624 0x00000012 0x190b2d24 +0x3ffc35b8: 0xa69f7980 0x3ffc3598 0x00000000 0x00000007 +0x3ffc35c8: 0x3ffc2d94 0x6c616e75 0x656e6769 0x74705f64 +0x3ffc35d8: 0x00745f72 0x00000000 0x3ffc3590 0x00000007 +0x3ffc35e8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc35f8: 0x3ff9e82c 0x3ff9e894 0x3ff9e8fc 0x00000000 +0x3ffc3608: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3ffc3618: 0x00000000 0x4001a480 0x00000000 0x00000000 +0x3ffc3628: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3638: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3648: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3658: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3668: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3678: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3688: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3698: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc36a8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc36b8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc36c8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc36d8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc36e8: 0x3ffc0000 +.coredump.tasks.data 0x3ffc3430 0x160 RW +0x3ffc3430: 0xdeadbeef 0x40085825 0x00060d30 0x80085800 +0x3ffc3440: 0x3ffc34c0 0x00000002 0x3ffc350c 0x3ffc3500 +0x3ffc3450: 0x00000000 0x3ff9e894 0x00000000 0x00000005 +0x3ffc3460: 0xffffffad 0x00000020 0x3ffc35f4 0x3ff9ebb7 +0x3ffc3470: 0x00000080 0x00000001 0x00000000 0x00000019 +0x3ffc3480: 0x0000001d 0x00000005 0x3ff9ebb7 0x00000080 +0x3ffc3490: 0x40023f29 0x3ffbfd0c 0x3ff9ea28 0x00000000 +0x3ffc34a0: 0x3ff9ebb7 0x00000080 0x00000001 0x00000000 +0x3ffc34b0: 0x80085800 0x3ffc34f0 0x00000001 0x3ff9e894 +0x3ffc34c0: 0x00000003 0x3ffbdb30 0x00000001 0x00000001 +0x3ffc34d0: 0x3ffc3500 0x00000000 0x3ff9e894 0x00000000 +0x3ffc34e0: 0x80085848 0x3ffc3520 0x0000000a 0x3ffbd9c8 +0x3ffc34f0: 0x00000003 0x0000001e 0x3f0024c8 0x00000001 +0x3ffc3500: 0x3ffbf78c 0x3ffc15d0 0x00000800 0x00000000 +0x3ffc3510: 0x80028ea8 0x3ffc3550 0x00000000 0x00000000 +0x3ffc3520: 0x00000003 0x3ffc3550 0x00000000 0x00000000 +0x3ffc3530: 0x00060021 0x3ffc2b10 0x3ffbdb30 0x00000065 +0x3ffc3540: 0x00000000 0x3ffc3570 0x40085830 0x00000000 +0x3ffc3550: 0x00060023 0x3ffbf4e8 0x00060c23 0x00000001 +0x3ffc3560: 0x00000000 0x3ffc3590 0x00000000 0x00000000 +0x3ffc3570: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3580: 0x00000000 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffc2be4 0x154 RW +0x3ffc2be4: 0x3ffc2ae0 0x00000065 0x3ffbf604 0x3ffbf604 +0x3ffc2bf4: 0x3ffc2be4 0x3ffbf5fc 0x00000014 0xdcf9b2ad +0x3ffc2c04: 0x429f774f 0x3ffc2be4 0x00000000 0x00000005 +0x3ffc2c14: 0x3ffc23e0 0x5f646162 0x5f727470 0x6b736174 +0x3ffc2c24: 0x00f24b00 0x00000000 0x3ffc2bdc 0x00000005 +0x3ffc2c34: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2c44: 0x3ff9e82c 0x3ff9e894 0x3ff9e8fc 0x00000000 +0x3ffc2c54: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3ffc2c64: 0x00000000 0x4001a480 0x00000000 0x00000000 +0x3ffc2c74: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2c84: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2c94: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2ca4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2cb4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2cc4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2cd4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2ce4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2cf4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2d04: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2d14: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2d24: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2d34: 0x3ffc0000 +.coredump.tasks.data 0x3ffc2ae0 0xfc RW +0x3ffc2ae0: 0x40023f84 0x40027c8f 0x00060230 0x800857c3 +0x3ffc2af0: 0x3ffc2b70 0x00000064 0x3ffbd9c8 0x00060021 +0x3ffc2b00: 0x3ffbf4e8 0x00060b23 0x0000007e 0x80027c8f +0x3ffc2b10: 0x3ffc2b50 0x00000000 0x00000065 0x3ffbf78c +0x3ffc2b20: 0x3ffc15d0 0x00000800 0x00000000 0x0000001b +0x3ffc2b30: 0x0000ffff 0x00000000 0x40023fec 0x3ffc15d0 +0x3ffc2b40: 0x40026a98 0x3ffbf34c 0x00000000 0x00000000 +0x3ffc2b50: 0x3ffc1600 0x3ffc15d0 0x00000800 0x00000000 +0x3ffc2b60: 0x80028ea8 0x3ffc2b90 0x00000000 0x00000000 +0x3ffc2b70: 0x00060021 0x3ffbf4e8 0x00060b23 0x0000007e +0x3ffc2b80: 0x00000000 0x3ffc2bb0 0x400857b4 0x00000000 +0x3ffc2b90: 0x00060023 0x3ffbf4e8 0x00060723 0x3ffc14f0 +0x3ffc2ba0: 0x00000000 0x3ffc2bd0 0x00000000 0x00000000 +0x3ffc2bb0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2bc0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc2bd0: 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffc1e00 0x154 RW +0x3ffc1e00: 0x3ffc1ce0 0x3ffbffd4 0x3ffbf5a0 0x3ffbf5a0 +0x3ffc1e10: 0x3ffc1e00 0x3ffbf598 0x00000019 0x4d9eaedf +0x3ffc1e20: 0x31ec0a0a 0x3ffc1e00 0x00000000 0x00000000 +0x3ffc1e30: 0x3ffc17fc 0x454c4449 0xdd2d5100 0x4009a514 +0x3ffc1e40: 0x00cf0a95 0x00000000 0x3ffc1df8 0x00000000 +0x3ffc1e50: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1e60: 0x3ff9e82c 0x3ff9e894 0x3ff9e8fc 0x00000000 +0x3ffc1e70: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3ffc1e80: 0x00000000 0x4001a480 0x00000000 0x00000000 +0x3ffc1e90: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1ea0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1eb0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1ec0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1ed0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1ee0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1ef0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1f00: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1f10: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1f20: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1f30: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1f40: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1f50: 0x3ffc0000 +.coredump.tasks.data 0x3ffc1ce0 0x118 RW +0x3ffc1ce0: 0x40023f84 0x400958be 0x00060530 0x8008a0fa +0x3ffc1cf0: 0x3ffc1d70 0x00000000 0x00000001 0x00000001 +0x3ffc1d00: 0x80000001 0x00060023 0x00000000 0x8008a5e2 +0x3ffc1d10: 0x3ffc1d40 0x00000000 0x4001a480 0x00060020 +0x3ffc1d20: 0x6000c000 0x00000000 0x0000004b 0x0000001e +0x3ffc1d30: 0x0000ffff 0x00000000 0x40023fec 0x6000c000 +0x3ffc1d40: 0x40026a98 0x3ffbe56c 0xa5a5a5a5 0xa5a5a5a5 +0x3ffc1d50: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3ffc1d60: 0x80027b99 0x3ffc1d90 0x00000008 0x00000001 +0x3ffc1d70: 0x3ffc1df0 0x00000000 0x00000000 0x00000000 +0x3ffc1d80: 0x80028ea8 0x3ffc1db0 0x00000000 0x00000000 +0x3ffc1d90: 0x00060021 0x3ffc15d0 0x3ffbdb30 0x00000001 +0x3ffc1da0: 0x00000000 0x3ffc1dd0 0x40027b90 0x00000000 +0x3ffc1db0: 0x00060023 0x3ffc15f0 0x3f4c0058 0x00000001 +0x3ffc1dc0: 0x00000000 0x3ffc1df0 0x00000000 0x00000000 +0x3ffc1dd0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1de0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc1df0: 0x00000000 0x00000000 +.coredump.tasks.data 0x3ffc3ef4 0x154 RW +0x3ffc3ef4: 0x3ffc3df0 0x000000c9 0x3ffbf58c 0x3ffbf58c +0x3ffc3f04: 0x3ffc3ef4 0x3ffbf584 0x0000000f 0xea6e5c25 +0x3ffc3f14: 0x2829f798 0x3ffc3ef4 0x00000000 0x0000000a +0x3ffc3f24: 0x3ffc36f0 0x6c696166 0x615f6465 0x72657373 +0x3ffc3f34: 0x00745f74 0x00000000 0x3ffc3eec 0x0000000a +0x3ffc3f44: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3f54: 0x3ff9e82c 0x3ff9e894 0x3ff9e8fc 0x00000000 +0x3ffc3f64: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3ffc3f74: 0x00000000 0x4001a480 0x00000000 0x00000000 +0x3ffc3f84: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3f94: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3fa4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3fb4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3fc4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3fd4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3fe4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3ff4: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc4004: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc4014: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc4024: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc4034: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc4044: 0x3ffc0000 +.coredump.tasks.data 0x3ffc3df0 0xfc RW +0x3ffc3df0: 0x40023f84 0x40027c8f 0x00060730 0x80085703 +0x3ffc3e00: 0x3ffc3e80 0x00000064 0x3ffbd9c8 0x00060021 +0x3ffc3e10: 0x3ffc34d0 0x3ffbdb30 0x00000065 0x80027c8f +0x3ffc3e20: 0x3ffc3e60 0x00000000 0x000000c9 0x3ffbf78c +0x3ffc3e30: 0x3ffc15d0 0x00000800 0x00000000 0x00000016 +0x3ffc3e40: 0x0000ffff 0x00000000 0x40023fec 0x3ffc15d0 +0x3ffc3e50: 0x40026a98 0x3ffc065c 0x00000000 0x00000000 +0x3ffc3e60: 0x3ffbf78c 0x3ffc15d0 0x00000800 0x00000000 +0x3ffc3e70: 0x80028ea8 0x3ffc3ea0 0x00000000 0x00000000 +0x3ffc3e80: 0x00060021 0x3ffc34d0 0x3ffbdb30 0x00000065 +0x3ffc3e90: 0x00000000 0x3ffc3ec0 0x400856f4 0x00000000 +0x3ffc3ea0: 0x00060023 0x3ffbf4e8 0x00060123 0x00000001 +0x3ffc3eb0: 0x00000000 0x3ffc3ee0 0x00000000 0x00000000 +0x3ffc3ec0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3ed0: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ffc3ee0: 0x00000000 0x00000000 0x00000000 +.coredump.tasks.data 0x3ff9fd68 0x154 RW +0x3ff9fd68: 0x3ff9fc40 0x3ff9e014 0x3ffbf530 0x3ffbf530 +0x3ff9fd78: 0x3ff9fd68 0x3ffbf528 0x00000003 0x39cd3d7d +0x3ff9fd88: 0xd06b8c32 0x3ff9fd68 0x00000000 0x00000016 +0x3ff9fd98: 0x3ff9ed64 0x5f707365 0x656d6974 0x65810072 +0x3ff9fda8: 0x00c90006 0x00000000 0x3ff9fd60 0x00000016 +0x3ff9fdb8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fdc8: 0x3ff9e82c 0x3ff9e894 0x3ff9e8fc 0x00000000 +0x3ff9fdd8: 0x00000000 0x00000001 0x00000000 0x00000000 +0x3ff9fde8: 0x00000000 0x4001a480 0x00000000 0x00000000 +0x3ff9fdf8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe08: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe18: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe28: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe38: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe48: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe58: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe68: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe78: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe88: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fe98: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fea8: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9feb8: 0x3ff90001 +.coredump.tasks.data 0x3ff9fc40 0x120 RW +0x3ff9fc40: 0x40023f84 0x4001a8d4 0x00060e30 0x80028fc0 +0x3ff9fc50: 0x3ff9fcd0 0x00060e23 0x00000000 0x00060e20 +0x3ff9fc60: 0x3fffde70 0x3fffdec0 0x00000004 0x8002575d +0x3ff9fc70: 0x3ff9fca0 0x3ffbdb30 0x00000000 0x3fffe2d0 +0x3ff9fc80: 0x3fffe2b0 0x3f408000 0x3f000270 0x0000000a +0x3ff9fc90: 0x0000ffff 0x00000000 0x40023fec 0x3fffe2b0 +0x3ff9fca0: 0x40026a98 0x3ff9c4dc 0xa5a5a5a5 0xa5a5a5a5 +0x3ff9fcb0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 +0x3ff9fcc0: 0x80028816 0x3ff9fce0 0x3ffbd9c8 0x00000000 +0x3ff9fcd0: 0x80084f0b 0x3ff9fd00 0x00000000 0x00000001 +0x3ff9fce0: 0x00000000 0x3fffe1d0 0x00060123 0x00000000 +0x3ff9fcf0: 0x80028ea8 0x3ff9fd20 0x00000000 0x00000000 +0x3ff9fd00: 0x3ffbd9c8 0x3ffbf4f0 0x00000000 0x00000000 +0x3ff9fd10: 0x00000000 0x3ff9fd40 0x40084efc 0x00000000 +0x3ff9fd20: 0x00060123 0x3fffe230 0x01a1ea0b 0x4002cdc8 +0x3ff9fd30: 0x00000000 0x3ff9fd60 0x00000000 0x00000000 +0x3ff9fd40: 0x00000000 0x00000000 0x00000000 0x00000000 +0x3ff9fd50: 0x80095f4b 0x3fffe280 0x3ffbf520 0x00000000 + +===================== ESP32 CORE DUMP END ===================== +=============================================================== +Done! diff --git a/components/espcoredump/test/expected_output b/components/espcoredump/test/expected_output deleted file mode 100644 index 6b253277e445..000000000000 --- a/components/espcoredump/test/expected_output +++ /dev/null @@ -1,745 +0,0 @@ -espcoredump.py v0.4-dev -=============================================================== -==================== ESP32 CORE DUMP START ==================== - -Crashed task handle: 0x3ffb6260, name: 'unaligned_ptr_t', GDB name: 'process 1073439328' - -================== CURRENT THREAD REGISTERS =================== -exccause 0x1d (StoreProhibitedCause) -excvaddr 0x5 -epc1 0x400e8547 -epc2 0x0 -epc3 0x0 -epc4 0x40082c40 -epc5 0x0 -epc6 0x0 -epc7 0x0 -eps2 0x0 -eps3 0x0 -eps4 0x60820 -eps5 0x0 -eps6 0x0 -eps7 0x0 -pc 0x400d0e45 0x400d0e45 -lbeg 0x400014fd 1073747197 -lend 0x4000150d 1073747213 -lcount 0xffffffff 4294967295 -sar 0x0 0 -ps 0x60820 395296 -threadptr -br -scompare1 -acclo -acchi -m0 -m1 -m2 -m3 -expstate -f64r_lo -f64r_hi -f64s -fcr -fsr -a0 0x800d0e20 -2146628064 -a1 0x3ffbaad0 1073457872 -a2 0x2 2 -a3 0x3ffbab1c 1073457948 -a4 0x3ffbab10 1073457936 -a5 0x3ffae970 1073408368 -a6 0x0 0 -a7 0x0 0 -a8 0x5 5 -a9 0xffffffad -83 -a10 0x20 32 -a11 0x3ffb62e0 1073439456 -a12 0x1 1 -a13 0x80 128 -a14 0x1 1 -a15 0x0 0 - -==================== CURRENT THREAD STACK ===================== -#0 0x400d0e45 in recur_func () at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:61 -#1 0x400d0e20 in bad_ptr_task (pvParameter=0x1) at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:44 -#2 0x400d0e20 in bad_ptr_task (pvParameter=0xa) at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:44 -#3 0x400d0e68 in recur_func () at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:68 -#4 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -======================== THREADS INFO ========================= - Id Target Id Frame -* 1 process 1073439328 0x400d0e45 in recur_func () at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:61 - 2 process 1073455736 0x400092dc in ?? () - 3 process 1073444404 0x400e85b2 in intrusive_list::intrusive_list (this=0x0) at /home/alexey/projects/esp/esp-idf/components/nvs_flash/src/intrusive_list.h:33 - 4 process 1073442456 0x400e85b2 in intrusive_list::intrusive_list (this=0x0) at /home/alexey/projects/esp/esp-idf/components/nvs_flash/src/intrusive_list.h:33 - 5 process 1073438932 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 - 6 process 1073439832 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 - 7 process 1073447132 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 - 8 process 1073412916 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 - 9 process 1073434712 xQueueGenericReceive (xQueue=0x3ffb4bdc , pvBuffer=0x0, xTicksToWait=, xJustPeeking=0) at /home/alexey/projects/esp/esp-idf/components/freertos/queue.c:1546 - 10 process 1073432952 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 - -==================== THREAD 1 (TCB: 0x3ffb6260, name: 'unaligned_ptr_t') ===================== -#0 0x400d0e45 in recur_func () at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:61 -#1 0x400d0e20 in bad_ptr_task (pvParameter=0x1) at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:44 -#2 0x400d0e20 in bad_ptr_task (pvParameter=0xa) at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:44 -#3 0x400d0e68 in recur_func () at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:68 -#4 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 2 (TCB: 0x3ffba278, name: 'unityTask') ===================== -#0 0x400092dc in ?? () -#1 0x4000930f in ?? () -#2 0x400d60b7 in uart_tx_wait_idle (uart_no=) at ../../../components/esp_rom/include/esp32/rom/uart.h:272 -#3 unity_flush () at /home/alexey/projects/esp/esp-idf/components/unity/unity_port_esp32.c:41 -#4 0x400d5cba in unity_run_tests_by_tag (tag=0x1 , invert=160) at /home/alexey/projects/esp/esp-idf/components/unity/unity_runner.c:199 -#5 0x400d6127 in unity_gets (dst=0x0, len=0) at /home/alexey/projects/esp/esp-idf/components/unity/unity_port_esp32.c:70 -#6 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 3 (TCB: 0x3ffb7634, name: 'IDLE1') ===================== -#0 0x400e85b2 in intrusive_list::intrusive_list (this=0x0) at /home/alexey/projects/esp/esp-idf/components/nvs_flash/src/intrusive_list.h:33 -#1 nvs::HashList::HashList (this=0x0) at /home/alexey/projects/esp/esp-idf/components/nvs_flash/src/nvs_item_hash_list.cpp:20 -#2 0x400d3852 in esp_timer_init () at /home/alexey/projects/esp/esp-idf/components/esp_common/src/esp_timer.c:365 -#3 0x40089d89 in prvCheckTasksWaitingTermination () at /home/alexey/projects/esp/esp-idf/components/freertos/tasks.c:3630 -#4 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 4 (TCB: 0x3ffb6e98, name: 'IDLE0') ===================== -#0 0x400e85b2 in intrusive_list::intrusive_list (this=0x0) at /home/alexey/projects/esp/esp-idf/components/nvs_flash/src/intrusive_list.h:33 -#1 nvs::HashList::HashList (this=0x0) at /home/alexey/projects/esp/esp-idf/components/nvs_flash/src/nvs_item_hash_list.cpp:20 -#2 0x400d3852 in esp_timer_init () at /home/alexey/projects/esp/esp-idf/components/esp_common/src/esp_timer.c:365 -#3 0x40089d89 in prvCheckTasksWaitingTermination () at /home/alexey/projects/esp/esp-idf/components/freertos/tasks.c:3630 -#4 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 5 (TCB: 0x3ffb60d4, name: 'bad_ptr_task') ===================== -#0 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 -#1 0x40089b5e in vTaskDelay (xTicksToDelay=72812) at /home/alexey/projects/esp/esp-idf/components/freertos/tasks.c:1437 -#2 0x400d0de3 in bad_ptr_func () at /home/alexey/projects/esp/esp-idf/components/espcoredump/test/test_core_dump.c:30 -#3 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 6 (TCB: 0x3ffb6458, name: 'failed_assert_t') ===================== -#0 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 -#1 0x40089b5e in vTaskDelay (xTicksToDelay=72812) at /home/alexey/projects/esp/esp-idf/components/freertos/tasks.c:1437 -#2 0x400d0d23 in _stext () at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:111 -#3 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 7 (TCB: 0x3ffb80dc, name: 'Tmr Svc') ===================== -#0 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 -#1 0x4008a901 in prvProcessTimerOrBlockTask (xNextExpireTime=1073428956, xListWasEmpty=0) at /home/alexey/projects/esp/esp-idf/components/freertos/timers.c:553 -#2 0x4008aa33 in prvProcessReceivedCommands () at /home/alexey/projects/esp/esp-idf/components/freertos/timers.c:803 -#3 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 8 (TCB: 0x3ffafb34, name: 'esp_timer') ===================== -#0 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 -#1 0x40088d34 in xQueueGenericReceive (xQueue=0x3ffaeab8, pvBuffer=, xTicksToWait=, xJustPeeking=0) at /home/alexey/projects/esp/esp-idf/components/freertos/queue.c:1542 -#2 0x400d378b in timer_process_alarm (dispatch_method=) at /home/alexey/projects/esp/esp-idf/components/esp_common/src/esp_timer.c:304 -#3 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 9 (TCB: 0x3ffb5058, name: 'ipc1') ===================== -#0 xQueueGenericReceive (xQueue=0x3ffb4bdc , pvBuffer=0x0, xTicksToWait=, xJustPeeking=0) at /home/alexey/projects/esp/esp-idf/components/freertos/queue.c:1546 -#1 0x40081d0f in esp_vApplicationTickHook () at /home/alexey/projects/esp/esp-idf/components/esp_common/src/freertos_hooks.c:41 -#2 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - -==================== THREAD 10 (TCB: 0x3ffb4978, name: 'ipc0') ===================== -#0 0x40081414 in esp_crosscore_isr (arg=0x0) at /home/alexey/projects/esp/esp-idf/components/esp32/crosscore_int.c:60 -#1 0x40088d34 in xQueueGenericReceive (xQueue=0x3ffb44fc , pvBuffer=, xTicksToWait=, xJustPeeking=0) at /home/alexey/projects/esp/esp-idf/components/freertos/queue.c:1542 -#2 0x40081d0f in esp_vApplicationTickHook () at /home/alexey/projects/esp/esp-idf/components/esp_common/src/freertos_hooks.c:41 -#3 0x40088160 in xthal_restore_extra_nw () at /Users/igrokhotkov/e/esp32/hal/hal/state_asm.S:97 - - -======================= ALL MEMORY REGIONS ======================== -Name Address Size Attrs -.rtc.text 0x400c0000 0x0 RW -.rtc.dummy 0x3ff80000 0x0 RW -.rtc.force_fast 0x3ff80000 0x0 RW -.rtc_noinit 0x50000200 0x0 RW -.rtc.force_slow 0x50000200 0x0 RW -.iram0.vectors 0x40080000 0x403 R XA -.iram0.text 0x40080404 0xa970 RWXA -.dram0.data 0x3ffb0000 0x3474 RW A -.noinit 0x3ffb3474 0x0 RW -.flash.rodata 0x3f400020 0x6e4c RW A -.flash.text 0x400d0020 0x188ef R XA -.iram0.text_end 0x4008ad74 0x0 RW -.dram0.heap_start 0x3ffb4cf0 0x0 RW -.coredump.tasks.data 0x3ffb6260 0x17c RW -.coredump.tasks.data 0x3ffbaa10 0x1f0 RW -.coredump.tasks.data 0x3ffba278 0x17c RW -.coredump.tasks.data 0x3ffb9f60 0x304 RW -.coredump.tasks.data 0x3ffb7634 0x17c RW -.coredump.tasks.data 0x3ffb7480 0x1a0 RW -.coredump.tasks.data 0x3ffb6e98 0x17c RW -.coredump.tasks.data 0x3ffb6ce0 0x1a4 RW -.coredump.tasks.data 0x3ffb60d4 0x17c RW -.coredump.tasks.data 0x3ffb5f20 0x1a0 RW -.coredump.tasks.data 0x3ffb6458 0x17c RW -.coredump.tasks.data 0x3ffbb270 0x1a0 RW -.coredump.tasks.data 0x3ffb80dc 0x17c RW -.coredump.tasks.data 0x3ffb7f00 0x1c8 RW -.coredump.tasks.data 0x3ffafb34 0x17c RW -.coredump.tasks.data 0x3ffaf960 0x1c0 RW -.coredump.tasks.data 0x3ffb5058 0x17c RW -.coredump.tasks.data 0x3ffb4ea0 0x1a4 RW -.coredump.tasks.data 0x3ffb4978 0x17c RW -.coredump.tasks.data 0x3ffb47a0 0x1c4 RW - -====================== CORE DUMP MEMORY CONTENTS ======================== -.coredump.tasks.data 0x3ffb6260 0x17c RW -0x3ffb6260: 0x3ffbaa80 0x3ffbaba0 0x00011884 0x3ffb3870 -0x3ffb6270: 0x3ffb3870 0x3ffb6260 0x3ffb3868 0x00000012 -0x3ffb6280: 0x3ffb6418 0x3ffb6418 0x3ffb6260 0x00000000 -0x3ffb6290: 0x00000007 0x3ffba404 0x6c616e75 0x656e6769 -0x3ffb62a0: 0x74705f64 0x00745f72 0x00000001 0x3ffbac00 -0x3ffb62b0: 0x00000000 0x00060c20 0x0000000f 0xcececece -0x3ffb62c0: 0x00000007 0x00000000 0x00000000 0x00000000 -0x3ffb62d0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb62e0: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb62f0: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb6300: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb6310: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6320: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6330: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6340: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6350: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6360: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6370: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6380: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6390: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb63a0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb63b0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb63c0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb63d0: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffbaa10 0x1f0 RW -0x3ffbaa10: 0xdeadbeef 0x400d0e45 0x00060830 0x800d0e20 -0x3ffbaa20: 0x3ffbaad0 0x00000002 0x3ffbab1c 0x3ffbab10 -0x3ffbaa30: 0x3ffae970 0x00000000 0x00000000 0x00000005 -0x3ffbaa40: 0xffffffad 0x00000020 0x3ffb62e0 0x00000001 -0x3ffbaa50: 0x00000080 0x00000001 0x00000000 0x00000000 -0x3ffbaa60: 0x0000001d 0x00000005 0x400014fd 0x4000150d -0x3ffbaa70: 0xffffffff 0x00000001 0x00000080 0x40082404 -0x3ffbaa80: 0x3ffb3edc 0x00000000 0x00000000 0x00000000 -0x3ffbaa90: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffbaaa0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbaab0: 0x00000001 0x00000080 0x00000001 0x00000000 -0x3ffbaac0: 0x800d0e20 0x3ffbab00 0x00000001 0x3ffae970 -0x3ffbaad0: 0x800db5bc 0x3ffbab00 0x0000000a 0x00000003 -0x3ffbaae0: 0x3ffbab10 0x3ffae970 0x00000000 0x00000000 -0x3ffbaaf0: 0x800d0e68 0x3ffbab30 0x0000000a 0x3ffb0c94 -0x3ffbab00: 0x3f400294 0x0000001e 0x3f4057e6 0x00000003 -0x3ffbab10: 0x80088da4 0x3ffb5f10 0x00000001 0xd0bc01ef -0x3ffbab20: 0x80088160 0x3ffbab60 0x00000000 0x00000000 -0x3ffbab30: 0x80088160 0x3ffbab60 0x00000000 0x00000003 -0x3ffbab40: 0x00000020 0x80000000 0x00060021 0x00000001 -0x3ffbab50: 0x00000000 0x3ffbab80 0x400d0e50 0x00000000 -0x3ffbab60: 0x00060023 0x3ffb3870 0x3ffb6260 0x00000000 -0x3ffbab70: 0x00000000 0x3ffbaba0 0x00000000 0x00000000 -0x3ffbab80: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbab90: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbaba0: 0x00000000 0x00000000 0x3ffbabac 0x00000000 -0x3ffbabb0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbabc0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbabd0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbabe0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbabf0: 0x00000000 0x00000000 0x00000000 0x00000000 -.coredump.tasks.data 0x3ffba278 0x17c RW -0x3ffba278: 0x3ffb9f60 0x3ffba200 0x000114a1 0x3ffb3848 -0x3ffba288: 0x3ffb3848 0x3ffba278 0x3ffb3840 0x00000014 -0x3ffba298: 0x3ffb4b9c 0x3ffb4b9c 0x3ffba278 0x00000000 -0x3ffba2a8: 0x00000005 0x3ffb8268 0x74696e75 0x73615479 -0x3ffba2b8: 0xcece006b 0x00cecece 0x00000000 0x3ffba264 -0x3ffba2c8: 0x00000000 0x00060021 0x0000000c 0xcececece -0x3ffba2d8: 0x00000005 0x00000000 0x00000000 0x00000000 -0x3ffba2e8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba2f8: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffba308: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffba318: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffba328: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba338: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba348: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba358: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba368: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba378: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba388: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba398: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba3a8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba3b8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba3c8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba3d8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba3e8: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb9f60 0x304 RW -0x3ffb9f60: 0x40082468 0x400092dc 0x00060530 0x8000930f -0x3ffb9f70: 0x3ffba020 0x3ffba09c 0x00000000 0x00000000 -0x3ffb9f80: 0x000114d2 0x00000057 0x00000037 0x00003ff4 -0x3ffb9f90: 0x00000000 0x00000000 0x00000000 0x80088378 -0x3ffb9fa0: 0x3ffb5ec0 0x00000000 0x3ffb8280 0x00000017 -0x3ffb9fb0: 0x0000ffff 0x00000000 0x400014fd 0x4000150d -0x3ffb9fc0: 0xffffffff 0x40082668 0x3ffb5ec0 0x400883a0 -0x3ffb9fd0: 0x3ffb353c 0x00000000 0x00000000 0x00000000 -0x3ffb9fe0: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb9ff0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba000: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffba010: 0x800d60b7 0x3ffba040 0x3ffba09c 0x000000ff -0x3ffba020: 0x3ffb353c 0x00000000 0x00000000 0x00000000 -0x3ffba030: 0x800d5cba 0x3ffba060 0x3ffba09c 0x000000ff -0x3ffba040: 0xc0045f65 0x0000ff00 0x00ff0000 0xff000000 -0x3ffba050: 0x800d6127 0x3ffba090 0x00000001 0x3ffba1a0 -0x3ffba060: 0x800d6127 0x3ffba090 0x00000001 0xd0bc01ef -0x3ffba070: 0x000000fe 0x3ffba19c 0x00000000 0x00000010 -0x3ffba080: 0x80088160 0x3ffba1c0 0x00000000 0x00000000 -0x3ffba090: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0x00000000 -0x3ffba0a0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba0b0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba0c0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba0d0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba0e0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba0f0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba100: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba110: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba120: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba130: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba140: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba150: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba160: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba170: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba180: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba190: 0x00000000 0x00000000 0x00000000 0xd0bc01ef -0x3ffba1a0: 0x3ffba09c 0x80000000 0x00060021 0x3ffb5700 -0x3ffba1b0: 0x00000000 0x3ffba1e0 0x400d611c 0x00000000 -0x3ffba1c0: 0x00060023 0x3ffb3848 0x3ffba278 0x00000000 -0x3ffba1d0: 0x00000000 0x3ffba200 0x00000000 0x00000000 -0x3ffba1e0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba1f0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba200: 0x00000000 0x00000000 0x3ffba20c 0x00000000 -0x3ffba210: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba220: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba230: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba240: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba250: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffba260: 0x00000000 -.coredump.tasks.data 0x3ffb7634 0x17c RW -0x3ffb7634: 0x3ffb7480 0x3ffb75c0 0xcececece 0x3ffb37e4 -0x3ffb7644: 0x3ffb6ea0 0x3ffb7634 0x3ffb37dc 0x00000019 -0x3ffb7654: 0xcececece 0xcececece 0x3ffb7634 0x00000000 -0x3ffb7664: 0x00000000 0x3ffb7024 0x454c4449 0xcece0031 -0x3ffb7674: 0xcececece 0x00cecece 0x00000001 0x3ffb7620 -0x3ffb7684: 0x00000000 0x00060021 0x00000007 0xcececece -0x3ffb7694: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb76a4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb76b4: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb76c4: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb76d4: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb76e4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb76f4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7704: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7714: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7724: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7734: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7744: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7754: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7764: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7774: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7784: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7794: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb77a4: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb7480 0x1a0 RW -0x3ffb7480: 0x40082468 0x400e85b2 0x00060030 0x800d3852 -0x3ffb7490: 0x3ffb7540 0x00000000 0x00000000 0x00000001 -0x3ffb74a0: 0x80000001 0x00000003 0x00060023 0x80089778 -0x3ffb74b0: 0x3ffb7530 0x00000003 0x00060823 0x00060820 -0x3ffb74c0: 0x00000001 0x00060820 0x3ffb84d0 0x00000000 -0x3ffb74d0: 0x0000ffff 0x00000000 0x4000c46c 0x4000c477 -0x3ffb74e0: 0xffffffff 0x40082668 0x00000001 0x400883a0 -0x3ffb74f0: 0x3ffb08fc 0x00000000 0x00000000 0x00000000 -0x3ffb7500: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb7510: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7520: 0x00000000 0x40089d80 0x00000000 0x00000000 -0x3ffb7530: 0x80089d89 0x3ffb7560 0x00000008 0x00000001 -0x3ffb7540: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7550: 0x80088160 0x3ffb7580 0x00000000 0x00000000 -0x3ffb7560: 0x00000001 0x80000000 0x00060021 0x00000000 -0x3ffb7570: 0x00000000 0x3ffb75a0 0x40089d80 0x00000000 -0x3ffb7580: 0x00060023 0x3ffb37e4 0x3ffb6e98 0x00000000 -0x3ffb7590: 0x00000000 0x3ffb75c0 0x00000000 0x00000000 -0x3ffb75a0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb75b0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb75c0: 0x00000000 0x00000000 0x3ffb75cc 0x00000000 -0x3ffb75d0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb75e0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb75f0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7600: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7610: 0x00000000 0x00000000 0x00000000 0x00000000 -.coredump.tasks.data 0x3ffb6e98 0x17c RW -0x3ffb6e98: 0x3ffb6ce0 0x3ffb6e20 0xcececece 0x3ffb763c -0x3ffb6ea8: 0x3ffb37e4 0x3ffb6e98 0x3ffb37dc 0x00000019 -0x3ffb6eb8: 0xcececece 0xcececece 0x3ffb6e98 0x00000000 -0x3ffb6ec8: 0x00000000 0x3ffb6888 0x454c4449 0xcece0030 -0x3ffb6ed8: 0xcececece 0x00cecece 0x00000000 0x3ffb6e84 -0x3ffb6ee8: 0x00000000 0x00060021 0x00000006 0xcececece -0x3ffb6ef8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f08: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f18: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb6f28: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb6f38: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb6f48: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f58: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f68: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f78: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f88: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6f98: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6fa8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6fb8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6fc8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6fd8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6fe8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6ff8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7008: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb6ce0 0x1a4 RW -0x3ffb6ce0: 0x40082468 0x400e85b2 0x00060530 0x800d3852 -0x3ffb6cf0: 0x3ffb6da0 0x00000000 0x00000003 0x00000001 -0x3ffb6d00: 0x80000001 0x00000003 0x00060a23 0x8008911e -0x3ffb6d10: 0x3ffb6d80 0x3ffb66fc 0x40001d48 0x00060420 -0x3ffb6d20: 0x00000001 0x00060420 0x00000000 0x00000000 -0x3ffb6d30: 0x0000ffff 0x00000000 0x4000c46c 0x4000c477 -0x3ffb6d40: 0xffffffff 0x40082668 0x00000001 0x400883a0 -0x3ffb6d50: 0x3ffb015c 0x00000000 0x00000000 0x00000000 -0x3ffb6d60: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb6d70: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6d80: 0x00000000 0x40089d80 0x00000000 0x00000000 -0x3ffb6d90: 0x80089d89 0x3ffb6dc0 0x00000008 0x00000000 -0x3ffb6da0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6db0: 0x80088160 0x3ffb6de0 0x00000000 0x00000000 -0x3ffb6dc0: 0x00000001 0x80000000 0x00060021 0x00060b23 -0x3ffb6dd0: 0x00000000 0x3ffb6e00 0x40089d80 0x00000000 -0x3ffb6de0: 0x00060023 0x3ffb37e4 0x3ffb7634 0x00000000 -0x3ffb6df0: 0x00000000 0x3ffb6e20 0x00000000 0x00000000 -0x3ffb6e00: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e10: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e20: 0x00000000 0x00000000 0x3ffb6e2c 0x00000000 -0x3ffb6e30: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e40: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e50: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e60: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e70: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6e80: 0x00000000 -.coredump.tasks.data 0x3ffb60d4 0x17c RW -0x3ffb60d4: 0x3ffb5f20 0x3ffb6060 0x00011c6c 0x3ffb37d0 -0x3ffb60e4: 0x3ffb6460 0x3ffb60d4 0x3ffb37c8 0x00000014 -0x3ffb60f4: 0xcececece 0xcececece 0x3ffb60d4 0x00000000 -0x3ffb6104: 0x00000005 0x3ffb58c4 0x5f646162 0x5f727470 -0x3ffb6114: 0x6b736174 0x00cece00 0x7fffffff 0x3ffb60c0 -0x3ffb6124: 0x00000000 0x00060021 0x0000000e 0xcececece -0x3ffb6134: 0x00000005 0x00000000 0x00000000 0x00000000 -0x3ffb6144: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6154: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb6164: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb6174: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb6184: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6194: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb61a4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb61b4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb61c4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb61d4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb61e4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb61f4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6204: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6214: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6224: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6234: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6244: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb5f20 0x1a0 RW -0x3ffb5f20: 0x40082468 0x40081414 0x00060330 0x80089b5e -0x3ffb5f30: 0x3ffb5fe0 0x00000000 0x00011c6c 0x80089778 -0x3ffb5f40: 0x3ffb4ef0 0x00000003 0x00060823 0x80081414 -0x3ffb5f50: 0x3ffb5fc0 0x3ff000dc 0x00000001 0x3ffb0038 -0x3ffb5f60: 0x00000001 0x00060320 0x00000000 0x00000000 -0x3ffb5f70: 0x0000ffff 0x00000000 0x400014fd 0x4000150d -0x3ffb5f80: 0xfffffff9 0x40082668 0x00000001 0x400883a0 -0x3ffb5f90: 0x3ffaf39c 0x00000000 0x00000000 0x00000000 -0x3ffb5fa0: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb5fb0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5fc0: 0x3f400230 0x00000018 0x3f4057e6 0x00000001 -0x3ffb5fd0: 0x800d0de3 0x3ffb6000 0x00011c6c 0x3ffb0c94 -0x3ffb5fe0: 0x80089778 0x3ffb4ef0 0x00000003 0x00060823 -0x3ffb5ff0: 0x80088160 0x3ffb6020 0x00000000 0x00000000 -0x3ffb6000: 0x00000020 0x80000000 0x00060021 0x00000000 -0x3ffb6010: 0x00000000 0x3ffb6040 0x400d0dd4 0x00000000 -0x3ffb6020: 0x00060023 0x3ffb3848 0x3ffba278 0x00000000 -0x3ffb6030: 0x00000000 0x3ffb6060 0x00000000 0x00000000 -0x3ffb6040: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6050: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6060: 0x00000000 0x00000000 0x3ffb606c 0x00000000 -0x3ffb6070: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6080: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6090: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb60a0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb60b0: 0x00000000 0x00000000 0x00000000 0x00000000 -.coredump.tasks.data 0x3ffb6458 0x17c RW -0x3ffb6458: 0x3ffbb270 0x3ffbb3b0 0x00011c6c 0x3ffb60dc -0x3ffb6468: 0x3ffb37d0 0x3ffb6458 0x3ffb37c8 0x0000000f -0x3ffb6478: 0xcececece 0xcececece 0x3ffb6458 0x00000000 -0x3ffb6488: 0x0000000a 0x3ffbac14 0x6c696166 0x615f6465 -0x3ffb6498: 0x72657373 0x00745f74 0x00000000 0x3ffbb410 -0x3ffb64a8: 0x00000000 0x00060021 0x00000010 0xcececece -0x3ffb64b8: 0x0000000a 0x00000000 0x00000000 0x00000000 -0x3ffb64c8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb64d8: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb64e8: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb64f8: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb6508: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6518: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6528: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6538: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6548: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6558: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6568: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6578: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6588: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb6598: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb65a8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb65b8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb65c8: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffbb270 0x1a0 RW -0x3ffbb270: 0x40082468 0x40081414 0x00060130 0x80089b5e -0x3ffbb280: 0x3ffbb330 0x00000000 0x00011c6c 0x800d5871 -0x3ffbb290: 0x3ffb9fd0 0x00000800 0x3ffb0004 0x80081414 -0x3ffbb2a0: 0x3ffbb310 0x3ff000dc 0x00000001 0x3ffb0038 -0x3ffbb2b0: 0x00000001 0x00060120 0x00000000 0x00000000 -0x3ffbb2c0: 0x0000ffff 0x00000000 0x400014fd 0x4000150d -0x3ffbb2d0: 0xfffffff8 0x40082668 0x00000001 0x400883a0 -0x3ffbb2e0: 0x3ffb46ec 0x00000000 0x00000000 0x00000000 -0x3ffbb2f0: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffbb300: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb310: 0x3f400144 0x0000001e 0x3f4057e6 0x00000001 -0x3ffbb320: 0x800d0d23 0x3ffbb350 0x00011c6c 0x3ffb0c94 -0x3ffbb330: 0x800d5871 0x3ffb9fd0 0x00000800 0x3ffb0004 -0x3ffbb340: 0x80088160 0x3ffbb370 0x00000000 0x00000000 -0x3ffbb350: 0x00000020 0x80000000 0x00060021 0x00000000 -0x3ffbb360: 0x00000000 0x3ffbb390 0x400d0d14 0x00000000 -0x3ffbb370: 0x00060023 0x3ffb38ac 0x3ffb6458 0x00000000 -0x3ffbb380: 0x00000000 0x3ffbb3b0 0x00000000 0x00000000 -0x3ffbb390: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb3a0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb3b0: 0x00000000 0x00000000 0x3ffbb3bc 0x00000000 -0x3ffbb3c0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb3d0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb3e0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb3f0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffbb400: 0x00000000 0x00000000 0x00000000 0x00000000 -.coredump.tasks.data 0x3ffb80dc 0x17c RW -0x3ffb80dc: 0x3ffb7f00 0x3ffb8060 0x00000000 0x3ffb37bc -0x3ffb80ec: 0x3ffb37bc 0x3ffb80dc 0x3ffb37b4 0x00000018 -0x3ffb80fc: 0x3ffb77ec 0x3ffb77ec 0x3ffb80dc 0x3ffb77e4 -0x3ffb810c: 0x00000001 0x3ffb78cc 0x20726d54 0x00637653 -0x3ffb811c: 0xcececece 0x00cecece 0x00000000 0x3ffb80c8 -0x3ffb812c: 0x00000000 0x00060021 0x00000008 0xcececece -0x3ffb813c: 0x00000001 0x00000000 0x00000000 0x00000000 -0x3ffb814c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb815c: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb816c: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb817c: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb818c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb819c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb81ac: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb81bc: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb81cc: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb81dc: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb81ec: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb81fc: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb820c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb821c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb822c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb823c: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb824c: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb7f00 0x1c8 RW -0x3ffb7f00: 0x40082468 0x40081414 0x00060030 0x8008a901 -0x3ffb7f10: 0x3ffb7fc0 0x00000000 0x00000000 0x3ffb7814 -0x3ffb7f20: 0x00000000 0x00000000 0x3ffb5450 0x80081414 -0x3ffb7f30: 0x3ffb7fa0 0x3ff000dc 0x00000001 0x3ffb0038 -0x3ffb7f40: 0x3ffb5460 0x400d2b50 0x00000000 0x00000000 -0x3ffb7f50: 0x0000ffff 0x00000000 0x00000000 0x00000000 -0x3ffb7f60: 0x00000000 0x40082668 0x3ffb5460 0x400883a0 -0x3ffb7f70: 0x3ffb139c 0x00000000 0x00000000 0x00000000 -0x3ffb7f80: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb7f90: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb7fa0: 0x40082468 0x40088158 0x00050030 0xd0bc01ef -0x3ffb7fb0: 0x8008aa33 0x3ffb7fe0 0x3ffb39dc 0x00000000 -0x3ffb7fc0: 0x00000000 0x4008aa18 0x00000000 0x00000000 -0x3ffb7fd0: 0x80088160 0x3ffb8010 0x00000000 0x00000000 -0x3ffb7fe0: 0x00000000 0x00000000 0x00000000 0xd0bc01ef -0x3ffb7ff0: 0x00000001 0x80000000 0x00060021 0x00060023 -0x3ffb8000: 0x00000000 0x3ffb8040 0x4008aa18 0x00000000 -0x3ffb8010: 0x3ffb139c 0x00000000 0x00000001 0xd0bc01ef -0x3ffb8020: 0x00060023 0x3ffb37f8 0x3ffb66fc 0x00000000 -0x3ffb8030: 0x00000000 0x3ffb8060 0x00000000 0x00000000 -0x3ffb8040: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb8050: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb8060: 0x00000000 0x00000000 0x3ffb806c 0x00000000 -0x3ffb8070: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb8080: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb8090: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb80a0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb80b0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb80c0: 0x00000000 0x00000000 -.coredump.tasks.data 0x3ffafb34 0x17c RW -0x3ffafb34: 0x3ffaf960 0x3ffafac0 0xcececece 0x3ffb5060 -0x3ffafb44: 0x3ffb4980 0x3ffafb34 0x3ffb3758 0x00000003 -0x3ffafb54: 0x3ffaeae4 0x3ffaeae4 0x3ffafb34 0x3ffaeadc -0x3ffafb64: 0x00000016 0x3ffaeb24 0x5f707365 0x656d6974 -0x3ffafb74: 0xcece0072 0x00cecece 0x00000000 0x3ffafb20 -0x3ffafb84: 0x00000000 0x00060021 0x00000001 0xcececece -0x3ffafb94: 0x00000016 0x00000000 0x00000000 0x00000000 -0x3ffafba4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafbb4: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffafbc4: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffafbd4: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffafbe4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafbf4: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc04: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc14: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc24: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc34: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc44: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc54: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc64: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc74: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc84: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafc94: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafca4: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffaf960 0x1c0 RW -0x3ffaf960: 0x40082468 0x40081414 0x00060630 0x80088d34 -0x3ffaf970: 0x3ffafa20 0x00000000 0x00000000 0x3ffb39d0 -0x3ffaf980: 0x00000015 0x00000055 0x3ffb48d0 0x80081414 -0x3ffaf990: 0x3ffafa00 0x3ff000dc 0x00000001 0x3ffb0038 -0x3ffaf9a0: 0x00000001 0x00060620 0x00000000 0x00000000 -0x3ffaf9b0: 0x0000ffff 0x00000000 0x00000000 0x00000000 -0x3ffaf9c0: 0x00000000 0x40082668 0x00000001 0x400883a0 -0x3ffaf9d0: 0x3ffa8dfc 0x00000000 0x00000000 0x00000000 -0x3ffaf9e0: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffaf9f0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafa00: 0x40082468 0x40088158 0x00050030 0x00000000 -0x3ffafa10: 0x800d378b 0x3ffafa40 0x3ffaeab8 0x00000000 -0x3ffafa20: 0x00000000 0x400d3778 0x00000000 0x00000000 -0x3ffafa30: 0x80088160 0x3ffafa80 0x00000000 0x00000000 -0x3ffafa40: 0x00000000 0x00000000 0x00000000 0xffffffff -0x3ffafa50: 0x00000000 0x00000000 0x0000c48c 0xd0bc01ef -0x3ffafa60: 0x3ffaeb0c 0x00000000 0x00000001 0x00060e23 -0x3ffafa70: 0x00000000 0x3ffafaa0 0x400d3778 0x00000000 -0x3ffafa80: 0x00060023 0x3ffb399c 0x3ffafb34 0x00000000 -0x3ffafa90: 0x00000000 0x3ffafac0 0x00000000 0x00000000 -0x3ffafaa0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafab0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafac0: 0x00000000 0x00000000 0x3ffafacc 0x00000000 -0x3ffafad0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafae0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafaf0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafb00: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffafb10: 0x00000000 0x00000000 0x00000000 0x00000000 -.coredump.tasks.data 0x3ffb5058 0x17c RW -0x3ffb5058: 0x3ffb4ea0 0x3ffb4fe0 0xcececece 0x3ffb3760 -0x3ffb5068: 0x3ffafb3c 0x3ffb5058 0x3ffb3758 0x00000001 -0x3ffb5078: 0x3ffb4c08 0x3ffb4c08 0x3ffb5058 0x3ffb4c00 -0x3ffb5088: 0x00000018 0x3ffb4c48 0x31637069 0xcecece00 -0x3ffb5098: 0xcececece 0x00cecece 0x00000001 0x3ffb5044 -0x3ffb50a8: 0x00000000 0x00060021 0x00000003 0xcececece -0x3ffb50b8: 0x00000018 0x00000000 0x00000000 0x00000000 -0x3ffb50c8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb50d8: 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb50e8: 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb50f8: 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb5108: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5118: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5128: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5138: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5148: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5158: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5168: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5178: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5188: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5198: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb51a8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb51b8: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb51c8: 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb4ea0 0x1a4 RW -0x3ffb4ea0: 0x40082468 0x40088d34 0x00060830 0x80081d0f -0x3ffb4eb0: 0x3ffb4f60 0x3ffb4bdc 0x00000000 0x3ffb4c30 -0x3ffb4ec0: 0x00000000 0x00000001 0x00000000 0x80088d34 -0x3ffb4ed0: 0x3ffb4f40 0x00000001 0x00000004 0x3ffb39d4 -0x3ffb4ee0: 0x0000000a 0x00800000 0x3ff4001c 0x00000000 -0x3ffb4ef0: 0x0000ffff 0x00000000 0x00000000 0x00000000 -0x3ffb4f00: 0x00000000 0x40082668 0x0000000a 0x400883a0 -0x3ffb4f10: 0x3ffae31c 0x00000000 0x00000000 0x00000000 -0x3ffb4f20: 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb4f30: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4f40: 0x3ffb39d4 0x0000000a 0x00800000 0x3ff4001c -0x3ffb4f50: 0x80088160 0x3ffb4fa0 0x00000001 0x00000000 -0x3ffb4f60: 0x3ffba280 0x0000000a 0x00800000 0xffffffff -0x3ffb4f70: 0x80088160 0x00000000 0x0001149c 0xd0bc01ef -0x3ffb4f80: 0x3ffb4c30 0x00000000 0x00000001 0x00000000 -0x3ffb4f90: 0x00000000 0x3ffb4fc0 0x40081cdc 0x00000001 -0x3ffb4fa0: 0x00000001 0x3ffb39c4 0x3ffb5058 0x00000000 -0x3ffb4fb0: 0x00000000 0x3ffb4fe0 0x00000000 0x00000000 -0x3ffb4fc0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4fd0: 0x800811ac 0x3ffe7d80 0x00000028 0x00000028 -0x3ffb4fe0: 0x00000000 0x00000000 0x3ffb4fec 0x00000000 -0x3ffb4ff0: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5000: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5010: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5020: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5030: 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb5040: 0x00000000 -.coredump.tasks.data 0x3ffb4978 0x17c RW -0x3ffb4978 : 0x3ffb47a0 0x3ffb4900 0xcececece 0x3ffafb3c -0x3ffb4988 : 0x3ffb3760 0x3ffb4978 0x3ffb3758 0x00000001 -0x3ffb4998 : 0x3ffb4528 0x3ffb4528 0x3ffb4978 0x3ffb4520 -0x3ffb49a8 : 0x00000018 0x3ffb4568 0x30637069 0xcecece00 -0x3ffb49b8 : 0xcececece 0x00cecece 0x00000000 0x3ffb4964 -0x3ffb49c8 : 0x00000000 0x00060021 0x00000002 0xcececece -0x3ffb49d8 : 0x00000018 0x00000000 0x00000000 0x00000000 -0x3ffb49e8 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb49f8 : 0x00000000 0x3ffae908 0x3ffae970 0x3ffae9d8 -0x3ffb4a08 : 0x00000000 0x00000000 0x00000001 0x00000000 -0x3ffb4a18 : 0x00000000 0x00000000 0x40001d48 0x00000000 -0x3ffb4a28 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a38 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a48 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a58 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a68 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a78 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a88 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4a98 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4aa8 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4ab8 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4ac8 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4ad8 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4ae8 : 0x00000000 0x00000000 0xcecece00 -.coredump.tasks.data 0x3ffb47a0 0x1c4 RW -0x3ffb47a0 : 0x40082468 0x40081414 0x00060e30 0x80088d34 -0x3ffb47b0 : 0x3ffb4860 0x00000000 0x00000000 0x3ffb39d0 -0x3ffb47c0 : 0x0000cdcd 0x00000001 0x00000000 0x80081414 -0x3ffb47d0 : 0x3ffb4840 0x3ff000dc 0x00000001 0x3ffb0038 -0x3ffb47e0 : 0x00000001 0x00060020 0x00000001 0x00000000 -0x3ffb47f0 : 0x0000ffff 0x00000000 0x00000000 0x00000000 -0x3ffb4800 : 0x00000000 0x40082668 0x00000001 0x400883a0 -0x3ffb4810 : 0x3ffadc3c 0x00000000 0x00000000 0x00000000 -0x3ffb4820 : 0xb33fffff 0x00000000 0x00000000 0x00000000 -0x3ffb4830 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4840 : 0x40082468 0x40088158 0x00050030 0x00000000 -0x3ffb4850 : 0x80081d0f 0x3ffb4880 0x3ffb44fc 0x00000000 -0x3ffb4860 : 0x00000000 0x40081cdc 0x00000000 0x00000000 -0x3ffb4870 : 0x80088160 0x3ffb48c0 0x00000000 0x00000000 -0x3ffb4880 : 0x00000000 0x00000000 0x00000000 0xffffffff -0x3ffb4890 : 0x00000000 0x00000000 0x00000000 0xd0bc01ef -0x3ffb48a0 : 0x3ffb4550 0x00000000 0x00000001 0x00000002 -0x3ffb48b0 : 0x00000000 0x3ffb48e0 0x40081cdc 0x00000000 -0x3ffb48c0 : 0x00060323 0x3ffb39c4 0x3ffb4978 0x00000001 -0x3ffb48d0 : 0x00000000 0x3ffb4900 0x00000000 0x00000000 -0x3ffb48e0 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb48f0 : 0x80081129 0x3ffe3b50 0x3ffb3740 0xd0bc01ef -0x3ffb4900 : 0x00000000 0x00000000 0x3ffb490c 0x00000000 -0x3ffb4910 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4920 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4930 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4940 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4950 : 0x00000000 0x00000000 0x00000000 0x00000000 -0x3ffb4960 : 0x00000000 - -===================== ESP32 CORE DUMP END ===================== -=============================================================== -Done! diff --git a/components/espcoredump/test/test.elf b/components/espcoredump/test/test.elf deleted file mode 100644 index b753b56a8c98..000000000000 Binary files a/components/espcoredump/test/test.elf and /dev/null differ diff --git a/components/espcoredump/test/test_espcoredump.py b/components/espcoredump/test/test_espcoredump.py index 11f84329ca4b..fa352f1abd36 100755 --- a/components/espcoredump/test/test_espcoredump.py +++ b/components/espcoredump/test/test_espcoredump.py @@ -30,27 +30,32 @@ from corefile.elf import ESPCoreDumpElfFile from corefile.loader import ESPCoreDumpFileLoader, ESPCoreDumpLoaderError +SUPPORTED_TARGET = ['esp32', 'esp32s2', 'esp32c3'] + class TestESPCoreDumpElfFile(unittest.TestCase): def test_read_elf(self): - elf = ESPCoreDumpElfFile('core.elf') - assert elf.load_segments - assert elf.note_segments + for target in SUPPORTED_TARGET: + elf = ESPCoreDumpElfFile(os.path.join(target, 'core.elf')) + assert elf.load_segments + assert elf.note_segments class TestESPCoreDumpFileLoader(unittest.TestCase): def test_load_wrong_encode_core_bin(self): - with self.assertRaises(ESPCoreDumpLoaderError): - ESPCoreDumpFileLoader(path='coredump.b64', is_b64=False) + for target in SUPPORTED_TARGET: + with self.assertRaises(ESPCoreDumpLoaderError): + ESPCoreDumpFileLoader(path=os.path.join(target, 'coredump.b64'), is_b64=False) def test_create_corefile(self): - loader = ESPCoreDumpFileLoader(path='coredump.b64', is_b64=True) - loader.create_corefile() + for target in SUPPORTED_TARGET: + loader = ESPCoreDumpFileLoader(path=os.path.join(target, 'coredump.b64'), is_b64=True) + loader.create_corefile() if __name__ == '__main__': # The purpose of these tests is to increase the code coverage at places which are sensitive to issues related to # Python 2&3 compatibility. - # The espcoredump is not suited for through unit testting. There lot of nested functions, interactive - # communication with the developement board and GDB, ... + # The espcoredump is not suited for through unit testing. There lot of nested functions, interactive + # communication with the development board and GDB, ... unittest.main() diff --git a/components/espcoredump/test/test_espcoredump.sh b/components/espcoredump/test/test_espcoredump.sh index 7c6d083f4c40..8eed51b2cdff 100755 --- a/components/espcoredump/test/test_espcoredump.sh +++ b/components/espcoredump/test/test_espcoredump.sh @@ -1,11 +1,31 @@ #!/usr/bin/env bash -{ coverage debug sys \ - && coverage erase \ - && coverage run -a --source=corefile ../espcoredump.py --gdb-timeout-sec 5 info_corefile -m -t b64 -c coredump.b64 -s core.elf test.elf &> output \ - && diff expected_output output \ - && coverage run -a --source=corefile ../espcoredump.py --gdb-timeout-sec 5 info_corefile -m -t elf -c core.elf test.elf &> output2 \ - && diff expected_output output2 \ - && coverage run -a --source=corefile ./test_espcoredump.py \ - && coverage report ../corefile/elf.py ../corefile/gdb.py ../corefile/loader.py ../corefile/xtensa.py ../espcoredump.py \ -; } || { echo 'The test for espcoredump has failed!'; exit 1; } +function help() { + echo "Usage: bash test_espcoredump.sh [ELF_DIR]" +} + +if [ -z "$1" ]; then + help + exit 1 +else + elf_dir=$1 +fi + +SUPPORTED_TARGETS=("esp32" "esp32s2" "esp32c3") +res=0 +coverage erase +for chip in "${SUPPORTED_TARGETS[@]}"; do + { + echo "run b64 decoding tests on $chip" + coverage run -a --source=corefile ../espcoredump.py --chip="$chip" --gdb-timeout-sec 5 info_corefile -m -t b64 -c "${chip}/coredump.b64" -s "${chip}/core.elf" "${elf_dir}/${chip}.elf" &>"${chip}/output" && + diff "${chip}/expected_output" "${chip}/output" && + coverage run -a --source=corefile ../espcoredump.py --chip="$chip" --gdb-timeout-sec 5 info_corefile -m -t elf -c "${chip}/core.elf" "${elf_dir}/${chip}.elf" &>"${chip}/output2" && + diff "${chip}/expected_output" "${chip}/output2" + } || { + echo 'The test for espcoredump has failed!' + res=1 + } +done +coverage run -a --source=corefile ./test_espcoredump.py +coverage report ../corefile/*.py ../espcoredump.py +exit $res diff --git a/components/espcoredump/test_apps/CMakeLists.txt b/components/espcoredump/test_apps/CMakeLists.txt new file mode 100644 index 000000000000..6c28dfd6d95a --- /dev/null +++ b/components/espcoredump/test_apps/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.5) + +# Here for reproducible builds, we use the CI compile options to make sure they're same. +# Use -ffile-prefix-map to map the local path prefix to ci path prefix + +set(ENV{EXTRA_CFLAGS} "-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable \ + -Werror=unused-but-set-variable -Werror=unused-function -Wstrict-prototypes \ + -ffile-prefix-map=$ENV{IDF_PATH}=/builds/espressif/esp-idf") + +set(ENV{EXTRA_CXXFLAGS} "-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable \ + -Werror=unused-but-set-variable -Werror=unused-function \ + -ffile-prefix-map=$ENV{IDF_PATH}=/builds/espressif/esp-idf") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_core_dump) diff --git a/components/espcoredump/test_apps/README.md b/components/espcoredump/test_apps/README.md new file mode 100644 index 000000000000..fb96bde3266f --- /dev/null +++ b/components/espcoredump/test_apps/README.md @@ -0,0 +1,6 @@ +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | + +# ESP Core Dump Tests + +This test app is used to provide built binaries for the test cases under test folders diff --git a/components/espcoredump/test_apps/build_espcoredump.sh b/components/espcoredump/test_apps/build_espcoredump.sh new file mode 100755 index 000000000000..d39d4780a45b --- /dev/null +++ b/components/espcoredump/test_apps/build_espcoredump.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +function help() { + echo "Usage: bash build_espcoredump.sh [OUTPUT_DIR]" +} + +if [ -z "$1" ]; then + help + exit 1 +else + output_dir=$1 +fi + +SUPPORTED_TARGETS=("esp32" "esp32s2" "esp32c3") +for chip in "${SUPPORTED_TARGETS[@]}"; do + { + echo "--------------------------" + echo "building $chip binaries..." + echo "--------------------------" + idf.py fullclean && rm -f sdkconfig + idf.py set-target $chip + idf.py build + cp ./build/test_core_dump.elf "${output_dir}/${chip}.elf" + } +done diff --git a/components/espcoredump/test_apps/main/CMakeLists.txt b/components/espcoredump/test_apps/main/CMakeLists.txt new file mode 100644 index 000000000000..855e56217286 --- /dev/null +++ b/components/espcoredump/test_apps/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRC_DIRS "." + PRIV_REQUIRES unity nvs_flash) diff --git a/components/espcoredump/test/test_core_dump.c b/components/espcoredump/test_apps/main/test_core_dump.c similarity index 95% rename from components/espcoredump/test/test_core_dump.c rename to components/espcoredump/test_apps/main/test_core_dump.c index ad6758b6726d..8c7d4ac00559 100644 --- a/components/espcoredump/test/test_core_dump.c +++ b/components/espcoredump/test_apps/main/test_core_dump.c @@ -96,10 +96,17 @@ void failed_assert_task(void *pvParameter) fflush(stdout); } -TEST_CASE("verify coredump functionality", "[coredump][ignore]") +void test_core_dump(void) { nvs_flash_init(); xTaskCreate(&bad_ptr_task, "bad_ptr_task", 2048, NULL, 5, NULL); xTaskCreatePinnedToCore(&unaligned_ptr_task, "unaligned_ptr_task", 2048, NULL, 7, NULL, 1); xTaskCreatePinnedToCore(&failed_assert_task, "failed_assert_task", 2048, NULL, 10, NULL, 0); } + +void app_main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_core_dump); + UNITY_END(); +} diff --git a/components/espcoredump/test_apps/sdkconfig.defaults b/components/espcoredump/test_apps/sdkconfig.defaults new file mode 100644 index 000000000000..4d49fabd1ecd --- /dev/null +++ b/components/espcoredump/test_apps/sdkconfig.defaults @@ -0,0 +1,14 @@ +CONFIG_ESP_COREDUMP_ENABLE_TO_UART=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=y +CONFIG_ESP_COREDUMP_ENABLE=y +CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64 +CONFIG_ESP_COREDUMP_UART_DELAY=0 +CONFIG_ESP_COREDUMP_DECODE_DISABLE=y +CONFIG_ESP_COREDUMP_DECODE="disable" + +# Settings for reproducible builds +CONFIG_APP_COMPILE_TIME_DATE=n +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=1 +CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 258301731780..e53efcf84ceb 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 258301731780493365bb249553ae7855a3e753ea +Subproject commit e53efcf84ceb6fac315ccb1348d6950ac33af309 diff --git a/components/expat/expat b/components/expat/expat index a28238bdeebc..57c7da69b78e 160000 --- a/components/expat/expat +++ b/components/expat/expat @@ -1 +1 @@ -Subproject commit a28238bdeebc087071777001245df1876a11f5ee +Subproject commit 57c7da69b78e3698e112a6b5da19d5109b8232d1 diff --git a/components/expat/port/include/expat_config.h b/components/expat/port/include/expat_config.h index b6b927a19bb1..468910220f45 100644 --- a/components/expat/port/include/expat_config.h +++ b/components/expat/port/include/expat_config.h @@ -63,7 +63,7 @@ #define PACKAGE_NAME "expat" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "expat 2.2.5" +#define PACKAGE_STRING "expat 2.4.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "expat" @@ -72,13 +72,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2.2.5" +#define PACKAGE_VERSION "2.4.3" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "2.2.5" +#define VERSION "2.4.3" /* whether byteorder is bigendian */ /* #undef WORDS_BIGENDIAN */ diff --git a/components/fatfs/src/ff.c b/components/fatfs/src/ff.c index 7d2f601d143b..2730b2c5ba40 100644 --- a/components/fatfs/src/ff.c +++ b/components/fatfs/src/ff.c @@ -6240,7 +6240,7 @@ static void putc_bfd ( /* Buffered write with code conversion */ WCHAR hs, wc; #if FF_LFN_UNICODE == 2 DWORD dc; - TCHAR *tp; + const TCHAR *tp; #endif #endif @@ -6282,7 +6282,7 @@ static void putc_bfd ( /* Buffered write with code conversion */ return; } } - tp = (TCHAR*)pb->bs; + tp = (const TCHAR*)pb->bs; dc = tchar2uni(&tp); /* UTF-8 ==> UTF-16 */ if (dc == 0xFFFFFFFF) return; wc = (WCHAR)dc; @@ -6444,7 +6444,7 @@ int f_printf ( for (;;) { c = *fmt++; - if (c == 0) break; /* End of string */ + if (c == 0) break; /* End of string */ if (c != '%') { /* Non escape character */ putc_bfd(&pb, c); continue; diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 1ce28a1670e5..b6dea429eece 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -375,6 +375,10 @@ static ssize_t vfs_fat_write(void* ctx, int fd, const void * data, size_t size) } unsigned written = 0; res = f_write(file, data, size, &written); + if (((written == 0) && (size != 0)) && (res == 0)) { + errno = ENOSPC; + return -1; + } if (res != FR_OK) { ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); errno = fresult_to_errno(res); @@ -459,6 +463,10 @@ static ssize_t vfs_fat_pwrite(void *ctx, int fd, const void *src, size_t size, o unsigned wr = 0; f_res = f_write(file, src, size, &wr); + if (((wr == 0) && (size != 0)) && (f_res == 0)) { + errno = ENOSPC; + return -1; + } if (f_res == FR_OK) { ret = wr; } else { diff --git a/components/freemodbus/common/esp_modbus_master.c b/components/freemodbus/common/esp_modbus_master.c index 2684d0e5b121..bd63c4c348c8 100644 --- a/components/freemodbus/common/esp_modbus_master.c +++ b/components/freemodbus/common/esp_modbus_master.c @@ -18,6 +18,8 @@ #include "esp_modbus_master.h" // for public interface defines #include "esp_modbus_callbacks.h" // for callback functions +static const char TAG[] __attribute__((unused)) = "MB_CONTROLLER_MASTER"; + // This file implements public API for Modbus master controller. // These functions are wrappers for interface functions of the controller static mb_master_interface_t* master_interface_ptr = NULL; diff --git a/components/freemodbus/common/esp_modbus_slave.c b/components/freemodbus/common/esp_modbus_slave.c index f69599c04a7c..601a5fa1fec5 100644 --- a/components/freemodbus/common/esp_modbus_slave.c +++ b/components/freemodbus/common/esp_modbus_slave.c @@ -43,6 +43,7 @@ static uint8_t mb_slave_id[] = { MB_ID_BYTE0(MB_CONTROLLER_SLAVE_ID), // Common interface pointer for slave port static mb_slave_interface_t* slave_interface_ptr = NULL; +static const char TAG[] __attribute__((unused)) = "MB_CONTROLLER_SLAVE"; // Searches the register in the area specified by type, returns descriptor if found, else NULL static mb_descr_entry_t* mbc_slave_find_reg_descriptor(mb_param_type_t type, uint16_t addr, size_t regs) @@ -259,11 +260,11 @@ static esp_err_t mbc_slave_send_param_info(mb_event_group_t par_type, uint16_t m par_info.mb_offset = mb_offset; BaseType_t status = xQueueSend(mbs_opts->mbs_notification_queue_handle, &par_info, MB_PAR_INFO_TOUT); if (pdTRUE == status) { - ESP_LOGD(MB_SLAVE_TAG, "Queue send parameter info (type, address, size): %d, 0x%.4x, %d", + ESP_LOGD(TAG, "Queue send parameter info (type, address, size): %d, 0x%.4x, %d", par_type, (uint32_t)par_address, par_size); error = ESP_OK; } else if (errQUEUE_FULL == status) { - ESP_LOGD(MB_SLAVE_TAG, "Parameter queue is overflowed."); + ESP_LOGD(TAG, "Parameter queue is overflowed."); } return error; } @@ -276,7 +277,7 @@ static esp_err_t mbc_slave_send_param_access_notification(mb_event_group_t event esp_err_t err = ESP_FAIL; mb_event_group_t bits = (mb_event_group_t)xEventGroupSetBits(mbs_opts->mbs_event_group, (EventBits_t)event); if (bits & event) { - ESP_LOGD(MB_SLAVE_TAG, "The MB_REG_CHANGE_EVENT = 0x%.2x is set.", (uint8_t)event); + ESP_LOGD(TAG, "The MB_REG_CHANGE_EVENT = 0x%.2x is set.", (uint8_t)event); err = ESP_OK; } return err; diff --git a/components/freemodbus/common/include/esp_modbus_common.h b/components/freemodbus/common/include/esp_modbus_common.h index 398af0ba9db2..9c65f08b90d6 100644 --- a/components/freemodbus/common/include/esp_modbus_common.h +++ b/components/freemodbus/common/include/esp_modbus_common.h @@ -22,6 +22,24 @@ extern "C" { #endif +#if __has_include("esp_check.h") +#include "esp_check.h" + +#define MB_RETURN_ON_FALSE(a, err_code, tag, format, ...) ESP_RETURN_ON_FALSE(a, err_code, tag, format __VA_OPT__(,) __VA_ARGS__) + +#else + +// if cannot include esp_check then use custom check macro + +#define MB_RETURN_ON_FALSE(a, err_code, tag, format, ...) do { \ + if (!(a)) { \ + ESP_LOGE(tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ + return err_code; \ + } \ +} while(0) + +#endif + #define MB_CONTROLLER_STACK_SIZE (CONFIG_FMB_CONTROLLER_STACK_SIZE) // Stack size for Modbus controller #define MB_CONTROLLER_PRIORITY (CONFIG_FMB_PORT_TASK_PRIO - 1) // priority of MB controller task diff --git a/components/freemodbus/common/include/esp_modbus_master.h b/components/freemodbus/common/include/esp_modbus_master.h index 5d7539b08d93..8084e6890270 100644 --- a/components/freemodbus/common/include/esp_modbus_master.h +++ b/components/freemodbus/common/include/esp_modbus_master.h @@ -25,6 +25,12 @@ extern "C" { #endif +#define MB_MASTER_CHECK(a, err_code, format, ...) MB_RETURN_ON_FALSE(a, err_code, TAG, format __VA_OPT__(,) __VA_ARGS__) + +#define MB_MASTER_ASSERT(con) do { \ + if (!(con)) { ESP_LOGE(TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \ + } while (0) + /*! * \brief Modbus descriptor table parameter type defines. */ diff --git a/components/freemodbus/common/include/esp_modbus_slave.h b/components/freemodbus/common/include/esp_modbus_slave.h index fa6a53bc44e2..040d18265bfc 100644 --- a/components/freemodbus/common/include/esp_modbus_slave.h +++ b/components/freemodbus/common/include/esp_modbus_slave.h @@ -28,6 +28,12 @@ extern "C" { #endif +#define MB_SLAVE_CHECK(a, err_code, format, ...) MB_RETURN_ON_FALSE(a, err_code, TAG, format __VA_OPT__(,) __VA_ARGS__) + +#define MB_SLAVE_ASSERT(con) do { \ + if (!(con)) { ESP_LOGE(TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \ + } while (0) + /** * @brief Parameter access event information type */ diff --git a/components/freemodbus/common/mbc_master.h b/components/freemodbus/common/mbc_master.h index 67e5f556c93c..086270385ff5 100644 --- a/components/freemodbus/common/mbc_master.h +++ b/components/freemodbus/common/mbc_master.h @@ -12,9 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _MB_CONTROLLER_MASTER_H #define _MB_CONTROLLER_MASTER_H +#include // for list #include "freertos/FreeRTOS.h" // for task creation and queue access #include "freertos/task.h" // for task api access #include "freertos/event_groups.h" // for event groups @@ -28,18 +30,6 @@ /* ----------------------- Defines ------------------------------------------*/ -#define MB_MASTER_TAG "MB_CONTROLLER_MASTER" - -#define MB_MASTER_CHECK(a, ret_val, str, ...) \ - if (!(a)) { \ - ESP_LOGE(MB_MASTER_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return (ret_val); \ - } - -#define MB_MASTER_ASSERT(con) do { \ - if (!(con)) { ESP_LOGE(MB_MASTER_TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \ - } while (0) - /** * @brief Request mode for parameter to use in data dictionary */ @@ -59,6 +49,19 @@ typedef struct { uart_parity_t parity; /*!< Modbus UART parity settings */ } mb_master_comm_info_t; +#if MB_MASTER_TCP_ENABLED +/** + * @brief Modbus slave addr list item for the master + */ +typedef struct mb_slave_addr_entry_s{ + uint16_t index; /*!< Index of the slave address */ + const char* ip_address; /*!< IP address string of the slave */ + uint8_t slave_addr; /*!< Short slave address */ + void* p_data; /*!< pointer to data structure */ + LIST_ENTRY(mb_slave_addr_entry_s) entries; /*!< The slave address entry */ +} mb_slave_addr_entry_t; +#endif + /** * @brief Modbus controller handler structure */ @@ -71,6 +74,10 @@ typedef struct { EventGroupHandle_t mbm_event_group; /*!< Modbus controller event group */ const mb_parameter_descriptor_t* mbm_param_descriptor_table; /*!< Modbus controller parameter description table */ size_t mbm_param_descriptor_size; /*!< Modbus controller parameter description table size*/ +#if MB_MASTER_TCP_ENABLED + LIST_HEAD(mbm_slave_addr_info_, mb_slave_addr_entry_s) mbm_slave_list; /*!< Slave address information list */ + uint16_t mbm_slave_list_count; +#endif } mb_master_options_t; typedef esp_err_t (*iface_get_cid_info)(uint16_t, const mb_parameter_descriptor_t**); /*!< Interface get_cid_info method */ diff --git a/components/freemodbus/common/mbc_slave.h b/components/freemodbus/common/mbc_slave.h index a116314f9a13..c0e16b544cbf 100644 --- a/components/freemodbus/common/mbc_slave.h +++ b/components/freemodbus/common/mbc_slave.h @@ -31,18 +31,6 @@ #define MB_CONTROLLER_NOTIFY_QUEUE_SIZE (CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE) // Number of messages in parameter notification queue #define MB_CONTROLLER_NOTIFY_TIMEOUT (pdMS_TO_TICKS(CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT)) // notification timeout -#define MB_SLAVE_TAG "MB_CONTROLLER_SLAVE" - -#define MB_SLAVE_CHECK(a, ret_val, str, ...) \ - if (!(a)) { \ - ESP_LOGE(MB_SLAVE_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return (ret_val); \ - } - -#define MB_SLAVE_ASSERT(con) do { \ - if (!(con)) { ESP_LOGE(MB_SLAVE_TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \ - } while (0) - /** * @brief Device communication parameters for master */ diff --git a/components/freemodbus/modbus/functions/mbfuncdisc.c b/components/freemodbus/modbus/functions/mbfuncdisc.c index 79ff68f280b4..cbfbe3384ea8 100644 --- a/components/freemodbus/modbus/functions/mbfuncdisc.c +++ b/components/freemodbus/modbus/functions/mbfuncdisc.c @@ -1,21 +1,31 @@ - /* - * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS - * Copyright (C) 2006 Christian Walter - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ +/* + * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS + * Copyright (C) 2006 Christian Walter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: mbfuncdisc.c,v 1.10 2007/09/12 10:15:56 wolti Exp $ + */ /* ----------------------- System includes ----------------------------------*/ #include "stdlib.h" diff --git a/components/freemodbus/modbus/include/mbport.h b/components/freemodbus/modbus/include/mbport.h index a73b949fba57..412d171051d9 100644 --- a/components/freemodbus/modbus/include/mbport.h +++ b/components/freemodbus/modbus/include/mbport.h @@ -222,6 +222,8 @@ BOOL xMBTCPPortInit( USHORT usTCPPort ); void vMBTCPPortClose( void ); +void vMBTCPPortEnable( void ); + void vMBTCPPortDisable( void ); BOOL xMBTCPPortGetRequest( UCHAR **ppucMBTCPFrame, USHORT * usTCPLength ); @@ -235,6 +237,8 @@ BOOL xMBMasterTCPPortInit( USHORT usTCPPort ); void vMBMasterTCPPortClose( void ); +void vMBMasterTCPPortEnable( void ); + void vMBMasterTCPPortDisable( void ); BOOL xMBMasterTCPPortGetRequest( UCHAR **ppucMBTCPFrame, USHORT * usTCPLength ); diff --git a/components/freemodbus/modbus/tcp/mbtcp.c b/components/freemodbus/modbus/tcp/mbtcp.c index 25277528cb93..624d90934444 100644 --- a/components/freemodbus/modbus/tcp/mbtcp.c +++ b/components/freemodbus/modbus/tcp/mbtcp.c @@ -86,12 +86,15 @@ eMBTCPDoInit( USHORT ucTCPPort ) void eMBTCPStart( void ) { + ESP_LOGD(MB_PORT_TAG, "TCP Slave port enable."); + vMBTCPPortEnable( ); } void eMBTCPStop( void ) { /* Make sure that no more clients are connected. */ + ESP_LOGD(MB_PORT_TAG, "TCP Slave port disable."); vMBTCPPortDisable( ); } diff --git a/components/freemodbus/modbus/tcp/mbtcp_m.c b/components/freemodbus/modbus/tcp/mbtcp_m.c index 05eca0d4074f..7e1f8950cba6 100644 --- a/components/freemodbus/modbus/tcp/mbtcp_m.c +++ b/components/freemodbus/modbus/tcp/mbtcp_m.c @@ -86,11 +86,15 @@ eMBMasterTCPDoInit( USHORT ucTCPPort ) void eMBMasterTCPStart( void ) { + ESP_LOGD(MB_PORT_TAG, "TCP Master port enable."); + vMBMasterTCPPortEnable( ); } void eMBMasterTCPStop( void ) { + ESP_LOGD(MB_PORT_TAG, "TCP Master port disable."); + vMBMasterTCPPortDisable( ); } eMBErrorCode diff --git a/components/freemodbus/port/port.c b/components/freemodbus/port/port.c index dd9063f27fa0..bd24b9414959 100644 --- a/components/freemodbus/port/port.c +++ b/components/freemodbus/port/port.c @@ -13,25 +13,33 @@ * limitations under the License. */ /* - * FreeModbus Libary: RT-Thread Port - * Copyright (C) 2013 Armink - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: port.c,v 1.60 2015/02/01 9:18:05 Armink $ - */ + * FreeModbus Libary: ESP32 Port + * Copyright (C) 2013 Armink + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: port.c,v 1.60 2015/02/01 9:18:05 Armink $ + */ /* ----------------------- System includes --------------------------------*/ diff --git a/components/freemodbus/port/port.h b/components/freemodbus/port/port.h index c74122abef09..2115db20828b 100644 --- a/components/freemodbus/port/port.h +++ b/components/freemodbus/port/port.h @@ -12,6 +12,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* + * FreeModbus Libary: ESP32 Port + * Copyright (C) 2010 Christian Walter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: port.h,v 1.1 2010/06/06 13:07:20 wolti Exp $ + */ #ifndef PORT_COMMON_H_ #define PORT_COMMON_H_ diff --git a/components/freemodbus/port/portevent_m.c b/components/freemodbus/port/portevent_m.c index 21975bc27791..0e4a59f6e0b8 100644 --- a/components/freemodbus/port/portevent_m.c +++ b/components/freemodbus/port/portevent_m.c @@ -13,22 +13,30 @@ * limitations under the License. */ /* - * FreeModbus Libary: ESP32 Port Demo Application + * FreeModbus Libary: ESP32 Port * Copyright (C) 2013 Armink * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. * * File: $Id: portevent.c v 1.60 2013/08/13 15:07:05 Armink add Master Functions$ */ diff --git a/components/freemodbus/port/portserial.c b/components/freemodbus/port/portserial.c index f86099533d6c..ccbb4bd28480 100644 --- a/components/freemodbus/port/portserial.c +++ b/components/freemodbus/port/portserial.c @@ -13,10 +13,9 @@ * limitations under the License. */ /* - * FreeModbus Libary: ESP32 Port Demo Application + * FreeModbus Libary: ESP32 Port * Copyright (C) 2010 Christian Walter * - * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: diff --git a/components/freemodbus/port/portserial_m.c b/components/freemodbus/port/portserial_m.c index 2179f99beac0..80c2306c336f 100644 --- a/components/freemodbus/port/portserial_m.c +++ b/components/freemodbus/port/portserial_m.c @@ -13,22 +13,30 @@ * limitations under the License. */ /* - * FreeModbus Libary: ESP32 Port Demo Application + * FreeModbus Libary: ESP32 Port * Copyright (C) 2013 Armink * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. * * File: $Id: portserial.c,v 1.60 2013/08/13 15:07:05 Armink add Master Functions $ */ diff --git a/components/freemodbus/port/porttimer_m.c b/components/freemodbus/port/porttimer_m.c index e473195ef35d..fe68af96a1c2 100644 --- a/components/freemodbus/port/porttimer_m.c +++ b/components/freemodbus/port/porttimer_m.c @@ -13,22 +13,30 @@ * limitations under the License. */ /* - * FreeModbus Libary: ESP32 Port Demo Application + * FreeModbus Libary: ESP32 Port * Copyright (C) 2013 Armink * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. * * File: $Id: porttimer_m.c,v 1.60 2013/08/13 15:07:05 Armink add Master Functions$ */ diff --git a/components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c b/components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c index c7c4e471d1b2..be97aefad569 100644 --- a/components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c +++ b/components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c @@ -40,6 +40,7 @@ extern BOOL xMBMasterPortSerialTxPoll(void); static mb_master_interface_t* mbm_interface_ptr = NULL; //&default_interface_inst; +static const char *TAG = "MB_CONTROLLER_MASTER"; // Modbus event processing task static void modbus_master_task(void *pvParameters) @@ -238,7 +239,7 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi (USHORT)mb_size, (LONG) MB_RESPONSE_TICS ); break; default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect function in request (%u) ", + ESP_LOGE(TAG, "%s: Incorrect function in request (%u) ", __FUNCTION__, mb_command); mb_error = MB_MRE_NO_REG; break; @@ -269,7 +270,7 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi break; default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect return code (%x) ", + ESP_LOGE(TAG, "%s: Incorrect return code (%x) ", __FUNCTION__, mb_error); error = ESP_FAIL; break; @@ -324,12 +325,12 @@ static uint8_t mbc_serial_master_get_command(mb_param_type_t param_type, mb_para if (mode != MB_PARAM_WRITE) { command = MB_FUNC_READ_DISCRETE_INPUTS; } else { - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect mode (%u)", + ESP_LOGE(TAG, "%s: Incorrect mode (%u)", __FUNCTION__, (uint8_t)mode); } break; default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u)", + ESP_LOGE(TAG, "%s: Incorrect param type (%u)", __FUNCTION__, param_type); break; } @@ -401,16 +402,16 @@ static esp_err_t mbc_serial_master_get_parameter(uint16_t cid, char* name, // Send request to read characteristic data error = mbc_serial_master_send_request(&request, value_ptr); if (error == ESP_OK) { - ESP_LOGD(MB_MASTER_TAG, "%s: Good response for get cid(%u) = %s", + ESP_LOGD(TAG, "%s: Good response for get cid(%u) = %s", __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error)); } else { - ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to get cid(%u) = %s", + ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s", __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error)); } // Set the type of parameter found in the table *type = reg_info.param_type; } else { - ESP_LOGE(MB_MASTER_TAG, "%s: The cid(%u) not found in the data dictionary.", + ESP_LOGE(TAG, "%s: The cid(%u) not found in the data dictionary.", __FUNCTION__, reg_info.cid); error = ESP_ERR_INVALID_ARG; } @@ -436,16 +437,16 @@ static esp_err_t mbc_serial_master_set_parameter(uint16_t cid, char* name, // Send request to write characteristic data error = mbc_serial_master_send_request(&request, value_ptr); if (error == ESP_OK) { - ESP_LOGD(MB_MASTER_TAG, "%s: Good response for set cid(%u) = %s", + ESP_LOGD(TAG, "%s: Good response for set cid(%u) = %s", __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error)); } else { - ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to set cid(%u) = %s", + ESP_LOGD(TAG, "%s: Bad response to set cid(%u) = %s", __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error)); } // Set the type of parameter found in the table *type = reg_info.param_type; } else { - ESP_LOGE(MB_MASTER_TAG, "%s: The requested cid(%u) not found in the data dictionary.", + ESP_LOGE(TAG, "%s: The requested cid(%u) not found in the data dictionary.", __FUNCTION__, reg_info.cid); error = ESP_ERR_INVALID_ARG; } diff --git a/components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.c b/components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.c index b45e83980cd5..d389c68dd501 100644 --- a/components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.c +++ b/components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.c @@ -29,6 +29,7 @@ // Shared pointer to interface structure static mb_slave_interface_t* mbs_interface_ptr = NULL; +static const char *TAG = "MB_CONTROLLER_SLAVE"; // Modbus task function static void modbus_slave_task(void *pvParameters) diff --git a/components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c b/components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c index a1e0d6875809..17e47f0c8c27 100644 --- a/components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c +++ b/components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c @@ -19,6 +19,7 @@ #include // for calculation of time stamp in milliseconds #include "esp_log.h" // for log_write #include // for memcpy +#include // for list #include "freertos/FreeRTOS.h" // for task creation and queue access #include "freertos/task.h" // for task api access #include "freertos/event_groups.h" // for event groups @@ -42,6 +43,59 @@ #define MB_TCP_CONNECTION_TOUT pdMS_TO_TICKS(CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000) static mb_master_interface_t* mbm_interface_ptr = NULL; +static const char *TAG = "MB_CONTROLLER_MASTER"; + +// Searches the slave address in the address info list and returns address info if found, else NULL +static mb_slave_addr_entry_t* mbc_tcp_master_find_slave_addr(uint8_t slave_addr) +{ + mb_slave_addr_entry_t* it; + mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; + + if (LIST_EMPTY(&mbm_opts->mbm_slave_list)) { + return NULL; + } + LIST_FOREACH(it, &mbm_opts->mbm_slave_list, entries) { + if (slave_addr == it->slave_addr) { + return it; + } + } + return NULL; +} + +static esp_err_t mbc_tcp_master_add_slave(uint16_t index, uint8_t slave_addr, const char* ip_addr) +{ + MB_MASTER_ASSERT(mbm_interface_ptr != NULL); + // Initialize interface properties + mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; + + mb_slave_addr_entry_t* new_slave_entry = (mb_slave_addr_entry_t*) heap_caps_malloc(sizeof(mb_slave_addr_entry_t), + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + MB_MASTER_CHECK((new_slave_entry != NULL), ESP_ERR_NO_MEM, "mb can not allocate memory for slave entry."); + new_slave_entry->index = index; + new_slave_entry->ip_address = ip_addr; + new_slave_entry->slave_addr = slave_addr; + new_slave_entry->p_data = NULL; + LIST_INSERT_HEAD(&mbm_opts->mbm_slave_list, new_slave_entry, entries); + MB_MASTER_CHECK((mbm_opts->mbm_slave_list_count < (MB_TCP_PORT_MAX_CONN - 1)), + ESP_ERR_INVALID_STATE, "mb max number of slaves < %d.", MB_TCP_PORT_MAX_CONN); + mbm_opts->mbm_slave_list_count++; + return ESP_OK; +} + +static void mbc_tcp_master_free_slave_list(void) +{ + mb_slave_addr_entry_t* it; + MB_MASTER_ASSERT(mbm_interface_ptr != NULL); + + // Initialize interface properties + mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; + + LIST_FOREACH(it, &mbm_opts->mbm_slave_list, entries) { + LIST_REMOVE(it, entries); + mbm_opts->mbm_slave_list_count--; + free(it); + } +} // Modbus event processing task static void modbus_tcp_master_task(void *pvParameters) @@ -111,31 +165,29 @@ static esp_err_t mbc_tcp_master_start(void) eMBPortProto proto = (comm_info->ip_mode == MB_MODE_TCP) ? MB_PROTO_TCP : MB_PROTO_UDP; eMBPortIpVer ip_ver = (comm_info->ip_addr_type == MB_IPV4) ? MB_PORT_IPV4 : MB_PORT_IPV6; vMBTCPPortMasterSetNetOpt(comm_info->ip_netif_ptr, ip_ver, proto); - vMBTCPPortMasterTaskStart(); - // Add slave IP address for each slave to initialise connection - for (int idx = 0; *comm_ip_table != NULL; idx++, comm_ip_table++) - { - result = (BOOL)xMBTCPPortMasterAddSlaveIp(*comm_ip_table); + status = eMBMasterEnable(); + MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE, + "mb stack set slave ID failure, eMBMasterEnable() returned (0x%x).", (uint32_t)status); + + // Add slave IP address for each slave to initialize connection + mb_slave_addr_entry_t *p_slave_info; + + LIST_FOREACH(p_slave_info, &mbm_opts->mbm_slave_list, entries) { + result = (BOOL)xMBTCPPortMasterAddSlaveIp(p_slave_info->index, p_slave_info->ip_address, p_slave_info->slave_addr); MB_MASTER_CHECK(result, ESP_ERR_INVALID_STATE, "mb stack add slave IP failed: %s.", *comm_ip_table); } - // Init polling event handlers and wait before start polling - xMBTCPPortMasterWaitEvent(mbm_opts->mbm_event_group, (EventBits_t)MB_EVENT_STACK_STARTED, 1); - status = eMBMasterEnable(); - MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE, - "mb stack set slave ID failure, eMBMasterEnable() returned (0x%x).", (uint32_t)status); + // Add end of list condition + (void)xMBTCPPortMasterAddSlaveIp(0xFF, NULL, 0xFF); - // Send end of list condition to start connection phase - (void)xMBTCPPortMasterAddSlaveIp(NULL); // Wait for connection done event bool start = (bool)xMBTCPPortMasterWaitEvent(mbm_opts->mbm_event_group, - (EventBits_t)MB_EVENT_STACK_STARTED, MB_TCP_CONNECTION_TOUT); + (EventBits_t)MB_EVENT_STACK_STARTED, MB_TCP_CONNECTION_TOUT); MB_MASTER_CHECK((start), ESP_ERR_INVALID_STATE, - "mb stack could not connect to slaves for %d seconds.", - CONFIG_FMB_TCP_CONNECTION_TOUT_SEC); - + "mb stack could not connect to slaves for %d seconds.", + CONFIG_FMB_TCP_CONNECTION_TOUT_SEC); return ESP_OK; } @@ -152,14 +204,15 @@ static esp_err_t mbc_tcp_master_destroy(void) MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, "mb stack disable failure."); mb_error = eMBMasterClose(); MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, - "mb stack close failure returned (0x%x).", (uint32_t)mb_error); + "mb stack close failure returned (0x%x).", (uint32_t)mb_error); // Stop polling by clearing correspondent bit in the event group xEventGroupClearBits(mbm_opts->mbm_event_group, - (EventBits_t)MB_EVENT_STACK_STARTED); + (EventBits_t)MB_EVENT_STACK_STARTED); (void)vTaskDelete(mbm_opts->mbm_task_handle); mbm_opts->mbm_task_handle = NULL; (void)vEventGroupDelete(mbm_opts->mbm_event_group); mbm_opts->mbm_event_group = NULL; + mbc_tcp_master_free_slave_list(); free(mbm_interface_ptr); // free the memory allocated for options vMBPortSetMode((UCHAR)MB_PORT_INACTIVE); mbm_interface_ptr = NULL; @@ -179,14 +232,25 @@ static esp_err_t mbc_tcp_master_set_descriptor(const mb_parameter_descriptor_t* MB_MASTER_CHECK((comm_ip_table != NULL), ESP_ERR_INVALID_ARG, "mb ip table address is incorrect."); const mb_parameter_descriptor_t *reg_ptr = descriptor; + uint16_t slave_cnt = 0; + mb_slave_addr_entry_t* p_slave = NULL; + // Go through all items in the table to check all Modbus registers - for (uint16_t counter = 0; counter < (num_elements); counter++, reg_ptr++) + for (int idx = 0; idx < (num_elements); idx++, reg_ptr++) { - MB_MASTER_CHECK((comm_ip_table[reg_ptr->mb_slave_addr - 1] != NULL), ESP_ERR_INVALID_ARG, "mb ip table address is incorrect."); // Below is the code to check consistency of the table format and required fields. - MB_MASTER_CHECK((reg_ptr->cid == counter), ESP_ERR_INVALID_ARG, "mb descriptor cid field is incorrect."); + MB_MASTER_CHECK((reg_ptr->cid == idx), ESP_ERR_INVALID_ARG, "mb descriptor cid field is incorrect."); MB_MASTER_CHECK((reg_ptr->param_key != NULL), ESP_ERR_INVALID_ARG, "mb descriptor param key is incorrect."); MB_MASTER_CHECK((reg_ptr->mb_size > 0), ESP_ERR_INVALID_ARG, "mb descriptor param size is incorrect."); + // Is the slave already in the list? + p_slave = mbc_tcp_master_find_slave_addr(reg_ptr->mb_slave_addr); + // Add it to slave list if not there. + if (!p_slave) { + // Is the IP address correctly defined for the slave? + MB_MASTER_CHECK((comm_ip_table[slave_cnt]), ESP_ERR_INVALID_STATE, "mb missing IP address for cid #%d.", reg_ptr->cid); + // Add slave to the list + MB_MASTER_ASSERT(mbc_tcp_master_add_slave(idx, reg_ptr->mb_slave_addr, comm_ip_table[slave_cnt++]) == ESP_OK); + } } mbm_opts->mbm_param_descriptor_table = descriptor; mbm_opts->mbm_param_descriptor_size = num_elements; @@ -216,52 +280,52 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void* // Calls appropriate request function to send request and waits response switch(mb_command) { - case MB_FUNC_READ_COILS: - mb_error = eMBMasterReqReadCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset, - (USHORT)mb_size , (LONG)MB_RESPONSE_TIMEOUT ); - break; - case MB_FUNC_WRITE_SINGLE_COIL: - mb_error = eMBMasterReqWriteCoil((UCHAR)mb_slave_addr, (USHORT)mb_offset, - *(USHORT*)data_ptr, (LONG)MB_RESPONSE_TIMEOUT ); - break; - case MB_FUNC_WRITE_MULTIPLE_COILS: - mb_error = eMBMasterReqWriteMultipleCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset, - (USHORT)mb_size, (UCHAR*)data_ptr, - (LONG)MB_RESPONSE_TIMEOUT); - break; - case MB_FUNC_READ_DISCRETE_INPUTS: - mb_error = eMBMasterReqReadDiscreteInputs((UCHAR)mb_slave_addr, (USHORT)mb_offset, - (USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT ); - break; - case MB_FUNC_READ_HOLDING_REGISTER: - mb_error = eMBMasterReqReadHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset, - (USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT ); - break; - case MB_FUNC_WRITE_REGISTER: - mb_error = eMBMasterReqWriteHoldingRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset, - *(USHORT*)data_ptr, (LONG)MB_RESPONSE_TIMEOUT ); - break; - - case MB_FUNC_WRITE_MULTIPLE_REGISTERS: - mb_error = eMBMasterReqWriteMultipleHoldingRegister( (UCHAR)mb_slave_addr, - (USHORT)mb_offset, (USHORT)mb_size, - (USHORT*)data_ptr, (LONG)MB_RESPONSE_TIMEOUT ); - break; - case MB_FUNC_READWRITE_MULTIPLE_REGISTERS: - mb_error = eMBMasterReqReadWriteMultipleHoldingRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset, - (USHORT)mb_size, (USHORT*)data_ptr, - (USHORT)mb_offset, (USHORT)mb_size, - (LONG)MB_RESPONSE_TIMEOUT ); - break; - case MB_FUNC_READ_INPUT_REGISTER: - mb_error = eMBMasterReqReadInputRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset, - (USHORT)mb_size, (LONG) MB_RESPONSE_TIMEOUT ); - break; - default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect function in request (%u) ", - __FUNCTION__, mb_command); - mb_error = MB_MRE_NO_REG; - break; + case MB_FUNC_READ_COILS: + mb_error = eMBMasterReqReadCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset, + (USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_WRITE_SINGLE_COIL: + mb_error = eMBMasterReqWriteCoil((UCHAR)mb_slave_addr, (USHORT)mb_offset, + *(USHORT *)data_ptr, (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_WRITE_MULTIPLE_COILS: + mb_error = eMBMasterReqWriteMultipleCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset, + (USHORT)mb_size, (UCHAR *)data_ptr, + (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_READ_DISCRETE_INPUTS: + mb_error = eMBMasterReqReadDiscreteInputs((UCHAR)mb_slave_addr, (USHORT)mb_offset, + (USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_READ_HOLDING_REGISTER: + mb_error = eMBMasterReqReadHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset, + (USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_WRITE_REGISTER: + mb_error = eMBMasterReqWriteHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset, + *(USHORT *)data_ptr, (LONG)MB_RESPONSE_TIMEOUT); + break; + + case MB_FUNC_WRITE_MULTIPLE_REGISTERS: + mb_error = eMBMasterReqWriteMultipleHoldingRegister((UCHAR)mb_slave_addr, + (USHORT)mb_offset, (USHORT)mb_size, + (USHORT *)data_ptr, (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_READWRITE_MULTIPLE_REGISTERS: + mb_error = eMBMasterReqReadWriteMultipleHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset, + (USHORT)mb_size, (USHORT *)data_ptr, + (USHORT)mb_offset, (USHORT)mb_size, + (LONG)MB_RESPONSE_TIMEOUT); + break; + case MB_FUNC_READ_INPUT_REGISTER: + mb_error = eMBMasterReqReadInputRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset, + (USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT); + break; + default: + ESP_LOGE(TAG, "%s: Incorrect function in request (%u) ", + __FUNCTION__, mb_command); + mb_error = MB_MRE_NO_REG; + break; } // Propagate the Modbus errors to higher level @@ -289,7 +353,7 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void* break; default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect return code (%x) ", __FUNCTION__, mb_error); + ESP_LOGE(TAG, "%s: Incorrect return code (%x) ", __FUNCTION__, mb_error); error = ESP_FAIL; break; } @@ -333,11 +397,11 @@ static uint8_t mbc_tcp_master_get_command(mb_param_type_t param_type, mb_param_m if (mode != MB_PARAM_WRITE) { command = MB_FUNC_READ_DISCRETE_INPUTS; } else { - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect mode (%u)", __FUNCTION__, (uint8_t)mode); + ESP_LOGE(TAG, "%s: Incorrect mode (%u)", __FUNCTION__, (uint8_t)mode); } break; default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u)", __FUNCTION__, param_type); + ESP_LOGE(TAG, "%s: Incorrect param type (%u)", __FUNCTION__, param_type); break; } return command; @@ -368,7 +432,7 @@ static esp_err_t mbc_tcp_master_set_param_data(void* dest, void* src, mb_descr_t memcpy((void*)dest, (void*)src, (size_t)param_size); break; default: - ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u).", + ESP_LOGE(TAG, "%s: Incorrect param type (%u).", __FUNCTION__, (uint16_t)param_type); err = ESP_ERR_NOT_SUPPORTED; break; @@ -397,7 +461,7 @@ static esp_err_t mbc_tcp_master_set_request(char* name, mb_param_mode_t mode, mb continue; // The length of strings is different then check next record in the table } // Compare the name of parameter with parameter key from table - uint8_t comp_result = memcmp((const char*)name, (const char*)reg_ptr->param_key, (size_t)param_key_len); + int comp_result = memcmp((const void*)name, (const void*)reg_ptr->param_key, (size_t)param_key_len); if (comp_result == 0) { // The correct line is found in the table and reg_ptr points to the found parameter description request->slave_addr = reg_ptr->mb_slave_addr; @@ -420,32 +484,44 @@ static esp_err_t mbc_tcp_master_get_parameter(uint16_t cid, char* name, uint8_t* { MB_MASTER_CHECK((name != NULL), ESP_ERR_INVALID_ARG, "mb incorrect descriptor."); MB_MASTER_CHECK((type != NULL), ESP_ERR_INVALID_ARG, "type pointer is incorrect."); + MB_MASTER_CHECK((value != NULL), ESP_ERR_INVALID_ARG, "value pointer is incorrect."); esp_err_t error = ESP_ERR_INVALID_RESPONSE; mb_param_request_t request ; mb_parameter_descriptor_t reg_info = { 0 }; - uint8_t param_buffer[PARAM_MAX_SIZE] = { 0 }; + uint8_t* pdata = NULL; error = mbc_tcp_master_set_request(name, MB_PARAM_READ, &request, ®_info); if ((error == ESP_OK) && (cid == reg_info.cid)) { - error = mbc_tcp_master_send_request(&request, ¶m_buffer[0]); + // alloc buffer to store parameter data + pdata = calloc(1, (reg_info.mb_size << 1)); + if (!pdata) { + return ESP_ERR_INVALID_STATE; + } + error = mbc_tcp_master_send_request(&request, pdata); if (error == ESP_OK) { // If data pointer is NULL then we don't need to set value (it is still in the cache of cid) if (value != NULL) { - error = mbc_tcp_master_set_param_data((void*)value, (void*)¶m_buffer[0], + error = mbc_tcp_master_set_param_data((void*)value, (void*)pdata, reg_info.param_type, reg_info.param_size); - MB_MASTER_CHECK((error == ESP_OK), ESP_ERR_INVALID_STATE, "fail to set parameter data."); + if (error != ESP_OK) { + ESP_LOGE(TAG, "fail to set parameter data."); + error = ESP_ERR_INVALID_STATE; + } else { + ESP_LOGD(TAG, "%s: Good response for get cid(%u) = %s", + __FUNCTION__, (unsigned)reg_info.cid, (char*)esp_err_to_name(error)); + } } - ESP_LOGD(MB_MASTER_TAG, "%s: Good response for get cid(%u) = %s", - __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error)); } else { - ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to get cid(%u) = %s", - __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error)); + ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s", + __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error)); + error = ESP_ERR_INVALID_RESPONSE; } + free(pdata); // Set the type of parameter found in the table *type = reg_info.param_type; } else { - ESP_LOGE(MB_MASTER_TAG, "%s: The cid(%u) not found in the data dictionary.", - __FUNCTION__, reg_info.cid); + ESP_LOGE(TAG, "%s: The cid(%u) not found in the data dictionary.", + __FUNCTION__, reg_info.cid); error = ESP_ERR_INVALID_ARG; } return error; @@ -461,27 +537,36 @@ static esp_err_t mbc_tcp_master_set_parameter(uint16_t cid, char* name, uint8_t* esp_err_t error = ESP_ERR_INVALID_RESPONSE; mb_param_request_t request ; mb_parameter_descriptor_t reg_info = { 0 }; - uint8_t param_buffer[PARAM_MAX_SIZE] = { 0 }; + uint8_t* pdata = NULL; error = mbc_tcp_master_set_request(name, MB_PARAM_WRITE, &request, ®_info); if ((error == ESP_OK) && (cid == reg_info.cid)) { + pdata = calloc(1, (reg_info.mb_size << 1)); // alloc parameter buffer + if (!pdata) { + return ESP_ERR_INVALID_STATE; + } // Transfer value of characteristic into parameter buffer - error = mbc_tcp_master_set_param_data((void*)¶m_buffer[0], (void*)value, - reg_info.param_type, reg_info.param_size); - MB_MASTER_CHECK((error == ESP_OK), ESP_ERR_INVALID_STATE, "failure to set parameter data."); + error = mbc_tcp_master_set_param_data((void*)pdata, (void*)value, + reg_info.param_type, reg_info.param_size); + if (error != ESP_OK) { + ESP_LOGE(TAG, "fail to set parameter data."); + free(pdata); + return ESP_ERR_INVALID_STATE; + } // Send request to write characteristic data - error = mbc_tcp_master_send_request(&request, ¶m_buffer[0]); + error = mbc_tcp_master_send_request(&request, pdata); if (error == ESP_OK) { - ESP_LOGD(MB_MASTER_TAG, "%s: Good response for set cid(%u) = %s", - __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error)); + ESP_LOGD(TAG, "%s: Good response for set cid(%u) = %s", + __FUNCTION__, (unsigned)reg_info.cid, (char*)esp_err_to_name(error)); } else { - ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to set cid(%u) = %s", + ESP_LOGD(TAG, "%s: Bad response to set cid(%u) = %s", __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error)); } + free(pdata); // Set the type of parameter found in the table *type = reg_info.param_type; } else { - ESP_LOGE(MB_MASTER_TAG, "%s: The requested cid(%u) not found in the data dictionary.", + ESP_LOGE(TAG, "%s: The requested cid(%u) not found in the data dictionary.", __FUNCTION__, reg_info.cid); error = ESP_ERR_INVALID_ARG; } @@ -501,8 +586,7 @@ static esp_err_t mbc_tcp_master_set_parameter(uint16_t cid, char* name, uint8_t* * @return result */ // Callback function for reading of MB Input Registers -eMBErrorCode eMBRegInputCBTcpMaster(UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNRegs) +eMBErrorCode eMBRegInputCBTcpMaster(UCHAR* pucRegBuffer, USHORT usAddress, USHORT usNRegs) { MB_MASTER_ASSERT(mbm_interface_ptr != NULL); mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; @@ -537,36 +621,40 @@ eMBErrorCode eMBRegInputCBTcpMaster(UCHAR * pucRegBuffer, USHORT usAddress, */ // Callback function for reading of MB Holding Registers // Executed by stack when request to read/write holding registers is received -eMBErrorCode eMBRegHoldingCBTcpMaster(UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNRegs, eMBRegisterMode eMode) +eMBErrorCode eMBRegHoldingCBTcpMaster(UCHAR *pucRegBuffer, USHORT usAddress, + USHORT usNRegs, eMBRegisterMode eMode) { MB_MASTER_ASSERT(mbm_interface_ptr != NULL); - mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; + mb_master_options_t *mbm_opts = &mbm_interface_ptr->opts; MB_MASTER_ASSERT(pucRegBuffer != NULL); USHORT usRegHoldingNregs = (USHORT)mbm_opts->mbm_reg_buffer_size; - UCHAR* pucHoldingBuffer = (UCHAR*)mbm_opts->mbm_reg_buffer_ptr; + UCHAR *pucHoldingBuffer = (UCHAR *)mbm_opts->mbm_reg_buffer_ptr; eMBErrorCode eStatus = MB_ENOERR; USHORT usRegs = usNRegs; // Check input and configuration parameters for correctness - if ((pucHoldingBuffer != NULL) - && (usRegHoldingNregs == usNRegs) - && (usNRegs >= 1)) { - switch (eMode) { - case MB_REG_WRITE: - while (usRegs > 0) { - _XFER_2_RD(pucRegBuffer, pucHoldingBuffer); - usRegs -= 1; - }; - break; - case MB_REG_READ: - while (usRegs > 0) { - _XFER_2_WR(pucHoldingBuffer, pucRegBuffer); - pucHoldingBuffer += 2; - usRegs -= 1; - }; - break; + if ((pucHoldingBuffer != NULL) && (usRegHoldingNregs == usNRegs) && (usNRegs >= 1)) + { + switch (eMode) + { + case MB_REG_WRITE: + while (usRegs > 0) + { + _XFER_2_RD(pucRegBuffer, pucHoldingBuffer); + usRegs -= 1; + }; + break; + case MB_REG_READ: + while (usRegs > 0) + { + _XFER_2_WR(pucHoldingBuffer, pucRegBuffer); + pucHoldingBuffer += 2; + usRegs -= 1; + }; + break; } - } else { + } + else + { eStatus = MB_ENOREG; } return eStatus; @@ -583,8 +671,8 @@ eMBErrorCode eMBRegHoldingCBTcpMaster(UCHAR * pucRegBuffer, USHORT usAddress, * @return result */ // Callback function for reading of MB Coils Registers -eMBErrorCode eMBRegCoilsCBTcpMaster(UCHAR* pucRegBuffer, USHORT usAddress, - USHORT usNCoils, eMBRegisterMode eMode) +eMBErrorCode eMBRegCoilsCBTcpMaster(UCHAR *pucRegBuffer, USHORT usAddress, + USHORT usNCoils, eMBRegisterMode eMode) { MB_MASTER_ASSERT(mbm_interface_ptr != NULL); mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; @@ -635,7 +723,7 @@ eMBErrorCode eMBRegCoilsCBTcpMaster(UCHAR* pucRegBuffer, USHORT usAddress, */ // Callback function for reading of MB Discrete Input Registers eMBErrorCode eMBRegDiscreteCBTcpMaster(UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNDiscrete) + USHORT usNDiscrete) { MB_MASTER_ASSERT(mbm_interface_ptr != NULL); mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts; @@ -698,17 +786,20 @@ esp_err_t mbc_tcp_master_create(void** handler) status = xTaskCreate((void*)&modbus_tcp_master_task, "modbus_tcp_master_task", MB_CONTROLLER_STACK_SIZE, - NULL, // No parameters + NULL, // No parameters MB_CONTROLLER_PRIORITY, &mbm_opts->mbm_task_handle); if (status != pdPASS) { vTaskDelete(mbm_opts->mbm_task_handle); MB_MASTER_CHECK((status == pdPASS), ESP_ERR_NO_MEM, - "mb controller task creation error, xTaskCreate() returns (0x%x).", - (uint32_t)status); + "mb controller task creation error, xTaskCreate() returns (0x%x).", + (uint32_t)status); } MB_MASTER_ASSERT(mbm_opts->mbm_task_handle != NULL); // The task is created but handle is incorrect + LIST_INIT(&mbm_opts->mbm_slave_list); // Init slave address list + mbm_opts->mbm_slave_list_count = 0; + // Initialize public interface methods of the interface mbm_interface_ptr->init = mbc_tcp_master_create; mbm_interface_ptr->destroy = mbc_tcp_master_destroy; diff --git a/components/freemodbus/tcp_master/port/port_tcp_master.c b/components/freemodbus/tcp_master/port/port_tcp_master.c index f4ace753b764..cf35b95e82f2 100644 --- a/components/freemodbus/tcp_master/port/port_tcp_master.c +++ b/components/freemodbus/tcp_master/port/port_tcp_master.c @@ -13,26 +13,34 @@ * limitations under the License. */ /* - * FreeModbus Libary: ESP32 TCP Port - * Copyright (C) 2006 Christian Walter - * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: port.h,v 1.2 2006/09/04 14:39:20 wolti Exp $ - */ + * FreeModbus Libary: ESP32 TCP Port + * Copyright (C) 2006 Christian Walter + * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: port.c,v 1.2 2006/09/04 14:39:20 wolti Exp $ + */ /* ----------------------- System includes ----------------------------------*/ #include @@ -58,7 +66,6 @@ #define MB_TCP_CONNECTION_TIMEOUT_MS ( 20 ) // Connection timeout in mS #define MB_TCP_RECONNECT_TIMEOUT ( 5000000 ) // Connection timeout in uS -#define MB_TCP_MASTER_PORT_TAG "MB_TCP_MASTER_PORT" #define MB_EVENT_REQ_DONE_MASK ( EV_MASTER_PROCESS_SUCCESS | \ EV_MASTER_ERROR_RESPOND_TIMEOUT | \ EV_MASTER_ERROR_RECEIVE_DATA | \ @@ -76,6 +83,7 @@ void vMBPortEventClose( void ); /* ----------------------- Static variables ---------------------------------*/ +static const char *TAG = "MB_TCP_MASTER_PORT"; static MbPortConfig_t xMbPortConfig; static EventGroupHandle_t xMasterEventHandle = NULL; static SemaphoreHandle_t xShutdownSemaphore = NULL; @@ -106,7 +114,7 @@ xMBMasterTCPPortInit( USHORT usTCPPort ) xMbPortConfig.pxMbSlaveInfo = calloc(MB_TCP_PORT_MAX_CONN, sizeof(MbSlaveInfo_t*)); if (!xMbPortConfig.pxMbSlaveInfo) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "TCP slave info alloc failure."); + ESP_LOGE(TAG, "TCP slave info alloc failure."); return FALSE; } for(int idx = 0; idx < MB_TCP_PORT_MAX_CONN; xMbPortConfig.pxMbSlaveInfo[idx] = NULL, idx++); @@ -115,12 +123,13 @@ xMBMasterTCPPortInit( USHORT usTCPPort ) xMbPortConfig.usPort = usTCPPort; xMbPortConfig.usMbSlaveInfoCount = 0; xMbPortConfig.ucCurSlaveIndex = 1; + xMbPortConfig.pxMbSlaveCurrInfo = NULL; - xMbPortConfig.xConnectQueue = xQueueCreate(2, sizeof(CHAR*)); + xMbPortConfig.xConnectQueue = xQueueCreate(2, sizeof(MbSlaveAddrInfo_t)); if (xMbPortConfig.xConnectQueue == 0) { // Queue was not created and must not be used. - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "TCP master queue creation failure."); + ESP_LOGE(TAG, "TCP master queue creation failure."); return FALSE; } @@ -134,10 +143,10 @@ xMBMasterTCPPortInit( USHORT usTCPPort ) MB_PORT_TASK_AFFINITY); if (xErr != pdTRUE) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "TCP master task creation failure."); + ESP_LOGE(TAG, "TCP master task creation failure."); (void)vTaskDelete(xMbPortConfig.xMbTcpTaskHandle); } else { - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "TCP master stack initialized."); + ESP_LOGI(TAG, "TCP master stack initialized."); bOkay = TRUE; } @@ -145,9 +154,30 @@ xMBMasterTCPPortInit( USHORT usTCPPort ) return bOkay; } +static MbSlaveInfo_t* vMBTCPPortMasterFindSlaveInfo(UCHAR ucSlaveAddr) +{ + int xIndex; + BOOL xFound = false; + for (xIndex = 0; xIndex < xMbPortConfig.usMbSlaveInfoCount; xIndex++) { + if (xMbPortConfig.pxMbSlaveInfo[xIndex]->ucSlaveAddr == ucSlaveAddr) { + xMbPortConfig.pxMbSlaveCurrInfo = xMbPortConfig.pxMbSlaveInfo[xIndex]; + xFound = TRUE; + xMbPortConfig.ucCurSlaveIndex = xIndex; + } + } + if (!xFound) { + xMbPortConfig.pxMbSlaveCurrInfo = NULL; + ESP_LOGE(TAG, "Slave info for short address %d not found.", ucSlaveAddr); + } + return xMbPortConfig.pxMbSlaveCurrInfo; +} + static MbSlaveInfo_t* vMBTCPPortMasterGetCurrInfo(void) { - return xMbPortConfig.pxMbSlaveInfo[xMbPortConfig.ucCurSlaveIndex - 1]; + if (!xMbPortConfig.pxMbSlaveCurrInfo) { + ESP_LOGE(TAG, "Incorrect current slave info."); + } + return xMbPortConfig.pxMbSlaveCurrInfo; } // Start Modbus event state machine @@ -158,10 +188,10 @@ static void vMBTCPPortMasterStartPoll(void) EventBits_t xFlags = xEventGroupSetBits(xMasterEventHandle, (EventBits_t)xMasterEvent); if (!(xFlags & xMasterEvent)) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to start TCP stack."); + ESP_LOGE(TAG, "Fail to start TCP stack."); } } else { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to start polling. Incorrect event handle..."); + ESP_LOGE(TAG, "Fail to start polling. Incorrect event handle..."); } } @@ -173,10 +203,10 @@ static void vMBTCPPortMasterStopPoll(void) EventBits_t xFlags = xEventGroupClearBits(xMasterEventHandle, (EventBits_t)xMasterEvent); if (!(xFlags & xMasterEvent)) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to stop polling."); + ESP_LOGE(TAG, "Fail to stop polling."); } } else { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to stop polling. Incorrect event handle..."); + ESP_LOGE(TAG, "Fail to stop polling. Incorrect event handle..."); } } @@ -207,11 +237,11 @@ static BOOL xMBTCPPortMasterCloseConnection(MbSlaveInfo_t* pxInfo) return FALSE; } if (pxInfo->xSockId == -1) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Wrong socket info or disconnected socket: %d, skip.", pxInfo->xSockId); + ESP_LOGE(TAG, "Wrong socket info or disconnected socket: %d, skip.", pxInfo->xSockId); return FALSE; } if (shutdown(pxInfo->xSockId, SHUT_RDWR) == -1) { - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Shutdown failed sock %d, errno=%d", pxInfo->xSockId, errno); + ESP_LOGV(TAG, "Shutdown failed sock %d, errno=%d", pxInfo->xSockId, errno); } close(pxInfo->xSockId); pxInfo->xSockId = -1; @@ -225,11 +255,6 @@ void vMBTCPPortMasterSetNetOpt(void* pvNetIf, eMBPortIpVer xIpVersion, eMBPortPr xMbPortConfig.eMbIpVer = xIpVersion; } -void vMBTCPPortMasterTaskStart(void) -{ - vTaskResume(xMbPortConfig.xMbTcpTaskHandle); -} - // Function returns time left for response processing according to response timeout static int64_t xMBTCPPortMasterGetRespTimeLeft(MbSlaveInfo_t* pxInfo) { @@ -281,12 +306,12 @@ static int xMBTCPPortMasterGetBuf(MbSlaveInfo_t* pxInfo, UCHAR* pucDstBuf, USHOR continue; } else if (errno == ENOTCONN) { // Socket connection closed - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) connection closed.", + ESP_LOGE(TAG, "Socket(#%d)(%s) connection closed.", pxInfo->xSockId, pxInfo->pcIpAddr); return ERR_CONN; } else { // Other error occurred during receiving - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) receive error, length=%d, errno=%d", + ESP_LOGE(TAG, "Socket(#%d)(%s) receive error, length=%d, errno=%d", pxInfo->xSockId, pxInfo->pcIpAddr, xLength, errno); return -1; } @@ -317,7 +342,7 @@ static int vMBTCPPortMasterReadPacket(MbSlaveInfo_t* pxInfo) pxInfo->xRcvErr = xRet; return xRet; } else if (xRet != MB_TCP_UID) { - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket (#%d)(%s), Fail to read modbus header. ret=%d", + ESP_LOGD(TAG, "Socket (#%d)(%s), Fail to read modbus header. ret=%d", pxInfo->xSockId, pxInfo->pcIpAddr, xRet); pxInfo->xRcvErr = ERR_VAL; return ERR_VAL; @@ -331,7 +356,7 @@ static int vMBTCPPortMasterReadPacket(MbSlaveInfo_t* pxInfo) return xRet; } else if (xRet != xLength) { // Received incorrect or fragmented packet. - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) incorrect packet, length=%d, TID=0x%02x, errno=%d(%s)", + ESP_LOGD(TAG, "Socket(#%d)(%s) incorrect packet, length=%d, TID=0x%02x, errno=%d(%s)", pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usRcvPos, usTidRcv, errno, strerror(errno)); pxInfo->xRcvErr = ERR_VAL; @@ -341,13 +366,13 @@ static int vMBTCPPortMasterReadPacket(MbSlaveInfo_t* pxInfo) // Check transaction identifier field in the incoming packet. if ((pxInfo->usTidCnt - 1) != usTidRcv) { - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket (#%d)(%s), incorrect TID(0x%02x)!=(0x%02x) received, discard data.", + ESP_LOGD(TAG, "Socket (#%d)(%s), incorrect TID(0x%02x)!=(0x%02x) received, discard data.", pxInfo->xSockId, pxInfo->pcIpAddr, usTidRcv, (pxInfo->usTidCnt - 1)); pxInfo->xRcvErr = ERR_BUF; return ERR_BUF; } pxInfo->usRcvPos += xRet + MB_TCP_UID; - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) get data, length=%d, TID=0x%02x, errno=%d(%s)", + ESP_LOGD(TAG, "Socket(#%d)(%s) get data, length=%d, TID=0x%02x, errno=%d(%s)", pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usRcvPos, usTidRcv, errno, strerror(errno)); pxInfo->xRcvErr = ERR_OK; @@ -364,7 +389,7 @@ static err_t xMBTCPPortMasterSetNonBlocking(MbSlaveInfo_t* pxInfo) // Set non blocking attribute for socket ULONG ulFlags = fcntl(pxInfo->xSockId, F_GETFL); if (fcntl(pxInfo->xSockId, F_SETFL, ulFlags | O_NONBLOCK) == -1) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), fcntl() call error=%d", + ESP_LOGE(TAG, "Socket(#%d)(%s), fcntl() call error=%d", pxInfo->xSockId, pxInfo->pcIpAddr, errno); return ERR_WOULDBLOCK; } @@ -397,12 +422,12 @@ static err_t xMBTCPPortMasterCheckAlive(MbSlaveInfo_t* pxInfo, ULONG xTimeoutMs) if (errno == EINPROGRESS) { xErr = ERR_INPROGRESS; } else { - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(" connection, select write err(errno) = %d(%d)."), + ESP_LOGV(TAG, MB_SLAVE_FMT(" connection, select write err(errno) = %d(%d)."), pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xErr, errno); xErr = ERR_CONN; } } else if (xErr == 0) { - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), connection timeout occurred, err(errno) = %d(%d).", + ESP_LOGV(TAG, "Socket(#%d)(%s), connection timeout occurred, err(errno) = %d(%d).", pxInfo->xSockId, pxInfo->pcIpAddr, xErr, errno); return ERR_INPROGRESS; } else { @@ -411,11 +436,11 @@ static err_t xMBTCPPortMasterCheckAlive(MbSlaveInfo_t* pxInfo, ULONG xTimeoutMs) // Check socket error xErr = getsockopt(pxInfo->xSockId, SOL_SOCKET, SO_ERROR, (void*)&xOptErr, (socklen_t*)&ulOptLen); if (xOptErr != 0) { - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), sock error occurred (%d).", + ESP_LOGD(TAG, "Socket(#%d)(%s), sock error occurred (%d).", pxInfo->xSockId, pxInfo->pcIpAddr, xOptErr); return ERR_CONN; } - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), is alive.", + ESP_LOGV(TAG, "Socket(#%d)(%s), is alive.", pxInfo->xSockId, pxInfo->pcIpAddr); return ERR_OK; } @@ -445,7 +470,7 @@ static BOOL xMBTCPPortMasterCheckHost(const CHAR* pcHostStr, ip_addr_t* pxHostAd int xRet = getaddrinfo(pcHostStr, NULL, &xHint, &pxAddrList); if (xRet != 0) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Incorrect host name or IP: %s", pcHostStr); + ESP_LOGE(TAG, "Incorrect host name or IP: %s", pcHostStr); return FALSE; } if (pxAddrList->ai_family == AF_INET) { @@ -463,20 +488,24 @@ static BOOL xMBTCPPortMasterCheckHost(const CHAR* pcHostStr, ip_addr_t* pxHostAd if (pxHostAddr) { *pxHostAddr = xTargetAddr; } - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Host[IP]: \"%s\"[%s]", pxAddrList->ai_canonname, pcStr); + ESP_LOGI(TAG, "Host[IP]: \"%s\"[%s]", pxAddrList->ai_canonname, pcStr); freeaddrinfo(pxAddrList); return TRUE; } -BOOL xMBTCPPortMasterAddSlaveIp(const CHAR* pcIpStr) +BOOL xMBTCPPortMasterAddSlaveIp(const USHORT usIndex, const CHAR* pcIpStr, UCHAR ucSlaveAddress) { BOOL xRes = FALSE; + MbSlaveAddrInfo_t xSlaveAddrInfo = { 0 }; MB_PORT_CHECK(xMbPortConfig.xConnectQueue != NULL, FALSE, "Wrong slave IP address to add."); - if (pcIpStr) { + if (pcIpStr && (usIndex != 0xFF)) { xRes = xMBTCPPortMasterCheckHost(pcIpStr, NULL); } if (xRes || !pcIpStr) { - BaseType_t xStatus = xQueueSend(xMbPortConfig.xConnectQueue, (const void*)&pcIpStr, 100); + xSlaveAddrInfo.pcIPAddr = pcIpStr; + xSlaveAddrInfo.usIndex = usIndex; + xSlaveAddrInfo.ucSlaveAddr = ucSlaveAddress; + BaseType_t xStatus = xQueueSend(xMbPortConfig.xConnectQueue, (void*)&xSlaveAddrInfo, 100); MB_PORT_CHECK((xStatus == pdTRUE), FALSE, "FAIL to add slave IP address: [%s].", pcIpStr); } return xRes; @@ -514,7 +543,7 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo) int xRet = getaddrinfo(pxInfo->pcIpAddr, pcStr, &xHint, &pxAddrList); free(pcStr); if (xRet != 0) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Cannot resolve host: %s", pxInfo->pcIpAddr); + ESP_LOGE(TAG, "Cannot resolve host: %s", pxInfo->pcIpAddr); return ERR_CONN; } @@ -537,12 +566,12 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo) if (pxInfo->xSockId <= 0) { pxInfo->xSockId = socket(pxCurAddr->ai_family, pxCurAddr->ai_socktype, pxCurAddr->ai_protocol); if (pxInfo->xSockId < 0) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Unable to create socket: #%d, errno %d", pxInfo->xSockId, errno); + ESP_LOGE(TAG, "Unable to create socket: #%d, errno %d", pxInfo->xSockId, errno); xErr = ERR_IF; continue; } } else { - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket (#%d)(%s) created.", pxInfo->xSockId, cStr); + ESP_LOGV(TAG, "Socket (#%d)(%s) created.", pxInfo->xSockId, cStr); } // Set non blocking attribute for socket @@ -553,7 +582,7 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo) xErr = connect(pxInfo->xSockId, (struct sockaddr*)pxCurAddr->ai_addr, pxCurAddr->ai_addrlen); if ((xErr < 0) && (errno == EINPROGRESS || errno == EALREADY)) { // The unblocking connect is pending (check status later) or already connected - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) connection is pending, errno %d (%s).", + ESP_LOGV(TAG, "Socket(#%d)(%s) connection is pending, errno %d (%s).", pxInfo->xSockId, cStr, errno, strerror(errno)); // Set keep alive flag in socket options @@ -566,12 +595,12 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo) continue; } else if (xErr != ERR_OK) { // Other error occurred during connection - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(" unable to connect, error=%d, errno %d (%s)"), + ESP_LOGV(TAG, MB_SLAVE_FMT(" unable to connect, error=%d, errno %d (%s)"), pxInfo->xIndex, pxInfo->xSockId, cStr, xErr, errno, strerror(errno)); xMBTCPPortMasterCloseConnection(pxInfo); xErr = ERR_CONN; } else { - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", successfully connected."), + ESP_LOGI(TAG, MB_SLAVE_FMT(", successfully connected."), pxInfo->xIndex, pxInfo->xSockId, cStr); continue; } @@ -613,7 +642,7 @@ static int xMBTCPPortMasterCheckConnState(fd_set* pxFdSet) xErr = xMBTCPPortMasterCheckAlive(pxInfo, 0); if ((xErr < 0) && (((xTime - pxInfo->xRecvTimeStamp) > MB_TCP_RECONNECT_TIMEOUT) || ((xTime - pxInfo->xSendTimeStamp) > MB_TCP_RECONNECT_TIMEOUT))) { - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", slave is down, off_time[r][w](us) = [%ju][%ju]."), + ESP_LOGI(TAG, MB_SLAVE_FMT(", slave is down, off_time[r][w](us) = [%ju][%ju]."), pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, @@ -635,9 +664,9 @@ static void xMBTCPPortMasterFsmSetError(eMBMasterErrorEventType xErrType, eMBMas static void vMBTCPPortMasterTask(void *pvParameters) { - CHAR* pcAddrStr = NULL; MbSlaveInfo_t* pxInfo; MbSlaveInfo_t* pxCurrInfo; + fd_set xConnSet; fd_set xReadSet; int xMaxSd = 0; @@ -647,51 +676,53 @@ static void vMBTCPPortMasterTask(void *pvParameters) // Register each slave in the connection info structure while (1) { - BaseType_t xStatus = xQueueReceive(xMbPortConfig.xConnectQueue, (void*)&pcAddrStr, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS)); - xMBTCPPortMasterCheckShutdown(); + MbSlaveAddrInfo_t xSlaveAddrInfo = { 0 }; + BaseType_t xStatus = xQueueReceive(xMbPortConfig.xConnectQueue, (void*)&xSlaveAddrInfo, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS)); + xMBTCPPortMasterCheckShutdown(); if (xStatus != pdTRUE) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to register slave IP."); + ESP_LOGE(TAG, "Fail to register slave IP."); } else { - if (pcAddrStr == NULL && xMbPortConfig.usMbSlaveInfoCount) { + if (xSlaveAddrInfo.pcIPAddr == NULL && xMbPortConfig.usMbSlaveInfoCount && xSlaveAddrInfo.usIndex == 0xFF) { break; } if (xMbPortConfig.usMbSlaveInfoCount > MB_TCP_PORT_MAX_CONN) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Exceeds maximum connections limit=%d.", MB_TCP_PORT_MAX_CONN); + ESP_LOGE(TAG, "Exceeds maximum connections limit=%d.", MB_TCP_PORT_MAX_CONN); break; } pxInfo = calloc(1, sizeof(MbSlaveInfo_t)); if (!pxInfo) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Slave(#%d), info structure allocation fail.", + ESP_LOGE(TAG, "Slave(#%d), info structure allocation fail.", xMbPortConfig.usMbSlaveInfoCount); free(pxInfo); break; } pxInfo->pucRcvBuf = calloc(MB_TCP_BUF_SIZE, sizeof(UCHAR)); if (!pxInfo->pucRcvBuf) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Slave(#%d), receive buffer allocation fail.", + ESP_LOGE(TAG, "Slave(#%d), receive buffer allocation fail.", xMbPortConfig.usMbSlaveInfoCount); free(pxInfo->pucRcvBuf); break; } pxInfo->usRcvPos = 0; - pxInfo->pcIpAddr = pcAddrStr; + pxInfo->pcIpAddr = xSlaveAddrInfo.pcIPAddr; pxInfo->xSockId = -1; pxInfo->xError = -1; pxInfo->xRecvTimeStamp = xMBTCPGetTimeStamp(); pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp(); pxInfo->xMbProto = MB_PROTO_TCP; - pxInfo->xIndex = xMbPortConfig.usMbSlaveInfoCount; + pxInfo->ucSlaveAddr = xSlaveAddrInfo.ucSlaveAddr; + pxInfo->xIndex = xSlaveAddrInfo.usIndex; pxInfo->usTidCnt = (USHORT)(xMbPortConfig.usMbSlaveInfoCount << 8U); // Register slave xMbPortConfig.pxMbSlaveInfo[xMbPortConfig.usMbSlaveInfoCount++] = pxInfo; - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Add slave IP: %s", pcAddrStr); + ESP_LOGI(TAG, "Add slave IP: %s", xSlaveAddrInfo.pcIPAddr); } } // Main connection cycle while (1) { - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Connecting to slaves..."); + ESP_LOGI(TAG, "Connecting to slaves..."); xTime = xMBTCPGetTimeStamp(); usSlaveConnCnt = 0; CHAR ucDot = '.'; @@ -704,7 +735,7 @@ static void vMBTCPPortMasterTask(void *pvParameters) pxInfo = xMbPortConfig.pxMbSlaveInfo[ucCnt]; // if slave descriptor is NULL then it is end of list or connection closed. if (!pxInfo) { - ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Index: %d is not initialized, skip.", ucCnt); + ESP_LOGV(TAG, "Index: %d is not initialized, skip.", ucCnt); if (xMbPortConfig.usMbSlaveInfoCount) { continue; } @@ -719,12 +750,12 @@ static void vMBTCPPortMasterTask(void *pvParameters) // In case of connection errors remove the socket from set if (FD_ISSET(pxInfo->xSockId, &xConnSet)) { FD_CLR(pxInfo->xSockId, &xConnSet); - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(" connect failed, error = %d."), + ESP_LOGE(TAG, MB_SLAVE_FMT(" connect failed, error = %d."), pxInfo->xIndex, pxInfo->xSockId, (char*)pxInfo->pcIpAddr, xErr); - if (usSlaveConnCnt) { - usSlaveConnCnt--; - } + if (usSlaveConnCnt) { + usSlaveConnCnt--; + } } break; case ERR_OK: @@ -733,7 +764,7 @@ static void vMBTCPPortMasterTask(void *pvParameters) FD_SET(pxInfo->xSockId, &xConnSet); usSlaveConnCnt++; xMaxSd = (pxInfo->xSockId > xMaxSd) ? pxInfo->xSockId : xMaxSd; - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", connected %d slave(s), error = %d."), + ESP_LOGD(TAG, MB_SLAVE_FMT(", connected %d slave(s), error = %d."), pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, usSlaveConnCnt, xErr); @@ -743,7 +774,7 @@ static void vMBTCPPortMasterTask(void *pvParameters) } break; default: - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", unexpected error = %d."), + ESP_LOGE(TAG, MB_SLAVE_FMT(", unexpected error = %d."), pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xErr); @@ -755,7 +786,7 @@ static void vMBTCPPortMasterTask(void *pvParameters) xMBTCPPortMasterCheckShutdown(); } } - ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Connected %d slaves, start polling...", usSlaveConnCnt); + ESP_LOGI(TAG, "Connected %d slaves, start polling...", usSlaveConnCnt); vMBTCPPortMasterStartPoll(); // Send event to start stack @@ -766,26 +797,26 @@ static void vMBTCPPortMasterTask(void *pvParameters) xMBMasterPortFsmWaitConfirmation(EV_MASTER_FRAME_TRANSMIT, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS)); // Synchronize state machine with send packet event if (xMBMasterPortFsmWaitConfirmation(EV_MASTER_FRAME_SENT, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS))) { - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "FSM Synchronized with sent event."); + ESP_LOGD(TAG, "FSM Synchronized with sent event."); } // Get slave info for the current slave. pxCurrInfo = vMBTCPPortMasterGetCurrInfo(); if (!pxCurrInfo) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Incorrect connection options for slave index: %d.", + ESP_LOGE(TAG, "Incorrect connection options for slave index: %d.", xMbPortConfig.ucCurSlaveIndex); vMBTCPPortMasterStopPoll(); xMBTCPPortMasterCheckShutdown(); break; // incorrect slave descriptor, reconnect. } xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo); - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Set select timeout, left time: %ju ms.", + ESP_LOGD(TAG, "Set select timeout, left time: %ju ms.", xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo)); // Wait respond from current slave during respond timeout int xRes = vMBTCPPortMasterRxCheck(pxCurrInfo->xSockId, &xReadSet, xTime); if (xRes == ERR_TIMEOUT) { // No respond from current slave, process timeout. // Need to drop response later if it is received after timeout. - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Select timeout, left time: %ju ms.", + ESP_LOGD(TAG, "Select timeout, left time: %ju ms.", xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo)); xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo); // Wait completion of last transaction @@ -794,7 +825,7 @@ static void vMBTCPPortMasterTask(void *pvParameters) continue; } else if (xRes < 0) { // Select error (slave connection or r/w failure). - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", socket select error. Slave disconnected?"), + ESP_LOGD(TAG, MB_SLAVE_FMT(", socket select error. Slave disconnected?"), pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr); xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo); // Wait completion of last transaction @@ -808,30 +839,30 @@ static void vMBTCPPortMasterTask(void *pvParameters) } else { // Check to make sure that active slave data is ready if (FD_ISSET(pxCurrInfo->xSockId, &xReadSet)) { - xErr = ERR_BUF; - for (int retry = 0; (xErr == ERR_BUF) && (retry < MB_TCP_READ_BUF_RETRY_CNT); retry++) { - xErr = vMBTCPPortMasterReadPacket(pxCurrInfo); + int xRet = ERR_BUF; + for (int retry = 0; (xRet == ERR_BUF) && (retry < MB_TCP_READ_BUF_RETRY_CNT); retry++) { + xRet = vMBTCPPortMasterReadPacket(pxCurrInfo); // The error ERR_BUF means received response to previous request // (due to timeout) with the same socket ID and incorrect TID, // then ignore it and try to get next response buffer. } - if (xErr > 0) { + if (xRet > 0) { // Response received correctly, send an event to stack xMBTCPPortMasterFsmSetError(EV_ERROR_INIT, EV_MASTER_FRAME_RECEIVED); - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", frame received."), + ESP_LOGD(TAG, MB_SLAVE_FMT(", frame received."), pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr); - } else if ((xErr == ERR_TIMEOUT) || (xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo) == 0)) { + } else if ((xRet == ERR_TIMEOUT) || (xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo) == 0)) { // Timeout occurred when receiving frame, process respond timeout - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", frame read timeout."), + ESP_LOGD(TAG, MB_SLAVE_FMT(", frame read timeout."), pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr); - } else if (xErr == ERR_BUF) { + } else if (xRet == ERR_BUF) { // After retries a response with incorrect TID received, process failure. xMBTCPPortMasterFsmSetError(EV_ERROR_RECEIVE_DATA, EV_MASTER_ERROR_PROCESS); - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", frame error."), + ESP_LOGD(TAG, MB_SLAVE_FMT(", frame error."), pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr); } else { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", critical error=%d."), - pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr, xErr); + ESP_LOGE(TAG, MB_SLAVE_FMT(", critical error=%d."), + pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr, xRet); // Stop polling process vMBTCPPortMasterStopPoll(); xMBTCPPortMasterCheckShutdown(); @@ -840,14 +871,14 @@ static void vMBTCPPortMasterTask(void *pvParameters) break; } xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo); - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Slave #%d, data processing left time %ju [ms].", pxCurrInfo->xIndex, xTime); + ESP_LOGD(TAG, "Slave #%d, data processing left time %ju [ms].", pxCurrInfo->xIndex, xTime); // Wait completion of Modbus frame processing before start of new transaction. if (xMBMasterPortFsmWaitConfirmation(MB_EVENT_REQ_DONE_MASK, pdMS_TO_TICKS(xTime))) { - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", data processing completed."), + ESP_LOGD(TAG, MB_SLAVE_FMT(", data processing completed."), pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr); } xTime = xMBTCPGetTimeStamp() - pxCurrInfo->xSendTimeStamp; - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", processing time[us] = %ju."), + ESP_LOGD(TAG, MB_SLAVE_FMT(", processing time[us] = %ju."), pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr, xTime); } } @@ -860,9 +891,27 @@ static void vMBTCPPortMasterTask(void *pvParameters) extern void vMBMasterPortEventClose(void); extern void vMBMasterPortTimerClose(void); +void +vMBMasterTCPPortEnable(void) +{ + vTaskResume(xMbPortConfig.xMbTcpTaskHandle); +} + void vMBMasterTCPPortDisable(void) { + // Try to exit the task gracefully, so select could release its internal callbacks + // that were allocated on the stack of the task we're going to delete + xShutdownSemaphore = xSemaphoreCreateBinary(); + // if no semaphore (alloc issues) or couldn't acquire it, just delete the task + if (xShutdownSemaphore == NULL || xSemaphoreTake(xShutdownSemaphore, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS)) != pdTRUE) { + ESP_LOGW(TAG, "Modbus port task couldn't exit gracefully within timeout -> abruptly deleting the task."); + vTaskDelete(xMbPortConfig.xMbTcpTaskHandle); + } + if (xShutdownSemaphore) { + vSemaphoreDelete(xShutdownSemaphore); + xShutdownSemaphore = NULL; + } for (USHORT ucCnt = 0; ucCnt < MB_TCP_PORT_MAX_CONN; ucCnt++) { MbSlaveInfo_t* pxInfo = xMbPortConfig.pxMbSlaveInfo[ucCnt]; if (pxInfo) { @@ -874,25 +923,12 @@ vMBMasterTCPPortDisable(void) xMbPortConfig.pxMbSlaveInfo[ucCnt] = NULL; } } + free(xMbPortConfig.pxMbSlaveInfo); } void vMBMasterTCPPortClose(void) { - // Try to exit the task gracefully, so select could release its internal callbacks - // that were allocated on the stack of the task we're going to delete - xShutdownSemaphore = xSemaphoreCreateBinary(); - // if no semaphore (alloc issues) or couldn't acquire it, just delete the task - if (xShutdownSemaphore == NULL || xSemaphoreTake(xShutdownSemaphore, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS)) != pdTRUE) { - ESP_LOGW(MB_TCP_MASTER_PORT_TAG, "Modbus port task couldn't exit gracefully within timeout -> abruptly deleting the task."); - vTaskDelete(xMbPortConfig.xMbTcpTaskHandle); - } - if (xShutdownSemaphore) { - vSemaphoreDelete(xShutdownSemaphore); - xShutdownSemaphore = NULL; - } - vMBMasterTCPPortDisable(); - free(xMbPortConfig.pxMbSlaveInfo); vQueueDelete(xMbPortConfig.xConnectQueue); vMBMasterPortTimerClose(); // Release resources for the event queue. @@ -922,13 +958,13 @@ int xMBMasterTCPPortWritePoll(MbSlaveInfo_t* pxInfo, const UCHAR * pucMBTCPFrame int xRes = (int)xMBTCPPortMasterCheckAlive(pxInfo, xTimeout); if ((xRes < 0) && (xRes != ERR_INPROGRESS)) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", is not writable, error: %d, errno %d"), + ESP_LOGE(TAG, MB_SLAVE_FMT(", is not writable, error: %d, errno %d"), pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno); return xRes; } xRes = send(pxInfo->xSockId, pucMBTCPFrame, usTCPLength, TCP_NODELAY); if (xRes < 0) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data error: %d, errno %d"), + ESP_LOGE(TAG, MB_SLAVE_FMT(", send data error: %d, errno %d"), pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno); } return xRes; @@ -938,36 +974,41 @@ BOOL xMBMasterTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength ) { BOOL bFrameSent = FALSE; - xMbPortConfig.ucCurSlaveIndex = ucMBMasterGetDestAddress(); - MbSlaveInfo_t* pxInfo = vMBTCPPortMasterGetCurrInfo(); - - // If socket active then send data - if (pxInfo->xSockId > -1) { - // Apply TID field to the frame before send - pucMBTCPFrame[MB_TCP_TID] = (UCHAR)(pxInfo->usTidCnt >> 8U); - pucMBTCPFrame[MB_TCP_TID + 1] = (UCHAR)(pxInfo->usTidCnt & 0xFF); - int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS); - if (xRes < 0) { - ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data failure, err(errno) = %d(%d)."), - pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno); - bFrameSent = FALSE; - pxInfo->xError = xRes; + USHORT ucCurSlaveIndex = ucMBMasterGetDestAddress(); + MbSlaveInfo_t* pxInfo = vMBTCPPortMasterFindSlaveInfo(ucCurSlaveIndex); + + // If the slave is correct and active then send data + // otherwise treat slave as died and skip + if (pxInfo != NULL) { + if (pxInfo->xSockId < 0) { + ESP_LOGD(TAG, MB_SLAVE_FMT(", send to died slave, error = %d"), + pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->xError); } else { - bFrameSent = TRUE; - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data successful: TID=0x%02x, %d (bytes), errno %d"), - pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usTidCnt, xRes, errno); - pxInfo->xError = 0; - pxInfo->usRcvPos = 0; - if (pxInfo->usTidCnt < (USHRT_MAX - 1)) { - pxInfo->usTidCnt++; + // Apply TID field to the frame before send + pucMBTCPFrame[MB_TCP_TID] = (UCHAR)(pxInfo->usTidCnt >> 8U); + pucMBTCPFrame[MB_TCP_TID + 1] = (UCHAR)(pxInfo->usTidCnt & 0xFF); + int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS); + if (xRes < 0) { + ESP_LOGE(TAG, MB_SLAVE_FMT(", send data failure, err(errno) = %d(%d)."), + pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno); + bFrameSent = FALSE; + pxInfo->xError = xRes; } else { - pxInfo->usTidCnt = (USHORT)(pxInfo->xIndex << 8U); + bFrameSent = TRUE; + ESP_LOGD(TAG, MB_SLAVE_FMT(", send data successful: TID=0x%02x, %d (bytes), errno %d"), + pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usTidCnt, xRes, errno); + pxInfo->xError = 0; + pxInfo->usRcvPos = 0; + if (pxInfo->usTidCnt < (USHRT_MAX - 1)) { + pxInfo->usTidCnt++; + } else { + pxInfo->usTidCnt = (USHORT)(pxInfo->xIndex << 8U); + } } + pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp(); } - pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp(); } else { - ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send to died slave, error = %d"), - pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->xError); + ESP_LOGD(TAG, "Send data to died slave, address = %d", ucCurSlaveIndex); } vMBMasterPortTimersRespondTimeoutEnable(); xMBMasterPortEventPost(EV_MASTER_FRAME_SENT); diff --git a/components/freemodbus/tcp_master/port/port_tcp_master.h b/components/freemodbus/tcp_master/port/port_tcp_master.h index c6a72fb2ee9b..ca5fe6029fc6 100644 --- a/components/freemodbus/tcp_master/port/port_tcp_master.h +++ b/components/freemodbus/tcp_master/port/port_tcp_master.h @@ -12,27 +12,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /* - * FreeModbus Libary: ESP32 TCP Port - * Copyright (C) 2006 Christian Walter - * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: port.h,v 1.2 2006/09/04 14:39:20 wolti Exp $ - */ +/* + * FreeModbus Libary: ESP32 TCP Port + * Copyright (C) 2006 Christian Walter + * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: port.h,v 1.2 2006/09/04 14:39:20 wolti Exp $ + */ #ifndef _PORT_TCP_SLAVE_H #define _PORT_TCP_SLAVE_H @@ -66,6 +74,7 @@ typedef struct { int xError; /*!< Socket error */ int xRcvErr; /*!< Socket receive error */ const char* pcIpAddr; /*!< TCP/UDP IP address */ + UCHAR ucSlaveAddr; /*!< Slave short address */ UCHAR* pucRcvBuf; /*!< Receive buffer pointer */ USHORT usRcvPos; /*!< Receive buffer position */ int pcPort; /*!< TCP/UDP port number */ @@ -76,28 +85,37 @@ typedef struct { } MbSlaveInfo_t; typedef struct { - TaskHandle_t xMbTcpTaskHandle; /*!< Master TCP/UDP handling task handle */ - QueueHandle_t xConnectQueue; /*!< Master connection queue */ - USHORT usPort; /*!< Master TCP/UDP port number */ - USHORT usMbSlaveInfoCount; /*!< Master count of connected slaves */ - USHORT ucCurSlaveIndex; /*!< Master current processing slave index */ - eMBPortIpVer eMbIpVer; /*!< Master IP version */ - eMBPortProto eMbProto; /*!< Master protocol type */ - void* pvNetIface; /*!< Master netif interface pointer */ - MbSlaveInfo_t** pxMbSlaveInfo; /*!< Master information structure for each connected slave */ + TaskHandle_t xMbTcpTaskHandle; /*!< Master TCP/UDP handling task handle */ + QueueHandle_t xConnectQueue; /*!< Master connection queue */ + USHORT usPort; /*!< Master TCP/UDP port number */ + USHORT usMbSlaveInfoCount; /*!< Master count of connected slaves */ + USHORT ucCurSlaveIndex; /*!< Master current processing slave index */ + eMBPortIpVer eMbIpVer; /*!< Master IP version */ + eMBPortProto eMbProto; /*!< Master protocol type */ + void* pvNetIface; /*!< Master netif interface pointer */ + MbSlaveInfo_t** pxMbSlaveInfo; /*!< Master information structure for each connected slave */ + MbSlaveInfo_t* pxMbSlaveCurrInfo; /*!< Master current slave information */ } MbPortConfig_t; +typedef struct { + USHORT usIndex; /*!< index of the address info */ + const char* pcIPAddr; /*!< represents the IP address of the slave */ + UCHAR ucSlaveAddr; /*!< slave unit ID (UID) field for MBAP frame */ +} MbSlaveAddrInfo_t; + /* ----------------------- Function prototypes ------------------------------*/ // The functions below are used by Modbus controller interface to configure Modbus port. /** * Registers slave IP address * + * @param usIndex index of element in the configuration * @param pcIpStr IP address to register + * @param ucSlaveAddress slave element index * * @return TRUE if address registered successfully, else FALSE */ -BOOL xMBTCPPortMasterAddSlaveIp(const CHAR* pcIpStr); +BOOL xMBTCPPortMasterAddSlaveIp(const USHORT usIndex, const CHAR* pcIpStr, UCHAR ucSlaveAddress); /** * Keeps FSM event handle and mask then wait for Master stack to start @@ -121,13 +139,6 @@ BOOL xMBTCPPortMasterWaitEvent(EventGroupHandle_t xEventHandle, EventBits_t xEve */ void vMBTCPPortMasterSetNetOpt(void* pvNetIf, eMBPortIpVer xIpVersion, eMBPortProto xProto); -/** - * Resume TCP/UDP Master processing task - * - * @return None - */ -void vMBTCPPortMasterTaskStart(void); - #ifdef __cplusplus PR_END_EXTERN_C #endif diff --git a/components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.c b/components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.c index e02a24a064e9..29b8678d8c72 100644 --- a/components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.c +++ b/components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.c @@ -32,6 +32,7 @@ // Shared pointer to interface structure static mb_slave_interface_t* mbs_interface_ptr = NULL; +static const char *TAG = "MB_CONTROLLER_SLAVE"; // Modbus task function static void modbus_tcp_slave_task(void *pvParameters) @@ -87,7 +88,6 @@ static esp_err_t mbc_tcp_slave_start(void) eMBPortProto proto = (mbs_opts->mbs_comm.ip_mode == MB_MODE_TCP) ? MB_PROTO_TCP : MB_PROTO_UDP; eMBPortIpVer ip_ver = (mbs_opts->mbs_comm.ip_addr_type == MB_IPV4) ? MB_PORT_IPV4 : MB_PORT_IPV6; vMBTCPPortSlaveSetNetOpt(mbs_opts->mbs_comm.ip_netif_ptr, ip_ver, proto, (char*)mbs_opts->mbs_comm.ip_addr); - vMBTCPPortSlaveStartServerTask(); status = eMBEnable(); MB_SLAVE_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE, @@ -118,7 +118,7 @@ static esp_err_t mbc_tcp_slave_destroy(void) (void)vQueueDelete(mbs_opts->mbs_notification_queue_handle); (void)vEventGroupDelete(mbs_opts->mbs_event_group); (void)vMBTCPPortClose(); - + mbs_interface_ptr = NULL; vMBPortSetMode((UCHAR)MB_PORT_INACTIVE); return ESP_OK; } diff --git a/components/freemodbus/tcp_slave/port/port_tcp_slave.c b/components/freemodbus/tcp_slave/port/port_tcp_slave.c index 50e75637fa41..9a843214fcdd 100644 --- a/components/freemodbus/tcp_slave/port/port_tcp_slave.c +++ b/components/freemodbus/tcp_slave/port/port_tcp_slave.c @@ -13,26 +13,34 @@ * limitations under the License. */ /* - * FreeModbus Libary: ESP32 TCP Port - * Copyright (C) 2006 Christian Walter - * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: port.h,v 1.2 2006/09/04 14:39:20 wolti Exp $ - */ + * FreeModbus Libary: ESP32 TCP Port + * Copyright (C) 2006 Christian Walter + * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: port.c,v 1.2 2006/09/04 14:39:20 wolti Exp $ + */ /* ----------------------- System includes ----------------------------------*/ #include @@ -60,13 +68,13 @@ /* ----------------------- Defines -----------------------------------------*/ #define MB_TCP_DISCONNECT_TIMEOUT ( CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000000 ) // disconnect timeout in uS #define MB_TCP_RESP_TIMEOUT_MS ( MB_MASTER_TIMEOUT_MS_RESPOND - 2 ) // slave response time limit -#define MB_TCP_SLAVE_PORT_TAG "MB_TCP_SLAVE_PORT" #define MB_TCP_NET_LISTEN_BACKLOG ( SOMAXCONN ) /* ----------------------- Prototypes ---------------------------------------*/ void vMBPortEventClose( void ); /* ----------------------- Static variables ---------------------------------*/ +static const char *TAG = "MB_TCP_SLAVE_PORT"; static int xListenSock = -1; static MbSlavePortConfig_t xConfig = { 0 }; @@ -128,14 +136,14 @@ xMBTCPPortInit( USHORT usTCPPort ) xConfig.pxMbClientInfo = calloc(MB_TCP_PORT_MAX_CONN + 1, sizeof(MbClientInfo_t*)); if (!xConfig.pxMbClientInfo) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "TCP client info allocation failure."); + ESP_LOGE(TAG, "TCP client info allocation failure."); return FALSE; } for(int idx = 0; idx < MB_TCP_PORT_MAX_CONN; xConfig.pxMbClientInfo[idx] = NULL, idx++); xConfig.xRespQueueHandle = xMBTCPPortRespQueueCreate(); if (!xConfig.xRespQueueHandle) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Response queue allocation failure."); + ESP_LOGE(TAG, "Response queue allocation failure."); return FALSE; } @@ -156,10 +164,10 @@ xMBTCPPortInit( USHORT usTCPPort ) vTaskSuspend(xConfig.xMbTcpTaskHandle); if (xErr != pdTRUE) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Server task creation failure."); + ESP_LOGE(TAG, "Server task creation failure."); vTaskDelete(xConfig.xMbTcpTaskHandle); } else { - ESP_LOGI(MB_TCP_SLAVE_PORT_TAG, "Protocol stack initialized."); + ESP_LOGI(TAG, "Protocol stack initialized."); bOkay = TRUE; } return bOkay; @@ -174,11 +182,6 @@ void vMBTCPPortSlaveSetNetOpt(void* pvNetIf, eMBPortIpVer xIpVersion, eMBPortPro xConfig.pcBindAddr = pcBindAddrStr; } -void vMBTCPPortSlaveStartServerTask(void) -{ - vTaskResume(xConfig.xMbTcpTaskHandle); -} - static int xMBTCPPortAcceptConnection(int xListenSockId, char** pcIPAddr) { MB_PORT_CHECK(pcIPAddr, -1, "Wrong IP address pointer."); @@ -194,7 +197,7 @@ static int xMBTCPPortAcceptConnection(int xListenSockId, char** pcIPAddr) // Accept new socket connection if not active xSockId = accept(xListenSockId, (struct sockaddr *)&xSrcAddr, &xSize); if (xSockId < 0) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Unable to accept connection: errno=%d", errno); + ESP_LOGE(TAG, "Unable to accept connection: errno=%d", errno); close(xSockId); } else { // Get the sender's ip address as string @@ -206,7 +209,7 @@ static int xMBTCPPortAcceptConnection(int xListenSockId, char** pcIPAddr) inet6_ntoa_r(((struct sockaddr_in6 *)&xSrcAddr)->sin6_addr, cAddrStr, sizeof(cAddrStr) - 1); } #endif - ESP_LOGI(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d), accept client connection from address: %s", xSockId, cAddrStr); + ESP_LOGI(TAG, "Socket (#%d), accept client connection from address: %s", xSockId, cAddrStr); pcStr = calloc(1, strlen(cAddrStr) + 1); if (pcStr && pcIPAddr) { memcpy(pcStr, cAddrStr, strlen(cAddrStr)); @@ -222,11 +225,11 @@ static BOOL xMBTCPPortCloseConnection(MbClientInfo_t* pxInfo) MB_PORT_CHECK(pxInfo, FALSE, "Client info is NULL."); if (pxInfo->xSockId == -1) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Wrong socket info or disconnected socket: %d.", pxInfo->xSockId); + ESP_LOGE(TAG, "Wrong socket info or disconnected socket: %d.", pxInfo->xSockId); return FALSE; } if (shutdown(pxInfo->xSockId, SHUT_RDWR) == -1) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d), shutdown failed: errno %d", pxInfo->xSockId, errno); + ESP_LOGE(TAG, "Socket (#%d), shutdown failed: errno %d", pxInfo->xSockId, errno); } close(pxInfo->xSockId); pxInfo->xSockId = -1; @@ -263,7 +266,7 @@ static int xMBTCPPortRxPoll(MbClientInfo_t* pxClientInfo, ULONG xTimeoutMs) } else if (xRet == 0) { // timeout occurred if ((xStartTimeStamp + xTimeoutMs * 1000) > xMBTCPGetTimeStamp()) { - ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d) Read timeout.", pxClientInfo->xSockId); + ESP_LOGD(TAG, "Socket (#%d) Read timeout.", pxClientInfo->xSockId); xRet = ERR_TIMEOUT; break; } @@ -278,12 +281,12 @@ static int xMBTCPPortRxPoll(MbClientInfo_t* pxClientInfo, ULONG xTimeoutMs) pxClientInfo->usTCPFrameBytesLeft, MSG_DONTWAIT); if (xLength < 0) { // If an error occurred during receiving - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Receive failed: length=%d, errno=%d", xLength, errno); + ESP_LOGE(TAG, "Receive failed: length=%d, errno=%d", xLength, errno); xRet = (err_t)xLength; break; } else if (xLength == 0) { // Socket connection closed - ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), connection closed.", + ESP_LOGD(TAG, "Socket (#%d)(%s), connection closed.", pxClientInfo->xSockId, pxClientInfo->pcIpAddr); xRet = ERR_CLSD; break; @@ -301,14 +304,14 @@ static int xMBTCPPortRxPoll(MbClientInfo_t* pxClientInfo, ULONG xTimeoutMs) pxClientInfo->usTCPFrameBytesLeft = xLength + MB_TCP_UID - pxClientInfo->usTCPBufPos; } else if (pxClientInfo->usTCPBufPos == (MB_TCP_UID + xLength)) { #if MB_TCP_DEBUG - prvvMBTCPLogFrame(MB_TCP_SLAVE_PORT_TAG, (UCHAR*)&pxClientInfo->pucTCPBuf[0], pxClientInfo->usTCPBufPos); + prvvMBTCPLogFrame(TAG, (UCHAR*)&pxClientInfo->pucTCPBuf[0], pxClientInfo->usTCPBufPos); #endif // Copy TID field from incoming packet pxClientInfo->usTidCnt = MB_TCP_GET_FIELD(pxClientInfo->pucTCPBuf, MB_TCP_TID); xRet = pxClientInfo->usTCPBufPos; break; } else if ((pxClientInfo->usTCPBufPos + xLength) >= MB_TCP_BUF_SIZE) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Incorrect buffer received (%u) bytes.", xLength); + ESP_LOGE(TAG, "Incorrect buffer received (%u) bytes.", xLength); // This should not happen. We can't deal with such a client and // drop the connection for security reasons. xRet = ERR_BUF; @@ -393,7 +396,7 @@ vMBTCPPortBindAddr(const CHAR* pcBindIp) { if (listen(xListenSockFd, MB_TCP_NET_LISTEN_BACKLOG) != 0) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Error occurred during listen: errno=%d", errno); + ESP_LOGE(TAG, "Error occurred during listen: errno=%d", errno); close(xListenSockFd); xListenSockFd = -1; continue; @@ -401,7 +404,7 @@ vMBTCPPortBindAddr(const CHAR* pcBindIp) } // Bind was successful pcStr = (pxCurAddr->ai_canonname == NULL) ? (CHAR*)"\0" : pxCurAddr->ai_canonname; - ESP_LOGI(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d), listener %s on port: %d, errno=%d", + ESP_LOGI(TAG, "Socket (#%d), listener %s on port: %d, errno=%d", xListenSockFd, pcStr, xConfig.usPort, errno); break; } @@ -467,11 +470,11 @@ static void vMBTCPPortServerTask(void *pvParameters) xErr = select(xMaxSd + 1 , &xReadSet , NULL , NULL , NULL); if ((xErr < 0) && (errno != EINTR)) { // error occurred during wait for read - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "select() errno = %d.", errno); + ESP_LOGE(TAG, "select() errno = %d.", errno); continue; } else if (xErr == 0) { // If timeout happened, something is wrong - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "select() timeout, errno = %d.", errno); + ESP_LOGE(TAG, "select() timeout, errno = %d.", errno); } // If something happened on the master socket, then its an incoming connection. @@ -487,21 +490,21 @@ static void vMBTCPPortServerTask(void *pvParameters) // if request for new connection but no space left if (pxClientInfo != NULL) { if (xConfig.pxMbClientInfo[MB_TCP_PORT_MAX_CONN] == NULL) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Fail to accept connection %d, only %d connections supported.", i + 1, MB_TCP_PORT_MAX_CONN); + ESP_LOGE(TAG, "Fail to accept connection %d, only %d connections supported.", i + 1, MB_TCP_PORT_MAX_CONN); } xConfig.pxMbClientInfo[MB_TCP_PORT_MAX_CONN] = pxClientInfo; // set last connection info } else { // allocate memory for new client info pxClientInfo = calloc(1, sizeof(MbClientInfo_t)); if (!pxClientInfo) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Client info allocation fail."); + ESP_LOGE(TAG, "Client info allocation fail."); vMBTCPPortFreeClientInfo(pxClientInfo); pxClientInfo = NULL; } else { // Accept new client connection pxClientInfo->xSockId = xMBTCPPortAcceptConnection(xListenSock, &pcClientIp); if (pxClientInfo->xSockId < 0) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Fail to accept connection for client %d.", (xConfig.usClientCount - 1)); + ESP_LOGE(TAG, "Fail to accept connection for client %d.", (xConfig.usClientCount - 1)); // Accept connection fail, then free client info and continue polling. vMBTCPPortFreeClientInfo(pxClientInfo); pxClientInfo = NULL; @@ -509,7 +512,7 @@ static void vMBTCPPortServerTask(void *pvParameters) } pxClientInfo->pucTCPBuf = calloc(MB_TCP_BUF_SIZE, sizeof(UCHAR)); if (!pxClientInfo->pucTCPBuf) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Fail to allocate buffer for client %d.", (xConfig.usClientCount - 1)); + ESP_LOGE(TAG, "Fail to allocate buffer for client %d.", (xConfig.usClientCount - 1)); vMBTCPPortFreeClientInfo(pxClientInfo); pxClientInfo = NULL; continue; @@ -543,17 +546,17 @@ static void vMBTCPPortServerTask(void *pvParameters) switch(xErr) { case ERR_TIMEOUT: - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), data receive timeout, time[us]: %d, close active connection.", + ESP_LOGE(TAG, "Socket (#%d)(%s), data receive timeout, time[us]: %d, close active connection.", pxClientInfo->xSockId, pxClientInfo->pcIpAddr, (int)(xTimeStamp - pxClientInfo->xRecvTimeStamp)); break; case ERR_CLSD: - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), connection closed by peer.", + ESP_LOGE(TAG, "Socket (#%d)(%s), connection closed by peer.", pxClientInfo->xSockId, pxClientInfo->pcIpAddr); break; case ERR_BUF: default: - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), read data error: %d", + ESP_LOGE(TAG, "Socket (#%d)(%s), read data error: %d", pxClientInfo->xSockId, pxClientInfo->pcIpAddr, xErr); break; } @@ -578,26 +581,26 @@ static void vMBTCPPortServerTask(void *pvParameters) // Complete frame received, inform state machine to process frame xMBPortEventPost(EV_FRAME_RECEIVED); - ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), get packet TID=0x%X, %d bytes.", + ESP_LOGD(TAG, "Socket (#%d)(%s), get packet TID=0x%X, %d bytes.", pxClientInfo->xSockId, pxClientInfo->pcIpAddr, pxClientInfo->usTidCnt, xErr); // Wait while response is not processed by stack by timeout UCHAR* pucSentBuffer = vxMBTCPPortRespQueueRecv(xConfig.xRespQueueHandle); if (pucSentBuffer == NULL) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Response time exceeds configured %d [ms], ignore packet.", + ESP_LOGE(TAG, "Response time exceeds configured %d [ms], ignore packet.", MB_TCP_RESP_TIMEOUT_MS); } else { USHORT usSentTid = MB_TCP_GET_FIELD(pucSentBuffer, MB_TCP_TID); if (usSentTid != pxClientInfo->usTidCnt) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Sent TID(%x) != Recv TID(%x), ignore packet.", + ESP_LOGE(TAG, "Sent TID(%x) != Recv TID(%x), ignore packet.", usSentTid, pxClientInfo->usTidCnt); } } // Get time stamp of last data update pxClientInfo->xSendTimeStamp = xMBTCPGetTimeStamp(); - ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Client %d, Socket(#%d), processing time = %d (us).", + ESP_LOGD(TAG, "Client %d, Socket(#%d), processing time = %d (us).", pxClientInfo->xIndex, pxClientInfo->xSockId, (int)(pxClientInfo->xSendTimeStamp - pxClientInfo->xRecvTimeStamp)); } @@ -606,7 +609,7 @@ static void vMBTCPPortServerTask(void *pvParameters) // client is not ready to be read int64_t xTime = xMBTCPGetTimeStamp() - pxClientInfo->xRecvTimeStamp; if (xTime > MB_TCP_DISCONNECT_TIMEOUT) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Client %d, Socket(#%d) do not answer for %d (us). Drop connection...", + ESP_LOGE(TAG, "Client %d, Socket(#%d) do not answer for %d (us). Drop connection...", pxClientInfo->xIndex, pxClientInfo->xSockId, (int)(xTime)); xMBTCPPortCloseConnection(pxClientInfo); @@ -615,7 +618,7 @@ static void vMBTCPPortServerTask(void *pvParameters) xConfig.pxMbClientInfo[i] = NULL; } } else { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Client %d is disconnected.", i); + ESP_LOGE(TAG, "Client %d is disconnected.", i); } } } // if ((pxClientInfo != NULL) @@ -634,6 +637,11 @@ vMBTCPPortClose( ) vTaskDelete(xConfig.xMbTcpTaskHandle); } +void vMBTCPPortEnable( void ) +{ + vTaskResume(xConfig.xMbTcpTaskHandle); +} + void vMBTCPPortDisable( void ) { @@ -646,6 +654,7 @@ vMBTCPPortDisable( void ) xConfig.pxMbClientInfo[i] = NULL; } } + free(xConfig.pxMbClientInfo); close(xListenSock); xListenSock = -1; vMBTCPPortRespQueueDelete(xConfig.xRespQueueHandle); @@ -685,7 +694,7 @@ xMBTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength ) // Check if socket writable xErr = select(xConfig.pxCurClientInfo->xSockId + 1, NULL, &xWriteSet, &xErrorSet, &xTimeVal); if ((xErr == -1) || FD_ISSET(xConfig.pxCurClientInfo->xSockId, &xErrorSet)) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket(#%d) , send select() error = %d.", + ESP_LOGE(TAG, "Socket(#%d) , send select() error = %d.", xConfig.pxCurClientInfo->xSockId, errno); return FALSE; } @@ -697,7 +706,7 @@ xMBTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength ) // Write message into socket and disable Nagle's algorithm xErr = send(xConfig.pxCurClientInfo->xSockId, pucMBTCPFrame, usTCPLength, TCP_NODELAY); if (xErr < 0) { - ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket(#%d), fail to send data, errno = %d", + ESP_LOGE(TAG, "Socket(#%d), fail to send data, errno = %d", xConfig.pxCurClientInfo->xSockId, errno); xConfig.pxCurClientInfo->xError = xErr; } else { @@ -705,7 +714,7 @@ xMBTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength ) vxMBTCPPortRespQueueSend(xConfig.xRespQueueHandle, (void*)pucMBTCPFrame); } } else { - ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Port is not active. Release lock."); + ESP_LOGD(TAG, "Port is not active. Release lock."); vxMBTCPPortRespQueueSend(xConfig.xRespQueueHandle, (void*)pucMBTCPFrame); } return bFrameSent; diff --git a/components/freemodbus/tcp_slave/port/port_tcp_slave.h b/components/freemodbus/tcp_slave/port/port_tcp_slave.h index ffed7959b209..ae6a023b4500 100644 --- a/components/freemodbus/tcp_slave/port/port_tcp_slave.h +++ b/components/freemodbus/tcp_slave/port/port_tcp_slave.h @@ -12,27 +12,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /* - * FreeModbus Libary: ESP32 TCP Port - * Copyright (C) 2006 Christian Walter - * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: port.h,v 1.2 2006/09/04 14:39:20 wolti Exp $ - */ +/* + * FreeModbus Libary: ESP32 TCP Port + * Copyright (C) 2006 Christian Walter + * Parts of crt0.S Copyright (c) 1995, 1996, 1998 Cygnus Support + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * IF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * File: $Id: port.h,v 1.2 2006/09/04 14:39:20 wolti Exp $ + */ #ifndef _PORT_TCP_SLAVE_H #define _PORT_TCP_SLAVE_H @@ -100,13 +108,6 @@ typedef struct { */ void vMBTCPPortSlaveSetNetOpt(void* pvNetIf, eMBPortIpVer xIpVersion, eMBPortProto xProto, CHAR* pcBindAddr); -/** - * Resume TCP Slave processing task - * - * @return None - */ -void vMBTCPPortSlaveStartServerTask(void); - #ifdef __cplusplus PR_END_EXTERN_C #endif diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index 4ab86e3a47ae..cf335e9b5e7d 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -42,7 +42,7 @@ else() # RISC-V port/riscv .) - set(required_components esp_timer) + set(required_components app_trace esp_timer) endif() list(APPEND srcs @@ -61,7 +61,7 @@ if(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY) list(APPEND srcs "port/xtensa/xtensa_loadstore_handler.S") endif() -# app_trace is required by FreeRTOS headers only when CONFIG_SYSVIEW_ENABLE=y, +# app_trace is required by FreeRTOS headers only when CONFIG_APPTRACE_SV_ENABLE=y, # but requirements can't depend on config options, so always require it. idf_component_register(SRCS "${srcs}" INCLUDE_DIRS ${include_dirs} diff --git a/components/freertos/include/freertos/projdefs.h b/components/freertos/include/freertos/projdefs.h index ce647fb6fb19..61cb7ebe54bd 100644 --- a/components/freertos/include/freertos/projdefs.h +++ b/components/freertos/include/freertos/projdefs.h @@ -42,7 +42,7 @@ definition here is not suitable for your application. */ #endif #ifndef pdTICKS_TO_MS - #define pdTICKS_TO_MS( xTicks ) ( ( uint32_t ) ( xTicks ) * 1000 / configTICK_RATE_HZ ) + #define pdTICKS_TO_MS( xTicks ) ( ( TickType_t ) ( ( uint64_t ) ( xTicks ) * 1000 / configTICK_RATE_HZ ) ) #endif diff --git a/components/freertos/include/freertos/queue.h b/components/freertos/include/freertos/queue.h index 8c35465316e6..991efc8cf3ec 100644 --- a/components/freertos/include/freertos/queue.h +++ b/components/freertos/include/freertos/queue.h @@ -1342,7 +1342,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * or semaphores contained in the set is in a state where a queue read or * semaphore take operation would be successful. * - * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * Note 1: See the documentation on http://www.FreeRTOS.org/RTOS-queue-sets.html * for reasons why queue sets are very rarely needed in practice as there are * simpler methods of blocking on multiple objects. * @@ -1431,7 +1431,7 @@ BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueS * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * - * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * Note 1: See the documentation on http://www.FreeRTOS.org/RTOS-queue-sets.html * for reasons why queue sets are very rarely needed in practice as there are * simpler methods of blocking on multiple objects. * diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index f0f167d226f2..60d350533783 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -22,15 +22,13 @@ entries: tasks: prvIdleTask (default) tasks: prvAddNewTaskToReadyList (default) tasks: xTaskCreatePinnedToCore (default) + tasks: xTaskCreateStaticPinnedToCore (default) tasks: vTaskResume (default) tasks: vTaskStartScheduler (default) tasks: vTaskSuspendAll (default) tasks: uxTaskGetNumberOfTasks (default) - tasks: uxTaskGetSystemState (default) tasks: xTaskGetIdleTaskHandle (default) tasks: xTaskRemoveFromUnorderedEventList (default) - tasks: uxTaskGetTaskNumber (default) - tasks: vTaskSetTaskNumber (default) tasks: uxTaskPriorityGet (default) tasks: vTaskPrioritySet (default) tasks: vTaskSetThreadLocalStoragePointerAndDelCallback (default) @@ -49,11 +47,18 @@ entries: tasks: pxTaskGetStackStart (default) tasks: uxTaskGetStackHighWaterMark (default) tasks: vTaskEndScheduler (default) - tasks: vTaskList (default) tasks: vTaskMissedYield (default) tasks: vTaskSetThreadLocalStoragePointer (default) tasks: xTaskGetAffinity (default) tasks: xTaskGetIdleTaskHandleForCPU (default) + if FREERTOS_USE_TRACE_FACILITY = y: + tasks: uxTaskGetSystemState (default) + tasks: uxTaskGetTaskNumber (default) + tasks: vTaskSetTaskNumber (default) + if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: + tasks: vTaskList (default) + if FREERTOS_GENERATE_RUN_TIME_STATS = y: + tasks: vTaskGetRunTimeStats (default) timers: prvInsertTimerInActiveList (default) timers: prvCheckForValidListAndQueue (default) timers: prvInitialiseNewTimer (default) @@ -65,6 +70,7 @@ entries: timers: prvProcessReceivedCommands (default) timers: xTimerCreateTimerTask (default) timers: xTimerCreate (default) + timers: xTimerCreateStatic (default) timers: xTimerGenericCommand (default) timers: xTimerGetPeriod (default) timers: xTimerGetExpiryTime (default) @@ -72,8 +78,12 @@ entries: timers: pvTimerGetTimerID (default) timers: vTimerSetTimerID (default) timers: prvGetNextExpireTime (default) + if FREERTOS_USE_TRACE_FACILITY = y: + timers: uxTimerGetTimerNumber (default) + timers: vTimerSetTimerNumber (default) event_groups: prvTestWaitCondition (default) event_groups: xEventGroupCreate (default) + event_groups: xEventGroupCreateStatic (default) event_groups: xEventGroupWaitBits (default) event_groups: xEventGroupClearBits (default) event_groups: xEventGroupSetBits (default) @@ -92,30 +102,24 @@ entries: queue: xQueueGiveMutexRecursive (default) queue: xQueueTakeMutexRecursive (default) queue: uxQueueMessagesWaiting (default) - queue: uxQueueGetQueueNumber (default) - queue: vQueueSetQueueNumber (default) - queue: ucQueueGetQueueType (default) - queue: vQueueAddToRegistry (default) - queue: pcQueueGetName (default) - queue: vQueueUnregisterQueue (default) queue: vQueueDelete (default) queue: vQueueWaitForMessageRestricted (default) queue: xQueueCreateSet (default) queue: xQueueAddToSet (default) queue: xQueueRemoveFromSet (default) queue: xQueueSelectFromSet (default) + queue: xQueueGenericCreateStatic (default) + queue: xQueueCreateMutexStatic (default) + queue: xQueueCreateCountingSemaphoreStatic (default) + if FREERTOS_QUEUE_REGISTRY_SIZE > 0: + queue: pcQueueGetName (default) + queue: vQueueAddToRegistry (default) + queue: vQueueUnregisterQueue (default) + if FREERTOS_USE_TRACE_FACILITY = y: + queue: uxQueueGetQueueNumber (default) + queue: vQueueSetQueueNumber (default) + queue: ucQueueGetQueueType (default) port_common:main_task (default) port:esp_startup_start_app (default) if ESP_SYSTEM_SINGLE_CORE_MODE = n: port:esp_startup_start_app_other_cores (default) - -if FREERTOS_SUPPORT_STATIC_ALLOCATION = y && FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: - [mapping:freertos_static] - archive: libfreertos.a - entries: - queue:xQueueGenericCreateStatic (default) - queue: xQueueCreateCountingSemaphoreStatic (default) - tasks: xTaskCreateStaticPinnedToCore (default) - timers: xTimerCreateStatic (default) - event_groups: xEventGroupCreateStatic (default) - queue: xQueueCreateMutexStatic (default) diff --git a/components/freertos/port/port_common.c b/components/freertos/port/port_common.c index b80c82a1b028..7815ba59429d 100644 --- a/components/freertos/port/port_common.c +++ b/components/freertos/port/port_common.c @@ -26,6 +26,7 @@ #include "esp_log.h" #include "soc/dport_access.h" #include "sdkconfig.h" +#include "esp_freertos_hooks.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/spiram.h" @@ -85,13 +86,24 @@ void esp_startup_start_app_common(void) assert(res == pdTRUE); } +#if !CONFIG_FREERTOS_UNICORE +static volatile bool s_app_cpu_startup_done = false; +static bool s_app_cpu_startup_idle_hook_cb(void) +{ + s_app_cpu_startup_done = true; + return true; +} +#endif + static void main_task(void* args) { #if !CONFIG_FREERTOS_UNICORE - // Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack - while (port_xSchedulerRunning[1] == 0) { - ; - } + // Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack + esp_register_freertos_idle_hook_for_cpu(s_app_cpu_startup_idle_hook_cb, 1); + while (!s_app_cpu_startup_done) { + ; + } + esp_deregister_freertos_idle_hook_for_cpu(s_app_cpu_startup_idle_hook_cb, 1); #endif // [refactor-todo] check if there is a way to move the following block to esp_system startup diff --git a/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h b/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h index 53cd736083a8..cfae510049e2 100644 --- a/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/port/riscv/include/freertos/FreeRTOSConfig.h @@ -292,4 +292,14 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configCHECK_MUTEX_GIVEN_BY_OWNER 0 #endif -#endif /* FREERTOS_CONFIG_H */ +#ifndef __ASSEMBLER__ +#if CONFIG_APPTRACE_SV_ENABLE +#include "SEGGER_SYSVIEW_FreeRTOS.h" +extern int xPortSwitchFlag; +#define os_task_switch_is_pended(_cpu_) (xPortSwitchFlag) +#else +#define os_task_switch_is_pended(_cpu_) (false) +#endif +#endif + +#endif // FREERTOS_CONFIG_RISCV_H diff --git a/components/freertos/port/riscv/port.c b/components/freertos/port/riscv/port.c index 2f6786841a1e..ca78285a5fe6 100644 --- a/components/freertos/port/riscv/port.c +++ b/components/freertos/port/riscv/port.c @@ -161,7 +161,7 @@ void vPortSetupTimer(void) systimer_hal_enable_alarm_int(SYSTIMER_ALARM_0); } -void prvTaskExitError(void) +__attribute__((noreturn)) static void _prvTaskExitError(void) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it @@ -174,6 +174,18 @@ void prvTaskExitError(void) abort(); } +__attribute__((naked)) static void prvTaskExitError(void) +{ + asm volatile(".option push\n" \ + ".option norvc\n" \ + "nop\n" \ + ".option pop"); + /* Task entry's RA will point here. Shifting RA into prvTaskExitError is necessary + to make GDB backtrace ending inside that function. + Otherwise backtrace will end in the function laying just before prvTaskExitError in address space. */ + _prvTaskExitError(); +} + /* Clear current interrupt mask and set given mask */ void vPortClearInterruptMask(int mask) { @@ -282,7 +294,9 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC sp -= RV_STK_FRMSZ; RvExcFrame *frame = (RvExcFrame *)sp; memset(frame, 0, sizeof(*frame)); - frame->ra = (UBaseType_t)prvTaskExitError; + /* Shifting RA into prvTaskExitError is necessary to make GDB backtrace ending inside that function. + Otherwise backtrace will end in the function laying just before prvTaskExitError in address space. */ + frame->ra = (UBaseType_t)prvTaskExitError + 4/*size of the nop insruction at the beginning of prvTaskExitError*/; frame->mepc = (UBaseType_t)pxCode; frame->a0 = (UBaseType_t)pvParameters; frame->gp = (UBaseType_t)&__global_pointer$; @@ -345,6 +359,7 @@ void vPortYieldOtherCore(BaseType_t coreid) void vPortYieldFromISR( void ) { + traceISR_EXIT_TO_SCHEDULER(); uxSchedulerRunning = 1; xPortSwitchFlag = 1; } diff --git a/components/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h b/components/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h index 6ec72e52b45a..778098e0b09c 100644 --- a/components/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h @@ -342,17 +342,21 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configENABLE_TASK_SNAPSHOT 1 #endif -#if CONFIG_SYSVIEW_ENABLE -#ifndef __ASSEMBLER__ -#include "SEGGER_SYSVIEW_FreeRTOS.h" -#undef INLINE // to avoid redefinition -#endif /* def __ASSEMBLER__ */ -#endif - #if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER #define configCHECK_MUTEX_GIVEN_BY_OWNER 1 #else #define configCHECK_MUTEX_GIVEN_BY_OWNER 0 #endif -#endif /* FREERTOS_CONFIG_H */ +#ifndef __ASSEMBLER__ +#if CONFIG_APPTRACE_SV_ENABLE +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +extern uint32_t port_switch_flag[]; +#define os_task_switch_is_pended(_cpu_) (port_switch_flag[_cpu_]) +#else +#define os_task_switch_is_pended(_cpu_) (false) +#endif +#endif + +#endif // FREERTOS_CONFIG_XTENSA_H diff --git a/components/freertos/port/xtensa/include/freertos/portmacro.h b/components/freertos/port/xtensa/include/freertos/portmacro.h index 222a5ae80106..19473a721e6a 100644 --- a/components/freertos/port/xtensa/include/freertos/portmacro.h +++ b/components/freertos/port/xtensa/include/freertos/portmacro.h @@ -105,7 +105,7 @@ typedef unsigned portBASE_TYPE UBaseType_t; // Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. // They can be called from interrupts too. // WARNING: Only applies to current CPU. See notes above. -static inline unsigned portENTER_CRITICAL_NESTED(void) { +static inline unsigned __attribute__((always_inline)) portENTER_CRITICAL_NESTED(void) { unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); return state; diff --git a/components/freertos/stream_buffer.c b/components/freertos/stream_buffer.c index d5a21b087682..82c4549c87c4 100644 --- a/components/freertos/stream_buffer.c +++ b/components/freertos/stream_buffer.c @@ -153,7 +153,10 @@ typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */ UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ #endif - portMUX_TYPE xStreamBufferMux; //Mutex required due to SMP + #ifdef ESP_PLATFORM + /* Mutex required due to SMP. This field shall be the last one of the structure. */ + portMUX_TYPE xStreamBufferMux; + #endif // ESP_PLATFORM } StreamBuffer_t; /* @@ -214,6 +217,17 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, size_t xTriggerLevelBytes, uint8_t ucFlags ) PRIVILEGED_FUNCTION; +#ifdef ESP_PLATFORM +/** + * Called by xStreamBufferReset() to reset the members of the StreamBuffer, excluding + * its spinlock. + */ +static void prvResetStreamBufferFields( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) PRIVILEGED_FUNCTION; +#endif /*-----------------------------------------------------------*/ #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) @@ -423,11 +437,23 @@ BaseType_t xReturn = pdFAIL; { if( pxStreamBuffer->xTaskWaitingToSend == NULL ) { - prvInitialiseNewStreamBuffer( pxStreamBuffer, - pxStreamBuffer->pucBuffer, - pxStreamBuffer->xLength, - pxStreamBuffer->xTriggerLevelBytes, - pxStreamBuffer->ucFlags ); + #ifdef ESP_PLATFORM + /* As we just entered a critical section, we must NOT reset the spinlock field. + * Thus, call `prvResetStreamBufferFields` instead of `prvInitialiseNewStreamBuffer` + */ + prvResetStreamBufferFields( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags ); + + #else // ESP_PLATFORM + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags ); + #endif // ESP_PLATFORM xReturn = pdPASS; #if( configUSE_TRACE_FACILITY == 1 ) @@ -1241,6 +1267,43 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, vPortCPUInitializeMutex( &pxStreamBuffer->xStreamBufferMux ); } + +#ifdef ESP_PLATFORM + + /** The goal of this function is to (re)set all the fields of the given StreamBuffer, except + * its lock. + */ + static void prvResetStreamBufferFields( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) + { + #if ( configASSERT_DEFINED == 1 ) + { + /* The value written just has to be identifiable when looking at the + * memory. Don't use 0xA5 as that is the stack fill value and could + * result in confusion as to what is actually being observed. */ + const BaseType_t xWriteValue = 0x55; + configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer ); + } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ + #endif + + /* Do not include the spinlock in the part to reset! + * Thus, make sure the spinlock is the last field of the structure. */ + _Static_assert( offsetof(StreamBuffer_t, xStreamBufferMux) == sizeof( StreamBuffer_t ) - sizeof(portMUX_TYPE), + "xStreamBufferMux must be the last field of structure StreamBuffer_t" ); + const size_t erasable = sizeof( StreamBuffer_t ) - sizeof(portMUX_TYPE); + ( void ) memset( ( void * ) pxStreamBuffer, 0x00, erasable ); /*lint !e9087 memset() requires void *. */ + pxStreamBuffer->pucBuffer = pucBuffer; + pxStreamBuffer->xLength = xBufferSizeBytes; + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; + pxStreamBuffer->ucFlags = ucFlags; + } + +#endif // ESP_PLATFORM + + #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index dd0487958c45..17710c18500d 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -131,22 +131,10 @@ configIDLE_TASK_NAME in FreeRTOSConfig.h. */ /*-----------------------------------------------------------*/ - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - { \ - UBaseType_t uxTopPriority = uxTopReadyPriority; \ - \ - /* Find the highest priority queue that contains ready tasks. */ \ - while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ - { \ - configASSERT( uxTopPriority ); \ - --uxTopPriority; \ - } \ - \ - /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ - the same priority get an equal share of the processor time. */ \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB[xPortGetCoreID()], &( pxReadyTasksLists[ uxTopPriority ] ) ); \ - uxTopReadyPriority = uxTopPriority; \ - } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + /* SMP does not support optimized selection while single-core configuration + can choose whether or not optimized selection is used. Therefore, this SMP + selection function must work for single-core and SMP */ + #define taskSELECT_HIGHEST_PRIORITY_TASK() taskSelectHighestPriorityTaskSMP() /*-----------------------------------------------------------*/ @@ -1421,7 +1409,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode configASSERT( pxPreviousWakeTime ); configASSERT( ( xTimeIncrement > 0U ) ); - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED ); taskENTER_CRITICAL( &xTaskQueueMutex ); { @@ -1505,7 +1493,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode /* A delay time of zero just forces a reschedule. */ if( xTicksToDelay > ( TickType_t ) 0U ) { - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED ); taskENTER_CRITICAL( &xTaskQueueMutex ); { traceTASK_DELAY(); @@ -2026,7 +2014,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) { /* Has the task already been resumed from within an ISR? */ - if( listIS_CONTAINED_WITHIN( &xPendingReadyList[xPortGetCoreID()], &( pxTCB->xEventListItem )) || + if( listIS_CONTAINED_WITHIN( &xPendingReadyList[xPortGetCoreID()], &( pxTCB->xEventListItem )) == pdFALSE && listIS_CONTAINED_WITHIN( &xPendingReadyList[!xPortGetCoreID()], &( pxTCB->xEventListItem )) == pdFALSE ) { /* Is it in the suspended list because it is in the Suspended @@ -2434,9 +2422,9 @@ TCB_t *pxTCB = NULL; BaseType_t xAlreadyYielded = pdFALSE; TickType_t xTicksToNextUnblockTime; - /* If uxSchedulerSuspended[xPortGetCoreID()] is zero then this function does not match a + /* If scheduler state is `taskSCHEDULER_RUNNING` then this function does not match a previous call to taskENTER_CRITICAL( &xTaskQueueMutex ). */ - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING ); /* It is possible that an ISR caused a task to be removed from an event list while the scheduler was suspended. If this was the case then the @@ -2874,7 +2862,7 @@ BaseType_t xYieldRequired = pdFALSE; /* Must not be called with the scheduler suspended as the implementation relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */ - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED ); /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occuring when the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */ @@ -3245,11 +3233,98 @@ BaseType_t xSwitchRequired = pdFALSE; #endif /* configUSE_APPLICATION_TASK_TAG */ /*-----------------------------------------------------------*/ +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) +static void taskSelectHighestPriorityTaskSMP( void ) +{ + /* This function is called from a critical section. So some optimizations are made */ + BaseType_t uxCurPriority; + BaseType_t xTaskScheduled = pdFALSE; + BaseType_t xNewTopPrioritySet = pdFALSE; + BaseType_t xCoreID = xPortGetCoreID(); /* Optimization: Read once */ + + /* Search for tasks, starting form the highest ready priority. If nothing is + * found, we eventually default to the IDLE tasks at priority 0 */ + for ( uxCurPriority = uxTopReadyPriority; uxCurPriority >= 0 && xTaskScheduled == pdFALSE; uxCurPriority-- ) + { + /* Check if current priority has one or more ready tasks. Skip if none */ + if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxCurPriority ] ) ) ) + { + continue; + } + + /* Save a copy of highest priority that has a ready state task */ + if( xNewTopPrioritySet == pdFALSE ) + { + xNewTopPrioritySet = pdTRUE; + uxTopReadyPriority = uxCurPriority; + } + + /* We now search this priority's ready task list for a runnable task. + * We always start searching from the head of the list, so we reset + * pxIndex to point to the tail so that we start walking the list from + * the first item */ + pxReadyTasksLists[ uxCurPriority ].pxIndex = ( ListItem_t * ) &( pxReadyTasksLists[ uxCurPriority ].xListEnd ); + + /* Get the first item on the list */ + TCB_t * pxTCBCur; + TCB_t * pxTCBFirst; + listGET_OWNER_OF_NEXT_ENTRY( pxTCBCur, &( pxReadyTasksLists[ uxCurPriority ] ) ); + pxTCBFirst = pxTCBCur; + do + { + /* Check if the current task is currently being executed. However, if + * it's being executed by the current core, we can still schedule it. + * Todo: Each task can store a xTaskRunState, instead of needing to + * check each core */ + UBaseType_t ux; + for( ux = 0; ux < ( UBaseType_t )portNUM_PROCESSORS; ux++ ) + { + if ( ux == xCoreID ) + { + continue; + } + else if ( pxCurrentTCB[ux] == pxTCBCur ) + { + /* Current task is already being executed. Get the next task */ + goto get_next_task; + } + } + + /* Check if the current task has a compatible affinity */ + if ( ( pxTCBCur->xCoreID != xCoreID ) && ( pxTCBCur->xCoreID != tskNO_AFFINITY ) ) + { + goto get_next_task; + } + + /* The current task is runnable. Schedule it */ + pxCurrentTCB[ xCoreID ] = pxTCBCur; + xTaskScheduled = pdTRUE; + + /* Move the current tasks list item to the back of the list in order + * to implement best effort round robin. To do this, we need to reset + * the pxIndex to point to the tail again. */ + pxReadyTasksLists[ uxCurPriority ].pxIndex = ( ListItem_t * ) &( pxReadyTasksLists[ uxCurPriority ].xListEnd ); + uxListRemove( &( pxTCBCur->xStateListItem ) ); + vListInsertEnd( &( pxReadyTasksLists[ uxCurPriority ] ), &( pxTCBCur->xStateListItem ) ); + break; + +get_next_task: + /* The current task cannot be scheduled. Get the next task in the list */ + listGET_OWNER_OF_NEXT_ENTRY( pxTCBCur, &( pxReadyTasksLists[ uxCurPriority ] ) ); + } while( pxTCBCur != pxTCBFirst); /* Check to see if we've walked the entire list */ + } + + assert( xTaskScheduled == pdTRUE ); /* At this point, a task MUST have been scheduled */ +} +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + void vTaskSwitchContext( void ) { - //Theoretically, this is only called from either the tick interrupt or the crosscore interrupt, so disabling - //interrupts shouldn't be necessary anymore. Still, for safety we'll leave it in for now. - int irqstate=portENTER_CRITICAL_NESTED(); + /* vTaskSwitchContext is called either from: + * - ISR dispatcher when return from an ISR (interrupts will already be disabled) + * - vTaskSuspend() which is not in a critical section + * Therefore, we enter a critical section ISR version to ensure safety */ + taskENTER_CRITICAL_ISR( &xTaskQueueMutex ); if( uxSchedulerSuspended[ xPortGetCoreID() ] != ( UBaseType_t ) pdFALSE ) { @@ -3278,7 +3353,6 @@ void vTaskSwitchContext( void ) overflows. The guard against negative values is to protect against suspect run time stat counter implementations - which are provided by the application, not the kernel. */ - taskENTER_CRITICAL_ISR(&xTaskQueueMutex); if( ulTotalRunTime > ulTaskSwitchedInTime[ xPortGetCoreID() ] ) { pxCurrentTCB[ xPortGetCoreID() ]->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime[ xPortGetCoreID() ] ); @@ -3287,7 +3361,6 @@ void vTaskSwitchContext( void ) { mtCOVERAGE_TEST_MARKER(); } - taskEXIT_CRITICAL_ISR(&xTaskQueueMutex); ulTaskSwitchedInTime[ xPortGetCoreID() ] = ulTotalRunTime; } #endif /* configGENERATE_RUN_TIME_STATS */ @@ -3296,123 +3369,17 @@ void vTaskSwitchContext( void ) taskFIRST_CHECK_FOR_STACK_OVERFLOW(); taskSECOND_CHECK_FOR_STACK_OVERFLOW(); - /* Select a new task to run */ - - /* - We cannot do taskENTER_CRITICAL_ISR(&xTaskQueueMutex); here because it saves the interrupt context to the task tcb, and we're - swapping that out here. Instead, we're going to do the work here ourselves. Because interrupts are already disabled, we only - need to acquire the mutex. - */ - vPortCPUAcquireMutex( &xTaskQueueMutex ); - - #if !configUSE_PORT_OPTIMISED_TASK_SELECTION - unsigned portBASE_TYPE foundNonExecutingWaiter = pdFALSE, ableToSchedule = pdFALSE, resetListHead; - unsigned portBASE_TYPE holdTop=pdFALSE; - tskTCB * pxTCB; - - portBASE_TYPE uxDynamicTopReady = uxTopReadyPriority; - /* - * ToDo: This scheduler doesn't correctly implement the round-robin scheduling as done in the single-core - * FreeRTOS stack when multiple tasks have the same priority and are all ready; it just keeps grabbing the - * first one. ToDo: fix this. - * (Is this still true? if any, there's the issue with one core skipping over the processes for the other - * core, potentially not giving the skipped-over processes any time.) - */ - - while ( ableToSchedule == pdFALSE && uxDynamicTopReady >= 0 ) - { - resetListHead = pdFALSE; - // Nothing to do for empty lists - if (!listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxDynamicTopReady ] ) )) { - - ableToSchedule = pdFALSE; - tskTCB * pxRefTCB; - - /* Remember the current list item so that we - can detect if all items have been inspected. - Once this happens, we move on to a lower - priority list (assuming nothing is suitable - for scheduling). Note: This can return NULL if - the list index is at the listItem */ - pxRefTCB = pxReadyTasksLists[ uxDynamicTopReady ].pxIndex->pvOwner; - - if ((void*)pxReadyTasksLists[ uxDynamicTopReady ].pxIndex==(void*)&pxReadyTasksLists[ uxDynamicTopReady ].xListEnd) { - //pxIndex points to the list end marker. Skip that and just get the next item. - listGET_OWNER_OF_NEXT_ENTRY( pxRefTCB, &( pxReadyTasksLists[ uxDynamicTopReady ] ) ); - } - - do { - listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ uxDynamicTopReady ] ) ); - /* Find out if the next task in the list is - already being executed by another core */ - foundNonExecutingWaiter = pdTRUE; - portBASE_TYPE i = 0; - for ( i=0; ixCoreID == tskNO_AFFINITY) { - pxCurrentTCB[xPortGetCoreID()] = pxTCB; - ableToSchedule = pdTRUE; - } else if (pxTCB->xCoreID == xPortGetCoreID()) { - pxCurrentTCB[xPortGetCoreID()] = pxTCB; - ableToSchedule = pdTRUE; - } else { - ableToSchedule = pdFALSE; - holdTop=pdTRUE; //keep this as the top prio, for the other CPU - } - } else { - ableToSchedule = pdFALSE; - } - - if (ableToSchedule == pdFALSE) { - resetListHead = pdTRUE; - } else if ((ableToSchedule == pdTRUE) && (resetListHead == pdTRUE)) { - tskTCB * pxResetTCB; - do { - listGET_OWNER_OF_NEXT_ENTRY( pxResetTCB, &( pxReadyTasksLists[ uxDynamicTopReady ] ) ); - } while(pxResetTCB != pxRefTCB); - } - } while ((ableToSchedule == pdFALSE) && (pxTCB != pxRefTCB)); - } else { - if (!holdTop) --uxTopReadyPriority; - } - --uxDynamicTopReady; - } - - #else - //For Unicore targets we can keep the current FreeRTOS O(1) - //Scheduler. I hope to optimize better the scheduler for - //Multicore settings -- This will involve to create a per - //affinity ready task list which will impact hugely on - //tasks module - taskSELECT_HIGHEST_PRIORITY_TASK(); - #endif - + /* Select a new task to run using either the generic C or port + optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ traceTASK_SWITCHED_IN(); - xSwitchingContext[ xPortGetCoreID() ] = pdFALSE; - - //Exit critical region manually as well: release the mux now, interrupts will be re-enabled when we - //exit the function. - vPortCPUReleaseMutex( &xTaskQueueMutex ); + xSwitchingContext[ xPortGetCoreID() ] = pdFALSE; #if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK vPortSetStackWatchpoint(pxCurrentTCB[xPortGetCoreID()]->pxStack); #endif - } - portEXIT_CRITICAL_NESTED(irqstate); + taskEXIT_CRITICAL_ISR( &xTaskQueueMutex ); } /*-----------------------------------------------------------*/ @@ -4511,7 +4478,9 @@ TCB_t *pxTCB; BaseType_t xTaskGetSchedulerState( void ) { BaseType_t xReturn; + unsigned state; + state = portENTER_CRITICAL_NESTED(); if( xSchedulerRunning == pdFALSE ) { xReturn = taskSCHEDULER_NOT_STARTED; @@ -4527,6 +4496,7 @@ TCB_t *pxTCB; xReturn = taskSCHEDULER_SUSPENDED; } } + portEXIT_CRITICAL_NESTED(state); return xReturn; } diff --git a/components/freertos/test/test_freertos_scheduling_round_robin.c b/components/freertos/test/test_freertos_scheduling_round_robin.c new file mode 100644 index 000000000000..27b9ea13632e --- /dev/null +++ b/components/freertos/test/test_freertos_scheduling_round_robin.c @@ -0,0 +1,177 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_rom_sys.h" +#include "hal/interrupt_controller_hal.h" +#include "unity.h" +#include "test_utils.h" + +/* +Test Best Effort Round Robin Scheduling: + +The following test case tests the "Best Effort Round Robin Scheduling" that fixes the skipping behavior found in older +versions of the ESP-IDF SMP FreeRTOS (see docs for more details about Best Effort Round Robin Scheduling). + +This test... +- Only runs under dual core configuration +- Will disable the tick interrupts of both cores + +Test flow as follows: + +1. Stop preemption on core 0 by raising the priority of the unity task +2. Stop preemption on core 0 by creating a blocker task +3. Disable tick interrupts on both cores +4. Create N spin tasks on each core, each with a sequential task_code +5. Unblock those spin tasks in a sequential order +6. Lower priority of unity task and stop the blocker task so that spin tasks are run +7. Each time a spin task is run (i.e., an iteration) it will send its task code to a queue +8. Spin tasks will clean themselves up +9. The queue should contain the task codes of the spin tasks in the order they were started in, thus showing that round + robin schedules the tasks in a sequential order. +*/ + +#if !defined(CONFIG_FREERTOS_UNICORE) && (defined(CONFIG_FREERTOS_CORETIMER_0) || defined(CONFIG_FREERTOS_CORETIMER_1)) + +#define SPIN_TASK_PRIO (CONFIG_UNITY_FREERTOS_PRIORITY + 1) +#define SPIN_TASK_NUM_ITER 3 +#define TASK_STACK_SIZE 1024 +#define NUM_PINNED_SPIN_TASK_PER_CORE 3 +#if defined(CONFIG_FREERTOS_CORETIMER_0) +#define TICK_INTR_IDX 6 +#else //defined(CONFIG_FREERTOS_CORETIMER_1) +#define TICK_INTR_IDX 15 +#endif + +static QueueHandle_t core0_run_order_queue; +static QueueHandle_t core1_run_order_queue; +static uint32_t total_iter_count[portNUM_PROCESSORS] = {0}; + +static void spin_task(void *arg) +{ + uint32_t task_code = (uint32_t)arg; + QueueHandle_t run_order_queue = ((task_code >> 4) == 0) ? core0_run_order_queue : core1_run_order_queue; + + //Wait to be started + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + for (int i = 0; i < SPIN_TASK_NUM_ITER; i++) { + xQueueSend(run_order_queue, &task_code, 0); + //No need for critical sections as tick interrupt is disabled + total_iter_count[xPortGetCoreID()]++; + taskYIELD(); + } + + //Last iteration of the last spin task on this core. Reenable this core's tick interrupt + if (total_iter_count[xPortGetCoreID()] == (NUM_PINNED_SPIN_TASK_PER_CORE * SPIN_TASK_NUM_ITER)) { + interrupt_controller_hal_enable_interrupts(1 <tx_desc[i].TDES0.Own = 0; /* Set Second Address Chained bit */ hal->tx_desc[i].TDES0.SecondAddressChained = 1; hal->tx_desc[i].TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE; @@ -427,27 +429,37 @@ void emac_hal_start(emac_hal_context_t *hal) hal->dma_regs->dmastatus.val = 0xFFFFFFFF; } -void emac_hal_stop(emac_hal_context_t *hal) +esp_err_t emac_hal_stop(emac_hal_context_t *hal) { typeof(hal->dma_regs->dmaoperation_mode) opm = hal->dma_regs->dmaoperation_mode; typeof(hal->mac_regs->gmacconfig) cfg = hal->mac_regs->gmacconfig; - /* Flush Transmit FIFO */ - opm.flush_tx_fifo = 1; /* Stop DMA transmission */ opm.start_stop_transmission_command = 0; - /* Stop DMA reception */ - opm.start_stop_rx = 0; - /* Disable receive state machine of the MAC for reception from the MII */ - cfg.rx = 0; + hal->dma_regs->dmaoperation_mode = opm; + if (hal->mac_regs->emacdebug.mactfcs != 0x0) { + /* Previous transmit in progress */ + return ESP_ERR_INVALID_STATE; + } /* Disable transmit state machine of the MAC for transmission on the MII */ cfg.tx = 0; + hal->mac_regs->gmacconfig = cfg; - hal->dma_regs->dmaoperation_mode = opm; + /* Disable receive state machine of the MAC for reception from the MII */ + cfg.rx = 0; hal->mac_regs->gmacconfig = cfg; + if (hal->mac_regs->emacdebug.mtlrfrcs != 0x0) { + /* Previous receive copy in progress */ + return ESP_ERR_INVALID_STATE; + } + /* Stop DMA reception */ + opm.start_stop_rx = 0; + hal->dma_regs->dmaoperation_mode = opm; /* Disable Ethernet MAC and DMA Interrupt */ hal->dma_regs->dmain_en.val = 0x0; + + return ESP_OK; } uint32_t emac_hal_get_tx_desc_owner(emac_hal_context_t *hal) diff --git a/components/hal/esp32/include/hal/cpu_ll.h b/components/hal/esp32/include/hal/cpu_ll.h index 7a83ddbc4343..3de6460c36cc 100644 --- a/components/hal/esp32/include/hal/cpu_ll.h +++ b/components/hal/esp32/include/hal/cpu_ll.h @@ -39,7 +39,7 @@ static inline uint32_t IRAM_ATTR cpu_ll_get_core_id(void) return id; } -static inline uint32_t cpu_ll_get_cycle_count(void) +static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void) { uint32_t result; RSR(CCOUNT, result); diff --git a/components/hal/esp32/include/hal/emac.h b/components/hal/esp32/include/hal/emac.h index ec0c1ab3b927..d1f0d712cb40 100644 --- a/components/hal/esp32/include/hal/emac.h +++ b/components/hal/esp32/include/hal/emac.h @@ -1,16 +1,8 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -381,9 +373,24 @@ uint32_t emac_hal_get_phy_data(emac_hal_context_t *hal); void emac_hal_set_address(emac_hal_context_t *hal, uint8_t *mac_addr); + +/** + * @brief Starts EMAC Transmission & Reception + * + * @param hal EMAC HAL context infostructure + */ void emac_hal_start(emac_hal_context_t *hal); -void emac_hal_stop(emac_hal_context_t *hal); +/** + * @brief Stops EMAC Transmission & Reception + * + * @param hal EMAC HAL context infostructure + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_STATE: previous frame transmission/reception is not completed. When this error occurs, + * wait and reapeat the EMAC stop again. + */ +esp_err_t emac_hal_stop(emac_hal_context_t *hal); uint32_t emac_hal_get_tx_desc_owner(emac_hal_context_t *hal); diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 2d3cee276307..10f35353d6b8 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -575,7 +575,7 @@ static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t sign * @param pin_name Pin name to configure * @param func Function to assign to the pin */ -static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) +static inline __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) { PIN_FUNC_SELECT(pin_name, func); } diff --git a/components/hal/esp32/include/hal/rtc_cntl_ll.h b/components/hal/esp32/include/hal/rtc_cntl_ll.h index f026da853bd2..31caf551bf70 100644 --- a/components/hal/esp32/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32/include/hal/rtc_cntl_ll.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -50,6 +42,11 @@ static inline void rtc_cntl_ll_ulp_wakeup_enable(void) SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN); } +static inline void rtc_cntl_ll_ulp_int_clear(void) +{ + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_SAR_INT_CLR); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32/include/hal/touch_sensor_ll.h b/components/hal/esp32/include/hal/touch_sensor_ll.h index fa4d7689e4f8..eace9f68bc10 100644 --- a/components/hal/esp32/include/hal/touch_sensor_ll.h +++ b/components/hal/esp32/include/hal/touch_sensor_ll.h @@ -100,7 +100,7 @@ static inline void touch_ll_set_sleep_time(uint16_t sleep_time) */ static inline void touch_ll_get_sleep_time(uint16_t *sleep_time) { - *sleep_time = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_touch_ctrl1, touch_meas_delay); + *sleep_time = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_touch_ctrl2, touch_sleep_cycles); } /** diff --git a/components/hal/esp32c3/include/hal/cpu_ll.h b/components/hal/esp32c3/include/hal/cpu_ll.h index 4e9d4494099b..ab3ab1768570 100644 --- a/components/hal/esp32c3/include/hal/cpu_ll.h +++ b/components/hal/esp32c3/include/hal/cpu_ll.h @@ -16,10 +16,13 @@ #include #include "soc/soc_caps.h" +#include "soc/dport_access.h" +#include "soc/system_reg.h" #include "esp_bit_defs.h" #include "soc/assist_debug_reg.h" #include "esp_attr.h" #include "riscv/csr.h" +#include "riscv/semihosting.h" /*performance counter*/ #define CSR_PCER_MACHINE 0x7e0 @@ -72,8 +75,29 @@ static inline void cpu_ll_init_hwloop(void) // Nothing needed here for ESP32-C3 } +static inline bool cpu_ll_is_debugger_attached(void) +{ + return REG_GET_BIT(ASSIST_DEBUG_C0RE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE); +} + static inline void cpu_ll_set_breakpoint(int id, uint32_t pc) { + if (cpu_ll_is_debugger_attached()) { + /* If we want to set breakpoint which when hit transfers control to debugger + * we need to set `action` in `mcontrol` to 1 (Enter Debug Mode). + * That `action` value is supported only when `dmode` of `tdata1` is set. + * But `dmode` can be modified by debugger only (from Debug Mode). + * + * So when debugger is connected we use special syscall to ask it to set breakpoint for us. + */ + long args[] = {true, id, (long)pc}; + int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args); + if (ret == 0) { + return; + } + } + /* The code bellow sets breakpoint which will trigger `Breakpoint` exception + * instead transfering control to debugger. */ RV_WRITE_CSR(tselect,id); RV_SET_CSR(CSR_TCONTROL,TCONTROL_MTE); RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE); @@ -83,6 +107,14 @@ static inline void cpu_ll_set_breakpoint(int id, uint32_t pc) static inline void cpu_ll_clear_breakpoint(int id) { + if (cpu_ll_is_debugger_attached()) { + /* see description in cpu_ll_set_breakpoint() */ + long args[] = {false, id}; + int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args); + if (ret == 0){ + return; + } + } RV_WRITE_CSR(tselect,id); RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE); RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE); @@ -106,6 +138,17 @@ static inline void cpu_ll_set_watchpoint(int id, bool on_write) { uint32_t addr_napot; + + if (cpu_ll_is_debugger_attached()) { + /* see description in cpu_ll_set_breakpoint() */ + long args[] = {true, id, (long)addr, (long)size, + (long)((on_read ? ESP_SEMIHOSTING_WP_FLG_RD : 0) | (on_write ? ESP_SEMIHOSTING_WP_FLG_WR : 0))}; + int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args); + if (ret == 0) { + return; + } + } + RV_WRITE_CSR(tselect,id); RV_SET_CSR(CSR_TCONTROL, TCONTROL_MPTE | TCONTROL_MTE); RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE); @@ -124,6 +167,14 @@ static inline void cpu_ll_set_watchpoint(int id, static inline void cpu_ll_clear_watchpoint(int id) { + if (cpu_ll_is_debugger_attached()) { + /* see description in cpu_ll_set_breakpoint() */ + long args[] = {false, id}; + int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args); + if (ret == 0){ + return; + } + } RV_WRITE_CSR(tselect,id); RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE); RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE); @@ -133,11 +184,6 @@ static inline void cpu_ll_clear_watchpoint(int id) return; } -FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void) -{ - return REG_GET_BIT(ASSIST_DEBUG_C0RE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE); -} - static inline void cpu_ll_break(void) { asm volatile("ebreak\n"); @@ -153,6 +199,11 @@ static inline void cpu_ll_set_vecbase(const void* vecbase) static inline void cpu_ll_waiti(void) { + if (cpu_ll_is_debugger_attached() && DPORT_REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON) == 0) { + /* when SYSTEM_CPU_WAIT_MODE_FORCE_ON is disabled in WFI mode SBA access to memory does not work for debugger, + so do not enter that mode when debugger is connected */ + return; + } asm volatile ("wfi\n"); } diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 6214bc06e32c..2baaf77e707b 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -26,6 +26,7 @@ #include "soc/gpio_periph.h" #include "soc/gpio_struct.h" #include "soc/rtc_cntl_reg.h" +#include "soc/usb_serial_jtag_reg.h" #include "hal/gpio_types.h" #include "stdlib.h" @@ -33,17 +34,6 @@ extern "C" { #endif -/* - * The following defines are used to disable USB JTAG when pins 18 and pins 19 - * are set to be used as GPIO. - * See gpio_pad_select_gpio() below. - * - * TODO: Delete these definitions once the USB device registers definition is - * merged. - */ -#define USB_DEVICE_CONF0_REG (0x60043018) -#define USB_DEVICE_USB_PAD_ENABLE (BIT(14)) - // Get GPIO hardware instance with giving gpio num #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) @@ -398,10 +388,11 @@ static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t sign * @param pin_name Pin name to configure * @param func Function to assign to the pin */ -static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) +static inline __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) { + // Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function if (pin_name == IO_MUX_GPIO18_REG || pin_name == IO_MUX_GPIO19_REG) { - CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_USB_PAD_ENABLE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); } PIN_FUNC_SELECT(pin_name, func); } diff --git a/components/hal/esp32c3/include/hal/spi_ll.h b/components/hal/esp32c3/include/hal/spi_ll.h index 8cc72b9b6db7..aee3032e96aa 100644 --- a/components/hal/esp32c3/include/hal/spi_ll.h +++ b/components/hal/esp32c3/include/hal/spi_ll.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* * NOTICE @@ -763,7 +755,7 @@ static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int dela */ static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold) { - hw->user1.cs_hold_time = hold - 1; + hw->user1.cs_hold_time = hold; hw->user.cs_hold = hold ? 1 : 0; } diff --git a/components/hal/esp32c3/include/hal/uhci_ll.h b/components/hal/esp32c3/include/hal/uhci_ll.h index 1566d0b0917c..235d28ab3a35 100644 --- a/components/hal/esp32c3/include/hal/uhci_ll.h +++ b/components/hal/esp32c3/include/hal/uhci_ll.h @@ -20,12 +20,16 @@ #include #include "uhci_types.h" #include "soc/uhci_struct.h" -#include "soc/gdma_struct.h" - -#define UHCI_DMA_INDEX 0 #define UHCI_LL_GET_HW(num) (((num) == 0) ? (&UHCI0) : (NULL)) +typedef enum { + UHCI_RX_BREAK_CHR_EOF = 0x1, + UHCI_RX_IDLE_EOF = 0x2, + UHCI_RX_LEN_EOF = 0x4, + UHCI_RX_EOF_MAX = 0x7, +} uhci_rxeof_cfg_t; + static inline void uhci_ll_init(uhci_dev_t *hw) { typeof(hw->conf0) conf0_reg; @@ -38,7 +42,8 @@ static inline void uhci_ll_init(uhci_dev_t *hw) static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num) { - abort(); // TODO ESP32-C3 IDF-2117 + hw->conf0.uart0_ce = (uart_num == 0)? 1: 0; + hw->conf0.uart1_ce = (uart_num == 1)? 1: 0; } static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char) @@ -90,20 +95,6 @@ static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_c hw->escape_conf.val = escape_conf_reg.val; } -static inline void uhci_ll_dma_in_reset(uhci_dev_t *hw) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].in.in_conf0.in_rst = 1; - GDMA.channel[UHCI_DMA_INDEX].in.in_conf0.in_rst = 0; -} - -static inline void uhci_ll_dma_out_reset(uhci_dev_t *hw) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].out.out_conf0.out_rst = 1; - GDMA.channel[UHCI_DMA_INDEX].out.out_conf0.out_rst = 0; -} - static inline void uhci_ll_enable_intr(uhci_dev_t *hw, uint32_t intr_mask) { hw->int_ena.val |= intr_mask; @@ -124,41 +115,6 @@ static inline uint32_t uhci_ll_get_intr(uhci_dev_t *hw) return hw->int_st.val; } -static inline void uhci_ll_set_rx_dma(uhci_dev_t *hw, uint32_t addr) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].in.in_link.addr = addr; -} - -static inline void uhci_ll_set_tx_dma(uhci_dev_t *hw, uint32_t addr) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].out.out_link.addr = addr; -} - -static inline void uhci_ll_rx_dma_start(uhci_dev_t *hw) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].in.in_link.start = 1; -} - -static inline void uhci_ll_tx_dma_start(uhci_dev_t *hw) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].out.out_link.start = 1; -} - -static inline void uhci_ll_rx_dma_stop(uhci_dev_t *hw) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].in.in_link.stop = 1; -} - -static inline void uhci_ll_tx_dma_stop(uhci_dev_t *hw) -{ - (void)hw; - GDMA.channel[UHCI_DMA_INDEX].out.out_link.stop = 1; -} static inline void uhci_ll_set_eof_mode(uhci_dev_t *hw, uint32_t eof_mode) { diff --git a/components/hal/esp32c3/include/hal/uhci_types.h b/components/hal/esp32c3/include/hal/uhci_types.h new file mode 100644 index 000000000000..7b7f41d0f94b --- /dev/null +++ b/components/hal/esp32c3/include/hal/uhci_types.h @@ -0,0 +1,54 @@ +// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + +// Though the UHCI driver hasn't been published, some types are defined here +// for users to develop over the HAL. See example: controller_hci_uart_esp32c3 + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * @brief UHCI escape sequence + */ +typedef struct { + uint8_t seper_chr; /*!< escape sequence character */ + uint8_t sub_chr1; /*!< escape sequence sub-character 1 */ + uint8_t sub_chr2; /*!< escape sequence sub-character 2 */ + bool sub_chr_en; /*!< enable use of sub-chaacter of escape sequence */ +} uhci_seper_chr_t; + +/** + * @brief UHCI software flow control + */ +typedef struct { + uint8_t xon_chr; /*!< character for XON */ + uint8_t xon_sub1; /*!< sub-character 1 for XON */ + uint8_t xon_sub2; /*!< sub-character 2 for XON */ + uint8_t xoff_chr; /*!< character 2 for XOFF */ + uint8_t xoff_sub1; /*!< sub-character 1 for XOFF */ + uint8_t xoff_sub2; /*!< sub-character 2 for XOFF */ + uint8_t flow_en; /*!< enable use of software flow control */ +} uhci_swflow_ctrl_sub_chr_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h index e75cf67b4397..6702eebbc227 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -37,7 +37,7 @@ typedef enum { USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1 = (1 << 8), USB_SERIAL_JTAG_INTR_BUS_RESET = (1 << 9), USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), -} usb_serial_jtag_intr_t; +} usb_serial_jtag_ll_intr_t; /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. @@ -51,6 +51,18 @@ static inline void usb_serial_jtag_ll_ena_intr_mask(uint32_t mask) USB_SERIAL_JTAG.int_ena.val |= mask; } +/** + * @brief Clear the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts bits need to be cleared. + * + * @return None + */ +static inline void usb_serial_jtag_ll_clr_intr_sts_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_clr.val = mask; +} + /** * @brief Disable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -156,6 +168,9 @@ static inline int usb_serial_jtag_ll_txfifo_writable(void) * @brief Flushes the TX buffer, that is, make it available for the * host to pick up. * + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically. + * It won't be executed if there is nothing in the fifo. + * * @return na */ static inline void usb_serial_jtag_ll_txfifo_flush(void) diff --git a/components/hal/esp32s2/include/hal/clk_gate_ll.h b/components/hal/esp32s2/include/hal/clk_gate_ll.h index 3d2690649b79..6dc896a7936c 100644 --- a/components/hal/esp32s2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s2/include/hal/clk_gate_ll.h @@ -29,6 +29,8 @@ extern "C" { static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) { switch (periph) { + case PERIPH_SARADC_MODULE: + return DPORT_APB_SARADC_CLK_EN; case PERIPH_LEDC_MODULE: return DPORT_LEDC_CLK_EN; case PERIPH_UART0_MODULE: @@ -109,6 +111,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en (void)enable; // unused switch (periph) { + case PERIPH_SARADC_MODULE: + return DPORT_APB_SARADC_RST; case PERIPH_LEDC_MODULE: return DPORT_LEDC_RST; case PERIPH_UART0_MODULE: diff --git a/components/hal/esp32s2/include/hal/cpu_ll.h b/components/hal/esp32s2/include/hal/cpu_ll.h index c70955eba263..ea4556adb509 100644 --- a/components/hal/esp32s2/include/hal/cpu_ll.h +++ b/components/hal/esp32s2/include/hal/cpu_ll.h @@ -33,7 +33,7 @@ static inline uint32_t IRAM_ATTR cpu_ll_get_core_id(void) return 0; } -static inline uint32_t cpu_ll_get_cycle_count(void) +static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void) { uint32_t result; RSR(CCOUNT, result); diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 12fafe60629a..4d27786c3e18 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -399,7 +399,7 @@ static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t sign * @param pin_name Pin name to configure * @param func Function to assign to the pin */ -static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) +static inline __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) { PIN_FUNC_SELECT(pin_name, func); } diff --git a/components/hal/esp32s2/include/hal/rmt_ll.h b/components/hal/esp32s2/include/hal/rmt_ll.h index e9533c04d8e0..d44d92dc895a 100644 --- a/components/hal/esp32s2/include/hal/rmt_ll.h +++ b/components/hal/esp32s2/include/hal/rmt_ll.h @@ -50,7 +50,7 @@ static inline bool rmt_ll_is_mem_power_down(rmt_dev_t *dev) static inline void rmt_ll_enable_mem_access(rmt_dev_t *dev, bool enable) { - dev->apb_conf.fifo_mask = enable; + dev->apb_conf.apb_fifo_mask = enable; } static inline void rmt_ll_set_counter_clock_src(rmt_dev_t *dev, uint32_t channel, uint8_t src, uint8_t div_num, uint8_t div_a, uint8_t div_b) @@ -253,17 +253,7 @@ static inline uint32_t rmt_ll_tx_get_channel_status(rmt_dev_t *dev, uint32_t cha static inline void rmt_ll_tx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit) { - dev->tx_lim_ch[channel].limit = limit; -} - -static inline void rmt_ll_rx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit) -{ - dev->tx_lim_ch[channel].rx_lim = limit; -} - -static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel) -{ - return dev->tx_lim_ch[channel].rx_lim; + dev->tx_lim_ch[channel].tx_lim = limit; } static inline void rmt_ll_enable_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable) @@ -302,12 +292,6 @@ static inline void rmt_ll_enable_tx_loop_interrupt(rmt_dev_t *dev, uint32_t chan dev->int_ena.val |= (enable << (channel + 16)); } -static inline void rmt_ll_enable_rx_thres_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable) -{ - dev->int_ena.val &= ~(1 << (channel + 20)); - dev->int_ena.val |= (enable << (channel + 20)); -} - static inline void rmt_ll_clear_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel) { dev->int_clr.val = (1 << (channel * 3)); @@ -338,11 +322,6 @@ static inline void rmt_ll_clear_tx_loop_interrupt(rmt_dev_t *dev, uint32_t chann dev->int_clr.val = (1 << (channel + 16)); } -static inline void rmt_ll_clear_rx_thres_interrupt(rmt_dev_t *dev, uint32_t channel) -{ - dev->int_clr.val = (1 << (channel + 20)); -} - static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev) { uint32_t status = dev->int_st.val; @@ -379,12 +358,6 @@ static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev) return (status & 0xF0000) >> 16; } -static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev) -{ - uint32_t status = dev->int_st.val; - return (status & 0xF00000) >> 20; -} - static inline void rmt_ll_tx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->carrier_duty_ch[channel], high, high_ticks); @@ -445,11 +418,6 @@ static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const r } } -static inline void rmt_ll_rx_enable_pingpong(rmt_dev_t *dev, uint32_t channel, bool enable) -{ - dev->conf_ch[channel].conf1.chk_rx_carrier_en = enable; -} - static inline void rmt_ll_config_update(rmt_dev_t *dev, uint32_t channel) { } diff --git a/components/hal/esp32s2/include/hal/rtc_cntl_ll.h b/components/hal/esp32s2/include/hal/rtc_cntl_ll.h index e1ad1d52cd39..ffba472c477c 100644 --- a/components/hal/esp32s2/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32s2/include/hal/rtc_cntl_ll.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -48,9 +40,11 @@ static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void) REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); } -static inline void rtc_cntl_ll_ulp_wakeup_enable(void) +static inline void rtc_cntl_ll_ulp_int_clear(void) { - SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S); + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_ULP_CP_INT_CLR); + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR); + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR); } #ifdef __cplusplus diff --git a/components/hal/esp32s2/include/hal/spi_ll.h b/components/hal/esp32s2/include/hal/spi_ll.h index 8571adb7c4ec..bfe7fcac0ff6 100644 --- a/components/hal/esp32s2/include/hal/spi_ll.h +++ b/components/hal/esp32s2/include/hal/spi_ll.h @@ -746,7 +746,7 @@ static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n) */ static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold) { - hw->ctrl2.cs_hold_time = hold - 1; + hw->ctrl2.cs_hold_time = hold; hw->user.cs_hold = hold ? 1 : 0; } diff --git a/components/hal/esp32s2/include/hal/usb_ll.h b/components/hal/esp32s2/include/hal/usb_ll.h index ffd648923d2c..881de8a0d68d 100644 --- a/components/hal/esp32s2/include/hal/usb_ll.h +++ b/components/hal/esp32s2/include/hal/usb_ll.h @@ -38,6 +38,6 @@ static inline void usb_ll_int_phy_pullup_conf(bool dp_pu, bool dp_pd, bool dm_pu conf.dp_pullup = dp_pu; conf.dp_pulldown = dp_pd; conf.dm_pullup = dm_pu; - conf.dm_pulldown = dp_pd; + conf.dm_pulldown = dm_pd; USB_WRAP.otg_conf = conf; } diff --git a/components/hal/esp32s3/include/hal/cpu_ll.h b/components/hal/esp32s3/include/hal/cpu_ll.h index 8445fdf44cfe..32f607854b78 100644 --- a/components/hal/esp32s3/include/hal/cpu_ll.h +++ b/components/hal/esp32s3/include/hal/cpu_ll.h @@ -38,7 +38,7 @@ static inline uint32_t IRAM_ATTR cpu_ll_get_core_id(void) return id; } -static inline uint32_t cpu_ll_get_cycle_count(void) +static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void) { uint32_t result; RSR(CCOUNT, result); diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 234b4775789b..fccbb5764ec9 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -35,8 +35,9 @@ extern "C" { // Get GPIO hardware instance with giving gpio num #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) -#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) -#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) +// On ESP32S3, pro cpu and app cpu shares the same interrupt enable bit +#define GPIO_LL_INTR_ENA (BIT(0)) +#define GPIO_LL_NMI_INTR_ENA (BIT(1)) /** * @brief Enable pull-up on GPIO. @@ -103,6 +104,8 @@ static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, gpio_num_t gpio_num, gp */ static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) { + // On ESP32S3, pcpu_int register represents GPIO0-31 interrupt status on both cores + (void)core_id; *status = hw->pcpu_int; } @@ -115,6 +118,8 @@ static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uin */ static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) { + // On ESP32S3, pcpu_int1 register represents GPIO32-48 interrupt status on both cores + (void)core_id; *status = hw->pcpu_int1.intr; } @@ -149,9 +154,8 @@ static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask) */ static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, gpio_num_t gpio_num) { - if (core_id == 0) { - GPIO.pin[gpio_num].int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable pro cpu intr - } + (void)core_id; + GPIO.pin[gpio_num].int_ena = GPIO_LL_INTR_ENA; //enable intr } /** @@ -397,7 +401,7 @@ static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t sign * @param pin_name Pin name to configure * @param func Function to assign to the pin */ -static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) +static inline __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) { PIN_FUNC_SELECT(pin_name, func); } diff --git a/components/hal/esp32s3/include/hal/rtc_cntl_ll.h b/components/hal/esp32s3/include/hal/rtc_cntl_ll.h index e1ad1d52cd39..ffba472c477c 100644 --- a/components/hal/esp32s3/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_cntl_ll.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -48,9 +40,11 @@ static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void) REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); } -static inline void rtc_cntl_ll_ulp_wakeup_enable(void) +static inline void rtc_cntl_ll_ulp_int_clear(void) { - SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S); + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_ULP_CP_INT_CLR); + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR); + REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR); } #ifdef __cplusplus diff --git a/components/hal/esp32s3/include/hal/spi_ll.h b/components/hal/esp32s3/include/hal/spi_ll.h index 3cdac824c6b6..6c26a54d8712 100644 --- a/components/hal/esp32s3/include/hal/spi_ll.h +++ b/components/hal/esp32s3/include/hal/spi_ll.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* * NOTICE @@ -770,7 +762,7 @@ static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int dela */ static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold) { - hw->user1.cs_hold_time = hold - 1; + hw->user1.cs_hold_time = hold; hw->user.cs_hold = hold ? 1 : 0; } diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index 95b53c5cbd1d..7b30bba21882 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -56,6 +56,18 @@ typedef enum { UART_INTR_CMD_CHAR_DET = (0x1 << 18), } uart_intr_t; +/** + * @brief Configure the UART core reset. + * + * @param hw Beginning address of the peripheral registers. + * @param core_rst_en True to enable the core reset, otherwise set it false. + * + * @return None. + */ +static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) +{ + hw->clk_conf.rst_core = core_rst_en; +} /** * @brief Set the UART source clock. diff --git a/components/hal/i2c_hal.c b/components/hal/i2c_hal.c index 2d975d8c996f..db2dd1a7e112 100644 --- a/components/hal/i2c_hal.c +++ b/components/hal/i2c_hal.c @@ -144,26 +144,11 @@ bool i2c_hal_is_master_mode(i2c_hal_context_t *hal) return i2c_ll_is_master_mode(hal->dev); } -void i2c_hal_get_rxfifo_cnt(i2c_hal_context_t *hal, uint32_t *len) -{ - *len = i2c_ll_get_rxfifo_cnt(hal->dev); -} - -void i2c_hal_get_txfifo_cnt(i2c_hal_context_t *hal, uint32_t *len) -{ - *len = i2c_ll_get_txfifo_len(hal->dev); -} - void i2c_hal_enable_slave_tx_it(i2c_hal_context_t *hal) { i2c_ll_slave_enable_tx_it(hal->dev); } -void i2c_hal_disable_slave_tx_it(i2c_hal_context_t *hal) -{ - i2c_ll_slave_disable_tx_it(hal->dev); -} - void i2c_hal_enable_slave_rx_it(i2c_hal_context_t *hal) { i2c_ll_slave_enable_rx_it(hal->dev); @@ -218,8 +203,3 @@ void i2c_hal_master_init(i2c_hal_context_t *hal, int i2c_num) i2c_ll_txfifo_rst(hal->dev); i2c_ll_rxfifo_rst(hal->dev); } - -void i2c_hal_update_config(i2c_hal_context_t *hal) -{ - i2c_ll_update(hal->dev); -} diff --git a/components/hal/i2c_hal_iram.c b/components/hal/i2c_hal_iram.c index 80c490009bf4..197143ae14e1 100644 --- a/components/hal/i2c_hal_iram.c +++ b/components/hal/i2c_hal_iram.c @@ -42,3 +42,23 @@ void i2c_hal_slave_handle_event(i2c_hal_context_t *hal, i2c_intr_event_t *event) { i2c_ll_slave_get_event(hal->dev, event); } + +void i2c_hal_disable_slave_tx_it(i2c_hal_context_t *hal) +{ + i2c_ll_slave_disable_tx_it(hal->dev); +} + +void i2c_hal_update_config(i2c_hal_context_t *hal) +{ + i2c_ll_update(hal->dev); +} + +void i2c_hal_get_rxfifo_cnt(i2c_hal_context_t *hal, uint32_t *len) +{ + *len = i2c_ll_get_rxfifo_cnt(hal->dev); +} + +void i2c_hal_get_txfifo_cnt(i2c_hal_context_t *hal, uint32_t *len) +{ + *len = i2c_ll_get_txfifo_len(hal->dev); +} diff --git a/components/hal/include/hal/gpio_types.h b/components/hal/include/hal/gpio_types.h index 2438014a5e70..2e8dec20fe8c 100644 --- a/components/hal/include/hal/gpio_types.h +++ b/components/hal/include/hal/gpio_types.h @@ -295,7 +295,6 @@ typedef enum { GPIO_NUM_19 = 19, /*!< GPIO19, input and output */ GPIO_NUM_20 = 20, /*!< GPIO20, input and output */ GPIO_NUM_21 = 21, /*!< GPIO21, input and output */ - GPIO_NUM_22 = 22, /*!< GPIO22, input and output */ GPIO_NUM_MAX, /** @endcond */ } gpio_num_t; diff --git a/components/hal/include/hal/rtc_hal.h b/components/hal/include/hal/rtc_hal.h index 1473ce0d305d..fb1624e1778d 100644 --- a/components/hal/include/hal/rtc_hal.h +++ b/components/hal/include/hal/rtc_hal.h @@ -54,3 +54,5 @@ void rtc_cntl_hal_enable_cpu_retention(void *addr); * Enable wakeup from ULP coprocessor. */ #define rtc_hal_ulp_wakeup_enable() rtc_cntl_ll_ulp_wakeup_enable() + +#define rtc_hal_ulp_int_clear() rtc_cntl_ll_ulp_int_clear() diff --git a/components/hal/include/hal/timer_hal.h b/components/hal/include/hal/timer_hal.h index f8c91739d91b..cb3d5e0671db 100644 --- a/components/hal/include/hal/timer_hal.h +++ b/components/hal/include/hal/timer_hal.h @@ -59,6 +59,15 @@ void timer_hal_init(timer_hal_context_t *hal, timer_group_t group_num, timer_idx */ void timer_hal_get_status_reg_mask_bit(timer_hal_context_t *hal, uint32_t *status_reg, uint32_t *mask_bit); +/** + * @brief Reset timer peripheral + * + * @param hal Context of the HAL layer + * + * @return None + */ +void timer_hal_reset_periph(timer_hal_context_t *hal); + /** * @brief Set timer clock prescale value * diff --git a/components/hal/spi_hal_iram.c b/components/hal/spi_hal_iram.c index dcbbe4753ccc..97a28e6d0d52 100644 --- a/components/hal/spi_hal_iram.c +++ b/components/hal/spi_hal_iram.c @@ -146,7 +146,8 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de lldesc_setup_link(hal->dmadesc_rx, trans->rcv_buffer, ((trans->rx_bitlen + 7) / 8), true); spi_dma_ll_rx_reset(hal->dma_in, hal->rx_dma_chan); - spi_ll_dma_rx_fifo_reset(hal->dma_in); + spi_ll_dma_rx_fifo_reset(hal->hw); + spi_ll_infifo_full_clr(hal->hw); spi_ll_dma_rx_enable(hal->hw, 1); spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx); } @@ -170,7 +171,8 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de lldesc_setup_link(hal->dmadesc_tx, trans->send_buffer, (trans->tx_bitlen + 7) / 8, false); spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); - spi_ll_dma_tx_fifo_reset(hal->dma_in); + spi_ll_dma_tx_fifo_reset(hal->hw); + spi_ll_outfifo_empty_clr(hal->hw); spi_ll_dma_tx_enable(hal->hw, 1); spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx); } diff --git a/components/hal/timer_hal.c b/components/hal/timer_hal.c index 7337b19464f6..48a918e9c7ed 100644 --- a/components/hal/timer_hal.c +++ b/components/hal/timer_hal.c @@ -26,3 +26,10 @@ void timer_hal_get_status_reg_mask_bit(timer_hal_context_t *hal, uint32_t *statu *status_reg = timer_ll_get_intr_status_reg(hal->dev); *mask_bit = timer_ll_get_intr_mask_bit(hal->dev, hal->idx); } + +void timer_hal_reset_periph(timer_hal_context_t *hal) +{ + timer_ll_intr_disable(hal->dev, hal->idx); + timer_ll_set_counter_enable(hal->dev, hal->idx, TIMER_PAUSE); + timer_ll_set_counter_value(hal->dev, hal->idx, 0ULL); +} diff --git a/components/heap/heap_tlsf.c b/components/heap/heap_tlsf.c index c9be8d35134d..e5f826011ffe 100644 --- a/components/heap/heap_tlsf.c +++ b/components/heap/heap_tlsf.c @@ -801,10 +801,14 @@ void* tlsf_memalign_offs(tlsf_t tlsf, size_t align, size_t size, size_t data_off */ const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum - off_adjust, align); - /* - ** If alignment is less than or equals base alignment, we're done. - ** If we requested 0 bytes, return null, as tlsf_malloc(0) does. - */ + /* + ** If alignment is less than or equal to base alignment, we're done, because + ** we are guaranteed that the size is at least sizeof(block_header_t), enough + ** to store next blocks' metadata. Plus, all pointers allocated will all be + ** aligned on a 4-byte bound, so ptr + data_offset will also have this + ** alignment constraint. Thus, the gap is not required. + ** If we requested 0 bytes, return null, as tlsf_malloc(0) does. + */ const size_t aligned_size = (adjust && align > ALIGN_SIZE) ? size_with_gap : adjust; block_header_t* block = block_locate_free(control, aligned_size); @@ -820,10 +824,12 @@ void* tlsf_memalign_offs(tlsf_t tlsf, size_t align, size_t size, size_t data_off tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); /* - ** If gap size is too small or if there is not gap but we need one, + ** If gap size is too small or if there is no gap but we need one, ** offset to next aligned boundary. + ** NOTE: No need for a gap if the alignment required is less than or is + ** equal to ALIGN_SIZE. */ - if ((gap && gap < gap_minimum) || (!gap && off_adjust)) + if ((gap && gap < gap_minimum) || (!gap && off_adjust && align > ALIGN_SIZE)) { const size_t gap_remain = gap_minimum - gap; const size_t offset = tlsf_max(gap_remain, align); diff --git a/components/heap/multi_heap.c b/components/heap/multi_heap.c index 059f6c19af43..2c85c1f7de68 100644 --- a/components/heap/multi_heap.c +++ b/components/heap/multi_heap.c @@ -197,6 +197,7 @@ void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size) void *result = tlsf_malloc(heap->heap_data, size); if(result) { heap->free_bytes -= tlsf_block_size(result); + heap->free_bytes -= tlsf_alloc_overhead(); if (heap->free_bytes < heap->minimum_free_bytes) { heap->minimum_free_bytes = heap->free_bytes; } @@ -217,6 +218,7 @@ void multi_heap_free_impl(multi_heap_handle_t heap, void *p) multi_heap_internal_lock(heap); heap->free_bytes += tlsf_block_size(p); + heap->free_bytes += tlsf_alloc_overhead(); tlsf_free(heap->heap_data, p); multi_heap_internal_unlock(heap); } @@ -239,6 +241,8 @@ void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size) size_t previous_block_size = tlsf_block_size(p); void *result = tlsf_realloc(heap->heap_data, p, size); if(result) { + /* No need to subtract the tlsf_alloc_overhead() as it has already + * been subtracted when allocating the block at first with malloc */ heap->free_bytes += previous_block_size; heap->free_bytes -= tlsf_block_size(result); if (heap->free_bytes < heap->minimum_free_bytes) { @@ -270,6 +274,7 @@ void *multi_heap_aligned_alloc_impl_offs(multi_heap_handle_t heap, size_t size, void *result = tlsf_memalign_offs(heap->heap_data, alignment, size, offset); if(result) { heap->free_bytes -= tlsf_block_size(result); + heap->free_bytes -= tlsf_alloc_overhead(); if(heap->free_bytes < heap->minimum_free_bytes) { heap->minimum_free_bytes = heap->free_bytes; } @@ -361,6 +366,7 @@ static void multi_heap_get_info_tlsf(void* ptr, size_t size, int used, void* use void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info) { uint32_t sl_interval; + uint32_t overhead; memset(info, 0, sizeof(multi_heap_info_t)); @@ -370,7 +376,10 @@ void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info) multi_heap_internal_lock(heap); tlsf_walk_pool(tlsf_get_pool(heap->heap_data), multi_heap_get_info_tlsf, info); - info->total_allocated_bytes = (heap->pool_size - tlsf_size()) - heap->free_bytes; + /* TLSF has an overhead per block. Calculate the total amount of overhead, it shall not be + * part of the allocated bytes */ + overhead = info->allocated_blocks * tlsf_alloc_overhead(); + info->total_allocated_bytes = (heap->pool_size - tlsf_size()) - heap->free_bytes - overhead; info->minimum_free_bytes = heap->minimum_free_bytes; info->total_free_bytes = heap->free_bytes; if (info->largest_free_block) { diff --git a/components/heap/test/test_malloc_caps.c b/components/heap/test/test_malloc_caps.c index fd3dc0228672..c658ee8b7828 100644 --- a/components/heap/test/test_malloc_caps.c +++ b/components/heap/test/test_malloc_caps.c @@ -121,8 +121,10 @@ TEST_CASE("IRAM_8BIT capability test", "[heap]") TEST_ASSERT((((int)ptr)&0xFF000000)==0x40000000); - TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_IRAM_8BIT) == (free_size - heap_caps_get_allocated_size(ptr))); - TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_32BIT) == (free_size32 - heap_caps_get_allocated_size(ptr))); + /* As the heap allocator may present an overhead for allocated blocks, + * we need to check that the free heap size is now smaller or equal to the former free size. */ + TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_IRAM_8BIT) <= (free_size - heap_caps_get_allocated_size(ptr))); + TEST_ASSERT(heap_caps_get_free_size(MALLOC_CAP_32BIT) <= (free_size32 - heap_caps_get_allocated_size(ptr))); free(ptr); } diff --git a/components/heap/test_multi_heap_host/test_multi_heap.cpp b/components/heap/test_multi_heap_host/test_multi_heap.cpp index 0a95c2d2c762..e85cceddc6b3 100644 --- a/components/heap/test_multi_heap_host/test_multi_heap.cpp +++ b/components/heap/test_multi_heap_host/test_multi_heap.cpp @@ -484,6 +484,42 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]") } } + /* Check that TLSF doesn't allocate a memory space smaller than required. + * In any case, TLSF will write data in the previous block than the one + * allocated. Thus, we should try to get/allocate this previous block. If + * the poisoned filled pattern has beeen overwritten by TLSF, then this + * previous block will trigger an exception. + * More info on this bug in !16296. */ + const size_t size = 50; /* TLSF will round the size up */ + uint8_t *buf1 = (uint8_t *)multi_heap_aligned_alloc(heap, size, 4); + uint8_t *buf2 = (uint8_t *)multi_heap_aligned_alloc(heap, size, 4); + multi_heap_free(heap, buf1); + /* By specifying a size equal of the gap between buf1 and buf2. We are + * trying to force TLSF to allocate two consecutive blocks. */ + buf1 = (uint8_t *)multi_heap_aligned_alloc(heap, buf2 - buf1, 4); + multi_heap_free(heap, buf2); + + printf("[ALIGNED_ALLOC] heap_size after: %d \n", multi_heap_free_size(heap)); REQUIRE((old_size - multi_heap_free_size(heap)) <= leakage); } + +// TLSF has some overhead when allocating blocks, check that overhead +TEST_CASE("multi_heap allocation overhead", "[multi_heap]") +{ + uint8_t heapdata[4 * 1024]; + size_t alloc_size = 256; + multi_heap_handle_t heap = multi_heap_register(heapdata, sizeof(heapdata)); + size_t free_bytes_1 = multi_heap_free_size(heap); + + /* Allocate any amount of data, in any case there will be an overhead */ + void *x = multi_heap_malloc(heap, alloc_size); + + /* free_bytes_2 should be free_bytes_1 - alloc_size - overhead. + * We don't know the value of overhead, let's check that it is non-zero */ + size_t free_bytes_2 = multi_heap_free_size(heap); + REQUIRE( free_bytes_1 > free_bytes_2 ); + REQUIRE( free_bytes_1 - free_bytes_2 > alloc_size ); + + multi_heap_free(heap, x); +} diff --git a/components/idf_test/include/esp32/idf_performance_target.h b/components/idf_test/include/esp32/idf_performance_target.h index f9f0c414988d..d6b64df99a72 100644 --- a/components/idf_test/include/esp32/idf_performance_target.h +++ b/components/idf_test/include/esp32/idf_performance_target.h @@ -33,87 +33,6 @@ #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 30 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 27 -/* - * Flash Performance value - * 4 subsections: legacy, normal (new driver after v4.0), SPI1 (external but on SPI1), external (SPI2) - * These thresholds are set to about 70% of the average test data, under certain condition. - * Contact Espressif for details. - */ -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B -//The single_core config is much faster than other configs. Use the value of other configs -//Collect data and correct it later -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B -//The single_core config is much faster than other configs. Use the value of other configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B 35300 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB (697*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB (6780*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE 11200 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B -//The single_core config is much faster than other configs. Use the value of other configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 20100 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B -//The single_core config is much faster than other configs. Use the value of other configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B 35200 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB (754*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB (6650*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 45300 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B -//The single_core config is much faster than other configs. Use the value of other configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B 16200 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B -//The single_core config is much faster than other configs. Use the value of other configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B 33600 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB (484*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB (1512*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE 49600 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 73500 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B (261*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB (470*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB (261*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 30900 -#endif - // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround) #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT 140 diff --git a/components/idf_test/include/esp32c3/idf_performance_target.h b/components/idf_test/include/esp32c3/idf_performance_target.h index c77e3efb1ecb..7fbf8b9eaf5d 100644 --- a/components/idf_test/include/esp32c3/idf_performance_target.h +++ b/components/idf_test/include/esp32c3/idf_performance_target.h @@ -29,85 +29,6 @@ #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 32 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 -/* - * Flash Performance value - * 4 subsections: legacy, normal (new driver after v4.0), SPI1 (external but on SPI1), external (SPI2) - * These thresholds are set to about 70% of the average test data, under certain condition. - * Contact Espressif for details. - */ -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B -// rom options is much slower. use its 70% -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B 42200 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B -// legacy & suspend config are much faster. use the 70% of slower configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B (179*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB (622*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB (6536*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE 23700 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 46400 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B -// legacy & suspend config are much faster. use the 70% of slower configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B (183*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB (605*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB (6676*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 22900 -#endif - -// No SPI1 tests for C3 -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE 0 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 43300 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B -// rom options is much slower. use its 70% -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B 99500 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB (300*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB (754*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 33900 -#endif - // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround) #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT 140 diff --git a/components/idf_test/include/esp32s2/idf_performance_target.h b/components/idf_test/include/esp32s2/idf_performance_target.h index f37c2a9e00f7..cd037bb47d75 100644 --- a/components/idf_test/include/esp32s2/idf_performance_target.h +++ b/components/idf_test/include/esp32s2/idf_performance_target.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -33,82 +25,3 @@ #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 32 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 - -/* - * Flash Performance value - * 4 subsections: legacy, normal (new driver after v4.0), SPI1 (external but on SPI1), external (SPI2) - * These thresholds are set to about 70% of the average test data, under certain condition. - * Contact Espressif for details. - */ -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B -//Great variation, use the 70% of min value -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B 33300 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B -// legacy config is much faster. use the 70% of slower configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B (239*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB -// Weird data. Use 70% average of slower configs. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB (546*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB (1191*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE 19500 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B -//release config is much faster than other configs. Use 70% average of other configs -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 46300 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B (249*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB (851*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB (11480*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 40100 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B 30500 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B (183*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB (474*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB (1283*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE 44100 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 47800 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B (252*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB -// write with large RAM buffer tests has lower performance value than normal performance tests -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB (398*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB (1204*1000) -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 22100 -#endif diff --git a/components/idf_test/include/esp32s3/idf_performance_target.h b/components/idf_test/include/esp32s3/idf_performance_target.h index 62f996fc6586..d735bb27023c 100644 --- a/components/idf_test/include/esp32s3/idf_performance_target.h +++ b/components/idf_test/include/esp32s3/idf_performance_target.h @@ -1,23 +1,15 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 43 // SHA256 hardware throughput at 240MHz, threshold set lower than worst case -#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 19.8 +#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 90 // esp_sha() time to process 32KB of input data from RAM #define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000 #define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900 @@ -32,82 +24,6 @@ #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 32 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 -/* - * Flash Performance value - * 4 subsections: legacy, normal (new driver after v4.0), SPI1 (external but on SPI1), external (SPI2) - * These thresholds are set to about 70% of the average test data, under certain condition. - * Contact Espressif for details. - * - * Currently all performance data on S3 are set to 0 for now. Update to a proper value later. - */ -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE 0 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 0 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE 0 -#endif - -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB 0 -#endif -#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE -//erase performance is highly depending on the chip vendor. Use 70% of the minimal value. -#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 0 -#endif - // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround) #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT 140 diff --git a/components/idf_test/integration_test/KnownIssues b/components/idf_test/integration_test/KnownIssues deleted file mode 100644 index 73f7e7a77486..000000000000 --- a/components/idf_test/integration_test/KnownIssues +++ /dev/null @@ -1,10 +0,0 @@ - -# BT heap size issue -ESP32.BTSTK_MISC_0301 - -# GATT read multiple -ESP32.BTSTK_GATT_27002 -ESP32.BTSTK_GATT_27003 - -# CI -ESP32.BLUEDROID_GAP_04005 diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index dcd0c18d3e7c..e32802ad1341 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -266,6 +266,11 @@ #endif +/** + * LWIP_DHCP_DISABLE_VENDOR_CLASS_ID==1: Do not add option 60 (Vendor Class Identifier) to DHCP packets + */ +#define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER 1 + /* ------------------------------------ ---------- AUTOIP options ---------- @@ -977,6 +982,7 @@ #define ESP_LWIP_SELECT 1 #define ESP_LWIP_LOCK 1 #define ESP_THREAD_PROTECTION 1 +#define ESP_IP_FORWARD 1 #ifdef CONFIG_LWIP_IPV6_AUTOCONFIG #define ESP_IPV6_AUTOCONFIG CONFIG_LWIP_IPV6_AUTOCONFIG diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index e7a26f0ff3c9..73a13d519f98 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -1,8 +1,16 @@ idf_build_get_property(idf_target IDF_TARGET) idf_build_get_property(python PYTHON) -idf_component_register(SRCS "esp_crt_bundle/esp_crt_bundle.c" - INCLUDE_DIRS "port/include" "mbedtls/include" "esp_crt_bundle/include" +set(mbedtls_srcs "") +set(mbedtls_include_dirs "port/include" "mbedtls/include") + +if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) + list(APPEND mbedtls_srcs "esp_crt_bundle/esp_crt_bundle.c") + list(APPEND mbedtls_include_dirs "esp_crt_bundle/include") +endif() + +idf_component_register(SRCS "${mbedtls_srcs}" + INCLUDE_DIRS "${mbedtls_include_dirs}" REQUIRES lwip PRIV_REQUIRES esp_pm soc ) @@ -15,9 +23,9 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) set(GENERATE_CERT_BUNDLEPY ${python} ${COMPONENT_DIR}/esp_crt_bundle/gen_crt_bundle.py) if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL) - list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem) + list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem ${DEFAULT_CRT_DIR}/cacrt_local.pem) elseif(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN) - list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem) + list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem ${DEFAULT_CRT_DIR}/cacrt_local.pem) list(APPEND args --filter ${DEFAULT_CRT_DIR}/cmn_crt_authorities.csv) endif() @@ -178,14 +186,17 @@ if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) endforeach() endif() -if(CONFIG_MBEDTLS_HARDWARE_MPI) - target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_mpi_exp_mod") -endif() - set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_LIBRARIES mbedtls) # Link mbedtls libraries to component library -target_link_libraries(${COMPONENT_LIB} PUBLIC ${mbedtls_targets}) +if(mbedtls_srcs STREQUAL "") + # For no sources in component library we must use "INTERFACE" + set(linkage_type INTERFACE) +else() + set(linkage_type PUBLIC) +endif() + +target_link_libraries(${COMPONENT_LIB} ${linkage_type} ${mbedtls_targets}) if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) # Link target (e.g. esp32s2) library to component library @@ -193,11 +204,11 @@ if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) set_property(TARGET mbedcrypto APPEND PROPERTY INTERFACE_LINK_LIBRARIES $) # The linker seems to be unable to resolve all the dependencies without increasing this set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 6) - target_link_libraries(${COMPONENT_LIB} PUBLIC ${target_lib}) + target_link_libraries(${COMPONENT_LIB} ${linkage_type} ${target_lib}) endif() # Link esp-cryptoauthlib to mbedtls if(CONFIG_ATCA_MBEDTLS_ECDSA) idf_component_get_property(cryptoauthlib esp-cryptoauthlib COMPONENT_LIB) - target_link_libraries(${COMPONENT_LIB} PUBLIC ${cryptoauthlib}) + target_link_libraries(${COMPONENT_LIB} ${linkage_type} ${cryptoauthlib}) endif() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 7b0f3c8a3ef7..b5770c1cb964 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -101,6 +101,8 @@ menu "mbedTLS" bool "Using dynamic TX/RX buffer" default n select MBEDTLS_ASYMMETRIC_CONTENT_LEN + # Dynamic buffer feature is not supported with DTLS + depends on !MBEDTLS_SSL_PROTO_DTLS && !MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH help Using dynamic TX/RX buffer. After enabling this option, mbedTLS will allocate TX buffer when need to send data and then free it if all data @@ -132,14 +134,14 @@ menu "mbedTLS" certificate and private key to ssl config object again. config MBEDTLS_DYNAMIC_FREE_CA_CERT - bool "Free SSL ca certificate after its usage" + bool "Free SSL CA certificate after its usage" default y depends on MBEDTLS_DYNAMIC_FREE_CONFIG_DATA help - Free ca certificate after its usage in the handshake process. + Free CA certificate after its usage in the handshake process. This option will decrease the heap footprint for the TLS handshake, but may lead to a problem: If the respective ssl object needs to perform the TLS handshake again, - the ca certificate should once again be registered to the ssl object. + the CA certificate should once again be registered to the ssl object. config MBEDTLS_DEBUG bool "Enable mbedTLS debugging" @@ -176,6 +178,111 @@ menu "mbedTLS" default 3 if MBEDTLS_DEBUG_LEVEL_DEBUG default 4 if MBEDTLS_DEBUG_LEVEL_VERBOSE + menu "mbedTLS v2.28.x related" + + config MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + bool "Variable SSL buffer length" + default n + help + This enables the SSL buffer to be resized automatically + based on the negotiated maximum fragment length in each direction. + + config MBEDTLS_ECDH_LEGACY_CONTEXT + bool "Use a backward compatible ECDH context (Experimental)" + default y + depends on MBEDTLS_ECDH_C && MBEDTLS_ECP_RESTARTABLE + help + Use the legacy ECDH context format. + Define this option only if you enable MBEDTLS_ECP_RESTARTABLE or if you + want to access ECDH context fields directly. + + config MBEDTLS_X509_TRUSTED_CERT_CALLBACK + bool "Enable trusted certificate callbacks" + default n + help + Enables users to configure the set of trusted certificates + through a callback instead of a linked list. + + See mbedTLS documentation for required API and more details. + + config MBEDTLS_SSL_CONTEXT_SERIALIZATION + bool "Enable serialization of the TLS context structures" + default n + help + Enable serialization of the TLS context structures + This is a local optimization in handling a single, potentially long-lived connection. + + See mbedTLS documentation for required API and more details. + Disabling this option will save some code size. + + config MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + bool "Keep peer certificate after handshake completion" + default y + depends on !MBEDTLS_DYNAMIC_FREE_PEER_CERT + help + Keep the peer's certificate after completion of the handshake. + Disabling this option will save about 4kB of heap and some code size. + + See mbedTLS documentation for required API and more details. + + menu "DTLS-based configurations" + visible if MBEDTLS_SSL_PROTO_DTLS + + config MBEDTLS_SSL_DTLS_CONNECTION_ID + bool "Support for the DTLS Connection ID extension" + depends on MBEDTLS_SSL_PROTO_DTLS + default n + help + Enable support for the DTLS Connection ID extension which allows to + identify DTLS connections across changes in the underlying transport. + The Connection ID extension is still in draft state. + Refer: version draft-ietf-tls-dtls-connection-id-05 + + config MBEDTLS_SSL_CID_IN_LEN_MAX + int "Maximum length of CIDs used for incoming DTLS messages" + default 32 + range 0 32 + depends on MBEDTLS_SSL_DTLS_CONNECTION_ID + help + Maximum length of CIDs used for incoming DTLS messages + + config MBEDTLS_SSL_CID_OUT_LEN_MAX + int "Maximum length of CIDs used for outgoing DTLS messages" + default 32 + range 0 32 + depends on MBEDTLS_SSL_DTLS_CONNECTION_ID + help + Maximum length of CIDs used for outgoing DTLS messages + + config MBEDTLS_SSL_CID_PADDING_GRANULARITY + int "Record plaintext padding (for DTLS 1.2)" + default 16 + range 0 32 + depends on MBEDTLS_SSL_DTLS_CONNECTION_ID + help + Controls the use of record plaintext padding when + using the Connection ID extension in DTLS 1.2. + + The padding will always be chosen so that the length of the + padded plaintext is a multiple of the value of this option. + + Notes: + A value of 1 means that no padding will be used for outgoing records. + On systems lacking division instructions, a power of two should be preferred. + + config MBEDTLS_SSL_DTLS_SRTP + bool "Enable support for negotiation of DTLS-SRTP (RFC 5764)" + depends on MBEDTLS_SSL_PROTO_DTLS + default n + help + Enable support for negotiation of DTLS-SRTP (RFC 5764) through the use_srtp extension. + + See mbedTLS documentation for required API and more details. + Disabling this option will save some code size. + + endmenu + + endmenu menu "Certificate Bundle" @@ -216,11 +323,13 @@ menu "mbedTLS" help Name of the custom certificate directory or file. This path is evaluated relative to the project root directory. - endmenu - - + config MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS + int "Maximum no of certificates allowed in certificate bundle" + default 200 + depends on MBEDTLS_CERTIFICATE_BUNDLE + endmenu config MBEDTLS_ECP_RESTARTABLE bool "Enable mbedTLS ecp restartable" @@ -277,7 +386,7 @@ menu "mbedTLS" Enable hardware accelerated multiple precision integer operations. Hardware accelerated multiplication, modulo multiplication, - and modular exponentiation for up to 4096 bit results. + and modular exponentiation for up to SOC_RSA_MAX_BIT_LEN bit results. These operations are used by RSA. diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index 465fb5c16f5c..afbc09163858 100644 --- a/components/mbedtls/component.mk +++ b/components/mbedtls/component.mk @@ -5,6 +5,8 @@ COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include esp_crt_bundle/include +COMPONENT_PRIV_INCLUDEDIRS := mbedtls/library + COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET) port/sha port/sha/parallel_engine port/aes port/aes/block port/md esp_crt_bundle COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o @@ -75,10 +77,6 @@ WRAP_FUNCTIONS = mbedtls_ssl_handshake_client_step \ COMPONENT_SRCDIRS += port/dynamic endif -ifdef CONFIG_MBEDTLS_HARDWARE_MPI -WRAP_FUNCTIONS += mbedtls_mpi_exp_mod -endif - ifneq ($(origin WRAP_FUNCTIONS),undefined) WRAP_ARGUMENT := -Wl,--wrap= COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) $(addprefix $(WRAP_ARGUMENT),$(WRAP_FUNCTIONS)) diff --git a/components/mbedtls/esp_crt_bundle/cacrt_all.pem b/components/mbedtls/esp_crt_bundle/cacrt_all.pem index a669b94fbd84..26f135040c26 100644 --- a/components/mbedtls/esp_crt_bundle/cacrt_all.pem +++ b/components/mbedtls/esp_crt_bundle/cacrt_all.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Wed Jan 23 04:12:09 2019 GMT +## Certificate data from Mozilla as of: Tue Apr 26 03:12:05 2022 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -13,8 +13,8 @@ ## an Apache+mod_ssl webserver for SSL client authentication. ## Just configure this file as the SSLCACertificateFile. ## -## Conversion done with mk-ca-bundle.pl version 1.27. -## SHA256: 18372117493b5b7ec006c31d966143fc95a9464a2b5f8d5188e23c5557b2292d +## Conversion done with mk-ca-bundle.pl version 1.29. +## SHA256: 34a54d5191775c1bd37be6cfd3f09e831e072555dc3a2e51f4a2c4b0f8ada5cc ## @@ -39,52 +39,6 @@ hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- -GlobalSign Root CA - R2 -======================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 -ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp -s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN -S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL -TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C -ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i -YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN -BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp -9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu -01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 -9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 -EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc -cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw -EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj -055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f -j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 -xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa -t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - Entrust.net Premium 2048 Secure Server CA ========================================= -----BEGIN CERTIFICATE----- @@ -130,30 +84,6 @@ Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -AddTrust External Root -====================== ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD -VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw -NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU -cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg -Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 -+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw -Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo -aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy -2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 -7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL -VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk -VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl -j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 -e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u -G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - Entrust Root Certification Authority ==================================== -----BEGIN CERTIFICATE----- @@ -180,87 +110,6 @@ W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -GeoTrust Global CA -================== ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw -MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo -BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet -8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc -T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU -vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q -zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 -d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 -mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p -XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm -Mw== ------END CERTIFICATE----- - -GeoTrust Universal CA -===================== ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 -MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu -Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t -JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e -RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs -7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d -8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V -qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga -Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB -Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu -KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 -ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 -XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB -hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 -qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL -oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK -xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF -KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 -DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK -xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU -p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI -P/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -GeoTrust Universal CA 2 -======================= ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 -MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg -SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 -DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 -j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q -JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a -QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 -WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP -20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn -ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC -SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG -8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 -+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E -BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ -4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ -mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq -A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg -Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP -pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d -FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp -gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm -X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - Comodo AAA Services root ======================== -----BEGIN CERTIFICATE----- @@ -285,38 +134,6 @@ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- -QuoVadis Root CA -================ ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE -ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz -MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp -cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD -EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk -J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL -F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL -YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen -AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w -PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y -ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 -MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj -YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs -ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW -Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu -BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw -FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 -tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo -fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul -LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x -gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi -5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi -5nrQNiOKSnQ2+Q== ------END CERTIFICATE----- - QuoVadis Root CA 2 ================== -----BEGIN CERTIFICATE----- @@ -404,26 +221,6 @@ s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ FL39vmwLAw== -----END CERTIFICATE----- -Sonera Class 2 Root CA -====================== ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG -U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw -NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh -IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 -/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT -dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG -f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P -tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH -nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT -XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt -0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI -cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph -Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx -EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH -llpwrN9M ------END CERTIFICATE----- - XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- @@ -496,36 +293,6 @@ KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- -Taiwan GRCA -=========== ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG -EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X -DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv -dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN -w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 -BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O -1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO -htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov -J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 -Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t -B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB -O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 -lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV -HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 -09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj -Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 -Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU -D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz -DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk -Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk -7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ -CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy -+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS ------END CERTIFICATE----- - DigiCert Assured ID Root CA =========================== -----BEGIN CERTIFICATE----- @@ -592,48 +359,6 @@ mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K -----END CERTIFICATE----- -Certplus Class 2 Primary CA -=========================== ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE -BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN -OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy -dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR -5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ -Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO -YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e -e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME -CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ -YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t -L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD -P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R -TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ -7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW -//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - -DST Root CA X3 -============== ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK -ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X -DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 -cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT -rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 -UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy -xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d -utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ -MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug -dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE -GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw -RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS -fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - SwissSign Gold CA - G2 ====================== -----BEGIN CERTIFICATE----- @@ -696,78 +421,6 @@ DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -GeoTrust Primary Certification Authority -======================================== ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx -CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ -cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN -b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 -nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge -RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt -tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI -hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K -Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN -NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa -Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG -1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -thawte Primary Root CA -====================== ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 -MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg -SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv -KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT -FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs -oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ -1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc -q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K -aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p -afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF -AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE -uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 -jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH -z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G5 -============================================================ ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln -biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh -dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz -j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD -Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r -fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ -BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv -Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG -SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ -X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE -KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC -Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE -ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - SecureTrust CA ============== -----BEGIN CERTIFICATE----- @@ -876,29 +529,6 @@ FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- -OISTE WISeKey Global Root GA CA -=============================== ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE -BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG -A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH -bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD -VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw -IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 -IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 -Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg -Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD -d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ -/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R -LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm -MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 -+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY -okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= ------END CERTIFICATE----- - Certigna ======== -----BEGIN CERTIFICATE----- @@ -921,50 +551,6 @@ PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -Deutsche Telekom Root CA 2 -========================== ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT -RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG -A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 -MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G -A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS -b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 -bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI -KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY -AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK -Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV -jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV -HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr -E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy -zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 -rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G -dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - -Cybertrust Global Root -====================== ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li -ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 -MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD -ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW -0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL -AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin -89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT -8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 -MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G -A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO -lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi -5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 -hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T -X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - ePKI Root Certification Authority ================================= -----BEGIN CERTIFICATE----- @@ -1016,136 +602,6 @@ vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD -----END CERTIFICATE----- -GeoTrust Primary Certification Authority - G3 -============================================= ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 -IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz -NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo -YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT -LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j -K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE -c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C -IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu -dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr -2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 -cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE -Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s -t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -thawte Primary Root CA - G2 -=========================== ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC -VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu -IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg -Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV -MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG -b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt -IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS -LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 -8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU -mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN -G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K -rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -thawte Primary Root CA - G3 -=========================== ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w -ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD -VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG -A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At -P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC -+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY -7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW -vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ -KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK -A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC -8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm -er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G2 -============================================= ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu -Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 -OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl -b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG -BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc -KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ -EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m -ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 -npaqBA+K ------END CERTIFICATE----- - -VeriSign Universal Root Certification Authority -=============================================== ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj -1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP -MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 -9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I -AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR -tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G -CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O -a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 -Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx -Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx -P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P -wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 -mJO37M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G4 -============================================================ ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC -VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 -b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz -ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU -cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo -b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 -Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz -rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw -HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u -Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD -A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx -AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - NetLock Arany (Class Gold) Főtanúsítvány ======================================== -----BEGIN CERTIFICATE----- @@ -1170,38 +626,6 @@ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -Staat der Nederlanden Root CA - G2 -================================== ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE -CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC -TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l -ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ -5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn -vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj -CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil -e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR -OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI -CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 -48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi -trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 -qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB -AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC -ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA -A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz -+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj -f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN -kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk -CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF -URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb -CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h -oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV -IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm -66+KAQ== ------END CERTIFICATE----- - Hongkong Post Root CA 1 ======================= -----BEGIN CERTIFICATE----- @@ -1353,82 +777,6 @@ Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- -Chambers of Commerce Root - 2008 -================================ ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy -Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl -ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF -EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl -cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA -XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj -h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ -ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk -NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g -D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 -lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ -0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 -EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI -G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ -BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh -bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh -bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC -CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH -AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 -wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH -3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU -RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 -M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 -YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF -9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK -zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG -nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ ------END CERTIFICATE----- - -Global Chambersign Root - 2008 -============================== ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx -NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg -Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ -QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf -VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf -XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 -ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB -/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA -TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M -H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe -Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF -HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB -AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT -BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE -BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm -aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm -aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp -1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 -dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG -/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 -ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s -dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg -9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH -foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du -qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr -P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq -c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- - Go Daddy Root Certificate Authority - G2 ======================================== -----BEGIN CERTIFICATE----- @@ -1700,27 +1048,6 @@ OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== -----END CERTIFICATE----- -Trustis FPS Root CA -=================== ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG -EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 -IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV -BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ -RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk -H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa -cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt -o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA -AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd -BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c -GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC -yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P -8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV -l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl -iB6XzCGcKQENZetX2fNXlrtIzYE= ------END CERTIFICATE----- - Buypass Class 2 Root CA ======================= -----BEGIN CERTIFICATE----- @@ -1803,30 +1130,6 @@ P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== -----END CERTIFICATE----- -EE Certification Centre Root CA -=============================== ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy -dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw -MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB -UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy -ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM -TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 -rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw -93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN -P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ -MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF -BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj -xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM -lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU -3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM -dcGWxZ0= ------END CERTIFICATE----- - D-TRUST Root Class 3 CA 2 2009 ============================== -----BEGIN CERTIFICATE----- @@ -2360,20 +1663,6 @@ HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu 9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= -----END CERTIFICATE----- -GlobalSign ECC Root CA - R4 -=========================== ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb -R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD -EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb -R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD -EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl -OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P -AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV -MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF -JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= ------END CERTIFICATE----- - GlobalSign ECC Root CA - R5 =========================== -----BEGIN CERTIFICATE----- @@ -2389,36 +1678,6 @@ uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- -Staat der Nederlanden Root CA - G3 -================================== ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE -CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC -TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l -ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y -olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t -x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy -EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K -Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur -mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 -1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp -07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo -FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE -41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu -yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD -U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq -KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 -v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA -8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b -8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r -mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq -1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI -JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV -tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= ------END CERTIFICATE----- - Staat der Nederlanden EV Root CA ================================ -----BEGIN CERTIFICATE----- @@ -2583,37 +1842,6 @@ kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- -Certinomis - Root CA -==================== ------BEGIN CERTIFICATE----- -MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK -Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg -LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx -EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD -ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos -P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo -d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap -z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00 -8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x -RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE -6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t -FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV -PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH -i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj -YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I -6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF -AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV -WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw -Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX -lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ -y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9 -Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng -DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi -I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM -cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr -hkIGuUE= ------END CERTIFICATE----- - OISTE WISeKey Global Root GB CA =============================== -----BEGIN CERTIFICATE----- @@ -2876,37 +2104,6 @@ MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- -LuxTrust Global Root 2 -====================== ------BEGIN CERTIFICATE----- -MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG -A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh -bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW -MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm -Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2 -xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC -wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm -1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm -FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF -wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/ -a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U -ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ -MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB -/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5 -Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT -+Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ -FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN -H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW -7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu -ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA -VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR -TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt -/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc -7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I -iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr ------END CERTIFICATE----- - TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 ============================================= -----BEGIN CERTIFICATE----- @@ -3187,96 +2384,6 @@ AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- -GTS Root R1 -=========== ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG -EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv -b3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG -A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx -9vaMf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7r -aKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnW -r4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqM -LnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly -4cpk9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr -06zqkUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 -wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om -3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNu -JLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEM -BQADggIBADiWCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 -d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6ZXPYfcX3v73sv -fuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZRgyFmxhE+885H7pwoHyXa/6xm -ld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9b -gsiG1eGZbYwE8na6SfZu6W0eX6DvJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq -4BjFbkerQUIpm/ZgDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWEr -tXvM+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyyF62ARPBo -pY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9SQ98POyDGCBDTtWTurQ0 -sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdwsE3PYJ/HQcu51OyLemGhmW/HGY0dVHLql -CFF1pkgl ------END CERTIFICATE----- - -GTS Root R2 -=========== ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG -EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv -b3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG -A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTuk -k3LvCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo -7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWI -m8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5Gm -dFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbu -ak7MkogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscsz -cTJGr61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW -Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73Vululycsl -aVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy -5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEM -BQADggIBALZp8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT -vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiTz9D2PGcDFWEJ -+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiApJiS4wGWAqoC7o87xdFtCjMw -c3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvbpxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3Da -WsYDQvTtN6LwG1BUSw7YhN4ZKJmBR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5r -n/WkhLx3+WuXrD5RRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56Gtmwfu -Nmsk0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC5AwiWVIQ -7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiFizoHCBy69Y9Vmhh1fuXs -gWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLnyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ld -o/DUhgkC ------END CERTIFICATE----- - -GTS Root R3 -=========== ------BEGIN CERTIFICATE----- -MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV -UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg -UjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE -ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUU -Rout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24Cej -QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP -0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFukfCPAlaUs3L6JbyO5o91lAFJekazInXJ0 -glMLfalAvWhgxeG4VDvBNhcl2MG9AjEAnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOa -KaqW04MjyaR7YbPMAuhd ------END CERTIFICATE----- - -GTS Root R4 -=========== ------BEGIN CERTIFICATE----- -MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV -UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg -UjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE -ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa -6zzuhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqj -QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV -2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0CMRw3J5QdCHojXohw0+WbhXRIjVhLfoI -N+4Zba3bssx9BzT1YBkstTTZbyACMANxsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11x -zPKwTdb+mciUqXWi4w== ------END CERTIFICATE----- - UCA Global G2 Root ================== -----BEGIN CERTIFICATE----- @@ -3369,3 +2476,872 @@ tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= -----END CERTIFICATE----- + +emSign Root CA - G1 +=================== +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET +MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl +ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx +ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk +aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN +LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 +cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW +DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ +6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH +hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 +vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q +NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q ++Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih +U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +emSign ECC Root CA - G3 +======================= +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG +A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg +MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 +MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 +ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc +58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr +MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D +CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 +jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +emSign Root CA - C1 +=================== +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx +EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp +Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD +ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up +ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ +Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX +OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V +I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms +lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ +XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp +/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 +NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 +wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ +BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +emSign ECC Root CA - C3 +======================= +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG +A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF +Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD +ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd +6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 +SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA +B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA +MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU +ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 3 +======================= +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG +A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK +Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2 +MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv +bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX +SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz +iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf +jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim +5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe +sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj +0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/ +JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u +y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h ++bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG +xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID +AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN +AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw +W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld +y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov ++BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc +eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw +9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7 +nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY +hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB +60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq +dBb9HxEGmpv0 +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G4 +========================================= +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu +bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1 +dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT +AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D +umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV +3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds +8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ +e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7 +ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X +xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV +7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW +Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n +MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q +jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht +7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK +YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt +jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+ +m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW +RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA +JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G ++TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT +kcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +Microsoft ECC Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND +IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4 +MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6 +thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB +eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM ++Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf +Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR +eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +Microsoft RSA Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg +UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw +NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u +MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml +7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e +S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7 +1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+ +dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F +yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS +MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr +lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ +0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ +ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og +6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80 +dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk ++ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex +/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy +AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW +ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE +7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT +c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D +5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +e-Szigno Root CA 2017 +===================== +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw +DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt +MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa +Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE +CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp +Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx +s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv +vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA +tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO +svxyqltZ+efcMQ== +-----END CERTIFICATE----- + +certSIGN Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw +EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy +MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH +TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05 +N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk +abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg +wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp +dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh +ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732 +jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf +95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc +z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL +iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud +DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB +ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB +/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5 +8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5 +BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW +atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU +Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M +NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N +0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +Trustwave Global Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV +UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 +ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0xNzA4MjMxOTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJV +UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 +ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALldUShLPDeS0YLOvR29 +zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0XznswuvCAAJWX/NKSqIk4cXGIDtiLK0thAf +LdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4Bq +stTnoApTAbqOl5F2brz81Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9o +WN0EACyW80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotPJqX+ +OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1lRtzuzWniTY+HKE40 +Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfwhI0Vcnyh78zyiGG69Gm7DIwLdVcE +uE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm ++9jaJXLE9gCxInm943xZYkqcBW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqj +ifLJS3tBEW1ntwiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1UdDwEB/wQEAwIB +BjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W0OhUKDtkLSGm+J1WE2pIPU/H +PinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfeuyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0H +ZJDmHvUqoai7PF35owgLEQzxPy0QlG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla +4gt5kNdXElE1GYhBaCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5R +vbbEsLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPTMaCm/zjd +zyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qequ5AvzSxnI9O4fKSTx+O +856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxhVicGaeVyQYHTtgGJoC86cnn+OjC/QezH +Yj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu +3R3y4G5OBVixwJAWKqQ9EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP +29FpHOTKyeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +Trustwave Global ECC P256 Certification Authority +================================================= +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy +dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1 +NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH77bOYj +43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoNFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqm +P62jQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt +0UrrdaVKEJmzsaGLSvcwCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjz +RM4q3wghDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +Trustwave Global ECC P384 Certification Authority +================================================= +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy +dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4 +NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGvaDXU1CDFH +Ba5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr +/TklZvFe/oyujUF5nQlgziip04pt89ZF1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV +HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn +ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl +CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw== +-----END CERTIFICATE----- + +NAVER Global Root Certification Authority +========================================= +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG +A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD +DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4 +NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT +UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb +UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW ++j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7 +XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2 +aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4 +Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z +VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B +A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai +cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy +YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV +HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK +21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB +jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx +hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg +E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH +D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ +A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY +qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG +I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg +kpzNNIaRkPpkUZ3+/uul9XXeifdy +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM SERVIDORES SEGUROS +=================================== +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF +UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy +NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4 +MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt +UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB +QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2 +LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG +SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD +zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c= +-----END CERTIFICATE----- + +GlobalSign Root R46 +=================== +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv +b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX +BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es +CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/ +r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje +2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt +bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj +K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4 +12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on +ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls +eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9 +vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM +BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy +gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92 +CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm +OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq +JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye +qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz +nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7 +DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3 +QEUxeCp6 +-----END CERTIFICATE----- + +GlobalSign Root E46 +=================== +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT +AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg +RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV +BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB +jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj +QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL +gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk +vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ +CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +GLOBALTRUST 2020 +================ +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx +IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT +VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh +BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy +MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi +D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO +VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM +CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm +fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA +A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR +JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG +DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU +clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ +mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud +IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw +4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 +iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS +8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 +HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS +vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 +oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF +YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl +gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== +-----END CERTIFICATE----- + +ANF Secure Server Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNVBAUTCUc2MzI4 +NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lv +bjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNVBAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3Qg +Q0EwHhcNMTkwOTA0MTAwMDM4WhcNMzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEw +MQswCQYDVQQGEwJFUzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQw +EgYDVQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9vdCBDQTCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCjcqQZAZ2cC4Ffc0m6p6zz +BE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9qyGFOtibBTI3/TO80sh9l2Ll49a2pcbnv +T1gdpd50IJeh7WhM3pIXS7yr/2WanvtH2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcv +B2VSAKduyK9o7PQUlrZXH1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXse +zx76W0OLzc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyRp1RM +VwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQzW7i1o0TJrH93PB0j +7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/SiOL9V8BY9KHcyi1Swr1+KuCLH5z +JTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJnLNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe +8TZBAQIvfXOn3kLMTOmJDVb3n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVO +Hj1tyRRM4y5Bu8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEATh65isagmD9uw2nAalxJ +UqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzx +j6ptBZNscsdW699QIyjlRRA96Gejrw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDt +dD+4E5UGUcjohybKpFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM +5gf0vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjqOknkJjCb +5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ/zo1PqVUSlJZS2Db7v54 +EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ92zg/LFis6ELhDtjTO0wugumDLmsx2d1H +hk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGy +g77FGr8H6lnco4g175x2MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3 +r5+qPeoott7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +Certum EC-384 CA +================ +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ +TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2 +MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh +dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq +vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn +iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo +ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0 +QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +Certum Trusted Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6MQswCQYDVQQG +EwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0g +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0Ew +HhcNMTgwMzE2MTIxMDEzWhcNNDMwMzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMY +QXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZn0EGze2jusDbCSzBfN8p +fktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/qp1x4EaTByIVcJdPTsuclzxFUl6s1wB52 +HO8AU5853BSlLCIls3Jy/I2z5T4IHhQqNwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2 +fJmItdUDmj0VDT06qKhF8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGt +g/BKEiJ3HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGamqi4 +NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi7VdNIuJGmj8PkTQk +fVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSFytKAQd8FqKPVhJBPC/PgP5sZ0jeJ +P/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0PqafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSY +njYJdmZm/Bo/6khUHL4wvYBQv3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHK +HRzQ+8S1h9E6Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQADggIBAEii1QAL +LtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4WxmB82M+w85bj/UvXgF2Ez8s +ALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvozMrnadyHncI013nR03e4qllY/p0m+jiGPp2K +h2RX5Rc64vmNueMzeMGQ2Ljdt4NR5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8 +CYyqOhNf6DR5UMEQGfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA +4kZf5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq0Uc9Nneo +WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj +6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTMqJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmT +OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck +bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +TunTrust Root CA +================ +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG +A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj +dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw +NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD +ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz +2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b +bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7 +NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd +gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW +VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f +Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ +juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas +DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS +VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI +04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl +0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd +Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY +YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp +adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x +xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP +jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM +MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z +ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r +AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +HARICA TLS RSA Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG +EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz +OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl +bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB +IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN +JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu +a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y +Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K +5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv +dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR +0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH +GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm +haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ +CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU +EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq +QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD +QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR +j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5 +vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0 +qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6 +Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/ +PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn +kf3/W9b3raYvAwtt41dU63ZTGI0RmLo= +-----END CERTIFICATE----- + +HARICA TLS ECC Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH +UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD +QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX +DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj +IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv +b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l +AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b +ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW +0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi +rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw +CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1Ud +DgQWBBRlzeurNR4APn7VdMActHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4w +gZswgZgGBFUdIAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABCAG8AbgBhAG4A +bwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAwADEANzAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9miWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL +4QjbEwj4KKE1soCzC1HA01aajTNFSa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDb +LIpgD7dvlAceHabJhfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1il +I45PVf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZEEAEeiGaP +cjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV1aUsIC+nmCjuRfzxuIgA +LI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2tCsvMo2ebKHTEm9caPARYpoKdrcd7b/+A +lun4jWq9GJAd/0kakFI3ky88Al2CdgtR5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH +9IBk9W6VULgRfhVwOEqwf9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpf +NIbnYrX9ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNKGbqE +ZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +vTrus ECC Root CA +================= +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMwRzELMAkGA1UE +BhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBS +b290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDczMTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAa +BgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+c +ToL0v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUde4BdS49n +TPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIwV53dVvHH4+m4SVBrm2nDb+zDfSXkV5UT +QJtS0zvzQBm8JsctBp61ezaf9SXUY2sAAjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQL +YgmRWAD5Tfs0aNoJrSEGGJTO +-----END CERTIFICATE----- + +vTrus Root CA +============= +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQELBQAwQzELMAkG +A1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xFjAUBgNVBAMTDXZUcnVzIFJv +b3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMxMDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoG +A1UEChMTaVRydXNDaGluYSBDby4sTHRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZots +SKYcIrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykUAyyNJJrI +ZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+GrPSbcKvdmaVayqwlHeF +XgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z98Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KA +YPxMvDVTAWqXcoKv8R1w6Jz1717CbMdHflqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70 +kLJrxLT5ZOrpGgrIDajtJ8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2 +AXPKBlim0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZNpGvu +/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQUqqzApVg+QxMaPnu +1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHWOXSuTEGC2/KmSNGzm/MzqvOmwMVO +9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMBAAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYg +scasGrz2iTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AgEAKbqSSaet8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1jbhd47F18iMjr +jld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvMKar5CKXiNxTKsbhm7xqC5PD4 +8acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIivTDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJn +xDHO2zTlJQNgJXtxmOTAGytfdELSS8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554Wg +icEFOwE30z9J4nfrI8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4 +sEb9b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNBUvupLnKW +nyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1PTi07NEPhmg4NpGaXutIc +SkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929vensBxXVsFy6K2ir40zSbofitzmdHxghm+H +l3s= +-----END CERTIFICATE----- + +ISRG Root X2 +============ +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQswCQYDVQQGEwJV +UzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElT +UkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVT +MSkwJwYDVQQKEyBJbnRlcm5ldCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNS +RyBSb290IFgyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H +ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9ItgKbppb +d9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZIzj0EAwMDaAAwZQIwe3lORlCEwkSHRhtF +cP9Ymd70/aTSVaYgLXTWNLxBo1BfASdWtL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5 +U6VR5CmD1/iQMVtCnwr1/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +HiPKI Root CA - G1 +================== +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xGzAZBgNVBAMMEkhpUEtJ +IFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRaFw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYT +AlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kg +Um9vdCBDQSAtIEcxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0 +o9QwqNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twvVcg3Px+k +wJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6lZgRZq2XNdZ1AYDgr/SE +YYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnzQs7ZngyzsHeXZJzA9KMuH5UHsBffMNsA +GJZMoYFL3QRtU6M9/Aes1MU3guvklQgZKILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfd +hSi8MEyr48KxRURHH+CKFgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj +1jOXTyFjHluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDry+K4 +9a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ/W3c1pzAtH2lsN0/ +Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgMa/aOEmem8rJY5AIJEzypuxC00jBF +8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQD +AgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqcSE5XCV0vrPSl +tJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6FzaZsT0pPBWGTMpWmWSBUdGSquE +wx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9TcXzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07Q +JNBAsNB1CI69aO4I1258EHBGG3zgiLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv +5wiZqAxeJoBF1PhoL5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+Gpz +jLrFNe85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wrkkVbbiVg +hUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+vhV4nYWBSipX3tUZQ9rb +yltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQUYDksswBVLuT1sw5XxJFBAJw/6KXf6vb/ +yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYDVQQLExtHbG9i +YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgwMTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9i +YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkW +ymOxuYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/+wpu+74zyTyjhNUwCgYI +KoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147bmF0774BxL4YSFlhgjICICadVGNA3jdg +UM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +GTS Root R1 +=========== +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7raKb0 +xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnWr4+w +B7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXW +nOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk +9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zq +kUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92wO1A +K/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om3xPX +V2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDW +cfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQAD +ggIBAJ+qQibbC5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuyh6f88/qBVRRi +ClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM47HLwEXWdyzRSjeZ2axfG34ar +J45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8JZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYci +NuaCp+0KueIHoI17eko8cdLiA6EfMgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5me +LMFrUKTX5hgUvYU/Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJF +fbdT6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ0E6yove+ +7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm2tIMPNuzjsmhDYAPexZ3 +FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bbbP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3 +gm3c +-----END CERTIFICATE----- + +GTS Root R2 +=========== +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo7JUl +e3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWIm8Wb +a96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS ++LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7M +kogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJG +r61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RWIr9q +S34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73VululycslaVNV +J1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy5okL +dWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQAD +ggIBAB/Kzt3HvqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyCB19m3H0Q/gxh +swWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2uNmSRXbBoGOqKYcl3qJfEycel +/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMgyALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVn +jWQye+mew4K6Ki3pHrTgSAai/GevHyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y5 +9PYjJbigapordwj6xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M +7YNRTOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924SgJPFI/2R8 +0L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV7LXTWtiBmelDGDfrs7vR +WGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjW +HYbL +-----END CERTIFICATE----- + +GTS Root R3 +=========== +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi +MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMw +HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ +R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24CejQjBA +MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP0/Eq +Er24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azT +L818+FsuVbu/3ZL3pAzcMeGiAjEA/JdmZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV +11RZt+cRLInUue4X +-----END CERTIFICATE----- + +GTS Root R4 +=========== +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi +MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQw +HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ +R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqjQjBA +MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV2Py1 +PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/C +r8deVl5c1RxYIigL9zC2L7F8AjEA8GE8p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh +4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +Telia Root CA v2 +================ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNVBAYT +AkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2 +MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQK +DBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ7 +6zBqAMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9vVYiQJ3q +9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9lRdU2HhE8Qx3FZLgmEKn +pNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTODn3WhUidhOPFZPY5Q4L15POdslv5e2QJl +tI5c0BE0312/UqeBAMN/mUWZFdUXyApT7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW +5olWK8jjfN7j/4nlNW4o6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNr +RBH0pUPCTEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6WT0E +BXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63RDolUK5X6wK0dmBR4 +M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZIpEYslOqodmJHixBTB0hXbOKSTbau +BcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGjYzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7W +xy+G2CQ5MB0GA1UdDgQWBBRyrOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi0f6X+J8wfBj5 +tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMMA8iZGok1GTzTyVR8qPAs5m4H +eW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBSSRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+C +y748fdHif64W1lZYudogsYMVoe+KTTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygC +QMez2P2ccGrGKMOF6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15 +h2Er3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMtTy3EHD70 +sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pTVmBds9hCG1xLEooc6+t9 +xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAWysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQ +raVplI/owd8k+BsHMYeB2F326CjYSlKArBPuUBQemMc= +-----END CERTIFICATE----- + +D-TRUST BR Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7 +dPYSzuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0QVK5buXu +QqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/VbNafAkl1bK6CKBrqx9t +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2JyX3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFWwKrY7RjEsK70Pvom +AjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHVdWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +D-TRUST EV Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8 +ZRCC/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rDwpdhQntJ +raOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3OqQo5FD4pPfsazK2/umL +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2V2X3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR +AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- diff --git a/components/mbedtls/esp_crt_bundle/cacrt_local.pem b/components/mbedtls/esp_crt_bundle/cacrt_local.pem new file mode 100644 index 000000000000..3633ed16193a --- /dev/null +++ b/components/mbedtls/esp_crt_bundle/cacrt_local.pem @@ -0,0 +1,33 @@ +## +## Local CA Root Certificates +## +## Local CA Root Certificates that gets appended to "cacrt_all.pem" + + +## letsencrypt has generated a cross signed certificate with DST ROOT CA X3 +## for compatibility after the expiry of the certificate. +## The new certificate has the ISSUER name as DST Root CA X3. +## Thus, the handshake fails if esp_crt_bundle does not find the +## respective name in the crt_bundle. +## Keeping this certificate for compatibility reasons. +## This will be removed once the cross-signed certificate expires in Sep 2024. + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- diff --git a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c index 89f3fb0b63f3..65e2fa925d5f 100644 --- a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c +++ b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c @@ -17,7 +17,6 @@ #include #include "esp_crt_bundle.h" #include "esp_log.h" -#include "esp_err.h" #define BUNDLE_HEADER_OFFSET 2 #define CRT_HEADER_OFFSET 4 @@ -157,27 +156,56 @@ int esp_crt_verify_callback(void *buf, mbedtls_x509_crt *crt, int depth, uint32_ /* Initialize the bundle into an array so we can do binary search for certs, the bundle generated by the python utility is already presorted by subject name */ -static esp_err_t esp_crt_bundle_init(const uint8_t *x509_bundle) +static esp_err_t esp_crt_bundle_init(const uint8_t *x509_bundle, size_t bundle_size) { - s_crt_bundle.num_certs = (x509_bundle[0] << 8) | x509_bundle[1]; - s_crt_bundle.crts = calloc(s_crt_bundle.num_certs, sizeof(x509_bundle)); + if (bundle_size < BUNDLE_HEADER_OFFSET + CRT_HEADER_OFFSET) { + ESP_LOGE(TAG, "Invalid certificate bundle"); + return ESP_ERR_INVALID_ARG; + } - if (s_crt_bundle.crts == NULL) { + uint16_t num_certs = (x509_bundle[0] << 8) | x509_bundle[1]; + if (num_certs > CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS) { + ESP_LOGE(TAG, "No. of certs in the certificate bundle = %d exceeds\n" + "Max allowed certificates in the certificate bundle = %d\n" + "Please update the menuconfig option with appropriate value", num_certs, CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS); + return ESP_ERR_INVALID_ARG; + } + + const uint8_t **crts = calloc(num_certs, sizeof(x509_bundle)); + if (crts == NULL) { ESP_LOGE(TAG, "Unable to allocate memory for bundle"); return ESP_ERR_NO_MEM; } const uint8_t *cur_crt; + /* This is the maximum region that is allowed to access */ + const uint8_t *bundle_end = x509_bundle + bundle_size; cur_crt = x509_bundle + BUNDLE_HEADER_OFFSET; - for (int i = 0; i < s_crt_bundle.num_certs; i++) { - s_crt_bundle.crts[i] = cur_crt; - + for (int i = 0; i < num_certs; i++) { + crts[i] = cur_crt; + if (cur_crt + CRT_HEADER_OFFSET > bundle_end) { + ESP_LOGE(TAG, "Invalid certificate bundle"); + free(crts); + return ESP_ERR_INVALID_ARG; + } size_t name_len = cur_crt[0] << 8 | cur_crt[1]; size_t key_len = cur_crt[2] << 8 | cur_crt[3]; cur_crt = cur_crt + CRT_HEADER_OFFSET + name_len + key_len; } + if (cur_crt > bundle_end) { + ESP_LOGE(TAG, "Invalid certificate bundle"); + free(crts); + return ESP_ERR_INVALID_ARG; + } + + /* The previous crt bundle is only updated when initialization of the + * current crt_bundle is successful */ + /* Free previous crt_bundle */ + free(s_crt_bundle.crts); + s_crt_bundle.num_certs = num_certs; + s_crt_bundle.crts = crts; return ESP_OK; } @@ -186,7 +214,7 @@ esp_err_t esp_crt_bundle_attach(void *conf) esp_err_t ret = ESP_OK; // If no bundle has been set by the user then use the bundle embedded in the binary if (s_crt_bundle.crts == NULL) { - ret = esp_crt_bundle_init(x509_crt_imported_bundle_bin_start); + ret = esp_crt_bundle_init(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start); } if (ret != ESP_OK) { @@ -217,9 +245,7 @@ void esp_crt_bundle_detach(mbedtls_ssl_config *conf) } } -void esp_crt_bundle_set(const uint8_t *x509_bundle) +esp_err_t esp_crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size) { - // Free any previously used bundle - free(s_crt_bundle.crts); - esp_crt_bundle_init(x509_bundle); + return esp_crt_bundle_init(x509_bundle, bundle_size); } diff --git a/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h b/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h index 33fb98b9969c..49069185b3ab 100644 --- a/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h +++ b/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h @@ -1,21 +1,14 @@ -// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ESP_CRT_BUNDLE_H_ #define _ESP_CRT_BUNDLE_H_ +#include "esp_err.h" #include "mbedtls/ssl.h" #ifdef __cplusplus @@ -52,13 +45,19 @@ void esp_crt_bundle_detach(mbedtls_ssl_config *conf); /** * @brief Set the default certificate bundle used for verification * - * Overrides the default certificate bundle. In most use cases the bundle should be + * Overrides the default certificate bundle only in case of successful initialization. In most use cases the bundle should be * set through menuconfig. The bundle needs to be sorted by subject name since binary search is * used to find certificates. * * @param[in] x509_bundle A pointer to the certificate bundle. + * + * @param[in] bundle_size Size of the certificate bundle in bytes. + * + * @return + * - ESP_OK if adding certificates was successful. + * - Other if an error occured or an action must be taken by the calling process. */ -void esp_crt_bundle_set(const uint8_t *x509_bundle); +esp_err_t esp_crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size); #ifdef __cplusplus diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 6465247f6716..8b0e35f2ad47 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 6465247f67167518b8813ae2faaf422704e4b1a3 +Subproject commit 8b0e35f2ad477fcc2a267cf434528024b8499085 diff --git a/components/mbedtls/port/aes/dma/esp_aes.c b/components/mbedtls/port/aes/dma/esp_aes.c index a0b9af4ca5ed..893b0556db15 100644 --- a/components/mbedtls/port/aes/dma/esp_aes.c +++ b/components/mbedtls/port/aes/dma/esp_aes.c @@ -31,6 +31,7 @@ #include "esp_intr_alloc.h" #include "driver/periph_ctrl.h" #include "esp_log.h" +#include "esp_attr.h" #include "soc/lldesc.h" #include "esp_heap_caps.h" #include "sys/param.h" @@ -79,8 +80,28 @@ static esp_pm_lock_handle_t s_pm_sleep_lock; #endif #endif +#if SOC_PSRAM_DMA_CAPABLE + +#if (CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B) +#define DCACHE_LINE_SIZE 16 +#elif (CONFIG_ESP32S2_DATA_CACHE_LINE_32B || CONFIG_ESP32S3_DATA_CACHE_LINE_32B) +#define DCACHE_LINE_SIZE 32 +#elif CONFIG_ESP32S3_DATA_CACHE_LINE_64B +#define DCACHE_LINE_SIZE 64 +#endif //(CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B) + +#endif //SOC_PSRAM_DMA_CAPABLE + static const char *TAG = "esp-aes"; +/* These are static due to: + * * Must be in DMA capable memory, so stack is not a safe place to put them + * * To avoid having to malloc/free them for every DMA operation + */ +static DRAM_ATTR lldesc_t s_stream_in_desc; +static DRAM_ATTR lldesc_t s_stream_out_desc; +static DRAM_ATTR uint8_t s_stream_in[AES_BLOCK_BYTES]; +static DRAM_ATTR uint8_t s_stream_out[AES_BLOCK_BYTES]; static inline void esp_aes_wait_dma_done(lldesc_t *output) { @@ -289,15 +310,12 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char /* Encrypt/decrypt the input using DMA */ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out) { - lldesc_t stream_in_desc, stream_out_desc; lldesc_t *in_desc_head = NULL, *out_desc_head = NULL; lldesc_t *out_desc_tail = NULL; /* pointer to the final output descriptor */ lldesc_t *block_desc = NULL, *block_in_desc = NULL, *block_out_desc = NULL; size_t lldesc_num; - uint8_t stream_in[16] = {}; unsigned stream_bytes = len % AES_BLOCK_BYTES; // bytes which aren't in a full block unsigned block_bytes = len - stream_bytes; // bytes which are in a full block - unsigned char *non_icache_input = NULL; unsigned blocks = (block_bytes / AES_BLOCK_BYTES) + ((stream_bytes > 0) ? 1 : 0); bool use_intr = false; bool input_needs_realloc = false; @@ -319,12 +337,12 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, if (block_bytes > 0) { /* Flush cache if input in external ram */ -#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) +#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) if (esp_ptr_external_ram(input)) { - Cache_WriteBack_All(); + Cache_WriteBack_Addr((uint32_t)input, len); } if (esp_ptr_external_ram(output)) { - if (((intptr_t)(output) & 0xF) != 0) { + if ((((intptr_t)(output) & (DCACHE_LINE_SIZE - 1)) != 0) || (block_bytes % DCACHE_LINE_SIZE != 0)) { // Non aligned ext-mem buffer output_needs_realloc = true; } @@ -348,7 +366,7 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, lldesc_num = lldesc_get_required_num(block_bytes); /* Allocate both in and out descriptors to save a malloc/free per function call */ - block_desc = heap_caps_malloc(sizeof(lldesc_t) * lldesc_num * 2, MALLOC_CAP_DMA); + block_desc = heap_caps_calloc(lldesc_num * 2, sizeof(lldesc_t), MALLOC_CAP_DMA); if (block_desc == NULL) { ESP_LOGE(TAG, "Failed to allocate memory"); ret = -1; @@ -359,30 +377,38 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, block_out_desc = block_desc + lldesc_num; lldesc_setup_link(block_in_desc, input, block_bytes, 0); - lldesc_setup_link(block_out_desc, output, block_bytes, 0); + //Limit max inlink descriptor length to be 16 byte aligned, require for EDMA + lldesc_setup_link_constrained(block_out_desc, output, block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED, 0); out_desc_tail = &block_out_desc[lldesc_num - 1]; } /* Any leftover bytes which are appended as an additional DMA list */ if (stream_bytes > 0) { - memcpy(stream_in, input + block_bytes, stream_bytes); - lldesc_setup_link(&stream_in_desc, stream_in, AES_BLOCK_BYTES, 0); - lldesc_setup_link(&stream_out_desc, stream_out, AES_BLOCK_BYTES, 0); + memset(&s_stream_in_desc, 0, sizeof(lldesc_t)); + memset(&s_stream_out_desc, 0, sizeof(lldesc_t)); + + memset(s_stream_in, 0, AES_BLOCK_BYTES); + memset(s_stream_out, 0, AES_BLOCK_BYTES); + + memcpy(s_stream_in, input + block_bytes, stream_bytes); + + lldesc_setup_link(&s_stream_in_desc, s_stream_in, AES_BLOCK_BYTES, 0); + lldesc_setup_link(&s_stream_out_desc, s_stream_out, AES_BLOCK_BYTES, 0); if (block_bytes > 0) { /* Link with block descriptors*/ - block_in_desc[lldesc_num - 1].empty = (uint32_t)&stream_in_desc; - block_out_desc[lldesc_num - 1].empty = (uint32_t)&stream_out_desc; + block_in_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_in_desc; + block_out_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_out_desc; } - out_desc_tail = &stream_out_desc; + out_desc_tail = &s_stream_out_desc; } // block buffers are sent to DMA first, unless there aren't any - in_desc_head = (block_bytes > 0) ? block_in_desc : &stream_in_desc; - out_desc_head = (block_bytes > 0) ? block_out_desc : &stream_out_desc; + in_desc_head = (block_bytes > 0) ? block_in_desc : &s_stream_in_desc; + out_desc_head = (block_bytes > 0) ? block_out_desc : &s_stream_out_desc; #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT) @@ -408,21 +434,21 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, aes_hal_transform_dma_start(blocks); esp_aes_dma_wait_complete(use_intr, out_desc_tail); -#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) +#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) if (block_bytes > 0) { if (esp_ptr_external_ram(output)) { - Cache_Invalidate_DCache_All(); + Cache_Invalidate_Addr((uint32_t)output, block_bytes); } } #endif aes_hal_transform_dma_finish(); if (stream_bytes > 0) { - memcpy(output + block_bytes, stream_out, stream_bytes); + memcpy(output + block_bytes, s_stream_out, stream_bytes); + memcpy(stream_out, s_stream_out, AES_BLOCK_BYTES); } cleanup: - free(non_icache_input); free(block_desc); return ret; } diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index dcbfac4ce9c6..81a5bfebd64d 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -490,7 +490,7 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx, /* Due to restrictions in the hardware (e.g. need to do the whole conversion in one go), some combinations of inputs are not supported */ static bool esp_aes_gcm_input_support_hw_accel(size_t length, const unsigned char *aad, size_t aad_len, - const unsigned char *input, unsigned char *output) + const unsigned char *input, unsigned char *output, uint8_t *stream_in) { bool support_hw_accel = true; @@ -505,10 +505,15 @@ static bool esp_aes_gcm_input_support_hw_accel(size_t length, const unsigned cha } else if (!esp_ptr_dma_capable(output) && length > 0) { /* output in non internal DMA memory */ support_hw_accel = false; + } else if (!esp_ptr_dma_capable(stream_in)) { + /* Stream in (and therefor other descriptors and buffers that come from the stack) + in non internal DMA memory */ + support_hw_accel = false; } else if (length == 0) { support_hw_accel = false; } + return support_hw_accel; } @@ -562,7 +567,7 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, unsigned block_bytes = aad_len - stream_bytes; // bytes which are in a full block /* Due to hardware limition only certain cases are fully supported in HW */ - if (!esp_aes_gcm_input_support_hw_accel(length, aad, aad_len, input, output)) { + if (!esp_aes_gcm_input_support_hw_accel(length, aad, aad_len, input, output, stream_in)) { return esp_aes_gcm_crypt_and_tag_partial_hw(ctx, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag); } diff --git a/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c b/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c index e2231eeb6cdd..8b224b4ca1a4 100644 --- a/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c +++ b/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "esp_crypto_shared_gdma.h" @@ -106,7 +98,7 @@ static esp_err_t crypto_shared_gdma_init(void) return ESP_OK; err: - ESP_LOGE(TAG, "Failed to acquire DMA channel, Err=0x%X", ret); + ESP_LOGE(TAG, "Failed to acquire DMA channel, Err=%d", ret); tx_channel = NULL; rx_channel = NULL; diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c index 373264452bce..b8620e05f602 100644 --- a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "esp_mbedtls_dynamic_impl.h" @@ -266,12 +258,12 @@ int esp_mbedtls_add_tx_buffer(mbedtls_ssl_context *ssl, size_t buffer_len) esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); if (!esp_buf) { - ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); + ESP_LOGE(TAG, "alloc(%zu bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; goto exit; } - ESP_LOGV(TAG, "add out buffer %d bytes @ %p", buffer_len, esp_buf->buf); + ESP_LOGV(TAG, "add out buffer %zu bytes @ %p", buffer_len, esp_buf->buf); esp_mbedtls_init_ssl_buf(esp_buf, buffer_len); init_tx_buffer(ssl, esp_buf->buf); @@ -350,13 +342,13 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl) ssl->in_hdr = msg_head; ssl->in_len = msg_head + 3; - if ((ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_hdr_len(ssl))) != 0) { + if ((ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl))) != 0) { if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { ESP_LOGD(TAG, "mbedtls_ssl_fetch_input reads data times out"); } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { ESP_LOGD(TAG, "mbedtls_ssl_fetch_input wants to read more data"); } else { - ESP_LOGE(TAG, "mbedtls_ssl_fetch_input error=-0x%x", -ret); + ESP_LOGE(TAG, "mbedtls_ssl_fetch_input error=%d", -ret); } goto exit; @@ -424,7 +416,16 @@ int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl) /** * The previous processing is just skipped, so "ssl->in_msglen = 0" */ - if (!ssl->in_msgtype) { + if (!ssl->in_msgtype +#if defined(MBEDTLS_SSL_SRV_C) + /** + * The ssl server read ClientHello manually without mbedtls_ssl_read_record(), so in_msgtype is not set and is zero. + * ClientHello has been processed and rx buffer should be freed. + * After processing ClientHello, the ssl state has been changed to MBEDTLS_SSL_SERVER_HELLO. + */ + && !(ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && ssl->state == MBEDTLS_SSL_SERVER_HELLO) +#endif + ) { goto exit; } @@ -531,27 +532,3 @@ void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl) } } #endif /* CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT */ - -#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT -void esp_mbedtls_free_peer_cert(mbedtls_ssl_context *ssl) -{ - if (ssl->session_negotiate->peer_cert) { - mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert ); - mbedtls_free( ssl->session_negotiate->peer_cert ); - ssl->session_negotiate->peer_cert = NULL; - } -} - -bool esp_mbedtls_ssl_is_rsa(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { - return true; - } else { - return false; - } -} -#endif diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h index 8f74097d5d54..5dac6dd188e1 100644 --- a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h @@ -1,20 +1,14 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _DYNAMIC_IMPL_H_ #define _DYNAMIC_IMPL_H_ #include +#include #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" #include "mbedtls/platform.h" @@ -32,7 +26,7 @@ TRACE_CHECK(_fn, "state"); \ \ if ((_ret = _fn) != 0) { \ - ESP_LOGV(TAG, "\"%s\" result is -0x%x", # _fn, -_ret); \ + ESP_LOGV(TAG, "\"%s\" result is %d", # _fn, -_ret); \ TRACE_CHECK(_fn, "fail"); \ return _ret; \ } \ @@ -52,7 +46,7 @@ struct esp_mbedtls_ssl_buf { unsigned char buf[]; }; -#define SSL_BUF_HEAD_OFFSET_SIZE offsetof(struct esp_mbedtls_ssl_buf, buf) +#define SSL_BUF_HEAD_OFFSET_SIZE ((int)offsetof(struct esp_mbedtls_ssl_buf, buf)) void esp_mbedtls_free_buf(unsigned char *buf); @@ -92,10 +86,4 @@ void esp_mbedtls_free_keycert_key(mbedtls_ssl_context *ssl); void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl); #endif -#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT -void esp_mbedtls_free_peer_cert(mbedtls_ssl_context *ssl); - -bool esp_mbedtls_ssl_is_rsa(mbedtls_ssl_context *ssl); -#endif - #endif /* _DYNAMIC_IMPL_H_ */ diff --git a/components/mbedtls/port/dynamic/esp_ssl_cli.c b/components/mbedtls/port/dynamic/esp_ssl_cli.c index 94ed064d6d8f..ddad9b44d312 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_cli.c +++ b/components/mbedtls/port/dynamic/esp_ssl_cli.c @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and - +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include #include "esp_mbedtls_dynamic_impl.h" @@ -72,19 +64,6 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) if (!ssl->keep_current_message) { CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); } -#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT - /** - * If current ciphersuite is RSA, we should free peer' - * certificate at step MBEDTLS_SSL_CLIENT_KEY_EXCHANGE. - * - * And if it is other kinds of ciphersuite, we can free - * peer certificate here. - */ - - if (esp_mbedtls_ssl_is_rsa(ssl) == false) { - esp_mbedtls_free_peer_cert(ssl); - } -#endif } break; case MBEDTLS_SSL_CERTIFICATE_REQUEST: @@ -133,12 +112,6 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); - } else { -#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT - if (esp_mbedtls_ssl_is_rsa(ssl) == true) { - esp_mbedtls_free_peer_cert(ssl); - } -#endif } break; case MBEDTLS_SSL_CERTIFICATE_VERIFY: diff --git a/components/mbedtls/port/dynamic/esp_ssl_srv.c b/components/mbedtls/port/dynamic/esp_ssl_srv.c index bc96dcfab076..eadd2e411787 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_srv.c +++ b/components/mbedtls/port/dynamic/esp_ssl_srv.c @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and - +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "esp_mbedtls_dynamic_impl.h" @@ -20,6 +12,24 @@ int __wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); static const char *TAG = "SSL Server"; +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA +/** + * Check if ciphersuite uses rsa key exchange methods. + */ +static bool ssl_ciphersuite_uses_rsa_key_ex(mbedtls_ssl_context *ssl) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->handshake->ciphersuite_info; + + if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { + return true; + } else { + return false; + } +} +#endif + static int manage_resource(mbedtls_ssl_context *ssl, bool add) { int state = add ? ssl->state : ssl->state - 1; @@ -73,7 +83,13 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA - esp_mbedtls_free_keycert_cert(ssl); + /** + * Not free keycert->cert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. + * For ssl server will use keycert->cert to parse client key exchange. + */ + if (!ssl_ciphersuite_uses_rsa_key_ex(ssl)) { + esp_mbedtls_free_keycert_cert(ssl); + } #endif } break; @@ -85,8 +101,14 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA esp_mbedtls_free_dhm(ssl); - esp_mbedtls_free_keycert_key(ssl); - esp_mbedtls_free_keycert(ssl); + /** + * Not free keycert->key and keycert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. + * For ssl server will use keycert->key to parse client key exchange. + */ + if (!ssl_ciphersuite_uses_rsa_key_ex(ssl)) { + esp_mbedtls_free_keycert_key(ssl); + esp_mbedtls_free_keycert(ssl); + } #endif } break; @@ -122,6 +144,18 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); } else { CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + /** + * Free keycert after MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. + * For ssl server will use keycert->cert and keycert->key to parse client key exchange. + */ + if (ssl_ciphersuite_uses_rsa_key_ex(ssl)) { + esp_mbedtls_free_keycert_cert(ssl); + esp_mbedtls_free_keycert_key(ssl); + esp_mbedtls_free_keycert(ssl); + } +#endif } break; case MBEDTLS_SSL_CERTIFICATE_VERIFY: @@ -136,10 +170,6 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); } else { CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); - -#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT - esp_mbedtls_free_peer_cert(ssl); -#endif } break; case MBEDTLS_SSL_CLIENT_FINISHED: diff --git a/components/mbedtls/port/dynamic/esp_ssl_tls.c b/components/mbedtls/port/dynamic/esp_ssl_tls.c index 7ae5bc108772..e64bc2e8c2ef 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_tls.c +++ b/components/mbedtls/port/dynamic/esp_ssl_tls.c @@ -1,15 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "esp_mbedtls_dynamic_impl.h" @@ -46,20 +39,149 @@ static int rx_done(mbedtls_ssl_context *ssl) return 1; } - ESP_LOGD(TAG, "RX left %d bytes", ssl->in_msglen); + ESP_LOGD(TAG, "RX left %zu bytes", ssl->in_msglen); return 0; } +static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); + mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + +static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) +{ + memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_init( &handshake->fin_md5 ); + mbedtls_sha1_init( &handshake->fin_sha1 ); + mbedtls_md5_starts_ret( &handshake->fin_md5 ); + mbedtls_sha1_starts_ret( &handshake->fin_sha1 ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_init( &handshake->fin_sha256 ); + mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_init( &handshake->fin_sha512 ); + mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + handshake->update_checksum = ssl_update_checksum_start; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); +#endif + +#if defined(MBEDTLS_DHM_C) + mbedtls_dhm_init( &handshake->dhm_ctx ); +#endif +#if defined(MBEDTLS_ECDH_C) + mbedtls_ecdh_init( &handshake->ecdh_ctx ); +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + mbedtls_ecjpake_init( &handshake->ecjpake_ctx ); +#if defined(MBEDTLS_SSL_CLI_C) + handshake->ecjpake_cache = NULL; + handshake->ecjpake_cache_len = 0; +#endif +#endif + +#if defined(MBEDTLS_SSL_ECP_RESTARTABLE) + mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx ); +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ + !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + mbedtls_pk_init( &handshake->peer_pubkey ); +#endif +} + +static int ssl_handshake_init( mbedtls_ssl_context *ssl ) +{ + /* Clear old handshake information if present */ + if( ssl->transform_negotiate ) + mbedtls_ssl_transform_free( ssl->transform_negotiate ); + if( ssl->session_negotiate ) + mbedtls_ssl_session_free( ssl->session_negotiate ); + if( ssl->handshake ) + mbedtls_ssl_handshake_free( ssl ); + + /* + * Either the pointers are now NULL or cleared properly and can be freed. + * Now allocate missing structures. + */ + if( ssl->transform_negotiate == NULL ) + { + ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) ); + } + + if( ssl->session_negotiate == NULL ) + { + ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) ); + } + + if( ssl->handshake == NULL ) + { + ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) ); + } + + /* All pointers should exist and can be directly freed without issue */ + if( ssl->handshake == NULL || + ssl->transform_negotiate == NULL || + ssl->session_negotiate == NULL ) + { + ESP_LOGD(TAG, "alloc() of ssl sub-contexts failed"); + + mbedtls_free( ssl->handshake ); + mbedtls_free( ssl->transform_negotiate ); + mbedtls_free( ssl->session_negotiate ); + + ssl->handshake = NULL; + ssl->transform_negotiate = NULL; + ssl->session_negotiate = NULL; + + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + /* Initialize structures */ + mbedtls_ssl_session_init( ssl->session_negotiate ); + mbedtls_ssl_transform_init( ssl->transform_negotiate ); + ssl_handshake_params_init( ssl->handshake ); + + return( 0 ); +} + int __wrap_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf) { - CHECK_OK(__real_mbedtls_ssl_setup(ssl, conf)); + ssl->conf = conf; + CHECK_OK(ssl_handshake_init(ssl)); - mbedtls_free(ssl->out_buf); ssl->out_buf = NULL; CHECK_OK(esp_mbedtls_setup_tx_buffer(ssl)); - mbedtls_free(ssl->in_buf); ssl->in_buf = NULL; esp_mbedtls_setup_rx_buffer(ssl); @@ -91,7 +213,7 @@ int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t ESP_LOGD(TAG, "fail, the connection indicated an EOF"); return 0; } else if (ret < 0) { - ESP_LOGD(TAG, "fail, error=-0x%x", -ret); + ESP_LOGD(TAG, "fail, error=%d", -ret); return ret; } ESP_LOGD(TAG, "end"); diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index ab789782467e..7378a7926221 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -67,8 +67,7 @@ static inline size_t bits_to_words(size_t bits) /* Return the number of words actually used to represent an mpi number. */ -int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ); -extern int __real_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ); +#if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) static size_t mpi_words(const mbedtls_mpi *mpi) { @@ -80,6 +79,7 @@ static size_t mpi_words(const mbedtls_mpi *mpi) return 0; } +#endif //(MBEDTLS_MPI_EXP_MOD_ALT || MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) /** * @@ -182,6 +182,8 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi return ret; } +#if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) + #ifdef ESP_MPI_USE_MONT_EXP /* * Return the most significant one-bit. @@ -272,22 +274,26 @@ static int mpi_montgomery_exp_calc( mbedtls_mpi *Z, const mbedtls_mpi *X, const * (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) * */ -int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ) +static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ) { int ret = 0; + + mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */ + mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */ + mbedtls_mpi_uint Mprime; + size_t x_words = mpi_words(X); size_t y_words = mpi_words(Y); size_t m_words = mpi_words(M); - /* "all numbers must be the same length", so choose longest number as cardinal length of operation... */ size_t num_words = esp_mpi_hardware_words(MAX(m_words, MAX(x_words, y_words))); - mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */ - mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */ - mbedtls_mpi_uint Mprime; + if (num_words * 32 > SOC_RSA_MAX_BIT_LEN) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } if (mbedtls_mpi_cmp_int(M, 0) <= 0 || (M->p[0] & 1) == 0) { return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; @@ -301,14 +307,6 @@ int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbed return mbedtls_mpi_lset(Z, 1); } - if (num_words * 32 > SOC_RSA_MAX_BIT_LEN) { -#ifdef CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI - return __real_mbedtls_mpi_exp_mod(Z, X, Y, M, _Rinv); -#else - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; -#endif - } - /* Determine RR pointer, either _RR for cached value or local RR_new */ if (_Rinv == NULL) { @@ -355,6 +353,32 @@ int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbed return ret; } +#endif /* (MBEDTLS_MPI_EXP_MOD_ALT || MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) */ + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *_RR ) +{ + int ret; +#if defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) + /* Try hardware API first and then fallback to software */ + ret = esp_mpi_exp_mod( X, A, E, N, _RR ); + if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) { + ret = mbedtls_mpi_exp_mod_soft( X, A, E, N, _RR ); + } +#else + /* Hardware approach */ + ret = esp_mpi_exp_mod( X, A, E, N, _RR ); +#endif + /* Note: For software only approach, it gets handled in mbedTLS library. + This file is not part of build objects for that case */ + + return ret; +} + #if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words); @@ -434,7 +458,18 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi return ret; } +int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ) +{ + mbedtls_mpi _B; + mbedtls_mpi_uint p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); +} /* Deal with the case when X & Y are too long for the hardware unit, by splitting one operand into two halves. diff --git a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c index 258f05094e60..62af3e9a7e7f 100644 --- a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c +++ b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c @@ -224,7 +224,7 @@ int esp_ds_rsa_sign( void *ctx, } if ((ret = (rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES), sig ))) != 0) { - ESP_LOGE(TAG, "Error in pkcs1_v15 encoding, returned %02x", ret); + ESP_LOGE(TAG, "Error in pkcs1_v15 encoding, returned %d", ret); heap_caps_free(signature); return -1; } @@ -238,14 +238,14 @@ int esp_ds_rsa_sign( void *ctx, s_esp_ds_hmac_key_id, &esp_ds_ctx); if (ds_r != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %02x ", ds_r); + ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %d ", ds_r); heap_caps_free(signature); return -1; } ds_r = esp_ds_finish_sign((void *)signature, esp_ds_ctx); if (ds_r != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_finish sign, returned %02X ", ds_r); + ESP_LOGE(TAG, "Error in esp_ds_finish sign, returned %d ", ds_r); heap_caps_free(signature); return -1; } diff --git a/components/mbedtls/port/include/mbedtls/bignum.h b/components/mbedtls/port/include/mbedtls/bignum.h index a317c4560609..4f84bed74076 100644 --- a/components/mbedtls/port/include/mbedtls/bignum.h +++ b/components/mbedtls/port/include/mbedtls/bignum.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include_next "mbedtls/bignum.h" @@ -77,4 +69,31 @@ void esp_mpi_release_hardware(void); */ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M); +#if CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI + +/** + * @brief Perform a sliding-window exponentiation: X = A^E mod N + * + * @param X The destination MPI. This must point to an initialized MPI. + * @param A The base of the exponentiation. + * This must point to an initialized MPI. + * @param E The exponent MPI. This must point to an initialized MPI. + * @param N The base for the modular reduction. This must point to an + * initialized MPI. + * @param _RR A helper MPI depending solely on \p N which can be used to + * speed-up multiple modular exponentiations for the same value + * of \p N. This may be \c NULL. If it is not \c NULL, it must + * point to an initialized MPI. + * + * @return \c 0 if successful. + * @return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * @return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or + * even, or if \c E is negative. + * @return Another negative error code on different kinds of failures. + * + */ +int mbedtls_mpi_exp_mod_soft(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR); + +#endif // CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI + #endif // CONFIG_MBEDTLS_HARDWARE_MPI diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index f36ebf9bc753..607d35ffc69c 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -1,12 +1,13 @@ /** * - * \brief Default mbedTLS configuration options for esp-idf + * \brief Default mbedTLS configuration options for ESP-IDF * * This set of compile-time options may be used to enable * or disable features selectively, and reduce the global * memory footprint. - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + */ +/* + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -20,8 +21,6 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef ESP_CONFIG_H @@ -153,15 +152,22 @@ #undef MBEDTLS_MD5_ALT #endif -/* The following MPI (bignum) functions have ESP32 hardware support. - For exponential mod, both software and hardware implementation - will be compiled. If CONFIG_MBEDTLS_HARDWARE_MPI is enabled, mod APIs - will be wrapped to use hardware implementation. -*/ -#undef MBEDTLS_MPI_EXP_MOD_ALT +/* The following MPI (bignum) functions have hardware support. + * Uncommenting these macros will use the hardware-accelerated + * implementations. + */ #ifdef CONFIG_MBEDTLS_HARDWARE_MPI +#ifdef CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI + /* Prefer hardware and fallback to software */ + #define MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK +#else + /* Hardware only mode */ + #define MBEDTLS_MPI_EXP_MOD_ALT +#endif #define MBEDTLS_MPI_MUL_MPI_ALT #else +#undef MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK +#undef MBEDTLS_MPI_EXP_MOD_ALT #undef MBEDTLS_MPI_MUL_MPI_ALT #endif @@ -303,18 +309,54 @@ * * \note This option only works with the default software implementation of * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT + * and MBEDTLS_ECDH_LEGACY_CONTEXT. */ #ifdef CONFIG_MBEDTLS_ECP_RESTARTABLE #define MBEDTLS_ECP_RESTARTABLE #endif +/** + * \def MBEDTLS_ECDH_LEGACY_CONTEXT + * + * Use a backward compatible ECDH context. + * + * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context + * defined in `ecdh.h`). For most applications, the choice of format makes + * no difference, since all library functions can work with either format, + * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. + + * The new format used when this option is disabled is smaller + * (56 bytes on a 32-bit platform). In future versions of the library, it + * will support alternative implementations of ECDH operations. + * The new format is incompatible with applications that access + * context fields directly and with restartable ECP operations. + * + * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you + * want to access ECDH context fields directly. Otherwise you should + * comment out this macro definition. + * + * This option has no effect if #MBEDTLS_ECDH_C is not enabled. + * + * \note This configuration option is experimental. Future versions of the + * library may modify the way the ECDH context layout is configured + * and may modify the layout of the new context type. + */ +#ifdef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT +#define MBEDTLS_ECDH_LEGACY_CONTEXT +#endif + /** * \def MBEDTLS_CMAC_C * * Enable the CMAC (Cipher-based Message Authentication Code) mode for block * ciphers. * + * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying + * implementation of the CMAC algorithm is provided by an alternate + * implementation, that alternate implementation may opt to not support + * AES-192 or 3DES as underlying block ciphers for the CMAC operation. + * * Module: library/cmac.c * * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C @@ -332,6 +374,7 @@ * * Comment macros to disable the curve and functions for it */ +/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ #ifdef CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED #define MBEDTLS_ECP_DP_SECP192R1_ENABLED #else @@ -387,12 +430,12 @@ #else #undef MBEDTLS_ECP_DP_BP512R1_ENABLED #endif +/* Montgomery curves (supporting ECP) */ #ifdef CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED #define MBEDTLS_ECP_DP_CURVE25519_ENABLED #else #undef MBEDTLS_ECP_DP_CURVE25519_ENABLED #endif - #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED #undef MBEDTLS_ECP_DP_CURVE448_ENABLED #endif @@ -420,7 +463,7 @@ * may result in a compromise of the long-term signing key. This is avoided by * the deterministic variant. * - * Requires: MBEDTLS_HMAC_DRBG_C + * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C * * Comment this macro to disable deterministic ECDSA. */ @@ -661,7 +704,7 @@ * * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C * * This enables the following ciphersuites (if other requisites are * enabled as well): @@ -689,7 +732,7 @@ * * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C * * This enables the following ciphersuites (if other requisites are * enabled as well): @@ -843,6 +886,69 @@ */ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID + * + * Enable support for the DTLS Connection ID extension + * (version draft-ietf-tls-dtls-connection-id-05, + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) + * which allows to identify DTLS connections across changes + * in the underlying transport. + * + * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, + * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`. + * See the corresponding documentation for more information. + * + * \warning The Connection ID extension is still in draft state. + * We make no stability promises for the availability + * or the shape of the API controlled by this option. + * + * The maximum lengths of outgoing and incoming CIDs can be configured + * through the options + * - MBEDTLS_SSL_CID_OUT_LEN_MAX + * - MBEDTLS_SSL_CID_IN_LEN_MAX. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment to enable the Connection ID extension. + */ +#ifdef CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID +#define MBEDTLS_SSL_DTLS_CONNECTION_ID +#else +#undef MBEDTLS_SSL_DTLS_CONNECTION_ID +#endif + +/** + * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION + * + * Enable serialization of the TLS context structures, through use of the + * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). + * + * This pair of functions allows one side of a connection to serialize the + * context associated with the connection, then free or re-use that context + * while the serialized state is persisted elsewhere, and finally deserialize + * that state to a live context for resuming read/write operations on the + * connection. From a protocol perspective, the state of the connection is + * unaffected, in particular this is entirely transparent to the peer. + * + * Note: this is distinct from TLS session resumption, which is part of the + * protocol and fully visible by the peer. TLS session resumption enables + * establishing new connections associated to a saved session with shorter, + * lighter handshakes, while context serialization is a local optimization in + * handling a single, potentially long-lived connection. + * + * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are + * saved after the handshake to allow for more efficient serialization, so if + * you don't need this feature you'll save RAM by disabling it. + * + * Comment to disable the context serialization APIs. + */ +#ifdef CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION +#define MBEDTLS_SSL_CONTEXT_SERIALIZATION +#else +#undef MBEDTLS_SSL_CONTEXT_SERIALIZATION +#endif + /** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC * * Enable support for Encrypt-then-MAC, RFC 7366. @@ -867,8 +973,8 @@ /** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET * - * Enable support for Extended Master Secret, aka Session Hash - * (draft-ietf-tls-session-hash-02). + * Enable support for RFC 7627: Session Hash and Extended Master Secret + * Extension. * * This was introduced as "the proper fix" to the Triple Handshake familiy of * attacks, but it is recommended to always use it (even if you disable @@ -890,7 +996,8 @@ /** * \def MBEDTLS_SSL_FALLBACK_SCSV * - * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). + * Enable support for RFC 7507: Fallback Signaling Cipher Suite Value (SCSV) + * for Preventing Protocol Downgrade Attacks. * * For servers, it is recommended to always enable this, unless you support * only one version of TLS, or know for sure that none of your clients @@ -904,6 +1011,32 @@ */ #define MBEDTLS_SSL_FALLBACK_SCSV +/** + * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * + * This option controls the availability of the API mbedtls_ssl_get_peer_cert() + * giving access to the peer's certificate after completion of the handshake. + * + * Unless you need mbedtls_ssl_peer_cert() in your application, it is + * recommended to disable this option for reduced RAM usage. + * + * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still + * defined, but always returns \c NULL. + * + * \note This option has no influence on the protection against the + * triple handshake attack. Even if it is disabled, Mbed TLS will + * still ensure that certificates do not change during renegotiation, + * for exaple by keeping a hash of the peer's certificate. + * + * Comment this macro to disable storing the peer's certificate + * after the handshake. + */ +#ifdef CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#else +#undef MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#endif + /** * \def MBEDTLS_SSL_PROTO_TLS1 * @@ -928,6 +1061,9 @@ * Requires: MBEDTLS_MD5_C * MBEDTLS_SHA1_C * + * \deprecated This option is deprecated and will be removed in a future + * version of Mbed TLS. + * * Comment this macro to disable support for SSL 3.0 */ #ifdef CONFIG_MBEDTLS_SSL_PROTO_SSL3 @@ -1085,6 +1221,41 @@ #undef MBEDTLS_SSL_DTLS_HELLO_VERIFY #endif +/** + * \def MBEDTLS_SSL_DTLS_SRTP + * + * Enable support for negotiation of DTLS-SRTP (RFC 5764) + * through the use_srtp extension. + * + * \note This feature provides the minimum functionality required + * to negotiate the use of DTLS-SRTP and to allow the derivation of + * the associated SRTP packet protection key material. + * In particular, the SRTP packet protection itself, as well as the + * demultiplexing of RTP and DTLS packets at the datagram layer + * (see Section 5 of RFC 5764), are not handled by this feature. + * Instead, after successful completion of a handshake negotiating + * the use of DTLS-SRTP, the extended key exporter API + * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement + * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 + * (this is implemented in the SSL example programs). + * The resulting key should then be passed to an SRTP stack. + * + * Setting this option enables the runtime API + * mbedtls_ssl_conf_dtls_srtp_protection_profiles() + * through which the supported DTLS-SRTP protection + * profiles can be configured. You must call this API at + * runtime if you wish to negotiate the use of DTLS-SRTP. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment this to enable support for use_srtp extension. + */ +#ifdef CONFIG_MBEDTLS_SSL_PROTO_DTLS +#define MBEDTLS_SSL_DTLS_SRTP +#else +#undef MBEDTLS_SSL_DTLS_SRTP +#endif + /** * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE * @@ -1169,6 +1340,21 @@ #define MBEDTLS_SSL_TRUNCATED_HMAC /** + * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + * + * When this option is enabled, the SSL buffer will be resized automatically + * based on the negotiated maximum fragment length in each direction. + * + * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + */ +#if defined MBEDTLS_SSL_MAX_FRAGMENT_LENGTH && CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH +#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH +#else +#undef MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH +#endif + +/** + * * \def MBEDTLS_VERSION_FEATURES * * Allow run-time checking of compile-time enabled features. Thus allowing users @@ -1634,7 +1820,9 @@ * This module is used by the following key exchanges: * ECDHE-ECDSA * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, + * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a + * short Weierstrass curve. */ #ifdef CONFIG_MBEDTLS_ECDSA_C #define MBEDTLS_ECDSA_C @@ -1712,11 +1900,11 @@ /** * \def MBEDTLS_GCM_C * - * Enable the Galois/Counter Mode (GCM) for AES. + * Enable the Galois/Counter Mode (GCM). * * Module: library/gcm.c * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C * * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other * requisites are enabled as well. @@ -2316,6 +2504,29 @@ #undef MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION #endif +/** + * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + * + * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` + * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure + * the set of trusted certificates through a callback instead of a linked + * list. + * + * This is useful for example in environments where a large number of trusted + * certificates is present and storing them in a linked list isn't efficient + * enough, or when the set of trusted certificates changes frequently. + * + * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and + * `mbedtls_ssl_conf_ca_cb()` for more information. + * + * Uncomment to enable trusted certificate callbacks. + */ +#ifdef CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK +#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK +#else +#undef MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK +#endif + /** * \def MBEDTLS_X509_CSR_WRITE_C * @@ -2376,6 +2587,51 @@ */ #define MBEDTLS_SSL_IN_CONTENT_LEN CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN +/** \def MBEDTLS_SSL_CID_IN_LEN_MAX + * + * The maximum length of CIDs used for incoming DTLS messages. + * + */ +#ifdef CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID +#define MBEDTLS_SSL_CID_IN_LEN_MAX CONFIG_MBEDTLS_SSL_CID_IN_LEN_MAX +#else +#undef MBEDTLS_SSL_CID_IN_LEN_MAX +#endif + + +/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX + * + * The maximum length of CIDs used for outgoing DTLS messages. + * + */ +#ifdef CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID +#define MBEDTLS_SSL_CID_OUT_LEN_MAX CONFIG_MBEDTLS_SSL_CID_OUT_LEN_MAX +#else +#undef MBEDTLS_SSL_CID_OUT_LEN_MAX +#endif + +/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * when using the Connection ID extension in DTLS 1.2. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + * + */ +#ifdef CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID +#define MBEDTLS_SSL_CID_PADDING_GRANULARITY CONFIG_MBEDTLS_SSL_CID_PADDING_GRANULARITY +#else +#undef MBEDTLS_SSL_CID_PADDING_GRANULARITY +#endif + + /** \def MBEDTLS_SSL_OUT_CONTENT_LEN * * Maximum outgoing fragment length in bytes. @@ -2409,6 +2665,10 @@ * default. At the time of writing, there is no practical attack on the use * of SHA-1 in handshake signatures, hence this option is turned on by default * for compatibility with existing peers. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. */ #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index 91f098411c52..9f390c41d5ac 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/components/mbedtls/port/sha/dma/sha.c @@ -31,6 +31,7 @@ #include "esp_log.h" #include "esp_crypto_lock.h" +#include "esp_attr.h" #include "soc/lldesc.h" #include "soc/cache_memory.h" #include "soc/periph_defs.h" @@ -64,6 +65,12 @@ const static char *TAG = "esp-sha"; +/* These are static due to: + * * Must be in DMA capable memory, so stack is not a safe place to put them + * * To avoid having to malloc/free them for every DMA operation + */ +static DRAM_ATTR lldesc_t s_dma_descr_input; +static DRAM_ATTR lldesc_t s_dma_descr_buf; void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state) { @@ -219,7 +226,7 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, return 0; } -#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) +#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) if (esp_ptr_external_ram(input)) { Cache_WriteBack_Addr((uint32_t)input, ilen); } @@ -273,34 +280,35 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u const void *buf, uint32_t buf_len, bool is_first_block) { int ret = 0; - lldesc_t dma_descr_input = {}; - lldesc_t dma_descr_buf = {}; lldesc_t *dma_descr_head; size_t num_blks = (ilen + buf_len) / block_length(sha_type); + memset(&s_dma_descr_input, 0, sizeof(lldesc_t)); + memset(&s_dma_descr_buf, 0, sizeof(lldesc_t)); + /* DMA descriptor for Memory to DMA-SHA transfer */ if (ilen) { - dma_descr_input.length = ilen; - dma_descr_input.size = ilen; - dma_descr_input.owner = 1; - dma_descr_input.eof = 1; - dma_descr_input.buf = (uint8_t *)input; - dma_descr_head = &dma_descr_input; + s_dma_descr_input.length = ilen; + s_dma_descr_input.size = ilen; + s_dma_descr_input.owner = 1; + s_dma_descr_input.eof = 1; + s_dma_descr_input.buf = (uint8_t *)input; + dma_descr_head = &s_dma_descr_input; } /* Check after input to overide head if there is any buf*/ if (buf_len) { - dma_descr_buf.length = buf_len; - dma_descr_buf.size = buf_len; - dma_descr_buf.owner = 1; - dma_descr_buf.eof = 1; - dma_descr_buf.buf = (uint8_t *)buf; - dma_descr_head = &dma_descr_buf; + s_dma_descr_buf.length = buf_len; + s_dma_descr_buf.size = buf_len; + s_dma_descr_buf.owner = 1; + s_dma_descr_buf.eof = 1; + s_dma_descr_buf.buf = (uint8_t *)buf; + dma_descr_head = &s_dma_descr_buf; } /* Link DMA lists */ if (buf_len && ilen) { - dma_descr_buf.eof = 0; - dma_descr_buf.empty = (uint32_t)(&dma_descr_input); + s_dma_descr_buf.eof = 0; + s_dma_descr_buf.empty = (uint32_t)(&s_dma_descr_input); } if (esp_sha_dma_start(dma_descr_head) != ESP_OK) { diff --git a/components/mbedtls/port/sha/esp_sha.c b/components/mbedtls/port/sha/esp_sha.c index 0940ed132022..9310875ac022 100644 --- a/components/mbedtls/port/sha/esp_sha.c +++ b/components/mbedtls/port/sha/esp_sha.c @@ -1,16 +1,8 @@ -// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -100,6 +92,6 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns } #endif //SOC_SHA_SUPPORT_SHA512 - ESP_LOGE(TAG, "SHA type %d not supported", sha_type); + ESP_LOGE(TAG, "SHA type %d not supported", (int)sha_type); abort(); } diff --git a/components/mbedtls/test/test_aes.c b/components/mbedtls/test/test_aes.c index 2c89d3f370d3..5f63444c02d3 100644 --- a/components/mbedtls/test/test_aes.c +++ b/components/mbedtls/test/test_aes.c @@ -12,6 +12,9 @@ #include "esp_timer.h" #include "esp_heap_caps.h" #include "test_utils.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" static const uint8_t key_256[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, @@ -296,7 +299,7 @@ TEST_CASE("mbedtls CFB-128 AES-256 test", "[aes]") free(decryptedtext); } -TEST_CASE("mbedtls CTR stream test", "[aes]") +static void aes_ctr_stream_test(void) { const unsigned SZ = 100; mbedtls_aes_context ctx; @@ -396,6 +399,11 @@ TEST_CASE("mbedtls CTR stream test", "[aes]") free(decryptedtext); } +TEST_CASE("mbedtls CTR stream test", "[aes]") +{ + aes_ctr_stream_test(); +} + TEST_CASE("mbedtls OFB stream test", "[aes]") { @@ -773,24 +781,22 @@ TEST_CASE("mbedtls OFB, chained DMA descriptors", "[aes]") -#ifdef CONFIG_SPIRAM_USE_MALLOC - -const uint8_t expected_cipher_psram_end[] = { - 0x7e, 0xdf, 0x13, 0xf3, 0x56, 0xef, 0x67, 0x01, - 0xfc, 0x08, 0x49, 0x62, 0xfa, 0xfe, 0x0c, 0x8b, - 0x99, 0x39, 0x09, 0x51, 0x2c, 0x9a, 0xd5, 0x48, - 0x4f, 0x76, 0xa2, 0x19, 0x2c, 0x08, 0x9d, 0x6a, +const uint8_t expected_cipher_ctr_end[] = { + 0x93, 0xca, 0xe0, 0x44, 0x96, 0x6d, 0xcb, 0xb2, + 0xcf, 0x8a, 0x8d, 0x73, 0x8c, 0x6b, 0xfa, 0x4d, + 0xd6, 0xc4, 0x18, 0x49, 0xdd, 0xc6, 0xbf, 0xc2, + 0xb9, 0xf0, 0x09, 0x69, 0x45, 0x42, 0xc6, 0x05, }; -void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps) +void aes_ctr_alignment_test(uint32_t input_buf_caps, uint32_t output_buf_caps) { mbedtls_aes_context ctx; uint8_t nonce[16]; uint8_t key[16]; uint8_t stream_block[16]; - size_t SZ = 6000; - size_t ALIGNMENT_SIZE_BYTES = 16; + size_t SZ = 32*200; + size_t ALIGNMENT_SIZE_BYTES = 64; memset(nonce, 0x2F, 16); memset(key, 0x1E, 16); @@ -815,7 +821,7 @@ void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps) offset = 0; memset(nonce, 0x2F, 16); mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, plaintext + i, chipertext + i); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_psram_end, chipertext + i + SZ - 32, 32); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_ctr_end, chipertext + i + SZ - 32, 32); // Decrypt offset = 0; @@ -833,14 +839,23 @@ void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps) free(decryptedtext); } +TEST_CASE("mbedtls AES internal mem alignment tests", "[aes]") +{ + uint32_t internal_dma_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL; + aes_ctr_alignment_test(internal_dma_caps, internal_dma_caps); +} + + +#ifdef CONFIG_SPIRAM_USE_MALLOC + void aes_psram_one_buf_ctr_test(void) { mbedtls_aes_context ctx; uint8_t nonce[16]; uint8_t key[16]; uint8_t stream_block[16]; - size_t SZ = 6000; - size_t ALIGNMENT_SIZE_BYTES = 16; + size_t SZ = 32*200; + size_t ALIGNMENT_SIZE_BYTES = 32; memset(nonce, 0x2F, 16); memset(key, 0x1E, 16); @@ -862,7 +877,7 @@ void aes_psram_one_buf_ctr_test(void) memset(buf, 0x26, SZ + ALIGNMENT_SIZE_BYTES); memset(nonce, 0x2F, 16); mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, buf + i, buf + i); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_psram_end, buf + i + SZ - 32, 32); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_ctr_end, buf + i + SZ - 32, 32); // Decrypt offset = 0; @@ -1444,9 +1459,9 @@ void aes_ext_flash_ctr_test(uint32_t output_buf_caps) /* Tests how crypto DMA handles data in external memory */ TEST_CASE("mbedtls AES PSRAM tests", "[aes]") { - aes_psram_ctr_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - aes_psram_ctr_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - aes_psram_ctr_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + aes_ctr_alignment_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + aes_ctr_alignment_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + aes_ctr_alignment_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); aes_psram_one_buf_ctr_test(); } @@ -1457,3 +1472,32 @@ TEST_CASE("mbedtls AES external flash tests", "[aes]") aes_ext_flash_ctr_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); } #endif // CONFIG_SPIRAM_USE_MALLOC + + +#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK + +RTC_FAST_ATTR uint8_t rtc_stack[4096]; +static xSemaphoreHandle done_sem; + +static void aes_ctr_stream_test_task(void *pv) +{ + aes_ctr_stream_test(); + xSemaphoreGive(done_sem); + vTaskDelete(NULL); +} + +TEST_CASE("mbedtls AES stack in RTC RAM", "[mbedtls]") +{ + done_sem = xSemaphoreCreateBinary(); + static StaticTask_t rtc_task; + memset(rtc_stack, 0, sizeof(rtc_stack)); + + TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack)); + + TEST_ASSERT_NOT_NULL(xTaskCreateStatic(aes_ctr_stream_test_task, "aes_ctr_task", sizeof(rtc_stack), NULL, + 3, rtc_stack, &rtc_task)); + TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)); + vSemaphoreDelete(done_sem); +} + +#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK diff --git a/components/mbedtls/test/test_esp_crt_bundle.c b/components/mbedtls/test/test_esp_crt_bundle.c index 86c0c956edea..1028fcc5936d 100644 --- a/components/mbedtls/test/test_esp_crt_bundle.c +++ b/components/mbedtls/test/test_esp_crt_bundle.c @@ -35,6 +35,7 @@ #include "mbedtls/debug.h" #include "esp_crt_bundle.h" +// #include "esp_random.h" #include "unity.h" #include "test_utils.h" @@ -253,7 +254,7 @@ esp_err_t client_setup(mbedtls_endpoint_t *client) return ESP_OK; } -int client_task(const uint8_t *bundle, esp_crt_validate_res_t *res) +int client_task(const uint8_t *bundle, size_t bundle_size, esp_crt_validate_res_t *res) { int ret = ESP_FAIL; @@ -269,7 +270,7 @@ int client_task(const uint8_t *bundle, esp_crt_validate_res_t *res) esp_crt_bundle_attach(&client.conf); if (bundle) { /* Set a bundle different from the menuconfig bundle */ - esp_crt_bundle_set(bundle); + esp_crt_bundle_set(bundle, bundle_size); } ESP_LOGI(TAG, "Connecting to %s:%s...", SERVER_ADDRESS, SERVER_PORT); @@ -329,11 +330,11 @@ TEST_CASE("custom certificate bundle", "[mbedtls]") } /* Test with default crt bundle that doesnt contain the ca crt */ - client_task(NULL, &validate_res); + client_task(NULL, 0, &validate_res); TEST_ASSERT(validate_res == ESP_CRT_VALIDATE_FAIL); /* Test with bundle that does contain the CA crt */ - client_task(server_cert_bundle_start, &validate_res); + client_task(server_cert_bundle_start, server_cert_bundle_end - server_cert_bundle_start, &validate_res); TEST_ASSERT(validate_res == ESP_CRT_VALIDATE_OK); exit_flag = true; @@ -390,3 +391,50 @@ TEST_CASE("custom certificate bundle - wrong signature", "[mbedtls]") esp_crt_bundle_detach(NULL); } + +TEST_CASE("custom certificate bundle init API - bound checking", "[mbedtls]") +{ + + uint8_t test_bundle[256] = {0}; + esp_err_t esp_ret; + /* The API should fail with bundle size given as 1 */ + esp_ret = esp_crt_bundle_set(test_bundle, 1); + TEST_ASSERT( esp_ret == ESP_ERR_INVALID_ARG); + + /* Check that the esp_crt_bundle_set API will not accept a bundle + * which has more no. of certs than configured in + * CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS */ + + uint8_t rand; + esp_fill_random(&rand, 1); + test_bundle[0] = rand; + + /* Make sure that the number of certs will always be greater than + * CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS */ + test_bundle[1] = rand + CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS; + + esp_ret = esp_crt_bundle_set(test_bundle, sizeof(test_bundle)); + TEST_ASSERT( esp_ret == ESP_ERR_INVALID_ARG); + + /* The API should fail with bundle_size < BUNDLE_HEADER_OFFSET (2) + CRT_HEADER_OFFSET (4) */ + test_bundle[0] = 0; + test_bundle[1] = 1; /* set num_certs = 1 */ + esp_ret = esp_crt_bundle_set(test_bundle, 5); + TEST_ASSERT(esp_ret == ESP_ERR_INVALID_ARG); + + /* Cert number is greater than actual certs present, The API should fail */ + /* Actual No. of certs present in bundle = 1, setting num_certs to 5 */ + test_bundle[1] = 5; /* num_certs */ + test_bundle[3] = 5; /* cert_1_name_len */ + test_bundle[5] = 10; /* cert_1_pub_key_len */ + /* Actual bundle size becomes BUNDLE_HEADER_OFFSET (2) + CRT_HEADER_OFFSET (4) + cert_1_name_len(5) + cert_1_pub_key_len(10) + * i.e. 21 bytes */ + esp_ret = esp_crt_bundle_set(test_bundle, 21); + TEST_ASSERT(esp_ret == ESP_ERR_INVALID_ARG); + + /* The API should fail if bundle_size < BUNDLE_HEADER_OFFSET (2) + CRT_HEADER_OFFSET (4) + cert_1_name_len(5) + cert_1_pub_key_len(10) */ + esp_ret = esp_crt_bundle_set(test_bundle, 20); + TEST_ASSERT(esp_ret == ESP_ERR_INVALID_ARG); + + esp_crt_bundle_detach(NULL); +} diff --git a/components/mbedtls/test/test_mbedtls_sha.c b/components/mbedtls/test/test_mbedtls_sha.c index 190769592aa1..7c60aeb4c8b1 100644 --- a/components/mbedtls/test/test_mbedtls_sha.c +++ b/components/mbedtls/test/test_mbedtls_sha.c @@ -475,11 +475,11 @@ TEST_CASE("mbedtls SHA512/t", "[mbedtls]") } } } +#endif //CONFIG_MBEDTLS_HARDWARE_SHA -#ifdef CONFIG_SPIRAM +#ifdef CONFIG_SPIRAM_USE_MALLOC TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]") { - const unsigned CALLS = 256; const unsigned CALL_SZ = 16 * 1024; mbedtls_sha256_context sha256_ctx; @@ -510,6 +510,26 @@ TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]") TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); } -#endif //CONFIG_SPIRAM +#endif //CONFIG_SPIRAM_USE_MALLOC -#endif //CONFIG_MBEDTLS_HARDWARE_SHA +#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK + +extern RTC_FAST_ATTR uint8_t rtc_stack[4096]; + +static xSemaphoreHandle done_sem; + +TEST_CASE("mbedtls SHA stack in RTC RAM", "[mbedtls]") +{ + done_sem = xSemaphoreCreateBinary(); + static StaticTask_t rtc_task; + memset(rtc_stack, 0, sizeof(rtc_stack)); + + TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack)); + + TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", sizeof(rtc_stack), NULL, + 3, rtc_stack, &rtc_task)); + TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)); + vSemaphoreDelete(done_sem); +} + +#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 4240a1a787f0..cc1b4b3c3b7d 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -248,6 +248,7 @@ static const uint8_t * _mdns_read_fqdn(const uint8_t * packet, const uint8_t * s buf[len] = '\0'; if (name->parts == 1 && buf[0] != '_' && (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0) + && (strcasecmp(buf, "arpa") != 0) && (strcasecmp(buf, "ip6") != 0) && (strcasecmp(buf, "in-addr") != 0)) { strlcat(name->host, ".", sizeof(name->host)); @@ -2468,7 +2469,8 @@ static const uint8_t * _mdns_parse_fqdn(const uint8_t * packet, const uint8_t * if (strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN) == 0 || strcasecmp(name->domain, "arpa") == 0) { return next_data; } - return 0; + name->invalid = true; // mark the current name invalid, but continue with other question + return next_data; } /** @@ -2482,7 +2484,8 @@ static bool _mdns_question_matches(mdns_parsed_question_t * question, uint16_t t if (type == MDNS_TYPE_A || type == MDNS_TYPE_AAAA) { return true; } else if (type == MDNS_TYPE_PTR || type == MDNS_TYPE_SDPTR) { - if (!strcasecmp(service->service->service, question->service) + if (question->service && question->proto && question->domain + && !strcasecmp(service->service->service, question->service) && !strcasecmp(service->service->proto, question->proto) && !strcasecmp(MDNS_DEFAULT_DOMAIN, question->domain)) { return true; diff --git a/components/mdns/test_afl_fuzz_host/sdkconfig.h b/components/mdns/test_afl_fuzz_host/sdkconfig.h index 1b5997b64861..e09b70b80449 100644 --- a/components/mdns/test_afl_fuzz_host/sdkconfig.h +++ b/components/mdns/test_afl_fuzz_host/sdkconfig.h @@ -53,7 +53,7 @@ #define CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF 0 #define CONFIG_BTDM_CTRL_PINNED_TO_CORE 0 #define CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF 1 -#define CONFIG_BT_RESERVE_DRAM 0x0 +#define CONFIG_BTDM_RESERVE_DRAM 0x0 #define CONFIG_COAP_MBEDTLS_PSK 1 #define CONFIG_COAP_LOG_DEFAULT_LEVEL 0 #define CONFIG_ADC_DISABLE_DAC 1 diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt index f10321a53b53..985078affa8a 160000 --- a/components/mqtt/esp-mqtt +++ b/components/mqtt/esp-mqtt @@ -1 +1 @@ -Subproject commit f10321a53b53a146ee299cfecc320b89c0cf6611 +Subproject commit 985078affa8a2d2b56b87c8e6455252850f895c6 diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index 077db452994e..ba4c124b9b19 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -16,6 +16,7 @@ set(srcs "newlib_init.c" "syscalls.c" "termios.c" + "stdatomic.c" "time.c") set(include_dirs platform_include) diff --git a/components/newlib/newlib.lf b/components/newlib/newlib.lf index 5f1c382f8d55..d92c04fb0f19 100644 --- a/components/newlib/newlib.lf +++ b/components/newlib/newlib.lf @@ -4,3 +4,4 @@ entries: heap (noflash) abort (noflash) assert (noflash) + stdatomic (noflash) diff --git a/components/newlib/stdatomic.c b/components/newlib/stdatomic.c new file mode 100644 index 000000000000..fc8f2a5dcf37 --- /dev/null +++ b/components/newlib/stdatomic.c @@ -0,0 +1,490 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +//replacement for gcc built-in functions + +#include "sdkconfig.h" +#include +#include +#include "soc/soc_caps.h" +#include "freertos/FreeRTOS.h" + +#ifdef __XTENSA__ +#include "xtensa/config/core-isa.h" + +#ifndef XCHAL_HAVE_S32C1I +#error "XCHAL_HAVE_S32C1I not defined, include correct header!" +#endif + +#define HAS_ATOMICS_32 (XCHAL_HAVE_S32C1I == 1) +// no 64-bit atomics on Xtensa +#define HAS_ATOMICS_64 0 + +#else // RISCV + +// GCC toolchain will define this pre-processor if "A" extension is supported +#ifndef __riscv_atomic +#define __riscv_atomic 0 +#endif + +#define HAS_ATOMICS_32 (__riscv_atomic == 1) +#define HAS_ATOMICS_64 ((__riscv_atomic == 1) && (__riscv_xlen == 64)) +#endif // (__XTENSA__, __riscv) + +#if SOC_CPU_CORES_NUM == 1 + +// Single core SoC: atomics can be implemented using portENTER_CRITICAL_NESTED +// and portEXIT_CRITICAL_NESTED, which disable and enable interrupts. +#define _ATOMIC_ENTER_CRITICAL() ({ \ + unsigned state = portENTER_CRITICAL_NESTED(); \ + state; \ +}) + +#define _ATOMIC_EXIT_CRITICAL(state) do { \ + portEXIT_CRITICAL_NESTED(state); \ + } while (0) + +#else // SOC_CPU_CORES_NUM + +_Static_assert(HAS_ATOMICS_32, "32-bit atomics should be supported if SOC_CPU_CORES_NUM > 1"); +// Only need to implement 64-bit atomics here. Use a single global portMUX_TYPE spinlock +// to emulate the atomics. +static portMUX_TYPE s_atomic_lock = portMUX_INITIALIZER_UNLOCKED; + +// Return value is not used but kept for compatibility with the single-core version above. +#define _ATOMIC_ENTER_CRITICAL() ({ \ + portENTER_CRITICAL_SAFE(&s_atomic_lock); \ + 0; \ +}) + +#define _ATOMIC_EXIT_CRITICAL(state) do { \ + (void) (state); \ + portEXIT_CRITICAL_SAFE(&s_atomic_lock); \ +} while(0) + +#endif // SOC_CPU_CORES_NUM + +#ifdef __clang__ +// Clang doesn't allow to define "__sync_*" atomics. The workaround is to define function with name "__sync_*_builtin", +// which implements "__sync_*" atomic functionality and use asm directive to set the value of symbol "__sync_*" to the name +// of defined function. + +#define CLANG_ATOMIC_SUFFIX(name_) name_ ## _builtin +#define CLANG_DECLARE_ALIAS(name_) \ +__asm__(".type " # name_ ", @function\n" \ + ".global " #name_ "\n" \ + ".equ " #name_ ", " #name_ "_builtin"); + +#else // __clang__ + +#define CLANG_ATOMIC_SUFFIX(name_) name_ +#define CLANG_DECLARE_ALIAS(name_) + +#endif // __clang__ + +#define ATOMIC_LOAD(n, type) type __atomic_load_ ## n (const type* mem, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *mem; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define ATOMIC_STORE(n, type) void __atomic_store_ ## n (type* mem, type val, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + *mem = val; \ + _ATOMIC_EXIT_CRITICAL(state); \ +} + +#define ATOMIC_EXCHANGE(n, type) type __atomic_exchange_ ## n (type* mem, type val, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *mem; \ + *mem = val; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define CMP_EXCHANGE(n, type) bool __atomic_compare_exchange_ ## n (type* mem, type* expect, type desired, bool weak, int success, int failure) \ +{ \ + bool ret = false; \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + if (*mem == *expect) { \ + ret = true; \ + *mem = desired; \ + } else { \ + *expect = *mem; \ + } \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define FETCH_ADD(n, type) type __atomic_fetch_add_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = *ptr + value; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define ADD_FETCH(n, type) type __atomic_add_fetch_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr + value; \ + *ptr = ret; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define FETCH_SUB(n, type) type __atomic_fetch_sub_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = *ptr - value; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define SUB_FETCH(n, type) type __atomic_sub_fetch_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr - value; \ + *ptr = ret; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define FETCH_AND(n, type) type __atomic_fetch_and_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = *ptr & value; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define AND_FETCH(n, type) type __atomic_and_fetch_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr & value; \ + *ptr = ret; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define FETCH_OR(n, type) type __atomic_fetch_or_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = *ptr | value; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define OR_FETCH(n, type) type __atomic_or_fetch_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr | value; \ + *ptr = ret; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define FETCH_XOR(n, type) type __atomic_fetch_xor_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = *ptr ^ value; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define XOR_FETCH(n, type) type __atomic_xor_fetch_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr ^ value; \ + *ptr = ret; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define FETCH_NAND(n, type) type __atomic_fetch_nand_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = ~(*ptr & value); \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define NAND_FETCH(n, type) type __atomic_nand_fetch_ ## n (type* ptr, type value, int memorder) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = ~(*ptr & value); \ + *ptr = ret; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} + +#define SYNC_FETCH_OP(op, n, type) type CLANG_ATOMIC_SUFFIX(__sync_fetch_and_ ## op ##_ ## n) (type* ptr, type value) \ +{ \ + return __atomic_fetch_ ## op ##_ ## n (ptr, value, __ATOMIC_SEQ_CST); \ +} \ +CLANG_DECLARE_ALIAS( __sync_fetch_and_ ## op ##_ ## n ) + +#define SYNC_OP_FETCH(op, n, type) type CLANG_ATOMIC_SUFFIX(__sync_ ## op ##_and_fetch_ ## n) (type* ptr, type value) \ +{ \ + return __atomic_ ## op ##_fetch_ ## n (ptr, value, __ATOMIC_SEQ_CST); \ +} \ +CLANG_DECLARE_ALIAS( __sync_ ## op ##_and_fetch_ ## n ) + +#define SYNC_BOOL_CMP_EXCHANGE(n, type) bool CLANG_ATOMIC_SUFFIX(__sync_bool_compare_and_swap_ ## n) (type *ptr, type oldval, type newval) \ +{ \ + bool ret = false; \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + if (*ptr == oldval) { \ + *ptr = newval; \ + ret = true; \ + } \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} \ +CLANG_DECLARE_ALIAS( __sync_bool_compare_and_swap_ ## n ) + +#define SYNC_VAL_CMP_EXCHANGE(n, type) type CLANG_ATOMIC_SUFFIX(__sync_val_compare_and_swap_ ## n) (type *ptr, type oldval, type newval) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + if (*ptr == oldval) { \ + *ptr = newval; \ + } \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} \ +CLANG_DECLARE_ALIAS( __sync_val_compare_and_swap_ ## n ) + +#define SYNC_LOCK_TEST_AND_SET(n, type) type CLANG_ATOMIC_SUFFIX(__sync_lock_test_and_set_ ## n) (type *ptr, type val) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + type ret = *ptr; \ + *ptr = val; \ + _ATOMIC_EXIT_CRITICAL(state); \ + return ret; \ +} \ +CLANG_DECLARE_ALIAS( __sync_lock_test_and_set_ ## n ) + +#define SYNC_LOCK_RELEASE(n, type) void CLANG_ATOMIC_SUFFIX(__sync_lock_release_ ## n) (type *ptr) \ +{ \ + unsigned state = _ATOMIC_ENTER_CRITICAL(); \ + *ptr = 0; \ + _ATOMIC_EXIT_CRITICAL(state); \ +} \ +CLANG_DECLARE_ALIAS( __sync_lock_release_ ## n ) + + +#if !HAS_ATOMICS_32 + +ATOMIC_EXCHANGE(1, uint8_t) +ATOMIC_EXCHANGE(2, uint16_t) +ATOMIC_EXCHANGE(4, uint32_t) + +CMP_EXCHANGE(1, uint8_t) +CMP_EXCHANGE(2, uint16_t) +CMP_EXCHANGE(4, uint32_t) + +FETCH_ADD(1, uint8_t) +FETCH_ADD(2, uint16_t) +FETCH_ADD(4, uint32_t) + +ADD_FETCH(1, uint8_t) +ADD_FETCH(2, uint16_t) +ADD_FETCH(4, uint32_t) + +FETCH_SUB(1, uint8_t) +FETCH_SUB(2, uint16_t) +FETCH_SUB(4, uint32_t) + +SUB_FETCH(1, uint8_t) +SUB_FETCH(2, uint16_t) +SUB_FETCH(4, uint32_t) + +FETCH_AND(1, uint8_t) +FETCH_AND(2, uint16_t) +FETCH_AND(4, uint32_t) + +AND_FETCH(1, uint8_t) +AND_FETCH(2, uint16_t) +AND_FETCH(4, uint32_t) + +FETCH_OR(1, uint8_t) +FETCH_OR(2, uint16_t) +FETCH_OR(4, uint32_t) + +OR_FETCH(1, uint8_t) +OR_FETCH(2, uint16_t) +OR_FETCH(4, uint32_t) + +FETCH_XOR(1, uint8_t) +FETCH_XOR(2, uint16_t) +FETCH_XOR(4, uint32_t) + +XOR_FETCH(1, uint8_t) +XOR_FETCH(2, uint16_t) +XOR_FETCH(4, uint32_t) + +FETCH_NAND(1, uint8_t) +FETCH_NAND(2, uint16_t) +FETCH_NAND(4, uint32_t) + +NAND_FETCH(1, uint8_t) +NAND_FETCH(2, uint16_t) +NAND_FETCH(4, uint32_t) + +SYNC_FETCH_OP(add, 1, uint8_t) +SYNC_FETCH_OP(add, 2, uint16_t) +SYNC_FETCH_OP(add, 4, uint32_t) + +SYNC_OP_FETCH(add, 1, uint8_t) +SYNC_OP_FETCH(add, 2, uint16_t) +SYNC_OP_FETCH(add, 4, uint32_t) + +SYNC_FETCH_OP(sub, 1, uint8_t) +SYNC_FETCH_OP(sub, 2, uint16_t) +SYNC_FETCH_OP(sub, 4, uint32_t) + +SYNC_OP_FETCH(sub, 1, uint8_t) +SYNC_OP_FETCH(sub, 2, uint16_t) +SYNC_OP_FETCH(sub, 4, uint32_t) + +SYNC_FETCH_OP(and, 1, uint8_t) +SYNC_FETCH_OP(and, 2, uint16_t) +SYNC_FETCH_OP(and, 4, uint32_t) + +SYNC_OP_FETCH(and, 1, uint8_t) +SYNC_OP_FETCH(and, 2, uint16_t) +SYNC_OP_FETCH(and, 4, uint32_t) + +SYNC_FETCH_OP(or, 1, uint8_t) +SYNC_FETCH_OP(or, 2, uint16_t) +SYNC_FETCH_OP(or, 4, uint32_t) + +SYNC_OP_FETCH(or, 1, uint8_t) +SYNC_OP_FETCH(or, 2, uint16_t) +SYNC_OP_FETCH(or, 4, uint32_t) + +SYNC_FETCH_OP(xor, 1, uint8_t) +SYNC_FETCH_OP(xor, 2, uint16_t) +SYNC_FETCH_OP(xor, 4, uint32_t) + +SYNC_OP_FETCH(xor, 1, uint8_t) +SYNC_OP_FETCH(xor, 2, uint16_t) +SYNC_OP_FETCH(xor, 4, uint32_t) + +SYNC_FETCH_OP(nand, 1, uint8_t) +SYNC_FETCH_OP(nand, 2, uint16_t) +SYNC_FETCH_OP(nand, 4, uint32_t) + +SYNC_OP_FETCH(nand, 1, uint8_t) +SYNC_OP_FETCH(nand, 2, uint16_t) +SYNC_OP_FETCH(nand, 4, uint32_t) + +SYNC_BOOL_CMP_EXCHANGE(1, uint8_t) +SYNC_BOOL_CMP_EXCHANGE(2, uint16_t) +SYNC_BOOL_CMP_EXCHANGE(4, uint32_t) + +SYNC_VAL_CMP_EXCHANGE(1, uint8_t) +SYNC_VAL_CMP_EXCHANGE(2, uint16_t) +SYNC_VAL_CMP_EXCHANGE(4, uint32_t) + + +SYNC_LOCK_TEST_AND_SET(1, uint8_t) +SYNC_LOCK_TEST_AND_SET(2, uint16_t) +SYNC_LOCK_TEST_AND_SET(4, uint32_t) + +SYNC_LOCK_RELEASE(1, uint8_t) +SYNC_LOCK_RELEASE(2, uint16_t) +SYNC_LOCK_RELEASE(4, uint32_t) + +// LLVM has not implemented native atomic load/stores for riscv targets without the Atomic extension. LLVM thread: https://reviews.llvm.org/D47553. +// Even though GCC does transform them, these libcalls need to be available for the case where a LLVM based project links against IDF. +ATOMIC_LOAD(1, uint8_t) +ATOMIC_LOAD(2, uint16_t) +ATOMIC_LOAD(4, uint32_t) +ATOMIC_STORE(1, uint8_t) +ATOMIC_STORE(2, uint16_t) +ATOMIC_STORE(4, uint32_t) + +#endif // !HAS_ATOMICS_32 + +#if !HAS_ATOMICS_64 + +ATOMIC_EXCHANGE(8, uint64_t) + +CMP_EXCHANGE(8, uint64_t) + +FETCH_ADD(8, uint64_t) + +FETCH_SUB(8, uint64_t) + +FETCH_AND(8, uint64_t) + +FETCH_OR(8, uint64_t) + +FETCH_XOR(8, uint64_t) + +FETCH_NAND(8, uint64_t) + +ADD_FETCH(8, uint64_t) + +SUB_FETCH(8, uint64_t) + +AND_FETCH(8, uint64_t) + +OR_FETCH(8, uint64_t) + +XOR_FETCH(8, uint64_t) + +NAND_FETCH(8, uint64_t) + +SYNC_FETCH_OP(add, 8, uint64_t) + +SYNC_FETCH_OP(sub, 8, uint64_t) + +SYNC_FETCH_OP(and, 8, uint64_t) + +SYNC_FETCH_OP(or, 8, uint64_t) + +SYNC_FETCH_OP(xor, 8, uint64_t) + +SYNC_FETCH_OP(nand, 8, uint64_t) + +SYNC_OP_FETCH(add, 8, uint64_t) + +SYNC_OP_FETCH(sub, 8, uint64_t) + +SYNC_OP_FETCH(and, 8, uint64_t) + +SYNC_OP_FETCH(or, 8, uint64_t) + +SYNC_OP_FETCH(xor, 8, uint64_t) + +SYNC_OP_FETCH(nand, 8, uint64_t) + +SYNC_BOOL_CMP_EXCHANGE(8, uint64_t) + +SYNC_VAL_CMP_EXCHANGE(8, uint64_t) + +SYNC_LOCK_TEST_AND_SET(8, uint64_t) +SYNC_LOCK_RELEASE(8, uint64_t) + +// LLVM has not implemented native atomic load/stores for riscv targets without the Atomic extension. LLVM thread: https://reviews.llvm.org/D47553. +// Even though GCC does transform them, these libcalls need to be available for the case where a LLVM based project links against IDF. +ATOMIC_LOAD(8, uint64_t) +ATOMIC_STORE(8, uint64_t) + +#endif // !HAS_ATOMICS_64 diff --git a/components/newlib/syscalls.c b/components/newlib/syscalls.c index d6c309859212..9cf58271668b 100644 --- a/components/newlib/syscalls.c +++ b/components/newlib/syscalls.c @@ -17,15 +17,16 @@ #include #include #include +#include #include #include #include #include "sdkconfig.h" #include "esp_rom_uart.h" -static int syscall_not_implemented(void) +static int syscall_not_implemented(struct _reent *r, ...) { - errno = ENOSYS; + __errno_r(r) = ENOSYS; return -1; } @@ -43,7 +44,7 @@ ssize_t _write_r_console(struct _reent *r, int fd, const void * data, size_t siz } return size; } - errno = EBADF; + __errno_r(r) = EBADF; return -1; } @@ -60,7 +61,19 @@ ssize_t _read_r_console(struct _reent *r, int fd, void * data, size_t size) } return received; } - errno = EBADF; + __errno_r(r) = EBADF; + return -1; +} + +static ssize_t _fstat_r_console(struct _reent *r, int fd, struct stat * st) +{ + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { + memset(st, 0, sizeof(*st)); + /* This needs to be set so that stdout and stderr are line buffered. */ + st->st_mode = S_IFCHR; + return 0; + } + __errno_r(r) = EBADF; return -1; } @@ -73,6 +86,8 @@ ssize_t _read_r(struct _reent *r, int fd, void * dst, size_t size) __attribute__((weak,alias("_read_r_console"))); ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size) __attribute__((weak,alias("_write_r_console"))); +int _fstat_r (struct _reent *r, int fd, struct stat *st) + __attribute__((weak,alias("_fstat_r_console"))); /* The aliases below are to "syscall_not_implemented", which @@ -90,8 +105,6 @@ off_t _lseek_r(struct _reent *r, int fd, off_t size, int mode) __attribute__((weak,alias("syscall_not_implemented"))); int _fcntl_r(struct _reent *r, int fd, int cmd, int arg) __attribute__((weak,alias("syscall_not_implemented"))); -int _fstat_r(struct _reent *r, int fd, struct stat * st) - __attribute__((weak,alias("syscall_not_implemented"))); int _stat_r(struct _reent *r, const char * path, struct stat * st) __attribute__((weak,alias("syscall_not_implemented"))); int _link_r(struct _reent *r, const char* n1, const char* n2) @@ -105,8 +118,6 @@ int _isatty_r(struct _reent *r, int fd) /* These functions are not expected to be overridden */ -int system(const char* str) - __attribute__((alias("syscall_not_implemented"))); int _system_r(struct _reent *r, const char *str) __attribute__((alias("syscall_not_implemented"))); int raise(int sig) @@ -124,6 +135,13 @@ void _exit(int __status) #pragma GCC diagnostic pop +/* Similar to syscall_not_implemented, but not taking struct _reent argument */ +int system(const char* str) +{ + errno = ENOSYS; + return -1; +} + /* Replaces newlib fcntl, which has been compiled without HAVE_FCNTL */ int fcntl(int fd, int cmd, ...) { diff --git a/components/newlib/test/test_time.c b/components/newlib/test/test_time.c index 752fa091abf5..15db812012ff 100644 --- a/components/newlib/test/test_time.c +++ b/components/newlib/test/test_time.c @@ -247,6 +247,7 @@ static void get_time_task(void *pvParameters) // although exit flag is set in another task, checking (exit_flag == false) is safe while (exit_flag == false) { gettimeofday(&tv_time, NULL); + vTaskDelay(1500 / portTICK_PERIOD_MS); } xSemaphoreGive(*sema); vTaskDelete(NULL); @@ -255,13 +256,9 @@ static void get_time_task(void *pvParameters) static void start_measure(int64_t* sys_time, int64_t* real_time) { struct timeval tv_time; - int64_t t1, t2; - do { - t1 = esp_timer_get_time(); - gettimeofday(&tv_time, NULL); - t2 = esp_timer_get_time(); - } while (t2 - t1 > 40); - *real_time = t2; + // there shouldn't be much time between gettimeofday and esp_timer_get_time + gettimeofday(&tv_time, NULL); + *real_time = esp_timer_get_time(); *sys_time = (int64_t)tv_time.tv_sec * 1000000L + tv_time.tv_usec; } @@ -297,7 +294,7 @@ static void measure_time_task(void *pvParameters) int64_t sys_time_us[2] = { main_sys_time_us[0], 0}; // although exit flag is set in another task, checking (exit_flag == false) is safe while (exit_flag == false) { - esp_rom_delay_us(2 * 1000000); // 2 sec + vTaskDelay(2000 / portTICK_PERIOD_MS); start_measure(&sys_time_us[1], &real_time_us[1]); result_adjtime_correction_us[1] += calc_correction("measure", sys_time_us, real_time_us); @@ -318,7 +315,7 @@ static void measure_time_task(void *pvParameters) vTaskDelete(NULL); } -TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=35]") +TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=15]") { exit_flag = false; @@ -331,8 +328,8 @@ TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=35]") xTaskCreatePinnedToCore(get_time_task, "get_time_task", 4096, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 0); xTaskCreatePinnedToCore(measure_time_task, "measure_time_task", 4096, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 1); - printf("start waiting for 30 seconds\n"); - vTaskDelay(30000 / portTICK_PERIOD_MS); + printf("start waiting for 10 seconds\n"); + vTaskDelay(10000 / portTICK_PERIOD_MS); // set exit flag to let thread exit exit_flag = true; diff --git a/components/nvs_flash/include/nvs.h b/components/nvs_flash/include/nvs.h index 26183853b7c5..6a45327bbae2 100644 --- a/components/nvs_flash/include/nvs.h +++ b/components/nvs_flash/include/nvs.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef ESP_NVS_H #define ESP_NVS_H @@ -105,7 +97,7 @@ typedef enum { */ typedef struct { char namespace_name[16]; /*!< Namespace to which key-value belong */ - char key[16]; /*!< Key of stored key-value pair */ + char key[NVS_KEY_NAME_MAX_SIZE]; /*!< Key of stored key-value pair */ nvs_type_t type; /*!< Type of stored key-value pair */ } nvs_entry_info_t; diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index 2f72a2090dc4..e658ab78e1b1 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "nvs_page.hpp" #if defined(LINUX_TARGET) #include "crc.h" @@ -204,6 +196,10 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c return ESP_ERR_NVS_VALUE_TOO_LONG; } + if ((!isVariableLengthType(datatype)) && dataSize > 8) { + return ESP_ERR_INVALID_ARG; + } + size_t totalSize = ENTRY_SIZE; size_t entriesCount = 1; if (isVariableLengthType(datatype)) { @@ -248,7 +244,8 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c return err; } - size_t left = dataSize / ENTRY_SIZE * ENTRY_SIZE; + size_t rest = dataSize % ENTRY_SIZE; + size_t left = dataSize - rest; if (left > 0) { err = writeEntryData(static_cast(data), left); if (err != ESP_OK) { @@ -256,7 +253,7 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c } } - size_t tail = dataSize - left; + size_t tail = rest; if (tail > 0) { std::fill_n(item.rawData, ENTRY_SIZE, 0xff); memcpy(item.rawData, static_cast(data) + left, tail); diff --git a/components/nvs_flash/src/nvs_storage.cpp b/components/nvs_flash/src/nvs_storage.cpp index 52952b7a381d..f1e997d3de0a 100644 --- a/components/nvs_flash/src/nvs_storage.cpp +++ b/components/nvs_flash/src/nvs_storage.cpp @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "nvs_storage.hpp" #ifndef ESP_PLATFORM @@ -419,11 +411,6 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin return ESP_ERR_NVS_NOT_ENOUGH_SPACE; } - NamespaceEntry* entry = new (std::nothrow) NamespaceEntry; - if (!entry) { - return ESP_ERR_NO_MEM; - } - auto err = writeItem(Page::NS_INDEX, ItemType::U8, nsName, &ns, sizeof(ns)); if (err != ESP_OK) { return err; @@ -431,6 +418,11 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin mNamespaceUsage.set(ns, true); nsIndex = ns; + NamespaceEntry* entry = new (std::nothrow) NamespaceEntry; + if (!entry) { + return ESP_ERR_NO_MEM; + } + entry->mIndex = ns; strncpy(entry->mName, nsName, sizeof(entry->mName) - 1); entry->mName[sizeof(entry->mName) - 1] = 0; @@ -735,11 +727,13 @@ esp_err_t Storage::calcEntriesInNamespace(uint8_t nsIndex, size_t& usedEntries) void Storage::fillEntryInfo(Item &item, nvs_entry_info_t &info) { info.type = static_cast(item.datatype); - strncpy(info.key, item.key, sizeof(info.key)); + strncpy(info.key, item.key, sizeof(info.key) - 1); + info.key[sizeof(info.key) - 1] = '\0'; for (auto &name : mNamespaces) { if(item.nsIndex == name.mIndex) { - strncpy(info.namespace_name, name.mName, sizeof(info.namespace_name)); + strncpy(info.namespace_name, name.mName, sizeof(info.namespace_name) - 1); + info.namespace_name[sizeof(info.namespace_name) -1] = '\0'; break; } } diff --git a/components/protocomm/include/transports/protocomm_ble.h b/components/protocomm/include/transports/protocomm_ble.h index 83f2b8597562..d684e7e921a5 100644 --- a/components/protocomm/include/transports/protocomm_ble.h +++ b/components/protocomm/include/transports/protocomm_ble.h @@ -84,6 +84,11 @@ typedef struct protocomm_ble_config { */ unsigned ble_bonding:1; + /** + * BLE security flag + */ + unsigned ble_sm_sc:1; + } protocomm_ble_config_t; /** diff --git a/components/protocomm/src/security/security1.c b/components/protocomm/src/security/security1.c index c32c51aecaa2..d9365f5027f8 100644 --- a/components/protocomm/src/security/security1.c +++ b/components/protocomm/src/security/security1.c @@ -1,16 +1,8 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -25,6 +17,7 @@ #include #include #include +#include #include #include @@ -116,7 +109,7 @@ static esp_err_t handle_session_command1(session_t *cur_session, hexdump("Dec Client verifier", check_buf, sizeof(check_buf)); /* constant time memcmp */ - if (mbedtls_ssl_safer_memcmp(check_buf, cur_session->device_pubkey, + if (mbedtls_ct_memcmp(check_buf, cur_session->device_pubkey, sizeof(cur_session->device_pubkey)) != 0) { ESP_LOGE(TAG, "Key mismatch. Close connection"); mbedtls_aes_free(&cur_session->ctx_aes); diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index d757fc71cb98..24ad6106288c 100644 --- a/components/protocomm/src/simple_ble/simple_ble.c +++ b/components/protocomm/src/simple_ble/simple_ble.c @@ -42,13 +42,13 @@ const uint8_t *simple_ble_get_uuid128(uint16_t handle) static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { switch (event) { - case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: adv_config_done &= (~adv_config_flag); if (adv_config_done == 0) { esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); } break; - case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: + case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: adv_config_done &= (~scan_rsp_config_flag); if (adv_config_done == 0) { esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); @@ -91,15 +91,13 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_ ESP_LOGE(TAG, "set device name failed, error code = 0x%x", ret); return; } - ret = esp_ble_gap_config_adv_data_raw(g_ble_cfg_p->raw_adv_data_p, - g_ble_cfg_p->raw_adv_data_len); + ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->adv_data_p); if (ret) { ESP_LOGE(TAG, "config raw adv data failed, error code = 0x%x ", ret); return; } adv_config_done |= adv_config_flag; - ret = esp_ble_gap_config_scan_rsp_data_raw(g_ble_cfg_p->raw_scan_rsp_data_p, - g_ble_cfg_p->raw_scan_rsp_data_len); + ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->scan_rsp_data_p); if (ret) { ESP_LOGE(TAG, "config raw scan rsp data failed, error code = 0x%x", ret); return; @@ -266,11 +264,12 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) ESP_LOGD(TAG, "Free mem at end of simple_ble_init %d", esp_get_free_heap_size()); /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/ - esp_ble_auth_req_t auth_req; + esp_ble_auth_req_t auth_req= ESP_LE_AUTH_REQ_MITM; if (cfg->ble_bonding) { - auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; //bonding with peer device after authentication - } else { - auth_req = ESP_LE_AUTH_REQ_SC_MITM; + auth_req |= ESP_LE_AUTH_BOND; //bonding with peer device after authentication + } + if (cfg->ble_sm_sc) { + auth_req |= ESP_LE_AUTH_REQ_SC_ONLY; } esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE; //set the IO capability to No output No input uint8_t key_size = 16; //the key size should be 7~16 bytes diff --git a/components/protocomm/src/simple_ble/simple_ble.h b/components/protocomm/src/simple_ble/simple_ble.h index 1d6fb846bb2c..8f09adcb1eaf 100644 --- a/components/protocomm/src/simple_ble/simple_ble.h +++ b/components/protocomm/src/simple_ble/simple_ble.h @@ -25,11 +25,9 @@ typedef struct { /** Name to be displayed to devices scanning for ESP32 */ const char *device_name; /** Raw advertisement data */ - uint8_t *raw_adv_data_p; - uint8_t raw_adv_data_len; + esp_ble_adv_data_t *adv_data_p; /** Raw scan response data */ - uint8_t *raw_scan_rsp_data_p; - uint8_t raw_scan_rsp_data_len; + esp_ble_adv_data_t *scan_rsp_data_p; /** Parameters to configure the nature of advertising */ esp_ble_adv_params_t adv_params; /** Descriptor table which consists of the configuration @@ -49,8 +47,10 @@ typedef struct { simple_ble_cb_t *connect_fn; /** MTU set callback */ simple_ble_cb_t *set_mtu_fn; - /** BLE bonding **/ - unsigned ble_bonding:1; + /** BLE bonding */ + unsigned ble_bonding:1; + /** BLE Secure Connection flag */ + unsigned ble_sm_sc:1; } simple_ble_cfg_t; diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index d2be1b7ef501..e88e62b03c6e 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -25,7 +25,6 @@ static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE; static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE; static const uint16_t character_user_description = ESP_GATT_UUID_CHAR_DESCRIPTION; static const uint8_t character_prop_read_write = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE; -static const uint8_t ble_advertisement_flags = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT; typedef struct { uint8_t type; @@ -52,14 +51,33 @@ typedef struct _protocomm_ble { ssize_t g_nu_lookup_count; uint16_t gatt_mtu; uint8_t *service_uuid; - uint8_t *raw_adv_data_p; - uint8_t raw_adv_data_len; - uint8_t *raw_scan_rsp_data_p; - uint8_t raw_scan_rsp_data_len; } _protocomm_ble_internal_t; static _protocomm_ble_internal_t *protoble_internal; +// config adv data +static esp_ble_adv_data_t adv_config = { + .set_scan_rsp = false, + .include_txpower = true, + .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec + .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .appearance = 0x00, + .manufacturer_len = 0, + .p_manufacturer_data = NULL, + .service_data_len = 0, + .p_service_data = NULL, + .service_uuid_len = 0, // Filled later + .p_service_uuid = NULL, // Filled later + .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), +}; +// config scan response data +static esp_ble_adv_data_t scan_rsp_config = { + .set_scan_rsp = true, + .include_name = true, + .manufacturer_len = 0, // Filled later + .p_manufacturer_data = NULL, // Filler later +}; + static esp_ble_adv_params_t adv_params = { .adv_int_min = 0x100, .adv_int_max = 0x100, @@ -417,8 +435,6 @@ static void protocomm_ble_cleanup(void) } free(protoble_internal->g_nu_lookup); } - free(protoble_internal->raw_adv_data_p); - free(protoble_internal->raw_scan_rsp_data_p); free(protoble_internal); protoble_internal = NULL; } @@ -491,133 +507,14 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con protoble_internal->pc_ble = pc; protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE; - /* The BLE advertisement data (max 31 bytes) consists of: - * 1) Flags - - * Size : length (1 byte) + type (1 byte) + value (1 byte) = 3 bytes - * 2) Complete 128 bit UUID of the service - - * Size : length (1 byte) + type (1 byte) + value (16 bytes) = 18 bytes - * - * Remaining 31 - (3 + 18) = 10 bytes could be used for manufacturer data - * or something else in the future. - */ - raw_data_info_t adv_data[] = { - { /* Flags */ - .type = ESP_BLE_AD_TYPE_FLAG, - .length = sizeof(ble_advertisement_flags), - .data_p = (uint8_t *) &ble_advertisement_flags - }, - { /* 128 bit Service UUID */ - .type = ESP_BLE_AD_TYPE_128SRV_CMPL, - .length = ESP_UUID_LEN_128, - .data_p = (uint8_t *) config->service_uuid - }, - }; - - /* Get the total raw data length required for above entries */ - uint8_t adv_data_len = 0; - for (uint8_t i = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) { - /* Add extra bytes required per entry, i.e. - * length (1 byte) + type (1 byte) = 2 bytes */ - adv_data_len += adv_data[i].length + 2; - } - if (adv_data_len > ESP_BLE_ADV_DATA_LEN_MAX) { - ESP_LOGE(TAG, "Advertisement data too long = %d bytes", adv_data_len); - protocomm_ble_cleanup(); - return ESP_ERR_NO_MEM; - } - - /* Allocate memory for the raw advertisement data */ - protoble_internal->raw_adv_data_len = adv_data_len; - protoble_internal->raw_adv_data_p = malloc(adv_data_len); - if (protoble_internal->raw_adv_data_p == NULL) { - ESP_LOGE(TAG, "Error allocating memory for raw advertisement data"); - protocomm_ble_cleanup(); - return ESP_ERR_NO_MEM; - } - - /* Form the raw advertisement data using above entries */ - for (uint8_t i = 0, len = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) { - protoble_internal->raw_adv_data_p[len++] = adv_data[i].length + 1; // + 1 byte for type - protoble_internal->raw_adv_data_p[len++] = adv_data[i].type; - memcpy(&protoble_internal->raw_adv_data_p[len], - adv_data[i].data_p, adv_data[i].length); - - if (adv_data[i].type == ESP_BLE_AD_TYPE_128SRV_CMPL) { - /* Remember where the primary service UUID is kept in the - * raw advertisement data, so that it can be used while - * populating the GATT database - */ - protoble_internal->service_uuid = &protoble_internal->raw_adv_data_p[len]; - } - - len += adv_data[i].length; - } - - size_t ble_devname_len = strlen(protocomm_ble_device_name); - /* The BLE scan response (31 bytes) consists of: - * 1) Device name (complete / incomplete) - - * Size : The maximum supported name length - * will be 31 - 2 (length + type) = 29 bytes - * - * Any remaining space may be used for accommodating - * other fields in the future - * - * 2) Manufacturer Data (To be truncated depending upon available size) - * Size : The maximum supported manufacturer data size - * will be 31 - 2 (length + type) - ble_devname_len - 2 (length + type) - */ + // Config adv data + adv_config.service_uuid_len = ESP_UUID_LEN_128; + adv_config.p_service_uuid = (uint8_t *) config->service_uuid; + protoble_internal->service_uuid = (uint8_t *) config->service_uuid; - raw_data_info_t scan_resp_data[] = { - { /* If full device name can fit in the scan response then indicate - * that by setting type to "Complete Name", else set it to "Short Name" - * so that client can fetch full device name - after connecting - by - * reading the device name characteristic under GAP service */ - .type = (ble_devname_len > (ESP_BLE_SCAN_RSP_DATA_LEN_MAX - 2) ? - ESP_BLE_AD_TYPE_NAME_SHORT : ESP_BLE_AD_TYPE_NAME_CMPL), - .length = MIN(ble_devname_len, (ESP_BLE_SCAN_RSP_DATA_LEN_MAX - 2)), - .data_p = (uint8_t *) protocomm_ble_device_name - }, - { - 0, - }, - }; - - if (protocomm_ble_mfg_data_len > 0) { - scan_resp_data[1].type = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE; - scan_resp_data[1].length = protocomm_ble_mfg_data_len; - scan_resp_data[1].data_p = (uint8_t *) protocomm_ble_mfg_data; - } - - /* Get the total raw scan response data length required for above entries */ - uint8_t scan_resp_data_len = 0; - for (int i = 0; i < (sizeof(scan_resp_data) / sizeof(scan_resp_data[0])); i++) { - /* Add extra bytes required per entry, i.e. - * length (1 byte) + type (1 byte) = 2 bytes */ - scan_resp_data_len += scan_resp_data[i].length + 2; - } - if (scan_resp_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX) { - ESP_LOGE(TAG, "Scan response data too long = %d bytes", scan_resp_data_len); - protocomm_ble_cleanup(); - return ESP_ERR_NO_MEM; - } - - /* Allocate memory for the raw scan response data */ - protoble_internal->raw_scan_rsp_data_len = scan_resp_data_len; - protoble_internal->raw_scan_rsp_data_p = malloc(scan_resp_data_len); - if (protoble_internal->raw_scan_rsp_data_p == NULL) { - ESP_LOGE(TAG, "Error allocating memory for raw response data"); - protocomm_ble_cleanup(); - return ESP_ERR_NO_MEM; - } - - /* Form the raw scan response data using above entries */ - for (uint8_t i = 0, len = 0; i < (sizeof(scan_resp_data) / sizeof(scan_resp_data[0])); i++) { - protoble_internal->raw_scan_rsp_data_p[len++] = scan_resp_data[i].length + 1; // + 1 byte for type - protoble_internal->raw_scan_rsp_data_p[len++] = scan_resp_data[i].type; - memcpy(&protoble_internal->raw_scan_rsp_data_p[len], - scan_resp_data[i].data_p, scan_resp_data[i].length); - len += scan_resp_data[i].length; - } + // Config scan response data + scan_rsp_config.manufacturer_len = protocomm_ble_mfg_data_len; + scan_rsp_config.p_manufacturer_data = (uint8_t *) protocomm_ble_mfg_data; simple_ble_cfg_t *ble_config = simple_ble_init(); if (ble_config == NULL) { @@ -637,15 +534,14 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con /* Set parameters required for advertising */ ble_config->adv_params = adv_params; - ble_config->raw_adv_data_p = protoble_internal->raw_adv_data_p; - ble_config->raw_adv_data_len = protoble_internal->raw_adv_data_len; - ble_config->raw_scan_rsp_data_p = protoble_internal->raw_scan_rsp_data_p; - ble_config->raw_scan_rsp_data_len = protoble_internal->raw_scan_rsp_data_len; + ble_config->adv_data_p = &adv_config; + ble_config->scan_rsp_data_p = &scan_rsp_config; ble_config->device_name = protocomm_ble_device_name; ble_config->gatt_db_count = populate_gatt_db(&ble_config->gatt_db); ble_config->ble_bonding = config->ble_bonding; + ble_config->ble_sm_sc = config->ble_sm_sc; if (ble_config->gatt_db_count == -1) { ESP_LOGE(TAG, "Invalid GATT database count"); diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index d51ab0567b47..83263edc50ce 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -121,8 +121,10 @@ typedef struct { simple_ble_cb_t *connect_fn; /** MTU set callback */ simple_ble_cb_t *set_mtu_fn; - /** BLE bonding **/ - unsigned ble_bonding:1; + /** BLE bonding */ + unsigned ble_bonding:1; + /** BLE Secure Connection flag */ + unsigned ble_sm_sc:1; } simple_ble_cfg_t; static simple_ble_cfg_t *ble_cfg_p; @@ -498,7 +500,7 @@ static int simple_ble_start(const simple_ble_cfg_t *cfg) ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO; /* Just Works */ ble_hs_cfg.sm_bonding = cfg->ble_bonding; ble_hs_cfg.sm_mitm = 1; - ble_hs_cfg.sm_sc = 1; /* Enable secure connection by default */ + ble_hs_cfg.sm_sc = cfg->ble_sm_sc; /* Distribute LTK and IRK */ ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; @@ -641,7 +643,14 @@ ble_gatt_add_characteristics(struct ble_gatt_chr_def *characteristics, int idx) memcpy(temp_uuid128_name.value, ble_uuid_base, BLE_UUID128_VAL_LENGTH); memcpy(&temp_uuid128_name.value[12], &protoble_internal->g_nu_lookup[idx].uuid, 2); - (characteristics + idx)->flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE; + (characteristics + idx)->flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE ; + +#if defined(CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION) + (characteristics + idx)->flags |= BLE_GATT_CHR_F_READ_ENC | + BLE_GATT_CHR_F_WRITE_ENC; +#endif + (characteristics + idx)->access_cb = gatt_svr_chr_access; /* Out of 128 bit UUID, 16 bits from g_nu_lookup table. Currently @@ -912,6 +921,7 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con ble_config->device_name = protocomm_ble_device_name; ble_config->ble_bonding = config->ble_bonding; + ble_config->ble_sm_sc = config->ble_sm_sc; if (populate_gatt_db(&ble_config->gatt_db, config) != 0) { ESP_LOGE(TAG, "Error populating GATT Database"); diff --git a/components/pthread/pthread_local_storage.c b/components/pthread/pthread_local_storage.c index 55727684700f..e784c4cb6b2f 100644 --- a/components/pthread/pthread_local_storage.c +++ b/components/pthread/pthread_local_storage.c @@ -113,12 +113,17 @@ int pthread_key_delete(pthread_key_t key) This is called from one of two places: If the thread was created via pthread_create() then it's called by pthread_task_func() when that thread ends, - and the FreeRTOS thread-local-storage is removed before the FreeRTOS task is deleted. + or calls pthread_exit(), and the FreeRTOS thread-local-storage is removed before the FreeRTOS task is deleted. For other tasks, this is called when the FreeRTOS idle task performs its task cleanup after the task is deleted. - (The reason for calling it early for pthreads is to keep the timing consistent with "normal" pthreads, so after - pthread_join() the task's destructors have all been called even if the idle task hasn't run cleanup yet.) + There are two reasons for calling it early for pthreads: + + - To keep the timing consistent with "normal" pthreads, so after pthread_join() the task's destructors have all + been called even if the idle task hasn't run cleanup yet. + + - The destructor is always called in the context of the thread itself - which is important if the task then calls + pthread_getspecific() or pthread_setspecific() to update the state further, as allowed for in the spec. */ static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls) { @@ -126,8 +131,13 @@ static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls assert(tls != NULL); /* Walk the list, freeing all entries and calling destructors if they are registered */ - value_entry_t *entry = SLIST_FIRST(tls); - while(entry != NULL) { + while (1) { + value_entry_t *entry = SLIST_FIRST(tls); + if (entry == NULL) { + break; + } + SLIST_REMOVE_HEAD(tls, next); + // This is a little slow, walking the linked list of keys once per value, // but assumes that the thread's value list will have less entries // than the keys list @@ -135,9 +145,7 @@ static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls if (key != NULL && key->destructor != NULL) { key->destructor(entry->value); } - value_entry_t *next_entry = SLIST_NEXT(entry, next); free(entry); - entry = next_entry; } free(tls); } @@ -250,7 +258,22 @@ int pthread_setspecific(pthread_key_t key, const void *value) } entry->key = key; entry->value = (void *) value; // see note above about cast - SLIST_INSERT_HEAD(tls, entry, next); + + // insert the new entry at the end of the list. this is important because + // a destructor may call pthread_setspecific() to add a new non-NULL value + // to the list, and this should be processed after all other entries. + // + // See pthread_local_storage_thread_deleted_callback() + value_entry_t *last_entry = NULL; + value_entry_t *it; + SLIST_FOREACH(it, tls, next) { + last_entry = it; + } + if (last_entry == NULL) { + SLIST_INSERT_HEAD(tls, entry, next); + } else { + SLIST_INSERT_AFTER(last_entry, entry, next); + } } return 0; diff --git a/components/pthread/test/test_pthread_local_storage.c b/components/pthread/test/test_pthread_local_storage.c index ebcaafcbe845..98e6fd7d99ba 100644 --- a/components/pthread/test/test_pthread_local_storage.c +++ b/components/pthread/test/test_pthread_local_storage.c @@ -162,3 +162,90 @@ TEST_CASE("pthread local storage stress test", "[pthread]") TEST_ASSERT_EQUAL(0, pthread_join(threads[i], NULL)); } } + + +#define NUM_KEYS 4 // number of keys used in repeat destructor test +#define NUM_REPEATS 17 // number of times we re-set a key to a non-NULL value to re-trigger destructor + +typedef struct { + pthread_key_t keys[NUM_KEYS]; // pthread local storage keys used in test + unsigned count; // number of times the destructor has been called + int last_idx; // index of last key where destructor was called +} destr_test_state_t; + +static void s_test_repeat_destructor(void *vp_state); +static void *s_test_repeat_destructor_thread(void *vp_state); + +// Test the correct behaviour of a pthread destructor function that uses +// pthread_setspecific() to set another value when it runs, and also +// +// As described in https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html +TEST_CASE("pthread local storage 'repeat' destructor test", "[pthread]") +{ + int r; + destr_test_state_t state = { .last_idx = -1 }; + pthread_t thread; + + for (int i = 0; i < NUM_KEYS; i++) { + r = pthread_key_create(&state.keys[i], s_test_repeat_destructor); + TEST_ASSERT_EQUAL(0, r); + } + + r = pthread_create(&thread, NULL, s_test_repeat_destructor_thread, &state); + TEST_ASSERT_EQUAL(0, r); + + r = pthread_join(thread, NULL); + TEST_ASSERT_EQUAL(0 ,r); + + // Cheating here to make sure compiler reads the value of 'count' from memory not from a register + // + // We expect the destructor was called NUM_REPEATS times when it repeated, then NUM_KEYS times when it didn't + TEST_ASSERT_EQUAL(NUM_REPEATS + NUM_KEYS, ((volatile destr_test_state_t)state).count); + + // cleanup + for (int i = 0; i < NUM_KEYS; i++) { + r = pthread_key_delete(state.keys[i]); + TEST_ASSERT_EQUAL(0, r); + } +} + +static void s_test_repeat_destructor(void *vp_state) +{ + destr_test_state_t *state = vp_state; + + state->count++; + printf("Destructor! Arg %p Count %d\n", state, state->count); + if (state->count > NUM_REPEATS) { + return; // Stop replacing values after NUM_REPEATS destructors have been called, they will be NULLed out now + } + + // Find the key which has a NULL value, this is the key for this destructor. We will set it back to 'state' to repeat later. + // At this point only one key should have a NULL value + int null_idx = -1; + for (int i = 0; i < NUM_KEYS; i++) { + if (pthread_getspecific(state->keys[i]) == NULL) { + TEST_ASSERT_EQUAL(-1, null_idx); // If more than one key has a NULL value, something has gone wrong + null_idx = i; + // don't break, verify the other keys have non-NULL values + } + } + + TEST_ASSERT_NOT_EQUAL(-1, null_idx); // One key should have a NULL value + + // The same key shouldn't be destroyed twice in a row, as new non-NULL values should be destroyed + // after existing non-NULL values (to match spec behaviour) + TEST_ASSERT_NOT_EQUAL(null_idx, state->last_idx); + + printf("Re-setting index %d\n", null_idx); + pthread_setspecific(state->keys[null_idx], state); + state->last_idx = null_idx; +} + +static void *s_test_repeat_destructor_thread(void *vp_state) +{ + destr_test_state_t *state = vp_state; + for (int i = 0; i < NUM_KEYS; i++) { + pthread_setspecific(state->keys[i], state); + } + pthread_exit(NULL); +} diff --git a/components/riscv/CMakeLists.txt b/components/riscv/CMakeLists.txt index 0290ca99375b..efc891b19ec8 100644 --- a/components/riscv/CMakeLists.txt +++ b/components/riscv/CMakeLists.txt @@ -11,7 +11,6 @@ else() "expression_with_stack_riscv_asm.S" "instruction_decode.c" "interrupt.c" - "stdatomic.c" "vectors.S") endif() diff --git a/components/riscv/include/riscv/semihosting.h b/components/riscv/include/riscv/semihosting.h new file mode 100644 index 000000000000..17eb90785b4c --- /dev/null +++ b/components/riscv/include/riscv/semihosting.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ESP custom semihosting calls numbers */ + +/** + * @brief Set/clear breakpoint + * + * @param set if true set breakpoint, otherwise clear it + * @param id breakpoint ID + * @param addr address to set breakpoint at. Ignored if `set` is false. + * @return return 0 on sucess or non-zero error code + */ +#define ESP_SEMIHOSTING_SYS_BREAKPOINT_SET 0x66 + +/** + * @brief Set/clear watchpoint + * + * @param set if true set watchpoint, otherwise clear it + * @param id watchpoint ID + * @param addr address to set watchpoint at. Ignored if `set` is false. + * @param size size of watchpoint. Ignored if `set` is false. + * @param flags watchpoint flags, see description below. Ignored if `set` is false. + * @return return 0 on sucess or non-zero error code + */ +#define ESP_SEMIHOSTING_SYS_WATCHPOINT_SET 0x67 + +/* bit values for `flags` argument of ESP_SEMIHOSTING_SYS_WATCHPOINT_SET call. Can be ORed. */ +/* watch for 'reads' at `addr` */ +#define ESP_SEMIHOSTING_WP_FLG_RD (1UL << 0) +/* watch for 'writes' at `addr` */ +#define ESP_SEMIHOSTING_WP_FLG_WR (1UL << 1) + +/** + * @brief Perform semihosting call + * + * See https://github.com/riscv/riscv-semihosting-spec/ and the linked + * ARM semihosting spec for details. + * + * @param id semihosting call number + * @param data data block to pass to the host; number of items and their + * meaning depends on the semihosting call. See the spec for + * details. + * + * @return return value from the host + */ +static inline long semihosting_call_noerrno(long id, long *data) +{ + register long a0 asm ("a0") = id; + register long a1 asm ("a1") = (long) data; + __asm__ __volatile__ ( + ".option push\n" + ".option norvc\n" + "slli zero, zero, 0x1f\n" + "ebreak\n" + "srai zero, zero, 0x7\n" + ".option pop\n" + : "+r"(a0) : "r"(a1) : "memory"); + return a0; +} + +/** + * @brief Perform semihosting call and retrieve errno + * + * @param id semihosting call number + * @param data data block to pass to the host; number of items and their + * meaning depends on the semihosting call. See the spec for + * details. + * @param[out] out_errno output, errno value from the host. Only set if + * the return value is negative. + * @return return value from the host + */ +static inline long semihosting_call(long id, long *data, int *out_errno) +{ + long ret = semihosting_call_noerrno(id, data); + if (ret < 0) { + /* Constant also defined in openocd_semihosting.h, + * which is common for RISC-V and Xtensa; it is not included here + * to avoid a circular dependency. + */ + const int semihosting_sys_errno = 0x13; + *out_errno = (int) semihosting_call_noerrno(semihosting_sys_errno, NULL); + } + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/linker.lf b/components/riscv/linker.lf index 2e5681238ccc..cfcb303cf08d 100644 --- a/components/riscv/linker.lf +++ b/components/riscv/linker.lf @@ -3,4 +3,3 @@ archive: libriscv.a entries: interrupt (noflash_text) vectors (noflash_text) - stdatomic (noflash_text) diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index 2e1c7c477f87..89bf09e1e9b4 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -18,285 +18,299 @@ #include "sdkconfig.h" - .equ SAVE_REGS, 32 - .equ CONTEXT_SIZE, (SAVE_REGS * 4) - .equ panic_from_exception, xt_unhandled_exception - .equ panic_from_isr, panicHandler - -.macro save_regs - addi sp, sp, -CONTEXT_SIZE - sw ra, RV_STK_RA(sp) - sw tp, RV_STK_TP(sp) - sw t0, RV_STK_T0(sp) - sw t1, RV_STK_T1(sp) - sw t2, RV_STK_T2(sp) - sw s0, RV_STK_S0(sp) - sw s1, RV_STK_S1(sp) - sw a0, RV_STK_A0(sp) - sw a1, RV_STK_A1(sp) - sw a2, RV_STK_A2(sp) - sw a3, RV_STK_A3(sp) - sw a4, RV_STK_A4(sp) - sw a5, RV_STK_A5(sp) - sw a6, RV_STK_A6(sp) - sw a7, RV_STK_A7(sp) - sw s2, RV_STK_S2(sp) - sw s3, RV_STK_S3(sp) - sw s4, RV_STK_S4(sp) - sw s5, RV_STK_S5(sp) - sw s6, RV_STK_S6(sp) - sw s7, RV_STK_S7(sp) - sw s8, RV_STK_S8(sp) - sw s9, RV_STK_S9(sp) - sw s10, RV_STK_S10(sp) - sw s11, RV_STK_S11(sp) - sw t3, RV_STK_T3(sp) - sw t4, RV_STK_T4(sp) - sw t5, RV_STK_T5(sp) - sw t6, RV_STK_T6(sp) + .equ SAVE_REGS, 32 + .equ CONTEXT_SIZE, (SAVE_REGS * 4) + .equ panic_from_exception, xt_unhandled_exception + .equ panic_from_isr, panicHandler + +/* Macro which first allocates space on the stack to save general + * purpose registers, and then save them. GP register is excluded. + * The default size allocated on the stack is CONTEXT_SIZE, but it + * can be overridden. */ +.macro save_general_regs cxt_size=CONTEXT_SIZE + addi sp, sp, -\cxt_size + sw ra, RV_STK_RA(sp) + sw tp, RV_STK_TP(sp) + sw t0, RV_STK_T0(sp) + sw t1, RV_STK_T1(sp) + sw t2, RV_STK_T2(sp) + sw s0, RV_STK_S0(sp) + sw s1, RV_STK_S1(sp) + sw a0, RV_STK_A0(sp) + sw a1, RV_STK_A1(sp) + sw a2, RV_STK_A2(sp) + sw a3, RV_STK_A3(sp) + sw a4, RV_STK_A4(sp) + sw a5, RV_STK_A5(sp) + sw a6, RV_STK_A6(sp) + sw a7, RV_STK_A7(sp) + sw s2, RV_STK_S2(sp) + sw s3, RV_STK_S3(sp) + sw s4, RV_STK_S4(sp) + sw s5, RV_STK_S5(sp) + sw s6, RV_STK_S6(sp) + sw s7, RV_STK_S7(sp) + sw s8, RV_STK_S8(sp) + sw s9, RV_STK_S9(sp) + sw s10, RV_STK_S10(sp) + sw s11, RV_STK_S11(sp) + sw t3, RV_STK_T3(sp) + sw t4, RV_STK_T4(sp) + sw t5, RV_STK_T5(sp) + sw t6, RV_STK_T6(sp) .endm .macro save_mepc - csrr t0, mepc - sw t0, RV_STK_MEPC(sp) + csrr t0, mepc + sw t0, RV_STK_MEPC(sp) .endm -.macro restore_regs - lw ra, RV_STK_RA(sp) - lw tp, RV_STK_TP(sp) - lw t0, RV_STK_T0(sp) - lw t1, RV_STK_T1(sp) - lw t2, RV_STK_T2(sp) - lw s0, RV_STK_S0(sp) - lw s1, RV_STK_S1(sp) - lw a0, RV_STK_A0(sp) - lw a1, RV_STK_A1(sp) - lw a2, RV_STK_A2(sp) - lw a3, RV_STK_A3(sp) - lw a4, RV_STK_A4(sp) - lw a5, RV_STK_A5(sp) - lw a6, RV_STK_A6(sp) - lw a7, RV_STK_A7(sp) - lw s2, RV_STK_S2(sp) - lw s3, RV_STK_S3(sp) - lw s4, RV_STK_S4(sp) - lw s5, RV_STK_S5(sp) - lw s6, RV_STK_S6(sp) - lw s7, RV_STK_S7(sp) - lw s8, RV_STK_S8(sp) - lw s9, RV_STK_S9(sp) - lw s10, RV_STK_S10(sp) - lw s11, RV_STK_S11(sp) - lw t3, RV_STK_T3(sp) - lw t4, RV_STK_T4(sp) - lw t5, RV_STK_T5(sp) - lw t6, RV_STK_T6(sp) - addi sp, sp, CONTEXT_SIZE +/* Restore the general purpose registers (excluding gp) from the context on + * the stack. The context is then deallocated. The default size is CONTEXT_SIZE + * but it can be overriden. */ +.macro restore_general_regs cxt_size=CONTEXT_SIZE + lw ra, RV_STK_RA(sp) + lw tp, RV_STK_TP(sp) + lw t0, RV_STK_T0(sp) + lw t1, RV_STK_T1(sp) + lw t2, RV_STK_T2(sp) + lw s0, RV_STK_S0(sp) + lw s1, RV_STK_S1(sp) + lw a0, RV_STK_A0(sp) + lw a1, RV_STK_A1(sp) + lw a2, RV_STK_A2(sp) + lw a3, RV_STK_A3(sp) + lw a4, RV_STK_A4(sp) + lw a5, RV_STK_A5(sp) + lw a6, RV_STK_A6(sp) + lw a7, RV_STK_A7(sp) + lw s2, RV_STK_S2(sp) + lw s3, RV_STK_S3(sp) + lw s4, RV_STK_S4(sp) + lw s5, RV_STK_S5(sp) + lw s6, RV_STK_S6(sp) + lw s7, RV_STK_S7(sp) + lw s8, RV_STK_S8(sp) + lw s9, RV_STK_S9(sp) + lw s10, RV_STK_S10(sp) + lw s11, RV_STK_S11(sp) + lw t3, RV_STK_T3(sp) + lw t4, RV_STK_T4(sp) + lw t5, RV_STK_T5(sp) + lw t6, RV_STK_T6(sp) + addi sp,sp, \cxt_size .endm .macro restore_mepc - lw t0, RV_STK_MEPC(sp) - csrw mepc, t0 + lw t0, RV_STK_MEPC(sp) + csrw mepc, t0 .endm - .global rtos_int_enter - .global rtos_int_exit - .global _global_interrupt_handler - - .section .exception_vectors.text - /* This is the vector table. MTVEC points here. - * - * Use 4-byte intructions here. 1 instruction = 1 entry of the table. - * The CPU jumps to MTVEC (i.e. the first entry) in case of an exception, - * and (MTVEC & 0xfffffffc) + (mcause & 0x7fffffff) * 4, in case of an interrupt. - * - * Note: for our CPU, we need to place this on a 256-byte boundary, as CPU - * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). - */ - - .balign 0x100 - .global _vector_table - .type _vector_table, @function + .global rtos_int_enter + .global rtos_int_exit + .global _global_interrupt_handler + + .section .exception_vectors.text + /* This is the vector table. MTVEC points here. + * + * Use 4-byte intructions here. 1 instruction = 1 entry of the table. + * The CPU jumps to MTVEC (i.e. the first entry) in case of an exception, + * and (MTVEC & 0xfffffffc) + (mcause & 0x7fffffff) * 4, in case of an interrupt. + * + * Note: for our CPU, we need to place this on a 256-byte boundary, as CPU + * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). + */ + + .balign 0x100 + .global _vector_table + .type _vector_table, @function _vector_table: - .option push - .option norvc - j _panic_handler /* exception handler, entry 0 */ - .rept (ETS_T1_WDT_INUM - 1) - j _interrupt_handler /* 24 identical entries, all pointing to the interrupt handler */ - .endr - j _panic_handler /* Call panic handler for ETS_T1_WDT_INUM interrupt (soc-level panic)*/ + .option push + .option norvc + j _panic_handler /* exception handler, entry 0 */ + .rept (ETS_T1_WDT_INUM - 1) + j _interrupt_handler /* 24 identical entries, all pointing to the interrupt handler */ + .endr + j _panic_handler /* Call panic handler for ETS_T1_WDT_INUM interrupt (soc-level panic)*/ j _panic_handler /* Call panic handler for ETS_CACHEERR_INUM interrupt (soc-level panic)*/ #ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE j _panic_handler /* Call panic handler for ETS_MEMPROT_ERR_INUM interrupt (soc-level panic)*/ - .rept (ETS_MAX_INUM - ETS_MEMPROT_ERR_INUM) - #else - .rept (ETS_MAX_INUM - ETS_CACHEERR_INUM) - #endif - j _interrupt_handler /* 6 identical entries, all pointing to the interrupt handler */ - .endr - - .option pop - .size _vector_table, .-_vector_table - - /* Exception handler.*/ - .type _panic_handler, @function + .rept (ETS_MAX_INUM - ETS_MEMPROT_ERR_INUM) + #else + .rept (ETS_MAX_INUM - ETS_CACHEERR_INUM) + #endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE + j _interrupt_handler /* 6 identical entries, all pointing to the interrupt handler */ + .endr + + .option pop + .size _vector_table, .-_vector_table + + /* Exception handler.*/ + .type _panic_handler, @function _panic_handler: - addi sp, sp, -RV_STK_FRMSZ /* allocate space on stack to store necessary registers */ - /* save general registers */ - sw ra, RV_STK_RA(sp) - sw gp, RV_STK_GP(sp) - sw tp, RV_STK_TP(sp) - sw t0, RV_STK_T0(sp) - sw t1, RV_STK_T1(sp) - sw t2, RV_STK_T2(sp) - sw s0, RV_STK_S0(sp) - sw s1, RV_STK_S1(sp) - sw a0, RV_STK_A0(sp) - sw a1, RV_STK_A1(sp) - sw a2, RV_STK_A2(sp) - sw a3, RV_STK_A3(sp) - sw a4, RV_STK_A4(sp) - sw a5, RV_STK_A5(sp) - sw a6, RV_STK_A6(sp) - sw a7, RV_STK_A7(sp) - sw s2, RV_STK_S2(sp) - sw s3, RV_STK_S3(sp) - sw s4, RV_STK_S4(sp) - sw s5, RV_STK_S5(sp) - sw s6, RV_STK_S6(sp) - sw s7, RV_STK_S7(sp) - sw s8, RV_STK_S8(sp) - sw s9, RV_STK_S9(sp) - sw s10, RV_STK_S10(sp) - sw s11, RV_STK_S11(sp) - sw t3, RV_STK_T3(sp) - sw t4, RV_STK_T4(sp) - sw t5, RV_STK_T5(sp) - sw t6, RV_STK_T6(sp) - addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when trap happened */ - sw t0, RV_STK_SP(sp) - csrr t0, mepc - sw t0, RV_STK_MEPC(sp) - csrr t0, mstatus - sw t0, RV_STK_MSTATUS(sp) - csrr t0, mtvec - sw t0, RV_STK_MTVEC(sp) - csrr t0, mtval - sw t0, RV_STK_MTVAL(sp) - csrr t0, mhartid - sw t0, RV_STK_MHARTID(sp) - - /* Call panic_from_exception(sp) or panic_from_isr(sp) - * depending on whether we have a pseudo excause or not. - * If mcause's highest bit is 1, then an interrupt called this routine, - * so we have a pseudo excause. Else, it is due to a exception, we don't - * have an pseudo excause */ - mv a0, sp - csrr a1, mcause - /* Branches instructions don't accept immediates values, so use t1 to - * store our comparator */ - li t0, 0x80000000 - bgeu a1, t0, _call_panic_handler - sw a1, RV_STK_MCAUSE(sp) - /* exception_from_panic never returns */ - j panic_from_exception + /* Allocate space on the stack and store general purpose registers */ + save_general_regs RV_STK_FRMSZ + + /* As gp register is not saved by the macro, save it here */ + sw gp, RV_STK_GP(sp) + + /* Same goes for the SP value before trapping */ + addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when trap happened */ + + /* Save CSRs */ + sw t0, RV_STK_SP(sp) + csrr t0, mepc + sw t0, RV_STK_MEPC(sp) + csrr t0, mstatus + sw t0, RV_STK_MSTATUS(sp) + csrr t0, mtvec + sw t0, RV_STK_MTVEC(sp) + csrr t0, mtval + sw t0, RV_STK_MTVAL(sp) + csrr t0, mhartid + sw t0, RV_STK_MHARTID(sp) + + /* Call panic_from_exception(sp) or panic_from_isr(sp) + * depending on whether we have a pseudo excause or not. + * If mcause's highest bit is 1, then an interrupt called this routine, + * so we have a pseudo excause. Else, it is due to a exception, we don't + * have an pseudo excause */ + mv a0, sp + csrr a1, mcause + /* Branches instructions don't accept immediates values, so use t1 to + * store our comparator */ + li t0, 0x80000000 + bgeu a1, t0, _call_panic_handler + sw a1, RV_STK_MCAUSE(sp) + jal panic_from_exception + /* We arrive here if the exception handler has returned. */ + j _return_from_exception + _call_panic_handler: - /* Remove highest bit from mcause (a1) register and save it in the - * structure */ - not t0, t0 - and a1, a1, t0 - sw a1, RV_STK_MCAUSE(sp) - /* exception_from_isr never returns */ - j panic_from_isr - .size panic_from_isr, .-panic_from_isr - - /* This is the interrupt handler. - * It saves the registers on the stack, - * prepares for interrupt nesting, - * re-enables the interrupts, - * then jumps to the C dispatcher in interrupt.c. - */ - .global _interrupt_handler - .type _interrupt_handler, @function + /* Remove highest bit from mcause (a1) register and save it in the + * structure */ + not t0, t0 + and a1, a1, t0 + sw a1, RV_STK_MCAUSE(sp) + jal panic_from_isr + + /* We arrive here if the exception handler has returned. This means that + * the exception was handled, and the execution flow should resume. + * Restore the registers and return from the exception. + */ +_return_from_exception: + restore_mepc + /* MTVEC and SP are assumed to be unmodified. + * MSTATUS, MHARTID, MTVAL are read-only and not restored. + */ + lw gp, RV_STK_GP(sp) + restore_general_regs RV_STK_FRMSZ + mret + .size _panic_handler, .-_panic_handler + + /* This is the interrupt handler. + * It saves the registers on the stack, + * prepares for interrupt nesting, + * re-enables the interrupts, + * then jumps to the C dispatcher in interrupt.c. + */ + .global _interrupt_handler + .type _interrupt_handler, @function _interrupt_handler: - /* entry */ - save_regs - save_mepc - - /* Before doing anythig preserve the stack pointer */ - /* It will be saved in current TCB, if needed */ - mv a0, sp - call rtos_int_enter - - /* Before dispatch c handler, restore interrupt to enable nested intr */ - csrr s1, mcause - csrr s2, mstatus - - /* Save the interrupt threshold level */ - la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG - lw s3, 0(t0) - - /* Increase interrupt threshold level */ - li t2, 0x7fffffff - and t1, s1, t2 /* t1 = mcause & mask */ - slli t1, t1, 2 /* t1 = mcause * 4 */ - la t2, INTC_INT_PRIO_REG(0) - add t1, t2, t1 /* t1 = INTC_INT_PRIO_REG + 4 * mcause */ - lw t2, 0(t1) /* t2 = INTC_INT_PRIO_REG[mcause] */ - addi t2, t2, 1 /* t2 = t2 +1 */ - sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */ - fence - - li t0, 0x8 - csrrs t0, mstatus, t0 - - #ifdef CONFIG_PM_TRACE - li a0, 0 /* = ESP_PM_TRACE_IDLE */ - #if SOC_CPU_CORES_NUM == 1 - li a1, 0 /* No need to check core ID on single core hardware */ - #else - csrr a1, mhartid - #endif - la t0, esp_pm_trace_exit - jalr t0 /* absolute jump, avoid the 1 MiB range constraint */ - #endif - - #ifdef CONFIG_PM_ENABLE - la t0, esp_pm_impl_isr_hook - jalr t0 /* absolute jump, avoid the 1 MiB range constraint */ - #endif - - /* call the C dispatcher */ - mv a0, sp /* argument 1, stack pointer */ - csrr a1, mcause /* argument 2, interrupt number */ - /* mask off the interrupt flag of mcause */ - li t0, 0x7fffffff - and a1, a1, t0 - jal _global_interrupt_handler - - /* After dispatch c handler, disable interrupt to make freertos make context switch */ - - la t0, 0x8 - csrrc t0, mstatus, t0 - - /* restore the interrupt threshold level */ - la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG - sw s3, 0(t0) - fence - - /* Yield to the next task is needed: */ - mv a0, sp - call rtos_int_exit - - /* The next (or current) stack pointer is returned in a0 */ - mv sp, a0 - - /* restore the rest of the registers */ - csrw mcause, s1 - csrw mstatus, s2 - restore_mepc - restore_regs - - /* exit, this will also re-enable the interrupts */ - mret - .size _interrupt_handler, .-_interrupt_handler + /* Start by saving the general purpose registers and the PC value before + * the interrupt happened. */ + save_general_regs + save_mepc + + /* Though it is not necessary we save GP and SP here. + * SP is necessary to help GDB to properly unwind + * the backtrace of threads preempted by interrupts (OS tick etc.). + * GP is saved just to have its proper value in GDB. */ + /* As gp register is not saved by the macro, save it here */ + sw gp, RV_STK_GP(sp) + /* Same goes for the SP value before trapping */ + addi t0, sp, CONTEXT_SIZE /* restore sp with the value when interrupt happened */ + /* Save SP */ + sw t0, RV_STK_SP(sp) + + /* Before doing anythig preserve the stack pointer */ + /* It will be saved in current TCB, if needed */ + mv a0, sp + call rtos_int_enter + /* If this is a non-nested interrupt, SP now points to the interrupt stack */ + + /* Before dispatch c handler, restore interrupt to enable nested intr */ + csrr s1, mcause + csrr s2, mstatus + + /* Save the interrupt threshold level */ + la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG + lw s3, 0(t0) + + /* Increase interrupt threshold level */ + li t2, 0x7fffffff + and t1, s1, t2 /* t1 = mcause & mask */ + slli t1, t1, 2 /* t1 = mcause * 4 */ + la t2, INTC_INT_PRIO_REG(0) + add t1, t2, t1 /* t1 = INTC_INT_PRIO_REG + 4 * mcause */ + lw t2, 0(t1) /* t2 = INTC_INT_PRIO_REG[mcause] */ + addi t2, t2, 1 /* t2 = t2 +1 */ + sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */ + fence + + li t0, 0x8 + csrrs t0, mstatus, t0 + /* MIE set. Nested interrupts can now occur */ + + #ifdef CONFIG_PM_TRACE + li a0, 0 /* = ESP_PM_TRACE_IDLE */ + #if SOC_CPU_CORES_NUM == 1 + li a1, 0 /* No need to check core ID on single core hardware */ + #else + csrr a1, mhartid + #endif + la t0, esp_pm_trace_exit + jalr t0 /* absolute jump, avoid the 1 MiB range constraint */ + #endif + + #ifdef CONFIG_PM_ENABLE + la t0, esp_pm_impl_isr_hook + jalr t0 /* absolute jump, avoid the 1 MiB range constraint */ + #endif + + /* call the C dispatcher */ + mv a0, sp /* argument 1, stack pointer */ + mv a1, s1 /* argument 2, interrupt number (mcause) */ + /* mask off the interrupt flag of mcause */ + li t0, 0x7fffffff + and a1, a1, t0 + jal _global_interrupt_handler + + /* After dispatch c handler, disable interrupt to make freertos make context switch */ + + li t0, 0x8 + csrrc t0, mstatus, t0 + /* MIE cleared. Nested interrupts are disabled */ + + /* restore the interrupt threshold level */ + la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG + sw s3, 0(t0) + fence + + /* Yield to the next task is needed: */ + mv a0, sp + call rtos_int_exit + /* If this is a non-nested interrupt, context switch called, SP now points to back to task stack. */ + + /* The next (or current) stack pointer is returned in a0 */ + mv sp, a0 + + /* restore the rest of the registers */ + csrw mcause, s1 + csrw mstatus, s2 + restore_mepc + restore_general_regs + + /* exit, this will also re-enable the interrupts */ + mret + .size _interrupt_handler, .-_interrupt_handler diff --git a/components/soc/esp32/include/soc/efuse_reg.h b/components/soc/esp32/include/soc/efuse_reg.h index 937585d9ba20..0c7d3d50325b 100644 --- a/components/soc/esp32/include/soc/efuse_reg.h +++ b/components/soc/esp32/include/soc/efuse_reg.h @@ -116,6 +116,7 @@ #define EFUSE_RD_CHIP_VER_PKG_ESP32U4WDH 4 #define EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 5 #define EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302 6 +#define EFUSE_RD_CHIP_VER_PKG_ESP32D0WDR2V3 7 /* EFUSE_RD_SPI_PAD_CONFIG_HD : RO ;bitpos:[8:4] ;default: 5'b0 ; */ /*description: read for SPI_pad_config_hd*/ #define EFUSE_RD_SPI_PAD_CONFIG_HD 0x0000001F diff --git a/components/soc/esp32/include/soc/uart_channel.h b/components/soc/esp32/include/soc/uart_channel.h index 5b8dc56d5ae2..89c6a8956ccf 100644 --- a/components/soc/esp32/include/soc/uart_channel.h +++ b/components/soc/esp32/include/soc/uart_channel.h @@ -1,16 +1,10 @@ -// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// This file defines GPIO lookup macros for available UART IO_MUX pins on ESP32. #ifndef _SOC_UART_CHANNEL_H #define _SOC_UART_CHANNEL_H diff --git a/components/soc/esp32c3/include/soc/efuse_reg.h b/components/soc/esp32c3/include/soc/efuse_reg.h index aca7304f5300..2522821041e0 100644 --- a/components/soc/esp32c3/include/soc/efuse_reg.h +++ b/components/soc/esp32c3/include/soc/efuse_reg.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_EFUSE_REG_H_ #define _SOC_EFUSE_REG_H_ @@ -264,11 +256,17 @@ extern "C" { #define EFUSE_KEY_PURPOSE_2_S 0 #define EFUSE_PGM_DATA4_REG (DR_REG_EFUSE_BASE + 0x010) -/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[31:30] ;default: 2'h0 ; */ +/* EFUSE_ERR_RST_ENABLE : RO ;bitpos:[31] ;default: 1'h0 ; */ +/*description: Use BLOCK0 to check error record registers, 0 - without check.*/ +#define EFUSE_ERR_RST_ENABLE (BIT(31)) +#define EFUSE_ERR_RST_ENABLE_M (BIT(31)) +#define EFUSE_ERR_RST_ENABLE_V 0x1 +#define EFUSE_ERR_RST_ENABLE_S 31 +/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[30] ;default: 1'h0 ; */ /*description: Reserved (used for four backups method).*/ -#define EFUSE_RPT4_RESERVED1 0x00000003 -#define EFUSE_RPT4_RESERVED1_M ((EFUSE_RPT4_RESERVED1_V)<<(EFUSE_RPT4_RESERVED1_S)) -#define EFUSE_RPT4_RESERVED1_V 0x3 +#define EFUSE_RPT4_RESERVED1 (BIT(30)) +#define EFUSE_RPT4_RESERVED1_M (BIT(30)) +#define EFUSE_RPT4_RESERVED1_V 0x1 #define EFUSE_RPT4_RESERVED1_S 30 /* EFUSE_SECURE_VERSION : R/W ;bitpos:[29:14] ;default: 16'h0 ; */ /*description: Secure version (used by ESP-IDF anti-rollback feature).*/ @@ -282,30 +280,12 @@ extern "C" { #define EFUSE_FORCE_SEND_RESUME_M (BIT(13)) #define EFUSE_FORCE_SEND_RESUME_V 0x1 #define EFUSE_FORCE_SEND_RESUME_S 13 -/* EFUSE_FLASH_ECC_EN : R/W ;bitpos:[12] ;default: 1'b0 ; */ -/*description: Set 1 to enable ECC for flash boot.*/ -#define EFUSE_FLASH_ECC_EN (BIT(12)) -#define EFUSE_FLASH_ECC_EN_M (BIT(12)) -#define EFUSE_FLASH_ECC_EN_V 0x1 -#define EFUSE_FLASH_ECC_EN_S 12 -/* EFUSE_FLASH_PAGE_SIZE : R/W ;bitpos:[11:10] ;default: 2'h0 ; */ -/*description: Set Flash page size.*/ -#define EFUSE_FLASH_PAGE_SIZE 0x00000003 -#define EFUSE_FLASH_PAGE_SIZE_M ((EFUSE_FLASH_PAGE_SIZE_V)<<(EFUSE_FLASH_PAGE_SIZE_S)) -#define EFUSE_FLASH_PAGE_SIZE_V 0x3 -#define EFUSE_FLASH_PAGE_SIZE_S 10 -/* EFUSE_FLASH_TYPE : R/W ;bitpos:[9] ;default: 1'b0 ; */ -/*description: Set the maximum lines of SPI flash. 0: four lines. 1: eight lines.*/ -#define EFUSE_FLASH_TYPE (BIT(9)) -#define EFUSE_FLASH_TYPE_M (BIT(9)) -#define EFUSE_FLASH_TYPE_V 0x1 -#define EFUSE_FLASH_TYPE_S 9 -/* EFUSE_PIN_POWER_SELECTION : R/W ;bitpos:[8] ;default: 1'b0 ; */ -/*description: GPIO33-GPIO37 power supply selection in ROM code. 0: VDD3P3_CPU. 1: VDD_SPI.*/ -#define EFUSE_PIN_POWER_SELECTION (BIT(8)) -#define EFUSE_PIN_POWER_SELECTION_M (BIT(8)) -#define EFUSE_PIN_POWER_SELECTION_V 0x1 -#define EFUSE_PIN_POWER_SELECTION_S 8 +/* EFUSE_RPT4_RESERVED7 : R/W ;bitpos:[12:8] ;default: 5'h0 ; */ +/*description: Reserved (used for four backups method).*/ +#define EFUSE_RPT4_RESERVED7 0x0000001F +#define EFUSE_RPT4_RESERVED7_M ((EFUSE_RPT4_RESERVED7_V)<<(EFUSE_RPT4_RESERVED7_S)) +#define EFUSE_RPT4_RESERVED7_V 0x1F +#define EFUSE_RPT4_RESERVED7_S 8 /* EFUSE_UART_PRINT_CONTROL : R/W ;bitpos:[7:6] ;default: 2'h0 ; */ /*description: Set the default UARTboot message output mode. 00: Enabled. 01: Enabled when GPIO8 is low at reset. 10: Enabled when GPIO8 is high at reset. 11:disabled.*/ @@ -319,31 +299,30 @@ extern "C" { #define EFUSE_ENABLE_SECURITY_DOWNLOAD_M (BIT(5)) #define EFUSE_ENABLE_SECURITY_DOWNLOAD_V 0x1 #define EFUSE_ENABLE_SECURITY_DOWNLOAD_S 5 -/* EFUSE_DIS_USB_DOWNLOAD_MODE : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: Set this bit to disable UART download mode through USB.*/ -#define EFUSE_DIS_USB_DOWNLOAD_MODE (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_M (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_V 0x1 -#define EFUSE_DIS_USB_DOWNLOAD_MODE_S 4 -/* EFUSE_FLASH_ECC_MODE : R/W ;bitpos:[3] ;default: 1'b0 ; */ -/*description: Set ECC mode in ROM 0: ROM would Enable Flash ECC 16to18 byte - mode. 1:ROM would use 16to17 byte mode.*/ -#define EFUSE_FLASH_ECC_MODE (BIT(3)) -#define EFUSE_FLASH_ECC_MODE_M (BIT(3)) -#define EFUSE_FLASH_ECC_MODE_V 0x1 -#define EFUSE_FLASH_ECC_MODE_S 3 -/* EFUSE_UART_PRINT_CHANNEL : R/W ;bitpos:[2] ;default: 1'b0 ; */ -/*description: Selectes the default UART print channel. 0: UART0. 1: UART1.*/ -#define EFUSE_UART_PRINT_CHANNEL (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_M (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_V 0x1 -#define EFUSE_UART_PRINT_CHANNEL_S 2 -/* EFUSE_DIS_LEGACY_SPI_BOOT : R/W ;bitpos:[1] ;default: 1'b0 ; */ -/*description: Set this bit to disable Legacy SPI boot mode (boot_mode[3:0] = 4).*/ -#define EFUSE_DIS_LEGACY_SPI_BOOT (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_M (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_V 0x1 -#define EFUSE_DIS_LEGACY_SPI_BOOT_S 1 +/* EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: Set this bit to disable download through USB-Serial-JTAG.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_M (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_S 4 +/* EFUSE_RPT4_RESERVED8 : R/W ;bitpos:[3] ;default: 1'b0 ; */ +/*description: Reserved (used for four backups method).*/ +#define EFUSE_RPT4_RESERVED8 (BIT(3)) +#define EFUSE_RPT4_RESERVED8_M (BIT(3)) +#define EFUSE_RPT4_RESERVED8_V 0x1 +#define EFUSE_RPT4_RESERVED8_S 3 +/* EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT : R/W ;bitpos:[2] ;default: 1'b0 ; */ +/*description: Disable USB-Serial-JTAG print during rom boot.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_M (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_S 2 +/* EFUSE_DIS_DIRECT_BOOT : R/W ;bitpos:[1] ;default: 1'b0 ; */ +/*description: Set this bit to disable direct boot*/ +#define EFUSE_DIS_DIRECT_BOOT (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_M (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_V 0x1 +#define EFUSE_DIS_DIRECT_BOOT_S 1 /* EFUSE_DIS_DOWNLOAD_MODE : R/W ;bitpos:[0] ;default: 1'b0 ; */ /*description: Set this bit to disable download mode (boot_mode[3:0] = 0 1 2 3 6 7).*/ #define EFUSE_DIS_DOWNLOAD_MODE (BIT(0)) @@ -636,11 +615,17 @@ extern "C" { #define EFUSE_KEY_PURPOSE_2_S 0 #define EFUSE_RD_REPEAT_DATA3_REG (DR_REG_EFUSE_BASE + 0x03C) -/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[31:30] ;default: 2'h0 ; */ +/* EFUSE_ERR_RST_ENABLE : RO ;bitpos:[31] ;default: 1'h0 ; */ +/*description: Use BLOCK0 to check error record registers, 0 - without check.*/ +#define EFUSE_ERR_RST_ENABLE (BIT(31)) +#define EFUSE_ERR_RST_ENABLE_M (BIT(31)) +#define EFUSE_ERR_RST_ENABLE_V 0x1 +#define EFUSE_ERR_RST_ENABLE_S 31 +/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[30] ;default: 1'h0 ; */ /*description: Reserved.*/ -#define EFUSE_RPT4_RESERVED1 0x00000003 -#define EFUSE_RPT4_RESERVED1_M ((EFUSE_RPT4_RESERVED1_V)<<(EFUSE_RPT4_RESERVED1_S)) -#define EFUSE_RPT4_RESERVED1_V 0x3 +#define EFUSE_RPT4_RESERVED1 (BIT(30)) +#define EFUSE_RPT4_RESERVED1_M (BIT(30)) +#define EFUSE_RPT4_RESERVED1_V 0x1 #define EFUSE_RPT4_RESERVED1_S 30 /* EFUSE_SECURE_VERSION : RO ;bitpos:[29:14] ;default: 16'h0 ; */ /*description: The value of SECURE_VERSION.*/ @@ -654,30 +639,12 @@ extern "C" { #define EFUSE_FORCE_SEND_RESUME_M (BIT(13)) #define EFUSE_FORCE_SEND_RESUME_V 0x1 #define EFUSE_FORCE_SEND_RESUME_S 13 -/* EFUSE_FLASH_ECC_EN : RO ;bitpos:[12] ;default: 1'b0 ; */ -/*description: The value of FLASH_ECC_EN.*/ -#define EFUSE_FLASH_ECC_EN (BIT(12)) -#define EFUSE_FLASH_ECC_EN_M (BIT(12)) -#define EFUSE_FLASH_ECC_EN_V 0x1 -#define EFUSE_FLASH_ECC_EN_S 12 -/* EFUSE_FLASH_PAGE_SIZE : RO ;bitpos:[11:10] ;default: 2'h0 ; */ -/*description: The value of FLASH_PAGE_SIZE.*/ -#define EFUSE_FLASH_PAGE_SIZE 0x00000003 -#define EFUSE_FLASH_PAGE_SIZE_M ((EFUSE_FLASH_PAGE_SIZE_V)<<(EFUSE_FLASH_PAGE_SIZE_S)) -#define EFUSE_FLASH_PAGE_SIZE_V 0x3 -#define EFUSE_FLASH_PAGE_SIZE_S 10 -/* EFUSE_FLASH_TYPE : RO ;bitpos:[9] ;default: 1'b0 ; */ -/*description: The value of FLASH_TYPE.*/ -#define EFUSE_FLASH_TYPE (BIT(9)) -#define EFUSE_FLASH_TYPE_M (BIT(9)) -#define EFUSE_FLASH_TYPE_V 0x1 -#define EFUSE_FLASH_TYPE_S 9 -/* EFUSE_PIN_POWER_SELECTION : RO ;bitpos:[8] ;default: 1'b0 ; */ -/*description: The value of PIN_POWER_SELECTION.*/ -#define EFUSE_PIN_POWER_SELECTION (BIT(8)) -#define EFUSE_PIN_POWER_SELECTION_M (BIT(8)) -#define EFUSE_PIN_POWER_SELECTION_V 0x1 -#define EFUSE_PIN_POWER_SELECTION_S 8 +/* EFUSE_RPT4_RESERVED7 : RO ;bitpos:[12:8] ;default: 5'h0 ; */ +/*description: Reserved.*/ +#define EFUSE_RPT4_RESERVED7 0x0000001F +#define EFUSE_RPT4_RESERVED7_M ((EFUSE_RPT4_RESERVED7_V)<<(EFUSE_RPT4_RESERVED7_S)) +#define EFUSE_RPT4_RESERVED7_V 0x1F +#define EFUSE_RPT4_RESERVED7_S 8 /* EFUSE_UART_PRINT_CONTROL : RO ;bitpos:[7:6] ;default: 2'h0 ; */ /*description: The value of UART_PRINT_CONTROL.*/ #define EFUSE_UART_PRINT_CONTROL 0x00000003 @@ -690,30 +657,30 @@ extern "C" { #define EFUSE_ENABLE_SECURITY_DOWNLOAD_M (BIT(5)) #define EFUSE_ENABLE_SECURITY_DOWNLOAD_V 0x1 #define EFUSE_ENABLE_SECURITY_DOWNLOAD_S 5 -/* EFUSE_DIS_USB_DOWNLOAD_MODE : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The value of DIS_USB_DOWNLOAD_MODE.*/ -#define EFUSE_DIS_USB_DOWNLOAD_MODE (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_M (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_V 0x1 -#define EFUSE_DIS_USB_DOWNLOAD_MODE_S 4 -/* EFUSE_FLASH_ECC_MODE : RO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: The value of FLASH_ECC_MODE.*/ -#define EFUSE_FLASH_ECC_MODE (BIT(3)) -#define EFUSE_FLASH_ECC_MODE_M (BIT(3)) -#define EFUSE_FLASH_ECC_MODE_V 0x1 -#define EFUSE_FLASH_ECC_MODE_S 3 -/* EFUSE_UART_PRINT_CHANNEL : RO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: The value of UART_PRINT_CHANNEL.*/ -#define EFUSE_UART_PRINT_CHANNEL (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_M (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_V 0x1 -#define EFUSE_UART_PRINT_CHANNEL_S 2 -/* EFUSE_DIS_LEGACY_SPI_BOOT : RO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: The value of DIS_LEGACY_SPI_BOOT.*/ -#define EFUSE_DIS_LEGACY_SPI_BOOT (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_M (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_V 0x1 -#define EFUSE_DIS_LEGACY_SPI_BOOT_S 1 +/* EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE : RO ;bitpos:[4] ;default: 1'b0 ; */ +/*description: The value of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_M (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_S 4 +/* EFUSE_RPT4_RESERVED8 : RO ;bitpos:[3] ;default: 1'b0 ; */ +/*description: Reserved.*/ +#define EFUSE_RPT4_RESERVED8 (BIT(3)) +#define EFUSE_RPT4_RESERVED8_M (BIT(3)) +#define EFUSE_RPT4_RESERVED8_V 0x1 +#define EFUSE_RPT4_RESERVED8_S 3 +/* EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT : RO ;bitpos:[2] ;default: 1'b0 ; */ +/*description: The value of DIS_USB_SERIAL_JTAG_ROM_PRINT.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_M (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_S 2 +/* EFUSE_DIS_DIRECT_BOOT : RO ;bitpos:[1] ;default: 1'b0 ; */ +/*description: The value of DIS_DIRECT_BOOT.*/ +#define EFUSE_DIS_DIRECT_BOOT (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_M (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_V 0x1 +#define EFUSE_DIS_DIRECT_BOOT_S 1 /* EFUSE_DIS_DOWNLOAD_MODE : RO ;bitpos:[0] ;default: 1'b0 ; */ /*description: The value of DIS_DOWNLOAD_MODE.*/ #define EFUSE_DIS_DOWNLOAD_MODE (BIT(0)) @@ -1468,12 +1435,12 @@ extern "C" { #define EFUSE_DIS_USB_DEVICE_ERR_M (BIT(11)) #define EFUSE_DIS_USB_DEVICE_ERR_V 0x1 #define EFUSE_DIS_USB_DEVICE_ERR_S 11 -/* EFUSE_DIS_DOWNLOAD_ICACHE : RO ;bitpos:[10] ;default: 1'b0 ; */ +/* EFUSE_DIS_DOWNLOAD_ICACHE_ERR : RO ;bitpos:[10] ;default: 1'b0 ; */ /*description: If DIS_DOWNLOAD_ICACHE is 1 then it indicates a programming error.*/ -#define EFUSE_DIS_DOWNLOAD_ICACHE (BIT(10)) -#define EFUSE_DIS_DOWNLOAD_ICACHE_M (BIT(10)) -#define EFUSE_DIS_DOWNLOAD_ICACHE_V 0x1 -#define EFUSE_DIS_DOWNLOAD_ICACHE_S 10 +#define EFUSE_DIS_DOWNLOAD_ICACHE_ERR (BIT(10)) +#define EFUSE_DIS_DOWNLOAD_ICACHE_ERR_M (BIT(10)) +#define EFUSE_DIS_DOWNLOAD_ICACHE_ERR_V 0x1 +#define EFUSE_DIS_DOWNLOAD_ICACHE_ERR_S 10 /* EFUSE_DIS_USB_JTAG_ERR : RO ;bitpos:[9] ;default: 1'b0 ; */ /*description: If DIS_USB_JTAG is 1 then it indicates a programming error.*/ #define EFUSE_DIS_USB_JTAG_ERR (BIT(9)) @@ -1606,11 +1573,17 @@ extern "C" { #define EFUSE_KEY_PURPOSE_2_ERR_S 0 #define EFUSE_RD_REPEAT_ERR3_REG (DR_REG_EFUSE_BASE + 0x188) -/* EFUSE_RPT4_RESERVED1_ERR : RO ;bitpos:[31:30] ;default: 2'h0 ; */ +/* EFUSE_ERR_RST_ENABLE_ERR : RO ;bitpos:[31] ;default: 1'h0 ; */ +/*description: Use BLOCK0 to check error record registers, 0 - without check.*/ +#define EFUSE_ERR_RST_ENABLE_ERR (BIT(31)) +#define EFUSE_ERR_RST_ENABLE_ERR_M (BIT(31)) +#define EFUSE_ERR_RST_ENABLE_ERR_V 0x1 +#define EFUSE_ERR_RST_ENABLE_ERR_S 31 +/* EFUSE_RPT4_RESERVED1_ERR : RO ;bitpos:[30] ;default: 1'h0 ; */ /*description: Reserved.*/ -#define EFUSE_RPT4_RESERVED1_ERR 0x00000003 -#define EFUSE_RPT4_RESERVED1_ERR_M ((EFUSE_RPT4_RESERVED1_ERR_V)<<(EFUSE_RPT4_RESERVED1_ERR_S)) -#define EFUSE_RPT4_RESERVED1_ERR_V 0x3 +#define EFUSE_RPT4_RESERVED1_ERR (BIT(30)) +#define EFUSE_RPT4_RESERVED1_ERR_M (BIT(30)) +#define EFUSE_RPT4_RESERVED1_ERR_V 0x1 #define EFUSE_RPT4_RESERVED1_ERR_S 30 /* EFUSE_SECURE_VERSION_ERR : RO ;bitpos:[29:14] ;default: 16'h0 ; */ /*description: If any bit in SECURE_VERSION is 1 then it indicates a programming error.*/ @@ -1624,30 +1597,12 @@ extern "C" { #define EFUSE_FORCE_SEND_RESUME_ERR_M (BIT(13)) #define EFUSE_FORCE_SEND_RESUME_ERR_V 0x1 #define EFUSE_FORCE_SEND_RESUME_ERR_S 13 -/* EFUSE_FLASH_ECC_EN : RO ;bitpos:[12] ;default: 1'b0 ; */ -/*description: If FLASH_ECC_EN_ERR is 1 then it indicates a programming error.*/ -#define EFUSE_FLASH_ECC_EN (BIT(12)) -#define EFUSE_FLASH_ECC_EN_M (BIT(12)) -#define EFUSE_FLASH_ECC_EN_V 0x1 -#define EFUSE_FLASH_ECC_EN_S 12 -/* EFUSE_FLASH_PAGE_SIZE : RO ;bitpos:[11:10] ;default: 2'h0 ; */ -/*description: If any bits in FLASH_PAGE_SIZE is 1 then it indicates a programming error.*/ -#define EFUSE_FLASH_PAGE_SIZE 0x00000003 -#define EFUSE_FLASH_PAGE_SIZE_M ((EFUSE_FLASH_PAGE_SIZE_V)<<(EFUSE_FLASH_PAGE_SIZE_S)) -#define EFUSE_FLASH_PAGE_SIZE_V 0x3 -#define EFUSE_FLASH_PAGE_SIZE_S 10 -/* EFUSE_FLASH_TYPE_ERR : RO ;bitpos:[9] ;default: 1'b0 ; */ -/*description: If FLASH_TYPE is 1 then it indicates a programming error.*/ -#define EFUSE_FLASH_TYPE_ERR (BIT(9)) -#define EFUSE_FLASH_TYPE_ERR_M (BIT(9)) -#define EFUSE_FLASH_TYPE_ERR_V 0x1 -#define EFUSE_FLASH_TYPE_ERR_S 9 -/* EFUSE_PIN_POWER_SELECTION_ERR : RO ;bitpos:[8] ;default: 1'b0 ; */ -/*description: If PIN_POWER_SELECTION is 1 then it indicates a programming error.*/ -#define EFUSE_PIN_POWER_SELECTION_ERR (BIT(8)) -#define EFUSE_PIN_POWER_SELECTION_ERR_M (BIT(8)) -#define EFUSE_PIN_POWER_SELECTION_ERR_V 0x1 -#define EFUSE_PIN_POWER_SELECTION_ERR_S 8 +/* EFUSE_RPT4_RESERVED7_ERR : RO ;bitpos:[12:8] ;default: 5'h0 ; */ +/*description: Reserved.*/ +#define EFUSE_RPT4_RESERVED7_ERR 0x0000001F +#define EFUSE_RPT4_RESERVED7_ERR_M ((EFUSE_RPT4_RESERVED7_ERR_V)<<(EFUSE_RPT4_RESERVED7_ERR_S)) +#define EFUSE_RPT4_RESERVED7_ERR_V 0x1F +#define EFUSE_RPT4_RESERVED7_ERR_S 8 /* EFUSE_UART_PRINT_CONTROL_ERR : RO ;bitpos:[7:6] ;default: 2'h0 ; */ /*description: If any bit in UART_PRINT_CONTROL is 1 then it indicates a programming error.*/ #define EFUSE_UART_PRINT_CONTROL_ERR 0x00000003 @@ -1660,30 +1615,30 @@ extern "C" { #define EFUSE_ENABLE_SECURITY_DOWNLOAD_ERR_M (BIT(5)) #define EFUSE_ENABLE_SECURITY_DOWNLOAD_ERR_V 0x1 #define EFUSE_ENABLE_SECURITY_DOWNLOAD_ERR_S 5 -/* EFUSE_DIS_USB_DOWNLOAD_MODE_ERR : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: If DIS_USB_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR_M (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR_V 0x1 -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR_S 4 -/* EFUSE_FLASH_ECC_MODE_ERR : RO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: If FLASH_ECC_MODE is 1 then it indicates a programming error.*/ -#define EFUSE_FLASH_ECC_MODE_ERR (BIT(3)) -#define EFUSE_FLASH_ECC_MODE_ERR_M (BIT(3)) -#define EFUSE_FLASH_ECC_MODE_ERR_V 0x1 -#define EFUSE_FLASH_ECC_MODE_ERR_S 3 -/* EFUSE_UART_PRINT_CHANNEL_ERR : RO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: If UART_PRINT_CHANNEL is 1 then it indicates a programming error.*/ -#define EFUSE_UART_PRINT_CHANNEL_ERR (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_ERR_M (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_ERR_V 0x1 -#define EFUSE_UART_PRINT_CHANNEL_ERR_S 2 -/* EFUSE_DIS_LEGACY_SPI_BOOT_ERR : RO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: If DIS_LEGACY_SPI_BOOT is 1 then it indicates a programming error.*/ -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR_M (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR_V 0x1 -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR_S 1 +/* EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR : RO ;bitpos:[4] ;default: 1'b0 ; */ +/*description: If DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR_M (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR_S 4 +/* EFUSE_RPT4_RESERVED8_ERR : RO ;bitpos:[3] ;default: 1'b0 ; */ +/*description: Reserved.*/ +#define EFUSE_RPT4_RESERVED8_ERR (BIT(3)) +#define EFUSE_RPT4_RESERVED8_ERR_M (BIT(3)) +#define EFUSE_RPT4_RESERVED8_ERR_V 0x1 +#define EFUSE_RPT4_RESERVED8_ERR_S 3 +/* EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR : RO ;bitpos:[2] ;default: 1'b0 ; */ +/*description: If DIS_USB_SERIAL_JTAG_ROM_PRINT is 1 then it indicates a programming error.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR_M (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR_S 2 +/* EFUSE_DIS_DIRECT_BOOT_ERR : RO ;bitpos:[1] ;default: 1'b0 ; */ +/*description: If DIS_DIRECT_BOOT is 1 then it indicates a programming error.*/ +#define EFUSE_DIS_DIRECT_BOOT_ERR (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_ERR_M (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_ERR_V 0x1 +#define EFUSE_DIS_DIRECT_BOOT_ERR_S 1 /* EFUSE_DIS_DOWNLOAD_MODE_ERR : RO ;bitpos:[0] ;default: 1'b0 ; */ /*description: If DIS_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ #define EFUSE_DIS_DOWNLOAD_MODE_ERR (BIT(0)) @@ -1700,104 +1655,97 @@ extern "C" { #define EFUSE_RPT4_RESERVED4_ERR_S 0 #define EFUSE_RD_RS_ERR0_REG (DR_REG_EFUSE_BASE + 0x1C0) -/* EFUSE_KEY4_FAIL : RO ;bitpos:[31] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of key$n is reliable 1: - Means that programming key$n failed and the number of error bytes is over 6.*/ -#define EFUSE_KEY4_FAIL (BIT(31)) -#define EFUSE_KEY4_FAIL_M (BIT(31)) -#define EFUSE_KEY4_FAIL_V 0x1 -#define EFUSE_KEY4_FAIL_S 31 +/* EFUSE_KEY3_FAIL : RO ;bitpos:[31] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of key3 is reliable 1: + Means that programming key3 failed and the number of error bytes is over 6.*/ +#define EFUSE_KEY3_FAIL (BIT(31)) +#define EFUSE_KEY3_FAIL_M (BIT(31)) +#define EFUSE_KEY3_FAIL_V 0x1 +#define EFUSE_KEY3_FAIL_S 31 /* EFUSE_KEY4_ERR_NUM : RO ;bitpos:[30:28] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_KEY4_ERR_NUM 0x00000007 #define EFUSE_KEY4_ERR_NUM_M ((EFUSE_KEY4_ERR_NUM_V)<<(EFUSE_KEY4_ERR_NUM_S)) #define EFUSE_KEY4_ERR_NUM_V 0x7 #define EFUSE_KEY4_ERR_NUM_S 28 -/* EFUSE_KEY3_FAIL : RO ;bitpos:[27] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of key$n is reliable 1: - Means that programming key$n failed and the number of error bytes is over 6.*/ -#define EFUSE_KEY3_FAIL (BIT(27)) -#define EFUSE_KEY3_FAIL_M (BIT(27)) -#define EFUSE_KEY3_FAIL_V 0x1 -#define EFUSE_KEY3_FAIL_S 27 +/* EFUSE_KEY2_FAIL : RO ;bitpos:[27] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of key2 is reliable 1: + Means that programming key2 failed and the number of error bytes is over 6.*/ +#define EFUSE_KEY2_FAIL (BIT(27)) +#define EFUSE_KEY2_FAIL_M (BIT(27)) +#define EFUSE_KEY2_FAIL_V 0x1 +#define EFUSE_KEY2_FAIL_S 27 /* EFUSE_KEY3_ERR_NUM : RO ;bitpos:[26:24] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_KEY3_ERR_NUM 0x00000007 #define EFUSE_KEY3_ERR_NUM_M ((EFUSE_KEY3_ERR_NUM_V)<<(EFUSE_KEY3_ERR_NUM_S)) #define EFUSE_KEY3_ERR_NUM_V 0x7 #define EFUSE_KEY3_ERR_NUM_S 24 -/* EFUSE_KEY2_FAIL : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of key$n is reliable 1: - Means that programming key$n failed and the number of error bytes is over 6.*/ -#define EFUSE_KEY2_FAIL (BIT(23)) -#define EFUSE_KEY2_FAIL_M (BIT(23)) -#define EFUSE_KEY2_FAIL_V 0x1 -#define EFUSE_KEY2_FAIL_S 23 +/* EFUSE_KEY1_FAIL : RO ;bitpos:[23] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of key1 is reliable 1: + Means that programming key1 failed and the number of error bytes is over 6.*/ +#define EFUSE_KEY1_FAIL (BIT(23)) +#define EFUSE_KEY1_FAIL_M (BIT(23)) +#define EFUSE_KEY1_FAIL_V 0x1 +#define EFUSE_KEY1_FAIL_S 23 /* EFUSE_KEY2_ERR_NUM : RO ;bitpos:[22:20] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_KEY2_ERR_NUM 0x00000007 #define EFUSE_KEY2_ERR_NUM_M ((EFUSE_KEY2_ERR_NUM_V)<<(EFUSE_KEY2_ERR_NUM_S)) #define EFUSE_KEY2_ERR_NUM_V 0x7 #define EFUSE_KEY2_ERR_NUM_S 20 -/* EFUSE_KEY1_FAIL : RO ;bitpos:[19] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of key$n is reliable 1: - Means that programming key$n failed and the number of error bytes is over 6.*/ -#define EFUSE_KEY1_FAIL (BIT(19)) -#define EFUSE_KEY1_FAIL_M (BIT(19)) -#define EFUSE_KEY1_FAIL_V 0x1 -#define EFUSE_KEY1_FAIL_S 19 +/* EFUSE_KEY0_FAIL : RO ;bitpos:[19] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of key0 is reliable 1: + Means that programming key0 failed and the number of error bytes is over 6.*/ +#define EFUSE_KEY0_FAIL (BIT(19)) +#define EFUSE_KEY0_FAIL_M (BIT(19)) +#define EFUSE_KEY0_FAIL_V 0x1 +#define EFUSE_KEY0_FAIL_S 19 /* EFUSE_KEY1_ERR_NUM : RO ;bitpos:[18:16] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_KEY1_ERR_NUM 0x00000007 #define EFUSE_KEY1_ERR_NUM_M ((EFUSE_KEY1_ERR_NUM_V)<<(EFUSE_KEY1_ERR_NUM_S)) #define EFUSE_KEY1_ERR_NUM_V 0x7 #define EFUSE_KEY1_ERR_NUM_S 16 -/* EFUSE_KEY0_FAIL : RO ;bitpos:[15] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of key$n is reliable 1: - Means that programming key$n failed and the number of error bytes is over 6.*/ -#define EFUSE_KEY0_FAIL (BIT(15)) -#define EFUSE_KEY0_FAIL_M (BIT(15)) -#define EFUSE_KEY0_FAIL_V 0x1 -#define EFUSE_KEY0_FAIL_S 15 +/* EFUSE_USR_DATA_FAIL : RO ;bitpos:[15] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of user data is reliable + 1: Means that programming user data failed and the number of error bytes is over 6.*/ +#define EFUSE_USR_DATA_FAIL (BIT(15)) +#define EFUSE_USR_DATA_FAIL_M (BIT(15)) +#define EFUSE_USR_DATA_FAIL_V 0x1 +#define EFUSE_USR_DATA_FAIL_S 15 /* EFUSE_KEY0_ERR_NUM : RO ;bitpos:[14:12] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_KEY0_ERR_NUM 0x00000007 #define EFUSE_KEY0_ERR_NUM_M ((EFUSE_KEY0_ERR_NUM_V)<<(EFUSE_KEY0_ERR_NUM_S)) #define EFUSE_KEY0_ERR_NUM_V 0x7 #define EFUSE_KEY0_ERR_NUM_S 12 -/* EFUSE_USR_DATA_FAIL : RO ;bitpos:[11] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the user data is reliable 1: Means - that programming user data failed and the number of error bytes is over 6.*/ -#define EFUSE_USR_DATA_FAIL (BIT(11)) -#define EFUSE_USR_DATA_FAIL_M (BIT(11)) -#define EFUSE_USR_DATA_FAIL_V 0x1 -#define EFUSE_USR_DATA_FAIL_S 11 +/* EFUSE_SYS_PART1_FAIL : RO ;bitpos:[11] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of system part1 is reliable + 1: Means that programming data of system part1 failed and the number of error bytes is over 6.*/ +#define EFUSE_SYS_PART1_FAIL (BIT(11)) +#define EFUSE_SYS_PART1_FAIL_M (BIT(11)) +#define EFUSE_SYS_PART1_FAIL_V 0x1 +#define EFUSE_SYS_PART1_FAIL_S 11 /* EFUSE_USR_DATA_ERR_NUM : RO ;bitpos:[10:8] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_USR_DATA_ERR_NUM 0x00000007 #define EFUSE_USR_DATA_ERR_NUM_M ((EFUSE_USR_DATA_ERR_NUM_V)<<(EFUSE_USR_DATA_ERR_NUM_S)) #define EFUSE_USR_DATA_ERR_NUM_V 0x7 #define EFUSE_USR_DATA_ERR_NUM_S 8 -/* EFUSE_SYS_PART1_FAIL : RO ;bitpos:[7] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of system part1 is reliable - 1: Means that programming user data failed and the number of error bytes is over 6.*/ -#define EFUSE_SYS_PART1_FAIL (BIT(7)) -#define EFUSE_SYS_PART1_FAIL_M (BIT(7)) -#define EFUSE_SYS_PART1_FAIL_V 0x1 -#define EFUSE_SYS_PART1_FAIL_S 7 +/* EFUSE_MAC_SPI_8M_FAIL : RO ;bitpos:[7] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of MAC_SPI_8M is reliable + 1: Means that programming MAC_SPI_8M failed and the number of error bytes is over 6.*/ +#define EFUSE_MAC_SPI_8M_FAIL (BIT(7)) +#define EFUSE_MAC_SPI_8M_FAIL_M (BIT(7)) +#define EFUSE_MAC_SPI_8M_FAIL_V 0x1 +#define EFUSE_MAC_SPI_8M_FAIL_S 7 /* EFUSE_SYS_PART1_NUM : RO ;bitpos:[6:4] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_SYS_PART1_NUM 0x00000007 #define EFUSE_SYS_PART1_NUM_M ((EFUSE_SYS_PART1_NUM_V)<<(EFUSE_SYS_PART1_NUM_S)) #define EFUSE_SYS_PART1_NUM_V 0x7 #define EFUSE_SYS_PART1_NUM_S 4 -/* EFUSE_MAC_SPI_8M_FAIL : RO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of MAC_SPI_8M is reliable - 1: Means that programming user data failed and the number of error bytes is over 6.*/ -#define EFUSE_MAC_SPI_8M_FAIL (BIT(3)) -#define EFUSE_MAC_SPI_8M_FAIL_M (BIT(3)) -#define EFUSE_MAC_SPI_8M_FAIL_V 0x1 -#define EFUSE_MAC_SPI_8M_FAIL_S 3 /* EFUSE_MAC_SPI_8M_ERR_NUM : RO ;bitpos:[2:0] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_MAC_SPI_8M_ERR_NUM 0x00000007 @@ -1806,26 +1754,26 @@ extern "C" { #define EFUSE_MAC_SPI_8M_ERR_NUM_S 0 #define EFUSE_RD_RS_ERR1_REG (DR_REG_EFUSE_BASE + 0x1C4) -/* EFUSE_SYS_PART2_FAIL : RO ;bitpos:[7] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of system part2 is reliable - 1: Means that programming user data failed and the number of error bytes is over 6.*/ -#define EFUSE_SYS_PART2_FAIL (BIT(7)) -#define EFUSE_SYS_PART2_FAIL_M (BIT(7)) -#define EFUSE_SYS_PART2_FAIL_V 0x1 -#define EFUSE_SYS_PART2_FAIL_S 7 +/* EFUSE_KEY5_FAIL : RO ;bitpos:[7] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of KEY5 is reliable 1: + Means that programming KEY5 failed and the number of error bytes is over 6.*/ +#define EFUSE_KEY5_FAIL (BIT(7)) +#define EFUSE_KEY5_FAIL_M (BIT(7)) +#define EFUSE_KEY5_FAIL_V 0x1 +#define EFUSE_KEY5_FAIL_S 7 /* EFUSE_SYS_PART2_ERR_NUM : RO ;bitpos:[6:4] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_SYS_PART2_ERR_NUM 0x00000007 #define EFUSE_SYS_PART2_ERR_NUM_M ((EFUSE_SYS_PART2_ERR_NUM_V)<<(EFUSE_SYS_PART2_ERR_NUM_S)) #define EFUSE_SYS_PART2_ERR_NUM_V 0x7 #define EFUSE_SYS_PART2_ERR_NUM_S 4 -/* EFUSE_KEY5_FAIL : RO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: 0: Means no failure and that the data of KEY5 is reliable 1: - Means that programming user data failed and the number of error bytes is over 6.*/ -#define EFUSE_KEY5_FAIL (BIT(3)) -#define EFUSE_KEY5_FAIL_M (BIT(3)) -#define EFUSE_KEY5_FAIL_V 0x1 -#define EFUSE_KEY5_FAIL_S 3 +/* EFUSE_KEY4_FAIL : RO ;bitpos:[3] ;default: 1'b0 ; */ +/*description: 0: Means no failure and that the data of KEY4 is reliable 1: + Means that programming KEY4 failed and the number of error bytes is over 6.*/ +#define EFUSE_KEY4_FAIL (BIT(3)) +#define EFUSE_KEY4_FAIL_M (BIT(3)) +#define EFUSE_KEY4_FAIL_V 0x1 +#define EFUSE_KEY4_FAIL_S 3 /* EFUSE_KEY5_ERR_NUM : RO ;bitpos:[2:0] ;default: 3'h0 ; */ /*description: The value of this signal means the number of error bytes.*/ #define EFUSE_KEY5_ERR_NUM 0x00000007 @@ -1867,6 +1815,9 @@ extern "C" { #define EFUSE_OP_CODE_V 0xFFFF #define EFUSE_OP_CODE_S 0 +#define EFUSE_WRITE_OP_CODE 0x5a5a +#define EFUSE_READ_OP_CODE 0x5aa5 + #define EFUSE_STATUS_REG (DR_REG_EFUSE_BASE + 0x1D0) /* EFUSE_REPEAT_ERR_CNT : RO ;bitpos:[17:10] ;default: 8'h0 ; */ /*description: Indicates the number of error bits during programming BLOCK0.*/ diff --git a/components/soc/esp32c3/include/soc/efuse_struct.h b/components/soc/esp32c3/include/soc/efuse_struct.h index 24915ba81049..9cb4b01e4498 100644 --- a/components/soc/esp32c3/include/soc/efuse_struct.h +++ b/components/soc/esp32c3/include/soc/efuse_struct.h @@ -73,20 +73,18 @@ typedef volatile struct efuse_dev_s { } pgm_data3; union { struct { - uint32_t dis_download_mode: 1; /*Set this bit to disable download mode (boot_mode[3:0] = 0 1 2 3 6 7).*/ - uint32_t dis_legacy_spi_boot: 1; /*Set this bit to disable Legacy SPI boot mode (boot_mode[3:0] = 4).*/ - uint32_t uart_print_channel: 1; /*Selectes the default UART print channel. 0: UART0. 1: UART1.*/ - uint32_t flash_ecc_mode: 1; /*Set ECC mode in ROM 0: ROM would Enable Flash ECC 16to18 byte mode. 1:ROM would use 16to17 byte mode.*/ - uint32_t dis_usb_download_mode: 1; /*Set this bit to disable UART download mode through USB.*/ - uint32_t enable_security_download: 1; /*Set this bit to enable secure UART download mode.*/ - uint32_t uart_print_control: 2; /*Set the default UARTboot message output mode. 00: Enabled. 01: Enabled when GPIO8 is low at reset. 10: Enabled when GPIO8 is high at reset. 11:disabled.*/ - uint32_t pin_power_selection: 1; /*GPIO33-GPIO37 power supply selection in ROM code. 0: VDD3P3_CPU. 1: VDD_SPI.*/ - uint32_t flash_type: 1; /*Set the maximum lines of SPI flash. 0: four lines. 1: eight lines.*/ - uint32_t flash_page_size: 2; /*Set Flash page size.*/ - uint32_t flash_ecc_en: 1; /*Set 1 to enable ECC for flash boot.*/ - uint32_t force_send_resume: 1; /*Set this bit to force ROM code to send a resume command during SPI boot.*/ - uint32_t secure_version: 16; /*Secure version (used by ESP-IDF anti-rollback feature).*/ - uint32_t rpt4_reserved1: 2; /*Reserved (used for four backups method).*/ + uint32_t dis_download_mode: 1; /*Set this bit to disable download mode (boot_mode[3:0] = 0 1 2 3 6 7).*/ + uint32_t dis_direct_boot: 1; /*Set this bit to disable direct boot.*/ + uint32_t dis_usb_serial_jtag_rom_print: 1; /*Set this bit to disable USB-Serial-JTAG print during rom boot*/ + uint32_t rpt4_reserved8: 1; /*Reserved (used for four backups method).*/ + uint32_t dis_usb_serial_jtag_download_mode: 1; /*Set this bit to disable download mode through USB-Serial-JTAG.*/ + uint32_t enable_security_download: 1; /*Set this bit to enable secure UART download mode.*/ + uint32_t uart_print_control: 2; /*Set the default UARTboot message output mode. 00: Enabled. 01: Enabled when GPIO8 is low at reset. 10: Enabled when GPIO8 is high at reset. 11:disabled.*/ + uint32_t rpt4_reserved7: 5; /*Reserved (used for four backups method).*/ + uint32_t force_send_resume: 1; /*Set this bit to force ROM code to send a resume command during SPI boot.*/ + uint32_t secure_version: 16; /*Secure version (used by ESP-IDF anti-rollback feature).*/ + uint32_t rpt4_reserved1: 1; /*Reserved (used for four backups method).*/ + uint32_t err_rst_enable: 1; /*Use BLOCK0 to check error record registers, 0 - without check.*/ }; uint32_t val; } pgm_data4; @@ -158,19 +156,17 @@ typedef volatile struct efuse_dev_s { union { struct { uint32_t dis_download_mode: 1; /*The value of DIS_DOWNLOAD_MODE.*/ - uint32_t dis_legacy_spi_boot: 1; /*The value of DIS_LEGACY_SPI_BOOT.*/ - uint32_t uart_print_channel: 1; /*The value of UART_PRINT_CHANNEL.*/ - uint32_t flash_ecc_mode: 1; /*The value of FLASH_ECC_MODE.*/ - uint32_t dis_usb_download_mode: 1; /*The value of DIS_USB_DOWNLOAD_MODE.*/ + uint32_t dis_direct_boot: 1; /*The value of DIS_DIRECT_BOOT.*/ + uint32_t dis_usb_serial_jtag_rom_print:1; /*The value of DIS_USB_SERIAL_JTAG_ROM_PRINT.*/ + uint32_t rpt4_reserved8: 1; /*Reserved.*/ + uint32_t dis_usb_serial_jtag_download_mode: 1; /*The value of dis_usb_serial_jtag_download_mode.*/ uint32_t enable_security_download: 1; /*The value of ENABLE_SECURITY_DOWNLOAD.*/ uint32_t uart_print_control: 2; /*The value of UART_PRINT_CONTROL.*/ - uint32_t pin_power_selection: 1; /*The value of PIN_POWER_SELECTION.*/ - uint32_t flash_type: 1; /*The value of FLASH_TYPE.*/ - uint32_t flash_page_size: 2; /*The value of FLASH_PAGE_SIZE.*/ - uint32_t flash_ecc_en: 1; /*The value of FLASH_ECC_EN.*/ + uint32_t rpt4_reserved7: 5; /*Reserved.*/ uint32_t force_send_resume: 1; /*The value of FORCE_SEND_RESUME.*/ uint32_t secure_version: 16; /*The value of SECURE_VERSION.*/ - uint32_t rpt4_reserved1: 2; /*Reserved.*/ + uint32_t rpt4_reserved1: 1; /*Reserved.*/ + uint32_t err_rst_enable: 1; /*Use BLOCK0 to check error record registers, 0 - without check.*/ }; uint32_t val; } rd_repeat_data3; @@ -325,20 +321,18 @@ typedef volatile struct efuse_dev_s { } rd_repeat_err2; union { struct { - uint32_t dis_download_mode_err: 1; /*If DIS_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ - uint32_t dis_legacy_spi_boot_err: 1; /*If DIS_LEGACY_SPI_BOOT is 1 then it indicates a programming error.*/ - uint32_t uart_print_channel_err: 1; /*If UART_PRINT_CHANNEL is 1 then it indicates a programming error.*/ - uint32_t flash_ecc_mode_err: 1; /*If FLASH_ECC_MODE is 1 then it indicates a programming error.*/ - uint32_t dis_usb_download_mode_err: 1; /*If DIS_USB_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ - uint32_t enable_security_download_err: 1; /*If ENABLE_SECURITY_DOWNLOAD is 1 then it indicates a programming error.*/ - uint32_t uart_print_control_err: 2; /*If any bit in UART_PRINT_CONTROL is 1 then it indicates a programming error.*/ - uint32_t pin_power_selection_err: 1; /*If PIN_POWER_SELECTION is 1 then it indicates a programming error.*/ - uint32_t flash_type_err: 1; /*If FLASH_TYPE is 1 then it indicates a programming error.*/ - uint32_t flash_page_size: 2; /*If any bits in FLASH_PAGE_SIZE is 1 then it indicates a programming error.*/ - uint32_t flash_ecc_en: 1; /*If FLASH_ECC_EN_ERR is 1 then it indicates a programming error.*/ - uint32_t force_send_resume_err: 1; /*If FORCE_SEND_RESUME is 1 then it indicates a programming error.*/ - uint32_t secure_version_err: 16; /*If any bit in SECURE_VERSION is 1 then it indicates a programming error.*/ - uint32_t rpt4_reserved1_err: 2; /*Reserved.*/ + uint32_t dis_download_mode_err: 1; /*If the value is not zero then it indicates a programming error on DIS_DOWNLOAD_MODE.*/ + uint32_t dis_direct_boot_err: 1; /*If the value is not zero then it indicates a programming error on DIS_DIRECT_BOOT.*/ + uint32_t dis_usb_serial_jtag_rom_print_err:1; /*If the value is not zero then it indicates a programming error on DIS_USB_SERIAL_JTAG_ROM_PRINT.*/ + uint32_t rpt4_reserved8_err: 1; /*Reserved.*/ + uint32_t dis_usb_serial_jtag_download_mode_err: 1; /*If the value is not zero then it indicates a programming error on DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE.*/ + uint32_t enable_security_download_err: 1; /*If the value is not zero then it indicates a programming error on ENABLE_SECURITY_DOWNLOAD.*/ + uint32_t uart_print_control_err: 2; /*If the value is not zero then it indicates a programming error on UART_PRINT_CONTROL.*/ + uint32_t rpt4_reserved7_err: 5; /*Reserved*/ + uint32_t force_send_resume_err: 1; /*If the value is not zero then it indicates a programming error on FORCE_SEND_RESUME.*/ + uint32_t secure_version_err: 16; /*If the value is not zero then it indicates a programming error on SECURE_VERSION.*/ + uint32_t rpt4_reserved1_err: 1; /*Reserved.*/ + uint32_t err_rst_enable_err: 1; /*Use BLOCK0 to check error record registers, 0 - without check.*/ }; uint32_t val; } rd_repeat_err3; @@ -364,30 +358,30 @@ typedef volatile struct efuse_dev_s { union { struct { uint32_t mac_spi_8m_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t mac_spi_8m_fail: 1; /*0: Means no failure and that the data of MAC_SPI_8M is reliable 1: Means that programming user data failed and the number of error bytes is over 6.*/ + uint32_t reserved3: 1; /*Reserved.*/ uint32_t sys_part1_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t sys_part1_fail: 1; /*0: Means no failure and that the data of system part1 is reliable 1: Means that programming user data failed and the number of error bytes is over 6.*/ + uint32_t mac_spi_8m_fail: 1; /*0: Means no failure and that the data of MAC_SPI_8M is reliable 1: Means that programming MAC_SPI_8M failed and the number of error bytes is over 6.*/ uint32_t usr_data_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t usr_data_fail: 1; /*0: Means no failure and that the user data is reliable 1: Means that programming user data failed and the number of error bytes is over 6.*/ + uint32_t sys_part1_fail: 1; /*0: Means no failure and that the data of system part1 is reliable 1: Means that programming the data of system part1 failed and the number of error bytes is over 6.*/ uint32_t key0_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t key0_fail: 1; /*0: Means no failure and that the data of key$n is reliable 1: Means that programming key$n failed and the number of error bytes is over 6.*/ + uint32_t usr_data_fail: 1; /*0: Means no failure and that the data of user data is reliable 1: Means that programming user data failed and the number of error bytes is over 6.*/ uint32_t key1_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t key1_fail: 1; /*0: Means no failure and that the data of key$n is reliable 1: Means that programming key$n failed and the number of error bytes is over 6.*/ + uint32_t key0_fail: 1; /*0: Means no failure and that the data of key0 is reliable 1: Means that programming key0 failed and the number of error bytes is over 6.*/ uint32_t key2_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t key2_fail: 1; /*0: Means no failure and that the data of key$n is reliable 1: Means that programming key$n failed and the number of error bytes is over 6.*/ + uint32_t key1_fail: 1; /*0: Means no failure and that the data of key1 is reliable 1: Means that programming key1 failed and the number of error bytes is over 6.*/ uint32_t key3_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t key3_fail: 1; /*0: Means no failure and that the data of key$n is reliable 1: Means that programming key$n failed and the number of error bytes is over 6.*/ + uint32_t key2_fail: 1; /*0: Means no failure and that the data of key2 is reliable 1: Means that programming key2 failed and the number of error bytes is over 6.*/ uint32_t key4_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t key4_fail: 1; /*0: Means no failure and that the data of key$n is reliable 1: Means that programming key$n failed and the number of error bytes is over 6.*/ + uint32_t key3_fail: 1; /*0: Means no failure and that the data of key3 is reliable 1: Means that programming key3 failed and the number of error bytes is over 6.*/ }; uint32_t val; } rd_rs_err0; union { struct { uint32_t key5_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t key5_fail: 1; /*0: Means no failure and that the data of KEY5 is reliable 1: Means that programming user data failed and the number of error bytes is over 6.*/ + uint32_t key4_fail: 1; /*0: Means no failure and that the data of KEY4 is reliable 1: Means that programming KEY4 failed and the number of error bytes is over 6.*/ uint32_t sys_part2_err_num: 3; /*The value of this signal means the number of error bytes.*/ - uint32_t sys_part2_fail: 1; /*0: Means no failure and that the data of system part2 is reliable 1: Means that programming user data failed and the number of error bytes is over 6.*/ + uint32_t key5_fail: 1; /*0: Means no failure and that the data of KEY5 is reliable 1: Means that programming KEY5 failed and the number of error bytes is over 6.*/ uint32_t reserved8: 24; /*Reserved.*/ }; uint32_t val; diff --git a/components/soc/esp32c3/include/soc/io_mux_reg.h b/components/soc/esp32c3/include/soc/io_mux_reg.h index 3f338ea92d5c..11eac6b06dea 100644 --- a/components/soc/esp32c3/include/soc/io_mux_reg.h +++ b/components/soc/esp32c3/include/soc/io_mux_reg.h @@ -141,9 +141,9 @@ #define SD_DATA2_GPIO_NUM 9 #define SD_DATA3_GPIO_NUM 10 -#define MAX_RTC_GPIO_NUM 0 -#define MAX_PAD_GPIO_NUM 22 -#define MAX_GPIO_NUM 22 +#define MAX_RTC_GPIO_NUM 5 +#define MAX_PAD_GPIO_NUM 21 +#define MAX_GPIO_NUM 25 #define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE #define PIN_CTRL (REG_IO_MUX_BASE +0x00) diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index 8330251da2af..c6c87bbdad9f 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include @@ -66,9 +58,8 @@ extern "C" { /* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP, * RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values. - * Valid if RTC_CNTL_DBG_ATTEN is 0. */ -#define RTC_CNTL_DBIAS_SLP 0 //sleep dig_dbias & rtc_dbias +#define RTC_CNTL_DBIAS_SLP 5 //sleep dig_dbias & rtc_dbias #define RTC_CNTL_DBIAS_0V90 13 //digital voltage #define RTC_CNTL_DBIAS_0V95 16 #define RTC_CNTL_DBIAS_1V00 18 @@ -113,7 +104,7 @@ extern "C" { /* set sleep_init default param */ -#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 3 +#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5 #define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0 #define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15 #define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0 diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index e61cf8493dab..5dd771989667 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -18,7 +18,7 @@ /*-------------------------- COMMON CAPS ---------------------------------------*/ #define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 - +#define SOC_EFUSE_HAS_EFUSE_RST_BUG 1 /*-------------------------- AES CAPS -----------------------------------------*/ #define SOC_AES_SUPPORT_DMA (1) @@ -95,7 +95,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) #define SOC_I2C_SUPPORT_XTAL (1) @@ -143,7 +143,7 @@ /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ -#define SOC_RTCIO_PIN_COUNT 0 +#define SOC_RTCIO_PIN_COUNT (0U) /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (3072) diff --git a/components/soc/esp32c3/include/soc/uart_channel.h b/components/soc/esp32c3/include/soc/uart_channel.h index 855728262ef3..2711d7f9dffa 100644 --- a/components/soc/esp32c3/include/soc/uart_channel.h +++ b/components/soc/esp32c3/include/soc/uart_channel.h @@ -1,61 +1,21 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// This file defines GPIO lookup macros for available UART IO_MUX pins on ESP32C3. #ifndef _SOC_UART_CHANNEL_H #define _SOC_UART_CHANNEL_H //UART channels -#define UART_GPIO1_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 1 -#define UART_GPIO3_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 3 -#define UART_GPIO19_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_CTS_DIRECT_GPIO_NUM 19 -#define UART_GPIO22_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RTS_DIRECT_GPIO_NUM 22 +#define UART_GPIO21_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 21 +#define UART_GPIO20_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 20 -#define UART_TXD_GPIO1_DIRECT_CHANNEL UART_GPIO1_DIRECT_CHANNEL -#define UART_RXD_GPIO3_DIRECT_CHANNEL UART_GPIO3_DIRECT_CHANNEL -#define UART_CTS_GPIO19_DIRECT_CHANNEL UART_GPIO19_DIRECT_CHANNEL -#define UART_RTS_GPIO22_DIRECT_CHANNEL UART_GPIO22_DIRECT_CHANNEL - -#define UART_GPIO10_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_TXD_DIRECT_GPIO_NUM 10 -#define UART_GPIO9_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_RXD_DIRECT_GPIO_NUM 9 -#define UART_GPIO6_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_CTS_DIRECT_GPIO_NUM 6 -#define UART_GPIO11_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_RTS_DIRECT_GPIO_NUM 11 - -#define UART_TXD_GPIO10_DIRECT_CHANNEL UART_GPIO10_DIRECT_CHANNEL -#define UART_RXD_GPIO9_DIRECT_CHANNEL UART_GPIO9_DIRECT_CHANNEL -#define UART_CTS_GPIO6_DIRECT_CHANNEL UART_GPIO6_DIRECT_CHANNEL -#define UART_RTS_GPIO11_DIRECT_CHANNEL UART_GPIO11_DIRECT_CHANNEL - -#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_TXD_DIRECT_GPIO_NUM 17 -#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_RXD_DIRECT_GPIO_NUM 16 -#define UART_GPIO8_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_CTS_DIRECT_GPIO_NUM 8 -#define UART_GPIO7_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_RTS_DIRECT_GPIO_NUM 7 - -#define UART_TXD_GPIO17_DIRECT_CHANNEL UART_GPIO17_DIRECT_CHANNEL -#define UART_RXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL -#define UART_CTS_GPIO8_DIRECT_CHANNEL UART_GPIO8_DIRECT_CHANNEL -#define UART_RTS_GPIO7_DIRECT_CHANNEL UART_GPIO7_DIRECT_CHANNEL +#define UART_TXD_GPIO21_DIRECT_CHANNEL UART_GPIO21_DIRECT_CHANNEL +#define UART_RXD_GPIO20_DIRECT_CHANNEL UART_GPIO20_DIRECT_CHANNEL #endif diff --git a/components/soc/esp32c3/interrupts.c b/components/soc/esp32c3/interrupts.c index 93790cc60cde..27775f61881a 100644 --- a/components/soc/esp32c3/interrupts.c +++ b/components/soc/esp32c3/interrupts.c @@ -14,9 +14,9 @@ #include "soc/interrupts.h" -const char *const esp_isr_names[ETS_MAX_INTR_SOURCE] = { +const char *const esp_isr_names[] = { [0] = "WIFI_MAC", - [1] = "WIFI_NMI", + [1] = "WIFI_MAC_NMI", [2] = "WIFI_PWR", [3] = "WIFI_BB", [4] = "BT_MAC", @@ -26,7 +26,7 @@ const char *const esp_isr_names[ETS_MAX_INTR_SOURCE] = { [8] = "RWBLE", [9] = "RWBT_NMI", [10] = "RWBLE_NMI", - [11] = "I2C", + [11] = "I2C_MASTER", [12] = "SLC0", [13] = "SLC1", [14] = "APB_CTRL", @@ -40,7 +40,7 @@ const char *const esp_isr_names[ETS_MAX_INTR_SOURCE] = { [22] = "UART1", [23] = "LEDC", [24] = "EFUSE", - [25] = "CAN", + [25] = "TWAI", [26] = "USB", [27] = "RTC_CORE", [28] = "RMT", @@ -65,16 +65,16 @@ const char *const esp_isr_names[ETS_MAX_INTR_SOURCE] = { [47] = "RSA", [48] = "AES", [49] = "SHA", - [50] = "ETS_FROM_CPU_INTR0", - [51] = "ETS_FROM_CPU_INTR1", - [52] = "ETS_FROM_CPU_INTR2", - [53] = "ETS_FROM_CPU_INTR3", - [54] = "ETS_ASSIST_DEBUG", - [55] = "ETS_DMA_APBPERI_PMS", - [56] = "ETS_CORE0_IRAM0_PMS", - [57] = "ETS_CORE0_DRAM0_PMS", - [58] = "ETS_CORE0_PIF_PMS", - [59] = "ETS_CORE0_PIF_PMS_SIZE", - [60] = "ETS_BAK_PMS_VIOLATE", - [61] = "ETS_CACHE_CORE0_ACS", + [50] = "FROM_CPU_INTR0", + [51] = "FROM_CPU_INTR1", + [52] = "FROM_CPU_INTR2", + [53] = "FROM_CPU_INTR3", + [54] = "ASSIST_DEBUG", + [55] = "DMA_APBPERI_PMS", + [56] = "CORE0_IRAM0_PMS", + [57] = "CORE0_DRAM0_PMS", + [58] = "CORE0_PIF_PMS", + [59] = "CORE0_PIF_PMS_SIZE", + [60] = "BAK_PMS_VIOLATE", + [61] = "CACHE_CORE0_ACS", }; diff --git a/components/soc/esp32s2/gpio_periph.c b/components/soc/esp32s2/gpio_periph.c index 346984b57c2b..0e7fa4661b81 100644 --- a/components/soc/esp32s2/gpio_periph.c +++ b/components/soc/esp32s2/gpio_periph.c @@ -62,7 +62,6 @@ const uint32_t GPIO_PIN_MUX_REG[SOC_GPIO_PIN_COUNT] = { IO_MUX_GPIO44_REG, IO_MUX_GPIO45_REG, IO_MUX_GPIO46_REG, - 0, }; const uint32_t GPIO_HOLD_MASK[SOC_GPIO_PIN_COUNT] = { @@ -113,5 +112,4 @@ const uint32_t GPIO_HOLD_MASK[SOC_GPIO_PIN_COUNT] = { BIT(23), BIT(24), BIT(25), - BIT(26), }; diff --git a/components/soc/esp32s2/include/soc/periph_defs.h b/components/soc/esp32s2/include/soc/periph_defs.h index 5361489741d4..e64872e2a5aa 100644 --- a/components/soc/esp32s2/include/soc/periph_defs.h +++ b/components/soc/esp32s2/include/soc/periph_defs.h @@ -55,6 +55,7 @@ typedef enum { PERIPH_AES_DMA_MODULE, PERIPH_SHA_DMA_MODULE, PERIPH_DEDIC_GPIO_MODULE, + PERIPH_SARADC_MODULE, PERIPH_MODULE_MAX } periph_module_t; diff --git a/components/soc/esp32s2/include/soc/rmt_reg.h b/components/soc/esp32s2/include/soc/rmt_reg.h index 0cd0aed5c1bb..351eac3b5fbf 100644 --- a/components/soc/esp32s2/include/soc/rmt_reg.h +++ b/components/soc/esp32s2/include/soc/rmt_reg.h @@ -1,1716 +1,2132 @@ -// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef _SOC_RMT_REG_H_ -#define _SOC_RMT_REG_H_ +/** + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include +#include "soc/soc.h" #ifdef __cplusplus extern "C" { #endif -#include "soc.h" -#define RMT_CH0DATA_REG (DR_REG_RMT_BASE + 0x0000) -#define RMT_CH1DATA_REG (DR_REG_RMT_BASE + 0x0004) +/** RMT_CH0DATA_REG register + * Read and write data for channel 0 via APB FIFO + */ +#define RMT_CH0DATA_REG (DR_REG_RMT_BASE + 0x0) +/** RMT_CH0_DATA : RO; bitpos: [31:0]; default: 0; + * This register is used to read and write data for channel 0 via APB FIFO. + */ +#define RMT_CH0_DATA 0xFFFFFFFFU +#define RMT_CH0_DATA_M (RMT_CH0_DATA_V << RMT_CH0_DATA_S) +#define RMT_CH0_DATA_V 0xFFFFFFFFU +#define RMT_CH0_DATA_S 0 -#define RMT_CH2DATA_REG (DR_REG_RMT_BASE + 0x0008) +/** RMT_CH1DATA_REG register + * Read and write data for channel 1 via APB FIFO + */ +#define RMT_CH1DATA_REG (DR_REG_RMT_BASE + 0x4) +/** RMT_CH1_DATA : RO; bitpos: [31:0]; default: 0; + * This register is used to read and write data for channel 1 via APB FIFO. + */ +#define RMT_CH1_DATA 0xFFFFFFFFU +#define RMT_CH1_DATA_M (RMT_CH1_DATA_V << RMT_CH1_DATA_S) +#define RMT_CH1_DATA_V 0xFFFFFFFFU +#define RMT_CH1_DATA_S 0 -#define RMT_CH3DATA_REG (DR_REG_RMT_BASE + 0x000c) +/** RMT_CH2DATA_REG register + * Read and write data for channel 2 via APB FIFO + */ +#define RMT_CH2DATA_REG (DR_REG_RMT_BASE + 0x8) +/** RMT_CH2_DATA : RO; bitpos: [31:0]; default: 0; + * This register is used to read and write data for channel 2 via APB FIFO. + */ +#define RMT_CH2_DATA 0xFFFFFFFFU +#define RMT_CH2_DATA_M (RMT_CH2_DATA_V << RMT_CH2_DATA_S) +#define RMT_CH2_DATA_V 0xFFFFFFFFU +#define RMT_CH2_DATA_S 0 -#define RMT_CH0CONF0_REG (DR_REG_RMT_BASE + 0x0010) -/* RMT_CARRIER_OUT_LV_CH0 : R/W ;bitpos:[29] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_OUT_LV_CH0 (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH0_M (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH0_V 0x1 -#define RMT_CARRIER_OUT_LV_CH0_S 29 -/* RMT_CARRIER_EN_CH0 : R/W ;bitpos:[28] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EN_CH0 (BIT(28)) -#define RMT_CARRIER_EN_CH0_M (BIT(28)) -#define RMT_CARRIER_EN_CH0_V 0x1 -#define RMT_CARRIER_EN_CH0_S 28 -/* RMT_CARRIER_EFF_EN_CH0 : R/W ;bitpos:[27] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EFF_EN_CH0 (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH0_M (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH0_V 0x1 -#define RMT_CARRIER_EFF_EN_CH0_S 27 -/* RMT_MEM_SIZE_CH0 : R/W ;bitpos:[26:24] ;default: 3'h1 ; */ -/*description: */ -#define RMT_MEM_SIZE_CH0 0x00000007 -#define RMT_MEM_SIZE_CH0_M ((RMT_MEM_SIZE_CH0_V)<<(RMT_MEM_SIZE_CH0_S)) -#define RMT_MEM_SIZE_CH0_V 0x7 -#define RMT_MEM_SIZE_CH0_S 24 -/* RMT_IDLE_THRES_CH0 : R/W ;bitpos:[23:8] ;default: 16'h1000 ; */ -/*description: */ -#define RMT_IDLE_THRES_CH0 0x0000FFFF -#define RMT_IDLE_THRES_CH0_M ((RMT_IDLE_THRES_CH0_V)<<(RMT_IDLE_THRES_CH0_S)) -#define RMT_IDLE_THRES_CH0_V 0xFFFF -#define RMT_IDLE_THRES_CH0_S 8 -/* RMT_DIV_CNT_CH0 : R/W ;bitpos:[7:0] ;default: 8'h2 ; */ -/*description: */ -#define RMT_DIV_CNT_CH0 0x000000FF -#define RMT_DIV_CNT_CH0_M ((RMT_DIV_CNT_CH0_V)<<(RMT_DIV_CNT_CH0_S)) -#define RMT_DIV_CNT_CH0_V 0xFF +/** RMT_CH3DATA_REG register + * Read and write data for channel 3 via APB FIFO + */ +#define RMT_CH3DATA_REG (DR_REG_RMT_BASE + 0xc) +/** RMT_CH3_DATA : RO; bitpos: [31:0]; default: 0; + * This register is used to read and write data for channel 3 via APB FIFO. + */ +#define RMT_CH3_DATA 0xFFFFFFFFU +#define RMT_CH3_DATA_M (RMT_CH3_DATA_V << RMT_CH3_DATA_S) +#define RMT_CH3_DATA_V 0xFFFFFFFFU +#define RMT_CH3_DATA_S 0 + +/** RMT_CH0CONF0_REG register + * Channel 0 configuration register 0 + */ +#define RMT_CH0CONF0_REG (DR_REG_RMT_BASE + 0x10) +/** RMT_DIV_CNT_CH0 : R/W; bitpos: [7:0]; default: 2; + * This field is used to configure clock divider for channel 0. + */ +#define RMT_DIV_CNT_CH0 0x000000FFU +#define RMT_DIV_CNT_CH0_M (RMT_DIV_CNT_CH0_V << RMT_DIV_CNT_CH0_S) +#define RMT_DIV_CNT_CH0_V 0x000000FFU #define RMT_DIV_CNT_CH0_S 0 +/** RMT_IDLE_THRES_CH0 : R/W; bitpos: [23:8]; default: 4096; + * Receiving ends when no edge is detected on input signals for continuous clock + * cycles longer than this field value. + */ +#define RMT_IDLE_THRES_CH0 0x0000FFFFU +#define RMT_IDLE_THRES_CH0_M (RMT_IDLE_THRES_CH0_V << RMT_IDLE_THRES_CH0_S) +#define RMT_IDLE_THRES_CH0_V 0x0000FFFFU +#define RMT_IDLE_THRES_CH0_S 8 +/** RMT_MEM_SIZE_CH0 : R/W; bitpos: [26:24]; default: 1; + * This field is used to configure the maximum blocks allocated to channel 0. The + * valid range is from 1 ~ 4-0. + */ +#define RMT_MEM_SIZE_CH0 0x00000007U +#define RMT_MEM_SIZE_CH0_M (RMT_MEM_SIZE_CH0_V << RMT_MEM_SIZE_CH0_S) +#define RMT_MEM_SIZE_CH0_V 0x00000007U +#define RMT_MEM_SIZE_CH0_S 24 +/** RMT_CARRIER_EFF_EN_CH0 : R/W; bitpos: [27]; default: 1; + * 1: Add carrier modulation on output signals only at data sending state for channel + * 0. 0: Add carrier modulation on signals at all states for channel 0. States here + * include idle state (ST_IDLE), reading data from RAM (ST_RD_MEM), and sending data + * stored in RAM (ST_SEND). Only valid when RMT_CARRIER_EN_CH0 is set to 1. + */ +#define RMT_CARRIER_EFF_EN_CH0 (BIT(27)) +#define RMT_CARRIER_EFF_EN_CH0_M (RMT_CARRIER_EFF_EN_CH0_V << RMT_CARRIER_EFF_EN_CH0_S) +#define RMT_CARRIER_EFF_EN_CH0_V 0x00000001U +#define RMT_CARRIER_EFF_EN_CH0_S 27 +/** RMT_CARRIER_EN_CH0 : R/W; bitpos: [28]; default: 1; + * This bit is used to enable carrier modulation for channel 0. 1: Add carrier + * modulation on output signals. 0: No carrier modulation is added on output signals. + */ +#define RMT_CARRIER_EN_CH0 (BIT(28)) +#define RMT_CARRIER_EN_CH0_M (RMT_CARRIER_EN_CH0_V << RMT_CARRIER_EN_CH0_S) +#define RMT_CARRIER_EN_CH0_V 0x00000001U +#define RMT_CARRIER_EN_CH0_S 28 +/** RMT_CARRIER_OUT_LV_CH0 : R/W; bitpos: [29]; default: 1; + * This bit is used to configure the position of carrier wave for channel 0. + * + * 1'h0: Add carrier wave on low-level output signals. + * + * 1'h1: Add carrier wave on high-level output signals. + */ +#define RMT_CARRIER_OUT_LV_CH0 (BIT(29)) +#define RMT_CARRIER_OUT_LV_CH0_M (RMT_CARRIER_OUT_LV_CH0_V << RMT_CARRIER_OUT_LV_CH0_S) +#define RMT_CARRIER_OUT_LV_CH0_V 0x00000001U +#define RMT_CARRIER_OUT_LV_CH0_S 29 -#define RMT_CH0CONF1_REG (DR_REG_RMT_BASE + 0x0014) -/* RMT_TX_STOP_CH0 : R/W ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_STOP_CH0 (BIT(20)) -#define RMT_TX_STOP_CH0_M (BIT(20)) -#define RMT_TX_STOP_CH0_V 0x1 -#define RMT_TX_STOP_CH0_S 20 -/* RMT_IDLE_OUT_EN_CH0 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_EN_CH0 (BIT(19)) -#define RMT_IDLE_OUT_EN_CH0_M (BIT(19)) -#define RMT_IDLE_OUT_EN_CH0_V 0x1 -#define RMT_IDLE_OUT_EN_CH0_S 19 -/* RMT_IDLE_OUT_LV_CH0 : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_LV_CH0 (BIT(18)) -#define RMT_IDLE_OUT_LV_CH0_M (BIT(18)) -#define RMT_IDLE_OUT_LV_CH0_V 0x1 -#define RMT_IDLE_OUT_LV_CH0_S 18 -/* RMT_REF_ALWAYS_ON_CH0 : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_ALWAYS_ON_CH0 (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH0_M (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH0_V 0x1 -#define RMT_REF_ALWAYS_ON_CH0_S 17 -/* RMT_CHK_RX_CARRIER_EN_CH0 : R/W ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CHK_RX_CARRIER_EN_CH0 (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH0_M (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH0_V 0x1 -#define RMT_CHK_RX_CARRIER_EN_CH0_S 16 -/* RMT_RX_FILTER_THRES_CH0 : R/W ;bitpos:[15:8] ;default: 8'hf ; */ -/*description: */ -#define RMT_RX_FILTER_THRES_CH0 0x000000FF -#define RMT_RX_FILTER_THRES_CH0_M ((RMT_RX_FILTER_THRES_CH0_V)<<(RMT_RX_FILTER_THRES_CH0_S)) -#define RMT_RX_FILTER_THRES_CH0_V 0xFF -#define RMT_RX_FILTER_THRES_CH0_S 8 -/* RMT_RX_FILTER_EN_CH0 : R/W ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_RX_FILTER_EN_CH0 (BIT(7)) -#define RMT_RX_FILTER_EN_CH0_M (BIT(7)) -#define RMT_RX_FILTER_EN_CH0_V 0x1 -#define RMT_RX_FILTER_EN_CH0_S 7 -/* RMT_TX_CONTI_MODE_CH0 : R/W ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_CONTI_MODE_CH0 (BIT(6)) -#define RMT_TX_CONTI_MODE_CH0_M (BIT(6)) -#define RMT_TX_CONTI_MODE_CH0_V 0x1 -#define RMT_TX_CONTI_MODE_CH0_S 6 -/* RMT_MEM_OWNER_CH0 : R/W ;bitpos:[5] ;default: 1'b1 ; */ -/*description: */ -#define RMT_MEM_OWNER_CH0 (BIT(5)) -#define RMT_MEM_OWNER_CH0_M (BIT(5)) -#define RMT_MEM_OWNER_CH0_V 0x1 -#define RMT_MEM_OWNER_CH0_S 5 -/* RMT_APB_MEM_RST_CH0 : WO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RST_CH0 (BIT(4)) -#define RMT_APB_MEM_RST_CH0_M (BIT(4)) -#define RMT_APB_MEM_RST_CH0_V 0x1 -#define RMT_APB_MEM_RST_CH0_S 4 -/* RMT_MEM_RD_RST_CH0 : WO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_RD_RST_CH0 (BIT(3)) -#define RMT_MEM_RD_RST_CH0_M (BIT(3)) -#define RMT_MEM_RD_RST_CH0_V 0x1 -#define RMT_MEM_RD_RST_CH0_S 3 -/* RMT_MEM_WR_RST_CH0 : WO ;bitpos:[2] ;default: 1'h0 ; */ -/*description: */ -#define RMT_MEM_WR_RST_CH0 (BIT(2)) -#define RMT_MEM_WR_RST_CH0_M (BIT(2)) -#define RMT_MEM_WR_RST_CH0_V 0x1 -#define RMT_MEM_WR_RST_CH0_S 2 -/* RMT_RX_EN_CH0 : R/W ;bitpos:[1] ;default: 1'h0 ; */ -/*description: */ -#define RMT_RX_EN_CH0 (BIT(1)) -#define RMT_RX_EN_CH0_M (BIT(1)) -#define RMT_RX_EN_CH0_V 0x1 -#define RMT_RX_EN_CH0_S 1 -/* RMT_TX_START_CH0 : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: */ -#define RMT_TX_START_CH0 (BIT(0)) -#define RMT_TX_START_CH0_M (BIT(0)) -#define RMT_TX_START_CH0_V 0x1 +/** RMT_CH0CONF1_REG register + * Channel 0 configuration register 1 + */ +#define RMT_CH0CONF1_REG (DR_REG_RMT_BASE + 0x14) +/** RMT_TX_START_CH0 : R/W; bitpos: [0]; default: 0; + * Set this bit to start sending data on channel 0. + */ +#define RMT_TX_START_CH0 (BIT(0)) +#define RMT_TX_START_CH0_M (RMT_TX_START_CH0_V << RMT_TX_START_CH0_S) +#define RMT_TX_START_CH0_V 0x00000001U #define RMT_TX_START_CH0_S 0 +/** RMT_RX_EN_CH0 : R/W; bitpos: [1]; default: 0; + * Set this bit to enable receiver to receive data on channel 0. + */ +#define RMT_RX_EN_CH0 (BIT(1)) +#define RMT_RX_EN_CH0_M (RMT_RX_EN_CH0_V << RMT_RX_EN_CH0_S) +#define RMT_RX_EN_CH0_V 0x00000001U +#define RMT_RX_EN_CH0_S 1 +/** RMT_MEM_WR_RST_CH0 : WO; bitpos: [2]; default: 0; + * Set this bit to reset RAM write address accessed by the receiver for channel 0. + */ +#define RMT_MEM_WR_RST_CH0 (BIT(2)) +#define RMT_MEM_WR_RST_CH0_M (RMT_MEM_WR_RST_CH0_V << RMT_MEM_WR_RST_CH0_S) +#define RMT_MEM_WR_RST_CH0_V 0x00000001U +#define RMT_MEM_WR_RST_CH0_S 2 +/** RMT_MEM_RD_RST_CH0 : WO; bitpos: [3]; default: 0; + * Set this bit to reset RAM read address accessed by the transmitter for channel 0. + */ +#define RMT_MEM_RD_RST_CH0 (BIT(3)) +#define RMT_MEM_RD_RST_CH0_M (RMT_MEM_RD_RST_CH0_V << RMT_MEM_RD_RST_CH0_S) +#define RMT_MEM_RD_RST_CH0_V 0x00000001U +#define RMT_MEM_RD_RST_CH0_S 3 +/** RMT_APB_MEM_RST_CH0 : WO; bitpos: [4]; default: 0; + * Set this bit to reset W/R ram address for channel 0 by accessing apb fifo. + */ +#define RMT_APB_MEM_RST_CH0 (BIT(4)) +#define RMT_APB_MEM_RST_CH0_M (RMT_APB_MEM_RST_CH0_V << RMT_APB_MEM_RST_CH0_S) +#define RMT_APB_MEM_RST_CH0_V 0x00000001U +#define RMT_APB_MEM_RST_CH0_S 4 +/** RMT_MEM_OWNER_CH0 : R/W; bitpos: [5]; default: 1; + * This bit marks the ownership of channel 0's RAM block. + * + * 1'h1: Receiver is using the RAM. + * + * 1'h0: Transmitter is using the RAM. + */ +#define RMT_MEM_OWNER_CH0 (BIT(5)) +#define RMT_MEM_OWNER_CH0_M (RMT_MEM_OWNER_CH0_V << RMT_MEM_OWNER_CH0_S) +#define RMT_MEM_OWNER_CH0_V 0x00000001U +#define RMT_MEM_OWNER_CH0_S 5 +/** RMT_TX_CONTI_MODE_CH0 : R/W; bitpos: [6]; default: 0; + * Set this bit to restart transmission in continuous node from the first data in + * channel 0. + */ +#define RMT_TX_CONTI_MODE_CH0 (BIT(6)) +#define RMT_TX_CONTI_MODE_CH0_M (RMT_TX_CONTI_MODE_CH0_V << RMT_TX_CONTI_MODE_CH0_S) +#define RMT_TX_CONTI_MODE_CH0_V 0x00000001U +#define RMT_TX_CONTI_MODE_CH0_S 6 +/** RMT_RX_FILTER_EN_CH0 : R/W; bitpos: [7]; default: 0; + * Set this bit to enable the receiver's filter for channel 0. + */ +#define RMT_RX_FILTER_EN_CH0 (BIT(7)) +#define RMT_RX_FILTER_EN_CH0_M (RMT_RX_FILTER_EN_CH0_V << RMT_RX_FILTER_EN_CH0_S) +#define RMT_RX_FILTER_EN_CH0_V 0x00000001U +#define RMT_RX_FILTER_EN_CH0_S 7 +/** RMT_RX_FILTER_THRES_CH0 : R/W; bitpos: [15:8]; default: 15; + * Set this field to ignore the input pulse when its width is less than + * RMT_RX_FILTER_THRES_CH0 APB clock cycles in receive mode. + */ +#define RMT_RX_FILTER_THRES_CH0 0x000000FFU +#define RMT_RX_FILTER_THRES_CH0_M (RMT_RX_FILTER_THRES_CH0_V << RMT_RX_FILTER_THRES_CH0_S) +#define RMT_RX_FILTER_THRES_CH0_V 0x000000FFU +#define RMT_RX_FILTER_THRES_CH0_S 8 +/** RMT_CHK_RX_CARRIER_EN_CH0 : R/W; bitpos: [16]; default: 0; + * Set this bit to enable memory loop read mode when carrier modulation is enabled for + * channel 0. + */ +#define RMT_CHK_RX_CARRIER_EN_CH0 (BIT(16)) +#define RMT_CHK_RX_CARRIER_EN_CH0_M (RMT_CHK_RX_CARRIER_EN_CH0_V << RMT_CHK_RX_CARRIER_EN_CH0_S) +#define RMT_CHK_RX_CARRIER_EN_CH0_V 0x00000001U +#define RMT_CHK_RX_CARRIER_EN_CH0_S 16 +/** RMT_REF_ALWAYS_ON_CH0 : R/W; bitpos: [17]; default: 0; + * Set this bit to select a base clock for channel 0. + * + * 1'h1: APB_CLK 1'h0: REF_TICK + */ +#define RMT_REF_ALWAYS_ON_CH0 (BIT(17)) +#define RMT_REF_ALWAYS_ON_CH0_M (RMT_REF_ALWAYS_ON_CH0_V << RMT_REF_ALWAYS_ON_CH0_S) +#define RMT_REF_ALWAYS_ON_CH0_V 0x00000001U +#define RMT_REF_ALWAYS_ON_CH0_S 17 +/** RMT_IDLE_OUT_LV_CH0 : R/W; bitpos: [18]; default: 0; + * This bit configures the level of output signals in channel 0 when the transmitter + * is in idle state. + */ +#define RMT_IDLE_OUT_LV_CH0 (BIT(18)) +#define RMT_IDLE_OUT_LV_CH0_M (RMT_IDLE_OUT_LV_CH0_V << RMT_IDLE_OUT_LV_CH0_S) +#define RMT_IDLE_OUT_LV_CH0_V 0x00000001U +#define RMT_IDLE_OUT_LV_CH0_S 18 +/** RMT_IDLE_OUT_EN_CH0 : R/W; bitpos: [19]; default: 0; + * This is the output enable bit for channel 0 in idle state. + */ +#define RMT_IDLE_OUT_EN_CH0 (BIT(19)) +#define RMT_IDLE_OUT_EN_CH0_M (RMT_IDLE_OUT_EN_CH0_V << RMT_IDLE_OUT_EN_CH0_S) +#define RMT_IDLE_OUT_EN_CH0_V 0x00000001U +#define RMT_IDLE_OUT_EN_CH0_S 19 +/** RMT_TX_STOP_CH0 : R/W; bitpos: [20]; default: 0; + * Set this bit to stop the transmitter of channel 0 sending data out. + */ +#define RMT_TX_STOP_CH0 (BIT(20)) +#define RMT_TX_STOP_CH0_M (RMT_TX_STOP_CH0_V << RMT_TX_STOP_CH0_S) +#define RMT_TX_STOP_CH0_V 0x00000001U +#define RMT_TX_STOP_CH0_S 20 -#define RMT_CH1CONF0_REG (DR_REG_RMT_BASE + 0x0018) -/* RMT_CARRIER_OUT_LV_CH1 : R/W ;bitpos:[29] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_OUT_LV_CH1 (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH1_M (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH1_V 0x1 -#define RMT_CARRIER_OUT_LV_CH1_S 29 -/* RMT_CARRIER_EN_CH1 : R/W ;bitpos:[28] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EN_CH1 (BIT(28)) -#define RMT_CARRIER_EN_CH1_M (BIT(28)) -#define RMT_CARRIER_EN_CH1_V 0x1 -#define RMT_CARRIER_EN_CH1_S 28 -/* RMT_CARRIER_EFF_EN_CH1 : R/W ;bitpos:[27] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EFF_EN_CH1 (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH1_M (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH1_V 0x1 -#define RMT_CARRIER_EFF_EN_CH1_S 27 -/* RMT_MEM_SIZE_CH1 : R/W ;bitpos:[26:24] ;default: 3'h1 ; */ -/*description: */ -#define RMT_MEM_SIZE_CH1 0x00000007 -#define RMT_MEM_SIZE_CH1_M ((RMT_MEM_SIZE_CH1_V)<<(RMT_MEM_SIZE_CH1_S)) -#define RMT_MEM_SIZE_CH1_V 0x7 -#define RMT_MEM_SIZE_CH1_S 24 -/* RMT_IDLE_THRES_CH1 : R/W ;bitpos:[23:8] ;default: 16'h1000 ; */ -/*description: */ -#define RMT_IDLE_THRES_CH1 0x0000FFFF -#define RMT_IDLE_THRES_CH1_M ((RMT_IDLE_THRES_CH1_V)<<(RMT_IDLE_THRES_CH1_S)) -#define RMT_IDLE_THRES_CH1_V 0xFFFF -#define RMT_IDLE_THRES_CH1_S 8 -/* RMT_DIV_CNT_CH1 : R/W ;bitpos:[7:0] ;default: 8'h2 ; */ -/*description: */ -#define RMT_DIV_CNT_CH1 0x000000FF -#define RMT_DIV_CNT_CH1_M ((RMT_DIV_CNT_CH1_V)<<(RMT_DIV_CNT_CH1_S)) -#define RMT_DIV_CNT_CH1_V 0xFF +/** RMT_CH1CONF0_REG register + * Channel 1 configuration register 0 + */ +#define RMT_CH1CONF0_REG (DR_REG_RMT_BASE + 0x18) +/** RMT_DIV_CNT_CH1 : R/W; bitpos: [7:0]; default: 2; + * This field is used to configure clock divider for channel 1. + */ +#define RMT_DIV_CNT_CH1 0x000000FFU +#define RMT_DIV_CNT_CH1_M (RMT_DIV_CNT_CH1_V << RMT_DIV_CNT_CH1_S) +#define RMT_DIV_CNT_CH1_V 0x000000FFU #define RMT_DIV_CNT_CH1_S 0 +/** RMT_IDLE_THRES_CH1 : R/W; bitpos: [23:8]; default: 4096; + * Receiving ends when no edge is detected on input signals for continuous clock + * cycles longer than this field value. + */ +#define RMT_IDLE_THRES_CH1 0x0000FFFFU +#define RMT_IDLE_THRES_CH1_M (RMT_IDLE_THRES_CH1_V << RMT_IDLE_THRES_CH1_S) +#define RMT_IDLE_THRES_CH1_V 0x0000FFFFU +#define RMT_IDLE_THRES_CH1_S 8 +/** RMT_MEM_SIZE_CH1 : R/W; bitpos: [26:24]; default: 1; + * This field is used to configure the maximum blocks allocated to channel 1. The + * valid range is from 1 ~ 4-1. + */ +#define RMT_MEM_SIZE_CH1 0x00000007U +#define RMT_MEM_SIZE_CH1_M (RMT_MEM_SIZE_CH1_V << RMT_MEM_SIZE_CH1_S) +#define RMT_MEM_SIZE_CH1_V 0x00000007U +#define RMT_MEM_SIZE_CH1_S 24 +/** RMT_CARRIER_EFF_EN_CH1 : R/W; bitpos: [27]; default: 1; + * 1: Add carrier modulation on output signals only at data sending state for channel + * 1. 0: Add carrier modulation on signals at all states for channel 1. States here + * include idle state (ST_IDLE), reading data from RAM (ST_RD_MEM), and sending data + * stored in RAM (ST_SEND). Only valid when RMT_CARRIER_EN_CH1 is set to 1. + */ +#define RMT_CARRIER_EFF_EN_CH1 (BIT(27)) +#define RMT_CARRIER_EFF_EN_CH1_M (RMT_CARRIER_EFF_EN_CH1_V << RMT_CARRIER_EFF_EN_CH1_S) +#define RMT_CARRIER_EFF_EN_CH1_V 0x00000001U +#define RMT_CARRIER_EFF_EN_CH1_S 27 +/** RMT_CARRIER_EN_CH1 : R/W; bitpos: [28]; default: 1; + * This bit is used to enable carrier modulation for channel 1. 1: Add carrier + * modulation on output signals. 0: No carrier modulation is added on output signals. + */ +#define RMT_CARRIER_EN_CH1 (BIT(28)) +#define RMT_CARRIER_EN_CH1_M (RMT_CARRIER_EN_CH1_V << RMT_CARRIER_EN_CH1_S) +#define RMT_CARRIER_EN_CH1_V 0x00000001U +#define RMT_CARRIER_EN_CH1_S 28 +/** RMT_CARRIER_OUT_LV_CH1 : R/W; bitpos: [29]; default: 1; + * This bit is used to configure the position of carrier wave for channel 1. + * + * 1'h0: Add carrier wave on low-level output signals. + * + * 1'h1: Add carrier wave on high-level output signals. + */ +#define RMT_CARRIER_OUT_LV_CH1 (BIT(29)) +#define RMT_CARRIER_OUT_LV_CH1_M (RMT_CARRIER_OUT_LV_CH1_V << RMT_CARRIER_OUT_LV_CH1_S) +#define RMT_CARRIER_OUT_LV_CH1_V 0x00000001U +#define RMT_CARRIER_OUT_LV_CH1_S 29 -#define RMT_CH1CONF1_REG (DR_REG_RMT_BASE + 0x001c) -/* RMT_TX_STOP_CH1 : R/W ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_STOP_CH1 (BIT(20)) -#define RMT_TX_STOP_CH1_M (BIT(20)) -#define RMT_TX_STOP_CH1_V 0x1 -#define RMT_TX_STOP_CH1_S 20 -/* RMT_IDLE_OUT_EN_CH1 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_EN_CH1 (BIT(19)) -#define RMT_IDLE_OUT_EN_CH1_M (BIT(19)) -#define RMT_IDLE_OUT_EN_CH1_V 0x1 -#define RMT_IDLE_OUT_EN_CH1_S 19 -/* RMT_IDLE_OUT_LV_CH1 : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_LV_CH1 (BIT(18)) -#define RMT_IDLE_OUT_LV_CH1_M (BIT(18)) -#define RMT_IDLE_OUT_LV_CH1_V 0x1 -#define RMT_IDLE_OUT_LV_CH1_S 18 -/* RMT_REF_ALWAYS_ON_CH1 : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_ALWAYS_ON_CH1 (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH1_M (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH1_V 0x1 -#define RMT_REF_ALWAYS_ON_CH1_S 17 -/* RMT_CHK_RX_CARRIER_EN_CH1 : R/W ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CHK_RX_CARRIER_EN_CH1 (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH1_M (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH1_V 0x1 -#define RMT_CHK_RX_CARRIER_EN_CH1_S 16 -/* RMT_RX_FILTER_THRES_CH1 : R/W ;bitpos:[15:8] ;default: 8'hf ; */ -/*description: */ -#define RMT_RX_FILTER_THRES_CH1 0x000000FF -#define RMT_RX_FILTER_THRES_CH1_M ((RMT_RX_FILTER_THRES_CH1_V)<<(RMT_RX_FILTER_THRES_CH1_S)) -#define RMT_RX_FILTER_THRES_CH1_V 0xFF -#define RMT_RX_FILTER_THRES_CH1_S 8 -/* RMT_RX_FILTER_EN_CH1 : R/W ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_RX_FILTER_EN_CH1 (BIT(7)) -#define RMT_RX_FILTER_EN_CH1_M (BIT(7)) -#define RMT_RX_FILTER_EN_CH1_V 0x1 -#define RMT_RX_FILTER_EN_CH1_S 7 -/* RMT_TX_CONTI_MODE_CH1 : R/W ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_CONTI_MODE_CH1 (BIT(6)) -#define RMT_TX_CONTI_MODE_CH1_M (BIT(6)) -#define RMT_TX_CONTI_MODE_CH1_V 0x1 -#define RMT_TX_CONTI_MODE_CH1_S 6 -/* RMT_MEM_OWNER_CH1 : R/W ;bitpos:[5] ;default: 1'b1 ; */ -/*description: */ -#define RMT_MEM_OWNER_CH1 (BIT(5)) -#define RMT_MEM_OWNER_CH1_M (BIT(5)) -#define RMT_MEM_OWNER_CH1_V 0x1 -#define RMT_MEM_OWNER_CH1_S 5 -/* RMT_APB_MEM_RST_CH1 : WO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RST_CH1 (BIT(4)) -#define RMT_APB_MEM_RST_CH1_M (BIT(4)) -#define RMT_APB_MEM_RST_CH1_V 0x1 -#define RMT_APB_MEM_RST_CH1_S 4 -/* RMT_MEM_RD_RST_CH1 : WO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_RD_RST_CH1 (BIT(3)) -#define RMT_MEM_RD_RST_CH1_M (BIT(3)) -#define RMT_MEM_RD_RST_CH1_V 0x1 -#define RMT_MEM_RD_RST_CH1_S 3 -/* RMT_MEM_WR_RST_CH1 : WO ;bitpos:[2] ;default: 1'h0 ; */ -/*description: */ -#define RMT_MEM_WR_RST_CH1 (BIT(2)) -#define RMT_MEM_WR_RST_CH1_M (BIT(2)) -#define RMT_MEM_WR_RST_CH1_V 0x1 -#define RMT_MEM_WR_RST_CH1_S 2 -/* RMT_RX_EN_CH1 : R/W ;bitpos:[1] ;default: 1'h0 ; */ -/*description: */ -#define RMT_RX_EN_CH1 (BIT(1)) -#define RMT_RX_EN_CH1_M (BIT(1)) -#define RMT_RX_EN_CH1_V 0x1 -#define RMT_RX_EN_CH1_S 1 -/* RMT_TX_START_CH1 : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: */ -#define RMT_TX_START_CH1 (BIT(0)) -#define RMT_TX_START_CH1_M (BIT(0)) -#define RMT_TX_START_CH1_V 0x1 +/** RMT_CH1CONF1_REG register + * Channel 1 configuration register 1 + */ +#define RMT_CH1CONF1_REG (DR_REG_RMT_BASE + 0x1c) +/** RMT_TX_START_CH1 : R/W; bitpos: [0]; default: 0; + * Set this bit to start sending data on channel 1. + */ +#define RMT_TX_START_CH1 (BIT(0)) +#define RMT_TX_START_CH1_M (RMT_TX_START_CH1_V << RMT_TX_START_CH1_S) +#define RMT_TX_START_CH1_V 0x00000001U #define RMT_TX_START_CH1_S 0 +/** RMT_RX_EN_CH1 : R/W; bitpos: [1]; default: 0; + * Set this bit to enable receiver to receive data on channel 1. + */ +#define RMT_RX_EN_CH1 (BIT(1)) +#define RMT_RX_EN_CH1_M (RMT_RX_EN_CH1_V << RMT_RX_EN_CH1_S) +#define RMT_RX_EN_CH1_V 0x00000001U +#define RMT_RX_EN_CH1_S 1 +/** RMT_MEM_WR_RST_CH1 : WO; bitpos: [2]; default: 0; + * Set this bit to reset RAM write address accessed by the receiver for channel 1. + */ +#define RMT_MEM_WR_RST_CH1 (BIT(2)) +#define RMT_MEM_WR_RST_CH1_M (RMT_MEM_WR_RST_CH1_V << RMT_MEM_WR_RST_CH1_S) +#define RMT_MEM_WR_RST_CH1_V 0x00000001U +#define RMT_MEM_WR_RST_CH1_S 2 +/** RMT_MEM_RD_RST_CH1 : WO; bitpos: [3]; default: 0; + * Set this bit to reset RAM read address accessed by the transmitter for channel 1. + */ +#define RMT_MEM_RD_RST_CH1 (BIT(3)) +#define RMT_MEM_RD_RST_CH1_M (RMT_MEM_RD_RST_CH1_V << RMT_MEM_RD_RST_CH1_S) +#define RMT_MEM_RD_RST_CH1_V 0x00000001U +#define RMT_MEM_RD_RST_CH1_S 3 +/** RMT_APB_MEM_RST_CH1 : WO; bitpos: [4]; default: 0; + * Set this bit to reset W/R ram address for channel 1 by accessing apb fifo. + */ +#define RMT_APB_MEM_RST_CH1 (BIT(4)) +#define RMT_APB_MEM_RST_CH1_M (RMT_APB_MEM_RST_CH1_V << RMT_APB_MEM_RST_CH1_S) +#define RMT_APB_MEM_RST_CH1_V 0x00000001U +#define RMT_APB_MEM_RST_CH1_S 4 +/** RMT_MEM_OWNER_CH1 : R/W; bitpos: [5]; default: 1; + * This bit marks the ownership of channel 1's RAM block. + * + * 1'h1: Receiver is using the RAM. + * + * 1'h0: Transmitter is using the RAM. + */ +#define RMT_MEM_OWNER_CH1 (BIT(5)) +#define RMT_MEM_OWNER_CH1_M (RMT_MEM_OWNER_CH1_V << RMT_MEM_OWNER_CH1_S) +#define RMT_MEM_OWNER_CH1_V 0x00000001U +#define RMT_MEM_OWNER_CH1_S 5 +/** RMT_TX_CONTI_MODE_CH1 : R/W; bitpos: [6]; default: 0; + * Set this bit to restart transmission in continuous node from the first data in + * channel 1. + */ +#define RMT_TX_CONTI_MODE_CH1 (BIT(6)) +#define RMT_TX_CONTI_MODE_CH1_M (RMT_TX_CONTI_MODE_CH1_V << RMT_TX_CONTI_MODE_CH1_S) +#define RMT_TX_CONTI_MODE_CH1_V 0x00000001U +#define RMT_TX_CONTI_MODE_CH1_S 6 +/** RMT_RX_FILTER_EN_CH1 : R/W; bitpos: [7]; default: 0; + * Set this bit to enable the receiver's filter for channel 1. + */ +#define RMT_RX_FILTER_EN_CH1 (BIT(7)) +#define RMT_RX_FILTER_EN_CH1_M (RMT_RX_FILTER_EN_CH1_V << RMT_RX_FILTER_EN_CH1_S) +#define RMT_RX_FILTER_EN_CH1_V 0x00000001U +#define RMT_RX_FILTER_EN_CH1_S 7 +/** RMT_RX_FILTER_THRES_CH1 : R/W; bitpos: [15:8]; default: 15; + * Set this field to ignore the input pulse when its width is less than + * RMT_RX_FILTER_THRES_CH1 APB clock cycles in receive mode. + */ +#define RMT_RX_FILTER_THRES_CH1 0x000000FFU +#define RMT_RX_FILTER_THRES_CH1_M (RMT_RX_FILTER_THRES_CH1_V << RMT_RX_FILTER_THRES_CH1_S) +#define RMT_RX_FILTER_THRES_CH1_V 0x000000FFU +#define RMT_RX_FILTER_THRES_CH1_S 8 +/** RMT_CHK_RX_CARRIER_EN_CH1 : R/W; bitpos: [16]; default: 0; + * Set this bit to enable memory loop read mode when carrier modulation is enabled for + * channel 1. + */ +#define RMT_CHK_RX_CARRIER_EN_CH1 (BIT(16)) +#define RMT_CHK_RX_CARRIER_EN_CH1_M (RMT_CHK_RX_CARRIER_EN_CH1_V << RMT_CHK_RX_CARRIER_EN_CH1_S) +#define RMT_CHK_RX_CARRIER_EN_CH1_V 0x00000001U +#define RMT_CHK_RX_CARRIER_EN_CH1_S 16 +/** RMT_REF_ALWAYS_ON_CH1 : R/W; bitpos: [17]; default: 0; + * Set this bit to select a base clock for channel 1. + * + * 1'h1: APB_CLK 1'h0: REF_TICK + */ +#define RMT_REF_ALWAYS_ON_CH1 (BIT(17)) +#define RMT_REF_ALWAYS_ON_CH1_M (RMT_REF_ALWAYS_ON_CH1_V << RMT_REF_ALWAYS_ON_CH1_S) +#define RMT_REF_ALWAYS_ON_CH1_V 0x00000001U +#define RMT_REF_ALWAYS_ON_CH1_S 17 +/** RMT_IDLE_OUT_LV_CH1 : R/W; bitpos: [18]; default: 0; + * This bit configures the level of output signals in channel 1 when the transmitter + * is in idle state. + */ +#define RMT_IDLE_OUT_LV_CH1 (BIT(18)) +#define RMT_IDLE_OUT_LV_CH1_M (RMT_IDLE_OUT_LV_CH1_V << RMT_IDLE_OUT_LV_CH1_S) +#define RMT_IDLE_OUT_LV_CH1_V 0x00000001U +#define RMT_IDLE_OUT_LV_CH1_S 18 +/** RMT_IDLE_OUT_EN_CH1 : R/W; bitpos: [19]; default: 0; + * This is the output enable bit for channel 1 in idle state. + */ +#define RMT_IDLE_OUT_EN_CH1 (BIT(19)) +#define RMT_IDLE_OUT_EN_CH1_M (RMT_IDLE_OUT_EN_CH1_V << RMT_IDLE_OUT_EN_CH1_S) +#define RMT_IDLE_OUT_EN_CH1_V 0x00000001U +#define RMT_IDLE_OUT_EN_CH1_S 19 +/** RMT_TX_STOP_CH1 : R/W; bitpos: [20]; default: 0; + * Set this bit to stop the transmitter of channel 1 sending data out. + */ +#define RMT_TX_STOP_CH1 (BIT(20)) +#define RMT_TX_STOP_CH1_M (RMT_TX_STOP_CH1_V << RMT_TX_STOP_CH1_S) +#define RMT_TX_STOP_CH1_V 0x00000001U +#define RMT_TX_STOP_CH1_S 20 -#define RMT_CH2CONF0_REG (DR_REG_RMT_BASE + 0x0020) -/* RMT_CARRIER_OUT_LV_CH2 : R/W ;bitpos:[29] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_OUT_LV_CH2 (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH2_M (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH2_V 0x1 -#define RMT_CARRIER_OUT_LV_CH2_S 29 -/* RMT_CARRIER_EN_CH2 : R/W ;bitpos:[28] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EN_CH2 (BIT(28)) -#define RMT_CARRIER_EN_CH2_M (BIT(28)) -#define RMT_CARRIER_EN_CH2_V 0x1 -#define RMT_CARRIER_EN_CH2_S 28 -/* RMT_CARRIER_EFF_EN_CH2 : R/W ;bitpos:[27] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EFF_EN_CH2 (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH2_M (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH2_V 0x1 -#define RMT_CARRIER_EFF_EN_CH2_S 27 -/* RMT_MEM_SIZE_CH2 : R/W ;bitpos:[26:24] ;default: 3'h1 ; */ -/*description: */ -#define RMT_MEM_SIZE_CH2 0x00000007 -#define RMT_MEM_SIZE_CH2_M ((RMT_MEM_SIZE_CH2_V)<<(RMT_MEM_SIZE_CH2_S)) -#define RMT_MEM_SIZE_CH2_V 0x7 -#define RMT_MEM_SIZE_CH2_S 24 -/* RMT_IDLE_THRES_CH2 : R/W ;bitpos:[23:8] ;default: 16'h1000 ; */ -/*description: */ -#define RMT_IDLE_THRES_CH2 0x0000FFFF -#define RMT_IDLE_THRES_CH2_M ((RMT_IDLE_THRES_CH2_V)<<(RMT_IDLE_THRES_CH2_S)) -#define RMT_IDLE_THRES_CH2_V 0xFFFF -#define RMT_IDLE_THRES_CH2_S 8 -/* RMT_DIV_CNT_CH2 : R/W ;bitpos:[7:0] ;default: 8'h2 ; */ -/*description: */ -#define RMT_DIV_CNT_CH2 0x000000FF -#define RMT_DIV_CNT_CH2_M ((RMT_DIV_CNT_CH2_V)<<(RMT_DIV_CNT_CH2_S)) -#define RMT_DIV_CNT_CH2_V 0xFF +/** RMT_CH2CONF0_REG register + * Channel 2 configuration register 0 + */ +#define RMT_CH2CONF0_REG (DR_REG_RMT_BASE + 0x20) +/** RMT_DIV_CNT_CH2 : R/W; bitpos: [7:0]; default: 2; + * This field is used to configure clock divider for channel 2. + */ +#define RMT_DIV_CNT_CH2 0x000000FFU +#define RMT_DIV_CNT_CH2_M (RMT_DIV_CNT_CH2_V << RMT_DIV_CNT_CH2_S) +#define RMT_DIV_CNT_CH2_V 0x000000FFU #define RMT_DIV_CNT_CH2_S 0 +/** RMT_IDLE_THRES_CH2 : R/W; bitpos: [23:8]; default: 4096; + * Receiving ends when no edge is detected on input signals for continuous clock + * cycles longer than this field value. + */ +#define RMT_IDLE_THRES_CH2 0x0000FFFFU +#define RMT_IDLE_THRES_CH2_M (RMT_IDLE_THRES_CH2_V << RMT_IDLE_THRES_CH2_S) +#define RMT_IDLE_THRES_CH2_V 0x0000FFFFU +#define RMT_IDLE_THRES_CH2_S 8 +/** RMT_MEM_SIZE_CH2 : R/W; bitpos: [26:24]; default: 1; + * This field is used to configure the maximum blocks allocated to channel 2. The + * valid range is from 1 ~ 4-2. + */ +#define RMT_MEM_SIZE_CH2 0x00000007U +#define RMT_MEM_SIZE_CH2_M (RMT_MEM_SIZE_CH2_V << RMT_MEM_SIZE_CH2_S) +#define RMT_MEM_SIZE_CH2_V 0x00000007U +#define RMT_MEM_SIZE_CH2_S 24 +/** RMT_CARRIER_EFF_EN_CH2 : R/W; bitpos: [27]; default: 1; + * 1: Add carrier modulation on output signals only at data sending state for channel + * 2. 0: Add carrier modulation on signals at all states for channel 2. States here + * include idle state (ST_IDLE), reading data from RAM (ST_RD_MEM), and sending data + * stored in RAM (ST_SEND). Only valid when RMT_CARRIER_EN_CH2 is set to 1. + */ +#define RMT_CARRIER_EFF_EN_CH2 (BIT(27)) +#define RMT_CARRIER_EFF_EN_CH2_M (RMT_CARRIER_EFF_EN_CH2_V << RMT_CARRIER_EFF_EN_CH2_S) +#define RMT_CARRIER_EFF_EN_CH2_V 0x00000001U +#define RMT_CARRIER_EFF_EN_CH2_S 27 +/** RMT_CARRIER_EN_CH2 : R/W; bitpos: [28]; default: 1; + * This bit is used to enable carrier modulation for channel 2. 1: Add carrier + * modulation on output signals. 0: No carrier modulation is added on output signals. + */ +#define RMT_CARRIER_EN_CH2 (BIT(28)) +#define RMT_CARRIER_EN_CH2_M (RMT_CARRIER_EN_CH2_V << RMT_CARRIER_EN_CH2_S) +#define RMT_CARRIER_EN_CH2_V 0x00000001U +#define RMT_CARRIER_EN_CH2_S 28 +/** RMT_CARRIER_OUT_LV_CH2 : R/W; bitpos: [29]; default: 1; + * This bit is used to configure the position of carrier wave for channel 2. + * + * 1'h0: Add carrier wave on low-level output signals. + * + * 1'h1: Add carrier wave on high-level output signals. + */ +#define RMT_CARRIER_OUT_LV_CH2 (BIT(29)) +#define RMT_CARRIER_OUT_LV_CH2_M (RMT_CARRIER_OUT_LV_CH2_V << RMT_CARRIER_OUT_LV_CH2_S) +#define RMT_CARRIER_OUT_LV_CH2_V 0x00000001U +#define RMT_CARRIER_OUT_LV_CH2_S 29 -#define RMT_CH2CONF1_REG (DR_REG_RMT_BASE + 0x0024) -/* RMT_TX_STOP_CH2 : R/W ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_STOP_CH2 (BIT(20)) -#define RMT_TX_STOP_CH2_M (BIT(20)) -#define RMT_TX_STOP_CH2_V 0x1 -#define RMT_TX_STOP_CH2_S 20 -/* RMT_IDLE_OUT_EN_CH2 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_EN_CH2 (BIT(19)) -#define RMT_IDLE_OUT_EN_CH2_M (BIT(19)) -#define RMT_IDLE_OUT_EN_CH2_V 0x1 -#define RMT_IDLE_OUT_EN_CH2_S 19 -/* RMT_IDLE_OUT_LV_CH2 : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_LV_CH2 (BIT(18)) -#define RMT_IDLE_OUT_LV_CH2_M (BIT(18)) -#define RMT_IDLE_OUT_LV_CH2_V 0x1 -#define RMT_IDLE_OUT_LV_CH2_S 18 -/* RMT_REF_ALWAYS_ON_CH2 : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_ALWAYS_ON_CH2 (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH2_M (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH2_V 0x1 -#define RMT_REF_ALWAYS_ON_CH2_S 17 -/* RMT_CHK_RX_CARRIER_EN_CH2 : R/W ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CHK_RX_CARRIER_EN_CH2 (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH2_M (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH2_V 0x1 -#define RMT_CHK_RX_CARRIER_EN_CH2_S 16 -/* RMT_RX_FILTER_THRES_CH2 : R/W ;bitpos:[15:8] ;default: 8'hf ; */ -/*description: */ -#define RMT_RX_FILTER_THRES_CH2 0x000000FF -#define RMT_RX_FILTER_THRES_CH2_M ((RMT_RX_FILTER_THRES_CH2_V)<<(RMT_RX_FILTER_THRES_CH2_S)) -#define RMT_RX_FILTER_THRES_CH2_V 0xFF -#define RMT_RX_FILTER_THRES_CH2_S 8 -/* RMT_RX_FILTER_EN_CH2 : R/W ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_RX_FILTER_EN_CH2 (BIT(7)) -#define RMT_RX_FILTER_EN_CH2_M (BIT(7)) -#define RMT_RX_FILTER_EN_CH2_V 0x1 -#define RMT_RX_FILTER_EN_CH2_S 7 -/* RMT_TX_CONTI_MODE_CH2 : R/W ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_CONTI_MODE_CH2 (BIT(6)) -#define RMT_TX_CONTI_MODE_CH2_M (BIT(6)) -#define RMT_TX_CONTI_MODE_CH2_V 0x1 -#define RMT_TX_CONTI_MODE_CH2_S 6 -/* RMT_MEM_OWNER_CH2 : R/W ;bitpos:[5] ;default: 1'b1 ; */ -/*description: */ -#define RMT_MEM_OWNER_CH2 (BIT(5)) -#define RMT_MEM_OWNER_CH2_M (BIT(5)) -#define RMT_MEM_OWNER_CH2_V 0x1 -#define RMT_MEM_OWNER_CH2_S 5 -/* RMT_APB_MEM_RST_CH2 : WO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RST_CH2 (BIT(4)) -#define RMT_APB_MEM_RST_CH2_M (BIT(4)) -#define RMT_APB_MEM_RST_CH2_V 0x1 -#define RMT_APB_MEM_RST_CH2_S 4 -/* RMT_MEM_RD_RST_CH2 : WO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_RD_RST_CH2 (BIT(3)) -#define RMT_MEM_RD_RST_CH2_M (BIT(3)) -#define RMT_MEM_RD_RST_CH2_V 0x1 -#define RMT_MEM_RD_RST_CH2_S 3 -/* RMT_MEM_WR_RST_CH2 : WO ;bitpos:[2] ;default: 1'h0 ; */ -/*description: */ -#define RMT_MEM_WR_RST_CH2 (BIT(2)) -#define RMT_MEM_WR_RST_CH2_M (BIT(2)) -#define RMT_MEM_WR_RST_CH2_V 0x1 -#define RMT_MEM_WR_RST_CH2_S 2 -/* RMT_RX_EN_CH2 : R/W ;bitpos:[1] ;default: 1'h0 ; */ -/*description: */ -#define RMT_RX_EN_CH2 (BIT(1)) -#define RMT_RX_EN_CH2_M (BIT(1)) -#define RMT_RX_EN_CH2_V 0x1 -#define RMT_RX_EN_CH2_S 1 -/* RMT_TX_START_CH2 : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: */ -#define RMT_TX_START_CH2 (BIT(0)) -#define RMT_TX_START_CH2_M (BIT(0)) -#define RMT_TX_START_CH2_V 0x1 +/** RMT_CH2CONF1_REG register + * Channel 2 configuration register 1 + */ +#define RMT_CH2CONF1_REG (DR_REG_RMT_BASE + 0x24) +/** RMT_TX_START_CH2 : R/W; bitpos: [0]; default: 0; + * Set this bit to start sending data on channel 2. + */ +#define RMT_TX_START_CH2 (BIT(0)) +#define RMT_TX_START_CH2_M (RMT_TX_START_CH2_V << RMT_TX_START_CH2_S) +#define RMT_TX_START_CH2_V 0x00000001U #define RMT_TX_START_CH2_S 0 +/** RMT_RX_EN_CH2 : R/W; bitpos: [1]; default: 0; + * Set this bit to enable receiver to receive data on channel 2. + */ +#define RMT_RX_EN_CH2 (BIT(1)) +#define RMT_RX_EN_CH2_M (RMT_RX_EN_CH2_V << RMT_RX_EN_CH2_S) +#define RMT_RX_EN_CH2_V 0x00000001U +#define RMT_RX_EN_CH2_S 1 +/** RMT_MEM_WR_RST_CH2 : WO; bitpos: [2]; default: 0; + * Set this bit to reset RAM write address accessed by the receiver for channel 2. + */ +#define RMT_MEM_WR_RST_CH2 (BIT(2)) +#define RMT_MEM_WR_RST_CH2_M (RMT_MEM_WR_RST_CH2_V << RMT_MEM_WR_RST_CH2_S) +#define RMT_MEM_WR_RST_CH2_V 0x00000001U +#define RMT_MEM_WR_RST_CH2_S 2 +/** RMT_MEM_RD_RST_CH2 : WO; bitpos: [3]; default: 0; + * Set this bit to reset RAM read address accessed by the transmitter for channel 2. + */ +#define RMT_MEM_RD_RST_CH2 (BIT(3)) +#define RMT_MEM_RD_RST_CH2_M (RMT_MEM_RD_RST_CH2_V << RMT_MEM_RD_RST_CH2_S) +#define RMT_MEM_RD_RST_CH2_V 0x00000001U +#define RMT_MEM_RD_RST_CH2_S 3 +/** RMT_APB_MEM_RST_CH2 : WO; bitpos: [4]; default: 0; + * Set this bit to reset W/R ram address for channel 2 by accessing apb fifo. + */ +#define RMT_APB_MEM_RST_CH2 (BIT(4)) +#define RMT_APB_MEM_RST_CH2_M (RMT_APB_MEM_RST_CH2_V << RMT_APB_MEM_RST_CH2_S) +#define RMT_APB_MEM_RST_CH2_V 0x00000001U +#define RMT_APB_MEM_RST_CH2_S 4 +/** RMT_MEM_OWNER_CH2 : R/W; bitpos: [5]; default: 1; + * This bit marks the ownership of channel 2's RAM block. + * + * 1'h1: Receiver is using the RAM. + * + * 1'h0: Transmitter is using the RAM. + */ +#define RMT_MEM_OWNER_CH2 (BIT(5)) +#define RMT_MEM_OWNER_CH2_M (RMT_MEM_OWNER_CH2_V << RMT_MEM_OWNER_CH2_S) +#define RMT_MEM_OWNER_CH2_V 0x00000001U +#define RMT_MEM_OWNER_CH2_S 5 +/** RMT_TX_CONTI_MODE_CH2 : R/W; bitpos: [6]; default: 0; + * Set this bit to restart transmission in continuous node from the first data in + * channel 2. + */ +#define RMT_TX_CONTI_MODE_CH2 (BIT(6)) +#define RMT_TX_CONTI_MODE_CH2_M (RMT_TX_CONTI_MODE_CH2_V << RMT_TX_CONTI_MODE_CH2_S) +#define RMT_TX_CONTI_MODE_CH2_V 0x00000001U +#define RMT_TX_CONTI_MODE_CH2_S 6 +/** RMT_RX_FILTER_EN_CH2 : R/W; bitpos: [7]; default: 0; + * Set this bit to enable the receiver's filter for channel 2. + */ +#define RMT_RX_FILTER_EN_CH2 (BIT(7)) +#define RMT_RX_FILTER_EN_CH2_M (RMT_RX_FILTER_EN_CH2_V << RMT_RX_FILTER_EN_CH2_S) +#define RMT_RX_FILTER_EN_CH2_V 0x00000001U +#define RMT_RX_FILTER_EN_CH2_S 7 +/** RMT_RX_FILTER_THRES_CH2 : R/W; bitpos: [15:8]; default: 15; + * Set this field to ignore the input pulse when its width is less than + * RMT_RX_FILTER_THRES_CH2 APB clock cycles in receive mode. + */ +#define RMT_RX_FILTER_THRES_CH2 0x000000FFU +#define RMT_RX_FILTER_THRES_CH2_M (RMT_RX_FILTER_THRES_CH2_V << RMT_RX_FILTER_THRES_CH2_S) +#define RMT_RX_FILTER_THRES_CH2_V 0x000000FFU +#define RMT_RX_FILTER_THRES_CH2_S 8 +/** RMT_CHK_RX_CARRIER_EN_CH2 : R/W; bitpos: [16]; default: 0; + * Set this bit to enable memory loop read mode when carrier modulation is enabled for + * channel 2. + */ +#define RMT_CHK_RX_CARRIER_EN_CH2 (BIT(16)) +#define RMT_CHK_RX_CARRIER_EN_CH2_M (RMT_CHK_RX_CARRIER_EN_CH2_V << RMT_CHK_RX_CARRIER_EN_CH2_S) +#define RMT_CHK_RX_CARRIER_EN_CH2_V 0x00000001U +#define RMT_CHK_RX_CARRIER_EN_CH2_S 16 +/** RMT_REF_ALWAYS_ON_CH2 : R/W; bitpos: [17]; default: 0; + * Set this bit to select a base clock for channel 2. + * + * 1'h1: APB_CLK 1'h0: REF_TICK + */ +#define RMT_REF_ALWAYS_ON_CH2 (BIT(17)) +#define RMT_REF_ALWAYS_ON_CH2_M (RMT_REF_ALWAYS_ON_CH2_V << RMT_REF_ALWAYS_ON_CH2_S) +#define RMT_REF_ALWAYS_ON_CH2_V 0x00000001U +#define RMT_REF_ALWAYS_ON_CH2_S 17 +/** RMT_IDLE_OUT_LV_CH2 : R/W; bitpos: [18]; default: 0; + * This bit configures the level of output signals in channel 2 when the transmitter + * is in idle state. + */ +#define RMT_IDLE_OUT_LV_CH2 (BIT(18)) +#define RMT_IDLE_OUT_LV_CH2_M (RMT_IDLE_OUT_LV_CH2_V << RMT_IDLE_OUT_LV_CH2_S) +#define RMT_IDLE_OUT_LV_CH2_V 0x00000001U +#define RMT_IDLE_OUT_LV_CH2_S 18 +/** RMT_IDLE_OUT_EN_CH2 : R/W; bitpos: [19]; default: 0; + * This is the output enable bit for channel 2 in idle state. + */ +#define RMT_IDLE_OUT_EN_CH2 (BIT(19)) +#define RMT_IDLE_OUT_EN_CH2_M (RMT_IDLE_OUT_EN_CH2_V << RMT_IDLE_OUT_EN_CH2_S) +#define RMT_IDLE_OUT_EN_CH2_V 0x00000001U +#define RMT_IDLE_OUT_EN_CH2_S 19 +/** RMT_TX_STOP_CH2 : R/W; bitpos: [20]; default: 0; + * Set this bit to stop the transmitter of channel 2 sending data out. + */ +#define RMT_TX_STOP_CH2 (BIT(20)) +#define RMT_TX_STOP_CH2_M (RMT_TX_STOP_CH2_V << RMT_TX_STOP_CH2_S) +#define RMT_TX_STOP_CH2_V 0x00000001U +#define RMT_TX_STOP_CH2_S 20 -#define RMT_CH3CONF0_REG (DR_REG_RMT_BASE + 0x0028) -/* RMT_CARRIER_OUT_LV_CH3 : R/W ;bitpos:[29] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_OUT_LV_CH3 (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH3_M (BIT(29)) -#define RMT_CARRIER_OUT_LV_CH3_V 0x1 -#define RMT_CARRIER_OUT_LV_CH3_S 29 -/* RMT_CARRIER_EN_CH3 : R/W ;bitpos:[28] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EN_CH3 (BIT(28)) -#define RMT_CARRIER_EN_CH3_M (BIT(28)) -#define RMT_CARRIER_EN_CH3_V 0x1 -#define RMT_CARRIER_EN_CH3_S 28 -/* RMT_CARRIER_EFF_EN_CH3 : R/W ;bitpos:[27] ;default: 1'b1 ; */ -/*description: */ -#define RMT_CARRIER_EFF_EN_CH3 (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH3_M (BIT(27)) -#define RMT_CARRIER_EFF_EN_CH3_V 0x1 -#define RMT_CARRIER_EFF_EN_CH3_S 27 -/* RMT_MEM_SIZE_CH3 : R/W ;bitpos:[26:24] ;default: 3'h1 ; */ -/*description: */ -#define RMT_MEM_SIZE_CH3 0x00000007 -#define RMT_MEM_SIZE_CH3_M ((RMT_MEM_SIZE_CH3_V)<<(RMT_MEM_SIZE_CH3_S)) -#define RMT_MEM_SIZE_CH3_V 0x7 -#define RMT_MEM_SIZE_CH3_S 24 -/* RMT_IDLE_THRES_CH3 : R/W ;bitpos:[23:8] ;default: 16'h1000 ; */ -/*description: */ -#define RMT_IDLE_THRES_CH3 0x0000FFFF -#define RMT_IDLE_THRES_CH3_M ((RMT_IDLE_THRES_CH3_V)<<(RMT_IDLE_THRES_CH3_S)) -#define RMT_IDLE_THRES_CH3_V 0xFFFF -#define RMT_IDLE_THRES_CH3_S 8 -/* RMT_DIV_CNT_CH3 : R/W ;bitpos:[7:0] ;default: 8'h2 ; */ -/*description: */ -#define RMT_DIV_CNT_CH3 0x000000FF -#define RMT_DIV_CNT_CH3_M ((RMT_DIV_CNT_CH3_V)<<(RMT_DIV_CNT_CH3_S)) -#define RMT_DIV_CNT_CH3_V 0xFF +/** RMT_CH3CONF0_REG register + * Channel 3 configuration register 0 + */ +#define RMT_CH3CONF0_REG (DR_REG_RMT_BASE + 0x28) +/** RMT_DIV_CNT_CH3 : R/W; bitpos: [7:0]; default: 2; + * This field is used to configure clock divider for channel 3. + */ +#define RMT_DIV_CNT_CH3 0x000000FFU +#define RMT_DIV_CNT_CH3_M (RMT_DIV_CNT_CH3_V << RMT_DIV_CNT_CH3_S) +#define RMT_DIV_CNT_CH3_V 0x000000FFU #define RMT_DIV_CNT_CH3_S 0 +/** RMT_IDLE_THRES_CH3 : R/W; bitpos: [23:8]; default: 4096; + * Receiving ends when no edge is detected on input signals for continuous clock + * cycles longer than this field value. + */ +#define RMT_IDLE_THRES_CH3 0x0000FFFFU +#define RMT_IDLE_THRES_CH3_M (RMT_IDLE_THRES_CH3_V << RMT_IDLE_THRES_CH3_S) +#define RMT_IDLE_THRES_CH3_V 0x0000FFFFU +#define RMT_IDLE_THRES_CH3_S 8 +/** RMT_MEM_SIZE_CH3 : R/W; bitpos: [26:24]; default: 1; + * This field is used to configure the maximum blocks allocated to channel 3. The + * valid range is from 1 ~ 4-3. + */ +#define RMT_MEM_SIZE_CH3 0x00000007U +#define RMT_MEM_SIZE_CH3_M (RMT_MEM_SIZE_CH3_V << RMT_MEM_SIZE_CH3_S) +#define RMT_MEM_SIZE_CH3_V 0x00000007U +#define RMT_MEM_SIZE_CH3_S 24 +/** RMT_CARRIER_EFF_EN_CH3 : R/W; bitpos: [27]; default: 1; + * 1: Add carrier modulation on output signals only at data sending state for channel + * 3. 0: Add carrier modulation on signals at all states for channel 3. States here + * include idle state (ST_IDLE), reading data from RAM (ST_RD_MEM), and sending data + * stored in RAM (ST_SEND). Only valid when RMT_CARRIER_EN_CH3 is set to 1. + */ +#define RMT_CARRIER_EFF_EN_CH3 (BIT(27)) +#define RMT_CARRIER_EFF_EN_CH3_M (RMT_CARRIER_EFF_EN_CH3_V << RMT_CARRIER_EFF_EN_CH3_S) +#define RMT_CARRIER_EFF_EN_CH3_V 0x00000001U +#define RMT_CARRIER_EFF_EN_CH3_S 27 +/** RMT_CARRIER_EN_CH3 : R/W; bitpos: [28]; default: 1; + * This bit is used to enable carrier modulation for channel 3. 1: Add carrier + * modulation on output signals. 0: No carrier modulation is added on output signals. + */ +#define RMT_CARRIER_EN_CH3 (BIT(28)) +#define RMT_CARRIER_EN_CH3_M (RMT_CARRIER_EN_CH3_V << RMT_CARRIER_EN_CH3_S) +#define RMT_CARRIER_EN_CH3_V 0x00000001U +#define RMT_CARRIER_EN_CH3_S 28 +/** RMT_CARRIER_OUT_LV_CH3 : R/W; bitpos: [29]; default: 1; + * This bit is used to configure the position of carrier wave for channel 3. + * + * 1'h0: Add carrier wave on low-level output signals. + * + * 1'h1: Add carrier wave on high-level output signals. + */ +#define RMT_CARRIER_OUT_LV_CH3 (BIT(29)) +#define RMT_CARRIER_OUT_LV_CH3_M (RMT_CARRIER_OUT_LV_CH3_V << RMT_CARRIER_OUT_LV_CH3_S) +#define RMT_CARRIER_OUT_LV_CH3_V 0x00000001U +#define RMT_CARRIER_OUT_LV_CH3_S 29 -#define RMT_CH3CONF1_REG (DR_REG_RMT_BASE + 0x002c) -/* RMT_TX_STOP_CH3 : R/W ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_STOP_CH3 (BIT(20)) -#define RMT_TX_STOP_CH3_M (BIT(20)) -#define RMT_TX_STOP_CH3_V 0x1 -#define RMT_TX_STOP_CH3_S 20 -/* RMT_IDLE_OUT_EN_CH3 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_EN_CH3 (BIT(19)) -#define RMT_IDLE_OUT_EN_CH3_M (BIT(19)) -#define RMT_IDLE_OUT_EN_CH3_V 0x1 -#define RMT_IDLE_OUT_EN_CH3_S 19 -/* RMT_IDLE_OUT_LV_CH3 : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_IDLE_OUT_LV_CH3 (BIT(18)) -#define RMT_IDLE_OUT_LV_CH3_M (BIT(18)) -#define RMT_IDLE_OUT_LV_CH3_V 0x1 -#define RMT_IDLE_OUT_LV_CH3_S 18 -/* RMT_REF_ALWAYS_ON_CH3 : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_ALWAYS_ON_CH3 (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH3_M (BIT(17)) -#define RMT_REF_ALWAYS_ON_CH3_V 0x1 -#define RMT_REF_ALWAYS_ON_CH3_S 17 -/* RMT_CHK_RX_CARRIER_EN_CH3 : R/W ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CHK_RX_CARRIER_EN_CH3 (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH3_M (BIT(16)) -#define RMT_CHK_RX_CARRIER_EN_CH3_V 0x1 -#define RMT_CHK_RX_CARRIER_EN_CH3_S 16 -/* RMT_RX_FILTER_THRES_CH3 : R/W ;bitpos:[15:8] ;default: 8'hf ; */ -/*description: */ -#define RMT_RX_FILTER_THRES_CH3 0x000000FF -#define RMT_RX_FILTER_THRES_CH3_M ((RMT_RX_FILTER_THRES_CH3_V)<<(RMT_RX_FILTER_THRES_CH3_S)) -#define RMT_RX_FILTER_THRES_CH3_V 0xFF -#define RMT_RX_FILTER_THRES_CH3_S 8 -/* RMT_RX_FILTER_EN_CH3 : R/W ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_RX_FILTER_EN_CH3 (BIT(7)) -#define RMT_RX_FILTER_EN_CH3_M (BIT(7)) -#define RMT_RX_FILTER_EN_CH3_V 0x1 -#define RMT_RX_FILTER_EN_CH3_S 7 -/* RMT_TX_CONTI_MODE_CH3 : R/W ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_CONTI_MODE_CH3 (BIT(6)) -#define RMT_TX_CONTI_MODE_CH3_M (BIT(6)) -#define RMT_TX_CONTI_MODE_CH3_V 0x1 -#define RMT_TX_CONTI_MODE_CH3_S 6 -/* RMT_MEM_OWNER_CH3 : R/W ;bitpos:[5] ;default: 1'b1 ; */ -/*description: */ -#define RMT_MEM_OWNER_CH3 (BIT(5)) -#define RMT_MEM_OWNER_CH3_M (BIT(5)) -#define RMT_MEM_OWNER_CH3_V 0x1 -#define RMT_MEM_OWNER_CH3_S 5 -/* RMT_APB_MEM_RST_CH3 : WO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RST_CH3 (BIT(4)) -#define RMT_APB_MEM_RST_CH3_M (BIT(4)) -#define RMT_APB_MEM_RST_CH3_V 0x1 -#define RMT_APB_MEM_RST_CH3_S 4 -/* RMT_MEM_RD_RST_CH3 : WO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_RD_RST_CH3 (BIT(3)) -#define RMT_MEM_RD_RST_CH3_M (BIT(3)) -#define RMT_MEM_RD_RST_CH3_V 0x1 -#define RMT_MEM_RD_RST_CH3_S 3 -/* RMT_MEM_WR_RST_CH3 : WO ;bitpos:[2] ;default: 1'h0 ; */ -/*description: */ -#define RMT_MEM_WR_RST_CH3 (BIT(2)) -#define RMT_MEM_WR_RST_CH3_M (BIT(2)) -#define RMT_MEM_WR_RST_CH3_V 0x1 -#define RMT_MEM_WR_RST_CH3_S 2 -/* RMT_RX_EN_CH3 : R/W ;bitpos:[1] ;default: 1'h0 ; */ -/*description: */ -#define RMT_RX_EN_CH3 (BIT(1)) -#define RMT_RX_EN_CH3_M (BIT(1)) -#define RMT_RX_EN_CH3_V 0x1 -#define RMT_RX_EN_CH3_S 1 -/* RMT_TX_START_CH3 : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: */ -#define RMT_TX_START_CH3 (BIT(0)) -#define RMT_TX_START_CH3_M (BIT(0)) -#define RMT_TX_START_CH3_V 0x1 +/** RMT_CH3CONF1_REG register + * Channel 3 configuration register 1 + */ +#define RMT_CH3CONF1_REG (DR_REG_RMT_BASE + 0x2c) +/** RMT_TX_START_CH3 : R/W; bitpos: [0]; default: 0; + * Set this bit to start sending data on channel 3. + */ +#define RMT_TX_START_CH3 (BIT(0)) +#define RMT_TX_START_CH3_M (RMT_TX_START_CH3_V << RMT_TX_START_CH3_S) +#define RMT_TX_START_CH3_V 0x00000001U #define RMT_TX_START_CH3_S 0 +/** RMT_RX_EN_CH3 : R/W; bitpos: [1]; default: 0; + * Set this bit to enable receiver to receive data on channel 3. + */ +#define RMT_RX_EN_CH3 (BIT(1)) +#define RMT_RX_EN_CH3_M (RMT_RX_EN_CH3_V << RMT_RX_EN_CH3_S) +#define RMT_RX_EN_CH3_V 0x00000001U +#define RMT_RX_EN_CH3_S 1 +/** RMT_MEM_WR_RST_CH3 : WO; bitpos: [2]; default: 0; + * Set this bit to reset RAM write address accessed by the receiver for channel 3. + */ +#define RMT_MEM_WR_RST_CH3 (BIT(2)) +#define RMT_MEM_WR_RST_CH3_M (RMT_MEM_WR_RST_CH3_V << RMT_MEM_WR_RST_CH3_S) +#define RMT_MEM_WR_RST_CH3_V 0x00000001U +#define RMT_MEM_WR_RST_CH3_S 2 +/** RMT_MEM_RD_RST_CH3 : WO; bitpos: [3]; default: 0; + * Set this bit to reset RAM read address accessed by the transmitter for channel 3. + */ +#define RMT_MEM_RD_RST_CH3 (BIT(3)) +#define RMT_MEM_RD_RST_CH3_M (RMT_MEM_RD_RST_CH3_V << RMT_MEM_RD_RST_CH3_S) +#define RMT_MEM_RD_RST_CH3_V 0x00000001U +#define RMT_MEM_RD_RST_CH3_S 3 +/** RMT_APB_MEM_RST_CH3 : WO; bitpos: [4]; default: 0; + * Set this bit to reset W/R ram address for channel 3 by accessing apb fifo. + */ +#define RMT_APB_MEM_RST_CH3 (BIT(4)) +#define RMT_APB_MEM_RST_CH3_M (RMT_APB_MEM_RST_CH3_V << RMT_APB_MEM_RST_CH3_S) +#define RMT_APB_MEM_RST_CH3_V 0x00000001U +#define RMT_APB_MEM_RST_CH3_S 4 +/** RMT_MEM_OWNER_CH3 : R/W; bitpos: [5]; default: 1; + * This bit marks the ownership of channel 3's RAM block. + * + * 1'h1: Receiver is using the RAM. + * + * 1'h0: Transmitter is using the RAM. + */ +#define RMT_MEM_OWNER_CH3 (BIT(5)) +#define RMT_MEM_OWNER_CH3_M (RMT_MEM_OWNER_CH3_V << RMT_MEM_OWNER_CH3_S) +#define RMT_MEM_OWNER_CH3_V 0x00000001U +#define RMT_MEM_OWNER_CH3_S 5 +/** RMT_TX_CONTI_MODE_CH3 : R/W; bitpos: [6]; default: 0; + * Set this bit to restart transmission in continuous node from the first data in + * channel 3. + */ +#define RMT_TX_CONTI_MODE_CH3 (BIT(6)) +#define RMT_TX_CONTI_MODE_CH3_M (RMT_TX_CONTI_MODE_CH3_V << RMT_TX_CONTI_MODE_CH3_S) +#define RMT_TX_CONTI_MODE_CH3_V 0x00000001U +#define RMT_TX_CONTI_MODE_CH3_S 6 +/** RMT_RX_FILTER_EN_CH3 : R/W; bitpos: [7]; default: 0; + * Set this bit to enable the receiver's filter for channel 3. + */ +#define RMT_RX_FILTER_EN_CH3 (BIT(7)) +#define RMT_RX_FILTER_EN_CH3_M (RMT_RX_FILTER_EN_CH3_V << RMT_RX_FILTER_EN_CH3_S) +#define RMT_RX_FILTER_EN_CH3_V 0x00000001U +#define RMT_RX_FILTER_EN_CH3_S 7 +/** RMT_RX_FILTER_THRES_CH3 : R/W; bitpos: [15:8]; default: 15; + * Set this field to ignore the input pulse when its width is less than + * RMT_RX_FILTER_THRES_CH3 APB clock cycles in receive mode. + */ +#define RMT_RX_FILTER_THRES_CH3 0x000000FFU +#define RMT_RX_FILTER_THRES_CH3_M (RMT_RX_FILTER_THRES_CH3_V << RMT_RX_FILTER_THRES_CH3_S) +#define RMT_RX_FILTER_THRES_CH3_V 0x000000FFU +#define RMT_RX_FILTER_THRES_CH3_S 8 +/** RMT_CHK_RX_CARRIER_EN_CH3 : R/W; bitpos: [16]; default: 0; + * Set this bit to enable memory loop read mode when carrier modulation is enabled for + * channel 3. + */ +#define RMT_CHK_RX_CARRIER_EN_CH3 (BIT(16)) +#define RMT_CHK_RX_CARRIER_EN_CH3_M (RMT_CHK_RX_CARRIER_EN_CH3_V << RMT_CHK_RX_CARRIER_EN_CH3_S) +#define RMT_CHK_RX_CARRIER_EN_CH3_V 0x00000001U +#define RMT_CHK_RX_CARRIER_EN_CH3_S 16 +/** RMT_REF_ALWAYS_ON_CH3 : R/W; bitpos: [17]; default: 0; + * Set this bit to select a base clock for channel 3. + * + * 1'h1: APB_CLK 1'h0: REF_TICK + */ +#define RMT_REF_ALWAYS_ON_CH3 (BIT(17)) +#define RMT_REF_ALWAYS_ON_CH3_M (RMT_REF_ALWAYS_ON_CH3_V << RMT_REF_ALWAYS_ON_CH3_S) +#define RMT_REF_ALWAYS_ON_CH3_V 0x00000001U +#define RMT_REF_ALWAYS_ON_CH3_S 17 +/** RMT_IDLE_OUT_LV_CH3 : R/W; bitpos: [18]; default: 0; + * This bit configures the level of output signals in channel 3 when the transmitter + * is in idle state. + */ +#define RMT_IDLE_OUT_LV_CH3 (BIT(18)) +#define RMT_IDLE_OUT_LV_CH3_M (RMT_IDLE_OUT_LV_CH3_V << RMT_IDLE_OUT_LV_CH3_S) +#define RMT_IDLE_OUT_LV_CH3_V 0x00000001U +#define RMT_IDLE_OUT_LV_CH3_S 18 +/** RMT_IDLE_OUT_EN_CH3 : R/W; bitpos: [19]; default: 0; + * This is the output enable bit for channel 3 in idle state. + */ +#define RMT_IDLE_OUT_EN_CH3 (BIT(19)) +#define RMT_IDLE_OUT_EN_CH3_M (RMT_IDLE_OUT_EN_CH3_V << RMT_IDLE_OUT_EN_CH3_S) +#define RMT_IDLE_OUT_EN_CH3_V 0x00000001U +#define RMT_IDLE_OUT_EN_CH3_S 19 +/** RMT_TX_STOP_CH3 : R/W; bitpos: [20]; default: 0; + * Set this bit to stop the transmitter of channel 3 sending data out. + */ +#define RMT_TX_STOP_CH3 (BIT(20)) +#define RMT_TX_STOP_CH3_M (RMT_TX_STOP_CH3_V << RMT_TX_STOP_CH3_S) +#define RMT_TX_STOP_CH3_V 0x00000001U +#define RMT_TX_STOP_CH3_S 20 -#define RMT_CH0STATUS_REG (DR_REG_RMT_BASE + 0x0030) -/* RMT_APB_MEM_RD_ERR_CH0 : RO ;bitpos:[27] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RD_ERR_CH0 (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH0_M (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH0_V 0x1 -#define RMT_APB_MEM_RD_ERR_CH0_S 27 -/* RMT_APB_MEM_WR_ERR_CH0 : RO ;bitpos:[26] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WR_ERR_CH0 (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH0_M (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH0_V 0x1 -#define RMT_APB_MEM_WR_ERR_CH0_S 26 -/* RMT_MEM_EMPTY_CH0 : RO ;bitpos:[25] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_EMPTY_CH0 (BIT(25)) -#define RMT_MEM_EMPTY_CH0_M (BIT(25)) -#define RMT_MEM_EMPTY_CH0_V 0x1 -#define RMT_MEM_EMPTY_CH0_S 25 -/* RMT_MEM_FULL_CH0 : RO ;bitpos:[24] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_FULL_CH0 (BIT(24)) -#define RMT_MEM_FULL_CH0_M (BIT(24)) -#define RMT_MEM_FULL_CH0_V 0x1 -#define RMT_MEM_FULL_CH0_S 24 -/* RMT_MEM_OWNER_ERR_CH0 : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_OWNER_ERR_CH0 (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH0_M (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH0_V 0x1 -#define RMT_MEM_OWNER_ERR_CH0_S 23 -/* RMT_STATE_CH0 : RO ;bitpos:[22:20] ;default: 3'b0 ; */ -/*description: */ -#define RMT_STATE_CH0 0x00000007 -#define RMT_STATE_CH0_M ((RMT_STATE_CH0_V)<<(RMT_STATE_CH0_S)) -#define RMT_STATE_CH0_V 0x7 -#define RMT_STATE_CH0_S 20 -/* RMT_MEM_RADDR_EX_CH0 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_RADDR_EX_CH0 0x000001FF -#define RMT_MEM_RADDR_EX_CH0_M ((RMT_MEM_RADDR_EX_CH0_V)<<(RMT_MEM_RADDR_EX_CH0_S)) -#define RMT_MEM_RADDR_EX_CH0_V 0x1FF -#define RMT_MEM_RADDR_EX_CH0_S 10 -/* RMT_MEM_WADDR_EX_CH0 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_WADDR_EX_CH0 0x000001FF -#define RMT_MEM_WADDR_EX_CH0_M ((RMT_MEM_WADDR_EX_CH0_V)<<(RMT_MEM_WADDR_EX_CH0_S)) -#define RMT_MEM_WADDR_EX_CH0_V 0x1FF +/** RMT_CH0STATUS_REG register + * Channel 0 status register + */ +#define RMT_CH0STATUS_REG (DR_REG_RMT_BASE + 0x30) +/** RMT_MEM_WADDR_EX_CH0 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when receiver of channel 0 is using + * the RAM. + */ +#define RMT_MEM_WADDR_EX_CH0 0x000001FFU +#define RMT_MEM_WADDR_EX_CH0_M (RMT_MEM_WADDR_EX_CH0_V << RMT_MEM_WADDR_EX_CH0_S) +#define RMT_MEM_WADDR_EX_CH0_V 0x000001FFU #define RMT_MEM_WADDR_EX_CH0_S 0 +/** RMT_MEM_RADDR_EX_CH0 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when transmitter of channel 0 is using + * the RAM. + */ +#define RMT_MEM_RADDR_EX_CH0 0x000001FFU +#define RMT_MEM_RADDR_EX_CH0_M (RMT_MEM_RADDR_EX_CH0_V << RMT_MEM_RADDR_EX_CH0_S) +#define RMT_MEM_RADDR_EX_CH0_V 0x000001FFU +#define RMT_MEM_RADDR_EX_CH0_S 10 +/** RMT_STATE_CH0 : RO; bitpos: [22:20]; default: 0; + * This field records the FSM status of channel 0. + */ +#define RMT_STATE_CH0 0x00000007U +#define RMT_STATE_CH0_M (RMT_STATE_CH0_V << RMT_STATE_CH0_S) +#define RMT_STATE_CH0_V 0x00000007U +#define RMT_STATE_CH0_S 20 +/** RMT_MEM_OWNER_ERR_CH0 : RO; bitpos: [23]; default: 0; + * This status bit will be set when the ownership of memory block is violated. + */ +#define RMT_MEM_OWNER_ERR_CH0 (BIT(23)) +#define RMT_MEM_OWNER_ERR_CH0_M (RMT_MEM_OWNER_ERR_CH0_V << RMT_MEM_OWNER_ERR_CH0_S) +#define RMT_MEM_OWNER_ERR_CH0_V 0x00000001U +#define RMT_MEM_OWNER_ERR_CH0_S 23 +/** RMT_MEM_FULL_CH0 : RO; bitpos: [24]; default: 0; + * This status bit will be set if the receiver receives more data than the memory + * allows. + */ +#define RMT_MEM_FULL_CH0 (BIT(24)) +#define RMT_MEM_FULL_CH0_M (RMT_MEM_FULL_CH0_V << RMT_MEM_FULL_CH0_S) +#define RMT_MEM_FULL_CH0_V 0x00000001U +#define RMT_MEM_FULL_CH0_S 24 +/** RMT_MEM_EMPTY_CH0 : RO; bitpos: [25]; default: 0; + * This status bit will be set when the data to be sent is more than memory allows and + * the wrap mode is disabled. + */ +#define RMT_MEM_EMPTY_CH0 (BIT(25)) +#define RMT_MEM_EMPTY_CH0_M (RMT_MEM_EMPTY_CH0_V << RMT_MEM_EMPTY_CH0_S) +#define RMT_MEM_EMPTY_CH0_V 0x00000001U +#define RMT_MEM_EMPTY_CH0_S 25 +/** RMT_APB_MEM_WR_ERR_CH0 : RO; bitpos: [26]; default: 0; + * This status bit will be set if the offset address out of memory size when writes + * RAM via APB bus. + */ +#define RMT_APB_MEM_WR_ERR_CH0 (BIT(26)) +#define RMT_APB_MEM_WR_ERR_CH0_M (RMT_APB_MEM_WR_ERR_CH0_V << RMT_APB_MEM_WR_ERR_CH0_S) +#define RMT_APB_MEM_WR_ERR_CH0_V 0x00000001U +#define RMT_APB_MEM_WR_ERR_CH0_S 26 +/** RMT_APB_MEM_RD_ERR_CH0 : RO; bitpos: [27]; default: 0; + * This status bit will be set if the offset address out of memory size when reads RAM + * via APB bus. + */ +#define RMT_APB_MEM_RD_ERR_CH0 (BIT(27)) +#define RMT_APB_MEM_RD_ERR_CH0_M (RMT_APB_MEM_RD_ERR_CH0_V << RMT_APB_MEM_RD_ERR_CH0_S) +#define RMT_APB_MEM_RD_ERR_CH0_V 0x00000001U +#define RMT_APB_MEM_RD_ERR_CH0_S 27 -#define RMT_CH1STATUS_REG (DR_REG_RMT_BASE + 0x0034) -/* RMT_APB_MEM_RD_ERR_CH1 : RO ;bitpos:[27] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RD_ERR_CH1 (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH1_M (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH1_V 0x1 -#define RMT_APB_MEM_RD_ERR_CH1_S 27 -/* RMT_APB_MEM_WR_ERR_CH1 : RO ;bitpos:[26] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WR_ERR_CH1 (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH1_M (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH1_V 0x1 -#define RMT_APB_MEM_WR_ERR_CH1_S 26 -/* RMT_MEM_EMPTY_CH1 : RO ;bitpos:[25] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_EMPTY_CH1 (BIT(25)) -#define RMT_MEM_EMPTY_CH1_M (BIT(25)) -#define RMT_MEM_EMPTY_CH1_V 0x1 -#define RMT_MEM_EMPTY_CH1_S 25 -/* RMT_MEM_FULL_CH1 : RO ;bitpos:[24] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_FULL_CH1 (BIT(24)) -#define RMT_MEM_FULL_CH1_M (BIT(24)) -#define RMT_MEM_FULL_CH1_V 0x1 -#define RMT_MEM_FULL_CH1_S 24 -/* RMT_MEM_OWNER_ERR_CH1 : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_OWNER_ERR_CH1 (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH1_M (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH1_V 0x1 -#define RMT_MEM_OWNER_ERR_CH1_S 23 -/* RMT_STATE_CH1 : RO ;bitpos:[22:20] ;default: 3'b0 ; */ -/*description: */ -#define RMT_STATE_CH1 0x00000007 -#define RMT_STATE_CH1_M ((RMT_STATE_CH1_V)<<(RMT_STATE_CH1_S)) -#define RMT_STATE_CH1_V 0x7 -#define RMT_STATE_CH1_S 20 -/* RMT_MEM_RADDR_EX_CH1 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_RADDR_EX_CH1 0x000001FF -#define RMT_MEM_RADDR_EX_CH1_M ((RMT_MEM_RADDR_EX_CH1_V)<<(RMT_MEM_RADDR_EX_CH1_S)) -#define RMT_MEM_RADDR_EX_CH1_V 0x1FF -#define RMT_MEM_RADDR_EX_CH1_S 10 -/* RMT_MEM_WADDR_EX_CH1 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_WADDR_EX_CH1 0x000001FF -#define RMT_MEM_WADDR_EX_CH1_M ((RMT_MEM_WADDR_EX_CH1_V)<<(RMT_MEM_WADDR_EX_CH1_S)) -#define RMT_MEM_WADDR_EX_CH1_V 0x1FF +/** RMT_CH1STATUS_REG register + * Channel 1 status register + */ +#define RMT_CH1STATUS_REG (DR_REG_RMT_BASE + 0x34) +/** RMT_MEM_WADDR_EX_CH1 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when receiver of channel 1 is using + * the RAM. + */ +#define RMT_MEM_WADDR_EX_CH1 0x000001FFU +#define RMT_MEM_WADDR_EX_CH1_M (RMT_MEM_WADDR_EX_CH1_V << RMT_MEM_WADDR_EX_CH1_S) +#define RMT_MEM_WADDR_EX_CH1_V 0x000001FFU #define RMT_MEM_WADDR_EX_CH1_S 0 +/** RMT_MEM_RADDR_EX_CH1 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when transmitter of channel 1 is using + * the RAM. + */ +#define RMT_MEM_RADDR_EX_CH1 0x000001FFU +#define RMT_MEM_RADDR_EX_CH1_M (RMT_MEM_RADDR_EX_CH1_V << RMT_MEM_RADDR_EX_CH1_S) +#define RMT_MEM_RADDR_EX_CH1_V 0x000001FFU +#define RMT_MEM_RADDR_EX_CH1_S 10 +/** RMT_STATE_CH1 : RO; bitpos: [22:20]; default: 0; + * This field records the FSM status of channel 1. + */ +#define RMT_STATE_CH1 0x00000007U +#define RMT_STATE_CH1_M (RMT_STATE_CH1_V << RMT_STATE_CH1_S) +#define RMT_STATE_CH1_V 0x00000007U +#define RMT_STATE_CH1_S 20 +/** RMT_MEM_OWNER_ERR_CH1 : RO; bitpos: [23]; default: 0; + * This status bit will be set when the ownership of memory block is violated. + */ +#define RMT_MEM_OWNER_ERR_CH1 (BIT(23)) +#define RMT_MEM_OWNER_ERR_CH1_M (RMT_MEM_OWNER_ERR_CH1_V << RMT_MEM_OWNER_ERR_CH1_S) +#define RMT_MEM_OWNER_ERR_CH1_V 0x00000001U +#define RMT_MEM_OWNER_ERR_CH1_S 23 +/** RMT_MEM_FULL_CH1 : RO; bitpos: [24]; default: 0; + * This status bit will be set if the receiver receives more data than the memory + * allows. + */ +#define RMT_MEM_FULL_CH1 (BIT(24)) +#define RMT_MEM_FULL_CH1_M (RMT_MEM_FULL_CH1_V << RMT_MEM_FULL_CH1_S) +#define RMT_MEM_FULL_CH1_V 0x00000001U +#define RMT_MEM_FULL_CH1_S 24 +/** RMT_MEM_EMPTY_CH1 : RO; bitpos: [25]; default: 0; + * This status bit will be set when the data to be sent is more than memory allows and + * the wrap mode is disabled. + */ +#define RMT_MEM_EMPTY_CH1 (BIT(25)) +#define RMT_MEM_EMPTY_CH1_M (RMT_MEM_EMPTY_CH1_V << RMT_MEM_EMPTY_CH1_S) +#define RMT_MEM_EMPTY_CH1_V 0x00000001U +#define RMT_MEM_EMPTY_CH1_S 25 +/** RMT_APB_MEM_WR_ERR_CH1 : RO; bitpos: [26]; default: 0; + * This status bit will be set if the offset address out of memory size when writes + * RAM via APB bus. + */ +#define RMT_APB_MEM_WR_ERR_CH1 (BIT(26)) +#define RMT_APB_MEM_WR_ERR_CH1_M (RMT_APB_MEM_WR_ERR_CH1_V << RMT_APB_MEM_WR_ERR_CH1_S) +#define RMT_APB_MEM_WR_ERR_CH1_V 0x00000001U +#define RMT_APB_MEM_WR_ERR_CH1_S 26 +/** RMT_APB_MEM_RD_ERR_CH1 : RO; bitpos: [27]; default: 0; + * This status bit will be set if the offset address out of memory size when reads RAM + * via APB bus. + */ +#define RMT_APB_MEM_RD_ERR_CH1 (BIT(27)) +#define RMT_APB_MEM_RD_ERR_CH1_M (RMT_APB_MEM_RD_ERR_CH1_V << RMT_APB_MEM_RD_ERR_CH1_S) +#define RMT_APB_MEM_RD_ERR_CH1_V 0x00000001U +#define RMT_APB_MEM_RD_ERR_CH1_S 27 -#define RMT_CH2STATUS_REG (DR_REG_RMT_BASE + 0x0038) -/* RMT_APB_MEM_RD_ERR_CH2 : RO ;bitpos:[27] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RD_ERR_CH2 (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH2_M (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH2_V 0x1 -#define RMT_APB_MEM_RD_ERR_CH2_S 27 -/* RMT_APB_MEM_WR_ERR_CH2 : RO ;bitpos:[26] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WR_ERR_CH2 (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH2_M (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH2_V 0x1 -#define RMT_APB_MEM_WR_ERR_CH2_S 26 -/* RMT_MEM_EMPTY_CH2 : RO ;bitpos:[25] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_EMPTY_CH2 (BIT(25)) -#define RMT_MEM_EMPTY_CH2_M (BIT(25)) -#define RMT_MEM_EMPTY_CH2_V 0x1 -#define RMT_MEM_EMPTY_CH2_S 25 -/* RMT_MEM_FULL_CH2 : RO ;bitpos:[24] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_FULL_CH2 (BIT(24)) -#define RMT_MEM_FULL_CH2_M (BIT(24)) -#define RMT_MEM_FULL_CH2_V 0x1 -#define RMT_MEM_FULL_CH2_S 24 -/* RMT_MEM_OWNER_ERR_CH2 : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_OWNER_ERR_CH2 (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH2_M (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH2_V 0x1 -#define RMT_MEM_OWNER_ERR_CH2_S 23 -/* RMT_STATE_CH2 : RO ;bitpos:[22:20] ;default: 3'b0 ; */ -/*description: */ -#define RMT_STATE_CH2 0x00000007 -#define RMT_STATE_CH2_M ((RMT_STATE_CH2_V)<<(RMT_STATE_CH2_S)) -#define RMT_STATE_CH2_V 0x7 -#define RMT_STATE_CH2_S 20 -/* RMT_MEM_RADDR_EX_CH2 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_RADDR_EX_CH2 0x000001FF -#define RMT_MEM_RADDR_EX_CH2_M ((RMT_MEM_RADDR_EX_CH2_V)<<(RMT_MEM_RADDR_EX_CH2_S)) -#define RMT_MEM_RADDR_EX_CH2_V 0x1FF -#define RMT_MEM_RADDR_EX_CH2_S 10 -/* RMT_MEM_WADDR_EX_CH2 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_WADDR_EX_CH2 0x000001FF -#define RMT_MEM_WADDR_EX_CH2_M ((RMT_MEM_WADDR_EX_CH2_V)<<(RMT_MEM_WADDR_EX_CH2_S)) -#define RMT_MEM_WADDR_EX_CH2_V 0x1FF +/** RMT_CH2STATUS_REG register + * Channel 2 status register + */ +#define RMT_CH2STATUS_REG (DR_REG_RMT_BASE + 0x38) +/** RMT_MEM_WADDR_EX_CH2 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when receiver of channel 2 is using + * the RAM. + */ +#define RMT_MEM_WADDR_EX_CH2 0x000001FFU +#define RMT_MEM_WADDR_EX_CH2_M (RMT_MEM_WADDR_EX_CH2_V << RMT_MEM_WADDR_EX_CH2_S) +#define RMT_MEM_WADDR_EX_CH2_V 0x000001FFU #define RMT_MEM_WADDR_EX_CH2_S 0 +/** RMT_MEM_RADDR_EX_CH2 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when transmitter of channel 2 is using + * the RAM. + */ +#define RMT_MEM_RADDR_EX_CH2 0x000001FFU +#define RMT_MEM_RADDR_EX_CH2_M (RMT_MEM_RADDR_EX_CH2_V << RMT_MEM_RADDR_EX_CH2_S) +#define RMT_MEM_RADDR_EX_CH2_V 0x000001FFU +#define RMT_MEM_RADDR_EX_CH2_S 10 +/** RMT_STATE_CH2 : RO; bitpos: [22:20]; default: 0; + * This field records the FSM status of channel 2. + */ +#define RMT_STATE_CH2 0x00000007U +#define RMT_STATE_CH2_M (RMT_STATE_CH2_V << RMT_STATE_CH2_S) +#define RMT_STATE_CH2_V 0x00000007U +#define RMT_STATE_CH2_S 20 +/** RMT_MEM_OWNER_ERR_CH2 : RO; bitpos: [23]; default: 0; + * This status bit will be set when the ownership of memory block is violated. + */ +#define RMT_MEM_OWNER_ERR_CH2 (BIT(23)) +#define RMT_MEM_OWNER_ERR_CH2_M (RMT_MEM_OWNER_ERR_CH2_V << RMT_MEM_OWNER_ERR_CH2_S) +#define RMT_MEM_OWNER_ERR_CH2_V 0x00000001U +#define RMT_MEM_OWNER_ERR_CH2_S 23 +/** RMT_MEM_FULL_CH2 : RO; bitpos: [24]; default: 0; + * This status bit will be set if the receiver receives more data than the memory + * allows. + */ +#define RMT_MEM_FULL_CH2 (BIT(24)) +#define RMT_MEM_FULL_CH2_M (RMT_MEM_FULL_CH2_V << RMT_MEM_FULL_CH2_S) +#define RMT_MEM_FULL_CH2_V 0x00000001U +#define RMT_MEM_FULL_CH2_S 24 +/** RMT_MEM_EMPTY_CH2 : RO; bitpos: [25]; default: 0; + * This status bit will be set when the data to be sent is more than memory allows and + * the wrap mode is disabled. + */ +#define RMT_MEM_EMPTY_CH2 (BIT(25)) +#define RMT_MEM_EMPTY_CH2_M (RMT_MEM_EMPTY_CH2_V << RMT_MEM_EMPTY_CH2_S) +#define RMT_MEM_EMPTY_CH2_V 0x00000001U +#define RMT_MEM_EMPTY_CH2_S 25 +/** RMT_APB_MEM_WR_ERR_CH2 : RO; bitpos: [26]; default: 0; + * This status bit will be set if the offset address out of memory size when writes + * RAM via APB bus. + */ +#define RMT_APB_MEM_WR_ERR_CH2 (BIT(26)) +#define RMT_APB_MEM_WR_ERR_CH2_M (RMT_APB_MEM_WR_ERR_CH2_V << RMT_APB_MEM_WR_ERR_CH2_S) +#define RMT_APB_MEM_WR_ERR_CH2_V 0x00000001U +#define RMT_APB_MEM_WR_ERR_CH2_S 26 +/** RMT_APB_MEM_RD_ERR_CH2 : RO; bitpos: [27]; default: 0; + * This status bit will be set if the offset address out of memory size when reads RAM + * via APB bus. + */ +#define RMT_APB_MEM_RD_ERR_CH2 (BIT(27)) +#define RMT_APB_MEM_RD_ERR_CH2_M (RMT_APB_MEM_RD_ERR_CH2_V << RMT_APB_MEM_RD_ERR_CH2_S) +#define RMT_APB_MEM_RD_ERR_CH2_V 0x00000001U +#define RMT_APB_MEM_RD_ERR_CH2_S 27 -#define RMT_CH3STATUS_REG (DR_REG_RMT_BASE + 0x003c) -/* RMT_APB_MEM_RD_ERR_CH3 : RO ;bitpos:[27] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RD_ERR_CH3 (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH3_M (BIT(27)) -#define RMT_APB_MEM_RD_ERR_CH3_V 0x1 -#define RMT_APB_MEM_RD_ERR_CH3_S 27 -/* RMT_APB_MEM_WR_ERR_CH3 : RO ;bitpos:[26] ;default: 1'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WR_ERR_CH3 (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH3_M (BIT(26)) -#define RMT_APB_MEM_WR_ERR_CH3_V 0x1 -#define RMT_APB_MEM_WR_ERR_CH3_S 26 -/* RMT_MEM_EMPTY_CH3 : RO ;bitpos:[25] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_EMPTY_CH3 (BIT(25)) -#define RMT_MEM_EMPTY_CH3_M (BIT(25)) -#define RMT_MEM_EMPTY_CH3_V 0x1 -#define RMT_MEM_EMPTY_CH3_S 25 -/* RMT_MEM_FULL_CH3 : RO ;bitpos:[24] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_FULL_CH3 (BIT(24)) -#define RMT_MEM_FULL_CH3_M (BIT(24)) -#define RMT_MEM_FULL_CH3_V 0x1 -#define RMT_MEM_FULL_CH3_S 24 -/* RMT_MEM_OWNER_ERR_CH3 : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_OWNER_ERR_CH3 (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH3_M (BIT(23)) -#define RMT_MEM_OWNER_ERR_CH3_V 0x1 -#define RMT_MEM_OWNER_ERR_CH3_S 23 -/* RMT_STATE_CH3 : RO ;bitpos:[22:20] ;default: 3'b0 ; */ -/*description: */ -#define RMT_STATE_CH3 0x00000007 -#define RMT_STATE_CH3_M ((RMT_STATE_CH3_V)<<(RMT_STATE_CH3_S)) -#define RMT_STATE_CH3_V 0x7 -#define RMT_STATE_CH3_S 20 -/* RMT_MEM_RADDR_EX_CH3 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_RADDR_EX_CH3 0x000001FF -#define RMT_MEM_RADDR_EX_CH3_M ((RMT_MEM_RADDR_EX_CH3_V)<<(RMT_MEM_RADDR_EX_CH3_S)) -#define RMT_MEM_RADDR_EX_CH3_V 0x1FF -#define RMT_MEM_RADDR_EX_CH3_S 10 -/* RMT_MEM_WADDR_EX_CH3 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_MEM_WADDR_EX_CH3 0x000001FF -#define RMT_MEM_WADDR_EX_CH3_M ((RMT_MEM_WADDR_EX_CH3_V)<<(RMT_MEM_WADDR_EX_CH3_S)) -#define RMT_MEM_WADDR_EX_CH3_V 0x1FF +/** RMT_CH3STATUS_REG register + * Channel 3 status register + */ +#define RMT_CH3STATUS_REG (DR_REG_RMT_BASE + 0x3c) +/** RMT_MEM_WADDR_EX_CH3 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when receiver of channel 3 is using + * the RAM. + */ +#define RMT_MEM_WADDR_EX_CH3 0x000001FFU +#define RMT_MEM_WADDR_EX_CH3_M (RMT_MEM_WADDR_EX_CH3_V << RMT_MEM_WADDR_EX_CH3_S) +#define RMT_MEM_WADDR_EX_CH3_V 0x000001FFU #define RMT_MEM_WADDR_EX_CH3_S 0 +/** RMT_MEM_RADDR_EX_CH3 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when transmitter of channel 3 is using + * the RAM. + */ +#define RMT_MEM_RADDR_EX_CH3 0x000001FFU +#define RMT_MEM_RADDR_EX_CH3_M (RMT_MEM_RADDR_EX_CH3_V << RMT_MEM_RADDR_EX_CH3_S) +#define RMT_MEM_RADDR_EX_CH3_V 0x000001FFU +#define RMT_MEM_RADDR_EX_CH3_S 10 +/** RMT_STATE_CH3 : RO; bitpos: [22:20]; default: 0; + * This field records the FSM status of channel 3. + */ +#define RMT_STATE_CH3 0x00000007U +#define RMT_STATE_CH3_M (RMT_STATE_CH3_V << RMT_STATE_CH3_S) +#define RMT_STATE_CH3_V 0x00000007U +#define RMT_STATE_CH3_S 20 +/** RMT_MEM_OWNER_ERR_CH3 : RO; bitpos: [23]; default: 0; + * This status bit will be set when the ownership of memory block is violated. + */ +#define RMT_MEM_OWNER_ERR_CH3 (BIT(23)) +#define RMT_MEM_OWNER_ERR_CH3_M (RMT_MEM_OWNER_ERR_CH3_V << RMT_MEM_OWNER_ERR_CH3_S) +#define RMT_MEM_OWNER_ERR_CH3_V 0x00000001U +#define RMT_MEM_OWNER_ERR_CH3_S 23 +/** RMT_MEM_FULL_CH3 : RO; bitpos: [24]; default: 0; + * This status bit will be set if the receiver receives more data than the memory + * allows. + */ +#define RMT_MEM_FULL_CH3 (BIT(24)) +#define RMT_MEM_FULL_CH3_M (RMT_MEM_FULL_CH3_V << RMT_MEM_FULL_CH3_S) +#define RMT_MEM_FULL_CH3_V 0x00000001U +#define RMT_MEM_FULL_CH3_S 24 +/** RMT_MEM_EMPTY_CH3 : RO; bitpos: [25]; default: 0; + * This status bit will be set when the data to be sent is more than memory allows and + * the wrap mode is disabled. + */ +#define RMT_MEM_EMPTY_CH3 (BIT(25)) +#define RMT_MEM_EMPTY_CH3_M (RMT_MEM_EMPTY_CH3_V << RMT_MEM_EMPTY_CH3_S) +#define RMT_MEM_EMPTY_CH3_V 0x00000001U +#define RMT_MEM_EMPTY_CH3_S 25 +/** RMT_APB_MEM_WR_ERR_CH3 : RO; bitpos: [26]; default: 0; + * This status bit will be set if the offset address out of memory size when writes + * RAM via APB bus. + */ +#define RMT_APB_MEM_WR_ERR_CH3 (BIT(26)) +#define RMT_APB_MEM_WR_ERR_CH3_M (RMT_APB_MEM_WR_ERR_CH3_V << RMT_APB_MEM_WR_ERR_CH3_S) +#define RMT_APB_MEM_WR_ERR_CH3_V 0x00000001U +#define RMT_APB_MEM_WR_ERR_CH3_S 26 +/** RMT_APB_MEM_RD_ERR_CH3 : RO; bitpos: [27]; default: 0; + * This status bit will be set if the offset address out of memory size when reads RAM + * via APB bus. + */ +#define RMT_APB_MEM_RD_ERR_CH3 (BIT(27)) +#define RMT_APB_MEM_RD_ERR_CH3_M (RMT_APB_MEM_RD_ERR_CH3_V << RMT_APB_MEM_RD_ERR_CH3_S) +#define RMT_APB_MEM_RD_ERR_CH3_V 0x00000001U +#define RMT_APB_MEM_RD_ERR_CH3_S 27 -#define RMT_CH0ADDR_REG (DR_REG_RMT_BASE + 0x0040) -/* RMT_APB_MEM_RADDR_CH0 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RADDR_CH0 0x000001FF -#define RMT_APB_MEM_RADDR_CH0_M ((RMT_APB_MEM_RADDR_CH0_V)<<(RMT_APB_MEM_RADDR_CH0_S)) -#define RMT_APB_MEM_RADDR_CH0_V 0x1FF -#define RMT_APB_MEM_RADDR_CH0_S 10 -/* RMT_APB_MEM_WADDR_CH0 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WADDR_CH0 0x000001FF -#define RMT_APB_MEM_WADDR_CH0_M ((RMT_APB_MEM_WADDR_CH0_V)<<(RMT_APB_MEM_WADDR_CH0_S)) -#define RMT_APB_MEM_WADDR_CH0_V 0x1FF +/** RMT_CH0ADDR_REG register + * Channel 0 address register + */ +#define RMT_CH0ADDR_REG (DR_REG_RMT_BASE + 0x40) +/** RMT_APB_MEM_WADDR_CH0 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when channel 0 writes RAM via APB bus. + */ +#define RMT_APB_MEM_WADDR_CH0 0x000001FFU +#define RMT_APB_MEM_WADDR_CH0_M (RMT_APB_MEM_WADDR_CH0_V << RMT_APB_MEM_WADDR_CH0_S) +#define RMT_APB_MEM_WADDR_CH0_V 0x000001FFU #define RMT_APB_MEM_WADDR_CH0_S 0 +/** RMT_APB_MEM_RADDR_CH0 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when channel 0 reads RAM via APB bus. + */ +#define RMT_APB_MEM_RADDR_CH0 0x000001FFU +#define RMT_APB_MEM_RADDR_CH0_M (RMT_APB_MEM_RADDR_CH0_V << RMT_APB_MEM_RADDR_CH0_S) +#define RMT_APB_MEM_RADDR_CH0_V 0x000001FFU +#define RMT_APB_MEM_RADDR_CH0_S 10 -#define RMT_CH1ADDR_REG (DR_REG_RMT_BASE + 0x0044) -/* RMT_APB_MEM_RADDR_CH1 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RADDR_CH1 0x000001FF -#define RMT_APB_MEM_RADDR_CH1_M ((RMT_APB_MEM_RADDR_CH1_V)<<(RMT_APB_MEM_RADDR_CH1_S)) -#define RMT_APB_MEM_RADDR_CH1_V 0x1FF -#define RMT_APB_MEM_RADDR_CH1_S 10 -/* RMT_APB_MEM_WADDR_CH1 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WADDR_CH1 0x000001FF -#define RMT_APB_MEM_WADDR_CH1_M ((RMT_APB_MEM_WADDR_CH1_V)<<(RMT_APB_MEM_WADDR_CH1_S)) -#define RMT_APB_MEM_WADDR_CH1_V 0x1FF +/** RMT_CH1ADDR_REG register + * Channel 1 address register + */ +#define RMT_CH1ADDR_REG (DR_REG_RMT_BASE + 0x44) +/** RMT_APB_MEM_WADDR_CH1 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when channel 1 writes RAM via APB bus. + */ +#define RMT_APB_MEM_WADDR_CH1 0x000001FFU +#define RMT_APB_MEM_WADDR_CH1_M (RMT_APB_MEM_WADDR_CH1_V << RMT_APB_MEM_WADDR_CH1_S) +#define RMT_APB_MEM_WADDR_CH1_V 0x000001FFU #define RMT_APB_MEM_WADDR_CH1_S 0 +/** RMT_APB_MEM_RADDR_CH1 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when channel 1 reads RAM via APB bus. + */ +#define RMT_APB_MEM_RADDR_CH1 0x000001FFU +#define RMT_APB_MEM_RADDR_CH1_M (RMT_APB_MEM_RADDR_CH1_V << RMT_APB_MEM_RADDR_CH1_S) +#define RMT_APB_MEM_RADDR_CH1_V 0x000001FFU +#define RMT_APB_MEM_RADDR_CH1_S 10 -#define RMT_CH2ADDR_REG (DR_REG_RMT_BASE + 0x0048) -/* RMT_APB_MEM_RADDR_CH2 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RADDR_CH2 0x000001FF -#define RMT_APB_MEM_RADDR_CH2_M ((RMT_APB_MEM_RADDR_CH2_V)<<(RMT_APB_MEM_RADDR_CH2_S)) -#define RMT_APB_MEM_RADDR_CH2_V 0x1FF -#define RMT_APB_MEM_RADDR_CH2_S 10 -/* RMT_APB_MEM_WADDR_CH2 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WADDR_CH2 0x000001FF -#define RMT_APB_MEM_WADDR_CH2_M ((RMT_APB_MEM_WADDR_CH2_V)<<(RMT_APB_MEM_WADDR_CH2_S)) -#define RMT_APB_MEM_WADDR_CH2_V 0x1FF +/** RMT_CH2ADDR_REG register + * Channel 2 address register + */ +#define RMT_CH2ADDR_REG (DR_REG_RMT_BASE + 0x48) +/** RMT_APB_MEM_WADDR_CH2 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when channel 2 writes RAM via APB bus. + */ +#define RMT_APB_MEM_WADDR_CH2 0x000001FFU +#define RMT_APB_MEM_WADDR_CH2_M (RMT_APB_MEM_WADDR_CH2_V << RMT_APB_MEM_WADDR_CH2_S) +#define RMT_APB_MEM_WADDR_CH2_V 0x000001FFU #define RMT_APB_MEM_WADDR_CH2_S 0 +/** RMT_APB_MEM_RADDR_CH2 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when channel 2 reads RAM via APB bus. + */ +#define RMT_APB_MEM_RADDR_CH2 0x000001FFU +#define RMT_APB_MEM_RADDR_CH2_M (RMT_APB_MEM_RADDR_CH2_V << RMT_APB_MEM_RADDR_CH2_S) +#define RMT_APB_MEM_RADDR_CH2_V 0x000001FFU +#define RMT_APB_MEM_RADDR_CH2_S 10 -#define RMT_CH3ADDR_REG (DR_REG_RMT_BASE + 0x004c) -/* RMT_APB_MEM_RADDR_CH3 : RO ;bitpos:[18:10] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_RADDR_CH3 0x000001FF -#define RMT_APB_MEM_RADDR_CH3_M ((RMT_APB_MEM_RADDR_CH3_V)<<(RMT_APB_MEM_RADDR_CH3_S)) -#define RMT_APB_MEM_RADDR_CH3_V 0x1FF -#define RMT_APB_MEM_RADDR_CH3_S 10 -/* RMT_APB_MEM_WADDR_CH3 : RO ;bitpos:[8:0] ;default: 9'b0 ; */ -/*description: */ -#define RMT_APB_MEM_WADDR_CH3 0x000001FF -#define RMT_APB_MEM_WADDR_CH3_M ((RMT_APB_MEM_WADDR_CH3_V)<<(RMT_APB_MEM_WADDR_CH3_S)) -#define RMT_APB_MEM_WADDR_CH3_V 0x1FF +/** RMT_CH3ADDR_REG register + * Channel 3 address register + */ +#define RMT_CH3ADDR_REG (DR_REG_RMT_BASE + 0x4c) +/** RMT_APB_MEM_WADDR_CH3 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when channel 3 writes RAM via APB bus. + */ +#define RMT_APB_MEM_WADDR_CH3 0x000001FFU +#define RMT_APB_MEM_WADDR_CH3_M (RMT_APB_MEM_WADDR_CH3_V << RMT_APB_MEM_WADDR_CH3_S) +#define RMT_APB_MEM_WADDR_CH3_V 0x000001FFU #define RMT_APB_MEM_WADDR_CH3_S 0 +/** RMT_APB_MEM_RADDR_CH3 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when channel 3 reads RAM via APB bus. + */ +#define RMT_APB_MEM_RADDR_CH3 0x000001FFU +#define RMT_APB_MEM_RADDR_CH3_M (RMT_APB_MEM_RADDR_CH3_V << RMT_APB_MEM_RADDR_CH3_S) +#define RMT_APB_MEM_RADDR_CH3_V 0x000001FFU +#define RMT_APB_MEM_RADDR_CH3_S 10 -#define RMT_INT_RAW_REG (DR_REG_RMT_BASE + 0x0050) -/* RMT_CH3_RX_THR_EVENT_INT_RAW : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_THR_EVENT_INT_RAW (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_RAW_M (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH3_RX_THR_EVENT_INT_RAW_S 23 -/* RMT_CH2_RX_THR_EVENT_INT_RAW : RO ;bitpos:[22] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_THR_EVENT_INT_RAW (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_RAW_M (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH2_RX_THR_EVENT_INT_RAW_S 22 -/* RMT_CH1_RX_THR_EVENT_INT_RAW : RO ;bitpos:[21] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_THR_EVENT_INT_RAW (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_RAW_M (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH1_RX_THR_EVENT_INT_RAW_S 21 -/* RMT_CH0_RX_THR_EVENT_INT_RAW : RO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_THR_EVENT_INT_RAW (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_RAW_M (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH0_RX_THR_EVENT_INT_RAW_S 20 -/* RMT_CH3_TX_LOOP_INT_RAW : RO ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_LOOP_INT_RAW (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_RAW_M (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_RAW_V 0x1 -#define RMT_CH3_TX_LOOP_INT_RAW_S 19 -/* RMT_CH2_TX_LOOP_INT_RAW : RO ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_LOOP_INT_RAW (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_RAW_M (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_RAW_V 0x1 -#define RMT_CH2_TX_LOOP_INT_RAW_S 18 -/* RMT_CH1_TX_LOOP_INT_RAW : RO ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_LOOP_INT_RAW (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_RAW_M (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_RAW_V 0x1 -#define RMT_CH1_TX_LOOP_INT_RAW_S 17 -/* RMT_CH0_TX_LOOP_INT_RAW : RO ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_LOOP_INT_RAW (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_RAW_M (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_RAW_V 0x1 -#define RMT_CH0_TX_LOOP_INT_RAW_S 16 -/* RMT_CH3_TX_THR_EVENT_INT_RAW : RO ;bitpos:[15] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_THR_EVENT_INT_RAW (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_RAW_M (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH3_TX_THR_EVENT_INT_RAW_S 15 -/* RMT_CH2_TX_THR_EVENT_INT_RAW : RO ;bitpos:[14] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_THR_EVENT_INT_RAW (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_RAW_M (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH2_TX_THR_EVENT_INT_RAW_S 14 -/* RMT_CH1_TX_THR_EVENT_INT_RAW : RO ;bitpos:[13] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_THR_EVENT_INT_RAW (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_RAW_M (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH1_TX_THR_EVENT_INT_RAW_S 13 -/* RMT_CH0_TX_THR_EVENT_INT_RAW : RO ;bitpos:[12] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_THR_EVENT_INT_RAW (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_RAW_M (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_RAW_V 0x1 -#define RMT_CH0_TX_THR_EVENT_INT_RAW_S 12 -/* RMT_CH3_ERR_INT_RAW : RO ;bitpos:[11] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_ERR_INT_RAW (BIT(11)) -#define RMT_CH3_ERR_INT_RAW_M (BIT(11)) -#define RMT_CH3_ERR_INT_RAW_V 0x1 -#define RMT_CH3_ERR_INT_RAW_S 11 -/* RMT_CH3_RX_END_INT_RAW : RO ;bitpos:[10] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_END_INT_RAW (BIT(10)) -#define RMT_CH3_RX_END_INT_RAW_M (BIT(10)) -#define RMT_CH3_RX_END_INT_RAW_V 0x1 -#define RMT_CH3_RX_END_INT_RAW_S 10 -/* RMT_CH3_TX_END_INT_RAW : RO ;bitpos:[9] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_END_INT_RAW (BIT(9)) -#define RMT_CH3_TX_END_INT_RAW_M (BIT(9)) -#define RMT_CH3_TX_END_INT_RAW_V 0x1 -#define RMT_CH3_TX_END_INT_RAW_S 9 -/* RMT_CH2_ERR_INT_RAW : RO ;bitpos:[8] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_ERR_INT_RAW (BIT(8)) -#define RMT_CH2_ERR_INT_RAW_M (BIT(8)) -#define RMT_CH2_ERR_INT_RAW_V 0x1 -#define RMT_CH2_ERR_INT_RAW_S 8 -/* RMT_CH2_RX_END_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_END_INT_RAW (BIT(7)) -#define RMT_CH2_RX_END_INT_RAW_M (BIT(7)) -#define RMT_CH2_RX_END_INT_RAW_V 0x1 -#define RMT_CH2_RX_END_INT_RAW_S 7 -/* RMT_CH2_TX_END_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_END_INT_RAW (BIT(6)) -#define RMT_CH2_TX_END_INT_RAW_M (BIT(6)) -#define RMT_CH2_TX_END_INT_RAW_V 0x1 -#define RMT_CH2_TX_END_INT_RAW_S 6 -/* RMT_CH1_ERR_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_ERR_INT_RAW (BIT(5)) -#define RMT_CH1_ERR_INT_RAW_M (BIT(5)) -#define RMT_CH1_ERR_INT_RAW_V 0x1 -#define RMT_CH1_ERR_INT_RAW_S 5 -/* RMT_CH1_RX_END_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_END_INT_RAW (BIT(4)) -#define RMT_CH1_RX_END_INT_RAW_M (BIT(4)) -#define RMT_CH1_RX_END_INT_RAW_V 0x1 -#define RMT_CH1_RX_END_INT_RAW_S 4 -/* RMT_CH1_TX_END_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_END_INT_RAW (BIT(3)) -#define RMT_CH1_TX_END_INT_RAW_M (BIT(3)) -#define RMT_CH1_TX_END_INT_RAW_V 0x1 -#define RMT_CH1_TX_END_INT_RAW_S 3 -/* RMT_CH0_ERR_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_ERR_INT_RAW (BIT(2)) -#define RMT_CH0_ERR_INT_RAW_M (BIT(2)) -#define RMT_CH0_ERR_INT_RAW_V 0x1 -#define RMT_CH0_ERR_INT_RAW_S 2 -/* RMT_CH0_RX_END_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_END_INT_RAW (BIT(1)) -#define RMT_CH0_RX_END_INT_RAW_M (BIT(1)) -#define RMT_CH0_RX_END_INT_RAW_V 0x1 -#define RMT_CH0_RX_END_INT_RAW_S 1 -/* RMT_CH0_TX_END_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_END_INT_RAW (BIT(0)) -#define RMT_CH0_TX_END_INT_RAW_M (BIT(0)) -#define RMT_CH0_TX_END_INT_RAW_V 0x1 +/** RMT_INT_RAW_REG register + * Raw interrupt status register + */ +#define RMT_INT_RAW_REG (DR_REG_RMT_BASE + 0x50) +/** RMT_CH0_TX_END_INT_RAW : RO; bitpos: [0]; default: 0; + * The interrupt raw bit for channel 0. Triggered when transmitting ends. + */ +#define RMT_CH0_TX_END_INT_RAW (BIT(0)) +#define RMT_CH0_TX_END_INT_RAW_M (RMT_CH0_TX_END_INT_RAW_V << RMT_CH0_TX_END_INT_RAW_S) +#define RMT_CH0_TX_END_INT_RAW_V 0x00000001U #define RMT_CH0_TX_END_INT_RAW_S 0 +/** RMT_CH0_RX_END_INT_RAW : RO; bitpos: [1]; default: 0; + * The interrupt raw bit for channel 0. Triggered when receiving ends. + */ +#define RMT_CH0_RX_END_INT_RAW (BIT(1)) +#define RMT_CH0_RX_END_INT_RAW_M (RMT_CH0_RX_END_INT_RAW_V << RMT_CH0_RX_END_INT_RAW_S) +#define RMT_CH0_RX_END_INT_RAW_V 0x00000001U +#define RMT_CH0_RX_END_INT_RAW_S 1 +/** RMT_CH0_ERR_INT_RAW : RO; bitpos: [2]; default: 0; + * The interrupt raw bit for channel 0. Triggered when error occurs. + */ +#define RMT_CH0_ERR_INT_RAW (BIT(2)) +#define RMT_CH0_ERR_INT_RAW_M (RMT_CH0_ERR_INT_RAW_V << RMT_CH0_ERR_INT_RAW_S) +#define RMT_CH0_ERR_INT_RAW_V 0x00000001U +#define RMT_CH0_ERR_INT_RAW_S 2 +/** RMT_CH1_TX_END_INT_RAW : RO; bitpos: [3]; default: 0; + * The interrupt raw bit for channel 1. Triggered when transmitting ends. + */ +#define RMT_CH1_TX_END_INT_RAW (BIT(3)) +#define RMT_CH1_TX_END_INT_RAW_M (RMT_CH1_TX_END_INT_RAW_V << RMT_CH1_TX_END_INT_RAW_S) +#define RMT_CH1_TX_END_INT_RAW_V 0x00000001U +#define RMT_CH1_TX_END_INT_RAW_S 3 +/** RMT_CH1_RX_END_INT_RAW : RO; bitpos: [4]; default: 0; + * The interrupt raw bit for channel 1. Triggered when receiving ends. + */ +#define RMT_CH1_RX_END_INT_RAW (BIT(4)) +#define RMT_CH1_RX_END_INT_RAW_M (RMT_CH1_RX_END_INT_RAW_V << RMT_CH1_RX_END_INT_RAW_S) +#define RMT_CH1_RX_END_INT_RAW_V 0x00000001U +#define RMT_CH1_RX_END_INT_RAW_S 4 +/** RMT_CH1_ERR_INT_RAW : RO; bitpos: [5]; default: 0; + * The interrupt raw bit for channel 1. Triggered when error occurs. + */ +#define RMT_CH1_ERR_INT_RAW (BIT(5)) +#define RMT_CH1_ERR_INT_RAW_M (RMT_CH1_ERR_INT_RAW_V << RMT_CH1_ERR_INT_RAW_S) +#define RMT_CH1_ERR_INT_RAW_V 0x00000001U +#define RMT_CH1_ERR_INT_RAW_S 5 +/** RMT_CH2_TX_END_INT_RAW : RO; bitpos: [6]; default: 0; + * The interrupt raw bit for channel 2. Triggered when transmitting ends. + */ +#define RMT_CH2_TX_END_INT_RAW (BIT(6)) +#define RMT_CH2_TX_END_INT_RAW_M (RMT_CH2_TX_END_INT_RAW_V << RMT_CH2_TX_END_INT_RAW_S) +#define RMT_CH2_TX_END_INT_RAW_V 0x00000001U +#define RMT_CH2_TX_END_INT_RAW_S 6 +/** RMT_CH2_RX_END_INT_RAW : RO; bitpos: [7]; default: 0; + * The interrupt raw bit for channel 2. Triggered when receiving ends. + */ +#define RMT_CH2_RX_END_INT_RAW (BIT(7)) +#define RMT_CH2_RX_END_INT_RAW_M (RMT_CH2_RX_END_INT_RAW_V << RMT_CH2_RX_END_INT_RAW_S) +#define RMT_CH2_RX_END_INT_RAW_V 0x00000001U +#define RMT_CH2_RX_END_INT_RAW_S 7 +/** RMT_CH2_ERR_INT_RAW : RO; bitpos: [8]; default: 0; + * The interrupt raw bit for channel 2. Triggered when error occurs. + */ +#define RMT_CH2_ERR_INT_RAW (BIT(8)) +#define RMT_CH2_ERR_INT_RAW_M (RMT_CH2_ERR_INT_RAW_V << RMT_CH2_ERR_INT_RAW_S) +#define RMT_CH2_ERR_INT_RAW_V 0x00000001U +#define RMT_CH2_ERR_INT_RAW_S 8 +/** RMT_CH3_TX_END_INT_RAW : RO; bitpos: [9]; default: 0; + * The interrupt raw bit for channel 3. Triggered when transmitting ends. + */ +#define RMT_CH3_TX_END_INT_RAW (BIT(9)) +#define RMT_CH3_TX_END_INT_RAW_M (RMT_CH3_TX_END_INT_RAW_V << RMT_CH3_TX_END_INT_RAW_S) +#define RMT_CH3_TX_END_INT_RAW_V 0x00000001U +#define RMT_CH3_TX_END_INT_RAW_S 9 +/** RMT_CH3_RX_END_INT_RAW : RO; bitpos: [10]; default: 0; + * The interrupt raw bit for channel 3. Triggered when receiving ends. + */ +#define RMT_CH3_RX_END_INT_RAW (BIT(10)) +#define RMT_CH3_RX_END_INT_RAW_M (RMT_CH3_RX_END_INT_RAW_V << RMT_CH3_RX_END_INT_RAW_S) +#define RMT_CH3_RX_END_INT_RAW_V 0x00000001U +#define RMT_CH3_RX_END_INT_RAW_S 10 +/** RMT_CH3_ERR_INT_RAW : RO; bitpos: [11]; default: 0; + * The interrupt raw bit for channel 3. Triggered when error occurs. + */ +#define RMT_CH3_ERR_INT_RAW (BIT(11)) +#define RMT_CH3_ERR_INT_RAW_M (RMT_CH3_ERR_INT_RAW_V << RMT_CH3_ERR_INT_RAW_S) +#define RMT_CH3_ERR_INT_RAW_V 0x00000001U +#define RMT_CH3_ERR_INT_RAW_S 11 +/** RMT_CH0_TX_THR_EVENT_INT_RAW : RO; bitpos: [12]; default: 0; + * The interrupt raw bit for channel 0. Triggered when transmitter sends more data + * than configured value. + */ +#define RMT_CH0_TX_THR_EVENT_INT_RAW (BIT(12)) +#define RMT_CH0_TX_THR_EVENT_INT_RAW_M (RMT_CH0_TX_THR_EVENT_INT_RAW_V << RMT_CH0_TX_THR_EVENT_INT_RAW_S) +#define RMT_CH0_TX_THR_EVENT_INT_RAW_V 0x00000001U +#define RMT_CH0_TX_THR_EVENT_INT_RAW_S 12 +/** RMT_CH1_TX_THR_EVENT_INT_RAW : RO; bitpos: [13]; default: 0; + * The interrupt raw bit for channel 1. Triggered when transmitter sends more data + * than configured value. + */ +#define RMT_CH1_TX_THR_EVENT_INT_RAW (BIT(13)) +#define RMT_CH1_TX_THR_EVENT_INT_RAW_M (RMT_CH1_TX_THR_EVENT_INT_RAW_V << RMT_CH1_TX_THR_EVENT_INT_RAW_S) +#define RMT_CH1_TX_THR_EVENT_INT_RAW_V 0x00000001U +#define RMT_CH1_TX_THR_EVENT_INT_RAW_S 13 +/** RMT_CH2_TX_THR_EVENT_INT_RAW : RO; bitpos: [14]; default: 0; + * The interrupt raw bit for channel 2. Triggered when transmitter sends more data + * than configured value. + */ +#define RMT_CH2_TX_THR_EVENT_INT_RAW (BIT(14)) +#define RMT_CH2_TX_THR_EVENT_INT_RAW_M (RMT_CH2_TX_THR_EVENT_INT_RAW_V << RMT_CH2_TX_THR_EVENT_INT_RAW_S) +#define RMT_CH2_TX_THR_EVENT_INT_RAW_V 0x00000001U +#define RMT_CH2_TX_THR_EVENT_INT_RAW_S 14 +/** RMT_CH3_TX_THR_EVENT_INT_RAW : RO; bitpos: [15]; default: 0; + * The interrupt raw bit for channel 3. Triggered when transmitter sends more data + * than configured value. + */ +#define RMT_CH3_TX_THR_EVENT_INT_RAW (BIT(15)) +#define RMT_CH3_TX_THR_EVENT_INT_RAW_M (RMT_CH3_TX_THR_EVENT_INT_RAW_V << RMT_CH3_TX_THR_EVENT_INT_RAW_S) +#define RMT_CH3_TX_THR_EVENT_INT_RAW_V 0x00000001U +#define RMT_CH3_TX_THR_EVENT_INT_RAW_S 15 +/** RMT_CH0_TX_LOOP_INT_RAW : RO; bitpos: [16]; default: 0; + * The interrupt raw bit for channel 0. Triggered when loop counting reaches the + * configured threshold value. + */ +#define RMT_CH0_TX_LOOP_INT_RAW (BIT(16)) +#define RMT_CH0_TX_LOOP_INT_RAW_M (RMT_CH0_TX_LOOP_INT_RAW_V << RMT_CH0_TX_LOOP_INT_RAW_S) +#define RMT_CH0_TX_LOOP_INT_RAW_V 0x00000001U +#define RMT_CH0_TX_LOOP_INT_RAW_S 16 +/** RMT_CH1_TX_LOOP_INT_RAW : RO; bitpos: [17]; default: 0; + * The interrupt raw bit for channel 1. Triggered when loop counting reaches the + * configured threshold value. + */ +#define RMT_CH1_TX_LOOP_INT_RAW (BIT(17)) +#define RMT_CH1_TX_LOOP_INT_RAW_M (RMT_CH1_TX_LOOP_INT_RAW_V << RMT_CH1_TX_LOOP_INT_RAW_S) +#define RMT_CH1_TX_LOOP_INT_RAW_V 0x00000001U +#define RMT_CH1_TX_LOOP_INT_RAW_S 17 +/** RMT_CH2_TX_LOOP_INT_RAW : RO; bitpos: [18]; default: 0; + * The interrupt raw bit for channel 2. Triggered when loop counting reaches the + * configured threshold value. + */ +#define RMT_CH2_TX_LOOP_INT_RAW (BIT(18)) +#define RMT_CH2_TX_LOOP_INT_RAW_M (RMT_CH2_TX_LOOP_INT_RAW_V << RMT_CH2_TX_LOOP_INT_RAW_S) +#define RMT_CH2_TX_LOOP_INT_RAW_V 0x00000001U +#define RMT_CH2_TX_LOOP_INT_RAW_S 18 +/** RMT_CH3_TX_LOOP_INT_RAW : RO; bitpos: [19]; default: 0; + * The interrupt raw bit for channel 3. Triggered when loop counting reaches the + * configured threshold value. + */ +#define RMT_CH3_TX_LOOP_INT_RAW (BIT(19)) +#define RMT_CH3_TX_LOOP_INT_RAW_M (RMT_CH3_TX_LOOP_INT_RAW_V << RMT_CH3_TX_LOOP_INT_RAW_S) +#define RMT_CH3_TX_LOOP_INT_RAW_V 0x00000001U +#define RMT_CH3_TX_LOOP_INT_RAW_S 19 -#define RMT_INT_ST_REG (DR_REG_RMT_BASE + 0x0054) -/* RMT_CH3_RX_THR_EVENT_INT_ST : RO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_THR_EVENT_INT_ST (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_ST_M (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH3_RX_THR_EVENT_INT_ST_S 23 -/* RMT_CH2_RX_THR_EVENT_INT_ST : RO ;bitpos:[22] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_THR_EVENT_INT_ST (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_ST_M (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH2_RX_THR_EVENT_INT_ST_S 22 -/* RMT_CH1_RX_THR_EVENT_INT_ST : RO ;bitpos:[21] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_THR_EVENT_INT_ST (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_ST_M (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH1_RX_THR_EVENT_INT_ST_S 21 -/* RMT_CH0_RX_THR_EVENT_INT_ST : RO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_THR_EVENT_INT_ST (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_ST_M (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH0_RX_THR_EVENT_INT_ST_S 20 -/* RMT_CH3_TX_LOOP_INT_ST : RO ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_LOOP_INT_ST (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_ST_M (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_ST_V 0x1 -#define RMT_CH3_TX_LOOP_INT_ST_S 19 -/* RMT_CH2_TX_LOOP_INT_ST : RO ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_LOOP_INT_ST (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_ST_M (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_ST_V 0x1 -#define RMT_CH2_TX_LOOP_INT_ST_S 18 -/* RMT_CH1_TX_LOOP_INT_ST : RO ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_LOOP_INT_ST (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_ST_M (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_ST_V 0x1 -#define RMT_CH1_TX_LOOP_INT_ST_S 17 -/* RMT_CH0_TX_LOOP_INT_ST : RO ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_LOOP_INT_ST (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_ST_M (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_ST_V 0x1 -#define RMT_CH0_TX_LOOP_INT_ST_S 16 -/* RMT_CH3_TX_THR_EVENT_INT_ST : RO ;bitpos:[15] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_THR_EVENT_INT_ST (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_ST_M (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH3_TX_THR_EVENT_INT_ST_S 15 -/* RMT_CH2_TX_THR_EVENT_INT_ST : RO ;bitpos:[14] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_THR_EVENT_INT_ST (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_ST_M (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH2_TX_THR_EVENT_INT_ST_S 14 -/* RMT_CH1_TX_THR_EVENT_INT_ST : RO ;bitpos:[13] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_THR_EVENT_INT_ST (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_ST_M (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH1_TX_THR_EVENT_INT_ST_S 13 -/* RMT_CH0_TX_THR_EVENT_INT_ST : RO ;bitpos:[12] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_THR_EVENT_INT_ST (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_ST_M (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_ST_V 0x1 -#define RMT_CH0_TX_THR_EVENT_INT_ST_S 12 -/* RMT_CH3_ERR_INT_ST : RO ;bitpos:[11] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_ERR_INT_ST (BIT(11)) -#define RMT_CH3_ERR_INT_ST_M (BIT(11)) -#define RMT_CH3_ERR_INT_ST_V 0x1 -#define RMT_CH3_ERR_INT_ST_S 11 -/* RMT_CH3_RX_END_INT_ST : RO ;bitpos:[10] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_END_INT_ST (BIT(10)) -#define RMT_CH3_RX_END_INT_ST_M (BIT(10)) -#define RMT_CH3_RX_END_INT_ST_V 0x1 -#define RMT_CH3_RX_END_INT_ST_S 10 -/* RMT_CH3_TX_END_INT_ST : RO ;bitpos:[9] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_END_INT_ST (BIT(9)) -#define RMT_CH3_TX_END_INT_ST_M (BIT(9)) -#define RMT_CH3_TX_END_INT_ST_V 0x1 -#define RMT_CH3_TX_END_INT_ST_S 9 -/* RMT_CH2_ERR_INT_ST : RO ;bitpos:[8] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_ERR_INT_ST (BIT(8)) -#define RMT_CH2_ERR_INT_ST_M (BIT(8)) -#define RMT_CH2_ERR_INT_ST_V 0x1 -#define RMT_CH2_ERR_INT_ST_S 8 -/* RMT_CH2_RX_END_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_END_INT_ST (BIT(7)) -#define RMT_CH2_RX_END_INT_ST_M (BIT(7)) -#define RMT_CH2_RX_END_INT_ST_V 0x1 -#define RMT_CH2_RX_END_INT_ST_S 7 -/* RMT_CH2_TX_END_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_END_INT_ST (BIT(6)) -#define RMT_CH2_TX_END_INT_ST_M (BIT(6)) -#define RMT_CH2_TX_END_INT_ST_V 0x1 -#define RMT_CH2_TX_END_INT_ST_S 6 -/* RMT_CH1_ERR_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_ERR_INT_ST (BIT(5)) -#define RMT_CH1_ERR_INT_ST_M (BIT(5)) -#define RMT_CH1_ERR_INT_ST_V 0x1 -#define RMT_CH1_ERR_INT_ST_S 5 -/* RMT_CH1_RX_END_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_END_INT_ST (BIT(4)) -#define RMT_CH1_RX_END_INT_ST_M (BIT(4)) -#define RMT_CH1_RX_END_INT_ST_V 0x1 -#define RMT_CH1_RX_END_INT_ST_S 4 -/* RMT_CH1_TX_END_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_END_INT_ST (BIT(3)) -#define RMT_CH1_TX_END_INT_ST_M (BIT(3)) -#define RMT_CH1_TX_END_INT_ST_V 0x1 -#define RMT_CH1_TX_END_INT_ST_S 3 -/* RMT_CH0_ERR_INT_ST : RO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_ERR_INT_ST (BIT(2)) -#define RMT_CH0_ERR_INT_ST_M (BIT(2)) -#define RMT_CH0_ERR_INT_ST_V 0x1 -#define RMT_CH0_ERR_INT_ST_S 2 -/* RMT_CH0_RX_END_INT_ST : RO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_END_INT_ST (BIT(1)) -#define RMT_CH0_RX_END_INT_ST_M (BIT(1)) -#define RMT_CH0_RX_END_INT_ST_V 0x1 -#define RMT_CH0_RX_END_INT_ST_S 1 -/* RMT_CH0_TX_END_INT_ST : RO ;bitpos:[0] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_END_INT_ST (BIT(0)) -#define RMT_CH0_TX_END_INT_ST_M (BIT(0)) -#define RMT_CH0_TX_END_INT_ST_V 0x1 +/** RMT_INT_ST_REG register + * Masked interrupt status register + */ +#define RMT_INT_ST_REG (DR_REG_RMT_BASE + 0x54) +/** RMT_CH0_TX_END_INT_ST : RO; bitpos: [0]; default: 0; + * The masked interrupt status bit for RMT_CH0_TX_END_INT. + */ +#define RMT_CH0_TX_END_INT_ST (BIT(0)) +#define RMT_CH0_TX_END_INT_ST_M (RMT_CH0_TX_END_INT_ST_V << RMT_CH0_TX_END_INT_ST_S) +#define RMT_CH0_TX_END_INT_ST_V 0x00000001U #define RMT_CH0_TX_END_INT_ST_S 0 +/** RMT_CH0_RX_END_INT_ST : RO; bitpos: [1]; default: 0; + * The masked interrupt status bit for RMT_CH0_RX_END_INT. + */ +#define RMT_CH0_RX_END_INT_ST (BIT(1)) +#define RMT_CH0_RX_END_INT_ST_M (RMT_CH0_RX_END_INT_ST_V << RMT_CH0_RX_END_INT_ST_S) +#define RMT_CH0_RX_END_INT_ST_V 0x00000001U +#define RMT_CH0_RX_END_INT_ST_S 1 +/** RMT_CH0_ERR_INT_ST : RO; bitpos: [2]; default: 0; + * The masked interrupt status bit for RMT_CH0_ERR_INT. + */ +#define RMT_CH0_ERR_INT_ST (BIT(2)) +#define RMT_CH0_ERR_INT_ST_M (RMT_CH0_ERR_INT_ST_V << RMT_CH0_ERR_INT_ST_S) +#define RMT_CH0_ERR_INT_ST_V 0x00000001U +#define RMT_CH0_ERR_INT_ST_S 2 +/** RMT_CH1_TX_END_INT_ST : RO; bitpos: [3]; default: 0; + * The masked interrupt status bit for RMT_CH1_TX_END_INT. + */ +#define RMT_CH1_TX_END_INT_ST (BIT(3)) +#define RMT_CH1_TX_END_INT_ST_M (RMT_CH1_TX_END_INT_ST_V << RMT_CH1_TX_END_INT_ST_S) +#define RMT_CH1_TX_END_INT_ST_V 0x00000001U +#define RMT_CH1_TX_END_INT_ST_S 3 +/** RMT_CH1_RX_END_INT_ST : RO; bitpos: [4]; default: 0; + * The masked interrupt status bit for RMT_CH1_RX_END_INT. + */ +#define RMT_CH1_RX_END_INT_ST (BIT(4)) +#define RMT_CH1_RX_END_INT_ST_M (RMT_CH1_RX_END_INT_ST_V << RMT_CH1_RX_END_INT_ST_S) +#define RMT_CH1_RX_END_INT_ST_V 0x00000001U +#define RMT_CH1_RX_END_INT_ST_S 4 +/** RMT_CH1_ERR_INT_ST : RO; bitpos: [5]; default: 0; + * The masked interrupt status bit for RMT_CH1_ERR_INT. + */ +#define RMT_CH1_ERR_INT_ST (BIT(5)) +#define RMT_CH1_ERR_INT_ST_M (RMT_CH1_ERR_INT_ST_V << RMT_CH1_ERR_INT_ST_S) +#define RMT_CH1_ERR_INT_ST_V 0x00000001U +#define RMT_CH1_ERR_INT_ST_S 5 +/** RMT_CH2_TX_END_INT_ST : RO; bitpos: [6]; default: 0; + * The masked interrupt status bit for RMT_CH2_TX_END_INT. + */ +#define RMT_CH2_TX_END_INT_ST (BIT(6)) +#define RMT_CH2_TX_END_INT_ST_M (RMT_CH2_TX_END_INT_ST_V << RMT_CH2_TX_END_INT_ST_S) +#define RMT_CH2_TX_END_INT_ST_V 0x00000001U +#define RMT_CH2_TX_END_INT_ST_S 6 +/** RMT_CH2_RX_END_INT_ST : RO; bitpos: [7]; default: 0; + * The masked interrupt status bit for RMT_CH2_RX_END_INT. + */ +#define RMT_CH2_RX_END_INT_ST (BIT(7)) +#define RMT_CH2_RX_END_INT_ST_M (RMT_CH2_RX_END_INT_ST_V << RMT_CH2_RX_END_INT_ST_S) +#define RMT_CH2_RX_END_INT_ST_V 0x00000001U +#define RMT_CH2_RX_END_INT_ST_S 7 +/** RMT_CH2_ERR_INT_ST : RO; bitpos: [8]; default: 0; + * The masked interrupt status bit for RMT_CH2_ERR_INT. + */ +#define RMT_CH2_ERR_INT_ST (BIT(8)) +#define RMT_CH2_ERR_INT_ST_M (RMT_CH2_ERR_INT_ST_V << RMT_CH2_ERR_INT_ST_S) +#define RMT_CH2_ERR_INT_ST_V 0x00000001U +#define RMT_CH2_ERR_INT_ST_S 8 +/** RMT_CH3_TX_END_INT_ST : RO; bitpos: [9]; default: 0; + * The masked interrupt status bit for RMT_CH3_TX_END_INT. + */ +#define RMT_CH3_TX_END_INT_ST (BIT(9)) +#define RMT_CH3_TX_END_INT_ST_M (RMT_CH3_TX_END_INT_ST_V << RMT_CH3_TX_END_INT_ST_S) +#define RMT_CH3_TX_END_INT_ST_V 0x00000001U +#define RMT_CH3_TX_END_INT_ST_S 9 +/** RMT_CH3_RX_END_INT_ST : RO; bitpos: [10]; default: 0; + * The masked interrupt status bit for RMT_CH3_RX_END_INT. + */ +#define RMT_CH3_RX_END_INT_ST (BIT(10)) +#define RMT_CH3_RX_END_INT_ST_M (RMT_CH3_RX_END_INT_ST_V << RMT_CH3_RX_END_INT_ST_S) +#define RMT_CH3_RX_END_INT_ST_V 0x00000001U +#define RMT_CH3_RX_END_INT_ST_S 10 +/** RMT_CH3_ERR_INT_ST : RO; bitpos: [11]; default: 0; + * The masked interrupt status bit for RMT_CH3_ERR_INT. + */ +#define RMT_CH3_ERR_INT_ST (BIT(11)) +#define RMT_CH3_ERR_INT_ST_M (RMT_CH3_ERR_INT_ST_V << RMT_CH3_ERR_INT_ST_S) +#define RMT_CH3_ERR_INT_ST_V 0x00000001U +#define RMT_CH3_ERR_INT_ST_S 11 +/** RMT_CH0_TX_THR_EVENT_INT_ST : RO; bitpos: [12]; default: 0; + * The masked interrupt status bit for RMT_CH0_TX_THR_EVENT_INT. + */ +#define RMT_CH0_TX_THR_EVENT_INT_ST (BIT(12)) +#define RMT_CH0_TX_THR_EVENT_INT_ST_M (RMT_CH0_TX_THR_EVENT_INT_ST_V << RMT_CH0_TX_THR_EVENT_INT_ST_S) +#define RMT_CH0_TX_THR_EVENT_INT_ST_V 0x00000001U +#define RMT_CH0_TX_THR_EVENT_INT_ST_S 12 +/** RMT_CH1_TX_THR_EVENT_INT_ST : RO; bitpos: [13]; default: 0; + * The masked interrupt status bit for RMT_CH1_TX_THR_EVENT_INT. + */ +#define RMT_CH1_TX_THR_EVENT_INT_ST (BIT(13)) +#define RMT_CH1_TX_THR_EVENT_INT_ST_M (RMT_CH1_TX_THR_EVENT_INT_ST_V << RMT_CH1_TX_THR_EVENT_INT_ST_S) +#define RMT_CH1_TX_THR_EVENT_INT_ST_V 0x00000001U +#define RMT_CH1_TX_THR_EVENT_INT_ST_S 13 +/** RMT_CH2_TX_THR_EVENT_INT_ST : RO; bitpos: [14]; default: 0; + * The masked interrupt status bit for RMT_CH2_TX_THR_EVENT_INT. + */ +#define RMT_CH2_TX_THR_EVENT_INT_ST (BIT(14)) +#define RMT_CH2_TX_THR_EVENT_INT_ST_M (RMT_CH2_TX_THR_EVENT_INT_ST_V << RMT_CH2_TX_THR_EVENT_INT_ST_S) +#define RMT_CH2_TX_THR_EVENT_INT_ST_V 0x00000001U +#define RMT_CH2_TX_THR_EVENT_INT_ST_S 14 +/** RMT_CH3_TX_THR_EVENT_INT_ST : RO; bitpos: [15]; default: 0; + * The masked interrupt status bit for RMT_CH3_TX_THR_EVENT_INT. + */ +#define RMT_CH3_TX_THR_EVENT_INT_ST (BIT(15)) +#define RMT_CH3_TX_THR_EVENT_INT_ST_M (RMT_CH3_TX_THR_EVENT_INT_ST_V << RMT_CH3_TX_THR_EVENT_INT_ST_S) +#define RMT_CH3_TX_THR_EVENT_INT_ST_V 0x00000001U +#define RMT_CH3_TX_THR_EVENT_INT_ST_S 15 +/** RMT_CH0_TX_LOOP_INT_ST : RO; bitpos: [16]; default: 0; + * The masked interrupt status bit for RMT_CH0_TX_LOOP_INT. + */ +#define RMT_CH0_TX_LOOP_INT_ST (BIT(16)) +#define RMT_CH0_TX_LOOP_INT_ST_M (RMT_CH0_TX_LOOP_INT_ST_V << RMT_CH0_TX_LOOP_INT_ST_S) +#define RMT_CH0_TX_LOOP_INT_ST_V 0x00000001U +#define RMT_CH0_TX_LOOP_INT_ST_S 16 +/** RMT_CH1_TX_LOOP_INT_ST : RO; bitpos: [17]; default: 0; + * The masked interrupt status bit for RMT_CH1_TX_LOOP_INT. + */ +#define RMT_CH1_TX_LOOP_INT_ST (BIT(17)) +#define RMT_CH1_TX_LOOP_INT_ST_M (RMT_CH1_TX_LOOP_INT_ST_V << RMT_CH1_TX_LOOP_INT_ST_S) +#define RMT_CH1_TX_LOOP_INT_ST_V 0x00000001U +#define RMT_CH1_TX_LOOP_INT_ST_S 17 +/** RMT_CH2_TX_LOOP_INT_ST : RO; bitpos: [18]; default: 0; + * The masked interrupt status bit for RMT_CH2_TX_LOOP_INT. + */ +#define RMT_CH2_TX_LOOP_INT_ST (BIT(18)) +#define RMT_CH2_TX_LOOP_INT_ST_M (RMT_CH2_TX_LOOP_INT_ST_V << RMT_CH2_TX_LOOP_INT_ST_S) +#define RMT_CH2_TX_LOOP_INT_ST_V 0x00000001U +#define RMT_CH2_TX_LOOP_INT_ST_S 18 +/** RMT_CH3_TX_LOOP_INT_ST : RO; bitpos: [19]; default: 0; + * The masked interrupt status bit for RMT_CH3_TX_LOOP_INT. + */ +#define RMT_CH3_TX_LOOP_INT_ST (BIT(19)) +#define RMT_CH3_TX_LOOP_INT_ST_M (RMT_CH3_TX_LOOP_INT_ST_V << RMT_CH3_TX_LOOP_INT_ST_S) +#define RMT_CH3_TX_LOOP_INT_ST_V 0x00000001U +#define RMT_CH3_TX_LOOP_INT_ST_S 19 -#define RMT_INT_ENA_REG (DR_REG_RMT_BASE + 0x0058) -/* RMT_CH3_RX_THR_EVENT_INT_ENA : R/W ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_THR_EVENT_INT_ENA (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_ENA_M (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH3_RX_THR_EVENT_INT_ENA_S 23 -/* RMT_CH2_RX_THR_EVENT_INT_ENA : R/W ;bitpos:[22] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_THR_EVENT_INT_ENA (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_ENA_M (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH2_RX_THR_EVENT_INT_ENA_S 22 -/* RMT_CH1_RX_THR_EVENT_INT_ENA : R/W ;bitpos:[21] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_THR_EVENT_INT_ENA (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_ENA_M (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH1_RX_THR_EVENT_INT_ENA_S 21 -/* RMT_CH0_RX_THR_EVENT_INT_ENA : R/W ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_THR_EVENT_INT_ENA (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_ENA_M (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH0_RX_THR_EVENT_INT_ENA_S 20 -/* RMT_CH3_TX_LOOP_INT_ENA : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_LOOP_INT_ENA (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_ENA_M (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_ENA_V 0x1 -#define RMT_CH3_TX_LOOP_INT_ENA_S 19 -/* RMT_CH2_TX_LOOP_INT_ENA : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_LOOP_INT_ENA (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_ENA_M (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_ENA_V 0x1 -#define RMT_CH2_TX_LOOP_INT_ENA_S 18 -/* RMT_CH1_TX_LOOP_INT_ENA : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_LOOP_INT_ENA (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_ENA_M (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_ENA_V 0x1 -#define RMT_CH1_TX_LOOP_INT_ENA_S 17 -/* RMT_CH0_TX_LOOP_INT_ENA : R/W ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_LOOP_INT_ENA (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_ENA_M (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_ENA_V 0x1 -#define RMT_CH0_TX_LOOP_INT_ENA_S 16 -/* RMT_CH3_TX_THR_EVENT_INT_ENA : R/W ;bitpos:[15] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_THR_EVENT_INT_ENA (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_ENA_M (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH3_TX_THR_EVENT_INT_ENA_S 15 -/* RMT_CH2_TX_THR_EVENT_INT_ENA : R/W ;bitpos:[14] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_THR_EVENT_INT_ENA (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_ENA_M (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH2_TX_THR_EVENT_INT_ENA_S 14 -/* RMT_CH1_TX_THR_EVENT_INT_ENA : R/W ;bitpos:[13] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_THR_EVENT_INT_ENA (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_ENA_M (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH1_TX_THR_EVENT_INT_ENA_S 13 -/* RMT_CH0_TX_THR_EVENT_INT_ENA : R/W ;bitpos:[12] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_THR_EVENT_INT_ENA (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_ENA_M (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_ENA_V 0x1 -#define RMT_CH0_TX_THR_EVENT_INT_ENA_S 12 -/* RMT_CH3_ERR_INT_ENA : R/W ;bitpos:[11] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_ERR_INT_ENA (BIT(11)) -#define RMT_CH3_ERR_INT_ENA_M (BIT(11)) -#define RMT_CH3_ERR_INT_ENA_V 0x1 -#define RMT_CH3_ERR_INT_ENA_S 11 -/* RMT_CH3_RX_END_INT_ENA : R/W ;bitpos:[10] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_END_INT_ENA (BIT(10)) -#define RMT_CH3_RX_END_INT_ENA_M (BIT(10)) -#define RMT_CH3_RX_END_INT_ENA_V 0x1 -#define RMT_CH3_RX_END_INT_ENA_S 10 -/* RMT_CH3_TX_END_INT_ENA : R/W ;bitpos:[9] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_END_INT_ENA (BIT(9)) -#define RMT_CH3_TX_END_INT_ENA_M (BIT(9)) -#define RMT_CH3_TX_END_INT_ENA_V 0x1 -#define RMT_CH3_TX_END_INT_ENA_S 9 -/* RMT_CH2_ERR_INT_ENA : R/W ;bitpos:[8] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_ERR_INT_ENA (BIT(8)) -#define RMT_CH2_ERR_INT_ENA_M (BIT(8)) -#define RMT_CH2_ERR_INT_ENA_V 0x1 -#define RMT_CH2_ERR_INT_ENA_S 8 -/* RMT_CH2_RX_END_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_END_INT_ENA (BIT(7)) -#define RMT_CH2_RX_END_INT_ENA_M (BIT(7)) -#define RMT_CH2_RX_END_INT_ENA_V 0x1 -#define RMT_CH2_RX_END_INT_ENA_S 7 -/* RMT_CH2_TX_END_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_END_INT_ENA (BIT(6)) -#define RMT_CH2_TX_END_INT_ENA_M (BIT(6)) -#define RMT_CH2_TX_END_INT_ENA_V 0x1 -#define RMT_CH2_TX_END_INT_ENA_S 6 -/* RMT_CH1_ERR_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_ERR_INT_ENA (BIT(5)) -#define RMT_CH1_ERR_INT_ENA_M (BIT(5)) -#define RMT_CH1_ERR_INT_ENA_V 0x1 -#define RMT_CH1_ERR_INT_ENA_S 5 -/* RMT_CH1_RX_END_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_END_INT_ENA (BIT(4)) -#define RMT_CH1_RX_END_INT_ENA_M (BIT(4)) -#define RMT_CH1_RX_END_INT_ENA_V 0x1 -#define RMT_CH1_RX_END_INT_ENA_S 4 -/* RMT_CH1_TX_END_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_END_INT_ENA (BIT(3)) -#define RMT_CH1_TX_END_INT_ENA_M (BIT(3)) -#define RMT_CH1_TX_END_INT_ENA_V 0x1 -#define RMT_CH1_TX_END_INT_ENA_S 3 -/* RMT_CH0_ERR_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_ERR_INT_ENA (BIT(2)) -#define RMT_CH0_ERR_INT_ENA_M (BIT(2)) -#define RMT_CH0_ERR_INT_ENA_V 0x1 -#define RMT_CH0_ERR_INT_ENA_S 2 -/* RMT_CH0_RX_END_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_END_INT_ENA (BIT(1)) -#define RMT_CH0_RX_END_INT_ENA_M (BIT(1)) -#define RMT_CH0_RX_END_INT_ENA_V 0x1 -#define RMT_CH0_RX_END_INT_ENA_S 1 -/* RMT_CH0_TX_END_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_END_INT_ENA (BIT(0)) -#define RMT_CH0_TX_END_INT_ENA_M (BIT(0)) -#define RMT_CH0_TX_END_INT_ENA_V 0x1 +/** RMT_INT_ENA_REG register + * Interrupt enable register + */ +#define RMT_INT_ENA_REG (DR_REG_RMT_BASE + 0x58) +/** RMT_CH0_TX_END_INT_ENA : R/W; bitpos: [0]; default: 0; + * The interrupt enabled bit for RMT_CH0_TX_END_INT. + */ +#define RMT_CH0_TX_END_INT_ENA (BIT(0)) +#define RMT_CH0_TX_END_INT_ENA_M (RMT_CH0_TX_END_INT_ENA_V << RMT_CH0_TX_END_INT_ENA_S) +#define RMT_CH0_TX_END_INT_ENA_V 0x00000001U #define RMT_CH0_TX_END_INT_ENA_S 0 +/** RMT_CH0_RX_END_INT_ENA : R/W; bitpos: [1]; default: 0; + * The interrupt enabled bit for RMT_CH0_RX_END_INT. + */ +#define RMT_CH0_RX_END_INT_ENA (BIT(1)) +#define RMT_CH0_RX_END_INT_ENA_M (RMT_CH0_RX_END_INT_ENA_V << RMT_CH0_RX_END_INT_ENA_S) +#define RMT_CH0_RX_END_INT_ENA_V 0x00000001U +#define RMT_CH0_RX_END_INT_ENA_S 1 +/** RMT_CH0_ERR_INT_ENA : R/W; bitpos: [2]; default: 0; + * The interrupt enabled bit for RMT_CH0_ERR_INT. + */ +#define RMT_CH0_ERR_INT_ENA (BIT(2)) +#define RMT_CH0_ERR_INT_ENA_M (RMT_CH0_ERR_INT_ENA_V << RMT_CH0_ERR_INT_ENA_S) +#define RMT_CH0_ERR_INT_ENA_V 0x00000001U +#define RMT_CH0_ERR_INT_ENA_S 2 +/** RMT_CH1_TX_END_INT_ENA : R/W; bitpos: [3]; default: 0; + * The interrupt enabled bit for RMT_CH1_TX_END_INT. + */ +#define RMT_CH1_TX_END_INT_ENA (BIT(3)) +#define RMT_CH1_TX_END_INT_ENA_M (RMT_CH1_TX_END_INT_ENA_V << RMT_CH1_TX_END_INT_ENA_S) +#define RMT_CH1_TX_END_INT_ENA_V 0x00000001U +#define RMT_CH1_TX_END_INT_ENA_S 3 +/** RMT_CH1_RX_END_INT_ENA : R/W; bitpos: [4]; default: 0; + * The interrupt enabled bit for RMT_CH1_RX_END_INT. + */ +#define RMT_CH1_RX_END_INT_ENA (BIT(4)) +#define RMT_CH1_RX_END_INT_ENA_M (RMT_CH1_RX_END_INT_ENA_V << RMT_CH1_RX_END_INT_ENA_S) +#define RMT_CH1_RX_END_INT_ENA_V 0x00000001U +#define RMT_CH1_RX_END_INT_ENA_S 4 +/** RMT_CH1_ERR_INT_ENA : R/W; bitpos: [5]; default: 0; + * The interrupt enabled bit for RMT_CH1_ERR_INT. + */ +#define RMT_CH1_ERR_INT_ENA (BIT(5)) +#define RMT_CH1_ERR_INT_ENA_M (RMT_CH1_ERR_INT_ENA_V << RMT_CH1_ERR_INT_ENA_S) +#define RMT_CH1_ERR_INT_ENA_V 0x00000001U +#define RMT_CH1_ERR_INT_ENA_S 5 +/** RMT_CH2_TX_END_INT_ENA : R/W; bitpos: [6]; default: 0; + * The interrupt enabled bit for RMT_CH2_TX_END_INT. + */ +#define RMT_CH2_TX_END_INT_ENA (BIT(6)) +#define RMT_CH2_TX_END_INT_ENA_M (RMT_CH2_TX_END_INT_ENA_V << RMT_CH2_TX_END_INT_ENA_S) +#define RMT_CH2_TX_END_INT_ENA_V 0x00000001U +#define RMT_CH2_TX_END_INT_ENA_S 6 +/** RMT_CH2_RX_END_INT_ENA : R/W; bitpos: [7]; default: 0; + * The interrupt enabled bit for RMT_CH2_RX_END_INT. + */ +#define RMT_CH2_RX_END_INT_ENA (BIT(7)) +#define RMT_CH2_RX_END_INT_ENA_M (RMT_CH2_RX_END_INT_ENA_V << RMT_CH2_RX_END_INT_ENA_S) +#define RMT_CH2_RX_END_INT_ENA_V 0x00000001U +#define RMT_CH2_RX_END_INT_ENA_S 7 +/** RMT_CH2_ERR_INT_ENA : R/W; bitpos: [8]; default: 0; + * The interrupt enabled bit for RMT_CH2_ERR_INT. + */ +#define RMT_CH2_ERR_INT_ENA (BIT(8)) +#define RMT_CH2_ERR_INT_ENA_M (RMT_CH2_ERR_INT_ENA_V << RMT_CH2_ERR_INT_ENA_S) +#define RMT_CH2_ERR_INT_ENA_V 0x00000001U +#define RMT_CH2_ERR_INT_ENA_S 8 +/** RMT_CH3_TX_END_INT_ENA : R/W; bitpos: [9]; default: 0; + * The interrupt enabled bit for RMT_CH3_TX_END_INT. + */ +#define RMT_CH3_TX_END_INT_ENA (BIT(9)) +#define RMT_CH3_TX_END_INT_ENA_M (RMT_CH3_TX_END_INT_ENA_V << RMT_CH3_TX_END_INT_ENA_S) +#define RMT_CH3_TX_END_INT_ENA_V 0x00000001U +#define RMT_CH3_TX_END_INT_ENA_S 9 +/** RMT_CH3_RX_END_INT_ENA : R/W; bitpos: [10]; default: 0; + * The interrupt enabled bit for RMT_CH3_RX_END_INT. + */ +#define RMT_CH3_RX_END_INT_ENA (BIT(10)) +#define RMT_CH3_RX_END_INT_ENA_M (RMT_CH3_RX_END_INT_ENA_V << RMT_CH3_RX_END_INT_ENA_S) +#define RMT_CH3_RX_END_INT_ENA_V 0x00000001U +#define RMT_CH3_RX_END_INT_ENA_S 10 +/** RMT_CH3_ERR_INT_ENA : R/W; bitpos: [11]; default: 0; + * The interrupt enabled bit for RMT_CH3_ERR_INT. + */ +#define RMT_CH3_ERR_INT_ENA (BIT(11)) +#define RMT_CH3_ERR_INT_ENA_M (RMT_CH3_ERR_INT_ENA_V << RMT_CH3_ERR_INT_ENA_S) +#define RMT_CH3_ERR_INT_ENA_V 0x00000001U +#define RMT_CH3_ERR_INT_ENA_S 11 +/** RMT_CH0_TX_THR_EVENT_INT_ENA : R/W; bitpos: [12]; default: 0; + * The interrupt enabled bit for RMT_CH0_TX_THR_EVENT_INT. + */ +#define RMT_CH0_TX_THR_EVENT_INT_ENA (BIT(12)) +#define RMT_CH0_TX_THR_EVENT_INT_ENA_M (RMT_CH0_TX_THR_EVENT_INT_ENA_V << RMT_CH0_TX_THR_EVENT_INT_ENA_S) +#define RMT_CH0_TX_THR_EVENT_INT_ENA_V 0x00000001U +#define RMT_CH0_TX_THR_EVENT_INT_ENA_S 12 +/** RMT_CH1_TX_THR_EVENT_INT_ENA : R/W; bitpos: [13]; default: 0; + * The interrupt enabled bit for RMT_CH1_TX_THR_EVENT_INT. + */ +#define RMT_CH1_TX_THR_EVENT_INT_ENA (BIT(13)) +#define RMT_CH1_TX_THR_EVENT_INT_ENA_M (RMT_CH1_TX_THR_EVENT_INT_ENA_V << RMT_CH1_TX_THR_EVENT_INT_ENA_S) +#define RMT_CH1_TX_THR_EVENT_INT_ENA_V 0x00000001U +#define RMT_CH1_TX_THR_EVENT_INT_ENA_S 13 +/** RMT_CH2_TX_THR_EVENT_INT_ENA : R/W; bitpos: [14]; default: 0; + * The interrupt enabled bit for RMT_CH2_TX_THR_EVENT_INT. + */ +#define RMT_CH2_TX_THR_EVENT_INT_ENA (BIT(14)) +#define RMT_CH2_TX_THR_EVENT_INT_ENA_M (RMT_CH2_TX_THR_EVENT_INT_ENA_V << RMT_CH2_TX_THR_EVENT_INT_ENA_S) +#define RMT_CH2_TX_THR_EVENT_INT_ENA_V 0x00000001U +#define RMT_CH2_TX_THR_EVENT_INT_ENA_S 14 +/** RMT_CH3_TX_THR_EVENT_INT_ENA : R/W; bitpos: [15]; default: 0; + * The interrupt enabled bit for RMT_CH3_TX_THR_EVENT_INT. + */ +#define RMT_CH3_TX_THR_EVENT_INT_ENA (BIT(15)) +#define RMT_CH3_TX_THR_EVENT_INT_ENA_M (RMT_CH3_TX_THR_EVENT_INT_ENA_V << RMT_CH3_TX_THR_EVENT_INT_ENA_S) +#define RMT_CH3_TX_THR_EVENT_INT_ENA_V 0x00000001U +#define RMT_CH3_TX_THR_EVENT_INT_ENA_S 15 +/** RMT_CH0_TX_LOOP_INT_ENA : R/W; bitpos: [16]; default: 0; + * The interrupt enabled bit for RMT_CH0_TX_LOOP_INT. + */ +#define RMT_CH0_TX_LOOP_INT_ENA (BIT(16)) +#define RMT_CH0_TX_LOOP_INT_ENA_M (RMT_CH0_TX_LOOP_INT_ENA_V << RMT_CH0_TX_LOOP_INT_ENA_S) +#define RMT_CH0_TX_LOOP_INT_ENA_V 0x00000001U +#define RMT_CH0_TX_LOOP_INT_ENA_S 16 +/** RMT_CH1_TX_LOOP_INT_ENA : R/W; bitpos: [17]; default: 0; + * The interrupt enabled bit for RMT_CH1_TX_LOOP_INT. + */ +#define RMT_CH1_TX_LOOP_INT_ENA (BIT(17)) +#define RMT_CH1_TX_LOOP_INT_ENA_M (RMT_CH1_TX_LOOP_INT_ENA_V << RMT_CH1_TX_LOOP_INT_ENA_S) +#define RMT_CH1_TX_LOOP_INT_ENA_V 0x00000001U +#define RMT_CH1_TX_LOOP_INT_ENA_S 17 +/** RMT_CH2_TX_LOOP_INT_ENA : R/W; bitpos: [18]; default: 0; + * The interrupt enabled bit for RMT_CH2_TX_LOOP_INT. + */ +#define RMT_CH2_TX_LOOP_INT_ENA (BIT(18)) +#define RMT_CH2_TX_LOOP_INT_ENA_M (RMT_CH2_TX_LOOP_INT_ENA_V << RMT_CH2_TX_LOOP_INT_ENA_S) +#define RMT_CH2_TX_LOOP_INT_ENA_V 0x00000001U +#define RMT_CH2_TX_LOOP_INT_ENA_S 18 +/** RMT_CH3_TX_LOOP_INT_ENA : R/W; bitpos: [19]; default: 0; + * The interrupt enabled bit for RMT_CH3_TX_LOOP_INT. + */ +#define RMT_CH3_TX_LOOP_INT_ENA (BIT(19)) +#define RMT_CH3_TX_LOOP_INT_ENA_M (RMT_CH3_TX_LOOP_INT_ENA_V << RMT_CH3_TX_LOOP_INT_ENA_S) +#define RMT_CH3_TX_LOOP_INT_ENA_V 0x00000001U +#define RMT_CH3_TX_LOOP_INT_ENA_S 19 -#define RMT_INT_CLR_REG (DR_REG_RMT_BASE + 0x005c) -/* RMT_CH3_RX_THR_EVENT_INT_CLR : WO ;bitpos:[23] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_THR_EVENT_INT_CLR (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_CLR_M (BIT(23)) -#define RMT_CH3_RX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH3_RX_THR_EVENT_INT_CLR_S 23 -/* RMT_CH2_RX_THR_EVENT_INT_CLR : WO ;bitpos:[22] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_THR_EVENT_INT_CLR (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_CLR_M (BIT(22)) -#define RMT_CH2_RX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH2_RX_THR_EVENT_INT_CLR_S 22 -/* RMT_CH1_RX_THR_EVENT_INT_CLR : WO ;bitpos:[21] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_THR_EVENT_INT_CLR (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_CLR_M (BIT(21)) -#define RMT_CH1_RX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH1_RX_THR_EVENT_INT_CLR_S 21 -/* RMT_CH0_RX_THR_EVENT_INT_CLR : WO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_THR_EVENT_INT_CLR (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_CLR_M (BIT(20)) -#define RMT_CH0_RX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH0_RX_THR_EVENT_INT_CLR_S 20 -/* RMT_CH3_TX_LOOP_INT_CLR : WO ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_LOOP_INT_CLR (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_CLR_M (BIT(19)) -#define RMT_CH3_TX_LOOP_INT_CLR_V 0x1 -#define RMT_CH3_TX_LOOP_INT_CLR_S 19 -/* RMT_CH2_TX_LOOP_INT_CLR : WO ;bitpos:[18] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_LOOP_INT_CLR (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_CLR_M (BIT(18)) -#define RMT_CH2_TX_LOOP_INT_CLR_V 0x1 -#define RMT_CH2_TX_LOOP_INT_CLR_S 18 -/* RMT_CH1_TX_LOOP_INT_CLR : WO ;bitpos:[17] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_LOOP_INT_CLR (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_CLR_M (BIT(17)) -#define RMT_CH1_TX_LOOP_INT_CLR_V 0x1 -#define RMT_CH1_TX_LOOP_INT_CLR_S 17 -/* RMT_CH0_TX_LOOP_INT_CLR : WO ;bitpos:[16] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_LOOP_INT_CLR (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_CLR_M (BIT(16)) -#define RMT_CH0_TX_LOOP_INT_CLR_V 0x1 -#define RMT_CH0_TX_LOOP_INT_CLR_S 16 -/* RMT_CH3_TX_THR_EVENT_INT_CLR : WO ;bitpos:[15] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_THR_EVENT_INT_CLR (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_CLR_M (BIT(15)) -#define RMT_CH3_TX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH3_TX_THR_EVENT_INT_CLR_S 15 -/* RMT_CH2_TX_THR_EVENT_INT_CLR : WO ;bitpos:[14] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_THR_EVENT_INT_CLR (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_CLR_M (BIT(14)) -#define RMT_CH2_TX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH2_TX_THR_EVENT_INT_CLR_S 14 -/* RMT_CH1_TX_THR_EVENT_INT_CLR : WO ;bitpos:[13] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_THR_EVENT_INT_CLR (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_CLR_M (BIT(13)) -#define RMT_CH1_TX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH1_TX_THR_EVENT_INT_CLR_S 13 -/* RMT_CH0_TX_THR_EVENT_INT_CLR : WO ;bitpos:[12] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_THR_EVENT_INT_CLR (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_CLR_M (BIT(12)) -#define RMT_CH0_TX_THR_EVENT_INT_CLR_V 0x1 -#define RMT_CH0_TX_THR_EVENT_INT_CLR_S 12 -/* RMT_CH3_ERR_INT_CLR : WO ;bitpos:[11] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_ERR_INT_CLR (BIT(11)) -#define RMT_CH3_ERR_INT_CLR_M (BIT(11)) -#define RMT_CH3_ERR_INT_CLR_V 0x1 -#define RMT_CH3_ERR_INT_CLR_S 11 -/* RMT_CH3_RX_END_INT_CLR : WO ;bitpos:[10] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_RX_END_INT_CLR (BIT(10)) -#define RMT_CH3_RX_END_INT_CLR_M (BIT(10)) -#define RMT_CH3_RX_END_INT_CLR_V 0x1 -#define RMT_CH3_RX_END_INT_CLR_S 10 -/* RMT_CH3_TX_END_INT_CLR : WO ;bitpos:[9] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH3_TX_END_INT_CLR (BIT(9)) -#define RMT_CH3_TX_END_INT_CLR_M (BIT(9)) -#define RMT_CH3_TX_END_INT_CLR_V 0x1 -#define RMT_CH3_TX_END_INT_CLR_S 9 -/* RMT_CH2_ERR_INT_CLR : WO ;bitpos:[8] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_ERR_INT_CLR (BIT(8)) -#define RMT_CH2_ERR_INT_CLR_M (BIT(8)) -#define RMT_CH2_ERR_INT_CLR_V 0x1 -#define RMT_CH2_ERR_INT_CLR_S 8 -/* RMT_CH2_RX_END_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_RX_END_INT_CLR (BIT(7)) -#define RMT_CH2_RX_END_INT_CLR_M (BIT(7)) -#define RMT_CH2_RX_END_INT_CLR_V 0x1 -#define RMT_CH2_RX_END_INT_CLR_S 7 -/* RMT_CH2_TX_END_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH2_TX_END_INT_CLR (BIT(6)) -#define RMT_CH2_TX_END_INT_CLR_M (BIT(6)) -#define RMT_CH2_TX_END_INT_CLR_V 0x1 -#define RMT_CH2_TX_END_INT_CLR_S 6 -/* RMT_CH1_ERR_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_ERR_INT_CLR (BIT(5)) -#define RMT_CH1_ERR_INT_CLR_M (BIT(5)) -#define RMT_CH1_ERR_INT_CLR_V 0x1 -#define RMT_CH1_ERR_INT_CLR_S 5 -/* RMT_CH1_RX_END_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_RX_END_INT_CLR (BIT(4)) -#define RMT_CH1_RX_END_INT_CLR_M (BIT(4)) -#define RMT_CH1_RX_END_INT_CLR_V 0x1 -#define RMT_CH1_RX_END_INT_CLR_S 4 -/* RMT_CH1_TX_END_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH1_TX_END_INT_CLR (BIT(3)) -#define RMT_CH1_TX_END_INT_CLR_M (BIT(3)) -#define RMT_CH1_TX_END_INT_CLR_V 0x1 -#define RMT_CH1_TX_END_INT_CLR_S 3 -/* RMT_CH0_ERR_INT_CLR : WO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_ERR_INT_CLR (BIT(2)) -#define RMT_CH0_ERR_INT_CLR_M (BIT(2)) -#define RMT_CH0_ERR_INT_CLR_V 0x1 -#define RMT_CH0_ERR_INT_CLR_S 2 -/* RMT_CH0_RX_END_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_RX_END_INT_CLR (BIT(1)) -#define RMT_CH0_RX_END_INT_CLR_M (BIT(1)) -#define RMT_CH0_RX_END_INT_CLR_V 0x1 -#define RMT_CH0_RX_END_INT_CLR_S 1 -/* RMT_CH0_TX_END_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ; */ -/*description: */ -#define RMT_CH0_TX_END_INT_CLR (BIT(0)) -#define RMT_CH0_TX_END_INT_CLR_M (BIT(0)) -#define RMT_CH0_TX_END_INT_CLR_V 0x1 +/** RMT_INT_CLR_REG register + * Interrupt clear register + */ +#define RMT_INT_CLR_REG (DR_REG_RMT_BASE + 0x5c) +/** RMT_CH0_TX_END_INT_CLR : WO; bitpos: [0]; default: 0; + * Set this bit to clear RMT_CH0_TX_END_INT interrupt. + */ +#define RMT_CH0_TX_END_INT_CLR (BIT(0)) +#define RMT_CH0_TX_END_INT_CLR_M (RMT_CH0_TX_END_INT_CLR_V << RMT_CH0_TX_END_INT_CLR_S) +#define RMT_CH0_TX_END_INT_CLR_V 0x00000001U #define RMT_CH0_TX_END_INT_CLR_S 0 +/** RMT_CH0_RX_END_INT_CLR : WO; bitpos: [1]; default: 0; + * Set this bit to clear RMT_CH0_RX_END_INT interrupt. + */ +#define RMT_CH0_RX_END_INT_CLR (BIT(1)) +#define RMT_CH0_RX_END_INT_CLR_M (RMT_CH0_RX_END_INT_CLR_V << RMT_CH0_RX_END_INT_CLR_S) +#define RMT_CH0_RX_END_INT_CLR_V 0x00000001U +#define RMT_CH0_RX_END_INT_CLR_S 1 +/** RMT_CH0_ERR_INT_CLR : WO; bitpos: [2]; default: 0; + * Set this bit to clear RMT_CH0_ERR_INT interrupt. + */ +#define RMT_CH0_ERR_INT_CLR (BIT(2)) +#define RMT_CH0_ERR_INT_CLR_M (RMT_CH0_ERR_INT_CLR_V << RMT_CH0_ERR_INT_CLR_S) +#define RMT_CH0_ERR_INT_CLR_V 0x00000001U +#define RMT_CH0_ERR_INT_CLR_S 2 +/** RMT_CH1_TX_END_INT_CLR : WO; bitpos: [3]; default: 0; + * Set this bit to clear RMT_CH1_TX_END_INT interrupt. + */ +#define RMT_CH1_TX_END_INT_CLR (BIT(3)) +#define RMT_CH1_TX_END_INT_CLR_M (RMT_CH1_TX_END_INT_CLR_V << RMT_CH1_TX_END_INT_CLR_S) +#define RMT_CH1_TX_END_INT_CLR_V 0x00000001U +#define RMT_CH1_TX_END_INT_CLR_S 3 +/** RMT_CH1_RX_END_INT_CLR : WO; bitpos: [4]; default: 0; + * Set this bit to clear RMT_CH1_RX_END_INT interrupt. + */ +#define RMT_CH1_RX_END_INT_CLR (BIT(4)) +#define RMT_CH1_RX_END_INT_CLR_M (RMT_CH1_RX_END_INT_CLR_V << RMT_CH1_RX_END_INT_CLR_S) +#define RMT_CH1_RX_END_INT_CLR_V 0x00000001U +#define RMT_CH1_RX_END_INT_CLR_S 4 +/** RMT_CH1_ERR_INT_CLR : WO; bitpos: [5]; default: 0; + * Set this bit to clear RMT_CH1_ERR_INT interrupt. + */ +#define RMT_CH1_ERR_INT_CLR (BIT(5)) +#define RMT_CH1_ERR_INT_CLR_M (RMT_CH1_ERR_INT_CLR_V << RMT_CH1_ERR_INT_CLR_S) +#define RMT_CH1_ERR_INT_CLR_V 0x00000001U +#define RMT_CH1_ERR_INT_CLR_S 5 +/** RMT_CH2_TX_END_INT_CLR : WO; bitpos: [6]; default: 0; + * Set this bit to clear RMT_CH2_TX_END_INT interrupt. + */ +#define RMT_CH2_TX_END_INT_CLR (BIT(6)) +#define RMT_CH2_TX_END_INT_CLR_M (RMT_CH2_TX_END_INT_CLR_V << RMT_CH2_TX_END_INT_CLR_S) +#define RMT_CH2_TX_END_INT_CLR_V 0x00000001U +#define RMT_CH2_TX_END_INT_CLR_S 6 +/** RMT_CH2_RX_END_INT_CLR : WO; bitpos: [7]; default: 0; + * Set this bit to clear RMT_CH2_RX_END_INT interrupt. + */ +#define RMT_CH2_RX_END_INT_CLR (BIT(7)) +#define RMT_CH2_RX_END_INT_CLR_M (RMT_CH2_RX_END_INT_CLR_V << RMT_CH2_RX_END_INT_CLR_S) +#define RMT_CH2_RX_END_INT_CLR_V 0x00000001U +#define RMT_CH2_RX_END_INT_CLR_S 7 +/** RMT_CH2_ERR_INT_CLR : WO; bitpos: [8]; default: 0; + * Set this bit to clear RMT_CH2_ERR_INT interrupt. + */ +#define RMT_CH2_ERR_INT_CLR (BIT(8)) +#define RMT_CH2_ERR_INT_CLR_M (RMT_CH2_ERR_INT_CLR_V << RMT_CH2_ERR_INT_CLR_S) +#define RMT_CH2_ERR_INT_CLR_V 0x00000001U +#define RMT_CH2_ERR_INT_CLR_S 8 +/** RMT_CH3_TX_END_INT_CLR : WO; bitpos: [9]; default: 0; + * Set this bit to clear RMT_CH3_TX_END_INT interrupt. + */ +#define RMT_CH3_TX_END_INT_CLR (BIT(9)) +#define RMT_CH3_TX_END_INT_CLR_M (RMT_CH3_TX_END_INT_CLR_V << RMT_CH3_TX_END_INT_CLR_S) +#define RMT_CH3_TX_END_INT_CLR_V 0x00000001U +#define RMT_CH3_TX_END_INT_CLR_S 9 +/** RMT_CH3_RX_END_INT_CLR : WO; bitpos: [10]; default: 0; + * Set this bit to clear RMT_CH3_RX_END_INT interrupt. + */ +#define RMT_CH3_RX_END_INT_CLR (BIT(10)) +#define RMT_CH3_RX_END_INT_CLR_M (RMT_CH3_RX_END_INT_CLR_V << RMT_CH3_RX_END_INT_CLR_S) +#define RMT_CH3_RX_END_INT_CLR_V 0x00000001U +#define RMT_CH3_RX_END_INT_CLR_S 10 +/** RMT_CH3_ERR_INT_CLR : WO; bitpos: [11]; default: 0; + * Set this bit to clear RMT_CH3_ERR_INT interrupt. + */ +#define RMT_CH3_ERR_INT_CLR (BIT(11)) +#define RMT_CH3_ERR_INT_CLR_M (RMT_CH3_ERR_INT_CLR_V << RMT_CH3_ERR_INT_CLR_S) +#define RMT_CH3_ERR_INT_CLR_V 0x00000001U +#define RMT_CH3_ERR_INT_CLR_S 11 +/** RMT_CH0_TX_THR_EVENT_INT_CLR : WO; bitpos: [12]; default: 0; + * Set this bit to clear RMT_CH0_TX_THR_EVENT_INT interrupt. + */ +#define RMT_CH0_TX_THR_EVENT_INT_CLR (BIT(12)) +#define RMT_CH0_TX_THR_EVENT_INT_CLR_M (RMT_CH0_TX_THR_EVENT_INT_CLR_V << RMT_CH0_TX_THR_EVENT_INT_CLR_S) +#define RMT_CH0_TX_THR_EVENT_INT_CLR_V 0x00000001U +#define RMT_CH0_TX_THR_EVENT_INT_CLR_S 12 +/** RMT_CH1_TX_THR_EVENT_INT_CLR : WO; bitpos: [13]; default: 0; + * Set this bit to clear RMT_CH1_TX_THR_EVENT_INT interrupt. + */ +#define RMT_CH1_TX_THR_EVENT_INT_CLR (BIT(13)) +#define RMT_CH1_TX_THR_EVENT_INT_CLR_M (RMT_CH1_TX_THR_EVENT_INT_CLR_V << RMT_CH1_TX_THR_EVENT_INT_CLR_S) +#define RMT_CH1_TX_THR_EVENT_INT_CLR_V 0x00000001U +#define RMT_CH1_TX_THR_EVENT_INT_CLR_S 13 +/** RMT_CH2_TX_THR_EVENT_INT_CLR : WO; bitpos: [14]; default: 0; + * Set this bit to clear RMT_CH2_TX_THR_EVENT_INT interrupt. + */ +#define RMT_CH2_TX_THR_EVENT_INT_CLR (BIT(14)) +#define RMT_CH2_TX_THR_EVENT_INT_CLR_M (RMT_CH2_TX_THR_EVENT_INT_CLR_V << RMT_CH2_TX_THR_EVENT_INT_CLR_S) +#define RMT_CH2_TX_THR_EVENT_INT_CLR_V 0x00000001U +#define RMT_CH2_TX_THR_EVENT_INT_CLR_S 14 +/** RMT_CH3_TX_THR_EVENT_INT_CLR : WO; bitpos: [15]; default: 0; + * Set this bit to clear RMT_CH3_TX_THR_EVENT_INT interrupt. + */ +#define RMT_CH3_TX_THR_EVENT_INT_CLR (BIT(15)) +#define RMT_CH3_TX_THR_EVENT_INT_CLR_M (RMT_CH3_TX_THR_EVENT_INT_CLR_V << RMT_CH3_TX_THR_EVENT_INT_CLR_S) +#define RMT_CH3_TX_THR_EVENT_INT_CLR_V 0x00000001U +#define RMT_CH3_TX_THR_EVENT_INT_CLR_S 15 +/** RMT_CH0_TX_LOOP_INT_CLR : WO; bitpos: [16]; default: 0; + * Set this bit to clear RMT_CH0_TX_LOOP_INT interrupt. + */ +#define RMT_CH0_TX_LOOP_INT_CLR (BIT(16)) +#define RMT_CH0_TX_LOOP_INT_CLR_M (RMT_CH0_TX_LOOP_INT_CLR_V << RMT_CH0_TX_LOOP_INT_CLR_S) +#define RMT_CH0_TX_LOOP_INT_CLR_V 0x00000001U +#define RMT_CH0_TX_LOOP_INT_CLR_S 16 +/** RMT_CH1_TX_LOOP_INT_CLR : WO; bitpos: [17]; default: 0; + * Set this bit to clear RMT_CH1_TX_LOOP_INT interrupt. + */ +#define RMT_CH1_TX_LOOP_INT_CLR (BIT(17)) +#define RMT_CH1_TX_LOOP_INT_CLR_M (RMT_CH1_TX_LOOP_INT_CLR_V << RMT_CH1_TX_LOOP_INT_CLR_S) +#define RMT_CH1_TX_LOOP_INT_CLR_V 0x00000001U +#define RMT_CH1_TX_LOOP_INT_CLR_S 17 +/** RMT_CH2_TX_LOOP_INT_CLR : WO; bitpos: [18]; default: 0; + * Set this bit to clear RMT_CH2_TX_LOOP_INT interrupt. + */ +#define RMT_CH2_TX_LOOP_INT_CLR (BIT(18)) +#define RMT_CH2_TX_LOOP_INT_CLR_M (RMT_CH2_TX_LOOP_INT_CLR_V << RMT_CH2_TX_LOOP_INT_CLR_S) +#define RMT_CH2_TX_LOOP_INT_CLR_V 0x00000001U +#define RMT_CH2_TX_LOOP_INT_CLR_S 18 +/** RMT_CH3_TX_LOOP_INT_CLR : WO; bitpos: [19]; default: 0; + * Set this bit to clear RMT_CH3_TX_LOOP_INT interrupt. + */ +#define RMT_CH3_TX_LOOP_INT_CLR (BIT(19)) +#define RMT_CH3_TX_LOOP_INT_CLR_M (RMT_CH3_TX_LOOP_INT_CLR_V << RMT_CH3_TX_LOOP_INT_CLR_S) +#define RMT_CH3_TX_LOOP_INT_CLR_V 0x00000001U +#define RMT_CH3_TX_LOOP_INT_CLR_S 19 -#define RMT_CH0CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x0060) -/* RMT_CARRIER_HIGH_CH0 : R/W ;bitpos:[31:16] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_CH0 0x0000FFFF -#define RMT_CARRIER_HIGH_CH0_M ((RMT_CARRIER_HIGH_CH0_V)<<(RMT_CARRIER_HIGH_CH0_S)) -#define RMT_CARRIER_HIGH_CH0_V 0xFFFF -#define RMT_CARRIER_HIGH_CH0_S 16 -/* RMT_CARRIER_LOW_CH0 : R/W ;bitpos:[15:0] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_LOW_CH0 0x0000FFFF -#define RMT_CARRIER_LOW_CH0_M ((RMT_CARRIER_LOW_CH0_V)<<(RMT_CARRIER_LOW_CH0_S)) -#define RMT_CARRIER_LOW_CH0_V 0xFFFF +/** RMT_CH0CARRIER_DUTY_REG register + * Channel 0 duty cycle configuration register + */ +#define RMT_CH0CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x60) +/** RMT_CARRIER_LOW_CH0 : R/W; bitpos: [15:0]; default: 64; + * This field is used to configure the clock cycles of carrier wave at low level for + * channel 0. + */ +#define RMT_CARRIER_LOW_CH0 0x0000FFFFU +#define RMT_CARRIER_LOW_CH0_M (RMT_CARRIER_LOW_CH0_V << RMT_CARRIER_LOW_CH0_S) +#define RMT_CARRIER_LOW_CH0_V 0x0000FFFFU #define RMT_CARRIER_LOW_CH0_S 0 +/** RMT_CARRIER_HIGH_CH0 : R/W; bitpos: [31:16]; default: 64; + * This field is used to configure the clock cycles of carrier wave at high level for + * channel 0. + */ +#define RMT_CARRIER_HIGH_CH0 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH0_M (RMT_CARRIER_HIGH_CH0_V << RMT_CARRIER_HIGH_CH0_S) +#define RMT_CARRIER_HIGH_CH0_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH0_S 16 -#define RMT_CH1CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x0064) -/* RMT_CARRIER_HIGH_CH1 : R/W ;bitpos:[31:16] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_CH1 0x0000FFFF -#define RMT_CARRIER_HIGH_CH1_M ((RMT_CARRIER_HIGH_CH1_V)<<(RMT_CARRIER_HIGH_CH1_S)) -#define RMT_CARRIER_HIGH_CH1_V 0xFFFF -#define RMT_CARRIER_HIGH_CH1_S 16 -/* RMT_CARRIER_LOW_CH1 : R/W ;bitpos:[15:0] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_LOW_CH1 0x0000FFFF -#define RMT_CARRIER_LOW_CH1_M ((RMT_CARRIER_LOW_CH1_V)<<(RMT_CARRIER_LOW_CH1_S)) -#define RMT_CARRIER_LOW_CH1_V 0xFFFF +/** RMT_CH1CARRIER_DUTY_REG register + * Channel 1 duty cycle configuration register + */ +#define RMT_CH1CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x64) +/** RMT_CARRIER_LOW_CH1 : R/W; bitpos: [15:0]; default: 64; + * This field is used to configure the clock cycles of carrier wave at low level for + * channel 1. + */ +#define RMT_CARRIER_LOW_CH1 0x0000FFFFU +#define RMT_CARRIER_LOW_CH1_M (RMT_CARRIER_LOW_CH1_V << RMT_CARRIER_LOW_CH1_S) +#define RMT_CARRIER_LOW_CH1_V 0x0000FFFFU #define RMT_CARRIER_LOW_CH1_S 0 +/** RMT_CARRIER_HIGH_CH1 : R/W; bitpos: [31:16]; default: 64; + * This field is used to configure the clock cycles of carrier wave at high level for + * channel 1. + */ +#define RMT_CARRIER_HIGH_CH1 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH1_M (RMT_CARRIER_HIGH_CH1_V << RMT_CARRIER_HIGH_CH1_S) +#define RMT_CARRIER_HIGH_CH1_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH1_S 16 -#define RMT_CH2CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x0068) -/* RMT_CARRIER_HIGH_CH2 : R/W ;bitpos:[31:16] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_CH2 0x0000FFFF -#define RMT_CARRIER_HIGH_CH2_M ((RMT_CARRIER_HIGH_CH2_V)<<(RMT_CARRIER_HIGH_CH2_S)) -#define RMT_CARRIER_HIGH_CH2_V 0xFFFF -#define RMT_CARRIER_HIGH_CH2_S 16 -/* RMT_CARRIER_LOW_CH2 : R/W ;bitpos:[15:0] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_LOW_CH2 0x0000FFFF -#define RMT_CARRIER_LOW_CH2_M ((RMT_CARRIER_LOW_CH2_V)<<(RMT_CARRIER_LOW_CH2_S)) -#define RMT_CARRIER_LOW_CH2_V 0xFFFF +/** RMT_CH2CARRIER_DUTY_REG register + * Channel 2 duty cycle configuration register + */ +#define RMT_CH2CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x68) +/** RMT_CARRIER_LOW_CH2 : R/W; bitpos: [15:0]; default: 64; + * This field is used to configure the clock cycles of carrier wave at low level for + * channel 2. + */ +#define RMT_CARRIER_LOW_CH2 0x0000FFFFU +#define RMT_CARRIER_LOW_CH2_M (RMT_CARRIER_LOW_CH2_V << RMT_CARRIER_LOW_CH2_S) +#define RMT_CARRIER_LOW_CH2_V 0x0000FFFFU #define RMT_CARRIER_LOW_CH2_S 0 +/** RMT_CARRIER_HIGH_CH2 : R/W; bitpos: [31:16]; default: 64; + * This field is used to configure the clock cycles of carrier wave at high level for + * channel 2. + */ +#define RMT_CARRIER_HIGH_CH2 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH2_M (RMT_CARRIER_HIGH_CH2_V << RMT_CARRIER_HIGH_CH2_S) +#define RMT_CARRIER_HIGH_CH2_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH2_S 16 -#define RMT_CH3CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x006c) -/* RMT_CARRIER_HIGH_CH3 : R/W ;bitpos:[31:16] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_CH3 0x0000FFFF -#define RMT_CARRIER_HIGH_CH3_M ((RMT_CARRIER_HIGH_CH3_V)<<(RMT_CARRIER_HIGH_CH3_S)) -#define RMT_CARRIER_HIGH_CH3_V 0xFFFF -#define RMT_CARRIER_HIGH_CH3_S 16 -/* RMT_CARRIER_LOW_CH3 : R/W ;bitpos:[15:0] ;default: 16'h40 ; */ -/*description: */ -#define RMT_CARRIER_LOW_CH3 0x0000FFFF -#define RMT_CARRIER_LOW_CH3_M ((RMT_CARRIER_LOW_CH3_V)<<(RMT_CARRIER_LOW_CH3_S)) -#define RMT_CARRIER_LOW_CH3_V 0xFFFF +/** RMT_CH3CARRIER_DUTY_REG register + * Channel 3 duty cycle configuration register + */ +#define RMT_CH3CARRIER_DUTY_REG (DR_REG_RMT_BASE + 0x6c) +/** RMT_CARRIER_LOW_CH3 : R/W; bitpos: [15:0]; default: 64; + * This field is used to configure the clock cycles of carrier wave at low level for + * channel 3. + */ +#define RMT_CARRIER_LOW_CH3 0x0000FFFFU +#define RMT_CARRIER_LOW_CH3_M (RMT_CARRIER_LOW_CH3_V << RMT_CARRIER_LOW_CH3_S) +#define RMT_CARRIER_LOW_CH3_V 0x0000FFFFU #define RMT_CARRIER_LOW_CH3_S 0 +/** RMT_CARRIER_HIGH_CH3 : R/W; bitpos: [31:16]; default: 64; + * This field is used to configure the clock cycles of carrier wave at high level for + * channel 3. + */ +#define RMT_CARRIER_HIGH_CH3 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH3_M (RMT_CARRIER_HIGH_CH3_V << RMT_CARRIER_HIGH_CH3_S) +#define RMT_CARRIER_HIGH_CH3_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_CH3_S 16 -#define RMT_CH0_TX_LIM_REG (DR_REG_RMT_BASE + 0x0070) -/* RMT_RX_LIM_CH0 : R/W ;bitpos:[29:21] ;default: 9'h80 ; */ -/*description: */ -#define RMT_RX_LIM_CH0 0x000001FF -#define RMT_RX_LIM_CH0_M ((RMT_RX_LIM_CH0_V)<<(RMT_RX_LIM_CH0_S)) -#define RMT_RX_LIM_CH0_V 0x1FF -#define RMT_RX_LIM_CH0_S 21 -/* RMT_LOOP_COUNT_RESET_CH0 : WO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_LOOP_COUNT_RESET_CH0 (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH0_M (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH0_V 0x1 -#define RMT_LOOP_COUNT_RESET_CH0_S 20 -/* RMT_TX_LOOP_CNT_EN_CH0 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_CNT_EN_CH0 (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH0_M (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH0_V 0x1 -#define RMT_TX_LOOP_CNT_EN_CH0_S 19 -/* RMT_TX_LOOP_NUM_CH0 : R/W ;bitpos:[18:9] ;default: 10'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_NUM_CH0 0x000003FF -#define RMT_TX_LOOP_NUM_CH0_M ((RMT_TX_LOOP_NUM_CH0_V)<<(RMT_TX_LOOP_NUM_CH0_S)) -#define RMT_TX_LOOP_NUM_CH0_V 0x3FF -#define RMT_TX_LOOP_NUM_CH0_S 9 -/* RMT_TX_LIM_CH0 : R/W ;bitpos:[8:0] ;default: 9'h80 ; */ -/*description: */ -#define RMT_TX_LIM_CH0 0x000001FF -#define RMT_TX_LIM_CH0_M ((RMT_TX_LIM_CH0_V)<<(RMT_TX_LIM_CH0_S)) -#define RMT_TX_LIM_CH0_V 0x1FF +/** RMT_CH0_TX_LIM_REG register + * Channel 0 Tx event configuration register + */ +#define RMT_CH0_TX_LIM_REG (DR_REG_RMT_BASE + 0x70) +/** RMT_TX_LIM_CH0 : R/W; bitpos: [8:0]; default: 128; + * This field is used to configure the maximum entries that channel 0 can send out. + * When RMT_MEM_SIZE_CH0 = 1, this field can be set to any value among 0 ~ 128 + * (64*32/16 = 128). When RMT_MEM_SIZE_CH0 > 1, this field can be set to any value + * among (0 ~ 128)*RMT_MEM_SIZE_CH0. + */ +#define RMT_TX_LIM_CH0 0x000001FFU +#define RMT_TX_LIM_CH0_M (RMT_TX_LIM_CH0_V << RMT_TX_LIM_CH0_S) +#define RMT_TX_LIM_CH0_V 0x000001FFU #define RMT_TX_LIM_CH0_S 0 +/** RMT_TX_LOOP_NUM_CH0 : R/W; bitpos: [18:9]; default: 0; + * This field is used to configure the maximum loop times when continuous transmission + * mode is enabled. + */ +#define RMT_TX_LOOP_NUM_CH0 0x000003FFU +#define RMT_TX_LOOP_NUM_CH0_M (RMT_TX_LOOP_NUM_CH0_V << RMT_TX_LOOP_NUM_CH0_S) +#define RMT_TX_LOOP_NUM_CH0_V 0x000003FFU +#define RMT_TX_LOOP_NUM_CH0_S 9 +/** RMT_TX_LOOP_CNT_EN_CH0 : R/W; bitpos: [19]; default: 0; + * This bit is used to enable loop counting. + */ +#define RMT_TX_LOOP_CNT_EN_CH0 (BIT(19)) +#define RMT_TX_LOOP_CNT_EN_CH0_M (RMT_TX_LOOP_CNT_EN_CH0_V << RMT_TX_LOOP_CNT_EN_CH0_S) +#define RMT_TX_LOOP_CNT_EN_CH0_V 0x00000001U +#define RMT_TX_LOOP_CNT_EN_CH0_S 19 +/** RMT_LOOP_COUNT_RESET_CH0 : WO; bitpos: [20]; default: 0; + * This bit is used to reset loop counting when continuous transmission mode is valid. + */ +#define RMT_LOOP_COUNT_RESET_CH0 (BIT(20)) +#define RMT_LOOP_COUNT_RESET_CH0_M (RMT_LOOP_COUNT_RESET_CH0_V << RMT_LOOP_COUNT_RESET_CH0_S) +#define RMT_LOOP_COUNT_RESET_CH0_V 0x00000001U +#define RMT_LOOP_COUNT_RESET_CH0_S 20 -#define RMT_CH1_TX_LIM_REG (DR_REG_RMT_BASE + 0x0074) -/* RMT_RX_LIM_CH1 : R/W ;bitpos:[29:21] ;default: 9'h80 ; */ -/*description: */ -#define RMT_RX_LIM_CH1 0x000001FF -#define RMT_RX_LIM_CH1_M ((RMT_RX_LIM_CH1_V)<<(RMT_RX_LIM_CH1_S)) -#define RMT_RX_LIM_CH1_V 0x1FF -#define RMT_RX_LIM_CH1_S 21 -/* RMT_LOOP_COUNT_RESET_CH1 : WO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_LOOP_COUNT_RESET_CH1 (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH1_M (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH1_V 0x1 -#define RMT_LOOP_COUNT_RESET_CH1_S 20 -/* RMT_TX_LOOP_CNT_EN_CH1 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_CNT_EN_CH1 (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH1_M (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH1_V 0x1 -#define RMT_TX_LOOP_CNT_EN_CH1_S 19 -/* RMT_TX_LOOP_NUM_CH1 : R/W ;bitpos:[18:9] ;default: 10'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_NUM_CH1 0x000003FF -#define RMT_TX_LOOP_NUM_CH1_M ((RMT_TX_LOOP_NUM_CH1_V)<<(RMT_TX_LOOP_NUM_CH1_S)) -#define RMT_TX_LOOP_NUM_CH1_V 0x3FF -#define RMT_TX_LOOP_NUM_CH1_S 9 -/* RMT_TX_LIM_CH1 : R/W ;bitpos:[8:0] ;default: 9'h80 ; */ -/*description: */ -#define RMT_TX_LIM_CH1 0x000001FF -#define RMT_TX_LIM_CH1_M ((RMT_TX_LIM_CH1_V)<<(RMT_TX_LIM_CH1_S)) -#define RMT_TX_LIM_CH1_V 0x1FF +/** RMT_CH1_TX_LIM_REG register + * Channel 1 Tx event configuration register + */ +#define RMT_CH1_TX_LIM_REG (DR_REG_RMT_BASE + 0x74) +/** RMT_TX_LIM_CH1 : R/W; bitpos: [8:0]; default: 128; + * This field is used to configure the maximum entries that channel 1 can send out. + * When RMT_MEM_SIZE_CH1 = 1, this field can be set to any value among 0 ~ 128 + * (64*32/16 = 128). When RMT_MEM_SIZE_CH1 > 1, this field can be set to any value + * among (0 ~ 128)*RMT_MEM_SIZE_CH1. + */ +#define RMT_TX_LIM_CH1 0x000001FFU +#define RMT_TX_LIM_CH1_M (RMT_TX_LIM_CH1_V << RMT_TX_LIM_CH1_S) +#define RMT_TX_LIM_CH1_V 0x000001FFU #define RMT_TX_LIM_CH1_S 0 +/** RMT_TX_LOOP_NUM_CH1 : R/W; bitpos: [18:9]; default: 0; + * This field is used to configure the maximum loop times when continuous transmission + * mode is enabled. + */ +#define RMT_TX_LOOP_NUM_CH1 0x000003FFU +#define RMT_TX_LOOP_NUM_CH1_M (RMT_TX_LOOP_NUM_CH1_V << RMT_TX_LOOP_NUM_CH1_S) +#define RMT_TX_LOOP_NUM_CH1_V 0x000003FFU +#define RMT_TX_LOOP_NUM_CH1_S 9 +/** RMT_TX_LOOP_CNT_EN_CH1 : R/W; bitpos: [19]; default: 0; + * This bit is used to enable loop counting. + */ +#define RMT_TX_LOOP_CNT_EN_CH1 (BIT(19)) +#define RMT_TX_LOOP_CNT_EN_CH1_M (RMT_TX_LOOP_CNT_EN_CH1_V << RMT_TX_LOOP_CNT_EN_CH1_S) +#define RMT_TX_LOOP_CNT_EN_CH1_V 0x00000001U +#define RMT_TX_LOOP_CNT_EN_CH1_S 19 +/** RMT_LOOP_COUNT_RESET_CH1 : WO; bitpos: [20]; default: 0; + * This bit is used to reset loop counting when continuous transmission mode is valid. + */ +#define RMT_LOOP_COUNT_RESET_CH1 (BIT(20)) +#define RMT_LOOP_COUNT_RESET_CH1_M (RMT_LOOP_COUNT_RESET_CH1_V << RMT_LOOP_COUNT_RESET_CH1_S) +#define RMT_LOOP_COUNT_RESET_CH1_V 0x00000001U +#define RMT_LOOP_COUNT_RESET_CH1_S 20 -#define RMT_CH2_TX_LIM_REG (DR_REG_RMT_BASE + 0x0078) -/* RMT_RX_LIM_CH2 : R/W ;bitpos:[29:21] ;default: 9'h80 ; */ -/*description: */ -#define RMT_RX_LIM_CH2 0x000001FF -#define RMT_RX_LIM_CH2_M ((RMT_RX_LIM_CH2_V)<<(RMT_RX_LIM_CH2_S)) -#define RMT_RX_LIM_CH2_V 0x1FF -#define RMT_RX_LIM_CH2_S 21 -/* RMT_LOOP_COUNT_RESET_CH2 : WO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_LOOP_COUNT_RESET_CH2 (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH2_M (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH2_V 0x1 -#define RMT_LOOP_COUNT_RESET_CH2_S 20 -/* RMT_TX_LOOP_CNT_EN_CH2 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_CNT_EN_CH2 (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH2_M (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH2_V 0x1 -#define RMT_TX_LOOP_CNT_EN_CH2_S 19 -/* RMT_TX_LOOP_NUM_CH2 : R/W ;bitpos:[18:9] ;default: 10'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_NUM_CH2 0x000003FF -#define RMT_TX_LOOP_NUM_CH2_M ((RMT_TX_LOOP_NUM_CH2_V)<<(RMT_TX_LOOP_NUM_CH2_S)) -#define RMT_TX_LOOP_NUM_CH2_V 0x3FF -#define RMT_TX_LOOP_NUM_CH2_S 9 -/* RMT_TX_LIM_CH2 : R/W ;bitpos:[8:0] ;default: 9'h80 ; */ -/*description: */ -#define RMT_TX_LIM_CH2 0x000001FF -#define RMT_TX_LIM_CH2_M ((RMT_TX_LIM_CH2_V)<<(RMT_TX_LIM_CH2_S)) -#define RMT_TX_LIM_CH2_V 0x1FF +/** RMT_CH2_TX_LIM_REG register + * Channel 2 Tx event configuration register + */ +#define RMT_CH2_TX_LIM_REG (DR_REG_RMT_BASE + 0x78) +/** RMT_TX_LIM_CH2 : R/W; bitpos: [8:0]; default: 128; + * This field is used to configure the maximum entries that channel 2 can send out. + * When RMT_MEM_SIZE_CH2 = 1, this field can be set to any value among 0 ~ 128 + * (64*32/16 = 128). When RMT_MEM_SIZE_CH2 > 1, this field can be set to any value + * among (0 ~ 128)*RMT_MEM_SIZE_CH2. + */ +#define RMT_TX_LIM_CH2 0x000001FFU +#define RMT_TX_LIM_CH2_M (RMT_TX_LIM_CH2_V << RMT_TX_LIM_CH2_S) +#define RMT_TX_LIM_CH2_V 0x000001FFU #define RMT_TX_LIM_CH2_S 0 +/** RMT_TX_LOOP_NUM_CH2 : R/W; bitpos: [18:9]; default: 0; + * This field is used to configure the maximum loop times when continuous transmission + * mode is enabled. + */ +#define RMT_TX_LOOP_NUM_CH2 0x000003FFU +#define RMT_TX_LOOP_NUM_CH2_M (RMT_TX_LOOP_NUM_CH2_V << RMT_TX_LOOP_NUM_CH2_S) +#define RMT_TX_LOOP_NUM_CH2_V 0x000003FFU +#define RMT_TX_LOOP_NUM_CH2_S 9 +/** RMT_TX_LOOP_CNT_EN_CH2 : R/W; bitpos: [19]; default: 0; + * This bit is used to enable loop counting. + */ +#define RMT_TX_LOOP_CNT_EN_CH2 (BIT(19)) +#define RMT_TX_LOOP_CNT_EN_CH2_M (RMT_TX_LOOP_CNT_EN_CH2_V << RMT_TX_LOOP_CNT_EN_CH2_S) +#define RMT_TX_LOOP_CNT_EN_CH2_V 0x00000001U +#define RMT_TX_LOOP_CNT_EN_CH2_S 19 +/** RMT_LOOP_COUNT_RESET_CH2 : WO; bitpos: [20]; default: 0; + * This bit is used to reset loop counting when continuous transmission mode is valid. + */ +#define RMT_LOOP_COUNT_RESET_CH2 (BIT(20)) +#define RMT_LOOP_COUNT_RESET_CH2_M (RMT_LOOP_COUNT_RESET_CH2_V << RMT_LOOP_COUNT_RESET_CH2_S) +#define RMT_LOOP_COUNT_RESET_CH2_V 0x00000001U +#define RMT_LOOP_COUNT_RESET_CH2_S 20 -#define RMT_CH3_TX_LIM_REG (DR_REG_RMT_BASE + 0x007c) -/* RMT_RX_LIM_CH3 : R/W ;bitpos:[29:21] ;default: 9'h80 ; */ -/*description: */ -#define RMT_RX_LIM_CH3 0x000001FF -#define RMT_RX_LIM_CH3_M ((RMT_RX_LIM_CH3_V)<<(RMT_RX_LIM_CH3_S)) -#define RMT_RX_LIM_CH3_V 0x1FF -#define RMT_RX_LIM_CH3_S 21 -/* RMT_LOOP_COUNT_RESET_CH3 : WO ;bitpos:[20] ;default: 1'b0 ; */ -/*description: */ -#define RMT_LOOP_COUNT_RESET_CH3 (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH3_M (BIT(20)) -#define RMT_LOOP_COUNT_RESET_CH3_V 0x1 -#define RMT_LOOP_COUNT_RESET_CH3_S 20 -/* RMT_TX_LOOP_CNT_EN_CH3 : R/W ;bitpos:[19] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_CNT_EN_CH3 (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH3_M (BIT(19)) -#define RMT_TX_LOOP_CNT_EN_CH3_V 0x1 -#define RMT_TX_LOOP_CNT_EN_CH3_S 19 -/* RMT_TX_LOOP_NUM_CH3 : R/W ;bitpos:[18:9] ;default: 10'b0 ; */ -/*description: */ -#define RMT_TX_LOOP_NUM_CH3 0x000003FF -#define RMT_TX_LOOP_NUM_CH3_M ((RMT_TX_LOOP_NUM_CH3_V)<<(RMT_TX_LOOP_NUM_CH3_S)) -#define RMT_TX_LOOP_NUM_CH3_V 0x3FF -#define RMT_TX_LOOP_NUM_CH3_S 9 -/* RMT_TX_LIM_CH3 : R/W ;bitpos:[8:0] ;default: 9'h80 ; */ -/*description: */ -#define RMT_TX_LIM_CH3 0x000001FF -#define RMT_TX_LIM_CH3_M ((RMT_TX_LIM_CH3_V)<<(RMT_TX_LIM_CH3_S)) -#define RMT_TX_LIM_CH3_V 0x1FF +/** RMT_CH3_TX_LIM_REG register + * Channel 3 Tx event configuration register + */ +#define RMT_CH3_TX_LIM_REG (DR_REG_RMT_BASE + 0x7c) +/** RMT_TX_LIM_CH3 : R/W; bitpos: [8:0]; default: 128; + * This field is used to configure the maximum entries that channel 3 can send out. + * When RMT_MEM_SIZE_CH3 = 1, this field can be set to any value among 0 ~ 128 + * (64*32/16 = 128). When RMT_MEM_SIZE_CH3 > 1, this field can be set to any value + * among (0 ~ 128)*RMT_MEM_SIZE_CH3. + */ +#define RMT_TX_LIM_CH3 0x000001FFU +#define RMT_TX_LIM_CH3_M (RMT_TX_LIM_CH3_V << RMT_TX_LIM_CH3_S) +#define RMT_TX_LIM_CH3_V 0x000001FFU #define RMT_TX_LIM_CH3_S 0 +/** RMT_TX_LOOP_NUM_CH3 : R/W; bitpos: [18:9]; default: 0; + * This field is used to configure the maximum loop times when continuous transmission + * mode is enabled. + */ +#define RMT_TX_LOOP_NUM_CH3 0x000003FFU +#define RMT_TX_LOOP_NUM_CH3_M (RMT_TX_LOOP_NUM_CH3_V << RMT_TX_LOOP_NUM_CH3_S) +#define RMT_TX_LOOP_NUM_CH3_V 0x000003FFU +#define RMT_TX_LOOP_NUM_CH3_S 9 +/** RMT_TX_LOOP_CNT_EN_CH3 : R/W; bitpos: [19]; default: 0; + * This bit is used to enable loop counting. + */ +#define RMT_TX_LOOP_CNT_EN_CH3 (BIT(19)) +#define RMT_TX_LOOP_CNT_EN_CH3_M (RMT_TX_LOOP_CNT_EN_CH3_V << RMT_TX_LOOP_CNT_EN_CH3_S) +#define RMT_TX_LOOP_CNT_EN_CH3_V 0x00000001U +#define RMT_TX_LOOP_CNT_EN_CH3_S 19 +/** RMT_LOOP_COUNT_RESET_CH3 : WO; bitpos: [20]; default: 0; + * This bit is used to reset loop counting when continuous transmission mode is valid. + */ +#define RMT_LOOP_COUNT_RESET_CH3 (BIT(20)) +#define RMT_LOOP_COUNT_RESET_CH3_M (RMT_LOOP_COUNT_RESET_CH3_V << RMT_LOOP_COUNT_RESET_CH3_S) +#define RMT_LOOP_COUNT_RESET_CH3_V 0x00000001U +#define RMT_LOOP_COUNT_RESET_CH3_S 20 -#define RMT_APB_CONF_REG (DR_REG_RMT_BASE + 0x0080) -/* RMT_CLK_EN : R/W ;bitpos:[31] ;default: 1'h0 ; */ -/*description: */ -#define RMT_CLK_EN (BIT(31)) -#define RMT_CLK_EN_M (BIT(31)) -#define RMT_CLK_EN_V 0x1 -#define RMT_CLK_EN_S 31 -/* RMT_MEM_FORCE_PU : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_FORCE_PU (BIT(4)) -#define RMT_MEM_FORCE_PU_M (BIT(4)) -#define RMT_MEM_FORCE_PU_V 0x1 -#define RMT_MEM_FORCE_PU_S 4 -/* RMT_MEM_FORCE_PD : R/W ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_FORCE_PD (BIT(3)) -#define RMT_MEM_FORCE_PD_M (BIT(3)) -#define RMT_MEM_FORCE_PD_V 0x1 -#define RMT_MEM_FORCE_PD_S 3 -/* RMT_MEM_CLK_FORCE_ON : R/W ;bitpos:[2] ;default: 1'b1 ; */ -/*description: */ -#define RMT_MEM_CLK_FORCE_ON (BIT(2)) -#define RMT_MEM_CLK_FORCE_ON_M (BIT(2)) -#define RMT_MEM_CLK_FORCE_ON_V 0x1 -#define RMT_MEM_CLK_FORCE_ON_S 2 -/* RMT_MEM_TX_WRAP_EN : R/W ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_MEM_TX_WRAP_EN (BIT(1)) -#define RMT_MEM_TX_WRAP_EN_M (BIT(1)) -#define RMT_MEM_TX_WRAP_EN_V 0x1 -#define RMT_MEM_TX_WRAP_EN_S 1 -/* RMT_APB_FIFO_MASK : R/W ;bitpos:[0] ;default: 1'h0 ; */ -/*description: */ -#define RMT_APB_FIFO_MASK (BIT(0)) -#define RMT_APB_FIFO_MASK_M (BIT(0)) -#define RMT_APB_FIFO_MASK_V 0x1 +/** RMT_APB_CONF_REG register + * RMT APB configuration register + */ +#define RMT_APB_CONF_REG (DR_REG_RMT_BASE + 0x80) +/** RMT_APB_FIFO_MASK : R/W; bitpos: [0]; default: 0; + * 1'h1: Access memory directly. 1'h0: access memory via APB FIFO. + */ +#define RMT_APB_FIFO_MASK (BIT(0)) +#define RMT_APB_FIFO_MASK_M (RMT_APB_FIFO_MASK_V << RMT_APB_FIFO_MASK_S) +#define RMT_APB_FIFO_MASK_V 0x00000001U #define RMT_APB_FIFO_MASK_S 0 +/** RMT_MEM_TX_WRAP_EN : R/W; bitpos: [1]; default: 0; + * Set this bit to enable wrap mode. + */ +#define RMT_MEM_TX_WRAP_EN (BIT(1)) +#define RMT_MEM_TX_WRAP_EN_M (RMT_MEM_TX_WRAP_EN_V << RMT_MEM_TX_WRAP_EN_S) +#define RMT_MEM_TX_WRAP_EN_V 0x00000001U +#define RMT_MEM_TX_WRAP_EN_S 1 +/** RMT_MEM_CLK_FORCE_ON : R/W; bitpos: [2]; default: 1; + * Set this bit to enable the clock for RAM when RMT module starts working, disable + * this clock when RMT stops working, to achieve low-power scheme. + */ +#define RMT_MEM_CLK_FORCE_ON (BIT(2)) +#define RMT_MEM_CLK_FORCE_ON_M (RMT_MEM_CLK_FORCE_ON_V << RMT_MEM_CLK_FORCE_ON_S) +#define RMT_MEM_CLK_FORCE_ON_V 0x00000001U +#define RMT_MEM_CLK_FORCE_ON_S 2 +/** RMT_MEM_FORCE_PD : R/W; bitpos: [3]; default: 0; + * Set this bit to power down RMT memory. + */ +#define RMT_MEM_FORCE_PD (BIT(3)) +#define RMT_MEM_FORCE_PD_M (RMT_MEM_FORCE_PD_V << RMT_MEM_FORCE_PD_S) +#define RMT_MEM_FORCE_PD_V 0x00000001U +#define RMT_MEM_FORCE_PD_S 3 +/** RMT_MEM_FORCE_PU : R/W; bitpos: [4]; default: 0; + * 1: Disable RAM's Light-sleep power down function. 0: power down RMT RAM when RMT is + * in Light-sleep mode. + */ +#define RMT_MEM_FORCE_PU (BIT(4)) +#define RMT_MEM_FORCE_PU_M (RMT_MEM_FORCE_PU_V << RMT_MEM_FORCE_PU_S) +#define RMT_MEM_FORCE_PU_V 0x00000001U +#define RMT_MEM_FORCE_PU_S 4 +/** RMT_CLK_EN : R/W; bitpos: [31]; default: 0; + * Clock gating enable bit for RMT registers to achieve low-power scheme. 1: Power up + * drive clock for RMT registers. 0: Power down drive clock for RMT registers. + */ +#define RMT_CLK_EN (BIT(31)) +#define RMT_CLK_EN_M (RMT_CLK_EN_V << RMT_CLK_EN_S) +#define RMT_CLK_EN_V 0x00000001U +#define RMT_CLK_EN_S 31 -#define RMT_TX_SIM_REG (DR_REG_RMT_BASE + 0x0084) -/* RMT_TX_SIM_EN : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_SIM_EN (BIT(4)) -#define RMT_TX_SIM_EN_M (BIT(4)) -#define RMT_TX_SIM_EN_V 0x1 -#define RMT_TX_SIM_EN_S 4 -/* RMT_TX_SIM_CH3 : R/W ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_SIM_CH3 (BIT(3)) -#define RMT_TX_SIM_CH3_M (BIT(3)) -#define RMT_TX_SIM_CH3_V 0x1 -#define RMT_TX_SIM_CH3_S 3 -/* RMT_TX_SIM_CH2 : R/W ;bitpos:[2] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_SIM_CH2 (BIT(2)) -#define RMT_TX_SIM_CH2_M (BIT(2)) -#define RMT_TX_SIM_CH2_V 0x1 -#define RMT_TX_SIM_CH2_S 2 -/* RMT_TX_SIM_CH1 : R/W ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_SIM_CH1 (BIT(1)) -#define RMT_TX_SIM_CH1_M (BIT(1)) -#define RMT_TX_SIM_CH1_V 0x1 -#define RMT_TX_SIM_CH1_S 1 -/* RMT_TX_SIM_CH0 : R/W ;bitpos:[0] ;default: 1'b0 ; */ -/*description: */ -#define RMT_TX_SIM_CH0 (BIT(0)) -#define RMT_TX_SIM_CH0_M (BIT(0)) -#define RMT_TX_SIM_CH0_V 0x1 +/** RMT_TX_SIM_REG register + * Enable RMT simultaneous transmission + */ +#define RMT_TX_SIM_REG (DR_REG_RMT_BASE + 0x84) +/** RMT_TX_SIM_CH0 : R/W; bitpos: [0]; default: 0; + * Set this bit to enable channel 0 to start sending data simultaneously with other + * enabled channels. + */ +#define RMT_TX_SIM_CH0 (BIT(0)) +#define RMT_TX_SIM_CH0_M (RMT_TX_SIM_CH0_V << RMT_TX_SIM_CH0_S) +#define RMT_TX_SIM_CH0_V 0x00000001U #define RMT_TX_SIM_CH0_S 0 +/** RMT_TX_SIM_CH1 : R/W; bitpos: [1]; default: 0; + * Set this bit to enable channel 1 to start sending data simultaneously with other + * enabled channels. + */ +#define RMT_TX_SIM_CH1 (BIT(1)) +#define RMT_TX_SIM_CH1_M (RMT_TX_SIM_CH1_V << RMT_TX_SIM_CH1_S) +#define RMT_TX_SIM_CH1_V 0x00000001U +#define RMT_TX_SIM_CH1_S 1 +/** RMT_TX_SIM_CH2 : R/W; bitpos: [2]; default: 0; + * Set this bit to enable channel 2 to start sending data simultaneously with other + * enabled channels. + */ +#define RMT_TX_SIM_CH2 (BIT(2)) +#define RMT_TX_SIM_CH2_M (RMT_TX_SIM_CH2_V << RMT_TX_SIM_CH2_S) +#define RMT_TX_SIM_CH2_V 0x00000001U +#define RMT_TX_SIM_CH2_S 2 +/** RMT_TX_SIM_CH3 : R/W; bitpos: [3]; default: 0; + * Set this bit to enable channel 3 to start sending data simultaneously with other + * enabled channels. + */ +#define RMT_TX_SIM_CH3 (BIT(3)) +#define RMT_TX_SIM_CH3_M (RMT_TX_SIM_CH3_V << RMT_TX_SIM_CH3_S) +#define RMT_TX_SIM_CH3_V 0x00000001U +#define RMT_TX_SIM_CH3_S 3 +/** RMT_TX_SIM_EN : R/W; bitpos: [4]; default: 0; + * This bit is used to enable multiple channels to start sending data simultaneously. + */ +#define RMT_TX_SIM_EN (BIT(4)) +#define RMT_TX_SIM_EN_M (RMT_TX_SIM_EN_V << RMT_TX_SIM_EN_S) +#define RMT_TX_SIM_EN_V 0x00000001U +#define RMT_TX_SIM_EN_S 4 -#define RMT_REF_CNT_RST_REG (DR_REG_RMT_BASE + 0x0088) -/* RMT_REF_CNT_RST_CH3 : R/W ;bitpos:[3] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_CNT_RST_CH3 (BIT(3)) -#define RMT_REF_CNT_RST_CH3_M (BIT(3)) -#define RMT_REF_CNT_RST_CH3_V 0x1 -#define RMT_REF_CNT_RST_CH3_S 3 -/* RMT_REF_CNT_RST_CH2 : R/W ;bitpos:[2] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_CNT_RST_CH2 (BIT(2)) -#define RMT_REF_CNT_RST_CH2_M (BIT(2)) -#define RMT_REF_CNT_RST_CH2_V 0x1 -#define RMT_REF_CNT_RST_CH2_S 2 -/* RMT_REF_CNT_RST_CH1 : R/W ;bitpos:[1] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_CNT_RST_CH1 (BIT(1)) -#define RMT_REF_CNT_RST_CH1_M (BIT(1)) -#define RMT_REF_CNT_RST_CH1_V 0x1 -#define RMT_REF_CNT_RST_CH1_S 1 -/* RMT_REF_CNT_RST_CH0 : R/W ;bitpos:[0] ;default: 1'b0 ; */ -/*description: */ -#define RMT_REF_CNT_RST_CH0 (BIT(0)) -#define RMT_REF_CNT_RST_CH0_M (BIT(0)) -#define RMT_REF_CNT_RST_CH0_V 0x1 +/** RMT_REF_CNT_RST_REG register + * RMT clock divider reset register + */ +#define RMT_REF_CNT_RST_REG (DR_REG_RMT_BASE + 0x88) +/** RMT_REF_CNT_RST_CH0 : R/W; bitpos: [0]; default: 0; + * This bit is used to reset the clock divider of channel 0. + */ +#define RMT_REF_CNT_RST_CH0 (BIT(0)) +#define RMT_REF_CNT_RST_CH0_M (RMT_REF_CNT_RST_CH0_V << RMT_REF_CNT_RST_CH0_S) +#define RMT_REF_CNT_RST_CH0_V 0x00000001U #define RMT_REF_CNT_RST_CH0_S 0 +/** RMT_REF_CNT_RST_CH1 : R/W; bitpos: [1]; default: 0; + * This bit is used to reset the clock divider of channel 1. + */ +#define RMT_REF_CNT_RST_CH1 (BIT(1)) +#define RMT_REF_CNT_RST_CH1_M (RMT_REF_CNT_RST_CH1_V << RMT_REF_CNT_RST_CH1_S) +#define RMT_REF_CNT_RST_CH1_V 0x00000001U +#define RMT_REF_CNT_RST_CH1_S 1 +/** RMT_REF_CNT_RST_CH2 : R/W; bitpos: [2]; default: 0; + * This bit is used to reset the clock divider of channel 2. + */ +#define RMT_REF_CNT_RST_CH2 (BIT(2)) +#define RMT_REF_CNT_RST_CH2_M (RMT_REF_CNT_RST_CH2_V << RMT_REF_CNT_RST_CH2_S) +#define RMT_REF_CNT_RST_CH2_V 0x00000001U +#define RMT_REF_CNT_RST_CH2_S 2 +/** RMT_REF_CNT_RST_CH3 : R/W; bitpos: [3]; default: 0; + * This bit is used to reset the clock divider of channel 3. + */ +#define RMT_REF_CNT_RST_CH3 (BIT(3)) +#define RMT_REF_CNT_RST_CH3_M (RMT_REF_CNT_RST_CH3_V << RMT_REF_CNT_RST_CH3_S) +#define RMT_REF_CNT_RST_CH3_V 0x00000001U +#define RMT_REF_CNT_RST_CH3_S 3 -#define RMT_CH0_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x008c) -/* RMT_CARRIER_HIGH_THRES_CH0 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_THRES_CH0 0x0000FFFF -#define RMT_CARRIER_HIGH_THRES_CH0_M ((RMT_CARRIER_HIGH_THRES_CH0_V)<<(RMT_CARRIER_HIGH_THRES_CH0_S)) -#define RMT_CARRIER_HIGH_THRES_CH0_V 0xFFFF -#define RMT_CARRIER_HIGH_THRES_CH0_S 16 -/* RMT_CARRIER_LOW_THRES_CH0 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_LOW_THRES_CH0 0x0000FFFF -#define RMT_CARRIER_LOW_THRES_CH0_M ((RMT_CARRIER_LOW_THRES_CH0_V)<<(RMT_CARRIER_LOW_THRES_CH0_S)) -#define RMT_CARRIER_LOW_THRES_CH0_V 0xFFFF +/** RMT_CH0_RX_CARRIER_RM_REG register + * Channel 0 carrier remove register + */ +#define RMT_CH0_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x8c) +/** RMT_CARRIER_LOW_THRES_CH0 : R/W; bitpos: [15:0]; default: 0; + * The low level period in carrier modulation mode is (RMT_CARRIER_LOW_THRES_CH0 + 1) + * clock cycles for channel 0. + */ +#define RMT_CARRIER_LOW_THRES_CH0 0x0000FFFFU +#define RMT_CARRIER_LOW_THRES_CH0_M (RMT_CARRIER_LOW_THRES_CH0_V << RMT_CARRIER_LOW_THRES_CH0_S) +#define RMT_CARRIER_LOW_THRES_CH0_V 0x0000FFFFU #define RMT_CARRIER_LOW_THRES_CH0_S 0 +/** RMT_CARRIER_HIGH_THRES_CH0 : R/W; bitpos: [31:16]; default: 0; + * The high level period in carrier modulation mode is (RMT_CARRIER_HIGH_THRES_CH0 + + * 1) clock cycles for channel 0. + */ +#define RMT_CARRIER_HIGH_THRES_CH0 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH0_M (RMT_CARRIER_HIGH_THRES_CH0_V << RMT_CARRIER_HIGH_THRES_CH0_S) +#define RMT_CARRIER_HIGH_THRES_CH0_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH0_S 16 -#define RMT_CH1_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x0090) -/* RMT_CARRIER_HIGH_THRES_CH1 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_THRES_CH1 0x0000FFFF -#define RMT_CARRIER_HIGH_THRES_CH1_M ((RMT_CARRIER_HIGH_THRES_CH1_V)<<(RMT_CARRIER_HIGH_THRES_CH1_S)) -#define RMT_CARRIER_HIGH_THRES_CH1_V 0xFFFF -#define RMT_CARRIER_HIGH_THRES_CH1_S 16 -/* RMT_CARRIER_LOW_THRES_CH1 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_LOW_THRES_CH1 0x0000FFFF -#define RMT_CARRIER_LOW_THRES_CH1_M ((RMT_CARRIER_LOW_THRES_CH1_V)<<(RMT_CARRIER_LOW_THRES_CH1_S)) -#define RMT_CARRIER_LOW_THRES_CH1_V 0xFFFF +/** RMT_CH1_RX_CARRIER_RM_REG register + * Channel 1 carrier remove register + */ +#define RMT_CH1_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x90) +/** RMT_CARRIER_LOW_THRES_CH1 : R/W; bitpos: [15:0]; default: 0; + * The low level period in carrier modulation mode is (RMT_CARRIER_LOW_THRES_CH1 + 1) + * clock cycles for channel 1. + */ +#define RMT_CARRIER_LOW_THRES_CH1 0x0000FFFFU +#define RMT_CARRIER_LOW_THRES_CH1_M (RMT_CARRIER_LOW_THRES_CH1_V << RMT_CARRIER_LOW_THRES_CH1_S) +#define RMT_CARRIER_LOW_THRES_CH1_V 0x0000FFFFU #define RMT_CARRIER_LOW_THRES_CH1_S 0 +/** RMT_CARRIER_HIGH_THRES_CH1 : R/W; bitpos: [31:16]; default: 0; + * The high level period in carrier modulation mode is (RMT_CARRIER_HIGH_THRES_CH1 + + * 1) clock cycles for channel 1. + */ +#define RMT_CARRIER_HIGH_THRES_CH1 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH1_M (RMT_CARRIER_HIGH_THRES_CH1_V << RMT_CARRIER_HIGH_THRES_CH1_S) +#define RMT_CARRIER_HIGH_THRES_CH1_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH1_S 16 -#define RMT_CH2_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x0094) -/* RMT_CARRIER_HIGH_THRES_CH2 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_THRES_CH2 0x0000FFFF -#define RMT_CARRIER_HIGH_THRES_CH2_M ((RMT_CARRIER_HIGH_THRES_CH2_V)<<(RMT_CARRIER_HIGH_THRES_CH2_S)) -#define RMT_CARRIER_HIGH_THRES_CH2_V 0xFFFF -#define RMT_CARRIER_HIGH_THRES_CH2_S 16 -/* RMT_CARRIER_LOW_THRES_CH2 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_LOW_THRES_CH2 0x0000FFFF -#define RMT_CARRIER_LOW_THRES_CH2_M ((RMT_CARRIER_LOW_THRES_CH2_V)<<(RMT_CARRIER_LOW_THRES_CH2_S)) -#define RMT_CARRIER_LOW_THRES_CH2_V 0xFFFF +/** RMT_CH2_RX_CARRIER_RM_REG register + * Channel 2 carrier remove register + */ +#define RMT_CH2_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x94) +/** RMT_CARRIER_LOW_THRES_CH2 : R/W; bitpos: [15:0]; default: 0; + * The low level period in carrier modulation mode is (RMT_CARRIER_LOW_THRES_CH2 + 1) + * clock cycles for channel 2. + */ +#define RMT_CARRIER_LOW_THRES_CH2 0x0000FFFFU +#define RMT_CARRIER_LOW_THRES_CH2_M (RMT_CARRIER_LOW_THRES_CH2_V << RMT_CARRIER_LOW_THRES_CH2_S) +#define RMT_CARRIER_LOW_THRES_CH2_V 0x0000FFFFU #define RMT_CARRIER_LOW_THRES_CH2_S 0 +/** RMT_CARRIER_HIGH_THRES_CH2 : R/W; bitpos: [31:16]; default: 0; + * The high level period in carrier modulation mode is (RMT_CARRIER_HIGH_THRES_CH2 + + * 1) clock cycles for channel 2. + */ +#define RMT_CARRIER_HIGH_THRES_CH2 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH2_M (RMT_CARRIER_HIGH_THRES_CH2_V << RMT_CARRIER_HIGH_THRES_CH2_S) +#define RMT_CARRIER_HIGH_THRES_CH2_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH2_S 16 -#define RMT_CH3_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x0098) -/* RMT_CARRIER_HIGH_THRES_CH3 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_HIGH_THRES_CH3 0x0000FFFF -#define RMT_CARRIER_HIGH_THRES_CH3_M ((RMT_CARRIER_HIGH_THRES_CH3_V)<<(RMT_CARRIER_HIGH_THRES_CH3_S)) -#define RMT_CARRIER_HIGH_THRES_CH3_V 0xFFFF -#define RMT_CARRIER_HIGH_THRES_CH3_S 16 -/* RMT_CARRIER_LOW_THRES_CH3 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: */ -#define RMT_CARRIER_LOW_THRES_CH3 0x0000FFFF -#define RMT_CARRIER_LOW_THRES_CH3_M ((RMT_CARRIER_LOW_THRES_CH3_V)<<(RMT_CARRIER_LOW_THRES_CH3_S)) -#define RMT_CARRIER_LOW_THRES_CH3_V 0xFFFF +/** RMT_CH3_RX_CARRIER_RM_REG register + * Channel 3 carrier remove register + */ +#define RMT_CH3_RX_CARRIER_RM_REG (DR_REG_RMT_BASE + 0x98) +/** RMT_CARRIER_LOW_THRES_CH3 : R/W; bitpos: [15:0]; default: 0; + * The low level period in carrier modulation mode is (RMT_CARRIER_LOW_THRES_CH3 + 1) + * clock cycles for channel 3. + */ +#define RMT_CARRIER_LOW_THRES_CH3 0x0000FFFFU +#define RMT_CARRIER_LOW_THRES_CH3_M (RMT_CARRIER_LOW_THRES_CH3_V << RMT_CARRIER_LOW_THRES_CH3_S) +#define RMT_CARRIER_LOW_THRES_CH3_V 0x0000FFFFU #define RMT_CARRIER_LOW_THRES_CH3_S 0 +/** RMT_CARRIER_HIGH_THRES_CH3 : R/W; bitpos: [31:16]; default: 0; + * The high level period in carrier modulation mode is (RMT_CARRIER_HIGH_THRES_CH3 + + * 1) clock cycles for channel 3. + */ +#define RMT_CARRIER_HIGH_THRES_CH3 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH3_M (RMT_CARRIER_HIGH_THRES_CH3_V << RMT_CARRIER_HIGH_THRES_CH3_S) +#define RMT_CARRIER_HIGH_THRES_CH3_V 0x0000FFFFU +#define RMT_CARRIER_HIGH_THRES_CH3_S 16 -#define RMT_DATE_REG (DR_REG_RMT_BASE + 0x0fc) -/* RMT_DATE : R/W ;bitpos:[31:0] ;default: 32'h19080700 ; */ -/*description: */ -#define RMT_DATE 0xFFFFFFFF -#define RMT_DATE_M ((RMT_DATE_V)<<(RMT_DATE_S)) -#define RMT_DATE_V 0xFFFFFFFF +/** RMT_DATE_REG register + * Version control register + */ +#define RMT_DATE_REG (DR_REG_RMT_BASE + 0xfc) +/** RMT_DATE : R/W; bitpos: [31:0]; default: 419898881; + * Version control register + */ +#define RMT_DATE 0xFFFFFFFFU +#define RMT_DATE_M (RMT_DATE_V << RMT_DATE_S) +#define RMT_DATE_V 0xFFFFFFFFU #define RMT_DATE_S 0 #ifdef __cplusplus } #endif - - - -#endif /*_SOC_RMT_REG_H_ */ diff --git a/components/soc/esp32s2/include/soc/rmt_struct.h b/components/soc/esp32s2/include/soc/rmt_struct.h index 5e4300409392..b9f271824882 100644 --- a/components/soc/esp32s2/include/soc/rmt_struct.h +++ b/components/soc/esp32s2/include/soc/rmt_struct.h @@ -1,18 +1,9 @@ -// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef _SOC_RMT_STRUCT_H_ -#define _SOC_RMT_STRUCT_H_ +/** + * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once #include @@ -20,271 +11,795 @@ extern "C" { #endif -typedef volatile struct rmt_dev_s { - uint32_t data_ch[4]; /* Data FIFO, Can only be accessed by PeriBus2 */ +/** Group: FIFO R/W registers */ +/** Type of chndata register + * Read and write data for channel n via APB FIFO + */ +typedef union { struct { - union { - struct { - uint32_t div_cnt: 8; - uint32_t idle_thres: 16; - uint32_t mem_size: 3; - uint32_t carrier_eff_en: 1; - uint32_t carrier_en: 1; - uint32_t carrier_out_lv: 1; - uint32_t reserved30: 2; - }; - uint32_t val; - } conf0; - union { - struct { - uint32_t tx_start: 1; - uint32_t rx_en: 1; - uint32_t mem_wr_rst: 1; - uint32_t mem_rd_rst: 1; - uint32_t apb_mem_rst: 1; - uint32_t mem_owner: 1; - uint32_t tx_conti_mode: 1; - uint32_t rx_filter_en: 1; - uint32_t rx_filter_thres: 8; - uint32_t chk_rx_carrier_en: 1; - uint32_t ref_always_on: 1; - uint32_t idle_out_lv: 1; - uint32_t idle_out_en: 1; - uint32_t tx_stop: 1; - uint32_t reserved21: 11; - }; - uint32_t val; - } conf1; + /** chn_data : RO; bitpos: [31:0]; default: 0; + * This register is used to read and write data for channel n via APB FIFO. + */ + uint32_t chn_data: 32; + }; + uint32_t val; +} rmt_chndata_reg_t; + + +/** Group: Configuration registers */ +/** Type of chnconf0 register + * Channel n configuration register 0 + */ +typedef union { + struct { + /** div_cnt : R/W; bitpos: [7:0]; default: 2; + * This field is used to configure clock divider for channel n. + */ + uint32_t div_cnt: 8; + /** idle_thres : R/W; bitpos: [23:8]; default: 4096; + * Receiving ends when no edge is detected on input signals for continuous clock + * cycles longer than this field value. + */ + uint32_t idle_thres: 16; + /** mem_size : R/W; bitpos: [26:24]; default: 1; + * This field is used to configure the maximum blocks allocated to channel n. The + * valid range is from 1 ~ 4-n. + */ + uint32_t mem_size: 3; + /** carrier_eff_en : R/W; bitpos: [27]; default: 1; + * 1: Add carrier modulation on output signals only at data sending state for channel + * n. 0: Add carrier modulation on signals at all states for channel n. States here + * include idle state (ST_IDLE), reading data from RAM (ST_RD_MEM), and sending data + * stored in RAM (ST_SEND). Only valid when RMT_CARRIER_EN_CHn is set to 1. + */ + uint32_t carrier_eff_en: 1; + /** carrier_en : R/W; bitpos: [28]; default: 1; + * This bit is used to enable carrier modulation for channel n. 1: Add carrier + * modulation on output signals. 0: No carrier modulation is added on output signals. + */ + uint32_t carrier_en: 1; + /** carrier_out_lv : R/W; bitpos: [29]; default: 1; + * This bit is used to configure the position of carrier wave for channel n. + * + * 1'h0: Add carrier wave on low-level output signals. + * + * 1'h1: Add carrier wave on high-level output signals. + */ + uint32_t carrier_out_lv: 1; + uint32_t reserved_30: 2; + }; + uint32_t val; +} rmt_chnconf0_reg_t; + +/** Type of chnconf1 register + * Channel n configuration register 1 + */ +typedef union { + struct { + /** tx_start : R/W; bitpos: [0]; default: 0; + * Set this bit to start sending data on channel n. + */ + uint32_t tx_start: 1; + /** rx_en : R/W; bitpos: [1]; default: 0; + * Set this bit to enable receiver to receive data on channel n. + */ + uint32_t rx_en: 1; + /** mem_wr_rst : WO; bitpos: [2]; default: 0; + * Set this bit to reset RAM write address accessed by the receiver for channel n. + */ + uint32_t mem_wr_rst: 1; + /** mem_rd_rst : WO; bitpos: [3]; default: 0; + * Set this bit to reset RAM read address accessed by the transmitter for channel n. + */ + uint32_t mem_rd_rst: 1; + /** apb_mem_rst : WO; bitpos: [4]; default: 0; + * Set this bit to reset W/R ram address for channel n by accessing apb fifo. + */ + uint32_t apb_mem_rst: 1; + /** mem_owner : R/W; bitpos: [5]; default: 1; + * This bit marks the ownership of channel n's RAM block. + * + * 1'h1: Receiver is using the RAM. + * + * 1'h0: Transmitter is using the RAM. + */ + uint32_t mem_owner: 1; + /** tx_conti_mode : R/W; bitpos: [6]; default: 0; + * Set this bit to restart transmission in continuous node from the first data in + * channel n. + */ + uint32_t tx_conti_mode: 1; + /** rx_filter_en : R/W; bitpos: [7]; default: 0; + * Set this bit to enable the receiver's filter for channel n. + */ + uint32_t rx_filter_en: 1; + /** rx_filter_thres : R/W; bitpos: [15:8]; default: 15; + * Set this field to ignore the input pulse when its width is less than + * RMT_RX_FILTER_THRES_CHn APB clock cycles in receive mode. + */ + uint32_t rx_filter_thres: 8; + /** chk_rx_carrier_en : R/W; bitpos: [16]; default: 0; + * Set this bit to enable memory loop read mode when carrier modulation is enabled for + * channel n. + */ + uint32_t chk_rx_carrier_en: 1; + /** ref_always_on : R/W; bitpos: [17]; default: 0; + * Set this bit to select a base clock for channel n. + * + * 1'h1: APB_CLK 1'h0: REF_TICK + */ + uint32_t ref_always_on: 1; + /** idle_out_lv : R/W; bitpos: [18]; default: 0; + * This bit configures the level of output signals in channel n when the transmitter + * is in idle state. + */ + uint32_t idle_out_lv: 1; + /** idle_out_en : R/W; bitpos: [19]; default: 0; + * This is the output enable bit for channel n in idle state. + */ + uint32_t idle_out_en: 1; + /** tx_stop : R/W; bitpos: [20]; default: 0; + * Set this bit to stop the transmitter of channel n sending data out. + */ + uint32_t tx_stop: 1; + uint32_t reserved_21: 11; + }; + uint32_t val; +} rmt_chnconf1_reg_t; + +/** Type of apb_conf register + * RMT APB configuration register + */ +typedef union { + struct { + /** apb_fifo_mask : R/W; bitpos: [0]; default: 0; + * 1'h1: Access memory directly. 1'h0: access memory via APB FIFO. + */ + uint32_t apb_fifo_mask: 1; + /** mem_tx_wrap_en : R/W; bitpos: [1]; default: 0; + * Set this bit to enable wrap mode. + */ + uint32_t mem_tx_wrap_en: 1; + /** mem_clk_force_on : R/W; bitpos: [2]; default: 1; + * Set this bit to enable the clock for RAM when RMT module starts working, disable + * this clock when RMT stops working, to achieve low-power scheme. + */ + uint32_t mem_clk_force_on: 1; + /** mem_force_pd : R/W; bitpos: [3]; default: 0; + * Set this bit to power down RMT memory. + */ + uint32_t mem_force_pd: 1; + /** mem_force_pu : R/W; bitpos: [4]; default: 0; + * 1: Disable RAM's Light-sleep power down function. 0: power down RMT RAM when RMT is + * in Light-sleep mode. + */ + uint32_t mem_force_pu: 1; + uint32_t reserved_5: 26; + /** clk_en : R/W; bitpos: [31]; default: 0; + * Clock gating enable bit for RMT registers to achieve low-power scheme. 1: Power up + * drive clock for RMT registers. 0: Power down drive clock for RMT registers. + */ + uint32_t clk_en: 1; + }; + uint32_t val; +} rmt_apb_conf_reg_t; + +/** Type of ref_cnt_rst register + * RMT clock divider reset register + */ +typedef union { + struct { + /** ref_cnt_rst_ch0 : R/W; bitpos: [0]; default: 0; + * This bit is used to reset the clock divider of channel 0. + */ + uint32_t ref_cnt_rst_ch0: 1; + /** ref_cnt_rst_ch1 : R/W; bitpos: [1]; default: 0; + * This bit is used to reset the clock divider of channel 1. + */ + uint32_t ref_cnt_rst_ch1: 1; + /** ref_cnt_rst_ch2 : R/W; bitpos: [2]; default: 0; + * This bit is used to reset the clock divider of channel 2. + */ + uint32_t ref_cnt_rst_ch2: 1; + /** ref_cnt_rst_ch3 : R/W; bitpos: [3]; default: 0; + * This bit is used to reset the clock divider of channel 3. + */ + uint32_t ref_cnt_rst_ch3: 1; + uint32_t reserved_4: 28; + }; + uint32_t val; +} rmt_ref_cnt_rst_reg_t; + +/** Type of chn_rx_carrier_rm register + * Channel n carrier remove register + */ +typedef union { + struct { + /** carrier_low_thres_ch : R/W; bitpos: [15:0]; default: 0; + * The low level period in carrier modulation mode is (RMT_CARRIER_LOW_THRES_CHn + 1) + * clock cycles for channel n. + */ + uint32_t carrier_low_thres_ch: 16; + /** carrier_high_thres_ch : R/W; bitpos: [31:16]; default: 0; + * The high level period in carrier modulation mode is (RMT_CARRIER_HIGH_THRES_CHn + + * 1) clock cycles for channel n. + */ + uint32_t carrier_high_thres_ch: 16; + }; + uint32_t val; +} rmt_chn_rx_carrier_rm_reg_t; + + +/** Group: Status registers */ +/** Type of chnstatus register + * Channel n status register + */ +typedef union { + struct { + /** mem_waddr_ex : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when receiver of channel n is using + * the RAM. + */ + uint32_t mem_waddr_ex: 9; + uint32_t reserved_9: 1; + /** mem_raddr_ex : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when transmitter of channel n is using + * the RAM. + */ + uint32_t mem_raddr_ex: 9; + uint32_t reserved_19: 1; + /** state : RO; bitpos: [22:20]; default: 0; + * This field records the FSM status of channel n. + */ + uint32_t state: 3; + /** mem_owner_err : RO; bitpos: [23]; default: 0; + * This status bit will be set when the ownership of memory block is violated. + */ + uint32_t mem_owner_err: 1; + /** mem_full : RO; bitpos: [24]; default: 0; + * This status bit will be set if the receiver receives more data than the memory + * allows. + */ + uint32_t mem_full: 1; + /** mem_empty : RO; bitpos: [25]; default: 0; + * This status bit will be set when the data to be sent is more than memory allows and + * the wrap mode is disabled. + */ + uint32_t mem_empty: 1; + /** apb_mem_wr_err : RO; bitpos: [26]; default: 0; + * This status bit will be set if the offset address out of memory size when writes + * RAM via APB bus. + */ + uint32_t apb_mem_wr_err: 1; + /** apb_mem_rd_err : RO; bitpos: [27]; default: 0; + * This status bit will be set if the offset address out of memory size when reads RAM + * via APB bus. + */ + uint32_t apb_mem_rd_err: 1; + uint32_t reserved_28: 4; + }; + uint32_t val; +} rmt_chnstatus_reg_t; + +/** Type of chnaddr register + * Channel n address register + */ +typedef union { + struct { + /** apb_mem_waddr_ch0 : RO; bitpos: [8:0]; default: 0; + * This field records the memory address offset when channel n writes RAM via APB bus. + */ + uint32_t apb_mem_waddr_ch0: 9; + uint32_t reserved_9: 1; + /** apb_mem_raddr_ch0 : RO; bitpos: [18:10]; default: 0; + * This field records the memory address offset when channel n reads RAM via APB bus. + */ + uint32_t apb_mem_raddr_ch0: 9; + uint32_t reserved_19: 13; + }; + uint32_t val; +} rmt_chnaddr_reg_t; + + +/** Group: Interrupt registers */ +/** Type of int_raw register + * Raw interrupt status register + */ +typedef union { + struct { + /** ch0_tx_end_int_raw : RO; bitpos: [0]; default: 0; + * The interrupt raw bit for channel 0. Triggered when transmitting ends. + */ + uint32_t ch0_tx_end_int_raw: 1; + /** ch0_rx_end_int_raw : RO; bitpos: [1]; default: 0; + * The interrupt raw bit for channel 0. Triggered when receiving ends. + */ + uint32_t ch0_rx_end_int_raw: 1; + /** ch0_err_int_raw : RO; bitpos: [2]; default: 0; + * The interrupt raw bit for channel 0. Triggered when error occurs. + */ + uint32_t ch0_err_int_raw: 1; + /** ch1_tx_end_int_raw : RO; bitpos: [3]; default: 0; + * The interrupt raw bit for channel 1. Triggered when transmitting ends. + */ + uint32_t ch1_tx_end_int_raw: 1; + /** ch1_rx_end_int_raw : RO; bitpos: [4]; default: 0; + * The interrupt raw bit for channel 1. Triggered when receiving ends. + */ + uint32_t ch1_rx_end_int_raw: 1; + /** ch1_err_int_raw : RO; bitpos: [5]; default: 0; + * The interrupt raw bit for channel 1. Triggered when error occurs. + */ + uint32_t ch1_err_int_raw: 1; + /** ch2_tx_end_int_raw : RO; bitpos: [6]; default: 0; + * The interrupt raw bit for channel 2. Triggered when transmitting ends. + */ + uint32_t ch2_tx_end_int_raw: 1; + /** ch2_rx_end_int_raw : RO; bitpos: [7]; default: 0; + * The interrupt raw bit for channel 2. Triggered when receiving ends. + */ + uint32_t ch2_rx_end_int_raw: 1; + /** ch2_err_int_raw : RO; bitpos: [8]; default: 0; + * The interrupt raw bit for channel 2. Triggered when error occurs. + */ + uint32_t ch2_err_int_raw: 1; + /** ch3_tx_end_int_raw : RO; bitpos: [9]; default: 0; + * The interrupt raw bit for channel 3. Triggered when transmitting ends. + */ + uint32_t ch3_tx_end_int_raw: 1; + /** ch3_rx_end_int_raw : RO; bitpos: [10]; default: 0; + * The interrupt raw bit for channel 3. Triggered when receiving ends. + */ + uint32_t ch3_rx_end_int_raw: 1; + /** ch3_err_int_raw : RO; bitpos: [11]; default: 0; + * The interrupt raw bit for channel 3. Triggered when error occurs. + */ + uint32_t ch3_err_int_raw: 1; + /** ch0_tx_thr_event_int_raw : RO; bitpos: [12]; default: 0; + * The interrupt raw bit for channel 0. Triggered when transmitter sends more data + * than configured value. + */ + uint32_t ch0_tx_thr_event_int_raw: 1; + /** ch1_tx_thr_event_int_raw : RO; bitpos: [13]; default: 0; + * The interrupt raw bit for channel 1. Triggered when transmitter sends more data + * than configured value. + */ + uint32_t ch1_tx_thr_event_int_raw: 1; + /** ch2_tx_thr_event_int_raw : RO; bitpos: [14]; default: 0; + * The interrupt raw bit for channel 2. Triggered when transmitter sends more data + * than configured value. + */ + uint32_t ch2_tx_thr_event_int_raw: 1; + /** ch3_tx_thr_event_int_raw : RO; bitpos: [15]; default: 0; + * The interrupt raw bit for channel 3. Triggered when transmitter sends more data + * than configured value. + */ + uint32_t ch3_tx_thr_event_int_raw: 1; + /** ch0_tx_loop_int_raw : RO; bitpos: [16]; default: 0; + * The interrupt raw bit for channel 0. Triggered when loop counting reaches the + * configured threshold value. + */ + uint32_t ch0_tx_loop_int_raw: 1; + /** ch1_tx_loop_int_raw : RO; bitpos: [17]; default: 0; + * The interrupt raw bit for channel 1. Triggered when loop counting reaches the + * configured threshold value. + */ + uint32_t ch1_tx_loop_int_raw: 1; + /** ch2_tx_loop_int_raw : RO; bitpos: [18]; default: 0; + * The interrupt raw bit for channel 2. Triggered when loop counting reaches the + * configured threshold value. + */ + uint32_t ch2_tx_loop_int_raw: 1; + /** ch3_tx_loop_int_raw : RO; bitpos: [19]; default: 0; + * The interrupt raw bit for channel 3. Triggered when loop counting reaches the + * configured threshold value. + */ + uint32_t ch3_tx_loop_int_raw: 1; + uint32_t reserved_20: 12; + }; + uint32_t val; +} rmt_int_raw_reg_t; + +/** Type of int_st register + * Masked interrupt status register + */ +typedef union { + struct { + /** ch0_tx_end_int_st : RO; bitpos: [0]; default: 0; + * The masked interrupt status bit for RMT_CH0_TX_END_INT. + */ + uint32_t ch0_tx_end_int_st: 1; + /** ch0_rx_end_int_st : RO; bitpos: [1]; default: 0; + * The masked interrupt status bit for RMT_CH0_RX_END_INT. + */ + uint32_t ch0_rx_end_int_st: 1; + /** ch0_err_int_st : RO; bitpos: [2]; default: 0; + * The masked interrupt status bit for RMT_CH0_ERR_INT. + */ + uint32_t ch0_err_int_st: 1; + /** ch1_tx_end_int_st : RO; bitpos: [3]; default: 0; + * The masked interrupt status bit for RMT_CH1_TX_END_INT. + */ + uint32_t ch1_tx_end_int_st: 1; + /** ch1_rx_end_int_st : RO; bitpos: [4]; default: 0; + * The masked interrupt status bit for RMT_CH1_RX_END_INT. + */ + uint32_t ch1_rx_end_int_st: 1; + /** ch1_err_int_st : RO; bitpos: [5]; default: 0; + * The masked interrupt status bit for RMT_CH1_ERR_INT. + */ + uint32_t ch1_err_int_st: 1; + /** ch2_tx_end_int_st : RO; bitpos: [6]; default: 0; + * The masked interrupt status bit for RMT_CH2_TX_END_INT. + */ + uint32_t ch2_tx_end_int_st: 1; + /** ch2_rx_end_int_st : RO; bitpos: [7]; default: 0; + * The masked interrupt status bit for RMT_CH2_RX_END_INT. + */ + uint32_t ch2_rx_end_int_st: 1; + /** ch2_err_int_st : RO; bitpos: [8]; default: 0; + * The masked interrupt status bit for RMT_CH2_ERR_INT. + */ + uint32_t ch2_err_int_st: 1; + /** ch3_tx_end_int_st : RO; bitpos: [9]; default: 0; + * The masked interrupt status bit for RMT_CH3_TX_END_INT. + */ + uint32_t ch3_tx_end_int_st: 1; + /** ch3_rx_end_int_st : RO; bitpos: [10]; default: 0; + * The masked interrupt status bit for RMT_CH3_RX_END_INT. + */ + uint32_t ch3_rx_end_int_st: 1; + /** ch3_err_int_st : RO; bitpos: [11]; default: 0; + * The masked interrupt status bit for RMT_CH3_ERR_INT. + */ + uint32_t ch3_err_int_st: 1; + /** ch0_tx_thr_event_int_st : RO; bitpos: [12]; default: 0; + * The masked interrupt status bit for RMT_CH0_TX_THR_EVENT_INT. + */ + uint32_t ch0_tx_thr_event_int_st: 1; + /** ch1_tx_thr_event_int_st : RO; bitpos: [13]; default: 0; + * The masked interrupt status bit for RMT_CH1_TX_THR_EVENT_INT. + */ + uint32_t ch1_tx_thr_event_int_st: 1; + /** ch2_tx_thr_event_int_st : RO; bitpos: [14]; default: 0; + * The masked interrupt status bit for RMT_CH2_TX_THR_EVENT_INT. + */ + uint32_t ch2_tx_thr_event_int_st: 1; + /** ch3_tx_thr_event_int_st : RO; bitpos: [15]; default: 0; + * The masked interrupt status bit for RMT_CH3_TX_THR_EVENT_INT. + */ + uint32_t ch3_tx_thr_event_int_st: 1; + /** ch0_tx_loop_int_st : RO; bitpos: [16]; default: 0; + * The masked interrupt status bit for RMT_CH0_TX_LOOP_INT. + */ + uint32_t ch0_tx_loop_int_st: 1; + /** ch1_tx_loop_int_st : RO; bitpos: [17]; default: 0; + * The masked interrupt status bit for RMT_CH1_TX_LOOP_INT. + */ + uint32_t ch1_tx_loop_int_st: 1; + /** ch2_tx_loop_int_st : RO; bitpos: [18]; default: 0; + * The masked interrupt status bit for RMT_CH2_TX_LOOP_INT. + */ + uint32_t ch2_tx_loop_int_st: 1; + /** ch3_tx_loop_int_st : RO; bitpos: [19]; default: 0; + * The masked interrupt status bit for RMT_CH3_TX_LOOP_INT. + */ + uint32_t ch3_tx_loop_int_st: 1; + uint32_t reserved_20: 12; + }; + uint32_t val; +} rmt_int_st_reg_t; + +/** Type of int_ena register + * Interrupt enable register + */ +typedef union { + struct { + /** ch0_tx_end_int_ena : R/W; bitpos: [0]; default: 0; + * The interrupt enabled bit for RMT_CH0_TX_END_INT. + */ + uint32_t ch0_tx_end_int_ena: 1; + /** ch0_rx_end_int_ena : R/W; bitpos: [1]; default: 0; + * The interrupt enabled bit for RMT_CH0_RX_END_INT. + */ + uint32_t ch0_rx_end_int_ena: 1; + /** ch0_err_int_ena : R/W; bitpos: [2]; default: 0; + * The interrupt enabled bit for RMT_CH0_ERR_INT. + */ + uint32_t ch0_err_int_ena: 1; + /** ch1_tx_end_int_ena : R/W; bitpos: [3]; default: 0; + * The interrupt enabled bit for RMT_CH1_TX_END_INT. + */ + uint32_t ch1_tx_end_int_ena: 1; + /** ch1_rx_end_int_ena : R/W; bitpos: [4]; default: 0; + * The interrupt enabled bit for RMT_CH1_RX_END_INT. + */ + uint32_t ch1_rx_end_int_ena: 1; + /** ch1_err_int_ena : R/W; bitpos: [5]; default: 0; + * The interrupt enabled bit for RMT_CH1_ERR_INT. + */ + uint32_t ch1_err_int_ena: 1; + /** ch2_tx_end_int_ena : R/W; bitpos: [6]; default: 0; + * The interrupt enabled bit for RMT_CH2_TX_END_INT. + */ + uint32_t ch2_tx_end_int_ena: 1; + /** ch2_rx_end_int_ena : R/W; bitpos: [7]; default: 0; + * The interrupt enabled bit for RMT_CH2_RX_END_INT. + */ + uint32_t ch2_rx_end_int_ena: 1; + /** ch2_err_int_ena : R/W; bitpos: [8]; default: 0; + * The interrupt enabled bit for RMT_CH2_ERR_INT. + */ + uint32_t ch2_err_int_ena: 1; + /** ch3_tx_end_int_ena : R/W; bitpos: [9]; default: 0; + * The interrupt enabled bit for RMT_CH3_TX_END_INT. + */ + uint32_t ch3_tx_end_int_ena: 1; + /** ch3_rx_end_int_ena : R/W; bitpos: [10]; default: 0; + * The interrupt enabled bit for RMT_CH3_RX_END_INT. + */ + uint32_t ch3_rx_end_int_ena: 1; + /** ch3_err_int_ena : R/W; bitpos: [11]; default: 0; + * The interrupt enabled bit for RMT_CH3_ERR_INT. + */ + uint32_t ch3_err_int_ena: 1; + /** ch0_tx_thr_event_int_ena : R/W; bitpos: [12]; default: 0; + * The interrupt enabled bit for RMT_CH0_TX_THR_EVENT_INT. + */ + uint32_t ch0_tx_thr_event_int_ena: 1; + /** ch1_tx_thr_event_int_ena : R/W; bitpos: [13]; default: 0; + * The interrupt enabled bit for RMT_CH1_TX_THR_EVENT_INT. + */ + uint32_t ch1_tx_thr_event_int_ena: 1; + /** ch2_tx_thr_event_int_ena : R/W; bitpos: [14]; default: 0; + * The interrupt enabled bit for RMT_CH2_TX_THR_EVENT_INT. + */ + uint32_t ch2_tx_thr_event_int_ena: 1; + /** ch3_tx_thr_event_int_ena : R/W; bitpos: [15]; default: 0; + * The interrupt enabled bit for RMT_CH3_TX_THR_EVENT_INT. + */ + uint32_t ch3_tx_thr_event_int_ena: 1; + /** ch0_tx_loop_int_ena : R/W; bitpos: [16]; default: 0; + * The interrupt enabled bit for RMT_CH0_TX_LOOP_INT. + */ + uint32_t ch0_tx_loop_int_ena: 1; + /** ch1_tx_loop_int_ena : R/W; bitpos: [17]; default: 0; + * The interrupt enabled bit for RMT_CH1_TX_LOOP_INT. + */ + uint32_t ch1_tx_loop_int_ena: 1; + /** ch2_tx_loop_int_ena : R/W; bitpos: [18]; default: 0; + * The interrupt enabled bit for RMT_CH2_TX_LOOP_INT. + */ + uint32_t ch2_tx_loop_int_ena: 1; + /** ch3_tx_loop_int_ena : R/W; bitpos: [19]; default: 0; + * The interrupt enabled bit for RMT_CH3_TX_LOOP_INT. + */ + uint32_t ch3_tx_loop_int_ena: 1; + uint32_t reserved_20: 12; + }; + uint32_t val; +} rmt_int_ena_reg_t; + +/** Type of int_clr register + * Interrupt clear register + */ +typedef union { + struct { + /** ch0_tx_end_int_clr : WO; bitpos: [0]; default: 0; + * Set this bit to clear RMT_CH0_TX_END_INT interrupt. + */ + uint32_t ch0_tx_end_int_clr: 1; + /** ch0_rx_end_int_clr : WO; bitpos: [1]; default: 0; + * Set this bit to clear RMT_CH0_RX_END_INT interrupt. + */ + uint32_t ch0_rx_end_int_clr: 1; + /** ch0_err_int_clr : WO; bitpos: [2]; default: 0; + * Set this bit to clear RMT_CH0_ERR_INT interrupt. + */ + uint32_t ch0_err_int_clr: 1; + /** ch1_tx_end_int_clr : WO; bitpos: [3]; default: 0; + * Set this bit to clear RMT_CH1_TX_END_INT interrupt. + */ + uint32_t ch1_tx_end_int_clr: 1; + /** ch1_rx_end_int_clr : WO; bitpos: [4]; default: 0; + * Set this bit to clear RMT_CH1_RX_END_INT interrupt. + */ + uint32_t ch1_rx_end_int_clr: 1; + /** ch1_err_int_clr : WO; bitpos: [5]; default: 0; + * Set this bit to clear RMT_CH1_ERR_INT interrupt. + */ + uint32_t ch1_err_int_clr: 1; + /** ch2_tx_end_int_clr : WO; bitpos: [6]; default: 0; + * Set this bit to clear RMT_CH2_TX_END_INT interrupt. + */ + uint32_t ch2_tx_end_int_clr: 1; + /** ch2_rx_end_int_clr : WO; bitpos: [7]; default: 0; + * Set this bit to clear RMT_CH2_RX_END_INT interrupt. + */ + uint32_t ch2_rx_end_int_clr: 1; + /** ch2_err_int_clr : WO; bitpos: [8]; default: 0; + * Set this bit to clear RMT_CH2_ERR_INT interrupt. + */ + uint32_t ch2_err_int_clr: 1; + /** ch3_tx_end_int_clr : WO; bitpos: [9]; default: 0; + * Set this bit to clear RMT_CH3_TX_END_INT interrupt. + */ + uint32_t ch3_tx_end_int_clr: 1; + /** ch3_rx_end_int_clr : WO; bitpos: [10]; default: 0; + * Set this bit to clear RMT_CH3_RX_END_INT interrupt. + */ + uint32_t ch3_rx_end_int_clr: 1; + /** ch3_err_int_clr : WO; bitpos: [11]; default: 0; + * Set this bit to clear RMT_CH3_ERR_INT interrupt. + */ + uint32_t ch3_err_int_clr: 1; + /** ch0_tx_thr_event_int_clr : WO; bitpos: [12]; default: 0; + * Set this bit to clear RMT_CH0_TX_THR_EVENT_INT interrupt. + */ + uint32_t ch0_tx_thr_event_int_clr: 1; + /** ch1_tx_thr_event_int_clr : WO; bitpos: [13]; default: 0; + * Set this bit to clear RMT_CH1_TX_THR_EVENT_INT interrupt. + */ + uint32_t ch1_tx_thr_event_int_clr: 1; + /** ch2_tx_thr_event_int_clr : WO; bitpos: [14]; default: 0; + * Set this bit to clear RMT_CH2_TX_THR_EVENT_INT interrupt. + */ + uint32_t ch2_tx_thr_event_int_clr: 1; + /** ch3_tx_thr_event_int_clr : WO; bitpos: [15]; default: 0; + * Set this bit to clear RMT_CH3_TX_THR_EVENT_INT interrupt. + */ + uint32_t ch3_tx_thr_event_int_clr: 1; + /** ch0_tx_loop_int_clr : WO; bitpos: [16]; default: 0; + * Set this bit to clear RMT_CH0_TX_LOOP_INT interrupt. + */ + uint32_t ch0_tx_loop_int_clr: 1; + /** ch1_tx_loop_int_clr : WO; bitpos: [17]; default: 0; + * Set this bit to clear RMT_CH1_TX_LOOP_INT interrupt. + */ + uint32_t ch1_tx_loop_int_clr: 1; + /** ch2_tx_loop_int_clr : WO; bitpos: [18]; default: 0; + * Set this bit to clear RMT_CH2_TX_LOOP_INT interrupt. + */ + uint32_t ch2_tx_loop_int_clr: 1; + /** ch3_tx_loop_int_clr : WO; bitpos: [19]; default: 0; + * Set this bit to clear RMT_CH3_TX_LOOP_INT interrupt. + */ + uint32_t ch3_tx_loop_int_clr: 1; + uint32_t reserved_20: 12; + }; + uint32_t val; +} rmt_int_clr_reg_t; + + +/** Group: Carrier wave duty cycle registers */ +/** Type of chncarrier_duty register + * Channel n duty cycle configuration register + */ +typedef union { + struct { + /** low : R/W; bitpos: [15:0]; default: 64; + * This field is used to configure the clock cycles of carrier wave at low level for + * channel n. + */ + uint32_t low: 16; + /** high : R/W; bitpos: [31:16]; default: 64; + * This field is used to configure the clock cycles of carrier wave at high level for + * channel n. + */ + uint32_t high: 16; + }; + uint32_t val; +} rmt_chncarrier_duty_reg_t; + + +/** Group: Tx event configuration registers */ +/** Type of chn_tx_lim register + * Channel n Tx event configuration register + */ +typedef union { + struct { + /** tx_lim : R/W; bitpos: [8:0]; default: 128; + * This field is used to configure the maximum entries that channel n can send out. + * When RMT_MEM_SIZE_CHn = 1, this field can be set to any value among 0 ~ 128 + * (64*32/16 = 128). When RMT_MEM_SIZE_CHn > 1, this field can be set to any value + * among (0 ~ 128)*RMT_MEM_SIZE_CHn. + */ + uint32_t tx_lim: 9; + /** tx_loop_num : R/W; bitpos: [18:9]; default: 0; + * This field is used to configure the maximum loop times when continuous transmission + * mode is enabled. + */ + uint32_t tx_loop_num: 10; + /** tx_loop_cnt_en : R/W; bitpos: [19]; default: 0; + * This bit is used to enable loop counting. + */ + uint32_t tx_loop_cnt_en: 1; + /** loop_count_reset : WO; bitpos: [20]; default: 0; + * This bit is used to reset loop counting when continuous transmission mode is valid. + */ + uint32_t loop_count_reset: 1; + uint32_t reserved_21: 11; + }; + uint32_t val; +} rmt_chn_tx_lim_reg_t; + +/** Type of tx_sim register + * Enable RMT simultaneous transmission + */ +typedef union { + struct { + /** tx_sim_ch0 : R/W; bitpos: [0]; default: 0; + * Set this bit to enable channel 0 to start sending data simultaneously with other + * enabled channels. + */ + uint32_t tx_sim_ch0: 1; + /** tx_sim_ch1 : R/W; bitpos: [1]; default: 0; + * Set this bit to enable channel 1 to start sending data simultaneously with other + * enabled channels. + */ + uint32_t tx_sim_ch1: 1; + /** tx_sim_ch2 : R/W; bitpos: [2]; default: 0; + * Set this bit to enable channel 2 to start sending data simultaneously with other + * enabled channels. + */ + uint32_t tx_sim_ch2: 1; + /** tx_sim_ch3 : R/W; bitpos: [3]; default: 0; + * Set this bit to enable channel 3 to start sending data simultaneously with other + * enabled channels. + */ + uint32_t tx_sim_ch3: 1; + /** tx_sim_en : R/W; bitpos: [4]; default: 0; + * This bit is used to enable multiple channels to start sending data simultaneously. + */ + uint32_t en: 1; + uint32_t reserved_5: 27; + }; + uint32_t val; +} rmt_tx_sim_reg_t; + + +/** Group: Version register */ +/** Type of date register + * Version control register + */ +typedef union { + struct { + /** date : R/W; bitpos: [31:0]; default: 419898881; + * Version control register + */ + uint32_t date: 32; + }; + uint32_t val; +} rmt_date_reg_t; + + +typedef struct rmt_dev_t { + volatile rmt_chndata_reg_t data_ch[4]; + volatile struct { + volatile rmt_chnconf0_reg_t conf0; + volatile rmt_chnconf1_reg_t conf1; } conf_ch[4]; - union { - struct { - uint32_t mem_waddr_ex: 9; - uint32_t reserved9: 1; - uint32_t mem_raddr_ex: 9; - uint32_t reserved19: 1; - uint32_t state: 3; - uint32_t mem_owner_err: 1; - uint32_t mem_full: 1; - uint32_t mem_empty: 1; - uint32_t apb_mem_wr_err: 1; - uint32_t apb_mem_rd_err: 1; - uint32_t reserved28: 4; - }; - uint32_t val; - } status_ch[4]; - union { - struct { - uint32_t waddr: 9; - uint32_t reserved9: 1; - uint32_t raddr: 9; - uint32_t reserved19: 13; - }; - uint32_t val; - } apb_mem_addr_ch[4]; - union { - struct { - uint32_t ch0_tx_end: 1; - uint32_t ch0_rx_end: 1; - uint32_t ch0_err: 1; - uint32_t ch1_tx_end: 1; - uint32_t ch1_rx_end: 1; - uint32_t ch1_err: 1; - uint32_t ch2_tx_end: 1; - uint32_t ch2_rx_end: 1; - uint32_t ch2_err: 1; - uint32_t ch3_tx_end: 1; - uint32_t ch3_rx_end: 1; - uint32_t ch3_err: 1; - uint32_t ch0_tx_thr_event: 1; - uint32_t ch1_tx_thr_event: 1; - uint32_t ch2_tx_thr_event: 1; - uint32_t ch3_tx_thr_event: 1; - uint32_t ch0_tx_loop: 1; - uint32_t ch1_tx_loop: 1; - uint32_t ch2_tx_loop: 1; - uint32_t ch3_tx_loop: 1; - uint32_t ch0_rx_thr_event: 1; - uint32_t ch1_rx_thr_event: 1; - uint32_t ch2_rx_thr_event: 1; - uint32_t ch3_rx_thr_event: 1; - uint32_t reserved24: 8; - }; - uint32_t val; - } int_raw; - union { - struct { - uint32_t ch0_tx_end: 1; - uint32_t ch0_rx_end: 1; - uint32_t ch0_err: 1; - uint32_t ch1_tx_end: 1; - uint32_t ch1_rx_end: 1; - uint32_t ch1_err: 1; - uint32_t ch2_tx_end: 1; - uint32_t ch2_rx_end: 1; - uint32_t ch2_err: 1; - uint32_t ch3_tx_end: 1; - uint32_t ch3_rx_end: 1; - uint32_t ch3_err: 1; - uint32_t ch0_tx_thr_event: 1; - uint32_t ch1_tx_thr_event: 1; - uint32_t ch2_tx_thr_event: 1; - uint32_t ch3_tx_thr_event: 1; - uint32_t ch0_tx_loop: 1; - uint32_t ch1_tx_loop: 1; - uint32_t ch2_tx_loop: 1; - uint32_t ch3_tx_loop: 1; - uint32_t ch0_rx_thr_event: 1; - uint32_t ch1_rx_thr_event: 1; - uint32_t ch2_rx_thr_event: 1; - uint32_t ch3_rx_thr_event: 1; - uint32_t reserved24: 8; - }; - uint32_t val; - } int_st; - union { - struct { - uint32_t ch0_tx_end: 1; - uint32_t ch0_rx_end: 1; - uint32_t ch0_err: 1; - uint32_t ch1_tx_end: 1; - uint32_t ch1_rx_end: 1; - uint32_t ch1_err: 1; - uint32_t ch2_tx_end: 1; - uint32_t ch2_rx_end: 1; - uint32_t ch2_err: 1; - uint32_t ch3_tx_end: 1; - uint32_t ch3_rx_end: 1; - uint32_t ch3_err: 1; - uint32_t ch0_tx_thr_event: 1; - uint32_t ch1_tx_thr_event: 1; - uint32_t ch2_tx_thr_event: 1; - uint32_t ch3_tx_thr_event: 1; - uint32_t ch0_tx_loop: 1; - uint32_t ch1_tx_loop: 1; - uint32_t ch2_tx_loop: 1; - uint32_t ch3_tx_loop: 1; - uint32_t ch0_rx_thr_event: 1; - uint32_t ch1_rx_thr_event: 1; - uint32_t ch2_rx_thr_event: 1; - uint32_t ch3_rx_thr_event: 1; - uint32_t reserved24: 8; - }; - uint32_t val; - } int_ena; - union { - struct { - uint32_t ch0_tx_end: 1; - uint32_t ch0_rx_end: 1; - uint32_t ch0_err: 1; - uint32_t ch1_tx_end: 1; - uint32_t ch1_rx_end: 1; - uint32_t ch1_err: 1; - uint32_t ch2_tx_end: 1; - uint32_t ch2_rx_end: 1; - uint32_t ch2_err: 1; - uint32_t ch3_tx_end: 1; - uint32_t ch3_rx_end: 1; - uint32_t ch3_err: 1; - uint32_t ch0_tx_thr_event: 1; - uint32_t ch1_tx_thr_event: 1; - uint32_t ch2_tx_thr_event: 1; - uint32_t ch3_tx_thr_event: 1; - uint32_t ch0_tx_loop: 1; - uint32_t ch1_tx_loop: 1; - uint32_t ch2_tx_loop: 1; - uint32_t ch3_tx_loop: 1; - uint32_t ch0_rx_thr_event: 1; - uint32_t ch1_rx_thr_event: 1; - uint32_t ch2_rx_thr_event: 1; - uint32_t ch3_rx_thr_event: 1; - uint32_t reserved24: 8; - }; - uint32_t val; - } int_clr; - union { - struct { - uint32_t low: 16; - uint32_t high: 16; - }; - uint32_t val; - } carrier_duty_ch[4]; - union { - struct { - uint32_t limit: 9; - uint32_t tx_loop_num: 10; - uint32_t tx_loop_cnt_en: 1; - uint32_t loop_count_reset: 1; - uint32_t rx_lim: 9; - uint32_t reserved30: 2; - }; - uint32_t val; - } tx_lim_ch[4]; - union { - struct { - uint32_t fifo_mask: 1; - uint32_t mem_tx_wrap_en: 1; - uint32_t mem_clk_force_on: 1; - uint32_t mem_force_pd: 1; - uint32_t mem_force_pu: 1; - uint32_t reserved5: 26; - uint32_t clk_en: 1; - }; - uint32_t val; - } apb_conf; - union { - struct { - uint32_t ch0: 1; - uint32_t ch1: 1; - uint32_t ch2: 1; - uint32_t ch3: 1; - uint32_t en: 1; - uint32_t reserved5: 27; - }; - uint32_t val; - } tx_sim; - union { - struct { - uint32_t ch0: 1; - uint32_t ch1: 1; - uint32_t ch2: 1; - uint32_t ch3: 1; - uint32_t reserved4: 28; - }; - uint32_t val; - } ref_cnt_rst; - union { - struct { - uint32_t carrier_low_thres_ch: 16; - uint32_t carrier_high_thres_ch:16; - }; - uint32_t val; - } ch_rx_carrier_rm[4]; - uint32_t reserved_9c; - uint32_t reserved_a0; - uint32_t reserved_a4; - uint32_t reserved_a8; - uint32_t reserved_ac; - uint32_t reserved_b0; - uint32_t reserved_b4; - uint32_t reserved_b8; - uint32_t reserved_bc; - uint32_t reserved_c0; - uint32_t reserved_c4; - uint32_t reserved_c8; - uint32_t reserved_cc; - uint32_t reserved_d0; - uint32_t reserved_d4; - uint32_t reserved_d8; - uint32_t reserved_dc; - uint32_t reserved_e0; - uint32_t reserved_e4; - uint32_t reserved_e8; - uint32_t reserved_ec; - uint32_t reserved_f0; - uint32_t reserved_f4; - uint32_t reserved_f8; - uint32_t date; /* Version Control Register */ + volatile rmt_chnstatus_reg_t status_ch[4]; + volatile rmt_chnaddr_reg_t apb_mem_addr_ch[4]; + volatile rmt_int_raw_reg_t int_raw; + volatile rmt_int_st_reg_t int_st; + volatile rmt_int_ena_reg_t int_ena; + volatile rmt_int_clr_reg_t int_clr; + volatile rmt_chncarrier_duty_reg_t carrier_duty_ch[4]; + volatile rmt_chn_tx_lim_reg_t tx_lim_ch[4]; + volatile rmt_apb_conf_reg_t apb_conf; + volatile rmt_tx_sim_reg_t tx_sim; + volatile rmt_ref_cnt_rst_reg_t ref_cnt_rst; + volatile rmt_chn_rx_carrier_rm_reg_t ch_rx_carrier_rm[4]; + uint32_t reserved_09c[24]; + volatile rmt_date_reg_t date; } rmt_dev_t; + + +#ifndef __cplusplus +_Static_assert(sizeof(rmt_dev_t) == 0x100, "Invalid size of rmt_dev_t structure"); +#endif + extern rmt_dev_t RMT; typedef struct { @@ -305,10 +820,9 @@ typedef volatile struct rmt_mem_s { rmt_item32_t data32[64]; } chan[4]; } rmt_mem_t; + extern rmt_mem_t RMTMEM; #ifdef __cplusplus } #endif - -#endif /* _SOC_RMT_STRUCT_H_ */ diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index ed8aa86ed643..82bbf3c97420 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -54,6 +54,7 @@ #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 #define SOC_CACHE_SUPPORT_WRAP 1 +#define SOC_PSRAM_DMA_CAPABLE 1 /*-------------------------- ADC CAPS ----------------------------------------*/ #define SOC_ADC_PERIPH_NUM (2) @@ -93,18 +94,18 @@ /*-------------------------- GPIO CAPS ---------------------------------------*/ // ESP32-S2 has 1 GPIO peripheral #define SOC_GPIO_PORT (1) -#define SOC_GPIO_PIN_COUNT (48) +#define SOC_GPIO_PIN_COUNT (47) -// On ESP32 those PADs which have RTC functions must set pullup/down/capability via RTC register. +// On ESP32-S2 those PADs which have RTC functions must set pullup/down/capability via RTC register. // On ESP32-S2, Digital IOs have their own registers to control pullup/down/capability, independent with RTC registers. #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) // Force hold is a new function of ESP32-S2 #define SOC_GPIO_SUPPORT_FORCE_HOLD (1) -// 0~47 except from 22~25, 47 are valid -#define SOC_GPIO_VALID_GPIO_MASK (0xFFFFFFFFFFFFULL & ~(0ULL | BIT22 | BIT23 | BIT24 | BIT25 | BIT47)) -// GPIO 46, 47 are input only -#define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT46 | BIT47)) +// 0~46 except from 22~25 are valid +#define SOC_GPIO_VALID_GPIO_MASK (0x7FFFFFFFFFFFULL & ~(0ULL | BIT22 | BIT23 | BIT24 | BIT25)) +// GPIO 46 is input only +#define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT46)) // Support to configure slept status #define SOC_GPIO_SUPPORT_SLP_SWITCH (1) @@ -121,8 +122,7 @@ #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ -//ESP32-S2 support hardware FSM reset -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. //ESP32-S2 support hardware clear bus #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) @@ -165,7 +165,6 @@ #define SOC_RMT_TX_CHANNELS_NUM (4) /*!< Number of channels that capable of Transmit */ #define SOC_RMT_RX_CHANNELS_NUM (4) /*!< Number of channels that capable of Receive */ #define SOC_RMT_CHANNELS_NUM (4) /*!< Total 4 channels (each channel can be configured to either TX or RX) */ -#define SOC_RMT_SUPPORT_RX_PINGPONG (1) /*!< Support Ping-Pong mode on RX path */ #define SOC_RMT_SUPPORT_RX_DEMODULATION (1) /*!< Support signal demodulation on RX path (i.e. remove carrier) */ #define SOC_RMT_SUPPORT_TX_LOOP_COUNT (1) /*!< Support transmit specified number of cycles in loop mode */ #define SOC_RMT_SUPPORT_TX_GROUP (1) /*!< Support a group of TX channels to transmit simultaneously */ diff --git a/components/soc/esp32s2/include/soc/uart_channel.h b/components/soc/esp32s2/include/soc/uart_channel.h index 5b8dc56d5ae2..ae5c84fb45cb 100644 --- a/components/soc/esp32s2/include/soc/uart_channel.h +++ b/components/soc/esp32s2/include/soc/uart_channel.h @@ -1,61 +1,41 @@ -// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// This file defines GPIO lookup macros for available UART IO_MUX pins on ESP32S2. #ifndef _SOC_UART_CHANNEL_H #define _SOC_UART_CHANNEL_H //UART channels -#define UART_GPIO1_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 1 -#define UART_GPIO3_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 3 -#define UART_GPIO19_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_CTS_DIRECT_GPIO_NUM 19 -#define UART_GPIO22_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RTS_DIRECT_GPIO_NUM 22 - -#define UART_TXD_GPIO1_DIRECT_CHANNEL UART_GPIO1_DIRECT_CHANNEL -#define UART_RXD_GPIO3_DIRECT_CHANNEL UART_GPIO3_DIRECT_CHANNEL -#define UART_CTS_GPIO19_DIRECT_CHANNEL UART_GPIO19_DIRECT_CHANNEL -#define UART_RTS_GPIO22_DIRECT_CHANNEL UART_GPIO22_DIRECT_CHANNEL - -#define UART_GPIO10_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_TXD_DIRECT_GPIO_NUM 10 -#define UART_GPIO9_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_RXD_DIRECT_GPIO_NUM 9 -#define UART_GPIO6_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_CTS_DIRECT_GPIO_NUM 6 -#define UART_GPIO11_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_RTS_DIRECT_GPIO_NUM 11 - -#define UART_TXD_GPIO10_DIRECT_CHANNEL UART_GPIO10_DIRECT_CHANNEL -#define UART_RXD_GPIO9_DIRECT_CHANNEL UART_GPIO9_DIRECT_CHANNEL -#define UART_CTS_GPIO6_DIRECT_CHANNEL UART_GPIO6_DIRECT_CHANNEL -#define UART_RTS_GPIO11_DIRECT_CHANNEL UART_GPIO11_DIRECT_CHANNEL - -#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_TXD_DIRECT_GPIO_NUM 17 -#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_RXD_DIRECT_GPIO_NUM 16 -#define UART_GPIO8_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_CTS_DIRECT_GPIO_NUM 8 -#define UART_GPIO7_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_RTS_DIRECT_GPIO_NUM 7 +#define UART_GPIO43_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 43 +#define UART_GPIO44_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 44 +#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_CTS_DIRECT_GPIO_NUM 16 +#define UART_GPIO15_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RTS_DIRECT_GPIO_NUM 15 + +#define UART_TXD_GPIO43_DIRECT_CHANNEL UART_GPIO43_DIRECT_CHANNEL +#define UART_RXD_GPIO44_DIRECT_CHANNEL UART_GPIO44_DIRECT_CHANNEL +#define UART_CTS_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL +#define UART_RTS_GPIO15_DIRECT_CHANNEL UART_GPIO15_DIRECT_CHANNEL + +#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_TXD_DIRECT_GPIO_NUM 17 +#define UART_GPIO18_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_RXD_DIRECT_GPIO_NUM 18 +#define UART_GPIO20_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_CTS_DIRECT_GPIO_NUM 20 +#define UART_GPIO19_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_RTS_DIRECT_GPIO_NUM 19 #define UART_TXD_GPIO17_DIRECT_CHANNEL UART_GPIO17_DIRECT_CHANNEL -#define UART_RXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL -#define UART_CTS_GPIO8_DIRECT_CHANNEL UART_GPIO8_DIRECT_CHANNEL -#define UART_RTS_GPIO7_DIRECT_CHANNEL UART_GPIO7_DIRECT_CHANNEL +#define UART_RXD_GPIO18_DIRECT_CHANNEL UART_GPIO18_DIRECT_CHANNEL +#define UART_CTS_GPIO20_DIRECT_CHANNEL UART_GPIO20_DIRECT_CHANNEL +#define UART_RTS_GPIO19_DIRECT_CHANNEL UART_GPIO19_DIRECT_CHANNEL #endif diff --git a/components/soc/esp32s2/include/soc/usb_struct.h b/components/soc/esp32s2/include/soc/usb_struct.h index e387490e9f42..14277b10e886 100644 --- a/components/soc/esp32s2/include/soc/usb_struct.h +++ b/components/soc/esp32s2/include/soc/usb_struct.h @@ -22,82 +22,81 @@ extern "C" { #endif typedef struct usb_reg { - volatile uint32_t gotgctl; /*!< 0x0 */ - volatile uint32_t gotgint; - volatile uint32_t gahbcfg; - volatile uint32_t gusbcfg; - volatile uint32_t grstctl; /*!< 0x10 */ - volatile uint32_t gintsts; - volatile uint32_t gintmsk; - volatile uint32_t grxstsr; - volatile uint32_t grxstsp; /*!< 0x20 */ - volatile uint32_t grxfsiz; - volatile uint32_t gnptxfsiz; - volatile uint32_t gnptxsts; - volatile uint32_t reserved0x2c; - volatile uint32_t gpvndctl; /*!< 0x30 */ - volatile uint32_t ggpio; - volatile uint32_t guid; - volatile uint32_t gsnpsid; - volatile uint32_t ghwcfg1; /*!< 0x40 */ - volatile uint32_t ghwcfg2; - volatile uint32_t ghwcfg3; - volatile uint32_t ghwcfg4; /*!< 0x50 */ - volatile uint32_t glpmcfg; /*!< 0x54 */ - volatile uint32_t gpwrdn; /*!< 0x58 */ - volatile uint32_t gdfifocfg; /*!< 0x5c */ - volatile uint32_t gadpctl; /*!< 0x60 */ - uint32_t reserved0x64[39]; - volatile uint32_t hptxfsiz; /*!< 0x100 */ - volatile uint32_t dieptxf[15]; /*!< 0x104 */ - uint32_t reserved0x140[176]; /*!< 0x140 */ + volatile uint32_t gotgctl; // 0x0000 OTG Control and Status Register + volatile uint32_t gotgint; // 0x0004 OTG Interrupt Register + volatile uint32_t gahbcfg; // 0x0008 AHB Configuration Register + volatile uint32_t gusbcfg; // 0x000c USB Configuration Register + volatile uint32_t grstctl; // 0x0010 Reset Register + volatile uint32_t gintsts; // 0x0014 Interrupt Register + volatile uint32_t gintmsk; // 0x0018 Interrupt Mask Register + volatile uint32_t grxstsr; // 0x001c Receive Status Debug Read Register + volatile uint32_t grxstsp; // 0x0020 Receive Status Read/Pop Register + volatile uint32_t grxfsiz; // 0x0024 Receive FIFO Size Register + volatile uint32_t gnptxfsiz; // 0x0028 Non-periodic Transmit FIFO Size Register + volatile uint32_t gnptxsts; // 0x002c Non-periodic Transmit FIFO/Queue Status Register + uint32_t reserved_0x0030_0x0040[4]; // 0x0030 to 0x0040 + volatile uint32_t gsnpsid; // 0x0040 Synopsys ID Register + volatile uint32_t ghwcfg1; // 0x0044 User Hardware Configuration 1 Register + volatile uint32_t ghwcfg2; // 0x0048 User Hardware Configuration 2 Register + volatile uint32_t ghwcfg3; // 0x004c User Hardware Configuration 3 Register + volatile uint32_t ghwcfg4; // 0x0050 User Hardware Configuration 4 Register + uint32_t reserved_0x0054_0x005c[2]; // 0x0054 to 0x005c + volatile uint32_t gdfifocfg; // 0x005c Global DFIFO Configuration Register + uint32_t reserved_0x0060_0x0100[40]; // 0x0060 to 0x0100 + volatile uint32_t hptxfsiz; // 0x0100 Host Periodic Transmit FIFO Size Register + volatile uint32_t dieptxf[4]; // 0x0104 to 0x0114 Device IN Endpoint Transmit FIFO Size Register i + uint32_t reserved_0x0114_0x0140[11]; // 0x0114 to 0x0140 + uint32_t reserved_0x0140_0x0400[176]; // 0x0140 to 0x0400 /** - * The Host Global Registers structure defines the size and relative - * field offsets for the Host Mode Global Registers. Host Global - * Registers offsets 400h-7FFh. - */ - volatile uint32_t hcfg; /*!< Host Configuration Register. Offset: 400h */ - volatile uint32_t hfir; /*!< Host Frame Interval Register. Offset: 404h */ - volatile uint32_t hfnum; /*!< Host Frame Number / Frame Remaining Register. Offset: 408h */ - uint32_t reserved0x40C; /*!< Reserved. Offset: 40Ch */ - volatile uint32_t hptxsts; /*!< Host Periodic Transmit FIFO/ Queue Status Register. Offset: 410h */ - volatile uint32_t haint; /*!< Host All Channels Interrupt Register. Offset: 414h */ - volatile uint32_t haintmsk; /*!< Host All Channels Interrupt Mask Register. Offset: 418h */ - volatile uint32_t hflbaddr; /*!< Host Frame List Base Address Register . Offset: 41Ch */ - uint32_t reserved0x420[7]; - volatile uint32_t hprt; //0x440 - uint32_t reserved0x444[240]; - volatile uint32_t dcfg; /*!< Device Configuration Register. Offset 800h */ - volatile uint32_t dctl; /*!< Device Control Register. Offset: 804h */ - volatile uint32_t dsts; /*!< Device Status Register (Read Only). Offset: 808h */ - uint32_t reserved0x80c; /*!< Reserved. Offset: 80Ch */ - volatile uint32_t diepmsk; /*!< Device IN Endpoint Common Interrupt Mask Register. Offset: 810h */ - volatile uint32_t doepmsk; /*!< Device OUT Endpoint Common Interrupt Mask Register. Offset: 814h */ - volatile uint32_t daint; /*!< Device All Endpoints Interrupt Register. Offset: 818h */ - volatile uint32_t daintmsk; /*!< Device All Endpoints Interrupt Mask Register. Offset: 81Ch */ - volatile uint32_t dtknqr1; /*!< Device IN Token Queue Read Register-1 (Read Only). Offset: 820h */ - volatile uint32_t dtknqr2; /*!< Device IN Token Queue Read Register-2 (Read Only). Offset: 824h */ - volatile uint32_t dvbusdis; /*!< Device VBUS discharge Register. Offset: 828h */ - volatile uint32_t dvbuspulse; /*!< Device VBUS Pulse Register. Offset: 82Ch */ - volatile uint32_t dtknqr3_dthrctl; /*!< Device IN Token Queue Read Register-3 (Read Only). Device Thresholding control register (Read/Write) Offset: 830h */ - volatile uint32_t dtknqr4_fifoemptymsk; /*!< Device IN Token Queue Read Register-4 (Read Only). Device IN EPs empty Inr. Mask Register (Read/Write)Offset: 834h */ - volatile uint32_t deachint; /*!< Device Each Endpoint Interrupt Register (Read Only). Offset: 838h */ - volatile uint32_t deachintmsk; /*!< Device Each Endpoint Interrupt mask Register (Read/Write). Offset: 83Ch */ - volatile uint32_t diepeachintmsk[16]; /*!< Device Each In Endpoint Interrupt mask Register (Read/Write). Offset: 840h */ - volatile uint32_t doepeachintmsk[16]; /*!< Device Each Out Endpoint Interrupt mask Register (Read/Write). Offset: 880h */ - uint32_t reserved0x8c0[16]; - /* Input Endpoints*/ - usb_in_endpoint_t in_ep_reg[USB_IN_EP_NUM]; /*!< 0x900*/ - uint32_t reserved6[72]; - /* Output Endpoints */ - usb_out_endpoint_t out_ep_reg[USB_OUT_EP_NUM]; - uint32_t reserved7[136]; - uint32_t pcgctrl; /*!<0xe00*/ - uint32_t pcgctrl1; - uint8_t reserved8[0x1000 - 0xe08]; /*!<0xd00*/ - uint32_t fifo[16][0x400]; /*!<0x1000*/ + * Host mode registers offsets from 0x0400 to 0x07FF + */ + volatile uint32_t hcfg; // 0x0400 Host Configuration Register + volatile uint32_t hfir; // 0x0404 Host Frame Interval Register + volatile uint32_t hfnum; // 0x0408 Host Frame Number/Frame Remaining Register + uint32_t reserved0x40C; // 0x040c Reserved + volatile uint32_t hptxsts; // 0x0410 Host Periodic Transmit FIFO/ Queue Status Register + volatile uint32_t haint; // 0x0414 Host All Channels Interrupt Register + volatile uint32_t haintmsk; // 0x0418 Host All Channels Interrupt Mask Register + volatile uint32_t hflbaddr; // 0x041c Host Frame List Base Address Register + uint32_t reserved0x0420_0x0440[8]; // 0x0420 to 0x0440 + volatile uint32_t hprt; // 0x0440 Host Port Control and Status Register + uint32_t reserved_0x0444_0x0500[47]; // 0x0444 to 0x0500 + //Skip over the host channel registers + volatile uint32_t host_chan_regs[128]; // 0x0500 to 0x0700 + uint32_t reserved_0x0700_0x0800[64]; // 0x0700 to 0x0800 + /** + * Device mode registers offsets from + */ + volatile uint32_t dcfg; // 0x0800 Device Configuration Register + volatile uint32_t dctl; // 0x0804 Device Control Register + volatile uint32_t dsts; // 0x0808 Device Status Register (Read Only) + uint32_t reserved0x80c; // 0x080c + volatile uint32_t diepmsk; // 0x0810 Device IN Endpoint Common Interrupt Mask Register + volatile uint32_t doepmsk; // 0x0814 Device OUT Endpoint Common Interrupt Mask Register + volatile uint32_t daint; // 0x0818 Device All Endpoints Interrupt Register + volatile uint32_t daintmsk; // 0x081c Device All Endpoints Interrupt Mask Register + uint32_t reserved_0x0820_0x0828[2]; // 0x0820 to 0x0828 + volatile uint32_t dvbusdis; // 0x0828 Device VBUS discharge Register + volatile uint32_t dvbuspulse; // 0x082c Device VBUS Pulse Register + volatile uint32_t dthrctl; // 0x0830 Device Thresholding control register (Read/Write) + volatile uint32_t dtknqr4_fifoemptymsk; // 0x0834 Device IN Endpoint FIFO Empty Interrupt Mask register + uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900 + // Input Endpoints + usb_in_endpoint_t in_ep_reg[USB_IN_EP_NUM]; // 0x0900 to 0x09e0 IN EP registers + uint32_t reserved_0x09e0_0x0b00[72]; // 0x09e0 to 0x0b00 + // Output Endpoints + usb_out_endpoint_t out_ep_reg[USB_OUT_EP_NUM]; // 0x0b00 to 0x0be0 OUT EP registers + uint32_t reserved_0x0be0_0x0d00[72]; // 0x0be0 to 0x0d00 + uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00 + /** + * Power Control and direct FIFO access + */ + uint32_t pcgctrl; // 0x0e00 Power and Clock Gating Control Register + uint32_t reserved_0x0e04; // 0x0e04 + uint8_t reserved8[0x1000 - 0xe08]; // 0x0d00 to 0x1000 + uint32_t fifo[16][0x400]; // 0x1000 to 0x2000 Device EP i/Host Channel i FIFO uint8_t reserved0x11000[0x20000 - 0x11000]; - uint32_t dbg_fifo[0x20000]; /*!< 0x20000*/ + uint32_t dbg_fifo[0x20000]; // 0x2000 to 0x22000 Direct Access to Data FIFO RAM for Debugging } usb_dev_t; extern usb_dev_t USB0; diff --git a/components/soc/esp32s2/rtc_io_periph.c b/components/soc/esp32s2/rtc_io_periph.c index 63828d8d25ad..217361070b67 100644 --- a/components/soc/esp32s2/rtc_io_periph.c +++ b/components/soc/esp32s2/rtc_io_periph.c @@ -62,7 +62,6 @@ const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = { -1,//GPIO44 -1,//GPIO45 -1,//GPIO46 - -1,//GPIO47 }; //Reg,Mux,Fun,IE,Up,Down,Rtc_number diff --git a/components/soc/esp32s3/include/soc/efuse_reg.h b/components/soc/esp32s3/include/soc/efuse_reg.h index 34bd0eea00f2..bd2112fa96e3 100644 --- a/components/soc/esp32s3/include/soc/efuse_reg.h +++ b/components/soc/esp32s3/include/soc/efuse_reg.h @@ -319,11 +319,17 @@ extern "C" { #define EFUSE_KEY_PURPOSE_2_S 0 #define EFUSE_PGM_DATA4_REG (DR_REG_EFUSE_BASE + 0x010) -/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[31:30] ;default: 2'h0 ; */ +/* EFUSE_DIS_USB_OTG_DOWNLOAD_MODE : RO ;bitpos:[31] ;default: 1'h0 ; */ +/*description: Set this bit to disable download through USB-OTG*/ +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE (BIT(31)) +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_M (BIT(31)) +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_V 0x1 +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_S 31 +/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[30] ;default: 1'h0 ; */ /*description: Reserved (used for four backups method).*/ -#define EFUSE_RPT4_RESERVED1 0x00000003 -#define EFUSE_RPT4_RESERVED1_M ((EFUSE_RPT4_RESERVED1_V)<<(EFUSE_RPT4_RESERVED1_S)) -#define EFUSE_RPT4_RESERVED1_V 0x3 +#define EFUSE_RPT4_RESERVED1 (BIT(30)) +#define EFUSE_RPT4_RESERVED1_M (BIT(30)) +#define EFUSE_RPT4_RESERVED1_V 0x1 #define EFUSE_RPT4_RESERVED1_S 30 /* EFUSE_SECURE_VERSION : R/W ;bitpos:[29:14] ;default: 16'h0 ; */ /*description: Secure version (used by ESP-IDF anti-rollback feature).*/ @@ -374,12 +380,12 @@ extern "C" { #define EFUSE_ENABLE_SECURITY_DOWNLOAD_M (BIT(5)) #define EFUSE_ENABLE_SECURITY_DOWNLOAD_V 0x1 #define EFUSE_ENABLE_SECURITY_DOWNLOAD_S 5 -/* EFUSE_DIS_USB_DOWNLOAD_MODE : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/* EFUSE_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE : R/W ;bitpos:[4] ;default: 1'b0 ; */ /*description: Set this bit to disable download through USB.*/ -#define EFUSE_DIS_USB_DOWNLOAD_MODE (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_M (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_V 0x1 -#define EFUSE_DIS_USB_DOWNLOAD_MODE_S 4 +#define EFUSE_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BIT(4)) +#define EFUSE_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_M (BIT(4)) +#define EFUSE_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_V 0x1 +#define EFUSE_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_S 4 /* EFUSE_FLASH_ECC_MODE : R/W ;bitpos:[3] ;default: 1'b0 ; */ /*description: Set this bit to set flsah ecc mode. 0:flash ecc 16to18 byte mode. 1:flash ecc 16to17 byte mode.*/ @@ -387,18 +393,18 @@ extern "C" { #define EFUSE_FLASH_ECC_MODE_M (BIT(3)) #define EFUSE_FLASH_ECC_MODE_V 0x1 #define EFUSE_FLASH_ECC_MODE_S 3 -/* EFUSE_UART_PRINT_CHANNEL : R/W ;bitpos:[2] ;default: 1'b0 ; */ -/*description: Selectes UART print channel. 0: UART0 1: UART1.*/ -#define EFUSE_UART_PRINT_CHANNEL (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_M (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_V 0x1 -#define EFUSE_UART_PRINT_CHANNEL_S 2 -/* EFUSE_DIS_LEGACY_SPI_BOOT : R/W ;bitpos:[1] ;default: 1'b0 ; */ +/* EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT : R/W ;bitpos:[2] ;default: 1'b0 ; */ +/*description: The value of DIS_USB_SERIAL_JTAG_ROM_PRINT.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_M (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_S 2 +/* EFUSE_DIS_DIRECT_BOOT : R/W ;bitpos:[1] ;default: 1'b0 ; */ /*description: Set this bit to disable Legacy SPI boot mode (boot_mode[3:0] = 4).*/ -#define EFUSE_DIS_LEGACY_SPI_BOOT (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_M (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_V 0x1 -#define EFUSE_DIS_LEGACY_SPI_BOOT_S 1 +#define EFUSE_DIS_DIRECT_BOOT (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_M (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_V 0x1 +#define EFUSE_DIS_DIRECT_BOOT_S 1 /* EFUSE_DIS_DOWNLOAD_MODE : R/W ;bitpos:[0] ;default: 1'b0 ; */ /*description: Set this bit to disable download mode (boot_mode[3:0] = 0 1 2 3 6 7).*/ #define EFUSE_DIS_DOWNLOAD_MODE (BIT(0)) @@ -744,12 +750,18 @@ extern "C" { #define EFUSE_KEY_PURPOSE_2_V 0xF #define EFUSE_KEY_PURPOSE_2_S 0 -#define EFUSE_RD_REPEAT_DATA3_REG (DR_REG_EFUSE_BASE + 0x03C) -/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[31:30] ;default: 2'h0 ; */ -/*description: Reserved.*/ -#define EFUSE_RPT4_RESERVED1 0x00000003 -#define EFUSE_RPT4_RESERVED1_M ((EFUSE_RPT4_RESERVED1_V)<<(EFUSE_RPT4_RESERVED1_S)) -#define EFUSE_RPT4_RESERVED1_V 0x3 +#define EFUSE_RD_REPEAT_DATA3_REG (DR_REG_EFUSE_BASE + 0x3C) +/* EFUSE_DIS_USB_OTG_DOWNLOAD_MODE : RO ;bitpos:[31] ;default: 1'h0 ; */ +/*description: Set this bit to disable download through USB-OTG*/ +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE (BIT(31)) +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_M (BIT(31)) +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_V 0x1 +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_S 31 +/* EFUSE_RPT4_RESERVED1 : RO ;bitpos:[30] ;default: 1'h0 ; */ +/*description: Reserved (used for four backups method).*/ +#define EFUSE_RPT4_RESERVED1 (BIT(30)) +#define EFUSE_RPT4_RESERVED1_M (BIT(30)) +#define EFUSE_RPT4_RESERVED1_V 0x1 #define EFUSE_RPT4_RESERVED1_S 30 /* EFUSE_SECURE_VERSION : RO ;bitpos:[29:14] ;default: 16'h0 ; */ /*description: The value of SECURE_VERSION.*/ @@ -799,30 +811,30 @@ extern "C" { #define EFUSE_ENABLE_SECURITY_DOWNLOAD_M (BIT(5)) #define EFUSE_ENABLE_SECURITY_DOWNLOAD_V 0x1 #define EFUSE_ENABLE_SECURITY_DOWNLOAD_S 5 -/* EFUSE_DIS_USB_DOWNLOAD_MODE : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: The value of DIS_USB_DOWNLOAD_MODE.*/ -#define EFUSE_DIS_USB_DOWNLOAD_MODE (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_M (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_V 0x1 -#define EFUSE_DIS_USB_DOWNLOAD_MODE_S 4 +/* EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE : RO ;bitpos:[4] ;default: 1'b0 ; */ +/*description: Set this bit to disable download through USB-Seial-JTAG.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_M (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_S 4 /* EFUSE_FLASH_ECC_MODE : RO ;bitpos:[3] ;default: 1'b0 ; */ /*description: The value of FLASH_ECC_MODE.*/ #define EFUSE_FLASH_ECC_MODE (BIT(3)) #define EFUSE_FLASH_ECC_MODE_M (BIT(3)) #define EFUSE_FLASH_ECC_MODE_V 0x1 #define EFUSE_FLASH_ECC_MODE_S 3 -/* EFUSE_UART_PRINT_CHANNEL : RO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: The value of UART_PRINT_CHANNEL.*/ -#define EFUSE_UART_PRINT_CHANNEL (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_M (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_V 0x1 -#define EFUSE_UART_PRINT_CHANNEL_S 2 -/* EFUSE_DIS_LEGACY_SPI_BOOT : RO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: The value of DIS_LEGACY_SPI_BOOT.*/ -#define EFUSE_DIS_LEGACY_SPI_BOOT (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_M (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_V 0x1 -#define EFUSE_DIS_LEGACY_SPI_BOOT_S 1 +/* EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT : RO ;bitpos:[2] ;default: 1'b0 ; */ +/*description: Disable USB-Serial-JTAG print during rom boot.*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_M (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_S 2 +/* EFUSE_DIS_DIRECT_BOOT : RO ;bitpos:[1] ;default: 1'b0 ; */ +/*description: Set this bit to disable direct boot.*/ +#define EFUSE_DIS_DIRECT_BOOT (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_M (BIT(1)) +#define EFUSE_DIS_DIRECT_BOOT_V 0x1 +#define EFUSE_DIS_DIRECT_BOOT_S 1 /* EFUSE_DIS_DOWNLOAD_MODE : RO ;bitpos:[0] ;default: 1'b0 ; */ /*description: The value of DIS_DOWNLOAD_MODE.*/ #define EFUSE_DIS_DOWNLOAD_MODE (BIT(0)) @@ -1757,11 +1769,17 @@ extern "C" { #define EFUSE_KEY_PURPOSE_2_ERR_S 0 #define EFUSE_RD_REPEAT_ERR3_REG (DR_REG_EFUSE_BASE + 0x188) -/* EFUSE_RPT4_RESERVED1_ERR : RO ;bitpos:[31:30] ;default: 2'h0 ; */ +/* EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_ERR : RO ;bitpos:[31] ;default: 1'h0 ; */ +/*description: Set this bit to disable download through USB-OTG.*/ +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_ERR (BIT(31)) +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_ERR_M (BIT(31)) +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_ERR_V 0x1 +#define EFUSE_DIS_USB_OTG_DOWNLOAD_MODE_ERR_S 31 +/* EFUSE_RPT4_RESERVED1_ERR : RO ;bitpos:[30] ;default: 1'h0 ; */ /*description: Reserved.*/ -#define EFUSE_RPT4_RESERVED1_ERR 0x00000003 -#define EFUSE_RPT4_RESERVED1_ERR_M ((EFUSE_RPT4_RESERVED1_ERR_V)<<(EFUSE_RPT4_RESERVED1_ERR_S)) -#define EFUSE_RPT4_RESERVED1_ERR_V 0x3 +#define EFUSE_RPT4_RESERVED1_ERR (BIT(30)) +#define EFUSE_RPT4_RESERVED1_ERR_M (BIT(30)) +#define EFUSE_RPT4_RESERVED1_ERR_V 0x1 #define EFUSE_RPT4_RESERVED1_ERR_S 30 /* EFUSE_SECURE_VERSION_ERR : RO ;bitpos:[29:14] ;default: 16'h0 ; */ /*description: If any bit in SECURE_VERSION is 1 then it indicates a programming error.*/ @@ -1811,30 +1829,25 @@ extern "C" { #define EFUSE_ENABLE_SECURITY_DOWNLOAD_ERR_M (BIT(5)) #define EFUSE_ENABLE_SECURITY_DOWNLOAD_ERR_V 0x1 #define EFUSE_ENABLE_SECURITY_DOWNLOAD_ERR_S 5 -/* EFUSE_DIS_USB_DOWNLOAD_MODE_ERR : RO ;bitpos:[4] ;default: 1'b0 ; */ -/*description: If DIS_USB_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR_M (BIT(4)) -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR_V 0x1 -#define EFUSE_DIS_USB_DOWNLOAD_MODE_ERR_S 4 +/* EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR : RO ;bitpos:[4] ;default: 1'b0 ; */ +/*description: If any bits in this filed are 1, then it indicates a programming error..*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR_M (BIT(4)) +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE_ERR_S 4 /* EFUSE_FLASH_ECC_MODE_ERR : RO ;bitpos:[3] ;default: 1'b0 ; */ /*description: If FLASH_ECC_MODE is 1*/ #define EFUSE_FLASH_ECC_MODE_ERR (BIT(3)) #define EFUSE_FLASH_ECC_MODE_ERR_M (BIT(3)) #define EFUSE_FLASH_ECC_MODE_ERR_V 0x1 #define EFUSE_FLASH_ECC_MODE_ERR_S 3 -/* EFUSE_UART_PRINT_CHANNEL_ERR : RO ;bitpos:[2] ;default: 1'b0 ; */ -/*description: If UART_PRINT_CHANNEL is 1 then it indicates a programming error.*/ -#define EFUSE_UART_PRINT_CHANNEL_ERR (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_ERR_M (BIT(2)) -#define EFUSE_UART_PRINT_CHANNEL_ERR_V 0x1 -#define EFUSE_UART_PRINT_CHANNEL_ERR_S 2 -/* EFUSE_DIS_LEGACY_SPI_BOOT_ERR : RO ;bitpos:[1] ;default: 1'b0 ; */ -/*description: If DIS_LEGACY_SPI_BOOT is 1 then it indicates a programming error.*/ -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR_M (BIT(1)) -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR_V 0x1 -#define EFUSE_DIS_LEGACY_SPI_BOOT_ERR_S 1 +/* EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR : RO ;bitpos:[2] ;default: 1'b0 ; */ +/*description: If any bits in this filed are 1, then it indicates a programming error..*/ +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR_M (BIT(2)) +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR_V 0x1 +#define EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT_ERR_S 2 + /* EFUSE_DIS_DOWNLOAD_MODE_ERR : RO ;bitpos:[0] ;default: 1'b0 ; */ /*description: If DIS_DOWNLOAD_MODE is 1 then it indicates a programming error.*/ #define EFUSE_DIS_DOWNLOAD_MODE_ERR (BIT(0)) diff --git a/components/soc/esp32s3/include/soc/gpio_struct.h b/components/soc/esp32s3/include/soc/gpio_struct.h index ff589aac9b50..fdcca9a0386f 100644 --- a/components/soc/esp32s3/include/soc/gpio_struct.h +++ b/components/soc/esp32s3/include/soc/gpio_struct.h @@ -115,20 +115,20 @@ typedef volatile struct { }; uint32_t val; } status1_w1tc; - uint32_t pcpu_int; /**/ - uint32_t pcpu_nmi_int; /**/ - uint32_t cpusdio_int; /**/ + uint32_t pcpu_int; /*GPIO0~31 PRO & APP CPU interrupt status*/ + uint32_t pcpu_nmi_int; /*GPIO0~31 PRO & APP CPU non-maskable interrupt status*/ + uint32_t cpusdio_int; union { struct { - uint32_t intr: 22; - uint32_t reserved22: 10; + uint32_t intr : 22; /*GPIO32-48 PRO & APP CPU interrupt status*/ + uint32_t reserved22 : 10; }; uint32_t val; } pcpu_int1; union { struct { - uint32_t intr: 22; - uint32_t reserved22: 10; + uint32_t intr : 22; /*GPIO32-48 PRO & APP CPU non-maskable interrupt status*/ + uint32_t reserved22 : 10; }; uint32_t val; } pcpu_nmi_int1; diff --git a/components/soc/esp32s3/include/soc/i2c_caps.h b/components/soc/esp32s3/include/soc/i2c_caps.h index 71ef195bb026..6e566ca01a3b 100644 --- a/components/soc/esp32s3/include/soc/i2c_caps.h +++ b/components/soc/esp32s3/include/soc/i2c_caps.h @@ -23,8 +23,7 @@ extern "C" { #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ -//ESP32-S3 support hardware FSM reset -#define SOC_I2C_SUPPORT_HW_FSM_RST (1) +// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined. //ESP32-S3 support hardware clear bus #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 38c53510ee85..eb6ee1ca38fa 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -19,6 +19,7 @@ #define SOC_DIG_SIGN_SUPPORTED 1 #define SOC_HMAC_SUPPORTED 1 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 +#define SOC_PSRAM_DMA_CAPABLE 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 /*-------------------------- ADC CAPS ----------------------------------------*/ @@ -107,6 +108,7 @@ #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ +#define SOC_UART_REQUIRE_CORE_RESET (1) /*--------------------------- SHA CAPS ---------------------------------------*/ /* Max amount of bytes in a single DMA operation is 4095, diff --git a/components/soc/esp32s3/include/soc/uart_channel.h b/components/soc/esp32s3/include/soc/uart_channel.h index 0475fd3b5feb..1b8b41da0018 100644 --- a/components/soc/esp32s3/include/soc/uart_channel.h +++ b/components/soc/esp32s3/include/soc/uart_channel.h @@ -1,58 +1,38 @@ -// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// This file defines GPIO lookup macros for available UART IO_MUX pins on ESP32S3. #pragma once //UART channels -#define UART_GPIO1_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 1 -#define UART_GPIO3_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 3 -#define UART_GPIO19_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_CTS_DIRECT_GPIO_NUM 19 -#define UART_GPIO22_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RTS_DIRECT_GPIO_NUM 22 - -#define UART_TXD_GPIO1_DIRECT_CHANNEL UART_GPIO1_DIRECT_CHANNEL -#define UART_RXD_GPIO3_DIRECT_CHANNEL UART_GPIO3_DIRECT_CHANNEL -#define UART_CTS_GPIO19_DIRECT_CHANNEL UART_GPIO19_DIRECT_CHANNEL -#define UART_RTS_GPIO22_DIRECT_CHANNEL UART_GPIO22_DIRECT_CHANNEL - -#define UART_GPIO10_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_TXD_DIRECT_GPIO_NUM 10 -#define UART_GPIO9_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_RXD_DIRECT_GPIO_NUM 9 -#define UART_GPIO6_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_CTS_DIRECT_GPIO_NUM 6 -#define UART_GPIO11_DIRECT_CHANNEL UART_NUM_1 -#define UART_NUM_1_RTS_DIRECT_GPIO_NUM 11 - -#define UART_TXD_GPIO10_DIRECT_CHANNEL UART_GPIO10_DIRECT_CHANNEL -#define UART_RXD_GPIO9_DIRECT_CHANNEL UART_GPIO9_DIRECT_CHANNEL -#define UART_CTS_GPIO6_DIRECT_CHANNEL UART_GPIO6_DIRECT_CHANNEL -#define UART_RTS_GPIO11_DIRECT_CHANNEL UART_GPIO11_DIRECT_CHANNEL - -#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_TXD_DIRECT_GPIO_NUM 17 -#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_RXD_DIRECT_GPIO_NUM 16 -#define UART_GPIO8_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_CTS_DIRECT_GPIO_NUM 8 -#define UART_GPIO7_DIRECT_CHANNEL UART_NUM_2 -#define UART_NUM_2_RTS_DIRECT_GPIO_NUM 7 +#define UART_GPIO43_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 43 +#define UART_GPIO44_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 44 +#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_CTS_DIRECT_GPIO_NUM 16 +#define UART_GPIO15_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RTS_DIRECT_GPIO_NUM 15 + +#define UART_TXD_GPIO43_DIRECT_CHANNEL UART_GPIO43_DIRECT_CHANNEL +#define UART_RXD_GPIO44_DIRECT_CHANNEL UART_GPIO44_DIRECT_CHANNEL +#define UART_CTS_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL +#define UART_RTS_GPIO15_DIRECT_CHANNEL UART_GPIO15_DIRECT_CHANNEL + +#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_TXD_DIRECT_GPIO_NUM 17 +#define UART_GPIO18_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_RXD_DIRECT_GPIO_NUM 18 +#define UART_GPIO20_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_CTS_DIRECT_GPIO_NUM 20 +#define UART_GPIO19_DIRECT_CHANNEL UART_NUM_1 +#define UART_NUM_1_RTS_DIRECT_GPIO_NUM 19 #define UART_TXD_GPIO17_DIRECT_CHANNEL UART_GPIO17_DIRECT_CHANNEL -#define UART_RXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL -#define UART_CTS_GPIO8_DIRECT_CHANNEL UART_GPIO8_DIRECT_CHANNEL -#define UART_RTS_GPIO7_DIRECT_CHANNEL UART_GPIO7_DIRECT_CHANNEL +#define UART_RXD_GPIO18_DIRECT_CHANNEL UART_GPIO18_DIRECT_CHANNEL +#define UART_CTS_GPIO20_DIRECT_CHANNEL UART_GPIO20_DIRECT_CHANNEL +#define UART_RTS_GPIO19_DIRECT_CHANNEL UART_GPIO19_DIRECT_CHANNEL diff --git a/components/soc/include/soc/lldesc.h b/components/soc/include/soc/lldesc.h index 31e02125c402..e29bf79d0f1d 100644 --- a/components/soc/include/soc/lldesc.h +++ b/components/soc/include/soc/lldesc.h @@ -31,6 +31,24 @@ /** Maximum size of data in the buffer that a DMA descriptor can hold. */ #define LLDESC_MAX_NUM_PER_DESC (4096-4) +// Some DMA operations might impose certain alignment restrictions on the length +#define LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED (4096 - 16) +#define LLDESC_MAX_NUM_PER_DESC_32B_ALIGNED (4096 - 32) + +/** + * Generate a linked list pointing to a (huge) buffer in an descriptor array. + * + * The caller should ensure there is enough size to hold the array, by calling + * ``lldesc_get_required_num_constrained`` with the same max_desc_size argument. + * + * @param[out] out_desc_array Output of a descriptor array, the head should be fed to the DMA. + * @param buffer Buffer for the descriptors to point to. + * @param size Size (or length for TX) of the buffer + * @param max_desc_size Maximum length of each descriptor + * @param isrx The RX DMA may require the buffer to be word-aligned, set to true for a RX link, otherwise false. + */ +void lldesc_setup_link_constrained(lldesc_t *out_desc_array, const void *buffer, int size, int max_desc_size, bool isrx); + /** * Generate a linked list pointing to a (huge) buffer in an descriptor array. * @@ -42,7 +60,7 @@ * @param size Size (or length for TX) of the buffer * @param isrx The RX DMA may require the buffer to be word-aligned, set to true for a RX link, otherwise false. */ -void lldesc_setup_link(lldesc_t *out_desc_array, const void *buffer, int size, bool isrx); +#define lldesc_setup_link(out_desc_array, buffer, size, isrx) lldesc_setup_link_constrained(out_desc_array, buffer, size, LLDESC_MAX_NUM_PER_DESC, isrx) /** * @brief Get the received length of a linked list, until end of the link or eof. @@ -58,10 +76,19 @@ int lldesc_get_received_len(lldesc_t* head, lldesc_t** out_next); * Get the number of descriptors required for a given buffer size. * * @param data_size Size to check descriptor num. - * + * @param max_desc_size Maximum length of each descriptor * @return Numbers required. */ -static inline int lldesc_get_required_num(int data_size) +static inline int lldesc_get_required_num_constrained(int data_size, int max_desc_size) { - return (data_size + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC; + return (data_size + max_desc_size - 1) / max_desc_size; } + +/** + * Get the number of descriptors required for a given buffer size. + * + * @param data_size Size to check descriptor num. + * + * @return Numbers required. + */ +#define lldesc_get_required_num(data_size) lldesc_get_required_num_constrained(data_size, LLDESC_MAX_NUM_PER_DESC) diff --git a/components/soc/lldesc.c b/components/soc/lldesc.c index c1bf6f022afc..3e27537e05db 100644 --- a/components/soc/lldesc.c +++ b/components/soc/lldesc.c @@ -1,12 +1,12 @@ #include "soc/lldesc.h" -void lldesc_setup_link(lldesc_t *dmadesc, const void *data, int len, bool isrx) +void lldesc_setup_link_constrained(lldesc_t *dmadesc, const void *data, int len, int max_desc_size, bool isrx) { int n = 0; while (len) { int dmachunklen = len; - if (dmachunklen > LLDESC_MAX_NUM_PER_DESC) { - dmachunklen = LLDESC_MAX_NUM_PER_DESC; + if (dmachunklen > max_desc_size) { + dmachunklen = max_desc_size; } if (isrx) { //Receive needs DMA length rounded to next 32-bit boundary diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 27d900b20c16..fd83f5b4c3cc 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -86,6 +86,7 @@ else() "spi_flash_chip_gd.c" "spi_flash_chip_winbond.c" "spi_flash_chip_boya.c" + "spi_flash_chip_th.c" "memspi_host_driver.c") list(APPEND cache_srcs diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index ed1d2ec3d7d7..05f0fc1f5bb6 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -228,13 +228,24 @@ menu "SPI Flash driver" config SPI_FLASH_SUPPORT_BOYA_CHIP bool "BOYA" - depends on !IDF_TARGET_ESP32 + # ESP32 doens't usually use this chip, default n to save iram. + default n if IDF_TARGET_ESP32 default y help Enable this to support auto detection of BOYA chips if chip vendor not directly given by ``chip_drv`` member of the chip struct. This adds support for variant chips, however will extend detecting time. + config SPI_FLASH_SUPPORT_TH_CHIP + bool "TH" + # ESP32 doens't usually use this chip, default n to save iram. + default n if IDF_TARGET_ESP32 + default y + help + Enable this to support auto detection of TH chips if chip vendor not directly + given by ``chip_drv`` member of the chip struct. This adds support for variant + chips, however will extend detecting time. + endmenu #auto detect flash chips config SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index aa93e3a17d57..bf94a060ed76 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -23,6 +23,7 @@ #include "sdkconfig.h" #include "esp_flash_internal.h" #include "spi_flash_defs.h" +#include "esp_rom_caps.h" static const char TAG[] = "spi_flash"; @@ -422,6 +423,9 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui // Can only erase multiples of the sector size, starting at sector boundary return ESP_ERR_INVALID_ARG; } + if (len == 0) { + return ESP_OK; + } err = ESP_OK; // Check for write protected regions overlapping the erase region @@ -484,6 +488,8 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui len_remain -= sector_size; } + assert(len_remain < len); + if (err != ESP_OK || len_remain == 0) { // On ESP32, the cache re-enable is in the end() function, while flush_cache should // happen when the cache is still disabled on ESP32. Break before the end() function and @@ -502,6 +508,28 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui return rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, start, len); } +#endif // !CONFIG_SPI_FLASH_ROM_IMPL + +#if defined(CONFIG_SPI_FLASH_ROM_IMPL) && ESP_ROM_HAS_ERASE_0_REGION_BUG + +/* ROM esp_flash_erase_region implementation doesn't handle 0 erase size correctly. + * Check the size and call ROM function instead of overriding it completely. + * The behavior is slightly different from esp_flash_erase_region above, thought: + * here the check for 0 size is done first, but in esp_flash_erase_region the check is + * done after the other arguments are checked. + */ +extern esp_err_t rom_esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len); +esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len) +{ + if (len == 0) { + return ESP_OK; + } + return rom_esp_flash_erase_region(chip, start, len); +} +#endif // defined(CONFIG_SPI_FLASH_ROM_IMPL) && ESP_ROM_HAS_ERASE_0_REGION_BUG + +#ifndef CONFIG_SPI_FLASH_ROM_IMPL + esp_err_t IRAM_ATTR esp_flash_get_chip_write_protect(esp_flash_t *chip, bool *out_write_protected) { esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -630,14 +658,14 @@ esp_err_t IRAM_ATTR esp_flash_set_protected_region(esp_flash_t *chip, const esp_ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length) { - if (length == 0) { - return ESP_OK; - } esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); VERIFY_CHIP_OP(read); if (buffer == NULL || address > chip->size || address+length > chip->size) { return ESP_ERR_INVALID_ARG; } + if (length == 0) { + return ESP_OK; + } //when the cache is disabled, only the DRAM can be read, check whether we need to receive in another buffer in DRAM. bool direct_read = chip->host->driver->supports_direct_read(chip->host, buffer); @@ -697,15 +725,15 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) { - if (length == 0) { - return ESP_OK; - } esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); VERIFY_CHIP_OP(write); CHECK_WRITE_ADDRESS(chip, address, length); if (buffer == NULL || address > chip->size || address+length > chip->size) { return ESP_ERR_INVALID_ARG; } + if (length == 0) { + return ESP_OK; + } //when the cache is disabled, only the DRAM can be read, check whether we need to copy the data first bool direct_write = chip->host->driver->supports_direct_write(chip->host, buffer); @@ -748,6 +776,7 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 err = chip->chip_drv->write(chip, write_buf, write_addr, write_len); len_remain -= write_len; + assert(len_remain < length); if (err != ESP_OK || len_remain == 0) { // On ESP32, the cache re-enable is in the end() function, while flush_cache should diff --git a/components/spi_flash/include/spi_flash_chip_th.h b/components/spi_flash/include/spi_flash_chip_th.h new file mode 100644 index 000000000000..7f631faf1361 --- /dev/null +++ b/components/spi_flash/include/spi_flash_chip_th.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_flash.h" +#include "spi_flash_chip_driver.h" + +extern const spi_flash_chip_t esp_flash_chip_th; diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index 800d2e1683dc..40699fd2ce86 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -7,7 +7,6 @@ entries: spi_flash_chip_mxic (noflash) spi_flash_chip_gd (noflash) spi_flash_chip_winbond (noflash) + spi_flash_chip_boya (noflash) + spi_flash_chip_th (noflash) memspi_host_driver (noflash) - - if IDF_TARGET_ESP32 = n: - spi_flash_chip_boya (noflash) diff --git a/components/spi_flash/spi_flash_chip_drivers.c b/components/spi_flash/spi_flash_chip_drivers.c index a7f68e895f8d..324a0dcad175 100644 --- a/components/spi_flash/spi_flash_chip_drivers.c +++ b/components/spi_flash/spi_flash_chip_drivers.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "spi_flash_chip_driver.h" @@ -20,6 +12,7 @@ #include "spi_flash_chip_gd.h" #include "spi_flash_chip_winbond.h" #include "spi_flash_chip_boya.h" +#include "spi_flash_chip_th.h" #include "sdkconfig.h" /* @@ -46,6 +39,9 @@ static const spi_flash_chip_t *default_registered_chips[] = { #endif #ifdef CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP &esp_flash_chip_boya, +#endif +#ifdef CONFIG_SPI_FLASH_SUPPORT_TH_CHIP + &esp_flash_chip_th, #endif // Default chip drivers that will accept all chip ID. // FM, Winbond and XMC chips are supposed to be supported by this chip driver. diff --git a/components/spi_flash/spi_flash_chip_th.c b/components/spi_flash/spi_flash_chip_th.c new file mode 100644 index 000000000000..9a8a2467664a --- /dev/null +++ b/components/spi_flash/spi_flash_chip_th.c @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "spi_flash_chip_generic.h" +#include "spi_flash_defs.h" + +esp_err_t spi_flash_chip_th_probe(esp_flash_t *chip, uint32_t flash_id) +{ + /* Check manufacturer and product IDs match our desired masks */ + const uint8_t MFG_ID = 0xcd; + if (flash_id >> 16 != MFG_ID) { + return ESP_ERR_NOT_FOUND; + } + + const uint16_t FLASH_ID_MASK = 0xFF00; + const uint16_t FLASH_ID_VALUE = 0x6000; + if ((flash_id & FLASH_ID_MASK) != FLASH_ID_VALUE) { + return ESP_ERR_NOT_FOUND; + } + + return ESP_OK; +} + +spi_flash_caps_t spi_flash_chip_th_get_caps(esp_flash_t *chip) +{ + spi_flash_caps_t caps_flags = 0; + // 32-bit-address flash is not supported + // flash-suspend is not supported + return caps_flags; +} + +static const char chip_name[] = "th"; + +// The th chip can use the functions for generic chips except from set read mode and probe, +// So we only replace these two functions. +const spi_flash_chip_t esp_flash_chip_th = { + .name = chip_name, + .timeout = &spi_flash_chip_generic_timeout, + .probe = spi_flash_chip_th_probe, + .reset = spi_flash_chip_generic_reset, + .detect_size = spi_flash_chip_generic_detect_size, + .erase_chip = spi_flash_chip_generic_erase_chip, + .erase_sector = spi_flash_chip_generic_erase_sector, + .erase_block = spi_flash_chip_generic_erase_block, + .sector_size = 4 * 1024, + .block_erase_size = 64 * 1024, + + .get_chip_write_protect = spi_flash_chip_generic_get_write_protect, + .set_chip_write_protect = spi_flash_chip_generic_set_write_protect, + + .num_protectable_regions = 0, + .protectable_regions = NULL, + .get_protected_regions = NULL, + .set_protected_regions = NULL, + + .read = spi_flash_chip_generic_read, + .write = spi_flash_chip_generic_write, + .program_page = spi_flash_chip_generic_page_program, + .page_size = 256, + .write_encrypted = spi_flash_chip_generic_write_encrypted, + + .wait_idle = spi_flash_chip_generic_wait_idle, + .set_io_mode = spi_flash_chip_generic_set_io_mode, + .get_io_mode = spi_flash_chip_generic_get_io_mode, + + .read_reg = spi_flash_chip_generic_read_reg, + .yield = spi_flash_chip_generic_yield, + .sus_setup = spi_flash_chip_generic_suspend_cmd_conf, + .get_chip_caps = spi_flash_chip_th_get_caps, +}; diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c index d61294040aef..ee9d83d2174f 100644 --- a/components/spi_flash/test/test_esp_flash.c +++ b/components/spi_flash/test/test_esp_flash.c @@ -609,6 +609,13 @@ void test_erase_large_region(const esp_partition_t *part) TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, part->address, 4)); TEST_ASSERT_EQUAL_HEX32(0, readback & (~written_data)); + /* Erase zero bytes, check that nothing got erased */ + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_erase_region(chip, part->address, 0)); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, part->address + part->size - 5, 4)); + TEST_ASSERT_EQUAL_HEX32(0, readback & (~written_data)); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, part->address, 4)); + TEST_ASSERT_EQUAL_HEX32(0, readback & (~written_data)); + /* Erase whole region */ TEST_ASSERT_EQUAL(ESP_OK, esp_flash_erase_region(chip, part->address, part->size)); @@ -1044,6 +1051,37 @@ static uint32_t measure_read(const char* name, const esp_partition_t* part, uint return time_measure_end(&time_ctx); } +static const char* get_chip_vendor(uint32_t id) +{ + switch (id) + { + case 0x20: + return "XMC"; + break; + case 0x68: + return "BOYA"; + break; + case 0xC8: + return "GigaDevice"; + break; + case 0x9D: + return "ISSI"; + break; + case 0xC2: + return "MXIC"; + break; + case 0xEF: + return "Winbond"; + break; + case 0xA1: + return "Fudan Micro"; + break; + default: + break; + } + return "generic"; +} + #define MEAS_WRITE(n) (measure_write("write in "#n"-byte chunks", part, data_to_write, n)) #define MEAS_READ(n) (measure_read("read in "#n"-byte chunks", part, data_read, n)) @@ -1068,37 +1106,35 @@ static void test_flash_read_write_performance(const esp_partition_t *part) TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_write, data_read, total_len); -#if !CONFIG_SPIRAM && !CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE -# define CHECK_DATA(bus, suffix) TEST_PERFORMANCE_CCOMP_GREATER_THAN(FLASH_SPEED_BYTE_PER_SEC_##bus##suffix, "%d", speed_##suffix) -# define CHECK_ERASE(bus, var) TEST_PERFORMANCE_CCOMP_GREATER_THAN(FLASH_SPEED_BYTE_PER_SEC_##bus##ERASE, "%d", var) -#else -# define CHECK_DATA(bus, suffix) ((void)speed_##suffix) -# define CHECK_ERASE(bus, var) ((void)var) -#endif +#define LOG_DATA(bus, suffix, chip) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_"#bus#suffix, "%d, flash_chip: %s", speed_##suffix, chip) +#define LOG_ERASE(bus, var, chip) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_"#bus"ERASE", "%d, flash_chip: %s", var, chip) // Erase time may vary a lot, can increase threshold if this fails with a reasonable speed -#define CHECK_PERFORMANCE(bus) do {\ - CHECK_DATA(bus, WR_4B); \ - CHECK_DATA(bus, RD_4B); \ - CHECK_DATA(bus, WR_2KB); \ - CHECK_DATA(bus, RD_2KB); \ - CHECK_ERASE(bus, erase_1); \ - CHECK_ERASE(bus, erase_2); \ +#define LOG_PERFORMANCE(bus, chip) do {\ + LOG_DATA(bus, WR_4B, chip); \ + LOG_DATA(bus, RD_4B, chip); \ + LOG_DATA(bus, WR_2KB, chip); \ + LOG_DATA(bus, RD_2KB, chip); \ + LOG_ERASE(bus, erase_1, chip); \ + LOG_ERASE(bus, erase_2, chip); \ } while (0) spi_host_device_t host_id; int cs_id; + uint32_t id; + esp_flash_read_id(chip, &id); + const char *chip_name = get_chip_vendor(id >> 16); get_chip_host(chip, &host_id, &cs_id); if (host_id != SPI1_HOST) { // Chips on other SPI buses - CHECK_PERFORMANCE(EXT_); + LOG_PERFORMANCE(EXT_, chip_name); } else if (cs_id == 0) { // Main flash - CHECK_PERFORMANCE(); + LOG_PERFORMANCE(,chip_name); } else { // Other cs pins on SPI1 - CHECK_PERFORMANCE(SPI1_); + LOG_PERFORMANCE(SPI1_, chip_name); } free(data_to_write); free(data_read); diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index 043ed6ff9364..de06e39b31cd 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -312,23 +312,17 @@ TEST_CASE("Test spi_flash read/write performance", "[spi_flash]") TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_write, data_read, total_len); -// Data checks are disabled when PSRAM is used or in Freertos compliance check test -#if !CONFIG_SPIRAM && !CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE -# define CHECK_DATA(suffix) TEST_PERFORMANCE_CCOMP_GREATER_THAN(FLASH_SPEED_BYTE_PER_SEC_LEGACY_##suffix, "%d", speed_##suffix) -# define CHECK_ERASE(var) TEST_PERFORMANCE_CCOMP_GREATER_THAN(FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE, "%d", var) -#else -# define CHECK_DATA(suffix) ((void)speed_##suffix) -# define CHECK_ERASE(var) ((void)var) -#endif +#define LOG_DATA(suffix) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_LEGACY_"#suffix, "%d", speed_##suffix) +#define LOG_ERASE(var) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE", "%d", var) - CHECK_DATA(WR_4B); - CHECK_DATA(RD_4B); - CHECK_DATA(WR_2KB); - CHECK_DATA(RD_2KB); + LOG_DATA(WR_4B); + LOG_DATA(RD_4B); + LOG_DATA(WR_2KB); + LOG_DATA(RD_2KB); // Erase time may vary a lot, can increase threshold if this fails with a reasonable speed - CHECK_ERASE(erase_1); - CHECK_ERASE(erase_2); + LOG_ERASE(erase_1); + LOG_ERASE(erase_2); free(data_to_write); free(data_read); diff --git a/components/spiffs/esp_spiffs.c b/components/spiffs/esp_spiffs.c index 1f43943a0d1e..df1473df47b9 100644 --- a/components/spiffs/esp_spiffs.c +++ b/components/spiffs/esp_spiffs.c @@ -177,20 +177,55 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf) return ESP_ERR_INVALID_STATE; } - esp_spiffs_t * efs = malloc(sizeof(esp_spiffs_t)); + const size_t flash_erase_sector_size = g_rom_flashchip.sector_size; + + /* Older versions of IDF allowed creating misaligned data partitions. + * This would result in hard-to-diagnose SPIFFS failures due to failing erase operations. + */ + if (partition->address % flash_erase_sector_size != 0) { + ESP_LOGE(TAG, "spiffs partition is not aligned to flash sector size, please check the partition table"); + /* No return intentional to avoid accidentally breaking applications + * which used misaligned read-only SPIFFS partitions. + */ + } + + /* Check if the SPIFFS internal data types are wide enough. + * Casting -1 to the unsigned type produces the maximum value the type can hold. + * All the checks here are based on comments for the said data types in spiffs_config.h. + */ + if (partition->size / flash_erase_sector_size > (spiffs_block_ix) -1) { + ESP_LOGE(TAG, "spiffs partition is too large for spiffs_block_ix type"); + return ESP_ERR_INVALID_ARG; + } + if (partition->size / log_page_size > (spiffs_page_ix) -1) { + /* For 256 byte pages the largest partition is 16MB, but larger partitions can be supported + * by increasing the page size (reducing the number of pages). + */ + ESP_LOGE(TAG, "spiffs partition is too large for spiffs_page_ix type. Please increase CONFIG_SPIFFS_PAGE_SIZE."); + return ESP_ERR_INVALID_ARG; + } + if (2 + 2 * (partition->size / (2 * log_page_size)) > (spiffs_obj_id) -1) { + ESP_LOGE(TAG, "spiffs partition is too large for spiffs_obj_id type. Please increase CONFIG_SPIFFS_PAGE_SIZE."); + return ESP_ERR_INVALID_ARG; + } + if (partition->size / log_page_size - 1 > (spiffs_span_ix) -1) { + ESP_LOGE(TAG, "spiffs partition is too large for spiffs_span_ix type. Please increase CONFIG_SPIFFS_PAGE_SIZE."); + return ESP_ERR_INVALID_ARG; + } + + esp_spiffs_t * efs = calloc(sizeof(esp_spiffs_t), 1); if (efs == NULL) { ESP_LOGE(TAG, "esp_spiffs could not be malloced"); return ESP_ERR_NO_MEM; } - memset(efs, 0, sizeof(esp_spiffs_t)); efs->cfg.hal_erase_f = spiffs_api_erase; efs->cfg.hal_read_f = spiffs_api_read; efs->cfg.hal_write_f = spiffs_api_write; - efs->cfg.log_block_size = g_rom_flashchip.sector_size; + efs->cfg.log_block_size = flash_erase_sector_size; efs->cfg.log_page_size = log_page_size; efs->cfg.phys_addr = 0; - efs->cfg.phys_erase_block = g_rom_flashchip.sector_size; + efs->cfg.phys_erase_block = flash_erase_sector_size; efs->cfg.phys_size = partition->size; efs->by_label = conf->partition_label != NULL; @@ -203,42 +238,38 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf) } efs->fds_sz = conf->max_files * sizeof(spiffs_fd); - efs->fds = malloc(efs->fds_sz); + efs->fds = calloc(efs->fds_sz, 1); if (efs->fds == NULL) { - ESP_LOGE(TAG, "fd buffer could not be malloced"); + ESP_LOGE(TAG, "fd buffer could not be allocated"); esp_spiffs_free(&efs); return ESP_ERR_NO_MEM; } - memset(efs->fds, 0, efs->fds_sz); #if SPIFFS_CACHE efs->cache_sz = sizeof(spiffs_cache) + conf->max_files * (sizeof(spiffs_cache_page) + efs->cfg.log_page_size); - efs->cache = malloc(efs->cache_sz); + efs->cache = calloc(efs->cache_sz, 1); if (efs->cache == NULL) { - ESP_LOGE(TAG, "cache buffer could not be malloced"); + ESP_LOGE(TAG, "cache buffer could not be allocated"); esp_spiffs_free(&efs); return ESP_ERR_NO_MEM; } - memset(efs->cache, 0, efs->cache_sz); #endif const uint32_t work_sz = efs->cfg.log_page_size * 2; - efs->work = malloc(work_sz); + efs->work = calloc(work_sz, 1); if (efs->work == NULL) { - ESP_LOGE(TAG, "work buffer could not be malloced"); + ESP_LOGE(TAG, "work buffer could not be allocated"); esp_spiffs_free(&efs); return ESP_ERR_NO_MEM; } - memset(efs->work, 0, work_sz); - efs->fs = malloc(sizeof(spiffs)); + efs->fs = calloc(sizeof(spiffs), 1); if (efs->fs == NULL) { - ESP_LOGE(TAG, "spiffs could not be malloced"); + ESP_LOGE(TAG, "spiffs could not be allocated"); esp_spiffs_free(&efs); return ESP_ERR_NO_MEM; } - memset(efs->fs, 0, sizeof(spiffs)); efs->fs->user_data = (void *)efs; efs->partition = partition; diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index 2711abf330ba..3b7ab22c8672 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -52,6 +52,16 @@ void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data, */ void esp_transport_ssl_set_cert_data_der(esp_transport_handle_t t, const char *data, int len); +/** + * @brief Enable the use of certification bundle for server verfication for + * an SSL connection. + * It must be first enabled in menuconfig. + * + * @param t ssl transport + * @param[in] crt_bundle_attach Function pointer to esp_crt_bundle_attach + */ +void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf))); + /** * @brief Enable global CA store for SSL connection * @@ -141,14 +151,12 @@ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t); */ void esp_transport_ssl_use_secure_element(esp_transport_handle_t t); - /** * @brief Set the ds_data handle in ssl context.(used for the digital signature operation) * * @param t ssl transport * ds_data the handle for ds data params */ - void esp_transport_ssl_set_ds_data(esp_transport_handle_t t, void *ds_data); /** diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index 573782e64bb8..214f877dd403 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -304,6 +304,14 @@ void esp_transport_ssl_use_secure_element(esp_transport_handle_t t) } #endif +void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf))) +{ + transport_ssl_t *ssl = esp_transport_get_context_data(t); + if (t && ssl) { + ssl->cfg.crt_bundle_attach = crt_bundle_attach; + } +} + static int ssl_get_socket(esp_transport_handle_t t) { if (t) { diff --git a/components/touch_element/test/CMakeLists.txt b/components/touch_element/test/CMakeLists.txt new file mode 100644 index 000000000000..fbdfd322bd9b --- /dev/null +++ b/components/touch_element/test/CMakeLists.txt @@ -0,0 +1,7 @@ +if(IDF_TARGET STREQUAL "esp32s2") + idf_component_register(SRCS "test_touch_element.c" + "test_touch_button.c" + "test_touch_slider.c" + "test_touch_matrix.c" + PRIV_REQUIRES unity touch_element) +endif() diff --git a/components/touch_element/test/component.mk b/components/touch_element/test/component.mk new file mode 100644 index 000000000000..888b7d448cfb --- /dev/null +++ b/components/touch_element/test/component.mk @@ -0,0 +1,5 @@ +# +# Component Makefile +# +# Touch Element lib is not supported in GNU Make build system +COMPONENT_CONFIG_ONLY := 1 diff --git a/components/touch_element/test/test_touch_button.c b/components/touch_element/test/test_touch_button.c new file mode 100644 index 000000000000..5bbd728b9f75 --- /dev/null +++ b/components/touch_element/test/test_touch_button.c @@ -0,0 +1,570 @@ +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "unity.h" + +#include "touch_element/touch_element_private.h" +#include "touch_element/touch_button.h" + +static portMUX_TYPE test_button_spinlock = portMUX_INITIALIZER_UNLOCKED; +#define TEST_BUTTON_ENTER_CRITICAL() portENTER_CRITICAL(&test_button_spinlock) +#define TEST_BUTTON_EXIT_CRITICAL() portEXIT_CRITICAL(&test_button_spinlock) + +static const touch_pad_t button_channel_array[14] = { + TOUCH_PAD_NUM1, + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3, + TOUCH_PAD_NUM4, + TOUCH_PAD_NUM5, + TOUCH_PAD_NUM6, + TOUCH_PAD_NUM7, + TOUCH_PAD_NUM8, + TOUCH_PAD_NUM9, + TOUCH_PAD_NUM10, + TOUCH_PAD_NUM11, + TOUCH_PAD_NUM12, + TOUCH_PAD_NUM13, + TOUCH_PAD_NUM14, +}; +const uint8_t BUTTON_CHANNEL_NUM = sizeof(button_channel_array) / sizeof(touch_pad_t); + +typedef struct { + QueueHandle_t valid_msg_handle; + SemaphoreHandle_t response_sig_handle; +} test_monitor_t; + +typedef struct { + QueueHandle_t valid_msg_handle; + SemaphoreHandle_t response_sig_handle; + touch_button_handle_t button_handle; +} test_concurrent_monitor_t; + +/* ------------------------------------------------------------------------------------------------------------------ */ +void test_button_event_simulator(touch_button_handle_t button_handle, touch_button_event_t button_event); +void test_button_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message); +static void test_button_callback_check(touch_button_handle_t current_handle, touch_button_message_t *current_message, touch_elem_message_t *valid_message); +void test_button_event_trigger_and_check(touch_button_handle_t handle, touch_button_event_t button_event); +void test_button_callback_trigger_and_check(touch_button_handle_t handle, touch_button_event_t button_event, bool should_trigger, test_monitor_t *monitor); +/* ------------------------------------------------ Dispatch method test -------------------------------------------- */ +static void test_button_disp_event(void); +static void test_button_disp_callback(void); +void test_button_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg); +/* ------------------------------------------------ Run-time test --------------------------------------------------- */ +static void test_button_event_change_lp(void); +static void test_button_callback_change_lp(void); +static void test_button_change_lp_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg); +/* ------------------------------------------------ Concurrent test ------------------------------------------------- */ +static void test_button_event_concurrent(void); +static void test_button_random_trigger_concurrent(void); +void test_random_trigger_concurrent_task(void *arg); +static void random_trigger_concurrent_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg); +/* ------------------------------------------------------------------------------------------------------------------ */ + +TEST_CASE("Touch button dispatch methods test", "[button][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_button_disp_event(); + test_button_disp_callback(); + touch_element_uninstall(); +} + +TEST_CASE("Touch button run-time test", "[button][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_button_event_change_lp(); + test_button_callback_change_lp(); + touch_element_uninstall(); +} + +TEST_CASE("Touch button concurrent test", "[button][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_button_event_concurrent(); + test_button_random_trigger_concurrent(); + touch_element_uninstall(); +} + +void test_button_event_simulator(touch_button_handle_t button_handle, touch_button_event_t button_event) +{ + te_button_handle_t te_button = (te_button_handle_t) button_handle; + touch_pad_t channel = te_button->device->channel; + if (button_event == TOUCH_BUTTON_EVT_ON_PRESS) { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + } else if (button_event == TOUCH_BUTTON_EVT_ON_RELEASE) { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + } else { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); //LongPress + } +} + +void test_button_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message) +{ + TEST_ASSERT_MESSAGE(current_message->handle == valid_message->handle, "check handle failed"); + TEST_ASSERT_MESSAGE(current_message->element_type == valid_message->element_type, "check element type failed"); + const touch_button_message_t *valid_button_message = touch_button_get_message(valid_message); + const touch_button_message_t *current_button_message = touch_button_get_message(current_message); + TEST_ASSERT_MESSAGE(current_button_message->event == valid_button_message->event, "check event failed"); +} + +static void test_button_callback_check(touch_button_handle_t current_handle, touch_button_message_t *current_message, touch_elem_message_t *valid_message) +{ + const touch_button_message_t *valid_button_message = touch_button_get_message(valid_message); + TEST_ASSERT_MESSAGE(valid_message->handle == current_handle, "check handle failed"); + TEST_ASSERT_MESSAGE(valid_message->element_type == TOUCH_ELEM_TYPE_BUTTON, "check element type failed"); + TEST_ASSERT_MESSAGE(valid_button_message->event == current_message->event, "check event failed"); +} + +void test_button_event_trigger_and_check(touch_button_handle_t handle, touch_button_event_t button_event) +{//TODO: refactor this with a constructor + touch_elem_message_t valid_message = { + .handle = handle, + .element_type = TOUCH_ELEM_TYPE_BUTTON, + .arg = NULL, + }; + touch_button_message_t button_message = { + .event = button_event + }; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + + test_button_event_simulator(handle, button_event); //Trigger signal + + touch_elem_message_t current_message; + te_button_handle_t te_button = handle; + esp_err_t ret = touch_element_message_receive(¤t_message, pdMS_TO_TICKS(2 * te_button->trigger_thr * 10)); + TEST_ASSERT_MESSAGE(ret == ESP_OK, "button event receive timeout"); + + test_button_event_check(&valid_message, ¤t_message); //Verification +} + +void test_button_callback_trigger_and_check(touch_button_handle_t handle, touch_button_event_t button_event, bool should_trigger, test_monitor_t *monitor) +{ + if (should_trigger) { + touch_elem_message_t valid_message = { + .handle = handle, + .element_type = TOUCH_ELEM_TYPE_BUTTON, + .arg = NULL + }; + touch_button_message_t button_message = { + .event = button_event + }; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + xQueueSend(monitor->valid_msg_handle, &valid_message, portMAX_DELAY); + } + + test_button_event_simulator(handle, button_event); //Trigger signal + + te_button_handle_t te_button = handle; + if (should_trigger) { //Verification + BaseType_t os_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(2 * te_button->trigger_thr * 10)); + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "Button queue timeout"); + } else { + BaseType_t os_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(500)); + TEST_ASSERT_MESSAGE(os_ret == pdFALSE, "Button invalid trigger"); + } +} + +static void test_button_disp_event(void) +{ + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + touch_button_global_config_t global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&global_config)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], + TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE | TOUCH_ELEM_EVENT_ON_LONGPRESS, + (void *) button_channel_array[i])); + TEST_ESP_OK(touch_button_set_longpress(button_handle[i], 300)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_EVENT)); + } + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + //10 times random press/longpress/release test + printf("Touch button event test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch button event test... (%d/10)\n", i + 1); + touch_button_handle_t current_handle = button_handle[random() % 14]; + test_button_event_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_PRESS); + test_button_event_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_LONGPRESS); + test_button_event_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_RELEASE); + } + printf("Touch button event test finish\n"); + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + touch_button_uninstall(); +} + +static void test_button_disp_callback(void) +{ + test_monitor_t monitor; + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + + touch_button_global_config_t button_init = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&button_init)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], + TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE | TOUCH_ELEM_EVENT_ON_LONGPRESS, + (void *) &monitor)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_button_set_callback(button_handle[i], &test_button_handler)); + TEST_ESP_OK(touch_button_set_longpress(button_handle[i], 300)); + } + TEST_ESP_OK(touch_element_start()); + + srandom((unsigned int)time(NULL)); + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + //10 times random press/longpress/release test + printf("Touch button callback test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch button callback test... (%d/10)\n", i + 1); + touch_button_handle_t current_handle = button_handle[random() % 14]; + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_PRESS, true, &monitor); + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_LONGPRESS, true, &monitor); + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_RELEASE, true, &monitor); + } + printf("Touch button callback test finish\n"); + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + touch_button_uninstall(); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); +} + +void test_button_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg) +{ + test_monitor_t *monitor = (test_monitor_t *)arg; + touch_elem_message_t valid_message; + BaseType_t os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(200)); //Get the valid message for the verification, 500ms timeout + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "test_button_handler: queue timeout"); + test_button_callback_check(handle, message, &valid_message); + xSemaphoreGive(monitor->response_sig_handle); +} + +static void test_button_event_change_lp(void) +{ + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + touch_button_global_config_t global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&global_config)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], TOUCH_ELEM_EVENT_ON_LONGPRESS, NULL)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_EVENT)); + } + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + //10 times random press/longpress/release test + printf("Touch button event change longtime test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch button event change longtime test... (%d/10)\n", i + 1); + esp_err_t ret; + uint8_t channel_index = random() % BUTTON_CHANNEL_NUM; + touch_elem_message_t valid_message = { + .handle = button_handle[channel_index], + .element_type = TOUCH_ELEM_TYPE_BUTTON, + .arg = NULL + }; + touch_button_message_t button_message = { + .event = TOUCH_BUTTON_EVT_ON_LONGPRESS + }; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + + TEST_ESP_OK(touch_button_set_longpress(valid_message.handle, 200 + (i + 1) * 50)); + test_button_event_simulator(valid_message.handle, button_message.event); //Trigger signal + + touch_elem_message_t current_message; + ret = touch_element_message_receive(¤t_message, pdMS_TO_TICKS(10 * 1000)); + TEST_ASSERT_MESSAGE(ret == ESP_OK, "button event LongPress timeout"); + test_button_event_check(&valid_message, ¤t_message); //Verification + + test_button_event_simulator(valid_message.handle, TOUCH_BUTTON_EVT_ON_RELEASE); //Release the button. + } + printf("Touch button event change longtime test finish\n"); + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + touch_button_uninstall(); +} + +static void test_button_callback_change_lp(void) +{ + test_monitor_t monitor; + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + + touch_button_global_config_t global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&global_config)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], TOUCH_ELEM_EVENT_ON_LONGPRESS, (void *)&monitor)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_button_set_callback(button_handle[i], &test_button_change_lp_handler)); + } + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + //10 times random press/longpress/release test + printf("Touch button event change longtime test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch button event change longtime test... (%d/10)\n", i + 1); + uint8_t channel_index = 5; //Always this channel + touch_elem_message_t valid_message = { + .handle = button_handle[channel_index], + .element_type = TOUCH_ELEM_TYPE_BUTTON, + .arg = NULL, + }; + touch_button_message_t button_message = { + .event = TOUCH_BUTTON_EVT_ON_LONGPRESS + }; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + test_button_event_simulator(button_handle[channel_index], button_message.event); + + BaseType_t os_ret = xSemaphoreTake(monitor.response_sig_handle, pdMS_TO_TICKS(10 * 1000)); //100ms timeout + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "Button LongPress queue timeout"); + test_button_event_simulator(valid_message.handle, TOUCH_BUTTON_EVT_ON_RELEASE); //Reset hardware + } + printf("Touch button event change longtime test finish\n"); + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + touch_button_uninstall(); +} + +static void test_button_change_lp_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg) +{ + test_monitor_t *monitor = (test_monitor_t *)arg; + touch_elem_message_t valid_message; + BaseType_t os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(200)); //Get the valid message for the verification, 500ms timeout + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "test_button_handler: queue timeout"); + test_button_callback_check(handle, message, &valid_message); + xSemaphoreGive(monitor->response_sig_handle); + TEST_ESP_OK(touch_button_set_longpress(valid_message.handle, 300)); // Always 300ms +} + +static void test_button_event_concurrent(void) +{ + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + touch_button_global_config_t global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&global_config)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, NULL)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_EVENT)); + } + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + //10 times random press/longpress/release test + printf("Touch button event concurrent test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch button event concurrent test... (%d/10)\n", i + 1); + esp_err_t ret; + uint32_t message_count = 0; + touch_elem_message_t current_message; + + TEST_BUTTON_ENTER_CRITICAL(); + for (int idx = 0; idx < BUTTON_CHANNEL_NUM; idx++) { + test_button_event_simulator(button_handle[idx], TOUCH_BUTTON_EVT_ON_PRESS); //All channels trigger + } + TEST_BUTTON_EXIT_CRITICAL(); + message_count = 0; + do { + ret = touch_element_message_receive(¤t_message, pdMS_TO_TICKS(500)); + if (ret == ESP_OK) { + message_count++; + } + } while (ret == ESP_OK); + TEST_ASSERT_MESSAGE(message_count == BUTTON_CHANNEL_NUM, "button concurrent Press failed"); + + TEST_BUTTON_ENTER_CRITICAL(); + for (int idx = 0; idx < BUTTON_CHANNEL_NUM; idx++) { + test_button_event_simulator(button_handle[idx], TOUCH_BUTTON_EVT_ON_RELEASE); //All channels trigger + } + TEST_BUTTON_EXIT_CRITICAL(); + message_count = 0; + do { + ret = touch_element_message_receive(¤t_message, pdMS_TO_TICKS(500)); + if (ret == ESP_OK) { + message_count++; + } + } while (ret == ESP_OK); + TEST_ASSERT_MESSAGE(message_count == BUTTON_CHANNEL_NUM, "button concurrent Release failed"); + } + printf("Touch button event concurrent test finish\n"); + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + touch_button_uninstall(); +} + +static void test_button_random_trigger_concurrent(void) +{ + uint64_t sem_and_monitor[BUTTON_CHANNEL_NUM]; + printf("Touch button random trigger concurrent test start\n"); + test_concurrent_monitor_t monitor[BUTTON_CHANNEL_NUM]; + + SemaphoreHandle_t count_sem = xSemaphoreCreateCounting(BUTTON_CHANNEL_NUM, 0); + + touch_button_global_config_t global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&global_config)); + for (uint32_t i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + monitor[i].response_sig_handle = xSemaphoreCreateBinary(); + monitor[i].valid_msg_handle = xQueueCreate(BUTTON_CHANNEL_NUM, sizeof(touch_elem_message_t)); + TEST_ASSERT(monitor[i].valid_msg_handle != NULL && monitor[i].response_sig_handle != NULL); + uintptr_t temp_count_sem = (uint32_t)count_sem; + uintptr_t temp_monitor = (uint32_t)&monitor[i]; //Prevent compiler warning + sem_and_monitor[i] = (uint64_t)(((uint64_t)temp_count_sem << 32) | (uint64_t) temp_monitor); + TEST_ESP_OK(touch_button_create(&button_config, &monitor[i].button_handle)); + TEST_ESP_OK(touch_button_subscribe_event(monitor[i].button_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_LONGPRESS | TOUCH_ELEM_EVENT_ON_RELEASE, (void *)&sem_and_monitor[i])); + TEST_ESP_OK(touch_button_set_longpress(monitor[i].button_handle, 500)); + TEST_ESP_OK(touch_button_set_dispatch_method(monitor[i].button_handle, TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_button_set_callback(monitor[i].button_handle, &random_trigger_concurrent_handler)); + } + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + for (uint32_t i = 0; i < BUTTON_CHANNEL_NUM; i++) { + BaseType_t os_ret = xTaskCreate(test_random_trigger_concurrent_task, "test_random_trigger_concurrent_task", 1024 * 4, (void *)&sem_and_monitor[i], 10, NULL); + TEST_ASSERT(os_ret == pdPASS); + } + + + uint32_t run_count = 0; + while (1) { + if (run_count++ % 1000 == 0) { + printf("Touch button random trigger concurrent test running... (1/1)\n"); + } + uint8_t count = uxSemaphoreGetCount(count_sem); + if (count == BUTTON_CHANNEL_NUM) { + vTaskDelay(1); //Let IDLE task running and get tasks cleanup + break; + } + vTaskDelay(1); + } + + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + vQueueDelete(monitor[i].valid_msg_handle); + vSemaphoreDelete(monitor[i].response_sig_handle); + TEST_ESP_OK(touch_button_delete(monitor[i].button_handle)); + } + touch_button_uninstall(); + printf("Touch button random trigger concurrent test stop\n"); +} + +void test_random_trigger_concurrent_task(void *arg) +{ + uintptr_t temp_monitor = *((uint32_t *) arg); + uintptr_t temp_count_sem = (*((uint64_t *) arg) >> 32); //Prevent compiler warning + test_concurrent_monitor_t *monitor = (test_concurrent_monitor_t *)temp_monitor; + SemaphoreHandle_t count_sem = (SemaphoreHandle_t) temp_count_sem; + uint32_t start_delay_time = (esp_random() % 100) * 10; + vTaskDelay(pdMS_TO_TICKS(start_delay_time)); + + touch_elem_message_t valid_message = { + .handle = monitor->button_handle, + .element_type = TOUCH_ELEM_TYPE_BUTTON, + .arg = NULL, + }; + touch_button_message_t button_message; + button_message.event = TOUCH_BUTTON_EVT_ON_PRESS; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + xQueueSend(monitor->valid_msg_handle, &valid_message, portMAX_DELAY); + test_button_event_simulator(valid_message.handle, button_message.event); //Trigger signal + BaseType_t res_sem_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(1000)); + TEST_ASSERT_MESSAGE(res_sem_ret == pdPASS, "Response timeout"); + + uint32_t hold_state_time_ms = (esp_random() % 100) * 10 + 100; + te_button_handle_t te_button = (te_button_handle_t) valid_message.handle; + if ((int)(hold_state_time_ms - te_button->trigger_thr * 10) > 50) { //should raise longpress event + button_message.event = TOUCH_BUTTON_EVT_ON_LONGPRESS; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + xQueueSend(monitor->valid_msg_handle, &valid_message, portMAX_DELAY); + test_button_event_simulator(valid_message.handle, button_message.event); //Trigger signal + res_sem_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(1000)); //+100 make sure it will really raise longpress event + TEST_ASSERT_MESSAGE(res_sem_ret == pdPASS, "Response timeout"); + } else { //should not raise longpress event + //Do nothing + } + + button_message.event = TOUCH_BUTTON_EVT_ON_RELEASE; + memcpy(valid_message.child_msg, &button_message, sizeof(touch_button_message_t)); //Construct valid_message + xQueueSend(monitor->valid_msg_handle, &valid_message, portMAX_DELAY); + test_button_event_simulator(valid_message.handle, button_message.event); //Trigger signal + res_sem_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(1000)); + TEST_ASSERT_MESSAGE(res_sem_ret == pdPASS, "Response timeout"); + + xSemaphoreGive(count_sem); + vTaskDelete(NULL); +} + +static void random_trigger_concurrent_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg) +{ + uintptr_t temp_monitor = *((uint32_t *) arg); //Prevent compiler warning + test_concurrent_monitor_t *monitor = (test_concurrent_monitor_t *) temp_monitor; + touch_elem_message_t valid_message; + BaseType_t os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(1000)); + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "valid message timeout"); + const touch_button_message_t *button_message = touch_button_get_message(&valid_message); + if (button_message->event == TOUCH_BUTTON_EVT_ON_LONGPRESS) { + touch_button_set_longpress(handle, portMAX_DELAY); //Prevent button triggers LongPress event again + } + TEST_ASSERT_MESSAGE(handle == valid_message.handle, "check handle failed"); + TEST_ASSERT_MESSAGE(valid_message.element_type == TOUCH_ELEM_TYPE_BUTTON, "check element type failed"); + TEST_ASSERT_MESSAGE(message->event == button_message->event, "check event failed"); + xSemaphoreGive(monitor->response_sig_handle); +} diff --git a/components/touch_element/test/test_touch_element.c b/components/touch_element/test/test_touch_element.c new file mode 100644 index 000000000000..883195021ab3 --- /dev/null +++ b/components/touch_element/test/test_touch_element.c @@ -0,0 +1,412 @@ +/* ---------------------------------------------------------- README ------------------------------------------------ + * This doc is aimed at explain some important code block and do some records for the test result, if developer or + * test-owner has some question in reading this code implementation, please read it first. + * + * CODE Block: + * `code-block-1`: Touch Element lib need some time to finish the initialization so as to configure the right threshold. + * Since some hardware issue(Must to pass 2 times "meas_done" interrupt), Touch Element lib will spend + * some time(Maybe <30ms) to finish the initialization, every operations (interrupts) happen to touch + * sensor will be ignored before initialization. That's why "vTaskDelay()" could be saw in after call + * "touch_element_start()". However, this just for the unit test, in the real application, users don't + * need to delay something. + * + * NOTES: + * `Simulator`: Currently the event simulator depend on the touch sensor driver and play some "hack" in some register so + * as to raise a FAKE interrupt. It means that Touch Element lib test case must be burned on dev-kit and keep + * the touch channel as clean as possible, ESP32-S2-Saola is good test board. //TODO: Remove the dependent of touch sensor driver. + ------------------------------------------------------------------------------------------------------------------ */ + +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "unity.h" + +#include "touch_element/touch_button.h" +#include "touch_element/touch_slider.h" +#include "touch_element/touch_matrix.h" + +typedef struct { + QueueHandle_t valid_msg_handle; + SemaphoreHandle_t response_sig_handle; +} test_monitor_t; + +/* ------------------------------------------------------------------------------------------------------------------ */ +extern void test_button_event_simulator(touch_button_handle_t button_handle, touch_button_event_t button_event); +extern void test_button_handler(touch_button_handle_t handle, touch_button_message_t *message, void *arg); +extern void test_button_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message); +extern void test_button_event_trigger_and_check(touch_button_handle_t handle, touch_button_event_t button_event); +extern void test_button_callback_trigger_and_check(touch_button_handle_t handle, touch_button_event_t button_event, bool should_trigger, test_monitor_t *monitor); +extern void test_slider_event_simulator(touch_slider_handle_t slider_handle, touch_slider_event_t slider_event, uint32_t random); +extern void test_slider_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message); +extern void test_matrix_event_simulator(touch_matrix_handle_t matrix_handle, touch_matrix_event_t matrix_event, uint32_t pos_index); +extern void test_matrix_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message); +/* ------------------------------------------------------------------------------------------------------------------ */ +static void test_waterproof_event_simulator(touch_pad_t guard_channel, touch_button_event_t guard_state); +static void test_system_waterproof_guard(void); +static void test_integrat_btn_sld_mat(void); +static void test_integration_monitor_task(void *arg); +/* ------------------------------------------------------------------------------------------------------------------ */ +TEST_CASE("Touch element integration test", "[touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_integrat_btn_sld_mat(); + touch_element_uninstall(); +} + +TEST_CASE("Touch element waterproof test", "[touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_system_waterproof_guard(); //TODO: add waterproof work with slider and matrix + touch_element_uninstall(); +} + +static void test_system_waterproof_guard(void) +{ + static const touch_pad_t button_channel_array[12] = { + TOUCH_PAD_NUM1, + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3, + TOUCH_PAD_NUM4, + TOUCH_PAD_NUM5, + TOUCH_PAD_NUM6, + TOUCH_PAD_NUM7, + TOUCH_PAD_NUM8, + TOUCH_PAD_NUM9, + TOUCH_PAD_NUM10, + TOUCH_PAD_NUM11, + TOUCH_PAD_NUM12 + }; + const uint8_t BUTTON_CHANNEL_NUM = sizeof(button_channel_array) / sizeof(touch_pad_t); + + test_monitor_t monitor; + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + touch_button_global_config_t global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&global_config)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = 0.1F + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, (void *)&monitor)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_button_set_callback(button_handle[i], test_button_handler)); + } + printf("Touch Element waterproof guard sensor test start\n"); + + srandom((unsigned int)time(NULL)); + {//No use waterproof guard sensor + touch_elem_waterproof_config_t waterproof_config = { + .guard_channel = TOUCH_WATERPROOF_GUARD_NOUSE, + .guard_sensitivity = 0.0F + }; + TEST_ESP_OK(touch_element_waterproof_install(&waterproof_config)); + TEST_ESP_OK(touch_element_start()); + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + for (int i = 0; i < 10; i++) { //Start state test + printf("Touch Element waterproof no-use guard sensor test... (%d/10)\n", i + 1); + touch_button_handle_t current_handle = button_handle[random() % 12]; + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_PRESS, true, &monitor); + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_RELEASE, true, &monitor); + } + TEST_ESP_OK(touch_element_stop()); + touch_element_waterproof_uninstall(); + } + + {//Use waterproof guard sensor(Add all handles) + touch_elem_waterproof_config_t waterproof_config = { + .guard_channel = TOUCH_PAD_NUM13, + .guard_sensitivity = 0.1F + }; + TEST_ESP_OK(touch_element_waterproof_install(&waterproof_config)); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_element_waterproof_add(button_handle[i])); + } + TEST_ESP_OK(touch_element_start()); + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + for (int i = 0; i < 10; i++) { + printf("Touch Element waterproof use guard sensor random trigger test... (%d/10)\n", i + 1); + bool should_trigger = random() % 2; + if (should_trigger) { + touch_button_handle_t current_handle = button_handle[random() % 12]; + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_PRESS, should_trigger, &monitor); + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_RELEASE, should_trigger, &monitor); + } else { + test_waterproof_event_simulator(waterproof_config.guard_channel, TOUCH_BUTTON_EVT_ON_PRESS); //Waterproof guard sensor trigger + touch_button_handle_t current_handle = button_handle[random() % 12]; + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_PRESS, should_trigger, &monitor); + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_RELEASE, should_trigger, &monitor); + test_waterproof_event_simulator(waterproof_config.guard_channel, TOUCH_BUTTON_EVT_ON_RELEASE); //Waterproof guard sensor release + } + } + TEST_ESP_OK(touch_element_stop()); + touch_element_waterproof_uninstall(); + } + + {//Put half button handles into guard ring + const uint8_t protect_handle_threshold = BUTTON_CHANNEL_NUM / 2; + touch_elem_waterproof_config_t waterproof_config = { + .guard_channel = TOUCH_PAD_NUM13, + .guard_sensitivity = 0.1F + }; + TEST_ESP_OK(touch_element_waterproof_install(&waterproof_config)); + for (int i = 0; i < protect_handle_threshold; i++) { + TEST_ESP_OK(touch_element_waterproof_add(button_handle[i])); + } + TEST_ESP_OK(touch_element_start()); + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + for (int i = 0; i < 10; i++) { + printf("Touch Element waterproof use guard sensor test(guard sensor is triggered will half button handles)... (%d/10)\n", i + 1); + test_waterproof_event_simulator(waterproof_config.guard_channel, TOUCH_BUTTON_EVT_ON_PRESS); //Waterproof guard sensor trigger + uint32_t handle_index = random() % 12; + touch_button_handle_t current_handle = button_handle[handle_index]; + bool should_trigger = (handle_index < protect_handle_threshold) ? false : true; + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_PRESS, should_trigger, &monitor); + test_button_callback_trigger_and_check(current_handle, TOUCH_BUTTON_EVT_ON_RELEASE, should_trigger, &monitor); + test_waterproof_event_simulator(waterproof_config.guard_channel, TOUCH_BUTTON_EVT_ON_RELEASE); //Waterproof guard sensor release + } + TEST_ESP_OK(touch_element_stop()); + touch_element_waterproof_uninstall(); + } + + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + touch_button_uninstall(); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); + printf("Touch Element waterproof guard sensor test finish\n"); +} + +static void test_waterproof_event_simulator(touch_pad_t guard_channel, touch_button_event_t guard_state) +{ + if (guard_state == TOUCH_BUTTON_EVT_ON_PRESS) { + touch_pad_set_cnt_mode(guard_channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + } else if (guard_state == TOUCH_BUTTON_EVT_ON_RELEASE) { + touch_pad_set_cnt_mode(guard_channel, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + } else { + printf("guard sensor simulator doesn't support this operation\n"); + } + /* Fixme: If the normal instance and guard sensor trigger at the same time, guard sensor will lock the state failed */ + vTaskDelay(pdMS_TO_TICKS(100)); +} + +static void test_integrat_btn_sld_mat(void) +{ + static const touch_pad_t button_channel_array[3] = { + TOUCH_PAD_NUM1, + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3 + }; + static const float button_sens_array[3] = { + 0.1F, + 0.1F, + 0.1F + }; + static const touch_pad_t slider_channel_array[5] = { + TOUCH_PAD_NUM4, + TOUCH_PAD_NUM5, + TOUCH_PAD_NUM6, + TOUCH_PAD_NUM7, + TOUCH_PAD_NUM8 + }; + static const float slider_sens_array[5] = { + 0.1F, + 0.1F, + 0.1F, + 0.1F, + 0.1F + }; + static const touch_pad_t x_axis_channel[3] = { + TOUCH_PAD_NUM9, + TOUCH_PAD_NUM10, + TOUCH_PAD_NUM11, + }; + static const touch_pad_t y_axis_channel[3] = { + TOUCH_PAD_NUM12, + TOUCH_PAD_NUM13, + TOUCH_PAD_NUM14, + }; + static const float x_axis_channel_sens[3] = { + 0.1F, + 0.1F, + 0.1F, + }; + static const float y_axis_channel_sens[3] = { + 0.1F, + 0.1F, + 0.1F, + }; + const uint8_t BUTTON_CHANNEL_NUM = sizeof(button_channel_array) / sizeof(touch_pad_t); + const uint8_t SLIDER_CHANNEL_NUM = sizeof(slider_channel_array) / sizeof(touch_pad_t); + const uint8_t MATRIX_CHANNEL_NUM_X = sizeof(x_axis_channel) / sizeof(touch_pad_t); + const uint8_t MATRIX_CHANNEL_NUM_Y = sizeof(y_axis_channel) / sizeof(touch_pad_t); + + printf("Integration test(button + slider + matrix) start\n"); + + BaseType_t os_ret; + touch_button_handle_t button_handle[BUTTON_CHANNEL_NUM]; + touch_slider_handle_t slider_handle; + touch_matrix_handle_t matrix_handle; + test_monitor_t monitor; + TaskHandle_t task_handle = NULL; + + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + os_ret = xTaskCreate(&test_integration_monitor_task, "test_integration_monitor_task", 4096, (void *)&monitor, 5, &task_handle); + TEST_ASSERT(monitor.valid_msg_handle != NULL && monitor.response_sig_handle != NULL && os_ret == pdPASS); + + touch_button_global_config_t button_global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG(); + touch_slider_global_config_t slider_global_config = TOUCH_SLIDER_GLOBAL_DEFAULT_CONFIG(); + touch_matrix_global_config_t matrix_global_config = TOUCH_MATRIX_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_button_install(&button_global_config)); + TEST_ESP_OK(touch_slider_install(&slider_global_config)); + TEST_ESP_OK(touch_matrix_install(&matrix_global_config)); + + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + touch_button_config_t button_config = { + .channel_num = button_channel_array[i], + .channel_sens = button_sens_array[i] + }; + TEST_ESP_OK(touch_button_create(&button_config, &button_handle[i])); + TEST_ESP_OK(touch_button_subscribe_event(button_handle[i], TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, NULL)); + TEST_ESP_OK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_EVENT)); + } + + touch_slider_config_t slider_config = { + .channel_array = slider_channel_array, + .sensitivity_array = slider_sens_array, + .channel_num = SLIDER_CHANNEL_NUM, + .position_range = 101 + }; + TEST_ESP_OK(touch_slider_create(&slider_config, &slider_handle)); + TEST_ESP_OK(touch_slider_subscribe_event(slider_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, NULL)); + TEST_ESP_OK(touch_slider_set_dispatch_method(slider_handle, TOUCH_ELEM_DISP_EVENT)); + + touch_matrix_config_t matrix_config = { + .x_channel_array = x_axis_channel, + .y_channel_array = y_axis_channel, + .x_sensitivity_array = x_axis_channel_sens, + .y_sensitivity_array = y_axis_channel_sens, + .x_channel_num = MATRIX_CHANNEL_NUM_X, + .y_channel_num = MATRIX_CHANNEL_NUM_Y + }; + TEST_ESP_OK(touch_matrix_create(&matrix_config, &matrix_handle)); + TEST_ESP_OK(touch_matrix_subscribe_event(matrix_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, NULL)); + TEST_ESP_OK(touch_matrix_set_dispatch_method(matrix_handle, TOUCH_ELEM_DISP_EVENT)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + for (int i = 0; i < 30; i++) { + printf("Integration test... (%d/30)\n", i + 1); + touch_elem_message_t valid_message; + valid_message.element_type = (random() % (TOUCH_ELEM_TYPE_MATRIX + 1)); + if (valid_message.element_type == TOUCH_ELEM_TYPE_BUTTON) { + uint32_t button_index = random() % BUTTON_CHANNEL_NUM; + valid_message.handle = button_handle[button_index]; + touch_button_message_t button_message = { + .event = TOUCH_BUTTON_EVT_ON_PRESS + }; + memcpy(valid_message.child_msg, &button_message, sizeof(button_message)); //Construct child message + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + test_button_event_simulator(valid_message.handle, button_message.event); + } else if (valid_message.element_type == TOUCH_ELEM_TYPE_SLIDER) { + valid_message.handle = slider_handle; + touch_slider_message_t slider_message = { + .event = TOUCH_SLIDER_EVT_ON_PRESS, + .position = 0 //No check + }; + memcpy(valid_message.child_msg, &slider_message, sizeof(slider_message)); //Construct child message + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + test_slider_event_simulator(valid_message.handle, slider_message.event, 1); + } else if (valid_message.element_type == TOUCH_ELEM_TYPE_MATRIX) { + uint32_t matrix_x_axis_index = random() % MATRIX_CHANNEL_NUM_X; + uint32_t matrix_y_axis_index = random() % MATRIX_CHANNEL_NUM_Y; + valid_message.handle = matrix_handle; + touch_matrix_message_t matrix_message = { + .event = TOUCH_MATRIX_EVT_ON_PRESS, + .position.x_axis = matrix_x_axis_index, + .position.y_axis = matrix_y_axis_index, + .position.index = matrix_x_axis_index * MATRIX_CHANNEL_NUM_Y + matrix_y_axis_index + }; + memcpy(valid_message.child_msg, &matrix_message, sizeof(matrix_message)); //Construct child message + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + test_matrix_event_simulator(valid_message.handle, matrix_message.event, matrix_message.position.index); + } + os_ret = xSemaphoreTake(monitor.response_sig_handle, pdMS_TO_TICKS(500)); + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "response queue timeout (500ms)"); + + if (valid_message.element_type == TOUCH_ELEM_TYPE_BUTTON) { + touch_button_message_t button_message; + button_message.event = TOUCH_BUTTON_EVT_ON_RELEASE; + memcpy(valid_message.child_msg, &button_message, sizeof(button_message)); + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + test_button_event_simulator(valid_message.handle, button_message.event); + } else if (valid_message.element_type == TOUCH_ELEM_TYPE_SLIDER) { + touch_slider_message_t slider_message; + slider_message.event = TOUCH_SLIDER_EVT_ON_RELEASE; + memcpy(valid_message.child_msg, &slider_message, sizeof(slider_message)); + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + test_slider_event_simulator(valid_message.handle, slider_message.event, 1); + } else if (valid_message.element_type == TOUCH_ELEM_TYPE_MATRIX) { + touch_matrix_message_t matrix_message; + matrix_message.event = TOUCH_MATRIX_EVT_ON_RELEASE; + memcpy(valid_message.child_msg, &matrix_message, sizeof(matrix_message)); + xQueueSend(monitor.valid_msg_handle, &valid_message, portMAX_DELAY); + const touch_matrix_message_t *matrix_message_ptr = touch_matrix_get_message(&valid_message); + test_matrix_event_simulator(valid_message.handle, matrix_message.event, matrix_message_ptr->position.index); + } + os_ret = xSemaphoreTake(monitor.response_sig_handle, pdMS_TO_TICKS(500)); + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "response queue timeout (500ms)"); + } + + TEST_ESP_OK(touch_element_stop()); + for (int i = 0; i < BUTTON_CHANNEL_NUM; i++) { + TEST_ESP_OK(touch_button_delete(button_handle[i])); + } + TEST_ESP_OK(touch_slider_delete(slider_handle)); + TEST_ESP_OK(touch_matrix_delete(matrix_handle)); + touch_button_uninstall(); + touch_slider_uninstall(); + touch_matrix_uninstall(); + + while (eTaskGetState(task_handle) == eRunning) { + vTaskDelay(pdTICKS_TO_MS(1)); + } + vTaskDelete(task_handle); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); + printf("Integration test(button + slider + matrix) finish\n"); +} + +static void test_integration_monitor_task(void *arg) +{ + test_monitor_t *monitor = (test_monitor_t *)arg; + BaseType_t os_ret; + touch_elem_message_t current_message, valid_message; + while (1) { + touch_element_message_receive(¤t_message, portMAX_DELAY); + os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(500)); //Get the valid message for the verification, 500ms timeout + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "trigger queue timeout (500ms)"); + if (current_message.element_type == TOUCH_ELEM_TYPE_BUTTON) { + test_button_event_check(&valid_message, ¤t_message); + } else if (current_message.element_type == TOUCH_ELEM_TYPE_SLIDER) { + test_slider_event_check(&valid_message, ¤t_message); + } else if (current_message.element_type == TOUCH_ELEM_TYPE_MATRIX) { + test_matrix_event_check(&valid_message, ¤t_message); + } + xSemaphoreGive(monitor->response_sig_handle); + } +} diff --git a/components/touch_element/test/test_touch_matrix.c b/components/touch_element/test/test_touch_matrix.c new file mode 100644 index 000000000000..1f2ca7557f2e --- /dev/null +++ b/components/touch_element/test/test_touch_matrix.c @@ -0,0 +1,442 @@ +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "unity.h" + +#include "touch_element/touch_element_private.h" +#include "touch_element/touch_matrix.h" + +static const touch_pad_t x_axis_channel[3] = { + TOUCH_PAD_NUM5, + TOUCH_PAD_NUM7, + TOUCH_PAD_NUM9, +}; +static const touch_pad_t y_axis_channel[3] = { + TOUCH_PAD_NUM11, + TOUCH_PAD_NUM12, + TOUCH_PAD_NUM14, +}; +static const float x_axis_channel_sens[3] = { + 0.1F, + 0.1F, + 0.1F, +}; +static const float y_axis_channel_sens[3] = { + 0.1F, + 0.1F, + 0.1F, +}; +const uint8_t MATRIX_CHANNEL_NUM_X = sizeof(x_axis_channel) / sizeof(touch_pad_t); +const uint8_t MATRIX_CHANNEL_NUM_Y = sizeof(y_axis_channel) / sizeof(touch_pad_t); + +typedef struct { + QueueHandle_t valid_msg_handle; + SemaphoreHandle_t response_sig_handle; +} test_monitor_t; + +/* ------------------------------------------------------------------------------------------------------------------ */ +void test_matrix_event_simulator(touch_matrix_handle_t matrix_handle, touch_matrix_event_t matrix_event, uint32_t pos_index); +static void test_matrix_channel_simulator(touch_pad_t channel, touch_matrix_event_t matrix_event); +void test_matrix_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message); +static void test_matrix_callback_check(touch_matrix_handle_t current_handle, touch_matrix_message_t *current_message, touch_elem_message_t *valid_message); +void test_matrix_event_trigger_and_check(touch_matrix_handle_t handle, touch_matrix_event_t matrix_event, uint32_t pos_index); +void test_matrix_callback_trigger_and_check(touch_matrix_handle_t handle, touch_matrix_event_t matrix_event, uint32_t pos_index, bool should_trigger, test_monitor_t *monitor); +/* ------------------------------------------------ Dispatch method test -------------------------------------------- */ +static void test_matrix_disp_event(void); +static void test_matrix_disp_callback(void); +static void test_matrix_handler(touch_matrix_handle_t handle, touch_matrix_message_t *message, void *arg); +/* ------------------------------------------------ Run-time test --------------------------------------------------- */ +static void test_matrix_event_change_lp(void); +static void test_matrix_callback_change_lp(void); +static void test_matrix_change_lp_handler(touch_matrix_handle_t out_handle, touch_matrix_message_t *out_message, void *arg); +/* ----------------------------------------------- Random channel trigger test -------------------------------------- */ +static void test_matrix_random_channel_trigger(void); +/* ------------------------------------------------------------------------------------------------------------------ */ + +TEST_CASE("Touch matrix dispatch methods test", "[matrix][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_matrix_disp_event(); + test_matrix_disp_callback(); + touch_element_uninstall(); +} + +TEST_CASE("Touch matrix run-time test", "[matrix][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_matrix_event_change_lp(); + test_matrix_callback_change_lp(); + touch_element_uninstall(); +} + +TEST_CASE("Touch matrix random channel trigger test", "[matrix][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_matrix_random_channel_trigger(); + touch_element_uninstall(); +} + +void test_matrix_event_simulator(touch_matrix_handle_t matrix_handle, touch_matrix_event_t matrix_event, uint32_t pos_index) +{ + te_matrix_handle_t te_matrix = (te_matrix_handle_t) matrix_handle; + touch_pad_t x_channel = te_matrix->device[pos_index / te_matrix->y_channel_num]->channel; + touch_pad_t y_channel = te_matrix->device[te_matrix->x_channel_num + (pos_index % te_matrix->y_channel_num)]->channel; + if (matrix_event == TOUCH_MATRIX_EVT_ON_PRESS) { + touch_pad_set_cnt_mode(x_channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + touch_pad_set_cnt_mode(y_channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + } else if (matrix_event == TOUCH_MATRIX_EVT_ON_RELEASE) { + touch_pad_set_cnt_mode(x_channel, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + touch_pad_set_cnt_mode(y_channel, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + } else { + touch_pad_set_cnt_mode(x_channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); // LongPress + touch_pad_set_cnt_mode(y_channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + } +} + +static void test_matrix_channel_simulator(touch_pad_t channel, touch_matrix_event_t matrix_event) +{ + if (matrix_event == TOUCH_MATRIX_EVT_ON_PRESS) { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + } else if (matrix_event == TOUCH_MATRIX_EVT_ON_RELEASE) { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + } +} + +void test_matrix_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message) +{ + TEST_ASSERT_MESSAGE(current_message->handle == valid_message->handle, "check handle failed"); + TEST_ASSERT_MESSAGE(current_message->element_type == valid_message->element_type, "check element type failed"); + const touch_matrix_message_t *valid_matrix_message = touch_matrix_get_message(valid_message); + const touch_matrix_message_t *current_matrix_message = touch_matrix_get_message(current_message); + TEST_ASSERT_MESSAGE(current_matrix_message->event == valid_matrix_message->event, "check event failed"); + TEST_ASSERT_MESSAGE(current_matrix_message->position.index == valid_matrix_message->position.index, "check index failed"); + TEST_ASSERT_MESSAGE(current_matrix_message->position.x_axis == valid_matrix_message->position.x_axis, "check x_axis failed"); + TEST_ASSERT_MESSAGE(current_matrix_message->position.y_axis == valid_matrix_message->position.y_axis, "check y_axis failed"); +} + +static inline void test_matrix_callback_check(touch_matrix_handle_t current_handle, touch_matrix_message_t *current_message, touch_elem_message_t *valid_message) +{ + const touch_matrix_message_t *valid_matrix_message = touch_matrix_get_message(valid_message); + TEST_ASSERT_MESSAGE(valid_message->handle == current_handle, "check handle failed"); + TEST_ASSERT_MESSAGE(valid_message->element_type == TOUCH_ELEM_TYPE_MATRIX, "check element type failed"); + TEST_ASSERT_MESSAGE(valid_matrix_message->event == current_message->event, "check event failed"); + TEST_ASSERT_MESSAGE(valid_matrix_message->position.index == current_message->position.index, "check index failed"); + TEST_ASSERT_MESSAGE(valid_matrix_message->position.x_axis == current_message->position.x_axis, "check x_axis failed"); + TEST_ASSERT_MESSAGE(valid_matrix_message->position.y_axis == current_message->position.y_axis, "check y_axis failed"); +} + +void test_matrix_event_trigger_and_check(touch_matrix_handle_t handle, touch_matrix_event_t matrix_event, uint32_t pos_index) +{ + touch_elem_message_t valid_message = { + .handle = handle, + .element_type = TOUCH_ELEM_TYPE_MATRIX, + .arg = NULL + }; + touch_matrix_message_t matrix_message = { + .event = matrix_event, + .position.index = pos_index, + .position.x_axis = pos_index / MATRIX_CHANNEL_NUM_Y, + .position.y_axis = pos_index % MATRIX_CHANNEL_NUM_Y + }; + memcpy(valid_message.child_msg, &matrix_message, sizeof(touch_matrix_message_t)); //Construct valid_message + + test_matrix_event_simulator(handle, matrix_event, pos_index); //Trigger signal + + touch_elem_message_t current_message; + te_matrix_handle_t te_matrix = handle; + esp_err_t ret = touch_element_message_receive(¤t_message, pdMS_TO_TICKS(2 * te_matrix->trigger_thr * 10)); //Get current message for verification + TEST_ASSERT_MESSAGE(ret == ESP_OK, "matrix event receive timeout"); + + test_matrix_event_check(&valid_message, ¤t_message); //Verification +} + +void test_matrix_callback_trigger_and_check(touch_matrix_handle_t handle, touch_matrix_event_t matrix_event, uint32_t pos_index, bool should_trigger, test_monitor_t *monitor) +{ + if (should_trigger) { + touch_elem_message_t valid_message = { + .handle = handle, + .element_type = TOUCH_ELEM_TYPE_MATRIX, + .arg = NULL + }; + touch_matrix_message_t matrix_message = { + .event = matrix_event, + .position.index = pos_index, + .position.x_axis = pos_index / MATRIX_CHANNEL_NUM_Y, + .position.y_axis = pos_index % MATRIX_CHANNEL_NUM_Y + }; + memcpy(valid_message.child_msg, &matrix_message, sizeof(touch_matrix_message_t)); //Construct valid_message + xQueueSend(monitor->valid_msg_handle, &valid_message, portMAX_DELAY); + } + + test_matrix_event_simulator(handle, matrix_event, pos_index); //Trigger signal + + te_matrix_handle_t te_matrix = handle; + if (should_trigger) { + BaseType_t os_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(2 * te_matrix->trigger_thr * 10)); + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "Matrix queue timeout"); + } else { + BaseType_t os_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(500)); + TEST_ASSERT_MESSAGE(os_ret == pdFALSE, "Matrix invalid trigger"); + } +} + +static void test_matrix_disp_event(void) +{ + touch_matrix_handle_t matrix_handle = NULL; + touch_matrix_global_config_t global_config = TOUCH_MATRIX_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_matrix_install(&global_config)); + touch_matrix_config_t matrix_config = { + .x_channel_array = x_axis_channel, + .y_channel_array = y_axis_channel, + .x_sensitivity_array = x_axis_channel_sens, + .y_sensitivity_array = y_axis_channel_sens, + .x_channel_num = MATRIX_CHANNEL_NUM_X, + .y_channel_num = MATRIX_CHANNEL_NUM_Y + }; + TEST_ESP_OK(touch_matrix_create(&matrix_config, &matrix_handle)); + TEST_ESP_OK(touch_matrix_subscribe_event(matrix_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_LONGPRESS | TOUCH_ELEM_EVENT_ON_RELEASE, NULL)); + TEST_ESP_OK(touch_matrix_set_longpress(matrix_handle, 300)); + TEST_ESP_OK(touch_matrix_set_dispatch_method(matrix_handle, TOUCH_ELEM_DISP_EVENT)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + printf("Touch matrix event test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch matrix event test... (%d/10)\n", i + 1); + uint32_t button_num = random() % ( MATRIX_CHANNEL_NUM_X * MATRIX_CHANNEL_NUM_Y ); + test_matrix_event_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_PRESS, button_num); + test_matrix_event_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_LONGPRESS, button_num); + test_matrix_event_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_RELEASE, button_num); + } + printf("Touch matrix event test finish\n"); + + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_matrix_delete(matrix_handle)); + touch_matrix_uninstall(); +} + +static void test_matrix_disp_callback(void) +{ + test_monitor_t monitor; + touch_matrix_handle_t matrix_handle = NULL; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + + touch_matrix_global_config_t global_config = TOUCH_MATRIX_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_matrix_install(&global_config)); + touch_matrix_config_t matrix_config = { + .x_channel_array = x_axis_channel, + .y_channel_array = y_axis_channel, + .x_sensitivity_array = x_axis_channel_sens, + .y_sensitivity_array = y_axis_channel_sens, + .x_channel_num = MATRIX_CHANNEL_NUM_X, + .y_channel_num = MATRIX_CHANNEL_NUM_Y + }; + TEST_ESP_OK(touch_matrix_create(&matrix_config, &matrix_handle)); + TEST_ESP_OK(touch_matrix_subscribe_event(matrix_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_LONGPRESS | TOUCH_ELEM_EVENT_ON_RELEASE, (void *)&monitor)); + TEST_ESP_OK(touch_matrix_set_longpress(matrix_handle, 300)); + TEST_ESP_OK(touch_matrix_set_dispatch_method(matrix_handle, TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_matrix_set_callback(matrix_handle, test_matrix_handler)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + printf("Touch matrix callback test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch matrix callback test... (%d/10)\n", i + 1); + uint32_t button_num = random() % (MATRIX_CHANNEL_NUM_X * MATRIX_CHANNEL_NUM_Y); + test_matrix_callback_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_PRESS, button_num, true, &monitor); + test_matrix_callback_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_LONGPRESS, button_num, true, &monitor); + test_matrix_callback_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_RELEASE, button_num, true, &monitor); + } + printf("Touch matrix callback test finish\n"); + + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_matrix_delete(matrix_handle)); + touch_matrix_uninstall(); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); +} + +static void test_matrix_handler(touch_matrix_handle_t handle, touch_matrix_message_t *message, void *arg) +{ + test_monitor_t *monitor = (test_monitor_t *)arg; + touch_elem_message_t valid_message; + BaseType_t os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(200)); + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "test_matrix_handler: queue timeout"); + test_matrix_callback_check(handle, message, &valid_message); + xSemaphoreGive(monitor->response_sig_handle); +} + +static void test_matrix_random_channel_trigger(void) +{ + test_monitor_t monitor; + touch_matrix_handle_t matrix_handle = NULL; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + + touch_matrix_global_config_t global_config = TOUCH_MATRIX_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_matrix_install(&global_config)); + touch_matrix_config_t matrix_config = { + .x_channel_array = x_axis_channel, + .y_channel_array = y_axis_channel, + .x_sensitivity_array = x_axis_channel_sens, + .y_sensitivity_array = y_axis_channel_sens, + .x_channel_num = MATRIX_CHANNEL_NUM_X, + .y_channel_num = MATRIX_CHANNEL_NUM_Y + }; + TEST_ESP_OK(touch_matrix_create(&matrix_config, &matrix_handle)); + TEST_ESP_OK(touch_matrix_subscribe_event(matrix_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, (void *) &monitor)); + TEST_ESP_OK(touch_matrix_set_dispatch_method(matrix_handle, TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_matrix_set_callback(matrix_handle, test_matrix_handler)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + printf("Touch matrix random channel trigger test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch matrix random channel trigger test... (%d/10)\n", i + 1); + uint32_t channel_index_1 = random() % (MATRIX_CHANNEL_NUM_X + MATRIX_CHANNEL_NUM_Y); + uint32_t channel_index_2 = random() % (MATRIX_CHANNEL_NUM_X + MATRIX_CHANNEL_NUM_Y); + touch_pad_t channel_1 = (channel_index_1 < MATRIX_CHANNEL_NUM_X) ? x_axis_channel[channel_index_1] : y_axis_channel[channel_index_1 - MATRIX_CHANNEL_NUM_X]; + touch_pad_t channel_2 = (channel_index_2 < MATRIX_CHANNEL_NUM_X) ? x_axis_channel[channel_index_2] : y_axis_channel[channel_index_2 - MATRIX_CHANNEL_NUM_X]; + if ((channel_index_1 <= 2 && channel_index_2 <= 2) || (channel_index_1 > 2 && channel_index_2 > 2)) { //all x channels triggered or all y channels triggered + //Should not be triggered + BaseType_t os_ret; + test_matrix_channel_simulator(channel_1, TOUCH_MATRIX_EVT_ON_PRESS); + test_matrix_channel_simulator(channel_2, TOUCH_MATRIX_EVT_ON_PRESS); + os_ret = xSemaphoreTake(monitor.response_sig_handle, pdMS_TO_TICKS(500)); + TEST_ASSERT_MESSAGE(os_ret == pdFAIL, "Matrix Press event invalid trigger"); + + test_matrix_channel_simulator(channel_1, TOUCH_MATRIX_EVT_ON_RELEASE); + test_matrix_channel_simulator(channel_2, TOUCH_MATRIX_EVT_ON_RELEASE); + os_ret = xSemaphoreTake(monitor.response_sig_handle, pdMS_TO_TICKS(500)); + TEST_ASSERT_MESSAGE(os_ret == pdFAIL, "Matrix Release event invalid trigger"); + } else { + //Should be triggered + uint8_t button_num; + if (channel_index_1 <= 2) { + button_num = channel_index_1 * matrix_config.y_channel_num + (channel_index_2 - MATRIX_CHANNEL_NUM_X); + } else { + button_num = channel_index_2 * matrix_config.x_channel_num + (channel_index_1 - MATRIX_CHANNEL_NUM_Y); + } + test_matrix_callback_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_PRESS, button_num, true, &monitor); + test_matrix_callback_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_RELEASE, button_num, true, &monitor); + } + } + printf("Touch matrix random channel trigger test finish\n"); + + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_matrix_delete(matrix_handle)); + touch_matrix_uninstall(); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); +} + +static void test_matrix_event_change_lp(void) +{ + touch_matrix_handle_t matrix_handle = NULL; + touch_matrix_global_config_t global_config = TOUCH_MATRIX_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_matrix_install(&global_config)); + touch_matrix_config_t matrix_config = { + .x_channel_array = x_axis_channel, + .y_channel_array = y_axis_channel, + .x_sensitivity_array = x_axis_channel_sens, + .y_sensitivity_array = y_axis_channel_sens, + .x_channel_num = MATRIX_CHANNEL_NUM_X, + .y_channel_num = MATRIX_CHANNEL_NUM_Y + }; + TEST_ESP_OK(touch_matrix_create(&matrix_config, &matrix_handle)); + TEST_ESP_OK(touch_matrix_subscribe_event(matrix_handle, TOUCH_ELEM_EVENT_ON_LONGPRESS, NULL)); + TEST_ESP_OK(touch_matrix_set_dispatch_method(matrix_handle, TOUCH_ELEM_DISP_EVENT)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + //10 times random press/longpress/release test + printf("Touch matrix event change longtime test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch matrix event change longtime test... (%d/10)\n", i + 1); + uint32_t button_num = random() % ( MATRIX_CHANNEL_NUM_X * MATRIX_CHANNEL_NUM_Y ); + TEST_ESP_OK(touch_matrix_set_longpress(matrix_handle, 200 + (i + 1) * 50)); + test_matrix_event_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_LONGPRESS, button_num); + test_matrix_event_simulator(matrix_handle, TOUCH_MATRIX_EVT_ON_RELEASE, button_num); //Reset hardware + vTaskDelay(pdMS_TO_TICKS(100)); //Fixme: Waiting for driver core handle release event + } + printf("Touch matrix event change longtime test finish\n"); + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_matrix_delete(matrix_handle)); + touch_matrix_uninstall(); +} + +static void test_matrix_callback_change_lp(void) +{ + test_monitor_t monitor; + touch_matrix_handle_t matrix_handle = NULL; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + + touch_matrix_global_config_t global_config = TOUCH_MATRIX_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_matrix_install(&global_config)); + touch_matrix_config_t matrix_config = { + .x_channel_array = x_axis_channel, + .y_channel_array = y_axis_channel, + .x_sensitivity_array = x_axis_channel_sens, + .y_sensitivity_array = y_axis_channel_sens, + .x_channel_num = MATRIX_CHANNEL_NUM_X, + .y_channel_num = MATRIX_CHANNEL_NUM_Y + }; + TEST_ESP_OK(touch_matrix_create(&matrix_config, &matrix_handle)); + TEST_ESP_OK(touch_matrix_subscribe_event(matrix_handle, TOUCH_ELEM_EVENT_ON_LONGPRESS, (void *)&monitor)); + TEST_ESP_OK(touch_matrix_set_longpress(matrix_handle, 300)); + TEST_ESP_OK(touch_matrix_set_dispatch_method(matrix_handle, TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_matrix_set_callback(matrix_handle, test_matrix_change_lp_handler)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + printf("Touch matrix callback change longtime test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch matrix callback change longtime test... (%d/10)\n", i + 1); + uint32_t button_num = random() % (MATRIX_CHANNEL_NUM_X * MATRIX_CHANNEL_NUM_Y); + test_matrix_callback_trigger_and_check(matrix_handle, TOUCH_MATRIX_EVT_ON_LONGPRESS, button_num, true, &monitor); + test_matrix_event_simulator(matrix_handle, TOUCH_MATRIX_EVT_ON_RELEASE, button_num); //Reset hardware + vTaskDelay(pdMS_TO_TICKS(100)); //Fixme: Waiting for driver core handle release event + + } + printf("Touch matrix callback change longtime test finish\n"); + + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_matrix_delete(matrix_handle)); + touch_matrix_uninstall(); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); +} + +static void test_matrix_change_lp_handler(touch_matrix_handle_t out_handle, touch_matrix_message_t *out_message, void *arg) +{ + test_monitor_t *monitor = (test_monitor_t *)arg; + touch_elem_message_t valid_message; + BaseType_t os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(200)); //500ms timeout + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "test_matrix_handler: queue timeout"); + test_matrix_callback_check(out_handle, out_message, &valid_message); + xSemaphoreGive(monitor->response_sig_handle); + TEST_ESP_OK(touch_matrix_set_longpress(valid_message.handle, 300)); // Always 300ms +} diff --git a/components/touch_element/test/test_touch_slider.c b/components/touch_element/test/test_touch_slider.c new file mode 100644 index 000000000000..47d70ed70d38 --- /dev/null +++ b/components/touch_element/test/test_touch_slider.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "unity.h" + +#include "touch_element/touch_element_private.h" +#include "touch_element/touch_slider.h" + +static const touch_pad_t slider_channel_array[5] = { + TOUCH_PAD_NUM1, + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3, + TOUCH_PAD_NUM4, + TOUCH_PAD_NUM5 +}; +static const float slider_sens_array[5] = { + 0.1F, + 0.1F, + 0.1F, + 0.1F, + 0.1F +}; +const uint8_t SLIDER_CHANNEL_NUM = sizeof(slider_channel_array) / sizeof(touch_pad_t); + +typedef struct { + QueueHandle_t valid_msg_handle; + SemaphoreHandle_t response_sig_handle; +} test_monitor_t; + +/* ------------------------------------------------------------------------------------------------------------------ */ +void test_slider_event_simulator(touch_slider_handle_t slider_handle, touch_slider_event_t slider_event, uint32_t random); +void test_slider_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message); +static void test_slider_callback_check(touch_slider_handle_t current_handle, touch_slider_message_t *current_message, touch_elem_message_t *valid_message); +void test_slider_event_trigger_and_check(touch_slider_handle_t handle, touch_slider_event_t slider_event, uint32_t random_channel); +void test_slider_callback_trigger_and_check(touch_slider_handle_t handle, touch_slider_event_t slider_event, bool should_trigger, test_monitor_t *monitor, uint32_t random_channel); +/* ------------------------------------------------ Dispatch method test -------------------------------------------- */ +static void test_slider_disp_event(void); +static void test_slider_disp_callback(void); +static void test_slider_handler(touch_slider_handle_t handle, touch_slider_message_t *message, void *arg); +/* ------------------------------------------------------------------------------------------------------------------ */ + +TEST_CASE("Touch slider dispatch methods test", "[slider][touch_element]") +{ + touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_element_install(&global_config)); + test_slider_disp_event(); + test_slider_disp_callback(); + touch_element_uninstall(); +} + +void test_slider_event_simulator(touch_slider_handle_t slider_handle, touch_slider_event_t slider_event, uint32_t random) +{ + te_slider_handle_t te_slider = (te_slider_handle_t) slider_handle; + touch_pad_t channel = te_slider->device[random % te_slider->channel_sum]->channel; + if (slider_event == TOUCH_SLIDER_EVT_ON_PRESS) { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); + } else if (slider_event == TOUCH_SLIDER_EVT_ON_RELEASE) { + touch_pad_set_cnt_mode(channel, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + } +} + +void test_slider_event_check(touch_elem_message_t *valid_message, touch_elem_message_t *current_message) +{ + TEST_ASSERT_MESSAGE(current_message->handle == valid_message->handle, "check handle failed"); + TEST_ASSERT_MESSAGE(current_message->element_type == valid_message->element_type, "check element type failed"); + const touch_slider_message_t *valid_slider_message = touch_slider_get_message(valid_message); + const touch_slider_message_t *current_slider_message = touch_slider_get_message(current_message); + TEST_ASSERT_MESSAGE(current_slider_message->event == valid_slider_message->event, "check event failed"); +} + +static void test_slider_callback_check(touch_slider_handle_t current_handle, touch_slider_message_t *current_message, touch_elem_message_t *valid_message) +{ + const touch_slider_message_t *valid_slider_message = touch_slider_get_message(valid_message); + TEST_ASSERT_MESSAGE(valid_message->handle == current_handle, "check handle failed"); + TEST_ASSERT_MESSAGE(valid_message->element_type == TOUCH_ELEM_TYPE_SLIDER, "check element type failed"); + TEST_ASSERT_MESSAGE(valid_slider_message->event == current_message->event, "check event failed"); +} + +void test_slider_event_trigger_and_check(touch_slider_handle_t handle, touch_slider_event_t slider_event, uint32_t random_channel) +{ + touch_elem_message_t valid_message, current_message; + touch_slider_message_t slider_message; + valid_message.handle = handle; + valid_message.element_type = TOUCH_ELEM_TYPE_SLIDER; + slider_message.event = slider_event; + memcpy(valid_message.child_msg, &slider_message, sizeof(touch_slider_message_t)); + test_slider_event_simulator(handle, slider_event, random_channel); + esp_err_t ret = touch_element_message_receive(¤t_message, 300); + TEST_ASSERT_MESSAGE(ret == ESP_OK, "slider event receive timeout"); + test_slider_event_check(&valid_message, ¤t_message); +} + +void test_slider_callback_trigger_and_check(touch_slider_handle_t handle, touch_slider_event_t slider_event, bool should_trigger, test_monitor_t *monitor, uint32_t random_channel) +{ + if (should_trigger) { + touch_elem_message_t valid_message = { + .handle = handle, + .element_type = TOUCH_ELEM_TYPE_SLIDER, + .arg = NULL + }; + touch_slider_message_t slider_message = { + .event = slider_event, + .position = 0 //No use + }; + memcpy(valid_message.child_msg, &slider_message, sizeof(touch_slider_message_t)); //Construct valid_message + xQueueSend(monitor->valid_msg_handle, &valid_message, portMAX_DELAY); + } + + test_slider_event_simulator(handle, slider_event, random_channel); //Trigger signal + + BaseType_t os_ret = xSemaphoreTake(monitor->response_sig_handle, pdMS_TO_TICKS(300)); + if (should_trigger) { + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "Button queue timeout"); + } else { + TEST_ASSERT_MESSAGE(os_ret == pdFALSE, "Button invalid trigger"); + } +} + + +static void test_slider_disp_event(void) +{ + touch_slider_handle_t slider_handle; + touch_slider_global_config_t global_config = TOUCH_SLIDER_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_slider_install(&global_config)); + /*< Create Touch Slider */ + touch_slider_config_t slider_config = { + .channel_array = slider_channel_array, + .sensitivity_array = slider_sens_array, + .channel_num = SLIDER_CHANNEL_NUM, + .position_range = 101 + }; + TEST_ESP_OK(touch_slider_create(&slider_config, &slider_handle)); + TEST_ESP_OK(touch_slider_subscribe_event(slider_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, (void *) slider_handle)); + TEST_ESP_OK(touch_slider_set_dispatch_method(slider_handle, TOUCH_ELEM_DISP_EVENT)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + //10 times random (x channels) press/release test + printf("Touch slider event test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch slider event test... (%d/10)\n", i + 1); + uint32_t random_channel = random() % SLIDER_CHANNEL_NUM; + test_slider_event_trigger_and_check(slider_handle, TOUCH_SLIDER_EVT_ON_PRESS, random_channel); + test_slider_event_trigger_and_check(slider_handle, TOUCH_SLIDER_EVT_ON_RELEASE, random_channel); + } + printf("Touch slider event test finish\n"); + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_slider_delete(slider_handle)); + touch_slider_uninstall(); +} + + +static void test_slider_disp_callback(void) +{ + test_monitor_t monitor; + monitor.valid_msg_handle = xQueueCreate(10, sizeof(touch_elem_message_t)); + monitor.response_sig_handle = xSemaphoreCreateBinary(); + TEST_ASSERT(monitor.valid_msg_handle != NULL || monitor.response_sig_handle != NULL); + + touch_slider_handle_t slider_handle; + touch_slider_global_config_t global_config = TOUCH_SLIDER_GLOBAL_DEFAULT_CONFIG(); + TEST_ESP_OK(touch_slider_install(&global_config)); + touch_slider_config_t slider_config = { + .channel_array = slider_channel_array, + .sensitivity_array = slider_sens_array, + .channel_num = SLIDER_CHANNEL_NUM, + .position_range = 101 + }; + TEST_ESP_OK(touch_slider_create(&slider_config, &slider_handle)); + TEST_ESP_OK(touch_slider_subscribe_event(slider_handle, TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE, (void *) &monitor)); + TEST_ESP_OK(touch_slider_set_dispatch_method(slider_handle, TOUCH_ELEM_DISP_CALLBACK)); + TEST_ESP_OK(touch_slider_set_callback(slider_handle, test_slider_handler)); + TEST_ESP_OK(touch_element_start()); + + vTaskDelay(pdMS_TO_TICKS(500)); //Mention in README, code-block-1 + + srandom((unsigned int)time(NULL)); + printf("Touch slider callback test start\n"); + for (int i = 0; i < 10; i++) { + printf("Touch slider callback test... (%d/10)\n", i + 1); + uint32_t random_channel = random() % SLIDER_CHANNEL_NUM; + test_slider_callback_trigger_and_check(slider_handle, TOUCH_SLIDER_EVT_ON_PRESS, true, &monitor, random_channel); + test_slider_callback_trigger_and_check(slider_handle, TOUCH_SLIDER_EVT_ON_RELEASE, true, &monitor, random_channel); + } + printf("Touch slider callback test finish\n"); + + TEST_ESP_OK(touch_element_stop()); + TEST_ESP_OK(touch_slider_delete(slider_handle)); + touch_slider_uninstall(); + vQueueDelete(monitor.valid_msg_handle); + vSemaphoreDelete(monitor.response_sig_handle); +} + +static void test_slider_handler(touch_slider_handle_t handle, touch_slider_message_t *message, void *arg) +{ + test_monitor_t *monitor = (test_monitor_t *)arg; + touch_elem_message_t valid_message; + BaseType_t os_ret = xQueueReceive(monitor->valid_msg_handle, &valid_message, pdMS_TO_TICKS(200)); //Get the valid message for verification, 200ms timeout + TEST_ASSERT_MESSAGE(os_ret == pdPASS, "test_slider_handler: queue timeout"); + + test_slider_callback_check(handle, message, &valid_message); //Verification + + xSemaphoreGive(monitor->response_sig_handle); +} diff --git a/components/vfs/CMakeLists.txt b/components/vfs/CMakeLists.txt index 48b69be18246..7f51dbeeff9f 100644 --- a/components/vfs/CMakeLists.txt +++ b/components/vfs/CMakeLists.txt @@ -1,13 +1,15 @@ idf_component_register(SRCS "vfs.c" "vfs_uart.c" "vfs_semihost.c" + "vfs_console.c" + PRIV_INCLUDE_DIRS private_include INCLUDE_DIRS include) if(CONFIG_ESP_CONSOLE_USB_CDC) target_sources(${COMPONENT_LIB} PRIVATE "vfs_cdcacm.c") endif() -if(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) +if(CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG OR CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) target_sources(${COMPONENT_LIB} PRIVATE "vfs_usb_serial_jtag.c") endif() diff --git a/components/vfs/component.mk b/components/vfs/component.mk index e880793520ae..d9adffb06c0c 100644 --- a/components/vfs/component.mk +++ b/components/vfs/component.mk @@ -1,3 +1,4 @@ +COMPONENT_PRIV_INCLUDEDIRS := private_include ifndef CONFIG_ESP_CONSOLE_USB_CDC COMPONENT_OBJEXCLUDE := vfs_cdcacm.o endif diff --git a/components/vfs/include/esp_vfs.h b/components/vfs/include/esp_vfs.h index ddbabd975cbc..36f0320dc8a6 100644 --- a/components/vfs/include/esp_vfs.h +++ b/components/vfs/include/esp_vfs.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_VFS_H__ #define __ESP_VFS_H__ @@ -254,7 +246,6 @@ typedef struct #endif // CONFIG_VFS_SUPPORT_SELECT } esp_vfs_t; - /** * Register a virtual filesystem for given path prefix. * @@ -387,7 +378,8 @@ int esp_vfs_utime(const char *path, const struct utimbuf *times); * @param timeout If not NULL, then points to timeval structure which * specifies the time period after which the functions should * time-out and return. If it is NULL, then the function will - * not time-out. + * not time-out. Note that the timeout period is rounded up to + * the system tick and incremented by one. * * @return The number of descriptors set in the descriptor sets, or -1 * when an error (specified by errno) have occurred. diff --git a/components/vfs/include/esp_vfs_cdcacm.h b/components/vfs/include/esp_vfs_cdcacm.h index b8dd03d92aa4..416efb35a4e4 100644 --- a/components/vfs/include/esp_vfs_cdcacm.h +++ b/components/vfs/include/esp_vfs_cdcacm.h @@ -1,16 +1,8 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/vfs/include/esp_vfs_console.h b/components/vfs/include/esp_vfs_console.h new file mode 100644 index 000000000000..bc5ce6733dd8 --- /dev/null +++ b/components/vfs/include/esp_vfs_console.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief add uart/usb_serial_jtag/usb_otg_acmcdc virtual filesystem driver + * + * This function is called from startup code to enable serial output + */ +esp_err_t esp_vfs_console_register(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/vfs/include/esp_vfs_dev.h b/components/vfs/include/esp_vfs_dev.h index 302017846594..91e9374972e3 100644 --- a/components/vfs/include/esp_vfs_dev.h +++ b/components/vfs/include/esp_vfs_dev.h @@ -1,16 +1,8 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -114,6 +106,20 @@ void esp_vfs_dev_uart_use_nonblocking(int uart_num); */ void esp_vfs_dev_uart_use_driver(int uart_num); +/** + * @brief set VFS to use USB-SERIAL-JTAG driver for reading and writing + * @note application must configure USB-SERIAL-JTAG driver before calling these functions + * With these functions, read and write are blocking and interrupt-driven. + */ +void esp_vfs_usb_serial_jtag_use_driver(void); + +/** + * @brief set VFS to use simple functions for reading and writing UART + * Read is non-blocking, write is busy waiting until TX FIFO has enough space. + * These functions are used by default. + */ +void esp_vfs_usb_serial_jtag_use_nonblocking(void); + #ifdef __cplusplus } #endif diff --git a/components/vfs/include/esp_vfs_usb_serial_jtag.h b/components/vfs/include/esp_vfs_usb_serial_jtag.h index 54ff1f4e4442..c53a671be897 100644 --- a/components/vfs/include/esp_vfs_usb_serial_jtag.h +++ b/components/vfs/include/esp_vfs_usb_serial_jtag.h @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/vfs/private_include/esp_vfs_private.h b/components/vfs/private_include/esp_vfs_private.h new file mode 100644 index 000000000000..7a3f9e1e657e --- /dev/null +++ b/components/vfs/private_include/esp_vfs_private.h @@ -0,0 +1,101 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_vfs.h" +#include "esp_vfs_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct vfs_entry_ { + esp_vfs_t vfs; // contains pointers to VFS functions + char path_prefix[ESP_VFS_PATH_MAX]; // path prefix mapped to this VFS + size_t path_prefix_len; // micro-optimization to avoid doing extra strlen + void* ctx; // optional pointer which can be passed to VFS + int offset; // index of this structure in s_vfs array +} vfs_entry_t; + + +/** + * @brief get pointer of uart vfs. + * + * This function is called in vfs_console in order to get the vfs implementation + * of uart. + * + * @return pointer to structure esp_vfs_t + */ +const esp_vfs_t *esp_vfs_uart_get_vfs(void); + +/** + * @brief get pointer of cdcacm vfs. + * + * This function is called in vfs_console in order to get the vfs implementation + * of cdcacm. + * + * @return pointer to structure esp_vfs_t + */ +const esp_vfs_t *esp_vfs_cdcacm_get_vfs(void); + +/** + * @brief get pointer of usb_serial_jtag vfs. + * + * This function is called in vfs_console in order to get the vfs implementation + * of usb_serial_jtag. + * + * @return pointer to structure esp_vfs_nonblocking_console_t + */ +const esp_vfs_t *esp_vfs_usb_serial_jtag_get_vfs(void); + +/** + * Register a virtual filesystem. + * + * @param base_path file path prefix associated with the filesystem. + * Must be a zero-terminated C string, may be empty. + * If not empty, must be up to ESP_VFS_PATH_MAX + * characters long, and at least 2 characters long. + * Name must start with a "/" and must not end with "/". + * For example, "/data" or "/dev/spi" are valid. + * These VFSes would then be called to handle file paths such as + * "/data/myfile.txt" or "/dev/spi/0". + * In the special case of an empty base_path, a "fallback" + * VFS is registered. Such VFS will handle paths which are not + * matched by any other registered VFS. + * @param len Length of the base_path. + * @param vfs Pointer to esp_vfs_t, a structure which maps syscalls to + * the filesystem driver functions. VFS component doesn't + * assume ownership of this pointer. + * @param ctx If vfs->flags has ESP_VFS_FLAG_CONTEXT_PTR set, a pointer + * which should be passed to VFS functions. Otherwise, NULL. + * @param vfs_index Index for getting the vfs content. + * + * @return ESP_OK if successful. + * ESP_ERR_NO_MEM if too many VFSes are registered. + * ESP_ERR_INVALID_ARG if given an invalid parameter. + */ +esp_err_t esp_vfs_register_common(const char *base_path, size_t len, const esp_vfs_t* vfs, void* ctx, int *vfs_index); + +/** + * Get vfs fd with given path. + * + * @param path file path prefix associated with the filesystem. + * + * @return Pointer to the `vfs_entry_t` corresponding to the given path, which cannot be NULL. + */ +const vfs_entry_t *get_vfs_for_path(const char *path); + +/** + * Get vfs fd with given vfs index. + * + * @param index VFS index. + * + * @return Pointer to the `vfs_entry_t` corresponding to the given path, which cannot be NULL. + */ +const vfs_entry_t *get_vfs_for_index(int index); + +#ifdef __cplusplus +} +#endif diff --git a/components/vfs/test/test_vfs_open.c b/components/vfs/test/test_vfs_open.c new file mode 100644 index 000000000000..4db1a386ba35 --- /dev/null +++ b/components/vfs/test/test_vfs_open.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "esp_vfs.h" +#include "unity.h" + +static int open_errno_test_open(const char * path, int flags, int mode) +{ + errno = EIO; + return -1; +} + +TEST_CASE("esp_vfs_open sets correct errno", "[vfs]") +{ + esp_vfs_t desc = { + .open = open_errno_test_open + }; + TEST_ESP_OK(esp_vfs_register("/test", &desc, NULL)); + + int fd = open("/test/path", 0, 0); + int e = errno; + TEST_ASSERT_EQUAL(-1, fd); + TEST_ASSERT_EQUAL(EIO, e); + + fd = open("/nonexistent/path", 0, 0); + e = errno; + TEST_ASSERT_EQUAL(-1, fd); + TEST_ASSERT_EQUAL(ENOENT, e); + + TEST_ESP_OK(esp_vfs_unregister("/test")); +} diff --git a/components/vfs/vfs.c b/components/vfs/vfs.c index 2e3d6ef3c85f..08ec576820a1 100644 --- a/components/vfs/vfs.c +++ b/components/vfs/vfs.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -26,6 +18,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "esp_vfs.h" +#include "esp_vfs_private.h" #include "sdkconfig.h" #ifdef CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT @@ -52,14 +45,6 @@ typedef struct { local_fd_t local_fd; } fd_table_t; -typedef struct vfs_entry_ { - esp_vfs_t vfs; // contains pointers to VFS functions - char path_prefix[ESP_VFS_PATH_MAX]; // path prefix mapped to this VFS - size_t path_prefix_len; // micro-optimization to avoid doing extra strlen - void* ctx; // optional pointer which can be passed to VFS - int offset; // index of this structure in s_vfs array -} vfs_entry_t; - typedef struct { bool isset; // none or at least one bit is set in the following 3 fd sets fd_set readfds; @@ -73,7 +58,7 @@ static size_t s_vfs_count = 0; static fd_table_t s_fd_table[MAX_FDS] = { [0 ... MAX_FDS-1] = FD_TABLE_ENTRY_UNUSED }; static _lock_t s_fd_table_lock; -static esp_err_t esp_vfs_register_common(const char* base_path, size_t len, const esp_vfs_t* vfs, void* ctx, int *vfs_index) +esp_err_t esp_vfs_register_common(const char* base_path, size_t len, const esp_vfs_t* vfs, void* ctx, int *vfs_index) { if (len != LEN_PATH_PREFIX_IGNORED) { /* empty prefix is allowed, "/" is not allowed */ @@ -248,7 +233,7 @@ esp_err_t esp_vfs_unregister_fd(esp_vfs_id_t vfs_id, int fd) return ret; } -static inline const vfs_entry_t *get_vfs_for_index(int index) +const vfs_entry_t *get_vfs_for_index(int index) { if (index < 0 || index >= s_vfs_count) { return NULL; @@ -293,7 +278,7 @@ static const char* translate_path(const vfs_entry_t* vfs, const char* src_path) return src_path + vfs->path_prefix_len; } -static const vfs_entry_t* get_vfs_for_path(const char* path) +const vfs_entry_t* get_vfs_for_path(const char* path) { const vfs_entry_t* best_match = NULL; ssize_t best_match_prefix_len = -1; @@ -407,7 +392,7 @@ int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode) __errno_r(r) = ENOMEM; return -1; } - __errno_r(r) = ENOENT; + __errno_r(r) = errno; return -1; } @@ -1003,8 +988,14 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds TickType_t ticks_to_wait = portMAX_DELAY; if (timeout) { - uint32_t timeout_ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; - ticks_to_wait = timeout_ms / portTICK_PERIOD_MS; + uint32_t timeout_ms = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000); + /* Round up the number of ticks. + * Not only we need to round up the number of ticks, but we also need to add 1. + * Indeed, `select` function shall wait for AT LEAST timeout, but on FreeRTOS, + * if we specify a timeout of 1 tick to `xSemaphoreTake`, it will take AT MOST + * 1 tick before triggering a timeout. Thus, we need to pass 2 ticks as a timeout + * to `xSemaphoreTake`. */ + ticks_to_wait = ((timeout_ms + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS) + 1; ESP_LOGD(TAG, "timeout is %dms", timeout_ms); } ESP_LOGD(TAG, "waiting without calling socket_select"); @@ -1015,8 +1006,16 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds if (ret >= 0) { ret += set_global_fd_sets(vfs_fds_triple, vfs_count, readfds, writefds, errorfds); } - if (sel_sem.is_sem_local && sel_sem.sem) { - vSemaphoreDelete(sel_sem.sem); + if (sel_sem.sem) { // Cleanup the select semaphore + if (sel_sem.is_sem_local) { + vSemaphoreDelete(sel_sem.sem); + } else if (socket_select) { + SemaphoreHandle_t *s = sel_sem.sem; + /* Select might have been triggered from both lwip and vfs fds at the same time, and + * we have to make sure that the lwip semaphore is cleared when we exit select(). + * It is safe, as the semaphore belongs to the calling thread. */ + xSemaphoreTake(*s, 0); + } sel_sem.sem = NULL; } free(vfs_fds_triple); diff --git a/components/vfs/vfs_cdcacm.c b/components/vfs/vfs_cdcacm.c index cd14d212ddcf..fb590a445df2 100644 --- a/components/vfs/vfs_cdcacm.c +++ b/components/vfs/vfs_cdcacm.c @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -309,17 +301,23 @@ void esp_vfs_dev_cdcacm_set_rx_line_endings(esp_line_endings_t mode) s_rx_mode = mode; } +static const esp_vfs_t vfs = { + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &cdcacm_write, + .open = &cdcacm_open, + .fstat = &cdcacm_fstat, + .close = &cdcacm_close, + .read = &cdcacm_read, + .fcntl = &cdcacm_fcntl, + .fsync = &cdcacm_fsync +}; + +const esp_vfs_t *esp_vfs_cdcacm_get_vfs(void) +{ + return &vfs; +} + esp_err_t esp_vfs_dev_cdcacm_register(void) { - const esp_vfs_t vfs = { - .flags = ESP_VFS_FLAG_DEFAULT, - .write = &cdcacm_write, - .open = &cdcacm_open, - .fstat = &cdcacm_fstat, - .close = &cdcacm_close, - .read = &cdcacm_read, - .fcntl = &cdcacm_fcntl, - .fsync = &cdcacm_fsync - }; return esp_vfs_register("/dev/cdcacm", &vfs, NULL); } diff --git a/components/vfs/vfs_console.c b/components/vfs/vfs_console.c new file mode 100644 index 000000000000..be10600b879a --- /dev/null +++ b/components/vfs/vfs_console.c @@ -0,0 +1,218 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_vfs_console.h" +#include "esp_rom_sys.h" +#include "esp_vfs_cdcacm.h" +#include "esp_vfs_private.h" +#include "esp_vfs_usb_serial_jtag.h" +#include "esp_vfs_dev.h" +#include "esp_private/usb_console.h" +#include "sdkconfig.h" + +#define STRINGIFY(s) STRINGIFY2(s) +#define STRINGIFY2(s) #s + +/** + * This file is to concentrate all the vfs(UART, USB_SERIAL_JTAG, CDCACM) console into one single file. + * Get the vfs information from their component (i.e. vfs_uart.c) through `esp_vfs_usb_xxx_get_console()`, + * which can help us to output some string to two different ports(i.e both through uart and usb_serial_jtag). + * Usually, we set a port as primary and another as secondary. For primary, it is used for all the features supported by each vfs implementation, + * while the secondary is only used for output. + */ + +typedef struct { + int fd_primary; + int fd_secondary; +} vfs_console_context_t; + +#if CONFIG_VFS_SUPPORT_IO +// Primary register part. +#ifdef CONFIG_ESP_CONSOLE_UART +const static char *primary_path = "/dev/uart"; +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +const static char *primary_path = "/dev/usbserjtag"; +#elif CONFIG_ESP_CONSOLE_USB_CDC +const static char *primary_path = "/dev/cdcacm"; +#endif + +// Secondary register part. +#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG +const static char *secondary_path = "/dev/secondary"; +static int secondary_vfs_index; +#endif // Secondary part + +static int primary_vfs_index; + +static vfs_console_context_t vfs_console= {0}; + +int console_open(const char * path, int flags, int mode) +{ +// Primary port open +#if CONFIG_ESP_CONSOLE_UART + vfs_console.fd_primary = get_vfs_for_path(primary_path)->vfs.open("/"STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM), flags, mode); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + vfs_console.fd_primary = esp_vfs_usb_serial_jtag_get_vfs()->open("/", flags, mode); +#elif CONFIG_ESP_CONSOLE_USB_CDC + vfs_console.fd_primary = esp_vfs_cdcacm_get_vfs()->open("/", flags, mode); +#endif + +// Secondary port open +#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + vfs_console.fd_secondary = get_vfs_for_path(secondary_path)->vfs.open("/", flags, mode); +#endif + return 0; +} + +ssize_t console_write(int fd, const void *data, size_t size) +{ + // All function calls are to primary, except from write and close, which will be forwarded to both primary and secondary. + get_vfs_for_index(primary_vfs_index)->vfs.write(vfs_console.fd_primary, data, size); +#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + get_vfs_for_index(secondary_vfs_index)->vfs.write(vfs_console.fd_secondary, data, size); +#endif + return size; +} + +int console_fstat(int fd, struct stat * st) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.fstat(fd, st); +} + +int console_close(int fd) +{ + // All function calls are to primary, except from write and close, which will be forwarded to both primary and secondary. + get_vfs_for_index(primary_vfs_index)->vfs.close(vfs_console.fd_primary); +#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + get_vfs_for_index(secondary_vfs_index)->vfs.close(vfs_console.fd_secondary); +#endif + return 0; +} + +ssize_t console_read(int fd, void * dst, size_t size) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.read(vfs_console.fd_primary, dst, size); +} + +int console_fcntl(int fd, int cmd, int arg) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.fcntl(vfs_console.fd_primary, cmd, arg); +} + +int console_fsync(int fd) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.fsync(vfs_console.fd_primary); +} + +#ifdef CONFIG_VFS_SUPPORT_DIR +int console_access(const char *path, int amode) +{ + // currently only UART support DIR. + return get_vfs_for_index(primary_vfs_index)->vfs.access("/"STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM), amode); +} +#endif // CONFIG_VFS_SUPPORT_DIR + +#ifdef CONFIG_VFS_SUPPORT_SELECT +static esp_err_t console_start_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + esp_vfs_select_sem_t select_sem, void **end_select_args) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.start_select(nfds, readfds, writefds, exceptfds, select_sem, end_select_args); +} + +esp_err_t console_end_select(void *end_select_args) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.end_select(end_select_args); +} + +#endif // CONFIG_VFS_SUPPORT_SELECT + +#ifdef CONFIG_VFS_SUPPORT_TERMIOS + +int console_tcsetattr(int fd, int optional_actions, const struct termios *p) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.tcsetattr(vfs_console.fd_primary, optional_actions, p); +} + +int console_tcgetattr(int fd, struct termios *p) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.tcgetattr(vfs_console.fd_primary, p); +} + +int console_tcdrain(int fd) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.tcdrain(vfs_console.fd_primary); +} + +int console_tcflush(int fd, int select) +{ + return get_vfs_for_index(primary_vfs_index)->vfs.tcflush(vfs_console.fd_primary, select); +} +#endif // CONFIG_VFS_SUPPORT_TERMIOS + +static const esp_vfs_t vfs = { + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &console_write, + .open = &console_open, + .fstat = &console_fstat, + .close = &console_close, + .read = &console_read, + .fcntl = &console_fcntl, + .fsync = &console_fsync, +#ifdef CONFIG_VFS_SUPPORT_DIR + .access = &console_access, +#endif // CONFIG_VFS_SUPPORT_DIR +#ifdef CONFIG_VFS_SUPPORT_SELECT + .start_select = &console_start_select, + .end_select = &console_end_select, +#endif // CONFIG_VFS_SUPPORT_SELECT +#ifdef CONFIG_VFS_SUPPORT_TERMIOS + .tcsetattr = &console_tcsetattr, + .tcgetattr = &console_tcgetattr, + .tcdrain = &console_tcdrain, + .tcflush = &console_tcflush, +#endif // CONFIG_VFS_SUPPORT_TERMIOS +}; + +esp_err_t esp_vfs_dev_console_register(void) +{ + return esp_vfs_register("/dev/console", &vfs, NULL); +} + +esp_err_t esp_vfs_console_register(void) +{ + esp_err_t err = ESP_OK; +// Primary register part. +#ifdef CONFIG_ESP_CONSOLE_UART + const esp_vfs_t *uart_vfs = esp_vfs_uart_get_vfs(); + err = esp_vfs_register_common(primary_path, strlen(primary_path), uart_vfs, NULL, &primary_vfs_index); +#elif CONFIG_ESP_CONSOLE_USB_CDC + const esp_vfs_t *cdcacm_vfs = esp_vfs_cdcacm_get_vfs(); + err = esp_usb_console_init(); + if (err != ESP_OK) { + return err; + } + err = esp_vfs_register_common(primary_path, strlen(primary_path), cdcacm_vfs, NULL, &primary_vfs_index); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + const esp_vfs_t *usb_serial_jtag_vfs = esp_vfs_usb_serial_jtag_get_vfs(); + err = esp_vfs_register_common(primary_path, strlen(primary_path), usb_serial_jtag_vfs, NULL, &primary_vfs_index); +#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + if (err != ESP_OK) { + return err; + } + +// Secondary register part. +#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + const esp_vfs_t *usb_serial_jtag_vfs = esp_vfs_usb_serial_jtag_get_vfs(); + err = esp_vfs_register_common(secondary_path, strlen(secondary_path), usb_serial_jtag_vfs, NULL, &secondary_vfs_index); + if(err != ESP_OK) { + return err; + } +#endif + err = esp_vfs_dev_console_register(); + return err; +} + +#endif // CONFIG_VFS_SUPPORT_IO diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c index ffd864506e08..90786f15648a 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -1,16 +1,8 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -969,31 +961,37 @@ static int uart_tcflush(int fd, int select) } #endif // CONFIG_VFS_SUPPORT_TERMIOS -void esp_vfs_dev_uart_register(void) -{ - esp_vfs_t vfs = { - .flags = ESP_VFS_FLAG_DEFAULT, - .write = &uart_write, - .open = &uart_open, - .fstat = &uart_fstat, - .close = &uart_close, - .read = &uart_read, - .fcntl = &uart_fcntl, - .fsync = &uart_fsync, +static const esp_vfs_t vfs = { + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &uart_write, + .open = &uart_open, + .fstat = &uart_fstat, + .close = &uart_close, + .read = &uart_read, + .fcntl = &uart_fcntl, + .fsync = &uart_fsync, #ifdef CONFIG_VFS_SUPPORT_DIR - .access = &uart_access, + .access = &uart_access, #endif // CONFIG_VFS_SUPPORT_DIR #ifdef CONFIG_VFS_SUPPORT_SELECT - .start_select = &uart_start_select, - .end_select = &uart_end_select, + .start_select = &uart_start_select, + .end_select = &uart_end_select, #endif // CONFIG_VFS_SUPPORT_SELECT #ifdef CONFIG_VFS_SUPPORT_TERMIOS - .tcsetattr = &uart_tcsetattr, - .tcgetattr = &uart_tcgetattr, - .tcdrain = &uart_tcdrain, - .tcflush = &uart_tcflush, + .tcsetattr = &uart_tcsetattr, + .tcgetattr = &uart_tcgetattr, + .tcdrain = &uart_tcdrain, + .tcflush = &uart_tcflush, #endif // CONFIG_VFS_SUPPORT_TERMIOS - }; +}; + +const esp_vfs_t* esp_vfs_uart_get_vfs(void) +{ + return &vfs; +} + +void esp_vfs_dev_uart_register(void) +{ ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &vfs, NULL)); } diff --git a/components/vfs/vfs_usb_serial_jtag.c b/components/vfs/vfs_usb_serial_jtag.c index e6083c925a82..20bb4dd4db79 100644 --- a/components/vfs/vfs_usb_serial_jtag.c +++ b/components/vfs/vfs_usb_serial_jtag.c @@ -1,16 +1,8 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ //This is a simple non-blocking (well, tx may spin for a bit if the buffer //is full) USB-serial-jtag driver. Select etc is not supported yet. @@ -26,9 +18,12 @@ #include "esp_vfs.h" #include "esp_vfs_dev.h" #include "esp_attr.h" +#include "esp_log.h" #include "sdkconfig.h" #include "soc/soc_caps.h" #include "hal/usb_serial_jtag_ll.h" +#include "esp_vfs_usb_serial_jtag.h" +#include "driver/usb_serial_jtag.h" // Token signifying that no character is available #define NONE -1 @@ -110,23 +105,21 @@ static int usb_serial_jtag_open(const char * path, int flags, int mode) static void usb_serial_jtag_tx_char(int fd, int c) { uint8_t cc=(uint8_t)c; - if (usb_serial_jtag_ll_txfifo_writable()) { - //We can write to the buffer. Immediately do so. - usb_serial_jtag_ll_write_txfifo(&cc, 1); - s_ctx.last_tx_ts = esp_timer_get_time(); - } else { - //Try to write to the buffer as long as we still expect the buffer to have - //a chance of being emptied by an active host. Just drop the data if there's - //no chance anymore. - while ((esp_timer_get_time() - s_ctx.last_tx_ts) < TX_FLUSH_TIMEOUT_US) { - if (usb_serial_jtag_ll_txfifo_writable()) { - //Woohoo, we can write again. Do so and exit the while loop. - usb_serial_jtag_ll_write_txfifo(&cc, 1); - s_ctx.last_tx_ts = esp_timer_get_time(); - break; - } + // Try to write to the buffer as long as we still expect the buffer to have + // a chance of being emptied by an active host. Just drop the data if there's + // no chance anymore. + // When we first try to send a character and the buffer is not accessible yet, + // we wait until the time has been more than TX_FLUSH_TIMEOUT_US since we successfully + // sent the last byte. If it takes longer than TX_FLUSH_TIMEOUT_US, we drop every + // byte until the buffer can be accessible again. + do { + if (usb_serial_jtag_ll_txfifo_writable()) { + usb_serial_jtag_ll_write_txfifo(&cc, 1); + s_ctx.last_tx_ts = esp_timer_get_time(); + break; } - } + } while ((esp_timer_get_time() - s_ctx.last_tx_ts) < TX_FLUSH_TIMEOUT_US); + } static int usb_serial_jtag_rx_char(int fd) @@ -361,25 +354,70 @@ void esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(esp_line_endings_t mode) s_ctx.rx_mode = mode; } +static const esp_vfs_t vfs = { + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &usb_serial_jtag_write, + .open = &usb_serial_jtag_open, + .fstat = &usb_serial_jtag_fstat, + .close = &usb_serial_jtag_close, + .read = &usb_serial_jtag_read, + .fcntl = &usb_serial_jtag_fcntl, + .fsync = &usb_serial_jtag_fsync, +#ifdef CONFIG_VFS_SUPPORT_TERMIOS + .tcsetattr = &usb_serial_jtag_tcsetattr, + .tcgetattr = &usb_serial_jtag_tcgetattr, + .tcdrain = &usb_serial_jtag_tcdrain, + .tcflush = &usb_serial_jtag_tcflush, +#endif // CONFIG_VFS_SUPPORT_TERMIOS +}; + +const esp_vfs_t* esp_vfs_usb_serial_jtag_get_vfs(void) +{ + return &vfs; +} esp_err_t esp_vfs_dev_usb_serial_jtag_register(void) { - esp_vfs_t vfs = { - .flags = ESP_VFS_FLAG_DEFAULT, - .write = &usb_serial_jtag_write, - .open = &usb_serial_jtag_open, - .fstat = &usb_serial_jtag_fstat, - .close = &usb_serial_jtag_close, - .read = &usb_serial_jtag_read, - .fcntl = &usb_serial_jtag_fcntl, - .fsync = &usb_serial_jtag_fsync, -#ifdef CONFIG_VFS_SUPPORT_TERMIOS - .tcsetattr = &usb_serial_jtag_tcsetattr, - .tcgetattr = &usb_serial_jtag_tcgetattr, - .tcdrain = &usb_serial_jtag_tcdrain, - .tcflush = &usb_serial_jtag_tcflush, -#endif // CONFIG_VFS_SUPPORT_TERMIOS - }; // "/dev/usb_serial_jtag" unfortunately is too long for vfs return esp_vfs_register("/dev/usbserjtag", &vfs, NULL); } + +/*********************************************************** + * VFS uses USB-SERIAL-JTAG driver part. + **********************************************************/ + +static int usbjtag_rx_char_via_driver(int fd) +{ + uint8_t c; + int n = usb_serial_jtag_read_bytes(&c, 1, portMAX_DELAY); + if (n <= 0) { + return NONE; + } + return c; +} + +static void usbjtag_tx_char_via_driver(int fd, int c) +{ + char ch = (char) c; + usb_serial_jtag_write_bytes(&ch, 1, portMAX_DELAY); +} + +void esp_vfs_usb_serial_jtag_use_nonblocking(void) +{ + _lock_acquire_recursive(&s_ctx.read_lock); + _lock_acquire_recursive(&s_ctx.write_lock); + s_ctx.tx_func = usb_serial_jtag_tx_char; + s_ctx.rx_func = usb_serial_jtag_rx_char; + _lock_release_recursive(&s_ctx.write_lock); + _lock_release_recursive(&s_ctx.read_lock); +} + +void esp_vfs_usb_serial_jtag_use_driver(void) +{ + _lock_acquire_recursive(&s_ctx.read_lock); + _lock_acquire_recursive(&s_ctx.write_lock); + s_ctx.tx_func = usbjtag_tx_char_via_driver; + s_ctx.rx_func = usbjtag_rx_char_via_driver; + _lock_release_recursive(&s_ctx.write_lock); + _lock_release_recursive(&s_ctx.read_lock); +} diff --git a/components/wear_levelling/README.rst b/components/wear_levelling/README.rst index c05a2f266740..e06711fb128c 100644 --- a/components/wear_levelling/README.rst +++ b/components/wear_levelling/README.rst @@ -5,6 +5,7 @@ Wear Levelling API Overview -------- + Most of flash memory and especially SPI flash that is used in {IDF_TARGET_NAME} has a sector-based organization and also has a limited number of erase/modification cycles per memory sector. The wear levelling component helps to distribute wear and tear among sectors more evenly without requiring any attention from the user. The wear levelling component provides API functions related to reading, writing, erasing, and memory mapping of data in external SPI flash through the partition component. The component also has higher-level API functions which work with the FAT filesystem defined in :doc:`FAT filesystem `. @@ -46,4 +47,3 @@ Memory Size ----------- The memory size is calculated in the wear levelling module based on partition parameters. The module uses some sectors of flash for internal data. - diff --git a/components/wear_levelling/README_CN.rst b/components/wear_levelling/README_CN.rst index 13d5abdd0c1e..65830266fec7 100644 --- a/components/wear_levelling/README_CN.rst +++ b/components/wear_levelling/README_CN.rst @@ -6,7 +6,7 @@ 概述 -------- -ESP32 所使用的 flash,特别是 SPI flash 多数具备扇区结构,且每个扇区仅允许有限次数的擦除/修改操作。为了避免过度使用某一扇区,乐鑫提供了磨损均衡组件,无需用户介入即可帮助用户均衡各个扇区之间的磨损。 +{IDF_TARGET_NAME} 所使用的 flash,特别是 SPI flash 多数具备扇区结构,且每个扇区仅允许有限次数的擦除/修改操作。为了避免过度使用某一扇区,乐鑫提供了磨损均衡组件,无需用户介入即可帮助用户均衡各个扇区之间的磨损。 磨损均衡组件包含了通过分区组件对外部 SPI flash 进行数据读取、写入、擦除和存储器映射相关的 API 函数。磨损均衡组件还具有软件上更高级别的 API 函数,与 :doc:`FAT 文件系统 ` 协同工作。 diff --git a/components/wifi_provisioning/Kconfig b/components/wifi_provisioning/Kconfig index 0d37a9b820e8..bdc9e39c28aa 100644 --- a/components/wifi_provisioning/Kconfig +++ b/components/wifi_provisioning/Kconfig @@ -17,9 +17,26 @@ menu "Wi-Fi Provisioning Manager" config WIFI_PROV_BLE_BONDING bool - default n prompt "Enable BLE bonding" depends on BT_ENABLED + default y help This option is applicable only when provisioning transport is BLE. + + config WIFI_PROV_BLE_SEC_CONN + bool + prompt "Enable BLE Secure connection flag" + depends on BT_NIMBLE_ENABLED + default y + help + Used to enable Secure connection support when provisioning transport is BLE. + + config WIFI_PROV_BLE_FORCE_ENCRYPTION + bool + prompt "Force Link Encryption during characteristic Read / Write" + depends on BT_NIMBLE_ENABLED + default y + help + Used to enforce link encryption when attempting to read / write characteristic + endmenu diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index b745d94be24a..ed8acab5246d 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -1,16 +1,8 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -621,8 +613,10 @@ static bool wifi_prov_mgr_stop_service(bool blocking) * released - some duration after - returning from a call to * wifi_prov_mgr_stop_provisioning(), like when it is called * inside a protocomm handler */ - assert(xTaskCreate(prov_stop_task, "prov_stop_task", 4096, (void *)1, - tskIDLE_PRIORITY, NULL) == pdPASS); + if (xTaskCreate(prov_stop_task, "prov_stop_task", 4096, (void *)1, tskIDLE_PRIORITY, NULL) != pdPASS) { + ESP_LOGE(TAG, "Failed to create prov_stop_task!"); + abort(); + } ESP_LOGD(TAG, "Provisioning scheduled for stopping"); } return true; @@ -706,16 +700,17 @@ static esp_err_t update_wifi_scan_results(void) goto exit; } - prov_ctx->ap_list[curr_channel] = (wifi_ap_record_t *) calloc(count, sizeof(wifi_ap_record_t)); + uint16_t get_count = MIN(count, MAX_SCAN_RESULTS); + prov_ctx->ap_list[curr_channel] = (wifi_ap_record_t *) calloc(get_count, sizeof(wifi_ap_record_t)); if (!prov_ctx->ap_list[curr_channel]) { ESP_LOGE(TAG, "Failed to allocate memory for AP list"); goto exit; } - if (esp_wifi_scan_get_ap_records(&count, prov_ctx->ap_list[curr_channel]) != ESP_OK) { + if (esp_wifi_scan_get_ap_records(&get_count, prov_ctx->ap_list[curr_channel]) != ESP_OK) { ESP_LOGE(TAG, "Failed to get scanned AP records"); goto exit; } - prov_ctx->ap_list_len[curr_channel] = count; + prov_ctx->ap_list_len[curr_channel] = get_count; if (prov_ctx->channels_per_group) { ESP_LOGD(TAG, "Scan results for channel %d :", curr_channel); @@ -738,7 +733,7 @@ static esp_err_t update_wifi_scan_results(void) /* Store results in sorted list */ { - int rc = MIN(count, MAX_SCAN_RESULTS); + int rc = get_count; int is = MAX_SCAN_RESULTS - rc - 1; while (rc > 0 && is >= 0) { if (prov_ctx->ap_list_sorted[is]) { diff --git a/components/wifi_provisioning/src/scheme_ble.c b/components/wifi_provisioning/src/scheme_ble.c index 3106dc47e7a4..a133592f92e2 100644 --- a/components/wifi_provisioning/src/scheme_ble.c +++ b/components/wifi_provisioning/src/scheme_ble.c @@ -38,8 +38,12 @@ static esp_err_t prov_start(protocomm_t *pc, void *config) protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config; - #ifdef CONFIG_WIFI_PROV_BLE_BONDING - ble_config->ble_bonding = 1; + #if defined(CONFIG_WIFI_PROV_BLE_BONDING) + ble_config->ble_bonding = 1; + #endif + + #if defined(CONFIG_WIFI_PROV_BLE_SEC_CONN) || defined(CONFIG_BT_BLUEDROID_ENABLED) + ble_config->ble_sm_sc = 1; #endif /* Start protocomm as BLE service */ diff --git a/components/wifi_provisioning/src/scheme_softap.c b/components/wifi_provisioning/src/scheme_softap.c index 289b1a4c6291..626cec81ba6f 100644 --- a/components/wifi_provisioning/src/scheme_softap.c +++ b/components/wifi_provisioning/src/scheme_softap.c @@ -182,10 +182,15 @@ static esp_err_t set_config_service(void *config, const char *service_name, cons } wifi_prov_softap_config_t *softap_config = (wifi_prov_softap_config_t *) config; - strlcpy(softap_config->ssid, service_name, sizeof(softap_config->ssid)); if (service_key) { + const int service_key_len = strlen(service_key); + if (service_key_len < 8 || service_key_len >= sizeof(softap_config->password)) { + ESP_LOGE(TAG, "Incorrect passphrase length for softAP: %d (Expected: Min - 8, Max - 64)", service_key_len); + return ESP_ERR_INVALID_ARG; + } strlcpy(softap_config->password, service_key, sizeof(softap_config->password)); } + strlcpy(softap_config->ssid, service_name, sizeof(softap_config->ssid)); return ESP_OK; } diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index 6b595dfb0208..02b2e6f3cff9 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -5,7 +5,6 @@ set(srcs "port/os_xtensa.c" "src/ap/wpa_auth_ie.c" "src/common/sae.c" "src/common/wpa_common.c" - "src/common/dpp.c" "src/utils/bitfield.c" "src/crypto/aes-siv.c" "src/crypto/sha256-kdf.c" @@ -37,6 +36,9 @@ set(srcs "port/os_xtensa.c" "src/esp_supplicant/esp_wps.c" "src/esp_supplicant/esp_wpa3.c" "src/esp_supplicant/esp_dpp.c" + "src/eap_peer/eap_fast.c" + "src/eap_peer/eap_fast_common.c" + "src/eap_peer/eap_fast_pac.c" "src/rsn_supp/pmksa_cache.c" "src/rsn_supp/wpa.c" "src/rsn_supp/wpa_ie.c" @@ -134,6 +136,7 @@ else() "src/crypto/sha1-internal.c" "src/crypto/sha1-pbkdf2.c" "src/crypto/sha1.c" + "src/crypto/sha1-tprf.c" "src/crypto/sha256-internal.c" "src/crypto/sha384-internal.c" "src/crypto/sha512-internal.c" @@ -154,7 +157,14 @@ else() set(roaming_src "") endif() -idf_component_register(SRCS "${srcs}" "${tls_src}" "${roaming_src}" "${crypto_src}" +if(CONFIG_WPA_DPP_SUPPORT) + set(dpp_src "src/common/dpp.c" + "src/esp_supplicant/esp_dpp.c") +else() + set(dpp_src "") +endif() + +idf_component_register(SRCS "${srcs}" "${tls_src}" "${roaming_src}" "${crypto_src}" "${dpp_src}" INCLUDE_DIRS include port/include include/esp_supplicant PRIV_INCLUDE_DIRS src src/utils PRIV_REQUIRES mbedtls esp_timer) @@ -169,6 +179,7 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE EAP_TTLS EAP_TLS EAP_PEAP + EAP_FAST USE_WPA2_TASK CONFIG_WPS2 CONFIG_WPS_PIN @@ -178,7 +189,6 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_ECC CONFIG_IEEE80211W CONFIG_SHA256 - CONFIG_DPP CONFIG_WNM ) @@ -188,5 +198,7 @@ endif() if(CONFIG_WPA_WPS_STRICT) target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPS_STRICT) endif() - +if(CONFIG_WPA_DPP_SUPPORT) + target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_DPP) +endif() set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3) diff --git a/components/wpa_supplicant/Kconfig b/components/wpa_supplicant/Kconfig index c98b38bcaa74..d612997308e8 100644 --- a/components/wpa_supplicant/Kconfig +++ b/components/wpa_supplicant/Kconfig @@ -38,8 +38,8 @@ menu "Supplicant" rigorously. Disabling this add the workaorunds with various APs. Enabling this may cause inter operability issues with some APs. - menuconfig WPA_11KV_SUPPORT - bool "Enable 802.11k, 802.11v APIs handling in supplicant" + config WPA_11KV_SUPPORT + bool "Enable 802.11k, 802.11v APIs handling" default n help Select this option to enable 802.11k 802.11v APIs(RRM and BTM support). @@ -54,12 +54,19 @@ menu "Supplicant" and on the radio environment. Current implementation adds beacon report, link measurement, neighbor report. - if WPA_11KV_SUPPORT - config WPA_SCAN_CACHE - bool "Keep scan results in cache" - default n - help - Keep scan results in cache, if not enabled, those - will be flushed immediately. - endif + config WPA_SCAN_CACHE + bool "Keep scan results in cache" + depends on WPA_11KV_SUPPORT + default n + help + Keep scan results in cache, if not enabled, those + will be flushed immediately. + + config WPA_DPP_SUPPORT + bool "Enable DPP support" + default n + select WPA_MBEDTLS_CRYPTO + help + Select this option to enable WiFi Easy Connect Support. + endmenu diff --git a/components/wpa_supplicant/include/esp_supplicant/esp_dpp.h b/components/wpa_supplicant/include/esp_supplicant/esp_dpp.h index c6c86bc536f0..d1bb43a0ada7 100644 --- a/components/wpa_supplicant/include/esp_supplicant/esp_dpp.h +++ b/components/wpa_supplicant/include/esp_supplicant/esp_dpp.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef ESP_DPP_H #define ESP_DPP_H diff --git a/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h b/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h index c6c2930a0fee..da19406320c6 100644 --- a/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h +++ b/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h @@ -27,6 +27,12 @@ typedef enum { ESP_EAP_TTLS_PHASE2_CHAP } esp_eap_ttls_phase2_types ; +typedef struct { + int fast_provisioning; + int fast_max_pac_list_len; + bool fast_pac_format_binary; +} esp_eap_fast_config; + #ifdef __cplusplus extern "C" { #endif @@ -209,6 +215,35 @@ esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable); */ esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type); +/** + * @brief Set client pac file + * + * @attention 1. For files read from the file system, length has to be decremented by 1 byte. + * @attention 2. Disabling the WPA_MBEDTLS_CRYPTO config is required to use EAP-FAST. + * + * @param pac_file: pointer to the pac file + * pac_file_len: length of the pac file + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int pac_file_len); + +/** + * @brief Set Phase 1 parameters for EAP-FAST + * + * @attention 1. Disabling the WPA_MBEDTLS_CRYPTO config is required to use EAP-FAST. + * + * @param config: eap fast phase 1 configuration + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(out of bound arguments) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config); + #ifdef __cplusplus } #endif diff --git a/components/wpa_supplicant/include/utils/wpa_debug.h b/components/wpa_supplicant/include/utils/wpa_debug.h index 9714617a6015..c6ac189c2283 100644 --- a/components/wpa_supplicant/include/utils/wpa_debug.h +++ b/components/wpa_supplicant/include/utils/wpa_debug.h @@ -176,7 +176,7 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, * * Note: New line '\n' is added to the end of the text when printing to stdout. */ -void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); +#define wpa_msg(...) do {} while(0) /** * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors diff --git a/components/wpa_supplicant/include/utils/wpabuf.h b/components/wpa_supplicant/include/utils/wpabuf.h index e9f4ce7b34e7..092b31e08ba4 100644 --- a/components/wpa_supplicant/include/utils/wpabuf.h +++ b/components/wpa_supplicant/include/utils/wpabuf.h @@ -1,6 +1,6 @@ /* * Dynamic data buffer - * Copyright (c) 2007-2009, Jouni Malinen + * Copyright (c) 2007-2012, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,6 +15,9 @@ #ifndef WPABUF_H #define WPABUF_H +/* wpabuf::buf is a pointer to external data */ +#define WPABUF_FLAG_EXT_DATA BIT(0) + /* * Internal data structure for wpabuf. Please do not touch this directly from * elsewhere. This is only defined in header file to allow inline functions @@ -23,8 +26,8 @@ struct wpabuf { size_t size; /* total size of the allocated buffer */ size_t used; /* length of data in the buffer */ - u8 *ext_data; /* pointer to external data; NULL if data follows - * struct wpabuf */ + u8 *buf; /* pointer to the head of the buffer */ + unsigned int flags; /* optionally followed by the allocated buffer */ }; @@ -35,6 +38,7 @@ struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len); struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len); struct wpabuf * wpabuf_dup(const struct wpabuf *src); void wpabuf_free(struct wpabuf *buf); +void wpabuf_clear_free(struct wpabuf *buf); void * wpabuf_put(struct wpabuf *buf, size_t len); struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b); struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len); @@ -78,9 +82,7 @@ static inline size_t wpabuf_tailroom(const struct wpabuf *buf) */ static inline const void * wpabuf_head(const struct wpabuf *buf) { - if (buf->ext_data) - return buf->ext_data; - return buf + 1; + return buf->buf; } static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf) @@ -95,9 +97,7 @@ static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf) */ static inline void * wpabuf_mhead(struct wpabuf *buf) { - if (buf->ext_data) - return buf->ext_data; - return buf + 1; + return buf->buf; } static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf) @@ -156,7 +156,8 @@ static inline void wpabuf_put_buf(struct wpabuf *dst, static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len) { - buf->ext_data = (u8 *) data; + buf->buf = (u8 *) data; + buf->flags = WPABUF_FLAG_EXT_DATA; buf->size = buf->used = len; } diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h index 74e1e349e91b..ce9aa559a440 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -289,6 +289,9 @@ char * ets_strdup(const char *s); #ifndef os_strlcpy #define os_strlcpy(d, s, n) strlcpy((d), (s), (n)) #endif +#ifndef os_strcat +#define os_strcat(d, s) strcat((d), (s)) +#endif #ifndef os_snprintf #ifdef _MSC_VER @@ -297,6 +300,9 @@ char * ets_strdup(const char *s); #define os_snprintf snprintf #endif #endif +#ifndef os_sprintf +#define os_sprintf sprintf +#endif static inline int os_snprintf_error(size_t size, int res) { diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index a76a7e8dce85..c96f0e4b96eb 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -1590,7 +1590,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) sm->pending_1_of_4_timeout = 0; eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); - if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { + if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) && sm->PMK != pmk) { /* PSK may have changed from the previous choice, so update * state machine data based on whatever PSK was selected here. */ diff --git a/components/wpa_supplicant/src/ap/wpa_auth_ie.c b/components/wpa_supplicant/src/ap/wpa_auth_ie.c index 368285403d32..532127c8e546 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_ie.c +++ b/components/wpa_supplicant/src/ap/wpa_auth_ie.c @@ -362,7 +362,7 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, const u8 *wpa_ie, size_t wpa_ie_len/*, const u8 *mdie, size_t mdie_len*/) { - struct wpa_ie_data data; + struct wpa_ie_data data = {0}; int ciphers, key_mgmt, res, version; u32 selector; diff --git a/components/wpa_supplicant/src/common/dpp.c b/components/wpa_supplicant/src/common/dpp.c index c96869b3182a..459e2b73e9d3 100644 --- a/components/wpa_supplicant/src/common/dpp.c +++ b/components/wpa_supplicant/src/common/dpp.c @@ -52,10 +52,6 @@ static const struct dpp_curve_params dpp_curves[] = { { NULL, 0, 0, 0, 0, NULL, 0, NULL } }; -void wpa_msg(void *ctx, int level, const char *fmt, ...) -{ -} - static struct wpabuf * gas_build_req(u8 action, u8 dialog_token, size_t size) { @@ -851,7 +847,7 @@ static int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, /* HKDF-Expand(PRK, info, L) */ res = dpp_hkdf_expand(hash_len, prk, hash_len, info, k1, hash_len); - os_memset(prk, 0, hash_len); + forced_memzero(prk, hash_len); if (res < 0) return -1; @@ -880,7 +876,7 @@ static int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, /* HKDF-Expand(PRK, info, L) */ res = dpp_hkdf_expand(hash_len, prk, hash_len, info, k2, hash_len); - os_memset(prk, 0, hash_len); + forced_memzero(prk, hash_len); if (res < 0) return -1; @@ -939,7 +935,7 @@ static int dpp_derive_ke(struct dpp_authentication *auth, u8 *ke, /* HKDF-Expand(PRK, info, L) */ res = dpp_hkdf_expand(hash_len, prk, hash_len, info_ke, ke, hash_len); - os_memset(prk, 0, hash_len); + forced_memzero(prk, hash_len); if (res < 0) return -1; @@ -3942,7 +3938,7 @@ static void dpp_build_legacy_cred_params(struct wpabuf *buf, wpa_snprintf_hex(psk, sizeof(psk), conf->psk, sizeof(conf->psk)); json_add_string(buf, "psk_hex", psk); - os_memset(psk, 0, sizeof(psk)); + forced_memzero(psk, sizeof(psk)); } } @@ -4114,6 +4110,8 @@ dpp_build_conf_obj_dpp(struct dpp_authentication *auth, goto fail; signature = os_malloc(2 * curve->prime_len); + if (!signature) + goto fail; if (dpp_bn2bin_pad(r, signature, curve->prime_len) < 0 || dpp_bn2bin_pad(s, signature + curve->prime_len, curve->prime_len) < 0) @@ -4674,6 +4672,7 @@ static struct crypto_key * dpp_parse_jwk(struct json_token *jwk, struct wpabuf *x = NULL, *y = NULL, *a = NULL; struct crypto_ec_group *group; struct crypto_key *pkey = NULL; + size_t len; token = json_get_member(jwk, "kty"); if (!token || token->type != JSON_STRING) { @@ -4732,9 +4731,10 @@ static struct crypto_key * dpp_parse_jwk(struct json_token *jwk, goto fail; } + len = wpabuf_len(x); a = wpabuf_concat(x, y); pkey = crypto_ec_set_pubkey_point(group, wpabuf_head(a), - wpabuf_len(x)); + len); crypto_ec_deinit((struct crypto_ec *)group); *key_curve = curve; @@ -4973,8 +4973,7 @@ static void dpp_copy_netaccesskey(struct dpp_authentication *auth, unsigned char *der = NULL; int der_len; - crypto_ec_get_priv_key_der(auth->own_protocol_key, &der, &der_len); - if (der_len <= 0) { + if (crypto_ec_get_priv_key_der(auth->own_protocol_key, &der, &der_len) < 0) { return; } wpabuf_free(auth->net_access_key); @@ -5732,7 +5731,7 @@ static int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, /* HKDF-Expand(PRK, info, L) */ res = dpp_hkdf_expand(hash_len, prk, hash_len, info, pmk, hash_len); - os_memset(prk, 0, hash_len); + forced_memzero(prk, hash_len); if (res < 0) return -1; @@ -5937,7 +5936,7 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, fail: if (ret != DPP_STATUS_OK) os_memset(intro, 0, sizeof(*intro)); - os_memset(Nx, 0, sizeof(Nx)); + forced_memzero(Nx, sizeof(Nx)); os_free(own_conn); os_free(signed_connector); os_free(info.payload); @@ -6115,7 +6114,7 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd) hexstr2bin(key, privkey, privkey_len) < 0) goto fail; } - wpa_hexdump(MSG_ERROR, "private key", privkey, privkey_len); + wpa_hexdump(MSG_DEBUG, "private key", privkey, privkey_len); pk = dpp_keygen(bi, curve, privkey, privkey_len); if (!pk) diff --git a/components/wpa_supplicant/src/common/sae.c b/components/wpa_supplicant/src/common/sae.c index 30c48aa722a7..469303cb286e 100644 --- a/components/wpa_supplicant/src/common/sae.c +++ b/components/wpa_supplicant/src/common/sae.c @@ -18,15 +18,6 @@ #include "sae.h" #include "esp_wifi_crypto_types.h" -/*TBD Move the this api to proper files once they are taken out of lib*/ -void wpabuf_clear_free(struct wpabuf *buf) -{ - if (buf) { - os_memset(wpabuf_mhead(buf), 0, wpabuf_len(buf)); - wpabuf_free(buf); - } -} - int sae_set_group(struct sae_data *sae, int group) { struct sae_temporary_data *tmp; @@ -57,6 +48,7 @@ int sae_set_group(struct sae_data *sae, int group) tmp->prime_len = tmp->dh->prime_len; if (tmp->prime_len > SAE_MAX_PRIME_LEN) { sae_clear_data(sae); + os_free(tmp); return ESP_FAIL; } @@ -64,6 +56,7 @@ int sae_set_group(struct sae_data *sae, int group) tmp->prime_len); if (tmp->prime_buf == NULL) { sae_clear_data(sae); + os_free(tmp); return ESP_FAIL; } tmp->prime = tmp->prime_buf; @@ -72,6 +65,7 @@ int sae_set_group(struct sae_data *sae, int group) tmp->dh->order_len); if (tmp->order_buf == NULL) { sae_clear_data(sae); + os_free(tmp); return ESP_FAIL; } tmp->order = tmp->order_buf; @@ -82,6 +76,7 @@ int sae_set_group(struct sae_data *sae, int group) /* Unsupported group */ wpa_printf(MSG_DEBUG, "SAE: Group %d not supported by the crypto library", group); + os_free(tmp); return ESP_FAIL; } @@ -152,7 +147,7 @@ static struct crypto_bignum * sae_get_rand(struct sae_data *sae) break; } - os_memset(val, 0, order_len); + forced_memzero(val, order_len); return bn; } @@ -680,6 +675,7 @@ static int sae_derive_commit(struct sae_data *sae) * theoretical infinite loop, break out after 100 * attemps. */ + crypto_bignum_deinit(mask, 1); return ESP_FAIL; } @@ -834,11 +830,11 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) if (sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK", val, sae->tmp->prime_len, keys, sizeof(keys)) < 0) goto fail; - os_memset(keyseed, 0, sizeof(keyseed)); + forced_memzero(keyseed, sizeof(keyseed)); os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN); os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN); os_memcpy(sae->pmkid, val, SAE_PMKID_LEN); - os_memset(keys, 0, sizeof(keys)); + forced_memzero(keys, sizeof(keys)); wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, SAE_KCK_LEN); wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN); @@ -1185,8 +1181,6 @@ static int sae_parse_password_identifier(struct sae_data *sae, sae->tmp->pw_id); return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER; } - os_free(sae->tmp->pw_id); - sae->tmp->pw_id = NULL; return WLAN_STATUS_SUCCESS; /* No Password Identifier */ } diff --git a/components/wpa_supplicant/src/common/scan.c b/components/wpa_supplicant/src/common/scan.c index 46dab15be13d..dac96e3b8085 100644 --- a/components/wpa_supplicant/src/common/scan.c +++ b/components/wpa_supplicant/src/common/scan.c @@ -36,6 +36,10 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Return"); return; } + if (!wpa_s->current_bss) { + wpa_dbg(wpa_s, MSG_INFO, "Current BSS is null - Return"); + return; + } params = os_zalloc(sizeof(*params)); if (!params) { diff --git a/components/wpa_supplicant/src/common/wnm_sta.c b/components/wpa_supplicant/src/common/wnm_sta.c index 284712f8b0c9..be6e0fa547bf 100644 --- a/components/wpa_supplicant/src/common/wnm_sta.c +++ b/components/wpa_supplicant/src/common/wnm_sta.c @@ -205,12 +205,15 @@ bool wpa_scan_res_match(struct wpa_supplicant *wpa_s, return false; } - /* TODO security Match */ + /* Just check for Open/secure mode */ + if ((current_bss->caps & WLAN_CAPABILITY_PRIVACY) != (target_bss->caps & WLAN_CAPABILITY_PRIVACY)) { + wpa_printf(MSG_DEBUG, "WNM: Security didn't match"); + return false; + } return true; } - static struct wpa_bss * compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs, enum mbo_transition_reject_reason *reason) diff --git a/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c b/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c index 155021ec1712..550d510819e7 100644 --- a/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c +++ b/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifdef ESP_PLATFORM #include "esp_system.h" @@ -65,6 +57,7 @@ int crypto_bignum_to_bin(const struct crypto_bignum *a, u8 *buf, size_t buflen, size_t padlen) { int num_bytes, offset; + int ret; if (padlen > buflen) { return -1; @@ -82,9 +75,11 @@ int crypto_bignum_to_bin(const struct crypto_bignum *a, } os_memset(buf, 0, offset); - mbedtls_mpi_write_binary((mbedtls_mpi *) a, buf + offset, mbedtls_mpi_size((mbedtls_mpi *)a) ); + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((mbedtls_mpi *) a, buf + offset, mbedtls_mpi_size((mbedtls_mpi *)a))); return num_bytes + offset; +cleanup: + return ret; } diff --git a/components/wpa_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/src/crypto/crypto_mbedtls-ec.c index 3f65393753aa..d55805db4b4a 100644 --- a/components/wpa_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifdef ESP_PLATFORM #include "esp_system.h" @@ -217,6 +209,9 @@ struct crypto_ec_point *crypto_ec_point_from_bin(struct crypto_ec *e, len = mbedtls_mpi_size(&e->group.P); pt = os_zalloc(sizeof(mbedtls_ecp_point)); + if (!pt) { + return NULL; + } mbedtls_ecp_point_init(pt); MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->X, val, len)); @@ -490,11 +485,15 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key(); if (!key) { - wpa_printf(MSG_ERROR, "%s: memory allocation failed\n", __func__); + wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); return NULL; } point = (mbedtls_ecp_point *)crypto_ec_point_from_bin((struct crypto_ec *)group, buf); + if (!point) { + wpa_printf(MSG_ERROR, "%s: Point initialization failed", __func__); + goto fail; + } if (crypto_ec_point_is_at_infinity((struct crypto_ec *)group, (struct crypto_ec_point *)point)) { wpa_printf(MSG_ERROR, "Point is at infinity"); goto fail; @@ -509,30 +508,16 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro wpa_printf(MSG_ERROR, "Invalid key"); goto fail; } - mbedtls_ecp_keypair *ecp_key = malloc(sizeof (*ecp_key)); - if (!ecp_key) { - wpa_printf(MSG_ERROR, "key allocation failed"); - goto fail; - } - - /* Init keypair */ - mbedtls_ecp_keypair_init(ecp_key); - // TODO Is it needed? check? - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&ecp_key->Q, point)); /* Assign values */ if( ( ret = mbedtls_pk_setup( key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ) ) != 0 ) goto fail; - if (key->pk_ctx) - os_free(key->pk_ctx); - key->pk_ctx = ecp_key; mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->Q, point); mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->grp, MBEDTLS_ECP_DP_SECP256R1); pkey = (struct crypto_key *)key; -cleanup: crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); return pkey; fail: @@ -566,7 +551,7 @@ int crypto_ec_get_priv_key_der(struct crypto_key *key, unsigned char **key_data, char der_data[ECP_PRV_DER_MAX_BYTES]; *key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES); - if (!*key_len) + if (*key_len <= 0) return -1; *key_data = os_malloc(*key_len); @@ -599,12 +584,12 @@ int crypto_ec_get_publickey_buf(struct crypto_key *key, u8 *key_buf, int len) mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; unsigned char buf[MBEDTLS_MPI_MAX_SIZE + 10]; /* tag, length + MPI */ unsigned char *c = buf + sizeof(buf ); - size_t pk_len = 0; + int pk_len = 0; memset(buf, 0, sizeof(buf) ); pk_len = mbedtls_pk_write_pubkey( &c, buf, pkey); - if (!pk_len) + if (pk_len < 0) return -1; if (len == 0) diff --git a/components/wpa_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/src/crypto/crypto_mbedtls.c index 9d9fb0e5fdd2..aa1d11804f48 100644 --- a/components/wpa_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/src/crypto/crypto_mbedtls.c @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifdef ESP_PLATFORM @@ -631,23 +621,16 @@ int crypto_mod_exp(const uint8_t *base, size_t base_len, mbedtls_mpi_init(&bn_result); mbedtls_mpi_init(&bn_rinv); - mbedtls_mpi_read_binary(&bn_base, base, base_len); - mbedtls_mpi_read_binary(&bn_exp, power, power_len); - mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len); + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&bn_base, base, base_len)); + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&bn_exp, power, power_len)); + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len)); - ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, - &bn_rinv); - if (ret < 0) { - mbedtls_mpi_free(&bn_base); - mbedtls_mpi_free(&bn_exp); - mbedtls_mpi_free(&bn_modulus); - mbedtls_mpi_free(&bn_result); - mbedtls_mpi_free(&bn_rinv); - return ret; - } + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, + &bn_rinv)); ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len); +cleanup: mbedtls_mpi_free(&bn_base); mbedtls_mpi_free(&bn_exp); mbedtls_mpi_free(&bn_modulus); diff --git a/components/wpa_supplicant/src/crypto/des-internal.c b/components/wpa_supplicant/src/crypto/des-internal.c index 4ed6957802b0..5d7cddae1fc8 100644 --- a/components/wpa_supplicant/src/crypto/des-internal.c +++ b/components/wpa_supplicant/src/crypto/des-internal.c @@ -419,8 +419,8 @@ int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) WPA_PUT_BE32(cypher, work[0]); WPA_PUT_BE32(cypher + 4, work[1]); - os_memset(pkey, 0, sizeof(pkey)); - os_memset(ek, 0, sizeof(ek)); + forced_memzero(pkey, sizeof(pkey)); + forced_memzero(ek, sizeof(ek)); return 0; } diff --git a/components/wpa_supplicant/src/crypto/libtommath.h b/components/wpa_supplicant/src/crypto/libtommath.h index 9e8ba2a0b257..b5f1a0eb524e 100644 --- a/components/wpa_supplicant/src/crypto/libtommath.h +++ b/components/wpa_supplicant/src/crypto/libtommath.h @@ -1657,7 +1657,7 @@ mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) } /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { return res; } diff --git a/components/wpa_supplicant/src/crypto/sha1-tprf.c b/components/wpa_supplicant/src/crypto/sha1-tprf.c new file mode 100644 index 000000000000..c3acf19750d5 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha1-tprf.c @@ -0,0 +1,72 @@ +/* + * SHA1 T-PRF for EAP-FAST + * Copyright (c) 2003-2005, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "sha1.h" +#include "crypto.h" + +/** + * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @seed: Seed value to bind into the key + * @seed_len: Length of the seed + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * Returns: 0 on success, -1 of failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5. + */ +int sha1_t_prf(const u8 *key, size_t key_len, const char *label, + const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) +{ + unsigned char counter = 0; + size_t pos, plen; + u8 hash[SHA1_MAC_LEN]; + size_t label_len = os_strlen(label); + u8 output_len[2]; + const unsigned char *addr[5]; + size_t len[5]; + + addr[0] = hash; + len[0] = 0; + addr[1] = (unsigned char *) label; + len[1] = label_len + 1; + addr[2] = seed; + len[2] = seed_len; + addr[3] = output_len; + len[3] = 2; + addr[4] = &counter; + len[4] = 1; + + output_len[0] = (buf_len >> 8) & 0xff; + output_len[1] = buf_len & 0xff; + pos = 0; + while (pos < buf_len) { + counter++; + plen = buf_len - pos; + if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) + return -1; + if (plen >= SHA1_MAC_LEN) { + os_memcpy(&buf[pos], hash, SHA1_MAC_LEN); + pos += SHA1_MAC_LEN; + } else { + os_memcpy(&buf[pos], hash, plen); + break; + } + len[0] = SHA1_MAC_LEN; + } + + forced_memzero(hash, SHA1_MAC_LEN); + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/src/crypto/tls_mbedtls.c index 23d8d9d7006e..785158b5ca44 100644 --- a/components/wpa_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/src/crypto/tls_mbedtls.c @@ -74,6 +74,7 @@ struct tls_connection { tls_context_t *tls; struct tls_data tls_io_data; unsigned char randbytes[2 * TLS_RANDOM_LEN]; + mbedtls_md_type_t mac; }; static void tls_mbedtls_cleanup(tls_context_t *tls) @@ -103,11 +104,9 @@ static int tls_mbedtls_write(void *ctx, const unsigned char *buf, size_t len) struct tls_connection *conn = (struct tls_connection *)ctx; struct tls_data *data = &conn->tls_io_data; - if (data->out_data) { - wpabuf_resize(&data->out_data, len); - } else { - data->out_data = wpabuf_alloc(len); - } + if (wpabuf_resize(&data->out_data, len) < 0) { + return 0; + } wpabuf_put_data(data->out_data, buf, len); @@ -119,21 +118,18 @@ static int tls_mbedtls_read(void *ctx, unsigned char *buf, size_t len) struct tls_connection *conn = (struct tls_connection *)ctx; struct tls_data *data = &conn->tls_io_data; struct wpabuf *local_buf; - size_t data_len = len; - if (data->in_data == NULL) { + if (data->in_data == NULL || len > wpabuf_len(data->in_data)) { + /* We don't have suffient buffer available for read */ + wpa_printf(MSG_INFO, "len=%zu not available in input", len); return MBEDTLS_ERR_SSL_WANT_READ; } - if (len > wpabuf_len(data->in_data)) { - wpa_printf(MSG_ERROR, "don't have suffient data\n"); - data_len = wpabuf_len(data->in_data); - } - - os_memcpy(buf, wpabuf_head(data->in_data), data_len); + os_memcpy(buf, wpabuf_head(data->in_data), len); /* adjust buffer */ if (len < wpabuf_len(data->in_data)) { - local_buf = wpabuf_alloc_copy(wpabuf_head(data->in_data) + len, + /* TODO optimize this operation */ + local_buf = wpabuf_alloc_copy(wpabuf_mhead_u8(data->in_data) + len, wpabuf_len(data->in_data) - len); wpabuf_free(data->in_data); data->in_data = local_buf; @@ -142,7 +138,7 @@ static int tls_mbedtls_read(void *ctx, unsigned char *buf, size_t len) data->in_data = NULL; } - return data_len; + return len; } static int set_pki_context(tls_context_t *tls, const struct tls_connection_params *cfg) @@ -545,7 +541,8 @@ int tls_global_set_verify(void *tls_ctx, int check_crl) } int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, - int verify_peer) + int verify_peer, unsigned int flags, + const u8 *session_ctx, size_t session_ctx_len) { wpa_printf(MSG_INFO, "TLS: tls_connection_set_verify not supported"); return -1; @@ -558,6 +555,7 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, { tls_context_t *tls = conn->tls; int ret = 0; + struct wpabuf *resp; /* data freed by sender */ conn->tls_io_data.out_data = NULL; @@ -572,6 +570,7 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, if (tls->ssl.handshake) { os_memcpy(conn->randbytes, tls->ssl.handshake->randbytes, TLS_RANDOM_LEN * 2); + conn->mac = tls->ssl.handshake->ciphersuite_info->mac; } } ret = mbedtls_ssl_handshake_step(&tls->ssl); @@ -591,7 +590,9 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, } end: - return conn->tls_io_data.out_data; + resp = conn->tls_io_data.out_data; + conn->tls_io_data.out_data = NULL; + return resp; } struct wpabuf * tls_connection_server_handshake(void *tls_ctx, @@ -608,10 +609,12 @@ struct wpabuf * tls_connection_encrypt(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data) { + struct wpabuf *resp; + size_t ret; + /* Reset dangling pointer */ conn->tls_io_data.out_data = NULL; - - ssize_t ret = mbedtls_ssl_write(&conn->tls->ssl, + ret = mbedtls_ssl_write(&conn->tls->ssl, (unsigned char*) wpabuf_head(in_data), wpabuf_len(in_data)); if (ret < wpabuf_len(in_data)) { @@ -619,27 +622,50 @@ struct wpabuf * tls_connection_encrypt(void *tls_ctx, __func__, __LINE__); } - return conn->tls_io_data.out_data; + resp = conn->tls_io_data.out_data; + conn->tls_io_data.out_data = NULL; + return resp; } -struct wpabuf * tls_connection_decrypt(void *tls_ctx, - struct tls_connection *conn, - const struct wpabuf *in_data) +struct wpabuf *tls_connection_decrypt(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data) { - unsigned char buf[1200]; +#define MAX_PHASE2_BUFFER 1536 + struct wpabuf *out = NULL; int ret; + unsigned char *buf = os_malloc(MAX_PHASE2_BUFFER); + + if (!buf) { + return NULL; + } + /* Reset dangling output buffer before setting data, data was freed by caller */ + conn->tls_io_data.out_data = NULL; + conn->tls_io_data.in_data = wpabuf_dup(in_data); - ret = mbedtls_ssl_read(&conn->tls->ssl, buf, 1200); + + if (!conn->tls_io_data.in_data) { + goto cleanup; + } + ret = mbedtls_ssl_read(&conn->tls->ssl, buf, MAX_PHASE2_BUFFER); if (ret < 0) { - wpa_printf(MSG_ERROR, "%s:%d, not able to write whole data", + wpa_printf(MSG_ERROR, "%s:%d, not able to read data", __func__, __LINE__); - return NULL; + goto cleanup; + } + out = wpabuf_alloc_copy(buf, ret); +cleanup: + /* there may be some error written in output buffer */ + if (conn->tls_io_data.out_data) { + os_free(conn->tls_io_data.out_data); + conn->tls_io_data.out_data = NULL; } - struct wpabuf *out = wpabuf_alloc_copy(buf, ret); + os_free(buf); return out; +#undef MAX_PHASE2_BUFFER } @@ -781,9 +807,8 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, int ret; u8 seed[2 * TLS_RANDOM_LEN]; mbedtls_ssl_context *ssl = &conn->tls->ssl; - mbedtls_ssl_transform *transform = ssl->transform; - if (!ssl || !transform) { + if (!ssl || !ssl->transform) { wpa_printf(MSG_ERROR, "TLS: %s, session ingo is null", __func__); return -1; } @@ -802,10 +827,10 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, wpa_hexdump_key(MSG_MSGDUMP, "random", seed, 2 * TLS_RANDOM_LEN); wpa_hexdump_key(MSG_MSGDUMP, "master", ssl->session->master, TLS_MASTER_SECRET_LEN); - if (transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384) { + if (conn->mac == MBEDTLS_MD_SHA384) { ret = tls_prf_sha384(ssl->session->master, TLS_MASTER_SECRET_LEN, label, seed, 2 * TLS_RANDOM_LEN, out, out_len); - } else if (transform->ciphersuite_info->mac == MBEDTLS_MD_SHA256) { + } else if (conn->mac == MBEDTLS_MD_SHA256) { ret = tls_prf_sha256(ssl->session->master, TLS_MASTER_SECRET_LEN, label, seed, 2 * TLS_RANDOM_LEN, out, out_len); } else { @@ -822,11 +847,27 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, } int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, - const char *label, u8 *out, size_t out_len) + const char *label, const u8 *context, + size_t context_len, u8 *out, size_t out_len) { return tls_connection_prf(tls_ctx, conn, label, 0, out, out_len); } +int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, + u8 *out, size_t out_len) +{ + wpa_printf(MSG_INFO, "TLS: tls_connection_get_eap_fast_key not supported, please unset mbedtls crypto and try again"); + return -1; +} + +int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, + int ext_type, const u8 *data, + size_t data_len) +{ + wpa_printf(MSG_INFO, "TLS: tls_connection_client_hello_ext not supported, please unset mbedtls crypto and try again"); + return -1; +} + int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) { if (conn->tls_io_data.in_data) { diff --git a/components/wpa_supplicant/src/eap_peer/eap.c b/components/wpa_supplicant/src/eap_peer/eap.c index b71f4c14b3d0..23903d07f16b 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.c +++ b/components/wpa_supplicant/src/eap_peer/eap.c @@ -49,6 +49,7 @@ void eap_deinit_prev_method(struct eap_sm *sm, const char *txt); #ifdef EAP_PEER_METHOD static struct eap_method *eap_methods = NULL; +static struct eap_method_type *config_methods; const struct eap_method * eap_peer_get_eap_method(int vendor, EapType method) { @@ -72,6 +73,33 @@ const struct eap_method * eap_peer_get_methods(size_t *count) return eap_methods; } +/** + * eap_config_allowed_method - Check whether EAP method is allowed + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @config: EAP configuration + * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types + * @method: EAP type + * Returns: 1 = allowed EAP method, 0 = not allowed + */ +static int eap_config_allowed_method(struct eap_sm *sm, + struct eap_peer_config *config, + int vendor, u32 method) +{ + int i; + struct eap_method_type *m; + + if (config == NULL || config->eap_methods == NULL) + return 1; + + m = config->eap_methods; + for (i = 0; m[i].vendor != EAP_VENDOR_IETF || + m[i].method != EAP_TYPE_NONE; i++) { + if (m[i].vendor == vendor && m[i].method == method) + return 1; + } + return 0; +} + EapType eap_peer_get_type(const char *name, int *vendor) { struct eap_method *m; @@ -85,6 +113,21 @@ EapType eap_peer_get_type(const char *name, int *vendor) return EAP_TYPE_NONE; } + +/** + * eap_allowed_method - Check whether EAP method is allowed + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types + * @method: EAP type + * Returns: 1 = allowed EAP method, 0 = not allowed + */ +int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method) +{ + return eap_config_allowed_method(sm, eap_get_config(sm), vendor, + method); +} + + static int eap_allowed_phase2_type(int vendor, int type) { @@ -194,6 +237,21 @@ void eap_peer_unregister_methods(void) +bool eap_sm_allowMethod(struct eap_sm *sm, int vendor, + EapType method) +{ + if (!eap_allowed_method(sm, vendor, method)) { + wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " + "vendor %u method %u", vendor, method); + return FALSE; + } + if (eap_peer_get_eap_method(vendor, method)) + return TRUE; + wpa_printf(MSG_DEBUG, "EAP: not included in build: " + "vendor %u method %u", vendor, method); + return FALSE; +} + int eap_peer_register_methods(void) { int ret = 0; @@ -213,6 +271,13 @@ int eap_peer_register_methods(void) ret = eap_peer_mschapv2_register(); #endif +#ifndef USE_MBEDTLS_CRYPTO +#ifdef EAP_FAST + if (ret == 0) + ret = eap_peer_fast_register(); +#endif +#endif + #ifdef EAP_PEAP if (ret == 0) ret = eap_peer_peap_register(); @@ -435,11 +500,12 @@ int eap_peer_config_init( sm->config.client_cert = (u8 *)sm->blob[0].name; sm->config.private_key = (u8 *)sm->blob[1].name; sm->config.ca_cert = (u8 *)sm->blob[2].name; - sm->config.ca_path = NULL; sm->config.fragment_size = 1400; /* fragment size */ + sm->config.pac_file = (char *) "blob://"; + /* anonymous identity */ if (g_wpa_anonymous_identity && g_wpa_anonymous_identity_len > 0) { sm->config.anonymous_identity_len = g_wpa_anonymous_identity_len; @@ -483,6 +549,56 @@ int eap_peer_config_init( sm->config.phase2 = "auth=MSCHAPV2"; } + /* To be used only for EAP-FAST */ + if (g_wpa_phase1_options) { + sm->config.phase1 = g_wpa_phase1_options; + } + + /* Allow methods with correct configuration only */ + size_t mcount; + int allowed_method_count = 0; + const struct eap_method *methods; + + if (!config_methods) { + methods = eap_peer_get_methods(&mcount); + if (methods == NULL) { + wpa_printf(MSG_ERROR, "EAP: Set config init: EAP methods not registered."); + return -1; + } + + // Allocate a buffer large enough to accomodate all the registered methods. + config_methods = os_malloc(mcount * sizeof(struct eap_method_type)); + if (config_methods == NULL) { + wpa_printf(MSG_ERROR, "EAP: Set config init: Out of memory, set configured methods failed"); + return -1; + } + + if (g_wpa_username) { + //set EAP-PEAP + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_PEAP; + //set EAP-TTLS + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_TTLS; + } + if (g_wpa_private_key) { + //set EAP-TLS + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_TLS; + } +#ifndef USE_MBEDTLS_CRYPTO + if (g_wpa_pac_file) { + //set EAP-FAST + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_FAST; + } +#endif + // Terminate the allowed method list + config_methods[allowed_method_count].vendor = EAP_VENDOR_IETF; + config_methods[allowed_method_count++].method = EAP_TYPE_NONE; + // Set the allowed methods to config + sm->config.eap_methods = config_methods; + } return 0; } @@ -496,6 +612,7 @@ void eap_peer_config_deinit(struct eap_sm *sm) os_free(sm->config.identity); os_free(sm->config.password); os_free(sm->config.new_password); + os_free(sm->config.eap_methods); os_bzero(&sm->config, sizeof(struct eap_peer_config)); } @@ -539,6 +656,17 @@ int eap_peer_blob_init(struct eap_sm *sm) sm->blob[2].data = g_wpa_ca_cert; } + if (g_wpa_pac_file && g_wpa_pac_file_len) { + sm->blob[3].name = (char *)os_zalloc(sizeof(char) * 8); + if (sm->blob[3].name == NULL) { + ret = -2; + goto _out; + } + os_strncpy(sm->blob[3].name, "blob://", 8); + sm->blob[3].len = g_wpa_pac_file_len; + sm->blob[3].data = g_wpa_pac_file; + } + return 0; _out: for (i = 0; i < BLOB_NUM; i++) { @@ -596,7 +724,6 @@ const char * eap_sm_get_method_name(struct eap_sm *sm) return sm->m->name; } - /** * eap_sm_request_identity - Request identity from user (ctrl_iface) * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() @@ -611,6 +738,37 @@ void eap_sm_request_identity(struct eap_sm *sm) eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0); } + +/** + * eap_sm_request_password - Request password from user (ctrl_iface) + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * + * EAP methods can call this function to request password information for the + * current network. This is normally called when the password is not included + * in the network configuration. The request will be sent to monitor programs + * through the control interface. + */ +void eap_sm_request_password(struct eap_sm *sm) +{ + eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0); +} + + +/** + * eap_sm_request_new_password - Request new password from user (ctrl_iface) + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * + * EAP methods can call this function to request new password information for + * the current network. This is normally called when the EAP method indicates + * that the current password has expired and password change is required. The + * request will be sent to monitor programs through the control interface. + */ +void eap_sm_request_new_password(struct eap_sm *sm) +{ + eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0); +} + + void eap_peer_blob_deinit(struct eap_sm *sm) { int i; @@ -625,6 +783,7 @@ void eap_peer_blob_deinit(struct eap_sm *sm) sm->config.client_cert = NULL; sm->config.private_key = NULL; sm->config.ca_cert = NULL; + sm->config.pac_file = NULL; } void eap_sm_abort(struct eap_sm *sm) @@ -717,6 +876,40 @@ const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len) *len = config->new_password_len; return config->new_password; } + + +static int eap_copy_buf(u8 **dst, size_t *dst_len, + const u8 *src, size_t src_len) +{ + if (src) { + *dst = os_memdup(src, src_len); + if (*dst == NULL) + return -1; + *dst_len = src_len; + } + return 0; +} + + +/** + * eap_set_config_blob - Set or add a named configuration blob + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @blob: New value for the blob + * + * Adds a new configuration blob or replaces the current value of an existing + * blob. + */ +void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob) +{ + if (!sm) + return; + + if (eap_copy_buf((u8 **)&sm->blob[3].data, (size_t *)&sm->blob[3].len, blob->data, blob->len) < 0) { + wpa_printf(MSG_ERROR, "EAP: Set config blob: Unable to modify the configuration blob"); + } +} + + /** * eap_get_config_blob - Get a named configuration blob * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() diff --git a/components/wpa_supplicant/src/eap_peer/eap.h b/components/wpa_supplicant/src/eap_peer/eap.h index 5432f43c32f7..a6ddeb4111f3 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.h +++ b/components/wpa_supplicant/src/eap_peer/eap.h @@ -40,6 +40,10 @@ u8 *g_wpa_new_password; int g_wpa_new_password_len; char *g_wpa_ttls_phase2_type; +char *g_wpa_phase1_options; + +u8 *g_wpa_pac_file; +int g_wpa_pac_file_len; const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len); void eap_deinit_prev_method(struct eap_sm *sm, const char *txt); @@ -54,5 +58,8 @@ void eap_peer_config_deinit(struct eap_sm *sm); void eap_sm_abort(struct eap_sm *sm); int eap_peer_register_methods(void); void eap_sm_request_identity(struct eap_sm *sm); +void eap_sm_request_password(struct eap_sm *sm); +void eap_sm_request_new_password(struct eap_sm *sm); +bool eap_sm_allowMethod(struct eap_sm *sm, int vendor, EapType method); #endif /* EAP_H */ diff --git a/components/wpa_supplicant/src/eap_peer/eap_config.h b/components/wpa_supplicant/src/eap_peer/eap_config.h index c6cad6f9366e..3ee19b64f4e9 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_config.h +++ b/components/wpa_supplicant/src/eap_peer/eap_config.h @@ -294,6 +294,15 @@ struct eap_peer_config { */ int pending_req_passphrase; + /** + * pending_req_sim - Pending SIM request + * + * This field should not be set in configuration step. It is only used + * internally when control interface is used to request needed + * information. + */ + int pending_req_sim; + /** * pending_req_otp - Whether there is a pending OTP request * @@ -303,6 +312,18 @@ struct eap_peer_config { */ char *pending_req_otp; + /** + * pac_file - File path or blob name for the PAC entries (EAP-FAST) + * + * wpa_supplicant will need to be able to create this file and write + * updates to it when PAC is being provisioned or refreshed. Full path + * to the file should be used since working directory may change when + * wpa_supplicant is run in the background. + * Alternatively, a named configuration blob can be used by setting + * this to blob://blob_name. + */ + char *pac_file; + /** * mschapv2_retry - MSCHAPv2 retry in progress * @@ -358,6 +379,26 @@ struct eap_peer_config { * 2 = require valid OCSP stapling response */ int ocsp; + + /** + * erp - Whether EAP Re-authentication Protocol (ERP) is enabled + */ + int erp; + + /** + * pending_ext_cert_check - External server certificate check status + * + * This field should not be set in configuration step. It is only used + * internally when control interface is used to request external + * validation of server certificate chain. + */ + enum { + NO_CHECK = 0, + PENDING_CHECK, + EXT_CERT_CHECK_GOOD, + EXT_CERT_CHECK_BAD, + } pending_ext_cert_check; + }; diff --git a/components/wpa_supplicant/src/eap_peer/eap_fast.c b/components/wpa_supplicant/src/eap_peer/eap_fast.c new file mode 100644 index 000000000000..b54bae37383f --- /dev/null +++ b/components/wpa_supplicant/src/eap_peer/eap_fast.c @@ -0,0 +1,1807 @@ +/* + * EAP peer method: EAP-FAST (RFC 4851) + * Copyright (c) 2004-2015, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "tls/tls.h" +#include "crypto/sha1.h" +#include "eap_peer/eap_tlv_common.h" +#include "eap_peer/eap_methods.h" +#include "eap_i.h" +#include "eap_tls_common.h" +#include "eap_config.h" +#include "eap_fast_pac.h" + +#include "eap_fast_pac.c" + +/* TODO: + * - test session resumption and enable it if it interoperates + * - password change (pending mschapv2 packet; replay decrypted packet) + */ + + +static void eap_fast_deinit(struct eap_sm *sm, void *priv); + + +struct eap_fast_data { + struct eap_ssl_data ssl; + + int fast_version; + + const struct eap_method *phase2_method; + void *phase2_priv; + int phase2_success; + + struct eap_method_type phase2_type; + struct eap_method_type *phase2_types; + size_t num_phase2_types; + int resuming; /* starting a resumed session */ + struct eap_fast_key_block_provisioning *key_block_p; +#define EAP_FAST_PROV_UNAUTH 1 +#define EAP_FAST_PROV_AUTH 2 + int provisioning_allowed; /* Allowed PAC provisioning modes */ + int provisioning; /* doing PAC provisioning (not the normal auth) */ + int anon_provisioning; /* doing anonymous (unauthenticated) + * provisioning */ + int session_ticket_used; + + u8 key_data[EAP_FAST_KEY_LEN]; + u8 *session_id; + size_t id_len; + u8 emsk[EAP_EMSK_LEN]; + int success; + + struct eap_fast_pac *pac; + struct eap_fast_pac *current_pac; + size_t max_pac_list_len; + int use_pac_binary_format; + + u8 simck[EAP_FAST_SIMCK_LEN]; + int simck_idx; + + struct wpabuf *pending_phase2_req; + struct wpabuf *pending_resp; +}; + + +static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, + const u8 *client_random, + const u8 *server_random, + u8 *master_secret) +{ + struct eap_fast_data *data = ctx; + + wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback"); + + if (client_random == NULL || server_random == NULL || + master_secret == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket failed - fall " + "back to full TLS handshake"); + data->session_ticket_used = 0; + if (data->provisioning_allowed) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Try to provision a " + "new PAC-Key"); + data->provisioning = 1; + data->current_pac = NULL; + } + return 0; + } + + wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket", ticket, len); + + if (data->current_pac == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key available for " + "using SessionTicket"); + data->session_ticket_used = 0; + return 0; + } + + eap_fast_derive_master_secret(data->current_pac->pac_key, + server_random, client_random, + master_secret); + + data->session_ticket_used = 1; + + return 1; +} + + +static void eap_fast_parse_phase1(struct eap_fast_data *data, + const char *phase1) +{ + const char *pos; + + pos = os_strstr(phase1, "fast_provisioning="); + if (pos) { + data->provisioning_allowed = atoi(pos + 18); + wpa_printf(MSG_INFO, "EAP-FAST: Automatic PAC provisioning " + "mode: %d", data->provisioning_allowed); + } + + pos = os_strstr(phase1, "fast_max_pac_list_len="); + if (pos) { + data->max_pac_list_len = atoi(pos + 22); + if (data->max_pac_list_len == 0) + data->max_pac_list_len = 1; + wpa_printf(MSG_INFO, "EAP-FAST: Maximum PAC list length: %lu", + (unsigned long) data->max_pac_list_len); + } + + pos = os_strstr(phase1, "fast_pac_format=binary"); + if (pos) { + data->use_pac_binary_format = 1; + wpa_printf(MSG_INFO, "EAP-FAST: Using binary format for PAC " + "list"); + } +} + + +static void * eap_fast_init(struct eap_sm *sm) +{ + struct eap_fast_data *data; + struct eap_peer_config *config = eap_get_config(sm); + + if (config == NULL) + return NULL; + + data = os_zalloc(sizeof(*data)); + if (data == NULL) + return NULL; + data->fast_version = EAP_FAST_VERSION; + data->max_pac_list_len = 10; + + if (config->phase1) + eap_fast_parse_phase1(data, config->phase1); + + if (eap_peer_select_phase2_methods(config, "auth=", + &data->phase2_types, + &data->num_phase2_types) < 0) { + eap_fast_deinit(sm, data); + return NULL; + } + + data->phase2_type.vendor = EAP_VENDOR_IETF; + data->phase2_type.method = EAP_TYPE_NONE; + + if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_FAST)) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL."); + eap_fast_deinit(sm, data); + return NULL; + } + + if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn, + eap_fast_session_ticket_cb, + data) < 0) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to set SessionTicket " + "callback"); + eap_fast_deinit(sm, data); + return NULL; + } + + /* + * The local RADIUS server in a Cisco AP does not seem to like empty + * fragments before data, so disable that workaround for CBC. + * TODO: consider making this configurable + */ + if (tls_connection_enable_workaround(sm->ssl_ctx, data->ssl.conn)) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to enable TLS " + "workarounds"); + } + + if (!config->pac_file) { + wpa_printf(MSG_INFO, "EAP-FAST: No PAC file configured"); + eap_fast_deinit(sm, data); + return NULL; + } + + if (data->use_pac_binary_format && + eap_fast_load_pac_bin(sm, &data->pac, config->pac_file) < 0) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to load PAC file"); + eap_fast_deinit(sm, data); + return NULL; + } + + if (!data->use_pac_binary_format && + eap_fast_load_pac(sm, &data->pac, config->pac_file) < 0) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to load PAC file"); + eap_fast_deinit(sm, data); + return NULL; + } + eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len); + + if (data->pac == NULL && !data->provisioning_allowed) { + wpa_printf(MSG_INFO, "EAP-FAST: No PAC configured and " + "provisioning disabled"); + eap_fast_deinit(sm, data); + return NULL; + } + + return data; +} + + +static void eap_fast_deinit(struct eap_sm *sm, void *priv) +{ + struct eap_fast_data *data = priv; + struct eap_fast_pac *pac, *prev; + + if (data == NULL) + return; + if (data->phase2_priv && data->phase2_method) + data->phase2_method->deinit(sm, data->phase2_priv); + os_free(data->phase2_types); + os_free(data->key_block_p); + eap_peer_tls_ssl_deinit(sm, &data->ssl); + + pac = data->pac; + prev = NULL; + while (pac) { + prev = pac; + pac = pac->next; + eap_fast_free_pac(prev); + } + os_memset(data->key_data, 0, EAP_FAST_KEY_LEN); + os_memset(data->emsk, 0, EAP_EMSK_LEN); + os_free(data->session_id); + wpabuf_free(data->pending_phase2_req); + wpabuf_free(data->pending_resp); + os_free(data); +} + + +static int eap_fast_derive_msk(struct eap_fast_data *data) +{ + if (eap_fast_derive_eap_msk(data->simck, data->key_data) < 0 || + eap_fast_derive_eap_emsk(data->simck, data->emsk) < 0) + return -1; + data->success = 1; + return 0; +} + + +static int eap_fast_derive_key_auth(struct eap_sm *sm, + struct eap_fast_data *data) +{ + u8 *sks; + + /* RFC 4851, Section 5.1: + * Extra key material after TLS key_block: session_key_seed[40] + */ + + sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, + EAP_FAST_SKS_LEN); + if (sks == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive " + "session_key_seed"); + return -1; + } + + /* + * RFC 4851, Section 5.2: + * S-IMCK[0] = session_key_seed + */ + wpa_hexdump_key(MSG_DEBUG, + "EAP-FAST: session_key_seed (SKS = S-IMCK[0])", + sks, EAP_FAST_SKS_LEN); + data->simck_idx = 0; + os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN); + os_free(sks); + return 0; +} + + +static int eap_fast_derive_key_provisioning(struct eap_sm *sm, + struct eap_fast_data *data) +{ + os_free(data->key_block_p); + data->key_block_p = (struct eap_fast_key_block_provisioning *) + eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, + sizeof(*data->key_block_p)); + if (data->key_block_p == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block"); + return -1; + } + /* + * RFC 4851, Section 5.2: + * S-IMCK[0] = session_key_seed + */ + wpa_hexdump_key(MSG_DEBUG, + "EAP-FAST: session_key_seed (SKS = S-IMCK[0])", + data->key_block_p->session_key_seed, + sizeof(data->key_block_p->session_key_seed)); + data->simck_idx = 0; + os_memcpy(data->simck, data->key_block_p->session_key_seed, + EAP_FAST_SIMCK_LEN); + wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge", + data->key_block_p->server_challenge, + sizeof(data->key_block_p->server_challenge)); + wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge", + data->key_block_p->client_challenge, + sizeof(data->key_block_p->client_challenge)); + return 0; +} + + +static int eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data) +{ + int res; + + if (data->anon_provisioning) + res = eap_fast_derive_key_provisioning(sm, data); + else + res = eap_fast_derive_key_auth(sm, data); + return res; +} + + +static int eap_fast_init_phase2_method(struct eap_sm *sm, + struct eap_fast_data *data) +{ + data->phase2_method = + eap_peer_get_eap_method(data->phase2_type.vendor, + data->phase2_type.method); + if (data->phase2_method == NULL) + return -1; + + if (data->key_block_p) { + sm->auth_challenge = data->key_block_p->server_challenge; + sm->peer_challenge = data->key_block_p->client_challenge; + } + sm->init_phase2 = 1; + data->phase2_priv = data->phase2_method->init(sm); + sm->init_phase2 = 0; + sm->auth_challenge = NULL; + sm->peer_challenge = NULL; + + return data->phase2_priv == NULL ? -1 : 0; +} + + +static int eap_fast_select_phase2_method(struct eap_fast_data *data, u8 type) +{ + size_t i; + + /* TODO: TNC with anonymous provisioning; need to require both + * completed MSCHAPv2 and TNC */ + + if (data->anon_provisioning && type != EAP_TYPE_MSCHAPV2) { + wpa_printf(MSG_INFO, "EAP-FAST: Only EAP-MSCHAPv2 is allowed " + "during unauthenticated provisioning; reject phase2" + " type %d", type); + return -1; + } + +#ifdef EAP_TNC + if (type == EAP_TYPE_TNC) { + data->phase2_type.vendor = EAP_VENDOR_IETF; + data->phase2_type.method = EAP_TYPE_TNC; + wpa_printf(MSG_DEBUG, "EAP-FAST: Selected Phase 2 EAP " + "vendor %d method %d for TNC", + data->phase2_type.vendor, + data->phase2_type.method); + return 0; + } +#endif /* EAP_TNC */ + + for (i = 0; i < data->num_phase2_types; i++) { + if (data->phase2_types[i].vendor != EAP_VENDOR_IETF || + data->phase2_types[i].method != type) + continue; + + data->phase2_type.vendor = data->phase2_types[i].vendor; + data->phase2_type.method = data->phase2_types[i].method; + wpa_printf(MSG_DEBUG, "EAP-FAST: Selected Phase 2 EAP " + "vendor %d method %d", + data->phase2_type.vendor, + data->phase2_type.method); + break; + } + + if (type != data->phase2_type.method || type == EAP_TYPE_NONE) + return -1; + + return 0; +} + + +static int eap_fast_phase2_request(struct eap_sm *sm, + struct eap_fast_data *data, + struct eap_method_ret *ret, + struct eap_hdr *hdr, + struct wpabuf **resp) +{ + size_t len = be_to_host16(hdr->length); + u8 *pos; + struct eap_method_ret iret; + struct eap_peer_config *config = eap_get_config(sm); + struct wpabuf msg; + + if (len <= sizeof(struct eap_hdr)) { + wpa_printf(MSG_INFO, "EAP-FAST: too short " + "Phase 2 request (len=%lu)", (unsigned long) len); + return -1; + } + pos = (u8 *) (hdr + 1); + wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos); + if (*pos == EAP_TYPE_IDENTITY) { + *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1); + return 0; + } + + if (data->phase2_priv && data->phase2_method && + *pos != data->phase2_type.method) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 EAP sequence - " + "deinitialize previous method"); + data->phase2_method->deinit(sm, data->phase2_priv); + data->phase2_method = NULL; + data->phase2_priv = NULL; + data->phase2_type.vendor = EAP_VENDOR_IETF; + data->phase2_type.method = EAP_TYPE_NONE; + } + + if (data->phase2_type.vendor == EAP_VENDOR_IETF && + data->phase2_type.method == EAP_TYPE_NONE && + eap_fast_select_phase2_method(data, *pos) < 0) { + if (eap_peer_tls_phase2_nak(data->phase2_types, + data->num_phase2_types, + hdr, resp)) + return -1; + return 0; + } + + if ((data->phase2_priv == NULL && + eap_fast_init_phase2_method(sm, data) < 0) || + data->phase2_method == NULL) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize " + "Phase 2 EAP method %d", *pos); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + return -1; + } + + os_memset(&iret, 0, sizeof(iret)); + wpabuf_set(&msg, hdr, len); + *resp = data->phase2_method->process(sm, data->phase2_priv, &iret, + &msg); + if (*resp == NULL || + (iret.methodState == METHOD_DONE && + iret.decision == DECISION_FAIL)) { + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + } else if ((iret.methodState == METHOD_DONE || + iret.methodState == METHOD_MAY_CONT) && + (iret.decision == DECISION_UNCOND_SUCC || + iret.decision == DECISION_COND_SUCC)) { + data->phase2_success = 1; + } + + if (*resp == NULL && config && + (config->pending_req_identity || config->pending_req_password || + config->pending_req_otp || config->pending_req_new_password || + config->pending_req_sim)) { + wpabuf_clear_free(data->pending_phase2_req); + data->pending_phase2_req = wpabuf_alloc_copy(hdr, len); + } else if (*resp == NULL) + return -1; + + return 0; +} + + +static struct wpabuf * eap_fast_tlv_nak(int vendor_id, int tlv_type) +{ + struct wpabuf *buf; + struct eap_tlv_nak_tlv *nak; + buf = wpabuf_alloc(sizeof(*nak)); + if (buf == NULL) + return NULL; + nak = wpabuf_put(buf, sizeof(*nak)); + nak->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | EAP_TLV_NAK_TLV); + nak->length = host_to_be16(6); + nak->vendor_id = host_to_be32(vendor_id); + nak->nak_type = host_to_be16(tlv_type); + return buf; +} + + +static struct wpabuf * eap_fast_tlv_result(int status, int intermediate) +{ + struct wpabuf *buf; + struct eap_tlv_intermediate_result_tlv *result; + buf = wpabuf_alloc(sizeof(*result)); + if (buf == NULL) + return NULL; + wpa_printf(MSG_DEBUG, "EAP-FAST: Add %sResult TLV(status=%d)", + intermediate ? "Intermediate " : "", status); + result = wpabuf_put(buf, sizeof(*result)); + result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | + (intermediate ? + EAP_TLV_INTERMEDIATE_RESULT_TLV : + EAP_TLV_RESULT_TLV)); + result->length = host_to_be16(2); + result->status = host_to_be16(status); + return buf; +} + + +static struct wpabuf * eap_fast_tlv_pac_ack(void) +{ + struct wpabuf *buf; + struct eap_tlv_result_tlv *res; + struct eap_tlv_pac_ack_tlv *ack; + + buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack)); + if (buf == NULL) + return NULL; + + wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV (ack)"); + ack = wpabuf_put(buf, sizeof(*ack)); + ack->tlv_type = host_to_be16(EAP_TLV_PAC_TLV | + EAP_TLV_TYPE_MANDATORY); + ack->length = host_to_be16(sizeof(*ack) - sizeof(struct eap_tlv_hdr)); + ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT); + ack->pac_len = host_to_be16(2); + ack->result = host_to_be16(EAP_TLV_RESULT_SUCCESS); + + return buf; +} + + +static struct wpabuf * eap_fast_process_eap_payload_tlv( + struct eap_sm *sm, struct eap_fast_data *data, + struct eap_method_ret *ret, + u8 *eap_payload_tlv, size_t eap_payload_tlv_len) +{ + struct eap_hdr *hdr; + struct wpabuf *resp = NULL; + + if (eap_payload_tlv_len < sizeof(*hdr)) { + wpa_printf(MSG_DEBUG, "EAP-FAST: too short EAP " + "Payload TLV (len=%lu)", + (unsigned long) eap_payload_tlv_len); + return NULL; + } + + hdr = (struct eap_hdr *) eap_payload_tlv; + if (be_to_host16(hdr->length) > eap_payload_tlv_len) { + wpa_printf(MSG_DEBUG, "EAP-FAST: EAP packet overflow in " + "EAP Payload TLV"); + return NULL; + } + + if (hdr->code != EAP_CODE_REQUEST) { + wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in " + "Phase 2 EAP header", hdr->code); + return NULL; + } + + if (eap_fast_phase2_request(sm, data, ret, hdr, &resp)) { + wpa_printf(MSG_INFO, "EAP-FAST: Phase2 Request processing " + "failed"); + return NULL; + } + + return eap_fast_tlv_eap_payload(resp); +} + + +static int eap_fast_validate_crypto_binding( + struct eap_tlv_crypto_binding_tlv *_bind) +{ + wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV: Version %d " + "Received Version %d SubType %d", + _bind->version, _bind->received_version, _bind->subtype); + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE", + _bind->nonce, sizeof(_bind->nonce)); + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC", + _bind->compound_mac, sizeof(_bind->compound_mac)); + + if (_bind->version != EAP_FAST_VERSION || + _bind->received_version != EAP_FAST_VERSION || + _bind->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST) { + wpa_printf(MSG_INFO, "EAP-FAST: Invalid version/subtype in " + "Crypto-Binding TLV: Version %d " + "Received Version %d SubType %d", + _bind->version, _bind->received_version, + _bind->subtype); + return -1; + } + + return 0; +} + + +static void eap_fast_write_crypto_binding( + struct eap_tlv_crypto_binding_tlv *rbind, + struct eap_tlv_crypto_binding_tlv *_bind, const u8 *cmk) +{ + rbind->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | + EAP_TLV_CRYPTO_BINDING_TLV); + rbind->length = host_to_be16(sizeof(*rbind) - + sizeof(struct eap_tlv_hdr)); + rbind->version = EAP_FAST_VERSION; + rbind->received_version = _bind->version; + rbind->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE; + os_memcpy(rbind->nonce, _bind->nonce, sizeof(_bind->nonce)); + inc_byte_array(rbind->nonce, sizeof(rbind->nonce)); + hmac_sha1(cmk, EAP_FAST_CMK_LEN, (u8 *) rbind, sizeof(*rbind), + rbind->compound_mac); + + wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: Version %d " + "Received Version %d SubType %d", + rbind->version, rbind->received_version, rbind->subtype); + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE", + rbind->nonce, sizeof(rbind->nonce)); + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC", + rbind->compound_mac, sizeof(rbind->compound_mac)); +} + + +static int eap_fast_get_phase2_key(struct eap_sm *sm, + struct eap_fast_data *data, + u8 *isk, size_t isk_len) +{ + u8 *key; + size_t key_len; + + os_memset(isk, 0, isk_len); + + if (data->phase2_method == NULL || data->phase2_priv == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not " + "available"); + return -1; + } + + if (data->phase2_method->isKeyAvailable == NULL || + data->phase2_method->getKey == NULL) + return 0; + + if (!data->phase2_method->isKeyAvailable(sm, data->phase2_priv) || + (key = data->phase2_method->getKey(sm, data->phase2_priv, + &key_len)) == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key material " + "from Phase 2"); + return -1; + } + + if (key_len > isk_len) + key_len = isk_len; + if (key_len == 32 && + data->phase2_method->vendor == EAP_VENDOR_IETF && + data->phase2_method->method == EAP_TYPE_MSCHAPV2) { + /* + * EAP-FAST uses reverse order for MS-MPPE keys when deriving + * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct + * ISK for EAP-FAST cryptobinding. + */ + os_memcpy(isk, key + 16, 16); + os_memcpy(isk + 16, key, 16); + } else + os_memcpy(isk, key, key_len); + os_free(key); + + return 0; +} + + +static int eap_fast_get_cmk(struct eap_sm *sm, struct eap_fast_data *data, + u8 *cmk) +{ + u8 isk[32], imck[60]; + + wpa_printf(MSG_DEBUG, "EAP-FAST: Determining CMK[%d] for Compound MIC " + "calculation", data->simck_idx + 1); + + /* + * RFC 4851, Section 5.2: + * IMCK[j] = T-PRF(S-IMCK[j-1], "Inner Methods Compound Keys", + * MSK[j], 60) + * S-IMCK[j] = first 40 octets of IMCK[j] + * CMK[j] = last 20 octets of IMCK[j] + */ + + if (eap_fast_get_phase2_key(sm, data, isk, sizeof(isk)) < 0) + return -1; + wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[j]", isk, sizeof(isk)); + if (sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN, + "Inner Methods Compound Keys", + isk, sizeof(isk), imck, sizeof(imck)) < 0) + return -1; + data->simck_idx++; + os_memcpy(data->simck, imck, EAP_FAST_SIMCK_LEN); + wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[j]", + data->simck, EAP_FAST_SIMCK_LEN); + os_memcpy(cmk, imck + EAP_FAST_SIMCK_LEN, EAP_FAST_CMK_LEN); + wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK[j]", + cmk, EAP_FAST_CMK_LEN); + + return 0; +} + + +static u8 * eap_fast_write_pac_request(u8 *pos, u16 pac_type) +{ + struct eap_tlv_hdr *pac; + struct eap_tlv_request_action_tlv *act; + struct eap_tlv_pac_type_tlv *type; + + act = (struct eap_tlv_request_action_tlv *) pos; + act->tlv_type = host_to_be16(EAP_TLV_REQUEST_ACTION_TLV); + act->length = host_to_be16(2); + act->action = host_to_be16(EAP_TLV_ACTION_PROCESS_TLV); + + pac = (struct eap_tlv_hdr *) (act + 1); + pac->tlv_type = host_to_be16(EAP_TLV_PAC_TLV); + pac->length = host_to_be16(sizeof(*type)); + + type = (struct eap_tlv_pac_type_tlv *) (pac + 1); + type->tlv_type = host_to_be16(PAC_TYPE_PAC_TYPE); + type->length = host_to_be16(2); + type->pac_type = host_to_be16(pac_type); + + return (u8 *) (type + 1); +} + + +static struct wpabuf * eap_fast_process_crypto_binding( + struct eap_sm *sm, struct eap_fast_data *data, + struct eap_method_ret *ret, + struct eap_tlv_crypto_binding_tlv *_bind, size_t bind_len) +{ + struct wpabuf *resp; + u8 *pos; + u8 cmk[EAP_FAST_CMK_LEN], cmac[SHA1_MAC_LEN]; + int res; + size_t len; + + if (eap_fast_validate_crypto_binding(_bind) < 0) + return NULL; + + if (eap_fast_get_cmk(sm, data, cmk) < 0) + return NULL; + + /* Validate received Compound MAC */ + os_memcpy(cmac, _bind->compound_mac, sizeof(cmac)); + os_memset(_bind->compound_mac, 0, sizeof(cmac)); + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for Compound " + "MAC calculation", (u8 *) _bind, bind_len); + hmac_sha1(cmk, EAP_FAST_CMK_LEN, (u8 *) _bind, bind_len, + _bind->compound_mac); + res = os_memcmp_const(cmac, _bind->compound_mac, sizeof(cmac)); + wpa_hexdump(MSG_DEBUG, "EAP-FAST: Received Compound MAC", + cmac, sizeof(cmac)); + wpa_hexdump(MSG_DEBUG, "EAP-FAST: Calculated Compound MAC", + _bind->compound_mac, sizeof(cmac)); + if (res != 0) { + wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not match"); + os_memcpy(_bind->compound_mac, cmac, sizeof(cmac)); + return NULL; + } + + /* + * Compound MAC was valid, so authentication succeeded. Reply with + * crypto binding to allow server to complete authentication. + */ + + len = sizeof(struct eap_tlv_crypto_binding_tlv); + resp = wpabuf_alloc(len); + if (resp == NULL) + return NULL; + + if (!data->anon_provisioning && data->phase2_success && + eap_fast_derive_msk(data) < 0) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to generate MSK"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + data->phase2_success = 0; + wpabuf_free(resp); + return NULL; + } + + if (!data->anon_provisioning && data->phase2_success) { + os_free(data->session_id); + data->session_id = eap_peer_tls_derive_session_id( + sm, &data->ssl, EAP_TYPE_FAST, &data->id_len); + if (data->session_id) { + wpa_hexdump(MSG_DEBUG, "EAP-FAST: Derived Session-Id", + data->session_id, data->id_len); + } else { + wpa_printf(MSG_ERROR, "EAP-FAST: Failed to derive " + "Session-Id"); + wpabuf_free(resp); + return NULL; + } + } + + pos = wpabuf_put(resp, sizeof(struct eap_tlv_crypto_binding_tlv)); + eap_fast_write_crypto_binding((struct eap_tlv_crypto_binding_tlv *) + pos, _bind, cmk); + + return resp; +} + + +static void eap_fast_parse_pac_tlv(struct eap_fast_pac *entry, int type, + u8 *pos, size_t len, int *pac_key_found) +{ + switch (type & 0x7fff) { + case PAC_TYPE_PAC_KEY: + wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key", pos, len); + if (len != EAP_FAST_PAC_KEY_LEN) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid PAC-Key " + "length %lu", (unsigned long) len); + break; + } + *pac_key_found = 1; + os_memcpy(entry->pac_key, pos, len); + break; + case PAC_TYPE_PAC_OPAQUE: + wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque", pos, len); + entry->pac_opaque = pos; + entry->pac_opaque_len = len; + break; + case PAC_TYPE_PAC_INFO: + wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info", pos, len); + entry->pac_info = pos; + entry->pac_info_len = len; + break; + default: + wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC type %d", + type); + break; + } +} + + +static int eap_fast_process_pac_tlv(struct eap_fast_pac *entry, + u8 *pac, size_t pac_len) +{ + struct pac_tlv_hdr *hdr; + u8 *pos; + size_t left, len; + int type, pac_key_found = 0; + + pos = pac; + left = pac_len; + + while (left > sizeof(*hdr)) { + hdr = (struct pac_tlv_hdr *) pos; + type = be_to_host16(hdr->type); + len = be_to_host16(hdr->len); + pos += sizeof(*hdr); + left -= sizeof(*hdr); + if (len > left) { + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV overrun " + "(type=%d len=%lu left=%lu)", + type, (unsigned long) len, + (unsigned long) left); + return -1; + } + + eap_fast_parse_pac_tlv(entry, type, pos, len, &pac_key_found); + + pos += len; + left -= len; + } + + if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) { + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV does not include " + "all the required fields"); + return -1; + } + + return 0; +} + + +static int eap_fast_parse_pac_info(struct eap_fast_pac *entry, int type, + u8 *pos, size_t len) +{ + u16 pac_type; + + switch (type & 0x7fff) { + case PAC_TYPE_CRED_LIFETIME: + if (len != 4) { + wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info - " + "Invalid CRED_LIFETIME length - ignored", + pos, len); + return 0; + } + break; + case PAC_TYPE_A_ID: + wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - A-ID", + pos, len); + entry->a_id = pos; + entry->a_id_len = len; + break; + case PAC_TYPE_I_ID: + wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - I-ID", + pos, len); + entry->i_id = pos; + entry->i_id_len = len; + break; + case PAC_TYPE_A_ID_INFO: + wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - A-ID-Info", + pos, len); + entry->a_id_info = pos; + entry->a_id_info_len = len; + break; + case PAC_TYPE_PAC_TYPE: + /* RFC 5422, Section 4.2.6 - PAC-Type TLV */ + if (len != 2) { + wpa_printf(MSG_INFO, "EAP-FAST: Invalid PAC-Type " + "length %lu (expected 2)", + (unsigned long) len); + wpa_hexdump_ascii(MSG_DEBUG, + "EAP-FAST: PAC-Info - PAC-Type", + pos, len); + return -1; + } + pac_type = WPA_GET_BE16(pos); + if (pac_type != PAC_TYPE_TUNNEL_PAC && + pac_type != PAC_TYPE_USER_AUTHORIZATION && + pac_type != PAC_TYPE_MACHINE_AUTHENTICATION) { + wpa_printf(MSG_INFO, "EAP-FAST: Unsupported PAC Type " + "%d", pac_type); + return -1; + } + + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info - PAC-Type %d", + pac_type); + entry->pac_type = pac_type; + break; + default: + wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC-Info " + "type %d", type); + break; + } + + return 0; +} + + +static int eap_fast_process_pac_info(struct eap_fast_pac *entry) +{ + struct pac_tlv_hdr *hdr; + u8 *pos; + size_t left, len; + int type; + + /* RFC 5422, Section 4.2.4 */ + + /* PAC-Type defaults to Tunnel PAC (Type 1) */ + entry->pac_type = PAC_TYPE_TUNNEL_PAC; + + pos = entry->pac_info; + left = entry->pac_info_len; + while (left > sizeof(*hdr)) { + hdr = (struct pac_tlv_hdr *) pos; + type = be_to_host16(hdr->type); + len = be_to_host16(hdr->len); + pos += sizeof(*hdr); + left -= sizeof(*hdr); + if (len > left) { + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info overrun " + "(type=%d len=%lu left=%lu)", + type, (unsigned long) len, + (unsigned long) left); + return -1; + } + + if (eap_fast_parse_pac_info(entry, type, pos, len) < 0) + return -1; + + pos += len; + left -= len; + } + + if (entry->a_id == NULL || entry->a_id_info == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info does not include " + "all the required fields"); + return -1; + } + + return 0; +} + + +static struct wpabuf * eap_fast_process_pac(struct eap_sm *sm, + struct eap_fast_data *data, + struct eap_method_ret *ret, + u8 *pac, size_t pac_len) +{ + struct eap_peer_config *config = eap_get_config(sm); + struct eap_fast_pac entry; + + os_memset(&entry, 0, sizeof(entry)); + if (eap_fast_process_pac_tlv(&entry, pac, pac_len) || + eap_fast_process_pac_info(&entry)) + return NULL; + + eap_fast_add_pac(&data->pac, &data->current_pac, &entry); + eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len); + if (data->use_pac_binary_format) + eap_fast_save_pac_bin(sm, data->pac, config->pac_file); + else + eap_fast_save_pac(sm, data->pac, config->pac_file); + + if (data->provisioning) { + if (data->anon_provisioning) { + /* + * Unauthenticated provisioning does not provide keying + * material and must end with an EAP-Failure. + * Authentication will be done separately after this. + */ + data->success = 0; + ret->decision = DECISION_FAIL; + } else { + /* + * Server may or may not allow authenticated + * provisioning also for key generation. + */ + ret->decision = DECISION_COND_SUCC; + } + wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV " + "- Provisioning completed successfully"); + sm->expected_failure = 1; + } else { + /* + * This is PAC refreshing, i.e., normal authentication that is + * expected to be completed with an EAP-Success. However, + * RFC 5422, Section 3.5 allows EAP-Failure to be sent even + * after protected success exchange in case of EAP-Fast + * provisioning, so we better use DECISION_COND_SUCC here + * instead of DECISION_UNCOND_SUCC. + */ + wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV " + "- PAC refreshing completed successfully"); + ret->decision = DECISION_COND_SUCC; + } + ret->methodState = METHOD_DONE; + return eap_fast_tlv_pac_ack(); +} + + +static int eap_fast_parse_decrypted(struct wpabuf *decrypted, + struct eap_fast_tlv_parse *tlv, + struct wpabuf **resp) +{ + int mandatory, tlv_type, res; + size_t len; + u8 *pos, *end; + + os_memset(tlv, 0, sizeof(*tlv)); + + /* Parse TLVs from the decrypted Phase 2 data */ + pos = wpabuf_mhead(decrypted); + end = pos + wpabuf_len(decrypted); + while (end - pos > 4) { + mandatory = pos[0] & 0x80; + tlv_type = WPA_GET_BE16(pos) & 0x3fff; + pos += 2; + len = WPA_GET_BE16(pos); + pos += 2; + if (len > (size_t) (end - pos)) { + wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow"); + return -1; + } + wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: " + "TLV type %d length %u%s", + tlv_type, (unsigned int) len, + mandatory ? " (mandatory)" : ""); + + res = eap_fast_parse_tlv(tlv, tlv_type, pos, len); + if (res == -2) + break; + if (res < 0) { + if (mandatory) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown " + "mandatory TLV type %d", tlv_type); + *resp = eap_fast_tlv_nak(0, tlv_type); + break; + } else { + wpa_printf(MSG_DEBUG, "EAP-FAST: ignored " + "unknown optional TLV type %d", + tlv_type); + } + } + + pos += len; + } + + return 0; +} + + +static int eap_fast_encrypt_response(struct eap_sm *sm, + struct eap_fast_data *data, + struct wpabuf *resp, + u8 identifier, struct wpabuf **out_data) +{ + if (resp == NULL) + return 0; + + wpa_hexdump_buf(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data", + resp); + if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST, + data->fast_version, identifier, + resp, out_data)) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 " + "frame"); + } + wpabuf_free(resp); + + return 0; +} + + +static struct wpabuf * eap_fast_pac_request(void) +{ + struct wpabuf *tmp; + u8 *pos, *pos2; + + tmp = wpabuf_alloc(sizeof(struct eap_tlv_hdr) + + sizeof(struct eap_tlv_request_action_tlv) + + sizeof(struct eap_tlv_pac_type_tlv)); + if (tmp == NULL) + return NULL; + + pos = wpabuf_put(tmp, 0); + pos2 = eap_fast_write_pac_request(pos, PAC_TYPE_TUNNEL_PAC); + wpabuf_put(tmp, pos2 - pos); + return tmp; +} + + +static int eap_fast_process_decrypted(struct eap_sm *sm, + struct eap_fast_data *data, + struct eap_method_ret *ret, + u8 identifier, + struct wpabuf *decrypted, + struct wpabuf **out_data) +{ + struct wpabuf *resp = NULL, *tmp; + struct eap_fast_tlv_parse tlv; + int failed = 0; + + if (eap_fast_parse_decrypted(decrypted, &tlv, &resp) < 0) + return 0; + if (resp) + return eap_fast_encrypt_response(sm, data, resp, + identifier, out_data); + + if (tlv.result == EAP_TLV_RESULT_FAILURE) { + resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0); + return eap_fast_encrypt_response(sm, data, resp, + identifier, out_data); + } + + if (tlv.iresult == EAP_TLV_RESULT_FAILURE) { + resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1); + return eap_fast_encrypt_response(sm, data, resp, + identifier, out_data); + } + + if (tlv.crypto_binding) { + tmp = eap_fast_process_crypto_binding(sm, data, ret, + tlv.crypto_binding, + tlv.crypto_binding_len); + if (tmp == NULL) + failed = 1; + else + resp = wpabuf_concat(resp, tmp); + } + + if (tlv.iresult == EAP_TLV_RESULT_SUCCESS) { + tmp = eap_fast_tlv_result(failed ? EAP_TLV_RESULT_FAILURE : + EAP_TLV_RESULT_SUCCESS, 1); + resp = wpabuf_concat(resp, tmp); + } + + if (tlv.eap_payload_tlv) { + tmp = eap_fast_process_eap_payload_tlv( + sm, data, ret, tlv.eap_payload_tlv, + tlv.eap_payload_tlv_len); + resp = wpabuf_concat(resp, tmp); + } + + if (tlv.pac && tlv.result != EAP_TLV_RESULT_SUCCESS) { + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV " + "acknowledging success"); + failed = 1; + } else if (tlv.pac && tlv.result == EAP_TLV_RESULT_SUCCESS) { + tmp = eap_fast_process_pac(sm, data, ret, tlv.pac, + tlv.pac_len); + resp = wpabuf_concat(resp, tmp); + } + + if (data->current_pac == NULL && data->provisioning && + !data->anon_provisioning && !tlv.pac && + (tlv.iresult == EAP_TLV_RESULT_SUCCESS || + tlv.result == EAP_TLV_RESULT_SUCCESS)) { + /* + * Need to request Tunnel PAC when using authenticated + * provisioning. + */ + wpa_printf(MSG_DEBUG, "EAP-FAST: Request Tunnel PAC"); + tmp = eap_fast_pac_request(); + resp = wpabuf_concat(resp, tmp); + } + + if (tlv.result == EAP_TLV_RESULT_SUCCESS && !failed) { + tmp = eap_fast_tlv_result(EAP_TLV_RESULT_SUCCESS, 0); + resp = wpabuf_concat(tmp, resp); + } else if (failed) { + tmp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0); + resp = wpabuf_concat(tmp, resp); + } + + if (resp && tlv.result == EAP_TLV_RESULT_SUCCESS && !failed && + tlv.crypto_binding && data->phase2_success) { + if (data->anon_provisioning) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Unauthenticated " + "provisioning completed successfully."); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + sm->expected_failure = 1; + } else { + wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication " + "completed successfully."); + if (data->provisioning) + ret->methodState = METHOD_MAY_CONT; + else + ret->methodState = METHOD_DONE; + ret->decision = DECISION_UNCOND_SUCC; + } + } + + if (resp == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send " + "empty response packet"); + resp = wpabuf_alloc(1); + } + + return eap_fast_encrypt_response(sm, data, resp, identifier, + out_data); +} + + +static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data, + struct eap_method_ret *ret, u8 identifier, + const struct wpabuf *in_data, + struct wpabuf **out_data) +{ + struct wpabuf *in_decrypted; + int res; + + wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for" + " Phase 2", (unsigned long) wpabuf_len(in_data)); + + if (data->pending_phase2_req) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Pending Phase 2 request - " + "skip decryption and use old data"); + /* Clear TLS reassembly state. */ + eap_peer_tls_reset_input(&data->ssl); + + in_decrypted = data->pending_phase2_req; + data->pending_phase2_req = NULL; + goto continue_req; + } + + if (wpabuf_len(in_data) == 0) { + /* Received TLS ACK - requesting more fragments */ + return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST, + data->fast_version, + identifier, NULL, out_data); + } + + res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted); + if (res) + return res; + +continue_req: + wpa_hexdump_buf(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)", + in_decrypted); + + if (wpabuf_len(in_decrypted) < 4) { + wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 " + "TLV frame (len=%lu)", + (unsigned long) wpabuf_len(in_decrypted)); + wpabuf_free(in_decrypted); + return -1; + } + + res = eap_fast_process_decrypted(sm, data, ret, identifier, + in_decrypted, out_data); + + wpabuf_free(in_decrypted); + + return res; +} + + +static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len) +{ + const u8 *a_id; + const struct pac_tlv_hdr *hdr; + + /* + * Parse authority identity (A-ID) from the EAP-FAST/Start. This + * supports both raw A-ID and one inside an A-ID TLV. + */ + a_id = buf; + *id_len = len; + if (len > sizeof(*hdr)) { + int tlen; + hdr = (const struct pac_tlv_hdr *) buf; + tlen = be_to_host16(hdr->len); + if (be_to_host16(hdr->type) == PAC_TYPE_A_ID && + sizeof(*hdr) + tlen <= len) { + wpa_printf(MSG_DEBUG, "EAP-FAST: A-ID was in TLV " + "(Start)"); + a_id = (const u8 *) (hdr + 1); + *id_len = tlen; + } + } + wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, *id_len); + + return a_id; +} + + +static void eap_fast_select_pac(struct eap_fast_data *data, + const u8 *a_id, size_t a_id_len) +{ + data->current_pac = eap_fast_get_pac(data->pac, a_id, a_id_len, + PAC_TYPE_TUNNEL_PAC); + if (data->current_pac == NULL) { + /* + * Tunnel PAC was not available for this A-ID. Try to use + * Machine Authentication PAC, if one is available. + */ + data->current_pac = eap_fast_get_pac( + data->pac, a_id, a_id_len, + PAC_TYPE_MACHINE_AUTHENTICATION); + } + + if (data->current_pac) { + wpa_printf(MSG_DEBUG, "EAP-FAST: PAC found for this A-ID " + "(PAC-Type %d)", data->current_pac->pac_type); + wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-FAST: A-ID-Info", + data->current_pac->a_id_info, + data->current_pac->a_id_info_len); + } +} + + +static int eap_fast_use_pac_opaque(struct eap_sm *sm, + struct eap_fast_data *data, + struct eap_fast_pac *pac) +{ + u8 *tlv; + size_t tlv_len, olen; + struct eap_tlv_hdr *ehdr; + + olen = pac->pac_opaque_len; + tlv_len = sizeof(*ehdr) + olen; + tlv = os_malloc(tlv_len); + if (tlv) { + ehdr = (struct eap_tlv_hdr *) tlv; + ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE); + ehdr->length = host_to_be16(olen); + os_memcpy(ehdr + 1, pac->pac_opaque, olen); + } + if (tlv == NULL || + tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn, + TLS_EXT_PAC_OPAQUE, + tlv, tlv_len) < 0) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to add PAC-Opaque TLS " + "extension"); + os_free(tlv); + return -1; + } + os_free(tlv); + + return 0; +} + + +static int eap_fast_clear_pac_opaque_ext(struct eap_sm *sm, + struct eap_fast_data *data) +{ + if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn, + TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to remove PAC-Opaque " + "TLS extension"); + return -1; + } + return 0; +} + + +static int eap_fast_set_provisioning_ciphers(struct eap_sm *sm, + struct eap_fast_data *data) +{ + u8 ciphers[7]; + int count = 0; + + if (data->provisioning_allowed & EAP_FAST_PROV_UNAUTH) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Enabling unauthenticated " + "provisioning TLS cipher suites"); + ciphers[count++] = TLS_CIPHER_ANON_DH_AES128_SHA; + } + + if (data->provisioning_allowed & EAP_FAST_PROV_AUTH) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Enabling authenticated " + "provisioning TLS cipher suites"); + ciphers[count++] = TLS_CIPHER_RSA_DHE_AES256_SHA; + ciphers[count++] = TLS_CIPHER_RSA_DHE_AES128_SHA; + ciphers[count++] = TLS_CIPHER_AES256_SHA; + ciphers[count++] = TLS_CIPHER_AES128_SHA; + ciphers[count++] = TLS_CIPHER_RC4_SHA; + } + + ciphers[count++] = TLS_CIPHER_NONE; + + if (tls_connection_set_cipher_list(sm->ssl_ctx, data->ssl.conn, + ciphers)) { + wpa_printf(MSG_INFO, "EAP-FAST: Could not configure TLS " + "cipher suites for provisioning"); + return -1; + } + + return 0; +} + + +static int eap_fast_process_start(struct eap_sm *sm, + struct eap_fast_data *data, u8 flags, + const u8 *pos, size_t left) +{ + const u8 *a_id; + size_t a_id_len; + + /* EAP-FAST Version negotiation (section 3.1) */ + wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own ver=%d)", + flags & EAP_TLS_VERSION_MASK, data->fast_version); + if ((flags & EAP_TLS_VERSION_MASK) < data->fast_version) + data->fast_version = flags & EAP_TLS_VERSION_MASK; + wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d", + data->fast_version); + + a_id = eap_fast_get_a_id(pos, left, &a_id_len); + eap_fast_select_pac(data, a_id, a_id_len); + + if (data->resuming && data->current_pac) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Trying to resume session - " + "do not add PAC-Opaque to TLS ClientHello"); + if (eap_fast_clear_pac_opaque_ext(sm, data) < 0) + return -1; + } else if (data->current_pac) { + /* + * PAC found for the A-ID and we are not resuming an old + * session, so add PAC-Opaque extension to ClientHello. + */ + if (eap_fast_use_pac_opaque(sm, data, data->current_pac) < 0) + return -1; + } else { + /* No PAC found, so we must provision one. */ + if (!data->provisioning_allowed) { + wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found and " + "provisioning disabled"); + return -1; + } + wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - " + "starting provisioning"); + if (eap_fast_set_provisioning_ciphers(sm, data) < 0 || + eap_fast_clear_pac_opaque_ext(sm, data) < 0) + return -1; + data->provisioning = 1; + } + + return 0; +} + + +static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, + struct eap_method_ret *ret, + const struct wpabuf *reqData) +{ + const struct eap_hdr *req; + size_t left; + int res; + u8 flags, id; + struct wpabuf *resp; + const u8 *pos; + struct eap_fast_data *data = priv; + struct wpabuf msg; + + pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret, + reqData, &left, &flags); + if (pos == NULL) + return NULL; + + req = wpabuf_head(reqData); + id = req->identifier; + + if (flags & EAP_TLS_FLAGS_START) { + if (eap_fast_process_start(sm, data, flags, pos, left) < 0) + return NULL; + + left = 0; /* A-ID is not used in further packet processing */ + } + + wpabuf_set(&msg, pos, left); + + resp = NULL; + if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && + !data->resuming) { + /* Process tunneled (encrypted) phase 2 data. */ + res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp); + if (res < 0) { + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + /* + * Ack possible Alert that may have caused failure in + * decryption. + */ + res = 1; + } + } else { + if (sm->waiting_ext_cert_check && data->pending_resp) { + struct eap_peer_config *config = eap_get_config(sm); + + if (config->pending_ext_cert_check == + EXT_CERT_CHECK_GOOD) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: External certificate check succeeded - continue handshake"); + resp = data->pending_resp; + data->pending_resp = NULL; + sm->waiting_ext_cert_check = 0; + return resp; + } + + if (config->pending_ext_cert_check == + EXT_CERT_CHECK_BAD) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: External certificate check failed - force authentication failure"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + sm->waiting_ext_cert_check = 0; + return NULL; + } + + wpa_printf(MSG_DEBUG, + "EAP-FAST: Continuing to wait external server certificate validation"); + return NULL; + } + + /* Continue processing TLS handshake (phase 1). */ + res = eap_peer_tls_process_helper(sm, &data->ssl, + EAP_TYPE_FAST, + data->fast_version, id, pos, + left, &resp); + if (res < 0) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: TLS processing failed"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + return resp; + } + + if (sm->waiting_ext_cert_check) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: Waiting external server certificate validation"); + wpabuf_free(data->pending_resp); + data->pending_resp = resp; + return NULL; + } + + if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { + char cipher[80]; + wpa_printf(MSG_DEBUG, + "EAP-FAST: TLS done, proceed to Phase 2"); + if (data->provisioning && + (!(data->provisioning_allowed & + EAP_FAST_PROV_AUTH) || + tls_get_cipher(sm->ssl_ctx, data->ssl.conn, + cipher, sizeof(cipher)) < 0 || + os_strstr(cipher, "ADH-") || + os_strstr(cipher, "anon"))) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Using " + "anonymous (unauthenticated) " + "provisioning"); + data->anon_provisioning = 1; + } else { + data->anon_provisioning = 0; + } + data->resuming = 0; + if (eap_fast_derive_keys(sm, data) < 0) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: Could not derive keys"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + wpabuf_free(resp); + return NULL; + } + } + + if (res == 2) { + /* + * Application data included in the handshake message. + */ + wpabuf_free(data->pending_phase2_req); + data->pending_phase2_req = resp; + resp = NULL; + res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp); + } + } + + if (res == 1) { + wpabuf_free(resp); + return eap_peer_tls_build_ack(id, EAP_TYPE_FAST, + data->fast_version); + } + + return resp; +} + + +#if 0 /* FIX */ +static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv) +{ + struct eap_fast_data *data = priv; + return tls_connection_established(sm->ssl_ctx, data->ssl.conn); +} + + +static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv) +{ + struct eap_fast_data *data = priv; + + if (data->phase2_priv && data->phase2_method && + data->phase2_method->deinit_for_reauth) + data->phase2_method->deinit_for_reauth(sm, data->phase2_priv); + os_free(data->key_block_p); + data->key_block_p = NULL; + wpabuf_free(data->pending_phase2_req); + data->pending_phase2_req = NULL; + wpabuf_free(data->pending_resp); + data->pending_resp = NULL; +} + + +static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv) +{ + struct eap_fast_data *data = priv; + if (eap_peer_tls_reauth_init(sm, &data->ssl)) { + os_free(data); + return NULL; + } + os_memset(data->key_data, 0, EAP_FAST_KEY_LEN); + os_memset(data->emsk, 0, EAP_EMSK_LEN); + os_free(data->session_id); + data->session_id = NULL; + if (data->phase2_priv && data->phase2_method && + data->phase2_method->init_for_reauth) + data->phase2_method->init_for_reauth(sm, data->phase2_priv); + data->phase2_success = 0; + data->resuming = 1; + data->provisioning = 0; + data->anon_provisioning = 0; + data->simck_idx = 0; + return priv; +} +#endif + + +static int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf, + size_t buflen, int verbose) +{ + struct eap_fast_data *data = priv; + int len, ret; + + len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose); + if (data->phase2_method) { + ret = os_snprintf(buf + len, buflen - len, + "EAP-FAST Phase2 method=%s\n", + data->phase2_method->name); + if (os_snprintf_error(buflen - len, ret)) + return len; + len += ret; + } + return len; +} + + +static bool eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv) +{ + struct eap_fast_data *data = priv; + return data->success; +} + + +static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len) +{ + struct eap_fast_data *data = priv; + u8 *key; + + if (!data->success) + return NULL; + + key = os_memdup(data->key_data, EAP_FAST_KEY_LEN); + if (key == NULL) + return NULL; + + *len = EAP_FAST_KEY_LEN; + + return key; +} + + +static u8 * eap_fast_get_session_id(struct eap_sm *sm, void *priv, size_t *len) +{ + struct eap_fast_data *data = priv; + u8 *id; + + if (!data->success || !data->session_id) + return NULL; + + id = os_memdup(data->session_id, data->id_len); + if (id == NULL) + return NULL; + + *len = data->id_len; + + return id; +} + + +static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len) +{ + struct eap_fast_data *data = priv; + u8 *key; + + if (!data->success) + return NULL; + + key = os_memdup(data->emsk, EAP_EMSK_LEN); + if (key == NULL) + return NULL; + + *len = EAP_EMSK_LEN; + + return key; +} + + +int eap_peer_fast_register(void) +{ + struct eap_method *eap; + + eap = eap_peer_method_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST"); + if (eap == NULL) + return -1; + + eap->init = eap_fast_init; + eap->deinit = eap_fast_deinit; + eap->process = eap_fast_process; + eap->isKeyAvailable = eap_fast_isKeyAvailable; + eap->getKey = eap_fast_getKey; + eap->getSessionId = eap_fast_get_session_id; + eap->get_status = eap_fast_get_status; +#if 0 + eap->has_reauth_data = eap_fast_has_reauth_data; + eap->deinit_for_reauth = eap_fast_deinit_for_reauth; + eap->init_for_reauth = eap_fast_init_for_reauth; +#endif + eap->get_emsk = eap_fast_get_emsk; + + return eap_peer_method_register(eap); +} diff --git a/components/wpa_supplicant/src/eap_peer/eap_fast_common.c b/components/wpa_supplicant/src/eap_peer/eap_fast_common.c new file mode 100644 index 000000000000..97024725312a --- /dev/null +++ b/components/wpa_supplicant/src/eap_peer/eap_fast_common.c @@ -0,0 +1,270 @@ +/* + * EAP-FAST common helper functions (RFC 4851) + * Copyright (c) 2008, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "crypto/sha1.h" +#include "tls/tls.h" +#include "eap_peer/eap_defs.h" +#include "eap_peer/eap_tlv_common.h" +#include "eap_peer/eap_fast_common.h" + + +void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len) +{ + struct pac_tlv_hdr hdr; + hdr.type = host_to_be16(type); + hdr.len = host_to_be16(len); + wpabuf_put_data(buf, &hdr, sizeof(hdr)); +} + + +void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data, + u16 len) +{ + eap_fast_put_tlv_hdr(buf, type, len); + wpabuf_put_data(buf, data, len); +} + + +void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, + const struct wpabuf *data) +{ + eap_fast_put_tlv_hdr(buf, type, wpabuf_len(data)); + wpabuf_put_buf(buf, data); +} + + +struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) +{ + struct wpabuf *e; + + if (buf == NULL) + return NULL; + + /* Encapsulate EAP packet in EAP-Payload TLV */ + wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV"); + e = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); + if (e == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " + "for TLV encapsulation"); + wpabuf_free(buf); + return NULL; + } + eap_fast_put_tlv_buf(e, + EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, + buf); + wpabuf_free(buf); + return e; +} + + +void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random, + const u8 *client_random, u8 *master_secret) +{ +#define TLS_RANDOM_LEN 32 +#define TLS_MASTER_SECRET_LEN 48 + u8 seed[2 * TLS_RANDOM_LEN]; + + wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random", + client_random, TLS_RANDOM_LEN); + wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random", + server_random, TLS_RANDOM_LEN); + + /* + * RFC 4851, Section 5.1: + * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash", + * server_random + client_random, 48) + */ + os_memcpy(seed, server_random, TLS_RANDOM_LEN); + os_memcpy(seed + TLS_RANDOM_LEN, client_random, TLS_RANDOM_LEN); + sha1_t_prf(pac_key, EAP_FAST_PAC_KEY_LEN, + "PAC to master secret label hash", + seed, sizeof(seed), master_secret, TLS_MASTER_SECRET_LEN); + + wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: master_secret", + master_secret, TLS_MASTER_SECRET_LEN); +} + + +u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, size_t len) +{ + u8 *out; + + out = os_malloc(len); + if (out == NULL) + return NULL; + + if (tls_connection_get_eap_fast_key(ssl_ctx, conn, out, len)) { + os_free(out); + return NULL; + } + + return out; +} + + +int eap_fast_derive_eap_msk(const u8 *simck, u8 *msk) +{ + /* + * RFC 4851, Section 5.4: EAP Master Session Key Generation + * MSK = T-PRF(S-IMCK[j], "Session Key Generating Function", 64) + */ + + if (sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, + "Session Key Generating Function", (u8 *) "", 0, + msk, EAP_FAST_KEY_LEN) < 0) + return -1; + wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)", + msk, EAP_FAST_KEY_LEN); + return 0; +} + + +int eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) +{ + /* + * RFC 4851, Section 5.4: EAP Master Session Key Genreration + * EMSK = T-PRF(S-IMCK[j], + * "Extended Session Key Generating Function", 64) + */ + + if (sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, + "Extended Session Key Generating Function", (u8 *) "", 0, + emsk, EAP_EMSK_LEN) < 0) + return -1; + wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)", + emsk, EAP_EMSK_LEN); + return 0; +} + + +int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, + int tlv_type, u8 *pos, size_t len) +{ + switch (tlv_type) { + case EAP_TLV_EAP_PAYLOAD_TLV: + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP-Payload TLV", + pos, len); + if (tlv->eap_payload_tlv) { + wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " + "EAP-Payload TLV in the message"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + return -2; + } + tlv->eap_payload_tlv = pos; + tlv->eap_payload_tlv_len = len; + break; + case EAP_TLV_RESULT_TLV: + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV", pos, len); + if (tlv->result) { + wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " + "Result TLV in the message"); + tlv->result = EAP_TLV_RESULT_FAILURE; + return -2; + } + if (len < 2) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " + "Result TLV"); + tlv->result = EAP_TLV_RESULT_FAILURE; + break; + } + tlv->result = WPA_GET_BE16(pos); + if (tlv->result != EAP_TLV_RESULT_SUCCESS && + tlv->result != EAP_TLV_RESULT_FAILURE) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Result %d", + tlv->result); + tlv->result = EAP_TLV_RESULT_FAILURE; + } + wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s", + tlv->result == EAP_TLV_RESULT_SUCCESS ? + "Success" : "Failure"); + break; + case EAP_TLV_INTERMEDIATE_RESULT_TLV: + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate Result TLV", + pos, len); + if (len < 2) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " + "Intermediate-Result TLV"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + break; + } + if (tlv->iresult) { + wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " + "Intermediate-Result TLV in the message"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + return -2; + } + tlv->iresult = WPA_GET_BE16(pos); + if (tlv->iresult != EAP_TLV_RESULT_SUCCESS && + tlv->iresult != EAP_TLV_RESULT_FAILURE) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Intermediate " + "Result %d", tlv->iresult); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + } + wpa_printf(MSG_DEBUG, "EAP-FAST: Intermediate Result: %s", + tlv->iresult == EAP_TLV_RESULT_SUCCESS ? + "Success" : "Failure"); + break; + case EAP_TLV_CRYPTO_BINDING_TLV: + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV", + pos, len); + if (tlv->crypto_binding) { + wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " + "Crypto-Binding TLV in the message"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + return -2; + } + tlv->crypto_binding_len = sizeof(struct eap_tlv_hdr) + len; + if (tlv->crypto_binding_len < sizeof(*tlv->crypto_binding)) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " + "Crypto-Binding TLV"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + return -2; + } + tlv->crypto_binding = (struct eap_tlv_crypto_binding_tlv *) + (pos - sizeof(struct eap_tlv_hdr)); + break; + case EAP_TLV_REQUEST_ACTION_TLV: + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Request-Action TLV", + pos, len); + if (tlv->request_action) { + wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " + "Request-Action TLV in the message"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + return -2; + } + if (len < 2) { + wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " + "Request-Action TLV"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + break; + } + tlv->request_action = WPA_GET_BE16(pos); + wpa_printf(MSG_DEBUG, "EAP-FAST: Request-Action: %d", + tlv->request_action); + break; + case EAP_TLV_PAC_TLV: + wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV", pos, len); + if (tlv->pac) { + wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " + "PAC TLV in the message"); + tlv->iresult = EAP_TLV_RESULT_FAILURE; + return -2; + } + tlv->pac = pos; + tlv->pac_len = len; + break; + default: + /* Unknown TLV */ + return -1; + } + + return 0; +} diff --git a/components/wpa_supplicant/src/eap_peer/eap_fast_common.h b/components/wpa_supplicant/src/eap_peer/eap_fast_common.h new file mode 100644 index 000000000000..724204cb5e32 --- /dev/null +++ b/components/wpa_supplicant/src/eap_peer/eap_fast_common.h @@ -0,0 +1,107 @@ +/* + * EAP-FAST definitions (RFC 4851) + * Copyright (c) 2004-2008, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_FAST_H +#define EAP_FAST_H + +#define EAP_FAST_VERSION 1 +#define EAP_FAST_KEY_LEN 64 +#define EAP_FAST_SIMCK_LEN 40 +#define EAP_FAST_SKS_LEN 40 +#define EAP_FAST_CMK_LEN 20 + +#define TLS_EXT_PAC_OPAQUE 35 + +/* + * RFC 5422: Section 4.2.1 - Formats for PAC TLV Attributes / Type Field + * Note: bit 0x8000 (Mandatory) and bit 0x4000 (Reserved) are also defined + * in the general PAC TLV format (Section 4.2). + */ +#define PAC_TYPE_PAC_KEY 1 +#define PAC_TYPE_PAC_OPAQUE 2 +#define PAC_TYPE_CRED_LIFETIME 3 +#define PAC_TYPE_A_ID 4 +#define PAC_TYPE_I_ID 5 +/* + * 6 was previous assigned for SERVER_PROTECTED_DATA, but + * draft-cam-winget-eap-fast-provisioning-02.txt changed this to Reserved. + */ +#define PAC_TYPE_A_ID_INFO 7 +#define PAC_TYPE_PAC_ACKNOWLEDGEMENT 8 +#define PAC_TYPE_PAC_INFO 9 +#define PAC_TYPE_PAC_TYPE 10 + +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +struct pac_tlv_hdr { + be16 type; + be16 len; +} STRUCT_PACKED; + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + + +#define EAP_FAST_PAC_KEY_LEN 32 + +/* RFC 5422: 4.2.6 PAC-Type TLV */ +#define PAC_TYPE_TUNNEL_PAC 1 +/* Application Specific Short Lived PACs (only in volatile storage) */ +/* User Authorization PAC */ +#define PAC_TYPE_USER_AUTHORIZATION 3 +/* Application Specific Long Lived PACs */ +/* Machine Authentication PAC */ +#define PAC_TYPE_MACHINE_AUTHENTICATION 2 + + +/* + * RFC 5422: + * Section 3.3 - Key Derivations Used in the EAP-FAST Provisioning Exchange + */ +struct eap_fast_key_block_provisioning { + /* Extra key material after TLS key_block */ + u8 session_key_seed[EAP_FAST_SKS_LEN]; + u8 server_challenge[16]; /* MSCHAPv2 ServerChallenge */ + u8 client_challenge[16]; /* MSCHAPv2 ClientChallenge */ +}; + + +struct wpabuf; +struct tls_connection; + +struct eap_fast_tlv_parse { + u8 *eap_payload_tlv; + size_t eap_payload_tlv_len; + struct eap_tlv_crypto_binding_tlv *crypto_binding; + size_t crypto_binding_len; + int iresult; + int result; + int request_action; + u8 *pac; + size_t pac_len; +}; + +void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len); +void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data, + u16 len); +void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, + const struct wpabuf *data); +struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf); +void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random, + const u8 *client_random, u8 *master_secret); +u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, + size_t len); +int eap_fast_derive_eap_msk(const u8 *simck, u8 *msk); +int eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk); +int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, + int tlv_type, u8 *pos, size_t len); + +#endif /* EAP_FAST_H */ diff --git a/components/wpa_supplicant/src/eap_peer/eap_fast_pac.c b/components/wpa_supplicant/src/eap_peer/eap_fast_pac.c new file mode 100644 index 000000000000..4f92f4ad3d88 --- /dev/null +++ b/components/wpa_supplicant/src/eap_peer/eap_fast_pac.c @@ -0,0 +1,932 @@ +/* + * EAP peer method: EAP-FAST PAC file processing + * Copyright (c) 2004-2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" +#include "os.h" + +#include "utils/common.h" +#include "eap_peer/eap_config.h" +#include "eap_peer/eap_i.h" +#include "eap_peer/eap_fast_pac.h" + +/* TODO: encrypt PAC-Key in the PAC file */ + + +/* Text data format */ +static const char *pac_file_hdr = + "wpa_supplicant EAP-FAST PAC file - version 1"; + +/* + * Binary data format + * 4-octet magic value: 6A E4 92 0C + * 2-octet version (big endian) + * + * + * version=0: + * Sequence of PAC entries: + * 2-octet PAC-Type (big endian) + * 32-octet PAC-Key + * 2-octet PAC-Opaque length (big endian) + * PAC-Opaque data (length bytes) + * 2-octet PAC-Info length (big endian) + * PAC-Info data (length bytes) + */ + +#define EAP_FAST_PAC_BINARY_MAGIC 0x6ae4920c +#define EAP_FAST_PAC_BINARY_FORMAT_VERSION 0 + + +/** + * eap_fast_free_pac - Free PAC data + * @pac: Pointer to the PAC entry + * + * Note that the PAC entry must not be in a list since this function does not + * remove the list links. + */ +void eap_fast_free_pac(struct eap_fast_pac *pac) +{ + os_free(pac->pac_opaque); + os_free(pac->pac_info); + os_free(pac->a_id); + os_free(pac->i_id); + os_free(pac->a_id_info); + os_free(pac); +} + + +/** + * eap_fast_get_pac - Get a PAC entry based on A-ID + * @pac_root: Pointer to root of the PAC list + * @a_id: A-ID to search for + * @a_id_len: Length of A-ID + * @pac_type: PAC-Type to search for + * Returns: Pointer to the PAC entry, or %NULL if A-ID not found + */ +struct eap_fast_pac * eap_fast_get_pac(struct eap_fast_pac *pac_root, + const u8 *a_id, size_t a_id_len, + u16 pac_type) +{ + struct eap_fast_pac *pac = pac_root; + + while (pac) { + if (pac->pac_type == pac_type && pac->a_id_len == a_id_len && + os_memcmp(pac->a_id, a_id, a_id_len) == 0) { + return pac; + } + pac = pac->next; + } + return NULL; +} + + +static void eap_fast_remove_pac(struct eap_fast_pac **pac_root, + struct eap_fast_pac **pac_current, + const u8 *a_id, size_t a_id_len, u16 pac_type) +{ + struct eap_fast_pac *pac, *prev; + + pac = *pac_root; + prev = NULL; + + while (pac) { + if (pac->pac_type == pac_type && pac->a_id_len == a_id_len && + os_memcmp(pac->a_id, a_id, a_id_len) == 0) { + if (prev == NULL) + *pac_root = pac->next; + else + prev->next = pac->next; + if (*pac_current == pac) + *pac_current = NULL; + eap_fast_free_pac(pac); + break; + } + prev = pac; + pac = pac->next; + } +} + + +static int eap_fast_copy_buf(u8 **dst, size_t *dst_len, + const u8 *src, size_t src_len) +{ + if (src) { + *dst = os_memdup(src, src_len); + if (*dst == NULL) + return -1; + *dst_len = src_len; + } + return 0; +} + + +/** + * eap_fast_add_pac - Add a copy of a PAC entry to a list + * @pac_root: Pointer to PAC list root pointer + * @pac_current: Pointer to the current PAC pointer + * @entry: New entry to clone and add to the list + * Returns: 0 on success, -1 on failure + * + * This function makes a clone of the given PAC entry and adds this copied + * entry to the list (pac_root). If an old entry for the same A-ID is found, + * it will be removed from the PAC list and in this case, pac_current entry + * is set to %NULL if it was the removed entry. + */ +int eap_fast_add_pac(struct eap_fast_pac **pac_root, + struct eap_fast_pac **pac_current, + struct eap_fast_pac *entry) +{ + struct eap_fast_pac *pac; + + if (entry == NULL || entry->a_id == NULL) + return -1; + + /* Remove a possible old entry for the matching A-ID. */ + eap_fast_remove_pac(pac_root, pac_current, + entry->a_id, entry->a_id_len, entry->pac_type); + + /* Allocate a new entry and add it to the list of PACs. */ + pac = os_zalloc(sizeof(*pac)); + if (pac == NULL) + return -1; + + pac->pac_type = entry->pac_type; + os_memcpy(pac->pac_key, entry->pac_key, EAP_FAST_PAC_KEY_LEN); + if (eap_fast_copy_buf(&pac->pac_opaque, &pac->pac_opaque_len, + entry->pac_opaque, entry->pac_opaque_len) < 0 || + eap_fast_copy_buf(&pac->pac_info, &pac->pac_info_len, + entry->pac_info, entry->pac_info_len) < 0 || + eap_fast_copy_buf(&pac->a_id, &pac->a_id_len, + entry->a_id, entry->a_id_len) < 0 || + eap_fast_copy_buf(&pac->i_id, &pac->i_id_len, + entry->i_id, entry->i_id_len) < 0 || + eap_fast_copy_buf(&pac->a_id_info, &pac->a_id_info_len, + entry->a_id_info, entry->a_id_info_len) < 0) { + eap_fast_free_pac(pac); + return -1; + } + + pac->next = *pac_root; + *pac_root = pac; + + return 0; +} + + +struct eap_fast_read_ctx { + FILE *f; + const char *pos; + const char *end; + int line; + char *buf; + size_t buf_len; +}; + +static int eap_fast_read_line(struct eap_fast_read_ctx *rc, char **value) +{ + char *pos; + + rc->line++; + if (rc->f) { + if (fgets(rc->buf, rc->buf_len, rc->f) == NULL) + return -1; + } else { + const char *l_end; + size_t len; + if (rc->pos >= rc->end) + return -1; + l_end = rc->pos; + while (l_end < rc->end && *l_end != '\n') + l_end++; + len = l_end - rc->pos; + if (len >= rc->buf_len) + len = rc->buf_len - 1; + os_memcpy(rc->buf, rc->pos, len); + rc->buf[len] = '\0'; + rc->pos = l_end + 1; + } + + rc->buf[rc->buf_len - 1] = '\0'; + pos = rc->buf; + while (*pos != '\0') { + if (*pos == '\n' || *pos == '\r') { + *pos = '\0'; + break; + } + pos++; + } + + pos = os_strchr(rc->buf, '='); + if (pos) + *pos++ = '\0'; + *value = pos; + + return 0; +} + + +static u8 * eap_fast_parse_hex(const char *value, size_t *len) +{ + int hlen; + u8 *buf; + + if (value == NULL) + return NULL; + hlen = os_strlen(value); + if (hlen & 1) + return NULL; + *len = hlen / 2; + buf = os_malloc(*len); + if (buf == NULL) + return NULL; + if (hexstr2bin(value, buf, *len)) { + os_free(buf); + return NULL; + } + return buf; +} + + +static int eap_fast_init_pac_data(struct eap_sm *sm, const char *pac_file, + struct eap_fast_read_ctx *rc) +{ + os_memset(rc, 0, sizeof(*rc)); + + rc->buf_len = 2048; + rc->buf = os_malloc(rc->buf_len); + if (rc->buf == NULL) + return -1; + + if (os_strncmp(pac_file, "blob://", 7) == 0) { + const struct wpa_config_blob *blob; + blob = eap_get_config_blob(sm, pac_file); + if (blob == NULL) { + wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - " + "assume no PAC entries have been " + "provisioned", pac_file); + os_free(rc->buf); + return -1; + } + rc->pos = (char *) blob->data; + rc->end = (char *) blob->data + blob->len; + } else { + rc->f = fopen(pac_file, "rb"); + if (rc->f == NULL) { + wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - " + "assume no PAC entries have been " + "provisioned", pac_file); + os_free(rc->buf); + return -1; + } + } + + return 0; +} + + +static void eap_fast_deinit_pac_data(struct eap_fast_read_ctx *rc) +{ + os_free(rc->buf); + if (rc->f) + fclose(rc->f); +} + + +static const char * eap_fast_parse_start(struct eap_fast_pac **pac) +{ + if (*pac) + return "START line without END"; + + *pac = os_zalloc(sizeof(struct eap_fast_pac)); + if (*pac == NULL) + return "No memory for PAC entry"; + (*pac)->pac_type = PAC_TYPE_TUNNEL_PAC; + return NULL; +} + + +static const char * eap_fast_parse_end(struct eap_fast_pac **pac_root, + struct eap_fast_pac **pac) +{ + if (*pac == NULL) + return "END line without START"; + if (*pac_root) { + struct eap_fast_pac *end = *pac_root; + while (end->next) + end = end->next; + end->next = *pac; + } else + *pac_root = *pac; + + *pac = NULL; + return NULL; +} + + +static const char * eap_fast_parse_pac_type(struct eap_fast_pac *pac, + char *pos) +{ + if (!pos) + return "Cannot parse pac type"; + pac->pac_type = atoi(pos); + if (pac->pac_type != PAC_TYPE_TUNNEL_PAC && + pac->pac_type != PAC_TYPE_USER_AUTHORIZATION && + pac->pac_type != PAC_TYPE_MACHINE_AUTHENTICATION) + return "Unrecognized PAC-Type"; + + return NULL; +} + + +static const char * eap_fast_parse_pac_key(struct eap_fast_pac *pac, char *pos) +{ + u8 *key; + size_t key_len; + + key = eap_fast_parse_hex(pos, &key_len); + if (key == NULL || key_len != EAP_FAST_PAC_KEY_LEN) { + os_free(key); + return "Invalid PAC-Key"; + } + + os_memcpy(pac->pac_key, key, EAP_FAST_PAC_KEY_LEN); + os_free(key); + + return NULL; +} + + +static const char * eap_fast_parse_pac_opaque(struct eap_fast_pac *pac, + char *pos) +{ + os_free(pac->pac_opaque); + pac->pac_opaque = eap_fast_parse_hex(pos, &pac->pac_opaque_len); + if (pac->pac_opaque == NULL) + return "Invalid PAC-Opaque"; + return NULL; +} + + +static const char * eap_fast_parse_a_id(struct eap_fast_pac *pac, char *pos) +{ + os_free(pac->a_id); + pac->a_id = eap_fast_parse_hex(pos, &pac->a_id_len); + if (pac->a_id == NULL) + return "Invalid A-ID"; + return NULL; +} + + +static const char * eap_fast_parse_i_id(struct eap_fast_pac *pac, char *pos) +{ + os_free(pac->i_id); + pac->i_id = eap_fast_parse_hex(pos, &pac->i_id_len); + if (pac->i_id == NULL) + return "Invalid I-ID"; + return NULL; +} + + +static const char * eap_fast_parse_a_id_info(struct eap_fast_pac *pac, + char *pos) +{ + os_free(pac->a_id_info); + pac->a_id_info = eap_fast_parse_hex(pos, &pac->a_id_info_len); + if (pac->a_id_info == NULL) + return "Invalid A-ID-Info"; + return NULL; +} + + +/** + * eap_fast_load_pac - Load PAC entries (text format) + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @pac_root: Pointer to root of the PAC list (to be filled) + * @pac_file: Name of the PAC file/blob to load + * Returns: 0 on success, -1 on failure + */ +int eap_fast_load_pac(struct eap_sm *sm, struct eap_fast_pac **pac_root, + const char *pac_file) +{ + struct eap_fast_read_ctx rc; + struct eap_fast_pac *pac = NULL; + int count = 0; + char *pos; + const char *err = NULL; + + if (pac_file == NULL) + return -1; + + if (eap_fast_init_pac_data(sm, pac_file, &rc) < 0) + return 0; + + if (eap_fast_read_line(&rc, &pos) < 0) { + /* empty file - assume it is fine to overwrite */ + printf("\n\nassuming it is fine to overwrite... \n\n"); + eap_fast_deinit_pac_data(&rc); + return 0; + } + printf("\n\nPAC FILE =\n%s", rc.pos); + if (os_strcmp(pac_file_hdr, rc.buf) != 0) + err = "Unrecognized header line"; + + while (!err && eap_fast_read_line(&rc, &pos) == 0) { + if (os_strcmp(rc.buf, "START") == 0) + err = eap_fast_parse_start(&pac); + else if (os_strcmp(rc.buf, "END") == 0) { + err = eap_fast_parse_end(pac_root, &pac); + count++; + } else if (!pac) + err = "Unexpected line outside START/END block"; + else if (os_strcmp(rc.buf, "PAC-Type") == 0) + err = eap_fast_parse_pac_type(pac, pos); + else if (os_strcmp(rc.buf, "PAC-Key") == 0) + err = eap_fast_parse_pac_key(pac, pos); + else if (os_strcmp(rc.buf, "PAC-Opaque") == 0) + err = eap_fast_parse_pac_opaque(pac, pos); + else if (os_strcmp(rc.buf, "A-ID") == 0) + err = eap_fast_parse_a_id(pac, pos); + else if (os_strcmp(rc.buf, "I-ID") == 0) + err = eap_fast_parse_i_id(pac, pos); + else if (os_strcmp(rc.buf, "A-ID-Info") == 0) + err = eap_fast_parse_a_id_info(pac, pos); + } + + if (pac) { + if (!err) + err = "PAC block not terminated with END"; + eap_fast_free_pac(pac); + } + + eap_fast_deinit_pac_data(&rc); + + if (err) { + wpa_printf(MSG_INFO, "EAP-FAST: %s in '%s:%d'", + err, pac_file, rc.line); + return -1; + } + + wpa_printf(MSG_DEBUG, "EAP-FAST: Read %d PAC entries from '%s'", + count, pac_file); + + return 0; +} + + +static void eap_fast_write(char **buf, char **pos, size_t *buf_len, + const char *field, const u8 *data, + size_t len, int txt) +{ + size_t i, need; + int ret; + char *end; + + if (data == NULL || buf == NULL || *buf == NULL || + pos == NULL || *pos == NULL || *pos < *buf) + return; + + need = os_strlen(field) + len * 2 + 30; + if (txt) + need += os_strlen(field) + len + 20; + + if (*pos - *buf + need > *buf_len) { + char *nbuf = os_realloc(*buf, *buf_len + need); + if (nbuf == NULL) { + os_free(*buf); + *buf = NULL; + return; + } + *pos = nbuf + (*pos - *buf); + *buf = nbuf; + *buf_len += need; + } + end = *buf + *buf_len; + + ret = os_snprintf(*pos, end - *pos, "%s=", field); + if (os_snprintf_error(end - *pos, ret)) + return; + *pos += ret; + *pos += wpa_snprintf_hex(*pos, end - *pos, data, len); + ret = os_snprintf(*pos, end - *pos, "\n"); + if (os_snprintf_error(end - *pos, ret)) + return; + *pos += ret; + + if (txt) { + ret = os_snprintf(*pos, end - *pos, "%s-txt=", field); + if (os_snprintf_error(end - *pos, ret)) + return; + *pos += ret; + for (i = 0; i < len; i++) { + ret = os_snprintf(*pos, end - *pos, "%c", data[i]); + if (os_snprintf_error(end - *pos, ret)) + return; + *pos += ret; + } + ret = os_snprintf(*pos, end - *pos, "\n"); + if (os_snprintf_error(end - *pos, ret)) + return; + *pos += ret; + } +} + + +static int eap_fast_write_pac(struct eap_sm *sm, const char *pac_file, + char *buf, size_t len) +{ + if (os_strncmp(pac_file, "blob://", 7) == 0) { + struct wpa_config_blob *blob; + blob = os_zalloc(sizeof(*blob)); + if (blob == NULL) + return -1; + blob->data = (u8 *) buf; + blob->len = len; + buf = NULL; + blob->name = os_strdup(pac_file + 7); + if (blob->name == NULL) { + os_free(blob); + return -1; + } + eap_set_config_blob(sm, blob); + } else { + FILE *f; + f = fopen(pac_file, "wb"); + if (f == NULL) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to open PAC " + "file '%s' for writing", pac_file); + return -1; + } + if (fwrite(buf, 1, len, f) != len) { + wpa_printf(MSG_INFO, "EAP-FAST: Failed to write all " + "PACs into '%s'", pac_file); + fclose(f); + return -1; + } + os_free(buf); + fclose(f); + } + + return 0; +} + + +static int eap_fast_add_pac_data(struct eap_fast_pac *pac, char **buf, + char **pos, size_t *buf_len) +{ + int ret; + + ret = os_snprintf(*pos, *buf + *buf_len - *pos, + "START\nPAC-Type=%d\n", pac->pac_type); + if (os_snprintf_error(*buf + *buf_len - *pos, ret)) + return -1; + + *pos += ret; + eap_fast_write(buf, pos, buf_len, "PAC-Key", + pac->pac_key, EAP_FAST_PAC_KEY_LEN, 0); + eap_fast_write(buf, pos, buf_len, "PAC-Opaque", + pac->pac_opaque, pac->pac_opaque_len, 0); + eap_fast_write(buf, pos, buf_len, "PAC-Info", + pac->pac_info, pac->pac_info_len, 0); + eap_fast_write(buf, pos, buf_len, "A-ID", + pac->a_id, pac->a_id_len, 0); + eap_fast_write(buf, pos, buf_len, "I-ID", + pac->i_id, pac->i_id_len, 1); + eap_fast_write(buf, pos, buf_len, "A-ID-Info", + pac->a_id_info, pac->a_id_info_len, 1); + if (*buf == NULL) { + wpa_printf(MSG_DEBUG, "EAP-FAST: No memory for PAC " + "data"); + return -1; + } + ret = os_snprintf(*pos, *buf + *buf_len - *pos, "END\n"); + if (os_snprintf_error(*buf + *buf_len - *pos, ret)) + return -1; + *pos += ret; + + return 0; +} + + +/** + * eap_fast_save_pac - Save PAC entries (text format) + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @pac_root: Root of the PAC list + * @pac_file: Name of the PAC file/blob + * Returns: 0 on success, -1 on failure + */ +int eap_fast_save_pac(struct eap_sm *sm, struct eap_fast_pac *pac_root, + const char *pac_file) +{ + struct eap_fast_pac *pac; + int ret, count = 0; + char *buf, *pos; + size_t buf_len; + + if (pac_file == NULL) + return -1; + + buf_len = 1024; + pos = buf = os_malloc(buf_len); + if (buf == NULL) + return -1; + + ret = os_snprintf(pos, buf + buf_len - pos, "%s\n", pac_file_hdr); + if (os_snprintf_error(buf + buf_len - pos, ret)) { + os_free(buf); + return -1; + } + pos += ret; + + pac = pac_root; + while (pac) { + if (eap_fast_add_pac_data(pac, &buf, &pos, &buf_len)) { + os_free(buf); + return -1; + } + count++; + pac = pac->next; + } + + if (eap_fast_write_pac(sm, pac_file, buf, pos - buf)) { + os_free(buf); + return -1; + } + + wpa_printf(MSG_DEBUG, "PAC file: %s", (sm->blob[3].data)); + wpa_printf(MSG_DEBUG, "EAP-FAST: Wrote %d PAC entries into '%s'", + count, pac_file); + + return 0; +} + + +/** + * eap_fast_pac_list_truncate - Truncate a PAC list to the given length + * @pac_root: Root of the PAC list + * @max_len: Maximum length of the list (>= 1) + * Returns: Number of PAC entries removed + */ +size_t eap_fast_pac_list_truncate(struct eap_fast_pac *pac_root, + size_t max_len) +{ + struct eap_fast_pac *pac, *prev; + size_t count; + + pac = pac_root; + prev = NULL; + count = 0; + + while (pac) { + count++; + if (count > max_len) + break; + prev = pac; + pac = pac->next; + } + + if (count <= max_len || prev == NULL) + return 0; + + count = 0; + prev->next = NULL; + + while (pac) { + prev = pac; + pac = pac->next; + eap_fast_free_pac(prev); + count++; + } + + return count; +} + + +static void eap_fast_pac_get_a_id(struct eap_fast_pac *pac) +{ + u8 *pos, *end; + u16 type, len; + + pos = pac->pac_info; + end = pos + pac->pac_info_len; + + while (end - pos > 4) { + type = WPA_GET_BE16(pos); + pos += 2; + len = WPA_GET_BE16(pos); + pos += 2; + if (len > (unsigned int) (end - pos)) + break; + + if (type == PAC_TYPE_A_ID) { + os_free(pac->a_id); + pac->a_id = os_memdup(pos, len); + if (pac->a_id == NULL) + break; + pac->a_id_len = len; + } + + if (type == PAC_TYPE_A_ID_INFO) { + os_free(pac->a_id_info); + pac->a_id_info = os_memdup(pos, len); + if (pac->a_id_info == NULL) + break; + pac->a_id_info_len = len; + } + + pos += len; + } +} + + +/** + * eap_fast_load_pac_bin - Load PAC entries (binary format) + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @pac_root: Pointer to root of the PAC list (to be filled) + * @pac_file: Name of the PAC file/blob to load + * Returns: 0 on success, -1 on failure + */ +int eap_fast_load_pac_bin(struct eap_sm *sm, struct eap_fast_pac **pac_root, + const char *pac_file) +{ + const struct wpa_config_blob *blob = NULL; + u8 *buf, *end, *pos; + size_t len = 0; + size_t count = 0; + struct eap_fast_pac *pac, *prev; + + *pac_root = NULL; + + if (pac_file == NULL) + return -1; + + if (sm->config.pac_file != NULL) { //if (os_strncmp(pac_file, "blob://", 7) == 0) { + blob = eap_get_config_blob(sm, PAC_FILE_NAME); + if (blob == NULL) { + wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - " + "assume no PAC entries have been " + "provisioned", pac_file); + return 0; + } + buf = (u8 *) blob->data; + len = blob->len; + } else { + buf = (u8 *) sm->blob[3].data; //(u8 *) os_readfile(pac_file, &len); + if (buf == NULL) { + wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - " + "assume no PAC entries have been " + "provisioned", pac_file); + return 0; + } + } + + if (len == 0) { + if (blob == NULL) + os_free(buf); + return 0; + } + + if (len < 6 || WPA_GET_BE32(buf) != EAP_FAST_PAC_BINARY_MAGIC || + WPA_GET_BE16(buf + 4) != EAP_FAST_PAC_BINARY_FORMAT_VERSION) { + wpa_printf(MSG_INFO, "EAP-FAST: Invalid PAC file '%s' (bin)", + pac_file); + if (blob == NULL) + os_free(buf); + return -1; + } + + pac = prev = NULL; + pos = buf + 6; + end = buf + len; + while (pos < end) { + u16 val; + + if (end - pos < 2 + EAP_FAST_PAC_KEY_LEN + 2 + 2) { + pac = NULL; + goto parse_fail; + } + + pac = os_zalloc(sizeof(*pac)); + if (pac == NULL) + goto parse_fail; + + pac->pac_type = WPA_GET_BE16(pos); + pos += 2; + os_memcpy(pac->pac_key, pos, EAP_FAST_PAC_KEY_LEN); + pos += EAP_FAST_PAC_KEY_LEN; + val = WPA_GET_BE16(pos); + pos += 2; + if (val > end - pos) + goto parse_fail; + pac->pac_opaque_len = val; + pac->pac_opaque = os_memdup(pos, pac->pac_opaque_len); + if (pac->pac_opaque == NULL) + goto parse_fail; + pos += pac->pac_opaque_len; + if (2 > end - pos) + goto parse_fail; + val = WPA_GET_BE16(pos); + pos += 2; + if (val > end - pos) + goto parse_fail; + pac->pac_info_len = val; + pac->pac_info = os_memdup(pos, pac->pac_info_len); + if (pac->pac_info == NULL) + goto parse_fail; + pos += pac->pac_info_len; + eap_fast_pac_get_a_id(pac); + + count++; + if (prev) + prev->next = pac; + else + *pac_root = pac; + prev = pac; + } + + if (blob == NULL) + os_free(buf); + + wpa_printf(MSG_DEBUG, "EAP-FAST: Read %lu PAC entries from '%s' (bin)", + (unsigned long) count, pac_file); + + return 0; + +parse_fail: + wpa_printf(MSG_INFO, "EAP-FAST: Failed to parse PAC file '%s' (bin)", + pac_file); + if (blob == NULL) + os_free(buf); + if (pac) + eap_fast_free_pac(pac); + return -1; +} + + +/** + * eap_fast_save_pac_bin - Save PAC entries (binary format) + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @pac_root: Root of the PAC list + * @pac_file: Name of the PAC file/blob + * Returns: 0 on success, -1 on failure + */ +int eap_fast_save_pac_bin(struct eap_sm *sm, struct eap_fast_pac *pac_root, + const char *pac_file) +{ + size_t len, count = 0; + struct eap_fast_pac *pac; + u8 *buf, *pos; + + len = 6; + pac = pac_root; + while (pac) { + if (pac->pac_opaque_len > 65535 || + pac->pac_info_len > 65535) + return -1; + len += 2 + EAP_FAST_PAC_KEY_LEN + 2 + pac->pac_opaque_len + + 2 + pac->pac_info_len; + pac = pac->next; + } + + buf = os_malloc(len); + if (buf == NULL) + return -1; + + pos = buf; + WPA_PUT_BE32(pos, EAP_FAST_PAC_BINARY_MAGIC); + pos += 4; + WPA_PUT_BE16(pos, EAP_FAST_PAC_BINARY_FORMAT_VERSION); + pos += 2; + + pac = pac_root; + while (pac) { + WPA_PUT_BE16(pos, pac->pac_type); + pos += 2; + os_memcpy(pos, pac->pac_key, EAP_FAST_PAC_KEY_LEN); + pos += EAP_FAST_PAC_KEY_LEN; + WPA_PUT_BE16(pos, pac->pac_opaque_len); + pos += 2; + os_memcpy(pos, pac->pac_opaque, pac->pac_opaque_len); + pos += pac->pac_opaque_len; + WPA_PUT_BE16(pos, pac->pac_info_len); + pos += 2; + os_memcpy(pos, pac->pac_info, pac->pac_info_len); + pos += pac->pac_info_len; + + pac = pac->next; + count++; + } + + if (eap_fast_write_pac(sm, pac_file, (char *) buf, len)) { + os_free(buf); + return -1; + } + + wpa_printf(MSG_DEBUG, "EAP-FAST: Wrote %lu PAC entries into '%s' " + "(bin)", (unsigned long) count, pac_file); + + return 0; +} diff --git a/components/wpa_supplicant/src/eap_peer/eap_fast_pac.h b/components/wpa_supplicant/src/eap_peer/eap_fast_pac.h new file mode 100644 index 000000000000..b50cdc304a6f --- /dev/null +++ b/components/wpa_supplicant/src/eap_peer/eap_fast_pac.h @@ -0,0 +1,50 @@ +/* + * EAP peer method: EAP-FAST PAC file processing + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_FAST_PAC_H +#define EAP_FAST_PAC_H + +#include "eap_peer/eap_fast_common.h" + +struct eap_fast_pac { + struct eap_fast_pac *next; + + u8 pac_key[EAP_FAST_PAC_KEY_LEN]; + u8 *pac_opaque; + size_t pac_opaque_len; + u8 *pac_info; + size_t pac_info_len; + u8 *a_id; + size_t a_id_len; + u8 *i_id; + size_t i_id_len; + u8 *a_id_info; + size_t a_id_info_len; + u16 pac_type; +}; + + +void eap_fast_free_pac(struct eap_fast_pac *pac); +struct eap_fast_pac * eap_fast_get_pac(struct eap_fast_pac *pac_root, + const u8 *a_id, size_t a_id_len, + u16 pac_type); +int eap_fast_add_pac(struct eap_fast_pac **pac_root, + struct eap_fast_pac **pac_current, + struct eap_fast_pac *entry); +int eap_fast_load_pac(struct eap_sm *sm, struct eap_fast_pac **pac_root, + const char *pac_file); +int eap_fast_save_pac(struct eap_sm *sm, struct eap_fast_pac *pac_root, + const char *pac_file); +size_t eap_fast_pac_list_truncate(struct eap_fast_pac *pac_root, + size_t max_len); +int eap_fast_load_pac_bin(struct eap_sm *sm, struct eap_fast_pac **pac_root, + const char *pac_file); +int eap_fast_save_pac_bin(struct eap_sm *sm, struct eap_fast_pac *pac_root, + const char *pac_file); + +#endif /* EAP_FAST_PAC_H */ diff --git a/components/wpa_supplicant/src/eap_peer/eap_i.h b/components/wpa_supplicant/src/eap_peer/eap_i.h index d5ffab3e8491..8d71b4983d69 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_i.h +++ b/components/wpa_supplicant/src/eap_peer/eap_i.h @@ -263,8 +263,9 @@ struct eap_method { #define CLIENT_CERT_NAME "CLC" #define CA_CERT_NAME "CAC" #define PRIVATE_KEY_NAME "PVK" +#define PAC_FILE_NAME "PAC" #define BLOB_NAME_LEN 3 -#define BLOB_NUM 3 +#define BLOB_NUM 4 enum SIG_WPA2 { SIG_WPA2_START = 0, @@ -282,6 +283,7 @@ struct eap_sm { void *eap_method_priv; int init_phase2; + void *msg_ctx; void *ssl_ctx; unsigned int workaround; @@ -296,6 +298,12 @@ struct eap_sm { #endif u8 finish_state; + /* Optional challenges generated in Phase 1 (EAP-FAST) */ + u8 *peer_challenge, *auth_challenge; + + unsigned int expected_failure:1; + unsigned int ext_cert_check:1; + unsigned int waiting_ext_cert_check:1; bool peap_done; u8 *eapKeyData; @@ -319,7 +327,9 @@ const char * eap_get_config_phase1(struct eap_sm *sm); const char * eap_get_config_phase2(struct eap_sm *sm); int eap_get_config_fragment_size(struct eap_sm *sm); struct eap_peer_config * eap_get_config(struct eap_sm *sm); +void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob); const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, const char *name); +int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method); bool wifi_sta_get_enterprise_disable_time_check(void); struct wpabuf * eap_sm_build_identity_resp(struct eap_sm *sm, u8 id, int encrypted); diff --git a/components/wpa_supplicant/src/eap_peer/eap_methods.h b/components/wpa_supplicant/src/eap_peer/eap_methods.h index 80a09677a4e6..bd2e907d0542 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_methods.h +++ b/components/wpa_supplicant/src/eap_peer/eap_methods.h @@ -30,6 +30,7 @@ void eap_peer_unregister_methods(void); int eap_peer_tls_register(void); int eap_peer_peap_register(void); int eap_peer_ttls_register(void); +int eap_peer_fast_register(void); int eap_peer_mschapv2_register(void); void eap_peer_unregister_methods(void); diff --git a/components/wpa_supplicant/src/eap_peer/eap_mschapv2.c b/components/wpa_supplicant/src/eap_peer/eap_mschapv2.c index 2e87c0e65df9..35c7aacc5317 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_mschapv2.c +++ b/components/wpa_supplicant/src/eap_peer/eap_mschapv2.c @@ -21,6 +21,7 @@ #include "eap_peer/eap_config.h" #include "eap_peer/mschapv2.h" #include "eap_peer/eap_methods.h" +#include "common/wpa_ctrl.h" #define MSCHAPV2_OP_CHALLENGE 1 #define MSCHAPV2_OP_RESPONSE 2 @@ -104,6 +105,24 @@ eap_mschapv2_init(struct eap_sm *sm) if (data == NULL) return NULL; + if (sm->peer_challenge) { + data->peer_challenge = os_memdup(sm->peer_challenge, + MSCHAPV2_CHAL_LEN); + if (data->peer_challenge == NULL) { + eap_mschapv2_deinit(sm, data); + return NULL; + } + } + + if (sm->auth_challenge) { + data->auth_challenge = os_memdup(sm->auth_challenge, + MSCHAPV2_CHAL_LEN); + if (data->auth_challenge == NULL) { + eap_mschapv2_deinit(sm, data); + return NULL; + } + } + data->phase2 = sm->init_phase2; return data; @@ -139,8 +158,15 @@ eap_mschapv2_challenge_reply( ms = wpabuf_put(resp, sizeof(*ms)); ms->op_code = MSCHAPV2_OP_RESPONSE; ms->mschapv2_id = mschapv2_id; - if (data->prev_error) + if (data->prev_error) { + /* + * TODO: this does not seem to be enough when processing two + * or more failure messages. IAS did not increment mschapv2_id + * in its own packets, but it seemed to expect the peer to + * increment this for all packets(?). + */ ms->mschapv2_id++; + } WPA_PUT_BE16(ms->ms_length, ms_len); wpabuf_put_u8(resp, sizeof(*r)); @@ -148,33 +174,53 @@ eap_mschapv2_challenge_reply( r = wpabuf_put(resp, sizeof(*r)); peer_challenge = r->peer_challenge; if (data->peer_challenge) { + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge generated " + "in Phase 1"); peer_challenge = data->peer_challenge; - os_memset(r->peer_challenge, 0, MSCHAPV2_CHAL_LEN); + os_memset(r->peer_challenge, 0, MSCHAPV2_CHAL_LEN); } else if (random_get_bytes(peer_challenge, MSCHAPV2_CHAL_LEN)) { wpabuf_free(resp); return NULL; } os_memset(r->reserved, 0, 8); - if (data->auth_challenge) + if (data->auth_challenge) { + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge generated " + "in Phase 1"); auth_challenge = data->auth_challenge; + } if (mschapv2_derive_response(identity, identity_len, password, password_len, pwhash, auth_challenge, peer_challenge, r->nt_response, data->auth_response, data->master_key)) { + wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to derive " + "response"); wpabuf_free(resp); return NULL; } data->auth_response_valid = 1; data->master_key_valid = 1; - r->flags = 0; + r->flags = 0; /* reserved, must be zero */ wpabuf_put_data(resp, identity, identity_len); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d " + "(response)", id, ms->mschapv2_id); return resp; } -static struct wpabuf * -eap_mschapv2_challenge( + +/** + * eap_mschapv2_process - Process an EAP-MSCHAPv2 challenge message + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @data: Pointer to private EAP method data from eap_mschapv2_init() + * @ret: Return values from EAP request validation and processing + * @req: Pointer to EAP-MSCHAPv2 header from the request + * @req_len: Length of the EAP-MSCHAPv2 data + * @id: EAP identifier used in the request + * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if + * no reply available + */ +static struct wpabuf * eap_mschapv2_challenge( struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, size_t req_len, u8 id) @@ -186,7 +232,10 @@ eap_mschapv2_challenge( eap_get_config_password(sm, &len) == NULL) return NULL; + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received challenge"); if (req_len < sizeof(*req) + 1) { + wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge data " + "(len %lu)", (unsigned long) req_len); ret->ignore = true; return NULL; } @@ -194,21 +243,30 @@ eap_mschapv2_challenge( challenge_len = *pos++; len = req_len - sizeof(*req) - 1; if (challenge_len != MSCHAPV2_CHAL_LEN) { + wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid challenge length " + "%lu", (unsigned long) challenge_len); ret->ignore = true; return NULL; } if (len < challenge_len) { + wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge" + " packet: len=%lu challenge_len=%lu", + (unsigned long) len, (unsigned long) challenge_len); ret->ignore = true; return NULL; } - if (data->passwd_change_challenge_valid) + if (data->passwd_change_challenge_valid) { + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Using challenge from the " + "failure message"); challenge = data->passwd_change_challenge; - else + } else challenge = pos; pos += challenge_len; len -= challenge_len; + wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Authentication Servername", + pos, len); ret->ignore = false; ret->methodState = METHOD_MAY_CONT; @@ -225,9 +283,13 @@ eap_mschapv2_password_changed(struct eap_sm *sm, { struct eap_peer_config *config = eap_get_config(sm); if (config && config->new_password) { + wpa_msg(sm->msg_ctx, MSG_INFO, + WPA_EVENT_PASSWORD_CHANGED + "EAP-MSCHAPV2: Password changed successfully"); data->prev_error = 0; os_free(config->password); if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { + /* TODO: update external storage */ } else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) { config->password = os_malloc(16); config->password_len = 16; @@ -257,11 +319,14 @@ eap_mschapv2_success(struct eap_sm *sm, const u8 *pos; size_t len; + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received success"); len = req_len - sizeof(*req); - pos = (const u8 *)(req + 1); + pos = (const u8 *) (req + 1); if (!data->auth_response_valid || mschapv2_verify_auth_response(data->auth_response, pos, len)) { - ret->methodState = METHOD_NONE; + wpa_printf(MSG_WARNING, "EAP-MSCHAPV2: Invalid authenticator " + "response in success request"); + ret->methodState = METHOD_DONE; ret->decision = DECISION_FAIL; return NULL; } @@ -271,15 +336,23 @@ eap_mschapv2_success(struct eap_sm *sm, pos++; len--; } + wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Success message", + pos, len); + wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Authentication succeeded"); + /* Note: Only op_code of the EAP-MSCHAPV2 header is included in success + * message. */ resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1, EAP_CODE_RESPONSE, id); if (resp == NULL) { + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Failed to allocate " + "buffer for success response"); ret->ignore = true; return NULL; } - wpabuf_put_u8(resp, MSCHAPV2_OP_SUCCESS); + wpabuf_put_u8(resp, MSCHAPV2_OP_SUCCESS); /* op_code */ + ret->methodState = METHOD_DONE; ret->decision = DECISION_UNCOND_SUCC; ret->allowNotifications = false; @@ -291,19 +364,25 @@ eap_mschapv2_success(struct eap_sm *sm, return resp; } -static int -eap_mschapv2_failure_txt(struct eap_sm *sm, - struct eap_mschapv2_data *data, char *txt) + +static int eap_mschapv2_failure_txt(struct eap_sm *sm, + struct eap_mschapv2_data *data, char *txt) { - char *pos; + char *pos = ""; int retry = 1; struct eap_peer_config *config = eap_get_config(sm); + /* For example: + * E=691 R=1 C=<32 octets hex challenge> V=3 M=Authentication Failure + */ + pos = txt; if (pos && os_strncmp(pos, "E=", 2) == 0) { pos += 2; data->prev_error = atoi(pos); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: error %d", + data->prev_error); pos = (char *)os_strchr(pos, ' '); if (pos) pos++; @@ -312,6 +391,8 @@ eap_mschapv2_failure_txt(struct eap_sm *sm, if (pos && os_strncmp(pos, "R=", 2) == 0) { pos += 2; retry = atoi(pos); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: retry is %sallowed", + retry == 1 ? "" : "not "); pos = (char *)os_strchr(pos, ' '); if (pos) pos++; @@ -324,19 +405,32 @@ eap_mschapv2_failure_txt(struct eap_sm *sm, if (hex_len == PASSWD_CHANGE_CHAL_LEN * 2) { if (hexstr2bin(pos, data->passwd_change_challenge, PASSWD_CHANGE_CHAL_LEN)) { - wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: invalid failure challenge\n"); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: invalid " + "failure challenge"); } else { + wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: failure " + "challenge", + data->passwd_change_challenge, + PASSWD_CHANGE_CHAL_LEN); data->passwd_change_challenge_valid = 1; } } else { - wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: required challenge field " - "was not present in failure message\n"); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: invalid failure " + "challenge len %d", hex_len); } + pos = os_strchr(pos, ' '); + if (pos) + pos++; + } else { + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: required challenge field " + "was not present in failure message"); } if (pos && os_strncmp(pos, "V=", 2) == 0) { pos += 2; data->passwd_change_version = atoi(pos); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: password changing " + "protocol version %d", data->passwd_change_version); pos = (char *)os_strchr(pos, ' '); if (pos) pos++; @@ -345,24 +439,38 @@ eap_mschapv2_failure_txt(struct eap_sm *sm, if (pos && os_strncmp(pos, "M=", 2) == 0) { pos += 2; } + if (data->prev_error == ERROR_AUTHENTICATION_FAILURE && retry && + config && config->phase2 && + os_strstr(config->phase2, "mschapv2_retry=0")) { + wpa_printf(MSG_DEBUG, + "EAP-MSCHAPV2: mark password retry disabled based on local configuration"); + retry = 0; + } if (data->prev_error == ERROR_PASSWD_EXPIRED && data->passwd_change_version == 3 && config) { if (config->new_password == NULL) { - wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Password expired - " - "password change reqired\n"); + wpa_msg(sm->msg_ctx, MSG_INFO, + "EAP-MSCHAPV2: Password expired - password " + "change required"); + eap_sm_request_new_password(sm); } } else if (retry == 1 && config) { + /* TODO: could prevent the current password from being used + * again at least for some period of time */ if (!config->mschapv2_retry) + eap_sm_request_identity(sm); + eap_sm_request_password(sm); config->mschapv2_retry = 1; } else if (config) { + /* TODO: prevent retries using same username/password */ config->mschapv2_retry = 0; } return retry == 1; } -static struct wpabuf * -eap_mschapv2_change_password( + +static struct wpabuf * eap_mschapv2_change_password( struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id) { @@ -393,46 +501,67 @@ eap_mschapv2_change_password( EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; + ms = wpabuf_put(resp, sizeof(*ms)); ms->op_code = MSCHAPV2_OP_CHANGE_PASSWORD; ms->mschapv2_id = req->mschapv2_id + 1; WPA_PUT_BE16(ms->ms_length, ms_len); cp = wpabuf_put(resp, sizeof(*cp)); + /* Encrypted-Password */ if (pwhash) { if (encrypt_pw_block_with_password_hash( - new_password, new_password_len, - password, cp->encr_password)) + new_password, new_password_len, + password, cp->encr_password)) goto fail; } else { if (new_password_encrypted_with_old_nt_password_hash( - new_password, new_password_len, - password, password_len, cp->encr_password)) + new_password, new_password_len, + password, password_len, cp->encr_password)) goto fail; } + /* Encrypted-Hash */ if (pwhash) { u8 new_password_hash[16]; - nt_password_hash(new_password, new_password_len, - new_password_hash); - nt_password_hash_encrypted_with_block(password, - new_password_hash, - cp->encr_hash); + if (nt_password_hash(new_password, new_password_len, + new_password_hash) || + nt_password_hash_encrypted_with_block(password, + new_password_hash, + cp->encr_hash)) + goto fail; } else { - old_nt_password_hash_encrypted_with_new_nt_password_hash( - new_password, new_password_len, - password, password_len, cp->encr_hash); + if (old_nt_password_hash_encrypted_with_new_nt_password_hash( + new_password, new_password_len, + password, password_len, cp->encr_hash)) + goto fail; } + /* Peer-Challenge */ if (random_get_bytes(cp->peer_challenge, MSCHAPV2_CHAL_LEN)) goto fail; + /* Reserved, must be zero */ os_memset(cp->reserved, 0, 8); + /* NT-Response */ + wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge", + data->passwd_change_challenge, PASSWD_CHANGE_CHAL_LEN); + wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge", + cp->peer_challenge, MSCHAPV2_CHAL_LEN); + wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: username", + username, username_len); + wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: new password", + new_password, new_password_len); generate_nt_response(data->passwd_change_challenge, cp->peer_challenge, - username, username_len, new_password, - new_password_len, cp->nt_response); - + username, username_len, + new_password, new_password_len, + cp->nt_response); + wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: NT-Response", + cp->nt_response, MSCHAPV2_NT_RESPONSE_LEN); + + /* Authenticator response is not really needed yet, but calculate it + * here so that challenges need not be saved. */ generate_authenticator_response(new_password, new_password_len, cp->peer_challenge, data->passwd_change_challenge, @@ -440,13 +569,23 @@ eap_mschapv2_change_password( cp->nt_response, data->auth_response); data->auth_response_valid = 1; - nt_password_hash(new_password, new_password_len, password_hash); - hash_nt_password_hash(password_hash, password_hash_hash); - get_master_key(password_hash_hash, cp->nt_response, data->master_key); + /* Likewise, generate master_key here since we have the needed data + * available. */ + if (nt_password_hash(new_password, new_password_len, password_hash) || + hash_nt_password_hash(password_hash, password_hash_hash) || + get_master_key(password_hash_hash, cp->nt_response, + data->master_key)) { + data->auth_response_valid = 0; + goto fail; + } data->master_key_valid = 1; + /* Flags */ os_memset(cp->flags, 0, 2); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d " + "(change pw)", id, ms->mschapv2_id); + return resp; fail: @@ -454,19 +593,38 @@ eap_mschapv2_change_password( return NULL; } -static struct wpabuf * -eap_mschapv2_failure(struct eap_sm *sm, - struct eap_mschapv2_data *data, - struct eap_method_ret *ret, - const struct eap_mschapv2_hdr *req, - size_t req_len, u8 id) + +/** + * eap_mschapv2_process - Process an EAP-MSCHAPv2 failure message + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @data: Pointer to private EAP method data from eap_mschapv2_init() + * @ret: Return values from EAP request validation and processing + * @req: Pointer to EAP-MSCHAPv2 header from the request + * @req_len: Length of the EAP-MSCHAPv2 data + * @id: EAP identifier used in th erequest + * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if + * no reply available + */ +static struct wpabuf * eap_mschapv2_failure(struct eap_sm *sm, + struct eap_mschapv2_data *data, + struct eap_method_ret *ret, + const struct eap_mschapv2_hdr *req, + size_t req_len, u8 id) { struct wpabuf *resp; - const u8 *msdata = (const u8 *)(req + 1); + const u8 *msdata = (const u8 *) (req + 1); char *buf; size_t len = req_len - sizeof(*req); int retry = 0; + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received failure"); + wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Failure data", + msdata, len); + /* + * eap_mschapv2_failure_txt() expects a nul terminated string, so we + * must allocate a large enough temporary buffer to create that since + * the received message does not include nul termination. + */ buf = (char *)dup_binstr(msdata, len); if (buf) { retry = eap_mschapv2_failure_txt(sm, data, buf); @@ -482,23 +640,31 @@ eap_mschapv2_failure(struct eap_sm *sm, data->passwd_change_version == 3) { struct eap_peer_config *config = eap_get_config(sm); if (config && config->new_password) - return eap_mschapv2_change_password(sm, data, ret, - req, id); + return eap_mschapv2_change_password(sm, data, ret, req, + id); + if (config && config->pending_req_new_password) + return NULL; } else if (retry && data->prev_error == ERROR_AUTHENTICATION_FAILURE) { + /* TODO: could try to retry authentication, e.g, after having + * changed the username/password. In this case, EAP MS-CHAP-v2 + * Failure Response would not be sent here. */ return NULL; } + /* Note: Only op_code of the EAP-MSCHAPV2 header is included in failure + * message. */ resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1, EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; - wpabuf_put_u8(resp, MSCHAPV2_OP_FAILURE); + wpabuf_put_u8(resp, MSCHAPV2_OP_FAILURE); /* op_code */ + return resp; } -static int -eap_mschapv2_check_config(struct eap_sm *sm) + +static int eap_mschapv2_check_config(struct eap_sm *sm) { struct eap_peer_config *config = eap_get_config(sm); @@ -520,19 +686,24 @@ eap_mschapv2_check_config(struct eap_sm *sm) return 0; } -static int -eap_mschapv2_check_mslen(struct eap_sm *sm, size_t len, - const struct eap_mschapv2_hdr *ms) + +static int eap_mschapv2_check_mslen(struct eap_sm *sm, size_t len, + const struct eap_mschapv2_hdr *ms) { size_t ms_len = WPA_GET_BE16(ms->ms_length); if (ms_len == len) return 0; + wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid header: len=%lu " + "ms_len=%lu", (unsigned long) len, (unsigned long) ms_len); if (sm->workaround) { - wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Workaround, ignore Invalid" - " header len=%lu ms_len=%lu\n", - (unsigned long)len, (unsigned long)ms_len); + /* Some authentication servers use invalid ms_len, + * ignore it for interoperability. */ + wpa_printf(MSG_INFO, "EAP-MSCHAPV2: workaround, ignore" + " invalid ms_len %lu (len %lu)", + (unsigned long) ms_len, + (unsigned long) len); return 0; } wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Invalid header len=%lu ms_len=%lu\n", @@ -541,18 +712,31 @@ eap_mschapv2_check_mslen(struct eap_sm *sm, size_t len, return -1; } -static void -eap_mschapv2_copy_challenge(struct eap_mschapv2_data *data, - const struct wpabuf *reqData) + +static void eap_mschapv2_copy_challenge(struct eap_mschapv2_data *data, + const struct wpabuf *reqData) { + /* + * Store a copy of the challenge message, so that it can be processed + * again in case retry is allowed after a possible failure. + */ wpabuf_free(data->prev_challenge); data->prev_challenge = wpabuf_dup(reqData); } -static struct wpabuf * -eap_mschapv2_process(struct eap_sm *sm, void *priv, - struct eap_method_ret *ret, - const struct wpabuf *reqData) + +/** + * eap_mschapv2_process - Process an EAP-MSCHAPv2 request + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @priv: Pointer to private EAP method data from eap_mschapv2_init() + * @ret: Return values from EAP request validation and processing + * @reqData: EAP request to be processed (eapReqData) + * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if + * no reply available + */ +static struct wpabuf * eap_mschapv2_process(struct eap_sm *sm, void *priv, + struct eap_method_ret *ret, + const struct wpabuf *reqData) { u8 id; size_t len; @@ -569,27 +753,31 @@ eap_mschapv2_process(struct eap_sm *sm, void *priv, if (config->mschapv2_retry && data->prev_challenge && data->prev_error == ERROR_AUTHENTICATION_FAILURE) { + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Replacing pending packet " + "with the previous challenge"); + reqData = data->prev_challenge; using_prev_challenge = 1; config->mschapv2_retry = 0; } - pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, - reqData, &len); + pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqData, + &len); if (pos == NULL || len < sizeof(*ms) + 1) { ret->ignore = true; return NULL; } - ms = (const struct eap_mschapv2_hdr *)pos; + ms = (const struct eap_mschapv2_hdr *) pos; if (eap_mschapv2_check_mslen(sm, len, ms)) { ret->ignore = true; return NULL; } id = eap_get_id(reqData); - wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: RX identifier %d mschapv2_id %d\n", - id, ms->mschapv2_id); + wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: RX identifier %d mschapv2_id %d", + id, ms->mschapv2_id); + switch (ms->op_code) { case MSCHAPV2_OP_CHALLENGE: if (!using_prev_challenge) @@ -602,19 +790,20 @@ eap_mschapv2_process(struct eap_sm *sm, void *priv, default: wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Unknow op code %d -ignored\n", ms->op_code); + ret->ignore = TRUE; return NULL; } } -static bool -eap_mschapv2_isKeyAvailable(struct eap_sm *sm, void *priv) + +static bool eap_mschapv2_isKeyAvailable(struct eap_sm *sm, void *priv) { struct eap_mschapv2_data *data = priv; return data->success && data->master_key_valid; } -static u8 * -eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len) + +static u8 * eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len) { struct eap_mschapv2_data *data = priv; u8 *key; @@ -626,20 +815,31 @@ eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len) key_len = 2 * MSCHAPV2_KEY_LEN; key = os_malloc(key_len); + if (key == NULL) + return NULL; - /* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key, - * peer MS-MPPE-Send-Key | MS-MPPE-Recv-Key */ - get_asymetric_start_key(data->master_key, key, - MSCHAPV2_KEY_LEN, 1, 0); + /* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key, i.e., + * peer MS-MPPE-Send-Key | MS-MPPE-Recv-Key */ + get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 1, 0); get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN, MSCHAPV2_KEY_LEN, 0, 0); + wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key", + key, key_len); + *len = key_len; return key; } -int -eap_peer_mschapv2_register(void) + +/** + * eap_peer_mschapv2_register - Register EAP-MSCHAPv2 peer method + * Returns: 0 on success, -1 on failure + * + * This function is used to register EAP-MSCHAPv2 peer method into the EAP + * method list. + */ +int eap_peer_mschapv2_register(void) { struct eap_method *eap; int ret; diff --git a/components/wpa_supplicant/src/eap_peer/eap_peap.c b/components/wpa_supplicant/src/eap_peer/eap_peap.c index 3a06bc3e8967..b21ab6bac7c6 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_peap.c +++ b/components/wpa_supplicant/src/eap_peer/eap_peap.c @@ -1042,10 +1042,9 @@ eap_peap_decrypt(struct eap_sm *sm, struct eap_peap_data *data, } -static struct wpabuf * -eap_peap_process(struct eap_sm *sm, void *priv, - struct eap_method_ret *ret, - const struct wpabuf *reqData) +static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, + struct eap_method_ret *ret, + const struct wpabuf *reqData) { const struct eap_hdr *req; size_t left; @@ -1096,6 +1095,14 @@ eap_peap_process(struct eap_sm *sm, void *priv, data->peap_version, id, pos, left, &resp); + if (res < 0) { + wpa_printf(MSG_DEBUG, + "EAP-PEAP: TLS processing failed"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + return resp; + } + if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { char label[24]; wpa_printf(MSG_DEBUG, "EAP-PEAP: TLS done, proceed to Phase 2"); diff --git a/components/wpa_supplicant/src/eap_peer/eap_tls.c b/components/wpa_supplicant/src/eap_peer/eap_tls.c index c6d0bd05985a..bad1e6d6409d 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_tls.c +++ b/components/wpa_supplicant/src/eap_peer/eap_tls.c @@ -16,6 +16,10 @@ #include "eap_peer/eap_config.h" #include "eap_peer/eap_methods.h" + +static void eap_tls_deinit(struct eap_sm *sm, void *priv); + + struct eap_tls_data { struct eap_ssl_data ssl; u8 *key_data; @@ -26,19 +30,6 @@ struct eap_tls_data { }; - -static void eap_tls_deinit(struct eap_sm *sm, void *priv) -{ - struct eap_tls_data *data = priv; - if (data == NULL) - return; - eap_peer_tls_ssl_deinit(sm, &data->ssl); - os_free(data->key_data); - os_free(data->session_id); - os_free(data); -} - - static void * eap_tls_init(struct eap_sm *sm) { struct eap_tls_data *data; @@ -66,6 +57,19 @@ static void * eap_tls_init(struct eap_sm *sm) return data; } + +static void eap_tls_deinit(struct eap_sm *sm, void *priv) +{ + struct eap_tls_data *data = priv; + if (data == NULL) + return; + eap_peer_tls_ssl_deinit(sm, &data->ssl); + os_free(data->key_data); + os_free(data->session_id); + os_free(data); +} + + static struct wpabuf * eap_tls_failure(struct eap_sm *sm, struct eap_tls_data *data, struct eap_method_ret *ret, int res, diff --git a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c index 3fd0e17a776b..9c1e8c958856 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c +++ b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c @@ -102,6 +102,10 @@ static int eap_tls_params_from_conf(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "TLS: using phase1 config options"); eap_tls_params_from_conf1(params, config); + if (data->eap_type == EAP_TYPE_FAST) { + wpa_printf(MSG_DEBUG, "EAP-TYPE == EAP-FAST #####################################"); + params->flags |= TLS_CONN_EAP_FAST; + } /* * Use blob data, if available. Otherwise, leave reference to external @@ -254,7 +258,7 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, if (out == NULL) return NULL; - if (tls_connection_export_key(data->ssl_ctx, data->conn, label, out, + if (tls_connection_export_key(data->ssl_ctx, data->conn, label, 0, 0, out, len)) { os_free(out); return NULL; diff --git a/components/wpa_supplicant/src/eap_peer/mschapv2.c b/components/wpa_supplicant/src/eap_peer/mschapv2.c index 84859111ecef..0e25ba896433 100644 --- a/components/wpa_supplicant/src/eap_peer/mschapv2.c +++ b/components/wpa_supplicant/src/eap_peer/mschapv2.c @@ -14,10 +14,11 @@ const u8 * mschapv2_remove_domain(const u8 *username, size_t *len) size_t i; /* - * MSCHAPV2 does not include optional domain name in the + * MSCHAPv2 does not include optional domain name in the * challenge-response calculation, so remove domain prefix - * (if present) + * (if present). */ + for (i = 0; i < *len; i++) { if (username[i] == '\\') { *len -= i + 1; @@ -28,31 +29,48 @@ const u8 * mschapv2_remove_domain(const u8 *username, size_t *len) return username; } + int mschapv2_derive_response(const u8 *identity, size_t identity_len, - const u8 *password, size_t password_len, - int pwhash, - const u8 *auth_challenge, - const u8 *peer_challenge, - u8 *nt_response, u8 *auth_response, - u8 *master_key) + const u8 *password, size_t password_len, + int pwhash, + const u8 *auth_challenge, + const u8 *peer_challenge, + u8 *nt_response, u8 *auth_response, + u8 *master_key) { const u8 *username; size_t username_len; u8 password_hash[16], password_hash_hash[16]; + wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity", + identity, identity_len); username_len = identity_len; username = mschapv2_remove_domain(identity, &username_len); + wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username", + username, username_len); + wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge", + auth_challenge, MSCHAPV2_CHAL_LEN); + wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge", + peer_challenge, MSCHAPV2_CHAL_LEN); + wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username", + username, username_len); + /* Authenticator response is not really needed yet, but calculate it + * here so that challenges need not be saved. */ if (pwhash) { + wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash", + password, password_len); if (generate_nt_response_pwhash(auth_challenge, peer_challenge, username, username_len, password, nt_response) || generate_authenticator_response_pwhash( - password, peer_challenge, auth_challenge, - username, username_len, nt_response, - auth_response)) + password, peer_challenge, auth_challenge, + username, username_len, nt_response, + auth_response)) return -1; } else { + wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password", + password, password_len); if (generate_nt_response(auth_challenge, peer_challenge, username, username_len, password, password_len, @@ -65,7 +83,12 @@ int mschapv2_derive_response(const u8 *identity, size_t identity_len, auth_response)) return -1; } + wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response", + nt_response, MSCHAPV2_NT_RESPONSE_LEN); + wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response", + auth_response, MSCHAPV2_AUTH_RESPONSE_LEN); + /* Generate master_key here since we have the needed data available. */ if (pwhash) { if (hash_nt_password_hash(password, password_hash_hash)) return -1; @@ -76,17 +99,20 @@ int mschapv2_derive_response(const u8 *identity, size_t identity_len, } if (get_master_key(password_hash_hash, nt_response, master_key)) return -1; + wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key", + master_key, MSCHAPV2_MASTER_KEY_LEN); return 0; } + int mschapv2_verify_auth_response(const u8 *auth_response, - const u8 *buf, size_t buf_len) + const u8 *buf, size_t buf_len) { u8 recv_response[MSCHAPV2_AUTH_RESPONSE_LEN]; if (buf_len < 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN || buf[0] != 'S' || buf[1] != '=' || - hexstr2bin((char *)(buf + 2), recv_response, + hexstr2bin((char *) (buf + 2), recv_response, MSCHAPV2_AUTH_RESPONSE_LEN) || os_memcmp(auth_response, recv_response, MSCHAPV2_AUTH_RESPONSE_LEN) != 0) diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_common.c b/components/wpa_supplicant/src/esp_supplicant/esp_common.c index a2e35d679f39..2e6a85bdaea5 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_common.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_common.c @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #include "utils/includes.h" @@ -33,12 +23,12 @@ struct wpa_supplicant g_wpa_supp; -static void *s_supplicant_task_hdl = NULL; +static TaskHandle_t s_supplicant_task_hdl = NULL; static void *s_supplicant_evt_queue = NULL; static void *s_supplicant_api_lock = NULL; -static int esp_handle_action_frm(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) +static int handle_action_frm(u8 *frame, size_t len, + u8 *sender, u32 rssi, u8 channel) { struct ieee_mgmt_frame *frm = os_malloc(sizeof(struct ieee_mgmt_frame) + len); @@ -61,7 +51,7 @@ static int esp_handle_action_frm(u8 *frame, size_t len, return 0; } -static void esp_rx_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, +static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, u8 *payload, size_t len, u32 rssi) { if (payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) { @@ -78,7 +68,7 @@ static void esp_rx_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, } } -static int esp_mgmt_rx_action(u8 *sender, u8 *payload, size_t len, u8 channel, u32 rssi) +static int mgmt_rx_action(u8 *sender, u8 *payload, size_t len, u8 channel, u32 rssi) { u8 category; u8 bssid[ETH_ALEN]; @@ -95,13 +85,13 @@ static int esp_mgmt_rx_action(u8 *sender, u8 *payload, size_t len, u8 channel, u if (category == WLAN_ACTION_WNM) { ieee802_11_rx_wnm_action(wpa_s, sender, payload, len); } else if (category == WLAN_ACTION_RADIO_MEASUREMENT) { - esp_rx_rrm_frame(wpa_s, sender, payload, len, rssi); + handle_rrm_frame(wpa_s, sender, payload, len, rssi); } return 0; } -static void esp_btm_rrm_task(void *pvParameters) +static void btm_rrm_task(void *pvParameters) { supplicant_event_t *evt; bool task_del = false; @@ -120,7 +110,7 @@ static void esp_btm_rrm_task(void *pvParameters) case SIG_SUPPLICANT_RX_ACTION: { struct ieee_mgmt_frame *frm = (struct ieee_mgmt_frame *)evt->data; - esp_mgmt_rx_action(frm->sender, frm->payload, frm->len, frm->channel, frm->rssi); + mgmt_rx_action(frm->sender, frm->payload, frm->len, frm->channel, frm->rssi); os_free(frm); break; } @@ -153,7 +143,7 @@ static void esp_btm_rrm_task(void *pvParameters) vTaskDelete(NULL); } -static void esp_clear_bssid_flag(struct wpa_supplicant *wpa_s) +static void clear_bssid_flag(struct wpa_supplicant *wpa_s) { wifi_config_t *config; @@ -175,7 +165,7 @@ static void esp_clear_bssid_flag(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "cleared bssid flag"); } -static void esp_register_action_frame(struct wpa_supplicant *wpa_s) +static void register_action_frame(struct wpa_supplicant *wpa_s) { wpa_s->type &= ~(1 << WLAN_FC_STYPE_ACTION); /* subtype is defined only for action frame */ @@ -193,8 +183,8 @@ static void esp_register_action_frame(struct wpa_supplicant *wpa_s) esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); } -static void esp_supplicant_sta_conn_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) +static void supplicant_sta_conn_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { u8 bssid[ETH_ALEN]; u8 *ie; @@ -215,32 +205,64 @@ static void esp_supplicant_sta_conn_handler(void* arg, esp_event_base_t event_ba ieee802_11_parse_elems(wpa_s, ie, bss->ie_len); wpa_bss_flush(wpa_s); /* Register for action frames */ - esp_register_action_frame(wpa_s); + register_action_frame(wpa_s); /* clear set bssid flag */ - esp_clear_bssid_flag(wpa_s); + clear_bssid_flag(wpa_s); } -static void esp_supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) +static void supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { struct wpa_supplicant *wpa_s = &g_wpa_supp; + wifi_event_sta_disconnected_t *disconn = event_data; + wpas_rrm_reset(wpa_s); if (wpa_s->current_bss) { wpa_s->current_bss = NULL; } + + if (disconn->reason != WIFI_REASON_ROAMING) { + clear_bssid_flag(wpa_s); + } } -void esp_supplicant_common_init(struct wpa_funcs *wpa_cb) +static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, + u32 rssi, u8 channel, u64 current_tsf) { - struct wpa_supplicant *wpa_s = &g_wpa_supp; + if (type == WLAN_FC_STYPE_BEACON || type == WLAN_FC_STYPE_PROBE_RESP) { + return esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf); + } else if (type == WLAN_FC_STYPE_ACTION) { + return handle_action_frm(frame, len, sender, rssi, channel); + } + + return -1; +} - s_supplicant_evt_queue = xQueueCreate(3, sizeof(supplicant_event_t)); - xTaskCreate(esp_btm_rrm_task, "btm_rrm_t", SUPPLICANT_TASK_STACK_SIZE, NULL, 2, s_supplicant_task_hdl); + +int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) +{ + struct wpa_supplicant *wpa_s = &g_wpa_supp; + int ret; s_supplicant_api_lock = xSemaphoreCreateRecursiveMutex(); if (!s_supplicant_api_lock) { - wpa_printf(MSG_ERROR, "esp_supplicant_common_init: failed to create Supplicant API lock"); - return; + wpa_printf(MSG_ERROR, "%s: failed to create Supplicant API lock", __func__); + ret = -1; + goto err; + } + + s_supplicant_evt_queue = xQueueCreate(3, sizeof(supplicant_event_t)); + + if (!s_supplicant_evt_queue) { + wpa_printf(MSG_ERROR, "%s: failed to create Supplicant event queue", __func__); + ret = -1; + goto err; + } + ret = xTaskCreate(btm_rrm_task, "btm_rrm_t", SUPPLICANT_TASK_STACK_SIZE, NULL, 2, &s_supplicant_task_hdl); + if (ret != pdPASS) { + wpa_printf(MSG_ERROR, "btm: failed to create task"); + ret = -1; + goto err; } esp_scan_init(wpa_s); @@ -248,48 +270,65 @@ void esp_supplicant_common_init(struct wpa_funcs *wpa_cb) wpas_clear_beacon_rep_data(wpa_s); esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, - &esp_supplicant_sta_conn_handler, NULL); + &supplicant_sta_conn_handler, NULL); esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, - &esp_supplicant_sta_disconn_handler, NULL); + &supplicant_sta_disconn_handler, NULL); wpa_s->type = 0; wpa_s->subtype = 0; - wpa_cb->wpa_sta_rx_mgmt = esp_ieee80211_handle_rx_frm; + esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); + wpa_cb->wpa_sta_rx_mgmt = ieee80211_handle_rx_frm; + return 0; +err: + esp_supplicant_common_deinit(); + return ret; } void esp_supplicant_common_deinit(void) { struct wpa_supplicant *wpa_s = &g_wpa_supp; - if (esp_supplicant_post_evt(SIG_SUPPLICANT_DEL_TASK, 0) != 0) { - wpa_printf(MSG_ERROR, "failed to send task delete event"); - } esp_scan_deinit(wpa_s); wpas_rrm_reset(wpa_s); wpas_clear_beacon_rep_data(wpa_s); esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, - &esp_supplicant_sta_conn_handler); + &supplicant_sta_conn_handler); esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, - &esp_supplicant_sta_disconn_handler); + &supplicant_sta_disconn_handler); + if (wpa_s->type) { + wpa_s->type = 0; + esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); + } + if (!s_supplicant_task_hdl && esp_supplicant_post_evt(SIG_SUPPLICANT_DEL_TASK, 0) != 0) { + if (s_supplicant_evt_queue) { + vQueueDelete(s_supplicant_evt_queue); + s_supplicant_evt_queue = NULL; + } + if (s_supplicant_api_lock) { + vSemaphoreDelete(s_supplicant_api_lock); + s_supplicant_api_lock = NULL; + } + wpa_printf(MSG_ERROR, "failed to send task delete event"); + } } int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb, void *cb_ctx) { - struct wpa_supplicant *wpa_s = &g_wpa_supp; struct wpa_ssid_value wpa_ssid = {0}; struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal(); + os_memcpy(wpa_ssid.ssid, ssid->ssid, ssid->len); wpa_ssid.ssid_len = ssid->len; - return wpas_rrm_send_neighbor_rep_request(wpa_s, &wpa_ssid, 0, 0, cb, cb_ctx); + + return wpas_rrm_send_neighbor_rep_request(&g_wpa_supp, &wpa_ssid, 0, 0, cb, cb_ctx); } int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason, const char *btm_candidates, int cand_list) { - struct wpa_supplicant *wpa_s = &g_wpa_supp; - return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason, btm_candidates, cand_list); + return wnm_send_bss_transition_mgmt_query(&g_wpa_supp, query_reason, btm_candidates, cand_list); } void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, @@ -390,24 +429,20 @@ int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data) evt->id = evt_id; evt->data = data; - SUPPLICANT_API_LOCK(); + /* Make sure lock exists before taking it */ + if (s_supplicant_api_lock) { + SUPPLICANT_API_LOCK(); + } else { + os_free(evt); + return -1; + } if (xQueueSend(s_supplicant_evt_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) { SUPPLICANT_API_UNLOCK(); os_free(evt); return -1; } - SUPPLICANT_API_UNLOCK(); - return 0; -} - -int esp_ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf) -{ - if (type == WLAN_FC_STYPE_BEACON || type == WLAN_FC_STYPE_PROBE_RESP) { - return esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf); - } else if (type == WLAN_FC_STYPE_ACTION) { - return esp_handle_action_frm(frame, len, sender, rssi, channel); + if (evt_id != SIG_SUPPLICANT_DEL_TASK) { + SUPPLICANT_API_UNLOCK(); } - - return -1; + return 0; } diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h b/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h index 4dfe7e3d0661..9d3350fa49fd 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifndef ESP_COMMON_I_H @@ -47,11 +37,9 @@ enum SIG_SUPPLICANT { }; int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data); -int esp_ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf); void esp_set_rm_enabled_ie(void); void esp_get_tx_power(uint8_t *tx_power); -void esp_supplicant_common_init(struct wpa_funcs *wpa_cb); +int esp_supplicant_common_init(struct wpa_funcs *wpa_cb); void esp_supplicant_common_deinit(void); #else @@ -59,11 +47,6 @@ void esp_supplicant_common_deinit(void); #include "esp_wnm.h" static inline void esp_set_rm_enabled_ie(void) {} -static inline int esp_ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf) -{ - return -1; -} int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb, void *cb_ctx) { diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_dpp.c b/components/wpa_supplicant/src/esp_supplicant/esp_dpp.c index c223b170f3a2..63a638deb499 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_dpp.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_dpp.c @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "esp_dpp_i.h" #include "esp_dpp.h" @@ -20,7 +12,8 @@ #include "esp_wifi.h" #include "common/ieee802_11_defs.h" -static void *s_dpp_task_hdl = NULL; +#ifdef CONFIG_DPP +static TaskHandle_t s_dpp_task_hdl = NULL; static void *s_dpp_evt_queue = NULL; static void *s_dpp_api_lock = NULL; @@ -42,22 +35,36 @@ struct action_rx_param { static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data) { - DPP_API_LOCK(); - dpp_event_t *evt = os_zalloc(sizeof(dpp_event_t)); + int ret = ESP_OK; + if (evt == NULL) { - DPP_API_UNLOCK(); - return ESP_ERR_NO_MEM; + ret = ESP_ERR_NO_MEM; + goto end; } evt->id = evt_id; evt->data = data; - if ( xQueueSend(s_dpp_evt_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) { + if (s_dpp_api_lock) { + DPP_API_LOCK(); + } else { + ret = ESP_ERR_DPP_FAILURE; + goto end; + } + if (xQueueSend(s_dpp_evt_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) { DPP_API_UNLOCK(); + ret = ESP_ERR_DPP_FAILURE; + goto end; + } + if (evt_id != SIG_DPP_DEL_TASK) { + DPP_API_UNLOCK(); + } + + return ret; +end: + if (evt) { os_free(evt); - return ESP_ERR_DPP_FAILURE; } - DPP_API_UNLOCK(); - return ESP_OK; + return ret; } static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data) @@ -178,7 +185,6 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, os_memcpy(wifi_cfg->sta.password, conf->passphrase, sizeof(wifi_cfg->sta.password)); if (conf->akm == DPP_AKM_PSK_SAE) { - wifi_cfg->sta.pmf_cfg.capable = true; wifi_cfg->sta.pmf_cfg.required = true; } } @@ -614,6 +620,7 @@ void esp_supp_dpp_stop_listen(void) esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) { struct dpp_global_config cfg = {0}; + int ret; os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx)); s_dpp_ctx.dpp_event_cb = cb; @@ -624,10 +631,15 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) s_dpp_stop_listening = false; s_dpp_evt_queue = xQueueCreate(3, sizeof(dpp_event_t)); - xTaskCreate(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, s_dpp_task_hdl); + ret = xTaskCreate(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, &s_dpp_task_hdl); + if (ret != pdPASS) { + wpa_printf(MSG_ERROR, "DPP: failed to create task"); + return ESP_FAIL; + } s_dpp_api_lock = xSemaphoreCreateRecursiveMutex(); if (!s_dpp_api_lock) { + esp_supp_dpp_deinit(); wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock"); return ESP_ERR_NO_MEM; } @@ -655,7 +667,12 @@ void esp_supp_dpp_deinit(void) params->key = NULL; } + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, + &offchan_event_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, + &offchan_event_handler); s_dpp_auth_retries = 0; dpp_global_deinit(s_dpp_ctx.dpp_global); esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0); } +#endif diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c b/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c index ec4a2d3fa842..b798916783fc 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c @@ -124,33 +124,29 @@ bool hostap_deinit(void *data) return true; } - if (hapd->wpa_auth->wpa_ie != NULL) { - os_free(hapd->wpa_auth->wpa_ie); - } - - if (hapd->wpa_auth->group != NULL) { - os_free(hapd->wpa_auth->group); - } - if (hapd->wpa_auth != NULL) { - os_free(hapd->wpa_auth); - } + if (hapd->wpa_auth->wpa_ie != NULL) { + os_free(hapd->wpa_auth->wpa_ie); + } - if (hapd->conf->ssid.wpa_psk != NULL) { - os_free(hapd->conf->ssid.wpa_psk); - } - - if (hapd->conf->ssid.wpa_passphrase != NULL) { - os_free(hapd->conf->ssid.wpa_passphrase); + if (hapd->wpa_auth->group != NULL) { + os_free(hapd->wpa_auth->group); + } + os_free(hapd->wpa_auth); } if (hapd->conf != NULL) { + if (hapd->conf->ssid.wpa_psk != NULL) { + os_free(hapd->conf->ssid.wpa_psk); + } + + if (hapd->conf->ssid.wpa_passphrase != NULL) { + os_free(hapd->conf->ssid.wpa_passphrase); + } os_free(hapd->conf); } - if (hapd != NULL) { - os_free(hapd); - } + os_free(hapd); esp_wifi_unset_appie_internal(WIFI_APPIE_WPA); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_scan.c b/components/wpa_supplicant/src/esp_supplicant/esp_scan.c index 44cfe7be2664..4cac3b9f6725 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_scan.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_scan.c @@ -29,6 +29,7 @@ #include "common/ieee802_11_common.h" #include "esp_supplicant/esp_common_i.h" #include "common/wnm_sta.h" +#include "esp_scan_i.h" extern struct wpa_supplicant g_wpa_supp; @@ -38,11 +39,11 @@ static void scan_done_event_handler(void *arg, STATUS status) /* update last scan time */ wpa_s->scan_start_tsf = esp_wifi_get_tsf_time(WIFI_IF_STA); - if (!wpa_s->scanning) { + if (wpa_s->scanning) { wpa_s->type &= ~(1 << WLAN_FC_STYPE_BEACON) & ~(1 << WLAN_FC_STYPE_PROBE_RESP); esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); } - esp_supplicant_post_evt(SIG_SUPPLICANT_SCAN_DONE, 0); + esp_supplicant_handle_scan_done_evt(); } static void esp_supp_handle_wnm_scan_done(struct wpa_supplicant *wpa_s) diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c index beaa5b64627e..e391e214902a 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c @@ -51,6 +51,15 @@ #define DATA_MUTEX_TAKE() xSemaphoreTakeRecursive(s_wpa2_data_lock,portMAX_DELAY) #define DATA_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wpa2_data_lock) +//length of the string "fast_provisioning={0/1/2} " +#define FAST_PROVISIONING_CONFIG_STR_LEN 20 +//length of the string "fast_max_pac_list_len=(int < 100) " +#define FAST_MAX_PAC_LIST_CONFIG_STR_LEN 25 +//length of the string "fast_pac_format=binary" +#define FAST_PAC_FORMAT_STR_LEN 22 +//Total +#define PHASE1_PARAM_STRING_LEN FAST_PROVISIONING_CONFIG_STR_LEN + FAST_MAX_PAC_LIST_CONFIG_STR_LEN + FAST_PAC_FORMAT_STR_LEN + static void *s_wpa2_data_lock = NULL; static struct eap_sm *gEapSm = NULL; @@ -63,7 +72,7 @@ static int wpa2_start_eapol_internal(void); int wpa2_post(uint32_t sig, uint32_t par); #ifdef USE_WPA2_TASK -static void *s_wpa2_task_hdl = NULL; +static TaskHandle_t s_wpa2_task_hdl = NULL; static void *s_wpa2_queue = NULL; static wpa2_state_t s_wpa2_state = WPA2_STATE_DISABLED; static void *s_wpa2_api_lock = NULL; @@ -412,7 +421,8 @@ int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData) return ESP_FAIL; } - if (ehdr->identifier == sm->current_identifier) { + if (ehdr->identifier == sm->current_identifier && + sm->lastRespData != NULL) { /*Retransmit*/ resp = sm->lastRespData; goto send_resp; @@ -450,6 +460,15 @@ int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData) if (m == NULL) { goto build_nak; } + + if (!eap_sm_allowMethod(sm, reqVendor, reqVendorMethod)) { + wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", + reqVendor, reqVendorMethod); + wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD + "vendor=%u method=%u -> NAK", + reqVendor, reqVendorMethod); + goto build_nak; + } if (sm->m) { eap_deinit_prev_method(sm, "GET_METHOD"); } @@ -481,30 +500,24 @@ int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData) if (resp == NULL) { return ESP_FAIL; } - ret = ESP_FAIL; - send_resp: if (resp == NULL) { wpa_printf(MSG_ERROR, "Response build fail, return."); return ESP_FAIL; } ret = eap_sm_send_eapol(sm, resp); - if (ret == ESP_OK) { - if (resp != sm->lastRespData) { - wpabuf_free(sm->lastRespData); - sm->lastRespData = resp; - } - } else { + if (resp != sm->lastRespData) { wpabuf_free(sm->lastRespData); - sm->lastRespData = NULL; + } + if (ret != ESP_OK) { wpabuf_free(resp); resp = NULL; - if (ret == WPA_ERR_INVALID_BSSID) { ret = WPA2_ENT_EAP_STATE_FAIL; wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL); } } + sm->lastRespData = resp; out: return ret; } @@ -744,14 +757,16 @@ static int eap_peer_sm_init(void) sm = (struct eap_sm *)os_zalloc(sizeof(*sm)); if (sm == NULL) { - return ESP_ERR_NO_MEM; + ret = ESP_ERR_NO_MEM; + return ret; } + gEapSm = sm; s_wpa2_data_lock = xSemaphoreCreateRecursiveMutex(); if (!s_wpa2_data_lock) { - free(sm); wpa_printf(MSG_ERROR, "wpa2 eap_peer_sm_init: failed to alloc data lock"); - return ESP_ERR_NO_MEM; + ret = ESP_ERR_NO_MEM; + goto _err; } wpa2_set_eap_state(WPA2_ENT_EAP_STATE_NOT_START); @@ -760,53 +775,51 @@ static int eap_peer_sm_init(void) ret = eap_peer_blob_init(sm); if (ret) { wpa_printf(MSG_ERROR, "eap_peer_blob_init failed\n"); - os_free(sm); - vSemaphoreDelete(s_wpa2_data_lock); - return ESP_FAIL; + ret = ESP_FAIL; + goto _err; } ret = eap_peer_config_init(sm, g_wpa_private_key_passwd, g_wpa_private_key_passwd_len); if (ret) { wpa_printf(MSG_ERROR, "eap_peer_config_init failed\n"); - eap_peer_blob_deinit(sm); - os_free(sm); - vSemaphoreDelete(s_wpa2_data_lock); - return ESP_FAIL; + ret = ESP_FAIL; + goto _err; } sm->ssl_ctx = tls_init(); if (sm->ssl_ctx == NULL) { wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " "context."); - eap_peer_blob_deinit(sm); - eap_peer_config_deinit(sm); - os_free(sm); - vSemaphoreDelete(s_wpa2_data_lock); - return ESP_FAIL; + ret = ESP_FAIL; + goto _err; } wpa2_rxq_init(); gEapSm = sm; #ifdef USE_WPA2_TASK - s_wpa2_queue = xQueueCreate(SIG_WPA2_MAX, sizeof( void * ) ); - xTaskCreate(wpa2_task, "wpa2T", WPA2_TASK_STACK_SIZE, NULL, 2, s_wpa2_task_hdl); + s_wpa2_queue = xQueueCreate(SIG_WPA2_MAX, sizeof( s_wpa2_queue ) ); + ret = xTaskCreate(wpa2_task, "wpa2T", WPA2_TASK_STACK_SIZE, NULL, 2, &s_wpa2_task_hdl); + if (ret != pdPASS) { + wpa_printf(MSG_ERROR, "wps enable: failed to create task"); + ret = ESP_FAIL; + goto _err; + } s_wifi_wpa2_sync_sem = xSemaphoreCreateCounting(1, 0); if (!s_wifi_wpa2_sync_sem) { - vQueueDelete(s_wpa2_queue); - s_wpa2_queue = NULL; - eap_peer_blob_deinit(sm); - eap_peer_config_deinit(sm); - os_free(sm); - vSemaphoreDelete(s_wpa2_data_lock); wpa_printf(MSG_ERROR, "WPA2: failed create wifi wpa2 task sync sem"); - return ESP_FAIL; + ret = ESP_FAIL; + goto _err; } wpa_printf(MSG_INFO, "wpa2_task prio:%d, stack:%d\n", 2, WPA2_TASK_STACK_SIZE); #endif return ESP_OK; + +_err: + eap_peer_sm_deinit(); + return ret; } /** @@ -839,8 +852,8 @@ static void eap_peer_sm_deinit(void) if (s_wifi_wpa2_sync_sem) { vSemaphoreDelete(s_wifi_wpa2_sync_sem); + s_wifi_wpa2_sync_sem = NULL; } - s_wifi_wpa2_sync_sem = NULL; if (s_wpa2_data_lock) { vSemaphoreDelete(s_wpa2_data_lock); @@ -848,6 +861,10 @@ static void eap_peer_sm_deinit(void) wpa_printf(MSG_DEBUG, "wpa2 eap_peer_sm_deinit: free data lock"); } + if (s_wpa2_queue) { + vQueueDelete(s_wpa2_queue); + s_wpa2_queue = NULL; + } os_free(sm); gEapSm = NULL; } @@ -1173,3 +1190,57 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types } return ESP_OK; } + +esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int pac_file_len) +{ + if (pac_file && pac_file_len > -1) { + if (pac_file_len < 512) { // The file contains less than 1 pac and is to be rewritten later + g_wpa_pac_file = (u8 *)os_zalloc(512); + if (g_wpa_pac_file == NULL) { + return ESP_ERR_NO_MEM; + } + g_wpa_pac_file_len = 0; + } else { // The file contains pac data + g_wpa_pac_file = (u8 *)os_zalloc(pac_file_len); + if (g_wpa_pac_file == NULL) { + return ESP_ERR_NO_MEM; + } + os_memcpy(g_wpa_pac_file, pac_file, pac_file_len); + g_wpa_pac_file_len = pac_file_len; + } + } else { + return ESP_FAIL; + } + + return ESP_OK; +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config) +{ + char config_for_supplicant[PHASE1_PARAM_STRING_LEN] = ""; + if ((config.fast_provisioning > -1) && (config.fast_provisioning <= 2)) { + os_sprintf((char *) &config_for_supplicant, "fast_provisioning=%d ", config.fast_provisioning); + } else { + return ESP_ERR_INVALID_ARG; + } + if (config.fast_max_pac_list_len && config.fast_max_pac_list_len < 100) { + os_sprintf((char *) &config_for_supplicant + strlen(config_for_supplicant), "fast_max_pac_list_len=%d ", config.fast_max_pac_list_len); + } else if (config.fast_max_pac_list_len >= 100) { + return ESP_ERR_INVALID_ARG; + } + if (config.fast_pac_format_binary) { + os_strcat((char *) &config_for_supplicant, (const char *) "fast_pac_format=binary"); + } + + // Free the old buffer if it already exists + if (g_wpa_phase1_options != NULL) { + os_free(g_wpa_phase1_options); + } + g_wpa_phase1_options = (char *)os_zalloc(sizeof(config_for_supplicant)); + if (g_wpa_phase1_options == NULL) { + return ESP_ERR_NO_MEM; + } + os_memcpy(g_wpa_phase1_options, &config_for_supplicant, sizeof(config_for_supplicant)); + return ESP_OK; + +} diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c index 480ba919ffd0..7a4fc56286b6 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c @@ -227,9 +227,10 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) } #ifndef ROAMING_SUPPORT -static inline void esp_supplicant_common_init(struct wpa_funcs *wpa_cb) +static inline int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) { wpa_cb->wpa_sta_rx_mgmt = NULL; + return 0; } static inline void esp_supplicant_common_deinit(void) { @@ -268,7 +269,11 @@ int esp_supplicant_init(void) wpa_cb->wpa_config_done = wpa_config_done; esp_wifi_register_wpa3_cb(wpa_cb); - esp_supplicant_common_init(wpa_cb); + ret = esp_supplicant_common_init(wpa_cb); + + if (ret != 0) { + return ret; + } esp_wifi_register_wpa_cb_internal(wpa_cb); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wps.c b/components/wpa_supplicant/src/esp_supplicant/esp_wps.c index 0f515e7b7854..8be60431239d 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wps.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wps.c @@ -1,16 +1,8 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include @@ -84,6 +76,7 @@ void wifi_station_wps_msg_timeout_internal(void); void wifi_station_wps_success_internal(void); void wifi_wps_scan_internal(void); void wifi_station_wps_eapol_start_handle_internal(void); +void wps_add_discard_ap(u8 *bssid); struct wps_sm *gWpsSm = NULL; static wps_factory_information_t *s_factory_info = NULL; @@ -304,8 +297,8 @@ static inline int wps_sm_ether_send(struct wps_sm *sm, const u8 *dest, u16 proto void *buffer = (void *)(data - sizeof(struct l2_ethhdr)); struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer; - memcpy(eth->h_dest, dest, ETH_ALEN); - memcpy(eth->h_source, sm->ownaddr, ETH_ALEN); + os_memcpy(eth->h_dest, dest, ETH_ALEN); + os_memcpy(eth->h_source, sm->ownaddr, ETH_ALEN); eth->h_proto = host_to_be16(proto); wps_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len); @@ -335,9 +328,9 @@ u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type, hdr->length = host_to_be16(data_len); if (data) { - memcpy(hdr + 1, data, data_len); + os_memcpy(hdr + 1, data, data_len); } else { - memset(hdr + 1, 0, data_len); + os_memset(hdr + 1, 0, data_len); } if (data_pos) { @@ -388,10 +381,10 @@ struct wps_data *wps_init(void) data->registrar = 0; /* currently, we force to support enrollee only */ if (data->registrar) { - memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN); + os_memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN); } else { - memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN); - memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN); + os_memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN); + os_memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN); } if (wps_get_type() == WPS_TYPE_PIN) { @@ -411,10 +404,10 @@ struct wps_data *wps_init(void) do { char tmpp[9]; os_bzero(tmpp, 9); - memcpy(tmpp, data->dev_password, 8); + os_memcpy(tmpp, data->dev_password, 8); wpa_printf(MSG_DEBUG, "WPS PIN [%s]", tmpp); wifi_event_sta_wps_er_pin_t evt; - memcpy(evt.pin_code, data->dev_password, 8); + os_memcpy(evt.pin_code, data->dev_password, 8); esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &evt, sizeof(evt), portMAX_DELAY); } while (0); } else if (wps_get_type() == WPS_TYPE_PBC) { @@ -444,7 +437,7 @@ struct wps_data *wps_init(void) os_free(data); return NULL; } - memcpy(data->dev_password, + os_memcpy(data->dev_password, wpabuf_head(cfg->wps->ap_nfc_dev_pw), wpabuf_len(cfg->wps->ap_nfc_dev_pw)); data->dev_password_len = wpabuf_len(cfg->wps->ap_nfc_dev_pw); @@ -524,15 +517,16 @@ wps_build_ic_appie_wps_pr(void) 0, NULL); } - if (wps_ie) { - if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) { - wpabuf_put_buf(extra_ie, wps_ie); - } else { - wpabuf_free(wps_ie); - return; - } + if (!wps_ie) { + return; + } + if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) { + wpabuf_put_buf(extra_ie, wps_ie); + } else { wpabuf_free(wps_ie); + return; } + wpabuf_free(wps_ie); esp_wifi_set_appie_internal(WIFI_APPIE_WPS_PR, (uint8_t *)wpabuf_head(extra_ie), extra_ie->used, 0); wpabuf_free(extra_ie); @@ -564,6 +558,10 @@ wps_parse_scan_result(struct wps_scan_ie *scan) wpa_printf(MSG_DEBUG, "wps parse scan: %s", tmp); #endif + if (!sm->is_wps_scan || !scan->bssid) { + return false; + } + if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING) @@ -571,38 +569,55 @@ wps_parse_scan_result(struct wps_scan_ie *scan) return false; } + if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) { + wpa_printf(MSG_INFO, "WEP not suppported in WPS"); + return false; + } + + if (sm->wps_pin_war) { + /* We have selected candidate for this scan */ + return false; + } + esp_wifi_get_mode(&op_mode); if ((op_mode == WIFI_MODE_STA || op_mode == WIFI_MODE_APSTA) && scan->wps) { + bool ap_found = false; + int count; struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4); - if (wps_is_selected_pbc_registrar(buf, scan->bssid) - || wps_is_selected_pin_registrar(buf, scan->bssid)) { - wpabuf_free(buf); - - if (sm->is_wps_scan == false) { - return false; - } - if (memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0 ) { - sm->discover_ssid_cnt++; - } - - if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) { - wpa_printf(MSG_ERROR, "WEP not suppported in WPS"); - - return false; + if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) || + (wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) { + /* Found one AP with selected registrar true */ + sm->ignore_sel_reg = false; + sm->discard_ap_cnt = 0; + ap_found = true; + } + if ((op_mode == WIFI_MODE_STA || op_mode == WIFI_MODE_APSTA) && + wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) { + /* AP is in discard list? */ + for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) { + if (os_memcmp(sm->dis_ap_list[count].bssid, scan->bssid, ETH_ALEN) == 0) { + wpa_printf(MSG_INFO, "discard ap bssid "MACSTR, MAC2STR(scan->bssid)); + return false; + } } + sm->wps_pin_war = true; + } + if (ap_found || sm->wps_pin_war) { + wpabuf_free(buf); esp_wifi_enable_sta_privacy_internal(); + os_memset(sm->config.ssid, 0, sizeof(sm->config.ssid)); strncpy((char *)sm->config.ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]); - if (scan->bssid) { - memcpy(gWpsSm->bssid, scan->bssid, ETH_ALEN); - memcpy(sm->config.bssid, scan->bssid, ETH_ALEN); + if (scan->bssid && memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0) { + wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR "\n", + MAC2STR(sm->config.bssid), MAC2STR(scan->bssid)); + sm->discover_ssid_cnt++; + os_memcpy(sm->bssid, scan->bssid, ETH_ALEN); + os_memcpy(sm->config.bssid, scan->bssid, ETH_ALEN); sm->config.bssid_set = 1; - } else { } wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->config.ssid); - sm->scan_cnt = 0; - sm->channel = scan->chan; return true; @@ -633,7 +648,8 @@ int wps_send_eap_identity_rsp(u8 id) ret = esp_wifi_get_assoc_bssid_internal(bssid); if (ret != 0) { wpa_printf(MSG_ERROR, "bssid is empty!"); - return ESP_FAIL; + ret = ESP_FAIL; + goto _err; } wpabuf_put_data(eap_buf, sm->identity, sm->identity_len); @@ -968,13 +984,6 @@ int wps_finish(void) } if (sm->wps->state == WPS_FINISHED) { - wifi_config_t *config = (wifi_config_t *)os_zalloc(sizeof(wifi_config_t)); - - if (config == NULL) { - wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL; - esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), portMAX_DELAY); - return ESP_FAIL; - } wpa_printf(MSG_DEBUG, "wps finished------>"); wps_set_status(WPS_STATUS_SUCCESS); @@ -983,10 +992,18 @@ int wps_finish(void) ets_timer_disarm(&sm->wps_msg_timeout_timer); if (sm->ap_cred_cnt == 1) { - memset(config, 0x00, sizeof(wifi_sta_config_t)); - memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]); - memcpy(config->sta.password, sm->key[0], sm->key_len[0]); - memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); + wifi_config_t *config = (wifi_config_t *)os_zalloc(sizeof(wifi_config_t)); + + if (config == NULL) { + wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL; + esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), portMAX_DELAY); + return ESP_FAIL; + } + + os_memset(config, 0x00, sizeof(wifi_sta_config_t)); + os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]); + os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]); + os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); config->sta.bssid_set = 0; esp_wifi_set_config(0, config); @@ -998,9 +1015,16 @@ int wps_finish(void) ret = 0; } else { - wpa_printf(MSG_ERROR, "wps failed----->"); - - ret = wps_stop_process(WPS_FAIL_REASON_NORMAL); + wpa_printf(MSG_ERROR, "wps failed-----> wps_pin_war=%d", sm->wps_pin_war); + if (sm->wps_pin_war) { + sm->discover_ssid_cnt = 0; + esp_wifi_disconnect(); + os_bzero(sm->ssid, sizeof(sm->ssid)); + os_bzero(sm->ssid_len, sizeof(sm->ssid_len)); + wps_add_discard_ap(sm->config.bssid); + } else { + ret = wps_stop_process(WPS_FAIL_REASON_NORMAL); + } } return ret; @@ -1020,11 +1044,12 @@ void wps_add_discard_ap(u8 *bssid) sm->discard_ap_cnt++; } else { for (cnt = 0; cnt < WPS_MAX_DIS_AP_NUM - 2; cnt++) { - memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6); + os_memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6); } sm->discard_ap_cnt = WPS_MAX_DIS_AP_NUM; } - memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6); + os_memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6); + wpa_printf(MSG_INFO, "Added BSSID:"MACSTR" to discard list cnt=%d" , MAC2STR(bssid), sm->discard_ap_cnt); } int wps_start_msg_timer(void) @@ -1089,9 +1114,9 @@ int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) os_free(param); return ESP_ERR_NO_MEM; } - memcpy(param->buf, buf, len); + os_memcpy(param->buf, buf, len); param->len = len; - memcpy(param->sa, src_addr, WPS_ADDR_LEN); + os_memcpy(param->sa, src_addr, WPS_ADDR_LEN); wps_rxq_enqueue(param); return wps_post(SIG_WPS_RX, 0); @@ -1241,7 +1266,10 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len) break; } out: - if (ret != 0 || res == WPS_FAILURE) { + if (ret != 0 && sm->wps_pin_war) { + sm->wps_pin_war = 0; + wifi_wps_scan(); + } else if ((ret != 0 || res == WPS_FAILURE)) { wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL; wpa_printf(MSG_DEBUG, "wpa rx eapol internal: fail ret=%d", ret); wps_set_status(WPS_STATUS_DISABLE); @@ -1284,19 +1312,19 @@ int wps_set_factory_info(const esp_wps_config_t *config) } if (config->factory_info.manufacturer[0] != 0) { - memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1); + os_memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1); } if (config->factory_info.model_number[0] != 0) { - memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1); + os_memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1); } if (config->factory_info.model_name[0] != 0) { - memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1); + os_memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1); } if (config->factory_info.device_name[0] != 0) { - memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1); + os_memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1); } wpa_printf(MSG_INFO, "manufacturer: %s, model number: %s, model name: %s, device name: %s", s_factory_info->manufacturer, @@ -1376,11 +1404,14 @@ int wps_dev_init(void) sm->ownaddr[3], sm->ownaddr[4], sm->ownaddr[5]); uuid_gen_mac_addr(sm->ownaddr, sm->uuid); - memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN); + os_memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN); return ESP_OK; _out: + if (!dev) { + return ret; + } if (dev->manufacturer) { os_free(dev->manufacturer); } @@ -1468,7 +1499,6 @@ void wifi_station_wps_msg_timeout_internal(void) { struct wps_sm *sm = gWpsSm; - if (!sm) { return; } @@ -1476,11 +1506,22 @@ wifi_station_wps_msg_timeout_internal(void) if (sm->wps->state == WPS_FINISHED) { wpa_printf(MSG_DEBUG, "wps msg timeout WPS_FINISHED"); wps_finish(); + return; } else if (sm->wps->state == RECV_M2) { wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2"); wpa_printf(MSG_DEBUG, "wps recev m2/m2d timeout------>"); + if (!sm->wps_pin_war) { + wps_stop_process(WPS_FAIL_REASON_RECV_M2D); + } + } + if (sm->wps_pin_war) { + esp_wifi_disconnect(); wps_add_discard_ap(sm->config.bssid); - wps_stop_process(WPS_FAIL_REASON_RECV_M2D); + sm->wps_pin_war = 0; + os_bzero(sm->ssid, sizeof(sm->ssid)); + os_bzero(sm->ssid_len, sizeof(sm->ssid_len)); + sm->discover_ssid_cnt = 0; + wifi_wps_scan(); } } @@ -1559,23 +1600,24 @@ wifi_station_wps_init(void) gWpsSm = (struct wps_sm *)os_zalloc(sizeof(struct wps_sm)); /* alloc Wps_sm */ if (!gWpsSm) { - goto _err; + goto _out; } sm = gWpsSm; - memset(sm, 0x00, sizeof(struct wps_sm)); + os_memset(sm, 0x00, sizeof(struct wps_sm)); esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac); - memcpy(sm->ownaddr, mac, ETH_ALEN); + os_memcpy(sm->ownaddr, mac, ETH_ALEN); sm->discover_ssid_cnt = 0; sm->ignore_sel_reg = false; sm->discard_ap_cnt = 0; - memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t)); - memset(&sm->config, 0x00, sizeof(wifi_sta_config_t)); + os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t)); + os_memset(&sm->config, 0x00, sizeof(wifi_sta_config_t)); sm->eapol_version = 0x1; sm->identity_len = 29; - memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len); + os_memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len); + sm->wps_pin_war = false; sm->is_wps_scan = false; @@ -1644,10 +1686,8 @@ wifi_station_wps_init(void) wps_deinit(); sm->wps = NULL; } - if (sm) { - os_free(gWpsSm); - gWpsSm = NULL; - } + os_free(gWpsSm); + gWpsSm = NULL; return ESP_FAIL; _out: return ESP_FAIL; @@ -1700,10 +1740,8 @@ wifi_station_wps_deinit(void) wps_deinit(); sm->wps = NULL; } - if (sm) { - os_free(gWpsSm); - gWpsSm = NULL; - } + os_free(gWpsSm); + gWpsSm = NULL; return ESP_OK; } @@ -1734,14 +1772,14 @@ wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx) return ESP_FAIL; } - memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx])); - memcpy(gWpsSm->ssid[idx], ssid, ssid_len); + os_memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx])); + os_memcpy(gWpsSm->ssid[idx], ssid, ssid_len); gWpsSm->ssid_len[idx] = ssid_len; gWpsSm->ap_cred_cnt++; tmpssid = (u8 *)os_zalloc(ssid_len + 1); if (tmpssid) { - memcpy(tmpssid, ssid, ssid_len); + os_memcpy(tmpssid, ssid, ssid_len); wpa_printf(MSG_DEBUG, "WPS: key[%s]", tmpssid); os_free(tmpssid); } @@ -1757,13 +1795,13 @@ wps_key_save(char *key, u8 key_len, u8 idx) return ESP_FAIL; } - memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx])); - memcpy(gWpsSm->key[idx], key, key_len); + os_memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx])); + os_memcpy(gWpsSm->key[idx], key, key_len); gWpsSm->key_len[idx] = key_len; tmpkey = (u8 *)os_zalloc(key_len + 1); if (tmpkey) { - memcpy(tmpkey, key, key_len); + os_memcpy(tmpkey, key, key_len); wpa_printf(MSG_DEBUG, "WPS: key[%s], idx - %d", tmpkey, idx); os_free(tmpkey); } @@ -1776,6 +1814,7 @@ wifi_wps_scan_done(void *arg, STATUS status) struct wps_sm *sm = gWpsSm; wifi_config_t wifi_config; + wpa_printf(MSG_INFO, "WPS: scan done"); if (wps_get_type() == WPS_TYPE_DISABLE) { return; } @@ -1801,14 +1840,17 @@ wifi_wps_scan_done(void *arg, STATUS status) if (wps_get_status() == WPS_STATUS_PENDING) { esp_wifi_disconnect(); - memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t)); + os_memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t)); esp_wifi_set_config(0, &wifi_config); wpa_printf(MSG_DEBUG, "WPS: neg start"); esp_wifi_connect(); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + ets_timer_arm(&sm->wps_msg_timeout_timer, 2000, 0); } else if (wps_get_status() == WPS_STATUS_SCANNING) { - if (sm->scan_cnt < WPS_IGNORE_SEL_REG_MAX_CNT) { + if (wps_get_type() == WPS_TYPE_PIN && sm->scan_cnt > WPS_IGNORE_SEL_REG_MAX_CNT) { sm->ignore_sel_reg = true; + sm->wps_pin_war = false; } ets_timer_arm(&sm->wps_scan_timer, 100, 0); } else { @@ -1869,6 +1911,8 @@ int wifi_station_wps_start(void) default: break; } + sm->discard_ap_cnt = 0; + os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t)); esp_wifi_set_wps_start_flag_internal(true); return ESP_OK; } @@ -1895,12 +1939,6 @@ int wps_task_deinit(void) wpa_printf(MSG_DEBUG, "wps task deinit: free queue"); } - if (s_wps_task_hdl) { - vTaskDelete(s_wps_task_hdl); - s_wps_task_hdl = NULL; - wpa_printf(MSG_DEBUG, "wps task deinit: free task"); - } - if (STAILQ_FIRST(&s_wps_rxq) != NULL){ wps_rxq_deinit(); } @@ -1941,7 +1979,7 @@ int wps_task_init(void) } os_bzero(s_wps_sig_cnt, SIG_WPS_NUM); - s_wps_queue = xQueueCreate(SIG_WPS_NUM, sizeof( void * ) ); + s_wps_queue = xQueueCreate(SIG_WPS_NUM, sizeof(s_wps_queue) ); if (!s_wps_queue) { wpa_printf(MSG_ERROR, "wps task init: failed to alloc queue"); goto _wps_no_mem; diff --git a/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c b/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c index 00c1bad29071..1a4585b6b64a 100644 --- a/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c +++ b/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c @@ -431,7 +431,7 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, network_ctx, bssid); if (sm->cur_pmksa) { - wpa_hexdump(MSG_ERROR, "RSN: PMKSA cache entry found - PMKID", + wpa_hexdump(MSG_DEBUG, "RSN: PMKSA cache entry found - PMKID", sm->cur_pmksa->pmkid, PMKID_LEN); return 0; } @@ -513,7 +513,10 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry, .dispatch_method = ESP_TIMER_TASK, .name = "pmksa_timeout_timer" }; - esp_timer_create(&pmksa_cache_timeout_timer_create, &(pmksa->cache_timeout_timer)); + if (esp_timer_create(&pmksa_cache_timeout_timer_create, &(pmksa->cache_timeout_timer)) != ESP_OK) { + os_free(pmksa); + pmksa = NULL; + } } return pmksa; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 99246a166ab2..d98eb7a7d605 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -1,4 +1,3 @@ - /* * WPA Supplicant - WPA state machine and EAPOL-Key processing * Copyright (c) 2003-2010, Jouni Malinen @@ -12,6 +11,7 @@ * * See README and COPYING for more details. */ + #include "utils/includes.h" #include "utils/common.h" @@ -2214,7 +2214,9 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len) if (esp_wifi_sta_get_reset_param_internal() != 0) { // check it's psk if (strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) { - hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN); + if (hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN) != 0) { + return; + } } else { pbkdf2_sha1((char *)esp_wifi_sta_get_prof_password_internal(), sta_ssid->ssid, (size_t)sta_ssid->len, 4096, esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN); diff --git a/components/wpa_supplicant/src/tls/libtommath.h b/components/wpa_supplicant/src/tls/libtommath.h index ea651db3ec8b..c3f5eee39e41 100644 --- a/components/wpa_supplicant/src/tls/libtommath.h +++ b/components/wpa_supplicant/src/tls/libtommath.h @@ -1653,7 +1653,7 @@ mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) } /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { return res; } diff --git a/components/wpa_supplicant/src/tls/tls.h b/components/wpa_supplicant/src/tls/tls.h index a3f42231fe8b..9a09fb2bb7da 100644 --- a/components/wpa_supplicant/src/tls/tls.h +++ b/components/wpa_supplicant/src/tls/tls.h @@ -82,6 +82,8 @@ struct tls_config { #define TLS_CONN_DISABLE_SESSION_TICKET BIT(2) #define TLS_CONN_REQUEST_OCSP BIT(3) #define TLS_CONN_REQUIRE_OCSP BIT(4) +#define TLS_CONN_SUITEB BIT(11) +#define TLS_CONN_EAP_FAST BIT(7) /** * struct tls_connection_params - Parameters for TLS connection @@ -278,17 +280,23 @@ int __must_check tls_global_set_verify(void *tls_ctx, int check_crl); * @tls_ctx: TLS context data from tls_init() * @conn: Connection context data from tls_connection_init() * @verify_peer: 1 = verify peer certificate + * @flags: Connection flags (TLS_CONN_*) + * @session_ctx: Session caching context or %NULL to use default + * @session_ctx_len: Length of @session_ctx in bytes. * Returns: 0 on success, -1 on failure */ -int __must_check tls_connection_set_verify(void *tls_ctx, +int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, - int verify_peer); + int verify_peer, + unsigned int flags, + const u8 *session_ctx, + size_t session_ctx_len); /** * tls_connection_get_random - Get random data from TLS connection * @tls_ctx: TLS context data from tls_init() * @conn: Connection context data from tls_connection_init() - * @keys: Structure of key/random data (filled on success) + * @data: Structure of client/server random data (filled on success) * Returns: 0 on success, -1 on failure */ int __must_check tls_connection_get_random(void *tls_ctx, @@ -300,17 +308,39 @@ int __must_check tls_connection_get_random(void *tls_ctx, * @tls_ctx: TLS context data from tls_init() * @conn: Connection context data from tls_connection_init() * @label: Label (e.g., description of the key) for PRF + * @context: Optional extra upper-layer context (max len 2^16) + * @context_len: The length of the context value * @out: Buffer for output data from TLS-PRF * @out_len: Length of the output buffer * Returns: 0 on success, -1 on failure * - * Exports keying material using the mechanism described in RFC 5705. + * Exports keying material using the mechanism described in RFC 5705. If + * context is %NULL, context is not provided; otherwise, context is provided + * (including the case of empty context with context_len == 0). */ int __must_check tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, const char *label, + const u8 *context, + size_t context_len, u8 *out, size_t out_len); +/** + * tls_connection_get_eap_fast_key - Derive key material for EAP-FAST + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @out: Buffer for output data from TLS-PRF + * @out_len: Length of the output buffer + * Returns: 0 on success, -1 on failure + * + * Exports key material after the normal TLS key block for use with + * EAP-FAST. Most callers will want tls_connection_export_key(), but EAP-FAST + * uses a different legacy mechanism. + */ +int __must_check tls_connection_get_eap_fast_key(void *tls_ctx, + struct tls_connection *conn, + u8 *out, size_t out_len); + /** * tls_connection_handshake - Process TLS handshake (client side) * @tls_ctx: TLS context data from tls_init() @@ -412,7 +442,9 @@ enum { TLS_CIPHER_RC4_SHA /* 0x0005 */, TLS_CIPHER_AES128_SHA /* 0x002f */, TLS_CIPHER_RSA_DHE_AES128_SHA /* 0x0031 */, - TLS_CIPHER_ANON_DH_AES128_SHA /* 0x0034 */ + TLS_CIPHER_ANON_DH_AES128_SHA /* 0x0034 */, + TLS_CIPHER_RSA_DHE_AES256_SHA /* 0x0039 */, + TLS_CIPHER_AES256_SHA /* 0x0035 */, }; /** diff --git a/components/wpa_supplicant/src/tls/tls_internal.c b/components/wpa_supplicant/src/tls/tls_internal.c index c0b237a89ca0..1db85731c2d3 100644 --- a/components/wpa_supplicant/src/tls/tls_internal.c +++ b/components/wpa_supplicant/src/tls/tls_internal.c @@ -267,7 +267,8 @@ int tls_global_set_verify(void *tls_ctx, int check_crl) int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, - int verify_peer) + int verify_peer, unsigned int flags, + const u8 *session_ctx, size_t session_ctx_len) { #ifdef CONFIG_TLS_INTERNAL_SERVER if (conn->server) @@ -276,6 +277,7 @@ int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, return -1; } + int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, struct tls_random *data) { @@ -290,6 +292,7 @@ int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, return -1; } + static int tls_get_keyblock_size(struct tls_connection *conn) { #ifdef CONFIG_TLS_INTERNAL_CLIENT @@ -303,8 +306,10 @@ static int tls_get_keyblock_size(struct tls_connection *conn) return -1; } + static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, - const char *label, int server_random_first, + const char *label, const u8 *context, + size_t context_len, int server_random_first, int skip_keyblock, u8 *out, size_t out_len) { int ret = -1, skip = 0; @@ -320,33 +325,46 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, return -1; _out = tmp_out; } + #ifdef CONFIG_TLS_INTERNAL_CLIENT if (conn->client) { ret = tlsv1_client_prf(conn->client, label, - server_random_first, - out, out_len); + server_random_first, + _out, skip + out_len); } #endif /* CONFIG_TLS_INTERNAL_CLIENT */ #ifdef CONFIG_TLS_INTERNAL_SERVER if (conn->server) { ret = tlsv1_server_prf(conn->server, label, - server_random_first, - out, out_len); + server_random_first, + _out, skip + out_len); } #endif /* CONFIG_TLS_INTERNAL_SERVER */ if (ret == 0 && skip_keyblock) os_memcpy(out, _out + skip, out_len); - wpa_bin_clear_free(tmp_out, skip); + bin_clear_free(tmp_out, skip); return ret; } + int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, - const char *label, u8 *out, size_t out_len) + const char *label, const u8 *context, + size_t context_len, u8 *out, size_t out_len) { - return tls_connection_prf(tls_ctx, conn, label, 0, 0, out, out_len); + return tls_connection_prf(tls_ctx, conn, label, context, context_len, + 0, 0, out, out_len); } + +int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, + u8 *out, size_t out_len) +{ + return tls_connection_prf(tls_ctx, conn, "key expansion", NULL, 0, + 1, 1, out, out_len); +} + + struct wpabuf * tls_connection_handshake(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data, diff --git a/components/wpa_supplicant/src/utils/wpabuf.c b/components/wpa_supplicant/src/utils/wpabuf.c index f6d33da717d7..17ebdafc5fa5 100644 --- a/components/wpa_supplicant/src/utils/wpabuf.c +++ b/components/wpa_supplicant/src/utils/wpabuf.c @@ -1,6 +1,6 @@ /* * Dynamic data buffer - * Copyright (c) 2007-2009, Jouni Malinen + * Copyright (c) 2007-2012, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -72,12 +72,12 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len) if (buf->used + add_len > buf->size) { unsigned char *nbuf; - if (buf->ext_data) { - nbuf = (unsigned char*)os_realloc(buf->ext_data, buf->used + add_len); + if (buf->flags & WPABUF_FLAG_EXT_DATA) { + nbuf = os_realloc(buf->buf, buf->used + add_len); if (nbuf == NULL) return -1; memset(nbuf + buf->used, 0, add_len); - buf->ext_data = nbuf; + buf->buf = nbuf; } else { #ifdef WPA_TRACE nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) + @@ -99,6 +99,7 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len) memset(nbuf + sizeof(struct wpabuf) + buf->used, 0, add_len); #endif /* WPA_TRACE */ + buf->buf = (u8 *) (buf + 1); *_buf = buf; } buf->size = buf->used + add_len; @@ -130,6 +131,7 @@ struct wpabuf * wpabuf_alloc(size_t len) #endif /* WPA_TRACE */ buf->size = len; + buf->buf = (u8 *) (buf + 1); return buf; } @@ -151,7 +153,8 @@ struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len) buf->size = len; buf->used = len; - buf->ext_data = data; + buf->buf = data; + buf->flags |= WPABUF_FLAG_EXT_DATA; return buf; } @@ -191,17 +194,28 @@ void wpabuf_free(struct wpabuf *buf) trace->magic); abort(); } - os_free(buf->ext_data); + if (buf->flags & WPABUF_FLAG_EXT_DATA) + os_free(buf->buf); os_free(trace); #else /* WPA_TRACE */ if (buf == NULL) return; - os_free(buf->ext_data); + if (buf->flags & WPABUF_FLAG_EXT_DATA) + os_free(buf->buf); os_free(buf); #endif /* WPA_TRACE */ } +void wpabuf_clear_free(struct wpabuf *buf) +{ + if (buf) { + os_memset(wpabuf_mhead(buf), 0, wpabuf_len(buf)); + wpabuf_free(buf); + } +} + + void * wpabuf_put(struct wpabuf *buf, size_t len) { void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf); diff --git a/components/wpa_supplicant/src/wps/wps.c b/components/wpa_supplicant/src/wps/wps.c index 11259cc799b9..c505a020318f 100644 --- a/components/wpa_supplicant/src/wps/wps.c +++ b/components/wpa_supplicant/src/wps/wps.c @@ -67,11 +67,12 @@ struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code) * @msg: WPS IE contents from Beacon or Probe Response frame * Returns: 1 if PBC Registrar is active, 0 if not */ -int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid) +int wps_is_selected_pbc_registrar(const struct wpabuf *msg) { - struct wps_sm *sm = wps_sm_get(); struct wps_parse_attr *attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr)); - int i = 0; + + if (!attr) + return 0; /* * In theory, this could also verify that attr.sel_reg_config_methods @@ -80,33 +81,23 @@ int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid) * it is safer to just use Device Password ID here. */ - if (wps_parse_msg(msg, attr) < 0) { - os_free(attr); - return 0; + if (wps_parse_msg(msg, attr) < 0 || + !attr->selected_registrar || *attr->selected_registrar == 0 || + !attr->dev_password_id || + WPA_GET_BE16(attr->dev_password_id) != DEV_PW_PUSHBUTTON) { + os_free(attr); + return 0; } - if(!attr->selected_registrar || *attr->selected_registrar == 0) { - if (sm->ignore_sel_reg == false) { - os_free(attr); - return 0; - } - else { - for (i = 0; i < WPS_MAX_DIS_AP_NUM; i++) { - if (0 == os_memcmp(sm->dis_ap_list[i].bssid, bssid, 6)) { - wpa_printf(MSG_DEBUG, "discard ap bssid[%02x:%02x:%02x:%02x:%02x:%02x]\n", \ - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - os_free(attr); - return 0; - } - } - } - } - if (!attr->dev_password_id || - WPA_GET_BE16(attr->dev_password_id) != DEV_PW_PUSHBUTTON) { - os_free(attr); - return 0; +#ifdef CONFIG_WPS_STRICT + if (!attr->sel_reg_config_methods || + !(WPA_GET_BE16(attr->sel_reg_config_methods) & + WPS_CONFIG_PUSHBUTTON)) { + os_free(attr); + return 0; } +#endif /* CONFIG_WPS_STRICT */ os_free(attr); return 1; @@ -114,14 +105,8 @@ int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid) #ifdef CONFIG_WPS_PIN -static int is_selected_pin_registrar(struct wps_parse_attr *attr, u8 *bssid) +static int is_selected_pin_registrar(struct wps_parse_attr *attr) { - struct wps_sm *sm = wps_sm_get(); - int i = 0; - - if (!sm || !bssid){ - return 0; - } /* * In theory, this could also verify that attr.sel_reg_config_methods * includes WPS_CONFIG_LABEL, WPS_CONFIG_DISPLAY, or WPS_CONFIG_KEYPAD, @@ -131,27 +116,19 @@ static int is_selected_pin_registrar(struct wps_parse_attr *attr, u8 *bssid) */ if (!attr->selected_registrar || *attr->selected_registrar == 0) { - if (sm->ignore_sel_reg == false) { - return 0; - } - else { - for (i = 0; i < WPS_MAX_DIS_AP_NUM; i++) { - if (0 == os_memcmp(sm->dis_ap_list[i].bssid, bssid, 6)) { - wpa_printf(MSG_DEBUG, "discard ap bssid[%02x:%02x:%02x:%02x:%02x:%02x]\n", \ - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - return 0; - } - } - } + return 0; } if (attr->dev_password_id != NULL && WPA_GET_BE16(attr->dev_password_id) == DEV_PW_PUSHBUTTON) { return 0; } #ifdef CONFIG_WPS_STRICT - if (!attr->sel_reg_config_methods) + if (!attr->sel_reg_config_methods || + !(WPA_GET_BE16(attr->sel_reg_config_methods) & + (WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD))) return 0; #endif /* CONFIG_WPS_STRICT */ + return 1; } @@ -161,7 +138,7 @@ static int is_selected_pin_registrar(struct wps_parse_attr *attr, u8 *bssid) * @msg: WPS IE contents from Beacon or Probe Response frame * Returns: 1 if PIN Registrar is active, 0 if not */ -int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid) +int wps_is_selected_pin_registrar(const struct wpabuf *msg) { struct wps_parse_attr *attr; int ret; @@ -175,7 +152,7 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid) return 0; } - ret = is_selected_pin_registrar(attr, bssid); + ret = is_selected_pin_registrar(attr); os_free(attr); return ret; @@ -193,20 +170,15 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid) int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, int ver1_compat) { - struct wps_sm *sm = wps_sm_get(); struct wps_parse_attr *attr; int ret = 0; unsigned int i; const u8 *pos; const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - if (!sm){ - return -10; - } - attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr)); if (attr == NULL) { - ret = -99; + ret = 0; goto _out; } @@ -222,7 +194,7 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, */ #ifdef CONFIG_WPS_PIN - ret = is_selected_pin_registrar(attr, sm->config.bssid); + ret = is_selected_pin_registrar(attr); goto _out; #endif } diff --git a/components/wpa_supplicant/src/wps/wps.h b/components/wpa_supplicant/src/wps/wps.h index d66b42218a1b..416434045027 100644 --- a/components/wpa_supplicant/src/wps/wps.h +++ b/components/wpa_supplicant/src/wps/wps.h @@ -233,8 +233,8 @@ enum wps_process_res wps_process_msg(struct wps_data *wps, struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code); -int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid); -int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid); +int wps_is_selected_pbc_registrar(const struct wpabuf *msg); +int wps_is_selected_pin_registrar(const struct wpabuf *msg); int wps_ap_priority_compar(const struct wpabuf *wps_a, const struct wpabuf *wps_b); int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, @@ -1054,6 +1054,7 @@ struct wps_sm { #endif u8 discover_ssid_cnt; bool ignore_sel_reg; + bool wps_pin_war; struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM]; u8 discard_ap_cnt; wifi_sta_config_t config; diff --git a/components/wpa_supplicant/src/wps/wps_registrar.c b/components/wpa_supplicant/src/wps/wps_registrar.c index 2a13b3bbb354..55215477d5da 100644 --- a/components/wpa_supplicant/src/wps/wps_registrar.c +++ b/components/wpa_supplicant/src/wps/wps_registrar.c @@ -1652,7 +1652,7 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg) os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len); // NOLINT(clang-analyzer-unix.Malloc) wps->cred.key_len = wps->new_psk_len; } else if (wps->use_psk_key && wps->wps->psk_set) { - char hex[65]; + char hex[65] = {0}; wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key"); os_memcpy(wps->cred.key, hex, 32 * 2); wps->cred.key_len = 32 * 2; diff --git a/components/wpa_supplicant/test/test_sae.c b/components/wpa_supplicant/test/test_sae.c index e0d99825e97f..e323ad3162dd 100644 --- a/components/wpa_supplicant/test/test_sae.c +++ b/components/wpa_supplicant/test/test_sae.c @@ -1,16 +1,8 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifdef CONFIG_WPA3_SAE @@ -36,6 +28,7 @@ static struct wpabuf *wpabuf_alloc2(size_t len) if (buf == NULL) return NULL; buf->size = len; + buf->buf = (u8 *)(buf+1); return buf; } @@ -47,7 +40,6 @@ void wpabuf_free2(struct wpabuf *buf) { if (buf == NULL) return; - os_free(buf->ext_data); os_free(buf); } diff --git a/components/xtensa/CMakeLists.txt b/components/xtensa/CMakeLists.txt index 3fa959a936d0..1511fb5d5af7 100644 --- a/components/xtensa/CMakeLists.txt +++ b/components/xtensa/CMakeLists.txt @@ -18,9 +18,6 @@ else() "${target}/trax_init.c" ) - if(IDF_TARGET STREQUAL "esp32s2") - list(APPEND srcs "stdatomic.c") - endif() endif() idf_component_register(SRCS ${srcs} diff --git a/components/xtensa/linker.lf b/components/xtensa/linker.lf index 148116f1a1bd..5227ce02df80 100644 --- a/components/xtensa/linker.lf +++ b/components/xtensa/linker.lf @@ -3,8 +3,6 @@ archive: libxtensa.a entries: eri (noflash_text) xtensa_intr_asm (noflash_text) - if IDF_TARGET_ESP32S2 = y: - stdatomic (noflash) [mapping:xt_hal] archive: libxt_hal.a diff --git a/components/xtensa/stdatomic.c b/components/xtensa/stdatomic.c deleted file mode 100644 index 4dc425c502d3..000000000000 --- a/components/xtensa/stdatomic.c +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//replacement for gcc built-in functions - -#include "sdkconfig.h" -#include -#include "xtensa/config/core-isa.h" -#include "xtensa/xtruntime.h" - -//reserved to measure atomic operation time -#define atomic_benchmark_intr_disable() -#define atomic_benchmark_intr_restore(STATE) - -// This allows nested interrupts disabling and restoring via local registers or stack. -// They can be called from interrupts too. -// WARNING: Only applies to current CPU. -#define _ATOMIC_ENTER_CRITICAL(void) ({ \ - unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); \ - atomic_benchmark_intr_disable(); \ - state; \ -}) - -#define _ATOMIC_EXIT_CRITICAL(state) do { \ - atomic_benchmark_intr_restore(state); \ - XTOS_RESTORE_JUST_INTLEVEL(state); \ - } while (0) - -#define ATOMIC_EXCHANGE(n, type) type __atomic_exchange_ ## n (type* mem, type val, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *mem; \ - *mem = val; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define CMP_EXCHANGE(n, type) bool __atomic_compare_exchange_ ## n (type* mem, type* expect, type desired, int success, int failure) \ -{ \ - bool ret = false; \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - if (*mem == *expect) { \ - ret = true; \ - *mem = desired; \ - } else { \ - *expect = *mem; \ - } \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_ADD(n, type) type __atomic_fetch_add_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr + value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_SUB(n, type) type __atomic_fetch_sub_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr - value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_AND(n, type) type __atomic_fetch_and_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr & value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_OR(n, type) type __atomic_fetch_or_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr | value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_XOR(n, type) type __atomic_fetch_xor_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr ^ value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define SYNC_FETCH_OP(op, n, type) type __sync_fetch_and_ ## op ##_ ## n (type* ptr, type value, ...) \ -{ \ - return __atomic_fetch_ ## op ##_ ## n (ptr, value, __ATOMIC_SEQ_CST); \ -} - -#define SYNC_BOOL_CMP_EXCHANGE(n, type) bool __sync_bool_compare_and_swap_ ## n (type *ptr, type oldval, type newval, ...) \ -{ \ - bool ret = false; \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - if (*ptr == oldval) { \ - *ptr = newval; \ - ret = true; \ - } \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define SYNC_VAL_CMP_EXCHANGE(n, type) type __sync_val_compare_and_swap_ ## n (type *ptr, type oldval, type newval, ...) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - if (*ptr == oldval) { \ - *ptr = newval; \ - } \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#ifndef XCHAL_HAVE_S32C1I -#error "XCHAL_HAVE_S32C1I not defined, include correct header!" -#endif - -//this piece of code should only be compiled if the cpu doesn't support atomic compare and swap (s32c1i) -#if XCHAL_HAVE_S32C1I == 0 - -#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" - -ATOMIC_EXCHANGE(1, uint8_t) -ATOMIC_EXCHANGE(2, uint16_t) -ATOMIC_EXCHANGE(4, uint32_t) -ATOMIC_EXCHANGE(8, uint64_t) - -CMP_EXCHANGE(1, uint8_t) -CMP_EXCHANGE(2, uint16_t) -CMP_EXCHANGE(4, uint32_t) -CMP_EXCHANGE(8, uint64_t) - -FETCH_ADD(1, uint8_t) -FETCH_ADD(2, uint16_t) -FETCH_ADD(4, uint32_t) -FETCH_ADD(8, uint64_t) - -FETCH_SUB(1, uint8_t) -FETCH_SUB(2, uint16_t) -FETCH_SUB(4, uint32_t) -FETCH_SUB(8, uint64_t) - -FETCH_AND(1, uint8_t) -FETCH_AND(2, uint16_t) -FETCH_AND(4, uint32_t) -FETCH_AND(8, uint64_t) - -FETCH_OR(1, uint8_t) -FETCH_OR(2, uint16_t) -FETCH_OR(4, uint32_t) -FETCH_OR(8, uint64_t) - -FETCH_XOR(1, uint8_t) -FETCH_XOR(2, uint16_t) -FETCH_XOR(4, uint32_t) -FETCH_XOR(8, uint64_t) - -SYNC_FETCH_OP(add, 1, uint8_t) -SYNC_FETCH_OP(add, 2, uint16_t) -SYNC_FETCH_OP(add, 4, uint32_t) -SYNC_FETCH_OP(add, 8, uint64_t) - -SYNC_FETCH_OP(sub, 1, uint8_t) -SYNC_FETCH_OP(sub, 2, uint16_t) -SYNC_FETCH_OP(sub, 4, uint32_t) -SYNC_FETCH_OP(sub, 8, uint64_t) - -SYNC_FETCH_OP(and, 1, uint8_t) -SYNC_FETCH_OP(and, 2, uint16_t) -SYNC_FETCH_OP(and, 4, uint32_t) -SYNC_FETCH_OP(and, 8, uint64_t) - -SYNC_FETCH_OP(or, 1, uint8_t) -SYNC_FETCH_OP(or, 2, uint16_t) -SYNC_FETCH_OP(or, 4, uint32_t) -SYNC_FETCH_OP(or, 8, uint64_t) - -SYNC_FETCH_OP(xor, 1, uint8_t) -SYNC_FETCH_OP(xor, 2, uint16_t) -SYNC_FETCH_OP(xor, 4, uint32_t) -SYNC_FETCH_OP(xor, 8, uint64_t) - -SYNC_BOOL_CMP_EXCHANGE(1, uint8_t) -SYNC_BOOL_CMP_EXCHANGE(2, uint16_t) -SYNC_BOOL_CMP_EXCHANGE(4, uint32_t) -SYNC_BOOL_CMP_EXCHANGE(8, uint64_t) - -SYNC_VAL_CMP_EXCHANGE(1, uint8_t) -SYNC_VAL_CMP_EXCHANGE(2, uint16_t) -SYNC_VAL_CMP_EXCHANGE(4, uint32_t) -SYNC_VAL_CMP_EXCHANGE(8, uint64_t) - -#endif diff --git a/components/xtensa/xtensa_intr.c b/components/xtensa/xtensa_intr.c index be728d0f9ef0..c94a70eb9dfb 100644 --- a/components/xtensa/xtensa_intr.c +++ b/components/xtensa/xtensa_intr.c @@ -143,7 +143,7 @@ xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg) return ((old == &xt_unhandled_interrupt) ? 0 : old); } -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE void * xt_get_interrupt_handler_arg(int n) { xt_handler_table_entry * entry; diff --git a/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png b/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png index e2e82962da43..7da28ae22572 100644 Binary files a/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png and b/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png differ diff --git a/docs/_static/esp32-s2-devkitm-1-v1-pin-layout.png b/docs/_static/esp32-s2-devkitm-1-v1-pin-layout.png new file mode 100644 index 000000000000..7b24a546d340 Binary files /dev/null and b/docs/_static/esp32-s2-devkitm-1-v1-pin-layout.png differ diff --git a/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png b/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png index db9b4349ac1d..3cb77d6ae02d 100644 Binary files a/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png and b/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png differ diff --git a/docs/_static/esp32-s2-saola-1-v1.2-annotated-photo.png b/docs/_static/esp32-s2-saola-1-v1.2-annotated-photo.png index 10fd2b1a7896..0178b1612978 100644 Binary files a/docs/_static/esp32-s2-saola-1-v1.2-annotated-photo.png and b/docs/_static/esp32-s2-saola-1-v1.2-annotated-photo.png differ diff --git a/docs/_static/esp32-s2_saola1-pinout.jpg b/docs/_static/esp32-s2_saola1-pinout.jpg new file mode 100644 index 000000000000..3f42688751c7 Binary files /dev/null and b/docs/_static/esp32-s2_saola1-pinout.jpg differ diff --git a/docs/_static/freertos-ready-task-list-smp-pxIndex.png b/docs/_static/freertos-ready-task-list-smp-pxIndex.png deleted file mode 100644 index 08346858e9d8..000000000000 Binary files a/docs/_static/freertos-ready-task-list-smp-pxIndex.png and /dev/null differ diff --git a/docs/_static/freertos-ready-task-list-smp.png b/docs/_static/freertos-ready-task-list-smp.png deleted file mode 100644 index 820007afc5a0..000000000000 Binary files a/docs/_static/freertos-ready-task-list-smp.png and /dev/null differ diff --git a/docs/_static/freertos-ready-task-list.png b/docs/_static/freertos-ready-task-list.png deleted file mode 100644 index ea1489545874..000000000000 Binary files a/docs/_static/freertos-ready-task-list.png and /dev/null differ diff --git a/docs/doxygen/Doxyfile_common b/docs/doxygen/Doxyfile_common index b9b23eeb223e..81d44d140aec 100644 --- a/docs/doxygen/Doxyfile_common +++ b/docs/doxygen/Doxyfile_common @@ -34,6 +34,7 @@ INPUT = \ $(IDF_PATH)/components/esp_wifi/include/esp_now.h \ $(IDF_PATH)/components/esp_wifi/include/esp_wifi_default.h \ $(IDF_PATH)/components/esp_wifi/include/esp_mesh.h \ + $(IDF_PATH)/components/wpa_supplicant/include/esp_supplicant/esp_dpp.h \ $(IDF_PATH)/components/esp_event/include/esp_event.h \ $(IDF_PATH)/components/esp_event/include/esp_event_base.h \ $(IDF_PATH)/components/esp_event/include/esp_event_legacy.h \ diff --git a/docs/en/COPYRIGHT.rst b/docs/en/COPYRIGHT.rst index 47f43daed7f7..528f334a0617 100644 --- a/docs/en/COPYRIGHT.rst +++ b/docs/en/COPYRIGHT.rst @@ -4,7 +4,7 @@ Copyrights and Licenses Software Copyrights =================== -All original source code in this repository is Copyright (C) 2015-2019 Espressif Systems. This source code is licensed under the Apache License 2.0 as described in the file LICENSE. +All original source code in this repository is Copyright (C) 2015-2022 Espressif Systems. This source code is licensed under the Apache License 2.0 as described in the file LICENSE. Additional third party copyrighted code is included under the following licenses. @@ -69,6 +69,8 @@ These third party libraries can be included into the application (firmware) prod * `qrcode`_ QR Code generator library Copyright (c) Project Nayuki, is licensed under MIT license. +* `freemodbus`_ Copyright (c) 2006-2013 Christian Walter, Armink and licensed under the BSD license. + Build Tools ----------- @@ -182,3 +184,4 @@ Copyright (C) 2011, ChaN, all right reserved. .. _sphinx_rtd_theme: https://github.com/readthedocs/sphinx_rtd_theme .. _cryptoauthlib: https://github.com/MicrochipTech/cryptoauthlib .. _qrcode: https://github.com/nayuki/QR-Code-generator +.. _freemodbus: https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32 diff --git a/docs/en/api-guides/app_trace.rst b/docs/en/api-guides/app_trace.rst index 946ffbf18acd..f107c53a817f 100644 --- a/docs/en/api-guides/app_trace.rst +++ b/docs/en/api-guides/app_trace.rst @@ -324,10 +324,10 @@ Another useful IDF feature built on top of application tracing library is the sy How To Use It """"""""""""" -Support for this feature is enabled by *Component config > Application Level Tracing > FreeRTOS SystemView Tracing* (:ref:`CONFIG_SYSVIEW_ENABLE`) menuconfig option. There are several other options enabled under the same menu: +Support for this feature is enabled by *Component config > Application Level Tracing > FreeRTOS SystemView Tracing* (:ref:`CONFIG_APPTRACE_SV_ENABLE`) menuconfig option. There are several other options enabled under the same menu: -1. {IDF_TARGET_NAME} timer to use as SystemView timestamp source: (:ref:`CONFIG_SYSVIEW_TS_SOURCE`) selects the source of timestamps for SystemView events. In single core mode timestamps are generated using {IDF_TARGET_NAME} internal cycle counter running at maximum 240 Mhz (~4 ns granularity). In dual-core mode external timer working at 40 Mhz is used, so timestamp granularity is 25 ns. -2. Individually enabled or disabled collection of SystemView events (``CONFIG_SYSVIEW_EVT_XXX``): +1. {IDF_TARGET_NAME} timer to use as SystemView timestamp source: (:ref:`CONFIG_APPTRACE_SV_TS_SOURCE`) selects the source of timestamps for SystemView events. In single core mode timestamps are generated using {IDF_TARGET_NAME} internal cycle counter running at maximum 240 Mhz (~4 ns granularity). In dual-core mode external timer working at 40 Mhz is used, so timestamp granularity is 25 ns. +2. Individually enabled or disabled collection of SystemView events (``CONFIG_APPTRACE_SV_EVT_XXX``): - Trace Buffer Overflow Event - ISR Enter Event diff --git a/docs/en/api-guides/core_dump.rst b/docs/en/api-guides/core_dump.rst index a05d0fd24db0..579332ee8a15 100644 --- a/docs/en/api-guides/core_dump.rst +++ b/docs/en/api-guides/core_dump.rst @@ -6,12 +6,6 @@ Core Dump Overview -------- -.. only:: not esp32 - - .. note:: - - The python utility does not fully support {IDF_TARGET_NAME} - ESP-IDF provides support to generate core dumps on unrecoverable software errors. This useful technique allows post-mortem analysis of software state at the moment of failure. Upon the crash system enters panic state, prints some information and halts or reboots depending configuration. User can choose to generate core dump in order to analyse the reason of failure on PC later on. Core dump contains snapshots of all tasks in the system at the moment of failure. Snapshots include tasks control blocks (TCB) and stacks. @@ -19,41 +13,66 @@ So it is possible to find out what task, at what instruction (line of code) and demand if previously attributed accordingly. ESP-IDF provides special script `espcoredump.py` to help users to retrieve and analyse core dumps. This tool provides two commands for core dumps analysis: -* info_corefile - prints crashed task's registers, callstack, list of available tasks in the system, memory regions and contents of memory stored in core dump (TCBs and stacks) -* dbg_corefile - creates core dump ELF file and runs GDB debug session with this file. User can examine memory, variables and tasks states manually. Note that since not all memory is saved in core dump only values of variables allocated on stack will be meaningfull +* ``info_corefile`` - prints crashed task's registers, callstack, list of available tasks in the system, memory regions and contents of memory stored in core dump (TCBs and stacks) +* ``dbg_corefile`` - creates core dump ELF file and runs GDB debug session with this file. User can examine memory, variables and tasks states manually. Note that since not all memory is saved in core dump only values of variables allocated on stack will be meaningful For more information about core dump internals see the - :doc:`Core dump internals ` -Configuration -------------- +Configurations +-------------- + +There are a number of core dump related configuration options which user can choose in project configuration menu (``idf.py menuconfig``). + +**Core dump data destination (Components -> Core dump -> Data destination)** + + * Save core dump to Flash (Flash) + * Print core dump to UART (UART) + * Disable core dump generation (None) + +**Core dump data format (Components -> Core dump -> Core dump data format)** + + * ELF format (Executable and Linkable Format file for core dump) + * Binary format (Basic binary format for core dump) + + The ELF format contains extended features and allow to save more information about broken tasks and crashed software but it requires more space in the flash memory. + This format of core dump is recommended for new software designs and is flexible enough to extend saved information for future revisions. -There are a number of core dump related configuration options which user can choose in project configuration menu (`idf.py menuconfig`). + The Binary format is kept for compatibility standpoint, it uses less space in the memory to keep data and provides better performance. -1. Core dump data destination (`Components -> Core dump -> Data destination`): +**Core dump data integrity check (Components -> Core dump -> Core dump data integrity check)** -* Save core dump to Flash (Flash) -* Print core dump to UART (UART) -* Disable core dump generation (None) + .. only:: esp32 -2. Core dump data format (`Components -> Core dump -> Core dump data format`): + * Use CRC32 for core dump integrity verification + * Use SHA256 for core dump integrity verification (only work in ELF format) -* ELF format (Executable and Linkable Format file for core dump) -* Binary format (Basic binary format for core dump) + The CRC32 option provides better calculation performance and consumes less memory for storage. -The ELF format contains extended features and allow to save more information about broken tasks and crashed software but it requires more space in the flash memory. -It also stores SHA256 of crashed application image. This format of core dump is recommended for new software designs and is flexible enough to extend saved information for future revisions. -The Binary format is kept for compatibility standpoint, it uses less space in the memory to keep data and provides better performance. + The SHA256 hash algorithm provides greater probability of detecting corruption than a CRC32 with multiple bit errors. -3. Maximum number of tasks snapshots in core dump (`Components -> Core dump -> Maximum number of tasks`). + .. only:: not esp32 -4. Delay before core dump is printed to UART (`Components -> Core dump -> Delay before print to UART`). Value is in ms. + * Use CRC32 for core dump integrity verification -5. Type of data integrity check for core dump (`Components -> Core dump -> Core dump data integrity check`). +**Maximum number of tasks snapshots in core dump (Components -> Core dump -> Maximum number of tasks)** -* Use CRC32 for core dump integrity verification -* Use SHA256 for core dump integrity verification +**Delay before core dump is printed to UART (Components -> Core dump -> Delay before print to UART)** -The SHA256 hash algorithm provides greater probability of detecting corruption than a CRC32 with multiple bit errors. The CRC32 option provides better calculation performance and consumes less memory for storage. + The value is in ms. + +**Handling of UART core dumps in IDF Monitor (Components -> Core dump -> Delay before print to UART)** + + The value is base64 encoded. + + * Decode and show summary (info_corefile) + * Don't decode + +.. only:: esp32c3 + + **Reserved stack size (Components -> Core dump -> Reserved stack size)** + + Size of the memory to be reserved for core dump stack. If 0 core dump process will run on the stack of crashed task/ISR, otherwise special stack will be allocated. + To ensure that core dump itself will not overflow task/ISR stack set this to the value above 800. Save core dump to flash ----------------------- @@ -62,40 +81,40 @@ When this option is selected core dumps are saved to special partition on flash. allocates necessary space on flash, But if user wants to use its own layout file together with core dump feature it should define separate partition for core dump as it is shown below:: - # Name, Type, SubType, Offset, Size - # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap - nvs, data, nvs, 0x9000, 0x6000 - phy_init, data, phy, 0xf000, 0x1000 - factory, app, factory, 0x10000, 1M - coredump, data, coredump,, 64K + # Name, Type, SubType, Offset, Size + # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap + nvs, data, nvs, 0x9000, 0x6000 + phy_init, data, phy, 0xf000, 0x1000 + factory, app, factory, 0x10000, 1M + coredump, data, coredump,, 64K -There are no special requrements for partition name. It can be choosen according to the user application needs, but partition type should be 'data' and +There are no special requirements for partition name. It can be chosen according to the user application needs, but partition type should be 'data' and sub-type should be 'coredump'. Also when choosing partition size note that core dump data structure introduces constant overhead of 20 bytes and per-task overhead of 12 bytes. -This overhead does not include size of TCB and stack for every task. So partirion size should be at least 20 + max tasks number x (12 + TCB size + max task stack size) bytes. +This overhead does not include size of TCB and stack for every task. So partition size should be at least 20 + max tasks number x (12 + TCB size + max task stack size) bytes. -The example of generic command to analyze core dump from flash is: `espcoredump.py -p info_corefile ` -or `espcoredump.py -p dbg_corefile ` +The example of generic command to analyze core dump from flash is: ``espcoredump.py -p info_corefile `` +or ``espcoredump.py -p dbg_corefile `` Print core dump to UART ----------------------- When this option is selected base64-encoded core dumps are printed on UART upon system panic. In this case user should save core dump text body to some file manually and -then run the following command: `espcoredump.py info_corefile -t b64 -c ` -or `espcoredump.py dbg_corefile -t b64 -c ` +then run the following command: ``espcoredump.py --chip info_corefile -t b64 -c `` +or ``espcoredump.py --chip dbg_corefile -t b64 -c `` Base64-encoded body of core dump will be between the following header and footer:: - ================= CORE DUMP START ================= - - ================= CORE DUMP END =================== + ================= CORE DUMP START ================= + + ================= CORE DUMP END =================== -The `CORE DUMP START` and `CORE DUMP END` lines must not be included in core dump text file. +The ``CORE DUMP START`` and ``CORE DUMP END`` lines must not be included in core dump text file. ROM Functions in Backtraces --------------------------- It is possible situation that at the moment of crash some tasks or/and crashed task itself have one or more ROM functions in their callstacks. -Since ROM is not part of the program ELF it will be impossible for GDB to parse such callstacks, because it tries to analyse functions' prologues to acomplish that. +Since ROM is not part of the program ELF it will be impossible for GDB to parse such callstacks, because it tries to analyse functions' prologues to accomplish that. In that case callstack printing will be broken with error message at the first ROM function. To overcome this issue you can use ROM ELF provided by Espressif ({IDF_TARGET_ROM_ELF}) and pass it to 'espcoredump.py'. @@ -108,18 +127,9 @@ Core dump supports retrieving variable data over GDB by attributing special nota Supported notations and RAM regions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. only:: esp32 - - - ``COREDUMP_DRAM_ATTR`` places variable into DRAM area which will be included into dump. - - ``COREDUMP_RTC_ATTR`` places variable into RTC area which will be included into dump. - - ``COREDUMP_RTC_FAST_ATTR`` places variable into RTC_FAST area which will be included into dump. - - ``COREDUMP_IRAM_ATTR`` places variable into IRAM area which will be included into dump when :ref:`Enable IRAM as 8 bit accessible memory ` is set. - -.. only:: esp32s2 - - - ``COREDUMP_DRAM_ATTR`` places variable into DRAM area which will be included into dump. - - ``COREDUMP_RTC_ATTR`` places variable into RTC area which will be included into dump. - - ``COREDUMP_RTC_FAST_ATTR`` places variable into RTC_FAST area which will be included into dump. +* ``COREDUMP_DRAM_ATTR`` places variable into DRAM area which will be included into dump. +* ``COREDUMP_RTC_ATTR`` places variable into RTC area which will be included into dump. +* ``COREDUMP_RTC_FAST_ATTR`` places variable into RTC_FAST area which will be included into dump. Example ^^^^^^^ @@ -128,53 +138,76 @@ Example 2. In your project, create a global variable in DRAM area as such as: - .. code-block:: bash +.. code-block:: bash - // uint8_t global_var; - COREDUMP_DRAM_ATTR uint8_t global_var; + // uint8_t global_var; + COREDUMP_DRAM_ATTR uint8_t global_var; -3. In main application, set the variable to any value and `assert(0)` to cause a crash. +3. In main application, set the variable to any value and ``assert(0)`` to cause a crash. - .. code-block:: bash +.. code-block:: bash - global_var = 25; - assert(0); + global_var = 25; + assert(0); 4. Build, flash and run the application on a target device and wait for the dumping information. 5. Run the command below to start core dumping in GDB, where ``PORT`` is the device USB port: - .. code-block:: bash +.. code-block:: bash - espcoredump.py -p PORT dbg_corefile + espcoredump.py -p PORT dbg_corefile 6. In GDB shell, type ``p global_var`` to get the variable content: - .. code-block:: bash - - (gdb) p global_var - $1 = 25 '\031' +.. code-block:: bash -Running 'espcoredump.py' ------------------------- + (gdb) p global_var + $1 = 25 '\031' -Generic command syntax: +Running ``espcoredump.py`` +-------------------------- -`espcoredump.py [options] command [args]` +Generic command syntax: ``espcoredump.py [options] command [args]`` :Script Options: - * --port,-p PORT. Serial port device. - * --baud,-b BAUD. Serial port baud rate used when flashing/reading. + + --chip {auto,esp32,esp32s2,esp32c3} + Target chip type. Default value is "auto" + + --port PORT, -p PORT Serial port device. Either "chip" or "port" need to be specified to determine the port when you have multi-target connected at the same time. + + --baud BAUD, -b BAUD Serial port baud rate used when flashing/reading + + --gdb-timeout-sec GDB_TIMEOUT_SEC + Overwrite the default internal delay for gdb responses + :Commands: - * info_corefile. Retrieve core dump and print useful info. - * dbg_corefile. Retrieve core dump and start GDB session with it. + + **dbg_corefile** Starts GDB debugging session with specified corefile + + **info_corefile** Print core dump info from file + :Command Arguments: - * --debug,-d DEBUG. Log level (0..3). - * --gdb,-g GDB. Path to gdb to use for data retrieval. - * --core,-c CORE. Path to core dump file to use (if skipped core dump will be read from flash). - * --core-format,-t CORE_FORMAT. Specifies that file passed with "-c" is an ELF ("elf"), dumped raw binary ("raw") or base64-encoded ("b64") format. - * --off,-o OFF. Offset of coredump partition in flash (type `idf.py partition_table` to see it). - * --save-core,-s SAVE_CORE. Save core to file. Othwerwise temporary core file will be deleted. Ignored with "-c". - * --rom-elf,-r ROM_ELF. Path to ROM ELF file to use (if skipped "esp32_rom.elf" is used). - * --print-mem,-m Print memory dump. Used only with "info_corefile". - * Path to program ELF file. + + --debug DEBUG, -d DEBUG + Log level (0..3) + + --gdb GDB, -g GDB Path to gdb + + --core CORE, -c CORE Path to core dump file (if skipped core dump will be read from flash) + + --core-format {b64,elf,raw}, -t {b64,elf,raw} + File specified with "-c" is an ELF ("elf"), raw (raw) or base64-encoded (b64) binary + + --off OFF, -o OFF Offset of coredump partition in flash (type "make partition_table" to see). + + --save-core SAVE_CORE, -s SAVE_CORE + Save core to file. Otherwise temporary core file will be deleted. Does not work with "-c" + + --rom-elf ROM_ELF, -r ROM_ELF + Path to ROM ELF file. Will use "_rom.elf" if not specified + + --print-mem, -m Print memory dump. Only valid when info_corefile. + + **** Path to program ELF file. diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index bef78f97c108..d37eb06bbbdf 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -111,7 +111,13 @@ Restrictions External RAM use has the following restrictions: * When flash cache is disabled (for example, if the flash is being written to), the external RAM also becomes inaccessible; any reads from or writes to it will lead to an illegal cache access exception. This is also the reason why ESP-IDF does not by default allocate any task stacks in external RAM (see below). - * External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Any buffers that will be used in combination with DMA must be allocated using ``heap_caps_malloc(size, MALLOC_CAP_DMA)`` and can be freed using a standard ``free()`` call. + + * External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Therefore when External RAM is enabled, any buffers that will be used in combination with DMA must be allocated using ``heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL)`` and can be freed using a standard ``free()`` call. + + .. only:: SOC_PSRAM_DMA_CAPABLE + + Note, although {IDF_TARGET_NAME} has hardware support for DMA to/from external RAM, this is not yet supported in ESP-IDF. + * External RAM uses the same cache region as the external flash. This means that frequently accessed variables in external RAM can be read and modified almost as quickly as in internal ram. However, when accessing large chunks of data (>32 KB), the cache can be insufficient, and speeds will fall back to the access speed of the external RAM. Moreover, accessing large chunks of data can "push out" cached flash, possibly making the execution of code slower afterwards. * In general, external RAM cannot be used as task stack memory. Due to this, :cpp:func:`xTaskCreate` and similar functions will always allocate internal memory for stack and task TCBs, and functions such as :cpp:func:`xTaskCreateStatic` will check if the buffers passed are internal. diff --git a/docs/en/api-guides/freertos-smp.rst b/docs/en/api-guides/freertos-smp.rst index 388cdde9f51d..1b71d6238094 100644 --- a/docs/en/api-guides/freertos-smp.rst +++ b/docs/en/api-guides/freertos-smp.rst @@ -19,7 +19,7 @@ FreeRTOS and ESP-IDF FreeRTOS. The API reference for vanilla FreeRTOS can be found via https://www.freertos.org/a00106.html For information regarding features that are exclusive to ESP-IDF FreeRTOS, -see :doc:`ESP-IDF FreeRTOS Additions<../api-reference/system/freertos_additions>`. +see :doc:`ESP-IDF FreeRTOS Additions`. .. only:: not CONFIG_FREERTOS_UNICORE @@ -30,10 +30,7 @@ see :doc:`ESP-IDF FreeRTOS Additions<../api-reference/system/freertos_additions> ``1`` for **APP_CPU**, or ``tskNO_AFFINITY`` which allows the task to run on both. - :ref:`round-robin-scheduling`: The ESP-IDF FreeRTOS scheduler will skip tasks when - implementing Round-Robin scheduling between multiple tasks in the Ready state - that are of the same priority. To avoid this behavior, ensure that those tasks either - enter a blocked state, or are distributed across a wider range of priorities. + :ref:`round-robin-scheduling`: The ESP-IDF FreeRTOS scheduler implements a "Best Effort Round-Robin Scheduling" instead of the ideal Round-Robin scheduling in vanilla FreeRTOS. :ref:`scheduler-suspension`: Suspending the scheduler in ESP-IDF FreeRTOS will only affect the scheduler on the the calling core. In other words, calling @@ -133,91 +130,88 @@ synchronicity. Round Robin Scheduling ^^^^^^^^^^^^^^^^^^^^^^ -Given multiple tasks in the Ready state and of the same priority, vanilla -FreeRTOS implements Round Robin scheduling between each task. This will result -in running those tasks in turn each time the scheduler is called -(e.g. every tick interrupt). On the other hand, the ESP-IDF FreeRTOS scheduler -may skip tasks when Round Robin scheduling multiple Ready state tasks of the -same priority. - -The issue of skipping tasks during Round Robin scheduling arises from the way -the Ready Tasks List is implemented in FreeRTOS. In vanilla FreeRTOS, -``pxReadyTasksList`` is used to store a list of tasks that are in the Ready -state. The list is implemented as an array of length ``configMAX_PRIORITIES`` -where each element of the array is a linked list. Each linked list is of type -``List_t`` and contains TCBs of tasks of the same priority that are in the -Ready state. The following diagram illustrates the ``pxReadyTasksList`` -structure. - -.. figure:: ../../_static/freertos-ready-task-list.png - :align: center - :alt: Vanilla FreeRTOS Ready Task List Structure - - Illustration of FreeRTOS Ready Task List Data Structure - - -Each linked list also contains a ``pxIndex`` which points to the last TCB -returned when the list was queried. This index allows the ``vTaskSwitchContext()`` -to start traversing the list at the TCB immediately after ``pxIndex`` hence -implementing Round Robin Scheduling between tasks of the same priority. - -In ESP-IDF FreeRTOS, the Ready Tasks List is shared between cores hence -``pxReadyTasksList`` will contain tasks pinned to different cores. When a core -calls the scheduler, it is able to look at the ``xCoreID`` member of each TCB -in the list to determine if a task is allowed to run on calling the core. The -ESP-IDF FreeRTOS ``pxReadyTasksList`` is illustrated below. - -.. figure:: ../../_static/freertos-ready-task-list-smp.png - :align: center - :alt: ESP-IDF FreeRTOS Ready Task List Structure - - Illustration of FreeRTOS Ready Task List Data Structure in ESP-IDF - -Therefore when **PRO_CPU** calls the scheduler, it will only consider the tasks -in blue or purple. Whereas when **APP_CPU** calls the scheduler, it will only -consider the tasks in orange or purple. - -Although each TCB has an ``xCoreID`` in ESP-IDF FreeRTOS, the linked list of -each priority only has a single ``pxIndex``. Therefore when the scheduler is -called from a particular core and traverses the linked list, it will skip all -TCBs pinned to the other core and point the pxIndex at the selected task. If -the other core then calls the scheduler, it will traverse the linked list -starting at the TCB immediately after ``pxIndex``. Therefore, TCBs skipped on -the previous scheduler call from the other core would not be considered on the -current scheduler call. This issue is demonstrated in the following -illustration. - -.. figure:: ../../_static/freertos-ready-task-list-smp-pxIndex.png - :align: center - :alt: ESP-IDF pxIndex Behavior - - Illustration of pxIndex behavior in ESP-IDF FreeRTOS - -Referring to the illustration above, assume that priority 9 is the highest -priority, and none of the tasks in priority 9 will block hence will always be -either in the running or Ready state. - -1) **PRO_CPU** calls the scheduler and selects Task A to run, hence moves -``pxIndex`` to point to Task A - -2) **APP_CPU** calls the scheduler and starts traversing from the task after -``pxIndex`` which is Task B. However Task B is not selected to run as it is not -pinned to **APP_CPU** hence it is skipped and Task C is selected instead. -``pxIndex`` now points to Task C - -3) **PRO_CPU** calls the scheduler and starts traversing from Task D. It skips -Task D and selects Task E to run and points ``pxIndex`` to Task E. Notice that -Task B isn’t traversed because it was skipped the last time **APP_CPU** called -the scheduler to traverse the list. - -4) The same situation with Task D will occur if **APP_CPU** calls the -scheduler again as ``pxIndex`` now points to Task E - -One solution to the issue of task skipping is to ensure that every task will -enter a blocked state so that they are removed from the Ready Task List. -Another solution is to distribute tasks across multiple priorities such that -a given priority will not be assigned multiple tasks that are pinned to -different cores. +Given multiple tasks in the Ready state and of the same priority, vanilla FreeRTOS implements Round Robin scheduling between multiple ready state tasks of the same priority. This will result in running those tasks in turn each time the scheduler is called (e.g. when the tick interrupt occurs or when a task blocks/yields). + +On the other hand, it is not possible for the ESP-IDF FreeRTOS scheduler to implement perfect Round Robin due to the fact that a particular task may not be able to run on a particular core due to the following reasons: + +- The task is pinned to the another core. +- For unpinned tasks, the task is already being run by another core. + +Therefore, when a core searches the ready state task list for a task to run, the core may need to skip over a few tasks in the same priority list or drop to a lower priority in order to find a ready state task that the core can run. + +The ESP-IDF FreeRTOS scheduler implements a Best Effort Round Robin scheduling for ready state tasks of the same priority by ensuring that tasks that have been selected to run will be placed at the back of the list, thus giving unselected tasks a higher priority on the next scheduling iteration (i.e., the next tick interrupt or yield) + +The following example demonstrates the Best Effort Round Robin Scheduling in action. Assume that: + +- There are four ready state tasks of the same priority ``AX, B0, C1, D1`` where: + - The priority is the current highest priority with ready state tasks + - The first character represents the task's names (i.e., ``A, B, C, D``) + - And the second character represents the tasks core pinning (and ``X`` means unpinned) +- The task list is always searched from the head + +.. code-block:: none + + -------------------------------------------------------------------------------- + + 1. Starting state. None of the ready state tasks have been selected to run + + Head [ AX , B0 , C1 , D0 ] Tail + + -------------------------------------------------------------------------------- + + 2. Core 0 has tick interrupt and searches for a task to run. + Task A is selected and is moved to the back of the list + + Core0--| + Head [ AX , B0 , C1 , D0 ] Tail + + 0 + Head [ B0 , C1 , D0 , AX ] Tail + + -------------------------------------------------------------------------------- + + 3. Core 1 has a tick interrupt and searches for a task to run. + Task B cannot be run due to incompatible affinity, so core 1 skips to Task C. + Task C is selected and is moved to the back of the list + + Core1-------| 0 + Head [ B0 , C1 , D0 , AX ] Tail + + 0 1 + Head [ B0 , D0 , AX , C1 ] Tail + + -------------------------------------------------------------------------------- + + 4. Core 0 has another tick interrupt and searches for a task to run. + Task B is selected and moved to the back of the list + + + Core0--| 1 + Head [ B0 , D0 , AX , C1 ] Tail + + 1 0 + Head [ D0 , AX , C1 , B0 ] Tail + + -------------------------------------------------------------------------------- + + 5. Core 1 has another tick and searches for a task to run. + Task D cannot be run due to incompatible affinity, so core 1 skips to Task A + Task A is selected and moved to the back of the list + + Core1-------| 0 + Head [ D0 , AX , C1 , B0 ] Tail + + 0 1 + Head [ D0 , C1 , B0 , AX ] Tail + + +The implications to users regarding the Best Effort Round Robin Scheduling: + +- Users cannot expect multiple ready state tasks of the same priority to run sequentially (as is the case in Vanilla FreeRTOS). As demonstrated in the example above, a core may need to skip over tasks. +- However, given enough ticks, a task will eventually be given some processing time. +- If a core cannot find a task runnable task at the highest ready state priority, it will drop to a lower priority to search for tasks. +- To achieve ideal round robin scheduling, users should ensure that all tasks of a particular priority are pinned to the same core. + .. _scheduler-suspension: diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index 1a9782001e50..3a558ac9de56 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -42,4 +42,5 @@ API Guides :esp32: Unit Testing (Legacy GNU Make) :SOC_USB_SUPPORTED: USB OTG Console :SOC_USB_SERIAL_JTAG_SUPPORTED: USB Serial/JTAG Controller Console - WiFi Driver + Wi-Fi Driver + Wi-Fi Security diff --git a/docs/en/api-guides/partition-tables.rst b/docs/en/api-guides/partition-tables.rst index ab377b21a6f4..d2f22d2e4fb8 100644 --- a/docs/en/api-guides/partition-tables.rst +++ b/docs/en/api-guides/partition-tables.rst @@ -274,7 +274,7 @@ The command-line interface of `parttool.py` has the following structure: parttool.py --port "/dev/ttyUSB1" read_partition --partition-type=data --partition-subtype=spiffs --output "spiffs.bin" # Write to partition 'factory' the contents of a file named 'factory.bin' - parttool.py --port "/dev/ttyUSB1" write_partition --partition-name=factory "factory.bin" + parttool.py --port "/dev/ttyUSB1" write_partition --partition-name=factory --input "factory.bin" # Print the size of default boot partition parttool.py --port "/dev/ttyUSB1" get_partition_info --partition-boot-default --info size diff --git a/docs/en/api-guides/tools/idf-component-manager.rst b/docs/en/api-guides/tools/idf-component-manager.rst new file mode 100644 index 000000000000..37002561943c --- /dev/null +++ b/docs/en/api-guides/tools/idf-component-manager.rst @@ -0,0 +1,72 @@ +********************* +IDF Component Manager +********************* + +The IDF Component manager is a tool that downloads dependencies for any ESP-IDF CMake project. The download happens automatically during a run of CMake. It can source components either from `the component registry `_ or from a git repository. + +A list of components can be found on ``_ + +Activating the Component Manager +================================ + +If CMake is started using ``idf.py`` or `ESP-IDF VSCode Extension `_ then the component manager will be activated by default. + +If CMake is used directly or with some CMake-based IDE like CLion, it's necessary to set the ``IDF_COMPONENT_MANAGER`` environment variable to ``1`` to enable the component manager integration with the build system. + +Using with a project +==================== + +Dependencies for each component in the project are defined in a separate manifest file named ``idf_component.yml`` placed in the root of the component. The manifest file template can be created for a component by running ``idf.py create-manifest --component=my_component``. When a new manifest is added to one of the components in the project it's necessary to reconfigure it manually by running ``idf.py reconfigure``. Then build will track changes in ``idf_component.yml`` manifests and automatically triggers CMake when necessary. + +There is an example application: example:`build_system/cmake/component_manager` that uses components installed by the component manager. + +It's not necessary to have a manifest for components that don't need any managed dependencies. + +When CMake configures the project (e.g. ``idf.py reconfigure``) component manager does a few things: + +- Processes ``idf_component.yml`` manifests for every component in the project and recursively solves dependencies +- Creates a ``dependencies.lock`` file in the root of the project with a full list of dependencies +- Downloads all dependencies to the ``managed_components`` directory + +The lock-file ``dependencies.lock`` and content of ``managed_components`` directory is not supposed to be modified by a user. When the component manager runs it always make sure they are up to date. If these files were accidentally modified it's possible to re-run the component manager by triggering CMake with ``idf.py reconfigure`` + +Defining dependencies in the manifest +===================================== + +.. code-block:: yaml + + dependencies: + # Required IDF version + idf: ">=4.1" + # Defining a dependency from the registry: + # https://components.espressif.com/component/example/cmp + example/cmp: ">=1.0.0" + + # # Other ways to define dependencies + # + # # For components maintained by Espressif only name can be used. + # # Same as `espressif/cmp` + # component: "~1.0.0" + # + # # Or in a longer form with extra parameters + # component2: + # version: ">=2.0.0" + # + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't affect the `main` component. + # # All dependencies of `main` are public by default. + # public: true + # + # # For components hosted on non-default registry: + # service_url: "https://componentregistry.company.com" + # + # # For components in git repository: + # test_component: + # path: test_component + # git: ssh://git@gitlab.com/user/components.git + # + # # For test projects during component development + # # components can be used from a local directory + # # with relative or absolute path + # some_local_component: + # path: ../../projects/component diff --git a/docs/en/api-guides/tools/idf-docker-image.rst b/docs/en/api-guides/tools/idf-docker-image.rst index f4b02e1aa6a1..8b104f8b59f2 100644 --- a/docs/en/api-guides/tools/idf-docker-image.rst +++ b/docs/en/api-guides/tools/idf-docker-image.rst @@ -59,7 +59,7 @@ The above command explained: To build with a specific docker image tag, specify it as ``espressif/idf:TAG``, for example:: - docker run --rm -v $PWD:/project -w /project espressif/idf:release-v4.0 idf.py build + docker run --rm -v $PWD:/project -w /project espressif/idf:release-v4.4 idf.py build You can check the up-to-date list of available tags at https://hub.docker.com/r/espressif/idf/tags. @@ -100,3 +100,22 @@ Then inside the container, use ``idf.py`` as usual:: .. note:: Commands which communicate with the development board, such as ``idf.py flash`` and ``idf.py monitor`` will not work in the container unless the serial port is passed through into the container. However currently this is not possible with Docker for Windows (https://github.com/docker/for-win/issues/1018) and Docker for Mac (https://github.com/docker/for-mac/issues/900). + +Building custom images +====================== + +The Dockerfile in ESP-IDF repository provides several build arguments which can be used to customize the Docker image: + +- ``IDF_CLONE_URL``: URL of the repository to clone ESP-IDF from. Can be set to a custom URL when working with a fork of ESP-IDF. Default is ``https://github.com/espressif/esp-idf.git``. +- ``IDF_CLONE_BRANCH_OR_TAG``: Name of a git branch or tag use when cloning ESP-IDF. This value is passed to ``git clone`` command using the ``--branch`` argument. Default is ``master``. +- ``IDF_CHECKOUT_REF``: If this argument is set to a non-empty value, ``git checkout $IDF_CHECKOUT_REF`` command will be performed after cloning. This argument can be set to the SHA of the specific commit to check out, for example if some specific commit on a release branch is desired. +- ``IDF_CLONE_SHALLOW``: If this argument is set to a non-empty value, ``--depth=1 --shallow-submodules`` arguments will be used when performing ``git clone``. This significantly reduces the amount of data downloaded and the size of the resulting Docker image. However, if switching to a different branch in such a "shallow" repository is necessary, an additional ``git fetch origin `` command must be executed first. +- ``IDF_INSTALL_TARGETS``: Comma-separated list of IDF targets to install toolchains for, or ``all`` to install toolchains for all targets. Selecting specific targets reduces the amount of data downloaded and the size of the resulting Docker image. Default is ``all``. + +To use these arguments, pass them via the ``--build-arg`` command line option. For example, the following command will build a Docker image with a shallow clone of ESP-IDF v4.4.1 and tools for ESP32-C3, only:: + + docker build -t idf-custom:v4.4.1-esp32c3 \ + --build-arg IDF_CLONE_BRANCH_OR_TAG=v4.4.1 \ + --build-arg IDF_CLONE_SHALLOW=1 \ + --build-arg IDF_INSTALL_TARGETS=esp32c3 \ + tools/docker diff --git a/docs/en/api-guides/tools/index.rst b/docs/en/api-guides/tools/index.rst index 862cbb4367ab..49b85291c3a1 100644 --- a/docs/en/api-guides/tools/index.rst +++ b/docs/en/api-guides/tools/index.rst @@ -8,3 +8,4 @@ Tools IDF Monitor IDF Docker image IDF Windows Installer + IDF Component Manager diff --git a/docs/en/api-guides/usb-serial-jtag-console.rst b/docs/en/api-guides/usb-serial-jtag-console.rst index b2834d9d4cb9..e3b7b2b5922f 100644 --- a/docs/en/api-guides/usb-serial-jtag-console.rst +++ b/docs/en/api-guides/usb-serial-jtag-console.rst @@ -46,9 +46,12 @@ Limitations There are several limitations to the USB console feature. These may or may not be significant, depending on the type of application being developed, and the development workflow. -1. If the application accidentally reconfigures the USB peripheral pins, or disables the USB Serial/JTAG Controller, the device will disappear from the system. After fixing the issue in the application, you will need to manually put the {IDF_TARGET_NAME} into download mode by pulling low GPIO0 and resetting the chip. +{IDF_TARGET_BOOT_PIN:default = "Not Updated!", esp32c3 = "GPIO9", esp32s3 = "GPIO0"} -2. If the application enters light sleep (including automatic light sleep) or deep sleep mode, USB CDC device will disappear from the system. +1. If the application accidentally reconfigures the USB peripheral pins, or disables the USB Serial/JTAG Controller, the device will disappear from the system. After fixing the issue in the application, you will need to manually put the {IDF_TARGET_NAME} into download mode by pulling low {IDF_TARGET_BOOT_PIN} and resetting the chip. + +2. If the application enters deep sleep mode, USB CDC device will disappear from the system. 3. The behaviour between an actual USB-to-serial bridge chip and the USB Serial/JTAG Controller is slightly different if the ESP-IDF application does not listen for incoming bytes. An USB-to-serial bridge chip will just send the bytes to a (not listening) chip, while the USB Serial/JTAG Controller will block until the application reads the bytes. This can lead to a non-responsive looking terminal program. +4. If the application enters light-sleep (including automatic light-sleep) or software reset, etc. The USB CDC device will still work on the system. But be aware that this might increase the power consumption, if you don't need USB CDC in sleep and want to keep low power consumption, please disable the menuconfig ``CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB``. Moreover, the power consumption will only increase when your USB CDC port is really in use (like data transaction), therefore, if your USB CDC just connects with power bank or battery, rather than something like computer, you don't need to care about the increasing power consumption mentioned above. diff --git a/docs/en/api-guides/wifi-security.rst b/docs/en/api-guides/wifi-security.rst new file mode 100644 index 000000000000..77f1bdc62451 --- /dev/null +++ b/docs/en/api-guides/wifi-security.rst @@ -0,0 +1,96 @@ +Wi-Fi Security +============== + +{IDF_TARGET_NAME} Wi-Fi Security Features +----------------------------------------- +- Support for Protected Management Frames (PMF) +- Support for WPA3-Personal + +In addition to traditional security methods (WEP/WPA-TKIP/WPA2-CCMP), {IDF_TARGET_NAME} Wi-Fi supports state-of-the-art security protocols, namely Protected Management Frames based on 802.11w standard and Wi-Fi Protected Access 3 (WPA3-Personal). Together, PMF and WPA3 provide better privacy and robustness against known attacks on traditional modes. + +Protected Management Frames (PMF) +--------------------------------- + +Introduction +++++++++++++ + +In Wi-Fi, management frames such as beacons, probes, (de)authentication, (dis)association are used by non-AP stations to scan and connect to an AP. Unlike data frames, these frames are sent unencrypted. +An attacker can use eavesdropping and packet injection to send spoofed (de)authentication/(dis)association frames at the right time, leading to the following attacks in case of unprotected management frame exchanges. + + - DOS attack on one or all clients in the range of the attacker. + - Tearing down existing association on AP side by sending association request. + - Forcing a client to perform 4-way handshake again in case PSK is compromised in order to get PTK. + - Getting SSID of hidden network from association request. + - Launching man-in-the-middle attack by forcing clients to deauth from legitimate AP and associating to a rogue one. + +PMF provides protection against these attacks by encrypting unicast management frames and providing integrity checks for broadcast management frames. These include deauthentication, disassociation and robust management frames. It also provides Secure Association (SA) teardown mechanism to prevent spoofed association/authentication frames from disconnecting already connected clients. + +There are 3 types of PMF configuration modes on both Station and AP side - + - PMF Optional + - PMF Required + - PMF Disabled + +Depending on the PMF configuration on Station and AP side, the resulting connection will behave differently. Below table summarises all possible outcomes. + ++--------------+------------------------+---------------------------+ +| STA Setting | AP Setting | Outcome | ++==============+========================+===========================+ +| PMF Optional | PMF Optional/Required | Mgmt Frames Protected | ++--------------+------------------------+---------------------------+ +| PMF Optional | PMF Disabled | Mgmt Frames Not Protected | ++--------------+------------------------+---------------------------+ +| PMF Required | PMF Optional/Required | Mgmt Frames Protected | ++--------------+------------------------+---------------------------+ +| PMF Required | PMF Disabled | STA refuses Connection | ++--------------+------------------------+---------------------------+ +| PMF Disabled | PMF Optional/Disabled | Mgmt Frames Not Protected | ++--------------+------------------------+---------------------------+ +| PMF Disabled | PMF Required | AP refuses Connection | ++--------------+------------------------+---------------------------+ + +API & Usage ++++++++++++ + +{IDF_TARGET_NAME} supports PMF only in Station mode. Station defaults to PMF Optional mode and disabling PMF is not possible. For even higher security, PMF required mode can be enabled by setting the ``required`` flag in `pmf_cfg` while using the :cpp:func:`esp_wifi_set_config` API. This will result in Station only connecting to a PMF enabled AP and rejecting all other AP's. An example of this configuration is given below. + + .. code-block:: c + + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASSWORD, + .pmf_cfg = { + .required = true + } + } + }; + +.. attention:: + + ``capable`` flag in `pmf_cfg` is deprecated and set to true internally. This is to take the additional security benefit of PMF whenever possible. + + +WPA3-Personal +------------- + +Introduction +++++++++++++ + +Wi-Fi Protected Access-3 (WPA3) is a set of enhancements to Wi-Fi access security intended to replace the current WPA2 standard. It includes new features and capabilities that offer significantly better protection against different types of attacks. It improves upon WPA2-Personal in following ways: + + - WPA3 uses Simultaneous Authentication of Equals (SAE), which is password-authenticated key agreement method based on Diffie-Hellman key exchange. Unlike WPA2, the technology is resistant to offline-dictionary attack, where the attacker attempts to determine shared password based on captured 4-way handshake without any further network interaction. + - Disallows outdated protocols such as TKIP, which is susceptible to simple attacks like MIC key recovery attack. + - Mandates Protected Management Frames (PMF), which provides protection for unicast and multicast robust management frames which include Disassoc and Deauth frames. This means that the attacker cannot disrupt an established WPA3 session by sending forged Assoc frames to the AP or Deauth/Disassoc frames to the Station. + - Provides forward secrecy, which means the captured data cannot be decrypted even if password is compromised after data transmission. + +Please refer to `Security `_ section of Wi-Fi Alliance's official website for further details. + +Setting up WPA3 with {IDF_TARGET_NAME} +++++++++++++++++++++++++++++++++++++++ + +In IDF Menuconfig under Wi-Fi component, a config option "Enable WPA3-Personal" is provided to Enable/Disable WPA3. By default it is kept enabled, if disabled {IDF_TARGET_NAME} will not be able to establish a WPA3 connection. Currently, WPA3 is supported only in the Station mode. Additionally, since PMF is mandated by WPA3 protocol, PMF Mode should be set to either Optional or Required while setting WiFi config. + +Refer to `Protected Management Frames (PMF)`_ on how to set this mode. + +After these settings are done, Station is ready to use WPA3-Personal. Application developers need not worry about the underlying security mode of the AP. WPA3-Personal is now the highest supported protocol in terms of security, so it will be automatically selected for the connection whenever available. For example, if an AP is configured to be in WPA3 Transition Mode, where it will advertise as both WPA2 and WPA3 capable, Station will choose WPA3 for the connection with above settings. +Note that Wi-Fi stack size requirement will increase 3kB when WPA3 is used. diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index 04689c7f02c1..51a3f11fb623 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -7,7 +7,7 @@ Wi-Fi Driver ------------------------------------ - Support Station-only mode, AP-only mode, Station/AP-coexistence mode - Support IEEE 802.11B, IEEE 802.11G, IEEE 802.11N and APIs to configure the protocol mode -- Support WPA/WPA2/WPA2-Enterprise and WPS +- Support WPA/WPA2/WPA3/WPA2-Enterprise and WPS - Support AMPDU, HT40, QoS and other key features - Support Modem-sleep - Support an Espressif-specific protocol which, in turn, supports up to **1 km** of data traffic @@ -22,7 +22,9 @@ How To Write a Wi-Fi Application Preparation +++++++++++ -Generally, the most effective way to begin your own Wi-Fi application is to select an example which is similar to your own application, and port the useful part into your project. It is not a MUST but it is strongly recommended that you take some time to read this article first, especially if you want to program a robust Wi-Fi application. This article is supplementary to the Wi-Fi APIs/Examples. It describes the principles of using the Wi-Fi APIs, the limitations of the current Wi-Fi API implementation, and the most common pitfalls in using Wi-Fi. This article also reveals some design details of the Wi-Fi driver. We recommend you to select an :example:`example `. +Generally, the most effective way to begin your own Wi-Fi application is to select an example which is similar to your own application, and port the useful part into your project. It is not a MUST but it is strongly recommended that you take some time to read this article first, especially if you want to program a robust Wi-Fi application. + +This article is supplementary to the Wi-Fi APIs/Examples. It describes the principles of using the Wi-Fi APIs, the limitations of the current Wi-Fi API implementation, and the most common pitfalls in using Wi-Fi. This article also reveals some design details of the Wi-Fi driver. We recommend you to select an :example:`example `. Setting Wi-Fi Compile-time Options ++++++++++++++++++++++++++++++++++++ @@ -62,8 +64,7 @@ Whether the error is critical or not depends on the API and the application scen - for non-recoverable, yet non-critical, errors, in which case printing the error code is a good method for error handling. - for non-recoverable, critical errors, in which case "assert" may be a good method for error handling. For example, if :cpp:func:`esp_wifi_set_mode` returns ESP_ERR_WIFI_NOT_INIT, it means that the Wi-Fi driver is not initialized by :cpp:func:`esp_wifi_init` successfully. You can detect this kind of error very quickly in the application development phase. -In esp_err.h, ESP_ERROR_CHECK checks the return values. It is a rather commonplace error-handling code and can be used -as the default error-handling code in the application development phase. However, we strongly recommend that API users write their own error-handling code. +In esp_err.h, ESP_ERROR_CHECK checks the return values. It is a rather commonplace error-handling code and can be used as the default error-handling code in the application development phase. However, we strongly recommend that API users write their own error-handling code. {IDF_TARGET_NAME} Wi-Fi API Parameter Initialization ---------------------------------------------------- @@ -419,40 +420,24 @@ Currently, the :cpp:func:`esp_wifi_scan_start()` API is supported only in Statio Scan Type +++++++++++++++++++++++++ -+------------------+--------------------------------------------------------------+ -| Mode | Description | -+==================+==============================================================+ -| Active Scan | Scan by sending a probe request. | -| | The default scan is an active scan. | -| | | -+------------------+--------------------------------------------------------------+ -| Passive Scan | No probe request is sent out. Just switch to the specific | -| | channel and wait for a beacon. | -| | Application can enable it via the scan_type field of | -| | wifi_scan_config_t. | -| | | -+------------------+--------------------------------------------------------------+ -| Foreground Scan | This scan is applicable when there is no Wi-Fi connection | -| | in Station mode. Foreground or background scanning is | -| | controlled by the Wi-Fi driver and cannot be configured by | -| | the application. | -+------------------+--------------------------------------------------------------+ -| Background Scan | This scan is applicable when there is a Wi-Fi connection in | -| | Station mode or in Station+AP mode. | -| | Whether it is a foreground scan or background scan depends on| -| | the Wi-Fi driver and cannot be configured by the application.| -| | | -+------------------+--------------------------------------------------------------+ -| All-Channel Scan | It scans all of the channels. | -| | If the channel field of wifi_scan_config_t is set | -| | to 0, it is an all-channel scan. | -| | | -+------------------+--------------------------------------------------------------+ -| Specific Channel | It scans specific channels only. | -| Scan | If the channel field of wifi_scan_config_t set to | -| | 1, it is a specific-channel scan. | -| | | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Mode + - Description + * - Active Scan + - Scan by sending a probe request. The default scan is an active scan. + * - Passive Scan + - No probe request is sent out. Just switch to the specific channel and wait for a beacon. Application can enable it via the scan_type field of wifi_scan_config_t. + * - Foreground Scan + - This scan is applicable when there is no Wi-Fi connection in station mode. Foreground or background scanning is controlled by the Wi-Fi driver and cannot be configured by the application. + * - Background Scan + - This scan is applicable when there is a Wi-Fi connection in station mode or in station/AP mode. Whether it is a foreground scan or background scan depends on the Wi-Fi driver and cannot be configured by the application. + * - All-Channel Scan + - It scans all of the channels. If the channel field of wifi_scan_config_t is set to 0, it is an all-channel scan. + * - Specific Channel Scan + - It scans specific channels only. If the channel field of wifi_scan_config_t set to 1-14, it is a specific-channel scan. The scan modes in above table can be combined arbitrarily, so we totally have 8 different scans: @@ -470,51 +455,35 @@ Scan Configuration The scan type and other per-scan attributes are configured by :cpp:func:`esp_wifi_scan_start`. The table below provides a detailed description of wifi_scan_config_t. -+------------------+--------------------------------------------------------------+ -| Field | Description | -+==================+==============================================================+ -| ssid | If the SSID is not NULL, it is only the AP with the same | -| | SSID that can be scanned. | -| | | -+------------------+--------------------------------------------------------------+ -| bssid | If the BSSID is not NULL, it is only the AP with the same | -| | BSSID that can be scanned. | -| | | -+------------------+--------------------------------------------------------------+ -| channel | If "channel" is 0, there will be an all-channel scan; | -| | otherwise, there will be a specific-channel scan. | -| | | -+------------------+--------------------------------------------------------------+ -| show_hidden | If "show_hidden" is 0, the scan ignores the AP with a hidden | -| | SSID; otherwise, the scan considers the hidden AP a normal | -| | one. | -+------------------+--------------------------------------------------------------+ -| scan_type | If "scan_type" is WIFI_SCAN_TYPE_ACTIVE, the scan is | -| | "active"; otherwise, it is a "passive" one. | -| | | -+------------------+--------------------------------------------------------------+ -| scan_time | This field is used to control how long the scan dwells on | -| | each channel. | -| | | -| | For passive scans, scan_time.passive designates the dwell | -| | time for each channel. | -| | | -| | For active scans, dwell times for each channel are listed | -| | in the table below. Here, min is short for scan | -| | time.active.min and max is short for scan_time.active.max. | -| | | -| | - min=0, max=0: scan dwells on each channel for 120 ms. | -| | - min>0, max=0: scan dwells on each channel for 120 ms. | -| | - min=0, max>0: scan dwells on each channel for ``max`` ms. | -| | - min>0, max>0: the minimum time the scan dwells on each | -| | channel is ``min`` ms. If no AP is found during this time | -| | frame, the scan switches to the next channel. Otherwise, | -| | the scan dwells on the channel for ``max`` ms. | -| | | -| | If you want to improve the performance of the | -| | the scan, you can try to modify these two parameters. | -| | | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Field + - Description + * - ssid + - If the SSID is not NULL, it is only the AP with the same SSID that can be scanned. + * - bssid + - If the BSSID is not NULL, it is only the AP with the same BSSID that can be scanned. + * - channel + - If “channel” is 0, there will be an all-channel scan; otherwise, there will be a specific-channel scan. + * - show_hidden + - If “show_hidden” is 0, the scan ignores the AP with a hidden SSID; otherwise, the scan considers the hidden AP a normal one. + * - scan_type + - If “scan_type” is WIFI_SCAN_TYPE_ACTIVE, the scan is “active”; otherwise, it is a “passive” one. + * - scan_time + - This field is used to control how long the scan dwells on each channel. + + For passive scans, scan_time.passive designates the dwell time for each channel. + + For active scans, dwell times for each channel are listed in the table below. Here, min is short for scan time.active.min and max is short for scan_time.active.max. + + - min=0, max=0: scan dwells on each channel for 120 ms. + - min>0, max=0: scan dwells on each channel for 120 ms. + - min=0, max>0: scan dwells on each channel for ``max`` ms. + - min>0, max>0: the minimum time the scan dwells on each channel is ``min`` ms. If no AP is found during this time frame, the scan switches to the next channel. Otherwise, the scan dwells on the channel for ``max`` ms. + + If you want to improve the performance of the scan, you can try to modify these two parameters. There are also some global scan attributes which are configured by API :cpp:func:`esp_wifi_set_config`, refer to `Station Basic Configuration`_ @@ -774,252 +743,258 @@ Wi-Fi Reason Code The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first column is the macro name defined in esp_wifi_types.h. The common prefix *WIFI_REASON* is removed, which means that *UNSPECIFIED* actually stands for *WIFI_REASON_UNSPECIFIED* and so on. The second column is the value of the reason. The third column is the standard value to which this reason is mapped in section 8.4.1.7 of IEEE 802.11-2012. (For more information, refer to the standard mentioned above.) The last column is a description of the reason. -+---------------------------+-------+---------+-------------------------------------------------------------+ -| Reason code | Value |Mapped To| Description | -+===========================+=======+=========+=============================================================+ -| UNSPECIFIED | 1 | 1 | Generally, it means an internal failure, e.g., the memory | -| | | | runs out, the internal TX fails, or the reason is received | -| | | | from the remote side, etc. | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AUTH_EXPIRE | 2 | 2 | The previous authentication is no longer valid. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - auth is timed out. | -| | | | - the reason is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP has not received any packets from the station | -| | | | in the past five minutes. | -| | | | - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`.| -| | | | - the station is de-authed by calling | -| | | | :cpp:func:`esp_wifi_deauth_sta()`. | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AUTH_LEAVE | 3 | 3 | De-authenticated, because the sending STA is | -| | | | leaving (or has left). | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_EXPIRE | 4 | 4 | Disassociated due to inactivity. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP has not received any packets from the | -| | | | station in the past five minutes. | -| | | | - the AP is stopped by calling :cpp:func:`esp_wifi_stop()` | -| | | | - the station is de-authed by calling | -| | | | :cpp:func:`esp_wifi_deauth_sta()` | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_TOOMANY | 5 | 5 | Disassociated, because the AP is unable to handle | -| | | | all currently associated STAs at the same time. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the stations associated with the AP reach the | -| | | | maximum number that the AP can support. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| NOT_AUTHED | 6 | 6 | Class-2 frame received from a non-authenticated STA. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP receives a packet with data from a | -| | | | non-authenticated station. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| NOT_ASSOCED | 7 | 7 | Class-3 frame received from a non-associated STA. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP receives a packet with data from a | -| | | | non-associated station. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_LEAVE | 8 | 8 | Disassociated, because the sending STA is leaving (or has | -| | | | left) BSS. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | - the station is disconnected by | -| | | | :cpp:func:`esp_wifi_disconnect()` and other APIs. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_NOT_AUTHED | 9 | 9 | STA requesting (re)association is not authenticated by the | -| | | | responding STA. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP receives packets with data from an | -| | | | associated, yet not authenticated, station. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| DISASSOC_PWRCAP_BAD | 10 | 10 | Disassociated, because the information in the Power | -| | | | Capability element is unacceptable. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| DISASSOC_SUPCHAN_BAD | 11 | 11 | Disassociated, because the information in the Supported | -| | | | Channels element is unacceptable. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| IE_INVALID | 13 | 13 | Invalid element, i.e. an element whose content does not meet| -| | | | the specifications of the Standard in frame formats clause. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP parses a wrong WPA or RSN IE. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| MIC_FAILURE | 14 | 14 | Message integrity code (MIC) failure. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| 4WAY_HANDSHAKE_TIMEOUT | 15 | 15 | Four-way handshake times out. For legacy reasons, in ESP | -| | | | this reason-code is replaced with | -| | | | WIFI_REASON_HANDSHAKE_TIMEOUT. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - the handshake times out. | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| GROUP_KEY_UPDATE_TIMEOUT | 16 | 16 | Group-Key Handshake times out. | -| | | | | -| | | | For the ESP station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| IE_IN_4WAY_DIFFERS | 17 | 17 | The element in the four-way handshake is different from the | -| | | | (Re-)Association Request/Probe and Response/Beacon frame. | -| | | | | -| | | | For the ESP station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | - the station finds that the four-way handshake IE differs | -| | | | from the IE in the (Re-)Association Request/Probe and | -| | | | Response/Beacon frame. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| GROUP_CIPHER_INVALID | 18 | 18 | Invalid group cipher. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| PAIRWISE_CIPHER_INVALID | 19 | 19 | Invalid pairwise cipher. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AKMP_INVALID | 20 | 20 | Invalid AKMP. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| UNSUPP_RSN_IE_VERSION | 21 | 21 | Unsupported RSNE version. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| INVALID_RSN_IE_CAP | 22 | 22 | Invalid RSNE capabilities. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| 802_1X_AUTH_FAILED | 23 | 23 | IEEE 802.1X. authentication failed. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - 802.1 x authentication fails. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| CIPHER_SUITE_REJECTED | 24 | 24 | Cipher suite rejected due to security policies. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| BEACON_TIMEOUT | 200 |reserved | Espressif-specific Wi-Fi reason-code: when the station | -| | | | loses N beacons continuously, it will disrupt the connection| -| | | | and report this reason. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| NO_AP_FOUND | 201 |reserved | Espressif-specific Wi-Fi reason-code: when the station | -| | | | fails to scan the target AP, this reason code will be | -| | | | reported. | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AUTH_FAIL | 202 |reserved | Espressif-specific Wi-Fi reason-code: the | -| | | | authentication fails, but not because of a timeout. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_FAIL | 203 |reserved | Espressif-specific Wi-Fi reason-code: the association | -| | | | fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| HANDSHAKE_TIMEOUT | 204 |reserved | Espressif-specific Wi-Fi reason-code: the | -| | | | handshake fails for the same reason as that in | -| | | | WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| CONNECTION_FAIL | 205 |reserved | Espressif-specific Wi-Fi reason-code: the | -| | | | connection to the AP has failed. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 5 10 12 40 + + * - Reason code + - Value + - Mapped To + - Description + * - UNSPECIFIED + - 1 + - 1 + - Generally, it means an internal failure, e.g., the memory runs out, the internal TX fails, or the reason is received from the remote side, etc. + * - AUTH_EXPIRE + - 2 + - 2 + - The previous authentication is no longer valid. + + For the ESP station, this reason is reported when: + + - auth is timed out. + - the reason is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP has not received any packets from the station in the past five minutes. + - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`. + - the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`. + * - AUTH_LEAVE + - 3 + - 3 + - De-authenticated, because the sending station is leaving (or has left). + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - ASSOC_EXPIRE + - 4 + - 4 + - Disassociated due to inactivity. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP has not received any packets from the station in the past five minutes. + - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`. + - the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`. + * - ASSOC_TOOMANY + - 5 + - 5 + - Disassociated, because the AP is unable to handle all currently associated STAs at the same time. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the stations associated with the AP reach the maximum number that the AP can support. + * - NOT_AUTHED + - 6 + - 6 + - Class-2 frame received from a non-authenticated STA. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP receives a packet with data from a non-authenticated station. + * - NOT_ASSOCED + - 7 + - 7 + - Class-3 frame received from a non-associated STA. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP receives a packet with data from a non-associated station. + * - ASSOC_LEAVE + - 8 + - 8 + - Disassociated, because the sending station is leaving (or has left) BSS. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + - the station is disconnected by :cpp:func:`esp_wifi_disconnect()` and other APIs. + * - ASSOC_NOT_AUTHED + - 9 + - 9 + - station requesting (re)association is not authenticated by the responding STA. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP receives packets with data from an associated, yet not authenticated, station. + * - DISASSOC_PWRCAP_BAD + - 10 + - 10 + - Disassociated, because the information in the Power Capability element is unacceptable. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - DISASSOC_SUPCHAN_BAD + - 11 + - 11 + - Disassociated, because the information in the Supported Channels element is unacceptable. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - IE_INVALID + - 13 + - 13 + - Invalid element, i.e. an element whose content does not meet the specifications of the Standard in frame formats clause. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP parses a wrong WPA or RSN IE. + * - MIC_FAILURE + - 14 + - 14 + - Message integrity code (MIC) failure. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - 4WAY_HANDSHAKE_TIMEOUT + - 15 + - 15 + - Four-way handshake times out. For legacy reasons, in ESP this reason-code is replaced with WIFI_REASON_HANDSHAKE_TIMEOUT. + + For the ESP station, this reason is reported when: + + - the handshake times out. + - it is received from the AP. + * - GROUP_KEY_UPDATE_TIMEOUT + - 16 + - 16 + - Group-Key Handshake times out. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - IE_IN_4WAY_DIFFERS + - 17 + - 17 + - The element in the four-way handshake is different from the (Re-)Association Request/Probe and Response/Beacon frame. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + - the station finds that the four-way handshake IE differs from the IE in the (Re-)Association Request/Probe and Response/Beacon frame. + * - GROUP_CIPHER_INVALID + - 18 + - 18 + - Invalid group cipher. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - PAIRWISE_CIPHER_INVALID + - 19 + - 19 + - Invalid pairwise cipher. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - AKMP_INVALID + - 20 + - 20 + - Invalid AKMP. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - UNSUPP_RSN_IE_VERSION + - 21 + - 21 + - Unsupported RSNE version. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - INVALID_RSN_IE_CAP + - 22 + - 22 + - Invalid RSNE capabilities. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - 802_1X_AUTH_FAILED + - 23 + - 23 + - IEEE 802.1X. authentication failed. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - IEEE 802.1X. authentication fails. + * - CIPHER_SUITE_REJECTED + - 24 + - 24 + - Cipher suite rejected due to security policies. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - BEACON_TIMEOUT + - 200 + - reserved + - Espressif-specific Wi-Fi reason-code: when the station loses N beacons continuously, it will disrupt the connection and report this reason. + * - NO_AP_FOUND + - 201 + - reserved + - Espressif-specific Wi-Fi reason-code: when the station fails to scan the target AP, this reason code will be reported. + * - AUTH_FAIL + - 202 + - reserved + - Espressif-specific Wi-Fi reason-code: the authentication fails, but not because of a timeout. + * - ASSOC_FAIL + - 203 + - reserved + - Espressif-specific Wi-Fi reason-code: the association fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY. + * - HANDSHAKE_TIMEOUT + - 204 + - reserved + - Espressif-specific Wi-Fi reason-code: the handshake fails for the same reason as that in WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT. + * - CONNECTION_FAIL + - 205 + - reserved + - Espressif-specific Wi-Fi reason-code: the connection to the AP has failed. {IDF_TARGET_NAME} Wi-Fi Station Connecting When Multiple APs Are Found ---------------------------------------------------------------------- @@ -1055,101 +1030,54 @@ Wi-Fi Mode +++++++++++++++++++++++++ Call :cpp:func:`esp_wifi_set_mode()` to set the Wi-Fi mode. -+------------------+--------------------------------------------------------------+ -| Mode | Description | -+==================+==============================================================+ -| WIFI_MODE_NULL | NULL mode: in this mode, the internal data struct is not | -| | allocated to the station and the AP, while both the | -| | station and AP interfaces are not initialized for | -| | RX/TX Wi-Fi data. Generally, this mode is used for Sniffer, | -| | or when you only want to stop both the STA and the AP | -| | without calling :cpp:func:`esp_wifi_deinit()` to unload the | -| | whole Wi-Fi driver. | -+------------------+--------------------------------------------------------------+ -| WIFI_MODE_STA | Station mode: in this mode, :cpp:func:`esp_wifi_start()` will| -| | init the internal station data, while the station's interface| -| | is ready for the RX and TX Wi-Fi data. After | -| | :cpp:func:`esp_wifi_connect()` is called, the STA will | -| | connect to the target target AP. | -+------------------+--------------------------------------------------------------+ -| WIFI_MODE_AP | AP mode: in this mode, :cpp:func:`esp_wifi_start()` will init| -| | the internal AP data, while the AP's interface is ready | -| | for RX/TX Wi-Fi data. Then, the Wi-Fi driver starts broad- | -| | casting beacons, and the AP is ready to get connected | -| | to other stations. | -+------------------+--------------------------------------------------------------+ -| WIFI_MODE_APSTA | Station-AP coexistence mode: in this mode, | -| | :cpp:func:`esp_wifi_start()` will simultaneously init both | -| | the station and the AP.This is done in station mode and AP | -| | mode. Please note that the channel of the external AP, which | -| | the ESP Station is connected to, has higher priority over the| -| | ESP AP channel. | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Mode + - Description + * - WIFI_MODE_NULL + - NULL mode: in this mode, the internal data struct is not allocated to the station and the AP, while both the station and AP interfaces are not initialized for RX/TX Wi-Fi data. Generally, this mode is used for Sniffer, or when you only want to stop both the station and the AP without calling :cpp:func:`esp_wifi_deinit()` to unload the whole Wi-Fi driver. + * - WIFI_MODE_STA + - Station mode: in this mode, :cpp:func:`esp_wifi_start()` will init the internal station data, while the station’s interface is ready for the RX and TX Wi-Fi data. After :cpp:func:`esp_wifi_connect()`, the station will connect to the target AP. + * - WIFI_MODE_AP + - AP mode: in this mode, :cpp:func:`esp_wifi_start()` will init the internal AP data, while the AP’s interface is ready for RX/TX Wi-Fi data. Then, the Wi-Fi driver starts broad-casting beacons, and the AP is ready to get connected to other stations. + * - WIFI_MODE_APSTA + - Station/AP coexistence mode: in this mode, :cpp:func:`esp_wifi_start()` will simultaneously init both the station and the AP. This is done in station mode and AP mode. Please note that the channel of the external AP, which the ESP station is connected to, has higher priority over the ESP AP channel. Station Basic Configuration +++++++++++++++++++++++++++++++++++++ API esp_wifi_set_config() can be used to configure the station. The table below describes the fields in detail. -+------------------+--------------------------------------------------------------+ -| Field | Description | -+==================+==============================================================+ -| ssid | This is the SSID of the target AP, to which the station wants| -| | to connect to. | -| | | -+------------------+--------------------------------------------------------------+ -| password | Password of the target AP. | -| | | -+------------------+--------------------------------------------------------------+ -| scan_method | For WIFI_FAST_SCAN scan, the scan ends when the first matched| -| | AP is found, for WIFI_ALL_CHANNEL_SCAN, the scan finds all | -| | matched APs on all channels. | -| | The default scan is WIFI_FAST_SCAN. | -+------------------+--------------------------------------------------------------+ -| bssid_set | If bssid_set is 0, the station connects to the AP whose SSID | -| | is the same as the field "ssid", while the field "bssid" | -| | is ignored. In all other cases, the station connects to | -| | the AP whose SSID is the same as the "ssid" field, while its | -| | BSSID is the same the "bssid" field . | -+------------------+--------------------------------------------------------------+ -| bssid | This is valid only when bssid_set is 1; see field | -| | "bssid_set". | -+------------------+--------------------------------------------------------------+ -| channel | If the channel is 0, the station scans the channel 1 ~ N to | -| | search for the target AP; otherwise, the station starts by | -| | scanning the channel whose value is the same as that of the | -| | "channel" field, and then scans others to find the target AP.| -| | If you do not know which channel the target AP is running on,| -| | set it to 0. | -+------------------+--------------------------------------------------------------+ -| sort_method | This field is only for WIFI_ALL_CHANNEL_SCAN | -| | | -| | If the sort_method is WIFI_CONNECT_AP_BY_SIGNAL, all matched | -| | APs are sorted by signal, for AP with best signal will be | -| | connected firstly. E.g. if the station want to connect AP | -| | whose ssid is "apxx", the scan finds two AP whose ssid equals| -| | to "apxx", the first AP's signal is -90 dBm, the second AP's | -| | signal is -30 dBm, the station connects the second AP | -| | firstly, it doesn't connect the first one unless it fails to | -| | connect the second one. | -| | | -| | If the sort_method is WIFI_CONNECT_AP_BY_SECURITY, all | -| | matched APs are sorted by security. E.g. if the station wants| -| | to connect AP whose ssid is "apxx", the scan finds two AP | -| | whose ssid is "apxx", the security of the first found AP is | -| | open while the second one is WPA2, the stations connects to | -| | the second AP firstly, it doesn't connect the second one | -| | unless it fails to connect the first one. | -+------------------+--------------------------------------------------------------+ -| threshold | The threshold is used to filter the found AP, if the RSSI or | -| | security mode is less than the configured threshold, the AP | -| | will be discard. | -| | | -| | If the RSSI set to 0, it means default threshold, the default| -| | RSSI threshold is -127 dBm. If the authmode threshold is set | -| | to 0, it means default threshold, the default authmode | -| | threshold is open. | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Field + - Description + * - ssid + - This is the SSID of the target AP, to which the station wants to connect to. + * - password + - Password of the target AP. + * - scan_method + - For WIFI_FAST_SCAN scan, the scan ends when the first matched AP is found. For WIFI_ALL_CHANNEL_SCAN, the scan finds all matched APs on all channels. The default scan is WIFI_FAST_SCAN. + * - bssid_set + - If bssid_set is 0, the station connects to the AP whose SSID is the same as the field “ssid”, while the field “bssid” is ignored. In all other cases, the station connects to the AP whose SSID is the same as the “ssid” field, while its BSSID is the same the “bssid” field . + * - bssid + - This is valid only when bssid_set is 1; see field “bssid_set”. + * - channel + - If the channel is 0, the station scans the channel 1 ~ N to search for the target AP; otherwise, the station starts by scanning the channel whose value is the same as that of the “channel” field, and then scans others to find the target AP. If you do not know which channel the target AP is running on, set it to 0. + * - sort_method + - This field is only for WIFI_ALL_CHANNEL_SCAN. + + If the sort_method is WIFI_CONNECT_AP_BY_SIGNAL, all matched APs are sorted by signal, for AP with best signal will be connected firstly. E.g. if the station want to connect AP whose ssid is “apxx”, the scan finds two AP whose ssid equals to “apxx”, the first AP’s signal is -90 dBm, the second AP’s signal is -30 dBm, the station connects the second AP firstly, it doesn’t connect the first one unless it fails to connect the second one. + + If the sort_method is WIFI_CONNECT_AP_BY_SECURITY, all matched APs are sorted by security. E.g. if the station wants to connect AP whose ssid is “apxx”, the scan finds two AP whose ssid is “apxx”, the security of the first found AP is open while the second one is WPA2, the stations connects to the second AP firstly, it doesn’t connect the second one unless it fails to connect the first one. + * - threshold + - The threshold is used to filter the found AP, if the RSSI or security mode is less than the configured threshold, the AP will be discard. + + If the RSSI set to 0, it means default threshold, the default RSSI threshold is -127 dBm. If the authmode threshold is set to 0, it means default threshold, the default authmode threshold is open. .. attention:: WEP/WPA security modes are deprecated in IEEE 802.11-2016 specifications and are recommended not to be used. These modes can be rejected using authmode threshold by setting threshold as WPA2 by threshold.authmode as WIFI_AUTH_WPA2_PSK. @@ -1159,80 +1087,52 @@ AP Basic Configuration API esp_wifi_set_config() can be used to configure the AP. The table below describes the fields in detail. -+------------------+--------------------------------------------------------------+ -| Field | Description | -+==================+==============================================================+ -| ssid | SSID of AP; if the ssid[0] is 0xFF and ssid[1] is 0xFF, | -| | the AP defaults the SSID to ESP_aabbcc, where "aabbcc" | -| | is the last three bytes of the AP MAC. | -| | | -+------------------+--------------------------------------------------------------+ -| password | Password of AP; if the auth mode is WIFI_AUTH_OPEN, | -| | this field will be ignored. | -| | | -+------------------+--------------------------------------------------------------+ -| ssid_len | Length of SSID; if ssid_len is 0, check the SSID until there | -| | is a termination character. If ssid_len > 32, change it to | -| | 32; otherwise, set the SSID length according to ssid_len. | -| | | -+------------------+--------------------------------------------------------------+ -| channel | Channel of AP; if the channel is out of range, the Wi-Fi | -| | driver defaults the channel to channel 1. So, please make | -| | sure the channel is within the required range. | -| | For more details, refer to `Wi-Fi Country Code`_. | -+------------------+--------------------------------------------------------------+ -| authmode | Auth mode of ESP AP; currently, ESP Wi-Fi does not | -| | support AUTH_WEP. If the authmode is an invalid value, | -| | AP defaults the value to WIFI_AUTH_OPEN. | -| | | -+------------------+--------------------------------------------------------------+ -| ssid_hidden | If ssid_hidden is 1, AP does not broadcast the SSID; | -| | otherwise, it does broadcast the SSID. | -| | | -+------------------+--------------------------------------------------------------+ -| max_connection | Currently, ESP Wi-Fi supports up to 10 Wi-Fi connections. | -| | If max_connection > 10, AP defaults the value to 10. | -| | | -+------------------+--------------------------------------------------------------+ -| beacon_interval | Beacon interval; the value is 100 ~ 60000 ms, with default | -| | value being 100 ms. If the value is out of range, | -| | AP defaults it to 100 ms. | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - Field + - Description + * - ssid + - SSID of AP; if the ssid[0] is 0xFF and ssid[1] is 0xFF, the AP defaults the SSID to ESP_aabbcc, where “aabbcc” is the last three bytes of the AP MAC. + * - password + - Password of AP; if the auth mode is WIFI_AUTH_OPEN, this field will be ignored. + * - ssid_len + - Length of SSID; if ssid_len is 0, check the SSID until there is a termination character. If ssid_len > 32, change it to 32; otherwise, set the SSID length according to ssid_len. + * - channel + - Channel of AP; if the channel is out of range, the Wi-Fi driver defaults the channel to channel 1. So, please make sure the channel is within the required range. For more details, refer to `Wi-Fi Country Code`_. + * - authmode + - Auth mode of ESP AP; currently, ESP Wi-Fi does not support AUTH_WEP. If the authmode is an invalid value, AP defaults the value to WIFI_AUTH_OPEN. + * - ssid_hidden + - If ssid_hidden is 1, AP does not broadcast the SSID; otherwise, it does broadcast the SSID. + * - max_connection + - Currently, ESP Wi-Fi supports up to 10 Wi-Fi connections. If max_connection > 10, AP defaults the value to 10. + * - beacon_interval + - Beacon interval; the value is 100 ~ 60000 ms, with default value being 100 ms. If the value is out of range, AP defaults it to 100 ms. Wi-Fi Protocol Mode +++++++++++++++++++++++++ Currently, the IDF supports the following protocol modes: -+--------------------+------------------------------------------------------------+ -| Protocol Mode | Description | -+====================+============================================================+ -| 802.11 B | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B) to set | -| | the station/AP to 802.11B-only mode. | -| | | -+--------------------+------------------------------------------------------------+ -| 802.11 BG | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_ | -| | PROTOCOL_11G) to set the station/AP to 802.11BG mode. | -| | | -+--------------------+------------------------------------------------------------+ -| 802.11 BGN | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| | -| | WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N) to set the station/ | -| | AP to BGN mode. | -| | | -+--------------------+------------------------------------------------------------+ -| 802.11 BGNLR | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| | -| | WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR) | -| | to set the station/AP to BGN and the | -| | Espressif-specific mode. | -+--------------------+------------------------------------------------------------+ -| 802.11 LR | Call esp_wifi_set_protocol (ifx, WIFI_PROTOCOL_LR) to set | -| | the station/AP only to the Espressif-specific mode. | -| | | -| | **This mode is an Espressif-patented mode which can achieve| -| | a one-kilometer line of sight range. Please, make sure both| -| | the station and the AP are connected to an | -| | ESP device** | -+--------------------+------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - Protocol Mode + - Description + * - 802.11b + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B) to set the station/AP to 802.11b-only mode. + * - 802.11bg + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G) to set the station/AP to 802.11bg mode. + * - 802.11bgn + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N) to set the station/ AP to BGN mode. + * - 802.11 BGNLR + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR) to set the station/AP to BGN and the Espressif-specific mode. + * - 802.11 LR + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_LR) to set the station/AP only to the Espressif-specific mode. + + **This mode is an Espressif-patented mode which can achieve a one-kilometer line of sight range. Please, make sure both the station and the AP are connected to an ESP device.** Long Range (LR) +++++++++++++++++++++++++ @@ -1306,148 +1206,96 @@ The general conditions for using LR are: Wi-Fi Country Code +++++++++++++++++++++++++ -Call :cpp:func:`esp_wifi_set_country()` to set the country info. -The table below describes the fields in detail, please consult local 2.4 GHz RF operating regulations before configuring these fields. - -+------------------+-----------------------------------------------------------------------------------+ -| Field | Description | -+==================+===================================================================================+ -| cc[3] | Country code string, this attributes identify the country or noncountry entity | -| | in which the station/AP is operating. If it's a country, the first two | -| | octets of this string is the two character country info as described in document | -| | ISO/IEC3166-1. The third octect is one of the following: | -| | | -| | - an ASCII space character, if the regulations under which the station/AP is | -| | operating encompass all environments for the current frequency band in the | -| | country. | -| | - an ASCII 'O' character if the regulations under which the station/AP is | -| | operating are for an outdoor environment only. | -| | - an ASCII 'I' character if the regulations under which the station/AP is | -| | operating are for an indoor environment only. | -| | - an ASCII 'X' character if the station/AP is operating under a noncountry | -| | entity. The first two octets of the noncountry entity is two ASCII 'XX' | -| | characters. | -| | - the binary representation of the Operating Class table number currently in use.| -| | Refer to Annex E, IEEE Std 802.11-2012. | -| | | -+------------------+-----------------------------------------------------------------------------------+ -| schan | Start channel, it's the minimum channel number of the regulations under which the | -| | station/AP can operate. | -| | | -+------------------+-----------------------------------------------------------------------------------+ -| nchan | Total number of channels as per the regulations, e.g. if the schan=1, nchan=13, | -| | it means the station/AP can send data from channel 1 to 13. | -| | | -+------------------+-----------------------------------------------------------------------------------+ -| policy | Country policy, this field control which country info will be used if the | -| | configured country info is conflict with the connected AP's. More description | -| | about policy is provided in following section. | -| | | -+------------------+-----------------------------------------------------------------------------------+ +Call :cpp:func:`esp_wifi_set_country()` to set the country info. The table below describes the fields in detail, please consult local 2.4 GHz RF operating regulations before configuring these fields. -The default country info is {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO}, if the Wi-Fi Mode is station/AP coexist mode, they share the same configured country info. Sometimes, the country info of AP, to which the station is connected, is different from the country info of configured. For example, the configured station has country info {.cc="JP", .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO}, but the connected AP has country info {.cc="CN", .schan=1, .nchan=13}, then country info of connected AP's is used. -Following table depicts which country info is used in different Wi-Fi Mode and different country policy, also describe the impact to active scan. +.. list-table:: + :header-rows: 1 + :widths: 15 55 -+-----------+----------------------------+----------------------------------------------------------------+ -| WiFi Mode | Policy | Description | -+===========+============================+================================================================+ -| Station | WIFI_COUNTRY_POLICY_AUTO | If the connected AP has country IE in its beacon, the country | -| | | info equals to the country info in beacon, otherwise, use | -| | | default country info. | -| | | | -| | | For scan: | -| | | | -| | | -If schan+nchan-1 >11 : | -| | | Use active scan from schan to 11 and use passive scan | -| | | from 12 to schan+nchan-1. | -| | | | -| | | -If schan+nchan-1 <= 11 : | -| | | Use active scan from schan to schan+nchan-1. | -| | | | -| | | Always keep in mind that if an AP with hidden SSID | -| | | is set to a passive scan channel, the passive scan will not | -| | | find it. In other words, if the application hopes to find the | -| | | AP with hidden SSID in every channel, the policy of | -| | | country info should be configured to | -| | | WIFI_COUNTRY_POLICY_MANUAL. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -| Station | WIFI_COUNTRY_POLICY_MANUAL | Always use the configured country info. | -| | | | -| | | For scan, scans channel "schan" to "schan+nchan-1" with active | -| | | scan. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -| AP | WIFI_COUNTRY_POLICY_AUTO | Always use the configured country info. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -| AP | WIFI_COUNTRY_POLICY_MANUAL | Always use the configured country info. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -|Station/AP-| WIFI_COUNTRY_POLICY_AUTO | If the station doesn't connects to any AP, the AP use the | -| | | configured country info. | -|coexistence| | If the station connects to an AP, the AP has the same | -| | | country info as the station. | -| | | | -| | | Same as station mode with policy WIFI_COUNTRY_POLICY_AUTO. | -+-----------+----------------------------+----------------------------------------------------------------+ + * - Field + - Description + * - cc[3] + - Country code string, this attributes identify the country or noncountry entity in which the station/AP is operating. If it’s a country, the first two octets of this string is the two character country info as described in document ISO/IEC3166-1. The third octect is one of the following: -Home Channel -************************* + - an ASCII space character, if the regulations under which the station/AP is operating encompass all environments for the current frequency band in the country. + - an ASCII ‘O’ character if the regulations under which the station/AP is operating are for an outdoor environment only. + - an ASCII ‘I’ character if the regulations under which the station/AP is operating are for an indoor environment only. + - an ASCII ‘X’ character if the station/AP is operating under a noncountry entity. The first two octets of the noncountry entity is two ASCII ‘XX’ characters. + - the binary representation of the Operating Class table number currently in use. Refer to Annex E, IEEE Std 802.11-2012. -In AP mode, the home channel is defined as the AP channel. In Station mode, home channel is defined as the channel of AP which the station is connected to. In Station/AP-coexistence mode, the home channel of AP and station must be the same, if they are different, the station's home channel is always in priority. Take the following as an example: the AP is on channel 6, and the station connects to an AP whose channel is 9. Since the station's home channel has higher priority, the AP needs to switch its channel from 6 to make sure that it has the same home channel as the station. While switching channel, the {IDF_TARGET_NAME} in SoftAP mode will notify the connected stations about the channel migration using a Channel Switch Announcement (CSA). Station that supports channel switching will transit without disconnecting and reconnecting to the SoftAP. + * - schan + - Start channel, it’s the minimum channel number of the regulations under which the station/AP can operate. + * - nchan + - Total number of channels as per the regulations, e.g. if the schan=1, nchan=13, it means the station/AP can send data from channel 1 to 13. + * - policy + - Country policy, this field control which country info will be used if the configured country info is conflict with the connected AP’s. More description about policy is provided in following section. +The default country info is {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO}, if the Wi-Fi Mode is station/AP coexist mode, they share the same configured country info. Sometimes, the country info of AP, to which the station is connected, is different from the country info of configured. For example, the configured station has country info {.cc="JP", .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO}, but the connected AP has country info {.cc="CN", .schan=1, .nchan=13}, then country info of connected AP's is used. -Wi-Fi Vendor IE Configuration -+++++++++++++++++++++++++++++++++++ +Following table depicts which country info is used in different Wi-Fi Mode and different country policy, also describe the impact to active scan. -By default, all Wi-Fi management frames are processed by the Wi-Fi driver, and the application does not need to care about them. Some applications, however, may have to handle the beacon, probe request, probe response and other management frames. For example, if you insert some vendor-specific IE into the management frames, it is only the management frames which contain this vendor-specific IE that will be processed. In {IDF_TARGET_NAME}, :cpp:func:`esp_wifi_set_vendor_ie()` and :cpp:func:`esp_wifi_set_vendor_ie_cb()` are responsible for this kind of tasks. +.. list-table:: + :header-rows: 1 + :widths: 15 15 35 -Wi-Fi Security -------------------------------- + * - Wi-Fi Mode + - Policy + - Description + * - Station + - WIFI_COUNTRY_POLICY_AUTO + - If the connected AP has country IE in its beacon, the country info equals to the country info in beacon, otherwise, use default country info. -In addition to traditional security methods (WEP/WPA-TKIP/WPA2-CCMP), {IDF_TARGET_NAME} Wi-Fi now supports state-of-the-art security protocols, namely Protected Management Frames based on 802.11w standard and Wi-Fi Protected Access 3 (WPA3-Personal). Together, PMF and WPA3 provide better privacy and robustness against known attacks in traditional modes. + For scan: -Protected Management Frames (PMF) -++++++++++++++++++++++++++++++++++ + - If schan+nchan-1 >11 : -In Wi-Fi, management frames such as beacons, probes, (de)authentication, (dis)association are used by non-AP stations to scan and connect to an AP. Unlike data frames, these frames are sent unencrypted. -An attacker can use eavesdropping and packet injection to send spoofed (de)authentication/(dis)association frames at the right time, leading to following attacks in case of unprotected management frame exchanges. + Use active scan from schan to 11 and use passive scan from 12 to schan+nchan-1. - - DOS attack on one or all clients in the range of the attacker. - - Tearing down existing association on AP side by sending association request. - - Forcing a client to perform 4-way handshake again in case PSK is compromised in order to get PTK. - - Getting SSID of hidden network from association request. - - Launching man-in-the-middle attack by forcing clients to deauth from legitimate AP and associating to a rogue one. + - If schan+nchan-1 <= 11 : -PMF provides protection against these attacks by encrypting unicast management frames and providing integrity checks for broadcast management frames. These include deauthentication, disassociation and robust management frames. It also provides Secure Association (SA) teardown mechanism to prevent spoofed association/authentication frames from disconnecting already connected clients. + Use active scan from schan to schan+nchan-1. -{IDF_TARGET_NAME} supports the following three modes of operation with respect to PMF. + Always keep in mind that if an AP with hidden SSID and station is set to a passive scan channel, the passive scan will not find it. In other words, if the application hopes to find the AP with hidden SSID in every channel, the policy of country info should be configured to WIFI_COUNTRY_POLICY_MANUAL. - - PMF not supported: In this mode, {IDF_TARGET_NAME} indicates to AP that it is not capable of supporting management protection during association. In effect, security in this mode will be equivalent to that in traditional mode. - - PMF capable, but not required: In this mode, {IDF_TARGET_NAME} indicates to AP that it is capable of supporting PMF. The management protection will be used if AP mandates PMF or is at least capable of supporting PMF. - - PMF capable and required: In this mode, {IDF_TARGET_NAME} will only connect to AP, if AP supports PMF. If not, {IDF_TARGET_NAME} will refuse to connect to the AP. + * - Station + - WIFI_COUNTRY_POLICY_MANUAL + - Always use the configured country info. For scan, scans channel “schan” to “schan+nchan-1” with active scan. + * - AP + - WIFI_COUNTRY_POLICY_AUTO + - Always use the configured country info. + * - AP + - WIFI_COUNTRY_POLICY_MANUAL + - Always use the configured country info. + * - Station/AP-coexistence + - WIFI_COUNTRY_POLICY_AUTO + - If the station doesn’t connects to any external AP, the AP use the configured country info. If the station connects to an external AP, the AP has the same country info as the station. -:cpp:func:`esp_wifi_set_config` can be used to configure PMF mode by setting appropriate flags in `pmf_cfg` parameter. Currently, PMF is supported only in Station mode. + Same as station mode with policy WIFI_COUNTRY_POLICY_AUTO. +Home Channel +************************* -WPA3-Personal -+++++++++++++++++++++++++++++++++ +In AP mode, the home channel is defined as the AP channel. In Station mode, home channel is defined as the channel of AP which the station is connected to. In Station/AP-coexistence mode, the home channel of AP and station must be the same, if they are different, the station's home channel is always in priority. Take the following as an example: the AP is on channel 6, and the station connects to an AP whose channel is 9. Since the station's home channel has higher priority, the AP needs to switch its channel from 6 to make sure that it has the same home channel as the station. While switching channel, the {IDF_TARGET_NAME} in SoftAP mode will notify the connected stations about the channel migration using a Channel Switch Announcement (CSA). Station that supports channel switching will transit without disconnecting and reconnecting to the SoftAP. -Wi-Fi Protected Access-3 (WPA3) is a set of enhancements to Wi-Fi access security intended to replace the current WPA2 standard. In order to provide more robust authentication, WPA3 uses Simultaneous Authentication of Equals (SAE), which is password-authenticated key agreement method based on Diffie-Hellman key exchange. Unlike WPA2, the technology is resistant to offline-dictionary attack, where the attacker attempts to determine shared password based on captured 4-way handshake without any further network interaction. WPA3 also provides forward secrecy, which means the captured data cannot be decrypted even if password is compromised after data transmission. Please refer to `Security `_ section of Wi-Fi Alliance's official website for further details. -In order to enable WPA3-Personal, "Enable WPA3-Personal" should be selected in menuconfig. If enabled, {IDF_TARGET_NAME} uses SAE for authentication if supported by the AP. Since PMF is a mandatory requirement for WPA3, PMF capability should be at least set to "PMF capable, but not required" for {IDF_TARGET_NAME} to use WPA3 mode. Application developers need not worry about the underlying security mode as highest available is chosen from security standpoint. Note that Wi-Fi stack size requirement will increase approximately by 3k when WPA3 is used. Currently, WPA3 is supported only in Station mode. +Wi-Fi Vendor IE Configuration ++++++++++++++++++++++++++++++++++++ +By default, all Wi-Fi management frames are processed by the Wi-Fi driver, and the application does not need to care about them. Some applications, however, may have to handle the beacon, probe request, probe response and other management frames. For example, if you insert some vendor-specific IE into the management frames, it is only the management frames which contain this vendor-specific IE that will be processed. In {IDF_TARGET_NAME}, :cpp:func:`esp_wifi_set_vendor_ie()` and :cpp:func:`esp_wifi_set_vendor_ie_cb()` are responsible for this kind of tasks. + + +Wi-Fi Easy Connect™ (DPP) +-------------------------- + +Wi-Fi Easy Connect\ :sup:`TM` (or Device Provisioning Protocol) is a secure and standardized provisioning protocol for configuration of Wi-Fi Devices. More information can be found on the API reference page :doc:`esp_dpp <../api-reference/network/esp_dpp>`. WPA2-Enterprise +++++++++++++++++++++++++++++++++ WPA2-Enterprise is the secure authentication mechanism for enterprise wireless networks. It uses RADIUS server for authentication of network users before connecting to the Access Point. The authentication process is based on 802.1X policy and comes with different Extended Authentication Protocol (EAP) methods like TLS, TTLS, PEAP etc. RADIUS server authenticates the users based on their credentials (username and password), digital certificates or both. When {IDF_TARGET_NAME} in Station mode tries to connect to an AP in enterprise mode, it sends authentication request to AP which is sent to RADIUS server by AP for authenticating the Station. Based on different EAP methods, the parameters can be set in configuration which can be opened using ``idf.py menuconfig``. WPA2_Enterprise is supported by {IDF_TARGET_NAME} only in Station mode. - For establishing a secure connection, AP and Station negotiate and agree on the best possible cipher suite to be used. {IDF_TARGET_NAME} supports 802.1X/EAP (WPA) method of AKM and Advanced encryption standard with Counter Mode Cipher Block Chaining Message Authentication protocol (AES-CCM) cipher suite. It also supports the cipher suites supported by mbedtls if `USE_MBEDTLS_CRYPTO` flag is set. - {IDF_TARGET_NAME} currently supports the following EAP methods: - EAP-TLS: This is certificate based method and only requires SSID and EAP-IDF. - PEAP: This is Protected EAP method. Username and Password are mandatory. @@ -1455,10 +1303,28 @@ For establishing a secure connection, AP and Station negotiate and agree on the - PAP: Password Authentication Protocol. - CHAP: Challenge Handshake Authentication Protocol. - MSCHAP and MSCHAP-V2. - + - EAP-FAST: This is a Protected Access Credentials (PAC) based authentication method which also uses identity and password. Currently, USE_MBEDTLS_CRYPTO flag should be disabled to use this feature. Detailed information on creating certificates and how to run wpa2_enterprise example on {IDF_TARGET_NAME} can be found in :example:`wifi/wpa2_enterprise`. +Wireless Network Management +---------------------------- + +Wireless Network Management allows client devices to exchange information about the network topology, including information related to RF environment. This makes each client network-aware, facilitating overall improvement in the performace of the wireless network. It is part of 802.11v specification. It also enables client to support Network assisted Roaming. + +Network assisted Roaming: Enables WLAN to send messages to associated clients, resulting clients to associate with APs with better link metrics. This is useful for both load balancing and in directing poorly connected clients. + +Current implementation of 802.11v includes support for BSS transition management frames. + +Radio Resource Measurement +--------------------------- + +Radio Resource Measurement (802.11k) is intended to improve the way traffic is distributed within a network. In a wireless LAN, each device normally connects to the access point (AP) that provides the strongest signal. Depending on the number and geographic locations of the subscribers, this arrangement can sometimes lead to excessive demand on one AP and underutilization of others, resulting in degradation of overall network performance. In a network conforming to 802.11k, if the AP having the strongest signal is loaded to its full capacity, a wireless device can be moved to one of the underutilized APs. Even though the signal may be weaker, the overall throughput is greater because more efficient use is made of the network resources. + +Current implementation of 802.11k includes support for beacon measurement report, link measurement report and neighbor request. + +Refer IDF example :idf_file:`examples/wifi/roaming/README.md` to set up and use these APIs. Example code only demonstrates how these APIs can be used, the application should define its own algorithm and cases as required. + .. only:: esp32s2 or esp32c3 Wi-Fi Location @@ -1470,13 +1336,16 @@ Detailed information on creating certificates and how to run wpa2_enterprise exa +++++++++++++++++++++++++++++ FTM is used to measure Wi-Fi Round Trip Time (Wi-Fi RTT) which is the time a Wi-Fi signal takes to travel from a device to another device and back again. Using Wi-Fi RTT the distance between the devices can be calculated with a simple formula of `RTT * c / 2`, where c is the speed of light. + FTM uses timestamps given by Wi-Fi interface hardware at the time of arrival or departure of frames exchanged between a pair of devices. One entity called FTM Initiator (mostly a Station device) discovers the FTM Responder (can be a Station or an Access Point) and negotiates to start an FTM procedure. The procedure uses multiple Action frames sent in bursts and its ACK's to gather the timestamps data. FTM Initiator gathers the data in the end to calculate an average Round-Trip-Time. + {IDF_TARGET_NAME} supports FTM in below configuration: - {IDF_TARGET_NAME} as FTM Initiator in Station mode. - {IDF_TARGET_NAME} as FTM Responder in SoftAP mode. Distance measurement using RTT is not accurate, factors such as RF interference, multi-path travel, antenna orientation and lack of calibration increase these inaccuracies. For better results it is suggested to perform FTM between two {IDF_TARGET_NAME} devices as Station and SoftAP. + Refer to IDF example :idf_file:`examples/wifi/ftm/README.md` for steps on how to setup and perform FTM. {IDF_TARGET_NAME} Wi-Fi Power-saving Mode @@ -1511,64 +1380,133 @@ The table below shows the best throughput results we got in Espressif's lab and .. only:: esp32 - +----------------------+-----------------+-----------------+---------------+--------------+ - | Type/Throughput | Air In Lab | Shield-box | Test Tool | IDF Version | - | | | | | (commit ID) | - +======================+=================+=================+===============+==============+ - | Raw 802.11 Packet RX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | Raw 802.11 Packet TX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP RX | 30 MBit/s | 85 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP TX | 30 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP RX | 20 MBit/s | 65 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP TX | 20 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + + * - Type/Throughput + - Air In Lab + - Shield-box + - Test Tool + - IDF Version (commit ID) + * - Raw 802.11 Packet RX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - Raw 802.11 Packet TX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - UDP RX + - 30 MBit/s + - 85 MBit/s + - iperf example + - 15575346 + * - UDP TX + - 30 MBit/s + - 75 MBit/s + - iperf example + - 15575346 + * - TCP RX + - 20 MBit/s + - 65 MBit/s + - iperf example + - 15575346 + * - TCP TX + - 20 MBit/s + - 75 MBit/s + - iperf example + - 15575346 When the throughput is tested by iperf example, the sdkconfig is :idf_file:`examples/wifi/iperf/sdkconfig.defaults.esp32`. .. only:: esp32s2 - +----------------------+-----------------+-----------------+---------------+--------------+ - | Type/Throughput | Air In Lab | Shield-box | Test Tool | IDF Version | - | | | | | (commit ID) | - +======================+=================+=================+===============+==============+ - | Raw 802.11 Packet RX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | Raw 802.11 Packet TX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP RX | 30 MBit/s | 70 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP TX | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP RX | 20 MBit/s | 32 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP TX | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + + * - Type/Throughput + - Air In Lab + - Shield-box + - Test Tool + - IDF Version (commit ID) + * - Raw 802.11 Packet RX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - Raw 802.11 Packet TX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - UDP RX + - 30 MBit/s + - 70 MBit/s + - iperf example + - 15575346 + * - UDP TX + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - TCP RX + - 20 MBit/s + - 32 MBit/s + - iperf example + - 15575346 + * - TCP TX + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 When the throughput is tested by iperf example, the sdkconfig is :idf_file:`examples/wifi/iperf/sdkconfig.defaults.esp32s2`. .. only:: esp32c3 - +----------------------+-----------------+-----------------+---------------+--------------+ - | Type/Throughput | Air In Lab | Shield-box | Test Tool | IDF Version | - | | | | | (commit ID) | - +======================+=================+=================+===============+==============+ - | Raw 802.11 Packet RX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | Raw 802.11 Packet TX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP RX | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP TX | 30 MBit/s | 40 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP RX | 20 MBit/s | 35 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP TX | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 40 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 35 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 When the throughput is tested by iperf example, the sdkconfig is :idf_file:`examples/wifi/iperf/sdkconfig.defaults.esp32c3`. @@ -1600,88 +1538,41 @@ Side-Effects to Avoid in Different Scenarios Theoretically, if we do not consider the side-effects the API imposes on the Wi-Fi driver or other stations/APs, we can send a raw 802.11 packet over the air, with any destination MAC, any source MAC, any BSSID, or any other type of packet. However,robust/useful applications should avoid such side-effects. The table below provides some tips/recommendations on how to avoid the side-effects of :cpp:func:`esp_wifi_80211_tx` in different scenarios. -+-----------------------------+---------------------------------------------------+ -| Scenario | Description | -+=============================+===================================================+ -| No WiFi connection | In this scenario, no Wi-Fi connection is set up, | -| | so there are no side-effects on the Wi-Fi driver. | -| | If en_sys_seq==true, the Wi-Fi driver is | -| | responsible for the sequence control. If | -| | en_sys_seq==false, the application needs to ensure| -| | that the buffer has the correct sequence. | -| | | -| | Theoretically, the MAC address can be any address.| -| | However, this may impact other stations/APs | -| | with the same MAC/BSSID. | -| | | -| | Side-effect example#1 | -| | The application calls esp_wifi_80211_tx to send | -| | a beacon with BSSID == mac_x in AP mode, but | -| | the mac_x is not the MAC of the AP interface. | -| | Moreover, there is another AP, say | -| | "other-AP", whose bssid is mac_x. If this | -| | happens, an "unexpected behavior" may occur, | -| | because the stations which connect to the | -| | "other-AP" cannot figure out whether the beacon is| -| | from the "other-AP" or the esp_wifi_80211_tx. | -| | | -| | To avoid the above-mentioned side-effects, we | -| | recommend that: | -| | | -| | - If esp_wifi_80211_tx is called in Station mode,| -| | the first MAC should be a multicast MAC or the | -| | exact target-device's MAC, while the second MAC| -| | should be that of the station interface. | -| | - If esp_wifi_80211_tx is called in AP mode, | -| | the first MAC should be a multicast MAC or the | -| | exact target-device's MAC, while the second MAC| -| | should be that of the AP interface. | -| | | -| | The recommendations above are only for avoiding | -| | side-effects and can be ignored when there are | -| | good reasons for doing this. | -+-----------------------------+---------------------------------------------------+ -| Have WiFi connection | When the Wi-Fi connection is already set up, and | -| | the sequence is controlled by the application, the| -| | latter may impact the sequence control of the | -| | Wi-Fi connection, as a whole. So, the | -| | en_sys_seq need to be true, otherwise | -| | ESP_ERR_WIFI_ARG is returned. | -| | | -| | The MAC-address recommendations in the | -| | "No WiFi connection" scenario also apply to this | -| | scenario. | -| | | -| | If the WiFi mode is station mode and the MAC | -| | address1 is the MAC of AP to which the station is | -| | connected, the MAC address2 is the MAC of station | -| | interface, we say the packets is from the station | -| | to AP. On the other hand, if the WiFi mode is | -| | AP mode and the MAC address1 is the MAC of | -| | the station who connects to this AP, the MAC | -| | address2 is the MAC of AP interface, we say | -| | the packet is from the AP to station. | -| | To avoid conflicting with WiFi connections, the | -| | following checks are applied: | -| | | -| | - If the packet type is data and is from the | -| | station to AP, the ToDS bit in IEEE 80211 | -| | frame control should be 1, the FromDS bit | -| | should be 0, otherwise the packet will be | -| | discarded by WiFi driver. | -| | - If the packet type is data and is from the | -| | AP to station, the ToDS bit in IEEE 80211 | -| | frame control should be 0, the FromDS bit | -| | should be 1, otherwise the packet will be | -| | discarded by WiFi driver. | -| | - If the packet is from station to AP or | -| | from AP to station, the Power Management, | -| | More Data, Re-Transmission bits should be 0, | -| | otherwise the packet will be discarded by WiFi | -| | driver. | -| | | -| | ESP_ERR_WIFI_ARG is returned if any check fails. | -+-----------------------------+---------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 10 50 + + * - Scenario + - Description + * - No Wi-Fi connection + - In this scenario, no Wi-Fi connection is set up, so there are no side-effects on the Wi-Fi driver. If en_sys_seq==true, the Wi-Fi driver is responsible for the sequence control. If en_sys_seq==false, the application needs to ensure that the buffer has the correct sequence. + + Theoretically, the MAC address can be any address. However, this may impact other stations/APs with the same MAC/BSSID. + + Side-effect example#1 The application calls esp_wifi_80211_tx to send a beacon with BSSID == mac_x in AP mode, but the mac_x is not the MAC of the AP interface. Moreover, there is another AP, say “other-AP”, whose bssid is mac_x. If this happens, an “unexpected behavior” may occur, because the stations which connect to the “other-AP” cannot figure out whether the beacon is from the “other-AP” or the esp_wifi_80211_tx. + + To avoid the above-mentioned side-effects, we recommend that: + + - If esp_wifi_80211_tx is called in station mode, the first MAC should be a multicast MAC or the exact target-device’s MAC, while the second MAC should be that of the station interface. + + - If esp_wifi_80211_tx is called in AP mode, the first MAC should be a multicast MAC or the exact target-device’s MAC, while the second MAC should be that of the AP interface. + + The recommendations above are only for avoiding side-effects and can be ignored when there are good reasons for doing this. + + * - Have Wi-Fi connection + - When the Wi-Fi connection is already set up, and the sequence is controlled by the application, the latter may impact the sequence control of the Wi-Fi connection, as a whole. So, the en_sys_seq need to be true, otherwise ESP_ERR_WIFI_ARG is returned. + + The MAC-address recommendations in the “No Wi-Fi connection” scenario also apply to this scenario. + + If the Wi-Fi mode is station mode and the MAC address1 is the MAC of AP to which the station is connected, the MAC address2 is the MAC of station interface, we say the packets is from the station to AP. On the other hand, if the Wi-Fi mode is AP mode and the MAC address1 is the MAC of the station who connects to this AP, the MAC address2 is the MAC of AP interface, we say the packet is from the AP to station. To avoid conflicting with Wi-Fi connections, the following checks are applied: + + - If the packet type is data and is from the station to AP, the ToDS bit in IEEE 80211 frame control should be 1, the FromDS bit should be 0, otherwise the packet will be discarded by Wi-Fi driver. + + - If the packet type is data and is from the AP to station, the ToDS bit in IEEE 80211 frame control should be 0, the FromDS bit should be 1, otherwise the packet will be discarded by Wi-Fi driver. + + - If the packet is from station to AP or from AP to station, the Power Management, More Data, Re-Transmission bits should be 0, otherwise the packet will be discarded by Wi-Fi driver. + + ESP_ERR_WIFI_ARG is returned if any check fails. Wi-Fi Sniffer Mode --------------------------- @@ -2015,115 +1906,304 @@ The parameters not mentioned in the following table should be set to the default .. only:: esp32 - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | Rank | Iperf | TX prior | High-performance | RX prior | Default | Memory saving | Minimum | - +============================+=======+==========+==================+==========+=========+===============+=========+ - | Available memory(KB) | 37.1 | 113.8 | 123.3 | 145.5 | 144.5 | 170.2 | 185.2 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 6 | 6 | 6 | 6 | 6 | 4 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 64 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 32 | 8 | 12 | 12 | 10 | 6 | Disable | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 65 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 65 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 15 | 15 | 15 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 13 | 13 | 13 | 13 | 13 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 74.6 | 50.8 | 46.5 | 39.9 | 44.2 | 33.8 | 25.6 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 63.6 | 35.5 | 42.3 | 48.5 | 40.5 | 30.1 | 27.8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 76.2 | 75.1 | 74.1 | 72.4 | 69.6 | 64.1 | 36.5 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 83.1 | 66.3 | 75.1 | 75.6 | 73.1 | 65.3 | 54.7 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 5 5 10 5 5 10 5 + + * - Rank + - Iperf + - TX prior + - High-performance + - RX prior + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 37.1 + - 113.8 + - 123.3 + - 145.5 + - 144.5 + - 170.2 + - 185.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 6 + - 6 + - 6 + - 6 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 64 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - WIFI_RX_BA_WIN + - 32 + - 8 + - 12 + - 12 + - 10 + - 6 + - Disable + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - TCP_WND_DEFAULT (KB) + - 65 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + * - TCP TX throughput (Mbit/s) + - 74.6 + - 50.8 + - 46.5 + - 39.9 + - 44.2 + - 33.8 + - 25.6 + * - TCP RX throughput (Mbit/s) + - 63.6 + - 35.5 + - 42.3 + - 48.5 + - 40.5 + - 30.1 + - 27.8 + * - UDP TX throughput (Mbit/s) + - 76.2 + - 75.1 + - 74.1 + - 72.4 + - 69.6 + - 64.1 + - 36.5 + * - UDP RX throughput (Mbit/s) + - 83.1 + - 66.3 + - 75.1 + - 75.6 + - 73.1 + - 65.3 + - 54.7 + .. only:: esp32s2 - +----------------------------+-------+------------------+---------+---------------+---------+ - | Rank | Iperf | High-performance | Default | Memory saving | Minimum | - +============================+=======+==================+=========+===============+=========+ - | Available memory (KB) | 4.1 | 24.2 | 78.4 | 86.5 | 116.4 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 |6 | 6 | 4 | 3 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 12 | 9 | 6 | 4 | 3 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT (KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 0 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 0 | 0 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | 0 | 0 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 16 | 8 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 37.6 | 33.1 | 22.5 | 12.2 | 5.5 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 31.5 | 28.1 | 20.1 | 13.1 | 7.2 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 58.1 | 57.3 | 28.1 | 22.6 | 8.7 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 78.1 | 66.7 | 65.3 | 53.8 | 28.5 | - +----------------------------+-------+------------------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 10 10 + + * - Rank + - Iperf + - High-performance + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 4.1 + - 24.2 + - 78.4 + - 86.5 + - 116.4 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 6 + - 6 + - 4 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_RX_BA_WIN + - 12 + - 9 + - 6 + - 4 + - 3 + * - TCP_SND_BUF_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - TCP_WND_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + - 16 + * - TCP TX throughput (Mbit/s) + - 37.6 + - 33.1 + - 22.5 + - 12.2 + - 5.5 + * - TCP RX throughput (Mbit/s) + - 31.5 + - 28.1 + - 20.1 + - 13.1 + - 7.2 + * - UDP TX throughput (Mbit/s) + - 58.1 + - 57.3 + - 28.1 + - 22.6 + - 8.7 + * - UDP RX throughput (Mbit/s) + - 78.1 + - 66.7 + - 65.3 + - 53.8 + - 28.5 .. only:: esp32c3 - +----------------------------+-------+---------+---------+ - | Rank | Iperf | Default | Minimum | - +============================+=======+=========+=========+ - | Available memory(KB) | 59 | 160 | 180 | - +----------------------------+-------+---------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 20 | 8 | 3 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_RX_BA_WIN | 32 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_WND_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_IRAM_OPT | - | - | - | - +----------------------------+-------+---------+---------+ - | WIFI_RX_IRAM_OPT | - | - | - | - +----------------------------+-------+---------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | - +----------------------------+-------+---------+---------+ - | TCP TX throughput (Mbit/s) | 38.1 | 27.2 | 20.4 | - +----------------------------+-------+---------+---------+ - | TCP RX throughput (Mbit/s) | 35.3 | 24.2 | 17.4 | - +----------------------------+-------+---------+---------+ - | UDP TX throughput (Mbit/s) | 40.6 | 38.9 | 34.1 | - +----------------------------+-------+---------+---------+ - | UDP RX throughput (Mbit/s) | 52.4 | 44.5 | 44.2 | - +----------------------------+-------+---------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 + + * - Rank + - Iperf + - Default + - Minimum + * - Available memory (KB) + - 59 + - 160 + - 180 + * - WIFI_STATIC_RX_BUFFER_NUM + - 20 + - 8 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_RX_BA_WIN + - 32 + - 16 + - 6 + * - TCP_SND_BUF_DEFAULT (KB) + - 40 + - 16 + - 6 + * - TCP_WND_DEFAULT (KB) + - 40 + - 16 + - 6 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + * - TCP TX throughput (Mbit/s) + - 38.1 + - 27.2 + - 20.4 + * - TCP RX throughput (Mbit/s) + - 35.3 + - 24.2 + - 17.4 + * - UDP TX throughput (Mbit/s) + - 40.6 + - 38.9 + - 34.1 + * - UDP RX throughput (Mbit/s) + - 52.4 + - 44.5 + - 44.2 .. only:: esp32 or esp32s2 .. note:: - The result is tested with a single stream in a shielded box using an ASUS RT-N66U router. - {IDF_TARGET_NAME}'s CPU is dual core with 240 MHz, {IDF_TARGET_NAME}'s flash is in QIO mode with 80 MHz. + The result is tested with a single stream in a shielded box using an ASUS RT-N66U router. {IDF_TARGET_NAME}'s CPU is dual core with 240 MHz, {IDF_TARGET_NAME}'s flash is in QIO mode with 80 MHz. .. only:: esp32 @@ -2186,79 +2266,187 @@ The parameters not mentioned in the following table should be set to the default .. only:: esp32 - +----------------------------+-------+---------+---------------+---------+ - | Rank | Iperf | Default | Memory saving | Minimum | - +============================+=======+=========+===============+=========+ - | Available memory(KB) | 113.8 | 152.4 | 181.2 | 202.6 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 128 | 128 | 128 | 128 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 16 | 16 | 8 | Disable | - +----------------------------+-------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 37.5 | 31.7 | 21.7 | 14.6 | - +----------------------------+-------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 31.5 | 29.8 | 26.5 | 21.1 | - +----------------------------+-------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 69.1 | 31.5 | 27.1 | 24.1 | - +----------------------------+-------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 40.1 | 38.5 | 37.5 | 36.9 | - +----------------------------+-------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 15 10 10 15 10 + + * - Rank + - Iperf + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 113.8 + - 152.4 + - 181.2 + - 202.6 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 128 + - 128 + - 128 + - 128 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_RX_BA_WIN + - 16 + - 16 + - 8 + - Disable + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - TCP_WND_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - TCP TX throughput (Mbit/s) + - 37.5 + - 31.7 + - 21.7 + - 14.6 + * - TCP RX throughput (Mbit/s) + - 31.5 + - 29.8 + - 26.5 + - 21.1 + * - UDP TX throughput (Mbit/s) + - 69.1 + - 31.5 + - 27.1 + - 24.1 + * - UDP RX throughput (Mbit/s) + - 40.1 + - 38.5 + - 37.5 + - 36.9 .. only:: esp32s2 - +----------------------------+-------+---------+---------------+---------+ - | Rank | Iperf | Default | Memory saving | Minimum | - +============================+=======+=========+===============+=========+ - | Available memory(KB) | 70.6 | 96.4 | 118.8 | 148.2 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 | 8 | 6 | 4 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 64 | 64 | 64 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 6 | 4 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 16 | 6 | 6 | Disable | - +----------------------------+-------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 8 | - +----------------------------+-------+---------+---------------+---------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | - +----------------------------+-------+---------+---------------+---------+ - | DATA_CACHE | 8 | 8 | 8 | 8 | - +----------------------------+-------+---------+---------------+---------+ - | DATA_CACHE_LINE | 32 | 32 | 32 | 32 | - +----------------------------+-------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 40.1 | 29.2 | 20.1 | 8.9 | - +----------------------------+-------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 21.9 | 16.8 | 14.8 | 9.6 | - +----------------------------+-------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 50.1 | 25.7 | 22.4 | 10.2 | - +----------------------------+-------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 45.3 | 43.1 | 28.5 | 15.1 | - +----------------------------+-------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 15 + + * - Rank + - Iperf + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 70.6 + - 96.4 + - 118.8 + - 148.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 8 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 64 + - 64 + - 64 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 6 + - 4 + * - WIFI_RX_BA_WIN + - 16 + - 6 + - 6 + - Disable + * - TCP_SND_BUF_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - TCP_WND_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + * - DATA_CACHE + - 8 + - 8 + - 8 + - 8 + * - DATA_CACHE_LINE + - 32 + - 32 + - 32 + - 32 + * - TCP TX throughput (Mbit/s) + - 40.1 + - 29.2 + - 20.1 + - 8.9 + * - TCP RX throughput (Mbit/s) + - 21.9 + - 16.8 + - 14.8 + - 9.6 + * - UDP TX throughput (Mbit/s) + - 50.1 + - 25.7 + - 22.4 + - 10.2 + * - UDP RX throughput (Mbit/s) + - 45.3 + - 43.1 + - 28.5 + - 15.1 .. note:: Reaching peak performance may cause task watchdog. It is a normal phenomenon considering the CPU may have no time for lower priority tasks. @@ -2347,80 +2535,58 @@ Description: The diagram shows the configuration of the Wi-Fi internal buffer. -+------------------+------------+------------+--------------+---------------------------------------+ -| Buffer Type | Alloc Type | Default | Configurable | Description | -+==================+============+============+==============+=======================================+ -| Static RX Buffer | Static | 10 * | Yes | This is a kind of DMA memory. It is | -| (Hardware RX | | 1600 Bytes | | initialized in | -| Buffer) | | | | :cpp:func:`esp_wifi_init()` and freed | -| | | | | in :cpp:func:`esp_wifi_deinit()`. The | -| | | | | 'Static Rx Buffer' forms the hardware | -| | | | | receiving list. Upon receiving a frame| -| | | | | over the air, hardware writes the | -| | | | | frame into the buffer and raises an | -| | | | | interrupt to the CPU. Then, the Wi-Fi | -| | | | | driver reads the content from the | -| | | | | buffer and returns the buffer back to | -| | | | | the list. | -| | | | | | -| | | | | If the application want to reduce the | -| | | | | the memory statically allocated by | -| | | | | Wi-Fi, they can reduce this value from| -| | | | | 10 to 6 to save 6400 Bytes memory. | -| | | | | It's not recommended to reduce the | -| | | | | configuration to a value less than 6 | -| | | | | unless the AMPDU feature is disabled. | -| | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ -| Dynamic RX Buffer| Dynamic | 32 | Yes | The buffer length is variable and it | -| | | | | depends on the received frames' | -| | | | | length. When the Wi-Fi driver receives| -| | | | | a frame from the 'Hardware Rx Buffer',| -| | | | | the 'Dynamic Rx Buffer' needs to be | -| | | | | allocated from the heap. The number of| -| | | | | the Dynamic Rx Buffer, configured in | -| | | | | the menuconfig, is used to limit the | -| | | | | total un-freed Dynamic Rx Buffer | -| | | | | number. | -+------------------+------------+------------+--------------+---------------------------------------+ -| Dynamic TX Buffer| Dynamic | 32 | Yes | This is a kind of DMA memory. It is | -| | | | | allocated to the heap. When the upper-| -| | | | | layer (LwIP) sends packets to the | -| | | | | Wi-Fi driver, it firstly allocates a | -| | | | | 'Dynamic TX Buffer' and makes a copy | -| | | | | of the upper-layer buffer. | -| | | | | | -| | | | | The Dynamic and Static TX Buffers are | -| | | | | mutually exclusive. | -+------------------+------------+------------+--------------+---------------------------------------+ -| Static TX Buffer | Static | 16 * | Yes | This is a kind of DMA memory. It is | -| | | 1600Bytes | | initialized in | -| | | | | :cpp:func:`esp_wifi_init()` and freed | -| | | | | in :cpp:func:`esp_wifi_deinit()`. When| -| | | | | the upper-layer (LwIP) sends packets | -| | | | | to the Wi-Fi driver, it firstly | -| | | | | allocates a 'Static TX Buffer' and | -| | | | | makes a copy of the upper-layer | -| | | | | buffer. | -| | | | | | -| | | | | The Dynamic and Static TX Buffer are | -| | | | | mutually exclusive. | -| | | | | | -| | | | | Since the TX buffer must be DMA | -| | | | | buffer, so when PSRAM is enabled, the | -| | | | | TX buffer must be static. | -+------------------+------------+------------+--------------+---------------------------------------+ -| Management Short | Dynamic | 8 | NO | Wi-Fi driver's internal buffer. | -| Buffer | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ -| Management Long | Dynamic | 32 | NO | Wi-Fi driver's internal buffer. | -| Buffer | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ -| Management Long | Dynamic | 32 | NO | Wi-Fi driver's internal buffer. | -| Long Buffer | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ - - +.. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + + * - Buffer Type + - Alloc Type + - Default + - Configurable + - Description + * - Static RX Buffer (Hardware RX Buffer) + - Static + - 10 * 1600 Bytes + - Yes + - This is a kind of DMA memory. It is initialized in :cpp:func:`esp_wifi_init()` and freed in :cpp:func:`esp_wifi_deinit()`. The ‘Static Rx Buffer’ forms the hardware receiving list. Upon receiving a frame over the air, hardware writes the frame into the buffer and raises an interrupt to the CPU. Then, the Wi-Fi driver reads the content from the buffer and returns the buffer back to the list. + + If the application want to reduce the the memory statically allocated by Wi-Fi, they can reduce this value from 10 to 6 to save 6400 Bytes memory. It’s not recommended to reduce the configuration to a value less than 6 unless the AMPDU feature is disabled. + * - Dynamic RX Buffer + - Dynamic + - 32 + - Yes + - The buffer length is variable and it depends on the received frames’ length. When the Wi-Fi driver receives a frame from the ‘Hardware Rx Buffer’, the ‘Dynamic Rx Buffer’ needs to be allocated from the heap. The number of the Dynamic Rx Buffer, configured in the menuconfig, is used to limit the total un-freed Dynamic Rx Buffer number. + * - Dynamic TX Buffer + - Dynamic + - 32 + - Yes + - This is a kind of DMA memory. It is allocated to the heap. When the upper- layer (LwIP) sends packets to the Wi-Fi driver, it firstly allocates a ‘Dynamic TX Buffer’ and makes a copy of the upper-layer buffer. + + The Dynamic and Static TX Buffers are mutually exclusive. + * - Static TX Buffer + - Static + - 16 * 1600Bytes + - Yes + - This is a kind of DMA memory. It is initialized in :cpp:func:`esp_wifi_init()` and freed in :cpp:func:`esp_wifi_deinit()`. When the upper-layer (LwIP) sends packets to the Wi-Fi driver, it firstly allocates a ‘Static TX Buffer’ and makes a copy of the upper-layer buffer. + + The Dynamic and Static TX Buffer are mutually exclusive. + + Since the TX buffer must be DMA buffer, so when PSRAM is enabled, the TX buffer must be static. + * - Management Short Buffer + - Dynamic + - 8 + - NO + - Wi-Fi driver’s internal buffer. + * - Management Long Buffer + - Dynamic + - 32 + - NO + - Wi-Fi driver’s internal buffer. + * - Management Long Long Buffer + - Dynamic + - 32 + - NO + - Wi-Fi driver’s internal buffer. Wi-Fi NVS Flash +++++++++++++++++++++ @@ -2441,4 +2607,4 @@ Please refer to a separate document with :doc:`wireshark-user-guide`. .. toctree:: :hidden: - wireshark-user-guide + wireshark-user-guide \ No newline at end of file diff --git a/docs/en/api-reference/bluetooth/controller_vhci.rst b/docs/en/api-reference/bluetooth/controller_vhci.rst index 22fb3f7903a1..6fc65df49777 100644 --- a/docs/en/api-reference/bluetooth/controller_vhci.rst +++ b/docs/en/api-reference/bluetooth/controller_vhci.rst @@ -1,13 +1,6 @@ Controller && VHCI ================== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - Application Example ------------------- diff --git a/docs/en/api-reference/bluetooth/esp_a2dp.rst b/docs/en/api-reference/bluetooth/esp_a2dp.rst index 8dea862fc179..e3b5c511666e 100644 --- a/docs/en/api-reference/bluetooth/esp_a2dp.rst +++ b/docs/en/api-reference/bluetooth/esp_a2dp.rst @@ -1,13 +1,6 @@ Bluetooth A2DP API ================== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - Application Example ------------------- diff --git a/docs/en/api-reference/bluetooth/esp_avrc.rst b/docs/en/api-reference/bluetooth/esp_avrc.rst index 1c15c7b69c8f..7b8fa6f6e92a 100644 --- a/docs/en/api-reference/bluetooth/esp_avrc.rst +++ b/docs/en/api-reference/bluetooth/esp_avrc.rst @@ -6,15 +6,6 @@ Overview Bluetooth AVRCP reference APIs. -`Instructions`_ - -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_bt_defs.rst b/docs/en/api-reference/bluetooth/esp_bt_defs.rst index 85e73d0688fb..58400242ce8a 100644 --- a/docs/en/api-reference/bluetooth/esp_bt_defs.rst +++ b/docs/en/api-reference/bluetooth/esp_bt_defs.rst @@ -1,19 +1,6 @@ BT GENERIC DEFINES ================== -Overview --------- - -`Instructions`_ - -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_bt_device.rst b/docs/en/api-reference/bluetooth/esp_bt_device.rst index b234cea14c30..d135e21340df 100644 --- a/docs/en/api-reference/bluetooth/esp_bt_device.rst +++ b/docs/en/api-reference/bluetooth/esp_bt_device.rst @@ -6,15 +6,6 @@ Overview Bluetooth device reference APIs. -`Instructions`_ - -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_bt_main.rst b/docs/en/api-reference/bluetooth/esp_bt_main.rst index 321f9331e2ec..2955ee57d083 100644 --- a/docs/en/api-reference/bluetooth/esp_bt_main.rst +++ b/docs/en/api-reference/bluetooth/esp_bt_main.rst @@ -1,19 +1,6 @@ BT MAIN API =========== -Overview --------- - -`Instructions`_ - -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_gap_ble.rst b/docs/en/api-reference/bluetooth/esp_gap_ble.rst index 8f95906853b6..8d539dfdccc4 100644 --- a/docs/en/api-reference/bluetooth/esp_gap_ble.rst +++ b/docs/en/api-reference/bluetooth/esp_gap_ble.rst @@ -1,13 +1,6 @@ GAP API ======= -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - Application Example ------------------- @@ -18,7 +11,7 @@ Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which conta - :example:`bluetooth/bluedroid/ble/gatt_security_client` - :example_file:`GATT Security Client Example Walkthrough ` -* This is a SMP security server demo and its tutorial. This demo initiates its security parameters and acts as a GATT server, which can send a pair request to the peer device and then complete the encryption procedure. +* This is a SMP security server demo and its tutorial. This demo initiates its security parameters and acts as a GATT server, which can send a pair request to the peer device and then complete the encryption procedure. - :example:`bluetooth/bluedroid/ble/gatt_security_server` - :example_file:`GATT Security Server Example Walkthrough ` diff --git a/docs/en/api-reference/bluetooth/esp_gap_bt.rst b/docs/en/api-reference/bluetooth/esp_gap_bt.rst index 346f7ec90a16..1466f6b766a3 100644 --- a/docs/en/api-reference/bluetooth/esp_gap_bt.rst +++ b/docs/en/api-reference/bluetooth/esp_gap_bt.rst @@ -1,18 +1,6 @@ CLASSIC BLUETOOTH GAP API ========================= -Overview --------- - -`Instructions`_ - -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_gatt_defs.rst b/docs/en/api-reference/bluetooth/esp_gatt_defs.rst index 931802126fd1..8b6a31ba57ed 100644 --- a/docs/en/api-reference/bluetooth/esp_gatt_defs.rst +++ b/docs/en/api-reference/bluetooth/esp_gatt_defs.rst @@ -1,18 +1,6 @@ GATT DEFINES ============ -Overview --------- - -`Instructions`_ - -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_gattc.rst b/docs/en/api-reference/bluetooth/esp_gattc.rst index 708888d2b5d2..bb511d196f4a 100644 --- a/docs/en/api-reference/bluetooth/esp_gattc.rst +++ b/docs/en/api-reference/bluetooth/esp_gattc.rst @@ -1,24 +1,17 @@ GATT CLIENT API =============== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - Application Example ------------------- Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which contains the following demos and their tutorials: -* This is a GATT client demo and its tutorial. This demo can scan for devices, connect to the GATT server and discover its services. +* This is a GATT client demo and its tutorial. This demo can scan for devices, connect to the GATT server and discover its services. - :example:`bluetooth/bluedroid/ble/gatt_client` - :example_file:`GATT Client Example Walkthrough ` -* This is a multiple connection demo and its tutorial. This demo can connect to multiple GATT server devices and discover their services. +* This is a multiple connection demo and its tutorial. This demo can connect to multiple GATT server devices and discover their services. - :example:`bluetooth/bluedroid/ble/gattc_multi_connect` - :example_file:`GATT Client Multi-connection Example Walkthrough ` diff --git a/docs/en/api-reference/bluetooth/esp_gatts.rst b/docs/en/api-reference/bluetooth/esp_gatts.rst index 1b48fccc8955..eb58060cbf48 100644 --- a/docs/en/api-reference/bluetooth/esp_gatts.rst +++ b/docs/en/api-reference/bluetooth/esp_gatts.rst @@ -1,19 +1,12 @@ GATT SERVER API =============== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - Application Example ------------------- Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which contains the following demos and their tutorials: -* This is a GATT sever demo and its tutorial. This demo creates a GATT service with an attribute table, which releases the user from adding attributes one by one. This is the recommended method of adding attributes. +* This is a GATT sever demo and its tutorial. This demo creates a GATT service with an attribute table, which releases the user from adding attributes one by one. This is the recommended method of adding attributes. - :example:`bluetooth/bluedroid/ble/gatt_server_service_table` - :example_file:`GATT Server Service Table Example Walkthrough ` diff --git a/docs/en/api-reference/bluetooth/esp_hf_client.rst b/docs/en/api-reference/bluetooth/esp_hf_client.rst index b79eb743f770..2a3f6d57a9a5 100644 --- a/docs/en/api-reference/bluetooth/esp_hf_client.rst +++ b/docs/en/api-reference/bluetooth/esp_hf_client.rst @@ -1,13 +1,6 @@ HFP CLIENT API ============== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_hf_defs.rst b/docs/en/api-reference/bluetooth/esp_hf_defs.rst index 4633a81f67e5..09152f3df604 100644 --- a/docs/en/api-reference/bluetooth/esp_hf_defs.rst +++ b/docs/en/api-reference/bluetooth/esp_hf_defs.rst @@ -1,13 +1,6 @@ HFP DEFINES =========== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/en/api-reference/bluetooth/esp_spp.rst b/docs/en/api-reference/bluetooth/esp_spp.rst index ced53408990f..51ceadd50785 100644 --- a/docs/en/api-reference/bluetooth/esp_spp.rst +++ b/docs/en/api-reference/bluetooth/esp_spp.rst @@ -1,13 +1,6 @@ SPP API =============== -Overview --------- - -`Instructions`_ - -.. _Instructions: ../template.html - Application Example ------------------- diff --git a/docs/en/api-reference/network/esp_dpp.rst b/docs/en/api-reference/network/esp_dpp.rst new file mode 100644 index 000000000000..7e8ebeebb0ee --- /dev/null +++ b/docs/en/api-reference/network/esp_dpp.rst @@ -0,0 +1,26 @@ +Wi-Fi Easy Connect\ :sup:`TM` (DPP) +=================================== + +Wi-Fi Easy Connect\ :sup:`TM`, also known as Device Provisioning Protocol (DPP) or Easy Connect, is a provisioning protocol certified by Wi-Fi Alliance. It is a secure and standardized provisioning protocol for configuration of Wi-Fi Devices. With Easy Connect adding a new device to a network is as simple as scanning a QR Code. This reduces complexity and enhances user experience while onboarding devices without UI like Smart Home and IoT products. Unlike old protocols like WiFi Protected Setup (WPS), Wi-Fi Easy Connect incorporates strong encryption through public key cryptography to ensure networks remain secure as new devices are added. +Easy Connect brings many benefits in the User Experience: + + - Simple and intuitive to use; no lengthy instructions to follow for new device setup + - No need to remember and enter passwords into the device being provisioned + - Works with electronic or printed QR codes, or human-readable strings + - Supports both WPA2 and WPA3 networks + +Please refer to Wi-Fi Alliance's official page on `Easy Connect `_ for more information. + +{IDF_TARGET_NAME} supports Enrollee mode of Easy Connect with QR Code as the provisioning method. A display is required to display this QR Code. Users can scan this QR Code using their capable device and provision the {IDF_TARGET_NAME} to their Wi-Fi network. The provisioning device needs to be connected to the AP which need not support Wi-Fi Easy Connect™. +Easy Connect is still an evolving protocol. Of known platforms that support the QR Code method are some Android smartphones with Android 10 or higher. To use Easy Connect no additional App needs to be installed on the supported smartphone. + +Application Example +------------------- + +Example on how to provision {IDF_TARGET_NAME} using a supported smartphone: :example:`wifi/wifi_easy_connect/dpp-enrollee`. + + +API Reference +------------- + +.. include-build-file:: inc/esp_dpp.inc diff --git a/docs/en/api-reference/network/index.rst b/docs/en/api-reference/network/index.rst index 097b37ca8b44..ecd1cb697d77 100644 --- a/docs/en/api-reference/network/index.rst +++ b/docs/en/api-reference/network/index.rst @@ -13,6 +13,7 @@ Wi-Fi SmartConfig ESP-NOW ESP Mesh + EasyConnect Code examples for the Wi-Fi API are provided in the :example:`wifi` directory of ESP-IDF examples. diff --git a/docs/en/api-reference/peripherals/ledc.rst b/docs/en/api-reference/peripherals/ledc.rst index 441dc5ef421e..f85d4f1ccf41 100644 --- a/docs/en/api-reference/peripherals/ledc.rst +++ b/docs/en/api-reference/peripherals/ledc.rst @@ -6,6 +6,7 @@ LED Control Introduction ------------ + The LED control (LEDC) peripheral is primarily designed to control the intensity of LEDs, although it can also be used to generate PWM signals for other purposes. It has {IDF_TARGET_LEDC_CHAN_NUM} channels which can generate independent waveforms that can be used, for example, to drive RGB LED devices. diff --git a/docs/en/api-reference/protocols/esp_crt_bundle.rst b/docs/en/api-reference/protocols/esp_crt_bundle.rst index baf55b5d0502..8d03cd772acb 100644 --- a/docs/en/api-reference/protocols/esp_crt_bundle.rst +++ b/docs/en/api-reference/protocols/esp_crt_bundle.rst @@ -12,7 +12,7 @@ The bundle comes with the complete list of root certificates from Mozilla’s NS When generating the bundle you may choose between: - * The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Wed Jan 23 04:12:09 2019 GMT. + * The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Tue Apr 26 03:12:05 2022 GMT. * A pre-selected filter list of the name of the most commonly used root certificates, reducing the amount of certificates to around 35 while still having around 90 % coverage according to market share statistics. In addition it is possible to specify a path to a certificate file or a directory containing certificates which then will be added to the generated bundle. diff --git a/docs/en/api-reference/protocols/mqtt.rst b/docs/en/api-reference/protocols/mqtt.rst index 47021b608aaa..7d00a037670b 100644 --- a/docs/en/api-reference/protocols/mqtt.rst +++ b/docs/en/api-reference/protocols/mqtt.rst @@ -33,30 +33,30 @@ URI - Curently support ``mqtt``, ``mqtts``, ``ws``, ``wss`` schemes - MQTT over TCP samples: - - ``mqtt://mqtt.eclipse.org``: MQTT over TCP, default port 1883: - - ``mqtt://mqtt.eclipse.org:1884`` MQTT over TCP, port 1884: - - ``mqtt://username:password@mqtt.eclipse.org:1884`` MQTT over TCP, + - ``mqtt://mqtt.eclipseprojects.io``: MQTT over TCP, default port 1883: + - ``mqtt://mqtt.eclipseprojects.io:1884`` MQTT over TCP, port 1884: + - ``mqtt://username:password@mqtt.eclipseprojects.io:1884`` MQTT over TCP, port 1884, with username and password - MQTT over SSL samples: - - ``mqtts://mqtt.eclipse.org``: MQTT over SSL, port 8883 - - ``mqtts://mqtt.eclipse.org:8884``: MQTT over SSL, port 8884 + - ``mqtts://mqtt.eclipseprojects.io``: MQTT over SSL, port 8883 + - ``mqtts://mqtt.eclipseprojects.io:8884``: MQTT over SSL, port 8884 - MQTT over Websocket samples: - - ``ws://mqtt.eclipse.org:80/mqtt`` + - ``ws://mqtt.eclipseprojects.io:80/mqtt`` - MQTT over Websocket Secure samples: - - ``wss://mqtt.eclipse.org:443/mqtt`` + - ``wss://mqtt.eclipseprojects.io:443/mqtt`` - Minimal configurations: .. code:: c const esp_mqtt_client_config_t mqtt_cfg = { - .uri = "mqtt://mqtt.eclipse.org", + .uri = "mqtt://mqtt.eclipseprojects.io", // .user_context = (void *)your_context }; esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); @@ -69,15 +69,15 @@ URI SSL ^^^ -- Get certificate from server, example: ``mqtt.eclipse.org`` - ``openssl s_client -showcerts -connect mqtt.eclipse.org:8883 /dev/null|openssl x509 -outform PEM >mqtt_eclipse_org.pem`` +- Get certificate from server, example: ``mqtt.eclipseprojects.io`` + ``openssl s_client -showcerts -connect mqtt.eclipseprojects.io:8883 /dev/null|openssl x509 -outform PEM >mqtt_eclipse_org.pem`` - Check the sample application: ``examples/mqtt_ssl`` - Configuration: .. code:: c const esp_mqtt_client_config_t mqtt_cfg = { - .uri = "mqtts://mqtt.eclipse.org:8883", + .uri = "mqtts://mqtt.eclipseprojects.io:8883", .event_handle = mqtt_event_handler, .cert_pem = (const char *)mqtt_eclipse_org_pem_start, }; diff --git a/docs/en/api-reference/provisioning/index.rst b/docs/en/api-reference/provisioning/index.rst index 18150c2e6f8f..0443208486a1 100644 --- a/docs/en/api-reference/provisioning/index.rst +++ b/docs/en/api-reference/provisioning/index.rst @@ -18,3 +18,10 @@ Code examples for above API are provided in the :example:`provisioning` director SmartConfig <../network/esp_smartconfig> Code example for above API is provided in :example:`wifi/smart_config` + +.. toctree:: + :maxdepth: 1 + + EasyConnect <../network/esp_dpp> + +Code example for above API is provided in :example:`wifi/wifi_easy_connect/dpp-enrollee` diff --git a/docs/en/api-reference/storage/nvs_flash.rst b/docs/en/api-reference/storage/nvs_flash.rst index 31ae316d8a7f..244064bf0861 100644 --- a/docs/en/api-reference/storage/nvs_flash.rst +++ b/docs/en/api-reference/storage/nvs_flash.rst @@ -8,7 +8,6 @@ Introduction Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This section introduces some concepts used by NVS. - Underlying storage ^^^^^^^^^^^^^^^^^^ @@ -378,5 +377,3 @@ API Reference .. include-build-file:: inc/nvs_flash.inc .. include-build-file:: inc/nvs.inc - - diff --git a/docs/en/api-reference/storage/sdmmc.rst b/docs/en/api-reference/storage/sdmmc.rst index 67946eaba3af..71f5b42df474 100644 --- a/docs/en/api-reference/storage/sdmmc.rst +++ b/docs/en/api-reference/storage/sdmmc.rst @@ -74,13 +74,22 @@ An example which combines the SDMMC driver with the FATFS library is provided in For card configuration and data transfer, choose the pair of functions relevant to your case from the table below. - ========================================================================= ================================= ================================= - Action Read Function Write Function - ========================================================================= ================================= ================================= - Read and write a single byte using IO_RW_DIRECT (CMD52) :cpp:func:`sdmmc_io_read_byte` :cpp:func:`sdmmc_io_write_byte` - Read and write multiple bytes using IO_RW_EXTENDED (CMD53) in byte mode :cpp:func:`sdmmc_io_read_bytes` :cpp:func:`sdmmc_io_write_bytes` - Read and write blocks of data using IO_RW_EXTENDED (CMD53) in block mode :cpp:func:`sdmmc_io_read_blocks` :cpp:func:`sdmmc_io_write_blocks` - ========================================================================= ================================= ================================= + .. list-table:: + :widths: 55 25 20 + :header-rows: 1 + + * - Action + - Read Function + - Write Function + * - Read and write a single byte using IO_RW_DIRECT (CMD52) + - :cpp:func:`sdmmc_io_read_byte` + - :cpp:func:`sdmmc_io_write_byte` + * - Read and write multiple bytes using IO_RW_EXTENDED (CMD53) in byte modes + - :cpp:func:`sdmmc_io_read_bytes` + - :cpp:func:`sdmmc_io_write_bytes` + * - Read and write blocks of data using IO_RW_EXTENDED (CMD53) in block modes + - :cpp:func:`sdmmc_io_read_blocks` + - :cpp:func:`sdmmc_io_write_blocks` SDIO interrupts can be enabled by the application using the function :cpp:func:`sdmmc_io_enable_int`. When using SDIO in 1-line mode, the D1 line also needs to be connected to use SDIO interrupts. @@ -88,8 +97,7 @@ An example which combines the SDMMC driver with the FATFS library is provided in .. only:: esp32 - There is a component ESSL (ESP Serial Slave Link) to use if you are communicating with an ESP32 - SDIO slave. See :doc:`/api-reference/protocols/esp_serial_slave_link` and example :example:`peripherals/sdio/host`. + There is a component ESSL (ESP Serial Slave Link) to use if you are communicating with an ESP32 SDIO slave. See :doc:`/api-reference/protocols/esp_serial_slave_link` and example :example:`peripherals/sdio/host`. Combo (memory + IO) cards ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/api-reference/storage/vfs.rst b/docs/en/api-reference/storage/vfs.rst index c7311d58ea45..3b35ff267d0d 100644 --- a/docs/en/api-reference/storage/vfs.rst +++ b/docs/en/api-reference/storage/vfs.rst @@ -6,4 +6,3 @@ API Reference .. include-build-file:: inc/esp_vfs.inc .. include-build-file:: inc/esp_vfs_dev.inc - diff --git a/docs/en/api-reference/system/console.rst b/docs/en/api-reference/system/console.rst index 2ea4799e0bda..72a7bd7bbd89 100644 --- a/docs/en/api-reference/system/console.rst +++ b/docs/en/api-reference/system/console.rst @@ -23,7 +23,7 @@ Line editing feature lets users compose commands by typing them, erasing symbols This feature relies on ANSI escape sequence support in the terminal application. As such, serial monitors which display raw UART data can not be used together with the line editing library. If you see ``[6n`` or similar escape sequence when running :example:`system/console` example instead of a command prompt (e.g. ``esp>`` ), it means that the serial monitor does not support escape sequences. Programs which are known to work are GNU screen, minicom, and idf_monitor.py (which can be invoked using ``idf.py monitor`` from project directory). -Here is an overview of functions provided by `linenoise`_ library. +Here is an overview of functions provided by `linenoise `_ library. Configuration ^^^^^^^^^^^^^ @@ -31,12 +31,15 @@ Configuration Linenoise library does not need explicit initialization. However, some configuration defaults may need to be changed before invoking the main line editing function. :cpp:func:`linenoiseClearScreen` + Clear terminal screen using an escape sequence and position the cursor at the top left corner. :cpp:func:`linenoiseSetMultiLine` + Switch between single line and multi line editing modes. In single line mode, if the length of the command exceeds the width of the terminal, the command text is scrolled within the line to show the end of the text. In this case the beginning of the text is hidden. Single line needs less data to be sent to refresh screen on each key press, so exhibits less glitching compared to the multi line mode. On the flip side, editing commands and copying command text from terminal in single line mode is harder. Default is single line mode. :cpp:func:`linenoiseAllowEmpty` + Set whether linenoise library will return a zero-length string (if ``true``) or ``NULL`` (if ``false``) for empty lines. By default, zero-length strings are returned. @@ -44,26 +47,33 @@ Main loop ^^^^^^^^^ :cpp:func:`linenoise` + In most cases, console applications have some form of read/eval loop. :cpp:func:`linenoise` is the single function which handles user's key presses and returns completed line once 'enter' key is pressed. As such, it handles the 'read' part of the loop. :cpp:func:`linenoiseFree` + This function must be called to release the command line buffer obtained from :cpp:func:`linenoise` function. + Hints and completions ^^^^^^^^^^^^^^^^^^^^^ :cpp:func:`linenoiseSetCompletionCallback` + When user presses 'tab' key, linenoise library invokes completion callback. The callback should inspect the contents of the command typed so far and provide a list of possible completions using calls to :cpp:func:`linenoiseAddCompletion` function. :cpp:func:`linenoiseSetCompletionCallback` function should be called to register this completion callback, if completion feature is desired. ``console`` component provides a ready made function to provide completions for registered commands, :cpp:func:`esp_console_get_completion` (see below). :cpp:func:`linenoiseAddCompletion` + Function to be called by completion callback to inform the library about possible completions of the currently typed command. :cpp:func:`linenoiseSetHintsCallback` + Whenever user input changes, linenoise invokes hints callback. This callback can inspect the command line typed so far, and provide a string with hints (which can include list of command arguments, for example). The library then displays the hint text on the same line where editing happens, possibly with a different color. :cpp:func:`linenoiseSetFreeHintsCallback` + If hint string returned by hints callback is dynamically allocated or needs to be otherwise recycled, the function which performs such cleanup should be registered via :cpp:func:`linenoiseSetFreeHintsCallback`. @@ -71,20 +81,26 @@ History ^^^^^^^ :cpp:func:`linenoiseHistorySetMaxLen` + This function sets the number of most recently typed commands to be kept in memory. Users can navigate the history using up/down arrows. :cpp:func:`linenoiseHistoryAdd` + Linenoise does not automatically add commands to history. Instead, applications need to call this function to add command strings to the history. :cpp:func:`linenoiseHistorySave` + Function saves command history from RAM to a text file, for example on an SD card or on a filesystem in flash memory. :cpp:func:`linenoiseHistoryLoad` + Counterpart to :cpp:func:`linenoiseHistorySave`, loads history from a file. :cpp:func:`linenoiseHistoryFree` + Releases memory used to store command history. Call this function when done working with linenoise library. + Splitting of command line into arguments ---------------------------------------- @@ -107,12 +123,7 @@ Examples: Argument parsing ---------------- -For argument parsing, ``console`` component includes `argtable3`_ library. Please see `tutorial`_ for an introduction to `argtable3`_. Github repository also includes `examples`_. - -.. _argtable3: http://www.argtable.org/ -.. _linenoise: https://github.com/antirez/linenoise -.. _tutorial: http://www.argtable.org/tutorial/ -.. _examples: https://github.com/argtable/argtable3/tree/master/examples +For argument parsing, ``console`` component includes `argtable3 `_ library. Please see `tutorial `_ for an introduction to `argtable3 `_. Github repository also includes `examples `_. Command registration and dispatching @@ -132,17 +143,22 @@ For each command, application provides the following information (in the form of A few other functions are provided by the command registration module: :cpp:func:`esp_console_run` + This function takes the command line string, splits it into argc/argv argument list using :cpp:func:`esp_console_split_argv`, looks up the command in the list of registered components, and if it is found, executes its handler. :cpp:func:`esp_console_register_help_command` + Adds ``help`` command to the list of registered commands. This command prints the list of all the registered commands, along with their arguments and help texts. :cpp:func:`esp_console_get_completion` + Callback function to be used with :cpp:func:`linenoiseSetCompletionCallback` from linenoise library. Provides completions to linenoise based on the list of registered commands. :cpp:func:`esp_console_get_hint` + Callback function to be used with :cpp:func:`linenoiseSetHintsCallback` from linenoise library. Provides argument hints for registered commands to linenoise. + Initialize console REPL environment ----------------------------------- @@ -152,6 +168,7 @@ In a typical application, you only need to call :cpp:func:`esp_console_new_repl_ After that, you can register your own commands with :cpp:func:`esp_console_cmd_register`. The REPL environment keeps in init state until you call :cpp:func:`esp_console_start_repl`. + Application Example ------------------- @@ -159,6 +176,7 @@ Example application illustrating usage of the ``console`` component is available Besides that, ESP-IDF contains several useful examples which based on `console` component and can be treated as "tools" when developing applications. For example, :example:`peripherals/i2c/i2c_tools`, :example:`wifi/iperf`. + API Reference ------------- diff --git a/docs/en/api-reference/system/heap_debug.rst b/docs/en/api-reference/system/heap_debug.rst index 22e597e5bb8c..b656b2ee6a82 100644 --- a/docs/en/api-reference/system/heap_debug.rst +++ b/docs/en/api-reference/system/heap_debug.rst @@ -273,7 +273,7 @@ Once you've identified the code which you think is leaking: - In the project configuration menu, navigate to ``Component settings`` -> ``Heap Memory Debugging`` -> :ref:`CONFIG_HEAP_TRACING_DEST` and select ``Host-Based``. - In the project configuration menu, navigate to ``Component settings`` -> ``Application Level Tracing`` -> :ref:`CONFIG_APPTRACE_DESTINATION` and select ``Trace memory``. -- In the project configuration menu, navigate to ``Component settings`` -> ``Application Level Tracing`` -> ``FreeRTOS SystemView Tracing`` and enable :ref:`CONFIG_SYSVIEW_ENABLE`. +- In the project configuration menu, navigate to ``Component settings`` -> ``Application Level Tracing`` -> ``FreeRTOS SystemView Tracing`` and enable :ref:`CONFIG_APPTRACE_SV_ENABLE`. - Call the function :cpp:func:`heap_trace_init_tohost` early in the program, to initialize JTAG heap tracing module. - Call the function :cpp:func:`heap_trace_start` to begin recording all mallocs/frees in the system. Call this immediately before the piece of code which you suspect is leaking memory. In host-based mode argument to this function is ignored and heap tracing module behaves like ``HEAP_TRACE_ALL`` was passed: all allocations and deallocations are sent to the host. diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst index 0329792ae442..0564cb0c6e82 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst @@ -16,8 +16,8 @@ BTLC_GPIO_ENABLE (BLOCK0) Enable btlc gpio = 0 R/W (0b00) POWERGLITCH_EN (BLOCK0) Set this bit to enable power glitch function = False R/W (0b0) POWER_GLITCH_DSENSE (BLOCK0) Sample delay configuration of power glitch = 0 R/W (0b00) - DIS_LEGACY_SPI_BOOT (BLOCK0) Disables Legacy SPI boot mode = False R/W (0b0) - UART_PRINT_CHANNEL (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) + DIS_DIRECT_BOOT (BLOCK0) Disables direct boot mode = False R/W (0b0) + DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) UART_PRINT_CONTROL (BLOCK0) Sets the default UART boot message output mode = Enabled R/W (0b00) FORCE_SEND_RESUME (BLOCK0) Force ROM code to send a resume command during SPI = False R/W (0b0) bootduring SPI boot @@ -126,7 +126,7 @@ DIS_USB_DEVICE (BLOCK0) Disables USB DEVICE = False R/W (0b0) DIS_USB (BLOCK0) Disables the USB OTG hardware = False R/W (0b0) USB_EXCHG_PINS (BLOCK0) Exchanges USB D+ and D- pins = False R/W (0b0) - DIS_USB_DOWNLOAD_MODE (BLOCK0) Disables use of USB in UART download boot mode = False R/W (0b0) + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Disables download through USB-Serial-JTAG = False R/W (0b0) Vdd_Spi Config fuses: PIN_POWER_SELECTION (BLOCK0) GPIO33-GPIO37 power supply selection in ROM code = VDD3P3_CPU R/W (0b0) diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst index e629a5ead60a..2ef9b1db4508 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst @@ -38,9 +38,9 @@ FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up, = 0 R/W (0x0) unit is (ms/2). When the value is 15, delay is 7. 5 ms - DIS_LEGACY_SPI_BOOT (BLOCK0) Disables Legacy SPI boot mode = False R/W (0b0) - UART_PRINT_CHANNEL (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) - DIS_USB_DOWNLOAD_MODE (BLOCK0) Disables use of USB in UART download boot mode = False R/W (0b0) + DIS_DIRECT_BOOT (BLOCK0) Disables direct boot mode = False R/W (0b0) + DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Disables download through USB-Serial-JTAG = False R/W (0b0) UART_PRINT_CONTROL (BLOCK0) Sets the default UART boot message output mode = Enabled R/W (0b00) FLASH_TYPE (BLOCK0) Selects SPI flash type = 4 data lines R/W (0b0) FORCE_SEND_RESUME (BLOCK0) Forces ROM code to send an SPI flash resume comman = False R/W (0b0) diff --git a/docs/en/api-reference/system/ota.rst b/docs/en/api-reference/system/ota.rst index 793b2c8a9989..f7e29c6f6a21 100644 --- a/docs/en/api-reference/system/ota.rst +++ b/docs/en/api-reference/system/ota.rst @@ -5,33 +5,24 @@ Over The Air Updates (OTA) OTA Process Overview -------------------- -The OTA update mechanism allows a device to update itself based on data received while the normal firmware is running -(for example, over WiFi or Bluetooth.) +The OTA update mechanism allows a device to update itself based on data received while the normal firmware is running (for example, over Wi-Fi or Bluetooth.) -OTA requires configuring the :doc:`Partition Table <../../api-guides/partition-tables>` of the device with at least two "OTA app slot" -partitions (ie `ota_0` and `ota_1`) and an "OTA Data Partition". +OTA requires configuring the :doc:`Partition Table <../../api-guides/partition-tables>` of the device with at least two "OTA app slot" partitions (i.e. `ota_0` and `ota_1`) and an "OTA Data Partition". -The OTA operation functions write a new app firmware image to whichever OTA app slot is not currently being used for -booting. Once the image is verified, the OTA Data partition is updated to specify that this image should be used for the -next boot. +The OTA operation functions write a new app firmware image to whichever OTA app slot that is currently not selected for booting. Once the image is verified, the OTA Data partition is updated to specify that this image should be used for the next boot. .. _ota_data_partition: OTA Data Partition ------------------ -An OTA data partition (type ``data``, subtype ``ota``) must be included in the :doc:`Partition Table <../../api-guides/partition-tables>` -of any project which uses the OTA functions. +An OTA data partition (type ``data``, subtype ``ota``) must be included in the :doc:`Partition Table <../../api-guides/partition-tables>` of any project which uses the OTA functions. -For factory boot settings, the OTA data partition should contain no data (all bytes erased to 0xFF). In this case the -esp-idf software bootloader will boot the factory app if it is present in the the partition table. If no factory app is -included in the partition table, the first available OTA slot (usually ``ota_0``) is booted. +For factory boot settings, the OTA data partition should contain no data (all bytes erased to 0xFF). In this case the esp-idf software bootloader will boot the factory app if it is present in the the partition table. If no factory app is included in the partition table, the first available OTA slot (usually ``ota_0``) is booted. After the first OTA update, the OTA data partition is updated to specify which OTA app slot partition should be booted next. -The OTA data partition is two flash sectors (0x2000 bytes) in size, to prevent problems if there is a power failure -while it is being written. Sectors are independently erased and written with matching data, and if they disagree a -counter field is used to determine which sector was written more recently. +The OTA data partition is two flash sectors (0x2000 bytes) in size, to prevent problems if there is a power failure while it is being written. Sectors are independently erased and written with matching data, and if they disagree a counter field is used to determine which sector was written more recently. .. _app_rollback: @@ -51,26 +42,19 @@ App OTA State States control the process of selecting a boot app: -+-----------------------------+--------------------------------------------------------+ -| States | Restriction of selecting a boot app in bootloader | -+=============================+========================================================+ -| ESP_OTA_IMG_VALID | None restriction. Will be selected. | -+-----------------------------+--------------------------------------------------------+ -| ESP_OTA_IMG_UNDEFINED | None restriction. Will be selected. | -+-----------------------------+--------------------------------------------------------+ -| ESP_OTA_IMG_INVALID | Will not be selected. | -+-----------------------------+--------------------------------------------------------+ -| ESP_OTA_IMG_ABORTED | Will not be selected. | -+-----------------------------+--------------------------------------------------------+ -| ESP_OTA_IMG_NEW | If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option | -| | is set it will be selected only once. In bootloader | -| | the state immediately changes to | -| | ``ESP_OTA_IMG_PENDING_VERIFY``. | -+-----------------------------+--------------------------------------------------------+ -| ESP_OTA_IMG_PENDING_VERIFY | If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option | -| | is set it will not be selected and the state will | -| | change to ``ESP_OTA_IMG_ABORTED``. | -+-----------------------------+--------------------------------------------------------+ +============================= ====================================================================== + States Restriction of selecting a boot app in bootloader +============================= ====================================================================== + ESP_OTA_IMG_VALID None restriction. Will be selected. + ESP_OTA_IMG_UNDEFINED None restriction. Will be selected. + ESP_OTA_IMG_INVALID Will not be selected. + ESP_OTA_IMG_ABORTED Will not be selected. + ESP_OTA_IMG_NEW If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set it will + be selected only once. In bootloader the state immediately changes to + ``ESP_OTA_IMG_PENDING_VERIFY``. + ESP_OTA_IMG_PENDING_VERIFY If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set it will + not be selected and the state will change to ``ESP_OTA_IMG_ABORTED``. +============================= ====================================================================== If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is not enabled (by default), then the use of the following functions :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` and :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` are optional, and ``ESP_OTA_IMG_NEW`` and ``ESP_OTA_IMG_PENDING_VERIFY`` states are not used. @@ -118,8 +102,7 @@ A brief description of where the states are set: * ``ESP_OTA_IMG_VALID`` state is set by :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` function. * ``ESP_OTA_IMG_UNDEFINED`` state is set by :cpp:func:`esp_ota_set_boot_partition` function if :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is not enabled. -* ``ESP_OTA_IMG_NEW`` state is set by :cpp:func:`esp_ota_set_boot_partition` function if - :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled. +* ``ESP_OTA_IMG_NEW`` state is set by :cpp:func:`esp_ota_set_boot_partition` function if :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled. * ``ESP_OTA_IMG_INVALID`` state is set by :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` function. * ``ESP_OTA_IMG_ABORTED`` state is set if there was no confirmation of the application operability and occurs reboots (if :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled). * ``ESP_OTA_IMG_PENDING_VERIFY`` state is set in a bootloader if :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled and selected app has ``ESP_OTA_IMG_NEW`` state. @@ -133,7 +116,6 @@ Anti-rollback prevents rollback to application with security version lower than This function works if set :ref:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK` option. In the bootloader, when selecting a bootable application, an additional security version check is added which is on the chip and in the application image. The version in the bootable firmware must be greater than or equal to the version in the chip. - :ref:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK` and :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` options are used together. In this case, rollback is possible only on the security version which is equal or higher than the version in the chip. @@ -151,7 +133,7 @@ A typical anti-rollback scheme is Recommendation: -If you want to avoid the download/erase overhead in case of the app from the server has security version lower then running app you have to get ``new_app_info.secure_version`` from the first package of an image and compare it with the secure version of efuse. Use ``esp_efuse_check_secure_version(new_app_info.secure_version)`` function if it is true then continue downloading otherwise abort. +If you want to avoid the download/erase overhead in case of the app from the server has security version lower then running app, you have to get ``new_app_info.secure_version`` from the first package of an image and compare it with the secure version of efuse. Use ``esp_efuse_check_secure_version(new_app_info.secure_version)`` function if it is true then continue downloading otherwise abort. .. code-block:: c @@ -220,8 +202,7 @@ The component `app_update` provides a tool :component_file:`otatool.py`_ documentation. + Writing generic documentation for multiple chips ------------------------------------------------ @@ -252,6 +252,7 @@ The documentation for all of Espressif's chips is built from the same files. To Exclusion of content based on chip-target """"""""""""""""""""""""""""""""""""""""" + Occasionally there will be content that is only relevant for one of targets. When this is the case, you can exclude that content by using the ''.. only:: TAG'' directive, where you replace 'TAG' with one of the following names: Chip name: @@ -342,6 +343,7 @@ If you need to exclude content inside a list or bullet points, then this should Substitution macros """"""""""""""""""" + When you need to refer to the chip's name, toolchain name, path or other common names that depend on the target type you can consider using the substitution macros supplied by :idf_file:`docs/idf_extensions/format_idf_target.py`. For example, the following reStructuredText content: @@ -407,7 +409,6 @@ You can setup environment to build documentation locally on your PC by installin 6. Blockdiag - http://blockdiag.com/en/index.html 7. Recommonmark - https://github.com/rtfd/recommonmark - The package "sphinx_idf_theme" is added to have the same "look and feel" of `ESP-IDF Programming Guide `_. Do not worry about being confronted with several packages to install. Besides Doxygen, all remaining packages are written in pure Python. Therefore installation of all of them is combined into one simple step. @@ -498,6 +499,7 @@ Build documentation will be placed in ``_build///html`` folder Building a subset of the documentation """""""""""""""""""""""""""""""""""""" + Since building the full documentation can be quite slow, it might be useful to just build just the subset of the documentation you are interested in. This can be achieved by listing the document you want to build:: diff --git a/docs/en/hw-reference/esp32/get-started-devkitc.rst b/docs/en/hw-reference/esp32/get-started-devkitc.rst index 5ba9712e54fd..c96673076fe3 100644 --- a/docs/en/hw-reference/esp32/get-started-devkitc.rst +++ b/docs/en/hw-reference/esp32/get-started-devkitc.rst @@ -9,7 +9,7 @@ This guide shows how to start using the ESP32-DevKitC V4 development board. For What You Need ------------- -* ESP32-DevKitC V4 board +* :ref:`ESP32-DevKitC V4 board ` * USB A / micro USB B cable * Computer running Windows, Linux, or macOS @@ -55,31 +55,34 @@ The following figure and the table below describe the key components, interfaces ESP32-DevKitC V4 with ESP32-WROOM-32 module soldered -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Key Component | Description | -+====================+======================================================================================================================================================================================+ -| ESP32-WROOM-32 | A module with ESP32 at its core. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| EN | Reset button. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Boot | Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| USB-to-UART Bridge | Single USB-UART bridge chip provides transfer rates of up to 3 Mbps. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Micro USB Port | USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32 module. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 5V Power On LED | Turns on when the USB or an external 5V power supply is connected to the board. For details see the schematics in `Related Documents`_. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| I/O | Most of the pins on the ESP module are broken out to the pin headers on the board. You can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. | -+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :widths: 25 75 + :header-rows: 1 - .. note:: + * - Key Component + - Description + * - ESP32-WROOM-32 + - A module with ESP32 at its core. For more information, see `ESP32-WROOM-32 Datasheet`_. + * - EN + - Reset button. + * - Boot + - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. + * - USB-to-UART Bridge + - Single USB-UART bridge chip provides transfer rates of up to 3 Mbps. + * - Micro USB Port + - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-WROOM-32 module. + * - 5V Power On LED + - Turns on when the USB or an external 5V power supply is connected to the board. For details see the schematics in `Related Documents`_. + * - I/O + - Most of the pins on the ESP module are broken out to the pin headers on the board. You can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - The pins D0, D1, D2, D3, CMD and CLK are used internally for communication between ESP32 and SPI flash memory. They are grouped on both sides near the USB connector. Avoid using these pins, as it may disrupt access to the SPI flash memory / SPI RAM. +.. note:: - .. note:: + The pins D0, D1, D2, D3, CMD and CLK are used internally for communication between ESP32 and SPI flash memory. They are grouped on both sides near the USB connector. Avoid using these pins, as it may disrupt access to the SPI flash memory / SPI RAM. - The pins GPIO16 and GPIO17 are available for use only on the boards with the modules ESP32-WROOM and ESP32-SOLO-1. The boards with ESP32-WROVER modules have the pins reserved for internal use. +.. note:: + + The pins GPIO16 and GPIO17 are available for use only on the boards with the modules ESP32-WROOM and ESP32-SOLO-1. The boards with ESP32-WROVER modules have the pins reserved for internal use. Power Supply Options @@ -106,7 +109,6 @@ The component C15 may cause the following issues on earlier ESP32-DevKitC V4 boa In case these issues occur, please remove the component. The figure below shows C15 highlighted in yellow. - .. figure:: ../../../_static/esp32-devkitc-c15-location.png :align: center :alt: Location of C15 (colored yellow) on ESP32-DevKitC V4 board @@ -138,23 +140,14 @@ Board Dimensions Related Documents ----------------- -* `ESP32-DevKitC V4 schematics`_ (PDF) -* `ESP32 Datasheet`_ (PDF) -* `ESP32-WROOM-32 Datasheet`_ (PDF) -* `ESP32-WROOM-32D and ESP32-WROOM-32U Datasheet`_ (PDF) -* `ESP32-WROVER Datasheet`_ (PDF) -* `ESP32-WROVER-B Datasheet`_ (PDF) -* `ESP Product Selector`_ - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - -.. _ESP32-DevKitC V4 schematics: https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch.pdf -.. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf -.. _ESP32-WROOM-32 Datasheet: https://espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf -.. _ESP32-WROOM-32D and ESP32-WROOM-32U Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32d_esp32-wroom-32u_datasheet_en.pdf -.. _ESP32-WROVER Datasheet: https://espressif.com/sites/default/files/documentation/esp32-wrover_datasheet_en.pdf -.. _ESP32-WROVER-B Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-wrover-b_datasheet_en.pdf -.. _ESP Product Selector: https://products.espressif.com/#/product-selector?names= +* `ESP32-DevKitC V4 schematics `_ (PDF) +* `ESP32 Datasheet `_ (PDF) +* `ESP32-WROOM-32 Datasheet `_ (PDF) +* `ESP32-WROOM-32D and ESP32-WROOM-32U Datasheet `_ (PDF) +* `ESP32-WROOM-DA Datasheet `_ (PDF) +* `ESP32-WROVER Datasheet `_ (PDF) +* `ESP32-WROVER-B Datasheet `_ (PDF) +* `ESP Product Selector `_ .. toctree:: :hidden: diff --git a/docs/en/hw-reference/esp32/get-started-wrover-kit.rst b/docs/en/hw-reference/esp32/get-started-wrover-kit.rst index c0cb54575a03..e38100487f1b 100644 --- a/docs/en/hw-reference/esp32/get-started-wrover-kit.rst +++ b/docs/en/hw-reference/esp32/get-started-wrover-kit.rst @@ -360,6 +360,11 @@ Now to Development Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. +The application examples that use some hardware specific to your ESP-WROVER-KIT can be found below. + +* On-board LCD example: :example:`peripherals/spi_master/lcd` +* SD card slot example: :example:`storage/sd_card` +* Camera connector example: https://github.com/espressif/esp32-camera Related Documents ----------------- diff --git a/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst b/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst index 1c6c536221f2..ef10353df1a1 100644 --- a/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst +++ b/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst @@ -6,9 +6,9 @@ ESP32-S2-DevKitM-1(U) This user guide provides information on Espressif's small-sized development board ESP32-S2-DevKitM-1(U). -ESP32-S2-DevKitM-1(U) is a general-purpose development board based on `ESP32-S2FH4 `__ chip, which falls into ESP32-S2 chip family. With a rich peripheral set and optimized pinout, this board allows rapid prototyping. +ESP32-S2-DevKitM-1(U) is a general-purpose development board based on `ESP32-S2FH4 `__ chip, which falls into ESP32-S2 chip series. With a rich peripheral set and optimized pinout, this board allows rapid prototyping. -ESP32-S2-DevKitM-1 is embedded with `ESP32-S2-MINI-1 `__ module (on-board PCB antenna), while ESP32-S2-DevKitM-1U with `ESP32-S2-MINI-1U `__ module (U.FL connector to support external IPEX antenna). +ESP32-S2-DevKitM-1 is embedded with `ESP32-S2-MINI-1 `__ module (on-board PCB antenna), while ESP32-S2-DevKitM-1U with `ESP32-S2-MINI-1U `__ module (external antenna connector). +----------------------+-----------------------+ | |ESP32-S2-DevKitM-1| | |ESP32-S2-DevKitM-1U| | @@ -24,6 +24,7 @@ The document consists of the following major sections: - `Getting started`_: Provides an overview of the ESP32-S2-DevKitM-1(U) and hardware/software setup instructions to get started. - `Hardware reference`_: Provides more detailed information about the ESP32-S2-DevKitM-1(U)'s hardware. +- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-S2-DevKitM-1(U). - `Related Documents`_: Gives links to related documentation. Getting Started @@ -73,6 +74,8 @@ Description of Components ESP32-S2-DevKitM-1U - front +The key components of the board are described in a clockwise direction. + .. list-table:: :widths: 30 70 :header-rows: 1 @@ -80,13 +83,13 @@ Description of Components * - Key Component - Description * - ESP32-S2-MINI-1 or ESP32-S2-MINI-1U - - ESP32-S2-MINI-1 and ESP32-S2-MINI-1U are two powerful, generic Wi-Fi MCU modules that integrate ESP32-S2FH4 chip. ESP32-S2-MINI-1 comes with a PCB antenna, and ESP32-S2-MINI-1U with a U.FL connector for external IPEX antenna. They both feature a 4 MB external SPI flash. + - ESP32-S2-MINI-1 and ESP32-S2-MINI-1U are two powerful, generic Wi-Fi MCU modules that integrate ESP32-S2FH4 chip. ESP32-S2-MINI-1 comes with a PCB antenna, and ESP32-S2-MINI-1U with an external antenna connector. They both feature a 4 MB external SPI flash. + * - Pin Headers + - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. Users can program ESP32-S2FH4 chip to enable multiple functions such as SPI, I2S, UART, I2C, touch sensors, PWM etc. For details, please see :ref:`user-guide-devkitm-1-v1-header-blocks`. * - 3.3 V Power On LED - Turns on when the USB power is connected to the board. * - USB to UART Bridge - Single USB-UART bridge chip provides transfer rates up to 3 Mbps. - * - I/O Connector - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. Users can program ESP32-S2FH4 chip to enable multiple functions such as SPI, I2S, UART, I2C, touch sensors, PWM etc. For details, please see :ref:`user-guide-devkitm-1-v1-header-blocks`. * - Reset Button - Reset button. * - Micro-USB Port @@ -94,12 +97,11 @@ Description of Components * - Boot Button - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. * - RGB LED - - Addressable RGB LED (WS2812), driven by GPIO18. + - Addressable RGB LED, driven by GPIO18. * - 5 V to 3.3 V LDO - Power regulator that converts a 5 V supply into a 3.3 V output. - * - U.FL Connector - - On **ESP32-S2-MINI-1U** module only. Connects to an external IPEX antenna. - + * - External Antenna Connector + - On **ESP32-S2-MINI-1U** module only. For connector dimensions, please refer to Section External Antenna Connector Dimensions in `ESP32-S2-MINI-1 & ESP32-S2-MINI-1U Datasheet `_. Start Application Development ----------------------------- @@ -111,11 +113,15 @@ Required Hardware - ESP32-S2-DevKitM-1(U) - + For ESP32-S2-DevKitM-1U, an IPEX antenna is also required. + + For ESP32-S2-DevKitM-1U, an antenna is also required. - USB 2.0 cable (Standard-A to Micro-B) - Computer running Windows, Linux, or macOS +.. note:: + + Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. + Software Setup ^^^^^^^^^^^^^^ @@ -123,7 +129,7 @@ Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-starte .. note:: - ESP32-S2 family chip only is only supported in ESP-IDF master or version v4.2 and higher. + ESP32-S2 series of chips only is only supported in ESP-IDF master or version v4.2 and higher. Hardware Reference ================== @@ -146,46 +152,46 @@ Power Supply Options There are three mutually exclusive ways to provide power to the board: -- Micro USB port, default power supply -- 5V and GND header pins -- 3V3 and GND header pins +- Micro-USB Port, default power supply +- 5V and GND pin headers +- 3V3 and GND pin headers -It is recommended to use the first option: micro USB port. +It is recommended to use the first option: Micro-USB Port. .. _user-guide-devkitm-1-v1-header-blocks: Header Block ------------ -The two tables below provide the **Name** and **Function** of I/O header pins on both sides of the board, as shown in :ref:`user-guide-devkitm-1-v1-board-front`. The numbering and names are the same as in the `ESP32-S2-DevKitM-1(U) Schematics `_ (PDF). +The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-devkitm-1-v1-board-front`. The numbering is the same as in the `ESP32-S2-DevKitM-1(U) Schematics `_ (PDF). J1 ^^^ -=== ==== ===== ======================================================== -No. Name Type Function -=== ==== ===== ======================================================== -1 3V3 P 3.3 V power supply -2 0 I/O/T RTC_GPIO0, GPIO0 -3 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 -4 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 -5 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 -6 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 -7 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 -8 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 -9 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 -10 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 -11 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD -12 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 -13 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 -14 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 -15 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 -16 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS -17 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P -18 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N -19 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 -20 5V P 5 V power supply -21 G G Ground -=== ==== ===== ======================================================== +=== ==== ========== ============================================================= +No. Name Type [#]_ Function +=== ==== ========== ============================================================= +1 3V3 P 3.3 V power supply +2 0 I/O/T RTC_GPIO0, GPIO0 +3 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 +4 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 +5 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 +6 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 +7 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 +8 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 +9 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 +10 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 +11 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD +12 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 +13 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 +14 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 +15 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 +16 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS +17 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P +18 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N +19 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 +20 5V P 5 V power supply +21 G G Ground +=== ==== ========== ============================================================= J3 ^^^ @@ -212,16 +218,33 @@ No. Name Type Function 18 21 I/O/T RTC_GPIO21, GPIO21 19 20 I/O/T RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ 20 19 I/O/T RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D- -21 18 I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3 +21 18 I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3, RGB LED === ==== ===== ======================================================== +.. [#] P: Power supply; I: Input; O: Output; T: High impedance. + +Pin Layout +^^^^^^^^^^^ +.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-pin-layout.png + :align: center + :scale: 15% + :alt: ESP32-S2-DevKitM-1(U) (click to enlarge) + :figclass: align-center + + ESP32-S2-DevKitM-1(U) Pin Layout (click to enlarge) + +Hardware Revision Details +========================= + +This is the first revision of this board released. + Related Documents ================= * `ESP32-S2-DevKitM-1(U) Schematics `_ (PDF) * `ESP32-S2-DevKitM-1(U) PCB Layout `_ (PDF) * `ESP32-S2-DevKitM-1(U) Dimensions `_ (PDF) -* `ESP32-S2 Family Datasheet `_ (PDF) +* `ESP32-S2 Series Datasheet `_ (PDF) * `ESP32-S2-MINI-1 & ESP32-S2-MINI-1U Datasheet `_ (PDF) * `ESP Product Selector `_ -For other design documentation for the board, please contact us at sales@espressif.com. +For other design documentation for the board, please contact us at `sales@espressif.com `_. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst b/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst index f90d449dc07a..177c4971c38b 100644 --- a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst +++ b/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst @@ -319,6 +319,11 @@ If you want to use more than one extension board at the same time, please check - IO11 is multiplexed; IO11 is also multiplexed stopping you from using ESP-LyraT-8311A's pin BT_ADC that is needed to initialize the board's six buttons. - **Solution 1**: For ESP-LyraP-TouchA, do not initialize IO6 (PHOTO) and IO11 (NETWORK). Please note that the six buttons on ESP-LyraT-8311A still cannot be used. **Solution 2**: On your ESP-LyraP-LCD32, remove R39, change R41 to 100 Ohm, switch BLCT_L to on. For your ESP-LyraP-TouchA, do not initialize IO11 (NETWORK). If you want to use the six buttons on your ESP-LyraT-8311A, also do not initialize IO6 (PHOTO). +Also, all extension boards and the :ref:`JTAG interface ` share the same pins IO39, IO40, IO41 and IO42. For this reason, the following may disturb the JTAG operation: + +* Plugging in any extension board +* Debugging an application that is using an extension board + Known issues ============ diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst b/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst index bf907a4fc26f..566c3af436aa 100644 --- a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst +++ b/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst @@ -342,6 +342,10 @@ If you want to use more than one extension board at the same time, please check - If ESP-LyraT-8311A's pin BT_ADC is used to initialize the board's six buttons, IO6 and IO11 will not be available for the other boards. - Do not initialize IO11 (NETWORK) for your ESP-LyraP-TouchA. Also, if you need to use BT_ADC, do not initialize IO6 (PHOTO). +Also, all extension boards and the :ref:`JTAG interface ` share the same pins IO39, IO40, IO41 and IO42. For this reason, the following may disturb the JTAG operation: + +* Plugging in any extension board +* Debugging an application that is using an extension board Hardware Revision Details @@ -387,6 +391,3 @@ Related Documents - `ESP32-S2-Kaluga-1 Pin Mapping `_ (Excel) For other design documentation for the board, please contact us at sales@espressif.com. - - - \ No newline at end of file diff --git a/docs/en/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst b/docs/en/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst index 378da941fd3a..7a6a90e47059 100644 --- a/docs/en/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst +++ b/docs/en/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst @@ -17,6 +17,7 @@ The document consists of the following major sections: - `Getting started`_: Provides an overview of the ESP32-S2-Saola-1 and hardware/software setup instructions to get started. - `Hardware reference`_: Provides more detailed information about the ESP32-S2-Saola-1's hardware. +- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-S2-Saola-1. - `Related Documents`_: Gives links to related documentation. Getting Started @@ -48,7 +49,6 @@ If you order a few samples, each ESP32-S2-Saola-1 comes in an individual package For retail orders, please go to https://www.espressif.com/en/company/contact/buy-a-sample. - Wholesale Orders ^^^^^^^^^^^^^^^^ @@ -59,6 +59,8 @@ For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales Description of Components ------------------------- +.. _user-guide-saola-1-v1.2-board-front: + .. figure:: ../../../_static/esp32-s2-saola-1-v1.2-annotated-photo.png :align: center :alt: ESP32-S2-Saola-1 - front/back @@ -66,6 +68,8 @@ Description of Components ESP32-S2-Saola-1 - front +The key components of the board are described in a clockwise direction. + .. list-table:: :widths: 30 70 :header-rows: 1 @@ -74,22 +78,21 @@ Description of Components - Description * - ESP32-S2-WROVER - ESP32-S2-WROVER is a powerful, generic Wi-Fi MCU module that integrates ESP32-S2. It has a PCB antenna, a 4 MB external SPI flash and an additional 2 MB PSRAM. - * - I/O Connector + * - Pin Headers - All available GPIO pins (except for the SPI bus for flash and PSRAM) are broken out to the pin headers on the board. Users can program ESP32-S2 chip to enable multiple functions such as SPI, I2S, UART, I2C, touch sensors, PWM etc. - * - USB to UART Bridge + * - 3.3 V Power On LED + - Turns on when the USB power is connected to the board. + * - USB-to-UART Bridge - Single USB-UART bridge chip provides transfer rates up to 3 Mbps. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. * - Reset Button - Reset button. - * - 3.3 V Power On LED - - Turns on when the USB power is connected to the board. * - Micro-USB Port - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-S2 chip. + * - Boot Button + - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. * - RGB LED - Addressable RGB LED (WS2812), driven by GPIO18. - Start Application Development ----------------------------- @@ -102,6 +105,10 @@ Required Hardware - USB 2.0 cable (Standard-A to Micro-B) - Computer running Windows, Linux, or macOS +.. note:: + + Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. + Software Setup ^^^^^^^^^^^^^^ @@ -109,7 +116,7 @@ Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-starte .. note:: - ESP32-S2 only supports ESP-IDF master or version v4.2 and higher. + ESP32-S2 series of chips only supports ESP-IDF master or version v4.2 and higher. Hardware Reference ================== @@ -132,9 +139,89 @@ Power Supply Options There are three mutually exclusive ways to provide power to the board: -- Micro USB port, default power supply -- 5V and GND header pins -- 3V3 and GND header pins +- Micro-USB port, default power supply +- 5V and GND pin headers +- 3V3 and GND pin headers + +It is recommended to use the first option: Micro-USB Port. + +Header Block +------------ + +The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J2 and J3). The pin header names are shown in :ref:`user-guide-saola-1-v1.2-board-front`. The numbering is the same as in the `ESP32-S2-Saola-1 Schematics`_ (PDF). + +J2 +^^^ +=== ==== ========== ====================================== +No. Name Type [#]_ Function +=== ==== ========== ====================================== +1 3V3 P 3.3 V power supply +2 IO0 I/O GPIO0, Boot +3 IO1 I/O GPIO1, ADC1_CH0, TOUCH_CH1 +4 IO2 I/O GPIO2, ADC1_CH1, TOUCH_CH2 +5 IO3 I/O GPIO3, ADC1_CH2, TOUCH_CH3 +6 IO4 I/O GPIO4, ADC1_CH3, TOUCH_CH4 +7 IO5 I/O GPIO5, ADC1_CH4, TOUCH_CH5 +8 IO6 I/O GPIO6, ADC1_CH5, TOUCH_CH6 +9 IO7 I/O GPIO7, ADC1_CH6, TOUCH_CH7 +10 IO8 I/O GPIO8, ADC1_CH7, TOUCH_CH8 +11 IO9 I/O GPIO9, ADC1_CH8, TOUCH_CH9 +12 IO10 I/O GPIO10, ADC1_CH9, TOUCH_CH10 +13 IO11 I/O GPIO11, ADC2_CH0, TOUCH_CH11 +14 IO12 I/O GPIO12, ADC2_CH1, TOUCH_CH12 +15 IO13 I/O GPIO13, ADC2_CH2, TOUCH_CH13 +16 IO14 I/O GPIO14, ADC2_CH3, TOUCH_CH14 +17 IO15 I/O GPIO15, ADC2_CH4, XTAL_32K_P +18 IO16 I/O GPIO16, ADC2_CH5, XTAL_32K_N +19 IO17 I/O GPIO17, ADC2_CH6, DAC_1 +20 5V0 P 5 V power supply +21 GND G Ground +=== ==== ========== ====================================== + +J3 +^^^ +=== ==== ===== ==================================== +No. Name Type Function +=== ==== ===== ==================================== +1 GND G Ground +2 RST I CHIP_PU, Reset +3 IO46 I GPIO46 +4 IO45 I/O GPIO45 +5 IO44 I/O GPIO44, U0RXD +6 IO43 I/O GPIO43, U0TXD +7 IO42 I/O GPIO42, MTMS +8 IO41 I/O GPIO41, MTDI +9 IO40 I/O GPIO40, MTDO +10 IO39 I/O GPIO39, MTCK +11 IO38 I/O GPIO38 +12 IO37 I/O GPIO37 +13 IO36 I/O GPIO36 +14 IO35 I/O GPIO35 +16 IO34 I/O GPIO34 +17 IO33 I/O GPIO33 +17 IO26 I/O GPIO26 +18 IO21 I/O GPIO21 +19 IO20 I/O GPIO20, ADC2_CH9, USB_D+ +20 IO19 I/O GPIO19, ADC2_CH8, USB_D- +21 IO18 I/O GPIO18, ADC2_CH7, DAC_2, RGB LED +=== ==== ===== ==================================== + +.. [#] P: Power supply; I: Input; O: Output; T: High impedance. + +Pin Layout +^^^^^^^^^^^ +.. figure:: ../../../_static/esp32-s2_saola1-pinout.jpg + :align: center + :scale: 45% + :alt: ESP32-S2-Saola-1 (click to enlarge) + :figclass: align-center + + ESP32-S2 Saola-1 Pin Layout (click to enlarge) + +Hardware Revision Details +========================= + +This is the first revision of this board released. Related Documents ================= @@ -146,7 +233,7 @@ Related Documents * `ESP32-S2-WROOM and ESP32-S2-WROOM-I Datasheet`_ (PDF) * `ESP Product Selector`_ -For other design documentation for the board, please contact us at sales@espressif.com. +For other design documentation for the board, please contact us at `sales@espressif.com `_. .. _ESP32-S2-Saola-1 Schematics: https://dl.espressif.com/dl/schematics/ESP32-S2-SAOLA-1_V1.1_schematics.pdf .. _ESP32-S2-Saola-1 Dimensions: https://dl.espressif.com/dl/schematics/ESP32-S2-Saola-1_V1.2_Dimensions.pdf diff --git a/docs/zh_CN/api-guides/app_trace.rst b/docs/zh_CN/api-guides/app_trace.rst index 7b8774d54074..3983d92844c3 100644 --- a/docs/zh_CN/api-guides/app_trace.rst +++ b/docs/zh_CN/api-guides/app_trace.rst @@ -325,10 +325,10 @@ IDF 中另一个基于应用层跟踪库的实用功能是系统级跟踪,它 如何使用 """""""" -若需使用这个功能,需要在 menuconfig 中开启 :ref:`CONFIG_SYSVIEW_ENABLE` 选项,具体路径为: *Component config > Application Level Tracing > FreeRTOS SystemView Tracing* 。在同一个菜单栏下还开启了其他几个选项: +若需使用这个功能,需要在 menuconfig 中开启 :ref:`CONFIG_APPTRACE_SV_ENABLE` 选项,具体路径为: *Component config > Application Level Tracing > FreeRTOS SystemView Tracing* 。在同一个菜单栏下还开启了其他几个选项: -1. *{IDF_TARGET_NAME} timer to use as SystemView timestamp source* (:ref:`CONFIG_SYSVIEW_TS_SOURCE`)选择 SystemView 事件使用的时间戳来源。在单核模式下,使用 {IDF_TARGET_NAME} 内部的循环计数器生成时间戳,其最大的工作频率是 240 MHz(时间戳粒度大约为 4 ns)。在双核模式下,使用工作在 40 MHz 的外部定时器,因此时间戳粒度为 25 ns。 -2. 可以单独启用或禁用的 SystemView 事件集合(``CONFIG_SYSVIEW_EVT_XXX``): +1. *{IDF_TARGET_NAME} timer to use as SystemView timestamp source* (:ref:`CONFIG_APPTRACE_SV_TS_SOURCE`)选择 SystemView 事件使用的时间戳来源。在单核模式下,使用 {IDF_TARGET_NAME} 内部的循环计数器生成时间戳,其最大的工作频率是 240 MHz(时间戳粒度大约为 4 ns)。在双核模式下,使用工作在 40 MHz 的外部定时器,因此时间戳粒度为 25 ns。 +2. 可以单独启用或禁用的 SystemView 事件集合(``CONFIG_APPTRACE_SV_EVT_XXX``): - Trace Buffer Overflow Event - ISR Enter Event diff --git a/docs/zh_CN/api-guides/external-ram.rst b/docs/zh_CN/api-guides/external-ram.rst index b0cea63e4290..ed484927ece7 100644 --- a/docs/zh_CN/api-guides/external-ram.rst +++ b/docs/zh_CN/api-guides/external-ram.rst @@ -112,9 +112,13 @@ ESP-IDF 启动过程中,片外 RAM 被映射到以 0x3F800000 起始的数据 * Flash cache 禁用时(比如,正在写入 flash),片外 RAM 将无法访问;同样,对片外 RAM 的读写操作也将导致 cache 访问异常。出于这个原因,ESP-IDF 不会在片外 RAM 中分配任务堆栈(详见下文)。 - * 片外 RAM 不能用于储存 DMA 事物描述符,也不能用作 DMA 读写操作的缓冲区 (Buffer)。与 DMA 搭配使用的 Buffer 必须先使用 ``heap_caps_malloc(size, MALLOC_CAP_DMA)`` 进行分配,之后可以调用标准 ``free()`` 回调释放 Buffer。 + * 片外 RAM 不能用于储存 DMA 事务描述符,也不能用作 DMA 读写操作的缓冲区 (Buffer)。因此,当片外 RAM 启用时,与 DMA 搭配使用的 Buffer 必须先使用 ``heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL)`` 进行分配,之后可以调用标准 ``free()`` 回调释放 Buffer。 - * 片外 RAM 与片外 flash 使用相同的 cache 区域,这意味着频繁在片外 RAM 访问的变量可以像在片上 RAM 中一样快速读取和修改。但访问大块数据时(大于 32 KB),cache 空间可能会不足,访问速度将回落到片外 RAM 访问速度。此外,访问大块数据可以挤出 flash cache,可能会降低代码执行速度。 +.. only:: SOC_PSRAM_DMA_CAPABLE + + 注意,尽管 {IDF_TARGET_NAME} 中已有硬件支持 DMA 与片外 RAM,但在 ESP-IDF 中,尚未提供软件支持。 + +* 片外 RAM 与片外 flash 使用相同的 cache 区域,这意味着频繁在片外 RAM 访问的变量可以像在片上 RAM 中一样快速读取和修改。但访问大块数据时(大于 32 KB),cache 空间可能会不足,访问速度将回落到片外 RAM 访问速度。此外,访问大块数据会挤出 flash cache,可能降低代码执行速度。 * 片外 RAM 不可用作任务堆栈存储器。因此 :cpp:func:`xTaskCreate` 及类似函数将始终为堆栈和任务 TCB 分配片上储存器,而 :cpp:func:`xTaskCreateStatic` 类型的函数将检查传递的 Buffer 是否属于片上存储器。 diff --git a/docs/zh_CN/api-guides/index.rst b/docs/zh_CN/api-guides/index.rst index 4fea835410e5..18a36e1ff799 100644 --- a/docs/zh_CN/api-guides/index.rst +++ b/docs/zh_CN/api-guides/index.rst @@ -43,3 +43,4 @@ API 指南 :SOC_USB_SUPPORTED: USB 控制台 :SOC_USB_SERIAL_JTAG_SUPPORTED: USB Serial/JTAG Controller Console Wi-Fi 驱动 + Wi-Fi Security diff --git a/docs/zh_CN/api-guides/partition-tables.rst b/docs/zh_CN/api-guides/partition-tables.rst index 23a95fd14cb0..2a2a91af6eea 100644 --- a/docs/zh_CN/api-guides/partition-tables.rst +++ b/docs/zh_CN/api-guides/partition-tables.rst @@ -174,7 +174,14 @@ MD5 校验和 二进制格式的分区表中含有一个 MD5 校验和。这个 MD5 校验和是根据分区表内容计算的,可在设备启动阶段,用于验证分区表的完整性。 -注意,一些版本较老的启动加载器无法支持 MD5 校验,如果发现 MD5 校验和则将报错 ``invalid magic number 0xebeb``。此时,用户可通过 ``gen_esp32part.py`` 的 ``--disable-md5sum`` 选项或者 :ref:`CONFIG_PARTITION_TABLE_MD5` 选项关闭 MD5 校验。 +.. only:: esp32 + + 用户可通过 ``gen_esp32part.py`` 的 ``--disable-md5sum`` 选项或者 :ref:`CONFIG_PARTITION_TABLE_MD5` 选项关闭 MD5 校验。对于 :ref:`ESP-IDF v3.1 版本前的引导加载程序 `,因为它不支持 MD5 校验,所以无法正常启动并报错 ``invalid magic number 0xebeb``,此时用户可以使用此选项关闭 MD5 校验。 + +.. only:: not esp32 + + 用户可通过 ``gen_esp32part.py`` 的 ``--disable-md5sum`` 选项或者 :ref:`CONFIG_PARTITION_TABLE_MD5` 选项关闭 MD5 校验。 + 烧写分区表 ---------- @@ -267,7 +274,7 @@ Python API parttool.py --port "/dev/ttyUSB1" read_partition --partition-type=data --partition-subtype=spiffs --output "spiffs.bin" # 将 'factory.bin' 文件中的内容写入到 'factory' 分区 - parttool.py --port "/dev/ttyUSB1" write_partition --partition-name=factory "factory.bin" + parttool.py --port "/dev/ttyUSB1" write_partition --partition-name=factory --input "factory.bin" # 打印默认启动分区的大小 parttool.py --port "/dev/ttyUSB1" get_partition_info --partition-boot-default --info size diff --git a/docs/zh_CN/api-guides/tools/idf-component-manager.rst b/docs/zh_CN/api-guides/tools/idf-component-manager.rst new file mode 100644 index 000000000000..8017f17fbc7b --- /dev/null +++ b/docs/zh_CN/api-guides/tools/idf-component-manager.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-guides/tools/idf-component-manager.rst diff --git a/docs/zh_CN/api-guides/tools/index.rst b/docs/zh_CN/api-guides/tools/index.rst index ef6903c59119..41438ae874c7 100644 --- a/docs/zh_CN/api-guides/tools/index.rst +++ b/docs/zh_CN/api-guides/tools/index.rst @@ -8,3 +8,4 @@ IDF 监视器 IDF Docker image IDF Windows Installer + IDF Component Manager diff --git a/docs/zh_CN/api-guides/wifi-security.rst b/docs/zh_CN/api-guides/wifi-security.rst new file mode 100644 index 000000000000..ae682a8363ee --- /dev/null +++ b/docs/zh_CN/api-guides/wifi-security.rst @@ -0,0 +1 @@ +.. include:: ../../en/api-guides/wifi-security.rst diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index fe4d238c4a1c..1509a1341779 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -2,17 +2,17 @@ ================== :link_to_translation:`en:[English]` + {IDF_TARGET_NAME} Wi-Fi 功能列表 ------------------------------------ - 支持仅 station 模式、仅 AP 模式、station/AP 共存模式 - 支持使用 IEEE 802.11B、IEEE 802.11G、IEEE 802.11N 和 API 配置协议模式 -- 支持 WPA/WPA2/WPA2-企业版和 WPS +- 支持 WPA/WPA2/WPA3/WPA2-企业版和 WPS - 支持 AMPDU、HT40、QoS 以及其它主要功能 - 支持 Modem-sleep - 支持乐鑫专属协议,可实现 **1 km** 数据通信量 - 空中数据传输最高可达 20 MBit/s TCP 吞吐量和 30 MBit/s UDP 吞吐量 - 支持 Sniffer -- 支持用于 Wi-Fi 连接的 fast_crypto 算法与普通算法的切换 - 支持快速扫描和全信道扫描 - 支持多个天线 - 支持获取信道状态信息 @@ -299,7 +299,7 @@ WIFI_EVENT_AP_PROBEREQRECVED } -1.Wi-Fi/LwIP 初始化阶段 +1. Wi-Fi/LwIP 初始化阶段 ++++++++++++++++++++++++++++++ - s1.1:主任务通过调用函数 :cpp:func:`esp_netif_init()` 创建一个 LwIP 核心任务,并初始化 LwIP 相关工作。 @@ -313,7 +313,7 @@ WIFI_EVENT_AP_PROBEREQRECVED 推荐按照 s1.1 ~ s1.5 的步骤顺序针对基于 Wi-Fi/LwIP 的应用程序进行初始化。但这一顺序 **并非** 强制,您可以在第 s1.1 步创建应用程序任务,然后在该应用程序任务中进行所有其它初始化操作。不过,如果您的应用程序任务依赖套接字,那么在初始化阶段创建应用程序任务可能并不适用。此时,您可以在接收到 IP 后再进行任务创建。 -2.Wi-Fi 配置阶段 +2. Wi-Fi 配置阶段 +++++++++++++++++++++++++++++++ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景下,Wi-Fi 驱动程序处于 station 模式。因此,首先您需调用函数 :cpp:func:`esp_wifi_set_mode` (WIFI_MODE_STA) 将 Wi-Fi 模式配置为 station 模式。可通过调用其它 esp_wifi_set_xxx API 进行更多设置,例如:协议模式、国家代码、带宽等。请参阅 `{IDF_TARGET_NAME} Wi-Fi 配置`_。 @@ -321,13 +321,13 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 如果 menuconfig 已使能 Wi-Fi NVS flash,则不论当前阶段还是后续的 Wi-Fi 配置信息都将被存储至该 flash 中。那么,当主板上电/重新启动时,就不需从头开始配置 Wi-Fi 驱动程序。您只需调用函数 esp_wifi_get_xxx API 获取之前存储的配置信息。当然,如果不想使用之前的配置,您依然可以重新配置 Wi-Fi 驱动程序。 -3.Wi-Fi 启动阶段 +3. Wi-Fi 启动阶段 ++++++++++++++++++++++++++++++++ - s3.1:调用函数 :cpp:func:`esp_wifi_start()` 启动 Wi-Fi 驱动程序。 - s3.2:Wi-Fi 驱动程序将事件 `WIFI_EVENT_STA_START`_ 发布到事件任务中,然后,事件任务将执行一些正常操作并调用应用程序的事件回调函数。 - s3.3:应用程序的事件回调函数将事件 `WIFI_EVENT_STA_START`_ 中继到应用程序任务中。推荐您此时调用函数 :cpp:func:`esp_wifi_connect()` 进行 Wi-Fi 连接。当然,您也可以等待在 `WIFI_EVENT_STA_START`_ 事件发生后的其它阶段再调用此函数。 -4.Wi-Fi 连接阶段 +4. Wi-Fi 连接阶段 +++++++++++++++++++++++++++++++++ - s4.1:调用函数 :cpp:func:`esp_wifi_connect()` 后,Wi-Fi 驱动程序将启动内部扫描/连接过程。 @@ -337,26 +337,26 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 步骤 s4.2 中 Wi-Fi 连接可能会由于某些原因而失败,例如:密码错误、未找到 AP 等。这种情况下,将引发 `WIFI_EVENT_STA_DISCONNECTED`_ 事件并提示连接错误原因。有关如何处理中断 Wi-Fi 连接的事件,请参阅下文阶段 6 的描述。 -5.Wi-Fi 获取 IP 阶段 +5. Wi-Fi 获取 IP 阶段 +++++++++++++++++++++++++++++++++ - s5.1:一旦步骤 4.2 中的 DHCP 客户端初始化完成,Wi-Fi 驱动程序将进入 *获取 IP* 阶段。 - s5.2:如果 Wi-Fi 成功从 DHCP 服务器接收到 IP 地址,则将引发 `IP_EVENT_STA_GOT_IP`_ 事件,事件任务将执行正常处理。 - s5.3:应用程序的事件回调函数将事件 `IP_EVENT_STA_GOT_IP`_ 中继到应用程序任务中。对于那些基于 LwIP 构建的应用程序,此事件较为特殊,因为它意味着应用程序已准备就绪,可以开始任务,例如:创建 TCP/UDP 套接字等。此时较为容易犯的一个错误就是在接收到 `IP_EVENT_STA_GOT_IP`_ 事件之前就初始化套接字。**切忌在接收到 IP 之前启动任何套接字相关操作。** -6.Wi-Fi 断开阶段 +6. Wi-Fi 断开阶段 +++++++++++++++++++++++++++++++++ - s6.1:当 Wi-Fi 因为某些原因(例如:AP 掉电、RSSI 较弱等)连接中断时,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件。此事件也可能在上文阶段 3 中发生。在这里,事件任务将通知 LwIP 任务清除/移除所有 UDP/TCP 连接。然后,所有应用程序套接字都将处于错误状态。也就是说,`WIFI_EVENT_STA_DISCONNECTED`_ 事件发生时,任何套接字都无法正常工作。 - s6.2:上述情况下,应用程序的事件回调函数会将 `WIFI_EVENT_STA_DISCONNECTED`_ 事件中继到应用程序任务中。推荐您调用函数 :cpp:func:`esp_wifi_connect()` 重新连接 Wi-Fi,关闭所有套接字,并在必要时重新创建套接字。请参阅 `WIFI_EVENT_STA_DISCONNECTED`_。 -7.Wi-Fi IP 更改阶段 +7. Wi-Fi IP 更改阶段 ++++++++++++++++++++++++++++++++++ - s7.1:如果 IP 地址发生更改,将引发 `IP_EVENT_STA_GOT_IP`_ 事件,其中 "ip_change" 被置为 "true"。 - s7.2:**此事件对应用程序至关重要。这一事件发生时,适合关闭所有已创建的套接字并进行重新创建。** -8.Wi-Fi 清理阶段 +8. Wi-Fi 清理阶段 ++++++++++++++++++++++++++++ - s8.1:调用函数 :cpp:func:`esp_wifi_disconnect()` 断开 Wi-Fi 连接。 @@ -420,25 +420,24 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 扫描类型 +++++++++++++++++++++++++ -+--------------+---------------------------------------------------------------------------------------------------+ -| 模式 | 描述 | -+==============+===================================================================================================+ -| 主动扫描 | 通过发送 probe request 进行扫描。该模式为默认的扫描模式。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 被动扫描 | 跳至某一特定信道并等待 beacon。应用程序可通过wifi_scan_config_t 中的 scan_type 字段使能被动扫描。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 前端扫描 | 不发出 probe request。在 station 模式下 Wi-Fi 未连接时,可进行前端扫描。 | -| | Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 后端扫描 | 在 station 模式或 station/AP 共存模式下 Wi-Fi 已连接时,可进行后端扫描。 | -| | Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 全信道扫描 | 扫描所有信道。wifi_scan_config_t 中的 channel 字段为 0 时, | -| | 当前模式为全信道扫描。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 特定信道扫描 | 仅扫描特定的信道。wifi_scan_config_t 中的 channel 字段为 1 | -| | 时,当前模式为特定信道扫描。 | -+--------------+---------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - 模式 + - 描述 + * - 主动扫描 + - 通过发送 probe request 进行扫描。该模式为默认的扫描模式。 + * - 被动扫描 + - 不发送 probe request。跳至某一特定信道并等待 beacon。应用程序可通过 wifi_scan_config_t 中的 scan_type 字段使能被动扫描。 + * - 前端扫描 + - 在 station 模式下 Wi-Fi 未连接时,可进行前端扫描。Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 + * - 后端扫描 + - 在 station 模式或 station/AP 共存模式下 Wi-Fi 已连接时,可进行后端扫描。Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 + * - 全信道扫描 + - 扫描所有信道。wifi_scan_config_t 中的 channel 字段为 0 时,当前模式为全信道扫描。 + * - 特定信道扫描 + - 仅扫描特定的信道。wifi_scan_config_t 中的 channel 字段为 1-14 时,当前模式为特定信道扫描。 上表中的扫描模式可以任意组合,因此共有 8 种不同扫描方式: @@ -451,42 +450,40 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 - 特定信道前端主动扫描 - 特定信道前端被动扫描 - 扫描配置 +++++++++++++++++ 扫描类型与其他扫描属性通过函数 :cpp:func:`esp_wifi_scan_start` 进行配置。下表详细描述了函数 wifi_scan_config_t 各字段信息。 -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| 字段 | 描述 | -+=============+======================================================================================================================+ -| ssid | 如果该字段的值不为 NULL,则仅可扫描到具有相同 SSID 值的 AP。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| bssid | 如果该字段的值不为 NULL,则仅可扫描到具有相同 BSSID 值的 AP。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| channel | 如果该字段值为 0,将进行全信道扫描;反之,将针对特定信道进行扫描。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| show_hidden | 如果该字段值为 0,本次扫描将忽略具有隐藏 SSID 的 AP; | -| | 反之,这些 AP 也会在扫描时被视为正常 AP。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| scan_type | 如果该字段值为为 WIFI_SCAN_TYPE_ACTIVE,则本次扫描为主动扫描; | -| | 反之,将被视为被动扫描。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| scan_time | 该字段用于控制每个信道的扫描时间。 | -| | | -| | 被动扫描时,scan_time.passive 字段负责为每个信道指定扫描时间。 | -| | | -| | 主动扫描时,每个信道的扫描时间如下列表所示。其中,min 代表 | -| | scan_time_active_min,max 代表 scan_time_active_max。 | -| | | -| | - min=0, max=0:每个信道的扫描时间为 120 ms。 | -| | - min>0, max=0:每个信道的扫描时间为 120 ms。 | -| | - min=0, max>0:每个信道的扫描时间为 ``max`` ms。 | -| | - min>0, max>0:每个信道扫描的最短时间为 ``min`` ms。 如果在这段时间内未找到 AP,将跳转至下一个信道。如这段时间内 | -| | 找到 AP,则该信道的扫描时间为 ``max`` ms。 | -| | | -| | 如希望提升 Wi-Fi 扫描性能,则可修改上述两个参数。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - 字段 + - 描述 + * - ssid + - 如果该字段的值不为 NULL,则仅可扫描到具有相同 SSID 值的 AP。 + * - bssid + - 如果该字段的值不为 NULL,则仅可扫描到具有相同 BSSID 值的 AP。 + * - channel + - 如果该字段值为 0,将进行全信道扫描;反之,将针对特定信道进行扫描。 + * - show_hidden + - 如果该字段值为 0,本次扫描将忽略具有隐藏 SSID 的 AP;反之,这些 AP 也会在扫描时被视为正常 AP。 + * - scan_type + - 如果该字段值为为 WIFI_SCAN_TYPE_ACTIVE,则本次扫描为主动扫描;反之,将被视为被动扫描。 + * - scan_time + - 该字段用于控制每个信道的扫描时间。 + + 被动扫描时,scan_time.passive 字段负责为每个信道指定扫描时间。 + + 主动扫描时,每个信道的扫描时间如下列表所示。其中,min 代表 scan_time_active_min,max 代表 scan_time_active_max。 + + - min=0, max=0:每个信道的扫描时间为 120 ms。 + - min>0, max=0:每个信道的扫描时间为 120 ms。 + - min=0, max>0:每个信道的扫描时间为 ``max`` ms。 + - min>0, max>0:每个信道扫描的最短时间为 ``min`` ms。 如果在这段时间内未找到 AP,将跳转至下一个信道。如这段时间内找到 AP,则该信道的扫描时间为 ``max`` ms。 + + 如希望提升 Wi-Fi 扫描性能,则可修改上述两个参数。 调用 API :cpp:func:`esp_wifi_set_config` 可全局配置一些扫描属性,请参阅 `station 基本配置`_。 @@ -746,212 +743,258 @@ Wi-Fi 原因代码 下表罗列了 {IDF_TARGET_NAME} 中定义的原因代码。其中,第一列为 esp_wifi_types.h 中定义的宏名称。名称中省去了前缀 *WIFI_REASON*,也就是说,名称 *UNSPECIFIED* 实际应为 *WIFI_REASON_UNSPECIFIED*,以此类推。第二列为原因代码的相应数值。第三列为该原因映射到 IEEE 802.11-2012 中 8.4.1.7 段的标准值。(更多详细信息,请参阅前文描述。)最后一列为这一原因的描述。 +.. list-table:: + :header-rows: 1 + :widths: 5 10 12 40 + + * - 原因代码 + - 数值 + - 映射值 + - 描述 + * - UNSPECIFIED + - 1 + - 1 + - 出现内部错误,例如:内存已满,内部发送失败,或该原因已被远端接收等。 + * - AUTH_EXPIRE + - 2 + - 2 + - 先前的 authentication 已失效。 + + 对于 ESP station,出现以下情况时将报告该代码: + + - authentication 超时; + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - 在过去五分钟之内,AP 未从 station 接收到任何数据包; + - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; + - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 authentication 取消。 + * - AUTH_LEAVE + - 3 + - 3 + - authentication 取消,因为发送 station 正在离开(或已经离开)。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - ASSOC_EXPIRE + - 4 + - 4 + - 因为 AP 不活跃,association 取消。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - 在过去五分钟之内, AP 未从 station 接收到任何数据包; + - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; + - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 authentication 取消。 + * - ASSOC_TOOMANY + - 5 + - 5 + - association 取消,因为 AP 无法同时处理所有当前已关联的 STA。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。 + * - NOT_AUTHED + - 6 + - 6 + - 从一个未认证 station 接收到 class-2 frame。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 从一个未认证 station 接收到数据包。 + * - NOT_ASSOCED + - 7 + - 7 + - 从一个未关联 station 接收到的 class-3 frame。 + + 对于 ESP station,出现以下情况时报告该代码: -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| 原因代码 | 数值 | 映射值 | 描述 | -+==========================+======+==========+=========================================================================+ -| UNSPECIFIED | 1 | 1 | 出现内部错误,例如:存储器已满,内部发送失败,或该原因已 被远端接收等。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AUTH_EXPIRE | 2 | 2 | 先前的 authentication 已失效。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时将报告该代码: | -| | | | | -| | | | - authentication 超时; | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时将报告该代码: | -| | | | | -| | | | - 在过去五分钟之内,AP 未从 station 接收到任何数据包; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 auth | -| | | | 取消。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AUTH_LEAVE | 3 | 3 | authentication 取消,因为发送 STA 正在离开(或已经离开)。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_EXPIRE | 4 | 4 | association 取消,因为 AP 不活跃。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - 在过去五分钟之内, AP 未从 station 接收到任何数据包; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 auth | -| | | | 取消。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_TOOMANY | 5 | 5 | association 取消,因为 AP 无法同时处理所有当前已关联的 STA。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| NOT_AUTHED | 6 | 6 | 从一个未认证 STA 接收到 class-2 frame。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 从一个未认证 station 接收到数据包。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| NOT_ASSOCED | 7 | 7 | 从一个未关联 STA 接收到的 class-3 frame。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 从未关联 station 接收到数据包。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_LEAVE | 8 | 8 | association 取消,因为发送 STA 正在离开(或已经离开)BSS。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码; | -| | | | - 由于调用 :cpp:func:`esp_wifi_disconnect()` 其它 API, | -| | | | station 断开连接。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_NOT_AUTHED | 9 | 9 | STA 的 re(association) 请求未被响应 STA 认证。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 从一个已关联,但未认证的 station 接收到数据包。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| DISASSOC_PWRCAP_BAD | 10 | 10 | association 取消,因为无法接收功率能力 (Power Capability) | -| | | | 元素中的信息。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| DISASSOC_SUPCHAN_BAD | 11 | 11 | association 取消,因为无法接收支持的信道 (Supported Channels) | -| | | | 元素中的信息。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| IE_INVALID | 13 | 13 | 无效元素,即内容不符合 Wi-Fi 协议中帧格式 (Frame formats) | -| | | | 章节所描述标准的元素。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 解析了一个错误的 WPA 或 RSN IE。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| MIC_FAILURE | 14 | 14 | 消息完整性代码 (MIC) 出错。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| 4WAY_HANDSHAKE_TIMEOUT | 15 | 15 | 四次握手超时。由于某些历史原因,在 ESP 中该原因代码实为 | -| | | | WIFI_REASON_HANDSHAKE_TIMEOUT。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 握手超时; | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| GROUP_KEY_UPDATE_TIMEOUT | 16 | 16 | 组密钥 (Group-Key) 握手超时。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| IE_IN_4WAY_DIFFERS | 17 | 17 | 四次握手中产生的元素与 (re-)association 后的 request/probe 以及 | -| | | | response/beacon frame 中的信息不同。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码; | -| | | | - station 发现四次握手的 IE 与 (re-)association 后的 request/probe | -| | | | 以及 response/beacon frame 中的 IE 不同。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| GROUP_CIPHER_INVALID | 18 | 18 | 无效组密文。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| PAIRWISE_CIPHER_INVALID | 19 | 19 | 无效成对密文。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AKMP_INVALID | 20 | 20 | 无效 AKMP。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| UNSUPP_RSN_IE_VERSION | 21 | 21 | RSNE 版本不支持。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| INVALID_RSN_IE_CAP | 22 | 22 | 无效的 RSNE 性能。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| 802_1X_AUTH_FAILED | 23 | 23 | IEEE 802.1X. authentication 失败。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - IEEE 802.1X. authentication 失败。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| CIPHER_SUITE_REJECTED | 24 | 24 | 因安全策略,安全密钥算法套件 (cipher suite) 被拒。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| BEACON_TIMEOUT | 200 | reserved | 乐鑫特有的 Wi-Fi 原因代码: 当 station 连续失去 N 个 beacon, | -| | | | 将中断连接并报告该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| NO_AP_FOUND | 201 | reserved | 乐鑫特有的 Wi-Fi 原因代码: 当 station 未扫描到目标 AP 时, | -| | | | 将报告该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AUTH_FAIL | 202 | reserved | 乐鑫特有的 Wi-Fi 原因代码: authentication 失败, | -| | | | 但并非由超时而引发。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_FAIL | 203 | reserved | 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 | -| | | | ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| HANDSHAKE_TIMEOUT | 204 | reserved | 乐鑫特有的 Wi-Fi 原因代码: 握手失败,与 | -| | | | WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT 中失败原因相同。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| CONNECTION_FAIL | 205 | reserved | 乐鑫特有的 Wi-Fi 原因代码: AP 连接失败。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ + - 从 AP 接收到该代码。 + 对于 ESP AP,出现以下情况时将报告该代码: + - AP 从未关联 station 接收到数据包。 + * - ASSOC_LEAVE + - 8 + - 8 + - association 取消,因为发送 station 正在离开(或已经离开)BSS。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + - 由于调用 :cpp:func:`esp_wifi_disconnect()` 和其它 API,station 断开连接。 + * - ASSOC_NOT_AUTHED + - 9 + - 9 + - station 的 re(association) 请求未被响应 station 认证。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 从一个已关联,但未认证的 station 接收到数据包。 + * - DISASSOC_PWRCAP_BAD + - 10 + - 10 + - association 取消,因为无法接收功率能力 (Power Capability) 元素中的信息。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - DISASSOC_SUPCHAN_BAD + - 11 + - 11 + - association 取消,因为无法接收支持的信道 (Supported Channels) 元素中的信息。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - IE_INVALID + - 13 + - 13 + - 无效元素,即内容不符合 Wi-Fi 协议中帧格式 (Frame formats) 章节所描述标准的元素。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 解析了一个错误的 WPA 或 RSN IE。 + * - MIC_FAILURE + - 14 + - 14 + - 消息完整性代码 (MIC) 出错。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - 4WAY_HANDSHAKE_TIMEOUT + - 15 + - 15 + - 四次握手超时。由于某些历史原因,在 ESP 中该原因代码实为 WIFI_REASON_HANDSHAKE_TIMEOUT。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 握手超时。 + - 从 AP 接收到该代码。 + * - GROUP_KEY_UPDATE_TIMEOUT + - 16 + - 16 + - 组密钥 (Group-Key) 握手超时。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - IE_IN_4WAY_DIFFERS + - 17 + - 17 + - 四次握手中产生的元素与 (re-)association 后的 request/probe 以及 response/beacon frame 中的信息不同。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + - station 发现四次握手的 IE 与 (re-)association 后的 request/probe 以及 response/beacon frame 中的 IE 不同。 + * - GROUP_CIPHER_INVALID + - 18 + - 18 + - 无效组密文。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - PAIRWISE_CIPHER_INVALID + - 19 + - 19 + - 无效成对密文。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - AKMP_INVALID + - 20 + - 20 + - 无效 AKMP。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - UNSUPP_RSN_IE_VERSION + - 21 + - 21 + - 不支持的 RSNE 版本。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - INVALID_RSN_IE_CAP + - 22 + - 22 + - 无效的 RSNE 性能。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - 802_1X_AUTH_FAILED + - 23 + - 23 + - IEEE 802.1X. authentication 失败。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - IEEE 802.1X. authentication 失败。 + * - CIPHER_SUITE_REJECTED + - 24 + - 24 + - 因安全策略,安全密钥算法套件 (cipher suite) 被拒。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - BEACON_TIMEOUT + - 200 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: 当 station 连续失去 N 个 beacon,将中断连接并报告该代码。 + * - NO_AP_FOUND + - 201 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: 当 station 未扫描到目标 AP 时,将报告该代码。 + * - AUTH_FAIL + - 202 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: authentication 失败,但并非由超时而引发。 + * - ASSOC_FAIL + - 203 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。 + * - HANDSHAKE_TIMEOUT + - 204 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: 握手失败,与 WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT 中失败原因相同。 + * - CONNECTION_FAIL + - 205 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: AP 连接失败。 找到多个 AP 时的 {IDF_TARGET_NAME} Wi-Fi station 连接 ---------------------------------------------------------------------- @@ -978,7 +1021,6 @@ Wi-Fi beacon 超时 beacon 超时发生后,station 将向 AP 发送 5 个 probe request,如果仍未从 AP 接收到 probe response 或 beacon,station 将与 AP 断开连接并产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件。 - {IDF_TARGET_NAME} Wi-Fi 配置 ------------------------------------- @@ -988,72 +1030,56 @@ Wi-Fi 模式 +++++++++++++++++++++++++ 调用函数 :cpp:func:`esp_wifi_set_mode()` 设置 Wi-Fi 模式。 -+-----------------+------------------------------------------------------------------------------+ -| 模式 | 描述 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_NULL | NULL 模式:此模式下,内部数据结构不分配给 station 和 AP,同时,station 和 AP | -| | 接口不会为发送/接收 Wi-Fi 数据进行初始化。通常,此模式用于 | -| | Sniffer,或者您不想通过调用函数 :cpp:func:`esp_wifi_deinit()` 卸载整个 | -| | Wi-Fi 驱动程序来同时停止 station 和 AP。 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_STA | Station 模式:此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 | -| | station 数据,同时 station 接口准备发送/接收 Wi-Fi 数据。调用函数 | -| | :cpp:func:`esp_wifi_connect()` 后,station 将连接到目标 AP。 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_AP | AP 模式:在此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 AP | -| | 数据,同时 AP 接口准备发送/接收 Wi-Fi 数据。随后,Wi-Fi | -| | 驱动程序开始广播 beacon,AP 即可与其它 station 连接。 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_APSTA | Station/AP 共存模式:在此模式下,函数 :cpp:func:`esp_wifi_start()` | -| | 将同时初始化 station 和 AP。该步骤在 Station 模式和 AP | -| | 模式下完成。请注意 ESP Station 所连外部 AP 的信道优先于 ESP AP 信道。 | -+-----------------+------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - 模式 + - 描述 + * - WIFI_MODE_NULL + - NULL 模式:此模式下,内部数据结构不分配给 station 和 AP,同时,station 和 AP 接口不会为发送/接收 Wi-Fi 数据进行初始化。通常,此模式用于 Sniffer,或者您不想通过调用函数 :cpp:func:`esp_wifi_deinit()` 卸载整个 Wi-Fi 驱动程序来同时停止 station 和 AP。 + * - WIFI_MODE_STA + - station 模式:此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 station 数据,同时 station 接口准备发送/接收 Wi-Fi 数据。调用函数 :cpp:func:`esp_wifi_connect()` 后,station 将连接到目标 AP。 + * - WIFI_MODE_AP + - AP 模式:在此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 AP 数据,同时 AP 接口准备发送/接收 Wi-Fi 数据。随后,Wi-Fi 驱动程序开始广播 beacon,AP 即可与其它 station 连接。 + * - WIFI_MODE_APSTA + - station/AP 共存模式:在此模式下,函数 :cpp:func:`esp_wifi_start()` 将同时初始化 station 和 AP。该步骤在 station 模式和 AP 模式下完成。请注意 ESP station 所连外部 AP 的信道优先于 ESP AP 信道。 Station 基本配置 +++++++++++++++++++++++++++++++++++++ API esp_wifi_set_config() 可用于配置 station。下表详细介绍了各个字段。 - -+-------------+---------------------------------------------------------------------------+ -| 字段 | 描述 | -+=============+===========================================================================+ -| ssid | station 想要连接的目标 AP 的 SSID。 | -+-------------+---------------------------------------------------------------------------+ -| password | 目标 AP 的密码。 | -+-------------+---------------------------------------------------------------------------+ -| scan_method | WIFI_FAST_SCAN 模式下,扫描到一个匹配的 AP 时即结束。WIFI_ALL_CHANNEL_SCA | -| | 模式下,在所有信道扫描所有匹配的 AP。默认扫描模式是 WIFI_FAST_SCAN。 | -+-------------+---------------------------------------------------------------------------+ -| bssid_set | 如果 bssid_set 为 0,station 连接 SSID 与 "ssid" 字段相同的 | -| | AP,同时忽略字段 "bssid"。其他情况下,station 连接 SSID | -| | 与 "ssid" 字段相同、BSSID 与 "bssid" 字段也相同的 AP。 | -+-------------+---------------------------------------------------------------------------+ -| bssid | 只有当 bssid_set 为 1 时有效。见字段 "bssid_set"。 | -+-------------+---------------------------------------------------------------------------+ -| channel | 该字段为 0 时,station 扫描信道 1~N 寻找目标 AP;否则,station | -| | 首先扫描值与 "channel" 字段相同的信道,再扫描其他信道。如果您不知道目标 | -| | AP 在哪个信道,请将该字段设置为 0。 | -+-------------+---------------------------------------------------------------------------+ -| sort_method | 该字段仅用于 WIFI_ALL_CHANNEL_SCAN 模式。如果设置为 | -| | WIFI_CONNECT_AP_BY_SIGNAL,所有匹配的 AP | -| | 将会按照信号强度排序,信号最好的 AP 会被首先连接。比如,如果 | -| | station 想要连接 ssid 为 "apxx" 的 AP,且扫描到两个这样的 | -| | AP。第一个 AP 的信号为 -90 dBm,第二个 AP 的信号为 -30 dBm,station | -| | 首先连接第二个 AP。除非失败,才会连接第一个。如果设置为 | -| | WIFI_CONNECT_AP_BY_SECURITY,所有匹配的 AP 将会按照安全性排序。比如,如果 | -| | station 想要连接 ssid 为 "apxx"的 AP,并且扫描到两个这样的 AP。第一个 | -| | AP 为开放式,第二个 AP 为 WPA2 加密,station 首先连接第二个 | -| | AP。除非失败,才会连接第一个。 | -+-------------+---------------------------------------------------------------------------+ -| threshold | 该字段用来筛选找到的 AP,如果 AP 的 RSSI | -| | 或安全模式小于配置的阈值,则不会被连接。如果 RSSI | -| | 设置为 0,则取 RSSI 的默认阈值 -127 dBm。如果 | -| | authmode 设置为 0,则取 authmode 默认阈值无授权。 | -+-------------+---------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 45 + + * - 字段 + - 描述 + * - ssid + - station 想要连接的目标 AP 的 SSID。 + * - password + - 目标 AP 的密码。 + * - scan_method + - WIFI_FAST_SCAN 模式下,扫描到一个匹配的 AP 时即结束。WIFI_ALL_CHANNEL_SCAN 模式下,在所有信道扫描所有匹配的 AP。默认扫描模式是 WIFI_FAST_SCAN。 + * - bssid_set + - 如果 bssid_set 为 0,station 连接 SSID 与 “ssid” 字段相同的 AP,同时忽略字段 “bssid”。其他情况下,station 连接 SSID 与 “ssid” 字段相同、BSSID 与 “bssid” 字段也相同的 AP。 + * - bssid + - 只有当 bssid_set 为 1 时有效。见字段 “bssid_set”。 + * - channel + - 该字段为 0 时,station 扫描信道 1 ~ N 寻找目标 AP;否则,station 首先扫描值与 “channel” 字段相同的信道,再扫描其他信道。如果您不知道目标 AP 在哪个信道,请将该字段设置为 0。 + * - sort_method + - 该字段仅用于 WIFI_ALL_CHANNEL_SCAN 模式。 + + 如果设置为 WIFI_CONNECT_AP_BY_SIGNAL,所有匹配的 AP 将会按照信号强度排序,信号最好的 AP 会被首先连接。比如,如果 station 想要连接 ssid 为 “apxx” 的 AP,且扫描到两个这样的 AP。第一个 AP 的信号为 -90 dBm,第二个 AP 的信号为 -30 dBm,station 首先连接第二个 AP。除非失败,才会连接第一个。 + + 如果设置为 WIFI_CONNECT_AP_BY_SECURITY,所有匹配的 AP 将会按照安全性排序。比如,如果 station 想要连接 ssid 为 “apxx” 的 AP,并且扫描到两个这样的 AP。第一个 AP 为开放式,第二个 AP 为 WPA2 加密,station 首先连接第二个 AP。除非失败,才会连接第一个。 + * - threshold + - 该字段用来筛选找到的 AP,如果 AP 的 RSSI 或安全模式小于配置的阈值,则不会被连接。 + + 如果 RSSI 设置为 0,则表示默认阈值、默认 RSSI 阈值为 -127 dBm。如果 authmode 阈值设置为 0,则表示默认阈值,默认 authmode 阈值无授权。 .. attention:: - WEP/WPA 安全模式在 IEEE802.11-2016 协议中已弃用,建议不要使用。可使用 authmode 阈值代替,通过将 threshold.authmode 设置为 WIFI_AUTH_WPA2_PSK 使用 WPA2 模式 AP 基本配置 @@ -1061,60 +1087,52 @@ AP 基本配置 API esp_wifi_set_config() 可用于配置 AP。下表详细介绍了各个字段。 -+-----------------+----------------------------------------------------------------------------------+ -| 字段 | 描述 | -+-----------------+----------------------------------------------------------------------------------+ -| ssid | 指 AP的 SSID。如果 ssid[0] 和 ssid[1] 均为 0xFF,AP | -| | 默认 SSID 为 ESP_aabbcc,"aabbcc" 是 AP MAC 的最后三个字节。 | -+-----------------+----------------------------------------------------------------------------------+ -| password | AP 的密码。如果身份验证模式为 WIFI_AUTH_OPEN,此字段将被忽略。 | -+-----------------+----------------------------------------------------------------------------------+ -| ssid_len | SSID 的长度。如果 ssid_len 为 0,则检查 SSID 直至出现终止字符。如果 | -| | ssid_len 大于 32,请更改为 32,或者根据 ssid_len 设置 SSID 长度。 | -+-----------------+----------------------------------------------------------------------------------+ -| channel | AP 的信道。如果信道超出范围,Wi-Fi 驱动程序将默认该信道为信道 | -| | 1。所以,请确保信道在要求的范围内。有关详细信息,请参阅 `Wi-Fi 国家/地区代码`_。 | -+-----------------+----------------------------------------------------------------------------------+ -| authmode | ESP AP 的身份验证模式。目前,ESP Wi-Fi 不支持 | -| | AUTH_WEP。如果 authmode 是一个无效值,AP | -| | 默认该值为 WIFI_AUTH_OPEN。 | -+-----------------+----------------------------------------------------------------------------------+ -| ssid_hidden | 如果 ssid_hidden 为 1,AP 不广播 SSID。若为其他值,则广播。 | -+-----------------+----------------------------------------------------------------------------------+ -| max_connection | 目前,ESP Wi-Fi 支持 10 个 Wi-Fi 连接。如果 | -| | max_connection 大于 10,AP 默认该值为 10。 | -+-----------------+----------------------------------------------------------------------------------+ -| beacon_interval | beacon 间隔。值为 100 ~ 60000 ms,默认值为 100 | -| | ms。如果该值不在上述范围,AP 默认取 100 ms。 | -+-----------------+----------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - 字段 + - 描述 + * - ssid + - 指 AP 的 SSID。如果 ssid[0] 和 ssid[1] 均为 0xFF,AP 默认 SSID 为 ESP_aabbcc,”aabbcc” 是 AP MAC 的最后三个字节。 + * - password + - AP 的密码。如果身份验证模式为 WIFI_AUTH_OPEN,此字段将被忽略。 + * - ssid_len + - SSID 的长度。如果 ssid_len 为 0,则检查 SSID 直至出现终止字符。如果 ssid_len 大于 32,请更改为 32,或者根据 ssid_len 设置 SSID 长度。 + * - channel + - AP 的信道。如果信道超出范围,Wi-Fi 驱动程序将默认该信道为信道 1。所以,请确保信道在要求的范围内。有关详细信息,请参阅 `Wi-Fi 国家/地区代码`_。 + * - authmode + - ESP AP 的身份验证模式。目前,ESP Wi-Fi 不支持 AUTH_WEP。如果 authmode 是一个无效值,AP 默认该值为 WIFI_AUTH_OPEN。 + * - ssid_hidden + - 如果 ssid_hidden 为 1,AP 不广播 SSID。若为其他值,则广播。 + * - max_connection + - 目前,ESP Wi-Fi 支持 10 个 Wi-Fi 连接。如果 max_connection 大于 10,AP 默认该值为 10。 + * - beacon_interval + - beacon 间隔。值为 100 ~ 60000 ms,默认值为 100 ms。如果该值不在上述范围,AP 默认取 100 ms。 Wi-Fi 协议模式 +++++++++++++++++++++++++ 目前,IDF 支持以下协议模式: -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 协议模式 | 描述 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11b | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_11B),将 | -| | station/AP 设置为仅 802.11b 模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11bg | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G),将 station/AP 设置为 | -| | 802.11bg 模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11bgn | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N),将 | -| | station/AP 设置为 802.11bgn 模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11 BGNLR | 调用函数 :cpp:func:`esp_wifi_set_protocol` | -| | (ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR),将 station/AP 设置为 802.11bgn | -| | 和乐鑫专属模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11 LR | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_LR),将 | -| | station/AP 设置为仅乐鑫专属模式。 | -| | | -| | **此模式是乐鑫的专利模式,可以达到 1 公里视线范围。请确保 | -| | station 和 AP 同时连接至 ESP 设备。** | -+--------------+------------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - 协议模式 + - 描述 + * - 802.11b + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B),将 station/AP 设置为仅 802.11b 模式。 + * - 802.11bg + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G),将 station/AP 设置为 802.11bg 模式。 + * - 802.11bgn + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N),将 station/AP 设置为 802.11bgn 模式。 + * - 802.11 BGNLR + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR),将 station/AP 设置为 802.11bgn 和乐鑫专属模式。 + * - 802.11 LR + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_LR),将 station/AP 设置为仅乐鑫专属模式。 + + **此模式是乐鑫的专利模式,可以达到 1 公里视线范围。请确保 station 和 AP 同时连接至 ESP 设备。** 远程 (LR) +++++++++++++++++++++++++ @@ -1190,66 +1208,69 @@ Wi-Fi 国家/地区代码 调用 :cpp:func:`esp_wifi_set_country()`,设置国家/地区信息。下表详细介绍了各个字段,请在配置这些字段之前参考当地的 2.4GHz RF 操作规定。 -+--------+----------------------------------------------------------------------------------------------------------------+ -| 字段 | 描述 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| cc[3] | 国家/地区代码字符串,此属性标识 station/AP | -| | 位于的国家/地区或非国家/地区实体。如果是一个国家/地区,该字符串的前两个八位字节是 | -| | ISO/IEC3166-1 中规定的国家/地区两位字母代码。第三个八位字节应是下述之一: | -| | | -| | -ASCII 码空格字符,代表 station/AP 所处国家/地区的规定允许当前频段所需的所有环境。 | -| | | -| | -ASCII 码 'O' 字符,代表 station/AP 所处国家/地区的规定仅允许室外环境。 | -| | | -| | -ASCII 码 'I' 字符,代表 station/AP 所处国家/地区的规定仅允许室内环境。 | -| | | -| | -ASCII 码 'X' 字符,代表 station/AP 位于非国家/地区实体。非国家实体的前两个八位字节是两个ASCII 码 'XX' 字符。 | -| | | -| | -当前使用的操作类表编号的二进制形式。见 IEEE Std 802.11-2012 附件 E。 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| schan | 起始信道,station/AP 所处国家/地区规定的最小信道数。 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| nchan | 规定的总信道数,比如,如果 schan=1,nchan=13,那么 station/AP 可以从信道 1 至 13 发送数据。 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| policy | 国家/地区政策,当配置的国家/地区信息与所连 AP | -| | 的国家/地区信息冲突时,该字段决定使用哪一信息。更多政策相关信息,可参见下文。 | -+--------+----------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - 字段 + - 描述 + * - cc[3] + - 国家/地区代码字符串,此属性标识 station/AP 位于的国家/地区或非国家/地区实体。如果是一个国家/地区,该字符串的前两个八位字节是 ISO/IEC3166-1 中规定的国家/地区两位字母代码。第三个八位字节应是下述之一: + + - ASCII 码空格字符,代表 station/AP 所处国家/地区的规定允许当前频段所需的所有环境。 + - ASCII 码 ‘O’ 字符,代表 station/AP 所处国家/地区的规定仅允许室外环境。 + - ASCII 码 ‘I’ 字符,代表 station/AP 所处国家/地区的规定仅允许室内环境。 + - ASCII 码 ‘X’ 字符,代表 station/AP 位于非国家/地区实体。非国家实体的前两个八位字节是两个 ASCII 码 ‘XX’ 字符。 + - 当前使用的操作类表编号的二进制形式。见 IEEE Std 802.11-2012 附件 E。 + + * - schan + - 起始信道,station/AP 所处国家/地区规定的最小信道数。 + * - nchan + - 规定的总信道数,比如,如果 schan=1,nchan=13,那么 station/AP 可以从信道 1 至 13 发送数据。 + * - policy + - 国家/地区政策,当配置的国家/地区信息与所连 AP 的国家/地区信息冲突时,该字段决定使用哪一信息。更多政策相关信息,可参见下文。 默认国家/地区信息为 {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO},如果 Wi-Fi 模式为 AP-STA 共存模式,则它们配置的国家/地区信息相同。有时,station 所连 AP 的国家/地区信息与配置的不同。例如,配置的 station 国家/地区信息为 {.cc="JP", .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO},但所连 AP 的国家/地区信息为 {.cc="CN", .schan=1, .nchan=13},此时,使用 AP 的国家/地区信息。 + 下表描述了在不同 Wi-Fi 模式和不同国家/地区政策下使用的国家/地区信息,并描述了对主动扫描的影响。 -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Wi-Fi 模式 | 政策 | 描述 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Station 模式 | WIFI_COUNTRY_POLICY_AUTO | 如果所连 AP 的 beacon 中有国家/地区的 IE,使用的国家/地区信息为 beacon | -| | | 中的信息,否则,使用默认信息。 | -| | | | -| | | 扫描时: | -| | | | -| | | -如果 schan+nchan-1>11, | -| | | 主动扫描起始信道至信道 11,被动扫描信道 12 至 信道 | -| | | schan+nchan-1。 | -| | | | -| | | -如果 schan+nchan-1<=11, | -| | | 主动扫描起始信道至信道 schan+nchan-1。 | -| | | | -| | | 请记住,如果 AP 带有隐藏 SSID | -| | | 且被设置为被动扫描信道,被动扫描将无法找到该 | -| | | AP。也就是说,如果应用程序希望在每个信道中找到带有隐藏 | -| | | SSID 的 AP,国家/地区信息应该配置为 | -| | | WIFI_COUNTRY_POLICY_MANUAL。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Station 模式 | WIFI_COUNTRY_POLICY_MANUAL | 总是使用配置的国家/地区信息。 扫描时,主动扫描起始信道至信道 schan+nchan-1。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| AP 模式 | WIFI_COUNTRY_POLICY_AUTO | 总是使用配置的国家/地区信息。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| AP 模式 | WIFI_COUNTRY_POLICY_MANUAL | 总是使用配置的国家/地区信息。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Station/AP 共存模式 | WIFI_COUNTRY_POLICY_AUTO | 如果 station 不连接任何 AP,AP 使用配置的国家/地区信息。如果 station | -| | | 连接一个 AP,该 AP 的国家/地区信息与该 station 相同。与 | -| | | Station 模式、WIFI_COUNTRY_POLICY_AUTO 政策下使用的国家/地区信息相同。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 15 35 + + * - Wi-Fi 模式 + - 政策 + - 描述 + * - station 模式 + - WIFI_COUNTRY_POLICY_AUTO + - 如果所连 AP 的 beacon 中有国家/地区的 IE,使用的国家/地区信息为 beacon 中的信息,否则,使用默认信息。 + + 扫描时: + + - 如果 schan+nchan-1>11: + + 主动扫描起始信道至信道 11,被动扫描信道 12 至 信道 schan+nchan-1。 + + - 如果 schan+nchan-1<=11: + 主动扫描起始信道至信道 schan+nchan-1。 + + 请记住,如果 AP 带有隐藏 SSID 且 station 被设置为被动扫描信道,被动扫描将无法找到该 AP。也就是说,如果应用程序希望在每个信道中找到带有隐藏 SSID 的 AP,国家/地区信息应该配置为 WIFI_COUNTRY_POLICY_MANUAL。 + + * - station 模式 + - WIFI_COUNTRY_POLICY_MANUAL + - 总是使用配置的国家/地区信息。 扫描时,主动扫描起始信道至信道 schan+nchan-1。 + * - AP 模式 + - WIFI_COUNTRY_POLICY_AUTO + - 总是使用配置的国家/地区信息。 + * - AP 模式 + - WIFI_COUNTRY_POLICY_MANUAL + - 总是使用配置的国家/地区信息。 + * - station/AP 共存模式 + - WIFI_COUNTRY_POLICY_AUTO + - 如果 station 不连接任何外部 AP,AP 使用配置的国家/地区信息。如果 station 连接一个外部 AP,该 AP 的国家/地区信息与该 station 相同。 + + 与 station 模式、WIFI_COUNTRY_POLICY_AUTO 政策下使用的国家/地区信息相同。 主信道 ************************* @@ -1262,40 +1283,70 @@ Wi-Fi 供应商 IE 配置 默认情况下,所有 Wi-Fi 管理帧都由 Wi-Fi 驱动程序处理,应用程序不需要任何操作。但是,某些应用程序可能需要处理 beacon、probe request、probe response 和其他管理帧。例如,如果在管理帧中插入一些只针对供应商的 IE,则只有包含此 IE 的管理帧才能得到处理。{IDF_TARGET_NAME} 中,:cpp:func:`esp_wifi_set_vendor_ie()` 和 :cpp:func:`esp_wifi_set_vendor_ie_cb()` 负责此类任务。 -Wi-Fi 安全性 -------------------------------- -除了传统的安全保障方法 (WEP/WPA-TKIP/WPA2-CCMP),{IDF_TARGET_NAME} Wi-Fi 如今还支持最先进的安全协议,即基于 802.11w 标准的“受保护的管理帧” (PMF) 和 Wi-Fi Protected Access 3 (WPA3-Personal) 技术。PMF 与 WPA3 一道,提供更好的隐私性,也能更强地抵御传统模式下的已知攻击。 +Wi-Fi Easy Connect™ (DPP) +-------------------------- -受保护的管理帧 (PMF) -++++++++++++++++++++++++++++++++++ +Wi-Fi Easy Connect\ :sup:`TM`(也称为设备配置协议)是一个安全且标准化的配置协议,用于配置 Wi-Fi 设备。更多信息请参考 :doc:`esp_dpp <../api-reference/network/esp_dpp>`。 -在 Wi-Fi 中,非 AP station 使用 beacon、探测器、(de)authentication、(dis)association 等管理帧来扫描和连接 AP。与数据帧不同,这些帧发送时未加密。 -攻击者可以使用窃听和数据包注入等方式在恰当的时间发送虚假的 (de)authentication 和 (dis)association 帧,如果未受保护的管理帧发生改变,将出现以下攻击。 +WPA2-Enterprise ++++++++++++++++++++++++++++++++++ - - 在攻击者范围内对一个或所有 client 进行 DOS 攻击。 - - 通过发送关联请求取消 AP 端的现有关联。 - - 如果 PSK 遭到破坏,强制 client 再次执行 4 次握手,以获得 PTK。 - - 从关联请求获取隐藏网络的 SSID。 - - 强制 client 从合法 AP 中 (de)authentication,并关联到流氓 AP,发起中间人攻击。 +WPA2-Enterprise 是企业无线网络的安全认证机制。在连接到接入点 (AP) 之前,它使用 RADIUS 服务器对网络用户进行身份验证。身份验证过程基于 802.1X 标准,并有不同的扩展身份验证协议 (EAP) 方法,如 TLS、TTLS、PEAP 等。RADIUS 服务器根据用户的凭据(用户名和密码)、数字证书或两者对用户进行身份验证。当处于 station 模式的 {IDF_TARGET_NAME} 尝试连接到企业模式的 AP 时,它会向 AP 发送身份验证请求,AP 会将该请求发送到 RADIUS 服务器以对 station 进行身份验证。根据不同的 EAP 方式,可以通过 ``idf.py menuconfig`` 打开配置,并在配置中设置参数。{IDF_TARGET_NAME} 仅在 station 模式下支持 WPA2_Enterprise。 -PMF 通过对单播管理帧进行加密,并检查广播管理帧的完整性,阻止上述攻击。其中包括 (de)authentication、(dis)association 和强奸的管理帧。PMF 同样提供“安全关联” (SA) 拆解机制,阻止欺骗 association/authentication frame 断开已连接的 client。 +为了建立安全连接,AP 和 station 协商并就要使用的最佳密码套件达成一致。{IDF_TARGET_NAME} 支持 AKM 的 802.1X/EAP (WPA) 方法和 AES-CCM(高级加密标准-带密码块链消息验证码协议的计数器模式)支持的密码套件。如果设置了 `USE_MBEDTLS_CRYPTO` 标志,{IDF_TARGET_NAME} 也支持 mbedtls 支持的密码套件。 -关于PMF,{IDF_TARGET_NAME} 支持以下三种操作模式。 +目前,{IDF_TARGET_NAME} 支持以下 EAP 方法: + - EAP-TLS: 这是基于证书的方法,只需要 SSID 和 EAP-IDF。 + - PEAP: - PEAP:这是受保护的 EAP 方法。用户名和密码是必填项。 + - EAP-TTLS: 这是基于凭据的方法。只有服务器身份验证是强制性的,而用户身份验证是可选的。用户名和密码是必填项。 它支持不同的 Phase2 方法,例如: + - PAP: 密码认证协议 + - CHAP: 询问握手身份验证协议 + - MSCHAP 和 MSCHAP-V2 + - EAP-FAST: 这是一种基于受保护的访问凭据 (PAC) 的认证方法,使用身份验证和密码。目前使用此功能时需要禁用 USE_MBEDTLS_CRYPTO 标志。 - - 不支持 PMF:此模式下,{IDF_TARGET_NAME} 向 AP 表示在关联过程中不能支持管理保护。实际上,此模式下的安全性与传统模式相同。 - - 支持但未要求使用 PMF:此模式下,{IDF_TARGET_NAME} 向AP表示能够支持 PMF。如果 AP 授权 PMF 或至少能支持 PMF,将使用管理保护。 - - 支持且需要 PMF:此模式下,如果 AP 支持 PMF,{IDF_TARGET_NAME} 将仅连接该 AP。如果不支持,{IDF_TARGET_NAME} 将拒绝连接该 AP。 +请查看 :example:`wifi/wpa2_enterprise` 获取关于证书创建以及如何在 {IDF_TARGET_NAME} 上运行 wpa2_enterprise 示例的详细信息。 -通过在 `pmf_cfg` 参数中设置适当标志,:cpp:func:`esp_wifi_set_config` 可以用来配置 PMF 模式。目前,仅 station 模式支持 PMF。 +无线网络管理 +---------------------------- +无线网络管理让客户端设备能够交换有关网络拓扑结构的信息,包括与射频环境相关的信息。这使每个客户端都能感知网络状况,从而促进无线网络性能的整体改进。这是 802.11v 规范的一部分。它还使客户端能够支持网络辅助漫游。 -WPA3-Personal -+++++++++++++++++++++++++++++++++ +网络辅助漫游让 WLAN 能够向关联的客户端发送消息,从而使客户端与具有更好链路指标的 AP 关联。这对于促进负载平衡以及引导连接不良的客户端都很有用。 + +目前 802.11v 的实现支持 BSS 过渡管理帧。 + +无线资源管理 +--------------------------- + +无线电资源测量(802.11k)旨在改善网络内流量的分配方式。在无线局域网中,一般情况下,无线设备会连接发射信号最强的 AP。根据用户的数量和地理位置,这种分配方式有时会导致某个 AP 超负荷而其它 AP 利用不足,从而导致整体网络性能下降。在符合 802.11k 规范的网络中,如果信号最强的 AP 已满负荷加载,无线设备则转移到其它未充分利用的 AP。尽管信号可能较弱,但由于更有效地利用了网络资源,总体吞吐量会更大。 + +目前 802.11k 的实现支持信标测量报告、链路测量报告和邻居请求。 + +请参考 IDF 示例程序 :idf_file:`examples/wifi/roaming/README.md` 来设置和使用这些 API。示例代码只演示了如何使用这些 API,应用程序应根据需要定义自己的算法和案例。 + +.. only:: esp32s2 or esp32c3 + + Wi-Fi Location + ------------------------------- + + Wi-Fi Location 将提高 AP 以外设备位置数据的准确性,这有助于创建新的、功能丰富的应用程序和服务,例如地理围栏、网络管理、导航等。用于确定设备相对于 AP 的位置的协议之一是精细定时测量 (FTM),它会计算 Wi-Fi 帧的飞行时间。 + + 精细定时测量 (FTM) + +++++++++++++++++++++++++++++ + + FTM 用于测量 Wi-Fi 往返时间(Wi-Fi RTT),即 Wi-Fi 信号从一个设备到另一个设备并返回所需的时间。使用 Wi-Fi RTT,设备之间的距离可以用一个简单的公式 `RTT * c / 2` 来计算,其中 c 是光速。 + + 对于设备之间交换的帧,FTM 在帧到达或离开时使用时间戳,这个时间戳由 Wi-Fi 接口硬件提供。FTM 发起方(主要是 station 设备)发现 FTM 响应方(可以是 station 或 AP),并协商启动 FTM 程序。该程序以突发形式发送的多个动作帧及其 ACK 来收集时间戳数据。FTM 发起方最后收集数据以计算平均往返时间。 + + {IDF_TARGET_NAME} 在以下配置中支持 FTM: -Wi-Fi Protected Access-3 (WPA3) 是一套增强 Wi-Fi 接入安全性的措施,旨在取代目前的 WPA2 标准。为了提供更强健的认证方式,WPA3 采用了等值同时认证 (SAE) 算法,即基于 Diffie-Hellman 密钥交换的密码认证密钥协议方法。与 WPA2 不同,该技术可以抵御离线字典攻击,即攻击者试图在没有任何进一步网络交互的情况下,根据捕获的 4 次握手来确定共享密码。WPA3 还提供前向保密功能,即数据传输后,即使密码泄露,也无法对捕获的数据进行解密。更多详细信息,请见 Wi-Fi 联盟官方网站 `Security `_ 一章。 + - {IDF_TARGET_NAME} 在 station 模式下为 FTM 发起方。 + - {IDF_TARGET_NAME} 在 AP 模式下为 FTM 响应方。 -要使能 WPA3-Personal,请在 menuconfig 中选择 "Enable WPA3-Personal"。使能后,如果 AP 支持,{IDF_TARGET_NAME} 会使用 SAE 进行身份认证。由于 WPA3 强制要求 PMF,{IDF_TARGET_NAME} 要使用 WPA3 模式,至少应该将 PMF 模式设置为 "PMF capable, but not required"(支持但未要求使用 PMF)。应用程序的安全模式已经选用最高级别,因此开发者无需担心。请注意,使用 WPA3 时,Wi-Fi 协议栈大小要求将增加约 3 k。目前,仅 Station 模式支持 WPA3。 + 使用 RTT 的距离测量并不准确,RF 干扰、多径传播、天线方向和缺乏校准等因素会增加这些不准确度。为了获得更好的结果,建议在两个 {IDF_TARGET_NAME} 设备之间执行 FTM,这两个设备可分别设置为 station 和 AP 模式。 + + 请参考 IDF 示例 :idf_file:`examples/wifi/ftm/README.md` 了解设置和执行 FTM 的详细步骤。 {IDF_TARGET_NAME} Wi-Fi 节能模式 ----------------------------------------- @@ -1329,69 +1380,139 @@ AP 睡眠 .. only:: esp32 - +----------------------------+----------------+------------+---------------+----------------------+ - | 类型/吞吐量 | 实验室空气状况 | 屏蔽箱 | 测试工具 | IDF 版本 (commit ID) | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包接收数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包发送数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 接收数据 | 30 MBit/s | 85 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 发送数据 | 30 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 接收数据 | 20 MBit/s | 65 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 发送数据 | 20 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - - 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32`。 + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 85 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 75 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 65 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 75 MBit/s + - iperf example + - 15575346 + + 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32s2`。 .. only:: esp32s2 - +----------------------------+----------------+------------+---------------+----------------------+ - | 类型/吞吐量 | 实验室空气状况 | 屏蔽箱 | 测试工具 | IDF 版本 (commit ID) | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包接收数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包发送数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 接收数据 | 30 MBit/s | 70 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 发送数据 | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 接收数据 | 20 MBit/s | 32 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 发送数据 | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 70 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 32 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32s2`。 .. only:: esp32c3 - +----------------------------+----------------+------------+---------------+----------------------+ - | 类型/吞吐量 | 实验室空气状况 | 屏蔽箱 | 测试工具 | IDF 版本 (commit ID) | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包接收数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包发送数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 接收数据 | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 发送数据 | 30 MBit/s | 40 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 接收数据 | 20 MBit/s | 35 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 发送数据 | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 40 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 35 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32c3`。 Wi-Fi 80211 数据包发送 --------------------------- -**重要说明:API esp_wifi_80211_tx 在 IDF 2.1 中不可用,即将发布的版本将可以使用。** - :cpp:func:`esp_wifi_80211_tx` API 可用于: - 发送 beacon、probe request、probe response 和 action 帧。 @@ -1417,67 +1538,46 @@ Wi-Fi 80211 数据包发送 理论上,如果不考虑 API 对 Wi-Fi 驱动程序或其他 station 或 AP 的副作用,可以通过空中发送一个原始的 802.11 数据包,包括任何目的地址的 MAC、任何源地址的 MAC、任何 BSSID、或任何其他类型的数据包。但是,一个具有强健、有用的应用程序应该避免这种副作用。下表针对如何避免 :cpp:func:`esp_wifi_80211_tx` 的副作用提供了一些提示或建议。 -+---------------+--------------------------------------------------------------------------------------------+ -| 场景 | 描述 | -+---------------+--------------------------------------------------------------------------------------------+ -| 无 Wi-Fi 连接 | 在这种情况下,因为没有 Wi-Fi 连接,Wi-Fi 驱动程序不会受到副作用影响。如果 | -| | en_sys_seq==true,则 Wi-Fi 驱动程序负责序列控制。如果 | -| | en_sys_seq==false,应用程序需要确保缓冲区的序列正确。 | -| | | -| | 理论上,MAC 地址可以是任何地址。但是,这样可能会影响其他使用相同 MAC/BSSID 的 station/AP。 | -| | | -| | 例如,AP 模式下,应用程序调用函数 | -| | :cpp:func:`esp_wifi_80211_tx` 发送带有 BSSID == mac_x 的 beacon,但是 mac_x | -| | 并非 AP 接口的 MAC。而且,还有 另一个 AP(我们称之为 "other-AP")的 bssid 是 | -| | mac_x。因此,连接到 "other-AP" 的 station 无法分辨 beacon 来自 "other-AP" 还是 | -| | :cpp:func:`esp_wifi_80211_tx`,就会出现 “意外行为”。 | -| | | -| | 为了避免上述副作用,我们建议: | -| | | -| | -如果在 Station 模式下调用函数 :cpp:func:`esp_wifi_80211_tx`,第一个 MAC 应该是组播 | -| | | -| | MAC 或是目标设备的 MAC,第二个 MAC 应该是 station 接口的 MAC。 | -| | | -| | -如果在 AP 模式下调用函数 esp_wifi_80211_tx,第一个 MAC 应该是组播 MAC 或是目标设备的 | -| | | -| | MAC, 第二个 MAC 应该是 AP 接口的 MAC。 | -| | | -| | 上述建议仅供避免副作用,在有充分理由的情况下可以忽略。 | -+---------------+--------------------------------------------------------------------------------------------+ -| 有 Wi-Fi 连接 | 当 Wi-Fi 已连接,且序列由应用程序控制,应用程序可能会影响整个 Wi-Fi | -| | 连接的序列控制。 因此,en_sys_seq 要为 true,否则将返回 ESP_ERR_WIFI_ARG。 | -| | | -| | “无 Wi-Fi 连接” 情况下的 MAC 地址建议也适用于此情况。如果 Wi-Fi | -| | 模式是 Station 模式,MAC 的地址 1 是 station 所连 AP 的 MAC,地址 | -| | 2 是 station 接口的 MAC,那么就称数据包是从 station 发送到 AP。另一方面,如果 Wi-Fi | -| | 模式是 AP 模式,且 MAC 地址 1 是该 AP 所连 station 的 MAC,地址 2 是 | -| | AP 接口的 MAC,那么就称数据包是从 AP 发送到 station。为避免与 | -| | Wi-Fi 连接冲突,可采用以下检查方法: | -| | | -| | -如果数据包类型是数据,且是从 station 发送到 AP,IEEE 802.11 | -| | | -| | Frame control 字段中的 ToDS 位应该为 1,FromDS 位为 0,否则,Wi-Fi | -| | | -| | 驱动程序不接受该数据包。 | -| | | -| | -如果数据包类型是数据,且是从 AP 发送到 station,IEEE 802.11 | -| | | -| | Frame control 字段中的 ToDS 位应该为 0,FromDS 位为 1,否则,Wi-Fi | -| | | -| | 驱动程序不接受该数据包。 | -| | | -| | -如果数据包是从 station 发送到 AP,或从 AP 到 station,Power Management、More | -| | | -| | Data 和 Re-Transmission 位应该为 0,否则,Wi-Fi 驱动程序不接受该数据包。 | -| | | -| | 如果任何检查失败,将返回 ESP_ERR_WIFI_ARG。 | -+---------------+--------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 10 55 + + * - 场景 + - 描述 + * - 无 Wi-Fi 连接 + - 在这种情况下,因为没有 Wi-Fi 连接,Wi-Fi 驱动程序不会受到副作用影响。如果 en_sys_seq==true,则 Wi-Fi 驱动程序负责序列控制。如果 en_sys_seq==false,应用程序需要确保缓冲区的序列正确。 + + 理论上,MAC 地址可以是任何地址。但是,这样可能会影响其他使用相同 MAC/BSSID 的 station/AP。 + + 例如,AP 模式下,应用程序调用函数 esp_wifi_80211_tx() 发送带有 BSSID == mac_x 的 beacon,但是 mac_x 并非 AP 接口的 MAC。而且,还有另一个 AP(我们称之为 “other-AP”)的 bssid 是 mac_x。因此,连接到 “other-AP” 的 station 无法分辨 beacon 来自 “other-AP” 还是 esp_wifi_80211_tx(),就会出现 “意外行为”。 + + 为了避免上述副作用,我们建议: + + - 如果在 station 模式下调用函数 esp_wifi_80211_tx(),第一个 MAC 应该是组播 MAC 或是目标设备的 MAC,第二个 MAC 应该是 station 接口的 MAC。 + + - 如果在 AP 模式下调用函数 esp_wifi_80211_tx,第一个 MAC 应该是组播 MAC 或是目标设备的 MAC,第二个 MAC 应该是 AP 接口的 MAC。 + + 上述建议仅供避免副作用,在有充分理由的情况下可以忽略。 + + * - 有 Wi-Fi 连接 + - 当 Wi-Fi 已连接,且序列由应用程序控制,应用程序可能会影响整个 Wi-Fi 连接的序列控制。 因此,en_sys_seq 要为 true,否则将返回 ESP_ERR_WIFI_ARG。 + + “无 Wi-Fi 连接”情况下的 MAC 地址建议也适用于此情况。 + + 如果 Wi-Fi 模式是 station 模式,MAC 的地址 1 是 station 所连 AP 的 MAC,地址 2 是 station 接口的 MAC,那么就称数据包是从 station 发送到 AP。另一方面,如果 Wi-Fi 模式是 AP 模式,且 MAC 地址 1 是该 AP 所连 station 的 MAC,地址 2 是 AP 接口的 MAC,那么就称数据包是从 AP 发送到 station。为避免与 Wi-Fi 连接冲突,可采用以下检查方法: + + - 如果数据包类型是数据,且是从 station 发送到 AP,IEEE 802.11 Frame control 字段中的 ToDS 位应该为 1,FromDS 位为 0,否则,Wi-Fi 驱动程序不接受该数据包。 + + - 如果数据包类型是数据,且是从 AP 发送到 station,IEEE 802.11 Frame control 字段中的 ToDS 位应该为 0,FromDS 位为 1,否则,Wi-Fi 驱动程序不接受该数据包。 + + - 如果数据包是从 station 发送到 AP,或从 AP 到 station,Power Management、More Data 和 Re-Transmission 位应该为 0,否则,Wi-Fi 驱动程序不接受该数据包。 + + 如果任何检查失败,将返回 ESP_ERR_WIFI_ARG。 Wi-Fi Sniffer 模式 --------------------------- -Wi-Fi Sniffer 模式可以通过 :cpp:func:`esp_wifi_set_promiscuous()` 使能。如果使能 Sniffer 模式, **可以** -向应用程序转储以下数据包。 +Wi-Fi Sniffer 模式可以通过 :cpp:func:`esp_wifi_set_promiscuous()` 使能。如果使能 Sniffer 模式, **可以** 向应用程序转储以下数据包。 - 802.11 管理帧 - 802.11 数据帧,包括 MPDU、AMPDU、AMSDU 等 @@ -1523,7 +1623,6 @@ Wi-Fi 多根天线 - 因为发送数据天线基于 WIFI_ANT_MODE_AUTO 类型的接收数据天线选择算法,只有接收数据的天线模式为 WIFI_ANT_MODE_AUTO 时,发送数据天线才能设置为 WIFI_ANT_MODE_AUTO。 - 目前,Bluetooth® 不支持多根天线功能,请不要使用与多根天线有关的 API。 - - 目前不支持 Bluetooth/Bluetooth LE SoftAP 共存模式。 推荐在以下场景中使用多根天线: @@ -1587,10 +1686,9 @@ Wi-Fi 信道状态信息 - 如果 wifi_csi_info_t 的 first_word_invalid 字段为 true,表示由于 {IDF_TARGET_NAME} 的硬件限制,CSI 数据的前四个字节无效。 - 更多信息,如RSSI,射频的噪声底,接收时间和天线 rx_ctrl 领域。 -.. note :: +.. note:: - 对于 STBC 数据包,每个空时流都提供了 CSI,不会出现 CSD(循环移位延迟)。由于附加链上的每一次循环移位为 -200 ns,因为子载波 0 中没有信道频率响应,在 HT-LTF 和 STBC-HT-LTF 中只记录第一空时流的 CSD 角度。CSD[10:0] 是 11 位,范围从 -pi 到 pi。 - - 如果调用 API :cpp:func:`esp_wifi_set_csi_config` 没有使能 LLTF、HT-LTF 或 STBC-HT-LTF,则 CSI 数据的总字节数会比表中的少。例如,如果没有使能 LLTF 和 HT-LTF,而使能 STBC-HT-LTF,当接收到上述条件、HT、40 MHz 或 STBC的数据包时,CSI 数据的总字节数为 244((61+60)*2+2=244,结果对齐为四个字节,最后两个字节无效)。 Wi-Fi 信道状态信息配置 @@ -1808,111 +1906,305 @@ Wi-Fi 使用的堆内存峰值是 Wi-Fi 驱动程序 **理论上消耗的最大 .. only:: esp32 - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | 等级 | Iperf | 发送数据优先 | 高性能 | 接收数据优先 | 默认值 | 节省内存 | 最小 | - +============================+=======+==============+========+==============+========+==========+=======+ - | 可用内存 (KB) | 37.1 | 113.8 | 123.3 | 145.5 | 144.5 | 170.2 | 185.2 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 6 | 6 | 6 | 6 | 6 | 4 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 64 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_RX_BA_WIN | 32 | 8 | 12 | 12 | 10 | 6 | 禁用 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 65 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 65 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 15 | 15 | 15 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 13 | 13 | 13 | 13 | 13 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 74.6 | 50.8 | 46.5 | 39.9 | 44.2 | 33.8 | 25.6 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 63.6 | 35.5 | 42.3 | 48.5 | 40.5 | 30.1 | 27.8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 76.2 | 75.1 | 74.1 | 72.4 | 69.6 | 64.1 | 36.5 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 83.1 | 66.3 | 75.1 | 75.6 | 73.1 | 65.3 | 54.7 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 5 5 10 5 5 10 5 + + * - 等级 + - Iperf + - 发送数据优先 + - 高性能 + - 接收数据优先 + - 默认值 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 37.1 + - 113.8 + - 123.3 + - 145.5 + - 144.5 + - 170.2 + - 185.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 6 + - 6 + - 6 + - 6 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 64 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - WIFI_RX_BA_WIN + - 32 + - 8 + - 12 + - 12 + - 10 + - 6 + - 禁用 + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - TCP_WND_DEFAULT (KB) + - 65 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + * - TCP 发送数据吞吐量 (Mbit/s) + - 74.6 + - 50.8 + - 46.5 + - 39.9 + - 44.2 + - 33.8 + - 25.6 + * - TCP 接收数据吞吐量 (Mbit/s) + - 63.6 + - 35.5 + - 42.3 + - 48.5 + - 40.5 + - 30.1 + - 27.8 + * - UDP 发送数据吞吐量 (Mbit/s) + - 76.2 + - 75.1 + - 74.1 + - 72.4 + - 69.6 + - 64.1 + - 36.5 + * - UDP 接收数据吞吐量 (Mbit/s) + - 83.1 + - 66.3 + - 75.1 + - 75.6 + - 73.1 + - 65.3 + - 54.7 .. only:: esp32s2 - +----------------------------+-------+--------+------+----------+-------+ - | 等级 | Iperf | 高性能 | 默认 | 节省内存 | 最小 | - +============================+=======+========+======+==========+=======+ - | 可用内存 (KB) | 4.1 | 24.2 | 78.4 | 86.5 | 116.4 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 | 6 | 6 | 4 | 3 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_RX_BA_WIN | 12 | 9 | 6 | 4 | 3 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 0 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 0 | 0 | - +----------------------------+-------+--------+------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | 0 | 0 | - +----------------------------+-------+--------+------+----------+-------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 16 | 8 | - +----------------------------+-------+--------+------+----------+-------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 37.6 | 33.1 | 22.5 | 12.2 | 5.5 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 31.5 | 28.1 | 20.1 | 13.1 | 7.2 | - +----------------------------+-------+--------+------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 58.1 | 57.3 | 28.1 | 22.6 | 8.7 | - +----------------------------+-------+--------+------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 78.1 | 66.7 | 65.3 | 53.8 | 28.5 | - +----------------------------+-------+--------+------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 10 10 + + * - 等级 + - Iperf + - 高性能 + - 默认 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 4.1 + - 24.2 + - 78.4 + - 86.5 + - 116.4 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 6 + - 6 + - 4 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_RX_BA_WIN + - 12 + - 9 + - 6 + - 4 + - 3 + * - TCP_SND_BUF_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - TCP_WND_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + - 16 + * - TCP 发送数据吞吐量 (Mbit/s) + - 37.6 + - 33.1 + - 22.5 + - 12.2 + - 5.5 + * - TCP 接收数据吞吐量 (Mbit/s) + - 31.5 + - 28.1 + - 20.1 + - 13.1 + - 7.2 + * - UDP 发送数据吞吐量 (Mbit/s) + - 58.1 + - 57.3 + - 28.1 + - 22.6 + - 8.7 + * - UDP 接收数据吞吐量 (Mbit/s) + - 78.1 + - 66.7 + - 65.3 + - 53.8 + - 28.5 .. only:: esp32c3 - +----------------------------+-------+---------+---------+ - | 等级 | Iperf | 默认 | 最小 | - +============================+=======+=========+=========+ - | 可用内存(KB) | 59 | 160 | 180 | - +----------------------------+-------+---------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 20 | 8 | 3 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_RX_BA_WIN | 32 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_WND_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | - +----------------------------+-------+---------+---------+ - | TCP 发送数据吞吐量 (Mbit/s)| 38.1 | 27.2 | 20.4 | - +----------------------------+-------+---------+---------+ - | TCP 接收数据吞吐量 (Mbit/s)| 35.3 | 24.2 | 17.4 | - +----------------------------+-------+---------+---------+ - | UDP 发送数据吞吐量 (Mbit/s)| 40.6 | 38.9 | 34.1 | - +----------------------------+-------+---------+---------+ - | UDP 接收数据吞吐量 (Mbit/s)| 52.4 | 44.5 | 44.2 | - +----------------------------+-------+---------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 + + * - 等级 + - Iperf + - 默认 + - 最小 + * - 可用内存 (KB) + - 59 + - 160 + - 180 + * - WIFI_STATIC_RX_BUFFER_NUM + - 20 + - 8 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_RX_BA_WIN + - 32 + - 16 + - 6 + * - TCP_SND_BUF_DEFAULT (KB) + - 40 + - 16 + - 6 + * - TCP_WND_DEFAULT (KB) + - 40 + - 16 + - 6 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + * - TCP 发送数据吞吐量 (Mbit/s) + - 38.1 + - 27.2 + - 20.4 + * - TCP 接收数据吞吐量 (Mbit/s) + - 35.3 + - 24.2 + - 17.4 + * - UDP 发送数据吞吐量 (Mbit/s) + - 40.6 + - 38.9 + - 34.1 + * - UDP 接收数据吞吐量 (Mbit/s) + - 52.4 + - 44.5 + - 44.2 + +.. only:: esp32 or esp32s2 .. note:: 以上结果由使用华硕RT-N66U路由器,在屏蔽箱中进行单流测试得出。{IDF_TARGET_NAME} 的 CPU 为双核,频率为 240 MHz,flash 为 QIO 模式,频率为 80 MHz。 - .. only:: esp32 **等级:** @@ -1974,81 +2266,190 @@ Wi-Fi 使用的堆内存峰值是 Wi-Fi 驱动程序 **理论上消耗的最大 .. only:: esp32 - +----------------------------+-------+-------+----------+-------+ - | 等级 | Iperf | 默认 | 节省内存 | 最小 | - +----------------------------+-------+-------+----------+-------+ - | 可用内存 (KB) | 113.8 | 152.4 | 181.2 | 202.6 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 128 | 128 | 128 | 128 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_RX_BA_WIN | 16 | 16 | 8 | 禁用 | - +----------------------------+-------+-------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+-------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+-------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+-------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 37.5 | 31.7 | 21.7 | 14.6 | - +----------------------------+-------+-------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 31.5 | 29.8 | 26.5 | 21.1 | - +----------------------------+-------+-------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 69.1 | 31.5 | 27.1 | 24.1 | - +----------------------------+-------+-------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 40.1 | 38.5 | 37.5 | 36.9 | - +----------------------------+-------+-------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 15 + + * - 等级 + - Iperf + - 默认 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 113.8 + - 152.4 + - 181.2 + - 202.6 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 128 + - 128 + - 128 + - 128 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_RX_BA_WIN + - 16 + - 16 + - 8 + - 禁用 + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - TCP_WND_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - TCP 发送数据吞吐量 (Mbit/s) + - 37.5 + - 31.7 + - 21.7 + - 14.6 + * - TCP 接收数据吞吐量 (Mbit/s) + - 31.5 + - 29.8 + - 26.5 + - 21.1 + * - UDP 发送数据吞吐量 (Mbit/s) + - 69.1 + - 31.5 + - 27.1 + - 24.1 + * - UDP 接收数据吞吐量 (Mbit/s) + - 40.1 + - 38.5 + - 37.5 + - 36.9 .. only:: esp32s2 - +----------------------------+-------+------+----------+-------+ - | 等级 | Iperf | 默认 | 节省内存 | 最小 | - +----------------------------+-------+------+----------+-------+ - | 可用内存 (KB) | 70.6 | 96.4 | 118.8 | 148.2 | - +----------------------------+-------+------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 | 8 | 6 | 4 | - +----------------------------+-------+------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 64 | 64 | 64 | - +----------------------------+-------+------+----------+-------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 6 | 4 | - +----------------------------+-------+------+----------+-------+ - | WIFI_RX_BA_WIN | 16 | 6 | 6 | 禁用 | - +----------------------------+-------+------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+------+----------+-------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 8 | - +----------------------------+-------+------+----------+-------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | - +----------------------------+-------+------+----------+-------+ - | DATA_CACHE | 8 | 8 | 8 | 8 | - +----------------------------+-------+------+----------+-------+ - | DATA_CACHE_LINE | 32 | 32 | 32 | 32 | - +----------------------------+-------+------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 40.1 | 29.2 | 20.1 | 8.9 | - +----------------------------+-------+------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 21.9 | 16.8 | 14.8 | 9.6 | - +----------------------------+-------+------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 50.1 | 25.7 | 22.4 | 10.2 | - +----------------------------+-------+------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 45.3 | 43.1 | 28.5 | 15.1 | - +----------------------------+-------+------+----------+-------+ - - + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 15 + + * - 等级 + - Iperf + - 默认 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 70.6 + - 96.4 + - 118.8 + - 148.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 8 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 64 + - 64 + - 64 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 6 + - 4 + * - WIFI_RX_BA_WIN + - 16 + - 6 + - 6 + - 禁用 + * - TCP_SND_BUF_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - TCP_WND_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + * - DATA_CACHE + - 8 + - 8 + - 8 + - 8 + * - DATA_CACHE_LINE + - 32 + - 32 + - 32 + - 32 + * - TCP 发送数据吞吐量 (Mbit/s) + - 40.1 + - 29.2 + - 20.1 + - 8.9 + * - TCP 接收数据吞吐量 (Mbit/s) + - 21.9 + - 16.8 + - 14.8 + - 9.6 + * - UDP 发送数据吞吐量 (Mbit/s) + - 50.1 + - 25.7 + - 22.4 + - 10.2 + * - UDP 接收数据吞吐量 (Mbit/s) + - 45.3 + - 43.1 + - 28.5 + - 15.1 + + .. note:: + 达到性能的峰值可能会触发任务看门狗,由于 CPU 可能没有时间处理低优先级的任务,这是一个正常现象。 Wi-Fi Menuconfig ----------------------- @@ -2134,44 +2535,58 @@ Wi-Fi 缓冲区配置 下表是 Wi-Fi 内部缓冲区的配置情况。 -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 缓冲区类型 | 分配类型 | 默认 | 是否可配置 | 描述 | -+========================+==========+=================+============+===============================================================+ -| 静态接收数据缓冲区 | 静态 | 10 * 1600 Bytes | 是 | 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` | -| | | | | 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 | -| (硬件接收数据缓冲区) | | | | 该缓冲区形成硬件接收列表。当通过空中接收到一个帧时,硬件将 | -| | | | | 该帧写入缓冲区,并向 CPU 发起一个中断。然后,Wi-Fi 驱动程 | -| | | | | 序从缓冲区中读取内容,并将缓冲区返回到列表中。 如果应用程序 | -| | | | | 希望减少 Wi-Fi 静态分配的内存,可以将该值从 10 减少到 6, | -| | | | | 从而节省 6400 Bytes 的内存。除非禁用 AMPDU 功能,否则不 | -| | | | | 建议将该值降低到 6 以下。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 动态接收数据缓冲区 | 动态 | 32 | 是 | 缓冲区的长度可变,取决于所接收帧的长度。当 Wi-Fi 驱动程序 | -| | | | | 从“硬件接收数据缓冲区”接收到一帧时,需要从堆中分配“动态接收 | -| | | | | 数据缓冲区”。在 Menuconfig 中配置的“动态接收数据缓冲区” | -| | | | | 数量用来限制未释放的“动态接收数据缓冲区”总数量。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 动态发送数据缓冲区 | 动态 | 32 | 是 | 这是一种DMA内存,位于堆内存中。当上层 (LwIP) 向 Wi-Fi | -| | | | | 驱动程序发送数据包时,该缓冲区首先分配一个“动态发送数据缓 | -| | | | | 冲区”,并复制上层缓冲区。动态发送数据缓冲区和静态发送数据 | -| | | | | 缓冲区相互排斥。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 静态发送数据缓冲区 | 静态 | 16 * 1600 Bytes | 是 | 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` | -| | | | | 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 | -| | | | | 当上层 (LwIP) 向 Wi-Fi 驱动程序发送数据包时,该缓冲区首先 | -| | | | | 分配一个“静态发送数据缓冲区”,并复制上层缓冲区。动态发送数据 | -| | | | | 缓冲区和静态发送数据缓冲区相互排斥。由于发送数据缓冲区必须是 | -| | | | | DMA 缓冲区,所以当使能 PSRAM 时,发送数据缓冲区必须是静态 | -| | | | | 的。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 管理短缓冲区 | 动态 | 8 | 否 | Wi-Fi 驱动程序的内部缓冲区。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 管理长缓冲区 | 动态 | 32 | 否 | Wi-Fi 驱动程序的内部缓冲区。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 管理超长缓冲区 | 动态 | 32 | 否 | Wi-Fi 驱动程序的内部缓冲区。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ - - +.. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + + * - 缓冲区类型 + - 分配类型 + - 默认 + - 是否可配置 + - 描述 + * - 静态接收数据缓冲区(硬件接收数据缓冲区) + - 静态 + - 10 * 1600 Bytes + - 是 + - 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 该缓冲区形成硬件接收列表。当通过空中接收到一个帧时,硬件将该帧写入缓冲区,并向 CPU 发起一个中断。然后,Wi-Fi 驱动程序从缓冲区中读取内容,并将缓冲区返回到列表中。 + + 如果应用程序希望减少 Wi-Fi 静态分配的内存,可以将该值从 10 减少到 6, 从而节省 6400 Bytes 的内存。除非禁用 AMPDU 功能,否则不建议将该值降低到 6 以下。 + * - 动态接收数据缓冲区 + - 动态 + - 32 + - 是 + - 缓冲区的长度可变,取决于所接收帧的长度。当 Wi-Fi 驱动程序 从“硬件接收数据缓冲区”接收到一帧时,需要从堆中分配“动态接收数据缓冲区”。在 Menuconfig 中配置的“动态接收数据缓冲区” 数量用来限制未释放的“动态接收数据缓冲区”总数量。 + * - 动态发送数据缓冲区 + - 动态 + - 32 + - 是 + - 这是一种 DMA 内存,位于堆内存中。当上层 (LwIP) 向 Wi-Fi 驱动程序发送数据包时,该缓冲区首先分配一个“动态发送数据缓 冲区”,并复制上层缓冲区。 + + 动态发送数据缓冲区和静态发送数据缓冲区相互排斥。 + * - 静态发送数据缓冲区 + - 静态 + - 16 * 1600 Bytes + - 是 + - 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 当上层 (LwIP) 向 Wi-Fi 驱动程序发送数据包时,该缓冲区首先 分配一个“静态发送数据缓冲区”,并复制上层缓冲区。 + + 动态发送数据缓冲区和静态发送数据缓冲区相互排斥。 + + 由于发送数据缓冲区必须是 DMA 缓冲区,所以当使能 PSRAM 时,发送数据缓冲区必须是静态的。 + * - 管理短缓冲区 + - 动态 + - 8 + - 否 + - Wi-Fi 驱动程序的内部缓冲区。 + * - 管理长缓冲区 + - 动态 + - 32 + - 否 + - Wi-Fi 驱动程序的内部缓冲区。 + * - 管理超长缓冲区 + - 动态 + - 32 + - 否 + - Wi-Fi 驱动程序的内部缓冲区。 Wi-Fi NVS Flash +++++++++++++++++++++ diff --git a/docs/zh_CN/api-reference/network/esp_dpp.rst b/docs/zh_CN/api-reference/network/esp_dpp.rst new file mode 100644 index 000000000000..66b50a4e342b --- /dev/null +++ b/docs/zh_CN/api-reference/network/esp_dpp.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/network/esp_dpp.rst diff --git a/docs/zh_CN/api-reference/network/index.rst b/docs/zh_CN/api-reference/network/index.rst index 57964dcca4e8..a6565d84f747 100644 --- a/docs/zh_CN/api-reference/network/index.rst +++ b/docs/zh_CN/api-reference/network/index.rst @@ -13,6 +13,7 @@ Wi-Fi Smart Config ESP-NOW ESP Mesh + EasyConnect 本部分的 Wi-Fi API 示例代码存放在 ESP-IDF 示例项目的 :example:`wifi` 目录下。 diff --git a/docs/zh_CN/api-reference/peripherals/ledc.rst b/docs/zh_CN/api-reference/peripherals/ledc.rst index 13a62dd0b25f..e8221a06e548 100644 --- a/docs/zh_CN/api-reference/peripherals/ledc.rst +++ b/docs/zh_CN/api-reference/peripherals/ledc.rst @@ -1,25 +1,39 @@ LED PWM 控制器 ============== +{IDF_TARGET_LEDC_CHAN_NUM:default="8", esp32="16", esp32s2="8", esp32c3="6"} :link_to_translation:`en:[English]` 概述 ------------ -LED PWM 控制器主要用于控制 LED,也可产生 PWM 信号用于其他设备的控制。该控制器有 8 路高速通道和 8 路低速通道,可以产生独立的波形来驱动 RGB LED 设备等。 +LED 控制器 (LEDC) 主要用于控制 LED,也可产生 PWM 信号用于其他设备的控制。 +该控制器有 {IDF_TARGET_LEDC_CHAN_NUM} 路通道,可以产生独立的波形来驱动 RGB LED 等设备。 -LED PWM 控制器的高速通道和低速通道均支持硬件渐变功能,可在无需 CPU 干预的情况下自动改变 PWM 信号的占空比,也可由软件改变 PWM 信号的占空比,实现亮度和颜色渐变。此外,低速通道在 Sleep 模式下仍可运行。 +.. only:: esp32 + + LEDC 通道共有两组,分别为 8 路高速通道和 8 路低速通道。高速通道模式在硬件中实现,可以自动且无干扰地改变 PWM 占空比。低速通道模式下,PWM 占空比需要由软件中的驱动器改变。每组通道都可以使用不同的时钟源。 + +LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实现亮度和颜色渐变。 功能概览 ---------------------- -要让指定 LED PWM 控制器 :ref:`高速模式或低速模式 ` 通道运行,需进行如下配置: +.. only:: esp32 + + 设置 LEDC 通道在 :ref:`高速模式或低速模式 ` 下运行,需要进行如下配置: + + +.. only:: not esp32 + + 设置 LEDC 通道分三步完成。注意,与 ESP32 不同,{IDF_TARGET_NAME} 仅支持设置通道为低速模式。 1. :ref:`ledc-api-configure-timer` 指定 PWM 信号的频率和占空比分辨率。 2. :ref:`ledc-api-configure-channel` 绑定定时器和输出 PWM 信号的 GPIO。 3. :ref:`ledc-api-change-pwm-signal` 输出 PWM 信号来驱动 LED。可通过软件控制或使用硬件渐变功能来改变 LED 的亮度。 +另一个可选步骤是可以在渐变终端设置一个中断。 .. figure:: ../../../_static/ledc-api-settings.jpg :align: center @@ -31,25 +45,28 @@ LED PWM 控制器的高速通道和低速通道均支持硬件渐变功能,可 .. _ledc-api-configure-timer: -配置定时器 +定时器配置 ^^^^^^^^^^^^^^^ 要设置定时器,可调用函数 :cpp:func:`ledc_timer_config`,并将包括如下配置参数的数据结构 :cpp:type:`ledc_timer_config_t` 传递给该函数: +.. list:: + + :esp32: - 速度模式 :cpp:type:`ledc_mode_t` + :not esp32: - 速度模式(值必须为 ``LEDC_LOW_SPEED_MODE``) - 定时器索引 :cpp:type:`ledc_timer_t` - - 速度模式 :cpp:type:`ledc_mode_t` - PWM 信号频率 - PWM 占空比分辨率 -频率和占空比分辨率相互关联。PWM 频率越高,占空比分辨率越低,反之则越高。使用该 API 用于除改变 LED 亮度以外的其他目的时,这一点很重要。更多信息详见 :ref:`ledc-api-supported-range-frequency-duty-resolution` 一节。 +频率和占空比分辨率相互关联。PWM 频率越高,占空比分辨率越低,反之亦然。如果 API 不是用来改变 LED 亮度,而是用于其它目的,这种相互关系可能会很重要。更多信息详见 :ref:`ledc-api-supported-range-frequency-duty-resolution` 一节。 .. _ledc-api-configure-channel: -配置通道 +通道配置 ^^^^^^^^^^^^^^^^^ -定时器设置好后,请配置选定的通道(:cpp:type:`ledc_channel_t` 之一)。配置通道需调用函数 :cpp:func:`ledc_channel_config`。 +定时器设置好后,请配置所需的通道(:cpp:type:`ledc_channel_t` 之一)。配置通道需调用函数 :cpp:func:`ledc_channel_config`。 通道的配置与定时器设置类似,需向通道配置函数传递包括通道配置参数的结构 :cpp:type:`ledc_channel_config_t` 。 @@ -65,11 +82,17 @@ LED PWM 控制器的高速通道和低速通道均支持硬件渐变功能,可 以下两节介绍了如何使用软件和硬件改变占空比。如有需要,PWM 信号的频率也可更改,详见 :ref:`ledc-api-change-pwm-frequency` 一节。 +.. only:: esp32s2 or esp32c3 + + .. note:: + + 在 {IDF_TARGET_NAME} 的 LED PWM 控制器中,所有的定时器和通道都只支持低速模式。对 PWM 设置的任何改变,都需要由软件显式地触发(见下文)。 + 使用软件改变 PWM 占空比 """""""""""""""""""""""""""""""""""" -调用函数 :cpp:func:`ledc_set_duty` 可以设置新的占空比。之后,调用函数 :cpp:func:`ledc_update_duty` 使新配置生效。要查看当前的占空比,可使用 ``_get_`` 函数 :cpp:func:`ledc_get_duty`。 +调用函数 :cpp:func:`ledc_set_duty` 可以设置新的占空比。之后,调用函数 :cpp:func:`ledc_update_duty` 使新配置生效。要查看当前设置的占空比,可使用 ``_get_`` 函数 :cpp:func:`ledc_get_duty`。 另外一种设置占空比和其他通道参数的方式是调用 :ref:`ledc-api-configure-channel` 一节提到的函数 :cpp:func:`ledc_channel_config`。 @@ -123,28 +146,31 @@ LED PWM 控制器 API 有多种方式即时改变 PWM 频率: 要注册处理程序来处理中断,可调用函数 :cpp:func:`ledc_isr_register`。 -.. _ledc-api-high_low_speed_mode: +.. only:: esp32 -LED PWM 控制器高速和低速模式 ----------------------------- + .. _ledc-api-high_low_speed_mode: + + LED PWM 控制器高速和低速模式 + ---------------------------------- -LED PWM 控制器有 8 个可用定时器和 16 路通道,其中有一半专以高速模式运行,另一半则以低速模式运行。要选取高速或低速定时器或通道,可借助所调用函数中的参数 :cpp:type:`ledc_mode_t` 。 + 高速模式的优点是可平稳地改变定时器设置。也就是说,高速模式下如定时器设置改变,此变更会自动应用于定时器的下一次溢出中断。而更新低速定时器时,设置变更应由软件显式触发。LED PWM 驱动的设置将在硬件层面被修改,比如在调用函数 :cpp:func:`ledc_timer_config` 或 :cpp:func:`ledc_timer_set` 时。 -高速模式的优点是可平稳地改变定时器设置。也就是说,高速模式下如定时器设置改变,此变更会自动应用于定时器的下一次溢出中断。而更新低速定时器时,设置变更应由软件显式触发。LED PWM 驱动器在后台更改设置,比如在调用函数 :cpp:func:`ledc_timer_config` 或 :cpp:func:`ledc_timer_set` 时。 + 更多关于速度模式的详细信息请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *LED PWM 控制器 (LEDC)* [`PDF <{IDF_TARGET_TRM_EN_URL}#ledpwm>`__]。注意,该手册中提到的支持 ``SLOW_CLOCK`` 暂不适用于 LED PWM 驱动。 -更多关于速度模式的详细信息请参阅 `ESP32 技术参考手册 `_ (PDF)。注意,该手册中提到的支持 ``SLOW_CLOCK`` 暂不适用于 LED PWM 驱动器。 + .. _ledc-api-supported-range-frequency-duty-resolution: +.. only:: not esp32 -.. _ledc-api-supported-range-frequency-duty-resolution: + .. _ledc-api-supported-range-frequency-duty-resolution: 频率和占空比分辨率支持范围 ------------------------------------------------- -LED PWM 控制器主要用于驱动 LED。该控制器 PWM 占空比设置的分辨率范围较广。比如,PWM 频率为 5 kHz 时,占空比分辨率最大可为 13 位。这意味着占空比可为 0 至 100% 之间的任意值,分辨率为 ~0.012%(2 ** 13 = 8192 LED 亮度的离散电平)。 +LED PWM 控制器主要用于驱动 LED。该控制器 PWM 占空比设置的分辨率范围较广。比如,PWM 频率为 5 kHz 时,占空比分辨率最大可为 13 位。这意味着占空比可为 0 至 100% 之间的任意值,分辨率为 ~0.012%(2 ** 13 = 8192 LED 亮度的离散电平)。然而,这些参数取决于为 LED PWM 控制器定时器计时的时钟信号,LED PWM 控制器为通道提供时钟(具体可参考 :ref:`定时器配置 ` 和 *{IDF_TARGET_NAME} 技术参考手册* > *LED PWM 计时器 (LEDC)* [`PDF <{IDF_TARGET_TRM_EN_URL}#ledpwm>`__])。 -LED PWM 控制器可用于生成频率较高的信号,足以为数码相机模组等其他设备计时。此时,最大频率可为 40 MHz,占空比分辨率为 1 位。也就是说,占空比固定为 50%,无法调整。 +LED PWM 控制器可用于生成频率较高的信号,足以为数码相机模组等其他设备提供时钟。此时,最大频率可为 40 MHz,占空比分辨率为 1 位。也就是说,占空比固定为 50%,无法调整。 -LED PWM 控制器 API 可在设定的频率和占空比分辨率超过 LED PWM 控制器硬件范围时报错。例如,试图将频率设置为 20 MHz、占空比分辨率设置为 3 位时,串行端口监视器上会报告如下错误: +LED PWM 控制器 API 会在设定的频率和占空比分辨率超过 LED PWM 控制器硬件范围时报错。例如,试图将频率设置为 20 MHz、占空比分辨率设置为 3 位时,串行端口监视器上会报告如下错误: .. highlight:: none @@ -160,7 +186,7 @@ LED PWM 控制器 API 可在设定的频率和占空比分辨率超过 LED PWM E (196) ledc: requested frequency and duty resolution cannot be achieved, try increasing freq_hz or duty_resolution. div_param=128000000 -占空比分辨率通常用 :cpp:type:`ledc_timer_bit_t` 设置,范围是 10 至 15位。如需较低的占空比分辨率(上至 10,下至 1),可直接输入相应数值。 +占空比分辨率通常用 :cpp:type:`ledc_timer_bit_t` 设置,范围是 10 至 15 位。如需较低的占空比分辨率(上至 10,下至 1),可直接输入相应数值。 应用实例 diff --git a/docs/zh_CN/api-reference/storage/nvs_flash.rst b/docs/zh_CN/api-reference/storage/nvs_flash.rst index c4dbb5ce6266..2747f1cd6197 100644 --- a/docs/zh_CN/api-reference/storage/nvs_flash.rst +++ b/docs/zh_CN/api-reference/storage/nvs_flash.rst @@ -11,9 +11,9 @@ 底层存储 ^^^^^^^^^^^^^^^^^^ -NVS 通过调用 ``spi_flash_{read|write|erase}`` API 对主 flash 的部分空间进行读、写、擦除操作,包括 ``data`` 类型和 ``nvs`` 子类型的所有分区。应用程序可调用 ``nvs_open`` API 选择使用带有 ``nvs`` 标签的分区,也可以通过调用 ``nvs_open_from_part`` API 选择使用指定名称的任意分区。 +NVS 库通过调用 :ref:`esp_partition ` API 使用主 flash 的部分空间,即类型为 ``data`` 且子类型为 ``nvs`` 的所有分区。应用程序可调用 :cpp:func:`nvs_open` API 选择使用带有 ``nvs`` 标签的分区,也可以通过调用 :cpp:func:`nvs_open_from_partition` API 选择使用指定名称的任意分区。 -NVS 库后续版本可能会增加其他存储器后端,实现将数据保存至其他 flash 芯片(SPI 或 I2C 接口)、RTC 或 FRAM 中。 +NVS 库后续版本可能会增加其他存储器后端,来将数据保存至其他 flash 芯片(SPI 或 I2C 接口)、RTC 或 FRAM 中。 .. note:: 如果 NVS 分区被截断(例如,更改分区表布局时),则应擦除分区内容。可以使用 ESP-IDF 构建系统中的 ``idf.py erase_flash`` 命令擦除 flash 上的所有内容。 @@ -23,15 +23,15 @@ NVS 库后续版本可能会增加其他存储器后端,实现将数据保存 键值对 ^^^^^^^^^^^^^^^ -NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持最大键长为 15 个字符,值可以为以下几种类型: +NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持的最大键长为 15 个字符。值可以为以下几种类型: - 整数型:``uint8_t``、``int8_t``、``uint16_t``、``int16_t``、``uint32_t``、``int32_t``、``uint64_t`` 和 ``int64_t``; -- 以 ``\0`` 结尾的字符串; +- 以 0 结尾的字符串; - 可变长度的二进制数据 (BLOB) .. note:: - 字符串值当前上限为 4000 字节,其中包括空终止符。BLOB 值上限为 508,000 字节或分区大小减去 4000 字节的 97.6%,以较低值为准。 + 字符串值当前上限为 4000 字节,其中包括空终止符。BLOB 值上限为 508,000 字节或分区大小的 97.6% 减去 4000 字节,以较低值为准。 后续可能会增加对 ``float`` 和 ``double`` 等其他类型数据的支持。 @@ -46,19 +46,139 @@ NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持最 命名空间 ^^^^^^^^^^ -为了减少不同组件之间键名的潜在冲突,NVS 将每个键值对分配给一个命名空间。命名空间的命名规则遵循键名的命名规则,即最多可占 15 个字符。命名空间的名称在调用 ``nvs_open`` 或 ``nvs_open_from_part`` 中指定,调用后将返回一个不透明句柄,用于后续调用 ``nvs_get_*``、``nvs_set_*`` 和 ``nvs_commit`` 函数。这样,一个句柄关联一个命名空间,键名便不会与其他命名空间中相同键名冲突。请注意,不同 NVS 分区中具有相同名称的命名空间将被视为不同的命名空间。 +为了减少不同组件之间键名的潜在冲突,NVS 将每个键值对分配给一个命名空间。命名空间的命名规则遵循键名的命名规则,例如,最多可占 15 个字符。命名空间的名称在调用 :cpp:func:`nvs_open` 或 :cpp:type:`nvs_open_from_partition` 中指定,调用后将返回一个不透明句柄,用于后续调用 ``nvs_get_*``、``nvs_set_*`` 和 ``nvs_commit`` 函数。这样,一个句柄关联一个命名空间,键名便不会与其他命名空间中相同键名冲突。请注意,不同 NVS 分区中具有相同名称的命名空间将被视为不同的命名空间。 + +NVS 迭代器 +^^^^^^^^^^^^^ + +迭代器允许根据指定的分区名称、命名空间和数据类型轮询 NVS 中存储的键值对。 + +您可以使用以下函数,执行相关操作: + +- ``nvs_entry_find``:返回一个不透明句柄,用于后续调用 ``nvs_entry_next`` 和 ``nvs_entry_info`` 函数; +- ``nvs_entry_next``:返回指向下一个键值对的迭代器; +- ``nvs_entry_info``:返回每个键值对的信息。 + +如果未找到符合标准的键值对,``nvs_entry_find`` 和 ``nvs_entry_next`` 将返回 NULL,此时不必释放迭代器。若不再需要迭代器,可使用 ``nvs_release_iterator`` 释放迭代器。 安全性、篡改性及鲁棒性 ^^^^^^^^^^^^^^^^^^^^^^^^^^ -NVS 与 ESP32 flash 加密系统不直接兼容。但如果 NVS 加密与 ESP32 flash 加密一起使用时,数据仍可以加密形式存储。更多详情请参阅 :ref:`nvs_encryption`。 +NVS 与 {IDF_TARGET_NAME} flash 加密系统不直接兼容。但如果 NVS 加密与 {IDF_TARGET_NAME} flash 加密一起使用时,数据仍可以加密形式存储。详情请参阅 :ref:`nvs_encryption`。 -如果未启用 NVS 加密,任何对 flash 芯片有物理访问权限的人都可以修改、擦除或添加键值对。NVS 加密启用后,如果不知道相应的 NVS 加密密钥,则无法修改或添加键值对并将其识别为有效键值。但是,针对擦除操作没有相应的防篡改功能。 +如果未启用 NVS 加密,任何对 flash 芯片有物理访问权限的用户都可以修改、擦除或添加键值对。NVS 加密启用后,如果不知道相应的 NVS 加密密钥,则无法修改或添加键值对并将其识别为有效键值对。但是,针对擦除操作没有相应的防篡改功能。 当 flash 处于不一致状态时,NVS 库会尝试恢复。在任何时间点关闭设备电源,然后重新打开电源,不会导致数据丢失;但如果关闭设备电源时正在写入新的键值对,这一键值对可能会丢失。该库还应当能对 flash 中的任意数据进行正确初始化。 +.. _nvs_encryption: + +NVS 加密 +-------------- + +NVS 分区内存储的数据可使用 AES-XTS 进行加密,类似于 IEEE P1619 磁盘加密标准中提到的加密方式。为了实现加密,每个条目被均视为一个扇区,并将条目相对地址(相对于分区开头)传递给加密算法,用作扇区号。可通过 :ref:`CONFIG_NVS_ENCRYPTION` 启用 NVS 加密。NVS 加密所需的密钥存储于其他分区,并且被 :doc:`Flash 加密 <../../security/flash-encryption>` 保护。因此,在使用 NVS 加密前应先启用 :doc:`Flash 加密 <../../security/flash-encryption>`。 + +启用 :doc:`Flash 加密 <../../security/flash-encryption>` 时,默认启用 NVS 加密。这是因为 Wi-Fi 驱动在默认的 NVS 分区中存储了凭证(如 SSID 和密码)。启用平台级加密后,仍需将它们作为默认选项进行加密。 + +使用 NVS 加密,分区表必须包含 :ref:`nvs_key_partition`。在分区表选项 (menuconfig->Partition Table) 下,为 NVS 加密提供了两个包含 :ref:`nvs_key_partition` 的分区表,您可以通过工程配置菜单 (``idf.py menuconfig``) 进行选择。请参考 :example:`security/flash_encryption` 中的例子,了解如何配置和使用 NVS 加密功能。 + +.. _nvs_key_partition: + +NVS 密钥分区 +^^^^^^^^^^^^^^^^^ + + 应用程序如果想使用 NVS 加密,则需要编译进一个类型为 `data`,子类型为 `key` 的密钥分区。该分区应标记为 `已加密` 且最小为 4096 字节。如需了解更多详细信息,请参考 :doc:`分区表 <../../api-guides/partition-tables>`。在分区表选项 (menuconfig->Partition Table) 下提供了两个包含 :ref:`nvs_key_partition` 的额外分区表,可以直接用于 :ref:`nvs_encryption`。这些分区的具体结构见下表: + +.. highlight:: none + +:: + + +-----------+--------------+-------------+----+ + | XTS encryption key (32) | + +---------------------------------------------+ + | XTS tweak key (32) | + +---------------------------------------------+ + | CRC32 (4) | + +---------------------------------------------+ + +可以通过以下两种方式生成 :ref:`nvs_key_partition` 中的 XTS 加密密钥: + +1. 在 ESP 芯片上生成密钥: + + 启用 NVS 加密时,可用 :cpp:func:`nvs_flash_init` API 函数来初始化加密的默认 NVS 分区,在内部生成 ESP 芯片上的 XTS 加密密钥。在找到 :ref:`nvs_key_partition` 后,API 函数利用 :component_file:`nvs_flash/include/nvs_flash.h` 提供的 :cpp:func:`nvs_flash_generate_keys` 函数,自动生成并存储该分区中的 NVS 密钥。只有当各自的密钥分区为空时,才会生成并存储新的密钥。可以借助 :cpp:func:`nvs_flash_secure_init_partition` 用同一个密钥分区来读取安全配置,以初始化一个定制的加密 NVS 分区。 + + API 函数 :cpp:func:`nvs_flash_secure_init` 和 :cpp:func:`nvs_flash_secure_init_partition` 不在内部产生密钥。当这些 API 函数用于初始化加密的 NVS 分区时,可以在启动后使用 `nvs_flash.h` 提供的 :cpp:func:`nvs_flash_generate_keys` API 函数生成密钥,以加密的形式把密钥写到密钥分区上。 + +2. 使用预先生成的密钥分区: + + 若 :ref:`nvs_key_partition` 中的密钥不是由应用程序生成,则需要使用预先生成的密钥分区。可以使用 :doc:`NVS 分区生成工具 ` 生成包含 XTS 加密密钥的 :ref:`nvs_key_partition`。用户可以借助以下两个命令,将预先生成的密钥分区储存在 flash 上: + + i) 建立并烧录分区表 + :: + + idf.py partition-table partition-table-flash + + ii) 调用 :component_file:`parttool.py`,将密钥存储在 flash 上的 :ref:`nvs_key_partition` 中。详见 :doc:` 分区表 ` 的分区工具部分。 + + + parttool.py --port /dev/ttyUSB0 --partition-table-offset "nvs_key partition offset" write_partition --partition-name="name of nvs_key partition" --input "nvs_key partition" + +由于分区已标记为 `已加密`,而且启用了 :doc:`Flash 加密 <../../security/flash-encryption>`,引导程序在首次启动时将使用 flash 加密对密钥分区进行加密。 + +应用程序可以使用不同的密钥对不同的 NVS 分区进行加密,这样就会需要多个加密密钥分区。应用程序应为加解密操作提供正确的密钥或密钥分区。 + +加密读取/写入 +^^^^^^^^^^^^^^^^^^^^ + +``nvs_get_*`` 和 ``nvs_set_*`` 等 NVS API 函数同样可以对 NVS 加密分区执行读写操作。 + +**加密默认的 NVS 分区:** +无需额外步骤即可启用默认 NVS 分区的加密。启用 :ref:`CONFIG_NVS_ENCRYPTION` 时, :cpp:func:`nvs_flash_init` API 函数会在内部使用找到的第一个 :ref:`nvs_key_partition` 执行额外步骤,以启用默认 NVS 分区的加密(详情请参考 API 文档)。另外,:cpp:func:`nvs_flash_secure_init` API 函数也可以用来启用默认 NVS 分区的加密。 + +**加密一个自定义的 NVS 分区:** +使用 :cpp:func:`nvs_flash_secure_init_partition` API 函数启用自定义 NVS 分区的加密,而非 :cpp:func:`nvs_flash_init_partition`。 + +使用 :cpp:func:`nvs_flash_secure_init` 和 :cpp:func:`nvs_flash_secure_init_partition` API 函数时,应用程序如需在加密状态下执行 NVS 读写操作,应遵循以下步骤: + + 1. 使用 ``esp_partition_find*`` API 查找密钥分区和 NVS 数据分区; + 2. 使用 ``nvs_flash_read_security_cfg`` 或 ``nvs_flash_generate_keys`` API 填充 ``nvs_sec_cfg_t`` 结构; + 3. 使用 ``nvs_flash_secure_init`` 或 ``nvs_flash_secure_init_partition`` API 初始化 NVS flash 分区; + 4. 使用 ``nvs_open`` 或 ``nvs_open_from_partition`` API 打开命名空间; + 5. 使用 ``nvs_get_*`` 或 ``nvs_set_*`` API 执行 NVS 读取/写入操作; + 6. 使用 ``nvs_flash_deinit`` API 释放已初始化的 NVS 分区。 + +NVS 分区生成程序 +------------------ + +NVS 分区生成程序帮助生成 NVS 分区二进制文件,可使用烧录程序将二进制文件单独烧录至特定分区。烧录至分区上的键值对由 CSV 文件提供,详情请参考 :doc:`NVS 分区生成程序 `。 + +应用示例 +------------------- + +ESP-IDF :example:`storage` 目录下提供了数个代码示例: + +:example:`storage/nvs_rw_value` + + 演示如何读取及写入 NVS 单个整数值。 + + 此示例中的值表示 {IDF_TARGET_NAME} 模组重启次数。NVS 中数据不会因为模组重启而丢失,因此只有将这一值存储于 NVS 中,才能起到重启次数计数器的作用。 + + 该示例也演示了如何检测读取/写入操作是否成功,以及某个特定值是否在 NVS 中尚未初始化。诊断程序以纯文本形式提供,帮助您追踪程序流程,及时发现问题。 + +:example:`storage/nvs_rw_blob`  + + 演示如何读取及写入 NVS 单个整数值和 Blob(二进制大对象),并在 NVS 中存储这一数值,即便 {IDF_TARGET_NAME} 模组重启也不会消失。 + + * value - 记录 {IDF_TARGET_NAME} 模组软重启次数和硬重启次数。 + * blob - 内含记录模组运行次数的表格。此表格将被从 NVS 读取至动态分配的 RAM 上。每次手动软重启后,表格内运行次数即增加一次,新加的运行次数被写入 NVS。下拉 GPIO0 即可手动软重启。 + + 该示例也演示了如何执行诊断程序以检测读取/写入操作是否成功。 + +:example:`storage/nvs_rw_value_cxx` + + 这个例子与 :example:`storage/nvs_rw_value` 完全一样,只是使用了 C++ 的 NVS 处理类。 + 内部实现 --------- @@ -70,7 +190,7 @@ NVS 按顺序存储键值对,新的键值对添加在最后。因此,如需 页面和条目 ^^^^^^^^^^^^^^^^^ -NVS 库在其操作中主要使用两个实体:页面和条目。页面是一个逻辑结构,用于存储部分的整体日志。逻辑页面对应 flash 的一个物理扇区,正在使用中的页面具有与之相关联的序列号。序列号赋予了页面顺序,较高的序列号对应较晚创建的页面。页面有以下几种状态: +NVS 库在其操作中主要使用两个实体:页面和条目。页面是一个逻辑结构,用于存储部分的整体日志。逻辑页面对应 flash 的一个物理扇区,正在使用中的页面具有与之相关联的 *序列号*。序列号赋予了页面顺序,较高的序列号对应较晚创建的页面。页面有以下几种状态: 空或未初始化 页面对应的 flash 扇区为空白状态(所有字节均为 ``0xff``)。此时,页面未存储任何数据且没有关联的序列号。 @@ -79,7 +199,8 @@ NVS 库在其操作中主要使用两个实体:页面和条目。页面是一 此时 flash 已完成初始化,页头部写入 flash,页面已具备有效序列号。页面中存在一些空条目,可写入数据。任意时刻,至多有一个页面处于活跃状态。 写满状态 - Flash 已写满键值对,状态不再改变。用户无法向写满状态下的页面写入新键值对,但仍可将一些键值对标记为已擦除。 + Flash 已写满键值对,状态不再改变。 + 用户无法向写满状态下的页面写入新键值对,但仍可将一些键值对标记为已擦除。 擦除状态 未擦除的键值对将移至其他页面,以便擦除当前页面。这一状态仅为暂时性状态,即 API 调用返回时,页面应脱离这一状态。如果设备突然断电,下次开机时,设备将继续把未擦除的键值对移至其他页面,并继续擦除当前页面。 @@ -106,11 +227,13 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 页面结构 ^^^^^^^^^^^^^^^^^^^ -当前,我们假设 flash 扇区大小为 4096 字节,并且 ESP32 flash 加密硬件在 32 字节块上运行。未来有可能引入一些编译时可配置项(可通过 menuconfig 进行配置),以适配具有不同扇区大小的 flash 芯片。但目前尚不清楚 SPI flash 驱动和 SPI flash cache 之类的系统组件是否支持其他扇区大小。 +当前,我们假设 flash 扇区大小为 4096 字节,并且 {IDF_TARGET_NAME} flash 加密硬件在 32 字节块上运行。未来有可能引入一些编译时可配置项(可通过 menuconfig 进行配置),以适配具有不同扇区大小的 flash 芯片。但目前尚不清楚 SPI flash 驱动和 SPI flash cache 之类的系统组件是否支持其他扇区大小。 -页面由头部、条目状态位图和条目三部分组成。为了实现与 ESP32 flash 加密功能兼容,条目大小设置为 32 字节。如果键值为整数型,条目则保存一个键值对;如果键值为字符串或 BLOB 类型,则条目仅保存一个键值对的部分内容(更多信息详见条目结构描述)。 +页面由头部、条目状态位图和条目三部分组成。为了实现与 {IDF_TARGET_NAME} flash 加密功能兼容,条目大小设置为 32 字节。如果键值为整数型,条目则保存一个键值对;如果键值为字符串或 BLOB 类型,则条目仅保存一个键值对的部分内容(更多信息详见条目结构描述)。 -页面结构如下图所示,括号内数字表示该部分的大小(以字节为单位):: +页面结构如下图所示,括号内数字表示该部分的大小(以字节为单位)。 + +:: +-----------+--------------+-------------+-------------------------+ | State (4) | Seq. no. (4) | version (1) | Unused (19) | CRC32 (4) | 页头部 (32) @@ -127,15 +250,15 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 | Entry 125 (32) | +------------------------------------------------------------------+ -头部和条目状态位图写入 flash 时不加密。如果启用了 ESP32 flash 加密功能,则条目写入 flash 时将会加密。 +头部和条目状态位图写入 flash 时不加密。如果启用了 {IDF_TARGET_NAME} flash 加密功能,则条目写入 flash 时将会加密。 -通过将 0 写入某些位可以定义页面状态值,表示状态改变。因此,如果需要变更页面状态,并不一定要擦除页面,除非要将其变更为擦除状态。 +通过将 0 写入某些位可以定义页面状态值,表示状态改变。因此,如果需要变更页面状态,并不一定要擦除页面,除非要将其变更为 *擦除* 状态。 -头部中的 ``version`` 字段反映了所用的 NVS 格式版本。为实现向后兼容,版本升级从 0xff 开始依次递减(例如,version-1 为 0xff,version-2 为 0xfe 等)。 +头部中的 ``version`` 字段反映了所用的 NVS 格式版本。为实现向后兼容,版本升级从 0xff 开始依次递减(例如,version-1 为 0xff,version-2 为 0xfe,以此类推)。 头部中 CRC32 值是由不包含状态值的条目计算所得(4 到 28 字节)。当前未使用的条目用 ``0xff`` 字节填充。 -条目结构和条目状态位图详细信息见下文描述。 +条目结构和条目状态位图的详细信息见下文描述。 条目和条目状态位图 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -151,6 +274,7 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 擦除(2'b00) 条目中的键值对已丢弃,条目内容不再解析。 + .. _structure_of_entry: 条目结构 @@ -167,12 +291,12 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 Primitive +--------------------------------+ +--------> | Data (8) | | Types +--------------------------------+ - +-> Fixed length -- + +-> Fixed length -- | | +---------+--------------+---------------+-------+ | +--------> | Size(4) | ChunkCount(1)| ChunkStart(1) | Rsv(2)| Data format ---+ BLOB Index +---------+--------------+---------------+-------+ | - | +----------+---------+-----------+ + | +----------+---------+-----------+ +-> Variable length --> | Size (2) | Rsv (2) | CRC32 (4) | (Strings, BLOB Data) +----------+---------+-----------+ @@ -180,10 +304,10 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 条目结构中各个字段含义如下: 命名空间 (NS, NameSpace) - 该条目的命名空间索引,详细信息见命名空间实现章节。 + 该条目的命名空间索引,详细信息参见命名空间实现章节。 类型 (Type) - 一个字节表示的值的数据类型,可能的类型见 ``nvs_types.h`` 中 ``ItemType`` 枚举。 + 一个字节表示的值的数据类型,:component_file:`nvs_flash/include/nvs_handle.hpp` 下的 :cpp:type:`ItemType` 枚举了可能的类型。 跨度 (Span) 该键值对所用的条目数量。如果键值为整数型,条目数量即为 1。如果键值为字符串或 BLOB,则条目数量取决于值的长度。 @@ -192,10 +316,10 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 用于存储 BLOB 类型数据块的索引。如果键值为其他数据类型,则此处索引应写入 ``0xff``。 CRC32 - 对条目下所有字节进行校验,所得的校验和(CRC32 字段不计算在内)。 + 对条目下所有字节进行校验后,所得的校验和(CRC32 字段不计算在内)。 键 (Key) - 即以零结尾的 ASCII 字符串,字符串最长为 15 字节,不包含最后一个字节的 NULL (``\0``) 终止符。 + 即以零结尾的 ASCII 字符串,字符串最长为 15 字节,不包含最后一个字节的零终止符。 数据 (Data) 如果键值类型为整数型,则数据字段仅包含键值。如果键值小于八个字节,使用 ``0xff`` 填充未使用的部分(右侧)。 @@ -205,21 +329,22 @@ CRC32 - 块大小 整个 BLOB 数据的大小(以字节为单位)。该字段仅用于 BLOB 索引类型条目。 - - ChunkCount - 存储过程中 BLOB 分成的数据块数量。该字段仅用于 BLOB 索引类型条目。 - - - ChunkStart + - ChunkCount + 存储过程中 BLOB 分成的数据块总量。该字段仅用于 BLOB 索引类型条目。 + + - ChunkStart BLOB 第一个数据块的块索引,后续数据块索引依次递增,步长为 1。该字段仅用于 BLOB 索引类型条目。 如果键值类型为字符串或 BLOB 数据块,数据字段的这八个字节将保存该键值的一些附加信息,如下所示: - + - 数据大小 实际数据的大小(以字节为单位)。如果键值类型为字符串,此字段也应将零终止符包含在内。此字段仅用于字符串和 BLOB 类型条目。 - CRC32 数据所有字节的校验和,该字段仅用于字符串和 BLOB 类型条目。 -可变长度值(字符串和 BLOB)写入后续条目,每个条目 32 字节。第一个条目的 span 字段将指明使用了多少条目。 +可变长度值(字符串和 BLOB)写入后续条目,每个条目 32 字节。第一个条目的 `Span` 字段将指明使用了多少条目。 + 命名空间 ^^^^^^^^^^ @@ -246,89 +371,6 @@ CRC32 哈希列表中每个节点均包含一个 24 位哈希值和 8 位条目索引。哈希值根据条目命名空间、键名和块索引由 CRC32 计算所得,计算结果保留 24 位。为减少将 32 位条目存储在链表中的开销,链表采用了数组的双向链表。每个数组占用 128 个字节,包含 29 个条目、两个链表指针和一个 32 位计数字段。因此,每页额外需要的 RAM 最少为 128 字节,最多为 640 字节。 -.. _nvs_encryption: - -NVS 加密 --------------- - -NVS 分区内存储的数据可使用 AES-XTS 进行加密,类似于 IEEE P1619 磁盘加密标准中提到的加密方式。为了实现加密,每个条目被均视为一个扇区,并将条目相对地址(相对于分区开头)传递给加密算法,用作扇区号。NVS 加密所需的密钥存储于其他分区,并进行了 :doc:`flash 加密 <../../security/flash-encryption>`。因此,在使用 NVS 加密前应先启用 :doc:`flash 加密 <../../security/flash-encryption>`。 - -.. _nvs_key_partition: - -NVS 密钥分区 -^^^^^^^^^^^^^^^^^ - -应用程序如果想使用 NVS 加密,则需要编译进一个类型为 ``data``,子类型为 ``key`` 的密钥分区。该分区应标记为已加密,且最小为 4096 字节,具体结构见下表。如需了解更多详细信息,请参考 :doc:`分区表 <../../api-guides/partition-tables>`。 - -:: - - +-----------+--------------+-------------+----+ - | XTS encryption key(32) | - +---------------------------------------------+ - | XTS tweak key (32) | - +---------------------------------------------+ - | CRC32(4) | - +---------------------------------------------+ - -使用 NVS 分区生成程序生成上述分区表,并烧录至设备。由于分区已标记为已加密,而且启用了 :doc:`flash 加密 <../../security/flash-encryption>`,引导程序在首次启动时将使用 flash 加密对密钥分区进行加密。您也可以在设备启动后调用 ``nvs_flash.h`` 提供的 ``nvs_flash_generate_keys`` API 生成加密密钥,然后再将密钥以加密形式写入密钥分区。 - -应用程序可以使用不同的密钥对不同的 NVS 分区进行加密,这样就会需要多个加密密钥分区。应用程序应为加解密操作提供正确的密钥或密钥分区。 - -加密读取/写入 -^^^^^^^^^^^^^^^^^^^^ - -``nvs_get_*`` 和 ``nvs_set_*`` 等 NVS API 函数同样可以对 NVS 加密分区执行读写操作。但用于初始化 NVS 非加密分区和加密分区的 API 则有所不同:初始化 NVS 非加密分区可以使用 ``nvs_flash_init`` 和 ``nvs_flash_init_partition``,但初始化 NVS 加密分区则需调用 ``nvs_flash_secure_init`` 和 ``nvs_flash_secure_init_partition``。上述 API 函数所需的 ``nvs_sec_cfg_t`` 结构可使用 ``nvs_flash_generate_keys`` 或者 ``nvs_flash_read_security_cfg`` 进行填充。 - -应用程序如需在加密状态下执行 NVS 读写操作,应遵循以下步骤: - - 1. 使用 ``esp_partition_find*`` API 查找密钥分区和 NVS 数据分区; - 2. 使用 ``nvs_flash_read_security_cfg`` 或 ``nvs_flash_generate_keys`` API 填充 ``nvs_sec_cfg_t`` 结构; - 3. 使用 ``nvs_flash_secure_init`` 或 ``nvs_flash_secure_init_partition`` API 初始化 NVS flash 分区; - 4. 使用 ``nvs_open`` 或 ``nvs_open_from_part`` API 打开命名空间; - 5. 使用 ``nvs_get_*`` 或 ``nvs_set_*`` API 执行 NVS 读取/写入操作; - 6. 使用 ``nvs_flash_deinit`` API 释放已初始化的 NVS 分区。 - -NVS 迭代器 -^^^^^^^^^^^^^ - -迭代器允许根据指定的分区名称、命名空间和数据类型轮询 NVS 中存储的键值对。 - -您可以使用以下函数,执行相关操作: - -- ``nvs_entry_find``:返回一个不透明句柄,用于后续调用 ``nvs_entry_next`` 和 ``nvs_entry_info`` 函数; -- ``nvs_entry_next``:返回指向下一个键值对的迭代器; -- ``nvs_entry_info``:返回每个键值对的信息。 - -如果未找到符合标准的键值对,``nvs_entry_find`` 和 ``nvs_entry_next`` 将返回 NULL,此时不必释放迭代器。若不再需要迭代器,可使用 ``nvs_release_iterator`` 释放迭代器。 - -NVS 分区生成程序 ------------------- - -NVS 分区生成程序帮助生成 NVS 分区二进制文件,可使用烧录程序将二进制文件单独烧录至特定分区。烧录至分区上的键值对由 CSV 文件提供,详情请参考 :doc:`NVS 分区生成程序 `。 - -应用示例 -------------------- - -ESP-IDF :example:`storage` 目录下提供了两个代码示例: - -:example:`storage/nvs_rw_value` - - 演示如何读取及写入 NVS 单个整数值。 - - 此示例中的值表示 ESP32 模组重启次数。NVS 中数据不会因为模组重启而丢失,因此只有将这一值存储于 NVS 中,才能起到重启次数计数器的作用。 - - 该示例也演示了如何检测读取/写入操作是否成功,以及某个特定值是否在 NVS 中尚未初始化。诊断程序以纯文本形式提供,帮助您追踪程序流程,及时发现问题。 - -:example:`storage/nvs_rw_blob`  - - 演示如何读取及写入 NVS 单个整数值和 Blob(二进制大对象),并在 NVS 中存储这一数值,即便 ESP32 模组重启也不会消失。 - - * value - 记录 ESP32 模组软重启次数和硬重启次数。 - * blob - 内含记录模组运行次数的表格。此表格将被从 NVS 读取至动态分配的 RAM 上。每次手动软重启后,表格内运行次数即增加一次,新加的运行次数被写入 NVS。下拉 GPIO0 即可手动软重启。 - - 该示例也演示了如何执行诊断程序以检测读取/写入操作是否成功。 - - API 参考 ------------- diff --git a/docs/zh_CN/api-reference/storage/sdmmc.rst b/docs/zh_CN/api-reference/storage/sdmmc.rst index 4d7d3400e9ee..61e1b6fa2461 100644 --- a/docs/zh_CN/api-reference/storage/sdmmc.rst +++ b/docs/zh_CN/api-reference/storage/sdmmc.rst @@ -3,18 +3,12 @@ SD/SDIO/MMC 驱动程序 :link_to_translation:`en:[English]` -.. only:: esp32c3 - - .. warning:: - - 本文档尚未针对 ESP32-C3 进行更新。 - 概述 -------- SD/SDIO/MMC 驱动是一种基于 SDMMC 和 SD SPI 主机驱动的协议级驱动程序,目前已支持 SD 存储器、SDIO 卡和 eMMC 芯片。 -SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`driver/include/driver/sdmmc_host.h`)为以下功能提供 API: +SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`driver/include/driver/sdmmc_host.h` 和 :component_file:`driver/include/driver/sdspi_host.h`)为以下功能提供 API: - 发送命令至从设备 - 接收和发送数据 @@ -22,76 +16,93 @@ SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`driver/include/driv 初始化函数及配置函数: -.. only:: esp32 +.. list:: - - 如需初始化和配置 SDMMC 主机,请参阅 :doc:`SDMMC 主机 API <../peripherals/sdmmc_host>` + :SOC_SDMMC_HOST_SUPPORTED: - 如需初始化和配置 SDMMC 主机,请参阅 :doc:`SDMMC 主机 API <../peripherals/sdmmc_host>` + - 如需初始化和配置 SD SPI 主机,请参阅 :doc:`SD SPI 主机 API <../peripherals/sdspi_host>` -- 如需初始化和配置 SD SPI 主机,请参阅 :doc:`SD SPI 主机 API <../peripherals/sdspi_host>` +.. only:: SOC_SDMMC_HOST_SUPPORTED -本文档中所述的 SDMMC 协议层仅处理 SD 协议相关事项,例如卡初始化和数据传输命令。 + 本文档中所述的 SDMMC 协议层仅处理 SD 协议相关事项,例如卡初始化和数据传输命令。 + + 协议层通过 :cpp:class:`sdmmc_host_t` 结构体和主机协同工作,该结构体包含指向主机各类函数的指针。 -协议层通过 :cpp:class:`sdmmc_host_t` 结构体和主机协同工作,该结构体包含指向主机各类函数的指针。 应用示例 ------------------- ESP-IDF :example:`storage/sd_card` 目录下提供了 SDMMC 驱动与 FatFs 库组合使用的示例,演示了先初始化卡,然后使用 POSIX 和 C 库 API 向卡读写数据。请参考示例目录下 README.md 文件,查看更多详细信息。 -协议层 API ------------------- +.. only:: SOC_SDMMC_HOST_SUPPORTED -协议层具备 :cpp:class:`sdmmc_host_t` 结构体,此结构体描述了 SD/MMC 主机驱动,列出了其功能,并提供指向驱动程序函数的指针。协议层将卡信息储存于 :cpp:class:`sdmmc_card_t` 结构体中。向 SD/MMC 主机发送命令时,协议层调用时需要一个 :cpp:class:`sdmmc_command_t` 结构体来描述命令、参数、预期返回值和需传输的数据(如有)。 + 协议层 API + ------------------ -用于 SD 存储卡的 API -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 协议层具备 :cpp:class:`sdmmc_host_t` 结构体,此结构体描述了 SD/MMC 主机驱动,列出了其功能,并提供指向驱动程序函数的指针。协议层将卡信息储存于 :cpp:class:`sdmmc_card_t` 结构体中。向 SD/MMC 主机发送命令时,协议层使用 :cpp:class:`sdmmc_command_t` 结构体来描述命令、参数、预期返回值和需传输的数据(如有)。 -1. 初始化主机,请调用主机驱动函数,例如 :cpp:func:`sdmmc_host_init` 和 :cpp:func:`sdmmc_host_init_slot`; -2. 初始化卡,请调用 :cpp:func:`sdmmc_card_init`,并将参数 ``host`` (即主机驱动信息)和参数 ``card`` (指向 :cpp:class:`sdmmc_card_t` 结构体的指针)传递给此函数。函数运行结束后,将会向 :cpp:class:`sdmmc_card_t` 结构体填充该卡的信息; -3. 读取或写入卡的扇区,请分别调用 :cpp:func:`sdmmc_read_sectors` 和 :cpp:func:`sdmmc_write_sectors`,并将参数 ``card`` (指向卡信息结构的指针)传递给函数; -4. 如果不再使用该卡,请调用主机驱动函数,例如 :cpp:func:`sdmmc_host_deinit`,以禁用主机外设,并释放驱动程序分配的资源。 -用于 eMMC 芯片的 API -^^^^^^^^^^^^^^^^^^^^^^^^^ + 用于 SD 存储卡的 API + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -从协议层的角度而言,eMMC 存储芯片与 SD 存储卡相同。尽管 eMMC 是芯片,不具备卡的外形,但由于协议相似 (`sdmmc_card_t`, `sdmmc_card_init`),用于 SD 卡的一些概念同样适用于 eMMC 芯片。注意,eMMC 芯片不可通过 SPI 使用,因此它与 SD API 主机驱动不兼容。 + 1. 初始化主机,请调用主机驱动函数,例如 :cpp:func:`sdmmc_host_init` 和 :cpp:func:`sdmmc_host_init_slot`; + 2. 初始化卡,请调用 :cpp:func:`sdmmc_card_init`,并将参数 ``host`` (即主机驱动信息)和参数 ``card`` (指向 :cpp:class:`sdmmc_card_t` 结构体的指针)传递给此函数。函数运行结束后,将会向 :cpp:class:`sdmmc_card_t` 结构体填充该卡的信息; + 3. 读取或写入卡的扇区,请分别调用 :cpp:func:`sdmmc_read_sectors` 和 :cpp:func:`sdmmc_write_sectors`,并将参数 ``card`` (指向卡信息结构的指针)传递给函数; + 4. 如果不再使用该卡,请调用主机驱动函数,例如 :cpp:func:`sdmmc_host_deinit`,以禁用主机外设,并释放驱动程序分配的资源。 -如需初始化 eMMC 内存并执行读/写操作,请参照上一章节 SD 卡操作步骤。 -用于 SDIO 卡的 API -^^^^^^^^^^^^^^^^^^^^^^^^^ + 用于 eMMC 芯片的 API + ^^^^^^^^^^^^^^^^^^^^^^^^^ -SDIO 卡初始化和检测过程与 SD 存储卡相同,唯一的区别是 SDIO 模式下数据传输命令不同。 + 从协议层的角度而言,eMMC 存储芯片与 SD 存储卡相同。尽管 eMMC 是芯片,不具备卡的外形,但由于协议相似 (`sdmmc_card_t`, `sdmmc_card_init`),用于 SD 卡的一些概念同样适用于 eMMC 芯片。注意,eMMC 芯片不可通过 SPI 使用,因此它与 SD API 主机驱动不兼容。 -在卡初始化和卡检测(通过运行 :cpp:func:`sdmmc_card_init`)期间,驱动仅配置 SDIO 卡如下寄存器: + 如需初始化 eMMC 内存并执行读/写操作,请参照上一章节 SD 卡操作步骤。 -1. I/O 中止 (0x06) 寄存器:在该寄存器中设置 RES 位可重置卡的 I/O 部分; -2. 总线接口控制 (0x07) 寄存器:如果主机和插槽配置中启用 4 线模式,则驱动程序会尝试在该寄存器中设置总线宽度字段。如果字段设置成功,则从机支持 4 线模式,主机也切换至 4 线模式; -3. 高速(0x13)寄存器:如果主机配置中启用高速模式,则会在该寄存器中设置 SHS 位。 -注意,驱动程序不会在 (1) I/O 使能寄存器和 Int 使能寄存器,及 (2) I/O 块大小中,设置任何位。应用程序可通过调用 :cpp:func:`sdmmc_io_write_byte` 来设置相关位。 + 用于 SDIO 卡的 API + ^^^^^^^^^^^^^^^^^^^^^^^^^ -如需设置卡配置或传输数据,请根据您的具体情况选择下表中的函数: + SDIO 卡初始化和检测过程与 SD 存储卡相同,唯一的区别是 SDIO 模式下数据传输命令不同。 -========================================================================= ================================= ================================= -操作 读函数 写函数 -========================================================================= ================================= ================================= -使用 IO_RW_DIRECT (CMD52) 读写单个字节。 :cpp:func:`sdmmc_io_read_byte` :cpp:func:`sdmmc_io_write_byte` -使用 IO_RW_EXTENDED (CMD53) 的字节模式读写多个字节。 :cpp:func:`sdmmc_io_read_bytes` :cpp:func:`sdmmc_io_write_bytes` -块模式下,使用 IO_RW_EXTENDED (CMD53) 读写数据块。 :cpp:func:`sdmmc_io_read_blocks` :cpp:func:`sdmmc_io_write_blocks` -========================================================================= ================================= ================================= + 在卡初始化和卡检测(通过运行 :cpp:func:`sdmmc_card_init`)期间,驱动仅配置 IO 卡如下寄存器: -使用 :cpp:func:`sdmmc_io_enable_int` 函数,应用程序可启用 SDIO 中断。 + 1. I/O 中止 (0x06) 寄存器:在该寄存器中设置 RES 位可重置卡的 IO 部分; + 2. 总线接口控制 (0x07) 寄存器:如果主机和插槽配置中启用 4 线模式,则驱动程序会尝试在该寄存器中设置总线宽度字段。如果字段设置成功,则从机支持 4 线模式,主机也切换至 4 线模式; + 3. 高速(0x13)寄存器:如果主机配置中启用高速模式,则该寄存器的 SHS 位会被设置。 -在单线模式下使用 SDIO 时,还需要连接 D1 线来启用 SDIO 中断。 + 注意,驱动程序不会在 (1) I/O 使能寄存器和 Int 使能寄存器,及 (2) I/O 块大小中,设置任何位。应用程序可通过调用 :cpp:func:`sdmmc_io_write_byte` 来设置相关位。 -如果您需要应用程序保持等待直至发生 SDIO 中断,请使用 :cpp:func:`sdmmc_io_wait_int` 函数。 + 如需卡配置或传输数据,请根据您的具体情况选择下表中的函数: + .. list-table:: + :widths: 55 25 20 + :header-rows: 1 -复合卡(存储 + SDIO) + * - 操作 + - 函数读取 + - 函数写入 + * - 使用 IO_RW_DIRECT (CMD52) 读写单个字节。 + - :cpp:func:`sdmmc_io_read_byte` + - :cpp:func:`sdmmc_io_write_byte` + * - 使用 IO_RW_EXTENDED (CMD53) 的字节模式读写多个字节。 + - :cpp:func:`sdmmc_io_read_bytes` + - :cpp:func:`sdmmc_io_write_bytes` + * - 块模式下,使用 IO_RW_EXTENDED (CMD53) 读写数据块。 + - :cpp:func:`sdmmc_io_read_blocks` + - :cpp:func:`sdmmc_io_write_blocks` + + 使用 :cpp:func:`sdmmc_io_enable_int` 函数,应用程序可启用 SDIO 中断。在单线模式下使用 SDIO 时,还需要连接 D1 线来启用 SDIO 中断。 + + 如果您需要应用程序保持等待直至发生 SDIO 中断,请使用 :cpp:func:`sdmmc_io_wait_int` 函数。 + + .. only:: esp32 + + 如果您需要与 ESP32 的 SDIO 从设备通信,请使用 ESSL 组件(ESP 串行从设备链接)。请参阅 :doc:`/api-reference/protocols/esp_serial_slave_link` 和 :example:`peripherals/sdio/host`。 + +复合卡(存储 + IO) ^^^^^^^^^^^^^^^^^^^^^^^^^ -该驱动程序不支持 SDIO 复合卡,复合卡会被视为 SDIO 卡。 +该驱动程序不支持 SD 复合卡,复合卡会被视为 IO 卡。 线程安全 @@ -99,6 +110,7 @@ SDIO 卡初始化和检测过程与 SD 存储卡相同,唯一的区别是 SDIO 多数应用程序仅需在一个任务中使用协议层。因此,协议层在 :cpp:class:`sdmmc_card_t` 结构体或在访问 SDMMC 或 SD SPI 主机驱动程序时不使用任何类型的锁。这种锁通常在较高层级实现,例如文件系统驱动程序。 + API 参考 ------------- diff --git a/docs/zh_CN/api-reference/storage/vfs.rst b/docs/zh_CN/api-reference/storage/vfs.rst index 0a7e78a679b5..7e7acb28aa9f 100644 --- a/docs/zh_CN/api-reference/storage/vfs.rst +++ b/docs/zh_CN/api-reference/storage/vfs.rst @@ -1,12 +1,5 @@ .. include:: ../../../../components/vfs/README_CN.rst -应用示例 -------------------- - -`指南`_ (未完成) - -.. _指南: ../../template.html - API 参考 ------------- diff --git a/docs/zh_CN/api-reference/system/console.rst b/docs/zh_CN/api-reference/system/console.rst index a95ba64d7059..b183ef316e78 100644 --- a/docs/zh_CN/api-reference/system/console.rst +++ b/docs/zh_CN/api-reference/system/console.rst @@ -6,7 +6,7 @@ ESP-IDF 提供了 ``console`` 组件,它包含了开发基于串口的交互 - 行编辑,由 `linenoise `_ 库具体实现,它支持处理退格键和方向键,支持回看命令的历史记录,支持命令的自动补全和参数提示。 - 将命令行拆分为参数列表。 -- 参数解析,由 `argtable3 `_ 库具体实现,它支持解析 GNU 样式的命令行参数。 +- 参数解析,由 `argtable3 `_ 库具体实现,该库提供解析 GNU 样式的命令行参数的 API。 - 用于注册和调度命令的函数。 - 帮助创建 REPL (Read-Evaluate-Print-Loop) 环境的函数。 @@ -14,19 +14,17 @@ ESP-IDF 提供了 ``console`` 组件,它包含了开发基于串口的交互 这些功能模块可以一起使用也可以独立使用,例如仅使用行编辑和命令注册的功能,然后使用 ``getopt`` 函数或者自定义的函数来实现参数解析,而不是直接使用 `argtable3 `_ 库。同样地,还可以使用更简单的命令输入方法(比如 ``fgets`` 函数)和其他用于命令分割和参数解析的方法。 - 行编辑 ------ 行编辑功能允许用户通过按键输入来编辑命令,使用退格键删除符号,使用左/右键在命令中移动光标,使用上/下键导航到之前输入的命令,使用制表键(“Tab”)来自动补全命令。 -.. note:: +.. note:: - 此功能依赖于终端应用程序对 ANSI 转移符的支持,显示原始 UART 数据的串口监视器不能与行编辑库一同使用。如果运行 :example:`system/console` 示例程序的时候观察到的输出结果是 ``[6n`` 或者类似的转义字符而不是命令行提示符 ``esp> `` 时,就表明当前的串口监视器不支持 ANSI 转移字符。已知可用的串口监视程序有 GNU screen,minicom 和 idf_monitor.py(可以通过在项目目录下执行 ``idf.py monitor`` 来调用)。 + 此功能依赖于终端应用程序对 ANSI 转义符的支持。因此,显示原始 UART 数据的串口监视器不能与行编辑库一同使用。如果运行 :example:`system/console` 示例程序的时候看到的输出结果是 ``[6n`` 或者类似的转义字符而不是命令行提示符 ``esp> `` 时,就表明当前的串口监视器不支持 ANSI 转义字符。已知可用的串口监视程序有 GNU screen、minicom 和 idf_monitor.py(可以通过在项目目录下执行 ``idf.py monitor`` 来调用)。 前往这里可以查看 `linenoise `_ 库提供的所有函数的描述。 - 配置 ^^^^ @@ -34,12 +32,16 @@ Linenoise 库不需要显式地初始化,但是在调用行编辑函数之前 :cpp:func:`linenoiseClearScreen` - 使用转移字符清除终端屏幕,并将光标定位在左上角。 + 使用转义字符清除终端屏幕,并将光标定位在左上角。 :cpp:func:`linenoiseSetMultiLine` 在单行和多行编辑模式之间进行切换。单行模式下,如果命令的长度超过终端的宽度,会在行内滚动命令文本以显示文本的结尾,在这种情况下,文本的开头部分会被隐藏。单行模式在每次按下按键时发送给屏幕刷新的数据比较少,与多行模式相比更不容易发生故障。另一方面,在单行模式下编辑命令和复制命令将变得更加困难。默认情况下开启的是单行模式。 +:cpp:func:`linenoiseAllowEmpty` + + 设置 linenoise 库收到空行的解析行为,设置为 ``true`` 时返回长度为零的字符串 (``""``) ,设置为 ``false`` 时返回 ``NULL``。默认情况下,将返回长度为零的字符串。 + 主循环 ^^^^^^ @@ -50,7 +52,7 @@ Linenoise 库不需要显式地初始化,但是在调用行编辑函数之前 :cpp:func:`linenoiseFree` - 必须调用此函数才能释放从 :cpp:func:`linenoise` 函数获取的命令行缓冲。 + 必须调用此函数才能释放从 :cpp:func:`linenoise` 函数获取的命令行缓冲区。 提示和补全 @@ -109,7 +111,7 @@ Linenoise 库不需要显式地初始化,但是在调用行编辑函数之前 - 参数由空格分隔 - 如果参数本身需要使用空格,可以使用 ``\`` (反斜杠)对它们进行转义 - 其它能被识别的转义字符有 ``\\`` (显示反斜杠本身)和 ``\"`` (显示双引号) -- 可以使用双引号来引用参数,引号只可能出现在参数的开头和结尾。参数中的引号必须如上所述进行转移。参数周围的引号会被 :cpp:func:`esp_console_split_argv` 函数删除 +- 可以使用双引号来引用参数,引号只可能出现在参数的开头和结尾。参数中的引号必须如上所述进行转义。参数周围的引号会被 :cpp:func:`esp_console_split_argv` 函数删除 示例: @@ -160,11 +162,11 @@ Linenoise 库不需要显式地初始化,但是在调用行编辑函数之前 初始化 REPL 环境 ---------------- -``console`` 组建还提供了一些 API 来帮助创建一个基本的 REPL 环境。 +除了上述的各种函数,``console`` 组件还提供了一些 API 来帮助创建一个基本的 REPL 环境。 -在一个典型的 console 应用中,你只需要调用 :cpp:func:`esp_console_new_repl_uart`,它会为你初始化好构建在 UART 基础上的 REPL 环境,其中包括安装 UART 驱动,基本的 console 配置,创建一个新的线程来执行 REPL 任务,注册一些基本的命令(比如 `help` 命令)。 +在一个典型的 console 应用中,你只需要调用 :cpp:func:`esp_console_new_repl_uart`,它会为你初始化好构建在 UART 基础上的 REPL 环境,其中包括安装 UART 驱动,基本的 console 配置,创建一个新的线程来执行 REPL 任务,注册一些基本的命令(比如 `help` 命令)。 -完了之后你可以使用 :cpp:func:`esp_console_cmd_register` 来注册其它命令。REPL 环境在初始化后需要再调用 :cpp:func:`esp_console_start_repl` 函数才能开始运行。 +之后你可以使用 :cpp:func:`esp_console_cmd_register` 来注册其它命令。REPL 环境在初始化后需要再调用 :cpp:func:`esp_console_start_repl` 函数才能开始运行。 应用程序示例 diff --git a/docs/zh_CN/api-reference/system/ota.rst b/docs/zh_CN/api-reference/system/ota.rst index de7e0f6dba92..184f6a830cb8 100644 --- a/docs/zh_CN/api-reference/system/ota.rst +++ b/docs/zh_CN/api-reference/system/ota.rst @@ -5,9 +5,9 @@ OTA 流程概览 ------------ -OTA 升级机制可以让设备在固件正常运行时根据接收数据更新(如通过 Wi-Fi 或蓝牙)。 +OTA 升级机制可以让设备在固件正常运行时根据接收数据(如通过 Wi-Fi 或蓝牙)进行自我更新。 -要运行 OTA 机制,需配置设备的 :doc:` 分区表 <../../api-guides/partition-tables>`,该分区表至少包括两个 OTA 应用程序分区(即 `ota_0` 和 `ota_1`)和一个 OTA 数据分区。 +要运行 OTA 机制,需配置设备的 :doc:`分区表 <../../api-guides/partition-tables>`,该分区表至少包括两个 OTA 应用程序分区(即 `ota_0` 和 `ota_1`)和一个 OTA 数据分区。 OTA 功能启动后,向当前未用于启动的 OTA 应用分区写入新的应用固件镜像。镜像验证后,OTA 数据分区更新,指定在下一次启动时使用该镜像。 @@ -16,9 +16,9 @@ OTA 功能启动后,向当前未用于启动的 OTA 应用分区写入新的 OTA 数据分区 ------------ -所有使用 OTA 功能项目,其 :doc:` 分区表 <../../api-guides/partition-tables>`必须包含一个 OTA 数据分区 (类型为 ``data``,子类型为 ``ota``)。 +所有使用 OTA 功能项目,其 :doc:`分区表 <../../api-guides/partition-tables>` 必须包含一个 OTA 数据分区(类型为 ``data``,子类型为 ``ota``)。 -工厂启动设置下,OTA 数据分区中应没有数据(所有字节擦写成 0xFF)。如果分区表中有工厂应用程序,ESP-IDF 软件启动加载器会启动工厂应用程序。如果分区表中没有工厂应用程序,则启动第一个可用的 OTA 分区(通常是 ``ota_0``)。 +工厂启动设置下,OTA 数据分区中应没有数据(所有字节擦写成 0xFF)。如果分区表中有工厂应用程序,ESP-IDF 软件引导加载程序会启动工厂应用程序。如果分区表中没有工厂应用程序,则启动第一个可用的 OTA 分区(通常是 ``ota_0``)。 第一次 OTA 升级后,OTA 数据分区更新,指定下一次启动哪个 OTA 应用程序分区。 @@ -29,10 +29,10 @@ OTA 数据分区是两个 0x2000 字节大小的 flash 扇区,防止写入时 应用程序回滚 ------------ -应用程序回滚的主要目的是确保设备更新后正常运转。该功能可使设备在更新新版本后出现严重错误时,回滚到之前正常运行的应用版本。回滚使能,OTA 升级,应用更新至新版本,之后可能有以下三种情况: +应用程序回滚的主要目的是确保设备在更新后正常工作。如果新版应用程序出现严重错误,该功能可使设备回滚到之前正常运行的应用版本。在使能回滚并且 OTA 升级应用程序至新版本后,可能出现的结果如下: -* 应用程序运行正常 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 将应用程序状态标记为 ``ESP_OTA_IMG_VALID``,启动无限制。 -* 应用程序出现严重错误,无法继续工作,必须回滚到此前的版本,:cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 将正在运行的版本标记为 ``ESP_OTA_IMG_INVALID`` 然后复位。启动加载器不会选取此版本,而是此前正常运行的版本。 +* 应用程序运行正常,:cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 将正在运行的应用程序状态标记为 ``ESP_OTA_IMG_VALID``,启动此应用程序无限制。 +* 应用程序出现严重错误,无法继续工作,必须回滚到此前的版本,:cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 将正在运行的版本标记为 ``ESP_OTA_IMG_INVALID`` 然后复位。引导加载程序不会选取此版本,而是启动此前正常运行的版本。 * 如果 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能,则无需调用函数便可复位,回滚至之前的应用版本。 注解:应用程序的状态不是写到程序的二进制镜像,而是写到 ``otadata`` 分区。该分区有一个 ``ota_seq`` 计数器,该计数器是 OTA 应用分区的指针,指向下次启动时选取应用所在的分区 (ota_0, ota_1, ...)。 @@ -43,14 +43,14 @@ OTA 数据分区是两个 0x2000 字节大小的 flash 扇区,防止写入时 状态控制了选取启动应用程序的过程: ============================= ======================================================== -状态 启动加载器选取启动应用程序的限制 +状态 引导加载程序选取启动应用程序的限制 ============================= ======================================================== ESP_OTA_IMG_VALID 没有限制,可以选取。 ESP_OTA_IMG_UNDEFINED 没有限制,可以选取。 ESP_OTA_IMG_INVALID 不会选取。 ESP_OTA_IMG_ABORTED 不会选取。 ESP_OTA_IMG_NEW 如使能 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE`, - 则仅会选取一次。在启动加载器中,状态立即变为 + 则仅会选取一次。在引导加载程序中,状态立即变为 ``ESP_OTA_IMG_PENDING_VERIFY``。 ESP_OTA_IMG_PENDING_VERIFY 如使能 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE`, 则不会选取,状态变为``ESP_OTA_IMG_ABORTED``。 @@ -67,12 +67,12 @@ Kconfig 中的 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户 * 新版应用程序下载成功,:cpp:func:`esp_ota_set_boot_partition` 函数将分区设为可启动,状态设为 ``ESP_OTA_IMG_NEW``。该状态表示应用程序为新版本,第一次启动需要监测。 * 重新启动 :cpp:func:`esp_restart`。 -* 启动加载器检查新版应用程序,若状态设置为 ``ESP_OTA_IMG_PENDING_VERIFY``,则写入 ``ESP_OTA_IMG_ABORTED``。 -* 启动加载器选取新版应用程序启动,应用程序状态不设置为 ``ESP_OTA_IMG_INVALID`` 或 ``ESP_OTA_IMG_ABORTED``。 -* 启动加载器检查所选取的新版应用程序,若状态设置为 ``ESP_OTA_IMG_NEW``,则写入 ``ESP_OTA_IMG_PENDING_VERIFY``。该状态表示,需确认应用程序的可操作性,如不确认,发生重启,则状态会重写为 ``ESP_OTA_IMG_ABORTED`` (见上文),该应用程序不可再启动,将回滚至上一版本。 +* 引导加载程序检查 ``ESP_OTA_IMG_PENDING_VERIFY`` 状态,如有设置,则将其写入 ``ESP_OTA_IMG_ABORTED``。 +* 引导加载程序选取一个新版应用程序来引导,这样应用程序状态就不会设置为 ``ESP_OTA_IMG_INVALID`` 或 ``ESP_OTA_IMG_ABORTED``。 +* 引导加载程序检查所选取的新版应用程序,若状态设置为 ``ESP_OTA_IMG_NEW``,则写入 ``ESP_OTA_IMG_PENDING_VERIFY``。该状态表示,需确认应用程序的可操作性,如不确认,发生重启,则状态会重写为 ``ESP_OTA_IMG_ABORTED`` (见上文),该应用程序不可再启动,将回滚至上一版本。 * 新版应用程序启动,应进行自测。 * 若通过自测,则必须调用函数 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback`,因为新版应用程序在等待确认其可操作性 (``ESP_OTA_IMG_PENDING_VERIFY`` 状态)。 -* 若未通过自测,则调用函数 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`,回滚至之前的版本,同时无效的新版本设置为 ``ESP_OTA_IMG_INVALID``。 +* 若未通过自测,则调用函数 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`,回滚至之前能正常工作的应用程序版本,同时将无效的新版本应用程序设置为 ``ESP_OTA_IMG_INVALID``。 * 如果新版应用程序可操作性没有确认,则状态一直为 ``ESP_OTA_IMG_PENDING_VERIFY``。下一次启动时,状态变更为 ``ESP_OTA_IMG_ABORTED``,阻止其再次启动,之后回滚到之前的版本。 意外复位 @@ -91,7 +91,7 @@ Kconfig 中的 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户 * 获取最后一个无效应用分区 :cpp:func:`esp_ota_get_last_invalid_partition`。 * 将获取的分区传递给 :cpp:func:`esp_ota_set_boot_partition`,更新 ``otadata``。 -* 重启 :cpp:func:`esp_restart`。启动加载器会启动指定应用程序。 +* 重启 :cpp:func:`esp_restart`。引导加载程序会启动指定应用程序。 要确定是否在应用程序启动时进行自测,可以调用 :cpp:func:`esp_ota_get_state_partition` 函数。如果结果为 ``ESP_OTA_IMG_PENDING_VERIFY``,则需要自测,后续确认应用程序的可操作性。 @@ -105,7 +105,7 @@ Kconfig 中的 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户 * 如果 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 没有使能,``ESP_OTA_IMG_NEW`` 由函数 :cpp:func:`esp_ota_set_boot_partition` 设置。 * ``ESP_OTA_IMG_INVALID`` 由函数 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 设置。 * 如果应用程序的可操作性无法确认,发生重启(:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能),则设置 ``ESP_OTA_IMG_ABORTED``。 -* 如果 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能,选取的应用程序状态为 ``ESP_OTA_IMG_NEW``,则在启动加载器中设置 ``ESP_OTA_IMG_PENDING_VERIFY``。 +* 如果 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能,选取的应用程序状态为 ``ESP_OTA_IMG_NEW``,则在引导加载程序中设置 ``ESP_OTA_IMG_PENDING_VERIFY``。 .. _anti-rollback: @@ -114,7 +114,7 @@ Kconfig 中的 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户 防回滚机制可以防止回滚到安全版本号低于芯片 eFuse 中烧录程序的应用程序版本。 -设置 :ref:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK`,启动防回滚机制。在启动加载器中选取可启动的应用程序,会额外检查芯片和应用程序镜像的安全版本号。可启动固件中的应用安全版本号必须等于或高于芯片中的应用安全版本号。 +设置 :ref:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK`,启动防回滚机制。在引导加载程序中选取可启动的应用程序,会额外检查芯片和应用程序镜像的安全版本号。可启动固件中的应用安全版本号必须等于或高于芯片中的应用安全版本号。 :ref:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK` 和 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 一起使用。此时,只有安全版本号等于或高于芯片中的应用安全版本号时才会回滚。 @@ -127,7 +127,7 @@ Kconfig 中的 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户 - 下载新版应用程序。 - 运行函数 :cpp:func:`esp_ota_set_boot_partition`,将新版应用程序设为可启动。如果新版应用程序的安全版本号低于芯片中的应用安全版本号,新版应用程序会被擦除,无法更新到新固件。 - 重新启动。 -- 在启动加载器中选取安全版本号等于或高于芯片中应用安全版本号的应用程序。如果 otadata 处于初始阶段,通过串行通道加载了安全版本号高于芯片中应用安全版本号的固件,则启动加载器中 eFuse 的安全版本号会立即更新。 +- 在引导加载程序中选取安全版本号等于或高于芯片中应用安全版本号的应用程序。如果 otadata 处于初始阶段,通过串行通道加载了安全版本号高于芯片中应用安全版本号的固件,则引导加载程序中 eFuse 的安全版本号会立即更新。 - 新版应用程序启动,之后进行可操作性检测,如果通过检测,则调用函数 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback`,将应用程序标记为 ``ESP_OTA_IMG_VALID``,更新芯片中应用程序的安全版本号。注意,如果调用函数 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`,可能会因为设备中没有可启动的应用程序而回滚失败,返回 ``ESP_ERR_OTA_ROLLBACK_FAILED`` 错误,应用程序状态一直为 ``ESP_OTA_IMG_PENDING_VERIFY``。 - 如果运行的应用程序处于 ``ESP_OTA_IMG_VALID`` 状态,则可再次更新。 @@ -183,7 +183,7 @@ Kconfig 中的 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户 没有安全启动的安全 OTA 升级 --------------------------- -即便硬件安全启动没有使能,也可验证已签名的 OTA 升级 +即便硬件安全启动没有使能,也可验证已签名的 OTA 升级。可通过设置 :ref:`CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT` 和 :ref:`CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT` 实现。 .. only:: esp32 @@ -202,7 +202,7 @@ OTA 工具 (otatool.py) - 写入 OTA 分区 (write_ota_partition) - 读取 OTA 分区 (read_ota_partition) -用户若想通过编程方式完成相关操作,可从另一个 Python 脚本导入并使用分区工具,或者从 Shell 脚本调用分区工具。前者可使用工具的 Python API,后者可使用命令行界面。 +用户若想通过编程方式完成相关操作,可从另一个 Python 脚本导入并使用该 OTA 工具,或者从 Shell 脚本调用该 OTA 工具。前者可使用工具的 Python API,后者可使用命令行界面。 Python API ^^^^^^^^^^ @@ -220,7 +220,7 @@ Python API sys.path.append(otatool_dir) # 使能 Python 寻找 otatool 模块 from otatool import * # 导入 otatool 模块内的所有名称 -要使用 OTA 工具的 Python API,第一步是创建 `OtatoolTarget`: +要使用 OTA 工具的 Python API,第一步是创建 `OtatoolTarget` 对象: .. code-block:: python @@ -302,4 +302,3 @@ API 参考 -------- .. include-build-file:: inc/esp_ota_ops.inc - diff --git a/docs/zh_CN/conf.py b/docs/zh_CN/conf.py index a13d6d79f962..cc6fbc27121a 100644 --- a/docs/zh_CN/conf.py +++ b/docs/zh_CN/conf.py @@ -14,9 +14,13 @@ sys.path.insert(0, os.path.abspath('..')) from conf_common import * # noqa: F403,F401 +import datetime + +current_year = datetime.datetime.now().year + # General information about the project. project = u'ESP-IDF 编程指南' -copyright = u'2016 - 2021 乐鑫信息科技(上海)股份有限公司' +copyright = u'2016 - {} 乐鑫信息科技(上海)股份有限公司'.format(current_year) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/zh_CN/contribute/documenting-code.rst b/docs/zh_CN/contribute/documenting-code.rst index 029c9a27e5c5..4826b31d2fc8 100644 --- a/docs/zh_CN/contribute/documenting-code.rst +++ b/docs/zh_CN/contribute/documenting-code.rst @@ -8,7 +8,7 @@ 概述 ---- -在项目库内编写代码文档时,请遵循 `Doxygen 代码注释风格 `_。要采用这一风格,您可以将 ``@param`` 等特殊命令插入到标准注释块中,比如: :: +在项目库内编写代码文档时,请遵循 `Doxygen 代码注释风格 `_。要采用这一风格,您可以将 ``@param`` 等特殊命令插入到标准注释块中,比如:: /** * @param ratio this is oxygen to air ratio @@ -42,7 +42,7 @@ Doxygen 支持多种排版风格,对于文档中可以包含的细节非常灵 在本项目库编写代码文档时,请遵守下列准则。 -1. 写明代码的基本内容:函数、结构、类型定义、枚举、宏等。请详细说明代码的用途、功能和限制,因为在阅读他人的文档时你也想看到这些信息。 +1. 写明代码的基本内容:函数、结构体、类型定义、枚举、宏等。请详细说明代码的用途、功能和限制,因为在阅读他人的文档时你也想看到这些信息。 2. 函数文档需简述该函数的功能,并解释输入参数和返回值的含义。 @@ -213,7 +213,7 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 .. note:: - `interactive shell`_ 使用的字体和 esp-idf 文档使用的字体略有不同。 + `interactive shell`_ 使用的字体和 esp-idf 文档使用的字体渲染后显示的效果略有不同。 添加注释 @@ -221,7 +221,7 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 写文档时,您可能需要: -- 留下建议,说明之后需添加会修改哪些内容。 +- 留下建议,说明之后哪些内容需要添加或修改。 - 提醒自己或其他人跟进。 这时,您可以使用 ``.. todo::`` 命令在 reST 文件中添加待做事项。如: @@ -250,7 +250,6 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 乐鑫各芯片的文档是基于现有文档完成的。为提高文档写作效率,使所写文档可重复用于其它芯片(以下称“目标”)文档中,我们为您提供以下功能: - 依据目标类型排除内容 """"""""""""""""""""" @@ -260,6 +259,7 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 * esp32 * esp32s2 +* esp32c3 从 'sdkconfig.h' 中定义标识符,标识符由目标的默认 menuconfig 设置生成,例如: @@ -278,9 +278,7 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 ESP32 specific content. -该指令也支持布尔逻辑操作符 'and'、'or' 和 'not'。 - -示例: +该指令也支持布尔逻辑操作符 'and'、'or' 和 'not'。示例: .. code-block:: none @@ -305,9 +303,9 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 .. _section_2_label: - .. only:: esp32s2 + .. only:: not esp32 - _section_2_label: + .. _section_2_label: Section 2 ^^^^^^^^^ @@ -331,7 +329,6 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 对此推荐的解决方案是:将这个文档添加到 :idf_file:`docs/conf_common.py` ``conditional_include_dict`` 中的一个列表里,例如,一个仅供支持蓝牙的目标可见的文档应被添加至 ``BT_DOCS``。此后,如果该文档未设置对应的标签,则 :idf_file:`docs/idf_extensions/exclude_docs.py` 会将其添加至 ``exclude_patterns``。 - 如果你需要从一个列表或项目符号条目中排除某一内容,应通过在 ''.. list:: '' 指令中使用 '':TAG:'' 角色来完成。 .. code-block:: none @@ -357,13 +354,13 @@ CI build 脚本中添加了检查功能,查找 RST 文件中的硬编码链接 This is a {IDF_TARGET_NAME}, with /{IDF_TARGET_PATH_NAME}/soc.c, compiled with `{IDF_TARGET_TOOLCHAIN_PREFIX}-gcc` with `CONFIG_{IDF_TARGET_CFG_PREFIX}_MULTI_DOC`. -这一扩展也支持定义本地(在单个源文件中)替代名称的标记。请在 RST 文件的一行中插入下示定义语言: +这一扩展也支持定义本地(在单个源文件中)替代名称的标记。请在 RST 文件的一行中插入以下定义语言: - {\IDF_TARGET_SUFFIX:default="DEFAULT_VALUE", esp32="ESP32_VALUE", esp32s2="ESP32S2_VALUE"} + {\IDF_TARGET_SUFFIX:default="DEFAULT_VALUE", esp32="ESP32_VALUE", esp32s2="ESP32S2_VALUE", esp32c3="ESP32C3_VALUE"} 这样将在当前的 RST 文件中根据目标类型为 {\IDF_TARGET_SUFFIX} 标签定义一个替代名称。例如: - {\IDF_TARGET_TX_PIN:default="IO3", esp32="IO4", esp32s2="IO5"} + {\IDF_TARGET_TX_PIN:default="IO3", esp32="IO4", esp32s2="IO5", esp32c3="IO6"} 上例将为 {\IDF_TARGET_TX_PIN} 标签定义一个替代名称,当使用 esp32s2 标签调用 sphinx 时,{\IDF_TARGET_TX_PIN} 将被替代为 "IO5"。 @@ -407,8 +404,8 @@ Sphinx 新手怎么办 1. Doxygen - http://doxygen.nl/ 2. Sphinx - https://github.com/sphinx-doc/sphinx/#readme-for-sphinx 3. Breathe - https://github.com/michaeljones/breathe#breathe -4. Document theme "sphinx_idf_theme" - https://github.com/rtfd/sphinx_idf_theme -5. Custom 404 page "sphinx-notfound-page" - https://github.com/rtfd/sphinx-notfound-page +4. "sphinx_idf_theme" 文档主题 - https://github.com/espressif/sphinx_idf_theme +5. "sphinx-notfound-page" 自定义 404 页面 - https://github.com/readthedocs/sphinx-notfound-page 6. Blockdiag - http://blockdiag.com/en/index.html 7. Recommonmark - https://github.com/rtfd/recommonmark @@ -500,7 +497,6 @@ Doxygen 的安装取决于操作系统: 生成后的文档将位于 ``_build///html`` 文件夹中。如需查阅,请在网页浏览器中打开该目录里的 ``index.html``。 - 生成文档子集 """""""""""""" @@ -520,7 +516,6 @@ Doxygen 的安装取决于操作系统: 请注意,这一功能仅用于文档写作过程中的检查和测试。其生成的 HTML 页面并非渲染完成后的格式,比如,运行这一指令并不会生成一个列有所有文档的索引,而且如果其中涉及到任何还未生成的文档参考都将导致错误警报出现。 - 生成 PDF """""""""""" diff --git a/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst b/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst index 271e23d320c7..ad390e807e20 100644 --- a/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst +++ b/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst @@ -11,7 +11,7 @@ ESP32-DevKitC V4 入门指南 * :ref:`ESP32-DevKitC V4 开发板 ` * USB A / micro USB B 数据线 -* PC(Windows、Linux 或 Mac OS) +* PC(Windows、Linux 或 macOS) 您可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 @@ -35,7 +35,6 @@ ESP32-DevKitC V4 是 `乐鑫 `_ 一款基于 ESP32 的小 - `ESP32-WROVER-E `_ - `ESP32-WROVER-IE `_ - - 可选排针或排母 详情请见 `乐鑫产品选型工具 `__。 @@ -83,7 +82,7 @@ ESP32-DevKitC V4(板载 ESP32-WROOM-32) .. note:: - 管脚 GPIO16 和 GPIO17 仅适用于板载 ESP32-WROOM 系列和 ESP32-SOLO-1 的开发板,保留内部使用。 + 管脚 GPIO16 和 GPIO17 仅适用于板载 ESP32-WROOM 系列和 ESP32-SOLO-1 的开发板,板载 ESP32-WROVER 系列开发板的管脚 GPIO16 和 GPIO17 保留内部使用。 电源选项 @@ -126,6 +125,7 @@ ESP32-DevKitC V4 上电前,请首先确认开发板完好无损。 现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至您的开发板。 + 开发板尺寸 ------------- @@ -144,9 +144,10 @@ ESP32-DevKitC 开发板尺寸 -- 仰视图 * `《ESP32 技术规格书》 `_ (PDF) * `《ESP32-WROOM-32 技术规格书》 `_ (PDF) * `《ESP32-WROOM-32D & ESP32-WROOM-32U 技术规格书》 `_ (PDF) +* `《ESP32-WROOM-DA 技术规格书》 `_ (PDF) * `《ESP32-WROVER 技术规格书》 `_ (PDF) * `《ESP32-WROVER-B 技术规格书》 `_ (PDF) -* `乐鑫产品选型工具 `__ +* `乐鑫产品选型工具 `_ .. toctree:: :hidden: diff --git a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst b/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst index deb5dd54c114..3c66f3acdbbb 100644 --- a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst +++ b/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst @@ -422,6 +422,12 @@ USB 供电 使能 UART 通信 现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至您的开发板。 +以下链接提供了与 ESP-WROVER-KIT 开发板硬件相关的示例: + +* 板上 LCD 示例::example:`peripherals/spi_master/lcd` +* SD 卡槽示例: :example:`storage/sd_card` +* 摄像头示例:https://github.com/espressif/esp32-camera + 相关文档 ----------------- diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst index b7e1ea57390b..f4e1670afb27 100644 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst +++ b/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst @@ -8,7 +8,7 @@ ESP32-S2-DevKitM-1(U) ESP32-S2-DevKitM-1(U) 是一款基于 `ESP32-S2FH4 `__ 芯片(ESP32-S2 系列)的通用型开发板。该款开发板具有丰富的外设和优化的引脚布局,令产品开发更快捷。 -ESP32-S2-DevKitM-1 搭载的是 `ESP32-S2-MINI-1 `__ 模组 (PCB 板载天线),ESP32-S2-DevKitM-1U 搭载的是 `ESP32-S2-MINI-1U `__ 模组 (U.FL 座子连接外部 IPEX 天线)。 +ESP32-S2-DevKitM-1 搭载的是 `ESP32-S2-MINI-1 `__ 模组 (PCB 板载天线),ESP32-S2-DevKitM-1U 搭载的是 `ESP32-S2-MINI-1U `__ 模组 (外部天线连接器)。 +----------------------+-----------------------+ | |ESP32-S2-DevKitM-1| | |ESP32-S2-DevKitM-1U| | @@ -24,6 +24,7 @@ ESP32-S2-DevKitM-1 搭载的是 `ESP32-S2-MINI-1 `_ 的外部天线连接器尺寸章节。 开始开发应用 ------------ @@ -110,11 +113,15 @@ ESP32-S2-DevKitM-1(U) 是乐鑫一款搭载 ESP32-S2-MINI-1 或 ESP32-S2-MINI-1U - ESP32-S2-DevKitM-1(U) - + 如使用 ESP32-S2-DevKitM-1U,还需准备 IPEX 天线 + + 如使用 ESP32-S2-DevKitM-1U,还需准备天线 -- USB 2.0 数据线(标准 A 型转 Micro-B型) +- USB 2.0 数据线(标准 A 型转 Micro-B 型) - 电脑 (Windows、Linux 或 macOS) +.. 注解:: + + 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 + 软件设置 ^^^^^^^^ @@ -145,46 +152,46 @@ ESP32-S2-DevKitM-1(U) 的主要组件和连接方式如下图所示。 您可从以下三种供电方式中任选其一给 ESP32-S2-DevKitM-1(U) 供电: -- Micro USB 端口供电(默认) -- 5V 和 GND 管脚供电 -- 3V3 和 GND 管脚供电 +- Micro-USB 接口供电(默认) +- 5V 和 GND 排针供电 +- 3V3 和 GND 排针供电 -建议选择第一种供电方式:Micro USB 端口供电。 +建议选择第一种供电方式:Micro-USB 接口供电。 .. _user-guide-devkitm-1-v1-header-blocks: 排针 ---- -下表列出了开发板两侧排针的 **名称** 和 **功能**,开发板排针图可前往 :ref:`user-guide-devkitm-1-v1-board-front` 查看。表格中的序号和名称与 `ESP32-S2-DevKitM-1(U) 原理图 `_ (PDF)一致。 +下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-devkitm-1-v1-board-front` 所示,排针的序号与 `ESP32-S2-DevKitM-1(U) 原理图 `_ (PDF)一致。 J1 ^^^ -==== ==== ===== ============================================================ -序号 名称 类型 功能 -==== ==== ===== ============================================================ -1 3V3 P 3.3 V 电源 -2 0 I/O/T RTC_GPIO0, GPIO0 -3 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 -4 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 -5 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 -6 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 -7 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 -8 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 -9 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 -10 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 -11 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD -12 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 -13 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 -14 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 -15 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 -16 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS -17 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P -18 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N -19 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 -20 5V P 5 V 电源 -21 G G 接地 -==== ==== ===== ============================================================ +==== ==== ========= ========================================================================= +序号 名称 类型 [#]_ 功能 +==== ==== ========= ========================================================================= +1 3V3 P 3.3 V 电源 +2 0 I/O/T RTC_GPIO0, GPIO0 +3 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 +4 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 +5 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 +6 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 +7 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 +8 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 +9 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 +10 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 +11 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD +12 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 +13 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 +14 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 +15 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 +16 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS +17 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P +18 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N +19 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 +20 5V P 5 V 电源 +21 G G 接地 +==== ==== ========= ========================================================================= J3 ^^^ @@ -211,9 +218,26 @@ J3 18 21 I/O/T RTC_GPIO21, GPIO21 19 20 I/O/T RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ 20 19 I/O/T RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D- -21 18 I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3 +21 18 I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3, RGB LED ==== ==== ===== ======================================================== +.. [#] P:电源;I:输入;O:输出;T:可设置为高阻。 + +管脚布局 +^^^^^^^^ +.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-pin-layout.png + :align: center + :scale: 15% + :alt: ESP32-S2-DevKitM-1(U) 管脚布局(点击放大) + :figclass: align-center + + ESP32-S2-DevKitM-1(U) 管脚布局(点击放大) + +硬件版本 +========== + +无历史版本。 + 相关文档 ======== * `ESP32-S2-DevKitM-1(U) 原理图 `_ (PDF) @@ -223,4 +247,4 @@ J3 * `ESP32-S2-MINI-1 & ESP32-S2-MINI-1U 技术规格书 `_ (PDF) * `乐鑫产品选型工具 `__ -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 +有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst index 4379c1d59f7d..2faed9f0e283 100644 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst +++ b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst @@ -1,10 +1,12 @@ -======================= -ESP32-S2-Kaluga-1 套件 -======================= +============================= +ESP32-S2-Kaluga-1 套件 v1.2 +============================= :link_to_translation:`en:[English]` -ESP32-S2-Kaluga-1 是一款来自乐鑫的开发套件,主要可用于以下目的: +最新版本::doc:`user-guide-esp32-s2-kaluga-1-kit` + +ESP32-S2-Kaluga-1 v1.2 是一款来自乐鑫的开发套件,主要可用于以下目的: - 展示 ESP32-S2 芯片的人机交互功能 - 为用户提供基于 ESP32-S2 的人机交互应用开发工具 @@ -22,7 +24,7 @@ ESP32-S2 的功能强大,应用场景非常丰富。对于初学者来说, :width: 3452px :height: 1590px :scale: 20% - :alt: ESP32-S2-Kaluga-1 套装装配图 + :alt: ESP32-S2-Kaluga-1-Kit-Assembly :figclass: align-center ESP32-S2-Kaluga-1-Kit 概述(点击放大) @@ -33,18 +35,20 @@ ESP32-S2-Kaluga-1 套件包括以下几个开发板: - 主板:*ESP32-S2-Kaluga-1* - 扩展板: - - :doc:`ESP-LyraT-8311A ` 音频播放器 - - :doc:`ESP-LyraP-TouchA ` 触摸板 - - :doc:`ESP-LyraP-LCD32 ` 3.2" LCD 屏 - - :doc:`ESP-LyraP-CAM ` 摄像头 + - :doc:`user-guide-esp-lyrat-8311a_v1.2` - 音频播放器 + - :doc:`user-guide-esp-lyrap-toucha-v1.1` - 触摸板 + - :doc:`user-guide-esp-lyrap-lcd32-v1.1` - 3.2" LCD 屏 + - :doc:`user-guide-esp-lyrap-cam-v1.0` - 摄像头 + +由于 ESP32-S2 的管脚复用,部分扩展板的兼容性有所限制,具体请见 :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-ext-board-compatibility`。 -本文档主要介绍** ESP32-S2-Kaluga-1 主板** 及其与扩展板的交互。更多有关具体扩展板的信息,请点击相应的链接。 +本文档主要介绍 **ESP32-S2-Kaluga-1 主板** 及其与扩展板的交互。更多有关具体扩展板的信息,请点击相应的链接。 本指南包括: - `快速入门`_:提供 ESP32-S2-Kaluga-1 的简要概述及必须了解的硬件和软件信息。 - `硬件参考`_:提供 ESP32-S2-Kaluga-1 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 +- `硬件修订历史`_:提供该开发板的“修订历史”、“已知问题”以及此开发板之前版本的用户指南链接。 - `相关文档`_:提供相关文档的链接。 @@ -52,7 +56,7 @@ ESP32-S2-Kaluga-1 套件包括以下几个开发板: ======== -本节介绍如何开始使用 ESP32-S2-Kaluga-1,主要包括三大部分:首先,介绍一些关于 ESP32-S2-Kaluga-1 的基本信息,然后在 `应用程序开发`_ 章节介绍如何进行硬件初始化,最后介绍如何为 ESP32-S2-Kaluga-1 烧录固件。 +本节介绍如何开始使用 ESP32-S2-Kaluga-1,主要包括三大部分:首先,介绍一些关于 ESP32-S2-Kaluga-1 的基本信息;然后,在 `应用程序开发`_ 章节介绍如何进行硬件初始化;最后,介绍如何为 ESP32-S2-Kaluga-1 烧录固件。 概述 @@ -60,13 +64,13 @@ ESP32-S2-Kaluga-1 套件包括以下几个开发板: ESP32-S2-Kaluga-1 主板是整个套件的核心。该主板集成了 ESP32-S2-WROVER 模组,并配备连接至各个扩展板的连接器。ESP32-S2-Kaluga-1 是人机交互接口原型设计的关键工具。 -ESP32-S2-Kaluga-1 主板配备了多个连接器,可连接至以下扩展板: +ESP32-S2-Kaluga-1 主板配备了多个连接器,可用于连接相应扩展板: -- 其他带有相应连接器的拓展板(比如 ESP-LyraT-8311A 和 ESP-LyraP-LCD32) -- 摄像头拓展板 (ESP-LyraP-CAM) -- 触摸板拓展板 (ESP-LyraP-TouchA) -- LCD 显示屏(敬请期待) -- I2C 设备(敬请期待) +- 扩展板连接器,用于连接 ESP-LyraT-8311A、ESP-LyraP-LCD32 +- 摄像头连接器,用于连接 ESP-LyraP-CAM +- 触摸 FPC 连接器,用于连接 ESP-LyraP-TouchA +- LCD FPC 连接器(尚无可用官方配套扩展板) +- I2C FPC 连接器(尚无可用官方配套扩展板) .. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-3d.png :align: center @@ -80,24 +84,24 @@ ESP32-S2-Kaluga-1 主板配备了多个连接器,可连接至以下扩展板 所有四个扩展板都经过特别设计,以支持以下功能: - * 触摸板控制 - * 集成 14 个触摸传感器,其中 3 个支持距离感应(接近模式) - * 支持最大 5 mm 的亚克力板 - * 湿手操作 - * 防水功能,ESP32-S2 可以配置为在多个触摸板同时被水复盖时自动禁用所有触摸板功能,并在去除水滴后重新启用触摸板 +* 触摸板控制 + * 带有 6 个触摸按钮 + * 支持最大 5 mm 亚克力板 + * 支持湿手操作 + * 支持防水功能。ESP32-S2 可以配置为在多个触摸板同时被水复盖时自动禁用所有触摸板功能,并在去除水滴后重新启用触摸板 - * 音频播放 - * 连接扬声器,以播放音频 - * 配合触控板使用,可控制音频播放和调节音量 +* 音频播放 + * 连接扬声器,以播放音频 + * 配合触控板使用,可控制音频播放和调节音量 - * LCD 显示屏 - * LCD 接口(8 位并行 RGB、8080 和 6800 接口) +* LCD 显示屏 + * LCD 接口(8 位并行 RGB、8080 和 6800 接口) - * 摄像头图像采集 - * 支持 OV2640 和 OV3660 相机模块 - * 8 位 DVP 图像传感器接口(ESP32-S2 还支持 16 位 DVP 图像传感器,但需要您自行进行二次开发) - * 高达 40 MHz 时钟频率 - * 优化 DMA 传输带宽,便于传输高分辨率图像 +* 摄像头图像采集 + * 支持 OV2640 和 OV3660 摄像头模块 + * 8-bit DVP 图像传感器接口(ESP32-S2 还支持 16 位 DVP 图像传感器,但需要您自行进行二次开发) + * 支持高达 40 MHz 时钟频率 + * 优化 DMA 传输带宽,便于传输高分辨率图像 组件描述 @@ -120,55 +124,57 @@ ESP32-S2-Kaluga-1 主板配备了多个连接器,可连接至以下扩展板 .. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - ESP32-S2-WROVER 模组 - - 模块集成 ESP32-S2 芯片,提供 Wi-Fi 连接、数据处理和灵活的数据存储 - * - 4.3" LCD FPC 连接器 - - (保留)使用 FPC 电缆连接至 4.3" LCD 拓展板 - * - ESP Prog 连接器 - - (保留)连接乐鑫固件下载设备 (ESP-Prog),从而向板子上的 ESP32-S2 芯片下载固件 - * - JTAG 开关 - - 切换到 ON 方向,启用 ESP32-S2 和 FT2232 之间的连接 - * - 引出管脚排针 2 - - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板排针(具体请见开发板上的标记) - * - USB 转 UART/JTAG 桥接器 - - FT2232 适配器板,允许在 USB 端口使用 UART/JTAG 协议进行通信 - * - 相机头排针 - - 用于安装摄像头扩展板(例如 ESP-LyraP-CAM) - * - 扩展板排针 - - 用于安装带有配套连接器的其他扩展板 - * - Reset 复位按钮 - - 重启系统 - * - Boot 按钮 - - 按下 **Boot** 键并保持,同时按一下 **Reset** 键,进入“固件下载”模式,通过串口下载固件。 - * - USB-UART/JTAG 端口 - - PC 和 ESP32-S2 模组之间的通信接口(UART 或 JTAG) - * - USB 电源端口 - - 电路板的电源 - * - 电池端口 - - 2 针连接器,连接外部电源 - * - 电源开关 - - 切换到 ON 方向,为系统供电 - * - RGB 跳线 - - 如需使用 RGB LED,需在该位置增加一个跳线 - * - RGB LED - - 可编程 RGB LED,由 GPIO45 控制。在使用前请先安装 RGB 跳线。 - * - 电源调节器 - - 5 V 转 3.3 V 调压器 - * - I2C FPC 连接器 - - (保留)使用 FPC 电缆连接到其他 I2C 扩展板 - * - 引出管脚排针 1 - - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板排针(具体请见开发板上的标记) - * - 触摸 FPC 连接器 - - 使用 FPC 电缆连接 ESP-LyraP-TouchA 扩展板 - * - 触摸开关 - - 切换到 OFF 方向,配置 GPIO1 到 GPIO14 连接触摸传感器;切换到 ON 方向,配置 GPIO1 到 GPIO14 用于其他目的。 - * - 3.2" LCD FPC 连接器 - - 通过 FPC 电缆连接主板和 3.2" LCD 扩展板(例如 ESP-LyraP-LCD32) + :widths: 30 70 + :header-rows: 1 + + * - 主要组件 + - 描述 + * - ESP32-S2-WROVER 模组 + - 集成 ESP32-S2 芯片,可提供 Wi-Fi 连接、数据处理和灵活的数据存储功能。 + * - 4.3" LCD FPC 连接器 + - (保留)可使用 FPC 线连接 4.3" LCD 扩展板。 + * - ESP Prog 连接器 + - (保留)用于连接乐鑫固件烧录设备 (ESP-Prog)。 + * - JTAG 开关 + - 切换到 ON 方向,启用 ESP32-S2 和 FT2232 之间的连接。此时,可通过 USB-UART/JTAG 端口进行 JTAG 调试,详见 :doc:`../../api-guides/jtag-debugging/index`。 + * - 引出管脚排针 2 + - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 + * - USB-to-UART/JTAG 桥接器 + - FT2232 适配器开发板,允许在 USB 端口使用 UART/JTAG 协议通信。 + * - 摄像头连接器 + - 用于连接摄像头扩展板,比如 ESP-LyraP-CAM。 + * - 扩展板连接器 + - 用于连接带有配套连接器的扩展板。 + * - Reset 复位按钮 + - 用于重启系统。 + * - Boot 按钮 + - 按下 **Boot** 键并保持,同时按一下 **Reset** 键,进入“固件下载”模式,通过串口下载固件。 + * - USB-UART/JTAG 端口 + - PC 和 ESP32-S2 模组之间的通信接口(UART 或 JTAG)。 + * - USB 电源端口 + - 为开发板供电。 + * - 电池端口 + - 2 针连接器,用于连接外部电池。 + * - 电源 LED 指示灯 + - 当 USB 电源或外部电源供电电压正常,则 LED 亮起。 + * - 电源开关 + - 打开可为系统供电。 + * - RGB 跳线 + - 如需使用 RGB LED,需在该位置增加一个跳线。 + * - RGB LED 指示灯 + - 可编程 RGB LED 指示灯,受控于 GPIO45。在使用前需要安装 RGB 跳线。 + * - 调压器 + - 5 V 转 3.3 V 调压器。 + * - I2C FPC 连接器 + - (保留)可通过 FPC 线连接其他 I2C 扩展板。 + * - 引出管脚排针 1 + - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 + * - 触摸 FPC 连接器 + - 可通过 FPC 线连接 ESP-LyraP-TouchA 扩展板。 + * - 触摸开关 + - 切换到 OFF 方向,配置 GPIO1 到 GPIO14 连接触摸传感器;切换到 ON 方向,配置 GPIO1 到 GPIO14 用于其他目的。 + * - 3.2" LCD FPC 连接器 + - 可通过 FPC 线连接 3.2" LCD 扩展板,比如 ESP-LyraP-LCD32。 应用程序开发 @@ -195,7 +201,7 @@ ESP32-S2-Kaluga-1 上电前,请首先确认开发板完好无损。 1. 连接您选择的扩展板(更多信息,请见对应拓展板的用户指南) 2. 插入两根 USB 电缆 -3. 打开 **电源开关** 时,**Power On LED** 应点亮。 +3. 打开 **电源开关** 时,**电源 LED 指示灯** 应点亮。 .. _user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup: @@ -224,13 +230,13 @@ ESP32-S2-Kaluga-1 上电前,请首先确认开发板完好无损。 - ESP-LyraP-TouchA - ESP-LyraP-LCD32 - 连接器 - - 20 针 FPC 电缆(用于连接 ESP32-S2-Kaluga-1 主板至 ESP-LyraP-TouchA 拓展板) + - 20 针 FPC 线(用于连接 ESP32-S2-Kaluga-1 主板至 ESP-LyraP-TouchA 扩展板) - 紧固件 - 安装螺栓 (x 8) - 螺丝 (x 4) - 螺母 (x 4) -零售购买,请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 +零售购买,请前往 https://www.espressif.com/zh-hans/contact-us/get-samples。 批发订单 @@ -252,10 +258,10 @@ ESP32-S2-Kaluga-1 的主要组件和连接方式如下图所示。 .. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-block-diagram.png :align: center - :alt: ESP32-S2-Kaluga-1 框图 + :alt: ESP32-S2-Kaluga-1 功能框图 :figclass: align-center - ESP32-S2-Kaluga-1 框图 + ESP32-S2-Kaluga-1 功能框图 电源选项 @@ -264,11 +270,90 @@ ESP32-S2-Kaluga-1 的主要组件和连接方式如下图所示。 开发板可任一选用以下四种供电方式: - Micro USB 端口供电(默认) -- 通过 2 针 *BAT* 连接器连接至外接电池 +- 通过 2 针电池连接器使用外部电池供电 - 5V / GND 管脚供电 - 3V3 / GND 管脚供电 +.. _user-guide-esp32-s2-kaluga-1-kit-v1.2-ext-board-compatibility: + +扩展板的兼容性 +-------------- + +如需同时使用多块扩展板,请首先查看以下兼容性信息: + +.. list-table:: + :widths: 20 10 30 40 + :header-rows: 1 + + * - 扩展板组合 + - 复用接口或管脚 + - 无法运行原因 + - 解决方案 + * - 8311A v1.2 + CAM v1.0 + - I2S 控制、IO46 + - ESP32-S2 仅有 1 个 I2S 接口,但这两个开发板均需使用 ESP32-S2 的 I2S 接口进行通信(ESP-LyraT-8311A 使用标准模式;ESP-LyraP-CAM 使用 Camera 协议)。如两个扩展板同时复用 IO46,ESP-LyraP-CAM 的正常使用将受到干扰。 + - 暂无解决方法。 + * - TouchA v1.1 + LCD32 v1.1 + - IO11、IO6 + - ESP-LyraP-TouchA 因管脚 IO11 复用,导致无法触发触摸动作;ESP-LyraP-LCD32 因 BK (BLCT) 管脚连接至 IO6 管脚复用,因此也无法使用。 + - 不要初始化 ESP-LyraP-TouchA 扩展板的 IO11 (NETWORK) 和 IO6 (PHOTO) 管脚。 + * - 8311A v1.2 + LCD32 v1.1 + - IO6 + - 这两款扩展板可以同时使用,但由于 ESP32-S2-Kaluga-1 的 BK (BLCT) 管脚已连接至 IO6,因此,ESP-LyraT-8311A 的 BT_ADC 管脚和 6 个按钮均无法使用。 + - 用户也可通过以下配置使用 ESP-LyraT-8311A 的 BT_ADC 管脚:移除 ESP-LyraP-LCD32 扩展板上的 R39,将 R41 换为 100 欧,并将 BLCT_L 开关打开。注意,此配置将导致用户无法通过软件控制显示屏的背光亮度。 + * - TouchA v1.1 + 8311A v1.2 + - ESP-LyraT-8311A 的 BT_ADC 管脚 + - 这两款扩展板可以同时使用。然而,当 ESP-LyraT-8311A 的 BT_ADC 管脚用于初始化扩展板的 6 个按钮时,ESP-LyraP-TouchA 无法成功触发。 + - 如果计划使用 ESP-LyraT-8311A 的 BT_ADC 管脚,请不要初始化 ESP-LyraP-TouchA 扩展板的 IO6 管脚 (PHOTO)。 + * - TouchA v1.1 + CAM v1.0 + - IO1、IO2、IO3 + - 由于管脚复用无法同时使用。 + - 不要初始化 ESP-LyraP-TouchA 的 IO1 (VOL_UP)、IO2 (PLAY) 和 IO3 (VOL_DOWN)。 + * - TouchA v1.1 + LCD32 v1.1 + CAM v1.0 + - IO1、IO2、IO3、IO6、IO11 + - 由于管脚复用无法同时使用。 + - **解决方案 1**:不要初始化 ESP-LyraP-TouchA 扩展板的 IO1 (VOL_UP)、IO2 (PLAY)、IO3 (VOL_DOWN)、IO6 (PHOTO) 和 IO11 (NETWORK)。 **解决方案 2**:用户也可通过以下配置正常初始化 IO6 (PHOTO):移除 ESP-LyraP-LCD32 扩展板上的 R39,将 R41 换为 100 欧,并将 BLCT_L 开关打开。注意,此配置将导致用户无法通过软件控制显示屏的背光亮度。 + * - TouchA v1.1 + LCD32 v1.1 + 8311A v1.2 + - IO6、IO11 + - IO11 管脚复用导致无法同时使用;IO6 管脚复用导致 ESP-LyraT-8311A 的 BT_ADC 管脚无法使用,因此无法初始化该扩展板的 6 个按钮。 + - **解决方法 1**:不要初始化 ESP-LyraP-TouchA 扩展板的 IO6 (PHOTO) 和 IO11 (NETWORK)。注意,此时 ESP-LyraT-8311A 的 6 个按钮依然无法使用。**解决方法 2**:移除 ESP-LyraP-LCD32 扩展板上的 R39,将 R41 换为 100 欧,并将 BLCT_L 开关打开。不要初始化 ESP-LyraP-TouchA 的 IO11 (NETWORK)。如果希望使用 ESP-LyraT-8311A 的 6 个按钮,则也不要初始化 IO6 (PHOTO)。 + +另外,所有扩展板和 :ref:`JTAG 接口 ` 共用管脚 IO39、IO40、IO41 和 IO42。因此,以下情况可能会干扰 JTAG 操作: + +* 插上扩展板 +* 调试正在使用扩展板的应用程序 + + +已知问题 +======== + +.. list-table:: + :widths: 22 24 32 22 + :header-rows: 1 + + * - 问题硬件 + - 描述 + - 主要原因 + - 解决方法 + * - ESP-LyraP-CAM v1.0、管脚 IO45、管脚 IO46 + - 当 ESP-LyraP-CAM v1.0 连接至主板时,可能导致主板无法烧录固件。 + - 开发板上电时,strapping 管脚 IO45 和 IO46 的上电时序错误,导致开发板无法正常启动。 + - 主板烧录固件时,不应连接该扩展板。 + * - ESP-LyraP-CAM v1.0、管脚 IO45、管脚 IO46 + - 使用 Reset 复位按键重启开发板可能无法达到期望结果。 + - 开发板上电时,strapping 管脚 IO45 和 IO46 的上电时序错误,导致开发板无法正常启动。 + - v1.2 暂无解决方法。该问题已经在 ESP32-S2-Kaluga-1 V1.3 中进行了修复。 + * - ESP-LyraT-8311A v1.2、管脚 IO46 + - 当 ESP-LyraT-8311A v1.2 连接至主板时,可能导致主板无法烧录固件。 + - 开发板上电时,strapping 管脚 IO46 的上电时序错误,导致开发板无法正常启动。 + - 主板烧录固件时,不应连接该扩展板。 + * - ESP-LyraT-8311A v1.2、管脚 IO46 + - 使用 Reset 复位按键重启开发板可能无法达到期望结果。 + - 开发板上电时,strapping 管脚 IO46 的上电时序错误,导致开发板无法正常启动。 + - v1.2 暂无解决方法。该问题已经在 ESP32-S2-Kaluga-1 V1.3 中进行了修复。 + + 硬件修订历史 ============ @@ -289,9 +374,9 @@ ESP32-S2-Kaluga-1 的主要组件和连接方式如下图所示。 - `ESP32-S2-WROVER 技术规格书 `_ (PDF) - `乐鑫产品选型工具 `__ - :doc:`../../api-guides/jtag-debugging/index` + - `ESP32-S2-Kaluga-1 原理图 `_ (PDF) - `ESP32-S2-Kaluga-1 PCB 布局图 `_ (PDF) -- `ESP32-S2-Kaluga-1 管脚映射表 `_ (Excel) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 +- `ESP32-S2-Kaluga-1 管脚映射 `_ (Excel) +有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 \ No newline at end of file diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst index 4b21b5961bce..7fabe69052ce 100644 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst +++ b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst @@ -1,5 +1,378 @@ -.. include:: ../../../en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst +============================== +ESP32-S2-Kaluga-1 套件 v1.3 +============================== +:link_to_translation:`en:[English]` + +更早版本::doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` + +ESP32-S2-Kaluga-1 v1.3 是一款来自乐鑫的开发套件,主要可用于以下目的: + +- 展示 ESP32-S2 芯片的人机交互功能 +- 为用户提供基于 ESP32-S2 的人机交互应用开发工具 + +ESP32-S2 的功能强大,应用场景非常丰富。对于初学者来说,可能的用例包括: + +- **智能家居**:从最简单的智能照明、智能门锁、智能插座,到更复杂的视频流设备、安防摄像头、OTT 设备和家用电器等 +- **电池供电设备**:Wi-Fi mesh 传感器网络、Wi-Fi 网络玩具、可穿戴设备、健康管理设备等 +- **工业自动化设备**:无线控制与机器人技术、智能照明、HVAC 控制设备等 +- **零售和餐饮业**:POS 机和服务机器人 + +.. Image of v1.2 is used as there are no visual changes + +.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-kit-v1.0-3d.png + :align: center + :width: 3452px + :height: 1590px + :scale: 20% + :alt: ESP32-S2-Kaluga-1-Kit-Assembly + :figclass: align-center + + ESP32-S2-Kaluga-1-Kit 概述(点击放大) + + +ESP32-S2-Kaluga-1 套件包括以下几个开发板: + +- 主板:*ESP32-S2-Kaluga-1* +- 扩展板: + + - :doc:`user-guide-esp-lyrat-8311a_v1.3` - 音频播放器 + - :doc:`user-guide-esp-lyrap-toucha-v1.1` - 触摸板 + - :doc:`user-guide-esp-lyrap-lcd32-v1.2` - 3.2" LCD 屏 + - :doc:`user-guide-esp-lyrap-cam-v1.1` - 摄像头 + +由于 ESP32-S2 的管脚复用,部分扩展板的兼容性有所限制,具体请见 :ref:`user-guide-esp32-s2-kaluga-1-kit-ext-board-compatibility`。 + +本文档主要介绍 **ESP32-S2-Kaluga-1 主板** 及其与扩展板的交互。更多有关具体扩展板的信息,请点击相应的链接。 + +本指南包括: + +- `快速入门`_:提供 ESP32-S2-Kaluga-1 的简要概述及必须了解的硬件和软件信息。 +- `硬件参考`_:提供 ESP32-S2-Kaluga-1 的详细硬件信息。 +- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 +- `相关文档`_:提供相关文档的链接。 + + +快速入门 +======== + + +本节介绍如何开始使用 ESP32-S2-Kaluga-1,主要包括三大部分:首先,介绍一些关于 ESP32-S2-Kaluga-1 的基本信息;然后,在 `应用程序开发`_ 章节介绍如何进行硬件初始化;最后,介绍如何为 ESP32-S2-Kaluga-1 烧录固件。 + + +概述 +---- + +ESP32-S2-Kaluga-1 主板是整个套件的核心。该主板集成了 ESP32-S2-WROVER 模组,并配备连接至各个扩展板的连接器。ESP32-S2-Kaluga-1 是人机交互接口原型设计的关键工具。 + +ESP32-S2-Kaluga-1 主板配备了多个连接器,可用于连接相应扩展板: + +- 扩展板连接器,用于连接 ESP-LyraT-8311A、ESP-LyraP-LCD32 +- 摄像头连接器,用于连接 ESP-LyraP-CAM +- 触摸 FPC 连接器,用于连接 ESP-LyraP-TouchA +- LCD FPC 连接器(尚无可用官方配套扩展板) +- I2C FPC 连接器(尚无可用官方配套扩展板) + +.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32s2-kaluga-1-v1.3-3d.png + :align: center + :width: 3089px + :height: 2335px + :scale: 25% + :alt: ESP32-S2-Kaluga-1 + :figclass: align-center + + ESP32-S2-Kaluga-1(点击放大) + +所有四个扩展板都经过特别设计,以支持以下功能: + +* 触摸板控制 + * 带有 6 个触摸按钮 + * 支持最大 5 mm 亚克力板 + * 支持湿手操作 + * 支持防水功能。ESP32-S2 可以配置为在多个触摸板同时被水复盖时自动禁用所有触摸板功能,并在去除水滴后重新启用触摸板 + +* 音频播放 + * 连接扬声器,以播放音频 + * 配合触控板使用,可控制音频播放和调节音量 + +* LCD 显示屏 + * LCD 接口(8 位并行 RGB、8080 和 6800 接口) + +* 摄像头图像采集 + * 支持 OV2640 和 OV3660 摄像头模块 + * 8-bit DVP 图像传感器接口(ESP32-S2 还支持 16 位 DVP 图像传感器,但需要您自行进行二次开发) + * 支持高达 40 MHz 时钟频率 + * 优化 DMA 传输带宽,便于传输高分辨率图像 + + +组件描述 +-------- + +.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.3-layout-front.png + :align: center + :width: 934px + :height: 645px + :scale: 70% + :alt: ESP32-S2-Kaluga-1 - 正面 + :figclass: align-center + + ESP32-S2-Kaluga-1 - 正面(点击放大) + +.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.3-layout-back.png + :align: center + :width: 934px + :height: 600px + :scale: 70% + :alt: ESP32-S2-Kaluga-1 - 反面 + :figclass: align-center + + ESP32-S2-Kaluga-1 - 反面(点击放大) + + +下表将从左边的 ESP32-S2 模组开始,以顺时针顺序介绍上图中的主要组件。 + +**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 + + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 主要组件 + - 描述 + * - ESP32-S2-WROVER 模组 + - 集成 ESP32-S2 芯片,可提供 Wi-Fi 连接、数据处理和灵活的数据存储功能。 + * - 4.3" LCD FPC 连接器 + - (保留)可使用 FPC 线连接 4.3" LCD 扩展板。 + * - ESP Prog 连接器 + - (保留)用于连接乐鑫固件烧录设备 (ESP-Prog)。 + * - JTAG 开关 + - 切换到 ON 方向,启用 ESP32-S2 和 FT2232 之间的连接。此时,可通过 USB-UART/JTAG 端口进行 JTAG 调试,详见 :doc:`../../api-guides/jtag-debugging/index`。 + * - 引出管脚排针 2 + - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 + * - USB-to-UART/JTAG 桥接器 + - FT2232 适配器开发板,允许在 USB 端口使用 UART/JTAG 协议通信。 + * - 摄像头连接器 + - 用于连接摄像头扩展板,比如 ESP-LyraP-CAM。 + * - 扩展板连接器 + - 用于连接带有配套连接器的扩展板。 + * - Reset 复位按钮 + - 用于重启系统。 + * - Boot 按钮 + - 按下 **Boot** 键并保持,同时按一下 **Reset** 键,进入“固件下载”模式,通过串口下载固件。 + * - USB-UART/JTAG 端口 + - PC 和 ESP32-S2 模组之间的通信接口(UART 或 JTAG)。 + * - USB 电源端口 + - 为开发板供电。 + * - 电池端口 + - 2 针连接器,用于连接外部电池。 + * - 电源 LED 指示灯 + - 当 USB 电源或外部电源供电电压正常,则 LED 亮起。 + * - 电源开关 + - 打开可为系统供电。 + * - RGB 跳线 + - 如需使用 RGB LED,需在该位置增加一个跳线。 + * - RGB LED 指示灯 + - 可编程 RGB LED 指示灯,受控于 GPIO45。在使用前需要安装 RGB 跳线。 + * - 调压器 + - 5 V 转 3.3 V 调压器。 + * - I2C FPC 连接器 + - (保留)可通过 FPC 线连接其他 I2C 扩展板。 + * - 引出管脚排针 1 + - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 + * - 触摸 FPC 连接器 + - 可通过 FPC 线连接 ESP-LyraP-TouchA 扩展板。 + * - 触摸开关 + - 切换到 OFF 方向,配置 GPIO1 到 GPIO14 连接触摸传感器;切换到 ON 方向,配置 GPIO1 到 GPIO14 用于其他目的。 + * - 3.2" LCD FPC 连接器 + - 可通过 FPC 线连接 3.2" LCD 扩展板,比如 ESP-LyraP-LCD32。 + + +应用程序开发 +------------ + +ESP32-S2-Kaluga-1 上电前,请首先确认开发板完好无损。 + + +硬件准备 +^^^^^^^^ + +- ESP32-S2-Kaluga-1 +- 两根 USB 2.0 电缆(标准 A 转 Micro-B) + + - 电源选项 + - 用于 UART/JTAG 通信 + +- PC(Windows、Linux 或 macOS) +- 您选择的任何扩展板 + + +硬件设置 +^^^^^^^^ + +1. 连接您选择的扩展板(更多信息,请见对应拓展板的用户指南) +2. 插入两根 USB 电缆 +3. 打开 **电源开关** 时,**电源 LED 指示灯** 应点亮。 + + +.. _user-guide-esp32-s2-kaluga-1-kit-software-setup: + +软件设置 +^^^^^^^^ + +请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 一节查看如何快速设置开发环境。 + +您还可以点击 `这里 `_,获取有关 ESP32-S2-Kaluga-1 套件编程指南与应用示例的更多内容。 + + +内容和包装 +---------- + +零售订单 +^^^^^^^^ + +每一个零售 ESP32-S2-Kaluga-1 开发套件均有独立包装。 + +.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32s2-kaluga-1-kit-v1.3-package-3d.png + :align: center + :alt: ESP32-S2-Kaluga-1 - 包装 + :figclass: align-center + + ESP32-S2-Kaluga-1 - 包装 + + +内含以下部分: + +- 主板 + - ESP32-S2-Kaluga-1 +- 扩展板: + - ESP-LyraT-8311A + - ESP-LyraP-CAM + - ESP-LyraP-TouchA + - ESP-LyraP-LCD32 +- 连接器 + - 20 针 FPC 线(用于连接 ESP32-S2-Kaluga-1 主板至 ESP-LyraP-TouchA 扩展板) +- 紧固件 + - 安装螺栓 (x 8) + - 螺丝 (x 4) + - 螺母 (x 4) + +零售购买,请前往 https://www.espressif.com/zh-hans/contact-us/get-samples。 + + +批发订单 +^^^^^^^^ + +ESP32-S2-Kaluga-1 开发套件的批发包装为纸板箱。 + +批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 + + +硬件参考 +======== + + +功能框图 +-------- + +.. Image of v1.2 is used as there are no visual changes + +ESP32-S2-Kaluga-1 的主要组件和连接方式如下图所示。 + +.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-block-diagram.png + :align: center + :alt: ESP32-S2-Kaluga-1 功能框图 + :figclass: align-center + + ESP32-S2-Kaluga-1 功能框图 + + +电源选项 +-------- + +开发板可任一选用以下四种供电方式: + +- Micro USB 端口供电(默认) +- 通过 2 针电池连接器使用外部电池供电 +- 5V / GND 管脚供电 +- 3V3 / GND 管脚供电 + + +.. _user-guide-esp32-s2-kaluga-1-kit-ext-board-compatibility: + +扩展板的兼容性 +-------------- + +如需同时使用多块扩展板,请首先查看以下兼容性信息: + +.. list-table:: + :widths: 20 15 33 32 + :header-rows: 1 + + * - 扩展板组合 + - 复用接口或管脚 + - 无法运行原因 + - 解决方案 + * - 8311A v1.3 + CAM v1.1 + - I2S 控制器 + - ESP32-S2 仅有 1 个 I2S 接口,但这两个开发板均需使用 ESP32-S2 的 I2S 接口进行通信(ESP-LyraT-8311A 使用标准模式;ESP-LyraP-CAM 使用 Camera 协议)。 + - 采用分时复用;或另外选择一款可以通过其他 GPIOs 或 DAC 连接的音频扩展板。 + * - TouchA v1.1 + LCD32 v1.2 + - IO11、IO6 + - 由于管脚 IO11 复用,导致无法触发触摸动作;ESP-LyraP-LCD32 则由于其 BLCT 管脚已与 IO6 断开,因此不受影响。 + - 不要初始化 ESP-LyraP-TouchA 扩展板的 IO11 (NETWORK) 管脚;或者配置 ESP-LyraP-LCD32 扩展板的 BLCT 管脚为 `-1` (相当于不使用 BLCT)。 + * - 8311A v1.3 + LCD32 v1.2 + - IO6 + - 配置 ESP-LyraP-LCD32 扩展板的 BK 管脚为 `-1` (相当于不使用 BK)。 + - ESP32-S2-Kaluga-1 的 BLCT 管脚将从 IO6 断开。 + * - TouchA v1.1 + 8311A v1.3 + - ESP-LyraT-8311A 的 BT_ADC 管脚 + - ESP-LyraT-8311A 在初始化 6 个按钮时需要使用 BT_ADC 管脚,而 ESP-LyraP-TouchA 在完成触摸动作时也需要使用 BT_ADC 管脚。 + - 如需使用 ESP-LyraT-8311A 的 6 个按钮,则不要初始化 ESP-LyraP-TouchA 的 IO6 (PHOTO) 管脚。 + * - TouchA v1.1 + CAM v1.1 + - IO1、IO2、IO3 + - 由于管脚复用无法同时使用。 + - 不要初始化 ESP-LyraP-TouchA 的 IO1 (VOL_UP)、IO2 (PLAY) 和 IO3 (VOL_DOWN)。 + * - TouchA v1.1 + LCD32 v1.2 + CAM v1.1 + - IO1、IO2、IO3、IO11 + - 由于管脚复用无法同时使用。 + - 不要初始化 ESP-LyraP-TouchA 的 IO1 (VOL_UP)、IO2 (PLAY)、IO3 (VOL_DOWN) 和 IO11 (NETWORK)。 + * - TouchA v1.1 + LCD32 v1.2 + 8311A v1.3 + - IO6、IO11 + - 如果使用 ESP-LyraT-8311A 的 BT_ADC 管脚初始化开发板的 6 个按钮,其他扩展板则无法使用 IO6 和 IO11。 + - 不要初始化 ESP-LyraP-TouchA 的 IO11 (NETWORK)。此外,如果需要使用 BT_ADC,则不要初始化 IO6 (PHOTO)。 + +另外,所有扩展板和 :ref:`JTAG 接口 ` 共用管脚 IO39、IO40、IO41 和 IO42。因此,以下情况可能会干扰 JTAG 操作: + +* 插上扩展板 +* 调试正在使用扩展板的应用程序 + + +硬件修订历史 +============ + +ESP32-S2-Kaluga-1 Kit v1.3 +-------------------------- + +* 以下管脚已重新分配,以解决固件烧录问题: + + * Camera D2:GPIO36 + * Camera D3:GPIO37 + * AU_I2S1_SDI:GPIO34 + * AU_WAKE_INT:GPIO46 + +* RGB 已移动至开发板边缘 +* 所有 dip 开关均移动至开发板的反面,从而便利用户操作 + + +ESP32-S2-Kaluga-1 Kit v1.2 +-------------------------- + +:doc:`首次发布 ` + + +相关文档 +======== .. toctree:: :hidden: @@ -7,4 +380,14 @@ user-guide-esp32-s2-kaluga-1-kit-v1.2.rst user-guide-esp-lyrap-cam-v1.1 user-guide-esp-lyrap-lcd32-v1.2 - user-guide-esp-lyrat-8311a_v1.3 \ No newline at end of file + user-guide-esp-lyrat-8311a_v1.3 + +- `ESP32-S2-WROVER 技术规格书 `_ (PDF) +- `乐鑫产品选型工具 `__ +- :doc:`../../api-guides/jtag-debugging/index` + +- `ESP32-S2-Kaluga-1 原理图 `_ (PDF) +- `ESP32-S2-Kaluga-1 PCB 布局图 `_ (PDF) +- `ESP32-S2-Kaluga-1 管脚映射 `_ (Excel) + +有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst index bf69d1e2b685..980ec4d77eaf 100644 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst +++ b/docs/zh_CN/hw-reference/esp32s2/user-guide-saola-1-v1.2.rst @@ -15,9 +15,10 @@ ESP32-S2-Saola-1 本指南包括如下内容: -- `入门指南`_: 简要介绍了 ESP32-S2-Saola-1 和硬件、软件设置指南。 -- `硬件参考`_: 详细介绍了 ESP32-S2-Saola-1 的硬件。 -- `相关文档`_: 列出了相关文档的链接。 +- `入门指南`_:简要介绍了 ESP32-S2-Saola-1 和硬件、软件设置指南。 +- `硬件参考`_:详细介绍了 ESP32-S2-Saola-1 的硬件。 +- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 +- `相关文档`_:列出了相关文档的链接。 入门指南 ======== @@ -58,6 +59,8 @@ ESP32-S2-Saola-1 是乐鑫一款基于 ESP32-S2 的小型开发板。板上的 组件介绍 -------- +.. _user-guide-saola-1-v1.2-board-front: + .. figure:: ../../../_static/esp32-s2-saola-1-v1.2-annotated-photo.png :align: center :alt: ESP32-S2-Saola-1 - 正面 @@ -65,6 +68,8 @@ ESP32-S2-Saola-1 是乐鑫一款基于 ESP32-S2 的小型开发板。板上的 ESP32-S2-Saola-1 - 正面 +以下按照顺时针的顺序依次介绍开发板上的主要组件。 + .. list-table:: :widths: 30 70 :header-rows: 1 @@ -73,18 +78,18 @@ ESP32-S2-Saola-1 是乐鑫一款基于 ESP32-S2 的小型开发板。板上的 - 介绍 * - ESP32-S2-WROVER - ESP32-S2-WROVER 集成 ESP32-S2,是通用型 Wi-Fi MCU 模组,功能强大。该模组采用 PCB 板载天线,配置了 4 MB SPI flash 和 2 MB SPI PSRAM。 - * - I/O 连接器 + * - Pin Headers(排针) - 所有可用 GPIO 管脚(除 Flash 和 PSRAM 的 SPI 总线)均已引出至开发板的排针。用户可对 ESP32-S2 芯片编程,使能 SPI、I2S、UART、I2C、触摸传感器、PWM 等多种功能。 - * - USB 至 UART 桥接器 + * - 3.3 V Power On LED(3.3 V 电源指示灯) + - 开发板连接 USB 电源后,该指示灯亮起。 + * - USB-to-UART Bridge(USB 转 UART 桥接器) - 单芯片 USB 至 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - Boot 键。 - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - Reset 键。 + * - Reset Button(Reset 键) - 复位按键。 - * - 3.3 V 电源指示灯 - - 开发板连接 USB 电源后,该指示灯亮起。 - * - Micro-USB 接口 + * - Micro-USB Port(Micro-USB 接口) - USB 接口。可用作开发板的供电电源或 PC 和 ESP32-S2 芯片的通信接口。 + * - Boot Button(Boot 键) + - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 * - RGB LED - 可寻址 RGB 发光二极管 (WS2812),由 GPIO18 驱动。 @@ -100,6 +105,10 @@ ESP32-S2-Saola-1 是乐鑫一款基于 ESP32-S2 的小型开发板。板上的 - USB 2.0 数据线(标准 A 型转 Micro-B型) - 电脑 (Windows、Linux 或 macOS) +.. 注解:: + + 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 + 软件设置 ^^^^^^^^ @@ -107,7 +116,7 @@ ESP32-S2-Saola-1 是乐鑫一款基于 ESP32-S2 的小型开发板。板上的 .. 注解:: - ESP32-S2 仅支持 ESP-IDF master 分支或 v4.2 以上版本。 + ESP32-S2 系列芯片仅支持 ESP-IDF master 分支或 v4.2 以上版本。 硬件参考 ======== @@ -130,19 +139,105 @@ ESP32-S2-Saola-1 的主要组件和连接方式如下图所示。 您可从以下三种供电方式中任选其一给 ESP32-S2-Saola-1 供电: -- Micro USB 端口供电(默认) -- 5V 和 GND 管脚供电 -- 3V3 和 GND 管脚供电 +- Micro-USB 接口供电(默认) +- 5V 和 GND 排针供电 +- 3V3 和 GND 排针供电 + +建议选择第一种供电方式:Micro-USB 接口供电。 + +排针 +---- + +下表列出了开发板两侧排针(J2 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-saola-1-v1.2-board-front` 所示,排针的序号与 `ESP32-S2-Saola-1 原理图`_ (PDF) 一致。 + +J2 +^^^ +==== ==== ========= ====================================== +序号 名称 类型 [#]_ 功能 +==== ==== ========= ====================================== +1 3V3 P 3.3 V 电源 +2 IO0 I/O GPIO0, 启动 +3 IO1 I/O GPIO1, ADC1_CH0, TOUCH_CH1 +4 IO2 I/O GPIO2, ADC1_CH1, TOUCH_CH2 +5 IO3 I/O GPIO3, ADC1_CH2, TOUCH_CH3 +6 IO4 I/O GPIO4, ADC1_CH3, TOUCH_CH4 +7 IO5 I/O GPIO5, ADC1_CH4, TOUCH_CH5 +8 IO6 I/O GPIO6, ADC1_CH5, TOUCH_CH6 +9 IO7 I/O GPIO7, ADC1_CH6, TOUCH_CH7 +10 IO8 I/O GPIO8, ADC1_CH7, TOUCH_CH8 +11 IO9 I/O GPIO9, ADC1_CH8, TOUCH_CH9 +12 IO10 I/O GPIO10, ADC1_CH9, TOUCH_CH10 +13 IO11 I/O GPIO11, ADC2_CH0, TOUCH_CH11 +14 IO12 I/O GPIO12, ADC2_CH1, TOUCH_CH12 +15 IO13 I/O GPIO13, ADC2_CH2, TOUCH_CH13 +16 IO14 I/O GPIO14, ADC2_CH3, TOUCH_CH14 +17 IO15 I/O GPIO15, ADC2_CH4, XTAL_32K_P +18 IO16 I/O GPIO16, ADC2_CH5, XTAL_32K_N +19 IO17 I/O GPIO17, ADC2_CH6, DAC_1 +20 5V0 P 5 V 电源 +21 GND G 接地 +==== ==== ========= ====================================== + +J3 +^^^ +==== ==== ===== ==================================== +序号 名称 类型 功能 +==== ==== ===== ==================================== +1 GND G 接地 +2 RST I CHIP_PU, 复位 +3 IO46 I GPIO46 +4 IO45 I/O GPIO45 +5 IO44 I/O GPIO44, U0RXD +6 IO43 I/O GPIO43, U0TXD +7 IO42 I/O GPIO42, MTMS +8 IO41 I/O GPIO41, MTDI +9 IO40 I/O GPIO40, MTDO +10 IO39 I/O GPIO39, MTCK +11 IO38 I/O GPIO38 +12 IO37 I/O GPIO37 +13 IO36 I/O GPIO36 +14 IO35 I/O GPIO35 +16 IO34 I/O GPIO34 +17 IO33 I/O GPIO33 +17 IO26 I/O GPIO26 +18 IO21 I/O GPIO21 +19 IO20 I/O GPIO20, ADC2_CH9, USB_D+ +20 IO19 I/O GPIO19, ADC2_CH8, USB_D- +21 IO18 I/O GPIO18, ADC2_CH7, DAC_2, RGB LED +==== ==== ===== ==================================== + +.. [#] P:电源;I:输入;O:输出;T:可设置为高阻。 + +管脚布局 +^^^^^^^^ +.. figure:: ../../../_static/esp32-s2_saola1-pinout.jpg + :align: center + :scale: 45% + :alt: ESP32-S2-Saola-1 管脚布局(点击放大) + :figclass: align-center -建议选择第一种供电方式:Micro USB 端口供电。 + ESP32-S2-Saola-1 管脚布局(点击放大) + +硬件版本 +========== + +无历史版本。 相关文档 ======== -* `ESP32-S2-Saola-1 原理图 `_ (PDF) -* `ESP32-S2-Saola-1 尺寸图 `_ (PDF) -* `ESP32-S2 技术规格书 `_ (PDF) -* `ESP32-S2-WROVER & ESP32-S2-WROVER-I 技术规格书 `_ (PDF) -* `ESP32-S2-WROOM & ESP32-S2-WROOM-I 技术规格书 `_ (PDF) -* `乐鑫产品选型工具 `__ - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 + +* `ESP32-S2-Saola-1 原理图`_ (PDF) +* `ESP32-S2-Saola-1 尺寸图`_ (PDF) +* `ESP32-S2 技术规格书`_ (PDF) +* `ESP32-S2-WROVER & ESP32-S2-WROVER-I 技术规格书`_ (PDF) +* `ESP32-S2-WROOM & ESP32-S2-WROOM-I 技术规格书`_ (PDF) +* `乐鑫产品选型工具`_ + +有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 + +.. _ESP32-S2-Saola-1 原理图: https://dl.espressif.com/dl/schematics/ESP32-S2-SAOLA-1_V1.1_schematics.pdf +.. _ESP32-S2-Saola-1 尺寸图: https://dl.espressif.com/dl/schematics/ESP32-S2-Saola-1_V1.2_Dimensions.pdf +.. _ESP32-S2 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_cn.pdf +.. _ESP32-S2-WROVER & ESP32-S2-WROVER-I 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-s2-wrover_esp32-s2-wrover-i_datasheet_cn.pdf +.. _ESP32-S2-WROOM & ESP32-S2-WROOM-I 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-s2-wroom_esp32-s2-wroom-i_datasheet_cn.pdf +.. _乐鑫产品选型工具: https://products.espressif.com/#/product-selector?names= diff --git a/examples/README.md b/examples/README.md index 240e270384a1..2dc9623b8d85 100644 --- a/examples/README.md +++ b/examples/README.md @@ -30,6 +30,17 @@ Building an example is the same as building any other project: * `idf.py build` to build the example. * Follow the printed instructions to flash, or run `idf.py -p PORT flash`. +## Running Test Python Script + +Some of the examples have `..._test.py` scripts that are used to test that the example works as expected. These scripts run automatically in the internal test queue. They are not intended to be run by ESP-IDF users but sometimes you may want to run them locally. The following requirements must be met in the IDF python virtual environment. + +* ttfw needs to be in the `PYTHONPATH`. Add it like this: `export PYTHONPATH=$PYTHONPATH:$IDF_PATH/tools/ci/python_packages` +* Install all requirements from `tools/ci/python_packages/ttfw_idf/requirements.txt`: `python -m pip install -r $IDF_PATH/tools/ci/python_packages/ttfw_idf/requirements.txt` + +These commands help solve the issue with `ModuleNotFoundError: No module named 'ttfw_idf'` and `ModuleNotFoundError: No module named 'tiny_test_fw'`. + +Some examples might fail due to other missing packages. You might need to install them manually: `pip install websocket`. + # Copying Examples Each example is a standalone project. The examples *do not have to be inside the esp-idf directory*. You can copy an example directory to anywhere on your computer in order to make a copy that you can modify and work with. diff --git a/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32 index 66db63bca00f..55915af404bc 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -669,7 +668,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_ancs/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32 index 6b79d4522093..5bd79aa13d3f 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -673,7 +672,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_dev.h b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_dev.h index 918046e799e8..d41b87280652 100644 --- a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_dev.h +++ b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_dev.h @@ -132,9 +132,9 @@ extern "C" { #define HID_KEY_LEFT_SHIFT 225 // Keyboard LeftShift #define HID_KEY_LEFT_ALT 226 // Keyboard LeftAlt #define HID_KEY_LEFT_GUI 227 // Keyboard LeftGUI -#define HID_KEY_RIGHT_CTRL 228 // Keyboard LeftContorl -#define HID_KEY_RIGHT_SHIFT 229 // Keyboard LeftShift -#define HID_KEY_RIGHT_ALT 230 // Keyboard LeftAlt +#define HID_KEY_RIGHT_CTRL 228 // Keyboard RightContorl +#define HID_KEY_RIGHT_SHIFT 229 // Keyboard RightShift +#define HID_KEY_RIGHT_ALT 230 // Keyboard RightAlt #define HID_KEY_RIGHT_GUI 231 // Keyboard RightGUI typedef uint8_t keyboard_cmd_t; diff --git a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32 index 52cb02588ec6..64d46d9ee63c 100644 --- a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -674,7 +673,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32 index 12731ad6fafb..6d8e7e637645 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -671,7 +670,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32 index 92acd27f335b..9b30e9aac3d5 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32 @@ -416,10 +416,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -460,7 +459,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -673,7 +672,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32 index 12731ad6fafb..6d8e7e637645 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -671,7 +670,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32 index 92acd27f335b..9b30e9aac3d5 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32 @@ -416,10 +416,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -460,7 +459,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -673,7 +672,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32 index 12731ad6fafb..6d8e7e637645 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -671,7 +670,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32 index 92acd27f335b..9b30e9aac3d5 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32 @@ -416,10 +416,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -460,7 +459,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -673,7 +672,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/gatt_client/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32 index 66db63bca00f..55915af404bc 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -669,7 +668,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32 index 6b79d4522093..5bd79aa13d3f 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -673,7 +672,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/gatt_security_server/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32 index 12731ad6fafb..6d8e7e637645 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -671,7 +670,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/gatt_server/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32 index 12731ad6fafb..6d8e7e637645 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -671,7 +670,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32 b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32 index 92acd27f335b..9b30e9aac3d5 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32 @@ -416,10 +416,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -460,7 +459,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -673,7 +672,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/README.md b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/README.md index eb6967380669..544ceea717fe 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/README.md +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/README.md @@ -1,3 +1,72 @@ -| Supported Targets | ESP32-C3 | -| ----------------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | +# ESP-IDF Gatt Security Client Example + +This example shows how to use the ESP BLE5.0 security APIs to connect in secure manner with peer device and use encryption for data exchange. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +To test this demo, you can run the [ble50_security_server_demo](../ble50_security_server), which starts advertising and can be connected to +this demo automatically. + +There are some important points for this demo: +1. `esp_ble_gap_set_security_param` should be used to set the security parameters in the initial stage; +2. `esp_ble_set_encryption` should be used to start encryption with peer device. If the peer device initiates the encryption, + `esp_ble_gap_security_rsp` should be used to send security response to the peer device when `ESP_GAP_BLE_SEC_REQ_EVT` is received. +3. The `gatt_security_client_demo` will receive a `ESP_GAP_BLE_AUTH_CMPL_EVT` once the encryption procedure has completed. + +Please, check this [tutorial](tutorial/ble50_security_client_Example_Walkthrough.md) for more information about this example. + +### Hardware Required + +* A development board with ESP32-C3 SoC, ESP32-S3 SoC and BT5.0 supported chip (e.g., ESP32-C3-DevKitC-1 etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (364) BTDM_INIT: BT controller compile version [3e61eea] +I (374) coexist: coexist rom version 8459080 +I (374) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08 +I (494) system_api: Base MAC address is not set +I (494) system_api: read default base MAC address from EFUSE +I (494) BTDM_INIT: Bluetooth MAC: 7c:df:a1:40:01:dd + +I (514) SEC_GATTC_DEMO: EVT 0, gattc if 3 +I (514) SEC_GATTC_DEMO: REG_EVT +I (524) SEC_GATTC_DEMO: Scan start success +I (2654) SEC_GATTC_DEMO: legacy adv, adv type 0x13 data len 31 +I (2654) SEC_GATTC_DEMO: legacy adv, adv type 0x1b data len 21 +I (3624) SEC_GATTC_DEMO: legacy adv, adv type 0x13 data len 31 +I (3624) SEC_GATTC_DEMO: legacy adv, adv type 0x1b data len 21 +I (4594) SEC_GATTC_DEMO: legacy adv, adv type 0x13 data len 31 +I (4594) SEC_GATTC_DEMO: legacy adv, adv type 0x1b data len 21 +I (5514) SEC_GATTC_DEMO: legacy adv, adv type 0x13 data len 31 +I (5524) SEC_GATTC_DEMO: legacy adv, adv type 0x1b data len 0 +I (7494) SEC_GATTC_DEMO: legacy adv, adv type 0x13 data len 31 +I (7494) SEC_GATTC_DEMO: legacy adv, adv type 0x1b data len 21 +I (8614) SEC_GATTC_DEMO: legacy adv, adv type 0x13 data len 31 +I (8614) SEC_GATTC_DEMO: legacy adv, adv type 0x1b data len 0 + +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults index 35138cc4a42a..b9e05235d627 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults @@ -348,7 +348,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -372,7 +371,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_EFF=1 CONFIG_BTDM_CTRL_BLE_MAX_ACT=10 @@ -412,7 +411,7 @@ CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BTDM_CTRL_SLEEP_MODE_EFF=0 CONFIG_BTDM_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BTDM_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -615,7 +614,7 @@ CONFIG_BT_SMP_ENABLE=y CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32c3 index 2c321ce3311d..e55b5c1931dc 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32s3 index 1394477da8ac..4d6c5551966d 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/sdkconfig.defaults.esp32s3 @@ -465,7 +465,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -525,14 +524,14 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # # # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -739,7 +738,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/tutorial/ble50_security_client_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/tutorial/ble50_security_client_Example_Walkthrough.md new file mode 100644 index 000000000000..513fa0e1b717 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/tutorial/ble50_security_client_Example_Walkthrough.md @@ -0,0 +1,147 @@ +# BLE50 GATT Security Client Example Walkthrough + +## Introduction + +* This document presents a review of the GATT Security Client code example for the ESP32C3 or BLE5.0 supported Chip. +* The GATT Client is capable of scanning for nearby devices and once it has found a device of interest, it requests a secure connection. The GATT client behaves as a central device that initiates a connection to a peripheral by sending a *Aux Connect Pairing Request* as specified by the [Bluetooth Core Specification Version 5.0](https://www.bluetooth.com/specifications/bluetooth-core-specification). +* The peripheral device is normally a GATT Server that exposes Services and Characteristics. The peripheral replies with a *Aux Connect Pairing Response* followed by authentication and exchange of keys. If the bonding process is also executed, the Long Term Keys are stored for subsequent connections. Finally an encrypted channel is established which can support protection against Man-In-The-Middle (MITM) attacks depending on the security configuration. +* The code is implemented using an Application Profile that upon registration, allows to set the local privacy configuration as events are triggered during the life time of the program. + +This document only includes a description of the security aspects of the BLE5.0 Security GATT Client implementation, for the more infor about extended scan , periodic scan please refer to [Periodic_Sync_Example Walkthrough] (../../peroidic_sync/tutorial/Periodic_Sync_Example_Walkthrough.md). + +##include + +```c +#include +#include +#include +#include +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gattc_api.h" +#include "esp_gatt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +``` +These `includes` are required for the FreeRTOS and underlying system components to run, including the logging functionality and a library to store data in non-volatile flash memory. We are interested in `“bt.h”`, `“esp_bt_main.h”`, `"esp_gap_ble_api.h"` and `“esp_gattc_api.h”`, which expose the BLE APIs required to implement this example. + +* `bt.h`: configures the BT controller and VHCI from the host side. +* `esp_bt_main.h`: initializes and enables the Bluedroid stack. +* `esp_gap_ble_api.h`: implements the GAP configuration, such as advertising and connection parameters. +* `esp_gattc_api.h`: implements the GATT Client configuration, such as connecting to peripherals and searching for services. + +## Configuring Local Privacy of the Security Client + +The example registers one Application Profile defined as: + +```c +#define PROFILE_NUM 1 +#define PROFILE_A_APP_ID 0 +``` + +The registration takes place in the ``app_main()`` function by using the ``esp_ble_gattc_app_register()`` function: + +```c +… +ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID); +if (ret){ + ESP_LOGE(GATTC_TAG, "%s gattc app register error, error code = %x\n", __func__, ret); +} +… +``` + +The Application Profile registration triggers an ``ESP_GATTC_REG_EVT`` event which is managed by the ``esp_gattc_cb()`` callback function and forwarded to the Profile A event handler ``gattc_profile_event_handler()``. Here, the event is used to configure the local privacy of the slave device by using the ``esp_ble_gap_config_local_privacy()`` function. + +```c +case ESP_GATTC_REG_EVT: + ESP_LOGI(GATTC_TAG, "REG_EVT"); + esp_ble_gap_config_local_privacy(true); + break; +``` + +This function is a Bluedroid API call for configuring default privacy settings on the local device. Once the privacy is set, an ``ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT`` is triggered which is used to set scan parameters and start scanning for nearby peripherals: + +```c + case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT: + if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(GATTC_TAG, "config local privacy failed, error code =%x", param->local_priva +cy_cmpl.status); + break; + } + esp_err_t scan_ret = esp_ble_gap_set_ext_scan_params(&ext_scan_params); + if (scan_ret){ + ESP_LOGE(GATTC_TAG, "set extend scan params error, error code = %x", scan_ret); + } + break; + case ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT: { + if (param->set_ext_scan_params.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTC_TAG, "extend scan parameters set failed, error status = %x", param->se +t_ext_scan_params.status); + break; + } + //the unit of the duration is second + esp_ble_gap_start_ext_scan(EXT_SCAN_DURATION, EXT_SCAN_PERIOD); + break; + } + case ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT: + if (param->ext_scan_start.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.st +atus); + +``` + +## Configuring and Bonding to a Slave Device + +The rest of the configuration for the GATT Client is performed normally in the same way as the regular GATT Client example. That is, the client finds a device of interest and opens a connection. At this point the GATT client, which is usually the central, initiates the pairing process by sending a Pairing Request to the peripheral device. This request should be acknowledged with a Pairing Response. The Pairing process is implemented automatically by the stack and no extra user configuration is needed. However, depending on the I/O capabilities of both devices, a passkey might be generated on the ESP32 which is presented to the user with the ``ESP_GAP_BLE_PASSKEY_NOTIF_EVT``: + +```c + 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. + ESP_LOGE(GATTS_TABLE_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey); + break; + +``` +The combination of input and output capabilities that determine which algorithm is used are: + +| | Display Only | Display Yes/No | Keyboard Only | No Input No Output | Keyboard Display| +| :-- | :------------- | :------------- | :------------- | :----------------- | :-------------- | +| **Display Only** | Just Works | Just Works | Passkey Entry | Just Works | Passkey Entry | +| **Display Yes/No** | Just Works | Just Works | Passkey Entry | Just Works | Passkey Entry | +| **Keyboard Only** | Passkey Entry | Passkey Entry | Passkey Entry | Just Works | Passkey Entry | +| **No Input No Output** | Just Works | Just Works | Just Works | Just Works | Just Works | +| **Keyboard Display** | Passkey Entry | Passkey Entry | Passkey Entry | Just Works | Passkey Entry | + +In the Just Works method, the Temporary Key is set to 0. This is a practical way to authenticate devices when no display or keyboards are attached to them, so that there is no way to show or enter a passkey. However, if the ESP32 GATT Client has an LCD, it can present the passkey generated locally so that the user can input it on the other peer device, or if the GATT Client has a keyboard, it can input the passkey generated by the other peer device. Additionally, a numeric comparison can be performed if both devices have a display and yes/no confirm buttons and LE Secure Connections are used, that way an independently generated passkey is displayed on both devices and the user manually checks that both 6-digit confirmation values match. + +## Exchanging Keys + +When the client connects to a remote device and the pairing is done successfully, The initiator and responder keys as decided during pairing req / rsp are exchanged. For each key exchange message, an ``ESP_GAP_BLE_KEY_EVT`` event is triggered which can be used to print the type of key received: + +```c +case ESP_GAP_BLE_KEY_EVT: + //shows the ble key info share with peer device to the user. + ESP_LOGI(GATTS_TABLE_TAG, "key type = %s", esp_key_type_to_str(param->ble_security.ble_key.key_type)); + break; +``` + +When the keys are exchanged successfully, the pairing process is completed and encryption of payload data can be started using the AES-128 engine. This triggers an ``ESP_GAP_BLE_AUTH_CMPL_EVT`` event which is used to print information: + +```c +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)); + ESP_LOGI(GATTS_TABLE_TAG, "remote BD_ADDR: %08x%04x",\ + (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], (bd_addr[4] << 8) + bd_addr[5]); + ESP_LOGI(GATTS_TABLE_TAG, "address type = %d", param->ble_security.auth_cmpl.addr_type); + ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail"); + break; +``` + +## Conclusion + +In this document, a review of the security aspects of the BLE5.0 GATT Client has been realized. BLE security encompasses Pairing, Bonding and Encryption. In order to establish a secure link between a central and a peripheral device, the local privacy of the GATT client is set, which allows the BLE stack to set necessary security parameters automatically without the need of additional user configuration. The combination of features and capabilities of the peer devices results in the selection of the appropriate pairing method which the BLE stack then executes. Immediately, the required keys are generated and exchanged and the encryption of subsequent messages is started using the AES-128 engine. These steps trigger different events that are managed by the GATT and GAP event handlers which can be used to print useful information such as the types of keys exchanged and the pairing status. The rest of the security GATT client functionality such as registering for notifications of characteristics is implemented in the same way as in [Periodic Sync Example Walkthrough](../../peroidic_sync/tutorial/Periodic_Sync_Example_Walkthrough.md). diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/README.md b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/README.md index 9cefa9c7c620..9e5c1f7ec443 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/README.md +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/README.md @@ -1,4 +1,61 @@ -| Supported Targets | ESP32-C3 | -| ----------------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | +# ESP-IDF BLE50 Security Server Example +This example shows how to use the APIs to connect in secure manner with peer device and use encryption for data exchange. + +To test this example, you can run [ble50_security_client_demo](../ble50_security_client), which starts scanning, connects to and starts encryption with `ble50_sec_gattc_demo` automatically. + +Please, check this [tutorial](tutorial/ble50_security_server_Example_Walkthrough.md) for more information about this example. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` +There are some important points for this demo: +1.`esp_ble_gap_set_security_param` should be used to set the security parameters in the initial stage; +2.`esp_ble_set_encryption` should be used to start encryption with peer device. If the peer device initiates the encryption, + `esp_ble_gap_security_rsp` should be used to send security response to the peer device when `ESP_GAP_BLE_SEC_REQ_EVT` is received. +3.The `ble50_sec_gattc_demo` will receive a `ESP_GAP_BLE_AUTH_CMPL_EVT` once the encryption procedure has completed. + +### Hardware Required + +* A development board with ESP32-C3 SoC, ESP32-S3 and BLE5.0 supoorted chips. (e.g., ESP32-C3-DevKitC-1, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (363) BTDM_INIT: BT controller compile version [3e61eea] +I (373) coexist: coexist rom version 8459080 +I (373) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08 +I (493) system_api: Base MAC address is not set +I (493) system_api: read default base MAC address from EFUSE +I (493) BTDM_INIT: Bluetooth MAC: 7c:df:a1:40:01:c5 + +I (503) SEC_GATTS_DEMO: app_main init bluetooth +I (523) SEC_GATTS_DEMO: ESP_GATTS_REG_EVT +I (523) SEC_GATTS_DEMO: The number handle = 8 +I (523) SEC_GATTS_DEMO: ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, tatus = 0 +I (523) SEC_GATTS_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT status 0 +I (533) SEC_GATTS_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT status 0 +I (543) SEC_GATTS_DEMO: ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status = 0 + +``` +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults index 6f36c20f9ee1..f341a400fd8a 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults @@ -348,7 +348,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -372,7 +371,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_EFF=1 CONFIG_BTDM_CTRL_BLE_MAX_ACT=10 @@ -412,7 +411,7 @@ CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BTDM_CTRL_SLEEP_MODE_EFF=0 CONFIG_BTDM_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BTDM_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -619,7 +618,6 @@ CONFIG_BT_SMP_ENABLE=y CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32c3 index 2c321ce3311d..e55b5c1931dc 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32s3 index 1394477da8ac..4d6c5551966d 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/sdkconfig.defaults.esp32s3 @@ -465,7 +465,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -525,14 +524,14 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # # # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -739,7 +738,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/tutorial/ble50_security_server_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/tutorial/ble50_security_server_Example_Walkthrough.md new file mode 100644 index 000000000000..656960bcba5e --- /dev/null +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/tutorial/ble50_security_server_Example_Walkthrough.md @@ -0,0 +1,235 @@ +# BLE50 Gatt Security Server Example Walkthrough + +## Introduction + +In this document, a description of the security GATT security Server BLE example for the ESP32C3 is presented. The security configuration enables a GATT Server acting as a peripheral device to bond with a central and establish an encrypted link between them. This functionality is defined by the [Bluetooth Specification version 4.2](https://www.bluetooth.com/specifications/bluetooth-core-specification) and implemented on the ESP-IDF BLE stack, specifically on the Security Manager Protocol (SMP) API. + +BLE security involves three interrelated concepts: pairing, bonding and encryption. Pairing concerns with the exchange of security features and types of keys needed. In addition, the pairing procedure takes care of the generation and exchange of shared keys. The core specification defines the legacy pairing and Secure Connections pairing (introduced in Bluetooth 5.0), which are both supported by ESP32C3. Once the exchange of shared keys is completed, a temporary encrypted link is established to exchange short term and long term keys. Bonding refers to storing the exchanged keys for subsequent connections so that they do not have to be transmitted again. Finally, encryption pertains to the ciphering of plain text data using the AES-128 engine and the shared keys. Server attributes may also be defined to allow only encrypted write and read messages. At any point of the communication, a peripheral device can always ask to start encryption by issuing a security request to the other peer device, which returns a security response by calling an API. + +This document only describes the security configuration. The rest of the GATT server functionalities, such as defining the service table, are explained in the GATT Server example walkthrough documentation. For a better understanding of this example workflow, it is recommended that the reader is familiar with the pairing feature exchange and key generation defined in the section 3.5 of the [Bluetooth Specification Version 4.2](https://www.bluetooth.com/specifications/bluetooth-core-specification) [Vol 3, Part H]. + +## Setting Security Parameters + +The ESP32 requires a series of security parameters in order to define how the pairing request and response are going to be built. The Pairing Response packet built by the GATT Server includes fields such as the input/output capabilities, Secure Connections pairing, authenticated Man-In-The-Middle (MITM) protection or no security requirements (see Section 2.3.1 of the [Bluetooth Specification Version 4.2](https://www.bluetooth.com/specifications/bluetooth-core-specification) [Vol 3, Part H]). In this example, this procedure is done in the `app_main()` function. The pairing request is sent by the initiator which in this case is a remote GATT client. The ESP32 server implemented in this example receives this request and replies with a pairing response, which contains the same security parameters in order for both devices to agree on the resources available and the applicable pairing algorithm (*Just Works* or *Passkey Entry*). Both the pairing request and response commands have the following parameters: + +* *IO Capability*: describes if the device has input/output capabilities such as a display or a keyboard. +* *OOB Flag*: describes if the device supports Out of Band passkey exchange, for example using NFC or Wi-Fi to exchange keys as TKs. +* *Authorization Request*: indicates the requested security properties such as Bonding, Secure Connections (SC), MITM protection or none that will be present in the Pairing Request and Response packets. +* *Maximum Encryption Key Size*: maximum encryption key size in octets. +* *Initiator Key Distribution/Generation*: indicates which keys the initiator is requesting to distribute/generate or use during the Transport Specific Key Distribution phase. In the pairing request, these keys are requested, while in the pairing response, these keys are confirmed to be distributed. +* *Responder Key Distribution/Generation*: indicates which keys the initiator is requesting the responder to distribute/generate or use during the Transport Specific Key Distribution phase. In the pairing request, these keys are requested, while in the pairing response, these keys are confirmed to be distributed. + +In code, these parameters are defined as follows: + +* *IO Capability*: + + ```c + esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;//set the IO capability to No Input No Output + ``` + + The possible values for *IO Capabilities* are: + + ```c + ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ + ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ + ESP_IO_CAP_IN 2 /*!< KeyboardOnly */ + ESP_IO_CAP_NONE 3 /*!< NoInputNoOutput */ + ESP_IO_CAP_KBDISP 4 /*!< Keyboard display */ + ``` + +* *Authorization Request*: + + ```c + esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication + ``` + + The possible values for *Authorization Request* are a combination of Bonding, MITM protection and Secure Connections requests: + + ```c + ESP_LE_AUTH_NO_BOND: No bonding. + ESP_LE_AUTH_BOND: Bonding is performed. + ESP_LE_AUTH_REQ_MITM: MITM Protection is enabled. + ESP_LE_AUTH_REQ_SC_ONLY: Secure Connections without bonding enabled. + ESP_LE_AUTH_REQ_SC_BOND: Secure Connections with bonding enabled. + ESP_LE_AUTH_REQ_SC_MITM: Secure Connections with MITM Protection and no bonding enabled. + ESP_LE_AUTH_REQ_SC_MITM_BOND: Secure Connections with MITM Protection and bonding enabled. + ``` + +* *Maximum Encryption Key Size*: + + ```c + uint8_t key_size = 16; //the key size should be 7~16 bytes + ``` + +* *Initiator Key Distribution/Generation*: + + ```c + uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + ``` + + The initiator distributes the LTK and IRK keys by the setting the EncKey and IdKey masks. + +* *Responder Key Distribution/Generation*: + + ```c + uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + ``` + + The responder distributes the LTK and IRK keys by the setting the *EncKey* and *IdKey* masks. + + Once defined, the parameters are set using the `esp_ble_gap_set_security_param()` function. This function sets the parameter type, the parameter value and the parameter length: + + ```c + esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t)); + esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t)); + esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t)); + esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t)); + esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t)); + ``` + + This information is enough for the BLE stack to perform the pairing process, including pairing confirmation and key generation. The procedure is invisible to the user and executed automatically by the stack. + +## Connecting and Bonding to a Peer Device + +The security parameters set previously are stored locally to be used later when the central device connects to the peripheral. Every time a remote device connects to the local GATT server, the connection event `ESP_GATTS_CONNECT_EVT` is triggered. This event is employed to perform the pairing and bonding process by invoking the `esp_ble_set_encryption()` function which takes as parameters the remote device address and the type of encryption that will be performed. The BLE stack then executes the actual pairing process in the background. In this example, the encryption includes MITM protection. + +```c +case ESP_GATTS_CONNECT_EVT: + //start security connect with peer device when receive the connect event sent by the central. + esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM); + break; +``` +The types of encryptions available are: + +* `ESP_BLE_SEC_NONE` +* `ESP_BLE_SEC_ENCRYPT` +* `ESP_BLE_SEC_ENCRYPT_NO_MITM` +* `ESP_BLE_SEC_ENCRYPT_MITM` + +The difference between `ESP_BLE_SEC_ENCRYPT` and `ESP_BLE_SEC_ENCRYPT_NO_MITM` lies in the fact that a previous connection might have a security level that needs to be upgraded, therefore requires to exchange keys again. + +In this example, the I/O capabilities are set to *No Input No Output*, therefore the *Just Works* pairing method, which doesn't not require the generation of a random 6-digit passkey, is used (For details, please refer to the table below). The user may modify the example to set the I/O capabilities to use other than *No Input No Output*. Therefore, depending on the I/O capabilities of the remote device, a passkey might be generated on the ESP32 which is presented to the user with the `ESP_GAP_BLE_PASSKEY_NOTIF_EVT`: + +```c +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. + ESP_LOGE(GATTS_TABLE_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey); + break; +``` + +The combination of input and output capabilities that determine which algorithm is used are: + +| | Display Only | Display Yes/No | Keyboard Only | No Input No Output | Keyboard Display| +| :-- | :------------- | :------------- | :------------- | :----------------- | :-------------- | +| **Display Only** | Just Works | Just Works | Passkey Entry | Just Works | Passkey Entry | +| **Display Yes/No** | Just Works | Just Works | Passkey Entry | Just Works | Passkey Entry | +| **Keyboard Only** | Passkey Entry | Passkey Entry | Passkey Entry | Just Works | Passkey Entry | +| **No Input No Output** | Just Works | Just Works | Just Works | Just Works | Just Works | +| **Keyboard Display** | Passkey Entry | Passkey Entry | Passkey Entry | Just Works | Passkey Entry | + + +## Exchanging Keys + +When the client connects to the server and the pairing is done successfully, the keys indicated by the `init_key` and `rsp_key` security parameters are exchanged. In this example the following keys are generated and distributed: + +* Local device LTK +* Local device IRK +* Local device CSRK +* Peer device LTK +* Peer device IRK + +Note that for this example only, the peer device CSRK is not exchanged. For each key exchange message, an `ESP_GAP_BLE_KEY_EVT` event is triggered, which can be used to print the type of key received: + +```c +case ESP_GAP_BLE_KEY_EVT: + //shows the ble key info share with peer device to the user. + ESP_LOGI(GATTS_TABLE_TAG, "key type = %s", esp_key_type_to_str(param->ble_security.ble_key.key_type)); + break; +``` + +When the keys are exchanged successfully, the pairing process is done. This triggers an `ESP_GAP_BLE_AUTH_CMPL_EVT` event, which is used to print information such as remote device, address type and pair status: + +```c +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)); + ESP_LOGI(GATTS_TABLE_TAG, "remote BD_ADDR: %08x%04x",\ + (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + + bd_addr[3], + (bd_addr[4] << 8) + bd_addr[5]); + ESP_LOGI(GATTS_TABLE_TAG, "address type = %d", + param->ble_security.auth_cmpl.addr_type); + ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s", + param->ble_security.auth_cmpl.success ? "success" : "fail"); + break; +} +``` + +## Security Permission for Attributes + +When defining the attributes of the server, different permissions can be set to the write and read events. Attributes permissions can be: + +* Permission to read +* Permission to read with encryption +* Permission to read with encryption and MITM protection +* Permission to write +* Permission to write with encryption +* Permission to write with encryption and MITM protection +* Permission to signed write +* Permission to signed write with MITM protection + +These permissions are defined in the API as: + +* `ESP_GATT_PERM_READ` +* `ESP_GATT_PERM_READ_ENCRYPTED` +* `ESP_GATT_PERM_READ_ENC_MITM` +* `ESP_GATT_PERM_WRITE` +* `ESP_GATT_PERM_WRITE_ENCRYPTED` +* `ESP_GATT_PERM_WRITE_ENC_MITM` +* `ESP_GATT_PERM_WRITE_SIGNED` +* `ESP_GATT_PERM_WRITE_SIGNED_MITM` + +When creating the services table, each attribute can have permissions to read or write, with or without encryption. When an attribute has encrypted permissions and a peer device that does not have the required security clearance tries to read or write to that attribute, the local host sends an Insufficient Authorization Error. In the example, the following attributes are defined with permissions with encryption: + +```c +… +// Body Sensor Location Characteristic Value + [HRS_IDX_BOBY_SENSOR_LOC_VAL] = { + {ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, + (uint8_t *)&body_sensor_location_uuid, + ESP_GATT_PERM_READ_ENCRYPTED, + sizeof(uint8_t), + sizeof(body_sensor_loc_val), + (uint8_t *)body_sensor_loc_val} + }, +… +// Heart Rate Control Point Characteristic Value + [HRS_IDX_HR_CTNL_PT_VAL] = { + {ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, + (uint8_t *)&heart_rate_ctrl_point, + ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED, + sizeof(uint8_t), + sizeof(heart_ctrl_point), + (uint8_t *)heart_ctrl_point} + }, +… +``` + +## Security Requests + +During the communication between a central and a peripheral device, the peripheral might request to start encryption at any moment by issuing a security request command. This command will trigger an `ESP_GAP_BLE_SEC_REQ_EVT` event on the central, which will reply a positive (true) security response to the peer device to accept the request or a negative (false) one to reject the request. In this example, this event is used to reply a start encryption response by using the `esp_ble_gap_security_rsp()` API call. + +```c +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; +``` +## Conclusion + +In this document, a review of the security aspects of the GATT Server has been realized. BLE security encompasses Pairing, Bonding and Encryption. In order to establish a secured link between a central and a peripheral device, security parameters that define the capabilities and features each device possess are set. The combination of features and capabilities of the peer devices results in the selection of the appropriate pairing method which the BLE stack then executes. Immediately, the required keys are generated and exchanged, and the encryption of subsequent messages is started using the AES-128 engine and these keys. These steps trigger different events that are managed by the GATT and GAP event handlers which can be used to print useful information such as the types of keys exchanged and the pairing status. In addition, attribute permissions are appointed to allow only encrypted read and write events when needed. The rest of the Security GATT server functionalities such as defining services and characteristics are implemented in the same way as presented in the GATT Server example. diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/README.md b/examples/bluetooth/bluedroid/ble_50/multi-adv/README.md index eb6967380669..a0c0d7cf94d6 100644 --- a/examples/bluetooth/bluedroid/ble_50/multi-adv/README.md +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/README.md @@ -1,3 +1,63 @@ -| Supported Targets | ESP32-C3 | -| ----------------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | +#ESP-IDF Multi Adv Example + +This example support legacy as well as extended advertisement for all phy. + +Please, check this [tutorial](tutorial/Mulit_Adv_Example_Walkthrough.md) for more information about this example. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32-C3 SoC and ESP32-S3 and BLE5.0 supported chips (e.g., ESP32-C3-DevKitC, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + + +## Example Output + +``` +I (361) BTDM_INIT: BT controller compile version [3e61eea] +I (371) coexist: coexist rom version 8459080 +I (371) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08 +I (491) system_api: Base MAC address is not set +I (491) system_api: read default base MAC address from EFUSE +I (491) BTDM_INIT: Bluetooth MAC: 7c:df:a1:40:01:c5 + +I (711) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0 +I (711) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status 0 +I (711) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status 0 +I (721) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0 +I (731) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status 0 +I (741) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0 +I (741) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0 +I (751) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status 0 +I (761) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status 0 +I (771) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0 +I (781) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0 +I (781) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status 0 +I (791) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0 +I (801) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status 0 + +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults index 0cb380576689..9cd61576dd5d 100644 --- a/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults @@ -348,7 +348,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -366,7 +365,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_EFF=1 CONFIG_BTDM_CTRL_BLE_MAX_ACT=10 @@ -406,7 +405,7 @@ CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BTDM_CTRL_SLEEP_MODE_EFF=0 CONFIG_BTDM_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BTDM_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -606,7 +605,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32c3 index 2c321ce3311d..e55b5c1931dc 100644 --- a/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32s3 index 1394477da8ac..4d6c5551966d 100644 --- a/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/sdkconfig.defaults.esp32s3 @@ -465,7 +465,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -525,14 +524,14 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # # # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -739,7 +738,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/tutorial/Mulit_Adv_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble_50/multi-adv/tutorial/Mulit_Adv_Example_Walkthrough.md new file mode 100644 index 000000000000..416420436328 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/tutorial/Mulit_Adv_Example_Walkthrough.md @@ -0,0 +1,282 @@ +# Multi Adv Example Walkthrough + +## introduction + +In this document, we review the Multi Adv example code which implements a Bluetooth Low Energy (BLE5.0) Multi adv profile on the ESP32C3. This example is designed around two Application Profiles and a series of events that are handled in order to execute a sequence of configuration steps, such as defining extended advertising parameters with all phy 1M,2M and coded and Ext adv data. + +## Includes + +First, let’s take a look at the include + +```c +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "sdkconfig.h" +``` + +These includes are required for the FreeRTOS and underlaying system components to run, including the logging functionality and a library to store data in non-volatile flash memory. We are interested in `"esp_bt.h"`, `"esp_bt_main.h"`, `"esp_gap_ble_api.h"` and `"esp_gatts_api.h"`, which expose the BLE APIs required to implement this example. + + * `esp_bt.h`: implements BT controller and VHCI configuration procedures from the host side. + * `esp_bt_main.h`: implements initialization and enabling of the Bluedroid stack. + * `esp_gap_ble_api.h`: implements GAP configuration, such as advertising and connection parameters. + * `esp_gatts_api.h`: implements GATT configuration, such as creating services and characteristics. + +## Main Entry Point + +The entry point to this example is the app_main() function: + +```c +void app_main(void) +{ + esp_err_t ret; + + // Initialize NVS. + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(LOG_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(LOG_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(LOG_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(LOG_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret){ + ESP_LOGE(LOG_TAG, "gap register error, error code = %x", ret); + return; + + } + + vTaskDelay(200 / portTICK_PERIOD_MS); + + test_sem = xSemaphoreCreateBinary(); + // 1M phy extend adv, Connectable advertising + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(0, &ext_adv_params_1M), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(0, addr_1m), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(0, sizeof(raw_adv_data_1m), &raw_adv_data_1m[0]), test_sem); + + // 2M phy extend adv, Scannable advertising + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(1, &ext_adv_params_2M), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(1, addr_2m), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(1, sizeof(raw_scan_rsp_data_2m), raw_scan_rsp_data_2m), test_sem); + + // 1M phy legacy adv, ADV_IND + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(2, &legacy_adv_params), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(2, addr_legacy), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(2, sizeof(legacy_adv_data), &legacy_adv_data[0]), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(2, sizeof(legacy_scan_rsp_data), &legacy_scan_rsp_data[0]), test_sem); + + // coded phy extend adv, Connectable advertising + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(3, &ext_adv_params_coded), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(3, addr_coded), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(3, sizeof(raw_scan_rsp_data_coded), &raw_scan_rsp_data_coded[0]), test_sem); + + // start all adv + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_start(4, &ext_adv[0]), test_sem); + + return; + +} +``` +The main function starts by initializing the non-volatile storage library. This library allows tosave key-value pairs in flash memory and is used by some components such as the Wi-Fi library to save the SSID and password: + +```c +ret = nvs_flash_init(); +``` +## BT Controller and Stack Initialization + +The main function also initializes the BT controller by first creating a BT controller configuration structure named `esp_bt_controller_config_t` with default settings generated by the `BT_CONTROLLER_INIT_CONFIG_DEFAULT()` macro. The BT controller implements the Host Controller Interface (HCI) on the controller side, the Link Layer (LL) and the Physical Layer (PHY).The BT Controller code is exposed as a library that interacts with underlying Bluetooth stack. The controller configuration includes setting the BT controller stack size, priority and HCI baud rate. With the settings created, the BT controller is initialized and enabled with the `esp_bt_controller_init()` function: + +```c +esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +ret = esp_bt_controller_init(&bt_cfg); +``` + +Next, the controller is enabled in BLE Mode. + +```c +ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); +``` +> The controller should be enabled in `ESP_BT_MODE_BTDM`, if you want to use the dual mode (BLE + BT). + +There are four Bluetooth modes supported: + +1. `ESP_BT_MODE_IDLE`: Bluetooth not running +2. `ESP_BT_MODE_BLE`: BLE mode +3. `ESP_BT_MODE_CLASSIC_BT`: BT Classic mode +4. `ESP_BT_MODE_BTDM`: Dual mode (BLE + BT Classic) + +After the initialization of the BT controller, the Bluedroid stack, which includes the common definitions and APIs for both BT Classic and BLE, is initialized and enabled by using: + +```c +ret = esp_bluedroid_init(); +ret = esp_bluedroid_enable(); +``` +The Bluetooth stack is up and running at this point in the program flow, however the functionality of the application has not been defined yet. The functionality is defined by reacting to events +such as what happens when another device tries to read or write parameters and establish a connection. User need to define GAP and GATT handlers. The application needs +to register a callback function for each event handler in order to let the application know which functions are going to handle the GAP and GATT events: + +```c +esp_ble_gap_register_callback(gap_event_handler); +``` +The functions `gap_event_handler()` handle all the events that are pu +shed to the application from the BLE stack. + +## Setting GAP Parameters + +The register application event is the first one that is triggered during the lifetime of the program, this example uses the Profile A GATT event handle to configure the advertising parameters upon registration. This example has the option to use both standard Bluetooth Core Specification advertising parameters or a customized raw buffer. The option can be selected with the `CONFIG_SET_RAW_ADV_DATA` define. The raw advertising data can be used to implement iBeacons, Eddystone or other proprietary, and custom frame types such as the ones used for Indoor Location Services that are different from the standard specifications. + +The function is used to configure different types of extended advertisement types and legacy adv with 1M,2M and coded phy in esp_ble_gap_ext_adv_set_params , esp_ble_gap_ext_adv_set_rand_addr and esp_ble_gap_config_ext_adv_data_raw. Respective structure of each one of them mentioned below with one example: + +```c +/** +* @brief ext adv parameters +*/ +typedef struct { + esp_ble_ext_adv_type_mask_t type; /*!< ext adv type */ + uint32_t interval_min; /*!< ext adv minimum interval */ + uint32_t interval_max; /*!< ext adv maximum interval */ + esp_ble_adv_channel_t channel_map; /*!< ext adv channel map */ + esp_ble_addr_type_t own_addr_type; /*!< ext adv own addresss type */ + esp_ble_addr_type_t peer_addr_type; /*!< ext adv peer address type */ + esp_bd_addr_t peer_addr; /*!< ext adv peer address */ + esp_ble_adv_filter_t filter_policy; /*!< ext adv filter policy */ + int8_t tx_power; /*!< ext adv tx power */ + esp_ble_gap_pri_phy_t primary_phy; /*!< ext adv primary phy */ + uint8_t max_skip; /*!< ext adv maximum skip */ + esp_ble_gap_phy_t secondary_phy; /*!< ext adv secondary phy */ + uint8_t sid; /*!< ext adv sid */ + bool scan_req_notif; /*!< ext adv sacn request event notify */ +} esp_ble_gap_ext_adv_params_t; + +``` +1M phy example-> +Ext adv param: + +```c +esp_ble_gap_ext_adv_params_t ext_adv_params_1M = { + .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, + .interval_min = 0x30, + .interval_max = 0x30, + .channel_map = ADV_CHNL_ALL, + .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .primary_phy = ESP_BLE_GAP_PHY_1M, + .max_skip = 0, + .secondary_phy = ESP_BLE_GAP_PHY_1M, + .sid = 0, + .scan_req_notif = false, + .own_addr_type = BLE_ADDR_TYPE_RANDOM, +}; + +``` +Random addr for 1M phy: + +```c +uint8_t addr_1m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x01}; + +``` +Ext adv data for 1M phy: + +```c +static uint8_t raw_adv_data_1m[] = { + 0x02, 0x01, 0x06, + 0x02, 0x0a, 0xeb, + 0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 'D', 'V', '_', '1', 'M' +}; + +``` + +Once we config the all the adv instance we can start all the adv using the func esp_ble_gap_ext_adv_start which can post this to scanner side with respective param. + +## GAP Event Handler +Once the Extended advertising data have been set, the GAP event `ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT and ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT ` is triggered. + +```c +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext +_adv_set_rand_addr.status); + break; + case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_ad +v_set_params.status); + break; + case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_ +data_set.status); + break; + case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->sca +n_rsp_set.status); + break; + case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_sta +rt.status); + break; + case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop +.status); + break; + default: + break; + } +} + +``` +## Default config + +This example by default configured with +1M phy extend adv, Connectable advertising +2M phy extend adv, Scannable advertising +1M phy legacy adv, ADV_IND +coded phy extend adv, Connectable advertising + +We can change Ext adv param ( adv type ), Random addr and Raw data using above struct and output will be seen accordingly. + + +## Conclusion +In this document, we have gone through the Multi adv example code describing each section. The application is designed around the concept of Application Profiles. In addition, the procedures that this example uses to register event handlers are explained. The events follow a sequence of configuration steps, such as defining Extended advertising parameters, Random address and Raw dat with respective phy. diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/README.md b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/README.md index eb6967380669..ab2f14116e4f 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/README.md +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/README.md @@ -1,3 +1,59 @@ -| Supported Targets | ESP32-C3 | -| ----------------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | +# ESP_IDF Periodic Adv Example + +This example support for the periodic advertisement which allow the scanner to sync with the advertiser so that scanner and advertiser wake up same time. It support extended adv with 2M phy in connectable mode. + + +To test this demo, we can run the [periodic_sync_demo](../peroidic_sync), which can do periodic scan and try to sync with periodic adv. + + +Please, check this [tutorial](tutorial/Periodic_adv_Example_Walkthrough.md) for more information about this example. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32-C3 SoC, ESP32-S3 and BLE5.0 supported chips (e.g., ESP32-C3-DevKitC-1, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (362) BTDM_INIT: BT controller compile version [3e61eea] +I (372) coexist: coexist rom version 8459080 +I (372) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08 +I (492) system_api: Base MAC address is not set +I (492) system_api: read default base MAC address from EFUSE +I (492) BTDM_INIT: Bluetooth MAC: 7c:df:a1:40:01:dd + +I (712) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0 +I (712) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status 0 +I (712) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status 0 +I (722) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status 0 +I (732) MULTI_ADV_DEMO: ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, status 0 +I (742) MULTI_ADV_DEMO: ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, status 0 +I (742) MULTI_ADV_DEMO: ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, status 0 + +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults index 0cb380576689..9cd61576dd5d 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults @@ -348,7 +348,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -366,7 +365,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_EFF=1 CONFIG_BTDM_CTRL_BLE_MAX_ACT=10 @@ -406,7 +405,7 @@ CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BTDM_CTRL_SLEEP_MODE_EFF=0 CONFIG_BTDM_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BTDM_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -606,7 +605,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32c3 index 2c321ce3311d..e55b5c1931dc 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32s3 index 1394477da8ac..4d6c5551966d 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/sdkconfig.defaults.esp32s3 @@ -465,7 +465,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -525,14 +524,14 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # # # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -739,7 +738,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md new file mode 100644 index 000000000000..ad843f80d1fd --- /dev/null +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md @@ -0,0 +1,299 @@ +# Periodic Adv Example Walkthrough + +## introduction + +In this document, We review the Periodic Adv example code which implements a Bluetooth Low Energy (BLE5.0) Multi adv profile on the ESP32C3. This example is designed the periodic advertisement which allow the scanner to sync with the advertiser so that scanner and advertiser wake up same time. + +##include +First, let’s take a look at the include + +```c +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "sdkconfig.h" +#include "freertos/semphr.h" +``` + +These includes are required for the FreeRTOS and underlying system components to run, including the logging functionality and a library to store data in non-volatile flash memory. We are interested in `"esp_bt.h"`, `"esp_bt_main.h"`, `"esp_gap_ble_api.h"` and `"esp_gatts_api.h"`, which expose the BLE APIs required to implement this example. + + * `esp_bt.h`: implements BT controller and VHCI configuration procedures from the host side. + * `esp_bt_main.h`: implements initialization and enabling of the Bluedroid stack. + * `esp_gap_ble_api.h`: implements GAP configuration, such as advertising and connection parameters. + * `esp_gatts_api.h`: implements GATT configuration, such as creating services and characteristics. + + ## Main Entry Point + + The entry point to this example is the app_main() function: + +```c +void app_main(void) +{ + esp_err_t ret; + + // Initialize NVS. + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(LOG_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret) +); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(LOG_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(LOG_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(LOG_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret){ + ESP_LOGE(LOG_TAG, "gap register error, error code = %x", ret); + return; + } + + vTaskDelay(200 / portTICK_PERIOD_MS); + + test_sem = xSemaphoreCreateBinary(); + // 2M phy extend adv, Connectable advertising + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(EXT_ADV_HANDLE, &ext_adv_params_2M), test_s +em); + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(EXT_ADV_HANDLE, addr_2m), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(EXT_ADV_HANDLE, sizeof(raw_ext_adv_dat +a_2m), &raw_ext_adv_data_2m[0]), test_sem); + + // start all adv + FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_start(NUM_EXT_ADV, &ext_adv[0]), test_sem); + + FUNC_SEND_WAIT_SEM(esp_ble_gap_periodic_adv_set_params(EXT_ADV_HANDLE, &periodic_adv_params), + test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_config_periodic_adv_data_raw(EXT_ADV_HANDLE, sizeof(periodic_a +dv_raw_data), &periodic_adv_raw_data[0]), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_periodic_adv_start(EXT_ADV_HANDLE), test_sem); + + return; +} + +``` +The main function starts by initializing the non-volatile storage library. This library allows to save key-value pairs in flash memory and is used by some components such as the Wi-Fi library to +save the SSID and password: + +```c +ret = nvs_flash_init(); +``` +## BT Controller and Stack Initialization + +The main function also initializes the BT controller by first creating a BT controller configuration structure named `esp_bt_controller_config_t` with default settings generated by the `BT_CONTROLLER_INIT_CONFIG_DEFAULT()` macro. The BT controller implements the Host Controller Interface (HCI) on the controller side, the Link Layer (LL) and the Physical Layer (PHY). The BT Controller is invisible to the user applications and deals with the lower layers of the BLE stack. The controller configuration includes setting the BT controller stack size, priority and HCI baud rate. With the settings created, the BT controller is initialized and enabled with the `esp_bt_controller_init()` function: + +```c +esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +ret = esp_bt_controller_init(&bt_cfg); +``` + +Next, the controller is enabled in BLE Mode. + +```c +ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); +``` +> The controller should be enabled in `ESP_BT_MODE_BTDM`, if you want to use the dual mode (BLE + + BT). + +There are four Bluetooth modes supported: + +1. `ESP_BT_MODE_IDLE`: Bluetooth not running +2. `ESP_BT_MODE_BLE`: BLE mode +3. `ESP_BT_MODE_CLASSIC_BT`: BT Classic mode +4. `ESP_BT_MODE_BTDM`: Dual mode (BLE + BT Classic) + +After the initialization of the BT controller, the Bluedroid stack, which includes the common definitions and APIs for both BT Classic and BLE, is initialized and enabled by using: + +```c + ret = esp_bluedroid_init(); + ret = esp_bluedroid_enable(); +``` +The Bluetooth stack is up and running at this point in the program flow, however the functionality of the application has not been defined yet. The functionality is defined by reacting to events such as what happens when another device tries to read or write parameters and establish a connection. The two main managers of events are the GAP and GATT event handlers. The application needs to register a callback function for each event handler in order to let the application know which functions are going to handle the GAP and GATT events: + +```c +esp_ble_gap_register_callback(gap_event_handler); +``` +The functions `gap_event_handler()` handle all the events that are pushed to the application from the BLE stack. + +## Setting GAP Parameters + +The register application event is the first one that is triggered during the lifetime of the program, this example uses the Profile A GATT event handle to configure the advertising parameters upon registration. This example has the option to use both standard Bluetooth Core Specification advertising parameters or a customized raw buffer. The option can be selected with the `CONFIG_SET_RAW_ADV_DATA` define. The raw advertising data can be used to implement iBeacons, Eddystone or other proprietaries, and custom frame types such as the ones used for Indoor Location Services that are different from the standard specifications. + +The function is used to configure different types of extended advertisement types and legacy adv with 1M,2M and coded phy is esp_ble_gap_ext_adv_set_params , esp_ble_gap_ext_adv_set_rand_addr and esp_ble_gap_config_ext_adv_data_raw. Respective structure of each one of them mentioned below with one example: + +```c +/** +* @brief ext adv parameters +*/ +typedef struct { + esp_ble_ext_adv_type_mask_t type; /*!< ext adv type */ + uint32_t interval_min; /*!< ext adv minimum interval */ + uint32_t interval_max; /*!< ext adv maximum interval */ + esp_ble_adv_channel_t channel_map; /*!< ext adv channel map */ + esp_ble_addr_type_t own_addr_type; /*!< ext adv own addresss type */ + esp_ble_addr_type_t peer_addr_type; /*!< ext adv peer address type */ + esp_bd_addr_t peer_addr; /*!< ext adv peer address */ + esp_ble_adv_filter_t filter_policy; /*!< ext adv filter policy */ + int8_t tx_power; /*!< ext adv tx power */ + esp_ble_gap_pri_phy_t primary_phy; /*!< ext adv primary phy */ + uint8_t max_skip; /*!< ext adv maximum skip */ + esp_ble_gap_phy_t secondary_phy; /*!< ext adv secondary phy */ + uint8_t sid; /*!< ext adv sid */ + bool scan_req_notif; /*!< ext adv sacn request event notify */ +} esp_ble_gap_ext_adv_params_t; + +``` +2M phy example-> +Ext adv param: +```c +esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { + .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_NONCONN_NONSCANNABLE_UNDIRECTED, + .interval_min = 0x30, + .interval_max = 0x30, + .channel_map = ADV_CHNL_ALL, + .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .primary_phy = ESP_BLE_GAP_PHY_1M, + .max_skip = 0, + .secondary_phy = ESP_BLE_GAP_PHY_2M, + .sid = 0, + .scan_req_notif = false, + .own_addr_type = BLE_ADDR_TYPE_RANDOM, +}; +``` + +Ext adv Random addr: +```c +uint8_t addr_2m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x02}; +``` +Ext adv raw data: + +```c +static uint8_t raw_ext_adv_data_2m[] = { + 0x02, 0x01, 0x06, + 0x02, 0x0a, 0xeb, + 0x13, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 'D', 'V', '_', '8', '0', 'M', 'S' +}; +``` + +Similar thing for the periodic param : +The function is used for the esp_ble_gap_periodic_adv_set_params, esp_ble_gap_config_periodic_adv_data_raw and esp_ble_gap_periodic_adv_start. Respective structure of each one of them mentioned below with one example: + +```c +static esp_ble_gap_periodic_adv_params_t periodic_adv_params = { + .interval_min = 0x40, // 80 ms interval + .interval_max = 0x40, + .properties = 0, // Do not include TX power +}; +``` + +```c +static uint8_t periodic_adv_raw_data[] = { + 0x02, 0x01, 0x06, + 0x02, 0x0a, 0xeb, + 0x03, 0x03, 0xab, 0xcd, + 0x11, 0x09, 'E', 'S', 'P', '_', 'P', 'E', 'R', 'I', 'O', 'D', 'I', + 'C', '_', 'A', 'D', 'V' +}; +``` + +```c +static esp_ble_gap_ext_adv_t ext_adv[1] = { + // instance, duration, peroid + [0] = {EXT_ADV_HANDLE, 0, 0}, +}; +``` +Once we config the all the adv instances, We can start advertising using the function esp_ble_gap_ext_adv_start a which can post this to scanner side with respective param. + +## GAP Event Handler +Once the Extended advertising data have been set, the GAP event `ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT,ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT and ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT` is triggered. + +```c + +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param){ + switch (event) { + case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext _adv_set_rand_addr.status); + break; + case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status); + break; + case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status); + break; + case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status); + break; + case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status); + break; + case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->p +eroid_adv_set_params.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, status %d", param->per +iod_adv_data_set.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, status %d", param->period +_adv_start.status); + break; + default: + break; + } +} +``` +## Default config +2M phy with connectable mode of periodic adv. + + +## Conclusion +In this document, we have gone through the Periodic adv example code describing each section. The application is designed around the concept of Application Profiles. In addition, the procedures that this example uses to register event handlers are explained. The events follow a sequence of configuration steps, such as defining Extended advertising parameters, Random address, Raw data, Periodic param, periodic data and start of Periodic adv in connectable mode. + + diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/README.md b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/README.md index eb6967380669..7aa81ba4cf4c 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/README.md +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/README.md @@ -1,3 +1,73 @@ -| Supported Targets | ESP32-C3 | -| ----------------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | + +# ESP-IDF Periodic Sync Example + +This example supports the periodic extended scan to scan the extended advertisement. + +To test this demo, we can run the [periodic_adv_demo](../peroidic_adv), which can start extended advertisement with supported param. + +Please, check this [tutorial](tutorial/Periodic_Sync_Example_Walkthrough.md) for more information about this example. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32-C3 SoC, ESP32-S3 and BLE5.0 supported chips (e.g., ESP32-C3-DevKitC-1, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` + +I (362) BTDM_INIT: BT controller compile version [3e61eea] +I (372) coexist: coexist rom version 8459080 +I (372) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08 +I (492) system_api: Base MAC address is not set +I (492) system_api: read default base MAC address from EFUSE +I (492) BTDM_INIT: Bluetooth MAC: 7c:df:a1:40:01:c5 + +Output1 Without advertisement: + +I (712) PERIODIC_SYNC: ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, status 0 +I (712) PERIODIC_SYNC: ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT, status 0 + +Output2 with advetisement: + +I (712) PERIODIC_SYNC: ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, status 0 +I (712) PERIODIC_SYNC: ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT, status 0 +I (712) PERIODIC_SYNC: Start create sync with the peer device ESP_MULTI_ADV_80MS +I (722) PERIODIC_SYNC: ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, status 0 +I (812) PERIODIC_SYNC: ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT, status 0 +I (812) sync addr: c0 de 52 00 00 02 +I (812) PERIODIC_SYNC: sync handle 1 sid 0 perioic adv interval 64 adv phy 2 +I (812) PERIODIC_SYNC: periodic adv report, sync handle 1 data status 0 data len 28 rssi -48 +I (892) PERIODIC_SYNC: periodic adv report, sync handle 1 data status 0 data len 28 rssi -47 +I (972) PERIODIC_SYNC: periodic adv report, sync handle 1 data status 0 data len 28 rssi -48 +I (1052) PERIODIC_SYNC: periodic adv report, sync handle 1 data status 0 data len 28 rssi -47 +I (1132) PERIODIC_SYNC: periodic adv report, sync handle 1 data status 0 data len 28 rssi -49 +I (1212) PERIODIC_SYNC: periodic adv report, sync handle 1 data status 0 data len 28 rssi -48 +I (1292) PERIODIC_SYNC: ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT, sync handle 1 + +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults index 0cb380576689..9cd61576dd5d 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults @@ -348,7 +348,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -366,7 +365,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_EFF=1 CONFIG_BTDM_CTRL_BLE_MAX_ACT=10 @@ -406,7 +405,7 @@ CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BTDM_CTRL_SLEEP_MODE_EFF=0 CONFIG_BTDM_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BTDM_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -606,7 +605,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32c3 index 2c321ce3311d..e55b5c1931dc 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32s3 index 1394477da8ac..4d6c5551966d 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/sdkconfig.defaults.esp32s3 @@ -465,7 +465,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -525,14 +524,14 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # # # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -739,7 +738,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/tutorial/Periodic_Sync_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/tutorial/Periodic_Sync_Example_Walkthrough.md new file mode 100644 index 000000000000..37375c551fd4 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/tutorial/Periodic_Sync_Example_Walkthrough.md @@ -0,0 +1,354 @@ +#Periodic Sync Example Walkthrough + +## Introduction +In this tutorial, the Periodic sync example code for the ESP32C3 is reviewed. The code implement Bluetooth Low Energy (BLE5.0) periodic sync , which scans for nearby peripheral which can support legacy, extended and periodic advertisement. Periodic Sync allow the advertiser to sync with scanner so that scanner and advertiser wake up at same time. + +* ADV_EXT_IND is over primary advertising channels +* AUX_ADV_IND and AUX_SYNC_IND are over secondary advertising channels + +Little info about the EXT_ADV_IND , AUX_ADV_IND and AUX_SYNC_IND with scanner support of periodic sync. + +ADV_EXT_IND is over primary advertising channels and is used to indicate that an advertisement will be sent on a secondary advertisement channel. The information in ADV_EXT_IND will inform the scanner: + +* Which secondary advertising channel will be used by AUX_ADV_IND +* Which PHY will be used by AUX_ADV_IND, 1M PHY, 2M PHY, or 1M Coded PHY +* When AUX_ADV_IND will be presented on that specified secondary advertising channel + +If the scanner is capable of periodic advertising, it will enable its receiver at a specific channel and PHY at a specific time slot. + +AUX_ADV_IND is over the secondary advertising channels and is used to indicate a periodic advertising event. The information in AUX_ADV_IND, which points to the first AUX_SYNC_IND, are: + +* The offset time of the next periodic advertising packet +* The interval of periodic advertising +* The secondary channel map used through this periodic advertising lifetime +Access address, etc. + +With this information, the scanner can synchronize with the advertiser and they will dance together. + +*AUX_SYNC_IND includes the AdvData which needs to be periodically advertised. + +## Includes + +```c +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h +#include "esp_system.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "sdkconfig.h" +#include "freertos/semphr.h" +``` + +These `includes` are required for the FreeRTOS and underlaying system components to run, including the logging functionality and a library to store data in non-volatile flash memory. We are interested in `“bt.h”`, `“esp_bt_main.h”`, `"esp_gap_ble_api.h"` and `“esp_gattc_api.h”`, which expose the BLE APIs required to implement this example. + +* `esp_bt.h`: configures the BT controller and VHCI from the host side. +* `esp_bt_main.h`: initializes and enables the Bluedroid stack. +* `esp_gap_ble_api.h`: implements the GAP configuration, such as advertising and connection parameters. +* `esp_gattc_api.h`: implements the GATT Client configuration, such as connecting to peripherals and searching for services. + +## Main Entry Point + +```c +void app_main(void) +{ + esp_err_t ret; + + // Initialize NVS. + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(LOG_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret) +); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(LOG_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(LOG_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(LOG_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret){ + ESP_LOGE(LOG_TAG, "gap register error, error code = %x", ret); + return; + } + + vTaskDelay(200 / portTICK_PERIOD_MS); + + test_sem = xSemaphoreCreateBinary(); + + FUNC_SEND_WAIT_SEM(esp_ble_gap_set_ext_scan_params(&ext_scan_params), test_sem); + FUNC_SEND_WAIT_SEM(esp_ble_gap_start_ext_scan(EXT_SCAN_DURATION, EXT_SCAN_PERIOD), test_sem); + + + return; +} +``` +The main function starts by initializing the non-volatile storage library. This library allows to save key-value pairs in flash memory and is used by some components such as the Wi-Fi library to save the SSID and password: + +```c +esp_err_t ret = nvs_flash_init(); +if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); +} +ESP_ERROR_CHECK( ret ); +``` + +## BT Controller and Stack Initialization + +The main function also initializes the BT controller by first creating a BT controller configuration structure named `esp_bt_controller_config_t` with default settings generated by the `BT_CONTROLLER_INIT_CONFIG_DEFAULT()` macro. The BT controller implements the Host Controller Interface (HCI) on the controller side, the Link Layer (LL) and the Physical Layer (PHY). The BT Controller is invisible to the user applications and deals with the lower layers of the BLE stack. The controller configuration includes setting the BT controller stack size, priority and HCI baud rate. With the settings created, the BT controller is initialized and enabled with the `esp_bt_controller_init()` function: + +```c +esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +ret = esp_bt_controller_init(&bt_cfg); +``` + +Next, the controller is enabled in BLE Mode. + +```c +ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); +``` +> The controller should be enabled in `ESP_BT_MODE_BTDM`, if you want to use the dual mode (BLE + +BT). + +There are four Bluetooth modes supported: + +1. `ESP_BT_MODE_IDLE`: Bluetooth not running +2. `ESP_BT_MODE_BLE`: BLE mode +3. `ESP_BT_MODE_CLASSIC_BT`: BT Classic mode +4. `ESP_BT_MODE_BTDM`: Dual mode (BLE + BT Classic) + +After the initialization of the BT controller, the Bluedroid stack, which includes the common definitions and APIs for both BT Classic and BLE, is initialized and enabled by using: + +```c +ret = esp_bluedroid_init(); +ret = esp_bluedroid_enable(); +``` +The main function ends by registering the GAP and GATT event handlers, as well as the Application Profile and set the maximum supported MTU size. + +```c + //register the callback function to the gap module + ret = esp_ble_gap_register_callback(esp_gap_cb); + + //register the callback function to the gattc module + ret = esp_ble_gattc_register_callback(esp_gattc_cb); + + ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID); + + esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500); + if (local_mtu_ret){ + ESP_LOGE(GATTC_TAG, "set local MTU failed, error code = %x", local_mtu_ret); + } +``` + +The GAP and GATT event handlers are the functions used to catch the events generated by the BLE stack and execute functions to configure parameters of the application. Moreover, the event handlers are also used to handle read and write events coming from the central. The GAP event handler takes care of scanning and connecting to servers and the GATT handler manages events that happen after the client has connected to a server, such as searching for services and writing and reading data. The GAP and GATT event handlers are registered by using: + +```c +esp_ble_gap_register_callback(); +esp_ble_gattc_register_callback(); +``` +The functions `esp_gap_cb()` and `esp_gattc_cb()` handle all the events generated by the BLE stack. + +## Setting Scan Parameters +if interested. However, in order to perform the scanning, first the configuration parameters needto be set. +The func will be called in the context of bin semaphore esp_ble_gap_set_ext_scan_params,which takes the param as struct esp_ble_ext_scan_params_t + +```c +/** +* @brief ext scan parameters +*/ +typedef struct { + esp_ble_addr_type_t own_addr_type; /*!< ext scan own addresss type */ + esp_ble_scan_filter_t filter_policy; /*!< ext scan filter policy */ + esp_ble_scan_duplicate_t scan_duplicate; /*!< ext scan duplicate scan */ + esp_ble_ext_scan_cfg_mask_t cfg_mask; /*!< ext scan config mask */ + esp_ble_ext_scan_cfg_t uncoded_cfg; /*!< ext scan uncoded config parameters */ + esp_ble_ext_scan_cfg_t coded_cfg; /*!< ext scan coded config parameters */ +} esp_ble_ext_scan_params_t; + + /** + * @brief ext scan config + */ + typedef struct { + esp_ble_scan_type_t scan_type; /*!< ext scan type */ + uint16_t scan_interval; /*!< ext scan interval. This is defined as the ti +me interval from when the Controller started its last LE scan until it begins the subsequent LE s +can.*/ + //Range: 0x0004 to 0x4000 + //Default: 0x0010 (10 ms) + //Time = N * 0.625 msec + //Time Range: 2.5 msec to 10.24 seconds + + uint16_t scan_window; /*!< ext scan window. The duration of the LE scan +. LE_Scan_Window shall be less than or equal to LE_Scan_Interval*/ + //Range: 0x0004 to 0x4000 //Defaul +t: 0x0010 (10 ms) + //Time = N * 0.625 msec + //Time Range: 2.5 msec to 10240 msec + + } esp_ble_ext_scan_cfg_t; + +``` +An it is initialized as : + +```c +static esp_ble_ext_scan_params_t ext_scan_params = { + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_duplicate = BLE_SCAN_DUPLICATE_ENABLE, + .cfg_mask = ESP_BLE_GAP_EXT_SCAN_CFG_UNCODE_MASK | ESP_BLE_GAP_EXT_SCAN_CFG_CODE_MASK, + .uncoded_cfg = {BLE_SCAN_TYPE_ACTIVE, 40, 40}, + .coded_cfg = {BLE_SCAN_TYPE_ACTIVE, 40, 40}, +}; +``` + +same for the periodic sync: + +```c +/** +* @brief periodic adv sync parameters +*/ +typedef struct { + esp_ble_gap_sync_t filter_policy; /*!< periodic advertising sync filter policy */ + uint8_t sid; /*!< periodic advertising sid */ + esp_ble_addr_type_t addr_type; /*!< periodic advertising address type */ + esp_bd_addr_t addr; /*!< periodic advertising address */ + uint16_t skip; /*!< the maximum number of periodic advertising events t +hat can be skipped */ + uint16_t sync_timeout; /*!< synchronization timeout */ +} esp_ble_gap_periodic_adv_sync_params_t; + +``` +An it is initialized as: +```c +static esp_ble_gap_periodic_adv_sync_params_t periodic_adv_sync_params = { + .filter_policy = 0, + .sid = 0, + .addr_type = BLE_ADDR_TYPE_RANDOM, + .skip = 10, + .sync_timeout = 1000, + }; +``` + The BLE scan parameters are configured so that the type of scanning is active (includes reading he scanning response), it is of public type, allows any advertising device to be read and has a scanning interval of 80 ms (1.25 ms * 0x40) and a scanning window of 80 ms (1.25 ms * 0x40). + + +## Start Scanning +This func invoke to start the scan to get near by discover devices esp_ble_gap_start_ext_scan. + +## Getting Scan Results +The Below call back fun used for the event from start of scan to the end of getting adv report extanded as well as periodic report. +We can differer extended and periodic adv using this event ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT and ESP_GAP_BLE_EXT_ADV_REPORT_EVT. + +```c +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, status %d", param->set_e +xt_scan_params.status); + break; + case ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT, status %d", param->ext_scan_s +tart.status); + break; + case ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT, status %d", param->period_adv_ +stop.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT: + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, status %d", param-> +period_adv_create_sync.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT: + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT, status %d", param-> +period_adv_sync_cancel.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT: + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT, status %d", para +m->period_adv_sync_term.status); + break; + case ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT: + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT, sync handle %d", param->period +ic_adv_sync_lost.sync_handle); + break; + case ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT: + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT, status %d", param->periodic_a +dv_sync_estab.status); + esp_log_buffer_hex("sync addr", param->periodic_adv_sync_estab.adv_addr, 6); + ESP_LOGI(LOG_TAG, "sync handle %d sid %d perioic adv interval %d adv phy %d", param->periodic_adv_sync_estab.sync_handle, + param->periodic_adv_sync_estab.sid, + param->periodic_adv_sync_estab.period_adv_interval, + param->periodic_adv_sync_estab.adv_phy); + break; + case ESP_GAP_BLE_EXT_ADV_REPORT_EVT: { + uint8_t *adv_name = NULL; + uint8_t adv_name_len = 0; + adv_name = esp_ble_resolve_adv_data(param->ext_adv_report.params.adv_data, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + if ((adv_name != NULL) && (memcmp(adv_name, "ESP_MULTI_ADV_80MS", adv_name_len) == 0) + && !periodic_sync) { + periodic_sync = true; + char adv_temp_name[30] = {'0'}; + memcpy(adv_temp_name, adv_name, adv_name_len); + ESP_LOGI(LOG_TAG, "Start create sync with the peer device %s", adv_temp_name); + periodic_adv_sync_params.sid = param->ext_adv_report.params.sid; + periodic_adv_sync_params.addr_type = param->ext_adv_report.params.addr_type; + memcpy(periodic_adv_sync_params.addr, param->ext_adv_report.params.addr, sizeof(esp_bd_addr_t)); + esp_ble_gap_periodic_adv_create_sync(&periodic_adv_sync_params); + } + } + break; + case ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT: + ESP_LOGI(LOG_TAG, "periodic adv report, sync handle %d data status %d data len %d rssi %d +", param->period_adv_report.params.sync_handle, + param->period_adv_report.params.data_status, + + param->period_adv_report.params.data_length, + + param->period_adv_report.params.rssi); + break; + + default: + break; + } +} +``` +## Default Config +Here we are doing scan as Active with the fixed duration of 80msec. + + +## Conclusion + +We have reviewed the Periodic Sync example code for the ESP32C3. This example scans for nearby devices which support extended adv and periodic adv. diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md index 5a6274be3269..63d6e11bc865 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md @@ -1,12 +1,12 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -ESP-IDF A2DP-SINK demo +A2DP-SINK EXAMPLE ====================== -Demo of A2DP audio sink role +Example of A2DP audio sink role -This is the demo of API implementing Advanced Audio Distribution Profile to receive an audio stream. +This is the example of API implementing Advanced Audio Distribution Profile to receive an audio stream. This example involves the use of Bluetooth legacy profile A2DP for audio stream reception, AVRCP for media information notifications, and I2S for audio stream output interface. @@ -34,9 +34,9 @@ If the internal DAC is selected, analog audio will be available on GPIO25 and GP idf.py menuconfig ``` -* Set the use of external I2S codec or internal DAC for audio output, and configure the output PINs under A2DP Example Configuration +* Choose external I2S codec or internal DAC for audio output, and configure the output PINs under A2DP Example Configuration -* Enable Classic Bluetooth and A2DP under Component config --> Bluetooth --> Bluedroid Enable +* Enable Classic Bluetooth and A2DP under **Component config --> Bluetooth --> Bluedroid Enable** ### Build and Flash @@ -72,5 +72,5 @@ I (128697) BT_AV: Audio packet count 400 Also, the sound will be heard if a loudspeaker is connected and possible external I2S codec is correctly configured. For ESP32 A2DP source example, the sound is noise as the audio source generates the samples with a random sequence. ## Troubleshooting -* For current stage, the supported audio codec in ESP32 A2DP is SBC. SBC data stream is transmitted to A2DP sink and then decoded into PCM samples as output. The PCM data format is normally of 44.1kHz sampling rate, two-channel 16-bit sample stream. Other decoder configurations in ESP32 A2DP sink is supported but need additional modifications of protocol stack settings. +* For current stage, the supported audio codec in ESP32 A2DP is SBC. SBC data stream is transmitted to A2DP sink and then decoded into PCM samples as output. The PCM data format is normally of 44.1kHz sampling rate, two-channel 16-bit sample stream. Other SBC configurations in ESP32 A2DP sink is supported but need additional modifications of protocol stack settings. * As a usage limitation, ESP32 A2DP sink can support at most one connection with remote A2DP source devices. Also, A2DP sink cannot be used together with A2DP source at the same time, but can be used with other profiles such as SPP and HFP. diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c index 35bcff13da7a..f9f4210e2dcb 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c @@ -1,4 +1,3 @@ - /* This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -27,121 +26,237 @@ #include "sys/lock.h" -// AVRCP used transaction label +/* AVRCP used transaction labels */ #define APP_RC_CT_TL_GET_CAPS (0) #define APP_RC_CT_TL_GET_META_DATA (1) #define APP_RC_CT_TL_RN_TRACK_CHANGE (2) #define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3) #define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4) +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* allocate new meta buffer */ +static void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param); +/* handler for new track is loaded */ +static void bt_av_new_track(void); +/* handler for track status change */ +static void bt_av_playback_changed(void); +/* handler for track playing position change */ +static void bt_av_play_pos_changed(void); +/* notification event handler */ +static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter); +/* installation for i2s */ +static void bt_i2s_driver_install(void); +/* uninstallation for i2s */ +static void bt_i2s_driver_uninstall(void); +/* set volume by remote controller */ +static void volume_set_by_controller(uint8_t volume); +/* set volume by local host */ +static void volume_set_by_local_host(uint8_t volume); +/* simulation volume change */ +static void volume_change_simulation(void *arg); /* a2dp event handler */ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param); -/* avrc CT event handler */ +/* avrc controller event handler */ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param); -/* avrc TG event handler */ +/* avrc target event handler */ static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param); -static uint32_t s_pkt_cnt = 0; +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +static uint32_t s_pkt_cnt = 0; /* count for audio packet */ static esp_a2d_audio_state_t s_audio_state = ESP_A2D_AUDIO_STATE_STOPPED; + /* audio stream datapath state */ static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; + /* connection state in string */ static const char *s_a2d_audio_state_str[] = {"Suspended", "Stopped", "Started"}; + /* audio stream datapath state in string */ static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; + /* AVRC target notification capability bit mask */ static _lock_t s_volume_lock; -static xTaskHandle s_vcs_task_hdl = NULL; -static uint8_t s_volume = 0; -static bool s_volume_notify; +static xTaskHandle s_vcs_task_hdl = NULL; /* handle for volume change simulation task */ +static uint8_t s_volume = 0; /* local volume value */ +static bool s_volume_notify; /* notify volume change or not */ -/* callback for A2DP sink */ -void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) +/******************************** + * STATIC FUNCTION DEFINITIONS + *******************************/ + +static void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param) { - switch (event) { - case ESP_A2D_CONNECTION_STATE_EVT: - case ESP_A2D_AUDIO_STATE_EVT: - case ESP_A2D_AUDIO_CFG_EVT: - case ESP_A2D_PROF_STATE_EVT: { - bt_app_work_dispatch(bt_av_hdl_a2d_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL); - break; - } - default: - ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); - break; - } + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); + uint8_t *attr_text = (uint8_t *) malloc (rc->meta_rsp.attr_length + 1); + + memcpy(attr_text, rc->meta_rsp.attr_text, rc->meta_rsp.attr_length); + attr_text[rc->meta_rsp.attr_length] = 0; + rc->meta_rsp.attr_text = attr_text; } -void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) +static void bt_av_new_track(void) { - write_ringbuf(data, len); - if (++s_pkt_cnt % 100 == 0) { - ESP_LOGI(BT_AV_TAG, "Audio packet count %u", s_pkt_cnt); + uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | + ESP_AVRC_MD_ATTR_ARTIST | + ESP_AVRC_MD_ATTR_ALBUM | + ESP_AVRC_MD_ATTR_GENRE; + esp_avrc_ct_send_metadata_cmd(APP_RC_CT_TL_GET_META_DATA, attr_mask); + + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, + ESP_AVRC_RN_TRACK_CHANGE)) { + esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_TRACK_CHANGE, + ESP_AVRC_RN_TRACK_CHANGE, 0); } } -void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param) +static void bt_av_playback_changed(void) { - esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); - uint8_t *attr_text = (uint8_t *) malloc (rc->meta_rsp.attr_length + 1); - memcpy(attr_text, rc->meta_rsp.attr_text, rc->meta_rsp.attr_length); - attr_text[rc->meta_rsp.attr_length] = 0; + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, + ESP_AVRC_RN_PLAY_STATUS_CHANGE)) { + esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAYBACK_CHANGE, + ESP_AVRC_RN_PLAY_STATUS_CHANGE, 0); + } +} - rc->meta_rsp.attr_text = attr_text; +static void bt_av_play_pos_changed(void) +{ + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, + ESP_AVRC_RN_PLAY_POS_CHANGED)) { + esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAY_POS_CHANGE, + ESP_AVRC_RN_PLAY_POS_CHANGED, 10); + } } -void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) +static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) { - switch (event) { - case ESP_AVRC_CT_METADATA_RSP_EVT: - bt_app_alloc_meta_buffer(param); - /* fall through */ - case ESP_AVRC_CT_CONNECTION_STATE_EVT: - case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: - case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: - case ESP_AVRC_CT_REMOTE_FEATURES_EVT: - case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { - bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + switch (event_id) { + /* when new track is loaded, this event comes */ + case ESP_AVRC_RN_TRACK_CHANGE: + bt_av_new_track(); break; - } + /* when track status changed, this event comes */ + case ESP_AVRC_RN_PLAY_STATUS_CHANGE: + ESP_LOGI(BT_AV_TAG, "Playback status changed: 0x%x", event_parameter->playback); + bt_av_playback_changed(); + break; + /* when track playing position changed, this event comes */ + case ESP_AVRC_RN_PLAY_POS_CHANGED: + ESP_LOGI(BT_AV_TAG, "Play position changed: %d-ms", event_parameter->play_pos); + bt_av_play_pos_changed(); + break; + /* others */ default: - ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + ESP_LOGI(BT_AV_TAG, "unhandled event: %d", event_id); break; } } -void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) +void bt_i2s_driver_install(void) { - switch (event) { - case ESP_AVRC_TG_CONNECTION_STATE_EVT: - case ESP_AVRC_TG_REMOTE_FEATURES_EVT: - case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: - case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: - case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: - case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: - bt_app_work_dispatch(bt_av_hdl_avrc_tg_evt, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); - break; - default: - ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); - break; + /* I2S configuration parameters */ + i2s_config_t i2s_config = { +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, +#else + .mode = I2S_MODE_MASTER | I2S_MODE_TX, /* only TX */ +#endif + .sample_rate = 44100, + .bits_per_sample = 16, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .dma_buf_count = 6, + .dma_buf_len = 60, + .intr_alloc_flags = 0, /* default interrupt priority */ + .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ + }; + + /* enable I2S */ + i2s_driver_install(0, &i2s_config, 0, NULL); +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); + i2s_set_pin(0, NULL); +#else + i2s_pin_config_t pin_config = { + .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, + .data_in_num = -1 /* not used */ + }; + i2s_set_pin(0, &pin_config); +#endif +} + +void bt_i2s_driver_uninstall(void) +{ + i2s_driver_uninstall(0); +} + +static void volume_set_by_controller(uint8_t volume) +{ + ESP_LOGI(BT_RC_TG_TAG, "Volume is set by remote controller to: %d%%", (uint32_t)volume * 100 / 0x7f); + /* set the volume in protection of lock */ + _lock_acquire(&s_volume_lock); + s_volume = volume; + _lock_release(&s_volume_lock); +} + +static void volume_set_by_local_host(uint8_t volume) +{ + ESP_LOGI(BT_RC_TG_TAG, "Volume is set locally to: %d%%", (uint32_t)volume * 100 / 0x7f); + /* set the volume in protection of lock */ + _lock_acquire(&s_volume_lock); + s_volume = volume; + _lock_release(&s_volume_lock); + + /* send notification response to remote AVRCP controller */ + if (s_volume_notify) { + esp_avrc_rn_param_t rn_param; + rn_param.volume = s_volume; + esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); + s_volume_notify = false; + } +} + +static void volume_change_simulation(void *arg) +{ + ESP_LOGI(BT_RC_TG_TAG, "start volume change simulation"); + + for (;;) { + /* volume up locally every 10 seconds */ + vTaskDelay(10000 / portTICK_RATE_MS); + uint8_t volume = (s_volume + 5) & 0x7f; + volume_set_by_local_host(volume); } } static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) { - ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event); + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + esp_a2d_cb_param_t *a2d = NULL; + switch (event) { + /* when connection state changed, this event comes */ case ESP_A2D_CONNECTION_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(p_param); uint8_t *bda = a2d->conn_stat.remote_bda; ESP_LOGI(BT_AV_TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", - s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); bt_i2s_task_shut_down(); + bt_i2s_driver_uninstall(); } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED){ esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); bt_i2s_task_start_up(); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTING) { + bt_i2s_driver_install(); } break; } + /* when audio stream transmission state changed, this event comes */ case ESP_A2D_AUDIO_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(p_param); ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); @@ -151,10 +266,11 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } break; } + /* when audio codec is configured, this event comes */ case ESP_A2D_AUDIO_CFG_EVT: { a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type %d", a2d->audio_cfg.mcc.type); - // for now only SBC stream is supported + ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", a2d->audio_cfg.mcc.type); + /* for now only SBC stream is supported */ if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) { int sample_rate = 16000; char oct0 = a2d->audio_cfg.mcc.cie.sbc[0]; @@ -167,113 +283,75 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } i2s_set_clk(0, sample_rate, 16, 2); - ESP_LOGI(BT_AV_TAG, "Configure audio player %x-%x-%x-%x", + ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], a2d->audio_cfg.mcc.cie.sbc[1], a2d->audio_cfg.mcc.cie.sbc[2], a2d->audio_cfg.mcc.cie.sbc[3]); - ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate=%d", sample_rate); + ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate); } break; } + /* when a2dp init or deinit completed, this event comes */ case ESP_A2D_PROF_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(p_param); if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) { - ESP_LOGI(BT_AV_TAG,"A2DP PROF STATE: Init Compl\n"); + ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete"); } else { - ESP_LOGI(BT_AV_TAG,"A2DP PROF STATE: Deinit Compl\n"); + ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete"); } break; } + /* others */ default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); - break; - } -} - -static void bt_av_new_track(void) -{ - // request metadata - uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST | ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_GENRE; - esp_avrc_ct_send_metadata_cmd(APP_RC_CT_TL_GET_META_DATA, attr_mask); - - // register notification if peer support the event_id - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_TRACK_CHANGE)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_TRACK_CHANGE, ESP_AVRC_RN_TRACK_CHANGE, 0); - } -} - -static void bt_av_playback_changed(void) -{ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_PLAY_STATUS_CHANGE)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAYBACK_CHANGE, ESP_AVRC_RN_PLAY_STATUS_CHANGE, 0); - } -} - -static void bt_av_play_pos_changed(void) -{ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_PLAY_POS_CHANGED)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAY_POS_CHANGE, ESP_AVRC_RN_PLAY_POS_CHANGED, 10); - } -} - -void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) -{ - switch (event_id) { - case ESP_AVRC_RN_TRACK_CHANGE: - bt_av_new_track(); - break; - case ESP_AVRC_RN_PLAY_STATUS_CHANGE: - ESP_LOGI(BT_AV_TAG, "Playback status changed: 0x%x", event_parameter->playback); - bt_av_playback_changed(); - break; - case ESP_AVRC_RN_PLAY_POS_CHANGED: - ESP_LOGI(BT_AV_TAG, "Play position changed: %d-ms", event_parameter->play_pos); - bt_av_play_pos_changed(); + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } } static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) { - ESP_LOGD(BT_RC_CT_TAG, "%s evt %d", __func__, event); + ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param); + switch (event) { + /* when connection state changed, this event comes */ case ESP_AVRC_CT_CONNECTION_STATE_EVT: { uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state event: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); if (rc->conn_stat.connected) { - // get remote supported event_ids of peer AVRCP Target esp_avrc_ct_send_get_rn_capabilities_cmd(APP_RC_CT_TL_GET_CAPS); } else { - // clear peer notification capability record s_avrc_peer_rn_cap.bits = 0; } break; } + /* when passthrough responsed, this event comes */ case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state); break; } + /* when metadata responsed, this event comes */ case ESP_AVRC_CT_METADATA_RSP_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); free(rc->meta_rsp.attr_text); break; } + /* when notified, this event comes */ case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); break; } + /* when feature of remote device indicated, this event comes */ case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC remote features %x, TG features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.tg_feat_flag); break; } + /* when notification capability of peer device got, this event comes */ case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { ESP_LOGI(BT_RC_CT_TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, rc->get_rn_caps_rsp.evt_set.bits); @@ -283,74 +361,46 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) bt_av_play_pos_changed(); break; } + /* others */ default: - ESP_LOGE(BT_RC_CT_TAG, "%s unhandled evt %d", __func__, event); + ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); break; } } -static void volume_set_by_controller(uint8_t volume) -{ - ESP_LOGI(BT_RC_TG_TAG, "Volume is set by remote controller %d%%\n", (uint32_t)volume * 100 / 0x7f); - _lock_acquire(&s_volume_lock); - s_volume = volume; - _lock_release(&s_volume_lock); -} - -static void volume_set_by_local_host(uint8_t volume) -{ - ESP_LOGI(BT_RC_TG_TAG, "Volume is set locally to: %d%%", (uint32_t)volume * 100 / 0x7f); - _lock_acquire(&s_volume_lock); - s_volume = volume; - _lock_release(&s_volume_lock); - - if (s_volume_notify) { - esp_avrc_rn_param_t rn_param; - rn_param.volume = s_volume; - esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); - s_volume_notify = false; - } -} - -static void volume_change_simulation(void *arg) -{ - ESP_LOGI(BT_RC_TG_TAG, "start volume change simulation"); - - for (;;) { - vTaskDelay(10000 / portTICK_RATE_MS); - - uint8_t volume = (s_volume + 5) & 0x7f; - volume_set_by_local_host(volume); - } -} - static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param) { - ESP_LOGD(BT_RC_TG_TAG, "%s evt %d", __func__, event); + ESP_LOGD(BT_RC_TG_TAG, "%s event: %d", __func__, event); + esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(p_param); + switch (event) { + /* when connection state changed, this event comes */ case ESP_AVRC_TG_CONNECTION_STATE_EVT: { uint8_t *bda = rc->conn_stat.remote_bda; ESP_LOGI(BT_RC_TG_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); if (rc->conn_stat.connected) { - // create task to simulate volume change - xTaskCreate(volume_change_simulation, "vcsT", 2048, NULL, 5, &s_vcs_task_hdl); + /* create task to simulate volume change */ + xTaskCreate(volume_change_simulation, "vcsTask", 2048, NULL, 5, &s_vcs_task_hdl); } else { vTaskDelete(s_vcs_task_hdl); ESP_LOGI(BT_RC_TG_TAG, "Stop volume change simulation"); } break; } + /* when passthrough commanded, this event comes */ case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { ESP_LOGI(BT_RC_TG_TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); break; } + /* when absolute volume command from remote device set, this event comes */ case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100/ 0x7f); + ESP_LOGI(BT_RC_TG_TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100 / 0x7f); volume_set_by_controller(rc->set_abs_vol.volume); break; } + /* when notification registered, this event comes */ case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { ESP_LOGI(BT_RC_TG_TAG, "AVRC register event notification: %d, param: 0x%x", rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { @@ -361,12 +411,81 @@ static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param) } break; } + /* when feature of remote device indicated, this event comes */ case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC remote features %x, CT features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); + ESP_LOGI(BT_RC_TG_TAG, "AVRC remote features: %x, CT features: %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); break; } + /* others */ default: - ESP_LOGE(BT_RC_TG_TAG, "%s unhandled evt %d", __func__, event); + ESP_LOGE(BT_RC_TG_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) +{ + switch (event) { + case ESP_A2D_CONNECTION_STATE_EVT: + case ESP_A2D_AUDIO_STATE_EVT: + case ESP_A2D_AUDIO_CFG_EVT: + case ESP_A2D_PROF_STATE_EVT: { + bt_app_work_dispatch(bt_av_hdl_a2d_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL); + break; + } + default: + ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); + break; + } +} + +void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) +{ + write_ringbuf(data, len); + + /* log the number every 100 packets */ + if (++s_pkt_cnt % 100 == 0) { + ESP_LOGI(BT_AV_TAG, "Audio packet count: %u", s_pkt_cnt); + } +} + +void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_CT_METADATA_RSP_EVT: + bt_app_alloc_meta_buffer(param); + /* fall through */ + case ESP_AVRC_CT_CONNECTION_STATE_EVT: + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { + bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + break; + } + default: + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_TG_CONNECTION_STATE_EVT: + case ESP_AVRC_TG_REMOTE_FEATURES_EVT: + case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: + case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: + bt_app_work_dispatch(bt_av_hdl_avrc_tg_evt, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + break; + default: + ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); break; } } diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h index 46342daadba2..d23e71ed93cf 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h @@ -13,27 +13,40 @@ #include "esp_a2dp_api.h" #include "esp_avrc_api.h" -#define BT_AV_TAG "BT_AV" -#define BT_RC_TG_TAG "RCTG" -#define BT_RC_CT_TAG "RCCT" +/* log tags */ +#define BT_AV_TAG "BT_AV" +#define BT_RC_TG_TAG "RC_TG" +#define BT_RC_CT_TAG "RC_CT" /** - * @brief callback function for A2DP sink + * @brief callback function for A2DP sink + * + * @param [in] event event id + * @param [in] param callback parameter */ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); /** - * @brief callback function for A2DP sink audio data stream + * @brief callback function for A2DP sink audio data stream + * + * @param [out] data data stream writteen by application task + * @param [in] len length of data stream in byte */ void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); /** - * @brief callback function for AVRCP controller + * @brief callback function for AVRCP controller + * + * @param [in] event event id + * @param [in] param callback parameter */ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); /** - * @brief callback function for AVRCP target + * @brief callback function for AVRCP target + * + * @param [in] event event id + * @param [in] param callback parameter */ void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c index 559402cc3efd..a36c2b42cceb 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c @@ -19,41 +19,31 @@ #include "driver/i2s.h" #include "freertos/ringbuf.h" +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* handler for application task */ static void bt_app_task_handler(void *arg); +/* handler for I2S task */ +static void bt_i2s_task_handler(void *arg); +/* message sender */ static bool bt_app_send_msg(bt_app_msg_t *msg); +/* handle dispatched messages */ static void bt_app_work_dispatched(bt_app_msg_t *msg); -static xQueueHandle s_bt_app_task_queue = NULL; -static xTaskHandle s_bt_app_task_handle = NULL; -static xTaskHandle s_bt_i2s_task_handle = NULL; -static RingbufHandle_t s_ringbuf_i2s = NULL;; - -bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) -{ - ESP_LOGD(BT_APP_CORE_TAG, "%s event 0x%x, param len %d", __func__, event, param_len); - - bt_app_msg_t msg; - memset(&msg, 0, sizeof(bt_app_msg_t)); - - msg.sig = BT_APP_SIG_WORK_DISPATCH; - msg.event = event; - msg.cb = p_cback; +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ - if (param_len == 0) { - return bt_app_send_msg(&msg); - } else if (p_params && param_len > 0) { - if ((msg.param = malloc(param_len)) != NULL) { - memcpy(msg.param, p_params, param_len); - /* check if caller has provided a copy callback to do the deep copy */ - if (p_copy_cback) { - p_copy_cback(&msg, msg.param, p_params); - } - return bt_app_send_msg(&msg); - } - } +static xQueueHandle s_bt_app_task_queue = NULL; /* handle of work queue */ +static xTaskHandle s_bt_app_task_handle = NULL; /* handle of application task */ +static xTaskHandle s_bt_i2s_task_handle = NULL; /* handle of I2S task */ +static RingbufHandle_t s_ringbuf_i2s = NULL; /* handle of ringbuffer for I2S */ - return false; -} +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ static bool bt_app_send_msg(bt_app_msg_t *msg) { @@ -78,17 +68,20 @@ static void bt_app_work_dispatched(bt_app_msg_t *msg) static void bt_app_task_handler(void *arg) { bt_app_msg_t msg; + for (;;) { + /* receive message from work queue and handle it */ if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (portTickType)portMAX_DELAY)) { - ESP_LOGD(BT_APP_CORE_TAG, "%s, sig 0x%x, 0x%x", __func__, msg.sig, msg.event); + ESP_LOGD(BT_APP_CORE_TAG, "%s, signal: 0x%x, event: 0x%x", __func__, msg.sig, msg.event); + switch (msg.sig) { case BT_APP_SIG_WORK_DISPATCH: bt_app_work_dispatched(&msg); break; default: - ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled sig: %d", __func__, msg.sig); + ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled signal: %d", __func__, msg.sig); break; - } // switch (msg.sig) + } /* switch (msg.sig) */ if (msg.param) { free(msg.param); @@ -97,11 +90,57 @@ static void bt_app_task_handler(void *arg) } } +static void bt_i2s_task_handler(void *arg) +{ + uint8_t *data = NULL; + size_t item_size = 0; + size_t bytes_written = 0; + + for (;;) { + /* receive data from ringbuffer and write it to I2S DMA transmit buffer */ + data = (uint8_t *)xRingbufferReceive(s_ringbuf_i2s, &item_size, (portTickType)portMAX_DELAY); + if (item_size != 0){ + i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); + vRingbufferReturnItem(s_ringbuf_i2s, (void *)data); + } + } +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) +{ + ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len); + + bt_app_msg_t msg; + memset(&msg, 0, sizeof(bt_app_msg_t)); + + msg.sig = BT_APP_SIG_WORK_DISPATCH; + msg.event = event; + msg.cb = p_cback; + + if (param_len == 0) { + return bt_app_send_msg(&msg); + } else if (p_params && param_len > 0) { + if ((msg.param = malloc(param_len)) != NULL) { + memcpy(msg.param, p_params, param_len); + /* check if caller has provided a copy callback to do the deep copy */ + if (p_copy_cback) { + p_copy_cback(msg.param, p_params, param_len); + } + return bt_app_send_msg(&msg); + } + } + + return false; +} + void bt_app_task_start_up(void) { s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); - xTaskCreate(bt_app_task_handler, "BtAppT", 3072, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle); - return; + xTaskCreate(bt_app_task_handler, "BtAppTask", 3072, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle); } void bt_app_task_shut_down(void) @@ -116,30 +155,12 @@ void bt_app_task_shut_down(void) } } -static void bt_i2s_task_handler(void *arg) -{ - uint8_t *data = NULL; - size_t item_size = 0; - size_t bytes_written = 0; - - for (;;) { - data = (uint8_t *)xRingbufferReceive(s_ringbuf_i2s, &item_size, (portTickType)portMAX_DELAY); - if (item_size != 0){ - i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); - vRingbufferReturnItem(s_ringbuf_i2s,(void *)data); - } - } -} - void bt_i2s_task_start_up(void) { - s_ringbuf_i2s = xRingbufferCreate(8 * 1024, RINGBUF_TYPE_BYTEBUF); - if(s_ringbuf_i2s == NULL){ + if ((s_ringbuf_i2s = xRingbufferCreate(8 * 1024, RINGBUF_TYPE_BYTEBUF)) == NULL) { return; } - - xTaskCreate(bt_i2s_task_handler, "BtI2ST", 1024, NULL, configMAX_PRIORITIES - 3, &s_bt_i2s_task_handle); - return; + xTaskCreate(bt_i2s_task_handler, "BtI2STask", 1024, NULL, configMAX_PRIORITIES - 3, &s_bt_i2s_task_handle); } void bt_i2s_task_shut_down(void) @@ -148,7 +169,6 @@ void bt_i2s_task_shut_down(void) vTaskDelete(s_bt_i2s_task_handle); s_bt_i2s_task_handle = NULL; } - if (s_ringbuf_i2s) { vRingbufferDelete(s_ringbuf_i2s); s_ringbuf_i2s = NULL; @@ -158,9 +178,6 @@ void bt_i2s_task_shut_down(void) size_t write_ringbuf(const uint8_t *data, size_t size) { BaseType_t done = xRingbufferSend(s_ringbuf_i2s, (void *)data, size, (portTickType)portMAX_DELAY); - if(done){ - return size; - } else { - return 0; - } + + return done ? size : 0; } diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h index eaa390de946b..b5534108ce7d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h @@ -13,41 +13,78 @@ #include #include -#define BT_APP_CORE_TAG "BT_APP_CORE" +/* log tag */ +#define BT_APP_CORE_TAG "BT_APP_CORE" -#define BT_APP_SIG_WORK_DISPATCH (0x01) +/* signal for `bt_app_work_dispatch` */ +#define BT_APP_SIG_WORK_DISPATCH (0x01) /** - * @brief handler for the dispatched work + * @brief handler for the dispatched work + * + * @param [in] event event id + * @param [in] param handler parameter */ typedef void (* bt_app_cb_t) (uint16_t event, void *param); /* message to be sent */ typedef struct { - uint16_t sig; /*!< signal to bt_app_task */ - uint16_t event; /*!< message event id */ - bt_app_cb_t cb; /*!< context switch callback */ - void *param; /*!< parameter area needs to be last */ + uint16_t sig; /*!< signal to bt_app_task */ + uint16_t event; /*!< message event id */ + bt_app_cb_t cb; /*!< context switch callback */ + void *param; /*!< parameter area needs to be last */ } bt_app_msg_t; /** - * @brief parameter deep-copy function to be customized + * @brief parameter deep-copy function to be customized + * + * @param [out] p_dest pointer to destination data + * @param [in] p_src pointer to source data + * @param [in] len data length in byte */ -typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src); +typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len); /** - * @brief work dispatcher for the application task + * @brief work dispatcher for the application task + * + * @param [in] p_cback callback function + * @param [in] event event id + * @param [in] p_params callback paramters + * @param [in] param_len parameter length in byte + * @param [in] p_copy_cback parameter deep-copy function + * + * @return true if work dispatch successfully, false otherwise */ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback); +/** + * @brief start up the application task + */ void bt_app_task_start_up(void); +/** + * @brief shut down the application task + */ void bt_app_task_shut_down(void); +/** + * @brief start up the is task + */ void bt_i2s_task_start_up(void); +/** + * @brief shut down the I2S task + */ void bt_i2s_task_shut_down(void); +/** + * @brief write data to ringbuffer + * + * @param [in] data pointer to data stream + * @param [in] size data length in byte + * + * @return size if writteen ringbuffer successfully, 0 others + */ size_t write_ringbuf(const uint8_t *data, size_t size); #endif /* __BT_APP_CORE_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c index c6b37034d92c..e77953d47b81 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c @@ -33,178 +33,158 @@ #include "esp_avrc_api.h" #include "driver/i2s.h" -/* event for handler "bt_av_hdl_stack_up */ +/* device name */ +#define LOCAL_DEVICE_NAME "ESP_SPEAKER" + +/* event for stack up */ enum { BT_APP_EVT_STACK_UP = 0, }; +/******************************** + * STATIC FUNCTION DECLARATIONS + *******************************/ + +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); /* handler for bluetooth stack enabled events */ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ -void app_main(void) -{ - /* Initialize NVS — it is used to store PHY calibration data */ - esp_err_t err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - ESP_ERROR_CHECK(err); - - i2s_config_t i2s_config = { -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, // Only TX -#endif - .sample_rate = 44100, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_buf_count = 6, - .dma_buf_len = 60, - .intr_alloc_flags = 0, //Default interrupt priority - .tx_desc_auto_clear = true //Auto clear tx descriptor on underflow - }; - - - i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - i2s_set_pin(0, NULL); -#else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 //Not used - }; - - i2s_set_pin(0, &pin_config); -#endif - - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - if ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(err)); - return; - } - - if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(err)); - return; - } - - if ((err = esp_bluedroid_init()) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(err)); - return; - } - - if ((err = esp_bluedroid_enable()) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(err)); - return; - } - - /* create application task */ - bt_app_task_start_up(); - - /* Bluetooth device name, connection mode and profile set up */ - bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); - -#if (CONFIG_BT_SSP_ENABLED == true) - /* Set default parameters for Secure Simple Pairing */ - esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; - esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; - esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); -#endif - - /* - * Set default parameters for Legacy Pairing - * Use fixed pin code - */ - esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; - esp_bt_pin_code_t pin_code; - pin_code[0] = '1'; - pin_code[1] = '2'; - pin_code[2] = '3'; - pin_code[3] = '4'; - esp_bt_gap_set_pin(pin_type, 4, pin_code); - -} - -void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { switch (event) { + /* when authentication completed, this event comes */ case ESP_BT_GAP_AUTH_CMPL_EVT: { if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name); esp_log_buffer_hex(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); } else { - ESP_LOGE(BT_AV_TAG, "authentication failed, status:%d", param->auth_cmpl.stat); + ESP_LOGE(BT_AV_TAG, "authentication failed, status: %d", param->auth_cmpl.stat); } break; } #if (CONFIG_BT_SSP_ENABLED == true) + /* when Security Simple Pairing user confirmation requested, this event comes */ case ESP_BT_GAP_CFM_REQ_EVT: ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); break; + /* when Security Simple Pairing passkey notified, this event comes */ case ESP_BT_GAP_KEY_NOTIF_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey); + ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey: %d", param->key_notif.passkey); break; + /* when Security Simple Pairing passkey requested, this event comes */ case ESP_BT_GAP_KEY_REQ_EVT: ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); break; #endif + /* when GAP mode changed, this event comes */ case ESP_BT_GAP_MODE_CHG_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%d", param->mode_chg.mode); + ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode: %d", param->mode_chg.mode); break; - + /* others */ default: { ESP_LOGI(BT_AV_TAG, "event: %d", event); break; } } - return; } + static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) { - ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event); + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + switch (event) { + /* when do the stack up, this event comes */ case BT_APP_EVT_STACK_UP: { - /* set up device name */ - char *dev_name = "ESP_SPEAKER"; - esp_bt_dev_set_device_name(dev_name); - + esp_bt_dev_set_device_name(LOCAL_DEVICE_NAME); esp_bt_gap_register_callback(bt_app_gap_cb); - /* initialize AVRCP controller */ - esp_avrc_ct_init(); + assert(esp_avrc_ct_init() == ESP_OK); esp_avrc_ct_register_callback(bt_app_rc_ct_cb); - /* initialize AVRCP target */ - assert (esp_avrc_tg_init() == ESP_OK); + assert(esp_avrc_tg_init() == ESP_OK); esp_avrc_tg_register_callback(bt_app_rc_tg_cb); esp_avrc_rn_evt_cap_mask_t evt_set = {0}; esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE); assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK); - /* initialize A2DP sink */ + assert(esp_a2d_sink_init() == ESP_OK); esp_a2d_register_callback(&bt_app_a2d_cb); esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); - esp_a2d_sink_init(); /* set discoverable and connectable mode, wait to be connected */ esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); break; } + /* others */ default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } } + +/******************************* + * MAIN ENTRY POINT + ******************************/ + +void app_main(void) +{ + /* initialize NVS — it is used to store PHY calibration data */ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + + /* + * This example only uses the functions of Classical Bluetooth. + * So release the controller memory for Bluetooth Low Energy. + */ + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + if ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(err)); + return; + } + if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(err)); + return; + } + if ((err = esp_bluedroid_init()) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(err)); + return; + } + if ((err = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(err)); + return; + } + +#if (CONFIG_BT_SSP_ENABLED == true) + /* set default parameters for Secure Simple Pairing */ + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + + /* set default parameters for Legacy Pairing (use fixed pin code 1234) */ + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + esp_bt_pin_code_t pin_code; + pin_code[0] = '1'; + pin_code[1] = '2'; + pin_code[2] = '3'; + pin_code[3] = '4'; + esp_bt_gap_set_pin(pin_type, 4, pin_code); + + bt_app_task_start_up(); + /* bluetooth device name, connection mode and profile set up */ + bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults index 52869c8bbb6f..bdbd39fdea35 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults @@ -7,5 +7,3 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y -CONFIG_BT_SPP_ENABLED=n -CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md new file mode 100644 index 000000000000..9ab91fb2c13e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md @@ -0,0 +1,163 @@ +# A2DP Sink Example Walkthrough + +## Introduction + +In this tutorial, the A2DP sink example code is reviewed. The code implements an A2DP sink role, which receives audio stream from A2DP source devices. + +## File Tree + +The file tree of this example is shown below. The [main](../main) folder contains the main files of this example including audio and video related files, program core files, main function file, etc. The [tutorial](../tutorial) folder contains this guidance document. + +```c +└── a2dp_sink +    ├── CMakeLists.txt +    ├── main +    │   ├── bt_app_av.c +    │   ├── bt_app_av.h +    │   ├── bt_app_core.c +    │   ├── bt_app_core.h +    │   ├── CMakeLists.txt +    │   ├── Kconfig.projbuild +    │   └── main.c +    ├── README.md +    ├── sdkconfig.defaults +    └── tutorial +    └── Example_A2DP_Sink.md + +2 directories, 11 files +``` + +## Main Entry Point + +This example is located in the examples folder of the ESP-IDF under the [bluetooth/bluedroid/classic_bt/a2dp_sink](../). The entry point of this program is `app_main()` which contained in [main/main.c](../main/main.c). + +### NVS Initialization + +The main function starts by initializing the non-volatile storage library. This library allows to save key-value pairs in flash memory and is used by some components such as the Wi-Fi library to save the SSID and password: + +```c +/* initialize NVS — it is used to store PHY calibration */ +esp_err_t ret = nvs_flash_init(); +if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); +} +ESP_ERROR_CHECK(ret); +``` + +### Bluetooth Controller and Stack Initialization + +The main function also initializes the Bluetooth Controller with default settings. The Bluetooth Controller is invisible to the user applications and deals with the lower layers of the Bluetooth Stack. Next, the controller is enabled in Classic Bluetooth Mode. + +```c +/* initialize Bluetooth Controller with default configuration */ +esp_bt_controller_config_t bt_cfg = ONTROLLER_INIT_CONFIG_DEFAULT(); +if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize controller ed\n", __func__); + return; +} +/* enable Bluetooth Controller in Classic Bluetooth mode */ +if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != OK) { + ESP_LOGE(BT_AV_TAG, "%s enable controller failed\n", __func__); + return; +} +``` + +After the initialization of the Bluetooth Controller, the Bluedroid Stack, which includes the common definitions and APIs for Classic Bluetooth is initialized and enabled by using: + +```c +/* initialize Bluedroid Host */ +if (esp_bluedroid_init() != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed\n", __func__); + return; +} +/* enable Bluedroid Host */ +if (esp_bluedroid_enable() != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed\n", __func__); + return; +} +``` + +The Classic Bluetooth uses an asynchronous programming paradigm. The entire Bluedroid stack sees the use of events, event handlers, callbacks and state machines. Most APIs are implemented by posting specific type of events to the work queue of Bluedroid Stack. Threads(FreeRTOS) tasks inside Bluedroid then process the events with specific handlers, according to the internal state. When the operations are completed, Bluedroid stack invokes the callback function which is registered by application, to report some other events and information. + +For example, after executing `esp_bt_gap_start_discovery()`, an event of `ESP_BT_GAP_DISC_STATE_CHANGED_EVT` occurs to inform that the discovery state has been changed. Application can do some processing at this time. + +### I2S Installation + +The main function installs I2S to play the audio. A loudspeaker, additional ADC or hardware requirements and possibly an external I2S codec may be needed. + +```c + /* I2S configuration parameters */ + i2s_config_t i2s_config = { +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, +#else + .mode = I2S_MODE_MASTER | I2S_MODE_TX, /* only TX */ +#endif + .sample_rate = 44100, + .bits_per_sample = 16, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .dma_buf_count = 6, + .dma_buf_len = 60, + .intr_alloc_flags = 0, /* default interrupt priority */ + .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ + }; + + /* enable I2S */ + i2s_driver_install(0, &i2s_config, 0, NULL); +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); + i2s_set_pin(0, NULL); +#else + i2s_pin_config_t pin_config = { + .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, + .data_in_num = -1 /* not used */ + }; + i2s_set_pin(0, &pin_config); +#endif +``` + +### Paring Parameter Settings + +The main function continues to set up paring parameters including Secure Simple Pairing and Legacy Pairing. + +```c +#if (CONFIG_BT_SSP_ENABLED == true) + /* set default parameters for Secure Simple Pairing */ + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + + /* set default parameters for Legacy Pairing (Use fixed pin code) */ + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + esp_bt_pin_code_t pin_code; + pin_code[0] = '1'; + pin_code[1] = '2'; + pin_code[2] = '3'; + pin_code[3] = '4'; + esp_bt_gap_set_pin(pin_type, 4, pin_code); +``` + +### Create Application Task + +Finally, the main function starts up the application task. `bt_app_task_start_up()` creates a work queue and a FreeRTOS task to process the events(messages) posted into the work queue. + +```c +/* create application task */ +bt_app_task_start_up(); +``` + +### Profile Set up + +The main function ends up dispatching event "BT_APP_STACK_UP_EVT" to the application task. + +```c +/* Bluetooth device name, connection mode and profile set up */ +bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL); +``` + +The call of function bt_app_work_dispatch posts the event "BT_APP_STACK_UP_EVT" together with the handler function `bt_av_hdl_stack_evt`, to the work queue of application task. The application task is then triggered to invoke the handler function to process this event. \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md index f5a61c5abb91..25e339b3acf9 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md @@ -1,18 +1,18 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -ESP-IDF A2DP-SOURCE demo +A2DP-SOURCE EXAMPLE ======================== -Demo of A2DP audio source role +Example of A2DP audio source role -This is the demo of using Advanced Audio Distribution Profile APIs to transmit audio stream. Application can take advantage of this example to implement portable audio players or microphones to transmit audio stream to A2DP sink devices. +This is the example of using Advanced Audio Distribution Profile (A2DP) APIs to transmit audio stream. Application can take advantage of this example to implement portable audio players or microphones to transmit audio stream to A2DP sink devices. ## How to use this example ### Hardware Required -This example is able to run on any commonly available ESP32 development board. And is supposed to connect to A2DP sink example in ESP-IDF. +This example is able to run on any commonly available ESP32 development board, and is supposed to connect to [A2DP sink example](../a2dp_sink) in ESP-IDF. ### Configure the project @@ -30,11 +30,15 @@ Build the project and flash it to the board, then run monitor tool to view seria idf.py -p PORT flash monitor ``` +(Replace PORT with the name of the serial port to use.) + (To exit the serial monitor, type ``Ctrl-]``.) +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + ## Example Output -For the first step, this example performs device discovery to search for a target device(A2DP sink) whose device name is "ESP_SPEAKER" and whose "Rendering" bit of its Service Class field is set in its Class of Device. If a candidate target is found, the local device will initiate connection with it. +For the first step, this example performs device discovery to search for a target device (A2DP sink) whose device name is "ESP_SPEAKER" and whose "Rendering" bit of its Service Class field is set in its Class of Device (COD). If a candidate target is found, the local device will initiate connection with it. After connection with A2DP sink is established, the example performs the following running loop 1-2-3-4-1: 1. audio transmission starts and lasts for a while @@ -47,7 +51,7 @@ The example implements an event loop triggered by a periodic "heart beat" timer After the local device discovers the target device and initiates connection, there will be logging message like this: ``` -I (4090) BT_AV: Found a target device, address 24:0a:c4:02:0e:ee, name ESP_SPEAKER +I (4090) BT_AV: Found a target device, address xx:xx:xx:xx:xx:xx, name ESP_SPEAKER I (4090) BT_AV: Cancel device discovery ... I (4100) BT_AV: Device discovery stopped. I (4100) BT_AV: a2dp connecting to peer: ESP_SPEAKER @@ -59,7 +63,7 @@ If connection is set up successfully, there will be such message: I (5100) BT_AV: a2dp connected ``` -Start of audio transmission has the following notification message: +Starting of audio transmission has the following notification message: ``` I (10880) BT_AV: a2dp media ready checking ... @@ -80,7 +84,8 @@ I (111040) BT_AV: a2dp disconnected ``` ## Troubleshooting -* For current stage, the supported audio codec in ESP32 A2DP is SBC. SBC audio stream is encoded from PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data. Other SBC configurations can be supported but there is a need for additional modifications to the protocol stack. +* For current stage, the supported audio codec in ESP32 A2DP is SBC. SBC audio stream is encoded from PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data. * The raw PCM media stream in the example is generated by a sequence of random number, so the sound played on the sink side will be piercing noise. * As a usage limitation, ESP32 A2DP source can support at most one connection with remote A2DP sink devices. Also, A2DP source cannot be used together with A2DP sink at the same time, but can be used with other profiles such as SPP and HFP. - +* Usually, the `ACL_CONN_NUM` is set to `2` but not `1` as one is used for a2dp connection and the other is used for avrcp connection. +* \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.c index 528b34fc50df..a7da29b693a8 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.c @@ -9,7 +9,6 @@ #include #include #include -#include "freertos/xtensa_api.h" #include "freertos/FreeRTOSConfig.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" @@ -17,39 +16,26 @@ #include "esp_log.h" #include "bt_app_core.h" +/********************************* + * STATIC FUNCTION DECLARATIONS + ********************************/ + +/* application task handler */ static void bt_app_task_handler(void *arg); +/* message sender for Work queue */ static bool bt_app_send_msg(bt_app_msg_t *msg); +/* handler for dispatched message */ static void bt_app_work_dispatched(bt_app_msg_t *msg); +/********************************* + * STATIC VARIABLES + ********************************/ static xQueueHandle s_bt_app_task_queue = NULL; static xTaskHandle s_bt_app_task_handle = NULL; -bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) -{ - ESP_LOGD(BT_APP_CORE_TAG, "%s event 0x%x, param len %d", __func__, event, param_len); - - bt_app_msg_t msg; - memset(&msg, 0, sizeof(bt_app_msg_t)); - - msg.sig = BT_APP_SIG_WORK_DISPATCH; - msg.event = event; - msg.cb = p_cback; - - if (param_len == 0) { - return bt_app_send_msg(&msg); - } else if (p_params && param_len > 0) { - if ((msg.param = malloc(param_len)) != NULL) { - memcpy(msg.param, p_params, param_len); - /* check if caller has provided a copy callback to do the deep copy */ - if (p_copy_cback) { - p_copy_cback(&msg, msg.param, p_params); - } - return bt_app_send_msg(&msg); - } - } - - return false; -} +/********************************* + * STATIC FUNCTION DEFINITIONS + ********************************/ static bool bt_app_send_msg(bt_app_msg_t *msg) { @@ -57,10 +43,11 @@ static bool bt_app_send_msg(bt_app_msg_t *msg) return false; } - if (xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_RATE_MS) != pdTRUE) { + if (pdTRUE != xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_RATE_MS)) { ESP_LOGE(BT_APP_CORE_TAG, "%s xQueue send failed", __func__); return false; } + return true; } @@ -74,17 +61,20 @@ static void bt_app_work_dispatched(bt_app_msg_t *msg) static void bt_app_task_handler(void *arg) { bt_app_msg_t msg; + for (;;) { + /* receive message from work queue and handle it */ if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (portTickType)portMAX_DELAY)) { - ESP_LOGD(BT_APP_CORE_TAG, "%s, sig 0x%x, 0x%x", __func__, msg.sig, msg.event); + ESP_LOGD(BT_APP_CORE_TAG, "%s, signal: 0x%x, event: 0x%x", __func__, msg.sig, msg.event); + switch (msg.sig) { case BT_APP_SIG_WORK_DISPATCH: bt_app_work_dispatched(&msg); break; default: - ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled sig: %d", __func__, msg.sig); + ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled signal: %d", __func__, msg.sig); break; - } // switch (msg.sig) + } if (msg.param) { free(msg.param); @@ -93,11 +83,41 @@ static void bt_app_task_handler(void *arg) } } +/********************************* + * EXTERN FUNCTION DEFINITIONS + ********************************/ + +bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) +{ + ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len); + + bt_app_msg_t msg; + memset(&msg, 0, sizeof(bt_app_msg_t)); + + msg.sig = BT_APP_SIG_WORK_DISPATCH; + msg.event = event; + msg.cb = p_cback; + + if (param_len == 0) { + return bt_app_send_msg(&msg); + } else if (p_params && param_len > 0) { + if ((msg.param = malloc(param_len)) != NULL) { + memcpy(msg.param, p_params, param_len); + /* check if caller has provided a copy callback to do the deep copy */ + if (p_copy_cback) { + p_copy_cback(msg.param, p_params, param_len); + } + return bt_app_send_msg(&msg); + } + } + + return false; +} + void bt_app_task_start_up(void) { s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); - xTaskCreate(bt_app_task_handler, "BtAppT", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle); - return; + xTaskCreate(bt_app_task_handler, "BtAppTask", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle); } void bt_app_task_shut_down(void) diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.h b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.h index 4415058a719a..f6d54243e563 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.h +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.h @@ -13,12 +13,17 @@ #include #include -#define BT_APP_CORE_TAG "BT_APP_CORE" +/* log tag */ +#define BT_APP_CORE_TAG "BT_APP_CORE" -#define BT_APP_SIG_WORK_DISPATCH (0x01) +/* signal for dispatcher */ +#define BT_APP_SIG_WORK_DISPATCH (0x01) /** - * @brief handler for the dispatched work + * @brief handler for the dispatched work + * + * @param [in] event message event id + * @param [in] param pointer to the parameter */ typedef void (* bt_app_cb_t) (uint16_t event, void *param); @@ -31,17 +36,35 @@ typedef struct { } bt_app_msg_t; /** - * @brief parameter deep-copy function to be customized + * @brief parameter deep-copy function to be customized + * + * @param [in] p_dest pointer to the destination + * @param [in] p_src pointer to the source + * @param [in] len data length in byte */ -typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src); +typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len); /** - * @brief work dispatcher for the application task + * @brief work dispatcher for the application task + * + * @param [in] p_cback handler for the dispatched work (event handler) + * @param [in] event message event id + * @param [in] p_params pointer to the parameter + * @param [in] param_len length of the parameter + * @param [in] p_copy_cback parameter deep-copy function + * + * @return true if work dispatch successfully, false otherwise */ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback); +/** + * @brief start up the application task + */ void bt_app_task_start_up(void); +/** + * @brief shut down the application task + */ void bt_app_task_shut_down(void); #endif /* __BT_APP_CORE_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c index 28d197c2a74c..c921d0c9b8d8 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c @@ -26,19 +26,24 @@ #include "esp_a2dp_api.h" #include "esp_avrc_api.h" -#define BT_AV_TAG "BT_AV" -#define BT_RC_CT_TAG "RCCT" +/* log tags */ +#define BT_AV_TAG "BT_AV" +#define BT_RC_CT_TAG "RC_CT" -// AVRCP used transaction label +/* device name */ +#define TARGET_DEVICE_NAME "ESP_SPEAKER" +#define LOCAL_DEVICE_NAME "ESP_A2DP_SRC" + +/* AVRCP used transaction label */ #define APP_RC_CT_TL_GET_CAPS (0) #define APP_RC_CT_TL_RN_VOLUME_CHANGE (1) -/* event for handler "bt_av_hdl_stack_up */ enum { - BT_APP_EVT_STACK_UP = 0, + BT_APP_STACK_UP_EVT = 0x0000, /* event for stack up */ + BT_APP_HEART_BEAT_EVT = 0xff00, /* event for heart beat */ }; -/* A2DP global state */ +/* A2DP global states */ enum { APP_AV_STATE_IDLE, APP_AV_STATE_DISCOVERING, @@ -57,43 +62,60 @@ enum { APP_AV_MEDIA_STATE_STOPPING, }; -#define BT_APP_HEART_BEAT_EVT (0xff00) +/********************************* + * STATIC FUNCTION DECLARATIONS + ********************************/ -/// handler for bluetooth stack enabled events +/* handler for bluetooth stack enabled events */ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); -/// callback function for A2DP source +/* avrc controller event handler */ +static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param); + +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/* callback function for A2DP source */ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); -/// callback function for A2DP source audio data stream +/* callback function for A2DP source audio data stream */ static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len); -/// callback function for AVRCP controller +/* callback function for AVRCP controller */ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); -static void a2d_app_heart_beat(void *arg); +/* handler for heart beat timer */ +static void bt_app_a2d_heart_beat(TimerHandle_t arg); -/// A2DP application state machine +/* A2DP application state machine */ static void bt_app_av_sm_hdlr(uint16_t event, void *param); -/// avrc CT event handler -static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param); +/* utils for transfer BLuetooth Deveice Address into string form */ +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size); /* A2DP application state machine handler for each state */ -static void bt_app_av_state_unconnected(uint16_t event, void *param); -static void bt_app_av_state_connecting(uint16_t event, void *param); -static void bt_app_av_state_connected(uint16_t event, void *param); -static void bt_app_av_state_disconnecting(uint16_t event, void *param); - -static esp_bd_addr_t s_peer_bda = {0}; -static uint8_t s_peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; -static int s_a2d_state = APP_AV_STATE_IDLE; -static int s_media_state = APP_AV_MEDIA_STATE_IDLE; -static int s_intv_cnt = 0; -static int s_connecting_intv = 0; -static uint32_t s_pkt_cnt = 0; -static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; -static TimerHandle_t s_tmr; +static void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param); +static void bt_app_av_state_connecting_hdlr(uint16_t event, void *param); +static void bt_app_av_state_connected_hdlr(uint16_t event, void *param); +static void bt_app_av_state_disconnecting_hdlr(uint16_t event, void *param); + +/********************************* + * STATIC VARIABLE DEFINITIONS + ********************************/ + +static esp_bd_addr_t s_peer_bda = {0}; /* Bluetooth Device Address of peer device*/ +static uint8_t s_peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /* Bluetooth Device Name of peer device*/ +static int s_a2d_state = APP_AV_STATE_IDLE; /* A2DP global state */ +static int s_media_state = APP_AV_MEDIA_STATE_IDLE; /* sub states of APP_AV_STATE_CONNECTED */ +static int s_intv_cnt = 0; /* count of heart beat intervals */ +static int s_connecting_intv = 0; /* count of heart beat intervals for connecting */ +static uint32_t s_pkt_cnt = 0; /* count of packets */ +static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; /* AVRC target notification event capability bit mask */ +static TimerHandle_t s_tmr; /* handle of heart beat timer */ + +/********************************* + * STATIC FUNCTION DEFINITIONS + ********************************/ static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) { @@ -101,68 +123,11 @@ static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) return NULL; } - uint8_t *p = bda; sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", - p[0], p[1], p[2], p[3], p[4], p[5]); + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); return str; } -void app_main(void) -{ - // Initialize NVS. - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK( ret ); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - - if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s initialize controller failed\n", __func__); - return; - } - - if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s enable controller failed\n", __func__); - return; - } - - if (esp_bluedroid_init() != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed\n", __func__); - return; - } - - if (esp_bluedroid_enable() != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed\n", __func__); - return; - } - - /* create application task */ - bt_app_task_start_up(); - - /* Bluetooth device name, connection mode and profile set up */ - bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); - -#if (CONFIG_BT_SSP_ENABLED == true) - /* Set default parameters for Secure Simple Pairing */ - esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; - esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; - esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); -#endif - - /* - * Set default parameters for Legacy Pairing - * Use variable pin, input pin code when pairing - */ - esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; - esp_bt_pin_code_t pin_code; - esp_bt_gap_set_pin(pin_type, 0, pin_code); -} - static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len) { uint8_t *rmt_bdname = NULL; @@ -172,6 +137,7 @@ static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len return false; } + /* get complete or short local name from eir data */ rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); if (!rmt_bdname) { rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); @@ -198,11 +164,12 @@ static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) { char bda_str[18]; - uint32_t cod = 0; - int32_t rssi = -129; /* invalid value */ + uint32_t cod = 0; /* class of device */ + int32_t rssi = -129; /* invalid value */ uint8_t *eir = NULL; esp_bt_gap_dev_prop_t *p; + /* handle the discovery results */ ESP_LOGI(BT_AV_TAG, "Scanned device: %s", bda2str(param->disc_res.bda, bda_str, 18)); for (int i = 0; i < param->disc_res.num_prop; i++) { p = param->disc_res.prop + i; @@ -230,38 +197,39 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) return; } - /* search for device named "ESP_SPEAKER" in its extended inqury response */ + /* search for target device in its Extended Inqury Response */ if (eir) { get_name_from_eir(eir, s_peer_bdname, NULL); - if (strcmp((char *)s_peer_bdname, "ESP_SPEAKER") != 0) { - return; + if (strcmp((char *)s_peer_bdname, TARGET_DEVICE_NAME) == 0) { + ESP_LOGI(BT_AV_TAG, "Found a target device, address %s, name %s", bda_str, s_peer_bdname); + s_a2d_state = APP_AV_STATE_DISCOVERED; + memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN); + ESP_LOGI(BT_AV_TAG, "Cancel device discovery ..."); + esp_bt_gap_cancel_discovery(); } - - ESP_LOGI(BT_AV_TAG, "Found a target device, address %s, name %s", bda_str, s_peer_bdname); - s_a2d_state = APP_AV_STATE_DISCOVERED; - memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN); - ESP_LOGI(BT_AV_TAG, "Cancel device discovery ..."); - esp_bt_gap_cancel_discovery(); } } - -void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { switch (event) { + /* when device discovered a result, this event comes */ case ESP_BT_GAP_DISC_RES_EVT: { filter_inquiry_scan_result(param); break; } + /* when discovery state changed, this event comes */ case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: { if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { if (s_a2d_state == APP_AV_STATE_DISCOVERED) { s_a2d_state = APP_AV_STATE_CONNECTING; ESP_LOGI(BT_AV_TAG, "Device discovery stopped."); ESP_LOGI(BT_AV_TAG, "a2dp connecting to peer: %s", s_peer_bdname); + /* connect source to peer device specificed by Bluetooth Device Address */ esp_a2d_source_connect(s_peer_bda); } else { - // not discovered, continue to discover + /* not discovered, continue to discover */ ESP_LOGI(BT_AV_TAG, "Device discovery failed, continue to discover..."); esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); } @@ -270,20 +238,19 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) } break; } - case ESP_BT_GAP_RMT_SRVCS_EVT: - case ESP_BT_GAP_RMT_SRVC_REC_EVT: - break; + /* when authentication completed, this event comes */ case ESP_BT_GAP_AUTH_CMPL_EVT: { if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name); esp_log_buffer_hex(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); } else { - ESP_LOGE(BT_AV_TAG, "authentication failed, status:%d", param->auth_cmpl.stat); + ESP_LOGE(BT_AV_TAG, "authentication failed, status: %d", param->auth_cmpl.stat); } break; } + /* when Legacy Pairing pin code requested, this event comes */ case ESP_BT_GAP_PIN_REQ_EVT: { - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); + ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit: %d", param->pin_req.min_16_digit); if (param->pin_req.min_16_digit) { ESP_LOGI(BT_AV_TAG, "Input pin code: 0000 0000 0000 0000"); esp_bt_pin_code_t pin_code = {0}; @@ -301,59 +268,60 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) } #if (CONFIG_BT_SSP_ENABLED == true) + /* when Security Simple Pairing user confirmation requested, this event comes */ case ESP_BT_GAP_CFM_REQ_EVT: ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); break; + /* when Security Simple Pairing passkey notified, this event comes */ case ESP_BT_GAP_KEY_NOTIF_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey); + ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey: %d", param->key_notif.passkey); break; + /* when Security Simple Pairing passkey requested, this event comes */ case ESP_BT_GAP_KEY_REQ_EVT: ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); break; #endif + /* when GAP mode changed, this event comes */ case ESP_BT_GAP_MODE_CHG_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%d", param->mode_chg.mode); + ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode: %d", param->mode_chg.mode); break; - + /* other */ default: { ESP_LOGI(BT_AV_TAG, "event: %d", event); break; } } + return; } static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) { - ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event); + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + switch (event) { - case BT_APP_EVT_STACK_UP: { - /* set up device name */ - char *dev_name = "ESP_A2DP_SRC"; + /* when stack up worked, this event comes */ + case BT_APP_STACK_UP_EVT: { + char *dev_name = LOCAL_DEVICE_NAME; esp_bt_dev_set_device_name(dev_name); - - /* register GAP callback function */ esp_bt_gap_register_callback(bt_app_gap_cb); - /* initialize AVRCP controller */ esp_avrc_ct_init(); esp_avrc_ct_register_callback(bt_app_rc_ct_cb); esp_avrc_rn_evt_cap_mask_t evt_set = {0}; esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE); - assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK); + ESP_ERROR_CHECK(esp_avrc_tg_set_rn_evt_cap(&evt_set)); - /* initialize A2DP source */ + esp_a2d_source_init(); esp_a2d_register_callback(&bt_app_a2d_cb); esp_a2d_source_register_data_callback(bt_app_a2d_data_cb); - esp_a2d_source_init(); /* set discoverable and connectable mode */ esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); - /* start device discovery */ ESP_LOGI(BT_AV_TAG, "Starting device discovery..."); s_a2d_state = APP_AV_STATE_DISCOVERING; esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); @@ -362,15 +330,17 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) do { int tmr_id = 0; s_tmr = xTimerCreate("connTmr", (10000 / portTICK_RATE_MS), - pdTRUE, (void *) &tmr_id, a2d_app_heart_beat); + pdTRUE, (void *) &tmr_id, bt_app_a2d_heart_beat); xTimerStart(s_tmr, portMAX_DELAY); } while (0); break; } - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); + /* other */ + default: { + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } + } } static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) @@ -378,54 +348,56 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL); } +/* generate some random noise to simulate source audio */ static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len) { - if (len < 0 || data == NULL) { + if (data == NULL || len < 0) { return 0; } - // generate random sequence - int val = rand() % (1 << 16); + int *p_buf = (int *)data; for (int i = 0; i < (len >> 1); i++) { - data[(i << 1)] = val & 0xff; - data[(i << 1) + 1] = (val >> 8) & 0xff; + p_buf[i] = rand() % (1 << 16); } return len; } -static void a2d_app_heart_beat(void *arg) +static void bt_app_a2d_heart_beat(TimerHandle_t arg) { bt_app_work_dispatch(bt_app_av_sm_hdlr, BT_APP_HEART_BEAT_EVT, NULL, 0, NULL); } static void bt_app_av_sm_hdlr(uint16_t event, void *param) { - ESP_LOGI(BT_AV_TAG, "%s state %d, evt 0x%x", __func__, s_a2d_state, event); + ESP_LOGI(BT_AV_TAG, "%s state: %d, event: 0x%x", __func__, s_a2d_state, event); + + /* select handler according to different states. */ switch (s_a2d_state) { case APP_AV_STATE_DISCOVERING: case APP_AV_STATE_DISCOVERED: break; case APP_AV_STATE_UNCONNECTED: - bt_app_av_state_unconnected(event, param); + bt_app_av_state_unconnected_hdlr(event, param); break; case APP_AV_STATE_CONNECTING: - bt_app_av_state_connecting(event, param); + bt_app_av_state_connecting_hdlr(event, param); break; case APP_AV_STATE_CONNECTED: - bt_app_av_state_connected(event, param); + bt_app_av_state_connected_hdlr(event, param); break; case APP_AV_STATE_DISCONNECTING: - bt_app_av_state_disconnecting(event, param); + bt_app_av_state_disconnecting_hdlr(event, param); break; default: - ESP_LOGE(BT_AV_TAG, "%s invalid state %d", __func__, s_a2d_state); + ESP_LOGE(BT_AV_TAG, "%s invalid state: %d", __func__, s_a2d_state); break; } } -static void bt_app_av_state_unconnected(uint16_t event, void *param) +static void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param) { + /* handle the events of intrest in unconnected state */ switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: case ESP_A2D_AUDIO_STATE_EVT: @@ -433,23 +405,26 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param) case ESP_A2D_MEDIA_CTRL_ACK_EVT: break; case BT_APP_HEART_BEAT_EVT: { - uint8_t *p = s_peer_bda; + uint8_t *bda = s_peer_bda; ESP_LOGI(BT_AV_TAG, "a2dp connecting to peer: %02x:%02x:%02x:%02x:%02x:%02x", - p[0], p[1], p[2], p[3], p[4], p[5]); + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); esp_a2d_source_connect(s_peer_bda); s_a2d_state = APP_AV_STATE_CONNECTING; s_connecting_intv = 0; break; } - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); + default: { + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } + } } -static void bt_app_av_state_connecting(uint16_t event, void *param) +static void bt_app_av_state_connecting_hdlr(uint16_t event, void *param) { esp_a2d_cb_param_t *a2d = NULL; + + /* handle the events of intrest in connecting state */ switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(param); @@ -468,13 +443,17 @@ static void bt_app_av_state_connecting(uint16_t event, void *param) case ESP_A2D_MEDIA_CTRL_ACK_EVT: break; case BT_APP_HEART_BEAT_EVT: + /** + * Switch state to APP_AV_STATE_UNCONNECTED + * when connecting lasts more than 2 heart beat intervals. + */ if (++s_connecting_intv >= 2) { s_a2d_state = APP_AV_STATE_UNCONNECTED; s_connecting_intv = 0; } break; default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } } @@ -482,6 +461,7 @@ static void bt_app_av_state_connecting(uint16_t event, void *param) static void bt_app_av_media_proc(uint16_t event, void *param) { esp_a2d_cb_param_t *a2d = NULL; + switch (s_media_state) { case APP_AV_MEDIA_STATE_IDLE: { if (event == BT_APP_HEART_BEAT_EVT) { @@ -507,7 +487,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param) s_intv_cnt = 0; s_media_state = APP_AV_MEDIA_STATE_STARTED; } else { - // not started succesfully, transfer to idle state + /* not started succesfully, transfer to idle state */ ESP_LOGI(BT_AV_TAG, "a2dp media start failed."); s_media_state = APP_AV_MEDIA_STATE_IDLE; } @@ -516,6 +496,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param) } case APP_AV_MEDIA_STATE_STARTED: { if (event == BT_APP_HEART_BEAT_EVT) { + /* stop media after 10 heart beat intervals */ if (++s_intv_cnt >= 10) { ESP_LOGI(BT_AV_TAG, "a2dp media stopping..."); esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP); @@ -541,12 +522,17 @@ static void bt_app_av_media_proc(uint16_t event, void *param) } break; } + default: { + break; + } } } -static void bt_app_av_state_connected(uint16_t event, void *param) +static void bt_app_av_state_connected_hdlr(uint16_t event, void *param) { esp_a2d_cb_param_t *a2d = NULL; + + /* handle the events of intrest in connected state */ switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(param); @@ -565,22 +551,25 @@ static void bt_app_av_state_connected(uint16_t event, void *param) break; } case ESP_A2D_AUDIO_CFG_EVT: - // not suppposed to occur for A2DP source + /* not suppposed to occur for A2DP source */ break; case ESP_A2D_MEDIA_CTRL_ACK_EVT: case BT_APP_HEART_BEAT_EVT: { bt_app_av_media_proc(event, param); break; } - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); + default: { + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } + } } -static void bt_app_av_state_disconnecting(uint16_t event, void *param) +static void bt_app_av_state_disconnecting_hdlr(uint16_t event, void *param) { esp_a2d_cb_param_t *a2d = NULL; + + /* handle the events of intrest in disconnecing state */ switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(param); @@ -596,18 +585,20 @@ static void bt_app_av_state_disconnecting(uint16_t event, void *param) case ESP_A2D_MEDIA_CTRL_ACK_EVT: case BT_APP_HEART_BEAT_EVT: break; - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); + default: { + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); break; } + } } +/* callback function for AVRCP controller */ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) { switch (event) { - case ESP_AVRC_CT_METADATA_RSP_EVT: case ESP_AVRC_CT_CONNECTION_STATE_EVT: case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_METADATA_RSP_EVT: case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: case ESP_AVRC_CT_REMOTE_FEATURES_EVT: case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: @@ -615,10 +606,11 @@ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); break; } - default: + default: { ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); break; } + } } static void bt_av_volume_changed(void) @@ -632,52 +624,63 @@ static void bt_av_volume_changed(void) void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) { switch (event_id) { - case ESP_AVRC_RN_VOLUME_CHANGE: + /* when volume changed locally on target, this event comes */ + case ESP_AVRC_RN_VOLUME_CHANGE: { ESP_LOGI(BT_RC_CT_TAG, "Volume changed: %d", event_parameter->volume); ESP_LOGI(BT_RC_CT_TAG, "Set absolute volume: volume %d", event_parameter->volume + 5); esp_avrc_ct_send_set_absolute_volume_cmd(APP_RC_CT_TL_RN_VOLUME_CHANGE, event_parameter->volume + 5); bt_av_volume_changed(); break; } + /* other */ + default: + break; + } } +/* AVRC controller event handler */ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) { ESP_LOGD(BT_RC_CT_TAG, "%s evt %d", __func__, event); esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param); + switch (event) { + /* when connection state changed, this event comes */ case ESP_AVRC_CT_CONNECTION_STATE_EVT: { uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state event: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); if (rc->conn_stat.connected) { - // get remote supported event_ids of peer AVRCP Target esp_avrc_ct_send_get_rn_capabilities_cmd(APP_RC_CT_TL_GET_CAPS); } else { - // clear peer notification capability record s_avrc_peer_rn_cap.bits = 0; } break; } + /* when passthrough responsed, this event comes */ case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state); + ESP_LOGI(BT_RC_CT_TAG, "AVRC passthrough response: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state); break; } + /* when metadata responsed, this event comes */ case ESP_AVRC_CT_METADATA_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); + ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata response: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); free(rc->meta_rsp.attr_text); break; } + /* when notification changed, this event comes */ case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); break; } + /* when indicate feature of remote device, this event comes */ case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC remote features %x, TG features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.tg_feat_flag); break; } + /* when get supported notification events capability of peer device, this event comes */ case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { ESP_LOGI(BT_RC_CT_TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, rc->get_rn_caps_rsp.evt_set.bits); @@ -686,13 +689,73 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) bt_av_volume_changed(); break; } + /* when set absolute volume responsed, this event comes */ case ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "Set absolute volume rsp: volume %d", rc->set_volume_rsp.volume); + ESP_LOGI(BT_RC_CT_TAG, "Set absolute volume response: volume %d", rc->set_volume_rsp.volume); break; } - - default: - ESP_LOGE(BT_RC_CT_TAG, "%s unhandled evt %d", __func__, event); + /* other */ + default: { + ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); break; } + } +} + +/********************************* + * MAIN ENTRY POINT + ********************************/ + +void app_main(void) +{ + /* initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + /* + * This example only uses the functions of Classical Bluetooth. + * So release the controller memory for Bluetooth Low Energy. + */ + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize controller failed\n", __func__); + return; + } + if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s enable controller failed\n", __func__); + return; + } + if (esp_bluedroid_init() != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed\n", __func__); + return; + } + if (esp_bluedroid_enable() != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed\n", __func__); + return; + } + +#if (CONFIG_BT_SSP_ENABLED == true) + /* set default parameters for Secure Simple Pairing */ + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + + /* + * Set default parameters for Legacy Pairing + * Use variable pin, input pin code when pairing + */ + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; + esp_bt_pin_code_t pin_code; + esp_bt_gap_set_pin(pin_type, 0, pin_code); + + bt_app_task_start_up(); + /* Bluetooth device name, connection mode and profile set up */ + bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL); } diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.defaults index e87de5c3bd36..d2565d29bb8b 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.defaults @@ -7,5 +7,3 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y -CONFIG_BT_SPP_ENABLED=n -CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/tutorial/Example_A2DP_Source.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/tutorial/Example_A2DP_Source.md new file mode 100644 index 000000000000..195603da4cbd --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/tutorial/Example_A2DP_Source.md @@ -0,0 +1,121 @@ +# A2DP Source Example Walkthrough + +## Introduction + +In this tutorial, the A2DP source example code is reviewed. The code implements an A2DP source role, which transmits audio stream to A2DP sink devices. This example performs device discovery to search for a target device and then initiates connection with it. After connection established, the source starts to transmit audio stream to peer device and change the volume locally based on heart beat. + +## File Tree + +The file tree of this example is shown below. The [main](../main) folder contains the main files of this example including program core files, main function file, etc. The [tutorial](../tutorial) folder contains this guidance document. + +```c +└── a2dp_source +    ├── CMakeLists.txt +    ├── main +    │   ├── bt_app_core.c +    │   ├── bt_app_core.h +    │   ├── CMakeLists.txt +    │   └── main.c +    ├── README.md +    ├── sdkconfig.defaults +    └── tutorial +    └── Example_A2DP_Source.md + +2 directories, 8 files +``` + +## Main Entry Point + +This example is located in the examples folder of the ESP-IDF under the [bluetooth/bluedroid/classic_bt/a2dp_source](../). The entry point of this program is `app_main()` which contained in [main/main.c](../main/main.c). + +### NVS Initialization + +The main function starts by initializing the non-volatile storage library. This library allows to save key-value pairs in flash memory and is used by some components such as the Wi-Fi library to save the SSID and password: + +```c +/* Initialize NVS — it is used to store PHY calibration */ +esp_err_t ret = nvs_flash_init(); +if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); +} +ESP_ERROR_CHECK(ret); +``` + +### Bluetooth Controller and Stack Initialization + +The main function also initializes the Bluetooth Controller with default settings. The Bluetooth Controller is invisible to the user applications and deals with the lower layers of the Bluetooth Stack. Next, the controller is enabled in Classic Bluetooth Mode. + +```c +/* initialize Bluetooth Controller with default configuration */ +esp_bt_controller_config_t bt_cfg = ONTROLLER_INIT_CONFIG_DEFAULT(); +if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize controller ed\n", __func__); + return; +} +/* Enable Bluetooth Controller in Classical Bluetooth mode */ +if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != OK) { + ESP_LOGE(BT_AV_TAG, "%s enable controller failed\n", __func__); + return; +} +``` + +After the initialization of the Bluetooth Controller, the Bluedroid stack, which includes the common definitions and APIs for Classic Bluetooth is initialized and enabled by using: + +```c +/* initialize Bluedroid Host */ +if (esp_bluedroid_init() != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed\n", __func__); + return; +} +/* Enable Bluedroid Host */ +if (esp_bluedroid_enable() != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed\n", __func__); + return; +} +``` + +The Classic Bluetooth uses an asynchronous programming paradigm. The entire Bluedroid stack sees the use of events, event handlers, callbacks and state machines. Most APIs are implemented by posting specific type of events to the work queue of Bluedroid Stack. Threads(FreeRTOS) tasks inside Bluedroid then process the events with specific handlers, according to the internal state. When the operations are completed, Bluedroid stack invokes the callback function which is registered by application, to report some other events and information. + +For example, after executing `esp_bt_gap_start_discovery()`, an event of `ESP_BT_GAP_DISC_STATE_CHANGED_EVT` occurs to inform that the discovery state has been changed. Application can do some processing at this time. + +### Paring Parameter Settings + +The main function continues to set up paring parameters including Secure Simple Pairing and Legacy Pairing. + +```c +#if (CONFIG_BT_SSP_ENABLED == true) +/* set default parameters for Secure Simple Pairing */ +esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; +esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; +esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + +/* + * Set default parameters for Legacy Pairing + * Use variable pin, input pin code when pairing + */ +esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; +esp_bt_pin_code_t pin_code; +esp_bt_gap_set_pin(pin_type, 0, pin_code); +``` + +### Create Application Task + +Finally, the main function starts up the application task. `bt_app_task_start_up()` creates a work queue and a FreeRTOS task to process the events(messages) posted into the work queue. + +```c +/* create application task */ +bt_app_task_start_up(); +``` + +### Profile Set up + +The main function ends up dispatching event "BT_APP_STACK_UP_EVT" to the application task. + +```c +/* Bluetooth device name, connection mode and profile set up */ +bt_app_work_dispatch(bt_av_hdl_stack_evt,BT_APP_STACK_UP_EVT, NULL, 0, NULL); +``` + +The call of function bt_app_work_dispatch posts the event "BT_APP_STACK_UP_EVT" together with the handler function `bt_av_hdl_stack_evt`, to the work queue of application task. The application task is then triggered to invoke the handler function to process this event. diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/README.md index 331d1ee65ba5..df62b4071705 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/README.md @@ -1,10 +1,11 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -# ESP-IDF BT-INQUIRY demo +# ESP-IDF BT-DISCOVERY Example -Demo of Classic Bluetooth Device and Service Discovery -This is the demo for user to use ESP_APIs to perform inquiry to search for a target device and then performs service search via SDP. +Example of Classic Bluetooth Device and Service Discovery. + +This is the example of using APIs to perform inquiry to search for a target device with a Major device type "Phone" or "Audio/Video" in the CoD (Class of Device) field and then performing a search via SDP (Service Discovery Protocol). ## How to use example @@ -23,21 +24,246 @@ idf.py menuconfig Build the project and flash it to the board, then run monitor tool to view serial output: ``` -idf.py -p PORT flash monitor +idf.py -p PORT build flash monitor ``` -(Replace PORT with the name of the serial port to use.) - -(To exit the serial monitor, type ``Ctrl-]``.) +To exit the serial monitor, type `Ctrl-]`. See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. -## Example Description +# TUTORIAL + +## Includes + +```c +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +``` + +These `includes` are required for the FreeRTOS and underlaying system components to run, including the logging functionality and a library to store data in non-volatile flash memory. We are interested in `bt.h`, `esp_bt_main.h`, `esp_bt_device.h` and `esp_gap_bt_api.h`, which expose the Classic Bluetooth APIs required to implement this example. + +* `bt.h`: configures the Bluetooth controller and VHCI from the host side. +* `esp_bt_main.h`: initializes and enables the Bluedroid stack. +* `esp_gap_bt_api.h`: implements the GAP configuration, such as Classic Bluetooth device and service discovery. +* `esp_bt_device.h`: implements the device configuration, such as device address and device name. + +## Main Entry Point + +The program’s entry point is the `app_main()` function. + +### Non-volatile Storage Library Initialization + +The main function starts by initializing the non-volatile storage library. This library allows to store PHY calibration data and save key-value pairs in flash memory. + +```c +esp_err_t ret = nvs_flash_init(); +if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); +} +ESP_ERROR_CHECK( ret ); +``` + +### Release The Controller Memory + +Then the main function releases the controller memory for unused modes. It releases the BLE (Bluetooth Low Energy) memory in the controller via: + +```c +ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); +``` + +The controller memory should be released only before initializing Bluetooth controller or after deinitializing Bluetooth controller. + +Note that once Bluetooth controller memory is released, the process cannot be reversed. It means you cannot use the Bluetooth mode which you have released by this function. -After the program started, the device will start inquiry to search for a device with Major device type "PHONE" in the Class of Device Field. Then it will cancel the inquiry and started to perform service discovering on this remote device. +## Bluetooth Controller and Stack Initialization + +The main function also initializes the Bluetooth controller by first creating the controller configuration structure named `esp_bt_controller_config_t` with default settings generated by the `BT_CONTROLLER_INIT_CONFIG_DEFAULT()` macro. The Bluetooth controller implements the Host Controller Interface (HCI) on the controller side, the Link Layer (LL), and the Physical Layer (PHY). The Bluetooth Controller is invisible to the user applications and deals with the lower layers of the Bluetooth stack. The controller configuration includes setting the Bluetooth controller stack size, priority, and HCI baud rate. With the settings created, the Bluetooth controller is initialized and enabled with the `esp_bt_controller_init()` function: + +```c +esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; +} +``` + +Next, the controller is enabled in Classic Bluetooth Mode. + +```c +if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; +} +``` +> If you want to use the dual mode (BLE + Bluetooth Classic), the controller should be enabled in `ESP_BT_MODE_BTDM`, and should not releases the BLE memory in the controller. + +There are four Bluetooth modes supported: + +1. `ESP_BT_MODE_IDLE`: Bluetooth not running +2. `ESP_BT_MODE_BLE`: BLE mode +3. `ESP_BT_MODE_CLASSIC_BT`: Bluetooth Classic mode +4. `ESP_BT_MODE_BTDM`: Dual mode (BLE + Bluetooth Classic) + +After the initialization of the Bluetooth controller, the Bluedroid stack, which includes the common definitions and APIs for both Bluetooth Classic and BLE, is initialized and enabled by using: + +```c +if ((ret = esp_bluedroid_init()) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret)); + return; +} + +if ((ret = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret)); + return; +} +``` + +The main function ends by starting up application function. + +```c +bt_app_gap_start_up(); +``` + +## Application Start Up +The application function starts by registering the GAP (Generic Access Profile) event handlers, + +```c + /* register GAP callback function */ + esp_bt_gap_register_callback(bt_app_gap_cb); +``` -## Trouble shooting +The GAP event handlers are the functions used to catch the events generated by the Bluetooth stack and execute functions to configure parameters of the application. + +The functions `bt_app_gap_cb` handle all the events generated by the Bluetooth stack. + +The application function then sets the device name and sets it as discoverable and connectable. After this, this device can be discovered and connected. + +```c +char *dev_name = "ESP_GAP_INQRUIY"; +esp_bt_dev_set_device_name(dev_name); + +/* set discoverable and connectable mode, wait to be connected */ +esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +``` + +The application function then initialises the information and status of application layer and starts to discover nearby Bluetooth devices. + +```c +/* inititialize device information and status */ +bt_app_gap_init(); + +/* start to discover nearby Bluetooth devices */ +app_gap_cb_t *p_dev = &m_dev_info; +p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING; +esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); +``` + +## GAP Callback + +### Get Device Discovery Result + +After device discovery gets started the state will change to `ESP_BT_GAP_DISCOVERY_STARTED`, and `bt_app_gap_cb` will be called with `ESP_BT_GAP_DISC_STATE_CHANGED_EVT`. + +If nearby Bluetooth devices are discovered `bt_app_gap_cb` will be called with `ESP_BT_GAP_DISC_RES_EVT`, to post the result to users. + +```c +case ESP_BT_GAP_DISC_RES_EVT: { + update_device_info(param); + break; +} +``` + +### Search For A Target Device + +Function `update_device_info` gets the CoD (Class of Device), RSSI (Received Signal Strength Indication), name, EIR (Extended Inquiry Result) from the discovery result. + +```c +for (int i = 0; i < param->disc_res.num_prop; i++) { + p = param->disc_res.prop + i; + switch (p->type) { + case ESP_BT_GAP_DEV_PROP_COD: + cod = *(uint32_t *)(p->val); + ESP_LOGI(GAP_TAG, "--Class of Device: 0x%x", cod); + break; + case ESP_BT_GAP_DEV_PROP_RSSI: + rssi = *(int8_t *)(p->val); + ESP_LOGI(GAP_TAG, "--RSSI: %d", rssi); + break; + case ESP_BT_GAP_DEV_PROP_BDNAME: + bdname_len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN : + (uint8_t)p->len; + bdname = (uint8_t *)(p->val); + break; + case ESP_BT_GAP_DEV_PROP_EIR: { + eir_len = p->len; + eir = (uint8_t *)(p->val); + break; + } + default: + break; + } +} +``` + +Pay attention that some Bluetooth devices may put their name in EIR data. We can get the device name from EIR data. + +```c +if (p_dev->eir && p_dev->bdname_len == 0) { + get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len); +} +``` + +Then, function `update_device_info` searches for a device with Major device type "Phone" or "Audio/Video" according to COD. For more information on COD, check [Bluetooth specifications](https://www.bluetooth.com/specifications/assigned-numbers/). + +```c +if (!esp_bt_gap_is_valid_cod(cod) || + (!(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_PHONE) && + !(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_AV))) { + return; +} +``` + +If the target device is found, the device discovery procedure is stopped. + +```c +ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname); +p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE; +ESP_LOGI(GAP_TAG, "Cancel device discovery ..."); +esp_bt_gap_cancel_discovery(); +``` + +### Service Discovery + +After device discovery stops the state will change to `ESP_BT_GAP_DISCOVERY_STOPPED` and `bt_app_gap_cb` will be called with `ESP_BT_GAP_DISC_STATE_CHANGED_EVT`. + +Then it performs service discovery targeting at this device. + +```c +p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING; +ESP_LOGI(GAP_TAG, "Discover services ..."); +esp_bt_gap_get_remote_services(p_dev->bda); +``` + +Then `bt_app_gap_cb` will be called with `ESP_BT_GAP_RMT_SRVCS_EVT` to post the service discovery result to users including the service UUID. For more information on the service UUID, you can check [Bluetooth specifications](https://www.bluetooth.com/specifications/assigned-numbers/). + +```c +for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) { + esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i; + ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37)); +} +``` -- Some old BT device doesn't place their device name in EIR, but new devices place their device name in EIR. Users can obtain the peer device name in `bt_app_gap_cb` `ESP_BT_GAP_DISC_RES_EVT` event handler or resolve it in EIR just like the function `get_name_from_eir` does. +## Conclusion -- ESP32 places its device name in EIR by default. \ No newline at end of file +We have reviewed the Bluetooth discovery example code. This example searches for nearby devices. When the device of interest is found, the example searches for the services of this device. We can get the device discovery result and service discovery result from the GAP callback, which is registered in advance. \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/CMakeLists.txt index 45a1c91d2463..cf2c455cb50e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "bt_discovery.c" +idf_component_register(SRCS "main.c" INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/bt_discovery.c b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c similarity index 87% rename from examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/bt_discovery.c rename to examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c index 64c7e789ff27..8ace9161f2bc 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/bt_discovery.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c @@ -122,6 +122,10 @@ static void update_device_info(esp_bt_gap_cb_param_t *param) char bda_str[18]; uint32_t cod = 0; int32_t rssi = -129; /* invalid value */ + uint8_t *bdname = NULL; + uint8_t bdname_len = 0; + uint8_t *eir = NULL; + uint8_t eir_len = 0; esp_bt_gap_dev_prop_t *p; ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18)); @@ -137,14 +141,23 @@ static void update_device_info(esp_bt_gap_cb_param_t *param) ESP_LOGI(GAP_TAG, "--RSSI: %d", rssi); break; case ESP_BT_GAP_DEV_PROP_BDNAME: + bdname_len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN : + (uint8_t)p->len; + bdname = (uint8_t *)(p->val); + break; + case ESP_BT_GAP_DEV_PROP_EIR: { + eir_len = p->len; + eir = (uint8_t *)(p->val); + break; + } default: break; } } - /* search for device with MAJOR service class as "rendering" in COD */ + /* search for device with Major device type "PHONE" or "Audio/Video" in COD */ app_gap_cb_t *p_dev = &m_dev_info; - if (p_dev->dev_found && 0 != memcmp(param->disc_res.bda, p_dev->bda, ESP_BD_ADDR_LEN)) { + if (p_dev->dev_found) { return; } @@ -156,40 +169,27 @@ static void update_device_info(esp_bt_gap_cb_param_t *param) memcpy(p_dev->bda, param->disc_res.bda, ESP_BD_ADDR_LEN); p_dev->dev_found = true; - for (int i = 0; i < param->disc_res.num_prop; i++) { - p = param->disc_res.prop + i; - switch (p->type) { - case ESP_BT_GAP_DEV_PROP_COD: - p_dev->cod = *(uint32_t *)(p->val); - break; - case ESP_BT_GAP_DEV_PROP_RSSI: - p_dev->rssi = *(int8_t *)(p->val); - break; - case ESP_BT_GAP_DEV_PROP_BDNAME: { - uint8_t len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN : - (uint8_t)p->len; - memcpy(p_dev->bdname, (uint8_t *)(p->val), len); - p_dev->bdname[len] = '\0'; - p_dev->bdname_len = len; - break; - } - case ESP_BT_GAP_DEV_PROP_EIR: { - memcpy(p_dev->eir, (uint8_t *)(p->val), p->len); - p_dev->eir_len = p->len; - break; - } - default: - break; - } + + p_dev->cod = cod; + p_dev->rssi = rssi; + if (bdname_len > 0) { + memcpy(p_dev->bdname, bdname, bdname_len); + p_dev->bdname[bdname_len] = '\0'; + p_dev->bdname_len = bdname_len; + } + if (eir_len > 0) { + memcpy(p_dev->eir, eir, eir_len); + p_dev->eir_len = eir_len; } if (p_dev->eir && p_dev->bdname_len == 0) { get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len); - ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname); - p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE; - ESP_LOGI(GAP_TAG, "Cancel device discovery ..."); - esp_bt_gap_cancel_discovery(); } + + ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname); + p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE; + ESP_LOGI(GAP_TAG, "Cancel device discovery ..."); + esp_bt_gap_cancel_discovery(); } static void bt_app_gap_init(void) @@ -197,8 +197,7 @@ static void bt_app_gap_init(void) app_gap_cb_t *p_dev = &m_dev_info; memset(p_dev, 0, sizeof(app_gap_cb_t)); - /* start to discover nearby Bluetooth devices */ - p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING; + p_dev->state = APP_GAP_STATE_IDLE; } static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) @@ -236,7 +235,6 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) { esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i; ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37)); - // ESP_LOGI(GAP_TAG, "--%d", u->len); } } else { ESP_LOGI(GAP_TAG, "Services for device %s not found", bda2str(p_dev->bda, bda_str, 18)); @@ -255,24 +253,27 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa static void bt_app_gap_start_up(void) { - char *dev_name = "ESP_GAP_INQRUIY"; - esp_bt_dev_set_device_name(dev_name); - /* register GAP callback function */ esp_bt_gap_register_callback(bt_app_gap_cb); + char *dev_name = "ESP_GAP_INQRUIY"; + esp_bt_dev_set_device_name(dev_name); + /* set discoverable and connectable mode, wait to be connected */ esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); /* inititialize device information and status */ bt_app_gap_init(); + /* start to discover nearby Bluetooth devices */ + app_gap_cb_t *p_dev = &m_dev_info; + p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING; esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); } void app_main(void) { - /* Initialize NVS — it is used to store PHY calibration data */ + /* Initialize NVS — it is used to store PHY calibration data and save key-value pairs in flash memory*/ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/sdkconfig.defaults index 356b30e950d9..ae41d8ca82a0 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/sdkconfig.defaults @@ -1,9 +1,5 @@ -# Override some defaults so BT stack is enabled and -# Classic BT is enabled and BT_DRAM_RELEASE is disabled +# Enable Classic BT and disable BLE CONFIG_BT_ENABLED=y -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y -CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_BT_A2DP_ENABLE=n CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md index aef56168b9ca..2a630479bdf9 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md @@ -1,24 +1,39 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -## ESP-IDF BT-SPP-ACCEPTOR demo +## ESP-IDF BT-SPP-ACCEPTOR Example -This is the demo for user to use ESP_APIs to create a **Serial Port Protocol** (**SPP**) acceptor and we aggregate **Secure Simple Pair** (**SSP**) into this demo to show how to use SPP when creating your own APPs. +This example is to show how to use the APIs of **Serial Port Protocol** (**SPP**) to create an SPP acceptor which performs as a server. We aggregate **Secure Simple Pair** (**SSP**) into this example to show how to use SPP when creating your own APPs. We also provide the example `bt_spp_initiator` or the example `bt_spp_vfs_initiator` to create an SPP initiator which performs as a client. In fact, you can create SPP acceptors and SPP initiators on a single device at the same time. ## How to use example ### Hardware Required -This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. - -To operate it should be connected to an SPP Initiator running on a smartphone or on another ESP32 development board. +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate the example, it should be connected to an SPP Initiator running on a smartphone, a computer or on another ESP32 development board. ### Configure the project +1. Open the project configuration menu: + ``` idf.py menuconfig ``` +2. Enable the SPP functionality by choosing the path as following: + +`Component config --> Bluetooth --> Bluedroid Options --> SPP` + +3. If you want to limit the number of connected devices, please make sure set the `BT/BLE MAX ACL CONNECTIONS` and `BR/EDR ACL Max Connections` with same value you want. + +`Component config --> Bluetooth --> Bluedroid Options --> BT/BLE MAX ACL CONNECTIONS(1~7)` +and +`Component config --> Bluetooth --> Bluetooth --> Bluetooth controller --> BR/EDR ACL Max Connections` + + +4. SSP is enabled as default in this example. If you prefer the legacy pairing, you can disable it in the following path. + +`Component config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`. + ### Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: @@ -35,16 +50,19 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l ## Example Description -After the program started, `bt_spp_initator` will connect it and send data. +After the program starts, the example will start an SPP acceptor. The example will calculate the data rate or just print the received data after the SPP connection is established. You can connect to the server and send data with another ESP32 development board, Andriod phone or computer which performs as the SPP initiator. ## Trouble shooting -- Acceptor is expected to start before `bt_spp_initator` start. +- To see the information of data, users shall set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code(should be same with `bt_spp_initiator`, if the peer device runs it). When setting `SPP_SHOW_MODE` as `SPP_SHOW_DATA`, if the data rate is too high or the data length is too long, it is strongly recommended to process them in other lower priority application task rather than in this callback directly. Since the printing takes too much time, and it may stuck the Bluetooth stack. -- To see the information of data, users shall set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code(should be same with `bt_spp_initator`). +## FAQ +Q: How to change the process of SSP? +A: Users can set the IO Capability and Security Mask for their device (fixed Security Mode, Security Mode 4). In short, the Security Mask sets the security level for authentication stage and the IO Capability determines the way of user interaction during pairing. The default Security Mask of this example is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](./ESP32_SSP.md). -- We also show the Security Simple Pair in this SPP demo. Users can set the IO Capability and Security Mode for their device (security level is fixed level 4). The default security mode of this demo is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](./ESP32_SSP.md). -## FAQ Q: How many SPP servers does ESP32 support? A: For now, the maximum number of SPP servers is 6, which is limited by the maximum number of SDP records. When the SPP server is successfully started, the unique SCN (Server Channel Number) will be mapped to the SPP server. + +Q: Is SPP absolutely reliable? +A: For now, most Bluetooth stacks implement the SPP based on the L2CAP Basic Mode, and the reliability only depends on the controller. If errors(e.g. CRC) are missed by controller, the L2CAP packet will not be retransmitted, so it is recommended that you should implement the retransmission at the application layer. For more information about L2CAP operation modes, please refer to Bluetooth Core Specification, Version 4.2 or later, Volume 3, Part A: Logical Link Control and Adaptation Protocol Specification. \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/CMakeLists.txt index e75017250b0a..cf2c455cb50e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "example_spp_acceptor_demo.c" +idf_component_register(SRCS "main.c" INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/example_spp_acceptor_demo.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c similarity index 72% rename from examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/example_spp_acceptor_demo.c rename to examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c index f68ceb2540b7..f6ffc0d156ed 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/example_spp_acceptor_demo.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c @@ -39,6 +39,18 @@ static long data_num = 0; static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; +static char *bda2str(uint8_t *bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + static void print_speed(void) { float time_old_s = time_old.tv_sec + time_old.tv_usec / 1000000.0; @@ -53,10 +65,16 @@ static void print_speed(void) static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { + char bda_str[18] = {0}; + switch (event) { case ESP_SPP_INIT_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); - esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME); + if (param->init.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); + esp_spp_start_srv(sec_mask, role_slave, 0, SPP_SERVER_NAME); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_INIT_EVT status:%d", param->init.status); + } break; case ESP_SPP_DISCOVERY_COMP_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT"); @@ -65,21 +83,35 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT"); break; case ESP_SPP_CLOSE_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); + ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT status:%d handle:%d close_by_remote:%d", param->close.status, + param->close.handle, param->close.async); break; case ESP_SPP_START_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT"); - esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + if (param->start.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT handle:%d sec_id:%d scn:%d", param->start.handle, param->start.sec_id, + param->start.scn); + esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_START_EVT status:%d", param->start.status); + } break; case ESP_SPP_CL_INIT_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT"); break; case ESP_SPP_DATA_IND_EVT: #if (SPP_SHOW_MODE == SPP_SHOW_DATA) - ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", + /* + * We only show the data in which the data length is less than 128 here. If you want to print the data and + * the data rate is high, it is strongly recommended to process them in other lower priority application task + * rather than in this callback directly. Since the printing takes too much time, it may stuck the Bluetooth + * stack and also have a effect on the throughput! + */ + ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len:%d handle:%d", param->data_ind.len, param->data_ind.handle); - esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); + if (param->data_ind.len < 128) { + esp_log_buffer_hex("", param->data_ind.data, param->data_ind.len); + } #else gettimeofday(&time_new, NULL); data_num += param->data_ind.len; @@ -95,7 +127,8 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT"); break; case ESP_SPP_SRV_OPEN_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); + ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT status:%d handle:%d, rem_bda:[%s]", param->srv_open.status, + param->srv_open.handle, bda2str(param->srv_open.rem_bda, bda_str, sizeof(bda_str))); gettimeofday(&time_old, NULL); break; case ESP_SPP_SRV_STOP_EVT: @@ -111,11 +144,13 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { + char bda_str[18] = {0}; + switch (event) { case ESP_BT_GAP_AUTH_CMPL_EVT:{ if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name); - esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); + ESP_LOGI(SPP_TAG, "authentication success: %s bda:[%s]", param->auth_cmpl.device_name, + bda2str(param->auth_cmpl.bda, bda_str, sizeof(bda_str))); } else { ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat); } @@ -153,7 +188,8 @@ void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) #endif case ESP_BT_GAP_MODE_CHG_EVT: - ESP_LOGI(SPP_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%d", param->mode_chg.mode); + ESP_LOGI(SPP_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%d bda:[%s]", param->mode_chg.mode, + bda2str(param->mode_chg.bda, bda_str, sizeof(bda_str))); break; default: { @@ -166,6 +202,7 @@ void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) void app_main(void) { + char bda_str[18] = {0}; esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); @@ -225,4 +262,6 @@ void app_main(void) esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; esp_bt_pin_code_t pin_code; esp_bt_gap_set_pin(pin_type, 0, pin_code); + + ESP_LOGI(SPP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); } diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md index 1a3a50943606..703fe745b0e1 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md @@ -1,23 +1,30 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -# ESP-IDF BT-SPP-INITATOR demo +# ESP-IDF BT-SPP-INITATOR Example -This is the demo for user to use ESP_APIs to create a **Serial Port Protocol** (**SPP**) initiator and we aggregate **Secure Simple Pair** (**SSP**) into this demo to show how to use SPP when creating your own APPs. +This example is to show how to use the APIs of **Serial Port Protocol** (**SPP**) to create an SPP initiator which performs as a client. we aggregate **Secure Simple Pair** (**SSP**) into this example to show how to use SPP when creating your own APPs. We also provide the example `bt_spp_acceptor` or the example `bt_spp_vfs_acceptor` to create an SPP acceptor which performs as a server. In fact, you can create SPP acceptors and SPP initiators on a single device at the same time. ## How to use example ### Hardware Required -This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate it should be connected to an SPP Acceptor running on another device. +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate the example, you should be connect to an SPP acceptor running on a smartphone, a computer or on another ESP32 development board. ### Configure the project - +1. Open the project configuration menu: ``` idf.py menuconfig ``` -In `menuconfig` path: `Coponent config --> Bluetooth--> Bluedroid Options -->SPP` and `Coponent config --> Bluetooth--> Bluedroid Options -->Secure Simple Pair`. +2. Enable the SPP functionality by choosing the path as following: + +`Component config --> Bluetooth --> Bluedroid Options --> SPP`. + +3. SSP is enabled as default in this example. If you prefer the legacy pairing, you can disable it in the following path. + +`Component config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`. + ### Build and Flash @@ -33,6 +40,9 @@ idf.py -p PORT flash monitor See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. +## Example Description + +After the program starts, the example will initiate a Bluetooth discovery procedure and filter out the peer device by the name in the EIR(Extended Inquiry Response). After discovering the SPP service, it will connect to the SPP acceptor and send data. The example will calculate the data rate or print the sent data after the SPP connection is established. ### Example Output When you run this example and the IO capability is `ESP_IO_CAP_IO` or `ESP_IO_CAP_IN` , the commands help table prints the following at the very beginning: @@ -98,13 +108,9 @@ Whether you should passkey or confirm the number also depends on the IO capabili ## Troubleshouting -- Set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code (should be same with bt_spp_acceptor). +- Set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code (should be same with `bt_spp_acceptor`, if the peer device runs it). When setting `SPP_SHOW_MODE` as `SPP_SHOW_DATA`, if the data rate is too high or the data length is too long, it is strongly recommended to process them in other lower priority application task rather than in this callback directly. Since the printing takes too much time, and it may stuck the Bluetooth stack. -- After the program started, It will connect to bt_spp_acceptor and send data. - -- We haven't do the same update to `bt_acceptor_demo` for the sake of reducing the size of ESP_IDF, but transplanting of input module is supported. - -- We also show the Security Simple Pair in this SPP demo. Users can set the IO Capability and Security Mode for their device (security level is fixed level 4). The default security mode of this demo is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](../bt_spp_acceptor/ESP32_SSP.md). +- We haven't do the same update to the example `bt_spp_acceptor` for the sake of reducing the size of ESP_IDF, but transplanting of input module is supported. ## Example Breakdown @@ -116,11 +122,10 @@ To clearly show how the SSP aggregate with the SPP , we use the Commands and Eff - If you want to update the command parse rules, please refer to `app_spp_msg_prs.c`. -- If you want to update the responses of HF Unit or want to update the log, please refer to `bt_app_spp.c`. - -- Task configuration part is in `example_spp_initiator_demo.c`. - ## FAQ +Q: How to change the process of SSP? +A: Users can set the IO Capability and Security Mask for their device (fixed Security Mode, Security Mode 4). In short, the Security Mask sets the security level for authentication stage and the IO Capability determines the way of user interaction during pairing. The default Security Mask of this example is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](../bt_spp_acceptor/ESP32_SSP.md). + Q: How can we reach the maximum throughput when using SPP? A: The default MTU size of classic Bluetooth SPP on ESP32 is 990 bytes, and higher throughput can be achieved in the case that data chunck size is close to the MTU size or multiple of MTU size. For example, sending 100 bytes data per second is much better than sending 10 bytes every 100 milliseconds. diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/CMakeLists.txt index 5881e2e9bb94..a9c07d5c0c2e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "example_spp_initiator_demo.c" +idf_component_register(SRCS "main.c" SRCS "app_spp_msg_prs.c" SRCS "app_spp_msg_set.c" SRCS "console_uart.c" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/example_spp_initiator_demo.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c similarity index 63% rename from examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/example_spp_initiator_demo.c rename to examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c index dab35f4c9462..480ee98eec9e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/example_spp_initiator_demo.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c @@ -54,6 +54,19 @@ static const uint8_t inq_num_rsps = 0; #define SPP_DATA_LEN ESP_SPP_MAX_MTU #endif static uint8_t spp_data[SPP_DATA_LEN]; +static uint8_t *s_p_data = NULL; /* data pointer of spp_data */ + +static char *bda2str(uint8_t *bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} static void print_speed(void) { @@ -101,58 +114,123 @@ static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { + uint8_t i = 0; + char bda_str[18] = {0}; + switch (event) { case ESP_SPP_INIT_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); - esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); - esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps); - + if (param->init.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); + esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_INIT_EVT status:%d", param->init.status); + } break; case ESP_SPP_DISCOVERY_COMP_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d scn_num=%d",param->disc_comp.status, param->disc_comp.scn_num); if (param->disc_comp.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT scn_num:%d", param->disc_comp.scn_num); + for (i = 0; i < param->disc_comp.scn_num; i++) { + ESP_LOGI(SPP_TAG, "-- [%d] scn:%d service_name:%s", i, param->disc_comp.scn[i], + param->disc_comp.service_name[i]); + } + /* We only connect to the first found server on the remote SPP acceptor here */ esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], peer_bd_addr); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d", param->disc_comp.status); } break; case ESP_SPP_OPEN_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT"); - esp_spp_write(param->open.handle, SPP_DATA_LEN, spp_data); - gettimeofday(&time_old, NULL); + if (param->open.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT handle:%d rem_bda:[%s]", param->open.handle, + bda2str(param->open.rem_bda, bda_str, sizeof(bda_str))); + /* Start to write the first data packet */ + esp_spp_write(param->open.handle, SPP_DATA_LEN, spp_data); + s_p_data = spp_data; + gettimeofday(&time_old, NULL); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_OPEN_EVT status:%d", param->open.status); + } break; case ESP_SPP_CLOSE_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); + ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT status:%d handle:%d close_by_remote:%d", param->close.status, + param->close.handle, param->close.async); break; case ESP_SPP_START_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT"); break; case ESP_SPP_CL_INIT_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT"); + if (param->cl_init.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT handle:%d sec_id:%d", param->cl_init.handle, param->cl_init.sec_id); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_CL_INIT_EVT status:%d", param->cl_init.status); + } break; case ESP_SPP_DATA_IND_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT"); break; - case ESP_SPP_CONG_EVT: + case ESP_SPP_WRITE_EVT: + if (param->write.status == ESP_SPP_SUCCESS) { + if (s_p_data + param->write.len == spp_data + SPP_DATA_LEN) { + /* Means the previous data packet be sent completely, send a new data packet */ + s_p_data = spp_data; + } else { + /* + * Means the previous data packet only be sent partially due to the lower layer congestion, resend the + * remainning data. + */ + s_p_data += param->write.len; + } #if (SPP_SHOW_MODE == SPP_SHOW_DATA) - ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT cong=%d", param->cong.cong); + /* + * We only show the data in which the data length is less than 128 here. If you want to print the data and + * the data rate is high, it is strongly recommended to process them in other lower priority application task + * rather than in this callback directly. Since the printing takes too much time, it may stuck the Bluetooth + * stack and also have a effect on the throughput! + */ + ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len:%d handle:%d cong:%d", param->write.len, param->write.handle, + param->write.cong); + if (param->write.len < 128) { + esp_log_buffer_hex("", spp_data, param->write.len); + /* Delay a little to avoid the task watch dog */ + vTaskDelay(pdMS_TO_TICKS(10)); + } +#else + gettimeofday(&time_new, NULL); + data_num += param->write.len; + if (time_new.tv_sec - time_old.tv_sec >= 3) { + print_speed(); + } #endif - if (param->cong.cong == 0) { - esp_spp_write(param->cong.handle, SPP_DATA_LEN, spp_data); + } else { + /* Means the prevous data packet is not sent at all, need to send the whole data packet again. */ + ESP_LOGE(SPP_TAG, "ESP_SPP_WRITE_EVT status:%d", param->write.status); } + + if (!param->write.cong) { + /* The lower layer is not congested, you can send the next data packet now. */ + esp_spp_write(param->write.handle, spp_data + SPP_DATA_LEN - s_p_data, s_p_data); + } else { + /* + * The lower layer is congested now, don't send the next data packet until receiving the + * ESP_SPP_CONG_EVT with param->cong.cong == 0. + */ + ; + } + + /* + * If you don't want to manage this complicated process, we also provide the SPP VFS mode that hides the + * implementation details. However, it is less efficient and will block the caller until all data has been sent. + */ break; - case ESP_SPP_WRITE_EVT: + case ESP_SPP_CONG_EVT: #if (SPP_SHOW_MODE == SPP_SHOW_DATA) - ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len=%d cong=%d", param->write.len , param->write.cong); - esp_log_buffer_hex("",spp_data,SPP_DATA_LEN); -#else - gettimeofday(&time_new, NULL); - data_num += param->write.len; - if (time_new.tv_sec - time_old.tv_sec >= 3) { - print_speed(); - } + ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT cong:%d", param->cong.cong); #endif - if (param->write.cong == 0) { - esp_spp_write(param->write.handle, SPP_DATA_LEN, spp_data); + if (param->cong.cong == 0) { + /* Send the privous (partial) data packet or the next data packet. */ + esp_spp_write(param->write.handle, spp_data + SPP_DATA_LEN - s_p_data, s_p_data); } break; case ESP_SPP_SRV_OPEN_EVT: @@ -172,6 +250,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_DISC_RES_EVT: ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_RES_EVT"); esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN); + /* Find the target peer device name in the EIR data */ for (int i = 0; i < param->disc_res.num_prop; i++){ if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR && get_name_from_eir(param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ @@ -179,8 +258,10 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa if (strlen(remote_device_name) == peer_bdname_len && strncmp(peer_bdname, remote_device_name, peer_bdname_len) == 0) { memcpy(peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); - esp_spp_start_discovery(peer_bd_addr); + /* Have found the target peer device, cancel the previous GAP discover procedure. And go on + * dsicovering the SPP service on the peer device */ esp_bt_gap_cancel_discovery(); + esp_spp_start_discovery(peer_bd_addr); } } } @@ -247,11 +328,14 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa void app_main(void) { + esp_err_t ret = ESP_OK; + char bda_str[18] = {0}; + for (int i = 0; i < SPP_DATA_LEN; ++i) { spp_data[i] = i; } - esp_err_t ret = nvs_flash_init(); + ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); @@ -286,16 +370,6 @@ void app_main(void) return; } - if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) { - ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) { - ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - #if (CONFIG_BT_SSP_ENABLED == true) /* Set default parameters for Secure Simple Pairing */ esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; @@ -303,9 +377,20 @@ void app_main(void) esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); if (iocap == ESP_BT_IO_CAP_IN || iocap == ESP_BT_IO_CAP_IO) { console_uart_init(); + vTaskDelay(pdMS_TO_TICKS(500)); } #endif + if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) { + ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) { + ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + /* * Set default parameters for Legacy Pairing * Use variable pin, input pin code when pairing @@ -313,4 +398,6 @@ void app_main(void) esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; esp_bt_pin_code_t pin_code; esp_bt_gap_set_pin(pin_type, 0, pin_code); + + ESP_LOGI(SPP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); } diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/README.md index 290015264bb5..1c4d282bac67 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/README.md @@ -1,17 +1,56 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -ESP-IDF BT-SPP-VFS-ACCEPTOR demo -====================== +## ESP-IDF BT-SPP-VFS-ACCEPTOR Example -Demo of SPP acceptor role +This example is to show how to use the APIs of **Serial Port Protocol** (**SPP**) to create an SPP acceptor which performs as a server, and it will register into the VFS. We aggregate **Secure Simple Pair** (**SSP**) into this example to show how to use SPP when creating your own APPs. We also provide the example `bt_spp_initiator` or the example `bt_spp_vfs_initiator` to create an SPP initiator which performs as a client. In fact, you can create SPP acceptors and SPP initiators on a single device at the same time. -This is the demo for user to use ESP_APIs to create a SPP acceptor. +## How to use example -Options choose step: -1. `idf.py menuconfig` -2. enter menuconfig `Component config`, choose `Bluetooth` -3. enter menu Bluetooth, choose `Classic Bluetooth` and `SPP Profile` -4. choose your options. +### Hardware Required -After the program started, bt_spp_vfs_initator will connect it and send data. +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate the example, it should be connected to an SPP Initiator running on a smartphone, a computer or on another ESP32 development board. + +### Configure the project + +1. Open the project configuration menu: + +``` +idf.py menuconfig +``` + +2. Enable the SPP functionality by choosing the path as following: + +`Component config --> Bluetooth --> Bluedroid Options --> SPP` + +3. If you want to limit the number of connected devices, please make sure set the `BT/BLE MAX ACL CONNECTIONS` and `BR/EDR ACL Max Connections` with same value you want. + +`Component config --> Bluetooth --> Bluedroid Options --> BT/BLE MAX ACL CONNECTIONS(1~7)` +and +`Component config --> Bluetooth --> Bluetooth --> Bluetooth controller --> BR/EDR ACL Max Connections` + + +4. SSP is enabled as default in this example. If you prefer the legacy pairing, you can disable it in the following path. + +`Component config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Description + +After the program starts, the example will start an SPP acceptor. The example will print the received data after the SPP connection is established. You can connect to the server and send data with another ESP32 development board, Andriod phone or computer which performs as the SPP initiator. + +## FAQ +Please refer the FAQ part in the [README.md](../bt_spp_acceptor/README.md) \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/CMakeLists.txt index cb65049dfe21..89b4347dcd92 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "example_spp_vfs_acceptor_demo.c" +idf_component_register(SRCS "main.c" "spp_task.c" INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c similarity index 73% rename from examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c rename to examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c index db608a36eef1..31205ba7e2b2 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c @@ -46,27 +46,51 @@ static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; #define SPP_DATA_LEN 100 -static uint8_t spp_data[SPP_DATA_LEN]; + +static char *bda2str(uint8_t *bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + static void spp_read_handle(void * param) { int size = 0; int fd = (int)param; - do { - /* controll the log frequency, retry after 1s */ - vTaskDelay(1000 / portTICK_PERIOD_MS); + uint8_t *spp_data = NULL; + + spp_data = malloc(SPP_DATA_LEN); + if (!spp_data) { + ESP_LOGE(SPP_TAG, "malloc spp_data failed, fd:%d", fd); + goto done; + } - size = read (fd, spp_data, SPP_DATA_LEN); - ESP_LOGI(SPP_TAG, "fd = %d data_len = %d", fd, size); - if (size == -1) { + do { + /* The frequency of calling this function also limits the speed at which the peer device can send data. */ + size = read(fd, spp_data, SPP_DATA_LEN); + if (size < 0) { break; - } - esp_log_buffer_hex(SPP_TAG, spp_data, size); - if (size == 0) { - /*read fail due to there is no data, retry after 1s*/ - vTaskDelay(1000 / portTICK_PERIOD_MS); + } else if (size == 0) { + /* There is no data, retry after 500 ms */ + vTaskDelay(500 / portTICK_PERIOD_MS); + } else { + ESP_LOGI(SPP_TAG, "fd = %d data_len = %d", fd, size); + esp_log_buffer_hex(SPP_TAG, spp_data, size); + /* To avoid task watchdog */ + vTaskDelay(10 / portTICK_PERIOD_MS); } } while (1); +done: + if (spp_data) { + free(spp_data); + } spp_wr_task_shut_down(); } @@ -74,13 +98,17 @@ static void esp_spp_cb(uint16_t e, void *p) { esp_spp_cb_event_t event = e; esp_spp_cb_param_t *param = p; + char bda_str[18] = {0}; switch (event) { case ESP_SPP_INIT_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT status=%d", param->init.status); if (param->init.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); + /* Enable SPP VFS mode */ esp_spp_vfs_register(); esp_spp_start_srv(sec_mask, role_slave, 0, SPP_SERVER_NAME); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_INIT_EVT status:%d", param->init.status); } break; case ESP_SPP_DISCOVERY_COMP_EVT: @@ -90,18 +118,25 @@ static void esp_spp_cb(uint16_t e, void *p) ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT"); break; case ESP_SPP_CLOSE_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); + ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT status:%d handle:%d close_by_remote:%d", param->close.status, + param->close.handle, param->close.async); break; case ESP_SPP_START_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT"); - esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + if (param->start.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT handle:%d sec_id:%d scn:%d", param->start.handle, param->start.sec_id, + param->start.scn); + esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_START_EVT status:%d", param->start.status); + } break; case ESP_SPP_CL_INIT_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT"); break; case ESP_SPP_SRV_OPEN_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT status=%d", param->srv_open.status); + ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT status:%d handle:%d, rem_bda:[%s]", param->srv_open.status, + param->srv_open.handle, bda2str(param->srv_open.rem_bda, bda_str, sizeof(bda_str))); if (param->srv_open.status == ESP_SPP_SUCCESS) { spp_wr_task_start_up(spp_read_handle, param->srv_open.fd); } @@ -113,6 +148,7 @@ static void esp_spp_cb(uint16_t e, void *p) static void esp_spp_stack_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { + /* To avoid stucking Bluetooth stack, we dispatch the SPP callback event to the other lower priority task */ spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL); } @@ -173,6 +209,7 @@ void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) void app_main(void) { + char bda_str[18] = {0}; esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); @@ -234,4 +271,6 @@ void app_main(void) esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; esp_bt_pin_code_t pin_code; esp_bt_gap_set_pin(pin_type, 0, pin_code); + + ESP_LOGI(SPP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); } diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/README.md index 374a9344f36c..1822cc0fb680 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/README.md @@ -1,17 +1,48 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -ESP-IDF BT-SPP-VFS-INITATOR demo -====================== +# ESP-IDF BT-SPP-INITATOR Example -Demo of SPP initator role +This example is to show how to use the APIs of **Serial Port Protocol** (**SPP**) to create an SPP initiator which performs as a client, and it will register into the VFS. we aggregate **Secure Simple Pair** (**SSP**) into this example to show how to use SPP when creating your own APPs. We also provide the example `bt_spp_acceptor` or the example `bt_spp_vfs_acceptor` to create an SPP acceptor which performs as a server. In fact, you can create SPP acceptors and SPP initiators on a single device at the same time. -This is the demo for user to use ESP_APIs to create a SPP initator. +## How to use example -Options choose step: -1. `idf.py menuconfig` -2. enter menuconfig `Component config`, choose `Bluetooth` -3. enter menu Bluetooth, choose `Classic Bluetooth` and `SPP Profile` -4. choose your options. +### Hardware Required -After the program started, It will connect to bt_spp_vfs_acceptor and send data. +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate the example, you should be connect to an SPP acceptor running on a smartphone, a computer or on another ESP32 development board. + +### Configure the project +1. Open the project configuration menu: +``` +idf.py menuconfig +``` + +2. Enable the SPP functionality by choosing the path as following: + +`Component config --> Bluetooth --> Bluedroid Options --> SPP`. + +3. SSP is enabled as default in this example. If you prefer the legacy pairing, you can disable it in the following path. + +`Component config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`. + + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Description + +After the program starts, the example will initiate a Bluetooth discovery procedure and filter out the peer device by the name in the EIR(Extended Inquiry Response). After discovering the SPP service, it will connect to the SPP acceptor and send data. + +## FAQ +Please refer the FAQ part in the [README.md](../bt_spp_initiator/README.md) diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/CMakeLists.txt index e853defaa2f2..89b4347dcd92 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "example_spp_vfs_initiator_demo.c" +idf_component_register(SRCS "main.c" "spp_task.c" INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c similarity index 74% rename from examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c rename to examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c index 7c6d01c287d1..8c099fbae6d7 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c @@ -53,26 +53,56 @@ static const uint8_t inq_len = 30; static const uint8_t inq_num_rsps = 0; #define SPP_DATA_LEN 20 -static uint8_t spp_data[SPP_DATA_LEN]; + +static char *bda2str(uint8_t *bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} static void spp_write_handle(void * param) { int size = 0; int fd = (int)param; - printf("%s %d %p\n", __func__,fd,param); - do { - /*Controll the log frequency, retry after 1s*/ - vTaskDelay(1000 / portTICK_PERIOD_MS); + uint8_t *spp_data = NULL; + uint16_t i = 0; - size = write (fd, spp_data, SPP_DATA_LEN); - ESP_LOGI(SPP_TAG, "fd = %d data_len = %d",fd, size); + spp_data = malloc(SPP_DATA_LEN); + if (!spp_data) { + ESP_LOGE(SPP_TAG, "malloc spp_data failed, fd:%d", fd); + goto done; + } + + for (i = 0; i < SPP_DATA_LEN; ++i) { + spp_data[i] = i; + } + + do { + /* + * The write function is blocked until all the target length of data has been sent to the lower layer + * successfully an error occurs. + */ + size = write(fd, spp_data, SPP_DATA_LEN); if (size == -1) { break; } else if ( size == 0) { - /*write fail due to ringbuf is full, retry after 1s*/ - vTaskDelay(1000 / portTICK_PERIOD_MS); + /*write fail due to ringbuf is full, retry after 500 ms*/ + vTaskDelay(500 / portTICK_PERIOD_MS); + } else { + ESP_LOGI(SPP_TAG, "fd = %d data_len = %d", fd, size); + vTaskDelay(10 / portTICK_PERIOD_MS); } } while (1); +done: + if (spp_data) { + free(spp_data); + } spp_wr_task_shut_down(); } @@ -112,37 +142,57 @@ static void esp_spp_cb(uint16_t e, void *p) { esp_spp_cb_event_t event = e; esp_spp_cb_param_t *param = p; + uint8_t i = 0; + char bda_str[18] = {0}; switch (event) { case ESP_SPP_INIT_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT status=%d", param->init.status); if (param->init.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); + /* Enable SPP VFS mode */ esp_spp_vfs_register(); esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_INIT_EVT status:%d", param->init.status); } break; case ESP_SPP_DISCOVERY_COMP_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d scn_num=%d",param->disc_comp.status, param->disc_comp.scn_num); if (param->disc_comp.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT scn_num:%d", param->disc_comp.scn_num); + for (i = 0; i < param->disc_comp.scn_num; i++) { + ESP_LOGI(SPP_TAG, "-- [%d] scn:%d service_name:%s", i, param->disc_comp.scn[i], + param->disc_comp.service_name[i]); + } + /* We only connect to the first found server on the remote SPP acceptor here */ esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], peer_bd_addr); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d", param->disc_comp.status); } break; case ESP_SPP_OPEN_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT status=%d", param->open.status); if (param->open.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT handle:%d fd:%d rem_bda:[%s]", param->open.handle, param->open.fd, + bda2str(param->open.rem_bda, bda_str, sizeof(bda_str))); spp_wr_task_start_up(spp_write_handle, param->open.fd); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_OPEN_EVT status:%d", param->open.status); } break; case ESP_SPP_CLOSE_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); + ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT status:%d handle:%d close_by_remote:%d", param->close.status, + param->close.handle, param->close.async); break; case ESP_SPP_START_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT"); break; case ESP_SPP_CL_INIT_EVT: - ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT"); + if (param->cl_init.status == ESP_SPP_SUCCESS) { + ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT handle:%d sec_id:%d", param->cl_init.handle, param->cl_init.sec_id); + } else { + ESP_LOGE(SPP_TAG, "ESP_SPP_CL_INIT_EVT status:%d", param->cl_init.status); + } break; case ESP_SPP_SRV_OPEN_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); @@ -158,6 +208,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_DISC_RES_EVT: ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_RES_EVT"); esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN); + /* Find the target peer device name in the EIR data */ for (int i = 0; i < param->disc_res.num_prop; i++){ if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR && get_name_from_eir(param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ @@ -165,8 +216,10 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa if (strlen(remote_device_name) == peer_bdname_len && strncmp(peer_bdname, remote_device_name, peer_bdname_len) == 0) { memcpy(peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); - esp_spp_start_discovery(peer_bd_addr); + /* Have found the target peer device, cancel the previous GAP discover procedure. And go on + * dsicovering the SPP service on the peer device */ esp_bt_gap_cancel_discovery(); + esp_spp_start_discovery(peer_bd_addr); } } } @@ -231,16 +284,16 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa static void esp_spp_stack_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { + /* To avoid stucking Bluetooth stack, we dispatch the SPP callback event to the other lower priority task */ spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL); } void app_main(void) { - for (int i = 0; i < SPP_DATA_LEN; ++i) { - spp_data[i] = i; - } + esp_err_t ret = ESP_OK; + char bda_str[18] = {0}; - esp_err_t ret = nvs_flash_init(); + ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); @@ -300,4 +353,6 @@ void app_main(void) esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; esp_bt_pin_code_t pin_code; esp_bt_gap_set_pin(pin_type, 0, pin_code); + + ESP_LOGI(SPP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); } diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md index 22b6404c1714..8eb46c6886e3 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md @@ -1,15 +1,15 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -# Hands-Free Audio Gateway +# Hands-Free Audio Gateway (HF-AG) -This example is to show how to use the APIs of Hands-Free (HF) Audio Gateway (AG) Component and the effects of them by providing a set of commands. You can use this example to communicate with a Hands-Free Unit (e.g. a headphone set). This example uses UART for user commands. +This example is to show how to use the APIs of Hands-Free Audio Gateway (hf_ag) Component and the effects of them by providing a set of commands. You can use this example to communicate with a device that implements Hands-Free Client Role (e.g. a headphone set). ## How to use example ### Hardware Required -This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate this example, it should be connected to a Hands-Free Unit running on a Headphone/Headset or on another ESP32 development board loaded with Hands Free Unit (hfp_hf) example from ESP-IDF. +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate this example, it should be connected to a Hands-Free Client running on a Headphone/Headset or on another ESP32 development board loaded with [hfp_hf](../hfp_hf) example of ESP-IDF. ### Configure the project @@ -17,12 +17,45 @@ This example is designed to run on commonly available ESP32 development board, e idf.py menuconfig ``` -ESP32 supports two types of audio data paths: PCM and HCI. Because the default sdkconfig of this example does not configured the data path in a specific way. You should config the data path you want: +### Special Configurations for HFP -- PCM : When using PCM, audio data stream is directed to GPIO pins and you should link these GPIO pins to a speaker via I2S port. You should choose PCM in `menuconfig` path: `Component config --> Bluetooth controller --> BR/EDR Sync(SCO/eSCO) default data path --> PCM`and also `Component config --> Bluetooth --> Bluedroid Options -->Hands Free/Handset Profile --> audio(SCO) data path --> PCM`. -- HCI : When using HCI, audio data stream will be transported to HF unit app via HCI. You should choose HCI in `menuconfig` path: `Component config -->Bluetooth controller -->BR/EDR Sync(SCO/eSCO) default data path --> HCI` and also `Component config --> Bluetooth --> Bluedroid Options -->Hands Free/Handset Profile --> audio(SCO) data path --> HCI`. +#### Data Path -**Note: Wide Band Speech is disabled by default, if you want to use it please select it in the menuconfig path: `Component config --> Bluetooth --> Bluedroid Options --> Wide Band Speech`.** +ESP32 HFP supports two types of audio datapath: PCM and HCI. + +The default configuration is `PCM`, if you want to use `vHCI` you should configure the data path before building and downloading the binary. + +- PCM: To use PCM, audio stream is directed from Bluetooth controller to the specific GPIO pins you set in the demo, and you should link these GPIO pins to a speaker via I2S port. The audio data will not go through the `Bluedroid`. In menuconfig, you should choose PCM in `menuconfig` path: + + `Component config --> Bluetooth controller --> BR/EDR Sync(SCO/eSCO) default data path --> PCM` + + and also + + `Component config --> Bluetooth --> Bluedroid Options --> Hands Free/Handset Profile --> audio(SCO) data path --> PCM`. + +- vHCI: To use vHCI, audio data stream will be directed from Bluetooth Controller through vHCI on ESP32 and go through the Bluedroid to the Application layer. In menuconfig, you should choose vHCI in `menuconfig` path: + + `Component config --> Bluetooth controller --> BR/EDR Sync(SCO/eSCO) default data path --> HCI` + + and also + + `Component config --> Bluetooth --> Bluedroid Options --> Hands Free/Handset Profile --> audio(SCO) data path --> HCI`. + +### Codec Choice + +ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`. + +`CVSD` is the default setting and is also the widely used codec for voice audio. But, `mSBC` is designed to have a better voice quality through `HFP`. To select which one is in use, we provide `Wide Band Speech` item in the `menuconfig`: + +`Component config --> Bluetooth --> Bluedroid Options --> Wide Band Speech.` + +Switching on the `Wide Band Speech` means that the preferred codec is `mSBC`, but which one is actually being used also depends on the `Data Path` configuration. + +- If you choose `PCM` for datapath, you can only use `CVSD` and hardware is responsible for the codec job. In the meanwhile, you cannot use `mSBC` by switching `Wide Band Speech` on, because the `mSBC` is implemented in the Bluedroid (Bluetooth Host Stack) by software. + +- If you choose `vHCI` for datapath with `Wide Band Speech` on, codec job is done in the Bluedroid and mSBC is being used. + +- If you choose `vHCI` for datapath with `Wide Band Speech` off, hardware is responsible for the codec job and `CVSD` is in use. ### Build and Flash diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c index 394c78e2b7d7..11fa79a5743d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c @@ -221,11 +221,14 @@ static void bt_app_send_data_task(void *arg) s_us_duration = s_now_enter_time - s_last_enter_time; if(s_audio_code == ESP_HF_AUDIO_STATE_CONNECTED_MSBC) { // time of a frame is 7.5ms, sample is 120, data is 2 (byte/sample), so a frame is 240 byte (HF_SBC_ENC_RAW_DATA_SIZE) - frame_data_num = s_us_duration / (PCM_BLOCK_DURATION_US / WBS_PCM_INPUT_DATA_SIZE); - s_last_enter_time += frame_data_num * (PCM_BLOCK_DURATION_US / WBS_PCM_INPUT_DATA_SIZE); + frame_data_num = s_us_duration / PCM_BLOCK_DURATION_US * WBS_PCM_INPUT_DATA_SIZE; + s_last_enter_time += frame_data_num / WBS_PCM_INPUT_DATA_SIZE * PCM_BLOCK_DURATION_US; } else { - frame_data_num = s_us_duration / (PCM_BLOCK_DURATION_US / PCM_INPUT_DATA_SIZE); - s_last_enter_time += frame_data_num * (PCM_BLOCK_DURATION_US / PCM_INPUT_DATA_SIZE); + frame_data_num = s_us_duration / PCM_BLOCK_DURATION_US * PCM_INPUT_DATA_SIZE; + s_last_enter_time += frame_data_num / PCM_INPUT_DATA_SIZE * PCM_BLOCK_DURATION_US; + } + if (frame_data_num == 0) { + continue; } buf = osi_malloc(frame_data_num); if (!buf) { diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md index 712e22929324..3d14722d5c62 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md @@ -1,9 +1,11 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -# Hands-Free Unit +# Hands-Free Client -This example is to show how to use the APIs of Hands-Free (HF) Unit Component and the effects of them by providing a set of commands. You can use this example to communicate with an Audio Gateway (AG) device (e.g. a smart phone). This example uses UART for user commands. +This example is to show how to use the APIs of Hands-Free Client Component and the effects of them by providing a set of commands. You can use this example to communicate with a device that implements Hands-Free Audio Gateway (HF-AG) (e.g. a smartphone). + +This demo sends back the audio data back to the HFP AG device, so you can hear your own voice when you link this demo with your HFP-AG device. ## How to use example @@ -17,12 +19,45 @@ This example is designed to run on commonly available ESP32 development board, e idf.py menuconfig ``` -ESP32 supports two types of audio data path: PCM() and HCI(Host-Controller Interface) but the default sdkconfig of this example does not config the data path in a specific way. You should config the data path you want: +### Special Configurations for HFP + +#### Data Path + +ESP32 HFP supports two types of audio datapath: PCM and HCI. + +The default configuration is `PCM`, if you want to use `vHCI` you should configure the data path before building and downloading the binary. + +- `PCM`: To use PCM, audio stream is directed from Bluetooth controller to the specific GPIO pins you set in the demo, and you should link these GPIO pins to a speaker via I2S port. The audio data will not go through the `Bluedroid`. In menuconfig, you should choose PCM in `menuconfig`: + + `Component config --> Bluetooth controller --> BR/EDR Sync(SCO/eSCO) default data path --> PCM` + + and also + + `Component config --> Bluetooth --> Bluedroid Options --> Hands Free/Handset Profile --> audio(SCO) data path --> PCM`. + +- `vHCI`: To use vHCI, audio data stream will be directed from Bluetooth Controller through vHCI on ESP32 and go through the Bluedroid to the Application layer. In menuconfig, you should choose vHCI in `menuconfig`: + + `Component config --> Bluetooth controller --> BR/EDR Sync(SCO/eSCO) default data path --> HCI` + + and also + + `Component config --> Bluetooth --> Bluedroid Options --> Hands Free/Handset Profile --> audio(SCO) data path --> HCI`. + +### Codec Choice + +ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`. + +`CVSD` is the default setting and is also the widely used codec for voice audio. But, `mSBC` is designed to have a better voice quality through `HFP`. To select which one is in use, we provide `Wide Band Speech` item in the `menuconfig` path: + +`Component config --> Bluetooth --> Bluedroid Options --> Wide Band Speech`. + +Switching on the `Wide Band Speech` means that the prefered codec is `mSBC`, but which one is actually being used also depends on the `Data Path` configuration. + +- If you choose `PCM` for datapath, you can only use `CVSD` and hardware is responsible for the codec job. In the meanwhile, you cannot use `mSBC` by switching `Wide Band Speech` on, because the `mSBC` is implemented in the Bluedroid (Bluetooth Host Stack) by software. -- PCM : When using PCM, audio data stream is mapped to GPIO pins and you should link these GPIO pins to a speaker via I2S port. And you should choose PCM in `menuconfig` path: `Component config --> Bluetooth controller --> BR/EDR Sync(SCO/eSCO) default data path --> PCM`and also `Component config --> Bluetooth --> Bluedroid Options -->Hands Free/Handset Profile --> audio(SCO) data path --> PCM`. -- HCI : When using HCI, audio data stream will be transport to HF unit app via HCI. And you should choose HCI in `menuconfig` path: `Component config -->Bluetooth controller -->BR/EDR Sync(SCO/eSCO) default data path --> HCI` and also `Component config --> Bluetooth --> Bluedroid Options -->Hands Free/Handset Profile --> audio(SCO) data path --> HCI`. +- If you choose `vHCI` for datapath with `Wide Band Speech` on, codec job is done in the Bluedroid and mSBC is being used. -**Note: Wide Band Speech is disabled by default, if you want to use it please select it in menuconfig path: `Component config --> Bluetooth --> Bluedroid Options --> Wide Band Speech`.** +- If you choose `vHCI` for datapath with `Wide Band Speech` off, hardware is responsible for the codec job and `CVSD` is in use. ### Build and Flash diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32c3 b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32c3 index 7fd8c2c99b9c..b5760a98a5df 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -426,7 +425,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -639,7 +638,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32s3 b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32s3 index 8edb8235239c..98346f889c79 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defauts.esp32 b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defauts.esp32 index 52cb02588ec6..64d46d9ee63c 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defauts.esp32 +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/sdkconfig.defauts.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -674,7 +673,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32 index 501543ed3dc0..f4156f503d73 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32 @@ -410,10 +410,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -454,7 +453,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # CONFIG_BTDM_COEX_BT_OPTIONS is not set -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) +# end of Bluetooth controller CONFIG_BTDM_CTRL_HW_CCA_EFF=0 CONFIG_BTDM_CTRL_DFT_TX_POWER_LEVEL_EFF=0 @@ -671,7 +670,7 @@ CONFIG_BT_ACL_CONNECTIONS=4 # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c3 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c3 index 8ba3abb18493..c25fd80898d0 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c3 @@ -367,7 +367,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 @@ -382,7 +381,7 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -424,7 +423,7 @@ CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=7 CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 -# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) +# end of Bluetooth controller # # MODEM SLEEP Options @@ -637,7 +636,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32s3 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32s3 index 89d79b1c0f2d..4f8545c0d85a 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32s3 @@ -470,7 +470,6 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_SOC_SUPPORT_5_0=y CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 @@ -530,7 +529,7 @@ CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # -# Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# Bluetooth controller # CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set @@ -539,7 +538,7 @@ CONFIG_BT_CTRL_PINNED_TO_CORE_0=y # MODEM SLEEP Options # # end of MODEM SLEEP Options -# end of Bluetooth controller(ESP32S3 Bluetooth Low Energy) +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -749,7 +748,6 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options # end of Bluetooth diff --git a/examples/bluetooth/esp_ble_mesh/aligenie_demo/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/aligenie_demo/sdkconfig.defaults.esp32c3 index bb2450caf2d8..cfba1d0ff940 100644 --- a/examples/bluetooth/esp_ble_mesh/aligenie_demo/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/aligenie_demo/sdkconfig.defaults.esp32c3 @@ -13,7 +13,6 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/sdkconfig.defaults b/examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/sdkconfig.defaults index a11b8edbed8f..433436bb8782 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/sdkconfig.defaults +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/sdkconfig.defaults @@ -46,7 +46,7 @@ CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y CONFIG_BT_SMP_ENABLE=y -CONFIG_BT_RESERVE_DRAM=0x10000 +CONFIG_BTDM_RESERVE_DRAM=0x10000 # # ESP32-specific diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/README.md b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/README.md index 86a244b8f7dd..60e96f31cee6 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/README.md +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | -| ----------------- | ----- | +| Supported Targets | ESP32 | ESP32-C3 | +| ----------------- | ----- | -------- | # ble mesh node console demo ## Introduction diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_adapter.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_adapter.c index 54e3dc185404..eea71312d021 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_adapter.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_adapter.c @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + #include "esp_ble_mesh_networking_api.h" #include "ble_mesh_adapter.h" @@ -116,9 +117,10 @@ int ble_mesh_node_statistics_accumulate(uint8_t *data, uint32_t value, uint16_t xSemaphoreTake(ble_mesh_node_sema, portMAX_DELAY); for (i = 0; i < ble_mesh_node_statistics.total_package_num; i++) { + /* Filter out repeated packages during retransmission */ if (ble_mesh_node_statistics.package_index[i] == sequence_num) { xSemaphoreGive(ble_mesh_node_sema); - return 1; + return 0; } } @@ -129,6 +131,7 @@ int ble_mesh_node_statistics_accumulate(uint8_t *data, uint32_t value, uint16_t } for (i = 0; i < ble_mesh_node_statistics.total_package_num; i++) { + /* Judge whether the package is received for the first time */ if (ble_mesh_node_statistics.package_index[i] == 0) { ble_mesh_node_statistics.package_index[i] = sequence_num; ble_mesh_node_statistics.package_num += 1; diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_main.c index f6b0889a6eb0..76803ca96449 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_main.c @@ -19,16 +19,11 @@ #include "esp_vfs_dev.h" #include "nvs.h" #include "nvs_flash.h" - #include "esp_vfs_fat.h" - #include "esp_console.h" - #include "ble_mesh_console_decl.h" #include "ble_mesh_example_init.h" -#define TAG "ble_mesh_test" - #if CONFIG_STORE_HISTORY #define MOUNT_PATH "/data" @@ -70,7 +65,14 @@ void app_main(void) initialize_filesystem(); repl_config.history_save_path = HISTORY_PATH; #endif + +#if CONFIG_IDF_TARGET_ESP32C3 + repl_config.prompt = "esp32c3>"; +#else repl_config.prompt = "esp32>"; +#endif + printf("!!!ready!!!\n"); + // init console REPL environment ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_cfg_client_cmd.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_cfg_client_cmd.c index 66c03a6edbfa..8afd9649819d 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_cfg_client_cmd.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_cfg_client_cmd.c @@ -20,6 +20,8 @@ typedef struct { struct arg_str *action_type; struct arg_str *set_state; struct arg_int *opcode; + struct arg_int *count; + struct arg_int *feature; struct arg_int *unicast_address; struct arg_int *appkey_index; struct arg_int *mod_id; @@ -218,6 +220,7 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv) esp_ble_mesh_cfg_default_ttl_set_t ttl_set; esp_ble_mesh_cfg_gatt_proxy_set_t proxy_set; esp_ble_mesh_cfg_app_key_add_t app_key_add; + esp_ble_mesh_cfg_heartbeat_pub_set_t heartbeat_pub_set; esp_ble_mesh_cfg_model_pub_set_t mod_pub_set = { .company_id = 0xFFFF, .cred_flag = false, @@ -261,6 +264,7 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv) if (configuration_client_model_operation.net_idx->count != 0) { client_common.ctx.net_idx = configuration_client_model_operation.net_idx->ival[0]; app_key_add.net_idx = configuration_client_model_operation.net_idx->ival[0]; + heartbeat_pub_set.net_idx = configuration_client_model_operation.net_idx->ival[0]; } if (configuration_client_model_operation.unicast_address->count != 0) { @@ -283,12 +287,14 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv) ttl_set.ttl = configuration_client_model_operation.value->ival[0]; proxy_set.gatt_proxy = configuration_client_model_operation.value->ival[0]; mod_pub_set.publish_ttl = configuration_client_model_operation.value->ival[0]; + heartbeat_pub_set.ttl = configuration_client_model_operation.value->ival[0]; } if (configuration_client_model_operation.addr->count != 0) { mod_sub_del.sub_addr = configuration_client_model_operation.addr->ival[0]; mod_sub_add.sub_addr = configuration_client_model_operation.addr->ival[0]; mod_pub_set.publish_addr = configuration_client_model_operation.addr->ival[0]; + heartbeat_pub_set.dst = configuration_client_model_operation.addr->ival[0]; } if (configuration_client_model_operation.mod_id->count != 0) { @@ -302,6 +308,7 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv) if (configuration_client_model_operation.relay_statue->count != 0) { relay_set.relay = configuration_client_model_operation.relay_statue->ival[0]; mod_pub_set.publish_period = configuration_client_model_operation.relay_statue->ival[0]; + heartbeat_pub_set.period = configuration_client_model_operation.relay_statue->ival[0]; } if (configuration_client_model_operation.relay_transmit->count != 0) { @@ -316,6 +323,14 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv) mod_pub_set.company_id = configuration_client_model_operation.cid->ival[0]; } + if (configuration_client_model_operation.count->count != 0) { + heartbeat_pub_set.count = configuration_client_model_operation.count->ival[0]; + } + + if (configuration_client_model_operation.feature->count != 0) { + heartbeat_pub_set.feature = configuration_client_model_operation.feature->ival[0]; + } + if (configuration_client_model_operation.action_type->count != 0) { if (strcmp(configuration_client_model_operation.action_type->sval[0], "get") == 0) { err = esp_ble_mesh_config_client_get_state(&client_common, &get_state); @@ -346,6 +361,8 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv) err = esp_ble_mesh_config_client_set_state(&client_common, (esp_ble_mesh_cfg_client_set_state_t *)&mod_pub_set); } else if (strcmp(configuration_client_model_operation.set_state->sval[0], "reset") == 0) { err = esp_ble_mesh_config_client_set_state(&client_common, NULL); + }else if(strcmp(configuration_client_model_operation.set_state->sval[0], "hbpub") == 0){ + err = esp_ble_mesh_config_client_set_state(&client_common, (esp_ble_mesh_cfg_client_set_state_t *)&heartbeat_pub_set); } } } else if (strcmp(configuration_client_model_operation.action_type->sval[0], "reg") == 0) { @@ -377,6 +394,8 @@ void ble_mesh_register_configuration_client_model_command(void) configuration_client_model_operation.value = arg_int0("v", NULL, "", "value"); configuration_client_model_operation.addr = arg_int0("a", NULL, "
", "address"); configuration_client_model_operation.mod_id = arg_int0("m", NULL, "", "model id"); + configuration_client_model_operation.count = arg_int0("b", NULL, "", "heartbeat count"); + configuration_client_model_operation.feature = arg_int0("f", NULL, "", "features"); configuration_client_model_operation.end = arg_end(1); const esp_console_cmd_t client_stconfiguration_client_model_operationate_cmd = { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_test_perf_client_cmd.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_test_perf_client_cmd.c index e839c6efe9b1..a2c320e978fa 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_test_perf_client_cmd.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_test_perf_client_cmd.c @@ -1,21 +1,12 @@ -// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" -#include "freertos/xtensa_api.h" #include "freertos/FreeRTOSConfig.h" #include "esp_ble_mesh_networking_api.h" diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_register_cmd.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_register_cmd.c index 7df00659eb80..599928a47b1c 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_register_cmd.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_register_cmd.c @@ -24,15 +24,9 @@ #include "ble_mesh_console_lib.h" #include "ble_mesh_adapter.h" #include "transaction.h" - -#include "provisioner_prov.h" - - #include "esp_ble_mesh_config_model_api.h" - #include "ble_mesh_console_decl.h" - typedef struct { struct arg_str *static_val; struct arg_int *static_val_len; @@ -147,6 +141,17 @@ typedef struct { } ble_mesh_provisioner_bind_model_t; ble_mesh_provisioner_bind_model_t provisioner_local_bind; +typedef struct { + struct arg_str *action_type; + struct arg_int *enable; + struct arg_int *op; + struct arg_int *hb_src; + struct arg_int *hb_dst; + struct arg_int *type; + struct arg_end *end; +} ble_mesh_provisioner_heartbeat_t; +static ble_mesh_provisioner_heartbeat_t heartbeat; + void ble_mesh_register_cmd(void); // Register callback function void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param); @@ -162,7 +167,7 @@ void ble_mesh_register_mesh_node(void) int ble_mesh_register_cb(int argc, char** argv) { - ESP_LOGE(TAG, "enter %s\n", __func__); + ESP_LOGD(TAG, "enter %s\n", __func__); ble_mesh_node_init(); esp_ble_mesh_register_prov_callback(ble_mesh_prov_cb); esp_ble_mesh_register_custom_model_callback(ble_mesh_model_cb); @@ -340,6 +345,18 @@ void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_p case ESP_BLE_MESH_PROVISIONER_ADD_LOCAL_NET_KEY_COMP_EVT: ble_mesh_callback_check_err_code(param->provisioner_add_net_key_comp.err_code, "Provisioner:NetKeyAdd"); break; + case ESP_BLE_MESH_PROVISIONER_ENABLE_HEARTBEAT_RECV_COMP_EVT: + ble_mesh_callback_check_err_code(param->provisioner_enable_heartbeat_recv_comp.err_code, "Provisioner:EnHbRecv"); + break; + case ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT: + ble_mesh_callback_check_err_code(param->provisioner_set_heartbeat_filter_type_comp.err_code, "Provisioner:SetHbFilterType"); + break; + case ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT: + ble_mesh_callback_check_err_code(param->provisioner_set_heartbeat_filter_info_comp.err_code, "Provisioner:SetHbFilterInfo"); + break; + case ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT: + ESP_LOGI(TAG, "Provisioner:HbRecv,OK,%d,%d", param->provisioner_recv_heartbeat.hb_src, param->provisioner_recv_heartbeat.hb_dst); + break; #endif default: break; @@ -593,6 +610,46 @@ int ble_mesh_init(int argc, char **argv) return err; } +int ble_mesh_provisioner_heartbeat(int argc, char** argv) +{ + esp_err_t result = ESP_OK; + bool enable = 1; + uint8_t type = 0; + esp_ble_mesh_heartbeat_filter_info_t info; + uint8_t op = 0; + + ESP_LOGD(TAG, "enter %s\n", __func__); + + int nerrors = arg_parse(argc, argv, (void **) &heartbeat); + if (nerrors != 0) { + arg_print_errors(stderr, heartbeat.end, argv[0]); + return 1; + } + + arg_int_to_value(heartbeat.enable, enable, "enable/disable receiving heartbeat"); + arg_int_to_value(heartbeat.type, type, "heartbeat filter type"); + arg_int_to_value(heartbeat.hb_dst, info.hb_dst, "destination address"); + arg_int_to_value(heartbeat.hb_src, info.hb_src, "source address"); + arg_int_to_value(heartbeat.op, op, "op"); + + if (strcmp(heartbeat.action_type->sval[0], "recv") == 0){ + result = esp_ble_mesh_provisioner_recv_heartbeat(enable); + }else if(strcmp(heartbeat.action_type->sval[0], "type") == 0){ + result = esp_ble_mesh_provisioner_set_heartbeat_filter_type(type); + }else if(strcmp(heartbeat.action_type->sval[0], "info")== 0){ + result = esp_ble_mesh_provisioner_set_heartbeat_filter_info(op, &info); + } + + if(result == ESP_OK){ + ESP_LOGI(TAG, "provisioner:OK\n"); + }else{ + ESP_LOGE(TAG, "provisioner:ERROR\n"); + } + + ESP_LOGD(TAG, "exit %s\n", __func__); + return result; +} + int ble_mesh_node_enable_bearer(int argc, char **argv) { esp_err_t err = 0; @@ -730,13 +787,13 @@ int ble_mesh_node_enter_network_auto(int argc, char **argv) ESP_LOGD(TAG, "enter %s\n", __func__); + err = get_value_string((char *)node_network_info.net_key->sval[0], (char *)info.net_key); + err = get_value_string((char *)node_network_info.dev_key->sval[0], (char *)info.dev_key); + err = get_value_string((char *)node_network_info.app_key->sval[0], (char *)info.app_key); arg_int_to_value(node_network_info.net_idx, info.net_idx, "network key index"); arg_int_to_value(node_network_info.unicast_addr, info.unicast_addr, "unicast address"); arg_int_to_value(node_network_info.app_idx, info.app_idx, "appkey index"); arg_int_to_value(node_network_info.group_addr, info.group_addr, "group address"); - err = get_value_string((char *)node_network_info.net_key->sval[0], (char *)info.net_key); - err = get_value_string((char *)node_network_info.dev_key->sval[0], (char *)info.dev_key); - err = get_value_string((char *)node_network_info.app_key->sval[0], (char *)info.app_key); err = bt_mesh_device_auto_enter_network(&info); if (err == ESP_OK) { @@ -809,7 +866,7 @@ int ble_mesh_provisioner_add_key(int argc, char **argv) uint8_t key[16] = {0}; esp_ble_mesh_prov_data_info_t info = { .net_idx = 1, - .flag = NET_IDX_FLAG, + .flag = PROV_DATA_NET_IDX_FLAG, }; ESP_LOGD(TAG, " enter %s\n", __func__); @@ -1146,5 +1203,22 @@ void ble_mesh_register_cmd(void) }; ESP_ERROR_CHECK(esp_console_cmd_register(&node_network_info_cmd)); + heartbeat.action_type = arg_str0("z", NULL, "", "action type"); + heartbeat.op = arg_int0("o", NULL, "", "add or remove a heartbeat filter entry"); + heartbeat.hb_src = arg_int0("s", NULL, "", "Heartbeat source address"); + heartbeat.hb_dst = arg_int0("d", NULL, "", "Heartbeat destination address"); + heartbeat.type = arg_int0("t", NULL, "", "set the heartbeat filter type"); + heartbeat.enable = arg_int0("e", NULL, "", "enable or disable receiving heartbeat messages"); + heartbeat.end = arg_end(1); + + const esp_console_cmd_t provisioner_heartbeat_cmd = { + .command = "bmphb", + .help = "ble mesh provisioner: support recv heartbeat", + .hint = NULL, + .func = &ble_mesh_provisioner_heartbeat, + .argtable = &heartbeat, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_heartbeat_cmd)); + init_transactions(); } diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults index a18fe8b7ff02..705b41e31873 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults @@ -19,8 +19,12 @@ CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=3 CONFIG_BLE_MESH_CFG_CLI=y CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y CONFIG_BLE_MESH_PROVISIONER=y +CONFIG_BLE_MESH_PROVISIONER_RECV_HB=y +CONFIG_BLE_MESH_PROVISIONER_RECV_HB_FILTER_SIZE=3 CONFIG_BLE_MESH_SELF_TEST=y CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK=y +CONFIG_BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM=80 +CONFIG_BLE_MESH_MAX_PROV_NODES=80 # partitions CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults.esp32c3 new file mode 100644 index 000000000000..eee9ca57cd7a --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/sdkconfig.defaults.esp32c3 @@ -0,0 +1,25 @@ +# ESP32C3-specific +##Override some defaults so BT stack is enabled +# by default in this example +CONFIG_BT_ENABLED=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y +CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y +CONFIG_BT_BTU_TASK_STACK_SIZE=4512 +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y + +# Override some defaults of ESP BLE Mesh +CONFIG_BLE_MESH=y +CONFIG_BLE_MESH_NODE=y +CONFIG_BLE_MESH_PB_GATT=y +CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=3 +CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=3 +CONFIG_BLE_MESH_CFG_CLI=y +CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y +CONFIG_BLE_MESH_PROVISIONER=y +CONFIG_BLE_MESH_SELF_TEST=y +CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK=y +CONFIG_BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM=80 +CONFIG_BLE_MESH_MAX_PROV_NODES=80 + +# end of ESP32C3-specific diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32c3 index d12cb753a0de..fcefd4a64105 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32s3 index be15b1ff5efa..fcefd4a64105 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32c3 index 842596952bfc..a75be7d093e6 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32s3 index 1b684c187c5b..a75be7d093e6 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32c3 index 3604e0480a72..0a18a5e39842 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32s3 index 1884086d0e09..0a18a5e39842 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32c3 index 12ca77e1dd27..fbb2f102d7d7 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32s3 index 33489399b378..fbb2f102d7d7 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32c3 index 035de4b18466..a51201e7c51e 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32s3 index 7f5eadea4133..a51201e7c51e 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32c3 index 883572177f05..40b895710b4f 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32s3 index 585751ad9e04..40b895710b4f 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32c3 index 12ca77e1dd27..fbb2f102d7d7 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32s3 index 33489399b378..fbb2f102d7d7 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32c3 index 83d0e49eb306..dfaa377627fc 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32s3 index 76061212d37e..dfaa377627fc 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_BTU_TASK_STACK_SIZE=4512 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32c3 index 12ca77e1dd27..fbb2f102d7d7 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32s3 index 33489399b378..fbb2f102d7d7 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32c3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32c3 index 6a5416994280..0145911f50fe 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32c3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32c3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_CTRL_COEX_PARAMETERS_ENABLE=y diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32s3 b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32s3 index 176776f9503b..0145911f50fe 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32s3 +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults.esp32s3 @@ -1,7 +1,6 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32S3=y CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE=y CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y CONFIG_BT_CTRL_COEX_PARAMETERS_ENABLE=y diff --git a/examples/bluetooth/hci/README.md b/examples/bluetooth/hci/README.md index 9ed15fc49fca..5b3490914790 100644 --- a/examples/bluetooth/hci/README.md +++ b/examples/bluetooth/hci/README.md @@ -12,6 +12,12 @@ Demonstrates interaction with controller through HCI over UART. See the [README.md](./controller_hci_uart_esp32/README.md) file in the example [controller_hci_uart_esp32](./controller_hci_uart_esp32). +## controller_hci_uart_esp32c3 + +Demonstrates interaction with controller through HCI over UART on ESP32-C3. + +See the [README.md](./controller_hci_uart_esp32c3/README.md) file in the example [controller_hci_uart_esp32c3](./controller_hci_uart_esp32c3). + ## controller_vhci_ble_adv Demonstrates interaction with controller though virtual HCI layer. In this example, simple BLE advertising is done. diff --git a/examples/bluetooth/hci/controller_hci_uart_esp32c3/CMakeLists.txt b/examples/bluetooth/hci/controller_hci_uart_esp32c3/CMakeLists.txt new file mode 100644 index 000000000000..c816f96634b2 --- /dev/null +++ b/examples/bluetooth/hci/controller_hci_uart_esp32c3/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(controller_hci_uart_demo) diff --git a/examples/bluetooth/hci/controller_hci_uart_esp32c3/README.md b/examples/bluetooth/hci/controller_hci_uart_esp32c3/README.md new file mode 100644 index 000000000000..32301501c0f2 --- /dev/null +++ b/examples/bluetooth/hci/controller_hci_uart_esp32c3/README.md @@ -0,0 +1,84 @@ +ESP-IDF UART HCI Controller +================================= +| Supported Targets | ESP32-C3 | +| ----------------- | -------- | + +This example demonstrates how to configure the Bluetooth Low Energy Controller's HCI (Host Controller Interface) to communicate over UART. + +Using this example, BLE radio capabilities of ESP32-C3 chip, can be: + +1. tested via standard HCI messages in Direct Test Mode + +2. used with external Bluetooth host stack installed on PC, or other MCU. + +This example uses UHCI, GDMA together with UART to implement the HCI UART transport. + +This example uses LL/register access directly, because the UHCI driver hasn't been implemented yet. + +## How to use example + +### Hardware Required + +This example should be able to run on any commonly available ESP32-C3 development board. To connect UART to PC, another board such as ESP_Test Board or FT232 USB UART board is usually needed. + +In this example, two UARTs are used: + +- UART0 is used as normal output or by IDF monitor + +- UART1 is used to convey HCI messages + + +RTS and CTS lines of UART1 are required. GPIO4, GPIO5, GPIO6, GPIO7 are used as TxD, RxD, RTS, CTS PINs of UART1, respectively. + +In a frequently-used scenario, if ESP_Test Board is used, connect the TX0, RX0, RTS0, CTS0 and GND of ESP_Test Board to ESP32-C3 UART1 PINs, and Attach ESP_Test board to the host PC. + +### Configure the project + +``` +idf.py menuconfig +``` + +* Baudrate of UART1 can be configured in `Example Configuration > UART Baudrate for HCI` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +The example sets up the HCI UART transport and enable Bluetooth Controller, after started. UART1 PIN and baudrate settings is printed at serial output: + +``` +I (296) cpu_start: Starting scheduler. +I (305) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (305) gpio: GPIO[6]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (315) gpio: GPIO[5]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (325) gpio: GPIO[7]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (335) BTDM_INIT: BT controller compile version [d913766] +I (345) coexist: coexist rom version 9387209 +I (345) phy_init: phy_version 909,aa05aec,Apr 16 2022,13:42:08 +I (435) system_api: Base MAC address is not set +I (435) system_api: read default base MAC address from EFUSE +I (445) BTDM_INIT: Bluetooth MAC: 7c:df:a1:61:e5:36 + +I (445) UHCI: HCI messages can be communicated over UART1: +--PINs: TxD 4, RxD 5, RTS 6, CTS 7 +--Baudrate: 115200 +``` + +After these output occurs, HCI messages can be commnunicated over UART1. + +## Troubleshooting + +## Example Breakdown + diff --git a/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/CMakeLists.txt b/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/CMakeLists.txt new file mode 100644 index 000000000000..47b859fbf97d --- /dev/null +++ b/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "uhci_uart_demo.c" + INCLUDE_DIRS "") diff --git a/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/Kconfig.projbuild b/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/Kconfig.projbuild new file mode 100644 index 000000000000..395e8bef94eb --- /dev/null +++ b/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/Kconfig.projbuild @@ -0,0 +1,10 @@ +menu "Example Configuration" + + config EXAMPLE_HCI_UART_BAUDRATE + int "UART Baudrate for HCI" + range 115200 921600 + default 115200 + help + UART Baudrate for HCI. Please use standard baudrate. + +endmenu diff --git a/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/uhci_uart_demo.c b/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/uhci_uart_demo.c new file mode 100644 index 000000000000..77306f0e48dd --- /dev/null +++ b/examples/bluetooth/hci/controller_hci_uart_esp32c3/main/uhci_uart_demo.c @@ -0,0 +1,289 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include "driver/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/uart.h" +#include "soc/lldesc.h" +#include "esp_private/gdma.h" +#include "hal/uhci_ll.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_log.h" + +static const char *tag = "UHCI"; + +#define UART_HCI_NUM (1) + +#define UART_RX_THRS (120) + +#define GPIO_UART_TXD_OUT (4) +#define GPIO_UART_RXD_IN (5) +#define GPIO_UART_RTS_OUT (6) +#define GPIO_UART_CTS_IN (7) + +#define GPIO_OUTPUT_PIN_SEL ((1ULL<pkt_thres.thrs = size; + + gdma_start(s_rx_channel, (intptr_t)(&uart_env.rx.link)); +} + +static IRAM_ATTR void hci_uart_tl_send_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg) +{ + assert(buf != NULL); + assert(size != 0); + assert(callback != NULL); + + uart_env.tx.callback = callback; + uart_env.tx.arg = arg; + + memset(&uart_env.tx.link, 0, sizeof(lldesc_t)); + uart_env.tx.link.length = size; + uart_env.tx.link.buf = buf; + uart_env.tx.link.eof = 1; + + gdma_start(s_tx_channel, (intptr_t)(&uart_env.tx.link)); +} + +static void hci_uart_tl_flow_on(void) +{ +} + +static bool hci_uart_tl_flow_off(void) +{ + return true; +} + +static void hci_uart_tl_finish_transfers(void) +{ +} + +static IRAM_ATTR bool hci_uart_tl_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + assert(dma_chan == s_rx_channel); + assert(uart_env.rx.callback != NULL); + esp_bt_hci_tl_callback_t callback = uart_env.rx.callback; + void *arg = uart_env.rx.arg; + + // clear callback pointer + uart_env.rx.callback = NULL; + uart_env.rx.arg = NULL; + + // call handler + callback(arg, ESP_BT_HCI_TL_STATUS_OK); + + // send notification to Bluetooth Controller task + esp_bt_h4tl_eif_io_event_notify(1); + + return true; +} + +static IRAM_ATTR bool hci_uart_tl_tx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + assert(dma_chan == s_tx_channel); + assert(uart_env.tx.callback != NULL); + esp_bt_hci_tl_callback_t callback = uart_env.tx.callback; + void *arg = uart_env.tx.arg; + + // clear callback pointer + uart_env.tx.callback = NULL; + uart_env.tx.arg = NULL; + + // call handler + callback(arg, ESP_BT_HCI_TL_STATUS_OK); + + // send notification to Bluetooth Controller task + esp_bt_h4tl_eif_io_event_notify(1); + + return true; +} + +static void uart_gpio_set(void) +{ + gpio_config_t io_output_conf = { + .intr_type = GPIO_PIN_INTR_DISABLE, //disable interrupt + .mode = GPIO_MODE_OUTPUT, // output mode + .pin_bit_mask = GPIO_OUTPUT_PIN_SEL, // bit mask of the output pins + .pull_down_en = 0, // disable pull-down mode + .pull_up_en = 0, // disable pull-up mode + }; + gpio_config(&io_output_conf); + + gpio_config_t io_input_conf = { + .intr_type = GPIO_PIN_INTR_DISABLE, //disable interrupt + .mode = GPIO_MODE_INPUT, // input mode + .pin_bit_mask = GPIO_INPUT_PIN_SEL, // bit mask of the input pins + .pull_down_en = 0, // disable pull-down mode + .pull_up_en = 0, // disable pull-down mode + }; + gpio_config(&io_input_conf); + + uart_set_pin(UART_HCI_NUM, GPIO_UART_TXD_OUT, GPIO_UART_RXD_IN, GPIO_UART_RTS_OUT, GPIO_UART_CTS_IN); +} + +void uhci_uart_install(void) +{ + periph_module_enable(PERIPH_UHCI0_MODULE); + periph_module_reset(PERIPH_UHCI0_MODULE); + + periph_module_enable(PERIPH_UART1_MODULE); + periph_module_reset(PERIPH_UART1_MODULE); + + uart_gpio_set(); + + // configure UART1 + uart_config_t uart_config = { + .baud_rate = CONFIG_EXAMPLE_HCI_UART_BAUDRATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + .rx_flow_ctrl_thresh = UART_RX_THRS, + .source_clk = UART_SCLK_APB, + }; + ESP_ERROR_CHECK(uart_param_config(UART_HCI_NUM, &uart_config)); + + // install DMA driver + gdma_channel_alloc_config_t tx_channel_config = { + .flags.reserve_sibling = 1, + .direction = GDMA_CHANNEL_DIRECTION_TX, + }; + ESP_ERROR_CHECK(gdma_new_channel(&tx_channel_config, &s_tx_channel)); + gdma_channel_alloc_config_t rx_channel_config = { + .direction = GDMA_CHANNEL_DIRECTION_RX, + .sibling_chan = s_tx_channel, + }; + ESP_ERROR_CHECK(gdma_new_channel(&rx_channel_config, &s_rx_channel)); + + gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART, 0)); + gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART, 0)); + + gdma_strategy_config_t strategy_config = { + .auto_update_desc = false, + .owner_check = false + }; + gdma_apply_strategy(s_tx_channel, &strategy_config); + gdma_apply_strategy(s_rx_channel, &strategy_config); + + gdma_rx_event_callbacks_t rx_cbs = { + .on_recv_eof = hci_uart_tl_rx_eof_callback + }; + gdma_register_rx_event_callbacks(s_rx_channel, &rx_cbs, NULL); + + gdma_tx_event_callbacks_t tx_cbs = { + .on_trans_eof = hci_uart_tl_tx_eof_callback + }; + gdma_register_tx_event_callbacks(s_tx_channel, &tx_cbs, NULL); + + // configure UHCI + uhci_ll_init(s_uhci_hw); + uhci_ll_set_eof_mode(s_uhci_hw, UHCI_RX_LEN_EOF); + // disable software flow control + s_uhci_hw->escape_conf.val = 0; + uhci_ll_attach_uart_port(s_uhci_hw, 1); +} + + +void app_main(void) +{ + esp_err_t ret; + + /* Initialize NVS — it is used to store PHY calibration data */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + uhci_uart_install(); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + bt_cfg.hci_tl_funcs = &s_hci_uart_tl_funcs; + + ret = esp_bt_controller_init(&bt_cfg); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret)); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret)); + return; + } + + ESP_LOGI(tag, "HCI messages can be communicated over UART%d: \n" + "--PINs: TxD %d, RxD %d, RTS %d, CTS %d\n" + "--Baudrate: %d", UART_HCI_NUM, + GPIO_UART_TXD_OUT, GPIO_UART_RXD_IN, GPIO_UART_RTS_OUT, GPIO_UART_CTS_IN, + CONFIG_EXAMPLE_HCI_UART_BAUDRATE); +} diff --git a/examples/bluetooth/hci/controller_hci_uart_esp32c3/sdkconfig.defaults b/examples/bluetooth/hci/controller_hci_uart_esp32c3/sdkconfig.defaults new file mode 100644 index 000000000000..b786985ee159 --- /dev/null +++ b/examples/bluetooth/hci/controller_hci_uart_esp32c3/sdkconfig.defaults @@ -0,0 +1,12 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# + +CONFIG_BT_ENABLED=y +CONFIG_BT_CTRL_ESP32C3=y +CONFIG_BT_CTRL_HCI_MODE_UART_H4=y +CONFIG_BT_CTRL_HCI_TL=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=n +CONFIG_BT_CTRL_BLE_SCAN_DUPL=n +# End of deprecated options diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt new file mode 100644 index 000000000000..12e4b51dbd85 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(spp_client) diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/Makefile b/examples/bluetooth/nimble/ble_spp/spp_client/Makefile new file mode 100644 index 000000000000..70ffe569ed8c --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := spp_client + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/README.md b/examples/bluetooth/nimble/ble_spp/spp_client/README.md new file mode 100644 index 000000000000..d4f5062db4a6 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/README.md @@ -0,0 +1,127 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | + +# BLE SPP central example + + In Bluetooth classic (BR/EDR) systems, a Serial Port Profile (SPP) is an adopted profile defined by the Bluetooth Special Interest Group (SIG) used to emulate a serial port connection over a Bluetooth wireless connection. For BLE systems, an adopted SPP profile over BLE is not defined, thus emulation of a serial port must be implemented as a vendor-specific custom profile. + + This reference design consists of two Demos, the BLE SPP server and BLE SPP client that run on their respective endpoints. These devices connect and exchange data wirelessly with each other. This capability creates a virtual serial link over the air. Each byte input can be sent and received by both the server and client. The SPP server is implemented as the [spp_server](../spp_server) demo while the SPP client is implemented as the [spp_client](../spp_client) demo. Espressif designed the BLE SPP applications to use the UART transport layer but you could adapt this design to work with other serial protocols, such as SPI. + + This vendor-specific custom profile is implemented in [main.c](../spp_client/main/main.c) and [main.c](../spp_server/main/main.c). + +## Using Examples + +### Initialization + + Both the server and client will first initialize the UART and BLE. The server demo will set up the serial port service with standard GATT and GAP services in the attribute server. The client demo will scan the BLE broadcast over the air to find the SPP server. + +### Event Processing + + The spp server has two main event processing functions for BLE event: + +```c + static int ble_spp_server_gap_event(struct ble_gap_event *event, void *arg); + static int ble_svc_gatt_handler(uint16_t conn_handle, uint16_t attr_handle,struct ble_gatt_access_ctxt *ctxt, void *arg); +``` + + The SPP client has one main event processing functions for BLE event: + +```c + esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t * param); +``` + + These are some queues and tasks used by SPP application: + + Queues: + + * spp_uart_queue - Uart data messages received from the Uart + + Tasks: + + * `ble_client_uart_task` - process Uart + +### Packet Structure + + After the Uart received data, the data will be posted to Uart task. Then, in the UART_DATA event, the raw data may be retrieved. The max length is 120 bytes every time. + If you run the BLE SPP demo with two ESP32 chips, the MTU size will be exchanged after the BLE connection is established, so every packet can be send directly. + If you only run the ble_spp_server demo, and it was connected by a phone, the MTU size may be less than 123 bytes. In such a case the data will be split into fragments and send in turn. + In every packet, we add 4 bytes to indicate that this is a fragment packet. The first two bytes contain "##" if this is a fragment packet, the third byte is the total number of the packets, the fourth byte is the current number of this packet. + The phone APP need to check the structure of the packet if it want to communicate with the ble_spp_server demo. + +### Sending Data Wirelessly + + The client will be sending WriteNoRsp packets to the server. The server side sends data through notifications. When the Uart receives data, the Uart task places it in the buffer. + +### Receiving Data Wirelessly + + The server will receive this data in the BLE_GATT_ACCESS_OP_WRITE_CHR event. + +### GATT Server Attribute Table + + charactertistic|UUID|Permissions + :-:|:-:|:-: + SPP_DATA_RECV_CHAR|0xABF1|READ&WRITE_NR + SPP_DATA_NOTIFY_CHAR|0xABF2|READ&NOTIFY + SPP_COMMAND_CHAR|0xABF3|READ&WRITE_NR + SPP_STATUS_CHAR|0xABF4|READ & NOTIFY + +This example creates GATT client and performs passive scan, it then connects to peripheral device if the device advertises connectability and the write characteristic. + +It performs three GATT operations against the specified peer: + +* Discover all services,characteristics and descriptors. + +* After the discovery is completed, take UART input from user and write characteristic. + + +Note : + +* Make sure to run `python -m pip install --user -r $IDF_PATH/requirements.txt -r $IDF_PATH/tools/ble/requirements.txt` to install the dependency packages needed. +* Currently this Python utility is only supported on Linux (BLE communication is via BLuez + DBus). + +## How to use example + +### Configure the project + +``` +idf.py menuconfig +``` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +This is the console output on successful connection: + +``` +I (487) NimBLE_SPP_BLE_CENT: BLE Host Task Started +GAP procedure initiated: stop advertising. +GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever +GAP procedure initiated: connect; peer_addr_type=0 peer_addr=7c:df:a1:40:3e:fa scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=0 max_ce_len=0 own_addr_type=0 +Connection established +GATT procedure initiated: discover all services +GATT procedure initiated: discover all characteristics; start_handle=1 end_handle=5 +GATT procedure initiated: discover all characteristics; start_handle=6 end_handle=9 +GATT procedure initiated: discover all characteristics; start_handle=10 end_handle=14 +GATT procedure initiated: discover all characteristics; start_handle=15 end_handle=65535 +GATT procedure initiated: discover all descriptors; chr_val_handle=8 end_handle=9 +GATT procedure initiated: discover all descriptors; chr_val_handle=17 end_handle=18 +GATT procedure initiated: discover all descriptors; chr_val_handle=20 end_handle=65535 +Service discovery complete; status=0 conn_handle=1 +I (9277) NimBLE_SPP_BLE_CENT: Data sent from client uart task = +1b5b41 +GATT procedure initiated: write; att_handle=17 len=3 +I (9277) NimBLE_SPP_BLE_CENT: Write in uart task success! +received notification; conn_handle=1 attr_handle=20 attr_len=1 + +``` diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt new file mode 100644 index 000000000000..7eff1870a2bd --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" "misc.c" "peer.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h b/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h new file mode 100644 index 000000000000..1417b8c13f10 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLESPPCLIENT_ +#define H_BLESPPCLIENT_ + +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_adv_fields; +struct ble_gap_conn_desc; +struct ble_hs_cfg; +union ble_store_value; +union ble_store_key; + +#define GATT_SVR_SVC_ALERT_UUID 0x1811 +#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define GATT_SVR_CHR_NEW_ALERT 0x2A46 +#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_mbuf(const struct os_mbuf *om); +char *addr_str(const void *addr); +void print_uuid(const ble_uuid_t *uuid); +void print_conn_desc(const struct ble_gap_conn_desc *desc); +void print_adv_fields(const struct ble_hs_adv_fields *fields); + +/** Peer. */ +struct peer_dsc { + SLIST_ENTRY(peer_dsc) next; + struct ble_gatt_dsc dsc; +}; +SLIST_HEAD(peer_dsc_list, peer_dsc); + +struct peer_chr { + SLIST_ENTRY(peer_chr) next; + struct ble_gatt_chr chr; + + struct peer_dsc_list dscs; +}; +SLIST_HEAD(peer_chr_list, peer_chr); + +struct peer_svc { + SLIST_ENTRY(peer_svc) next; + struct ble_gatt_svc svc; + + struct peer_chr_list chrs; +}; +SLIST_HEAD(peer_svc_list, peer_svc); + +struct peer; +typedef void peer_disc_fn(const struct peer *peer, int status, void *arg); + +struct peer { + SLIST_ENTRY(peer) next; + + uint16_t conn_handle; + + /** List of discovered GATT services. */ + struct peer_svc_list svcs; + + /** Keeps track of where we are in the service discovery process. */ + uint16_t disc_prev_chr_val; + struct peer_svc *cur_svc; + + /** Callback that gets executed when service discovery completes. */ + peer_disc_fn *disc_cb; + void *disc_cb_arg; +}; + +int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, + void *disc_cb_arg); +const struct peer_dsc * +peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid); +const struct peer_chr * +peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid); +const struct peer_svc * +peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid); +int peer_delete(uint16_t conn_handle); +int peer_add(uint16_t conn_handle); +int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs); +struct peer * +peer_find(uint16_t conn_handle); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/component.mk b/examples/bluetooth/nimble/ble_spp/spp_client/main/component.mk new file mode 100644 index 000000000000..a98f634eae06 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c b/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c new file mode 100644 index 000000000000..8acad2638002 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c @@ -0,0 +1,431 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "ble_spp_client.h" + +#include "driver/uart.h" +static const char *tag = "NimBLE_SPP_BLE_CENT"; +static int ble_spp_client_gap_event(struct ble_gap_event *event, void *arg); +QueueHandle_t spp_common_uart_queue = NULL; +void ble_store_config_init(void); +static bool is_connect = false; +uint16_t connection_handle; +uint16_t attribute_handle; +/* 16 Bit Alert Notification Service UUID */ +#define GATT_SVR_SVC_ALERT_UUID 0x1811 + +/* 16 Bit SPP Service UUID */ +#define GATT_SPP_SVC_UUID 0xABF0 + +/* 16 Bit SPP Service Characteristic UUID */ +#define GATT_SPP_CHR_UUID 0xABF1 + +static void +ble_spp_client_set_handles(const struct peer *peer){ + const struct peer_chr *chr; + chr = peer_chr_find_uuid(peer, + BLE_UUID16_DECLARE(GATT_SPP_SVC_UUID), + BLE_UUID16_DECLARE(GATT_SPP_CHR_UUID)); + connection_handle = peer->conn_handle; + attribute_handle = chr->chr.val_handle; +} + +/** + * Called when service discovery of the specified peer has completed. + */ +static void +ble_spp_client_on_disc_complete(const struct peer *peer, int status, void *arg) +{ + + if (status != 0) { + /* Service discovery failed. Terminate the connection. */ + MODLOG_DFLT(ERROR, "Error: Service discovery failed; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); + return; + } + + /* Service discovery has completed successfully. Now we have a complete + * list of services, characteristics, and descriptors that the peer + * supports. + */ + MODLOG_DFLT(INFO, "Service discovery complete; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + + ble_spp_client_set_handles(peer); +} + +/** + * Initiates the GAP general discovery procedure. + */ +static void +ble_spp_client_scan(void) +{ + uint8_t own_addr_type; + struct ble_gap_disc_params disc_params; + int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Tell the controller to filter duplicates; we don't want to process + * repeated advertisements from the same device. + */ + disc_params.filter_duplicates = 1; + + /** + * Perform a passive scan. I.e., don't send follow-up scan requests to + * each advertiser. + */ + disc_params.passive = 1; + + /* Use defaults for the rest of the parameters. */ + disc_params.itvl = 0; + disc_params.window = 0; + disc_params.filter_policy = 0; + disc_params.limited = 0; + + rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, + ble_spp_client_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error initiating GAP discovery procedure; rc=%d\n", + rc); + } +} + +/** + * Indicates whether we should try to connect to the sender of the specified + * advertisement. The function returns a positive result if the device + * advertises connectability and support for the Alert Notification service. + */ +static int +ble_spp_client_should_connect(const struct ble_gap_disc_desc *disc) +{ + struct ble_hs_adv_fields fields; + int rc; + int i; + + /* The device has to be advertising connectability. */ + if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND && + disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) { + + return 0; + } + + rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data); + if (rc != 0) { + return rc; + } + + /* The device has to advertise support for the Alert Notification + * service (0x1811). + */ + for (i = 0; i < fields.num_uuids16; i++) { + if (ble_uuid_u16(&fields.uuids16[i].u) == GATT_SVR_SVC_ALERT_UUID) { + return 1; + } + } + + return 0; +} + +/** + * Connects to the sender of the specified advertisement of it looks + * interesting. A device is "interesting" if it advertises connectability and + * support for the Alert Notification service. + */ +static void +ble_spp_client_connect_if_interesting(const struct ble_gap_disc_desc *disc) +{ + uint8_t own_addr_type; + int rc; + + /* Don't do anything if we don't care about this advertiser. */ + if (!ble_spp_client_should_connect(disc)) { + return; + } + + /* Scanning must be stopped before a connection can be initiated. */ + rc = ble_gap_disc_cancel(); + if (rc != 0) { + MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); + return; + } + + /* Figure out address to use for connect (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for + * timeout. + */ + + rc = ble_gap_connect(own_addr_type, &disc->addr, 30000, NULL, + ble_spp_client_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d " + "addr=%s; rc=%d\n", + disc->addr.type, addr_str(disc->addr.val), rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that is + * established. ble_spp_client uses the same callback for all connections. + * + * @param event The event being signalled. + * @param arg Application-specified argument; unused by + * ble_spp_client. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +ble_spp_client_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + struct ble_hs_adv_fields fields; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_DISC: + rc = ble_hs_adv_parse_fields(&fields, event->disc.data, + event->disc.length_data); + if (rc != 0) { + return 0; + } + + /* An advertisment report was received during GAP discovery. */ + print_adv_fields(&fields); + + /* Try to connect to the advertiser if it looks interesting. */ + ble_spp_client_connect_if_interesting(&event->disc); + return 0; + + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + if (event->connect.status == 0) { + /* Connection successfully established. */ + MODLOG_DFLT(INFO, "Connection established "); + is_connect = true; + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + MODLOG_DFLT(INFO, "\n"); + + /* Remember peer. */ + rc = peer_add(event->connect.conn_handle); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc); + return 0; + } + + /* Perform service discovery. */ + rc = peer_disc_all(event->connect.conn_handle, + ble_spp_client_on_disc_complete, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc); + return 0; + } + } else { + /* Connection attempt failed; resume scanning. */ + MODLOG_DFLT(ERROR, "Error: Connection failed; status=%d\n", + event->connect.status); + ble_spp_client_scan(); + } + + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + /* Connection terminated. */ + MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason); + print_conn_desc(&event->disconnect.conn); + MODLOG_DFLT(INFO, "\n"); + + /* Forget about peer. */ + peer_delete(event->disconnect.conn.conn_handle); + + /* Resume scanning. */ + ble_spp_client_scan(); + return 0; + + case BLE_GAP_EVENT_DISC_COMPLETE: + MODLOG_DFLT(INFO, "discovery complete; reason=%d\n", + event->disc_complete.reason); + return 0; + + case BLE_GAP_EVENT_NOTIFY_RX: + /* Peer sent us a notification or indication. */ + MODLOG_DFLT(INFO, "received %s; conn_handle=%d attr_handle=%d " + "attr_len=%d\n", + event->notify_rx.indication ? + "indication" : + "notification", + event->notify_rx.conn_handle, + event->notify_rx.attr_handle, + OS_MBUF_PKTLEN(event->notify_rx.om)); + + /* Attribute data is contained in event->notify_rx.om. Use + * `os_mbuf_copydata` to copy the data received in notification mbuf */ + return 0; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + + default: + return 0; + } +} + +static void +ble_spp_client_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +ble_spp_client_on_sync(void) +{ + int rc; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Begin scanning for a peripheral to connect to. */ + ble_spp_client_scan(); +} + +void ble_spp_client_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} +void ble_client_uart_task(void *pvParameters) +{ + ESP_LOGI(tag,"BLE client UART task started\n"); + int rc; + uart_event_t event; + for (;;) { + //Waiting for UART event. + if (xQueueReceive(spp_common_uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + switch (event.type) { + //Event of UART receving data + case UART_DATA: + if (event.size && (is_connect == true)) { + + /* Writing characteristics */ + uint8_t * temp = NULL; + temp = (uint8_t *)malloc(sizeof(uint8_t)*event.size); + if(temp == NULL){ + ESP_LOGE(tag, "malloc failed,%s L#%d\n", __func__, __LINE__); + break; + } + memset(temp, 0x0, event.size); + uart_read_bytes(UART_NUM_0,temp,event.size,portMAX_DELAY); + rc = ble_gattc_write_flat(connection_handle, attribute_handle,temp, event.size,NULL, NULL); + if(rc == 0){ + ESP_LOGI(tag,"Write in uart task success!"); + } + else{ + ESP_LOGI(tag,"Error in writing characteristic"); + } + free(temp); + } + break; + default: + break; + } + } + } + vTaskDelete(NULL); + +} +static void ble_spp_uart_init(void) +{ + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_RTS, + .rx_flow_ctrl_thresh = 122, + .source_clk = UART_SCLK_APB, + }; + + //Install UART driver, and get the queue. + uart_driver_install(UART_NUM_0, 4096, 8192, 10, &spp_common_uart_queue, 0); + //Set UART parameters + uart_param_config(UART_NUM_0, &uart_config); + //Set UART pins + uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + xTaskCreate(ble_client_uart_task, "uTask", 2048, (void*)UART_NUM_0, 8, NULL); +} +void +app_main(void) +{ + int rc; + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + + /* Initialize UART driver and start uart task */ + ble_spp_uart_init(); + + /* Configure the host. */ + ble_hs_cfg.reset_cb = ble_spp_client_on_reset; + ble_hs_cfg.sync_cb = ble_spp_client_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Initialize data structures to track connected peers. */ + rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble-ble-spp-client"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(ble_spp_client_host_task); +} diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/misc.c b/examples/bluetooth/nimble/ble_spp/spp_client/main/misc.c new file mode 100644 index 000000000000..a48103312d77 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/misc.c @@ -0,0 +1,198 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "ble_spp_client.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_mbuf(const struct os_mbuf *om) +{ + int colon, i; + + colon = 0; + while (om != NULL) { + if (colon) { + MODLOG_DFLT(INFO, ":"); + } else { + colon = 1; + } + for (i = 0; i < om->om_len; i++) { + MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", om->om_data[i]); + } + om = SLIST_NEXT(om, om_next); + } +} + +char * +addr_str(const void *addr) +{ + static char buf[6 * 2 + 5 + 1]; + const uint8_t *u8p; + + u8p = addr; + sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); + + return buf; +} + +void +print_uuid(const ble_uuid_t *uuid) +{ + char buf[BLE_UUID_STR_LEN]; + + MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf)); +} + +/** + * Logs information about a connection to the console. + */ +void +print_conn_desc(const struct ble_gap_conn_desc *desc) +{ + MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ", + desc->conn_handle, desc->our_ota_addr.type, + addr_str(desc->our_ota_addr.val)); + MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ", + desc->our_id_addr.type, addr_str(desc->our_id_addr.val)); + MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ", + desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val)); + MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ", + desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val)); + MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + + +void +print_adv_fields(const struct ble_hs_adv_fields *fields) +{ + char s[BLE_HS_ADV_MAX_SZ]; + const uint8_t *u8p; + int i; + + if (fields->flags != 0) { + MODLOG_DFLT(DEBUG, " flags=0x%02x\n", fields->flags); + } + + if (fields->uuids16 != NULL) { + MODLOG_DFLT(DEBUG, " uuids16(%scomplete)=", + fields->uuids16_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids16; i++) { + print_uuid(&fields->uuids16[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uuids32 != NULL) { + MODLOG_DFLT(DEBUG, " uuids32(%scomplete)=", + fields->uuids32_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids32; i++) { + print_uuid(&fields->uuids32[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uuids128 != NULL) { + MODLOG_DFLT(DEBUG, " uuids128(%scomplete)=", + fields->uuids128_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids128; i++) { + print_uuid(&fields->uuids128[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->name != NULL) { + assert(fields->name_len < sizeof s - 1); + memcpy(s, fields->name, fields->name_len); + s[fields->name_len] = '\0'; + MODLOG_DFLT(DEBUG, " name(%scomplete)=%s\n", + fields->name_is_complete ? "" : "in", s); + } + + if (fields->tx_pwr_lvl_is_present) { + MODLOG_DFLT(DEBUG, " tx_pwr_lvl=%d\n", fields->tx_pwr_lvl); + } + + if (fields->slave_itvl_range != NULL) { + MODLOG_DFLT(DEBUG, " slave_itvl_range="); + print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->svc_data_uuid16 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid16="); + print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->public_tgt_addr != NULL) { + MODLOG_DFLT(DEBUG, " public_tgt_addr="); + u8p = fields->public_tgt_addr; + for (i = 0; i < fields->num_public_tgt_addrs; i++) { + MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p)); + u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->appearance_is_present) { + MODLOG_DFLT(DEBUG, " appearance=0x%04x\n", fields->appearance); + } + + if (fields->adv_itvl_is_present) { + MODLOG_DFLT(DEBUG, " adv_itvl=0x%04x\n", fields->adv_itvl); + } + + if (fields->svc_data_uuid32 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid32="); + print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->svc_data_uuid128 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid128="); + print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uri != NULL) { + MODLOG_DFLT(DEBUG, " uri="); + print_bytes(fields->uri, fields->uri_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->mfg_data != NULL) { + MODLOG_DFLT(DEBUG, " mfg_data="); + print_bytes(fields->mfg_data, fields->mfg_data_len); + MODLOG_DFLT(DEBUG, "\n"); + } +} diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/peer.c b/examples/bluetooth/nimble/ble_spp/spp_client/main/peer.c new file mode 100644 index 000000000000..9675ed9a7e8c --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/peer.c @@ -0,0 +1,794 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "host/ble_hs.h" +#include "ble_spp_client.h" + +static void *peer_svc_mem; +static struct os_mempool peer_svc_pool; + +static void *peer_chr_mem; +static struct os_mempool peer_chr_pool; + +static void *peer_dsc_mem; +static struct os_mempool peer_dsc_pool; + +static void *peer_mem; +static struct os_mempool peer_pool; +static SLIST_HEAD(, peer) peers; + +static struct peer_svc * +peer_svc_find_range(struct peer *peer, uint16_t attr_handle); +static struct peer_svc * +peer_svc_find(struct peer *peer, uint16_t svc_start_handle, + struct peer_svc **out_prev); +int +peer_svc_is_empty(const struct peer_svc *svc); + +uint16_t +chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr); +int +chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr); +static struct peer_chr * +peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle, + struct peer_chr **out_prev); +static void +peer_disc_chrs(struct peer *peer); + +static int +peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg); + +struct peer * +peer_find(uint16_t conn_handle) +{ + struct peer *peer; + + SLIST_FOREACH(peer, &peers, next) { + if (peer->conn_handle == conn_handle) { + return peer; + } + } + + return NULL; +} + +static void +peer_disc_complete(struct peer *peer, int rc) +{ + peer->disc_prev_chr_val = 0; + + /* Notify caller that discovery has completed. */ + if (peer->disc_cb != NULL) { + peer->disc_cb(peer, rc, peer->disc_cb_arg); + } +} + +static struct peer_dsc * +peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle) +{ + struct peer_dsc *prev; + struct peer_dsc *dsc; + + prev = NULL; + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (dsc->dsc.handle >= dsc_handle) { + break; + } + + prev = dsc; + } + + return prev; +} + +static struct peer_dsc * +peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle, + struct peer_dsc **out_prev) +{ + struct peer_dsc *prev; + struct peer_dsc *dsc; + + prev = peer_dsc_find_prev(chr, dsc_handle); + if (prev == NULL) { + dsc = SLIST_FIRST(&chr->dscs); + } else { + dsc = SLIST_NEXT(prev, next); + } + + if (dsc != NULL && dsc->dsc.handle != dsc_handle) { + dsc = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return dsc; +} + +static int +peer_dsc_add(struct peer *peer, uint16_t chr_val_handle, + const struct ble_gatt_dsc *gatt_dsc) +{ + struct peer_dsc *prev; + struct peer_dsc *dsc; + struct peer_svc *svc; + struct peer_chr *chr; + + svc = peer_svc_find_range(peer, chr_val_handle); + if (svc == NULL) { + /* Can't find service for discovered descriptor; this shouldn't + * happen. + */ + assert(0); + return BLE_HS_EUNKNOWN; + } + + chr = peer_chr_find(svc, chr_val_handle, NULL); + if (chr == NULL) { + /* Can't find characteristic for discovered descriptor; this shouldn't + * happen. + */ + assert(0); + return BLE_HS_EUNKNOWN; + } + + dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev); + if (dsc != NULL) { + /* Descriptor already discovered. */ + return 0; + } + + dsc = os_memblock_get(&peer_dsc_pool); + if (dsc == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + memset(dsc, 0, sizeof * dsc); + + dsc->dsc = *gatt_dsc; + + if (prev == NULL) { + SLIST_INSERT_HEAD(&chr->dscs, dsc, next); + } else { + SLIST_NEXT(prev, next) = dsc; + } + + return 0; +} + +static void +peer_disc_dscs(struct peer *peer) +{ + struct peer_chr *chr; + struct peer_svc *svc; + int rc; + + /* Search through the list of discovered characteristics for the first + * characteristic that contains undiscovered descriptors. Then, discover + * all descriptors belonging to that characteristic. + */ + SLIST_FOREACH(svc, &peer->svcs, next) { + SLIST_FOREACH(chr, &svc->chrs, next) { + if (!chr_is_empty(svc, chr) && + SLIST_EMPTY(&chr->dscs) && + peer->disc_prev_chr_val <= chr->chr.def_handle) { + + rc = ble_gattc_disc_all_dscs(peer->conn_handle, + chr->chr.val_handle, + chr_end_handle(svc, chr), + peer_dsc_disced, peer); + if (rc != 0) { + peer_disc_complete(peer, rc); + } + + peer->disc_prev_chr_val = chr->chr.val_handle; + return; + } + } + } + + /* All descriptors discovered. */ + peer_disc_complete(peer, 0); +} + +static int +peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg) +{ + struct peer *peer; + int rc; + + peer = arg; + assert(peer->conn_handle == conn_handle); + + switch (error->status) { + case 0: + rc = peer_dsc_add(peer, chr_val_handle, dsc); + break; + + case BLE_HS_EDONE: + /* All descriptors in this characteristic discovered; start discovering + * descriptors in the next characteristic. + */ + if (peer->disc_prev_chr_val > 0) { + peer_disc_dscs(peer); + } + rc = 0; + break; + + default: + /* Error; abort discovery. */ + rc = error->status; + break; + } + + if (rc != 0) { + /* Error; abort discovery. */ + peer_disc_complete(peer, rc); + } + + return rc; +} + +uint16_t +chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr) +{ + const struct peer_chr *next_chr; + + next_chr = SLIST_NEXT(chr, next); + if (next_chr != NULL) { + return next_chr->chr.def_handle - 1; + } else { + return svc->svc.end_handle; + } +} + +int +chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr) +{ + return chr_end_handle(svc, chr) <= chr->chr.val_handle; +} + +static struct peer_chr * +peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle) +{ + struct peer_chr *prev; + struct peer_chr *chr; + + prev = NULL; + SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle >= chr_val_handle) { + break; + } + + prev = chr; + } + + return prev; +} + +static struct peer_chr * +peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle, + struct peer_chr **out_prev) +{ + struct peer_chr *prev; + struct peer_chr *chr; + + prev = peer_chr_find_prev(svc, chr_val_handle); + if (prev == NULL) { + chr = SLIST_FIRST(&svc->chrs); + } else { + chr = SLIST_NEXT(prev, next); + } + + if (chr != NULL && chr->chr.val_handle != chr_val_handle) { + chr = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return chr; +} + +static void +peer_chr_delete(struct peer_chr *chr) +{ + struct peer_dsc *dsc; + + while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) { + SLIST_REMOVE_HEAD(&chr->dscs, next); + os_memblock_put(&peer_dsc_pool, dsc); + } + + os_memblock_put(&peer_chr_pool, chr); +} + +static int +peer_chr_add(struct peer *peer, uint16_t svc_start_handle, + const struct ble_gatt_chr *gatt_chr) +{ + struct peer_chr *prev; + struct peer_chr *chr; + struct peer_svc *svc; + + svc = peer_svc_find(peer, svc_start_handle, NULL); + if (svc == NULL) { + /* Can't find service for discovered characteristic; this shouldn't + * happen. + */ + assert(0); + return BLE_HS_EUNKNOWN; + } + + chr = peer_chr_find(svc, gatt_chr->def_handle, &prev); + if (chr != NULL) { + /* Characteristic already discovered. */ + return 0; + } + + chr = os_memblock_get(&peer_chr_pool); + if (chr == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + memset(chr, 0, sizeof * chr); + + chr->chr = *gatt_chr; + + if (prev == NULL) { + SLIST_INSERT_HEAD(&svc->chrs, chr, next); + } else { + SLIST_NEXT(prev, next) = chr; + } + + return 0; +} + +static int +peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) +{ + struct peer *peer; + int rc; + + peer = arg; + assert(peer->conn_handle == conn_handle); + + switch (error->status) { + case 0: + rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr); + break; + + case BLE_HS_EDONE: + /* All characteristics in this service discovered; start discovering + * characteristics in the next service. + */ + if (peer->disc_prev_chr_val > 0) { + peer_disc_chrs(peer); + } + rc = 0; + break; + + default: + rc = error->status; + break; + } + + if (rc != 0) { + /* Error; abort discovery. */ + peer_disc_complete(peer, rc); + } + + return rc; +} + +static void +peer_disc_chrs(struct peer *peer) +{ + struct peer_svc *svc; + int rc; + + /* Search through the list of discovered service for the first service that + * contains undiscovered characteristics. Then, discover all + * characteristics belonging to that service. + */ + SLIST_FOREACH(svc, &peer->svcs, next) { + if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) { + peer->cur_svc = svc; + rc = ble_gattc_disc_all_chrs(peer->conn_handle, + svc->svc.start_handle, + svc->svc.end_handle, + peer_chr_disced, peer); + if (rc != 0) { + peer_disc_complete(peer, rc); + } + return; + } + } + + /* All characteristics discovered. */ + peer_disc_dscs(peer); +} + +int +peer_svc_is_empty(const struct peer_svc *svc) +{ + return svc->svc.end_handle <= svc->svc.start_handle; +} + +static struct peer_svc * +peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle) +{ + struct peer_svc *prev; + struct peer_svc *svc; + + prev = NULL; + SLIST_FOREACH(svc, &peer->svcs, next) { + if (svc->svc.start_handle >= svc_start_handle) { + break; + } + + prev = svc; + } + + return prev; +} + +static struct peer_svc * +peer_svc_find(struct peer *peer, uint16_t svc_start_handle, + struct peer_svc **out_prev) +{ + struct peer_svc *prev; + struct peer_svc *svc; + + prev = peer_svc_find_prev(peer, svc_start_handle); + if (prev == NULL) { + svc = SLIST_FIRST(&peer->svcs); + } else { + svc = SLIST_NEXT(prev, next); + } + + if (svc != NULL && svc->svc.start_handle != svc_start_handle) { + svc = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return svc; +} + +static struct peer_svc * +peer_svc_find_range(struct peer *peer, uint16_t attr_handle) +{ + struct peer_svc *svc; + + SLIST_FOREACH(svc, &peer->svcs, next) { + if (svc->svc.start_handle <= attr_handle && + svc->svc.end_handle >= attr_handle) { + + return svc; + } + } + + return NULL; +} + +const struct peer_svc * +peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid) +{ + const struct peer_svc *svc; + + SLIST_FOREACH(svc, &peer->svcs, next) { + if (ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) { + return svc; + } + } + + return NULL; +} + +const struct peer_chr * +peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid) +{ + const struct peer_svc *svc; + const struct peer_chr *chr; + + svc = peer_svc_find_uuid(peer, svc_uuid); + if (svc == NULL) { + return NULL; + } + + SLIST_FOREACH(chr, &svc->chrs, next) { + if (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) { + return chr; + } + } + + return NULL; +} + +const struct peer_dsc * +peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid) +{ + const struct peer_chr *chr; + const struct peer_dsc *dsc; + + chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid); + if (chr == NULL) { + return NULL; + } + + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) { + return dsc; + } + } + + return NULL; +} + +static int +peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc) +{ + struct peer_svc *prev; + struct peer_svc *svc; + + svc = peer_svc_find(peer, gatt_svc->start_handle, &prev); + if (svc != NULL) { + /* Service already discovered. */ + return 0; + } + + svc = os_memblock_get(&peer_svc_pool); + if (svc == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + memset(svc, 0, sizeof * svc); + + svc->svc = *gatt_svc; + SLIST_INIT(&svc->chrs); + + if (prev == NULL) { + SLIST_INSERT_HEAD(&peer->svcs, svc, next); + } else { + SLIST_INSERT_AFTER(prev, svc, next); + } + + return 0; +} + +static void +peer_svc_delete(struct peer_svc *svc) +{ + struct peer_chr *chr; + + while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) { + SLIST_REMOVE_HEAD(&svc->chrs, next); + peer_chr_delete(chr); + } + + os_memblock_put(&peer_svc_pool, svc); +} + +static int +peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, void *arg) +{ + struct peer *peer; + int rc; + + peer = arg; + assert(peer->conn_handle == conn_handle); + + switch (error->status) { + case 0: + rc = peer_svc_add(peer, service); + break; + + case BLE_HS_EDONE: + /* All services discovered; start discovering characteristics. */ + if (peer->disc_prev_chr_val > 0) { + peer_disc_chrs(peer); + } + rc = 0; + break; + + default: + rc = error->status; + break; + } + + if (rc != 0) { + /* Error; abort discovery. */ + peer_disc_complete(peer, rc); + } + + return rc; +} + + +int +peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg) +{ + struct peer_svc *svc; + struct peer *peer; + int rc; + + peer = peer_find(conn_handle); + if (peer == NULL) { + return BLE_HS_ENOTCONN; + } + + /* Undiscover everything first. */ + while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { + SLIST_REMOVE_HEAD(&peer->svcs, next); + peer_svc_delete(svc); + } + + peer->disc_prev_chr_val = 1; + peer->disc_cb = disc_cb; + peer->disc_cb_arg = disc_cb_arg; + + rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer); + if (rc != 0) { + return rc; + } + + return 0; +} + +int +peer_delete(uint16_t conn_handle) +{ + struct peer_svc *svc; + struct peer *peer; + int rc; + + peer = peer_find(conn_handle); + if (peer == NULL) { + return BLE_HS_ENOTCONN; + } + + SLIST_REMOVE(&peers, peer, peer, next); + + while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { + SLIST_REMOVE_HEAD(&peer->svcs, next); + peer_svc_delete(svc); + } + + rc = os_memblock_put(&peer_pool, peer); + if (rc != 0) { + return BLE_HS_EOS; + } + + return 0; +} + +int +peer_add(uint16_t conn_handle) +{ + struct peer *peer; + + /* Make sure the connection handle is unique. */ + peer = peer_find(conn_handle); + if (peer != NULL) { + return BLE_HS_EALREADY; + } + + peer = os_memblock_get(&peer_pool); + if (peer == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + + memset(peer, 0, sizeof * peer); + peer->conn_handle = conn_handle; + + SLIST_INSERT_HEAD(&peers, peer, next); + + return 0; +} + +static void +peer_free_mem(void) +{ + free(peer_mem); + peer_mem = NULL; + + free(peer_svc_mem); + peer_svc_mem = NULL; + + free(peer_chr_mem); + peer_chr_mem = NULL; + + free(peer_dsc_mem); + peer_dsc_mem = NULL; +} + +int +peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs) +{ + int rc; + + /* Free memory first in case this function gets called more than once. */ + peer_free_mem(); + + peer_mem = malloc( + OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer))); + if (peer_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_pool, max_peers, + sizeof (struct peer), peer_mem, + "peer_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + peer_svc_mem = malloc( + OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc))); + if (peer_svc_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_svc_pool, max_svcs, + sizeof (struct peer_svc), peer_svc_mem, + "peer_svc_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + peer_chr_mem = malloc( + OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr))); + if (peer_chr_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_chr_pool, max_chrs, + sizeof (struct peer_chr), peer_chr_mem, + "peer_chr_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + peer_dsc_mem = malloc( + OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc))); + if (peer_dsc_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_dsc_pool, max_dscs, + sizeof (struct peer_dsc), peer_dsc_mem, + "peer_dsc_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + return 0; + +err: + peer_free_mem(); + return rc; +} diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/sdkconfig.defaults b/examples/bluetooth/nimble/ble_spp/spp_client/sdkconfig.defaults new file mode 100644 index 000000000000..c829fc5c002e --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_client/sdkconfig.defaults @@ -0,0 +1,12 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt new file mode 100644 index 000000000000..55b96496a362 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(spp_server) diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/Makefile b/examples/bluetooth/nimble/ble_spp/spp_server/Makefile new file mode 100644 index 000000000000..be21a9d26b8b --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := spp_server + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/README.md b/examples/bluetooth/nimble/ble_spp/spp_server/README.md new file mode 100644 index 000000000000..b1324e32685f --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/README.md @@ -0,0 +1,117 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | + +# BLE SPP peripheral example + + In Bluetooth classic (BR/EDR) systems, a Serial Port Profile (SPP) is an adopted profile defined by the Bluetooth Special Interest Group (SIG) used to emulate a serial port connection over a Bluetooth wireless connection. For BLE systems, an adopted SPP profile over BLE is not defined, thus emulation of a serial port must be implemented as a vendor-specific custom profile. + + This reference design consists of two Demos, the BLE SPP server and BLE SPP client that run on their respective endpoints. These devices connect and exchange data wirelessly with each other. This capability creates a virtual serial link over the air. Each byte input can be sent and received by both the server and client. The SPP server is implemented as the [spp_server](../spp_server) demo while the SPP client is implemented as the [spp_client](../spp_client) demo. Espressif designed the BLE SPP applications to use the UART transport layer but you could adapt this design to work with other serial protocols, such as SPI. + + This vendor-specific custom profile is implemented in [main.c](../spp_client/main/main.c) and [main.c](../spp_server/main/main.c). + +## Using Examples + +### Initialization + + Both the server and client will first initialize the UART and BLE. The server demo will set up the serial port service with standard GATT and GAP services in the attribute server. The client demo will scan the BLE broadcast over the air to find the SPP server. + +### Event Processing + + The SPP server has two main event processing functions for BLE event: + +```c + static int ble_spp_server_gap_event(struct ble_gap_event *event, void *arg); + static int ble_svc_gatt_handler(uint16_t conn_handle, uint16_t attr_handle,struct ble_gatt_access_ctxt *ctxt, void *arg); +``` + + The SPP client has one main event processing functions for BLE event: + +```c + esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t * param); +``` + + These are some queues and tasks used by SPP application: + + Queues: + + * spp_uart_queue - Uart data messages received from the Uart + + Tasks: + + * `ble_server_uart_task` - process Uart + +### Packet Structure + + After the Uart received data, the data will be posted to Uart task. Then, in the UART_DATA event, the raw data may be retrieved. The max length is 120 bytes every time. + If you run the BLE SPP demo with two ESP32 chips, the MTU size will be exchanged for 200 bytes after the ble connection is established, so every packet can be send directly. + If you only run the ble_spp_server demo, and it was connected by a phone, the MTU size may be less than 123 bytes. In such a case the data will be split into fragments and send in turn. + In every packet, we add 4 bytes to indicate that this is a fragment packet. The first two bytes contain "##" if this is a fragment packet, the third byte is the total number of the packets, the fourth byte is the current number of this packet. + The phone APP need to check the structure of the packet if it want to communicate with the ble_spp_server demo. + +### Sending Data Wirelessly + + The client will be sending WriteNoRsp packets to the server. The server side sends data through notifications. When the Uart receives data, the Uart task places it in the buffer. + +### Receiving Data Wirelessly + + The server will receive this data in the BLE_GATT_ACCESS_OP_WRITE_CHR event. + +### GATT Server Attribute Table + + charactertistic|UUID|Permissions + :-:|:-:|:-: + SPP_DATA_RECV_CHAR|0xABF1|READ&WRITE_NR + SPP_DATA_NOTIFY_CHAR|0xABF2|READ&NOTIFY + SPP_COMMAND_CHAR|0xABF3|READ&WRITE_NR + SPP_STATUS_CHAR|0xABF4|READ & NOTIFY + +This example creates GATT client and performs passive scan, it then connects to peripheral device if the device advertises connectability and the write characteristic. + +It performs three GATT operations against the specified peer: + +* Discover all services,characteristics and descriptors. + +* After the discovery is completed, take UART input from user and write characteristic. + + +Note : + +* Make sure to run `python -m pip install --user -r $IDF_PATH/requirements.txt -r $IDF_PATH/tools/ble/requirements.txt` to install the dependency packages needed. +* Currently this Python utility is only supported on Linux (BLE communication is via BLuez + DBus). + +## How to use example + +### Configure the project + +``` +idf.py menuconfig +``` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +This is the console output on successful connection: + +``` +I (464) NimBLE_SPP_BLE_PRPH: BLE Host Task Started +GAP procedure initiated: stop advertising. +Device Address: 7c:df:a1:40:3e:fa +GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 +connection established; status=0 handle=1 our_ota_addr_type=0 our_ota_addr=7c:df:a1:40:3e:fa our_id_addr_type=0 our_id_addr=7c:df:a1:40:3e:fa peer_ota_addr_type=0 peer_ota_addr=7c:df:a1:c2:19:92 peer_id_addr_type=0 peer_id_addr=7c:df:a1:c2:19:92 conn_itvl=40 conn_latency=0 supervision_timeout=256 encrypted=0 authenticated=0 bonded=0 + +I (6924) NimBLE_SPP_BLE_PRPH: Data received in write event,conn_handle = 1,attr_handle = 11 +1b5b41I +(10824) NimBLE_SPP_BLE_PRPH: Notification sent successfully + +``` diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt new file mode 100644 index 000000000000..1d440d5d68ed --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "main.c" + "gatt_svr.c" + "misc.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_spp/spp_server/main/Kconfig.projbuild new file mode 100644 index 000000000000..ad7ae8bcc288 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/Kconfig.projbuild @@ -0,0 +1,7 @@ +menu "Example Configuration" + + config EXAMPLE_IO_TYPE + int "IO Type" + default 3 + +endmenu diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h b/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h new file mode 100644 index 000000000000..bc2b437c6c2c --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLESPPSERVER_ +#define H_BLESPPSERVER_ + +#include +#include "nimble/ble.h" +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +/** GATT server. */ +#define GATT_SVR_SVC_ALERT_UUID 0x1811 +#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define GATT_SVR_CHR_NEW_ALERT 0x2A46 +#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int new_gatt_svr_init(void); + +/* Console */ +int scli_init(void); +int scli_receive_key(int *key); + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_addr(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/component.mk b/examples/bluetooth/nimble/ble_spp/spp_server/main/component.mk new file mode 100644 index 000000000000..a98f634eae06 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/gatt_svr.c b/examples/bluetooth/nimble/ble_spp/spp_server/main/gatt_svr.c new file mode 100644 index 000000000000..143d372beec8 --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/gatt_svr.c @@ -0,0 +1,207 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" +#include "ble_spp_server.h" + +/* 16 Bit Alert Notification Service UUID */ +#define BLE_SVC_ANS_UUID16 0x1811 + +/* 16 Bit Alert Notification Service Characteristic UUIDs */ +#define BLE_SVC_ANS_CHR_UUID16_SUP_NEW_ALERT_CAT 0x2a47 +#define BLE_SVC_ANS_CHR_UUID16_NEW_ALERT 0x2a46 +#define BLE_SVC_ANS_CHR_UUID16_SUP_UNR_ALERT_CAT 0x2a48 +#define BLE_SVC_ANS_CHR_UUID16_UNR_ALERT_STAT 0x2a45 +#define BLE_SVC_ANS_CHR_UUID16_ALERT_NOT_CTRL_PT 0x2a44 + +/** + * The vendor specific security test service consists of two characteristics: + * o random-number-generator: generates a random 32-bit number each time + * it is read. This characteristic can only be read over an encrypted + * connection. + * o static-value: a single-byte characteristic that can always be read, + * but can only be written over an encrypted connection. + */ + +/* 59462f12-9543-9999-12c8-58b459a2712d */ +static const ble_uuid128_t gatt_svr_svc_sec_test_uuid = + BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, + 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); + +/* 5c3a659e-897e-45e1-b016-007107c96df6 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid = + BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +/* 5c3a659e-897e-45e1-b016-007107c96df7 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid = + BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +static uint8_t gatt_svr_sec_test_static_val; + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + /*** Service: Security test. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc_sec_test_uuid.u, + .characteristics = (struct ble_gatt_chr_def[]) + { { + /*** Characteristic: Random number generator. */ + .uuid = &gatt_svr_chr_sec_test_rand_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, + }, { + /*** Characteristic: Static value. */ + .uuid = &gatt_svr_chr_sec_test_static_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, + }, { + 0, /* No more characteristics in this service. */ + } + }, + }, + + { + 0, /* No more services. */ + }, +}; + +static int +gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) +{ + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + return 0; +} + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + const ble_uuid_t *uuid; + int rand_num; + int rc; + + uuid = ctxt->chr->uuid; + + /* Determine which characteristic is being accessed by examining its + * 128-bit UUID. + */ + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) { + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + + /* Respond with a 32-bit random number. */ + rand_num = rand(); + rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) { + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + rc = gatt_svr_chr_write(ctxt->om, + sizeof gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val, + &gatt_svr_sec_test_static_val, NULL); + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + } + + /* Unknown characteristic; the nimble stack should not have called this + * function. + */ + assert(0); + return BLE_ATT_ERR_UNLIKELY; +} + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + MODLOG_DFLT(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +int +new_gatt_svr_init(void) +{ + int rc; + + ble_svc_gap_init(); + ble_svc_gatt_init(); + + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c b/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c new file mode 100644 index 000000000000..373c90373bfb --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c @@ -0,0 +1,443 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "ble_spp_server.h" +#include "driver/uart.h" + +static const char *tag = "NimBLE_SPP_BLE_PRPH"; +static int ble_spp_server_gap_event(struct ble_gap_event *event, void *arg); +static uint8_t own_addr_type; +int gatt_svr_register(void); +QueueHandle_t spp_common_uart_queue = NULL; +static bool is_connect = false; +uint16_t connection_handle; +static uint16_t ble_svc_gatt_read_val_handle,ble_spp_svc_gatt_read_val_handle; + +/* 16 Bit Alert Notification Service UUID */ +#define BLE_SVC_ANS_UUID16 0x1811 + +/* 16 Bit Alert Notification Service Characteristic UUIDs */ +#define BLE_SVC_ANS_CHR_UUID16_SUP_NEW_ALERT_CAT 0x2a47 + +/* 16 Bit SPP Service UUID */ +#define BLE_SVC_SPP_UUID16 0xABF0 + +/* 16 Bit SPP Service Characteristic UUID */ +#define BLE_SVC_SPP_CHR_UUID16 0xABF1 + +void ble_store_config_init(void); + +/** + * Logs information about a connection to the console. + */ +static void +ble_spp_server_print_conn_desc(struct ble_gap_conn_desc *desc) +{ + MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=", + desc->conn_handle, desc->our_ota_addr.type); + print_addr(desc->our_ota_addr.val); + MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=", + desc->our_id_addr.type); + print_addr(desc->our_id_addr.val); + MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr.type); + print_addr(desc->peer_ota_addr.val); + MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr.type); + print_addr(desc->peer_id_addr.val); + MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d\n", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +ble_spp_server_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + const char *name; + int rc; + + /** + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info). + * o Advertising tx power. + * o Device name. + * o 16-bit service UUIDs (alert notifications). + */ + + memset(&fields, 0, sizeof fields); + + /* Advertise two flags: + * o Discoverability in forthcoming advertisement (general) + * o BLE-only (BR/EDR unsupported). + */ + fields.flags = BLE_HS_ADV_F_DISC_GEN | + BLE_HS_ADV_F_BREDR_UNSUP; + + /* Indicate that the TX power level field should be included; have the + * stack fill this value automatically. This is done by assigning the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + + name = ble_svc_gap_device_name(); + fields.name = (uint8_t *)name; + fields.name_len = strlen(name); + fields.name_is_complete = 1; + + fields.uuids16 = (ble_uuid16_t[]) { + BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID) + }; + fields.num_uuids16 = 1; + fields.uuids16_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising. */ + memset(&adv_params, 0, sizeof adv_params); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, + &adv_params, ble_spp_server_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that forms. + * ble_spp_server uses the same callback for all connections. + * + * @param event The type of event being signalled. + * @param ctxt Various information pertaining to the event. + * @param arg Application-specified argument; unused by + * ble_spp_server. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +ble_spp_server_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + MODLOG_DFLT(INFO, "connection %s; status=%d ", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + if (event->connect.status == 0) { + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + ble_spp_server_print_conn_desc(&desc); + is_connect=true; + connection_handle = event->connect.conn_handle; + } + MODLOG_DFLT(INFO, "\n"); + if (event->connect.status != 0) { + /* Connection failed; resume advertising. */ + ble_spp_server_advertise(); + } + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason); + ble_spp_server_print_conn_desc(&event->disconnect.conn); + MODLOG_DFLT(INFO, "\n"); + + /* Connection terminated; resume advertising. */ + ble_spp_server_advertise(); + return 0; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + MODLOG_DFLT(INFO, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + assert(rc == 0); + ble_spp_server_print_conn_desc(&desc); + MODLOG_DFLT(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_ADV_COMPLETE: + MODLOG_DFLT(INFO, "advertise complete; reason=%d", + event->adv_complete.reason); + ble_spp_server_advertise(); + return 0; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + + default: + return 0; + } +} + +static void +ble_spp_server_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +ble_spp_server_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Printing ADDR */ + uint8_t addr_val[6] = {0}; + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + MODLOG_DFLT(INFO, "Device Address: "); + print_addr(addr_val); + MODLOG_DFLT(INFO, "\n"); + /* Begin advertising. */ + ble_spp_server_advertise(); +} + +void ble_spp_server_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +/* Callback function for custom service */ +static int ble_svc_gatt_handler(uint16_t conn_handle, uint16_t attr_handle,struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + switch(ctxt->op){ + case BLE_GATT_ACCESS_OP_READ_CHR: + ESP_LOGI(tag, "Callback for read"); + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + ESP_LOGI(tag,"Data received in write event,conn_handle = %x,attr_handle = %x",conn_handle,attr_handle); + break; + + default: + ESP_LOGI(tag, "\nDefault Callback"); + break; + } + return 0; +} + +/* Define new custom service */ +static const struct ble_gatt_svc_def new_ble_svc_gatt_defs[] = { + { + /*** Service: GATT */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_UUID16), + .characteristics = (struct ble_gatt_chr_def[]) { { + /* Support new alert category */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_CHR_UUID16_SUP_NEW_ALERT_CAT), + .access_cb = ble_svc_gatt_handler, + .val_handle = &ble_svc_gatt_read_val_handle, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE, + }, + { + 0, /* No more characteristics */ + } + }, + }, + { + /*** Service: SPP */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_SPP_UUID16), + .characteristics = (struct ble_gatt_chr_def[]) { { + /* Support SPP service */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_SPP_CHR_UUID16), + .access_cb = ble_svc_gatt_handler, + .val_handle = &ble_spp_svc_gatt_read_val_handle, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE, + }, + { + 0, /* No more characteristics */ + } + }, + }, + { + 0, /* No more services. */ + }, +}; + +int gatt_svr_register(void) +{ + int rc=0; + + rc = ble_gatts_count_cfg(new_ble_svc_gatt_defs); + + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(new_ble_svc_gatt_defs); + if (rc != 0) { + return rc; + } + + return 0; +} + + +void ble_server_uart_task(void *pvParameters){ + ESP_LOGI(tag,"BLE server UART_task started\n"); + uart_event_t event; + int rc=0; + for (;;) { + //Waiting for UART event. + if (xQueueReceive(spp_common_uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + switch (event.type) { + //Event of UART receving data + case UART_DATA: + if (event.size && (is_connect == true)) { + static uint8_t ntf[1]; + ntf[0] = 90; + struct os_mbuf *txom; + txom = ble_hs_mbuf_from_flat(ntf, sizeof(ntf)); + rc = ble_gattc_notify_custom(connection_handle,ble_spp_svc_gatt_read_val_handle,txom); + if( rc == 0){ + ESP_LOGI(tag,"Notification sent successfully"); + } + else { + ESP_LOGI(tag,"Error in sending notification"); + } + } + break; + default: + break; + } + } + } + vTaskDelete(NULL); +} +static void ble_spp_uart_init(void) +{ + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_RTS, + .rx_flow_ctrl_thresh = 122, + .source_clk = UART_SCLK_APB, + }; + //Install UART driver, and get the queue. + uart_driver_install(UART_NUM_0, 4096, 8192, 10,&spp_common_uart_queue,0); + //Set UART parameters + uart_param_config(UART_NUM_0, &uart_config); + //Set UART pins + uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + xTaskCreate(ble_server_uart_task, "uTask", 2048, (void*)UART_NUM_0, 8, NULL); +} + + +void +app_main(void) +{ + int rc; + + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + + /* Initialize uart driver and start uart task */ + ble_spp_uart_init(); + + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = ble_spp_server_on_reset; + ble_hs_cfg.sync_cb = ble_spp_server_on_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + ble_hs_cfg.sm_io_cap = CONFIG_EXAMPLE_IO_TYPE; +#ifdef CONFIG_EXAMPLE_BONDING + ble_hs_cfg.sm_bonding = 1; +#endif +#ifdef CONFIG_EXAMPLE_MITM + ble_hs_cfg.sm_mitm = 1; +#endif +#ifdef CONFIG_EXAMPLE_USE_SC + ble_hs_cfg.sm_sc = 1; +#else + ble_hs_cfg.sm_sc = 0; +#endif +#ifdef CONFIG_EXAMPLE_BONDING + ble_hs_cfg.sm_our_key_dist = 1; + ble_hs_cfg.sm_their_key_dist = 1; +#endif + + + rc = new_gatt_svr_init(); + assert(rc == 0); + + /* Register custom service */ + rc = gatt_svr_register(); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble-ble-spp-svr"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(ble_spp_server_host_task); +} diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/misc.c b/examples/bluetooth/nimble/ble_spp/spp_server/main/misc.c new file mode 100644 index 000000000000..b4a3fc79c22c --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/misc.c @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ble_spp_server.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/sdkconfig.defaults b/examples/bluetooth/nimble/ble_spp/spp_server/sdkconfig.defaults new file mode 100644 index 000000000000..c829fc5c002e --- /dev/null +++ b/examples/bluetooth/nimble/ble_spp/spp_server/sdkconfig.defaults @@ -0,0 +1,12 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y diff --git a/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c b/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c index fb93e64feeb7..5a4e3b4811e3 100644 --- a/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c +++ b/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c @@ -123,11 +123,6 @@ void wifi_init_sta(void) * However these modes are deprecated and not advisable to be used. Incase your Access point * doesn't support WPA2, these mode can be enabled by commenting below line */ .threshold.authmode = WIFI_AUTH_WPA2_PSK, - - .pmf_cfg = { - .capable = true, - .required = false - }, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); diff --git a/examples/bluetooth/nimble/throughput_app/README.md b/examples/bluetooth/nimble/throughput_app/README.md new file mode 100644 index 000000000000..0b26ba21db0f --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/README.md @@ -0,0 +1,16 @@ +# Throughput demo Examples + +There are two different example folders inside this `throughput_app`, `bleprph_throughput` and `blecent_throughput`. As the names suggest, both of them play role of `peripheral` and `central` respectively. These example demonstrate application throughput for NimBLE on ESP32. Two ESP32 boards are needed to run this demo. The `blecent_throughput` example has CLI support to select GATT operation from READ/WRITE/NOTIFY. It can also accept connection parameters at start of program, more details can be found in respective READMEs. + +## Using the examples + +First build and flash two ESP32 boards with `bleprph_throughput` and `blecent_throughput` examples. The central automatically scans and connects to peripheral based on peripheral name string (`nimble_prph`). In the next step, user may choose to configure connection parameters (`MTU`, `connection interval`, `latency`, `supervision timeout`, `connection event length`). In the next step, user needs to specify throughput test name (`read`, `write` or `notify`) and test time in seconds. Below are +sample numbers of different throughput test runs for 60 seconds (MTU = 512, conn itvl = 7.5msec, conn event length = 7.5msec) + +|GATT method | Measurement time | Application Throughput| +|--- | --- | ---| +|NOTIFY | 60 seconds | ~340Kbps| +|READ | 60 seconds | ~200kbps| +|WRITE | 60 seconds | ~500kbps| + +The notify output is seen on `bleprph_throughput` console and read/write throughput are seen on `blecent_throughput` console. diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/CMakeLists.txt b/examples/bluetooth/nimble/throughput_app/blecent_throughput/CMakeLists.txt new file mode 100644 index 000000000000..39d134aae854 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(blecent_throughput) diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/Makefile b/examples/bluetooth/nimble/throughput_app/blecent_throughput/Makefile new file mode 100644 index 000000000000..52b2d627b87d --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := blecent_throughput + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/README.md b/examples/bluetooth/nimble/throughput_app/blecent_throughput/README.md new file mode 100644 index 000000000000..9dbd38ba6826 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/README.md @@ -0,0 +1,150 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +# Throughput blecent Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +`blecent_throughput` demonstrates client side implementation required for NimBLE throughput example. It connects to `bleprph_throughput` based on name string `nimble_prph`. It has interactive CLI support to start READ/WRITE/NOTIFY GATT operation for user specified time. + +It performs read operation on peripheral's `THRPT_LONG_CHR_READ_WRITE` characteristic, write operation on `THRPT_CHR_READ_WRITE` and subscribes to `THRPT_CHR_NOTIFY` characteristic for notifications. If user does not specify any throughput test method for 30 seconds (`BLE_RX_TIMEOUT`) then the program starts with default READ operations for 60 seconds. + +`blecent_throughput` uses the `NimBLE` as BLE host. + +### Procedure to use this demo example + +* `idf.py menuconfig` and configure the parameters as needed (connection related parameters in example parameters). +* `bleprph_throughput` example needs to be run along with this client side example. +* After connection link is established between these two devices, user is given a window of `YES_NO_PARAM` (5 seconds) to customize connection parameters. If user has configured parameters from menuconfig, this step can be skipped by either waiting it out or entering `Insert no`. +* User needs to enter `Insert yes` to customize connection parameters. Enter `MTU` and other connection parameters as directed on console instructions e.g. `MTU 512` for MTU and `conn 6 120 0 500 0 0` for connection parameters in sequence of `min conn_itvl`, `max conn_itvl`, `latency`, `supervision timeout`, `min conn_evt_len` and `max_conn_evt_len`. +* User will be now presented with throughput test related console prints, this suggests application is now ready to be run throughput test for user defined time. The prints may appear like below + +``` + ================================================================== + | Steps to test nimble throughput | + | | + | 1. Enter throughput [--Type] [--Test time] | + | Type: read/write/notify. | + | Test time: Enter value in seconds. | + | | + | e.g. throughput read 600 | + | | + | ** Enter 'throughput read 60' for reading char for 60 seconds | + | OR 'throughput write 60' for writing to char for 60 seconds | + | OR 'throughput notify 60' for notifications (for 60 seconds)**| + | | + ================================================================= + +``` +* If user fail to enter any values for next 30 seconds, the app falls to default behavior of READ for 60 seconds mode. +* Read and write throughput numbers will be presented in `blecent_throughput` console output. For notification `bleprph_throughput` console shall be referred, as the peripheral is the one who is sending notifications. Below is the sample output of the app: + +``` +Type 'help' to get the list of commands. +Use UP/DOWN arrows to navigate through command history. +Press TAB when typing command name to auto-complete. +I (1123) CLI: BLE CLI registered +I (1123) blecent_throughput: BLE Host Task Started + + =============================================================================================== + | Steps to test nimble throughput | + | | + | 1. Print 'help' to gain overview of commands | + | | +I (1163) blecent_throughput: Do you want to configure connection params ? +I (1183) blecent_throughput: If yes then enter in this format: `Insert Yes` + + =============================================================================================== +Throughput demo >> GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever +I (6213) blecent_throughput: Event DISC +I (6213) blecent_throughput: connect; fields.num_uuids128 =0 +I (6223) blecent_throughput: central connect to `nimble_prph` success +GAP procedure initiated: connect; peer_addr_type=1 peer_addr=14:58:11:c1:d0:2d scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=0 max_ce_len=0 own_addr_type=0 +E (36243) blecent_throughput: Error: Connection failed; status = 13 +GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever +I (36293) blecent_throughput: Event DISC +I (36293) blecent_throughput: connect; fields.num_uuids128 =0 +I (36293) blecent_throughput: Name = nimble_prph +ל�j6�^n���� +I (36303) blecent_throughput: central connect to `nimble_prph` success +GAP procedure initiated: connect; peer_addr_type=0 peer_addr=84:0d:8e:e6:83:de scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=0 max_ce_len=0 own_addr_type=0 +I (36393) blecent_throughput: Connection established +GATT procedure initiated: exchange mtu +GAP procedure initiated: connection parameter update; conn_handle=0 itvl_min=6 itvl_max=6 latency=0 supervision_timeout=500 min_ce_len=8 max_ce_len=768 +GATT procedure initiated: discover all services +I (36783) blecent_throughput: mtu update event; conn_handle = 0 cid = 4 mtu = 512 +GATT procedure initiated: discover all characteristics; start_handle=1 end_handle=5 +GATT procedure initiated: discover all characteristics; start_handle=6 end_handle=9 +GATT procedure initiated: discover all characteristics; start_handle=10 end_handle=65535 +GATT procedure initiated: discover all descriptors; chr_val_handle=8 end_handle=9 +GATT procedure initiated: discover all descriptors; chr_val_handle=14 end_handle=15 +GATT procedure initiated: discover all descriptors; chr_val_handle=17 end_handle=65535 +I (36933) blecent_throughput: Service discovery complete; status=0 conn_handle=0 + +I (36933) blecent_throughput: Format for throughput demo:: throughput read 100 + ================================================================== + | Steps to test nimble throughput | + | | + | 1. Enter throughput [--Type] [--Test time] | + | Type: read/write/notify. | + | Test time: Enter value in seconds. | + | | + | e.g. throughput read 600 | + | | + | ** Enter 'throughput read 60' for reading char for 60 seconds | + | OR 'throughput write 60' for writing to char for 60 seconds | + | OR 'throughput notify 60' for notifications (for 60 seconds)**| + | | + ================================================================= + +Throughput demo >> throughput read 10 +I (55333) Throughput demo handler: throughput read 10 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +Throughput demo >> GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +``` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example scope + +This demo example tries to demonstrate stable implementation of GATT operations like read/write and notify. The READ and WRITE GATT operations require ACK from peer, so this central app makes sure that next GATT operation is performed after completion of previous one. In case of notification (`bleprph_throughput` sends) operation there is no waiting for ACK, however one needs to mind `os_mbufs` getting full, so one may need to allocate higher number of mbufs through menuconfig. + +## Example output + +The `Procedure to use this demo example` section above covers initial console outputs. In this section we provide final console output depicting throughput numbers + +``` +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 +GATT procedure initiated: read; att_handle=17 + +**************************************************************** +I (65363) blecent_throughput: Application Read throughput = 106800 bps, Read op counter = 268 + +**************************************************************** + +``` diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/CMakeLists.txt b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/CMakeLists.txt new file mode 100644 index 000000000000..730bfff91608 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "cmd_system.c" + INCLUDE_DIRS "." + REQUIRES console spi_flash) diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/cmd_system.c b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/cmd_system.c new file mode 100644 index 000000000000..4fa3240b1cd8 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/cmd_system.c @@ -0,0 +1,336 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include +#include +#include "esp_log.h" +#include "esp_console.h" +#include "esp_system.h" +#include "esp_sleep.h" +#include "esp_spi_flash.h" +#include "driver/rtc_io.h" +#include "driver/uart.h" +#include "argtable3/argtable3.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "cmd_system.h" +#include "sdkconfig.h" + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define WITH_TASKS_INFO 1 +#endif + +static const char *TAG = "cmd_system"; + +static void register_free(void); +static void register_heap(void); +static void register_version(void); +static void register_restart(void); +static void register_deep_sleep(void); +static void register_light_sleep(void); +#if WITH_TASKS_INFO +static void register_tasks(void); +#endif + +void register_system(void) +{ + register_free(); + register_heap(); + register_version(); + register_restart(); + register_deep_sleep(); + register_light_sleep(); +#if WITH_TASKS_INFO + register_tasks(); +#endif +} + +/* 'version' command */ +static int get_version(int argc, char **argv) +{ + esp_chip_info_t info; + esp_chip_info(&info); + printf("IDF Version:%s\r\n", esp_get_idf_version()); + printf("Chip info:\r\n"); + printf("\tmodel:%s\r\n", info.model == CHIP_ESP32 ? "ESP32" : "Unknow"); + printf("\tcores:%d\r\n", info.cores); + printf("\tfeature:%s%s%s%s%d%s\r\n", + info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "", + info.features & CHIP_FEATURE_BLE ? "/BLE" : "", + info.features & CHIP_FEATURE_BT ? "/BT" : "", + info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:", + spi_flash_get_chip_size() / (1024 * 1024), " MB"); + printf("\trevision number:%d\r\n", info.revision); + return 0; +} + +static void register_version(void) +{ + const esp_console_cmd_t cmd = { + .command = "version", + .help = "Get version of chip and SDK", + .hint = NULL, + .func = &get_version, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} + +/** 'restart' command restarts the program */ + +static int restart(int argc, char **argv) +{ + ESP_LOGI(TAG, "Restarting"); + esp_restart(); +} + +static void register_restart(void) +{ + const esp_console_cmd_t cmd = { + .command = "restart", + .help = "Software reset of the chip", + .hint = NULL, + .func = &restart, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} + +/** 'free' command prints available heap memory */ + +static int free_mem(int argc, char **argv) +{ + printf("%d\n", esp_get_free_heap_size()); + return 0; +} + +static void register_free(void) +{ + const esp_console_cmd_t cmd = { + .command = "free", + .help = "Get the current size of free heap memory", + .hint = NULL, + .func = &free_mem, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} + +/* 'heap' command prints minumum heap size */ +static int heap_size(int argc, char **argv) +{ + uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT); + ESP_LOGI(TAG, "min heap size: %u", heap_size); + return 0; +} + +static void register_heap(void) +{ + const esp_console_cmd_t heap_cmd = { + .command = "heap", + .help = "Get minimum size of free heap memory that was available during program execution", + .hint = NULL, + .func = &heap_size, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) ); + +} + +/** 'tasks' command prints the list of tasks and related information */ +#if WITH_TASKS_INFO + +static int tasks_info(int argc, char **argv) +{ + const size_t bytes_per_task = 40; /* see vTaskList description */ + char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task); + if (task_list_buffer == NULL) { + ESP_LOGE(TAG, "failed to allocate buffer for vTaskList output"); + return 1; + } + fputs("Task Name\tStatus\tPrio\tHWM\tTask#", stdout); +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID + fputs("\tAffinity", stdout); +#endif + fputs("\n", stdout); + vTaskList(task_list_buffer); + fputs(task_list_buffer, stdout); + free(task_list_buffer); + return 0; +} + +static void register_tasks(void) +{ + const esp_console_cmd_t cmd = { + .command = "tasks", + .help = "Get information about running tasks", + .hint = NULL, + .func = &tasks_info, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} + +#endif // WITH_TASKS_INFO + +/** 'deep_sleep' command puts the chip into deep sleep mode */ + +static struct { + struct arg_int *wakeup_time; + struct arg_int *wakeup_gpio_num; + struct arg_int *wakeup_gpio_level; + struct arg_end *end; +} deep_sleep_args; + + +static int deep_sleep(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &deep_sleep_args); + if (nerrors != 0) { + arg_print_errors(stderr, deep_sleep_args.end, argv[0]); + return 1; + } + if (deep_sleep_args.wakeup_time->count) { + uint64_t timeout = 1000ULL * deep_sleep_args.wakeup_time->ival[0]; + ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout); + ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) ); + } + if (deep_sleep_args.wakeup_gpio_num->count) { + int io_num = deep_sleep_args.wakeup_gpio_num->ival[0]; + if (!rtc_gpio_is_valid_gpio(io_num)) { + ESP_LOGE(TAG, "GPIO %d is not an RTC IO", io_num); + return 1; + } + int level = 0; + if (deep_sleep_args.wakeup_gpio_level->count) { + level = deep_sleep_args.wakeup_gpio_level->ival[0]; + if (level != 0 && level != 1) { + ESP_LOGE(TAG, "Invalid wakeup level: %d", level); + return 1; + } + } + ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level", + io_num, level ? "HIGH" : "LOW"); + + ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) ); + } + rtc_gpio_isolate(GPIO_NUM_12); + esp_deep_sleep_start(); +} + +static void register_deep_sleep(void) +{ + deep_sleep_args.wakeup_time = + arg_int0("t", "time", "", "Wake up time, ms"); + deep_sleep_args.wakeup_gpio_num = + arg_int0(NULL, "io", "", + "If specified, wakeup using GPIO with given number"); + deep_sleep_args.wakeup_gpio_level = + arg_int0(NULL, "io_level", "<0|1>", "GPIO level to trigger wakeup"); + deep_sleep_args.end = arg_end(3); + + const esp_console_cmd_t cmd = { + .command = "deep_sleep", + .help = "Enter deep sleep mode. " + "Two wakeup modes are supported: timer and GPIO. " + "If no wakeup option is specified, will sleep indefinitely.", + .hint = NULL, + .func = &deep_sleep, + .argtable = &deep_sleep_args + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} + +/** 'light_sleep' command puts the chip into light sleep mode */ + +static struct { + struct arg_int *wakeup_time; + struct arg_int *wakeup_gpio_num; + struct arg_int *wakeup_gpio_level; + struct arg_end *end; +} light_sleep_args; + +static int light_sleep(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &light_sleep_args); + if (nerrors != 0) { + arg_print_errors(stderr, light_sleep_args.end, argv[0]); + return 1; + } + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); + if (light_sleep_args.wakeup_time->count) { + uint64_t timeout = 1000ULL * light_sleep_args.wakeup_time->ival[0]; + ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout); + ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) ); + } + int io_count = light_sleep_args.wakeup_gpio_num->count; + if (io_count != light_sleep_args.wakeup_gpio_level->count) { + ESP_LOGE(TAG, "Should have same number of 'io' and 'io_level' arguments"); + return 1; + } + for (int i = 0; i < io_count; ++i) { + int io_num = light_sleep_args.wakeup_gpio_num->ival[i]; + int level = light_sleep_args.wakeup_gpio_level->ival[i]; + if (level != 0 && level != 1) { + ESP_LOGE(TAG, "Invalid wakeup level: %d", level); + return 1; + } + ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level", + io_num, level ? "HIGH" : "LOW"); + + ESP_ERROR_CHECK( gpio_wakeup_enable(io_num, level ? GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL) ); + } + if (io_count > 0) { + ESP_ERROR_CHECK( esp_sleep_enable_gpio_wakeup() ); + } + if (CONFIG_ESP_CONSOLE_UART_NUM <= UART_NUM_1) { + ESP_LOGI(TAG, "Enabling UART wakeup (press ENTER to exit light sleep)"); + ESP_ERROR_CHECK( uart_set_wakeup_threshold(CONFIG_ESP_CONSOLE_UART_NUM, 3) ); + ESP_ERROR_CHECK( esp_sleep_enable_uart_wakeup(CONFIG_ESP_CONSOLE_UART_NUM) ); + } + fflush(stdout); + uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); + esp_light_sleep_start(); + esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + const char *cause_str; + switch (cause) { + case ESP_SLEEP_WAKEUP_GPIO: + cause_str = "GPIO"; + break; + case ESP_SLEEP_WAKEUP_UART: + cause_str = "UART"; + break; + case ESP_SLEEP_WAKEUP_TIMER: + cause_str = "timer"; + break; + default: + cause_str = "unknown"; + printf("%d\n", cause); + } + ESP_LOGI(TAG, "Woke up from: %s", cause_str); + return 0; +} + +static void register_light_sleep(void) +{ + light_sleep_args.wakeup_time = + arg_int0("t", "time", "", "Wake up time, ms"); + light_sleep_args.wakeup_gpio_num = + arg_intn(NULL, "io", "", 0, 8, + "If specified, wakeup using GPIO with given number"); + light_sleep_args.wakeup_gpio_level = + arg_intn(NULL, "io_level", "<0|1>", 0, 8, "GPIO level to trigger wakeup"); + light_sleep_args.end = arg_end(3); + + const esp_console_cmd_t cmd = { + .command = "light_sleep", + .help = "Enter light sleep mode. " + "Two wakeup modes are supported: timer and GPIO. " + "Multiple GPIO pins can be specified using pairs of " + "'io' and 'io_level' arguments. " + "Will also wake up on UART input.", + .hint = NULL, + .func = &light_sleep, + .argtable = &light_sleep_args + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/cmd_system.h b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/cmd_system.h new file mode 100644 index 000000000000..96bf93b71bc0 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/cmd_system.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// Register system functions +void register_system(void); + +#ifdef __cplusplus +} +#endif diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/component.mk b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/component.mk new file mode 100644 index 000000000000..e0e9f4c128a7 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/components/cmd_system/component.mk @@ -0,0 +1,10 @@ +# +# Component Makefile +# +# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, +# this will take the sources in the src/ directory, compile them and link them into +# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, +# please read the SDK documents if you need to do this. +# + +COMPONENT_ADD_INCLUDEDIRS := . diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/CMakeLists.txt b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/CMakeLists.txt new file mode 100644 index 000000000000..7488f906a10e --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" "misc.c" "peer.c" "scli.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/Kconfig.projbuild b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/Kconfig.projbuild new file mode 100644 index 000000000000..f82a600bcf82 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/Kconfig.projbuild @@ -0,0 +1,44 @@ +menu "Example Configuration" + + config EXAMPLE_PEER_ADDR + string "Peer Address" + default "ADDR_ANY" + help + Enter the peer address in aa:bb:cc:dd:ee:ff form to connect to a specific peripheral + + config EXAMPLE_CONN_ITVL_MIN + int "Minimum connection itvl" + default 6 + help + Set the minimum connection interval in 1.25msec units. + + config EXAMPLE_CONN_ITVL_MAX + int "Maximum connection itvl" + default 6 + help + Set the maximum connection interval in 1.25msec units. + + config EXAMPLE_CONN_LATENCY + int "Connection latency" + default 0 + help + Set the connection latency. + + config EXAMPLE_CONN_TIMEOUT + int "Supervision timeout" + default 500 + help + Set the supervision timeout in 10msec units. + + config EXAMPLE_CONN_CE_LEN_MIN + int "Minimum connection event length" + default 12 + help + Set the minimum connection event length in 0.625msec units. + + config EXAMPLE_CONN_CE_LEN_MAX + int "Maximum connection event length" + default 12 + help + Set the maximum connection event length in 0.625msec units. +endmenu diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/component.mk b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/component.mk new file mode 100644 index 000000000000..a98f634eae06 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/gattc.h b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/gattc.h new file mode 100644 index 000000000000..998349812300 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/gattc.h @@ -0,0 +1,109 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLECENT_ +#define H_BLECENT_ + +#pragma once + +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_adv_fields; +struct ble_gap_conn_desc; +struct ble_hs_cfg; +union ble_store_value; +union ble_store_key; + +#define BLECENT_SVC_ALERT_UUID 0x1811 +#define BLECENT_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define BLECENT_CHR_NEW_ALERT 0x2A46 +#define BLECENT_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define BLECENT_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define BLECENT_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_mbuf(const struct os_mbuf *om); +char *addr_str(const void *addr); +void print_uuid(const ble_uuid_t *uuid); +void print_conn_desc(const struct ble_gap_conn_desc *desc); +void print_adv_fields(const struct ble_hs_adv_fields *fields); + +/** Peer. */ +struct peer_dsc { + SLIST_ENTRY(peer_dsc) next; + struct ble_gatt_dsc dsc; +}; +SLIST_HEAD(peer_dsc_list, peer_dsc); + +struct peer_chr { + SLIST_ENTRY(peer_chr) next; + struct ble_gatt_chr chr; + + struct peer_dsc_list dscs; +}; +SLIST_HEAD(peer_chr_list, peer_chr); + +struct peer_svc { + SLIST_ENTRY(peer_svc) next; + struct ble_gatt_svc svc; + + struct peer_chr_list chrs; +}; +SLIST_HEAD(peer_svc_list, peer_svc); + +struct peer; +typedef void peer_disc_fn(const struct peer *peer, int status, void *arg); + +struct peer { + SLIST_ENTRY(peer) next; + + uint16_t conn_handle; + + /** List of discovered GATT services. */ + struct peer_svc_list svcs; + + /** Keeps track of where we are in the service discovery process. */ + uint16_t disc_prev_chr_val; + struct peer_svc *cur_svc; + + /** Callback that gets executed when service discovery completes. */ + peer_disc_fn *disc_cb; + void *disc_cb_arg; +}; + +int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, + void *disc_cb_arg); +const struct peer_dsc * +peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid); +const struct peer_chr * +peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid); +const struct peer_svc * +peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid); +int peer_delete(uint16_t conn_handle); +int peer_add(uint16_t conn_handle); +int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs); +struct peer * +peer_find(uint16_t conn_handle); +/* Console */ +int scli_init(void); +void ble_register_cli(void); +int scli_receive_key(int *key); +int cli_receive_key(int *key); +int scli_receive_yesno(bool *key); +void scli_reset_queue(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c new file mode 100644 index 000000000000..b1e8f753116a --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c @@ -0,0 +1,796 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "gattc.h" +#include "esp_timer.h" +#include "linenoise/linenoise.h" +#include "esp_console.h" +#include "driver/uart.h" +#include "esp_vfs_dev.h" +#include "argtable3/argtable3.h" +#include "cmd_system.h" +#include "../src/ble_hs_hci_priv.h" + +/* 0000xxxx-8c26-476f-89a7-a108033a69c7 */ +#define THRPT_UUID_DECLARE(uuid16) \ + ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT( \ + 0xc7, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ + 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ + ))) + +/* 0000xxxx-8c26-476f-89a7-a108033a69c6 */ +#define THRPT_UUID_DECLARE_ALT(uuid16) \ + ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT( \ + 0xc6, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ + 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ + ))) + +#define THRPT_SVC 0x0001 +#define THRPT_CHR_READ_WRITE 0x0006 +#define THRPT_CHR_NOTIFY 0x000a +#define THRPT_LONG_CHR_READ_WRITE 0x000b +#define THRPT_LONG_CHR_READ_WRITE_ALT 0x001a +#define THRPT_CHR_READ_WRITE_ALT 0x001f + +/* Throughput cases */ +#define READ_THROUGHPUT 1 +#define WRITE_THROUGHPUT 2 +#define NOTIFY_THROUGHPUT 3 + +#define READ_THROUGHPUT_PAYLOAD 500 +#define WRITE_THROUGHPUT_PAYLOAD 500 +#define LL_PACKET_TIME 2120 +#define LL_PACKET_LENGTH 251 +static const char *tag = "blecent_throughput"; +static int blecent_gap_event(struct ble_gap_event *event, void *arg); +static uint8_t peer_addr[6]; +static SemaphoreHandle_t xSemaphore; +static int mbuf_len_total; +static int failure_count; +static int conn_params_def[] = {40, 40, 0, 500, 80, 80}; +static struct ble_gap_upd_params conn_params = { + /** Minimum value for connection interval in 1.25ms units */ + .itvl_min = CONFIG_EXAMPLE_CONN_ITVL_MIN, + /** Maximum value for connection interval in 1.25ms units */ + .itvl_max = CONFIG_EXAMPLE_CONN_ITVL_MAX, + /** Connection latency */ + .latency = CONFIG_EXAMPLE_CONN_LATENCY, + /** Supervision timeout in 10ms units */ + .supervision_timeout = CONFIG_EXAMPLE_CONN_TIMEOUT, + /** Minimum length of connection event in 0.625ms units */ + .min_ce_len = CONFIG_EXAMPLE_CONN_CE_LEN_MIN, + /** Maximum length of connection event in 0.625ms units */ + .max_ce_len = CONFIG_EXAMPLE_CONN_CE_LEN_MAX, +}; + +static int mtu_def = 512; +/* test_data accepts test_name and test_time from CLI */ +static int test_data[] = {1, 600}; +void ble_store_config_init(void); + +static int +blecent_notify(uint16_t conn_handle, uint16_t val_handle, + ble_gatt_attr_fn *cb, struct peer *peer, int test_time) +{ + uint8_t value[2] = {1, 0};/*To subscribe to notifications*/ + int rc; + + rc = ble_gattc_write_flat(conn_handle, val_handle, + value, sizeof value, NULL, &test_time); + if (rc != 0) { + ESP_LOGE(tag, "Error: Failed to subscribe to characteristic; " + "rc = %d", rc); + goto err; + } + + return 0; +err: + /* Terminate the connection. */ + return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +static int blecent_write(uint16_t conn_handle, uint16_t val_handle, + struct peer *peer, int test_time) +{ + int64_t start_time, end_time, write_time = 0; + int write_count = 0; + uint8_t value[WRITE_THROUGHPUT_PAYLOAD] = {0}; + int rc; + + value[0] = rand(); + failure_count = 0; + start_time = esp_timer_get_time(); + + while (write_time < test_time * 1000) { + /* Wait till the previous write is complete. For first time Semaphore + * is already available */ + label: + rc = ble_gattc_write_no_rsp_flat(conn_handle, val_handle, &value, sizeof value); + + if(rc == BLE_HS_ENOMEM) { + vTaskDelay(2); /* Wait for buffers to free up and try again */ + goto label; + } + else if (rc != 0) { + ESP_LOGE(tag, "Error: Failed to write characteristic; rc=%d\n",rc); + goto err; + } + + end_time = esp_timer_get_time(); + write_time = (end_time - start_time) / 1000 ; + write_count += 1; + } + + /* Each successful write is of WRITE_THROUGHPUT_PAYLOAD Bytes of + * application data. */ + printf("\n****************************************************************\n"); + ESP_LOGI(tag, "Application Write throughput = %d bps, write count = %d," + "failure count = %d", + ((write_count - failure_count) * 8 * WRITE_THROUGHPUT_PAYLOAD) / test_time, + write_count, failure_count); + printf("\n****************************************************************\n"); + + return 0; +err: + /* Terminate the connection. */ + return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +static int +blecent_repeat_read(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + if (error->status == 0) { + xSemaphoreGive(xSemaphore); + ESP_LOGD(tag, " attr_handle=%d value=", attr->handle); + mbuf_len_total += OS_MBUF_PKTLEN(attr->om); + } else { + ESP_LOGE(tag, " Read failed, callback error code = %d", error->status ); + xSemaphoreGive(xSemaphore); + } + return error->status; +} + +static int blecent_read(uint16_t conn_handle, uint16_t val_handle, + ble_gatt_attr_fn *cb, struct peer *peer, int test_time) +{ + int rc, read_count = 0; + int64_t start_time, end_time, read_time = 0; + /* Keep track of number of bytes read from char */ + mbuf_len_total = 0; + start_time = esp_timer_get_time(); + + ESP_LOGD(tag, " Throughput read started :val_handle=%d test_time=%d", val_handle, + test_time); + + while (read_time < (test_time * 1000)) { + /* Wait till the previous read is complete. For first time use Semaphore + * is already available */ + xSemaphoreTake(xSemaphore, portMAX_DELAY); + + rc = ble_gattc_read(peer->conn_handle, val_handle, + blecent_repeat_read, (void *) &peer); + if (rc != 0) { + ESP_LOGE(tag, "Error: Failed to read characteristic; rc=%d", + rc); + goto err; + } + + end_time = esp_timer_get_time(); + read_time = (end_time - start_time) / 1000 ; + read_count += 1; + } + + /* Application data throughput */ + printf("\n****************************************************************\n"); + ESP_LOGI(tag, "Application Read throughput = %d bps, Read op counter = %d", + (mbuf_len_total * 8) / (test_time), read_count); + printf("\n****************************************************************\n"); + return 0; + +err: + /* Terminate the connection. */ + vTaskDelay(100 / portTICK_PERIOD_MS); + return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +static void throughput_task(void *arg) +{ + struct peer *peer = (struct peer *)arg; + const struct peer_chr *chr; + const struct peer_dsc *dsc; + int rc = 0; + + while (1) { + vTaskDelay(4000 / portTICK_PERIOD_MS); + ESP_LOGI(tag, "Format for throughput demo:: throughput read 100"); + printf(" ==================================================================\n"); + printf(" | Steps to test nimble throughput |\n"); + printf(" | |\n"); + printf(" | 1. Enter throughput [--Type] [--Test time] |\n"); + printf(" | Type: read/write/notify. |\n"); + printf(" | Test time: Enter value in seconds. |\n"); + printf(" | |\n"); + printf(" | e.g. throughput read 600 |\n"); + printf(" | |\n"); + printf(" | ** Enter 'throughput read 60' for reading char for 60 seconds |\n"); + printf(" | OR 'throughput write 60' for writing to char for 60 seconds |\n"); + printf(" | OR 'throughput notify 60' for notifications (for 60 seconds)**|\n"); + printf(" | |\n"); + printf(" =================================================================\n\n"); + /* XXX Delay ? */ + vTaskDelay(1000 / portTICK_PERIOD_MS); + + if (!cli_receive_key(test_data)) { + /* No command supplied, start with reading */ + test_data[0] = READ_THROUGHPUT; + test_data[1] = 60; + ESP_LOGI(tag, "No command received from user, start with READ op" + " with 60 seconds test time"); + } + scli_reset_queue(); + + switch (test_data[0]) { + + case READ_THROUGHPUT: + /* Read the characteristic supporting long read support + * `THRPT_LONG_CHR_READ_WRITE` (0x000b) */ + chr = peer_chr_find_uuid(peer, + THRPT_UUID_DECLARE(THRPT_SVC), + THRPT_UUID_DECLARE(THRPT_LONG_CHR_READ_WRITE)); + if (chr == NULL) { + ESP_LOGE(tag, "Peer does not support " + "LONG_READ (0x000b) characteristic "); + break; + } + + if (test_data[1] > 0) { + rc = blecent_read(peer->conn_handle, chr->chr.val_handle, + blecent_repeat_read, (void *) peer, test_data[1]); + if (rc != 0) { + ESP_LOGE(tag, "Error while reading from GATTS; rc = %d", rc); + } + } else { + ESP_LOGE(tag, "Please enter non-zero value for test time in seconds!!"); + } + break; + + case WRITE_THROUGHPUT: + chr = peer_chr_find_uuid(peer, + THRPT_UUID_DECLARE(THRPT_SVC), + THRPT_UUID_DECLARE(THRPT_CHR_READ_WRITE)); + if (chr == NULL) { + ESP_LOGE(tag, "Error: Peer doesn't support the READ " + "WRITE characteristic (0x0006) "); + break; + } + + if (test_data[1] > 0) { + rc = blecent_write(peer->conn_handle, chr->chr.val_handle, (void *) peer, test_data[1]); + if (rc != 0) { + ESP_LOGE(tag, "Error while writing data; rc = %d", rc); + } + } else { + ESP_LOGE(tag, "Please enter non-zero value for test time in seconds!!"); + } + break; + + case NOTIFY_THROUGHPUT: + chr = peer_chr_find_uuid(peer, + THRPT_UUID_DECLARE(THRPT_SVC), + THRPT_UUID_DECLARE(THRPT_CHR_NOTIFY)); + if (chr == NULL) { + ESP_LOGE(tag, "Error: Peer doesn't support the NOTIFY " + "characteristic (0x000a) "); + break; + } + dsc = peer_dsc_find_uuid(peer, + THRPT_UUID_DECLARE(THRPT_SVC), + THRPT_UUID_DECLARE(THRPT_CHR_NOTIFY), + BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16)); + if (dsc == NULL) { + ESP_LOGE(tag, "Error: Peer lacks a CCCD for the Notify " + "Status characteristic\n"); + break; + } + + rc = blecent_notify(peer->conn_handle, dsc->dsc.handle, + NULL, (void *) peer, test_data[1]); + if (rc != 0) { + ESP_LOGE(tag, "Subscribing to notification failed; rc = %d ", rc); + } else { + ESP_LOGI(tag, "Subscribed to notifications. Throughput number" + " can be seen on peripheral terminal after %d seconds", + test_data[1]); + } + vTaskDelay(test_data[1]*1000 / portTICK_PERIOD_MS); + break; + + default: + break; + } + + vTaskDelay(5000 / portTICK_PERIOD_MS); + } + vTaskDelete(NULL); +} + +static void +blecent_read_write_subscribe(const struct peer *peer) +{ + xTaskCreate(throughput_task, "throughput_task", 4096, (void *) peer, 10, NULL); + return; +} + +/** + * Called when service discovery of the specified peer has completed. + */ +static void +blecent_on_disc_complete(const struct peer *peer, int status, void *arg) +{ + + if (status != 0) { + /* Service discovery failed. Terminate the connection. */ + ESP_LOGE(tag, "Error: Service discovery failed; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); + return; + } + + /* Service discovery has completed successfully. Now we have a complete + * list of services, characteristics, and descriptors that the peer + * supports. + */ + ESP_LOGI(tag, "Service discovery complete; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + + /* Now perform three GATT procedures against the peer: read, + * write, and subscribe to notifications depending upon user input. + */ + blecent_read_write_subscribe(peer); +} + +/** + * Initiates the GAP general discovery procedure. + */ +static void +blecent_scan(void) +{ + uint8_t own_addr_type; + struct ble_gap_disc_params disc_params; + int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(tag, "error determining address type; rc=%d", rc); + return; + } + + /* Tell the controller to filter duplicates; we don't want to process + * repeated advertisements from the same device. + */ + disc_params.filter_duplicates = 1; + + /** + * Perform a passive scan. I.e., don't send follow-up scan requests to + * each advertiser. + */ + disc_params.passive = 1; + + /* Use defaults for the rest of the parameters. */ + disc_params.itvl = 0; + disc_params.window = 0; + disc_params.filter_policy = 0; + disc_params.limited = 0; + + rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, + blecent_gap_event, NULL); + if (rc != 0) { + ESP_LOGE(tag, "Error initiating GAP discovery procedure; rc=%d\n", + rc); + } +} + +/** + * Indicates whether we should try to connect to the sender of the specified + * advertisement. The function returns a positive result if the device + * advertises connectability and support for the THRPT service i.e. 0x0001. + */ +static int +blecent_should_connect(const struct ble_gap_disc_desc *disc) +{ + struct ble_hs_adv_fields fields; + int rc; + int i; + + rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data); + if (rc != 0) { + return rc; + } + + if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) { + ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR); + /* Convert string to address */ + sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &peer_addr[5], &peer_addr[4], &peer_addr[3], + &peer_addr[2], &peer_addr[1], &peer_addr[0]); + if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { + return 0; + } + } + + ESP_LOGI(tag, "connect; fields.num_uuids128 =%d", fields.num_uuids128); + for (i = 0; i < fields.num_uuids128; i++) { + if ((memcmp(&fields.uuids128[i], THRPT_UUID_DECLARE(THRPT_SVC), + sizeof(ble_uuid128_t))) == 0 ) { + ESP_LOGI(tag, "blecent_should_connect 'THRPT' success"); + return 1; + } + } + + char serv_name[] = "nimble_prph"; + if (fields.name != NULL) { + ESP_LOGI(tag, "Device Name = %s", (char *)fields.name); + + if (memcmp(fields.name, serv_name, fields.name_len) == 0) { + ESP_LOGI(tag, "central connect to `nimble_prph` success"); + return 1; + } + } + return 0; +} + +/** + * Connects to the sender of the specified advertisement of it looks + * interesting. A device is "interesting" if it advertises connectability and + * support for the Alert Notification service. + */ +static void +blecent_connect_if_interesting(const struct ble_gap_disc_desc *disc) +{ + uint8_t own_addr_type; + int rc; + + /* Don't do anything if we don't care about this advertiser. */ + if (!blecent_should_connect(disc)) { + return; + } + + /* Scanning must be stopped before a connection can be initiated. */ + rc = ble_gap_disc_cancel(); + if (rc != 0) { + MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); + return; + } + + /* Figure out address to use for connect (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(tag, "error determining address type; rc=%d\n", rc); + return; + } + + /* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for + * timeout. + */ + rc = ble_gap_connect(own_addr_type, &disc->addr, 30000, NULL, + blecent_gap_event, NULL); + if (rc != 0) { + ESP_LOGE(tag, "Error: Failed to connect to device; addr_type=%d " + "addr=%s; rc=%d\n", + disc->addr.type, addr_str(disc->addr.val), rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that is + * established. central uses the same callback for all connections. + * + * @param event The event being signalled. + * @param arg Application-specified argument; unused by + * gattc. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +blecent_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + struct ble_hs_adv_fields fields; + int rc; + + + switch (event->type) { + case BLE_GAP_EVENT_DISC: + ESP_LOGI(tag, "Event DISC "); + rc = ble_hs_adv_parse_fields(&fields, event->disc.data, + event->disc.length_data); + if (rc != 0) { + return 0; + } + + /* An advertisment report was received during GAP discovery. */ + print_adv_fields(&fields); + + /* Try to connect to the advertiser if it looks interesting. */ + blecent_connect_if_interesting(&event->disc); + return 0; + + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + if (event->connect.status == 0) { + /* Connection successfully established. */ + /* XXX Set packet length in controller for better throughput */ + ESP_LOGI(tag, "Connection established "); + rc = ble_hs_hci_util_set_data_len(event->connect.conn_handle, + LL_PACKET_LENGTH, LL_PACKET_TIME); + if (rc != 0) { + ESP_LOGE(tag, "Set packet length failed; rc = %d", rc); + } + + rc = ble_att_set_preferred_mtu(mtu_def); + if (rc != 0) { + ESP_LOGE(tag, "Failed to set preferred MTU; rc = %d", rc); + } + + rc = ble_gattc_exchange_mtu(event->connect.conn_handle, NULL, NULL); + if (rc != 0) { + ESP_LOGE(tag, "Failed to negotiate MTU; rc = %d", rc); + } + + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + + rc = ble_gap_update_params(event->connect.conn_handle, &conn_params); + if (rc != 0) { + ESP_LOGE(tag, "Failed to update params; rc = %d", rc); + } + + /* Remember peer. */ + rc = peer_add(event->connect.conn_handle); + if (rc != 0) { + ESP_LOGE(tag, "Failed to add peer; rc = %d", rc); + return 0; + } + + /* Perform service discovery. */ + rc = peer_disc_all(event->connect.conn_handle, + blecent_on_disc_complete, NULL); + if (rc != 0) { + ESP_LOGE(tag, "Failed to discover services; rc = %d", rc); + return 0; + } + } else { + /* Connection attempt failed; resume scanning. */ + ESP_LOGE(tag, "Error: Connection failed; status = %d", + event->connect.status); + blecent_scan(); + } + + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + /* Connection terminated. */ + ESP_LOGI(tag, "disconnect; reason=%d ", event->disconnect.reason); + print_conn_desc(&event->disconnect.conn); + ESP_LOGI(tag, "\n"); + + /* Forget about peer. */ + peer_delete(event->disconnect.conn.conn_handle); + /* Resume scanning. */ + blecent_scan(); + return 0; + + case BLE_GAP_EVENT_DISC_COMPLETE: + ESP_LOGI(tag, "discovery complete; reason = %d", + event->disc_complete.reason); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + ESP_LOGI(tag, "encryption change event; status = %d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + return 0; + + case BLE_GAP_EVENT_NOTIFY_RX: + /* Peer sent us a notification or indication. */ + mbuf_len_total = mbuf_len_total + OS_MBUF_PKTLEN(event->notify_rx.om); + ESP_LOGI(tag, "received %s; conn_handle = %d attr_handle = %d " + "attr_len = %d ; Total length = %d", + event->notify_rx.indication ? + "indication" : + "notification", + event->notify_rx.conn_handle, + event->notify_rx.attr_handle, + OS_MBUF_PKTLEN(event->notify_rx.om), + mbuf_len_total); + /* Attribute data is contained in event->notify_rx.attr_data. */ + return 0; + + case BLE_GAP_EVENT_MTU: + ESP_LOGI(tag, "mtu update event; conn_handle = %d cid = %d mtu = %d", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + + default: + return 0; + } +} + +static void +blecent_on_reset(int reason) +{ + ESP_LOGE(tag, "Resetting state; reason=%d\n", reason); +} + +static void +blecent_on_sync(void) +{ + int rc; + bool yes = false; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + ESP_LOGI(tag, "Do you want to configure connection params ? "); + ESP_LOGI(tag, "If yes then enter in this format: `Insert Yes` "); + if (scli_receive_yesno(&yes)) { + if (yes) { + ESP_LOGI(tag, " Enter preferred MTU, format:: `MTU 512` "); + if (scli_receive_key(&mtu_def)) { + ESP_LOGI(tag, "MTU provided by user= %d", mtu_def); + } else { + ESP_LOGD(tag, "No input for setting MTU; use default mtu = %d", mtu_def); + } + + scli_reset_queue(); + ESP_LOGI(tag, "For Conn param: Enter `min_itvl` `max_itvl`" + "`latency` `timeout` `min_ce` `max_ce` in same order"); + ESP_LOGI(tag, "Enter conn_update in this format:: `conn 6 120 0 500 0 0`"); + + if (scli_receive_key(conn_params_def)) { + /** Minimum value for connection interval in 1.25ms units */ + conn_params.itvl_min = conn_params_def[0]; + /** Maximum value for connection interval in 1.25ms units */ + conn_params.itvl_max = conn_params_def[1]; + /** Connection latency */ + conn_params.latency = conn_params_def[2]; + /** Supervision timeout in 10ms units */ + conn_params.supervision_timeout = conn_params_def[3]; + /** Minimum length of connection event in 0.625ms units */ + conn_params.min_ce_len = conn_params_def[4]; + /** Maximum length of connection event in 0.625ms units */ + conn_params.max_ce_len = conn_params_def[5]; + + } else { + ESP_LOGD(tag, "no input by user for conn param; use default "); + } + scli_reset_queue(); + } + } + /* Begin scanning for a peripheral to connect to. */ + blecent_scan(); +} + +void blecent_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + xSemaphore = xSemaphoreCreateBinary(); + xSemaphoreGive(xSemaphore); + + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + vSemaphoreDelete(xSemaphore); + nimble_port_freertos_deinit(); +} + +void +app_main(void) +{ + int rc; + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + + /* Configure the host. */ + ble_hs_cfg.reset_cb = blecent_on_reset; + ble_hs_cfg.sync_cb = blecent_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Initialize data structures to track connected peers. */ + rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("gattc-throughput"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + /* Before starting with blecent host task, let us get CLI task up and + * running */ + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + esp_console_repl_t *repl = NULL; + repl_config.prompt = "Throughput : "; + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); + register_system(); + esp_console_register_help_command(); + /* Register commands */ + ble_register_cli(); + + /* As BLE CLI has been registered, let us start nimble host task */ + nimble_port_freertos_init(blecent_host_task); + + printf("\n ===============================================================================================\n"); + printf(" | Steps to test nimble throughput |\n"); + printf(" | |\n"); + printf(" | 1. Print 'help' to gain overview of commands |\n"); + printf(" | |\n"); + printf("\n ===============================================================================================\n"); + + const char *prompt = LOG_COLOR_I "Throughput demo >> " LOG_RESET_COLOR; + + while (true) { + /* Get a line using linenoise. + * The line is returned when ENTER is pressed. + */ + char *line = linenoise(prompt); + if (line == NULL) { /* Ignore empty lines */ + continue; + } + /* Add the command to the history */ + linenoiseHistoryAdd(line); + + /* Try to run the command */ + int ret; + esp_err_t err = esp_console_run(line, &ret); + if (err == ESP_ERR_NOT_FOUND) { + printf("Unrecognized command\n"); + } else if (err == ESP_ERR_INVALID_ARG) { + // command was empty + } else if (err == ESP_OK && ret != ESP_OK) { + printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret)); + } else if (err != ESP_OK) { + printf("Internal error: %s\n", esp_err_to_name(err)); + } + /* linenoise allocates line buffer on the heap, so need to free it */ + linenoiseFree(line); + } +} diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/misc.c b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/misc.c new file mode 100644 index 000000000000..b7d6997c736a --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/misc.c @@ -0,0 +1,198 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "gattc.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_mbuf(const struct os_mbuf *om) +{ + int colon, i; + + colon = 0; + while (om != NULL) { + if (colon) { + MODLOG_DFLT(INFO, ":"); + } else { + colon = 1; + } + for (i = 0; i < om->om_len; i++) { + MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", om->om_data[i]); + } + om = SLIST_NEXT(om, om_next); + } +} + +char * +addr_str(const void *addr) +{ + static char buf[6 * 2 + 5 + 1]; + const uint8_t *u8p; + + u8p = addr; + sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); + + return buf; +} + +void +print_uuid(const ble_uuid_t *uuid) +{ + char buf[BLE_UUID_STR_LEN]; + + MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf)); +} + +/** + * Logs information about a connection to the console. + */ +void +print_conn_desc(const struct ble_gap_conn_desc *desc) +{ + MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ", + desc->conn_handle, desc->our_ota_addr.type, + addr_str(desc->our_ota_addr.val)); + MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ", + desc->our_id_addr.type, addr_str(desc->our_id_addr.val)); + MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ", + desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val)); + MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ", + desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val)); + MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + + +void +print_adv_fields(const struct ble_hs_adv_fields *fields) +{ + char s[BLE_HS_ADV_MAX_SZ]; + const uint8_t *u8p; + int i; + + if (fields->flags != 0) { + MODLOG_DFLT(DEBUG, " flags=0x%02x\n", fields->flags); + } + + if (fields->uuids16 != NULL) { + MODLOG_DFLT(DEBUG, " uuids16(%scomplete)=", + fields->uuids16_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids16; i++) { + print_uuid(&fields->uuids16[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uuids32 != NULL) { + MODLOG_DFLT(DEBUG, " uuids32(%scomplete)=", + fields->uuids32_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids32; i++) { + print_uuid(&fields->uuids32[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uuids128 != NULL) { + MODLOG_DFLT(DEBUG, " uuids128(%scomplete)=", + fields->uuids128_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids128; i++) { + print_uuid(&fields->uuids128[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->name != NULL) { + assert(fields->name_len < sizeof s - 1); + memcpy(s, fields->name, fields->name_len); + s[fields->name_len] = '\0'; + MODLOG_DFLT(DEBUG, " name(%scomplete)=%s\n", + fields->name_is_complete ? "" : "in", s); + } + + if (fields->tx_pwr_lvl_is_present) { + MODLOG_DFLT(DEBUG, " tx_pwr_lvl=%d\n", fields->tx_pwr_lvl); + } + + if (fields->slave_itvl_range != NULL) { + MODLOG_DFLT(DEBUG, " slave_itvl_range="); + print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->svc_data_uuid16 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid16="); + print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->public_tgt_addr != NULL) { + MODLOG_DFLT(DEBUG, " public_tgt_addr="); + u8p = fields->public_tgt_addr; + for (i = 0; i < fields->num_public_tgt_addrs; i++) { + MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p)); + u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->appearance_is_present) { + MODLOG_DFLT(DEBUG, " appearance=0x%04x\n", fields->appearance); + } + + if (fields->adv_itvl_is_present) { + MODLOG_DFLT(DEBUG, " adv_itvl=0x%04x\n", fields->adv_itvl); + } + + if (fields->svc_data_uuid32 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid32="); + print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->svc_data_uuid128 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid128="); + print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uri != NULL) { + MODLOG_DFLT(DEBUG, " uri="); + print_bytes(fields->uri, fields->uri_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->mfg_data != NULL) { + MODLOG_DFLT(DEBUG, " mfg_data="); + print_bytes(fields->mfg_data, fields->mfg_data_len); + MODLOG_DFLT(DEBUG, "\n"); + } +} diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/peer.c b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/peer.c new file mode 100644 index 000000000000..e7e655cd1f7d --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/peer.c @@ -0,0 +1,795 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "host/ble_hs.h" +#include "gattc.h" + +static void *peer_svc_mem; +static struct os_mempool peer_svc_pool; + +static void *peer_chr_mem; +static struct os_mempool peer_chr_pool; + +static void *peer_dsc_mem; +static struct os_mempool peer_dsc_pool; + +static void *peer_mem; +static struct os_mempool peer_pool; +static SLIST_HEAD(, peer) peers; + +static struct peer_svc * +peer_svc_find_range(struct peer *peer, uint16_t attr_handle); +static struct peer_svc * +peer_svc_find(struct peer *peer, uint16_t svc_start_handle, + struct peer_svc **out_prev); +int +peer_svc_is_empty(const struct peer_svc *svc); + +uint16_t +chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr); +int +chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr); +static struct peer_chr * +peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle, + struct peer_chr **out_prev); +static void +peer_disc_chrs(struct peer *peer); + +static int +peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg); + +struct peer * +peer_find(uint16_t conn_handle) +{ + struct peer *peer; + + SLIST_FOREACH(peer, &peers, next) { + if (peer->conn_handle == conn_handle) { + return peer; + } + } + + return NULL; +} + +static void +peer_disc_complete(struct peer *peer, int rc) +{ + peer->disc_prev_chr_val = 0; + + /* Notify caller that discovery has completed. */ + if (peer->disc_cb != NULL) { + peer->disc_cb(peer, rc, peer->disc_cb_arg); + } +} + +static struct peer_dsc * +peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle) +{ + struct peer_dsc *prev; + struct peer_dsc *dsc; + + prev = NULL; + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (dsc->dsc.handle >= dsc_handle) { + break; + } + + prev = dsc; + } + + return prev; +} + +static struct peer_dsc * +peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle, + struct peer_dsc **out_prev) +{ + struct peer_dsc *prev; + struct peer_dsc *dsc; + + prev = peer_dsc_find_prev(chr, dsc_handle); + if (prev == NULL) { + dsc = SLIST_FIRST(&chr->dscs); + } else { + dsc = SLIST_NEXT(prev, next); + } + + if (dsc != NULL && dsc->dsc.handle != dsc_handle) { + dsc = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return dsc; +} + +static int +peer_dsc_add(struct peer *peer, uint16_t chr_val_handle, + const struct ble_gatt_dsc *gatt_dsc) +{ + struct peer_dsc *prev; + struct peer_dsc *dsc; + struct peer_svc *svc; + struct peer_chr *chr; + + svc = peer_svc_find_range(peer, chr_val_handle); + if (svc == NULL) { + /* Can't find service for discovered descriptor; this shouldn't + * happen. + */ + assert(0); + return BLE_HS_EUNKNOWN; + } + + chr = peer_chr_find(svc, chr_val_handle, NULL); + if (chr == NULL) { + /* Can't find characteristic for discovered descriptor; this shouldn't + * happen. + */ + assert(0); + return BLE_HS_EUNKNOWN; + } + + dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev); + if (dsc != NULL) { + /* Descriptor already discovered. */ + return 0; + } + + dsc = os_memblock_get(&peer_dsc_pool); + if (dsc == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + memset(dsc, 0, sizeof * dsc); + + dsc->dsc = *gatt_dsc; + + if (prev == NULL) { + SLIST_INSERT_HEAD(&chr->dscs, dsc, next); + } else { + SLIST_NEXT(prev, next) = dsc; + } + + return 0; +} + +static void +peer_disc_dscs(struct peer *peer) +{ + struct peer_chr *chr; + struct peer_svc *svc; + int rc; + + /* Search through the list of discovered characteristics for the first + * characteristic that contains undiscovered descriptors. Then, discover + * all descriptors belonging to that characteristic. + */ + SLIST_FOREACH(svc, &peer->svcs, next) { + SLIST_FOREACH(chr, &svc->chrs, next) { + if (!chr_is_empty(svc, chr) && + SLIST_EMPTY(&chr->dscs) && + peer->disc_prev_chr_val <= chr->chr.def_handle) { + + rc = ble_gattc_disc_all_dscs(peer->conn_handle, + chr->chr.val_handle, + chr_end_handle(svc, chr), + peer_dsc_disced, peer); + if (rc != 0) { + peer_disc_complete(peer, rc); + } + + peer->disc_prev_chr_val = chr->chr.val_handle; + return; + } + } + } + + /* All descriptors discovered. */ + peer_disc_complete(peer, 0); +} + +static int +peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg) +{ + struct peer *peer; + int rc; + + peer = arg; + assert(peer->conn_handle == conn_handle); + + switch (error->status) { + case 0: + rc = peer_dsc_add(peer, chr_val_handle, dsc); + break; + + case BLE_HS_EDONE: + /* All descriptors in this characteristic discovered; start discovering + * descriptors in the next characteristic. + */ + if (peer->disc_prev_chr_val > 0) { + peer_disc_dscs(peer); + } + rc = 0; + break; + + default: + /* Error; abort discovery. */ + rc = error->status; + break; + } + + if (rc != 0) { + /* Error; abort discovery. */ + peer_disc_complete(peer, rc); + } + + return rc; +} + +uint16_t +chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr) +{ + const struct peer_chr *next_chr; + + next_chr = SLIST_NEXT(chr, next); + if (next_chr != NULL) { + return next_chr->chr.def_handle - 1; + } else { + return svc->svc.end_handle; + } +} + +int +chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr) +{ + return chr_end_handle(svc, chr) <= chr->chr.val_handle; +} + +static struct peer_chr * +peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle) +{ + struct peer_chr *prev; + struct peer_chr *chr; + + prev = NULL; + SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle >= chr_val_handle) { + break; + } + + prev = chr; + } + + return prev; +} + +static struct peer_chr * +peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle, + struct peer_chr **out_prev) +{ + struct peer_chr *prev; + struct peer_chr *chr; + + prev = peer_chr_find_prev(svc, chr_val_handle); + if (prev == NULL) { + chr = SLIST_FIRST(&svc->chrs); + } else { + chr = SLIST_NEXT(prev, next); + } + + if (chr != NULL && chr->chr.val_handle != chr_val_handle) { + chr = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return chr; +} + +static void +peer_chr_delete(struct peer_chr *chr) +{ + struct peer_dsc *dsc; + + while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) { + SLIST_REMOVE_HEAD(&chr->dscs, next); + os_memblock_put(&peer_dsc_pool, dsc); + } + + os_memblock_put(&peer_chr_pool, chr); +} + +static int +peer_chr_add(struct peer *peer, uint16_t svc_start_handle, + const struct ble_gatt_chr *gatt_chr) +{ + struct peer_chr *prev; + struct peer_chr *chr; + struct peer_svc *svc; + + svc = peer_svc_find(peer, svc_start_handle, NULL); + if (svc == NULL) { + /* Can't find service for discovered characteristic; this shouldn't + * happen. + */ + assert(0); + return BLE_HS_EUNKNOWN; + } + + chr = peer_chr_find(svc, gatt_chr->def_handle, &prev); + if (chr != NULL) { + /* Characteristic already discovered. */ + return 0; + } + + chr = os_memblock_get(&peer_chr_pool); + if (chr == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + memset(chr, 0, sizeof * chr); + + chr->chr = *gatt_chr; + + if (prev == NULL) { + SLIST_INSERT_HEAD(&svc->chrs, chr, next); + } else { + SLIST_NEXT(prev, next) = chr; + } + + return 0; +} + +static int +peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) +{ + struct peer *peer; + int rc; + + peer = arg; + assert(peer->conn_handle == conn_handle); + + switch (error->status) { + case 0: + rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr); + break; + + case BLE_HS_EDONE: + /* All characteristics in this service discovered; start discovering + * characteristics in the next service. + */ + if (peer->disc_prev_chr_val > 0) { + peer_disc_chrs(peer); + } + rc = 0; + break; + + default: + rc = error->status; + break; + } + + if (rc != 0) { + /* Error; abort discovery. */ + peer_disc_complete(peer, rc); + } + + return rc; +} + +static void +peer_disc_chrs(struct peer *peer) +{ + struct peer_svc *svc; + int rc; + + /* Search through the list of discovered service for the first service that + * contains undiscovered characteristics. Then, discover all + * characteristics belonging to that service. + */ + + SLIST_FOREACH(svc, &peer->svcs, next) { + if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) { + peer->cur_svc = svc; + rc = ble_gattc_disc_all_chrs(peer->conn_handle, + svc->svc.start_handle, + svc->svc.end_handle, + peer_chr_disced, peer); + if (rc != 0) { + peer_disc_complete(peer, rc); + } + return; + } + } + + /* All characteristics discovered. */ + peer_disc_dscs(peer); +} + +int +peer_svc_is_empty(const struct peer_svc *svc) +{ + return svc->svc.end_handle <= svc->svc.start_handle; +} + +static struct peer_svc * +peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle) +{ + struct peer_svc *prev; + struct peer_svc *svc; + + prev = NULL; + SLIST_FOREACH(svc, &peer->svcs, next) { + if (svc->svc.start_handle >= svc_start_handle) { + break; + } + + prev = svc; + } + + return prev; +} + +static struct peer_svc * +peer_svc_find(struct peer *peer, uint16_t svc_start_handle, + struct peer_svc **out_prev) +{ + struct peer_svc *prev; + struct peer_svc *svc; + + prev = peer_svc_find_prev(peer, svc_start_handle); + if (prev == NULL) { + svc = SLIST_FIRST(&peer->svcs); + } else { + svc = SLIST_NEXT(prev, next); + } + + if (svc != NULL && svc->svc.start_handle != svc_start_handle) { + svc = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return svc; +} + +static struct peer_svc * +peer_svc_find_range(struct peer *peer, uint16_t attr_handle) +{ + struct peer_svc *svc; + + SLIST_FOREACH(svc, &peer->svcs, next) { + if (svc->svc.start_handle <= attr_handle && + svc->svc.end_handle >= attr_handle) { + + return svc; + } + } + + return NULL; +} + +const struct peer_svc * +peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid) +{ + const struct peer_svc *svc; + + SLIST_FOREACH(svc, &peer->svcs, next) { + if ((uuid != NULL) && (ble_uuid_cmp(&(svc->svc.uuid.u), uuid) == 0)) { + return svc; + } + } + + return NULL; +} + +const struct peer_chr * +peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid) +{ + const struct peer_svc *svc; + const struct peer_chr *chr; + + svc = peer_svc_find_uuid(peer, svc_uuid); + if (svc == NULL) { + return NULL; + } + + SLIST_FOREACH(chr, &svc->chrs, next) { + if ((chr_uuid != NULL) && (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0)) { + return chr; + } + } + + return NULL; +} + +const struct peer_dsc * +peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid) +{ + const struct peer_chr *chr; + const struct peer_dsc *dsc; + + chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid); + if (chr == NULL) { + return NULL; + } + + SLIST_FOREACH(dsc, &chr->dscs, next) { + if ((dsc_uuid != NULL) && (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0)) { + return dsc; + } + } + + return NULL; +} + +static int +peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc) +{ + struct peer_svc *prev; + struct peer_svc *svc; + + svc = peer_svc_find(peer, gatt_svc->start_handle, &prev); + if (svc != NULL) { + /* Service already discovered. */ + return 0; + } + + svc = os_memblock_get(&peer_svc_pool); + if (svc == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + memset(svc, 0, sizeof * svc); + + svc->svc = *gatt_svc; + SLIST_INIT(&svc->chrs); + + if (prev == NULL) { + SLIST_INSERT_HEAD(&peer->svcs, svc, next); + } else { + SLIST_INSERT_AFTER(prev, svc, next); + } + + return 0; +} + +static void +peer_svc_delete(struct peer_svc *svc) +{ + struct peer_chr *chr; + + while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) { + SLIST_REMOVE_HEAD(&svc->chrs, next); + peer_chr_delete(chr); + } + + os_memblock_put(&peer_svc_pool, svc); +} + +static int +peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, void *arg) +{ + struct peer *peer; + int rc; + + peer = arg; + assert(peer->conn_handle == conn_handle); + + switch (error->status) { + case 0: + rc = peer_svc_add(peer, service); + break; + + case BLE_HS_EDONE: + /* All services discovered; start discovering characteristics. */ + if (peer->disc_prev_chr_val > 0) { + peer_disc_chrs(peer); + } + rc = 0; + break; + + default: + rc = error->status; + break; + } + + if (rc != 0) { + /* Error; abort discovery. */ + peer_disc_complete(peer, rc); + } + + return rc; +} + +int +peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg) +{ + struct peer_svc *svc; + struct peer *peer; + int rc; + + peer = peer_find(conn_handle); + if (peer == NULL) { + return BLE_HS_ENOTCONN; + } + + /* Undiscover everything first. */ + while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { + SLIST_REMOVE_HEAD(&peer->svcs, next); + peer_svc_delete(svc); + } + + peer->disc_prev_chr_val = 1; + peer->disc_cb = disc_cb; + peer->disc_cb_arg = disc_cb_arg; + + rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer); + if (rc != 0) { + return rc; + } + + return 0; +} + +int +peer_delete(uint16_t conn_handle) +{ + struct peer_svc *svc; + struct peer *peer; + int rc; + + peer = peer_find(conn_handle); + if (peer == NULL) { + return BLE_HS_ENOTCONN; + } + + SLIST_REMOVE(&peers, peer, peer, next); + + while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { + SLIST_REMOVE_HEAD(&peer->svcs, next); + peer_svc_delete(svc); + } + + rc = os_memblock_put(&peer_pool, peer); + if (rc != 0) { + return BLE_HS_EOS; + } + + return 0; +} + +int +peer_add(uint16_t conn_handle) +{ + struct peer *peer; + + /* Make sure the connection handle is unique. */ + peer = peer_find(conn_handle); + if (peer != NULL) { + return BLE_HS_EALREADY; + } + + peer = os_memblock_get(&peer_pool); + if (peer == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + + memset(peer, 0, sizeof * peer); + peer->conn_handle = conn_handle; + + SLIST_INSERT_HEAD(&peers, peer, next); + + return 0; +} + +static void +peer_free_mem(void) +{ + free(peer_mem); + peer_mem = NULL; + + free(peer_svc_mem); + peer_svc_mem = NULL; + + free(peer_chr_mem); + peer_chr_mem = NULL; + + free(peer_dsc_mem); + peer_dsc_mem = NULL; +} + +int +peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs) +{ + int rc; + + /* Free memory first in case this function gets called more than once. */ + peer_free_mem(); + + peer_mem = malloc( + OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer))); + if (peer_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_pool, max_peers, + sizeof (struct peer), peer_mem, + "peer_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + peer_svc_mem = malloc( + OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc))); + if (peer_svc_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_svc_pool, max_svcs, + sizeof (struct peer_svc), peer_svc_mem, + "peer_svc_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + peer_chr_mem = malloc( + OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr))); + if (peer_chr_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_chr_pool, max_chrs, + sizeof (struct peer_chr), peer_chr_mem, + "peer_chr_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + peer_dsc_mem = malloc( + OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc))); + if (peer_dsc_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&peer_dsc_pool, max_dscs, + sizeof (struct peer_dsc), peer_dsc_mem, + "peer_dsc_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } + + return 0; + +err: + peer_free_mem(); + ESP_LOGE("ERROR", "Error while allocating mem"); + return rc; +} diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/scli.c b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/scli.c new file mode 100644 index 000000000000..3e03db1f7baa --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/scli.c @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_log.h" +#include +#include +#include +#include "esp_vfs_dev.h" +#include "linenoise/linenoise.h" +#include +#include +#include +#include + +#define BLE_RX_TIMEOUT (30000 / portTICK_PERIOD_MS) +#define BLE_RX_PARAM (10000 / portTICK_PERIOD_MS) +#define YES_NO_PARAM (5000 / portTICK_PERIOD_MS) + +static QueueHandle_t cli_handle; +static int key[2]; +static int conn_param[10]; +static int mtu; + +#define CONSOLE_PROMPT_LEN_MAX (32) + +typedef enum { + CONSOLE_REPL_STATE_DEINIT, + CONSOLE_REPL_STATE_INIT, + CONSOLE_REPL_STATE_START, +} repl_state_t; + +static int conn_param_handler(int argc, char *argv[]) +{ + ESP_LOGI("Conn param Arguments entered", "%d", argc); + if (argc != 7) { + return -1; + } + + sscanf(argv[1], "%d", &conn_param[0]); + sscanf(argv[2], "%d", &conn_param[1]); + sscanf(argv[3], "%d", &conn_param[2]); + sscanf(argv[4], "%d", &conn_param[3]); + sscanf(argv[5], "%d", &conn_param[4]); + sscanf(argv[6], "%d", &conn_param[5]); + + ESP_LOGI("You entered", "%s %d %d %d %d %d %d", argv[0], conn_param[0], conn_param[1], + conn_param[2], conn_param[3], conn_param[4], conn_param[5]); + xQueueSend(cli_handle, &conn_param[0], 500 / portTICK_PERIOD_MS); + return 0; +} + +static int conn_mtu_handler(int argc, char *argv[]) +{ + ESP_LOGI("MTU Arguments entered", "%d", argc); + if (argc != 2) { + return -1; + } + + sscanf(argv[1], "%d", &mtu); + ESP_LOGI("You entered", "%s %d", argv[0], mtu); + xQueueSend(cli_handle, &mtu, 500 / portTICK_PERIOD_MS); + return 0; +} + +static int throughput_demo_handler(int argc, char *argv[]) +{ + char pkey[8]; + + if (argc != 3) { + return -1; + } + + sscanf(argv[1], "%s", pkey); + + if (strcmp(pkey, "read") == 0) { + key[0] = 1; + } else if (strcmp(pkey, "write") == 0) { + key[0] = 2; + } else if (strcmp(pkey, "notify") == 0) { + key[0] = 3; + } else { + key[0] = 0; + } + + sscanf(argv[2], "%d", &key[1]); + + ESP_LOGI("Throughput demo handler", "%s %s %d", argv[0], argv[1], key[1]); + xQueueSend(cli_handle, &key[0], 500 / portTICK_PERIOD_MS); + + return 0; +} + +static int yesno_handler(int argc, char *argv[]) +{ + char yesno[4]; + bool yes; + + if (argc != 2) { + return -1; + } + + sscanf(argv[1], "%s", yesno); + + if (strcmp(yesno, "Yes") || strcmp (yesno, "YES") || strcmp(yesno, "yes")) { + yes = 1; + } else { + yes = 0; + } + + ESP_LOGI("User entered", "%s %s", argv[0], yesno); + xQueueSend(cli_handle, &yes, 500 / portTICK_PERIOD_MS); + return 0; +} + +int scli_receive_yesno(bool *console_key) +{ + return xQueueReceive(cli_handle, console_key, YES_NO_PARAM); +} + +int scli_receive_key(int *console_key) +{ + return xQueueReceive(cli_handle, console_key, BLE_RX_PARAM); +} + +int cli_receive_key(int *console_key) +{ + return xQueueReceive(cli_handle, console_key, BLE_RX_TIMEOUT); +} + +void scli_reset_queue(void) +{ + xQueueReset(cli_handle); +} + +static esp_console_cmd_t cmds[] = { + { + .command = "conn", + .help = "Set connection parameters: min itvl, max itvl, latency," + "supervision timeout, min CE, max CE", + .func = &conn_param_handler, + }, + { + .command = "MTU", + .help = "Set MTU value", + .func = &conn_mtu_handler, + }, + { + .command = "throughput", + .help = "Enter read/write/notify and time (in seconds)", + .func = &throughput_demo_handler, + }, + { + .command = "Insert", + .help = "Enter Insert Yes for YES or Insert No for NO", + .func = &yesno_handler, + }, +}; + +void ble_register_cli(void) +{ + int cmds_num = sizeof(cmds) / sizeof(esp_console_cmd_t); + int i; + for (i = 0; i < cmds_num; i++) { + esp_console_cmd_register(&cmds[i]); + } + + cli_handle = xQueueCreate( 1, sizeof(int) * 6); + if (cli_handle == NULL) { + return; + } + + ESP_LOGI("CLI", "BLE CLI registered "); + return; +} diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/sdkconfig.defaults b/examples/bluetooth/nimble/throughput_app/blecent_throughput/sdkconfig.defaults new file mode 100644 index 000000000000..4a39777ef605 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/sdkconfig.defaults @@ -0,0 +1,15 @@ +# Override some defaults so BT stack is enabled +# in this example and some misc buffer sizes are increased + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=512 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=20 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=255 diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/CMakeLists.txt b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/CMakeLists.txt new file mode 100644 index 000000000000..628c9f7714e6 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(bleprph_throughput) diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/Makefile b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/Makefile new file mode 100644 index 000000000000..fc03ce2a49e0 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := bleprph_throughput + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/README.md b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/README.md new file mode 100644 index 000000000000..1e0d1a77da38 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/README.md @@ -0,0 +1,66 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +# Throughput bleprph Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +`bleprph_throughput` demonstrates server side implementation required for NimBLE throughput example. It has characteristics supporting READ, WRITE and NOTIFY (`PTS_LONG_CHR_READ_WRITE`,`PTS_CHR_READ_WRITE`,`PTS_CHR_NOTIFY`). The data of 500 Bytes (`READ_THROUGHPUT_PAYLOAD`) and 400 Bytes (`WRITE_THROUGHPUT_PAYLOAD`) is transferred for throughput GATT read and write operations respectively. + +`bleprph_throughput` uses the `nimble` component as BLE host. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (573) BTDM_INIT: BT controller compile version [b73c48e] +I (573) system_api: Base MAC address is not set +I (573) system_api: read default base MAC address from EFUSE +I (663) phy: phy_version: 4500, 0cd6843, Sep 17 2020, 15:37:07, 0, 0 +I (903) bleprph_throughput: BLE Host Task Started +I (933) bleprph_throughput: Device Address: +I (933) bleprph_throughput: 3c:71:bf:99:38:7a +GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 +I (1403) bleprph_throughput: connection established; status = 0 +I (1433) bleprph_throughput: mtu update event; conn_handle = 0 mtu = 512 + +``` + +In a separate terminal flash and run corresponding `blecent_throughput` for full fledged throughput demo. + +If at the `blecent_throughput` side `notify` is selected as GATT operation, then below console output can be observed: + +``` +I (23853) bleprph_throughput: subscribe event; cur_notify=1; value handle; val_handle = 14 +GATT procedure initiated: notify; att_handle=14 +GATT procedure initiated: notify; att_handle=14 +GATT procedure initiated: notify; att_handle=14 +GATT procedure initiated: notify; att_handle=14 +. +. +. + +********************************* +I (83943) bleprph_throughput: Notify throughput = 160466 bps, count = 2407 + +********************************* +I (83943) bleprph_throughput: Notification test completed for stipulated time of 60 sec + +``` + +> Here, bps is bits per second; count is number of Notifications successfully sent. + +## Example scope + +This demo example along with `blecent_throughput` tries to demonstrate stable implementation of GATT operations like read/write and notify. For `bleprph_throughput` app, notifications are sent almost continuously for stipulated period of time. The almost part is because we use counting semaphore (~100) to mimic continuous notifications. Here one needs to understand that notifications are sent in `os_mbufs` packets and there can always be chance of them getting full because of continuous operation, so one may need to allocate higher number of mbufs through menuconfig, whenever there is `os_mbuf` memory exhaustion, app provides delay so NimBLE host stack can breathe and free `mbuf chains`. diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/CMakeLists.txt b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/CMakeLists.txt new file mode 100644 index 000000000000..e8a76d0b091c --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" "gatt_svr.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/component.mk b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/component.mk new file mode 100644 index 000000000000..a98f634eae06 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/gatt_svr.c b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/gatt_svr.c new file mode 100644 index 000000000000..4a0059c5e650 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/gatt_svr.c @@ -0,0 +1,214 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" +#include "gatts_sens.h" +#include "esp_log.h" + +/* 0000xxxx-8c26-476f-89a7-a108033a69c7 */ +#define THRPT_UUID_DECLARE(uuid16) \ + ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT( \ + 0xc7, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ + 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ + ))) + +/* 0000xxxx-8c26-476f-89a7-a108033a69c6 */ +#define THRPT_UUID_DECLARE_ALT(uuid16) \ + ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT( \ + 0xc6, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ + 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ + ))) + +#define THRPT_SVC 0x0001 +#define THRPT_CHR_READ_WRITE 0x0006 +#define THRPT_CHR_NOTIFY 0x000a +#define THRPT_LONG_CHR_READ_WRITE 0x000b + +#define READ_THROUGHPUT_PAYLOAD 500 +#define WRITE_THROUGHPUT_PAYLOAD 500 + +static const char *tag = "bleprph_throughput"; + +static uint8_t gatt_svr_thrpt_static_long_val[READ_THROUGHPUT_PAYLOAD]; +static uint8_t gatt_svr_thrpt_static_short_val[WRITE_THROUGHPUT_PAYLOAD]; +uint16_t notify_handle; + +static int +gatt_svr_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static const struct ble_gatt_svc_def gatts_test_svcs[] = { + { + /*** Service: THRPT test. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = THRPT_UUID_DECLARE(THRPT_SVC), + .characteristics = (struct ble_gatt_chr_def[]) + { { + .uuid = THRPT_UUID_DECLARE(THRPT_CHR_READ_WRITE), + .access_cb = gatt_svr_read_write_long_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE, + + }, { + .uuid = THRPT_UUID_DECLARE(THRPT_CHR_NOTIFY), + .access_cb = gatt_svr_read_write_long_test, + .val_handle = ¬ify_handle, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid = THRPT_UUID_DECLARE(THRPT_LONG_CHR_READ_WRITE), + .access_cb = gatt_svr_read_write_long_test, + .flags = BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_READ, + }, { + 0, /* No more characteristics in this service. */ + } + }, + }, + + { + 0, /* No more services. */ + }, +}; + +static uint16_t +extract_uuid16_from_thrpt_uuid128(const ble_uuid_t *uuid) +{ + const uint8_t *u8ptr; + uint16_t uuid16; + + u8ptr = BLE_UUID128(uuid)->value; + uuid16 = u8ptr[12]; + uuid16 |= (uint16_t)u8ptr[13] << 8; + return uuid16; +} + +static int +gatt_svr_chr_write(uint16_t conn_handle, uint16_t attr_handle, + struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) +{ + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + return 0; +} + +static int +gatt_svr_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_thrpt_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case THRPT_LONG_CHR_READ_WRITE: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_thrpt_static_long_val, + &gatt_svr_thrpt_static_long_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + gatt_svr_thrpt_static_long_val[0] = rand(); + rc = os_mbuf_append(ctxt->om, &gatt_svr_thrpt_static_long_val, + sizeof gatt_svr_thrpt_static_long_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + return 0; + + case THRPT_CHR_READ_WRITE: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_thrpt_static_short_val, + gatt_svr_thrpt_static_short_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, gatt_svr_thrpt_static_short_val, + sizeof gatt_svr_thrpt_static_short_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + return BLE_ATT_ERR_UNLIKELY; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + ESP_LOGD(tag, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + ESP_LOGD(tag, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + ESP_LOGD(tag, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +int +gatt_svr_init(void) +{ + int rc; + + ble_svc_gap_init(); + ble_svc_gatt_init(); + + rc = ble_gatts_count_cfg(gatts_test_svcs); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatts_test_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/gatts_sens.h b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/gatts_sens.h new file mode 100644 index 000000000000..1313c12156c1 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/gatts_sens.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_GATTS_SENS_ +#define H_GATTS_SENS_ + +#include "nimble/ble.h" +#include "modlog/modlog.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint16_t notify_handle; + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c new file mode 100644 index 000000000000..94a79c852684 --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c @@ -0,0 +1,395 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +#include "freertos/FreeRTOSConfig.h" +/* BLE */ +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "gatts_sens.h" +#include "../src/ble_hs_hci_priv.h" + +#define NOTIFY_THROUGHPUT_PAYLOAD 500 +#define MIN_REQUIRED_MBUF 2 /* Assuming payload of 500Bytes and each mbuf can take 292Bytes. */ +#define PREFERRED_MTU_VALUE 512 +#define LL_PACKET_TIME 2120 +#define LL_PACKET_LENGTH 251 +#define MTU_DEF 512 + +static const char *tag = "bleprph_throughput"; +static const char *device_name = "nimble_prph"; +static SemaphoreHandle_t notify_sem; +static bool notify_state; +static int notify_test_time = 60; +static uint16_t conn_handle; +/* Dummy variable */ +static uint8_t dummy; +static uint8_t gatts_addr_type; + +static int gatts_gap_event(struct ble_gap_event *event, void *arg); + +/** + * Utility function to log an array of bytes. + */ + +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) { + ESP_LOGI(tag, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + ESP_LOGI(tag, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} + +static void +bleprph_print_conn_desc(struct ble_gap_conn_desc *desc) +{ + ESP_LOGI(tag, "handle=%d our_ota_addr_type=%d our_ota_addr=", + desc->conn_handle, desc->our_ota_addr.type); + print_addr(desc->our_ota_addr.val); + ESP_LOGI(tag, " our_id_addr_type=%d our_id_addr=", + desc->our_id_addr.type); + print_addr(desc->our_id_addr.val); + ESP_LOGI(tag, " peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr.type); + print_addr(desc->peer_ota_addr.val); + ESP_LOGI(tag, " peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr.type); + print_addr(desc->peer_id_addr.val); + ESP_LOGI(tag, " conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +/* + * Enables advertising with parameters: + * o General discoverable mode + * o Undirected connectable mode + */ +static void +gatts_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + int rc; + + /* + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info) + * o Advertising tx power + * o Device name + */ + memset(&fields, 0, sizeof(fields)); + + /* + * Advertise two flags: + * o Discoverability in forthcoming advertisement (general) + * o BLE-only (BR/EDR unsupported) + */ + fields.flags = BLE_HS_ADV_F_DISC_GEN | + BLE_HS_ADV_F_BREDR_UNSUP; + + /* + * Indicate that the TX power level field should be included; have the + * stack fill this value automatically. This is done by assigning the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + fields.name = (uint8_t *)device_name; + fields.name_len = strlen(device_name); + fields.name_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + ESP_LOGE(tag, "Error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising */ + memset(&adv_params, 0, sizeof(adv_params)); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(gatts_addr_type, NULL, BLE_HS_FOREVER, + &adv_params, gatts_gap_event, NULL); + if (rc != 0) { + ESP_LOGE(tag, "Error enabling advertisement; rc=%d\n", rc); + return; + } +} + +/* This function sends notifications to the client */ +static void +notify_task(void *arg) +{ + static uint8_t payload[NOTIFY_THROUGHPUT_PAYLOAD] = {0};/* Data payload */ + int rc, notify_count = 0; + int64_t start_time, end_time, notify_time = 0; + struct os_mbuf *om; + + payload[0] = dummy; /* storing dummy data */ + payload[1] = rand(); + payload[99] = rand(); + + while (!notify_state) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + while (1) { + switch (notify_test_time) { + + case 0: + vTaskDelay(1000 / portTICK_PERIOD_MS); + break; + default: + start_time = esp_timer_get_time(); + + if (!notify_state) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + break; + } + + while (notify_time < (notify_test_time * 1000)) { + /* We are anyway using counting semaphore for sending + * notifications. So hopefully not much waiting period will be + * introduced before sending a new notification. Revisit this + * counter if need to do away with semaphore waiting. XXX */ + xSemaphoreTake(notify_sem, portMAX_DELAY); + + if (dummy == 200) { + dummy = 0; + } + dummy++; + + /* Check if the MBUFs are available */ + if (os_msys_num_free() >= MIN_REQUIRED_MBUF) { + om = ble_hs_mbuf_from_flat(payload, sizeof(payload)); + if (om == NULL) { + /* Memory not available for mbuf */ + ESP_LOGE(tag, "No MBUFs available from pool, retry.."); + vTaskDelay(100 / portTICK_PERIOD_MS); + om = ble_hs_mbuf_from_flat(payload, sizeof(payload)); + assert(om != NULL); + } + + rc = ble_gattc_notify_custom(conn_handle, notify_handle, om); + if (rc != 0) { + ESP_LOGE(tag, "Error while sending notification; rc = %d", rc); + notify_count -= 1; + xSemaphoreGive(notify_sem); + /* Most probably error is because we ran out of mbufs (rc = 6), + * increase the mbuf count/size from menuconfig. Though + * inserting delay is not good solution let us keep it + * simple for time being so that the mbufs get freed up + * (?), of course assumption is we ran out of mbufs */ + vTaskDelay(10 / portTICK_PERIOD_MS); + } + } else { + ESP_LOGE(tag, "Not enough OS_MBUFs available; reduce notify count "); + xSemaphoreGive(notify_sem); + notify_count -= 1; + } + + end_time = esp_timer_get_time(); + notify_time = (end_time - start_time) / 1000 ; + notify_count += 1; + } + + printf("\n*********************************\n"); + ESP_LOGI(tag, "Notify throughput = %d bps, count = %d", + (notify_count * NOTIFY_THROUGHPUT_PAYLOAD * 8) / notify_test_time, notify_count); + printf("\n*********************************\n"); + ESP_LOGI(tag, " Notification test complete for stipulated time of %d sec", notify_test_time); + notify_test_time = 0; + notify_count = 0; + + break; + } + vTaskDelay(3000 / portTICK_PERIOD_MS); + } +} + +static int +gatts_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed */ + ESP_LOGI(tag, "connection %s; status = %d ", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + rc = ble_att_set_preferred_mtu(PREFERRED_MTU_VALUE); + if (rc != 0) { + ESP_LOGE(tag, "Failed to set preferred MTU; rc = %d", rc); + } + + if (event->connect.status != 0) { + /* Connection failed; resume advertising */ + gatts_advertise(); + } + + rc = ble_hs_hci_util_set_data_len(event->connect.conn_handle, + LL_PACKET_LENGTH, + LL_PACKET_TIME); + if (rc != 0) { + ESP_LOGE(tag, "Set packet length failed"); + } + + conn_handle = event->connect.conn_handle; + break; + + case BLE_GAP_EVENT_DISCONNECT: + ESP_LOGI(tag, "disconnect; reason = %d", event->disconnect.reason); + + /* Connection terminated; resume advertising */ + gatts_advertise(); + break; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + ESP_LOGI(tag, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + assert(rc == 0); + bleprph_print_conn_desc(&desc); + return 0; + + case BLE_GAP_EVENT_ADV_COMPLETE: + ESP_LOGI(tag, "adv complete "); + gatts_advertise(); + break; + + case BLE_GAP_EVENT_SUBSCRIBE: + ESP_LOGI(tag, "subscribe event; cur_notify=%d; value handle; " + "val_handle = %d", + event->subscribe.cur_notify, event->subscribe.attr_handle); + if (event->subscribe.attr_handle == notify_handle) { + notify_state = event->subscribe.cur_notify; + if (arg != NULL) { + ESP_LOGI(tag, "notify test time = %d", *(int *)arg); + notify_test_time = *((int *)arg); + } + xSemaphoreGive(notify_sem); + } else if (event->subscribe.attr_handle != notify_handle) { + notify_state = event->subscribe.cur_notify; + } + break; + + case BLE_GAP_EVENT_NOTIFY_TX: + ESP_LOGD(tag, "BLE_GAP_EVENT_NOTIFY_TX success !!"); + if ((event->notify_tx.status == 0) || + (event->notify_tx.status == BLE_HS_EDONE)) { + /* Send new notification i.e. give Semaphore. By definition, + * sending new notifications should not be based on successful + * notifications sent, but let us adopt this method to avoid too + * many `BLE_HS_ENOMEM` errors because of continuous transfer of + * notifications.XXX */ + xSemaphoreGive(notify_sem); + } else { + ESP_LOGE(tag, "BLE_GAP_EVENT_NOTIFY_TX notify tx status = %d", event->notify_tx.status); + } + break; + + case BLE_GAP_EVENT_MTU: + ESP_LOGI(tag, "mtu update event; conn_handle = %d mtu = %d ", + event->mtu.conn_handle, + event->mtu.value); + break; + } + return 0; +} + +static void +gatts_on_sync(void) +{ + int rc; + uint8_t addr_val[6] = {0}; + + rc = ble_hs_id_infer_auto(0, &gatts_addr_type); + assert(rc == 0); + rc = ble_hs_id_copy_addr(gatts_addr_type, addr_val, NULL); + assert(rc == 0); + ESP_LOGI(tag, "Device Address: "); + print_addr(addr_val); + /* Begin advertising */ + gatts_advertise(); +} + +static void +gatts_on_reset(int reason) +{ + ESP_LOGE(tag, "Resetting state; reason=%d\n", reason); +} + +void gatts_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* Create a counting semaphore for Notification. Can be used to track + * successful notification txmission. Optimistically take some big number + * for counting Semaphore */ + notify_sem = xSemaphoreCreateCounting(100, 0); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + vSemaphoreDelete(notify_sem); + nimble_port_freertos_deinit(); +} + +void app_main(void) +{ + int rc; + + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration */ + ble_hs_cfg.sync_cb = gatts_on_sync; + ble_hs_cfg.reset_cb = gatts_on_reset; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb, + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Initialize Notify Task */ + xTaskCreate(notify_task, "notify_task", 4096, NULL, 10, NULL); + + rc = gatt_svr_init(); + assert(rc == 0); + + /* Set the default device name */ + rc = ble_svc_gap_device_name_set(device_name); + assert(rc == 0); + + /* Start the task */ + nimble_port_freertos_init(gatts_host_task); +} diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/sdkconfig.defaults b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/sdkconfig.defaults new file mode 100644 index 000000000000..cbacfa46628d --- /dev/null +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/sdkconfig.defaults @@ -0,0 +1,16 @@ +# Override some defaults so BT stack is enabled +# in this example and some example specific misc sizes are increased. + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=512 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=20 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=255 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=50 diff --git a/examples/build_system/cmake/component_manager/CMakeLists.txt b/examples/build_system/cmake/component_manager/CMakeLists.txt new file mode 100644 index 000000000000..9b15cac7871a --- /dev/null +++ b/examples/build_system/cmake/component_manager/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(component_manager) diff --git a/examples/build_system/cmake/component_manager/README.md b/examples/build_system/cmake/component_manager/README.md new file mode 100644 index 000000000000..182664f55338 --- /dev/null +++ b/examples/build_system/cmake/component_manager/README.md @@ -0,0 +1,55 @@ +# Using the component manager for downloading dependencies + +This example demonstrates how to use [IDF Component Manager](https://pypi.org/project/idf-component-manager/) for downloading dependencies from [the component registry](https://components.espressif.com). More details and use cases of IDF Component Manager can be found in the programming guide under `API Guides` -> `Tools` -> `IDF Component Manager`. + +## How to use the example +### Hardware Required + +This example is designed to work with any commonly available development kit. + +### Build and Flash + +Run `idf.py reconfigure` to configure this project. During CMake execution the component manager will process data from the manifest file `./main/idf_component.yml` where 2 dependencies are defined: + +- `idf: ">=4.1"` - Specifies required version of ESP-IDF. +- `example/cmp: ">=3.3.3"` - Defines dependency on [example/cmp](https://components.espressif.com/component/example/cmp) component that is used by the main component. + +CMake Output: +``` +... +Solving dependencies requirements +Updating lock file at /home/user/esp-idf/examples/build_system/cmake/component_manager/dependencies.lock +Processing 2 dependencies: +[1/2] example/cmp +[2/2] idf +... +``` + +Content of the `./managed_components` directory after successful build: +``` +> find ./managed_components +./managed_components +./managed_components/example__cmp +./managed_components/example__cmp/include +./managed_components/example__cmp/include/cmp.h +./managed_components/example__cmp/LICENSE +./managed_components/example__cmp/README.md +./managed_components/example__cmp/CMakeLists.txt +./managed_components/example__cmp/changelog.md +./managed_components/example__cmp/cmp.c +./managed_components/example__cmp/idf_component.yml +``` + +Flash the project and run the serial monitor to view the output: + +``` +idf.py -p PORT flash monitor +``` + +### Example Output + +The example outputs a line from the `cmp_hello` function from the component downloaded by the component manager. + +``` +Hello from example component! +``` diff --git a/examples/build_system/cmake/component_manager/main/CMakeLists.txt b/examples/build_system/cmake/component_manager/main/CMakeLists.txt new file mode 100644 index 000000000000..9bc2623419c6 --- /dev/null +++ b/examples/build_system/cmake/component_manager/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "component_manager.c" + INCLUDE_DIRS ".") diff --git a/examples/build_system/cmake/component_manager/main/component_manager.c b/examples/build_system/cmake/component_manager/main/component_manager.c new file mode 100644 index 000000000000..6358d964dddb --- /dev/null +++ b/examples/build_system/cmake/component_manager/main/component_manager.c @@ -0,0 +1,7 @@ +#include +#include "cmp.h" + +void app_main(void) +{ + cmp_hello(); +} diff --git a/examples/build_system/cmake/component_manager/main/idf_component.yml b/examples/build_system/cmake/component_manager/main/idf_component.yml new file mode 100644 index 000000000000..1a90a2c8c463 --- /dev/null +++ b/examples/build_system/cmake/component_manager/main/idf_component.yml @@ -0,0 +1,36 @@ +dependencies: + # Required IDF version + idf: ">=4.1" + + # Defining a dependency from the registry: + # https://components.espressif.com/component/example/cmp + example/cmp: ">=3.3.3" + + # # Other ways to define dependencies + # + # # For components maintained by Espressif only name can be used. + # # Same as `espressif/cmp` + # component: "~1.0.0" + # + # # Or in a longer form with extra parameters + # component2: + # version: ">=2.0.0" + # + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect for the `main` component. + # # All dependencies of `main` are public by default. + # public: true + # + # # For components hosted on non-default registry: + # service_url: "https://componentregistry.company.com" + # + # # For components in git repository: + # test_component: + # path: test_component + # git: ssh://git@gitlab.com/user/components.git + # + # # For test projects during component development + # # components can be used from a local directory + # # with relative or absolute path + # some_local_component: + # path: ../../projects/component diff --git a/examples/mesh/internal_communication/main/mesh_main.c b/examples/mesh/internal_communication/main/mesh_main.c index 26f5a3ba7ac1..722aa693cce7 100644 --- a/examples/mesh/internal_communication/main/mesh_main.c +++ b/examples/mesh/internal_communication/main/mesh_main.c @@ -245,6 +245,7 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base, mesh_connected_indicator(mesh_layer); is_mesh_connected = true; if (esp_mesh_is_root()) { + esp_netif_dhcpc_stop(netif_sta); esp_netif_dhcpc_start(netif_sta); } esp_mesh_comm_p2p_start(); diff --git a/examples/mesh/ip_internal_network/main/mqtt_app.c b/examples/mesh/ip_internal_network/main/mqtt_app.c index abc8ac95c4c2..abec5f5b0dad 100644 --- a/examples/mesh/ip_internal_network/main/mqtt_app.c +++ b/examples/mesh/ip_internal_network/main/mqtt_app.c @@ -71,7 +71,7 @@ void mqtt_app_publish(char* topic, char *publish_string) void mqtt_app_start(void) { esp_mqtt_client_config_t mqtt_cfg = { - .uri = "mqtt://mqtt.eclipse.org", + .uri = "mqtt://mqtt.eclipseprojects.io", }; s_client = esp_mqtt_client_init(&mqtt_cfg); diff --git a/examples/mesh/manual_networking/main/mesh_main.c b/examples/mesh/manual_networking/main/mesh_main.c index 3cbfdad6c876..ff419acc4277 100644 --- a/examples/mesh/manual_networking/main/mesh_main.c +++ b/examples/mesh/manual_networking/main/mesh_main.c @@ -213,6 +213,7 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base, last_layer = mesh_layer; mesh_connected_indicator(mesh_layer); if (esp_mesh_is_root()) { + esp_netif_dhcpc_stop(netif_sta); esp_netif_dhcpc_start(netif_sta); } } diff --git a/examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c b/examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c index 425f8fa9e1ca..faf584b48e2c 100644 --- a/examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c +++ b/examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c @@ -59,7 +59,8 @@ static void gpio_task_example(void* arg) void app_main(void) { - gpio_config_t io_conf; + //zero-initialize the config structure. + gpio_config_t io_conf = {}; //disable interrupt io_conf.intr_type = GPIO_INTR_DISABLE; //set as output mode diff --git a/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c b/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c index c29231b24e5a..4e363215d565 100644 --- a/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c +++ b/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c @@ -56,6 +56,9 @@ void app_main(void) #elif CONFIG_ESP_CONSOLE_USB_CDC esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl)); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl)); #endif register_i2ctools(); diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c index 5c24fa622aa5..219f08ef6085 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c @@ -290,14 +290,14 @@ void app_main(void) uint8_t init_value[SOC_SPI_MAXIMUM_BUFFER_SIZE] = {0x0}; spi_slave_hd_write_buffer(SLAVE_HOST, 0, init_value, SOC_SPI_MAXIMUM_BUFFER_SIZE); - uint32_t send_buf_size = 5000; - spi_slave_hd_write_buffer(SLAVE_HOST, SLAVE_MAX_TX_BUF_LEN_REG, (uint8_t *)&send_buf_size, 4); + static uint32_t send_buf_size = 5000; + spi_slave_hd_write_buffer(SLAVE_HOST, SLAVE_MAX_TX_BUF_LEN_REG, (uint8_t *)&send_buf_size, sizeof(send_buf_size)); - uint32_t recv_buf_size = 120; - spi_slave_hd_write_buffer(SLAVE_HOST, SLAVE_MAX_RX_BUF_LEN_REG, (uint8_t *)&recv_buf_size, 4); + static uint32_t recv_buf_size = 120; + spi_slave_hd_write_buffer(SLAVE_HOST, SLAVE_MAX_RX_BUF_LEN_REG, (uint8_t *)&recv_buf_size, sizeof(recv_buf_size)); uint32_t slave_ready_flag = SLAVE_READY_FLAG; - spi_slave_hd_write_buffer(SLAVE_HOST, SLAVE_READY_FLAG_REG, (uint8_t *)&slave_ready_flag, 4); + spi_slave_hd_write_buffer(SLAVE_HOST, SLAVE_READY_FLAG_REG, (uint8_t *)&slave_ready_flag, sizeof(slave_ready_flag)); xTaskCreate(sender, "sendTask", 4096, &send_buf_size, 1, NULL); xTaskCreate(receiver, "recvTask", 4096, &recv_buf_size, 1, NULL); diff --git a/examples/protocols/coap_client/README.md b/examples/protocols/coap_client/README.md index a870f9363ef0..f2f024585e3f 100644 --- a/examples/protocols/coap_client/README.md +++ b/examples/protocols/coap_client/README.md @@ -59,33 +59,29 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output Prerequisite: we startup a CoAP server on coap server example, -or use the default of coap://californium.eclipse.org. +or use the default of coaps://californium.eclipseprojects.io. and you could receive data from CoAP server if succeed, such as the following log: ``` ... -I (332) wifi: mode : sta (30:ae:a4:04:1b:7c) -I (1672) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1 -I (1672) wifi: state: init -> auth (b0) -I (1682) wifi: state: auth -> assoc (0) -I (1692) wifi: state: assoc -> run (10) -I (1692) wifi: connected with huawei_cw, channel 11 -I (1692) wifi: pm start, type: 1 - -I (2582) event: sta ip: 192.168.3.89, mask: 255.255.255.0, gw: 192.168.3.1 -I (2582) CoAP_client: Connected to AP -I (2582) CoAP_client: DNS lookup succeeded. IP=104.196.15.150 +I (5104) esp_netif_handlers: example_connect: sta ip: 192.168.0.103, mask: 255.255.255.0, gw: 192.168.0.1 +I (5104) example_connect: Got IPv4 event: Interface "example_connect: sta" address: 192.168.0.103 +I (5604) example_connect: Got IPv6 event: Interface "example_connect: sta" address: fe80:0000:0000:0000:32ae:a4ff:fec5:3234, type: ESP_IP6_ADDR_IS_LINK_LOCAL +I (5604) example_connect: Connected to example_connect: sta +I (5614) example_connect: - IPv4 address: 192.168.0.103 +I (5614) example_connect: - IPv6 address: fe80:0000:0000:0000:32ae:a4ff:fec5:3234, type: ESP_IP6_ADDR_IS_LINK_LOCAL +I (6004) CoAP_client: DNS lookup succeeded. IP=35.185.40.182 Received: -************************************************************ -CoAP RFC 7252 Cf 2.0.0-SNAPSHOT -************************************************************ +**************************************************************** +CoAP RFC 7252 Cf 3.0.0-SNAPSHOT +**************************************************************** This server is using the Eclipse Californium (Cf) CoAP framework published under EPL+EDL: http://www.eclipse.org/californium/ -(c) 2014, 2015, 2016 Institute for Pervasive Computing, ETH Zurich and others -************************************************************ +(c) 2014-2020 Institute for Pervasive Computing, ETH Zurich and others +**************************************************************** ... ``` @@ -96,6 +92,6 @@ This can be found at https://libcoap.net/doc/reference/4.2.0/ * Please make sure Target Url includes valid `host`, optional `port`, optional `path`, and begins with `coap://`, `coaps://` or `coap+tcp://` for a coap server that supports TCP -(not all do including coap+tcp://californium.eclipse.org). +(not all do including coap+tcp://californium.eclipseprojects.io). * CoAP logging can be enabled by running 'idf.py menuconfig -> Component config -> CoAP Configuration' and setting appropriate log level diff --git a/examples/protocols/coap_client/main/Kconfig.projbuild b/examples/protocols/coap_client/main/Kconfig.projbuild index 33b04a7b86dc..206b2fa7128d 100644 --- a/examples/protocols/coap_client/main/Kconfig.projbuild +++ b/examples/protocols/coap_client/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example CoAP Client Configuration" config EXAMPLE_TARGET_DOMAIN_URI string "Target Uri" - default "coaps://californium.eclipse.org" + default "coaps://californium.eclipseprojects.io" help Target uri for the example to use. Use coaps:// prefix for encrypted traffic using Pre-Shared Key (PSK) or Public Key Infrastructure (PKI). diff --git a/examples/protocols/esp_http_client/esp_http_client_test.py b/examples/protocols/esp_http_client/esp_http_client_test.py index 17a6d8346cda..2bdf6b5b2446 100644 --- a/examples/protocols/esp_http_client/esp_http_client_test.py +++ b/examples/protocols/esp_http_client/esp_http_client_test.py @@ -25,15 +25,30 @@ def test_examples_protocol_esp_http_client(env, extra_data): dut1.expect(re.compile(r'HTTP PATCH Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP DELETE Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP HEAD Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP GET Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP POST Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP PUT Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP PATCH Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP DELETE Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP HEAD Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP Basic Auth Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP Basic Auth redirect Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP Digest Auth Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Relative path redirect Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Absolute path redirect Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTPS Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTPS Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP redirect to HTTPS Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP chunk encoding Status = 200, content_length = (-?\d)')) # content-len for chunked encoding is typically -1, could be a positive length in some cases dut1.expect(re.compile(r'HTTP Stream reader Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTPS Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'Last esp error code: 0x8001')) + dut1.expect(re.compile(r'HTTP GET Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP POST Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Status = 206, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Status = 206, content_length = 10')) + dut1.expect(re.compile(r'HTTP Status = 206, content_length = 10')) dut1.expect('Finish http example') # test mbedtls dynamic resource @@ -51,15 +66,30 @@ def test_examples_protocol_esp_http_client(env, extra_data): dut1.expect(re.compile(r'HTTP PATCH Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP DELETE Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP HEAD Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP GET Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP POST Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP PUT Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP PATCH Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP DELETE Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP HEAD Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP Basic Auth Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP Basic Auth redirect Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP Digest Auth Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Relative path redirect Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Absolute path redirect Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTPS Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTPS Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP redirect to HTTPS Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'HTTP chunk encoding Status = 200, content_length = (-?\d)')) # content-len for chunked encoding is typically -1, could be a positive length in some cases dut1.expect(re.compile(r'HTTP Stream reader Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTPS Status = 200, content_length = (\d)')) dut1.expect(re.compile(r'Last esp error code: 0x8001')) + dut1.expect(re.compile(r'HTTP GET Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP POST Status = 200, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Status = 206, content_length = (\d)')) + dut1.expect(re.compile(r'HTTP Status = 206, content_length = 10')) + dut1.expect(re.compile(r'HTTP Status = 206, content_length = 10')) dut1.expect('Finish http example') diff --git a/examples/protocols/esp_http_client/main/CMakeLists.txt b/examples/protocols/esp_http_client/main/CMakeLists.txt index 2cb6a74b8a6f..1b140afc4666 100644 --- a/examples/protocols/esp_http_client/main/CMakeLists.txt +++ b/examples/protocols/esp_http_client/main/CMakeLists.txt @@ -3,4 +3,6 @@ # (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.) idf_component_register(SRCS "esp_http_client_example.c" INCLUDE_DIRS "." - EMBED_TXTFILES howsmyssl_com_root_cert.pem) + EMBED_TXTFILES howsmyssl_com_root_cert.pem + dl_espressif_com_root_cert.pem + postman_echo_com_root_cert.pem) diff --git a/examples/protocols/esp_http_client/main/component.mk b/examples/protocols/esp_http_client/main/component.mk index cb97ca08ee04..a96255ef4f2c 100644 --- a/examples/protocols/esp_http_client/main/component.mk +++ b/examples/protocols/esp_http_client/main/component.mk @@ -5,4 +5,4 @@ # embed files from the "certs" directory as binary data symbols # in the app -COMPONENT_EMBED_TXTFILES := howsmyssl_com_root_cert.pem +COMPONENT_EMBED_TXTFILES := howsmyssl_com_root_cert.pem dl_espressif_com_root_cert.pem postman_echo_com_root_cert.pem diff --git a/examples/protocols/esp_http_client/main/dl_espressif_com_root_cert.pem b/examples/protocols/esp_http_client/main/dl_espressif_com_root_cert.pem new file mode 100644 index 000000000000..42841598fcbd --- /dev/null +++ b/examples/protocols/esp_http_client/main/dl_espressif_com_root_cert.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE6jCCA9KgAwIBAgIQCjUI1VwpKwF9+K1lwA/35DANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0yMDA5MjQwMDAwMDBaFw0zMDA5MjMyMzU5NTlaME8xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxKTAnBgNVBAMTIERpZ2lDZXJ0IFRMUyBS +U0EgU0hBMjU2IDIwMjAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAwUuzZUdwvN1PWNvsnO3DZuUfMRNUrUpmRh8sCuxkB+Uu3Ny5CiDt3+PE0J6a +qXodgojlEVbbHp9YwlHnLDQNLtKS4VbL8Xlfs7uHyiUDe5pSQWYQYE9XE0nw6Ddn +g9/n00tnTCJRpt8OmRDtV1F0JuJ9x8piLhMbfyOIJVNvwTRYAIuE//i+p1hJInuW +raKImxW8oHzf6VGo1bDtN+I2tIJLYrVJmuzHZ9bjPvXj1hJeRPG/cUJ9WIQDgLGB +Afr5yjK7tI4nhyfFK3TUqNaX3sNk+crOU6JWvHgXjkkDKa77SU+kFbnO8lwZV21r +eacroicgE7XQPUDTITAHk+qZ9QIDAQABo4IBrjCCAaowHQYDVR0OBBYEFLdrouqo +qoSMeeq02g+YssWVdrn0MB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFV +MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +EgYDVR0TAQH/BAgwBgEB/wIBADB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGG +GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2Nh +Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDB7BgNV +HR8EdDByMDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRH +bG9iYWxSb290Q0EuY3JsMDegNaAzhjFodHRwOi8vY3JsNC5kaWdpY2VydC5jb20v +RGlnaUNlcnRHbG9iYWxSb290Q0EuY3JsMDAGA1UdIAQpMCcwBwYFZ4EMAQEwCAYG +Z4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEBAHer +t3onPa679n/gWlbJhKrKW3EX3SJH/E6f7tDBpATho+vFScH90cnfjK+URSxGKqNj +OSD5nkoklEHIqdninFQFBstcHL4AGw+oWv8Zu2XHFq8hVt1hBcnpj5h232sb0HIM +ULkwKXq/YFkQZhM6LawVEWwtIwwCPgU7/uWhnOKK24fXSuhe50gG66sSmvKvhMNb +g0qZgYOrAKHKCjxMoiWJKiKnpPMzTFuMLhoClw+dj20tlQj7T9rxkTgl4ZxuYRiH +as6xuwAwapu3r9rxxZf+ingkquqTgLozZXq8oXfpf2kUCwA/d5KxTVtzhwoT0JzI +8ks5T1KESaZMkE4f97Q= +-----END CERTIFICATE----- diff --git a/examples/protocols/esp_http_client/main/esp_http_client_example.c b/examples/protocols/esp_http_client/main/esp_http_client_example.c index e017d177800f..d1df4a2a1208 100644 --- a/examples/protocols/esp_http_client/main/esp_http_client_example.c +++ b/examples/protocols/esp_http_client/main/esp_http_client_example.c @@ -18,6 +18,9 @@ #include "esp_netif.h" #include "protocol_examples_common.h" #include "esp_tls.h" +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE +#include "esp_crt_bundle.h" +#endif #include "esp_http_client.h" @@ -38,6 +41,12 @@ static const char *TAG = "HTTP_CLIENT"; extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start"); extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end"); +extern const char dl_espressif_com_root_cert_pem_start[] asm("_binary_dl_espressif_com_root_cert_pem_start"); +extern const char dl_espressif_com_root_cert_pem_end[] asm("_binary_dl_espressif_com_root_cert_pem_end"); + +extern const char postman_echo_com_root_cert_pem_start[] asm("_binary_postman_echo_com_root_cert_pem_start"); +extern const char postman_echo_com_root_cert_pem_end[] asm("_binary_postman_echo_com_root_cert_pem_end"); + esp_err_t _http_event_handler(esp_http_client_event_t *evt) { static char *output_buffer; // Buffer to store response of http request from event handler @@ -95,14 +104,14 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt) int mbedtls_err = 0; esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL); if (err != 0) { - if (output_buffer != NULL) { - free(output_buffer); - output_buffer = NULL; - } - output_len = 0; ESP_LOGI(TAG, "Last esp error code: 0x%x", err); ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err); } + if (output_buffer != NULL) { + free(output_buffer); + output_buffer = NULL; + } + output_len = 0; break; } return ESP_OK; @@ -360,12 +369,13 @@ static void http_auth_digest(void) esp_http_client_cleanup(client); } +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void https_with_url(void) { esp_http_client_config_t config = { .url = "https://www.howsmyssl.com", .event_handler = _http_event_handler, - .cert_pem = howsmyssl_com_root_cert_pem_start, + .crt_bundle_attach = esp_crt_bundle_attach, }; esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); @@ -379,6 +389,7 @@ static void https_with_url(void) } esp_http_client_cleanup(client); } +#endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void https_with_hostname_path(void) { @@ -445,6 +456,7 @@ static void http_redirect_to_https(void) esp_http_client_config_t config = { .url = "http://httpbin.org/redirect-to?url=https%3A%2F%2Fwww.howsmyssl.com", .event_handler = _http_event_handler, + .cert_pem = howsmyssl_com_root_cert_pem_start, }; esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); @@ -521,6 +533,7 @@ static void https_async(void) .event_handler = _http_event_handler, .is_async = true, .timeout_ms = 5000, + .cert_pem = postman_echo_com_root_cert_pem_start, }; esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err; @@ -618,7 +631,7 @@ static void http_native_request(void) } int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER); if (data_read >= 0) { - ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d", + ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d", esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer)); @@ -629,11 +642,13 @@ static void http_native_request(void) esp_http_client_cleanup(client); } +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void http_partial_download(void) { esp_http_client_config_t config = { - .url = "http://jigsaw.w3.org/HTTP/TE/foo.txt", + .url = "https://dl.espressif.com/dl/esp-idf/ci/esp_http_client_demo.txt", .event_handler = _http_event_handler, + .crt_bundle_attach = esp_crt_bundle_attach, }; esp_http_client_handle_t client = esp_http_client_init(&config); @@ -672,6 +687,7 @@ static void http_partial_download(void) esp_http_client_cleanup(client); } +#endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void http_test_task(void *pvParameters) { @@ -684,7 +700,9 @@ static void http_test_task(void *pvParameters) http_auth_digest(); http_relative_redirect(); http_absolute_redirect(); +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE https_with_url(); +#endif https_with_hostname_path(); http_redirect_to_https(); http_download_chunk(); @@ -692,7 +710,9 @@ static void http_test_task(void *pvParameters) https_async(); https_with_invalid_url(); http_native_request(); +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE http_partial_download(); +#endif ESP_LOGI(TAG, "Finish http example"); vTaskDelete(NULL); diff --git a/examples/protocols/esp_http_client/main/postman_echo_com_root_cert.pem b/examples/protocols/esp_http_client/main/postman_echo_com_root_cert.pem new file mode 100644 index 000000000000..4bb70093a996 --- /dev/null +++ b/examples/protocols/esp_http_client/main/postman_echo_com_root_cert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV +BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw +MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp +ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/ +y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N +Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo +Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C +zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J +Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB +AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O +BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV +rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u +c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud +HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG +BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G +VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1 +l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt +8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ +59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu +VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w= +-----END CERTIFICATE----- diff --git a/examples/protocols/http2_request/README.md b/examples/protocols/http2_request/README.md index 808d595427b4..e7be3a83efc1 100644 --- a/examples/protocols/http2_request/README.md +++ b/examples/protocols/http2_request/README.md @@ -1,6 +1,55 @@ # HTTP/2 Request Example -Established HTTP/2 connection with https://http2.golang.org -- Performs a GET on /clockstream -- Performs a PUT on /ECHO +Establish an HTTP/2 connection with https://http2.github.io +- Performs a GET on /index.html +## How to use example +Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. + +### Hardware Required + +* A development board with ESP32/ESP32-S2/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for power supply and programming + +### Configure the project + +``` +idf.py menuconfig +``` +Open the project configuration menu (`idf.py menuconfig`) to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (5609) example_connect: - IPv4 address: 192.168.0.103 +I (5609) example_connect: - IPv6 address: fe80:0000:0000:0000:ae67:b2ff:fe45:0194, type: ESP_IP6_ADDR_IS_LINK_LOCAL +Connecting to server +Connection done +[get-response] + +. +. +. +Body of index.html +. +. +. +. + +[get-response] Frame fully received +[get-response] Stream Closed +``` diff --git a/examples/protocols/http2_request/components/sh2lib/sh2lib.c b/examples/protocols/http2_request/components/sh2lib/sh2lib.c index 364fdec79449..8f298c4bcc51 100644 --- a/examples/protocols/http2_request/components/sh2lib/sh2lib.c +++ b/examples/protocols/http2_request/components/sh2lib/sh2lib.c @@ -235,27 +235,35 @@ static int do_http2_connect(struct sh2lib_handle *hd) return 0; } -int sh2lib_connect(struct sh2lib_handle *hd, const char *uri) +int sh2lib_connect(struct sh2lib_config_t *cfg, struct sh2lib_handle *hd) { memset(hd, 0, sizeof(*hd)); + + if (cfg == NULL) { + ESP_LOGE(TAG, "[sh2-connect] pointer to sh2lib configurations cannot be NULL"); + goto error; + } + const char *proto[] = {"h2", NULL}; esp_tls_cfg_t tls_cfg = { .alpn_protos = proto, + .cacert_buf = cfg->cacert_buf, + .cacert_bytes = cfg->cacert_bytes, .non_block = true, .timeout_ms = 10 * 1000, }; - if ((hd->http2_tls = esp_tls_conn_http_new(uri, &tls_cfg)) == NULL) { + if ((hd->http2_tls = esp_tls_conn_http_new(cfg->uri, &tls_cfg)) == NULL) { ESP_LOGE(TAG, "[sh2-connect] esp-tls connection failed"); goto error; } struct http_parser_url u; http_parser_url_init(&u); - http_parser_parse_url(uri, strlen(uri), 0, &u); - hd->hostname = strndup(&uri[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len); + http_parser_parse_url(cfg->uri, strlen(cfg->uri), 0, &u); + hd->hostname = strndup(&cfg->uri[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len); /* HTTP/2 Connection */ if (do_http2_connect(hd) != 0) { - ESP_LOGE(TAG, "[sh2-connect] HTTP2 Connection failed with %s", uri); + ESP_LOGE(TAG, "[sh2-connect] HTTP2 Connection failed with %s", cfg->uri); goto error; } diff --git a/examples/protocols/http2_request/components/sh2lib/sh2lib.h b/examples/protocols/http2_request/components/sh2lib/sh2lib.h index f67137695ca4..78733a0b0ec9 100644 --- a/examples/protocols/http2_request/components/sh2lib/sh2lib.h +++ b/examples/protocols/http2_request/components/sh2lib/sh2lib.h @@ -38,6 +38,15 @@ struct sh2lib_handle { struct esp_tls *http2_tls; /*!< Pointer to the TLS session handle */ }; +/** + * @brief sh2lib configuration structure + */ +struct sh2lib_config_t { + const char *uri; /*!< Pointer to the URI that should be connected to */ + const unsigned char *cacert_buf; /*!< Pointer to the buffer containing CA certificate */ + unsigned int cacert_bytes; /*!< Size of the CA certifiacte pointed by cacert_buf */ +}; + /** Flag indicating receive stream is reset */ #define DATA_RECV_RST_STREAM 1 /** Flag indicating frame is completely received */ @@ -88,14 +97,13 @@ typedef int (*sh2lib_putpost_data_cb_t)(struct sh2lib_handle *handle, char *data * * Only 'https' URIs are supported. * + * @param[in] cfg Pointer to the sh2lib configurations of the type 'struct sh2lib_config_t'. * @param[out] hd Pointer to a variable of the type 'struct sh2lib_handle'. - * @param[in] uri Pointer to the URI that should be connected to. - * * @return * - ESP_OK if the connection was successful * - ESP_FAIL if the connection fails */ -int sh2lib_connect(struct sh2lib_handle *hd, const char *uri); +int sh2lib_connect(struct sh2lib_config_t *cfg, struct sh2lib_handle *hd); /** * @brief Free a sh2lib handle diff --git a/examples/protocols/http2_request/main/CMakeLists.txt b/examples/protocols/http2_request/main/CMakeLists.txt index 40f03c88004b..a450362baad1 100644 --- a/examples/protocols/http2_request/main/CMakeLists.txt +++ b/examples/protocols/http2_request/main/CMakeLists.txt @@ -1,2 +1,3 @@ idf_component_register(SRCS "http2_request_example_main.c" - INCLUDE_DIRS ".") + INCLUDE_DIRS "." + EMBED_TXTFILES "http2_github_io_root_cert.pem") diff --git a/examples/protocols/http2_request/main/component.mk b/examples/protocols/http2_request/main/component.mk index e69de29bb2d1..bbe96a05f93a 100644 --- a/examples/protocols/http2_request/main/component.mk +++ b/examples/protocols/http2_request/main/component.mk @@ -0,0 +1,5 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) +COMPONENT_EMBED_TXTFILES := http2_github_io_root_cert.pem diff --git a/examples/protocols/http2_request/main/http2_github_io_root_cert.pem b/examples/protocols/http2_request/main/http2_github_io_root_cert.pem new file mode 100644 index 000000000000..8c4c74105869 --- /dev/null +++ b/examples/protocols/http2_request/main/http2_github_io_root_cert.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy +YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2 +4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC +Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1 +itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn +4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X +sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft +bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA +MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy +dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t +L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG +BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ +UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D +aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd +aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH +E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly +/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu +xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF +0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae +cPUeybQ= +-----END CERTIFICATE----- diff --git a/examples/protocols/http2_request/main/http2_request_example_main.c b/examples/protocols/http2_request/main/http2_request_example_main.c index 0dc6dfd124c9..5dce7dbbda5d 100644 --- a/examples/protocols/http2_request/main/http2_request_example_main.c +++ b/examples/protocols/http2_request/main/http2_request_example_main.c @@ -1,6 +1,6 @@ /* HTTP2 GET Example using nghttp2 - Contacts http2.golang.org and executes the GET/PUT requests. A thin API + Contacts http2.github.io and executes the GET request. A thin API wrapper on top of nghttp2, to properly demonstrate the interactions. This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -26,12 +26,13 @@ #include "sh2lib.h" +extern const uint8_t server_root_cert_pem_start[] asm("_binary_http2_github_io_root_cert_pem_start"); +extern const uint8_t server_root_cert_pem_end[] asm("_binary_http2_github_io_root_cert_pem_end"); + /* The HTTP/2 server to connect to */ -#define HTTP2_SERVER_URI "https://http2.golang.org" +#define HTTP2_SERVER_URI "https://http2.github.io" /* A GET request that keeps streaming current time every second */ -#define HTTP2_STREAMING_GET_PATH "/clockstream" -/* A PUT request that echoes whatever we had sent to it */ -#define HTTP2_PUT_PATH "/ECHO" +#define HTTP2_STREAMING_GET_PATH "/index.html" int handle_get_response(struct sh2lib_handle *handle, const char *data, size_t len, int flags) @@ -101,8 +102,14 @@ static void http2_task(void *args) /* HTTP2: one connection multiple requests. Do the TLS/TCP connection first */ printf("Connecting to server\n"); + struct sh2lib_config_t cfg = { + .uri = HTTP2_SERVER_URI, + .cacert_buf = server_root_cert_pem_start, + .cacert_bytes = server_root_cert_pem_end - server_root_cert_pem_start, + }; struct sh2lib_handle hd; - if (sh2lib_connect(&hd, HTTP2_SERVER_URI) != 0) { + + if (sh2lib_connect(&cfg, &hd) != 0) { printf("Failed to connect\n"); vTaskDelete(NULL); return; @@ -111,10 +118,6 @@ static void http2_task(void *args) /* HTTP GET */ sh2lib_do_get(&hd, HTTP2_STREAMING_GET_PATH, handle_get_response); - - /* HTTP PUT */ - sh2lib_do_put(&hd, HTTP2_PUT_PATH, send_put_data, handle_echo_response); - while (1) { /* Process HTTP2 send/receive */ if (sh2lib_execute(&hd) < 0) { diff --git a/examples/protocols/http2_request/sdkconfig.defaults b/examples/protocols/http2_request/sdkconfig.defaults deleted file mode 100644 index a79804293a31..000000000000 --- a/examples/protocols/http2_request/sdkconfig.defaults +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_ESP_TLS_INSECURE=y -CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y diff --git a/examples/protocols/http_server/ws_echo_server/README.md b/examples/protocols/http_server/ws_echo_server/README.md index 8fa421933773..011b14b22a05 100644 --- a/examples/protocols/http_server/ws_echo_server/README.md +++ b/examples/protocols/http_server/ws_echo_server/README.md @@ -6,7 +6,8 @@ This example demonstrates the HTTPD server using the WebSocket feature. ## How to Use Example The example starts a WS server on a local network, so a WS client is needed to interact with the server (an example test -ws_server_example_test.py could be used as a simple WS client). +ws_server_example_test.py could be used as a simple WS client). If you run ws_server_example_test.py and get +`ModuleNotFoundError: No module named 'websocket'`, then please install `websocket` by running `python -m pip install websocket-client`. The server registers WebSocket handler which echoes back the received WebSocket frame. It also demonstrates use of asynchronous send, which is triggered on reception of a certain message. diff --git a/examples/protocols/http_server/ws_echo_server/ws_server_example_test.py b/examples/protocols/http_server/ws_echo_server/ws_server_example_test.py index e44896bd31f3..54bfbfca9975 100644 --- a/examples/protocols/http_server/ws_echo_server/ws_server_example_test.py +++ b/examples/protocols/http_server/ws_echo_server/ws_server_example_test.py @@ -20,9 +20,14 @@ import re import ttfw_idf -import websocket from tiny_test_fw import Utility +try: + import websocket +except ImportError: + print("Please install 'websocket' by running 'python -m pip install websocket-client'") + raise + OPCODE_TEXT = 0x1 OPCODE_BIN = 0x2 OPCODE_PING = 0x9 diff --git a/examples/protocols/https_request/main/https_request_example_main.c b/examples/protocols/https_request/main/https_request_example_main.c index d3331459535c..cf87b33dd305 100644 --- a/examples/protocols/https_request/main/https_request_example_main.c +++ b/examples/protocols/https_request/main/https_request_example_main.c @@ -5,22 +5,13 @@ * * Adapted from the ssl_client1 example in mbedtls. * - * Original Copyright (C) 2006-2016, ARM Limited, All Rights Reserved, Apache 2.0 License. - * Additions Copyright (C) Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD, Apache 2.0 License. + * SPDX-FileCopyrightText: 2006-2016 ARM Limited, All Rights Reserved * + * SPDX-License-Identifier: Apache-2.0 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-FileContributor: 2015-2022 Espressif Systems (Shanghai) CO LTD */ + #include #include #include "freertos/FreeRTOS.h" @@ -41,7 +32,9 @@ #include "lwip/dns.h" #include "esp_tls.h" +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE #include "esp_crt_bundle.h" +#endif /* Constants that aren't configurable in menuconfig */ #define WEB_SERVER "www.howsmyssl.com" @@ -134,6 +127,7 @@ static void https_get_request(esp_tls_cfg_t cfg) } } +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void https_get_request_using_crt_bundle(void) { ESP_LOGI(TAG, "https_request using crt bundle"); @@ -142,6 +136,7 @@ static void https_get_request_using_crt_bundle(void) }; https_get_request(cfg); } +#endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void https_get_request_using_cacert_buf(void) { @@ -173,7 +168,9 @@ static void https_request_task(void *pvparameters) { ESP_LOGI(TAG, "Start https_request example"); +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE https_get_request_using_crt_bundle(); +#endif https_get_request_using_cacert_buf(); https_get_request_using_global_ca_store(); diff --git a/examples/protocols/icmp_echo/main/echo_example_main.c b/examples/protocols/icmp_echo/main/echo_example_main.c index 86e3884c1765..b4044b660ebc 100644 --- a/examples/protocols/icmp_echo/main/echo_example_main.c +++ b/examples/protocols/icmp_echo/main/echo_example_main.c @@ -204,6 +204,9 @@ void app_main(void) #elif CONFIG_ESP_CONSOLE_USB_CDC esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &s_repl)); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl)); #endif /* register command `ping` */ diff --git a/examples/protocols/modbus/serial/mb_master/main/master.c b/examples/protocols/modbus/serial/mb_master/main/master.c index 6b71a5747d2f..e944c2ef3443 100644 --- a/examples/protocols/modbus/serial/mb_master/main/master.c +++ b/examples/protocols/modbus/serial/mb_master/main/master.c @@ -38,14 +38,6 @@ #define POLL_TIMEOUT_MS (1) #define POLL_TIMEOUT_TICS (POLL_TIMEOUT_MS / portTICK_RATE_MS) -#define MASTER_TAG "MASTER_TEST" - -#define MASTER_CHECK(a, ret_val, str, ...) \ - if (!(a)) { \ - ESP_LOGE(MASTER_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return (ret_val); \ - } - // The macro to get offset for parameter in the appropriate structure #define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1)) #define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1)) @@ -57,6 +49,8 @@ // Options can be used as bit masks or parameter limits #define OPTS(min_val, max_val, step_val) { .opt1 = min_val, .opt2 = max_val, .opt3 = step_val } +static const char *TAG = "MASTER_TEST"; + // Enumeration of modbus device addresses accessed by master device enum { MB_DEVICE_ADDR1 = 1 // Only one slave device used for the test (add other slave addresses here) @@ -135,7 +129,7 @@ static void* master_get_param_data(const mb_parameter_descriptor_t* param_descri break; } } else { - ESP_LOGE(MASTER_TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid); + ESP_LOGE(TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid); assert(instance_ptr != NULL); } return instance_ptr; @@ -149,7 +143,7 @@ static void master_operation_func(void *arg) bool alarm_state = false; const mb_parameter_descriptor_t* param_descriptor = NULL; - ESP_LOGI(MASTER_TAG, "Start modbus test..."); + ESP_LOGI(TAG, "Start modbus test..."); for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++) { // Read all found characteristics from slave(s) @@ -169,7 +163,7 @@ static void master_operation_func(void *arg) err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key, (uint8_t*)temp_data_ptr, &type); if (err == ESP_OK) { - ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = (0x%08x) read successful.", + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%08x) read successful.", param_descriptor->cid, (char*)param_descriptor->param_key, (char*)param_descriptor->param_units, @@ -181,13 +175,13 @@ static void master_operation_func(void *arg) err = mbc_master_set_parameter(cid, (char*)param_descriptor->param_key, (uint8_t*)temp_data_ptr, &type); if (err == ESP_OK) { - ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = (0x%08x), write successful.", + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%08x), write successful.", param_descriptor->cid, (char*)param_descriptor->param_key, (char*)param_descriptor->param_units, *(uint32_t*)temp_data_ptr); } else { - ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).", + ESP_LOGE(TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).", param_descriptor->cid, (char*)param_descriptor->param_key, (int)err, @@ -195,7 +189,7 @@ static void master_operation_func(void *arg) } } } else { - ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", + ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", param_descriptor->cid, (char*)param_descriptor->param_key, (int)err, @@ -208,7 +202,7 @@ static void master_operation_func(void *arg) *(float*)temp_data_ptr = value; if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) || (param_descriptor->mb_param_type == MB_PARAM_INPUT)) { - ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.", + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.", param_descriptor->cid, (char*)param_descriptor->param_key, (char*)param_descriptor->param_units, @@ -222,7 +216,7 @@ static void master_operation_func(void *arg) } else { uint16_t state = *(uint16_t*)temp_data_ptr; const char* rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF"; - ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.", + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.", param_descriptor->cid, (char*)param_descriptor->param_key, (char*)param_descriptor->param_units, @@ -234,7 +228,7 @@ static void master_operation_func(void *arg) } } } else { - ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", + ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", param_descriptor->cid, (char*)param_descriptor->param_key, (int)err, @@ -248,13 +242,13 @@ static void master_operation_func(void *arg) } if (alarm_state) { - ESP_LOGI(MASTER_TAG, "Alarm triggered by cid #%d.", + ESP_LOGI(TAG, "Alarm triggered by cid #%d.", param_descriptor->cid); } else { - ESP_LOGE(MASTER_TAG, "Alarm is not triggered after %d retries.", + ESP_LOGE(TAG, "Alarm is not triggered after %d retries.", MASTER_MAX_RETRY); } - ESP_LOGI(MASTER_TAG, "Destroy master..."); + ESP_LOGI(TAG, "Destroy master..."); ESP_ERROR_CHECK(mbc_master_destroy()); } @@ -275,38 +269,38 @@ static esp_err_t master_init(void) void* master_handler = NULL; esp_err_t err = mbc_master_init(MB_PORT_SERIAL_MASTER, &master_handler); - MASTER_CHECK((master_handler != NULL), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, TAG, "mb controller initialization fail."); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mb controller initialization fail, returns(0x%x).", (uint32_t)err); err = mbc_master_setup((void*)&comm); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mb controller setup fail, returns(0x%x).", (uint32_t)err); // Set UART pin numbers err = uart_set_pin(MB_PORT_NUM, CONFIG_MB_UART_TXD, CONFIG_MB_UART_RXD, CONFIG_MB_UART_RTS, UART_PIN_NO_CHANGE); + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, + "mb serial set pin failure, uart_set_pin() returned (0x%x).", (uint32_t)err); err = mbc_master_start(); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mb controller start fail, returns(0x%x).", (uint32_t)err); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, - "mb serial set pin failure, uart_set_pin() returned (0x%x).", (uint32_t)err); // Set driver mode to Half Duplex err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mb serial set mode failure, uart_set_mode() returned (0x%x).", (uint32_t)err); vTaskDelay(5); err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mb controller set descriptor fail, returns(0x%x).", (uint32_t)err); - ESP_LOGI(MASTER_TAG, "Modbus master stack initialized..."); + ESP_LOGI(TAG, "Modbus master stack initialized..."); return err; } diff --git a/examples/protocols/modbus/serial/mb_slave/main/slave.c b/examples/protocols/modbus/serial/mb_slave/main/slave.c index 30f3a3858026..1c6b431440c4 100644 --- a/examples/protocols/modbus/serial/mb_slave/main/slave.c +++ b/examples/protocols/modbus/serial/mb_slave/main/slave.c @@ -40,7 +40,7 @@ | MB_EVENT_COILS_WR) #define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK) -static const char *SLAVE_TAG = "SLAVE_TEST"; +static const char *TAG = "SLAVE_TEST"; static portMUX_TYPE param_lock = portMUX_INITIALIZER_UNLOCKED; @@ -92,7 +92,7 @@ void app_main(void) mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure // Set UART log level - esp_log_level_set(SLAVE_TAG, ESP_LOG_INFO); + esp_log_level_set(TAG, ESP_LOG_INFO); void* mbc_slave_handler = NULL; ESP_ERROR_CHECK(mbc_slave_init(MB_PORT_SERIAL_SLAVE, &mbc_slave_handler)); // Initialization of Modbus controller @@ -166,8 +166,8 @@ void app_main(void) // Set UART driver mode to Half Duplex ESP_ERROR_CHECK(uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX)); - ESP_LOGI(SLAVE_TAG, "Modbus slave stack initialized."); - ESP_LOGI(SLAVE_TAG, "Start modbus test..."); + ESP_LOGI(TAG, "Modbus slave stack initialized."); + ESP_LOGI(TAG, "Start modbus test..."); // The cycle below will be terminated when parameter holdingRegParams.dataChan0 // incremented each access cycle reaches the CHAN_DATA_MAX_VAL value. @@ -180,7 +180,7 @@ void app_main(void) if(event & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) { // Get parameter information from parameter queue ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", rw_str, (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, @@ -198,7 +198,7 @@ void app_main(void) } } else if (event & MB_EVENT_INPUT_REG_RD) { ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, (uint32_t)reg_info.type, @@ -206,7 +206,7 @@ void app_main(void) (uint32_t)reg_info.size); } else if (event & MB_EVENT_DISCRETE_RD) { ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, (uint32_t)reg_info.type, @@ -214,7 +214,7 @@ void app_main(void) (uint32_t)reg_info.size); } else if (event & (MB_EVENT_COILS_RD | MB_EVENT_COILS_WR)) { ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", rw_str, (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, @@ -225,7 +225,7 @@ void app_main(void) } } // Destroy of Modbus controller on alarm - ESP_LOGI(SLAVE_TAG,"Modbus controller destroyed."); + ESP_LOGI(TAG,"Modbus controller destroyed."); vTaskDelay(100); ESP_ERROR_CHECK(mbc_slave_destroy()); } diff --git a/examples/protocols/modbus/tcp/example_test.py b/examples/protocols/modbus/tcp/example_test.py index 17c8226662eb..46e4f8a68fca 100644 --- a/examples/protocols/modbus/tcp/example_test.py +++ b/examples/protocols/modbus/tcp/example_test.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + import logging import os import re @@ -69,7 +72,7 @@ def __init__(self, dut=None, name=None, ip_addr=None, expect=None): super(DutTestThread, self).__init__() def __enter__(self): - logger.debug('Restart %s.' % self.tname) + logger.debug('Restart %s.', self.tname) # Reset DUT first self.dut.reset() # Capture output from the DUT @@ -80,7 +83,7 @@ def __exit__(self, exc_type, exc_value, traceback): """ The exit method of context manager """ if exc_type is not None or exc_value is not None: - logger.info('Thread %s rised an exception type: %s, value: %s' % (self.tname, str(exc_type), str(exc_value))) + logger.info('Thread %s rised an exception type: %s, value: %s', self.tname, str(exc_type), str(exc_value)) def run(self): """ The function implements thread functionality @@ -95,7 +98,7 @@ def run(self): # Check DUT exceptions dut_exceptions = self.dut.get_exceptions() if 'Guru Meditation Error:' in dut_exceptions: - raise Exception('%s generated an exception: %s\n' % (str(self.dut), dut_exceptions)) + raise RuntimeError('%s generated an exception(s): %s\n' % (str(self.dut), dut_exceptions)) # Mark thread has run to completion without any exceptions self.data = self.dut.stop_capture_raw_data(capture_id=self.dut.name) @@ -106,15 +109,17 @@ def set_ip(self, index=0): message = r'.*Waiting IP([0-9]{1,2}) from stdin.*' # Read all data from previous restart to get prompt correctly self.dut.read() - result = self.dut.expect(re.compile(message), TEST_EXPECT_STR_TIMEOUT) + result = self.dut.expect(re.compile(message), timeout=TEST_EXPECT_STR_TIMEOUT) if int(result[0]) != index: - raise Exception('Incorrect index of IP=%d for %s\n' % (int(result[0]), str(self.dut))) - message = 'IP%s=%s' % (result[0], self.ip_addr) - self.dut.write(message, '\r\n', False) - logger.debug('Sent message for %s: %s' % (self.tname, message)) + raise RuntimeError('Incorrect index of IP=%s for %s\n' % (result[0], str(self.dut))) + # Use the same slave IP address for all characteristics during the test + self.dut.write('IP0=' + self.ip_addr, '\n', False) + self.dut.write('IP1=' + self.ip_addr, '\n', False) + self.dut.write('IP2=' + self.ip_addr, '\n', False) + logger.debug('Set IP address=%s for %s', self.ip_addr, self.tname) message = r'.*IP\([0-9]+\) = \[([0-9a-zA-Z\.\:]+)\] set from stdin.*' - result = self.dut.expect(re.compile(message), TEST_EXPECT_STR_TIMEOUT) - logger.debug('Thread %s initialized with slave IP (%s).' % (self.tname, result[0])) + result = self.dut.expect(re.compile(message), timeout=TEST_EXPECT_STR_TIMEOUT) + logger.debug('Thread %s initialized with slave IP=%s.', self.tname, self.ip_addr) def test_start(self, timeout_value): """ The method to initialize and handle test stages @@ -122,37 +127,37 @@ def test_start(self, timeout_value): def handle_get_ip4(data): """ Handle get_ip v4 """ - logger.debug('%s[STACK_IPV4]: %s' % (self.tname, str(data))) + logger.debug('%s[STACK_IPV4]: %s', self.tname, str(data)) self.test_stage = STACK_IPV4 def handle_get_ip6(data): """ Handle get_ip v6 """ - logger.debug('%s[STACK_IPV6]: %s' % (self.tname, str(data))) + logger.debug('%s[STACK_IPV6]: %s', self.tname, str(data)) self.test_stage = STACK_IPV6 def handle_init(data): """ Handle init """ - logger.debug('%s[STACK_INIT]: %s' % (self.tname, str(data))) + logger.debug('%s[STACK_INIT]: %s', self.tname, str(data)) self.test_stage = STACK_INIT def handle_connect(data): """ Handle connect """ - logger.debug('%s[STACK_CONNECT]: %s' % (self.tname, str(data))) + logger.debug('%s[STACK_CONNECT]: %s', self.tname, str(data)) self.test_stage = STACK_CONNECT def handle_test_start(data): """ Handle connect """ - logger.debug('%s[STACK_START]: %s' % (self.tname, str(data))) + logger.debug('%s[STACK_START]: %s', self.tname, str(data)) self.test_stage = STACK_START def handle_par_ok(data): """ Handle parameter ok """ - logger.debug('%s[READ_PAR_OK]: %s' % (self.tname, str(data))) + logger.debug('%s[READ_PAR_OK]: %s', self.tname, str(data)) if self.test_stage >= STACK_START: self.param_ok_count += 1 self.test_stage = STACK_PAR_OK @@ -160,14 +165,14 @@ def handle_par_ok(data): def handle_par_fail(data): """ Handle parameter fail """ - logger.debug('%s[READ_PAR_FAIL]: %s' % (self.tname, str(data))) + logger.debug('%s[READ_PAR_FAIL]: %s', self.tname, str(data)) self.param_fail_count += 1 self.test_stage = STACK_PAR_FAIL def handle_destroy(data): """ Handle destroy """ - logger.debug('%s[DESTROY]: %s' % (self.tname, str(data))) + logger.debug('%s[DESTROY]: %s', self.tname, str(data)) self.test_stage = STACK_DESTROY self.test_finish = True @@ -183,7 +188,7 @@ def handle_destroy(data): (re.compile(self.expected[STACK_DESTROY]), handle_destroy), timeout=timeout_value) except DUT.ExpectTimeout: - logger.debug('%s, expect timeout on stage #%d (%s seconds)' % (self.tname, self.test_stage, timeout_value)) + logger.debug('%s, expect timeout on stage #%d (%s seconds)', self.tname, self.test_stage, timeout_value) self.test_finish = True @@ -193,14 +198,14 @@ def test_check_mode(dut=None, mode_str=None, value=None): global logger try: opt = dut.app.get_sdkconfig()[mode_str] - logger.debug('%s {%s} = %s.\n' % (str(dut), mode_str, opt)) + logger.debug('%s {%s} = %s.\n', str(dut), mode_str, opt) return value == opt except Exception: - logger.error('ENV_TEST_FAILURE: %s: Cannot find option %s in sdkconfig.' % (str(dut), mode_str)) + logger.error('ENV_TEST_FAILURE: %s: Cannot find option %s in sdkconfig.', str(dut), mode_str) return False -@ttfw_idf.idf_example_test(env_tag='Example_Modbus_TCP') +@ttfw_idf.idf_example_test(env_tag='Example_Modbus_TCP', target=['esp32']) def test_modbus_communication(env, comm_mode): global logger @@ -235,7 +240,7 @@ def test_modbus_communication(env, comm_mode): master_name = TEST_MASTER_TCP else: logger.error('ENV_TEST_FAILURE: IP resolver mode do not match in the master and slave implementation.\n') - raise Exception('ENV_TEST_FAILURE: IP resolver mode do not match in the master and slave implementation.\n') + raise RuntimeError('ENV_TEST_FAILURE: IP resolver mode do not match in the master and slave implementation.\n') address = None if test_check_mode(dut_master, 'CONFIG_MB_SLAVE_IP_FROM_STDIN', 'y'): logger.info('ENV_TEST_INFO: Set slave IP address through STDIN.\n') @@ -249,9 +254,9 @@ def test_modbus_communication(env, comm_mode): if address is not None: print('Found IP slave address: %s' % address[0]) else: - raise Exception('ENV_TEST_FAILURE: Slave IP address is not found in the output. Check network settings.\n') + raise RuntimeError('ENV_TEST_FAILURE: Slave IP address is not found in the output. Check network settings.\n') else: - raise Exception('ENV_TEST_FAILURE: Slave IP resolver is not configured correctly.\n') + raise RuntimeError('ENV_TEST_FAILURE: Slave IP resolver is not configured correctly.\n') # Create thread for each dut with DutTestThread(dut=dut_master, name=master_name, ip_addr=address[0], expect=pattern_dict_master) as dut_master_thread: @@ -265,32 +270,32 @@ def test_modbus_communication(env, comm_mode): dut_slave_thread.join(timeout=TEST_THREAD_JOIN_TIMEOUT) dut_master_thread.join(timeout=TEST_THREAD_JOIN_TIMEOUT) - if dut_slave_thread.isAlive(): - logger.error('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' % - (dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT)) - raise Exception('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' % - (dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT)) - - if dut_master_thread.isAlive(): - logger.error('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' % - (dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT)) - raise Exception('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' % - (dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT)) - - logger.info('TEST_INFO: %s error count = %d, %s error count = %d.\n' % - (dut_master_thread.tname, dut_master_thread.param_fail_count, - dut_slave_thread.tname, dut_slave_thread.param_fail_count)) - logger.info('TEST_INFO: %s ok count = %d, %s ok count = %d.\n' % - (dut_master_thread.tname, dut_master_thread.param_ok_count, - dut_slave_thread.tname, dut_slave_thread.param_ok_count)) + if dut_slave_thread.is_alive(): + logger.error('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n', + dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT) + raise RuntimeError('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' % + (dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT)) + + if dut_master_thread.is_alive(): + logger.error('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n', + dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT) + raise RuntimeError('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' % + (dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT)) + + logger.info('TEST_INFO: %s error count = %d, %s error count = %d.\n', + dut_master_thread.tname, dut_master_thread.param_fail_count, + dut_slave_thread.tname, dut_slave_thread.param_fail_count) + logger.info('TEST_INFO: %s ok count = %d, %s ok count = %d.\n', + dut_master_thread.tname, dut_master_thread.param_ok_count, + dut_slave_thread.tname, dut_slave_thread.param_ok_count) if ((dut_master_thread.param_fail_count > TEST_READ_MAX_ERR_COUNT) or (dut_slave_thread.param_fail_count > TEST_READ_MAX_ERR_COUNT) or (dut_slave_thread.param_ok_count == 0) or (dut_master_thread.param_ok_count == 0)): - raise Exception('TEST_FAILURE: %s parameter read error(ok) count = %d(%d), %s parameter read error(ok) count = %d(%d).\n' % - (dut_master_thread.tname, dut_master_thread.param_fail_count, dut_master_thread.param_ok_count, - dut_slave_thread.tname, dut_slave_thread.param_fail_count, dut_slave_thread.param_ok_count)) + raise RuntimeError('TEST_FAILURE: %s parameter read error(ok) count = %d(%d), %s parameter read error(ok) count = %d(%d).\n' % + (dut_master_thread.tname, dut_master_thread.param_fail_count, dut_master_thread.param_ok_count, + dut_slave_thread.tname, dut_slave_thread.param_fail_count, dut_slave_thread.param_ok_count)) logger.info('TEST_SUCCESS: The Modbus parameter test is completed successfully.\n') finally: diff --git a/examples/protocols/modbus/tcp/mb_tcp_master/main/tcp_master.c b/examples/protocols/modbus/tcp/mb_tcp_master/main/tcp_master.c index 2a397d00ab12..b0cb83095aa9 100644 --- a/examples/protocols/modbus/tcp/mb_tcp_master/main/tcp_master.c +++ b/examples/protocols/modbus/tcp/mb_tcp_master/main/tcp_master.c @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "string.h" +// FreeModbus Master Example ESP32 + +#include +#include #include "esp_log.h" #include "esp_system.h" #include "esp_wifi.h" @@ -44,14 +47,6 @@ #define POLL_TIMEOUT_TICS (POLL_TIMEOUT_MS / portTICK_RATE_MS) #define MB_MDNS_PORT (502) -#define MASTER_TAG "MASTER_TEST" - -#define MASTER_CHECK(a, ret_val, str, ...) \ - if (!(a)) { \ - ESP_LOGE(MASTER_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return (ret_val); \ - } - // The macro to get offset for parameter in the appropriate structure #define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1)) #define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1)) @@ -76,12 +71,14 @@ #endif #define MB_MDNS_INSTANCE(pref) pref"mb_master_tcp" +static const char *TAG = "MASTER_TEST"; // Enumeration of modbus device addresses accessed by master device // Each address in the table is a index of TCP slave ip address in mb_communication_info_t::tcp_ip_addr table enum { MB_DEVICE_ADDR1 = 1, // Slave address 1 - MB_DEVICE_COUNT + MB_DEVICE_ADDR2 = 200, + MB_DEVICE_ADDR3 = 35 }; // Enumeration of all supported CIDs for device (used in parameter definition table) @@ -114,11 +111,11 @@ const mb_parameter_descriptor_t device_parameters[] = { HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, { CID_INP_DATA_1, STR("Temperature_1"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 2, 2, INPUT_OFFSET(input_data1), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, - { CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 2, 2, + { CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR2, MB_PARAM_HOLDING, 2, 2, HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, - { CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 4, 2, + { CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR2, MB_PARAM_INPUT, 4, 2, INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, - { CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 4, 2, + { CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR3, MB_PARAM_HOLDING, 4, 2, HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER }, { CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 0, 8, COIL_OFFSET(coils_port0), PARAM_TYPE_U16, 2, OPTS( BIT1, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER }, @@ -127,20 +124,26 @@ const mb_parameter_descriptor_t device_parameters[] = { }; // Calculate number of parameters in the table -const uint16_t num_device_parameters = (sizeof(device_parameters)/sizeof(device_parameters[0])); +const uint16_t num_device_parameters = (sizeof(device_parameters) / sizeof(device_parameters[0])); // This table represents slave IP addresses that correspond to the short address field of the slave in device_parameters structure // Modbus TCP stack shall use these addresses to be able to connect and read parameters from slave -char* slave_ip_address_table[MB_DEVICE_COUNT] = { +char* slave_ip_address_table[] = { #if CONFIG_MB_SLAVE_IP_FROM_STDIN "FROM_STDIN", // Address corresponds to MB_DEVICE_ADDR1 and set to predefined value by user - NULL + "FROM_STDIN", // Corresponds to characteristic MB_DEVICE_ADDR2 + "FROM_STDIN", // Corresponds to characteristic MB_DEVICE_ADDR3 + NULL // End of table condition (must be included) #elif CONFIG_MB_MDNS_IP_RESOLVER + NULL, + NULL, NULL, NULL #endif }; +const size_t ip_table_sz = (size_t)(sizeof(slave_ip_address_table) / sizeof(slave_ip_address_table[0])); + #if CONFIG_MB_SLAVE_IP_FROM_STDIN // Scan IP address according to IPV settings @@ -191,8 +194,8 @@ static int master_get_slave_ip_stdin(char** addr_table) fputc('\n', stdout); ip_str = master_scan_addr(&index, buf); if (ip_str != NULL) { - ESP_LOGI(MASTER_TAG, "IP(%d) = [%s] set from stdin.", ip_cnt, ip_str); - if ((ip_cnt >= MB_DEVICE_COUNT) || (index != ip_cnt)) { + ESP_LOGI(TAG, "IP(%d) = [%s] set from stdin.", ip_cnt, ip_str); + if ((ip_cnt >= ip_table_sz) || (index != ip_cnt)) { addr_table[ip_cnt] = NULL; break; } @@ -204,10 +207,10 @@ static int master_get_slave_ip_stdin(char** addr_table) } } else { if (addr_table[ip_cnt]) { - ESP_LOGI(MASTER_TAG, "Leave IP(%d) = [%s] set manually.", ip_cnt, addr_table[ip_cnt]); + ESP_LOGI(TAG, "Leave IP(%d) = [%s] set manually.", ip_cnt, addr_table[ip_cnt]); ip_cnt++; } else { - ESP_LOGI(MASTER_TAG, "IP(%d) is not set in the table.", ip_cnt); + ESP_LOGI(TAG, "IP(%d) is not set in the table.", ip_cnt); break; } } @@ -217,6 +220,16 @@ static int master_get_slave_ip_stdin(char** addr_table) #elif CONFIG_MB_MDNS_IP_RESOLVER +typedef struct slave_addr_entry_s { + uint16_t index; + char* ip_address; + uint8_t slave_addr; + void* p_data; + LIST_ENTRY(slave_addr_entry_s) entries; +} slave_addr_entry_t; + +LIST_HEAD(slave_addr_, slave_addr_entry_s) slave_addr_list = LIST_HEAD_INITIALIZER(slave_addr_list); + // convert MAC from binary format to string static inline char* gen_mac_str(const uint8_t* mac, char* pref, char* mac_str) { @@ -240,7 +253,7 @@ static void master_start_mdns_service() ESP_ERROR_CHECK(mdns_init()); // set mDNS hostname (required if you want to advertise services) ESP_ERROR_CHECK(mdns_hostname_set(hostname)); - ESP_LOGI(MASTER_TAG, "mdns hostname set to: [%s]", hostname); + ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname); // set default mDNS instance name ESP_ERROR_CHECK(mdns_instance_name_set(MB_MDNS_INSTANCE("esp32_"))); @@ -281,15 +294,21 @@ static char* master_get_slave_ip_str(mdns_ip_addr_t* address, mb_tcp_addr_type_t return slave_ip_str; } -static esp_err_t master_resolve_slave(const char* name, mdns_result_t* result, char** resolved_ip, +static esp_err_t master_resolve_slave(uint8_t short_addr, mdns_result_t* result, char** resolved_ip, mb_tcp_addr_type_t addr_type) { - if (!name || !result) { + if (!short_addr || !result || !resolved_ip) { return ESP_ERR_INVALID_ARG; } mdns_result_t* r = result; int t; char* slave_ip = NULL; + char slave_name[22] = {0}; + + if (sprintf(slave_name, "mb_slave_tcp_%02X", short_addr) < 0) { + ESP_LOGE(TAG, "Fail to create instance name for index: %d", short_addr); + abort(); + } for (; r ; r = r->next) { if ((r->ip_protocol == MDNS_IP_PROTOCOL_V4) && (addr_type == MB_IPV6)) { continue; @@ -298,7 +317,7 @@ static esp_err_t master_resolve_slave(const char* name, mdns_result_t* result, c } // Check host name for Modbus short address and // append it into slave ip address table - if ((strcmp(r->instance_name, name) == 0) && (r->port == CONFIG_FMB_TCP_PORT_DEFAULT)) { + if ((strcmp(r->instance_name, slave_name) == 0) && (r->port == CONFIG_FMB_TCP_PORT_DEFAULT)) { printf(" PTR : %s\n", r->instance_name); if (r->txt_count) { printf(" TXT : [%u] ", r->txt_count); @@ -309,92 +328,124 @@ static esp_err_t master_resolve_slave(const char* name, mdns_result_t* result, c } slave_ip = master_get_slave_ip_str(r->addr, addr_type); if (slave_ip) { - ESP_LOGI(MASTER_TAG, "Resolved slave %s[%s]:%u", r->hostname, slave_ip, r->port); + ESP_LOGI(TAG, "Resolved slave %s[%s]:%u", r->hostname, slave_ip, r->port); *resolved_ip = slave_ip; return ESP_OK; } } } *resolved_ip = NULL; - ESP_LOGD(MASTER_TAG, "Fail to resolve slave: %s", name); + ESP_LOGD(TAG, "Fail to resolve slave: %s", slave_name); return ESP_ERR_NOT_FOUND; } static int master_create_slave_list(mdns_result_t* results, char** addr_table, - mb_tcp_addr_type_t addr_type) + int addr_table_size, mb_tcp_addr_type_t addr_type) { if (!results) { return -1; } - int i, addr, resolved = 0; + int i, slave_addr, cid_resolve_cnt = 0; + int ip_index = 0; const mb_parameter_descriptor_t* pdescr = &device_parameters[0]; char** ip_table = addr_table; - char slave_name[22] = {0}; char* slave_ip = NULL; + slave_addr_entry_t *it; - for (i = 0; (i < num_device_parameters && pdescr); i++, pdescr++) { - addr = pdescr->mb_slave_addr; - if (-1 == sprintf(slave_name, "mb_slave_tcp_%02X", addr)) { - ESP_LOGI(MASTER_TAG, "Fail to create instance name for index: %d", addr); - abort(); + for (i = 0; (i < num_device_parameters && pdescr); i++, pdescr++) + { + slave_addr = pdescr->mb_slave_addr; + + it = NULL; + // Is the slave address already registered? + LIST_FOREACH(it, &slave_addr_list, entries) { + if (slave_addr == it->slave_addr) { + break; + } } - if (!ip_table[addr - 1]) { - esp_err_t err = master_resolve_slave(slave_name, results, &slave_ip, addr_type); + if (!it) { + // Resolve new slave IP address using its short address + esp_err_t err = master_resolve_slave(slave_addr, results, &slave_ip, addr_type); if (err != ESP_OK) { - ESP_LOGE(MASTER_TAG, "Index: %d, sl_addr: %d, name:%s, failed to resolve!", - i, addr, slave_name); + ESP_LOGE(TAG, "Index: %d, sl_addr: %d, failed to resolve!", i, slave_addr); // Set correspond index to NULL indicate host not resolved - ip_table[addr - 1] = NULL; + ip_table[ip_index] = NULL; continue; } - ip_table[addr - 1] = slave_ip; //slave_name; - ESP_LOGI(MASTER_TAG, "Index: %d, sl_addr: %d, name:%s, resolve to IP: [%s]", - i, addr, slave_name, slave_ip); - resolved++; + // Register new slave address information + slave_addr_entry_t* new_slave_entry = (slave_addr_entry_t*) heap_caps_malloc(sizeof(slave_addr_entry_t), + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + MB_RETURN_ON_FALSE((new_slave_entry != NULL), ESP_ERR_NO_MEM, + TAG, "Can not allocate memory for slave entry."); + new_slave_entry->index = i; + new_slave_entry->ip_address = slave_ip; + new_slave_entry->slave_addr = slave_addr; + new_slave_entry->p_data = NULL; + LIST_INSERT_HEAD(&slave_addr_list, new_slave_entry, entries); + ip_table[ip_index] = slave_ip; + ESP_LOGI(TAG, "Index: %d, sl_addr: %d, resolved to IP: [%s]", + i, slave_addr, slave_ip); + cid_resolve_cnt++; + if (ip_index < addr_table_size) { + ip_index++; + } } else { - ESP_LOGI(MASTER_TAG, "Index: %d, sl_addr: %d, name:%s, set to IP: [%s]", - i, addr, slave_name, ip_table[addr - 1]); - resolved++; - } - } - return resolved; -} - -static void master_destroy_slave_list(char** table) -{ - for (int i = 0; ((i < MB_DEVICE_COUNT) && table[i] != NULL); i++) { - if (table[i]) { - free(table[i]); - table[i] = NULL; + ip_table[ip_index] = it ? it->ip_address : ip_table[ip_index]; + ESP_LOGI(TAG, "Index: %d, sl_addr: %d, set to IP: [%s]", + i, slave_addr, ip_table[ip_index]); + cid_resolve_cnt++; } } + ESP_LOGI(TAG, "Resolved %d cids, with %d IP addresses", cid_resolve_cnt, ip_index); + return cid_resolve_cnt; } static int master_query_slave_service(const char * service_name, const char * proto, mb_tcp_addr_type_t addr_type) { - ESP_LOGI(MASTER_TAG, "Query PTR: %s.%s.local", service_name, proto); + ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto); mdns_result_t* results = NULL; int count = 0; esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results); if(err){ - ESP_LOGE(MASTER_TAG, "Query Failed: %s", esp_err_to_name(err)); + ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); return count; } if(!results){ - ESP_LOGW(MASTER_TAG, "No results found!"); + ESP_LOGW(TAG, "No results found!"); return count; } - count = master_create_slave_list(results, slave_ip_address_table, addr_type); + count = master_create_slave_list(results, slave_ip_address_table, ip_table_sz, addr_type); mdns_query_results_free(results); return count; } #endif +static void master_destroy_slave_list(char** table, size_t ip_table_size) +{ +#if CONFIG_MB_MDNS_IP_RESOLVER + slave_addr_entry_t *it; + LIST_FOREACH(it, &slave_addr_list, entries) { + LIST_REMOVE(it, entries); + free(it); + } +#endif + for (int i = 0; ((i < ip_table_size) && table[i] != NULL); i++) { + if (table[i]) { +#if CONFIG_MB_SLAVE_IP_FROM_STDIN + free(table[i]); + table[i] = "FROM_STDIN"; +#elif CONFIG_MB_MDNS_IP_RESOLVER + table[i] = NULL; +#endif + } + } +} + // The function to get pointer to parameter storage (instance) according to parameter description table static void* master_get_param_data(const mb_parameter_descriptor_t* param_descriptor) { @@ -420,7 +471,7 @@ static void* master_get_param_data(const mb_parameter_descriptor_t* param_descri break; } } else { - ESP_LOGE(MASTER_TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid); + ESP_LOGE(TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid); assert(instance_ptr != NULL); } return instance_ptr; @@ -434,7 +485,7 @@ static void master_operation_func(void *arg) bool alarm_state = false; const mb_parameter_descriptor_t* param_descriptor = NULL; - ESP_LOGI(MASTER_TAG, "Start modbus test..."); + ESP_LOGI(TAG, "Start modbus test..."); for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++) { // Read all found characteristics from slave(s) @@ -454,7 +505,7 @@ static void master_operation_func(void *arg) *(float*)temp_data_ptr = value; if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) || (param_descriptor->mb_param_type == MB_PARAM_INPUT)) { - ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.", + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.", param_descriptor->cid, (char*)param_descriptor->param_key, (char*)param_descriptor->param_units, @@ -468,7 +519,7 @@ static void master_operation_func(void *arg) } else { uint16_t state = *(uint16_t*)temp_data_ptr; const char* rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF"; - ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.", + ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.", param_descriptor->cid, (char*)param_descriptor->param_key, (char*)param_descriptor->param_units, @@ -480,7 +531,7 @@ static void master_operation_func(void *arg) } } } else { - ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = %d (%s).", + ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = %d (%s).", param_descriptor->cid, (char*)param_descriptor->param_key, (int)err, @@ -493,13 +544,13 @@ static void master_operation_func(void *arg) } if (alarm_state) { - ESP_LOGI(MASTER_TAG, "Alarm triggered by cid #%d.", + ESP_LOGI(TAG, "Alarm triggered by cid #%d.", param_descriptor->cid); } else { - ESP_LOGE(MASTER_TAG, "Alarm is not triggered after %d retries.", + ESP_LOGE(TAG, "Alarm is not triggered after %d retries.", MASTER_MAX_RETRY); } - ESP_LOGI(MASTER_TAG, "Destroy master..."); + ESP_LOGI(TAG, "Destroy master..."); vTaskDelay(100); } @@ -510,15 +561,18 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type) ESP_ERROR_CHECK(nvs_flash_erase()); result = nvs_flash_init(); } - MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "nvs_flash_init fail, returns(0x%x).", (uint32_t)result); result = esp_netif_init(); - MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_netif_init fail, returns(0x%x).", (uint32_t)result); result = esp_event_loop_create_default(); - MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_event_loop_create_default fail, returns(0x%x).", (uint32_t)result); #if CONFIG_MB_MDNS_IP_RESOLVER @@ -529,12 +583,14 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type) // Read "Establishing Wi-Fi or Ethernet Connection" section in // examples/protocols/README.md for more information about this function. result = example_connect(); - MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "example_connect fail, returns(0x%x).", (uint32_t)result); #if CONFIG_EXAMPLE_CONNECT_WIFI result = esp_wifi_set_ps(WIFI_PS_NONE); - MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_wifi_set_ps fail, returns(0x%x).", (uint32_t)result); #endif @@ -544,17 +600,17 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type) res = master_query_slave_service("_modbus", "_tcp", ip_addr_type); } if (res < num_device_parameters) { - ESP_LOGE(MASTER_TAG, "Could not resolve one or more slave IP addresses, resolved: %d out of %d.", res, num_device_parameters ); - ESP_LOGE(MASTER_TAG, "Make sure you configured all slaves according to device parameter table and they alive in the network."); + ESP_LOGE(TAG, "Could not resolve one or more slave IP addresses, resolved: %d out of %d.", res, num_device_parameters ); + ESP_LOGE(TAG, "Make sure you configured all slaves according to device parameter table and they alive in the network."); return ESP_ERR_NOT_FOUND; } mdns_free(); #elif CONFIG_MB_SLAVE_IP_FROM_STDIN int ip_cnt = master_get_slave_ip_stdin(slave_ip_address_table); if (ip_cnt) { - ESP_LOGI(MASTER_TAG, "Configured %d IP addresse(s).", ip_cnt); + ESP_LOGI(TAG, "Configured %d IP addresse(s).", ip_cnt); } else { - ESP_LOGE(MASTER_TAG, "Fail to get IP address from stdin. Continue."); + ESP_LOGE(TAG, "Fail to get IP address from stdin. Continue."); return ESP_ERR_NOT_FOUND; } #endif @@ -564,23 +620,26 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type) static esp_err_t destroy_services(void) { esp_err_t err = ESP_OK; -#if CONFIG_MB_MDNS_IP_RESOLVER - master_destroy_slave_list(slave_ip_address_table); -#endif + master_destroy_slave_list(slave_ip_address_table, ip_table_sz); + err = example_disconnect(); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "example_disconnect fail, returns(0x%x).", (uint32_t)err); err = esp_event_loop_delete_default(); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_event_loop_delete_default fail, returns(0x%x).", (uint32_t)err); err = esp_netif_deinit(); - MASTER_CHECK((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE, + TAG, "esp_netif_deinit fail, returns(0x%x).", (uint32_t)err); err = nvs_flash_deinit(); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "nvs_flash_deinit fail, returns(0x%x).", (uint32_t)err); return err; @@ -592,25 +651,30 @@ static esp_err_t master_init(mb_communication_info_t* comm_info) void* master_handler = NULL; esp_err_t err = mbc_master_init_tcp(&master_handler); - MASTER_CHECK((master_handler != NULL), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, + TAG, "mb controller initialization fail."); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mb controller initialization fail, returns(0x%x).", (uint32_t)err); err = mbc_master_setup((void*)comm_info); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mb controller setup fail, returns(0x%x).", (uint32_t)err); err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mb controller set descriptor fail, returns(0x%x).", (uint32_t)err); - ESP_LOGI(MASTER_TAG, "Modbus master stack initialized..."); + ESP_LOGI(TAG, "Modbus master stack initialized..."); err = mbc_master_start(); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mb controller start fail, returns(0x%x).", (uint32_t)err); vTaskDelay(5); @@ -620,10 +684,11 @@ static esp_err_t master_init(mb_communication_info_t* comm_info) static esp_err_t master_destroy(void) { esp_err_t err = mbc_master_destroy(); - MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_master_destroy fail, returns(0x%x).", (uint32_t)err); - ESP_LOGI(MASTER_TAG, "Modbus master stack destroy..."); + ESP_LOGI(TAG, "Modbus master stack destroy..."); return err; } diff --git a/examples/protocols/modbus/tcp/mb_tcp_slave/main/Kconfig.projbuild b/examples/protocols/modbus/tcp/mb_tcp_slave/main/Kconfig.projbuild index 45c10bb50e66..27a297909979 100644 --- a/examples/protocols/modbus/tcp/mb_tcp_slave/main/Kconfig.projbuild +++ b/examples/protocols/modbus/tcp/mb_tcp_slave/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Modbus Example Configuration" config MB_SLAVE_ADDR int "Modbus slave address" - range 1 127 + range 1 255 default 1 help This is the Modbus slave address in the network. diff --git a/examples/protocols/modbus/tcp/mb_tcp_slave/main/tcp_slave.c b/examples/protocols/modbus/tcp/mb_tcp_slave/main/tcp_slave.c index 87cad1bfad55..a8d2319ad85a 100644 --- a/examples/protocols/modbus/tcp/mb_tcp_slave/main/tcp_slave.c +++ b/examples/protocols/modbus/tcp/mb_tcp_slave/main/tcp_slave.c @@ -8,7 +8,6 @@ #include "esp_err.h" #include "sdkconfig.h" #include "esp_log.h" - #include "esp_system.h" #include "esp_wifi.h" #include "esp_event.h" @@ -47,13 +46,7 @@ | MB_EVENT_COILS_WR) #define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK) -#define SLAVE_TAG "SLAVE_TEST" - -#define SLAVE_CHECK(a, ret_val, str, ...) \ - if (!(a)) { \ - ESP_LOGE(SLAVE_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return (ret_val); \ - } +static const char *TAG = "SLAVE_TEST"; static portMUX_TYPE param_lock = portMUX_INITIALIZER_UNLOCKED; @@ -103,7 +96,7 @@ static void start_mdns_service(void) ESP_ERROR_CHECK(mdns_init()); //set mDNS hostname (required if you want to advertise services) ESP_ERROR_CHECK(mdns_hostname_set(hostname)); - ESP_LOGI(SLAVE_TAG, "mdns hostname set to: [%s]", hostname); + ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname); //set default mDNS instance name ESP_ERROR_CHECK(mdns_instance_name_set(MB_MDNS_INSTANCE("esp32_"))); @@ -167,8 +160,8 @@ static void slave_operation_func(void *arg) { mb_param_info_t reg_info; // keeps the Modbus registers access information - ESP_LOGI(SLAVE_TAG, "Modbus slave stack initialized."); - ESP_LOGI(SLAVE_TAG, "Start modbus test..."); + ESP_LOGI(TAG, "Modbus slave stack initialized."); + ESP_LOGI(TAG, "Start modbus test..."); // The cycle below will be terminated when parameter holding_data0 // incremented each access cycle reaches the CHAN_DATA_MAX_VAL value. for(;holding_reg_params.holding_data0 < MB_CHAN_DATA_MAX_VAL;) { @@ -179,7 +172,7 @@ static void slave_operation_func(void *arg) if(event & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) { // Get parameter information from parameter queue ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", rw_str, (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, @@ -197,7 +190,7 @@ static void slave_operation_func(void *arg) } } else if (event & MB_EVENT_INPUT_REG_RD) { ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, (uint32_t)reg_info.type, @@ -205,7 +198,7 @@ static void slave_operation_func(void *arg) (uint32_t)reg_info.size); } else if (event & MB_EVENT_DISCRETE_RD) { ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, (uint32_t)reg_info.type, @@ -213,7 +206,7 @@ static void slave_operation_func(void *arg) (uint32_t)reg_info.size); } else if (event & (MB_EVENT_COILS_RD | MB_EVENT_COILS_WR)) { ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT)); - ESP_LOGI(SLAVE_TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", + ESP_LOGI(TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u", rw_str, (uint32_t)reg_info.time_stamp, (uint32_t)reg_info.mb_offset, @@ -224,7 +217,7 @@ static void slave_operation_func(void *arg) } } // Destroy of Modbus controller on alarm - ESP_LOGI(SLAVE_TAG,"Modbus controller destroyed."); + ESP_LOGI(TAG,"Modbus controller destroyed."); vTaskDelay(100); } @@ -235,15 +228,18 @@ static esp_err_t init_services(void) ESP_ERROR_CHECK(nvs_flash_erase()); result = nvs_flash_init(); } - SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "nvs_flash_init fail, returns(0x%x).", (uint32_t)result); result = esp_netif_init(); - SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_netif_init fail, returns(0x%x).", (uint32_t)result); result = esp_event_loop_create_default(); - SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_event_loop_create_default fail, returns(0x%x).", (uint32_t)result); #if CONFIG_MB_MDNS_IP_RESOLVER @@ -254,12 +250,14 @@ static esp_err_t init_services(void) // Read "Establishing Wi-Fi or Ethernet Connection" section in // examples/protocols/README.md for more information about this function. result = example_connect(); - SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "example_connect fail, returns(0x%x).", (uint32_t)result); #if CONFIG_EXAMPLE_CONNECT_WIFI result = esp_wifi_set_ps(WIFI_PS_NONE); - SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_wifi_set_ps fail, returns(0x%x).", (uint32_t)result); #endif @@ -271,19 +269,23 @@ static esp_err_t destroy_services(void) esp_err_t err = ESP_OK; err = example_disconnect(); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "example_disconnect fail, returns(0x%x).", (uint32_t)err); err = esp_event_loop_delete_default(); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "esp_event_loop_delete_default fail, returns(0x%x).", (uint32_t)err); err = esp_netif_deinit(); - SLAVE_CHECK((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE, + TAG, "esp_netif_deinit fail, returns(0x%x).", (uint32_t)err); err = nvs_flash_deinit(); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "nvs_flash_deinit fail, returns(0x%x).", (uint32_t)err); #if CONFIG_MB_MDNS_IP_RESOLVER @@ -301,7 +303,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) // Initialization of Modbus controller esp_err_t err = mbc_slave_init_tcp(&slave_handler); - SLAVE_CHECK((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE, + TAG, "mb controller initialization fail."); comm_info->ip_addr = NULL; // Bind to any address @@ -309,7 +312,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) // Setup communication parameters and start stack err = mbc_slave_setup((void*)comm_info); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_setup fail, returns(0x%x).", (uint32_t)err); @@ -324,7 +328,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) reg_area.address = (void*)&holding_reg_params.holding_data0; // Set pointer to storage instance reg_area.size = sizeof(float) << 2; // Set the size of register storage instance err = mbc_slave_set_descriptor(reg_area); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (uint32_t)err); @@ -333,7 +338,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) reg_area.address = (void*)&holding_reg_params.holding_data4; // Set pointer to storage instance reg_area.size = sizeof(float) << 2; // Set the size of register storage instance err = mbc_slave_set_descriptor(reg_area); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (uint32_t)err); @@ -343,7 +349,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) reg_area.address = (void*)&input_reg_params.input_data0; reg_area.size = sizeof(float) << 2; err = mbc_slave_set_descriptor(reg_area); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (uint32_t)err); reg_area.type = MB_PARAM_INPUT; @@ -351,7 +358,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) reg_area.address = (void*)&input_reg_params.input_data4; reg_area.size = sizeof(float) << 2; err = mbc_slave_set_descriptor(reg_area); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (uint32_t)err); @@ -361,7 +369,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) reg_area.address = (void*)&coil_reg_params; reg_area.size = sizeof(coil_reg_params); err = mbc_slave_set_descriptor(reg_area); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (uint32_t)err); @@ -371,7 +380,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) reg_area.address = (void*)&discrete_reg_params; reg_area.size = sizeof(discrete_reg_params); err = mbc_slave_set_descriptor(reg_area); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (uint32_t)err); @@ -380,7 +390,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) // Starts of modbus controller and stack err = mbc_slave_start(); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_start fail, returns(0x%x).", (uint32_t)err); vTaskDelay(5); @@ -390,7 +401,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info) static esp_err_t slave_destroy(void) { esp_err_t err = mbc_slave_destroy(); - SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE, + MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, + TAG, "mbc_slave_destroy fail, returns(0x%x).", (uint32_t)err); return err; @@ -405,7 +417,7 @@ void app_main(void) ESP_ERROR_CHECK(init_services()); // Set UART log level - esp_log_level_set(SLAVE_TAG, ESP_LOG_INFO); + esp_log_level_set(TAG, ESP_LOG_INFO); mb_communication_info_t comm_info = { 0 }; diff --git a/examples/protocols/mqtt/ssl/README.md b/examples/protocols/mqtt/ssl/README.md index aa96a6841a56..680fc8a14170 100644 --- a/examples/protocols/mqtt/ssl/README.md +++ b/examples/protocols/mqtt/ssl/README.md @@ -2,7 +2,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example connects to the broker mqtt.eclipse.org using ssl transport and as a demonstration subscribes/unsubscribes and send a message on certain topic. +This example connects to the broker mqtt.eclipseprojects.io using ssl transport and as a demonstration subscribes/unsubscribes and send a message on certain topic. (Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker. @@ -19,13 +19,13 @@ This example can be executed on any ESP32 board, the only required interface is * Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. * When using Make build system, set `Default serial port` under `Serial flasher config`. -PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipse.org. +PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipseprojects.io. In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used). ``` -echo "" | openssl s_client -showcerts -connect mqtt.eclipse.org:8883 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >mqtt_eclipse_org.pem +echo "" | openssl s_client -showcerts -connect mqtt.eclipseprojects.io:8883 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >mqtt_eclipse_org.pem ``` Please note that this is not a general command for downloading a root certificate for an arbitrary host; -this command works with mqtt.eclipse.org as the site provides root certificate in the chain, which then could be extracted +this command works with mqtt.eclipseprojects.io as the site provides root certificate in the chain, which then could be extracted with text operation. ### Build and Flash diff --git a/examples/protocols/mqtt/ssl/main/Kconfig.projbuild b/examples/protocols/mqtt/ssl/main/Kconfig.projbuild index b1acbc5cab2e..5e9357d1a698 100644 --- a/examples/protocols/mqtt/ssl/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/ssl/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URI string "Broker URL" - default "mqtts://mqtt.eclipse.org:8883" + default "mqtts://mqtt.eclipseprojects.io:8883" help URL of an mqtt broker which this example connects to. diff --git a/examples/protocols/mqtt/ssl_ds/configure_ds.py b/examples/protocols/mqtt/ssl_ds/configure_ds.py index b718052301c6..d37129e242bd 100644 --- a/examples/protocols/mqtt/ssl_ds/configure_ds.py +++ b/examples/protocols/mqtt/ssl_ds/configure_ds.py @@ -1,16 +1,6 @@ #!/usr/bin/env python -# Copyright 2020 Espressif Systems (Shanghai) Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 import argparse import hashlib import hmac @@ -263,18 +253,26 @@ def configure_efuse_key_block(args, idf_target): key_file.write(new_hmac_key) # Burn efuse key efuse_burn_key(args, idf_target) - # Read fresh summary of the efuse to read the key value from efuse. - # If the key read from efuse matches with the key generated - # on host then burn_key operation was successfull - new_efuse_summary_json = get_efuse_summary_json(args, idf_target) - hmac_key_read = new_efuse_summary_json[key_blk]['value'] - hmac_key_read = bytes.fromhex(hmac_key_read) - if new_hmac_key == hmac_key_read: - print('Key was successfully written to the efuse (KEY BLOCK %1d)' % (args.efuse_key_id)) + if args.production is False: + # Read fresh summary of the efuse to read the key value from efuse. + # If the key read from efuse matches with the key generated + # on host then burn_key operation was successfull + new_efuse_summary_json = get_efuse_summary_json(args, idf_target) + hmac_key_read = new_efuse_summary_json[key_blk]['value'] + print(hmac_key_read) + hmac_key_read = bytes.fromhex(hmac_key_read) + if new_hmac_key == hmac_key_read: + print('Key was successfully written to the efuse (KEY BLOCK %1d)' % (args.efuse_key_id)) + else: + print('ERROR: Failed to burn the hmac key to efuse (KEY BLOCK %1d),' + '\nPlease execute the script again using a different key id' % (args.efuse_key_id)) + return None else: - print('ERROR: Failed to burn the hmac key to efuse (KEY BLOCK %1d),' - '\nPlease execute the script again using a different key id' % (args.efuse_key_id)) - return None + new_efuse_summary_json = get_efuse_summary_json(args, idf_target) + if new_efuse_summary_json[key_purpose]['value'] != 'HMAC_DOWN_DIGITAL_SIGNATURE': + print('ERROR: Failed to verify the key purpose of the key block{})'.format(args.efuse_key_id)) + return None + hmac_key_read = new_hmac_key else: # If the efuse key block is redable, then read the key from efuse block and use it for encrypting the RSA private key parameters. # If the efuse key block is not redable or it has key purpose set to a different @@ -297,7 +295,7 @@ def configure_efuse_key_block(args, idf_target): '\nplease execute the script again with a different value of the efuse key id.' % (args.efuse_key_id)) return None - # Return the hmac key read from the efuse + # Return the hmac key burned into the efuse return hmac_key_read diff --git a/examples/protocols/mqtt/tcp/main/Kconfig.projbuild b/examples/protocols/mqtt/tcp/main/Kconfig.projbuild index fc6e8a184c97..c11539fb8d28 100644 --- a/examples/protocols/mqtt/tcp/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/tcp/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URL string "Broker URL" - default "mqtt://mqtt.eclipse.org" + default "mqtt://mqtt.eclipseprojects.io" help URL of the broker to connect to diff --git a/examples/protocols/mqtt/ws/README.md b/examples/protocols/mqtt/ws/README.md index 3b2a05a979ec..c9ca6eabea02 100644 --- a/examples/protocols/mqtt/ws/README.md +++ b/examples/protocols/mqtt/ws/README.md @@ -2,7 +2,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example connects to the broker mqtt.eclipse.org over web sockets as a demonstration subscribes/unsubscribes and send a message on certain topic. +This example connects to the broker mqtt.eclipseprojects.io over web sockets as a demonstration subscribes/unsubscribes and send a message on certain topic. (Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker. diff --git a/examples/protocols/mqtt/ws/main/Kconfig.projbuild b/examples/protocols/mqtt/ws/main/Kconfig.projbuild index c298f5d7c8ee..e547a5156cdc 100644 --- a/examples/protocols/mqtt/ws/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/ws/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URI string "Broker URL" - default "ws://mqtt.eclipse.org:80/mqtt" + default "ws://mqtt.eclipseprojects.io:80/mqtt" help URL of an mqtt broker which this example connects to. diff --git a/examples/protocols/mqtt/wss/README.md b/examples/protocols/mqtt/wss/README.md index c07477fe1293..3d2fa2b8af49 100644 --- a/examples/protocols/mqtt/wss/README.md +++ b/examples/protocols/mqtt/wss/README.md @@ -1,7 +1,7 @@ # ESP-MQTT MQTT over WSS Sample application (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example connects to the broker mqtt.eclipse.org over secure websockets and as a demonstration subscribes/unsubscribes and send a message on certain topic. +This example connects to the broker mqtt.eclipseprojects.io over secure websockets and as a demonstration subscribes/unsubscribes and send a message on certain topic. (Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker. @@ -18,15 +18,15 @@ This example can be executed on any ESP32 board, the only required interface is * Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. * When using Make build system, set `Default serial port` under `Serial flasher config`. -Note how to create a PEM certificate for mqtt.eclipse.org: +Note how to create a PEM certificate for mqtt.eclipseprojects.io: -PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipse.org. +PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipseprojects.io. In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used). ``` -echo "" | openssl s_client -showcerts -connect mqtt.eclipse.org:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >mqtt_eclipse_org.pem +echo "" | openssl s_client -showcerts -connect mqtt.eclipseprojects.io:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >mqtt_eclipse_org.pem ``` Please note that this is not a general command for downloading a root certificate for an arbitrary host; -this command works with mqtt.eclipse.org as the site provides root certificate in the chain, which then could be extracted +this command works with mqtt.eclipseprojects.io as the site provides root certificate in the chain, which then could be extracted with text operation. ### Build and Flash diff --git a/examples/protocols/mqtt/wss/main/Kconfig.projbuild b/examples/protocols/mqtt/wss/main/Kconfig.projbuild index 5e43c8949363..b6d1f593ddfc 100644 --- a/examples/protocols/mqtt/wss/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/wss/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URI string "Broker URL" - default "wss://mqtt.eclipse.org:443/mqtt" + default "wss://mqtt.eclipseprojects.io:443/mqtt" help URL of an mqtt broker which this example connects to. diff --git a/examples/protocols/pppos_client/README.md b/examples/protocols/pppos_client/README.md index c00e8f626d4c..d0e677850ada 100644 --- a/examples/protocols/pppos_client/README.md +++ b/examples/protocols/pppos_client/README.md @@ -128,4 +128,8 @@ E (626) sim800: sim800_init(628): sync failed ``` * Make sure your modem module is in command mode stably before you run this example. +2. Why the modem restarts before switching to PPP mode or while getting operator's information? + + * Make sure the modem device is properly powered. Please consult the device's datasheet for the power requirement (BG96 consumes approximately 200mA while establishing a connection and may restart if powered only from ESP32-WROVER Kit) + (For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) diff --git a/examples/protocols/pppos_client/main/pppos_client_main.c b/examples/protocols/pppos_client/main/pppos_client_main.c index 67a64c3fb000..2602299e25da 100644 --- a/examples/protocols/pppos_client/main/pppos_client_main.c +++ b/examples/protocols/pppos_client/main/pppos_client_main.c @@ -19,7 +19,7 @@ #include "bg96.h" #include "sim7600.h" -#define BROKER_URL "mqtt://mqtt.eclipse.org" +#define BROKER_URL "mqtt://mqtt.eclipseprojects.io" static const char *TAG = "pppos_example"; static EventGroupHandle_t event_group = NULL; diff --git a/examples/protocols/smtp_client/main/smtp_client_example_main.c b/examples/protocols/smtp_client/main/smtp_client_example_main.c index 52f090405f46..88cf49be9df9 100644 --- a/examples/protocols/smtp_client/main/smtp_client_example_main.c +++ b/examples/protocols/smtp_client/main/smtp_client_example_main.c @@ -100,6 +100,7 @@ static int write_and_get_response(mbedtls_net_context *sock_fd, unsigned char *b do { len = DATA_SIZE - 1; + memset(data, 0, DATA_SIZE); ret = mbedtls_net_recv(sock_fd, data, len); if (ret <= 0) { @@ -153,6 +154,7 @@ static int write_ssl_and_get_response(mbedtls_ssl_context *ssl, unsigned char *b do { len = DATA_SIZE - 1; + memset(data, 0, DATA_SIZE); ret = mbedtls_ssl_read(ssl, data, len); if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { @@ -482,8 +484,12 @@ static void smtp_client_task(void *pvParameters) ret = 0; /* No errors */ exit: - mbedtls_ssl_session_reset(&ssl); mbedtls_net_free(&server_fd); + mbedtls_x509_crt_free(&cacert); + mbedtls_ssl_free(&ssl); + mbedtls_ssl_config_free(&conf); + mbedtls_ctr_drbg_free(&ctr_drbg); + mbedtls_entropy_free(&entropy); if (ret != 0) { mbedtls_strerror(ret, buf, 100); diff --git a/examples/protocols/websocket/README.md b/examples/protocols/websocket/README.md index c434a7c13b73..791e9f4300c8 100644 --- a/examples/protocols/websocket/README.md +++ b/examples/protocols/websocket/README.md @@ -36,7 +36,7 @@ I (4472) tcpip_adapter: eth ip: 192.168.2.137, mask: 255.255.255.0, gw: 192.168. I (4472) example_connect: Connected to Ethernet I (4472) example_connect: IPv4 address: 192.168.2.137 I (4472) example_connect: IPv6 address: fe80:0000:0000:0000:bedd:c2ff:fed4:a92b -I (4482) WEBSOCKET: Connecting to ws://echo.websocket.org... +I (4482) WEBSOCKET: Connecting to ws://echo.websocket.events... I (5012) WEBSOCKET: WEBSOCKET_EVENT_CONNECTED I (5492) WEBSOCKET: Sending hello 0000 I (6052) WEBSOCKET: WEBSOCKET_EVENT_DATA @@ -56,3 +56,35 @@ W (9162) WEBSOCKET: Received=hello 0003 ``` + +## Python Flask echo server + +By default, the `ws://echo.websocket.events` endpoint is used. You can setup a Python websocket echo server locally and try the `ws://:5000` endpoint. To do this, install Flask-sock Python package + +``` +pip install flask-sock +``` + +and start a Flask websocket echo server locally by executing the following Python code: + +```python +from flask import Flask +from flask_sock import Sock + +app = Flask(__name__) +sock = Sock(app) + + +@sock.route('/') +def echo(ws): + while True: + data = ws.receive() + ws.send(data) + + +if __name__ == '__main__': + # To run your Flask + WebSocket server in production you can use Gunicorn: + # gunicorn -b 0.0.0.0:5000 --workers 4 --threads 100 module:app + app.run(host="0.0.0.0", debug=True) +``` + diff --git a/examples/protocols/websocket/main/Kconfig.projbuild b/examples/protocols/websocket/main/Kconfig.projbuild index 0613b9033560..d146488e3cf0 100644 --- a/examples/protocols/websocket/main/Kconfig.projbuild +++ b/examples/protocols/websocket/main/Kconfig.projbuild @@ -16,7 +16,7 @@ menu "Example Configuration" config WEBSOCKET_URI string "Websocket endpoint URI" depends on WEBSOCKET_URI_FROM_STRING - default "ws://echo.websocket.org" + default "ws://echo.websocket.events" help URL of websocket endpoint this example connects to and sends echo diff --git a/examples/provisioning/wifi_prov_mgr/main/app_main.c b/examples/provisioning/wifi_prov_mgr/main/app_main.c index 733f64fa3360..004521abfae6 100644 --- a/examples/provisioning/wifi_prov_mgr/main/app_main.c +++ b/examples/provisioning/wifi_prov_mgr/main/app_main.c @@ -261,6 +261,7 @@ void app_main(void) /* What is the service key (could be NULL) * This translates to : * - Wi-Fi password when scheme is wifi_prov_scheme_softap + * (Minimum expected length: 8, maximum 64 for WPA2-PSK) * - simply ignored when scheme is wifi_prov_scheme_ble */ const char *service_key = NULL; diff --git a/examples/storage/spiffs/spiffs_example_test.py b/examples/storage/spiffs/spiffs_example_test.py index 4151f93c0f3a..1922a070c637 100644 --- a/examples/storage/spiffs/spiffs_example_test.py +++ b/examples/storage/spiffs/spiffs_example_test.py @@ -16,7 +16,7 @@ def test_examples_spiffs(env, extra_data): 'example: Reading file', 'example: Read from file: \'Hello World!\'', 'example: SPIFFS unmounted', - timeout=20) + timeout=60) if __name__ == '__main__': diff --git a/examples/system/app_trace_to_host/sdkconfig.defaults b/examples/system/app_trace_to_host/sdkconfig.defaults index 7ebca1615377..7e35e60b6d26 100644 --- a/examples/system/app_trace_to_host/sdkconfig.defaults +++ b/examples/system/app_trace_to_host/sdkconfig.defaults @@ -1,5 +1,5 @@ # Enable application tracing by default -CONFIG_APPTRACE_DEST_TRAX=y +CONFIG_APPTRACE_DEST_JTAG=y CONFIG_APPTRACE_ENABLE=y # Disable WiFi stack by default CONFIG_WIFI_ENABLED=n diff --git a/examples/system/esp_timer/main/esp_timer_example_main.c b/examples/system/esp_timer/main/esp_timer_example_main.c index 9750423991b8..bccb6e0bb223 100644 --- a/examples/system/esp_timer/main/esp_timer_example_main.c +++ b/examples/system/esp_timer/main/esp_timer_example_main.c @@ -61,14 +61,16 @@ void app_main(void) /* Timekeeping continues in light sleep, and timers are scheduled * correctly after light sleep. */ - ESP_LOGI(TAG, "Entering light sleep for 0.5s, time since boot: %lld us", - esp_timer_get_time()); + int64_t t1 = esp_timer_get_time(); + ESP_LOGI(TAG, "Entering light sleep for 0.5s, time since boot: %lld us", t1); ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(500000)); esp_light_sleep_start(); - ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", - esp_timer_get_time()); + int64_t t2 = esp_timer_get_time(); + ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", t2); + + assert(abs((t2 - t1) - 500000) < 1000); /* Let the timer run for a little bit more */ usleep(2000000); diff --git a/examples/system/gcov/sdkconfig.defaults b/examples/system/gcov/sdkconfig.defaults index 5a21ba3a9515..fc57db37a07a 100644 --- a/examples/system/gcov/sdkconfig.defaults +++ b/examples/system/gcov/sdkconfig.defaults @@ -1,4 +1,4 @@ -CONFIG_APPTRACE_DEST_TRAX=y +CONFIG_APPTRACE_DEST_JTAG=y # CONFIG_APPTRACE_DEST_NONE is not set CONFIG_APPTRACE_ENABLE=y CONFIG_APPTRACE_LOCK_ENABLE=y diff --git a/examples/system/ota/advanced_https_ota/example_test.py b/examples/system/ota/advanced_https_ota/example_test.py index 8167ede97e91..a43413031431 100644 --- a/examples/system/ota/advanced_https_ota/example_test.py +++ b/examples/system/ota/advanced_https_ota/example_test.py @@ -1,4 +1,5 @@ import http.server +import multiprocessing import os import random import re @@ -6,60 +7,12 @@ import ssl import struct import subprocess -from threading import Thread import ttfw_idf from tiny_test_fw import DUT -server_cert = '-----BEGIN CERTIFICATE-----\n' \ - 'MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ\n'\ - 'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\ - 'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\ - 'b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ\n'\ - 'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\ - 'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\ - 'b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL\n'\ - 'SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W\n'\ - 'ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ\n'\ - 'S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz\n'\ - 'YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz\n'\ - '3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap\n'\ - 'rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud\n'\ - 'IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk\n'\ - 'B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32\n'\ - '3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9\n'\ - 'RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN\n'\ - 'lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=\n'\ - '-----END CERTIFICATE-----\n' - -server_key = '-----BEGIN PRIVATE KEY-----\n'\ - 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP\n'\ - 'wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu\n'\ - 'c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m\n'\ - 'KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO\n'\ - '2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv\n'\ - 'L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO\n'\ - 'AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH\n'\ - 'fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj\n'\ - 'z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF\n'\ - 'gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z\n'\ - 'Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q\n'\ - 'jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz\n'\ - 'i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw\n'\ - '8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N\n'\ - 'JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq\n'\ - 'gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv\n'\ - 'kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN\n'\ - 'P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al\n'\ - 'pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG\n'\ - '1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU\n'\ - '10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ\n'\ - 'hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O\n'\ - 'rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G\n'\ - 'rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ\n'\ - 'YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG\n'\ - 'vSXnRLaxQhooWm+IuX9SuBQ=\n'\ - '-----END PRIVATE KEY-----\n' +server_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_certs/server_cert.pem') +key_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_certs/server_key.pem') def get_my_ip(): @@ -79,21 +32,6 @@ def get_server_status(host_ip, port): return False -def create_file(server_file, file_data): - with open(server_file, 'w+') as file: - file.write(file_data) - - -def get_ca_cert(ota_image_dir): - os.chdir(ota_image_dir) - server_file = os.path.join(ota_image_dir, 'server_cert.pem') - create_file(server_file, server_cert) - - key_file = os.path.join(ota_image_dir, 'server_key.pem') - create_file(key_file, server_key) - return server_file, key_file - - def https_request_handler(): """ Returns a request handler class that handles broken pipe exception @@ -118,7 +56,7 @@ def handle(self): def start_https_server(ota_image_dir, server_ip, server_port): - server_file, key_file = get_ca_cert(ota_image_dir) + os.chdir(ota_image_dir) requestHandler = https_request_handler() httpd = http.server.HTTPServer((server_ip, server_port), requestHandler) @@ -129,7 +67,7 @@ def start_https_server(ota_image_dir, server_ip, server_port): def start_chunked_server(ota_image_dir, server_port): - server_file, key_file = get_ca_cert(ota_image_dir) + os.chdir(ota_image_dir) chunked_server = subprocess.Popen(['openssl', 's_server', '-WWW', '-key', key_file, '-cert', server_file, '-port', str(server_port)]) return chunked_server @@ -156,7 +94,6 @@ def handle(self): def start_redirect_server(ota_image_dir, server_ip, server_port, redirection_port): os.chdir(ota_image_dir) - server_file, key_file = get_ca_cert(ota_image_dir) redirectHandler = redirect_handler_factory('https://' + server_ip + ':' + str(redirection_port) + '/advanced_https_ota.bin') httpd = http.server.HTTPServer((server_ip, server_port), redirectHandler) @@ -190,7 +127,7 @@ def test_examples_protocol_advanced_https_ota_example(env, extra_data): # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -201,7 +138,7 @@ def test_examples_protocol_advanced_https_ota_example(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - thread1.close() + thread1.terminate() dut1.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) @@ -209,6 +146,7 @@ def test_examples_protocol_advanced_https_ota_example(env, extra_data): dut1.expect('Loaded app from partition at offset', timeout=60) dut1.expect('Starting Advanced OTA example', timeout=30) dut1.reset() + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -244,7 +182,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(env, extra_d # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -254,12 +192,14 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(env, extra_d print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut1.expect('Image validation failed, image is corrupted', timeout=30) os.remove(binary_file) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -294,7 +234,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(env, extr # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -304,12 +244,14 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(env, extr print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut1.expect('advanced_https_ota_example: esp_https_ota_read_img_desc failed', timeout=30) os.remove(binary_file) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -343,7 +285,7 @@ def test_examples_protocol_advanced_https_ota_example_random(env, extra_data): # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -353,12 +295,14 @@ def test_examples_protocol_advanced_https_ota_example_random(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) - dut1.expect('esp_ota_ops: OTA image has invalid magic byte', timeout=10) + dut1.expect(re.compile(r'esp_https_ota: Mismatch chip id, expected 0, found \d'), timeout=10) os.remove(binary_file) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -395,8 +339,6 @@ def test_examples_protocol_advanced_https_ota_example_chunked(env, extra_data): dut1.expect('Loaded app from partition at offset', timeout=60) dut1.expect('Starting Advanced OTA example', timeout=30) chunked_server.kill() - os.remove(os.path.join(dut1.app.binary_path, 'server_cert.pem')) - os.remove(os.path.join(dut1.app.binary_path, 'server_key.pem')) @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -412,8 +354,9 @@ def test_examples_protocol_advanced_https_ota_example_redirect_url(env, extra_da """ dut1 = env.get_dut('advanced_https_ota_example', 'examples/system/ota/advanced_https_ota', dut_class=ttfw_idf.ESP32DUT) server_port = 8001 - # Port to which the request should be redirecetd + # Port to which the request should be redirected redirection_server_port = 8081 + redirection_server_port1 = 8082 # File to be downloaded. This file is generated after compilation bin_name = 'advanced_https_ota.bin' # check and log bin size @@ -423,21 +366,25 @@ def test_examples_protocol_advanced_https_ota_example_redirect_url(env, extra_da # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() - thread2 = Thread(target=start_redirect_server, args=(dut1.app.binary_path, host_ip, redirection_server_port, server_port)) + thread2 = multiprocessing.Process(target=start_redirect_server, args=(dut1.app.binary_path, host_ip, redirection_server_port, redirection_server_port1)) thread2.daemon = True thread2.start() + thread3 = multiprocessing.Process(target=start_redirect_server, args=(dut1.app.binary_path, host_ip, redirection_server_port1, server_port)) + thread3.daemon = True + thread3.start() dut1.start_app() dut1.expect('Loaded app from partition at offset', timeout=30) try: ip_address = dut1.expect(re.compile(r' sta ip: ([^,]+),'), timeout=30) print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: + thread1.terminate() + thread2.terminate() + thread3.terminate() raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - thread1.close() - thread2.close() dut1.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(redirection_server_port) + '/' + bin_name)) @@ -445,6 +392,9 @@ def test_examples_protocol_advanced_https_ota_example_redirect_url(env, extra_da dut1.expect('Loaded app from partition at offset', timeout=60) dut1.expect('Starting Advanced OTA example', timeout=30) dut1.reset() + thread1.terminate() + thread2.terminate() + thread3.terminate() @ttfw_idf.idf_example_test(env_tag='Example_8Mflash_Ethernet') @@ -481,7 +431,7 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(env, extra_d # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -492,6 +442,7 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(env, extra_d print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting Advanced OTA example', timeout=30) # Use originally generated image with secure_version=1 @@ -507,7 +458,8 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(env, extra_d print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + anti_rollback_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + anti_rollback_bin_name) dut1.expect('New firmware security version is less than eFuse programmed, 0 < 1', timeout=30) - os.remove(anti_rollback_bin_name) + os.remove(binary_file) + thread1.terminate() if __name__ == '__main__': diff --git a/examples/system/ota/advanced_https_ota/test_certs/server_cert.pem b/examples/system/ota/advanced_https_ota/test_certs/server_cert.pem new file mode 100644 index 000000000000..b29ba7ab1f54 --- /dev/null +++ b/examples/system/ota/advanced_https_ota/test_certs/server_cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ +TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD +VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j +b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ +TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD +VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL +SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W +ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ +S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz +YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz +3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap +rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud +IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk +B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32 +3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9 +RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN +lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y= +-----END CERTIFICATE----- diff --git a/examples/system/ota/advanced_https_ota/test_certs/server_key.pem b/examples/system/ota/advanced_https_ota/test_certs/server_key.pem new file mode 100644 index 000000000000..20a4bdb624f0 --- /dev/null +++ b/examples/system/ota/advanced_https_ota/test_certs/server_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP +wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu +c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m +KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO +2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv +L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO +AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH +fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj +z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF +gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z +Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q +jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz +i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw +8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N +JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq +gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv +kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN +P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al +pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG +1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU +10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ +hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O +rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G +rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ +YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG +vSXnRLaxQhooWm+IuX9SuBQ= +-----END PRIVATE KEY----- diff --git a/examples/system/ota/native_ota_example/example_test.py b/examples/system/ota/native_ota_example/example_test.py index 66d92baa9966..9c4b21fc0d27 100644 --- a/examples/system/ota/native_ota_example/example_test.py +++ b/examples/system/ota/native_ota_example/example_test.py @@ -1,4 +1,5 @@ import http.server +import multiprocessing import os import random import re @@ -6,7 +7,6 @@ import ssl import struct import subprocess -from threading import Thread import ttfw_idf from tiny_test_fw import DUT @@ -157,7 +157,7 @@ def test_examples_protocol_native_ota_example(env, extra_data): # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -168,7 +168,7 @@ def test_examples_protocol_native_ota_example(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - thread1.close() + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) @@ -176,6 +176,7 @@ def test_examples_protocol_native_ota_example(env, extra_data): dut1.expect('Loaded app from partition at offset', timeout=60) dut1.expect('Starting OTA example', timeout=30) dut1.reset() + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -211,7 +212,7 @@ def test_examples_protocol_native_ota_example_truncated_bin(env, extra_data): # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -221,12 +222,14 @@ def test_examples_protocol_native_ota_example_truncated_bin(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut1.expect('native_ota_example: Image validation failed, image is corrupted', timeout=20) os.remove(binary_file) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -261,7 +264,7 @@ def test_examples_protocol_native_ota_example_truncated_header(env, extra_data): # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -271,12 +274,14 @@ def test_examples_protocol_native_ota_example_truncated_header(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut1.expect('native_ota_example: received package is not fit len', timeout=20) os.remove(binary_file) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') @@ -310,7 +315,7 @@ def test_examples_protocol_native_ota_example_random(env, extra_data): # start test host_ip = get_my_ip() if (get_server_status(host_ip, server_port) is False): - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() dut1.start_app() @@ -320,12 +325,14 @@ def test_examples_protocol_native_ota_example_random(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) dut1.expect('esp_ota_ops: OTA image has invalid magic byte', timeout=20) os.remove(binary_file) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_WIFI') diff --git a/examples/system/ota/simple_ota_example/example_test.py b/examples/system/ota/simple_ota_example/example_test.py index f2cb87868c14..b61d325bcf88 100644 --- a/examples/system/ota/simple_ota_example/example_test.py +++ b/examples/system/ota/simple_ota_example/example_test.py @@ -1,9 +1,9 @@ import http.server +import multiprocessing import os import re import socket import ssl -from threading import Thread import ttfw_idf from tiny_test_fw import DUT, Utility @@ -67,11 +67,16 @@ def get_my_ip(): return my_ip -def start_https_server(ota_image_dir, server_ip, server_port): - # parser = argparse.ArgumentParser() - # parser.add_argument('-p', '--port', dest='port', type= int, - # help= "Server Port", default= 8000) - # args = parser.parse_args() +def get_server_status(host_ip, server_port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_status = sock.connect_ex((host_ip, server_port)) + sock.close() + if server_status == 0: + return True + return False + + +def start_https_server(ota_image_dir, server_ip, server_port, server_file=None, key_file=None): os.chdir(ota_image_dir) server_file = os.path.join(ota_image_dir, 'server_cert.pem') @@ -131,9 +136,10 @@ def test_examples_protocol_simple_ota_example(env, extra_data): sha256_bootloader, sha256_app = calc_all_sha256(dut1) # start test host_ip = get_my_ip() - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() + if (get_server_status(host_ip, 8000) is False): + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() dut1.start_app() dut1.expect('Loaded app from partition at offset 0x10000', timeout=30) check_sha256(sha256_bootloader, dut1.expect(re.compile(r'SHA-256 for bootloader:\s+([a-f0-9]+)'))[0]) @@ -143,13 +149,14 @@ def test_examples_protocol_simple_ota_example(env, extra_data): print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - thread1.close() + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut1.write('https://' + host_ip + ':8000/simple_ota.bin') dut1.expect('Loaded app from partition at offset 0x110000', timeout=60) dut1.expect('Starting OTA example', timeout=30) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_EthKitV1') @@ -167,9 +174,10 @@ def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(env, e ttfw_idf.log_performance('simple_ota_bin_size', '{}KB'.format(bin_size // 1024)) # start test host_ip = get_my_ip() - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() + if (get_server_status(host_ip, 8000) is False): + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() dut1.start_app() dut1.expect('Loaded app from partition at offset 0x10000', timeout=30) try: @@ -177,13 +185,14 @@ def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(env, e print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - thread1.close() + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut1.write('https://' + host_ip + ':8000/simple_ota.bin') dut1.expect('Loaded app from partition at offset 0x110000', timeout=60) dut1.expect('Starting OTA example', timeout=30) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_Flash_Encryption_OTA') @@ -204,9 +213,10 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption(env, extra_d dut1.erase_flash() # start test host_ip = get_my_ip() - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() + if (get_server_status(host_ip, 8000) is False): + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() dut1.start_app() dut1.expect('Loaded app from partition at offset 0x20000', timeout=30) dut1.expect('Flash encryption mode is DEVELOPMENT (not secure)', timeout=10) @@ -215,7 +225,7 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption(env, extra_d print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - thread1.close() + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -223,6 +233,7 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption(env, extra_d dut1.expect('Loaded app from partition at offset 0x120000', timeout=60) dut1.expect('Flash encryption mode is DEVELOPMENT (not secure)', timeout=10) dut1.expect('Starting OTA example', timeout=30) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_EthKitV1') @@ -242,9 +253,10 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat sha256_bootloader, sha256_app = calc_all_sha256(dut1) # start test host_ip = get_my_ip() - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() + if (get_server_status(host_ip, 8000) is False): + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() dut1.start_app() dut1.expect('Loaded app from partition at offset 0x20000', timeout=30) check_sha256(sha256_bootloader, dut1.expect(re.compile(r'SHA-256 for bootloader:\s+([a-f0-9]+)'))[0]) @@ -254,6 +266,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -264,6 +277,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat dut1.expect('Loaded app from partition at offset 0x120000', timeout=20) dut1.expect('Starting OTA example', timeout=30) + thread1.terminate() @ttfw_idf.idf_example_test(env_tag='Example_EthKitV12') @@ -283,9 +297,10 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat sha256_bootloader, sha256_app = calc_all_sha256(dut1) # start test host_ip = get_my_ip() - thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() + if (get_server_status(host_ip, 8000) is False): + thread1 = multiprocessing.Process(target=start_https_server, args=(dut1.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() dut1.start_app() dut1.expect('Loaded app from partition at offset 0x20000', timeout=30) check_sha256(sha256_bootloader, dut1.expect(re.compile(r'SHA-256 for bootloader:\s+([a-f0-9]+)'))[0]) @@ -295,6 +310,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + thread1.terminate() dut1.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -308,6 +324,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat dut1.expect('Loaded app from partition at offset 0x120000', timeout=20) dut1.expect('Starting OTA example', timeout=30) + thread1.terminate() if __name__ == '__main__': diff --git a/examples/system/sysview_tracing/README.md b/examples/system/sysview_tracing/README.md index dc5a643a6dd2..93ab9efa4fca 100644 --- a/examples/system/sysview_tracing/README.md +++ b/examples/system/sysview_tracing/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-S2 | -| ----------------- | ----- | -------- | +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | # Example: Application Level Tracing - SystemView Tracing (sysview_tracing) This test code shows how to perform system-wide behavioral analysis of the program using [SEGGER SystemView tool](https://www.segger.com/products/development-tools/systemview/). diff --git a/examples/system/sysview_tracing/main/sysview_tracing.c b/examples/system/sysview_tracing/main/sysview_tracing.c index a561ca2dfe95..97fac1f3e9ee 100644 --- a/examples/system/sysview_tracing/main/sysview_tracing.c +++ b/examples/system/sysview_tracing/main/sysview_tracing.c @@ -26,7 +26,7 @@ typedef struct { } example_event_data_t; -#if CONFIG_SYSVIEW_ENABLE +#if CONFIG_APPTRACE_SV_ENABLE #if !CONFIG_USE_CUSTOM_EVENT_ID #define SYSVIEW_EXAMPLE_SEND_EVENT_ID 0 @@ -165,13 +165,13 @@ void app_main(void) }, #if CONFIG_FREERTOS_UNICORE == 0 { - .group = TIMER_GROUP_1, - .timer = TIMER_1, + .group = TIMER_GROUP_0, + .timer = TIMER_0, }, #endif }; -#if CONFIG_SYSVIEW_ENABLE && CONFIG_USE_CUSTOM_EVENT_ID +#if CONFIG_APPTRACE_SV_ENABLE && CONFIG_USE_CUSTOM_EVENT_ID // Currently OpenOCD does not support requesting module info from target. So do the following... // Wait untill SystemView module receives START command from host, // after that data can be sent to the host using onboard API, @@ -183,7 +183,7 @@ void app_main(void) #endif example_timer_init(TIMER_GROUP_1, TIMER_0, 2000); - example_timer_init(TIMER_GROUP_1, TIMER_1, 4000); + example_timer_init(TIMER_GROUP_0, TIMER_0, 4000); xTaskCreatePinnedToCore(example_task, "svtrace0", 2048, &event_data[0], 3, &event_data[0].thnd, 0); ESP_LOGI(TAG, "Created task %p", event_data[0].thnd); diff --git a/examples/system/sysview_tracing/sdkconfig.defaults b/examples/system/sysview_tracing/sdkconfig.defaults index f0cb3a80b9d1..1dd29527d185 100644 --- a/examples/system/sysview_tracing/sdkconfig.defaults +++ b/examples/system/sysview_tracing/sdkconfig.defaults @@ -4,21 +4,21 @@ CONFIG_FREERTOS_UNICORE=y # 1ms tick period CONFIG_FREERTOS_HZ=1000 # Enable application tracing by default -CONFIG_APPTRACE_DEST_TRAX=y +CONFIG_APPTRACE_DEST_JTAG=y CONFIG_APPTRACE_ENABLE=y # Enable FreeRTOS SystemView Tracing by default -CONFIG_SYSVIEW_ENABLE=y -CONFIG_SYSVIEW_TS_SOURCE_TIMER_00=y -CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE=y -CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE=y -CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE=y -CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE=y -CONFIG_SYSVIEW_EVT_IDLE_ENABLE=y -CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE=y -CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE=y +CONFIG_APPTRACE_SV_ENABLE=y +CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00=y +CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE=y diff --git a/examples/system/sysview_tracing_heap_log/README.md b/examples/system/sysview_tracing_heap_log/README.md index 6f31050ed142..9514af9a13b1 100644 --- a/examples/system/sysview_tracing_heap_log/README.md +++ b/examples/system/sysview_tracing_heap_log/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-S2 | -| ----------------- | ----- | -------- | +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | # SystemView Heap and Log Tracing Example diff --git a/examples/system/sysview_tracing_heap_log/sdkconfig.defaults b/examples/system/sysview_tracing_heap_log/sdkconfig.defaults index e5fa3d614121..ccc6fdd18ff8 100644 --- a/examples/system/sysview_tracing_heap_log/sdkconfig.defaults +++ b/examples/system/sysview_tracing_heap_log/sdkconfig.defaults @@ -4,24 +4,25 @@ CONFIG_FREERTOS_UNICORE=y # 1ms tick period CONFIG_FREERTOS_HZ=1000 # Enable application tracing by default -CONFIG_APPTRACE_DEST_TRAX=y +CONFIG_APPTRACE_DEST_JTAG=y +CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE=y CONFIG_APPTRACE_ENABLE=y # Enable FreeRTOS SystemView Tracing by default -CONFIG_SYSVIEW_ENABLE=y -CONFIG_SYSVIEW_TS_SOURCE_TIMER_00=y -CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE=y -CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE=y -CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE=y -CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE=y -CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE=y -CONFIG_SYSVIEW_EVT_IDLE_ENABLE=y -CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE=y -CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE=y +CONFIG_APPTRACE_SV_ENABLE=y +CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00=y +CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE=y # Disable color output in logs CONFIG_LOG_COLORS=n # Enable heap tracing to host diff --git a/examples/system/sysview_tracing_heap_log/sdkconfig.defaults.esp32c3 b/examples/system/sysview_tracing_heap_log/sdkconfig.defaults.esp32c3 new file mode 100644 index 000000000000..675f4d9294df --- /dev/null +++ b/examples/system/sysview_tracing_heap_log/sdkconfig.defaults.esp32c3 @@ -0,0 +1,30 @@ +# Enable single core mode by default +CONFIG_MEMMAP_SMP=n +CONFIG_FREERTOS_UNICORE=y +# 1ms tick period +CONFIG_FREERTOS_HZ=1000 +# Enable application tracing by default +CONFIG_APPTRACE_DEST_JTAG=y +CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE=y +CONFIG_APPTRACE_ENABLE=y +# Enable FreeRTOS SystemView Tracing by default +CONFIG_APPTRACE_SV_ENABLE=y +CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00=y +CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE=y +CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE=y +CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE=y +# Disable color output in logs +CONFIG_LOG_COLORS=n +# Enable heap tracing to host +CONFIG_HEAP_TRACING_TOHOST=y +CONFIG_HEAP_TRACING_STACK_DEPTH=0 diff --git a/examples/wifi/ftm/main/ftm_main.c b/examples/wifi/ftm/main/ftm_main.c index 446329e19a61..2d3eaf23ba29 100644 --- a/examples/wifi/ftm/main/ftm_main.c +++ b/examples/wifi/ftm/main/ftm_main.c @@ -261,7 +261,10 @@ static bool wifi_perform_scan(const char *ssid, bool internal) uint8_t i; ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_scan_start(&scan_config, true) ); + if (ESP_OK != esp_wifi_scan_start(&scan_config, true)) { + ESP_LOGI(TAG_STA, "Failed to perform scan"); + return false; + } esp_wifi_scan_get_ap_num(&g_scan_ap_num); if (g_scan_ap_num == 0) { @@ -317,7 +320,7 @@ static bool wifi_cmd_ap_set(const char* ssid, const char* pass) if (pass) { if (strlen(pass) != 0 && strlen(pass) < 8) { s_reconnect = true; - ESP_LOGE(TAG_AP, "password less than 8"); + ESP_LOGE(TAG_AP, "password cannot be less than 8 characters long"); return false; } strlcpy((char*) g_ap_config.ap.password, pass, MAX_PASSPHRASE_LEN); @@ -341,8 +344,11 @@ static int wifi_cmd_ap(int argc, char** argv) return 1; } - wifi_cmd_ap_set(ap_args.ssid->sval[0], ap_args.password->sval[0]); - ESP_LOGI(TAG_AP, "Starting SoftAP with FTM Responder support, SSID - %s, Password - %s", ap_args.ssid->sval[0], ap_args.password->sval[0]); + if (true == wifi_cmd_ap_set(ap_args.ssid->sval[0], ap_args.password->sval[0])) + ESP_LOGI(TAG_AP, "Starting SoftAP with FTM Responder support, SSID - %s, Password - %s", ap_args.ssid->sval[0], ap_args.password->sval[0]); + else + ESP_LOGE(TAG_AP, "Failed to start SoftAP!"); + return 0; } @@ -476,7 +482,7 @@ static int wifi_cmd_ftm(int argc, char **argv) } bits = xEventGroupWaitBits(ftm_event_group, FTM_REPORT_BIT | FTM_FAILURE_BIT, - pdFALSE, pdFALSE, portMAX_DELAY); + pdTRUE, pdFALSE, portMAX_DELAY); /* Processing data from FTM session */ if (bits & FTM_REPORT_BIT) { ftm_process_report(); @@ -485,7 +491,6 @@ static int wifi_cmd_ftm(int argc, char **argv) g_ftm_report_num_entries = 0; ESP_LOGI(TAG_STA, "Estimated RTT - %d nSec, Estimated Distance - %d.%02d meters", g_rtt_est, g_dist_est / 100, g_dist_est % 100); - xEventGroupClearBits(ftm_event_group, FTM_REPORT_BIT); } else { /* Failure case */ } diff --git a/examples/wifi/getting_started/station/main/station_example_main.c b/examples/wifi/getting_started/station/main/station_example_main.c index f8d91e26e126..e478a4fc2bc2 100644 --- a/examples/wifi/getting_started/station/main/station_example_main.c +++ b/examples/wifi/getting_started/station/main/station_example_main.c @@ -96,11 +96,6 @@ void wifi_init_sta(void) * However these modes are deprecated and not advisable to be used. Incase your Access point * doesn't support WPA2, these mode can be enabled by commenting below line */ .threshold.authmode = WIFI_AUTH_WPA2_PSK, - - .pmf_cfg = { - .capable = true, - .required = false - }, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); diff --git a/examples/wifi/iperf/main/cmd_wifi.c b/examples/wifi/iperf/main/cmd_wifi.c index 08ef097e360e..e5f5369f1d43 100644 --- a/examples/wifi/iperf/main/cmd_wifi.c +++ b/examples/wifi/iperf/main/cmd_wifi.c @@ -148,7 +148,6 @@ static bool wifi_cmd_sta_join(const char* ssid, const char* pass) int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0); wifi_config_t wifi_config = { 0 }; - wifi_config.sta.pmf_cfg.capable = true; strlcpy((char*) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); if (pass) { diff --git a/examples/wifi/iperf/main/iperf_example_main.c b/examples/wifi/iperf/main/iperf_example_main.c index 30f0980fc2a4..46a108092b0d 100644 --- a/examples/wifi/iperf/main/iperf_example_main.c +++ b/examples/wifi/iperf/main/iperf_example_main.c @@ -38,6 +38,9 @@ void app_main(void) #elif CONFIG_ESP_CONSOLE_USB_CDC esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl)); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl)); #endif /* Register commands */ diff --git a/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c b/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c index 1012894e2c40..ea7cb56b6c35 100644 --- a/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c +++ b/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c @@ -243,6 +243,9 @@ void app_main(void) #elif CONFIG_ESP_CONSOLE_USB_CDC esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl)); +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl)); #endif /* Register commands */ diff --git a/examples/wifi/wifi_eap_fast/CMakeLists.txt b/examples/wifi/wifi_eap_fast/CMakeLists.txt new file mode 100644 index 000000000000..c3da72840dda --- /dev/null +++ b/examples/wifi/wifi_eap_fast/CMakeLists.txt @@ -0,0 +1,9 @@ + +# (Automatically converted from project Makefile by convert_to_cmake.py.) + +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(wifi_eap_fast) diff --git a/examples/wifi/wifi_eap_fast/Makefile b/examples/wifi/wifi_eap_fast/Makefile new file mode 100644 index 000000000000..e2a68e2ca377 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := wifi_eap_fast + +include $(IDF_PATH)/make/project.mk diff --git a/examples/wifi/wifi_eap_fast/README.md b/examples/wifi/wifi_eap_fast/README.md new file mode 100644 index 000000000000..aced7cc9bce1 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/README.md @@ -0,0 +1,67 @@ +# WPA2 Enterprise Example + +This example shows how ESP32 connects to AP with Wi-Fi enterprise encryption using the EAP-FAST method. The example does the following steps: + +1. Install CA certificate which is optional. +2. Set user name and password and identity. +3. Set the PAC file which may be empty. +4. Enable wpa2 enterprise. +5. Connect to AP. + +*Note:* 1. EAP-FAST is not supported with `CONFIG_WPA_MBEDTLS_CRYPTO` and so is disabled by default. + 2. Setting the config `fast_provisioning` to methods 0 and 1 do not support saving the PAC credentials in case of a restart or loss of power. + 3. The certificates present in the `examples/wifi/wifi_eap_fast/main` folder contain server certificates which have the corresponding CA as well. These can be used for server validation which is opptional. + 4. The expiration date of these certificates is 2027/06/05. + +### Configuration + +``` +idf.py menuconfig +``` +* Set SSID of Access Point to connect in Example Configuration. +* Enter EAP-ID. +* Enter Username and Password. +* Enable or disable Validate Server option. + +### Build and Flash the project. + +``` +idf.py -p PORT flash monitor +``` + +### Example output + +Here is an example of wpa2 enterprise (FAST method) console output. +``` +I (690) example: Setting WiFi configuration SSID wpa2_test... +I (690) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07 +I (800) wifi:mode : sta (24:6f:28:80:41:78) +I (800) wifi:enable tsf +I (1410) wifi:new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1 +I (2410) wifi:state: init -> auth (b0) +I (2420) wifi:state: auth -> assoc (0) +E (2420) wifi:Association refused temporarily, comeback time 3072 mSec +I (5500) wifi:state: assoc -> assoc (0) +I (5500) wifi:state: assoc -> init (6c0) +I (5500) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 +I (7560) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1 +I (7560) wifi:state: init -> auth (b0) +I (7560) wifi:state: auth -> assoc (0) +I (7570) wifi:state: assoc -> run (10) +I (7770) wifi:connected with wpa2_test, aid = 1, channel 6, BW20, bssid = 24:4b:fe:ab:be:99 +I (7770) wifi:security: WPA2-ENT, phy: bg, rssi: -80 +I (7780) wifi:pm start, type: 1 + +I (7800) example: ~~~~~~~~~~~ +I (7800) example: IP:0.0.0.0 +I (7800) example: MASK:0.0.0.0 +I (7800) example: GW:0.0.0.0 +I (7800) example: ~~~~~~~~~~~ +I (7870) wifi:AP's beacon interval = 102400 us, DTIM period = 1 +I (8580) esp_netif_handlers: sta ip: 192.168.5.3, mask: 255.255.255.0, gw: 192.168.5.1 +I (12800) example: ~~~~~~~~~~~ +I (12800) example: IP:192.168.5.3 +I (12800) example: MASK:255.255.255.0 +I (12800) example: GW:192.168.5.1 +I (12800) example: ~~~~~~~~~~~ +``` diff --git a/examples/wifi/wifi_eap_fast/main/CMakeLists.txt b/examples/wifi/wifi_eap_fast/main/CMakeLists.txt new file mode 100644 index 000000000000..52efdcebe862 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/CMakeLists.txt @@ -0,0 +1,4 @@ +# Embed CA, certificate & key directly into binary +idf_component_register(SRCS "wifi_eap_fast_main.c" + INCLUDE_DIRS "." + EMBED_TXTFILES ca.pem pac_file.pac) diff --git a/examples/wifi/wifi_eap_fast/main/Kconfig.projbuild b/examples/wifi/wifi_eap_fast/main/Kconfig.projbuild new file mode 100644 index 000000000000..3276f85d8df3 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/Kconfig.projbuild @@ -0,0 +1,53 @@ +menu "Example Configuration" + + choice + prompt "Enterprise configuration to be used" + default EXAMPLE_WPA_WPA2_ENTERPRISE + config EXAMPLE_WPA_WPA2_ENTERPRISE + bool "WPA_WPA2_ENT" + config EXAMPLE_WPA3_ENTERPRISE + bool "WPA3_ENT" + depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 + select ESP_WIFI_GCMP_SUPPORT + select ESP_WIFI_GMAC_SUPPORT + select WPA_SUITE_B_192 + endchoice + + config EXAMPLE_WIFI_SSID + string "WiFi SSID" + default "wpa2_test" + help + SSID (network name) for the example to connect to. + + if EXAMPLE_WPA_WPA2_ENTERPRISE + config EXAMPLE_VALIDATE_SERVER_CERT + bool "Validate server" + default y + help + Validate the servers' certificate using CA cert. + endif + + if !EXAMPLE_WPA_WPA2_ENTERPRISE + config EXAMPLE_VALIDATE_SERVER_CERT + default y + endif + + config EXAMPLE_EAP_ID + string "EAP ID" + default "example@espressif.com" + help + Identity in phase 1 of EAP procedure. + + config EXAMPLE_EAP_USERNAME + string "EAP USERNAME" + default "espressif" + help + Username for EAP method. + + config EXAMPLE_EAP_PASSWORD + string "EAP PASSWORD" + default "test11" + help + Password for EAP method. + +endmenu diff --git a/examples/wifi/wifi_eap_fast/main/ca.pem b/examples/wifi/wifi_eap_fast/main/ca.pem new file mode 100644 index 000000000000..1bdf23d94bb3 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/ca.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3DCCA0WgAwIBAgIJAMnlgL1czsmjMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD +VQQGEwJGUjEPMA0GA1UECAwGUmFkaXVzMRIwEAYDVQQHDAlTb21ld2hlcmUxFTAT +BgNVBAoMDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs +ZS5jb20xJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X +DTE3MDYwNzA4MDY0OVoXDTI3MDYwNTA4MDY0OVowgZMxCzAJBgNVBAYTAkZSMQ8w +DQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMGA1UECgwMRXhh +bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG +A1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcN +AQEBBQADgY0AMIGJAoGBALpWR23fn/TmHxsXsHdrydzPSd17fZkc71WsaicgQR66 +1tIVYb22UWGfj9KPM8THMsV74ew4ZkaQ39qvU0iuQIRrKARFHFok+vbaecgWMeWe +vGIqdnmyB9gJYaFOKgtSkfXsu2ddsqdvLYwcDbczrq8X9yEXpN6mnxXeCcPG4F0p +AgMBAAGjggE0MIIBMDAdBgNVHQ4EFgQUgigpdAUpONoDq0pQ3yfxrslCSpcwgcgG +A1UdIwSBwDCBvYAUgigpdAUpONoDq0pQ3yfxrslCSpehgZmkgZYwgZMxCzAJBgNV +BAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMG +A1UECgwMRXhhbXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxl +LmNvbTEmMCQGA1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCCQDJ +5YC9XM7JozAMBgNVHRMEBTADAQH/MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly93 +d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZIhvcNAQELBQADgYEA +euxOBPInSJRKAIseMxPmAabtAqKNslZSmpG4He3lkKt+HM3jfznUt3psmD7j1hFW +S4l7KXzzajvaGYybDq5N9MqrDjhGn3VXZqOLMUNDL7OQq96TzgqsTBT1dmVSbNlt +PQgiAeKAk3tmH4lRRi9MTBSyJ6I92JYcS5H6Bs4ZwCc= +-----END CERTIFICATE----- diff --git a/examples/wifi/wifi_eap_fast/main/component.mk b/examples/wifi/wifi_eap_fast/main/component.mk new file mode 100644 index 000000000000..79d840e3d412 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/component.mk @@ -0,0 +1,9 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + +# embed files from the "certs" directory as binary data symbols +# in the app +COMPONENT_EMBED_TXTFILES := ca.pem +COMPONENT_EMBED_TXTFILES += pac_file.pac diff --git a/examples/wifi/wifi_eap_fast/main/pac_file.pac b/examples/wifi/wifi_eap_fast/main/pac_file.pac new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/examples/wifi/wifi_eap_fast/main/server.crt b/examples/wifi/wifi_eap_fast/main/server.crt new file mode 100644 index 000000000000..0af6f1741fa1 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/server.crt @@ -0,0 +1,70 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 47 (0x2f) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=FR, ST=Radius, L=Somewhere, O=Example Inc./emailAddress=admin@example.com, CN=Example Certificate Authority + Validity + Not Before: Jun 7 08:06:49 2017 GMT + Not After : Jun 5 08:06:49 2027 GMT + Subject: C=FR, ST=Radius, O=Example Inc., CN=Example Server Certificate/emailAddress=admin@example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d8:e2:e0:75:91:83:87:d8:c8:80:c6:20:4d: + e9:14:24:30:98:33:53:fa:56:0e:ec:9a:43:7f:87: + a9:22:94:26:06:c7:ac:b5:d9:ec:55:06:81:b7:0d: + c9:24:51:49:fa:47:fb:4b:4e:fc:ed:75:8a:e1:28: + 32:bc:c5:e0:4c:45:c4:58:60:15:67:1e:6b:40:19: + 3f:f0:ab:92:61:92:2d:71:10:2e:f2:eb:bc:81:2f: + 5a:3b:74:ca:5f:fd:e0:ee:d1:d9:07:6a:6c:20:c0: + 07:88:b4:8b:0f:ad:1e:c9:4f:7c:11:98:37:89:15: + de:24:b1:11:1a:7c:97:4a:cf:f3:c8:cb:79:9e:9c: + c3:71:da:a6:94:97:f5:95:fd:61:06:44:e2:3f:12: + 43:0b:1d:33:48:91:d2:ce:4f:97:a1:ed:6a:30:c7: + 5d:98:b5:6e:0a:b7:4f:d9:03:ec:80:76:09:b0:40: + a1:a1:af:ab:2a:59:c4:0f:56:22:bc:be:14:be:18: + df:10:7d:5d:22:bf:e5:04:77:7a:75:6b:3e:eb:6d: + 20:a1:a7:60:d4:f1:87:9d:9f:60:b9:d3:db:2c:25: + f4:91:4a:f1:d2:40:e5:a1:10:88:a0:41:5a:98:40: + ca:15:d7:e3:e6:3e:c0:6a:d5:46:b2:b4:90:b4:ae: + 3b:e3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.example.com/example_ca.crl + + Signature Algorithm: sha1WithRSAEncryption + a4:25:21:51:0b:22:6c:63:8d:a9:c1:4f:04:33:69:79:34:f0: + 36:dd:8f:6a:27:5f:07:a2:1d:ef:8b:f0:96:e6:e7:a3:b8:3b: + 85:5e:3f:26:43:8a:8e:95:58:9c:a6:db:9c:51:bf:ea:53:16: + 3e:c1:a8:11:1a:c6:cf:0e:a1:17:18:64:d2:05:f1:c0:9c:a6: + 2b:16:c4:29:54:03:d2:17:bd:15:74:d6:ad:8a:8f:2d:cc:27: + 3b:88:88:f2:ea:d0:a2:cb:e9:42:57:df:26:9f:8a:a2:02:2f: + 35:b6:19:1d:26:43:44:af:12:4b:bc:b9:84:50:02:fd:1d:fa: + 50:e8 +-----BEGIN CERTIFICATE----- +MIIDWTCCAsKgAwIBAgIBLzANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx +DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF +eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw +JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw +ODA2NDlaFw0yNzA2MDUwODA2NDlaMHwxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS +YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEjMCEGA1UEAwwaRXhhbXBsZSBT +ZXJ2ZXIgQ2VydGlmaWNhdGUxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu +Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydji4HWRg4fYyIDG +IE3pFCQwmDNT+lYO7JpDf4epIpQmBsestdnsVQaBtw3JJFFJ+kf7S0787XWK4Sgy +vMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSL +D60eyU98EZg3iRXeJLERGnyXSs/zyMt5npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHS +zk+Xoe1qMMddmLVuCrdP2QPsgHYJsEChoa+rKlnED1YivL4UvhjfEH1dIr/lBHd6 +dWs+620goadg1PGHnZ9gudPbLCX0kUrx0kDloRCIoEFamEDKFdfj5j7AatVGsrSQ +tK474wIDAQABo08wTTATBgNVHSUEDDAKBggrBgEFBQcDATA2BgNVHR8ELzAtMCug +KaAnhiVodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGVfY2EuY3JsMA0GCSqG +SIb3DQEBBQUAA4GBAKQlIVELImxjjanBTwQzaXk08Dbdj2onXweiHe+L8Jbm56O4 +O4VePyZDio6VWJym25xRv+pTFj7BqBEaxs8OoRcYZNIF8cCcpisWxClUA9IXvRV0 +1q2Kjy3MJzuIiPLq0KLL6UJX3yafiqICLzW2GR0mQ0SvEku8uYRQAv0d+lDo +-----END CERTIFICATE----- diff --git a/examples/wifi/wifi_eap_fast/main/server.key b/examples/wifi/wifi_eap_fast/main/server.key new file mode 100644 index 000000000000..9b3433273eae --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAydji4HWRg4fYyIDGIE3pFCQwmDNT+lYO7JpDf4epIpQmBses +tdnsVQaBtw3JJFFJ+kf7S0787XWK4SgyvMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu +8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSLD60eyU98EZg3iRXeJLERGnyXSs/zyMt5 +npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHSzk+Xoe1qMMddmLVuCrdP2QPsgHYJsECh +oa+rKlnED1YivL4UvhjfEH1dIr/lBHd6dWs+620goadg1PGHnZ9gudPbLCX0kUrx +0kDloRCIoEFamEDKFdfj5j7AatVGsrSQtK474wIDAQABAoIBAQC2kGDEPBJdMSW2 +VCLfXRiPixwYzXQLXIMrJWwfkQg9qlmqkDd6U50aWkRA2UswegW7RhfYSZ0i+cmf +VMhvTVpOIlwwwtcY6b5/v1bBy60eaySGuuh79xQMlFO8qynQIMStvUfbGTqrdIRb +9VBB4YeS9T12fILejtTZwv2BQ2dj1Y1SCay6Ri85UzJqSClRKgHISybvVdLNjPvP +0TRFBr57zyjL6WE8teKiKchzQko2u86No5uBCdKGsrAkrsdcR0YqlM/pZxd3VKNm ++eny0k+dZZlvcPxzkzP4hEp9+Rw5rP9/s3s/cCwvuuC5JO32ATBWKCbTvPv/XPDb +MdSJtOshAoGBAPzk0eswkcbFYtpnpBNmBAr1dtAdW1lfjUI2ucMMwt7Wns0P/tt+ +gq6Hi1wTaGP0l/dIECgeHwjtWj31ZJjQtFJ1y/kafxo4o9cA8vCydpdvSZaldAfg +sbLlDTDYzEpelaDIbNQBBXFoC5U9JlBhBsIFCL5Z8ZuIeFPsb7t5wwuHAoGBAMxT +jyWfNm1uNxp1xgCnrRsLPQPVnURrSFAqcHrECqRu3F7sozTN7q/cZViemxPvVDGQ +p9c+9bHwaYvW4trO5qDHJ++gGwm5L52bMAY1VUfeTt67fqrey43XpdmzcTX1V9Uj +QWawPUCSDzFjL1MjfCIejtyYf5ash53vj+T8r/vFAoGAA/OPVB1uKazr3n3AEo2F +gqZTNO1AgCT+EArK3EFWyiSQVqPpV4SihheYFdg3yVgJB9QYbIgL9BfBUTaEW97m +8mLkzP+c/Mvlw3ZAVYJ0V+llPPVY2saoACOUES9SAdd4fwqiqK1baGo3xB0wfBEI +CgAKIu9E1ylKuAT5ufQtGAECgYEAtP/kU5h5N3El4QupTdU7VDSdZTMqsHw0v8cI +gsf9AXKvRmtrnBA8u46KPHmruHoO5CVXeSZtsaXdaaH+rYQQ6yXg67WxnehtFLlv +TmCaXiLBTS9cYvMf8FOyuGnsBLeEietEOTov2G5KhR5uwsAxa2wUc7endor5S9/2 +YQuyvV0CgYALbiFpILd5l1ip65eE6JdA3hfttUbV2j2NSW12ej69vqbeOfaSgNse +uYCcXFsBbQPhNPwA+4d1oCe8SyXZg1f7gE812z2Tyr/3vdVnNZlitoxhsHmGiyS7 +gZdaTYCb78l9z0EBdaCVvA16owEle4SR6f9eCwzSI0WPOUra+x/hrA== +-----END RSA PRIVATE KEY----- diff --git a/examples/wifi/wifi_eap_fast/main/server.pem b/examples/wifi/wifi_eap_fast/main/server.pem new file mode 100644 index 000000000000..b6e3c0d16dbb --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/server.pem @@ -0,0 +1,57 @@ +Bag Attributes + localKeyID: 63 3B C1 EE 3A 4A 9B 3E FF 9E E7 BC 17 50 D7 F7 B7 7E 3B C0 +subject=/C=FR/ST=Radius/O=Example Inc./CN=Example Server Certificate/emailAddress=admin@example.com +issuer=/C=FR/ST=Radius/L=Somewhere/O=Example Inc./emailAddress=admin@example.com/CN=Example Certificate Authority +-----BEGIN CERTIFICATE----- +MIIDWTCCAsKgAwIBAgIBLzANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx +DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF +eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw +JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw +ODA2NDlaFw0yNzA2MDUwODA2NDlaMHwxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS +YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEjMCEGA1UEAwwaRXhhbXBsZSBT +ZXJ2ZXIgQ2VydGlmaWNhdGUxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu +Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydji4HWRg4fYyIDG +IE3pFCQwmDNT+lYO7JpDf4epIpQmBsestdnsVQaBtw3JJFFJ+kf7S0787XWK4Sgy +vMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSL +D60eyU98EZg3iRXeJLERGnyXSs/zyMt5npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHS +zk+Xoe1qMMddmLVuCrdP2QPsgHYJsEChoa+rKlnED1YivL4UvhjfEH1dIr/lBHd6 +dWs+620goadg1PGHnZ9gudPbLCX0kUrx0kDloRCIoEFamEDKFdfj5j7AatVGsrSQ +tK474wIDAQABo08wTTATBgNVHSUEDDAKBggrBgEFBQcDATA2BgNVHR8ELzAtMCug +KaAnhiVodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGVfY2EuY3JsMA0GCSqG +SIb3DQEBBQUAA4GBAKQlIVELImxjjanBTwQzaXk08Dbdj2onXweiHe+L8Jbm56O4 +O4VePyZDio6VWJym25xRv+pTFj7BqBEaxs8OoRcYZNIF8cCcpisWxClUA9IXvRV0 +1q2Kjy3MJzuIiPLq0KLL6UJX3yafiqICLzW2GR0mQ0SvEku8uYRQAv0d+lDo +-----END CERTIFICATE----- +Bag Attributes + localKeyID: 63 3B C1 EE 3A 4A 9B 3E FF 9E E7 BC 17 50 D7 F7 B7 7E 3B C0 +Key Attributes: +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIzOJcU8NzjKACAggA +MBQGCCqGSIb3DQMHBAjdK4dY0QgcrgSCBMgCv4euS7bxaRTMSXYliVA+UrAI0iJL +oQgZ6cGFqXqasKu7K6BltLXaKJLX321gV2ofHHAxa1CWFwIgrv/bhci10cJr6BaL +a3+5L5e/EO0eRKVzoplput9mTP27pcJSu8jN5jOu054oamzFKtgGcBuL9mRCAfVq +JSCwbSUHPrwZX6jVDsLggrvE78SIXEYAQDfUrbvBY1kGNNV+U9v410SREYXI3q+8 +a4Paotf2HN5G0nvr0BSJUbY0NUe4AP1NfOM1VE8UiLL3LfZE3ZbOm6XsM8Mxf8rV +BkDOzhErF/dXOE65b5xG4KfoXy78WN7OeJpjNgNUDUl1/3+bc++8f7ZBzOtVAjP7 +diDYU/UrQeLUrLVxTLD6C9J9HvbW5JCEa1FN+pKQKxeaQ9j/dDhJ7XI4ctaIIQui +zrOTLEhBqC10TaNabLNVsLFCgFQMREBVYZoBYbFIZLT4FuRk5yaAYRDCrRKgqlu6 +61E0jOD/hDZIbBO/Vf94d+VaypeFonoz6SdrWgf4heN530d5fd5nOxElRl8LmUcH +LriwJIXB7XCfwgjREceRQpjiqmWPl8hcfe9E2NzwldbE+eLN0mlXgRyLlU+eXova +3r1u60Hb9ocLux3kHUXpZ+MomwkwqIn9qFC0U3KBGt7SmhUWypmoNUPiXP0U4Lno +tynPBODzhDeRv2T0qxULc6OznDE3WOuy88B94/JXhB5D56bRb9FkkpHpmn8MP8SW +fIV3cK/cBoGxgyk+IaL0aQbojFtyeyKbkrz1W3WnPtB3/kqd8USzpCvUBMBVG83D +XzHcU/mRYO61BgyGv0VBXdBtPbmW1CK73eX7gc/uOtqhxUQc3g5hNZDL2rxPCpID +alyGlSQxY8cPWJbYMPq2RHoJNDxnTbFhDm3mdOoTg5qK4+cUZMBqfq1kswXM9Z4p +LSnIviRjpL4a7hhDVAJYOo29rBP+QNdt5CkyLNwjnDv+l8jHOMTP4t1RPvoQx6hc +aOQOcSQnIqDgzot3//dnC2mBTQ66jsOnRPMMs9MQ4up6Wrc5PEt5avBi3B4AQC2Q +TUjL6QAcMR5cJbkecp+5h7W5pUw3OYcYpg6G+unJVGSgZkye2lySGgNuRLmcYjVA +gXfA9a8+HN/TFGHP668pZvHQrfV470ETnHhrh+NLN5AIDR+UFG8is7Xj7Ly2/5bN +M3Q3AYSCb8P8/ZrV3Dfm3qoCoxuNYax0PYt/JBWXTtPG1SClUQg+yo8VMiNw877h +IEdkg1QBxKWY5x+ThK79y+Cwub795ym9bYTwAtH8kpLmamoBT8UvgJumh0i8NGg3 +04B/oyg1P8/TxfbD0uaTPC+tmbIKVyHybTQL6/E0bs2knPp2Zyxno3yE3AI70msZ +mGNuK9mkxITIUbijiRZyeQvZz/x/daYwQ0WuaXXpPQvKcFu7LyIEad8QpIqtSCax +VS9Mtwe7zTCp0jmQDBGltlk1B2rUlQ5rxsFN6kJtBULdQc1TTj0NUp3ESeAE3A/l +wE8fPzBht1OKghJqVndGoh01XhKJfpfaQ85CES0HzA6Nll8SQO0bn6u4SBZGEvBT +pFarRrtS6KbulTDB3yBPrKgd1ZoBQv5/ScW8fPcLi55U6nhR28uu+zKy4yZFgOFR +2KU= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/examples/wifi/wifi_eap_fast/main/wifi_eap_fast_main.c b/examples/wifi/wifi_eap_fast/main/wifi_eap_fast_main.c new file mode 100644 index 000000000000..8588feef3636 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/main/wifi_eap_fast_main.c @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_wpa2.h" +#include "esp_event.h" +#include "esp_log.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "esp_netif.h" + +/* The examples use simple WiFi configuration that you can set via + project configuration menu. + + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" + +*/ +#define EXAMPLE_WIFI_SSID CONFIG_EXAMPLE_WIFI_SSID + +#define EXAMPLE_EAP_ID CONFIG_EXAMPLE_EAP_ID +#define EXAMPLE_EAP_USERNAME CONFIG_EXAMPLE_EAP_USERNAME +#define EXAMPLE_EAP_PASSWORD CONFIG_EXAMPLE_EAP_PASSWORD + +/* FreeRTOS event group to signal when we are connected & ready to make a request */ +static EventGroupHandle_t wifi_event_group; + +/* esp netif object representing the WIFI station */ +static esp_netif_t *sta_netif = NULL; + +/* The event group allows multiple bits for each event, + but we only care about one event - are we connected + to the AP with an IP? */ +const int CONNECTED_BIT = BIT0; + +static const char *TAG = "example"; + +/* CA cert, taken from ca.pem + + To embed it in the app binary, the PEM, CRT and KEY file is named + in the component.mk COMPONENT_EMBED_TXTFILES variable. +*/ +#if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT) +extern uint8_t ca_pem_start[] asm("_binary_ca_pem_start"); +extern uint8_t ca_pem_end[] asm("_binary_ca_pem_end"); +#endif +extern uint8_t pac_file_pac_start[] asm("_binary_pac_file_pac_start"); +extern uint8_t pac_file_pac_end[] asm("_binary_pac_file_pac_end"); + +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + } +} + +static void initialise_wifi(void) +{ +#if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT) + unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start; +#endif + unsigned int pac_file_bytes = pac_file_pac_end - pac_file_pac_start; + + ESP_ERROR_CHECK(esp_netif_init()); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + sta_netif = esp_netif_create_default_wifi_sta(); + assert(sta_netif); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) ); + ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + }, + }; + ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EXAMPLE_EAP_ID, strlen(EXAMPLE_EAP_ID)) ); + +#if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT) || \ + defined(CONFIG_EXAMPLE_WPA3_ENTERPRISE) + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_ca_cert(ca_pem_start, ca_pem_bytes) ); +#endif /* CONFIG_EXAMPLE_VALIDATE_SERVER_CERT */ /* EXAMPLE_WPA3_ENTERPRISE */ + + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EXAMPLE_EAP_USERNAME, strlen(EXAMPLE_EAP_USERNAME)) ); + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EXAMPLE_EAP_PASSWORD, strlen(EXAMPLE_EAP_PASSWORD)) ); + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_pac_file(pac_file_pac_start, pac_file_bytes - 1) ); + esp_eap_fast_config eap_fast_config = { + .fast_provisioning = 2, + .fast_max_pac_list_len = 0, + .fast_pac_format_binary = false + }; + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_fast_phase1_params(eap_fast_config) ); + + ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_enable() ); + ESP_ERROR_CHECK( esp_wifi_start() ); +} + +static void wpa2_enterprise_example_task(void *pvParameters) +{ + esp_netif_ip_info_t ip; + memset(&ip, 0, sizeof(esp_netif_ip_info_t)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + while (1) { + vTaskDelay(5000 / portTICK_PERIOD_MS); + + if (esp_netif_get_ip_info(sta_netif, &ip) == 0) { + ESP_LOGI(TAG, "~~~~~~~~~~~"); + ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip.ip)); + ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip.netmask)); + ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip.gw)); + ESP_LOGI(TAG, "~~~~~~~~~~~"); + } + } +} + +void app_main(void) +{ + ESP_ERROR_CHECK( nvs_flash_init() ); + initialise_wifi(); + xTaskCreate(&wpa2_enterprise_example_task, "wpa2_enterprise_example_task", 4096, NULL, 5, NULL); +} diff --git a/examples/wifi/wifi_eap_fast/sdkconfig.defaults b/examples/wifi/wifi_eap_fast/sdkconfig.defaults new file mode 100644 index 000000000000..be56c7c496a4 --- /dev/null +++ b/examples/wifi/wifi_eap_fast/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_WPA_MBEDTLS_CRYPTO=n diff --git a/examples/wifi/wifi_easy_connect/dpp-enrollee/sdkconfig.defaults b/examples/wifi/wifi_easy_connect/dpp-enrollee/sdkconfig.defaults new file mode 100644 index 000000000000..e67b04732c6e --- /dev/null +++ b/examples/wifi/wifi_easy_connect/dpp-enrollee/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_WPA_DPP_SUPPORT=y diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_ca.pem b/examples/wifi/wpa2_enterprise/main/wpa2_ca.pem index 1bdf23d94bb3..79aa4b780320 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_ca.pem +++ b/examples/wifi/wpa2_enterprise/main/wpa2_ca.pem @@ -1,23 +1,24 @@ -----BEGIN CERTIFICATE----- -MIID3DCCA0WgAwIBAgIJAMnlgL1czsmjMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD -VQQGEwJGUjEPMA0GA1UECAwGUmFkaXVzMRIwEAYDVQQHDAlTb21ld2hlcmUxFTAT -BgNVBAoMDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs -ZS5jb20xJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X -DTE3MDYwNzA4MDY0OVoXDTI3MDYwNTA4MDY0OVowgZMxCzAJBgNVBAYTAkZSMQ8w -DQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMGA1UECgwMRXhh -bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG -A1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcN -AQEBBQADgY0AMIGJAoGBALpWR23fn/TmHxsXsHdrydzPSd17fZkc71WsaicgQR66 -1tIVYb22UWGfj9KPM8THMsV74ew4ZkaQ39qvU0iuQIRrKARFHFok+vbaecgWMeWe -vGIqdnmyB9gJYaFOKgtSkfXsu2ddsqdvLYwcDbczrq8X9yEXpN6mnxXeCcPG4F0p -AgMBAAGjggE0MIIBMDAdBgNVHQ4EFgQUgigpdAUpONoDq0pQ3yfxrslCSpcwgcgG -A1UdIwSBwDCBvYAUgigpdAUpONoDq0pQ3yfxrslCSpehgZmkgZYwgZMxCzAJBgNV -BAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMG -A1UECgwMRXhhbXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxl -LmNvbTEmMCQGA1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCCQDJ -5YC9XM7JozAMBgNVHRMEBTADAQH/MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly93 -d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZIhvcNAQELBQADgYEA -euxOBPInSJRKAIseMxPmAabtAqKNslZSmpG4He3lkKt+HM3jfznUt3psmD7j1hFW -S4l7KXzzajvaGYybDq5N9MqrDjhGn3VXZqOLMUNDL7OQq96TzgqsTBT1dmVSbNlt -PQgiAeKAk3tmH4lRRi9MTBSyJ6I92JYcS5H6Bs4ZwCc= +MIID/TCCAuWgAwIBAgIUatfCTX7iKBpesWLfGDPboZtTLYAwDQYJKoZIhvcNAQEL +BQAwgY0xCzAJBgNVBAYTAklOMQ4wDAYDVQQIDAVTVEFURTENMAsGA1UEBwwEQ0lU +WTEXMBUGA1UECgwORVhBTVBFTCBDQSBPUkcxEDAOBgNVBAsMB3VuaXQgQ0ExEjAQ +BgNVBAMMCUNlcnQgQXV0aDEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5j +b20wHhcNMjIwMTI3MTExOTQyWhcNMjIwMjI2MTExOTQyWjCBjTELMAkGA1UEBhMC +SU4xDjAMBgNVBAgMBVNUQVRFMQ0wCwYDVQQHDARDSVRZMRcwFQYDVQQKDA5FWEFN +UEVMIENBIE9SRzEQMA4GA1UECwwHdW5pdCBDQTESMBAGA1UEAwwJQ2VydCBBdXRo +MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMkpdIyAYWrC1Si56Gpco7qQrRgXujlYpWo7AND4 +gggOVSrTIQGF0gCVBdPACttUVzEIylfPpIY0+Q/brxJCDRlIKLthVUFljtvLcfCC +Xk5212i3m+Hnc8rQVallfHJ+C2IRWX5cK2RPY6NGbM6sUT05vqoSr4Yo4MndUBcj +vU4HzEyZ3bGMrucA7inpdGKEGWbG4kEBKrQs8EHX9a6iAxz1WI4uP4piV5sbADBZ +0vCuWKzqrfGmfEp9ugOln9++2YsNSL03qMCHgiWRZNsZ/7JF7P4dDFbSPBHLLpTd +ykTRDZMVBV33wLINX1dd4O3Oat7zpkw3Xi1fpBWLtx4cOp8CAwEAAaNTMFEwHQYD +VR0OBBYEFHay+5pwKLYskiaZL9O+lfRSPN52MB8GA1UdIwQYMBaAFHay+5pwKLYs +kiaZL9O+lfRSPN52MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AAQdNQucDXU/uBJgQzPjaVeO8g1j1YPXb8tmMnta2daR6M9MX3iczZFvLU5egE2x +aYJ/0J/dKxLj2r5iRWQMEjNgpIWIO2hmTsHfq/hBql+5RJQnaeTlfJ+q8k3aYlEA +bHtkHuGJbP5r0H6lcubcuqzBDI/oYDoHwDF5+FyRjPBahyA7an7+MJnuhKxzQdX1 +kkpz3uxO/nL9LS7whUl09PhoRGFM4sIZxvTKw0eyChVRUEH6Z5E3JqOKOS1+B5VI +y3zi6kaluKsS5jMJ9PlXmdkiMKQWeknOeG54a4bzIVKPgDPdu9k2S18qEbSPavMF +7JvRlzqkfmqSQ7UTtPnulh4= -----END CERTIFICATE----- diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_client.crt b/examples/wifi/wpa2_enterprise/main/wpa2_client.crt index 12dbfc8f5504..e8c0f68651fb 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_client.crt +++ b/examples/wifi/wpa2_enterprise/main/wpa2_client.crt @@ -1,70 +1,83 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 48 (0x30) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=FR, ST=Radius, L=Somewhere, O=Example Inc./emailAddress=admin@example.com, CN=Example Certificate Authority + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IN, ST=STATE, L=CITY, O=EXAMPEL CA ORG, OU=unit CA, CN=Cert Auth/emailAddress=admin@example.com Validity - Not Before: Jun 7 08:06:49 2017 GMT - Not After : Jun 5 08:06:49 2027 GMT - Subject: C=FR, ST=Radius, O=Example Inc., CN=user@example.com/emailAddress=user@example.com + Not Before: Jan 27 11:29:15 2022 GMT + Not After : Jan 27 11:29:15 2023 GMT + Subject: C=IN, ST=STATE, L=CITY, O=EXAMPLE INC, OU=unit Client, CN=Example Client/emailAddress=user@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) + RSA Public-Key: (2048 bit) Modulus: - 00:d2:f6:be:72:a5:ab:2e:56:0c:dd:f2:3b:2c:7c: - e0:5d:05:40:af:0c:8c:f3:82:0c:d0:18:34:b4:e3: - 7d:5f:8d:0a:3e:aa:79:02:f9:96:ad:10:00:ec:51: - e9:dc:3f:fb:ea:b0:57:eb:48:c7:ca:ef:e8:05:ab: - ee:3f:66:ba:5c:9e:7f:40:85:9f:25:a0:e0:e3:7c: - cf:b6:e6:31:f5:fd:24:03:c8:f4:fb:d8:a4:f3:92: - 29:05:aa:55:43:80:f7:3e:13:10:43:3a:89:24:be: - d8:01:86:d1:69:73:44:7d:f8:b9:46:2b:6b:51:d0: - 11:31:4b:06:ae:9f:45:fa:12:17:0c:ef:6a:fa:d0: - f7:36:46:eb:2e:db:4e:20:46:01:33:ac:b1:f7:4a: - e6:18:3d:53:22:dc:e8:4a:12:78:11:2f:e4:3b:92: - bd:d7:07:5a:c9:81:5d:48:58:c8:0f:9b:e9:a4:0f: - bb:89:b1:ad:38:07:6f:93:d0:a6:12:56:f9:07:48: - d2:23:2f:a3:a9:93:b0:11:0a:27:4c:48:0a:8d:70: - 41:68:76:7a:dd:bc:54:c3:42:33:b0:7b:f6:ae:1f: - e7:95:5e:11:ca:f2:b4:4b:5c:ba:47:64:f0:f3:d7: - 87:95:7f:93:06:a1:72:c9:81:12:a5:b7:8f:9d:7e: - d1:ef + 00:c4:9c:0a:f9:43:91:7f:92:6c:ea:f5:cb:a4:b4: + e2:a0:56:c5:9b:2b:6f:e0:84:25:4d:69:f4:4f:22: + 13:80:8e:04:8e:73:c4:61:14:2f:fd:df:58:60:10: + 98:97:6e:a4:8d:50:84:ba:ce:93:70:3d:ed:e6:01: + d9:4f:9d:27:c7:bf:a0:fc:89:fa:1a:62:4f:cd:96: + 3e:c8:7c:27:43:06:1d:38:b9:f1:d1:a3:0a:d1:a1: + b9:7a:2c:ec:8a:90:c3:3c:d5:51:7e:c1:67:42:81: + f1:fc:47:8a:c9:6f:37:19:71:06:09:c6:ce:61:7c: + 7a:bd:57:4a:a0:15:ee:12:ee:3d:1e:50:a5:2c:13: + 30:bf:d3:8a:57:05:31:39:66:23:1d:1d:ca:b6:06: + 5f:e8:a0:4e:b8:0d:87:ca:78:d3:83:92:e3:ba:c5: + 5b:20:cc:e2:26:b0:11:49:d5:a9:4d:40:49:b9:95: + 58:ab:cd:03:14:38:21:b5:a4:6e:c1:71:f8:5d:23: + 13:31:2f:bd:e6:61:7d:0d:da:ef:b7:c6:e0:27:93: + 00:45:51:1f:99:2f:1d:cd:fe:77:dd:5a:4e:1b:c6: + 92:fe:a0:29:15:6c:47:5d:b8:1f:dd:b4:2e:ff:91: + 8b:3d:e1:41:f4:74:32:7d:58:45:5e:19:96:ed:e2: + 92:fb Exponent: 65537 (0x10001) X509v3 extensions: - X509v3 Extended Key Usage: - TLS Web Client Authentication - X509v3 CRL Distribution Points: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 70:76:1C:98:6A:8B:7D:CB:BD:91:19:FE:74:CE:04:9D:10:9C:57:09 + X509v3 Authority Key Identifier: + keyid:76:B2:FB:9A:70:28:B6:2C:92:26:99:2F:D3:BE:95:F4:52:3C:DE:76 - Full Name: - URI:http://www.example.com/example_ca.crl - - Signature Algorithm: sha1WithRSAEncryption - 2d:02:bc:7b:88:b8:5c:e1:07:b8:bb:ba:b2:f3:98:14:8f:cb: - b0:21:13:b5:e5:6f:05:4f:92:fa:ac:c0:53:a7:b0:cd:7e:ba: - 87:36:85:25:d7:41:c5:29:84:22:74:af:bf:3e:34:36:d5:24: - 7a:81:e2:1b:54:52:85:6f:76:de:dc:63:98:45:fc:2c:31:fa: - 22:a4:72:3a:8d:d4:6a:2e:de:33:10:41:eb:94:1d:e3:59:cd: - b2:be:ab:f0:b6:20:86:9c:b8:46:ee:c5:64:ba:b6:6c:cc:53: - 44:7a:80:12:77:7c:e7:51:67:91:32:2f:88:9d:93:a8:ef:d6: - cd:de + Signature Algorithm: sha256WithRSAEncryption + 72:66:54:e3:01:bc:fe:11:fc:14:ff:a1:29:83:6a:03:ed:29: + 80:c6:02:29:4a:cd:8c:d3:3f:a4:d8:b7:57:64:4e:76:a1:9b: + ff:11:da:1a:66:1d:4b:79:0c:eb:2d:36:03:91:a9:6f:a0:63: + 0b:42:3f:61:19:ef:5e:12:8e:85:2a:eb:0f:38:34:4f:56:52: + 36:05:c6:0b:73:07:ed:20:17:ef:1c:22:af:6a:d1:ba:7d:82: + e3:47:4d:39:09:dc:94:e2:43:8f:57:b6:6b:5c:58:bc:0e:b8: + 9f:72:51:e5:ed:ad:a8:e7:9e:d5:eb:bb:e8:3f:08:73:82:e4: + 1c:c6:45:1a:a3:47:0e:0b:dd:d8:f9:58:28:c0:8c:77:78:9a: + 62:7b:24:be:fa:5a:c6:95:ae:a0:fa:80:0a:19:2d:00:3f:50: + ae:9c:07:65:e8:7b:5a:04:da:86:23:d8:30:23:70:87:14:f8: + ac:82:ef:3b:38:f9:84:90:f8:b1:ff:87:6d:47:8e:1b:0c:8e: + 17:13:9e:72:2c:a2:9a:76:7c:87:e4:0d:a2:85:6a:1d:fc:f4: + 01:ea:21:91:b6:5d:48:3a:60:21:8e:54:26:99:3c:ff:7e:49: + 92:81:48:b5:d7:8a:59:84:aa:14:e7:09:23:7c:74:2d:62:5a: + 4e:17:da:82 -----BEGIN CERTIFICATE----- -MIIDTjCCAregAwIBAgIBMDANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx -DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF -eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw -JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw -ODA2NDlaFw0yNzA2MDUwODA2NDlaMHExCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS -YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEZMBcGA1UEAwwQdXNlckBleGFt -cGxlLmNvbTEfMB0GCSqGSIb3DQEJARYQdXNlckBleGFtcGxlLmNvbTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBANL2vnKlqy5WDN3yOyx84F0FQK8MjPOC -DNAYNLTjfV+NCj6qeQL5lq0QAOxR6dw/++qwV+tIx8rv6AWr7j9mulyef0CFnyWg -4ON8z7bmMfX9JAPI9PvYpPOSKQWqVUOA9z4TEEM6iSS+2AGG0WlzRH34uUYra1HQ -ETFLBq6fRfoSFwzvavrQ9zZG6y7bTiBGATOssfdK5hg9UyLc6EoSeBEv5DuSvdcH -WsmBXUhYyA+b6aQPu4mxrTgHb5PQphJW+QdI0iMvo6mTsBEKJ0xICo1wQWh2et28 -VMNCM7B79q4f55VeEcrytEtcukdk8PPXh5V/kwahcsmBEqW3j51+0e8CAwEAAaNP -ME0wEwYDVR0lBAwwCgYIKwYBBQUHAwIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDov -L3d3dy5leGFtcGxlLmNvbS9leGFtcGxlX2NhLmNybDANBgkqhkiG9w0BAQUFAAOB -gQAtArx7iLhc4Qe4u7qy85gUj8uwIRO15W8FT5L6rMBTp7DNfrqHNoUl10HFKYQi -dK+/PjQ21SR6geIbVFKFb3be3GOYRfwsMfoipHI6jdRqLt4zEEHrlB3jWc2yvqvw -tiCGnLhG7sVkurZszFNEeoASd3znUWeRMi+InZOo79bN3g== +MIIEFzCCAv+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjTELMAkGA1UEBhMCSU4x +DjAMBgNVBAgMBVNUQVRFMQ0wCwYDVQQHDARDSVRZMRcwFQYDVQQKDA5FWEFNUEVM +IENBIE9SRzEQMA4GA1UECwwHdW5pdCBDQTESMBAGA1UEAwwJQ2VydCBBdXRoMSAw +HgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yMjAxMjcxMTI5MTVa +Fw0yMzAxMjcxMTI5MTVaMIGSMQswCQYDVQQGEwJJTjEOMAwGA1UECAwFU1RBVEUx +DTALBgNVBAcMBENJVFkxFDASBgNVBAoMC0VYQU1QTEUgSU5DMRQwEgYDVQQLDAt1 +bml0IENsaWVudDEXMBUGA1UEAwwORXhhbXBsZSBDbGllbnQxHzAdBgkqhkiG9w0B +CQEWEHVzZXJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDEnAr5Q5F/kmzq9cuktOKgVsWbK2/ghCVNafRPIhOAjgSOc8RhFC/931hg +EJiXbqSNUIS6zpNwPe3mAdlPnSfHv6D8ifoaYk/Nlj7IfCdDBh04ufHRowrRobl6 +LOyKkMM81VF+wWdCgfH8R4rJbzcZcQYJxs5hfHq9V0qgFe4S7j0eUKUsEzC/04pX +BTE5ZiMdHcq2Bl/ooE64DYfKeNODkuO6xVsgzOImsBFJ1alNQEm5lVirzQMUOCG1 +pG7BcfhdIxMxL73mYX0N2u+3xuAnkwBFUR+ZLx3N/nfdWk4bxpL+oCkVbEdduB/d +tC7/kYs94UH0dDJ9WEVeGZbt4pL7AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW +BBRwdhyYaot9y72RGf50zgSdEJxXCTAfBgNVHSMEGDAWgBR2svuacCi2LJImmS/T +vpX0UjzedjANBgkqhkiG9w0BAQsFAAOCAQEAcmZU4wG8/hH8FP+hKYNqA+0pgMYC +KUrNjNM/pNi3V2ROdqGb/xHaGmYdS3kM6y02A5Gpb6BjC0I/YRnvXhKOhSrrDzg0 +T1ZSNgXGC3MH7SAX7xwir2rRun2C40dNOQnclOJDj1e2a1xYvA64n3JR5e2tqOee +1eu76D8Ic4LkHMZFGqNHDgvd2PlYKMCMd3iaYnskvvpaxpWuoPqAChktAD9QrpwH +Zeh7WgTahiPYMCNwhxT4rILvOzj5hJD4sf+HbUeOGwyOFxOeciyimnZ8h+QNooVq +Hfz0AeohkbZdSDpgIY5UJpk8/35JkoFItdeKWYSqFOcJI3x0LWJaThfagg== -----END CERTIFICATE----- diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_client.key b/examples/wifi/wpa2_enterprise/main/wpa2_client.key index 99936e25b7a9..249d0b0030f3 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_client.key +++ b/examples/wifi/wpa2_enterprise/main/wpa2_client.key @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA0va+cqWrLlYM3fI7LHzgXQVArwyM84IM0Bg0tON9X40KPqp5 -AvmWrRAA7FHp3D/76rBX60jHyu/oBavuP2a6XJ5/QIWfJaDg43zPtuYx9f0kA8j0 -+9ik85IpBapVQ4D3PhMQQzqJJL7YAYbRaXNEffi5RitrUdARMUsGrp9F+hIXDO9q -+tD3NkbrLttOIEYBM6yx90rmGD1TItzoShJ4ES/kO5K91wdayYFdSFjID5vppA+7 -ibGtOAdvk9CmElb5B0jSIy+jqZOwEQonTEgKjXBBaHZ63bxUw0IzsHv2rh/nlV4R -yvK0S1y6R2Tw89eHlX+TBqFyyYESpbePnX7R7wIDAQABAoIBAQC5PncO3tBIeMEF -pu007FZq9/DLhP7D2B9+HrMxX0y4uXUUf8aQyS74ukPFP0xV3U1M0BnzfU4KscyQ -Jl+nBoKAT6C3vF15wiGXQAJ4vPuD4Ate03fjKWH2ixJAakhCZR01QbIXBnBkdrvf -401BBjlPUDcIGZo8FbLzEMlGTo84vE9v3Qmkbi+PzPCh2YC+NDmsOcIW1zpmwyYC -ZYCpoWgl4++kqXXn0NGhuaOgB0JLsJOBpx/hOOjBU/wXCKaXZ1vchYqfbvvx2gf2 -WX4P0CiTH1z7MEAHanaZkcnNyxV/oF1EIMY5p0vDDzgrKtppvPOqspjydje03+CE -t0wKGPi5AoGBAPAG2Y4efgwLcoWdPjKZtsHLhDhLJnvxkqnNkzdPnLZojNi8pKkV -/Yu++pPemJZZa4YAp+OnqyEfhcha+HYqKMwRC8t3YrEVOlRQTfW/OoSrp059JIRV -jTvq/u7DdYGJRRgMLUJiEI+7xj1WbTc2EceJAgn0qfKvbvBtVJP0LH1TAoGBAOEA -xZB7SwyX+zDGRTugqMYg+sYobbQHJ7utLyoX+ckeG+sPEjEYLpQQfshET/gwF8ZK -4aILkACx/tna799xCjQdmyyc338NO9WULlY1xF+65WfeaxrtTAsqVikX3p19McRI -ijX8k7Msy3gYWJXev3MCtPT2+g68IgbL/W2wY+l1AoGAT7xGy0Jv5vpqid5pig+s -OYatHrJAT445hXUIQaiNy77Bg0JvhMgMWT8RKMwabl+4K2TOYP8TB0bcf2lQ/pgU -w22qOGYpf+AoZ1fh/hAPlYEcbCOAXQG6kDwJgjGmOGjsbgelhVbkX4smWLv8PgoV -L+7goYQIbNlAhlgbb6b+nIcCgYBB7Zr2Cdpkt0en9ACnRx0M6O7yDziNzqbqzAUM -3XeYYZUmnATlk8NaKTcs8S9JdrYQqTJR6/dm7MDTDt7IZvPpb19fhBvMu5DztPaa -1ihTMI01kStq+WsVvnL+mXrmRJ/HdsXgqcCReKep6eBTEbChP4LMYG3G0YNa4HzC -njO4XQKBgQDRnbqqg2CNTnS94BN2D3uzzELtwsIG6aVCtl09ZsLnGaBKVVDtP6BI -j2hGD7xw4g5JeSPIJU5J03nALTY3hz1JyI7AJCX7+JRtUTX2A8C4mlbeul7ilGaU -A7MFT8GqhjYYa84GzNcA1mK8ynlixpL8+yzTT/8lWInWRBa69SkktA== +MIIEogIBAAKCAQEAxJwK+UORf5Js6vXLpLTioFbFmytv4IQlTWn0TyITgI4EjnPE +YRQv/d9YYBCYl26kjVCEus6TcD3t5gHZT50nx7+g/In6GmJPzZY+yHwnQwYdOLnx +0aMK0aG5eizsipDDPNVRfsFnQoHx/EeKyW83GXEGCcbOYXx6vVdKoBXuEu49HlCl +LBMwv9OKVwUxOWYjHR3KtgZf6KBOuA2HynjTg5LjusVbIMziJrARSdWpTUBJuZVY +q80DFDghtaRuwXH4XSMTMS+95mF9Ddrvt8bgJ5MARVEfmS8dzf533VpOG8aS/qAp +FWxHXbgf3bQu/5GLPeFB9HQyfVhFXhmW7eKS+wIDAQABAoIBADWnlAMUYnebISg5 +7dpEFvjE1WaUQxLVXUy0Fp0l4oaZuzqY80W++Z3hvr9wqAPjiPqbt603RNtDu1Gi +vYhRjhKgBDIHAX8Dx12GnBmgcCKFX6IkdI7OXNx6syBZdDAYc399g6EA7MokpkI/ +z+tK85F427n9TEMkcmaLlOz9Lxxw9niRmGsafGTHh+BswfKOhPOWs3+VGthBKFyt +JFJdZStLBpJqPNu+3PeVgqN33At9cy7CPTD/HFtRn3aRuRPxrxg16gAtkaNcv5pY +hSKLtytoble26o9WCeDuslqzU9nZ96if/WCesf15/suHMljqP9C5x7UovT2gsTU/ +B0UBLEECgYEA+xfRwjm0JaKK3x4htyUtQF2pxi2XfPxStOM3hCywgVwcX/NWYiY0 +17xGPuOV84ovm1tSBi/J++WKlvXGaN0MRb+xLQLi5YzUxFnEOnZ/jf6ivqXMBWF3 +u8EMRib5PH/+g5f/0k3i6cQ8uMyyDmaX/f00JDTjKfylq4bZ+VWD2psCgYEAyHOm +l8Lok4xqkYtMMLsy5TVRIlDNNRe7E8zxI3ioKi43WbgbNH7QMoQke7dUJIB4i7nk +n6kNeNOkq663go4A23toKa7M1zD+WAq6Q3Iwx+5YE7Ppx+Vnd3qCTNTFivi5BgRW +4ZWuV+ogHtUIvfXgVb6dG3kqXq4aAVgGdCgZ/yECgYAtcH4RPAgR13xyLC3FywCJ +aWnT52RGxhLhkUz2qm+2uUiZRJwZXvipIfVEZEM6s4MyBjCt1fAjmcKe1xN03qvd +43bYwnD1QasvbV9JhTBILhCdl7t4Lc9RNvpVp6/q9u7EObmeAWJTE6Q5fTGr0X0o +Ba5t7vQ9IO+KPvkrWgJmiQKBgHBOS3IPo5q3OyXcM43B9BvzKUfemXo7l3bahefn +u+AWELDVs3hP7HnBC2e9KQliaSdvuSWy43dkrIf71Zjx0o0lsRBZfS67pmTRbdZH +7gi2AubXEA4M+1E3dDVzqFHaVF+Ioty0rf9XjzN3C/TSAyRHLWKtGg394VgLZ2JA +7X/BAoGAQit+fRX/Ct8pZLxngG8XpYhJIbN5Jvv4vqSCvEhaMDJ+VHD9tAU+QWRU +lQ0uZelaazy3Ilc64Sdh8syOMlDhGM9HWA0kT3rwarMGbO078e8kWua47ghTbSXh +9dgoL6wOtdBTo2sTfmG8FBQRwFh9wj4bSomkUAhjpXid4GCNdH8= -----END RSA PRIVATE KEY----- diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_client.pem b/examples/wifi/wpa2_enterprise/main/wpa2_client.pem index c7c4fe7ddaa0..e8c0f68651fb 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_client.pem +++ b/examples/wifi/wpa2_enterprise/main/wpa2_client.pem @@ -1,57 +1,83 @@ -Bag Attributes - localKeyID: 40 1A 0E 8F 13 CA 96 2C 6D DB 18 E4 EF A8 83 84 0C 61 85 FE -subject=/C=FR/ST=Radius/O=Example Inc./CN=user@example.com/emailAddress=user@example.com -issuer=/C=FR/ST=Radius/L=Somewhere/O=Example Inc./emailAddress=admin@example.com/CN=Example Certificate Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IN, ST=STATE, L=CITY, O=EXAMPEL CA ORG, OU=unit CA, CN=Cert Auth/emailAddress=admin@example.com + Validity + Not Before: Jan 27 11:29:15 2022 GMT + Not After : Jan 27 11:29:15 2023 GMT + Subject: C=IN, ST=STATE, L=CITY, O=EXAMPLE INC, OU=unit Client, CN=Example Client/emailAddress=user@example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:c4:9c:0a:f9:43:91:7f:92:6c:ea:f5:cb:a4:b4: + e2:a0:56:c5:9b:2b:6f:e0:84:25:4d:69:f4:4f:22: + 13:80:8e:04:8e:73:c4:61:14:2f:fd:df:58:60:10: + 98:97:6e:a4:8d:50:84:ba:ce:93:70:3d:ed:e6:01: + d9:4f:9d:27:c7:bf:a0:fc:89:fa:1a:62:4f:cd:96: + 3e:c8:7c:27:43:06:1d:38:b9:f1:d1:a3:0a:d1:a1: + b9:7a:2c:ec:8a:90:c3:3c:d5:51:7e:c1:67:42:81: + f1:fc:47:8a:c9:6f:37:19:71:06:09:c6:ce:61:7c: + 7a:bd:57:4a:a0:15:ee:12:ee:3d:1e:50:a5:2c:13: + 30:bf:d3:8a:57:05:31:39:66:23:1d:1d:ca:b6:06: + 5f:e8:a0:4e:b8:0d:87:ca:78:d3:83:92:e3:ba:c5: + 5b:20:cc:e2:26:b0:11:49:d5:a9:4d:40:49:b9:95: + 58:ab:cd:03:14:38:21:b5:a4:6e:c1:71:f8:5d:23: + 13:31:2f:bd:e6:61:7d:0d:da:ef:b7:c6:e0:27:93: + 00:45:51:1f:99:2f:1d:cd:fe:77:dd:5a:4e:1b:c6: + 92:fe:a0:29:15:6c:47:5d:b8:1f:dd:b4:2e:ff:91: + 8b:3d:e1:41:f4:74:32:7d:58:45:5e:19:96:ed:e2: + 92:fb + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 70:76:1C:98:6A:8B:7D:CB:BD:91:19:FE:74:CE:04:9D:10:9C:57:09 + X509v3 Authority Key Identifier: + keyid:76:B2:FB:9A:70:28:B6:2C:92:26:99:2F:D3:BE:95:F4:52:3C:DE:76 + + Signature Algorithm: sha256WithRSAEncryption + 72:66:54:e3:01:bc:fe:11:fc:14:ff:a1:29:83:6a:03:ed:29: + 80:c6:02:29:4a:cd:8c:d3:3f:a4:d8:b7:57:64:4e:76:a1:9b: + ff:11:da:1a:66:1d:4b:79:0c:eb:2d:36:03:91:a9:6f:a0:63: + 0b:42:3f:61:19:ef:5e:12:8e:85:2a:eb:0f:38:34:4f:56:52: + 36:05:c6:0b:73:07:ed:20:17:ef:1c:22:af:6a:d1:ba:7d:82: + e3:47:4d:39:09:dc:94:e2:43:8f:57:b6:6b:5c:58:bc:0e:b8: + 9f:72:51:e5:ed:ad:a8:e7:9e:d5:eb:bb:e8:3f:08:73:82:e4: + 1c:c6:45:1a:a3:47:0e:0b:dd:d8:f9:58:28:c0:8c:77:78:9a: + 62:7b:24:be:fa:5a:c6:95:ae:a0:fa:80:0a:19:2d:00:3f:50: + ae:9c:07:65:e8:7b:5a:04:da:86:23:d8:30:23:70:87:14:f8: + ac:82:ef:3b:38:f9:84:90:f8:b1:ff:87:6d:47:8e:1b:0c:8e: + 17:13:9e:72:2c:a2:9a:76:7c:87:e4:0d:a2:85:6a:1d:fc:f4: + 01:ea:21:91:b6:5d:48:3a:60:21:8e:54:26:99:3c:ff:7e:49: + 92:81:48:b5:d7:8a:59:84:aa:14:e7:09:23:7c:74:2d:62:5a: + 4e:17:da:82 -----BEGIN CERTIFICATE----- -MIIDTjCCAregAwIBAgIBMDANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx -DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF -eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw -JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw -ODA2NDlaFw0yNzA2MDUwODA2NDlaMHExCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS -YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEZMBcGA1UEAwwQdXNlckBleGFt -cGxlLmNvbTEfMB0GCSqGSIb3DQEJARYQdXNlckBleGFtcGxlLmNvbTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBANL2vnKlqy5WDN3yOyx84F0FQK8MjPOC -DNAYNLTjfV+NCj6qeQL5lq0QAOxR6dw/++qwV+tIx8rv6AWr7j9mulyef0CFnyWg -4ON8z7bmMfX9JAPI9PvYpPOSKQWqVUOA9z4TEEM6iSS+2AGG0WlzRH34uUYra1HQ -ETFLBq6fRfoSFwzvavrQ9zZG6y7bTiBGATOssfdK5hg9UyLc6EoSeBEv5DuSvdcH -WsmBXUhYyA+b6aQPu4mxrTgHb5PQphJW+QdI0iMvo6mTsBEKJ0xICo1wQWh2et28 -VMNCM7B79q4f55VeEcrytEtcukdk8PPXh5V/kwahcsmBEqW3j51+0e8CAwEAAaNP -ME0wEwYDVR0lBAwwCgYIKwYBBQUHAwIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDov -L3d3dy5leGFtcGxlLmNvbS9leGFtcGxlX2NhLmNybDANBgkqhkiG9w0BAQUFAAOB -gQAtArx7iLhc4Qe4u7qy85gUj8uwIRO15W8FT5L6rMBTp7DNfrqHNoUl10HFKYQi -dK+/PjQ21SR6geIbVFKFb3be3GOYRfwsMfoipHI6jdRqLt4zEEHrlB3jWc2yvqvw -tiCGnLhG7sVkurZszFNEeoASd3znUWeRMi+InZOo79bN3g== +MIIEFzCCAv+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjTELMAkGA1UEBhMCSU4x +DjAMBgNVBAgMBVNUQVRFMQ0wCwYDVQQHDARDSVRZMRcwFQYDVQQKDA5FWEFNUEVM +IENBIE9SRzEQMA4GA1UECwwHdW5pdCBDQTESMBAGA1UEAwwJQ2VydCBBdXRoMSAw +HgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yMjAxMjcxMTI5MTVa +Fw0yMzAxMjcxMTI5MTVaMIGSMQswCQYDVQQGEwJJTjEOMAwGA1UECAwFU1RBVEUx +DTALBgNVBAcMBENJVFkxFDASBgNVBAoMC0VYQU1QTEUgSU5DMRQwEgYDVQQLDAt1 +bml0IENsaWVudDEXMBUGA1UEAwwORXhhbXBsZSBDbGllbnQxHzAdBgkqhkiG9w0B +CQEWEHVzZXJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDEnAr5Q5F/kmzq9cuktOKgVsWbK2/ghCVNafRPIhOAjgSOc8RhFC/931hg +EJiXbqSNUIS6zpNwPe3mAdlPnSfHv6D8ifoaYk/Nlj7IfCdDBh04ufHRowrRobl6 +LOyKkMM81VF+wWdCgfH8R4rJbzcZcQYJxs5hfHq9V0qgFe4S7j0eUKUsEzC/04pX +BTE5ZiMdHcq2Bl/ooE64DYfKeNODkuO6xVsgzOImsBFJ1alNQEm5lVirzQMUOCG1 +pG7BcfhdIxMxL73mYX0N2u+3xuAnkwBFUR+ZLx3N/nfdWk4bxpL+oCkVbEdduB/d +tC7/kYs94UH0dDJ9WEVeGZbt4pL7AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW +BBRwdhyYaot9y72RGf50zgSdEJxXCTAfBgNVHSMEGDAWgBR2svuacCi2LJImmS/T +vpX0UjzedjANBgkqhkiG9w0BAQsFAAOCAQEAcmZU4wG8/hH8FP+hKYNqA+0pgMYC +KUrNjNM/pNi3V2ROdqGb/xHaGmYdS3kM6y02A5Gpb6BjC0I/YRnvXhKOhSrrDzg0 +T1ZSNgXGC3MH7SAX7xwir2rRun2C40dNOQnclOJDj1e2a1xYvA64n3JR5e2tqOee +1eu76D8Ic4LkHMZFGqNHDgvd2PlYKMCMd3iaYnskvvpaxpWuoPqAChktAD9QrpwH +Zeh7WgTahiPYMCNwhxT4rILvOzj5hJD4sf+HbUeOGwyOFxOeciyimnZ8h+QNooVq +Hfz0AeohkbZdSDpgIY5UJpk8/35JkoFItdeKWYSqFOcJI3x0LWJaThfagg== -----END CERTIFICATE----- -Bag Attributes - localKeyID: 40 1A 0E 8F 13 CA 96 2C 6D DB 18 E4 EF A8 83 84 0C 61 85 FE -Key Attributes: ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIvLOGpsoWmVMCAggA -MBQGCCqGSIb3DQMHBAhE0X+F6dzt+QSCBMjeI5lZaP89SD5MPX7wzByOKAEFrBMF -89epa3xAtxb6r42WRIoidg2MwVxsG5qjNt6+iD4AZuqDCP6J7UDg5LpWGicG0jXe -Wc947pIUUc4q29ZYoAMG4Kx6ccF864rdGPjwhkqCg3KQJsUp8uXNltFdhni7cQ5e -eHNGkL1YHpAYGJJQNchHjbyIMfhzSbc2nSPmCvMbN5PucJH183Cw4UzonfUHkvzA -VZmRrFkbd8F+mojie9x8MghWaNlozs2Rn+pAhk1YSmH+w++ZfSiTwAhN1LA6AdjH -FvCEUJHyrFxEPVPMJsfVTYM1t1PxCIfMykh6bby9esH78L3ItpDkMC4TJWq4q7zA -fxufhC8DCxdz5pLEYSrxBF+3YdG4vqIPF5fXj0IqtiYP8se01Smc5C5JuFtYQxyZ -E10hiSKJvDr0VCiBswyBBc4QPGI2y2vDpg1R5Ure2Mp1phDTcGIoDKw6bwlVfiTb -d0nKYwXDO5OigZ/W92FO4hAMIe+7E+q3If7Rp4fvyECoHlT2WYQ4Sq+xxSWxQSv6 -RHrTyyHTg9VIdMDxI6aLiLZBXhh1Q2fkRrh1utAfYH4hAhUscp8v1+0XQo93efbn -JJ7oPhbeapPIqzabcRyUG5dwuKzdzjN/k/R90h3DEzqFE372MeyYghfPB3VQolHd -GZ1bAEiAYkjgVQbezTZ5vON+hqz1f1gIanpCB+b1pW32ljS4ANEm3SjZfaUt41Wu -lO2Btpp4ugs4dt/HBJbzTGHwEHAqtYux+GYMeBZkXFabMozU1rY8yTsF6Oz1Taj6 -fZlm3NJ4gcnLx8lLAITSTJ63GwhPAxEmhmsA98yCJ4BIPgkBpCDT9wFyRLTD2qr5 -kQat2lS6qVLHTXTJhGaAddzc+ISv+tMskreLluIJo2Y8GKgpmYapnTU00Jeh846R -AUmHBayHdwjWBRHJgdxSuy3EkLuEbskzKeKOKt/2NsoCwgEpt77v87/yYZvqIzFm -wS48oQA/bVTEbRPPfjUfPbqkqg6Lsit1bBLuCSJZ5gSnS6a/q3/ArbZX12Uoyg21 -j4OXCILoqAs69rTZl0aDEWfOkCyAYxlDNcbE4x6JxTjfWuTvSfOGI87ktMuErvZV -IprOVhYF08xk1oGLPMjjqtCU05vrOf2d55vlx6WinZ4+5IMrFnixCYPtlb1V5HGL -w6ZLP5pP4cM0buFwrGaVOzy6dtP3ZX5JAXbV3lnV9SfzsN3t5hnMUsg9GkVW7FDQ -H6G8v2rIVP5VirQiNc2tJUk/46ybvsnrOvlrvTcXGMpWK3iCn27qi2swmwE0CSjW -hXydeKFi/tyxBDwOl/V13dYzpdU1sCVE7NZfVL0LA62jPZdRBAau0s3FMictyha3 -5BGr6mo41XTm2faOwnLoJTjlzGG01Bh8Di/B00+2Y1caDZAaHgpYO4Rs0c5W7NiG -zH0HrFJ4M+5Jw12n4LMYMZYvr+EmsLGlTkLqf26u2D98qH0vG7Hjht3/N66Eu5ct -hwRQaRuiFKx7tnte4K/iI3GjCqaGOACHSF3cQBjOe1jlEgMBXrb3C1SKaw8hnIgX -5T/wgCeVXHSQNlp3udTd9qIYYMi93Jb3ajeZva3bgz2KNbdnwVuk3cUi2vWHShzi -7sY= ------END ENCRYPTED PRIVATE KEY----- diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_server.crt b/examples/wifi/wpa2_enterprise/main/wpa2_server.crt index 0af6f1741fa1..d2e21e6d2d27 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_server.crt +++ b/examples/wifi/wpa2_enterprise/main/wpa2_server.crt @@ -1,70 +1,83 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 47 (0x2f) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=FR, ST=Radius, L=Somewhere, O=Example Inc./emailAddress=admin@example.com, CN=Example Certificate Authority + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IN, ST=STATE, L=CITY, O=EXAMPEL CA ORG, OU=unit CA, CN=Cert Auth/emailAddress=admin@example.com Validity - Not Before: Jun 7 08:06:49 2017 GMT - Not After : Jun 5 08:06:49 2027 GMT - Subject: C=FR, ST=Radius, O=Example Inc., CN=Example Server Certificate/emailAddress=admin@example.com + Not Before: Jan 27 11:25:19 2022 GMT + Not After : Jan 27 11:25:19 2023 GMT + Subject: C=IN, ST=STATE, L=CITY, O=EXAMPEL CA ORG, OU=unit Server, CN=Example Server/emailAddress=admin@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) + RSA Public-Key: (2048 bit) Modulus: - 00:c9:d8:e2:e0:75:91:83:87:d8:c8:80:c6:20:4d: - e9:14:24:30:98:33:53:fa:56:0e:ec:9a:43:7f:87: - a9:22:94:26:06:c7:ac:b5:d9:ec:55:06:81:b7:0d: - c9:24:51:49:fa:47:fb:4b:4e:fc:ed:75:8a:e1:28: - 32:bc:c5:e0:4c:45:c4:58:60:15:67:1e:6b:40:19: - 3f:f0:ab:92:61:92:2d:71:10:2e:f2:eb:bc:81:2f: - 5a:3b:74:ca:5f:fd:e0:ee:d1:d9:07:6a:6c:20:c0: - 07:88:b4:8b:0f:ad:1e:c9:4f:7c:11:98:37:89:15: - de:24:b1:11:1a:7c:97:4a:cf:f3:c8:cb:79:9e:9c: - c3:71:da:a6:94:97:f5:95:fd:61:06:44:e2:3f:12: - 43:0b:1d:33:48:91:d2:ce:4f:97:a1:ed:6a:30:c7: - 5d:98:b5:6e:0a:b7:4f:d9:03:ec:80:76:09:b0:40: - a1:a1:af:ab:2a:59:c4:0f:56:22:bc:be:14:be:18: - df:10:7d:5d:22:bf:e5:04:77:7a:75:6b:3e:eb:6d: - 20:a1:a7:60:d4:f1:87:9d:9f:60:b9:d3:db:2c:25: - f4:91:4a:f1:d2:40:e5:a1:10:88:a0:41:5a:98:40: - ca:15:d7:e3:e6:3e:c0:6a:d5:46:b2:b4:90:b4:ae: - 3b:e3 + 00:b4:cb:f6:1d:10:2f:4a:c3:1e:a7:38:6d:79:02: + f2:af:0a:da:cd:34:cf:5c:3a:8d:d6:1b:9f:f1:17: + ed:9e:5d:7c:db:b5:a3:d1:7d:79:97:1e:f6:09:22: + c4:f4:c7:67:76:94:79:e6:d7:3a:3e:16:40:ef:60: + 01:4f:41:93:1b:3e:d1:cf:7a:62:51:da:d5:f0:ee: + f1:92:88:7d:ec:4f:c8:db:60:7d:4c:07:c9:9f:35: + 85:b8:97:54:f2:78:78:9f:a1:c1:1f:4f:a2:ea:06: + 7c:59:d9:be:51:cb:13:0c:ed:32:82:f0:a1:9f:bd: + 86:03:c4:9d:4a:dd:b8:48:07:0b:ce:84:94:92:8c: + d1:cd:7d:b2:b5:d7:fd:81:4c:68:1f:bf:92:1b:ee: + 22:b4:0d:4a:ac:b0:fc:b1:83:ae:25:2b:55:5a:c0: + 36:76:46:1c:74:0f:2e:55:93:4e:53:6a:d9:ff:f2: + f9:3d:92:f7:19:cd:4e:a7:8d:28:be:f3:b5:b7:20: + 19:74:38:4d:e1:96:26:f7:7f:69:10:a3:50:ab:86: + be:7d:76:d8:46:0f:25:e8:6b:16:65:e0:c8:cb:9c: + b8:4d:21:6d:5b:76:d0:75:0d:82:df:42:33:0b:05: + 69:0a:c1:70:98:27:7b:fb:05:eb:41:13:c4:dc:a8: + f1:05 Exponent: 65537 (0x10001) X509v3 extensions: - X509v3 Extended Key Usage: - TLS Web Server Authentication - X509v3 CRL Distribution Points: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + E8:B5:B7:60:BA:CD:9C:F2:7A:7D:20:01:48:DC:03:C5:F2:F7:1E:80 + X509v3 Authority Key Identifier: + keyid:76:B2:FB:9A:70:28:B6:2C:92:26:99:2F:D3:BE:95:F4:52:3C:DE:76 - Full Name: - URI:http://www.example.com/example_ca.crl - - Signature Algorithm: sha1WithRSAEncryption - a4:25:21:51:0b:22:6c:63:8d:a9:c1:4f:04:33:69:79:34:f0: - 36:dd:8f:6a:27:5f:07:a2:1d:ef:8b:f0:96:e6:e7:a3:b8:3b: - 85:5e:3f:26:43:8a:8e:95:58:9c:a6:db:9c:51:bf:ea:53:16: - 3e:c1:a8:11:1a:c6:cf:0e:a1:17:18:64:d2:05:f1:c0:9c:a6: - 2b:16:c4:29:54:03:d2:17:bd:15:74:d6:ad:8a:8f:2d:cc:27: - 3b:88:88:f2:ea:d0:a2:cb:e9:42:57:df:26:9f:8a:a2:02:2f: - 35:b6:19:1d:26:43:44:af:12:4b:bc:b9:84:50:02:fd:1d:fa: - 50:e8 + Signature Algorithm: sha256WithRSAEncryption + c2:59:a0:58:92:87:7a:56:85:9e:1f:93:26:44:5a:ca:47:0f: + e6:b6:a2:40:37:03:46:8e:e3:dc:48:e6:51:21:38:f4:45:db: + 00:17:de:0d:9f:cc:1c:cd:42:c0:41:fe:fb:e9:bb:65:75:23: + f4:95:0a:dd:13:8e:90:85:e4:09:36:7b:0f:d5:62:f5:62:67: + ff:0e:2f:43:cf:4f:0c:c1:61:85:84:02:6e:41:d6:d8:3f:ce: + 33:b0:fc:b8:d7:ab:27:f2:cb:b9:ab:23:7a:62:d1:1b:41:25: + 51:7a:d6:52:43:67:7f:64:89:56:fa:5c:10:94:29:f0:5d:58: + 28:89:41:0d:10:13:2a:c2:3b:84:b5:43:aa:b5:f4:bc:17:0b: + 4e:25:77:fb:0c:97:f0:ec:a0:52:31:26:96:61:e8:a5:46:99: + 75:4f:eb:ab:f9:93:12:87:0b:44:8e:6f:c7:2b:0b:51:4e:b3: + ba:9f:5d:9e:40:4f:81:3a:e3:b3:d4:12:63:60:62:90:42:76: + 7e:27:d6:da:b3:ae:7b:bc:85:a2:bf:6c:d5:04:46:a1:05:2b: + a4:78:58:29:44:44:08:7b:7b:62:7b:8c:8c:58:8d:2e:80:ae: + f5:6c:5b:41:af:58:b9:52:f6:d2:2d:89:a6:64:6c:38:57:eb: + b1:e2:da:f9 -----BEGIN CERTIFICATE----- -MIIDWTCCAsKgAwIBAgIBLzANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx -DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF -eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw -JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw -ODA2NDlaFw0yNzA2MDUwODA2NDlaMHwxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS -YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEjMCEGA1UEAwwaRXhhbXBsZSBT -ZXJ2ZXIgQ2VydGlmaWNhdGUxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu -Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydji4HWRg4fYyIDG -IE3pFCQwmDNT+lYO7JpDf4epIpQmBsestdnsVQaBtw3JJFFJ+kf7S0787XWK4Sgy -vMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSL -D60eyU98EZg3iRXeJLERGnyXSs/zyMt5npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHS -zk+Xoe1qMMddmLVuCrdP2QPsgHYJsEChoa+rKlnED1YivL4UvhjfEH1dIr/lBHd6 -dWs+620goadg1PGHnZ9gudPbLCX0kUrx0kDloRCIoEFamEDKFdfj5j7AatVGsrSQ -tK474wIDAQABo08wTTATBgNVHSUEDDAKBggrBgEFBQcDATA2BgNVHR8ELzAtMCug -KaAnhiVodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGVfY2EuY3JsMA0GCSqG -SIb3DQEBBQUAA4GBAKQlIVELImxjjanBTwQzaXk08Dbdj2onXweiHe+L8Jbm56O4 -O4VePyZDio6VWJym25xRv+pTFj7BqBEaxs8OoRcYZNIF8cCcpisWxClUA9IXvRV0 -1q2Kjy3MJzuIiPLq0KLL6UJX3yafiqICLzW2GR0mQ0SvEku8uYRQAv0d+lDo +MIIEGzCCAwOgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjTELMAkGA1UEBhMCSU4x +DjAMBgNVBAgMBVNUQVRFMQ0wCwYDVQQHDARDSVRZMRcwFQYDVQQKDA5FWEFNUEVM +IENBIE9SRzEQMA4GA1UECwwHdW5pdCBDQTESMBAGA1UEAwwJQ2VydCBBdXRoMSAw +HgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yMjAxMjcxMTI1MTla +Fw0yMzAxMjcxMTI1MTlaMIGWMQswCQYDVQQGEwJJTjEOMAwGA1UECAwFU1RBVEUx +DTALBgNVBAcMBENJVFkxFzAVBgNVBAoMDkVYQU1QRUwgQ0EgT1JHMRQwEgYDVQQL +DAt1bml0IFNlcnZlcjEXMBUGA1UEAwwORXhhbXBsZSBTZXJ2ZXIxIDAeBgkqhkiG +9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAtMv2HRAvSsMepzhteQLyrwrazTTPXDqN1huf8Rftnl1827Wj0X15 +lx72CSLE9MdndpR55tc6PhZA72ABT0GTGz7Rz3piUdrV8O7xkoh97E/I22B9TAfJ +nzWFuJdU8nh4n6HBH0+i6gZ8Wdm+UcsTDO0ygvChn72GA8SdSt24SAcLzoSUkozR +zX2ytdf9gUxoH7+SG+4itA1KrLD8sYOuJStVWsA2dkYcdA8uVZNOU2rZ//L5PZL3 +Gc1Op40ovvO1tyAZdDhN4ZYm939pEKNQq4a+fXbYRg8l6GsWZeDIy5y4TSFtW3bQ +dQ2C30IzCwVpCsFwmCd7+wXrQRPE3KjxBQIDAQABo3sweTAJBgNVHRMEAjAAMCwG +CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV +HQ4EFgQU6LW3YLrNnPJ6fSABSNwDxfL3HoAwHwYDVR0jBBgwFoAUdrL7mnAotiyS +Jpkv076V9FI83nYwDQYJKoZIhvcNAQELBQADggEBAMJZoFiSh3pWhZ4fkyZEWspH +D+a2okA3A0aO49xI5lEhOPRF2wAX3g2fzBzNQsBB/vvpu2V1I/SVCt0TjpCF5Ak2 +ew/VYvViZ/8OL0PPTwzBYYWEAm5B1tg/zjOw/LjXqyfyy7mrI3pi0RtBJVF61lJD +Z39kiVb6XBCUKfBdWCiJQQ0QEyrCO4S1Q6q19LwXC04ld/sMl/DsoFIxJpZh6KVG +mXVP66v5kxKHC0SOb8crC1FOs7qfXZ5AT4E647PUEmNgYpBCdn4n1tqzrnu8haK/ +bNUERqEFK6R4WClERAh7e2J7jIxYjS6ArvVsW0GvWLlS9tItiaZkbDhX67Hi2vk= -----END CERTIFICATE----- diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_server.key b/examples/wifi/wpa2_enterprise/main/wpa2_server.key index 9b3433273eae..9941947570f2 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_server.key +++ b/examples/wifi/wpa2_enterprise/main/wpa2_server.key @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAydji4HWRg4fYyIDGIE3pFCQwmDNT+lYO7JpDf4epIpQmBses -tdnsVQaBtw3JJFFJ+kf7S0787XWK4SgyvMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu -8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSLD60eyU98EZg3iRXeJLERGnyXSs/zyMt5 -npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHSzk+Xoe1qMMddmLVuCrdP2QPsgHYJsECh -oa+rKlnED1YivL4UvhjfEH1dIr/lBHd6dWs+620goadg1PGHnZ9gudPbLCX0kUrx -0kDloRCIoEFamEDKFdfj5j7AatVGsrSQtK474wIDAQABAoIBAQC2kGDEPBJdMSW2 -VCLfXRiPixwYzXQLXIMrJWwfkQg9qlmqkDd6U50aWkRA2UswegW7RhfYSZ0i+cmf -VMhvTVpOIlwwwtcY6b5/v1bBy60eaySGuuh79xQMlFO8qynQIMStvUfbGTqrdIRb -9VBB4YeS9T12fILejtTZwv2BQ2dj1Y1SCay6Ri85UzJqSClRKgHISybvVdLNjPvP -0TRFBr57zyjL6WE8teKiKchzQko2u86No5uBCdKGsrAkrsdcR0YqlM/pZxd3VKNm -+eny0k+dZZlvcPxzkzP4hEp9+Rw5rP9/s3s/cCwvuuC5JO32ATBWKCbTvPv/XPDb -MdSJtOshAoGBAPzk0eswkcbFYtpnpBNmBAr1dtAdW1lfjUI2ucMMwt7Wns0P/tt+ -gq6Hi1wTaGP0l/dIECgeHwjtWj31ZJjQtFJ1y/kafxo4o9cA8vCydpdvSZaldAfg -sbLlDTDYzEpelaDIbNQBBXFoC5U9JlBhBsIFCL5Z8ZuIeFPsb7t5wwuHAoGBAMxT -jyWfNm1uNxp1xgCnrRsLPQPVnURrSFAqcHrECqRu3F7sozTN7q/cZViemxPvVDGQ -p9c+9bHwaYvW4trO5qDHJ++gGwm5L52bMAY1VUfeTt67fqrey43XpdmzcTX1V9Uj -QWawPUCSDzFjL1MjfCIejtyYf5ash53vj+T8r/vFAoGAA/OPVB1uKazr3n3AEo2F -gqZTNO1AgCT+EArK3EFWyiSQVqPpV4SihheYFdg3yVgJB9QYbIgL9BfBUTaEW97m -8mLkzP+c/Mvlw3ZAVYJ0V+llPPVY2saoACOUES9SAdd4fwqiqK1baGo3xB0wfBEI -CgAKIu9E1ylKuAT5ufQtGAECgYEAtP/kU5h5N3El4QupTdU7VDSdZTMqsHw0v8cI -gsf9AXKvRmtrnBA8u46KPHmruHoO5CVXeSZtsaXdaaH+rYQQ6yXg67WxnehtFLlv -TmCaXiLBTS9cYvMf8FOyuGnsBLeEietEOTov2G5KhR5uwsAxa2wUc7endor5S9/2 -YQuyvV0CgYALbiFpILd5l1ip65eE6JdA3hfttUbV2j2NSW12ej69vqbeOfaSgNse -uYCcXFsBbQPhNPwA+4d1oCe8SyXZg1f7gE812z2Tyr/3vdVnNZlitoxhsHmGiyS7 -gZdaTYCb78l9z0EBdaCVvA16owEle4SR6f9eCwzSI0WPOUra+x/hrA== +MIIEpAIBAAKCAQEAtMv2HRAvSsMepzhteQLyrwrazTTPXDqN1huf8Rftnl1827Wj +0X15lx72CSLE9MdndpR55tc6PhZA72ABT0GTGz7Rz3piUdrV8O7xkoh97E/I22B9 +TAfJnzWFuJdU8nh4n6HBH0+i6gZ8Wdm+UcsTDO0ygvChn72GA8SdSt24SAcLzoSU +kozRzX2ytdf9gUxoH7+SG+4itA1KrLD8sYOuJStVWsA2dkYcdA8uVZNOU2rZ//L5 +PZL3Gc1Op40ovvO1tyAZdDhN4ZYm939pEKNQq4a+fXbYRg8l6GsWZeDIy5y4TSFt +W3bQdQ2C30IzCwVpCsFwmCd7+wXrQRPE3KjxBQIDAQABAoIBAQCn1hwQWOD+L2p6 +Y9jEmOb/dj0ueJLzFGxtUdHFt6ff9vuc3t9H74p7rsNKMdvTPHWg0C7mC/FGh9Qa +I+6zS7WrekK9r+gsAtHOy5K4rDrxsBNPDCDk/um+Aaq0dM/oE8wurLOiRISBainw +I0IZnkJ+Iohco9P2fbM2NkSqpm+XdFuJsbsqYkry7Oj2XmT+08nMHbFTqyB9CsuM +zHrrBlyo9YAF3Im4cLmvHUGuGC6Ovz9abKVEX0BoOAkdPkIR1J7QXsqv+RtYzYE6 +vYndw+3b1kMyAy2NKBPLfUyIf8MF5E/MSEnRlfhDkzBd4pngx746j9RegQt5GznT +jEDrrQVBAoGBANv29o+eNoaEdoZSzBLv++8K5arF4MRCmiBCu4CqIPYEg4JZ3pC0 +sx0ZbxBDxyWnhpU3XhjcgFRAjVFB18jXOvBdqbY9nnUgpnmpjUDG1Xv5+p4igC8t +oQpOqWDgf5cBBPsIsllyh2ZxllHrmIW98NXqPM2VzXpcQKtTSsGrLRtxAoGBANJq +V/unl8IQGdXoDfFjOQQTJi98eeerCXiSYRJHoj3vY8AFOct4ky+xtxFcQ5UqlxWG +3Ag6LGfh4wMk3lc5WtufHLBmAMTQKjy28Muyr1rpXi5VI2iM11mYqpy5oquYyISM +KhPQS4llvd/iLNpOcOtuY06Nb3QnBFrTg/F3TNzVAoGBANCtZJAvio7nUAJyvkQh +BCNtdSEkBO5sOQfuBzAzNn3vHkwlsi4aH+q1XFZT1rR0UAtzsYNofR5w9yBllK9m +8PVkBkNsBc4coZK+NdGEULgDGa24EV+wrBy5L5tGoATD5NO7FmghbS7VB8TD+7i1 +z6tBQ1nOildQ+dEPfdZp7KshAoGAW8hNZpVdKiZxzo+xfUjFtxRPRMlsN3Sw5eob +86hRieihP0JISovm0BgZ/bWcOTXhv18bHW+arRmoN1fesHdxPXlzPzLPRQp0UhWO +hZwEx4giL92tW06MJSXlzgVfgrBbTw4A0LG8MUuy/jSfUf6DXP7CzKH/KtBWIvQ+ +ipZ6bZ0CgYAw3yomPFsGsOKMwIDhuVNn/1pUmIVBq4IGXUbz2y4hTxKXbyDXo5zN +/DPLOhiE3MUopu7o3XA+3Y90fGn0vnnXW7U/pygjGOrHho1jVc5knUieVHQKiMgI +g0FWnOpmytheSnU/EZDsEde5ka6JMdIRH4urjO/rhhm0oBGN9kkrCg== -----END RSA PRIVATE KEY----- diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_server.pem b/examples/wifi/wpa2_enterprise/main/wpa2_server.pem index b6e3c0d16dbb..d2e21e6d2d27 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_server.pem +++ b/examples/wifi/wpa2_enterprise/main/wpa2_server.pem @@ -1,57 +1,83 @@ -Bag Attributes - localKeyID: 63 3B C1 EE 3A 4A 9B 3E FF 9E E7 BC 17 50 D7 F7 B7 7E 3B C0 -subject=/C=FR/ST=Radius/O=Example Inc./CN=Example Server Certificate/emailAddress=admin@example.com -issuer=/C=FR/ST=Radius/L=Somewhere/O=Example Inc./emailAddress=admin@example.com/CN=Example Certificate Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IN, ST=STATE, L=CITY, O=EXAMPEL CA ORG, OU=unit CA, CN=Cert Auth/emailAddress=admin@example.com + Validity + Not Before: Jan 27 11:25:19 2022 GMT + Not After : Jan 27 11:25:19 2023 GMT + Subject: C=IN, ST=STATE, L=CITY, O=EXAMPEL CA ORG, OU=unit Server, CN=Example Server/emailAddress=admin@example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b4:cb:f6:1d:10:2f:4a:c3:1e:a7:38:6d:79:02: + f2:af:0a:da:cd:34:cf:5c:3a:8d:d6:1b:9f:f1:17: + ed:9e:5d:7c:db:b5:a3:d1:7d:79:97:1e:f6:09:22: + c4:f4:c7:67:76:94:79:e6:d7:3a:3e:16:40:ef:60: + 01:4f:41:93:1b:3e:d1:cf:7a:62:51:da:d5:f0:ee: + f1:92:88:7d:ec:4f:c8:db:60:7d:4c:07:c9:9f:35: + 85:b8:97:54:f2:78:78:9f:a1:c1:1f:4f:a2:ea:06: + 7c:59:d9:be:51:cb:13:0c:ed:32:82:f0:a1:9f:bd: + 86:03:c4:9d:4a:dd:b8:48:07:0b:ce:84:94:92:8c: + d1:cd:7d:b2:b5:d7:fd:81:4c:68:1f:bf:92:1b:ee: + 22:b4:0d:4a:ac:b0:fc:b1:83:ae:25:2b:55:5a:c0: + 36:76:46:1c:74:0f:2e:55:93:4e:53:6a:d9:ff:f2: + f9:3d:92:f7:19:cd:4e:a7:8d:28:be:f3:b5:b7:20: + 19:74:38:4d:e1:96:26:f7:7f:69:10:a3:50:ab:86: + be:7d:76:d8:46:0f:25:e8:6b:16:65:e0:c8:cb:9c: + b8:4d:21:6d:5b:76:d0:75:0d:82:df:42:33:0b:05: + 69:0a:c1:70:98:27:7b:fb:05:eb:41:13:c4:dc:a8: + f1:05 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + E8:B5:B7:60:BA:CD:9C:F2:7A:7D:20:01:48:DC:03:C5:F2:F7:1E:80 + X509v3 Authority Key Identifier: + keyid:76:B2:FB:9A:70:28:B6:2C:92:26:99:2F:D3:BE:95:F4:52:3C:DE:76 + + Signature Algorithm: sha256WithRSAEncryption + c2:59:a0:58:92:87:7a:56:85:9e:1f:93:26:44:5a:ca:47:0f: + e6:b6:a2:40:37:03:46:8e:e3:dc:48:e6:51:21:38:f4:45:db: + 00:17:de:0d:9f:cc:1c:cd:42:c0:41:fe:fb:e9:bb:65:75:23: + f4:95:0a:dd:13:8e:90:85:e4:09:36:7b:0f:d5:62:f5:62:67: + ff:0e:2f:43:cf:4f:0c:c1:61:85:84:02:6e:41:d6:d8:3f:ce: + 33:b0:fc:b8:d7:ab:27:f2:cb:b9:ab:23:7a:62:d1:1b:41:25: + 51:7a:d6:52:43:67:7f:64:89:56:fa:5c:10:94:29:f0:5d:58: + 28:89:41:0d:10:13:2a:c2:3b:84:b5:43:aa:b5:f4:bc:17:0b: + 4e:25:77:fb:0c:97:f0:ec:a0:52:31:26:96:61:e8:a5:46:99: + 75:4f:eb:ab:f9:93:12:87:0b:44:8e:6f:c7:2b:0b:51:4e:b3: + ba:9f:5d:9e:40:4f:81:3a:e3:b3:d4:12:63:60:62:90:42:76: + 7e:27:d6:da:b3:ae:7b:bc:85:a2:bf:6c:d5:04:46:a1:05:2b: + a4:78:58:29:44:44:08:7b:7b:62:7b:8c:8c:58:8d:2e:80:ae: + f5:6c:5b:41:af:58:b9:52:f6:d2:2d:89:a6:64:6c:38:57:eb: + b1:e2:da:f9 -----BEGIN CERTIFICATE----- -MIIDWTCCAsKgAwIBAgIBLzANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx -DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF -eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw -JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw -ODA2NDlaFw0yNzA2MDUwODA2NDlaMHwxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS -YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEjMCEGA1UEAwwaRXhhbXBsZSBT -ZXJ2ZXIgQ2VydGlmaWNhdGUxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu -Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydji4HWRg4fYyIDG -IE3pFCQwmDNT+lYO7JpDf4epIpQmBsestdnsVQaBtw3JJFFJ+kf7S0787XWK4Sgy -vMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSL -D60eyU98EZg3iRXeJLERGnyXSs/zyMt5npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHS -zk+Xoe1qMMddmLVuCrdP2QPsgHYJsEChoa+rKlnED1YivL4UvhjfEH1dIr/lBHd6 -dWs+620goadg1PGHnZ9gudPbLCX0kUrx0kDloRCIoEFamEDKFdfj5j7AatVGsrSQ -tK474wIDAQABo08wTTATBgNVHSUEDDAKBggrBgEFBQcDATA2BgNVHR8ELzAtMCug -KaAnhiVodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGVfY2EuY3JsMA0GCSqG -SIb3DQEBBQUAA4GBAKQlIVELImxjjanBTwQzaXk08Dbdj2onXweiHe+L8Jbm56O4 -O4VePyZDio6VWJym25xRv+pTFj7BqBEaxs8OoRcYZNIF8cCcpisWxClUA9IXvRV0 -1q2Kjy3MJzuIiPLq0KLL6UJX3yafiqICLzW2GR0mQ0SvEku8uYRQAv0d+lDo +MIIEGzCCAwOgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjTELMAkGA1UEBhMCSU4x +DjAMBgNVBAgMBVNUQVRFMQ0wCwYDVQQHDARDSVRZMRcwFQYDVQQKDA5FWEFNUEVM +IENBIE9SRzEQMA4GA1UECwwHdW5pdCBDQTESMBAGA1UEAwwJQ2VydCBBdXRoMSAw +HgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yMjAxMjcxMTI1MTla +Fw0yMzAxMjcxMTI1MTlaMIGWMQswCQYDVQQGEwJJTjEOMAwGA1UECAwFU1RBVEUx +DTALBgNVBAcMBENJVFkxFzAVBgNVBAoMDkVYQU1QRUwgQ0EgT1JHMRQwEgYDVQQL +DAt1bml0IFNlcnZlcjEXMBUGA1UEAwwORXhhbXBsZSBTZXJ2ZXIxIDAeBgkqhkiG +9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAtMv2HRAvSsMepzhteQLyrwrazTTPXDqN1huf8Rftnl1827Wj0X15 +lx72CSLE9MdndpR55tc6PhZA72ABT0GTGz7Rz3piUdrV8O7xkoh97E/I22B9TAfJ +nzWFuJdU8nh4n6HBH0+i6gZ8Wdm+UcsTDO0ygvChn72GA8SdSt24SAcLzoSUkozR +zX2ytdf9gUxoH7+SG+4itA1KrLD8sYOuJStVWsA2dkYcdA8uVZNOU2rZ//L5PZL3 +Gc1Op40ovvO1tyAZdDhN4ZYm939pEKNQq4a+fXbYRg8l6GsWZeDIy5y4TSFtW3bQ +dQ2C30IzCwVpCsFwmCd7+wXrQRPE3KjxBQIDAQABo3sweTAJBgNVHRMEAjAAMCwG +CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV +HQ4EFgQU6LW3YLrNnPJ6fSABSNwDxfL3HoAwHwYDVR0jBBgwFoAUdrL7mnAotiyS +Jpkv076V9FI83nYwDQYJKoZIhvcNAQELBQADggEBAMJZoFiSh3pWhZ4fkyZEWspH +D+a2okA3A0aO49xI5lEhOPRF2wAX3g2fzBzNQsBB/vvpu2V1I/SVCt0TjpCF5Ak2 +ew/VYvViZ/8OL0PPTwzBYYWEAm5B1tg/zjOw/LjXqyfyy7mrI3pi0RtBJVF61lJD +Z39kiVb6XBCUKfBdWCiJQQ0QEyrCO4S1Q6q19LwXC04ld/sMl/DsoFIxJpZh6KVG +mXVP66v5kxKHC0SOb8crC1FOs7qfXZ5AT4E647PUEmNgYpBCdn4n1tqzrnu8haK/ +bNUERqEFK6R4WClERAh7e2J7jIxYjS6ArvVsW0GvWLlS9tItiaZkbDhX67Hi2vk= -----END CERTIFICATE----- -Bag Attributes - localKeyID: 63 3B C1 EE 3A 4A 9B 3E FF 9E E7 BC 17 50 D7 F7 B7 7E 3B C0 -Key Attributes: ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIzOJcU8NzjKACAggA -MBQGCCqGSIb3DQMHBAjdK4dY0QgcrgSCBMgCv4euS7bxaRTMSXYliVA+UrAI0iJL -oQgZ6cGFqXqasKu7K6BltLXaKJLX321gV2ofHHAxa1CWFwIgrv/bhci10cJr6BaL -a3+5L5e/EO0eRKVzoplput9mTP27pcJSu8jN5jOu054oamzFKtgGcBuL9mRCAfVq -JSCwbSUHPrwZX6jVDsLggrvE78SIXEYAQDfUrbvBY1kGNNV+U9v410SREYXI3q+8 -a4Paotf2HN5G0nvr0BSJUbY0NUe4AP1NfOM1VE8UiLL3LfZE3ZbOm6XsM8Mxf8rV -BkDOzhErF/dXOE65b5xG4KfoXy78WN7OeJpjNgNUDUl1/3+bc++8f7ZBzOtVAjP7 -diDYU/UrQeLUrLVxTLD6C9J9HvbW5JCEa1FN+pKQKxeaQ9j/dDhJ7XI4ctaIIQui -zrOTLEhBqC10TaNabLNVsLFCgFQMREBVYZoBYbFIZLT4FuRk5yaAYRDCrRKgqlu6 -61E0jOD/hDZIbBO/Vf94d+VaypeFonoz6SdrWgf4heN530d5fd5nOxElRl8LmUcH -LriwJIXB7XCfwgjREceRQpjiqmWPl8hcfe9E2NzwldbE+eLN0mlXgRyLlU+eXova -3r1u60Hb9ocLux3kHUXpZ+MomwkwqIn9qFC0U3KBGt7SmhUWypmoNUPiXP0U4Lno -tynPBODzhDeRv2T0qxULc6OznDE3WOuy88B94/JXhB5D56bRb9FkkpHpmn8MP8SW -fIV3cK/cBoGxgyk+IaL0aQbojFtyeyKbkrz1W3WnPtB3/kqd8USzpCvUBMBVG83D -XzHcU/mRYO61BgyGv0VBXdBtPbmW1CK73eX7gc/uOtqhxUQc3g5hNZDL2rxPCpID -alyGlSQxY8cPWJbYMPq2RHoJNDxnTbFhDm3mdOoTg5qK4+cUZMBqfq1kswXM9Z4p -LSnIviRjpL4a7hhDVAJYOo29rBP+QNdt5CkyLNwjnDv+l8jHOMTP4t1RPvoQx6hc -aOQOcSQnIqDgzot3//dnC2mBTQ66jsOnRPMMs9MQ4up6Wrc5PEt5avBi3B4AQC2Q -TUjL6QAcMR5cJbkecp+5h7W5pUw3OYcYpg6G+unJVGSgZkye2lySGgNuRLmcYjVA -gXfA9a8+HN/TFGHP668pZvHQrfV470ETnHhrh+NLN5AIDR+UFG8is7Xj7Ly2/5bN -M3Q3AYSCb8P8/ZrV3Dfm3qoCoxuNYax0PYt/JBWXTtPG1SClUQg+yo8VMiNw877h -IEdkg1QBxKWY5x+ThK79y+Cwub795ym9bYTwAtH8kpLmamoBT8UvgJumh0i8NGg3 -04B/oyg1P8/TxfbD0uaTPC+tmbIKVyHybTQL6/E0bs2knPp2Zyxno3yE3AI70msZ -mGNuK9mkxITIUbijiRZyeQvZz/x/daYwQ0WuaXXpPQvKcFu7LyIEad8QpIqtSCax -VS9Mtwe7zTCp0jmQDBGltlk1B2rUlQ5rxsFN6kJtBULdQc1TTj0NUp3ESeAE3A/l -wE8fPzBht1OKghJqVndGoh01XhKJfpfaQ85CES0HzA6Nll8SQO0bn6u4SBZGEvBT -pFarRrtS6KbulTDB3yBPrKgd1ZoBQv5/ScW8fPcLi55U6nhR28uu+zKy4yZFgOFR -2KU= ------END ENCRYPTED PRIVATE KEY----- diff --git a/export.sh b/export.sh index c3d4617ba03e..5e9a65ba0233 100644 --- a/export.sh +++ b/export.sh @@ -156,9 +156,12 @@ enable_autocomplete() { eval "$(env _IDF.PY_COMPLETE=$SOURCE_ZSH idf.py)" || echo "WARNING: Failed to load shell autocompletion for zsh version: $ZSH_VERSION!" elif [ -n "${BASH_SOURCE-}" ] then - eval "$(env LANG=en _IDF.PY_COMPLETE=$SOURCE_BASH idf.py)" || echo "WARNING: Failed to load shell autocompletion for bash version: $BASH_VERSION!" + WARNING_MSG="WARNING: Failed to load shell autocompletion for bash version: $BASH_VERSION!" + [[ ${BASH_VERSINFO[0]} -lt 4 ]] && { echo "$WARNING_MSG"; return; } + eval "$(env LANG=en _IDF.PY_COMPLETE=$SOURCE_BASH idf.py)" || echo "$WARNING_MSG" fi + unset WARNING_MSG unset SOURCE_ZSH unset SOURCE_BASH diff --git a/install.ps1 b/install.ps1 index bcd020b95cbc..d06dc0f831c5 100644 --- a/install.ps1 +++ b/install.ps1 @@ -8,12 +8,14 @@ if($args.count -eq 0){ $TARGETS = $args[0] -join ',' } Write-Output "Installing ESP-IDF tools" -Start-Process -Wait -NoNewWindow -FilePath "python" -Args "$IDF_PATH/tools/idf_tools.py install --targets=${TARGETS}" -if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # if error +$proces_tools = Start-Process -Wait -PassThru -NoNewWindow -FilePath "python" -Args "$IDF_PATH/tools/idf_tools.py install --targets=${TARGETS}" +$exit_code_tools = $proces_tools.ExitCode +if ($exit_code_tools -ne 0) { exit $exit_code_tools } # if error Write-Output "Setting up Python environment" -Start-Process -Wait -NoNewWindow -FilePath "python" -Args "$IDF_PATH/tools/idf_tools.py install-python-env" -if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE} # if error +$proces_py_env = Start-Process -Wait -PassThru -NoNewWindow -FilePath "python" -Args "$IDF_PATH/tools/idf_tools.py install-python-env --features=${FEATURES}" +$exit_code_py_env = $proces_py_env.ExitCode +if ($exit_code_py_env -ne 0) { exit $exit_code_py_env } # if error Write-Output " diff --git a/make/version.mk b/make/version.mk index 1a1c24457be6..32cf09cd936b 100644 --- a/make/version.mk +++ b/make/version.mk @@ -1,3 +1,3 @@ IDF_VERSION_MAJOR := 4 IDF_VERSION_MINOR := 3 -IDF_VERSION_PATCH := 2 +IDF_VERSION_PATCH := 3 diff --git a/requirements.txt b/requirements.txt index 7340d07e8fd8..dad5ce413b74 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,7 @@ cryptography>=2.1.4,<35 cffi<1.15;python_version<'3.6' pyparsing>=2.0.3,<2.4.0 pyelftools>=0.22 +idf-component-manager~=1.0 gdbgui==0.13.2.0 # 0.13.2.1 supports Python 3.6+ only @@ -21,6 +22,8 @@ pygdbmi<=0.9.0.2 # The pygdbmi required max version 0.9.0.2 since 0.9.0.3 is not compatible with latest gdbgui (>=0.13.2.0) # A compatible Socket.IO should be used. See https://github.com/miguelgrinberg/python-socketio/issues/578 python-socketio<5 +jinja2<3.1 # See https://github.com/espressif/esp-idf/issues/8760 +itsdangerous<2.1 kconfiglib==13.7.1 diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt deleted file mode 100644 index 51d3a993f1e3..000000000000 --- a/tools/ci/check_copyright_ignore.txt +++ /dev/null @@ -1,4265 +0,0 @@ -.gitlab/ci/dependencies/generate_rules.py -components/app_trace/app_trace_membufs_proto.c -components/app_trace/port/include/esp_app_trace_port.h -components/app_trace/port/riscv/port.c -components/app_trace/port/xtensa/port.c -components/app_trace/private_include/esp_app_trace_membufs_proto.h -components/app_trace/sys_view/Config/Global.h -components/app_trace/sys_view/Config/SEGGER_RTT_Conf.h -components/app_trace/sys_view/Config/SEGGER_SYSVIEW_Conf.h -components/app_trace/sys_view/SEGGER/SEGGER.h -components/app_trace/sys_view/SEGGER/SEGGER_RTT.h -components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.c -components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.h -components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h -components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_Int.h -components/app_trace/sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c -components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c -components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.h -components/bootloader/subproject/main/bootloader_hooks.h -components/bootloader/subproject/main/bootloader_start.c -components/bootloader/subproject/main/ld/esp32/bootloader.ld -components/bootloader/subproject/main/ld/esp32/bootloader.rom.ld -components/bootloader/subproject/main/ld/esp32c3/bootloader.ld -components/bootloader/subproject/main/ld/esp32c3/bootloader.rom.ld -components/bootloader/subproject/main/ld/esp32h2/bootloader.ld -components/bootloader/subproject/main/ld/esp32s2/bootloader.ld -components/bootloader/subproject/main/ld/esp32s2/bootloader.rom.ld -components/bootloader/subproject/main/ld/esp32s3/bootloader.ld -components/bootloader/subproject/main/ld/esp32s3/bootloader.rom.ld -components/bt/common/api/esp_blufi_api.c -components/bt/common/api/include/api/esp_blufi_api.h -components/bt/common/btc/core/btc_alarm.c -components/bt/common/btc/core/btc_manage.c -components/bt/common/btc/core/btc_task.c -components/bt/common/btc/include/btc/btc_alarm.h -components/bt/common/btc/include/btc/btc_manage.h -components/bt/common/btc/include/btc/btc_task.h -components/bt/common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c -components/bt/common/btc/profile/esp/blufi/blufi_prf.c -components/bt/common/btc/profile/esp/blufi/blufi_protocol.c -components/bt/common/btc/profile/esp/blufi/include/blufi_int.h -components/bt/common/btc/profile/esp/blufi/include/esp_blufi.h -components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c -components/bt/common/btc/profile/esp/include/btc_blufi_prf.h -components/bt/common/include/bt_common.h -components/bt/common/include/bt_user_config.h -components/bt/common/osi/alarm.c -components/bt/common/osi/allocator.c -components/bt/common/osi/buffer.c -components/bt/common/osi/config.c -components/bt/common/osi/fixed_queue.c -components/bt/common/osi/future.c -components/bt/common/osi/hash_functions.c -components/bt/common/osi/hash_map.c -components/bt/common/osi/include/osi/alarm.h -components/bt/common/osi/include/osi/allocator.h -components/bt/common/osi/include/osi/buffer.h -components/bt/common/osi/include/osi/config.h -components/bt/common/osi/include/osi/fixed_queue.h -components/bt/common/osi/include/osi/future.h -components/bt/common/osi/include/osi/hash_functions.h -components/bt/common/osi/include/osi/hash_map.h -components/bt/common/osi/include/osi/list.h -components/bt/common/osi/include/osi/mutex.h -components/bt/common/osi/include/osi/osi.h -components/bt/common/osi/include/osi/semaphore.h -components/bt/common/osi/include/osi/thread.h -components/bt/common/osi/list.c -components/bt/common/osi/mutex.c -components/bt/common/osi/osi.c -components/bt/common/osi/semaphore.c -components/bt/common/osi/thread.c -components/bt/controller/esp32/bt.c -components/bt/controller/esp32/hli_api.c -components/bt/controller/esp32/hli_api.h -components/bt/controller/esp32c3/bt.c -components/bt/controller/esp32s3/bt.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c -components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_low_power_api.h -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h -components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_proxy_api.h -components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h -components/bt/esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c -components/bt/esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c -components/bt/esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c -components/bt/esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c -components/bt/esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c -components/bt/esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c -components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_config_model_api.h -components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_generic_model_api.h -components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_health_model_api.h -components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_lighting_model_api.h -components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_sensor_model_api.h -components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_time_scene_model_api.h -components/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_generic_model.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_health_model.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c -components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_config_model.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_generic_model.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_health_model.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_lighting_model.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_sensor_model.h -components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_time_scene_model.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_atomic.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_byteorder.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_compiler.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_config.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_dlist.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_ffs.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_mutex.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_slist.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_timer.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_trace.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_types.h -components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h -components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c -components/bt/esp_ble_mesh/mesh_common/mesh_buf.c -components/bt/esp_ble_mesh/mesh_common/mesh_common.c -components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c -components/bt/esp_ble_mesh/mesh_common/mesh_mutex.c -components/bt/esp_ble_mesh/mesh_common/mesh_timer.c -components/bt/esp_ble_mesh/mesh_common/mesh_util.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/aes.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/cbc_mode.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ccm_mode.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/cmac_mode.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/constants.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ctr_mode.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ctr_prng.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ecc.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ecc_dh.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ecc_dsa.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/ecc_platform_specific.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/hmac.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/hmac_prng.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/sha256.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/include/tinycrypt/utils.h -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/aes_decrypt.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/aes_encrypt.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/cbc_mode.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ccm_mode.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/cmac_mode.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ctr_mode.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ctr_prng.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ecc.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ecc_dh.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ecc_dsa.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/ecc_platform_specific.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/hmac.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/hmac_prng.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/sha256.c -components/bt/esp_ble_mesh/mesh_common/tinycrypt/src/utils.c -components/bt/esp_ble_mesh/mesh_core/access.c -components/bt/esp_ble_mesh/mesh_core/access.h -components/bt/esp_ble_mesh/mesh_core/adv.c -components/bt/esp_ble_mesh/mesh_core/adv.h -components/bt/esp_ble_mesh/mesh_core/beacon.c -components/bt/esp_ble_mesh/mesh_core/beacon.h -components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c -components/bt/esp_ble_mesh/mesh_core/cfg_cli.c -components/bt/esp_ble_mesh/mesh_core/cfg_srv.c -components/bt/esp_ble_mesh/mesh_core/crypto.c -components/bt/esp_ble_mesh/mesh_core/crypto.h -components/bt/esp_ble_mesh/mesh_core/fast_prov.c -components/bt/esp_ble_mesh/mesh_core/fast_prov.h -components/bt/esp_ble_mesh/mesh_core/foundation.h -components/bt/esp_ble_mesh/mesh_core/friend.c -components/bt/esp_ble_mesh/mesh_core/friend.h -components/bt/esp_ble_mesh/mesh_core/health_cli.c -components/bt/esp_ble_mesh/mesh_core/health_srv.c -components/bt/esp_ble_mesh/mesh_core/include/cfg_cli.h -components/bt/esp_ble_mesh/mesh_core/include/cfg_srv.h -components/bt/esp_ble_mesh/mesh_core/include/health_cli.h -components/bt/esp_ble_mesh/mesh_core/include/health_srv.h -components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h -components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h -components/bt/esp_ble_mesh/mesh_core/include/mesh_hci.h -components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h -components/bt/esp_ble_mesh/mesh_core/include/mesh_proxy.h -components/bt/esp_ble_mesh/mesh_core/include/mesh_uuid.h -components/bt/esp_ble_mesh/mesh_core/local_operation.c -components/bt/esp_ble_mesh/mesh_core/local_operation.h -components/bt/esp_ble_mesh/mesh_core/lpn.c -components/bt/esp_ble_mesh/mesh_core/lpn.h -components/bt/esp_ble_mesh/mesh_core/main.c -components/bt/esp_ble_mesh/mesh_core/mesh.h -components/bt/esp_ble_mesh/mesh_core/net.c -components/bt/esp_ble_mesh/mesh_core/net.h -components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c -components/bt/esp_ble_mesh/mesh_core/prov.c -components/bt/esp_ble_mesh/mesh_core/prov.h -components/bt/esp_ble_mesh/mesh_core/provisioner_main.c -components/bt/esp_ble_mesh/mesh_core/provisioner_main.h -components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c -components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h -components/bt/esp_ble_mesh/mesh_core/proxy_client.c -components/bt/esp_ble_mesh/mesh_core/proxy_client.h -components/bt/esp_ble_mesh/mesh_core/proxy_server.c -components/bt/esp_ble_mesh/mesh_core/proxy_server.h -components/bt/esp_ble_mesh/mesh_core/scan.c -components/bt/esp_ble_mesh/mesh_core/scan.h -components/bt/esp_ble_mesh/mesh_core/settings.c -components/bt/esp_ble_mesh/mesh_core/settings.h -components/bt/esp_ble_mesh/mesh_core/settings_uid.c -components/bt/esp_ble_mesh/mesh_core/settings_uid.h -components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.c -components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.h -components/bt/esp_ble_mesh/mesh_core/test.c -components/bt/esp_ble_mesh/mesh_core/test.h -components/bt/esp_ble_mesh/mesh_core/transport.c -components/bt/esp_ble_mesh/mesh_core/transport.h -components/bt/esp_ble_mesh/mesh_models/client/client_common.c -components/bt/esp_ble_mesh/mesh_models/client/generic_client.c -components/bt/esp_ble_mesh/mesh_models/client/include/client_common.h -components/bt/esp_ble_mesh/mesh_models/client/include/generic_client.h -components/bt/esp_ble_mesh/mesh_models/client/include/lighting_client.h -components/bt/esp_ble_mesh/mesh_models/client/include/sensor_client.h -components/bt/esp_ble_mesh/mesh_models/client/include/time_scene_client.h -components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c -components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c -components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c -components/bt/esp_ble_mesh/mesh_models/common/device_property.c -components/bt/esp_ble_mesh/mesh_models/common/include/device_property.h -components/bt/esp_ble_mesh/mesh_models/common/include/model_opcode.h -components/bt/esp_ble_mesh/mesh_models/server/generic_server.c -components/bt/esp_ble_mesh/mesh_models/server/include/generic_server.h -components/bt/esp_ble_mesh/mesh_models/server/include/lighting_server.h -components/bt/esp_ble_mesh/mesh_models/server/include/sensor_server.h -components/bt/esp_ble_mesh/mesh_models/server/include/server_common.h -components/bt/esp_ble_mesh/mesh_models/server/include/state_binding.h -components/bt/esp_ble_mesh/mesh_models/server/include/state_transition.h -components/bt/esp_ble_mesh/mesh_models/server/include/time_scene_server.h -components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c -components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c -components/bt/esp_ble_mesh/mesh_models/server/server_common.c -components/bt/esp_ble_mesh/mesh_models/server/state_binding.c -components/bt/esp_ble_mesh/mesh_models/server/state_transition.c -components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c -components/bt/host/bluedroid/api/esp_a2dp_api.c -components/bt/host/bluedroid/api/esp_avrc_api.c -components/bt/host/bluedroid/api/esp_bt_device.c -components/bt/host/bluedroid/api/esp_bt_main.c -components/bt/host/bluedroid/api/esp_gap_bt_api.c -components/bt/host/bluedroid/api/esp_hf_ag_api.c -components/bt/host/bluedroid/api/esp_hf_client_api.c -components/bt/host/bluedroid/api/esp_hidd_api.c -components/bt/host/bluedroid/api/esp_hidh_api.c -components/bt/host/bluedroid/api/esp_spp_api.c -components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h -components/bt/host/bluedroid/api/include/api/esp_avrc_api.h -components/bt/host/bluedroid/api/include/api/esp_bt_defs.h -components/bt/host/bluedroid/api/include/api/esp_bt_device.h -components/bt/host/bluedroid/api/include/api/esp_bt_main.h -components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h -components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h -components/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h -components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h -components/bt/host/bluedroid/api/include/api/esp_gattc_api.h -components/bt/host/bluedroid/api/include/api/esp_gatts_api.h -components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h -components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h -components/bt/host/bluedroid/api/include/api/esp_hf_defs.h -components/bt/host/bluedroid/api/include/api/esp_hidd_api.h -components/bt/host/bluedroid/api/include/api/esp_hidh_api.h -components/bt/host/bluedroid/api/include/api/esp_spp_api.h -components/bt/host/bluedroid/bta/ar/bta_ar.c -components/bt/host/bluedroid/bta/ar/include/bta_ar_int.h -components/bt/host/bluedroid/bta/av/bta_av_aact.c -components/bt/host/bluedroid/bta/av/bta_av_act.c -components/bt/host/bluedroid/bta/av/bta_av_api.c -components/bt/host/bluedroid/bta/av/bta_av_cfg.c -components/bt/host/bluedroid/bta/av/bta_av_ci.c -components/bt/host/bluedroid/bta/av/bta_av_main.c -components/bt/host/bluedroid/bta/av/bta_av_sbc.c -components/bt/host/bluedroid/bta/av/bta_av_ssm.c -components/bt/host/bluedroid/bta/av/include/bta_av_int.h -components/bt/host/bluedroid/bta/dm/bta_dm_act.c -components/bt/host/bluedroid/bta/dm/bta_dm_api.c -components/bt/host/bluedroid/bta/dm/bta_dm_cfg.c -components/bt/host/bluedroid/bta/dm/bta_dm_ci.c -components/bt/host/bluedroid/bta/dm/bta_dm_co.c -components/bt/host/bluedroid/bta/dm/bta_dm_main.c -components/bt/host/bluedroid/bta/dm/bta_dm_pm.c -components/bt/host/bluedroid/bta/dm/bta_dm_qos.c -components/bt/host/bluedroid/bta/dm/bta_dm_sco.c -components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h -components/bt/host/bluedroid/bta/gatt/bta_gatt_common.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_cache.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_ci.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c -components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c -components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c -components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c -components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c -components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c -components/bt/host/bluedroid/bta/gatt/bta_gatts_utils.c -components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h -components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h -components/bt/host/bluedroid/bta/hd/bta_hd_act.c -components/bt/host/bluedroid/bta/hd/bta_hd_api.c -components/bt/host/bluedroid/bta/hd/bta_hd_main.c -components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h -components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_at.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_cfg.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c -components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c -components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_at.h -components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_at.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_cmd.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_rfc.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c -components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sdp.c -components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_at.h -components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h -components/bt/host/bluedroid/bta/hh/bta_hh_act.c -components/bt/host/bluedroid/bta/hh/bta_hh_api.c -components/bt/host/bluedroid/bta/hh/bta_hh_cfg.c -components/bt/host/bluedroid/bta/hh/bta_hh_le.c -components/bt/host/bluedroid/bta/hh/bta_hh_main.c -components/bt/host/bluedroid/bta/hh/bta_hh_utils.c -components/bt/host/bluedroid/bta/hh/include/bta_hh_int.h -components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h -components/bt/host/bluedroid/bta/include/bta/bta_ag_co.h -components/bt/host/bluedroid/bta/include/bta/bta_api.h -components/bt/host/bluedroid/bta/include/bta/bta_ar_api.h -components/bt/host/bluedroid/bta/include/bta/bta_av_api.h -components/bt/host/bluedroid/bta/include/bta/bta_av_ci.h -components/bt/host/bluedroid/bta/include/bta/bta_av_co.h -components/bt/host/bluedroid/bta/include/bta/bta_av_sbc.h -components/bt/host/bluedroid/bta/include/bta/bta_dm_ci.h -components/bt/host/bluedroid/bta/include/bta/bta_dm_co.h -components/bt/host/bluedroid/bta/include/bta/bta_gap_bt_co.h -components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h -components/bt/host/bluedroid/bta/include/bta/bta_gatt_common.h -components/bt/host/bluedroid/bta/include/bta/bta_gattc_ci.h -components/bt/host/bluedroid/bta/include/bta/bta_gattc_co.h -components/bt/host/bluedroid/bta/include/bta/bta_gatts_co.h -components/bt/host/bluedroid/bta/include/bta/bta_hd_api.h -components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h -components/bt/host/bluedroid/bta/include/bta/bta_hf_client_co.h -components/bt/host/bluedroid/bta/include/bta/bta_hfp_defs.h -components/bt/host/bluedroid/bta/include/bta/bta_hh_api.h -components/bt/host/bluedroid/bta/include/bta/bta_hh_co.h -components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h -components/bt/host/bluedroid/bta/include/bta/bta_jv_co.h -components/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h -components/bt/host/bluedroid/bta/include/bta/bta_sys.h -components/bt/host/bluedroid/bta/include/bta/utl.h -components/bt/host/bluedroid/bta/jv/bta_jv_act.c -components/bt/host/bluedroid/bta/jv/bta_jv_api.c -components/bt/host/bluedroid/bta/jv/bta_jv_cfg.c -components/bt/host/bluedroid/bta/jv/bta_jv_main.c -components/bt/host/bluedroid/bta/jv/include/bta_jv_int.h -components/bt/host/bluedroid/bta/sdp/bta_sdp.c -components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c -components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c -components/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c -components/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h -components/bt/host/bluedroid/bta/sys/bta_sys_conn.c -components/bt/host/bluedroid/bta/sys/bta_sys_main.c -components/bt/host/bluedroid/bta/sys/include/bta_sys_int.h -components/bt/host/bluedroid/bta/sys/utl.c -components/bt/host/bluedroid/btc/core/btc_ble_storage.c -components/bt/host/bluedroid/btc/core/btc_config.c -components/bt/host/bluedroid/btc/core/btc_dev.c -components/bt/host/bluedroid/btc/core/btc_dm.c -components/bt/host/bluedroid/btc/core/btc_main.c -components/bt/host/bluedroid/btc/core/btc_profile_queue.c -components/bt/host/bluedroid/btc/core/btc_sm.c -components/bt/host/bluedroid/btc/core/btc_storage.c -components/bt/host/bluedroid/btc/core/btc_util.c -components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h -components/bt/host/bluedroid/btc/include/btc/btc_common.h -components/bt/host/bluedroid/btc/include/btc/btc_config.h -components/bt/host/bluedroid/btc/include/btc/btc_dev.h -components/bt/host/bluedroid/btc/include/btc/btc_dm.h -components/bt/host/bluedroid/btc/include/btc/btc_main.h -components/bt/host/bluedroid/btc/include/btc/btc_profile_queue.h -components/bt/host/bluedroid/btc/include/btc/btc_sm.h -components/bt/host/bluedroid/btc/include/btc/btc_storage.h -components/bt/host/bluedroid/btc/include/btc/btc_util.h -components/bt/host/bluedroid/btc/profile/esp/ble_button/button_pro.c -components/bt/host/bluedroid/btc/profile/esp/include/button_pro.h -components/bt/host/bluedroid/btc/profile/esp/include/wx_airsync_prf.h -components/bt/host/bluedroid/btc/profile/esp/wechat_AirSync/wx_airsync_prf.c -components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c -components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c -components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c -components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c -components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c -components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c -components/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h -components/bt/host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c -components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c -components/bt/host/bluedroid/btc/profile/std/battery/battery_prf.c -components/bt/host/bluedroid/btc/profile/std/battery/include/srvc_battery_int.h -components/bt/host/bluedroid/btc/profile/std/dis/dis_profile.c -components/bt/host/bluedroid/btc/profile/std/dis/include/srvc_dis_int.h -components/bt/host/bluedroid/btc/profile/std/gap/bta_gap_bt_co.c -components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c -components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c -components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c -components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c -components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c -components/bt/host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c -components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c -components/bt/host/bluedroid/btc/profile/std/hid/bta_hh_co.c -components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c -components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c -components/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h -components/bt/host/bluedroid/btc/profile/std/include/btc_a2dp.h -components/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_control.h -components/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_sink.h -components/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h -components/bt/host/bluedroid/btc/profile/std/include/btc_av.h -components/bt/host/bluedroid/btc/profile/std/include/btc_av_api.h -components/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h -components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h -components/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h -components/bt/host/bluedroid/btc/profile/std/include/btc_gatt_common.h -components/bt/host/bluedroid/btc/profile/std/include/btc_gatt_util.h -components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h -components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h -components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h -components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h -components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h -components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h -components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h -components/bt/host/bluedroid/btc/profile/std/include/dis_api.h -components/bt/host/bluedroid/btc/profile/std/include/srvc_api.h -components/bt/host/bluedroid/btc/profile/std/smp/esp_app_sec.c -components/bt/host/bluedroid/btc/profile/std/smp/include/esp_sec_api.h -components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c -components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h -components/bt/host/bluedroid/common/include/common/bt_common_types.h -components/bt/host/bluedroid/common/include/common/bt_defs.h -components/bt/host/bluedroid/common/include/common/bt_target.h -components/bt/host/bluedroid/common/include/common/bt_trace.h -components/bt/host/bluedroid/common/include/common/bt_vendor_lib.h -components/bt/host/bluedroid/common/include/common/bte.h -components/bt/host/bluedroid/common/include/common/bte_appl.h -components/bt/host/bluedroid/device/bdaddr.c -components/bt/host/bluedroid/device/controller.c -components/bt/host/bluedroid/device/include/device/bdaddr.h -components/bt/host/bluedroid/device/include/device/controller.h -components/bt/host/bluedroid/device/include/device/device_features.h -components/bt/host/bluedroid/device/include/device/event_mask.h -components/bt/host/bluedroid/device/include/device/interop.h -components/bt/host/bluedroid/device/include/device/interop_database.h -components/bt/host/bluedroid/device/include/device/version.h -components/bt/host/bluedroid/device/interop.c -components/bt/host/bluedroid/external/sbc/decoder/include/oi_assert.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_bitstream.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_bt_spec.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc_private.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_common.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_cpu_dep.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_modules.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_osinterface.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_status.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_stddefs.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_string.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_time.h -components/bt/host/bluedroid/external/sbc/decoder/include/oi_utils.h -components/bt/host/bluedroid/external/sbc/decoder/srce/alloc.c -components/bt/host/bluedroid/external/sbc/decoder/srce/bitalloc-sbc.c -components/bt/host/bluedroid/external/sbc/decoder/srce/bitalloc.c -components/bt/host/bluedroid/external/sbc/decoder/srce/bitstream-decode.c -components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-oina.c -components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-private.c -components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c -components/bt/host/bluedroid/external/sbc/decoder/srce/dequant.c -components/bt/host/bluedroid/external/sbc/decoder/srce/framing-sbc.c -components/bt/host/bluedroid/external/sbc/decoder/srce/framing.c -components/bt/host/bluedroid/external/sbc/decoder/srce/oi_codec_version.c -components/bt/host/bluedroid/external/sbc/decoder/srce/synthesis-8-generated.c -components/bt/host/bluedroid/external/sbc/decoder/srce/synthesis-dct8.c -components/bt/host/bluedroid/external/sbc/decoder/srce/synthesis-sbc.c -components/bt/host/bluedroid/external/sbc/encoder/include/sbc_dct.h -components/bt/host/bluedroid/external/sbc/encoder/include/sbc_enc_func_declare.h -components/bt/host/bluedroid/external/sbc/encoder/include/sbc_encoder.h -components/bt/host/bluedroid/external/sbc/encoder/include/sbc_if.h -components/bt/host/bluedroid/external/sbc/encoder/include/sbc_types.h -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_analysis.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_dct.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_dct_coeffs.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c -components/bt/host/bluedroid/external/sbc/encoder/srce/sbc_packing.c -components/bt/host/bluedroid/external/sbc/plc/include/sbc_plc.h -components/bt/host/bluedroid/external/sbc/plc/sbc_plc.c -components/bt/host/bluedroid/hci/hci_audio.c -components/bt/host/bluedroid/hci/hci_hal_h4.c -components/bt/host/bluedroid/hci/hci_layer.c -components/bt/host/bluedroid/hci/hci_packet_factory.c -components/bt/host/bluedroid/hci/hci_packet_parser.c -components/bt/host/bluedroid/hci/include/hci/bt_vendor_lib.h -components/bt/host/bluedroid/hci/include/hci/hci_audio.h -components/bt/host/bluedroid/hci/include/hci/hci_hal.h -components/bt/host/bluedroid/hci/include/hci/hci_internals.h -components/bt/host/bluedroid/hci/include/hci/hci_layer.h -components/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h -components/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h -components/bt/host/bluedroid/hci/include/hci/packet_fragmenter.h -components/bt/host/bluedroid/hci/packet_fragmenter.c -components/bt/host/bluedroid/main/bte_init.c -components/bt/host/bluedroid/main/bte_main.c -components/bt/host/bluedroid/stack/a2dp/a2d_api.c -components/bt/host/bluedroid/stack/a2dp/a2d_sbc.c -components/bt/host/bluedroid/stack/a2dp/include/a2d_int.h -components/bt/host/bluedroid/stack/avct/avct_api.c -components/bt/host/bluedroid/stack/avct/avct_ccb.c -components/bt/host/bluedroid/stack/avct/avct_l2c.c -components/bt/host/bluedroid/stack/avct/avct_lcb.c -components/bt/host/bluedroid/stack/avct/avct_lcb_act.c -components/bt/host/bluedroid/stack/avct/include/avct_defs.h -components/bt/host/bluedroid/stack/avct/include/avct_int.h -components/bt/host/bluedroid/stack/avdt/avdt_ad.c -components/bt/host/bluedroid/stack/avdt/avdt_api.c -components/bt/host/bluedroid/stack/avdt/avdt_ccb.c -components/bt/host/bluedroid/stack/avdt/avdt_ccb_act.c -components/bt/host/bluedroid/stack/avdt/avdt_l2c.c -components/bt/host/bluedroid/stack/avdt/avdt_msg.c -components/bt/host/bluedroid/stack/avdt/avdt_scb.c -components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c -components/bt/host/bluedroid/stack/avdt/include/avdt_defs.h -components/bt/host/bluedroid/stack/avdt/include/avdt_int.h -components/bt/host/bluedroid/stack/avrc/avrc_api.c -components/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c -components/bt/host/bluedroid/stack/avrc/avrc_bld_tg.c -components/bt/host/bluedroid/stack/avrc/avrc_opt.c -components/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c -components/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c -components/bt/host/bluedroid/stack/avrc/avrc_sdp.c -components/bt/host/bluedroid/stack/avrc/avrc_utils.c -components/bt/host/bluedroid/stack/avrc/include/avrc_int.h -components/bt/host/bluedroid/stack/btm/btm_acl.c -components/bt/host/bluedroid/stack/btm/btm_ble.c -components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c -components/bt/host/bluedroid/stack/btm/btm_ble_addr.c -components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c -components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c -components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c -components/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c -components/bt/host/bluedroid/stack/btm/btm_ble_gap.c -components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c -components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c -components/bt/host/bluedroid/stack/btm/btm_dev.c -components/bt/host/bluedroid/stack/btm/btm_devctl.c -components/bt/host/bluedroid/stack/btm/btm_inq.c -components/bt/host/bluedroid/stack/btm/btm_main.c -components/bt/host/bluedroid/stack/btm/btm_pm.c -components/bt/host/bluedroid/stack/btm/btm_sco.c -components/bt/host/bluedroid/stack/btm/btm_sec.c -components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h -components/bt/host/bluedroid/stack/btm/include/btm_int.h -components/bt/host/bluedroid/stack/btu/btu_hcif.c -components/bt/host/bluedroid/stack/btu/btu_init.c -components/bt/host/bluedroid/stack/btu/btu_task.c -components/bt/host/bluedroid/stack/gap/gap_api.c -components/bt/host/bluedroid/stack/gap/gap_ble.c -components/bt/host/bluedroid/stack/gap/gap_conn.c -components/bt/host/bluedroid/stack/gap/gap_utils.c -components/bt/host/bluedroid/stack/gap/include/gap_int.h -components/bt/host/bluedroid/stack/gatt/att_protocol.c -components/bt/host/bluedroid/stack/gatt/gatt_api.c -components/bt/host/bluedroid/stack/gatt/gatt_attr.c -components/bt/host/bluedroid/stack/gatt/gatt_auth.c -components/bt/host/bluedroid/stack/gatt/gatt_cl.c -components/bt/host/bluedroid/stack/gatt/gatt_db.c -components/bt/host/bluedroid/stack/gatt/gatt_main.c -components/bt/host/bluedroid/stack/gatt/gatt_sr.c -components/bt/host/bluedroid/stack/gatt/gatt_utils.c -components/bt/host/bluedroid/stack/gatt/include/gatt_int.h -components/bt/host/bluedroid/stack/hcic/hciblecmds.c -components/bt/host/bluedroid/stack/hcic/hcicmds.c -components/bt/host/bluedroid/stack/hid/hidd_api.c -components/bt/host/bluedroid/stack/hid/hidd_conn.c -components/bt/host/bluedroid/stack/hid/hidh_api.c -components/bt/host/bluedroid/stack/hid/hidh_conn.c -components/bt/host/bluedroid/stack/hid/include/hid_conn.h -components/bt/host/bluedroid/stack/hid/include/hid_int.h -components/bt/host/bluedroid/stack/include/stack/a2d_api.h -components/bt/host/bluedroid/stack/include/stack/a2d_sbc.h -components/bt/host/bluedroid/stack/include/stack/avct_api.h -components/bt/host/bluedroid/stack/include/stack/avdt_api.h -components/bt/host/bluedroid/stack/include/stack/avdtc_api.h -components/bt/host/bluedroid/stack/include/stack/avrc_api.h -components/bt/host/bluedroid/stack/include/stack/avrc_defs.h -components/bt/host/bluedroid/stack/include/stack/bt_types.h -components/bt/host/bluedroid/stack/include/stack/btm_api.h -components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h -components/bt/host/bluedroid/stack/include/stack/btu.h -components/bt/host/bluedroid/stack/include/stack/dyn_mem.h -components/bt/host/bluedroid/stack/include/stack/gap_api.h -components/bt/host/bluedroid/stack/include/stack/gatt_api.h -components/bt/host/bluedroid/stack/include/stack/gattdefs.h -components/bt/host/bluedroid/stack/include/stack/hcidefs.h -components/bt/host/bluedroid/stack/include/stack/hcimsgs.h -components/bt/host/bluedroid/stack/include/stack/hidd_api.h -components/bt/host/bluedroid/stack/include/stack/hiddefs.h -components/bt/host/bluedroid/stack/include/stack/hidh_api.h -components/bt/host/bluedroid/stack/include/stack/l2c_api.h -components/bt/host/bluedroid/stack/include/stack/l2cap_client.h -components/bt/host/bluedroid/stack/include/stack/l2cdefs.h -components/bt/host/bluedroid/stack/include/stack/port_api.h -components/bt/host/bluedroid/stack/include/stack/port_ext.h -components/bt/host/bluedroid/stack/include/stack/profiles_api.h -components/bt/host/bluedroid/stack/include/stack/rfcdefs.h -components/bt/host/bluedroid/stack/include/stack/sdp_api.h -components/bt/host/bluedroid/stack/include/stack/sdpdefs.h -components/bt/host/bluedroid/stack/include/stack/smp_api.h -components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h -components/bt/host/bluedroid/stack/l2cap/l2c_api.c -components/bt/host/bluedroid/stack/l2cap/l2c_ble.c -components/bt/host/bluedroid/stack/l2cap/l2c_csm.c -components/bt/host/bluedroid/stack/l2cap/l2c_fcr.c -components/bt/host/bluedroid/stack/l2cap/l2c_link.c -components/bt/host/bluedroid/stack/l2cap/l2c_main.c -components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c -components/bt/host/bluedroid/stack/l2cap/l2c_utils.c -components/bt/host/bluedroid/stack/l2cap/l2cap_client.c -components/bt/host/bluedroid/stack/rfcomm/include/port_int.h -components/bt/host/bluedroid/stack/rfcomm/include/rfc_int.h -components/bt/host/bluedroid/stack/rfcomm/port_api.c -components/bt/host/bluedroid/stack/rfcomm/port_rfc.c -components/bt/host/bluedroid/stack/rfcomm/port_utils.c -components/bt/host/bluedroid/stack/rfcomm/rfc_l2cap_if.c -components/bt/host/bluedroid/stack/rfcomm/rfc_mx_fsm.c -components/bt/host/bluedroid/stack/rfcomm/rfc_port_fsm.c -components/bt/host/bluedroid/stack/rfcomm/rfc_port_if.c -components/bt/host/bluedroid/stack/rfcomm/rfc_ts_frames.c -components/bt/host/bluedroid/stack/rfcomm/rfc_utils.c -components/bt/host/bluedroid/stack/sdp/include/sdpint.h -components/bt/host/bluedroid/stack/sdp/sdp_api.c -components/bt/host/bluedroid/stack/sdp/sdp_db.c -components/bt/host/bluedroid/stack/sdp/sdp_discovery.c -components/bt/host/bluedroid/stack/sdp/sdp_main.c -components/bt/host/bluedroid/stack/sdp/sdp_server.c -components/bt/host/bluedroid/stack/sdp/sdp_utils.c -components/bt/host/bluedroid/stack/smp/aes.c -components/bt/host/bluedroid/stack/smp/include/aes.h -components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h -components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h -components/bt/host/bluedroid/stack/smp/include/smp_int.h -components/bt/host/bluedroid/stack/smp/p_256_curvepara.c -components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c -components/bt/host/bluedroid/stack/smp/p_256_multprecision.c -components/bt/host/bluedroid/stack/smp/smp_act.c -components/bt/host/bluedroid/stack/smp/smp_api.c -components/bt/host/bluedroid/stack/smp/smp_br_main.c -components/bt/host/bluedroid/stack/smp/smp_cmac.c -components/bt/host/bluedroid/stack/smp/smp_keys.c -components/bt/host/bluedroid/stack/smp/smp_l2c.c -components/bt/host/bluedroid/stack/smp/smp_main.c -components/bt/host/bluedroid/stack/smp/smp_utils.c -components/bt/host/nimble/esp-hci/include/esp_nimble_hci.h -components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c -components/bt/host/nimble/port/include/console/console.h -components/bt/host/nimble/port/include/esp_nimble_cfg.h -components/bt/host/nimble/port/include/esp_nimble_mem.h -components/bt/host/nimble/port/src/esp_nimble_mem.c -components/bt/include/esp32/include/esp_bt.h -components/bt/include/esp32c3/include/esp_bt.h -components/bt/include/esp32s3/include/esp_bt.h -components/bt/test/test_bt_common.c -components/bt/test/test_smp.c -components/cbor/port/include/cbor.h -components/coap/port/include/coap3/coap.h -components/coap/port/include/coap_config.h -components/coap/port/include/coap_config_posix.h -components/console/argtable3/argtable3.c -components/console/argtable3/argtable3.h -components/console/linenoise/linenoise.c -components/console/linenoise/linenoise.h -components/driver/include/driver/usb_serial_jtag.h -components/driver/usb_serial_jtag.c -components/esp32/include/rom/aes.h -components/esp32/include/rom/bigint.h -components/esp32/include/rom/cache.h -components/esp32/include/rom/crc.h -components/esp32/include/rom/efuse.h -components/esp32/include/rom/ets_sys.h -components/esp32/include/rom/gpio.h -components/esp32/include/rom/libc_stubs.h -components/esp32/include/rom/lldesc.h -components/esp32/include/rom/md5_hash.h -components/esp32/include/rom/miniz.h -components/esp32/include/rom/queue.h -components/esp32/include/rom/rtc.h -components/esp32/include/rom/secure_boot.h -components/esp32/include/rom/sha.h -components/esp32/include/rom/spi_flash.h -components/esp32/include/rom/tbconsole.h -components/esp32/include/rom/tjpgd.h -components/esp32/include/rom/uart.h -components/esp_adc_cal/esp_adc_cal_esp32.c -components/esp_adc_cal/esp_adc_cal_esp32c3.c -components/esp_adc_cal/esp_adc_cal_esp32h2.c -components/esp_adc_cal/esp_adc_cal_esp32s2.c -components/esp_adc_cal/include/esp_adc_cal.h -components/esp_common/include/esp_assert.h -components/esp_common/include/esp_attr.h -components/esp_common/include/esp_bit_defs.h -components/esp_common/include/esp_check.h -components/esp_common/include/esp_compiler.h -components/esp_common/include/esp_err.h -components/esp_common/include/esp_idf_version.h -components/esp_common/include/esp_types.h -components/esp_common/src/esp_err_to_name.c -components/esp_common/test/test_attr.c -components/esp_eth/include/esp_eth.h -components/esp_eth/include/esp_eth_com.h -components/esp_eth/include/esp_eth_mac.h -components/esp_eth/include/esp_eth_netif_glue.h -components/esp_eth/include/esp_eth_phy.h -components/esp_eth/include/eth_phy_regs_struct.h -components/esp_eth/src/dm9051.h -components/esp_eth/src/esp_eth.c -components/esp_eth/src/esp_eth_mac_dm9051.c -components/esp_eth/src/esp_eth_mac_esp.c -components/esp_eth/src/esp_eth_mac_ksz8851snl.c -components/esp_eth/src/esp_eth_mac_openeth.c -components/esp_eth/src/esp_eth_mac_w5500.c -components/esp_eth/src/esp_eth_netif_glue.c -components/esp_eth/src/esp_eth_phy.c -components/esp_eth/src/esp_eth_phy_dm9051.c -components/esp_eth/src/esp_eth_phy_dp83848.c -components/esp_eth/src/esp_eth_phy_ip101.c -components/esp_eth/src/esp_eth_phy_ksz80xx.c -components/esp_eth/src/esp_eth_phy_ksz8851snl.c -components/esp_eth/src/esp_eth_phy_lan87xx.c -components/esp_eth/src/esp_eth_phy_rtl8201.c -components/esp_eth/src/esp_eth_phy_w5500.c -components/esp_eth/src/ksz8851.h -components/esp_eth/src/openeth.h -components/esp_eth/src/w5500.h -components/esp_eth/test/test_emac.c -components/esp_eth/test_apps/component_ut_test.py -components/esp_eth/test_apps/main/esp_eth_test.c -components/esp_event/default_event_loop.c -components/esp_event/esp_event.c -components/esp_event/esp_event_private.c -components/esp_event/event_loop_legacy.c -components/esp_event/event_send.c -components/esp_event/host_test/esp_event_unit_test/main/esp_event_test.cpp -components/esp_event/host_test/fixtures.hpp -components/esp_event/include/esp_event.h -components/esp_event/include/esp_event_base.h -components/esp_event/include/esp_event_legacy.h -components/esp_event/include/esp_event_loop.h -components/esp_event/private_include/esp_event_internal.h -components/esp_event/private_include/esp_event_private.h -components/esp_event/test/test_default_loop.c -components/esp_event/test/test_event.c -components/esp_gdbstub/esp32/gdbstub_target_config.h -components/esp_gdbstub/esp32c3/gdbstub_esp32c3.c -components/esp_gdbstub/esp32c3/gdbstub_target_config.h -components/esp_gdbstub/esp32h2/gdbstub_esp32h2.c -components/esp_gdbstub/esp32h2/gdbstub_target_config.h -components/esp_gdbstub/esp32s2/gdbstub_target_config.h -components/esp_gdbstub/esp32s3/gdbstub_target_config.h -components/esp_gdbstub/esp_common/gdbstub_common.c -components/esp_gdbstub/include/esp_gdbstub.h -components/esp_gdbstub/private_include/esp_gdbstub_common.h -components/esp_gdbstub/riscv/esp_gdbstub_arch.h -components/esp_gdbstub/riscv/gdbstub_riscv.c -components/esp_gdbstub/src/gdbstub.c -components/esp_gdbstub/src/packet.c -components/esp_gdbstub/xtensa/esp_gdbstub_arch.h -components/esp_gdbstub/xtensa/gdbstub_xtensa.c -components/esp_hid/include/esp_hid_common.h -components/esp_hid/include/esp_hidd.h -components/esp_hid/include/esp_hidd_gatts.h -components/esp_hid/include/esp_hidd_transport.h -components/esp_hid/include/esp_hidh.h -components/esp_hid/include/esp_hidh_bluedroid.h -components/esp_hid/include/esp_hidh_gattc.h -components/esp_hid/include/esp_hidh_transport.h -components/esp_hid/private/ble_hidd.h -components/esp_hid/private/ble_hidh.h -components/esp_hid/private/bt_hidd.h -components/esp_hid/private/bt_hidh.h -components/esp_hid/private/esp_hidd_private.h -components/esp_hid/private/esp_hidh_private.h -components/esp_hid/src/ble_hidd.c -components/esp_hid/src/ble_hidh.c -components/esp_hid/src/bt_hidd.c -components/esp_hid/src/bt_hidh.c -components/esp_hid/src/esp_hid_common.c -components/esp_hid/src/esp_hidd.c -components/esp_hid/src/esp_hidh.c -components/esp_hid/test/hid_descriptor.h -components/esp_hid/test/test_esp_hid.c -components/esp_https_ota/include/esp_https_ota.h -components/esp_https_ota/src/esp_https_ota.c -components/esp_hw_support/include/esp_clk.h -components/esp_hw_support/include/soc/esp_himem.h -components/esp_hw_support/include/soc/esp_spiram.h -components/esp_ipc/include/esp_ipc.h -components/esp_ipc/src/esp_ipc.c -components/esp_ipc/test/test_ipc.c -components/esp_ipc/test/test_ipc_isr.c -components/esp_lcd/test/test_i2c_lcd_panel.c -components/esp_lcd/test/test_i80_board.h -components/esp_lcd/test/test_i80_lcd_panel.c -components/esp_lcd/test/test_lvgl_port.h -components/esp_lcd/test/test_lvgl_port_v7.c -components/esp_lcd/test/test_rgb_panel.c -components/esp_lcd/test/test_spi_board.h -components/esp_lcd/test/test_spi_lcd_panel.c -components/esp_local_ctrl/include/esp_local_ctrl.h -components/esp_local_ctrl/proto-c/esp_local_ctrl.pb-c.c -components/esp_local_ctrl/proto-c/esp_local_ctrl.pb-c.h -components/esp_local_ctrl/python/esp_local_ctrl_pb2.py -components/esp_local_ctrl/src/esp_local_ctrl.c -components/esp_local_ctrl/src/esp_local_ctrl_handler.c -components/esp_local_ctrl/src/esp_local_ctrl_priv.h -components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c -components/esp_local_ctrl/src/esp_local_ctrl_transport_httpd.c -components/esp_netif/esp_netif_defaults.c -components/esp_netif/esp_netif_handlers.c -components/esp_netif/esp_netif_objects.c -components/esp_netif/include/esp_netif.h -components/esp_netif/include/esp_netif_defaults.h -components/esp_netif/include/esp_netif_ip_addr.h -components/esp_netif/include/esp_netif_net_stack.h -components/esp_netif/include/esp_netif_ppp.h -components/esp_netif/include/esp_netif_slip.h -components/esp_netif/include/esp_netif_sta_list.h -components/esp_netif/include/esp_netif_types.h -components/esp_netif/loopback/esp_netif_loopback.c -components/esp_netif/lwip/esp_netif_lwip.c -components/esp_netif/lwip/esp_netif_lwip_defaults.c -components/esp_netif/lwip/esp_netif_lwip_internal.h -components/esp_netif/lwip/esp_netif_lwip_ppp.c -components/esp_netif/lwip/esp_netif_lwip_ppp.h -components/esp_netif/lwip/esp_netif_lwip_slip.c -components/esp_netif/lwip/esp_netif_lwip_slip.h -components/esp_netif/lwip/esp_netif_sta_list.c -components/esp_netif/private_include/esp_netif_private.h -components/esp_netif/test/test_esp_netif.c -components/esp_netif/test_apps/component_ut_test.py -components/esp_netif/test_apps/main/esp_netif_test.c -components/esp_phy/esp32/include/phy_init_data.h -components/esp_phy/esp32c3/include/phy_init_data.h -components/esp_phy/esp32h2/include/phy_init_data.h -components/esp_phy/esp32s2/include/phy_init_data.h -components/esp_phy/esp32s3/include/phy_init_data.h -components/esp_phy/include/esp_phy_init.h -components/esp_phy/include/phy.h -components/esp_phy/src/phy_init.c -components/esp_phy/src/phy_init_esp32hxx.c -components/esp_phy/test/test_phy_rtc.c -components/esp_pm/include/esp32/pm.h -components/esp_pm/include/esp32c3/pm.h -components/esp_pm/include/esp32h2/pm.h -components/esp_pm/include/esp32s2/pm.h -components/esp_pm/include/esp32s3/pm.h -components/esp_pm/include/esp_pm.h -components/esp_pm/include/esp_private/pm_impl.h -components/esp_pm/include/esp_private/pm_trace.h -components/esp_pm/pm_impl.c -components/esp_pm/pm_locks.c -components/esp_pm/pm_trace.c -components/esp_pm/test/test_pm.c -components/esp_ringbuf/include/freertos/ringbuf.h -components/esp_ringbuf/ringbuf.c -components/esp_ringbuf/test/test_ringbuf.c -components/esp_rom/esp32/esp_rom_caps.h -components/esp_rom/esp32/ld/esp32.rom.api.ld -components/esp_rom/esp32/ld/esp32.rom.eco3.ld -components/esp_rom/esp32/ld/esp32.rom.ld -components/esp_rom/esp32/ld/esp32.rom.libgcc.ld -components/esp_rom/esp32/ld/esp32.rom.newlib-data.ld -components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld -components/esp_rom/esp32/ld/esp32.rom.newlib-locale.ld -components/esp_rom/esp32/ld/esp32.rom.newlib-nano.ld -components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld -components/esp_rom/esp32/ld/esp32.rom.redefined.ld -components/esp_rom/esp32/ld/esp32.rom.spiflash.ld -components/esp_rom/esp32/ld/esp32.rom.syscalls.ld -components/esp_rom/esp32c3/esp_rom_caps.h -components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld -components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld -components/esp_rom/esp32c3/ld/esp32c3.rom.ld -components/esp_rom/esp32c3/ld/esp32c3.rom.libgcc.ld -components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-nano.ld -components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld -components/esp_rom/esp32c3/ld/esp32c3.rom.version.ld -components/esp_rom/esp32h2/esp_rom_caps.h -components/esp_rom/esp32h2/ld/esp32h2.rom.api.ld -components/esp_rom/esp32h2/ld/esp32h2.rom.ld -components/esp_rom/esp32h2/ld/esp32h2.rom.libgcc.ld -components/esp_rom/esp32h2/ld/esp32h2.rom.newlib-nano.ld -components/esp_rom/esp32h2/ld/esp32h2.rom.newlib.ld -components/esp_rom/esp32h2/ld/esp32h2.rom.version.ld -components/esp_rom/esp32s2/esp_rom_caps.h -components/esp_rom/esp32s2/ld/esp32s2.rom.api.ld -components/esp_rom/esp32s2/ld/esp32s2.rom.ld -components/esp_rom/esp32s2/ld/esp32s2.rom.libgcc.ld -components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-data.ld -components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld -components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-nano.ld -components/esp_rom/esp32s2/ld/esp32s2.rom.spiflash.ld -components/esp_rom/esp32s2/usb_descriptors.c -components/esp_rom/esp32s3/esp_rom_caps.h -components/esp_rom/esp32s3/ld/esp32s3.rom.api.ld -components/esp_rom/esp32s3/ld/esp32s3.rom.ld -components/esp_rom/esp32s3/ld/esp32s3.rom.libgcc.ld -components/esp_rom/esp32s3/ld/esp32s3.rom.newlib-nano.ld -components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld -components/esp_rom/esp32s3/ld/esp32s3.rom.version.ld -components/esp_rom/host_test/rom_test/main/rom_test.cpp -components/esp_rom/include/esp32/rom/aes.h -components/esp_rom/include/esp32/rom/bigint.h -components/esp_rom/include/esp32/rom/cache.h -components/esp_rom/include/esp32/rom/crc.h -components/esp_rom/include/esp32/rom/efuse.h -components/esp_rom/include/esp32/rom/ets_sys.h -components/esp_rom/include/esp32/rom/gpio.h -components/esp_rom/include/esp32/rom/libc_stubs.h -components/esp_rom/include/esp32/rom/lldesc.h -components/esp_rom/include/esp32/rom/md5_hash.h -components/esp_rom/include/esp32/rom/miniz.h -components/esp_rom/include/esp32/rom/rsa_pss.h -components/esp_rom/include/esp32/rom/rtc.h -components/esp_rom/include/esp32/rom/secure_boot.h -components/esp_rom/include/esp32/rom/sha.h -components/esp_rom/include/esp32/rom/spi_flash.h -components/esp_rom/include/esp32/rom/tbconsole.h -components/esp_rom/include/esp32/rom/tjpgd.h -components/esp_rom/include/esp32/rom/uart.h -components/esp_rom/include/esp32c3/rom/aes.h -components/esp_rom/include/esp32c3/rom/apb_backup_dma.h -components/esp_rom/include/esp32c3/rom/bigint.h -components/esp_rom/include/esp32c3/rom/cache.h -components/esp_rom/include/esp32c3/rom/crc.h -components/esp_rom/include/esp32c3/rom/digital_signature.h -components/esp_rom/include/esp32c3/rom/efuse.h -components/esp_rom/include/esp32c3/rom/esp_flash.h -components/esp_rom/include/esp32c3/rom/ets_sys.h -components/esp_rom/include/esp32c3/rom/gpio.h -components/esp_rom/include/esp32c3/rom/hmac.h -components/esp_rom/include/esp32c3/rom/libc_stubs.h -components/esp_rom/include/esp32c3/rom/lldesc.h -components/esp_rom/include/esp32c3/rom/md5_hash.h -components/esp_rom/include/esp32c3/rom/miniz.h -components/esp_rom/include/esp32c3/rom/rom_layout.h -components/esp_rom/include/esp32c3/rom/rsa_pss.h -components/esp_rom/include/esp32c3/rom/rtc.h -components/esp_rom/include/esp32c3/rom/secure_boot.h -components/esp_rom/include/esp32c3/rom/sha.h -components/esp_rom/include/esp32c3/rom/spi_flash.h -components/esp_rom/include/esp32c3/rom/tjpgd.h -components/esp_rom/include/esp32c3/rom/uart.h -components/esp_rom/include/esp32h2/rom/aes.h -components/esp_rom/include/esp32h2/rom/apb_backup_dma.h -components/esp_rom/include/esp32h2/rom/bigint.h -components/esp_rom/include/esp32h2/rom/cache.h -components/esp_rom/include/esp32h2/rom/crc.h -components/esp_rom/include/esp32h2/rom/digital_signature.h -components/esp_rom/include/esp32h2/rom/efuse.h -components/esp_rom/include/esp32h2/rom/esp_flash.h -components/esp_rom/include/esp32h2/rom/ets_sys.h -components/esp_rom/include/esp32h2/rom/gpio.h -components/esp_rom/include/esp32h2/rom/hmac.h -components/esp_rom/include/esp32h2/rom/libc_stubs.h -components/esp_rom/include/esp32h2/rom/lldesc.h -components/esp_rom/include/esp32h2/rom/md5_hash.h -components/esp_rom/include/esp32h2/rom/miniz.h -components/esp_rom/include/esp32h2/rom/rom_layout.h -components/esp_rom/include/esp32h2/rom/rsa_pss.h -components/esp_rom/include/esp32h2/rom/rtc.h -components/esp_rom/include/esp32h2/rom/secure_boot.h -components/esp_rom/include/esp32h2/rom/sha.h -components/esp_rom/include/esp32h2/rom/spi_flash.h -components/esp_rom/include/esp32h2/rom/tjpgd.h -components/esp_rom/include/esp32h2/rom/uart.h -components/esp_rom/include/esp32s2/rom/aes.h -components/esp_rom/include/esp32s2/rom/bigint.h -components/esp_rom/include/esp32s2/rom/cache.h -components/esp_rom/include/esp32s2/rom/crc.h -components/esp_rom/include/esp32s2/rom/digital_signature.h -components/esp_rom/include/esp32s2/rom/efuse.h -components/esp_rom/include/esp32s2/rom/ets_sys.h -components/esp_rom/include/esp32s2/rom/gpio.h -components/esp_rom/include/esp32s2/rom/hmac.h -components/esp_rom/include/esp32s2/rom/libc_stubs.h -components/esp_rom/include/esp32s2/rom/lldesc.h -components/esp_rom/include/esp32s2/rom/md5_hash.h -components/esp_rom/include/esp32s2/rom/miniz.h -components/esp_rom/include/esp32s2/rom/opi_flash.h -components/esp_rom/include/esp32s2/rom/rsa_pss.h -components/esp_rom/include/esp32s2/rom/rtc.h -components/esp_rom/include/esp32s2/rom/secure_boot.h -components/esp_rom/include/esp32s2/rom/sha.h -components/esp_rom/include/esp32s2/rom/spi_flash.h -components/esp_rom/include/esp32s2/rom/uart.h -components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h -components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h -components/esp_rom/include/esp32s2/rom/usb/cpio.h -components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h -components/esp_rom/include/esp32s2/rom/usb/usb_common.h -components/esp_rom/include/esp32s2/rom/usb/usb_dc.h -components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h -components/esp_rom/include/esp32s2/rom/usb/usb_device.h -components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h -components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h -components/esp_rom/include/esp32s2/rom/usb/usb_persist.h -components/esp_rom/include/esp32s3/rom/aes.h -components/esp_rom/include/esp32s3/rom/bigint.h -components/esp_rom/include/esp32s3/rom/cache.h -components/esp_rom/include/esp32s3/rom/crc.h -components/esp_rom/include/esp32s3/rom/digital_signature.h -components/esp_rom/include/esp32s3/rom/efuse.h -components/esp_rom/include/esp32s3/rom/ets_sys.h -components/esp_rom/include/esp32s3/rom/gpio.h -components/esp_rom/include/esp32s3/rom/hmac.h -components/esp_rom/include/esp32s3/rom/libc_stubs.h -components/esp_rom/include/esp32s3/rom/lldesc.h -components/esp_rom/include/esp32s3/rom/md5_hash.h -components/esp_rom/include/esp32s3/rom/miniz.h -components/esp_rom/include/esp32s3/rom/opi_flash.h -components/esp_rom/include/esp32s3/rom/rom_layout.h -components/esp_rom/include/esp32s3/rom/rsa_pss.h -components/esp_rom/include/esp32s3/rom/rtc.h -components/esp_rom/include/esp32s3/rom/secure_boot.h -components/esp_rom/include/esp32s3/rom/sha.h -components/esp_rom/include/esp32s3/rom/spi_flash.h -components/esp_rom/include/esp32s3/rom/tjpgd.h -components/esp_rom/include/esp32s3/rom/uart.h -components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h -components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h -components/esp_rom/include/esp32s3/rom/usb/cpio.h -components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h -components/esp_rom/include/esp32s3/rom/usb/usb_common.h -components/esp_rom/include/esp32s3/rom/usb/usb_dc.h -components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h -components/esp_rom/include/esp32s3/rom/usb/usb_device.h -components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h -components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h -components/esp_rom/include/esp32s3/rom/usb/usb_persist.h -components/esp_rom/include/esp_rom_crc.h -components/esp_rom/include/esp_rom_efuse.h -components/esp_rom/include/esp_rom_gpio.h -components/esp_rom/include/esp_rom_md5.h -components/esp_rom/include/esp_rom_sys.h -components/esp_rom/include/esp_rom_uart.h -components/esp_rom/include/linux/soc/reset_reasons.h -components/esp_rom/linux/esp_rom_crc.c -components/esp_rom/linux/esp_rom_efuse.c -components/esp_rom/linux/esp_rom_md5.c -components/esp_rom/linux/esp_rom_sys.c -components/esp_rom/patches/esp_rom_crc.c -components/esp_rom/patches/esp_rom_sys.c -components/esp_rom/patches/esp_rom_tjpgd.c -components/esp_rom/patches/esp_rom_uart.c -components/esp_rom/test/test_libgcc.c -components/esp_rom/test/test_miniz.c -components/esp_rom/test/test_tjpgd.c -components/esp_serial_slave_link/essl.c -components/esp_serial_slave_link/essl_internal.h -components/esp_serial_slave_link/essl_sdio.c -components/esp_serial_slave_link/essl_spi.c -components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h -components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h -components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h -components/esp_serial_slave_link/include/essl_spi/esp32c3_defs.h -components/esp_serial_slave_link/include/essl_spi/esp32h2_defs.h -components/esp_serial_slave_link/include/essl_spi/esp32s2_defs.h -components/esp_serial_slave_link/include/essl_spi/esp32s3_defs.h -components/esp_system/crosscore_int.c -components/esp_system/dbg_stubs.c -components/esp_system/eh_frame_parser.c -components/esp_system/esp_err.c -components/esp_system/esp_system.c -components/esp_system/fpga_overrides.c -components/esp_system/freertos_hooks.c -components/esp_system/include/eh_frame_parser.h -components/esp_system/include/esp_debug_helpers.h -components/esp_system/include/esp_expression_with_stack.h -components/esp_system/include/esp_freertos_hooks.h -components/esp_system/include/esp_int_wdt.h -components/esp_system/include/esp_private/crosscore_int.h -components/esp_system/include/esp_private/dbg_stubs.h -components/esp_system/include/esp_private/panic_internal.h -components/esp_system/include/esp_private/startup_internal.h -components/esp_system/include/esp_private/system_internal.h -components/esp_system/include/esp_private/usb_console.h -components/esp_system/include/esp_system.h -components/esp_system/include/esp_task.h -components/esp_system/include/esp_task_wdt.h -components/esp_system/int_wdt.c -components/esp_system/panic.c -components/esp_system/port/arch/riscv/expression_with_stack.c -components/esp_system/port/arch/riscv/panic_arch.c -components/esp_system/port/arch/xtensa/debug_helpers.c -components/esp_system/port/arch/xtensa/expression_with_stack.c -components/esp_system/port/arch/xtensa/panic_arch.c -components/esp_system/port/arch/xtensa/trax.c -components/esp_system/port/brownout.c -components/esp_system/port/cpu_start.c -components/esp_system/port/include/esp_clk_internal.h -components/esp_system/port/include/port/panic_funcs.h -components/esp_system/port/include/riscv/eh_frame_parser_impl.h -components/esp_system/port/panic_handler.c -components/esp_system/port/public_compat/brownout.h -components/esp_system/port/public_compat/cache_err_int.h -components/esp_system/port/public_compat/trax.h -components/esp_system/port/soc/esp32/cache_err_int.c -components/esp_system/port/soc/esp32/cache_err_int.h -components/esp_system/port/soc/esp32/clk.c -components/esp_system/port/soc/esp32/intr.c -components/esp_system/port/soc/esp32/reset_reason.c -components/esp_system/port/soc/esp32/system_internal.c -components/esp_system/port/soc/esp32c3/apb_backup_dma.c -components/esp_system/port/soc/esp32c3/cache_err_int.c -components/esp_system/port/soc/esp32c3/cache_err_int.h -components/esp_system/port/soc/esp32c3/clk.c -components/esp_system/port/soc/esp32c3/reset_reason.c -components/esp_system/port/soc/esp32c3/system_internal.c -components/esp_system/port/soc/esp32h2/apb_backup_dma.c -components/esp_system/port/soc/esp32h2/cache_err_int.c -components/esp_system/port/soc/esp32h2/cache_err_int.h -components/esp_system/port/soc/esp32h2/clk.c -components/esp_system/port/soc/esp32h2/reset_reason.c -components/esp_system/port/soc/esp32h2/system_internal.c -components/esp_system/port/soc/esp32s2/cache_err_int.c -components/esp_system/port/soc/esp32s2/cache_err_int.h -components/esp_system/port/soc/esp32s2/clk.c -components/esp_system/port/soc/esp32s2/reset_reason.c -components/esp_system/port/soc/esp32s2/system_internal.c -components/esp_system/port/soc/esp32s2/usb_console.c -components/esp_system/port/soc/esp32s3/cache_err_int.c -components/esp_system/port/soc/esp32s3/cache_err_int.h -components/esp_system/port/soc/esp32s3/clk.c -components/esp_system/port/soc/esp32s3/reset_reason.c -components/esp_system/port/soc/esp32s3/system_internal.c -components/esp_system/port/soc/esp32s3/usb_console.c -components/esp_system/stack_check.c -components/esp_system/startup.c -components/esp_system/system_time.c -components/esp_system/task_wdt.c -components/esp_system/test/test_delay.c -components/esp_system/test/test_reset_reason.c -components/esp_system/test/test_sleep.c -components/esp_system/test/test_stack_check.c -components/esp_system/test/test_system_time.c -components/esp_system/test_eh_frame_parser/eh_frame_parser_impl.h -components/esp_system/test_eh_frame_parser/esp_private/panic_internal.h -components/esp_system/test_eh_frame_parser/linker.ld -components/esp_system/test_eh_frame_parser/main.c -components/esp_system/ubsan.c -components/esp_timer/include/esp_private/esp_timer_private.h -components/esp_timer/include/esp_timer.h -components/esp_timer/private_include/esp_timer_impl.h -components/esp_timer/src/esp_timer.c -components/esp_timer/src/esp_timer_impl_frc_legacy.c -components/esp_timer/src/esp_timer_impl_lac.c -components/esp_timer/src/esp_timer_impl_systimer.c -components/esp_timer/src/ets_timer_legacy.c -components/esp_timer/src/system_time.c -components/esp_timer/test/test_esp_timer.c -components/esp_timer/test/test_esp_timer_light_sleep.c -components/esp_timer/test/test_ets_timer.c -components/esp_websocket_client/esp_websocket_client.c -components/esp_websocket_client/include/esp_websocket_client.h -components/esp_websocket_client/test/test_websocket_client.c -components/esp_wifi/esp32/esp_adapter.c -components/esp_wifi/esp32c3/esp_adapter.c -components/esp_wifi/esp32s2/esp_adapter.c -components/esp_wifi/esp32s3/esp_adapter.c -components/esp_wifi/include/esp_coexist.h -components/esp_wifi/include/esp_coexist_adapter.h -components/esp_wifi/include/esp_coexist_internal.h -components/esp_wifi/include/esp_mesh.h -components/esp_wifi/include/esp_mesh_internal.h -components/esp_wifi/include/esp_now.h -components/esp_wifi/include/esp_private/esp_wifi_private.h -components/esp_wifi/include/esp_private/esp_wifi_types_private.h -components/esp_wifi/include/esp_private/wifi.h -components/esp_wifi/include/esp_private/wifi_os_adapter.h -components/esp_wifi/include/esp_private/wifi_types.h -components/esp_wifi/include/esp_smartconfig.h -components/esp_wifi/include/esp_wifi.h -components/esp_wifi/include/esp_wifi_crypto_types.h -components/esp_wifi/include/esp_wifi_default.h -components/esp_wifi/include/esp_wifi_netif.h -components/esp_wifi/include/esp_wifi_types.h -components/esp_wifi/include/smartconfig_ack.h -components/esp_wifi/src/coexist.c -components/esp_wifi/src/lib_printf.c -components/esp_wifi/src/mesh_event.c -components/esp_wifi/src/smartconfig.c -components/esp_wifi/src/smartconfig_ack.c -components/esp_wifi/src/wifi_default.c -components/esp_wifi/src/wifi_init.c -components/esp_wifi/src/wifi_netif.c -components/esp_wifi/test/test_wifi.c -components/esp_wifi/test/test_wifi_init.c -components/espcoredump/corefile/__init__.py -components/espcoredump/corefile/_parse_soc_header.py -components/espcoredump/corefile/elf.py -components/espcoredump/corefile/gdb.py -components/espcoredump/corefile/loader.py -components/espcoredump/corefile/riscv.py -components/espcoredump/corefile/soc_headers/esp32.py -components/espcoredump/corefile/soc_headers/esp32c3.py -components/espcoredump/corefile/soc_headers/esp32s2.py -components/espcoredump/corefile/soc_headers/esp32s3.py -components/espcoredump/corefile/xtensa.py -components/espcoredump/espcoredump.py -components/espcoredump/include/esp_core_dump.h -components/espcoredump/include/port/riscv/esp_core_dump_summary_port.h -components/espcoredump/include/port/xtensa/esp_core_dump_summary_port.h -components/espcoredump/include_core_dump/core_dump_binary.h -components/espcoredump/include_core_dump/core_dump_checksum.h -components/espcoredump/include_core_dump/core_dump_elf.h -components/espcoredump/include_core_dump/elf.h -components/espcoredump/include_core_dump/esp_core_dump_common.h -components/espcoredump/include_core_dump/esp_core_dump_port.h -components/espcoredump/include_core_dump/esp_core_dump_types.h -components/espcoredump/include_core_dump/port/riscv/esp_core_dump_port_impl.h -components/espcoredump/include_core_dump/port/xtensa/esp_core_dump_port_impl.h -components/espcoredump/src/core_dump_binary.c -components/espcoredump/src/core_dump_checksum.c -components/espcoredump/src/core_dump_common.c -components/espcoredump/src/core_dump_elf.c -components/espcoredump/src/core_dump_flash.c -components/espcoredump/src/core_dump_uart.c -components/espcoredump/src/port/riscv/core_dump_port.c -components/espcoredump/test/test_espcoredump.py -components/espcoredump/test_apps/main/test_core_dump.c -components/expat/port/include/expat_config.h -components/expat/test/test_expat.c -components/fatfs/diskio/diskio.c -components/fatfs/diskio/diskio_impl.h -components/fatfs/diskio/diskio_rawflash.c -components/fatfs/diskio/diskio_rawflash.h -components/fatfs/diskio/diskio_sdmmc.c -components/fatfs/diskio/diskio_sdmmc.h -components/fatfs/diskio/diskio_wl.c -components/fatfs/diskio/diskio_wl.h -components/fatfs/port/freertos/ffsystem.c -components/fatfs/port/linux/ffsystem.c -components/fatfs/src/diskio.c -components/fatfs/src/diskio.h -components/fatfs/src/ff.c -components/fatfs/src/ff.h -components/fatfs/src/ffconf.h -components/fatfs/src/ffsystem.c -components/fatfs/src/ffunicode.c -components/fatfs/test/test_fatfs_common.c -components/fatfs/test/test_fatfs_common.h -components/fatfs/test/test_fatfs_rawflash.c -components/fatfs/test/test_fatfs_sdmmc.c -components/fatfs/test/test_fatfs_spiflash.c -components/fatfs/test_fatfs_host/main.cpp -components/fatfs/test_fatfs_host/sdkconfig/sdkconfig.h -components/fatfs/test_fatfs_host/test_fatfs.cpp -components/fatfs/vfs/esp_vfs_fat.h -components/fatfs/vfs/vfs_fat.c -components/fatfs/vfs/vfs_fat_internal.h -components/fatfs/vfs/vfs_fat_sdmmc.c -components/fatfs/vfs/vfs_fat_spiflash.c -components/freemodbus/common/esp_modbus_callbacks.h -components/freemodbus/common/esp_modbus_master.c -components/freemodbus/common/esp_modbus_master_serial.c -components/freemodbus/common/esp_modbus_master_tcp.c -components/freemodbus/common/esp_modbus_slave.c -components/freemodbus/common/esp_modbus_slave_serial.c -components/freemodbus/common/esp_modbus_slave_tcp.c -components/freemodbus/common/include/esp_modbus_common.h -components/freemodbus/common/include/esp_modbus_master.h -components/freemodbus/common/include/esp_modbus_slave.h -components/freemodbus/common/include/mbcontroller.h -components/freemodbus/common/mbc_master.h -components/freemodbus/common/mbc_slave.h -components/freemodbus/modbus/ascii/mbascii.c -components/freemodbus/modbus/ascii/mbascii.h -components/freemodbus/modbus/ascii/mbascii_m.c -components/freemodbus/modbus/functions/mbfunccoils.c -components/freemodbus/modbus/functions/mbfunccoils_m.c -components/freemodbus/modbus/functions/mbfuncdiag.c -components/freemodbus/modbus/functions/mbfuncdisc.c -components/freemodbus/modbus/functions/mbfuncdisc_m.c -components/freemodbus/modbus/functions/mbfuncholding.c -components/freemodbus/modbus/functions/mbfuncholding_m.c -components/freemodbus/modbus/functions/mbfuncinput.c -components/freemodbus/modbus/functions/mbfuncinput_m.c -components/freemodbus/modbus/functions/mbfuncother.c -components/freemodbus/modbus/functions/mbutils.c -components/freemodbus/modbus/include/mb.h -components/freemodbus/modbus/include/mb_m.h -components/freemodbus/modbus/include/mbconfig.h -components/freemodbus/modbus/include/mbframe.h -components/freemodbus/modbus/include/mbfunc.h -components/freemodbus/modbus/include/mbport.h -components/freemodbus/modbus/include/mbproto.h -components/freemodbus/modbus/include/mbutils.h -components/freemodbus/modbus/mb.c -components/freemodbus/modbus/mb_m.c -components/freemodbus/modbus/rtu/mbcrc.c -components/freemodbus/modbus/rtu/mbcrc.h -components/freemodbus/modbus/rtu/mbrtu.c -components/freemodbus/modbus/rtu/mbrtu.h -components/freemodbus/modbus/rtu/mbrtu_m.c -components/freemodbus/modbus/tcp/mbtcp.c -components/freemodbus/modbus/tcp/mbtcp.h -components/freemodbus/modbus/tcp/mbtcp_m.c -components/freemodbus/modbus/tcp/mbtcp_m.h -components/freemodbus/port/port.c -components/freemodbus/port/port.h -components/freemodbus/port/portevent.c -components/freemodbus/port/portevent_m.c -components/freemodbus/port/portother.c -components/freemodbus/port/portother_m.c -components/freemodbus/port/portserial.c -components/freemodbus/port/portserial_m.c -components/freemodbus/port/porttimer.c -components/freemodbus/port/porttimer_m.c -components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c -components/freemodbus/serial_master/modbus_controller/mbc_serial_master.h -components/freemodbus/serial_master/port/port_serial_master.h -components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.c -components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.h -components/freemodbus/serial_slave/port/port_serial_slave.h -components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c -components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.h -components/freemodbus/tcp_master/port/port_tcp_master.c -components/freemodbus/tcp_master/port/port_tcp_master.h -components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.c -components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.h -components/freemodbus/tcp_slave/port/port_tcp_slave.c -components/freemodbus/tcp_slave/port/port_tcp_slave.h -components/freertos/FreeRTOS-openocd.c -components/freertos/croutine.c -components/freertos/esp_additions/task_snapshot.c -components/freertos/event_groups.c -components/freertos/freertos_v8_compat.c -components/freertos/include/esp_additions/freertos/FreeRTOSConfig.h -components/freertos/include/esp_additions/freertos/task_snapshot.h -components/freertos/include/esp_additions/freertos_tasks_c_additions.h -components/freertos/include/freertos/FreeRTOS.h -components/freertos/include/freertos/StackMacros.h -components/freertos/include/freertos/atomic.h -components/freertos/include/freertos/croutine.h -components/freertos/include/freertos/deprecated_definitions.h -components/freertos/include/freertos/event_groups.h -components/freertos/include/freertos/list.h -components/freertos/include/freertos/message_buffer.h -components/freertos/include/freertos/mpu_prototypes.h -components/freertos/include/freertos/mpu_wrappers.h -components/freertos/include/freertos/portable.h -components/freertos/include/freertos/projdefs.h -components/freertos/include/freertos/queue.h -components/freertos/include/freertos/semphr.h -components/freertos/include/freertos/stack_macros.h -components/freertos/include/freertos/stream_buffer.h -components/freertos/include/freertos/task.h -components/freertos/include/freertos/timers.h -components/freertos/list.c -components/freertos/port/linux/include/freertos/FreeRTOSConfig_arch.h -components/freertos/port/linux/include/freertos/portmacro.h -components/freertos/port/riscv/include/freertos/FreeRTOSConfig_arch.h -components/freertos/port/riscv/include/freertos/portbenchmark.h -components/freertos/port/riscv/include/freertos/portmacro.h -components/freertos/port/riscv/port.c -components/freertos/port/xtensa/include/freertos/FreeRTOSConfig_arch.h -components/freertos/port/xtensa/include/freertos/portbenchmark.h -components/freertos/port/xtensa/include/freertos/portmacro.h -components/freertos/port/xtensa/include/freertos/portmacro_priv.h -components/freertos/port/xtensa/include/freertos/xtensa_api.h -components/freertos/port/xtensa/include/freertos/xtensa_config.h -components/freertos/port/xtensa/include/freertos/xtensa_context.h -components/freertos/port/xtensa/include/freertos/xtensa_rtos.h -components/freertos/port/xtensa/include/freertos/xtensa_timer.h -components/freertos/port/xtensa/port.c -components/freertos/port/xtensa/xt_asm_utils.h -components/freertos/port/xtensa/xtensa_init.c -components/freertos/port/xtensa/xtensa_overlay_os_hook.c -components/freertos/queue.c -components/freertos/stream_buffer.c -components/freertos/tasks.c -components/freertos/test/test_context_save_clobber.c -components/freertos/test/test_float_in_isr.c -components/freertos/test/test_freertos_backported_functions.c -components/freertos/test/test_freertos_debug_functions.c -components/freertos/test/test_freertos_eventgroups.c -components/freertos/test/test_freertos_get_state.c -components/freertos/test/test_freertos_isinisrcontext.c -components/freertos/test/test_freertos_mutex.c -components/freertos/test/test_freertos_scheduling_time.c -components/freertos/test/test_freertos_task_delay_until.c -components/freertos/test/test_freertos_task_delete.c -components/freertos/test/test_freertos_task_notify.c -components/freertos/test/test_freertos_trace_utilities.c -components/freertos/test/test_isr_latency.c -components/freertos/test/test_legacy_hooks.c -components/freertos/test/test_newlib_reent.c -components/freertos/test/test_panic.c -components/freertos/test/test_preemption.c -components/freertos/test/test_queuesets.c -components/freertos/test/test_spinlocks.c -components/freertos/test/test_stream_buffers.c -components/freertos/test/test_suspend_scheduler.c -components/freertos/test/test_task_priorities.c -components/freertos/test/test_task_suspend_resume.c -components/freertos/test/test_tasks_snapshot.c -components/freertos/test/test_thread_local.c -components/freertos/test/test_timers.c -components/freertos/test/test_xtensa_loadstore_handler.c -components/freertos/timers.c -components/hal/adc_hal.c -components/hal/aes_hal.c -components/hal/cpu_hal.c -components/hal/dac_hal.c -components/hal/ds_hal.c -components/hal/emac_hal.c -components/hal/esp32/adc_hal.c -components/hal/esp32/brownout_hal.c -components/hal/esp32/gpio_hal_workaround.c -components/hal/esp32/include/hal/adc_hal.h -components/hal/esp32/include/hal/adc_hal_conf.h -components/hal/esp32/include/hal/adc_ll.h -components/hal/esp32/include/hal/aes_ll.h -components/hal/esp32/include/hal/can_hal.h -components/hal/esp32/include/hal/can_ll.h -components/hal/esp32/include/hal/can_types.h -components/hal/esp32/include/hal/clk_gate_ll.h -components/hal/esp32/include/hal/cpu_ll.h -components/hal/esp32/include/hal/dac_ll.h -components/hal/esp32/include/hal/emac_ll.h -components/hal/esp32/include/hal/gpio_ll.h -components/hal/esp32/include/hal/i2c_ll.h -components/hal/esp32/include/hal/i2s_ll.h -components/hal/esp32/include/hal/interrupt_controller_ll.h -components/hal/esp32/include/hal/ledc_ll.h -components/hal/esp32/include/hal/mcpwm_ll.h -components/hal/esp32/include/hal/mpu_ll.h -components/hal/esp32/include/hal/mwdt_ll.h -components/hal/esp32/include/hal/pcnt_ll.h -components/hal/esp32/include/hal/rmt_ll.h -components/hal/esp32/include/hal/rtc_cntl_ll.h -components/hal/esp32/include/hal/rtc_io_ll.h -components/hal/esp32/include/hal/rwdt_ll.h -components/hal/esp32/include/hal/sha_ll.h -components/hal/esp32/include/hal/sigmadelta_ll.h -components/hal/esp32/include/hal/soc_ll.h -components/hal/esp32/include/hal/spi_flash_encrypted_ll.h -components/hal/esp32/include/hal/spi_flash_ll.h -components/hal/esp32/include/hal/spi_ll.h -components/hal/esp32/include/hal/timer_ll.h -components/hal/esp32/include/hal/touch_sensor_hal.h -components/hal/esp32/include/hal/touch_sensor_ll.h -components/hal/esp32/include/hal/trace_ll.h -components/hal/esp32/include/hal/twai_ll.h -components/hal/esp32/include/hal/uart_ll.h -components/hal/esp32/interrupt_descriptor_table.c -components/hal/esp32/touch_sensor_hal.c -components/hal/esp32c3/adc_hal.c -components/hal/esp32c3/brownout_hal.c -components/hal/esp32c3/hmac_hal.c -components/hal/esp32c3/include/hal/adc_hal.h -components/hal/esp32c3/include/hal/adc_hal_conf.h -components/hal/esp32c3/include/hal/adc_ll.h -components/hal/esp32c3/include/hal/aes_ll.h -components/hal/esp32c3/include/hal/clk_gate_ll.h -components/hal/esp32c3/include/hal/cpu_ll.h -components/hal/esp32c3/include/hal/ds_ll.h -components/hal/esp32c3/include/hal/gdma_ll.h -components/hal/esp32c3/include/hal/gpio_ll.h -components/hal/esp32c3/include/hal/gpspi_flash_ll.h -components/hal/esp32c3/include/hal/hmac_hal.h -components/hal/esp32c3/include/hal/hmac_ll.h -components/hal/esp32c3/include/hal/i2c_ll.h -components/hal/esp32c3/include/hal/i2s_ll.h -components/hal/esp32c3/include/hal/interrupt_controller_ll.h -components/hal/esp32c3/include/hal/ledc_ll.h -components/hal/esp32c3/include/hal/memprot_ll.h -components/hal/esp32c3/include/hal/mpu_ll.h -components/hal/esp32c3/include/hal/mwdt_ll.h -components/hal/esp32c3/include/hal/rtc_cntl_ll.h -components/hal/esp32c3/include/hal/rwdt_ll.h -components/hal/esp32c3/include/hal/sha_ll.h -components/hal/esp32c3/include/hal/sigmadelta_ll.h -components/hal/esp32c3/include/hal/soc_ll.h -components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h -components/hal/esp32c3/include/hal/spi_flash_ll.h -components/hal/esp32c3/include/hal/spi_ll.h -components/hal/esp32c3/include/hal/spimem_flash_ll.h -components/hal/esp32c3/include/hal/systimer_ll.h -components/hal/esp32c3/include/hal/timer_ll.h -components/hal/esp32c3/include/hal/twai_ll.h -components/hal/esp32c3/include/hal/uart_ll.h -components/hal/esp32c3/include/hal/uhci_ll.h -components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h -components/hal/esp32c3/rtc_cntl_hal.c -components/hal/esp32h2/adc_hal.c -components/hal/esp32h2/brownout_hal.c -components/hal/esp32h2/hmac_hal.c -components/hal/esp32h2/include/hal/adc_hal.h -components/hal/esp32h2/include/hal/adc_hal_conf.h -components/hal/esp32h2/include/hal/adc_ll.h -components/hal/esp32h2/include/hal/aes_ll.h -components/hal/esp32h2/include/hal/clk_gate_ll.h -components/hal/esp32h2/include/hal/cpu_ll.h -components/hal/esp32h2/include/hal/ds_ll.h -components/hal/esp32h2/include/hal/gdma_ll.h -components/hal/esp32h2/include/hal/gpio_ll.h -components/hal/esp32h2/include/hal/gpspi_flash_ll.h -components/hal/esp32h2/include/hal/hmac_hal.h -components/hal/esp32h2/include/hal/hmac_ll.h -components/hal/esp32h2/include/hal/i2c_ll.h -components/hal/esp32h2/include/hal/i2s_ll.h -components/hal/esp32h2/include/hal/interrupt_controller_ll.h -components/hal/esp32h2/include/hal/ledc_ll.h -components/hal/esp32h2/include/hal/memprot_ll.h -components/hal/esp32h2/include/hal/mpu_ll.h -components/hal/esp32h2/include/hal/mwdt_ll.h -components/hal/esp32h2/include/hal/rtc_cntl_ll.h -components/hal/esp32h2/include/hal/rwdt_ll.h -components/hal/esp32h2/include/hal/sha_ll.h -components/hal/esp32h2/include/hal/sigmadelta_ll.h -components/hal/esp32h2/include/hal/soc_ll.h -components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h -components/hal/esp32h2/include/hal/spi_flash_ll.h -components/hal/esp32h2/include/hal/spi_ll.h -components/hal/esp32h2/include/hal/spimem_flash_ll.h -components/hal/esp32h2/include/hal/systimer_ll.h -components/hal/esp32h2/include/hal/timer_ll.h -components/hal/esp32h2/include/hal/twai_ll.h -components/hal/esp32h2/include/hal/uart_ll.h -components/hal/esp32h2/include/hal/uhci_ll.h -components/hal/esp32h2/include/hal/uhci_types.h -components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h -components/hal/esp32h2/rtc_cntl_hal.c -components/hal/esp32s2/adc_hal.c -components/hal/esp32s2/brownout_hal.c -components/hal/esp32s2/cp_dma_hal.c -components/hal/esp32s2/dac_hal.c -components/hal/esp32s2/include/hal/adc_hal.h -components/hal/esp32s2/include/hal/adc_hal_conf.h -components/hal/esp32s2/include/hal/adc_ll.h -components/hal/esp32s2/include/hal/aes_ll.h -components/hal/esp32s2/include/hal/clk_gate_ll.h -components/hal/esp32s2/include/hal/cp_dma_hal.h -components/hal/esp32s2/include/hal/cp_dma_ll.h -components/hal/esp32s2/include/hal/cpu_ll.h -components/hal/esp32s2/include/hal/crypto_dma_ll.h -components/hal/esp32s2/include/hal/dac_hal.h -components/hal/esp32s2/include/hal/dac_ll.h -components/hal/esp32s2/include/hal/dedic_gpio_ll.h -components/hal/esp32s2/include/hal/gpio_ll.h -components/hal/esp32s2/include/hal/gpspi_flash_ll.h -components/hal/esp32s2/include/hal/i2c_ll.h -components/hal/esp32s2/include/hal/i2s_ll.h -components/hal/esp32s2/include/hal/interrupt_controller_ll.h -components/hal/esp32s2/include/hal/ledc_ll.h -components/hal/esp32s2/include/hal/memprot_ll.h -components/hal/esp32s2/include/hal/memprot_peri_ll.h -components/hal/esp32s2/include/hal/mpu_ll.h -components/hal/esp32s2/include/hal/mwdt_ll.h -components/hal/esp32s2/include/hal/pcnt_ll.h -components/hal/esp32s2/include/hal/rtc_cntl_ll.h -components/hal/esp32s2/include/hal/rtc_io_ll.h -components/hal/esp32s2/include/hal/rwdt_ll.h -components/hal/esp32s2/include/hal/sha_ll.h -components/hal/esp32s2/include/hal/sigmadelta_ll.h -components/hal/esp32s2/include/hal/soc_ll.h -components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h -components/hal/esp32s2/include/hal/spi_flash_ll.h -components/hal/esp32s2/include/hal/spi_ll.h -components/hal/esp32s2/include/hal/spimem_flash_ll.h -components/hal/esp32s2/include/hal/systimer_ll.h -components/hal/esp32s2/include/hal/timer_ll.h -components/hal/esp32s2/include/hal/touch_sensor_hal.h -components/hal/esp32s2/include/hal/touch_sensor_ll.h -components/hal/esp32s2/include/hal/trace_ll.h -components/hal/esp32s2/include/hal/twai_ll.h -components/hal/esp32s2/include/hal/uart_ll.h -components/hal/esp32s2/include/hal/usb_ll.h -components/hal/esp32s2/interrupt_descriptor_table.c -components/hal/esp32s2/touch_sensor_hal.c -components/hal/esp32s3/brownout_hal.c -components/hal/esp32s3/include/hal/adc_hal_conf.h -components/hal/esp32s3/include/hal/adc_ll.h -components/hal/esp32s3/include/hal/aes_ll.h -components/hal/esp32s3/include/hal/cpu_ll.h -components/hal/esp32s3/include/hal/gdma_ll.h -components/hal/esp32s3/include/hal/gpio_ll.h -components/hal/esp32s3/include/hal/gpspi_flash_ll.h -components/hal/esp32s3/include/hal/i2c_ll.h -components/hal/esp32s3/include/hal/i2s_ll.h -components/hal/esp32s3/include/hal/interrupt_controller_ll.h -components/hal/esp32s3/include/hal/lcd_ll.h -components/hal/esp32s3/include/hal/ledc_ll.h -components/hal/esp32s3/include/hal/mcpwm_ll.h -components/hal/esp32s3/include/hal/memprot_ll.h -components/hal/esp32s3/include/hal/mpu_ll.h -components/hal/esp32s3/include/hal/mwdt_ll.h -components/hal/esp32s3/include/hal/pcnt_ll.h -components/hal/esp32s3/include/hal/rtc_cntl_ll.h -components/hal/esp32s3/include/hal/rtc_io_ll.h -components/hal/esp32s3/include/hal/rwdt_ll.h -components/hal/esp32s3/include/hal/sha_ll.h -components/hal/esp32s3/include/hal/sigmadelta_ll.h -components/hal/esp32s3/include/hal/soc_ll.h -components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h -components/hal/esp32s3/include/hal/spi_flash_ll.h -components/hal/esp32s3/include/hal/spi_ll.h -components/hal/esp32s3/include/hal/spimem_flash_ll.h -components/hal/esp32s3/include/hal/systimer_ll.h -components/hal/esp32s3/include/hal/timer_ll.h -components/hal/esp32s3/include/hal/touch_sensor_hal.h -components/hal/esp32s3/include/hal/touch_sensor_ll.h -components/hal/esp32s3/include/hal/trace_ll.h -components/hal/esp32s3/include/hal/twai_ll.h -components/hal/esp32s3/include/hal/uart_ll.h -components/hal/esp32s3/include/hal/uhci_ll.h -components/hal/esp32s3/include/hal/usb_ll.h -components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h -components/hal/esp32s3/interrupt_descriptor_table.c -components/hal/esp32s3/touch_sensor_hal.c -components/hal/gdma_hal.c -components/hal/gpio_hal.c -components/hal/i2c_hal.c -components/hal/i2c_hal_iram.c -components/hal/i2s_hal.c -components/hal/include/hal/adc_hal.h -components/hal/include/hal/adc_types.h -components/hal/include/hal/aes_hal.h -components/hal/include/hal/aes_types.h -components/hal/include/hal/brownout_hal.h -components/hal/include/hal/cpu_hal.h -components/hal/include/hal/cpu_types.h -components/hal/include/hal/dac_hal.h -components/hal/include/hal/dac_types.h -components/hal/include/hal/dma_types.h -components/hal/include/hal/ds_hal.h -components/hal/include/hal/emac_hal.h -components/hal/include/hal/esp_flash_err.h -components/hal/include/hal/eth_types.h -components/hal/include/hal/gdma_hal.h -components/hal/include/hal/gpio_hal.h -components/hal/include/hal/gpio_types.h -components/hal/include/hal/i2c_hal.h -components/hal/include/hal/i2c_types.h -components/hal/include/hal/i2s_hal.h -components/hal/include/hal/i2s_types.h -components/hal/include/hal/interrupt_controller_hal.h -components/hal/include/hal/interrupt_controller_types.h -components/hal/include/hal/lcd_hal.h -components/hal/include/hal/lcd_types.h -components/hal/include/hal/ledc_hal.h -components/hal/include/hal/ledc_types.h -components/hal/include/hal/mcpwm_hal.h -components/hal/include/hal/mcpwm_types.h -components/hal/include/hal/memprot_types.h -components/hal/include/hal/mpu_hal.h -components/hal/include/hal/mpu_types.h -components/hal/include/hal/pcnt_hal.h -components/hal/include/hal/pcnt_types.h -components/hal/include/hal/rmt_hal.h -components/hal/include/hal/rmt_types.h -components/hal/include/hal/rtc_hal.h -components/hal/include/hal/rtc_io_hal.h -components/hal/include/hal/rtc_io_types.h -components/hal/include/hal/sdio_slave_hal.h -components/hal/include/hal/sdio_slave_ll.h -components/hal/include/hal/sdio_slave_types.h -components/hal/include/hal/sha_hal.h -components/hal/include/hal/sha_types.h -components/hal/include/hal/sigmadelta_hal.h -components/hal/include/hal/sigmadelta_types.h -components/hal/include/hal/soc_hal.h -components/hal/include/hal/spi_flash_encrypt_hal.h -components/hal/include/hal/spi_flash_hal.h -components/hal/include/hal/spi_flash_types.h -components/hal/include/hal/spi_hal.h -components/hal/include/hal/spi_slave_hal.h -components/hal/include/hal/spi_slave_hd_hal.h -components/hal/include/hal/spi_types.h -components/hal/include/hal/systimer_hal.h -components/hal/include/hal/systimer_types.h -components/hal/include/hal/timer_hal.h -components/hal/include/hal/timer_types.h -components/hal/include/hal/touch_sensor_hal.h -components/hal/include/hal/touch_sensor_types.h -components/hal/include/hal/twai_hal.h -components/hal/include/hal/twai_types.h -components/hal/include/hal/uart_hal.h -components/hal/include/hal/uart_types.h -components/hal/include/hal/uhci_types.h -components/hal/include/hal/usb_hal.h -components/hal/include/hal/usb_types_private.h -components/hal/include/hal/usbh_hal.h -components/hal/include/hal/usbh_ll.h -components/hal/include/hal/wdt_hal.h -components/hal/include/hal/wdt_types.h -components/hal/interrupt_controller_hal.c -components/hal/lcd_hal.c -components/hal/ledc_hal.c -components/hal/ledc_hal_iram.c -components/hal/mcpwm_hal.c -components/hal/mpu_hal.c -components/hal/pcnt_hal.c -components/hal/platform_port/include/hal/assert.h -components/hal/platform_port/include/hal/check.h -components/hal/platform_port/include/hal/log.h -components/hal/platform_port/include/hal/misc.h -components/hal/rmt_hal.c -components/hal/rtc_io_hal.c -components/hal/sdio_slave_hal.c -components/hal/sha_hal.c -components/hal/sigmadelta_hal.c -components/hal/soc_hal.c -components/hal/spi_flash_encrypt_hal_iram.c -components/hal/spi_flash_hal.c -components/hal/spi_flash_hal_gpspi.c -components/hal/spi_flash_hal_iram.c -components/hal/spi_hal.c -components/hal/spi_hal_iram.c -components/hal/spi_slave_hal.c -components/hal/spi_slave_hal_iram.c -components/hal/spi_slave_hd_hal.c -components/hal/systimer_hal.c -components/hal/test/test_mpu.c -components/hal/timer_hal.c -components/hal/touch_sensor_hal.c -components/hal/twai_hal.c -components/hal/twai_hal_iram.c -components/hal/uart_hal.c -components/hal/uart_hal_iram.c -components/hal/usb_hal.c -components/hal/usbh_hal.c -components/hal/wdt_hal_iram.c -components/heap/heap_caps.c -components/heap/heap_caps_init.c -components/heap/heap_private.h -components/heap/heap_task_info.c -components/heap/heap_tlsf.c -components/heap/heap_tlsf.h -components/heap/heap_tlsf_block_functions.h -components/heap/heap_tlsf_config.h -components/heap/heap_trace_standalone.c -components/heap/include/esp_heap_caps.h -components/heap/include/esp_heap_caps_init.h -components/heap/include/esp_heap_task_info.h -components/heap/include/esp_heap_trace.h -components/heap/include/heap_memory_layout.h -components/heap/include/multi_heap.h -components/heap/include/soc/soc_memory_layout.h -components/heap/multi_heap.c -components/heap/multi_heap_config.h -components/heap/multi_heap_internal.h -components/heap/multi_heap_platform.h -components/heap/multi_heap_poisoning.c -components/heap/port/esp32/memory_layout.c -components/heap/port/esp32c3/memory_layout.c -components/heap/port/esp32h2/memory_layout.c -components/heap/port/esp32s2/memory_layout.c -components/heap/port/esp32s3/memory_layout.c -components/heap/port/memory_layout_utils.c -components/heap/test/test_aligned_alloc_caps.c -components/heap/test/test_allocator_timings.c -components/heap/test/test_diram.c -components/heap/test/test_heap_trace.c -components/heap/test/test_leak.c -components/heap/test/test_malloc.c -components/heap/test/test_malloc_caps.c -components/heap/test/test_realloc.c -components/heap/test/test_runtime_heap_reg.c -components/heap/test_multi_heap_host/main.cpp -components/heap/test_multi_heap_host/test_multi_heap.cpp -components/idf_test/include/esp32/idf_performance_target.h -components/idf_test/include/esp32c3/idf_performance_target.h -components/idf_test/include/esp32h2/idf_performance_target.h -components/idf_test/include/esp32s2/idf_performance_target.h -components/idf_test/include/esp32s3/idf_performance_target.h -components/idf_test/include/idf_performance.h -components/ieee802154/include/esp_ieee802154.h -components/ieee802154/include/esp_ieee802154_types.h -components/jsmn/include/jsmn.h -components/jsmn/src/jsmn.c -components/linux/include/sys/queue.h -components/log/esp_log_private.h -components/log/host_test/log_test/main/log_test.cpp -components/log/log_linux.c -components/lwip/apps/dhcpserver/dhcpserver.c -components/lwip/apps/ping/esp_ping.c -components/lwip/apps/ping/ping.c -components/lwip/apps/ping/ping_sock.c -components/lwip/apps/sntp/sntp.c -components/lwip/include/apps/dhcpserver/dhcpserver.h -components/lwip/include/apps/dhcpserver/dhcpserver_options.h -components/lwip/include/apps/esp_ping.h -components/lwip/include/apps/esp_sntp.h -components/lwip/include/apps/ping/ping.h -components/lwip/include/apps/ping/ping_sock.h -components/lwip/include/apps/sntp/sntp.h -components/lwip/port/esp32/debug/lwip_debug.c -components/lwip/port/esp32/freertos/sys_arch.c -components/lwip/port/esp32/hooks/lwip_default_hooks.c -components/lwip/port/esp32/hooks/tcp_isn_default.c -components/lwip/port/esp32/include/arch/cc.h -components/lwip/port/esp32/include/arch/perf.h -components/lwip/port/esp32/include/arch/sys_arch.h -components/lwip/port/esp32/include/arch/vfs_lwip.h -components/lwip/port/esp32/include/arpa/inet.h -components/lwip/port/esp32/include/debug/lwip_debug.h -components/lwip/port/esp32/include/lwip_default_hooks.h -components/lwip/port/esp32/include/lwipopts.h -components/lwip/port/esp32/include/netdb.h -components/lwip/port/esp32/include/netif/dhcp_state.h -components/lwip/port/esp32/include/netif/ethernetif.h -components/lwip/port/esp32/include/netif/openthreadif.h -components/lwip/port/esp32/include/netif/wlanif.h -components/lwip/port/esp32/include/netinet/in.h -components/lwip/port/esp32/include/netinet/tcp.h -components/lwip/port/esp32/include/sntp/sntp_get_set_time.h -components/lwip/port/esp32/include/sys/socket.h -components/lwip/port/esp32/netif/dhcp_state.c -components/lwip/port/esp32/netif/ethernetif.c -components/lwip/port/esp32/netif/openthreadif.c -components/lwip/port/esp32/netif/wlanif.c -components/lwip/port/esp32/no_vfs_syscalls.c -components/lwip/port/esp32/vfs_lwip.c -components/lwip/test_afl_host/dhcp_di.h -components/lwip/test_afl_host/dhcpserver_di.h -components/lwip/test_afl_host/dns_di.h -components/lwip/test_afl_host/esp_attr.h -components/lwip/test_afl_host/esp_netif_loopback_mock.c -components/lwip/test_afl_host/network_mock.c -components/lwip/test_afl_host/no_warn_host.h -components/lwip/test_afl_host/test_dhcp_client.c -components/lwip/test_afl_host/test_dhcp_server.c -components/lwip/test_afl_host/test_dns.c -components/lwip/weekend_test/net_suite_test.py -components/mbedtls/esp_crt_bundle/esp_crt_bundle.c -components/mbedtls/esp_crt_bundle/gen_crt_bundle.py -components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h -components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/test_gen_crt_bundle.py -components/mbedtls/port/aes/block/esp_aes.c -components/mbedtls/port/aes/dma/esp_aes.c -components/mbedtls/port/aes/dma/esp_aes_crypto_dma_impl.c -components/mbedtls/port/aes/dma/esp_aes_gdma_impl.c -components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h -components/mbedtls/port/aes/esp_aes_common.c -components/mbedtls/port/aes/esp_aes_gcm.c -components/mbedtls/port/aes/esp_aes_xts.c -components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c -components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c -components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h -components/mbedtls/port/dynamic/esp_ssl_cli.c -components/mbedtls/port/dynamic/esp_ssl_srv.c -components/mbedtls/port/dynamic/esp_ssl_tls.c -components/mbedtls/port/esp32/bignum.c -components/mbedtls/port/esp32c3/bignum.c -components/mbedtls/port/esp32h2/bignum.c -components/mbedtls/port/esp32s2/bignum.c -components/mbedtls/port/esp32s3/bignum.c -components/mbedtls/port/esp_bignum.c -components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c -components/mbedtls/port/esp_hardware.c -components/mbedtls/port/esp_mem.c -components/mbedtls/port/esp_timing.c -components/mbedtls/port/include/aes/esp_aes.h -components/mbedtls/port/include/aes/esp_aes_gcm.h -components/mbedtls/port/include/aes/esp_aes_internal.h -components/mbedtls/port/include/aes_alt.h -components/mbedtls/port/include/bignum_impl.h -components/mbedtls/port/include/esp32/aes.h -components/mbedtls/port/include/esp32/sha.h -components/mbedtls/port/include/esp32s2/aes.h -components/mbedtls/port/include/esp32s2/gcm.h -components/mbedtls/port/include/esp32s2/sha.h -components/mbedtls/port/include/esp_crypto_shared_gdma.h -components/mbedtls/port/include/esp_ds/esp_rsa_sign_alt.h -components/mbedtls/port/include/esp_mem.h -components/mbedtls/port/include/gcm_alt.h -components/mbedtls/port/include/mbedtls/bignum.h -components/mbedtls/port/include/mbedtls/esp_config.h -components/mbedtls/port/include/mbedtls/esp_debug.h -components/mbedtls/port/include/md/esp_md.h -components/mbedtls/port/include/md5_alt.h -components/mbedtls/port/include/rsa_sign_alt.h -components/mbedtls/port/include/sha/sha_dma.h -components/mbedtls/port/include/sha/sha_parallel_engine.h -components/mbedtls/port/include/sha1_alt.h -components/mbedtls/port/include/sha256_alt.h -components/mbedtls/port/include/sha512_alt.h -components/mbedtls/port/mbedtls_debug.c -components/mbedtls/port/md/esp_md.c -components/mbedtls/port/net_sockets.c -components/mbedtls/port/sha/dma/esp_sha1.c -components/mbedtls/port/sha/dma/esp_sha256.c -components/mbedtls/port/sha/dma/esp_sha512.c -components/mbedtls/port/sha/dma/esp_sha_crypto_dma_impl.c -components/mbedtls/port/sha/dma/esp_sha_gdma_impl.c -components/mbedtls/port/sha/dma/include/esp_sha_dma_priv.h -components/mbedtls/port/sha/dma/sha.c -components/mbedtls/port/sha/esp_sha.c -components/mbedtls/port/sha/parallel_engine/esp_sha1.c -components/mbedtls/port/sha/parallel_engine/esp_sha256.c -components/mbedtls/port/sha/parallel_engine/esp_sha512.c -components/mbedtls/port/sha/parallel_engine/sha.c -components/mbedtls/test/test_aes.c -components/mbedtls/test/test_aes_gcm.c -components/mbedtls/test/test_aes_perf.c -components/mbedtls/test/test_aes_sha_parallel.c -components/mbedtls/test/test_apb_dport_access.c -components/mbedtls/test/test_apb_dport_access.h -components/mbedtls/test/test_ecp.c -components/mbedtls/test/test_esp_crt_bundle.c -components/mbedtls/test/test_mbedtls.c -components/mbedtls/test/test_mbedtls_mpi.c -components/mbedtls/test/test_mbedtls_sha.c -components/mbedtls/test/test_rsa.c -components/mbedtls/test/test_sha_perf.c -components/mdns/host_test/components/esp_event_mock/esp_event_mock.c -components/mdns/host_test/components/esp_event_mock/include/esp_event.h -components/mdns/host_test/components/esp_event_mock/include/esp_event_base.h -components/mdns/host_test/components/esp_netif_linux/esp_netif_linux.c -components/mdns/host_test/components/esp_netif_linux/include/esp_wifi_types.h -components/mdns/host_test/components/esp_system_protocols_linux/esp_log_impl.c -components/mdns/host_test/components/esp_system_protocols_linux/include/bsd_strings.h -components/mdns/host_test/components/esp_system_protocols_linux/include/machine/endian.h -components/mdns/host_test/components/esp_system_protocols_linux/strlcat.c -components/mdns/host_test/components/esp_timer_linux/esp_timer_linux.c -components/mdns/host_test/components/esp_timer_linux/include/esp_timer.h -components/mdns/host_test/components/esp_timer_linux/timer_task.cpp -components/mdns/host_test/components/esp_timer_linux/timer_task.hpp -components/mdns/host_test/components/freertos_linux/freertos_linux.c -components/mdns/host_test/components/freertos_linux/include/esp_task.h -components/mdns/host_test/components/freertos_linux/include/freertos/FreeRTOS.h -components/mdns/host_test/components/freertos_linux/include/freertos/task.h -components/mdns/host_test/components/freertos_linux/queue_unique_ptr.cpp -components/mdns/host_test/components/freertos_linux/queue_unique_ptr.hpp -components/mdns/host_test/main/main.c -components/mdns/include/mdns.h -components/mdns/include/mdns_console.h -components/mdns/mdns.c -components/mdns/mdns_console.c -components/mdns/mdns_networking_lwip.c -components/mdns/mdns_networking_socket.c -components/mdns/private_include/mdns_networking.h -components/mdns/private_include/mdns_private.h -components/mdns/test/test_mdns.c -components/mdns/test_afl_fuzz_host/esp32_mock.c -components/mdns/test_afl_fuzz_host/esp32_mock.h -components/mdns/test_afl_fuzz_host/esp_attr.h -components/mdns/test_afl_fuzz_host/esp_netif_mock.c -components/mdns/test_afl_fuzz_host/mdns_di.h -components/mdns/test_afl_fuzz_host/mdns_mock.h -components/mdns/test_afl_fuzz_host/sdkconfig.h -components/mdns/test_afl_fuzz_host/test.c -components/mqtt/host_test/main/test_mqtt_client.cpp -components/mqtt/host_test/mocks/include/freertos/FreeRTOSConfig.h -components/mqtt/host_test/mocks/include/freertos/portmacro.h -components/mqtt/host_test/mocks/include/machine/endian.h -components/mqtt/host_test/mocks/include/sys/queue.h -components/mqtt/test/test_mqtt.c -components/newlib/abort.c -components/newlib/assert.c -components/newlib/heap.c -components/newlib/locks.c -components/newlib/newlib_init.c -components/newlib/platform_include/assert.h -components/newlib/platform_include/endian.h -components/newlib/platform_include/errno.h -components/newlib/platform_include/esp_newlib.h -components/newlib/platform_include/net/if.h -components/newlib/platform_include/pthread.h -components/newlib/platform_include/sys/dirent.h -components/newlib/platform_include/sys/ioctl.h -components/newlib/platform_include/sys/lock.h -components/newlib/platform_include/sys/poll.h -components/newlib/platform_include/sys/random.h -components/newlib/platform_include/sys/reent.h -components/newlib/platform_include/sys/select.h -components/newlib/platform_include/sys/termios.h -components/newlib/platform_include/sys/time.h -components/newlib/platform_include/sys/uio.h -components/newlib/platform_include/sys/un.h -components/newlib/platform_include/sys/unistd.h -components/newlib/platform_include/sys/utime.h -components/newlib/platform_include/time.h -components/newlib/poll.c -components/newlib/port/esp_time_impl.c -components/newlib/priv_include/esp_time_impl.h -components/newlib/pthread.c -components/newlib/random.c -components/newlib/reent_init.c -components/newlib/stdatomic.c -components/newlib/syscalls.c -components/newlib/termios.c -components/newlib/test/test_atomic.c -components/newlib/test/test_locks.c -components/newlib/test/test_newlib.c -components/newlib/test/test_setjmp.c -components/newlib/test/test_shared_stack_printf.c -components/newlib/test/test_time.c -components/newlib/test_apps/app_test.py -components/newlib/test_apps/main/test_newlib_main.c -components/newlib/test_apps/main/test_stdatomic.c -components/newlib/time.c -components/nghttp/port/http_parser.c -components/nghttp/port/include/http_parser.h -components/nghttp/port/include/nghttp2/nghttp2ver.h -components/nghttp/private_include/config.h -components/nvs_flash/host_test/fixtures/test_fixtures.hpp -components/nvs_flash/host_test/nvs_page_test/main/nvs_page_test.cpp -components/nvs_flash/include/nvs.h -components/nvs_flash/include/nvs_flash.h -components/nvs_flash/include/nvs_handle.hpp -components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py -components/nvs_flash/src/compressed_enum_table.hpp -components/nvs_flash/src/intrusive_list.h -components/nvs_flash/src/nvs.hpp -components/nvs_flash/src/nvs_api.cpp -components/nvs_flash/src/nvs_cxx_api.cpp -components/nvs_flash/src/nvs_encrypted_partition.cpp -components/nvs_flash/src/nvs_encrypted_partition.hpp -components/nvs_flash/src/nvs_handle_locked.cpp -components/nvs_flash/src/nvs_handle_locked.hpp -components/nvs_flash/src/nvs_handle_simple.cpp -components/nvs_flash/src/nvs_handle_simple.hpp -components/nvs_flash/src/nvs_item_hash_list.cpp -components/nvs_flash/src/nvs_item_hash_list.hpp -components/nvs_flash/src/nvs_page.cpp -components/nvs_flash/src/nvs_page.hpp -components/nvs_flash/src/nvs_pagemanager.cpp -components/nvs_flash/src/nvs_pagemanager.hpp -components/nvs_flash/src/nvs_partition.cpp -components/nvs_flash/src/nvs_partition.hpp -components/nvs_flash/src/nvs_partition_lookup.cpp -components/nvs_flash/src/nvs_partition_lookup.hpp -components/nvs_flash/src/nvs_partition_manager.cpp -components/nvs_flash/src/nvs_partition_manager.hpp -components/nvs_flash/src/nvs_platform.hpp -components/nvs_flash/src/nvs_storage.cpp -components/nvs_flash/src/nvs_storage.hpp -components/nvs_flash/src/nvs_test_api.h -components/nvs_flash/src/nvs_types.cpp -components/nvs_flash/src/nvs_types.hpp -components/nvs_flash/src/partition.hpp -components/nvs_flash/test/test_nvs.c -components/nvs_flash/test_nvs_host/esp_error_check_stub.cpp -components/nvs_flash/test_nvs_host/main.cpp -components/nvs_flash/test_nvs_host/sdkconfig.h -components/nvs_flash/test_nvs_host/spi_flash_emulation.cpp -components/nvs_flash/test_nvs_host/spi_flash_emulation.h -components/nvs_flash/test_nvs_host/test_compressed_enum_table.cpp -components/nvs_flash/test_nvs_host/test_fixtures.hpp -components/nvs_flash/test_nvs_host/test_intrusive_list.cpp -components/nvs_flash/test_nvs_host/test_nvs.cpp -components/nvs_flash/test_nvs_host/test_nvs_cxx_api.cpp -components/nvs_flash/test_nvs_host/test_nvs_handle.cpp -components/nvs_flash/test_nvs_host/test_nvs_initialization.cpp -components/nvs_flash/test_nvs_host/test_nvs_partition.cpp -components/nvs_flash/test_nvs_host/test_nvs_storage.cpp -components/nvs_flash/test_nvs_host/test_partition_manager.cpp -components/nvs_flash/test_nvs_host/test_spi_flash_emulation.cpp -components/openssl/include/internal/ssl3.h -components/openssl/include/internal/ssl_cert.h -components/openssl/include/internal/ssl_code.h -components/openssl/include/internal/ssl_dbg.h -components/openssl/include/internal/ssl_lib.h -components/openssl/include/internal/ssl_methods.h -components/openssl/include/internal/ssl_pkey.h -components/openssl/include/internal/ssl_stack.h -components/openssl/include/internal/ssl_types.h -components/openssl/include/internal/ssl_x509.h -components/openssl/include/internal/tls1.h -components/openssl/include/internal/x509_vfy.h -components/openssl/include/openssl/bio.h -components/openssl/include/openssl/err.h -components/openssl/include/platform/ssl_opt.h -components/openssl/include/platform/ssl_pm.h -components/openssl/include/platform/ssl_port.h -components/openssl/library/ssl_bio.c -components/openssl/library/ssl_cert.c -components/openssl/library/ssl_err.c -components/openssl/library/ssl_lib.c -components/openssl/library/ssl_methods.c -components/openssl/library/ssl_pkey.c -components/openssl/library/ssl_stack.c -components/openssl/platform/ssl_pm.c -components/openssl/platform/ssl_port.c -components/openssl/test/test_openssl.c -components/openthread/include/esp_openthread.h -components/openthread/include/esp_openthread_border_router.h -components/openthread/include/esp_openthread_lock.h -components/openthread/include/esp_openthread_netif_glue.h -components/openthread/include/esp_openthread_types.h -components/openthread/private_include/openthread-core-esp32x-ftd-config.h -components/openthread/private_include/openthread-core-esp32x-radio-config.h -components/partition_table/check_sizes.py -components/partition_table/gen_empty_partition.py -components/partition_table/gen_esp32part.py -components/partition_table/parttool.py -components/partition_table/test/test_partition.c -components/partition_table/test_gen_esp32part_host/check_sizes_test.py -components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py -components/partition_table/test_gen_esp32part_host/test_utils.py -components/perfmon/include/perfmon.h -components/perfmon/include/xtensa_perfmon_access.h -components/perfmon/include/xtensa_perfmon_apis.h -components/perfmon/include/xtensa_perfmon_masks.h -components/perfmon/test/test_perfmon_ansi.c -components/perfmon/xtensa_perfmon_access.c -components/perfmon/xtensa_perfmon_apis.c -components/perfmon/xtensa_perfmon_masks.c -components/protocomm/include/common/protocomm.h -components/protocomm/include/security/protocomm_security.h -components/protocomm/include/security/protocomm_security0.h -components/protocomm/include/security/protocomm_security1.h -components/protocomm/include/transports/protocomm_console.h -components/protocomm/include/transports/protocomm_httpd.h -components/protocomm/proto-c/constants.pb-c.c -components/protocomm/proto-c/constants.pb-c.h -components/protocomm/proto-c/sec0.pb-c.c -components/protocomm/proto-c/sec0.pb-c.h -components/protocomm/proto-c/sec1.pb-c.c -components/protocomm/proto-c/sec1.pb-c.h -components/protocomm/proto-c/session.pb-c.c -components/protocomm/proto-c/session.pb-c.h -components/protocomm/python/constants_pb2.py -components/protocomm/python/sec0_pb2.py -components/protocomm/python/sec1_pb2.py -components/protocomm/python/session_pb2.py -components/protocomm/src/common/protocomm.c -components/protocomm/src/common/protocomm_priv.h -components/protocomm/src/security/security0.c -components/protocomm/src/security/security1.c -components/protocomm/src/transports/protocomm_console.c -components/protocomm/src/transports/protocomm_httpd.c -components/protocomm/test/test_protocomm.c -components/pthread/include/esp_pthread.h -components/pthread/pthread.c -components/pthread/pthread_cond_var.c -components/pthread/pthread_internal.h -components/pthread/pthread_local_storage.c -components/pthread/test/test_cxx_cond_var.cpp -components/pthread/test/test_cxx_std_future.cpp -components/pthread/test/test_pthread.c -components/pthread/test/test_pthread_cond_var.c -components/pthread/test/test_pthread_cxx.cpp -components/pthread/test/test_pthread_local_storage.c -components/riscv/include/esp_private/panic_reason.h -components/riscv/include/riscv/csr.h -components/riscv/include/riscv/encoding.h -components/riscv/include/riscv/instruction_decode.h -components/riscv/include/riscv/interrupt.h -components/riscv/include/riscv/riscv_interrupts.h -components/riscv/include/riscv/rvruntime-frames.h -components/riscv/instruction_decode.c -components/riscv/interrupt.c -components/sdmmc/include/sdmmc_cmd.h -components/sdmmc/sdmmc_cmd.c -components/sdmmc/sdmmc_common.c -components/sdmmc/sdmmc_common.h -components/sdmmc/sdmmc_init.c -components/sdmmc/sdmmc_io.c -components/sdmmc/sdmmc_mmc.c -components/sdmmc/sdmmc_sd.c -components/sdmmc/test/test_sdio.c -components/soc/esp32/adc_periph.c -components/soc/esp32/dac_periph.c -components/soc/esp32/gpio_periph.c -components/soc/esp32/i2c_periph.c -components/soc/esp32/i2s_periph.c -components/soc/esp32/include/soc/adc_channel.h -components/soc/esp32/include/soc/apb_ctrl_reg.h -components/soc/esp32/include/soc/apb_ctrl_struct.h -components/soc/esp32/include/soc/bb_reg.h -components/soc/esp32/include/soc/boot_mode.h -components/soc/esp32/include/soc/can_periph.h -components/soc/esp32/include/soc/can_struct.h -components/soc/esp32/include/soc/clkout_channel.h -components/soc/esp32/include/soc/dac_channel.h -components/soc/esp32/include/soc/dport_access.h -components/soc/esp32/include/soc/dport_reg.h -components/soc/esp32/include/soc/efuse_reg.h -components/soc/esp32/include/soc/emac_dma_struct.h -components/soc/esp32/include/soc/emac_ext_struct.h -components/soc/esp32/include/soc/emac_mac_struct.h -components/soc/esp32/include/soc/fe_reg.h -components/soc/esp32/include/soc/flash_encryption_reg.h -components/soc/esp32/include/soc/frc_timer_reg.h -components/soc/esp32/include/soc/gdma_channel.h -components/soc/esp32/include/soc/gpio_pins.h -components/soc/esp32/include/soc/gpio_reg.h -components/soc/esp32/include/soc/gpio_sd_reg.h -components/soc/esp32/include/soc/gpio_sd_struct.h -components/soc/esp32/include/soc/gpio_sig_map.h -components/soc/esp32/include/soc/gpio_struct.h -components/soc/esp32/include/soc/hinf_reg.h -components/soc/esp32/include/soc/hinf_struct.h -components/soc/esp32/include/soc/host_reg.h -components/soc/esp32/include/soc/host_struct.h -components/soc/esp32/include/soc/hwcrypto_reg.h -components/soc/esp32/include/soc/i2c_reg.h -components/soc/esp32/include/soc/i2c_struct.h -components/soc/esp32/include/soc/i2s_reg.h -components/soc/esp32/include/soc/i2s_struct.h -components/soc/esp32/include/soc/io_mux_reg.h -components/soc/esp32/include/soc/ledc_reg.h -components/soc/esp32/include/soc/ledc_struct.h -components/soc/esp32/include/soc/mmu.h -components/soc/esp32/include/soc/nrx_reg.h -components/soc/esp32/include/soc/pcnt_reg.h -components/soc/esp32/include/soc/pcnt_struct.h -components/soc/esp32/include/soc/periph_defs.h -components/soc/esp32/include/soc/pid.h -components/soc/esp32/include/soc/reset_reasons.h -components/soc/esp32/include/soc/rmt_reg.h -components/soc/esp32/include/soc/rmt_struct.h -components/soc/esp32/include/soc/rtc.h -components/soc/esp32/include/soc/rtc_cntl_reg.h -components/soc/esp32/include/soc/rtc_cntl_struct.h -components/soc/esp32/include/soc/rtc_i2c_reg.h -components/soc/esp32/include/soc/rtc_io_channel.h -components/soc/esp32/include/soc/rtc_io_reg.h -components/soc/esp32/include/soc/rtc_io_struct.h -components/soc/esp32/include/soc/sdio_slave_pins.h -components/soc/esp32/include/soc/sdmmc_pins.h -components/soc/esp32/include/soc/sdmmc_reg.h -components/soc/esp32/include/soc/sdmmc_struct.h -components/soc/esp32/include/soc/sens_reg.h -components/soc/esp32/include/soc/sens_struct.h -components/soc/esp32/include/soc/slc_reg.h -components/soc/esp32/include/soc/slc_struct.h -components/soc/esp32/include/soc/soc.h -components/soc/esp32/include/soc/soc_caps.h -components/soc/esp32/include/soc/soc_pins.h -components/soc/esp32/include/soc/soc_ulp.h -components/soc/esp32/include/soc/spi_pins.h -components/soc/esp32/include/soc/spi_reg.h -components/soc/esp32/include/soc/spi_struct.h -components/soc/esp32/include/soc/syscon_reg.h -components/soc/esp32/include/soc/syscon_struct.h -components/soc/esp32/include/soc/timer_group_reg.h -components/soc/esp32/include/soc/timer_group_struct.h -components/soc/esp32/include/soc/touch_sensor_channel.h -components/soc/esp32/include/soc/twai_struct.h -components/soc/esp32/include/soc/uart_channel.h -components/soc/esp32/include/soc/uart_pins.h -components/soc/esp32/include/soc/uart_reg.h -components/soc/esp32/include/soc/uart_struct.h -components/soc/esp32/include/soc/uhci_reg.h -components/soc/esp32/include/soc/uhci_struct.h -components/soc/esp32/include/soc/wdev_reg.h -components/soc/esp32/interrupts.c -components/soc/esp32/lcd_periph.c -components/soc/esp32/ledc_periph.c -components/soc/esp32/mcpwm_periph.c -components/soc/esp32/pcnt_periph.c -components/soc/esp32/rmt_periph.c -components/soc/esp32/rtc_io_periph.c -components/soc/esp32/sdio_slave_periph.c -components/soc/esp32/sdmmc_periph.c -components/soc/esp32/sigmadelta_periph.c -components/soc/esp32/spi_periph.c -components/soc/esp32/timer_periph.c -components/soc/esp32/touch_sensor_periph.c -components/soc/esp32/uart_periph.c -components/soc/esp32c3/adc_periph.c -components/soc/esp32c3/gdma_periph.c -components/soc/esp32c3/gpio_periph.c -components/soc/esp32c3/i2c_bbpll.h -components/soc/esp32c3/i2c_periph.c -components/soc/esp32c3/i2s_periph.c -components/soc/esp32c3/include/soc/adc_channel.h -components/soc/esp32c3/include/soc/apb_ctrl_reg.h -components/soc/esp32c3/include/soc/apb_ctrl_struct.h -components/soc/esp32c3/include/soc/apb_saradc_reg.h -components/soc/esp32c3/include/soc/apb_saradc_struct.h -components/soc/esp32c3/include/soc/assist_debug_reg.h -components/soc/esp32c3/include/soc/bb_reg.h -components/soc/esp32c3/include/soc/boot_mode.h -components/soc/esp32c3/include/soc/cache_memory.h -components/soc/esp32c3/include/soc/clkout_channel.h -components/soc/esp32c3/include/soc/dport_access.h -components/soc/esp32c3/include/soc/efuse_reg.h -components/soc/esp32c3/include/soc/efuse_struct.h -components/soc/esp32c3/include/soc/extmem_reg.h -components/soc/esp32c3/include/soc/fe_reg.h -components/soc/esp32c3/include/soc/gdma_channel.h -components/soc/esp32c3/include/soc/gdma_reg.h -components/soc/esp32c3/include/soc/gdma_struct.h -components/soc/esp32c3/include/soc/gpio_pins.h -components/soc/esp32c3/include/soc/gpio_reg.h -components/soc/esp32c3/include/soc/gpio_sd_reg.h -components/soc/esp32c3/include/soc/gpio_sd_struct.h -components/soc/esp32c3/include/soc/gpio_sig_map.h -components/soc/esp32c3/include/soc/gpio_struct.h -components/soc/esp32c3/include/soc/hwcrypto_reg.h -components/soc/esp32c3/include/soc/i2c_reg.h -components/soc/esp32c3/include/soc/i2c_struct.h -components/soc/esp32c3/include/soc/i2s_reg.h -components/soc/esp32c3/include/soc/i2s_struct.h -components/soc/esp32c3/include/soc/interrupt_core0_reg.h -components/soc/esp32c3/include/soc/interrupt_reg.h -components/soc/esp32c3/include/soc/io_mux_reg.h -components/soc/esp32c3/include/soc/ledc_reg.h -components/soc/esp32c3/include/soc/ledc_struct.h -components/soc/esp32c3/include/soc/mmu.h -components/soc/esp32c3/include/soc/nrx_reg.h -components/soc/esp32c3/include/soc/periph_defs.h -components/soc/esp32c3/include/soc/reset_reasons.h -components/soc/esp32c3/include/soc/rmt_reg.h -components/soc/esp32c3/include/soc/rmt_struct.h -components/soc/esp32c3/include/soc/rtc.h -components/soc/esp32c3/include/soc/rtc_cntl_reg.h -components/soc/esp32c3/include/soc/rtc_cntl_struct.h -components/soc/esp32c3/include/soc/rtc_i2c_reg.h -components/soc/esp32c3/include/soc/rtc_i2c_struct.h -components/soc/esp32c3/include/soc/sensitive_reg.h -components/soc/esp32c3/include/soc/sensitive_struct.h -components/soc/esp32c3/include/soc/soc.h -components/soc/esp32c3/include/soc/soc_caps.h -components/soc/esp32c3/include/soc/soc_pins.h -components/soc/esp32c3/include/soc/spi_mem_reg.h -components/soc/esp32c3/include/soc/spi_mem_struct.h -components/soc/esp32c3/include/soc/spi_pins.h -components/soc/esp32c3/include/soc/spi_reg.h -components/soc/esp32c3/include/soc/spi_struct.h -components/soc/esp32c3/include/soc/syscon_reg.h -components/soc/esp32c3/include/soc/syscon_struct.h -components/soc/esp32c3/include/soc/system_reg.h -components/soc/esp32c3/include/soc/system_struct.h -components/soc/esp32c3/include/soc/systimer_reg.h -components/soc/esp32c3/include/soc/systimer_struct.h -components/soc/esp32c3/include/soc/twai_struct.h -components/soc/esp32c3/include/soc/uart_channel.h -components/soc/esp32c3/include/soc/uart_pins.h -components/soc/esp32c3/include/soc/uart_reg.h -components/soc/esp32c3/include/soc/uart_struct.h -components/soc/esp32c3/include/soc/uhci_reg.h -components/soc/esp32c3/include/soc/uhci_struct.h -components/soc/esp32c3/include/soc/usb_serial_jtag_reg.h -components/soc/esp32c3/include/soc/usb_serial_jtag_struct.h -components/soc/esp32c3/include/soc/wdev_reg.h -components/soc/esp32c3/interrupts.c -components/soc/esp32c3/ld/esp32c3.peripherals.ld -components/soc/esp32c3/ledc_periph.c -components/soc/esp32c3/rmt_periph.c -components/soc/esp32c3/sigmadelta_periph.c -components/soc/esp32c3/spi_periph.c -components/soc/esp32c3/timer_periph.c -components/soc/esp32c3/uart_periph.c -components/soc/esp32h2/adc_periph.c -components/soc/esp32h2/gdma_periph.c -components/soc/esp32h2/gpio_periph.c -components/soc/esp32h2/i2c_periph.c -components/soc/esp32h2/i2s_periph.c -components/soc/esp32h2/include/soc/adc_channel.h -components/soc/esp32h2/include/soc/apb_ctrl_reg.h -components/soc/esp32h2/include/soc/apb_ctrl_struct.h -components/soc/esp32h2/include/soc/apb_saradc_reg.h -components/soc/esp32h2/include/soc/apb_saradc_struct.h -components/soc/esp32h2/include/soc/assist_debug_reg.h -components/soc/esp32h2/include/soc/bb_reg.h -components/soc/esp32h2/include/soc/boot_mode.h -components/soc/esp32h2/include/soc/cache_memory.h -components/soc/esp32h2/include/soc/clkout_channel.h -components/soc/esp32h2/include/soc/clkrst_reg.h -components/soc/esp32h2/include/soc/dport_access.h -components/soc/esp32h2/include/soc/efuse_reg.h -components/soc/esp32h2/include/soc/efuse_struct.h -components/soc/esp32h2/include/soc/extmem_reg.h -components/soc/esp32h2/include/soc/fe_reg.h -components/soc/esp32h2/include/soc/gdma_channel.h -components/soc/esp32h2/include/soc/gdma_reg.h -components/soc/esp32h2/include/soc/gdma_struct.h -components/soc/esp32h2/include/soc/gpio_pins.h -components/soc/esp32h2/include/soc/gpio_reg.h -components/soc/esp32h2/include/soc/gpio_sd_reg.h -components/soc/esp32h2/include/soc/gpio_sd_struct.h -components/soc/esp32h2/include/soc/gpio_sig_map.h -components/soc/esp32h2/include/soc/gpio_struct.h -components/soc/esp32h2/include/soc/hwcrypto_reg.h -components/soc/esp32h2/include/soc/i2c_reg.h -components/soc/esp32h2/include/soc/i2c_struct.h -components/soc/esp32h2/include/soc/i2s_reg.h -components/soc/esp32h2/include/soc/i2s_struct.h -components/soc/esp32h2/include/soc/interrupt_core0_reg.h -components/soc/esp32h2/include/soc/interrupt_reg.h -components/soc/esp32h2/include/soc/io_mux_reg.h -components/soc/esp32h2/include/soc/ledc_reg.h -components/soc/esp32h2/include/soc/ledc_struct.h -components/soc/esp32h2/include/soc/mmu.h -components/soc/esp32h2/include/soc/nrx_reg.h -components/soc/esp32h2/include/soc/periph_defs.h -components/soc/esp32h2/include/soc/reset_reasons.h -components/soc/esp32h2/include/soc/rmt_reg.h -components/soc/esp32h2/include/soc/rmt_struct.h -components/soc/esp32h2/include/soc/rtc.h -components/soc/esp32h2/include/soc/rtc_caps.h -components/soc/esp32h2/include/soc/rtc_cntl_reg.h -components/soc/esp32h2/include/soc/rtc_cntl_struct.h -components/soc/esp32h2/include/soc/rtc_i2c_reg.h -components/soc/esp32h2/include/soc/rtc_i2c_struct.h -components/soc/esp32h2/include/soc/rtc_io_caps.h -components/soc/esp32h2/include/soc/sensitive_reg.h -components/soc/esp32h2/include/soc/sensitive_struct.h -components/soc/esp32h2/include/soc/soc.h -components/soc/esp32h2/include/soc/soc_caps.h -components/soc/esp32h2/include/soc/soc_pins.h -components/soc/esp32h2/include/soc/spi_caps.h -components/soc/esp32h2/include/soc/spi_mem_reg.h -components/soc/esp32h2/include/soc/spi_mem_struct.h -components/soc/esp32h2/include/soc/spi_pins.h -components/soc/esp32h2/include/soc/spi_reg.h -components/soc/esp32h2/include/soc/spi_struct.h -components/soc/esp32h2/include/soc/syscon_reg.h -components/soc/esp32h2/include/soc/syscon_struct.h -components/soc/esp32h2/include/soc/system_reg.h -components/soc/esp32h2/include/soc/system_struct.h -components/soc/esp32h2/include/soc/systimer_reg.h -components/soc/esp32h2/include/soc/systimer_struct.h -components/soc/esp32h2/include/soc/twai_struct.h -components/soc/esp32h2/include/soc/uart_channel.h -components/soc/esp32h2/include/soc/uart_pins.h -components/soc/esp32h2/include/soc/uart_reg.h -components/soc/esp32h2/include/soc/uart_struct.h -components/soc/esp32h2/include/soc/uhci_reg.h -components/soc/esp32h2/include/soc/uhci_struct.h -components/soc/esp32h2/include/soc/usb_serial_jtag_reg.h -components/soc/esp32h2/include/soc/usb_serial_jtag_struct.h -components/soc/esp32h2/include/soc/wdev_reg.h -components/soc/esp32h2/interrupts.c -components/soc/esp32h2/ld/esp32h2.peripherals.ld -components/soc/esp32h2/ledc_periph.c -components/soc/esp32h2/rmt_periph.c -components/soc/esp32h2/sigmadelta_periph.c -components/soc/esp32h2/spi_periph.c -components/soc/esp32h2/timer_periph.c -components/soc/esp32h2/uart_periph.c -components/soc/esp32s2/adc_periph.c -components/soc/esp32s2/dac_periph.c -components/soc/esp32s2/dedic_gpio_periph.c -components/soc/esp32s2/gpio_periph.c -components/soc/esp32s2/i2c_periph.c -components/soc/esp32s2/i2s_periph.c -components/soc/esp32s2/include/soc/adc_channel.h -components/soc/esp32s2/include/soc/apb_ctrl_reg.h -components/soc/esp32s2/include/soc/apb_ctrl_struct.h -components/soc/esp32s2/include/soc/apb_saradc_reg.h -components/soc/esp32s2/include/soc/apb_saradc_struct.h -components/soc/esp32s2/include/soc/assist_debug_reg.h -components/soc/esp32s2/include/soc/bb_reg.h -components/soc/esp32s2/include/soc/boot_mode.h -components/soc/esp32s2/include/soc/cache_memory.h -components/soc/esp32s2/include/soc/clkout_channel.h -components/soc/esp32s2/include/soc/cp_dma_reg.h -components/soc/esp32s2/include/soc/cp_dma_struct.h -components/soc/esp32s2/include/soc/crypto_dma_reg.h -components/soc/esp32s2/include/soc/dac_channel.h -components/soc/esp32s2/include/soc/dedic_gpio_reg.h -components/soc/esp32s2/include/soc/dedic_gpio_struct.h -components/soc/esp32s2/include/soc/dport_access.h -components/soc/esp32s2/include/soc/dport_reg.h -components/soc/esp32s2/include/soc/efuse_reg.h -components/soc/esp32s2/include/soc/efuse_struct.h -components/soc/esp32s2/include/soc/extmem_reg.h -components/soc/esp32s2/include/soc/fe_reg.h -components/soc/esp32s2/include/soc/frc_timer_reg.h -components/soc/esp32s2/include/soc/gdma_channel.h -components/soc/esp32s2/include/soc/gpio_pins.h -components/soc/esp32s2/include/soc/gpio_reg.h -components/soc/esp32s2/include/soc/gpio_sd_reg.h -components/soc/esp32s2/include/soc/gpio_sd_struct.h -components/soc/esp32s2/include/soc/gpio_sig_map.h -components/soc/esp32s2/include/soc/gpio_struct.h -components/soc/esp32s2/include/soc/hwcrypto_reg.h -components/soc/esp32s2/include/soc/i2c_reg.h -components/soc/esp32s2/include/soc/i2c_struct.h -components/soc/esp32s2/include/soc/i2s_reg.h -components/soc/esp32s2/include/soc/i2s_struct.h -components/soc/esp32s2/include/soc/interrupt_reg.h -components/soc/esp32s2/include/soc/io_mux_reg.h -components/soc/esp32s2/include/soc/ledc_reg.h -components/soc/esp32s2/include/soc/ledc_struct.h -components/soc/esp32s2/include/soc/memprot_defs.h -components/soc/esp32s2/include/soc/mmu.h -components/soc/esp32s2/include/soc/nrx_reg.h -components/soc/esp32s2/include/soc/pcnt_reg.h -components/soc/esp32s2/include/soc/pcnt_struct.h -components/soc/esp32s2/include/soc/periph_defs.h -components/soc/esp32s2/include/soc/reset_reasons.h -components/soc/esp32s2/include/soc/rmt_reg.h -components/soc/esp32s2/include/soc/rmt_struct.h -components/soc/esp32s2/include/soc/rtc.h -components/soc/esp32s2/include/soc/rtc_cntl_reg.h -components/soc/esp32s2/include/soc/rtc_cntl_struct.h -components/soc/esp32s2/include/soc/rtc_i2c_reg.h -components/soc/esp32s2/include/soc/rtc_i2c_struct.h -components/soc/esp32s2/include/soc/rtc_io_channel.h -components/soc/esp32s2/include/soc/rtc_io_reg.h -components/soc/esp32s2/include/soc/rtc_io_struct.h -components/soc/esp32s2/include/soc/sdio_slave_pins.h -components/soc/esp32s2/include/soc/sdmmc_pins.h -components/soc/esp32s2/include/soc/sens_reg.h -components/soc/esp32s2/include/soc/sens_struct.h -components/soc/esp32s2/include/soc/sensitive_reg.h -components/soc/esp32s2/include/soc/soc.h -components/soc/esp32s2/include/soc/soc_pins.h -components/soc/esp32s2/include/soc/soc_ulp.h -components/soc/esp32s2/include/soc/spi_mem_reg.h -components/soc/esp32s2/include/soc/spi_mem_struct.h -components/soc/esp32s2/include/soc/spi_pins.h -components/soc/esp32s2/include/soc/spi_reg.h -components/soc/esp32s2/include/soc/spi_struct.h -components/soc/esp32s2/include/soc/syscon_reg.h -components/soc/esp32s2/include/soc/syscon_struct.h -components/soc/esp32s2/include/soc/system_reg.h -components/soc/esp32s2/include/soc/systimer_reg.h -components/soc/esp32s2/include/soc/systimer_struct.h -components/soc/esp32s2/include/soc/touch_sensor_channel.h -components/soc/esp32s2/include/soc/touch_sensor_pins.h -components/soc/esp32s2/include/soc/twai_struct.h -components/soc/esp32s2/include/soc/uart_channel.h -components/soc/esp32s2/include/soc/uart_pins.h -components/soc/esp32s2/include/soc/uart_reg.h -components/soc/esp32s2/include/soc/uart_struct.h -components/soc/esp32s2/include/soc/uhci_reg.h -components/soc/esp32s2/include/soc/uhci_struct.h -components/soc/esp32s2/include/soc/usb_pins.h -components/soc/esp32s2/include/soc/usb_reg.h -components/soc/esp32s2/include/soc/usb_struct.h -components/soc/esp32s2/include/soc/usb_types.h -components/soc/esp32s2/include/soc/usb_wrap_reg.h -components/soc/esp32s2/include/soc/usb_wrap_struct.h -components/soc/esp32s2/include/soc/usbh_struct.h -components/soc/esp32s2/include/soc/wdev_reg.h -components/soc/esp32s2/interrupts.c -components/soc/esp32s2/lcd_periph.c -components/soc/esp32s2/ledc_periph.c -components/soc/esp32s2/pcnt_periph.c -components/soc/esp32s2/rmt_periph.c -components/soc/esp32s2/rtc_io_periph.c -components/soc/esp32s2/sigmadelta_periph.c -components/soc/esp32s2/spi_periph.c -components/soc/esp32s2/timer_periph.c -components/soc/esp32s2/touch_sensor_periph.c -components/soc/esp32s2/uart_periph.c -components/soc/esp32s2/usb_periph.c -components/soc/esp32s3/adc_periph.c -components/soc/esp32s3/dedic_gpio_periph.c -components/soc/esp32s3/gdma_periph.c -components/soc/esp32s3/gpio_periph.c -components/soc/esp32s3/i2c_periph.c -components/soc/esp32s3/i2s_periph.c -components/soc/esp32s3/include/soc/adc_channel.h -components/soc/esp32s3/include/soc/apb_ctrl_reg.h -components/soc/esp32s3/include/soc/apb_ctrl_struct.h -components/soc/esp32s3/include/soc/apb_saradc_reg.h -components/soc/esp32s3/include/soc/apb_saradc_struct.h -components/soc/esp32s3/include/soc/assist_debug_reg.h -components/soc/esp32s3/include/soc/assist_debug_struct.h -components/soc/esp32s3/include/soc/bb_reg.h -components/soc/esp32s3/include/soc/boot_mode.h -components/soc/esp32s3/include/soc/brownout_caps.h -components/soc/esp32s3/include/soc/cache_memory.h -components/soc/esp32s3/include/soc/clkout_channel.h -components/soc/esp32s3/include/soc/cpu.h -components/soc/esp32s3/include/soc/cpu_caps.h -components/soc/esp32s3/include/soc/dport_access.h -components/soc/esp32s3/include/soc/dport_reg.h -components/soc/esp32s3/include/soc/efuse_reg.h -components/soc/esp32s3/include/soc/efuse_struct.h -components/soc/esp32s3/include/soc/extmem_reg.h -components/soc/esp32s3/include/soc/extmem_struct.h -components/soc/esp32s3/include/soc/fe_reg.h -components/soc/esp32s3/include/soc/gdma_channel.h -components/soc/esp32s3/include/soc/gdma_reg.h -components/soc/esp32s3/include/soc/gdma_struct.h -components/soc/esp32s3/include/soc/gpio_caps.h -components/soc/esp32s3/include/soc/gpio_pins.h -components/soc/esp32s3/include/soc/gpio_reg.h -components/soc/esp32s3/include/soc/gpio_sd_reg.h -components/soc/esp32s3/include/soc/gpio_sd_struct.h -components/soc/esp32s3/include/soc/gpio_sig_map.h -components/soc/esp32s3/include/soc/gpio_struct.h -components/soc/esp32s3/include/soc/hinf_reg.h -components/soc/esp32s3/include/soc/hinf_struct.h -components/soc/esp32s3/include/soc/host_reg.h -components/soc/esp32s3/include/soc/host_struct.h -components/soc/esp32s3/include/soc/i2c_caps.h -components/soc/esp32s3/include/soc/i2c_reg.h -components/soc/esp32s3/include/soc/i2c_struct.h -components/soc/esp32s3/include/soc/i2s_reg.h -components/soc/esp32s3/include/soc/i2s_struct.h -components/soc/esp32s3/include/soc/interrupt_core0_reg.h -components/soc/esp32s3/include/soc/interrupt_core0_struct.h -components/soc/esp32s3/include/soc/interrupt_core1_reg.h -components/soc/esp32s3/include/soc/interrupt_core1_struct.h -components/soc/esp32s3/include/soc/interrupt_reg.h -components/soc/esp32s3/include/soc/interrupt_struct.h -components/soc/esp32s3/include/soc/io_mux_reg.h -components/soc/esp32s3/include/soc/lcd_cam_reg.h -components/soc/esp32s3/include/soc/lcd_cam_struct.h -components/soc/esp32s3/include/soc/ledc_caps.h -components/soc/esp32s3/include/soc/ledc_reg.h -components/soc/esp32s3/include/soc/ledc_struct.h -components/soc/esp32s3/include/soc/mmu.h -components/soc/esp32s3/include/soc/mpu_caps.h -components/soc/esp32s3/include/soc/nrx_reg.h -components/soc/esp32s3/include/soc/pcnt_caps.h -components/soc/esp32s3/include/soc/pcnt_reg.h -components/soc/esp32s3/include/soc/pcnt_struct.h -components/soc/esp32s3/include/soc/peri_backup_reg.h -components/soc/esp32s3/include/soc/peri_backup_struct.h -components/soc/esp32s3/include/soc/periph_defs.h -components/soc/esp32s3/include/soc/reset_reasons.h -components/soc/esp32s3/include/soc/rmt_reg.h -components/soc/esp32s3/include/soc/rmt_struct.h -components/soc/esp32s3/include/soc/rtc.h -components/soc/esp32s3/include/soc/rtc_cntl_reg.h -components/soc/esp32s3/include/soc/rtc_cntl_struct.h -components/soc/esp32s3/include/soc/rtc_gpio_channel.h -components/soc/esp32s3/include/soc/rtc_i2c_reg.h -components/soc/esp32s3/include/soc/rtc_i2c_struct.h -components/soc/esp32s3/include/soc/rtc_io_caps.h -components/soc/esp32s3/include/soc/rtc_io_channel.h -components/soc/esp32s3/include/soc/rtc_io_reg.h -components/soc/esp32s3/include/soc/rtc_io_struct.h -components/soc/esp32s3/include/soc/sdio_slave_pins.h -components/soc/esp32s3/include/soc/sdmmc_pins.h -components/soc/esp32s3/include/soc/sdmmc_reg.h -components/soc/esp32s3/include/soc/sdmmc_struct.h -components/soc/esp32s3/include/soc/sens_reg.h -components/soc/esp32s3/include/soc/sens_struct.h -components/soc/esp32s3/include/soc/sensitive_reg.h -components/soc/esp32s3/include/soc/sensitive_struct.h -components/soc/esp32s3/include/soc/sigmadelta_caps.h -components/soc/esp32s3/include/soc/soc.h -components/soc/esp32s3/include/soc/soc_caps.h -components/soc/esp32s3/include/soc/soc_pins.h -components/soc/esp32s3/include/soc/soc_ulp.h -components/soc/esp32s3/include/soc/spi_mem_reg.h -components/soc/esp32s3/include/soc/spi_mem_struct.h -components/soc/esp32s3/include/soc/spi_pins.h -components/soc/esp32s3/include/soc/spi_reg.h -components/soc/esp32s3/include/soc/spi_struct.h -components/soc/esp32s3/include/soc/syscon_reg.h -components/soc/esp32s3/include/soc/syscon_struct.h -components/soc/esp32s3/include/soc/system_reg.h -components/soc/esp32s3/include/soc/system_struct.h -components/soc/esp32s3/include/soc/systimer_reg.h -components/soc/esp32s3/include/soc/systimer_struct.h -components/soc/esp32s3/include/soc/timer_group_reg.h -components/soc/esp32s3/include/soc/timer_group_struct.h -components/soc/esp32s3/include/soc/touch_channel.h -components/soc/esp32s3/include/soc/touch_sensor_caps.h -components/soc/esp32s3/include/soc/touch_sensor_channel.h -components/soc/esp32s3/include/soc/twai_caps.h -components/soc/esp32s3/include/soc/twai_struct.h -components/soc/esp32s3/include/soc/uart_caps.h -components/soc/esp32s3/include/soc/uart_channel.h -components/soc/esp32s3/include/soc/uart_pins.h -components/soc/esp32s3/include/soc/uart_reg.h -components/soc/esp32s3/include/soc/uart_struct.h -components/soc/esp32s3/include/soc/uhci_reg.h -components/soc/esp32s3/include/soc/uhci_struct.h -components/soc/esp32s3/include/soc/usb_caps.h -components/soc/esp32s3/include/soc/usb_device_reg.h -components/soc/esp32s3/include/soc/usb_pins.h -components/soc/esp32s3/include/soc/usb_reg.h -components/soc/esp32s3/include/soc/usb_serial_jtag_reg.h -components/soc/esp32s3/include/soc/usb_serial_jtag_struct.h -components/soc/esp32s3/include/soc/usb_struct.h -components/soc/esp32s3/include/soc/usb_types.h -components/soc/esp32s3/include/soc/usb_wrap_reg.h -components/soc/esp32s3/include/soc/usb_wrap_struct.h -components/soc/esp32s3/include/soc/usbh_struct.h -components/soc/esp32s3/include/soc/wdev_reg.h -components/soc/esp32s3/include/soc/world_controller_reg.h -components/soc/esp32s3/include/soc/world_controller_struct.h -components/soc/esp32s3/interrupts.c -components/soc/esp32s3/lcd_periph.c -components/soc/esp32s3/ledc_periph.c -components/soc/esp32s3/mcpwm_periph.c -components/soc/esp32s3/pcnt_periph.c -components/soc/esp32s3/rmt_periph.c -components/soc/esp32s3/rtc_io_periph.c -components/soc/esp32s3/sdio_slave_periph.c -components/soc/esp32s3/sdmmc_periph.c -components/soc/esp32s3/sigmadelta_periph.c -components/soc/esp32s3/spi_periph.c -components/soc/esp32s3/timer_periph.c -components/soc/esp32s3/touch_sensor_periph.c -components/soc/esp32s3/uart_periph.c -components/soc/esp32s3/usb_periph.c -components/soc/esp32s3/usb_periph.h -components/soc/include/soc/adc_periph.h -components/soc/include/soc/dac_periph.h -components/soc/include/soc/dedic_gpio_periph.h -components/soc/include/soc/efuse_periph.h -components/soc/include/soc/emac_periph.h -components/soc/include/soc/gdma_periph.h -components/soc/include/soc/gpio_periph.h -components/soc/include/soc/hwcrypto_periph.h -components/soc/include/soc/i2c_periph.h -components/soc/include/soc/i2s_periph.h -components/soc/include/soc/interrupts.h -components/soc/include/soc/lcd_periph.h -components/soc/include/soc/ledc_periph.h -components/soc/include/soc/lldesc.h -components/soc/include/soc/mcpwm_periph.h -components/soc/include/soc/pcnt_periph.h -components/soc/include/soc/rmt_periph.h -components/soc/include/soc/rtc_cntl_periph.h -components/soc/include/soc/rtc_io_periph.h -components/soc/include/soc/rtc_periph.h -components/soc/include/soc/sdio_slave_periph.h -components/soc/include/soc/sdmmc_periph.h -components/soc/include/soc/sens_periph.h -components/soc/include/soc/sigmadelta_periph.h -components/soc/include/soc/soc_memory_types.h -components/soc/include/soc/spi_periph.h -components/soc/include/soc/syscon_periph.h -components/soc/include/soc/timer_periph.h -components/soc/include/soc/touch_sensor_periph.h -components/soc/include/soc/twai_periph.h -components/soc/include/soc/uart_periph.h -components/soc/include/soc/uhci_periph.h -components/soc/include/soc/usb_periph.h -components/soc/lldesc.c -components/soc/soc_include_legacy_warn.c -components/spi_flash/cache_utils.h -components/spi_flash/esp32/flash_ops_esp32.c -components/spi_flash/esp32/spi_flash_rom_patch.c -components/spi_flash/esp32c3/flash_ops_esp32c3.c -components/spi_flash/esp32c3/spi_flash_rom_patch.c -components/spi_flash/esp32h2/flash_ops_esp32h2.c -components/spi_flash/esp32h2/spi_flash_rom_patch.c -components/spi_flash/esp32s2/flash_ops_esp32s2.c -components/spi_flash/esp32s2/spi_flash_rom_patch.c -components/spi_flash/esp32s3/flash_ops_esp32s3.c -components/spi_flash/esp_flash_api.c -components/spi_flash/esp_flash_spi_init.c -components/spi_flash/flash_mmap.c -components/spi_flash/flash_ops.c -components/spi_flash/include/esp_flash.h -components/spi_flash/include/esp_flash_internal.h -components/spi_flash/include/esp_flash_spi_init.h -components/spi_flash/include/esp_partition.h -components/spi_flash/include/esp_spi_flash.h -components/spi_flash/include/esp_spi_flash_counters.h -components/spi_flash/include/memspi_host_driver.h -components/spi_flash/include/spi_flash/spi_flash_defs.h -components/spi_flash/include/spi_flash_chip_boya.h -components/spi_flash/include/spi_flash_chip_driver.h -components/spi_flash/include/spi_flash_chip_gd.h -components/spi_flash/include/spi_flash_chip_generic.h -components/spi_flash/include/spi_flash_chip_issi.h -components/spi_flash/include/spi_flash_chip_mxic.h -components/spi_flash/include/spi_flash_chip_winbond.h -components/spi_flash/memspi_host_driver.c -components/spi_flash/partition.c -components/spi_flash/sim/SpiFlash.cpp -components/spi_flash/sim/SpiFlash.h -components/spi_flash/sim/flash_mock.cpp -components/spi_flash/sim/flash_mock_util.c -components/spi_flash/sim/sdkconfig/sdkconfig.h -components/spi_flash/spi_flash_chip_boya.c -components/spi_flash/spi_flash_chip_drivers.c -components/spi_flash/spi_flash_chip_gd.c -components/spi_flash/spi_flash_chip_generic.c -components/spi_flash/spi_flash_chip_issi.c -components/spi_flash/spi_flash_chip_mxic.c -components/spi_flash/spi_flash_chip_mxic_opi.c -components/spi_flash/spi_flash_chip_winbond.c -components/spi_flash/spi_flash_os_func_app.c -components/spi_flash/spi_flash_os_func_noos.c -components/spi_flash/test/test_cache_disabled.c -components/spi_flash/test/test_esp_flash.c -components/spi_flash/test/test_flash_encryption.c -components/spi_flash/test/test_large_flash_writes.c -components/spi_flash/test/test_mmap.c -components/spi_flash/test/test_out_of_bounds_write.c -components/spi_flash/test/test_partition_ext.c -components/spi_flash/test/test_partitions.c -components/spi_flash/test/test_read_write.c -components/spi_flash/test/test_spi_flash.c -components/spiffs/esp_spiffs.c -components/spiffs/include/esp_spiffs.h -components/spiffs/include/spiffs_config.h -components/spiffs/spiffs_api.c -components/spiffs/spiffs_api.h -components/spiffs/spiffsgen.py -components/spiffs/test/test_spiffs.c -components/spiffs/test_spiffs_host/main.cpp -components/spiffs/test_spiffs_host/sdkconfig/sdkconfig.h -components/spiffs/test_spiffs_host/test_spiffs.cpp -components/spiffs/test_spiffsgen/test_spiffsgen.py -components/tcp_transport/include/esp_transport.h -components/tcp_transport/include/esp_transport_ssl.h -components/tcp_transport/include/esp_transport_tcp.h -components/tcp_transport/include/esp_transport_ws.h -components/tcp_transport/private_include/esp_transport_internal.h -components/tcp_transport/private_include/esp_transport_utils.h -components/tcp_transport/test/tcp_transport_fixtures.h -components/tcp_transport/test/test_transport_basic.c -components/tcp_transport/test/test_transport_connect.c -components/tcp_transport/test/test_transport_fixtures.c -components/tcp_transport/transport.c -components/tcp_transport/transport_ssl.c -components/tcp_transport/transport_utils.c -components/tcp_transport/transport_ws.c -components/tcpip_adapter/include/tcpip_adapter.h -components/tcpip_adapter/include/tcpip_adapter_compatible/tcpip_adapter_compat.h -components/tcpip_adapter/include/tcpip_adapter_types.h -components/tcpip_adapter/tcpip_adapter_compat.c -components/tinyusb/additions/include/tinyusb.h -components/tinyusb/additions/include/tinyusb_types.h -components/tinyusb/additions/include/tusb_cdc_acm.h -components/tinyusb/additions/include/tusb_config.h -components/tinyusb/additions/include/tusb_console.h -components/tinyusb/additions/include/tusb_tasks.h -components/tinyusb/additions/include/vfs_tinyusb.h -components/tinyusb/additions/include_private/cdc.h -components/tinyusb/additions/include_private/descriptors_control.h -components/tinyusb/additions/include_private/usb_descriptors.h -components/tinyusb/additions/src/cdc.c -components/tinyusb/additions/src/descriptors_control.c -components/tinyusb/additions/src/tinyusb.c -components/tinyusb/additions/src/tusb_cdc_acm.c -components/tinyusb/additions/src/tusb_console.c -components/tinyusb/additions/src/tusb_tasks.c -components/tinyusb/additions/src/usb_descriptors.c -components/tinyusb/additions/src/vfs_tinyusb.c -components/touch_element/include/touch_element/touch_button.h -components/touch_element/include/touch_element/touch_element.h -components/touch_element/include/touch_element/touch_element_private.h -components/touch_element/include/touch_element/touch_matrix.h -components/touch_element/include/touch_element/touch_slider.h -components/touch_element/test/test_touch_button.c -components/touch_element/test/test_touch_element.c -components/touch_element/test/test_touch_matrix.c -components/touch_element/test/test_touch_slider.c -components/touch_element/touch_button.c -components/touch_element/touch_element.c -components/touch_element/touch_matrix.c -components/touch_element/touch_slider.c -components/ulp/esp32ulp_mapgen.py -components/ulp/include/esp32/ulp.h -components/ulp/include/esp32s2/ulp.h -components/ulp/include/esp32s2/ulp_riscv.h -components/ulp/include/esp32s3/ulp.h -components/ulp/include/ulp_common.h -components/ulp/ld/esp32.ulp.ld -components/ulp/ld/esp32s2.ulp.riscv.ld -components/ulp/test/esp32/test_ulp.c -components/ulp/test/esp32/test_ulp_as.c -components/ulp/test/esp32s2/test_ulp_riscv.c -components/ulp/test/ulp_riscv/test_main.c -components/ulp/ulp.c -components/ulp/ulp_macro.c -components/ulp/ulp_private.h -components/ulp/ulp_riscv.c -components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv.h -components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_gpio.h -components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_register_ops.h -components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_utils.h -components/ulp/ulp_riscv/ulp_riscv_utils.c -components/unity/include/priv/setjmp.h -components/unity/include/unity_config.h -components/unity/include/unity_fixture_extras.h -components/unity/include/unity_test_runner.h -components/unity/unity_port_esp32.c -components/unity/unity_runner.c -components/usb/test/common/test_usb_mock_classes.c -components/usb/test/common/test_usb_mock_classes.h -components/usb/test/hcd/test_hcd_ctrl.c -components/vfs/include/esp_vfs.h -components/vfs/include/esp_vfs_cdcacm.h -components/vfs/include/esp_vfs_common.h -components/vfs/include/esp_vfs_dev.h -components/vfs/include/esp_vfs_eventfd.h -components/vfs/include/esp_vfs_semihost.h -components/vfs/include/esp_vfs_usb_serial_jtag.h -components/vfs/test/test_vfs_access.c -components/vfs/test/test_vfs_append.c -components/vfs/test/test_vfs_eventfd.c -components/vfs/test/test_vfs_fd.c -components/vfs/test/test_vfs_lwip.c -components/vfs/test/test_vfs_paths.c -components/vfs/test/test_vfs_select.c -components/vfs/test/test_vfs_uart.c -components/vfs/vfs.c -components/vfs/vfs_cdcacm.c -components/vfs/vfs_eventfd.c -components/vfs/vfs_semihost.c -components/vfs/vfs_uart.c -components/vfs/vfs_usb_serial_jtag.c -components/wear_levelling/Partition.cpp -components/wear_levelling/SPI_Flash.cpp -components/wear_levelling/WL_Ext_Perf.cpp -components/wear_levelling/WL_Ext_Safe.cpp -components/wear_levelling/WL_Flash.cpp -components/wear_levelling/crc32.cpp -components/wear_levelling/crc32.h -components/wear_levelling/include/wear_levelling.h -components/wear_levelling/private_include/Flash_Access.h -components/wear_levelling/private_include/Partition.h -components/wear_levelling/private_include/SPI_Flash.h -components/wear_levelling/private_include/WL_Config.h -components/wear_levelling/private_include/WL_Ext_Cfg.h -components/wear_levelling/private_include/WL_Ext_Perf.h -components/wear_levelling/private_include/WL_Ext_Safe.h -components/wear_levelling/private_include/WL_Flash.h -components/wear_levelling/private_include/WL_State.h -components/wear_levelling/test/test_wl.c -components/wear_levelling/test_wl_host/esp_error_check_stub.cpp -components/wear_levelling/test_wl_host/main.cpp -components/wear_levelling/test_wl_host/sdkconfig/sdkconfig.h -components/wear_levelling/test_wl_host/test_wl.cpp -components/wear_levelling/wear_levelling.cpp -components/wifi_provisioning/include/wifi_provisioning/manager.h -components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h -components/wifi_provisioning/include/wifi_provisioning/scheme_console.h -components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h -components/wifi_provisioning/include/wifi_provisioning/wifi_config.h -components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h -components/wifi_provisioning/proto-c/wifi_config.pb-c.c -components/wifi_provisioning/proto-c/wifi_config.pb-c.h -components/wifi_provisioning/proto-c/wifi_constants.pb-c.c -components/wifi_provisioning/proto-c/wifi_constants.pb-c.h -components/wifi_provisioning/proto-c/wifi_scan.pb-c.c -components/wifi_provisioning/proto-c/wifi_scan.pb-c.h -components/wifi_provisioning/python/wifi_config_pb2.py -components/wifi_provisioning/python/wifi_constants_pb2.py -components/wifi_provisioning/python/wifi_scan_pb2.py -components/wifi_provisioning/src/handlers.c -components/wifi_provisioning/src/manager.c -components/wifi_provisioning/src/scheme_console.c -components/wifi_provisioning/src/scheme_softap.c -components/wifi_provisioning/src/wifi_config.c -components/wifi_provisioning/src/wifi_provisioning_priv.h -components/wifi_provisioning/src/wifi_scan.c -components/wpa_supplicant/esp_supplicant/include/esp_dpp.h -components/wpa_supplicant/esp_supplicant/include/esp_rrm.h -components/wpa_supplicant/esp_supplicant/include/esp_wnm.h -components/wpa_supplicant/esp_supplicant/include/esp_wpa.h -components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h -components/wpa_supplicant/esp_supplicant/include/esp_wps.h -components/wpa_supplicant/esp_supplicant/src/esp_common.c -components/wpa_supplicant/esp_supplicant/src/esp_common_i.h -components/wpa_supplicant/esp_supplicant/src/esp_dpp.c -components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h -components/wpa_supplicant/esp_supplicant/src/esp_hostap.c -components/wpa_supplicant/esp_supplicant/src/esp_hostap.h -components/wpa_supplicant/esp_supplicant/src/esp_scan.c -components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h -components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h -components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c -components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c -components/wpa_supplicant/esp_supplicant/src/esp_wpa3_i.h -components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h -components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c -components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c -components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h -components/wpa_supplicant/esp_supplicant/src/esp_wps.c -components/wpa_supplicant/include/utils/wpa_debug.h -components/wpa_supplicant/include/utils/wpabuf.h -components/wpa_supplicant/port/include/byteswap.h -components/wpa_supplicant/port/include/endian.h -components/wpa_supplicant/port/include/os.h -components/wpa_supplicant/port/include/supplicant_opt.h -components/wpa_supplicant/port/os_xtensa.c -components/wpa_supplicant/src/ap/ap_config.c -components/wpa_supplicant/src/ap/ap_config.h -components/wpa_supplicant/src/ap/hostapd.h -components/wpa_supplicant/src/ap/ieee802_1x.c -components/wpa_supplicant/src/ap/ieee802_1x.h -components/wpa_supplicant/src/ap/sta_info.h -components/wpa_supplicant/src/ap/wpa_auth.c -components/wpa_supplicant/src/ap/wpa_auth.h -components/wpa_supplicant/src/ap/wpa_auth_i.h -components/wpa_supplicant/src/ap/wpa_auth_ie.c -components/wpa_supplicant/src/ap/wpa_auth_ie.h -components/wpa_supplicant/src/common/bss.c -components/wpa_supplicant/src/common/bss.h -components/wpa_supplicant/src/common/defs.h -components/wpa_supplicant/src/common/dpp.c -components/wpa_supplicant/src/common/dpp.h -components/wpa_supplicant/src/common/eapol_common.h -components/wpa_supplicant/src/common/ieee802_11_common.c -components/wpa_supplicant/src/common/ieee802_11_common.h -components/wpa_supplicant/src/common/ieee802_11_defs.h -components/wpa_supplicant/src/common/rrm.c -components/wpa_supplicant/src/common/rrm.h -components/wpa_supplicant/src/common/sae.c -components/wpa_supplicant/src/common/sae.h -components/wpa_supplicant/src/common/scan.c -components/wpa_supplicant/src/common/scan.h -components/wpa_supplicant/src/common/wnm_sta.c -components/wpa_supplicant/src/common/wnm_sta.h -components/wpa_supplicant/src/common/wpa_common.c -components/wpa_supplicant/src/common/wpa_common.h -components/wpa_supplicant/src/common/wpa_ctrl.h -components/wpa_supplicant/src/common/wpa_supplicant_i.h -components/wpa_supplicant/src/crypto/aes-cbc.c -components/wpa_supplicant/src/crypto/aes-ccm.c -components/wpa_supplicant/src/crypto/aes-ctr.c -components/wpa_supplicant/src/crypto/aes-internal-dec.c -components/wpa_supplicant/src/crypto/aes-internal-enc.c -components/wpa_supplicant/src/crypto/aes-internal.c -components/wpa_supplicant/src/crypto/aes-omac1.c -components/wpa_supplicant/src/crypto/aes-siv.c -components/wpa_supplicant/src/crypto/aes-unwrap.c -components/wpa_supplicant/src/crypto/aes-wrap.c -components/wpa_supplicant/src/crypto/aes.h -components/wpa_supplicant/src/crypto/aes_i.h -components/wpa_supplicant/src/crypto/aes_siv.h -components/wpa_supplicant/src/crypto/aes_wrap.h -components/wpa_supplicant/src/crypto/ccmp.c -components/wpa_supplicant/src/crypto/ccmp.h -components/wpa_supplicant/src/crypto/crypto.h -components/wpa_supplicant/src/crypto/crypto_internal-cipher.c -components/wpa_supplicant/src/crypto/crypto_internal-modexp.c -components/wpa_supplicant/src/crypto/crypto_internal-rsa.c -components/wpa_supplicant/src/crypto/crypto_internal.c -components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c -components/wpa_supplicant/src/crypto/crypto_mbedtls-ec.c -components/wpa_supplicant/src/crypto/crypto_mbedtls-rsa.c -components/wpa_supplicant/src/crypto/crypto_mbedtls.c -components/wpa_supplicant/src/crypto/crypto_ops.c -components/wpa_supplicant/src/crypto/des-internal.c -components/wpa_supplicant/src/crypto/des_i.h -components/wpa_supplicant/src/crypto/dh_group5.c -components/wpa_supplicant/src/crypto/dh_group5.h -components/wpa_supplicant/src/crypto/dh_groups.c -components/wpa_supplicant/src/crypto/dh_groups.h -components/wpa_supplicant/src/crypto/libtommath.h -components/wpa_supplicant/src/crypto/md4-internal.c -components/wpa_supplicant/src/crypto/md5-internal.c -components/wpa_supplicant/src/crypto/md5.c -components/wpa_supplicant/src/crypto/md5.h -components/wpa_supplicant/src/crypto/md5_i.h -components/wpa_supplicant/src/crypto/ms_funcs.c -components/wpa_supplicant/src/crypto/ms_funcs.h -components/wpa_supplicant/src/crypto/random.h -components/wpa_supplicant/src/crypto/rc4.c -components/wpa_supplicant/src/crypto/sha1-internal.c -components/wpa_supplicant/src/crypto/sha1-pbkdf2.c -components/wpa_supplicant/src/crypto/sha1-prf.c -components/wpa_supplicant/src/crypto/sha1-tlsprf.c -components/wpa_supplicant/src/crypto/sha1.c -components/wpa_supplicant/src/crypto/sha1.h -components/wpa_supplicant/src/crypto/sha1_i.h -components/wpa_supplicant/src/crypto/sha256-internal.c -components/wpa_supplicant/src/crypto/sha256-kdf.c -components/wpa_supplicant/src/crypto/sha256-prf.c -components/wpa_supplicant/src/crypto/sha256-tlsprf.c -components/wpa_supplicant/src/crypto/sha256.c -components/wpa_supplicant/src/crypto/sha256.h -components/wpa_supplicant/src/crypto/sha256_i.h -components/wpa_supplicant/src/crypto/sha384-internal.c -components/wpa_supplicant/src/crypto/sha384-tlsprf.c -components/wpa_supplicant/src/crypto/sha384.h -components/wpa_supplicant/src/crypto/sha384_i.h -components/wpa_supplicant/src/crypto/sha512-internal.c -components/wpa_supplicant/src/crypto/sha512_i.h -components/wpa_supplicant/src/crypto/tls_mbedtls.c -components/wpa_supplicant/src/drivers/driver.h -components/wpa_supplicant/src/eap_peer/chap.c -components/wpa_supplicant/src/eap_peer/chap.h -components/wpa_supplicant/src/eap_peer/eap.c -components/wpa_supplicant/src/eap_peer/eap.h -components/wpa_supplicant/src/eap_peer/eap_common.c -components/wpa_supplicant/src/eap_peer/eap_common.h -components/wpa_supplicant/src/eap_peer/eap_config.h -components/wpa_supplicant/src/eap_peer/eap_defs.h -components/wpa_supplicant/src/eap_peer/eap_i.h -components/wpa_supplicant/src/eap_peer/eap_methods.h -components/wpa_supplicant/src/eap_peer/eap_mschapv2.c -components/wpa_supplicant/src/eap_peer/eap_peap.c -components/wpa_supplicant/src/eap_peer/eap_peap_common.c -components/wpa_supplicant/src/eap_peer/eap_peap_common.h -components/wpa_supplicant/src/eap_peer/eap_tls.c -components/wpa_supplicant/src/eap_peer/eap_tls.h -components/wpa_supplicant/src/eap_peer/eap_tls_common.c -components/wpa_supplicant/src/eap_peer/eap_tls_common.h -components/wpa_supplicant/src/eap_peer/eap_tlv_common.h -components/wpa_supplicant/src/eap_peer/eap_ttls.c -components/wpa_supplicant/src/eap_peer/eap_ttls.h -components/wpa_supplicant/src/eap_peer/mschapv2.c -components/wpa_supplicant/src/eap_peer/mschapv2.h -components/wpa_supplicant/src/rsn_supp/pmksa_cache.c -components/wpa_supplicant/src/rsn_supp/pmksa_cache.h -components/wpa_supplicant/src/rsn_supp/wpa.c -components/wpa_supplicant/src/rsn_supp/wpa.h -components/wpa_supplicant/src/rsn_supp/wpa_i.h -components/wpa_supplicant/src/rsn_supp/wpa_ie.c -components/wpa_supplicant/src/rsn_supp/wpa_ie.h -components/wpa_supplicant/src/tls/asn1.c -components/wpa_supplicant/src/tls/asn1.h -components/wpa_supplicant/src/tls/bignum.c -components/wpa_supplicant/src/tls/bignum.h -components/wpa_supplicant/src/tls/libtommath.h -components/wpa_supplicant/src/tls/pkcs1.c -components/wpa_supplicant/src/tls/pkcs1.h -components/wpa_supplicant/src/tls/pkcs5.c -components/wpa_supplicant/src/tls/pkcs5.h -components/wpa_supplicant/src/tls/pkcs8.c -components/wpa_supplicant/src/tls/pkcs8.h -components/wpa_supplicant/src/tls/rsa.c -components/wpa_supplicant/src/tls/rsa.h -components/wpa_supplicant/src/tls/tls.h -components/wpa_supplicant/src/tls/tls_internal.c -components/wpa_supplicant/src/tls/tlsv1_client.c -components/wpa_supplicant/src/tls/tlsv1_client.h -components/wpa_supplicant/src/tls/tlsv1_client_i.h -components/wpa_supplicant/src/tls/tlsv1_client_read.c -components/wpa_supplicant/src/tls/tlsv1_client_write.c -components/wpa_supplicant/src/tls/tlsv1_common.c -components/wpa_supplicant/src/tls/tlsv1_common.h -components/wpa_supplicant/src/tls/tlsv1_cred.c -components/wpa_supplicant/src/tls/tlsv1_cred.h -components/wpa_supplicant/src/tls/tlsv1_record.c -components/wpa_supplicant/src/tls/tlsv1_record.h -components/wpa_supplicant/src/tls/tlsv1_server.c -components/wpa_supplicant/src/tls/tlsv1_server.h -components/wpa_supplicant/src/tls/tlsv1_server_i.h -components/wpa_supplicant/src/tls/tlsv1_server_read.c -components/wpa_supplicant/src/tls/tlsv1_server_write.c -components/wpa_supplicant/src/tls/x509v3.c -components/wpa_supplicant/src/tls/x509v3.h -components/wpa_supplicant/src/utils/base64.c -components/wpa_supplicant/src/utils/base64.h -components/wpa_supplicant/src/utils/bitfield.c -components/wpa_supplicant/src/utils/bitfield.h -components/wpa_supplicant/src/utils/common.c -components/wpa_supplicant/src/utils/common.h -components/wpa_supplicant/src/utils/ext_password.c -components/wpa_supplicant/src/utils/ext_password.h -components/wpa_supplicant/src/utils/ext_password_i.h -components/wpa_supplicant/src/utils/includes.h -components/wpa_supplicant/src/utils/json.c -components/wpa_supplicant/src/utils/json.h -components/wpa_supplicant/src/utils/list.h -components/wpa_supplicant/src/utils/state_machine.h -components/wpa_supplicant/src/utils/uuid.c -components/wpa_supplicant/src/utils/uuid.h -components/wpa_supplicant/src/utils/wpa_debug.c -components/wpa_supplicant/src/utils/wpabuf.c -components/wpa_supplicant/src/wps/wps.c -components/wpa_supplicant/src/wps/wps.h -components/wpa_supplicant/src/wps/wps_attr_build.c -components/wpa_supplicant/src/wps/wps_attr_parse.c -components/wpa_supplicant/src/wps/wps_attr_parse.h -components/wpa_supplicant/src/wps/wps_attr_process.c -components/wpa_supplicant/src/wps/wps_common.c -components/wpa_supplicant/src/wps/wps_defs.h -components/wpa_supplicant/src/wps/wps_dev_attr.c -components/wpa_supplicant/src/wps/wps_dev_attr.h -components/wpa_supplicant/src/wps/wps_enrollee.c -components/wpa_supplicant/src/wps/wps_i.h -components/wpa_supplicant/src/wps/wps_registrar.c -components/wpa_supplicant/src/wps/wps_validate.c -components/wpa_supplicant/test/test_crypto.c -components/wpa_supplicant/test/test_dpp.c -components/wpa_supplicant/test/test_offchannel.c -components/wpa_supplicant/test/test_sae.c -components/xtensa/eri.c -components/xtensa/esp32/include/xtensa/config/core-isa.h -components/xtensa/esp32/include/xtensa/config/core-matmap.h -components/xtensa/esp32/include/xtensa/config/core.h -components/xtensa/esp32/include/xtensa/config/defs.h -components/xtensa/esp32/include/xtensa/config/extreg.h -components/xtensa/esp32/include/xtensa/config/specreg.h -components/xtensa/esp32/include/xtensa/config/system.h -components/xtensa/esp32/include/xtensa/config/tie-asm.h -components/xtensa/esp32/include/xtensa/config/tie.h -components/xtensa/esp32s2/include/xtensa/config/core-isa.h -components/xtensa/esp32s2/include/xtensa/config/core-matmap.h -components/xtensa/esp32s2/include/xtensa/config/core.h -components/xtensa/esp32s2/include/xtensa/config/defs.h -components/xtensa/esp32s2/include/xtensa/config/extreg.h -components/xtensa/esp32s2/include/xtensa/config/specreg.h -components/xtensa/esp32s2/include/xtensa/config/system.h -components/xtensa/esp32s2/include/xtensa/config/tie-asm.h -components/xtensa/esp32s2/include/xtensa/config/tie.h -components/xtensa/esp32s3/include/xtensa/config/core-isa.h -components/xtensa/esp32s3/include/xtensa/config/core-matmap.h -components/xtensa/esp32s3/include/xtensa/config/core.h -components/xtensa/esp32s3/include/xtensa/config/defs.h -components/xtensa/esp32s3/include/xtensa/config/extreg.h -components/xtensa/esp32s3/include/xtensa/config/specreg.h -components/xtensa/esp32s3/include/xtensa/config/system.h -components/xtensa/esp32s3/include/xtensa/config/tie-asm.h -components/xtensa/esp32s3/include/xtensa/config/tie.h -components/xtensa/include/eri.h -components/xtensa/include/esp_panic.h -components/xtensa/include/esp_private/panic_reason.h -components/xtensa/include/xt_instr_macros.h -components/xtensa/include/xt_trax.h -components/xtensa/include/xtensa-debug-module.h -components/xtensa/include/xtensa/cacheasm.h -components/xtensa/include/xtensa/cacheattrasm.h -components/xtensa/include/xtensa/core-macros.h -components/xtensa/include/xtensa/coreasm.h -components/xtensa/include/xtensa/corebits.h -components/xtensa/include/xtensa/hal.h -components/xtensa/include/xtensa/idmaasm.h -components/xtensa/include/xtensa/mpuasm.h -components/xtensa/include/xtensa/specreg.h -components/xtensa/include/xtensa/traxreg.h -components/xtensa/include/xtensa/xdm-regs.h -components/xtensa/include/xtensa/xt_perf_consts.h -components/xtensa/include/xtensa/xtensa-libdb-macros.h -components/xtensa/include/xtensa/xtensa-versions.h -components/xtensa/include/xtensa/xtensa-xer.h -components/xtensa/include/xtensa/xtensa_api.h -components/xtensa/include/xtensa/xtensa_context.h -components/xtensa/include/xtensa/xtruntime-core-state.h -components/xtensa/include/xtensa/xtruntime-frames.h -components/xtensa/include/xtensa/xtruntime.h -components/xtensa/trax/test/test.c -components/xtensa/trax/traceparse.py -components/xtensa/xt_trax.c -components/xtensa/xtensa_intr.c -docs/conf_common.py -docs/en/conf.py -docs/generate_chart.py -docs/zh_CN/conf.py -examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs.c -examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs.h -examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs_demo.c -examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c -examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.h -examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_api.c -examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_api.h -examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_demo.c -examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_protocol.h -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/ble_hidd_demo_main.c -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/esp_hidd_prf_api.c -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/esp_hidd_prf_api.h -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_dev.c -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_dev.h -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hid_device_le_prf.c -examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/hidd_le_prf_int.h -examples/bluetooth/bluedroid/ble/ble_ibeacon/main/esp_ibeacon_api.c -examples/bluetooth/bluedroid/ble/ble_ibeacon/main/esp_ibeacon_api.h -examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c -examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c -examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c -examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.h -examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c -examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c -examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c -examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c -examples/bluetooth/bluedroid/ble/gatt_security_server/main/example_ble_sec_gatts_demo.c -examples/bluetooth/bluedroid/ble/gatt_security_server/main/example_ble_sec_gatts_demo.h -examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c -examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c -examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.h -examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c -examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c -examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c -examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.h -examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c -examples/bluetooth/bluedroid/ble_50/peroidic_adv/main/periodic_adv_demo.c -examples/bluetooth/bluedroid/ble_50/peroidic_sync/main/periodic_sync_demo.c -examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c -examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h -examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c -examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h -examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c -examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.c -examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.h -examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c -examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/bt_discovery.c -examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/example_spp_acceptor_demo.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/app_spp_msg_prs.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/app_spp_msg_prs.h -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/app_spp_msg_set.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/app_spp_msg_set.h -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/console_uart.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/console_uart.h -examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/example_spp_initiator_demo.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.h -examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c -examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.h -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_prs.c -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_prs.h -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.c -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.h -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_core.c -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_core.h -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.h -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/gpio_pcm_config.c -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/gpio_pcm_config.h -examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_prs.c -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_prs.h -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.c -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.h -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_core.c -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_core.h -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_hf.c -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_hf.h -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/gpio_pcm_config.c -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/gpio_pcm_config.h -examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c -examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c -examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.h -examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c -examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.h -examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c -examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c -examples/bluetooth/blufi/main/blufi_example.h -examples/bluetooth/blufi/main/blufi_example_main.c -examples/bluetooth/blufi/main/blufi_init.c -examples/bluetooth/blufi/main/blufi_security.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/genie_event.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/genie_mesh.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/genie_model_srv.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/genie_reset.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/genie_timer.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/genie_util.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_dlist.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_event.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_mesh.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_model_srv.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_reset.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_slist.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_timer.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_util.h -examples/bluetooth/esp_ble_mesh/aligenie_demo/main/aligenie_demo.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/main/board.c -examples/bluetooth/esp_ble_mesh/aligenie_demo/main/include/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/ble_unit.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/ble_unit.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/run_tc.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/run_tc.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/sync.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/sync.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/test_env.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/test_env.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/wifi_connect.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/wifi_connect.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/wifi_unit.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/components/case/wifi_unit.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/main/coex_cmd.c -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/main/coex_cmd.h -examples/bluetooth/esp_ble_mesh/ble_mesh_coex_test/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_adapter.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_adapter.h -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_cfg_srv_model.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_cfg_srv_model.h -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_decl.h -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_lib.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_lib.h -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_console_system.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_cfg_client_cmd.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_gen_onoff_client_cmd.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_reg_test_perf_client_cmd.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_register_cmd.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/ble_mesh_register_server_cmd.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/register_bluetooth.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/transaction.c -examples/bluetooth/esp_ble_mesh/ble_mesh_console/main/transaction.h -examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_server/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/main.c -examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/board.c -examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/board.h -examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/cmd_decl.h -examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/cmd_wifi.c -examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/main.c -examples/bluetooth/esp_ble_mesh/common_components/button/button.c -examples/bluetooth/esp_ble_mesh/common_components/button/button_obj.cpp -examples/bluetooth/esp_ble_mesh/common_components/button/include/iot_button.h -examples/bluetooth/esp_ble_mesh/common_components/example_init/ble_mesh_example_init.c -examples/bluetooth/esp_ble_mesh/common_components/example_init/ble_mesh_example_init.h -examples/bluetooth/esp_ble_mesh/common_components/example_nvs/ble_mesh_example_nvs.c -examples/bluetooth/esp_ble_mesh/common_components/example_nvs/ble_mesh_example_nvs.h -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_client_model.c -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_client_model.h -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_common.h -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_operation.c -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_operation.h -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_server_model.c -examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_server_model.h -examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/iot_led.h -examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/iot_light.h -examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/light_driver.h -examples/bluetooth/esp_ble_mesh/common_components/light_driver/iot_led.c -examples/bluetooth/esp_ble_mesh/common_components/light_driver/iot_light.c -examples/bluetooth/esp_ble_mesh/common_components/light_driver/light_driver.c -examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c -examples/bluetooth/esp_hid_device/main/esp_hid_gap.c -examples/bluetooth/esp_hid_device/main/esp_hid_gap.h -examples/bluetooth/esp_hid_host/main/esp_hid_gap.c -examples/bluetooth/esp_hid_host/main/esp_hid_gap.h -examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c -examples/bluetooth/hci/ble_adv_scan_combined/main/app_bt.c -examples/bluetooth/hci/controller_hci_uart/main/controller_hci_uart_demo.c -examples/bluetooth/hci/controller_hci_uart_esp32c3/main/uhci_uart_demo.c -examples/bluetooth/hci/controller_vhci_ble_adv/main/app_bt.c -examples/bluetooth/hci/hci_common_component/bt_hci_common.c -examples/bluetooth/hci/hci_common_component/include/bt_hci_common.h -examples/bluetooth/nimble/blecent/blecent_test.py -examples/bluetooth/nimble/blecent/main/blecent.h -examples/bluetooth/nimble/blecent/main/main.c -examples/bluetooth/nimble/blecent/main/misc.c -examples/bluetooth/nimble/blecent/main/peer.c -examples/bluetooth/nimble/blehr/blehr_test.py -examples/bluetooth/nimble/blehr/main/blehr_sens.h -examples/bluetooth/nimble/blehr/main/gatt_svr.c -examples/bluetooth/nimble/blehr/main/main.c -examples/bluetooth/nimble/blemesh/main/app_mesh.c -examples/bluetooth/nimble/bleprph/bleprph_test.py -examples/bluetooth/nimble/bleprph/main/bleprph.h -examples/bluetooth/nimble/bleprph/main/gatt_svr.c -examples/bluetooth/nimble/bleprph/main/main.c -examples/bluetooth/nimble/bleprph/main/misc.c -examples/bluetooth/nimble/bleprph/main/scli.c -examples/bluetooth/nimble/bleprph_wifi_coex/main/bleprph.h -examples/bluetooth/nimble/bleprph_wifi_coex/main/gatt_svr.c -examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c -examples/build_system/cmake/component_manager/main/component_manager.c -examples/build_system/cmake/idf_as_lib/main.c -examples/build_system/cmake/idf_as_lib/stubs/esp32/cpu_start.c -examples/build_system/cmake/idf_as_lib/stubs/esp32/esp_system.h -examples/build_system/cmake/idf_as_lib/stubs/esp32/flash_ops.c -examples/build_system/cmake/idf_as_lib/stubs/esp32/system_api.c -examples/build_system/cmake/idf_as_lib/stubs/freertos/freertos/task.h -examples/build_system/cmake/idf_as_lib/stubs/freertos/task.c -examples/build_system/cmake/idf_as_lib/stubs/spi_flash/esp_spi_flash.h -examples/build_system/cmake/import_lib/main/main.cpp -examples/build_system/cmake/import_prebuilt/main/main.c -examples/build_system/cmake/import_prebuilt/prebuilt/components/prebuilt/prebuilt.c -examples/build_system/cmake/import_prebuilt/prebuilt/components/prebuilt/prebuilt.h -examples/build_system/cmake/import_prebuilt/prebuilt/main/main.c -examples/build_system/cmake/linux_host_app/main/linux_host_app.cpp -examples/build_system/cmake/multi_config/main/func.h -examples/build_system/cmake/multi_config/main/func_dev.c -examples/build_system/cmake/multi_config/main/func_prod.c -examples/build_system/cmake/multi_config/main/multi_config_example_main.c -examples/common_components/iperf/include/iperf.h -examples/common_components/iperf/iperf.c -examples/common_components/led_strip/include/led_strip.h -examples/common_components/led_strip/led_strip_rmt_ws2812.c -examples/common_components/protocol_examples_common/addr_from_stdin.c -examples/common_components/protocol_examples_common/connect.c -examples/common_components/protocol_examples_common/include/addr_from_stdin.h -examples/common_components/protocol_examples_common/include/protocol_examples_common.h -examples/common_components/protocol_examples_common/stdin_out.c -examples/common_components/qrcode/esp_qrcode_main.c -examples/common_components/qrcode/esp_qrcode_wrapper.c -examples/common_components/qrcode/include/qrcode.h -examples/common_components/qrcode/qrcodegen.c -examples/common_components/qrcode/qrcodegen.h -examples/custom_bootloader/bootloader_hooks/bootloader_components/my_boot_hooks/hooks.c -examples/custom_bootloader/bootloader_hooks/example_test.py -examples/custom_bootloader/bootloader_hooks/main/bootloader_hooks_example_main.c -examples/custom_bootloader/bootloader_override/example_test.py -examples/cxx/exceptions/example_test.py -examples/cxx/exceptions/main/exception_example_main.cpp -examples/cxx/experimental/blink_cxx/main/main.cpp -examples/cxx/experimental/esp_event_async_cxx/main/esp_event_async_cxx_example.cpp -examples/cxx/experimental/esp_event_cxx/main/esp_event_cxx_example.cpp -examples/cxx/experimental/esp_modem_cxx/main/simple_client.cpp -examples/cxx/experimental/esp_modem_cxx/main/simple_mqtt_client.cpp -examples/cxx/experimental/esp_modem_cxx/main/simple_mqtt_client.hpp -examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/esp_mqtt_cxx.cpp -examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt.hpp -examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt_client_config.hpp -examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_ssl_example.cpp -examples/cxx/experimental/esp_mqtt_cxx/tcp/main/mqtt_tcp_example.cpp -examples/cxx/experimental/esp_timer_cxx/main/esp_timer_example.cpp -examples/cxx/experimental/experimental_cpp_component/esp_event_api.cpp -examples/cxx/experimental/experimental_cpp_component/esp_event_cxx.cpp -examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp -examples/cxx/experimental/experimental_cpp_component/esp_timer_cxx.cpp -examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/esp_timer_test.cpp -examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp -examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/gpio_cxx_test.cpp -examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp -examples/cxx/experimental/experimental_cpp_component/include/esp_event_api.hpp -examples/cxx/experimental/experimental_cpp_component/include/esp_event_cxx.hpp -examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp -examples/cxx/experimental/experimental_cpp_component/include/esp_timer_cxx.hpp -examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp -examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp -examples/cxx/experimental/experimental_cpp_component/test/test_esp_event_cxx.cpp -examples/cxx/experimental/experimental_cpp_component/test/test_esp_timer.cpp -examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp -examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp -examples/cxx/experimental/sensor_mcp9808/main/sensor_mcp9808.cpp -examples/cxx/pthread/example_test.py -examples/cxx/pthread/main/cpp_pthread.cpp -examples/cxx/rtti/example_test.py -examples/cxx/rtti/main/rtti_example_main.cpp -examples/ethernet/basic/main/ethernet_example_main.c -examples/ethernet/enc28j60/components/eth_enc28j60/enc28j60.h -examples/ethernet/enc28j60/components/eth_enc28j60/esp_eth_enc28j60.h -examples/ethernet/enc28j60/components/eth_enc28j60/esp_eth_mac_enc28j60.c -examples/ethernet/enc28j60/components/eth_enc28j60/esp_eth_phy_enc28j60.c -examples/ethernet/enc28j60/main/enc28j60_example_main.c -examples/ethernet/eth2ap/main/ethernet_example_main.c -examples/ethernet/iperf/iperf_test.py -examples/ethernet/iperf/main/cmd_ethernet.c -examples/ethernet/iperf/main/cmd_ethernet.h -examples/ethernet/iperf/main/ethernet_example_main.c -examples/get-started/blink/example_test.py -examples/get-started/blink/main/blink_example_main.c -examples/get-started/hello_world/example_test.py -examples/get-started/hello_world/main/hello_world_main.c -examples/get-started/sample_project/main/main.c -examples/mesh/internal_communication/main/include/mesh_light.h -examples/mesh/internal_communication/main/mesh_light.c -examples/mesh/internal_communication/main/mesh_main.c -examples/mesh/ip_internal_network/main/include/mesh_netif.h -examples/mesh/ip_internal_network/main/mesh_main.c -examples/mesh/ip_internal_network/main/mesh_netif.c -examples/mesh/ip_internal_network/main/mqtt_app.c -examples/mesh/manual_networking/main/include/mesh_light.h -examples/mesh/manual_networking/main/mesh_light.c -examples/mesh/manual_networking/main/mesh_main.c -examples/network/network_tests/main/net_suite.c -examples/network/network_tests/main/stdinout.c -examples/network/network_tests/main/stdinout.h -examples/network/simple_sniffer/components/pcap/pcap.c -examples/network/simple_sniffer/components/pcap/pcap.h -examples/network/simple_sniffer/main/cmd_sniffer.c -examples/network/simple_sniffer/main/cmd_sniffer.h -examples/network/simple_sniffer/main/simple_sniffer_example_main.c -examples/openthread/ot_br/main/esp_ot_br.c -examples/openthread/ot_br/main/esp_ot_config.h -examples/openthread/ot_rcp/main/esp_ot_config.h -examples/openthread/ot_rcp/main/esp_ot_rcp.c -examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c -examples/peripherals/adc/single_read/adc/main/adc1_example_main.c -examples/peripherals/adc/single_read/adc2/main/adc2_example_main.c -examples/peripherals/adc/single_read/single_read/main/single_read.c -examples/peripherals/gpio/generic_gpio/example_test.py -examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c -examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/include/matrix_keyboard.h -examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/src/matrix_keyboard.c -examples/peripherals/gpio/matrix_keyboard/main/matrix_keyboard_example_main.c -examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c -examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c -examples/peripherals/i2c/i2c_tools/example_test.py -examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.c -examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.h -examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c -examples/peripherals/i2s/i2s_adc_dac/main/app_main.c -examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h -examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py -examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c -examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c -examples/peripherals/lcd/tjpgd/main/decode_image.c -examples/peripherals/lcd/tjpgd/main/decode_image.h -examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c -examples/peripherals/lcd/tjpgd/main/pretty_effect.c -examples/peripherals/lcd/tjpgd/main/pretty_effect.h -examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c -examples/peripherals/ledc/ledc_fade/main/ledc_fade_example_main.c -examples/peripherals/mcpwm/mcpwm_bldc_hall_control/main/mcpwm_bldc_hall_control_example_main.c -examples/peripherals/mcpwm/mcpwm_brushed_dc_control/components/motor_ctrl_timer/motor_ctrl_timer.c -examples/peripherals/mcpwm/mcpwm_brushed_dc_control/components/motor_ctrl_timer/motor_ctrl_timer.h -examples/peripherals/mcpwm/mcpwm_brushed_dc_control/main/cmd_mcpwm_motor.c -examples/peripherals/mcpwm/mcpwm_brushed_dc_control/main/mcpwm_brushed_dc_control_example.c -examples/peripherals/mcpwm/mcpwm_brushed_dc_control/main/mcpwm_brushed_dc_control_example.h -examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/main/mcpwm_capture_hc_sr04.c -examples/peripherals/mcpwm/mcpwm_servo_control/main/mcpwm_servo_control_example_main.c -examples/peripherals/mcpwm/mcpwm_sync_example/main/mcpwm_sync_example.c -examples/peripherals/pcnt/pulse_count_event/main/pcnt_event_example_main.c -examples/peripherals/pcnt/rotary_encoder/components/rotary_encoder/include/rotary_encoder.h -examples/peripherals/pcnt/rotary_encoder/components/rotary_encoder/src/rotary_encoder_pcnt_ec11.c -examples/peripherals/pcnt/rotary_encoder/main/rotary_encoder_example_main.c -examples/peripherals/rmt/ir_protocols/components/infrared_tools/include/ir_timings.h -examples/peripherals/rmt/ir_protocols/components/infrared_tools/include/ir_tools.h -examples/peripherals/rmt/ir_protocols/components/infrared_tools/src/ir_builder_rmt_nec.c -examples/peripherals/rmt/ir_protocols/components/infrared_tools/src/ir_builder_rmt_rc5.c -examples/peripherals/rmt/ir_protocols/components/infrared_tools/src/ir_parser_rmt_nec.c -examples/peripherals/rmt/ir_protocols/components/infrared_tools/src/ir_parser_rmt_rc5.c -examples/peripherals/rmt/ir_protocols/example_test.py -examples/peripherals/rmt/ir_protocols/main/ir_protocols_main.c -examples/peripherals/rmt/led_strip/main/led_strip_main.c -examples/peripherals/rmt/morse_code/main/morse_code_main.c -examples/peripherals/rmt/musical_buzzer/components/musical_buzzer/include/musical_buzzer.h -examples/peripherals/rmt/musical_buzzer/components/musical_buzzer/src/musical_buzzer_rmt.c -examples/peripherals/rmt/musical_buzzer/main/musical_buzzer_example_main.c -examples/peripherals/sdio/host/main/app_main.c -examples/peripherals/sdio/sdio_test.py -examples/peripherals/sdio/slave/main/app_main.c -examples/peripherals/secure_element/atecc608_ecdsa/main/ecdsa_example_main.c -examples/peripherals/sigmadelta/main/sigmadelta_example_main.c -examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c -examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.h -examples/peripherals/spi_master/hd_eeprom/main/spi_eeprom_main.c -examples/peripherals/spi_master/lcd/main/decode_image.c -examples/peripherals/spi_master/lcd/main/decode_image.h -examples/peripherals/spi_master/lcd/main/pretty_effect.c -examples/peripherals/spi_master/lcd/main/pretty_effect.h -examples/peripherals/spi_master/lcd/main/spi_master_example_main.c -examples/peripherals/spi_slave/receiver/main/app_main.c -examples/peripherals/spi_slave/sender/main/app_main.c -examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c -examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c -examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c -examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c -examples/peripherals/temp_sensor/main/temp_sensor_main.c -examples/peripherals/timer_group/example_test.py -examples/peripherals/timer_group/main/timer_group_example_main.c -examples/peripherals/touch_element/touch_button/main/touch_button_example_main.c -examples/peripherals/touch_element/touch_element_waterproof/main/waterproof_example_main.c -examples/peripherals/touch_element/touch_elements_combination/main/touch_elements_example_main.c -examples/peripherals/touch_element/touch_matrix/main/touch_matrix_example_main.c -examples/peripherals/touch_element/touch_slider/main/touch_slider_example_main.c -examples/peripherals/touch_pad_interrupt/main/esp32/tp_interrupt_main.c -examples/peripherals/touch_pad_interrupt/main/esp32s2/tp_interrupt_main.c -examples/peripherals/touch_pad_read/main/esp32/tp_read_main.c -examples/peripherals/touch_pad_read/main/esp32s2/tp_read_main.c -examples/peripherals/twai/twai_alert_and_recovery/example_test.py -examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c -examples/peripherals/twai/twai_network/example_test.py -examples/peripherals/twai/twai_network/twai_network_listen_only/main/twai_network_example_listen_only_main.c -examples/peripherals/twai/twai_network/twai_network_master/main/twai_network_example_master_main.c -examples/peripherals/twai/twai_network/twai_network_slave/main/twai_network_example_slave_main.c -examples/peripherals/twai/twai_self_test/example_test.py -examples/peripherals/twai/twai_self_test/main/twai_self_test_example_main.c -examples/peripherals/uart/nmea0183_parser/main/nmea_parser.c -examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h -examples/peripherals/uart/nmea0183_parser/main/nmea_parser_example_main.c -examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c -examples/peripherals/uart/uart_echo/main/uart_echo_example_main.c -examples/peripherals/uart/uart_echo_rs485/main/rs485_example.c -examples/peripherals/uart/uart_events/main/uart_events_example_main.c -examples/peripherals/uart/uart_repl/main/uart_repl_example_main.c -examples/peripherals/uart/uart_select/main/uart_select_example_main.c -examples/peripherals/usb/tusb_console/main/tusb_console_main.c -examples/peripherals/usb/tusb_sample_descriptor/main/tusb_sample_descriptor_main.c -examples/peripherals/usb/tusb_serial_device/main/tusb_serial_device_main.c -examples/peripherals/wave_gen/main/wave_gen_example_main.c -examples/protocols/asio/asio_chat/example_test.py -examples/protocols/asio/asio_chat/main/asio_chat.cpp -examples/protocols/asio/asio_chat/main/chat_message.hpp -examples/protocols/asio/asio_chat/main/client.hpp -examples/protocols/asio/asio_chat/main/server.hpp -examples/protocols/asio/ssl_client_server/example_test.py -examples/protocols/asio/ssl_client_server/main/asio_ssl_main.cpp -examples/protocols/asio/tcp_echo_server/asio_tcp_server_test.py -examples/protocols/asio/tcp_echo_server/main/echo_server.cpp -examples/protocols/asio/udp_echo_server/asio_udp_server_test.py -examples/protocols/asio/udp_echo_server/main/udp_echo_server.cpp -examples/protocols/cbor/example_test.py -examples/protocols/cbor/main/cbor_example_main.c -examples/protocols/coap_client/main/coap_client_example_main.c -examples/protocols/coap_server/main/coap_server_example_main.c -examples/protocols/esp_http_client/esp_http_client_test.py -examples/protocols/esp_http_client/main/esp_http_client_example.c -examples/protocols/esp_local_ctrl/example_test.py -examples/protocols/esp_local_ctrl/main/app_main.c -examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c -examples/protocols/esp_local_ctrl/scripts/esp_local_ctrl.py -examples/protocols/esp_local_ctrl/scripts/proto_lc.py -examples/protocols/http2_request/components/sh2lib/sh2lib.c -examples/protocols/http2_request/components/sh2lib/sh2lib.h -examples/protocols/http2_request/example_test.py -examples/protocols/http2_request/main/http2_request_example_main.c -examples/protocols/http_request/example_test.py -examples/protocols/http_request/main/http_request_example_main.c -examples/protocols/http_server/advanced_tests/http_server_advanced_test.py -examples/protocols/http_server/advanced_tests/main/include/tests.h -examples/protocols/http_server/advanced_tests/main/main.c -examples/protocols/http_server/advanced_tests/main/tests.c -examples/protocols/http_server/advanced_tests/scripts/test.py -examples/protocols/http_server/captive_portal/example_test.py -examples/protocols/http_server/captive_portal/main/dns_server.c -examples/protocols/http_server/captive_portal/main/include/dns_server.h -examples/protocols/http_server/captive_portal/main/main.c -examples/protocols/http_server/file_serving/http_server_file_serving_test.py -examples/protocols/http_server/file_serving/main/file_server.c -examples/protocols/http_server/file_serving/main/main.c -examples/protocols/http_server/persistent_sockets/http_server_persistence_test.py -examples/protocols/http_server/persistent_sockets/main/main.c -examples/protocols/http_server/restful_server/main/esp_rest_main.c -examples/protocols/http_server/restful_server/main/rest_server.c -examples/protocols/http_server/simple/http_server_simple_test.py -examples/protocols/http_server/simple/main/main.c -examples/protocols/http_server/ws_echo_server/main/ws_echo_server.c -examples/protocols/http_server/ws_echo_server/ws_server_example_test.py -examples/protocols/https_mbedtls/example_test.py -examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c -examples/protocols/https_request/example_test.py -examples/protocols/https_request/main/https_request_example_main.c -examples/protocols/https_server/simple/example_test.py -examples/protocols/https_server/simple/main/main.c -examples/protocols/https_server/wss_server/main/keep_alive.c -examples/protocols/https_server/wss_server/main/keep_alive.h -examples/protocols/https_server/wss_server/main/wss_server_example.c -examples/protocols/https_server/wss_server/wss_server_example_test.py -examples/protocols/https_x509_bundle/example_test.py -examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c -examples/protocols/icmp_echo/example_test.py -examples/protocols/icmp_echo/main/echo_example_main.c -examples/protocols/mdns/main/mdns_example_main.c -examples/protocols/mdns/mdns_example_test.py -examples/protocols/modbus/mb_example_common/include/modbus_params.h -examples/protocols/modbus/mb_example_common/modbus_params.c -examples/protocols/modbus/serial/example_test.py -examples/protocols/modbus/serial/mb_master/main/master.c -examples/protocols/modbus/serial/mb_slave/main/slave.c -examples/protocols/modbus/tcp/example_test.py -examples/protocols/modbus/tcp/mb_tcp_master/main/tcp_master.c -examples/protocols/modbus/tcp/mb_tcp_slave/main/tcp_slave.c -examples/protocols/mqtt/ssl/main/app_main.c -examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py -examples/protocols/mqtt/ssl_ds/configure_ds.py -examples/protocols/mqtt/ssl_ds/main/app_main.c -examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c -examples/protocols/mqtt/ssl_psk/main/app_main.c -examples/protocols/mqtt/tcp/main/app_main.c -examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py -examples/protocols/mqtt/ws/main/app_main.c -examples/protocols/mqtt/ws/mqtt_ws_example_test.py -examples/protocols/mqtt/wss/main/app_main.c -examples/protocols/mqtt/wss/mqtt_wss_example_test.py -examples/protocols/openssl_client/example_test.py -examples/protocols/openssl_client/main/openssl_client_example.h -examples/protocols/openssl_client/main/openssl_client_example_main.c -examples/protocols/openssl_server/example_test.py -examples/protocols/openssl_server/main/openssl_server_example.h -examples/protocols/openssl_server/main/openssl_server_example_main.c -examples/protocols/pppos_client/components/modem/include/bg96.h -examples/protocols/pppos_client/components/modem/include/esp_modem.h -examples/protocols/pppos_client/components/modem/include/esp_modem_compat.h -examples/protocols/pppos_client/components/modem/include/esp_modem_dce.h -examples/protocols/pppos_client/components/modem/include/esp_modem_dce_service.h -examples/protocols/pppos_client/components/modem/include/esp_modem_dte.h -examples/protocols/pppos_client/components/modem/include/esp_modem_netif.h -examples/protocols/pppos_client/components/modem/include/sim7600.h -examples/protocols/pppos_client/components/modem/include/sim800.h -examples/protocols/pppos_client/components/modem/src/bg96.c -examples/protocols/pppos_client/components/modem/src/esp_modem_compat.c -examples/protocols/pppos_client/components/modem/src/esp_modem_dce_service.c -examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c -examples/protocols/pppos_client/components/modem/src/sim7600.c -examples/protocols/pppos_client/components/modem/src/sim800.c -examples/protocols/pppos_client/example_test.py -examples/protocols/pppos_client/main/pppos_client_main.c -examples/protocols/slip/slip_udp/components/slip_modem/include/slip_modem.h -examples/protocols/slip/slip_udp/components/slip_modem/library/slip_modem.c -examples/protocols/slip/slip_udp/main/slip_client_main.c -examples/protocols/smtp_client/main/smtp_client_example_main.c -examples/protocols/sntp/example_test.py -examples/protocols/sntp/main/sntp_example_main.c -examples/protocols/sockets/non_blocking/example_test.py -examples/protocols/sockets/non_blocking/main/non_blocking_socket_example.c -examples/protocols/sockets/tcp_client/example_test.py -examples/protocols/sockets/tcp_client/main/tcp_client.c -examples/protocols/sockets/tcp_client_multi_net/main/tcp_client_multiple.c -examples/protocols/sockets/tcp_server/example_test.py -examples/protocols/sockets/tcp_server/main/tcp_server.c -examples/protocols/sockets/udp_client/example_test.py -examples/protocols/sockets/udp_client/main/udp_client.c -examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c -examples/protocols/sockets/udp_server/example_test.py -examples/protocols/sockets/udp_server/main/udp_server.c -examples/protocols/static_ip/main/static_ip_example_main.c -examples/protocols/websocket/example_test.py -examples/protocols/websocket/main/websocket_example.c -examples/provisioning/legacy/ble_prov/ble_prov_test.py -examples/provisioning/legacy/ble_prov/main/app_main.c -examples/provisioning/legacy/ble_prov/main/app_prov.c -examples/provisioning/legacy/ble_prov/main/app_prov.h -examples/provisioning/legacy/ble_prov/main/app_prov_handlers.c -examples/provisioning/legacy/console_prov/main/app_main.c -examples/provisioning/legacy/console_prov/main/app_prov.c -examples/provisioning/legacy/console_prov/main/app_prov.h -examples/provisioning/legacy/console_prov/main/app_prov_handlers.c -examples/provisioning/legacy/custom_config/components/custom_provisioning/include/custom_provisioning/custom_config.h -examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.c -examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.h -examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py -examples/provisioning/legacy/custom_config/components/custom_provisioning/src/custom_config.c -examples/provisioning/legacy/custom_config/main/app_main.c -examples/provisioning/legacy/custom_config/main/app_prov.c -examples/provisioning/legacy/custom_config/main/app_prov.h -examples/provisioning/legacy/custom_config/main/app_prov_handlers.c -examples/provisioning/legacy/softap_prov/main/app_main.c -examples/provisioning/legacy/softap_prov/main/app_prov.c -examples/provisioning/legacy/softap_prov/main/app_prov.h -examples/provisioning/legacy/softap_prov/main/app_prov_handlers.c -examples/provisioning/legacy/softap_prov/softap_prov_test.py -examples/provisioning/wifi_prov_mgr/main/app_main.c -examples/provisioning/wifi_prov_mgr/wifi_prov_mgr_test.py -examples/security/flash_encryption/example_test.py -examples/security/flash_encryption/main/flash_encrypt_main.c -examples/storage/custom_flash_driver/components/custom_chip_driver/chip_drivers.c -examples/storage/custom_flash_driver/components/custom_chip_driver/spi_flash_chip_eon.c -examples/storage/custom_flash_driver/main/main.c -examples/storage/ext_flash_fatfs/example_test.py -examples/storage/ext_flash_fatfs/main/ext_flash_fatfs_example_main.c -examples/storage/nvs_rw_blob/main/nvs_blob_example_main.c -examples/storage/nvs_rw_blob/nvs_rw_blob_example_test.py -examples/storage/nvs_rw_value/main/nvs_value_example_main.c -examples/storage/nvs_rw_value/nvs_rw_value_example_test.py -examples/storage/nvs_rw_value_cxx/main/nvs_value_example_main.cpp -examples/storage/nvs_rw_value_cxx/nvs_rw_value_cxx_example_test.py -examples/storage/partition_api/partition_find/main/main.c -examples/storage/partition_api/partition_find/partition_find_example_test.py -examples/storage/partition_api/partition_mmap/main/main.c -examples/storage/partition_api/partition_mmap/partition_mmap_example_test.py -examples/storage/partition_api/partition_ops/main/main.c -examples/storage/partition_api/partition_ops/partition_ops_example_test.py -examples/storage/parttool/example_test.py -examples/storage/parttool/main/parttool_main.c -examples/storage/parttool/parttool_example.py -examples/storage/sd_card/sdmmc/main/sd_card_example_main.c -examples/storage/sd_card/sdmmc/sd_card_example_test.py -examples/storage/sd_card/sdspi/main/sd_card_example_main.c -examples/storage/sd_card/sdspi/sd_card_example_test.py -examples/storage/semihost_vfs/main/semihost_vfs_example_main.c -examples/storage/semihost_vfs/semihost_vfs_example_test.py -examples/storage/spiffs/main/spiffs_example_main.c -examples/storage/spiffs/spiffs_example_test.py -examples/storage/spiffsgen/example_test.py -examples/storage/spiffsgen/main/spiffsgen_example_main.c -examples/storage/wear_levelling/main/wear_levelling_example_main.c -examples/storage/wear_levelling/wear_levelling_example_test.py -examples/system/app_trace_to_host/example_test.py -examples/system/app_trace_to_host/main/app_trace_to_host_example_main.c -examples/system/base_mac_address/example_test.py -examples/system/base_mac_address/main/base_mac_address_example_main.c -examples/system/console/advanced/components/cmd_nvs/cmd_nvs.c -examples/system/console/advanced/components/cmd_nvs/cmd_nvs.h -examples/system/console/advanced/components/cmd_system/cmd_system.c -examples/system/console/advanced/components/cmd_system/cmd_system.h -examples/system/console/advanced/example_test.py -examples/system/console/advanced/main/cmd_decl.h -examples/system/console/advanced/main/cmd_wifi.c -examples/system/console/advanced/main/cmd_wifi.h -examples/system/console/advanced/main/console_example_main.c -examples/system/console/basic/example_test.py -examples/system/console/basic/main/cmd_decl.h -examples/system/console/basic/main/cmd_wifi.c -examples/system/console/basic/main/cmd_wifi.h -examples/system/console/basic/main/console_example_main.c -examples/system/console_usb/main/console_usb_example_main.c -examples/system/deep_sleep/example_test.py -examples/system/deep_sleep/main/deep_sleep_example_main.c -examples/system/efuse/example_test.py -examples/system/efuse/main/efuse_main.c -examples/system/efuse/main/esp_efuse_custom_table.c -examples/system/efuse/main/include/esp_efuse_custom_table.h -examples/system/esp_event/default_event_loop/example_test.py -examples/system/esp_event/default_event_loop/main/event_source.h -examples/system/esp_event/default_event_loop/main/main.c -examples/system/esp_event/user_event_loops/example_test.py -examples/system/esp_event/user_event_loops/main/event_source.h -examples/system/esp_event/user_event_loops/main/main.c -examples/system/esp_timer/example_test.py -examples/system/esp_timer/main/esp_timer_example_main.c -examples/system/eventfd/example_test.py -examples/system/eventfd/main/eventfd_example.c -examples/system/freertos/real_time_stats/example_test.py -examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c -examples/system/gcov/components/sample/some_funcs.c -examples/system/gcov/example_test.py -examples/system/gcov/main/gcov_example_func.c -examples/system/gcov/main/gcov_example_main.c -examples/system/gdbstub/main/gdbstub_main.c -examples/system/heap_task_tracking/main/heap_task_tracking_main.c -examples/system/himem/example_test.py -examples/system/himem/main/himem_example_main.c -examples/system/ipc/ipc_isr/example_test.py -examples/system/ipc/ipc_isr/main/main.c -examples/system/light_sleep/example_test.py -examples/system/light_sleep/main/light_sleep_example_main.c -examples/system/ota/advanced_https_ota/example_test.py -examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c -examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c -examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c -examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h -examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h -examples/system/ota/advanced_https_ota/main/ble_helper/include/nimble_gatts.h -examples/system/ota/advanced_https_ota/main/ble_helper/nimble_gatts.c -examples/system/ota/native_ota_example/example_test.py -examples/system/ota/native_ota_example/main/native_ota_example.c -examples/system/ota/otatool/example_test.py -examples/system/ota/otatool/get_running_partition.py -examples/system/ota/otatool/main/otatool_main.c -examples/system/ota/otatool/otatool_example.py -examples/system/ota/simple_ota_example/example_test.py -examples/system/ota/simple_ota_example/main/simple_ota_example.c -examples/system/perfmon/example_test.py -examples/system/perfmon/main/perfmon_example_main.c -examples/system/pthread/example_test.py -examples/system/pthread/main/pthread_example.c -examples/system/select/example_test.py -examples/system/select/main/select_example.c -examples/system/startup_time/example_test.py -examples/system/startup_time/main/hello_world_main.c -examples/system/sysview_tracing/example_test.py -examples/system/sysview_tracing/main/sysview_tracing.c -examples/system/sysview_tracing_heap_log/example_test.py -examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c -examples/system/task_watchdog/example_test.py -examples/system/task_watchdog/main/task_watchdog_example_main.c -examples/system/ulp_fsm/ulp/example_test.py -examples/system/ulp_fsm/ulp/main/ulp_example_main.c -examples/system/ulp_fsm/ulp_adc/example_test.py -examples/system/ulp_fsm/ulp_adc/main/ulp_adc_example_main.c -examples/system/ulp_riscv/ds18b20_onewire/main/ulp/main.c -examples/system/ulp_riscv/ds18b20_onewire/main/ulp_riscv_ds18b20_example_main.c -examples/system/ulp_riscv/gpio/example_test.py -examples/system/ulp_riscv/gpio/main/ulp/main.c -examples/system/ulp_riscv/gpio/main/ulp_riscv_example_main.c -examples/system/unit_test/components/testable/include/testable.h -examples/system/unit_test/components/testable/mean.c -examples/system/unit_test/components/testable/test/test_mean.c -examples/system/unit_test/example_test.py -examples/system/unit_test/main/example_unit_test_main.c -examples/system/unit_test/test/main/example_unit_test_test.c -examples/wifi/espnow/main/espnow_example.h -examples/wifi/espnow/main/espnow_example_main.c -examples/wifi/fast_scan/main/fast_scan.c -examples/wifi/ftm/main/ftm_main.c -examples/wifi/getting_started/softAP/main/softap_example_main.c -examples/wifi/getting_started/station/main/station_example_main.c -examples/wifi/iperf/iperf_test.py -examples/wifi/iperf/main/cmd_decl.h -examples/wifi/iperf/main/cmd_wifi.c -examples/wifi/iperf/main/cmd_wifi.h -examples/wifi/iperf/main/iperf_example_main.c -examples/wifi/power_save/main/power_save.c -examples/wifi/roaming/main/roaming_example.c -examples/wifi/scan/main/scan.c -examples/wifi/smart_config/main/smartconfig_main.c -examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c -examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c -examples/wifi/wps/main/wps.c -tools/ble/lib_ble_client.py -tools/ble/lib_gap.py -tools/ble/lib_gatt.py -tools/build_apps.py -tools/catch/catch.hpp -tools/check_python_dependencies.py -tools/check_term.py -tools/ci/check_artifacts_expire_time.py -tools/ci/check_build_warnings.py -tools/ci/check_callgraph.py -tools/ci/check_codeowners.py -tools/ci/check_deprecated_kconfigs.py -tools/ci/check_examples_cmake_make.py -tools/ci/check_executables.py -tools/ci/check_kconfigs.py -tools/ci/check_public_headers.py -tools/ci/check_readme_links.py -tools/ci/check_rules_yml.py -tools/ci/check_soc_struct_headers.py -tools/ci/check_tools_files_patterns.py -tools/ci/check_type_comments.py -tools/ci/checkout_project_ref.py -tools/ci/ci_fetch_submodule.py -tools/ci/ci_get_mr_info.py -tools/ci/deploy_docs.py -tools/ci/envsubst.py -tools/ci/idf_ci_utils.py -tools/ci/python_packages/gitlab_api.py -tools/ci/python_packages/idf_http_server_test/adder.py -tools/ci/python_packages/idf_http_server_test/client.py -tools/ci/python_packages/idf_http_server_test/test.py -tools/ci/python_packages/idf_iperf_test_util/Attenuator.py -tools/ci/python_packages/idf_iperf_test_util/IperfUtility.py -tools/ci/python_packages/idf_iperf_test_util/LineChart.py -tools/ci/python_packages/idf_iperf_test_util/PowerControl.py -tools/ci/python_packages/idf_iperf_test_util/TestReport.py -tools/ci/python_packages/tiny_test_fw/App.py -tools/ci/python_packages/tiny_test_fw/DUT.py -tools/ci/python_packages/tiny_test_fw/Env.py -tools/ci/python_packages/tiny_test_fw/EnvConfig.py -tools/ci/python_packages/tiny_test_fw/TinyFW.py -tools/ci/python_packages/tiny_test_fw/Utility/CIAssignTest.py -tools/ci/python_packages/tiny_test_fw/Utility/CaseConfig.py -tools/ci/python_packages/tiny_test_fw/Utility/GitlabCIJob.py -tools/ci/python_packages/tiny_test_fw/Utility/SearchCases.py -tools/ci/python_packages/tiny_test_fw/Utility/TestCase.py -tools/ci/python_packages/tiny_test_fw/Utility/__init__.py -tools/ci/python_packages/tiny_test_fw/bin/Runner.py -tools/ci/python_packages/tiny_test_fw/bin/example.py -tools/ci/python_packages/tiny_test_fw/docs/conf.py -tools/ci/python_packages/ttfw_idf/CIScanTests.py -tools/ci/python_packages/ttfw_idf/DebugUtils.py -tools/ci/python_packages/ttfw_idf/IDFApp.py -tools/ci/python_packages/ttfw_idf/IDFAssignTest.py -tools/ci/python_packages/ttfw_idf/IDFDUT.py -tools/ci/python_packages/ttfw_idf/__init__.py -tools/ci/python_packages/ttfw_idf/unity_test_parser.py -tools/ci/python_packages/wifi_tools.py -tools/ci/test_autocomplete.py -tools/ci/test_check_kconfigs.py -tools/cmake/convert_to_cmake.py -tools/esp_app_trace/espytrace/apptrace.py -tools/esp_app_trace/espytrace/sysview.py -tools/esp_app_trace/logtrace_proc.py -tools/esp_app_trace/sysviewtrace_proc.py -tools/esp_app_trace/test/sysview/blink.c -tools/esp_prov/__init__.py -tools/esp_prov/esp_prov.py -tools/esp_prov/proto/__init__.py -tools/esp_prov/prov/__init__.py -tools/esp_prov/prov/custom_prov.py -tools/esp_prov/prov/wifi_prov.py -tools/esp_prov/prov/wifi_scan.py -tools/esp_prov/security/__init__.py -tools/esp_prov/security/security.py -tools/esp_prov/security/security0.py -tools/esp_prov/security/security1.py -tools/esp_prov/transport/__init__.py -tools/esp_prov/transport/ble_cli.py -tools/esp_prov/transport/transport.py -tools/esp_prov/transport/transport_ble.py -tools/esp_prov/transport/transport_console.py -tools/esp_prov/transport/transport_http.py -tools/esp_prov/utils/__init__.py -tools/esp_prov/utils/convenience.py -tools/find_apps.py -tools/find_build_apps/__init__.py -tools/find_build_apps/cmake.py -tools/find_build_apps/common.py -tools/find_build_apps/make.py -tools/gdb_panic_server.py -tools/gen_esp_err_to_name.py -tools/idf_monitor.py -tools/idf_monitor_base/ansi_color_converter.py -tools/idf_monitor_base/argument_parser.py -tools/idf_monitor_base/chip_specific_config.py -tools/idf_monitor_base/console_parser.py -tools/idf_monitor_base/console_reader.py -tools/idf_monitor_base/constants.py -tools/idf_monitor_base/coredump.py -tools/idf_monitor_base/exceptions.py -tools/idf_monitor_base/gdbhelper.py -tools/idf_monitor_base/line_matcher.py -tools/idf_monitor_base/logger.py -tools/idf_monitor_base/output_helpers.py -tools/idf_monitor_base/serial_handler.py -tools/idf_monitor_base/serial_reader.py -tools/idf_monitor_base/stoppable_thread.py -tools/idf_monitor_base/web_socket_client.py -tools/idf_py_actions/constants.py -tools/idf_py_actions/core_ext.py -tools/idf_py_actions/create_ext.py -tools/idf_py_actions/debug_ext.py -tools/idf_py_actions/dfu_ext.py -tools/idf_py_actions/errors.py -tools/idf_py_actions/global_options.py -tools/idf_py_actions/serial_ext.py -tools/idf_py_actions/tools.py -tools/idf_py_actions/uf2_ext.py -tools/kconfig/conf.c -tools/kconfig/confdata.c -tools/kconfig/expand_env.c -tools/kconfig/expand_env.h -tools/kconfig/expr.c -tools/kconfig/expr.h -tools/kconfig/gconf.c -tools/kconfig/images.c -tools/kconfig/kxgettext.c -tools/kconfig/list.h -tools/kconfig/lkc.h -tools/kconfig/lkc_proto.h -tools/kconfig/lxdialog/checklist.c -tools/kconfig/lxdialog/dialog.h -tools/kconfig/lxdialog/inputbox.c -tools/kconfig/lxdialog/menubox.c -tools/kconfig/lxdialog/textbox.c -tools/kconfig/lxdialog/util.c -tools/kconfig/lxdialog/yesno.c -tools/kconfig/mconf.c -tools/kconfig/menu.c -tools/kconfig/nconf.c -tools/kconfig/nconf.gui.c -tools/kconfig/nconf.h -tools/kconfig/qconf.h -tools/kconfig/symbol.c -tools/kconfig/util.c -tools/kconfig_new/confgen.py -tools/kconfig_new/confserver.py -tools/kconfig_new/esp-windows-curses/setup.py -tools/kconfig_new/gen_kconfig_doc.py -tools/kconfig_new/prepare_kconfig_files.py -tools/kconfig_new/test/confgen/test_confgen.py -tools/kconfig_new/test/confserver/test_confserver.py -tools/kconfig_new/test/gen_kconfig_doc/test_kconfig_out.py -tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py -tools/ldgen/entity.py -tools/ldgen/fragments.py -tools/ldgen/generation.py -tools/ldgen/ldgen.py -tools/ldgen/ldgen_common.py -tools/ldgen/linker_script.py -tools/ldgen/output_commands.py -tools/ldgen/samples/template.ld -tools/ldgen/sdkconfig.py -tools/ldgen/test/data/linker_script.ld -tools/ldgen/test/test_entity.py -tools/ldgen/test/test_fragments.py -tools/ldgen/test/test_generation.py -tools/ldgen/test/test_output_commands.py -tools/mass_mfg/mfg_gen.py -tools/mkdfu.py -tools/mkuf2.py -tools/mocks/esp_system/include/esp_task.h -tools/templates/sample_component/include/main.h -tools/templates/sample_component/main.c -tools/test_apps/build_system/embed_test/main/test_main.c -tools/test_apps/build_system/ldalign_test/check_alignment.py -tools/test_apps/build_system/ldalign_test/main/test_main.c -tools/test_apps/build_system/ldgen_test/check_placements.py -tools/test_apps/build_system/ldgen_test/main/src1.c -tools/test_apps/build_system/ldgen_test/main/src2.c -tools/test_apps/build_system/ldgen_test/main/test_main.c -tools/test_apps/build_system/rsource_test/main/test_main.c -tools/test_apps/peripherals/i2c_wifi/app_test.py -tools/test_apps/peripherals/i2c_wifi/main/i2c_wifi_main.c -tools/test_apps/protocols/esp_netif/build_config/main/init_macro.h -tools/test_apps/protocols/esp_netif/build_config/main/main.cpp -tools/test_apps/protocols/esp_netif/build_config/main/netif_init_c99.c -tools/test_apps/protocols/esp_netif/build_config/main/netif_init_cpp.cpp -tools/test_apps/protocols/mqtt/build_test/main/mqtt_app.cpp -tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py -tools/test_apps/protocols/mqtt/publish_connect_test/main/connect_test.c -tools/test_apps/protocols/mqtt/publish_connect_test/main/publish_connect_test.c -tools/test_apps/protocols/mqtt/publish_connect_test/main/publish_test.c -tools/test_apps/protocols/openssl/app_test.py -tools/test_apps/protocols/openssl/main/connect_test.c -tools/test_apps/protocols/openssl/main/main.c -tools/test_apps/protocols/pppos/app_test.py -tools/test_apps/protocols/pppos/main/null_dce.c -tools/test_apps/protocols/pppos/main/null_dce.h -tools/test_apps/protocols/pppos/main/pppos_client_main.c -tools/test_apps/security/secure_boot/example_test.py -tools/test_apps/security/secure_boot/main/secure_boot_main.c -tools/test_apps/security/secure_boot/main/secure_boot_main_esp32.c -tools/test_apps/system/bootloader_sections/main/test_main.c -tools/test_apps/system/build_test/main/test_main.c -tools/test_apps/system/cxx_no_except/main/main.cpp -tools/test_apps/system/gdb_loadable_elf/app_test.py -tools/test_apps/system/gdb_loadable_elf/main/hello_world_main.c -tools/test_apps/system/longjmp_test/app_test.py -tools/test_apps/system/longjmp_test/main/hello_world_main.c -tools/test_apps/system/memprot/app_test.py -tools/test_apps/system/memprot/main/esp32c3/test_memprot_main.c -tools/test_apps/system/memprot/main/esp32c3/test_panic.c -tools/test_apps/system/memprot/main/esp32s2/test_memprot_main.c -tools/test_apps/system/memprot/main/esp32s2/test_panic.c -tools/test_apps/system/monitor_ide_integration/app_test.py -tools/test_apps/system/monitor_ide_integration/main/main.c -tools/test_apps/system/no_embedded_paths/check_for_file_paths.py -tools/test_apps/system/no_embedded_paths/main/test_no_embedded_paths_main.c -tools/test_apps/system/panic/app_test.py -tools/test_apps/system/panic/main/test_panic_main.c -tools/test_apps/system/panic/panic_tests.py -tools/test_apps/system/panic/test_panic_util/test_panic_util.py -tools/test_apps/system/startup/app_test.py -tools/test_apps/system/startup/main/chip_info_patch.c -tools/test_apps/system/startup/main/test_startup_main.c -tools/test_idf_monitor/dummy.c -tools/test_idf_monitor/idf_monitor_wrapper.py -tools/test_idf_monitor/run_test_idf_monitor.py -tools/test_idf_py/extra_path/some_ext.py -tools/test_idf_py/idf_ext.py -tools/test_idf_py/test_idf_extensions/test_ext/__init__.py -tools/test_idf_py/test_idf_extensions/test_ext/test_extension.py -tools/test_idf_py/test_idf_py.py -tools/test_idf_size/test_idf_size.py -tools/test_idf_tools/test_idf_tools.py -tools/test_mkdfu/test_mkdfu.py -tools/test_mkuf2/test_mkuf2.py -tools/unit-test-app/components/test_utils/ccomp_timer.c -tools/unit-test-app/components/test_utils/ccomp_timer_impl_riscv.c -tools/unit-test-app/components/test_utils/ccomp_timer_impl_xtensa.c -tools/unit-test-app/components/test_utils/include/ccomp_timer.h -tools/unit-test-app/components/test_utils/include/test_utils.h -tools/unit-test-app/components/test_utils/private_include/ccomp_timer_impl.h -tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c -tools/unit-test-app/components/test_utils/ref_clock_impl_timergroup.c -tools/unit-test-app/components/test_utils/test/ccomp_timer_test_api.c -tools/unit-test-app/components/test_utils/test/ccomp_timer_test_data.c -tools/unit-test-app/components/test_utils/test/ccomp_timer_test_inst.c -tools/unit-test-app/components/test_utils/test_runner.c -tools/unit-test-app/components/test_utils/test_utils.c -tools/unit-test-app/idf_ext.py -tools/unit-test-app/main/app_main.c -tools/unit-test-app/tools/CreateSectionTable.py -tools/unit-test-app/tools/UnitTestParser.py -tools/unit-test-app/unit_test.py -tools/windows/eclipse_make.py -tools/windows/idf_exe/idf_main.c diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index e38e07564b1d..8de30a30f244 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -38,6 +38,7 @@ components/spi_flash/include/spi_flash_chip_mxic.h components/spi_flash/include/spi_flash_chip_gd.h components/spi_flash/include/spi_flash_chip_winbond.h components/spi_flash/include/spi_flash_chip_boya.h +components/spi_flash/include/spi_flash_chip_th.h components/spi_flash/include/memspi_host_driver.h components/spi_flash/include/spi_flash_chip_driver.h components/spi_flash/include/spi_flash_chip_generic.h @@ -49,6 +50,7 @@ components/wpa_supplicant/port/ components/mbedtls/port/include/ components/mbedtls/mbedtls/include/mbedtls/ +components/mbedtls/mbedtls/include/psa/ components/coap/ components/nghttp/ diff --git a/tools/ci/config/assign-test.yml b/tools/ci/config/assign-test.yml index e603460e213f..40e3cfe875dc 100644 --- a/tools/ci/config/assign-test.yml +++ b/tools/ci/config/assign-test.yml @@ -9,6 +9,7 @@ assign_test: # we have a lot build example jobs. now we don't use dependencies, just download all artifacts of build stage. dependencies: # Here is not a hard dependency relationship, could be skipped. so we do not use "needs" here. - build_ssc_esp32 + - build_ssc_esp32c3 - build_esp_idf_tests_cmake_esp32 - build_esp_idf_tests_cmake_esp32s2 - build_esp_idf_tests_cmake_esp32c3 @@ -19,7 +20,7 @@ assign_test: UNIT_TEST_DIR: "${CI_PROJECT_DIR}/components/idf_test/unit_test" # COMPONENT_UT_DIRS is set by `set_component_ut_vars` in `utils.sh` COMPONENT_UT_OUTPUT_DIR: "${CI_PROJECT_DIR}/component_ut" - INTEGRATION_CONFIG_OUTPUT_PATH: "${CI_PROJECT_DIR}/components/idf_test/integration_test/CIConfigs" + INTEGRATION_TEST_DIR: "${CI_PROJECT_DIR}/tools/ci/integration_test" INTEGRATION_TEST_CASE_PATH: "${CI_PROJECT_DIR}/auto_test_script/TestCaseFiles" ASSIGN_TEST_CASE_SCRIPT: "${CI_PROJECT_DIR}/auto_test_script/bin/CIAssignTestCases.py" PYTHONPATH: ${CI_PROJECT_DIR}/auto_test_script/packages @@ -31,6 +32,7 @@ assign_test: - $EXAMPLE_TEST_DIR/test_configs - $CUSTOM_TEST_DIR/test_configs - $COMPONENT_UT_OUTPUT_DIR/test_configs + - $INTEGRATION_TEST_DIR/test_configs - build_examples/artifact_index.json - build_test_apps/artifact_index.json - build_component_ut/artifact_index.json @@ -48,7 +50,7 @@ assign_test: - retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH} - python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only # assign integration test cases - - python ${ASSIGN_TEST_CASE_SCRIPT} -t ${INTEGRATION_TEST_CASE_PATH} -c $CI_TARGET_TEST_CONFIG_FILE -b $IDF_PATH/SSC/ssc_bin -o $INTEGRATION_CONFIG_OUTPUT_PATH + - python ${ASSIGN_TEST_CASE_SCRIPT} -t ${INTEGRATION_TEST_CASE_PATH} -c $CI_TARGET_TEST_CONFIG_FILE -b $IDF_PATH/SSC/ssc_bin -o $INTEGRATION_TEST_DIR/test_configs update_test_cases: extends: .rules:ref:master-schedule diff --git a/tools/ci/config/build.yml b/tools/ci/config/build.yml index bd4bbcdd6e02..542b2fc33ddb 100644 --- a/tools/ci/config/build.yml +++ b/tools/ci/config/build.yml @@ -440,7 +440,7 @@ build_template_app: # get all exclude paths specified in tools/ci/sonar_exclude_list.txt | ignore lines start with # | xargs | replace all to - export CUSTOM_EXCLUDES=$(cat $CI_PROJECT_DIR/tools/ci/sonar_exclude_list.txt | grep -v '^#' | xargs | sed -e 's/ /,/g') # Exclude the report dir - - export EXCLUSIONS="$SUBMODULES,$REPORT_DIR/**,docs/_static/**,**/*.png,**/*.jpg" + - export EXCLUSIONS="$CUSTOM_EXCLUDES,$SUBMODULES,$REPORT_DIR/**,docs/_static/**,**/*.png,**/*.jpg" - python $NORMALIZE_CLANGTIDY_PY $CI_PROJECT_DIR/$REPORT_DIR/warnings.txt $CI_PROJECT_DIR/$REPORT_DIR/clang_tidy_report.txt $CI_PROJECT_DIR variables: GIT_DEPTH: 0 diff --git a/tools/ci/config/host-test.yml b/tools/ci/config/host-test.yml index a306767b950b..a62fef2477ff 100644 --- a/tools/ci/config/host-test.yml +++ b/tools/ci/config/host-test.yml @@ -252,12 +252,18 @@ test_espcoredump: artifacts: when: always paths: - - components/espcoredump/test/.coverage - - components/espcoredump/test/output + - components/espcoredump/test/**/.coverage + - components/espcoredump/test/**/output expire_in: 1 week + variables: + IDF_COREDUMP_ELF_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/idf/idf-coredump-elf.git" + IDF_COREDUMP_ELF_TAG: idf-20210915 + # install CMake version specified in tools.json + SETUP_TOOLS_LIST: "all" script: + - retry_failed git clone ${IDF_COREDUMP_ELF_REPO} -b $IDF_COREDUMP_ELF_TAG - cd components/espcoredump/test/ - - ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_espcoredump.sh + - ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_espcoredump.sh ${CI_PROJECT_DIR}/idf-coredump-elf test_logtrace_proc: extends: .host_test_template diff --git a/tools/ci/config/pre_check.yml b/tools/ci/config/pre_check.yml index 4893117b961f..df491d0448b6 100644 --- a/tools/ci/config/pre_check.yml +++ b/tools/ci/config/pre_check.yml @@ -137,11 +137,15 @@ scan_tests: TEST_APPS_TEST_DIR: ${CI_PROJECT_DIR}/tools/test_apps TEST_APPS_OUTPUT_DIR: ${CI_PROJECT_DIR}/tools/test_apps/test_configs COMPONENT_UT_OUTPUT_DIR: ${CI_PROJECT_DIR}/component_ut/test_configs + EXTRA_TEST_DIRS: >- + examples/bluetooth/esp_ble_mesh/ble_mesh_console + examples/bluetooth/hci/controller_hci_uart_esp32 + examples/wifi/iperf PYTHON_VER: 3 script: - set_component_ut_vars - python $CI_SCAN_TESTS_PY example_test $EXAMPLE_TEST_DIR -b make --exclude examples/build_system/idf_as_lib -c $TEST_CONFIG_FILE -o $EXAMPLE_TEST_OUTPUT_DIR - - python $CI_SCAN_TESTS_PY example_test $EXAMPLE_TEST_DIR -b cmake --exclude examples/build_system/idf_as_lib -c $TEST_CONFIG_FILE -o $EXAMPLE_TEST_OUTPUT_DIR + - python $CI_SCAN_TESTS_PY example_test $EXAMPLE_TEST_DIR -b cmake --exclude examples/build_system/idf_as_lib -c $TEST_CONFIG_FILE -o $EXAMPLE_TEST_OUTPUT_DIR --extra_test_dirs $EXTRA_TEST_DIRS - python $CI_SCAN_TESTS_PY test_apps $TEST_APPS_TEST_DIR -c $TEST_CONFIG_FILE -o $TEST_APPS_OUTPUT_DIR - python $CI_SCAN_TESTS_PY component_ut $COMPONENT_UT_DIRS --exclude $COMPONENT_UT_EXCLUDES -c $TEST_CONFIG_FILE -o $COMPONENT_UT_OUTPUT_DIR diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index b8cf186d7090..8afcd80416e8 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -116,14 +116,13 @@ - .rules:tests:integration_test needs: - assign_test - - build_ssc_esp32 variables: LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF" LOG_PATH: "${CI_PROJECT_DIR}/TEST_LOGS" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/auto_test_script/TestCaseFiles" - MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/ModuleDefinition.yml" - CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/components/idf_test/integration_test/CIConfigs" - KNOWN_ISSUE_FILE: "${CI_PROJECT_DIR}/components/idf_test/integration_test/KnownIssues" + INTEGRATION_TEST_DIR: "${CI_PROJECT_DIR}/tools/ci/integration_test" + CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/tools/ci/integration_test/test_configs" + PREPARE_TEST_BIN_SCRIPT: "${CI_PROJECT_DIR}/tools/ci/integration_test/prepare_test_bins.py" CI_RUNNER_SCRIPT: "${CI_PROJECT_DIR}/auto_test_script/bin/CIRunner.py" PYTHONPATH: ${CI_PROJECT_DIR}/auto_test_script/packages # auto_test_script only supports python 3.7.x @@ -140,10 +139,17 @@ - retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch - retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH} - python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only - - cat ${KNOWN_ISSUE_FILE} >> ${TEST_CASE_FILE_PATH}/KnownIssues + - cat ${INTEGRATION_TEST_DIR}/KnownIssues >> ${TEST_CASE_FILE_PATH}/KnownIssues # run test + - python ${PREPARE_TEST_BIN_SCRIPT} $CONFIG_FILE - python ${CI_RUNNER_SCRIPT} -l "$LOG_PATH/$JOB_FULL_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH +.integration_test_esp32c3_template: + extends: + - .integration_test_template + variables: + LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32C3_IDF" + test_weekend_mqtt: extends: - .test_app_template @@ -357,7 +363,7 @@ component_ut_test_001: UT_001: extends: .unit_test_32_template - parallel: 49 + parallel: 50 tags: - ESP32_IDF - UT_T1_1 @@ -366,7 +372,7 @@ UT_001: UT_002: extends: .unit_test_32_template - parallel: 13 + parallel: 14 tags: - ESP32_IDF - UT_T1_1 @@ -573,14 +579,20 @@ UT_046: UT_047: extends: .unit_test_s2_template - parallel: 5 + parallel: 6 tags: - ESP32S2_IDF - UT_T1_1 +UT_048: + extends: .unit_test_32_template + tags: + - ESP32_IDF + - UT_T1_1 + UT_C3: extends: .unit_test_c3_template - parallel: 30 + parallel: 31 tags: - ESP32C3_IDF - UT_T1_1 @@ -632,11 +644,12 @@ nvs_compatible_test: - cd auto_test_script - ./tools/prepare_nvs_bin.sh # run test + - python ${PREPARE_TEST_BIN_SCRIPT} $CONFIG_FILE - python ${CI_RUNNER_SCRIPT} -l "$LOG_PATH/$JOB_FULL_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH IT_001: extends: .integration_test_template - parallel: 3 + parallel: 2 tags: - ESP32_IDF - SSC_T1_4 @@ -649,34 +662,26 @@ IT_002: IT_003: extends: .integration_test_template - parallel: 14 + parallel: 9 tags: - ESP32_IDF - SSC_T2_5 -IT_004: - extends: .integration_test_template - tags: - - ESP32_IDF - - SSC_T1_APC - IT_005: extends: .integration_test_template - parallel: 2 tags: - ESP32_IDF - SSC_T1_5 IT_006: extends: .integration_test_template - parallel: 12 + parallel: 5 tags: - ESP32_IDF - SSC_T1_6 IT_007: extends: .integration_test_template - parallel: 3 tags: - ESP32_IDF - SSC_T1_7 @@ -687,12 +692,6 @@ IT_008: - ESP32_IDF - SSC_T1_8 -IT_009: - extends: .integration_test_template - tags: - - ESP32_IDF - - SSC_T1_3 - IT_011: extends: .integration_test_template tags: @@ -745,7 +744,6 @@ IT_018: IT_019: extends: .integration_test_template - parallel: 2 tags: - ESP32_IDF - SSC_T2_2 @@ -756,8 +754,15 @@ IT_020: - ESP32_IDF - SSC_T2_3 -IT_021: +IT_022: extends: .integration_test_template tags: - ESP32_IDF - - SSC_T2_4 + - SSC_T3_2 + +IT_C3_001: + extends: .integration_test_esp32c3_template + parallel: 5 + tags: + - ESP32C3_IDF + - SSC_T2_5 diff --git a/tools/ci/executable-list.txt b/tools/ci/executable-list.txt index d36e7ef0aa2f..5b1e147164aa 100644 --- a/tools/ci/executable-list.txt +++ b/tools/ci/executable-list.txt @@ -5,6 +5,7 @@ components/esp_wifi/test_md5/test_md5.sh components/espcoredump/espcoredump.py components/espcoredump/test/test_espcoredump.py components/espcoredump/test/test_espcoredump.sh +components/espcoredump/test_apps/build_espcoredump.sh components/heap/test_multi_heap_host/test_all_configs.sh components/mbedtls/esp_crt_bundle/gen_crt_bundle.py components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/test_gen_crt_bundle.py @@ -65,7 +66,6 @@ tools/ci/test_check_kconfigs.py tools/ci/test_configure_ci_environment.sh tools/cmake/convert_to_cmake.py tools/docker/entrypoint.sh -tools/docker/hooks/build tools/esp_app_trace/logtrace_proc.py tools/esp_app_trace/sysviewtrace_proc.py tools/esp_app_trace/test/logtrace/test.sh diff --git a/tools/ci/integration_test/KnownIssues b/tools/ci/integration_test/KnownIssues new file mode 100644 index 000000000000..69141b0abdb2 --- /dev/null +++ b/tools/ci/integration_test/KnownIssues @@ -0,0 +1,3 @@ + +# IDFCI-1067 +ESP32C3.NIMBLE_GAP_14009 diff --git a/tools/ci/integration_test/README.md b/tools/ci/integration_test/README.md new file mode 100644 index 000000000000..b4381d8923cb --- /dev/null +++ b/tools/ci/integration_test/README.md @@ -0,0 +1,17 @@ +# Integration Test Description + +## Case Lists +- WiFi Standard cases for only esp32. +- BLE Standard cases for esp32 and esp32c3. + +## Trigger +- By bot: + - `@bot test with label: integration_test` + +## Bot Filter +- A case filter could be used in `@bot` message: +- For wifi cases: + - `@bot test with label: integration_test; with filter module: WIFI MAC, TCPIP, Mesh, System` +- For bt/ble cases: + - `@bot test with label: integration_test; with filter module: BT Stack, BLUEDROID, BT Profile, NIMBLE` +- use `@bot help` for more details. diff --git a/tools/ci/integration_test/prepare_test_bins.py b/tools/ci/integration_test/prepare_test_bins.py new file mode 100644 index 000000000000..fea2a11cd37e --- /dev/null +++ b/tools/ci/integration_test/prepare_test_bins.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import os + +import gitlab +import gitlab_api +from AutoTestScript.RunnerConfigs.Config import Config + +SSC_BUILD_JOB_MAP = { + 'ESP32': 'build_ssc_esp32', + 'ESP32C3': 'build_ssc_esp32c3', +} +NEEDED_FILES = [ + 'flasher_args.json', + 'bootloader/bootloader.bin', + 'partition_table/partition-table.bin', + 'ssc.bin', + 'ssc.elf', +] +IDF_PATH = os.environ.get('IDF_PATH') + + +def try_to_download_artifacts(bin_path): + ''' + bin_path: "SSC/ssc_bin/ESP32[C3]/SSC[_APP]" + ''' + project_id = os.getenv('CI_PROJECT_ID') + pipeline_id = os.getenv('CI_PIPELINE_ID') + gitlab_inst = gitlab_api.Gitlab(project_id) + build_job_name = SSC_BUILD_JOB_MAP[bin_path.split('/')[-2]] + job_list = gitlab_inst.find_job_id(build_job_name, pipeline_id=pipeline_id) + files_to_download = [os.path.join(bin_path, f) for f in NEEDED_FILES] + for job_info in job_list: + try: + gitlab_inst.download_artifact(job_info['id'], files_to_download, IDF_PATH) + print('Downloaded {} from {}'.format(bin_path, job_info['id'])) + break + except gitlab.exceptions.GitlabError as e: + if e.response_code == 404: + continue + raise + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + 'test_config_file', + help='The test config file to be used.' + ) + args = parser.parse_args() + + configs = Config.parse(args.test_config_file) + test_bin_paths = configs.get_bin_paths() + + for _path in test_bin_paths: + if os.path.exists(_path): + continue + relative_path = os.path.relpath(_path, IDF_PATH) + try_to_download_artifacts(relative_path) + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/CIConfigs/nvs_compatible_test_.yml b/tools/ci/integration_test/test_configs/nvs_compatible_test_.yml similarity index 100% rename from components/idf_test/integration_test/CIConfigs/nvs_compatible_test_.yml rename to tools/ci/integration_test/test_configs/nvs_compatible_test_.yml diff --git a/tools/ci/mypy_ignore_list.txt b/tools/ci/mypy_ignore_list.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/ci/python_packages/gitlab_api.py b/tools/ci/python_packages/gitlab_api.py index 598e76375e6e..b0a9e0a5809f 100644 --- a/tools/ci/python_packages/gitlab_api.py +++ b/tools/ci/python_packages/gitlab_api.py @@ -28,9 +28,16 @@ def wrapper(self, *args, **kwargs): # type: (Gitlab, Any, Any) -> Any try: res = func(self, *args, **kwargs) except (IOError, EOFError, gitlab.exceptions.GitlabError) as e: - if isinstance(e, gitlab.exceptions.GitlabError) and e.response_code != 500: - # Only retry on error 500 - raise e + if isinstance(e, gitlab.exceptions.GitlabError): + if e.response_code == 500: + # retry on this error + pass + elif e.response_code == 404 and os.environ.get('LOCAL_GITLAB_HTTPS_HOST', None): + # remove the environment variable "LOCAL_GITLAB_HTTPS_HOST" and retry + os.environ.pop('LOCAL_GITLAB_HTTPS_HOST', None) + else: + # other GitlabErrors aren't retried + raise e retried += 1 if retried > self.DOWNLOAD_ERROR_MAX_RETRIES: raise e # get out of the loop diff --git a/tools/ci/python_packages/ttfw_idf/CIScanTests.py b/tools/ci/python_packages/ttfw_idf/CIScanTests.py index c1b38f89bb00..08bb1f1d7bfc 100644 --- a/tools/ci/python_packages/ttfw_idf/CIScanTests.py +++ b/tools/ci/python_packages/ttfw_idf/CIScanTests.py @@ -94,7 +94,9 @@ def main(): # type: () -> None help='output path of the scan result') parser.add_argument('--exclude', nargs='*', help='Ignore specified directory. Can be used multiple times.') - parser.add_argument('--preserve', action='store_true', + parser.add_argument('--extra_test_dirs', nargs='*', + help='Additional directories to preserve artifacts for local tests') + parser.add_argument('--preserve_all', action='store_true', help='add this flag to preserve artifacts for all apps') parser.add_argument('--build-all', action='store_true', help='add this flag to build all apps') @@ -116,7 +118,8 @@ def main(): # type: () -> None output_json([], target, args.build_system, args.output_path) SystemExit(0) - paths = set([os.path.join(str(os.getenv('IDF_PATH')), path) if not os.path.isabs(path) else path for path in args.paths]) + idf_path = str(os.getenv('IDF_PATH')) + paths = set([os.path.join(idf_path, path) if not os.path.isabs(path) else path for path in args.paths]) test_cases = [] for path in paths: @@ -126,7 +129,6 @@ def main(): # type: () -> None assign = _TestAppsAssignTest(path, args.ci_config_file) else: raise SystemExit(1) # which is impossible - test_cases.extend(assign.search_cases()) ''' @@ -150,15 +152,16 @@ def main(): # type: () -> None if build_test_case_apps: scan_info_dict[target]['test_case_apps'] = set() + test_dirs = args.extra_test_dirs if args.extra_test_dirs else [] for case in test_cases: - app_dir = case.case_info['app_dir'] - app_target = case.case_info['target'] - if app_target.lower() != target.lower(): - continue + if case.case_info['target'].lower() == target.lower(): + test_dirs.append(case.case_info['app_dir']) + for app_dir in test_dirs: + app_dir = os.path.join(idf_path, app_dir) if not os.path.isabs(app_dir) else app_dir _apps = find_apps(build_system_class, app_dir, True, exclude_apps, target.lower()) if _apps: scan_info_dict[target]['test_case_apps'].update(_apps) - exclude_apps.append(app_dir) + exclude_apps.extend(_apps) else: scan_info_dict[target]['test_case_apps'] = set() @@ -169,7 +172,6 @@ def main(): # type: () -> None find_apps(build_system_class, path, True, exclude_apps, target.lower())) else: scan_info_dict[target]['standalone_apps'] = set() - test_case_apps_preserve_default = True if build_system == 'cmake' else False for target in SUPPORTED_TARGETS: apps = [] @@ -178,14 +180,14 @@ def main(): # type: () -> None 'app_dir': app_dir, 'build_system': args.build_system, 'target': target, - 'preserve': args.preserve or test_case_apps_preserve_default + 'preserve': args.preserve_all or test_case_apps_preserve_default }) for app_dir in scan_info_dict[target]['standalone_apps']: apps.append({ 'app_dir': app_dir, 'build_system': args.build_system, 'target': target, - 'preserve': args.preserve + 'preserve': args.preserve_all }) output_path = os.path.join(args.output_path, 'scan_{}_{}.json'.format(target.lower(), build_system)) with open(output_path, 'w') as fw: diff --git a/tools/ci/sonar_exclude_list.txt b/tools/ci/sonar_exclude_list.txt index c3ac06f2511f..a91e445f5210 100644 --- a/tools/ci/sonar_exclude_list.txt +++ b/tools/ci/sonar_exclude_list.txt @@ -9,3 +9,7 @@ # FreeRTOS upstream code (don't include our port files here) components/freertos/*.c components/freertos/include/freertos/*.h + +# wpa_supplicant upstream code +components/wpa_supplicant/src/** +components/wpa_supplicant/include/** diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index 2931c24d8457..593ca1b8de9f 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -701,20 +701,8 @@ endmenu\n" >> ${IDF_PATH}/Kconfig git checkout CMakeLists.txt rm -f log.txt - print_status "Compiles with dependencies delivered by component manager" - clean_build_dir - # Make sure that component manager is not installed - pip uninstall -y idf_component_manager - printf "\n#include \"test_component.h\"\n" >> main/main.c - printf "dependencies:\n test_component:\n path: test_component\n git: ${COMPONENT_MANAGER_TEST_REPO}\n" >> idf_project.yml - ! idf.py build || failure "Build should fail if dependencies are not installed" - pip install ${COMPONENT_MANAGER_REPO} || failure "Failed to install the component manager" - idf.py reconfigure build || failure "Build didn't succeed with required components installed by package manager" - pip uninstall -y idf_component_manager - rm idf_project.yml - git checkout main/main.c - print_status "Build fails if partitions don't fit in flash" + clean_build_dir sed -i.bak "s/CONFIG_ESPTOOLPY_FLASHSIZE.\+//" sdkconfig # remove all flashsize config echo "CONFIG_ESPTOOLPY_FLASHSIZE_1MB=y" >> sdkconfig # introduce undersize flash ( idf.py build 2>&1 | grep "does not fit in configured flash size 1MB" ) || failure "Build didn't fail with expected flash size failure message" @@ -837,7 +825,6 @@ endmenu\n" >> ${IDF_PATH}/Kconfig rm -rf "$IDF_PATH/example_proj" - print_status "All tests completed" if [ -n "${FAILURES}" ]; then echo "Some failures were detected:" diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index 88fb0a14b05a..12875b46d843 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -143,6 +143,7 @@ function(__build_init idf_path) idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(prefix __PREFIX) file(GLOB component_dirs ${idf_path}/components/*) + list(SORT component_dirs) foreach(component_dir ${component_dirs}) get_filename_component(component_dir ${component_dir} ABSOLUTE) __component_dir_quick_check(is_component ${component_dir}) diff --git a/tools/cmake/component.cmake b/tools/cmake/component.cmake index 47e3f2159498..ae9dcec154b8 100644 --- a/tools/cmake/component.cmake +++ b/tools/cmake/component.cmake @@ -275,6 +275,7 @@ macro(__component_add_sources sources) endif() file(GLOB dir_sources "${abs_dir}/*.c" "${abs_dir}/*.cpp" "${abs_dir}/*.S") + list(SORT dir_sources) if(dir_sources) foreach(src ${dir_sources}) @@ -433,9 +434,8 @@ function(idf_component_register) __component_check_target() __component_add_sources(sources) - # Add component manifest and lock files to list of dependencies + # Add component manifest to the list of dependencies set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${COMPONENT_DIR}/idf_component.yml") - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${COMPONENT_DIR}/dependencies.lock") # Create the final target for the component. This target is the target that is # visible outside the build system. diff --git a/tools/cmake/dfu.cmake b/tools/cmake/dfu.cmake index 45f7470e77fe..e1a13cd064a5 100644 --- a/tools/cmake/dfu.cmake +++ b/tools/cmake/dfu.cmake @@ -25,6 +25,7 @@ function(__add_dfu_targets) -o "${CMAKE_CURRENT_BINARY_DIR}/dfu.bin" --json "${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json" --pid "${dfu_pid}" + --flash-size "${CONFIG_ESPTOOLPY_FLASHSIZE}" DEPENDS gen_project_binary bootloader VERBATIM USES_TERMINAL) diff --git a/tools/cmake/kconfig.cmake b/tools/cmake/kconfig.cmake index 1bf8ab5e9b2c..91dcfb317198 100644 --- a/tools/cmake/kconfig.cmake +++ b/tools/cmake/kconfig.cmake @@ -102,10 +102,13 @@ endfunction() function(__kconfig_component_init component_target) __component_get_property(component_dir ${component_target} COMPONENT_DIR) file(GLOB kconfig "${component_dir}/Kconfig") + list(SORT kconfig) __component_set_property(${component_target} KCONFIG "${kconfig}") file(GLOB kconfig "${component_dir}/Kconfig.projbuild") + list(SORT kconfig) __component_set_property(${component_target} KCONFIG_PROJBUILD "${kconfig}") file(GLOB sdkconfig_rename "${component_dir}/sdkconfig.rename") + list(SORT sdkconfig_rename) __component_set_property(${component_target} SDKCONFIG_RENAME "${sdkconfig_rename}") endfunction() diff --git a/tools/cmake/version.cmake b/tools/cmake/version.cmake index cc29a2011160..a0529308fd84 100644 --- a/tools/cmake/version.cmake +++ b/tools/cmake/version.cmake @@ -1,3 +1,3 @@ set(IDF_VERSION_MAJOR 4) set(IDF_VERSION_MINOR 3) -set(IDF_VERSION_PATCH 2) +set(IDF_VERSION_PATCH 3) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 5cf2ff4ecc64..e46f14cb5954 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -41,20 +41,28 @@ RUN : \ # It is possibe to combine both, e.g.: # IDF_CLONE_BRANCH_OR_TAG=release/vX.Y # IDF_CHECKOUT_REF=. +# Use IDF_CLONE_SHALLOW=1 to peform shallow clone (i.e. --depth=1 --shallow-submodules) +# Use IDF_INSTALL_TARGETS to install tools only for selected chip targets (CSV) ARG IDF_CLONE_URL=https://github.com/espressif/esp-idf.git ARG IDF_CLONE_BRANCH_OR_TAG=master ARG IDF_CHECKOUT_REF= +ARG IDF_CLONE_SHALLOW= +ARG IDF_INSTALL_TARGETS=all ENV IDF_PATH=/opt/esp/idf ENV IDF_TOOLS_PATH=/opt/esp RUN echo IDF_CHECKOUT_REF=$IDF_CHECKOUT_REF IDF_CLONE_BRANCH_OR_TAG=$IDF_CLONE_BRANCH_OR_TAG && \ git clone --recursive \ + ${IDF_CLONE_SHALLOW:+--depth=1 --shallow-submodules} \ ${IDF_CLONE_BRANCH_OR_TAG:+-b $IDF_CLONE_BRANCH_OR_TAG} \ $IDF_CLONE_URL $IDF_PATH && \ if [ -n "$IDF_CHECKOUT_REF" ]; then \ cd $IDF_PATH && \ + if [ -n "$IDF_CLONE_SHALLOW" ]; then \ + git fetch origin --depth=1 --recurse-submodules ${IDF_CHECKOUT_REF}; \ + fi && \ git checkout $IDF_CHECKOUT_REF && \ git submodule update --init --recursive; \ fi @@ -63,7 +71,7 @@ RUN echo IDF_CHECKOUT_REF=$IDF_CHECKOUT_REF IDF_CLONE_BRANCH_OR_TAG=$IDF_CLONE_B ARG CRYPTOGRAPHY_DONT_BUILD_RUST=1 RUN : \ && update-ca-certificates --fresh \ - && $IDF_PATH/tools/idf_tools.py --non-interactive install required \ + && $IDF_PATH/tools/idf_tools.py --non-interactive install required --targets=${IDF_INSTALL_TARGETS} \ && $IDF_PATH/tools/idf_tools.py --non-interactive install cmake \ && $IDF_PATH/tools/idf_tools.py --non-interactive install-python-env \ && rm -rf $IDF_TOOLS_PATH/dist \ diff --git a/tools/docker/hooks/build b/tools/docker/hooks/build deleted file mode 100755 index f98295115d81..000000000000 --- a/tools/docker/hooks/build +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# This file gets executed to build the image on the Docker Hub. -# See https://docs.docker.com/docker-hub/builds/advanced/#build-hook-examples for details. - -set -euo pipefail - -echo "Building for branch ${SOURCE_BRANCH}, commit ${SOURCE_COMMIT}" - -docker build \ - --build-arg IDF_CLONE_BRANCH_OR_TAG=${SOURCE_BRANCH} \ - --build-arg IDF_CHECKOUT_REF=${SOURCE_COMMIT} \ - -f $DOCKERFILE_PATH \ - -t $IMAGE_NAME . diff --git a/tools/esp_prov/proto/__init__.py b/tools/esp_prov/proto/__init__.py index 4c1bd501bfff..4800fd32dc1b 100644 --- a/tools/esp_prov/proto/__init__.py +++ b/tools/esp_prov/proto/__init__.py @@ -13,17 +13,20 @@ # limitations under the License. # +import importlib.util import os - - -def _load_source(name, path): - try: - from importlib.machinery import SourceFileLoader - return SourceFileLoader(name, path).load_module() - except ImportError: - # importlib.machinery doesn't exists in Python 2 so we will use imp (deprecated in Python 3) - import imp - return imp.load_source(name, path) +import sys +from importlib.abc import Loader +from typing import Any + + +def _load_source(name, path): # type: (str, str) -> Any + spec = importlib.util.spec_from_file_location(name, path) + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + assert isinstance(spec.loader, Loader) + spec.loader.exec_module(module) + return module idf_path = os.environ['IDF_PATH'] diff --git a/tools/esp_prov/requirements.txt b/tools/esp_prov/requirements.txt index f21e32fb5aaa..3904e0d9e44a 100644 --- a/tools/esp_prov/requirements.txt +++ b/tools/esp_prov/requirements.txt @@ -1,3 +1,3 @@ future -protobuf +protobuf<=3.20.1 cryptography diff --git a/tools/idf_monitor.py b/tools/idf_monitor.py index 490178e53a31..40f2e8371760 100755 --- a/tools/idf_monitor.py +++ b/tools/idf_monitor.py @@ -594,8 +594,11 @@ def main_loop(self): # generates an event which will result in the finishing of # the last line. This is fix for handling lines sent # without EOL. + # finalizing the line when coredump is in progress causes decoding issues + # the espcoredump loader uses empty line as a sign for end-of-coredump + # line is finalized only for non coredump data elif event_tag == TAG_SERIAL_FLUSH: - self.handle_serial_input(data, finalize_line=True) + self.handle_serial_input(data, finalize_line=not self._coredump_buffer) else: raise RuntimeError('Bad event data %r' % ((event_tag,data),)) except SerialStopException: @@ -1007,7 +1010,7 @@ def main(): '--disable-address-decoding', '-d', help="Don't print lines about decoded addresses from the application ELF file.", action='store_true', - default=True if os.environ.get('ESP_MONITOR_DECODE') == 0 else False + default=os.getenv('ESP_MONITOR_DECODE') == '0' ) parser.add_argument( @@ -1075,19 +1078,22 @@ def main(): args = parser.parse_args() + # The port name is changed in cases described in the following lines. Use a local argument and + # avoid the modification of args.port. + port = args.port + # GDB uses CreateFile to open COM port, which requires the COM name to be r'\\.\COMx' if the COM # number is larger than 10 - if os.name == 'nt' and args.port.startswith('COM'): - args.port = args.port.replace('COM', r'\\.\COM') + if os.name == 'nt' and port.startswith('COM'): + port = port.replace('COM', r'\\.\COM') yellow_print('--- WARNING: GDB cannot open serial ports accessed as COMx') - yellow_print('--- Using %s instead...' % args.port) - elif args.port.startswith('/dev/tty.') and sys.platform == 'darwin': - args.port = args.port.replace('/dev/tty.', '/dev/cu.') + yellow_print('--- Using %s instead...' % port) + elif port.startswith('/dev/tty.') and sys.platform == 'darwin': + port = port.replace('/dev/tty.', '/dev/cu.') yellow_print('--- WARNING: Serial ports accessed as /dev/tty.* will hang gdb if launched.') - yellow_print('--- Using %s instead...' % args.port) + yellow_print('--- Using %s instead...' % port) - serial_instance = serial.serial_for_url(args.port, args.baud, - do_not_open=True) + serial_instance = serial.serial_for_url(port, args.baud, do_not_open=True) serial_instance.dtr = False serial_instance.rts = False @@ -1104,8 +1110,10 @@ def main(): except KeyError: pass # not running a make jobserver - # Pass the actual used port to callee of idf_monitor (e.g. make) through `ESPPORT` environment - # variable + # Pass the actual used port to callee of idf_monitor (e.g. idf.py/cmake) through `ESPPORT` environment + # variable. + # Note that the port must be original port argument without any replacement done in IDF Monitor (idf.py + # has a check for this). # To make sure the key as well as the value are str type, by the requirements of subprocess espport_key = str('ESPPORT') espport_val = str(args.port) diff --git a/tools/idf_py_actions/core_ext.py b/tools/idf_py_actions/core_ext.py index 6fc41728a391..4e5b8051aebb 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -380,16 +380,6 @@ def list_targets_callback(ctx, param, value): 'order_dependencies': ['reconfigure'], 'options': global_options, }, - 'erase_otadata': { - 'callback': build_target, - 'help': 'Erase otadata partition.', - 'options': global_options, - }, - 'read_otadata': { - 'callback': build_target, - 'help': 'Read otadata partition.', - 'options': global_options, - }, 'build-system-targets': { 'callback': list_build_system_targets, 'help': 'Print list of build system targets.', diff --git a/tools/idf_py_actions/serial_ext.py b/tools/idf_py_actions/serial_ext.py index 3aa7fe8f6a2a..9b8dfb8c7440 100644 --- a/tools/idf_py_actions/serial_ext.py +++ b/tools/idf_py_actions/serial_ext.py @@ -138,6 +138,17 @@ def global_callback(ctx, global_args, tasks): task.action_args['encrypted'] = True break + def ota_targets(target_name, ctx, args): + """ + Execute the target build system to build target 'target_name'. + Additionally set global variables for baud and port. + Calls ensure_build_directory() which will run cmake to generate a build + directory (with the specified generator) as needed. + """ + args.port = args.port or _get_default_serial_port(args) + ensure_build_directory(args, ctx.info_name) + run_target(target_name, args, {'ESPBAUD': str(args.baud), 'ESPPORT': args.port}) + baud_rate = { 'names': ['-b', '--baud'], 'help': 'Baud rate for flashing.', @@ -154,19 +165,20 @@ def global_callback(ctx, global_args, tasks): 'default': None, } + BAUD_AND_PORT = [baud_rate, port] serial_actions = { 'global_action_callbacks': [global_callback], 'actions': { 'flash': { 'callback': flash, 'help': 'Flash the project.', - 'options': global_options + [baud_rate, port], + 'options': global_options + BAUD_AND_PORT, 'order_dependencies': ['all', 'erase_flash'], }, 'erase_flash': { 'callback': erase_flash, 'help': 'Erase entire flash chip.', - 'options': [baud_rate, port], + 'options': BAUD_AND_PORT, }, 'monitor': { 'callback': @@ -218,19 +230,19 @@ def global_callback(ctx, global_args, tasks): 'partition_table-flash': { 'callback': flash, 'help': 'Flash partition table only.', - 'options': [baud_rate, port], + 'options': BAUD_AND_PORT, 'order_dependencies': ['partition_table', 'erase_flash'], }, 'bootloader-flash': { 'callback': flash, 'help': 'Flash bootloader only.', - 'options': [baud_rate, port], + 'options': BAUD_AND_PORT, 'order_dependencies': ['bootloader', 'erase_flash'], }, 'app-flash': { 'callback': flash, 'help': 'Flash the app only.', - 'options': [baud_rate, port], + 'options': BAUD_AND_PORT, 'order_dependencies': ['app', 'erase_flash'], }, 'encrypted-app-flash': { @@ -243,6 +255,16 @@ def global_callback(ctx, global_args, tasks): 'help': 'Flash the encrypted project.', 'order_dependencies': ['all', 'erase_flash'], }, + 'erase_otadata': { + 'callback': ota_targets, + 'help': 'Erase otadata partition.', + 'options': global_options + BAUD_AND_PORT, + }, + 'read_otadata': { + 'callback': ota_targets, + 'help': 'Read otadata partition.', + 'options': global_options + BAUD_AND_PORT, + }, }, } diff --git a/tools/idf_size.py b/tools/idf_size.py index 80152fa3070c..e8dfe730f647 100755 --- a/tools/idf_size.py +++ b/tools/idf_size.py @@ -6,19 +6,8 @@ # Includes information which is not shown in "xtensa-esp32-elf-size", # or easy to parse from "xtensa-esp32-elf-objdump" or raw map files. # -# Copyright 2017-2021 Espressif Systems (Shanghai) CO LTD -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 # from __future__ import division, print_function, unicode_literals @@ -244,11 +233,13 @@ def get_name_score(name): # type: (str) -> int split_name = section.split('.') if len(split_name) > 1: # If the section has a memory type, update the type and try to display the type properly - assert len(split_name) == 3 and split_name[0] == '', 'Unexpected section name' + assert split_name[0] == '', 'Unexpected section name "{}"'.format(section) memory_name = '.iram' if 'iram' in split_name[1] else\ '.dram' if 'dram' in split_name[1] else\ '.flash' if 'flash' in split_name[1] else\ '.' + split_name[1] + if len(split_name) < 3: + split_name.append('') # in order to avoid failures in the following lines display_name_list[i] = 'DRAM .' + split_name[2] if 'dram' in split_name[1] else\ 'IRAM' + split_name[1].replace('iram', '') + ' .' + split_name[2] if 'iram' in split_name[1] else\ 'Flash .' + split_name[2] if 'flash' in split_name[1] else\ @@ -281,11 +272,10 @@ def load_map_data(map_file): # type: (TextIO) -> Tuple[str, Dict, Dict] detected_chip = detect_target_chip(map_file) sections = load_sections(map_file) - # Exclude the .dummy section, which usually means shared region among I/D buses - dummy_keys = [key for key in sections if key.endswith(('.dummy'))] - if dummy_keys: - sections.pop(*dummy_keys) - + # Exclude the dummy and .text_end section, which usually means shared region among I/D buses + for key in list(sections.keys()): + if key.endswith(('dummy', '.text_end')): + sections.pop(key) return detected_chip, segments, sections @@ -370,7 +360,10 @@ def load_sections(map_file): # type: (TextIO) -> Dict RE_FULL_LINE = re.compile(r'\s*(?P\S*) +0x(?P
[\da-f]+) +0x(?P[\da-f]+)\s*(?P.*)$') # Extract archive and object_file from the file_info field - RE_FILE = re.compile(r'((?P[^ ]+\.a)?\(?(?P[^ ]+\.(o|obj))\)?)') + # The object file extention (.obj or .o) is optional including the dot. This is necessary for some third-party + # libraries. Since the dot is optional and the search gready the parsing of the object name must stop at ). Hence + # the [^ )] part of the regex. + RE_FILE = re.compile(r'((?P[^ ]+\.a)?\(?(?P[^ )]+(\.(o|obj))?)\)?)') def dump_src_line(src): # type: (Dict) -> str return '%s(%s) addr: 0x%08x, size: 0x%x+%d' % (src['sym_name'], src['file'], src['address'], src['size'], src['fill']) @@ -441,7 +434,7 @@ def dump_src_line(src): # type: (Dict) -> str # Extract archive and file information n = RE_FILE.match(m.group('file')) - assert n + assert n, 'Archive and file information not found for "{}"'.format(m.group('file')) archive = n.group('archive') if archive is None: @@ -622,8 +615,6 @@ def in_iram(x): # type: (MemRegions.Region) -> bool r.dram_total = get_size(dram_filter) iram_filter = filter(in_iram, segments) r.iram_total = get_size(iram_filter) - if r.diram_total == 0: - r.diram_total = r.dram_total + r.iram_total def filter_in_section(sections, section_to_check): # type: (Iterable[MemRegions.Region], str) -> List[MemRegions.Region] return list(filter(lambda x: LinkingSections.in_section(x.section, section_to_check), sections)) # type: ignore @@ -631,8 +622,6 @@ def filter_in_section(sections, section_to_check): # type: (Iterable[MemRegions dram_sections = list(filter(in_dram, sections)) iram_sections = list(filter(in_iram, sections)) diram_sections = list(filter(in_diram, sections)) - if not diram_sections: - diram_sections = dram_sections + iram_sections flash_sections = filter_in_section(sections, 'flash') dram_data_list = filter_in_section(dram_sections, 'data') diff --git a/tools/idf_tools.py b/tools/idf_tools.py index 0bcde35556b9..90e32798e73a 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -55,6 +55,7 @@ import subprocess import sys import tarfile +import time import zipfile from collections import OrderedDict, namedtuple @@ -368,20 +369,20 @@ def urlretrieve_ctx(url, filename, reporthook=None, data=None, context=None): # https://github.com/espressif/esp-idf/issues/3819#issuecomment-515167118 # https://github.com/espressif/esp-idf/issues/4063#issuecomment-531490140 # https://stackoverflow.com/a/43046729 -def rename_with_retry(path_from, path_to): - if sys.platform.startswith('win'): - retry_count = 100 - else: - retry_count = 1 - +def rename_with_retry(path_from, path_to): # type: (str, str) -> None + retry_count = 20 if sys.platform.startswith('win') else 1 for retry in range(retry_count): try: os.rename(path_from, path_to) return - except (OSError, WindowsError): # WindowsError until Python 3.3, then OSError + except OSError: + msg = 'Rename {} to {} failed'.format(path_from, path_to) if retry == retry_count - 1: + fatal(msg + '. Antivirus software might be causing this. Disabling it temporarily could solve the issue.') raise - warn('Rename {} to {} failed, retrying...'.format(path_from, path_to)) + warn(msg + ', retrying...') + # Sleep before the next try in order to pass the antivirus check on Windows + time.sleep(0.5) def strip_container_dirs(path, levels): @@ -1497,8 +1498,8 @@ def action_install_python_env(args): # type: ignore try: subprocess.check_call([virtualenv_python, '-m', 'pip', '--version'], stdout=sys.stdout, stderr=sys.stderr) except subprocess.CalledProcessError: - warn('PIP is not available in the virtual environment.') - # Reinstallation of the virtual environment could help if PIP was installed for the main Python + warn('pip is not available in the existing virtual environment, new virtual environment will be created.') + # Reinstallation of the virtual environment could help if pip was installed for the main Python reinstall = True if reinstall and os.path.exists(idf_python_env_path): @@ -1506,17 +1507,50 @@ def action_install_python_env(args): # type: ignore shutil.rmtree(idf_python_env_path) if not os.path.exists(virtualenv_python): - info('Creating a new Python environment in {}'.format(idf_python_env_path)) + # Before creating the virtual environment, check if pip is installed. + try: + subprocess.check_call([sys.executable, '-m', 'pip', '--version']) + except subprocess.CalledProcessError: + fatal('Python interpreter at {} doesn\'t have pip installed. ' + 'Please check the Getting Started Guides for the steps to install prerequisites for your OS.'.format(sys.executable)) + raise SystemExit(1) + virtualenv_installed_via_pip = False try: import virtualenv # noqa: F401 except ImportError: info('Installing virtualenv') subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--user', 'virtualenv'], stdout=sys.stdout, stderr=sys.stderr) + virtualenv_installed_via_pip = True + # since we just installed virtualenv via pip, we know that version is recent enough + # so the version check below is not necessary. + + with_seeder_option = True + if not virtualenv_installed_via_pip: + # virtualenv is already present in the system and may have been installed via OS package manager + # check the version to determine if we should add --seeder option + try: + major_ver = int(virtualenv.__version__.split('.')[0]) + if major_ver < 20: + warn('Virtualenv version {} is old, please consider upgrading it'.format(virtualenv.__version__)) + with_seeder_option = False + except (ValueError, NameError, AttributeError, IndexError): + pass + + info('Creating a new Python environment in {}'.format(idf_python_env_path)) + virtualenv_options = ['--python', sys.executable] + if with_seeder_option: + virtualenv_options += ['--seeder', 'pip'] - subprocess.check_call([sys.executable, '-m', 'virtualenv', '--seeder', 'pip', idf_python_env_path], + subprocess.check_call([sys.executable, '-m', 'virtualenv'] + + virtualenv_options + + [idf_python_env_path], stdout=sys.stdout, stderr=sys.stderr) + env_copy = os.environ.copy() + if env_copy.get('PIP_USER') == 'yes': + warn('Found PIP_USER="yes" in the environment. Disabling PIP_USER in this shell to install packages into a virtual environment.') + env_copy['PIP_USER'] = 'no' run_args = [virtualenv_python, '-m', 'pip', 'install', '--no-warn-script-location'] requirements_txt = os.path.join(global_idf_path, 'requirements.txt') run_args += ['-r', requirements_txt] @@ -1532,7 +1566,7 @@ def action_install_python_env(args): # type: ignore run_args += ['--find-links', wheels_dir] info('Installing Python packages from {}'.format(requirements_txt)) - subprocess.check_call(run_args, stdout=sys.stdout, stderr=sys.stderr) + subprocess.check_call(run_args, stdout=sys.stdout, stderr=sys.stderr, env=env_copy) def action_add_version(args): diff --git a/tools/ldgen/fragments.py b/tools/ldgen/fragments.py index 424b2fa5d72e..bcba9f2237c6 100644 --- a/tools/ldgen/fragments.py +++ b/tools/ldgen/fragments.py @@ -1,17 +1,6 @@ # -# Copyright 2021 Espressif Systems (Shanghai) CO LTD -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 # import abc import os @@ -190,7 +179,7 @@ class Fragment(): """ IDENTIFIER = Word(alphas + '_', alphanums + '_') - ENTITY = Word(alphanums + '.-_$') + ENTITY = Word(alphanums + '.-_$+') @abc.abstractmethod def set_key_value(self, key, parse_results): diff --git a/tools/ldgen/samples/sdkconfig b/tools/ldgen/samples/sdkconfig index 30c053f86d15..8ea12dbbc505 100644 --- a/tools/ldgen/samples/sdkconfig +++ b/tools/ldgen/samples/sdkconfig @@ -119,7 +119,7 @@ CONFIG_AWS_IOT_SDK= # CONFIG_BT_ENABLED= CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BT_RESERVE_DRAM=0 +CONFIG_BTDM_RESERVE_DRAM=0 # # ADC configuration diff --git a/tools/ldgen/test/test_fragments.py b/tools/ldgen/test/test_fragments.py index f9f19ce4a7e7..5765182c50d8 100755 --- a/tools/ldgen/test/test_fragments.py +++ b/tools/ldgen/test/test_fragments.py @@ -1,19 +1,9 @@ #!/usr/bin/env python # -# Copyright 2021 Espressif Systems (Shanghai) CO LTD -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 # + import os import sys import tempfile @@ -682,6 +672,18 @@ def test_archive(self): with self.assertRaises(ParseFatalException): FragmentFile(test_fragment, self.sdkconfig) + def test_archive_allowed_names(self): + test_fragment = self.create_fragment_file(u""" +[mapping:test] +archive: + libstdc++.a +entries: + * (default) +""") + + fragment_file = FragmentFile(test_fragment, self.sdkconfig) + self.assertEqual('libstdc++.a', fragment_file.fragments[0].archive) + def test_empty_entries(self): test_fragment = self.create_fragment_file(u""" [mapping:test] diff --git a/tools/mass_mfg/docs/README.rst b/tools/mass_mfg/docs/README.rst index 6ed10a22a0c8..23e326f84803 100644 --- a/tools/mass_mfg/docs/README.rst +++ b/tools/mass_mfg/docs/README.rst @@ -10,8 +10,8 @@ This utility is designed to create instances of factory NVS partition images on Please note that this utility only creates manufacturing binary images which then need to be flashed onto your devices using: -- `esptool.py`_ -- `Flash Download tool`_ (available on Windows only).Just download it, unzip, and follow the instructions inside the *doc* folder. +- `esptool.py`_. +- `Flash Download tool`_ (available on Windows only). Just download it, unzip, and follow the instructions inside the *doc* folder. - Direct flash programming using custom production tools. @@ -21,7 +21,7 @@ Prerequisites **This utility is dependent on esp-idf's NVS partition utility.** * Operating System requirements: - - Linux / MacOS / Windows (standard distributions) + - Linux/macOS/Windows (standard distributions) * The following packages are needed to use this utility: - `Python `_ @@ -63,8 +63,7 @@ The data in the configuration file has the following format (the `REPEAT` tag is .. note:: The first line in this file should always be the ``namespace`` entry. -Each line should have three parameters: ``key,type,encoding``, separated by a comma. -If the ``REPEAT`` tag is present, the value corresponding to this key in the master value CSV file will be the same for all devices. +Each line should have three parameters: ``key,type,encoding``, separated by a comma. If the ``REPEAT`` tag is present, the value corresponding to this key in the master value CSV file will be the same for all devices. *Please refer to README of the NVS Partition Generator utility for detailed description of each parameter.* @@ -133,66 +132,72 @@ Running the utility python mfg_gen.py [-h] {generate,generate-key} ... - Optional Arguments: - +-----+------------+----------------------------------------------------------------------+ - | No. | Parameter | Description | - +=====+============+======================================================================+ - | 1 | -h, --help | show this help message and exit | - +-----+------------+----------------------------------------------------------------------+ +**Optional Arguments**: + + +-----+------------+----------------------------------------------------------------------+ + | No. | Parameter | Description | + +=====+============+======================================================================+ + | 1 | -h, --help | show this help message and exit | + +-----+------------+----------------------------------------------------------------------+ + +**Commands**: - Commands: Run mfg_gen.py {command} -h for additional help - +-----+--------------+--------------------------------------------------------------------+ - | No. | Parameter | Description | - +=====+==============+====================================================================+ - | 1 | generate | Generate NVS partition | - +-----+--------------+--------------------------------------------------------------------+ - | 2 | generate-key | Generate keys for encryption | - +-----+--------------+--------------------------------------------------------------------+ + + +-----+--------------+--------------------------------------------------------------------+ + | No. | Parameter | Description | + +=====+==============+====================================================================+ + | 1 | generate | Generate NVS partition | + +-----+--------------+--------------------------------------------------------------------+ + | 2 | generate-key | Generate keys for encryption | + +-----+--------------+--------------------------------------------------------------------+ **To generate factory images for each device (Default):** - **Usage**:: - - python mfg_gen.py generate [-h] [--fileid FILEID] [--version {1,2}] [--keygen] - [--keyfile KEYFILE] [--inputkey INPUTKEY] - [--outdir OUTDIR] - conf values prefix size - - Positional Arguments: - +--------------+----------------------------------------------------------------------+ - | Parameter | Description | - +==============+======================================================================+ - | conf | Path to configuration csv file to parse | - +--------------+----------------------------------------------------------------------+ - | values | Path to values csv file to parse | - +--------------+----------------------------------------------------------------------+ - | prefix | Unique name for each output filename prefix | - +-----+--------------+----------------------------------------------------------------+ - | size | Size of NVS partition in bytes | - | | (must be multiple of 4096) | - +--------------+----------------------------------------------------------------------+ - - Optional Arguments: - +---------------------+--------------------------------------------------------------------+ - | Parameter | Description | - +=====================+====================================================================+ - | -h, --help | show this help message and exit | - +---------------------+--------------------------------------------------------------------+ - | --fileid FILEID | Unique file identifier(any key in values file) | - | | for each filename suffix (Default: numeric value(1,2,3...) | - +---------------------+--------------------------------------------------------------------+ - | --version {1,2} | Set multipage blob version. | - | | Version 1 - Multipage blob support disabled. | - | | Version 2 - Multipage blob support enabled. | - | | Default: Version 2 | - +---------------------+--------------------------------------------------------------------+ - | --keygen | Generates key for encrypting NVS partition | - +---------------------+--------------------------------------------------------------------+ - | --inputkey INPUTKEY | File having key for encrypting NVS partition | - +---------------------+--------------------------------------------------------------------+ - | --outdir OUTDIR | Output directory to store files created | - | | (Default: current directory) | - +---------------------+--------------------------------------------------------------------+ + +**Usage**:: + + python mfg_gen.py generate [-h] [--fileid FILEID] [--version {1,2}] [--keygen] + [--keyfile KEYFILE] [--inputkey INPUTKEY] + [--outdir OUTDIR] + conf values prefix size + +**Positional Arguments**: + + +--------------+----------------------------------------------------------------------+ + | Parameter | Description | + +==============+======================================================================+ + | conf | Path to configuration csv file to parse | + +--------------+----------------------------------------------------------------------+ + | values | Path to values csv file to parse | + +--------------+----------------------------------------------------------------------+ + | prefix | Unique name for each output filename prefix | + +-----+--------------+----------------------------------------------------------------+ + | size | Size of NVS partition in bytes | + | | (must be multiple of 4096) | + +--------------+----------------------------------------------------------------------+ + +**Optional Arguments**: + + +---------------------+--------------------------------------------------------------------+ + | Parameter | Description | + +=====================+====================================================================+ + | -h, --help | show this help message and exit | + +---------------------+--------------------------------------------------------------------+ + | --fileid FILEID | Unique file identifier(any key in values file) | + | | for each filename suffix (Default: numeric value(1,2,3...) | + +---------------------+--------------------------------------------------------------------+ + | --version {1,2} | Set multipage blob version. | + | | Version 1 - Multipage blob support disabled. | + | | Version 2 - Multipage blob support enabled. | + | | Default: Version 2 | + +---------------------+--------------------------------------------------------------------+ + | --keygen | Generates key for encrypting NVS partition | + +---------------------+--------------------------------------------------------------------+ + | --inputkey INPUTKEY | File having key for encrypting NVS partition | + +---------------------+--------------------------------------------------------------------+ + | --outdir OUTDIR | Output directory to store files created | + | | (Default: current directory) | + +---------------------+--------------------------------------------------------------------+ You can run the utility to generate factory images for each device using the command below. A sample CSV file is provided with the utility:: @@ -216,21 +221,23 @@ You can run the utility to encrypt factory images for each device using the comm python mfg_gen.py generate samples/sample_config.csv samples/sample_values_singlepage_blob.csv Sample 0x3000 --inputkey keys/sample_keys.bin **To generate only encryption keys:** - **Usage**:: - - python mfg_gen.py generate-key [-h] [--keyfile KEYFILE] [--outdir OUTDIR] - - Optional Arguments: - +--------------------+----------------------------------------------------------------------+ - | Parameter | Description | - +====================+======================================================================+ - | -h, --help | show this help message and exit | - +--------------------+----------------------------------------------------------------------+ - | --keyfile KEYFILE | Path to output encryption keys file | - +--------------------+----------------------------------------------------------------------+ - | --outdir OUTDIR | Output directory to store files created. | - | | (Default: current directory) | - +--------------------+----------------------------------------------------------------------+ + +**Usage**:: + + python mfg_gen.py generate-key [-h] [--keyfile KEYFILE] [--outdir OUTDIR] + +**Optional Arguments**: + + +--------------------+----------------------------------------------------------------------+ + | Parameter | Description | + +====================+======================================================================+ + | -h, --help | show this help message and exit | + +--------------------+----------------------------------------------------------------------+ + | --keyfile KEYFILE | Path to output encryption keys file | + +--------------------+----------------------------------------------------------------------+ + | --outdir OUTDIR | Output directory to store files created. | + | | (Default: current directory) | + +--------------------+----------------------------------------------------------------------+ You can run the utility to generate only encryption keys using the command below:: diff --git a/tools/mass_mfg/docs/README_CN.rst b/tools/mass_mfg/docs/README_CN.rst index 2d76a84dc816..79aeb1f7ef85 100644 --- a/tools/mass_mfg/docs/README_CN.rst +++ b/tools/mass_mfg/docs/README_CN.rst @@ -10,9 +10,9 @@ 注意,该程序仅创建用于量产的二进制映像,您需要使用以下工具将映像烧录到设备上: -- esptool.py -- Flash 下载工具(仅适用于 Windows) -- 直接烧录程序 +- `esptool.py`_。 +- `Flash 下载工具`_ (仅适用于 Windows)。下载后解压,然后按照 doc 文件夹中的说明操作。 +- 使用定制的生产工具直接烧录程序。 准备工作 @@ -21,10 +21,10 @@ **该程序需要用到分区公用程序。** * 操作系统要求: - - Linux、MacOS 或 Windows(标准版) + - Linux、macOS 或 Windows(标准版) * 安装依赖包: - - Python: https://www.python.org/downloads/。 + - `Python `_。 .. note:: @@ -50,7 +50,7 @@ CSV 配置文件 ---------------------- -CSV 配置文件中包含设备待烧录的配置信息,定义了待烧录的配置项。例如定义 ``firmware_key`` (``key``) 的 ``type`` 为 ``data``,``encoding`` 为 ``hex2bin``。 +CSV 配置文件中包含设备待烧录的配置信息,定义了待烧录的配置项。 配置文件中数据格式如下(`REPEAT` 标签可选):: @@ -69,11 +69,13 @@ CSV 配置文件中包含设备待烧录的配置信息,定义了待烧录的 CSV 配置文件示例如下:: + app,namespace, firmware_key,data,hex2bin serial_no,data,string,REPEAT <-- "serial_no" 被标记为 "REPEAT" device_no,data,i32 + .. note:: 请确保: @@ -84,14 +86,12 @@ CSV 配置文件示例如下:: 主 CSV 文件 --------------------- -主 CSV 文件中包含设备待烧录的详细信息,文件中每行均对应一个设备实体。主 CSV 文件中的 ``key`` 应首先在 CSV 配置文件中定义。 +主 CSV 文件中包含设备待烧录的详细信息,文件中每行均对应一个设备实体。 主 CSV 文件的数据格式如下:: key1,key2,key3,..... - value1,value2,value3,.... <-- 对应一个设备实体 - value4,value5,value6,.... <-- 对应一个设备实体 - value7,value8,value9,.... <-- 对应一个设备实体 + value1,value2,value3,.... .. note:: 文件中键 (``key``) 名应始终置于文件首行。从配置文件中获取的键,在此文件中的排列顺序应与其在配置文件中的排列顺序相同。主 CSV 文件同时可以包含其它列(键),这些列将被视为元数据,而不会编译进最终二进制文件。 @@ -106,10 +106,10 @@ CSV 配置文件示例如下:: 主 CSV 文件示例如下:: - id,firmware_key,serial_no,device_no - 1,1a2b3c4d5e6faabb,A1,101 <-- 对应一个设备实体(在 CSV 配置文件中标记为 `REPEAT` 的键,除第一个条目外,其他均为空) - 2,1a2b3c4d5e6fccdd,,102 <-- 对应一个设备实体 - 3,1a2b3c4d5e6feeff,,103 <-- 对应一个设备实体 + id,firmware_key,serial_no,device_no + 1,1a2b3c4d5e6faabb,A1,101 + 2,1a2b3c4d5e6fccdd,,102 + 3,1a2b3c4d5e6feeff,,103 .. note:: 如果出现 `REPEAT` 标签,则会在相同目录下生成一个新的主 CSV 文件用作主输入文件,并在每行为带有 `REPEAT` 标签的键插入键值。 @@ -124,6 +124,7 @@ CSV 配置文件示例如下:: 此步骤将为每一设备生成一个中间 CSV 文件。 + 运行量产程序 ------------------- @@ -236,7 +237,8 @@ CSV 配置文件示例如下:: +-------------------+----------------------------------------------+ | --outdir OUTDIR | 输出目录,用于存储创建的文件(默认当前目录) | +-------------------+----------------------------------------------+ - + + 运行以下命令仅生成加密密钥:: python mfg_gen.py generate-key @@ -254,3 +256,5 @@ CSV 配置文件示例如下:: - ``csv/`` 存储生成的中间 CSV 文件 - ``keys/`` 存储加密密钥(创建工厂加密映像时会用到) +.. _esptool.py: https://github.com/espressif/esptool/#readme +.. _Flash 下载工具: https://www.espressif.com/en/support/download/other-tools?keys=flash+download+tools \ No newline at end of file diff --git a/tools/mkdfu.py b/tools/mkdfu.py index 980cf278ba98..d643de1140d0 100755 --- a/tools/mkdfu.py +++ b/tools/mkdfu.py @@ -114,6 +114,26 @@ def as_hex(val): # type: (int) -> bytes # This CRC32 gets added after DFUSUFFIX_STRUCT DFUCRC_STRUCT = b' int """ Calculate CRC32/JAMCRC of data, with an optional initial value """ @@ -127,6 +147,17 @@ def pad_bytes(b, multiple, padding=b'\x00'): # type: (bytes, int, bytes) -> byt return b + padding * (padded_len - len(b)) +def flash_size_bytes(size): # type: (str) -> int + """ + Given a flash size passed in args.flash_size + (ie 4MB), return the size in bytes. + """ + try: + return int(size.rstrip('MB'), 10) * 1024 * 1024 + except ValueError: + raise argparse.ArgumentTypeError('Unknown size {}'.format(size)) + + class EspDfuWriter(object): def __init__(self, dest_file, pid, part_size): # type: (typing.BinaryIO, int, int) -> None self.dest = dest_file @@ -135,6 +166,29 @@ def __init__(self, dest_file, pid, part_size): # type: (typing.BinaryIO, int, i self.entries = [] # type: typing.List[bytes] self.index = [] # type: typing.List[DFUInfo] + def add_flash_params_file(self, flash_size): # type: (str) -> None + """ + Add a file containing flash chip parameters + + Corresponds to the "flashchip" data structure that the ROM + has in RAM. + + See flash_set_parameters() in esptool.py for more info + """ + flash_params = FlashParamsData( + ishspi=0, + legacy=0, + deviceId=0, # ignored + chip_size=flash_size_bytes(flash_size), # flash size in bytes + block_size=64 * 1024, + sector_size=4 * 1024, + page_size=256, + status_mask=0xffff, + ) + data = struct.pack(FLASH_PARAMS_STRUCT, *flash_params) + flags = DFU_INFO_FLAG_PARAM | DFU_INFO_FLAG_NOERASE | DFU_INFO_FLAG_IGNORE_MD5 + self._add_cpio_flash_entry(FLASH_PARAMS_FILE, 0, data, flags) + def add_file(self, flash_addr, path): # type: (int, str) -> None """ Add file to be written into flash at given address @@ -177,14 +231,14 @@ def finish(self): # type: () -> None self.dest.write(out_data) def _add_cpio_flash_entry( - self, filename, flash_addr, data - ): # type: (str, int, bytes) -> None + self, filename, flash_addr, data, flags=0 + ): # type: (str, int, bytes, int) -> None md5 = hashlib.md5() md5.update(data) self.index.append( DFUInfo( address=flash_addr, - flags=0, + flags=flags, name=filename.encode('utf-8'), md5=md5.digest(), ) @@ -207,6 +261,8 @@ def _add_cpio_entry( def action_write(args): # type: (typing.Mapping[str, typing.Any]) -> None writer = EspDfuWriter(args['output_file'], args['pid'], args['part_size']) + print('Adding flash chip parameters file with flash_size = {}'.format(args['flash_size'])) + writer.add_flash_params_file(args['flash_size']) for addr, f in args['files']: print('Adding {} at {:#x}'.format(f, addr)) writer.add_file(addr, f) @@ -239,6 +295,10 @@ def main(): write_parser.add_argument('files', metavar='
', help='Add at
', nargs='*') + write_parser.add_argument('-fs', '--flash-size', + help='SPI Flash size in MegaBytes (1MB, 2MB, 4MB, 8MB, 16MB, 32MB, 64MB, 128MB)', + choices=['1MB', '2MB', '4MB', '8MB', '16MB', '32MB', '64MB', '128MB'], + default='2MB') args = parser.parse_args() @@ -272,6 +332,7 @@ def process_json_file(path): 'files': files, 'pid': args.pid, 'part_size': args.part_size, + 'flash_size': args.flash_size, } {'write': action_write diff --git a/tools/test_apps/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild b/tools/test_apps/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild index 874db25c4b4f..f2c38432d0d1 100644 --- a/tools/test_apps/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild +++ b/tools/test_apps/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild @@ -2,25 +2,25 @@ menu "Example Configuration" config EXAMPLE_BROKER_SSL_URI string "Broker SSL URL" - default "mqtts://mqtt.eclipse.org:8883" + default "mqtts://mqtt.eclipseprojects.io:8883" help URL of an mqtt broker for ssl transport config EXAMPLE_BROKER_TCP_URI string "Broker TCP URL" - default "mqtt://mqtt.eclipse.org:1883" + default "mqtt://mqtt.eclipseprojects.io:1883" help URL of an mqtt broker for tcp transport config EXAMPLE_BROKER_WS_URI string "Broker WS URL" - default "ws://mqtt.eclipse.org:80/mqtt" + default "ws://mqtt.eclipseprojects.io:80/mqtt" help URL of an mqtt broker for ws transport config EXAMPLE_BROKER_WSS_URI string "Broker WSS URL" - default "wss://mqtt.eclipse.org:443/mqtt" + default "wss://mqtt.eclipseprojects.io:443/mqtt" help URL of an mqtt broker for wss transport diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.no_esp_cert_bundle b/tools/test_apps/system/build_test/sdkconfig.ci.no_esp_cert_bundle new file mode 100644 index 000000000000..990777a89e75 --- /dev/null +++ b/tools/test_apps/system/build_test/sdkconfig.ci.no_esp_cert_bundle @@ -0,0 +1 @@ +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n diff --git a/tools/test_apps/system/panic/panic_tests.py b/tools/test_apps/system/panic/panic_tests.py index 93d196ea66e5..c890f4ae7da2 100644 --- a/tools/test_apps/system/panic/panic_tests.py +++ b/tools/test_apps/system/panic/panic_tests.py @@ -51,13 +51,13 @@ def task_wdt_inner(env, test_name): dut.expect_backtrace() dut.expect_elf_sha256() dut.expect_none('Guru Meditation') - test_common(dut, test_name, - expected_backtrace=['panic_abort', - 'esp_system_abort', - 'abort', - 'task_wdt_isr', - '_xt_lowint1'] + - get_default_backtrace(dut.test_name)) + if ('gdbstub' in test_name): + test_common(dut, test_name, expected_backtrace=[ + # Backtrace interrupted when abort is called, IDF-842 + 'panic_abort', 'esp_system_abort' + ]) + else: + test_common(dut, test_name) def int_wdt_inner(env, test_name): @@ -105,11 +105,13 @@ def abort_inner(env, test_name): dut.expect_backtrace() dut.expect_elf_sha256() dut.expect_none('Guru Meditation', 'Re-entered core dump') - test_common(dut, test_name, - expected_backtrace=['panic_abort', - 'esp_system_abort', - 'abort'] + - get_default_backtrace(dut.test_name)) + if ('gdbstub' in test_name): + test_common(dut, test_name, expected_backtrace=[ + # Backtrace interrupted when abort is called, IDF-842 + 'panic_abort', 'esp_system_abort' + ]) + else: + test_common(dut, test_name) def abort_cached_disabled_inner(env, test_name): diff --git a/tools/test_idf_py/test_idf_py.py b/tools/test_idf_py/test_idf_py.py index 4049a141a0d4..8ed6b321741f 100755 --- a/tools/test_idf_py/test_idf_py.py +++ b/tools/test_idf_py/test_idf_py.py @@ -17,7 +17,7 @@ import os import subprocess import sys -import unittest +from unittest import TestCase, main try: from StringIO import StringIO @@ -36,7 +36,17 @@ link_path = os.path.join(current_dir, '..', 'idf_py_actions', 'test_ext') -class TestExtensions(unittest.TestCase): +class TestWithoutExtensions(TestCase): + def setUp(self): + self.initial_env = dict(os.environ) + os.environ['IDF_COMPONENT_MANAGER'] = '0' + os.environ['IDF_EXTRA_ACTIONS_PATH'] = '' + + def tearDown(self): + os.environ = self.initial_env + + +class TestExtensions(TestWithoutExtensions): def test_extension_loading(self): try: os.symlink(extension_path, link_path) @@ -78,7 +88,7 @@ def test_hidden_commands(self): os.remove(link_path) -class TestDependencyManagement(unittest.TestCase): +class TestDependencyManagement(TestWithoutExtensions): def test_dependencies(self): result = idf.init_cli()( args=['--dry-run', 'flash'], @@ -129,7 +139,7 @@ def test_dupplicated_commands_warning(self): 'WARNING: Command "clean" is found in the list of commands more than once.', capturedOutput.getvalue()) -class TestVerboseFlag(unittest.TestCase): +class TestVerboseFlag(TestWithoutExtensions): def test_verbose_messages(self): output = subprocess.check_output( [ @@ -155,7 +165,7 @@ def test_verbose_messages_not_shown_by_default(self): self.assertNotIn('Verbose mode on', output) -class TestGlobalAndSubcommandParameters(unittest.TestCase): +class TestGlobalAndSubcommandParameters(TestWithoutExtensions): def test_set_twice_same_value(self): """Can set -D twice: globally and for subcommand if values are the same""" @@ -174,21 +184,24 @@ def test_set_twice_different_values(self): ) -class TestDeprecations(unittest.TestCase): +class TestDeprecations(TestWithoutExtensions): def test_exit_with_error_for_subcommand(self): try: - subprocess.check_output([sys.executable, idf_py_path, '-C%s' % current_dir, 'test-2'], env=os.environ, - stderr=subprocess.STDOUT) + subprocess.check_output( + [sys.executable, idf_py_path, '-C%s' % current_dir, 'test-2'], env=os.environ, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: self.assertIn('Error: Command "test-2" is deprecated and was removed.', e.output.decode('utf-8', 'ignore')) def test_exit_with_error_for_option(self): try: - subprocess.check_output([sys.executable, idf_py_path, '-C%s' % current_dir, '--test-5=asdf'], - env=os.environ, stderr=subprocess.STDOUT) + subprocess.check_output( + [sys.executable, idf_py_path, '-C%s' % current_dir, '--test-5=asdf'], + env=os.environ, + stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - self.assertIn('Error: Option "test_5" is deprecated since v2.0 and was removed in v3.0.', - e.output.decode('utf-8', 'ignore')) + self.assertIn( + 'Error: Option "test_5" is deprecated since v2.0 and was removed in v3.0.', + e.output.decode('utf-8', 'ignore')) def test_deprecation_messages(self): output = subprocess.check_output( @@ -206,7 +219,8 @@ def test_deprecation_messages(self): 'ta', 'test-1', ], - env=os.environ, stderr=subprocess.STDOUT).decode('utf-8', 'ignore') + env=os.environ, + stderr=subprocess.STDOUT).decode('utf-8', 'ignore') self.assertIn('Warning: Option "test_sub_1" is deprecated and will be removed in future versions.', output) self.assertIn( @@ -222,4 +236,4 @@ def test_deprecation_messages(self): if __name__ == '__main__': - unittest.main() + main() diff --git a/tools/test_idf_size/expected_output b/tools/test_idf_size/expected_output index c421a7d89ed6..f3cc62a8f951 100644 --- a/tools/test_idf_size/expected_output +++ b/tools/test_idf_size/expected_output @@ -1,4 +1,25 @@ +*** +Building project for esp32... + +*** +Running mem_test.py for esp32... +Test complete without errors + +*** +Building project for esp32s2... + +*** +Running mem_test.py for esp32s2... +Test complete without errors + +*** +Building project for esp32c3... + +*** +Running mem_test.py for esp32c3... +Test complete without errors + *** Running idf_size.py... Total sizes: @@ -8,15 +29,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) .text size: 37908 bytes .vectors size: 1024 bytes -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) - .data size: 9324 bytes - .bss size: 8296 bytes - .text size: 37908 bytes - .vectors size: 1024 bytes Used Flash size : 186524 bytes .text : 146944 bytes .rodata : 39580 bytes -Total image size: 283036 bytes (.bin may be padded larger) +Total image size: 234780 bytes (.bin may be padded larger) *** Running idf_size.py on bootloader... @@ -27,17 +43,10 @@ Used static DRAM: 7212 bytes ( 58324 remain, 11.0% used) .rodata size: 7160 bytes Used static IRAM: 18796 bytes ( 78484 remain, 19.3% used) .text size: 18796 bytes -Used stat D/IRAM: 26008 bytes ( 136808 remain, 16.0% used) - .data size: 4 bytes - .bss size: 48 bytes - .text size: 18796 bytes - .rodata size: 7160 bytes -Total image size: 51920 bytes (.bin may be padded larger) +Total image size: 25960 bytes (.bin may be padded larger) *** Running idf_size.py with overflow... -WARNING: Given section not found in any memory region. -Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py Total sizes: Used static DRAM: 33464 bytes ( 147272 remain, 18.5% used) .data size: 17464 bytes @@ -45,15 +54,10 @@ Used static DRAM: 33464 bytes ( 147272 remain, 18.5% used) Used static IRAM: 181518 bytes ( -50446 remain, 138.5% used) Overflow detected! You can run idf.py size-files for more information. .text size: 180491 bytes .vectors size: 1027 bytes -Used stat D/IRAM: 214982 bytes ( 96826 remain, 68.9% used) - .data size: 17464 bytes - .bss size: 16000 bytes - .text size: 180491 bytes - .vectors size: 1027 bytes Used Flash size : 531135 bytes .text : 432171 bytes .rodata : 98708 bytes -Total image size: 929099 bytes (.bin may be padded larger) +Total image size: 730117 bytes (.bin may be padded larger) *** Running idf_size.py --archives... @@ -64,15 +68,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) .text size: 37908 bytes .vectors size: 1024 bytes -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) - .data size: 9324 bytes - .bss size: 8296 bytes - .text size: 37908 bytes - .vectors size: 1024 bytes Used Flash size : 186524 bytes .text : 146944 bytes .rodata : 39580 bytes -Total image size: 283036 bytes (.bin may be padded larger) +Total image size: 234780 bytes (.bin may be padded larger) Per-archive contributions to ELF file: Archive File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total liblwip.a 14 3751 0 0 3765 66978 13936 80928 @@ -123,15 +122,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) .text size: 37908 bytes .vectors size: 1024 bytes -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) - .data size: 9324 bytes - .bss size: 8296 bytes - .text size: 37908 bytes - .vectors size: 1024 bytes Used Flash size : 186524 bytes .text : 146944 bytes .rodata : 39580 bytes -Total image size: 283036 bytes (.bin may be padded larger) +Total image size: 234780 bytes (.bin may be padded larger) Per-file contributions to ELF file: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total lib_a-vfprintf.o 0 0 0 0 0 14193 704 14897 @@ -425,15 +419,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) .text size: 37908 bytes .vectors size: 1024 bytes -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) - .data size: 9324 bytes - .bss size: 8296 bytes - .text size: 37908 bytes - .vectors size: 1024 bytes Used Flash size : 186524 bytes .text : 146944 bytes .rodata : 39580 bytes -Total image size: 283036 bytes (.bin may be padded larger) +Total image size: 234780 bytes (.bin may be padded larger) Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -508,16 +497,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 7212 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 18796 +20136 ( +13656 remain, +33792 total) .text size: 37908 bytes 18796 +19112 .vectors size: 1024 bytes 0 +1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 26008 +30544 (+118448 remain, +148992 total) - .data size: 9324 bytes 4 +9320 - .bss size: 8296 bytes 48 +8248 - .text size: 37908 bytes 18796 +19112 - .vectors size: 1024 bytes 0 +1024 - .rodata size: 0 bytes 7160 -7160 Used Flash size : 186524 bytes 0 +186524 .text : 146944 bytes 0 +146944 .rodata : 39580 bytes 0 +39580 -Total image size: 283036 bytes (.bin may be padded larger) 51920 +231116 +Total image size: 234780 bytes (.bin may be padded larger) 25960 +208820 *** Running idf_size.py diff with itself... @@ -531,15 +514,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 17620 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38932 ( +0 remain, +0 total) .text size: 37908 bytes 37908 .vectors size: 1024 bytes 1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 56552 ( +0 remain, +0 total) - .data size: 9324 bytes 9324 - .bss size: 8296 bytes 8296 - .text size: 37908 bytes 37908 - .vectors size: 1024 bytes 1024 Used Flash size : 186524 bytes 186524 .text : 146944 bytes 146944 .rodata : 39580 bytes 39580 -Total image size: 283036 bytes (.bin may be padded larger) 283036 +Total image size: 234780 bytes (.bin may be padded larger) 234780 *** Running idf_size.py diff with another app... @@ -550,18 +528,13 @@ Total sizes of : Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 10604 +7016 ( -7016 remain, +0 total) .data size: 9324 bytes 8580 +744 .bss size: 8296 bytes 2024 +6272 -Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38959 -27 ( +27 remain, +0 total) - .text size: 37908 bytes 37932 -24 - .vectors size: 1024 bytes 1027 -3 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 49563 +6989 ( -6989 remain, +0 total) - .data size: 9324 bytes 8580 +744 - .bss size: 8296 bytes 2024 +6272 - .text size: 37908 bytes 37932 -24 +Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38956 -24 ( +24 remain, +0 total) + .text size: 37908 bytes 37929 -21 .vectors size: 1024 bytes 1027 -3 Used Flash size : 186524 bytes 99551 +86973 .text : 146944 bytes 77191 +69753 .rodata : 39580 bytes 22360 +17220 -Total image size: 283036 bytes (.bin may be padded larger) 194629 +88407 +Total image size: 234780 bytes (.bin may be padded larger) 147087 +87693 *** Running idf_size.py diff with app in reverse order... @@ -572,18 +545,13 @@ Total sizes of : Used static DRAM: 10604 bytes ( 170132 remain, 5.9% used) 17620 -7016 ( +7016 remain, +0 total) .data size: 8580 bytes 9324 -744 .bss size: 2024 bytes 8296 -6272 -Used static IRAM: 38959 bytes ( 92113 remain, 29.7% used) 38932 +27 ( -27 remain, +0 total) - .text size: 37932 bytes 37908 +24 - .vectors size: 1027 bytes 1024 +3 -Used stat D/IRAM: 49563 bytes ( 262245 remain, 15.9% used) 56552 -6989 ( +6989 remain, +0 total) - .data size: 8580 bytes 9324 -744 - .bss size: 2024 bytes 8296 -6272 - .text size: 37932 bytes 37908 +24 +Used static IRAM: 38956 bytes ( 92116 remain, 29.7% used) 38932 +24 ( -24 remain, +0 total) + .text size: 37929 bytes 37908 +21 .vectors size: 1027 bytes 1024 +3 Used Flash size : 99551 bytes 186524 -86973 .text : 77191 bytes 146944 -69753 .rodata : 22360 bytes 39580 -17220 -Total image size: 194629 bytes (.bin may be padded larger) 283036 -88407 +Total image size: 147087 bytes (.bin may be padded larger) 234780 -87693 *** Running idf_size.py diff --archives with bootloader... @@ -598,16 +566,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 7212 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 18796 +20136 ( +13656 remain, +33792 total) .text size: 37908 bytes 18796 +19112 .vectors size: 1024 bytes 0 +1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 26008 +30544 (+118448 remain, +148992 total) - .data size: 9324 bytes 4 +9320 - .bss size: 8296 bytes 48 +8248 - .text size: 37908 bytes 18796 +19112 - .vectors size: 1024 bytes 0 +1024 - .rodata size: 0 bytes 7160 -7160 Used Flash size : 186524 bytes 0 +186524 .text : 146944 bytes 0 +146944 .rodata : 39580 bytes 0 +39580 -Total image size: 283036 bytes (.bin may be padded larger) 51920 +231116 +Total image size: 234780 bytes (.bin may be padded larger) 25960 +208820 Per-archive contributions to ELF file: Archive File DRAM .data & 0.bss & 0.rodata IRAM .text & 0.text & 0.vectors & _loader.text ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -669,15 +631,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 17620 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38932 ( +0 remain, +0 total) .text size: 37908 bytes 37908 .vectors size: 1024 bytes 1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 56552 ( +0 remain, +0 total) - .data size: 9324 bytes 9324 - .bss size: 8296 bytes 8296 - .text size: 37908 bytes 37908 - .vectors size: 1024 bytes 1024 Used Flash size : 186524 bytes 186524 .text : 146944 bytes 146944 .rodata : 39580 bytes 39580 -Total image size: 283036 bytes (.bin may be padded larger) 283036 +Total image size: 234780 bytes (.bin may be padded larger) 234780 Per-archive contributions to ELF file: Archive File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -730,18 +687,13 @@ Total sizes of : Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 10604 +7016 ( -7016 remain, +0 total) .data size: 9324 bytes 8580 +744 .bss size: 8296 bytes 2024 +6272 -Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38959 -27 ( +27 remain, +0 total) - .text size: 37908 bytes 37932 -24 - .vectors size: 1024 bytes 1027 -3 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 49563 +6989 ( -6989 remain, +0 total) - .data size: 9324 bytes 8580 +744 - .bss size: 8296 bytes 2024 +6272 - .text size: 37908 bytes 37932 -24 +Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38956 -24 ( +24 remain, +0 total) + .text size: 37908 bytes 37929 -21 .vectors size: 1024 bytes 1027 -3 Used Flash size : 186524 bytes 99551 +86973 .text : 146944 bytes 77191 +69753 .rodata : 39580 bytes 22360 +17220 -Total image size: 283036 bytes (.bin may be padded larger) 194629 +88407 +Total image size: 234780 bytes (.bin may be padded larger) 147087 +87693 Per-archive contributions to ELF file: Archive File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -806,18 +758,13 @@ Total sizes of : Used static DRAM: 10604 bytes ( 170132 remain, 5.9% used) 17620 -7016 ( +7016 remain, +0 total) .data size: 8580 bytes 9324 -744 .bss size: 2024 bytes 8296 -6272 -Used static IRAM: 38959 bytes ( 92113 remain, 29.7% used) 38932 +27 ( -27 remain, +0 total) - .text size: 37932 bytes 37908 +24 - .vectors size: 1027 bytes 1024 +3 -Used stat D/IRAM: 49563 bytes ( 262245 remain, 15.9% used) 56552 -6989 ( +6989 remain, +0 total) - .data size: 8580 bytes 9324 -744 - .bss size: 2024 bytes 8296 -6272 - .text size: 37932 bytes 37908 +24 +Used static IRAM: 38956 bytes ( 92116 remain, 29.7% used) 38932 +24 ( -24 remain, +0 total) + .text size: 37929 bytes 37908 +21 .vectors size: 1027 bytes 1024 +3 Used Flash size : 99551 bytes 186524 -86973 .text : 77191 bytes 146944 -69753 .rodata : 22360 bytes 39580 -17220 -Total image size: 194629 bytes (.bin may be padded larger) 283036 -88407 +Total image size: 147087 bytes (.bin may be padded larger) 234780 -87693 Per-archive contributions to ELF file: Archive File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -886,16 +833,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 7212 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 18796 +20136 ( +13656 remain, +33792 total) .text size: 37908 bytes 18796 +19112 .vectors size: 1024 bytes 0 +1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 26008 +30544 (+118448 remain, +148992 total) - .data size: 9324 bytes 4 +9320 - .bss size: 8296 bytes 48 +8248 - .text size: 37908 bytes 18796 +19112 - .vectors size: 1024 bytes 0 +1024 - .rodata size: 0 bytes 7160 -7160 Used Flash size : 186524 bytes 0 +186524 .text : 146944 bytes 0 +146944 .rodata : 39580 bytes 0 +39580 -Total image size: 283036 bytes (.bin may be padded larger) 51920 +231116 +Total image size: 234780 bytes (.bin may be padded larger) 25960 +208820 Per-file contributions to ELF file: Object File DRAM .data & 0.bss & 0.rodata IRAM .text & 0.text & 0.vectors & _loader.text ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -1185,34 +1126,34 @@ ieee80211_action_vendor. 0 0 0 0 0 wps_internal.o 0 0 0 0 0 0 0 0 0 0 0 The following entries are present in only: Object File DRAM .data & 0.bss & 0.rodata IRAM .text & 0.text & 0.vectors & _loader.text ram_st_total Flash .text & .rodata flash_total - bootloader_utility.c.o 0 1 1607 0 0 0 2216 3824 0 0 3823 - esp_image_format.c.o 0 8 1291 0 0 0 2316 3615 0 0 3607 - bootloader_esp32.c.o 0 0 891 1610 0 0 26 2527 0 0 2527 - rtc_clk.c.o 0 4 160 0 0 0 2217 2381 0 0 2377 - spi_flash_rom_patch.c.o 0 0 0 0 0 0 2110 2110 0 0 2110 - bootloader_flash.c.o 4 1 649 0 0 0 898 1552 0 0 1551 - rtc_clk_init.c.o 0 0 559 773 0 0 0 1332 0 0 1332 - bootloader_random.c.o 0 0 118 0 0 0 1057 1175 0 0 1175 - bootloader_common.c.o 0 0 506 0 0 0 493 999 0 0 999 +bootloader_utility.c.obj 0 1 1607 0 0 0 2216 3824 0 0 3823 + esp_image_format.c.obj 0 8 1291 0 0 0 2316 3615 0 0 3607 + bootloader_esp32.c.obj 0 0 891 1610 0 0 26 2527 0 0 2527 + rtc_clk.c.obj 0 4 160 0 0 0 2217 2381 0 0 2377 +spi_flash_rom_patch.c.ob 0 0 0 0 0 0 2110 2110 0 0 2110 + bootloader_flash.c.obj 4 1 649 0 0 0 898 1552 0 0 1551 + rtc_clk_init.c.obj 0 0 559 773 0 0 0 1332 0 0 1332 + bootloader_random.c.obj 0 0 118 0 0 0 1057 1175 0 0 1175 + bootloader_common.c.obj 0 0 506 0 0 0 493 999 0 0 999 bootloader_flash_config_ 0 0 0 13 0 0 970 983 0 0 983 - rtc_time.c.o 0 0 197 705 0 0 0 902 0 0 902 - bootloader_sha.c.o 0 4 322 0 0 0 479 805 0 0 801 - flash_partitions.c.o 0 0 355 0 0 0 365 720 0 0 720 - rtc_wdt.c.o 0 0 0 0 0 0 710 710 0 0 710 - bootloader_init.c.o 0 24 348 352 0 0 0 724 0 0 700 - flash_qio_mode.c.o 0 0 0 502 0 0 0 502 0 0 502 - rtc_init.c.o 0 0 0 301 0 0 0 301 0 0 301 - bootloader_start.c.o 0 0 59 143 0 0 0 202 0 0 202 - bootloader_clock.c.o 0 0 8 0 0 0 170 178 0 0 178 + rtc_time.c.obj 0 0 197 705 0 0 0 902 0 0 902 + bootloader_sha.c.obj 0 4 322 0 0 0 479 805 0 0 801 + flash_partitions.c.obj 0 0 355 0 0 0 365 720 0 0 720 + rtc_wdt.c.obj 0 0 0 0 0 0 710 710 0 0 710 + bootloader_init.c.obj 0 24 348 352 0 0 0 724 0 0 700 + flash_qio_mode.c.obj 0 0 0 502 0 0 0 502 0 0 502 + rtc_init.c.obj 0 0 0 301 0 0 0 301 0 0 301 + bootloader_start.c.obj 0 0 59 143 0 0 0 202 0 0 202 + bootloader_clock.c.obj 0 0 8 0 0 0 170 178 0 0 178 bootloader_efuse_esp32.c 0 0 0 0 0 0 130 130 0 0 130 - log_noos.c.o 0 0 0 0 0 0 34 34 0 0 34 - cpu_util.c.o 0 0 0 0 0 0 18 18 0 0 18 + log_noos.c.obj 0 0 0 0 0 0 34 34 0 0 34 + cpu_util.c.obj 0 0 0 0 0 0 18 18 0 0 18 crtbegin.o 0 0 8 0 0 0 0 8 0 0 8 crtend.o 0 0 8 0 0 0 0 8 0 0 8 crti.o 0 0 0 3 0 0 3 6 0 0 6 crt0.o 0 0 0 0 0 0 0 0 0 0 0 crtn.o 0 0 0 0 0 0 0 0 0 0 0 - project_elf_src.c.o 0 0 0 0 0 0 0 0 0 0 0 + project_elf_src.c.obj 0 0 0 0 0 0 0 0 0 0 0 lib_a-impure.o 0 0 0 0 0 0 0 0 0 0 0 lib_a-memcmp.o 0 0 0 0 0 0 0 0 0 0 0 lib_a-memcpy.o 0 0 0 0 0 0 0 0 0 0 0 @@ -1222,7 +1163,7 @@ bootloader_efuse_esp32.c 0 0 0 0 0 lib_a-strncpy.o 0 0 0 0 0 0 0 0 0 0 0 lib_a-strstr.o 0 0 0 0 0 0 0 0 0 0 0 _bswapsi2.o 0 0 0 0 0 0 0 0 0 0 0 - gpio_periph.c.o 0 0 0 0 0 0 0 0 0 0 0 + gpio_periph.c.obj 0 0 0 0 0 0 0 0 0 0 0 *** Running idf_size.py diff --files with itself... @@ -1236,15 +1177,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 17620 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38932 ( +0 remain, +0 total) .text size: 37908 bytes 37908 .vectors size: 1024 bytes 1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 56552 ( +0 remain, +0 total) - .data size: 9324 bytes 9324 - .bss size: 8296 bytes 8296 - .text size: 37908 bytes 37908 - .vectors size: 1024 bytes 1024 Used Flash size : 186524 bytes 186524 .text : 146944 bytes 146944 .rodata : 39580 bytes 39580 -Total image size: 283036 bytes (.bin may be padded larger) 283036 +Total image size: 234780 bytes (.bin may be padded larger) 234780 Per-file contributions to ELF file: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -1540,18 +1476,13 @@ Total sizes of : Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 10604 +7016 ( -7016 remain, +0 total) .data size: 9324 bytes 8580 +744 .bss size: 8296 bytes 2024 +6272 -Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38959 -27 ( +27 remain, +0 total) - .text size: 37908 bytes 37932 -24 - .vectors size: 1024 bytes 1027 -3 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 49563 +6989 ( -6989 remain, +0 total) - .data size: 9324 bytes 8580 +744 - .bss size: 8296 bytes 2024 +6272 - .text size: 37908 bytes 37932 -24 +Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38956 -24 ( +24 remain, +0 total) + .text size: 37908 bytes 37929 -21 .vectors size: 1024 bytes 1027 -3 Used Flash size : 186524 bytes 99551 +86973 .text : 146944 bytes 77191 +69753 .rodata : 39580 bytes 22360 +17220 -Total image size: 283036 bytes (.bin may be padded larger) 194629 +88407 +Total image size: 234780 bytes (.bin may be padded larger) 147087 +87693 Per-file contributions to ELF file: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -1841,114 +1772,114 @@ ieee80211_action_vendor. 0 0 0 0 0 wps_internal.o 0 0 0 0 0 0 0 0 The following entries are present in only: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total - tasks.c.o 12 700 5737 0 6449 0 451 6200 - esp_err_to_name.c.o 0 0 0 0 0 53 5101 5154 - vfs_uart.c.o 116 8 0 0 124 3758 783 4657 - panic.c.o 2029 5 2223 0 4257 0 0 4252 - portasm.S.o 3084 0 476 0 3560 0 0 3560 - intr_alloc.c.o 8 22 656 0 686 1681 704 3049 - queue.c.o 0 0 2411 0 2411 0 366 2777 - uart.c.o 56 12 0 0 68 2099 452 2607 - multi_heap.c.o 300 0 2245 0 2545 0 0 2545 - cpu_start.c.o 0 1 1067 0 1068 255 1073 2395 - rtc_clk.c.o 160 4 2104 0 2268 0 0 2264 - vfs.c.o 192 40 0 0 232 1892 132 2216 - gpio.c.o 32 0 0 0 32 1193 970 2195 - spi_flash_hal_iram.c.o 24 0 1798 0 1822 0 0 1822 - xtensa_vectors.S.o 8 0 1344 425 1777 0 36 1813 - task_wdt.c.o 53 4 0 0 57 1223 494 1770 + tasks.c.obj 12 700 5737 0 6449 0 451 6200 + esp_err_to_name.c.obj 0 0 0 0 0 53 5101 5154 + vfs_uart.c.obj 116 8 0 0 124 3758 783 4657 + panic.c.obj 2029 5 2223 0 4257 0 0 4252 + portasm.S.obj 3084 0 476 0 3560 0 0 3560 + intr_alloc.c.obj 8 22 656 0 686 1681 704 3049 + queue.c.obj 0 0 2411 0 2411 0 366 2777 + uart.c.obj 56 12 0 0 68 2099 452 2607 + multi_heap.c.obj 300 0 2245 0 2545 0 0 2545 + cpu_start.c.obj 0 1 1067 0 1068 255 1073 2395 + rtc_clk.c.obj 160 4 2104 0 2268 0 0 2264 + vfs.c.obj 192 40 0 0 232 1892 132 2216 + gpio.c.obj 32 0 0 0 32 1193 970 2195 +spi_flash_hal_iram.c.obj 24 0 1798 0 1822 0 0 1822 + xtensa_vectors.S.obj 8 0 1344 425 1777 0 36 1813 + task_wdt.c.obj 53 4 0 0 57 1223 494 1770 spi_flash_chip_generic.c 340 0 1423 0 1763 0 0 1763 - flash_mmap.c.o 0 264 1320 0 1584 125 296 1741 - cache_utils.c.o 4 14 833 0 851 81 430 1348 - heap_caps.c.o 4 0 884 0 888 50 362 1300 - timers.c.o 8 56 1007 0 1071 0 223 1238 - esp_timer_impl_lac.c.o 8 8 514 0 530 322 389 1233 - heap_caps_init.c.o 0 4 0 0 4 834 379 1213 - soc_memory_layout.c.o 0 0 0 0 0 0 1197 1197 - periph_ctrl.c.o 8 0 0 0 8 696 488 1192 - port.c.o 0 32 737 0 769 0 340 1077 - xtensa_intr_asm.S.o 1024 0 51 0 1075 0 0 1075 + flash_mmap.c.obj 0 264 1320 0 1584 125 296 1741 + cache_utils.c.obj 4 14 833 0 851 81 430 1348 + heap_caps.c.obj 4 0 884 0 888 50 362 1300 + timers.c.obj 8 56 1007 0 1071 0 223 1238 +esp_timer_impl_lac.c.obj 8 8 514 0 530 322 389 1233 + heap_caps_init.c.obj 0 4 0 0 4 834 379 1213 + soc_memory_layout.c.obj 0 0 0 0 0 0 1197 1197 + periph_ctrl.c.obj 8 0 0 0 8 696 488 1192 + port.c.obj 0 32 737 0 769 0 340 1077 + xtensa_intr_asm.S.obj 1024 0 51 0 1075 0 0 1075 bootloader_flash_config_ 0 0 1028 0 1028 17 0 1045 - rtc_time.c.o 0 0 819 0 819 0 194 1013 - ringbuf.c.o 0 0 858 0 858 0 150 1008 - rtc_init.c.o 0 0 956 0 956 0 0 956 - esp_flash_api.c.o 0 0 600 0 600 16 244 860 - clk.c.o 0 0 64 0 64 582 208 854 - partition.c.o 0 8 0 0 8 668 181 849 - time.c.o 0 32 123 0 155 719 0 842 - memory_layout_utils.c.o 0 0 0 0 0 505 295 800 - rtc_wdt.c.o 0 0 796 0 796 0 0 796 - esp_timer.c.o 8 12 280 0 300 401 104 793 - dport_access.c.o 8 40 422 0 470 189 126 745 - ipc.c.o 0 56 192 0 248 367 117 676 - log.c.o 8 264 34 0 306 484 147 673 - locks.c.o 8 0 487 0 495 5 84 584 - esp_flash_spi_init.c.o 120 4 0 0 124 191 261 572 - uart_hal.c.o 0 0 0 0 0 493 0 493 - flash_qio_mode.c.o 0 0 0 0 0 490 0 490 - crosscore_int.c.o 8 8 195 0 211 134 146 483 - int_wdt.c.o 0 1 94 0 95 341 0 435 - system_api_esp32.c.o 0 0 435 0 435 0 0 435 - esp_app_desc.c.o 0 0 109 0 109 12 256 377 + rtc_time.c.obj 0 0 819 0 819 0 194 1013 + ringbuf.c.obj 0 0 858 0 858 0 150 1008 + rtc_init.c.obj 0 0 956 0 956 0 0 956 + esp_flash_api.c.obj 0 0 600 0 600 16 244 860 + clk.c.obj 0 0 64 0 64 582 208 854 + partition.c.obj 0 8 0 0 8 668 181 849 + time.c.obj 0 32 123 0 155 719 0 842 +memory_layout_utils.c.ob 0 0 0 0 0 505 295 800 + rtc_wdt.c.obj 0 0 796 0 796 0 0 796 + esp_timer.c.obj 8 12 280 0 300 401 104 793 + dport_access.c.obj 8 40 422 0 470 189 126 745 + ipc.c.obj 0 56 192 0 248 367 117 676 + log.c.obj 8 264 34 0 306 484 147 673 + locks.c.obj 8 0 487 0 495 5 84 584 +esp_flash_spi_init.c.obj 120 4 0 0 124 191 261 572 + uart_hal.c.obj 0 0 0 0 0 493 0 493 + flash_qio_mode.c.obj 0 0 0 0 0 490 0 490 + crosscore_int.c.obj 8 8 195 0 211 134 146 483 + int_wdt.c.obj 0 1 94 0 95 341 0 435 + system_api_esp32.c.obj 0 0 435 0 435 0 0 435 + esp_app_desc.c.obj 0 0 109 0 109 12 256 377 lib_a-locale.o 364 0 0 0 364 0 10 374 - uart_hal_iram.c.o 0 0 0 0 0 147 222 369 - xtensa_context.S.o 0 0 367 0 367 0 0 367 - esp_ota_ops.c.o 0 4 0 0 4 147 214 361 - spi_flash_hal.c.o 0 0 0 0 0 302 48 350 - brownout.c.o 0 0 0 0 0 120 203 323 - freertos_hooks.c.o 8 128 47 0 183 243 0 298 - spi_flash_chip_gd.c.o 95 0 181 0 276 0 0 276 - brownout_hal.c.o 0 0 0 0 0 269 0 269 + uart_hal_iram.c.obj 0 0 0 0 0 147 222 369 + xtensa_context.S.obj 0 0 367 0 367 0 0 367 + esp_ota_ops.c.obj 0 4 0 0 4 147 214 361 + spi_flash_hal.c.obj 0 0 0 0 0 302 48 350 + brownout.c.obj 0 0 0 0 0 120 203 323 + freertos_hooks.c.obj 8 128 47 0 183 243 0 298 + spi_flash_chip_gd.c.obj 95 0 181 0 276 0 0 276 + brownout_hal.c.obj 0 0 0 0 0 269 0 269 dport_panic_highint_hdl. 12 0 250 0 262 0 0 262 - soc_hal.c.o 24 0 234 0 258 0 0 258 - memspi_host_driver.c.o 43 0 206 0 249 0 0 249 - rtc_module.c.o 16 8 0 0 24 231 0 247 - syscall_table.c.o 144 240 0 0 384 82 0 226 - debug_helpers.c.o 0 0 217 0 217 0 0 217 - spi_flash_chip_issi.c.o 97 0 101 0 198 0 0 198 + soc_hal.c.obj 24 0 234 0 258 0 0 258 +memspi_host_driver.c.obj 43 0 206 0 249 0 0 249 + rtc_module.c.obj 16 8 0 0 24 231 0 247 + syscall_table.c.obj 144 240 0 0 384 82 0 226 + debug_helpers.c.obj 0 0 217 0 217 0 0 217 +spi_flash_chip_issi.c.ob 97 0 101 0 198 0 0 198 pthread_local_storage.c. 8 4 0 0 12 183 0 191 - log_freertos.c.o 0 8 188 0 196 0 0 188 - gpio_periph.c.o 0 0 0 0 0 0 160 160 - cache_err_int.c.o 0 0 56 0 56 98 0 154 - heap.c.o 0 0 151 0 151 0 0 151 - xtensa_intr.c.o 0 0 113 0 113 0 35 148 + log_freertos.c.obj 0 8 188 0 196 0 0 188 + gpio_periph.c.obj 0 0 0 0 0 0 160 160 + cache_err_int.c.obj 0 0 56 0 56 98 0 154 + heap.c.obj 0 0 151 0 151 0 0 151 + xtensa_intr.c.obj 0 0 113 0 113 0 35 148 spi_flash_os_func_noos.c 16 0 127 0 143 0 0 143 spi_flash_os_func_app.c. 24 0 91 0 115 25 0 140 - list.c.o 0 0 138 0 138 0 0 138 - blink.c.o 0 0 0 0 0 72 39 111 - pthread.c.o 0 8 0 0 8 81 0 81 - bootloader_mem.c.o 0 0 0 0 0 58 20 78 - cpu_util.c.o 0 0 75 0 75 0 0 75 + list.c.obj 0 0 138 0 138 0 0 138 + blink.c.obj 0 0 0 0 0 72 39 111 + pthread.c.obj 0 8 0 0 8 81 0 81 + bootloader_mem.c.obj 0 0 0 0 0 58 20 78 + cpu_util.c.obj 0 0 75 0 75 0 0 75 lib_a-mbtowc_r.o 0 0 0 0 0 72 0 72 lib_a-localeconv.o 0 0 0 0 0 63 0 63 - flash_ops.c.o 20 4 14 0 38 29 0 63 - reent_init.c.o 0 0 59 0 59 0 0 59 - rtc_io.c.o 0 0 0 0 0 53 0 53 - syscalls.c.o 0 0 0 0 0 50 0 50 - mpu_hal.c.o 0 0 0 0 0 47 0 47 + flash_ops.c.obj 20 4 14 0 38 29 0 63 + reent_init.c.obj 0 0 59 0 59 0 0 59 + rtc_io.c.obj 0 0 0 0 0 53 0 53 + syscalls.c.obj 0 0 0 0 0 50 0 50 + mpu_hal.c.obj 0 0 0 0 0 47 0 47 xtensa_vector_defaults.S 0 0 46 0 46 0 0 46 - xtensa_init.c.o 0 4 32 0 36 0 0 32 + xtensa_init.c.obj 0 4 32 0 36 0 0 32 spi_flash_chip_drivers.c 20 0 0 0 20 0 0 20 - pthread.c.o 0 0 0 0 0 12 0 12 + pthread.c.obj 0 0 0 0 0 12 0 12 crtend.o 0 0 0 0 0 0 8 8 - pm_esp32.c.o 0 0 0 0 0 8 0 8 - cpu_hal.c.o 0 0 8 0 8 0 0 8 + pm_esp32.c.obj 0 0 0 0 0 8 0 8 + cpu_hal.c.obj 0 0 8 0 8 0 0 8 crti.o 0 0 0 3 3 3 0 6 cxx_exception_stubs.cpp. 0 0 0 0 0 6 0 6 - cxx_guards.cpp.o 0 0 0 0 0 5 0 5 + cxx_guards.cpp.obj 0 0 0 0 0 5 0 5 crtbegin.o 0 0 0 0 0 0 4 4 - FreeRTOS-openocd.c.o 4 0 0 0 4 0 0 4 + FreeRTOS-openocd.c.obj 4 0 0 0 4 0 0 4 crt0.o 0 0 0 0 0 0 0 0 crtn.o 0 0 0 0 0 0 0 0 - project_elf_src.c.o 0 0 0 0 0 0 0 0 - bootloader_common.c.o 0 0 0 0 0 0 0 0 + project_elf_src.c.obj 0 0 0 0 0 0 0 0 + bootloader_common.c.obj 0 0 0 0 0 0 0 0 bootloader_efuse_esp32.c 0 0 0 0 0 0 0 0 - bootloader_flash.c.o 0 0 0 0 0 0 0 0 - bootloader_random.c.o 0 0 0 0 0 0 0 0 - bootloader_sha.c.o 0 0 0 0 0 0 0 0 - bootloader_utility.c.o 0 0 0 0 0 0 0 0 - esp_image_format.c.o 0 0 0 0 0 0 0 0 - flash_partitions.c.o 0 0 0 0 0 0 0 0 + bootloader_flash.c.obj 0 0 0 0 0 0 0 0 + bootloader_random.c.obj 0 0 0 0 0 0 0 0 + bootloader_sha.c.obj 0 0 0 0 0 0 0 0 +bootloader_utility.c.obj 0 0 0 0 0 0 0 0 + esp_image_format.c.obj 0 0 0 0 0 0 0 0 + flash_partitions.c.obj 0 0 0 0 0 0 0 0 isatty.o 0 0 0 0 0 0 0 0 lib_a-bzero.o 0 0 0 0 0 0 0 0 lib_a-ctype_.o 0 0 0 0 0 0 0 0 @@ -2005,25 +1936,25 @@ bootloader_efuse_esp32.c 0 0 0 0 0 lib_a-wcrtomb.o 0 0 0 0 0 0 0 0 lib_a-wctomb_r.o 0 0 0 0 0 0 0 0 lib_a-wsetup.o 0 0 0 0 0 0 0 0 - spi_common.c.o 0 0 0 0 0 0 0 0 - esp_efuse_api.c.o 0 0 0 0 0 0 0 0 - esp_efuse_fields.c.o 0 0 0 0 0 0 0 0 - esp_efuse_table.c.o 0 0 0 0 0 0 0 0 - esp_efuse_utility.c.o 0 0 0 0 0 0 0 0 - hw_random.c.o 0 0 0 0 0 0 0 0 - pm_locks.c.o 0 0 0 0 0 0 0 0 - system_api.c.o 0 0 0 0 0 0 0 0 + spi_common.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_api.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_fields.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_table.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_utility.c.obj 0 0 0 0 0 0 0 0 + hw_random.c.obj 0 0 0 0 0 0 0 0 + pm_locks.c.obj 0 0 0 0 0 0 0 0 + system_api.c.obj 0 0 0 0 0 0 0 0 _bswapsi2.o 0 0 0 0 0 0 0 0 - esp_sha256.c.o 0 0 0 0 0 0 0 0 - sha.c.o 0 0 0 0 0 0 0 0 - gpio_hal.c.o 0 0 0 0 0 0 0 0 - rtc_io_hal.c.o 0 0 0 0 0 0 0 0 - rtc_io_periph.c.o 0 0 0 0 0 0 0 0 - spi_periph.c.o 0 0 0 0 0 0 0 0 - uart_periph.c.o 0 0 0 0 0 0 0 0 - spi_flash_rom_patch.c.o 0 0 0 0 0 0 0 0 - md5-internal.c.o 0 0 0 0 0 0 0 0 - debug_helpers_asm.S.o 0 0 0 0 0 0 0 0 + esp_sha256.c.obj 0 0 0 0 0 0 0 0 + sha.c.obj 0 0 0 0 0 0 0 0 + gpio_hal.c.obj 0 0 0 0 0 0 0 0 + rtc_io_hal.c.obj 0 0 0 0 0 0 0 0 + rtc_io_periph.c.obj 0 0 0 0 0 0 0 0 + spi_periph.c.obj 0 0 0 0 0 0 0 0 + uart_periph.c.obj 0 0 0 0 0 0 0 0 +spi_flash_rom_patch.c.ob 0 0 0 0 0 0 0 0 + md5-internal.c.obj 0 0 0 0 0 0 0 0 + debug_helpers_asm.S.obj 0 0 0 0 0 0 0 0 *** Running idf_size.py diff --files with app in reverse order... @@ -2034,18 +1965,13 @@ Total sizes of : Used static DRAM: 10604 bytes ( 170132 remain, 5.9% used) 17620 -7016 ( +7016 remain, +0 total) .data size: 8580 bytes 9324 -744 .bss size: 2024 bytes 8296 -6272 -Used static IRAM: 38959 bytes ( 92113 remain, 29.7% used) 38932 +27 ( -27 remain, +0 total) - .text size: 37932 bytes 37908 +24 - .vectors size: 1027 bytes 1024 +3 -Used stat D/IRAM: 49563 bytes ( 262245 remain, 15.9% used) 56552 -6989 ( +6989 remain, +0 total) - .data size: 8580 bytes 9324 -744 - .bss size: 2024 bytes 8296 -6272 - .text size: 37932 bytes 37908 +24 +Used static IRAM: 38956 bytes ( 92116 remain, 29.7% used) 38932 +24 ( -24 remain, +0 total) + .text size: 37929 bytes 37908 +21 .vectors size: 1027 bytes 1024 +3 Used Flash size : 99551 bytes 186524 -86973 .text : 77191 bytes 146944 -69753 .rodata : 22360 bytes 39580 -17220 -Total image size: 194629 bytes (.bin may be padded larger) 283036 -88407 +Total image size: 147087 bytes (.bin may be padded larger) 234780 -87693 Per-file contributions to ELF file: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total | | |-| | |-| | |-| | |-| | |-| | |-| | |-| | |- @@ -2091,114 +2017,114 @@ state_asm--save_extra_nw| | | | | | | 62 _popcountsi2.o| | | | | | | | | | | | | | | | | | | | | | | | The following entries are present in only: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total - tasks.c.o 12 700 5737 0 6449 0 451 6200 - esp_err_to_name.c.o 0 0 0 0 0 53 5101 5154 - vfs_uart.c.o 116 8 0 0 124 3758 783 4657 - panic.c.o 2029 5 2223 0 4257 0 0 4252 - portasm.S.o 3084 0 476 0 3560 0 0 3560 - intr_alloc.c.o 8 22 656 0 686 1681 704 3049 - queue.c.o 0 0 2411 0 2411 0 366 2777 - uart.c.o 56 12 0 0 68 2099 452 2607 - multi_heap.c.o 300 0 2245 0 2545 0 0 2545 - cpu_start.c.o 0 1 1067 0 1068 255 1073 2395 - rtc_clk.c.o 160 4 2104 0 2268 0 0 2264 - vfs.c.o 192 40 0 0 232 1892 132 2216 - gpio.c.o 32 0 0 0 32 1193 970 2195 - spi_flash_hal_iram.c.o 24 0 1798 0 1822 0 0 1822 - xtensa_vectors.S.o 8 0 1344 425 1777 0 36 1813 - task_wdt.c.o 53 4 0 0 57 1223 494 1770 + tasks.c.obj 12 700 5737 0 6449 0 451 6200 + esp_err_to_name.c.obj 0 0 0 0 0 53 5101 5154 + vfs_uart.c.obj 116 8 0 0 124 3758 783 4657 + panic.c.obj 2029 5 2223 0 4257 0 0 4252 + portasm.S.obj 3084 0 476 0 3560 0 0 3560 + intr_alloc.c.obj 8 22 656 0 686 1681 704 3049 + queue.c.obj 0 0 2411 0 2411 0 366 2777 + uart.c.obj 56 12 0 0 68 2099 452 2607 + multi_heap.c.obj 300 0 2245 0 2545 0 0 2545 + cpu_start.c.obj 0 1 1067 0 1068 255 1073 2395 + rtc_clk.c.obj 160 4 2104 0 2268 0 0 2264 + vfs.c.obj 192 40 0 0 232 1892 132 2216 + gpio.c.obj 32 0 0 0 32 1193 970 2195 +spi_flash_hal_iram.c.obj 24 0 1798 0 1822 0 0 1822 + xtensa_vectors.S.obj 8 0 1344 425 1777 0 36 1813 + task_wdt.c.obj 53 4 0 0 57 1223 494 1770 spi_flash_chip_generic.c 340 0 1423 0 1763 0 0 1763 - flash_mmap.c.o 0 264 1320 0 1584 125 296 1741 - cache_utils.c.o 4 14 833 0 851 81 430 1348 - heap_caps.c.o 4 0 884 0 888 50 362 1300 - timers.c.o 8 56 1007 0 1071 0 223 1238 - esp_timer_impl_lac.c.o 8 8 514 0 530 322 389 1233 - heap_caps_init.c.o 0 4 0 0 4 834 379 1213 - soc_memory_layout.c.o 0 0 0 0 0 0 1197 1197 - periph_ctrl.c.o 8 0 0 0 8 696 488 1192 - port.c.o 0 32 737 0 769 0 340 1077 - xtensa_intr_asm.S.o 1024 0 51 0 1075 0 0 1075 + flash_mmap.c.obj 0 264 1320 0 1584 125 296 1741 + cache_utils.c.obj 4 14 833 0 851 81 430 1348 + heap_caps.c.obj 4 0 884 0 888 50 362 1300 + timers.c.obj 8 56 1007 0 1071 0 223 1238 +esp_timer_impl_lac.c.obj 8 8 514 0 530 322 389 1233 + heap_caps_init.c.obj 0 4 0 0 4 834 379 1213 + soc_memory_layout.c.obj 0 0 0 0 0 0 1197 1197 + periph_ctrl.c.obj 8 0 0 0 8 696 488 1192 + port.c.obj 0 32 737 0 769 0 340 1077 + xtensa_intr_asm.S.obj 1024 0 51 0 1075 0 0 1075 bootloader_flash_config_ 0 0 1028 0 1028 17 0 1045 - rtc_time.c.o 0 0 819 0 819 0 194 1013 - ringbuf.c.o 0 0 858 0 858 0 150 1008 - rtc_init.c.o 0 0 956 0 956 0 0 956 - esp_flash_api.c.o 0 0 600 0 600 16 244 860 - clk.c.o 0 0 64 0 64 582 208 854 - partition.c.o 0 8 0 0 8 668 181 849 - time.c.o 0 32 123 0 155 719 0 842 - memory_layout_utils.c.o 0 0 0 0 0 505 295 800 - rtc_wdt.c.o 0 0 796 0 796 0 0 796 - esp_timer.c.o 8 12 280 0 300 401 104 793 - dport_access.c.o 8 40 422 0 470 189 126 745 - ipc.c.o 0 56 192 0 248 367 117 676 - log.c.o 8 264 34 0 306 484 147 673 - locks.c.o 8 0 487 0 495 5 84 584 - esp_flash_spi_init.c.o 120 4 0 0 124 191 261 572 - uart_hal.c.o 0 0 0 0 0 493 0 493 - flash_qio_mode.c.o 0 0 0 0 0 490 0 490 - crosscore_int.c.o 8 8 195 0 211 134 146 483 - int_wdt.c.o 0 1 94 0 95 341 0 435 - system_api_esp32.c.o 0 0 435 0 435 0 0 435 - esp_app_desc.c.o 0 0 109 0 109 12 256 377 + rtc_time.c.obj 0 0 819 0 819 0 194 1013 + ringbuf.c.obj 0 0 858 0 858 0 150 1008 + rtc_init.c.obj 0 0 956 0 956 0 0 956 + esp_flash_api.c.obj 0 0 600 0 600 16 244 860 + clk.c.obj 0 0 64 0 64 582 208 854 + partition.c.obj 0 8 0 0 8 668 181 849 + time.c.obj 0 32 123 0 155 719 0 842 +memory_layout_utils.c.ob 0 0 0 0 0 505 295 800 + rtc_wdt.c.obj 0 0 796 0 796 0 0 796 + esp_timer.c.obj 8 12 280 0 300 401 104 793 + dport_access.c.obj 8 40 422 0 470 189 126 745 + ipc.c.obj 0 56 192 0 248 367 117 676 + log.c.obj 8 264 34 0 306 484 147 673 + locks.c.obj 8 0 487 0 495 5 84 584 +esp_flash_spi_init.c.obj 120 4 0 0 124 191 261 572 + uart_hal.c.obj 0 0 0 0 0 493 0 493 + flash_qio_mode.c.obj 0 0 0 0 0 490 0 490 + crosscore_int.c.obj 8 8 195 0 211 134 146 483 + int_wdt.c.obj 0 1 94 0 95 341 0 435 + system_api_esp32.c.obj 0 0 435 0 435 0 0 435 + esp_app_desc.c.obj 0 0 109 0 109 12 256 377 lib_a-locale.o 364 0 0 0 364 0 10 374 - uart_hal_iram.c.o 0 0 0 0 0 147 222 369 - xtensa_context.S.o 0 0 367 0 367 0 0 367 - esp_ota_ops.c.o 0 4 0 0 4 147 214 361 - spi_flash_hal.c.o 0 0 0 0 0 302 48 350 - brownout.c.o 0 0 0 0 0 120 203 323 - freertos_hooks.c.o 8 128 47 0 183 243 0 298 - spi_flash_chip_gd.c.o 95 0 181 0 276 0 0 276 - brownout_hal.c.o 0 0 0 0 0 269 0 269 + uart_hal_iram.c.obj 0 0 0 0 0 147 222 369 + xtensa_context.S.obj 0 0 367 0 367 0 0 367 + esp_ota_ops.c.obj 0 4 0 0 4 147 214 361 + spi_flash_hal.c.obj 0 0 0 0 0 302 48 350 + brownout.c.obj 0 0 0 0 0 120 203 323 + freertos_hooks.c.obj 8 128 47 0 183 243 0 298 + spi_flash_chip_gd.c.obj 95 0 181 0 276 0 0 276 + brownout_hal.c.obj 0 0 0 0 0 269 0 269 dport_panic_highint_hdl. 12 0 250 0 262 0 0 262 - soc_hal.c.o 24 0 234 0 258 0 0 258 - memspi_host_driver.c.o 43 0 206 0 249 0 0 249 - rtc_module.c.o 16 8 0 0 24 231 0 247 - syscall_table.c.o 144 240 0 0 384 82 0 226 - debug_helpers.c.o 0 0 217 0 217 0 0 217 - spi_flash_chip_issi.c.o 97 0 101 0 198 0 0 198 + soc_hal.c.obj 24 0 234 0 258 0 0 258 +memspi_host_driver.c.obj 43 0 206 0 249 0 0 249 + rtc_module.c.obj 16 8 0 0 24 231 0 247 + syscall_table.c.obj 144 240 0 0 384 82 0 226 + debug_helpers.c.obj 0 0 217 0 217 0 0 217 +spi_flash_chip_issi.c.ob 97 0 101 0 198 0 0 198 pthread_local_storage.c. 8 4 0 0 12 183 0 191 - log_freertos.c.o 0 8 188 0 196 0 0 188 - gpio_periph.c.o 0 0 0 0 0 0 160 160 - cache_err_int.c.o 0 0 56 0 56 98 0 154 - heap.c.o 0 0 151 0 151 0 0 151 - xtensa_intr.c.o 0 0 113 0 113 0 35 148 + log_freertos.c.obj 0 8 188 0 196 0 0 188 + gpio_periph.c.obj 0 0 0 0 0 0 160 160 + cache_err_int.c.obj 0 0 56 0 56 98 0 154 + heap.c.obj 0 0 151 0 151 0 0 151 + xtensa_intr.c.obj 0 0 113 0 113 0 35 148 spi_flash_os_func_noos.c 16 0 127 0 143 0 0 143 spi_flash_os_func_app.c. 24 0 91 0 115 25 0 140 - list.c.o 0 0 138 0 138 0 0 138 - blink.c.o 0 0 0 0 0 72 39 111 - pthread.c.o 0 8 0 0 8 81 0 81 - bootloader_mem.c.o 0 0 0 0 0 58 20 78 - cpu_util.c.o 0 0 75 0 75 0 0 75 + list.c.obj 0 0 138 0 138 0 0 138 + blink.c.obj 0 0 0 0 0 72 39 111 + pthread.c.obj 0 8 0 0 8 81 0 81 + bootloader_mem.c.obj 0 0 0 0 0 58 20 78 + cpu_util.c.obj 0 0 75 0 75 0 0 75 lib_a-mbtowc_r.o 0 0 0 0 0 72 0 72 lib_a-localeconv.o 0 0 0 0 0 63 0 63 - flash_ops.c.o 20 4 14 0 38 29 0 63 - reent_init.c.o 0 0 59 0 59 0 0 59 - rtc_io.c.o 0 0 0 0 0 53 0 53 - syscalls.c.o 0 0 0 0 0 50 0 50 - mpu_hal.c.o 0 0 0 0 0 47 0 47 + flash_ops.c.obj 20 4 14 0 38 29 0 63 + reent_init.c.obj 0 0 59 0 59 0 0 59 + rtc_io.c.obj 0 0 0 0 0 53 0 53 + syscalls.c.obj 0 0 0 0 0 50 0 50 + mpu_hal.c.obj 0 0 0 0 0 47 0 47 xtensa_vector_defaults.S 0 0 46 0 46 0 0 46 - xtensa_init.c.o 0 4 32 0 36 0 0 32 + xtensa_init.c.obj 0 4 32 0 36 0 0 32 spi_flash_chip_drivers.c 20 0 0 0 20 0 0 20 - pthread.c.o 0 0 0 0 0 12 0 12 + pthread.c.obj 0 0 0 0 0 12 0 12 crtend.o 0 0 0 0 0 0 8 8 - pm_esp32.c.o 0 0 0 0 0 8 0 8 - cpu_hal.c.o 0 0 8 0 8 0 0 8 + pm_esp32.c.obj 0 0 0 0 0 8 0 8 + cpu_hal.c.obj 0 0 8 0 8 0 0 8 crti.o 0 0 0 3 3 3 0 6 cxx_exception_stubs.cpp. 0 0 0 0 0 6 0 6 - cxx_guards.cpp.o 0 0 0 0 0 5 0 5 + cxx_guards.cpp.obj 0 0 0 0 0 5 0 5 crtbegin.o 0 0 0 0 0 0 4 4 - FreeRTOS-openocd.c.o 4 0 0 0 4 0 0 4 + FreeRTOS-openocd.c.obj 4 0 0 0 4 0 0 4 crt0.o 0 0 0 0 0 0 0 0 crtn.o 0 0 0 0 0 0 0 0 - project_elf_src.c.o 0 0 0 0 0 0 0 0 - bootloader_common.c.o 0 0 0 0 0 0 0 0 + project_elf_src.c.obj 0 0 0 0 0 0 0 0 + bootloader_common.c.obj 0 0 0 0 0 0 0 0 bootloader_efuse_esp32.c 0 0 0 0 0 0 0 0 - bootloader_flash.c.o 0 0 0 0 0 0 0 0 - bootloader_random.c.o 0 0 0 0 0 0 0 0 - bootloader_sha.c.o 0 0 0 0 0 0 0 0 - bootloader_utility.c.o 0 0 0 0 0 0 0 0 - esp_image_format.c.o 0 0 0 0 0 0 0 0 - flash_partitions.c.o 0 0 0 0 0 0 0 0 + bootloader_flash.c.obj 0 0 0 0 0 0 0 0 + bootloader_random.c.obj 0 0 0 0 0 0 0 0 + bootloader_sha.c.obj 0 0 0 0 0 0 0 0 +bootloader_utility.c.obj 0 0 0 0 0 0 0 0 + esp_image_format.c.obj 0 0 0 0 0 0 0 0 + flash_partitions.c.obj 0 0 0 0 0 0 0 0 isatty.o 0 0 0 0 0 0 0 0 lib_a-bzero.o 0 0 0 0 0 0 0 0 lib_a-ctype_.o 0 0 0 0 0 0 0 0 @@ -2255,25 +2181,25 @@ bootloader_efuse_esp32.c 0 0 0 0 0 lib_a-wcrtomb.o 0 0 0 0 0 0 0 0 lib_a-wctomb_r.o 0 0 0 0 0 0 0 0 lib_a-wsetup.o 0 0 0 0 0 0 0 0 - spi_common.c.o 0 0 0 0 0 0 0 0 - esp_efuse_api.c.o 0 0 0 0 0 0 0 0 - esp_efuse_fields.c.o 0 0 0 0 0 0 0 0 - esp_efuse_table.c.o 0 0 0 0 0 0 0 0 - esp_efuse_utility.c.o 0 0 0 0 0 0 0 0 - hw_random.c.o 0 0 0 0 0 0 0 0 - pm_locks.c.o 0 0 0 0 0 0 0 0 - system_api.c.o 0 0 0 0 0 0 0 0 + spi_common.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_api.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_fields.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_table.c.obj 0 0 0 0 0 0 0 0 + esp_efuse_utility.c.obj 0 0 0 0 0 0 0 0 + hw_random.c.obj 0 0 0 0 0 0 0 0 + pm_locks.c.obj 0 0 0 0 0 0 0 0 + system_api.c.obj 0 0 0 0 0 0 0 0 _bswapsi2.o 0 0 0 0 0 0 0 0 - esp_sha256.c.o 0 0 0 0 0 0 0 0 - sha.c.o 0 0 0 0 0 0 0 0 - gpio_hal.c.o 0 0 0 0 0 0 0 0 - rtc_io_hal.c.o 0 0 0 0 0 0 0 0 - rtc_io_periph.c.o 0 0 0 0 0 0 0 0 - spi_periph.c.o 0 0 0 0 0 0 0 0 - uart_periph.c.o 0 0 0 0 0 0 0 0 - spi_flash_rom_patch.c.o 0 0 0 0 0 0 0 0 - md5-internal.c.o 0 0 0 0 0 0 0 0 - debug_helpers_asm.S.o 0 0 0 0 0 0 0 0 + esp_sha256.c.obj 0 0 0 0 0 0 0 0 + sha.c.obj 0 0 0 0 0 0 0 0 + gpio_hal.c.obj 0 0 0 0 0 0 0 0 + rtc_io_hal.c.obj 0 0 0 0 0 0 0 0 + rtc_io_periph.c.obj 0 0 0 0 0 0 0 0 + spi_periph.c.obj 0 0 0 0 0 0 0 0 + uart_periph.c.obj 0 0 0 0 0 0 0 0 +spi_flash_rom_patch.c.ob 0 0 0 0 0 0 0 0 + md5-internal.c.obj 0 0 0 0 0 0 0 0 + debug_helpers_asm.S.obj 0 0 0 0 0 0 0 0 The following entries are present in only: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total tcp_in.o 0 54 0 0 54 8127 916 9043 @@ -2532,16 +2458,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 7212 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 18796 +20136 ( +13656 remain, +33792 total) .text size: 37908 bytes 18796 +19112 .vectors size: 1024 bytes 0 +1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 26008 +30544 (+118448 remain, +148992 total) - .data size: 9324 bytes 4 +9320 - .bss size: 8296 bytes 48 +8248 - .text size: 37908 bytes 18796 +19112 - .vectors size: 1024 bytes 0 +1024 - .rodata size: 0 bytes 7160 -7160 Used Flash size : 186524 bytes 0 +186524 .text : 146944 bytes 0 +146944 .rodata : 39580 bytes 0 +39580 -Total image size: 283036 bytes (.bin may be padded larger) 51920 +231116 +Total image size: 234780 bytes (.bin may be padded larger) 25960 +208820 Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -2625,16 +2545,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 7212 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 18796 +20136 ( +13656 remain, +33792 total) .text size: 37908 bytes 18796 +19112 .vectors size: 1024 bytes 0 +1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 26008 +30544 (+118448 remain, +148992 total) - .data size: 9324 bytes 4 +9320 - .bss size: 8296 bytes 48 +8248 - .text size: 37908 bytes 18796 +19112 - .vectors size: 1024 bytes 0 +1024 - .rodata size: 0 bytes 7160 -7160 Used Flash size : 186524 bytes 0 +186524 .text : 146944 bytes 0 +146944 .rodata : 39580 bytes 0 +39580 -Total image size: 283036 bytes (.bin may be padded larger) 51920 +231116 +Total image size: 234780 bytes (.bin may be padded larger) 25960 +208820 Symbols within the archive: libc.a (Not all symbols may be reported) @@ -2696,15 +2610,10 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 17620 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38932 ( +0 remain, +0 total) .text size: 37908 bytes 37908 .vectors size: 1024 bytes 1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 56552 ( +0 remain, +0 total) - .data size: 9324 bytes 9324 - .bss size: 8296 bytes 8296 - .text size: 37908 bytes 37908 - .vectors size: 1024 bytes 1024 Used Flash size : 186524 bytes 186524 .text : 146944 bytes 146944 .rodata : 39580 bytes 39580 -Total image size: 283036 bytes (.bin may be padded larger) 283036 +Total image size: 234780 bytes (.bin may be padded larger) 234780 Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -2775,18 +2684,13 @@ Total sizes of : Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 10604 +7016 ( -7016 remain, +0 total) .data size: 9324 bytes 8580 +744 .bss size: 8296 bytes 2024 +6272 -Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38959 -27 ( +27 remain, +0 total) - .text size: 37908 bytes 37932 -24 - .vectors size: 1024 bytes 1027 -3 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 49563 +6989 ( -6989 remain, +0 total) - .data size: 9324 bytes 8580 +744 - .bss size: 8296 bytes 2024 +6272 - .text size: 37908 bytes 37932 -24 +Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38956 -24 ( +24 remain, +0 total) + .text size: 37908 bytes 37929 -21 .vectors size: 1024 bytes 1027 -3 Used Flash size : 186524 bytes 99551 +86973 .text : 146944 bytes 77191 +69753 .rodata : 39580 bytes 22360 +17220 -Total image size: 283036 bytes (.bin may be padded larger) 194629 +88407 +Total image size: 234780 bytes (.bin may be padded larger) 147087 +87693 Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -2895,9 +2799,6 @@ Section total: 961 4272 .iram0.text - Section total: 0 0 -.iram0.text_end - -Section total: 0 0 - .iram0.vectors - Section total: 0 0 @@ -2925,18 +2826,13 @@ Total sizes of : Used static DRAM: 10604 bytes ( 170132 remain, 5.9% used) 17620 -7016 ( +7016 remain, +0 total) .data size: 8580 bytes 9324 -744 .bss size: 2024 bytes 8296 -6272 -Used static IRAM: 38959 bytes ( 92113 remain, 29.7% used) 38932 +27 ( -27 remain, +0 total) - .text size: 37932 bytes 37908 +24 - .vectors size: 1027 bytes 1024 +3 -Used stat D/IRAM: 49563 bytes ( 262245 remain, 15.9% used) 56552 -6989 ( +6989 remain, +0 total) - .data size: 8580 bytes 9324 -744 - .bss size: 2024 bytes 8296 -6272 - .text size: 37932 bytes 37908 +24 +Used static IRAM: 38956 bytes ( 92116 remain, 29.7% used) 38932 +24 ( -24 remain, +0 total) + .text size: 37929 bytes 37908 +21 .vectors size: 1027 bytes 1024 +3 Used Flash size : 99551 bytes 186524 -86973 .text : 77191 bytes 146944 -69753 .rodata : 22360 bytes 39580 -17220 -Total image size: 194629 bytes (.bin may be padded larger) 283036 -88407 +Total image size: 147087 bytes (.bin may be padded larger) 234780 -87693 Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -3045,9 +2941,6 @@ Section total: 4272 961 .iram0.text - Section total: 0 0 -.iram0.text_end - -Section total: 0 0 - .iram0.vectors - Section total: 0 0 @@ -3075,18 +2968,13 @@ Total sizes of : Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 10604 +7016 ( -7016 remain, +0 total) .data size: 9324 bytes 8580 +744 .bss size: 8296 bytes 2024 +6272 -Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38959 -27 ( +27 remain, +0 total) - .text size: 37908 bytes 37932 -24 - .vectors size: 1024 bytes 1027 -3 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 49563 +6989 ( -6989 remain, +0 total) - .data size: 9324 bytes 8580 +744 - .bss size: 8296 bytes 2024 +6272 - .text size: 37908 bytes 37932 -24 +Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 38956 -24 ( +24 remain, +0 total) + .text size: 37908 bytes 37929 -21 .vectors size: 1024 bytes 1027 -3 Used Flash size : 186524 bytes 99551 +86973 .text : 146944 bytes 77191 +69753 .rodata : 39580 bytes 22360 +17220 -Total image size: 283036 bytes (.bin may be padded larger) 194629 +88407 +Total image size: 234780 bytes (.bin may be padded larger) 147087 +87693 Symbols within the archive: libfreertos.a (Not all symbols may be reported) @@ -3344,9 +3232,6 @@ Section total: 0 0 xt_unhandled_interrupt 26 26 Section total: 12428 12459 -31 -.iram0.text_end - -Section total: 0 0 - .iram0.vectors - .DebugExceptionVector.text 6 6 .DoubleExceptionVector.text 15 15 @@ -3378,15 +3263,15 @@ Section total: 0 0 *** Running idf_size.py for esp32s2... Total sizes: -Used stat D/IRAM: 43023 bytes ( 153585 remain, 21.9% used) +Used stat D/IRAM: 43020 bytes ( 153588 remain, 21.9% used) .data size: 7152 bytes .bss size: 1936 bytes - .text size: 32908 bytes + .text size: 32905 bytes .vectors size: 1027 bytes Used Flash size : 93019 bytes .text : 74439 bytes .rodata : 18580 bytes -Total image size: 134106 bytes (.bin may be padded larger) +Total image size: 134103 bytes (.bin may be padded larger) *** Running idf_size.py for esp32s2 with overflow... @@ -3404,15 +3289,15 @@ Total image size: 708078 bytes (.bin may be padded larger) *** Running idf_size.py for esp32s2 (target autodetected)... Total sizes: -Used stat D/IRAM: 43023 bytes ( 153585 remain, 21.9% used) +Used stat D/IRAM: 43020 bytes ( 153588 remain, 21.9% used) .data size: 7152 bytes .bss size: 1936 bytes - .text size: 32908 bytes + .text size: 32905 bytes .vectors size: 1027 bytes Used Flash size : 93019 bytes .text : 74439 bytes .rodata : 18580 bytes -Total image size: 134106 bytes (.bin may be padded larger) +Total image size: 134103 bytes (.bin may be padded larger) *** Running idf_size.py on bootloader for esp32s2... @@ -3437,15 +3322,15 @@ Total image size: 22305 bytes (.bin may be padded larger) *** Running idf_size.py --archives for esp32s2... Total sizes: -Used stat D/IRAM: 43023 bytes ( 153585 remain, 21.9% used) +Used stat D/IRAM: 43020 bytes ( 153588 remain, 21.9% used) .data size: 7152 bytes .bss size: 1936 bytes - .text size: 32908 bytes + .text size: 32905 bytes .vectors size: 1027 bytes Used Flash size : 93019 bytes .text : 74439 bytes .rodata : 18580 bytes -Total image size: 134106 bytes (.bin may be padded larger) +Total image size: 134103 bytes (.bin may be padded larger) Per-archive contributions to ELF file: Archive File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total libc.a 364 4 0 0 368 54964 3645 58973 @@ -3477,143 +3362,143 @@ Per-archive contributions to ELF file: *** Running idf_size.py --files for esp32s2... Total sizes: -Used stat D/IRAM: 43023 bytes ( 153585 remain, 21.9% used) +Used stat D/IRAM: 43020 bytes ( 153588 remain, 21.9% used) .data size: 7152 bytes .bss size: 1936 bytes - .text size: 32908 bytes + .text size: 32905 bytes .vectors size: 1027 bytes Used Flash size : 93019 bytes .text : 74439 bytes .rodata : 18580 bytes -Total image size: 134106 bytes (.bin may be padded larger) +Total image size: 134103 bytes (.bin may be padded larger) Per-file contributions to ELF file: Object File DRAM .data & 0.bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata flash_total lib_a-vfprintf.o 0 0 0 0 0 13681 700 14381 lib_a-svfprintf.o 0 0 0 0 0 13294 752 14046 lib_a-svfiprintf.o 0 0 0 0 0 9623 1172 10795 lib_a-vfiprintf.o 0 0 0 0 0 9933 700 10633 - tasks.c.o 12 660 4954 0 5626 0 406 5372 - esp_err_to_name.c.o 0 0 0 0 0 53 5101 5154 - panic.c.o 2552 1 2321 0 4874 0 0 4873 - vfs_uart.c.o 80 8 0 0 88 3689 423 4192 + tasks.c.obj 12 660 4954 0 5626 0 406 5372 + esp_err_to_name.c.obj 0 0 0 0 0 53 5101 5154 + panic.c.obj 2552 1 2321 0 4874 0 0 4873 + vfs_uart.c.obj 80 8 0 0 88 3689 423 4192 lib_a-dtoa.o 0 0 0 0 0 3524 13 3537 - intr_alloc.c.o 8 13 660 0 681 1682 706 3056 - queue.c.o 0 0 2397 0 2397 0 424 2821 - uart.c.o 40 8 0 0 48 2087 452 2579 - multi_heap.c.o 300 0 2273 0 2573 0 0 2573 + intr_alloc.c.obj 8 13 660 0 681 1682 706 3056 + queue.c.obj 0 0 2397 0 2397 0 424 2821 + uart.c.obj 40 8 0 0 48 2087 452 2579 + multi_heap.c.obj 300 0 2273 0 2573 0 0 2573 lib_a-mprec.o 0 0 0 0 0 2144 296 2440 - rtc_clk.c.o 381 8 1867 0 2256 0 0 2248 - vfs.c.o 192 40 0 0 232 1892 132 2216 - portasm.S.o 1544 0 365 0 1909 0 0 1909 - spi_flash_hal_iram.c.o 24 0 1804 0 1828 0 0 1828 + rtc_clk.c.obj 381 8 1867 0 2256 0 0 2248 + vfs.c.obj 192 40 0 0 232 1892 132 2216 + portasm.S.obj 1544 0 365 0 1909 0 0 1909 +spi_flash_hal_iram.c.obj 24 0 1804 0 1828 0 0 1828 spi_flash_chip_generic.c 340 0 1417 0 1757 0 0 1757 - task_wdt.c.o 53 4 0 0 57 1190 496 1739 - flash_mmap.c.o 0 392 1200 0 1592 124 252 1576 - heap_caps.c.o 4 0 898 0 902 50 362 1314 - xtensa_vectors.S.o 0 0 864 425 1289 0 0 1289 - rtc_init.c.o 0 0 1255 0 1255 0 8 1263 - timers.c.o 8 56 987 0 1051 0 223 1218 - heap_caps_init.c.o 0 4 0 0 4 838 379 1217 - cpu_start.c.o 0 0 536 0 536 152 489 1177 + task_wdt.c.obj 53 4 0 0 57 1190 496 1739 + flash_mmap.c.obj 0 392 1200 0 1592 124 252 1576 + heap_caps.c.obj 4 0 898 0 902 50 362 1314 + xtensa_vectors.S.obj 0 0 864 425 1289 0 0 1289 + rtc_init.c.obj 0 0 1255 0 1255 0 8 1263 + timers.c.obj 8 56 987 0 1051 0 223 1218 + heap_caps_init.c.obj 0 4 0 0 4 838 379 1217 + cpu_start.c.obj 0 0 536 0 536 152 489 1177 esp_timer_impl_systimer. 8 8 388 0 404 252 442 1090 - ringbuf.c.o 0 0 858 0 858 0 150 1008 - periph_ctrl.c.o 8 0 0 0 8 661 272 941 - clk.c.o 0 0 34 0 34 626 281 941 + ringbuf.c.obj 0 0 858 0 858 0 150 1008 + periph_ctrl.c.obj 8 0 0 0 8 661 272 941 + clk.c.obj 0 0 34 0 34 626 281 941 lib_a-fseeko.o 0 0 0 0 0 910 0 910 - partition.c.o 0 8 0 0 8 679 181 860 - esp_flash_api.c.o 0 0 600 0 600 16 240 856 - time.c.o 0 32 115 0 147 719 0 834 - memory_layout_utils.c.o 0 0 0 0 0 509 295 804 - rtc_wdt.c.o 0 0 800 0 800 0 0 800 - esp_timer.c.o 8 12 280 0 300 405 104 797 - log.c.o 8 264 406 0 678 94 147 655 - rtc_time.c.o 0 0 626 0 626 0 0 626 - esp_flash_spi_init.c.o 120 4 0 0 124 215 281 616 - locks.c.o 8 0 487 0 495 5 84 584 - xtensa_intr_asm.S.o 512 0 51 0 563 0 0 563 - port.c.o 0 16 408 0 424 0 87 495 - crosscore_int.c.o 8 4 154 0 166 86 237 485 - soc_memory_layout.c.o 0 0 0 0 0 0 479 479 - rtc_sleep.c.o 0 0 414 0 414 0 0 414 - uart_hal.c.o 0 0 0 0 0 409 0 409 - spi_flash_hal.c.o 0 0 0 0 0 309 96 405 - cache_utils.c.o 0 8 197 0 205 21 176 394 - hello_world_main.c.o 0 0 0 0 0 192 196 388 + partition.c.obj 0 8 0 0 8 679 181 860 + esp_flash_api.c.obj 0 0 600 0 600 16 240 856 + time.c.obj 0 32 115 0 147 719 0 834 +memory_layout_utils.c.ob 0 0 0 0 0 509 295 804 + rtc_wdt.c.obj 0 0 800 0 800 0 0 800 + esp_timer.c.obj 8 12 280 0 300 405 104 797 + log.c.obj 8 264 406 0 678 94 147 655 + rtc_time.c.obj 0 0 626 0 626 0 0 626 +esp_flash_spi_init.c.obj 120 4 0 0 124 215 281 616 + locks.c.obj 8 0 487 0 495 5 84 584 + xtensa_intr_asm.S.obj 512 0 51 0 563 0 0 563 + port.c.obj 0 16 408 0 424 0 87 495 + crosscore_int.c.obj 8 4 154 0 166 86 237 485 + soc_memory_layout.c.obj 0 0 0 0 0 0 479 479 + rtc_sleep.c.obj 0 0 414 0 414 0 0 414 + uart_hal.c.obj 0 0 0 0 0 409 0 409 + spi_flash_hal.c.obj 0 0 0 0 0 309 96 405 + cache_utils.c.obj 0 8 197 0 205 21 176 394 + hello_world_main.c.obj 0 0 0 0 0 192 196 388 lib_a-locale.o 364 0 0 0 364 0 10 374 - timer.c.o 16 16 0 0 32 184 170 370 + timer.c.obj 16 16 0 0 32 184 170 370 lib_a-refill.o 0 0 0 0 0 368 0 368 - esp_ota_ops.c.o 0 4 0 0 4 151 214 365 - int_wdt.c.o 0 0 59 0 59 302 0 361 - system_api_esp32s2.c.o 0 0 323 0 323 27 0 350 - brownout.c.o 0 0 0 0 0 120 203 323 + esp_ota_ops.c.obj 0 4 0 0 4 151 214 365 + int_wdt.c.obj 0 0 59 0 59 302 0 361 +system_api_esp32s2.c.obj 0 0 323 0 323 27 0 350 + brownout.c.obj 0 0 0 0 0 120 203 323 windowspill_asm.o 0 0 315 0 315 0 0 315 - cpu_util.c.o 0 0 309 0 309 0 0 309 - brownout_hal.c.o 0 0 0 0 0 304 0 304 - freertos_hooks.c.o 8 64 47 0 119 243 0 298 - spi_flash_chip_gd.c.o 95 0 181 0 276 0 0 276 - esp_app_desc.c.o 0 0 0 0 0 0 256 256 - memspi_host_driver.c.o 43 0 206 0 249 0 0 249 - rtc_module.c.o 16 8 0 0 24 231 0 247 + cpu_util.c.obj 0 0 309 0 309 0 0 309 + brownout_hal.c.obj 0 0 0 0 0 304 0 304 + freertos_hooks.c.obj 8 64 47 0 119 243 0 298 + spi_flash_chip_gd.c.obj 95 0 181 0 276 0 0 276 + esp_app_desc.c.obj 0 0 0 0 0 0 256 256 +memspi_host_driver.c.obj 43 0 206 0 249 0 0 249 + rtc_module.c.obj 16 8 0 0 24 231 0 247 lib_a-fopen.o 0 0 0 0 0 244 0 244 lib_a-puts.o 0 0 0 0 0 234 2 236 lib_a-reent.o 0 0 0 0 0 236 0 236 lib_a-snprintf.o 0 0 0 0 0 217 0 217 - syscall_table.c.o 144 240 0 0 384 70 0 214 - xtensa_context.S.o 0 0 201 0 201 0 0 201 - spi_flash_chip_issi.c.o 97 0 101 0 198 0 0 198 + syscall_table.c.obj 144 240 0 0 384 70 0 214 + xtensa_context.S.obj 0 0 201 0 201 0 0 201 +spi_flash_chip_issi.c.ob 97 0 101 0 198 0 0 198 pthread_local_storage.c. 8 4 0 0 12 183 0 191 - log_freertos.c.o 0 8 188 0 196 0 0 188 - heap.c.o 0 0 151 0 151 0 0 151 - xtensa_intr.c.o 0 0 112 0 112 0 35 147 + log_freertos.c.obj 0 8 188 0 196 0 0 188 + heap.c.obj 0 0 151 0 151 0 0 151 + xtensa_intr.c.obj 0 0 112 0 112 0 35 147 spi_flash_os_func_app.c. 24 0 95 0 119 25 0 144 - list.c.o 0 0 138 0 138 0 0 138 + list.c.obj 0 0 138 0 138 0 0 138 lib_a-flags.o 0 0 0 0 0 128 0 128 dport_panic_highint_hdl. 0 0 123 0 123 0 0 123 lib_a-printf.o 0 0 0 0 0 116 0 116 spi_flash_os_func_noos.c 16 0 89 0 105 0 0 105 lib_a-s_frexp.o 0 0 0 0 0 100 0 100 - cache_err_int.c.o 0 0 0 0 0 96 0 96 + cache_err_int.c.obj 0 0 0 0 0 96 0 96 lib_a-vprintf.o 0 0 0 0 0 94 0 94 - pthread.c.o 0 8 0 0 8 81 0 81 - flash_ops.c.o 20 4 28 0 52 29 0 77 + pthread.c.obj 0 8 0 0 8 81 0 81 + flash_ops.c.obj 20 4 28 0 52 29 0 77 lib_a-localeconv.o 0 0 0 0 0 63 0 63 - reent_init.c.o 0 0 59 0 59 0 0 59 - rtc_io.c.o 0 0 0 0 0 53 0 53 - syscalls.c.o 0 0 0 0 0 50 0 50 + reent_init.c.obj 0 0 59 0 59 0 0 59 + rtc_io.c.obj 0 0 0 0 0 53 0 53 + syscalls.c.obj 0 0 0 0 0 50 0 50 xtensa_vector_defaults.S 0 0 46 0 46 0 0 46 lib_a-fseek.o 0 0 0 0 0 45 0 45 - uart_hal_iram.c.o 0 0 0 0 0 43 0 43 - system_api.c.o 0 8 40 0 48 0 0 40 + uart_hal_iram.c.obj 0 0 0 0 0 43 0 43 + system_api.c.obj 0 8 40 0 48 0 0 40 _divdi3.o 0 0 0 0 0 0 40 40 _moddi3.o 0 0 0 0 0 0 40 40 _udivdi3.o 0 0 0 0 0 0 40 40 _umoddi3.o 0 0 0 0 0 0 40 40 - xtensa_init.c.o 0 4 32 0 36 0 0 32 + xtensa_init.c.obj 0 4 32 0 36 0 0 32 interrupts--intlevel.o 0 0 0 0 0 0 32 32 spi_flash_chip_drivers.c 20 0 0 0 20 0 0 20 - pthread.c.o 0 0 0 0 0 12 0 12 + pthread.c.obj 0 0 0 0 0 12 0 12 lib_a-errno.o 0 0 0 0 0 10 0 10 crtend.o 0 0 0 0 0 0 8 8 - pm_esp32s2.c.o 0 0 0 0 0 8 0 8 + pm_esp32s2.c.obj 0 0 0 0 0 8 0 8 int_asm--set_intclear.o 0 0 8 0 8 0 0 8 state_asm--restore_extra 0 0 7 0 7 0 0 7 state_asm--save_extra_nw 0 0 7 0 7 0 0 7 crti.o 0 0 0 3 3 3 0 6 cxx_exception_stubs.cpp. 0 0 0 0 0 6 0 6 - cxx_guards.cpp.o 0 0 0 0 0 5 0 5 + cxx_guards.cpp.obj 0 0 0 0 0 5 0 5 crtbegin.o 0 0 0 0 0 0 4 4 - FreeRTOS-openocd.c.o 4 0 0 0 4 0 0 4 + FreeRTOS-openocd.c.obj 4 0 0 0 4 0 0 4 crt0.o 0 0 0 0 0 0 0 0 crtn.o 0 0 0 0 0 0 0 0 - project_elf_src.c.o 0 0 0 0 0 0 0 0 - bootloader_common.c.o 0 0 0 0 0 0 0 0 + project_elf_src.c.obj 0 0 0 0 0 0 0 0 + bootloader_common.c.obj 0 0 0 0 0 0 0 0 bootloader_efuse_esp32s2 0 0 0 0 0 0 0 0 - bootloader_flash.c.o 0 0 0 0 0 0 0 0 - bootloader_random.c.o 0 0 0 0 0 0 0 0 - bootloader_sha.c.o 0 0 0 0 0 0 0 0 - bootloader_utility.c.o 0 0 0 0 0 0 0 0 - esp_image_format.c.o 0 0 0 0 0 0 0 0 - flash_partitions.c.o 0 0 0 0 0 0 0 0 + bootloader_flash.c.obj 0 0 0 0 0 0 0 0 + bootloader_random.c.obj 0 0 0 0 0 0 0 0 + bootloader_sha.c.obj 0 0 0 0 0 0 0 0 +bootloader_utility.c.obj 0 0 0 0 0 0 0 0 + esp_image_format.c.obj 0 0 0 0 0 0 0 0 + flash_partitions.c.obj 0 0 0 0 0 0 0 0 isatty.o 0 0 0 0 0 0 0 0 lib_a-assert.o 0 0 0 0 0 0 0 0 lib_a-bzero.o 0 0 0 0 0 0 0 0 @@ -3676,10 +3561,10 @@ bootloader_efuse_esp32s2 0 0 0 0 0 lib_a-wcrtomb.o 0 0 0 0 0 0 0 0 lib_a-wctomb_r.o 0 0 0 0 0 0 0 0 lib_a-wsetup.o 0 0 0 0 0 0 0 0 - gpio.c.o 0 0 0 0 0 0 0 0 - spi_common.c.o 0 0 0 0 0 0 0 0 - hw_random.c.o 0 0 0 0 0 0 0 0 - pm_locks.c.o 0 0 0 0 0 0 0 0 + gpio.c.obj 0 0 0 0 0 0 0 0 + spi_common.c.obj 0 0 0 0 0 0 0 0 + hw_random.c.obj 0 0 0 0 0 0 0 0 + pm_locks.c.obj 0 0 0 0 0 0 0 0 _addsubdf3.o 0 0 0 0 0 0 0 0 _cmpdf2.o 0 0 0 0 0 0 0 0 _divdf3.o 0 0 0 0 0 0 0 0 @@ -3687,33 +3572,33 @@ bootloader_efuse_esp32s2 0 0 0 0 0 _floatdidf.o 0 0 0 0 0 0 0 0 _floatsidf.o 0 0 0 0 0 0 0 0 _muldf3.o 0 0 0 0 0 0 0 0 - esp_mem.c.o 0 0 0 0 0 0 0 0 - platform.c.o 0 0 0 0 0 0 0 0 - platform_util.c.o 0 0 0 0 0 0 0 0 - sha256.c.o 0 0 0 0 0 0 0 0 - gpio_hal.c.o 0 0 0 0 0 0 0 0 - rtc_io_hal.c.o 0 0 0 0 0 0 0 0 - spi_flash_hal_gpspi.c.o 0 0 0 0 0 0 0 0 - timer_hal.c.o 0 0 0 0 0 0 0 0 - gpio_periph.c.o 0 0 0 0 0 0 0 0 - rtc_io_periph.c.o 0 0 0 0 0 0 0 0 - spi_periph.c.o 0 0 0 0 0 0 0 0 - uart_periph.c.o 0 0 0 0 0 0 0 0 - md5-internal.c.o 0 0 0 0 0 0 0 0 - stdatomic.c.o 0 0 0 0 0 0 0 0 + esp_mem.c.obj 0 0 0 0 0 0 0 0 + platform.c.obj 0 0 0 0 0 0 0 0 + platform_util.c.obj 0 0 0 0 0 0 0 0 + sha256.c.obj 0 0 0 0 0 0 0 0 + gpio_hal.c.obj 0 0 0 0 0 0 0 0 + rtc_io_hal.c.obj 0 0 0 0 0 0 0 0 +spi_flash_hal_gpspi.c.ob 0 0 0 0 0 0 0 0 + timer_hal.c.obj 0 0 0 0 0 0 0 0 + gpio_periph.c.obj 0 0 0 0 0 0 0 0 + rtc_io_periph.c.obj 0 0 0 0 0 0 0 0 + spi_periph.c.obj 0 0 0 0 0 0 0 0 + uart_periph.c.obj 0 0 0 0 0 0 0 0 + md5-internal.c.obj 0 0 0 0 0 0 0 0 + stdatomic.c.obj 0 0 0 0 0 0 0 0 *** Running idf_size.py --archive_details for esp32s2... Total sizes: -Used stat D/IRAM: 43023 bytes ( 153585 remain, 21.9% used) +Used stat D/IRAM: 43020 bytes ( 153588 remain, 21.9% used) .data size: 7152 bytes .bss size: 1936 bytes - .text size: 32908 bytes + .text size: 32905 bytes .vectors size: 1027 bytes Used Flash size : 93019 bytes .text : 74439 bytes .rodata : 18580 bytes -Total image size: 134106 bytes (.bin may be padded larger) +Total image size: 134103 bytes (.bin may be padded larger) Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -3794,9 +3679,6 @@ Section total: 3216 Symbols from section: .iram0.text Section total: 0 -Symbols from section: .iram0.text_end -Section total: 0 - Symbols from section: .iram0.vectors Section total: 0 @@ -3828,27 +3710,27 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) 0 Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) 0 +38932 ( +92140 remain, +131072 total) .text size: 37908 bytes 0 +37908 .vectors size: 1024 bytes 0 +1024 -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) 43023 +13529 (+101671 remain, +115200 total) - .data size: 9324 bytes 7152 +2172 - .bss size: 8296 bytes 1936 +6360 - .text size: 37908 bytes 32908 +5000 - .vectors size: 1024 bytes 1027 -3 +Used stat D/IRAM: 0 bytes ( 0 remain, 0.0% used) 43020 -43020 (-153588 remain, -196608 total) + .data size: 0 bytes 7152 -7152 + .bss size: 0 bytes 1936 -1936 + .text size: 0 bytes 32905 -32905 + .vectors size: 0 bytes 1027 -1027 Used Flash size : 186524 bytes 93019 +93505 .text : 146944 bytes 74439 +72505 .rodata : 39580 bytes 18580 +21000 -Total image size: 283036 bytes (.bin may be padded larger) 134106 +148930 +Total image size: 234780 bytes (.bin may be padded larger) 134103 +100677 *** Running idf_size.py for esp32c3... Total sizes: -Used stat D/IRAM: 48648 bytes ( 279032 remain, 14.8% used) +Used stat D/IRAM: 48466 bytes ( 279214 remain, 14.8% used) .data size: 5048 bytes .bss size: 3664 bytes - .text size: 39936 bytes -Used Flash size : 248080 bytes + .text size: 39754 bytes +Used Flash size : 117008 bytes .text : 90400 bytes .rodata : 26352 bytes -Total image size: 293064 bytes (.bin may be padded larger) +Total image size: 161810 bytes (.bin may be padded larger) *** Running idf_size.py for esp32c3 with overflow... @@ -3856,39 +3738,37 @@ WARNING: Given section not found in any memory region. Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py WARNING: Given section not found in any memory region. Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py -WARNING: Given section not found in any memory region. -Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py Total sizes: Used stat D/IRAM: 551174 bytes (-223494 remain, 168.2% used) Overflow detected! You can run idf.py size-files for more information. .text size: 551174 bytes -Used Flash size : 953344 bytes +Used Flash size : 494592 bytes .text : 410978 bytes .rodata : 83358 bytes -Total image size: 1504518 bytes (.bin may be padded larger) +Total image size: 1045766 bytes (.bin may be padded larger) *** Running idf_size.py for esp32c3 (target autodetected)... Total sizes: -Used stat D/IRAM: 48648 bytes ( 279032 remain, 14.8% used) +Used stat D/IRAM: 48466 bytes ( 279214 remain, 14.8% used) .data size: 5048 bytes .bss size: 3664 bytes - .text size: 39936 bytes -Used Flash size : 248080 bytes + .text size: 39754 bytes +Used Flash size : 117008 bytes .text : 90400 bytes .rodata : 26352 bytes -Total image size: 293064 bytes (.bin may be padded larger) +Total image size: 161810 bytes (.bin may be padded larger) *** Running idf_size.py --archives for esp32c3... Total sizes: -Used stat D/IRAM: 48648 bytes ( 279032 remain, 14.8% used) +Used stat D/IRAM: 48466 bytes ( 279214 remain, 14.8% used) .data size: 5048 bytes .bss size: 3664 bytes - .text size: 39936 bytes -Used Flash size : 248080 bytes + .text size: 39754 bytes +Used Flash size : 117008 bytes .text : 90400 bytes .rodata : 26352 bytes -Total image size: 293064 bytes (.bin may be padded larger) +Total image size: 161810 bytes (.bin may be padded larger) Per-archive contributions to ELF file: Archive File DRAM .data .rtc.data DRAM .bss IRAM0 .text ram_st_total Flash .text & .rodata & .appdesc flash_total ilp32\libc.a 4 0 4 0 8 53504 4098 0 57606 @@ -3920,162 +3800,162 @@ Per-archive contributions to ELF file: *** Running idf_size.py --files for esp32c3... Total sizes: -Used stat D/IRAM: 48648 bytes ( 279032 remain, 14.8% used) +Used stat D/IRAM: 48466 bytes ( 279214 remain, 14.8% used) .data size: 5048 bytes .bss size: 3664 bytes - .text size: 39936 bytes -Used Flash size : 248080 bytes + .text size: 39754 bytes +Used Flash size : 117008 bytes .text : 90400 bytes .rodata : 26352 bytes -Total image size: 293064 bytes (.bin may be padded larger) +Total image size: 161810 bytes (.bin may be padded larger) Per-file contributions to ELF file: Object File DRAM .data .rtc.data DRAM .bss IRAM0 .text ram_st_total Flash .text & .rodata & .appdesc flash_total lib_a-vfprintf.o 0 0 0 0 0 14720 748 0 15468 lib_a-svfiprintf.o 0 0 0 0 0 9544 1172 0 10716 lib_a-vfiprintf.o 0 0 0 0 0 9756 737 0 10493 - esp_err_to_name.c.o 6 0 0 0 6 56 7065 0 7127 - tasks.c.o 8 0 664 5552 6224 0 1080 0 6640 - heap_tlsf.c.o 1796 0 0 4036 5832 0 0 0 5832 + esp_err_to_name.c.obj 6 0 0 0 6 56 7065 0 7127 + tasks.c.obj 8 0 664 5552 6224 0 1080 0 6640 + heap_tlsf.c.obj 1796 0 0 4036 5832 0 0 0 5832 lib_a-dtoa.o 0 0 0 0 0 5312 233 0 5545 - vfs_uart.c.o 80 0 8 0 88 4402 270 0 4752 - queue.c.o 0 0 0 3192 3192 0 1495 0 4687 + vfs_uart.c.obj 80 0 8 0 88 4402 270 0 4752 + queue.c.obj 0 0 0 3192 3192 0 1495 0 4687 lib_a-mprec.o 0 0 0 0 0 4252 406 0 4658 - memprot.c.o 0 0 0 772 772 2762 800 0 4334 + memprot.c.obj 0 0 0 772 772 2762 800 0 4334 spi_flash_chip_generic.c 554 0 0 2684 3238 0 0 0 3238 - uart.c.o 40 0 8 0 48 2588 511 0 3139 - intr_alloc.c.o 0 0 13 688 701 2128 198 0 3014 - panic_arch.c.o 0 0 0 0 0 1060 1693 0 2753 - vfs.c.o 192 0 40 0 232 2360 108 0 2660 - rtc_init.c.o 0 0 0 0 0 2068 500 0 2568 - gpio.c.o 0 0 0 0 0 1856 459 0 2315 - spi_flash_hal_iram.c.o 0 0 0 2220 2220 0 0 0 2220 - task_wdt.c.o 45 0 12 0 57 1438 478 0 1961 - flash_mmap.c.o 0 0 136 1530 1666 182 240 0 1952 - rtc_clk.c.o 171 0 4 1738 1913 0 0 0 1909 - esp_flash_api.c.o 20 0 0 968 988 82 762 0 1832 - heap_caps.c.o 4 0 4 1122 1130 286 355 0 1767 - ringbuf.c.o 0 0 0 1004 1004 0 512 0 1516 - spi_flash_hal_gpspi.c.o 0 0 0 1484 1484 0 0 0 1484 - esp_efuse_utility.c.o 0 0 4 0 4 998 475 0 1473 - locks.c.o 0 0 168 924 1092 152 344 0 1420 - heap_caps_init.c.o 0 0 4 0 4 1052 338 0 1390 - startup.c.o 12 0 8 44 64 834 497 0 1387 - partition.c.o 0 0 8 0 8 1070 268 0 1338 + uart.c.obj 40 0 8 0 48 2588 511 0 3139 + intr_alloc.c.obj 0 0 13 688 701 2128 198 0 3014 + panic_arch.c.obj 0 0 0 0 0 1060 1693 0 2753 + vfs.c.obj 192 0 40 0 232 2360 108 0 2660 + rtc_init.c.obj 0 0 0 0 0 2068 500 0 2568 + gpio.c.obj 0 0 0 0 0 1856 459 0 2315 +spi_flash_hal_iram.c.obj 0 0 0 2220 2220 0 0 0 2220 + task_wdt.c.obj 45 0 12 0 57 1438 478 0 1961 + flash_mmap.c.obj 0 0 136 1530 1666 182 240 0 1952 + rtc_clk.c.obj 171 0 4 1738 1913 0 0 0 1909 + esp_flash_api.c.obj 20 0 0 968 988 82 762 0 1832 + heap_caps.c.obj 4 0 4 1122 1130 286 355 0 1767 + ringbuf.c.obj 0 0 0 1004 1004 0 512 0 1516 +spi_flash_hal_gpspi.c.ob 0 0 0 1484 1484 0 0 0 1484 + esp_efuse_utility.c.obj 0 0 4 0 4 998 475 0 1473 + locks.c.obj 0 0 168 924 1092 152 344 0 1420 + heap_caps_init.c.obj 0 0 4 0 4 1052 338 0 1390 + startup.c.obj 12 0 8 44 64 834 497 0 1387 + partition.c.obj 0 0 8 0 8 1070 268 0 1338 lib_a-fseeko.o 0 0 0 0 0 1264 0 0 1264 - wdt_hal_iram.c.o 0 0 0 1160 1160 0 0 0 1160 + wdt_hal_iram.c.obj 0 0 0 1160 1160 0 0 0 1160 lib_a-fvwrite.o 0 0 0 0 0 1156 0 0 1156 lib_a-findfp.o 0 0 0 0 0 1040 96 0 1136 - panic.c.o 12 0 5 6 23 958 131 0 1107 - clk.c.o 0 0 0 0 0 838 212 0 1050 - memspi_host_driver.c.o 397 0 0 636 1033 0 0 0 1033 + panic.c.obj 12 0 5 6 23 958 131 0 1107 + clk.c.obj 0 0 0 0 0 838 212 0 1050 +memspi_host_driver.c.obj 397 0 0 636 1033 0 0 0 1033 spi_flash_chip_winbond.c 203 0 0 748 951 0 0 0 951 - memory_layout_utils.c.o 0 0 0 0 0 650 283 0 933 - periph_ctrl.c.o 0 0 27 0 27 836 85 0 921 - esp_timer.c.o 0 0 8 296 304 514 72 0 882 +memory_layout_utils.c.ob 0 0 0 0 0 650 283 0 933 + periph_ctrl.c.obj 0 0 27 0 27 836 85 0 921 + esp_timer.c.obj 0 0 8 296 304 514 72 0 882 lib_a-fflush.o 0 0 0 0 0 856 0 0 856 trunctfdf2.o 0 0 0 0 0 848 0 0 848 - port.c.o 4 0 1556 588 2148 66 190 0 848 - systimer_hal.c.o 85 0 0 760 845 0 0 0 845 - multi_heap.c.o 157 0 0 678 835 0 0 0 835 - time.c.o 0 0 20 180 200 620 0 0 800 - log.c.o 8 0 264 32 304 562 122 0 724 - cpu_start.c.o 0 0 0 464 464 42 158 0 664 + port.c.obj 4 0 1556 588 2148 66 190 0 848 + systimer_hal.c.obj 85 0 0 760 845 0 0 0 845 + multi_heap.c.obj 157 0 0 678 835 0 0 0 835 + time.c.obj 0 0 20 180 200 620 0 0 800 + log.c.obj 8 0 264 32 304 562 122 0 724 + cpu_start.c.obj 0 0 0 464 464 42 158 0 664 esp_timer_impl_systimer. 16 0 12 210 238 296 125 0 647 - esp_flash_spi_init.c.o 68 0 4 0 72 272 261 0 601 +esp_flash_spi_init.c.obj 68 0 4 0 72 272 261 0 601 spi_flash_os_func_app.c. 52 0 0 414 466 34 95 0 595 - rtc_time.c.o 0 0 0 590 590 0 0 0 590 - port_systick.c.o 0 0 8 370 378 0 192 0 562 - vectors.S.o 0 0 0 522 522 0 0 0 522 + rtc_time.c.obj 0 0 0 590 590 0 0 0 590 + port_systick.c.obj 0 0 8 370 378 0 192 0 562 + vectors.S.obj 0 0 0 522 522 0 0 0 522 lib_a-refill.o 0 0 0 0 0 512 0 0 512 lib_a-reent.o 0 0 0 0 0 500 0 0 500 - esp_app_desc.c.o 1 0 8 198 207 32 4 256 491 + esp_app_desc.c.obj 1 0 8 198 207 32 4 256 491 lib_a-ftello.o 0 0 0 0 0 488 0 0 488 - hello_world_main.c.o 0 0 0 0 0 248 232 0 480 + hello_world_main.c.obj 0 0 0 0 0 248 232 0 480 lib_a-fclose.o 0 0 0 0 0 456 0 0 456 - spi_flash_hal.c.o 0 0 0 0 0 342 96 0 438 + spi_flash_hal.c.obj 0 0 0 0 0 342 96 0 438 lib_a-makebuf.o 0 0 0 0 0 436 0 0 436 - port_common.c.o 0 0 0 104 104 128 186 0 418 + port_common.c.obj 0 0 0 104 104 128 186 0 418 lib_a-fopen.o 0 0 0 0 0 416 0 0 416 - sleep_modes.c.o 0 0 0 0 0 244 171 0 415 - crosscore_int.c.o 0 0 4 162 166 106 120 0 388 + sleep_modes.c.obj 0 0 0 0 0 244 171 0 415 + crosscore_int.c.obj 0 0 4 162 166 106 120 0 388 lib_a-wsetup.o 0 0 0 0 0 384 0 0 384 lib_a-locale.o 4 0 0 0 4 0 378 0 382 lib_a-puts.o 0 0 0 0 0 372 0 0 372 - uart_hal.c.o 0 0 0 0 0 366 0 0 366 - panic_handler.c.o 8 0 4 82 94 266 8 0 364 - esp_time_impl.c.o 0 0 12 0 12 362 0 0 362 + uart_hal.c.obj 0 0 0 0 0 366 0 0 366 + panic_handler.c.obj 8 0 4 82 94 266 8 0 364 + esp_time_impl.c.obj 0 0 12 0 12 362 0 0 362 lib_a-fwalk.o 0 0 0 0 0 340 0 0 340 - bootloader_flash.c.o 0 0 0 340 340 0 0 0 340 - freertos_hooks.c.o 0 0 64 48 112 290 0 0 338 + bootloader_flash.c.obj 0 0 0 340 340 0 0 0 340 + freertos_hooks.c.obj 0 0 64 48 112 290 0 0 338 lib_a-stdio.o 0 0 0 0 0 316 0 0 316 - spi_flash_chip_gd.c.o 123 0 0 190 313 0 0 0 313 - rtc_sleep.c.o 0 0 0 308 308 0 0 0 308 - esp_ota_ops.c.o 0 0 4 0 4 186 121 0 307 - system_internal.c.o 0 0 0 298 298 0 0 0 298 - int_wdt.c.o 0 0 8 74 82 206 0 0 280 - interrupt.c.o 0 0 256 130 386 0 137 0 267 - spi_flash_chip_mxic.c.o 190 0 0 76 266 0 0 0 266 - esp_err.c.o 108 0 0 154 262 0 0 0 262 - system_time.c.o 0 0 8 38 46 142 80 0 260 + spi_flash_chip_gd.c.obj 123 0 0 190 313 0 0 0 313 + rtc_sleep.c.obj 0 0 0 308 308 0 0 0 308 + esp_ota_ops.c.obj 0 0 4 0 4 186 121 0 307 + system_internal.c.obj 0 0 0 298 298 0 0 0 298 + int_wdt.c.obj 0 0 8 74 82 206 0 0 280 + interrupt.c.obj 0 0 256 130 386 0 137 0 267 +spi_flash_chip_mxic.c.ob 190 0 0 76 266 0 0 0 266 + esp_err.c.obj 108 0 0 154 262 0 0 0 262 + system_time.c.obj 0 0 8 38 46 142 80 0 260 lib_a-ctype_.o 0 0 0 0 0 0 257 0 257 - cpu_util_esp32c3.c.o 0 0 0 0 0 250 0 0 250 - esp_clk.c.o 0 16 4 30 50 200 0 0 246 + cpu_util_esp32c3.c.obj 0 0 0 0 0 250 0 0 250 + esp_clk.c.obj 0 16 4 30 50 200 0 0 246 pthread_local_storage.c. 0 0 4 0 4 242 0 0 242 - spi_flash_chip_issi.c.o 125 0 0 112 237 0 0 0 237 - memory_layout.c.o 4 0 0 0 4 0 231 0 235 - log_freertos.c.o 0 0 8 232 240 0 0 0 232 - newlib_init.c.o 156 0 240 0 396 76 0 0 232 +spi_flash_chip_issi.c.ob 125 0 0 112 237 0 0 0 237 + memory_layout.c.obj 4 0 0 0 4 0 231 0 235 + log_freertos.c.obj 0 0 8 232 240 0 0 0 232 + newlib_init.c.obj 156 0 240 0 396 76 0 0 232 lib_a-printf.o 0 0 0 0 0 224 0 0 224 - regi2c_ctrl.c.o 0 0 0 202 202 0 0 0 202 - heap.c.o 0 0 0 190 190 0 0 0 190 + regi2c_ctrl.c.obj 0 0 0 202 202 0 0 0 202 + heap.c.obj 0 0 0 190 190 0 0 0 190 lib_a-s_frexp.o 0 0 0 0 0 180 8 0 188 lib_a-assert.o 0 0 0 0 0 124 63 0 187 - cache_utils.c.o 0 0 8 144 152 38 0 0 182 + cache_utils.c.obj 0 0 8 144 152 38 0 0 182 lib_a-vprintf.o 0 0 0 0 0 176 0 0 176 - spi_flash_chip_boya.c.o 125 0 0 46 171 0 0 0 171 - esp_system.c.o 0 0 20 90 110 80 0 0 170 +spi_flash_chip_boya.c.ob 125 0 0 46 171 0 0 0 171 + esp_system.c.obj 0 0 20 90 110 80 0 0 170 lib_a-flags.o 0 0 0 0 0 168 0 0 168 - abort.c.o 38 0 0 128 166 0 0 0 166 - brownout_hal.c.o 0 0 0 0 0 160 0 0 160 - esp_efuse_api.c.o 0 0 0 0 0 158 0 0 158 - portasm.S.o 0 0 0 154 154 0 0 0 154 + abort.c.obj 38 0 0 128 166 0 0 0 166 + brownout_hal.c.obj 0 0 0 0 0 160 0 0 160 + esp_efuse_api.c.obj 0 0 0 0 0 158 0 0 158 + portasm.S.obj 0 0 0 154 154 0 0 0 154 lib_a-fiprintf.o 0 0 0 0 0 148 0 0 148 - list.c.o 0 0 0 134 134 0 0 0 134 + list.c.obj 0 0 0 134 134 0 0 0 134 spi_flash_encrypt_hal_ir 0 0 0 132 132 0 0 0 132 - cache_err_int.c.o 0 0 0 4 4 124 0 0 128 + cache_err_int.c.obj 0 0 0 4 4 124 0 0 128 spi_flash_os_func_noos.c 36 0 0 86 122 0 0 0 122 lib_a-mbtowc_r.o 0 0 0 0 0 108 0 0 108 - flash_ops.c.o 24 0 4 40 68 38 0 0 102 - pthread.c.o 0 0 8 0 8 100 0 0 100 - esp_efuse_table.c.o 96 0 0 0 96 0 0 0 96 - uart_hal_iram.c.o 0 0 0 0 0 88 0 0 88 - gpio_periph.c.o 0 0 0 0 0 0 88 0 88 - apb_backup_dma.c.o 0 0 0 52 52 34 0 0 86 + flash_ops.c.obj 24 0 4 40 68 38 0 0 102 + pthread.c.obj 0 0 8 0 8 100 0 0 100 + esp_efuse_table.c.obj 96 0 0 0 96 0 0 0 96 + uart_hal_iram.c.obj 0 0 0 0 0 88 0 0 88 + gpio_periph.c.obj 0 0 0 0 0 0 88 0 88 + apb_backup_dma.c.obj 0 0 0 52 52 34 0 0 86 interrupt_controller_hal 0 0 0 0 0 80 0 0 80 - reent_init.c.o 0 0 0 76 76 0 0 0 76 - instruction_decode.c.o 0 0 0 0 0 74 0 0 74 - chip_info.c.o 0 0 0 0 0 70 0 0 70 + reent_init.c.obj 0 0 0 76 76 0 0 0 76 +instruction_decode.c.obj 0 0 0 0 0 74 0 0 74 + chip_info.c.obj 0 0 0 0 0 70 0 0 70 lib_a-fseek.o 0 0 0 0 0 68 0 0 68 lib_a-wctomb_r.o 0 0 0 0 0 64 0 0 64 - flash_qio_mode.c.o 0 0 0 0 0 58 0 0 58 + flash_qio_mode.c.obj 0 0 0 0 0 58 0 0 58 lib_a-sysgettod.o 0 0 0 0 0 56 0 0 56 - brownout.c.o 0 0 0 0 0 38 5 0 43 + brownout.c.obj 0 0 0 0 0 38 5 0 43 lib_a-localeconv.o 0 0 0 0 0 40 0 0 40 - syscalls.c.o 0 0 0 0 0 36 0 0 36 - esp_efuse_fields.c.o 0 0 0 0 0 32 0 0 32 - cpu_hal.c.o 0 0 0 32 32 0 0 0 32 + syscalls.c.obj 0 0 0 0 0 36 0 0 36 + esp_efuse_fields.c.obj 0 0 0 0 0 32 0 0 32 + cpu_hal.c.obj 0 0 0 32 32 0 0 0 32 spi_flash_chip_drivers.c 32 0 0 0 32 0 0 0 32 lib_a-errno.o 0 0 0 0 0 28 0 0 28 - cpu_util.c.o 0 0 0 28 28 0 0 0 28 - pm_impl.c.o 0 0 0 0 0 28 0 0 28 + cpu_util.c.obj 0 0 0 28 28 0 0 0 28 + pm_impl.c.obj 0 0 0 0 0 28 0 0 28 bootloader_flash_config_ 0 0 0 0 0 26 0 0 26 - esp_rom_uart.c.o 0 0 0 24 24 0 0 0 24 - bootloader_mem.c.o 0 0 0 0 0 14 0 0 14 - pthread.c.o 0 0 0 0 0 6 0 0 6 - spi_bus_lock.c.o 4 0 0 0 4 0 0 0 4 - FreeRTOS-openocd.c.o 4 0 0 0 4 0 0 0 4 - cxx_guards.cpp.o 0 0 0 0 0 2 0 0 2 - ubsan.c.o 0 0 0 2 2 0 0 0 2 + esp_rom_uart.c.obj 0 0 0 24 24 0 0 0 24 + bootloader_mem.c.obj 0 0 0 0 0 14 0 0 14 + pthread.c.obj 0 0 0 0 0 6 0 0 6 + spi_bus_lock.c.obj 4 0 0 0 4 0 0 0 4 + FreeRTOS-openocd.c.obj 4 0 0 0 4 0 0 0 4 + cxx_guards.cpp.obj 0 0 0 0 0 2 0 0 2 + ubsan.c.obj 0 0 0 2 2 0 0 0 2 lib_a-environ.o 0 0 4 0 4 0 0 0 0 _divdi3.o 0 0 0 0 0 0 0 0 0 _moddi3.o 0 0 0 0 0 0 0 0 0 @@ -4085,14 +3965,14 @@ bootloader_flash_config_ 0 0 0 0 0 *** Running idf_size.py --archive_details for esp32c3... Total sizes: -Used stat D/IRAM: 48648 bytes ( 279032 remain, 14.8% used) +Used stat D/IRAM: 48466 bytes ( 279214 remain, 14.8% used) .data size: 5048 bytes .bss size: 3664 bytes - .text size: 39936 bytes -Used Flash size : 248080 bytes + .text size: 39754 bytes +Used Flash size : 117008 bytes .text : 90400 bytes .rodata : 26352 bytes -Total image size: 293064 bytes (.bin may be padded larger) +Total image size: 161810 bytes (.bin may be padded larger) Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -4186,9 +4066,6 @@ Symbols from section: .flash.text uart_get_selectlock : 6 Section total: 5280 -Symbols from section: .flash_rodata_dummy -Section total: 0 - Symbols from section: .iram0.bss Section total: 0 @@ -4198,9 +4075,6 @@ Section total: 0 Symbols from section: .iram0.text Section total: 0 -Symbols from section: .iram0.text_end -Section total: 0 - Symbols from section: .noinit Section total: 0 @@ -4222,14 +4096,13 @@ Total sizes: Used static IRAM: 46786 bytes ( 239934 remain, 16.3% used) .text size: 45759 bytes .vectors size: 1027 bytes -Used stat D/IRAM: 11773 bytes ( 123395 remain, 8.7% used) +Used stat D/IRAM: 11772 bytes ( 123396 remain, 8.7% used) .data size: 9252 bytes .bss size: 2520 bytes - .text size: 1 bytes -Used Flash size : 245923 bytes +Used Flash size : 114851 bytes .text : 87463 bytes .rodata : 27132 bytes -Total image size: 301962 bytes (.bin may be padded larger) +Total image size: 170889 bytes (.bin may be padded larger) *** Running idf_size.py for esp32s3 with overflow... @@ -4240,10 +4113,10 @@ Used static IRAM: 337906 bytes ( -51186 remain, 117.9% used) Overflow detected! Used stat D/IRAM: 94049 bytes ( 41119 remain, 69.6% used) .data size: 68929 bytes .bss size: 25120 bytes -Used Flash size : 854930 bytes +Used Flash size : 461714 bytes .text : 366715 bytes .rodata : 94743 bytes -Total image size: 1261765 bytes (.bin may be padded larger) +Total image size: 868549 bytes (.bin may be padded larger) *** Running idf_size.py for esp32s3 (target autodetected)... @@ -4251,14 +4124,13 @@ Total sizes: Used static IRAM: 46786 bytes ( 239934 remain, 16.3% used) .text size: 45759 bytes .vectors size: 1027 bytes -Used stat D/IRAM: 11773 bytes ( 123395 remain, 8.7% used) +Used stat D/IRAM: 11772 bytes ( 123396 remain, 8.7% used) .data size: 9252 bytes .bss size: 2520 bytes - .text size: 1 bytes -Used Flash size : 245923 bytes +Used Flash size : 114851 bytes .text : 87463 bytes .rodata : 27132 bytes -Total image size: 301962 bytes (.bin may be padded larger) +Total image size: 170889 bytes (.bin may be padded larger) *** Running idf_size.py --archives for esp32s3... @@ -4266,14 +4138,13 @@ Total sizes: Used static IRAM: 46786 bytes ( 239934 remain, 16.3% used) .text size: 45759 bytes .vectors size: 1027 bytes -Used stat D/IRAM: 11773 bytes ( 123395 remain, 8.7% used) +Used stat D/IRAM: 11772 bytes ( 123396 remain, 8.7% used) .data size: 9252 bytes .bss size: 2520 bytes - .text size: 1 bytes -Used Flash size : 245923 bytes +Used Flash size : 114851 bytes .text : 87463 bytes .rodata : 27132 bytes -Total image size: 301962 bytes (.bin may be padded larger) +Total image size: 170889 bytes (.bin may be padded larger) Per-archive contributions to ELF file: Archive File DRAM .data .rtc.data DRAM .bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata & .appdesc flash_total no-rtti\libc.a 4 0 4 0 0 8 58528 4685 0 63217 @@ -4311,209 +4182,208 @@ Total sizes: Used static IRAM: 46786 bytes ( 239934 remain, 16.3% used) .text size: 45759 bytes .vectors size: 1027 bytes -Used stat D/IRAM: 11773 bytes ( 123395 remain, 8.7% used) +Used stat D/IRAM: 11772 bytes ( 123396 remain, 8.7% used) .data size: 9252 bytes .bss size: 2520 bytes - .text size: 1 bytes -Used Flash size : 245923 bytes +Used Flash size : 114851 bytes .text : 87463 bytes .rodata : 27132 bytes -Total image size: 301962 bytes (.bin may be padded larger) +Total image size: 170889 bytes (.bin may be padded larger) Per-file contributions to ELF file: Object File DRAM .data .rtc.data DRAM .bss IRAM0 .text & 0.vectors ram_st_total Flash .text & .rodata & .appdesc flash_total lib_a-vfprintf.o 0 0 0 0 0 0 13707 700 0 14407 lib_a-svfprintf.o 0 0 0 0 0 0 13331 752 0 14083 lib_a-svfiprintf.o 0 0 0 0 0 0 9650 1172 0 10822 lib_a-vfiprintf.o 0 0 0 0 0 0 9827 700 0 10527 - tasks.c.o 8 0 704 6792 0 7504 0 1158 0 7958 - esp_err_to_name.c.o 0 0 0 0 0 0 53 7287 0 7340 - heap_tlsf.c.o 1796 0 0 3591 0 5387 0 0 0 5387 - queue.c.o 0 0 0 3038 0 3038 0 1515 0 4553 - vfs_uart.c.o 116 0 8 0 0 124 4051 282 0 4449 + tasks.c.obj 8 0 704 6792 0 7504 0 1158 0 7958 + esp_err_to_name.c.obj 0 0 0 0 0 0 53 7287 0 7340 + heap_tlsf.c.obj 1796 0 0 3591 0 5387 0 0 0 5387 + queue.c.obj 0 0 0 3038 0 3038 0 1515 0 4553 + vfs_uart.c.obj 116 0 8 0 0 124 4051 282 0 4449 lib_a-dtoa.o 0 0 0 0 0 0 3592 165 0 3757 - portasm.S.o 3084 0 0 416 0 3500 0 0 0 3500 + portasm.S.obj 3084 0 0 416 0 3500 0 0 0 3500 spi_flash_chip_generic.c 554 0 0 2529 0 3083 0 0 0 3083 - intr_alloc.c.o 8 0 22 717 0 747 1958 198 0 2881 + intr_alloc.c.obj 8 0 22 717 0 747 1958 198 0 2881 lib_a-mprec.o 0 0 0 0 0 0 2340 409 0 2749 - uart.c.o 56 0 12 0 0 68 2091 511 0 2658 - panic_arch.c.o 0 0 0 0 0 0 715 1538 0 2253 - spi_flash_hal_iram.c.o 0 0 0 2250 0 2250 0 0 0 2250 - vfs.c.o 192 0 40 0 0 232 1935 111 0 2238 - rtc_clk.c.o 171 0 8 2059 0 2238 0 0 0 2230 - xtensa_vectors.S.o 32 0 0 1464 425 1921 0 48 0 1969 - task_wdt.c.o 53 0 12 0 0 65 1319 591 0 1963 - spi_flash_hal_gpspi.c.o 0 0 0 1842 0 1842 0 0 0 1842 - rtc_init.c.o 0 0 0 0 0 0 1703 70 0 1773 - esp_flash_api.c.o 20 0 0 862 0 882 89 762 0 1733 - flash_mmap.c.o 0 0 520 1298 0 1818 166 240 0 1704 - port.c.o 0 0 24 945 0 969 147 541 0 1633 - heap_caps.c.o 4 0 4 1003 0 1011 261 355 0 1623 - wdt_hal_iram.c.o 0 0 0 1493 0 1493 0 0 0 1493 - periph_ctrl.c.o 8 0 37 0 0 45 1377 85 0 1470 - cpu_start.c.o 0 0 5 732 0 737 371 334 0 1437 - ringbuf.c.o 0 0 0 873 0 873 0 512 0 1385 - cache_utils.c.o 4 0 14 685 0 703 92 570 0 1351 - heap_caps_init.c.o 0 0 4 0 0 4 905 430 0 1335 - startup.c.o 8 0 11 69 0 88 748 505 0 1330 - locks.c.o 8 0 168 782 0 958 122 344 0 1256 - partition.c.o 0 0 8 0 0 8 938 268 0 1206 - systimer_hal.c.o 85 0 0 1052 0 1137 0 0 0 1137 - xtensa_intr_asm.S.o 1024 0 0 51 0 1075 0 0 0 1075 - panic.c.o 12 0 5 12 0 29 875 147 0 1046 - memspi_host_driver.c.o 397 0 0 637 0 1034 0 0 0 1034 - clk.c.o 0 0 0 0 0 0 802 212 0 1014 - esp_timer.c.o 8 0 8 282 0 298 505 72 0 867 - memory_layout_utils.c.o 0 0 0 0 0 0 575 283 0 858 - debug_helpers.c.o 0 0 0 747 0 747 0 73 0 820 + uart.c.obj 56 0 12 0 0 68 2091 511 0 2658 + panic_arch.c.obj 0 0 0 0 0 0 715 1538 0 2253 +spi_flash_hal_iram.c.obj 0 0 0 2250 0 2250 0 0 0 2250 + vfs.c.obj 192 0 40 0 0 232 1935 111 0 2238 + rtc_clk.c.obj 171 0 8 2059 0 2238 0 0 0 2230 + xtensa_vectors.S.obj 32 0 0 1464 425 1921 0 48 0 1969 + task_wdt.c.obj 53 0 12 0 0 65 1319 591 0 1963 +spi_flash_hal_gpspi.c.ob 0 0 0 1842 0 1842 0 0 0 1842 + rtc_init.c.obj 0 0 0 0 0 0 1703 70 0 1773 + esp_flash_api.c.obj 20 0 0 862 0 882 89 762 0 1733 + flash_mmap.c.obj 0 0 520 1298 0 1818 166 240 0 1704 + port.c.obj 0 0 24 945 0 969 147 541 0 1633 + heap_caps.c.obj 4 0 4 1003 0 1011 261 355 0 1623 + wdt_hal_iram.c.obj 0 0 0 1493 0 1493 0 0 0 1493 + periph_ctrl.c.obj 8 0 37 0 0 45 1377 85 0 1470 + cpu_start.c.obj 0 0 5 732 0 737 371 334 0 1437 + ringbuf.c.obj 0 0 0 873 0 873 0 512 0 1385 + cache_utils.c.obj 4 0 14 685 0 703 92 570 0 1351 + heap_caps_init.c.obj 0 0 4 0 0 4 905 430 0 1335 + startup.c.obj 8 0 11 69 0 88 748 505 0 1330 + locks.c.obj 8 0 168 782 0 958 122 344 0 1256 + partition.c.obj 0 0 8 0 0 8 938 268 0 1206 + systimer_hal.c.obj 85 0 0 1052 0 1137 0 0 0 1137 + xtensa_intr_asm.S.obj 1024 0 0 51 0 1075 0 0 0 1075 + panic.c.obj 12 0 5 12 0 29 875 147 0 1046 +memspi_host_driver.c.obj 397 0 0 637 0 1034 0 0 0 1034 + clk.c.obj 0 0 0 0 0 0 802 212 0 1014 + esp_timer.c.obj 8 0 8 282 0 298 505 72 0 867 +memory_layout_utils.c.ob 0 0 0 0 0 0 575 283 0 858 + debug_helpers.c.obj 0 0 0 747 0 747 0 73 0 820 lib_a-fseeko.o 0 0 0 0 0 0 818 0 0 818 spi_flash_chip_winbond.c 136 0 0 659 0 795 0 0 0 795 - multi_heap.c.o 157 0 0 601 0 758 0 0 0 758 - esp_ipc.c.o 0 0 56 188 0 244 456 97 0 741 + multi_heap.c.obj 157 0 0 601 0 758 0 0 0 758 + esp_ipc.c.obj 0 0 56 188 0 244 456 97 0 741 lib_a-fvwrite.o 0 0 0 0 0 0 721 0 0 721 - panic_handler.c.o 8 0 8 66 0 82 634 8 0 716 + panic_handler.c.obj 8 0 8 66 0 82 634 8 0 716 lib_a-findfp.o 0 0 0 0 0 0 612 96 0 708 - rtc_time.c.o 0 0 0 675 0 675 0 0 0 675 - log.c.o 8 0 264 42 0 314 499 122 0 671 - time.c.o 0 0 20 127 0 147 509 0 0 636 + rtc_time.c.obj 0 0 0 675 0 675 0 0 0 675 + log.c.obj 8 0 264 42 0 314 499 122 0 671 + time.c.obj 0 0 20 127 0 147 509 0 0 636 esp_timer_impl_systimer. 24 0 12 198 0 234 286 125 0 633 - port_systick.c.o 0 0 12 394 0 406 0 192 0 586 - esp_flash_spi_init.c.o 68 0 4 0 0 72 243 261 0 572 + port_systick.c.obj 0 0 12 394 0 406 0 192 0 586 +esp_flash_spi_init.c.obj 68 0 4 0 0 72 243 261 0 572 lib_a-fflush.o 0 0 0 0 0 0 552 0 0 552 interrupt_descriptor_tab 0 0 0 0 0 0 12 512 0 524 spi_flash_os_func_app.c. 52 0 0 324 0 376 44 95 0 515 - crosscore_int.c.o 8 0 8 229 0 245 142 120 0 499 - system_internal.c.o 0 0 0 475 0 475 0 16 0 491 - esp_app_desc.c.o 1 0 8 194 0 203 31 4 256 486 - rtc_sleep.c.o 0 0 0 476 0 476 0 0 0 476 - hello_world_main.c.o 0 0 0 0 0 0 228 232 0 460 - port_common.c.o 0 0 8 98 0 106 146 214 0 458 - spi_flash_hal.c.o 0 0 0 0 0 0 351 96 0 447 - bootloader_flash.c.o 0 0 0 444 0 444 0 0 0 444 - uart_hal.c.o 0 0 0 0 0 0 432 0 0 432 - xtensa_context.S.o 0 0 0 390 0 390 0 0 0 390 + crosscore_int.c.obj 8 0 8 229 0 245 142 120 0 499 + system_internal.c.obj 0 0 0 475 0 475 0 16 0 491 + esp_app_desc.c.obj 1 0 8 194 0 203 31 4 256 486 + rtc_sleep.c.obj 0 0 0 476 0 476 0 0 0 476 + hello_world_main.c.obj 0 0 0 0 0 0 228 232 0 460 + port_common.c.obj 0 0 8 98 0 106 146 214 0 458 + spi_flash_hal.c.obj 0 0 0 0 0 0 351 96 0 447 + bootloader_flash.c.obj 0 0 0 444 0 444 0 0 0 444 + uart_hal.c.obj 0 0 0 0 0 0 432 0 0 432 + xtensa_context.S.obj 0 0 0 390 0 390 0 0 0 390 lib_a-locale.o 4 0 0 0 0 4 0 374 0 378 - esp_ipc_isr.c.o 4 0 16 19 0 39 187 144 0 354 - spi_flash_chip_gd.c.o 123 0 0 202 0 325 0 0 0 325 - memory_layout.c.o 0 0 0 0 0 0 0 315 0 315 + esp_ipc_isr.c.obj 4 0 16 19 0 39 187 144 0 354 + spi_flash_chip_gd.c.obj 123 0 0 202 0 325 0 0 0 325 + memory_layout.c.obj 0 0 0 0 0 0 0 315 0 315 lib_a-refill.o 0 0 0 0 0 0 312 0 0 312 windowspill_asm.o 0 0 0 311 0 311 0 0 0 311 - freertos_hooks.c.o 8 0 128 47 0 183 247 0 0 302 - esp_time_impl.c.o 0 0 12 0 0 12 281 0 0 281 + freertos_hooks.c.obj 8 0 128 47 0 183 247 0 0 302 + esp_time_impl.c.obj 0 0 12 0 0 12 281 0 0 281 lib_a-ftello.o 0 0 0 0 0 0 278 0 0 278 lib_a-fclose.o 0 0 0 0 0 0 270 0 0 270 - esp_ota_ops.c.o 0 0 4 0 0 4 148 121 0 269 + esp_ota_ops.c.obj 0 0 4 0 0 4 148 121 0 269 lib_a-makebuf.o 0 0 0 0 0 0 263 0 0 263 - spi_flash_chip_mxic.c.o 190 0 0 70 0 260 0 0 0 260 - soc_hal.c.o 24 0 0 234 0 258 0 0 0 258 +spi_flash_chip_mxic.c.ob 190 0 0 70 0 260 0 0 0 260 + soc_hal.c.obj 24 0 0 234 0 258 0 0 0 258 lib_a-ctype_.o 0 0 0 0 0 0 0 257 0 257 lib_a-reent.o 0 0 0 0 0 0 252 0 0 252 - esp_err.c.o 108 0 0 140 0 248 0 0 0 248 - brownout_hal.c.o 0 0 0 0 0 0 244 0 0 244 - int_wdt.c.o 0 0 9 90 0 99 152 0 0 242 - system_time.c.o 0 0 8 35 0 43 126 80 0 241 - esp_clk.c.o 0 16 4 25 0 45 194 0 0 235 - spi_flash_chip_issi.c.o 125 0 0 108 0 233 0 0 0 233 - newlib_init.c.o 156 0 240 0 0 396 73 0 0 229 + esp_err.c.obj 108 0 0 140 0 248 0 0 0 248 + brownout_hal.c.obj 0 0 0 0 0 0 244 0 0 244 + int_wdt.c.obj 0 0 9 90 0 99 152 0 0 242 + system_time.c.obj 0 0 8 35 0 43 126 80 0 241 + esp_clk.c.obj 0 16 4 25 0 45 194 0 0 235 +spi_flash_chip_issi.c.ob 125 0 0 108 0 233 0 0 0 233 + newlib_init.c.obj 156 0 240 0 0 396 73 0 0 229 lib_a-wsetup.o 0 0 0 0 0 0 223 0 0 223 pthread_local_storage.c. 8 0 4 0 0 12 213 0 0 221 lib_a-snprintf.o 0 0 0 0 0 0 217 0 0 217 lib_a-fopen.o 0 0 0 0 0 0 216 0 0 216 spi_flash_encrypt_hal_ir 0 0 0 213 0 213 0 0 0 213 - log_freertos.c.o 0 0 8 205 0 213 0 0 0 205 - abort.c.o 38 0 0 157 0 195 0 0 0 195 + log_freertos.c.obj 0 0 8 205 0 213 0 0 0 205 + abort.c.obj 38 0 0 157 0 195 0 0 0 195 lib_a-puts.o 0 0 0 0 0 0 190 0 0 190 - xtensa_intr.c.o 0 0 0 26 0 26 126 35 0 187 + xtensa_intr.c.obj 0 0 0 26 0 26 126 35 0 187 lib_a-stdio.o 0 0 0 0 0 0 182 0 0 182 - regi2c_ctrl.c.o 8 0 0 171 0 179 0 0 0 179 - spi_flash_chip_boya.c.o 125 0 0 52 0 177 0 0 0 177 - list.c.o 0 0 0 164 0 164 0 0 0 164 - cpu_util.c.o 0 0 0 137 0 137 0 20 0 157 - heap.c.o 0 0 0 151 0 151 0 0 0 151 - highint_hdl.S.o 0 0 0 147 0 147 0 0 0 147 - esp_ipc_isr_handler.S.o 16 0 0 125 0 141 0 0 0 141 + regi2c_ctrl.c.obj 8 0 0 171 0 179 0 0 0 179 +spi_flash_chip_boya.c.ob 125 0 0 52 0 177 0 0 0 177 + list.c.obj 0 0 0 164 0 164 0 0 0 164 + cpu_util.c.obj 0 0 0 137 0 137 0 20 0 157 + heap.c.obj 0 0 0 151 0 151 0 0 0 151 + highint_hdl.S.obj 0 0 0 147 0 147 0 0 0 147 +esp_ipc_isr_handler.S.ob 16 0 0 125 0 141 0 0 0 141 lib_a-assert.o 0 0 0 0 0 0 72 60 0 132 lib_a-flags.o 0 0 0 0 0 0 128 0 0 128 - esp_system.c.o 0 0 20 56 0 76 70 0 0 126 + esp_system.c.obj 0 0 20 56 0 76 70 0 0 126 lib_a-fwalk.o 0 0 0 0 0 0 119 0 0 119 lib_a-printf.o 0 0 0 0 0 0 112 0 0 112 spi_flash_os_func_noos.c 36 0 0 72 0 108 0 0 0 108 - uart_hal_iram.c.o 0 0 0 0 0 0 105 0 0 105 + uart_hal_iram.c.obj 0 0 0 0 0 0 105 0 0 105 lib_a-s_frexp.o 0 0 0 0 0 0 100 0 0 100 - flash_ops.c.o 24 0 4 41 0 69 33 0 0 98 - pthread.c.o 0 0 8 0 0 8 97 0 0 97 + flash_ops.c.obj 24 0 4 41 0 69 33 0 0 98 + pthread.c.obj 0 0 8 0 0 8 97 0 0 97 lib_a-vprintf.o 0 0 0 0 0 0 94 0 0 94 - cache_err_int.c.o 0 0 0 7 0 7 78 0 0 85 + cache_err_int.c.obj 0 0 0 7 0 7 78 0 0 85 lib_a-fiprintf.o 0 0 0 0 0 0 84 0 0 84 - mpu_hal.c.o 0 0 0 0 0 0 72 0 0 72 - panic_handler_asm.S.o 0 0 0 66 0 66 0 0 0 66 + mpu_hal.c.obj 0 0 0 0 0 0 72 0 0 72 + panic_handler_asm.S.obj 0 0 0 66 0 66 0 0 0 66 lib_a-wctomb_r.o 0 0 0 0 0 0 65 0 0 65 lib_a-mbtowc_r.o 0 0 0 0 0 0 64 0 0 64 - reent_init.c.o 0 0 0 63 0 63 0 0 0 63 + reent_init.c.obj 0 0 0 63 0 63 0 0 0 63 interrupt_controller_hal 0 0 0 0 0 0 59 0 0 59 - flash_qio_mode.c.o 0 0 0 0 0 0 58 0 0 58 + flash_qio_mode.c.obj 0 0 0 0 0 0 58 0 0 58 lib_a-fseek.o 0 0 0 0 0 0 49 0 0 49 state_asm--restore_extra 0 0 0 47 0 47 0 0 0 47 state_asm--save_extra_nw 0 0 0 47 0 47 0 0 0 47 lib_a-localeconv.o 0 0 0 0 0 0 47 0 0 47 xtensa_vector_defaults.S 0 0 0 46 0 46 0 0 0 46 - cpu_hal.c.o 0 0 0 42 0 42 0 0 0 42 + cpu_hal.c.obj 0 0 0 42 0 42 0 0 0 42 _divdi3.o 0 0 0 0 0 0 0 40 0 40 _moddi3.o 0 0 0 0 0 0 0 40 0 40 _udivdi3.o 0 0 0 0 0 0 0 40 0 40 _umoddi3.o 0 0 0 0 0 0 0 40 0 40 - brownout.c.o 0 0 0 0 0 0 30 5 0 35 + brownout.c.obj 0 0 0 0 0 0 30 5 0 35 spi_flash_chip_drivers.c 32 0 0 0 0 32 0 0 0 32 interrupts--intlevel.o 0 0 0 0 0 0 0 32 0 32 - syscalls.c.o 0 0 0 0 0 0 31 0 0 31 - chip_info.c.o 0 0 0 0 0 0 29 0 0 29 + syscalls.c.obj 0 0 0 0 0 0 31 0 0 31 + chip_info.c.obj 0 0 0 0 0 0 29 0 0 29 lib_a-sysgettod.o 0 0 0 0 0 0 28 0 0 28 - debug_helpers_asm.S.o 0 0 0 26 0 26 0 0 0 26 - esp_rom_uart.c.o 0 0 0 24 0 24 0 0 0 24 + debug_helpers_asm.S.obj 0 0 0 26 0 26 0 0 0 26 + esp_rom_uart.c.obj 0 0 0 24 0 24 0 0 0 24 bootloader_flash_config_ 0 0 0 0 0 0 22 0 0 22 - bootloader_mem.c.o 0 0 0 0 0 0 15 0 0 15 + bootloader_mem.c.obj 0 0 0 0 0 0 15 0 0 15 lib_a-errno.o 0 0 0 0 0 0 13 0 0 13 - pthread.c.o 0 0 0 0 0 0 12 0 0 12 + pthread.c.obj 0 0 0 0 0 0 12 0 0 12 crtend.o 0 0 0 0 0 0 0 8 0 8 - pm_impl.c.o 0 0 0 0 0 0 8 0 0 8 + pm_impl.c.obj 0 0 0 0 0 0 8 0 0 8 crti.o 0 0 0 0 3 3 3 0 0 6 - cxx_guards.cpp.o 0 0 0 0 0 0 5 0 0 5 - ubsan.c.o 0 0 0 5 0 5 0 0 0 5 + cxx_guards.cpp.obj 0 0 0 0 0 0 5 0 0 5 + ubsan.c.obj 0 0 0 5 0 5 0 0 0 5 crtbegin.o 0 0 0 0 0 0 0 4 0 4 - spi_bus_lock.c.o 0 0 0 0 0 0 0 4 0 4 - FreeRTOS-openocd.c.o 4 0 0 0 0 4 0 0 0 4 + spi_bus_lock.c.obj 0 0 0 0 0 0 0 4 0 4 + FreeRTOS-openocd.c.obj 4 0 0 0 0 4 0 0 0 4 crt0.o 0 0 0 0 0 0 0 0 0 0 crtn.o 0 0 0 0 0 0 0 0 0 0 project_elf_src_esp32s3. 0 0 0 0 0 0 0 0 0 0 - bootloader_common.c.o 0 0 0 0 0 0 0 0 0 0 + bootloader_common.c.obj 0 0 0 0 0 0 0 0 0 0 bootloader_common_loader 0 0 0 0 0 0 0 0 0 0 bootloader_efuse_esp32s3 0 0 0 0 0 0 0 0 0 0 bootloader_random_esp32s 0 0 0 0 0 0 0 0 0 0 - bootloader_sha.c.o 0 0 0 0 0 0 0 0 0 0 - bootloader_utility.c.o 0 0 0 0 0 0 0 0 0 0 - esp_image_format.c.o 0 0 0 0 0 0 0 0 0 0 - flash_partitions.c.o 0 0 0 0 0 0 0 0 0 0 - gdma.c.o 0 0 0 0 0 0 0 0 0 0 - gpio.c.o 0 0 0 0 0 0 0 0 0 0 - rtc_io.c.o 0 0 0 0 0 0 0 0 0 0 - rtc_module.c.o 0 0 0 0 0 0 0 0 0 0 - spi_common.c.o 0 0 0 0 0 0 0 0 0 0 - dport_access.c.o 0 0 0 0 0 0 0 0 0 0 - esp_crypto_lock.c.o 0 0 0 0 0 0 0 0 0 0 + bootloader_sha.c.obj 0 0 0 0 0 0 0 0 0 0 +bootloader_utility.c.obj 0 0 0 0 0 0 0 0 0 0 + esp_image_format.c.obj 0 0 0 0 0 0 0 0 0 0 + flash_partitions.c.obj 0 0 0 0 0 0 0 0 0 0 + gdma.c.obj 0 0 0 0 0 0 0 0 0 0 + gpio.c.obj 0 0 0 0 0 0 0 0 0 0 + rtc_io.c.obj 0 0 0 0 0 0 0 0 0 0 + rtc_module.c.obj 0 0 0 0 0 0 0 0 0 0 + spi_common.c.obj 0 0 0 0 0 0 0 0 0 0 + dport_access.c.obj 0 0 0 0 0 0 0 0 0 0 + esp_crypto_lock.c.obj 0 0 0 0 0 0 0 0 0 0 esp_ipc_isr_routines.S.o 0 0 0 0 0 0 0 0 0 0 - pm_locks.c.o 0 0 0 0 0 0 0 0 0 0 - gdma_hal.c.o 0 0 0 0 0 0 0 0 0 0 - gpio_hal.c.o 0 0 0 0 0 0 0 0 0 0 - rtc_io_hal.c.o 0 0 0 0 0 0 0 0 0 0 - sha_hal.c.o 0 0 0 0 0 0 0 0 0 0 + pm_locks.c.obj 0 0 0 0 0 0 0 0 0 0 + gdma_hal.c.obj 0 0 0 0 0 0 0 0 0 0 + gpio_hal.c.obj 0 0 0 0 0 0 0 0 0 0 + rtc_io_hal.c.obj 0 0 0 0 0 0 0 0 0 0 + sha_hal.c.obj 0 0 0 0 0 0 0 0 0 0 esp_crypto_shared_gdma.c 0 0 0 0 0 0 0 0 0 0 - esp_sha256.c.o 0 0 0 0 0 0 0 0 0 0 - esp_sha_gdma_impl.c.o 0 0 0 0 0 0 0 0 0 0 - sha.c.o 0 0 0 0 0 0 0 0 0 0 - gdma_periph.c.o 0 0 0 0 0 0 0 0 0 0 - gpio_periph.c.o 0 0 0 0 0 0 0 0 0 0 - rtc_io_periph.c.o 0 0 0 0 0 0 0 0 0 0 - spi_periph.c.o 0 0 0 0 0 0 0 0 0 0 - uart_periph.c.o 0 0 0 0 0 0 0 0 0 0 + esp_sha256.c.obj 0 0 0 0 0 0 0 0 0 0 + esp_sha_gdma_impl.c.obj 0 0 0 0 0 0 0 0 0 0 + sha.c.obj 0 0 0 0 0 0 0 0 0 0 + gdma_periph.c.obj 0 0 0 0 0 0 0 0 0 0 + gpio_periph.c.obj 0 0 0 0 0 0 0 0 0 0 + rtc_io_periph.c.obj 0 0 0 0 0 0 0 0 0 0 + spi_periph.c.obj 0 0 0 0 0 0 0 0 0 0 + uart_periph.c.obj 0 0 0 0 0 0 0 0 0 0 int_asm--set_intclear.o 0 0 0 0 0 0 0 0 0 0 lib_a-bzero.o 0 0 0 0 0 0 0 0 0 0 lib_a-environ.o 0 0 4 0 0 4 0 0 0 0 @@ -4578,14 +4448,13 @@ Total sizes: Used static IRAM: 46786 bytes ( 239934 remain, 16.3% used) .text size: 45759 bytes .vectors size: 1027 bytes -Used stat D/IRAM: 11773 bytes ( 123395 remain, 8.7% used) +Used stat D/IRAM: 11772 bytes ( 123396 remain, 8.7% used) .data size: 9252 bytes .bss size: 2520 bytes - .text size: 1 bytes -Used Flash size : 245923 bytes +Used Flash size : 114851 bytes .text : 87463 bytes .rodata : 27132 bytes -Total image size: 301962 bytes (.bin may be padded larger) +Total image size: 170889 bytes (.bin may be padded larger) Symbols within the archive: libdriver.a (Not all symbols may be reported) @@ -4653,9 +4522,6 @@ Symbols from section: .flash.text uart_get_selectlock : 12 Section total: 3468 -Symbols from section: .flash_rodata_dummy -Section total: 0 - Symbols from section: .iram0.bss Section total: 0 @@ -4665,9 +4531,6 @@ Section total: 0 Symbols from section: .iram0.text Section total: 0 -Symbols from section: .iram0.text_end -Section total: 0 - Symbols from section: .iram0.vectors Section total: 0 @@ -4704,21 +4567,21 @@ Producing JSON output... "iram_total": 131072, "used_iram_ratio": 0.297027587890625, "iram_remain": 92140, - "diram_data": 9324, - "diram_bss": 8296, - "diram_text": 37908, - "diram_vectors": 1024, + "diram_data": 0, + "diram_bss": 0, + "diram_text": 0, + "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, - "diram_total": 311808, - "used_diram": 56552, - "used_diram_ratio": 0.18136802134646962, - "diram_remain": 255256, + "diram_total": 0, + "used_diram": 0, + "used_diram_ratio": 0, + "diram_remain": 0, "flash_code": 146944, "flash_rodata": 39580, "flash_other": 0, "used_flash_non_ram": 186524, - "total_size": 283036 + "total_size": 234780 } { "liblwip.a": { @@ -6480,21 +6343,21 @@ Producing JSON output... "iram_total": 131072, "used_iram_ratio": 0.297027587890625, "iram_remain": 92140, - "diram_data": 9324, - "diram_bss": 8296, - "diram_text": 37908, - "diram_vectors": 1024, + "diram_data": 0, + "diram_bss": 0, + "diram_text": 0, + "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, - "diram_total": 311808, - "used_diram": 56552, - "used_diram_ratio": 0.18136802134646962, - "diram_remain": 255256, + "diram_total": 0, + "used_diram": 0, + "used_diram_ratio": 0, + "diram_remain": 0, "flash_code": 146944, "flash_rodata": 39580, "flash_other": 0, "used_flash_non_ram": 186524, - "total_size": 283036 + "total_size": 234780 }, "reference": { "dram_data": 8580, @@ -6506,27 +6369,27 @@ Producing JSON output... "used_dram_ratio": 0.05867121104815864, "dram_remain": 170132, "iram_vectors": 1027, - "iram_text": 37932, + "iram_text": 37929, "iram_other": 0, - "used_iram": 38959, + "used_iram": 38956, "iram_total": 131072, - "used_iram_ratio": 0.29723358154296875, - "iram_remain": 92113, - "diram_data": 8580, - "diram_bss": 2024, - "diram_text": 37932, - "diram_vectors": 1027, + "used_iram_ratio": 0.297210693359375, + "iram_remain": 92116, + "diram_data": 0, + "diram_bss": 0, + "diram_text": 0, + "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, - "diram_total": 311808, - "used_diram": 49563, - "used_diram_ratio": 0.1589535868226601, - "diram_remain": 262245, + "diram_total": 0, + "used_diram": 0, + "used_diram_ratio": 0, + "diram_remain": 0, "flash_code": 77191, "flash_rodata": 22360, "flash_other": 0, "used_flash_non_ram": 99551, - "total_size": 194629 + "total_size": 147087 }, "diff": { "dram_data": 744, @@ -6538,27 +6401,27 @@ Producing JSON output... "used_dram_ratio": 0.03881905099150142, "dram_remain": -7016, "iram_vectors": -3, - "iram_text": -24, + "iram_text": -21, "iram_other": 0, - "used_iram": -27, + "used_iram": -24, "iram_total": 0, - "used_iram_ratio": -0.00020599365234375, - "iram_remain": 27, - "diram_data": 744, - "diram_bss": 6272, - "diram_text": -24, - "diram_vectors": -3, + "used_iram_ratio": -0.00018310546875, + "iram_remain": 24, + "diram_data": 0, + "diram_bss": 0, + "diram_text": 0, + "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, "diram_total": 0, - "used_diram": 6989, - "used_diram_ratio": 0.022414434523809534, - "diram_remain": -6989, + "used_diram": 0, + "used_diram_ratio": 0, + "diram_remain": 0, "flash_code": 69753, "flash_rodata": 17220, "flash_other": 0, "used_flash_non_ram": 86973, - "total_size": 88407 + "total_size": 87693 } } { @@ -8762,7 +8625,7 @@ Producing JSON output... "flash_total": 10633, "ram_st_total": 0 }, - "libfreertos.a:tasks.c.o": { + "libfreertos.a:tasks.c.obj": { ".dram0.bss": 700, ".dram0.data": 12, ".flash.rodata": 451, @@ -8770,13 +8633,13 @@ Producing JSON output... "flash_total": 6200, "ram_st_total": 6449 }, - "libesp_common.a:esp_err_to_name.c.o": { + "libesp_common.a:esp_err_to_name.c.obj": { ".flash.rodata": 5101, ".flash.text": 53, "flash_total": 5154, "ram_st_total": 0 }, - "libvfs.a:vfs_uart.c.o": { + "libvfs.a:vfs_uart.c.obj": { ".dram0.bss": 8, ".dram0.data": 116, ".flash.rodata": 783, @@ -8784,14 +8647,14 @@ Producing JSON output... "flash_total": 4657, "ram_st_total": 124 }, - "libesp32.a:panic.c.o": { + "libesp32.a:panic.c.obj": { ".dram0.bss": 5, ".dram0.data": 2029, ".iram0.text": 2223, "flash_total": 4252, "ram_st_total": 4257 }, - "libfreertos.a:portasm.S.o": { + "libfreertos.a:portasm.S.obj": { ".dram0.data": 3084, ".iram0.text": 476, "flash_total": 3560, @@ -8803,7 +8666,7 @@ Producing JSON output... "flash_total": 3537, "ram_st_total": 0 }, - "libesp32.a:intr_alloc.c.o": { + "libesp32.a:intr_alloc.c.obj": { ".dram0.bss": 22, ".dram0.data": 8, ".flash.rodata": 704, @@ -8812,13 +8675,13 @@ Producing JSON output... "flash_total": 3049, "ram_st_total": 686 }, - "libfreertos.a:queue.c.o": { + "libfreertos.a:queue.c.obj": { ".flash.rodata": 366, ".iram0.text": 2411, "flash_total": 2777, "ram_st_total": 2411 }, - "libdriver.a:uart.c.o": { + "libdriver.a:uart.c.obj": { ".dram0.bss": 12, ".dram0.data": 56, ".flash.rodata": 452, @@ -8826,7 +8689,7 @@ Producing JSON output... "flash_total": 2607, "ram_st_total": 68 }, - "libheap.a:multi_heap.c.o": { + "libheap.a:multi_heap.c.obj": { ".dram0.data": 300, ".iram0.text": 2245, "flash_total": 2545, @@ -8838,7 +8701,7 @@ Producing JSON output... "flash_total": 2436, "ram_st_total": 0 }, - "libesp32.a:cpu_start.c.o": { + "libesp32.a:cpu_start.c.obj": { ".dram0.bss": 1, ".flash.rodata": 1073, ".flash.text": 255, @@ -8846,14 +8709,14 @@ Producing JSON output... "flash_total": 2395, "ram_st_total": 1068 }, - "libsoc.a:rtc_clk.c.o": { + "libsoc.a:rtc_clk.c.obj": { ".dram0.bss": 4, ".dram0.data": 160, ".iram0.text": 2104, "flash_total": 2264, "ram_st_total": 2268 }, - "libvfs.a:vfs.c.o": { + "libvfs.a:vfs.c.obj": { ".dram0.bss": 40, ".dram0.data": 192, ".flash.rodata": 132, @@ -8861,20 +8724,20 @@ Producing JSON output... "flash_total": 2216, "ram_st_total": 232 }, - "libdriver.a:gpio.c.o": { + "libdriver.a:gpio.c.obj": { ".dram0.data": 32, ".flash.rodata": 970, ".flash.text": 1193, "flash_total": 2195, "ram_st_total": 32 }, - "libsoc.a:spi_flash_hal_iram.c.o": { + "libsoc.a:spi_flash_hal_iram.c.obj": { ".dram0.data": 24, ".iram0.text": 1798, "flash_total": 1822, "ram_st_total": 1822 }, - "libfreertos.a:xtensa_vectors.S.o": { + "libfreertos.a:xtensa_vectors.S.obj": { ".dram0.data": 8, ".flash.rodata": 36, ".iram0.text": 1344, @@ -8882,7 +8745,7 @@ Producing JSON output... "flash_total": 1813, "ram_st_total": 1777 }, - "libesp32.a:task_wdt.c.o": { + "libesp32.a:task_wdt.c.obj": { ".dram0.bss": 4, ".dram0.data": 53, ".flash.rodata": 494, @@ -8890,13 +8753,13 @@ Producing JSON output... "flash_total": 1770, "ram_st_total": 57 }, - "libspi_flash.a:spi_flash_chip_generic.c.o": { + "libspi_flash.a:spi_flash_chip_generic.c.obj": { ".dram0.data": 340, ".iram0.text": 1423, "flash_total": 1763, "ram_st_total": 1763 }, - "libspi_flash.a:flash_mmap.c.o": { + "libspi_flash.a:flash_mmap.c.obj": { ".dram0.bss": 264, ".flash.rodata": 296, ".flash.text": 125, @@ -8904,7 +8767,7 @@ Producing JSON output... "flash_total": 1741, "ram_st_total": 1584 }, - "libspi_flash.a:cache_utils.c.o": { + "libspi_flash.a:cache_utils.c.obj": { ".dram0.bss": 14, ".dram0.data": 4, ".flash.rodata": 430, @@ -8913,7 +8776,7 @@ Producing JSON output... "flash_total": 1348, "ram_st_total": 851 }, - "libheap.a:heap_caps.c.o": { + "libheap.a:heap_caps.c.obj": { ".dram0.data": 4, ".flash.rodata": 362, ".flash.text": 50, @@ -8921,7 +8784,7 @@ Producing JSON output... "flash_total": 1300, "ram_st_total": 888 }, - "libfreertos.a:timers.c.o": { + "libfreertos.a:timers.c.obj": { ".dram0.bss": 56, ".dram0.data": 8, ".flash.rodata": 223, @@ -8929,7 +8792,7 @@ Producing JSON output... "flash_total": 1238, "ram_st_total": 1071 }, - "libesp_timer.a:esp_timer_impl_lac.c.o": { + "libesp_timer.a:esp_timer_impl_lac.c.obj": { ".dram0.bss": 8, ".dram0.data": 8, ".flash.rodata": 389, @@ -8938,57 +8801,57 @@ Producing JSON output... "flash_total": 1233, "ram_st_total": 530 }, - "libheap.a:heap_caps_init.c.o": { + "libheap.a:heap_caps_init.c.obj": { ".dram0.bss": 4, ".flash.rodata": 379, ".flash.text": 834, "flash_total": 1213, "ram_st_total": 4 }, - "libsoc.a:soc_memory_layout.c.o": { + "libsoc.a:soc_memory_layout.c.obj": { ".flash.rodata": 1197, "flash_total": 1197, "ram_st_total": 0 }, - "libdriver.a:periph_ctrl.c.o": { + "libdriver.a:periph_ctrl.c.obj": { ".dram0.data": 8, ".flash.rodata": 488, ".flash.text": 696, "flash_total": 1192, "ram_st_total": 8 }, - "libfreertos.a:port.c.o": { + "libfreertos.a:port.c.obj": { ".dram0.bss": 32, ".flash.rodata": 340, ".iram0.text": 737, "flash_total": 1077, "ram_st_total": 769 }, - "libfreertos.a:xtensa_intr_asm.S.o": { + "libfreertos.a:xtensa_intr_asm.S.obj": { ".dram0.data": 1024, ".iram0.text": 51, "flash_total": 1075, "ram_st_total": 1075 }, - "libbootloader_support.a:bootloader_flash_config_esp32.c.o": { + "libbootloader_support.a:bootloader_flash_config_esp32.c.obj": { ".flash.text": 17, ".iram0.text": 1028, "flash_total": 1045, "ram_st_total": 1028 }, - "libsoc.a:rtc_time.c.o": { + "libsoc.a:rtc_time.c.obj": { ".flash.rodata": 194, ".iram0.text": 819, "flash_total": 1013, "ram_st_total": 819 }, - "libesp_ringbuf.a:ringbuf.c.o": { + "libesp_ringbuf.a:ringbuf.c.obj": { ".flash.rodata": 150, ".iram0.text": 858, "flash_total": 1008, "ram_st_total": 858 }, - "libsoc.a:rtc_init.c.o": { + "libsoc.a:rtc_init.c.obj": { ".iram0.text": 956, "flash_total": 956, "ram_st_total": 956 @@ -8998,46 +8861,46 @@ Producing JSON output... "flash_total": 918, "ram_st_total": 0 }, - "libspi_flash.a:esp_flash_api.c.o": { + "libspi_flash.a:esp_flash_api.c.obj": { ".flash.rodata": 244, ".flash.text": 16, ".iram0.text": 600, "flash_total": 860, "ram_st_total": 600 }, - "libesp32.a:clk.c.o": { + "libesp32.a:clk.c.obj": { ".flash.rodata": 208, ".flash.text": 582, ".iram0.text": 64, "flash_total": 854, "ram_st_total": 64 }, - "libspi_flash.a:partition.c.o": { + "libspi_flash.a:partition.c.obj": { ".dram0.bss": 8, ".flash.rodata": 181, ".flash.text": 668, "flash_total": 849, "ram_st_total": 8 }, - "libnewlib.a:time.c.o": { + "libnewlib.a:time.c.obj": { ".dram0.bss": 32, ".flash.text": 719, ".iram0.text": 123, "flash_total": 842, "ram_st_total": 155 }, - "libsoc.a:memory_layout_utils.c.o": { + "libsoc.a:memory_layout_utils.c.obj": { ".flash.rodata": 295, ".flash.text": 505, "flash_total": 800, "ram_st_total": 0 }, - "libsoc.a:rtc_wdt.c.o": { + "libsoc.a:rtc_wdt.c.obj": { ".iram0.text": 796, "flash_total": 796, "ram_st_total": 796 }, - "libesp_timer.a:esp_timer.c.o": { + "libesp_timer.a:esp_timer.c.obj": { ".dram0.bss": 12, ".dram0.data": 8, ".flash.rodata": 104, @@ -9046,7 +8909,7 @@ Producing JSON output... "flash_total": 793, "ram_st_total": 300 }, - "libesp32.a:dport_access.c.o": { + "libesp32.a:dport_access.c.obj": { ".dram0.bss": 40, ".dram0.data": 8, ".flash.rodata": 126, @@ -9055,7 +8918,7 @@ Producing JSON output... "flash_total": 745, "ram_st_total": 470 }, - "libesp_common.a:ipc.c.o": { + "libesp_common.a:ipc.c.obj": { ".dram0.bss": 56, ".flash.rodata": 117, ".flash.text": 367, @@ -9063,7 +8926,7 @@ Producing JSON output... "flash_total": 676, "ram_st_total": 248 }, - "liblog.a:log.c.o": { + "liblog.a:log.c.obj": { ".dram0.bss": 264, ".dram0.data": 8, ".flash.rodata": 147, @@ -9072,7 +8935,7 @@ Producing JSON output... "flash_total": 673, "ram_st_total": 306 }, - "libnewlib.a:locks.c.o": { + "libnewlib.a:locks.c.obj": { ".dram0.data": 8, ".flash.rodata": 84, ".flash.text": 5, @@ -9080,7 +8943,7 @@ Producing JSON output... "flash_total": 584, "ram_st_total": 495 }, - "libspi_flash.a:esp_flash_spi_init.c.o": { + "libspi_flash.a:esp_flash_spi_init.c.obj": { ".dram0.bss": 4, ".dram0.data": 120, ".flash.rodata": 261, @@ -9088,17 +8951,17 @@ Producing JSON output... "flash_total": 572, "ram_st_total": 124 }, - "libsoc.a:uart_hal.c.o": { + "libsoc.a:uart_hal.c.obj": { ".flash.text": 493, "flash_total": 493, "ram_st_total": 0 }, - "libbootloader_support.a:flash_qio_mode.c.o": { + "libbootloader_support.a:flash_qio_mode.c.obj": { ".flash.text": 490, "flash_total": 490, "ram_st_total": 0 }, - "libesp32.a:crosscore_int.c.o": { + "libesp32.a:crosscore_int.c.obj": { ".dram0.bss": 8, ".dram0.data": 8, ".flash.rodata": 146, @@ -9107,19 +8970,19 @@ Producing JSON output... "flash_total": 483, "ram_st_total": 211 }, - "libesp32.a:int_wdt.c.o": { + "libesp32.a:int_wdt.c.obj": { ".dram0.bss": 1, ".flash.text": 341, ".iram0.text": 94, "flash_total": 435, "ram_st_total": 95 }, - "libesp32.a:system_api_esp32.c.o": { + "libesp32.a:system_api_esp32.c.obj": { ".iram0.text": 435, "flash_total": 435, "ram_st_total": 435 }, - "libapp_update.a:esp_app_desc.c.o": { + "libapp_update.a:esp_app_desc.c.obj": { ".flash.rodata": 256, ".flash.text": 12, ".iram0.text": 109, @@ -9132,31 +8995,31 @@ Producing JSON output... "flash_total": 374, "ram_st_total": 364 }, - "libsoc.a:uart_hal_iram.c.o": { + "libsoc.a:uart_hal_iram.c.obj": { ".flash.rodata": 222, ".flash.text": 147, "flash_total": 369, "ram_st_total": 0 }, - "libfreertos.a:xtensa_context.S.o": { + "libfreertos.a:xtensa_context.S.obj": { ".iram0.text": 367, "flash_total": 367, "ram_st_total": 367 }, - "libapp_update.a:esp_ota_ops.c.o": { + "libapp_update.a:esp_ota_ops.c.obj": { ".dram0.bss": 4, ".flash.rodata": 214, ".flash.text": 147, "flash_total": 361, "ram_st_total": 4 }, - "libsoc.a:spi_flash_hal.c.o": { + "libsoc.a:spi_flash_hal.c.obj": { ".flash.rodata": 48, ".flash.text": 302, "flash_total": 350, "ram_st_total": 0 }, - "libesp_common.a:brownout.c.o": { + "libesp_common.a:brownout.c.obj": { ".flash.rodata": 203, ".flash.text": 120, "flash_total": 323, @@ -9167,7 +9030,7 @@ Producing JSON output... "flash_total": 315, "ram_st_total": 315 }, - "libesp_common.a:freertos_hooks.c.o": { + "libesp_common.a:freertos_hooks.c.obj": { ".dram0.bss": 128, ".dram0.data": 8, ".flash.text": 243, @@ -9175,36 +9038,36 @@ Producing JSON output... "flash_total": 298, "ram_st_total": 183 }, - "libspi_flash.a:spi_flash_chip_gd.c.o": { + "libspi_flash.a:spi_flash_chip_gd.c.obj": { ".dram0.data": 95, ".iram0.text": 181, "flash_total": 276, "ram_st_total": 276 }, - "libsoc.a:brownout_hal.c.o": { + "libsoc.a:brownout_hal.c.obj": { ".flash.text": 269, "flash_total": 269, "ram_st_total": 0 }, - "libesp32.a:dport_panic_highint_hdl.S.o": { + "libesp32.a:dport_panic_highint_hdl.S.obj": { ".dram0.data": 12, ".iram0.text": 250, "flash_total": 262, "ram_st_total": 262 }, - "libsoc.a:soc_hal.c.o": { + "libsoc.a:soc_hal.c.obj": { ".dram0.data": 24, ".iram0.text": 234, "flash_total": 258, "ram_st_total": 258 }, - "libspi_flash.a:memspi_host_driver.c.o": { + "libspi_flash.a:memspi_host_driver.c.obj": { ".dram0.data": 43, ".iram0.text": 206, "flash_total": 249, "ram_st_total": 249 }, - "libdriver.a:rtc_module.c.o": { + "libdriver.a:rtc_module.c.obj": { ".dram0.bss": 8, ".dram0.data": 16, ".flash.text": 231, @@ -9227,7 +9090,7 @@ Producing JSON output... "flash_total": 234, "ram_st_total": 0 }, - "libnewlib.a:syscall_table.c.o": { + "libnewlib.a:syscall_table.c.obj": { ".dram0.bss": 240, ".dram0.data": 144, ".flash.text": 82, @@ -9239,66 +9102,66 @@ Producing JSON output... "flash_total": 217, "ram_st_total": 0 }, - "libxtensa.a:debug_helpers.c.o": { + "libxtensa.a:debug_helpers.c.obj": { ".iram0.text": 217, "flash_total": 217, "ram_st_total": 217 }, - "libspi_flash.a:spi_flash_chip_issi.c.o": { + "libspi_flash.a:spi_flash_chip_issi.c.obj": { ".dram0.data": 97, ".iram0.text": 101, "flash_total": 198, "ram_st_total": 198 }, - "libpthread.a:pthread_local_storage.c.o": { + "libpthread.a:pthread_local_storage.c.obj": { ".dram0.bss": 4, ".dram0.data": 8, ".flash.text": 183, "flash_total": 191, "ram_st_total": 12 }, - "liblog.a:log_freertos.c.o": { + "liblog.a:log_freertos.c.obj": { ".dram0.bss": 8, ".iram0.text": 188, "flash_total": 188, "ram_st_total": 196 }, - "libsoc_esp32.a:gpio_periph.c.o": { + "libsoc_esp32.a:gpio_periph.c.obj": { ".flash.rodata": 160, "flash_total": 160, "ram_st_total": 0 }, - "libesp32.a:cache_err_int.c.o": { + "libesp32.a:cache_err_int.c.obj": { ".flash.text": 98, ".iram0.text": 56, "flash_total": 154, "ram_st_total": 56 }, - "libnewlib.a:heap.c.o": { + "libnewlib.a:heap.c.obj": { ".iram0.text": 151, "flash_total": 151, "ram_st_total": 151 }, - "libfreertos.a:xtensa_intr.c.o": { + "libfreertos.a:xtensa_intr.c.obj": { ".flash.rodata": 35, ".iram0.text": 113, "flash_total": 148, "ram_st_total": 113 }, - "libspi_flash.a:spi_flash_os_func_noos.c.o": { + "libspi_flash.a:spi_flash_os_func_noos.c.obj": { ".dram0.data": 16, ".iram0.text": 127, "flash_total": 143, "ram_st_total": 143 }, - "libspi_flash.a:spi_flash_os_func_app.c.o": { + "libspi_flash.a:spi_flash_os_func_app.c.obj": { ".dram0.data": 24, ".flash.text": 25, ".iram0.text": 91, "flash_total": 140, "ram_st_total": 115 }, - "libfreertos.a:list.c.o": { + "libfreertos.a:list.c.obj": { ".iram0.text": 138, "flash_total": 138, "ram_st_total": 138 @@ -9314,7 +9177,7 @@ Producing JSON output... "flash_total": 128, "ram_st_total": 0 }, - "libmain.a:blink.c.o": { + "libmain.a:blink.c.obj": { ".flash.rodata": 39, ".flash.text": 72, "flash_total": 111, @@ -9335,19 +9198,19 @@ Producing JSON output... "flash_total": 84, "ram_st_total": 0 }, - "libpthread.a:pthread.c.o": { + "libpthread.a:pthread.c.obj": { ".dram0.bss": 8, ".flash.text": 81, "flash_total": 81, "ram_st_total": 8 }, - "libbootloader_support.a:bootloader_mem.c.o": { + "libbootloader_support.a:bootloader_mem.c.obj": { ".flash.rodata": 20, ".flash.text": 58, "flash_total": 78, "ram_st_total": 0 }, - "libsoc.a:cpu_util.c.o": { + "libsoc.a:cpu_util.c.obj": { ".iram0.text": 75, "flash_total": 75, "ram_st_total": 75 @@ -9362,7 +9225,7 @@ Producing JSON output... "flash_total": 63, "ram_st_total": 0 }, - "libspi_flash.a:flash_ops.c.o": { + "libspi_flash.a:flash_ops.c.obj": { ".dram0.bss": 4, ".dram0.data": 20, ".flash.text": 29, @@ -9380,27 +9243,27 @@ Producing JSON output... "flash_total": 62, "ram_st_total": 62 }, - "libnewlib.a:reent_init.c.o": { + "libnewlib.a:reent_init.c.obj": { ".iram0.text": 59, "flash_total": 59, "ram_st_total": 59 }, - "libdriver.a:rtc_io.c.o": { + "libdriver.a:rtc_io.c.obj": { ".flash.text": 53, "flash_total": 53, "ram_st_total": 0 }, - "libnewlib.a:syscalls.c.o": { + "libnewlib.a:syscalls.c.obj": { ".flash.text": 50, "flash_total": 50, "ram_st_total": 0 }, - "libsoc.a:mpu_hal.c.o": { + "libsoc.a:mpu_hal.c.obj": { ".flash.text": 47, "flash_total": 47, "ram_st_total": 0 }, - "libfreertos.a:xtensa_vector_defaults.S.o": { + "libfreertos.a:xtensa_vector_defaults.S.obj": { ".iram0.text": 46, "flash_total": 46, "ram_st_total": 46 @@ -9430,7 +9293,7 @@ Producing JSON output... "flash_total": 40, "ram_st_total": 0 }, - "libfreertos.a:xtensa_init.c.o": { + "libfreertos.a:xtensa_init.c.obj": { ".dram0.bss": 4, ".iram0.text": 32, "flash_total": 32, @@ -9441,12 +9304,12 @@ Producing JSON output... "flash_total": 32, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_drivers.c.o": { + "libspi_flash.a:spi_flash_chip_drivers.c.obj": { ".dram0.data": 20, "flash_total": 20, "ram_st_total": 20 }, - "libnewlib.a:pthread.c.o": { + "libnewlib.a:pthread.c.obj": { ".flash.text": 12, "flash_total": 12, "ram_st_total": 0 @@ -9461,7 +9324,7 @@ Producing JSON output... "flash_total": 8, "ram_st_total": 0 }, - "libesp32.a:pm_esp32.c.o": { + "libesp32.a:pm_esp32.c.obj": { ".flash.text": 8, "flash_total": 8, "ram_st_total": 0 @@ -9471,7 +9334,7 @@ Producing JSON output... "flash_total": 8, "ram_st_total": 8 }, - "libsoc.a:cpu_hal.c.o": { + "libsoc.a:cpu_hal.c.obj": { ".iram0.text": 8, "flash_total": 8, "ram_st_total": 8 @@ -9482,12 +9345,12 @@ Producing JSON output... "flash_total": 6, "ram_st_total": 3 }, - "libcxx.a:cxx_exception_stubs.cpp.o": { + "libcxx.a:cxx_exception_stubs.cpp.obj": { ".flash.text": 6, "flash_total": 6, "ram_st_total": 0 }, - "libcxx.a:cxx_guards.cpp.o": { + "libcxx.a:cxx_guards.cpp.obj": { ".flash.text": 5, "flash_total": 5, "ram_st_total": 0 @@ -9497,7 +9360,7 @@ Producing JSON output... "flash_total": 4, "ram_st_total": 0 }, - "libfreertos.a:FreeRTOS-openocd.c.o": { + "libfreertos.a:FreeRTOS-openocd.c.obj": { ".dram0.data": 4, "flash_total": 4, "ram_st_total": 4 @@ -9510,39 +9373,39 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "(exe):project_elf_src.c.o": { + "(exe):project_elf_src.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_common.c.o": { + "libbootloader_support.a:bootloader_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_efuse_esp32.c.o": { + "libbootloader_support.a:bootloader_efuse_esp32.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash.c.o": { + "libbootloader_support.a:bootloader_flash.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_random.c.o": { + "libbootloader_support.a:bootloader_random.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_sha.c.o": { + "libbootloader_support.a:bootloader_sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_utility.c.o": { + "libbootloader_support.a:bootloader_utility.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:esp_image_format.c.o": { + "libbootloader_support.a:esp_image_format.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:flash_partitions.c.o": { + "libbootloader_support.a:flash_partitions.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -9790,35 +9653,35 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:spi_common.c.o": { + "libdriver.a:spi_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_api.c.o": { + "libefuse.a:esp_efuse_api.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_fields.c.o": { + "libefuse.a:esp_efuse_fields.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_table.c.o": { + "libefuse.a:esp_efuse_table.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_utility.c.o": { + "libefuse.a:esp_efuse_utility.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp32.a:hw_random.c.o": { + "libesp32.a:hw_random.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_common.a:pm_locks.c.o": { + "libesp_common.a:pm_locks.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_common.a:system_api.c.o": { + "libesp_common.a:system_api.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -9854,43 +9717,43 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:esp_sha256.c.o": { + "libmbedcrypto.a:esp_sha256.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:sha.c.o": { + "libmbedcrypto.a:sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:gpio_hal.c.o": { + "libsoc.a:gpio_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:rtc_io_hal.c.o": { + "libsoc.a:rtc_io_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32.a:rtc_io_periph.c.o": { + "libsoc_esp32.a:rtc_io_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32.a:spi_periph.c.o": { + "libsoc_esp32.a:spi_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32.a:uart_periph.c.o": { + "libsoc_esp32.a:uart_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_rom_patch.c.o": { + "libspi_flash.a:spi_flash_rom_patch.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libwpa_supplicant.a:md5-internal.c.o": { + "libwpa_supplicant.a:md5-internal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libxtensa.a:debug_helpers_asm.S.o": { + "libxtensa.a:debug_helpers_asm.S.obj": { "flash_total": 0, "ram_st_total": 0 } @@ -9920,18 +9783,18 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "(exe):project_elf_src.c.o": { + "(exe):project_elf_src.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libapp_update.a:esp_app_desc.c.o": { + "libapp_update.a:esp_app_desc.c.obj": { ".flash.rodata": -256, ".flash.text": -12, ".iram0.text": -109, "flash_total": -377, "ram_st_total": -109 }, - "libapp_update.a:esp_ota_ops.c.o": { + "libapp_update.a:esp_ota_ops.c.obj": { ".dram0.bss": -4, ".flash.rodata": -214, ".flash.text": -147, @@ -9944,15 +9807,15 @@ Producing JSON output... "flash_total": 840, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_common.c.o": { + "libbootloader_support.a:bootloader_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_efuse_esp32.c.o": { + "libbootloader_support.a:bootloader_efuse_esp32.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash.c.o": { + "libbootloader_support.a:bootloader_flash.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -9960,23 +9823,23 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash_config_esp32.c.o": { + "libbootloader_support.a:bootloader_flash_config_esp32.c.obj": { ".flash.text": -17, ".iram0.text": -1028, "flash_total": -1045, "ram_st_total": -1028 }, - "libbootloader_support.a:bootloader_mem.c.o": { + "libbootloader_support.a:bootloader_mem.c.obj": { ".flash.rodata": -20, ".flash.text": -58, "flash_total": -78, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_random.c.o": { + "libbootloader_support.a:bootloader_random.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_sha.c.o": { + "libbootloader_support.a:bootloader_sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -9984,11 +9847,11 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_utility.c.o": { + "libbootloader_support.a:bootloader_utility.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:esp_image_format.c.o": { + "libbootloader_support.a:esp_image_format.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -9996,11 +9859,11 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:flash_partitions.c.o": { + "libbootloader_support.a:flash_partitions.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:flash_qio_mode.c.o": { + "libbootloader_support.a:flash_qio_mode.c.obj": { ".flash.text": -490, "flash_total": -490, "ram_st_total": 0 @@ -10409,7 +10272,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libcxx.a:cxx_exception_stubs.cpp.o": { + "libcxx.a:cxx_exception_stubs.cpp.obj": { ".flash.text": -6, "flash_total": -6, "ram_st_total": 0 @@ -10419,7 +10282,7 @@ Producing JSON output... "flash_total": 6, "ram_st_total": 0 }, - "libcxx.a:cxx_guards.cpp.o": { + "libcxx.a:cxx_guards.cpp.obj": { ".flash.text": -5, "flash_total": -5, "ram_st_total": 0 @@ -10429,7 +10292,7 @@ Producing JSON output... "flash_total": 5, "ram_st_total": 0 }, - "libdriver.a:gpio.c.o": { + "libdriver.a:gpio.c.obj": { ".dram0.data": -32, ".flash.rodata": -970, ".flash.text": -1193, @@ -10440,7 +10303,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:periph_ctrl.c.o": { + "libdriver.a:periph_ctrl.c.obj": { ".dram0.data": -8, ".flash.rodata": -488, ".flash.text": -696, @@ -10454,12 +10317,12 @@ Producing JSON output... "flash_total": 784, "ram_st_total": 8 }, - "libdriver.a:rtc_io.c.o": { + "libdriver.a:rtc_io.c.obj": { ".flash.text": -53, "flash_total": -53, "ram_st_total": 0 }, - "libdriver.a:rtc_module.c.o": { + "libdriver.a:rtc_module.c.obj": { ".dram0.bss": -8, ".dram0.data": -16, ".flash.text": -231, @@ -10473,7 +10336,7 @@ Producing JSON output... "flash_total": 299, "ram_st_total": 16 }, - "libdriver.a:spi_common.c.o": { + "libdriver.a:spi_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -10484,7 +10347,7 @@ Producing JSON output... "flash_total": 409, "ram_st_total": 16 }, - "libdriver.a:uart.c.o": { + "libdriver.a:uart.c.obj": { ".dram0.bss": -12, ".dram0.data": -56, ".flash.rodata": -452, @@ -10499,19 +10362,19 @@ Producing JSON output... "flash_total": 46, "ram_st_total": 20 }, - "libefuse.a:esp_efuse_api.c.o": { + "libefuse.a:esp_efuse_api.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_fields.c.o": { + "libefuse.a:esp_efuse_fields.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_table.c.o": { + "libefuse.a:esp_efuse_table.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_utility.c.o": { + "libefuse.a:esp_efuse_utility.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -10521,7 +10384,7 @@ Producing JSON output... "flash_total": 336, "ram_st_total": 0 }, - "libesp32.a:cache_err_int.c.o": { + "libesp32.a:cache_err_int.c.obj": { ".flash.text": -98, ".iram0.text": -56, "flash_total": -154, @@ -10533,7 +10396,7 @@ Producing JSON output... "flash_total": 154, "ram_st_total": 56 }, - "libesp32.a:clk.c.o": { + "libesp32.a:clk.c.obj": { ".flash.rodata": -208, ".flash.text": -582, ".iram0.text": -64, @@ -10547,7 +10410,7 @@ Producing JSON output... "flash_total": 1541, "ram_st_total": 67 }, - "libesp32.a:cpu_start.c.o": { + "libesp32.a:cpu_start.c.obj": { ".dram0.bss": -1, ".flash.rodata": -1073, ".flash.text": -255, @@ -10563,7 +10426,7 @@ Producing JSON output... "flash_total": 1569, "ram_st_total": 807 }, - "libesp32.a:crosscore_int.c.o": { + "libesp32.a:crosscore_int.c.obj": { ".dram0.bss": -8, ".dram0.data": -8, ".flash.rodata": -146, @@ -10588,7 +10451,7 @@ Producing JSON output... "flash_total": 132, "ram_st_total": 2104 }, - "libesp32.a:dport_access.c.o": { + "libesp32.a:dport_access.c.obj": { ".dram0.bss": -40, ".dram0.data": -8, ".flash.rodata": -126, @@ -10606,7 +10469,7 @@ Producing JSON output... "flash_total": 865, "ram_st_total": 587 }, - "libesp32.a:dport_panic_highint_hdl.S.o": { + "libesp32.a:dport_panic_highint_hdl.S.obj": { ".dram0.data": -12, ".iram0.text": -250, "flash_total": -262, @@ -10662,7 +10525,7 @@ Producing JSON output... "flash_total": 188, "ram_st_total": 179 }, - "libesp32.a:hw_random.c.o": { + "libesp32.a:hw_random.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -10672,7 +10535,7 @@ Producing JSON output... "flash_total": 74, "ram_st_total": 78 }, - "libesp32.a:int_wdt.c.o": { + "libesp32.a:int_wdt.c.obj": { ".dram0.bss": -1, ".flash.text": -341, ".iram0.text": -94, @@ -10686,7 +10549,7 @@ Producing JSON output... "flash_total": 388, "ram_st_total": 88 }, - "libesp32.a:intr_alloc.c.o": { + "libesp32.a:intr_alloc.c.obj": { ".dram0.bss": -22, ".dram0.data": -8, ".flash.rodata": -704, @@ -10716,7 +10579,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libesp32.a:panic.c.o": { + "libesp32.a:panic.c.obj": { ".dram0.bss": -5, ".dram0.data": -2029, ".iram0.text": -2223, @@ -10734,7 +10597,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libesp32.a:pm_esp32.c.o": { + "libesp32.a:pm_esp32.c.obj": { ".flash.text": -8, "flash_total": -8, "ram_st_total": 0 @@ -10757,12 +10620,12 @@ Producing JSON output... "flash_total": 1251, "ram_st_total": 597 }, - "libesp32.a:system_api_esp32.c.o": { + "libesp32.a:system_api_esp32.c.obj": { ".iram0.text": -435, "flash_total": -435, "ram_st_total": -435 }, - "libesp32.a:task_wdt.c.o": { + "libesp32.a:task_wdt.c.obj": { ".dram0.bss": -4, ".dram0.data": -53, ".flash.rodata": -494, @@ -10780,19 +10643,19 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libesp_common.a:brownout.c.o": { + "libesp_common.a:brownout.c.obj": { ".flash.rodata": -203, ".flash.text": -120, "flash_total": -323, "ram_st_total": 0 }, - "libesp_common.a:esp_err_to_name.c.o": { + "libesp_common.a:esp_err_to_name.c.obj": { ".flash.rodata": -5101, ".flash.text": -53, "flash_total": -5154, "ram_st_total": 0 }, - "libesp_common.a:freertos_hooks.c.o": { + "libesp_common.a:freertos_hooks.c.obj": { ".dram0.bss": -128, ".dram0.data": -8, ".flash.text": -243, @@ -10800,7 +10663,7 @@ Producing JSON output... "flash_total": -298, "ram_st_total": -183 }, - "libesp_common.a:ipc.c.o": { + "libesp_common.a:ipc.c.obj": { ".dram0.bss": -56, ".flash.rodata": -117, ".flash.text": -367, @@ -10808,21 +10671,21 @@ Producing JSON output... "flash_total": -676, "ram_st_total": -248 }, - "libesp_common.a:pm_locks.c.o": { + "libesp_common.a:pm_locks.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_common.a:system_api.c.o": { + "libesp_common.a:system_api.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_ringbuf.a:ringbuf.c.o": { + "libesp_ringbuf.a:ringbuf.c.obj": { ".flash.rodata": -150, ".iram0.text": -858, "flash_total": -1008, "ram_st_total": -858 }, - "libesp_timer.a:esp_timer.c.o": { + "libesp_timer.a:esp_timer.c.obj": { ".dram0.bss": -12, ".dram0.data": -8, ".flash.rodata": -104, @@ -10831,7 +10694,7 @@ Producing JSON output... "flash_total": -793, "ram_st_total": -300 }, - "libesp_timer.a:esp_timer_impl_lac.c.o": { + "libesp_timer.a:esp_timer_impl_lac.c.obj": { ".dram0.bss": -8, ".dram0.data": -8, ".flash.rodata": -389, @@ -10848,7 +10711,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libfreertos.a:FreeRTOS-openocd.c.o": { + "libfreertos.a:FreeRTOS-openocd.c.obj": { ".dram0.data": -4, "flash_total": -4, "ram_st_total": -4 @@ -10862,7 +10725,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libfreertos.a:list.c.o": { + "libfreertos.a:list.c.obj": { ".iram0.text": -138, "flash_total": -138, "ram_st_total": -138 @@ -10872,7 +10735,7 @@ Producing JSON output... "flash_total": 142, "ram_st_total": 142 }, - "libfreertos.a:port.c.o": { + "libfreertos.a:port.c.obj": { ".dram0.bss": -32, ".flash.rodata": -340, ".iram0.text": -737, @@ -10886,7 +10749,7 @@ Producing JSON output... "flash_total": 986, "ram_st_total": 633 }, - "libfreertos.a:portasm.S.o": { + "libfreertos.a:portasm.S.obj": { ".dram0.data": -3084, ".iram0.text": -476, "flash_total": -3560, @@ -10898,7 +10761,7 @@ Producing JSON output... "flash_total": 3564, "ram_st_total": 3564 }, - "libfreertos.a:queue.c.o": { + "libfreertos.a:queue.c.obj": { ".flash.rodata": -366, ".iram0.text": -2411, "flash_total": -2777, @@ -10916,7 +10779,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libfreertos.a:tasks.c.o": { + "libfreertos.a:tasks.c.obj": { ".dram0.bss": -700, ".dram0.data": -12, ".flash.rodata": -451, @@ -10932,7 +10795,7 @@ Producing JSON output... "flash_total": 6190, "ram_st_total": 6387 }, - "libfreertos.a:timers.c.o": { + "libfreertos.a:timers.c.obj": { ".dram0.bss": -56, ".dram0.data": -8, ".flash.rodata": -223, @@ -10948,7 +10811,7 @@ Producing JSON output... "flash_total": 1390, "ram_st_total": 1213 }, - "libfreertos.a:xtensa_context.S.o": { + "libfreertos.a:xtensa_context.S.obj": { ".iram0.text": -367, "flash_total": -367, "ram_st_total": -367 @@ -10958,7 +10821,7 @@ Producing JSON output... "flash_total": 299, "ram_st_total": 299 }, - "libfreertos.a:xtensa_init.c.o": { + "libfreertos.a:xtensa_init.c.obj": { ".dram0.bss": -4, ".iram0.text": -32, "flash_total": -32, @@ -10970,7 +10833,7 @@ Producing JSON output... "flash_total": 32, "ram_st_total": 36 }, - "libfreertos.a:xtensa_intr.c.o": { + "libfreertos.a:xtensa_intr.c.obj": { ".flash.rodata": -35, ".iram0.text": -113, "flash_total": -148, @@ -10982,7 +10845,7 @@ Producing JSON output... "flash_total": 139, "ram_st_total": 104 }, - "libfreertos.a:xtensa_intr_asm.S.o": { + "libfreertos.a:xtensa_intr_asm.S.obj": { ".dram0.data": -1024, ".iram0.text": -51, "flash_total": -1075, @@ -10994,7 +10857,7 @@ Producing JSON output... "flash_total": 1075, "ram_st_total": 1075 }, - "libfreertos.a:xtensa_vector_defaults.S.o": { + "libfreertos.a:xtensa_vector_defaults.S.obj": { ".iram0.text": -46, "flash_total": -46, "ram_st_total": -46 @@ -11004,7 +10867,7 @@ Producing JSON output... "flash_total": 46, "ram_st_total": 46 }, - "libfreertos.a:xtensa_vectors.S.o": { + "libfreertos.a:xtensa_vectors.S.obj": { ".dram0.data": -8, ".flash.rodata": -36, ".iram0.text": -1344, @@ -11137,7 +11000,7 @@ Producing JSON output... "flash_total": -4, "ram_st_total": -4 }, - "libheap.a:heap_caps.c.o": { + "libheap.a:heap_caps.c.obj": { ".dram0.data": -4, ".flash.rodata": -362, ".flash.text": -50, @@ -11153,7 +11016,7 @@ Producing JSON output... "flash_total": 1980, "ram_st_total": 1199 }, - "libheap.a:heap_caps_init.c.o": { + "libheap.a:heap_caps_init.c.obj": { ".dram0.bss": -4, ".flash.rodata": -379, ".flash.text": -834, @@ -11167,7 +11030,7 @@ Producing JSON output... "flash_total": 1417, "ram_st_total": 4 }, - "libheap.a:multi_heap.c.o": { + "libheap.a:multi_heap.c.obj": { ".dram0.data": -300, ".iram0.text": -2245, "flash_total": -2545, @@ -11185,7 +11048,7 @@ Producing JSON output... "flash_total": 1434, "ram_st_total": 1434 }, - "liblog.a:log.c.o": { + "liblog.a:log.c.obj": { ".dram0.bss": -264, ".dram0.data": -8, ".flash.rodata": -147, @@ -11203,7 +11066,7 @@ Producing JSON output... "flash_total": 1026, "ram_st_total": 732 }, - "liblog.a:log_freertos.c.o": { + "liblog.a:log_freertos.c.obj": { ".dram0.bss": -8, ".iram0.text": -188, "flash_total": -188, @@ -11457,17 +11320,17 @@ Producing JSON output... "flash_total": 63, "ram_st_total": 0 }, - "libmain.a:blink.c.o": { + "libmain.a:blink.c.obj": { ".flash.rodata": -39, ".flash.text": -72, "flash_total": -111, "ram_st_total": 0 }, - "libmbedcrypto.a:esp_sha256.c.o": { + "libmbedcrypto.a:esp_sha256.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:sha.c.o": { + "libmbedcrypto.a:sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -11631,12 +11494,12 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libnewlib.a:heap.c.o": { + "libnewlib.a:heap.c.obj": { ".iram0.text": -151, "flash_total": -151, "ram_st_total": -151 }, - "libnewlib.a:locks.c.o": { + "libnewlib.a:locks.c.obj": { ".dram0.data": -8, ".flash.rodata": -84, ".flash.text": -5, @@ -11651,12 +11514,12 @@ Producing JSON output... "flash_total": 644, "ram_st_total": 560 }, - "libnewlib.a:pthread.c.o": { + "libnewlib.a:pthread.c.obj": { ".flash.text": -12, "flash_total": -12, "ram_st_total": 0 }, - "libnewlib.a:reent_init.c.o": { + "libnewlib.a:reent_init.c.obj": { ".iram0.text": -59, "flash_total": -59, "ram_st_total": -59 @@ -11667,7 +11530,7 @@ Producing JSON output... "flash_total": 70, "ram_st_total": 68 }, - "libnewlib.a:syscall_table.c.o": { + "libnewlib.a:syscall_table.c.obj": { ".dram0.bss": -240, ".dram0.data": -144, ".flash.text": -82, @@ -11681,7 +11544,7 @@ Producing JSON output... "flash_total": 211, "ram_st_total": 384 }, - "libnewlib.a:syscalls.c.o": { + "libnewlib.a:syscalls.c.obj": { ".flash.text": -50, "flash_total": -50, "ram_st_total": 0 @@ -11692,7 +11555,7 @@ Producing JSON output... "flash_total": 139, "ram_st_total": 94 }, - "libnewlib.a:time.c.o": { + "libnewlib.a:time.c.obj": { ".dram0.bss": -32, ".flash.text": -719, ".iram0.text": -123, @@ -11790,7 +11653,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libpthread.a:pthread.c.o": { + "libpthread.a:pthread.c.obj": { ".dram0.bss": -8, ".flash.text": -81, "flash_total": -81, @@ -11805,7 +11668,7 @@ Producing JSON output... "flash_total": 992, "ram_st_total": 190 }, - "libpthread.a:pthread_local_storage.c.o": { + "libpthread.a:pthread_local_storage.c.obj": { ".dram0.bss": -4, ".dram0.data": -8, ".flash.text": -183, @@ -11840,17 +11703,17 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:brownout_hal.c.o": { + "libsoc.a:brownout_hal.c.obj": { ".flash.text": -269, "flash_total": -269, "ram_st_total": 0 }, - "libsoc.a:cpu_hal.c.o": { + "libsoc.a:cpu_hal.c.obj": { ".iram0.text": -8, "flash_total": -8, "ram_st_total": -8 }, - "libsoc.a:cpu_util.c.o": { + "libsoc.a:cpu_util.c.obj": { ".iram0.text": -75, "flash_total": -75, "ram_st_total": -75 @@ -11860,7 +11723,7 @@ Producing JSON output... "flash_total": 310, "ram_st_total": 310 }, - "libsoc.a:gpio_hal.c.o": { + "libsoc.a:gpio_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -11868,18 +11731,18 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:memory_layout_utils.c.o": { + "libsoc.a:memory_layout_utils.c.obj": { ".flash.rodata": -295, ".flash.text": -505, "flash_total": -800, "ram_st_total": 0 }, - "libsoc.a:mpu_hal.c.o": { + "libsoc.a:mpu_hal.c.obj": { ".flash.text": -47, "flash_total": -47, "ram_st_total": 0 }, - "libsoc.a:rtc_clk.c.o": { + "libsoc.a:rtc_clk.c.obj": { ".dram0.bss": -4, ".dram0.data": -160, ".iram0.text": -2104, @@ -11893,7 +11756,7 @@ Producing JSON output... "flash_total": 2454, "ram_st_total": 2462 }, - "libsoc.a:rtc_init.c.o": { + "libsoc.a:rtc_init.c.obj": { ".iram0.text": -956, "flash_total": -956, "ram_st_total": -956 @@ -11903,7 +11766,7 @@ Producing JSON output... "flash_total": 980, "ram_st_total": 980 }, - "libsoc.a:rtc_io_hal.c.o": { + "libsoc.a:rtc_io_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -11916,7 +11779,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:rtc_time.c.o": { + "libsoc.a:rtc_time.c.obj": { ".flash.rodata": -194, ".iram0.text": -819, "flash_total": -1013, @@ -11928,18 +11791,18 @@ Producing JSON output... "flash_total": 940, "ram_st_total": 803 }, - "libsoc.a:rtc_wdt.c.o": { + "libsoc.a:rtc_wdt.c.obj": { ".iram0.text": -796, "flash_total": -796, "ram_st_total": -796 }, - "libsoc.a:soc_hal.c.o": { + "libsoc.a:soc_hal.c.obj": { ".dram0.data": -24, ".iram0.text": -234, "flash_total": -258, "ram_st_total": -258 }, - "libsoc.a:soc_memory_layout.c.o": { + "libsoc.a:soc_memory_layout.c.obj": { ".flash.rodata": -1197, "flash_total": -1197, "ram_st_total": 0 @@ -11949,47 +11812,47 @@ Producing JSON output... "flash_total": 1239, "ram_st_total": 0 }, - "libsoc.a:spi_flash_hal.c.o": { + "libsoc.a:spi_flash_hal.c.obj": { ".flash.rodata": -48, ".flash.text": -302, "flash_total": -350, "ram_st_total": 0 }, - "libsoc.a:spi_flash_hal_iram.c.o": { + "libsoc.a:spi_flash_hal_iram.c.obj": { ".dram0.data": -24, ".iram0.text": -1798, "flash_total": -1822, "ram_st_total": -1822 }, - "libsoc.a:uart_hal.c.o": { + "libsoc.a:uart_hal.c.obj": { ".flash.text": -493, "flash_total": -493, "ram_st_total": 0 }, - "libsoc.a:uart_hal_iram.c.o": { + "libsoc.a:uart_hal_iram.c.obj": { ".flash.rodata": -222, ".flash.text": -147, "flash_total": -369, "ram_st_total": 0 }, - "libsoc_esp32.a:gpio_periph.c.o": { + "libsoc_esp32.a:gpio_periph.c.obj": { ".flash.rodata": -160, "flash_total": -160, "ram_st_total": 0 }, - "libsoc_esp32.a:rtc_io_periph.c.o": { + "libsoc_esp32.a:rtc_io_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32.a:spi_periph.c.o": { + "libsoc_esp32.a:spi_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32.a:uart_periph.c.o": { + "libsoc_esp32.a:uart_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libspi_flash.a:cache_utils.c.o": { + "libspi_flash.a:cache_utils.c.obj": { ".dram0.bss": -14, ".dram0.data": -4, ".flash.rodata": -430, @@ -12007,14 +11870,14 @@ Producing JSON output... "flash_total": 1311, "ram_st_total": 854 }, - "libspi_flash.a:esp_flash_api.c.o": { + "libspi_flash.a:esp_flash_api.c.obj": { ".flash.rodata": -244, ".flash.text": -16, ".iram0.text": -600, "flash_total": -860, "ram_st_total": -600 }, - "libspi_flash.a:esp_flash_spi_init.c.o": { + "libspi_flash.a:esp_flash_spi_init.c.obj": { ".dram0.bss": -4, ".dram0.data": -120, ".flash.rodata": -261, @@ -12022,7 +11885,7 @@ Producing JSON output... "flash_total": -572, "ram_st_total": -124 }, - "libspi_flash.a:flash_mmap.c.o": { + "libspi_flash.a:flash_mmap.c.obj": { ".dram0.bss": -264, ".flash.rodata": -296, ".flash.text": -125, @@ -12038,7 +11901,7 @@ Producing JSON output... "flash_total": 1749, "ram_st_total": 1594 }, - "libspi_flash.a:flash_ops.c.o": { + "libspi_flash.a:flash_ops.c.obj": { ".dram0.bss": -4, ".dram0.data": -20, ".flash.text": -29, @@ -12054,13 +11917,13 @@ Producing JSON output... "flash_total": 2483, "ram_st_total": 2425 }, - "libspi_flash.a:memspi_host_driver.c.o": { + "libspi_flash.a:memspi_host_driver.c.obj": { ".dram0.data": -43, ".iram0.text": -206, "flash_total": -249, "ram_st_total": -249 }, - "libspi_flash.a:partition.c.o": { + "libspi_flash.a:partition.c.obj": { ".dram0.bss": -8, ".flash.rodata": -181, ".flash.text": -668, @@ -12074,43 +11937,43 @@ Producing JSON output... "flash_total": 723, "ram_st_total": 8 }, - "libspi_flash.a:spi_flash_chip_drivers.c.o": { + "libspi_flash.a:spi_flash_chip_drivers.c.obj": { ".dram0.data": -20, "flash_total": -20, "ram_st_total": -20 }, - "libspi_flash.a:spi_flash_chip_gd.c.o": { + "libspi_flash.a:spi_flash_chip_gd.c.obj": { ".dram0.data": -95, ".iram0.text": -181, "flash_total": -276, "ram_st_total": -276 }, - "libspi_flash.a:spi_flash_chip_generic.c.o": { + "libspi_flash.a:spi_flash_chip_generic.c.obj": { ".dram0.data": -340, ".iram0.text": -1423, "flash_total": -1763, "ram_st_total": -1763 }, - "libspi_flash.a:spi_flash_chip_issi.c.o": { + "libspi_flash.a:spi_flash_chip_issi.c.obj": { ".dram0.data": -97, ".iram0.text": -101, "flash_total": -198, "ram_st_total": -198 }, - "libspi_flash.a:spi_flash_os_func_app.c.o": { + "libspi_flash.a:spi_flash_os_func_app.c.obj": { ".dram0.data": -24, ".flash.text": -25, ".iram0.text": -91, "flash_total": -140, "ram_st_total": -115 }, - "libspi_flash.a:spi_flash_os_func_noos.c.o": { + "libspi_flash.a:spi_flash_os_func_noos.c.obj": { ".dram0.data": -16, ".iram0.text": -127, "flash_total": -143, "ram_st_total": -143 }, - "libspi_flash.a:spi_flash_rom_patch.c.o": { + "libspi_flash.a:spi_flash_rom_patch.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -12224,7 +12087,7 @@ Producing JSON output... "flash_total": 2111, "ram_st_total": 13 }, - "libvfs.a:vfs.c.o": { + "libvfs.a:vfs.c.obj": { ".dram0.bss": -40, ".dram0.data": -192, ".flash.rodata": -132, @@ -12240,7 +12103,7 @@ Producing JSON output... "flash_total": 2319, "ram_st_total": 232 }, - "libvfs.a:vfs_uart.c.o": { + "libvfs.a:vfs_uart.c.obj": { ".dram0.bss": -8, ".dram0.data": -116, ".flash.rodata": -783, @@ -12304,7 +12167,7 @@ Producing JSON output... "flash_total": 0, "ram_st_total": 0 }, - "libwpa_supplicant.a:md5-internal.c.o": { + "libwpa_supplicant.a:md5-internal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -12321,12 +12184,12 @@ Producing JSON output... "flash_total": 8, "ram_st_total": 8 }, - "libxtensa.a:debug_helpers.c.o": { + "libxtensa.a:debug_helpers.c.obj": { ".iram0.text": -217, "flash_total": -217, "ram_st_total": -217 }, - "libxtensa.a:debug_helpers_asm.S.o": { + "libxtensa.a:debug_helpers_asm.S.obj": { "flash_total": 0, "ram_st_total": 0 } @@ -12463,7 +12326,6 @@ Producing JSON output... "uart_get_selectlock": 12 }, ".iram0.text": {}, - ".iram0.text_end": {}, ".iram0.vectors": {}, ".noinit": {}, ".rtc.bss": {}, @@ -12571,7 +12433,6 @@ Producing JSON output... "uart_wait_tx_done": -425 }, ".iram0.text": {}, - ".iram0.text_end": {}, ".iram0.vectors": {}, ".noinit": {}, ".rtc.bss": {}, @@ -12601,19 +12462,19 @@ Producing JSON output for esp32s2... "iram_remain": 0, "diram_data": 7152, "diram_bss": 1936, - "diram_text": 32908, + "diram_text": 32905, "diram_vectors": 1027, "diram_rodata": 0, "diram_other": 0, "diram_total": 196608, - "used_diram": 43023, - "used_diram_ratio": 0.2188262939453125, - "diram_remain": 153585, + "used_diram": 43020, + "used_diram_ratio": 0.21881103515625, + "diram_remain": 153588, "flash_code": 74439, "flash_rodata": 18580, "flash_other": 0, "used_flash_non_ram": 93019, - "total_size": 134106 + "total_size": 134103 } { "libc.a": { @@ -12816,7 +12677,7 @@ Producing JSON output for esp32s2... "flash_total": 10633, "ram_st_total": 0 }, - "libfreertos.a:tasks.c.o": { + "libfreertos.a:tasks.c.obj": { ".dram0.bss": 660, ".dram0.data": 12, ".flash.rodata": 406, @@ -12824,20 +12685,20 @@ Producing JSON output for esp32s2... "flash_total": 5372, "ram_st_total": 5626 }, - "libesp_common.a:esp_err_to_name.c.o": { + "libesp_common.a:esp_err_to_name.c.obj": { ".flash.rodata": 5101, ".flash.text": 53, "flash_total": 5154, "ram_st_total": 0 }, - "libesp32s2.a:panic.c.o": { + "libesp32s2.a:panic.c.obj": { ".dram0.bss": 1, ".dram0.data": 2552, ".iram0.text": 2321, "flash_total": 4873, "ram_st_total": 4874 }, - "libvfs.a:vfs_uart.c.o": { + "libvfs.a:vfs_uart.c.obj": { ".dram0.bss": 8, ".dram0.data": 80, ".flash.rodata": 423, @@ -12851,7 +12712,7 @@ Producing JSON output for esp32s2... "flash_total": 3537, "ram_st_total": 0 }, - "libesp32s2.a:intr_alloc.c.o": { + "libesp32s2.a:intr_alloc.c.obj": { ".dram0.bss": 13, ".dram0.data": 8, ".flash.rodata": 706, @@ -12860,13 +12721,13 @@ Producing JSON output for esp32s2... "flash_total": 3056, "ram_st_total": 681 }, - "libfreertos.a:queue.c.o": { + "libfreertos.a:queue.c.obj": { ".flash.rodata": 424, ".iram0.text": 2397, "flash_total": 2821, "ram_st_total": 2397 }, - "libdriver.a:uart.c.o": { + "libdriver.a:uart.c.obj": { ".dram0.bss": 8, ".dram0.data": 40, ".flash.rodata": 452, @@ -12874,7 +12735,7 @@ Producing JSON output for esp32s2... "flash_total": 2579, "ram_st_total": 48 }, - "libheap.a:multi_heap.c.o": { + "libheap.a:multi_heap.c.obj": { ".dram0.data": 300, ".iram0.text": 2273, "flash_total": 2573, @@ -12886,14 +12747,14 @@ Producing JSON output for esp32s2... "flash_total": 2440, "ram_st_total": 0 }, - "libsoc.a:rtc_clk.c.o": { + "libsoc.a:rtc_clk.c.obj": { ".dram0.bss": 8, ".dram0.data": 381, ".iram0.text": 1867, "flash_total": 2248, "ram_st_total": 2256 }, - "libvfs.a:vfs.c.o": { + "libvfs.a:vfs.c.obj": { ".dram0.bss": 40, ".dram0.data": 192, ".flash.rodata": 132, @@ -12901,25 +12762,25 @@ Producing JSON output for esp32s2... "flash_total": 2216, "ram_st_total": 232 }, - "libfreertos.a:portasm.S.o": { + "libfreertos.a:portasm.S.obj": { ".dram0.data": 1544, ".iram0.text": 365, "flash_total": 1909, "ram_st_total": 1909 }, - "libsoc.a:spi_flash_hal_iram.c.o": { + "libsoc.a:spi_flash_hal_iram.c.obj": { ".dram0.data": 24, ".iram0.text": 1804, "flash_total": 1828, "ram_st_total": 1828 }, - "libspi_flash.a:spi_flash_chip_generic.c.o": { + "libspi_flash.a:spi_flash_chip_generic.c.obj": { ".dram0.data": 340, ".iram0.text": 1417, "flash_total": 1757, "ram_st_total": 1757 }, - "libesp32s2.a:task_wdt.c.o": { + "libesp32s2.a:task_wdt.c.obj": { ".dram0.bss": 4, ".dram0.data": 53, ".flash.rodata": 496, @@ -12927,7 +12788,7 @@ Producing JSON output for esp32s2... "flash_total": 1739, "ram_st_total": 57 }, - "libspi_flash.a:flash_mmap.c.o": { + "libspi_flash.a:flash_mmap.c.obj": { ".dram0.bss": 392, ".flash.rodata": 252, ".flash.text": 124, @@ -12935,7 +12796,7 @@ Producing JSON output for esp32s2... "flash_total": 1576, "ram_st_total": 1592 }, - "libheap.a:heap_caps.c.o": { + "libheap.a:heap_caps.c.obj": { ".dram0.data": 4, ".flash.rodata": 362, ".flash.text": 50, @@ -12943,19 +12804,19 @@ Producing JSON output for esp32s2... "flash_total": 1314, "ram_st_total": 902 }, - "libfreertos.a:xtensa_vectors.S.o": { + "libfreertos.a:xtensa_vectors.S.obj": { ".iram0.text": 864, ".iram0.vectors": 425, "flash_total": 1289, "ram_st_total": 1289 }, - "libsoc.a:rtc_init.c.o": { + "libsoc.a:rtc_init.c.obj": { ".flash.rodata": 8, ".iram0.text": 1255, "flash_total": 1263, "ram_st_total": 1255 }, - "libfreertos.a:timers.c.o": { + "libfreertos.a:timers.c.obj": { ".dram0.bss": 56, ".dram0.data": 8, ".flash.rodata": 223, @@ -12963,21 +12824,21 @@ Producing JSON output for esp32s2... "flash_total": 1218, "ram_st_total": 1051 }, - "libheap.a:heap_caps_init.c.o": { + "libheap.a:heap_caps_init.c.obj": { ".dram0.bss": 4, ".flash.rodata": 379, ".flash.text": 838, "flash_total": 1217, "ram_st_total": 4 }, - "libesp32s2.a:cpu_start.c.o": { + "libesp32s2.a:cpu_start.c.obj": { ".flash.rodata": 489, ".flash.text": 152, ".iram0.text": 536, "flash_total": 1177, "ram_st_total": 536 }, - "libesp_timer.a:esp_timer_impl_systimer.c.o": { + "libesp_timer.a:esp_timer_impl_systimer.c.obj": { ".dram0.bss": 8, ".dram0.data": 8, ".flash.rodata": 442, @@ -12986,20 +12847,20 @@ Producing JSON output for esp32s2... "flash_total": 1090, "ram_st_total": 404 }, - "libesp_ringbuf.a:ringbuf.c.o": { + "libesp_ringbuf.a:ringbuf.c.obj": { ".flash.rodata": 150, ".iram0.text": 858, "flash_total": 1008, "ram_st_total": 858 }, - "libdriver.a:periph_ctrl.c.o": { + "libdriver.a:periph_ctrl.c.obj": { ".dram0.data": 8, ".flash.rodata": 272, ".flash.text": 661, "flash_total": 941, "ram_st_total": 8 }, - "libesp32s2.a:clk.c.o": { + "libesp32s2.a:clk.c.obj": { ".flash.rodata": 281, ".flash.text": 626, ".iram0.text": 34, @@ -13011,39 +12872,39 @@ Producing JSON output for esp32s2... "flash_total": 910, "ram_st_total": 0 }, - "libspi_flash.a:partition.c.o": { + "libspi_flash.a:partition.c.obj": { ".dram0.bss": 8, ".flash.rodata": 181, ".flash.text": 679, "flash_total": 860, "ram_st_total": 8 }, - "libspi_flash.a:esp_flash_api.c.o": { + "libspi_flash.a:esp_flash_api.c.obj": { ".flash.rodata": 240, ".flash.text": 16, ".iram0.text": 600, "flash_total": 856, "ram_st_total": 600 }, - "libnewlib.a:time.c.o": { + "libnewlib.a:time.c.obj": { ".dram0.bss": 32, ".flash.text": 719, ".iram0.text": 115, "flash_total": 834, "ram_st_total": 147 }, - "libsoc.a:memory_layout_utils.c.o": { + "libsoc.a:memory_layout_utils.c.obj": { ".flash.rodata": 295, ".flash.text": 509, "flash_total": 804, "ram_st_total": 0 }, - "libsoc.a:rtc_wdt.c.o": { + "libsoc.a:rtc_wdt.c.obj": { ".iram0.text": 800, "flash_total": 800, "ram_st_total": 800 }, - "libesp_timer.a:esp_timer.c.o": { + "libesp_timer.a:esp_timer.c.obj": { ".dram0.bss": 12, ".dram0.data": 8, ".flash.rodata": 104, @@ -13052,7 +12913,7 @@ Producing JSON output for esp32s2... "flash_total": 797, "ram_st_total": 300 }, - "liblog.a:log.c.o": { + "liblog.a:log.c.obj": { ".dram0.bss": 264, ".dram0.data": 8, ".flash.rodata": 147, @@ -13061,12 +12922,12 @@ Producing JSON output for esp32s2... "flash_total": 655, "ram_st_total": 678 }, - "libsoc.a:rtc_time.c.o": { + "libsoc.a:rtc_time.c.obj": { ".iram0.text": 626, "flash_total": 626, "ram_st_total": 626 }, - "libspi_flash.a:esp_flash_spi_init.c.o": { + "libspi_flash.a:esp_flash_spi_init.c.obj": { ".dram0.bss": 4, ".dram0.data": 120, ".flash.rodata": 281, @@ -13074,7 +12935,7 @@ Producing JSON output for esp32s2... "flash_total": 616, "ram_st_total": 124 }, - "libnewlib.a:locks.c.o": { + "libnewlib.a:locks.c.obj": { ".dram0.data": 8, ".flash.rodata": 84, ".flash.text": 5, @@ -13082,20 +12943,20 @@ Producing JSON output for esp32s2... "flash_total": 584, "ram_st_total": 495 }, - "libfreertos.a:xtensa_intr_asm.S.o": { + "libfreertos.a:xtensa_intr_asm.S.obj": { ".dram0.data": 512, ".iram0.text": 51, "flash_total": 563, "ram_st_total": 563 }, - "libfreertos.a:port.c.o": { + "libfreertos.a:port.c.obj": { ".dram0.bss": 16, ".flash.rodata": 87, ".iram0.text": 408, "flash_total": 495, "ram_st_total": 424 }, - "libesp32s2.a:crosscore_int.c.o": { + "libesp32s2.a:crosscore_int.c.obj": { ".dram0.bss": 4, ".dram0.data": 8, ".flash.rodata": 237, @@ -13104,28 +12965,28 @@ Producing JSON output for esp32s2... "flash_total": 485, "ram_st_total": 166 }, - "libsoc.a:soc_memory_layout.c.o": { + "libsoc.a:soc_memory_layout.c.obj": { ".flash.rodata": 479, "flash_total": 479, "ram_st_total": 0 }, - "libsoc.a:rtc_sleep.c.o": { + "libsoc.a:rtc_sleep.c.obj": { ".iram0.text": 414, "flash_total": 414, "ram_st_total": 414 }, - "libsoc.a:uart_hal.c.o": { + "libsoc.a:uart_hal.c.obj": { ".flash.text": 409, "flash_total": 409, "ram_st_total": 0 }, - "libsoc.a:spi_flash_hal.c.o": { + "libsoc.a:spi_flash_hal.c.obj": { ".flash.rodata": 96, ".flash.text": 309, "flash_total": 405, "ram_st_total": 0 }, - "libspi_flash.a:cache_utils.c.o": { + "libspi_flash.a:cache_utils.c.obj": { ".dram0.bss": 8, ".flash.rodata": 176, ".flash.text": 21, @@ -13133,7 +12994,7 @@ Producing JSON output for esp32s2... "flash_total": 394, "ram_st_total": 205 }, - "libmain.a:hello_world_main.c.o": { + "libmain.a:hello_world_main.c.obj": { ".flash.rodata": 196, ".flash.text": 192, "flash_total": 388, @@ -13145,7 +13006,7 @@ Producing JSON output for esp32s2... "flash_total": 374, "ram_st_total": 364 }, - "libdriver.a:timer.c.o": { + "libdriver.a:timer.c.obj": { ".dram0.bss": 16, ".dram0.data": 16, ".flash.rodata": 170, @@ -13158,26 +13019,26 @@ Producing JSON output for esp32s2... "flash_total": 368, "ram_st_total": 0 }, - "libapp_update.a:esp_ota_ops.c.o": { + "libapp_update.a:esp_ota_ops.c.obj": { ".dram0.bss": 4, ".flash.rodata": 214, ".flash.text": 151, "flash_total": 365, "ram_st_total": 4 }, - "libesp32s2.a:int_wdt.c.o": { + "libesp32s2.a:int_wdt.c.obj": { ".flash.text": 302, ".iram0.text": 59, "flash_total": 361, "ram_st_total": 59 }, - "libesp32s2.a:system_api_esp32s2.c.o": { + "libesp32s2.a:system_api_esp32s2.c.obj": { ".flash.text": 27, ".iram0.text": 323, "flash_total": 350, "ram_st_total": 323 }, - "libesp_common.a:brownout.c.o": { + "libesp_common.a:brownout.c.obj": { ".flash.rodata": 203, ".flash.text": 120, "flash_total": 323, @@ -13188,17 +13049,17 @@ Producing JSON output for esp32s2... "flash_total": 315, "ram_st_total": 315 }, - "libsoc.a:cpu_util.c.o": { + "libsoc.a:cpu_util.c.obj": { ".iram0.text": 309, "flash_total": 309, "ram_st_total": 309 }, - "libsoc.a:brownout_hal.c.o": { + "libsoc.a:brownout_hal.c.obj": { ".flash.text": 304, "flash_total": 304, "ram_st_total": 0 }, - "libesp_common.a:freertos_hooks.c.o": { + "libesp_common.a:freertos_hooks.c.obj": { ".dram0.bss": 64, ".dram0.data": 8, ".flash.text": 243, @@ -13206,24 +13067,24 @@ Producing JSON output for esp32s2... "flash_total": 298, "ram_st_total": 119 }, - "libspi_flash.a:spi_flash_chip_gd.c.o": { + "libspi_flash.a:spi_flash_chip_gd.c.obj": { ".dram0.data": 95, ".iram0.text": 181, "flash_total": 276, "ram_st_total": 276 }, - "libapp_update.a:esp_app_desc.c.o": { + "libapp_update.a:esp_app_desc.c.obj": { ".flash.rodata": 256, "flash_total": 256, "ram_st_total": 0 }, - "libspi_flash.a:memspi_host_driver.c.o": { + "libspi_flash.a:memspi_host_driver.c.obj": { ".dram0.data": 43, ".iram0.text": 206, "flash_total": 249, "ram_st_total": 249 }, - "libdriver.a:rtc_module.c.o": { + "libdriver.a:rtc_module.c.obj": { ".dram0.bss": 8, ".dram0.data": 16, ".flash.text": 231, @@ -13251,56 +13112,56 @@ Producing JSON output for esp32s2... "flash_total": 217, "ram_st_total": 0 }, - "libnewlib.a:syscall_table.c.o": { + "libnewlib.a:syscall_table.c.obj": { ".dram0.bss": 240, ".dram0.data": 144, ".flash.text": 70, "flash_total": 214, "ram_st_total": 384 }, - "libfreertos.a:xtensa_context.S.o": { + "libfreertos.a:xtensa_context.S.obj": { ".iram0.text": 201, "flash_total": 201, "ram_st_total": 201 }, - "libspi_flash.a:spi_flash_chip_issi.c.o": { + "libspi_flash.a:spi_flash_chip_issi.c.obj": { ".dram0.data": 97, ".iram0.text": 101, "flash_total": 198, "ram_st_total": 198 }, - "libpthread.a:pthread_local_storage.c.o": { + "libpthread.a:pthread_local_storage.c.obj": { ".dram0.bss": 4, ".dram0.data": 8, ".flash.text": 183, "flash_total": 191, "ram_st_total": 12 }, - "liblog.a:log_freertos.c.o": { + "liblog.a:log_freertos.c.obj": { ".dram0.bss": 8, ".iram0.text": 188, "flash_total": 188, "ram_st_total": 196 }, - "libnewlib.a:heap.c.o": { + "libnewlib.a:heap.c.obj": { ".iram0.text": 151, "flash_total": 151, "ram_st_total": 151 }, - "libfreertos.a:xtensa_intr.c.o": { + "libfreertos.a:xtensa_intr.c.obj": { ".flash.rodata": 35, ".iram0.text": 112, "flash_total": 147, "ram_st_total": 112 }, - "libspi_flash.a:spi_flash_os_func_app.c.o": { + "libspi_flash.a:spi_flash_os_func_app.c.obj": { ".dram0.data": 24, ".flash.text": 25, ".iram0.text": 95, "flash_total": 144, "ram_st_total": 119 }, - "libfreertos.a:list.c.o": { + "libfreertos.a:list.c.obj": { ".iram0.text": 138, "flash_total": 138, "ram_st_total": 138 @@ -13310,7 +13171,7 @@ Producing JSON output for esp32s2... "flash_total": 128, "ram_st_total": 0 }, - "libesp32s2.a:dport_panic_highint_hdl.S.o": { + "libesp32s2.a:dport_panic_highint_hdl.S.obj": { ".iram0.text": 123, "flash_total": 123, "ram_st_total": 123 @@ -13320,7 +13181,7 @@ Producing JSON output for esp32s2... "flash_total": 116, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_os_func_noos.c.o": { + "libspi_flash.a:spi_flash_os_func_noos.c.obj": { ".dram0.data": 16, ".iram0.text": 89, "flash_total": 105, @@ -13331,7 +13192,7 @@ Producing JSON output for esp32s2... "flash_total": 100, "ram_st_total": 0 }, - "libesp32s2.a:cache_err_int.c.o": { + "libesp32s2.a:cache_err_int.c.obj": { ".flash.text": 96, "flash_total": 96, "ram_st_total": 0 @@ -13341,13 +13202,13 @@ Producing JSON output for esp32s2... "flash_total": 94, "ram_st_total": 0 }, - "libpthread.a:pthread.c.o": { + "libpthread.a:pthread.c.obj": { ".dram0.bss": 8, ".flash.text": 81, "flash_total": 81, "ram_st_total": 8 }, - "libspi_flash.a:flash_ops.c.o": { + "libspi_flash.a:flash_ops.c.obj": { ".dram0.bss": 4, ".dram0.data": 20, ".flash.text": 29, @@ -13360,22 +13221,22 @@ Producing JSON output for esp32s2... "flash_total": 63, "ram_st_total": 0 }, - "libnewlib.a:reent_init.c.o": { + "libnewlib.a:reent_init.c.obj": { ".iram0.text": 59, "flash_total": 59, "ram_st_total": 59 }, - "libdriver.a:rtc_io.c.o": { + "libdriver.a:rtc_io.c.obj": { ".flash.text": 53, "flash_total": 53, "ram_st_total": 0 }, - "libnewlib.a:syscalls.c.o": { + "libnewlib.a:syscalls.c.obj": { ".flash.text": 50, "flash_total": 50, "ram_st_total": 0 }, - "libfreertos.a:xtensa_vector_defaults.S.o": { + "libfreertos.a:xtensa_vector_defaults.S.obj": { ".iram0.text": 46, "flash_total": 46, "ram_st_total": 46 @@ -13385,12 +13246,12 @@ Producing JSON output for esp32s2... "flash_total": 45, "ram_st_total": 0 }, - "libsoc.a:uart_hal_iram.c.o": { + "libsoc.a:uart_hal_iram.c.obj": { ".flash.text": 43, "flash_total": 43, "ram_st_total": 0 }, - "libesp_common.a:system_api.c.o": { + "libesp_common.a:system_api.c.obj": { ".dram0.bss": 8, ".iram0.text": 40, "flash_total": 40, @@ -13416,7 +13277,7 @@ Producing JSON output for esp32s2... "flash_total": 40, "ram_st_total": 0 }, - "libfreertos.a:xtensa_init.c.o": { + "libfreertos.a:xtensa_init.c.obj": { ".dram0.bss": 4, ".iram0.text": 32, "flash_total": 32, @@ -13427,12 +13288,12 @@ Producing JSON output for esp32s2... "flash_total": 32, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_drivers.c.o": { + "libspi_flash.a:spi_flash_chip_drivers.c.obj": { ".dram0.data": 20, "flash_total": 20, "ram_st_total": 20 }, - "libnewlib.a:pthread.c.o": { + "libnewlib.a:pthread.c.obj": { ".flash.text": 12, "flash_total": 12, "ram_st_total": 0 @@ -13447,7 +13308,7 @@ Producing JSON output for esp32s2... "flash_total": 8, "ram_st_total": 0 }, - "libesp32s2.a:pm_esp32s2.c.o": { + "libesp32s2.a:pm_esp32s2.c.obj": { ".flash.text": 8, "flash_total": 8, "ram_st_total": 0 @@ -13473,12 +13334,12 @@ Producing JSON output for esp32s2... "flash_total": 6, "ram_st_total": 3 }, - "libcxx.a:cxx_exception_stubs.cpp.o": { + "libcxx.a:cxx_exception_stubs.cpp.obj": { ".flash.text": 6, "flash_total": 6, "ram_st_total": 0 }, - "libcxx.a:cxx_guards.cpp.o": { + "libcxx.a:cxx_guards.cpp.obj": { ".flash.text": 5, "flash_total": 5, "ram_st_total": 0 @@ -13488,7 +13349,7 @@ Producing JSON output for esp32s2... "flash_total": 4, "ram_st_total": 0 }, - "libfreertos.a:FreeRTOS-openocd.c.o": { + "libfreertos.a:FreeRTOS-openocd.c.obj": { ".dram0.data": 4, "flash_total": 4, "ram_st_total": 4 @@ -13501,39 +13362,39 @@ Producing JSON output for esp32s2... "flash_total": 0, "ram_st_total": 0 }, - "(exe):project_elf_src.c.o": { + "(exe):project_elf_src.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_common.c.o": { + "libbootloader_support.a:bootloader_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_efuse_esp32s2.c.o": { + "libbootloader_support.a:bootloader_efuse_esp32s2.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash.c.o": { + "libbootloader_support.a:bootloader_flash.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_random.c.o": { + "libbootloader_support.a:bootloader_random.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_sha.c.o": { + "libbootloader_support.a:bootloader_sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_utility.c.o": { + "libbootloader_support.a:bootloader_utility.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:esp_image_format.c.o": { + "libbootloader_support.a:esp_image_format.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:flash_partitions.c.o": { + "libbootloader_support.a:flash_partitions.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -13786,19 +13647,19 @@ Producing JSON output for esp32s2... "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:gpio.c.o": { + "libdriver.a:gpio.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:spi_common.c.o": { + "libdriver.a:spi_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp32s2.a:hw_random.c.o": { + "libesp32s2.a:hw_random.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_common.a:pm_locks.c.o": { + "libesp_common.a:pm_locks.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -13830,59 +13691,59 @@ Producing JSON output for esp32s2... "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:esp_mem.c.o": { + "libmbedcrypto.a:esp_mem.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:platform.c.o": { + "libmbedcrypto.a:platform.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:platform_util.c.o": { + "libmbedcrypto.a:platform_util.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:sha256.c.o": { + "libmbedcrypto.a:sha256.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:gpio_hal.c.o": { + "libsoc.a:gpio_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:rtc_io_hal.c.o": { + "libsoc.a:rtc_io_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:spi_flash_hal_gpspi.c.o": { + "libsoc.a:spi_flash_hal_gpspi.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:timer_hal.c.o": { + "libsoc.a:timer_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32s2.a:gpio_periph.c.o": { + "libsoc_esp32s2.a:gpio_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32s2.a:rtc_io_periph.c.o": { + "libsoc_esp32s2.a:rtc_io_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32s2.a:spi_periph.c.o": { + "libsoc_esp32s2.a:spi_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc_esp32s2.a:uart_periph.c.o": { + "libsoc_esp32s2.a:uart_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libwpa_supplicant.a:md5-internal.c.o": { + "libwpa_supplicant.a:md5-internal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libxtensa.a:stdatomic.c.o": { + "libxtensa.a:stdatomic.c.obj": { "flash_total": 0, "ram_st_total": 0 } @@ -13959,7 +13820,6 @@ Producing JSON output for esp32s2... "uart_get_selectlock": 12 }, ".iram0.text": {}, - ".iram0.text_end": {}, ".iram0.vectors": {}, ".noinit": {}, ".rtc.bss": {}, @@ -13988,19 +13848,19 @@ Producing JSON output for esp32c3... "iram_remain": 0, "diram_data": 5048, "diram_bss": 3664, - "diram_text": 39936, + "diram_text": 39754, "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, "diram_total": 327680, - "used_diram": 48648, - "used_diram_ratio": 0.1484619140625, - "diram_remain": 279032, + "used_diram": 48466, + "used_diram_ratio": 0.147906494140625, + "diram_remain": 279214, "flash_code": 90400, "flash_rodata": 26352, - "flash_other": 131328, - "used_flash_non_ram": 248080, - "total_size": 293064 + "flash_other": 256, + "used_flash_non_ram": 117008, + "total_size": 161810 } { "ilp32\\libc.a": { @@ -14210,14 +14070,14 @@ Producing JSON output for esp32c3... "flash_total": 10493, "ram_st_total": 0 }, - "libesp_common.a:esp_err_to_name.c.o": { + "libesp_common.a:esp_err_to_name.c.obj": { ".dram0.data": 6, ".flash.rodata": 7065, ".flash.text": 56, "flash_total": 7127, "ram_st_total": 6 }, - "libfreertos.a:tasks.c.o": { + "libfreertos.a:tasks.c.obj": { ".dram0.bss": 664, ".dram0.data": 8, ".flash.rodata": 1080, @@ -14225,7 +14085,7 @@ Producing JSON output for esp32c3... "flash_total": 6640, "ram_st_total": 6224 }, - "libheap.a:heap_tlsf.c.o": { + "libheap.a:heap_tlsf.c.obj": { ".dram0.data": 1796, ".iram0.text": 4036, "flash_total": 5832, @@ -14237,7 +14097,7 @@ Producing JSON output for esp32c3... "flash_total": 5545, "ram_st_total": 0 }, - "libvfs.a:vfs_uart.c.o": { + "libvfs.a:vfs_uart.c.obj": { ".dram0.bss": 8, ".dram0.data": 80, ".flash.rodata": 270, @@ -14245,7 +14105,7 @@ Producing JSON output for esp32c3... "flash_total": 4752, "ram_st_total": 88 }, - "libfreertos.a:queue.c.o": { + "libfreertos.a:queue.c.obj": { ".flash.rodata": 1495, ".iram0.text": 3192, "flash_total": 4687, @@ -14257,20 +14117,20 @@ Producing JSON output for esp32c3... "flash_total": 4658, "ram_st_total": 0 }, - "libesp_hw_support.a:memprot.c.o": { + "libesp_hw_support.a:memprot.c.obj": { ".flash.rodata": 800, ".flash.text": 2762, ".iram0.text": 772, "flash_total": 4334, "ram_st_total": 772 }, - "libspi_flash.a:spi_flash_chip_generic.c.o": { + "libspi_flash.a:spi_flash_chip_generic.c.obj": { ".dram0.data": 554, ".iram0.text": 2684, "flash_total": 3238, "ram_st_total": 3238 }, - "libdriver.a:uart.c.o": { + "libdriver.a:uart.c.obj": { ".dram0.bss": 8, ".dram0.data": 40, ".flash.rodata": 511, @@ -14278,7 +14138,7 @@ Producing JSON output for esp32c3... "flash_total": 3139, "ram_st_total": 48 }, - "libesp_hw_support.a:intr_alloc.c.o": { + "libesp_hw_support.a:intr_alloc.c.obj": { ".dram0.bss": 13, ".flash.rodata": 198, ".flash.text": 2128, @@ -14286,13 +14146,13 @@ Producing JSON output for esp32c3... "flash_total": 3014, "ram_st_total": 701 }, - "libesp_system.a:panic_arch.c.o": { + "libesp_system.a:panic_arch.c.obj": { ".flash.rodata": 1693, ".flash.text": 1060, "flash_total": 2753, "ram_st_total": 0 }, - "libvfs.a:vfs.c.o": { + "libvfs.a:vfs.c.obj": { ".dram0.bss": 40, ".dram0.data": 192, ".flash.rodata": 108, @@ -14300,24 +14160,24 @@ Producing JSON output for esp32c3... "flash_total": 2660, "ram_st_total": 232 }, - "libesp_hw_support.a:rtc_init.c.o": { + "libesp_hw_support.a:rtc_init.c.obj": { ".flash.rodata": 500, ".flash.text": 2068, "flash_total": 2568, "ram_st_total": 0 }, - "libdriver.a:gpio.c.o": { + "libdriver.a:gpio.c.obj": { ".flash.rodata": 459, ".flash.text": 1856, "flash_total": 2315, "ram_st_total": 0 }, - "libhal.a:spi_flash_hal_iram.c.o": { + "libhal.a:spi_flash_hal_iram.c.obj": { ".iram0.text": 2220, "flash_total": 2220, "ram_st_total": 2220 }, - "libesp_system.a:task_wdt.c.o": { + "libesp_system.a:task_wdt.c.obj": { ".dram0.bss": 12, ".dram0.data": 45, ".flash.rodata": 478, @@ -14325,7 +14185,7 @@ Producing JSON output for esp32c3... "flash_total": 1961, "ram_st_total": 57 }, - "libspi_flash.a:flash_mmap.c.o": { + "libspi_flash.a:flash_mmap.c.obj": { ".dram0.bss": 136, ".flash.rodata": 240, ".flash.text": 182, @@ -14333,14 +14193,14 @@ Producing JSON output for esp32c3... "flash_total": 1952, "ram_st_total": 1666 }, - "libesp_hw_support.a:rtc_clk.c.o": { + "libesp_hw_support.a:rtc_clk.c.obj": { ".dram0.bss": 4, ".dram0.data": 171, ".iram0.text": 1738, "flash_total": 1909, "ram_st_total": 1913 }, - "libspi_flash.a:esp_flash_api.c.o": { + "libspi_flash.a:esp_flash_api.c.obj": { ".dram0.data": 20, ".flash.rodata": 762, ".flash.text": 82, @@ -14348,7 +14208,7 @@ Producing JSON output for esp32c3... "flash_total": 1832, "ram_st_total": 988 }, - "libheap.a:heap_caps.c.o": { + "libheap.a:heap_caps.c.obj": { ".dram0.bss": 4, ".dram0.data": 4, ".flash.rodata": 355, @@ -14357,25 +14217,25 @@ Producing JSON output for esp32c3... "flash_total": 1767, "ram_st_total": 1130 }, - "libesp_ringbuf.a:ringbuf.c.o": { + "libesp_ringbuf.a:ringbuf.c.obj": { ".flash.rodata": 512, ".iram0.text": 1004, "flash_total": 1516, "ram_st_total": 1004 }, - "libhal.a:spi_flash_hal_gpspi.c.o": { + "libhal.a:spi_flash_hal_gpspi.c.obj": { ".iram0.text": 1484, "flash_total": 1484, "ram_st_total": 1484 }, - "libefuse.a:esp_efuse_utility.c.o": { + "libefuse.a:esp_efuse_utility.c.obj": { ".dram0.bss": 4, ".flash.rodata": 475, ".flash.text": 998, "flash_total": 1473, "ram_st_total": 4 }, - "libnewlib.a:locks.c.o": { + "libnewlib.a:locks.c.obj": { ".dram0.bss": 168, ".flash.rodata": 344, ".flash.text": 152, @@ -14383,14 +14243,14 @@ Producing JSON output for esp32c3... "flash_total": 1420, "ram_st_total": 1092 }, - "libheap.a:heap_caps_init.c.o": { + "libheap.a:heap_caps_init.c.obj": { ".dram0.bss": 4, ".flash.rodata": 338, ".flash.text": 1052, "flash_total": 1390, "ram_st_total": 4 }, - "libesp_system.a:startup.c.o": { + "libesp_system.a:startup.c.obj": { ".dram0.bss": 8, ".dram0.data": 12, ".flash.rodata": 497, @@ -14399,7 +14259,7 @@ Producing JSON output for esp32c3... "flash_total": 1387, "ram_st_total": 64 }, - "libspi_flash.a:partition.c.o": { + "libspi_flash.a:partition.c.obj": { ".dram0.bss": 8, ".flash.rodata": 268, ".flash.text": 1070, @@ -14411,7 +14271,7 @@ Producing JSON output for esp32c3... "flash_total": 1264, "ram_st_total": 0 }, - "libhal.a:wdt_hal_iram.c.o": { + "libhal.a:wdt_hal_iram.c.obj": { ".iram0.text": 1160, "flash_total": 1160, "ram_st_total": 1160 @@ -14427,7 +14287,7 @@ Producing JSON output for esp32c3... "flash_total": 1136, "ram_st_total": 0 }, - "libesp_system.a:panic.c.o": { + "libesp_system.a:panic.c.obj": { ".dram0.bss": 5, ".dram0.data": 12, ".flash.rodata": 131, @@ -14436,38 +14296,38 @@ Producing JSON output for esp32c3... "flash_total": 1107, "ram_st_total": 23 }, - "libesp_system.a:clk.c.o": { + "libesp_system.a:clk.c.obj": { ".flash.rodata": 212, ".flash.text": 838, "flash_total": 1050, "ram_st_total": 0 }, - "libspi_flash.a:memspi_host_driver.c.o": { + "libspi_flash.a:memspi_host_driver.c.obj": { ".dram0.data": 397, ".iram0.text": 636, "flash_total": 1033, "ram_st_total": 1033 }, - "libspi_flash.a:spi_flash_chip_winbond.c.o": { + "libspi_flash.a:spi_flash_chip_winbond.c.obj": { ".dram0.data": 203, ".iram0.text": 748, "flash_total": 951, "ram_st_total": 951 }, - "libheap.a:memory_layout_utils.c.o": { + "libheap.a:memory_layout_utils.c.obj": { ".flash.rodata": 283, ".flash.text": 650, "flash_total": 933, "ram_st_total": 0 }, - "libdriver.a:periph_ctrl.c.o": { + "libdriver.a:periph_ctrl.c.obj": { ".dram0.bss": 27, ".flash.rodata": 85, ".flash.text": 836, "flash_total": 921, "ram_st_total": 27 }, - "libesp_timer.a:esp_timer.c.o": { + "libesp_timer.a:esp_timer.c.obj": { ".dram0.bss": 8, ".flash.rodata": 72, ".flash.text": 514, @@ -14485,7 +14345,7 @@ Producing JSON output for esp32c3... "flash_total": 848, "ram_st_total": 0 }, - "libfreertos.a:port.c.o": { + "libfreertos.a:port.c.obj": { ".dram0.bss": 1556, ".dram0.data": 4, ".flash.rodata": 190, @@ -14494,26 +14354,26 @@ Producing JSON output for esp32c3... "flash_total": 848, "ram_st_total": 2148 }, - "libhal.a:systimer_hal.c.o": { + "libhal.a:systimer_hal.c.obj": { ".dram0.data": 85, ".iram0.text": 760, "flash_total": 845, "ram_st_total": 845 }, - "libheap.a:multi_heap.c.o": { + "libheap.a:multi_heap.c.obj": { ".dram0.data": 157, ".iram0.text": 678, "flash_total": 835, "ram_st_total": 835 }, - "libnewlib.a:time.c.o": { + "libnewlib.a:time.c.obj": { ".dram0.bss": 20, ".flash.text": 620, ".iram0.text": 180, "flash_total": 800, "ram_st_total": 200 }, - "liblog.a:log.c.o": { + "liblog.a:log.c.obj": { ".dram0.bss": 264, ".dram0.data": 8, ".flash.rodata": 122, @@ -14522,14 +14382,14 @@ Producing JSON output for esp32c3... "flash_total": 724, "ram_st_total": 304 }, - "libesp_system.a:cpu_start.c.o": { + "libesp_system.a:cpu_start.c.obj": { ".flash.rodata": 158, ".flash.text": 42, ".iram0.text": 464, "flash_total": 664, "ram_st_total": 464 }, - "libesp_timer.a:esp_timer_impl_systimer.c.o": { + "libesp_timer.a:esp_timer_impl_systimer.c.obj": { ".dram0.bss": 12, ".dram0.data": 16, ".flash.rodata": 125, @@ -14538,7 +14398,7 @@ Producing JSON output for esp32c3... "flash_total": 647, "ram_st_total": 238 }, - "libspi_flash.a:esp_flash_spi_init.c.o": { + "libspi_flash.a:esp_flash_spi_init.c.obj": { ".dram0.bss": 4, ".dram0.data": 68, ".flash.rodata": 261, @@ -14546,7 +14406,7 @@ Producing JSON output for esp32c3... "flash_total": 601, "ram_st_total": 72 }, - "libspi_flash.a:spi_flash_os_func_app.c.o": { + "libspi_flash.a:spi_flash_os_func_app.c.obj": { ".dram0.data": 52, ".flash.rodata": 95, ".flash.text": 34, @@ -14554,19 +14414,19 @@ Producing JSON output for esp32c3... "flash_total": 595, "ram_st_total": 466 }, - "libesp_hw_support.a:rtc_time.c.o": { + "libesp_hw_support.a:rtc_time.c.obj": { ".iram0.text": 590, "flash_total": 590, "ram_st_total": 590 }, - "libfreertos.a:port_systick.c.o": { + "libfreertos.a:port_systick.c.obj": { ".dram0.bss": 8, ".flash.rodata": 192, ".iram0.text": 370, "flash_total": 562, "ram_st_total": 378 }, - "libriscv.a:vectors.S.o": { + "libriscv.a:vectors.S.obj": { ".iram0.text": 522, "flash_total": 522, "ram_st_total": 522 @@ -14581,7 +14441,7 @@ Producing JSON output for esp32c3... "flash_total": 500, "ram_st_total": 0 }, - "libapp_update.a:esp_app_desc.c.o": { + "libapp_update.a:esp_app_desc.c.obj": { ".dram0.bss": 8, ".dram0.data": 1, ".flash.appdesc": 256, @@ -14596,7 +14456,7 @@ Producing JSON output for esp32c3... "flash_total": 488, "ram_st_total": 0 }, - "libmain.a:hello_world_main.c.o": { + "libmain.a:hello_world_main.c.obj": { ".flash.rodata": 232, ".flash.text": 248, "flash_total": 480, @@ -14607,7 +14467,7 @@ Producing JSON output for esp32c3... "flash_total": 456, "ram_st_total": 0 }, - "libhal.a:spi_flash_hal.c.o": { + "libhal.a:spi_flash_hal.c.obj": { ".flash.rodata": 96, ".flash.text": 342, "flash_total": 438, @@ -14618,7 +14478,7 @@ Producing JSON output for esp32c3... "flash_total": 436, "ram_st_total": 0 }, - "libfreertos.a:port_common.c.o": { + "libfreertos.a:port_common.c.obj": { ".flash.rodata": 186, ".flash.text": 128, ".iram0.text": 104, @@ -14630,13 +14490,13 @@ Producing JSON output for esp32c3... "flash_total": 416, "ram_st_total": 0 }, - "libesp_hw_support.a:sleep_modes.c.o": { + "libesp_hw_support.a:sleep_modes.c.obj": { ".flash.rodata": 171, ".flash.text": 244, "flash_total": 415, "ram_st_total": 0 }, - "libesp_system.a:crosscore_int.c.o": { + "libesp_system.a:crosscore_int.c.obj": { ".dram0.bss": 4, ".flash.rodata": 120, ".flash.text": 106, @@ -14661,12 +14521,12 @@ Producing JSON output for esp32c3... "flash_total": 372, "ram_st_total": 0 }, - "libhal.a:uart_hal.c.o": { + "libhal.a:uart_hal.c.obj": { ".flash.text": 366, "flash_total": 366, "ram_st_total": 0 }, - "libesp_system.a:panic_handler.c.o": { + "libesp_system.a:panic_handler.c.obj": { ".dram0.bss": 4, ".dram0.data": 8, ".flash.rodata": 8, @@ -14675,7 +14535,7 @@ Producing JSON output for esp32c3... "flash_total": 364, "ram_st_total": 94 }, - "libnewlib.a:esp_time_impl.c.o": { + "libnewlib.a:esp_time_impl.c.obj": { ".dram0.bss": 12, ".flash.text": 362, "flash_total": 362, @@ -14686,12 +14546,12 @@ Producing JSON output for esp32c3... "flash_total": 340, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash.c.o": { + "libbootloader_support.a:bootloader_flash.c.obj": { ".iram0.text": 340, "flash_total": 340, "ram_st_total": 340 }, - "libesp_system.a:freertos_hooks.c.o": { + "libesp_system.a:freertos_hooks.c.obj": { ".dram0.bss": 64, ".flash.text": 290, ".iram0.text": 48, @@ -14703,56 +14563,56 @@ Producing JSON output for esp32c3... "flash_total": 316, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_gd.c.o": { + "libspi_flash.a:spi_flash_chip_gd.c.obj": { ".dram0.data": 123, ".iram0.text": 190, "flash_total": 313, "ram_st_total": 313 }, - "libesp_hw_support.a:rtc_sleep.c.o": { + "libesp_hw_support.a:rtc_sleep.c.obj": { ".iram0.text": 308, "flash_total": 308, "ram_st_total": 308 }, - "libapp_update.a:esp_ota_ops.c.o": { + "libapp_update.a:esp_ota_ops.c.obj": { ".dram0.bss": 4, ".flash.rodata": 121, ".flash.text": 186, "flash_total": 307, "ram_st_total": 4 }, - "libesp_system.a:system_internal.c.o": { + "libesp_system.a:system_internal.c.obj": { ".iram0.text": 298, "flash_total": 298, "ram_st_total": 298 }, - "libesp_system.a:int_wdt.c.o": { + "libesp_system.a:int_wdt.c.obj": { ".dram0.bss": 8, ".flash.text": 206, ".iram0.text": 74, "flash_total": 280, "ram_st_total": 82 }, - "libriscv.a:interrupt.c.o": { + "libriscv.a:interrupt.c.obj": { ".dram0.bss": 256, ".flash.rodata": 137, ".iram0.text": 130, "flash_total": 267, "ram_st_total": 386 }, - "libspi_flash.a:spi_flash_chip_mxic.c.o": { + "libspi_flash.a:spi_flash_chip_mxic.c.obj": { ".dram0.data": 190, ".iram0.text": 76, "flash_total": 266, "ram_st_total": 266 }, - "libesp_system.a:esp_err.c.o": { + "libesp_system.a:esp_err.c.obj": { ".dram0.data": 108, ".iram0.text": 154, "flash_total": 262, "ram_st_total": 262 }, - "libesp_timer.a:system_time.c.o": { + "libesp_timer.a:system_time.c.obj": { ".dram0.bss": 8, ".flash.rodata": 80, ".flash.text": 142, @@ -14765,12 +14625,12 @@ Producing JSON output for esp32c3... "flash_total": 257, "ram_st_total": 0 }, - "libesp_hw_support.a:cpu_util_esp32c3.c.o": { + "libesp_hw_support.a:cpu_util_esp32c3.c.obj": { ".flash.text": 250, "flash_total": 250, "ram_st_total": 0 }, - "libesp_hw_support.a:esp_clk.c.o": { + "libesp_hw_support.a:esp_clk.c.obj": { ".dram0.bss": 4, ".flash.text": 200, ".iram0.text": 30, @@ -14778,31 +14638,31 @@ Producing JSON output for esp32c3... "flash_total": 246, "ram_st_total": 50 }, - "libpthread.a:pthread_local_storage.c.o": { + "libpthread.a:pthread_local_storage.c.obj": { ".dram0.bss": 4, ".flash.text": 242, "flash_total": 242, "ram_st_total": 4 }, - "libspi_flash.a:spi_flash_chip_issi.c.o": { + "libspi_flash.a:spi_flash_chip_issi.c.obj": { ".dram0.data": 125, ".iram0.text": 112, "flash_total": 237, "ram_st_total": 237 }, - "libheap.a:memory_layout.c.o": { + "libheap.a:memory_layout.c.obj": { ".dram0.data": 4, ".flash.rodata": 231, "flash_total": 235, "ram_st_total": 4 }, - "liblog.a:log_freertos.c.o": { + "liblog.a:log_freertos.c.obj": { ".dram0.bss": 8, ".iram0.text": 232, "flash_total": 232, "ram_st_total": 240 }, - "libnewlib.a:newlib_init.c.o": { + "libnewlib.a:newlib_init.c.obj": { ".dram0.bss": 240, ".dram0.data": 156, ".flash.text": 76, @@ -14814,12 +14674,12 @@ Producing JSON output for esp32c3... "flash_total": 224, "ram_st_total": 0 }, - "libesp_hw_support.a:regi2c_ctrl.c.o": { + "libesp_hw_support.a:regi2c_ctrl.c.obj": { ".iram0.text": 202, "flash_total": 202, "ram_st_total": 202 }, - "libnewlib.a:heap.c.o": { + "libnewlib.a:heap.c.obj": { ".iram0.text": 190, "flash_total": 190, "ram_st_total": 190 @@ -14836,7 +14696,7 @@ Producing JSON output for esp32c3... "flash_total": 187, "ram_st_total": 0 }, - "libspi_flash.a:cache_utils.c.o": { + "libspi_flash.a:cache_utils.c.obj": { ".dram0.bss": 8, ".flash.text": 38, ".iram0.text": 144, @@ -14848,13 +14708,13 @@ Producing JSON output for esp32c3... "flash_total": 176, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_boya.c.o": { + "libspi_flash.a:spi_flash_chip_boya.c.obj": { ".dram0.data": 125, ".iram0.text": 46, "flash_total": 171, "ram_st_total": 171 }, - "libesp_system.a:esp_system.c.o": { + "libesp_system.a:esp_system.c.obj": { ".dram0.bss": 20, ".flash.text": 80, ".iram0.text": 90, @@ -14866,23 +14726,23 @@ Producing JSON output for esp32c3... "flash_total": 168, "ram_st_total": 0 }, - "libnewlib.a:abort.c.o": { + "libnewlib.a:abort.c.obj": { ".dram0.data": 38, ".iram0.text": 128, "flash_total": 166, "ram_st_total": 166 }, - "libhal.a:brownout_hal.c.o": { + "libhal.a:brownout_hal.c.obj": { ".flash.text": 160, "flash_total": 160, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_api.c.o": { + "libefuse.a:esp_efuse_api.c.obj": { ".flash.text": 158, "flash_total": 158, "ram_st_total": 0 }, - "libfreertos.a:portasm.S.o": { + "libfreertos.a:portasm.S.obj": { ".iram0.text": 154, "flash_total": 154, "ram_st_total": 154 @@ -14892,23 +14752,23 @@ Producing JSON output for esp32c3... "flash_total": 148, "ram_st_total": 0 }, - "libfreertos.a:list.c.o": { + "libfreertos.a:list.c.obj": { ".iram0.text": 134, "flash_total": 134, "ram_st_total": 134 }, - "libhal.a:spi_flash_encrypt_hal_iram.c.o": { + "libhal.a:spi_flash_encrypt_hal_iram.c.obj": { ".iram0.text": 132, "flash_total": 132, "ram_st_total": 132 }, - "libesp_system.a:cache_err_int.c.o": { + "libesp_system.a:cache_err_int.c.obj": { ".flash.text": 124, ".iram0.text": 4, "flash_total": 128, "ram_st_total": 4 }, - "libspi_flash.a:spi_flash_os_func_noos.c.o": { + "libspi_flash.a:spi_flash_os_func_noos.c.obj": { ".dram0.data": 36, ".iram0.text": 86, "flash_total": 122, @@ -14919,7 +14779,7 @@ Producing JSON output for esp32c3... "flash_total": 108, "ram_st_total": 0 }, - "libspi_flash.a:flash_ops.c.o": { + "libspi_flash.a:flash_ops.c.obj": { ".dram0.bss": 4, ".dram0.data": 24, ".flash.text": 38, @@ -14927,49 +14787,49 @@ Producing JSON output for esp32c3... "flash_total": 102, "ram_st_total": 68 }, - "libpthread.a:pthread.c.o": { + "libpthread.a:pthread.c.obj": { ".dram0.bss": 8, ".flash.text": 100, "flash_total": 100, "ram_st_total": 8 }, - "libefuse.a:esp_efuse_table.c.o": { + "libefuse.a:esp_efuse_table.c.obj": { ".dram0.data": 96, "flash_total": 96, "ram_st_total": 96 }, - "libhal.a:uart_hal_iram.c.o": { + "libhal.a:uart_hal_iram.c.obj": { ".flash.text": 88, "flash_total": 88, "ram_st_total": 0 }, - "libsoc.a:gpio_periph.c.o": { + "libsoc.a:gpio_periph.c.obj": { ".flash.rodata": 88, "flash_total": 88, "ram_st_total": 0 }, - "libesp_system.a:apb_backup_dma.c.o": { + "libesp_system.a:apb_backup_dma.c.obj": { ".flash.text": 34, ".iram0.text": 52, "flash_total": 86, "ram_st_total": 52 }, - "libhal.a:interrupt_controller_hal.c.o": { + "libhal.a:interrupt_controller_hal.c.obj": { ".flash.text": 80, "flash_total": 80, "ram_st_total": 0 }, - "libnewlib.a:reent_init.c.o": { + "libnewlib.a:reent_init.c.obj": { ".iram0.text": 76, "flash_total": 76, "ram_st_total": 76 }, - "libriscv.a:instruction_decode.c.o": { + "libriscv.a:instruction_decode.c.obj": { ".flash.text": 74, "flash_total": 74, "ram_st_total": 0 }, - "libesp_hw_support.a:chip_info.c.o": { + "libesp_hw_support.a:chip_info.c.obj": { ".flash.text": 70, "flash_total": 70, "ram_st_total": 0 @@ -14984,7 +14844,7 @@ Producing JSON output for esp32c3... "flash_total": 64, "ram_st_total": 0 }, - "libbootloader_support.a:flash_qio_mode.c.o": { + "libbootloader_support.a:flash_qio_mode.c.obj": { ".flash.text": 58, "flash_total": 58, "ram_st_total": 0 @@ -14994,7 +14854,7 @@ Producing JSON output for esp32c3... "flash_total": 56, "ram_st_total": 0 }, - "libesp_system.a:brownout.c.o": { + "libesp_system.a:brownout.c.obj": { ".flash.rodata": 5, ".flash.text": 38, "flash_total": 43, @@ -15005,22 +14865,22 @@ Producing JSON output for esp32c3... "flash_total": 40, "ram_st_total": 0 }, - "libnewlib.a:syscalls.c.o": { + "libnewlib.a:syscalls.c.obj": { ".flash.text": 36, "flash_total": 36, "ram_st_total": 0 }, - "libefuse.a:esp_efuse_fields.c.o": { + "libefuse.a:esp_efuse_fields.c.obj": { ".flash.text": 32, "flash_total": 32, "ram_st_total": 0 }, - "libhal.a:cpu_hal.c.o": { + "libhal.a:cpu_hal.c.obj": { ".iram0.text": 32, "flash_total": 32, "ram_st_total": 32 }, - "libspi_flash.a:spi_flash_chip_drivers.c.o": { + "libspi_flash.a:spi_flash_chip_drivers.c.obj": { ".dram0.data": 32, "flash_total": 32, "ram_st_total": 32 @@ -15030,52 +14890,52 @@ Producing JSON output for esp32c3... "flash_total": 28, "ram_st_total": 0 }, - "libesp_hw_support.a:cpu_util.c.o": { + "libesp_hw_support.a:cpu_util.c.obj": { ".iram0.text": 28, "flash_total": 28, "ram_st_total": 28 }, - "libesp_pm.a:pm_impl.c.o": { + "libesp_pm.a:pm_impl.c.obj": { ".flash.text": 28, "flash_total": 28, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash_config_esp32c3.c.o": { + "libbootloader_support.a:bootloader_flash_config_esp32c3.c.obj": { ".flash.text": 26, "flash_total": 26, "ram_st_total": 0 }, - "libesp_rom.a:esp_rom_uart.c.o": { + "libesp_rom.a:esp_rom_uart.c.obj": { ".iram0.text": 24, "flash_total": 24, "ram_st_total": 24 }, - "libbootloader_support.a:bootloader_mem.c.o": { + "libbootloader_support.a:bootloader_mem.c.obj": { ".flash.text": 14, "flash_total": 14, "ram_st_total": 0 }, - "libnewlib.a:pthread.c.o": { + "libnewlib.a:pthread.c.obj": { ".flash.text": 6, "flash_total": 6, "ram_st_total": 0 }, - "libdriver.a:spi_bus_lock.c.o": { + "libdriver.a:spi_bus_lock.c.obj": { ".dram0.data": 4, "flash_total": 4, "ram_st_total": 4 }, - "libfreertos.a:FreeRTOS-openocd.c.o": { + "libfreertos.a:FreeRTOS-openocd.c.obj": { ".dram0.data": 4, "flash_total": 4, "ram_st_total": 4 }, - "libcxx.a:cxx_guards.cpp.o": { + "libcxx.a:cxx_guards.cpp.obj": { ".flash.text": 2, "flash_total": 2, "ram_st_total": 0 }, - "libesp_system.a:ubsan.c.o": { + "libesp_system.a:ubsan.c.obj": { ".iram0.text": 2, "flash_total": 2, "ram_st_total": 2 @@ -15185,11 +15045,9 @@ Producing JSON output for esp32c3... "uart_set_select_notif_callback": 30, "uart_get_selectlock": 6 }, - ".flash_rodata_dummy": {}, ".iram0.bss": {}, ".iram0.data": {}, ".iram0.text": {}, - ".iram0.text_end": {}, ".noinit": {}, ".rtc.bss": {}, ".rtc.data": {}, @@ -15217,19 +15075,19 @@ Producing JSON output for esp32s3... "iram_remain": 239934, "diram_data": 9252, "diram_bss": 2520, - "diram_text": 1, + "diram_text": 0, "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, "diram_total": 135168, - "used_diram": 11773, - "used_diram_ratio": 0.08709901751893939, - "diram_remain": 123395, + "used_diram": 11772, + "used_diram_ratio": 0.08709161931818182, + "diram_remain": 123396, "flash_code": 87463, "flash_rodata": 27132, - "flash_other": 131328, - "used_flash_non_ram": 245923, - "total_size": 301962 + "flash_other": 256, + "used_flash_non_ram": 114851, + "total_size": 170889 } { "no-rtti\\libc.a": { @@ -15463,7 +15321,7 @@ Producing JSON output for esp32s3... "flash_total": 10527, "ram_st_total": 0 }, - "libfreertos.a:tasks.c.o": { + "libfreertos.a:tasks.c.obj": { ".dram0.bss": 704, ".dram0.data": 8, ".flash.rodata": 1158, @@ -15471,25 +15329,25 @@ Producing JSON output for esp32s3... "flash_total": 7958, "ram_st_total": 7504 }, - "libesp_common.a:esp_err_to_name.c.o": { + "libesp_common.a:esp_err_to_name.c.obj": { ".flash.rodata": 7287, ".flash.text": 53, "flash_total": 7340, "ram_st_total": 0 }, - "libheap.a:heap_tlsf.c.o": { + "libheap.a:heap_tlsf.c.obj": { ".dram0.data": 1796, ".iram0.text": 3591, "flash_total": 5387, "ram_st_total": 5387 }, - "libfreertos.a:queue.c.o": { + "libfreertos.a:queue.c.obj": { ".flash.rodata": 1515, ".iram0.text": 3038, "flash_total": 4553, "ram_st_total": 3038 }, - "libvfs.a:vfs_uart.c.o": { + "libvfs.a:vfs_uart.c.obj": { ".dram0.bss": 8, ".dram0.data": 116, ".flash.rodata": 282, @@ -15503,19 +15361,19 @@ Producing JSON output for esp32s3... "flash_total": 3757, "ram_st_total": 0 }, - "libfreertos.a:portasm.S.o": { + "libfreertos.a:portasm.S.obj": { ".dram0.data": 3084, ".iram0.text": 416, "flash_total": 3500, "ram_st_total": 3500 }, - "libspi_flash.a:spi_flash_chip_generic.c.o": { + "libspi_flash.a:spi_flash_chip_generic.c.obj": { ".dram0.data": 554, ".iram0.text": 2529, "flash_total": 3083, "ram_st_total": 3083 }, - "libesp_hw_support.a:intr_alloc.c.o": { + "libesp_hw_support.a:intr_alloc.c.obj": { ".dram0.bss": 22, ".dram0.data": 8, ".flash.rodata": 198, @@ -15530,7 +15388,7 @@ Producing JSON output for esp32s3... "flash_total": 2749, "ram_st_total": 0 }, - "libdriver.a:uart.c.o": { + "libdriver.a:uart.c.obj": { ".dram0.bss": 12, ".dram0.data": 56, ".flash.rodata": 511, @@ -15538,18 +15396,18 @@ Producing JSON output for esp32s3... "flash_total": 2658, "ram_st_total": 68 }, - "libesp_system.a:panic_arch.c.o": { + "libesp_system.a:panic_arch.c.obj": { ".flash.rodata": 1538, ".flash.text": 715, "flash_total": 2253, "ram_st_total": 0 }, - "libhal.a:spi_flash_hal_iram.c.o": { + "libhal.a:spi_flash_hal_iram.c.obj": { ".iram0.text": 2250, "flash_total": 2250, "ram_st_total": 2250 }, - "libvfs.a:vfs.c.o": { + "libvfs.a:vfs.c.obj": { ".dram0.bss": 40, ".dram0.data": 192, ".flash.rodata": 111, @@ -15557,14 +15415,14 @@ Producing JSON output for esp32s3... "flash_total": 2238, "ram_st_total": 232 }, - "libesp_hw_support.a:rtc_clk.c.o": { + "libesp_hw_support.a:rtc_clk.c.obj": { ".dram0.bss": 8, ".dram0.data": 171, ".iram0.text": 2059, "flash_total": 2230, "ram_st_total": 2238 }, - "libfreertos.a:xtensa_vectors.S.o": { + "libfreertos.a:xtensa_vectors.S.obj": { ".dram0.data": 32, ".flash.rodata": 48, ".iram0.text": 1464, @@ -15572,7 +15430,7 @@ Producing JSON output for esp32s3... "flash_total": 1969, "ram_st_total": 1921 }, - "libesp_system.a:task_wdt.c.o": { + "libesp_system.a:task_wdt.c.obj": { ".dram0.bss": 12, ".dram0.data": 53, ".flash.rodata": 591, @@ -15580,18 +15438,18 @@ Producing JSON output for esp32s3... "flash_total": 1963, "ram_st_total": 65 }, - "libhal.a:spi_flash_hal_gpspi.c.o": { + "libhal.a:spi_flash_hal_gpspi.c.obj": { ".iram0.text": 1842, "flash_total": 1842, "ram_st_total": 1842 }, - "libesp_hw_support.a:rtc_init.c.o": { + "libesp_hw_support.a:rtc_init.c.obj": { ".flash.rodata": 70, ".flash.text": 1703, "flash_total": 1773, "ram_st_total": 0 }, - "libspi_flash.a:esp_flash_api.c.o": { + "libspi_flash.a:esp_flash_api.c.obj": { ".dram0.data": 20, ".flash.rodata": 762, ".flash.text": 89, @@ -15599,7 +15457,7 @@ Producing JSON output for esp32s3... "flash_total": 1733, "ram_st_total": 882 }, - "libspi_flash.a:flash_mmap.c.o": { + "libspi_flash.a:flash_mmap.c.obj": { ".dram0.bss": 520, ".flash.rodata": 240, ".flash.text": 166, @@ -15607,7 +15465,7 @@ Producing JSON output for esp32s3... "flash_total": 1704, "ram_st_total": 1818 }, - "libfreertos.a:port.c.o": { + "libfreertos.a:port.c.obj": { ".dram0.bss": 24, ".flash.rodata": 541, ".flash.text": 147, @@ -15615,7 +15473,7 @@ Producing JSON output for esp32s3... "flash_total": 1633, "ram_st_total": 969 }, - "libheap.a:heap_caps.c.o": { + "libheap.a:heap_caps.c.obj": { ".dram0.bss": 4, ".dram0.data": 4, ".flash.rodata": 355, @@ -15624,12 +15482,12 @@ Producing JSON output for esp32s3... "flash_total": 1623, "ram_st_total": 1011 }, - "libhal.a:wdt_hal_iram.c.o": { + "libhal.a:wdt_hal_iram.c.obj": { ".iram0.text": 1493, "flash_total": 1493, "ram_st_total": 1493 }, - "libdriver.a:periph_ctrl.c.o": { + "libdriver.a:periph_ctrl.c.obj": { ".dram0.bss": 37, ".dram0.data": 8, ".flash.rodata": 85, @@ -15637,7 +15495,7 @@ Producing JSON output for esp32s3... "flash_total": 1470, "ram_st_total": 45 }, - "libesp_system.a:cpu_start.c.o": { + "libesp_system.a:cpu_start.c.obj": { ".dram0.bss": 5, ".flash.rodata": 334, ".flash.text": 371, @@ -15645,13 +15503,13 @@ Producing JSON output for esp32s3... "flash_total": 1437, "ram_st_total": 737 }, - "libesp_ringbuf.a:ringbuf.c.o": { + "libesp_ringbuf.a:ringbuf.c.obj": { ".flash.rodata": 512, ".iram0.text": 873, "flash_total": 1385, "ram_st_total": 873 }, - "libspi_flash.a:cache_utils.c.o": { + "libspi_flash.a:cache_utils.c.obj": { ".dram0.bss": 14, ".dram0.data": 4, ".flash.rodata": 570, @@ -15660,14 +15518,14 @@ Producing JSON output for esp32s3... "flash_total": 1351, "ram_st_total": 703 }, - "libheap.a:heap_caps_init.c.o": { + "libheap.a:heap_caps_init.c.obj": { ".dram0.bss": 4, ".flash.rodata": 430, ".flash.text": 905, "flash_total": 1335, "ram_st_total": 4 }, - "libesp_system.a:startup.c.o": { + "libesp_system.a:startup.c.obj": { ".dram0.bss": 11, ".dram0.data": 8, ".flash.rodata": 505, @@ -15676,7 +15534,7 @@ Producing JSON output for esp32s3... "flash_total": 1330, "ram_st_total": 88 }, - "libnewlib.a:locks.c.o": { + "libnewlib.a:locks.c.obj": { ".dram0.bss": 168, ".dram0.data": 8, ".flash.rodata": 344, @@ -15685,26 +15543,26 @@ Producing JSON output for esp32s3... "flash_total": 1256, "ram_st_total": 958 }, - "libspi_flash.a:partition.c.o": { + "libspi_flash.a:partition.c.obj": { ".dram0.bss": 8, ".flash.rodata": 268, ".flash.text": 938, "flash_total": 1206, "ram_st_total": 8 }, - "libhal.a:systimer_hal.c.o": { + "libhal.a:systimer_hal.c.obj": { ".dram0.data": 85, ".iram0.text": 1052, "flash_total": 1137, "ram_st_total": 1137 }, - "libxtensa.a:xtensa_intr_asm.S.o": { + "libxtensa.a:xtensa_intr_asm.S.obj": { ".dram0.data": 1024, ".iram0.text": 51, "flash_total": 1075, "ram_st_total": 1075 }, - "libesp_system.a:panic.c.o": { + "libesp_system.a:panic.c.obj": { ".dram0.bss": 5, ".dram0.data": 12, ".flash.rodata": 147, @@ -15713,19 +15571,19 @@ Producing JSON output for esp32s3... "flash_total": 1046, "ram_st_total": 29 }, - "libspi_flash.a:memspi_host_driver.c.o": { + "libspi_flash.a:memspi_host_driver.c.obj": { ".dram0.data": 397, ".iram0.text": 637, "flash_total": 1034, "ram_st_total": 1034 }, - "libesp_system.a:clk.c.o": { + "libesp_system.a:clk.c.obj": { ".flash.rodata": 212, ".flash.text": 802, "flash_total": 1014, "ram_st_total": 0 }, - "libesp_timer.a:esp_timer.c.o": { + "libesp_timer.a:esp_timer.c.obj": { ".dram0.bss": 8, ".dram0.data": 8, ".flash.rodata": 72, @@ -15734,13 +15592,13 @@ Producing JSON output for esp32s3... "flash_total": 867, "ram_st_total": 298 }, - "libheap.a:memory_layout_utils.c.o": { + "libheap.a:memory_layout_utils.c.obj": { ".flash.rodata": 283, ".flash.text": 575, "flash_total": 858, "ram_st_total": 0 }, - "libesp_system.a:debug_helpers.c.o": { + "libesp_system.a:debug_helpers.c.obj": { ".flash.rodata": 73, ".iram0.text": 747, "flash_total": 820, @@ -15751,19 +15609,19 @@ Producing JSON output for esp32s3... "flash_total": 818, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_winbond.c.o": { + "libspi_flash.a:spi_flash_chip_winbond.c.obj": { ".dram0.data": 136, ".iram0.text": 659, "flash_total": 795, "ram_st_total": 795 }, - "libheap.a:multi_heap.c.o": { + "libheap.a:multi_heap.c.obj": { ".dram0.data": 157, ".iram0.text": 601, "flash_total": 758, "ram_st_total": 758 }, - "libesp_ipc.a:esp_ipc.c.o": { + "libesp_ipc.a:esp_ipc.c.obj": { ".dram0.bss": 56, ".flash.rodata": 97, ".flash.text": 456, @@ -15776,7 +15634,7 @@ Producing JSON output for esp32s3... "flash_total": 721, "ram_st_total": 0 }, - "libesp_system.a:panic_handler.c.o": { + "libesp_system.a:panic_handler.c.obj": { ".dram0.bss": 8, ".dram0.data": 8, ".flash.rodata": 8, @@ -15791,12 +15649,12 @@ Producing JSON output for esp32s3... "flash_total": 708, "ram_st_total": 0 }, - "libesp_hw_support.a:rtc_time.c.o": { + "libesp_hw_support.a:rtc_time.c.obj": { ".iram0.text": 675, "flash_total": 675, "ram_st_total": 675 }, - "liblog.a:log.c.o": { + "liblog.a:log.c.obj": { ".dram0.bss": 264, ".dram0.data": 8, ".flash.rodata": 122, @@ -15805,14 +15663,14 @@ Producing JSON output for esp32s3... "flash_total": 671, "ram_st_total": 314 }, - "libnewlib.a:time.c.o": { + "libnewlib.a:time.c.obj": { ".dram0.bss": 20, ".flash.text": 509, ".iram0.text": 127, "flash_total": 636, "ram_st_total": 147 }, - "libesp_timer.a:esp_timer_impl_systimer.c.o": { + "libesp_timer.a:esp_timer_impl_systimer.c.obj": { ".dram0.bss": 12, ".dram0.data": 24, ".flash.rodata": 125, @@ -15821,14 +15679,14 @@ Producing JSON output for esp32s3... "flash_total": 633, "ram_st_total": 234 }, - "libfreertos.a:port_systick.c.o": { + "libfreertos.a:port_systick.c.obj": { ".dram0.bss": 12, ".flash.rodata": 192, ".iram0.text": 394, "flash_total": 586, "ram_st_total": 406 }, - "libspi_flash.a:esp_flash_spi_init.c.o": { + "libspi_flash.a:esp_flash_spi_init.c.obj": { ".dram0.bss": 4, ".dram0.data": 68, ".flash.rodata": 261, @@ -15841,13 +15699,13 @@ Producing JSON output for esp32s3... "flash_total": 552, "ram_st_total": 0 }, - "libhal.a:interrupt_descriptor_table.c.o": { + "libhal.a:interrupt_descriptor_table.c.obj": { ".flash.rodata": 512, ".flash.text": 12, "flash_total": 524, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_os_func_app.c.o": { + "libspi_flash.a:spi_flash_os_func_app.c.obj": { ".dram0.data": 52, ".flash.rodata": 95, ".flash.text": 44, @@ -15855,7 +15713,7 @@ Producing JSON output for esp32s3... "flash_total": 515, "ram_st_total": 376 }, - "libesp_system.a:crosscore_int.c.o": { + "libesp_system.a:crosscore_int.c.obj": { ".dram0.bss": 8, ".dram0.data": 8, ".flash.rodata": 120, @@ -15864,13 +15722,13 @@ Producing JSON output for esp32s3... "flash_total": 499, "ram_st_total": 245 }, - "libesp_system.a:system_internal.c.o": { + "libesp_system.a:system_internal.c.obj": { ".flash.rodata": 16, ".iram0.text": 475, "flash_total": 491, "ram_st_total": 475 }, - "libapp_update.a:esp_app_desc.c.o": { + "libapp_update.a:esp_app_desc.c.obj": { ".dram0.bss": 8, ".dram0.data": 1, ".flash.appdesc": 256, @@ -15880,18 +15738,18 @@ Producing JSON output for esp32s3... "flash_total": 486, "ram_st_total": 203 }, - "libesp_hw_support.a:rtc_sleep.c.o": { + "libesp_hw_support.a:rtc_sleep.c.obj": { ".iram0.text": 476, "flash_total": 476, "ram_st_total": 476 }, - "libmain.a:hello_world_main.c.o": { + "libmain.a:hello_world_main.c.obj": { ".flash.rodata": 232, ".flash.text": 228, "flash_total": 460, "ram_st_total": 0 }, - "libfreertos.a:port_common.c.o": { + "libfreertos.a:port_common.c.obj": { ".dram0.bss": 8, ".flash.rodata": 214, ".flash.text": 146, @@ -15899,23 +15757,23 @@ Producing JSON output for esp32s3... "flash_total": 458, "ram_st_total": 106 }, - "libhal.a:spi_flash_hal.c.o": { + "libhal.a:spi_flash_hal.c.obj": { ".flash.rodata": 96, ".flash.text": 351, "flash_total": 447, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_flash.c.o": { + "libbootloader_support.a:bootloader_flash.c.obj": { ".iram0.text": 444, "flash_total": 444, "ram_st_total": 444 }, - "libhal.a:uart_hal.c.o": { + "libhal.a:uart_hal.c.obj": { ".flash.text": 432, "flash_total": 432, "ram_st_total": 0 }, - "libfreertos.a:xtensa_context.S.o": { + "libfreertos.a:xtensa_context.S.obj": { ".iram0.text": 390, "flash_total": 390, "ram_st_total": 390 @@ -15926,7 +15784,7 @@ Producing JSON output for esp32s3... "flash_total": 378, "ram_st_total": 4 }, - "libesp_ipc.a:esp_ipc_isr.c.o": { + "libesp_ipc.a:esp_ipc_isr.c.obj": { ".dram0.bss": 16, ".dram0.data": 4, ".flash.rodata": 144, @@ -15935,13 +15793,13 @@ Producing JSON output for esp32s3... "flash_total": 354, "ram_st_total": 39 }, - "libspi_flash.a:spi_flash_chip_gd.c.o": { + "libspi_flash.a:spi_flash_chip_gd.c.obj": { ".dram0.data": 123, ".iram0.text": 202, "flash_total": 325, "ram_st_total": 325 }, - "libheap.a:memory_layout.c.o": { + "libheap.a:memory_layout.c.obj": { ".flash.rodata": 315, "flash_total": 315, "ram_st_total": 0 @@ -15956,7 +15814,7 @@ Producing JSON output for esp32s3... "flash_total": 311, "ram_st_total": 311 }, - "libesp_system.a:freertos_hooks.c.o": { + "libesp_system.a:freertos_hooks.c.obj": { ".dram0.bss": 128, ".dram0.data": 8, ".flash.text": 247, @@ -15964,7 +15822,7 @@ Producing JSON output for esp32s3... "flash_total": 302, "ram_st_total": 183 }, - "libnewlib.a:esp_time_impl.c.o": { + "libnewlib.a:esp_time_impl.c.obj": { ".dram0.bss": 12, ".flash.text": 281, "flash_total": 281, @@ -15980,7 +15838,7 @@ Producing JSON output for esp32s3... "flash_total": 270, "ram_st_total": 0 }, - "libapp_update.a:esp_ota_ops.c.o": { + "libapp_update.a:esp_ota_ops.c.obj": { ".dram0.bss": 4, ".flash.rodata": 121, ".flash.text": 148, @@ -15992,13 +15850,13 @@ Producing JSON output for esp32s3... "flash_total": 263, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_mxic.c.o": { + "libspi_flash.a:spi_flash_chip_mxic.c.obj": { ".dram0.data": 190, ".iram0.text": 70, "flash_total": 260, "ram_st_total": 260 }, - "libhal.a:soc_hal.c.o": { + "libhal.a:soc_hal.c.obj": { ".dram0.data": 24, ".iram0.text": 234, "flash_total": 258, @@ -16014,25 +15872,25 @@ Producing JSON output for esp32s3... "flash_total": 252, "ram_st_total": 0 }, - "libesp_system.a:esp_err.c.o": { + "libesp_system.a:esp_err.c.obj": { ".dram0.data": 108, ".iram0.text": 140, "flash_total": 248, "ram_st_total": 248 }, - "libhal.a:brownout_hal.c.o": { + "libhal.a:brownout_hal.c.obj": { ".flash.text": 244, "flash_total": 244, "ram_st_total": 0 }, - "libesp_system.a:int_wdt.c.o": { + "libesp_system.a:int_wdt.c.obj": { ".dram0.bss": 9, ".flash.text": 152, ".iram0.text": 90, "flash_total": 242, "ram_st_total": 99 }, - "libesp_timer.a:system_time.c.o": { + "libesp_timer.a:system_time.c.obj": { ".dram0.bss": 8, ".flash.rodata": 80, ".flash.text": 126, @@ -16040,7 +15898,7 @@ Producing JSON output for esp32s3... "flash_total": 241, "ram_st_total": 43 }, - "libesp_hw_support.a:esp_clk.c.o": { + "libesp_hw_support.a:esp_clk.c.obj": { ".dram0.bss": 4, ".flash.text": 194, ".iram0.text": 25, @@ -16048,13 +15906,13 @@ Producing JSON output for esp32s3... "flash_total": 235, "ram_st_total": 45 }, - "libspi_flash.a:spi_flash_chip_issi.c.o": { + "libspi_flash.a:spi_flash_chip_issi.c.obj": { ".dram0.data": 125, ".iram0.text": 108, "flash_total": 233, "ram_st_total": 233 }, - "libnewlib.a:newlib_init.c.o": { + "libnewlib.a:newlib_init.c.obj": { ".dram0.bss": 240, ".dram0.data": 156, ".flash.text": 73, @@ -16066,7 +15924,7 @@ Producing JSON output for esp32s3... "flash_total": 223, "ram_st_total": 0 }, - "libpthread.a:pthread_local_storage.c.o": { + "libpthread.a:pthread_local_storage.c.obj": { ".dram0.bss": 4, ".dram0.data": 8, ".flash.text": 213, @@ -16083,18 +15941,18 @@ Producing JSON output for esp32s3... "flash_total": 216, "ram_st_total": 0 }, - "libhal.a:spi_flash_encrypt_hal_iram.c.o": { + "libhal.a:spi_flash_encrypt_hal_iram.c.obj": { ".iram0.text": 213, "flash_total": 213, "ram_st_total": 213 }, - "liblog.a:log_freertos.c.o": { + "liblog.a:log_freertos.c.obj": { ".dram0.bss": 8, ".iram0.text": 205, "flash_total": 205, "ram_st_total": 213 }, - "libnewlib.a:abort.c.o": { + "libnewlib.a:abort.c.obj": { ".dram0.data": 38, ".iram0.text": 157, "flash_total": 195, @@ -16106,7 +15964,7 @@ Producing JSON output for esp32s3... "flash_total": 190, "ram_st_total": 0 }, - "libxtensa.a:xtensa_intr.c.o": { + "libxtensa.a:xtensa_intr.c.obj": { ".flash.rodata": 35, ".flash.text": 126, ".iram0.text": 26, @@ -16118,40 +15976,40 @@ Producing JSON output for esp32s3... "flash_total": 182, "ram_st_total": 0 }, - "libesp_hw_support.a:regi2c_ctrl.c.o": { + "libesp_hw_support.a:regi2c_ctrl.c.obj": { ".dram0.data": 8, ".iram0.text": 171, "flash_total": 179, "ram_st_total": 179 }, - "libspi_flash.a:spi_flash_chip_boya.c.o": { + "libspi_flash.a:spi_flash_chip_boya.c.obj": { ".dram0.data": 125, ".iram0.text": 52, "flash_total": 177, "ram_st_total": 177 }, - "libfreertos.a:list.c.o": { + "libfreertos.a:list.c.obj": { ".iram0.text": 164, "flash_total": 164, "ram_st_total": 164 }, - "libesp_hw_support.a:cpu_util.c.o": { + "libesp_hw_support.a:cpu_util.c.obj": { ".flash.rodata": 20, ".iram0.text": 137, "flash_total": 157, "ram_st_total": 137 }, - "libnewlib.a:heap.c.o": { + "libnewlib.a:heap.c.obj": { ".iram0.text": 151, "flash_total": 151, "ram_st_total": 151 }, - "libesp_system.a:highint_hdl.S.o": { + "libesp_system.a:highint_hdl.S.obj": { ".iram0.text": 147, "flash_total": 147, "ram_st_total": 147 }, - "libesp_ipc.a:esp_ipc_isr_handler.S.o": { + "libesp_ipc.a:esp_ipc_isr_handler.S.obj": { ".dram0.data": 16, ".iram0.text": 125, "flash_total": 141, @@ -16168,7 +16026,7 @@ Producing JSON output for esp32s3... "flash_total": 128, "ram_st_total": 0 }, - "libesp_system.a:esp_system.c.o": { + "libesp_system.a:esp_system.c.obj": { ".dram0.bss": 20, ".flash.text": 70, ".iram0.text": 56, @@ -16185,13 +16043,13 @@ Producing JSON output for esp32s3... "flash_total": 112, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_os_func_noos.c.o": { + "libspi_flash.a:spi_flash_os_func_noos.c.obj": { ".dram0.data": 36, ".iram0.text": 72, "flash_total": 108, "ram_st_total": 108 }, - "libhal.a:uart_hal_iram.c.o": { + "libhal.a:uart_hal_iram.c.obj": { ".flash.text": 105, "flash_total": 105, "ram_st_total": 0 @@ -16201,7 +16059,7 @@ Producing JSON output for esp32s3... "flash_total": 100, "ram_st_total": 0 }, - "libspi_flash.a:flash_ops.c.o": { + "libspi_flash.a:flash_ops.c.obj": { ".dram0.bss": 4, ".dram0.data": 24, ".flash.text": 33, @@ -16209,7 +16067,7 @@ Producing JSON output for esp32s3... "flash_total": 98, "ram_st_total": 69 }, - "libpthread.a:pthread.c.o": { + "libpthread.a:pthread.c.obj": { ".dram0.bss": 8, ".flash.text": 97, "flash_total": 97, @@ -16220,7 +16078,7 @@ Producing JSON output for esp32s3... "flash_total": 94, "ram_st_total": 0 }, - "libesp_system.a:cache_err_int.c.o": { + "libesp_system.a:cache_err_int.c.obj": { ".flash.text": 78, ".iram0.text": 7, "flash_total": 85, @@ -16231,12 +16089,12 @@ Producing JSON output for esp32s3... "flash_total": 84, "ram_st_total": 0 }, - "libhal.a:mpu_hal.c.o": { + "libhal.a:mpu_hal.c.obj": { ".flash.text": 72, "flash_total": 72, "ram_st_total": 0 }, - "libesp_system.a:panic_handler_asm.S.o": { + "libesp_system.a:panic_handler_asm.S.obj": { ".iram0.text": 66, "flash_total": 66, "ram_st_total": 66 @@ -16251,17 +16109,17 @@ Producing JSON output for esp32s3... "flash_total": 64, "ram_st_total": 0 }, - "libnewlib.a:reent_init.c.o": { + "libnewlib.a:reent_init.c.obj": { ".iram0.text": 63, "flash_total": 63, "ram_st_total": 63 }, - "libhal.a:interrupt_controller_hal.c.o": { + "libhal.a:interrupt_controller_hal.c.obj": { ".flash.text": 59, "flash_total": 59, "ram_st_total": 0 }, - "libbootloader_support.a:flash_qio_mode.c.o": { + "libbootloader_support.a:flash_qio_mode.c.obj": { ".flash.text": 58, "flash_total": 58, "ram_st_total": 0 @@ -16286,12 +16144,12 @@ Producing JSON output for esp32s3... "flash_total": 47, "ram_st_total": 0 }, - "libfreertos.a:xtensa_vector_defaults.S.o": { + "libfreertos.a:xtensa_vector_defaults.S.obj": { ".iram0.text": 46, "flash_total": 46, "ram_st_total": 46 }, - "libhal.a:cpu_hal.c.o": { + "libhal.a:cpu_hal.c.obj": { ".iram0.text": 42, "flash_total": 42, "ram_st_total": 42 @@ -16316,13 +16174,13 @@ Producing JSON output for esp32s3... "flash_total": 40, "ram_st_total": 0 }, - "libesp_system.a:brownout.c.o": { + "libesp_system.a:brownout.c.obj": { ".flash.rodata": 5, ".flash.text": 30, "flash_total": 35, "ram_st_total": 0 }, - "libspi_flash.a:spi_flash_chip_drivers.c.o": { + "libspi_flash.a:spi_flash_chip_drivers.c.obj": { ".dram0.data": 32, "flash_total": 32, "ram_st_total": 32 @@ -16332,12 +16190,12 @@ Producing JSON output for esp32s3... "flash_total": 32, "ram_st_total": 0 }, - "libnewlib.a:syscalls.c.o": { + "libnewlib.a:syscalls.c.obj": { ".flash.text": 31, "flash_total": 31, "ram_st_total": 0 }, - "libesp_hw_support.a:chip_info.c.o": { + "libesp_hw_support.a:chip_info.c.obj": { ".flash.text": 29, "flash_total": 29, "ram_st_total": 0 @@ -16347,22 +16205,22 @@ Producing JSON output for esp32s3... "flash_total": 28, "ram_st_total": 0 }, - "libesp_system.a:debug_helpers_asm.S.o": { + "libesp_system.a:debug_helpers_asm.S.obj": { ".iram0.text": 26, "flash_total": 26, "ram_st_total": 26 }, - "libesp_rom.a:esp_rom_uart.c.o": { + "libesp_rom.a:esp_rom_uart.c.obj": { ".iram0.text": 24, "flash_total": 24, "ram_st_total": 24 }, - "libbootloader_support.a:bootloader_flash_config_esp32s3.c.o": { + "libbootloader_support.a:bootloader_flash_config_esp32s3.c.obj": { ".flash.text": 22, "flash_total": 22, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_mem.c.o": { + "libbootloader_support.a:bootloader_mem.c.obj": { ".flash.text": 15, "flash_total": 15, "ram_st_total": 0 @@ -16372,7 +16230,7 @@ Producing JSON output for esp32s3... "flash_total": 13, "ram_st_total": 0 }, - "libnewlib.a:pthread.c.o": { + "libnewlib.a:pthread.c.obj": { ".flash.text": 12, "flash_total": 12, "ram_st_total": 0 @@ -16382,7 +16240,7 @@ Producing JSON output for esp32s3... "flash_total": 8, "ram_st_total": 0 }, - "libesp_pm.a:pm_impl.c.o": { + "libesp_pm.a:pm_impl.c.obj": { ".flash.text": 8, "flash_total": 8, "ram_st_total": 0 @@ -16393,12 +16251,12 @@ Producing JSON output for esp32s3... "flash_total": 6, "ram_st_total": 3 }, - "libcxx.a:cxx_guards.cpp.o": { + "libcxx.a:cxx_guards.cpp.obj": { ".flash.text": 5, "flash_total": 5, "ram_st_total": 0 }, - "libesp_system.a:ubsan.c.o": { + "libesp_system.a:ubsan.c.obj": { ".iram0.text": 5, "flash_total": 5, "ram_st_total": 5 @@ -16408,12 +16266,12 @@ Producing JSON output for esp32s3... "flash_total": 4, "ram_st_total": 0 }, - "libdriver.a:spi_bus_lock.c.o": { + "libdriver.a:spi_bus_lock.c.obj": { ".flash.rodata": 4, "flash_total": 4, "ram_st_total": 0 }, - "libfreertos.a:FreeRTOS-openocd.c.o": { + "libfreertos.a:FreeRTOS-openocd.c.obj": { ".dram0.data": 4, "flash_total": 4, "ram_st_total": 4 @@ -16426,127 +16284,127 @@ Producing JSON output for esp32s3... "flash_total": 0, "ram_st_total": 0 }, - "(exe):project_elf_src_esp32s3.c.o": { + "(exe):project_elf_src_esp32s3.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_common.c.o": { + "libbootloader_support.a:bootloader_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_common_loader.c.o": { + "libbootloader_support.a:bootloader_common_loader.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_efuse_esp32s3.c.o": { + "libbootloader_support.a:bootloader_efuse_esp32s3.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_random_esp32s3.c.o": { + "libbootloader_support.a:bootloader_random_esp32s3.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_sha.c.o": { + "libbootloader_support.a:bootloader_sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:bootloader_utility.c.o": { + "libbootloader_support.a:bootloader_utility.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:esp_image_format.c.o": { + "libbootloader_support.a:esp_image_format.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libbootloader_support.a:flash_partitions.c.o": { + "libbootloader_support.a:flash_partitions.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:gdma.c.o": { + "libdriver.a:gdma.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:gpio.c.o": { + "libdriver.a:gpio.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:rtc_io.c.o": { + "libdriver.a:rtc_io.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:rtc_module.c.o": { + "libdriver.a:rtc_module.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libdriver.a:spi_common.c.o": { + "libdriver.a:spi_common.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_hw_support.a:dport_access.c.o": { + "libesp_hw_support.a:dport_access.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_hw_support.a:esp_crypto_lock.c.o": { + "libesp_hw_support.a:esp_crypto_lock.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_ipc.a:esp_ipc_isr_routines.S.o": { + "libesp_ipc.a:esp_ipc_isr_routines.S.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libesp_pm.a:pm_locks.c.o": { + "libesp_pm.a:pm_locks.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libhal.a:gdma_hal.c.o": { + "libhal.a:gdma_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libhal.a:gpio_hal.c.o": { + "libhal.a:gpio_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libhal.a:rtc_io_hal.c.o": { + "libhal.a:rtc_io_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libhal.a:sha_hal.c.o": { + "libhal.a:sha_hal.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:esp_crypto_shared_gdma.c.o": { + "libmbedcrypto.a:esp_crypto_shared_gdma.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:esp_sha256.c.o": { + "libmbedcrypto.a:esp_sha256.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:esp_sha_gdma_impl.c.o": { + "libmbedcrypto.a:esp_sha_gdma_impl.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libmbedcrypto.a:sha.c.o": { + "libmbedcrypto.a:sha.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:gdma_periph.c.o": { + "libsoc.a:gdma_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:gpio_periph.c.o": { + "libsoc.a:gpio_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:rtc_io_periph.c.o": { + "libsoc.a:rtc_io_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:spi_periph.c.o": { + "libsoc.a:spi_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, - "libsoc.a:uart_periph.c.o": { + "libsoc.a:uart_periph.c.obj": { "flash_total": 0, "ram_st_total": 0 }, @@ -16837,11 +16695,9 @@ Producing JSON output for esp32s3... "uart_set_select_notif_callback": 23, "uart_get_selectlock": 12 }, - ".flash_rodata_dummy": {}, ".iram0.bss": {}, ".iram0.data": {}, ".iram0.text": {}, - ".iram0.text_end": {}, ".iram0.vectors": {}, ".noinit": {}, ".rtc.bss": {}, diff --git a/tools/test_idf_size/expected_output.json b/tools/test_idf_size/expected_output.json index 53c3f9eed627..f43de9d6a4c7 100644 --- a/tools/test_idf_size/expected_output.json +++ b/tools/test_idf_size/expected_output.json @@ -14,19 +14,19 @@ "iram_total": 131072, "used_iram_ratio": 0.297027587890625, "iram_remain": 92140, - "diram_data": 9324, - "diram_bss": 8296, - "diram_text": 37908, - "diram_vectors": 1024, + "diram_data": 0, + "diram_bss": 0, + "diram_text": 0, + "diram_vectors": 0, "diram_rodata": 0, "diram_other": 0, - "diram_total": 311808, - "used_diram": 56552, - "used_diram_ratio": 0.18136802134646962, - "diram_remain": 255256, + "diram_total": 0, + "used_diram": 0, + "used_diram_ratio": 0, + "diram_remain": 0, "flash_code": 146944, "flash_rodata": 39580, "flash_other": 0, "used_flash_non_ram": 186524, - "total_size": 283036 + "total_size": 234780 } diff --git a/tools/test_idf_size/expected_output.txt b/tools/test_idf_size/expected_output.txt index b41f162be3b3..e0560f0a54fb 100644 --- a/tools/test_idf_size/expected_output.txt +++ b/tools/test_idf_size/expected_output.txt @@ -5,12 +5,7 @@ Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used) Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used) .text size: 37908 bytes .vectors size: 1024 bytes -Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used) - .data size: 9324 bytes - .bss size: 8296 bytes - .text size: 37908 bytes - .vectors size: 1024 bytes Used Flash size : 186524 bytes .text : 146944 bytes .rodata : 39580 bytes -Total image size: 283036 bytes (.bin may be padded larger) +Total image size: 234780 bytes (.bin may be padded larger) diff --git a/tools/test_idf_size/mem_test.py b/tools/test_idf_size/mem_test.py new file mode 100644 index 000000000000..4bfaf0d5cd75 --- /dev/null +++ b/tools/test_idf_size/mem_test.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +# +import argparse +import json +import os +import re +from typing import Dict + +IDF_PATH = os.environ['IDF_PATH'] +MAX_SIZE_DIFF = 50 + + +def mem_test(size_json, esptool_output): # type: (dict, list) -> None + seg_len = {} # type: Dict[str, int] + for i in esptool_output: + tmp = i.split(' ') + if tmp[0] == 'Segment': + # tmp look like ['Segment', '2:', 'len', '0x02780', 'load', '0x3fc90610', 'file_offs', '0x00007ab0', '[BYTE_ACCESSIBLE,MEM_INTERNAL,DRAM]'] + # tmp[3] contains the size of the segment and tmp[8] contains the name of the memory segment + esptool_mem = {'mem_type':tmp[8], 'size':tmp[3]} + seg = re.sub(r'MEM_INTERNAL|,|BYTE_ACCESSIBLE|\n|\[|\]', '', esptool_mem['mem_type']) + # If there are two IRAMs in esptool output it will compute these two IRAM lengths in a seg_len['IRAM'] + seg_len[seg] = int(esptool_mem['size'], 16) if seg not in seg_len else seg_len[seg] + int(esptool_mem['size'], 16) + # including flash_other to DROM because flash_other contain .flash.appdesc that includes in DROM that produced by esptool + size_from_map = [('IROM', size_json['flash_code']), ('IRAM', size_json['iram_text'] + size_json['iram_vectors'] + size_json['diram_text'] + + size_json['diram_vectors']), ('DROM', size_json['flash_rodata'] + size_json['flash_other']), ('DRAM', size_json + ['dram_data'] + size_json['diram_data'])] + for mem_type, size in size_from_map: + if abs(size - seg_len[mem_type]) > MAX_SIZE_DIFF: + raise RuntimeError(mem_type + " segment in idf_size isn't correct regarding esptool") + print('Test complete without errors') + + +def main(): # type: () -> None + parser = argparse.ArgumentParser(description='mem_test.py - a tool to test accuracy of the sizes of the memory segments regarding idf.py size by esptool') + + parser.add_argument( + 'size_json', help='JSON file with the output of the idf.py size', + type=argparse.FileType('r')) + parser.add_argument( + 'esptool_output', help='File with the output of the esptool', + type=argparse.FileType('r')) + + args = parser.parse_args() + mem_test(json.loads(args.size_json.read()), args.esptool_output.read().split('\n')) + + +if __name__ == '__main__': + main() diff --git a/tools/test_idf_size/size_schema.json b/tools/test_idf_size/size_schema.json index 80c8bdeb4a2d..ea877d6708c7 100644 --- a/tools/test_idf_size/size_schema.json +++ b/tools/test_idf_size/size_schema.json @@ -77,10 +77,7 @@ "(^\\.flash\\.(rodata|text|appdesc|rodata_noload)$)": { "$ref": "#/$defs/archive_details" }, - "(^\\.flash_rodata_dummy$)": { - "$ref": "#/$defs/archive_details" - }, - "(^\\.iram0\\.(text|vectors|text_end|bss|data)$)": { + "(^\\.iram0\\.(text|vectors|bss|data)$)": { "$ref": "#/$defs/archive_details" }, "(^\\.rtc\\.(bss|data|text)$)": { diff --git a/tools/test_idf_size/test.sh b/tools/test_idf_size/test.sh index 12f07f044c95..9ad84455a549 100755 --- a/tools/test_idf_size/test.sh +++ b/tools/test_idf_size/test.sh @@ -1,7 +1,31 @@ #!/usr/bin/env bash -{ coverage debug sys \ - && coverage erase &> output \ + +memory_test () { + pushd $IDF_PATH/examples/get-started/hello_world \ + && echo -e "\n***\nBuilding project for $1..." &>> $IDF_PATH/tools/test_idf_size/output \ + && idf.py set-target $1 \ + && idf.py build \ + && echo -e "\n***\nRunning mem_test.py for $1..." &>> $IDF_PATH/tools/test_idf_size/output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json build/hello-world.map > size_output.json \ + && python $IDF_PATH/components/esptool_py/esptool/esptool.py --chip $1 image_info build/hello-world.bin > esptool_output \ + && python -m coverage run -a $IDF_PATH/tools/test_idf_size/mem_test.py size_output.json esptool_output &>> $IDF_PATH/tools/test_idf_size/output \ + && popd +} + +json_test() { + echo -e "\n***\nProducing JSON output for $1..." &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app_$1.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app_$1.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app_$1.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app_$1.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output +} + +{ python -m coverage debug sys \ + && python -m coverage erase &> output \ + && memory_test esp32 \ + && memory_test esp32s2 \ + && memory_test esp32c3 \ && echo -e "\n***\nRunning idf_size.py..." &>> output \ && coverage run -a $IDF_PATH/tools/idf_size.py app.map &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader..." &>> output \ @@ -101,21 +125,9 @@ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map --diff app2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map --diff app2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map --diff app2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && echo -e "\n***\nProducing JSON output for esp32s2..." &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app_esp32s2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app_esp32s2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app_esp32s2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app_esp32s2.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && echo -e "\n***\nProducing JSON output for esp32c3..." &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app_esp32c3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app_esp32c3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app_esp32c3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app_esp32c3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && echo -e "\n***\nProducing JSON output for esp32s3..." &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app_esp32s3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app_esp32s3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app_esp32s3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ - && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app_esp32s3.map | python $IDF_PATH/tools/test_idf_size/json_validate_test.py &>> output \ + && json_test esp32s2 \ + && json_test esp32c3 \ + && json_test esp32s3 \ && echo -e "\n***\nProducing JSON file output..." &>> output \ && coverage run -a $IDF_PATH/tools/idf_size.py --json --output-file output.json app.map &>> output \ && echo -e "\n***\nProducing text file output..." &>> output \ diff --git a/tools/test_idf_tools/test_idf_tools.py b/tools/test_idf_tools/test_idf_tools.py index 56ddb25c15fa..20ba4090cf3f 100755 --- a/tools/test_idf_tools/test_idf_tools.py +++ b/tools/test_idf_tools/test_idf_tools.py @@ -3,6 +3,7 @@ # SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 +import json import os import shutil import sys @@ -43,13 +44,29 @@ def redirect_stdout(target): XTENSA_ESP32S2_ELF = 'xtensa-esp32s2-elf' XTENSA_ESP32S3_ELF = 'xtensa-esp32s3-elf' -ESP32ULP_VERSION = '2.28.51-esp-20191205' -ESP32S2ULP_VERSION = '2.28.51-esp-20191205' -OPENOCD_VERSION = 'v0.10.0-esp32-20211111' -RISC_VERSION = 'esp-2021r2-8.4.0' -XTENSA_ESP32_ELF_VERSION = 'esp-2021r2-8.4.0' -XTENSA_ESP32S2_ELF_VERSION = 'esp-2021r2-8.4.0' -XTENSA_ESP32S3_ELF_VERSION = 'esp-2021r2-8.4.0' + +def get_version_dict(): + ''' + Return a dictionary with tool name to tool version mapping. + + It works with tools.json directly and not through idf_tools.py in order to bypass the script under test. This is + a little hacky but thanks to this, versions are not required to be updated here every time a tool is updated. + ''' + with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'tools.json')) as f: + tools_obj = json.loads(f.read()) + + return dict((tool['name'], tool['versions'][0]['name']) for tool in tools_obj['tools']) + + +version_dict = get_version_dict() + +ESP32ULP_VERSION = version_dict[ESP32ULP] +ESP32S2ULP_VERSION = version_dict[ESP32S2ULP] +OPENOCD_VERSION = version_dict[OPENOCD] +RISC_VERSION = version_dict[RISC] +XTENSA_ESP32_ELF_VERSION = version_dict[XTENSA_ESP32_ELF] +XTENSA_ESP32S2_ELF_VERSION = version_dict[XTENSA_ESP32S2_ELF] +XTENSA_ESP32S3_ELF_VERSION = version_dict[XTENSA_ESP32S3_ELF] class TestUsage(unittest.TestCase): diff --git a/tools/test_mkdfu/1/dfu.bin b/tools/test_mkdfu/1/dfu.bin index cc28754f3825..9c306c7229c2 100644 Binary files a/tools/test_mkdfu/1/dfu.bin and b/tools/test_mkdfu/1/dfu.bin differ diff --git a/tools/test_mkdfu/2/dfu.bin b/tools/test_mkdfu/2/dfu.bin index 31774a80cfcb..8f75cd404681 100644 Binary files a/tools/test_mkdfu/2/dfu.bin and b/tools/test_mkdfu/2/dfu.bin differ diff --git a/tools/test_mkdfu/test_mkdfu.py b/tools/test_mkdfu/test_mkdfu.py index 064614851856..40bf04a4cc9e 100755 --- a/tools/test_mkdfu/test_mkdfu.py +++ b/tools/test_mkdfu/test_mkdfu.py @@ -45,7 +45,8 @@ def common_test(self, json_input=None, file_args=[], output_to_compare=None, par self.addCleanup(os.unlink, f_out.name) args = [mkdfu_path, 'write', '-o', f_out.name, - '--pid', '2'] + '--pid', '2', + '--flash-size', '4MB'] if part_size: args += ['--part-size', str(part_size)] if json_input: @@ -55,6 +56,8 @@ def common_test(self, json_input=None, file_args=[], output_to_compare=None, par p = pexpect.spawn(sys.executable, args, timeout=10, encoding='utf-8') self.addCleanup(p.terminate, force=True) + p.expect_exact('Adding flash chip parameters file with flash_size = 4MB') + for addr, f_path in sorted(file_args, key=lambda e: e[0]): p.expect_exact('Adding {} at {}'.format(f_path, hex(addr))) @@ -114,7 +117,7 @@ class TestSplit(TestMkDFU): tests with images prepared in the "2" subdirectory "2/dfu.bin" was prepared with: - mkdfu.py write --part-size 5 --pid 2 -o 2/dfu.bin 0 bin + mkdfu.py write --part-size 5 --pid 2 --flash-size 4MB -o 2/dfu.bin 0 bin where the content of "bin" is b"\xce" * 10 ''' def test_split(self): diff --git a/tools/toolchain_versions.mk b/tools/toolchain_versions.mk index 05dfd3e4f66e..27b712945ba5 100644 --- a/tools/toolchain_versions.mk +++ b/tools/toolchain_versions.mk @@ -1,6 +1,6 @@ -SUPPORTED_TOOLCHAIN_COMMIT_DESC = esp-2021r2 +SUPPORTED_TOOLCHAIN_COMMIT_DESC = esp-2021r2-patch3 SUPPORTED_TOOLCHAIN_GCC_VERSIONS = 8.4.0 -CURRENT_TOOLCHAIN_COMMIT_DESC = esp-2021r2 -CURRENT_TOOLCHAIN_COMMIT_DESC_SHORT = esp-2021r2 +CURRENT_TOOLCHAIN_COMMIT_DESC = esp-2021r2-patch3 +CURRENT_TOOLCHAIN_COMMIT_DESC_SHORT = esp-2021r2-patch3 CURRENT_TOOLCHAIN_GCC_VERSION = 8.4.0 diff --git a/tools/tools.json b/tools/tools.json index 664b34d558be..6ceefe20c2a2 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -25,41 +25,46 @@ "versions": [ { "linux-amd64": { - "sha256": "3eb3d68b27fa6ba5af6f88da21cb8face9be0094daaa8960793cfe570ab785ff", - "size": 90565318, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-linux-amd64.tar.gz" + "sha256": "9edd1e77627688f435561922d14299f6a0021ba1f6ff67e472e1108695a69e53", + "size": 90569312, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-linux-amd64.tar.gz" }, "linux-arm64": { - "sha256": "aa534be24e45e06b7080a6a3bb8cd9e3cfb818f5f8bce2244d7cfb5e91336541", - "size": 86860292, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-linux-arm64.tar.gz" + "sha256": "3a21a3e310e6b1e7d7bed1f3e59698a5bd29ed3a5ca79fba9265d7dd2f1e0cd2", + "size": 86838362, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-linux-arm64.tar.gz" }, "linux-armel": { - "sha256": "f0e49ce06fe7833ff5d76961dc2dac5449d320f823bb8c05a302cf85a3a6eb04", - "size": 86183421, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-linux-armel.tar.gz" + "sha256": "89313c4c1d8db1b01624f31b58bf3fbe527160569828ac4301e9daa75c52716d", + "size": 86187540, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-linux-armel.tar.gz" + }, + "linux-armhf": { + "sha256": "ec07a9c75a0aa4b86496cacf2034154cd4a693b6f317c66a4a122c71fd04a518", + "size": 83298212, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-linux-armhf.tar.gz" }, "linux-i686": { - "sha256": "06de09b74652de43e5b22db3b7fc992623044baa75e9faaab68317a986715ba3", - "size": 92582250, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-linux-i686.tar.gz" + "sha256": "a1f165a836f175daa6fbfde4ca99cb93b377f021fbfc41f79a700bd4df965a9a", + "size": 92580267, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-linux-i686.tar.gz" }, "macos": { - "sha256": "96443f69c8569417c780ee749d91ef33cffe22153fffa30a0fbf12107d87381b", - "size": 97808961, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-macos.tar.gz" + "sha256": "dda3d7a43efd995d9a51d5a5741626dbf915df46078aef0b5aea7163ac82398b", + "size": 97807647, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-macos.tar.gz" }, - "name": "esp-2021r2-8.4.0", + "name": "esp-2021r2-patch3-8.4.0", "status": "recommended", "win32": { - "sha256": "eba06307022cc659e3c5345ecb3c620c99ec5d0d2a5cb59ac21c831edcbafc45", - "size": 116460829, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch1-win32.zip" + "sha256": "fd147592928ef2d7092ba34b01ecd776fe26ba3d7e3f9b6b215a3b46e981ee2c", + "size": 116464819, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-win32.zip" }, "win64": { - "sha256": "36a47c80fa79a867244f39794565c391cf4646d221c8f3e228bef45a5de1d32a", - "size": 119506634, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch1-win64.zip" + "sha256": "9395315c07de0b9f05c9a6616ba1f05e76ab651053f2f40479163a8e03cfa830", + "size": 119511910, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch3-win64.zip" } } ] @@ -89,41 +94,46 @@ "versions": [ { "linux-amd64": { - "sha256": "a6e0947c92b823ca04f062522249f0a428357e0b056f1ff4c6bcabef83cf63a7", - "size": 90901736, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-linux-amd64.tar.gz" + "sha256": "a32451a8edc1104b83cd9971178e61826e957d7db9ad9f81798a8969fd5a954e", + "size": 90894048, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-linux-amd64.tar.gz" }, "linux-arm64": { - "sha256": "d2e5600fc194b508bd393b236a09fd62ed70afb6c36619d4b106b696a56ca66d", - "size": 87176557, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-linux-arm64.tar.gz" + "sha256": "2ac2c94a533a99a091d2159c678c611c712c494b5f68d97913254712047260f9", + "size": 87178224, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-linux-arm64.tar.gz" }, "linux-armel": { - "sha256": "3fff4199e986dd74660f17ca27d9414cb98f1b911a7f13bb3b22e784cb1156cf", - "size": 86581102, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-linux-armel.tar.gz" + "sha256": "da49afee1e2e03eaab3f492718789442d33b562800e2a892679f95b50be24d14", + "size": 86569314, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-linux-armel.tar.gz" + }, + "linux-armhf": { + "sha256": "f2b9b89522f28547c8725a54c4e57e8a35dac56edc26aa8cd607c87a050249ac", + "size": 83700311, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-linux-armhf.tar.gz" }, "linux-i686": { - "sha256": "7732f9fb371d36b6b324820e300beecc33c2719921a61cf1cdb5bc625016b346", - "size": 92875986, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-linux-i686.tar.gz" + "sha256": "36d3c4990a5feb68aa8534463bc9e8ee367fe23886f78e1d726f4411c7571462", + "size": 92884013, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-linux-i686.tar.gz" }, "macos": { - "sha256": "e6dd32782fcff8f633299b97d1c671d6b6513390aca2ddbd7543c2cc62e72d7e", - "size": 98212907, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-macos.tar.gz" + "sha256": "de9af641678c93775e932ee5ec4f478f8925cfc1ebc22e41adc4fb85430a0c35", + "size": 98224709, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-macos.tar.gz" }, - "name": "esp-2021r2-8.4.0", + "name": "esp-2021r2-patch3-8.4.0", "status": "recommended", "win32": { - "sha256": "083458aed4e0e1efad3779098b5626dbb41cfe00892daf1ae1fde07f59ac40b9", - "size": 116905046, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch1-win32.zip" + "sha256": "ccf08afe60046f87b0e81ca17dc5073eda68ab5e7522c163dd5b583d713b7b39", + "size": 116924759, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-win32.zip" }, "win64": { - "sha256": "e535084882355d5f7587d79d4c0b6d135a318288acf50a5a2fe1b90dbc934b61", - "size": 119924946, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch1-win64.zip" + "sha256": "37c91490b8fc75e638c23785e261eaf553be2dcd106cf6cff5b76981fa02955b", + "size": 119912142, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch3-win64.zip" } } ] @@ -153,41 +163,46 @@ "versions": [ { "linux-amd64": { - "sha256": "b958eb47f51fc2a91e3beda78a331a380eb8c96d5452f7795adf3f565d7fca2f", - "size": 90887465, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-linux-amd64.tar.gz" + "sha256": "59b271d014ff3915b6db1b43b610a45eea15fe5d6877d12cae8a191cc996ed37", + "size": 90903617, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-linux-amd64.tar.gz" }, "linux-arm64": { - "sha256": "5fb122f1109a0b1aa7a42b6b48f56c854c0a84d13047a3bb0a78bdc737bf70e2", - "size": 87047917, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-linux-arm64.tar.gz" + "sha256": "7051b32483e61f98606d71c98e372929428a5165df791dcd5830ed9517763152", + "size": 87065204, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-linux-arm64.tar.gz" }, "linux-armel": { - "sha256": "d618be508629749110785ce0038b35959cc4e6953629e2dc6d65697425b905e1", - "size": 86448074, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-linux-armel.tar.gz" + "sha256": "48c8dbbf96eec691a812327dc580042d9718fe989e60c2111ebfd692ac710081", + "size": 86455731, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-linux-armel.tar.gz" + }, + "linux-armhf": { + "sha256": "efc037db5b3565d907c611ef9d17f156080949c0382feeaec86ed7b54d9fa2ae", + "size": 83561862, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-linux-armhf.tar.gz" }, "linux-i686": { - "sha256": "9701907da616992079d302acf5a04f97361b39ca3e74112690b2c896875f3a62", - "size": 92888291, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-linux-i686.tar.gz" + "sha256": "552dca3f4302ab7ca88a934b0391200198c9d10a4d8ac413fe604cbf8601f950", + "size": 92906274, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-linux-i686.tar.gz" }, "macos": { - "sha256": "d417885a5d150d94b3b84f68460b7af399a789cb0c7c632e222feed666c8aaea", - "size": 98564027, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-macos.tar.gz" + "sha256": "e5af78f05d3af07617805d06ebb45ff2fe9b6aed6970a84c35eea28a5d8d5e53", + "size": 98553473, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-macos.tar.gz" }, - "name": "esp-2021r2-8.4.0", + "name": "esp-2021r2-patch3-8.4.0", "status": "recommended", "win32": { - "sha256": "0985f5292370daad2bf228d80bcd51aacb060288a24c7d1965fddfb16e4e2613", - "size": 116862406, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch1-win32.zip" + "sha256": "1b70163acccc5655449de1d149427a54f384156bd35816ec60c422d76d033f05", + "size": 116847008, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-win32.zip" }, "win64": { - "sha256": "cb98c854017ffa3222ef1db9e76151364d6f22841b11b07e857363065be91d1f", - "size": 120052967, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch1-win64.zip" + "sha256": "58e58575d1938879fd51e822181e54bcb343aa846eb3fca8f616c2cde7bd0041", + "size": 120066269, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch3-win64.zip" } } ] @@ -217,41 +232,46 @@ "versions": [ { "linux-amd64": { - "sha256": "812d735063da9d063b374b59f55832a96c41fbd27ddaef19000a75de8607ba21", - "size": 106837189, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-linux-amd64.tar.gz" + "sha256": "179cbad579790ad35e0f414a18d90017c0f158c397022411a8e9867db2174f15", + "size": 106843321, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-linux-amd64.tar.gz" }, "linux-arm64": { - "sha256": "712f1fbc3e08304a6f32aa18b346b16bbcb413b507b3d4c7c3211bf0d7dc4813", - "size": 103273444, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-linux-arm64.tar.gz" + "sha256": "fb339d476c79c76db8f903b265cab6bb6950d5ed954dec644445252d3378023c", + "size": 103277393, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-linux-arm64.tar.gz" }, "linux-armel": { - "sha256": "80a3342cda2cd4b6b75ebb2b36d5d12fce7d375cfadadcff01ec3a907f0a16a2", - "size": 103058744, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-linux-armel.tar.gz" + "sha256": "51a6296d8334b7452dba44b2b62e87afd7fd1c74bafa1aa29b1f4ab72cb9e5e0", + "size": 103062256, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-linux-armel.tar.gz" + }, + "linux-armhf": { + "sha256": "faa723e2fe84154ea8081ef204d9db51c5b7e5702497dff4f3b33e250e42f776", + "size": 100134810, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-linux-armhf.tar.gz" }, "linux-i686": { - "sha256": "7f0162a81558ab0ed09d6c5d356def25b5cb3d5c2d61358f20152fa260ccc8ae", - "size": 109447789, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-linux-i686.tar.gz" + "sha256": "fef60f7ef37ffaa50416d8f244cdbd710d6729dae41ef06c4ec0e50a1f3b7dd7", + "size": 109460025, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-linux-i686.tar.gz" }, "macos": { - "sha256": "3ff7e5427907cf8e271c1f959b70fb01e39625c3caf61a6567e7b38aa0c11578", - "size": 113672945, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-macos.tar.gz" + "sha256": "4aacc1742a76349d790b1ac8e9e9d963daefda5346dbd6741cfe8e7a35a44e4e", + "size": 113703959, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-macos.tar.gz" }, - "name": "esp-2021r2-8.4.0", + "name": "esp-2021r2-patch3-8.4.0", "status": "recommended", "win32": { - "sha256": "f1ff7d2a87e1f1515371c1e4868b982e6a0958df144e2f1b2bd7e684ec1f9c93", - "size": 144692343, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch1-win32.zip" + "sha256": "eb2a442d7f551ebeb842995ec372ec4b364314ca2d7aae779399a74972f7d6bc", + "size": 144711970, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-win32.zip" }, "win64": { - "sha256": "791b8c8ed99934a2ec7f42100f2c71fb1ef7042efa7c6267c0d59394175c827a", - "size": 146593717, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch1-win64.zip" + "sha256": "f5607e5187317d521f0474cade83f8eb590f2d165d95c3779b6ce11fbac21d1f", + "size": 146606480, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch3/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-win64.zip" } } ] @@ -486,41 +506,41 @@ "versions": [ { "linux-amd64": { - "sha256": "eed0030e49206175fb564756c9210a6389347867b3528b16f50d725d47b45bf0", - "size": 1808044, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-linux-amd64-0.10.0-esp32-20211111.tar.gz" + "sha256": "3460945f3560ef673264a0259a33dcbf0dd18ac6b7b4862e89318655c62215c7", + "size": 1901040, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-linux-amd64-0.11.0-esp32-20211220.tar.gz" }, "linux-arm64": { - "sha256": "b4927173aa4230157d2f5019b3c51e94c880a0320c3ab7349cdc20c6b1c1eb14", - "size": 1702956, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-linux-arm64-0.10.0-esp32-20211111.tar.gz" + "sha256": "65d4de147d37c04e1c65d020e9c38e90db5a71e9e0bc602f5c8e0f44e46cd098", + "size": 1792274, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-linux-arm64-0.11.0-esp32-20211220.tar.gz" }, "linux-armel": { - "sha256": "590fe5427496ca94616796235803145aef74db2aad19bf25ee19e8c6ab7b94d4", - "size": 1841453, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-linux-armel-0.10.0-esp32-20211111.tar.gz" + "sha256": "4c03c5fdf73d9a4357cb5e2918c8e3d99900c7a1bb6d50e8712a8d38477398a0", + "size": 1943340, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-linux-armel-0.11.0-esp32-20211220.tar.gz" }, "linux-armhf": { - "sha256": "27d754dbc3fb02cd3e78503a4f348288dc473e0fadbe87ac83090bdb0de51b00", - "size": 1713102, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-linux-armhf-0.10.0-esp32-20211111.tar.gz" + "sha256": "acbb2bf74454ad2e45bab690538082cd6538a687ba2ba3d233309eb985702aba", + "size": 1803024, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-linux-armhf-0.11.0-esp32-20211220.tar.gz" }, "macos": { - "sha256": "bc194319a39f8bb03ce75dab39feb51a36fa528bdee8bb594ccdd30730990c2f", - "size": 1873988, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-macos-0.10.0-esp32-20211111.tar.gz" + "sha256": "689149120965a8c36c78c1852035b72f500f2a5b406f53624ed4c0a85c4e9a60", + "size": 1959080, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-macos-0.11.0-esp32-20211220.tar.gz" }, - "name": "v0.10.0-esp32-20211111", + "name": "v0.11.0-esp32-20211220", "status": "recommended", "win32": { - "sha256": "590ece2f7c1bf20a3bfadb8b82255d4735a8f4666c9cb897cc4584f72f3040fb", - "size": 2288659, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-win32-0.10.0-esp32-20211111.zip" + "sha256": "18f5515c4cecce5866e2f7cc7ff536f1a21a624e40a61d24c9dea4a910657cbb", + "size": 2441430, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-win32-0.11.0-esp32-20211220.zip" }, "win64": { - "sha256": "590ece2f7c1bf20a3bfadb8b82255d4735a8f4666c9cb897cc4584f72f3040fb", - "size": 2288659, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20211111/openocd-esp32-win32-0.10.0-esp32-20211111.zip" + "sha256": "18f5515c4cecce5866e2f7cc7ff536f1a21a624e40a61d24c9dea4a910657cbb", + "size": 2441430, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20211220/openocd-esp32-win32-0.11.0-esp32-20211220.zip" } } ] diff --git a/tools/unit-test-app/components/test_utils/include/test_utils.h b/tools/unit-test-app/components/test_utils/include/test_utils.h index a1b61d391450..56e73569018b 100644 --- a/tools/unit-test-app/components/test_utils/include/test_utils.h +++ b/tools/unit-test-app/components/test_utils/include/test_utils.h @@ -47,28 +47,28 @@ extern "C" { #define _TEST_PERFORMANCE_ASSERT(ARG) printf("Ignoring performance test [%s]\n", PERFORMANCE_STR(ARG)) #endif -#define TEST_PERFORMANCE_LESS_THAN(name, value_fmt, value) do { \ - printf("[Performance][" PERFORMANCE_STR(name) "]: "value_fmt"\n", value); \ +#define TEST_PERFORMANCE_LESS_THAN(name, value_fmt, value, ...) do { \ + IDF_LOG_PERFORMANCE(#name, value_fmt, value, ##__VA_ARGS__); \ _TEST_PERFORMANCE_ASSERT(value < PERFORMANCE_CON(IDF_PERFORMANCE_MAX_, name)); \ } while(0) -#define TEST_PERFORMANCE_GREATER_THAN(name, value_fmt, value) do { \ - printf("[Performance][" PERFORMANCE_STR(name) "]: "value_fmt"\n", value); \ +#define TEST_PERFORMANCE_GREATER_THAN(name, value_fmt, value, ...) do { \ + IDF_LOG_PERFORMANCE(#name, value_fmt, value, ##__VA_ARGS__); \ _TEST_PERFORMANCE_ASSERT(value > PERFORMANCE_CON(IDF_PERFORMANCE_MIN_, name)); \ } while(0) /* Macros to be used when performance is calculated using the cache compensated timer will not assert if ccomp not supported */ #if SOC_CCOMP_TIMER_SUPPORTED -#define TEST_PERFORMANCE_CCOMP_GREATER_THAN(name, value_fmt, value) \ - TEST_PERFORMANCE_GREATER_THAN(name, value_fmt, value) -#define TEST_PERFORMANCE_CCOMP_LESS_THAN(name, value_fmt, value) \ - TEST_PERFORMANCE_LESS_THAN(name, value_fmt, value) +#define TEST_PERFORMANCE_CCOMP_GREATER_THAN(name, value_fmt, value, ...) \ + TEST_PERFORMANCE_GREATER_THAN(name, value_fmt, value, ##__VA_ARGS__) +#define TEST_PERFORMANCE_CCOMP_LESS_THAN(name, value_fmt, value, ...) \ + TEST_PERFORMANCE_LESS_THAN(name, value_fmt, value, ##__VA_ARGS__) #else -#define TEST_PERFORMANCE_CCOMP_GREATER_THAN(name, value_fmt, value) \ - printf("[Performance][" PERFORMANCE_STR(name) "]: "value_fmt"\n", value); -#define TEST_PERFORMANCE_CCOMP_LESS_THAN(name, value_fmt, value) \ - printf("[Performance][" PERFORMANCE_STR(name) "]: "value_fmt"\n", value); +#define TEST_PERFORMANCE_CCOMP_GREATER_THAN(name, value_fmt, value, ...) \ + IDF_LOG_PERFORMANCE(#name, value_fmt, value, ##__VA_ARGS__) +#define TEST_PERFORMANCE_CCOMP_LESS_THAN(name, value_fmt, value, ...) \ + IDF_LOG_PERFORMANCE(#name, value_fmt, value, ##__VA_ARGS__) #endif //SOC_CCOMP_TIMER_SUPPORTED @@ -77,8 +77,8 @@ extern "C" { * @param value_fmt: print format and unit of the value, for example: "%02fms", "%dKB" * @param value : the performance value. */ -#define IDF_LOG_PERFORMANCE(item, value_fmt, value) \ - printf("[Performance][%s]: "value_fmt"\n", item, value) +#define IDF_LOG_PERFORMANCE(item, value_fmt, value, ...) \ + printf("[Performance][%s]: "value_fmt"\n", item, value, ##__VA_ARGS__) /* Some definitions applicable to Unity running in FreeRTOS */