forked from espressif/esp-idf
Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ab8f793ca | ||
|
|
1e36383909 | ||
|
|
1e8fca74f2 | ||
|
|
32c63fca90 | ||
|
|
4921446d3d | ||
|
|
96a00e59f4 | ||
|
|
36c2ef2828 | ||
|
|
8491705b63 | ||
|
|
2c5f35fa8a | ||
|
|
e632f2b366 | ||
|
|
72f4f9542c | ||
|
|
cbe42f1132 | ||
|
|
8aa7eaa646 | ||
|
|
d21e948381 | ||
|
|
b50a8e0878 | ||
|
|
fa734e6af8 | ||
|
|
ca44fb1528 | ||
|
|
f8b9cb2864 | ||
|
|
7b70154566 | ||
|
|
fd50bcf704 | ||
|
|
c1e204634f | ||
|
|
96d00c5fa5 | ||
|
|
054d3b81a6 | ||
|
|
daeaa8092b | ||
|
|
56b4596b53 | ||
|
|
bebc75af48 | ||
|
|
71cf821659 | ||
|
|
652e214f55 | ||
|
|
345e6acf80 | ||
|
|
e8e6021ada | ||
|
|
df0ca79bdb | ||
|
|
ca77bdddbf | ||
|
|
e459f7b498 | ||
|
|
841aca897c | ||
|
|
b860069c10 | ||
|
|
bb1aa0ed5e | ||
|
|
481da3143d | ||
|
|
536d6eea61 | ||
|
|
176ea97dd0 | ||
|
|
ca2a15dca7 | ||
|
|
5d88861dba | ||
|
|
f8e633a352 | ||
|
|
9e40c13d4e | ||
|
|
6e0c046bd9 | ||
|
|
9e1324fbbb | ||
|
|
95c118171a | ||
|
|
2af8fac1d9 | ||
|
|
93c28d1fac | ||
|
|
97ed80f415 | ||
|
|
b18f37b2e2 | ||
|
|
0ca5134d5f | ||
|
|
a7c17edc8a | ||
|
|
bab80796ca | ||
|
|
c219c9dcb2 | ||
|
|
e892fed593 | ||
|
|
18a262a6fa | ||
|
|
7988705558 | ||
|
|
8e7f7dfe59 | ||
|
|
b257ad7d9e | ||
|
|
4d95ffcca2 | ||
|
|
adb20fb2f3 | ||
|
|
a8227a1d13 | ||
|
|
d2715324e5 | ||
|
|
2deea3b1b0 | ||
|
|
e60640ab04 | ||
|
|
899c7852a4 | ||
|
|
be74e06e50 | ||
|
|
d3e730ff57 | ||
|
|
06bf491f13 | ||
|
|
54bf4dccfa | ||
|
|
d9ec7df393 | ||
|
|
71cddbdf8f | ||
|
|
a699475df2 | ||
|
|
b5976a7167 | ||
|
|
1c7340d229 | ||
|
|
b3e1829f10 | ||
|
|
2515cd72c1 | ||
|
|
8a841d7cdf | ||
|
|
31d05a5072 | ||
|
|
bfb7c66a9f | ||
|
|
3bb84e7738 | ||
|
|
ff4ca61cc6 | ||
|
|
f195a1d8ae | ||
|
|
d52331849e | ||
|
|
d29cce7f0a | ||
|
|
6b47fcdbdc | ||
|
|
9a2362b5c7 | ||
|
|
abe7a9d020 | ||
|
|
9f63baf061 | ||
|
|
bf4320ba68 | ||
|
|
5c175721e9 | ||
|
|
78ea042e7d | ||
|
|
af7b21851e | ||
|
|
974b8dd4c4 | ||
|
|
87da4bccd4 | ||
|
|
c68f520389 | ||
|
|
232786235b | ||
|
|
61fdb62c54 | ||
|
|
c4155d4b47 | ||
|
|
34e8265821 | ||
|
|
3ebcb25fb1 | ||
|
|
7223c8db5b | ||
|
|
fc7bf950f3 | ||
|
|
c37b15fa22 | ||
|
|
e3fd4b097b | ||
|
|
86141ad01c | ||
|
|
223cf48c26 | ||
|
|
6d9d40e888 | ||
|
|
45c90be913 | ||
|
|
e7dc6eb8da | ||
|
|
56e7cb0c70 | ||
|
|
ad095f555b | ||
|
|
e349f1b484 | ||
|
|
be8295a918 | ||
|
|
c8912b79a6 | ||
|
|
ec510fdf18 | ||
|
|
e8f5b76112 | ||
|
|
0f0cfb2cbc | ||
|
|
62589fa251 | ||
|
|
f16e8cb48e | ||
|
|
532912b025 | ||
|
|
176d6fa4d0 | ||
|
|
7ad3837244 | ||
|
|
e7f75e6559 | ||
|
|
03e6d07b50 | ||
|
|
c71b1f6d4d | ||
|
|
40b7ea1f95 | ||
|
|
48d3badc0f | ||
|
|
fa270d72c7 | ||
|
|
baaf4de703 | ||
|
|
34a84c829c | ||
|
|
340e2dff12 | ||
|
|
c8d15588e5 | ||
|
|
8de16142a5 | ||
|
|
e378ecd6cf | ||
|
|
d20b442af2 | ||
|
|
726ce37b14 | ||
|
|
df079d4ca9 | ||
|
|
2ec1b7434e | ||
|
|
9cb875949c | ||
|
|
bfa07bb9d8 | ||
|
|
929632739a |
@@ -87,9 +87,8 @@ class OtatoolTarget():
|
||||
seq = bytearray(self.otadata[start:start + 4])
|
||||
crc = bytearray(self.otadata[start + 28:start + 32])
|
||||
|
||||
seq = struct.unpack('>I', seq)
|
||||
crc = struct.unpack('>I', crc)
|
||||
|
||||
seq = struct.unpack('I', seq)
|
||||
crc = struct.unpack('I', crc)
|
||||
info.append(otadata_info(seq[0], crc[0]))
|
||||
|
||||
return info
|
||||
@@ -108,7 +107,7 @@ class OtatoolTarget():
|
||||
|
||||
def is_otadata_info_valid(status):
|
||||
seq = status.seq % (1 << 32)
|
||||
crc = hex(binascii.crc32(struct.pack("I", seq), 0xFFFFFFFF) % (1 << 32))
|
||||
crc = binascii.crc32(struct.pack('I', seq), 0xFFFFFFFF) % (1 << 32)
|
||||
return seq < (int('0xFFFFFFFF', 16) % (1 << 32)) and status.crc == crc
|
||||
|
||||
partition_table = self.target.partition_table
|
||||
@@ -219,8 +218,8 @@ def _read_otadata(target):
|
||||
|
||||
otadata_info = target._get_otadata_info()
|
||||
|
||||
print(" {:8s} \t {:8s} | \t {:8s} \t {:8s}".format("OTA_SEQ", "CRC", "OTA_SEQ", "CRC"))
|
||||
print("Firmware: 0x{:8x} \t0x{:8x} | \t0x{:8x} \t 0x{:8x}".format(otadata_info[0].seq, otadata_info[0].crc,
|
||||
print(' {:8s} \t {:8s} | \t {:8s} \t {:8s}'.format('OTA_SEQ', 'CRC', 'OTA_SEQ', 'CRC'))
|
||||
print('Firmware: 0x{:08x} \t0x{:08x} | \t0x{:08x} \t 0x{:08x}'.format(otadata_info[0].seq, otadata_info[0].crc,
|
||||
otadata_info[1].seq, otadata_info[1].crc))
|
||||
|
||||
|
||||
|
||||
@@ -615,6 +615,7 @@ menu "Security features"
|
||||
config SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||
bool "Release"
|
||||
select SECURE_ENABLE_SECURE_ROM_DL_MODE if SECURE_TARGET_HAS_SECURE_ROM_DL_MODE && !SECURE_DISABLE_ROM_DL_MODE # NOERROR
|
||||
select PARTITION_TABLE_MD5 if !ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS
|
||||
|
||||
endchoice
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@ extern "C" {
|
||||
|
||||
#define PART_FLAG_ENCRYPTED (1<<0)
|
||||
|
||||
/* The md5sum value is found this many bytes after the ESP_PARTITION_MAGIC_MD5 offset */
|
||||
#define ESP_PARTITION_MD5_OFFSET 16
|
||||
|
||||
/* Pre-partition table fixed flash offsets */
|
||||
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
|
||||
#define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "sys/param.h"
|
||||
@@ -295,7 +296,18 @@ RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
|
||||
|
||||
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
|
||||
|
||||
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)(SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t));
|
||||
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
|
||||
|
||||
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
|
||||
|
||||
#if !IS_BOOTLOADER_BUILD
|
||||
/* The app needs to be told this memory is reserved, important if configured to use RTC memory as heap.
|
||||
|
||||
Note that keeping this macro here only works when other symbols in this file are referenced by the app, as
|
||||
this feature is otherwise 100% part of the bootloader. However this seems to happen in all apps.
|
||||
*/
|
||||
SOC_RESERVE_MEMORY_REGION(RTC_RETAIN_MEM_ADDR, RTC_RETAIN_MEM_ADDR + sizeof(rtc_retain_mem_t), rtc_retain_mem);
|
||||
#endif
|
||||
|
||||
static bool check_rtc_retain_mem(void)
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table
|
||||
MD5Update(&context, (unsigned char *) partition_table, num_parts * sizeof(esp_partition_info_t));
|
||||
MD5Final(digest, &context);
|
||||
|
||||
unsigned char *md5sum = ((unsigned char *) part) + 16; // skip the 2B magic number and the 14B fillup bytes
|
||||
unsigned char *md5sum = ((unsigned char *) part) + ESP_PARTITION_MD5_OFFSET;
|
||||
|
||||
if (memcmp(md5sum, digest, sizeof(digest)) != 0) {
|
||||
if (log_errors) {
|
||||
|
||||
@@ -573,6 +573,6 @@ idf_component_register(SRCS "${srcs}"
|
||||
if(CONFIG_BT_ENABLED)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib")
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib/esp32")
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
endif()
|
||||
|
||||
@@ -428,21 +428,6 @@ menu "Bluetooth"
|
||||
If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
menuconfig BTDM_COEX_BT_OPTIONS
|
||||
bool "Coexistence Bluetooth Side Options"
|
||||
depends on ESP32_WIFI_SW_COEXIST_ENABLE
|
||||
default n
|
||||
help
|
||||
Options of Bluetooth Side of WiFi and bluetooth coexistence.
|
||||
|
||||
config BTDM_COEX_BLE_ADV_HIGH_PRIORITY
|
||||
bool "Improve BLE ADV priority for WiFi & BLE coexistence"
|
||||
depends on BTDM_COEX_BT_OPTIONS
|
||||
default n
|
||||
help
|
||||
Improve BLE ADV coexistence priority to make it better performance.
|
||||
For example, BLE mesh need to enable this option to improve BLE adv performance.
|
||||
|
||||
endmenu
|
||||
|
||||
choice BT_HOST
|
||||
|
||||
@@ -9,11 +9,11 @@ COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
LIBS := btdm_app
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/controller/lib \
|
||||
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/controller/lib/esp32 \
|
||||
$(addprefix -l,$(LIBS))
|
||||
|
||||
# re-link program if BT binary libs change
|
||||
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/controller/lib/lib%.a,$(LIBS))
|
||||
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/controller/lib/esp32/lib%.a,$(LIBS))
|
||||
|
||||
COMPONENT_SUBMODULES += controller/lib
|
||||
|
||||
|
||||
@@ -238,7 +238,6 @@ extern uint8_t coex_schm_curr_period_get(void);
|
||||
extern void * coex_schm_curr_phase_get(void);
|
||||
extern int coex_wifi_channel_get(uint8_t *primary, uint8_t *secondary);
|
||||
extern int coex_register_wifi_channel_change_callback(void *cb);
|
||||
extern void coex_ble_adv_priority_high_set(bool high);
|
||||
|
||||
extern char _bss_start_btdm;
|
||||
extern char _bss_end_btdm;
|
||||
@@ -1461,12 +1460,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BTDM_COEX_BLE_ADV_HIGH_PRIORITY
|
||||
coex_ble_adv_priority_high_set(true);
|
||||
#else
|
||||
coex_ble_adv_priority_high_set(false);
|
||||
#endif
|
||||
|
||||
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
Submodule components/bt/controller/lib updated: c2e961d07c...1f7e45e2f6
@@ -751,7 +751,18 @@ static int prov_auth(uint8_t method, uint8_t action, uint8_t size)
|
||||
uint32_t num = 0U;
|
||||
|
||||
bt_mesh_rand(&num, sizeof(num));
|
||||
num %= div[size - 1];
|
||||
|
||||
if (output == BLE_MESH_BLINK ||
|
||||
output == BLE_MESH_BEEP ||
|
||||
output == BLE_MESH_VIBRATE) {
|
||||
/** NOTE: According to the Bluetooth Mesh Profile Specification
|
||||
* Section 5.4.2.4, blink, beep and vibrate should be a random
|
||||
* integer between 0 and 10^size.
|
||||
*/
|
||||
num = (num % (div[size - 1] - 1)) + 1;
|
||||
} else {
|
||||
num %= div[size - 1];
|
||||
}
|
||||
|
||||
sys_put_be32(num, &link.auth[12]);
|
||||
(void)memset(link.auth, 0, 12);
|
||||
|
||||
@@ -1954,7 +1954,17 @@ static int prov_auth(const uint8_t idx, uint8_t method, uint8_t action, uint8_t
|
||||
uint32_t num = 0U;
|
||||
|
||||
bt_mesh_rand(&num, sizeof(num));
|
||||
num %= div[size - 1];
|
||||
|
||||
if (input == BLE_MESH_PUSH ||
|
||||
input == BLE_MESH_TWIST) {
|
||||
/** NOTE: According to the Bluetooth Mesh Profile Specification
|
||||
* Section 5.4.2.4, push and twist should be a random integer
|
||||
* between 0 and 10^size.
|
||||
*/
|
||||
num = (num % (div[size - 1] - 1)) + 1;
|
||||
} else {
|
||||
num %= div[size - 1];
|
||||
}
|
||||
|
||||
sys_put_be32(num, &link[idx].auth[12]);
|
||||
memset(link[idx].auth, 0, 12);
|
||||
@@ -2057,7 +2067,7 @@ int bt_mesh_provisioner_set_oob_input_data(const uint8_t idx, const uint8_t *val
|
||||
memset(link[idx].auth, 0, 16);
|
||||
if (num_flag) {
|
||||
/* Provisioner inputs number */
|
||||
memcpy(link[idx].auth + 12, val, sizeof(uint32_t));
|
||||
sys_memcpy_swap(link[idx].auth + 12, val, sizeof(uint32_t));
|
||||
} else {
|
||||
/* Provisioner inputs string */
|
||||
memcpy(link[idx].auth, val, link[idx].auth_size);
|
||||
@@ -2094,7 +2104,7 @@ int bt_mesh_provisioner_set_oob_output_data(const uint8_t idx, const uint8_t *nu
|
||||
if (num_flag) {
|
||||
/* Provisioner output number */
|
||||
memset(link[idx].auth, 0, 16);
|
||||
memcpy(link[idx].auth + 16 - size, num, size);
|
||||
sys_memcpy_swap(link[idx].auth + 16 - size, num, size);
|
||||
} else {
|
||||
/* Provisioner output string */
|
||||
memset(link[idx].auth, 0, 16);
|
||||
|
||||
@@ -301,6 +301,7 @@ typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_p
|
||||
* @param len : length of data from phone
|
||||
* @param output_data : data want to send to phone
|
||||
* @param output_len : length of data want to send to phone
|
||||
* @param need_free : output reporting if memory needs to be freed or not *
|
||||
*/
|
||||
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
|
||||
|
||||
@@ -311,7 +312,7 @@ typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8
|
||||
* @param crypt_len : length of plain text
|
||||
* @return Nonnegative number is encrypted length, if error, return negative number;
|
||||
*/
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len);
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI decrypt the data after negotiate a share key
|
||||
|
||||
@@ -258,7 +258,7 @@ typedef union {
|
||||
/**
|
||||
* @brief GATT Client callback function type
|
||||
* @param event : Event type
|
||||
* @param gatts_if : GATT client access interface, normally
|
||||
* @param gattc_if : GATT client access interface, normally
|
||||
* different gattc_if correspond to different profile
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
@@ -312,7 +312,7 @@ esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if);
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] remote_bda: remote device bluetooth device address.
|
||||
* @param[in] remote_addr_type: remote device bluetooth device the address type.
|
||||
* @param[in] is_direct: direct connection or background auto connection
|
||||
* @param[in] is_direct: direct connection or background auto connection(by now, background auto connection is not supported).
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
|
||||
@@ -184,7 +184,7 @@ typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
* @param[out] length of data successfully read
|
||||
* @return length of data successfully read
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
|
||||
|
||||
@@ -592,4 +592,4 @@ void esp_hf_outgoing_data_ready(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__ESP_HF_AG_API_H__
|
||||
#endif //__ESP_HF_AG_API_H__
|
||||
|
||||
@@ -271,7 +271,7 @@ typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t l
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
* @param[out] length of data successfully read
|
||||
* @return length of data successfully read
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);
|
||||
|
||||
|
||||
@@ -394,6 +394,8 @@ void bta_gattc_co_cache_addr_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(cache_env, 0x0, sizeof(cache_env_t));
|
||||
|
||||
if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) {
|
||||
cache_env->addr_fp = fp;
|
||||
cache_env->is_open = TRUE;
|
||||
|
||||
@@ -53,7 +53,11 @@
|
||||
/* Max HF Clients Supported From App */
|
||||
static UINT16 btc_max_hf_clients = 1;
|
||||
/* HF Param Definition */
|
||||
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||
static hf_local_param_t hf_local_param[BTC_HF_NUM_CB];
|
||||
#else
|
||||
static hf_local_param_t *hf_local_param;
|
||||
#endif
|
||||
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
#ifndef BTC_HF_FEATURES
|
||||
@@ -296,7 +300,15 @@ bt_status_t btc_hf_execute_service(BOOLEAN b_enable)
|
||||
************************************************************************************/
|
||||
bt_status_t btc_hf_init(bt_bdaddr_t *bd_addr)
|
||||
{
|
||||
int idx = btc_hf_idx_by_bdaddr(bd_addr);
|
||||
int idx = 0;
|
||||
UNUSED(bd_addr);
|
||||
|
||||
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||
if ((hf_local_param = (hf_local_param_t *)osi_malloc(sizeof(hf_local_param_t) * BTC_HF_NUM_CB)) == NULL) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
BTC_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btc_max_hf_clients);
|
||||
/* Invoke the enable service API to the core to set the appropriate service_id
|
||||
* Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
|
||||
@@ -322,10 +334,18 @@ bt_status_t btc_hf_init(bt_bdaddr_t *bd_addr)
|
||||
|
||||
void btc_hf_deinit(bt_bdaddr_t *bd_addr)
|
||||
{
|
||||
int idx = btc_hf_idx_by_bdaddr(bd_addr);
|
||||
UNUSED(bd_addr);
|
||||
|
||||
BTC_TRACE_EVENT("%s", __FUNCTION__);
|
||||
btc_dm_disable_service(BTA_HFP_SERVICE_ID);
|
||||
hf_local_param[idx].btc_hf_cb.initialized = false;
|
||||
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||
if (hf_local_param) {
|
||||
osi_free(hf_local_param);
|
||||
hf_local_param = NULL;
|
||||
}
|
||||
#else
|
||||
hf_local_param[0].btc_hf_cb.initialized = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bt_status_t connect_init(bt_bdaddr_t *bd_addr, uint16_t uuid)
|
||||
|
||||
@@ -206,11 +206,6 @@ typedef union
|
||||
/* APP ID definition*/
|
||||
#define BTC_HF_ID_1 0
|
||||
|
||||
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||
extern hf_local_param_t *hf_local_param_ptr;
|
||||
#define hf_local_param (*hf_local_param_ptr)
|
||||
#endif
|
||||
|
||||
/* BTC-AG control block to map bdaddr to BTA handle */
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -93,6 +93,10 @@
|
||||
#include "bta_hf_client_int.h"
|
||||
#endif
|
||||
|
||||
#if BTA_AG_INCLUDED == TRUE
|
||||
#include "bta_ag_int.h"
|
||||
#endif
|
||||
|
||||
#if BTA_SDP_INCLUDED == TRUE
|
||||
#include "bta_sdp_int.h"
|
||||
#endif
|
||||
@@ -216,6 +220,12 @@ void BTE_DeinitStack(void)
|
||||
osi_free(bta_hf_client_cb_ptr);
|
||||
bta_hf_client_cb_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
#if (defined BTA_AG_INCLUDED && BTA_AG_INCLUDED == TRUE)
|
||||
if (bta_ag_cb_ptr){
|
||||
osi_free(bta_ag_cb_ptr);
|
||||
bta_ag_cb_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
if (bta_dm_conn_srvcs_ptr){
|
||||
osi_free(bta_dm_conn_srvcs_ptr);
|
||||
@@ -374,6 +384,12 @@ bt_status_t BTE_InitStack(void)
|
||||
}
|
||||
memset((void *)bta_hf_client_cb_ptr, 0, sizeof(tBTA_HF_CLIENT_CB));
|
||||
#endif
|
||||
#if (defined BTA_AG_INCLUDED && BTA_AG_INCLUDED == TRUE)
|
||||
if ((bta_ag_cb_ptr = (tBTA_AG_CB *)osi_malloc(sizeof(tBTA_AG_CB))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)bta_ag_cb_ptr, 0, sizeof(tBTA_AG_CB));
|
||||
#endif
|
||||
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
|
||||
if ((bta_jv_cb_ptr = (tBTA_JV_CB *)osi_malloc(sizeof(tBTA_JV_CB))) == NULL) {
|
||||
goto error_exit;
|
||||
|
||||
@@ -2032,6 +2032,30 @@ void btm_ble_create_ll_conn_complete (UINT8 status)
|
||||
btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Function btm_ble_create_conn_cancel_complete
|
||||
**
|
||||
** Description LE connection cancel complete.
|
||||
**
|
||||
******************************************************************************/
|
||||
void btm_ble_create_conn_cancel_complete (UINT8 *p)
|
||||
{
|
||||
UINT8 status;
|
||||
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
|
||||
switch (status) {
|
||||
case HCI_SUCCESS:
|
||||
if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) {
|
||||
btm_ble_set_conn_st (BLE_CONN_IDLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Function btm_proc_smp_cback
|
||||
**
|
||||
|
||||
@@ -403,6 +403,7 @@ tBTM_STATUS btm_ble_start_adv(void);
|
||||
tBTM_STATUS btm_ble_stop_adv(void);
|
||||
tBTM_STATUS btm_ble_start_scan(void);
|
||||
void btm_ble_create_ll_conn_complete (UINT8 status);
|
||||
void btm_ble_create_conn_cancel_complete (UINT8 *p);
|
||||
|
||||
/* LE security function from btm_sec.c */
|
||||
#if SMP_INCLUDED == TRUE
|
||||
|
||||
@@ -981,6 +981,9 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
|
||||
case HCI_BLE_TEST_END:
|
||||
btm_ble_test_command_complete(p);
|
||||
break;
|
||||
case HCI_BLE_CREATE_CONN_CANCEL:
|
||||
btm_ble_create_conn_cancel_complete(p);
|
||||
break;
|
||||
|
||||
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
|
||||
case HCI_BLE_ADD_DEV_RESOLVING_LIST:
|
||||
|
||||
@@ -1835,7 +1835,7 @@ UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
|
||||
}
|
||||
|
||||
// If already congested, do not accept any more packets
|
||||
if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
|
||||
if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent && fixed_cid != L2CAP_SMP_CID) {
|
||||
L2CAP_TRACE_DEBUG ("L2CAP - CID: 0x%04x cannot send, already congested\
|
||||
xmit_hold_q.count: %u buff_quota: %u", fixed_cid,
|
||||
fixed_queue_length(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q),
|
||||
|
||||
@@ -764,8 +764,7 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
/* Check if the peer device's and own public key are not same. If they are same then
|
||||
* return pairing fail. This check is needed to avoid 'Impersonation in Passkey entry
|
||||
* protocol' vulnerability (CVE-2020-26558).*/
|
||||
if ((memcmp(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, sizeof(BT_OCTET32)) == 0) &&
|
||||
(memcmp(p_cb->loc_publ_key.y, p_cb->peer_publ_key.y, sizeof(BT_OCTET32)) == 0)) {
|
||||
if ((memcmp(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, sizeof(BT_OCTET32)) == 0)) {
|
||||
p_cb->status = SMP_PAIR_AUTH_FAIL;
|
||||
p_cb->failure = SMP_PAIR_AUTH_FAIL;
|
||||
reason = SMP_PAIR_AUTH_FAIL;
|
||||
|
||||
@@ -211,7 +211,9 @@ void ble_hci_trans_buf_free(uint8_t *buf)
|
||||
*/
|
||||
int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg)
|
||||
{
|
||||
return BLE_ERR_UNSUPPORTED;
|
||||
ble_hci_acl_pool.mpe_put_cb = cb;
|
||||
ble_hci_acl_pool.mpe_put_arg = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_hci_trans_reset(void)
|
||||
@@ -248,6 +250,7 @@ static struct os_mbuf *ble_hci_trans_acl_buf_alloc(void)
|
||||
static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
||||
{
|
||||
struct os_mbuf *m;
|
||||
int rc;
|
||||
int sr;
|
||||
if (len < BLE_HCI_DATA_HDR_SZ || len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) {
|
||||
return;
|
||||
@@ -256,9 +259,11 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
||||
m = ble_hci_trans_acl_buf_alloc();
|
||||
|
||||
if (!m) {
|
||||
ESP_LOGE(TAG, "%s failed to allocate ACL buffers; increase ACL_BUF_COUNT", __func__);
|
||||
return;
|
||||
}
|
||||
if (os_mbuf_append(m, data, len)) {
|
||||
if ((rc = os_mbuf_append(m, data, len)) != 0) {
|
||||
ESP_LOGE(TAG, "%s failed to os_mbuf_append; rc = %d", __func__, rc);
|
||||
os_mbuf_free_chain(m);
|
||||
return;
|
||||
}
|
||||
|
||||
Submodule components/bt/host/nimble/nimble updated: ba72e37ac4...57d751b93a
@@ -488,6 +488,7 @@ esp_err_t esp_bt_sleep_disable(void);
|
||||
* Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached
|
||||
* the amount of device in the filter can be configured in menuconfig.
|
||||
*
|
||||
* @note This function name is incorrectly spelled, it will be fixed in release 5.x version.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
|
||||
@@ -344,14 +344,9 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
||||
int freq;
|
||||
spi_hal_context_t *hal = &(host->hal);
|
||||
hal->half_duplex = dev_config->flags & SPI_DEVICE_HALFDUPLEX ? 1 : 0;
|
||||
#ifdef SOC_SPI_SUPPORT_AS_CS
|
||||
hal->as_cs = dev_config->flags & SPI_DEVICE_CLK_AS_CS ? 1 : 0;
|
||||
#endif
|
||||
hal->positive_cs = dev_config->flags & SPI_DEVICE_POSITIVE_CS ? 1 : 0;
|
||||
hal->no_compensate = dev_config->flags & SPI_DEVICE_NO_DUMMY ? 1 : 0;
|
||||
|
||||
spi_hal_timing_conf_t temp_timing_conf;
|
||||
|
||||
esp_err_t ret = spi_hal_get_clock_conf(hal, dev_config->clock_speed_hz, duty_cycle,
|
||||
!(bus_attr->flags & SPICOMMON_BUSFLAG_IOMUX_PINS),
|
||||
dev_config->input_delay_ns, &freq,
|
||||
@@ -453,16 +448,20 @@ static SPI_MASTER_ISR_ATTR void spi_setup_device(spi_device_t *dev)
|
||||
hal->mode = dev->cfg.mode;
|
||||
hal->tx_lsbfirst = dev->cfg.flags & SPI_DEVICE_TXBIT_LSBFIRST ? 1 : 0;
|
||||
hal->rx_lsbfirst = dev->cfg.flags & SPI_DEVICE_RXBIT_LSBFIRST ? 1 : 0;
|
||||
hal->no_compensate = dev->cfg.flags & SPI_DEVICE_NO_DUMMY ? 1 : 0;
|
||||
hal->sio = dev->cfg.flags & SPI_DEVICE_3WIRE ? 1 : 0;
|
||||
hal->dummy_bits = dev->cfg.dummy_bits;
|
||||
hal->cs_setup = dev->cfg.cs_ena_pretrans;
|
||||
hal->cs_hold =dev->cfg.cs_ena_posttrans;
|
||||
hal->cs_hold = dev->cfg.cs_ena_posttrans;
|
||||
//set hold_time to 0 will not actually append delay to CS
|
||||
//set it to 1 since we do need at least one clock of hold time in most cases
|
||||
if (hal->cs_hold == 0) hal->cs_hold = 1;
|
||||
hal->cs_pin_id = dev->id;
|
||||
hal->timing_conf = &dev->timing_conf;
|
||||
hal->half_duplex = dev->cfg.flags & SPI_DEVICE_HALFDUPLEX ? 1 : 0;
|
||||
#ifdef SOC_SPI_SUPPORT_AS_CS
|
||||
hal->as_cs = dev->cfg.flags & SPI_DEVICE_CLK_AS_CS ? 1 : 0;
|
||||
#endif
|
||||
hal->positive_cs = dev->cfg.flags & SPI_DEVICE_POSITIVE_CS ? 1 : 0;
|
||||
hal->no_compensate = dev->cfg.flags & SPI_DEVICE_NO_DUMMY ? 1 : 0;
|
||||
|
||||
spi_hal_setup_device(hal);
|
||||
}
|
||||
@@ -517,7 +516,6 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_
|
||||
hal->rx_bitlen = trans->rxlength;
|
||||
hal->rcv_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_rcv;
|
||||
hal->send_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_send;
|
||||
hal->half_duplex = dev->cfg.flags & SPI_DEVICE_HALFDUPLEX ? 1 : 0;
|
||||
hal->cmd = trans->cmd;
|
||||
hal->addr = trans->addr;
|
||||
//Set up QIO/DIO if needed
|
||||
|
||||
@@ -497,14 +497,14 @@ bool IRAM_ATTR timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer
|
||||
return timer_hal_get_auto_reload(&(p_timer_obj[group_num][timer_num]->hal));
|
||||
}
|
||||
|
||||
esp_err_t timer_spinlock_take(timer_group_t group_num)
|
||||
esp_err_t IRAM_ATTR timer_spinlock_take(timer_group_t group_num)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_spinlock_give(timer_group_t group_num)
|
||||
esp_err_t IRAM_ATTR timer_spinlock_give(timer_group_t group_num)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
|
||||
@@ -695,10 +695,11 @@ menu "ESP32-specific"
|
||||
that after enabling this Wi-Fi/Bluetooth will not work.
|
||||
|
||||
config ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS
|
||||
bool "App compatible with bootloaders before IDF v2.1"
|
||||
bool "App compatible with bootloaders before ESP-IDF v2.1"
|
||||
select ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS
|
||||
default n
|
||||
help
|
||||
Bootloaders before IDF v2.1 did less initialisation of the
|
||||
Bootloaders before ESP-IDF v2.1 did less initialisation of the
|
||||
system clock. This setting needs to be enabled to build an app
|
||||
which can be booted by these older bootloaders.
|
||||
|
||||
@@ -710,6 +711,22 @@ menu "ESP32-specific"
|
||||
|
||||
Enabling this setting adds approximately 1KB to the app's IRAM usage.
|
||||
|
||||
config ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS
|
||||
bool "App compatible with bootloader and partition table before ESP-IDF v3.1"
|
||||
default n
|
||||
help
|
||||
Partition tables before ESP-IDF V3.1 do not contain an MD5 checksum
|
||||
field, and the bootloader before ESP-IDF v3.1 cannot read a partition
|
||||
table that contains an MD5 checksum field.
|
||||
|
||||
Enable this option only if your app needs to boot on a bootloader and/or
|
||||
partition table that was generated from a version *before* ESP-IDF v3.1.
|
||||
|
||||
If this option and Flash Encryption are enabled at the same time, and any
|
||||
data partitions in the partition table are marked Encrypted, then the
|
||||
partition encrypted flag should be manually verified in the app before accessing
|
||||
the partition (see CVE-2021-27926).
|
||||
|
||||
config ESP32_APP_INIT_CLK
|
||||
bool
|
||||
default y if ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS
|
||||
|
||||
@@ -134,3 +134,12 @@ REGION_ALIAS("rtc_data_location", rtc_data_seg );
|
||||
#else
|
||||
REGION_ALIAS("default_rodata_seg", dram0_0_seg);
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
/**
|
||||
* If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must
|
||||
* also be first in the segment.
|
||||
*/
|
||||
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
ASSERT(_rodata_start == ORIGIN(default_rodata_seg),
|
||||
".flash.appdesc section must be placed at the beginning of the rodata segment.")
|
||||
#endif
|
||||
|
||||
@@ -249,14 +249,23 @@ SECTIONS
|
||||
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
|
||||
"DRAM segment data does not fit.")
|
||||
|
||||
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
|
||||
.flash.rodata : ALIGN(0x10)
|
||||
.flash.appdesc : ALIGN(0x10)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
|
||||
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
|
||||
/* Create an empty gap within this section. Thanks to this, the end of this
|
||||
* section will match .flah.rodata's begin address. Thus, both sections
|
||||
* will be merged when creating the final bin image. */
|
||||
. = ALIGN(ALIGNOF(.flash.rodata));
|
||||
} >default_rodata_seg
|
||||
|
||||
.flash.rodata : ALIGN(0x10)
|
||||
{
|
||||
_flash_rodata_start = ABSOLUTE(.);
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
@@ -312,6 +321,8 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
} >default_rodata_seg
|
||||
|
||||
_flash_rodata_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
.flash.text :
|
||||
{
|
||||
_stext = .;
|
||||
|
||||
@@ -237,6 +237,23 @@ esp_err_t esp_pm_configure(const void* vconfig)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_pm_get_configuration(void* vconfig)
|
||||
{
|
||||
if (vconfig == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_pm_config_esp32_t* config = (esp_pm_config_esp32_t*) vconfig;
|
||||
|
||||
portENTER_CRITICAL(&s_switch_lock);
|
||||
config->light_sleep_enable = s_light_sleep_en;
|
||||
config->max_freq_mhz = s_cpu_freq_by_mode[PM_MODE_CPU_MAX].freq_mhz;
|
||||
config->min_freq_mhz = s_cpu_freq_by_mode[PM_MODE_APB_MIN].freq_mhz;
|
||||
portEXIT_CRITICAL(&s_switch_lock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static pm_mode_t IRAM_ATTR get_lowest_allowed_mode(void)
|
||||
{
|
||||
/* TODO: optimize using ffs/clz */
|
||||
|
||||
@@ -668,14 +668,17 @@ static uint32_t get_power_down_flags(void)
|
||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON;
|
||||
}
|
||||
|
||||
// RTC_FAST_MEM is needed for deep sleep stub.
|
||||
// If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub
|
||||
// can run.
|
||||
// In the new chip revision, deep sleep stub will be optional,
|
||||
// and this can be changed.
|
||||
#if !CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||
/* RTC_FAST_MEM is needed for deep sleep stub.
|
||||
If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub can run.
|
||||
In the new chip revision, deep sleep stub will be optional, and this can be changed. */
|
||||
if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) {
|
||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
|
||||
}
|
||||
#else
|
||||
/* If RTC_FAST_MEM is used for heap, force RTC_FAST_MEM to be powered on. */
|
||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
|
||||
#endif
|
||||
|
||||
// RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
|
||||
// If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH.
|
||||
|
||||
@@ -161,8 +161,9 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
|
||||
|
||||
free(esp_ds_ctx);
|
||||
|
||||
// should not fail if called with correct purpose
|
||||
assert(ets_hmac_invalidate_downstream(ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) == ETS_OK);
|
||||
int res = ets_hmac_invalidate_downstream(ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE);
|
||||
assert(res == ETS_OK); // should not fail if called with correct purpose
|
||||
(void)res;
|
||||
|
||||
ds_disable_release();
|
||||
|
||||
|
||||
@@ -120,3 +120,13 @@ REGION_ALIAS("rtc_data_location", rtc_data_seg );
|
||||
#else
|
||||
REGION_ALIAS("default_rodata_seg", dram0_0_seg);
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
|
||||
/**
|
||||
* If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must
|
||||
* also be first in the segment.
|
||||
*/
|
||||
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
ASSERT(_rodata_reserved_start == ORIGIN(default_rodata_seg),
|
||||
".flash.appdesc section must be placed at the beginning of the rodata segment.")
|
||||
#endif
|
||||
|
||||
@@ -232,8 +232,7 @@ SECTIONS
|
||||
_heap_start = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
|
||||
.flash.rodata : ALIGN(0x10)
|
||||
.flash.appdesc : ALIGN(0x10)
|
||||
{
|
||||
_rodata_reserved_start = ABSOLUTE(.);
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
@@ -241,6 +240,16 @@ SECTIONS
|
||||
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
|
||||
/* Create an empty gap within this section. Thanks to this, the end of this
|
||||
* section will match .flah.rodata's begin address. Thus, both sections
|
||||
* will be merged when creating the final bin image. */
|
||||
. = ALIGN(ALIGNOF(.flash.rodata));
|
||||
} >default_rodata_seg
|
||||
|
||||
.flash.rodata : ALIGN(0x10)
|
||||
{
|
||||
_flash_rodata_start = ABSOLUTE(.);
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
@@ -297,6 +306,8 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
} >default_rodata_seg
|
||||
|
||||
_flash_rodata_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
.flash.text :
|
||||
{
|
||||
_stext = .;
|
||||
|
||||
@@ -232,6 +232,23 @@ esp_err_t esp_pm_configure(const void* vconfig)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_pm_get_configuration(void* vconfig)
|
||||
{
|
||||
if (vconfig == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_pm_config_esp32s2_t* config = (esp_pm_config_esp32s2_t*) vconfig;
|
||||
|
||||
portENTER_CRITICAL(&s_switch_lock);
|
||||
config->light_sleep_enable = s_light_sleep_en;
|
||||
config->max_freq_mhz = s_cpu_freq_by_mode[PM_MODE_CPU_MAX].freq_mhz;
|
||||
config->min_freq_mhz = s_cpu_freq_by_mode[PM_MODE_APB_MIN].freq_mhz;
|
||||
portEXIT_CRITICAL(&s_switch_lock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static pm_mode_t IRAM_ATTR get_lowest_allowed_mode(void)
|
||||
{
|
||||
/* TODO: optimize using ffs/clz */
|
||||
|
||||
@@ -703,14 +703,17 @@ static uint32_t get_power_down_flags(void)
|
||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON;
|
||||
}
|
||||
|
||||
// RTC_FAST_MEM is needed for deep sleep stub.
|
||||
// If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub
|
||||
// can run.
|
||||
// In the new chip revision, deep sleep stub will be optional,
|
||||
// and this can be changed.
|
||||
#if !CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||
/* RTC_FAST_MEM is needed for deep sleep stub.
|
||||
If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub can run.
|
||||
In the new chip revision, deep sleep stub will be optional, and this can be changed. */
|
||||
if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) {
|
||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
|
||||
}
|
||||
#else
|
||||
/* If RTC_FAST_MEM is used for heap, force RTC_FAST_MEM to be powered on. */
|
||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
|
||||
#endif
|
||||
|
||||
// RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
|
||||
// If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH.
|
||||
|
||||
@@ -23,7 +23,7 @@ extern "C" {
|
||||
/** Minor version number (x.X.x) */
|
||||
#define ESP_IDF_VERSION_MINOR 2
|
||||
/** Patch version number (x.x.X) */
|
||||
#define ESP_IDF_VERSION_PATCH 1
|
||||
#define ESP_IDF_VERSION_PATCH 2
|
||||
|
||||
/**
|
||||
* Macro to convert IDF version number into an integer
|
||||
|
||||
@@ -59,6 +59,14 @@ typedef enum {
|
||||
*/
|
||||
esp_err_t esp_pm_configure(const void* config);
|
||||
|
||||
/**
|
||||
* @brief Get implementation-specific power management configuration
|
||||
* @param config pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32)
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if the pointer is null
|
||||
*/
|
||||
esp_err_t esp_pm_get_configuration(void* config);
|
||||
|
||||
/**
|
||||
* @brief Opaque handle to the power management lock
|
||||
|
||||
@@ -255,6 +255,8 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl)
|
||||
esp_err_t ret = ESP_OK;
|
||||
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)) {
|
||||
@@ -262,14 +264,13 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl)
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
goto err;
|
||||
}
|
||||
ETH_CHECK(eth_driver->phy->reset(eth_driver->phy) == ESP_OK, "reset phy failed", err, ESP_FAIL);
|
||||
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(eth_driver), 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);
|
||||
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS,
|
||||
"start eth_link_timer failed", err, ESP_FAIL);
|
||||
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, ð_driver, sizeof(eth_driver), 0) == ESP_OK,
|
||||
"send ETHERNET_EVENT_START event failed", err_event, ESP_FAIL);
|
||||
return ESP_OK;
|
||||
err_event:
|
||||
xTimerStop(eth_driver->check_link_timer, 0);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -202,6 +202,8 @@ static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent);
|
||||
esp_eth_mediator_t *eth = dm9051->eth;
|
||||
/* in case any link status has changed, let's assume we're in link down status */
|
||||
dm9051->link_status = ETH_LINK_DOWN;
|
||||
/* Start auto negotiation */
|
||||
bmcr_reg_t bmcr = {
|
||||
.speed_select = 1, /* 100Mbps */
|
||||
@@ -215,8 +217,8 @@ static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy)
|
||||
bmsr_reg_t bmsr;
|
||||
dscsr_reg_t dscsr;
|
||||
uint32_t to = 0;
|
||||
for (to = 0; to < dm9051->autonego_timeout_ms / 10; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
for (to = 0; to < dm9051->autonego_timeout_ms / 100; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||
"read BMSR failed", err);
|
||||
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_DSCSR_REG_ADDR, &(dscsr.val)) == ESP_OK,
|
||||
@@ -225,11 +227,9 @@ static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (to >= dm9051->autonego_timeout_ms / 10) {
|
||||
if (to >= dm9051->autonego_timeout_ms / 100) {
|
||||
ESP_LOGW(TAG, "Ethernet PHY auto negotiation timeout");
|
||||
}
|
||||
/* Updata information about link, speed, duplex */
|
||||
PHY_CHECK(dm9051_update_link_duplex_speed(dm9051) == ESP_OK, "update link duplex speed failed", err);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -191,6 +191,8 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent);
|
||||
esp_eth_mediator_t *eth = dp83848->eth;
|
||||
/* in case any link status has changed, let's assume we're in link down status */
|
||||
dp83848->link_status = ETH_LINK_DOWN;
|
||||
/* Start auto negotiation */
|
||||
bmcr_reg_t bmcr = {
|
||||
.speed_select = 1, /* 100Mbps */
|
||||
@@ -204,8 +206,8 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy)
|
||||
bmsr_reg_t bmsr;
|
||||
physts_reg_t physts;
|
||||
uint32_t to = 0;
|
||||
for (to = 0; to < dp83848->autonego_timeout_ms / 10; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
for (to = 0; to < dp83848->autonego_timeout_ms / 100; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
PHY_CHECK(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||
"read BMSR failed", err);
|
||||
PHY_CHECK(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_STS_REG_ADDR, &(physts.val)) == ESP_OK,
|
||||
@@ -215,11 +217,9 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy)
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= dp83848->autonego_timeout_ms / 10) {
|
||||
if (to >= dp83848->autonego_timeout_ms / 100) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
/* Updata information about link, speed, duplex */
|
||||
PHY_CHECK(dp83848_update_link_duplex_speed(dp83848) == ESP_OK, "update link duplex speed failed", err);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -231,6 +231,8 @@ static esp_err_t ip101_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent);
|
||||
esp_eth_mediator_t *eth = ip101->eth;
|
||||
/* in case any link status has changed, let's assume we're in link down status */
|
||||
ip101->link_status = ETH_LINK_DOWN;
|
||||
/* Restart auto negotiation */
|
||||
bmcr_reg_t bmcr = {
|
||||
.speed_select = 1, /* 100Mbps */
|
||||
@@ -243,8 +245,8 @@ static esp_err_t ip101_negotiate(esp_eth_phy_t *phy)
|
||||
/* Wait for auto negotiation complete */
|
||||
bmsr_reg_t bmsr;
|
||||
uint32_t to = 0;
|
||||
for (to = 0; to < ip101->autonego_timeout_ms / 10; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
for (to = 0; to < ip101->autonego_timeout_ms / 100; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
PHY_CHECK(eth->phy_reg_read(eth, ip101->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||
"read BMSR failed", err);
|
||||
if (bmsr.auto_nego_complete) {
|
||||
@@ -252,11 +254,9 @@ static esp_err_t ip101_negotiate(esp_eth_phy_t *phy)
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= ip101->autonego_timeout_ms / 10) {
|
||||
if (to >= ip101->autonego_timeout_ms / 100) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
/* Updata information about link, speed, duplex */
|
||||
PHY_CHECK(ip101_update_link_duplex_speed(ip101) == ESP_OK, "update link duplex speed failed", err);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -276,6 +276,8 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
|
||||
esp_eth_mediator_t *eth = lan8720->eth;
|
||||
/* in case any link status has changed, let's assume we're in link down status */
|
||||
lan8720->link_status = ETH_LINK_DOWN;
|
||||
/* Restart auto negotiation */
|
||||
bmcr_reg_t bmcr = {
|
||||
.speed_select = 1, /* 100Mbps */
|
||||
@@ -287,9 +289,9 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
|
||||
/* Wait for auto negotiation complete */
|
||||
bmsr_reg_t bmsr;
|
||||
pscsr_reg_t pscsr;
|
||||
int32_t to = 0;
|
||||
for (to = 0; to < lan8720->autonego_timeout_ms / 10; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
uint32_t to = 0;
|
||||
for (to = 0; to < lan8720->autonego_timeout_ms / 100; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
PHY_CHECK(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||
"read BMSR failed", err);
|
||||
PHY_CHECK(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_PSCSR_REG_ADDR, &(pscsr.val)) == ESP_OK,
|
||||
@@ -299,11 +301,9 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= lan8720->autonego_timeout_ms / 10) {
|
||||
if (to >= lan8720->autonego_timeout_ms / 100) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
/* Updata information about link, speed, duplex */
|
||||
PHY_CHECK(lan8720_update_link_duplex_speed(lan8720) == ESP_OK, "update link duplex speed failed", err);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -185,6 +185,8 @@ static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent);
|
||||
esp_eth_mediator_t *eth = rtl8201->eth;
|
||||
/* in case any link status has changed, let's assume we're in link down status */
|
||||
rtl8201->link_status = ETH_LINK_DOWN;
|
||||
/* Restart auto negotiation */
|
||||
bmcr_reg_t bmcr = {
|
||||
.speed_select = 1, /* 100Mbps */
|
||||
@@ -197,8 +199,8 @@ static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy)
|
||||
/* Wait for auto negotiation complete */
|
||||
bmsr_reg_t bmsr;
|
||||
uint32_t to = 0;
|
||||
for (to = 0; to < rtl8201->autonego_timeout_ms / 10; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
for (to = 0; to < rtl8201->autonego_timeout_ms / 100; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
PHY_CHECK(eth->phy_reg_read(eth, rtl8201->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||
"read BMSR failed", err);
|
||||
if (bmsr.auto_nego_complete) {
|
||||
@@ -206,11 +208,9 @@ static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy)
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= rtl8201->autonego_timeout_ms / 10) {
|
||||
if (to >= rtl8201->autonego_timeout_ms / 100) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
/* Updata information about link, speed, duplex */
|
||||
PHY_CHECK(rtl8201_update_link_duplex_speed(rtl8201) == ESP_OK, "update link duplex speed failed", err);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -898,7 +898,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
|
||||
}
|
||||
ESP_LOG_LEVEL(sev, TAG, "esp_transport_read returned:%d and errno:%d ", rlen, errno);
|
||||
}
|
||||
if (rlen < 0 && ridx == 0) {
|
||||
if (rlen < 0 && ridx == 0 && !esp_http_client_is_complete_data_received(client)) {
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
return ridx;
|
||||
|
||||
@@ -319,9 +319,6 @@ endmenu # Wi-Fi
|
||||
menu "PHY"
|
||||
|
||||
config ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
|
||||
# ToDo: remove target dependency once NVS and PHY partial calibration are supported
|
||||
# also re-enable the <RF_calibration> entry in docs/../api-guides/index.rst
|
||||
depends on IDF_TARGET_ESP32
|
||||
bool "Store phy calibration data in NVS"
|
||||
default y
|
||||
help
|
||||
|
||||
@@ -655,7 +655,7 @@ esp_err_t esp_mesh_stop(void);
|
||||
* - If the packet is to the root ("to" parameter isn't NULL) or to external IP network, MESH_DATA_TODS should be set.
|
||||
* - If the packet is from the root to an internal device, MESH_DATA_FROMDS should be set.
|
||||
* - Specify whether this API is block or non-block, block by default
|
||||
* - If needs non-block, MESH_DATA_NONBLOCK should be set.
|
||||
* - If needs non-blocking, MESH_DATA_NONBLOCK should be set. Otherwise, may use esp_mesh_send_block_time() to specify a blocking time.
|
||||
* - In the situation of the root change, MESH_DATA_DROP identifies this packet can be dropped by the new root
|
||||
* for upstream data to external IP network, we try our best to avoid data loss caused by the root change, but
|
||||
* there is a risk that the new root is running out of memory because most of memory is occupied by the pending data which
|
||||
@@ -688,6 +688,17 @@ esp_err_t esp_mesh_stop(void);
|
||||
*/
|
||||
esp_err_t esp_mesh_send(const mesh_addr_t *to, const mesh_data_t *data,
|
||||
int flag, const mesh_opt_t opt[], int opt_count);
|
||||
/**
|
||||
* @brief Set blocking time of esp_mesh_send()
|
||||
*
|
||||
* @attention This API shall be called before mesh is started.
|
||||
*
|
||||
* @param[in] time_ms blocking time of esp_mesh_send(), unit:ms
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t esp_mesh_send_block_time(uint32_t time_ms);
|
||||
|
||||
/**
|
||||
* @brief Receive a packet targeted to self over the mesh network
|
||||
|
||||
Submodule components/esp_wifi/lib updated: 1c4c5396ca...188461a182
Submodule components/esptool_py/esptool updated: 4fa0bd7b0d...4698b39673
@@ -388,7 +388,22 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
}
|
||||
|
||||
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes );
|
||||
/* Check for multiplication overflow. */
|
||||
configASSERT( ( uxItemSize == 0 ) || ( uxQueueLength == ( xQueueSizeInBytes / uxItemSize ) ) );
|
||||
|
||||
/* Check for addition overflow. */
|
||||
configASSERT( ( sizeof( Queue_t ) + xQueueSizeInBytes ) > xQueueSizeInBytes );
|
||||
|
||||
/* Allocate the queue and storage area. Justification for MISRA
|
||||
deviation as follows: pvPortMalloc() always ensures returned memory
|
||||
blocks are aligned per the requirements of the MCU stack. In this case
|
||||
pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||
alignment requirements of the Queue_t structure - which in this case
|
||||
is an int8_t *. Therefore, whenever the stack alignment requirements
|
||||
are greater than or equal to the pointer to char requirements the cast
|
||||
is safe. In other cases alignment requirements are not strict (one or
|
||||
two bytes). */
|
||||
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */
|
||||
|
||||
if( pxNewQueue != NULL )
|
||||
{
|
||||
|
||||
@@ -164,7 +164,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
#endif
|
||||
uint32_t *threadptr;
|
||||
void *task_thread_local_start;
|
||||
extern int _thread_local_start, _thread_local_end, _rodata_start;
|
||||
extern int _thread_local_start, _thread_local_end, _flash_rodata_start, _flash_rodata_align;
|
||||
// TODO: check that TLS area fits the stack
|
||||
uint32_t thread_local_sz = (uint8_t *)&_thread_local_end - (uint8_t *)&_thread_local_start;
|
||||
|
||||
@@ -223,24 +223,62 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
frame->vpri = 0xFFFFFFFF;
|
||||
#endif
|
||||
|
||||
/* Init threadptr reg and TLS vars */
|
||||
/* Init threadptr register and set up TLS run-time area.
|
||||
* The following diagram illustrates the layout of link-time and run-time
|
||||
* TLS sections.
|
||||
*
|
||||
* +-------------+
|
||||
* |Section: | Linker symbols:
|
||||
* |.flash.rodata| ---------------
|
||||
* 0x0+-------------+ <-- _flash_rodata_start
|
||||
* ^ | |
|
||||
* | | Other data |
|
||||
* | | ... |
|
||||
* | +-------------+ <-- _thread_local_start
|
||||
* | |.tbss | ^
|
||||
* v | | |
|
||||
* 0xNNNN|int example; | | (thread_local_size)
|
||||
* |.tdata | v
|
||||
* +-------------+ <-- _thread_local_end
|
||||
* | Other data |
|
||||
* | ... |
|
||||
* | |
|
||||
* +-------------+
|
||||
*
|
||||
* Local variables of
|
||||
* pxPortInitialiseStack
|
||||
* -----------------------
|
||||
* +-------------+ <-- pxTopOfStack
|
||||
* |.tdata (*) | ^
|
||||
* ^ |int example; | |(thread_local_size
|
||||
* | | | |
|
||||
* | |.tbss (*) | v
|
||||
* | +-------------+ <-- task_thread_local_start
|
||||
* 0xNNNN | | | ^
|
||||
* | | | |
|
||||
* | | | |_thread_local_start - _rodata_start
|
||||
* | | | |
|
||||
* | | | v
|
||||
* v +-------------+ <-- threadptr
|
||||
*
|
||||
* (*) The stack grows downward!
|
||||
*/
|
||||
task_thread_local_start = (void *)(((uint32_t)pxTopOfStack - XT_CP_SIZE - thread_local_sz) & ~0xf);
|
||||
memcpy(task_thread_local_start, &_thread_local_start, thread_local_sz);
|
||||
threadptr = (uint32_t *)(sp + XT_STK_EXTRA);
|
||||
/* Calculate THREADPTR value:
|
||||
/* Calculate THREADPTR value.
|
||||
* The generated code will add THREADPTR value to a constant value determined at link time,
|
||||
* to get the address of the TLS variable.
|
||||
* The constant value is calculated by the linker as follows
|
||||
* (search for 'tpoff' in elf32-xtensa.c in BFD):
|
||||
* offset = address - tls_section_vma + align_up(TCB_SIZE, tls_section_alignment)
|
||||
* where TCB_SIZE is hardcoded to 8. There doesn't seem to be a way to propagate
|
||||
* the section alignment value from the ld script into the code, so it is hardcoded
|
||||
* in both places.
|
||||
* where TCB_SIZE is hardcoded to 8.
|
||||
* Note this is slightly different compared to the RISC-V port, where offset = address - tls_section_vma.
|
||||
*/
|
||||
const uint32_t tls_section_alignment = 0x10; /* has to be in sync with ALIGN value of .flash.rodata section */
|
||||
const uint32_t tls_section_alignment = (uint32_t) &_flash_rodata_align; /* ALIGN value of .flash.rodata section */
|
||||
const uint32_t tcb_size = 8; /* Unrelated to FreeRTOS, this is the constant from BFD */
|
||||
const uint32_t base = (tcb_size + tls_section_alignment - 1) & (~(tls_section_alignment - 1));
|
||||
*threadptr = (uint32_t)task_thread_local_start - ((uint32_t)&_thread_local_start - (uint32_t)&_rodata_start) - base;
|
||||
*threadptr = (uint32_t)task_thread_local_start - ((uint32_t)&_thread_local_start - (uint32_t)&_flash_rodata_start) - base;
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Init the coprocessor save area (see xtensa_context.h) */
|
||||
@@ -385,7 +423,7 @@ uint32_t xPortGetTickRateHz(void) {
|
||||
void __attribute__((optimize("-O3"))) vPortEnterCritical(portMUX_TYPE *mux)
|
||||
{
|
||||
BaseType_t oldInterruptLevel = portENTER_CRITICAL_NESTED();
|
||||
/* Interrupts may already be disabled (because we're doing this recursively)
|
||||
/* Interrupts may already be disabled (because we're doing this recursively)
|
||||
* but we can't get the interrupt level after
|
||||
* vPortCPUAquireMutex, because it also may mess with interrupts.
|
||||
* Get it here first, then later figure out if we're nesting
|
||||
@@ -434,4 +472,4 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, c
|
||||
dest = strcat(dest, str[i]);
|
||||
}
|
||||
esp_system_abort(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,69 +91,69 @@
|
||||
#endif
|
||||
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B 22200
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_4B 10000
|
||||
#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 53400
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_4B 30000
|
||||
#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 (701*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_WR_2KB (400*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 (7088*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_RD_2KB (4000*1000)
|
||||
#endif
|
||||
//This value is usually around 44K, but there are some chips with such low performance....
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE 12000
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE 6000
|
||||
#endif
|
||||
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 27400
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_4B 10000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B 53600
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_4B 30000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB (694*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_WR_2KB (400*1000)
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB (7797*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_RD_2KB (4000*1000)
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 44300
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_ERASE 20000
|
||||
#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 24400
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_4B 10000
|
||||
#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 50100
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_4B 30000
|
||||
#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 (618*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_WR_2KB (400*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 (1601*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_RD_2KB (800*1000)
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE 59800
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_SPI1_ERASE 30000
|
||||
#endif
|
||||
|
||||
// Some performance value based on the test against GD chip with single_core config.
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 68900
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_WR_4B 40000
|
||||
#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 (359*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_4B (200*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 (475*1000)
|
||||
#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 (1697*1000)
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_RD_2KB (900*1000)
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 76600
|
||||
#define IDF_PERFORMANCE_MIN_FLASH_SPEED_BYTE_PER_SEC_EXT_ERASE 40000
|
||||
#endif
|
||||
|
||||
//time to perform the task selection plus context switch (from task)
|
||||
|
||||
Submodule components/lwip/lwip updated: 7285b846a2...2c9c531f0a
@@ -876,6 +876,7 @@ u32_t lwip_hook_tcp_isn(const struct ip_addr *local_ip, u16_t local_port,
|
||||
#define ESP_SOCKET 1
|
||||
#define ESP_LWIP_SELECT 1
|
||||
#define ESP_LWIP_LOCK 1
|
||||
#define ESP_THREAD_PROTECTION 1
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV6_AUTOCONFIG
|
||||
#define ESP_IPV6_AUTOCONFIG CONFIG_LWIP_IPV6_AUTOCONFIG
|
||||
@@ -901,6 +902,7 @@ u32_t lwip_hook_tcp_isn(const struct ip_addr *local_ip, u16_t local_port,
|
||||
* DHCP_DEBUG: Enable debugging in dhcp.c.
|
||||
*/
|
||||
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||
#define ESP_DHCP_DEBUG LWIP_DBG_OFF
|
||||
#define LWIP_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_DEBUG LWIP_DBG_OFF
|
||||
|
||||
|
||||
@@ -15,17 +15,22 @@ menu "mbedTLS"
|
||||
mbedtls_platform_set_calloc_free() function
|
||||
- Internal IRAM memory wherever applicable else internal DRAM
|
||||
|
||||
Recommended mode here is always internal, since that is most preferred
|
||||
Recommended mode here is always internal (*), since that is most preferred
|
||||
from security perspective. But if application requirement does not
|
||||
allow sufficient free internal memory then alternate mode can be
|
||||
selected.
|
||||
|
||||
(*) In case of ESP32-S2, hardware allows encryption of external
|
||||
SPIRAM contents provided hardware flash encryption feature is enabled.
|
||||
In that case, using external SPIRAM allocation strategy is also safe choice
|
||||
from security perspective.
|
||||
|
||||
config MBEDTLS_INTERNAL_MEM_ALLOC
|
||||
bool "Internal memory"
|
||||
|
||||
config MBEDTLS_EXTERNAL_MEM_ALLOC
|
||||
bool "External SPIRAM"
|
||||
depends on ESP32_SPIRAM_SUPPORT
|
||||
depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC
|
||||
|
||||
config MBEDTLS_DEFAULT_MEM_ALLOC
|
||||
bool "Default alloc mode"
|
||||
|
||||
@@ -23,6 +23,33 @@
|
||||
|
||||
static const char *TAG = "Dynamic Impl";
|
||||
|
||||
static void esp_mbedtls_set_buf_state(unsigned char *buf, esp_mbedtls_ssl_buf_states state)
|
||||
{
|
||||
struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]);
|
||||
temp->state = state;
|
||||
}
|
||||
|
||||
static esp_mbedtls_ssl_buf_states esp_mbedtls_get_buf_state(unsigned char *buf)
|
||||
{
|
||||
struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]);
|
||||
return temp->state;
|
||||
}
|
||||
|
||||
void esp_mbedtls_free_buf(unsigned char *buf)
|
||||
{
|
||||
struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]);
|
||||
ESP_LOGV(TAG, "free buffer @ %p", temp);
|
||||
mbedtls_free(temp);
|
||||
}
|
||||
|
||||
static void esp_mbedtls_init_ssl_buf(struct esp_mbedtls_ssl_buf *buf, unsigned int len)
|
||||
{
|
||||
if (buf) {
|
||||
buf->state = ESP_MBEDTLS_SSL_BUF_CACHED;
|
||||
buf->len = len;
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_mbedtls_parse_record_header(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
ssl->in_msgtype = ssl->in_hdr[0];
|
||||
@@ -118,21 +145,22 @@ static void init_rx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf)
|
||||
|
||||
static int esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context *ssl, int len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
|
||||
if (ssl->out_buf) {
|
||||
mbedtls_free(ssl->out_buf);
|
||||
esp_mbedtls_free_buf(ssl->out_buf);
|
||||
ssl->out_buf = NULL;
|
||||
}
|
||||
|
||||
buf = mbedtls_calloc(1, len);
|
||||
if (!buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", len);
|
||||
esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + len);
|
||||
if (!esp_buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + len);
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "add out buffer %d bytes @ %p", len, buf);
|
||||
ESP_LOGV(TAG, "add out buffer %d bytes @ %p", len, esp_buf->buf);
|
||||
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, len);
|
||||
/**
|
||||
* Mark the out_msg offset from ssl->out_buf.
|
||||
*
|
||||
@@ -140,7 +168,7 @@ static int esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context *ssl, int len)
|
||||
*/
|
||||
ssl->out_msg = (unsigned char *)MBEDTLS_SSL_HEADER_LEN;
|
||||
|
||||
init_tx_buffer(ssl, buf);
|
||||
init_tx_buffer(ssl, esp_buf->buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -150,7 +178,7 @@ int esp_mbedtls_setup_tx_buffer(mbedtls_ssl_context *ssl)
|
||||
CHECK_OK(esp_mbedtls_alloc_tx_buf(ssl, TX_IDLE_BUFFER_SIZE));
|
||||
|
||||
/* mark the out buffer has no data cached */
|
||||
ssl->out_iv = NULL;
|
||||
esp_mbedtls_set_buf_state(ssl->out_buf, ESP_MBEDTLS_SSL_BUF_NO_CACHED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -168,10 +196,7 @@ int esp_mbedtls_reset_add_tx_buffer(mbedtls_ssl_context *ssl)
|
||||
|
||||
int esp_mbedtls_reset_free_tx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
ESP_LOGV(TAG, "free out buffer @ %p", ssl->out_buf);
|
||||
|
||||
mbedtls_free(ssl->out_buf);
|
||||
|
||||
esp_mbedtls_free_buf(ssl->out_buf);
|
||||
init_tx_buffer(ssl, NULL);
|
||||
|
||||
CHECK_OK(esp_mbedtls_setup_tx_buffer(ssl));
|
||||
@@ -181,21 +206,22 @@ int esp_mbedtls_reset_free_tx_buffer(mbedtls_ssl_context *ssl)
|
||||
|
||||
int esp_mbedtls_reset_add_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
unsigned char *buf;
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
|
||||
if (ssl->in_buf) {
|
||||
mbedtls_free(ssl->in_buf);
|
||||
esp_mbedtls_free_buf(ssl->in_buf);
|
||||
ssl->in_buf = NULL;
|
||||
}
|
||||
|
||||
buf = mbedtls_calloc(1, MBEDTLS_SSL_IN_BUFFER_LEN);
|
||||
if (!buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN);
|
||||
esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + MBEDTLS_SSL_IN_BUFFER_LEN);
|
||||
if (!esp_buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + MBEDTLS_SSL_IN_BUFFER_LEN);
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "add in buffer %d bytes @ %p", MBEDTLS_SSL_IN_BUFFER_LEN, buf);
|
||||
ESP_LOGV(TAG, "add in buffer %d bytes @ %p", MBEDTLS_SSL_IN_BUFFER_LEN, esp_buf->buf);
|
||||
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, MBEDTLS_SSL_IN_BUFFER_LEN);
|
||||
/**
|
||||
* Mark the in_msg offset from ssl->in_buf.
|
||||
*
|
||||
@@ -203,38 +229,34 @@ int esp_mbedtls_reset_add_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
*/
|
||||
ssl->in_msg = (unsigned char *)MBEDTLS_SSL_HEADER_LEN;
|
||||
|
||||
init_rx_buffer(ssl, buf);
|
||||
init_rx_buffer(ssl, esp_buf->buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void esp_mbedtls_reset_free_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
ESP_LOGV(TAG, "free in buffer @ %p", ssl->in_buf);
|
||||
|
||||
mbedtls_free(ssl->in_buf);
|
||||
|
||||
init_rx_buffer(ssl, NULL);
|
||||
esp_mbedtls_free_buf(ssl->in_buf);
|
||||
init_rx_buffer(ssl, NULL);
|
||||
}
|
||||
|
||||
int esp_mbedtls_add_tx_buffer(mbedtls_ssl_context *ssl, size_t buffer_len)
|
||||
{
|
||||
int ret = 0;
|
||||
int cached = 0;
|
||||
unsigned char *buf;
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
unsigned char cache_buf[CACHE_BUFFER_SIZE];
|
||||
|
||||
ESP_LOGV(TAG, "--> add out");
|
||||
|
||||
if (ssl->out_buf) {
|
||||
if (ssl->out_iv) {
|
||||
if (esp_mbedtls_get_buf_state(ssl->out_buf) == ESP_MBEDTLS_SSL_BUF_CACHED) {
|
||||
ESP_LOGV(TAG, "out buffer is not empty");
|
||||
ret = 0;
|
||||
goto exit;
|
||||
} else {
|
||||
memcpy(cache_buf, ssl->out_buf, CACHE_BUFFER_SIZE);
|
||||
|
||||
mbedtls_free(ssl->out_buf);
|
||||
esp_mbedtls_free_buf(ssl->out_buf);
|
||||
init_tx_buffer(ssl, NULL);
|
||||
cached = 1;
|
||||
}
|
||||
@@ -242,15 +264,17 @@ int esp_mbedtls_add_tx_buffer(mbedtls_ssl_context *ssl, size_t buffer_len)
|
||||
|
||||
buffer_len = tx_buffer_len(ssl, buffer_len);
|
||||
|
||||
buf = mbedtls_calloc(1, buffer_len);
|
||||
if (!buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", 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);
|
||||
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "add out buffer %d bytes @ %p", buffer_len, buf);
|
||||
init_tx_buffer(ssl, buf);
|
||||
ESP_LOGV(TAG, "add out buffer %d bytes @ %p", buffer_len, esp_buf->buf);
|
||||
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, buffer_len);
|
||||
init_tx_buffer(ssl, esp_buf->buf);
|
||||
|
||||
if (cached) {
|
||||
memcpy(ssl->out_ctr, cache_buf, COUNTER_SIZE);
|
||||
@@ -270,11 +294,11 @@ int esp_mbedtls_free_tx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[CACHE_BUFFER_SIZE];
|
||||
unsigned char *pdata;
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
|
||||
ESP_LOGV(TAG, "--> free out");
|
||||
|
||||
if (!ssl->out_buf || (ssl->out_buf && !ssl->out_iv)) {
|
||||
if (!ssl->out_buf || (ssl->out_buf && (esp_mbedtls_get_buf_state(ssl->out_buf) == ESP_MBEDTLS_SSL_BUF_NO_CACHED))) {
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
@@ -282,22 +306,19 @@ int esp_mbedtls_free_tx_buffer(mbedtls_ssl_context *ssl)
|
||||
memcpy(buf, ssl->out_ctr, COUNTER_SIZE);
|
||||
memcpy(buf + COUNTER_SIZE, ssl->out_iv, CACHE_IV_SIZE);
|
||||
|
||||
ESP_LOGV(TAG, "free out buffer @ %p", ssl->out_buf);
|
||||
|
||||
mbedtls_free(ssl->out_buf);
|
||||
|
||||
esp_mbedtls_free_buf(ssl->out_buf);
|
||||
init_tx_buffer(ssl, NULL);
|
||||
|
||||
pdata = mbedtls_calloc(1, TX_IDLE_BUFFER_SIZE);
|
||||
if (!pdata) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", TX_IDLE_BUFFER_SIZE);
|
||||
esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + TX_IDLE_BUFFER_SIZE);
|
||||
if (!esp_buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + TX_IDLE_BUFFER_SIZE);
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
memcpy(pdata, buf, CACHE_BUFFER_SIZE);
|
||||
init_tx_buffer(ssl, pdata);
|
||||
ssl->out_iv = NULL;
|
||||
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, TX_IDLE_BUFFER_SIZE);
|
||||
memcpy(esp_buf->buf, buf, CACHE_BUFFER_SIZE);
|
||||
init_tx_buffer(ssl, esp_buf->buf);
|
||||
esp_mbedtls_set_buf_state(ssl->out_buf, ESP_MBEDTLS_SSL_BUF_NO_CACHED);
|
||||
exit:
|
||||
ESP_LOGV(TAG, "<-- free out");
|
||||
|
||||
@@ -309,7 +330,7 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
int cached = 0;
|
||||
int ret = 0;
|
||||
int buffer_len;
|
||||
unsigned char *buf;
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
unsigned char cache_buf[16];
|
||||
unsigned char msg_head[5];
|
||||
size_t in_msglen, in_left;
|
||||
@@ -317,9 +338,13 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
ESP_LOGV(TAG, "--> add rx");
|
||||
|
||||
if (ssl->in_buf) {
|
||||
ESP_LOGV(TAG, "in buffer is not empty");
|
||||
ret = 0;
|
||||
goto exit;
|
||||
if (esp_mbedtls_get_buf_state(ssl->in_buf) == ESP_MBEDTLS_SSL_BUF_CACHED) {
|
||||
ESP_LOGV(TAG, "in buffer is not empty");
|
||||
ret = 0;
|
||||
goto exit;
|
||||
} else {
|
||||
cached = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ssl->in_hdr = msg_head;
|
||||
@@ -346,22 +371,23 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
ESP_LOGV(TAG, "message length is %d RX buffer length should be %d left is %d",
|
||||
(int)in_msglen, (int)buffer_len, (int)ssl->in_left);
|
||||
|
||||
buf = mbedtls_calloc(1, buffer_len);
|
||||
if (!buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", buffer_len);
|
||||
if (cached) {
|
||||
memcpy(cache_buf, ssl->in_buf, 16);
|
||||
esp_mbedtls_free_buf(ssl->in_buf);
|
||||
init_rx_buffer(ssl, NULL);
|
||||
}
|
||||
|
||||
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);
|
||||
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "add in buffer %d bytes @ %p", buffer_len, buf);
|
||||
ESP_LOGV(TAG, "add in buffer %d bytes @ %p", buffer_len, esp_buf->buf);
|
||||
|
||||
if (ssl->in_ctr) {
|
||||
memcpy(cache_buf, ssl->in_ctr, 16);
|
||||
mbedtls_free(ssl->in_ctr);
|
||||
cached = 1;
|
||||
}
|
||||
|
||||
init_rx_buffer(ssl, buf);
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, buffer_len);
|
||||
init_rx_buffer(ssl, esp_buf->buf);
|
||||
|
||||
if (cached) {
|
||||
memcpy(ssl->in_ctr, cache_buf, 8);
|
||||
@@ -382,14 +408,15 @@ int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[16];
|
||||
unsigned char *pdata;
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
|
||||
ESP_LOGV(TAG, "--> free rx");
|
||||
|
||||
/**
|
||||
* When have read multi messages once, can't free the input buffer directly.
|
||||
*/
|
||||
if (!ssl->in_buf || (ssl->in_hslen && (ssl->in_hslen < ssl->in_msglen))) {
|
||||
if (!ssl->in_buf || (ssl->in_hslen && (ssl->in_hslen < ssl->in_msglen)) ||
|
||||
(ssl->in_buf && (esp_mbedtls_get_buf_state(ssl->in_buf) == ESP_MBEDTLS_SSL_BUF_NO_CACHED))) {
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
@@ -404,22 +431,20 @@ int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
memcpy(buf, ssl->in_ctr, 8);
|
||||
memcpy(buf + 8, ssl->in_iv, 8);
|
||||
|
||||
ESP_LOGV(TAG, "free in buffer @ %p", ssl->out_buf);
|
||||
|
||||
mbedtls_free(ssl->in_buf);
|
||||
|
||||
esp_mbedtls_free_buf(ssl->in_buf);
|
||||
init_rx_buffer(ssl, NULL);
|
||||
|
||||
pdata = mbedtls_calloc(1, 16);
|
||||
if (!pdata) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", 16);
|
||||
esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + 16);
|
||||
if (!esp_buf) {
|
||||
ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + 16);
|
||||
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(pdata, buf, 16);
|
||||
ssl->in_ctr = pdata;
|
||||
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, 16);
|
||||
memcpy(esp_buf->buf, buf, 16);
|
||||
init_rx_buffer(ssl, esp_buf->buf);
|
||||
esp_mbedtls_set_buf_state(ssl->in_buf, ESP_MBEDTLS_SSL_BUF_NO_CACHED);
|
||||
exit:
|
||||
ESP_LOGV(TAG, "<-- free rx");
|
||||
|
||||
@@ -516,4 +541,17 @@ void esp_mbedtls_free_peer_cert(mbedtls_ssl_context *ssl)
|
||||
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
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
\
|
||||
if ((_ret = _fn) != 0) { \
|
||||
ESP_LOGV(TAG, "\"%s\" result is -0x%x", # _fn, -_ret); \
|
||||
if (_ret == MBEDTLS_ERR_SSL_CONN_EOF) {\
|
||||
return 0; \
|
||||
} \
|
||||
TRACE_CHECK(_fn, "fail"); \
|
||||
return _ret; \
|
||||
} \
|
||||
@@ -44,6 +41,21 @@
|
||||
\
|
||||
})
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SSL_BUF_CACHED,
|
||||
ESP_MBEDTLS_SSL_BUF_NO_CACHED,
|
||||
} esp_mbedtls_ssl_buf_states;
|
||||
|
||||
struct esp_mbedtls_ssl_buf {
|
||||
esp_mbedtls_ssl_buf_states state;
|
||||
unsigned int len;
|
||||
unsigned char buf[];
|
||||
};
|
||||
|
||||
#define SSL_BUF_HEAD_OFFSET_SIZE offsetof(struct esp_mbedtls_ssl_buf, buf)
|
||||
|
||||
void esp_mbedtls_free_buf(unsigned char *buf);
|
||||
|
||||
int esp_mbedtls_setup_tx_buffer(mbedtls_ssl_context *ssl);
|
||||
|
||||
void esp_mbedtls_setup_rx_buffer(mbedtls_ssl_context *ssl);
|
||||
@@ -82,6 +94,8 @@ void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl);
|
||||
|
||||
#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_ */
|
||||
|
||||
@@ -73,7 +73,17 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add)
|
||||
CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
|
||||
}
|
||||
#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT
|
||||
esp_mbedtls_free_peer_cert(ssl);
|
||||
/**
|
||||
* 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;
|
||||
@@ -123,6 +133,12 @@ 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:
|
||||
|
||||
@@ -85,7 +85,16 @@ int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t
|
||||
{
|
||||
int ret;
|
||||
|
||||
CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
|
||||
ESP_LOGD(TAG, "add mbedtls RX buffer");
|
||||
ret = esp_mbedtls_add_rx_buffer(ssl);
|
||||
if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
|
||||
ESP_LOGD(TAG, "fail, the connection indicated an EOF");
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
ESP_LOGD(TAG, "fail, error=-0x%x", -ret);
|
||||
return ret;
|
||||
}
|
||||
ESP_LOGD(TAG, "end");
|
||||
|
||||
ret = __real_mbedtls_ssl_read(ssl, buf, len);
|
||||
|
||||
@@ -99,12 +108,12 @@ int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t
|
||||
void __wrap_mbedtls_ssl_free(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
if (ssl->out_buf) {
|
||||
mbedtls_free(ssl->out_buf);
|
||||
esp_mbedtls_free_buf(ssl->out_buf);
|
||||
ssl->out_buf = NULL;
|
||||
}
|
||||
|
||||
if (ssl->in_buf) {
|
||||
mbedtls_free(ssl->in_buf);
|
||||
esp_mbedtls_free_buf(ssl->in_buf);
|
||||
ssl->in_buf = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -405,7 +405,8 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
||||
{
|
||||
lldesc_t stream_in_desc, stream_out_desc;
|
||||
lldesc_t *in_desc_head, *out_desc_head;
|
||||
lldesc_t *block_desc = NULL, *block_in_desc, *block_out_desc;
|
||||
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
|
||||
@@ -472,8 +473,10 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
||||
block_in_desc = block_desc;
|
||||
block_out_desc = block_desc + lldesc_num;
|
||||
|
||||
lldesc_setup_link(block_desc, input, block_bytes, 0);
|
||||
lldesc_setup_link(block_desc + lldesc_num, output, block_bytes, 0);
|
||||
lldesc_setup_link(block_in_desc, input, block_bytes, 0);
|
||||
lldesc_setup_link(block_out_desc, output, block_bytes, 0);
|
||||
|
||||
out_desc_tail = &block_out_desc[lldesc_num - 1];
|
||||
}
|
||||
|
||||
/* Any leftover bytes which are appended as an additional DMA list */
|
||||
@@ -488,6 +491,8 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
||||
block_in_desc[lldesc_num - 1].empty = (uint32_t)&stream_in_desc;
|
||||
block_out_desc[lldesc_num - 1].empty = (uint32_t)&stream_out_desc;
|
||||
}
|
||||
|
||||
out_desc_tail = &stream_out_desc;
|
||||
}
|
||||
|
||||
// block buffers are sent to DMA first, unless there aren't any
|
||||
@@ -516,7 +521,7 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
||||
|
||||
/* Start AES operation */
|
||||
REG_WRITE(AES_TRIGGER_REG, 1);
|
||||
esp_aes_dma_wait_complete(use_intr, out_desc_head);
|
||||
esp_aes_dma_wait_complete(use_intr, out_desc_tail);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
@@ -73,7 +74,7 @@ TEST_CASE("mbedtls CTR stream test", "[aes]")
|
||||
no matter how many bytes we encrypt each call
|
||||
*/
|
||||
for (int bytes_to_process = 1; bytes_to_process < SZ; bytes_to_process++) {
|
||||
|
||||
ESP_LOGD("test", "bytes_to_process %d", bytes_to_process);
|
||||
memset(nonce, 0xEE, 16);
|
||||
memset(chipertext, 0x0, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
@@ -87,10 +88,14 @@ TEST_CASE("mbedtls CTR stream test", "[aes]")
|
||||
mbedtls_aes_crypt_ctr(&ctx, length, &offset, nonce,
|
||||
stream_block, plaintext + idx, chipertext + idx );
|
||||
}
|
||||
ESP_LOG_BUFFER_HEXDUMP("expected", expected_cipher, SZ, ESP_LOG_DEBUG);
|
||||
ESP_LOG_BUFFER_HEXDUMP("actual ", chipertext, SZ, ESP_LOG_DEBUG);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, chipertext, SZ);
|
||||
|
||||
// Decrypt
|
||||
memset(nonce, 0xEE, 16);
|
||||
memset(decryptedtext, 0x22, SZ);
|
||||
offset = 0;
|
||||
for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) {
|
||||
// Limit length of last call to avoid exceeding buffer size
|
||||
@@ -98,6 +103,7 @@ TEST_CASE("mbedtls CTR stream test", "[aes]")
|
||||
mbedtls_aes_crypt_ctr(&ctx, length, &offset, nonce,
|
||||
stream_block, chipertext + idx, decryptedtext + idx );
|
||||
}
|
||||
ESP_LOG_BUFFER_HEXDUMP("decrypted", decryptedtext, SZ, ESP_LOG_DEBUG);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
}
|
||||
free(plaintext);
|
||||
@@ -273,6 +279,7 @@ TEST_CASE("mbedtls OFB stream test", "[aes]")
|
||||
*/
|
||||
|
||||
for (int bytes_to_process = 1; bytes_to_process < SZ; bytes_to_process++) {
|
||||
ESP_LOGD("test", "bytes_to_process %d", bytes_to_process);
|
||||
// Encrypt
|
||||
memset(iv, 0xEE, 16);
|
||||
size_t offset = 0;
|
||||
@@ -286,6 +293,7 @@ TEST_CASE("mbedtls OFB stream test", "[aes]")
|
||||
|
||||
// Decrypt
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(decryptedtext, 0x22, SZ);
|
||||
offset = 0;
|
||||
for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) {
|
||||
// Limit length of last call to avoid exceeding buffer size
|
||||
|
||||
@@ -52,6 +52,7 @@ menu "Partition Table"
|
||||
config PARTITION_TABLE_MD5
|
||||
bool "Generate an MD5 checksum for the partition table"
|
||||
default y
|
||||
depends on !ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS
|
||||
help
|
||||
Generate an MD5 checksum for the partition table for protecting the
|
||||
integrity of the table. The generation should be turned off for legacy
|
||||
|
||||
@@ -396,11 +396,6 @@ bool rtc_clk_8md256_enabled(void);
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
|
||||
|
||||
/**
|
||||
* @brief Set XTAL wait cycles by RTC slow clock's period
|
||||
*/
|
||||
void rtc_clk_set_xtal_wait(void);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
* @param slow_freq clock source (one of rtc_slow_freq_t values)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "esp_attr.h"
|
||||
#include "hal/uart_types.h"
|
||||
#include "soc/uart_periph.h"
|
||||
|
||||
@@ -66,7 +67,7 @@ typedef enum {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
|
||||
{
|
||||
uint32_t sclk_freq = (source_clk == UART_SCLK_APB) ? APB_CLK_FREQ : REF_CLK_FREQ;
|
||||
uint32_t clk_div = ((sclk_freq) << 4) / baud;
|
||||
@@ -85,7 +86,7 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk,
|
||||
*
|
||||
* @return The current baudrate
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
|
||||
{
|
||||
uint32_t src_clk = hw->conf0.tick_ref_always_on ? APB_CLK_FREQ : REF_CLK_FREQ;
|
||||
typeof(hw->clk_div) div_reg = hw->clk_div;
|
||||
@@ -100,7 +101,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val |= mask;
|
||||
}
|
||||
@@ -113,7 +114,7 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
}
|
||||
@@ -125,7 +126,7 @@ static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return The UART interrupt status.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
|
||||
{
|
||||
return hw->int_st.val;
|
||||
}
|
||||
@@ -138,7 +139,7 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@@ -150,7 +151,7 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return Interrupt enabled value
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
|
||||
{
|
||||
return hw->int_ena.val;
|
||||
}
|
||||
@@ -164,7 +165,7 @@ static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len)
|
||||
FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len)
|
||||
{
|
||||
//Get the UART APB fifo addr. Read fifo, we use APB address
|
||||
uint32_t fifo_addr = (hw == &UART0) ? UART_FIFO_REG(0) : (hw == &UART1) ? UART_FIFO_REG(1) : UART_FIFO_REG(2);
|
||||
@@ -185,7 +186,7 @@ static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len)
|
||||
FORCE_INLINE_ATTR void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len)
|
||||
{
|
||||
//Get the UART AHB fifo addr, Write fifo, we use AHB address
|
||||
uint32_t fifo_addr = (hw == &UART0) ? UART_FIFO_AHB_REG(0) : (hw == &UART1) ? UART_FIFO_AHB_REG(1) : UART_FIFO_AHB_REG(2);
|
||||
@@ -201,7 +202,7 @@ static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||
{
|
||||
//Hardware issue: we can not use `rxfifo_rst` to reset the hw rxfifo.
|
||||
uint16_t fifo_cnt;
|
||||
@@ -230,7 +231,7 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
{
|
||||
if (hw == &UART0) {
|
||||
hw->conf0.txfifo_rst = 1;
|
||||
@@ -245,7 +246,7 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
*
|
||||
* @return The readable data length in rxfifo.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
{
|
||||
uint32_t fifo_cnt = hw->status.rxfifo_cnt;
|
||||
typeof(hw->mem_rx_status) rx_status = hw->mem_rx_status;
|
||||
@@ -271,7 +272,7 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
*
|
||||
* @return The data length of txfifo can be written.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
{
|
||||
return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt;
|
||||
}
|
||||
@@ -284,7 +285,7 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit)
|
||||
{
|
||||
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
|
||||
if(stop_bit == UART_STOP_BITS_2) {
|
||||
@@ -304,7 +305,7 @@ static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_b
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit)
|
||||
{
|
||||
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
|
||||
if(hw->rs485_conf.dl1_en == 1 && hw->conf0.stop_bit_num == 0x1) {
|
||||
@@ -322,7 +323,7 @@ static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
|
||||
{
|
||||
if(parity_mode != UART_PARITY_DISABLE) {
|
||||
hw->conf0.parity = parity_mode & 0x1;
|
||||
@@ -338,7 +339,7 @@ static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode)
|
||||
{
|
||||
if(hw->conf0.parity_en) {
|
||||
*parity_mode = 0X2 | hw->conf0.parity;
|
||||
@@ -356,7 +357,7 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd)
|
||||
{
|
||||
hw->conf1.rxfifo_full_thrhd = full_thrhd;
|
||||
}
|
||||
@@ -370,7 +371,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd)
|
||||
{
|
||||
hw->conf1.txfifo_empty_thrhd = empty_thrhd;
|
||||
}
|
||||
@@ -384,7 +385,7 @@ static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_t
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
|
||||
{
|
||||
hw->idle_conf.rx_idle_thrhd = rx_idle_thr;
|
||||
}
|
||||
@@ -397,7 +398,7 @@ static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
|
||||
{
|
||||
hw->idle_conf.tx_idle_num = idle_num;
|
||||
}
|
||||
@@ -410,7 +411,7 @@ static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
|
||||
FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
|
||||
{
|
||||
if(break_num > 0) {
|
||||
hw->idle_conf.tx_brk_num = break_num;
|
||||
@@ -429,7 +430,7 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs)
|
||||
{
|
||||
//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set.
|
||||
if(flow_ctrl & UART_HW_FLOWCTRL_RTS) {
|
||||
@@ -453,7 +454,7 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl)
|
||||
{
|
||||
*flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
||||
if(hw->conf1.rx_flow_en) {
|
||||
@@ -473,7 +474,7 @@ static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en)
|
||||
{
|
||||
if(sw_flow_ctrl_en) {
|
||||
hw->flow_conf.xonoff_del = 1;
|
||||
@@ -501,7 +502,7 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char)
|
||||
{
|
||||
hw->at_cmd_char.data = cmd_char->cmd_char;
|
||||
hw->at_cmd_char.char_num = cmd_char->char_num;
|
||||
@@ -518,7 +519,7 @@ static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_ch
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit)
|
||||
{
|
||||
hw->conf0.bit_num = data_bit;
|
||||
}
|
||||
@@ -531,7 +532,7 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
|
||||
{
|
||||
*source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK;
|
||||
}
|
||||
@@ -544,7 +545,7 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
|
||||
{
|
||||
hw->conf0.sw_rts = level & 0x1;
|
||||
}
|
||||
@@ -557,7 +558,7 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
|
||||
{
|
||||
hw->conf0.sw_dtr = level & 0x1;
|
||||
}
|
||||
@@ -571,7 +572,7 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
{
|
||||
hw->sleep_conf.active_threshold = wakeup_thrd - SOC_UART_MIN_WAKEUP_THRESH;
|
||||
}
|
||||
@@ -583,7 +584,7 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
{
|
||||
hw->rs485_conf.en = 0;
|
||||
hw->rs485_conf.tx_rx_en = 0;
|
||||
@@ -598,7 +599,7 @@ static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
{
|
||||
// Application software control, remove echo
|
||||
hw->rs485_conf.rx_busy_tx_en = 1;
|
||||
@@ -615,7 +616,7 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
{
|
||||
// Enable receiver, sw_rts = 1 generates low level on RTS pin
|
||||
hw->conf0.sw_rts = 1;
|
||||
@@ -634,7 +635,7 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
{
|
||||
hw->conf0.irda_en = 0;
|
||||
// Transmitters output signal loop back to the receivers input signal
|
||||
@@ -652,7 +653,7 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
{
|
||||
hw->rs485_conf.en = 0;
|
||||
hw->rs485_conf.tx_rx_en = 0;
|
||||
@@ -669,7 +670,7 @@ static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
default:
|
||||
@@ -700,7 +701,7 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num)
|
||||
{
|
||||
*cmd_char = hw->at_cmd_char.data;
|
||||
*char_num = hw->at_cmd_char.char_num;
|
||||
@@ -713,7 +714,7 @@ static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, ui
|
||||
*
|
||||
* @return The UART wakeup threshold value.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
|
||||
{
|
||||
return hw->sleep_conf.active_threshold + SOC_UART_MIN_WAKEUP_THRESH;
|
||||
}
|
||||
@@ -726,7 +727,7 @@ static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
|
||||
*
|
||||
* @return The bit mode.
|
||||
*/
|
||||
static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit)
|
||||
{
|
||||
*data_bit = hw->conf0.bit_num;
|
||||
}
|
||||
@@ -738,7 +739,7 @@ static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *
|
||||
*
|
||||
* @return True if the state machine is in the IDLE state, otherwise false is returned.
|
||||
*/
|
||||
static inline bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
{
|
||||
typeof(hw->status) status = hw->status;
|
||||
return ((status.txfifo_cnt == 0) && (status.st_utx_out == 0));
|
||||
@@ -751,7 +752,7 @@ static inline bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
*
|
||||
* @return True if hw rts flow control is enabled, otherwise false is returned.
|
||||
*/
|
||||
static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
|
||||
{
|
||||
return hw->conf1.rx_flow_en;
|
||||
}
|
||||
@@ -763,7 +764,7 @@ static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
|
||||
*
|
||||
* @return True if hw cts flow control is enabled, otherwise false is returned.
|
||||
*/
|
||||
static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
|
||||
{
|
||||
return hw->conf0.tx_flow_en;
|
||||
}
|
||||
@@ -776,7 +777,7 @@ static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
|
||||
{
|
||||
hw->conf0.loopback = loop_back_en;
|
||||
}
|
||||
@@ -790,7 +791,7 @@ static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
{
|
||||
typeof(hw->conf0) conf0_reg = hw->conf0;
|
||||
conf0_reg.irda_tx_inv = (inv_mask & UART_SIGNAL_IRDA_TX_INV) ? 1 : 0;
|
||||
@@ -812,7 +813,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thr)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thr)
|
||||
{
|
||||
if (hw->conf0.tick_ref_always_on == 0) {
|
||||
//Hardware issue workaround: when using ref_tick, the rx timeout threshold needs increase to 10 times.
|
||||
@@ -837,7 +838,7 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thr)
|
||||
*
|
||||
* @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0.
|
||||
*/
|
||||
static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
{
|
||||
uint16_t tout_thrd = 0;
|
||||
if (hw->conf1.rx_tout_en > 0) {
|
||||
@@ -857,7 +858,7 @@ static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
*
|
||||
* @return maximum timeout threshold.
|
||||
*/
|
||||
static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||
{
|
||||
uint16_t tout_thrd = 0;
|
||||
if (hw->conf0.tick_ref_always_on == 0) {
|
||||
|
||||
@@ -190,6 +190,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
|
||||
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
|
||||
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
|
||||
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN, 0);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#pragma once
|
||||
#include "hal/uart_types.h"
|
||||
#include "soc/uart_periph.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -63,7 +64,7 @@ typedef enum {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
|
||||
{
|
||||
uint32_t sclk_freq = (source_clk == UART_SCLK_APB) ? APB_CLK_FREQ : REF_CLK_FREQ;
|
||||
uint32_t clk_div = ((sclk_freq) << 4) / baud;
|
||||
@@ -82,7 +83,7 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk,
|
||||
*
|
||||
* @return The current baudrate
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
|
||||
{
|
||||
uint32_t src_clk = hw->conf0.tick_ref_always_on ? APB_CLK_FREQ : REF_CLK_FREQ;
|
||||
typeof(hw->clk_div) div_reg = hw->clk_div;
|
||||
@@ -97,7 +98,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val |= mask;
|
||||
}
|
||||
@@ -110,7 +111,7 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
}
|
||||
@@ -122,7 +123,7 @@ static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return The UART interrupt status.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
|
||||
{
|
||||
return hw->int_st.val;
|
||||
}
|
||||
@@ -135,7 +136,7 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@@ -147,7 +148,7 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return interrupt enable value
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
|
||||
{
|
||||
return hw->int_ena.val;
|
||||
}
|
||||
@@ -161,7 +162,7 @@ static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len)
|
||||
FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len)
|
||||
{
|
||||
//Get the UART fifo addr, ESP32-S2 have 2 UART
|
||||
uint32_t fifo_addr = (hw == &UART0) ? UART_FIFO_AHB_REG(0) : UART_FIFO_AHB_REG(1);
|
||||
@@ -179,7 +180,7 @@ static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len)
|
||||
FORCE_INLINE_ATTR void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len)
|
||||
{
|
||||
//Get the UART fifo addr, ESP32-S2 have 2 UART
|
||||
uint32_t fifo_addr = (hw == &UART0) ? UART_FIFO_AHB_REG(0) : UART_FIFO_AHB_REG(1);
|
||||
@@ -195,7 +196,7 @@ static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||
{
|
||||
hw->conf0.rxfifo_rst = 1;
|
||||
hw->conf0.rxfifo_rst = 0;
|
||||
@@ -208,7 +209,7 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
{
|
||||
hw->conf0.txfifo_rst = 1;
|
||||
hw->conf0.txfifo_rst = 0;
|
||||
@@ -221,7 +222,7 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
*
|
||||
* @return The readable data length in rxfifo.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
{
|
||||
return hw->status.rxfifo_cnt;
|
||||
}
|
||||
@@ -233,7 +234,7 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
*
|
||||
* @return The data length of txfifo can be written.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
{
|
||||
return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt;
|
||||
}
|
||||
@@ -246,7 +247,7 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit)
|
||||
{
|
||||
hw->conf0.stop_bit_num = stop_bit;
|
||||
}
|
||||
@@ -259,7 +260,7 @@ static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_b
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit)
|
||||
{
|
||||
*stop_bit = hw->conf0.stop_bit_num;
|
||||
}
|
||||
@@ -272,7 +273,7 @@ static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
|
||||
{
|
||||
if(parity_mode != UART_PARITY_DISABLE) {
|
||||
hw->conf0.parity = parity_mode & 0x1;
|
||||
@@ -288,7 +289,7 @@ static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode)
|
||||
{
|
||||
if(hw->conf0.parity_en) {
|
||||
*parity_mode = 0X2 | hw->conf0.parity;
|
||||
@@ -306,7 +307,7 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd)
|
||||
{
|
||||
hw->conf1.rxfifo_full_thrhd = full_thrhd;
|
||||
}
|
||||
@@ -320,7 +321,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd)
|
||||
{
|
||||
hw->conf1.txfifo_empty_thrhd = empty_thrhd;
|
||||
}
|
||||
@@ -334,7 +335,7 @@ static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_t
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
|
||||
{
|
||||
hw->idle_conf.rx_idle_thrhd = rx_idle_thr;
|
||||
}
|
||||
@@ -347,7 +348,7 @@ static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
|
||||
{
|
||||
hw->idle_conf.tx_idle_num = idle_num;
|
||||
}
|
||||
@@ -360,7 +361,7 @@ static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
|
||||
FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
|
||||
{
|
||||
if(break_num > 0) {
|
||||
hw->idle_conf.tx_brk_num = break_num;
|
||||
@@ -379,7 +380,7 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs)
|
||||
{
|
||||
//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set.
|
||||
if(flow_ctrl & UART_HW_FLOWCTRL_RTS) {
|
||||
@@ -403,7 +404,7 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl)
|
||||
{
|
||||
*flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
||||
if(hw->conf1.rx_flow_en) {
|
||||
@@ -423,7 +424,7 @@ static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en)
|
||||
{
|
||||
if(sw_flow_ctrl_en) {
|
||||
hw->flow_conf.xonoff_del = 1;
|
||||
@@ -451,7 +452,7 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char)
|
||||
{
|
||||
hw->at_cmd_char.data = cmd_char->cmd_char;
|
||||
hw->at_cmd_char.char_num = cmd_char->char_num;
|
||||
@@ -468,7 +469,7 @@ static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_ch
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit)
|
||||
{
|
||||
hw->conf0.bit_num = data_bit;
|
||||
}
|
||||
@@ -481,7 +482,7 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
|
||||
{
|
||||
*source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK;
|
||||
}
|
||||
@@ -494,7 +495,7 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
|
||||
{
|
||||
hw->conf0.sw_rts = level & 0x1;
|
||||
}
|
||||
@@ -507,7 +508,7 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
|
||||
{
|
||||
hw->conf0.sw_dtr = level & 0x1;
|
||||
}
|
||||
@@ -521,7 +522,7 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
{
|
||||
hw->sleep_conf.active_threshold = wakeup_thrd - SOC_UART_MIN_WAKEUP_THRESH;
|
||||
}
|
||||
@@ -533,7 +534,7 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
{
|
||||
hw->rs485_conf.en = 0;
|
||||
hw->rs485_conf.tx_rx_en = 0;
|
||||
@@ -548,7 +549,7 @@ static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
{
|
||||
// Application software control, remove echo
|
||||
hw->rs485_conf.rx_busy_tx_en = 1;
|
||||
@@ -565,7 +566,7 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
{
|
||||
// Enable receiver, sw_rts = 1 generates low level on RTS pin
|
||||
hw->conf0.sw_rts = 1;
|
||||
@@ -584,7 +585,7 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
{
|
||||
hw->conf0.irda_en = 0;
|
||||
// Transmitters output signal loop back to the receivers input signal
|
||||
@@ -602,7 +603,7 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
{
|
||||
hw->rs485_conf.en = 0;
|
||||
hw->rs485_conf.tx_rx_en = 0;
|
||||
@@ -619,7 +620,7 @@ static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
default:
|
||||
@@ -650,7 +651,7 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num)
|
||||
{
|
||||
*cmd_char = hw->at_cmd_char.data;
|
||||
*char_num = hw->at_cmd_char.char_num;
|
||||
@@ -663,7 +664,7 @@ static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, ui
|
||||
*
|
||||
* @return The UART wakeup threshold value.
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
|
||||
{
|
||||
return hw->sleep_conf.active_threshold + SOC_UART_MIN_WAKEUP_THRESH;
|
||||
}
|
||||
@@ -676,7 +677,7 @@ static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
|
||||
*
|
||||
* @return The bit mode.
|
||||
*/
|
||||
static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit)
|
||||
FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit)
|
||||
{
|
||||
*data_bit = hw->conf0.bit_num;
|
||||
}
|
||||
@@ -688,7 +689,7 @@ static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *
|
||||
*
|
||||
* @return True if the state machine is in the IDLE state, otherwise false is returned.
|
||||
*/
|
||||
static inline bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
{
|
||||
return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0));
|
||||
}
|
||||
@@ -700,7 +701,7 @@ static inline bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
*
|
||||
* @return True if hw rts flow control is enabled, otherwise false is returned.
|
||||
*/
|
||||
static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
|
||||
{
|
||||
return hw->conf1.rx_flow_en;
|
||||
}
|
||||
@@ -712,7 +713,7 @@ static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
|
||||
*
|
||||
* @return True if hw cts flow control is enabled, otherwise false is returned.
|
||||
*/
|
||||
static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
|
||||
{
|
||||
return hw->conf0.tx_flow_en;
|
||||
}
|
||||
@@ -725,7 +726,7 @@ static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
|
||||
{
|
||||
hw->conf0.loopback = loop_back_en;
|
||||
}
|
||||
@@ -739,7 +740,7 @@ static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
{
|
||||
typeof(hw->conf0) conf0_reg = hw->conf0;
|
||||
conf0_reg.irda_tx_inv = (inv_mask & UART_SIGNAL_IRDA_TX_INV) ? 1 : 0;
|
||||
@@ -761,7 +762,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
|
||||
{
|
||||
uint16_t tout_val = tout_thrd;
|
||||
if(tout_thrd > 0) {
|
||||
@@ -779,7 +780,7 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
|
||||
*
|
||||
* @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0.
|
||||
*/
|
||||
static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
{
|
||||
uint16_t tout_thrd = 0;
|
||||
if(hw->conf1.rx_tout_en > 0) {
|
||||
@@ -795,7 +796,7 @@ static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
*
|
||||
* @return maximum timeout threshold.
|
||||
*/
|
||||
static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||
FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||
{
|
||||
return UART_RX_TOUT_THRHD_V;
|
||||
}
|
||||
|
||||
@@ -153,29 +153,6 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_set_xtal_wait(void)
|
||||
{
|
||||
/*
|
||||
the `xtal_wait` time need 1ms, so we need calibrate slow clk period,
|
||||
and `RTC_CNTL_XTL_BUF_WAIT` depend on it.
|
||||
*/
|
||||
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
|
||||
rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
|
||||
rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
|
||||
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
|
||||
if (slow_clk_freq == (rtc_slow_freq_x32k)) {
|
||||
cal_clk = RTC_CAL_32K_XTAL;
|
||||
} else if (slow_clk_freq == rtc_slow_freq_8MD256) {
|
||||
cal_clk = RTC_CAL_8MD256;
|
||||
}
|
||||
uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 2000);
|
||||
uint32_t xtal_wait_1ms = 100;
|
||||
if (slow_clk_period) {
|
||||
xtal_wait_1ms = (1000 << RTC_CLK_CAL_FRACT) / slow_clk_period;
|
||||
}
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, xtal_wait_1ms);
|
||||
}
|
||||
|
||||
void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
||||
@@ -190,7 +167,6 @@ void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
|
||||
so if the slow_clk is 8md256, clk_8m must be force power on
|
||||
*/
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU, (slow_freq == RTC_SLOW_FREQ_8MD256) ? 1 : 0);
|
||||
rtc_clk_set_xtal_wait();
|
||||
ets_delay_us(DELAY_SLOW_CLK_SWITCH);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ static const char *TAG = "rtc_init";
|
||||
void rtc_init(rtc_config_t cfg)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
|
||||
rtc_clk_set_xtal_wait();
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait);
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
|
||||
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
|
||||
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
|
||||
|
||||
@@ -26,6 +26,10 @@ void touch_hal_init(void)
|
||||
touch_ll_clear_trigger_status_mask();
|
||||
touch_ll_set_meas_times(TOUCH_PAD_MEASURE_CYCLE_DEFAULT);
|
||||
touch_ll_set_sleep_time(TOUCH_PAD_SLEEP_CYCLE_DEFAULT);
|
||||
/* Configure the touch-sensor power domain into self-bias since bandgap-bias
|
||||
* level is different under sleep-mode compared to running-mode. self-bias is
|
||||
* always on after chip startup. */
|
||||
touch_ll_sleep_low_power(true);
|
||||
touch_ll_set_voltage_high(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD);
|
||||
touch_ll_set_voltage_low(TOUCH_PAD_LOW_VOLTAGE_THRESHOLD);
|
||||
touch_ll_set_voltage_attenuation(TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD);
|
||||
@@ -142,9 +146,6 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable)
|
||||
if (enable) {
|
||||
touch_ll_sleep_set_channel_num(pad_num);
|
||||
touch_ll_sleep_set_threshold(SOC_TOUCH_PAD_THRESHOLD_MAX);
|
||||
/* Default change touch dbias to self-dbias to save power.
|
||||
Measuring the sleep pad threshold after `sleep_channel_set_config`. */
|
||||
touch_ll_sleep_low_power(true);
|
||||
touch_ll_sleep_reset_benchmark();
|
||||
} else {
|
||||
touch_ll_sleep_set_channel_num(TOUCH_PAD_NUM0);
|
||||
|
||||
@@ -128,7 +128,7 @@ TEST_CASE("Calculate 8M clock frequency", "[rtc_clk]")
|
||||
uint32_t rtc_8md256_period = rtc_clk_cal(RTC_CAL_8MD256, 100);
|
||||
uint32_t rtc_fast_freq_hz = 1000000ULL * (1 << RTC_CLK_CAL_FRACT) * 256 / rtc_8md256_period;
|
||||
printf("RTC_FAST_CLK=%d Hz\n", rtc_fast_freq_hz);
|
||||
TEST_ASSERT_INT32_WITHIN(500000, RTC_FAST_CLK_FREQ_APPROX, rtc_fast_freq_hz);
|
||||
TEST_ASSERT_INT32_WITHIN(650000, RTC_FAST_CLK_FREQ_APPROX, rtc_fast_freq_hz);
|
||||
}
|
||||
|
||||
TEST_CASE("Test switching between PLL and XTAL", "[rtc_clk]")
|
||||
|
||||
@@ -131,9 +131,9 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void)
|
||||
// Scheduler hasn't been started yet, it means that spi_flash API is being
|
||||
// called from the 2nd stage bootloader or from user_start_cpu0, i.e. from
|
||||
// PRO CPU. APP CPU is either in reset or spinning inside user_start_cpu1,
|
||||
// which is in IRAM. So it is safe to disable cache for the other_cpuid here.
|
||||
// which is in IRAM. So it is safe to disable cache for the other_cpuid after
|
||||
// esp_intr_noniram_disable.
|
||||
assert(other_cpuid == 1);
|
||||
spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]);
|
||||
} else {
|
||||
// Temporarily raise current task priority to prevent a deadlock while
|
||||
// waiting for IPC task to start on the other CPU
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/lock.h>
|
||||
#include "esp32/rom/md5_hash.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_flash.h"
|
||||
@@ -30,14 +31,14 @@
|
||||
|
||||
#define HASH_LEN 32 /* SHA-256 digest length */
|
||||
|
||||
#define MD5_DIGEST_LEN 16
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Enable built-in checks in queue.h in debug builds
|
||||
#define INVARIANTS
|
||||
#endif
|
||||
#include "sys/queue.h"
|
||||
|
||||
|
||||
|
||||
typedef struct partition_list_item_ {
|
||||
esp_partition_t info;
|
||||
bool user_registered;
|
||||
@@ -159,24 +160,53 @@ static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t typ
|
||||
// This function is called only once, with s_partition_list_lock taken.
|
||||
static esp_err_t load_partitions(void)
|
||||
{
|
||||
const uint32_t* ptr;
|
||||
const uint8_t *p_start;
|
||||
const uint8_t *p_end;
|
||||
spi_flash_mmap_handle_t handle;
|
||||
|
||||
// Temporary list of loaded partitions, if valid then we copy this to s_partition_list
|
||||
typeof(s_partition_list) new_partitions_list = SLIST_HEAD_INITIALIZER(s_partition_list);
|
||||
partition_list_item_t* last = NULL;
|
||||
|
||||
#if CONFIG_PARTITION_TABLE_MD5
|
||||
const uint8_t *md5_part = NULL;
|
||||
const uint8_t *stored_md5;
|
||||
uint8_t calc_md5[MD5_DIGEST_LEN];
|
||||
struct MD5Context context;
|
||||
|
||||
MD5Init(&context);
|
||||
#endif
|
||||
|
||||
// map 64kB block where partition table is located
|
||||
esp_err_t err = spi_flash_mmap(ESP_PARTITION_TABLE_OFFSET & 0xffff0000,
|
||||
SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_DATA, (const void**) &ptr, &handle);
|
||||
SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_DATA, (const void **)&p_start, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
// calculate partition address within mmap-ed region
|
||||
const esp_partition_info_t* it = (const esp_partition_info_t*)
|
||||
(ptr + (ESP_PARTITION_TABLE_OFFSET & 0xffff) / sizeof(*ptr));
|
||||
const esp_partition_info_t* end = it + SPI_FLASH_SEC_SIZE / sizeof(*it);
|
||||
// tail of the linked list of partitions
|
||||
partition_list_item_t* last = NULL;
|
||||
for (; it != end; ++it) {
|
||||
if (it->magic != ESP_PARTITION_MAGIC) {
|
||||
p_start += (ESP_PARTITION_TABLE_OFFSET & 0xffff);
|
||||
p_end = p_start + SPI_FLASH_SEC_SIZE;
|
||||
|
||||
for(const uint8_t *p_entry = p_start; p_entry < p_end; p_entry += sizeof(esp_partition_info_t)) {
|
||||
esp_partition_info_t entry;
|
||||
// copying to RAM instead of using pointer to flash to avoid any chance of TOCTOU due to cache miss
|
||||
// when flash encryption is used
|
||||
memcpy(&entry, p_entry, sizeof(entry));
|
||||
|
||||
#if CONFIG_PARTITION_TABLE_MD5
|
||||
if (entry.magic == ESP_PARTITION_MAGIC_MD5) {
|
||||
md5_part = p_entry;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (entry.magic != ESP_PARTITION_MAGIC) {
|
||||
break;
|
||||
}
|
||||
|
||||
#if CONFIG_PARTITION_TABLE_MD5
|
||||
MD5Update(&context, (void *)&entry, sizeof(entry));
|
||||
#endif
|
||||
|
||||
// allocate new linked list item and populate it with data from partition table
|
||||
partition_list_item_t* item = (partition_list_item_t*) calloc(sizeof(partition_list_item_t), 1);
|
||||
if (item == NULL) {
|
||||
@@ -184,35 +214,70 @@ static esp_err_t load_partitions(void)
|
||||
break;
|
||||
}
|
||||
item->info.flash_chip = esp_flash_default_chip;
|
||||
item->info.address = it->pos.offset;
|
||||
item->info.size = it->pos.size;
|
||||
item->info.type = it->type;
|
||||
item->info.subtype = it->subtype;
|
||||
item->info.encrypted = it->flags & PART_FLAG_ENCRYPTED;
|
||||
item->info.address = entry.pos.offset;
|
||||
item->info.size = entry.pos.size;
|
||||
item->info.type = entry.type;
|
||||
item->info.subtype = entry.subtype;
|
||||
item->info.encrypted = entry.flags & PART_FLAG_ENCRYPTED;
|
||||
item->user_registered = false;
|
||||
|
||||
if (!esp_flash_encryption_enabled()) {
|
||||
/* If flash encryption is not turned on, no partitions should be treated as encrypted */
|
||||
item->info.encrypted = false;
|
||||
} else if (it->type == PART_TYPE_APP
|
||||
|| (it->type == PART_TYPE_DATA && it->subtype == PART_SUBTYPE_DATA_OTA)
|
||||
|| (it->type == PART_TYPE_DATA && it->subtype == PART_SUBTYPE_DATA_NVS_KEYS)) {
|
||||
} else if (entry.type == PART_TYPE_APP
|
||||
|| (entry.type == PART_TYPE_DATA && entry.subtype == PART_SUBTYPE_DATA_OTA)
|
||||
|| (entry.type == PART_TYPE_DATA && entry.subtype == PART_SUBTYPE_DATA_NVS_KEYS)) {
|
||||
/* If encryption is turned on, all app partitions and OTA data
|
||||
are always encrypted */
|
||||
item->info.encrypted = true;
|
||||
}
|
||||
|
||||
// it->label may not be zero-terminated
|
||||
strncpy(item->info.label, (const char*) it->label, sizeof(item->info.label) - 1);
|
||||
item->info.label[sizeof(it->label)] = 0;
|
||||
// item->info.label is initialized by calloc, so resulting string will be null terminated
|
||||
strncpy(item->info.label, (const char*) entry.label, sizeof(item->info.label) - 1);
|
||||
|
||||
// add it to the list
|
||||
if (last == NULL) {
|
||||
SLIST_INSERT_HEAD(&s_partition_list, item, next);
|
||||
SLIST_INSERT_HEAD(&new_partitions_list, item, next);
|
||||
} else {
|
||||
SLIST_INSERT_AFTER(last, item, next);
|
||||
}
|
||||
last = item;
|
||||
}
|
||||
|
||||
#if CONFIG_PARTITION_TABLE_MD5
|
||||
if (md5_part == NULL) {
|
||||
ESP_LOGE(TAG, "No MD5 found in partition table");
|
||||
err = ESP_ERR_NOT_FOUND;
|
||||
} else {
|
||||
stored_md5 = md5_part + ESP_PARTITION_MD5_OFFSET;
|
||||
|
||||
MD5Final(calc_md5, &context);
|
||||
|
||||
ESP_LOG_BUFFER_HEXDUMP("calculated md5", calc_md5, MD5_DIGEST_LEN, ESP_LOG_VERBOSE);
|
||||
ESP_LOG_BUFFER_HEXDUMP("stored md5", stored_md5, MD5_DIGEST_LEN, ESP_LOG_VERBOSE);
|
||||
|
||||
if (memcmp(calc_md5, stored_md5, MD5_DIGEST_LEN) != 0) {
|
||||
ESP_LOGE(TAG, "Partition table MD5 mismatch");
|
||||
err = ESP_ERR_INVALID_STATE;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Partition table MD5 verified");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err == ESP_OK) {
|
||||
/* Don't copy the list to the static variable unless it's verified */
|
||||
s_partition_list = new_partitions_list;
|
||||
} else {
|
||||
/* Otherwise, free all the memory we just allocated */
|
||||
partition_list_item_t *it = new_partitions_list.slh_first;
|
||||
while (it) {
|
||||
partition_list_item_t *next = it->next.sle_next;
|
||||
free(it);
|
||||
it = next;
|
||||
}
|
||||
}
|
||||
|
||||
spi_flash_munmap(handle);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ endif()
|
||||
set(ULP_MAP_GEN ${PYTHON} ${IDF_PATH}/components/ulp/esp32ulp_mapgen.py)
|
||||
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/esp32.ulp.ld)
|
||||
|
||||
get_filename_component(sdkconfig_dir ${SDKCONFIG} DIRECTORY)
|
||||
get_filename_component(sdkconfig_dir ${SDKCONFIG_HEADER} DIRECTORY)
|
||||
|
||||
foreach(include ${COMPONENT_INCLUDES})
|
||||
list(APPEND component_includes -I${include})
|
||||
@@ -50,7 +50,7 @@ get_filename_component(ULP_LD_SCRIPT ${ULP_LD_TEMPLATE} NAME)
|
||||
add_custom_command( OUTPUT ${ULP_LD_SCRIPT}
|
||||
COMMAND ${CMAKE_C_COMPILER} -E -P -xc -o ${ULP_LD_SCRIPT} ${ULP_PREPROCESSOR_ARGS} ${ULP_LD_TEMPLATE}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${ULP_LD_TEMPLATE}
|
||||
DEPENDS ${ULP_LD_TEMPLATE} ${SDKCONFIG_HEADER}
|
||||
VERBATIM)
|
||||
add_custom_target(${ULP_APP_NAME}_ld_script
|
||||
DEPENDS ${ULP_LD_SCRIPT}
|
||||
|
||||
@@ -52,7 +52,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
|
||||
-DCOMPONENT_DIR=${COMPONENT_DIR}
|
||||
-DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES>
|
||||
-DIDF_PATH=${idf_path}
|
||||
-DSDKCONFIG=${SDKCONFIG_HEADER}
|
||||
-DSDKCONFIG_HEADER=${SDKCONFIG_HEADER}
|
||||
-DPYTHON=${python}
|
||||
${extra_cmake_args}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${app_name} --target build
|
||||
|
||||
@@ -64,6 +64,7 @@ int wpa_sm_get_key(uint8_t *ifx, int *alg, u8 *addr, int *key_idx, u8 *key, size
|
||||
void wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len);
|
||||
|
||||
void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm);
|
||||
static bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd);
|
||||
static inline enum wpa_states wpa_sm_get_state(struct wpa_sm *sm)
|
||||
{
|
||||
return sm->wpa_state;;
|
||||
@@ -806,11 +807,19 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm,
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
/* Detect possible key reinstallation */
|
||||
if (wpa_supplicant_gtk_in_use(sm, &(sm->gd))) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
|
||||
gd->keyidx, gd->tx, gd->gtk_len);
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
|
||||
"(keyidx=%d tx=%d len=%d).\n", gd->keyidx, gd->tx,
|
||||
gd->gtk_len);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
|
||||
if (sm->group_cipher == WPA_CIPHER_TKIP) {
|
||||
/* Swap Tx/Rx keys for Michael MIC */
|
||||
@@ -847,7 +856,7 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd)
|
||||
static bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd)
|
||||
{
|
||||
u8 *_gtk = gd->gtk;
|
||||
u8 gtk_buf[32];
|
||||
@@ -857,8 +866,6 @@ bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd)
|
||||
u8 bssid[6];
|
||||
int keyidx;
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "WPA: Judge GTK: (keyidx=%d len=%d).", gd->keyidx, gd->gtk_len);
|
||||
#endif
|
||||
@@ -871,19 +878,10 @@ bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd)
|
||||
_gtk = gtk_buf;
|
||||
}
|
||||
|
||||
//check if gtk is in use.
|
||||
if (wpa_sm_get_key(&ifx, &alg, bssid, &keyidx, gtk_get, gd->gtk_len, gd->keyidx) == 0) {
|
||||
if (wpa_sm_get_key(&ifx, &alg, bssid, &keyidx, gtk_get, gd->gtk_len, gd->keyidx - 2) == 0) {
|
||||
if (ifx == 0 && alg == gd->alg && memcmp(bssid, sm->bssid, ETH_ALEN) == 0 &&
|
||||
memcmp(_gtk, gtk_get, gd->gtk_len) == 0) {
|
||||
wpa_printf(MSG_DEBUG, "GTK %d is already in use in entry %d, it may be an attack, ignor it.", gd->keyidx, gd->keyidx + 2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wpa_sm_get_key(&ifx, &alg, bssid, &keyidx, gtk_get, gd->gtk_len, (gd->keyidx+1)%2) == 0) {
|
||||
if (ifx == 0 && alg == gd->alg && memcmp(bssid, sm->bssid, ETH_ALEN) == 0 &&
|
||||
memcmp(_gtk, gtk_get, gd->gtk_len) == 0) {
|
||||
wpa_printf(MSG_DEBUG, "GTK %d is already in use in entry %d, it may be an attack, ignor it.", gd->keyidx, (gd->keyidx+1)%2 + 2);
|
||||
wpa_printf(MSG_DEBUG, "GTK %d is already in use in entry %d, it may be an attack, ignore it.", gd->keyidx, hw_keyidx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1562,10 +1560,8 @@ failed:
|
||||
u16 rekey= (WPA_SM_STATE(sm) == WPA_COMPLETED);
|
||||
|
||||
if((sm->gd).gtk_len) {
|
||||
if (wpa_supplicant_gtk_in_use(sm, &(sm->gd)) == false) {
|
||||
if (wpa_supplicant_install_gtk(sm, &(sm->gd)))
|
||||
goto failed;
|
||||
}
|
||||
if (wpa_supplicant_install_gtk(sm, &(sm->gd)))
|
||||
goto failed;
|
||||
} else {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@@ -21,47 +21,32 @@ PROJECT_NAME = "ESP32 Programming Guide"
|
||||
## and used to include in API reference documentation
|
||||
|
||||
INPUT = \
|
||||
##
|
||||
## Wi-Fi - API Reference
|
||||
##
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_wifi.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_wifi_types.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_smartconfig.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_now.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_wifi_default.h \
|
||||
## Mesh - API Reference
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_mesh.h \
|
||||
## Event loop - API Reference
|
||||
$(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 \
|
||||
## Bluetooth - API Reference
|
||||
## Controller && VHCI
|
||||
$(IDF_PATH)/components/bt/include/esp_bt.h \
|
||||
## Bluetooth COMMON
|
||||
## Issue with __attribute__
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_bt_main.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_bt_device.h \
|
||||
## Bluetooth LE
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h \
|
||||
## Issue with __attribute__
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_blufi_api.h \
|
||||
## Bluetooth Classic
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h \
|
||||
## Issue with __attribute__
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_spp_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h \
|
||||
## NimBLE related Bluetooth APIs
|
||||
$(IDF_PATH)/components/bt/host/nimble/esp-hci/include/esp_nimble_hci.h \
|
||||
## ESP BLE Mesh APIs
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_low_power_api.h \
|
||||
@@ -75,17 +60,11 @@ INPUT = \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_sensor_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_time_scene_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h \
|
||||
##
|
||||
## Ethernet - API Reference
|
||||
##
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_com.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_mac.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_phy.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_netif_glue.h \
|
||||
##
|
||||
## Peripherals - API Reference
|
||||
##
|
||||
$(IDF_PATH)/components/driver/include/driver/gpio.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/rtc_io.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/i2c.h \
|
||||
@@ -132,38 +111,21 @@ INPUT = \
|
||||
$(IDF_PATH)/components/soc/soc/esp32/include/soc/touch_sensor_channel.h \
|
||||
$(IDF_PATH)/components/soc/soc/esp32/include/soc/uart_channel.h \
|
||||
$(IDF_PATH)/components/soc/soc/esp32/include/soc/rtc_io_channel.h \
|
||||
## esp_netif - API Reference
|
||||
$(IDF_PATH)/components/esp_netif/include/esp_netif.h \
|
||||
$(IDF_PATH)/components/esp_netif/include/esp_netif_net_stack.h \
|
||||
##
|
||||
## Protocols - API Reference
|
||||
##
|
||||
## ESP-TLS
|
||||
$(IDF_PATH)/components/esp-tls/esp_tls.h \
|
||||
## MQTT
|
||||
$(IDF_PATH)/components/mqtt/esp-mqtt/include/mqtt_client.h \
|
||||
## ICMP-ECHO
|
||||
$(IDF_PATH)/components/lwip/include/apps/ping/ping_sock.h \
|
||||
## SNTP
|
||||
$(IDF_PATH)/components/lwip/include/apps/sntp/sntp.h \
|
||||
## mDNS
|
||||
$(IDF_PATH)/components/mdns/include/mdns.h \
|
||||
$(IDF_PATH)/components/esp_http_client/include/esp_http_client.h \
|
||||
$(IDF_PATH)/components/esp_websocket_client/include/esp_websocket_client.h \
|
||||
## HTTP / HTTPS Server
|
||||
$(IDF_PATH)/components/esp_http_server/include/esp_http_server.h \
|
||||
$(IDF_PATH)/components/esp_https_server/include/esp_https_server.h \
|
||||
## ESP Local Ctrl
|
||||
$(IDF_PATH)/components/esp_local_ctrl/include/esp_local_ctrl.h \
|
||||
## ESP Serial Slave Link
|
||||
$(IDF_PATH)/components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \
|
||||
$(IDF_PATH)/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
|
||||
## ESP Certificate Bundle
|
||||
$(IDF_PATH)/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h \
|
||||
##
|
||||
## Provisioning - API Reference
|
||||
##
|
||||
## Protocol Communication
|
||||
$(IDF_PATH)/components/protocomm/include/common/protocomm.h \
|
||||
$(IDF_PATH)/components/protocomm/include/security/protocomm_security.h \
|
||||
$(IDF_PATH)/components/protocomm/include/security/protocomm_security0.h \
|
||||
@@ -171,132 +133,79 @@ INPUT = \
|
||||
$(IDF_PATH)/components/protocomm/include/transports/protocomm_ble.h \
|
||||
$(IDF_PATH)/components/protocomm/include/transports/protocomm_console.h \
|
||||
$(IDF_PATH)/components/protocomm/include/transports/protocomm_httpd.h \
|
||||
## WiFi Provisioning
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/manager.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/scheme_console.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h \
|
||||
##
|
||||
## Storage - API Reference
|
||||
##
|
||||
## SPI Flash and Partition APIs
|
||||
$(IDF_PATH)/components/spi_flash/include/esp_flash_spi_init.h \
|
||||
$(IDF_PATH)/components/spi_flash/include/esp_flash.h \
|
||||
$(IDF_PATH)/components/spi_flash/include/esp_partition.h \
|
||||
$(IDF_PATH)/components/bootloader_support/include/esp_flash_encrypt.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/spi_flash_types.h \
|
||||
## SPIFFS
|
||||
$(IDF_PATH)/components/spiffs/include/esp_spiffs.h \
|
||||
## SD/MMC Card Host
|
||||
$(IDF_PATH)/components/sdmmc/include/sdmmc_cmd.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdmmc_host.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdmmc_types.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdspi_host.h \
|
||||
## SDIO slave
|
||||
$(IDF_PATH)/components/driver/include/driver/sdio_slave.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/sdio_slave_types.h \
|
||||
## Non-Volatile Storage
|
||||
$(IDF_PATH)/components/nvs_flash/include/nvs.h \
|
||||
$(IDF_PATH)/components/nvs_flash/include/nvs_flash.h \
|
||||
## Virtual Filesystem
|
||||
$(IDF_PATH)/components/vfs/include/esp_vfs.h \
|
||||
$(IDF_PATH)/components/vfs/include/esp_vfs_dev.h \
|
||||
$(IDF_PATH)/components/vfs/include/esp_vfs_semihost.h \
|
||||
## FAT Filesystem
|
||||
## NOTE: for two lines below header_file.inc is not used
|
||||
$(IDF_PATH)/components/fatfs/vfs/esp_vfs_fat.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_impl.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_sdmmc.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_wl.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_rawflash.h \
|
||||
## Wear Levelling
|
||||
$(IDF_PATH)/components/wear_levelling/include/wear_levelling.h \
|
||||
##
|
||||
## System - API Reference
|
||||
##
|
||||
## ESP Console
|
||||
$(IDF_PATH)/components/console/esp_console.h \
|
||||
## Memory Allocation
|
||||
$(IDF_PATH)/components/heap/include/esp_heap_caps.h \
|
||||
$(IDF_PATH)/components/heap/include/esp_heap_trace.h \
|
||||
$(IDF_PATH)/components/heap/include/esp_heap_caps_init.h \
|
||||
$(IDF_PATH)/components/heap/include/multi_heap.h \
|
||||
## Himem
|
||||
$(IDF_PATH)/components/esp32/include/esp32/himem.h \
|
||||
## Interrupt Allocation
|
||||
$(IDF_PATH)/components/$(IDF_TARGET)/include/esp_intr_alloc.h \
|
||||
## Watchdogs
|
||||
## NOTE: for two lines below header_file.inc is not used
|
||||
$(IDF_PATH)/components/esp_common/include/esp_int_wdt.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_task_wdt.h \
|
||||
## Hooks
|
||||
$(IDF_PATH)/components/esp_common/include/esp_freertos_hooks.h \
|
||||
## Inter-Processor Call
|
||||
$(IDF_PATH)/components/esp_ipc/include/esp_ipc.h \
|
||||
## Call Function with External stack
|
||||
$(IDF_PATH)/components/esp_common/include/esp_expression_with_stack.h \
|
||||
## Over The Air Updates (OTA)
|
||||
$(IDF_PATH)/components/app_update/include/esp_ota_ops.h \
|
||||
## ESP HTTPS OTA
|
||||
$(IDF_PATH)/components/esp_https_ota/include/esp_https_ota.h \
|
||||
## Sleep
|
||||
$(IDF_PATH)/components/$(IDF_TARGET)/include/esp_sleep.h \
|
||||
## Logging
|
||||
$(IDF_PATH)/components/log/include/esp_log.h \
|
||||
## Base MAC address
|
||||
## NOTE: for line below header_file.inc is not used
|
||||
$(IDF_PATH)/components/esp_system/include/esp_system.h \
|
||||
## IDF version
|
||||
$(IDF_PATH)/components/esp_common/include/esp_idf_version.h \
|
||||
##
|
||||
## ULP Coprocessor - API Guides
|
||||
##
|
||||
## NOTE: for line below header_file.inc is not used
|
||||
$(IDF_PATH)/components/ulp/include/$(IDF_TARGET)/ulp.h \
|
||||
$(IDF_PATH)/components/ulp/include/ulp_common.h \
|
||||
##
|
||||
## Application Level Tracing - API Reference
|
||||
##
|
||||
$(IDF_PATH)/components/app_trace/include/esp_app_trace.h \
|
||||
$(IDF_PATH)/components/app_trace/include/esp_sysview_trace.h \
|
||||
### Power management
|
||||
$(IDF_PATH)/components/esp_common/include/esp_pm.h \
|
||||
$(IDF_PATH)/components/$(IDF_TARGET)/include/$(IDF_TARGET)/pm.h \
|
||||
### esp_timer, High Resolution Timer
|
||||
$(IDF_PATH)/components/esp_timer/include/esp_timer.h \
|
||||
### esp_event, Event Loop Library
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event.h \
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event_base.h \
|
||||
### eFuse Manager
|
||||
$(IDF_PATH)/components/efuse/include/esp_efuse.h \
|
||||
### App Image Format
|
||||
$(IDF_PATH)/components/bootloader_support/include/esp_app_format.h \
|
||||
### ESP Pthread parameters
|
||||
$(IDF_PATH)/components/pthread/include/esp_pthread.h \
|
||||
###
|
||||
### FreeRTOS
|
||||
###
|
||||
$(IDF_PATH)/components/freertos/include/freertos/task.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/queue.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/semphr.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/timers.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/event_groups.h \
|
||||
### Ringbuffer
|
||||
$(IDF_PATH)/components/esp_ringbuf/include/freertos/ringbuf.h \
|
||||
### Helper functions for error codes
|
||||
$(IDF_PATH)/components/esp_common/include/esp_err.h \
|
||||
### System APIs
|
||||
$(IDF_PATH)/components/esp_system/include/esp_system.h \
|
||||
### Modbus controller component header file
|
||||
$(IDF_PATH)/components/freemodbus/common/include/esp_modbus_common.h \
|
||||
$(IDF_PATH)/components/freemodbus/common/include/esp_modbus_slave.h \
|
||||
$(IDF_PATH)/components/freemodbus/common/include/esp_modbus_master.h \
|
||||
### Performance Monitor component header file
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_access.h \
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_apis.h \
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_masks.h
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_access.h \
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_apis.h \
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_masks.h
|
||||
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
|
||||
@@ -153,7 +153,6 @@ LEGACY_DOCS = ['api-guides/build-system-legacy.rst',
|
||||
|
||||
ESP32_DOCS = ['api-guides/ulp_instruction_set.rst',
|
||||
'api-reference/system/himem.rst',
|
||||
'api-guides/RF_calibration.rst',
|
||||
'api-reference/system/ipc.rst',
|
||||
'security/secure-boot-v1.rst',
|
||||
'api-reference/peripherals/secure_element.rst',
|
||||
|
||||
@@ -48,13 +48,7 @@ PHY initialization data
|
||||
The PHY initialization data is used for RF calibration.
|
||||
There are two ways to get the PHY initialization data.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
One is the default initialization data which is located in the header file :idf_file:`components/esp_wifi/esp32/include/phy_init_data.h`.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
One is the default initialization data which is located in the header file :idf_file:`components/esp_wifi/esp32s2/include/phy_init_data.h`.
|
||||
One is the default initialization data which is located in the header file :idf_file:`components/esp_wifi/esp32/include/phy_init_data.h`.
|
||||
|
||||
It is embedded into the application binary after compiling and then stored into read-only memory (DROM).
|
||||
To use the default initialization data, please go to ``menuconfig`` and disable :ref:`CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION`.
|
||||
|
||||
@@ -426,7 +426,7 @@ Here are two "*", because the length of the data to be emitted is unknown that r
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len)
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
|
||||
|
||||
The data to be encrypted and decrypted must use the same length. The IV8 is a 8 bit sequence value of frames, which can be used as a 8 bit of IV.
|
||||
|
||||
|
||||
@@ -10,6 +10,40 @@ Bootloader performs the following functions:
|
||||
|
||||
Bootloader is located at the address `0x1000` in the flash.
|
||||
|
||||
Bootloader compatibility
|
||||
-------------------------
|
||||
|
||||
It is recommended to update to newer :doc:`versions of ESP-IDF </versions>`: when they are released. The OTA (over the air) update process can flash new apps in the field but cannot flash a new bootloader. For this reason, the bootloader supports booting apps built from newer versions of ESP-IDF.
|
||||
|
||||
The bootloader does not support booting apps from older versions of ESP-IDF. When updating ESP-IDF manually on an existing product that might need to downgrade the app to an older version, keep using the older ESP-IDF bootloader binary as well.
|
||||
|
||||
.. note::
|
||||
|
||||
If testing an OTA update for an existing product in production, always test it using the same ESP-IDF bootloader binary that is deployed in production.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
Before ESP-IDF V2.1
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Bootloaders built from very old versions of ESP-IDF (before ESP-IDF V2.1) perform less hardware configuration than newer versions. When using a bootloader from these early ESP-IDF versions and building a new app, enable the config option :ref:`CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS`.
|
||||
|
||||
Before ESP-IDF V3.1
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Bootloaders built from versions of ESP-IDF before V3.1 do not support MD5 checksums in the partition table binary. When using a bootloader from these ESP-IDF versions and building a new app, enable the config option :ref:`CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS`.
|
||||
|
||||
SPI Flash Configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Each ESP-IDF application or bootloader .bin file contains a header with :ref:`CONFIG_ESPTOOLPY_FLASHMODE`, :ref:`CONFIG_ESPTOOLPY_FLASHFREQ`, :ref:`CONFIG_ESPTOOLPY_FLASHSIZE` embedded in it. These are used to configure the SPI flash during boot.
|
||||
|
||||
The :first stage bootloader in ROM reads the second stage bootloader header from flash and uses these settings to load it. However, at this time the system clock speed is lower than configured and not all flash modes are supported. When the second stage bootloader then runs and re-configures the flash, it reads values from the currently selected app binary header not the bootloader header. This allows an OTA update to change the SPI flash settings in use.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
Bootloaders prior to ESP-IDF V4.0 used the bootloader's own header to configure the SPI flash, meaning these values could not be changed in an update. To maintain compatibility with older bootloaders, the app re-initializes the flash settings during app startup using the configuration found in the app header.
|
||||
|
||||
FACTORY reset
|
||||
---------------------------
|
||||
The user can write a basic working firmware and load it into the factory partition.
|
||||
|
||||
@@ -3,7 +3,7 @@ Build System
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
This document explains the implementation of the ESP-IDF build system and the concept of "components". Read this document if you want to know how to organise and build a new ESP-IDF project or component.
|
||||
This document explains the implementation of the ESP-IDF build system and the concept of "components". Read this document if you want to know how to organize and build a new ESP-IDF project or component.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -13,24 +13,17 @@ This document explains the implementation of the ESP-IDF build system and the co
|
||||
Overview
|
||||
========
|
||||
|
||||
An ESP-IDF project can be seen as an amalgamation of a number of components.
|
||||
For example, for a webserver that shows the current humidity, there could be:
|
||||
An ESP-IDF project can be seen as an amalgamation of a number of components. For example, for a webserver that shows the current humidity, there could be:
|
||||
|
||||
- The ESP-IDF base libraries (libc, ROM bindings, etc)
|
||||
- The WiFi drivers
|
||||
- The Wi-Fi drivers
|
||||
- A TCP/IP stack
|
||||
- The FreeRTOS operating system
|
||||
- A webserver
|
||||
- A driver for the humidity sensor
|
||||
- Main code tying it all together
|
||||
|
||||
ESP-IDF makes these components explicit and configurable. To do that,
|
||||
when a project is compiled, the build system will look up all the
|
||||
components in the ESP-IDF directories, the project directories and
|
||||
(optionally) in additional custom component directories. It then
|
||||
allows the user to configure the ESP-IDF project using a a text-based
|
||||
menu system to customize each component. After the components in the
|
||||
project are configured, the build system will compile the project.
|
||||
ESP-IDF makes these components explicit and configurable. To do that, when a project is compiled, the build system will look up all the components in the ESP-IDF directories, the project directories and (optionally) in additional custom component directories. It then allows the user to configure the ESP-IDF project using a text-based menu system to customize each component. After the components in the project are configured, the build system will compile the project.
|
||||
|
||||
Concepts
|
||||
--------
|
||||
@@ -80,6 +73,7 @@ Type ``idf.py --help`` for a list of commands. Here are a summary of the most us
|
||||
- Run the main build tool (Ninja_ or `GNU Make`). By default, the build tool is automatically detected but it can be explicitly set by passing the ``-G`` option to ``idf.py``.
|
||||
|
||||
Building is incremental so if no source files or configuration has changed since the last build, nothing will be done.
|
||||
|
||||
- ``idf.py clean`` will "clean" the project by deleting build output files from the build directory, forcing a "full rebuild" the next time the project is built. Cleaning doesn't delete CMake configuration output and some other files.
|
||||
- ``idf.py fullclean`` will delete the entire "build" directory contents. This includes all CMake configuration output. The next time the project is built, CMake will configure it from scratch. Note that this option recursively deletes *all* files in the build directory, so use with care. Project configuration is not deleted.
|
||||
- ``idf.py flash`` will automatically build the project if necessary, and then flash it to the target. The ``-p`` and ``-b`` options can be used to set serial port name and flasher baud rate, respectively.
|
||||
@@ -107,14 +101,15 @@ The order of multiple ``idf.py`` commands on the same invocation is not importan
|
||||
|
||||
idf.py options
|
||||
^^^^^^^^^^^^^^
|
||||
To list all available root level options, run ``idf.py --help``. To list options that are specific for a subcommand, run ``idf.py <command> --help``, for example ``idf.py monitor --help``.
|
||||
Here is a list of some useful options:
|
||||
|
||||
To list all available root level options, run ``idf.py --help``. To list options that are specific for a subcommand, run ``idf.py <command> --help``, for example ``idf.py monitor --help``. Here is a list of some useful options:
|
||||
|
||||
- ``-C <dir>`` allows overriding the project directory from the default current working directory.
|
||||
- ``-B <dir>`` allows overriding the build directory from the default ``build`` subdirectory of the project directory.
|
||||
- ``--ccache`` flag can be used to enable CCache_ when compiling source files, if the CCache_ tool is installed. This can dramatically reduce some build times.
|
||||
|
||||
Note that some older versions of CCache may exhibit bugs on some platforms, so if files are not rebuilt as expected then try disabling ccache and build again. CCache can be enabled by default by setting the ``IDF_CCACHE_ENABLE`` environment variable to a non-zero value.
|
||||
Note that some older versions of CCache may exhibit bugs on some platforms, so if files are not rebuilt as expected then try disabling CCache and build again. CCache can be enabled by default by setting the ``IDF_CCACHE_ENABLE`` environment variable to a non-zero value.
|
||||
|
||||
- ``-v`` flag causes both ``idf.py`` and the build system to produce verbose build output. This can be useful for debugging build problems.
|
||||
- ``--cmake-warn-uninitialized`` (or ``-w``) will cause CMake to print uninitialized variable warnings inside the project directory (not for directories not found inside the project directory). This only controls CMake variable warnings inside CMake itself, not other types of build warnings. This option can also be set permanently by setting the ``IDF_CMAKE_WARN_UNINITIALIZED`` environment variable to a non-zero value.
|
||||
|
||||
@@ -168,7 +163,6 @@ Or::
|
||||
|
||||
.. note:: Providing variables at the end of the command line is ``make`` syntax, and works for ``make`` on all platforms.
|
||||
|
||||
|
||||
Using CMake in an IDE
|
||||
---------------------
|
||||
|
||||
@@ -185,8 +179,7 @@ Setting up the Python Interpreter
|
||||
|
||||
ESP-IDF works well with all supported Python versions. It should work out-of-box even if you have a legacy system where the default ``python`` interpreter is still Python 2.7, however, it is advised to switch to Python 3 if possible.
|
||||
|
||||
``idf.py`` and other Python scripts will run with the default Python interpreter, i.e. ``python``. You can switch to a
|
||||
different one like ``python3 $IDF_PATH/tools/idf.py ...``, or you can set up a shell alias or another script to simplify the command.
|
||||
``idf.py`` and other Python scripts will run with the default Python interpreter, i.e. ``python``. You can switch to a different one like ``python3 $IDF_PATH/tools/idf.py ...``, or you can set up a shell alias or another script to simplify the command.
|
||||
|
||||
If using CMake directly, running ``cmake -D PYTHON=python3 ...`` will cause CMake to override the default Python interpreter.
|
||||
|
||||
@@ -195,7 +188,7 @@ If using an IDE with CMake, setting the ``PYTHON`` value as a CMake cache overri
|
||||
To manage the Python version more generally via the command line, check out the tools pyenv_ or virtualenv_. These let you change the default Python version.
|
||||
|
||||
Possible issues
|
||||
^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The user of ``idf.py`` may sometimes experience ``ImportError`` described below.
|
||||
|
||||
@@ -239,8 +232,7 @@ An example project directory tree might look like this::
|
||||
|
||||
This example "myProject" contains the following elements:
|
||||
|
||||
- A top-level project CMakeLists.txt file. This is the primary file which CMake uses to learn how to build the project; and may set project-wide CMake variables. It includes the file :idf_file:`/tools/cmake/project.cmake` which
|
||||
implements the rest of the build system. Finally, it sets the project name and defines the project.
|
||||
- A top-level project CMakeLists.txt file. This is the primary file which CMake uses to learn how to build the project; and may set project-wide CMake variables. It includes the file :idf_file:`/tools/cmake/project.cmake` which implements the rest of the build system. Finally, it sets the project name and defines the project.
|
||||
|
||||
- "sdkconfig" project configuration file. This file is created/updated when ``idf.py menuconfig`` runs, and holds configuration for all of the components in the project (including ESP-IDF itself). The "sdkconfig" file may or may not be added to the source control system of the project.
|
||||
|
||||
@@ -250,8 +242,7 @@ This example "myProject" contains the following elements:
|
||||
|
||||
- "build" directory is where build output is created. This directory is created by ``idf.py`` if it doesn't already exist. CMake configures the project and generates interim build files in this directory. Then, after the main build process is run, this directory will also contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code.
|
||||
|
||||
Component directories each contain a component ``CMakeLists.txt`` file. This file contains variable definitions
|
||||
to control the build process of the component, and its integration into the overall project. See `Component CMakeLists Files`_ for more details.
|
||||
Component directories each contain a component ``CMakeLists.txt`` file. This file contains variable definitions to control the build process of the component, and its integration into the overall project. See `Component CMakeLists Files`_ for more details.
|
||||
|
||||
Each component may also include a ``Kconfig`` file defining the `component configuration`_ options that can be set via ``menuconfig``. Some components may also include ``Kconfig.projbuild`` and ``project_include.cmake`` files, which are special files for `overriding parts of the project`_.
|
||||
|
||||
@@ -271,7 +262,6 @@ Minimal project::
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(myProject)
|
||||
|
||||
|
||||
.. _project-mandatory-parts:
|
||||
|
||||
Mandatory Parts
|
||||
@@ -283,6 +273,7 @@ The inclusion of these three lines, in the order shown above, is necessary for e
|
||||
- ``include($ENV{IDF_PATH}/tools/cmake/project.cmake)`` pulls in the rest of the CMake functionality to configure the project, discover all the components, etc.
|
||||
- ``project(myProject)`` creates the project itself, and specifies the project name. The project name is used for the final binary output files of the app - ie ``myProject.elf``, ``myProject.bin``. Only one project can be defined per CMakeLists file.
|
||||
|
||||
.. _optional_project_variable:
|
||||
|
||||
Optional Project Variables
|
||||
--------------------------
|
||||
@@ -290,7 +281,9 @@ Optional Project Variables
|
||||
These variables all have default values that can be overridden for custom behaviour. Look in :idf_file:`/tools/cmake/project.cmake` for all of the implementation details.
|
||||
|
||||
- ``COMPONENT_DIRS``, ``COMPONENTS_DIRS``: Directories to search for components. Defaults to ``IDF_PATH/components``, ``PROJECT_DIR/components``, and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in these places.
|
||||
|
||||
- ``EXTRA_COMPONENT_DIRS``, ``EXTRA_COMPONENTS_DIRS``: Optional list of additional directories to search for components. Paths can be relative to the project directory, or absolute.
|
||||
|
||||
- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the ``COMPONENT_DIRS`` directories. Use this variable to "trim down" the project for faster build times. Note that any component which "requires" another component via the REQUIRES or PRIV_REQUIRES arguments on component registration will automatically have it added to this list, so the ``COMPONENTS`` list can be very short.
|
||||
|
||||
Any paths in these variables can be absolute paths, or set relative to the project directory.
|
||||
@@ -302,11 +295,7 @@ To set these variables, use the `cmake set command <cmake set_>`_ ie ``set(VARIA
|
||||
Renaming ``main`` component
|
||||
----------------------------
|
||||
|
||||
The build system provides special treatment to the ``main`` component. It is a component that gets automatically added to the build provided
|
||||
that it is in the expected location, PROJECT_DIR/main. All other components in the build are also added as its dependencies,
|
||||
saving the user from hunting down dependencies and providing a build that works right out of the box. Renaming the ``main`` component
|
||||
causes the loss of these behind-the-scences heavy lifting, requiring the user to specify the location of the newly renamed component
|
||||
and manually specifying its dependencies. Specifically, the steps to renaming ``main`` are as follows:
|
||||
The build system provides special treatment to the ``main`` component. It is a component that gets automatically added to the build provided that it is in the expected location, PROJECT_DIR/main. All other components in the build are also added as its dependencies, saving the user from hunting down dependencies and providing a build that works right out of the box. Renaming the ``main`` component causes the loss of these behind-the-scenes heavy lifting, requiring the user to specify the location of the newly renamed component and manually specifying its dependencies. Specifically, the steps to renaming ``main`` are as follows:
|
||||
|
||||
1. Rename ``main`` directory.
|
||||
2. Set ``EXTRA_COMPONENT_DIRS`` in the project CMakeLists.txt to include the renamed ``main`` directory.
|
||||
@@ -328,13 +317,12 @@ The list of directories in ``COMPONENT_DIRS`` is searched for the project's comp
|
||||
|
||||
When CMake runs to configure the project, it logs the components included in the build. This list can be useful for debugging the inclusion/exclusion of certain components.
|
||||
|
||||
.. _cmake-components-same-name:
|
||||
|
||||
Multiple components with the same name
|
||||
--------------------------------------
|
||||
|
||||
When ESP-IDF is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means ESP-IDF's internal components first, then the project's components, and finally any components set in ``EXTRA_COMPONENT_DIRS``. If two or more of these directories
|
||||
contain component sub-directories with the same name, the component in the last place searched is used. This allows, for example, overriding ESP-IDF components
|
||||
with a modified version by copying that component from the ESP-IDF components directory to the project components directory and then modifying it there.
|
||||
If used in this way, the ESP-IDF directory itself can remain untouched.
|
||||
When ESP-IDF is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means ESP-IDF's internal components first, then the project's components, and finally any components set in ``EXTRA_COMPONENT_DIRS``. If two or more of these directories contain component sub-directories with the same name, the component in the last place searched is used. This allows, for example, overriding ESP-IDF components with a modified version by copying that component from the ESP-IDF components directory to the project components directory and then modifying it there. If used in this way, the ESP-IDF directory itself can remain untouched.
|
||||
|
||||
.. _cmake_minimal_component_cmakelists:
|
||||
|
||||
@@ -354,10 +342,10 @@ The minimal component ``CMakeLists.txt`` file simply registers the component to
|
||||
- ``REQUIRES`` is not actually required, but it is very often required to declare what other components this component will use. See :ref:`component requirements`.
|
||||
|
||||
A library with the name of the component will be built and linked into the final app.
|
||||
|
||||
Directories are usually specified relative to the ``CMakeLists.txt`` file itself, although they can be absolute.
|
||||
|
||||
There are other arguments that can be passed to ``idf_component_register``. These arguments
|
||||
are discussed :ref:`here<cmake-component-register>`.
|
||||
There are other arguments that can be passed to ``idf_component_register``. These arguments are discussed :ref:`here<cmake-component-register>`.
|
||||
|
||||
See `example component requirements`_ and `example component CMakeLists`_ for more complete component ``CMakeLists.txt`` examples.
|
||||
|
||||
@@ -400,6 +388,8 @@ from the component CMakeLists.txt:
|
||||
|
||||
Other build properties are listed :ref:`here<cmake-build-properties>`.
|
||||
|
||||
.. _component_build_control:
|
||||
|
||||
Controlling Component Compilation
|
||||
---------------------------------
|
||||
|
||||
@@ -425,8 +415,7 @@ When using these commands, place them after the call to ``idf_component_register
|
||||
Component Configuration
|
||||
=======================
|
||||
|
||||
Each component can also have a ``Kconfig`` file, alongside ``CMakeLists.txt``. This contains
|
||||
configuration settings to add to the configuration menu for this component.
|
||||
Each component can also have a ``Kconfig`` file, alongside ``CMakeLists.txt``. This contains configuration settings to add to the configuration menu for this component.
|
||||
|
||||
These settings are found under the "Component Settings" menu when menuconfig is run.
|
||||
|
||||
@@ -459,8 +448,11 @@ When writing a component
|
||||
PRIV_REQUIRES console spiffs)
|
||||
|
||||
- ``REQUIRES`` should be set to all components whose header files are #included from the *public* header files of this component.
|
||||
|
||||
- ``PRIV_REQUIRES`` should be set to all components whose header files are #included from *any source files* in this component, unless already listed in ``REQUIRES``. Also any component which is required to be linked in order for this component to function correctly.
|
||||
|
||||
- The values of ``REQUIRES`` and ``PRIV_REQUIRES`` should not depend on any configuration choices (``CONFIG_xxx`` macros). This is because requirements are expanded before configuration is loaded. Other component variables (like include paths or source files) can depend on configuration choices.
|
||||
|
||||
- Not setting either or both ``REQUIRES`` variables is fine. If the component has no requirements except for the `Common component requirements`_ needed for RTOS, libc, etc.
|
||||
|
||||
If a components only supports some target chips (values of ``IDF_TARGET``) then it can specify ``REQUIRED_IDF_TARGETS`` in the ``idf_component_register`` call to express these requirements. In this case the build system will generate an error if the component is included into the build, but does not support the selected target.
|
||||
@@ -564,7 +556,6 @@ This means that the ``spark_plug/CMakeLists.txt`` file doesn't need any ``REQUIR
|
||||
INCLUDE_DIRS ".")
|
||||
|
||||
|
||||
|
||||
Source File Include Directories
|
||||
-------------------------------
|
||||
|
||||
@@ -602,6 +593,7 @@ Including components in the build
|
||||
- Components mentioned explicitly in ``COMPONENTS``.
|
||||
- Those components' requirements (evaluated recursively).
|
||||
- The "common" components that every component depends on.
|
||||
|
||||
- Setting ``COMPONENTS`` to the minimal list of required components can significantly reduce compile times.
|
||||
|
||||
.. _component-requirements-implementation:
|
||||
@@ -623,6 +615,7 @@ The order of components in the ``BUILD_COMPONENTS`` variable determines other or
|
||||
- Order that :ref:`project_include.cmake` files are included into the project.
|
||||
- Order that the list of header paths is generated for compilation (via ``-I`` argument). (Note that for a given component's source files, only that component's dependency's header paths are passed to the compiler.)
|
||||
|
||||
.. _override_project_config:
|
||||
|
||||
Overriding Parts of the Project
|
||||
===============================
|
||||
@@ -632,9 +625,7 @@ Overriding Parts of the Project
|
||||
project_include.cmake
|
||||
---------------------
|
||||
|
||||
For components that have build requirements which must be evaluated before any component CMakeLists
|
||||
files are evaluated, you can create a file called ``project_include.cmake`` in the
|
||||
component directory. This CMake file is included when ``project.cmake`` is evaluating the entire project.
|
||||
For components that have build requirements which must be evaluated before any component CMakeLists files are evaluated, you can create a file called ``project_include.cmake`` in the component directory. This CMake file is included when ``project.cmake`` is evaluating the entire project.
|
||||
|
||||
``project_include.cmake`` files are used inside ESP-IDF, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app".
|
||||
|
||||
@@ -649,19 +640,18 @@ Take great care when setting variables or targets in a ``project_include.cmake``
|
||||
KConfig.projbuild
|
||||
-----------------
|
||||
|
||||
This is an equivalent to ``project_include.cmake`` for :ref:`component-configuration` KConfig files. If you want to include
|
||||
configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``CMakeLists.txt`` file.
|
||||
This is an equivalent to ``project_include.cmake`` for :ref:`component-configuration` KConfig files. If you want to include configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``CMakeLists.txt`` file.
|
||||
|
||||
Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for :ref:`component-configuration`.
|
||||
|
||||
``project_include.cmake`` files are used inside ESP-IDF, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app".
|
||||
|
||||
.. _config_only_component:
|
||||
|
||||
Configuration-Only Components
|
||||
=============================
|
||||
|
||||
Special components which contain no source files, only ``Kconfig.projbuild`` and ``KConfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``idf_component_register()`` with no
|
||||
arguments specified. This function will include the component in the project build, but no library will be built *and* no header files will be added to any include paths.
|
||||
|
||||
Special components which contain no source files, only ``Kconfig.projbuild`` and ``KConfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``idf_component_register()`` with no arguments specified. This function will include the component in the project build, but no library will be built *and* no header files will be added to any include paths.
|
||||
|
||||
Debugging CMake
|
||||
===============
|
||||
@@ -689,8 +679,7 @@ If you don't want this behaviour, it can be disabled by passing ``--no-warnings`
|
||||
|
||||
Browse the :idf_file:`/tools/cmake/project.cmake` file and supporting functions in :idf:`/tools/cmake/` for more details.
|
||||
|
||||
.. _gnu-make-to-cmake:
|
||||
|
||||
.. _component_cmakelists_example:
|
||||
|
||||
Example Component CMakeLists
|
||||
============================
|
||||
@@ -780,12 +769,7 @@ Note that component dependencies may depend on ``IDF_TARGET`` variable, but not
|
||||
Source Code Generation
|
||||
----------------------
|
||||
|
||||
Some components will have a situation where a source file isn't
|
||||
supplied with the component itself but has to be generated from
|
||||
another file. Say our component has a header file that consists of the
|
||||
converted binary data of a BMP file, converted using a hypothetical
|
||||
tool called bmp2h. The header file is then included in as C source
|
||||
file called graphics_lib.c::
|
||||
Some components will have a situation where a source file isn't supplied with the component itself but has to be generated from another file. Say our component has a header file that consists of the converted binary data of a BMP file, converted using a hypothetical tool called bmp2h. The header file is then included in as C source file called graphics_lib.c::
|
||||
|
||||
add_custom_command(OUTPUT logo.h
|
||||
COMMAND bmp2h -i ${COMPONENT_DIR}/logo.bmp -o log.h
|
||||
@@ -800,18 +784,13 @@ file called graphics_lib.c::
|
||||
|
||||
This answer is adapted from the `CMake FAQ entry <cmake faq generated files_>`_, which contains some other examples that will also work with ESP-IDF builds.
|
||||
|
||||
In this example, logo.h will be generated in the
|
||||
current directory (the build directory) while logo.bmp comes with the
|
||||
component and resides under the component path. Because logo.h is a
|
||||
generated file, it should be cleaned when the project is cleaned. For this reason
|
||||
it is added to the `ADDITIONAL_MAKE_CLEAN_FILES`_ property.
|
||||
In this example, logo.h will be generated in the current directory (the build directory) while logo.bmp comes with the component and resides under the component path. Because logo.h is a generated file, it should be cleaned when the project is cleaned. For this reason it is added to the `ADDITIONAL_MAKE_CLEAN_FILES`_ property.
|
||||
|
||||
.. note::
|
||||
|
||||
If generating files as part of the project CMakeLists.txt file, not a component CMakeLists.txt, then use build property ``PROJECT_DIR`` instead of ``${COMPONENT_DIR}`` and ``${PROJECT_NAME}.elf`` instead of ``${COMPONENT_LIB}``.)
|
||||
|
||||
If a a source file from another component included ``logo.h``, then ``add_dependencies`` would need to be called to add a dependency between
|
||||
the two components, to ensure that the component source files were always compiled in the correct order.
|
||||
If a a source file from another component included ``logo.h``, then ``add_dependencies`` would need to be called to add a dependency between the two components, to ensure that the component source files were always compiled in the correct order.
|
||||
|
||||
.. _cmake_embed_data:
|
||||
|
||||
@@ -825,7 +804,6 @@ You can specify argument ``EMBED_FILES`` in the component registration, giving s
|
||||
idf_component_register(...
|
||||
EMBED_FILES server_root_cert.der)
|
||||
|
||||
|
||||
Or if the file is a string, you can use the variable ``EMBED_TXTFILES``. This will embed the contents of the text file as a null-terminated string::
|
||||
|
||||
idf_component_register(...
|
||||
@@ -853,10 +831,7 @@ For an example of using this technique, see the "main" component of the file_ser
|
||||
Code and Data Placements
|
||||
------------------------
|
||||
|
||||
ESP-IDF has a feature called linker script generation that enables components to define where its code and data will be placed in memory through
|
||||
linker fragment files. These files are processed by the build system, and is used to augment the linker script used for linking
|
||||
app binary. See :doc:`Linker Script Generation <linker-script-generation>` for a quick start guide as well as a detailed discussion
|
||||
of the mechanism.
|
||||
ESP-IDF has a feature called linker script generation that enables components to define where its code and data will be placed in memory through linker fragment files. These files are processed by the build system, and is used to augment the linker script used for linking app binary. See :doc:`Linker Script Generation <linker-script-generation>` for a quick start guide as well as a detailed discussion of the mechanism.
|
||||
|
||||
.. _component-build-full-override:
|
||||
|
||||
@@ -865,11 +840,7 @@ Fully Overriding The Component Build Process
|
||||
|
||||
.. highlight:: cmake
|
||||
|
||||
Obviously, there are cases where all these recipes are insufficient for a
|
||||
certain component, for example when the component is basically a wrapper
|
||||
around another third-party component not originally intended to be
|
||||
compiled under this build system. In that case, it's possible to forego
|
||||
the ESP-IDF build system entirely by using a CMake feature called ExternalProject_. Example component CMakeLists::
|
||||
Obviously, there are cases where all these recipes are insufficient for a certain component, for example when the component is basically a wrapper around another third-party component not originally intended to be compiled under this build system. In that case, it's possible to forego the ESP-IDF build system entirely by using a CMake feature called ExternalProject_. Example component CMakeLists::
|
||||
|
||||
# External build process for quirc, runs in source dir and
|
||||
# produces libquirc.a
|
||||
@@ -883,7 +854,6 @@ the ESP-IDF build system entirely by using a CMake feature called ExternalProjec
|
||||
)
|
||||
|
||||
# Add libquirc.a to the build process
|
||||
#
|
||||
add_library(quirc STATIC IMPORTED GLOBAL)
|
||||
add_dependencies(quirc quirc_build)
|
||||
|
||||
@@ -942,6 +912,7 @@ In addition to ``sdkconfig.defaults`` file, build system will also load defaults
|
||||
|
||||
If ``SDKCONFIG_DEFAULTS`` is used to override the name of defaults file/files, the name of target-specific defaults file will be derived from ``SDKCONFIG_DEFAULTS`` value/values using the rule above.
|
||||
|
||||
.. _flash_parameters:
|
||||
|
||||
Flash arguments
|
||||
===============
|
||||
@@ -999,12 +970,14 @@ To select the target before building the project, use ``idf.py set-target <targe
|
||||
2. removing the sdkconfig file (``mv sdkconfig sdkconfig.old``)
|
||||
3. configuring the project with the new target (``idf.py -DIDF_TARGET=esp32 reconfigure``)
|
||||
|
||||
It is also possible to pass the desired ``IDF_TARGET`` as an environement variable (e.g. ``export IDF_TARGET=esp32s2``) or as a CMake variable (e.g. ``-DIDF_TARGET=esp32s2`` argument to CMake or idf.py). Setting the environment variable is a convenient method if you mostly work with one type of the chip.
|
||||
It is also possible to pass the desired ``IDF_TARGET`` as an environment variable (e.g. ``export IDF_TARGET=esp32s2``) or as a CMake variable (e.g. ``-DIDF_TARGET=esp32s2`` argument to CMake or idf.py). Setting the environment variable is a convenient method if you mostly work with one type of the chip.
|
||||
|
||||
To specify the _default_ value of ``IDF_TARGET`` for a given project, add ``CONFIG_IDF_TARGET`` value to ``sdkconfig.defaults``. For example, ``CONFIG_IDF_TARGET="esp32s2"``. This value will be used if ``IDF_TARGET`` is not specified by other method: using an environment variable, CMake variable, or ``idf.py set-target`` command.
|
||||
|
||||
If the target has not been set by any of these methods, the build system will default to ``esp32`` target.
|
||||
|
||||
.. _write-pure-component:
|
||||
|
||||
Writing Pure CMake Components
|
||||
=============================
|
||||
|
||||
@@ -1026,13 +999,10 @@ Here is an example minimal "pure CMake" component CMakeLists file for a componen
|
||||
- This file is quite simple as there are not a lot of source files. For components with a large number of files, the globbing behaviour of ESP-IDF's component logic can make the component CMakeLists style simpler.)
|
||||
- Any time a component adds a library target with the component name, the ESP-IDF build system will automatically add this to the build, expose public include directories, etc. If a component wants to add a library target with a different name, dependencies will need to be added manually via CMake commands.
|
||||
|
||||
|
||||
Using Third-Party CMake Projects with Components
|
||||
================================================
|
||||
|
||||
CMake is used for a lot of open-source C and C++ projects — code that users can tap into for their applications. One of the benefits of having a CMake build system
|
||||
is the ability to import these third-party projects, sometimes even without modification! This allows for users to be able to get functionality that may
|
||||
not yet be provided by a component, or use another library for the same functionality.
|
||||
CMake is used for a lot of open-source C and C++ projects — code that users can tap into for their applications. One of the benefits of having a CMake build system is the ability to import these third-party projects, sometimes even without modification! This allows for users to be able to get functionality that may not yet be provided by a component, or use another library for the same functionality.
|
||||
|
||||
.. highlight:: cmake
|
||||
|
||||
@@ -1051,19 +1021,16 @@ Importing a library might look like this for a hypothetical library ``foo`` to b
|
||||
# Publicly link `foo` to `main` component
|
||||
target_link_libraries(main PUBLIC foo)
|
||||
|
||||
For an actual example, take a look at :example:`build_system/cmake/import_lib`. Take note that what needs to be done in order to import
|
||||
the library may vary. It is recommended to read up on the library's documentation for instructions on how to
|
||||
import it from other projects. Studying the library's CMakeLists.txt and build structure can also be helpful.
|
||||
For an actual example, take a look at :example:`build_system/cmake/import_lib`. Take note that what needs to be done in order to import the library may vary. It is recommended to read up on the library's documentation for instructions on how to import it from other projects. Studying the library's CMakeLists.txt and build structure can also be helpful.
|
||||
|
||||
It is also possible to wrap a third-party library to be used as a component in this manner. For example, the :component:`mbedtls` component is a wrapper for
|
||||
Espressif's fork of `mbedtls <https://github.com/ARMmbed/mbedtls>`_. See its :component_file:`component CMakeLists.txt <mbedtls/CMakeLists.txt>`.
|
||||
It is also possible to wrap a third-party library to be used as a component in this manner. For example, the :component:`mbedtls` component is a wrapper for Espressif's fork of `mbedtls <https://github.com/ARMmbed/mbedtls>`_. See its :component_file:`component CMakeLists.txt <mbedtls/CMakeLists.txt>`.
|
||||
|
||||
The CMake variable ``ESP_PLATFORM`` is set to 1 whenever the ESP-IDF build system is being used. Tests such as ``if (ESP_PLATFORM)`` can be used in generic CMake code if special IDF-specific logic is required.
|
||||
|
||||
Using ESP-IDF components from external libraries
|
||||
------------------------------------------------
|
||||
|
||||
The above example assumes that the external library ``foo` (or ``tinyxml`` in the case of the ``import_lib`` example) doesn't need to use any ESP-IDF APIs apart from common APIs such as libc, libstdc++, etc. If the external library needs to use APIs provided by other ESP-IDF components, this needs to be specified in the external CMakeLists.txt file by adding a dependency on the library target ``idf::<componentname>``.
|
||||
The above example assumes that the external library ``foo`` (or ``tinyxml`` in the case of the ``import_lib`` example) doesn't need to use any ESP-IDF APIs apart from common APIs such as libc, libstdc++, etc. If the external library needs to use APIs provided by other ESP-IDF components, this needs to be specified in the external CMakeLists.txt file by adding a dependency on the library target ``idf::<componentname>``.
|
||||
|
||||
For example, in the ``foo/CMakeLists.txt`` file::
|
||||
|
||||
@@ -1082,8 +1049,7 @@ Using Prebuilt Libraries with Components
|
||||
|
||||
Another possibility is that you have a prebuilt static library (``.a`` file), built by some other build process.
|
||||
|
||||
The ESP-IDF build system provides a utility function ``add_prebuilt_library`` for users to be able to easily import and use
|
||||
prebuilt libraries::
|
||||
The ESP-IDF build system provides a utility function ``add_prebuilt_library`` for users to be able to easily import and use prebuilt libraries::
|
||||
|
||||
add_prebuilt_library(target_name lib_path [REQUIRES req1 req2 ...] [PRIV_REQUIRES req1 req2 ...])
|
||||
|
||||
@@ -1094,18 +1060,14 @@ where:
|
||||
|
||||
Optional arguments ``REQUIRES`` and ``PRIV_REQUIRES`` specify dependency on other components. These have the same meaning as the arguments for ``idf_component_register``.
|
||||
|
||||
Take note that the prebuilt library must have been compiled for the same target as the consuming project. Configuration relevant to the prebuilt
|
||||
library must also match. If not paid attention to, these two factors may contribute to subtle bugs in the app.
|
||||
Take note that the prebuilt library must have been compiled for the same target as the consuming project. Configuration relevant to the prebuilt library must also match. If not paid attention to, these two factors may contribute to subtle bugs in the app.
|
||||
|
||||
For an example, take a look at :example:`build_system/cmake/import_prebuilt`.
|
||||
|
||||
|
||||
Using ESP-IDF in Custom CMake Projects
|
||||
======================================
|
||||
|
||||
ESP-IDF provides a template CMake project for easily creating an application. However, in some instances the user might already
|
||||
have an existing CMake project or may want to create a custom one. In these cases it is desirable to be able to consume IDF components
|
||||
as libraries to be linked to the user's targets (libraries/ executables).
|
||||
ESP-IDF provides a template CMake project for easily creating an application. However, in some instances the user might already have an existing CMake project or may want to create a custom one. In these cases it is desirable to be able to consume IDF components as libraries to be linked to the user's targets (libraries/ executables).
|
||||
|
||||
It is possible to do so by using the :ref:`build system APIs provided<cmake_buildsystem_api>` by :idf_file:`tools/cmake/idf.cmake`. For example:
|
||||
|
||||
@@ -1118,7 +1080,7 @@ It is possible to do so by using the :ref:`build system APIs provided<cmake_buil
|
||||
include($ENV{IDF_PATH}/tools/cmake/idf.cmake)
|
||||
|
||||
# Include ESP-IDF components in the build, may be thought as an equivalent of
|
||||
# add_subdirectory() but with some additional procesing and magic for ESP-IDF build
|
||||
# add_subdirectory() but with some additional processing and magic for ESP-IDF build
|
||||
# specific build processes.
|
||||
idf_build_process(esp32)
|
||||
|
||||
@@ -1130,8 +1092,7 @@ It is possible to do so by using the :ref:`build system APIs provided<cmake_buil
|
||||
# Let the build system know what the project executable is to attach more targets, dependencies, etc.
|
||||
idf_build_executable(${CMAKE_PROJECT_NAME}.elf)
|
||||
|
||||
The example in :example:`build_system/cmake/idf_as_lib` demonstrates the creation of an application equivalent to :example:`hello world application <get-started/hello_world>`
|
||||
using a custom CMake project.
|
||||
The example in :example:`build_system/cmake/idf_as_lib` demonstrates the creation of an application equivalent to :example:`hello world application <get-started/hello_world>` using a custom CMake project.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -1149,17 +1110,13 @@ idf-build-commands
|
||||
|
||||
idf_build_get_property(var property [GENERATOR_EXPRESSION])
|
||||
|
||||
Retrieve a :ref:`build property<cmake-build-properties>` *property* and store it in *var* accessible from the current scope. Specifying
|
||||
*GENERATOR_EXPRESSION* will retrieve the generator expression string for that property, instead of the actual value, which
|
||||
can be used with CMake commands that support generator expressions.
|
||||
Retrieve a :ref:`build property<cmake-build-properties>` *property* and store it in *var* accessible from the current scope. Specifying *GENERATOR_EXPRESSION* will retrieve the generator expression string for that property, instead of the actual value, which can be used with CMake commands that support generator expressions.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_build_set_property(property val [APPEND])
|
||||
|
||||
Set a :ref:`build property<cmake-build-properties>` *property* with value *val*. Specifying *APPEND* will append the specified value to the current
|
||||
value of the property. If the property does not previously exist or it is currently empty, the specified value becomes
|
||||
the first element/member instead.
|
||||
Set a :ref:`build property<cmake-build-properties>` *property* with value *val*. Specifying *APPEND* will append the specified value to the current value of the property. If the property does not previously exist or it is currently empty, the specified value becomes the first element/member instead.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
@@ -1181,11 +1138,8 @@ This command does not guarantee that the component will be processed during buil
|
||||
[BUILD_DIR build_dir]
|
||||
[COMPONENTS component1 component2 ...])
|
||||
|
||||
Performs the bulk of the behind-the-scenes magic for including ESP-IDF components such as component configuration, libraries creation,
|
||||
dependency expansion and resolution. Among these functions, perhaps the most important
|
||||
from a user's perspective is the libraries creation by calling each component's ``idf_component_register``. This command creates the libraries for each component, which are accessible using aliases in the form
|
||||
idf::*component_name*. These aliases can be used to link the components to the user's own targets, either libraries
|
||||
or executables.
|
||||
Performs the bulk of the behind-the-scenes magic for including ESP-IDF components such as component configuration, libraries creation, dependency expansion and resolution. Among these functions, perhaps the most important from a user's perspective is the libraries creation by calling each component's ``idf_component_register``. This command creates the libraries for each component, which are accessible using aliases in the form idf::*component_name*.
|
||||
These aliases can be used to link the components to the user's own targets, either libraries or executables.
|
||||
|
||||
The call requires the target chip to be specified with *target* argument. Optional arguments for the call include:
|
||||
|
||||
@@ -1196,64 +1150,58 @@ The call requires the target chip to be specified with *target* argument. Option
|
||||
- SDKCONFIG_DEFAULTS - list of files containing default config to use in the build (list must contain full paths); defaults to empty. For each value *filename* in the list, the config from file *filename.target*, if it exists, is also loaded.
|
||||
- BUILD_DIR - directory to place ESP-IDF build-related artifacts, such as generated binaries, text files, components; defaults to CMAKE_BINARY_DIR
|
||||
- COMPONENTS - select components to process among the components known by the build system (added via `idf_build_component`). This argument is used to trim the build.
|
||||
Other components are automatically added if they are required in the dependency chain, i.e.
|
||||
the public and private requirements of the components in this list are automatically added, and in turn the public and private requirements of those requirements,
|
||||
so on and so forth. If not specified, all components known to the build system are processed.
|
||||
Other components are automatically added if they are required in the dependency chain, i.e. the public and private requirements of the components in this list are automatically added, and in turn the public and private requirements of those requirements, so on and so forth. If not specified, all components known to the build system are processed.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_build_executable(executable)
|
||||
|
||||
Specify the executable *executable* for ESP-IDF build. This attaches additional targets such as dependencies related to
|
||||
flashing, generating additional binary files, etc. Should be called after ``idf_build_process``.
|
||||
Specify the executable *executable* for ESP-IDF build. This attaches additional targets such as dependencies related to flashing, generating additional binary files, etc. Should be called after ``idf_build_process``.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_build_get_config(var config [GENERATOR_EXPRESSION])
|
||||
|
||||
Get the value of the specified config. Much like build properties, specifying
|
||||
*GENERATOR_EXPRESSION* will retrieve the generator expression string for that config, instead of the actual value, which
|
||||
can be used with CMake commands that support generator expressions. Actual config values are only known after call to `idf_build_process`, however.
|
||||
Get the value of the specified config. Much like build properties, specifying *GENERATOR_EXPRESSION* will retrieve the generator expression string for that config, instead of the actual value, which can be used with CMake commands that support generator expressions. Actual config values are only known after call to ``idf_build_process``, however.
|
||||
|
||||
.. _cmake-build-properties:
|
||||
|
||||
idf-build-properties
|
||||
--------------------
|
||||
|
||||
These are properties that describe the build. Values of build properties can be retrieved by using the build command ``idf_build_get_property``.
|
||||
For example, to get the Python interpreter used for the build:
|
||||
These are properties that describe the build. Values of build properties can be retrieved by using the build command ``idf_build_get_property``. For example, to get the Python interpreter used for the build:
|
||||
|
||||
.. code-block: cmake
|
||||
.. code-block:: cmake
|
||||
|
||||
idf_build_get_property(python PYTHON)
|
||||
message(STATUS "The Python intepreter is: ${python}")
|
||||
|
||||
- BUILD_DIR - build directory; set from ``idf_build_process`` BUILD_DIR argument
|
||||
- BUILD_COMPONENTS - list of components included in the build; set by ``idf_build_process``
|
||||
- BUILD_COMPONENT_ALIASES - list of library alias of components included in the build; set by ``idf_build_process``
|
||||
- C_COMPILE_OPTIONS - compile options applied to all components' C source files
|
||||
- COMPILE_OPTIONS - compile options applied to all components' source files, regardless of it being C or C++
|
||||
- COMPILE_DEFINITIONS - compile definitions applied to all component source files
|
||||
- CXX_COMPILE_OPTIONS - compile options applied to all components' C++ source files
|
||||
- EXECUTABLE - project executable; set by call to ``idf_build_executable``
|
||||
- EXECUTABLE_NAME - name of project executable without extension; set by call to ``idf_build_executable``
|
||||
- EXECUTABLE_DIR - path containing the output executable
|
||||
- IDF_PATH - ESP-IDF path; set from IDF_PATH environment variable, if not, inferred from the location of ``idf.cmake``
|
||||
- IDF_TARGET - target chip for the build; set from the required target argument for ``idf_build_process``
|
||||
- IDF_VER - ESP-IDF version; set from either a version file or the Git revision of the IDF_PATH repository
|
||||
- INCLUDE_DIRECTORIES - include directories for all component source files
|
||||
- KCONFIGS - list of Kconfig files found in components in build; set by ``idf_build_process``
|
||||
- KCONFIG_PROJBUILDS - list of Kconfig.projbuild diles found in components in build; set by ``idf_build_process``
|
||||
- PROJECT_NAME - name of the project; set from ``idf_build_process`` PROJECT_NAME argument
|
||||
- PROJECT_DIR - directory of the project; set from ``idf_build_process`` PROJECT_DIR argument
|
||||
- PROJECT_VER - version of the project; set from ``idf_build_process`` PROJECT_VER argument
|
||||
- PYTHON - Python interpreter used for the build; set from PYTHON environment variable if available, if not "python" is used
|
||||
- SDKCONFIG - full path to output config file; set from ``idf_build_process`` SDKCONFIG argument
|
||||
- SDKCONFIG_DEFAULTS - list of files containing default config to use in the build; set from ``idf_build_process`` SDKCONFIG_DEFAULTS argument
|
||||
- SDKCONFIG_HEADER - full path to C/C++ header file containing component configuration; set by ``idf_build_process``
|
||||
- SDKCONFIG_CMAKE - full path to CMake file containing component configuration; set by ``idf_build_process``
|
||||
- SDKCONFIG_JSON - full path to JSON file containing component configuration; set by ``idf_build_process``
|
||||
- SDKCONFIG_JSON_MENUS - full path to JSON file containing config menus; set by ``idf_build_process``
|
||||
- BUILD_DIR - build directory; set from ``idf_build_process`` BUILD_DIR argument
|
||||
- BUILD_COMPONENTS - list of components included in the build; set by ``idf_build_process``
|
||||
- BUILD_COMPONENT_ALIASES - list of library alias of components included in the build; set by ``idf_build_process``
|
||||
- C_COMPILE_OPTIONS - compile options applied to all components' C source files
|
||||
- COMPILE_OPTIONS - compile options applied to all components' source files, regardless of it being C or C++
|
||||
- COMPILE_DEFINITIONS - compile definitions applied to all component source files
|
||||
- CXX_COMPILE_OPTIONS - compile options applied to all components' C++ source files
|
||||
- EXECUTABLE - project executable; set by call to ``idf_build_executable``
|
||||
- EXECUTABLE_NAME - name of project executable without extension; set by call to ``idf_build_executable``
|
||||
- EXECUTABLE_DIR - path containing the output executable
|
||||
- IDF_PATH - ESP-IDF path; set from IDF_PATH environment variable, if not, inferred from the location of ``idf.cmake``
|
||||
- IDF_TARGET - target chip for the build; set from the required target argument for ``idf_build_process``
|
||||
- IDF_VER - ESP-IDF version; set from either a version file or the Git revision of the IDF_PATH repository
|
||||
- INCLUDE_DIRECTORIES - include directories for all component source files
|
||||
- KCONFIGS - list of Kconfig files found in components in build; set by ``idf_build_process``
|
||||
- KCONFIG_PROJBUILDS - list of Kconfig.projbuild files found in components in build; set by ``idf_build_process``
|
||||
- PROJECT_NAME - name of the project; set from ``idf_build_process`` PROJECT_NAME argument
|
||||
- PROJECT_DIR - directory of the project; set from ``idf_build_process`` PROJECT_DIR argument
|
||||
- PROJECT_VER - version of the project; set from ``idf_build_process`` PROJECT_VER argument
|
||||
- PYTHON - Python interpreter used for the build; set from PYTHON environment variable if available, if not "python" is used
|
||||
- SDKCONFIG - full path to output config file; set from ``idf_build_process`` SDKCONFIG argument
|
||||
- SDKCONFIG_DEFAULTS - list of files containing default config to use in the build; set from ``idf_build_process`` SDKCONFIG_DEFAULTS argument
|
||||
- SDKCONFIG_HEADER - full path to C/C++ header file containing component configuration; set by ``idf_build_process``
|
||||
- SDKCONFIG_CMAKE - full path to CMake file containing component configuration; set by ``idf_build_process``
|
||||
- SDKCONFIG_JSON - full path to JSON file containing component configuration; set by ``idf_build_process``
|
||||
- SDKCONFIG_JSON_MENUS - full path to JSON file containing config menus; set by ``idf_build_process``
|
||||
|
||||
idf-component-commands
|
||||
----------------------
|
||||
@@ -1262,17 +1210,13 @@ idf-component-commands
|
||||
|
||||
idf_component_get_property(var component property [GENERATOR_EXPRESSION])
|
||||
|
||||
Retrieve a specified *component*'s :ref:`component property<cmake-component-properties>`, *property* and store it in *var* accessible from the current scope. Specifying
|
||||
*GENERATOR_EXPRESSION* will retrieve the generator expression string for that property, instead of the actual value, which
|
||||
can be used with CMake commands that support generator expressions.
|
||||
Retrieve a specified *component*'s :ref:`component property<cmake-component-properties>`, *property* and store it in *var* accessible from the current scope. Specifying *GENERATOR_EXPRESSION* will retrieve the generator expression string for that property, instead of the actual value, which can be used with CMake commands that support generator expressions.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_component_set_property(component property val [APPEND])
|
||||
|
||||
Set a specified *component*'s :ref:`component property<cmake-component-properties>`, *property* with value *val*. Specifying *APPEND* will append the specified value to the current
|
||||
value of the property. If the property does not previously exist or it is currently empty, the specified value becomes
|
||||
the first element/member instead.
|
||||
Set a specified *component*'s :ref:`component property<cmake-component-properties>`, *property* with value *val*. Specifying *APPEND* will append the specified value to the current value of the property. If the property does not previously exist or it is currently empty, the specified value becomes the first element/member instead.
|
||||
|
||||
.. _cmake-component-register:
|
||||
|
||||
@@ -1288,9 +1232,7 @@ the first element/member instead.
|
||||
[EMBED_FILES file1 file2 ...]
|
||||
[EMBED_TXTFILES file1 file2 ...])
|
||||
|
||||
Register a component to the build system. Much like the ``project()`` CMake command, this should be called from the component's
|
||||
CMakeLists.txt directly (not through a function or macro) and is recommended to be called before any other command. Here are some
|
||||
guidelines on what commands can **not** be called before ``idf_component_register``:
|
||||
Register a component to the build system. Much like the ``project()`` CMake command, this should be called from the component's CMakeLists.txt directly (not through a function or macro) and is recommended to be called before any other command. Here are some guidelines on what commands can **not** be called before ``idf_component_register``:
|
||||
|
||||
- commands that are not valid in CMake script mode
|
||||
- custom commands defined in project_include.cmake
|
||||
@@ -1300,8 +1242,7 @@ Commands that set and operate on variables are generally okay to call before ``i
|
||||
|
||||
The arguments for ``idf_component_register`` include:
|
||||
|
||||
- SRCS - component source files used for creating a static library for the component; if not specified, component is a treated as a
|
||||
config-only component and an interface library is created instead.
|
||||
- SRCS - component source files used for creating a static library for the component; if not specified, component is a treated as a config-only component and an interface library is created instead.
|
||||
- SRC_DIRS, EXCLUDE_SRCS - used to glob source files (.c, .cpp, .S) by specifying directories, instead of specifying source files manually via SRCS. Note that this is subject to the :ref:`limitations of globbing in CMake<cmake-file-globbing>`. Source files specified in EXCLUDE_SRCS are removed from the globbed files.
|
||||
- INCLUDE_DIRS - paths, relative to the component directory, which will be added to the include search path for all other components which require the current component
|
||||
- PRIV_INCLUDE_DIRS - directory paths, must be relative to the component directory, which will be added to the include search path for this component's source files only
|
||||
@@ -1310,9 +1251,7 @@ The arguments for ``idf_component_register`` include:
|
||||
- LDFRAGMENTS - component linker fragment files
|
||||
- REQUIRED_IDF_TARGETS - specify the only target the component supports
|
||||
|
||||
The following are used for :ref:`embedding data into the component<cmake_embed_data>`, and is considered as source files
|
||||
when determining if a component is config-only. This means that even if the component does not specify source files, a static library is still
|
||||
created internally for the component if it specifies either:
|
||||
The following are used for :ref:`embedding data into the component<cmake_embed_data>`, and is considered as source files when determining if a component is config-only. This means that even if the component does not specify source files, a static library is still created internally for the component if it specifies either:
|
||||
|
||||
- EMBED_FILES - binary files to be embedded in the component
|
||||
- EMBED_TXTFILES - text files to be embedded in the component
|
||||
@@ -1322,22 +1261,18 @@ created internally for the component if it specifies either:
|
||||
idf-component-properties
|
||||
------------------------
|
||||
|
||||
These are properties that describe a component. Values of component properties can be retrieved by using the build command ``idf_component_get_property``.
|
||||
For example, to get the directory of the ``freertos`` component:
|
||||
These are properties that describe a component. Values of component properties can be retrieved by using the build command ``idf_component_get_property``. For example, to get the directory of the ``freertos`` component:
|
||||
|
||||
.. code-block: cmake
|
||||
.. code-block:: cmake
|
||||
|
||||
idf_component_get_property(dir freertos COMPONENT_DIR)
|
||||
message(STATUS "The 'freertos' component directory is: ${dir}")
|
||||
|
||||
- COMPONENT_ALIAS - alias for COMPONENT_LIB used for linking the component to external targets; set by ``idf_build_component`` and alias library itself
|
||||
is created by ``idf_component_register``
|
||||
- COMPONENT_ALIAS - alias for COMPONENT_LIB used for linking the component to external targets; set by ``idf_build_component`` and alias library itself is created by ``idf_component_register``
|
||||
- COMPONENT_DIR - component directory; set by ``idf_build_component``
|
||||
- COMPONENT_LIB - name for created component static/interface library; set by ``idf_build_component`` and library itself
|
||||
is created by ``idf_component_register``
|
||||
- COMPONENT_LIB - name for created component static/interface library; set by ``idf_build_component`` and library itself is created by ``idf_component_register``
|
||||
- COMPONENT_NAME - name of the component; set by ``idf_build_component`` based on the component directory name
|
||||
- COMPONENT_TYPE - type of the component, whether LIBRARY or CONFIG_ONLY. A component is of type LIBRARY if it specifies
|
||||
source files or embeds a file
|
||||
- COMPONENT_TYPE - type of the component, whether LIBRARY or CONFIG_ONLY. A component is of type LIBRARY if it specifies source files or embeds a file
|
||||
- EMBED_FILES - list of files to embed in component; set from ``idf_component_register`` EMBED_FILES argument
|
||||
- EMBED_TXTFILES - list of text files to embed in component; set from ``idf_component_register`` EMBED_TXTFILES argument
|
||||
- INCLUDE_DIRS - list of component include directories; set from ``idf_component_register`` INCLUDE_DIRS argument
|
||||
@@ -1382,6 +1317,8 @@ For project components (not part of ESP-IDF), there are a few different options:
|
||||
|
||||
The best option will depend on your particular project and its users.
|
||||
|
||||
.. _build_system_metadata:
|
||||
|
||||
Build System Metadata
|
||||
=====================
|
||||
|
||||
@@ -1445,6 +1382,7 @@ This section describes the standard ESP-IDF application build process. The build
|
||||
|
||||
Initialization
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This phase sets up necessary parameters for the build.
|
||||
|
||||
- Upon inclusion of ``idf.cmake`` in ``project.cmake``, the following steps are performed:
|
||||
@@ -1470,6 +1408,7 @@ Enumeration
|
||||
|
||||
Processing
|
||||
^^^^^^^^^^
|
||||
|
||||
This phase processes the components in the build, and is the second half of ``idf_build_process()``.
|
||||
|
||||
- Load project configuration from sdkconfig file and generate an sdkconfig.cmake and sdkconfig.h header. These define configuration variables/macros that are accessible from the build scripts and C/C++ source/header files, respectively.
|
||||
@@ -1483,16 +1422,12 @@ Finalization
|
||||
- Create executable and link the component libraries to it.
|
||||
- Generate project metadata files such as project_description.json and display relevant information about the project built.
|
||||
|
||||
|
||||
Browse :idf_file:`/tools/cmake/project.cmake` for more details.
|
||||
|
||||
Migrating from ESP-IDF GNU Make System
|
||||
======================================
|
||||
|
||||
Some aspects of the CMake-based ESP-IDF build system are very similar to the older GNU Make-based system. The developer needs to provide values
|
||||
the include directories, source files etc. There is a syntactical difference, however, as the developer needs to pass these as arguments
|
||||
to the registration command, `idf_component_register`.
|
||||
|
||||
Some aspects of the CMake-based ESP-IDF build system are very similar to the older GNU Make-based system. The developer needs to provide values the include directories, source files etc. There is a syntactical difference, however, as the developer needs to pass these as arguments to the registration command, ``idf_component_register``.
|
||||
|
||||
Automatic Conversion Tool
|
||||
-------------------------
|
||||
@@ -1546,7 +1481,6 @@ No Longer Necessary
|
||||
|
||||
- In the legacy Make-based build system, it is required to also set ``COMPONENT_SRCDIRS`` if ``COMPONENT_SRCS`` is set. In CMake, the equivalent is not necessary i.e. specifying ``SRC_DIRS`` to ``idf_component_register`` if ``SRCS`` is also specified (in fact, ``SRCS`` is ignored if ``SRC_DIRS`` is specified).
|
||||
|
||||
|
||||
Flashing from make
|
||||
------------------
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ API Guides
|
||||
Linker Script Generation <linker-script-generation>
|
||||
lwIP TCP/IP Stack <lwip>
|
||||
Partition Tables <partition-tables>
|
||||
:esp32: RF Calibration <RF_calibration>
|
||||
RF Calibration <RF_calibration>
|
||||
ROM debug console <romconsole>
|
||||
:esp32: Secure Boot <../security/secure-boot-v1>
|
||||
Secure Boot V2 <../security/secure-boot-v2>
|
||||
|
||||
@@ -171,7 +171,14 @@ MD5 checksum
|
||||
|
||||
The binary format of the partition table contains an MD5 checksum computed based on the partition table. This checksum is used for checking the integrity of the partition table during the boot.
|
||||
|
||||
The MD5 checksum generation can be disabled by the ``--disable-md5sum`` option of ``gen_esp32part.py`` or by the :ref:`CONFIG_PARTITION_TABLE_MD5` option. This is useful for example when one uses a legacy bootloader which cannot process MD5 checksums and the boot fails with the error message ``invalid magic number 0xebeb``.
|
||||
.. only:: esp32
|
||||
|
||||
The MD5 checksum generation can be disabled by the ``--disable-md5sum`` option of ``gen_esp32part.py`` or by the :ref:`CONFIG_PARTITION_TABLE_MD5` option. This is useful for example when one :ref:`uses a bootloader from ESP-IDF before v3.1 <CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS>` which cannot process MD5 checksums and the boot fails with the error message ``invalid magic number 0xebeb``.
|
||||
|
||||
.. only:: not esp32
|
||||
|
||||
The MD5 checksum generation can be disabled by the ``--disable-md5sum`` option of ``gen_esp32part.py`` or by the :ref:`CONFIG_PARTITION_TABLE_MD5` option.
|
||||
|
||||
|
||||
Flashing the partition table
|
||||
----------------------------
|
||||
|
||||
@@ -8,40 +8,57 @@ The IDF monitor tool is mainly a serial terminal program which relays serial dat
|
||||
|
||||
This tool can be launched from an IDF project by running ``idf.py monitor``.
|
||||
|
||||
(For the legacy GNU Make system, run ``make monitor``.)
|
||||
For the legacy GNU Make system, run ``make monitor``.
|
||||
|
||||
|
||||
Keyboard Shortcuts
|
||||
==================
|
||||
|
||||
For easy interaction with IDF Monitor, use the keyboard shortcuts given in the table.
|
||||
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Keyboard Shortcut | Action | Description |
|
||||
+===================+========================================================+======================================================================================================================================================================================================================================================+
|
||||
| Ctrl+] | Exit the program | |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Ctrl+T | Menu escape key | Press and follow it by one of the keys given below. |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+T | Send the menu character itself to remote | |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+] | Send the exit character itself to remote | |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+P | Reset target into bootloader to pause app via RTS line | Resets the target, into bootloader via the RTS line (if connected), so that the board runs nothing. Useful when you need to wait for another device to startup. |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+R | Reset target board via RTS | Resets the target board and re-starts the application via the RTS line (if connected). |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+F | Build and flash the project | Pauses idf_monitor to run the project ``flash`` target, then resumes idf_monitor. Any changed source files are recompiled and then re-flashed. Target ``encrypted-flash`` is run if idf_monitor was started with argument ``-E``. |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+A (or A) | Build and flash the app only | Pauses idf_monitor to run the ``app-flash`` target, then resumes idf_monitor. Similar to the ``flash`` target, but only the main app is built and re-flashed. Target ``encrypted-app-flash`` is run if idf_monitor was started with argument ``-E``. |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+Y | Stop/resume log output printing on screen | Discards all incoming serial data while activated. Allows to quickly pause and examine log output without quitting the monitor. |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+L | Stop/resume log output saved to file | Creates a file in the project directory and the output is written to that file until this is disabled with the same keyboard shortcut (or IDF Monitor exits). |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+H (or H) | Display all keyboard shortcuts | |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| - Ctrl+X (or X) | Exit the program | |
|
||||
+-------------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 15 25 55
|
||||
|
||||
* - Keyboard Shortcut
|
||||
- Action
|
||||
- Description
|
||||
* - Ctrl+]
|
||||
- Exit the program
|
||||
-
|
||||
* - Ctrl+T
|
||||
- Menu escape key
|
||||
- Press and follow it by one of the keys given below.
|
||||
* - * Ctrl+T
|
||||
- Send the menu character itself to remote
|
||||
-
|
||||
* - * Ctrl+]
|
||||
- Send the exit character itself to remote
|
||||
-
|
||||
* - * Ctrl+P
|
||||
- Reset target into bootloader to pause app via RTS line
|
||||
- Resets the target, into bootloader via the RTS line (if connected), so that the board runs nothing. Useful when you need to wait for another device to startup.
|
||||
* - * Ctrl+R
|
||||
- Reset target board via RTS
|
||||
- Resets the target board and re-starts the application via the RTS line (if connected).
|
||||
* - * Ctrl+F
|
||||
- Build and flash the project
|
||||
- Pauses idf_monitor to run the project ``flash`` target, then resumes idf_monitor. Any changed source files are recompiled and then re-flashed. Target ``encrypted-flash`` is run if idf_monitor was started with argument ``-E``.
|
||||
* - * Ctrl+A (or A)
|
||||
- Build and flash the app only
|
||||
- Pauses idf_monitor to run the ``app-flash`` target, then resumes idf_monitor. Similar to the ``flash`` target, but only the main app is built and re-flashed. Target ``encrypted-app-flash`` is run if idf_monitor was started with argument ``-E``.
|
||||
* - * Ctrl+Y
|
||||
- Stop/resume log output printing on screen
|
||||
- Discards all incoming serial data while activated. Allows to quickly pause and examine log output without quitting the monitor.
|
||||
* - * Ctrl+L
|
||||
- Stop/resume log output saved to file
|
||||
- Creates a file in the project directory and the output is written to that file until this is disabled with the same keyboard shortcut (or IDF Monitor exits).
|
||||
* - * Ctrl+H (or H)
|
||||
- Display all keyboard shortcuts
|
||||
-
|
||||
* - * Ctrl+X (or X)
|
||||
- Exit the program
|
||||
-
|
||||
|
||||
Any keys pressed, other than ``Ctrl-]`` and ``Ctrl-T``, will be sent through the serial port.
|
||||
|
||||
@@ -49,7 +66,6 @@ Any keys pressed, other than ``Ctrl-]`` and ``Ctrl-T``, will be sent through the
|
||||
IDF-specific features
|
||||
=====================
|
||||
|
||||
|
||||
Automatic Address Decoding
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -122,40 +138,23 @@ Restrictions on what to print can be specified as a series of ``<tag>:<log_level
|
||||
For example, ``PRINT_FILTER="tag1:W"`` matches and prints only the outputs written with ``ESP_LOGW("tag1", ...)`` or at lower verbosity level, i.e. ``ESP_LOGE("tag1", ...)``. Not specifying a ``<log_level>`` or using ``*`` defaults to Verbose level.
|
||||
|
||||
.. note::
|
||||
Use primary logging to disable at compilation the outputs you do not
|
||||
need through the :doc:`logging library<../../api-reference/system/log>`.
|
||||
Output filtering with IDF monitor is a secondary solution
|
||||
which can be useful for adjusting the filtering options without
|
||||
recompiling the application.
|
||||
Use primary logging to disable at compilation the outputs you do not need through the :doc:`logging library<../../api-reference/system/log>`. Output filtering with IDF monitor is a secondary solution which can be useful for adjusting the filtering options without recompiling the application.
|
||||
|
||||
Your app tags must not contain spaces, asterisks ``*``,
|
||||
and semicolons ``:`` to be compatible with the output filtering feature.
|
||||
Your app tags must not contain spaces, asterisks ``*``, or colons ``:`` to be compatible with the output filtering feature.
|
||||
|
||||
If the last line of the output in your app is not followed by a carriage return, the output filtering might get confused, i.e., the monitor starts to print the line and later finds out that the line should not have been written. This is a known issue and can be avoided by always adding a carriage return (especially when no output follows immediately afterwards).
|
||||
|
||||
Examples Of Filtering Rules:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- ``*`` can be used to match any tags. However, the string
|
||||
``PRINT_FILTER="*:I tag1:E"`` with regards to ``tag1`` prints errors
|
||||
only, because the rule for ``tag1`` has a higher priority over the rule for ``*``.
|
||||
- The default (empty) rule is equivalent to ``*:V`` because matching every tag
|
||||
at the Verbose level or lower means matching everything.
|
||||
- ``"*:N"`` suppresses not only the outputs from logging functions, but also
|
||||
the prints made by ``printf``, etc. To avoid this, use ``*:E`` or a higher verbosity level.
|
||||
- Rules ``"tag1:V"``, ``"tag1:v"``, ``"tag1:"``, ``"tag1:*"``, and ``"tag1"``
|
||||
are equivalent.
|
||||
- Rule ``"tag1:W tag1:E"`` is equivalent to ``"tag1:E"`` because any
|
||||
consequent occurrence of the same tag name overwrites the previous one.
|
||||
- Rule ``"tag1:I tag2:W"`` only prints ``tag1`` at the Info verbosity level or
|
||||
lower and ``tag2`` at the Warning verbosity level or lower.
|
||||
- Rule ``"tag1:I tag2:W tag3:N"`` is essentially equivalent to the previous
|
||||
one because ``tag3:N`` specifies that ``tag3`` should not be printed.
|
||||
- ``tag3:N`` in the rule ``"tag1:I tag2:W tag3:N *:V"`` is more meaningful because
|
||||
without ``tag3:N`` the ``tag3`` messages could have been printed;
|
||||
the errors for ``tag1`` and ``tag2`` will be printed at the specified (or lower)
|
||||
verbosity level and everything else will be printed by default.
|
||||
|
||||
- ``*`` can be used to match any tags. However, the string ``PRINT_FILTER="*:I tag1:E"`` with regards to ``tag1`` prints errors only, because the rule for ``tag1`` has a higher priority over the rule for ``*``.
|
||||
- The default (empty) rule is equivalent to ``*:V`` because matching every tag at the Verbose level or lower means matching everything.
|
||||
- ``"*:N"`` suppresses not only the outputs from logging functions, but also the prints made by ``printf``, etc. To avoid this, use ``*:E`` or a higher verbosity level.
|
||||
- Rules ``"tag1:V"``, ``"tag1:v"``, ``"tag1:"``, ``"tag1:*"``, and ``"tag1"`` are equivalent.
|
||||
- Rule ``"tag1:W tag1:E"`` is equivalent to ``"tag1:E"`` because any consequent occurrence of the same tag name overwrites the previous one.
|
||||
- Rule ``"tag1:I tag2:W"`` only prints ``tag1`` at the Info verbosity level or lower and ``tag2`` at the Warning verbosity level or lower.
|
||||
- Rule ``"tag1:I tag2:W tag3:N"`` is essentially equivalent to the previous one because ``tag3:N`` specifies that ``tag3`` should not be printed.
|
||||
- ``tag3:N`` in the rule ``"tag1:I tag2:W tag3:N *:V"`` is more meaningful because without ``tag3:N`` the ``tag3`` messages could have been printed; the errors for ``tag1`` and ``tag2`` will be printed at the specified (or lower) verbosity level and everything else will be printed by default.
|
||||
|
||||
|
||||
A More Complex Filtering Example
|
||||
@@ -192,7 +191,7 @@ Known Issues with IDF Monitor
|
||||
=============================
|
||||
|
||||
Issues Observed on Windows
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- If in the Windows environment you receive the error "winpty: command not found", fix it by running ``pacman -S winpty``.
|
||||
- Arrow keys, as well as some other keys, do not work in GDB due to Windows Console limitations.
|
||||
@@ -203,4 +202,4 @@ Issues Observed on Windows
|
||||
.. _addr2line: https://sourceware.org/binutils/docs/binutils/addr2line.html
|
||||
.. _gdb: https://sourceware.org/gdb/download/onlinedocs/
|
||||
.. _pySerial: https://github.com/pyserial/pyserial
|
||||
.. _miniterm: https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.miniterm
|
||||
.. _miniterm: https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.miniterm
|
||||
@@ -40,6 +40,20 @@ Inside ``IDF_TOOLS_PATH``, the scripts performing tools installation create the
|
||||
- ``dist`` — where the archives of the tools are downloaded.
|
||||
- ``tools`` — where the tools are extracted. The tools are extracted into subdirectories: ``tools/TOOL_NAME/VERSION/``. This arrangement allows different versions of tools to be installed side by side.
|
||||
|
||||
GitHub Assets Mirror
|
||||
--------------------
|
||||
|
||||
Most of the tools downloaded by the tools installer are GitHub Release Assets, which are files attached to a software release on GitHub.
|
||||
|
||||
If GitHub downloads are inaccessible or slow to access, it's possible to configure a GitHub assets mirror.
|
||||
|
||||
To use Espressif's download server, set the environment variable ``IDF_GITHUB_ASSETS`` to ``dl.espressif.com/github_assets``. When the install process is downloading a tool from ``github.com``, the URL will be rewritten to use this server instead.
|
||||
|
||||
Any mirror server can be used provided the URL matches the ``github.com`` download URL format: the install process will replace ``https://github.com`` with ``https://${IDF_GITHUB_ASSETS}`` for any GitHub asset URL that it downloads.
|
||||
|
||||
.. note:: The Espressif download server doesn't currently mirror everything from GitHub, it only mirrors files attached as Assets to some releases as well as source archives for some releases.
|
||||
|
||||
|
||||
``idf_tools.py`` script
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -44,11 +44,7 @@ To compile the ULP code as part of the component, the following steps must be ta
|
||||
|
||||
ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}")
|
||||
|
||||
The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here will also be used by other generated artifacts
|
||||
such as the ELF file, map file, header file and linker export file. The second argument specifies the ULP assembly source files.
|
||||
Finally, the third argument specifies the list of component source files which include the header file to be generated.
|
||||
This list is needed to build the dependencies correctly and ensure that the generated header file will be created before any of these files are compiled.
|
||||
See section below for the concept of generated header files for ULP applications.
|
||||
The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here will also be used by other generated artifacts such as the ELF file, map file, header file and linker export file. The second argument specifies the ULP assembly source files. Finally, the third argument specifies the list of component source files which include the header file to be generated. This list is needed to build the dependencies correctly and ensure that the generated header file will be created before any of these files are compiled. See section below for the concept of generated header files for ULP applications.
|
||||
|
||||
3. Build the application as usual (e.g. `idf.py app`)
|
||||
|
||||
@@ -149,7 +145,7 @@ Declaration of the entry point symbol comes from the generated header file menti
|
||||
ULP Program Flow
|
||||
----------------
|
||||
|
||||
The ULP coprocessor is started by a timer. The timer is started once ``ulp_run`` is called. The timer counts the number of RTC_SLOW_CLK ticks (by default, produced by an internal 150kHz RC oscillator). The number of ticks is set using ``SENS_ULP_CP_SLEEP_CYCx_REG`` registers (x = 0..4). When starting the ULP for the first time, ``SENS_ULP_CP_SLEEP_CYC0_REG`` will be used to set the number of timer ticks. Later the ULP program can select another ``SENS_ULP_CP_SLEEP_CYCx_REG`` register using the ``sleep`` instruction.
|
||||
The ULP coprocessor is started by a timer. The timer is started once ``ulp_run`` is called. The timer counts a number of RTC_SLOW_CLK ticks (by default, produced by an internal 150 kHz RC oscillator). The number of ticks is set using ``SENS_ULP_CP_SLEEP_CYCx_REG`` registers (x = 0..4). When starting the ULP for the first time, ``SENS_ULP_CP_SLEEP_CYC0_REG`` will be used to set the number of timer ticks. Later the ULP program can select another ``SENS_ULP_CP_SLEEP_CYCx_REG`` register using the ``sleep`` instruction.
|
||||
|
||||
The application can set ULP timer period values (SENS_ULP_CP_SLEEP_CYCx_REG, x = 0..4) using the ``ulp_set_wakeup_period`` function.
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@ ESP-IDF comes with a unit test application that is based on the Unity - unit tes
|
||||
Normal Test Cases
|
||||
------------------
|
||||
|
||||
Unit tests are located in the ``test`` subdirectory of a component.
|
||||
Tests are written in C, and a single C source file can contain multiple test cases.
|
||||
Test files start with the word "test".
|
||||
Unit tests are located in the ``test`` subdirectory of a component. Tests are written in C, and a single C source file can contain multiple test cases. Test files start with the word "test".
|
||||
|
||||
Each test file should include the ``unity.h`` header and the header for the C module to be tested.
|
||||
|
||||
@@ -19,16 +17,17 @@ Tests are added in a function in the C file as follows:
|
||||
|
||||
TEST_CASE("test name", "[module name]"
|
||||
{
|
||||
// Add test here
|
||||
// Add test here
|
||||
}
|
||||
|
||||
The first argument is a descriptive name for the test, the second argument is an identifier in square brackets.
|
||||
Identifiers are used to group related test, or tests with specific properties.
|
||||
|
||||
- The first argument is a descriptive name for the test.
|
||||
- The second argument is an identifier in square brackets. Identifiers are used to group related test, or tests with specific properties.
|
||||
|
||||
.. note::
|
||||
There is no need to add a main function with ``UNITY_BEGIN()`` and ``UNITY_END()`` in each test case. ``unity_platform.c`` will run ``UNITY_BEGIN()`` autonomously, and run the test cases, then call ``UNITY_END()``.
|
||||
|
||||
The ``test`` subdirectory should contain a :ref:`component CMakeLists.txt <component-directories>`, since they are themselves, components. ESP-IDF uses the ``unity`` test framework and should be specified as a requirement for the component. Normally, components :ref:`should list their sources manually <cmake-file-globbing>`; for component tests however, this requirement is relaxed and the use of the ``SRC_DIRS`` argument in ``idf_component_register`` is advised.
|
||||
The ``test`` subdirectory should contain a :ref: `component CMakeLists.txt <component-directories>`, since they are themselves, components. ESP-IDF uses the ``unity`` test framework and should be specified as a requirement for the component. Normally, components :ref: `should list their sources manually <cmake-file-globbing>`; for component tests however, this requirement is relaxed and the use of the ``SRC_DIRS`` argument in ``idf_component_register`` is advised.
|
||||
|
||||
Overall, the minimal ``test`` subdirectory ``CMakeLists.txt`` file should contain the following:
|
||||
|
||||
@@ -44,8 +43,7 @@ See http://www.throwtheswitch.org/unity for more information about writing tests
|
||||
Multi-device Test Cases
|
||||
-------------------------
|
||||
|
||||
The normal test cases will be executed on one DUT (Device Under Test). However, components that require some form of communication (e.g., GPIO, SPI) require another device to communicate with, thus cannot be tested normal test cases.
|
||||
Multi-device test cases involve writing multiple test functions, and running them on multiple DUTs.
|
||||
The normal test cases will be executed on one DUT (Device Under Test). However, components that require some form of communication (e.g., GPIO, SPI) require another device to communicate with, thus cannot be tested normal test cases. Multi-device test cases involve writing multiple test functions, and running them on multiple DUTs.
|
||||
|
||||
The following is an example of a multi-device test case:
|
||||
|
||||
@@ -75,13 +73,13 @@ The following is an example of a multi-device test case:
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("gpio multiple devices test example", "[driver]", gpio_master_test, gpio_slave_test);
|
||||
|
||||
|
||||
The macro ``TEST_CASE_MULTIPLE_DEVICES`` is used to declare a multi-device test case.
|
||||
The first argument is test case name, the second argument is test case description.
|
||||
From the third argument, up to 5 test functions can be defined, each function will be the entry point of tests running on each DUT.
|
||||
|
||||
Running test cases from different DUTs could require synchronizing between DUTs. We provide ``unity_wait_for_signal`` and ``unity_send_signal`` to support synchronizing with UART.
|
||||
As the scenario in the above example, the slave should get GPIO level after master set level. DUT UART console will prompt and user interaction is required:
|
||||
- The first argument is test case name.
|
||||
- The second argument is test case description.
|
||||
- From the third argument, up to 5 test functions can be defined, each function will be the entry point of tests running on each DUT.
|
||||
|
||||
Running test cases from different DUTs could require synchronizing between DUTs. We provide ``unity_wait_for_signal`` and ``unity_send_signal`` to support synchronizing with UART. As the scenario in the above example, the slave should get GPIO level after master set level. DUT UART console will prompt and user interaction is required:
|
||||
|
||||
DUT1 (master) console::
|
||||
|
||||
@@ -98,9 +96,7 @@ Once the signal is sent from DUT2, you need to press "Enter" on DUT1, then DUT1
|
||||
Multi-stage Test Cases
|
||||
-----------------------
|
||||
|
||||
The normal test cases are expected to finish without reset (or only need to check if reset happens). Sometimes we expect to run some specific tests after certain kinds of reset.
|
||||
For example, we expect to test if the reset reason is correct after a wakeup from deep sleep. We need to create a deep-sleep reset first and then check the reset reason.
|
||||
To support this, we can define multi-stage test cases, to group a set of test functions::
|
||||
The normal test cases are expected to finish without reset (or only need to check if reset happens). Sometimes we expect to run some specific tests after certain kinds of reset. For example, we expect to test if the reset reason is correct after a wakeup from deep sleep. We need to create a deep-sleep reset first and then check the reset reason. To support this, we can define multi-stage test cases, to group a set of test functions::
|
||||
|
||||
static void trigger_deepsleep(void)
|
||||
{
|
||||
@@ -118,16 +114,12 @@ To support this, we can define multi-stage test cases, to group a set of test fu
|
||||
|
||||
Multi-stage test cases present a group of test functions to users. It needs user interactions (select cases and select different stages) to run the case.
|
||||
|
||||
|
||||
Tests For Different Targets
|
||||
---------------------------
|
||||
------------------------------
|
||||
|
||||
Some tests (especially those related to hardware) cannot run on all targets. Below is a guide how
|
||||
to make your unit tests run on only specified targets.
|
||||
Some tests (especially those related to hardware) cannot run on all targets. Below is a guide how to make your unit tests run on only specified targets.
|
||||
|
||||
1. Wrap your test code by ``!(TEMPORARY_)DISABLED_FOR_TARGETS()`` macros and place them either in
|
||||
the original test file, or sepeprate the code into files grouped by functions, but make sure all
|
||||
these files will be processed by the compiler. E.g.: ::
|
||||
1. Wrap your test code by ``!(TEMPORARY_)DISABLED_FOR_TARGETS()`` macros and place them either in the original test file, or sepeprate the code into files grouped by functions, but make sure all these files will be processed by the compiler. E.g.::
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP8266)
|
||||
TEST_CASE("a test that is not ready for esp32 and esp8266 yet", "[]")
|
||||
@@ -135,11 +127,7 @@ to make your unit tests run on only specified targets.
|
||||
}
|
||||
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP8266)
|
||||
|
||||
Once you need one of the tests to be compiled on a specified target, just modify the targets
|
||||
in the disabled list. It's more encouraged to use some general conception that can be
|
||||
described in ``soc_caps.h`` to control the disabling of tests. If this is done but some of the
|
||||
tests are not ready yet, use both of them (and remove ``!(TEMPORARY_)DISABLED_FOR_TARGETS()``
|
||||
later). E.g.: ::
|
||||
Once you need one of the tests to be compiled on a specified target, just modify the targets in the disabled list. It's more encouraged to use some general conception that can be described in ``soc_caps.h`` to control the disabling of tests. If this is done but some of the tests are not ready yet, use both of them (and remove ``!(TEMPORARY_)DISABLED_FOR_TARGETS()`` later). E.g.: ::
|
||||
|
||||
#if SOC_SDIO_SLAVE_SUPPORTED
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP64)
|
||||
@@ -150,49 +138,32 @@ to make your unit tests run on only specified targets.
|
||||
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP64)
|
||||
#endif //SOC_SDIO_SLAVE_SUPPORTED
|
||||
|
||||
2. For test code that you are 100% for sure that will not be supported (e.g. no peripheral at
|
||||
all), use ``DISABLED_FOR_TARGETS``; for test code that should be disabled temporarily, or due to
|
||||
lack of runners, etc., use ``TEMPORARY_DISABLED_FOR_TARGETS``.
|
||||
2. For test code that you are 100% for sure that will not be supported (e.g. no peripheral at all), use ``DISABLED_FOR_TARGETS``; for test code that should be disabled temporarily, or due to lack of runners, etc., use ``TEMPORARY_DISABLED_FOR_TARGETS``.
|
||||
|
||||
Some old ways of disabling unit tests for targets, that have obvious disadvantages, are deprecated:
|
||||
|
||||
- DON'T put the test code under ``test/target`` folder and use CMakeLists.txt to choose one of the
|
||||
target folder. This is prevented because test code is more likely to be reused than the
|
||||
implementations. If you put something into ``test/esp32`` just to avoid building it on esp32s2,
|
||||
it's hard to make the code tidy if you want to enable the test again on esp32s3.
|
||||
- DON'T put the test code under ``test/target`` folder and use CMakeLists.txt to choose one of the target folder. This is prevented because test code is more likely to be reused than the implementations. If you put something into ``test/esp32`` just to avoid building it on esp32s2, it's hard to make the code tidy if you want to enable the test again on esp32s3.
|
||||
|
||||
- DON'T use ``CONFIG_IDF_TARGET_xxx`` macros to disable the test items any more. This makes it
|
||||
harder to track disabled tests and enable them again. Also, a black-list style ``#if !disabled``
|
||||
is preferred to white-list style ``#if CONFIG_IDF_TARGET_xxx``, since you will not silently
|
||||
disable cases when new targets are added in the future. But for test implementations, it's
|
||||
allowed to use ``#if CONFIG_IDF_TARGET_xxx`` to pick one of the implementation code.
|
||||
- DON'T use ``CONFIG_IDF_TARGET_xxx`` macros to disable the test items any more. This makes it harder to track disabled tests and enable them again. Also, a black-list style ``#if !disabled`` is preferred to white-list style ``#if CONFIG_IDF_TARGET_xxx``, since you will not silently disable cases when new targets are added in the future. But for test implementations, it's allowed to use ``#if CONFIG_IDF_TARGET_xxx`` to pick one of the implementation code.
|
||||
|
||||
- Test item: some items that will be performed on some targets, but skipped on other
|
||||
targets. E.g.
|
||||
- Test item: some items that will be performed on some targets, but skipped on other targets. E.g.
|
||||
|
||||
There are three test items SD 1-bit, SD 4-bit and SDSPI. For ESP32-S2, which doesn't have
|
||||
SD host, among the tests only SDSPI is enabled on ESP32-S2.
|
||||
There are three test items SD 1-bit, SD 4-bit and SDSPI. For ESP32-S2, which doesn't have SD host, among the tests only SDSPI is enabled on ESP32-S2.
|
||||
|
||||
- Test implementation: some code will always happen, but in different ways. E.g.
|
||||
|
||||
There is no SDIO PKT_LEN register on ESP8266. If you want to get the length from the slave
|
||||
as a step in the test process, you can have different implementation code protected by
|
||||
``#if CONFIG_IDF_TARGET_`` reading in different ways.
|
||||
There is no SDIO PKT_LEN register on ESP8266. If you want to get the length from the slave as a step in the test process, you can have different implementation code protected by ``#if CONFIG_IDF_TARGET_`` reading in different ways.
|
||||
|
||||
But please avoid using ``#else`` macro. When new target is added, the test case will fail at
|
||||
building stage, so that the maintainer will be aware of this, and choose one of the
|
||||
implementations explicitly.
|
||||
But please avoid using ``#else`` macro. When new target is added, the test case will fail at building stage, so that the maintainer will be aware of this, and choose one of the implementations explicitly.
|
||||
|
||||
Building Unit Test App
|
||||
----------------------
|
||||
|
||||
Follow the setup instructions in the top-level esp-idf README.
|
||||
Make sure that ``IDF_PATH`` environment variable is set to point to the path of esp-idf top-level directory.
|
||||
Follow the setup instructions in the top-level esp-idf README. Make sure that ``IDF_PATH`` environment variable is set to point to the path of esp-idf top-level directory.
|
||||
|
||||
Change into ``tools/unit-test-app`` directory to configure and build it:
|
||||
|
||||
* ``idf.py menuconfig`` - configure unit test app.
|
||||
|
||||
* ``idf.py -T all build`` - build unit test app with tests for each component having tests in the ``test`` subdirectory.
|
||||
* ``idf.py -T "xxx yyy" build`` - build unit test app with tests for some space-separated specific components (For instance: ``idf.py -T heap build`` - build unit tests only for ``heap`` component directory).
|
||||
* ``idf.py -T all -E "xxx yyy" build`` - build unit test app with all unit tests, except for unit tests of some components (For instance: ``idf.py -T all -E "ulp mbedtls" build`` - build all unit tests exludes ``ulp`` and ``mbedtls`` components).
|
||||
@@ -248,8 +219,7 @@ Test cases can be run by inputting one of the following:
|
||||
|
||||
- An asterisk to run all test cases
|
||||
|
||||
``[multi_device]`` and ``[multi_stage]`` tags tell the test runner whether a test case is a multiple devices or multiple stages of test case.
|
||||
These tags are automatically added by ```TEST_CASE_MULTIPLE_STAGES`` and ``TEST_CASE_MULTIPLE_DEVICES`` macros.
|
||||
``[multi_device]`` and ``[multi_stage]`` tags tell the test runner whether a test case is a multiple devices or multiple stages of test case. These tags are automatically added by ```TEST_CASE_MULTIPLE_STAGES`` and ``TEST_CASE_MULTIPLE_DEVICES`` macros.
|
||||
|
||||
After you select a multi-device test case, it will print sub-menu::
|
||||
|
||||
@@ -267,10 +237,7 @@ Similar to multi-device test cases, multi-stage test cases will also print sub-m
|
||||
(1) "trigger_deepsleep"
|
||||
(2) "check_deepsleep_reset_reason"
|
||||
|
||||
|
||||
First time you execute this case, input ``1`` to run first stage (trigger deepsleep).
|
||||
After DUT is rebooted and able to run test cases, select this case again and input ``2`` to run the second stage.
|
||||
The case only passes if the last stage passes and all previous stages trigger reset.
|
||||
First time you execute this case, input ``1`` to run first stage (trigger deepsleep). After DUT is rebooted and able to run test cases, select this case again and input ``2`` to run the second stage. The case only passes if the last stage passes and all previous stages trigger reset.
|
||||
|
||||
|
||||
Timing Code with Cache Compensated Timer
|
||||
@@ -282,13 +249,9 @@ However, if the instruction or data is not in cache, it needs to be fetched from
|
||||
|
||||
Code and data placements can vary between builds, and some arrangements may be more favorable with regards to cache access (i.e., minimizing cache misses). This can technically affect execution speed, however these factors are usually irrelevant as their effect 'average out' over the device's operation.
|
||||
|
||||
The effect of the cache on execution speed, however, can be relevant in benchmarking scenarios (espcially microbenchmarks). There might be some variability in measured time
|
||||
between runs and between different builds. A technique for eliminating for some of the
|
||||
variability is to place code and data in instruction or data RAM (IRAM/DRAM), respectively. The CPU can access IRAM and DRAM directly, eliminating the cache out of the equation.
|
||||
However, this might not always be viable as the size of IRAM and DRAM is limited.
|
||||
The effect of the cache on execution speed, however, can be relevant in benchmarking scenarios (espcially microbenchmarks). There might be some variability in measured time between runs and between different builds. A technique for eliminating for some of the variability is to place code and data in instruction or data RAM (IRAM/DRAM), respectively. The CPU can access IRAM and DRAM directly, eliminating the cache out of the equation. However, this might not always be viable as the size of IRAM and DRAM is limited.
|
||||
|
||||
The cache compensated timer is an alternative to placing the code/data to be benchmarked in IRAM/DRAM. This timer uses the processor's internal event counters in order to determine the amount
|
||||
of time spent on waiting for code/data in case of a cache miss, then subtract that from the recorded wall time.
|
||||
The cache compensated timer is an alternative to placing the code/data to be benchmarked in IRAM/DRAM. This timer uses the processor's internal event counters in order to determine the amount of time spent on waiting for code/data in case of a cache miss, then subtract that from the recorded wall time.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -303,6 +266,4 @@ of time spent on waiting for code/data in case of a cache miss, then subtract th
|
||||
int64_t t = ccomp_timer_stop();
|
||||
|
||||
|
||||
One limitation of the cache compensated timer is that the task that benchmarked functions should be pinned to a core. This is due to each core having its own event counters that are independent of each other. For example, if ``ccomp_timer_start`` gets called on one core, put to sleep by the scheduler, wakes up, and gets rescheduled on the other core, then the corresponding ``ccomp_timer_stop`` will be invalid.
|
||||
invalid.
|
||||
|
||||
One limitation of the cache compensated timer is that the task that benchmarked functions should be pinned to a core. This is due to each core having its own event counters that are independent of each other. For example, if ``ccomp_timer_start`` gets called on one core, put to sleep by the scheduler, wakes up, and gets rescheduled on the other core, then the corresponding ``ccomp_timer_stop`` will be invalid.
|
||||
@@ -219,6 +219,35 @@ Linux and macOS
|
||||
cd ~/esp/esp-idf
|
||||
./install.sh
|
||||
|
||||
Alternative File Downloads
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The tools installer downloads a number of files attached to GitHub Releases. If accessing GitHub is slow then it is possible to set an environment variable to prefer Espressif's download server for GitHub asset downloads.
|
||||
|
||||
.. note:: This setting only controls individual tools downloaded from GitHub releases, it doesn't change the URLs used to access any Git repositories.
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
To prefer the Espressif download server when running the ESP-IDF Tools Installer or installing tools from the command line, open the System control panel, then click on Advanced Settings. Add a new Environment Variable (of type either User or System) with the name ``IDF_GITHUB_ASSETS`` and value ``dl.espressif.com/github_assets``. Click OK once done.
|
||||
|
||||
If the command line window or ESP-IDF Tools Installer window was already open before you added the new environment variable, you will need to close and reopen it.
|
||||
|
||||
While this environment variable is still set, the ESP-IDF Tools Installer and the command line installer will prefer the Espressif download server.
|
||||
|
||||
.. Once the ESP-IDF Tools Installer binary is updated to include the checkbox, the above can be rewritten to refer to it
|
||||
|
||||
Linux and macOS
|
||||
---------------
|
||||
|
||||
To prefer the Espressif download server when installing tools, use the following sequence of commands when running ``install.sh``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd ~/esp/esp-idf
|
||||
export IDF_GITHUB_ASSETS="dl.espressif.com/github_assets"
|
||||
./install.sh
|
||||
|
||||
Customizing the tools installation path
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -30,7 +30,15 @@ The easiest way to install ESP-IDF's prerequisites is to download the ESP-IDF To
|
||||
|
||||
https://dl.espressif.com/dl/esp-idf-tools-setup-2.3.exe
|
||||
|
||||
The installer includes the cross-compilers, OpenOCD, cmake_ and Ninja_ build tool. The installer can also download and run installers for Python_ 3.7 and `Git For Windows`_ if they are not already installed on the computer.
|
||||
.. IMPORTANT: Next time this link is updated, please go to get-started/index.rst and rewrite the section under "Alternative File Downloads ... Windows". Then delete this comment.
|
||||
|
||||
The installer includes the cross-compilers, OpenOCD, CMake_ and Ninja_ build tool. The installer can also download and run installers for Python_ 3.7 and `Git For Windows`_ if they are not already installed on the computer.
|
||||
|
||||
The installer also offers to download one of the ESP-IDF release versions. Please choose a directory for downloading ESP-IDF. The recommended directory is ``%userprofile%\esp`` where ``%userprofile%`` is your home directory. If you do not have it yet, please run the following command to create a new one:
|
||||
|
||||
.. code-block:: batch
|
||||
|
||||
mkdir %userprofile%\esp
|
||||
|
||||
The installer also offers to download one of the ESP-IDF release versions.
|
||||
|
||||
@@ -64,7 +72,7 @@ For advanced users who want to customize the install process:
|
||||
|
||||
|
||||
.. _MSYS2: https://www.msys2.org/
|
||||
.. _cmake: https://cmake.org/download/
|
||||
.. _CMake: https://cmake.org/download/
|
||||
.. _ninja: https://ninja-build.org/
|
||||
.. _Python: https://www.python.org/downloads/windows/
|
||||
.. _Git for Windows: https://gitforwindows.org/
|
||||
|
||||
@@ -8,7 +8,7 @@ This user guide provides information on the ESP-LyraT-8311A extension board.
|
||||
|
||||
This board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below.
|
||||
|
||||
Currently, ESP-LyraT-8311A v1.3 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2`.
|
||||
Currently, ESP-LyraT-8311A v1.2 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2`.
|
||||
|
||||
The ESP-LyraT-8311A extends the functionality of your main board by adding sound processing functionality:
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ The ESP32-S2-Kaluga-1 board has connectors for boards with:
|
||||
|
||||
- Extension header (ESP-LyraT-8311A, ESP-LyraP-LCD32)
|
||||
- Camera header (ESP-LyraP-CAM)
|
||||
- Touch FPC coneector (ESP-LyraP-TouchA)
|
||||
- Touch FPC connector (ESP-LyraP-TouchA)
|
||||
- LCD FPC connector (no official extension boards yet)
|
||||
- I2C FPC connector (no official extension boards yet)
|
||||
|
||||
@@ -316,7 +316,7 @@ If you want to use more than one extension board at the same time, please check
|
||||
- **Solution 1**: For ESP-LyraP-TouchA, do not initialize IO1 (VOL_UP), IO2 (PLAY), IO3 (VOL_DOWN), IO6 (PHOTO) and IO11 (NETWORK). **Solution 2**: It will allow you to initialize IO6 (PHOTO) properly, but will stop you from controlling the background brightness with software. On your ESP-LyraP-LCD32, remove R39, change R41 to 100 Ohm, switch BLCT_L to on.
|
||||
* - TouchA v1.1 + LCD32 v1.1 + 8311A v1.2
|
||||
- IO6, IO11
|
||||
- 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.
|
||||
- IO11 is multiplexed; IO6 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).
|
||||
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ If you want to use more than one extension board at the same time, please check
|
||||
- Utilize time division multiple access, or use a different audio module that can be connected via other GPIOs or DAC.
|
||||
* - TouchA v1.1 + LCD32 v1.2
|
||||
- IO11, IO6
|
||||
- Touch actions cannot be triggered because of the multiplexed pin IO11. ESP-LyraP-LCD32 will not be affected because its BLCT pin will be disconnected fron IO6.
|
||||
- Touch actions cannot be triggered because of the multiplexed pin IO11. ESP-LyraP-LCD32 will not be affected because its BLCT pin will be disconnected from IO6.
|
||||
- Do not initialize IO11 (NETWORK) for your ESP-LyraP-TouchA, or configure the BLCT pin to `-1` (= do not use BLCT) for your ESP-LyraP-LCD32.
|
||||
* - 8311A v1.3 + LCD32 v1.2
|
||||
- IO6
|
||||
|
||||
@@ -59,7 +59,7 @@ ESP32 配网流程
|
||||
node_height = 60;
|
||||
edge_length = 380;
|
||||
span_height = 10;
|
||||
default_fontsize = 12;
|
||||
default_fontsize = 12;
|
||||
|
||||
Phone <- ESP32 [label="广播"];
|
||||
Phone -> ESP32 [label="建立 GATT 链接"];
|
||||
@@ -139,17 +139,17 @@ Ack 帧格式(8 bit):
|
||||
| | | |
|
||||
+------------------+-----------------------+--------------------+
|
||||
| MSB - CheckSum | 2 |
|
||||
+------------------+--------------------------------------------+
|
||||
+------------------+--------------------------------------------+
|
||||
|
||||
1. Type
|
||||
|
||||
类型域,占 1 byte。分为 Type 和 Subtype(子类型域)两部分, Type 占低 2 bit,Subtype 占高 6 bit。
|
||||
|
||||
|
||||
* 控制帧,暂不进行加密,可校验;
|
||||
|
||||
|
||||
* 数据帧,可加密,可校验。
|
||||
|
||||
**1.1 控制帧 (0x0 b’00)**
|
||||
**1.1 控制帧 (0x0 b’00)**
|
||||
|
||||
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
|
||||
| 控制帧 (二进制) | 含义 | 解释 | 备注 |
|
||||
@@ -333,7 +333,7 @@ Ack 帧格式(8 bit):
|
||||
2. Frame Control
|
||||
|
||||
帧控制域,占 1 byte,每个 bit 表示不同含义。
|
||||
|
||||
|
||||
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 位 | 含义 |
|
||||
+================+===============================================================================================================================+
|
||||
@@ -376,11 +376,11 @@ Ack 帧格式(8 bit):
|
||||
3. Sequence Control
|
||||
|
||||
序列控制域。帧发送时,无论帧的类型是什么,序列 (Sequence) 都会自动加 1,用来防止重放攻击 (Replay Attack)。每次重现连接后,序列清零。
|
||||
|
||||
|
||||
4. Length
|
||||
|
||||
Data 域的长度,不包含 CheckSum。
|
||||
|
||||
|
||||
5. Data
|
||||
|
||||
不同的 Type 或 Subtype,Data 域的含义均不同。请参考上方表格。
|
||||
@@ -388,7 +388,7 @@ Ack 帧格式(8 bit):
|
||||
6. CheckSum
|
||||
|
||||
此域为 2 byte 的校验,用来校验『序列 + 数据长度 + 明文数据』。
|
||||
|
||||
|
||||
ESP32 端的安全实现
|
||||
------------------
|
||||
|
||||
@@ -415,29 +415,29 @@ ESP32 端的安全实现
|
||||
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
|
||||
|
||||
该函数用来接收协商期间的正常数据 (normal data),处理完成后,需要将待发送的数据使用 output_data 和 output_len 传出。
|
||||
|
||||
|
||||
BluFi 会在调用完 negotiate_data_handler 后,发送 negotiate_data_handler 传出的 output_data。
|
||||
|
||||
|
||||
这里的两个『*』,因为需要发出去的数据长度未知,所以需要函数自行分配 (malloc) 或者指向全局变量,通过 need_free 通知是否需要释放内存。
|
||||
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len);
|
||||
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
|
||||
加密和解密的数据长度必须一致。其中 iv8 为帧的 8 bit 序列 (sequence),可作为 iv 的某 8 bit 来使用。
|
||||
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
|
||||
加密和解密的数据长度必须一致。其中 iv8 为帧的 8 bit 序列 (sequence),可作为 iv 的某 8 bit 来使用。
|
||||
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len);
|
||||
|
||||
|
||||
该函数用来计算 CheckSum,返回值为 CheckSum 的值。BluFi 会使用该函数返回值与包末尾的 CheckSum 做比较。
|
||||
|
||||
|
||||
GATT 相关说明
|
||||
-------------
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@ API 指南
|
||||
:esp32: 单元测试 (传统 GNU Make) <unit-tests-legacy>
|
||||
应用层跟踪 <app_trace>
|
||||
ROM debug console <romconsole>
|
||||
:esp32: RF Calibration <RF_calibration>
|
||||
RF Calibration <RF_calibration>
|
||||
WiFi Driver <wifi>
|
||||
:SOC_BT_SUPPORTED: ESP-BLE-MESH <esp-ble-mesh/ble-mesh-index>
|
||||
ESP-MESH (Wi-Fi) <mesh>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user