mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-25 01:37:22 +00:00
move common source files from esp32 to esp_common
This commit is contained in:
@@ -16,15 +16,11 @@ else()
|
||||
"coexist.c"
|
||||
"cpu_start.c"
|
||||
"crosscore_int.c"
|
||||
"dbg_stubs.c"
|
||||
"dport_access.c"
|
||||
"dport_panic_highint_hdl.S"
|
||||
"esp_adapter.c"
|
||||
"esp_err_to_name.c"
|
||||
"esp_timer.c"
|
||||
"esp_timer_esp32.c"
|
||||
"esp_himem.c"
|
||||
"ets_timer_legacy.c"
|
||||
"fast_crypto_ops.c"
|
||||
"freertos_hooks.c"
|
||||
"gdbstub.c"
|
||||
@@ -36,14 +32,12 @@ else()
|
||||
"panic.c"
|
||||
"phy_init.c"
|
||||
"pm_esp32.c"
|
||||
"pm_locks.c"
|
||||
"pm_trace.c"
|
||||
"reset_reason.c"
|
||||
"restore.c"
|
||||
"sleep_modes.c"
|
||||
"spiram.c"
|
||||
"spiram_psram.c"
|
||||
"stack_check.c"
|
||||
"system_api.c"
|
||||
"task_wdt.c"
|
||||
"wifi_init.c"
|
||||
@@ -56,7 +50,7 @@ else()
|
||||
# app_update is added here because cpu_start.c uses esp_ota_get_app_description() function.
|
||||
set(COMPONENT_PRIV_REQUIRES
|
||||
app_trace app_update bootloader_support log mbedtls nvs_flash
|
||||
pthread smartconfig_ack spi_flash vfs wpa_supplicant xtensa-debug-module espcoredump)
|
||||
pthread smartconfig_ack spi_flash vfs wpa_supplicant xtensa-debug-module espcoredump esp_common)
|
||||
|
||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf ld/esp32_fragments.lf)
|
||||
|
||||
@@ -134,7 +128,7 @@ else()
|
||||
|
||||
# disable stack protection in files which are involved in initialization of that feature
|
||||
set_source_files_properties(
|
||||
stack_check.c cpu_start.c
|
||||
cpu_start.c
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
-fno-stack-protector)
|
||||
endif()
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_system_internal.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
|
@@ -53,5 +53,4 @@ esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
||||
COMPONENT_EXTRA_CLEAN := esp32_out.ld $(COMPONENT_BUILD_DIR)/esp32.project.ld
|
||||
|
||||
# disable stack protection in files which are involved in initialization of that feature
|
||||
stack_check.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS))
|
||||
cpu_start.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS))
|
||||
|
@@ -69,7 +69,7 @@
|
||||
#include "esp_clk_internal.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_pm.h"
|
||||
#include "pm_impl.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
#include "trax.h"
|
||||
#include "esp_ota_ops.h"
|
||||
|
||||
|
@@ -1,95 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// This module implements debug/trace stubs. The stub is a piece of special code which can invoked by OpenOCD
|
||||
// Currently one stub is used for GCOV functionality
|
||||
//
|
||||
|
||||
#include "eri.h"
|
||||
#include "xtensa-debug-module.h"
|
||||
#include "esp_dbg_stubs.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#if CONFIG_ESP32_DEBUG_STUBS_ENABLE
|
||||
/*
|
||||
Debug stubs is actually a table of 4-byte entries. Every entry is equal to zero or must contain meaningfull data.
|
||||
The first entry is a service one and has the followinf format:
|
||||
- tramp_addr, 4 bytes; Address of buffer for trampoline/code. Max size is ESP_DBG_STUBS_CODE_BUF_SIZE.
|
||||
- min_stack_addr, 4 bytes; Start of the buffer for minimal onboard stack or data. Max size is ESP_DBG_STUBS_STACK_MIN_SIZE.
|
||||
- data_alloc, 4 bytes; Address of function to allocate memory on target.
|
||||
- data_free, 4 bytes; Address of function to free target memory.
|
||||
This entry is used by OpenOCD code to invoke other stub entries and allocate memory for them.
|
||||
*/
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_dbg_stubs";
|
||||
|
||||
#define ESP_DBG_STUBS_TRAX_REG ERI_TRAX_TRIGGERPC
|
||||
#define ESP_DBG_STUBS_CODE_BUF_SIZE 32
|
||||
#define ESP_DBG_STUBS_STACK_MIN_SIZE 2048
|
||||
|
||||
#define DBG_STUB_TRAMP_ATTR IRAM_ATTR
|
||||
|
||||
static struct {
|
||||
uint32_t tramp_addr;
|
||||
uint32_t min_stack_addr; // minimal stack addr
|
||||
uint32_t data_alloc;
|
||||
uint32_t data_free;
|
||||
} s_dbg_stubs_ctl_data;
|
||||
|
||||
static uint32_t s_stub_entry[ESP_DBG_STUB_ENTRY_MAX];
|
||||
static uint8_t s_stub_min_stack[ESP_DBG_STUBS_STACK_MIN_SIZE];
|
||||
static DBG_STUB_TRAMP_ATTR uint8_t s_stub_code_buf[ESP_DBG_STUBS_CODE_BUF_SIZE];
|
||||
|
||||
// TODO: all called funcs should be in IRAM to work with disabled flash cache
|
||||
static void * esp_dbg_stubs_data_alloc(uint32_t size)
|
||||
{
|
||||
ESP_LOGV(TAG, "%s %d", __func__, size);
|
||||
void *p = malloc(size);
|
||||
ESP_LOGV(TAG, "%s EXIT %p", __func__, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void esp_dbg_stubs_data_free(void *addr)
|
||||
{
|
||||
ESP_LOGV(TAG, "%s %p", __func__, addr);
|
||||
free(addr);
|
||||
ESP_LOGV(TAG, "%s EXIT %p", __func__, addr);
|
||||
}
|
||||
|
||||
void esp_dbg_stubs_init()
|
||||
{
|
||||
s_dbg_stubs_ctl_data.tramp_addr = (uint32_t)s_stub_code_buf;
|
||||
s_dbg_stubs_ctl_data.min_stack_addr = (uint32_t)s_stub_min_stack;
|
||||
s_dbg_stubs_ctl_data.data_alloc = (uint32_t)esp_dbg_stubs_data_alloc;
|
||||
s_dbg_stubs_ctl_data.data_free = (uint32_t)esp_dbg_stubs_data_free;
|
||||
|
||||
s_stub_entry[ESP_DBG_STUB_CONTROL_DATA] = (uint32_t)&s_dbg_stubs_ctl_data;
|
||||
eri_write(ESP_DBG_STUBS_TRAX_REG, (uint32_t)s_stub_entry);
|
||||
ESP_LOGV(TAG, "%s stubs %x", __func__, eri_read(ESP_DBG_STUBS_TRAX_REG));
|
||||
}
|
||||
|
||||
esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry)
|
||||
{
|
||||
if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) {
|
||||
ESP_LOGE(TAG, "Invalid stub id %d!", id);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
s_stub_entry[id] = entry;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,581 +0,0 @@
|
||||
//Do not edit this file because it is autogenerated by gen_esp_err_to_name.py
|
||||
|
||||
#include <string.h>
|
||||
#if __has_include("soc/soc.h")
|
||||
#include "soc/soc.h"
|
||||
#endif
|
||||
#if __has_include("esp32/ulp.h")
|
||||
#include "esp32/ulp.h"
|
||||
#endif
|
||||
#if __has_include("esp_efuse.h")
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
#if __has_include("esp_err.h")
|
||||
#include "esp_err.h"
|
||||
#endif
|
||||
#if __has_include("esp_http_client.h")
|
||||
#include "esp_http_client.h"
|
||||
#endif
|
||||
#if __has_include("esp_http_server.h")
|
||||
#include "esp_http_server.h"
|
||||
#endif
|
||||
#if __has_include("esp_image_format.h")
|
||||
#include "esp_image_format.h"
|
||||
#endif
|
||||
#if __has_include("esp_mesh.h")
|
||||
#include "esp_mesh.h"
|
||||
#endif
|
||||
#if __has_include("esp_now.h")
|
||||
#include "esp_now.h"
|
||||
#endif
|
||||
#if __has_include("esp_ota_ops.h")
|
||||
#include "esp_ota_ops.h"
|
||||
#endif
|
||||
#if __has_include("esp_ping.h")
|
||||
#include "esp_ping.h"
|
||||
#endif
|
||||
#if __has_include("esp_spi_flash.h")
|
||||
#include "esp_spi_flash.h"
|
||||
#endif
|
||||
#if __has_include("esp_wifi.h")
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
#if __has_include("esp_wps.h")
|
||||
#include "esp_wps.h"
|
||||
#endif
|
||||
#if __has_include("nvs.h")
|
||||
#include "nvs.h"
|
||||
#endif
|
||||
#if __has_include("tcpip_adapter.h")
|
||||
#include "tcpip_adapter.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
#define ERR_TBL_IT(err) {err, #err}
|
||||
|
||||
typedef struct {
|
||||
esp_err_t code;
|
||||
const char *msg;
|
||||
} esp_err_msg_t;
|
||||
|
||||
static const esp_err_msg_t esp_err_msg_table[] = {
|
||||
// components/esp32/include/esp_err.h
|
||||
# ifdef ESP_FAIL
|
||||
ERR_TBL_IT(ESP_FAIL), /* -1 Generic esp_err_t code indicating failure */
|
||||
# endif
|
||||
# ifdef ESP_OK
|
||||
ERR_TBL_IT(ESP_OK), /* 0 esp_err_t value indicating success (no error) */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NO_MEM
|
||||
ERR_TBL_IT(ESP_ERR_NO_MEM), /* 257 0x101 Out of memory */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_ARG
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_ARG), /* 258 0x102 Invalid argument */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_STATE
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_STATE), /* 259 0x103 Invalid state */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_SIZE
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_SIZE), /* 260 0x104 Invalid size */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NOT_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_NOT_FOUND), /* 261 0x105 Requested resource not found */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NOT_SUPPORTED
|
||||
ERR_TBL_IT(ESP_ERR_NOT_SUPPORTED), /* 262 0x106 Operation or feature not supported */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TIMEOUT
|
||||
ERR_TBL_IT(ESP_ERR_TIMEOUT), /* 263 0x107 Operation timed out */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_RESPONSE
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_RESPONSE), /* 264 0x108 Received response was invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_CRC
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_CRC), /* 265 0x109 CRC or checksum was invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_VERSION
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_VERSION), /* 266 0x10a Version was invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_INVALID_MAC
|
||||
ERR_TBL_IT(ESP_ERR_INVALID_MAC), /* 267 0x10b MAC address was invalid */
|
||||
# endif
|
||||
// components/nvs_flash/include/nvs.h
|
||||
# ifdef ESP_ERR_NVS_BASE
|
||||
ERR_TBL_IT(ESP_ERR_NVS_BASE), /* 4352 0x1100 Starting number of error codes */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_NOT_INITIALIZED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_NOT_INITIALIZED), /* 4353 0x1101 The storage driver is not initialized */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_NOT_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_NVS_NOT_FOUND), /* 4354 0x1102 Id namespace doesn’t exist yet and mode is
|
||||
NVS_READONLY */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_TYPE_MISMATCH
|
||||
ERR_TBL_IT(ESP_ERR_NVS_TYPE_MISMATCH), /* 4355 0x1103 The type of set or get operation doesn't
|
||||
match the type of value stored in NVS */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_READ_ONLY
|
||||
ERR_TBL_IT(ESP_ERR_NVS_READ_ONLY), /* 4356 0x1104 Storage handle was opened as read only */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_NOT_ENOUGH_SPACE
|
||||
ERR_TBL_IT(ESP_ERR_NVS_NOT_ENOUGH_SPACE), /* 4357 0x1105 There is not enough space in the underlying
|
||||
storage to save the value */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_INVALID_NAME
|
||||
ERR_TBL_IT(ESP_ERR_NVS_INVALID_NAME), /* 4358 0x1106 Namespace name doesn’t satisfy constraints */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_INVALID_HANDLE
|
||||
ERR_TBL_IT(ESP_ERR_NVS_INVALID_HANDLE), /* 4359 0x1107 Handle has been closed or is NULL */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_REMOVE_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_REMOVE_FAILED), /* 4360 0x1108 The value wasn’t updated because flash write
|
||||
operation has failed. The value was written
|
||||
however, and update will be finished after
|
||||
re-initialization of nvs, provided that
|
||||
flash operation doesn’t fail again. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_KEY_TOO_LONG
|
||||
ERR_TBL_IT(ESP_ERR_NVS_KEY_TOO_LONG), /* 4361 0x1109 Key name is too long */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_PAGE_FULL
|
||||
ERR_TBL_IT(ESP_ERR_NVS_PAGE_FULL), /* 4362 0x110a Internal error; never returned by nvs API
|
||||
functions */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_INVALID_STATE
|
||||
ERR_TBL_IT(ESP_ERR_NVS_INVALID_STATE), /* 4363 0x110b NVS is in an inconsistent state due to a
|
||||
previous error. Call nvs_flash_init and
|
||||
nvs_open again, then retry. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_INVALID_LENGTH
|
||||
ERR_TBL_IT(ESP_ERR_NVS_INVALID_LENGTH), /* 4364 0x110c String or blob length is not sufficient to
|
||||
store data */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_NO_FREE_PAGES
|
||||
ERR_TBL_IT(ESP_ERR_NVS_NO_FREE_PAGES), /* 4365 0x110d NVS partition doesn't contain any empty
|
||||
pages. This may happen if NVS partition was
|
||||
truncated. Erase the whole partition and
|
||||
call nvs_flash_init again. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_VALUE_TOO_LONG
|
||||
ERR_TBL_IT(ESP_ERR_NVS_VALUE_TOO_LONG), /* 4366 0x110e String or blob length is longer than
|
||||
supported by the implementation */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_PART_NOT_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_NVS_PART_NOT_FOUND), /* 4367 0x110f Partition with specified name is not found
|
||||
in the partition table */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_NEW_VERSION_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_NVS_NEW_VERSION_FOUND), /* 4368 0x1110 NVS partition contains data in new format
|
||||
and cannot be recognized by this version of
|
||||
code */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_XTS_ENCR_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_XTS_ENCR_FAILED), /* 4369 0x1111 XTS encryption failed while writing NVS entry */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_XTS_DECR_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_XTS_DECR_FAILED), /* 4370 0x1112 XTS decryption failed while reading NVS entry */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_XTS_CFG_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_XTS_CFG_FAILED), /* 4371 0x1113 XTS configuration setting failed */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_XTS_CFG_NOT_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_NVS_XTS_CFG_NOT_FOUND), /* 4372 0x1114 XTS configuration not found */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_ENCR_NOT_SUPPORTED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_ENCR_NOT_SUPPORTED), /* 4373 0x1115 NVS encryption is not supported in this version */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_KEYS_NOT_INITIALIZED
|
||||
ERR_TBL_IT(ESP_ERR_NVS_KEYS_NOT_INITIALIZED), /* 4374 0x1116 NVS key partition is uninitialized */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_CORRUPT_KEY_PART
|
||||
ERR_TBL_IT(ESP_ERR_NVS_CORRUPT_KEY_PART), /* 4375 0x1117 NVS key partition is corrupt */
|
||||
# endif
|
||||
// components/ulp/include/esp32/ulp.h
|
||||
# ifdef ESP_ERR_ULP_BASE
|
||||
ERR_TBL_IT(ESP_ERR_ULP_BASE), /* 4608 0x1200 Offset for ULP-related error codes */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ULP_SIZE_TOO_BIG
|
||||
ERR_TBL_IT(ESP_ERR_ULP_SIZE_TOO_BIG), /* 4609 0x1201 Program doesn't fit into RTC memory reserved
|
||||
for the ULP */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ULP_INVALID_LOAD_ADDR
|
||||
ERR_TBL_IT(ESP_ERR_ULP_INVALID_LOAD_ADDR), /* 4610 0x1202 Load address is outside of RTC memory
|
||||
reserved for the ULP */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ULP_DUPLICATE_LABEL
|
||||
ERR_TBL_IT(ESP_ERR_ULP_DUPLICATE_LABEL), /* 4611 0x1203 More than one label with the same number was
|
||||
defined */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ULP_UNDEFINED_LABEL
|
||||
ERR_TBL_IT(ESP_ERR_ULP_UNDEFINED_LABEL), /* 4612 0x1204 Branch instructions references an undefined label */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ULP_BRANCH_OUT_OF_RANGE
|
||||
ERR_TBL_IT(ESP_ERR_ULP_BRANCH_OUT_OF_RANGE), /* 4613 0x1205 Branch target is out of range of B
|
||||
instruction (try replacing with BX) */
|
||||
# endif
|
||||
// components/app_update/include/esp_ota_ops.h
|
||||
# ifdef ESP_ERR_OTA_BASE
|
||||
ERR_TBL_IT(ESP_ERR_OTA_BASE), /* 5376 0x1500 Base error code for ota_ops api */
|
||||
# endif
|
||||
# ifdef ESP_ERR_OTA_PARTITION_CONFLICT
|
||||
ERR_TBL_IT(ESP_ERR_OTA_PARTITION_CONFLICT), /* 5377 0x1501 Error if request was to write or erase the
|
||||
current running partition */
|
||||
# endif
|
||||
# ifdef ESP_ERR_OTA_SELECT_INFO_INVALID
|
||||
ERR_TBL_IT(ESP_ERR_OTA_SELECT_INFO_INVALID), /* 5378 0x1502 Error if OTA data partition contains invalid
|
||||
content */
|
||||
# endif
|
||||
# ifdef ESP_ERR_OTA_VALIDATE_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_OTA_VALIDATE_FAILED), /* 5379 0x1503 Error if OTA app image is invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_OTA_SMALL_SEC_VER
|
||||
ERR_TBL_IT(ESP_ERR_OTA_SMALL_SEC_VER), /* 5380 0x1504 Error if the firmware has a secure version
|
||||
less than the running firmware. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_OTA_ROLLBACK_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_OTA_ROLLBACK_FAILED), /* 5381 0x1505 Error if flash does not have valid firmware
|
||||
in passive partition and hence rollback is
|
||||
not possible */
|
||||
# endif
|
||||
# ifdef ESP_ERR_OTA_ROLLBACK_INVALID_STATE
|
||||
ERR_TBL_IT(ESP_ERR_OTA_ROLLBACK_INVALID_STATE), /* 5382 0x1506 Error if current active firmware is still
|
||||
marked in pending validation state
|
||||
(ESP_OTA_IMG_PENDING_VERIFY), essentially
|
||||
first boot of firmware image post upgrade
|
||||
and hence firmware upgrade is not possible */
|
||||
# endif
|
||||
// components/efuse/include/esp_efuse.h
|
||||
# ifdef ESP_ERR_EFUSE
|
||||
ERR_TBL_IT(ESP_ERR_EFUSE), /* 5632 0x1600 Base error code for efuse api. */
|
||||
# endif
|
||||
# ifdef ESP_OK_EFUSE_CNT
|
||||
ERR_TBL_IT(ESP_OK_EFUSE_CNT), /* 5633 0x1601 OK the required number of bits is set. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_EFUSE_CNT_IS_FULL
|
||||
ERR_TBL_IT(ESP_ERR_EFUSE_CNT_IS_FULL), /* 5634 0x1602 Error field is full. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_EFUSE_REPEATED_PROG
|
||||
ERR_TBL_IT(ESP_ERR_EFUSE_REPEATED_PROG), /* 5635 0x1603 Error repeated programming of programmed
|
||||
bits is strictly forbidden. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_CODING
|
||||
ERR_TBL_IT(ESP_ERR_CODING), /* 5636 0x1604 Error while a encoding operation. */
|
||||
# endif
|
||||
// components/bootloader_support/include/esp_image_format.h
|
||||
# ifdef ESP_ERR_IMAGE_BASE
|
||||
ERR_TBL_IT(ESP_ERR_IMAGE_BASE), /* 8192 0x2000 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_IMAGE_FLASH_FAIL
|
||||
ERR_TBL_IT(ESP_ERR_IMAGE_FLASH_FAIL), /* 8193 0x2001 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_IMAGE_INVALID
|
||||
ERR_TBL_IT(ESP_ERR_IMAGE_INVALID), /* 8194 0x2002 */
|
||||
# endif
|
||||
// components/esp32/include/esp_err.h
|
||||
# ifdef ESP_ERR_WIFI_BASE
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_BASE), /* 12288 0x3000 Starting number of WiFi error codes */
|
||||
# endif
|
||||
// components/esp32/include/esp_wifi.h
|
||||
# ifdef ESP_ERR_WIFI_NOT_INIT
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_NOT_INIT), /* 12289 0x3001 WiFi driver was not installed by esp_wifi_init */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_NOT_STARTED
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_NOT_STARTED), /* 12290 0x3002 WiFi driver was not started by esp_wifi_start */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_NOT_STOPPED
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_NOT_STOPPED), /* 12291 0x3003 WiFi driver was not stopped by esp_wifi_stop */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_IF
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_IF), /* 12292 0x3004 WiFi interface error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_MODE
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_MODE), /* 12293 0x3005 WiFi mode error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_STATE
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_STATE), /* 12294 0x3006 WiFi internal state error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_CONN
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_CONN), /* 12295 0x3007 WiFi internal control block of station or
|
||||
soft-AP error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_NVS
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_NVS), /* 12296 0x3008 WiFi internal NVS module error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_MAC
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_MAC), /* 12297 0x3009 MAC address is invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_SSID
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_SSID), /* 12298 0x300a SSID is invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_PASSWORD
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_PASSWORD), /* 12299 0x300b Password is invalid */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_TIMEOUT
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_TIMEOUT), /* 12300 0x300c Timeout error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_WAKE_FAIL
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_WAKE_FAIL), /* 12301 0x300d WiFi is in sleep state(RF closed) and wakeup fail */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_WOULD_BLOCK
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_WOULD_BLOCK), /* 12302 0x300e The caller would block */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_NOT_CONNECT
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_NOT_CONNECT), /* 12303 0x300f Station still in disconnect status */
|
||||
# endif
|
||||
// components/esp32/include/esp_wps.h
|
||||
# ifdef ESP_ERR_WIFI_REGISTRAR
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_REGISTRAR), /* 12339 0x3033 WPS registrar is not supported */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_WPS_TYPE
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_WPS_TYPE), /* 12340 0x3034 WPS type error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_WIFI_WPS_SM
|
||||
ERR_TBL_IT(ESP_ERR_WIFI_WPS_SM), /* 12341 0x3035 WPS state machine is not initialized */
|
||||
# endif
|
||||
// components/esp32/include/esp_now.h
|
||||
# ifdef ESP_ERR_ESPNOW_BASE
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_BASE), /* 12388 0x3064 ESPNOW error number base. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_NOT_INIT
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_NOT_INIT), /* 12389 0x3065 ESPNOW is not initialized. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_ARG
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_ARG), /* 12390 0x3066 Invalid argument */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_NO_MEM
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_NO_MEM), /* 12391 0x3067 Out of memory */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_FULL
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_FULL), /* 12392 0x3068 ESPNOW peer list is full */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_NOT_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_NOT_FOUND), /* 12393 0x3069 ESPNOW peer is not found */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_INTERNAL
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_INTERNAL), /* 12394 0x306a Internal error */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_EXIST
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_EXIST), /* 12395 0x306b ESPNOW peer has existed */
|
||||
# endif
|
||||
# ifdef ESP_ERR_ESPNOW_IF
|
||||
ERR_TBL_IT(ESP_ERR_ESPNOW_IF), /* 12396 0x306c Interface error */
|
||||
# endif
|
||||
// components/esp32/include/esp_err.h
|
||||
# ifdef ESP_ERR_MESH_BASE
|
||||
ERR_TBL_IT(ESP_ERR_MESH_BASE), /* 16384 0x4000 Starting number of MESH error codes */
|
||||
# endif
|
||||
// components/esp32/include/esp_mesh.h
|
||||
# ifdef ESP_ERR_MESH_WIFI_NOT_START
|
||||
ERR_TBL_IT(ESP_ERR_MESH_WIFI_NOT_START), /* 16385 0x4001 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NOT_INIT
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NOT_INIT), /* 16386 0x4002 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NOT_CONFIG
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NOT_CONFIG), /* 16387 0x4003 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NOT_START
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NOT_START), /* 16388 0x4004 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NOT_SUPPORT
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NOT_SUPPORT), /* 16389 0x4005 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NOT_ALLOWED
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NOT_ALLOWED), /* 16390 0x4006 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NO_MEMORY
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NO_MEMORY), /* 16391 0x4007 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_ARGUMENT
|
||||
ERR_TBL_IT(ESP_ERR_MESH_ARGUMENT), /* 16392 0x4008 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_EXCEED_MTU
|
||||
ERR_TBL_IT(ESP_ERR_MESH_EXCEED_MTU), /* 16393 0x4009 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_TIMEOUT
|
||||
ERR_TBL_IT(ESP_ERR_MESH_TIMEOUT), /* 16394 0x400a */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_DISCONNECTED
|
||||
ERR_TBL_IT(ESP_ERR_MESH_DISCONNECTED), /* 16395 0x400b */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_QUEUE_FAIL
|
||||
ERR_TBL_IT(ESP_ERR_MESH_QUEUE_FAIL), /* 16396 0x400c */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_QUEUE_FULL
|
||||
ERR_TBL_IT(ESP_ERR_MESH_QUEUE_FULL), /* 16397 0x400d */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NO_PARENT_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NO_PARENT_FOUND), /* 16398 0x400e */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_NO_ROUTE_FOUND
|
||||
ERR_TBL_IT(ESP_ERR_MESH_NO_ROUTE_FOUND), /* 16399 0x400f */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_OPTION_NULL
|
||||
ERR_TBL_IT(ESP_ERR_MESH_OPTION_NULL), /* 16400 0x4010 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_OPTION_UNKNOWN
|
||||
ERR_TBL_IT(ESP_ERR_MESH_OPTION_UNKNOWN), /* 16401 0x4011 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_XON_NO_WINDOW
|
||||
ERR_TBL_IT(ESP_ERR_MESH_XON_NO_WINDOW), /* 16402 0x4012 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_INTERFACE
|
||||
ERR_TBL_IT(ESP_ERR_MESH_INTERFACE), /* 16403 0x4013 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_DISCARD_DUPLICATE
|
||||
ERR_TBL_IT(ESP_ERR_MESH_DISCARD_DUPLICATE), /* 16404 0x4014 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_DISCARD
|
||||
ERR_TBL_IT(ESP_ERR_MESH_DISCARD), /* 16405 0x4015 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_MESH_VOTING
|
||||
ERR_TBL_IT(ESP_ERR_MESH_VOTING), /* 16406 0x4016 */
|
||||
# endif
|
||||
// components/tcpip_adapter/include/tcpip_adapter.h
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_BASE
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_BASE), /* 20480 0x5000 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS), /* 20481 0x5001 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY), /* 20482 0x5002 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED), /* 20483 0x5003 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED), /* 20484 0x5004 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED), /* 20485 0x5005 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_NO_MEM
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_NO_MEM), /* 20486 0x5006 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED
|
||||
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED), /* 20487 0x5007 */
|
||||
# endif
|
||||
// components/lwip/include/apps/esp_ping.h
|
||||
# ifdef ESP_ERR_PING_BASE
|
||||
ERR_TBL_IT(ESP_ERR_PING_BASE), /* 24576 0x6000 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_PING_INVALID_PARAMS
|
||||
ERR_TBL_IT(ESP_ERR_PING_INVALID_PARAMS), /* 24577 0x6001 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_PING_NO_MEM
|
||||
ERR_TBL_IT(ESP_ERR_PING_NO_MEM), /* 24578 0x6002 */
|
||||
# endif
|
||||
// components/esp_http_client/include/esp_http_client.h
|
||||
# ifdef ESP_ERR_HTTP_BASE
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_BASE), /* 28672 0x7000 Starting number of HTTP error codes */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_MAX_REDIRECT
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_MAX_REDIRECT), /* 28673 0x7001 The error exceeds the number of HTTP redirects */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_CONNECT
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_CONNECT), /* 28674 0x7002 Error open the HTTP connection */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_WRITE_DATA
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_WRITE_DATA), /* 28675 0x7003 Error write HTTP data */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_FETCH_HEADER
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_FETCH_HEADER), /* 28676 0x7004 Error read HTTP header from server */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_INVALID_TRANSPORT
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_INVALID_TRANSPORT), /* 28677 0x7005 There are no transport support for the input
|
||||
scheme */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_CONNECTING
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_CONNECTING), /* 28678 0x7006 HTTP connection hasn't been established yet */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_EAGAIN
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_EAGAIN), /* 28679 0x7007 Mapping of errno EAGAIN to esp_err_t */
|
||||
# endif
|
||||
// components/esp_http_server/include/esp_http_server.h
|
||||
# ifdef ESP_ERR_HTTPD_BASE
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_BASE), /* 32768 0x8000 Starting number of HTTPD error codes */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_HANDLERS_FULL
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_HANDLERS_FULL), /* 32769 0x8001 All slots for registering URI handlers have
|
||||
been consumed */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_HANDLER_EXISTS
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_HANDLER_EXISTS), /* 32770 0x8002 URI handler with same method and target URI
|
||||
already registered */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_INVALID_REQ
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_INVALID_REQ), /* 32771 0x8003 Invalid request pointer */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_RESULT_TRUNC
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_RESULT_TRUNC), /* 32772 0x8004 Result string truncated */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_RESP_HDR
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_RESP_HDR), /* 32773 0x8005 Response header field larger than supported */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_RESP_SEND
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_RESP_SEND), /* 32774 0x8006 Error occured while sending response packet */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_ALLOC_MEM
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_ALLOC_MEM), /* 32775 0x8007 Failed to dynamically allocate memory for
|
||||
resource */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTPD_TASK
|
||||
ERR_TBL_IT(ESP_ERR_HTTPD_TASK), /* 32776 0x8008 Failed to launch server task/thread */
|
||||
# endif
|
||||
// components/spi_flash/include/esp_spi_flash.h
|
||||
# ifdef ESP_ERR_FLASH_BASE
|
||||
ERR_TBL_IT(ESP_ERR_FLASH_BASE), /* 65552 0x10010 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_FLASH_OP_FAIL
|
||||
ERR_TBL_IT(ESP_ERR_FLASH_OP_FAIL), /* 65553 0x10011 */
|
||||
# endif
|
||||
# ifdef ESP_ERR_FLASH_OP_TIMEOUT
|
||||
ERR_TBL_IT(ESP_ERR_FLASH_OP_TIMEOUT), /* 65554 0x10012 */
|
||||
# endif
|
||||
};
|
||||
#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
|
||||
static const char esp_unknown_msg[] =
|
||||
#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
"ERROR";
|
||||
#else
|
||||
"UNKNOWN ERROR";
|
||||
#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
|
||||
const char *esp_err_to_name(esp_err_t code)
|
||||
{
|
||||
#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(esp_err_msg_table)/sizeof(esp_err_msg_table[0]); ++i) {
|
||||
if (esp_err_msg_table[i].code == code) {
|
||||
return esp_err_msg_table[i].msg;
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
|
||||
return esp_unknown_msg;
|
||||
}
|
||||
|
||||
const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen)
|
||||
{
|
||||
#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(esp_err_msg_table)/sizeof(esp_err_msg_table[0]); ++i) {
|
||||
if (esp_err_msg_table[i].code == code) {
|
||||
strlcpy(buf, esp_err_msg_table[i].msg, buflen);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
|
||||
|
||||
if (strerror_r(code, buf, buflen) == 0) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
snprintf(buf, buflen, "%s 0x%x(%d)", esp_unknown_msg, code, code);
|
||||
|
||||
return buf;
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
/**
|
||||
* @brief Internal function to restart PRO and APP CPUs.
|
||||
*
|
||||
* @note This function should not be called from FreeRTOS applications.
|
||||
* Use esp_restart instead.
|
||||
*
|
||||
* This is an internal function called by esp_restart. It is called directly
|
||||
* by the panic handler and brownout detector interrupt.
|
||||
*/
|
||||
void esp_restart_noos() __attribute__ ((noreturn));
|
||||
|
||||
/**
|
||||
* @brief Internal function to set reset reason hint
|
||||
*
|
||||
* The hint is used do distinguish different reset reasons when software reset
|
||||
* is performed.
|
||||
*
|
||||
* The hint is stored in RTC store register, RTC_RESET_CAUSE_REG.
|
||||
*
|
||||
* @param hint Desired esp_reset_reason_t value for the real reset reason
|
||||
*/
|
||||
void esp_reset_reason_set_hint(esp_reset_reason_t hint);
|
||||
|
||||
/**
|
||||
* @brief Internal function to get the reset hint value
|
||||
* @return - Reset hint value previously stored into RTC_RESET_CAUSE_REG using
|
||||
* esp_reset_reason_set_hint function
|
||||
* - ESP_RST_UNKNOWN if the value in RTC_RESET_CAUSE_REG is invalid
|
||||
*/
|
||||
esp_reset_reason_t esp_reset_reason_get_hint(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,516 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_task.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_timer_impl.h"
|
||||
|
||||
#ifdef CONFIG_ESP_TIMER_PROFILING
|
||||
#define WITH_PROFILING 1
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Enable built-in checks in queue.h in debug builds
|
||||
#define INVARIANTS
|
||||
#endif
|
||||
#include "sys/queue.h"
|
||||
|
||||
#define TIMER_EVENT_QUEUE_SIZE 16
|
||||
|
||||
struct esp_timer {
|
||||
uint64_t alarm;
|
||||
uint64_t period;
|
||||
esp_timer_cb_t callback;
|
||||
void* arg;
|
||||
#if WITH_PROFILING
|
||||
const char* name;
|
||||
size_t times_triggered;
|
||||
size_t times_armed;
|
||||
uint64_t total_callback_run_time;
|
||||
#endif // WITH_PROFILING
|
||||
LIST_ENTRY(esp_timer) list_entry;
|
||||
};
|
||||
|
||||
static bool is_initialized();
|
||||
static esp_err_t timer_insert(esp_timer_handle_t timer);
|
||||
static esp_err_t timer_remove(esp_timer_handle_t timer);
|
||||
static bool timer_armed(esp_timer_handle_t timer);
|
||||
static void timer_list_lock();
|
||||
static void timer_list_unlock();
|
||||
|
||||
#if WITH_PROFILING
|
||||
static void timer_insert_inactive(esp_timer_handle_t timer);
|
||||
static void timer_remove_inactive(esp_timer_handle_t timer);
|
||||
#endif // WITH_PROFILING
|
||||
|
||||
static const char* TAG = "esp_timer";
|
||||
|
||||
// list of currently armed timers
|
||||
static LIST_HEAD(esp_timer_list, esp_timer) s_timers =
|
||||
LIST_HEAD_INITIALIZER(s_timers);
|
||||
#if WITH_PROFILING
|
||||
// list of unarmed timers, used only to be able to dump statistics about
|
||||
// all the timers
|
||||
static LIST_HEAD(esp_inactive_timer_list, esp_timer) s_inactive_timers =
|
||||
LIST_HEAD_INITIALIZER(s_timers);
|
||||
// used to keep track of the timer when executing the callback
|
||||
static esp_timer_handle_t s_timer_in_callback;
|
||||
#endif
|
||||
// task used to dispatch timer callbacks
|
||||
static TaskHandle_t s_timer_task;
|
||||
// counting semaphore used to notify the timer task from ISR
|
||||
static SemaphoreHandle_t s_timer_semaphore;
|
||||
// mutex which protects timers from deletion during callback execution
|
||||
static SemaphoreHandle_t s_timer_delete_mutex;
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
// memory for s_timer_semaphore and s_timer_delete_mutex
|
||||
static StaticQueue_t s_timer_semaphore_memory;
|
||||
static StaticQueue_t s_timer_delete_mutex_memory;
|
||||
#endif
|
||||
|
||||
// lock protecting s_timers, s_inactive_timers, s_timer_in_callback
|
||||
static portMUX_TYPE s_timer_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
|
||||
|
||||
esp_err_t esp_timer_create(const esp_timer_create_args_t* args,
|
||||
esp_timer_handle_t* out_handle)
|
||||
{
|
||||
if (!is_initialized()) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (args->callback == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_timer_handle_t result = (esp_timer_handle_t) calloc(1, sizeof(*result));
|
||||
if (result == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
result->callback = args->callback;
|
||||
result->arg = args->arg;
|
||||
#if WITH_PROFILING
|
||||
result->name = args->name;
|
||||
timer_insert_inactive(result);
|
||||
#endif
|
||||
*out_handle = result;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us)
|
||||
{
|
||||
if (!is_initialized() || timer_armed(timer)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
timer->alarm = esp_timer_get_time() + timeout_us;
|
||||
timer->period = 0;
|
||||
#if WITH_PROFILING
|
||||
timer->times_armed++;
|
||||
#endif
|
||||
return timer_insert(timer);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period_us)
|
||||
{
|
||||
if (!is_initialized() || timer_armed(timer)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
period_us = MAX(period_us, esp_timer_impl_get_min_period_us());
|
||||
timer->alarm = esp_timer_get_time() + period_us;
|
||||
timer->period = period_us;
|
||||
#if WITH_PROFILING
|
||||
timer->times_armed++;
|
||||
#endif
|
||||
return timer_insert(timer);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_timer_stop(esp_timer_handle_t timer)
|
||||
{
|
||||
if (!is_initialized() || !timer_armed(timer)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return timer_remove(timer);
|
||||
}
|
||||
|
||||
esp_err_t esp_timer_delete(esp_timer_handle_t timer)
|
||||
{
|
||||
if (timer == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (timer_armed(timer)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
xSemaphoreTakeRecursive(s_timer_delete_mutex, portMAX_DELAY);
|
||||
#if WITH_PROFILING
|
||||
if (timer == s_timer_in_callback) {
|
||||
s_timer_in_callback = NULL;
|
||||
}
|
||||
timer_remove_inactive(timer);
|
||||
#endif
|
||||
free(timer);
|
||||
xSemaphoreGiveRecursive(s_timer_delete_mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t timer_insert(esp_timer_handle_t timer)
|
||||
{
|
||||
timer_list_lock();
|
||||
#if WITH_PROFILING
|
||||
timer_remove_inactive(timer);
|
||||
#endif
|
||||
esp_timer_handle_t it, last = NULL;
|
||||
if (LIST_FIRST(&s_timers) == NULL) {
|
||||
LIST_INSERT_HEAD(&s_timers, timer, list_entry);
|
||||
} else {
|
||||
LIST_FOREACH(it, &s_timers, list_entry) {
|
||||
if (timer->alarm < it->alarm) {
|
||||
LIST_INSERT_BEFORE(it, timer, list_entry);
|
||||
break;
|
||||
}
|
||||
last = it;
|
||||
}
|
||||
if (it == NULL) {
|
||||
assert(last);
|
||||
LIST_INSERT_AFTER(last, timer, list_entry);
|
||||
}
|
||||
}
|
||||
if (timer == LIST_FIRST(&s_timers)) {
|
||||
esp_timer_impl_set_alarm(timer->alarm);
|
||||
}
|
||||
timer_list_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t timer_remove(esp_timer_handle_t timer)
|
||||
{
|
||||
timer_list_lock();
|
||||
LIST_REMOVE(timer, list_entry);
|
||||
timer->alarm = 0;
|
||||
timer->period = 0;
|
||||
#if WITH_PROFILING
|
||||
timer_insert_inactive(timer);
|
||||
#endif
|
||||
timer_list_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if WITH_PROFILING
|
||||
|
||||
static IRAM_ATTR void timer_insert_inactive(esp_timer_handle_t timer)
|
||||
{
|
||||
/* May be locked or not, depending on where this is called from.
|
||||
* Lock recursively.
|
||||
*/
|
||||
timer_list_lock();
|
||||
esp_timer_handle_t head = LIST_FIRST(&s_inactive_timers);
|
||||
if (head == NULL) {
|
||||
LIST_INSERT_HEAD(&s_inactive_timers, timer, list_entry);
|
||||
} else {
|
||||
/* Insert as head element as this is the fastest thing to do.
|
||||
* Removal is O(1) anyway.
|
||||
*/
|
||||
LIST_INSERT_BEFORE(head, timer, list_entry);
|
||||
}
|
||||
timer_list_unlock();
|
||||
}
|
||||
|
||||
static IRAM_ATTR void timer_remove_inactive(esp_timer_handle_t timer)
|
||||
{
|
||||
timer_list_lock();
|
||||
LIST_REMOVE(timer, list_entry);
|
||||
timer_list_unlock();
|
||||
}
|
||||
|
||||
#endif // WITH_PROFILING
|
||||
|
||||
static IRAM_ATTR bool timer_armed(esp_timer_handle_t timer)
|
||||
{
|
||||
return timer->alarm > 0;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void timer_list_lock()
|
||||
{
|
||||
portENTER_CRITICAL(&s_timer_lock);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void timer_list_unlock()
|
||||
{
|
||||
portEXIT_CRITICAL(&s_timer_lock);
|
||||
}
|
||||
|
||||
static void timer_process_alarm(esp_timer_dispatch_t dispatch_method)
|
||||
{
|
||||
/* unused, provision to allow running callbacks from ISR */
|
||||
(void) dispatch_method;
|
||||
|
||||
xSemaphoreTakeRecursive(s_timer_delete_mutex, portMAX_DELAY);
|
||||
timer_list_lock();
|
||||
uint64_t now = esp_timer_impl_get_time();
|
||||
esp_timer_handle_t it = LIST_FIRST(&s_timers);
|
||||
while (it != NULL &&
|
||||
it->alarm < now) {
|
||||
LIST_REMOVE(it, list_entry);
|
||||
if (it->period > 0) {
|
||||
it->alarm += it->period;
|
||||
timer_insert(it);
|
||||
} else {
|
||||
it->alarm = 0;
|
||||
#if WITH_PROFILING
|
||||
timer_insert_inactive(it);
|
||||
#endif
|
||||
}
|
||||
#if WITH_PROFILING
|
||||
uint64_t callback_start = now;
|
||||
s_timer_in_callback = it;
|
||||
#endif
|
||||
timer_list_unlock();
|
||||
(*it->callback)(it->arg);
|
||||
timer_list_lock();
|
||||
now = esp_timer_impl_get_time();
|
||||
#if WITH_PROFILING
|
||||
/* The callback might have deleted the timer.
|
||||
* If this happens, esp_timer_delete will set s_timer_in_callback
|
||||
* to NULL.
|
||||
*/
|
||||
if (s_timer_in_callback) {
|
||||
s_timer_in_callback->times_triggered++;
|
||||
s_timer_in_callback->total_callback_run_time += now - callback_start;
|
||||
}
|
||||
#endif
|
||||
it = LIST_FIRST(&s_timers);
|
||||
}
|
||||
esp_timer_handle_t first = LIST_FIRST(&s_timers);
|
||||
if (first) {
|
||||
esp_timer_impl_set_alarm(first->alarm);
|
||||
}
|
||||
timer_list_unlock();
|
||||
xSemaphoreGiveRecursive(s_timer_delete_mutex);
|
||||
}
|
||||
|
||||
static void timer_task(void* arg)
|
||||
{
|
||||
while (true){
|
||||
int res = xSemaphoreTake(s_timer_semaphore, portMAX_DELAY);
|
||||
assert(res == pdTRUE);
|
||||
timer_process_alarm(ESP_TIMER_TASK);
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR timer_alarm_handler(void* arg)
|
||||
{
|
||||
int need_yield;
|
||||
if (xSemaphoreGiveFromISR(s_timer_semaphore, &need_yield) != pdPASS) {
|
||||
ESP_EARLY_LOGD(TAG, "timer queue overflow");
|
||||
return;
|
||||
}
|
||||
if (need_yield == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool is_initialized()
|
||||
{
|
||||
return s_timer_task != NULL;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_timer_init(void)
|
||||
{
|
||||
esp_err_t err;
|
||||
if (is_initialized()) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
memset(&s_timer_semaphore_memory, 0, sizeof(StaticQueue_t));
|
||||
s_timer_semaphore = xSemaphoreCreateCountingStatic(TIMER_EVENT_QUEUE_SIZE, 0, &s_timer_semaphore_memory);
|
||||
#else
|
||||
s_timer_semaphore = xSemaphoreCreateCounting(TIMER_EVENT_QUEUE_SIZE, 0);
|
||||
#endif
|
||||
if (!s_timer_semaphore) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
memset(&s_timer_delete_mutex_memory, 0, sizeof(StaticQueue_t));
|
||||
s_timer_delete_mutex = xSemaphoreCreateRecursiveMutexStatic(&s_timer_delete_mutex_memory);
|
||||
#else
|
||||
s_timer_delete_mutex = xSemaphoreCreateRecursiveMutex();
|
||||
#endif
|
||||
if (!s_timer_delete_mutex) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
int ret = xTaskCreatePinnedToCore(&timer_task, "esp_timer",
|
||||
ESP_TASK_TIMER_STACK, NULL, ESP_TASK_TIMER_PRIO, &s_timer_task, PRO_CPU_NUM);
|
||||
if (ret != pdPASS) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = esp_timer_impl_init(&timer_alarm_handler);
|
||||
if (err != ESP_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
out:
|
||||
if (s_timer_task) {
|
||||
vTaskDelete(s_timer_task);
|
||||
s_timer_task = NULL;
|
||||
}
|
||||
if (s_timer_semaphore) {
|
||||
vSemaphoreDelete(s_timer_semaphore);
|
||||
s_timer_semaphore = NULL;
|
||||
}
|
||||
if (s_timer_delete_mutex) {
|
||||
vSemaphoreDelete(s_timer_delete_mutex);
|
||||
s_timer_delete_mutex = NULL;
|
||||
}
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_timer_deinit(void)
|
||||
{
|
||||
if (!is_initialized()) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* Check if there are any active timers */
|
||||
if (!LIST_EMPTY(&s_timers)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* We can only check if there are any timers which are not deleted if
|
||||
* profiling is enabled.
|
||||
*/
|
||||
#if WITH_PROFILING
|
||||
if (!LIST_EMPTY(&s_inactive_timers)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_timer_impl_deinit();
|
||||
|
||||
vTaskDelete(s_timer_task);
|
||||
s_timer_task = NULL;
|
||||
vSemaphoreDelete(s_timer_semaphore);
|
||||
s_timer_semaphore = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void print_timer_info(esp_timer_handle_t t, char** dst, size_t* dst_size)
|
||||
{
|
||||
size_t cb = snprintf(*dst, *dst_size,
|
||||
#if WITH_PROFILING
|
||||
"%-12s %12lld %12lld %9d %9d %12lld\n",
|
||||
t->name, t->period, t->alarm,
|
||||
t->times_armed, t->times_triggered, t->total_callback_run_time);
|
||||
/* keep this in sync with the format string, used in esp_timer_dump */
|
||||
#define TIMER_INFO_LINE_LEN 78
|
||||
#else
|
||||
"timer@%p %12lld %12lld\n", t, t->period, t->alarm);
|
||||
#define TIMER_INFO_LINE_LEN 46
|
||||
#endif
|
||||
*dst += cb;
|
||||
*dst_size -= cb;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_timer_dump(FILE* stream)
|
||||
{
|
||||
/* Since timer lock is a critical section, we don't want to print directly
|
||||
* to stdout, since that may cause a deadlock if stdout is interrupt-driven
|
||||
* (via the UART driver). Allocate sufficiently large chunk of memory first,
|
||||
* print to it, then dump this memory to stdout.
|
||||
*/
|
||||
|
||||
esp_timer_handle_t it;
|
||||
|
||||
/* First count the number of timers */
|
||||
size_t timer_count = 0;
|
||||
timer_list_lock();
|
||||
LIST_FOREACH(it, &s_timers, list_entry) {
|
||||
++timer_count;
|
||||
}
|
||||
#if WITH_PROFILING
|
||||
LIST_FOREACH(it, &s_inactive_timers, list_entry) {
|
||||
++timer_count;
|
||||
}
|
||||
#endif
|
||||
timer_list_unlock();
|
||||
|
||||
/* Allocate the memory for this number of timers. Since we have unlocked,
|
||||
* we may find that there are more timers. There's no bulletproof solution
|
||||
* for this (can't allocate from a critical section), but we allocate
|
||||
* slightly more and the output will be truncated if that is not enough.
|
||||
*/
|
||||
size_t buf_size = TIMER_INFO_LINE_LEN * (timer_count + 3);
|
||||
char* print_buf = calloc(1, buf_size + 1);
|
||||
if (print_buf == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Print to the buffer */
|
||||
timer_list_lock();
|
||||
char* pos = print_buf;
|
||||
LIST_FOREACH(it, &s_timers, list_entry) {
|
||||
print_timer_info(it, &pos, &buf_size);
|
||||
}
|
||||
#if WITH_PROFILING
|
||||
LIST_FOREACH(it, &s_inactive_timers, list_entry) {
|
||||
print_timer_info(it, &pos, &buf_size);
|
||||
}
|
||||
#endif
|
||||
timer_list_unlock();
|
||||
|
||||
/* Print the buffer */
|
||||
fputs(print_buf, stream);
|
||||
|
||||
free(print_buf);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int64_t IRAM_ATTR esp_timer_get_next_alarm()
|
||||
{
|
||||
int64_t next_alarm = INT64_MAX;
|
||||
timer_list_lock();
|
||||
esp_timer_handle_t it = LIST_FIRST(&s_timers);
|
||||
if (it) {
|
||||
next_alarm = it->alarm;
|
||||
}
|
||||
timer_list_unlock();
|
||||
return next_alarm;
|
||||
}
|
||||
|
||||
int64_t IRAM_ATTR esp_timer_get_time()
|
||||
{
|
||||
return (int64_t) esp_timer_impl_get_time();
|
||||
}
|
@@ -20,7 +20,7 @@
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp_timer_impl.h"
|
||||
#include "esp_private/esp_timer_impl.h"
|
||||
#include "soc/frc_timer_reg.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@@ -78,7 +78,7 @@
|
||||
/* ALARM_OVERFLOW_VAL is used as timer alarm value when there are not timers
|
||||
* enabled which need to fire within the next timer overflow period. This alarm
|
||||
* is used to perform timekeeping (i.e. to track timer overflows).
|
||||
* Due to the 0xffffffff cannot recognize the real overflow or the scenario that
|
||||
* Due to the 0xffffffff cannot recognize the real overflow or the scenario that
|
||||
* ISR happens follow set_alarm, so change the ALARM_OVERFLOW_VAL to resolve this problem.
|
||||
* Set it to 0xefffffffUL. The remain 0x10000000UL(about 3 second) is enough to handle ISR.
|
||||
*/
|
||||
@@ -129,9 +129,9 @@ static bool s_mask_overflow;
|
||||
|
||||
//The timer_overflow_happened read alarm register to tell if overflow happened.
|
||||
//However, there is a monent that overflow happens, and before ISR function called
|
||||
//alarm register is set to another value, then you call timer_overflow_happened,
|
||||
//alarm register is set to another value, then you call timer_overflow_happened,
|
||||
//it will return false.
|
||||
//So we store the overflow value when new alarm is to be set.
|
||||
//So we store the overflow value when new alarm is to be set.
|
||||
static bool s_overflow_happened;
|
||||
|
||||
#ifdef CONFIG_PM_DFS_USE_RTC_TIMER_REF
|
||||
@@ -157,7 +157,7 @@ static inline bool IRAM_ATTR timer_overflow_happened()
|
||||
}
|
||||
|
||||
return ((REG_READ(FRC_TIMER_CTRL_REG(1)) & FRC_TIMER_INT_STATUS) != 0 &&
|
||||
((REG_READ(FRC_TIMER_ALARM_REG(1)) == ALARM_OVERFLOW_VAL && TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_COUNT_REG(1))) && !s_mask_overflow) ||
|
||||
((REG_READ(FRC_TIMER_ALARM_REG(1)) == ALARM_OVERFLOW_VAL && TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_COUNT_REG(1))) && !s_mask_overflow) ||
|
||||
(!TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_ALARM_REG(1))) && TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_COUNT_REG(1))))));
|
||||
}
|
||||
|
||||
|
@@ -1,101 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file esp_timer_impl.h
|
||||
*
|
||||
* @brief Interface between common and platform-specific parts of esp_timer.
|
||||
*
|
||||
* The functions in this header file are implemented for each supported SoC.
|
||||
* High level functions defined in esp_timer.c call the functions here to
|
||||
* interact with the hardware.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize platform specific layer of esp_timer
|
||||
* @param alarm_handler function to call on timer interrupt
|
||||
* @return ESP_OK, ESP_ERR_NO_MEM, or one of the errors from interrupt allocator
|
||||
*/
|
||||
esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize platform specific layer of esp_timer
|
||||
*/
|
||||
void esp_timer_impl_deinit();
|
||||
|
||||
/**
|
||||
* @brief Set up the timer interrupt to fire at a particular time
|
||||
*
|
||||
* If the alarm time is too close in the future, implementation should set the
|
||||
* alarm to the earliest time possible.
|
||||
*
|
||||
* @param timestamp time in microseconds when interrupt should fire (relative to
|
||||
* boot time, i.e. as returned by esp_timer_impl_get_time)
|
||||
*/
|
||||
void esp_timer_impl_set_alarm(uint64_t timestamp);
|
||||
|
||||
/**
|
||||
* @brief Notify esp_timer implementation that APB frequency has changed
|
||||
*
|
||||
* Called by the frequency switching code.
|
||||
*
|
||||
* @param apb_ticks_per_us new number of APB clock ticks per microsecond
|
||||
*/
|
||||
void esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us);
|
||||
|
||||
/**
|
||||
* @brief Adjust current esp_timer time by a certain value
|
||||
*
|
||||
* Called from light sleep code to synchronize esp_timer time with RTC time.
|
||||
*
|
||||
* @param time_us adjustment to apply to esp_timer time, in microseconds
|
||||
*/
|
||||
void esp_timer_impl_advance(int64_t time_us);
|
||||
|
||||
/**
|
||||
* @brief Get time, in microseconds, since esp_timer_impl_init was called
|
||||
* @return timestamp in microseconds
|
||||
*/
|
||||
uint64_t esp_timer_impl_get_time();
|
||||
|
||||
/**
|
||||
* @brief Get minimal timer period, in microseconds
|
||||
* Periods shorter than the one returned may not be possible to achieve due to
|
||||
* interrupt latency and context switch time. Short period of periodic timer may
|
||||
* cause the system to spend all the time servicing the interrupt and timer
|
||||
* callback, preventing other tasks from running.
|
||||
* @return minimal period of periodic timer, in microseconds
|
||||
*/
|
||||
uint64_t esp_timer_impl_get_min_period_us();
|
||||
|
||||
/**
|
||||
* @brief obtain internal critical section used esp_timer implementation
|
||||
* This can be used when a sequence of calls to esp_timer has to be made,
|
||||
* and it is necessary that the state of the timer is consistent between
|
||||
* the calls. Should be treated in the same way as a spinlock.
|
||||
* Call esp_timer_impl_unlock to release the lock
|
||||
*/
|
||||
void esp_timer_impl_lock();
|
||||
|
||||
|
||||
/**
|
||||
* @brief counterpart of esp_timer_impl_lock
|
||||
*/
|
||||
void esp_timer_impl_unlock();
|
@@ -1,126 +0,0 @@
|
||||
// Copyright 2010-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.
|
||||
|
||||
/*
|
||||
* ets_timer module implements a set of legacy timer APIs which are
|
||||
* used by the WiFi driver. This is done on top of the newer esp_timer APIs.
|
||||
* Applications should not use ets_timer functions, as they may change without
|
||||
* notice.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_types.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "soc/frc_timer_reg.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_timer_impl.h"
|
||||
|
||||
/* We abuse 'timer_arg' field of ETSTimer structure to hold a pointer to esp_timer */
|
||||
#define ESP_TIMER(p_ets_timer) ((esp_timer_handle_t) (p_ets_timer)->timer_arg)
|
||||
|
||||
/* We abuse 'timer_expire' field of ETSTimer structure to hold a magic value
|
||||
* signifying that the contents of the timer was zeroed out.
|
||||
*/
|
||||
#define TIMER_INITIALIZED_FIELD(p_ets_timer) ((p_ets_timer)->timer_expire)
|
||||
#define TIMER_INITIALIZED_VAL 0x12121212
|
||||
|
||||
static IRAM_ATTR bool timer_initialized(ETSTimer *ptimer)
|
||||
{
|
||||
return TIMER_INITIALIZED_FIELD(ptimer) == TIMER_INITIALIZED_VAL;
|
||||
}
|
||||
|
||||
void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg)
|
||||
{
|
||||
if (!timer_initialized(ptimer)) {
|
||||
memset(ptimer, 0, sizeof(*ptimer));
|
||||
TIMER_INITIALIZED_FIELD(ptimer) = TIMER_INITIALIZED_VAL;
|
||||
}
|
||||
|
||||
if (ESP_TIMER(ptimer) == NULL) {
|
||||
const esp_timer_create_args_t create_args = {
|
||||
.callback = pfunction,
|
||||
.arg = parg,
|
||||
.name = "ETSTimer",
|
||||
.dispatch_method = ESP_TIMER_TASK
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK( esp_timer_create(&create_args, (esp_timer_handle_t*)&(ptimer->timer_arg)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IRAM_ATTR ets_timer_arm_us(ETSTimer *ptimer, uint32_t time_us, bool repeat_flag)
|
||||
{
|
||||
assert(timer_initialized(ptimer));
|
||||
esp_timer_stop(ESP_TIMER(ptimer)); // no error check
|
||||
if (!repeat_flag) {
|
||||
ESP_ERROR_CHECK( esp_timer_start_once(ESP_TIMER(ptimer), time_us) );
|
||||
} else {
|
||||
ESP_ERROR_CHECK( esp_timer_start_periodic(ESP_TIMER(ptimer), time_us) );
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR ets_timer_arm(ETSTimer *ptimer, uint32_t time_ms, bool repeat_flag)
|
||||
{
|
||||
uint64_t time_us = 1000LL * (uint64_t) time_ms;
|
||||
assert(timer_initialized(ptimer));
|
||||
esp_timer_stop(ESP_TIMER(ptimer)); // no error check
|
||||
if (!repeat_flag) {
|
||||
ESP_ERROR_CHECK( esp_timer_start_once(ESP_TIMER(ptimer), time_us) );
|
||||
} else {
|
||||
ESP_ERROR_CHECK( esp_timer_start_periodic(ESP_TIMER(ptimer), time_us) );
|
||||
}
|
||||
}
|
||||
|
||||
void ets_timer_done(ETSTimer *ptimer)
|
||||
{
|
||||
if (timer_initialized(ptimer)) {
|
||||
esp_timer_delete(ESP_TIMER(ptimer));
|
||||
ptimer->timer_arg = NULL;
|
||||
TIMER_INITIALIZED_FIELD(ptimer) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR ets_timer_disarm(ETSTimer *ptimer)
|
||||
{
|
||||
if (timer_initialized(ptimer)) {
|
||||
esp_timer_stop(ESP_TIMER(ptimer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ets_timer_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ets_timer_deinit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void os_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg) __attribute__((alias("ets_timer_setfn")));
|
||||
void os_timer_disarm(ETSTimer *ptimer) __attribute__((alias("ets_timer_disarm")));
|
||||
void os_timer_arm_us(ETSTimer *ptimer,uint32_t u_seconds,bool repeat_flag) __attribute__((alias("ets_timer_arm_us")));
|
||||
void os_timer_arm(ETSTimer *ptimer,uint32_t milliseconds,bool repeat_flag) __attribute__((alias("ets_timer_arm")));
|
||||
void os_timer_done(ETSTimer *ptimer) __attribute__((alias("ets_timer_done")));
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_pm.h"
|
||||
#include "pm_impl.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
|
||||
//We use just a static array here because it's not expected many components will need
|
||||
//an idle or tick hook.
|
||||
|
@@ -40,7 +40,7 @@
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp32/cache_err_int.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_system_internal.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#if CONFIG_SYSVIEW_ENABLE
|
||||
|
@@ -31,9 +31,9 @@
|
||||
#include "freertos/xtensa_timer.h"
|
||||
#include "xtensa/core-macros.h"
|
||||
|
||||
#include "pm_impl.h"
|
||||
#include "pm_trace.h"
|
||||
#include "esp_timer_impl.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
#include "esp_private/pm_trace.h"
|
||||
#include "esp_private/esp_timer_impl.h"
|
||||
#include "esp32/pm.h"
|
||||
|
||||
/* CCOMPARE update timeout, in CPU cycles. Any value above ~600 cycles will work
|
||||
|
@@ -1,121 +0,0 @@
|
||||
// Copyright 2016-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.
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file pm_impl.h
|
||||
*
|
||||
* This header file defines interface between PM lock functions (pm_locks.c)
|
||||
* and the chip-specific power management (DFS/light sleep) implementation.
|
||||
*/
|
||||
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_timer.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
/**
|
||||
* This is an enum of possible power modes supported by the implementation
|
||||
*/
|
||||
typedef enum {
|
||||
PM_MODE_LIGHT_SLEEP,//!< Light sleep
|
||||
PM_MODE_APB_MIN, //!< Idle (no CPU frequency or APB frequency locks)
|
||||
PM_MODE_APB_MAX, //!< Maximum APB frequency mode
|
||||
PM_MODE_CPU_MAX, //!< Maximum CPU frequency mode
|
||||
PM_MODE_COUNT //!< Number of items
|
||||
} pm_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Get the mode corresponding to a certain lock
|
||||
* @param type lock type
|
||||
* @param arg argument value for this lock (passed to esp_pm_lock_create)
|
||||
* @return lowest power consumption mode which meets the constraints of the lock
|
||||
*/
|
||||
pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg);
|
||||
|
||||
/**
|
||||
* If profiling is enabled, this data type will be used to store microsecond
|
||||
* timestamps.
|
||||
*/
|
||||
typedef int64_t pm_time_t;
|
||||
|
||||
/**
|
||||
* See \ref esp_pm_impl_switch_mode
|
||||
*/
|
||||
typedef enum {
|
||||
MODE_LOCK,
|
||||
MODE_UNLOCK
|
||||
} pm_mode_switch_t;
|
||||
|
||||
/**
|
||||
* @brief Switch between power modes when lock is taken or released
|
||||
* @param mode pm_mode_t corresponding to the lock being taken or released,
|
||||
* as returned by \ref esp_pm_impl_get_mode
|
||||
* @param lock_or_unlock
|
||||
* - MODE_LOCK: lock was taken. Implementation needs to make sure
|
||||
* that the constraints of the lock are met by switching to the
|
||||
* given 'mode' or any of the higher power ones.
|
||||
* - MODE_UNLOCK: lock was released. If all the locks for given
|
||||
* mode are released, and no locks for higher power modes are
|
||||
* taken, implementation can switch to one of lower power modes.
|
||||
* @param now timestamp when the lock was taken or released. Passed as
|
||||
* a minor optimization, so that the implementation does not need to
|
||||
* call pm_get_time again.
|
||||
*/
|
||||
void esp_pm_impl_switch_mode(pm_mode_t mode, pm_mode_switch_t lock_or_unlock, pm_time_t now);
|
||||
|
||||
/**
|
||||
* @brief Call once at startup to initialize pm implementation
|
||||
*/
|
||||
void esp_pm_impl_init();
|
||||
|
||||
/**
|
||||
* @brief Hook function for the idle task
|
||||
* Must be called from the IDLE task on each CPU before entering waiti state.
|
||||
*/
|
||||
void esp_pm_impl_idle_hook();
|
||||
|
||||
/**
|
||||
* @brief Hook function for the interrupt dispatcher
|
||||
* Must be called soon after entering the ISR
|
||||
*/
|
||||
void esp_pm_impl_isr_hook();
|
||||
|
||||
/**
|
||||
* @brief Dump the information about time spent in each of the pm modes.
|
||||
*
|
||||
* Prints three columns:
|
||||
* mode name, total time in mode (in microseconds), percentage of time in mode
|
||||
*
|
||||
* @param out stream to dump the information to
|
||||
*/
|
||||
void esp_pm_impl_dump_stats(FILE* out);
|
||||
|
||||
/**
|
||||
* @brief Hook function implementing `waiti` instruction, should be invoked from idle task context
|
||||
*/
|
||||
void esp_pm_impl_waiti();
|
||||
|
||||
#ifdef CONFIG_PM_PROFILING
|
||||
#define WITH_PROFILING
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PROFILING
|
||||
static inline pm_time_t IRAM_ATTR pm_get_time()
|
||||
{
|
||||
return esp_timer_get_time();
|
||||
}
|
||||
#endif // WITH_PROFILING
|
@@ -1,205 +0,0 @@
|
||||
// Copyright 2016-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.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/lock.h>
|
||||
#include "esp_pm.h"
|
||||
#include "esp_system.h"
|
||||
#include "sys/queue.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "pm_impl.h"
|
||||
#include "esp_timer.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
typedef struct esp_pm_lock {
|
||||
esp_pm_lock_type_t type; /*!< type passed to esp_pm_lock_create */
|
||||
int arg; /*!< argument passed to esp_pm_lock_create */
|
||||
pm_mode_t mode; /*!< implementation-defined mode for this type of lock*/
|
||||
const char* name; /*!< used to identify the lock */
|
||||
SLIST_ENTRY(esp_pm_lock) next; /*!< linked list pointer */
|
||||
size_t count; /*!< lock count */
|
||||
portMUX_TYPE spinlock; /*!< spinlock used when operating on 'count' */
|
||||
#ifdef WITH_PROFILING
|
||||
pm_time_t last_taken; /*!< time what the lock was taken (valid if count > 0) */
|
||||
pm_time_t time_held; /*!< total time the lock was taken.
|
||||
If count > 0, this doesn't include the time since last_taken */
|
||||
size_t times_taken; /*!< number of times the lock was ever taken */
|
||||
#endif
|
||||
} esp_pm_lock_t;
|
||||
|
||||
|
||||
static const char* s_lock_type_names[] = {
|
||||
"CPU_FREQ_MAX",
|
||||
"APB_FREQ_MAX",
|
||||
"NO_LIGHT_SLEEP"
|
||||
};
|
||||
|
||||
/* List of all existing locks, used for esp_pm_dump_locks */
|
||||
static SLIST_HEAD(esp_pm_locks_head, esp_pm_lock) s_list =
|
||||
SLIST_HEAD_INITIALIZER(s_head);
|
||||
/* Protects the above list */
|
||||
static _lock_t s_list_lock;
|
||||
|
||||
|
||||
esp_err_t esp_pm_lock_create(esp_pm_lock_type_t lock_type, int arg,
|
||||
const char* name, esp_pm_lock_handle_t* out_handle)
|
||||
{
|
||||
#ifndef CONFIG_PM_ENABLE
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
if (out_handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_pm_lock_t* new_lock = (esp_pm_lock_t*) calloc(1, sizeof(*new_lock));
|
||||
if (!new_lock) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
new_lock->type = lock_type;
|
||||
new_lock->arg = arg;
|
||||
new_lock->mode = esp_pm_impl_get_mode(lock_type, arg);
|
||||
new_lock->name = name;
|
||||
new_lock->spinlock = (portMUX_TYPE) portMUX_INITIALIZER_UNLOCKED;
|
||||
*out_handle = new_lock;
|
||||
|
||||
_lock_acquire(&s_list_lock);
|
||||
SLIST_INSERT_HEAD(&s_list, new_lock, next);
|
||||
_lock_release(&s_list_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_pm_lock_delete(esp_pm_lock_handle_t handle)
|
||||
{
|
||||
#ifndef CONFIG_PM_ENABLE
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
if (handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (handle->count > 0) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
_lock_acquire(&s_list_lock);
|
||||
SLIST_REMOVE(&s_list, handle, esp_pm_lock, next);
|
||||
_lock_release(&s_list_lock);
|
||||
free(handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_pm_lock_acquire(esp_pm_lock_handle_t handle)
|
||||
{
|
||||
#ifndef CONFIG_PM_ENABLE
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
if (handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&handle->spinlock);
|
||||
if (handle->count++ == 0) {
|
||||
pm_time_t now = 0;
|
||||
#ifdef WITH_PROFILING
|
||||
now = pm_get_time();
|
||||
#endif
|
||||
esp_pm_impl_switch_mode(handle->mode, MODE_LOCK, now);
|
||||
#ifdef WITH_PROFILING
|
||||
handle->last_taken = now;
|
||||
handle->times_taken++;
|
||||
#endif
|
||||
}
|
||||
portEXIT_CRITICAL(&handle->spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_pm_lock_release(esp_pm_lock_handle_t handle)
|
||||
{
|
||||
#ifndef CONFIG_PM_ENABLE
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
if (handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
portENTER_CRITICAL(&handle->spinlock);
|
||||
if (handle->count == 0) {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
goto out;
|
||||
}
|
||||
if (--handle->count == 0) {
|
||||
pm_time_t now = 0;
|
||||
#ifdef WITH_PROFILING
|
||||
now = pm_get_time();
|
||||
handle->time_held += now - handle->last_taken;
|
||||
#endif
|
||||
esp_pm_impl_switch_mode(handle->mode, MODE_UNLOCK, now);
|
||||
}
|
||||
out:
|
||||
portEXIT_CRITICAL(&handle->spinlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_pm_dump_locks(FILE* stream)
|
||||
{
|
||||
#ifndef CONFIG_PM_ENABLE
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PROFILING
|
||||
pm_time_t cur_time = pm_get_time();
|
||||
pm_time_t cur_time_d100 = cur_time / 100;
|
||||
#endif // WITH_PROFILING
|
||||
|
||||
_lock_acquire(&s_list_lock);
|
||||
#ifdef WITH_PROFILING
|
||||
fprintf(stream, "Time: %lld\n", cur_time);
|
||||
#endif
|
||||
|
||||
fprintf(stream, "Lock stats:\n");
|
||||
esp_pm_lock_t* it;
|
||||
SLIST_FOREACH(it, &s_list, next) {
|
||||
portENTER_CRITICAL(&it->spinlock);
|
||||
if (it->name == NULL) {
|
||||
fprintf(stream, "lock@%p ", it);
|
||||
} else {
|
||||
fprintf(stream, "%-15s ", it->name);
|
||||
}
|
||||
#ifdef WITH_PROFILING
|
||||
pm_time_t time_held = it->time_held;
|
||||
if (it->count > 0) {
|
||||
time_held += cur_time - it->last_taken;
|
||||
}
|
||||
fprintf(stream, "%10s %3d %3d %9d %9lld %3lld%%\n",
|
||||
s_lock_type_names[it->type], it->arg,
|
||||
it->count, it->times_taken, time_held,
|
||||
(time_held + cur_time_d100 - 1) / cur_time_d100);
|
||||
#else
|
||||
fprintf(stream, "%10s %3d %3d\n", s_lock_type_names[it->type], it->arg, it->count);
|
||||
#endif // WITH_PROFILING
|
||||
portEXIT_CRITICAL(&it->spinlock);
|
||||
}
|
||||
_lock_release(&s_list_lock);
|
||||
#ifdef WITH_PROFILING
|
||||
esp_pm_impl_dump_stats(stream);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include "pm_trace.h"
|
||||
#include "esp_private/pm_trace.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
|
||||
|
@@ -1,45 +0,0 @@
|
||||
// Copyright 2016-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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
typedef enum {
|
||||
ESP_PM_TRACE_IDLE,
|
||||
ESP_PM_TRACE_TICK,
|
||||
ESP_PM_TRACE_FREQ_SWITCH,
|
||||
ESP_PM_TRACE_CCOMPARE_UPDATE,
|
||||
ESP_PM_TRACE_ISR_HOOK,
|
||||
ESP_PM_TRACE_SLEEP,
|
||||
ESP_PM_TRACE_TYPE_MAX
|
||||
} esp_pm_trace_event_t;
|
||||
|
||||
void esp_pm_trace_init();
|
||||
void esp_pm_trace_enter(esp_pm_trace_event_t event, int core_id);
|
||||
void esp_pm_trace_exit(esp_pm_trace_event_t event, int core_id);
|
||||
|
||||
#ifdef CONFIG_PM_TRACE
|
||||
|
||||
#define ESP_PM_TRACE_ENTER(event, core_id) \
|
||||
esp_pm_trace_enter(ESP_PM_TRACE_ ## event, core_id)
|
||||
#define ESP_PM_TRACE_EXIT(event, core_id) \
|
||||
esp_pm_trace_exit(ESP_PM_TRACE_ ## event, core_id)
|
||||
|
||||
#else // CONFIG_PM_TRACE
|
||||
|
||||
#define ESP_PM_TRACE_ENTER(type, core_id) do { (void) core_id; } while(0)
|
||||
#define ESP_PM_TRACE_EXIT(type, core_id) do { (void) core_id; } while(0)
|
||||
|
||||
#endif // CONFIG_PM_TRACE
|
@@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_system_internal.h"
|
||||
#include "esp32/rom/rtc.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
static void esp_reset_reason_clear_hint();
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <sys/param.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_timer_impl.h"
|
||||
#include "esp_private/esp_timer_impl.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp_newlib.h"
|
||||
|
@@ -1,39 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#if CONFIG_STACK_CHECK
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "stack_chk";
|
||||
|
||||
void *__stack_chk_guard = NULL;
|
||||
|
||||
static void __attribute__ ((constructor))
|
||||
__esp_stack_guard_setup (void)
|
||||
{
|
||||
ESP_LOGD(TAG, "Intialize random stack guard");
|
||||
__stack_chk_guard = (void *)esp_random();
|
||||
}
|
||||
|
||||
void __stack_chk_fail (void)
|
||||
{
|
||||
ets_printf("\r\nStack smashing protect failure!\r\n\r\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif
|
@@ -36,7 +36,7 @@
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_system_internal.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include "driver/timer.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp_system_internal.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
|
||||
static const char *TAG = "task_wdt";
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ". ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
set(COMPONENT_REQUIRES unity test_utils nvs_flash ulp)
|
||||
set(COMPONENT_REQUIRES unity test_utils nvs_flash ulp esp_common)
|
||||
|
||||
register_component()
|
||||
|
||||
@@ -21,7 +21,7 @@ execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_cry
|
||||
COMMAND cut -c 1-7
|
||||
OUTPUT_VARIABLE WIFI_CRYPTO_MD5
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
|
||||
# Calculate MD5 value of header file esp_coexist_adapter.h
|
||||
execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_coexist_adapter.h
|
||||
COMMAND cut -c 1-7
|
||||
@@ -34,4 +34,4 @@ add_definitions(-DCOEX_ADAPTER_MD5=\"${COEX_ADAPTER_MD5}\")
|
||||
|
||||
add_custom_target(esp32_test_logo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h")
|
||||
|
||||
add_dependencies(${COMPONENT_TARGET} esp32_test_logo)
|
||||
add_dependencies(${COMPONENT_TARGET} esp32_test_logo)
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "test_utils.h"
|
||||
#include "../esp_timer_impl.h"
|
||||
#include "esp_private/esp_timer_impl.h"
|
||||
|
||||
#ifdef CONFIG_ESP_TIMER_PROFILING
|
||||
#define WITH_PROFILING 1
|
||||
|
Reference in New Issue
Block a user