From c4b3f6bbbc4b10d126ab3fa80a09899337f75597 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 10 Jan 2017 14:04:54 +1100 Subject: [PATCH 001/139] Update esptool.py to v2.0-beta1 Minor bug fixes, no major functionality changes. --- .gitmodules | 2 +- components/esptool_py/Makefile.projbuild | 2 +- components/esptool_py/esptool | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 9cba0ec5ef..6a6af0e9d5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = https://github.com/espressif/esp32-wifi-lib.git [submodule "components/esptool_py/esptool"] path = components/esptool_py/esptool - url = https://github.com/themadinventor/esptool.git + url = https://github.com/espressif/esptool.git [submodule "components/bt/lib"] path = components/bt/lib url = https://github.com/espressif/esp32-bt-lib.git diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index e249d14432..dfe8e1f428 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -29,7 +29,7 @@ endif ESPTOOL_ELF2IMAGE_OPTIONS := -ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_WRITE_FLASH_OPTIONS) +ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z,-u) $(ESPTOOL_WRITE_FLASH_OPTIONS) ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index fe69994270..e9e9179f6f 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit fe69994270e2a450aad3e94a409b58460b1a214f +Subproject commit e9e9179f6fc3f2ecfc568987d3224b5e53a05f06 From 3168ad10e79646e9d3422c36175aad5c6d60fff8 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Sun, 15 Jan 2017 11:11:58 +0800 Subject: [PATCH 002/139] Core timer 2 is unusable for FreeRTOS ticks because it triggers a high-level interrupt. This commit deletes the option to select it. --- components/esp32/intr_alloc.c | 8 +------- components/freertos/Kconfig | 5 ----- components/freertos/include/freertos/FreeRTOSConfig.h | 4 ---- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/components/esp32/intr_alloc.c b/components/esp32/intr_alloc.c index 1cb2fba5d9..bfd6c51206 100644 --- a/components/esp32/intr_alloc.c +++ b/components/esp32/intr_alloc.c @@ -89,12 +89,6 @@ typedef struct { #define INT15RES INTDESC_SPECIAL #endif -#if CONFIG_FREERTOS_CORETIMER_2 -#define INT16RES INTDESC_RESVD -#else -#define INT16RES INTDESC_SPECIAL -#endif - //This is basically a software-readable version of the interrupt usage table in include/soc/soc.h const static int_desc_t int_desc[32]={ { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //0 @@ -113,7 +107,7 @@ const static int_desc_t int_desc[32]={ { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //13 { 7, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //14, NMI { 3, INTTP_NA, {INT15RES, INT15RES } }, //15 - { 5, INTTP_NA, {INT16RES, INT16RES } }, //16 + { 5, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL} }, //16 { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //17 { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //18 { 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //19 diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 15178539b4..ee2b289ef8 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -30,11 +30,6 @@ config FREERTOS_CORETIMER_1 help Select this to use timer 1 -config FREERTOS_CORETIMER_2 - bool "Timer 2 (int 16, level 5)" - help - Select this to use timer 2 - endchoice config FREERTOS_HZ diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index b2fc077bc3..9deb9f4b5e 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -90,10 +90,6 @@ #define XT_TIMER_INDEX 0 #elif CONFIG_FREERTOS_CORETIMER_1 #define XT_TIMER_INDEX 1 -#elif CONFIG_FREERTOS_CORETIMER_2 -#define XT_TIMER_INDEX 2 -#elif CONFIG_FREERTOS_CORETIMER_3 -#define XT_TIMER_INDEX 3 #endif #define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS From cdf8836ceb1617e0f7674a608ffbbf23f43b9c94 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 16 Jan 2017 15:01:25 +1100 Subject: [PATCH 003/139] build: Use greedy match for toolchain version detection (fixes macOS) --- make/project.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/make/project.mk b/make/project.mk index c4c3022a6b..bebb1fc7d4 100644 --- a/make/project.mk +++ b/make/project.mk @@ -430,8 +430,8 @@ $(foreach submodule,$(subst $(IDF_PATH)/,,$(filter $(IDF_PATH)/%,$(COMPONENT_SUB # the part after the brackets is extracted into TOOLCHAIN_GCC_VER. ifdef CONFIG_TOOLPREFIX ifndef MAKE_RESTARTS -TOOLCHAIN_COMMIT_DESC := $(shell $(CC) --version | sed -E -n 's|xtensa-esp32-elf-gcc.*?\ \(([^)]*).*|\1|gp') -TOOLCHAIN_GCC_VER := $(shell $(CC) --version | sed -E -n 's|xtensa-esp32-elf-gcc.*?\ \(.*\)\ (.*)|\1|gp') +TOOLCHAIN_COMMIT_DESC := $(shell $(CC) --version | sed -E -n 's|xtensa-esp32-elf-gcc.*\ \(([^)]*).*|\1|gp') +TOOLCHAIN_GCC_VER := $(shell $(CC) --version | sed -E -n 's|xtensa-esp32-elf-gcc.*\ \(.*\)\ (.*)|\1|gp') # Officially supported version(s) SUPPORTED_TOOLCHAIN_COMMIT_DESC := crosstool-NG crosstool-ng-1.22.0-61-gab8375a From 53b0b03e6380d03f824e3d0be57f36fb7740bf2a Mon Sep 17 00:00:00 2001 From: shangke Date: Mon, 16 Jan 2017 17:06:12 +0800 Subject: [PATCH 004/139] esp_event: event stack overflow --- components/esp32/Kconfig | 2 +- components/ethernet/emac_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 0afe5ba0f8..8bbd6d032e 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -113,7 +113,7 @@ config SYSTEM_EVENT_QUEUE_SIZE config SYSTEM_EVENT_TASK_STACK_SIZE int "Event loop task stack size" - default 2048 + default 4096 help Config system event task stack size in different application. diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index 9446e8ee35..067d1a8ed7 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -588,7 +588,7 @@ esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size) if (emac_config.emac_status != EMAC_RUNTIME_START || emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) { ESP_LOGI(TAG, "tx netif close"); ret = ERR_IF; - goto _exit; + return ret; } xSemaphoreTakeRecursive( emac_tx_xMutex, ( TickType_t ) portMAX_DELAY ); From 3684e6ddfdc2e2d31b68e6081a298e3e3b387ab4 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Mon, 16 Jan 2017 17:20:05 +0800 Subject: [PATCH 005/139] update wifi lib: fix some wifi lib bugs 1. net80211: fix get ap info error(a4614877) 2. tw9358: sta mac same with softap(ea38d32c) 3. tw9221: scan channel error when connected(183d469c) --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index b26cd21764..49b6d079dd 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit b26cd217641acf08da932f4de8e858083ea83113 +Subproject commit 49b6d079ddd180518fc1dea7ef47af04e5f4a031 From 075446318df651216be42966e721c30d822b48e2 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 17 Jan 2017 00:42:55 +0800 Subject: [PATCH 006/139] spi_flash: define spi_flash_guard_{start,stop} with IRAM_ATTR These functions are marked as inline and are called from functions which are in IRAM. In release (-Os) builds, the compiler may decide not to inline these functions. Placing these functions into IRAM explicitly works around this. --- components/spi_flash/flash_ops.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index fffe487bd1..a74558a96f 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -103,16 +103,18 @@ SpiFlashOpResult IRAM_ATTR spi_flash_unlock() return SPI_FLASH_RESULT_OK; } -static inline void spi_flash_guard_start() +static inline void IRAM_ATTR spi_flash_guard_start() { - if (s_flash_guard_ops) + if (s_flash_guard_ops) { s_flash_guard_ops->start(); + } } -static inline void spi_flash_guard_end() +static inline void IRAM_ATTR spi_flash_guard_end() { - if (s_flash_guard_ops) + if (s_flash_guard_ops) { s_flash_guard_ops->end(); + } } esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec) From c47cc6348947cfd1aa6a8aa87e0764c1f07630c6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 17 Jan 2017 00:49:38 +0800 Subject: [PATCH 007/139] newlib: change definition of assert for release builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One common pattern of using assert function looks as follows: int ret = do_foo(); assert(ret == 0); // which reads as: “do_foo should never fail here, by design” The problem with such code is that if ‘assert’ is removed by the preprocessor in release build, variable ret is no longer used, and the compiler issues a warning about this. Changing assert definition in the way done here make the variable used, from language syntax perspective. Semantically, the variable is still unused at run time (as sizeof can be evaluated at compile time), so the compiler can optimize things away if possible. --- components/newlib/include/assert.h | 2 +- components/nvs_flash/src/nvs_pagemanager.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/newlib/include/assert.h b/components/newlib/include/assert.h index 91bb040cab..df46c030b2 100644 --- a/components/newlib/include/assert.h +++ b/components/newlib/include/assert.h @@ -11,7 +11,7 @@ extern "C" { #undef assert #ifdef NDEBUG /* required by ANSI standard */ -# define assert(__e) ((void)0) +# define assert(__e) ((void) sizeof(__e)) #else # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ __ASSERT_FUNC, #__e)) diff --git a/components/nvs_flash/src/nvs_pagemanager.cpp b/components/nvs_flash/src/nvs_pagemanager.cpp index f4d02a7d40..768b30667a 100644 --- a/components/nvs_flash/src/nvs_pagemanager.cpp +++ b/components/nvs_flash/src/nvs_pagemanager.cpp @@ -163,8 +163,10 @@ esp_err_t PageManager::requestNewPage() return err; } +#ifndef NDEBUG assert(usedEntries == newPage->getUsedEntryCount()); - +#endif + mPageList.erase(maxErasedItemsPageIt); mFreePageList.push_back(erasedPage); From 18963815019e68bd1a354f1ea18a302cc3ca217c Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 17 Jan 2017 01:17:20 +0800 Subject: [PATCH 008/139] readme: fix link formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64fe3ed365..59191bc7d9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![alt text](https://readthedocs.org/projects/docs/badge/?version=latest "Documentation Status")](http://esp-idf.readthedocs.io/en/latest/?badge=latest) -ESP-IDF is the official development framework for the `ESP32 `_ chip. +ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview>) chip. # Developing With the ESP-IDF From 1989917f7102f524f9ecdce1d675b21cf561617c Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 17 Jan 2017 01:18:23 +0800 Subject: [PATCH 009/139] docs: fix data RAM size Fixes https://github.com/espressif/esp-idf/issues/184 --- docs/general-notes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general-notes.rst b/docs/general-notes.rst index a683467007..6597337a1e 100644 --- a/docs/general-notes.rst +++ b/docs/general-notes.rst @@ -100,7 +100,7 @@ The code which has to run after wake-up from deep sleep mode has to be placed in DRAM (data RAM) ^^^^^^^^^^^^^^^ -Non-constant static data and zero-initialized data is placed by the linker into 200 kB ``0x3FFB0000 — 0x3FFF0000`` region. Note that this region is reduced by 64kB (by shifting start address to ``0x3FFC0000``) if Bluetooth stack is used. Length of this region is also reduced by 16 kB or 32kB if trace memory is used. All space which is left in this region after placing static data there is used for the runtime heap. +Non-constant static data and zero-initialized data is placed by the linker into the 256 kB ``0x3FFB0000 — 0x3FFF0000`` region. Note that this region is reduced by 64kB (by shifting start address to ``0x3FFC0000``) if Bluetooth stack is used. Length of this region is also reduced by 16 kB or 32kB if trace memory is used. All space which is left in this region after placing static data there is used for the runtime heap. Constant data may also be placed into DRAM, for example if it is used in an ISR handler (see notes in IRAM section above). To do that, ``DRAM_ATTR`` define can be used:: From 382999b378dfeb1dc224c74e8830e64fa1ed0d61 Mon Sep 17 00:00:00 2001 From: Krzysztof Budzynski Date: Mon, 16 Jan 2017 23:08:35 +0100 Subject: [PATCH 010/139] Moved examples to new folders / categories. Removed example numbers from example names --- examples/{05_ble_adv => bluetooth/ble_adv}/Makefile | 0 .../{05_ble_adv => bluetooth/ble_adv}/README.rst | 0 .../{05_ble_adv => bluetooth/ble_adv}/main/app_bt.c | 0 .../ble_adv}/main/component.mk | 0 .../ble_adv}/sdkconfig.defaults | 0 examples/{12_blufi => bluetooth/blufi}/Makefile | 0 examples/{12_blufi => bluetooth/blufi}/README.rst | 0 .../{12_blufi => bluetooth/blufi}/main/blufi_demo.h | 0 .../{12_blufi => bluetooth/blufi}/main/blufi_main.c | 0 .../blufi}/main/blufi_security.c | 0 .../{12_blufi => bluetooth/blufi}/main/component.mk | 0 .../blufi}/sdkconfig.defaults | 0 .../gatt_client}/Makefile | 0 .../gatt_client}/README.rst | 0 .../gatt_client}/main/component.mk | 0 .../gatt_client}/main/gattc_demo.c | 0 .../gatt_client}/sdkconfig.defaults | 0 .../gatt_server}/Makefile | 0 .../gatt_server}/README.rst | 0 .../gatt_server}/main/component.mk | 0 .../gatt_server}/main/gatts_demo.c | 0 .../gatt_server}/sdkconfig.defaults | 0 .../gatt_server_service_table}/Makefile | 0 .../gatt_server_service_table}/README.rst | 0 .../gatt_server_service_table}/main/component.mk | 0 .../main/gatts_table_creat_demo.c | 0 .../main/gatts_table_creat_demo.h | 0 .../gatt_server_service_table}/sdkconfig.defaults | 0 .../{17_ethernet => ethernet/ethernet}/Makefile | 0 .../{17_ethernet => ethernet/ethernet}/README.md | 0 .../ethernet}/main/component.mk | 0 .../ethernet}/main/ethernet_main.c | 0 .../ethernet}/main/tlk110_phy.h | 0 examples/{02_blink => get-started/blink}/Makefile | 0 examples/{02_blink => get-started/blink}/README.md | 0 .../blink}/main/Kconfig.projbuild | 0 .../{02_blink => get-started/blink}/main/blink.c | 0 .../blink}/main/component.mk | 0 .../blink}/sdkconfig.defaults | 0 .../hello_world}/Makefile | 0 .../hello_world}/README.md | 0 .../hello_world}/main/component.mk | 0 .../hello_world}/main/hello_world_main.c | 0 examples/{21_gpio => peripherals/gpio}/Makefile | 0 examples/{21_gpio => peripherals/gpio}/README.md | 0 .../gpio}/main/component.mk | 0 .../{21_gpio => peripherals/gpio}/main/gpio_test.c | 0 examples/{18_i2c => peripherals/i2c}/Makefile | 0 examples/{18_i2c => peripherals/i2c}/README.md | 0 .../{16_pcnt => peripherals/i2c}/main/component.mk | 0 .../{18_i2c => peripherals/i2c}/main/i2c_test.c | 0 examples/{22_i2s => peripherals/i2s}/Makefile | 0 .../{22_i2s => peripherals/i2s}/main/app_main.c | 0 .../{22_i2s => peripherals/i2s}/main/component.mk | 0 examples/{29_ledc => peripherals/ledc}/Makefile | 0 examples/{29_ledc => peripherals/ledc}/README.md | 0 .../{18_i2c => peripherals/ledc}/main/component.mk | 0 .../{29_ledc => peripherals/ledc}/main/ledc_fade.c | 0 examples/{16_pcnt => peripherals/pcnt}/Makefile | 0 examples/{16_pcnt => peripherals/pcnt}/README.md | 0 .../{20_uart => peripherals/pcnt}/main/component.mk | 0 .../{16_pcnt => peripherals/pcnt}/main/pcnt_test.c | 0 .../rmt_nec_tx_rx}/Makefile | 0 .../rmt_nec_tx_rx}/README.md | 0 .../rmt_nec_tx_rx}/main/component.mk | 0 .../rmt_nec_tx_rx}/main/infrared_nec.c | 0 .../rmt_nec_tx_rx}/main/infrared_nec_main.c | 0 .../sigmadelta}/Makefile | 0 .../sigmadelta}/README.md | 0 .../sigmadelta}/main/component.mk | 0 .../sigmadelta}/main/sigmadelta_test.c | 0 .../spi_master}/Makefile | 0 .../spi_master}/main/component.mk | 0 .../spi_master}/main/spi_master.c | 0 .../timer_group}/Makefile | 0 .../timer_group}/README.md | 0 .../timer_group}/main/component.mk | 0 .../timer_group}/main/timer_group.c | 0 examples/{20_uart => peripherals/uart}/Makefile | 0 .../{21_gpio => peripherals/uart}/main/component.mk | 0 .../{20_uart => peripherals/uart}/main/uart_test.c | 0 .../coap_client}/Makefile | 0 .../coap_client}/main/Kconfig.projbuild | 0 .../coap_client}/main/coap_client.c | 0 .../coap_client}/main/component.mk | 0 .../coap_server}/Makefile | 0 .../coap_server}/main/Kconfig.projbuild | 0 .../coap_server}/main/coap_server.c | 0 .../coap_server}/main/component.mk | 0 .../http_request}/Makefile | 0 .../http_request}/README.md | 0 .../http_request}/main/Kconfig.projbuild | 0 .../http_request}/main/component.mk | 0 .../http_request}/main/http_request_main.c | 0 .../https_request}/Makefile | 0 .../https_request}/README.md | 0 .../https_request}/main/Kconfig.projbuild | 0 .../https_request}/main/component.mk | 0 .../https_request}/main/https_request_main.c | 0 .../https_request}/main/server_root_cert.pem | 0 .../{30_mdns_example => protocols/mdns}/Makefile | 0 .../{30_mdns_example => protocols/mdns}/README.md | 0 .../mdns}/main/Kconfig.projbuild | 0 .../mdns}/main/component.mk | 0 .../mdns}/main/mdns_example_main.c | 0 .../openssl_client}/Makefile | 0 .../openssl_client}/README.md | 0 .../openssl_client}/main/Kconfig.projbuild | 0 .../openssl_client}/main/component.mk | 0 .../openssl_client}/main/openssl_client.c | 0 .../openssl_client}/main/openssl_client.h | 0 .../openssl_server}/Makefile | 0 .../openssl_server}/README.md | 0 .../openssl_server}/main/Kconfig.projbuild | 0 .../openssl_server}/main/cacert.pem | 0 .../openssl_server}/main/component.mk | 0 .../openssl_server}/main/openssl_server.c | 0 .../openssl_server}/main/openssl_server.h | 0 .../openssl_server}/main/prvtkey.pem | 0 examples/{06_sntp => protocols/sntp}/Makefile | 0 examples/{06_sntp => protocols/sntp}/README.md | 0 .../sntp}/main/Kconfig.projbuild | 0 .../{25_ota => protocols/sntp}/main/component.mk | 0 .../{06_sntp => protocols/sntp}/main/sntp_main.c | 0 .../nvs_rw_blob}/Makefile | 0 .../nvs_rw_blob}/README.md | 0 .../nvs_rw_blob}/main/component.mk | 0 .../nvs_rw_blob}/main/nvs_rw_blob.c | 0 .../nvs_rw_value}/Makefile | 0 .../nvs_rw_value}/README.md | 0 .../nvs_rw_value}/main/component.mk | 0 .../nvs_rw_value}/main/nvs_rw_value.c | 0 examples/{27_sd_card => storage/sd_card}/Makefile | 0 examples/{27_sd_card => storage/sd_card}/README.md | 0 .../sd_card}/main/component.mk | 0 .../{27_sd_card => storage/sd_card}/main/sd_card.c | 0 examples/{25_ota => system/ota}/Makefile | 0 examples/{25_ota => system/ota}/OTA_workflow.png | Bin examples/{25_ota => system/ota}/README.md | 0 .../{25_ota => system/ota}/main/Kconfig.projbuild | 0 .../ota}/main/component.mk | 0 examples/{25_ota => system/ota}/main/ota.c | 0 examples/{25_ota => system/ota}/sdkconfig.defaults | 0 .../wpa2_enterprise}/Makefile | 0 .../wpa2_enterprise}/README.md | 0 .../wpa2_enterprise}/main/Kconfig.projbuild | 0 .../wpa2_enterprise}/main/component.mk | 0 .../wpa2_enterprise}/main/wpa2_ca.pem | 0 .../wpa2_enterprise}/main/wpa2_client.crt | 0 .../wpa2_enterprise}/main/wpa2_client.key | 0 .../wpa2_enterprise}/main/wpa2_client.pem | 0 .../wpa2_enterprise}/main/wpa2_enterprise_main.c | 0 .../wpa2_enterprise}/main/wpa2_server.crt | 0 .../wpa2_enterprise}/main/wpa2_server.key | 0 .../wpa2_enterprise}/main/wpa2_server.pem | 0 155 files changed, 0 insertions(+), 0 deletions(-) rename examples/{05_ble_adv => bluetooth/ble_adv}/Makefile (100%) rename examples/{05_ble_adv => bluetooth/ble_adv}/README.rst (100%) rename examples/{05_ble_adv => bluetooth/ble_adv}/main/app_bt.c (100%) rename examples/{02_blink => bluetooth/ble_adv}/main/component.mk (100%) rename examples/{05_ble_adv => bluetooth/ble_adv}/sdkconfig.defaults (100%) rename examples/{12_blufi => bluetooth/blufi}/Makefile (100%) rename examples/{12_blufi => bluetooth/blufi}/README.rst (100%) rename examples/{12_blufi => bluetooth/blufi}/main/blufi_demo.h (100%) rename examples/{12_blufi => bluetooth/blufi}/main/blufi_main.c (100%) rename examples/{12_blufi => bluetooth/blufi}/main/blufi_security.c (100%) rename examples/{12_blufi => bluetooth/blufi}/main/component.mk (100%) rename examples/{12_blufi => bluetooth/blufi}/sdkconfig.defaults (100%) rename examples/{15_gatt_client => bluetooth/gatt_client}/Makefile (100%) rename examples/{15_gatt_client => bluetooth/gatt_client}/README.rst (100%) rename examples/{15_gatt_client => bluetooth/gatt_client}/main/component.mk (100%) rename examples/{15_gatt_client => bluetooth/gatt_client}/main/gattc_demo.c (100%) rename examples/{14_gatt_server => bluetooth/gatt_client}/sdkconfig.defaults (100%) rename examples/{14_gatt_server => bluetooth/gatt_server}/Makefile (100%) rename examples/{14_gatt_server => bluetooth/gatt_server}/README.rst (100%) rename examples/{14_gatt_server => bluetooth/gatt_server}/main/component.mk (100%) rename examples/{14_gatt_server => bluetooth/gatt_server}/main/gatts_demo.c (100%) rename examples/{15_gatt_client => bluetooth/gatt_server}/sdkconfig.defaults (100%) rename examples/{33_gatt_server_service_table => bluetooth/gatt_server_service_table}/Makefile (100%) rename examples/{33_gatt_server_service_table => bluetooth/gatt_server_service_table}/README.rst (100%) rename examples/{33_gatt_server_service_table => bluetooth/gatt_server_service_table}/main/component.mk (100%) rename examples/{33_gatt_server_service_table => bluetooth/gatt_server_service_table}/main/gatts_table_creat_demo.c (100%) rename examples/{33_gatt_server_service_table => bluetooth/gatt_server_service_table}/main/gatts_table_creat_demo.h (100%) rename examples/{33_gatt_server_service_table => bluetooth/gatt_server_service_table}/sdkconfig.defaults (100%) rename examples/{17_ethernet => ethernet/ethernet}/Makefile (100%) rename examples/{17_ethernet => ethernet/ethernet}/README.md (100%) rename examples/{03_http_request => ethernet/ethernet}/main/component.mk (100%) rename examples/{17_ethernet => ethernet/ethernet}/main/ethernet_main.c (100%) rename examples/{17_ethernet => ethernet/ethernet}/main/tlk110_phy.h (100%) rename examples/{02_blink => get-started/blink}/Makefile (100%) rename examples/{02_blink => get-started/blink}/README.md (100%) rename examples/{02_blink => get-started/blink}/main/Kconfig.projbuild (100%) rename examples/{02_blink => get-started/blink}/main/blink.c (100%) rename examples/{05_ble_adv => get-started/blink}/main/component.mk (100%) rename examples/{02_blink => get-started/blink}/sdkconfig.defaults (100%) rename examples/{01_hello_world => get-started/hello_world}/Makefile (100%) rename examples/{01_hello_world => get-started/hello_world}/README.md (100%) rename examples/{01_hello_world => get-started/hello_world}/main/component.mk (100%) rename examples/{01_hello_world => get-started/hello_world}/main/hello_world_main.c (100%) rename examples/{21_gpio => peripherals/gpio}/Makefile (100%) rename examples/{21_gpio => peripherals/gpio}/README.md (100%) rename examples/{09_openssl_client => peripherals/gpio}/main/component.mk (100%) rename examples/{21_gpio => peripherals/gpio}/main/gpio_test.c (100%) rename examples/{18_i2c => peripherals/i2c}/Makefile (100%) rename examples/{18_i2c => peripherals/i2c}/README.md (100%) rename examples/{16_pcnt => peripherals/i2c}/main/component.mk (100%) rename examples/{18_i2c => peripherals/i2c}/main/i2c_test.c (100%) rename examples/{22_i2s => peripherals/i2s}/Makefile (100%) rename examples/{22_i2s => peripherals/i2s}/main/app_main.c (100%) rename examples/{22_i2s => peripherals/i2s}/main/component.mk (100%) rename examples/{29_ledc => peripherals/ledc}/Makefile (100%) rename examples/{29_ledc => peripherals/ledc}/README.md (100%) rename examples/{18_i2c => peripherals/ledc}/main/component.mk (100%) rename examples/{29_ledc => peripherals/ledc}/main/ledc_fade.c (100%) rename examples/{16_pcnt => peripherals/pcnt}/Makefile (100%) rename examples/{16_pcnt => peripherals/pcnt}/README.md (100%) rename examples/{20_uart => peripherals/pcnt}/main/component.mk (100%) rename examples/{16_pcnt => peripherals/pcnt}/main/pcnt_test.c (100%) rename examples/{11_rmt_nec_tx_rx => peripherals/rmt_nec_tx_rx}/Makefile (100%) rename examples/{11_rmt_nec_tx_rx => peripherals/rmt_nec_tx_rx}/README.md (100%) rename examples/{11_rmt_nec_tx_rx => peripherals/rmt_nec_tx_rx}/main/component.mk (100%) rename examples/{11_rmt_nec_tx_rx => peripherals/rmt_nec_tx_rx}/main/infrared_nec.c (100%) rename examples/{11_rmt_nec_tx_rx => peripherals/rmt_nec_tx_rx}/main/infrared_nec_main.c (100%) rename examples/{19_sigmadelta => peripherals/sigmadelta}/Makefile (100%) rename examples/{19_sigmadelta => peripherals/sigmadelta}/README.md (100%) rename examples/{19_sigmadelta => peripherals/sigmadelta}/main/component.mk (100%) rename examples/{19_sigmadelta => peripherals/sigmadelta}/main/sigmadelta_test.c (100%) rename examples/{26_spi_master => peripherals/spi_master}/Makefile (100%) rename examples/{26_spi_master => peripherals/spi_master}/main/component.mk (100%) rename examples/{26_spi_master => peripherals/spi_master}/main/spi_master.c (100%) rename examples/{13_timer_group => peripherals/timer_group}/Makefile (100%) rename examples/{13_timer_group => peripherals/timer_group}/README.md (100%) rename examples/{07_nvs_rw_value => peripherals/timer_group}/main/component.mk (100%) rename examples/{13_timer_group => peripherals/timer_group}/main/timer_group.c (100%) rename examples/{20_uart => peripherals/uart}/Makefile (100%) rename examples/{21_gpio => peripherals/uart}/main/component.mk (100%) rename examples/{20_uart => peripherals/uart}/main/uart_test.c (100%) rename examples/{23_coap_client => protocols/coap_client}/Makefile (100%) rename examples/{23_coap_client => protocols/coap_client}/main/Kconfig.projbuild (100%) rename examples/{23_coap_client => protocols/coap_client}/main/coap_client.c (100%) rename examples/{08_nvs_rw_blob => protocols/coap_client}/main/component.mk (100%) rename examples/{24_coap_server => protocols/coap_server}/Makefile (100%) rename examples/{24_coap_server => protocols/coap_server}/main/Kconfig.projbuild (100%) rename examples/{24_coap_server => protocols/coap_server}/main/coap_server.c (100%) rename examples/{13_timer_group => protocols/coap_server}/main/component.mk (100%) rename examples/{03_http_request => protocols/http_request}/Makefile (100%) rename examples/{03_http_request => protocols/http_request}/README.md (100%) rename examples/{03_http_request => protocols/http_request}/main/Kconfig.projbuild (100%) rename examples/{06_sntp => protocols/http_request}/main/component.mk (100%) rename examples/{03_http_request => protocols/http_request}/main/http_request_main.c (100%) rename examples/{04_https_request => protocols/https_request}/Makefile (100%) rename examples/{04_https_request => protocols/https_request}/README.md (100%) rename examples/{04_https_request => protocols/https_request}/main/Kconfig.projbuild (100%) rename examples/{04_https_request => protocols/https_request}/main/component.mk (100%) rename examples/{04_https_request => protocols/https_request}/main/https_request_main.c (100%) rename examples/{04_https_request => protocols/https_request}/main/server_root_cert.pem (100%) rename examples/{30_mdns_example => protocols/mdns}/Makefile (100%) rename examples/{30_mdns_example => protocols/mdns}/README.md (100%) rename examples/{30_mdns_example => protocols/mdns}/main/Kconfig.projbuild (100%) rename examples/{17_ethernet => protocols/mdns}/main/component.mk (100%) rename examples/{30_mdns_example => protocols/mdns}/main/mdns_example_main.c (100%) rename examples/{09_openssl_client => protocols/openssl_client}/Makefile (100%) rename examples/{09_openssl_client => protocols/openssl_client}/README.md (100%) rename examples/{09_openssl_client => protocols/openssl_client}/main/Kconfig.projbuild (100%) rename examples/{29_ledc => protocols/openssl_client}/main/component.mk (100%) rename examples/{09_openssl_client => protocols/openssl_client}/main/openssl_client.c (100%) rename examples/{09_openssl_client => protocols/openssl_client}/main/openssl_client.h (100%) rename examples/{10_openssl_server => protocols/openssl_server}/Makefile (100%) rename examples/{10_openssl_server => protocols/openssl_server}/README.md (100%) rename examples/{10_openssl_server => protocols/openssl_server}/main/Kconfig.projbuild (100%) rename examples/{10_openssl_server => protocols/openssl_server}/main/cacert.pem (100%) rename examples/{10_openssl_server => protocols/openssl_server}/main/component.mk (100%) rename examples/{10_openssl_server => protocols/openssl_server}/main/openssl_server.c (100%) rename examples/{10_openssl_server => protocols/openssl_server}/main/openssl_server.h (100%) rename examples/{10_openssl_server => protocols/openssl_server}/main/prvtkey.pem (100%) rename examples/{06_sntp => protocols/sntp}/Makefile (100%) rename examples/{06_sntp => protocols/sntp}/README.md (100%) rename examples/{06_sntp => protocols/sntp}/main/Kconfig.projbuild (100%) rename examples/{25_ota => protocols/sntp}/main/component.mk (100%) rename examples/{06_sntp => protocols/sntp}/main/sntp_main.c (100%) rename examples/{08_nvs_rw_blob => storage/nvs_rw_blob}/Makefile (100%) rename examples/{08_nvs_rw_blob => storage/nvs_rw_blob}/README.md (100%) rename examples/{23_coap_client => storage/nvs_rw_blob}/main/component.mk (100%) rename examples/{08_nvs_rw_blob => storage/nvs_rw_blob}/main/nvs_rw_blob.c (100%) rename examples/{07_nvs_rw_value => storage/nvs_rw_value}/Makefile (100%) rename examples/{07_nvs_rw_value => storage/nvs_rw_value}/README.md (100%) rename examples/{24_coap_server => storage/nvs_rw_value}/main/component.mk (100%) rename examples/{07_nvs_rw_value => storage/nvs_rw_value}/main/nvs_rw_value.c (100%) rename examples/{27_sd_card => storage/sd_card}/Makefile (100%) rename examples/{27_sd_card => storage/sd_card}/README.md (100%) rename examples/{27_sd_card => storage/sd_card}/main/component.mk (100%) rename examples/{27_sd_card => storage/sd_card}/main/sd_card.c (100%) rename examples/{25_ota => system/ota}/Makefile (100%) rename examples/{25_ota => system/ota}/OTA_workflow.png (100%) rename examples/{25_ota => system/ota}/README.md (100%) rename examples/{25_ota => system/ota}/main/Kconfig.projbuild (100%) rename examples/{30_mdns_example => system/ota}/main/component.mk (100%) rename examples/{25_ota => system/ota}/main/ota.c (100%) rename examples/{25_ota => system/ota}/sdkconfig.defaults (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/Makefile (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/README.md (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/Kconfig.projbuild (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/component.mk (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_ca.pem (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_client.crt (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_client.key (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_client.pem (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_enterprise_main.c (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_server.crt (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_server.key (100%) rename examples/{31_wpa2_enterprise => wifi/wpa2_enterprise}/main/wpa2_server.pem (100%) diff --git a/examples/05_ble_adv/Makefile b/examples/bluetooth/ble_adv/Makefile similarity index 100% rename from examples/05_ble_adv/Makefile rename to examples/bluetooth/ble_adv/Makefile diff --git a/examples/05_ble_adv/README.rst b/examples/bluetooth/ble_adv/README.rst similarity index 100% rename from examples/05_ble_adv/README.rst rename to examples/bluetooth/ble_adv/README.rst diff --git a/examples/05_ble_adv/main/app_bt.c b/examples/bluetooth/ble_adv/main/app_bt.c similarity index 100% rename from examples/05_ble_adv/main/app_bt.c rename to examples/bluetooth/ble_adv/main/app_bt.c diff --git a/examples/02_blink/main/component.mk b/examples/bluetooth/ble_adv/main/component.mk similarity index 100% rename from examples/02_blink/main/component.mk rename to examples/bluetooth/ble_adv/main/component.mk diff --git a/examples/05_ble_adv/sdkconfig.defaults b/examples/bluetooth/ble_adv/sdkconfig.defaults similarity index 100% rename from examples/05_ble_adv/sdkconfig.defaults rename to examples/bluetooth/ble_adv/sdkconfig.defaults diff --git a/examples/12_blufi/Makefile b/examples/bluetooth/blufi/Makefile similarity index 100% rename from examples/12_blufi/Makefile rename to examples/bluetooth/blufi/Makefile diff --git a/examples/12_blufi/README.rst b/examples/bluetooth/blufi/README.rst similarity index 100% rename from examples/12_blufi/README.rst rename to examples/bluetooth/blufi/README.rst diff --git a/examples/12_blufi/main/blufi_demo.h b/examples/bluetooth/blufi/main/blufi_demo.h similarity index 100% rename from examples/12_blufi/main/blufi_demo.h rename to examples/bluetooth/blufi/main/blufi_demo.h diff --git a/examples/12_blufi/main/blufi_main.c b/examples/bluetooth/blufi/main/blufi_main.c similarity index 100% rename from examples/12_blufi/main/blufi_main.c rename to examples/bluetooth/blufi/main/blufi_main.c diff --git a/examples/12_blufi/main/blufi_security.c b/examples/bluetooth/blufi/main/blufi_security.c similarity index 100% rename from examples/12_blufi/main/blufi_security.c rename to examples/bluetooth/blufi/main/blufi_security.c diff --git a/examples/12_blufi/main/component.mk b/examples/bluetooth/blufi/main/component.mk similarity index 100% rename from examples/12_blufi/main/component.mk rename to examples/bluetooth/blufi/main/component.mk diff --git a/examples/12_blufi/sdkconfig.defaults b/examples/bluetooth/blufi/sdkconfig.defaults similarity index 100% rename from examples/12_blufi/sdkconfig.defaults rename to examples/bluetooth/blufi/sdkconfig.defaults diff --git a/examples/15_gatt_client/Makefile b/examples/bluetooth/gatt_client/Makefile similarity index 100% rename from examples/15_gatt_client/Makefile rename to examples/bluetooth/gatt_client/Makefile diff --git a/examples/15_gatt_client/README.rst b/examples/bluetooth/gatt_client/README.rst similarity index 100% rename from examples/15_gatt_client/README.rst rename to examples/bluetooth/gatt_client/README.rst diff --git a/examples/15_gatt_client/main/component.mk b/examples/bluetooth/gatt_client/main/component.mk similarity index 100% rename from examples/15_gatt_client/main/component.mk rename to examples/bluetooth/gatt_client/main/component.mk diff --git a/examples/15_gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c similarity index 100% rename from examples/15_gatt_client/main/gattc_demo.c rename to examples/bluetooth/gatt_client/main/gattc_demo.c diff --git a/examples/14_gatt_server/sdkconfig.defaults b/examples/bluetooth/gatt_client/sdkconfig.defaults similarity index 100% rename from examples/14_gatt_server/sdkconfig.defaults rename to examples/bluetooth/gatt_client/sdkconfig.defaults diff --git a/examples/14_gatt_server/Makefile b/examples/bluetooth/gatt_server/Makefile similarity index 100% rename from examples/14_gatt_server/Makefile rename to examples/bluetooth/gatt_server/Makefile diff --git a/examples/14_gatt_server/README.rst b/examples/bluetooth/gatt_server/README.rst similarity index 100% rename from examples/14_gatt_server/README.rst rename to examples/bluetooth/gatt_server/README.rst diff --git a/examples/14_gatt_server/main/component.mk b/examples/bluetooth/gatt_server/main/component.mk similarity index 100% rename from examples/14_gatt_server/main/component.mk rename to examples/bluetooth/gatt_server/main/component.mk diff --git a/examples/14_gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c similarity index 100% rename from examples/14_gatt_server/main/gatts_demo.c rename to examples/bluetooth/gatt_server/main/gatts_demo.c diff --git a/examples/15_gatt_client/sdkconfig.defaults b/examples/bluetooth/gatt_server/sdkconfig.defaults similarity index 100% rename from examples/15_gatt_client/sdkconfig.defaults rename to examples/bluetooth/gatt_server/sdkconfig.defaults diff --git a/examples/33_gatt_server_service_table/Makefile b/examples/bluetooth/gatt_server_service_table/Makefile similarity index 100% rename from examples/33_gatt_server_service_table/Makefile rename to examples/bluetooth/gatt_server_service_table/Makefile diff --git a/examples/33_gatt_server_service_table/README.rst b/examples/bluetooth/gatt_server_service_table/README.rst similarity index 100% rename from examples/33_gatt_server_service_table/README.rst rename to examples/bluetooth/gatt_server_service_table/README.rst diff --git a/examples/33_gatt_server_service_table/main/component.mk b/examples/bluetooth/gatt_server_service_table/main/component.mk similarity index 100% rename from examples/33_gatt_server_service_table/main/component.mk rename to examples/bluetooth/gatt_server_service_table/main/component.mk diff --git a/examples/33_gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c similarity index 100% rename from examples/33_gatt_server_service_table/main/gatts_table_creat_demo.c rename to examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c diff --git a/examples/33_gatt_server_service_table/main/gatts_table_creat_demo.h b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.h similarity index 100% rename from examples/33_gatt_server_service_table/main/gatts_table_creat_demo.h rename to examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.h diff --git a/examples/33_gatt_server_service_table/sdkconfig.defaults b/examples/bluetooth/gatt_server_service_table/sdkconfig.defaults similarity index 100% rename from examples/33_gatt_server_service_table/sdkconfig.defaults rename to examples/bluetooth/gatt_server_service_table/sdkconfig.defaults diff --git a/examples/17_ethernet/Makefile b/examples/ethernet/ethernet/Makefile similarity index 100% rename from examples/17_ethernet/Makefile rename to examples/ethernet/ethernet/Makefile diff --git a/examples/17_ethernet/README.md b/examples/ethernet/ethernet/README.md similarity index 100% rename from examples/17_ethernet/README.md rename to examples/ethernet/ethernet/README.md diff --git a/examples/03_http_request/main/component.mk b/examples/ethernet/ethernet/main/component.mk similarity index 100% rename from examples/03_http_request/main/component.mk rename to examples/ethernet/ethernet/main/component.mk diff --git a/examples/17_ethernet/main/ethernet_main.c b/examples/ethernet/ethernet/main/ethernet_main.c similarity index 100% rename from examples/17_ethernet/main/ethernet_main.c rename to examples/ethernet/ethernet/main/ethernet_main.c diff --git a/examples/17_ethernet/main/tlk110_phy.h b/examples/ethernet/ethernet/main/tlk110_phy.h similarity index 100% rename from examples/17_ethernet/main/tlk110_phy.h rename to examples/ethernet/ethernet/main/tlk110_phy.h diff --git a/examples/02_blink/Makefile b/examples/get-started/blink/Makefile similarity index 100% rename from examples/02_blink/Makefile rename to examples/get-started/blink/Makefile diff --git a/examples/02_blink/README.md b/examples/get-started/blink/README.md similarity index 100% rename from examples/02_blink/README.md rename to examples/get-started/blink/README.md diff --git a/examples/02_blink/main/Kconfig.projbuild b/examples/get-started/blink/main/Kconfig.projbuild similarity index 100% rename from examples/02_blink/main/Kconfig.projbuild rename to examples/get-started/blink/main/Kconfig.projbuild diff --git a/examples/02_blink/main/blink.c b/examples/get-started/blink/main/blink.c similarity index 100% rename from examples/02_blink/main/blink.c rename to examples/get-started/blink/main/blink.c diff --git a/examples/05_ble_adv/main/component.mk b/examples/get-started/blink/main/component.mk similarity index 100% rename from examples/05_ble_adv/main/component.mk rename to examples/get-started/blink/main/component.mk diff --git a/examples/02_blink/sdkconfig.defaults b/examples/get-started/blink/sdkconfig.defaults similarity index 100% rename from examples/02_blink/sdkconfig.defaults rename to examples/get-started/blink/sdkconfig.defaults diff --git a/examples/01_hello_world/Makefile b/examples/get-started/hello_world/Makefile similarity index 100% rename from examples/01_hello_world/Makefile rename to examples/get-started/hello_world/Makefile diff --git a/examples/01_hello_world/README.md b/examples/get-started/hello_world/README.md similarity index 100% rename from examples/01_hello_world/README.md rename to examples/get-started/hello_world/README.md diff --git a/examples/01_hello_world/main/component.mk b/examples/get-started/hello_world/main/component.mk similarity index 100% rename from examples/01_hello_world/main/component.mk rename to examples/get-started/hello_world/main/component.mk diff --git a/examples/01_hello_world/main/hello_world_main.c b/examples/get-started/hello_world/main/hello_world_main.c similarity index 100% rename from examples/01_hello_world/main/hello_world_main.c rename to examples/get-started/hello_world/main/hello_world_main.c diff --git a/examples/21_gpio/Makefile b/examples/peripherals/gpio/Makefile similarity index 100% rename from examples/21_gpio/Makefile rename to examples/peripherals/gpio/Makefile diff --git a/examples/21_gpio/README.md b/examples/peripherals/gpio/README.md similarity index 100% rename from examples/21_gpio/README.md rename to examples/peripherals/gpio/README.md diff --git a/examples/09_openssl_client/main/component.mk b/examples/peripherals/gpio/main/component.mk similarity index 100% rename from examples/09_openssl_client/main/component.mk rename to examples/peripherals/gpio/main/component.mk diff --git a/examples/21_gpio/main/gpio_test.c b/examples/peripherals/gpio/main/gpio_test.c similarity index 100% rename from examples/21_gpio/main/gpio_test.c rename to examples/peripherals/gpio/main/gpio_test.c diff --git a/examples/18_i2c/Makefile b/examples/peripherals/i2c/Makefile similarity index 100% rename from examples/18_i2c/Makefile rename to examples/peripherals/i2c/Makefile diff --git a/examples/18_i2c/README.md b/examples/peripherals/i2c/README.md similarity index 100% rename from examples/18_i2c/README.md rename to examples/peripherals/i2c/README.md diff --git a/examples/16_pcnt/main/component.mk b/examples/peripherals/i2c/main/component.mk similarity index 100% rename from examples/16_pcnt/main/component.mk rename to examples/peripherals/i2c/main/component.mk diff --git a/examples/18_i2c/main/i2c_test.c b/examples/peripherals/i2c/main/i2c_test.c similarity index 100% rename from examples/18_i2c/main/i2c_test.c rename to examples/peripherals/i2c/main/i2c_test.c diff --git a/examples/22_i2s/Makefile b/examples/peripherals/i2s/Makefile similarity index 100% rename from examples/22_i2s/Makefile rename to examples/peripherals/i2s/Makefile diff --git a/examples/22_i2s/main/app_main.c b/examples/peripherals/i2s/main/app_main.c similarity index 100% rename from examples/22_i2s/main/app_main.c rename to examples/peripherals/i2s/main/app_main.c diff --git a/examples/22_i2s/main/component.mk b/examples/peripherals/i2s/main/component.mk similarity index 100% rename from examples/22_i2s/main/component.mk rename to examples/peripherals/i2s/main/component.mk diff --git a/examples/29_ledc/Makefile b/examples/peripherals/ledc/Makefile similarity index 100% rename from examples/29_ledc/Makefile rename to examples/peripherals/ledc/Makefile diff --git a/examples/29_ledc/README.md b/examples/peripherals/ledc/README.md similarity index 100% rename from examples/29_ledc/README.md rename to examples/peripherals/ledc/README.md diff --git a/examples/18_i2c/main/component.mk b/examples/peripherals/ledc/main/component.mk similarity index 100% rename from examples/18_i2c/main/component.mk rename to examples/peripherals/ledc/main/component.mk diff --git a/examples/29_ledc/main/ledc_fade.c b/examples/peripherals/ledc/main/ledc_fade.c similarity index 100% rename from examples/29_ledc/main/ledc_fade.c rename to examples/peripherals/ledc/main/ledc_fade.c diff --git a/examples/16_pcnt/Makefile b/examples/peripherals/pcnt/Makefile similarity index 100% rename from examples/16_pcnt/Makefile rename to examples/peripherals/pcnt/Makefile diff --git a/examples/16_pcnt/README.md b/examples/peripherals/pcnt/README.md similarity index 100% rename from examples/16_pcnt/README.md rename to examples/peripherals/pcnt/README.md diff --git a/examples/20_uart/main/component.mk b/examples/peripherals/pcnt/main/component.mk similarity index 100% rename from examples/20_uart/main/component.mk rename to examples/peripherals/pcnt/main/component.mk diff --git a/examples/16_pcnt/main/pcnt_test.c b/examples/peripherals/pcnt/main/pcnt_test.c similarity index 100% rename from examples/16_pcnt/main/pcnt_test.c rename to examples/peripherals/pcnt/main/pcnt_test.c diff --git a/examples/11_rmt_nec_tx_rx/Makefile b/examples/peripherals/rmt_nec_tx_rx/Makefile similarity index 100% rename from examples/11_rmt_nec_tx_rx/Makefile rename to examples/peripherals/rmt_nec_tx_rx/Makefile diff --git a/examples/11_rmt_nec_tx_rx/README.md b/examples/peripherals/rmt_nec_tx_rx/README.md similarity index 100% rename from examples/11_rmt_nec_tx_rx/README.md rename to examples/peripherals/rmt_nec_tx_rx/README.md diff --git a/examples/11_rmt_nec_tx_rx/main/component.mk b/examples/peripherals/rmt_nec_tx_rx/main/component.mk similarity index 100% rename from examples/11_rmt_nec_tx_rx/main/component.mk rename to examples/peripherals/rmt_nec_tx_rx/main/component.mk diff --git a/examples/11_rmt_nec_tx_rx/main/infrared_nec.c b/examples/peripherals/rmt_nec_tx_rx/main/infrared_nec.c similarity index 100% rename from examples/11_rmt_nec_tx_rx/main/infrared_nec.c rename to examples/peripherals/rmt_nec_tx_rx/main/infrared_nec.c diff --git a/examples/11_rmt_nec_tx_rx/main/infrared_nec_main.c b/examples/peripherals/rmt_nec_tx_rx/main/infrared_nec_main.c similarity index 100% rename from examples/11_rmt_nec_tx_rx/main/infrared_nec_main.c rename to examples/peripherals/rmt_nec_tx_rx/main/infrared_nec_main.c diff --git a/examples/19_sigmadelta/Makefile b/examples/peripherals/sigmadelta/Makefile similarity index 100% rename from examples/19_sigmadelta/Makefile rename to examples/peripherals/sigmadelta/Makefile diff --git a/examples/19_sigmadelta/README.md b/examples/peripherals/sigmadelta/README.md similarity index 100% rename from examples/19_sigmadelta/README.md rename to examples/peripherals/sigmadelta/README.md diff --git a/examples/19_sigmadelta/main/component.mk b/examples/peripherals/sigmadelta/main/component.mk similarity index 100% rename from examples/19_sigmadelta/main/component.mk rename to examples/peripherals/sigmadelta/main/component.mk diff --git a/examples/19_sigmadelta/main/sigmadelta_test.c b/examples/peripherals/sigmadelta/main/sigmadelta_test.c similarity index 100% rename from examples/19_sigmadelta/main/sigmadelta_test.c rename to examples/peripherals/sigmadelta/main/sigmadelta_test.c diff --git a/examples/26_spi_master/Makefile b/examples/peripherals/spi_master/Makefile similarity index 100% rename from examples/26_spi_master/Makefile rename to examples/peripherals/spi_master/Makefile diff --git a/examples/26_spi_master/main/component.mk b/examples/peripherals/spi_master/main/component.mk similarity index 100% rename from examples/26_spi_master/main/component.mk rename to examples/peripherals/spi_master/main/component.mk diff --git a/examples/26_spi_master/main/spi_master.c b/examples/peripherals/spi_master/main/spi_master.c similarity index 100% rename from examples/26_spi_master/main/spi_master.c rename to examples/peripherals/spi_master/main/spi_master.c diff --git a/examples/13_timer_group/Makefile b/examples/peripherals/timer_group/Makefile similarity index 100% rename from examples/13_timer_group/Makefile rename to examples/peripherals/timer_group/Makefile diff --git a/examples/13_timer_group/README.md b/examples/peripherals/timer_group/README.md similarity index 100% rename from examples/13_timer_group/README.md rename to examples/peripherals/timer_group/README.md diff --git a/examples/07_nvs_rw_value/main/component.mk b/examples/peripherals/timer_group/main/component.mk similarity index 100% rename from examples/07_nvs_rw_value/main/component.mk rename to examples/peripherals/timer_group/main/component.mk diff --git a/examples/13_timer_group/main/timer_group.c b/examples/peripherals/timer_group/main/timer_group.c similarity index 100% rename from examples/13_timer_group/main/timer_group.c rename to examples/peripherals/timer_group/main/timer_group.c diff --git a/examples/20_uart/Makefile b/examples/peripherals/uart/Makefile similarity index 100% rename from examples/20_uart/Makefile rename to examples/peripherals/uart/Makefile diff --git a/examples/21_gpio/main/component.mk b/examples/peripherals/uart/main/component.mk similarity index 100% rename from examples/21_gpio/main/component.mk rename to examples/peripherals/uart/main/component.mk diff --git a/examples/20_uart/main/uart_test.c b/examples/peripherals/uart/main/uart_test.c similarity index 100% rename from examples/20_uart/main/uart_test.c rename to examples/peripherals/uart/main/uart_test.c diff --git a/examples/23_coap_client/Makefile b/examples/protocols/coap_client/Makefile similarity index 100% rename from examples/23_coap_client/Makefile rename to examples/protocols/coap_client/Makefile diff --git a/examples/23_coap_client/main/Kconfig.projbuild b/examples/protocols/coap_client/main/Kconfig.projbuild similarity index 100% rename from examples/23_coap_client/main/Kconfig.projbuild rename to examples/protocols/coap_client/main/Kconfig.projbuild diff --git a/examples/23_coap_client/main/coap_client.c b/examples/protocols/coap_client/main/coap_client.c similarity index 100% rename from examples/23_coap_client/main/coap_client.c rename to examples/protocols/coap_client/main/coap_client.c diff --git a/examples/08_nvs_rw_blob/main/component.mk b/examples/protocols/coap_client/main/component.mk similarity index 100% rename from examples/08_nvs_rw_blob/main/component.mk rename to examples/protocols/coap_client/main/component.mk diff --git a/examples/24_coap_server/Makefile b/examples/protocols/coap_server/Makefile similarity index 100% rename from examples/24_coap_server/Makefile rename to examples/protocols/coap_server/Makefile diff --git a/examples/24_coap_server/main/Kconfig.projbuild b/examples/protocols/coap_server/main/Kconfig.projbuild similarity index 100% rename from examples/24_coap_server/main/Kconfig.projbuild rename to examples/protocols/coap_server/main/Kconfig.projbuild diff --git a/examples/24_coap_server/main/coap_server.c b/examples/protocols/coap_server/main/coap_server.c similarity index 100% rename from examples/24_coap_server/main/coap_server.c rename to examples/protocols/coap_server/main/coap_server.c diff --git a/examples/13_timer_group/main/component.mk b/examples/protocols/coap_server/main/component.mk similarity index 100% rename from examples/13_timer_group/main/component.mk rename to examples/protocols/coap_server/main/component.mk diff --git a/examples/03_http_request/Makefile b/examples/protocols/http_request/Makefile similarity index 100% rename from examples/03_http_request/Makefile rename to examples/protocols/http_request/Makefile diff --git a/examples/03_http_request/README.md b/examples/protocols/http_request/README.md similarity index 100% rename from examples/03_http_request/README.md rename to examples/protocols/http_request/README.md diff --git a/examples/03_http_request/main/Kconfig.projbuild b/examples/protocols/http_request/main/Kconfig.projbuild similarity index 100% rename from examples/03_http_request/main/Kconfig.projbuild rename to examples/protocols/http_request/main/Kconfig.projbuild diff --git a/examples/06_sntp/main/component.mk b/examples/protocols/http_request/main/component.mk similarity index 100% rename from examples/06_sntp/main/component.mk rename to examples/protocols/http_request/main/component.mk diff --git a/examples/03_http_request/main/http_request_main.c b/examples/protocols/http_request/main/http_request_main.c similarity index 100% rename from examples/03_http_request/main/http_request_main.c rename to examples/protocols/http_request/main/http_request_main.c diff --git a/examples/04_https_request/Makefile b/examples/protocols/https_request/Makefile similarity index 100% rename from examples/04_https_request/Makefile rename to examples/protocols/https_request/Makefile diff --git a/examples/04_https_request/README.md b/examples/protocols/https_request/README.md similarity index 100% rename from examples/04_https_request/README.md rename to examples/protocols/https_request/README.md diff --git a/examples/04_https_request/main/Kconfig.projbuild b/examples/protocols/https_request/main/Kconfig.projbuild similarity index 100% rename from examples/04_https_request/main/Kconfig.projbuild rename to examples/protocols/https_request/main/Kconfig.projbuild diff --git a/examples/04_https_request/main/component.mk b/examples/protocols/https_request/main/component.mk similarity index 100% rename from examples/04_https_request/main/component.mk rename to examples/protocols/https_request/main/component.mk diff --git a/examples/04_https_request/main/https_request_main.c b/examples/protocols/https_request/main/https_request_main.c similarity index 100% rename from examples/04_https_request/main/https_request_main.c rename to examples/protocols/https_request/main/https_request_main.c diff --git a/examples/04_https_request/main/server_root_cert.pem b/examples/protocols/https_request/main/server_root_cert.pem similarity index 100% rename from examples/04_https_request/main/server_root_cert.pem rename to examples/protocols/https_request/main/server_root_cert.pem diff --git a/examples/30_mdns_example/Makefile b/examples/protocols/mdns/Makefile similarity index 100% rename from examples/30_mdns_example/Makefile rename to examples/protocols/mdns/Makefile diff --git a/examples/30_mdns_example/README.md b/examples/protocols/mdns/README.md similarity index 100% rename from examples/30_mdns_example/README.md rename to examples/protocols/mdns/README.md diff --git a/examples/30_mdns_example/main/Kconfig.projbuild b/examples/protocols/mdns/main/Kconfig.projbuild similarity index 100% rename from examples/30_mdns_example/main/Kconfig.projbuild rename to examples/protocols/mdns/main/Kconfig.projbuild diff --git a/examples/17_ethernet/main/component.mk b/examples/protocols/mdns/main/component.mk similarity index 100% rename from examples/17_ethernet/main/component.mk rename to examples/protocols/mdns/main/component.mk diff --git a/examples/30_mdns_example/main/mdns_example_main.c b/examples/protocols/mdns/main/mdns_example_main.c similarity index 100% rename from examples/30_mdns_example/main/mdns_example_main.c rename to examples/protocols/mdns/main/mdns_example_main.c diff --git a/examples/09_openssl_client/Makefile b/examples/protocols/openssl_client/Makefile similarity index 100% rename from examples/09_openssl_client/Makefile rename to examples/protocols/openssl_client/Makefile diff --git a/examples/09_openssl_client/README.md b/examples/protocols/openssl_client/README.md similarity index 100% rename from examples/09_openssl_client/README.md rename to examples/protocols/openssl_client/README.md diff --git a/examples/09_openssl_client/main/Kconfig.projbuild b/examples/protocols/openssl_client/main/Kconfig.projbuild similarity index 100% rename from examples/09_openssl_client/main/Kconfig.projbuild rename to examples/protocols/openssl_client/main/Kconfig.projbuild diff --git a/examples/29_ledc/main/component.mk b/examples/protocols/openssl_client/main/component.mk similarity index 100% rename from examples/29_ledc/main/component.mk rename to examples/protocols/openssl_client/main/component.mk diff --git a/examples/09_openssl_client/main/openssl_client.c b/examples/protocols/openssl_client/main/openssl_client.c similarity index 100% rename from examples/09_openssl_client/main/openssl_client.c rename to examples/protocols/openssl_client/main/openssl_client.c diff --git a/examples/09_openssl_client/main/openssl_client.h b/examples/protocols/openssl_client/main/openssl_client.h similarity index 100% rename from examples/09_openssl_client/main/openssl_client.h rename to examples/protocols/openssl_client/main/openssl_client.h diff --git a/examples/10_openssl_server/Makefile b/examples/protocols/openssl_server/Makefile similarity index 100% rename from examples/10_openssl_server/Makefile rename to examples/protocols/openssl_server/Makefile diff --git a/examples/10_openssl_server/README.md b/examples/protocols/openssl_server/README.md similarity index 100% rename from examples/10_openssl_server/README.md rename to examples/protocols/openssl_server/README.md diff --git a/examples/10_openssl_server/main/Kconfig.projbuild b/examples/protocols/openssl_server/main/Kconfig.projbuild similarity index 100% rename from examples/10_openssl_server/main/Kconfig.projbuild rename to examples/protocols/openssl_server/main/Kconfig.projbuild diff --git a/examples/10_openssl_server/main/cacert.pem b/examples/protocols/openssl_server/main/cacert.pem similarity index 100% rename from examples/10_openssl_server/main/cacert.pem rename to examples/protocols/openssl_server/main/cacert.pem diff --git a/examples/10_openssl_server/main/component.mk b/examples/protocols/openssl_server/main/component.mk similarity index 100% rename from examples/10_openssl_server/main/component.mk rename to examples/protocols/openssl_server/main/component.mk diff --git a/examples/10_openssl_server/main/openssl_server.c b/examples/protocols/openssl_server/main/openssl_server.c similarity index 100% rename from examples/10_openssl_server/main/openssl_server.c rename to examples/protocols/openssl_server/main/openssl_server.c diff --git a/examples/10_openssl_server/main/openssl_server.h b/examples/protocols/openssl_server/main/openssl_server.h similarity index 100% rename from examples/10_openssl_server/main/openssl_server.h rename to examples/protocols/openssl_server/main/openssl_server.h diff --git a/examples/10_openssl_server/main/prvtkey.pem b/examples/protocols/openssl_server/main/prvtkey.pem similarity index 100% rename from examples/10_openssl_server/main/prvtkey.pem rename to examples/protocols/openssl_server/main/prvtkey.pem diff --git a/examples/06_sntp/Makefile b/examples/protocols/sntp/Makefile similarity index 100% rename from examples/06_sntp/Makefile rename to examples/protocols/sntp/Makefile diff --git a/examples/06_sntp/README.md b/examples/protocols/sntp/README.md similarity index 100% rename from examples/06_sntp/README.md rename to examples/protocols/sntp/README.md diff --git a/examples/06_sntp/main/Kconfig.projbuild b/examples/protocols/sntp/main/Kconfig.projbuild similarity index 100% rename from examples/06_sntp/main/Kconfig.projbuild rename to examples/protocols/sntp/main/Kconfig.projbuild diff --git a/examples/25_ota/main/component.mk b/examples/protocols/sntp/main/component.mk similarity index 100% rename from examples/25_ota/main/component.mk rename to examples/protocols/sntp/main/component.mk diff --git a/examples/06_sntp/main/sntp_main.c b/examples/protocols/sntp/main/sntp_main.c similarity index 100% rename from examples/06_sntp/main/sntp_main.c rename to examples/protocols/sntp/main/sntp_main.c diff --git a/examples/08_nvs_rw_blob/Makefile b/examples/storage/nvs_rw_blob/Makefile similarity index 100% rename from examples/08_nvs_rw_blob/Makefile rename to examples/storage/nvs_rw_blob/Makefile diff --git a/examples/08_nvs_rw_blob/README.md b/examples/storage/nvs_rw_blob/README.md similarity index 100% rename from examples/08_nvs_rw_blob/README.md rename to examples/storage/nvs_rw_blob/README.md diff --git a/examples/23_coap_client/main/component.mk b/examples/storage/nvs_rw_blob/main/component.mk similarity index 100% rename from examples/23_coap_client/main/component.mk rename to examples/storage/nvs_rw_blob/main/component.mk diff --git a/examples/08_nvs_rw_blob/main/nvs_rw_blob.c b/examples/storage/nvs_rw_blob/main/nvs_rw_blob.c similarity index 100% rename from examples/08_nvs_rw_blob/main/nvs_rw_blob.c rename to examples/storage/nvs_rw_blob/main/nvs_rw_blob.c diff --git a/examples/07_nvs_rw_value/Makefile b/examples/storage/nvs_rw_value/Makefile similarity index 100% rename from examples/07_nvs_rw_value/Makefile rename to examples/storage/nvs_rw_value/Makefile diff --git a/examples/07_nvs_rw_value/README.md b/examples/storage/nvs_rw_value/README.md similarity index 100% rename from examples/07_nvs_rw_value/README.md rename to examples/storage/nvs_rw_value/README.md diff --git a/examples/24_coap_server/main/component.mk b/examples/storage/nvs_rw_value/main/component.mk similarity index 100% rename from examples/24_coap_server/main/component.mk rename to examples/storage/nvs_rw_value/main/component.mk diff --git a/examples/07_nvs_rw_value/main/nvs_rw_value.c b/examples/storage/nvs_rw_value/main/nvs_rw_value.c similarity index 100% rename from examples/07_nvs_rw_value/main/nvs_rw_value.c rename to examples/storage/nvs_rw_value/main/nvs_rw_value.c diff --git a/examples/27_sd_card/Makefile b/examples/storage/sd_card/Makefile similarity index 100% rename from examples/27_sd_card/Makefile rename to examples/storage/sd_card/Makefile diff --git a/examples/27_sd_card/README.md b/examples/storage/sd_card/README.md similarity index 100% rename from examples/27_sd_card/README.md rename to examples/storage/sd_card/README.md diff --git a/examples/27_sd_card/main/component.mk b/examples/storage/sd_card/main/component.mk similarity index 100% rename from examples/27_sd_card/main/component.mk rename to examples/storage/sd_card/main/component.mk diff --git a/examples/27_sd_card/main/sd_card.c b/examples/storage/sd_card/main/sd_card.c similarity index 100% rename from examples/27_sd_card/main/sd_card.c rename to examples/storage/sd_card/main/sd_card.c diff --git a/examples/25_ota/Makefile b/examples/system/ota/Makefile similarity index 100% rename from examples/25_ota/Makefile rename to examples/system/ota/Makefile diff --git a/examples/25_ota/OTA_workflow.png b/examples/system/ota/OTA_workflow.png similarity index 100% rename from examples/25_ota/OTA_workflow.png rename to examples/system/ota/OTA_workflow.png diff --git a/examples/25_ota/README.md b/examples/system/ota/README.md similarity index 100% rename from examples/25_ota/README.md rename to examples/system/ota/README.md diff --git a/examples/25_ota/main/Kconfig.projbuild b/examples/system/ota/main/Kconfig.projbuild similarity index 100% rename from examples/25_ota/main/Kconfig.projbuild rename to examples/system/ota/main/Kconfig.projbuild diff --git a/examples/30_mdns_example/main/component.mk b/examples/system/ota/main/component.mk similarity index 100% rename from examples/30_mdns_example/main/component.mk rename to examples/system/ota/main/component.mk diff --git a/examples/25_ota/main/ota.c b/examples/system/ota/main/ota.c similarity index 100% rename from examples/25_ota/main/ota.c rename to examples/system/ota/main/ota.c diff --git a/examples/25_ota/sdkconfig.defaults b/examples/system/ota/sdkconfig.defaults similarity index 100% rename from examples/25_ota/sdkconfig.defaults rename to examples/system/ota/sdkconfig.defaults diff --git a/examples/31_wpa2_enterprise/Makefile b/examples/wifi/wpa2_enterprise/Makefile similarity index 100% rename from examples/31_wpa2_enterprise/Makefile rename to examples/wifi/wpa2_enterprise/Makefile diff --git a/examples/31_wpa2_enterprise/README.md b/examples/wifi/wpa2_enterprise/README.md similarity index 100% rename from examples/31_wpa2_enterprise/README.md rename to examples/wifi/wpa2_enterprise/README.md diff --git a/examples/31_wpa2_enterprise/main/Kconfig.projbuild b/examples/wifi/wpa2_enterprise/main/Kconfig.projbuild similarity index 100% rename from examples/31_wpa2_enterprise/main/Kconfig.projbuild rename to examples/wifi/wpa2_enterprise/main/Kconfig.projbuild diff --git a/examples/31_wpa2_enterprise/main/component.mk b/examples/wifi/wpa2_enterprise/main/component.mk similarity index 100% rename from examples/31_wpa2_enterprise/main/component.mk rename to examples/wifi/wpa2_enterprise/main/component.mk diff --git a/examples/31_wpa2_enterprise/main/wpa2_ca.pem b/examples/wifi/wpa2_enterprise/main/wpa2_ca.pem similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_ca.pem rename to examples/wifi/wpa2_enterprise/main/wpa2_ca.pem diff --git a/examples/31_wpa2_enterprise/main/wpa2_client.crt b/examples/wifi/wpa2_enterprise/main/wpa2_client.crt similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_client.crt rename to examples/wifi/wpa2_enterprise/main/wpa2_client.crt diff --git a/examples/31_wpa2_enterprise/main/wpa2_client.key b/examples/wifi/wpa2_enterprise/main/wpa2_client.key similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_client.key rename to examples/wifi/wpa2_enterprise/main/wpa2_client.key diff --git a/examples/31_wpa2_enterprise/main/wpa2_client.pem b/examples/wifi/wpa2_enterprise/main/wpa2_client.pem similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_client.pem rename to examples/wifi/wpa2_enterprise/main/wpa2_client.pem diff --git a/examples/31_wpa2_enterprise/main/wpa2_enterprise_main.c b/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_enterprise_main.c rename to examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c diff --git a/examples/31_wpa2_enterprise/main/wpa2_server.crt b/examples/wifi/wpa2_enterprise/main/wpa2_server.crt similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_server.crt rename to examples/wifi/wpa2_enterprise/main/wpa2_server.crt diff --git a/examples/31_wpa2_enterprise/main/wpa2_server.key b/examples/wifi/wpa2_enterprise/main/wpa2_server.key similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_server.key rename to examples/wifi/wpa2_enterprise/main/wpa2_server.key diff --git a/examples/31_wpa2_enterprise/main/wpa2_server.pem b/examples/wifi/wpa2_enterprise/main/wpa2_server.pem similarity index 100% rename from examples/31_wpa2_enterprise/main/wpa2_server.pem rename to examples/wifi/wpa2_enterprise/main/wpa2_server.pem From f7a9a2f50b9c5ba6075c9da61b37b011de00a3f0 Mon Sep 17 00:00:00 2001 From: Krzysztof Budzynski Date: Mon, 16 Jan 2017 23:08:35 +0100 Subject: [PATCH 011/139] Modified buid_examples.sh to handle new locations of examples --- make/build_examples.sh | 52 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/make/build_examples.sh b/make/build_examples.sh index ab59208795..e85ec26a70 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -15,34 +15,38 @@ FAILED_EXAMPLES="" RESULT_WARNINGS=22 # magic number result code for "warnings found" -for example in ${IDF_PATH}/examples/*; do - [ -f ${example}/Makefile ] || continue - echo "Building ${example} as ${EXAMPLE_NUM}..." - mkdir -p example_builds/${EXAMPLE_NUM} - cp -r ${example} example_builds/${EXAMPLE_NUM} - pushd example_builds/${EXAMPLE_NUM}/`basename ${example}` +# traverse categories +for category in ${IDF_PATH}/examples/*; do + # traverse examples within each category + for example in ${category}/*; do + [ -f ${example}/Makefile ] || continue + echo "Building ${example} as ${EXAMPLE_NUM}..." + mkdir -p example_builds/${EXAMPLE_NUM} + cp -r ${example} example_builds/${EXAMPLE_NUM} + pushd example_builds/${EXAMPLE_NUM}/`basename ${example}` - # be stricter in the CI build than the default IDF settings - export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations" - export EXTRA_CXXFLAGS=${EXTRA_CFLAGS} + # be stricter in the CI build than the default IDF settings + export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations" + export EXTRA_CXXFLAGS=${EXTRA_CFLAGS} - # build non-verbose first - BUILDLOG=$(mktemp -t examplebuild.XXXX.log) - ( - set -o pipefail # so result of make all isn't lost when piping to tee - set -e - make clean defconfig - make $* all 2>&1 | tee $BUILDLOG - ) || { RESULT=$?; FAILED_EXAMPLES+=" ${example}"; make V=1; } # only build verbose if there's an error - popd - EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) + # build non-verbose first + BUILDLOG=$(mktemp -t examplebuild.XXXX.log) + ( + set -o pipefail # so result of make all isn't lost when piping to tee + set -e + make clean defconfig + make $* all 2>&1 | tee $BUILDLOG + ) || { RESULT=$?; FAILED_EXAMPLES+=" ${example}"; make V=1; } # only build verbose if there's an error + popd + EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) - if grep -q ": warning:" $BUILDLOG; then - [ $RESULT -eq 0 ] && RESULT=$RESULT_WARNINGS - FAILED_EXAMPLES+=" ${example} (warnings)" - fi + if grep -q ": warning:" $BUILDLOG; then + [ $RESULT -eq 0 ] && RESULT=$RESULT_WARNINGS + FAILED_EXAMPLES+=" ${example} (warnings)" + fi - rm -f $BUILDLOG + rm -f $BUILDLOG + done done if [ $RESULT -eq $RESULT_WARNINGS ]; then From 469d390d46f7f397e1434e791ef279983250885c Mon Sep 17 00:00:00 2001 From: Krzysztof Budzynski Date: Mon, 16 Jan 2017 23:08:35 +0100 Subject: [PATCH 012/139] Moved api documentation to new folders / categories --- docs/api/{ => bluetooth}/bt_common.rst | 0 docs/api/{ => bluetooth}/bt_le.rst | 0 docs/api/{ => bluetooth}/controller_vhci.rst | 0 docs/api/{ => bluetooth}/esp_blufi.rst | 0 docs/api/{ => bluetooth}/esp_bt_defs.rst | 0 docs/api/{ => bluetooth}/esp_bt_device.rst | 0 docs/api/{ => bluetooth}/esp_bt_main.rst | 0 docs/api/{ => bluetooth}/esp_gap_ble.rst | 0 docs/api/{ => bluetooth}/esp_gatt_defs.rst | 0 docs/api/{ => bluetooth}/esp_gattc.rst | 0 docs/api/{ => bluetooth}/esp_gatts.rst | 0 docs/api/{bt.rst => bluetooth/index.rst} | 7 +- docs/api/{ => ethernet}/esp_eth.rst | 0 docs/api/ethernet/index.rst | 8 ++ docs/api/{ => peripherals}/gpio.rst | 0 docs/api/{ => peripherals}/i2c.rst | 0 docs/api/peripherals/index.rst | 16 +++ docs/api/{ => peripherals}/ledc.rst | 0 docs/api/{ => peripherals}/pcnt.rst | 0 docs/api/{ => peripherals}/rmt.rst | 0 docs/api/{ => peripherals}/sigmadelta.rst | 0 docs/api/{ => peripherals}/spi_master.rst | 0 docs/api/{ => peripherals}/timer.rst | 0 docs/api/{ => peripherals}/uart.rst | 0 docs/api/protocols/index.rst | 8 ++ docs/api/{ => protocols}/mdns.rst | 0 docs/api/{ => storage}/fatfs.rst | 0 docs/api/storage/index.rst | 12 ++ docs/api/{ => storage}/nvs_flash.rst | 0 docs/api/{ => storage}/sdmmc.rst | 0 docs/api/{ => storage}/spi_flash.rst | 0 docs/api/{ => storage}/vfs.rst | 0 docs/api/{ => system}/deep_sleep.rst | 0 docs/api/system/index.rst | 13 ++ docs/api/{ => system}/intr_alloc.rst | 0 docs/api/{ => system}/log.rst | 0 docs/api/{ => system}/mem_alloc.rst | 0 docs/api/{ => system}/ota.rst | 0 docs/api/{ => system}/wdts.rst | 0 docs/api/{ => wifi}/esp_smartconfig.rst | 0 docs/api/{ => wifi}/esp_wifi.rst | 0 docs/api/wifi/index.rst | 8 ++ docs/index.rst | 127 ++++--------------- docs/{api => }/ulp.rst | 0 44 files changed, 96 insertions(+), 103 deletions(-) rename docs/api/{ => bluetooth}/bt_common.rst (100%) rename docs/api/{ => bluetooth}/bt_le.rst (100%) rename docs/api/{ => bluetooth}/controller_vhci.rst (100%) rename docs/api/{ => bluetooth}/esp_blufi.rst (100%) rename docs/api/{ => bluetooth}/esp_bt_defs.rst (100%) rename docs/api/{ => bluetooth}/esp_bt_device.rst (100%) rename docs/api/{ => bluetooth}/esp_bt_main.rst (100%) rename docs/api/{ => bluetooth}/esp_gap_ble.rst (100%) rename docs/api/{ => bluetooth}/esp_gatt_defs.rst (100%) rename docs/api/{ => bluetooth}/esp_gattc.rst (100%) rename docs/api/{ => bluetooth}/esp_gatts.rst (100%) rename docs/api/{bt.rst => bluetooth/index.rst} (71%) rename docs/api/{ => ethernet}/esp_eth.rst (100%) create mode 100644 docs/api/ethernet/index.rst rename docs/api/{ => peripherals}/gpio.rst (100%) rename docs/api/{ => peripherals}/i2c.rst (100%) create mode 100644 docs/api/peripherals/index.rst rename docs/api/{ => peripherals}/ledc.rst (100%) rename docs/api/{ => peripherals}/pcnt.rst (100%) rename docs/api/{ => peripherals}/rmt.rst (100%) rename docs/api/{ => peripherals}/sigmadelta.rst (100%) rename docs/api/{ => peripherals}/spi_master.rst (100%) rename docs/api/{ => peripherals}/timer.rst (100%) rename docs/api/{ => peripherals}/uart.rst (100%) create mode 100644 docs/api/protocols/index.rst rename docs/api/{ => protocols}/mdns.rst (100%) rename docs/api/{ => storage}/fatfs.rst (100%) create mode 100644 docs/api/storage/index.rst rename docs/api/{ => storage}/nvs_flash.rst (100%) rename docs/api/{ => storage}/sdmmc.rst (100%) rename docs/api/{ => storage}/spi_flash.rst (100%) rename docs/api/{ => storage}/vfs.rst (100%) rename docs/api/{ => system}/deep_sleep.rst (100%) create mode 100644 docs/api/system/index.rst rename docs/api/{ => system}/intr_alloc.rst (100%) rename docs/api/{ => system}/log.rst (100%) rename docs/api/{ => system}/mem_alloc.rst (100%) rename docs/api/{ => system}/ota.rst (100%) rename docs/api/{ => system}/wdts.rst (100%) rename docs/api/{ => wifi}/esp_smartconfig.rst (100%) rename docs/api/{ => wifi}/esp_wifi.rst (100%) create mode 100644 docs/api/wifi/index.rst rename docs/{api => }/ulp.rst (100%) diff --git a/docs/api/bt_common.rst b/docs/api/bluetooth/bt_common.rst similarity index 100% rename from docs/api/bt_common.rst rename to docs/api/bluetooth/bt_common.rst diff --git a/docs/api/bt_le.rst b/docs/api/bluetooth/bt_le.rst similarity index 100% rename from docs/api/bt_le.rst rename to docs/api/bluetooth/bt_le.rst diff --git a/docs/api/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst similarity index 100% rename from docs/api/controller_vhci.rst rename to docs/api/bluetooth/controller_vhci.rst diff --git a/docs/api/esp_blufi.rst b/docs/api/bluetooth/esp_blufi.rst similarity index 100% rename from docs/api/esp_blufi.rst rename to docs/api/bluetooth/esp_blufi.rst diff --git a/docs/api/esp_bt_defs.rst b/docs/api/bluetooth/esp_bt_defs.rst similarity index 100% rename from docs/api/esp_bt_defs.rst rename to docs/api/bluetooth/esp_bt_defs.rst diff --git a/docs/api/esp_bt_device.rst b/docs/api/bluetooth/esp_bt_device.rst similarity index 100% rename from docs/api/esp_bt_device.rst rename to docs/api/bluetooth/esp_bt_device.rst diff --git a/docs/api/esp_bt_main.rst b/docs/api/bluetooth/esp_bt_main.rst similarity index 100% rename from docs/api/esp_bt_main.rst rename to docs/api/bluetooth/esp_bt_main.rst diff --git a/docs/api/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst similarity index 100% rename from docs/api/esp_gap_ble.rst rename to docs/api/bluetooth/esp_gap_ble.rst diff --git a/docs/api/esp_gatt_defs.rst b/docs/api/bluetooth/esp_gatt_defs.rst similarity index 100% rename from docs/api/esp_gatt_defs.rst rename to docs/api/bluetooth/esp_gatt_defs.rst diff --git a/docs/api/esp_gattc.rst b/docs/api/bluetooth/esp_gattc.rst similarity index 100% rename from docs/api/esp_gattc.rst rename to docs/api/bluetooth/esp_gattc.rst diff --git a/docs/api/esp_gatts.rst b/docs/api/bluetooth/esp_gatts.rst similarity index 100% rename from docs/api/esp_gatts.rst rename to docs/api/bluetooth/esp_gatts.rst diff --git a/docs/api/bt.rst b/docs/api/bluetooth/index.rst similarity index 71% rename from docs/api/bt.rst rename to docs/api/bluetooth/index.rst index 2eae5dd4cf..fffe674425 100644 --- a/docs/api/bt.rst +++ b/docs/api/bluetooth/index.rst @@ -1,9 +1,10 @@ -Bluetooth -========= +Bluetooth API +************* .. toctree:: - :caption: Bluetooth APIs + :maxdepth: 2 Bluetooth Controller && VHCI Bluetooth Common Bluetooth LE + diff --git a/docs/api/esp_eth.rst b/docs/api/ethernet/esp_eth.rst similarity index 100% rename from docs/api/esp_eth.rst rename to docs/api/ethernet/esp_eth.rst diff --git a/docs/api/ethernet/index.rst b/docs/api/ethernet/index.rst new file mode 100644 index 0000000000..aeb0137c5e --- /dev/null +++ b/docs/api/ethernet/index.rst @@ -0,0 +1,8 @@ +Ethernet API +************ + +.. toctree:: + :maxdepth: 1 + + Ethernet + diff --git a/docs/api/gpio.rst b/docs/api/peripherals/gpio.rst similarity index 100% rename from docs/api/gpio.rst rename to docs/api/peripherals/gpio.rst diff --git a/docs/api/i2c.rst b/docs/api/peripherals/i2c.rst similarity index 100% rename from docs/api/i2c.rst rename to docs/api/peripherals/i2c.rst diff --git a/docs/api/peripherals/index.rst b/docs/api/peripherals/index.rst new file mode 100644 index 0000000000..9ea0c41ab6 --- /dev/null +++ b/docs/api/peripherals/index.rst @@ -0,0 +1,16 @@ +Peripherals API +*************** + +.. toctree:: + :maxdepth: 1 + + GPIO + UART + I2C + SPI Master + Timer + Pulse Counter + Sigma-delta Modulation + LED Control + Remote Control + diff --git a/docs/api/ledc.rst b/docs/api/peripherals/ledc.rst similarity index 100% rename from docs/api/ledc.rst rename to docs/api/peripherals/ledc.rst diff --git a/docs/api/pcnt.rst b/docs/api/peripherals/pcnt.rst similarity index 100% rename from docs/api/pcnt.rst rename to docs/api/peripherals/pcnt.rst diff --git a/docs/api/rmt.rst b/docs/api/peripherals/rmt.rst similarity index 100% rename from docs/api/rmt.rst rename to docs/api/peripherals/rmt.rst diff --git a/docs/api/sigmadelta.rst b/docs/api/peripherals/sigmadelta.rst similarity index 100% rename from docs/api/sigmadelta.rst rename to docs/api/peripherals/sigmadelta.rst diff --git a/docs/api/spi_master.rst b/docs/api/peripherals/spi_master.rst similarity index 100% rename from docs/api/spi_master.rst rename to docs/api/peripherals/spi_master.rst diff --git a/docs/api/timer.rst b/docs/api/peripherals/timer.rst similarity index 100% rename from docs/api/timer.rst rename to docs/api/peripherals/timer.rst diff --git a/docs/api/uart.rst b/docs/api/peripherals/uart.rst similarity index 100% rename from docs/api/uart.rst rename to docs/api/peripherals/uart.rst diff --git a/docs/api/protocols/index.rst b/docs/api/protocols/index.rst new file mode 100644 index 0000000000..632bd141dc --- /dev/null +++ b/docs/api/protocols/index.rst @@ -0,0 +1,8 @@ +Protocols API +************* + +.. toctree:: + :maxdepth: 1 + + mDNS + diff --git a/docs/api/mdns.rst b/docs/api/protocols/mdns.rst similarity index 100% rename from docs/api/mdns.rst rename to docs/api/protocols/mdns.rst diff --git a/docs/api/fatfs.rst b/docs/api/storage/fatfs.rst similarity index 100% rename from docs/api/fatfs.rst rename to docs/api/storage/fatfs.rst diff --git a/docs/api/storage/index.rst b/docs/api/storage/index.rst new file mode 100644 index 0000000000..30fb2088c7 --- /dev/null +++ b/docs/api/storage/index.rst @@ -0,0 +1,12 @@ +Storage API +*********** + +.. toctree:: + :maxdepth: 1 + + SPI Flash and Partition APIs + SD/MMC + Non-Volatile Storage + Virtual Filesystem + FAT Filesystem + diff --git a/docs/api/nvs_flash.rst b/docs/api/storage/nvs_flash.rst similarity index 100% rename from docs/api/nvs_flash.rst rename to docs/api/storage/nvs_flash.rst diff --git a/docs/api/sdmmc.rst b/docs/api/storage/sdmmc.rst similarity index 100% rename from docs/api/sdmmc.rst rename to docs/api/storage/sdmmc.rst diff --git a/docs/api/spi_flash.rst b/docs/api/storage/spi_flash.rst similarity index 100% rename from docs/api/spi_flash.rst rename to docs/api/storage/spi_flash.rst diff --git a/docs/api/vfs.rst b/docs/api/storage/vfs.rst similarity index 100% rename from docs/api/vfs.rst rename to docs/api/storage/vfs.rst diff --git a/docs/api/deep_sleep.rst b/docs/api/system/deep_sleep.rst similarity index 100% rename from docs/api/deep_sleep.rst rename to docs/api/system/deep_sleep.rst diff --git a/docs/api/system/index.rst b/docs/api/system/index.rst new file mode 100644 index 0000000000..6bbd7c10c5 --- /dev/null +++ b/docs/api/system/index.rst @@ -0,0 +1,13 @@ +System API +********** + +.. toctree:: + :maxdepth: 1 + + Memory Allocation + Interrupt Allocation + Watchdogs + OTA + Deep Sleep + Logging + diff --git a/docs/api/intr_alloc.rst b/docs/api/system/intr_alloc.rst similarity index 100% rename from docs/api/intr_alloc.rst rename to docs/api/system/intr_alloc.rst diff --git a/docs/api/log.rst b/docs/api/system/log.rst similarity index 100% rename from docs/api/log.rst rename to docs/api/system/log.rst diff --git a/docs/api/mem_alloc.rst b/docs/api/system/mem_alloc.rst similarity index 100% rename from docs/api/mem_alloc.rst rename to docs/api/system/mem_alloc.rst diff --git a/docs/api/ota.rst b/docs/api/system/ota.rst similarity index 100% rename from docs/api/ota.rst rename to docs/api/system/ota.rst diff --git a/docs/api/wdts.rst b/docs/api/system/wdts.rst similarity index 100% rename from docs/api/wdts.rst rename to docs/api/system/wdts.rst diff --git a/docs/api/esp_smartconfig.rst b/docs/api/wifi/esp_smartconfig.rst similarity index 100% rename from docs/api/esp_smartconfig.rst rename to docs/api/wifi/esp_smartconfig.rst diff --git a/docs/api/esp_wifi.rst b/docs/api/wifi/esp_wifi.rst similarity index 100% rename from docs/api/esp_wifi.rst rename to docs/api/wifi/esp_wifi.rst diff --git a/docs/api/wifi/index.rst b/docs/api/wifi/index.rst new file mode 100644 index 0000000000..2abe2b2fff --- /dev/null +++ b/docs/api/wifi/index.rst @@ -0,0 +1,8 @@ +Wi-Fi API +********* + +.. toctree:: + :maxdepth: 1 + + Wi-Fi + Smart Config diff --git a/docs/index.rst b/docs/index.rst index eafe102447..d1072b6511 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,118 +26,46 @@ Contents: .. toctree:: :caption: What Else? :maxdepth: 1 - - General Notes - partition-tables - build_system - openocd - core_dump - Flash encryption - Secure Boot - ULP coprocessor -.. API Reference - .. - Table of Contents Outline - .. - 1. System - TBA - 1.1. Fundamentals of multiprocessor programming with FreeRTOS - TBA - 1.2. Application startup flow - TBA - 1.3. Flash encryption and secure boot: how they work and APIs - 1.4. Lower Power Coprocessor - TBA - 1.5. Watchdogs - 1.6. Memory allocation - 1.7. ... - 2. Memory - TBA - 2.1. Memory layout of the application (IRAM/IROM, limitations of each) - TBA - 2.2. Flash layout and partitions - TBA - 2.3. Flash access APIs - TBA - 2.4. Partition APIs - TBA - 2.5. OTA mechanism (app partitions, OTA partition) and APIs - TBA - 2.6. ... - 3. Wi-Fi - 4. Bluetooth - 4.1. BT Classic - TBA - 4.2. BLE - 5. Ethernet - TBA - 6. Interfaces - 6.1. GPIO - 6.2. ADC - TBA - 6.3. DAC - TBA - 6.4. UART - 6.5. I2C - TBA - 6.6. I2S - TBA - 6.7. SPI - - 6.8. CAN - TBA - 6.9. SD Controller - TBA - 6.10. Infrared - TBA - 6.11. Pulse Counter - TBA - 6.12. PWM - TBA - 6.13. LED PWM - 6.14. ... - 7. Sensors - TBA - 7.1. Hall Sensor - TBA - 7.2. Temperature Sensor - TBA - 7.3. Touch Sensor - TBA - 8. Protocols - TBA - 9. Components - 9.1. Logging - 9.2 Non-Volatile Storage - 9.3 Virtual Filesystem - 9.3. Http sever - TBA - 10. Applications - TBA - .. - API Dcoumentation Teamplate - .. + General Notes + Build System + Debugging + ESP32 Core Dump + Partition Tables + Flash Encryption + Secure Boot + Deep Sleep Wake Stubs + ULP Coprocessor .. toctree:: :caption: API Reference - :maxdepth: 1 + :maxdepth: 2 - Wi-Fi - Smart Config - Bluetooth - Watchdogs - OTA - GPIO - UART - LED Control - Remote Control - Timer - I2C - Pulse Counter - Sigma-delta Modulation - SD/MMC - SPI Flash and Partition APIs - SPI Master API - Logging - Non-Volatile Storage - Virtual Filesystem - FAT Filesystem - Ethernet - Interrupt Allocation - Memory Allocation - Deep Sleep - deep-sleep-stub - - mDNS - Template + Wi-Fi + Bluetooth + Ethernet + Peripherals + System + Storage + Protocols .. toctree:: - :caption: Technical Reference + :caption: Hardware Reference - Technical Reference - -.. Resources - TBA + Technical Reference Manual + Pin List and Functions + Chip Pinout + Silicon Errata .. toctree:: :caption: Contribute :maxdepth: 1 - contributing + Contributions Guide Style Guide - documenting-code - contributor-agreement + Documenting Code + API Template + Contributor Agreement .. toctree:: :caption: Legal @@ -147,8 +75,7 @@ Contents: Indices -------- +======= * :ref:`genindex` -* :ref:`search` diff --git a/docs/api/ulp.rst b/docs/ulp.rst similarity index 100% rename from docs/api/ulp.rst rename to docs/ulp.rst From 47a0b88f6e4498ce70f8aa0482289f8987338d33 Mon Sep 17 00:00:00 2001 From: Krzysztof Budzynski Date: Mon, 16 Jan 2017 23:08:35 +0100 Subject: [PATCH 013/139] Updated relative paths to included documents --- docs/api/storage/nvs_flash.rst | 6 +++--- docs/api/storage/spi_flash.rst | 4 ++-- docs/api/storage/vfs.rst | 6 ++++-- docs/api/system/log.rst | 8 +++----- docs/ulp.rst | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/api/storage/nvs_flash.rst b/docs/api/storage/nvs_flash.rst index e2ac34ada8..00094d8697 100644 --- a/docs/api/storage/nvs_flash.rst +++ b/docs/api/storage/nvs_flash.rst @@ -1,11 +1,11 @@ -.. include:: ../../components/nvs_flash/README.rst +.. include:: ../../../components/nvs_flash/README.rst Application Example ------------------- Two examples are provided in ESP-IDF examples directory: -`07_nvs_rw_value `_ +`storage/nvs_rw_value `_ Demonstrates how to read and write a single integer value using NVS. @@ -13,7 +13,7 @@ Two examples are provided in ESP-IDF examples directory: Example also shows how to check if read / write operation was successful, or certain value is not initialized in NVS. Diagnostic is provided in plain text to help track program flow and capture any issues on the way. -`08_nvs_rw_blob `_ +`storage/nvs_rw_blob `_ Demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP32 module restarts. diff --git a/docs/api/storage/spi_flash.rst b/docs/api/storage/spi_flash.rst index 5903c0902d..209b413779 100644 --- a/docs/api/storage/spi_flash.rst +++ b/docs/api/storage/spi_flash.rst @@ -1,11 +1,11 @@ -.. include:: ../../components/spi_flash/README.rst +.. include:: ../../../components/spi_flash/README.rst Application Example ------------------- `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference ------------- diff --git a/docs/api/storage/vfs.rst b/docs/api/storage/vfs.rst index 71550f111c..d4e5d24ab7 100644 --- a/docs/api/storage/vfs.rst +++ b/docs/api/storage/vfs.rst @@ -1,9 +1,11 @@ -.. include:: ../../components/vfs/README.rst +.. include:: ../../../components/vfs/README.rst Application Example ------------------- -`Instructions `_ +`Instructions`_ + +.. _Instructions: ../template.html API Reference ------------- diff --git a/docs/api/system/log.rst b/docs/api/system/log.rst index d2f2fcd073..d812740bb2 100644 --- a/docs/api/system/log.rst +++ b/docs/api/system/log.rst @@ -1,17 +1,15 @@ -.. include:: ../../components/log/README.rst +.. include:: ../../../components/log/README.rst Application Example ------------------- `Instructions`_ +.. _Instructions: ../template.html + API Reference ------------- -`Instructions`_ - -.. _Instructions: template.html - Header Files ^^^^^^^^^^^^ diff --git a/docs/ulp.rst b/docs/ulp.rst index 9db42e633e..4ee6ed7a2f 100644 --- a/docs/ulp.rst +++ b/docs/ulp.rst @@ -1 +1 @@ -.. include:: ../../components/ulp/README.rst +.. include:: ../components/ulp/README.rst From ad25997349b2b513dc8b2ab2513b7072b83a2087 Mon Sep 17 00:00:00 2001 From: Krzysztof Budzynski Date: Mon, 16 Jan 2017 23:08:36 +0100 Subject: [PATCH 014/139] Updated links to examples in new folders / categories in api documentation --- docs/api/bluetooth/controller_vhci.rst | 4 ++-- docs/api/bluetooth/esp_blufi.rst | 2 +- docs/api/bluetooth/esp_bt_defs.rst | 2 +- docs/api/bluetooth/esp_bt_device.rst | 2 +- docs/api/bluetooth/esp_bt_main.rst | 2 +- docs/api/bluetooth/esp_gap_ble.rst | 6 +++--- docs/api/bluetooth/esp_gatt_defs.rst | 2 +- docs/api/bluetooth/esp_gattc.rst | 4 ++-- docs/api/bluetooth/esp_gatts.rst | 4 ++-- docs/api/ethernet/esp_eth.rst | 2 +- docs/api/peripherals/gpio.rst | 2 +- docs/api/peripherals/i2c.rst | 2 +- docs/api/peripherals/ledc.rst | 2 +- docs/api/peripherals/pcnt.rst | 2 +- docs/api/peripherals/rmt.rst | 2 +- docs/api/peripherals/timer.rst | 2 +- docs/api/peripherals/uart.rst | 2 +- docs/api/protocols/mdns.rst | 2 +- docs/api/storage/sdmmc.rst | 2 +- docs/api/wifi/esp_wifi.rst | 2 +- docs/build_system.rst | 2 +- examples/storage/nvs_rw_blob/README.md | 2 +- examples/storage/nvs_rw_value/README.md | 2 +- examples/system/ota/README.md | 4 ++-- 24 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index a9c1a79289..3868d9cec7 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -11,13 +11,13 @@ Application Example Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`05_ble_adv `_ +`bluetooth/ble_adv `_ This is a BLE advertising demo with virtual HCI interface. Send Reset/ADV_PARAM/ADV_DATA/ADV_ENABLE HCI command for BLE advertising. `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference ------------- diff --git a/docs/api/bluetooth/esp_blufi.rst b/docs/api/bluetooth/esp_blufi.rst index 13432dc154..a281c3d3d6 100644 --- a/docs/api/bluetooth/esp_blufi.rst +++ b/docs/api/bluetooth/esp_blufi.rst @@ -13,7 +13,7 @@ Application Example Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`12_blufi `_ +`bluetooth/blufi `_ This is a BLUFI demo. This demo can set ESP32's wifi to softap/station/softap&station mode and config wifi connections. diff --git a/docs/api/bluetooth/esp_bt_defs.rst b/docs/api/bluetooth/esp_bt_defs.rst index 801b13df78..217dfb7620 100644 --- a/docs/api/bluetooth/esp_bt_defs.rst +++ b/docs/api/bluetooth/esp_bt_defs.rst @@ -11,7 +11,7 @@ Application Example `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/bluetooth/esp_bt_device.rst b/docs/api/bluetooth/esp_bt_device.rst index c344a5e633..79c2e9c9bf 100644 --- a/docs/api/bluetooth/esp_bt_device.rst +++ b/docs/api/bluetooth/esp_bt_device.rst @@ -13,7 +13,7 @@ Application Example `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/bluetooth/esp_bt_main.rst b/docs/api/bluetooth/esp_bt_main.rst index 48bb0c9cc0..f44dc7eebc 100644 --- a/docs/api/bluetooth/esp_bt_main.rst +++ b/docs/api/bluetooth/esp_bt_main.rst @@ -11,7 +11,7 @@ Application Example `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/bluetooth/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst index 856ed27302..088ab27dba 100644 --- a/docs/api/bluetooth/esp_gap_ble.rst +++ b/docs/api/bluetooth/esp_gap_ble.rst @@ -11,14 +11,14 @@ Application Example Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`14_gatts_demo `_ -`15_gattc_demo `_ +`14_gatts_demo `_ +`15_gattc_demo `_ The two demos use different gap api, such like advertising, scan, set device name and others. `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/bluetooth/esp_gatt_defs.rst b/docs/api/bluetooth/esp_gatt_defs.rst index 70e808a5d7..621c6d95e1 100644 --- a/docs/api/bluetooth/esp_gatt_defs.rst +++ b/docs/api/bluetooth/esp_gatt_defs.rst @@ -11,7 +11,7 @@ Application Example `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/bluetooth/esp_gattc.rst b/docs/api/bluetooth/esp_gattc.rst index 7ff1e9de7e..eada883fd7 100644 --- a/docs/api/bluetooth/esp_gattc.rst +++ b/docs/api/bluetooth/esp_gattc.rst @@ -11,13 +11,13 @@ Application Example Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`15_gattc_demo `_ +`15_gattc_demo `_ This is a gatt client demo. This demo can scan devices, connect to the gatt server and discover the service. `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/bluetooth/esp_gatts.rst b/docs/api/bluetooth/esp_gatts.rst index 4278e6b33e..877840402c 100644 --- a/docs/api/bluetooth/esp_gatts.rst +++ b/docs/api/bluetooth/esp_gatts.rst @@ -11,13 +11,13 @@ Application Example Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`14_gatts_demo `_ +`14_gatts_demo `_ This is a gatt server demo. Use gatt api to create a gatt server with send advertising. This gatt server can be connected and the service can be discovery. `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html API Reference diff --git a/docs/api/ethernet/esp_eth.rst b/docs/api/ethernet/esp_eth.rst index 371aa5b233..5702389af8 100644 --- a/docs/api/ethernet/esp_eth.rst +++ b/docs/api/ethernet/esp_eth.rst @@ -4,7 +4,7 @@ ETHERNET Application Example ------------------- -ethernet example: `examples/17_ethernet `_. +ethernet example: `examples/ethernet/ethernet `_. API Reference ------------- diff --git a/docs/api/peripherals/gpio.rst b/docs/api/peripherals/gpio.rst index f331b9d265..643eac1f4d 100644 --- a/docs/api/peripherals/gpio.rst +++ b/docs/api/peripherals/gpio.rst @@ -10,7 +10,7 @@ Note that GPIO6-11 are usually used for SPI flash. GPIO34-39 can only be set as Application Example ------------------- -GPIO output and input interrupt example: `examples/21_gpio `_. +GPIO output and input interrupt example: `examples/peripherals/gpio `_. API Reference ------------- diff --git a/docs/api/peripherals/i2c.rst b/docs/api/peripherals/i2c.rst index 2f89681f1d..93d863da6b 100644 --- a/docs/api/peripherals/i2c.rst +++ b/docs/api/peripherals/i2c.rst @@ -9,7 +9,7 @@ ESP32 has two I2C controllers which can be set as master mode or slave mode. Application Example ------------------- -I2C master and slave example: `examples/18_i2c `_. +I2C master and slave example: `examples/peripherals/i2c `_. API Reference ------------- diff --git a/docs/api/peripherals/ledc.rst b/docs/api/peripherals/ledc.rst index 12d7cd16d0..8c55e2413b 100644 --- a/docs/api/peripherals/ledc.rst +++ b/docs/api/peripherals/ledc.rst @@ -12,7 +12,7 @@ decrease the duty cycle gradually, allowing for fades without any processor inte Application Example ------------------- -LEDC change duty cycle and fading control example: `examples/29_ledc `_. +LEDC change duty cycle and fading control example: `examples/peripherals/ledc `_. API Reference ------------- diff --git a/docs/api/peripherals/pcnt.rst b/docs/api/peripherals/pcnt.rst index 7fe73e6f47..bf4fcd0406 100644 --- a/docs/api/peripherals/pcnt.rst +++ b/docs/api/peripherals/pcnt.rst @@ -9,7 +9,7 @@ The PCNT (Pulse Counter) module is designed to count the number of rising and/or Application Example ------------------- -Pulse counter with control signal and event interrupt example: `examples/16_pcnt `_. +Pulse counter with control signal and event interrupt example: `examples/peripherals/pcnt `_. API Reference ------------- diff --git a/docs/api/peripherals/rmt.rst b/docs/api/peripherals/rmt.rst index 9d834b1e28..715bc46786 100644 --- a/docs/api/peripherals/rmt.rst +++ b/docs/api/peripherals/rmt.rst @@ -9,7 +9,7 @@ The RMT (Remote Control) module driver can be used to send and receive infrared Application Example ------------------- -NEC remote control TX and RX example: `examples/11_rmt_nec_tx_rx `_. +NEC remote control TX and RX example: `examples/peripherals/rmt_nec_tx_rx `_. API Reference ------------- diff --git a/docs/api/peripherals/timer.rst b/docs/api/peripherals/timer.rst index 0db0a12c23..203c6b0d30 100644 --- a/docs/api/peripherals/timer.rst +++ b/docs/api/peripherals/timer.rst @@ -12,7 +12,7 @@ They are all 64-bit generic timers based on 16-bit prescalers and 64-bit auto-re Application Example ------------------- -64-bit hardware timer example: `examples/13_timer_group `_. +64-bit hardware timer example: `examples/peripherals/timer_group `_. API Reference ------------- diff --git a/docs/api/peripherals/uart.rst b/docs/api/peripherals/uart.rst index fa83309e2a..8684b2afa3 100644 --- a/docs/api/peripherals/uart.rst +++ b/docs/api/peripherals/uart.rst @@ -16,7 +16,7 @@ API Reference `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html Header Files ^^^^^^^^^^^^ diff --git a/docs/api/protocols/mdns.rst b/docs/api/protocols/mdns.rst index 95789444f5..d674e25a08 100644 --- a/docs/api/protocols/mdns.rst +++ b/docs/api/protocols/mdns.rst @@ -163,7 +163,7 @@ Example of using the methods above: Application Example ------------------- -mDNS server/scanner example: `examples/30_mdns_example `_. +mDNS server/scanner example: `examples/protocols/mdsn `_. API Reference ------------- diff --git a/docs/api/storage/sdmmc.rst b/docs/api/storage/sdmmc.rst index e751852f95..fe2e5c27f8 100644 --- a/docs/api/storage/sdmmc.rst +++ b/docs/api/storage/sdmmc.rst @@ -15,7 +15,7 @@ Protocol layer works with the host via ``sdmmc_host_t`` structure. This structur Application Example ------------------- -An example which combines SDMMC driver with FATFS library is provided in ``examples/27_sd_card`` directory. This example initializes the card, writes and reads data from it using POSIX and C library APIs. See README.md file in the example directory for more information. +An example which combines SDMMC driver with FATFS library is provided in ``examples/storage/sd_card`` directory. This example initializes the card, writes and reads data from it using POSIX and C library APIs. See README.md file in the example directory for more information. Protocol layer APIs diff --git a/docs/api/wifi/esp_wifi.rst b/docs/api/wifi/esp_wifi.rst index c13d3d751a..1fe832a2c5 100644 --- a/docs/api/wifi/esp_wifi.rst +++ b/docs/api/wifi/esp_wifi.rst @@ -16,7 +16,7 @@ API Reference `Instructions`_ -.. _Instructions: template.html +.. _Instructions: ../template.html Header Files ^^^^^^^^^^^^ diff --git a/docs/build_system.rst b/docs/build_system.rst index 7a33a41256..d4353287b9 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -464,7 +464,7 @@ The file's contents will be added to the .rodata section in flash, and are avail The names are generated from the full name of the file, as given in COMPONENT_EMBED_FILES. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. -For an example of using this technique, see examples/04_https_request - the certificate file contents are loaded from the text .pem file at compile time. +For an example of using this technique, see examples/protocols/https_request - the certificate file contents are loaded from the text .pem file at compile time. Fully Overriding The Component Makefile diff --git a/examples/storage/nvs_rw_blob/README.md b/examples/storage/nvs_rw_blob/README.md index 81a0e36c71..94b8549b36 100644 --- a/examples/storage/nvs_rw_blob/README.md +++ b/examples/storage/nvs_rw_blob/README.md @@ -7,7 +7,7 @@ Demonstrates how to read and write a single integer value and a blob (binary lar Example also shows how to implement diagnostics if read / write operation was successful. -If not done already, consider checking simpler example *07_nvs_rw_value*, that has been used as a starting point for preparing this one. +If not done already, consider checking simpler example *storage/nvs_rw_value*, that has been used as a starting point for preparing this one. Detailed functional description of NVS and API is provided in [documentation](http://esp-idf.readthedocs.io/en/latest/api/nvs_flash.html). diff --git a/examples/storage/nvs_rw_value/README.md b/examples/storage/nvs_rw_value/README.md index 09cd364e8d..797e8d422a 100644 --- a/examples/storage/nvs_rw_value/README.md +++ b/examples/storage/nvs_rw_value/README.md @@ -6,7 +6,7 @@ The value holds the number of ESP32 module restarts. Since it is written to NVS, Example also shows how to check if read / write operation was successful, or certain value is not initialized in NVS. Diagnostic is provided in plain text to help track program flow and capture any issues on the way. -Check another example *08_nvs_rw_blob*, that shows how to read and write variable length binary data (blob). +Check another example *storage/nvs_rw_blob*, that shows how to read and write variable length binary data (blob). Detailed functional description of NVS and API is provided in [documentation](http://esp-idf.readthedocs.io/en/latest/api/nvs_flash.html). diff --git a/examples/system/ota/README.md b/examples/system/ota/README.md index 49a47d3799..886dbf5fbb 100644 --- a/examples/system/ota/README.md +++ b/examples/system/ota/README.md @@ -30,12 +30,12 @@ Connect your host PC to the same AP that you will use for the ESP32. Python has a built-in HTTP server that can be used for example purposes. -For our upgrade example OTA file, we're going to use the `01_hello_world` example. +For our upgrade example OTA file, we're going to use the `get-started/hello_world` example. Open a new terminal to run the HTTP server, then run these commands to build the example and start the server: ``` -cd $IDF_PATH/examples/01_hello_world +cd $IDF_PATH/examples/get-started/hello_world make cd build python -m SimpleHTTPServer 8070 From 905180667c6a0604dd7117c80b20b91d6520e3a8 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 10 Jan 2017 20:49:24 +0800 Subject: [PATCH 015/139] components/openssl: refactor openssl debugging and assert function 1. add openssl option at menuconfig 2. remove SSL_ERR to reduce complexity 3. add more functions about debugging and assert According these, our coders and customers may use and debug the OpenSSL code easily. --- components/openssl/Kconfig | 70 ++++ components/openssl/include/internal/ssl_dbg.h | 208 +++++++++--- components/openssl/include/platform/ssl_opt.h | 30 +- components/openssl/include/platform/ssl_pm.h | 5 + .../openssl/include/platform/ssl_port.h | 28 +- components/openssl/library/ssl_cert.c | 26 +- components/openssl/library/ssl_lib.c | 316 ++++++++++-------- components/openssl/library/ssl_pkey.c | 69 ++-- components/openssl/library/ssl_stack.c | 18 +- components/openssl/library/ssl_x509.c | 78 +++-- components/openssl/platform/ssl_pm.c | 165 +++++---- components/openssl/platform/ssl_port.c | 39 +-- 12 files changed, 646 insertions(+), 406 deletions(-) create mode 100644 components/openssl/Kconfig diff --git a/components/openssl/Kconfig b/components/openssl/Kconfig new file mode 100644 index 0000000000..7ade98c459 --- /dev/null +++ b/components/openssl/Kconfig @@ -0,0 +1,70 @@ +menu "OpenSSL" + +config OPENSSL_DEBUG + bool "Enable OpenSSL debugging" + default n + help + Enable OpenSSL debugging function. + + If the option is enabled, "SSL_DEBUG" works. + +config OPENSSL_DEBUG_LEVEL + int "OpenSSL debugging level" + default 0 + range 0 255 + depends on OPENSSL_DEBUG + help + OpenSSL debugging level. + + Only function whose debugging level is higher than "OPENSSL_DEBUG_LEVEL" works. + + For example: + If OPENSSL_DEBUG_LEVEL = 2, you use function "SSL_DEBUG(1, "malloc failed")". Because 1 < 2, it will not print. + +config OPENSSL_LOWLEVEL_DEBUG + bool "Enable OpenSSL low-level module debugging" + default n + depends on OPENSSL_DEBUG + select MBEDTLS_DEBUG + help + If the option is enabled, low-level module debugging function of OpenSSL is enabled, e.g. mbedtls internal debugging function. + +choice OPENSSL_ASSERT + prompt "Select OpenSSL assert function" + default CONFIG_OPENSSL_ASSERT_EXIT + help + OpenSSL function needs "assert" function to check if input parameters are valid. + + If you want to use assert debugging function, "OPENSSL_DEBUG" should be enabled. + +config OPENSSL_ASSERT_DO_NOTHING + bool "Do nothing" + help + Do nothing and "SSL_ASSERT" does not work. + +config OPENSSL_ASSERT_EXIT + bool "Check and exit" + help + Enable assert exiting, it will check and return error code. + +config OPENSSL_ASSERT_DEBUG + bool "Show debugging message" + depends on OPENSSL_DEBUG + help + Enable assert debugging, it will check and show debugging message. + +config OPENSSL_ASSERT_DEBUG_EXIT + bool "Show debugging message and exit" + depends on OPENSSL_DEBUG + help + Enable assert debugging and exiting, it will check, show debugging message and return error code. + +config OPENSSL_ASSERT_DEBUG_BLOCK + bool "Show debugging message and block" + depends on OPENSSL_DEBUG + help + Enable assert debugging and blocking, it will check, show debugging message and block by "while (1);". + +endchoice + +endmenu diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index b4c0754637..12ba25f99d 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -22,72 +22,170 @@ extern "C" { #endif -#ifndef SSL_DEBUG_ENBALE -#define SSL_DEBUG_ENBALE 0 -#endif - -#ifndef SSL_DEBUG_LEVEL -#define SSL_DEBUG_LEVEL 0 -#endif - -#ifndef SSL_ASSERT_ENABLE -#define SSL_ASSERT_ENABLE 0 -#endif - -#ifndef SSL_DEBUG_LOCATION_ENABLE -#define SSL_DEBUG_LOCATION_ENABLE 0 -#endif - -#if SSL_DEBUG_ENBALE - #if !defined(SSL_PRINT_LOG) || !defined(SSL_ERROR_LOG) || !defined(SSL_LOCAL_LOG) - #include "stdio.h" - extern int printf(const char *fmt, ...); - #ifndef SSL_PRINT_LOG - #define SSL_PRINT_LOG printf - #endif - #ifndef SSL_ERROR_LOG - #define SSL_ERROR_LOG printf - #endif - #ifndef SSL_LOCAL_LOG - #define SSL_LOCAL_LOG printf - #endif - #endif +#ifdef CONFIG_OPENSSL_DEBUG_LEVEL + #define SSL_DEBUG_LEVEL CONFIG_OPENSSL_DEBUG_LEVEL #else - #ifdef SSL_PRINT_LOG - #undef SSL_PRINT_LOG - #endif - #define SSL_PRINT_LOG(...) - - #ifdef SSL_ERROR_LOG - #undef SSL_ERROR_LOG - #endif - #define SSL_ERROR_LOG(...) - #ifdef SSL_LOCAL_LOG - #undef SSL_LOCAL_LOG - #endif - #define SSL_LOCAL_LOG(...) + #define SSL_DEBUG_LEVEL 0 #endif -#if SSL_DEBUG_LOCATION_ENABLE - #define SSL_DEBUG_LOCATION() SSL_LOCAL_LOG("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__) +#define SSL_DEBUG_ON (SSL_DEBUG_LEVEL + 1) +#define SSL_DEBUG_OFF (SSL_DEBUG_LEVEL - 1) + +#ifdef CONFIG_OPENSSL_DEBUG + #ifndef SSL_DEBUG_LOG + #error "SSL_DEBUG_LOG is not defined" + #endif + + #ifndef SSL_DEBUG_FL + #define SSL_DEBUG_FL "\n" + #endif + + #define SSL_SHOW_LOCATION() \ + SSL_DEBUG_LOG("SSL assert : %s %d\n", \ + __FILE__, __LINE__) + + #define SSL_DEBUG(level, fmt, ...) \ + { \ + if (level > SSL_DEBUG_LEVEL) { \ + SSL_DEBUG_LOG(fmt SSL_DEBUG_FL, ##__VA_ARGS__); \ + } \ + } +#else /* CONFIG_OPENSSL_DEBUG */ + #define SSL_SHOW_LOCATION() + + #define SSL_DEBUG(level, fmt, ...) +#endif /* CONFIG_OPENSSL_DEBUG */ + +/** + * OpenSSL assert function + * + * if select "CONFIG_OPENSSL_ASSERT_DEBUG", SSL_ASSERT* will show error file name and line + * if select "CONFIG_OPENSSL_ASSERT_EXIT", SSL_ASSERT* will just return error code. + * if select "CONFIG_OPENSSL_ASSERT_DEBUG_EXIT" SSL_ASSERT* will show error file name and line, + * then return error code. + * if select "CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK", SSL_ASSERT* will show error file name and line, + * then block here with "while (1)" + * + * SSL_ASSERT1 may will return "-1", so function's return argument is integer. + * SSL_ASSERT2 may will return "NULL", so function's return argument is a point. + * SSL_ASSERT2 may will return nothing, so function's return argument is "void". + */ +#if defined(CONFIG_OPENSSL_ASSERT_DEBUG) + #define SSL_ASSERT1(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + } \ + } + + #define SSL_ASSERT2(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + } \ + } + + #define SSL_ASSERT3(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + } \ + } +#elif defined(CONFIG_OPENSSL_ASSERT_EXIT) + #define SSL_ASSERT1(s) \ + { \ + if (!(s)) { \ + return -1; \ + } \ + } + + #define SSL_ASSERT2(s) \ + { \ + if (!(s)) { \ + return NULL; \ + } \ + } + + #define SSL_ASSERT3(s) \ + { \ + if (!(s)) { \ + return ; \ + } \ + } +#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_EXIT) + #define SSL_ASSERT1(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + return -1; \ + } \ + } + + #define SSL_ASSERT2(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + return NULL; \ + } \ + } + + #define SSL_ASSERT3(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + return ; \ + } \ + } +#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK) + #define SSL_ASSERT1(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + while (1); \ + } \ + } + + #define SSL_ASSERT2(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + while (1); \ + } \ + } + + #define SSL_ASSERT3(s) \ + { \ + if (!(s)) { \ + SSL_SHOW_LOCATION(); \ + while (1); \ + } \ + } #else - #define SSL_DEBUG_LOCATION() + #define SSL_ASSERT1(s) + #define SSL_ASSERT2(s) + #define SSL_ASSERT3(s) #endif -#if SSL_ASSERT_ENABLE - #define SSL_ASSERT(s) { if (!(s)) { SSL_DEBUG_LOCATION(); } } -#else - #define SSL_ASSERT(s) -#endif +#define SSL_PLATFORM_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_PLATFORM_ERROR_LEVEL SSL_DEBUG_ON -#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); ret = err; goto go; } +#define SSL_CERT_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_CERT_ERROR_LEVEL SSL_DEBUG_ON -#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); goto go; } +#define SSL_PKEY_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_PKEY_ERROR_LEVEL SSL_DEBUG_ON -#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT_LOG(fmt, ##__VA_ARGS__);} } +#define SSL_X509_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_X509_ERROR_LEVEL SSL_DEBUG_ON + +#define SSL_LIB_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_LIB_ERROR_LEVEL SSL_DEBUG_ON + +#define SSL_STACK_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_STACK_ERROR_LEVEL SSL_DEBUG_ON #ifdef __cplusplus -} + } #endif #endif diff --git a/components/openssl/include/platform/ssl_opt.h b/components/openssl/include/platform/ssl_opt.h index 01d438eb8a..a9c55e8c46 100644 --- a/components/openssl/include/platform/ssl_opt.h +++ b/components/openssl/include/platform/ssl_opt.h @@ -15,34 +15,6 @@ #ifndef _SSL_OPT_H_ #define _SSL_OPT_H_ -#ifdef __cplusplus - extern "C" { -#endif - -/** - * if not define "ESP32_IDF_PLATFORM", system will use esp8266 platform interface - */ -#define ESP32_IDF_PLATFORM - -/** - * openssl debug print function enable - */ -#define SSL_DEBUG_ENBALE 0 - -/** - * openssl debug print function level. function whose level is lower that "SSL_DEBUG_LEVEL" - * will not print message - */ -#define SSL_DEBUG_LEVEL 0 - -/** - * openssl assert function enable, it will check the input paramter and print the message - */ -#define SSL_ASSERT_ENABLE 0 - -/** - * openssl location function enable, it will print location of the positioning error - */ -#define SSL_DEBUG_LOCATION_ENABLE 0 +#include "sdkconfig.h" #endif diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index a516d57422..cbbe3aa3a2 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -19,6 +19,7 @@ extern "C" { #endif +#include #include "ssl_types.h" #include "ssl_port.h" @@ -53,4 +54,8 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len); long ssl_pm_get_verify_result(const SSL *ssl); +#ifdef __cplusplus + } +#endif + #endif diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 35c8dc18f9..492ea405b2 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -19,31 +19,27 @@ extern "C" { #endif -#include "platform/ssl_opt.h" - -#ifdef ESP32_IDF_PLATFORM - #include "esp_types.h" #include "esp_log.h" +#include "string.h" +#include "malloc.h" void *ssl_mem_zalloc(size_t size); -void *ssl_mem_malloc(size_t size); -void ssl_mem_free(void *p); -void* ssl_memcpy(void *to, const void *from, size_t size); -size_t ssl_strlen(const char *src); +#define ssl_mem_malloc malloc +#define ssl_mem_free free -void ssl_speed_up_enter(void); -void ssl_speed_up_exit(void); +#define ssl_memcpy memcpy +#define ssl_strlen strlen -#define SSL_PRINT_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__) -#define SSL_ERROR_LOG(fmt, ...) ESP_LOGE("openssl", fmt, ##__VA_ARGS__) -#define SSL_LOCAL_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__) +#define ssl_speed_up_enter() +#define ssl_speed_up_exit() -#elif defined(SSL_PLATFORM_USER_INCLUDE) - -SSL_PLATFORM_USER_INCLUDE +#define SSL_DEBUG_FL +#define SSL_DEBUG_LOG(fmt, ...) ESP_LOGI("openssl", fmt, ##__VA_ARGS__) +#ifdef __cplusplus + } #endif #endif diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index 0193a441e0..5c608125ac 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -29,8 +29,10 @@ CERT *__ssl_cert_new(CERT *ic) EVP_PKEY *ipk; cert = ssl_mem_zalloc(sizeof(CERT)); - if (!cert) - SSL_RET(failed1, "ssl_mem_zalloc\n"); + if (!cert) { + SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "no enough memory > (cert)"); + goto no_mem; + } if (ic) { ipk = ic->pkey; @@ -41,20 +43,24 @@ CERT *__ssl_cert_new(CERT *ic) } cert->pkey = __EVP_PKEY_new(ipk); - if (!cert->pkey) - SSL_RET(failed2, "__EVP_PKEY_new\n"); + if (!cert->pkey) { + SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__EVP_PKEY_new() return NULL"); + goto pkey_err; + } cert->x509 = __X509_new(ix); - if (!cert->x509) - SSL_RET(failed3, "__X509_new\n"); + if (!cert->x509) { + SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__X509_new() return NULL"); + goto x509_err; + } return cert; -failed3: +x509_err: EVP_PKEY_free(cert->pkey); -failed2: +pkey_err: ssl_mem_free(cert); -failed1: +no_mem: return NULL; } @@ -71,6 +77,8 @@ CERT *ssl_cert_new(void) */ void ssl_cert_free(CERT *cert) { + SSL_ASSERT3(cert); + X509_free(cert->x509); EVP_PKEY_free(cert->pkey); diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 23b8bf4cea..43c130077e 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -21,11 +21,49 @@ #define SSL_SEND_DATA_MAX_LENGTH 1460 +/** + * @brief create a new SSL session object + */ +static SSL_SESSION* SSL_SESSION_new(void) +{ + SSL_SESSION *session; + + session = ssl_mem_zalloc(sizeof(SSL_SESSION)); + if (!session) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (session)"); + goto failed1; + } + + session->peer = X509_new(); + if (!session->peer) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL"); + goto failed2; + } + + return session; + +failed2: + ssl_mem_free(session); +failed1: + return NULL; +} + +/** + * @brief free a new SSL session object + */ +static void SSL_SESSION_free(SSL_SESSION *session) +{ + X509_free(session->peer); + ssl_mem_free(session); +} + /** * @brief Discover whether the current connection is in the error state */ int ossl_statem_in_error(const SSL *ssl) { + SSL_ASSERT1(ssl); + if (ssl->statem.state == MSG_FLOW_ERROR) return 1; @@ -37,6 +75,8 @@ int ossl_statem_in_error(const SSL *ssl) */ int SSL_want(const SSL *ssl) { + SSL_ASSERT1(ssl); + return ssl->rwstate; } @@ -45,6 +85,8 @@ int SSL_want(const SSL *ssl) */ int SSL_want_nothing(const SSL *ssl) { + SSL_ASSERT1(ssl); + return (SSL_want(ssl) == SSL_NOTHING); } @@ -53,6 +95,8 @@ int SSL_want_nothing(const SSL *ssl) */ int SSL_want_read(const SSL *ssl) { + SSL_ASSERT1(ssl); + return (SSL_want(ssl) == SSL_READING); } @@ -61,6 +105,8 @@ int SSL_want_read(const SSL *ssl) */ int SSL_want_write(const SSL *ssl) { + SSL_ASSERT1(ssl); + return (SSL_want(ssl) == SSL_WRITING); } @@ -69,6 +115,8 @@ int SSL_want_write(const SSL *ssl) */ int SSL_want_x509_lookup(const SSL *ssl) { + SSL_ASSERT1(ssl); + return (SSL_want(ssl) == SSL_WRITING); } @@ -79,7 +127,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) { int ret = SSL_ERROR_SYSCALL; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); if (ret_code > 0) ret = SSL_ERROR_NONE; @@ -110,45 +158,13 @@ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) { OSSL_HANDSHAKE_STATE state; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); state = SSL_METHOD_CALL(get_state, ssl); return state; } -/** - * @brief create a new SSL session object - */ -SSL_SESSION* SSL_SESSION_new(void) -{ - SSL_SESSION *session; - - session = ssl_mem_zalloc(sizeof(SSL_SESSION)); - if (!session) - SSL_RET(failed1, "ssl_mem_zalloc\n"); - - session->peer = X509_new(); - if (!session->peer) - SSL_RET(failed2, "X509_new\n"); - - return session; - -failed2: - ssl_mem_free(session); -failed1: - return NULL; -} - -/** - * @brief free a new SSL session object - */ -void SSL_SESSION_free(SSL_SESSION *session) -{ - X509_free(session->peer); - ssl_mem_free(session); -} - /** * @brief create a SSL context */ @@ -158,19 +174,28 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) CERT *cert; X509 *client_ca; - if (!method) SSL_RET(go_failed1, "method:NULL\n"); + if (!method) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no no_method"); + return NULL; + } client_ca = X509_new(); - if (!client_ca) - SSL_RET(go_failed1, "X509_new\n"); + if (!client_ca) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL"); + goto failed1; + } cert = ssl_cert_new(); - if (!cert) - SSL_RET(go_failed2, "ssl_cert_new\n"); + if (!cert) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "ssl_cert_new() return NULL"); + goto failed2; + } ctx = (SSL_CTX *)ssl_mem_zalloc(sizeof(SSL_CTX)); - if (!ctx) - SSL_RET(go_failed3, "ssl_mem_zalloc:ctx\n"); + if (!ctx) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ctx)"); + goto failed3; + } ctx->method = method; ctx->client_CA = client_ca; @@ -180,11 +205,11 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) return ctx; -go_failed3: +failed3: ssl_cert_free(cert); -go_failed2: +failed2: X509_free(client_ca); -go_failed1: +failed1: return NULL; } @@ -193,7 +218,7 @@ go_failed1: */ void SSL_CTX_free(SSL_CTX* ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT3(ctx); ssl_cert_free(ctx->cert); @@ -207,8 +232,8 @@ void SSL_CTX_free(SSL_CTX* ctx) */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) { - SSL_ASSERT(ctx); - SSL_ASSERT(meth); + SSL_ASSERT1(ctx); + SSL_ASSERT1(meth); ctx->method = meth; @@ -222,7 +247,7 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) */ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT2(ctx); return ctx->method; } @@ -235,24 +260,34 @@ SSL *SSL_new(SSL_CTX *ctx) int ret = 0; SSL *ssl; - if (!ctx) - SSL_RET(failed1, "ctx:NULL\n"); + if (!ctx) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no ctx"); + return NULL; + } ssl = (SSL *)ssl_mem_zalloc(sizeof(SSL)); - if (!ssl) - SSL_RET(failed1, "ssl_mem_zalloc\n"); + if (!ssl) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ssl)"); + goto failed1; + } ssl->session = SSL_SESSION_new(); - if (!ssl->session) - SSL_RET(failed2, "SSL_SESSION_new\n"); + if (!ssl->session) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_SESSION_new() return NULL"); + goto failed2; + } ssl->cert = __ssl_cert_new(ctx->cert); - if (!ssl->cert) - SSL_RET(failed3, "__ssl_cert_new\n"); + if (!ssl->cert) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__ssl_cert_new() return NULL"); + goto failed3; + } ssl->client_CA = __X509_new(ctx->client_CA); - if (!ssl->client_CA) - SSL_RET(failed4, "__X509_new\n"); + if (!ssl->client_CA) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__X509_new() return NULL"); + goto failed4; + } ssl->ctx = ctx; ssl->method = ctx->method; @@ -263,8 +298,10 @@ SSL *SSL_new(SSL_CTX *ctx) ssl->verify_mode = ctx->verify_mode; ret = SSL_METHOD_CALL(new, ssl); - if (ret) - SSL_RET(failed5, "ssl_new\n"); + if (ret) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); + goto failed5; + } ssl->rwstate = SSL_NOTHING; @@ -287,7 +324,7 @@ failed1: */ void SSL_free(SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); SSL_METHOD_CALL(free, ssl); @@ -307,7 +344,7 @@ int SSL_do_handshake(SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ret = SSL_METHOD_CALL(handshake, ssl); @@ -319,7 +356,7 @@ int SSL_do_handshake(SSL *ssl) */ int SSL_connect(SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return SSL_do_handshake(ssl); } @@ -329,7 +366,7 @@ int SSL_connect(SSL *ssl) */ int SSL_accept(SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return SSL_do_handshake(ssl); } @@ -341,7 +378,7 @@ int SSL_shutdown(SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); if (SSL_get_state(ssl) != TLS_ST_OK) return 1; @@ -357,21 +394,25 @@ int SSL_clear(SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ret = SSL_shutdown(ssl); - if (1 != ret) - SSL_ERR(0, go_failed1, "SSL_shutdown\n"); + if (1 != ret) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret); + goto failed1; + } SSL_METHOD_CALL(free, ssl); ret = SSL_METHOD_CALL(new, ssl); - if (!ret) - SSL_ERR(0, go_failed1, "ssl_new\n"); + if (!ret) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); + goto failed1; + } return 1; -go_failed1: +failed1: return ret; } @@ -382,9 +423,9 @@ int SSL_read(SSL *ssl, void *buffer, int len) { int ret; - SSL_ASSERT(ssl); - SSL_ASSERT(buffer); - SSL_ASSERT(len); + SSL_ASSERT1(ssl); + SSL_ASSERT1(buffer); + SSL_ASSERT1(len); ssl->rwstate = SSL_READING; @@ -405,9 +446,9 @@ int SSL_write(SSL *ssl, const void *buffer, int len) int send_bytes; const unsigned char *pbuf; - SSL_ASSERT(ssl); - SSL_ASSERT(buffer); - SSL_ASSERT(len); + SSL_ASSERT1(ssl); + SSL_ASSERT1(buffer); + SSL_ASSERT1(len); ssl->rwstate = SSL_WRITING; @@ -443,7 +484,7 @@ int SSL_write(SSL *ssl, const void *buffer, int len) */ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); return ssl->ctx; } @@ -453,7 +494,7 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) */ const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); return ssl->method; } @@ -465,22 +506,26 @@ int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) { int ret; - SSL_ASSERT(ssl); - SSL_ASSERT(method); + SSL_ASSERT1(ssl); + SSL_ASSERT1(method); if (ssl->version != method->version) { ret = SSL_shutdown(ssl); - if (1 != ret) - SSL_ERR(0, go_failed1, "SSL_shutdown\n"); + if (1 != ret) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret); + goto failed1; + } SSL_METHOD_CALL(free, ssl); ssl->method = method; ret = SSL_METHOD_CALL(new, ssl); - if (!ret) - SSL_ERR(0, go_failed1, "ssl_new\n"); + if (!ret) { + SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); + goto failed1; + } } else { ssl->method = method; } @@ -488,7 +533,7 @@ int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) return 1; -go_failed1: +failed1: return ret; } @@ -497,7 +542,7 @@ go_failed1: */ int SSL_get_shutdown(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->shutdown; } @@ -507,7 +552,7 @@ int SSL_get_shutdown(const SSL *ssl) */ void SSL_set_shutdown(SSL *ssl, int mode) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); ssl->shutdown = mode; } @@ -520,7 +565,7 @@ int SSL_pending(const SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ret = SSL_METHOD_CALL(pending, ssl); @@ -534,7 +579,7 @@ int SSL_has_pending(const SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); if (SSL_pending(ssl)) ret = 1; @@ -549,6 +594,8 @@ int SSL_has_pending(const SSL *ssl) */ unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) { + SSL_ASSERT1(ctx); + return ctx->options &= ~op; } @@ -557,6 +604,8 @@ unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) */ unsigned long SSL_CTX_get_options(SSL_CTX *ctx) { + SSL_ASSERT1(ctx); + return ctx->options; } @@ -565,6 +614,8 @@ unsigned long SSL_CTX_get_options(SSL_CTX *ctx) */ unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) { + SSL_ASSERT1(ctx); + return ctx->options |= opt; } @@ -573,7 +624,7 @@ unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) */ unsigned long SSL_clear_options(SSL *ssl, unsigned long op) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->options & ~op; } @@ -583,7 +634,7 @@ unsigned long SSL_clear_options(SSL *ssl, unsigned long op) */ unsigned long SSL_get_options(SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->options; } @@ -593,7 +644,7 @@ unsigned long SSL_get_options(SSL *ssl) */ unsigned long SSL_set_options(SSL *ssl, unsigned long op) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->options |= op; } @@ -605,7 +656,7 @@ int SSL_get_fd(const SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ret = SSL_METHOD_CALL(get_fd, ssl, 0); @@ -619,7 +670,7 @@ int SSL_get_rfd(const SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ret = SSL_METHOD_CALL(get_fd, ssl, 0); @@ -633,7 +684,7 @@ int SSL_get_wfd(const SSL *ssl) { int ret; - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ret = SSL_METHOD_CALL(get_fd, ssl, 0); @@ -645,8 +696,8 @@ int SSL_get_wfd(const SSL *ssl) */ int SSL_set_fd(SSL *ssl, int fd) { - SSL_ASSERT(ssl); - SSL_ASSERT(fd >= 0); + SSL_ASSERT1(ssl); + SSL_ASSERT1(fd >= 0); SSL_METHOD_CALL(set_fd, ssl, fd, 0); @@ -658,8 +709,8 @@ int SSL_set_fd(SSL *ssl, int fd) */ int SSL_set_rfd(SSL *ssl, int fd) { - SSL_ASSERT(ssl); - SSL_ASSERT(fd >= 0); + SSL_ASSERT1(ssl); + SSL_ASSERT1(fd >= 0); SSL_METHOD_CALL(set_fd, ssl, fd, 0); @@ -671,8 +722,8 @@ int SSL_set_rfd(SSL *ssl, int fd) */ int SSL_set_wfd(SSL *ssl, int fd) { - SSL_ASSERT(ssl); - SSL_ASSERT(fd >= 0); + SSL_ASSERT1(ssl); + SSL_ASSERT1(fd >= 0); SSL_METHOD_CALL(set_fd, ssl, fd, 0); @@ -684,7 +735,7 @@ int SSL_set_wfd(SSL *ssl, int fd) */ int SSL_version(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->version; } @@ -715,7 +766,7 @@ static const char* ssl_protocol_to_string(int version) */ const char *SSL_get_version(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); return ssl_protocol_to_string(SSL_version(ssl)); } @@ -987,7 +1038,7 @@ const char *SSL_rstate_string(SSL *ssl) { const char *str; - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); switch (ssl->rlayer.rstate) { @@ -1015,7 +1066,7 @@ const char *SSL_rstate_string_long(SSL *ssl) { const char *str = "unknown"; - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); switch (ssl->rlayer.rstate) { @@ -1042,7 +1093,7 @@ char *SSL_state_string(const SSL *ssl) { char *str = "UNKWN "; - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); if (ossl_statem_in_error(ssl)) str = "SSLERR"; @@ -1150,7 +1201,7 @@ char *SSL_state_string_long(const SSL *ssl) { char *str = "UNKWN "; - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); if (ossl_statem_in_error(ssl)) str = "SSLERR"; @@ -1262,8 +1313,7 @@ char *SSL_state_string_long(const SSL *ssl) */ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) { - SSL_ASSERT(ctx); - SSL_ASSERT(len); + SSL_ASSERT3(ctx); ctx->read_buffer_len = len; } @@ -1273,8 +1323,8 @@ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) */ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) { - SSL_ASSERT(ssl); - SSL_ASSERT(len); + SSL_ASSERT3(ssl); + SSL_ASSERT3(len); SSL_METHOD_CALL(set_bufflen, ssl, len); } @@ -1284,7 +1334,7 @@ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) */ void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); ssl->info_callback = cb; } @@ -1294,7 +1344,7 @@ void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int v */ int SSL_CTX_up_ref(SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); /** * no support multi-thread SSL here @@ -1309,7 +1359,7 @@ int SSL_CTX_up_ref(SSL_CTX *ctx) */ void SSL_set_security_level(SSL *ssl, int level) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); ssl->cert->sec_level = level; } @@ -1319,7 +1369,7 @@ void SSL_set_security_level(SSL *ssl, int level) */ int SSL_get_security_level(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->cert->sec_level; } @@ -1329,7 +1379,7 @@ int SSL_get_security_level(const SSL *ssl) */ int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); return ctx->verify_mode; } @@ -1341,7 +1391,7 @@ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) { long l; - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); l = ctx->session_timeout; ctx->session_timeout = t; @@ -1354,7 +1404,7 @@ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) */ long SSL_CTX_get_timeout(const SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); return ctx->session_timeout; } @@ -1364,7 +1414,7 @@ long SSL_CTX_get_timeout(const SSL_CTX *ctx) */ void SSL_set_read_ahead(SSL *ssl, int yes) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); ssl->rlayer.read_ahead = yes; } @@ -1374,7 +1424,7 @@ void SSL_set_read_ahead(SSL *ssl, int yes) */ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { - SSL_ASSERT(ctx); + SSL_ASSERT3(ctx); ctx->read_ahead = yes; } @@ -1384,7 +1434,7 @@ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) */ int SSL_get_read_ahead(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->rlayer.read_ahead; } @@ -1394,7 +1444,7 @@ int SSL_get_read_ahead(const SSL *ssl) */ long SSL_CTX_get_read_ahead(SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); return ctx->read_ahead; } @@ -1404,7 +1454,7 @@ long SSL_CTX_get_read_ahead(SSL_CTX *ctx) */ long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); return ctx->read_ahead; } @@ -1414,7 +1464,7 @@ long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) */ long SSL_set_time(SSL *ssl, long t) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ssl->session->time = t; @@ -1426,7 +1476,7 @@ long SSL_set_time(SSL *ssl, long t) */ long SSL_set_timeout(SSL *ssl, long t) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); ssl->session->timeout = t; @@ -1438,7 +1488,7 @@ long SSL_set_timeout(SSL *ssl, long t) */ long SSL_get_verify_result(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return SSL_METHOD_CALL(get_verify_result, ssl); } @@ -1448,7 +1498,7 @@ long SSL_get_verify_result(const SSL *ssl) */ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { - SSL_ASSERT(ctx); + SSL_ASSERT1(ctx); return ctx->param.depth; } @@ -1458,7 +1508,7 @@ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) */ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { - SSL_ASSERT(ctx); + SSL_ASSERT3(ctx); ctx->param.depth = depth; } @@ -1468,7 +1518,7 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) */ int SSL_get_verify_depth(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT1(ssl); return ssl->param.depth; } @@ -1478,7 +1528,7 @@ int SSL_get_verify_depth(const SSL *ssl) */ void SSL_set_verify_depth(SSL *ssl, int depth) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); ssl->param.depth = depth; } @@ -1488,7 +1538,7 @@ void SSL_set_verify_depth(SSL *ssl, int depth) */ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) { - SSL_ASSERT(ctx); + SSL_ASSERT3(ctx); ctx->verify_mode = mode; ctx->default_verify_callback = verify_callback; @@ -1499,7 +1549,7 @@ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509 */ void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) { - SSL_ASSERT(ssl); + SSL_ASSERT3(ssl); ssl->verify_mode = mode; ssl->verify_callback = verify_callback; diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index dbd82dc9c2..567a33e2c2 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -26,8 +26,10 @@ EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) EVP_PKEY *pkey; pkey = ssl_mem_zalloc(sizeof(EVP_PKEY)); - if (!pkey) - SSL_RET(failed1, "ssl_mem_zalloc\n"); + if (!pkey) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)"); + goto no_mem; + } if (ipk) { pkey->method = ipk->method; @@ -36,14 +38,16 @@ EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) } ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk); - if (ret) - SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n"); + if (ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(new) return %d", ret); + goto failed; + } return pkey; -failed2: +failed: ssl_mem_free(pkey); -failed1: +no_mem: return NULL; } @@ -60,6 +64,8 @@ EVP_PKEY* EVP_PKEY_new(void) */ void EVP_PKEY_free(EVP_PKEY *pkey) { + SSL_ASSERT3(pkey); + EVP_PKEY_METHOD_CALL(free, pkey); ssl_mem_free(pkey); @@ -78,22 +84,27 @@ EVP_PKEY *d2i_PrivateKey(int type, int ret; EVP_PKEY *pkey; - SSL_ASSERT(pp); - SSL_ASSERT(*pp); - SSL_ASSERT(length); + SSL_ASSERT2(pp); + SSL_ASSERT2(*pp); + SSL_ASSERT2(length); if (a && *a) { pkey = *a; } else { pkey = EVP_PKEY_new();; - if (!pkey) - SSL_RET(failed1, "EVP_PKEY_new\n"); + if (!pkey) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_new() return NULL"); + goto failed1; + } + m = 1; } ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); - if (ret) - SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n"); + if (ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(load) return %d", ret); + goto failed2; + } if (a) *a = pkey; @@ -112,8 +123,8 @@ failed1: */ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { - SSL_ASSERT(ctx); - SSL_ASSERT(pkey); + SSL_ASSERT1(ctx); + SSL_ASSERT1(pkey); if (ctx->cert->pkey == pkey) return 1; @@ -131,8 +142,8 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) */ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { - SSL_ASSERT(ssl); - SSL_ASSERT(pkey); + SSL_ASSERT1(ssl); + SSL_ASSERT1(pkey); if (ssl->cert->pkey == pkey) return 1; @@ -155,12 +166,16 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, EVP_PKEY *pk; pk = d2i_PrivateKey(0, NULL, &d, len); - if (!pk) - SSL_RET(failed1, "d2i_PrivateKey\n"); + if (!pk) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); + goto failed1; + } ret = SSL_CTX_use_PrivateKey(ctx, pk); - if (!ret) - SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + if (!ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_PrivateKey() return %d", ret); + goto failed2; + } return 1; @@ -180,12 +195,16 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, EVP_PKEY *pk; pk = d2i_PrivateKey(0, NULL, &d, len); - if (!pk) - SSL_RET(failed1, "d2i_PrivateKey\n"); + if (!pk) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); + goto failed1; + } ret = SSL_use_PrivateKey(ssl, pk); - if (!ret) - SSL_RET(failed2, "SSL_use_PrivateKey\n"); + if (!ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret); + goto failed2; + } return 1; diff --git a/components/openssl/library/ssl_stack.c b/components/openssl/library/ssl_stack.c index 5dbb69af9d..da836daf9c 100644 --- a/components/openssl/library/ssl_stack.c +++ b/components/openssl/library/ssl_stack.c @@ -31,12 +31,16 @@ OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) char **data; stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK)); - if (!stack) - SSL_RET(failed1, "ssl_mem_zalloc\n"); + if (!stack) { + SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (stack)"); + goto no_mem1; + } data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES); - if (!data) - SSL_RET(failed2, "ssl_mem_zalloc\n"); + if (!data) { + SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (data)"); + goto no_mem2; + } stack->data = data; stack->num_alloc = MIN_NODES; @@ -44,9 +48,9 @@ OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) return stack; -failed2: +no_mem2: ssl_mem_free(stack); -failed1: +no_mem1: return NULL; } @@ -63,7 +67,7 @@ OPENSSL_STACK *OPENSSL_sk_new_null(void) */ void OPENSSL_sk_free(OPENSSL_STACK *stack) { - SSL_ASSERT(stack); + SSL_ASSERT3(stack); ssl_mem_free(stack->data); ssl_mem_free(stack); diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index d0426db18c..ef0503c053 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -34,8 +34,10 @@ X509* __X509_new(X509 *ix) X509 *x; x = ssl_mem_zalloc(sizeof(X509)); - if (!x) - SSL_RET(failed1, "ssl_mem_zalloc\n"); + if (!x) { + SSL_DEBUG(SSL_X509_ERROR_LEVEL, "no enough memory > (x)"); + goto no_mem; + } if (ix) x->method = ix->method; @@ -43,14 +45,16 @@ X509* __X509_new(X509 *ix) x->method = X509_method(); ret = X509_METHOD_CALL(new, x, ix); - if (ret) - SSL_RET(failed2, "x509_new\n"); + if (ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(new) return %d", ret); + goto failed; + } return x; -failed2: +failed: ssl_mem_free(x); -failed1: +no_mem: return NULL; } @@ -67,6 +71,8 @@ X509* X509_new(void) */ void X509_free(X509 *x) { + SSL_ASSERT3(x); + X509_METHOD_CALL(free, x); ssl_mem_free(x); @@ -82,21 +88,25 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) int ret; X509 *x; - SSL_ASSERT(buffer); - SSL_ASSERT(len); + SSL_ASSERT2(buffer); + SSL_ASSERT2(len); if (cert && *cert) { x = *cert; } else { x = X509_new(); - if (!x) - SSL_RET(failed1, "X509_new\n"); + if (!x) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL"); + goto failed1; + } m = 1; } ret = X509_METHOD_CALL(load, x, buffer, len); - if (ret) - SSL_RET(failed2, "x509_load\n"); + if (ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret); + goto failed2; + } return x; @@ -112,8 +122,8 @@ failed1: */ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) { - SSL_ASSERT(ctx); - SSL_ASSERT(x); + SSL_ASSERT1(ctx); + SSL_ASSERT1(x); if (ctx->client_CA == x) return 1; @@ -130,8 +140,8 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { - SSL_ASSERT(ssl); - SSL_ASSERT(x); + SSL_ASSERT1(ssl); + SSL_ASSERT1(x); if (ssl->client_CA == x) return 1; @@ -148,8 +158,8 @@ int SSL_add_client_CA(SSL *ssl, X509 *x) */ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { - SSL_ASSERT(ctx); - SSL_ASSERT(x); + SSL_ASSERT1(ctx); + SSL_ASSERT1(x); if (ctx->cert->x509 == x) return 1; @@ -166,8 +176,8 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) */ int SSL_use_certificate(SSL *ssl, X509 *x) { - SSL_ASSERT(ssl); - SSL_ASSERT(x); + SSL_ASSERT1(ssl); + SSL_ASSERT1(x); if (ssl->cert->x509 == x) return 1; @@ -184,7 +194,7 @@ int SSL_use_certificate(SSL *ssl, X509 *x) */ X509 *SSL_get_certificate(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); return ssl->cert->x509; } @@ -199,12 +209,16 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, X509 *x; x = d2i_X509(NULL, d, len); - if (!x) - SSL_RET(failed1, "d2i_X509\n"); + if (!x) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); + goto failed1; + } ret = SSL_CTX_use_certificate(ctx, x); - if (!ret) - SSL_RET(failed2, "SSL_CTX_use_certificate\n"); + if (!ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_certificate() return %d", ret); + goto failed2; + } return 1; @@ -224,12 +238,16 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, X509 *x; x = d2i_X509(NULL, d, len); - if (!x) - SSL_RET(failed1, "d2i_X509\n"); + if (!x) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); + goto failed1; + } ret = SSL_use_certificate(ssl, x); - if (!ret) - SSL_RET(failed2, "SSL_use_certificate\n"); + if (!ret) { + SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_certificate() return %d", ret); + goto failed2; + } return 1; @@ -260,7 +278,7 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) */ X509 *SSL_get_peer_certificate(const SSL *ssl) { - SSL_ASSERT(ssl); + SSL_ASSERT2(ssl); return ssl->session->peer; } diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 15015107f0..b175b38262 100755 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -25,13 +25,7 @@ #include "mbedtls/error.h" #include "mbedtls/certs.h" -#if 0 - #define DEBUG_LOAD_BUF_STRING(str) SSL_DEBUG(1, "%s\n", str) -#else - #define DEBUG_LOAD_BUF_STRING(str) -#endif - -#define X509_INFO_STRING_LENGTH 1024 +#define X509_INFO_STRING_LENGTH 8192 struct ssl_pm { @@ -63,13 +57,36 @@ struct pkey_pm mbedtls_pk_context *ex_pkey; }; - unsigned int max_content_len; - /*********************************************************************************************/ /************************************ SSL arch interface *************************************/ +#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG + +/* mbedtls debug level */ +#define MBEDTLS_DEBUG_LEVEL 4 + +/** + * @brief mbedtls debug function + */ +static void ssl_platform_debug(void *ctx, int level, + const char *file, int line, + const char *str) +{ + /* Shorten 'file' from the whole file path to just the filename + + This is a bit wasteful because the macros are compiled in with + the full _FILE_ path in each case. + */ + char *file_sep = rindex(file, '/'); + if(file_sep) + file = file_sep + 1; + + SSL_DEBUG(SSL_DEBUG_ON, "%s:%d %s", file, line, str); +} +#endif + /** * @brief create SSL low-level object */ @@ -87,11 +104,13 @@ int ssl_pm_new(SSL *ssl) const SSL_METHOD *method = ssl->method; ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm)); - if (!ssl_pm) - SSL_ERR(ret, failed1, "ssl_mem_zalloc\n"); + if (!ssl_pm) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (ssl_pm)"); + goto no_mem; + } max_content_len = ssl->ctx->read_buffer_len; - + mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); @@ -101,8 +120,10 @@ int ssl_pm_new(SSL *ssl) mbedtls_ssl_init(&ssl_pm->ssl); ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); - if (ret) - SSL_ERR(ret, failed2, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ctr_drbg_seed() return -0x%x", -ret); + goto mbedtls_err1; + } if (method->endpoint) { endpoint = MBEDTLS_SSL_IS_SERVER; @@ -110,8 +131,10 @@ int ssl_pm_new(SSL *ssl) endpoint = MBEDTLS_SSL_IS_CLIENT; } ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); - if (ret) - SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_config_defaults() return -0x%x", -ret); + goto mbedtls_err2; + } if (TLS_ANY_VERSION != ssl->version) { if (TLS1_2_VERSION == ssl->version) @@ -132,11 +155,18 @@ int ssl_pm_new(SSL *ssl) mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); +#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG + mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL); + mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL); +#else mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); +#endif ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); - if (ret) - SSL_ERR(ret, failed3, "mbedtls_ssl_setup:[-0x%x]\n", -ret); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_setup() return -0x%x", -ret); + goto mbedtls_err2; + } mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); @@ -144,13 +174,13 @@ int ssl_pm_new(SSL *ssl) return 0; -failed3: +mbedtls_err2: mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); -failed2: +mbedtls_err1: mbedtls_entropy_free(&ssl_pm->entropy); ssl_mem_free(ssl_pm); -failed1: +no_mem: return -1; } @@ -222,16 +252,12 @@ static int mbedtls_handshake( mbedtls_ssl_context *ssl ) { int ret = 0; - if (ssl == NULL || ssl->conf == NULL) - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { ret = mbedtls_ssl_handshake_step(ssl); - - SSL_DEBUG(1, "ssl ret %d state %d heap %d\n", - ret, ssl->state, system_get_free_heap_size()); - + + SSL_DEBUG(SSL_PLATFORM_DEBUG_LEVEL, "ssl ret %d state %d", ret, ssl->state); + if (ret != 0) break; } @@ -248,19 +274,15 @@ int ssl_pm_handshake(SSL *ssl) if (mbed_ret) return 0; - SSL_DEBUG(1, "ssl_speed_up_enter "); ssl_speed_up_enter(); - SSL_DEBUG(1, "OK\n"); - + while((mbed_ret = mbedtls_handshake(&ssl_pm->ssl)) != 0) { if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) { break; } } - - SSL_DEBUG(1, "ssl_speed_up_exit "); + ssl_speed_up_exit(); - SSL_DEBUG(1, "OK\n"); if (!mbed_ret) { struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; @@ -270,7 +292,7 @@ int ssl_pm_handshake(SSL *ssl) x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); } else { ret = 0; - SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -mbed_ret); } return ret; @@ -430,23 +452,28 @@ int x509_pm_show_info(X509 *x) return -1; buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH); - if (!buf) - SSL_RET(failed1, ""); + if (!buf) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (buf)"); + goto no_mem; + } ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1, "", x509_crt); - if (ret <= 0) - SSL_RET(failed2, ""); + if (ret <= 0) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_x509_crt_info() return -0x%x", -ret); + goto mbedtls_err1; + } + buf[ret] = 0; ssl_mem_free(buf); - SSL_DEBUG(1, "%s", buf); + SSL_DEBUG(SSL_DEBUG_ON, "%s", buf); return 0; -failed2: +mbedtls_err1: ssl_mem_free(buf); -failed1: +no_mem: return -1; } @@ -455,8 +482,10 @@ int x509_pm_new(X509 *x, X509 *m_x) struct x509_pm *x509_pm; x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm)); - if (!x509_pm) - SSL_RET(failed1, "ssl_mem_zalloc\n"); + if (!x509_pm) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm)"); + goto failed1; + } x->x509_pm = x509_pm; @@ -498,34 +527,38 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) if (!x509_pm->x509_crt) { x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt)); - if (!x509_pm->x509_crt) - SSL_RET(failed1, "ssl_mem_malloc\n"); + if (!x509_pm->x509_crt) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm->x509_crt)"); + goto no_mem; + } } load_buf = ssl_mem_malloc(len + 1); - if (!load_buf) - SSL_RET(failed2, "ssl_mem_malloc\n"); + if (!load_buf) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)"); + goto failed; + } ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; - DEBUG_LOAD_BUF_STRING(load_buf); - mbedtls_x509_crt_init(x509_pm->x509_crt); ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1); ssl_mem_free(load_buf); - if (ret) - SSL_RET(failed2, "mbedtls_x509_crt_parse, return [-0x%x]\n", -ret); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_x509_crt_parse return -0x%x", -ret); + goto failed; + } return 0; -failed2: +failed: mbedtls_x509_crt_free(x509_pm->x509_crt); ssl_mem_free(x509_pm->x509_crt); x509_pm->x509_crt = NULL; -failed1: +no_mem: return -1; } @@ -574,34 +607,38 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) if (!pkey_pm->pkey) { pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context)); - if (!pkey_pm->pkey) - SSL_RET(failed1, "ssl_mem_malloc\n"); + if (!pkey_pm->pkey) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (pkey_pm->pkey)"); + goto no_mem; + } } load_buf = ssl_mem_malloc(len + 1); - if (!load_buf) - SSL_RET(failed2, "ssl_mem_malloc\n"); + if (!load_buf) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)"); + goto failed; + } ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; - DEBUG_LOAD_BUF_STRING(load_buf); - mbedtls_pk_init(pkey_pm->pkey); ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0); ssl_mem_free(load_buf); - if (ret) - SSL_RET(failed2, "mbedtls_pk_parse_key, return [-0x%x]\n", -ret); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_pk_parse_key return -0x%x", -ret); + goto failed; + } return 0; -failed2: +failed: mbedtls_pk_free(pkey_pm->pkey); ssl_mem_free(pkey_pm->pkey); pkey_pm->pkey = NULL; -failed1: +no_mem: return -1; } diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index ae3b849ca3..8c7a31338b 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -14,15 +14,10 @@ #include "ssl_port.h" -#ifdef ESP32_IDF_PLATFORM - -#include "string.h" -#include "malloc.h" - /*********************************************************************************************/ /********************************* SSL general interface *************************************/ -void* ssl_mem_zalloc(size_t size) +void *ssl_mem_zalloc(size_t size) { void *p = malloc(size); @@ -32,35 +27,3 @@ void* ssl_mem_zalloc(size_t size) return p; } -void *ssl_mem_malloc(size_t size) -{ - return malloc(size); -} - -void ssl_mem_free(void *p) -{ - free(p); -} - -void* ssl_memcpy(void *to, const void *from, size_t size) -{ - return memcpy(to, from, size); -} - -size_t ssl_strlen(const char *src) -{ - return strlen(src); -} - -void ssl_speed_up_enter(void) -{ - -} - -void ssl_speed_up_exit(void) -{ - -} - -#endif - From 8c25a0fd9d530bfaf3d665ac4649e9e543411928 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 16 Jan 2017 19:52:23 +0800 Subject: [PATCH 016/139] time: workaround for FRC_TIMER_INT_REG write issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases (when RTC register reads are performed from the APP CPU), a write to FRC_TIMER_INT_REG may be lost on the bus. Writing to another DPORT register immediately before or after that works around the issue. We write one dummy value to an address which doesn’t have any register associated with it. Fixes https://github.com/espressif/arduino-esp32/issues/120 --- components/newlib/test/test_time.c | 50 ++++++++++++++++++++++++++++++ components/newlib/time.c | 5 +++ 2 files changed, 55 insertions(+) create mode 100644 components/newlib/test/test_time.c diff --git a/components/newlib/test/test_time.c b/components/newlib/test/test_time.c new file mode 100644 index 0000000000..a230a220bc --- /dev/null +++ b/components/newlib/test/test_time.c @@ -0,0 +1,50 @@ +#include +#include +#include "unity.h" +#include "driver/adc.h" +#include +#include +#include "soc/rtc_cntl_reg.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "sdkconfig.h" + + +// https://github.com/espressif/arduino-esp32/issues/120 +TEST_CASE("Reading RTC registers on APP CPU doesn't affect clock", "[newlib]") +{ + // This runs on APP CPU: + void time_adc_test_task(void* arg) + { + for (int i = 0; i < 200000; ++i) { + // wait for 20us, reading one of RTC registers + uint32_t ccount = xthal_get_ccount(); + while (xthal_get_ccount() - ccount < 20 * CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) { + volatile uint32_t val = REG_READ(RTC_CNTL_STATE0_REG); + (void) val; + } + } + SemaphoreHandle_t * p_done = (SemaphoreHandle_t *) arg; + xSemaphoreGive(*p_done); + vTaskDelay(1); + vTaskDelete(NULL); + } + + SemaphoreHandle_t done = xSemaphoreCreateBinary(); + xTaskCreatePinnedToCore(&time_adc_test_task, "time_adc", 4096, &done, 5, NULL, 1); + + // This runs on PRO CPU: + for (int i = 0; i < 4; ++i) { + struct timeval tv_start; + gettimeofday(&tv_start, NULL); + vTaskDelay(1000/portTICK_PERIOD_MS); + struct timeval tv_stop; + gettimeofday(&tv_stop, NULL); + float time_sec = tv_stop.tv_sec - tv_start.tv_sec + 1e-6f * (tv_stop.tv_usec - tv_start.tv_usec); + printf("(0) time taken: %f sec\n", time_sec); + TEST_ASSERT_TRUE(fabs(time_sec - 1.0f) < 0.1); + } + TEST_ASSERT_TRUE(xSemaphoreTake(done, 5000 / portTICK_RATE_MS)); +} + diff --git a/components/newlib/time.c b/components/newlib/time.c index c9fa72eeee..004b7398c2 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -83,6 +83,11 @@ static volatile uint64_t s_microseconds = 0; static void IRAM_ATTR frc_timer_isr() { + // Write to FRC_TIMER_INT_REG may not take effect in some cases (root cause TBD) + // This extra write works around this issue. + // There is no register at DR_REG_FRC_TIMER_BASE + 0x60 (in fact, any DPORT register address can be used). + WRITE_PERI_REG(DR_REG_FRC_TIMER_BASE + 0x60, 0xabababab); + // Clear interrupt status WRITE_PERI_REG(FRC_TIMER_INT_REG(0), FRC_TIMER_INT_CLR); s_microseconds += FRC1_ISR_PERIOD_US; } From 7776d3e0652090ad491cf23698560b7787c8b781 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 16 Jan 2017 19:53:10 +0800 Subject: [PATCH 017/139] time: only define {get,set}_boot_time if FRC1 or RTC is used as time source Fixes https://github.com/espressif/esp-idf/issues/238 --- components/newlib/time.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/newlib/time.c b/components/newlib/time.c index 004b7398c2..30c7ca7f40 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -94,6 +94,7 @@ static void IRAM_ATTR frc_timer_isr() #endif // WITH_FRC1 +#if defined(WITH_RTC) || defined(WITH_FRC1) static void set_boot_time(uint64_t time_us) { _lock_acquire(&s_boot_time_lock); @@ -118,6 +119,7 @@ static uint64_t get_boot_time() _lock_release(&s_boot_time_lock); return result; } +#endif //defined(WITH_RTC) || defined(WITH_FRC1) void esp_setup_time_syscalls() { From 71ab455c8719a683eed20bddff8712069e3d0f3c Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Mon, 16 Jan 2017 22:03:58 +0000 Subject: [PATCH 018/139] Allow writes to encrypted partitions There is a size alignment requirement but it is checked by spi_flash_write_encrypted. However, this check flat-out bans encrypted writes. --- components/spi_flash/partition.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index 490efbb32c..45f66d696b 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -230,10 +230,6 @@ esp_err_t esp_partition_write(const esp_partition_t* partition, size_t dst_offset, const void* src, size_t size) { assert(partition != NULL); - //todo : need add ecrypt write support ,size must be 32-bytes align - if(partition->encrypted == true) { - return ESP_FAIL; - } if (dst_offset > partition->size) { return ESP_ERR_INVALID_ARG; } From f9ac7657e382257d6754b2fef741aee981fc670f Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Tue, 17 Jan 2017 13:51:44 +0800 Subject: [PATCH 019/139] component/bt : update bt lib to fix flash operation bug --- components/bt/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/lib b/components/bt/lib index 566acfd8c6..52639e93f4 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 566acfd8c61a4ba0fb6b9026c89488b01af0fff0 +Subproject commit 52639e93f42b426c5f3d29935f3f17fb1c6e2169 From f4d5d151aa2a9201a0844e3081d5428a941d2eef Mon Sep 17 00:00:00 2001 From: Wu Jian Gang Date: Tue, 17 Jan 2017 16:52:42 +0800 Subject: [PATCH 020/139] esp32: add get idf version api --- components/esp32/include/esp_system.h | 7 ++++++- components/esp32/system_api.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index e1f46de803..30701761ad 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -124,7 +124,12 @@ esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated)); */ const char* system_get_sdk_version(void) __attribute__ ((deprecated)); - +/** + * Get IDF version + * + * @return constant string from IDF_VER + */ +const char* esp_get_idf_version(void); #ifdef __cplusplus } diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 2f834a9eac..d984af78a7 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -179,4 +179,8 @@ const char* system_get_sdk_version(void) return "master"; } +const char* esp_get_idf_version(void) +{ + return IDF_VER; +} From 3c8235d40df124382cce8f8fade81ccd4a0706f0 Mon Sep 17 00:00:00 2001 From: Wu Jian Gang Date: Tue, 17 Jan 2017 17:44:25 +0800 Subject: [PATCH 021/139] lwip: Allow config TCP_MAXRTX & TCP_SYNMAXRTX in menuconfig --- components/lwip/Kconfig | 32 ++++++++++++++------ components/lwip/include/lwip/port/lwipopts.h | 4 +-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 760e035c8c..f7bae32581 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -47,27 +47,41 @@ config LWIP_SO_RCVBUF Enabling this option allows checking for available data on a netconn. config LWIP_DHCP_MAX_NTP_SERVERS - int "Maximum number of NTP servers" - default 1 - range 1 16 - help - Set maxumum number of NTP servers used by LwIP SNTP module. - First argument of sntp_setserver/sntp_setservername functions - is limited to this value. + int "Maximum number of NTP servers" + default 1 + range 1 16 + help + Set maximum number of NTP servers used by LwIP SNTP module. + First argument of sntp_setserver/sntp_setservername functions + is limited to this value. config LWIP_IP_FRAG bool "Enable fragment outgoing IP packets" default 0 - help + help Enabling this option allows fragmenting outgoing IP packets if their size exceeds MTU. config LWIP_IP_REASSEMBLY bool "Enable reassembly incoming fragmented IP packets" default 0 - help + help Enabling this option allows reassemblying incoming fragmented IP packets. +config TCP_MAXRTX + int "Maximum number of retransmissions of data segments" + default 12 + range 3 12 + help + Set maximum number of retransmissions of data segments. + +config TCP_SYNMAXRTX + int "Maximum number of retransmissions of SYN segments" + default 6 + range 3 12 + help + Set maximum number of retransmissions of SYN segments. + endmenu diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 6d1dfbd497..638c1f7404 100644 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -288,12 +288,12 @@ /** * TCP_MAXRTX: Maximum number of retransmissions of data segments. */ -#define TCP_MAXRTX 12 //(*(volatile uint32*)0x600011E8) +#define TCP_MAXRTX CONFIG_TCP_MAXRTX /** * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. */ -#define TCP_SYNMAXRTX 6 //(*(volatile uint32*)0x600011E4) +#define TCP_SYNMAXRTX CONFIG_TCP_SYNMAXRTX /** * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. From 963c3aa16abeed87f2e896f19b8c2282ae52efef Mon Sep 17 00:00:00 2001 From: Wu Jian Gang Date: Tue, 17 Jan 2017 17:55:29 +0800 Subject: [PATCH 022/139] gitignore: Update gitignore for examples --- .gitignore | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 25a5a30910..f11370493d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,10 +15,13 @@ GPATH .#* \#*# +# eclipse setting +.settings + # Example project files -examples/*/sdkconfig -examples/*/sdkconfig.old -examples/*/build +examples/*/*/sdkconfig +examples/*/*/sdkconfig.old +examples/*/*/build #Doc build artifacts docs/_build/ From 799be9fa3a20c2ce606e3dd4f4b1242561fe8364 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Tue, 17 Jan 2017 18:42:11 +0800 Subject: [PATCH 023/139] component/bt : fix gatt server table bugs 1. fix gatt server table bugs 2. fix blufi a minor bug --- .../btc/profile/esp/blufi/blufi_prf.c | 2 +- components/bt/bluedroid/stack/gatt/gatt_db.c | 22 +++++++++---------- components/bt/bluedroid/stack/gatt/gatt_sr.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c b/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c index 7866ca0f80..15b4ccf5a9 100644 --- a/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c +++ b/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c @@ -198,7 +198,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_e2p, (GATT_PERM_READ), - (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY), + (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY), NULL, NULL); break; case BLUFI_CHAR_E2P_UUID: /* ESP32 to Phone */ diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index fd27959d96..a574b5d1ed 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -651,27 +651,28 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, case GATT_UUID_INCLUDE_SERVICE: return GATT_NOT_FOUND; default: - if (p_cur->p_value->attr_val.attr_max_len < length) { + if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len < length) { GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length"); return GATT_INVALID_ATTR_LEN; - } else { + } else if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len > 0) { memcpy(p_cur->p_value->attr_val.attr_val, value, length); p_cur->p_value->attr_val.attr_len = length; + } else { + return GATT_INVALID_ATTR_LEN; } break; } } else { - if (p_cur->p_value->attr_val.attr_max_len < length) { + if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len < length) { GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length"); - } else { + } else if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len > 0) { memcpy(p_cur->p_value->attr_val.attr_val, value, length); p_cur->p_value->attr_val.attr_len = length; + } else { + return GATT_INVALID_ATTR_LEN; } - } - break; - } p_cur = p_cur->p_next; @@ -699,8 +700,9 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, UINT16 *length, UINT8 **value) { tGATT_ATTR16 *p_cur; - GATT_TRACE_DEBUG("***********%s*************\n", __func__); + GATT_TRACE_DEBUG("attr_handle = %x\n", attr_handle); + if (p_db == NULL) { GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db is NULL.\n"); return GATT_INVALID_PDU; @@ -713,7 +715,6 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; while (p_cur != NULL) { - LOG_ERROR("p_ur->handle = %x\n", p_cur->handle); if (p_cur->handle == attr_handle) { if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) { @@ -722,7 +723,7 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, case GATT_UUID_INCLUDE_SERVICE: break; default: - if (p_cur->p_value->attr_val.attr_len != 0) { + if (p_cur->p_value && p_cur->p_value->attr_val.attr_len != 0) { *length = p_cur->p_value->attr_val.attr_len; *value = p_cur->p_value->attr_val.attr_val; return GATT_SUCCESS; @@ -748,7 +749,6 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, } - p_cur = p_cur->p_next; } diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index a817ad1478..a7ee3b5ad0 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -1159,7 +1159,7 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE); gatt_dequeue_sr_cmd(p_tcb); } - } else { + } else if (reason == GATT_SUCCESS || reason == GATT_STACK_RSP) { attp_send_sr_msg(p_tcb, p_msg); gatt_dequeue_sr_cmd(p_tcb); } From 5508826509314c7a0291a421795696dee7402611 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Tue, 17 Jan 2017 20:13:25 +0800 Subject: [PATCH 024/139] component/bt : fix gatts demo mistakes & unpeg notify bug --- .../btc/profile/std/gatt/btc_gattc.c | 2 +- .../bluetooth/gatt_server/main/gatts_demo.c | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c index 537be9092c..71e01c76e0 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -448,7 +448,7 @@ static void btc_gattc_unreg_for_notify(btc_ble_gattc_args_t *arg) memset(¶m, 0, sizeof(esp_ble_gattc_cb_param_t)); param.unreg_for_notify.status = status; memcpy(¶m.unreg_for_notify.srvc_id, &arg->unreg_for_notify.service_id, sizeof(esp_gatt_srvc_id_t)); - memcpy(¶m.unreg_for_notify.char_id, &arg->unreg_for_notify.service_id, sizeof(esp_gatt_id_t)); + memcpy(¶m.unreg_for_notify.char_id, &arg->unreg_for_notify.char_id, sizeof(esp_gatt_id_t)); btc_gattc_cb_to_app(ESP_GATTC_UNREG_FOR_NOTIFY_EVT, arg->unreg_for_notify.gattc_if, ¶m); } diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 98feaa2240..18de5cc7b7 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -247,15 +247,15 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i switch (event) { case ESP_GATTS_REG_EVT: ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; + gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; esp_ble_gap_set_device_name(TEST_DEVICE_NAME); esp_ble_gap_config_adv_data(&test_adv_data); - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B); + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B); break; case ESP_GATTS_READ_EVT: { ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); @@ -284,13 +284,13 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; case ESP_GATTS_CREATE_EVT: ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; + gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, + esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, NULL, NULL); @@ -301,10 +301,10 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, + gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); break; @@ -326,7 +326,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], param->connect.is_connected); - gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; + gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; break; case ESP_GATTS_DISCONNECT_EVT: case ESP_GATTS_OPEN_EVT: From fb7b2180914d9619b551f0ab1b9530b08de45f6a Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 17 Jan 2017 18:53:29 +0100 Subject: [PATCH 025/139] Fixed broken links --- docs/api/bluetooth/esp_gap_ble.rst | 2 +- docs/api/peripherals/sigmadelta.rst | 2 +- docs/api/peripherals/spi_master.rst | 2 +- docs/api/protocols/mdns.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/bluetooth/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst index 088ab27dba..40ccdba50f 100644 --- a/docs/api/bluetooth/esp_gap_ble.rst +++ b/docs/api/bluetooth/esp_gap_ble.rst @@ -27,7 +27,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_gap_ble_api.h `_ + * `bt/bluedroid/api/include/esp_gap_ble_api.h `_ Macros diff --git a/docs/api/peripherals/sigmadelta.rst b/docs/api/peripherals/sigmadelta.rst index b03f049421..56e4d77e72 100644 --- a/docs/api/peripherals/sigmadelta.rst +++ b/docs/api/peripherals/sigmadelta.rst @@ -10,7 +10,7 @@ This driver configures the channels of the sigma-delta module. Application Example ------------------- -Sigma-delta Modulation example: `examples/14_sigmadelta `_. +Sigma-delta Modulation example: `examples/peripherals/sigmadelta `_. API Reference ------------- diff --git a/docs/api/peripherals/spi_master.rst b/docs/api/peripherals/spi_master.rst index 5b57d85f42..012d1832ce 100644 --- a/docs/api/peripherals/spi_master.rst +++ b/docs/api/peripherals/spi_master.rst @@ -111,7 +111,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `drivers/include/drivers/spi_master.h `_ + * `driver/include/driver/spi_master.h `_ Macros ^^^^^^ diff --git a/docs/api/protocols/mdns.rst b/docs/api/protocols/mdns.rst index d674e25a08..6214883965 100644 --- a/docs/api/protocols/mdns.rst +++ b/docs/api/protocols/mdns.rst @@ -163,7 +163,7 @@ Example of using the methods above: Application Example ------------------- -mDNS server/scanner example: `examples/protocols/mdsn `_. +mDNS server/scanner example: `examples/protocols/mdns `_. API Reference ------------- From 5ae9647667619e862fd9969f44edd1cefd52e3b6 Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 17 Jan 2017 19:12:48 +0100 Subject: [PATCH 026/139] Added links to examples in API documentation --- docs/api/peripherals/spi_master.rst | 5 +++++ docs/api/peripherals/uart.rst | 8 +++----- docs/api/system/deep_sleep.rst | 5 +++++ docs/api/system/log.rst | 8 +++++--- docs/api/system/ota.rst | 5 +++++ docs/api/wifi/esp_wifi.rst | 8 +++----- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/docs/api/peripherals/spi_master.rst b/docs/api/peripherals/spi_master.rst index 012d1832ce..9e5c0eb636 100644 --- a/docs/api/peripherals/spi_master.rst +++ b/docs/api/peripherals/spi_master.rst @@ -105,6 +105,11 @@ on the transmission. For received data, use ``rx_data`` and set ``SPI_USE_RXDATA not touch the ``tx_buffer`` or ``rx_buffer`` members, because they use the same memory locations as ``tx_data`` and ``rx_data``. +Application Example +------------------- + +Display graphics on the ILI9341-based 320x240 LCD: `examples/peripherals/spi_master `_. + API Reference ------------- diff --git a/docs/api/peripherals/uart.rst b/docs/api/peripherals/uart.rst index 8684b2afa3..b00b4e0648 100644 --- a/docs/api/peripherals/uart.rst +++ b/docs/api/peripherals/uart.rst @@ -6,18 +6,16 @@ Overview `Instructions`_ +.. _Instructions: ../template.html + Application Example ------------------- -`Instructions`_ +Configure uart settings and install uart driver to read/write using UART0 and UART1 interfaces: `examples/peripherals/uart `_. API Reference ------------- -`Instructions`_ - -.. _Instructions: ../template.html - Header Files ^^^^^^^^^^^^ diff --git a/docs/api/system/deep_sleep.rst b/docs/api/system/deep_sleep.rst index 9e6642fd90..393d5f025e 100644 --- a/docs/api/system/deep_sleep.rst +++ b/docs/api/system/deep_sleep.rst @@ -87,3 +87,8 @@ The following function can be used to enter deep sleep once wakeup sources are c .. doxygenfunction:: esp_deep_sleep_start +Application Example +------------------- + +Implementation of basic functionality of deep sleep is shown in `protocols/sntp `_ example, where ESP module is periodically waken up to retrive time from NTP server. + diff --git a/docs/api/system/log.rst b/docs/api/system/log.rst index d812740bb2..24d3bef80a 100644 --- a/docs/api/system/log.rst +++ b/docs/api/system/log.rst @@ -3,9 +3,11 @@ Application Example ------------------- -`Instructions`_ - -.. _Instructions: ../template.html +Log library is commonly used by most of esp-idf components and examples. For demonstration of log functionality check `examples `_ folder of `espressif/esp-idf `_ repository, that among others, contains the following examples: + +* `system/ota `_ +* `storage/sd_card `_ +* `protocols/https_request `_ API Reference ------------- diff --git a/docs/api/system/ota.rst b/docs/api/system/ota.rst index a4984620f6..ce2fdba635 100644 --- a/docs/api/system/ota.rst +++ b/docs/api/system/ota.rst @@ -1,6 +1,11 @@ OTA === +Application Example +------------------- + +Demonstration of OTA (over the air) firmware update workflow: `examples/system/ota `_. + API Reference ------------- diff --git a/docs/api/wifi/esp_wifi.rst b/docs/api/wifi/esp_wifi.rst index 1fe832a2c5..247ddf7522 100644 --- a/docs/api/wifi/esp_wifi.rst +++ b/docs/api/wifi/esp_wifi.rst @@ -6,18 +6,16 @@ Overview `Instructions`_ +.. _Instructions: ../template.html + Application Example ------------------- -`Instructions`_ +Simple code showing how to connect ESP32 module to an Access Point: `esp-idf-template `_. API Reference ------------- -`Instructions`_ - -.. _Instructions: ../template.html - Header Files ^^^^^^^^^^^^ From 03c14809f96d43352e76c4e3282b8ed6bd70b412 Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 17 Jan 2017 20:03:26 +0100 Subject: [PATCH 027/139] Updated links to point directly to example folder, fixed names --- docs/api/bluetooth/controller_vhci.rst | 10 ++++------ docs/api/bluetooth/esp_blufi.rst | 6 +++--- docs/api/bluetooth/esp_gap_ble.rst | 16 ++++++---------- docs/api/bluetooth/esp_gattc.rst | 12 +++++------- docs/api/bluetooth/esp_gatts.rst | 13 +++++-------- docs/api/storage/nvs_flash.rst | 6 +++--- 6 files changed, 26 insertions(+), 37 deletions(-) diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 3868d9cec7..dfad1af25e 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -6,19 +6,17 @@ Overview `Instructions`_ +.. _Instructions: ../template.html + Application Example ------------------- -Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`bluetooth/ble_adv `_ +`ble_adv `_ This is a BLE advertising demo with virtual HCI interface. Send Reset/ADV_PARAM/ADV_DATA/ADV_ENABLE HCI command for BLE advertising. -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- diff --git a/docs/api/bluetooth/esp_blufi.rst b/docs/api/bluetooth/esp_blufi.rst index a281c3d3d6..442e54f5ca 100644 --- a/docs/api/bluetooth/esp_blufi.rst +++ b/docs/api/bluetooth/esp_blufi.rst @@ -11,11 +11,11 @@ Use should concern these things: Application Example ------------------- -Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`bluetooth/blufi `_ +`blufi `_ -This is a BLUFI demo. This demo can set ESP32's wifi to softap/station/softap&station mode and config wifi connections. + This is a BLUFI demo. This demo can set ESP32's wifi to softap/station/softap&station mode and config wifi connections. API Reference diff --git a/docs/api/bluetooth/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst index 40ccdba50f..f53b8d56ad 100644 --- a/docs/api/bluetooth/esp_gap_ble.rst +++ b/docs/api/bluetooth/esp_gap_ble.rst @@ -1,25 +1,21 @@ GAP API -======== +======= Overview -------- `Instructions`_ +.. _Instructions: ../template.html + Application Example ------------------- -Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following examples: -`14_gatts_demo `_ -`15_gattc_demo `_ - -The two demos use different gap api, such like advertising, scan, set device name and others. - -`Instructions`_ - -.. _Instructions: ../template.html +`gatt_server `_, `gatt_client `_ + The two demos use different gap api, such like advertising, scan, set device name and others. API Reference ------------- diff --git a/docs/api/bluetooth/esp_gattc.rst b/docs/api/bluetooth/esp_gattc.rst index eada883fd7..adfc225dfa 100644 --- a/docs/api/bluetooth/esp_gattc.rst +++ b/docs/api/bluetooth/esp_gattc.rst @@ -6,18 +6,16 @@ Overview `Instructions`_ +.. _Instructions: ../template.html + Application Example ------------------- -Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`15_gattc_demo `_ +`gatt_client `_ -This is a gatt client demo. This demo can scan devices, connect to the gatt server and discover the service. - -`Instructions`_ - -.. _Instructions: ../template.html + This is a gatt client demo. This demo can scan devices, connect to the gatt server and discover the service. API Reference diff --git a/docs/api/bluetooth/esp_gatts.rst b/docs/api/bluetooth/esp_gatts.rst index 877840402c..4753490d4d 100644 --- a/docs/api/bluetooth/esp_gatts.rst +++ b/docs/api/bluetooth/esp_gatts.rst @@ -6,19 +6,16 @@ Overview `Instructions`_ +.. _Instructions: ../template.html + Application Example ------------------- -Check `/examples `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: -`14_gatts_demo `_ - -This is a gatt server demo. Use gatt api to create a gatt server with send advertising. This gatt server can be connected and the service can be discovery. - -`Instructions`_ - -.. _Instructions: ../template.html +`gatt_server `_ + This is a gatt server demo. Use gatt api to create a gatt server with send advertising. This gatt server can be connected and the service can be discovery. API Reference ------------- diff --git a/docs/api/storage/nvs_flash.rst b/docs/api/storage/nvs_flash.rst index 00094d8697..9e97c3a811 100644 --- a/docs/api/storage/nvs_flash.rst +++ b/docs/api/storage/nvs_flash.rst @@ -3,9 +3,9 @@ Application Example ------------------- -Two examples are provided in ESP-IDF examples directory: +Two examples are provided in ESP-IDF `examples/storage `_ directory: -`storage/nvs_rw_value `_ +`nvs_rw_value `_ Demonstrates how to read and write a single integer value using NVS. @@ -13,7 +13,7 @@ Two examples are provided in ESP-IDF examples directory: Example also shows how to check if read / write operation was successful, or certain value is not initialized in NVS. Diagnostic is provided in plain text to help track program flow and capture any issues on the way. -`storage/nvs_rw_blob `_ +`nvs_rw_blob `_ Demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP32 module restarts. From 46d8ece20e5e48fd0f0abeccd62fc62284f92d35 Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 17 Jan 2017 20:37:27 +0100 Subject: [PATCH 028/139] Docs folder info, ref. https://github.com/espressif/esp-idf/issues/243; Doc title fix --- docs/README.md | 11 +++++++++++ docs/conf.py | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..475ce0973e --- /dev/null +++ b/docs/README.md @@ -0,0 +1,11 @@ +# Documentation Source Folder + +This folder contains source files of [ESP-IDF documentation](http://esp-idf.readthedocs.io/). + +The sources do not render well in GitHub and some information is not visible at all. + +Use actual documentation generated instantly on each commit: + +* Main server: http://esp-idf.readthedocs.io/ or http://esp-idf.rtfd.io/ +* Mirror: https://dl.espressif.com/doc/esp-idf/latest/ + diff --git a/docs/conf.py b/docs/conf.py index 551cd86dd0..d38d3dee9d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -65,8 +65,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'ESP32 Programming Guide' -copyright = u'2016, Espressif' +project = u'ESP-IDF Programming Guide' +copyright = u'2016 - 2017, Espressif' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From 66647bb5bd4b5475ad2372216378f186aac43718 Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 17 Jan 2017 21:12:54 +0100 Subject: [PATCH 029/139] Typo corrections --- docs/api/wifi/esp_smartconfig.rst | 2 +- docs/{build_system.rst => build-system.rst} | 6 +++--- docs/index.rst | 2 +- docs/security/flash-encryption.rst | 4 +++- examples/storage/sd_card/README.md | 3 ++- 5 files changed, 10 insertions(+), 7 deletions(-) rename docs/{build_system.rst => build-system.rst} (98%) diff --git a/docs/api/wifi/esp_smartconfig.rst b/docs/api/wifi/esp_smartconfig.rst index 262218aa8b..11a6bccbfa 100644 --- a/docs/api/wifi/esp_smartconfig.rst +++ b/docs/api/wifi/esp_smartconfig.rst @@ -1,5 +1,5 @@ Smart Config -=== +============ API Reference ------------- diff --git a/docs/build_system.rst b/docs/build-system.rst similarity index 98% rename from docs/build_system.rst rename to docs/build-system.rst index d4353287b9..8f43b21176 100644 --- a/docs/build_system.rst +++ b/docs/build-system.rst @@ -131,7 +131,7 @@ Component Makefiles Each project contains one or more components, which can either be part of esp-idf or added from other component directories. -A component is any sub-directory that contains a `component.mk` file.[#f1]_. +A component is any sub-directory that contains a `component.mk` file [#f1]_. Minimal Component Makefile ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -464,7 +464,7 @@ The file's contents will be added to the .rodata section in flash, and are avail The names are generated from the full name of the file, as given in COMPONENT_EMBED_FILES. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. -For an example of using this technique, see examples/protocols/https_request - the certificate file contents are loaded from the text .pem file at compile time. +For an example of using this technique, see `examples/protocols/https_request `_ - the certificate file contents are loaded from the text .pem file at compile time. Fully Overriding The Component Makefile @@ -485,7 +485,7 @@ is set then the component can instruct the linker to link other binaries instead .. _esp-idf-template: https://github.com/espressif/esp-idf-template .. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html -.. _[_f1]: Actually, some components in esp-idf are "pure configuration" components that don't have a component.mk file, only a Makefile.projbuild and/or Kconfig.projbuild file. However, these components are unusual and most components have a component.mk file. +.. [#f1] Actually, some components in esp-idf are "pure configuration" components that don't have a component.mk file, only a Makefile.projbuild and/or Kconfig.projbuild file. However, these components are unusual and most components have a component.mk file. Custom sdkconfig defaults diff --git a/docs/index.rst b/docs/index.rst index d1072b6511..b934472b59 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -28,7 +28,7 @@ Contents: :maxdepth: 1 General Notes - Build System + Build System Debugging ESP32 Core Dump Partition Tables diff --git a/docs/security/flash-encryption.rst b/docs/security/flash-encryption.rst index 298a0a75bf..8c6bd4c857 100644 --- a/docs/security/flash-encryption.rst +++ b/docs/security/flash-encryption.rst @@ -291,11 +291,13 @@ Flash Encryption Algorithm - Each 32 byte block is encrypted with a unique key which is derived from this main flash encryption key XORed with the offset of this block in the flash (a "key tweak"). - The specific tweak depends on the setting of ``FLASH_CRYPT_CONFIG`` efuse. This is a 4 bit efuse, where each bit enables XORing of a particular range of the key bits: + - Bit 1, bits 0-66 of the key are XORed. - Bit 2, bits 67-131 of the key are XORed. - Bit 3, bits 132-194 of the key are XORed. - Bit 4, bits 195-256 of the key are XORed. -It is recommended that ``FLASH_CRYPT_CONFIG`` is always left to set the default value `0xF`, so that all key bits are XORed with the block offset. See `Setting FLASH_CRYPT_CONFIG` for details. + + It is recommended that ``FLASH_CRYPT_CONFIG`` is always left to set the default value `0xF`, so that all key bits are XORed with the block offset. See `Setting FLASH_CRYPT_CONFIG` for details. - The high 19 bits of the block offset (bit 5 to bit 23) are XORed with the main flash encryption key. This range is chosen for two reasons: the maximum flash size is 16MB (24 bits), and each block is 32 bytes so the least significant 5 bits are always zero. diff --git a/examples/storage/sd_card/README.md b/examples/storage/sd_card/README.md index bfc6a39fe9..b125716eae 100644 --- a/examples/storage/sd_card/README.md +++ b/examples/storage/sd_card/README.md @@ -32,7 +32,8 @@ N/C | WP | This example doesn't utilize card detect (CD) and write protect (WP) signals from SD card slot. ### Note about GPIO2 -GPIO2 pin is used as a bootstrapping pin, and should be low to enter UART download mode. One way to do this is to connect GPIO0 and GPIO2 using a jumper, and then the auto-reset circuit on most development boards will pull GPIO2 low along with GPIO2, when entering download mode. + +GPIO2 pin is used as a bootstrapping pin, and should be low to enter UART download mode. One way to do this is to connect GPIO0 and GPIO2 using a jumper, and then the auto-reset circuit on most development boards will pull GPIO2 low along with GPIO0, when entering download mode. ### Note about GPIO12 From 8aa5082baae0db503b1bfb6876b63a03e5d458fc Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 17 Jan 2017 21:20:24 +0100 Subject: [PATCH 030/139] Fixed memory leak in example, ref. https://github.com/espressif/esp-idf/issues/209 --- examples/storage/nvs_rw_blob/main/nvs_rw_blob.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/storage/nvs_rw_blob/main/nvs_rw_blob.c b/examples/storage/nvs_rw_blob/main/nvs_rw_blob.c index 0d4b7db4ee..c0a865eb6a 100644 --- a/examples/storage/nvs_rw_blob/main/nvs_rw_blob.c +++ b/examples/storage/nvs_rw_blob/main/nvs_rw_blob.c @@ -87,10 +87,10 @@ esp_err_t save_run_time(void) required_size += sizeof(uint32_t); run_time[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS; err = nvs_set_blob(my_handle, "run_time", run_time, required_size); - if (err != ESP_OK) return err; - free(run_time); + if (err != ESP_OK) return err; + // Commit err = nvs_commit(my_handle); if (err != ESP_OK) return err; From 4676d159adc6e92ab90546a618c340b9a5814459 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 18 Jan 2017 15:07:27 +0800 Subject: [PATCH 031/139] spi_flash: fix race condition when doing operations in unpinned tasks spi_flash_enable_interrupts_caches_and_other_cpu function used to enable non-IRAM interrupts after giving up flash operation lock, which would cause problems if another task was waiting on the lock to start a flash operation. In fact, non-IRAM interrupts should be re-enabled before the task scheduler is resumed. Otherwise non-pinned task can be moved to the other CPU due to preemption, causing esp_intr_noniram_enable to be called on the other CPU, causing an abort to be triggered. Fixes the issue reported in https://github.com/espressif/esp-idf/pull/258 --- components/spi_flash/cache_utils.c | 32 ++++++++-- components/spi_flash/test/test_spi_flash.c | 69 ++++++++++------------ 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 983ff5d256..df9d18c443 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -41,6 +41,9 @@ static uint32_t s_flash_op_cache_state[2]; static SemaphoreHandle_t s_flash_op_mutex; static volatile bool s_flash_op_can_start = false; static volatile bool s_flash_op_complete = false; +#ifndef NDEBUG +static volatile int s_flash_op_cpu = -1; +#endif void spi_flash_init_lock() { @@ -85,6 +88,11 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() const uint32_t cpuid = xPortGetCoreID(); const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; +#ifndef NDEBUG + // For sanity check later: record the CPU which has started doing flash operation + assert(s_flash_op_cpu == -1); + s_flash_op_cpu = cpuid; +#endif if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { // Scheduler hasn't been started yet, it means that spi_flash API is being @@ -98,12 +106,13 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() // disable cache there and block other tasks from executing. s_flash_op_can_start = false; s_flash_op_complete = false; - esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid); + esp_err_t ret = esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid); + assert(ret == ESP_OK); while (!s_flash_op_can_start) { // Busy loop and wait for spi_flash_op_block_func to disable cache // on the other CPU } - // Disable scheduler on CPU cpuid + // Disable scheduler on the current CPU vTaskSuspendAll(); // This is guaranteed to run on CPU because the other CPU is now // occupied by highest priority task @@ -119,6 +128,11 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() { const uint32_t cpuid = xPortGetCoreID(); const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; +#ifndef NDEBUG + // Sanity check: flash operation ends on the same CPU as it has started + assert(cpuid == s_flash_op_cpu); + s_flash_op_cpu = -1; +#endif // Re-enable cache on this CPU spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); @@ -132,13 +146,21 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() } else { // Signal to spi_flash_op_block_task that flash operation is complete s_flash_op_complete = true; - // Resume tasks on the current CPU + } + // Re-enable non-iram interrupts + esp_intr_noniram_enable(); + + // Resume tasks on the current CPU, if the scheduler has started. + // NOTE: enabling non-IRAM interrupts has to happen before this, + // because once the scheduler has started, due to preemption the + // current task can end up being moved to the other CPU. + // But esp_intr_noniram_enable has to be called on the same CPU which + // called esp_intr_noniram_disable + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { xTaskResumeAll(); } // Release API lock spi_flash_op_unlock(); - // Re-enable non-iram interrupts - esp_intr_noniram_enable(); } void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os() diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index 330e37bb82..4f3171049e 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -8,26 +8,25 @@ #include struct flash_test_ctx { - uint32_t offset[2]; - bool fail[2]; + uint32_t offset; + bool fail; SemaphoreHandle_t done; }; static void flash_test_task(void *arg) { - const uint32_t coreid = xPortGetCoreID(); - ets_printf("t%d\n", coreid); struct flash_test_ctx *ctx = (struct flash_test_ctx *) arg; vTaskDelay(100 / portTICK_PERIOD_MS); - const uint32_t sector = ctx->offset[coreid]; - ets_printf("es%d\n", coreid); + const uint32_t sector = ctx->offset; + printf("t%d\n", sector); + printf("es%d\n", sector); if (spi_flash_erase_sector(sector) != ESP_OK) { - ctx->fail[coreid] = true; - ets_printf("Erase failed\r\n"); + ctx->fail = true; + printf("Erase failed\r\n"); xSemaphoreGive(ctx->done); vTaskDelete(NULL); } - ets_printf("ed%d\n", coreid); + printf("ed%d\n", sector); vTaskDelay(0 / portTICK_PERIOD_MS); @@ -35,58 +34,52 @@ static void flash_test_task(void *arg) const uint32_t n = 4096; for (uint32_t offset = 0; offset < n; offset += 4) { if (spi_flash_write(sector * SPI_FLASH_SEC_SIZE + offset, (const uint8_t *) &val, 4) != ESP_OK) { - ets_printf("Write failed at offset=%d\r\n", offset); - ctx->fail[coreid] = true; + printf("Write failed at offset=%d\r\n", offset); + ctx->fail = true; break; } } - ets_printf("wd%d\n", coreid); + printf("wd%d\n", sector); vTaskDelay(0 / portTICK_PERIOD_MS); uint32_t val_read; for (uint32_t offset = 0; offset < n; offset += 4) { if (spi_flash_read(sector * SPI_FLASH_SEC_SIZE + offset, (uint8_t *) &val_read, 4) != ESP_OK) { - ets_printf("Read failed at offset=%d\r\n", offset); - ctx->fail[coreid] = true; + printf("Read failed at offset=%d\r\n", offset); + ctx->fail = true; break; } if (val_read != val) { - ets_printf("Read invalid value=%08x at offset=%d\r\n", val_read, offset); - ctx->fail[coreid] = true; + printf("Read invalid value=%08x at offset=%d\r\n", val_read, offset); + ctx->fail = true; break; } } - ets_printf("td%d\n", coreid); + printf("td%d\n", sector); xSemaphoreGive(ctx->done); vTaskDelete(NULL); } TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash]") { - TaskHandle_t procpu_task; - TaskHandle_t appcpu_task; - struct flash_test_ctx ctx; + SemaphoreHandle_t done = xSemaphoreCreateCounting(4, 0); + struct flash_test_ctx ctx[4] = { + { .offset = 0x100 + 6, .done = done }, + { .offset = 0x100 + 7, .done = done }, + { .offset = 0x100 + 8, .done = done }, + { .offset = 0x100 + 9, .done = done } + }; - ctx.offset[0] = 6; - ctx.offset[1] = 7; - ctx.fail[0] = 0; - ctx.fail[1] = 0; - ctx.done = xSemaphoreCreateBinary(); + xTaskCreatePinnedToCore(flash_test_task, "1", 2048, &ctx[0], 3, NULL, 0); + xTaskCreatePinnedToCore(flash_test_task, "2", 2048, &ctx[1], 3, NULL, 1); + xTaskCreatePinnedToCore(flash_test_task, "3", 2048, &ctx[2], 3, NULL, tskNO_AFFINITY); + xTaskCreatePinnedToCore(flash_test_task, "4", 2048, &ctx[3], 3, NULL, tskNO_AFFINITY); - xTaskCreatePinnedToCore(flash_test_task, "1", 2048, &ctx, 3, &procpu_task, 0); - if (portNUM_PROCESSORS == 2) { - xTaskCreatePinnedToCore(flash_test_task, "2", 2048, &ctx, 3, &appcpu_task, 1); - } - - xSemaphoreTake(ctx.done, portMAX_DELAY); - if (portNUM_PROCESSORS == 2) { - xSemaphoreTake(ctx.done, portMAX_DELAY); - } - - TEST_ASSERT_EQUAL(false, ctx.fail[0]); - if (portNUM_PROCESSORS == 2) { - TEST_ASSERT_EQUAL(false, ctx.fail[1]); + for (int i = 0; i < 4; ++i) { + xSemaphoreTake(done, portMAX_DELAY); + TEST_ASSERT_FALSE(ctx[i].fail); } + vSemaphoreDelete(done); } From 2bb67985dc2ca796e1ee7595e95c737558ebd191 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Wed, 18 Jan 2017 16:38:06 +0800 Subject: [PATCH 032/139] component/bt : move some codes of controller to iram 1. mv codes which called by sir into iram 2. mv libcoexist.a into iram --- components/bt/lib | 2 +- components/esp32/ld/esp32.common.ld | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bt/lib b/components/bt/lib index 52639e93f4..9c1eea6bb0 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 52639e93f42b426c5f3d29935f3f17fb1c6e2169 +Subproject commit 9c1eea6bb03adc3b3847fff79c3f017652840a46 diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index 8cc3b5b22e..3e5d6b7d83 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -84,6 +84,7 @@ SECTIONS *librtc.a:(.literal .text .literal.* .text.*) *libpp.a:(.literal .text .literal.* .text.*) *libhal.a:(.literal .text .literal.* .text.*) + *libcoexist.a:(.literal .text .literal.* .text.*) _iram_text_end = ABSOLUTE(.); } > iram0_0_seg From 57f911033da7ebd1fbf4d91fe9e86dc2f43ed3f6 Mon Sep 17 00:00:00 2001 From: antti Date: Mon, 5 Dec 2016 17:29:12 +0800 Subject: [PATCH 033/139] esp32: add unit testing doc --- docs/index.rst | 4 +-- docs/unit-tests.rst | 68 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 docs/unit-tests.rst diff --git a/docs/index.rst b/docs/index.rst index d1072b6511..b8d24d690c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -36,6 +36,7 @@ Contents: Secure Boot Deep Sleep Wake Stubs ULP Coprocessor + Unit Testing .. toctree:: :caption: API Reference @@ -77,5 +78,4 @@ Contents: Indices ======= -* :ref:`genindex` - +* :ref:`genindex` \ No newline at end of file diff --git a/docs/unit-tests.rst b/docs/unit-tests.rst new file mode 100644 index 0000000000..a32533755e --- /dev/null +++ b/docs/unit-tests.rst @@ -0,0 +1,68 @@ +Unit Testing in ESP32 +===================== + +ESP-IDF comes with a unit test app based on Unity - unit test framework. Unit tests are integrated in the ESP-IDF repository and are placed in ``test`` subdirectory of each component respectively. + +Adding unit tests +----------------- + +Unit tests are added in the ``test`` subdirectory of the respective component. +Tests are added in C files, a single C file can include multiple test cases. +Test files start with the word "test". + +The test file should include unity.h and the header for the C module to be tested. + +Tests are added in a function in the C file as follows:: + + TEST_CASE("test name", "[module name]" + { + // Add test here + } + +First argument is a descriptive name for the test, second argument is an identifier in square brackets. +Identifiers are used to group related test, or tests with specific properties. + +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()``, run the tests cases, and then call ``​UNITY_END()``. + +Each `test` subdirectory needs to include component.mk file with at least the following line of code:: + + COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive + +See http://www.throwtheswitch.org/unity for more information about writing tests in Unity. + +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. + +Change into tools/unit-test-app directory to configure and build it: + +* `make menuconfig` - configure unit test app. + +* `make TESTS_ALL=1` - build unit test app with tests for each component having tests in the ``test`` subdirectory. +* `make TEST_COMPONENTS='xxx'` - build unit test app with tests for specific components. + +When the build finishes, it will print instructions for flashing the chip. You can simply run ``make flash`` to flash all build output. + +You can also run ``make flash TESTS_ALL=1`` or ``make TEST_COMPONENTS='xxx'`` to build and flash. Everything needed will be rebuilt automatically before flashing. + +Use menuconfig to set the serial port for flashing. + +Running unit tests +------------------ + +After flashing reset the ESP32 and it will boot the unit test app. + +Unit test app prints a test menu with all available tests. + +Test cases can be run by inputting one of the following: + +- Test case name in quotation marks to run a single test case + +- Test case index to run a single test case + +- Module name in square brackets to run all test cases for a specific module + +- An asterisk to run all test cases From f8b5c293463047ba423901af45f20770fb3e7d9f Mon Sep 17 00:00:00 2001 From: antti Date: Wed, 14 Dec 2016 16:38:45 +0800 Subject: [PATCH 034/139] esp32: add [ignore] tag to some unit test cases for CI Add ignore tag on unit test cases that are not supported in CI yet --- components/driver/test/test_spi_master.c | 2 +- components/esp32/test/test_ahb_arb.c | 2 +- components/esp32/test/test_deep_sleep.c | 18 +++++++-------- components/esp32/test/test_delay.c | 2 +- components/esp32/test/test_fastbus.c | 2 +- components/esp32/test/test_miniz.c | 2 +- components/esp32/test/test_unal_dma.c | 2 +- components/fatfs/test/test_fatfs.c | 22 +++++++++---------- components/freertos/test/test_freertos.c | 2 +- .../freertos/test/test_freertos_eventgroups.c | 4 ++-- .../freertos/test/test_freertos_task_delete.c | 2 +- components/freertos/test/test_panic.c | 2 +- components/freertos/test/test_ringbuf.c | 4 ++-- components/mbedtls/test/test_mbedtls_sha.c | 2 +- components/newlib/test/test_newlib.c | 4 ++-- .../partition_table/test/test_partition.c | 2 +- components/sdmmc/test/test_sd.c | 4 ++-- components/spi_flash/test/test_spi_flash.c | 2 +- components/ulp/test/test_ulp.c | 6 ++--- 19 files changed, 43 insertions(+), 43 deletions(-) diff --git a/components/driver/test/test_spi_master.c b/components/driver/test/test_spi_master.c index d54cc5a633..cb04af8c97 100644 --- a/components/driver/test/test_spi_master.c +++ b/components/driver/test/test_spi_master.c @@ -80,7 +80,7 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]") } -TEST_CASE("SPI Master test", "[spi]") +TEST_CASE("SPI Master test", "[spi][ignore]") { spi_bus_config_t buscfg={ .mosi_io_num=4, diff --git a/components/esp32/test/test_ahb_arb.c b/components/esp32/test/test_ahb_arb.c index 65f4906fd5..21cf6d7781 100644 --- a/components/esp32/test/test_ahb_arb.c +++ b/components/esp32/test/test_ahb_arb.c @@ -269,7 +269,7 @@ static void tskTwo(void *pvParameters) } -TEST_CASE("S32C1I vs AHB test (needs I2S)", "[hw]") +TEST_CASE("S32C1I vs AHB test (needs I2S)", "[hw][ignore]") { int i; TaskHandle_t th[3]; diff --git a/components/esp32/test/test_deep_sleep.c b/components/esp32/test/test_deep_sleep.c index a47b6daf3f..d892177dc4 100644 --- a/components/esp32/test/test_deep_sleep.c +++ b/components/esp32/test/test_deep_sleep.c @@ -4,7 +4,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -TEST_CASE("esp_deepsleep works", "[deepsleep]") +TEST_CASE("esp_deepsleep works", "[deepsleep][ignore]") { esp_deep_sleep(2000000); } @@ -25,20 +25,20 @@ static void do_deep_sleep_from_app_cpu() } } -TEST_CASE("wake up using timer", "[deepsleep]") +TEST_CASE("wake up using timer", "[deepsleep][ignore]") { esp_deep_sleep_enable_timer_wakeup(2000000); esp_deep_sleep_start(); } -TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep]") +TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][ignore]") { esp_deep_sleep_enable_timer_wakeup(2000000); do_deep_sleep_from_app_cpu(); } -TEST_CASE("wake up using ext0 (13 high)", "[deepsleep]") +TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]") { ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13)); @@ -47,7 +47,7 @@ TEST_CASE("wake up using ext0 (13 high)", "[deepsleep]") esp_deep_sleep_start(); } -TEST_CASE("wake up using ext0 (13 low)", "[deepsleep]") +TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]") { ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); @@ -56,7 +56,7 @@ TEST_CASE("wake up using ext0 (13 low)", "[deepsleep]") esp_deep_sleep_start(); } -TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep]") +TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ignore]") { // This test needs external pulldown ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); @@ -64,7 +64,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep]") esp_deep_sleep_start(); } -TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep]") +TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ignore]") { // This test needs external pullup ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); @@ -72,7 +72,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep]") esp_deep_sleep_start(); } -TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep]") +TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep][ignore]") { ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13)); @@ -82,7 +82,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep]") esp_deep_sleep_start(); } -TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep]") +TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][ignore]") { ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); diff --git a/components/esp32/test/test_delay.c b/components/esp32/test/test_delay.c index 0b6c4aaf97..c34c3bda77 100644 --- a/components/esp32/test/test_delay.c +++ b/components/esp32/test/test_delay.c @@ -37,7 +37,7 @@ static void test_delay_task(void* p) vTaskDelete(NULL); } -TEST_CASE("ets_delay produces correct delay on both CPUs", "[delay]") +TEST_CASE("ets_delay produces correct delay on both CPUs", "[delay][ignore]") { int delay_ms = 50; const delay_test_arg_t args = { .delay_us = delay_ms * 1000, .method = 0 }; diff --git a/components/esp32/test/test_fastbus.c b/components/esp32/test/test_fastbus.c index 4ac5c55a88..2b58c725b0 100644 --- a/components/esp32/test/test_fastbus.c +++ b/components/esp32/test/test_fastbus.c @@ -96,7 +96,7 @@ static void tskTwo(void *pvParameters) // TODO: split this thing into separate orthogonal tests -TEST_CASE("Fast I/O bus test", "[hw]") +TEST_CASE("Fast I/O bus test", "[hw][ignore]") { int i; if ((REG_UART_BASE(0) >> 16) != 0x3ff4) { diff --git a/components/esp32/test/test_miniz.c b/components/esp32/test/test_miniz.c index 3453c859a9..d7d9dc33b6 100644 --- a/components/esp32/test/test_miniz.c +++ b/components/esp32/test/test_miniz.c @@ -7,7 +7,7 @@ #define DATASIZE (1024*64) -TEST_CASE("Test miniz compression/decompression", "[miniz]") +TEST_CASE("Test miniz compression/decompression", "[miniz][ignore]") { int x; char b; diff --git a/components/esp32/test/test_unal_dma.c b/components/esp32/test/test_unal_dma.c index 3726632a41..c05d0d0f36 100644 --- a/components/esp32/test/test_unal_dma.c +++ b/components/esp32/test/test_unal_dma.c @@ -183,7 +183,7 @@ int mymemcmp(char *a, char *b, int len) -TEST_CASE("Unaligned DMA test (needs I2S)", "[hw]") +TEST_CASE("Unaligned DMA test (needs I2S)", "[hw][ignore]") { int x; char src[2049], dest[2049]; diff --git a/components/fatfs/test/test_fatfs.c b/components/fatfs/test/test_fatfs.c index 9ee6606fb8..c2331d6e26 100644 --- a/components/fatfs/test/test_fatfs.c +++ b/components/fatfs/test/test_fatfs.c @@ -52,7 +52,7 @@ static void create_file_with_text(const char* name, const char* text) TEST_ASSERT_EQUAL(0, fclose(f)); } -TEST_CASE("can create and write file on sd card", "[fatfs]") +TEST_CASE("can create and write file on sd card", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -69,7 +69,7 @@ TEST_CASE("can create and write file on sd card", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("can read file on sd card", "[fatfs]") +TEST_CASE("can read file on sd card", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); @@ -134,7 +134,7 @@ static void speed_test(void* buf, size_t buf_size, size_t file_size, bool write) } -TEST_CASE("read speed test", "[fatfs]") +TEST_CASE("read speed test", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); @@ -151,7 +151,7 @@ TEST_CASE("read speed test", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("write speed test", "[fatfs]") +TEST_CASE("write speed test", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); @@ -171,7 +171,7 @@ TEST_CASE("write speed test", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("can lseek", "[fatfs]") +TEST_CASE("can lseek", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -208,7 +208,7 @@ TEST_CASE("can lseek", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("stat returns correct values", "[fatfs]") +TEST_CASE("stat returns correct values", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -249,7 +249,7 @@ TEST_CASE("stat returns correct values", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("unlink removes a file", "[fatfs]") +TEST_CASE("unlink removes a file", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -271,7 +271,7 @@ TEST_CASE("unlink removes a file", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("link copies a file, rename moves a file", "[fatfs]") +TEST_CASE("link copies a file, rename moves a file", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -373,7 +373,7 @@ done: } -TEST_CASE("multiple tasks can use same volume", "[fatfs]") +TEST_CASE("multiple tasks can use same volume", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -434,7 +434,7 @@ TEST_CASE("multiple tasks can use same volume", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("can create and remove directories", "[fatfs]") +TEST_CASE("can create and remove directories", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -470,7 +470,7 @@ TEST_CASE("can create and remove directories", "[fatfs]") HEAP_SIZE_CHECK(0); } -TEST_CASE("opendir, readdir, rewinddir, seekdir work as expected", "[fatfs]") +TEST_CASE("opendir, readdir, rewinddir, seekdir work as expected", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); diff --git a/components/freertos/test/test_freertos.c b/components/freertos/test/test_freertos.c index ced375279b..2eb0c9391b 100644 --- a/components/freertos/test/test_freertos.c +++ b/components/freertos/test/test_freertos.c @@ -187,7 +187,7 @@ static void uartRxInit(xQueueHandle q) } // TODO: split this thing into separate orthogonal tests -TEST_CASE("Bunch of FreeRTOS tests", "[freertos]") +TEST_CASE("Bunch of FreeRTOS tests", "[freertos][ignore]") { char *tst; TaskHandle_t th[12]; diff --git a/components/freertos/test/test_freertos_eventgroups.c b/components/freertos/test/test_freertos_eventgroups.c index b17e127c28..32dee2d201 100644 --- a/components/freertos/test/test_freertos_eventgroups.c +++ b/components/freertos/test/test_freertos_eventgroups.c @@ -38,7 +38,7 @@ static void task_event_group_call_response(void *param) vTaskDelete(NULL); } -TEST_CASE("FreeRTOS Event Groups", "[freertos]") +TEST_CASE("FreeRTOS Event Groups", "[freertos][ignore]") { eg = xEventGroupCreate(); @@ -89,7 +89,7 @@ static void task_test_sync(void *param) vTaskDelete(NULL); } -TEST_CASE("FreeRTOS Event Group Sync", "[freertos]") +TEST_CASE("FreeRTOS Event Group Sync", "[freertos][ignore]") { eg = xEventGroupCreate(); diff --git a/components/freertos/test/test_freertos_task_delete.c b/components/freertos/test/test_freertos_task_delete.c index 3101db2564..d8cc2755ed 100644 --- a/components/freertos/test/test_freertos_task_delete.c +++ b/components/freertos/test/test_freertos_task_delete.c @@ -13,7 +13,7 @@ static void task_delete_self(void *param) vTaskDelete(NULL); } -TEST_CASE("FreeRTOS Delete Tasks", "[freertos]") +TEST_CASE("FreeRTOS Delete Tasks", "[freertos][ignore]") { xTaskCreatePinnedToCore(task_delete_self, "tsk_self_a", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0); xTaskCreatePinnedToCore(task_delete_self, "tsk_self_a", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0); diff --git a/components/freertos/test/test_panic.c b/components/freertos/test/test_panic.c index 782b7a5642..6297d80c0e 100644 --- a/components/freertos/test/test_panic.c +++ b/components/freertos/test/test_panic.c @@ -17,7 +17,7 @@ #include "soc/io_mux_reg.h" -TEST_CASE("Panic handler", "[freertos]") +TEST_CASE("Panic handler", "[freertos][ignore]") { volatile int *i; i = (volatile int *)0x0; diff --git a/components/freertos/test/test_ringbuf.c b/components/freertos/test/test_ringbuf.c index 7d3c8788c9..8f8328532d 100644 --- a/components/freertos/test/test_ringbuf.c +++ b/components/freertos/test/test_ringbuf.c @@ -185,12 +185,12 @@ static void testRingbuffer(int type) } // TODO: split this thing into separate orthogonal tests -TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos]") +TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos][ignore]") { testRingbuffer(0); } -TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos]") +TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos][ignore]") { testRingbuffer(1); } diff --git a/components/mbedtls/test/test_mbedtls_sha.c b/components/mbedtls/test/test_mbedtls_sha.c index b18169827b..2ec3bc3477 100644 --- a/components/mbedtls/test/test_mbedtls_sha.c +++ b/components/mbedtls/test/test_mbedtls_sha.c @@ -116,7 +116,7 @@ static void tskRunSHA256Test(void *pvParameters) vTaskDelete(NULL); } -TEST_CASE("mbedtls SHA multithreading", "[mbedtls]") +TEST_CASE("mbedtls SHA multithreading", "[mbedtls][ignore]") { done_sem = xSemaphoreCreateCounting(4, 0); xTaskCreate(tskRunSHA1Test, "SHA1Task1", 8192, NULL, 3, NULL); diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c index 1d2a4bf09f..3627850209 100644 --- a/components/newlib/test/test_newlib.c +++ b/components/newlib/test/test_newlib.c @@ -19,7 +19,7 @@ TEST_CASE("test ctype functions", "[newlib]") TEST_ASSERT_FALSE( isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a')); } -TEST_CASE("test atoX functions", "[newlib]") +TEST_CASE("test atoX functions", "[newlib][ignore]") { TEST_ASSERT_EQUAL_INT(-2147483648, atoi("-2147483648")); TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647")); @@ -153,7 +153,7 @@ TEST_CASE("test 64bit int formats", "[newlib]") TEST_ASSERT_EQUAL(val, sval); } #else -TEST_CASE("test 64bit int formats", "[newlib]") +TEST_CASE("test 64bit int formats", "[newlib][ignore]") { char* res = NULL; const uint64_t val = 123456789012LL; diff --git a/components/partition_table/test/test_partition.c b/components/partition_table/test/test_partition.c index a4288d8e1d..a268222802 100644 --- a/components/partition_table/test/test_partition.c +++ b/components/partition_table/test/test_partition.c @@ -26,7 +26,7 @@ TEST_CASE("Can read partition table", "[partition]") printf("%d\n", __builtin_clz(count)); } -TEST_CASE("Can write, read, mmap partition", "[partition]") +TEST_CASE("Can write, read, mmap partition", "[partition][ignore]") { const esp_partition_t *p = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL); TEST_ASSERT_NOT_NULL(p); diff --git a/components/sdmmc/test/test_sd.c b/components/sdmmc/test/test_sd.c index 6c2154817f..768fecc258 100644 --- a/components/sdmmc/test/test_sd.c +++ b/components/sdmmc/test/test_sd.c @@ -26,7 +26,7 @@ #include -TEST_CASE("can probe SD", "[sd]") +TEST_CASE("can probe SD", "[sd][ignore]") { sdmmc_host_t config = SDMMC_HOST_DEFAULT(); sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); @@ -76,7 +76,7 @@ static void do_single_write_read_test(sdmmc_card_t* card, free(buffer); } -TEST_CASE("can write and read back blocks", "[sd]") +TEST_CASE("can write and read back blocks", "[sd][ignore]") { sdmmc_host_t config = SDMMC_HOST_DEFAULT(); config.max_freq_khz = SDMMC_FREQ_HIGHSPEED; diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index 330e37bb82..bf05b64db4 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -62,7 +62,7 @@ static void flash_test_task(void *arg) vTaskDelete(NULL); } -TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash]") +TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash][ignore]") { TaskHandle_t procpu_task; TaskHandle_t appcpu_task; diff --git a/components/ulp/test/test_ulp.c b/components/ulp/test/test_ulp.c index 854eb3ee20..f04178623c 100644 --- a/components/ulp/test/test_ulp.c +++ b/components/ulp/test/test_ulp.c @@ -64,7 +64,7 @@ TEST_CASE("ulp add test", "[ulp]") TEST_ASSERT_EQUAL(10 + 11, RTC_SLOW_MEM[18] & 0xffff); } -TEST_CASE("ulp branch test", "[ulp]") +TEST_CASE("ulp branch test", "[ulp][ignore]") { assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); @@ -95,7 +95,7 @@ TEST_CASE("ulp branch test", "[ulp]") TEST_ASSERT_EQUAL(0, RTC_SLOW_MEM[64]); } -TEST_CASE("ulp wakeup test", "[ulp]") +TEST_CASE("ulp wakeup test", "[ulp][ignore]") { assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); @@ -121,7 +121,7 @@ TEST_CASE("ulp wakeup test", "[ulp]") esp_deep_sleep_start(); } -TEST_CASE("ulp controls RTC_IO", "[ulp]") +TEST_CASE("ulp controls RTC_IO", "[ulp][ignore]") { assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); From 0501507d6b405d30afc7465e88f4128e30332ec4 Mon Sep 17 00:00:00 2001 From: antti Date: Wed, 7 Dec 2016 13:58:51 +0800 Subject: [PATCH 035/139] CI: add script for parsing unit test cases for CI from test files Add python script that parses list of unit test cases for CI from component test folder Modify .gitlab-ci.yml to run this script as part of build unit tests stage --- .gitlab-ci.yml | 24 +- .../CIConfigs/UT_Function_SYS_01.yml | 7 - components/idf_test/unit_test/TestCaseAll.yml | 461 ------------------ .../TestCaseScript/IDFUnitTest/UnitTest.py | 19 +- tools/unit-test-app/ModuleDefinition.yml | 127 +++++ tools/unit-test-app/UnitTestParser.py | 169 +++++++ 6 files changed, 325 insertions(+), 482 deletions(-) delete mode 100644 components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml delete mode 100644 components/idf_test/unit_test/TestCaseAll.yml create mode 100644 tools/unit-test-app/ModuleDefinition.yml create mode 100644 tools/unit-test-app/UnitTestParser.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8cb5c8bcac..81a8fba4fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -87,6 +87,8 @@ build_esp_idf_tests: - ./tools/unit-test-app/build/*.elf - ./tools/unit-test-app/build/*.map - ./tools/unit-test-app/build/bootloader/*.bin + - ./components/idf_test/unit_test/TestCaseAll.yml + - ./components/idf_test/unit_test/CIConfigs/*.yml expire_in: 6 mos script: @@ -94,6 +96,7 @@ build_esp_idf_tests: - git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..." - make defconfig - make TESTS_ALL=1 + - python UnitTestParser.py build_examples: <<: *build_template @@ -160,6 +163,7 @@ test_report: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test" REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report" + MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml" artifacts: when: always paths: @@ -180,8 +184,7 @@ test_report: - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script # generate report - - TEST_RESULT=Pass - - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH || TEST_RESULT=Fail + - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || FAIL=True # commit to CI-test-result project - git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git - rm -rf CI-test-result/RawData/$RESULT_PATH @@ -263,6 +266,7 @@ deploy_docs: # append test level folder to TEST_CASE_FILE_PATH in before_script of test job TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test" # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary + MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml" artifacts: when: always @@ -284,7 +288,7 @@ deploy_docs: - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script # run test - - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH + - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH # template for overnight test jobs @@ -309,7 +313,7 @@ deploy_docs: - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script # run test - - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH + - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH # template for unit test jobs .unit_test_template: &unit_test_template @@ -324,6 +328,10 @@ deploy_docs: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" APP_NAME: "ut" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test" + MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml" + + dependencies: + - build_esp_idf_tests UT_Function_SYS_01: <<: *unit_test_template @@ -333,6 +341,14 @@ UT_Function_SYS_01: before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_01.yml +UT_Function_SYS_02: + <<: *unit_test_template + tags: + - ESP32_IDF + - UT_T1_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_02.yml + IT_Function_SYS_01: <<: *test_template tags: diff --git a/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml b/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml deleted file mode 100644 index f4755dfec4..0000000000 --- a/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml +++ /dev/null @@ -1,7 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [UT1] -Filter: -- Add: - ID: [SYS_OS_0102, SYS_MISC_0102, SYS_MISC_0107, SYS_MISC_0106, SYS_MISC_0109, - SYS_MISC_0108, SYS_MISC_0112, SYS_MISC_0113, SYS_MISC_0110, SYS_MISC_0111, SYS_LIB_0103, - SYS_LIB_0102, SYS_LIB_0101, SYS_LIB_0106, SYS_LIB_0105, SYS_LIB_0104] diff --git a/components/idf_test/unit_test/TestCaseAll.yml b/components/idf_test/unit_test/TestCaseAll.yml deleted file mode 100644 index 4e5c01f219..0000000000 --- a/components/idf_test/unit_test/TestCaseAll.yml +++ /dev/null @@ -1,461 +0,0 @@ -test cases: -- CI ready: 'Yes' - ID: SYS_LIB_0101 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "check if ROM or Flash is used for functions" - - [dummy] - comment: check if ROM or Flash is used for functions - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run lib test - sub module: Std Lib - summary: lib unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: lib - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_LIB_0102 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test time functions" - - [dummy] - comment: test time functions - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run lib test - sub module: Std Lib - summary: lib unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: lib - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_LIB_0103 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test sscanf function" - - [dummy] - comment: test sscanf function - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run lib test - sub module: Std Lib - summary: lib unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: lib - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_LIB_0104 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test sprintf function" - - [dummy] - comment: test sprintf function - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run lib test - sub module: Std Lib - summary: lib unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: lib - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_LIB_0105 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test atoX functions" - - [dummy] - comment: test atoX functions - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run lib test - sub module: Std Lib - summary: lib unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: lib - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_LIB_0106 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test ctype functions" - - [dummy] - comment: test ctype functions - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run lib test - sub module: Std Lib - summary: lib unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: lib - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0102 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "mbedtls MPI self-tests" - - [dummy] - comment: mbedtls MPI self-tests - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run bignum test - sub module: Misc - summary: bignum unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: bignum - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0103 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test AES thread safety" - - [dummy] - comment: test AES thread safety - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run hwcrypto test - sub module: Misc - summary: hwcrypto unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: hwcrypto - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0104 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test AES acceleration" - - [dummy] - comment: test AES acceleration - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run hwcrypto test - sub module: Misc - summary: hwcrypto unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: hwcrypto - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0105 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test SHA thread safety" - - [dummy] - comment: test SHA thread safety - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run hwcrypto test - sub module: Misc - summary: hwcrypto unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: hwcrypto - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0106 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "context switch saves FP registers" - - [dummy] - comment: context switch saves FP registers - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run fp test - sub module: Misc - summary: fp unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: fp - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0107 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test FP sqrt" - - [dummy] - comment: test FP sqrt - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run fp test - sub module: Misc - summary: fp unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: fp - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0108 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test FP div" - - [dummy] - comment: test FP div - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run fp test - sub module: Misc - summary: fp unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: fp - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0109 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test FP mul" - - [dummy] - comment: test FP mul - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run fp test - sub module: Misc - summary: fp unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: fp - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0110 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test FP add" - - [dummy] - comment: test FP add - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run fp test - sub module: Misc - summary: fp unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: fp - version: v1 (2016-10-26) -- CI ready: 'Yes' - ID: SYS_MISC_0111 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "Test JPEG decompression library" - - [dummy] - comment: Test JPEG decompression library - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run JPEG decompression test - sub module: Misc - summary: JPEG decompression library unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: tjpgd - version: v1 (2016-10-31) -- CI ready: 'Yes' - ID: SYS_MISC_0112 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "mbedtls AES self-tests" - - [dummy] - comment: mbedtls AES self-tests - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run mbedtls AES self-tests - sub module: Misc - summary: mbedtls AES unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: mbedtls AES - version: v1 (2016-10-31) -- CI ready: 'Yes' - ID: SYS_MISC_0113 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "mbedtls SHA self-tests" - - [dummy] - comment: mbedtls SHA self-tests - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run mbedtls SHA self-tests - sub module: Misc - summary: mbedtls SHA unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: mbedtls SHA - version: v1 (2016-10-31) -- CI ready: 'Yes' - ID: SYS_MISC_0115 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "test SHA acceleration" - - [dummy] - comment: test SHA acceleration - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run SHA acceleration test - sub module: Misc - summary: SHA acceleration unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: SHA acceleration - version: v1 (2016-10-31) -- CI ready: 'Yes' - ID: SYS_OS_0102 - SDK: ESP32_IDF - Test App: UT - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "Freertos TLS delete cb" - - [dummy] - comment: Freertos TLS delete cb - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run Freertos TLS delete cb test - sub module: OS - summary: Freertos TLS delete cb unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: Freertos TLS delete cb - version: v1 (2016-10-31) diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index bfc8edeaa9..1625e4e36c 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -9,41 +9,40 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, timeout=timeout, log_path=log_path) - + self.test_case = None self.test_timeout = 20 - + # load param from excel for i in range(1, len(cmd_set)): if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] + cmd_string = "self.test_case = " + "\"" + cmd_set[i][0] + "\"" exec cmd_string self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) pass def send_commands(self): self.flush_data("UT1") - + try: - # add case select by name mark " before case name - self.serial_write_line("UT1", "\"" + self.test_case) + self.serial_write_line("UT1", "\"" + self.test_case + "\"") data = "" for _ in range(self.timeout): time.sleep(1) #wait for test to run before reading result data += self.serial_read_data("UT1") - if re.search('[^0] Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 + if re.search('[^0].* Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 self.set_result("Succeed") break else: self.set_result("Fail") - + except StandardError,e: NativeLog.add_exception_log(e) - + def execute(self): TCActionBase.TCActionBase.execute(self) self.send_commands() - + def main(): pass diff --git a/tools/unit-test-app/ModuleDefinition.yml b/tools/unit-test-app/ModuleDefinition.yml new file mode 100644 index 0000000000..0f9a31f901 --- /dev/null +++ b/tools/unit-test-app/ModuleDefinition.yml @@ -0,0 +1,127 @@ +freertos: + module: System + module abbr: SYS + sub module: OS + sub module abbr: OS +nvs: + module: System + module abbr: SYS + sub module: NVS + sub module abbr: NVS +partition: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +ulp: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +fp: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +hw: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +tjpgd: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +miniz: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +mmap: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +bignum: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +newlib: + module: System + module abbr: SYS + sub module: Std Lib + sub module abbr: STD +aes: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +mbedtls: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +spi_flash: + module: Driver + module abbr: DRV + sub module: SPI + sub module abbr: SPI +spi_flash_read: + module: Driver + module abbr: DRV + sub module: SPI + sub module abbr: SPI +spi_flash_write: + module: Driver + module abbr: DRV + sub module: SPI + sub module abbr: SPI +esp32: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +deepsleep: + module: RTC + module abbr: RTC + sub module: Deep Sleep + sub module abbr: SLEEP +sd: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +cxx: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +fatfs: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +delay: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +spi: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +vfs: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC +misc: + module: System + module abbr: SYS + sub module: Misc + sub module abbr: MISC + + diff --git a/tools/unit-test-app/UnitTestParser.py b/tools/unit-test-app/UnitTestParser.py new file mode 100644 index 0000000000..26f90a0262 --- /dev/null +++ b/tools/unit-test-app/UnitTestParser.py @@ -0,0 +1,169 @@ +import yaml +import os +import re +import sys +import shutil + + +MODULE_MAP = yaml.load(open("ModuleDefinition.yml", "r")) + +TEST_CASE_PATTERN = { + "initial condition": "UTINIT1", + "SDK": "ESP32_IDF", + "level": "Unit", + "execution time": 0, + "Test App": "UT", + "auto test": "Yes", + "category": "Function", + "test point 1": "basic function", + "version": "v1 (2016-12-06)", + "test environment": "UT_T1_1", + "expected result": "1. set succeed" +} + +CONFIG_FILE_PATTERN = { + "Config": {"execute count": 1, "execute order": "in order"}, + "DUT": [], + "Filter": [{"Add": {"ID": []}}] +} + +test_cases = list() +test_ids = {} +test_ids_by_job = {} +unit_jobs = {} + +os.chdir(os.path.join("..", "..")) +IDF_PATH = os.getcwd() + + +class Parser(object): + @classmethod + def parse_test_folders(cls): + test_folder_paths = list() + os.chdir(os.path.join(IDF_PATH, "components")) + component_dirs = os.listdir(".") + for dir in component_dirs: + os.chdir(dir) + if "test" in os.listdir("."): + test_folder_paths.append(os.path.join(os.getcwd(), "test")) + os.chdir("..") + Parser.parse_test_files(test_folder_paths) + + @classmethod + def parse_test_files(cls, test_folder_paths): + for path in test_folder_paths: + os.chdir(path) + for file_path in os.listdir("."): + if file_path[-2:] == ".c": + Parser.read_test_file(os.path.join(os.getcwd(), file_path), len(test_cases)+1) + os.chdir(os.path.join("..", "..")) + Parser.dump_test_cases(test_cases) + + @classmethod + def read_test_file(cls, test_file_path, file_index): + test_index = 0 + with open(test_file_path, "r") as file: + for line in file: + if re.match("TEST_CASE", line): + test_index += 1 + tags = re.split(r"[\[\]\"]", line) + Parser.parse_test_cases(file_index, test_index, tags) + + + @classmethod + def parse_test_cases(cls, file_index, test_index, tags): + ci_ready = "Yes" + test_env = "UT_T1_1" + for tag in tags: + if tag == "ignore": + ci_ready = "No" + if re.match("test_env=", tag): + test_env = tag[9:] + module_name = tags[4] + try: + MODULE_MAP[module_name] + except KeyError: + module_name = "misc" + id = "UT_%s_%s_%03d%02d" % (MODULE_MAP[module_name]['module abbr'], + MODULE_MAP[module_name]['sub module abbr'], + file_index, test_index) + test_case = dict(TEST_CASE_PATTERN) + test_case.update({"module": MODULE_MAP[module_name]['module'], + "CI ready": ci_ready, + "cmd set": ["IDFUnitTest/UnitTest", [tags[1]]], + "ID": id, + "test point 2": module_name, + "steps": tags[1], + "comment": tags[1], + "test environment": test_env, + "sub module": MODULE_MAP[module_name]['sub module'], + "summary": tags[1]}) + if test_case["CI ready"] == "Yes": + if test_ids.has_key(test_env): + test_ids[test_env].append(id) + else: + test_ids.update({test_env: [id]}) + test_cases.append(test_case) + + @classmethod + def dump_test_cases(cls, test_cases): + os.chdir(os.path.join(IDF_PATH, "components", "idf_test", "unit_test")) + with open ("TestCaseAll.yml", "wb+") as f: + yaml.dump({"test cases": test_cases}, f, allow_unicode=True, default_flow_style=False) + + @classmethod + def dump_ci_config(cls): + Parser.split_test_cases() + os.chdir(os.path.join(IDF_PATH, "components", "idf_test", "unit_test")) + if not os.path.exists("CIConfigs"): + os.makedirs("CIConfigs") + os.chdir("CIConfigs") + for unit_job in unit_jobs: + job = dict(CONFIG_FILE_PATTERN) + job.update({"DUT": ["UT1"]}) + job.update({"Filter": [{"Add": {"ID": test_ids_by_job[unit_job]}}]}) + with open (unit_job + ".yml", "wb+") as f: + yaml.dump(job, f, allow_unicode=True, default_flow_style=False) + + @classmethod + def split_test_cases(cls): + for job in unit_jobs: + test_ids_by_job.update({job: list()}) + for test_env in test_ids: + available_jobs = list() + for job in unit_jobs: + if test_env in unit_jobs[job]: + available_jobs.append(job) + for idx, job in enumerate(available_jobs): + test_ids_by_job[job] += (test_ids[test_env][idx*len(test_ids[test_env])/len(available_jobs):(idx+1)*len(test_ids[test_env])/len(available_jobs)]) + + @classmethod + def parse_gitlab_ci(cls): + os.chdir(IDF_PATH) + with open(".gitlab-ci.yml", "rb") as f: + gitlab_ci = yaml.load(f) + keys = gitlab_ci.keys() + for key in keys: + if re.match("UT_", key): + test_env = gitlab_ci[key]["tags"] + unit_job = key + key = {} + key.update({unit_job: test_env}) + unit_jobs.update(key) + + @classmethod + def copy_module_def_file(cls): + src = os.path.join(IDF_PATH, "tools", "unit-test-app", "ModuleDefinition.yml") + dst = os.path.join(IDF_PATH, "components", "idf_test", "unit_test") + shutil.copy(src, dst) + + +def main(): + Parser.parse_test_folders() + Parser.parse_gitlab_ci() + Parser.dump_ci_config() + Parser.copy_module_def_file() + + +if __name__ == '__main__': + main() From f7e2e456e41145f6922b5c6a53ee3f003a389aa7 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 18 Jan 2017 18:31:06 +0800 Subject: [PATCH 036/139] intr_alloc: mark inline asm operand as earlyclobber When compiling in release mode, compiler was choosing same register for oldint and intmask variables, so INTENABLE was never modified. This effectively broke disabling of non-IRAM interrupts during flash operations, observed in the existing tests if task watchdog is enabled. This change adds an extra constraint tells the compiler that output operand should not be placed into the same register as an input one. --- components/esp32/intr_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/intr_alloc.c b/components/esp32/intr_alloc.c index bfd6c51206..d9cc627e17 100644 --- a/components/esp32/intr_alloc.c +++ b/components/esp32/intr_alloc.c @@ -700,7 +700,7 @@ void esp_intr_noniram_disable() "and a3,%0,%1\n" //mask ints that need disabling "wsr a3,INTENABLE\n" //write back "rsync\n" - :"=r"(oldint):"r"(intmask):"a3"); + :"=&r"(oldint):"r"(intmask):"a3"); //Save which ints we did disable non_iram_int_disabled[cpu]=oldint&non_iram_int_mask[cpu]; } From 0564263e5b3db25df4b851d4504bc6cbcbd460c5 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Wed, 18 Jan 2017 20:17:03 +0800 Subject: [PATCH 037/139] tw7809: fix station no rewiring softap probability --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 49b6d079dd..ddc4b0cbc5 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 49b6d079ddd180518fc1dea7ef47af04e5f4a031 +Subproject commit ddc4b0cbc59c2c63ba1f0e02a9cd4972c083782c From 865b21d5a15abb0d7a80bb298c483e7d7f25b1c6 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 18 Jan 2017 15:36:10 +0200 Subject: [PATCH 038/139] Fix compilation if CONSOLE_UART is set to NONE CONFIG_CONSOLE_UART_BAUDRATE is not defined --- components/esp32/cpu_start.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index b5e896e573..edc2881a28 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -175,7 +175,9 @@ void start_cpu0_default(void) trax_start_trace(TRAX_DOWNCOUNT_WORDS); #endif esp_set_cpu_freq(); // set CPU frequency configured in menuconfig +#ifndef CONFIG_CONSOLE_UART_NONE uart_div_modify(CONFIG_CONSOLE_UART_NUM, (APB_CLK_FREQ << 4) / CONFIG_CONSOLE_UART_BAUDRATE); +#endif #if CONFIG_BROWNOUT_DET esp_brownout_init(); #endif From 26015f5d88205a115ef55acfb6b3bd7ec7919251 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 18 Jan 2017 16:06:54 +0200 Subject: [PATCH 039/139] Do not printf if debug is not enabled --- components/tcpip_adapter/tcpip_adapter_lwip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index b2725e3447..40f235d545 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -85,7 +85,7 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) { dhcps_start(esp_netif[tcpip_if], ip_info->ip); - printf("dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n", + TCPIP_ADAPTER_DEBUG("dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n", IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw)); dhcps_status = TCPIP_ADAPTER_DHCP_STARTED; From d3a2d6aedcf9124af3a06f21fdb06d6197e39afa Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 18 Jan 2017 16:13:09 +0200 Subject: [PATCH 040/139] Do not printf if debug level is not correct --- components/lwip/api/tcpip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/lwip/api/tcpip.c b/components/lwip/api/tcpip.c index f3422af706..8374c429cd 100755 --- a/components/lwip/api/tcpip.c +++ b/components/lwip/api/tcpip.c @@ -501,8 +501,8 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg) sys_thread_t xLwipTaskHandle = sys_thread_new(TCPIP_THREAD_NAME , tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); - printf("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n", - (u32_t)xLwipTaskHandle,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n", + (u32_t)xLwipTaskHandle,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE)); } From 31ec0a7c4453ace7bddac6258fd676381b2cc1ae Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 18 Jan 2017 23:14:29 +0800 Subject: [PATCH 041/139] freertos: call tick hooks on CPU1 even if CPU0 scheduler is suspended MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The block which dispatches ticks on CPU1 was a copy of the code block for the normal path (CPU0). It used to check uxPendedTicks, with the logic that uxPendedTicks can be 0 iff the scheduler is not suspended. On CPU1 however, uxPendedTicks is not related to the state of the scheduler (as uxPendedTicks is updated on CPU0). Due to this, if CPU0 scheduler was suspended, and uxPendedTicks happened to be nonzero, tick hooks on CPU1 didn’t run, even though CPU1 scheduler was working. This change removes the check for uxPendedTicks in CPU1 code path, so that the tick hooks on CPU1 always get called (as for the CPU0 code path). --- components/freertos/tasks.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 6caabaa38e..0b5cc42957 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -2381,26 +2381,15 @@ BaseType_t xSwitchRequired = pdFALSE; switch, even when this routine (running on core 0) unblocks a bunch of high-priority tasks... this is less than optimal -- JD. */ if ( xPortGetCoreID()!=0 ) { + #if ( configUSE_TICK_HOOK == 1 ) + vApplicationTickHook(); + #endif /* configUSE_TICK_HOOK */ + esp_vApplicationTickHook(); + /* We can't really calculate what we need, that's done on core 0... just assume we need a switch. ToDo: Make this more intelligent? -- JD */ - { - /* Guard against the tick hook being called when the pended tick - count is being unwound (when the scheduler is being unlocked). */ - if( ( uxSchedulerSuspended[ xPortGetCoreID() ] != ( UBaseType_t ) pdFALSE ) || uxPendedTicks == ( UBaseType_t ) 0U ) - { - #if ( configUSE_TICK_HOOK == 1 ) - vApplicationTickHook(); - #endif /* configUSE_TICK_HOOK */ - esp_vApplicationTickHook(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - return pdTRUE; } From 97e3c0fec4f21bf932fb4ab47a15302c603ac860 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Wed, 18 Jan 2017 20:05:26 +0800 Subject: [PATCH 042/139] kconfig: move PHY-related settings into new menu - PHY options must be shown when either WIFI or BT is enabled. - Add clarification that TX power option applies to WiFi only. --- components/esp32/Kconfig | 42 +++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 8bbd6d032e..5db28b6bea 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -1,4 +1,4 @@ -menu "ESP32-specific config" +menu "ESP32-specific" choice ESP32_DEFAULT_CPU_FREQ_MHZ prompt "CPU frequency" @@ -490,9 +490,27 @@ config SW_COEXIST_ENABLE Recommended for heavy traffic scenarios. Both coexistence configuration options are automatically managed, no user intervention is required. + +config ESP32_WIFI_RX_BUFFER_NUM + int "Max number of WiFi RX buffers" + depends on WIFI_ENABLED + range 2 25 + default 25 + help + Set the number of WiFi rx buffers. Each buffer takes approximately 1.6KB of RAM. + Larger number for higher throughput but more memory. Smaller number for lower + throughput but less memory. + +config PHY_ENABLED + bool + default y if WIFI_ENABLED || BT_ENABLED + +menu PHY + visible if PHY_ENABLED + config ESP32_PHY_AUTO_INIT bool "Initialize PHY in startup code" - depends on WIFI_ENABLED + depends on PHY_ENABLED default y help If enabled, PHY will be initialized in startup code, before @@ -507,7 +525,7 @@ config ESP32_PHY_AUTO_INIT config ESP32_PHY_INIT_DATA_IN_PARTITION bool "Use a partition to store PHY init data" - depends on WIFI_ENABLED + depends on PHY_ENABLED default n help If enabled, PHY init data will be loaded from a partition. @@ -523,20 +541,12 @@ config ESP32_PHY_INIT_DATA_IN_PARTITION If unsure, choose 'n'. config ESP32_PHY_MAX_TX_POWER - int "Max TX power (dBm)" + int "Max WiFi TX power (dBm)" range 0 20 default 20 - depends on WIFI_ENABLED + depends on PHY_ENABLED && WIFI_ENABLED help - Set maximum transmit power. Actual transmit power for high + Set maximum transmit power for WiFi radio. Actual transmit power for high data rates may be lower than this setting. - -config ESP32_WIFI_RX_BUFFER_NUM - int "Max number of WiFi RX buffers" - depends on WIFI_ENABLED - range 2 25 - default 25 - help - Set the number of WiFi rx buffers. Each buffer takes approximately 1.6KB of RAM. - Larger number for higher throughput but more memory. Smaller number for lower - throughput but less memory. + +endmenu From efbd2805e296a02929c299bc9091a2daae60592b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 19 Jan 2017 00:32:10 +0800 Subject: [PATCH 043/139] ethernet: improve kconfig option descriptions Also limit suggested EMAC task priority range to 22, as the top priority should be used only by IPC tasks. --- components/ethernet/Kconfig | 41 ++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/components/ethernet/Kconfig b/components/ethernet/Kconfig index 0ea94eaafd..663871f2a0 100644 --- a/components/ethernet/Kconfig +++ b/components/ethernet/Kconfig @@ -5,30 +5,47 @@ menuconfig ETHERNET Select this option to enable ethernet driver and show the submenu with ethernet features. config DMA_RX_BUF_NUM - int "DMA Rx Buf Num" - default 10 - depends on ETHERNET - help - Dma rx buf num ,can not be 0 . - -config DMA_TX_BUF_NUM - int "DMA Tx Buf Num" + int "Number of DMA RX buffers" + range 1 10 default 10 depends on ETHERNET help - Dma tx Buf num ,can not be 0. + Number of DMA receive buffers. Each buffer is 1600 bytes. + Buffers are allocated statically. + Larger number of buffers increases throughput. + +config DMA_TX_BUF_NUM + int "Number of DMA RX buffers" + range 1 10 + default 10 + depends on ETHERNET + help + Number of DMA transmit buffers. Each buffer is 1600 bytes. + Buffers are allocated statically. + Larger number of buffers increases throughput. config EMAC_L2_TO_L3_RX_BUF_MODE - bool "L2 To L3 RX BUF COPY MODE" + bool "Enable copy between Layer2 and Layer3" default n depends on ETHERNET help - Receive Buf user copy mode or pointer mode. + If this options is selected, a copy of each received buffer will be created when + passing it from the Ethernet MAC (L2) to the IP stack (L3). Otherwise, IP stack + will receive pointers to the DMA buffers used by Ethernet MAC. + + When Ethernet MAC doesn't have any unused buffers left, it will drop incomming + packets (flow control may help with this problem, to some extent). + + The buffers for the IP stack are allocated from the heap, so the total number of + receive buffers is limited by the available heap size, if this option is selected. + + If unsure, choose n. config EMAC_TASK_PRIORITY int "EMAC_TASK_PRIORITY" default 20 + range 3 22 depends on ETHERNET help - Emac task priority ,suggest 3 ~ 23. + Ethernet MAC task priority. From 90c43ea95edd18726e28d2e1e88aed4160db8136 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 18 Jan 2017 22:49:41 +0800 Subject: [PATCH 044/139] newlib: fix register used for DPORT/RTC bug workaround While there was no register at DR_REG_FRC_TIMER_BASE + 0x60, due to peripheral address space wraparound this write actually affected one of FRC2 registers, which is used by WiFi stack to implement legacy ets_timer APIs. This change uses FRC_TIMER_LOAD_REG(0) instead, which can be set to known value safely. --- components/newlib/time.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/newlib/time.c b/components/newlib/time.c index 30c7ca7f40..7595ab82b8 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -85,9 +85,8 @@ static void IRAM_ATTR frc_timer_isr() { // Write to FRC_TIMER_INT_REG may not take effect in some cases (root cause TBD) // This extra write works around this issue. - // There is no register at DR_REG_FRC_TIMER_BASE + 0x60 (in fact, any DPORT register address can be used). - WRITE_PERI_REG(DR_REG_FRC_TIMER_BASE + 0x60, 0xabababab); - // Clear interrupt status + // FRC_TIMER_LOAD_REG(0) is used here, but any other DPORT register address can also be used. + WRITE_PERI_REG(FRC_TIMER_LOAD_REG(0), FRC_TIMER_LOAD_VALUE(0)); WRITE_PERI_REG(FRC_TIMER_INT_REG(0), FRC_TIMER_INT_CLR); s_microseconds += FRC1_ISR_PERIOD_US; } From 0b6598c49206228896f41f20ada2382270d9da6b Mon Sep 17 00:00:00 2001 From: krzychb Date: Wed, 18 Jan 2017 21:03:15 +0100 Subject: [PATCH 045/139] Added README.md to example category folders --- examples/bluetooth/README.md | 5 +++++ examples/ethernet/README.md | 3 +++ examples/get-started/README.md | 5 +++++ examples/peripherals/README.md | 5 +++++ examples/protocols/README.md | 5 +++++ examples/protocols/mdns/README.md | 2 +- examples/storage/README.md | 5 +++++ examples/system/README.md | 5 +++++ examples/wifi/README.md | 3 +++ 9 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 examples/bluetooth/README.md create mode 100644 examples/ethernet/README.md create mode 100644 examples/get-started/README.md create mode 100644 examples/peripherals/README.md create mode 100644 examples/protocols/README.md create mode 100644 examples/storage/README.md create mode 100644 examples/system/README.md create mode 100644 examples/wifi/README.md diff --git a/examples/bluetooth/README.md b/examples/bluetooth/README.md new file mode 100644 index 0000000000..07bbe8ac14 --- /dev/null +++ b/examples/bluetooth/README.md @@ -0,0 +1,5 @@ +# Bluetooth Examples + +Note: To use examples in this directory, you need to have Bluetooth enabled in configuration. Run `make menuconfig`, go to `Component config` and verify if you see `[*] Bluetooth`. If not - enable if and save. + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/ethernet/README.md b/examples/ethernet/README.md new file mode 100644 index 0000000000..1b9ee845bb --- /dev/null +++ b/examples/ethernet/README.md @@ -0,0 +1,3 @@ +# Ethernet Examples + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/get-started/README.md b/examples/get-started/README.md new file mode 100644 index 0000000000..8a6792e718 --- /dev/null +++ b/examples/get-started/README.md @@ -0,0 +1,5 @@ +# Get Started Examples + +Simple code to get started with ESP32 and ESP-IDF. + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/peripherals/README.md b/examples/peripherals/README.md new file mode 100644 index 0000000000..fdb4444191 --- /dev/null +++ b/examples/peripherals/README.md @@ -0,0 +1,5 @@ +# Peripherals Examples + +This section provides examples how to configure and use ESP32’s internal peripherals like GPIO, UART, I2C, SPI, timers, counters, ADC / DAC, PWM, etc. + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/protocols/README.md b/examples/protocols/README.md new file mode 100644 index 0000000000..2c34c3da60 --- /dev/null +++ b/examples/protocols/README.md @@ -0,0 +1,5 @@ +# Protocols Examples + +Implementation of internet communication protocols and services. + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/protocols/mdns/README.md b/examples/protocols/mdns/README.md index 1c298604b8..76dbdc17b7 100644 --- a/examples/protocols/mdns/README.md +++ b/examples/protocols/mdns/README.md @@ -1,4 +1,4 @@ -# 30_mdns example +# mDNS example Shows how to use mDNS to advertise lookup services and hosts diff --git a/examples/storage/README.md b/examples/storage/README.md new file mode 100644 index 0000000000..36b1f64b27 --- /dev/null +++ b/examples/storage/README.md @@ -0,0 +1,5 @@ +# Storage Examples + +Storage and management of user and system data in module’s flash and on external memory / devices. + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/system/README.md b/examples/system/README.md new file mode 100644 index 0000000000..3fb812f307 --- /dev/null +++ b/examples/system/README.md @@ -0,0 +1,5 @@ +# System Examples + +Configuration and management of memory, interrupts, WDT (watchdog timer), OTA (over the air updates), deep sleep and logging. + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/wifi/README.md b/examples/wifi/README.md new file mode 100644 index 0000000000..b0dc683508 --- /dev/null +++ b/examples/wifi/README.md @@ -0,0 +1,3 @@ +# Wi-Fi Examples + +See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. From 16b23a407cde7492c215c4019ddaef9200412a72 Mon Sep 17 00:00:00 2001 From: krzychb Date: Wed, 18 Jan 2017 21:04:11 +0100 Subject: [PATCH 046/139] Added links from api category TOC to example category folders Typo fix in bluetooth README.md --- docs/api/bluetooth/index.rst | 2 ++ docs/api/ethernet/index.rst | 2 ++ docs/api/peripherals/index.rst | 2 ++ docs/api/protocols/index.rst | 2 ++ docs/api/storage/index.rst | 2 ++ docs/api/system/index.rst | 2 ++ docs/api/wifi/index.rst | 3 +++ examples/bluetooth/README.md | 2 +- 8 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/api/bluetooth/index.rst b/docs/api/bluetooth/index.rst index fffe674425..5a096c75ef 100644 --- a/docs/api/bluetooth/index.rst +++ b/docs/api/bluetooth/index.rst @@ -8,3 +8,5 @@ Bluetooth API Bluetooth Common Bluetooth LE + +Example code for this API section is provided in `examples/bluetooth `_ directory of ESP-IDF repository. diff --git a/docs/api/ethernet/index.rst b/docs/api/ethernet/index.rst index aeb0137c5e..31181d23ea 100644 --- a/docs/api/ethernet/index.rst +++ b/docs/api/ethernet/index.rst @@ -6,3 +6,5 @@ Ethernet API Ethernet + +Example code for this API section is provided in `examples/ethernet `_ directory of ESP-IDF repository. diff --git a/docs/api/peripherals/index.rst b/docs/api/peripherals/index.rst index 9ea0c41ab6..147a722fc6 100644 --- a/docs/api/peripherals/index.rst +++ b/docs/api/peripherals/index.rst @@ -14,3 +14,5 @@ Peripherals API LED Control Remote Control + +Example code for this API section is provided in `examples/peripherals `_ directory of ESP-IDF repository. diff --git a/docs/api/protocols/index.rst b/docs/api/protocols/index.rst index 632bd141dc..9a3a9a0c2f 100644 --- a/docs/api/protocols/index.rst +++ b/docs/api/protocols/index.rst @@ -6,3 +6,5 @@ Protocols API mDNS + +Example code for this API section is provided in `examples/protocols `_ directory of ESP-IDF repository. diff --git a/docs/api/storage/index.rst b/docs/api/storage/index.rst index 30fb2088c7..bf21cc9eea 100644 --- a/docs/api/storage/index.rst +++ b/docs/api/storage/index.rst @@ -10,3 +10,5 @@ Storage API Virtual Filesystem FAT Filesystem + +Example code for this API section is provided in `examples/storage `_ directory of ESP-IDF repository. diff --git a/docs/api/system/index.rst b/docs/api/system/index.rst index 6bbd7c10c5..f5746f80fd 100644 --- a/docs/api/system/index.rst +++ b/docs/api/system/index.rst @@ -11,3 +11,5 @@ System API Deep Sleep Logging + +Example code for this API section is provided in `examples/system `_ directory of ESP-IDF repository. diff --git a/docs/api/wifi/index.rst b/docs/api/wifi/index.rst index 2abe2b2fff..aecf87fa3b 100644 --- a/docs/api/wifi/index.rst +++ b/docs/api/wifi/index.rst @@ -6,3 +6,6 @@ Wi-Fi API Wi-Fi Smart Config + + +Example code for this API section is provided in `examples/wifi `_ directory of ESP-IDF repository. diff --git a/examples/bluetooth/README.md b/examples/bluetooth/README.md index 07bbe8ac14..3d60a59162 100644 --- a/examples/bluetooth/README.md +++ b/examples/bluetooth/README.md @@ -1,5 +1,5 @@ # Bluetooth Examples -Note: To use examples in this directory, you need to have Bluetooth enabled in configuration. Run `make menuconfig`, go to `Component config` and verify if you see `[*] Bluetooth`. If not - enable if and save. +Note: To use examples in this directory, you need to have Bluetooth enabled in configuration. Run `make menuconfig`, go to `Component config` and verify if you see `[*] Bluetooth`. If not - enable it and save. See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. From 9a8a82e857920ba57811795f15aba3c55b1a4380 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 19 Jan 2017 11:18:44 +1100 Subject: [PATCH 047/139] phyinit: Use PHY config to enable, don't need phy_get_romfunc_addr to init --- components/esp32/component.mk | 8 +++----- components/esp32/cpu_freq.c | 2 -- components/esp32/phy.h | 3 +-- components/esp32/phy_init.c | 7 +++---- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/components/esp32/component.mk b/components/esp32/component.mk index e1cd2c6524..a8109a0f5e 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -3,16 +3,14 @@ # COMPONENT_SRCDIRS := . hwcrypto -LIBS := core rtc phy -ifdef CONFIG_BT_ENABLED -LIBS += coexist +LIBS := core rtc +ifdef CONFIG_PHY_ENABLED # BT || WIFI +LIBS += phy coexist endif ifdef CONFIG_WIFI_ENABLED LIBS += net80211 pp wpa smartconfig coexist wps wpa2 endif -LIBS := $(sort $(LIBS)) # de-duplicate, we can handle different orders here - LINKER_SCRIPTS += esp32.common.ld esp32.rom.ld esp32.peripherals.ld ifeq ("$(CONFIG_NEWLIB_NANO_FORMAT)","y") diff --git a/components/esp32/cpu_freq.c b/components/esp32/cpu_freq.c index 7618f147af..f5ccd13df7 100644 --- a/components/esp32/cpu_freq.c +++ b/components/esp32/cpu_freq.c @@ -17,7 +17,6 @@ #include "rom/ets_sys.h" #include "rom/uart.h" #include "sdkconfig.h" -#include "phy.h" #include "rtc.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" @@ -32,7 +31,6 @@ void esp_set_cpu_freq(void) { uint32_t freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; - phy_get_romfunc_addr(); // freq will be changed to 40MHz in rtc_init_lite, // wait uart tx finish, otherwise some uart output will be lost diff --git a/components/esp32/phy.h b/components/esp32/phy.h index 81990f2e36..c0affb36ef 100644 --- a/components/esp32/phy.h +++ b/components/esp32/phy.h @@ -25,8 +25,7 @@ extern "C" { */ /** - * @brief Initialize function pointer table in PHY library. - * @note This function should be called before register_chipv7_phy. + * @brief Return ROM function pointer table from PHY library. */ void phy_get_romfunc_addr(void); diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 07a455d501..5b130eaf7a 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -27,7 +27,7 @@ #include "nvs.h" #include "sdkconfig.h" -#ifdef CONFIG_WIFI_ENABLED +#ifdef CONFIG_PHY_ENABLED #include "phy.h" #include "phy_init_data.h" @@ -39,8 +39,7 @@ esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data, { assert(init_data); assert(calibration_data); - // Initialize PHY pointer table - phy_get_romfunc_addr(); + REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); // Enable WiFi peripheral clock @@ -221,4 +220,4 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, return err; } -#endif // CONFIG_WIFI_ENABLED +#endif // CONFIG_PHY_ENABLED From b1df4c47f98e0b5082146543e362c8e849be9d22 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 19 Jan 2017 10:58:09 +0800 Subject: [PATCH 048/139] kconfig: define ESP32_PHY_MAX_TX_POWER if PHY_ENABLED ESP32_PHY_MAX_TX_POWER option is only meaningful for WiFi, so previous change made it depend on WIFI_ENABLED. However if WiFi is not enabled, but BT is, this option becomes undefined which breaks phy_init_data generation. This change turns ESP32_PHY_MAX_TX_POWER into a hidden parameter, which depends on PHY_ENABLED. New user-visible parameter, ESP32_PHY_MAX_WIFI_TX_POWER is introduced which depends on WIFI_ENABLED and is used as default value for ESP32_PHY_MAX_TX_POWER if WIFI_ENABLED is set. Otherwise ESP32_PHY_MAX_WIFI_TX_POWER is set to 20. --- components/esp32/Kconfig | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 5db28b6bea..c6e4cc7e22 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -539,8 +539,8 @@ config ESP32_PHY_INIT_DATA_IN_PARTITION into the application binary. If unsure, choose 'n'. - -config ESP32_PHY_MAX_TX_POWER + +config ESP32_PHY_MAX_WIFI_TX_POWER int "Max WiFi TX power (dBm)" range 0 20 default 20 @@ -548,5 +548,11 @@ config ESP32_PHY_MAX_TX_POWER help Set maximum transmit power for WiFi radio. Actual transmit power for high data rates may be lower than this setting. - + +config ESP32_PHY_MAX_TX_POWER + int + depends on PHY_ENABLED + default 20 if !WIFI_ENABLED + default ESP32_PHY_MAX_WIFI_TX_POWER if WIFI_ENABLED + endmenu From 2ea4d7fd0217f3df266df73da5e2e17df3bec6d8 Mon Sep 17 00:00:00 2001 From: shangke Date: Thu, 19 Jan 2017 16:45:30 +0800 Subject: [PATCH 049/139] ethernet: limit rx buf num when flow ctrl enable. --- components/ethernet/Kconfig | 5 +++-- components/ethernet/emac_main.c | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/components/ethernet/Kconfig b/components/ethernet/Kconfig index 663871f2a0..46e86cc60e 100644 --- a/components/ethernet/Kconfig +++ b/components/ethernet/Kconfig @@ -6,17 +6,18 @@ menuconfig ETHERNET config DMA_RX_BUF_NUM int "Number of DMA RX buffers" - range 1 10 + range 3 20 default 10 depends on ETHERNET help Number of DMA receive buffers. Each buffer is 1600 bytes. Buffers are allocated statically. Larger number of buffers increases throughput. + If enable flow ctrl, the num must be above 9 . config DMA_TX_BUF_NUM int "Number of DMA RX buffers" - range 1 10 + range 3 20 default 10 depends on ETHERNET help diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index 067d1a8ed7..853887cfc5 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -216,7 +216,14 @@ static void emac_set_user_config_data(eth_config_t *config ) emac_config.emac_phy_check_init = config->phy_check_init; emac_config.emac_phy_get_speed_mode = config->phy_get_speed_mode; emac_config.emac_phy_get_duplex_mode = config->phy_get_duplex_mode; +#if DMA_RX_BUF_NUM > 9 emac_config.emac_flow_ctrl_enable = config->flow_ctrl_enable; +#else + if(config->flow_ctrl_enable == true) { + ESP_LOGE(TAG, "eth flow ctrl init err!!! Please run make menuconfig and make sure DMA_RX_BUF_NUM > 9 ."); + } + emac_config.emac_flow_ctrl_enable = false; +#endif emac_config.emac_phy_get_partner_pause_enable = config->phy_get_partner_pause_enable; } From 0073ff3acdb1baf27300a4bc025ed9462d77783a Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Thu, 19 Jan 2017 11:49:59 +0800 Subject: [PATCH 050/139] component/bt : add api to set raw adv_data/scan_rsp_data 1. add api to set raw scan response data 2. add api to set raw scan response data 3. update doxygen 4. add menuconfig to config gatt server demo --- components/bt/bluedroid/api/esp_gap_ble_api.c | 47 +++++ .../bluedroid/api/include/esp_gap_ble_api.h | 41 +++++ components/bt/bluedroid/bta/dm/bta_dm_act.c | 47 +++++ components/bt/bluedroid/bta/dm/bta_dm_api.c | 58 +++++++ components/bt/bluedroid/bta/dm/bta_dm_int.h | 18 +- components/bt/bluedroid/bta/dm/bta_dm_main.c | 161 +++++++++--------- components/bt/bluedroid/bta/include/bta_api.h | 32 ++++ .../btc/profile/std/gap/btc_gap_ble.c | 106 +++++++++++- .../btc/profile/std/include/btc_gap_ble.h | 12 ++ .../bt/bluedroid/stack/btm/btm_ble_gap.c | 41 +++++ .../bt/bluedroid/stack/include/btm_ble_api.h | 30 ++++ docs/api/bluetooth/esp_gap_ble.rst | 9 + examples/bluetooth/gatt_server/README.rst | 15 ++ examples/bluetooth/gatt_server/main/Kconfig | 10 ++ .../bluetooth/gatt_server/main/gatts_demo.c | 28 ++- 15 files changed, 570 insertions(+), 85 deletions(-) create mode 100644 examples/bluetooth/gatt_server/main/Kconfig diff --git a/components/bt/bluedroid/api/esp_gap_ble_api.c b/components/bt/bluedroid/api/esp_gap_ble_api.c index 56bedc4242..2807281aed 100644 --- a/components/bt/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/bluedroid/api/esp_gap_ble_api.c @@ -252,3 +252,50 @@ uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *len return (BTM_CheckAdvData( adv_data, type, length)); } +esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len) +{ + btc_msg_t msg; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (raw_data == NULL + || (raw_data_len <= 0 || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW; + arg.cfg_adv_data_raw.raw_adv = raw_data; + arg.cfg_adv_data_raw.raw_adv_len = raw_data_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len) +{ + btc_msg_t msg; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (raw_data == NULL + || (raw_data_len <= 0 || raw_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW; + arg.cfg_scan_rsp_data_raw.raw_scan_rsp = raw_data; + arg.cfg_scan_rsp_data_raw.raw_scan_rsp_len = raw_data_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} diff --git a/components/bt/bluedroid/api/include/esp_gap_ble_api.h b/components/bt/bluedroid/api/include/esp_gap_ble_api.h index 1d27edb881..fa8eb2432e 100644 --- a/components/bt/bluedroid/api/include/esp_gap_ble_api.h +++ b/components/bt/bluedroid/api/include/esp_gap_ble_api.h @@ -44,6 +44,8 @@ typedef enum { ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, /*!< When scan response data set complete, the event comes */ ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, /*!< When scan parameters set complete, the event comes */ ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */ + ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */ + ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */ } esp_gap_ble_cb_event_t; /// Advertising data maximum length @@ -270,6 +272,18 @@ typedef union { int flag; /*!< Advertising data flag bit */ int num_resps; /*!< Scan result number */ } scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT + */ + struct ble_adv_data_raw_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */ + } adv_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT + */ + struct ble_scan_rsp_data_raw_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */ + } scan_rsp_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT */ } esp_ble_gap_cb_param_t; /** @@ -448,6 +462,33 @@ esp_err_t esp_ble_gap_set_device_name(const char *name); */ uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length); +/** + * @brief This function is called to set raw advertising data. User need to fill + * ADV data by self. + * + * @param[in] raw_data : raw advertising data + * @param[in] raw_data_len : raw advertising data length , less than 31 bytes + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len); + +/** + * @brief This function is called to set raw scan response data. User need to fill + * scan response data by self. + * + * @param[in] raw_data : raw scan response data + * @param[in] raw_data_len : raw scan response data length , less than 31 bytes + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len); + #ifdef __cplusplus } #endif diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c index 67af7f03bf..66eb55dac2 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -4608,6 +4608,30 @@ void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data) } } +/******************************************************************************* +** +** Function bta_dm_ble_set_adv_config_raw +** +** Description This function set the customized ADV data configuration +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data) +{ + tBTA_STATUS status = BTA_FAILURE; + + if (BTM_BleWriteAdvDataRaw(p_data->ble_set_adv_data_raw.p_raw_adv, + p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) { + status = BTA_SUCCESS; + } + + if (p_data->ble_set_adv_data_raw.p_adv_data_cback) { + (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status); + } +} + + /******************************************************************************* ** ** Function bta_dm_ble_set_scan_rsp @@ -4631,6 +4655,29 @@ void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data) } } +/******************************************************************************* +** +** Function bta_dm_ble_set_scan_rsp_raw +** +** Description This function set the raw scan response data +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data) +{ + tBTA_STATUS status = BTA_FAILURE; + + if (BTM_BleWriteScanRspRaw(p_data->ble_set_adv_data_raw.p_raw_adv, + p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) { + status = BTA_SUCCESS; + } + + if (p_data->ble_set_adv_data_raw.p_adv_data_cback) { + (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status); + } +} + /******************************************************************************* ** ** Function bta_dm_ble_set_data_length diff --git a/components/bt/bluedroid/bta/dm/bta_dm_api.c b/components/bt/bluedroid/bta/dm/bta_dm_api.c index 914bbfabc2..132d2ea8f7 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_api.c @@ -1077,6 +1077,35 @@ void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv } } +/******************************************************************************* +** +** Function BTA_DmBleSetAdvConfigRaw +** +** Description This function is called to set raw Advertising data +** +** Parameters p_raw_adv : raw advertising data. +** raw_adv_len : raw advertising data length. +** p_adv_data_cback : set adv data complete callback. +** +** Returns None +** +*******************************************************************************/ +void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len, + tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback) +{ + tBTA_DM_API_SET_ADV_CONFIG_RAW *p_msg; + + if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG_RAW *) + GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG_RAW))) != NULL) { + p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT; + p_msg->p_adv_data_cback = p_adv_data_cback; + p_msg->p_raw_adv = p_raw_adv; + p_msg->raw_adv_len = raw_adv_len; + + bta_sys_sendmsg(p_msg); + } +} + /******************************************************************************* ** ** Function BTA_DmBleSetScanRsp @@ -1104,6 +1133,35 @@ extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA * } } +/******************************************************************************* +** +** Function BTA_DmBleSetScanRspRaw +** +** Description This function is called to set raw scan response data +** +** Parameters p_raw_scan_rsp : raw scan_rspertising data. +** raw_scan_rsp_len : raw scan_rspertising data length. +** p_scan_rsp_data_cback : set scan_rsp data complete callback. +** +** Returns None +** +*******************************************************************************/ +void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len, + tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback) +{ + tBTA_DM_API_SET_ADV_CONFIG_RAW *p_msg; + + if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG_RAW *) + GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG_RAW))) != NULL) { + p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT; + p_msg->p_adv_data_cback = p_scan_rsp_data_cback; + p_msg->p_raw_adv = p_raw_scan_rsp; + p_msg->raw_adv_len = raw_scan_rsp_len; + + bta_sys_sendmsg(p_msg); + } +} + /******************************************************************************* ** ** Function BTA_DmBleSetStorageParams diff --git a/components/bt/bluedroid/bta/dm/bta_dm_int.h b/components/bt/bluedroid/bta/dm/bta_dm_int.h index 80e0bea477..7475ad254e 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_int.h +++ b/components/bt/bluedroid/bta/dm/bta_dm_int.h @@ -109,7 +109,11 @@ enum { support setting the ble advertising param by the APP******/ BTA_DM_API_BLE_ADV_PARAM_All_EVT, BTA_DM_API_BLE_SET_ADV_CONFIG_EVT, + /* Add for set raw advertising data */ + BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT, BTA_DM_API_BLE_SET_SCAN_RSP_EVT, + /* Add for set raw scan response data */ + BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT, BTA_DM_API_BLE_BROADCAST_EVT, BTA_DM_API_SET_DATA_LENGTH_EVT, @@ -545,6 +549,15 @@ typedef struct { tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback; } tBTA_DM_API_SET_ADV_CONFIG; +/* raw scan response and raw advertising data use + the same structure */ +typedef struct { + BT_HDR hdr; + UINT8 *p_raw_adv; + UINT32 raw_adv_len; + tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback; +} tBTA_DM_API_SET_ADV_CONFIG_RAW; + typedef struct { BT_HDR hdr; UINT8 batch_scan_full_max; @@ -708,6 +721,7 @@ typedef union { tBTA_DM_API_BLE_ADV_PARAMS ble_set_adv_params; tBTA_DM_API_BLE_ADV_PARAMS_ALL ble_set_adv_params_all; tBTA_DM_API_SET_ADV_CONFIG ble_set_adv_data; + tBTA_DM_API_SET_ADV_CONFIG_RAW ble_set_adv_data_raw; #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE tBTA_DM_API_SCAN_FILTER_PARAM_SETUP ble_scan_filt_param_setup; tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond; @@ -1093,9 +1107,11 @@ extern void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data); extern void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data); extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data); -extern void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data); +extern void bta_dm_ble_set_adv_params_all(tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data); +extern void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data); +extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data); extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data); diff --git a/components/bt/bluedroid/bta/dm/bta_dm_main.c b/components/bt/bluedroid/bta/dm/bta_dm_main.c index ea3f54618f..25c4978538 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_main.c @@ -47,86 +47,95 @@ typedef void (*tBTA_DM_ACTION)(tBTA_DM_MSG *p_data); const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { /* device manager local device API events */ - bta_dm_enable, /* 0 BTA_DM_API_ENABLE_EVT */ - bta_dm_disable, /* 1 BTA_DM_API_DISABLE_EVT */ - bta_dm_set_dev_name, /* 2 BTA_DM_API_SET_NAME_EVT */ - bta_dm_set_visibility, /* 3 BTA_DM_API_SET_VISIBILITY_EVT */ - bta_dm_acl_change, /* 8 BTA_DM_ACL_CHANGE_EVT */ - bta_dm_add_device, /* 9 BTA_DM_API_ADD_DEVICE_EVT */ - bta_dm_close_acl, /* 10 BTA_DM_API_ADD_DEVICE_EVT */ + bta_dm_enable, /* 0 BTA_DM_API_ENABLE_EVT */ + bta_dm_disable, /* 1 BTA_DM_API_DISABLE_EVT */ + bta_dm_set_dev_name, /* 2 BTA_DM_API_SET_NAME_EVT */ + bta_dm_set_visibility, /* 3 BTA_DM_API_SET_VISIBILITY_EVT */ + bta_dm_acl_change, /* 8 BTA_DM_ACL_CHANGE_EVT */ + bta_dm_add_device, /* 9 BTA_DM_API_ADD_DEVICE_EVT */ + bta_dm_close_acl, /* 10 BTA_DM_API_ADD_DEVICE_EVT */ /* security API events */ - bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */ - bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */ - bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */ + bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */ + bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */ + bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */ /* power manger events */ - bta_dm_pm_btm_status, /* 16 BTA_DM_PM_BTM_STATUS_EVT */ - bta_dm_pm_timer, /* 17 BTA_DM_PM_TIMER_EVT*/ + bta_dm_pm_btm_status, /* 16 BTA_DM_PM_BTM_STATUS_EVT */ + bta_dm_pm_timer, /* 17 BTA_DM_PM_TIMER_EVT*/ /* simple pairing events */ - bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */ + bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */ - bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */ + bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */ #if (BTM_OOB_INCLUDED == TRUE) - bta_dm_loc_oob, /* 20 BTA_DM_API_LOC_OOB_EVT */ - bta_dm_ci_io_req_act, /* 21 BTA_DM_CI_IO_REQ_EVT */ - bta_dm_ci_rmt_oob_act, /* 22 BTA_DM_CI_RMT_OOB_EVT */ + bta_dm_loc_oob, /* 20 BTA_DM_API_LOC_OOB_EVT */ + bta_dm_ci_io_req_act, /* 21 BTA_DM_CI_IO_REQ_EVT */ + bta_dm_ci_rmt_oob_act, /* 22 BTA_DM_CI_RMT_OOB_EVT */ #endif /* BTM_OOB_INCLUDED */ #if BLE_INCLUDED == TRUE - bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */ - bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */ - bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */ - bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */ + bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */ + bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */ + bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */ + bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */ bta_dm_security_grant, bta_dm_ble_set_bg_conn_type, - bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ - bta_dm_ble_set_conn_scan_params, /* BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT */ - bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */ - bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */ - bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT*/ - bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */ - /*******This handler function added by Yulong at 2016/9/9 to - support the random address setting for the APP******/ - bta_dm_ble_set_rand_address, /*BTA_DM_API_SET_RAND_ADDR_EVT*/ - /*******This handler function added by Yulong at 2016/10/19 to - support stop the ble advertising setting by the APP******/ - bta_dm_ble_stop_advertising, /*BTA_DM_API_BLE_STOP_ADV_EVT*/ + bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ + bta_dm_ble_set_conn_scan_params, /* BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT */ + bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */ + bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */ + bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT*/ + bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */ + /* This handler function added by + Yulong at 2016/9/9 to support the + random address setting for the APP */ + bta_dm_ble_set_rand_address, /* BTA_DM_API_SET_RAND_ADDR_EVT*/ + /* This handler function added by + Yulong at 2016/10/19 to support + stop the ble advertising setting + by the APP */ + bta_dm_ble_stop_advertising, /* BTA_DM_API_BLE_STOP_ADV_EVT*/ #if BLE_PRIVACY_SPT == TRUE - bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */ + bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */ #endif - bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_ADV_PARAM_EVT */ - bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */ - bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */ - bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSPT */ - bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ - bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */ + bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_ADV_PARAM_EVT */ + bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */ + bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */ + /* New function to allow set raw adv + data to HCI */ + bta_dm_ble_set_adv_config_raw, /* BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT */ + bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */ + /* New function to allow set raw scan + response data to HCI */ + bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */ + bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ + bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */ #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */ - bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */ - bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */ + bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */ + bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */ + bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */ #endif - bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/ - bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */ - bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */ - btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */ - bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ - bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */ - bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */ - bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */ - bta_dm_ble_track_advertiser, /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */ - bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */ + bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/ + bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */ + bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */ + btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */ + bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ + bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */ + bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */ + bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */ + bta_dm_ble_track_advertiser, /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */ + bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */ #endif - bta_dm_enable_test_mode, /* BTA_DM_API_ENABLE_TEST_MODE_EVT */ - bta_dm_disable_test_mode, /* BTA_DM_API_DISABLE_TEST_MODE_EVT */ - bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */ + bta_dm_enable_test_mode, /* BTA_DM_API_ENABLE_TEST_MODE_EVT */ + bta_dm_disable_test_mode, /* BTA_DM_API_DISABLE_TEST_MODE_EVT */ + bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */ - bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */ - bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */ + bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */ + bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */ }; @@ -161,24 +170,24 @@ enum { /* action function list */ const tBTA_DM_ACTION bta_dm_search_action[] = { - bta_dm_search_start, /* 0 BTA_DM_API_SEARCH */ - bta_dm_search_cancel, /* 1 BTA_DM_API_SEARCH_CANCEL */ - bta_dm_discover, /* 2 BTA_DM_API_DISCOVER */ - bta_dm_inq_cmpl, /* 3 BTA_DM_INQUIRY_CMPL */ - bta_dm_rmt_name, /* 4 BTA_DM_REMT_NAME */ - bta_dm_sdp_result, /* 5 BTA_DM_SDP_RESULT */ - bta_dm_search_cmpl, /* 6 BTA_DM_SEARCH_CMPL */ - bta_dm_free_sdp_db, /* 7 BTA_DM_FREE_SDP_DB */ - bta_dm_disc_result, /* 8 BTA_DM_DISC_RESULT */ - bta_dm_search_result, /* 9 BTA_DM_SEARCH_RESULT */ - bta_dm_queue_search, /* 10 BTA_DM_QUEUE_SEARCH */ - bta_dm_queue_disc, /* 11 BTA_DM_QUEUE_DISC */ - bta_dm_search_clear_queue, /* 12 BTA_DM_SEARCH_CLEAR_QUEUE */ - bta_dm_search_cancel_cmpl, /* 13 BTA_DM_SEARCH_CANCEL_CMPL */ - bta_dm_search_cancel_notify, /* 14 BTA_DM_SEARCH_CANCEL_NOTIFY */ - bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */ - bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */ - bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */ + bta_dm_search_start, /* 0 BTA_DM_API_SEARCH */ + bta_dm_search_cancel, /* 1 BTA_DM_API_SEARCH_CANCEL */ + bta_dm_discover, /* 2 BTA_DM_API_DISCOVER */ + bta_dm_inq_cmpl, /* 3 BTA_DM_INQUIRY_CMPL */ + bta_dm_rmt_name, /* 4 BTA_DM_REMT_NAME */ + bta_dm_sdp_result, /* 5 BTA_DM_SDP_RESULT */ + bta_dm_search_cmpl, /* 6 BTA_DM_SEARCH_CMPL */ + bta_dm_free_sdp_db, /* 7 BTA_DM_FREE_SDP_DB */ + bta_dm_disc_result, /* 8 BTA_DM_DISC_RESULT */ + bta_dm_search_result, /* 9 BTA_DM_SEARCH_RESULT */ + bta_dm_queue_search, /* 10 BTA_DM_QUEUE_SEARCH */ + bta_dm_queue_disc, /* 11 BTA_DM_QUEUE_DISC */ + bta_dm_search_clear_queue, /* 12 BTA_DM_SEARCH_CLEAR_QUEUE */ + bta_dm_search_cancel_cmpl, /* 13 BTA_DM_SEARCH_CANCEL_CMPL */ + bta_dm_search_cancel_notify, /* 14 BTA_DM_SEARCH_CANCEL_NOTIFY */ + bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */ + bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */ + bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */ #if BLE_INCLUDED == TRUE , bta_dm_close_gatt_conn #endif diff --git a/components/bt/bluedroid/bta/include/bta_api.h b/components/bt/bluedroid/bta/include/bta_api.h index 338fb96891..1b97dc4fc6 100644 --- a/components/bt/bluedroid/bta/include/bta_api.h +++ b/components/bt/bluedroid/bta/include/bta_api.h @@ -2050,6 +2050,22 @@ extern void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg, tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); +/******************************************************************************* +** +** Function BTA_DmBleSetAdvConfigRaw +** +** Description This function is called to set raw Advertising data +** +** Parameters p_raw_adv : raw advertising data. +** raw_adv_len : raw advertising data length. +** p_adv_data_cback : set adv data complete callback. +** +** Returns None +** +*******************************************************************************/ +extern void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len, + tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); + /******************************************************************************* ** ** Function BTA_DmBleSetScanRsp @@ -2065,6 +2081,22 @@ extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg, tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); +/******************************************************************************* +** +** Function BTA_DmBleSetScanRspRaw +** +** Description This function is called to set raw scan response data +** +** Parameters p_raw_scan_rsp : raw scan_rspertising data. +** raw_scan_rsp_len : raw scan_rspertising data length. +** p_scan_rsp_data_cback : set scan_rsp data complete callback. +** +** Returns None +** +*******************************************************************************/ +extern void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len, + tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback); + /******************************************************************************* ** ** Function BTA_DmBleBroadcast diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 4161567538..339ff68420 100644 --- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -30,7 +30,7 @@ static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_g { esp_gap_ble_cb_t btc_gap_ble_cb = (esp_gap_ble_cb_t)btc_profile_cb_get(BTC_PID_GAP_BLE); if (btc_gap_ble_cb) { - btc_gap_ble_cb(event, param); + btc_gap_ble_cb(event, param); } } @@ -303,6 +303,44 @@ static void btc_scan_rsp_data_callback(tBTA_STATUS status) } } +static void btc_adv_data_raw_callback(tBTA_STATUS status) +{ + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT; + param.adv_data_raw_cmpl.status = status; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL); + + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + +static void btc_scan_rsp_data_raw_callback(tBTA_STATUS status) +{ + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT; + param.scan_rsp_data_raw_cmpl.status = status; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL); + + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + static void btc_ble_set_adv_data(esp_ble_adv_data_t *adv_data, tBTA_SET_ADV_DATA_CMPL_CBACK p_adv_data_cback) { @@ -317,6 +355,18 @@ static void btc_ble_set_adv_data(esp_ble_adv_data_t *adv_data, } } +static void btc_ble_set_adv_data_raw(uint8_t *raw_adv, uint32_t raw_adv_len, + tBTA_SET_ADV_DATA_CMPL_CBACK p_adv_data_cback) +{ + BTA_DmBleSetAdvConfigRaw(raw_adv, raw_adv_len, p_adv_data_cback); +} + +static void btc_ble_set_scan_rsp_data_raw(uint8_t *raw_scan_rsp, uint32_t raw_scan_rsp_len, + tBTA_SET_ADV_DATA_CMPL_CBACK p_scan_rsp_data_cback) +{ + BTA_DmBleSetScanRspRaw(raw_scan_rsp, raw_scan_rsp_len, p_scan_rsp_data_cback); +} + static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params) { tBLE_BD_ADDR peer_addr; @@ -520,6 +570,12 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg) case ESP_GAP_BLE_SCAN_RESULT_EVT: btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RESULT_EVT, param); break; + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, param); + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: + btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, param); + break; default: break; @@ -551,6 +607,30 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } break; } + case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW: { + btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src; + btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *) p_dest; + + if (src && src->cfg_adv_data_raw.raw_adv && src->cfg_adv_data_raw.raw_adv_len > 0) { + dst->cfg_adv_data_raw.raw_adv = GKI_getbuf(src->cfg_adv_data_raw.raw_adv_len); + if (dst->cfg_adv_data_raw.raw_adv) { + memcpy(dst->cfg_adv_data_raw.raw_adv, src->cfg_adv_data_raw.raw_adv, src->cfg_adv_data_raw.raw_adv_len); + } + } + break; + } + case BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW: { + btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src; + btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *) p_dest; + + if (src && src->cfg_scan_rsp_data_raw.raw_scan_rsp && src->cfg_scan_rsp_data_raw.raw_scan_rsp_len > 0) { + dst->cfg_scan_rsp_data_raw.raw_scan_rsp = GKI_getbuf(src->cfg_scan_rsp_data_raw.raw_scan_rsp_len); + if (dst->cfg_scan_rsp_data_raw.raw_scan_rsp) { + memcpy(dst->cfg_scan_rsp_data_raw.raw_scan_rsp, src->cfg_scan_rsp_data_raw.raw_scan_rsp, src->cfg_scan_rsp_data_raw.raw_scan_rsp_len); + } + } + break; + } default: LOG_ERROR("Unhandled deep copy %d\n", msg->act); break; @@ -576,6 +656,20 @@ static void btc_gap_ble_arg_deep_free(btc_msg_t *msg) } break; } + case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW: { + uint8_t *raw_adv = ((btc_ble_gap_args_t *)msg->arg)->cfg_adv_data_raw.raw_adv; + if (raw_adv) { + GKI_freebuf(raw_adv); + } + break; + } + case BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW: { + uint8_t *raw_scan_rsp = ((btc_ble_gap_args_t *)msg->arg)->cfg_scan_rsp_data_raw.raw_scan_rsp; + if (raw_scan_rsp) { + GKI_freebuf(raw_scan_rsp); + } + break; + } default: LOG_DEBUG("Unhandled deep free %d\n", msg->act); break; @@ -631,6 +725,16 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) case BTC_GAP_BLE_ACT_SET_DEV_NAME: BTA_DmSetDeviceName(arg->set_dev_name.device_name); break; + case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW: + btc_ble_set_adv_data_raw(arg->cfg_adv_data_raw.raw_adv, + arg->cfg_adv_data_raw.raw_adv_len, + btc_adv_data_raw_callback); + break; + case BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW: + btc_ble_set_scan_rsp_data_raw(arg->cfg_scan_rsp_data_raw.raw_scan_rsp, + arg->cfg_scan_rsp_data_raw.raw_scan_rsp_len, + btc_scan_rsp_data_raw_callback); + break; default: break; } diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h index 9a35db4083..ea639bcde9 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -32,6 +32,8 @@ typedef enum { BTC_GAP_BLE_ACT_SET_RAND_ADDRESS, BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY, BTC_GAP_BLE_ACT_SET_DEV_NAME, + BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW, + BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW, } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -76,6 +78,16 @@ typedef union { #define ESP_GAP_DEVICE_NAME_MAX (32) char device_name[ESP_GAP_DEVICE_NAME_MAX + 1]; } set_dev_name; + //BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW, + struct config_adv_data_raw_args { + uint8_t *raw_adv; + uint32_t raw_adv_len; + } cfg_adv_data_raw; + //BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW, + struct config_scan_rsp_data_raw_args { + uint8_t *raw_scan_rsp; + uint32_t raw_scan_rsp_len; + } cfg_scan_rsp_data_raw; } btc_ble_gap_args_t; void btc_gap_ble_call_handler(btc_msg_t *msg); diff --git a/components/bt/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/bluedroid/stack/btm/btm_ble_gap.c index 98a8a23689..4cfce3b667 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c @@ -1298,6 +1298,26 @@ tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p return status; } +/******************************************************************************* +** +** Function BTM_BleWriteScanRspRaw +** +** Description This function is called to write raw scan response data +** +** Parameters: None. +** +** Returns void +** +*******************************************************************************/ +tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len) +{ + if (btsnd_hcic_ble_set_scan_rsp_data((UINT8)raw_scan_rsp_len, p_raw_scan_rsp)) { + return BTM_SUCCESS; + } else { + return BTM_NO_RESOURCES; + } +} + /******************************************************************************* ** ** Function BTM_BleWriteAdvData @@ -1345,6 +1365,27 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p } +/******************************************************************************* +** +** Function BTM_BleWriteAdvDataRaw +** +** Description This function is called to write raw advertising data. +** +** Parameters: None. +** +** Returns void +** +*******************************************************************************/ +tBTM_STATUS BTM_BleWriteAdvDataRaw(UINT8 *p_raw_adv, UINT32 raw_adv_len) +{ + if (btsnd_hcic_ble_set_adv_data((UINT8)raw_adv_len, p_raw_adv)) { + return BTM_SUCCESS; + } else { + return BTM_NO_RESOURCES; + } +} + + /******************************************************************************* ** ** Function BTM_BleSetRandAddress diff --git a/components/bt/bluedroid/stack/include/btm_ble_api.h b/components/bt/bluedroid/stack/include/btm_ble_api.h index c6ff180761..6eb078386c 100644 --- a/components/bt/bluedroid/stack/include/btm_ble_api.h +++ b/components/bt/bluedroid/stack/include/btm_ble_api.h @@ -936,6 +936,22 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max, tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data); +/******************************************************************************* +** +** Function BTM_BleWriteAdvDataRaw +** +** Description This function is called to write raw advertising data. +** +** Parameters: p_raw_adv : point to raw advertising data +** raw_adv_len : raw advertising data +** +** Returns BTM_SUCCESS means success. +** +*******************************************************************************/ +//extern +tBTM_STATUS BTM_BleWriteAdvDataRaw(UINT8 *p_raw_adv, UINT32 raw_adv_len); + + BOOLEAN BTM_BleSetRandAddress(BD_ADDR rand_addr); @@ -1136,6 +1152,20 @@ tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback, tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data); +/******************************************************************************* +** +** Function BTM_BleWriteScanRspRaw +** +** Description This function is called to write raw scan response data +** +** Parameters: None. +** +** Returns void +** +*******************************************************************************/ +//extern +tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len); + /******************************************************************************* ** ** Function BTM_BleObserve diff --git a/docs/api/bluetooth/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst index 088ab27dba..b605d76e4d 100644 --- a/docs/api/bluetooth/esp_gap_ble.rst +++ b/docs/api/bluetooth/esp_gap_ble.rst @@ -40,6 +40,7 @@ Macros .. doxygendefine:: ESP_BLE_ADV_FLAG_DMT_HOST_SPT .. doxygendefine:: ESP_BLE_ADV_FLAG_NON_LIMIT_DISC .. doxygendefine:: ESP_BLE_ADV_DATA_LEN_MAX +.. doxygendefine:: ESP_BLE_SCAN_RSP_DATA_LEN_MAX Type Definitions ^^^^^^^^^^^^^^^^ @@ -90,6 +91,12 @@ Structures .. doxygenstruct:: esp_ble_gap_cb_param_t::ble_scan_result_evt_param :members: +.. doxygenstruct:: esp_ble_gap_cb_param_t::ble_adv_data_raw_cmpl_evt_param + :members: + +.. doxygenstruct:: esp_ble_gap_cb_param_t::ble_scan_rsp_data_raw_cmpl_evt_param + :members: + Functions ^^^^^^^^^ @@ -107,4 +114,6 @@ Functions .. doxygenfunction:: esp_ble_gap_config_local_privacy .. doxygenfunction:: esp_ble_gap_set_device_name .. doxygenfunction:: esp_ble_resolve_adv_data +.. doxygenfunction:: esp_ble_gap_config_adv_data_raw +.. doxygenfunction:: esp_ble_gap_config_scan_rsp_data_raw diff --git a/examples/bluetooth/gatt_server/README.rst b/examples/bluetooth/gatt_server/README.rst index 85d860f285..bbfd76626c 100644 --- a/examples/bluetooth/gatt_server/README.rst +++ b/examples/bluetooth/gatt_server/README.rst @@ -3,3 +3,18 @@ ESP-IDF GATT SERVER demo This is the demo for user to use ESP_APIs to create a GATT Server. +Options choose step: + 1. make menuconfig. + 2. enter menuconfig "Component config". + 3. enter menuconfig "Example 'GATT SERVER' Config". + 4. choose your options. + +UPDATE NOTE +=========== + +2017-01-19: + 1. Use New APIs to set raw advertising data and raw scan response data. + 2. Could use macro CONFIG_SET_RAW_ADV_DATA (should use menuconfig) to config use raw advertising/scan_response + or use structure do automatically config. The macro CONFIG_SET_RAW_ADV will effect both advertising data + and scan_response data. + diff --git a/examples/bluetooth/gatt_server/main/Kconfig b/examples/bluetooth/gatt_server/main/Kconfig new file mode 100644 index 0000000000..e37d40057f --- /dev/null +++ b/examples/bluetooth/gatt_server/main/Kconfig @@ -0,0 +1,10 @@ +menu "Example 'GATT SERVER' Config" + +config SET_RAW_ADV_DATA + bool "adv data or scan_rsp data use raw data or structure" + default "y" + help + Set raw advertising data/scan response data by self or use adv_data/scan_rsp_data structure to + set advertising data/scan response data. If use structure, lower layer will encapsulate the packets. + +endmenu diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 18de5cc7b7..11b3da6473 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -30,6 +30,8 @@ #include "esp_bt_main.h" #include "esp_bt_main.h" +#include "sdkconfig.h" + #define GATTS_TAG "GATTS_DEMO" ///Declare the static function @@ -51,8 +53,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 -uint8_t char1_str[] ={0x11,0x22,0x33}; - +uint8_t char1_str[] = {0x11,0x22,0x33}; esp_attr_value_t gatts_demo_char1_val = { .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, @@ -60,7 +61,12 @@ esp_attr_value_t gatts_demo_char1_val = .attr_value = char1_str, }; - +#ifdef CONFIG_SET_RAW_ADV_DATA +static uint8_t raw_adv_data[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe}; +static uint8_t raw_scan_rsp_data[] = {0x7, 0x7, 0x7, 0x7, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, + 0xb, 0xb, 0xb, 0xb, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xe, 0xe, 0xe}; +#else static uint8_t test_service_uuid128[32] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value @@ -85,6 +91,7 @@ static esp_ble_adv_data_t test_adv_data = { .p_service_uuid = test_service_uuid128, .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), }; +#endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t test_adv_params = { .adv_int_min = 0x20, @@ -134,6 +141,12 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: esp_ble_gap_start_advertising(&test_adv_params); break; + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; default: break; } @@ -149,8 +162,12 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; esp_ble_gap_set_device_name(TEST_DEVICE_NAME); +#ifdef CONFIG_SET_RAW_ADV_DATA + esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); + esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); +#else esp_ble_gap_config_adv_data(&test_adv_data); - +#endif esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A); break; case ESP_GATTS_READ_EVT: { @@ -252,9 +269,6 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; - esp_ble_gap_set_device_name(TEST_DEVICE_NAME); - esp_ble_gap_config_adv_data(&test_adv_data); - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B); break; case ESP_GATTS_READ_EVT: { From 12b1c9996224d6435eaf2df17b11ddea81f1c02c Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Thu, 19 Jan 2017 17:32:27 +0800 Subject: [PATCH 051/139] esp32: update wifi lib to fix ap not respond BA bug Currently softap doesn't respond BA when receiving AMPDU, this fix is to fix this bug --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index ddc4b0cbc5..fc92f2e5bc 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit ddc4b0cbc59c2c63ba1f0e02a9cd4972c083782c +Subproject commit fc92f2e5bcd34fa945445e8cad47cbf1f2a4bdb6 From 3c28283377653cff1a6826ea0c9aee88ed098f61 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Thu, 19 Jan 2017 18:59:50 +0800 Subject: [PATCH 052/139] CI: fix bug that test result always fail the path of module definition file from unit test is not correct --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 81a8fba4fb..1e330320e7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -163,7 +163,7 @@ test_report: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test" REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report" - MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml" + MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/ModuleDefinition.yml" artifacts: when: always paths: @@ -328,7 +328,7 @@ deploy_docs: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" APP_NAME: "ut" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test" - MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml" + MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/ModuleDefinition.yml" dependencies: - build_esp_idf_tests From 5305842763cd0ddb209c7f83d9c82bf142c996f1 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Thu, 19 Jan 2017 23:37:12 +0800 Subject: [PATCH 053/139] CI: fix merge error on test report job the variable used to save report result is changed by merge error --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1e330320e7..9814a652be 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -184,7 +184,8 @@ test_report: - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script # generate report - - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || FAIL=True + - TEST_RESULT=Pass + - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || TEST_RESULT=Fail # commit to CI-test-result project - git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git - rm -rf CI-test-result/RawData/$RESULT_PATH From 0b257cfcefa1144579f8dfe4103a97146665fac6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 12 Jan 2017 13:30:39 +1100 Subject: [PATCH 054/139] bt: esp_ble_gatts_send_indicate: Fix description --- components/bt/bluedroid/api/include/esp_gatts_api.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bt/bluedroid/api/include/esp_gatts_api.h b/components/bt/bluedroid/api/include/esp_gatts_api.h index b18039ce79..777bbec3de 100644 --- a/components/bt/bluedroid/api/include/esp_gatts_api.h +++ b/components/bt/bluedroid/api/include/esp_gatts_api.h @@ -449,7 +449,8 @@ esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle); * @param[in] attr_handle - attribute handle to indicate. * @param[in] value_len - indicate value length. * @param[in] value: value to indicate. - * @param[in] need_confirm - if this indication expects a confirmation or not. + * @param[in] need_confirm - Whether a confirmation is required. + * false sends a GATT notification, true sends a GATT indication. * * @return * - ESP_OK : success From b022232e8415f1362ada131df253cc4e07b53ce9 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 18 Jan 2017 10:57:53 +1100 Subject: [PATCH 055/139] esp_panic.h: Add C++ include guards --- components/esp32/include/esp_panic.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/esp32/include/esp_panic.h b/components/esp32/include/esp_panic.h index aa83c6d381..e9668facc5 100644 --- a/components/esp32/include/esp_panic.h +++ b/components/esp32/include/esp_panic.h @@ -1,6 +1,10 @@ #ifndef PANIC_H #define PANIC_H +#ifdef __cplusplus +extern "C" +{ +#endif #define PANIC_RSN_NONE 0 #define PANIC_RSN_DEBUGEXCEPTION 1 @@ -59,4 +63,8 @@ void esp_clear_watchpoint(int no); #endif +#ifdef __cplusplus +} +#endif + #endif From ac412feb69abad798d6b989d23293d61092f6eaa Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 19 Jan 2017 23:46:41 +1100 Subject: [PATCH 056/139] gpio: Attach gpio intr to the isr_server on the right core. Make sure GPIO interrupts get attached to the core that the ISR service routine is running on, otherwise they don't arrive. --- components/driver/gpio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 4e83705408..f1e724dd57 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -133,10 +133,10 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) return ESP_OK; } -esp_err_t gpio_intr_enable(gpio_num_t gpio_num) +static esp_err_t gpio_intr_enable_on_core (gpio_num_t gpio_num, uint32_t core_id) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); - if (xPortGetCoreID() == 0) { + if (core_id == 0) { GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr } else { GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr @@ -144,6 +144,11 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num) return ESP_OK; } +esp_err_t gpio_intr_enable(gpio_num_t gpio_num) +{ + return gpio_intr_enable_on_core (gpio_num, xPortGetCoreID()); +} + esp_err_t gpio_intr_disable(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); @@ -380,7 +385,7 @@ esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void gpio_isr_func[gpio_num].fn = isr_handler; gpio_isr_func[gpio_num].args = args; } - gpio_intr_enable(gpio_num); + gpio_intr_enable_on_core (gpio_num, esp_intr_get_cpu(gpio_isr_handle)); portEXIT_CRITICAL(&gpio_spinlock); return ESP_OK; } From a14f22f65bf7bb69a4a11db22011cc1cd57e5ee4 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 20 Jan 2017 14:17:03 +1100 Subject: [PATCH 057/139] netconn_gethostbyname: Fix race reporting success If the DNS request is dispatched and performed very quickly, then it can complete before tcpip_callback() actually returns, in which case we'll destroy the actual err_t error value passed in the message. Use a local variable for the tcpip_callback error code so that can't happen. Resolves #269 https://github.com/espressif/esp-idf/pull/269 --- components/lwip/api/api_lib.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/lwip/api/api_lib.c b/components/lwip/api/api_lib.c index 087115f0b9..e5c247f0bc 100755 --- a/components/lwip/api/api_lib.c +++ b/components/lwip/api/api_lib.c @@ -880,10 +880,11 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr) { API_VAR_DECLARE(struct dns_api_msg, msg); + err_t localerr; #if !LWIP_MPU_COMPATIBLE sys_sem_t sem; #endif /* LWIP_MPU_COMPATIBLE */ - err_t err; + err_t err = ERR_OK; LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); @@ -918,14 +919,14 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr) } #endif /* LWIP_NETCONN_SEM_PER_THREAD */ - err = tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg)); - if (err != ERR_OK) { + localerr = tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg)); + if (localerr != ERR_OK) { #if !LWIP_NETCONN_SEM_PER_THREAD sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem)); #endif /* !LWIP_NETCONN_SEM_PER_THREAD */ API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return err; + return localerr; } sys_sem_wait(API_EXPR_REF_SEM(API_VAR_REF(msg).sem)); From 6f3f3bb30c0c9d0170fd92de7084c579427a55c2 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sat, 31 Dec 2016 01:09:54 +0000 Subject: [PATCH 058/139] Add missing bit from LEDC interrupt state struct. Resolves #191 https://github.com/espressif/esp-idf/pull/191 --- components/esp32/include/soc/ledc_struct.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/esp32/include/soc/ledc_struct.h b/components/esp32/include/soc/ledc_struct.h index d119289acd..c52f670770 100644 --- a/components/esp32/include/soc/ledc_struct.h +++ b/components/esp32/include/soc/ledc_struct.h @@ -122,6 +122,7 @@ typedef volatile struct { uint32_t lstimer1_ovf: 1; /*The interrupt status bit for low speed channel1 counter overflow event.*/ uint32_t lstimer2_ovf: 1; /*The interrupt status bit for low speed channel2 counter overflow event.*/ uint32_t lstimer3_ovf: 1; /*The interrupt status bit for low speed channel3 counter overflow event.*/ + uint32_t duty_chng_end_hsch0: 1; /*The interrupt enable bit for high speed channel 0 duty change done event.*/ uint32_t duty_chng_end_hsch1: 1; /*The interrupt status bit for high speed channel 1 duty change done event.*/ uint32_t duty_chng_end_hsch2: 1; /*The interrupt status bit for high speed channel 2 duty change done event.*/ uint32_t duty_chng_end_hsch3: 1; /*The interrupt status bit for high speed channel 3 duty change done event.*/ From 74aff89918e173fa724b38ccb2f38920db66a6c8 Mon Sep 17 00:00:00 2001 From: Mike Ryan Date: Wed, 11 Jan 2017 16:40:37 -0800 Subject: [PATCH 059/139] gatts_demo: re-enter advertising after client disconnects In the existing tree, after a connected client disconnects the device will never re-enter the advertising state. Additional clients will not be able to discover or connect to the device. This patch forces the device back into the advertising state upon disconnection. Resolves Pull Request #217 https://github.com/espressif/esp-idf/pull/217 --- examples/bluetooth/gatt_server/main/gatts_demo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 11b3da6473..a018ddb752 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -250,6 +250,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; break; case ESP_GATTS_DISCONNECT_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; case ESP_GATTS_OPEN_EVT: case ESP_GATTS_CANCEL_OPEN_EVT: case ESP_GATTS_CLOSE_EVT: From 15072028c45424f51f918048ae8d846f8592a842 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 19 Jan 2017 16:16:06 +0800 Subject: [PATCH 060/139] docs: use custom roles to generate GitHub links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change replaces direct links to GitHub master branch with auto-generated links using docutils custom roles. These auto-generated links point to the tree or blob for the git commit ID (or tag) of the repository. This is needed to ensure that links don’t become broken when files in master branch are moved around or deleted. The following roles are introduced: - :idf:`path` - points to directory inside ESP-IDF - :idf_blob:`path` - points to file inside ESP-IDF - :idf_raw:`path` - points to raw view of the file inside ESP-IDF - :component:`path` - points to directory inside ESP-IDF components dir - :component_blob:`path` - points to file inside ESP-IDF components dir - :component_raw:`path` - points to raw view of the file inside ESP-IDF components dir - :example:`path` - points to directory inside ESP-IDF examples dir - :example_blob:`path` - points to file inside ESP-IDF examples dir - :example_raw:`path` - points to raw view of the file inside ESP-IDF examples dir A check is added to the CI build script, which searches RST files for presence of hard-coded links (identified by tree/master, blob/master, or raw/master part of the URL). This check can be run manually: cd docs && make gh-linkcheck Additionally, Sphinx linkcheck build type is used to create new CI test, which check for broken links. This test has to be triggered explicitly, because including it in normal build process (when the commit is not yet deployed to Github) will not work. It can be triggered in a regular fashion using a combination of cron and Curl, similar to stress tests. --- .gitignore | 1 + .gitlab-ci.yml | 21 +++++++++++ CONTRIBUTING.rst | 2 +- components/vfs/README.rst | 2 +- docs/COPYRIGHT.rst | 4 +-- docs/Makefile | 24 +++++++++++++ docs/api/bluetooth/controller_vhci.rst | 6 ++-- docs/api/bluetooth/esp_blufi.rst | 6 ++-- docs/api/bluetooth/esp_bt_defs.rst | 2 +- docs/api/bluetooth/esp_bt_device.rst | 2 +- docs/api/bluetooth/esp_bt_main.rst | 2 +- docs/api/bluetooth/esp_gap_ble.rst | 8 ++--- docs/api/bluetooth/esp_gatt_defs.rst | 2 +- docs/api/bluetooth/esp_gattc.rst | 8 ++--- docs/api/bluetooth/esp_gatts.rst | 8 ++--- docs/api/bluetooth/index.rst | 2 +- docs/api/ethernet/esp_eth.rst | 4 +-- docs/api/ethernet/index.rst | 2 +- docs/api/peripherals/gpio.rst | 4 +-- docs/api/peripherals/i2c.rst | 4 +-- docs/api/peripherals/index.rst | 2 +- docs/api/peripherals/ledc.rst | 4 +-- docs/api/peripherals/pcnt.rst | 4 +-- docs/api/peripherals/rmt.rst | 4 +-- docs/api/peripherals/sigmadelta.rst | 4 +-- docs/api/peripherals/spi_master.rst | 4 +-- docs/api/peripherals/timer.rst | 4 +-- docs/api/peripherals/uart.rst | 4 +-- docs/api/protocols/index.rst | 2 +- docs/api/protocols/mdns.rst | 4 +-- docs/api/storage/index.rst | 2 +- docs/api/storage/nvs_flash.rst | 10 +++--- docs/api/storage/spi_flash.rst | 4 +-- docs/api/storage/vfs.rst | 4 +-- docs/api/system/deep_sleep.rst | 2 +- docs/api/system/index.rst | 2 +- docs/api/system/intr_alloc.rst | 2 +- docs/api/system/log.rst | 10 +++--- docs/api/system/mem_alloc.rst | 4 +-- docs/api/system/ota.rst | 4 +-- docs/api/system/wdts.rst | 4 +-- docs/api/wifi/esp_smartconfig.rst | 2 +- docs/api/wifi/esp_wifi.rst | 2 +- docs/api/wifi/index.rst | 2 +- docs/build-system.rst | 2 +- docs/conf.py | 48 +++++++++----------------- docs/contributor-agreement.rst | 4 +-- docs/documenting-code.rst | 2 +- docs/link-roles.py | 34 ++++++++++++++++++ docs/make-project.rst | 2 +- docs/repo_util.py | 5 +++ docs/windows-setup.rst | 2 +- 52 files changed, 187 insertions(+), 116 deletions(-) create mode 100644 docs/link-roles.py create mode 100644 docs/repo_util.py diff --git a/.gitignore b/.gitignore index f11370493d..82f7fd3f2b 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ examples/*/*/build docs/_build/ docs/doxygen-warning-log.txt docs/xml/ +docs/man/ # Unit test app files tools/unit-test-app/sdkconfig diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 81a8fba4fb..6cbac58741 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -125,6 +125,7 @@ build_docs: - doxygen # If not building master branch, and there are Doxygen warnings, print them and bail out - test "${CI_BUILD_REF_NAME}" = "master" || test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false ) + - make gh-linkcheck - make html artifacts: paths: @@ -246,6 +247,26 @@ deploy_docs: - scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH - ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest" +check_doc_links: + stage: test + image: espressif/esp32-ci-env + tags: + - check_doc_links + only: + # can only be triggered + - triggers + script: + # must be triggered with CHECK_LINKS=Yes, otherwise exit without test + - test $CHECK_LINKS = "Yes" || exit 0 + # can only run on master branch (otherwise the commit is not on Github yet) + - test "${CI_BUILD_REF_NAME}" = "master" || exit 0 + - cd docs + - make linkcheck + artifacts: + paths: + - docs/_build/linkcheck + expire_in: 1 mos + # AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW # template for test jobs diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 5810d06b98..df40705044 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -21,7 +21,7 @@ Before sending us a Pull Request, please consider this list of points: * Is the code adequately commented for people to understand how it is structured? -* Is there documentation or examples that go with code contributions? `There are additional suggestions for writing good examples in the examples README `_. +* Is there documentation or examples that go with code contributions? There are additional suggestions for writing good examples in :idf:`examples` readme. * Are comments and documentation written in clear English, with no spelling or grammar errors? diff --git a/components/vfs/README.rst b/components/vfs/README.rst index 2ad7aa7ec2..26d857fc8d 100644 --- a/components/vfs/README.rst +++ b/components/vfs/README.rst @@ -140,7 +140,7 @@ actually is translated to to this (by the preprocessor): fprintf(__getreent()->_stderr, "42\n"); -where the ``__getreent()`` function returns a per-task pointer to ``struct _reent`` (`source `_). This structure is allocated on the TCB of each task. When a task is initialized, ``_stdin``, ``_stdout`` and ``_stderr`` members of ``struct _reent`` are set to the values of ``_stdin``, ``_stdout`` and ``_stderr`` of ``_GLOBAL_REENT`` (i.e. the structure which is used before FreeRTOS is started). +where the ``__getreent()`` function returns a per-task pointer to ``struct _reent`` (:component_file:`newlib/include/sys/reent.h#L370-L417>`). This structure is allocated on the TCB of each task. When a task is initialized, ``_stdin``, ``_stdout`` and ``_stderr`` members of ``struct _reent`` are set to the values of ``_stdin``, ``_stdout`` and ``_stderr`` of ``_GLOBAL_REENT`` (i.e. the structure which is used before FreeRTOS is started). Such a design has the following consequences: diff --git a/docs/COPYRIGHT.rst b/docs/COPYRIGHT.rst index 67b3d9bf1c..0e0d457207 100644 --- a/docs/COPYRIGHT.rst +++ b/docs/COPYRIGHT.rst @@ -14,7 +14,7 @@ Additional third party copyrighted code is included under the following licenses * Xtensa header files (components/esp32/include/xtensa) are Copyright (C) 2013 Tensilica Inc and are licensed under the MIT License as reproduce in the individual header files. -* `esptool.py`_ (bin/esptool.py) is Copyright (C) 2014-2016 Fredrik Ahlberg, Angus Gratton and is licensed under the GNU General Public License v2, as described in the file components/esptool_py/LICENSE. +* `esptool.py`_ (components/esptool_py/esptool) is Copyright (C) 2014-2016 Fredrik Ahlberg, Angus Gratton and is licensed under the GNU General Public License v2, as described in the file components/esptool_py/LICENSE. * Original parts of FreeRTOS_ (components/freertos) are Copyright (C) 2015 Real Time Engineers Ltd and is licensed under the GNU General Public License V2 with the FreeRTOS Linking Exception, as described in the file components/freertos/license.txt. @@ -96,7 +96,7 @@ Copyright (C) 2011, ChaN, all right reserved. .. _Newlib: https://sourceware.org/newlib/ .. _FreeRTOS: http://freertos.org/ -.. _esptool.py: https://github.com/themadinventor/esptool +.. _esptool.py: https://github.com/espressif/esptool .. _LWIP: http://savannah.nongnu.org/projects/lwip/ .. _TinyBasic: https://github.com/BleuLlama/TinyBasicPlus .. _miniz: https://code.google.com/archive/p/miniz/ diff --git a/docs/Makefile b/docs/Makefile index c04268ff1d..8076416b78 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -161,6 +161,30 @@ linkcheck: @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." +gh-linkcheck: + @echo "Checking for hardcoded GitHub links" + @if (find ../ -name '*.rst' | xargs grep \ + 'https://github.com/espressif/esp-idf/tree\|https://github.com/espressif/esp-idf/blob\|https://github.com/espressif/esp-idf/raw'\ + ); \ + then \ + echo "WARNINIG: Some .rst files contain hardcoded Github links."; \ + echo "Please check above output and replace links with one of the following:"; \ + echo "- :idf:\`dir\` - points to directory inside ESP-IDF"; \ + echo "- :idf_blob:\`file\` - points to file inside ESP-IDF"; \ + echo "- :idf_raw:\`file\` - points to raw view of the file inside ESP-IDF"; \ + echo "- :component:\`dir\` - points to directory inside ESP-IDF components dir"; \ + echo "- :component_blob:\`file\` - points to file inside ESP-IDF components dir"; \ + echo "- :component_raw:\`file\` - points to raw view of the file inside ESP-IDF"; \ + echo " components dir"; \ + echo "- :example:\`dir\` - points to directory inside ESP-IDF examples dir"; \ + echo "- :example_blob:\`file\` - points to file inside ESP-IDF examples dir"; \ + echo "- :example_raw:\`file\` - points to raw view of the file inside ESP-IDF"; \ + echo " examples dir"; \ + echo "These link types will point to the correct GitHub version automatically"; \ + exit 1; \ + fi + @echo "No hardcoded links found" + doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index dfad1af25e..35248cbb1e 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -11,9 +11,9 @@ Overview Application Example ------------------- -Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check :example:`bluetooth` folder in ESP-IDF examples, which contains the following example: -`ble_adv `_ +:example:`bluetooth/ble_adv` This is a BLE advertising demo with virtual HCI interface. Send Reset/ADV_PARAM/ADV_DATA/ADV_ENABLE HCI command for BLE advertising. @@ -23,7 +23,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/include/bt.h `_ + * :component_file:`bt/include/bt.h` Type Definitions ^^^^^^^^^^^^^^^^ diff --git a/docs/api/bluetooth/esp_blufi.rst b/docs/api/bluetooth/esp_blufi.rst index 442e54f5ca..5a1b1595a9 100644 --- a/docs/api/bluetooth/esp_blufi.rst +++ b/docs/api/bluetooth/esp_blufi.rst @@ -11,9 +11,9 @@ Use should concern these things: Application Example ------------------- -Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check :example:`bluetooth` folder in ESP-IDF examples, which contains the following example: -`blufi `_ +:example:`bluetooth/blufi` This is a BLUFI demo. This demo can set ESP32's wifi to softap/station/softap&station mode and config wifi connections. @@ -24,7 +24,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_blufi_api.h `_ + * :component_file:`bt/bluedroid/api/include/esp_blufi_api.h` Macros ^^^^^^ diff --git a/docs/api/bluetooth/esp_bt_defs.rst b/docs/api/bluetooth/esp_bt_defs.rst index 217dfb7620..527fe9359f 100644 --- a/docs/api/bluetooth/esp_bt_defs.rst +++ b/docs/api/bluetooth/esp_bt_defs.rst @@ -20,7 +20,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_bt_defs.h `_ + * :component_file:`bt/bluedroid/api/include/esp_bt_defs.h` Macros diff --git a/docs/api/bluetooth/esp_bt_device.rst b/docs/api/bluetooth/esp_bt_device.rst index 79c2e9c9bf..50e9dcf1a0 100644 --- a/docs/api/bluetooth/esp_bt_device.rst +++ b/docs/api/bluetooth/esp_bt_device.rst @@ -22,7 +22,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_bt_device.h `_ + * :component_file:`bt/bluedroid/api/include/esp_bt_device.h` Macros diff --git a/docs/api/bluetooth/esp_bt_main.rst b/docs/api/bluetooth/esp_bt_main.rst index f44dc7eebc..1c085a1347 100644 --- a/docs/api/bluetooth/esp_bt_main.rst +++ b/docs/api/bluetooth/esp_bt_main.rst @@ -20,7 +20,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_bt_main.h `_ + * :component_file:`bt/bluedroid/api/include/esp_bt_main.h` Macros diff --git a/docs/api/bluetooth/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst index f53b8d56ad..9b2fb1ea07 100644 --- a/docs/api/bluetooth/esp_gap_ble.rst +++ b/docs/api/bluetooth/esp_gap_ble.rst @@ -11,11 +11,11 @@ Overview Application Example ------------------- -Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following examples: +Check :example:`bluetooth` folder in ESP-IDF examples, which contains the following examples: -`gatt_server `_, `gatt_client `_ +:example:`bluetooth/gatt_server`, :example:`bluetooth/gatt_client` - The two demos use different gap api, such like advertising, scan, set device name and others. + The two demos use different GAP APIs, such like advertising, scan, set device name and others. API Reference ------------- @@ -23,7 +23,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_gap_ble_api.h `_ + * :component_file:`bt/bluedroid/api/include/esp_gap_ble_api.h` Macros diff --git a/docs/api/bluetooth/esp_gatt_defs.rst b/docs/api/bluetooth/esp_gatt_defs.rst index 621c6d95e1..11cb640279 100644 --- a/docs/api/bluetooth/esp_gatt_defs.rst +++ b/docs/api/bluetooth/esp_gatt_defs.rst @@ -20,7 +20,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_gatt_defs.h `_ + * :component_file:`bt/bluedroid/api/include/esp_gatt_defs.h` Macros diff --git a/docs/api/bluetooth/esp_gattc.rst b/docs/api/bluetooth/esp_gattc.rst index adfc225dfa..b41c7e09e3 100644 --- a/docs/api/bluetooth/esp_gattc.rst +++ b/docs/api/bluetooth/esp_gattc.rst @@ -11,11 +11,11 @@ Overview Application Example ------------------- -Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check :example:`bluetooth` folder in ESP-IDF examples, which contains the following examples: -`gatt_client `_ +:example:`bluetooth/gatt_client` - This is a gatt client demo. This demo can scan devices, connect to the gatt server and discover the service. + This is a GATT client demo. This demo can scan devices, connect to the GATT server and discover the service. API Reference @@ -24,7 +24,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_gattc_api.h `_ + * :component_file:`bt/bluedroid/api/include/esp_gattc_api.h` Macros ^^^^^^ diff --git a/docs/api/bluetooth/esp_gatts.rst b/docs/api/bluetooth/esp_gatts.rst index 4753490d4d..8f0414d67f 100644 --- a/docs/api/bluetooth/esp_gatts.rst +++ b/docs/api/bluetooth/esp_gatts.rst @@ -11,11 +11,11 @@ Overview Application Example ------------------- -Check `/examples/bluetooth `_ folder of `espressif/esp-idf `_ repository, that contains the following example: +Check :example:`bluetooth` folder in ESP-IDF examples, which contains the following example: -`gatt_server `_ +:example:`bluetooth/gatt_server` - This is a gatt server demo. Use gatt api to create a gatt server with send advertising. This gatt server can be connected and the service can be discovery. + This is a GATT server demo. Use GATT API to create a GATT server with send advertising. This GATT server can be connected and the service can be discovery. API Reference ------------- @@ -23,7 +23,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `bt/bluedroid/api/include/esp_gatts_api.h `_ + * :component_file:`bt/bluedroid/api/include/esp_gatts_api.h` Macros ^^^^^^ diff --git a/docs/api/bluetooth/index.rst b/docs/api/bluetooth/index.rst index 5a096c75ef..996a26e138 100644 --- a/docs/api/bluetooth/index.rst +++ b/docs/api/bluetooth/index.rst @@ -9,4 +9,4 @@ Bluetooth API Bluetooth LE -Example code for this API section is provided in `examples/bluetooth `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`bluetooth` directory of ESP-IDF examples. diff --git a/docs/api/ethernet/esp_eth.rst b/docs/api/ethernet/esp_eth.rst index 5702389af8..fbecdca339 100644 --- a/docs/api/ethernet/esp_eth.rst +++ b/docs/api/ethernet/esp_eth.rst @@ -4,7 +4,7 @@ ETHERNET Application Example ------------------- -ethernet example: `examples/ethernet/ethernet `_. +Ethernet example: :example:`ethernet/ethernet`. API Reference ------------- @@ -12,7 +12,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `components/ethernet/include/esp_eth.h `_ + * :component_file:`ethernet/include/esp_eth.h` Macros ^^^^^^ diff --git a/docs/api/ethernet/index.rst b/docs/api/ethernet/index.rst index 31181d23ea..6e95831d32 100644 --- a/docs/api/ethernet/index.rst +++ b/docs/api/ethernet/index.rst @@ -7,4 +7,4 @@ Ethernet API Ethernet -Example code for this API section is provided in `examples/ethernet `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`ethernet` directory of ESP-IDF examples. diff --git a/docs/api/peripherals/gpio.rst b/docs/api/peripherals/gpio.rst index 643eac1f4d..da3f4607ea 100644 --- a/docs/api/peripherals/gpio.rst +++ b/docs/api/peripherals/gpio.rst @@ -10,7 +10,7 @@ Note that GPIO6-11 are usually used for SPI flash. GPIO34-39 can only be set as Application Example ------------------- -GPIO output and input interrupt example: `examples/peripherals/gpio `_. +GPIO output and input interrupt example: :example:`peripherals/gpio`. API Reference ------------- @@ -18,7 +18,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/include/driver/driver/gpio.h `_ + * :component_file:`driver/include/driver/gpio.h` Macros ^^^^^^ diff --git a/docs/api/peripherals/i2c.rst b/docs/api/peripherals/i2c.rst index 93d863da6b..bd30a345d8 100644 --- a/docs/api/peripherals/i2c.rst +++ b/docs/api/peripherals/i2c.rst @@ -9,7 +9,7 @@ ESP32 has two I2C controllers which can be set as master mode or slave mode. Application Example ------------------- -I2C master and slave example: `examples/peripherals/i2c `_. +I2C master and slave example: :example:`peripherals/i2c`. API Reference ------------- @@ -17,7 +17,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/include/driver/i2c.h `_ + * :component_file:`driver/include/driver/i2c.h` Macros ^^^^^^ diff --git a/docs/api/peripherals/index.rst b/docs/api/peripherals/index.rst index 147a722fc6..f3c1dbe4a3 100644 --- a/docs/api/peripherals/index.rst +++ b/docs/api/peripherals/index.rst @@ -15,4 +15,4 @@ Peripherals API Remote Control -Example code for this API section is provided in `examples/peripherals `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`peripherals` directory of ESP-IDF examples. diff --git a/docs/api/peripherals/ledc.rst b/docs/api/peripherals/ledc.rst index 8c55e2413b..a1a96543dc 100644 --- a/docs/api/peripherals/ledc.rst +++ b/docs/api/peripherals/ledc.rst @@ -12,7 +12,7 @@ decrease the duty cycle gradually, allowing for fades without any processor inte Application Example ------------------- -LEDC change duty cycle and fading control example: `examples/peripherals/ledc `_. +LEDC change duty cycle and fading control example: :example:`peripherals/ledc`. API Reference ------------- @@ -20,7 +20,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/include/driver/ledc.h `_ + * :component_file:`driver/include/driver/ledc.h` Macros ^^^^^^ diff --git a/docs/api/peripherals/pcnt.rst b/docs/api/peripherals/pcnt.rst index bf4fcd0406..63e6ad6443 100644 --- a/docs/api/peripherals/pcnt.rst +++ b/docs/api/peripherals/pcnt.rst @@ -9,7 +9,7 @@ The PCNT (Pulse Counter) module is designed to count the number of rising and/or Application Example ------------------- -Pulse counter with control signal and event interrupt example: `examples/peripherals/pcnt `_. +Pulse counter with control signal and event interrupt example: :example:`peripherals/pcnt`. API Reference ------------- @@ -17,7 +17,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/pcnt.h `_ + * :component_file:`driver/include/driver/pcnt.h` Macros diff --git a/docs/api/peripherals/rmt.rst b/docs/api/peripherals/rmt.rst index 715bc46786..276ed939e1 100644 --- a/docs/api/peripherals/rmt.rst +++ b/docs/api/peripherals/rmt.rst @@ -9,7 +9,7 @@ The RMT (Remote Control) module driver can be used to send and receive infrared Application Example ------------------- -NEC remote control TX and RX example: `examples/peripherals/rmt_nec_tx_rx `_. +NEC remote control TX and RX example: :example:`peripherals/rmt_nec_tx_rx`. API Reference ------------- @@ -17,7 +17,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/rmt.h `_ + * :component_file:`driver/include/driver/rmt.h` Macros ^^^^^^ diff --git a/docs/api/peripherals/sigmadelta.rst b/docs/api/peripherals/sigmadelta.rst index 56e4d77e72..fb51ae8b03 100644 --- a/docs/api/peripherals/sigmadelta.rst +++ b/docs/api/peripherals/sigmadelta.rst @@ -10,7 +10,7 @@ This driver configures the channels of the sigma-delta module. Application Example ------------------- -Sigma-delta Modulation example: `examples/peripherals/sigmadelta `_. +Sigma-delta Modulation example: :example:`peripherals/sigmadelta`. API Reference ------------- @@ -18,7 +18,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/sigmadelta.h `_ + * :component_file:`driver/include/driver/sigmadelta.h` Macros diff --git a/docs/api/peripherals/spi_master.rst b/docs/api/peripherals/spi_master.rst index 9e5c0eb636..78039cbd79 100644 --- a/docs/api/peripherals/spi_master.rst +++ b/docs/api/peripherals/spi_master.rst @@ -108,7 +108,7 @@ as ``tx_data`` and ``rx_data``. Application Example ------------------- -Display graphics on the ILI9341-based 320x240 LCD: `examples/peripherals/spi_master `_. +Display graphics on the ILI9341-based 320x240 LCD: :example:`peripherals/spi_master`. API Reference ------------- @@ -116,7 +116,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/include/driver/spi_master.h `_ + * :component_file:`driver/include/driver/spi_master.h` Macros ^^^^^^ diff --git a/docs/api/peripherals/timer.rst b/docs/api/peripherals/timer.rst index 203c6b0d30..7b5253fde1 100644 --- a/docs/api/peripherals/timer.rst +++ b/docs/api/peripherals/timer.rst @@ -12,7 +12,7 @@ They are all 64-bit generic timers based on 16-bit prescalers and 64-bit auto-re Application Example ------------------- -64-bit hardware timer example: `examples/peripherals/timer_group `_. +64-bit hardware timer example: :example:`peripherals/timer_group`. API Reference ------------- @@ -20,7 +20,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `components/driver/timer.h `_ + * :component_file:`driver/include/driver/timer.h` Macros ^^^^^^ diff --git a/docs/api/peripherals/uart.rst b/docs/api/peripherals/uart.rst index b00b4e0648..1392361d9f 100644 --- a/docs/api/peripherals/uart.rst +++ b/docs/api/peripherals/uart.rst @@ -11,7 +11,7 @@ Overview Application Example ------------------- -Configure uart settings and install uart driver to read/write using UART0 and UART1 interfaces: `examples/peripherals/uart `_. +Configure uart settings and install uart driver to read/write using UART0 and UART1 interfaces: :example:`peripherals/uart`. API Reference ------------- @@ -19,7 +19,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `driver/include/driver/uart.h `_ + * :component_file:`driver/include/driver/uart.h` Data Structures ^^^^^^^^^^^^^^^ diff --git a/docs/api/protocols/index.rst b/docs/api/protocols/index.rst index 9a3a9a0c2f..b5572d8cd6 100644 --- a/docs/api/protocols/index.rst +++ b/docs/api/protocols/index.rst @@ -7,4 +7,4 @@ Protocols API mDNS -Example code for this API section is provided in `examples/protocols `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`protocols` directory of ESP-IDF examples. diff --git a/docs/api/protocols/mdns.rst b/docs/api/protocols/mdns.rst index 6214883965..1355642de1 100644 --- a/docs/api/protocols/mdns.rst +++ b/docs/api/protocols/mdns.rst @@ -163,7 +163,7 @@ Example of using the methods above: Application Example ------------------- -mDNS server/scanner example: `examples/protocols/mdns `_. +mDNS server/scanner example: :example:`protocols/mdns`. API Reference ------------- @@ -171,7 +171,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `components/mdns/include/mdns.h `_ + * :component_file:`mdns/include/mdns.h` Macros ^^^^^^ diff --git a/docs/api/storage/index.rst b/docs/api/storage/index.rst index bf21cc9eea..207ad01ccb 100644 --- a/docs/api/storage/index.rst +++ b/docs/api/storage/index.rst @@ -11,4 +11,4 @@ Storage API FAT Filesystem -Example code for this API section is provided in `examples/storage `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`storage` directory of ESP-IDF examples. diff --git a/docs/api/storage/nvs_flash.rst b/docs/api/storage/nvs_flash.rst index 9e97c3a811..ce1af94546 100644 --- a/docs/api/storage/nvs_flash.rst +++ b/docs/api/storage/nvs_flash.rst @@ -3,9 +3,9 @@ Application Example ------------------- -Two examples are provided in ESP-IDF `examples/storage `_ directory: +Two examples are provided in :example:`storage` directory of ESP-IDF examples: -`nvs_rw_value `_ +:example:`storage/nvs_rw_value` Demonstrates how to read and write a single integer value using NVS. @@ -13,7 +13,7 @@ Two examples are provided in ESP-IDF `examples/storage `_ +:example:`storage/nvs_rw_blob` Demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP32 module restarts. @@ -29,8 +29,8 @@ API Reference Header Files ^^^^^^^^^^^^ - * `nvs_flash/include/nvs_flash.h `_ - * `nvs_flash/include/nvs.h `_ + * :component_file:`nvs_flash/include/nvs_flash.h` + * :component_file:`nvs_flash/include/nvs.h` Macros ^^^^^^ diff --git a/docs/api/storage/spi_flash.rst b/docs/api/storage/spi_flash.rst index 209b413779..ab03b38faa 100644 --- a/docs/api/storage/spi_flash.rst +++ b/docs/api/storage/spi_flash.rst @@ -13,8 +13,8 @@ API Reference Header Files ^^^^^^^^^^^^ - * `spi_flash/include/esp_spi_flash.h `_ - * `spi_flash/include/esp_partition.h `_ + * :component_file:`spi_flash/include/esp_spi_flash.h` + * :component_file:`spi_flash/include/esp_partition.h` Macros ^^^^^^ diff --git a/docs/api/storage/vfs.rst b/docs/api/storage/vfs.rst index d4e5d24ab7..0035229d83 100644 --- a/docs/api/storage/vfs.rst +++ b/docs/api/storage/vfs.rst @@ -13,8 +13,8 @@ API Reference Header Files ^^^^^^^^^^^^ - * `vfs/include/esp_vfs.h `_ - * `vfs/include/esp_vfs_dev.h `_ + * :component_file:`vfs/include/esp_vfs.h` + * :component_file:`vfs/include/esp_vfs_dev.h` Macros ^^^^^^ diff --git a/docs/api/system/deep_sleep.rst b/docs/api/system/deep_sleep.rst index 393d5f025e..87986026df 100644 --- a/docs/api/system/deep_sleep.rst +++ b/docs/api/system/deep_sleep.rst @@ -90,5 +90,5 @@ The following function can be used to enter deep sleep once wakeup sources are c Application Example ------------------- -Implementation of basic functionality of deep sleep is shown in `protocols/sntp `_ example, where ESP module is periodically waken up to retrive time from NTP server. +Implementation of basic functionality of deep sleep is shown in :example:`protocols/sntp` example, where ESP module is periodically waken up to retrive time from NTP server. diff --git a/docs/api/system/index.rst b/docs/api/system/index.rst index f5746f80fd..a7d5d39018 100644 --- a/docs/api/system/index.rst +++ b/docs/api/system/index.rst @@ -12,4 +12,4 @@ System API Logging -Example code for this API section is provided in `examples/system `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`system` directory of ESP-IDF examples. diff --git a/docs/api/system/intr_alloc.rst b/docs/api/system/intr_alloc.rst index 4d2f21abac..015cc32cd2 100644 --- a/docs/api/system/intr_alloc.rst +++ b/docs/api/system/intr_alloc.rst @@ -66,7 +66,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `esp_intr_alloc.h `_ + * :component_file:`esp32/include/esp_intr_alloc.h` Macros diff --git a/docs/api/system/log.rst b/docs/api/system/log.rst index 24d3bef80a..8aadeac095 100644 --- a/docs/api/system/log.rst +++ b/docs/api/system/log.rst @@ -3,11 +3,11 @@ Application Example ------------------- -Log library is commonly used by most of esp-idf components and examples. For demonstration of log functionality check `examples `_ folder of `espressif/esp-idf `_ repository, that among others, contains the following examples: +Log library is commonly used by most of esp-idf components and examples. For demonstration of log functionality check :idf:`examples` folder of `espressif/esp-idf `_ repository, that among others, contains the following examples: -* `system/ota `_ -* `storage/sd_card `_ -* `protocols/https_request `_ +* :example:`system/ota` +* :example:`storage/sd_card` +* :example:`protocols/https_request` API Reference ------------- @@ -15,7 +15,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `log/include/esp_log.h `_ + * :component_file:`log/include/esp_log.h` Macros ^^^^^^ diff --git a/docs/api/system/mem_alloc.rst b/docs/api/system/mem_alloc.rst index cebea5b8a5..35868f755d 100644 --- a/docs/api/system/mem_alloc.rst +++ b/docs/api/system/mem_alloc.rst @@ -37,8 +37,8 @@ API Reference Header Files ^^^^^^^^^^^^ - * `esp_heap_alloc_caps.h `_ - * `heap_regions.h `_ + * :component_file:`esp32/include/esp_heap_alloc_caps.h` + * :component_file:`freertos/include/freertos/heap_regions.h` Macros diff --git a/docs/api/system/ota.rst b/docs/api/system/ota.rst index ce2fdba635..6ea4ea1f85 100644 --- a/docs/api/system/ota.rst +++ b/docs/api/system/ota.rst @@ -4,7 +4,7 @@ OTA Application Example ------------------- -Demonstration of OTA (over the air) firmware update workflow: `examples/system/ota `_. +Demonstration of OTA (over the air) firmware update workflow: :example:`system/ota`. API Reference ------------- @@ -12,7 +12,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `app_update/include/esp_ota_ops.h `_ + * :component_file:`app_update/include/esp_ota_ops.h` Macros ^^^^^^ diff --git a/docs/api/system/wdts.rst b/docs/api/system/wdts.rst index 1b476f2f79..e15ff53dd7 100644 --- a/docs/api/system/wdts.rst +++ b/docs/api/system/wdts.rst @@ -59,8 +59,8 @@ API Reference Header Files ^^^^^^^^^^^^ - * `esp32/include/esp_int_wdt.h `_ - * `esp32/include/esp_task_wdt.h `_ + * :component_file:`esp32/include/esp_int_wdt.h` + * :component_file:`esp32/include/esp_task_wdt.h` Functions diff --git a/docs/api/wifi/esp_smartconfig.rst b/docs/api/wifi/esp_smartconfig.rst index 11a6bccbfa..31295a5d45 100644 --- a/docs/api/wifi/esp_smartconfig.rst +++ b/docs/api/wifi/esp_smartconfig.rst @@ -7,7 +7,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `esp32/include/esp_smartconfig.h `_ + * :component_file:`esp32/include/esp_smartconfig.h` Type Definitions ^^^^^^^^^^^^^^^^ diff --git a/docs/api/wifi/esp_wifi.rst b/docs/api/wifi/esp_wifi.rst index 247ddf7522..042e810e39 100644 --- a/docs/api/wifi/esp_wifi.rst +++ b/docs/api/wifi/esp_wifi.rst @@ -19,7 +19,7 @@ API Reference Header Files ^^^^^^^^^^^^ - * `esp32/include/esp_wifi.h `_ + * :component_file:`esp32/include/esp_wifi.h` Macros ------ diff --git a/docs/api/wifi/index.rst b/docs/api/wifi/index.rst index aecf87fa3b..97165df6b0 100644 --- a/docs/api/wifi/index.rst +++ b/docs/api/wifi/index.rst @@ -8,4 +8,4 @@ Wi-Fi API Smart Config -Example code for this API section is provided in `examples/wifi `_ directory of ESP-IDF repository. +Example code for this API section is provided in :example:`wifi` directory of ESP-IDF examples. diff --git a/docs/build-system.rst b/docs/build-system.rst index 8f43b21176..0973eeb31f 100644 --- a/docs/build-system.rst +++ b/docs/build-system.rst @@ -464,7 +464,7 @@ The file's contents will be added to the .rodata section in flash, and are avail The names are generated from the full name of the file, as given in COMPONENT_EMBED_FILES. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. -For an example of using this technique, see `examples/protocols/https_request `_ - the certificate file contents are loaded from the text .pem file at compile time. +For an example of using this technique, see :example:`protocols/https_request` - the certificate file contents are loaded from the text .pem file at compile time. Fully Overriding The Component Makefile diff --git a/docs/conf.py b/docs/conf.py index d38d3dee9d..380a643869 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,30 +14,21 @@ import sys import os +import re +from subprocess import call, Popen, PIPE +import shlex # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('.')) +from repo_util import run_cmd_get_output # -- Run DoxyGen to prepare XML for Sphinx--------------------------------- # ref. https://github.com/rtfd/readthedocs.org/issues/388 -from subprocess import call, Popen, PIPE -import shlex - call('doxygen') -# -- Function to get output of a command ---------------------------------- -def run_cmd_get_output(cmd): - process = Popen(shlex.split(cmd), stdout=PIPE) - (output, err) = process.communicate() - exit_code = process.wait() - if exit_code != 0: - raise RuntimeError('command line program has failed') - return output - - # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. @@ -46,7 +37,7 @@ def run_cmd_get_output(cmd): # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['breathe'] +extensions = ['breathe', 'link-roles'] # Breathe extension variables breathe_projects = { "esp32-idf": "xml/" } @@ -73,22 +64,17 @@ copyright = u'2016 - 2017, Espressif' # built documents. # -# Different setup depending if script is running on ReadTheDocs or elsewhere -on_rtd = os.environ.get('READTHEDOCS') == 'True' -if on_rtd: - # The short X.Y version. - # Apparently ReadTheDocs is getting confused by other version / release - # ReadTheDocs is building specific or the latest release from GitHub. - version = '1.0' - release = '1.0' -else: - # This is supposed to be "the short X.Y version", but it's the only version - # visible when you open index.html. - # Display full version to make things less confusing. - # If needed, nearest tag is returned by 'git describe --abbrev=0'. - version = run_cmd_get_output('git describe') - # The full version, including alpha/beta/rc tags. - release = run_cmd_get_output('git describe') +# Readthedocs largely ignores 'version' and 'release', and displays one of +# 'latest', tag name, or branch name, depending on the build type. +# Still, this is useful for non-RTD builds. +# This is supposed to be "the short X.Y version", but it's the only version +# visible when you open index.html. +# Display full version to make things less confusing. +version = run_cmd_get_output('git describe') +# The full version, including alpha/beta/rc tags. +# If needed, nearest tag is returned by 'git describe --abbrev=0'. +release = version +print 'Version: {0} Release: {1}'.format(version, release) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/contributor-agreement.rst b/docs/contributor-agreement.rst index a7919da8f8..aac25ad4fd 100644 --- a/docs/contributor-agreement.rst +++ b/docs/contributor-agreement.rst @@ -12,8 +12,8 @@ Framework (esp-idf) ("We" or "Us"). The purpose of this contributor agreement ("Agreement") is to clarify and document the rights granted by contributors to Us. To make this -document effective, please follow the instructions at -https://github.com/espressif/esp-idf/blob/master/CONTRIBUTING.rst. +document effective, please follow the instructions at +:idf_file:`CONTRIBUTING.rst` 1. DEFINITIONS ~~~~~~~~~~~~~~ diff --git a/docs/documenting-code.rst b/docs/documenting-code.rst index a73e26de4b..a201dafb8c 100644 --- a/docs/documenting-code.rst +++ b/docs/documenting-code.rst @@ -135,7 +135,7 @@ OK, but I am new to Sphinx! --------------------------- 1. No worries. All the software you need is well documented. It is also open source and free. Start by checking `Sphinx `_ documentation. If you are not clear how to write using rst markup language, see `reStructuredText Primer `_. -2. Check the source files of this documentation to understand what is behind of what you see now on the screen. Sources are maintained on GitHub in `espressif/esp-idf`_ repository in `/docs `_ folder. You can go directly to the source file of this page by scrolling up and clicking the link in the top right corner. When on GitHub, see what's really inside, open source files by clicking ``Raw`` button. +2. Check the source files of this documentation to understand what is behind of what you see now on the screen. Sources are maintained on GitHub in `espressif/esp-idf`_ repository in :idf:`docs` folder. You can go directly to the source file of this page by scrolling up and clicking the link in the top right corner. When on GitHub, see what's really inside, open source files by clicking ``Raw`` button. 3. You will likely want to see how documentation builds and looks like before posting it on the GitHub. There are two options to do so: * Install `Sphinx `_, `Breathe `_ and `Doxygen `_ to build it locally. You would need a Linux machine for that. diff --git a/docs/link-roles.py b/docs/link-roles.py new file mode 100644 index 0000000000..e774721922 --- /dev/null +++ b/docs/link-roles.py @@ -0,0 +1,34 @@ +# based on http://protips.readthedocs.io/link-roles.html + +from docutils import nodes +from repo_util import run_cmd_get_output + +def get_github_rev(): + path = run_cmd_get_output('git rev-parse --short HEAD') + tag = run_cmd_get_output('git describe --exact-match') + print 'Git commit ID: ', path + if len(tag): + print 'Git tag: ', tag + path = tag + return path + + +def setup(app): + baseurl = 'https://github.com/espressif/esp-idf' + rev = get_github_rev() + app.add_role('idf', autolink('{}/tree/{}/%s'.format(baseurl, rev))) + app.add_role('idf_file', autolink('{}/blob/{}/%s'.format(baseurl, rev))) + app.add_role('idf_raw', autolink('{}/raw/{}/%s'.format(baseurl, rev))) + app.add_role('component', autolink('{}/tree/{}/components/%s'.format(baseurl, rev))) + app.add_role('component_file', autolink('{}/blob/{}/components/%s'.format(baseurl, rev))) + app.add_role('component_raw', autolink('{}/raw/{}/components/%s'.format(baseurl, rev))) + app.add_role('example', autolink('{}/tree/{}/examples/%s'.format(baseurl, rev))) + app.add_role('example_file', autolink('{}/blob/{}/examples/%s'.format(baseurl, rev))) + app.add_role('example_raw', autolink('{}/raw/{}/examples/%s'.format(baseurl, rev))) + +def autolink(pattern): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + url = pattern % (text,) + node = nodes.reference(rawtext, text, refuri=url, **options) + return [node], [] + return role diff --git a/docs/make-project.rst b/docs/make-project.rst index e72bb81dd0..0bfac801bb 100644 --- a/docs/make-project.rst +++ b/docs/make-project.rst @@ -4,7 +4,7 @@ Build and Flash with Make Finding a project ----------------- -As well as the `esp-idf-template `_ project mentioned in the setup guide, esp-idf comes with some example projects on github in the `examples `_ directory. +As well as the `esp-idf-template `_ project mentioned in the setup guide, ESP-IDF comes with some example projects on github in the :idf:`examples` directory. Once you've found the project you want to work with, change to its directory and you can configure and build it: diff --git a/docs/repo_util.py b/docs/repo_util.py new file mode 100644 index 0000000000..6249c11df1 --- /dev/null +++ b/docs/repo_util.py @@ -0,0 +1,5 @@ +import re +import os + +def run_cmd_get_output(cmd): + return os.popen(cmd).read().strip() diff --git a/docs/windows-setup.rst b/docs/windows-setup.rst index 00205fb78b..996eacee56 100644 --- a/docs/windows-setup.rst +++ b/docs/windows-setup.rst @@ -23,7 +23,7 @@ As an alternative to getting a pre-prepared environment, you can set up the envi * Run through the installer steps, and accept the "Run MSYS2 now" option at the end. A window will open with a MSYS2 terminal. -* The ESP-IDF repository on github contains a script in the tools directory titled ``windows_install_prerequisites.sh``. If you haven't downloaded the ESP-IDF yet, that's OK - you can just `download that one file in Raw format from here `_. Save it somewhere on your computer. +* The ESP-IDF repository on github contains a script in the tools directory titled ``windows_install_prerequisites.sh``. If you haven't downloaded the ESP-IDF yet, that's OK - you can just download that one file in Raw format from here: :idf_raw:`tools/windows/windows_install_prerequisites.sh`. Save it somewhere on your computer. * Type the path to the shell script into the MSYS2 terminal window. You can type it as a normal Windows path, but use forward-slashes instead of back-slashes. ie: ``C:/Users/myuser/Downloads/windows_install_prerequisites.sh``. You can read the script beforehand to check what it does. From b4a29f52404fb82988f44230a5a421a256d25a44 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 20 Jan 2017 15:46:09 +0800 Subject: [PATCH 061/139] ci: deploy code and docs for release branches Currently deploy happens only for the master branch. This change is needed to support release branches. --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9814a652be..da957619a6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -206,6 +206,7 @@ push_master_to_github: stage: deploy only: - master + - /^release\/v.*$/ tags: - deploy when: on_success @@ -229,6 +230,7 @@ deploy_docs: stage: deploy only: - master + - /^release\/v.*$/ - triggers tags: - deploy From 95c150fe2c77af7f7d4f19d4807aaea0a818e9a6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 4 Jan 2017 17:37:15 +1100 Subject: [PATCH 062/139] spiflash: Add spi_flash_read_encrypted() function --- components/spi_flash/flash_ops.c | 27 ++++++++++++++++++++ components/spi_flash/include/esp_spi_flash.h | 17 ++++++++++++ 2 files changed, 44 insertions(+) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index a74558a96f..22070eb5ff 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -381,6 +381,33 @@ out: return spi_flash_translate_rc(rc); } +#define FLASH_PAGE_SIZE 0x10000 + +esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size) +{ + if (src + size > g_rom_flashchip.chip_size) { + return ESP_ERR_INVALID_SIZE; + } + if (size == 0) { + return ESP_OK; + } + + esp_err_t err; + const uint8_t *map; + spi_flash_mmap_handle_t map_handle; + size_t map_src = src & ~(FLASH_PAGE_SIZE-1); + size_t map_size = size + (src - map_src); + + err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle); + if (err != ESP_OK) { + return err; + } + memcpy(dstv, map + (src - map_src), size); + spi_flash_munmap(map_handle); + return err; +} + + static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc) { switch (rc) { diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index bf897e8995..d0b6cd20b9 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -116,6 +116,23 @@ esp_err_t spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t si */ esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size); + +/** + * @brief Read data from Encrypted Flash. + * + * If flash encryption is enabled, this function will transparently decrypt data as it is read. + * If flash encryption is not enabled, this function behaves the same as spi_flash_read(). + * + * See @ref esp_flash_encryption_enabled() for a function to check if flash encryption is enabled. + * + * @param src source address of the data in Flash. + * @param dest pointer to the destination buffer + * @param size length of data + * + * @return esp_err_t + */ +esp_err_t spi_flash_read_encrypted(size_t src, void *dstv, size_t size); + /** * @brief Enumeration which specifies memory space requested in an mmap call */ From 36ccdee6ecd35c4b60eb95b97c510ba4794cb645 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 5 Jan 2017 15:51:02 +1100 Subject: [PATCH 063/139] spi_flash: Flush flash cache if flash_mmap()ing a written-to page Without this, it's possible for stale information to be read from cache via mmap, even if the MMU table entry had been invalidated prior to writing flash (if the same MMU table entry was re-used after writing flash.) --- components/spi_flash/cache_utils.h | 8 +++ components/spi_flash/flash_mmap.c | 69 +++++++++++++++++++++ components/spi_flash/flash_ops.c | 10 +++ components/spi_flash/test/test_config.h | 24 +++++++ components/spi_flash/test/test_mmap.c | 54 +++++++++++++++- components/spi_flash/test/test_read_write.c | 4 +- components/spi_flash/test/test_spi_flash.c | 7 ++- 7 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 components/spi_flash/test/test_config.h diff --git a/components/spi_flash/cache_utils.h b/components/spi_flash/cache_utils.h index 598b8fba77..9cd9ad6b49 100644 --- a/components/spi_flash/cache_utils.h +++ b/components/spi_flash/cache_utils.h @@ -48,4 +48,12 @@ void spi_flash_disable_interrupts_caches_and_other_cpu_no_os(); // This function is implied to be called when other CPU is not running or running code from IRAM. void spi_flash_enable_interrupts_caches_no_os(); +// Mark the pages containing a flash region as having been +// erased or written to. This means the flash cache needs +// to be evicted before these pages can be flash_mmap()ed again, +// as they may contain stale data +// +// Only call this while holding spi_flash_op_lock() +void spi_flash_mark_modified_region(uint32_t start_addr, uint32_t length); + #endif //ESP_SPI_FLASH_CACHE_UTILS_H diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 15f75f3634..0b83ac33c0 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -46,6 +46,15 @@ #define VADDR1_FIRST_USABLE_ADDR 0x400D0000 #define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / FLASH_PAGE_SIZE + 64) +/* Ensure pages in a region haven't been marked as written via + spi_flash_mark_modified_region(). If the page has + been written, flush the entire flash cache before returning. + + This ensures stale cache entries are never read after fresh calls + to spi_flash_mmap(), while keeping the number of cache flushes to a + minimum. +*/ +static void spi_flash_ensure_unmodified_region(size_t start_addr, size_t length); typedef struct mmap_entry_{ uint32_t handle; @@ -91,7 +100,11 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ if (src_addr + size > g_rom_flashchip.chip_size) { return ESP_ERR_INVALID_ARG; } + spi_flash_disable_interrupts_caches_and_other_cpu(); + + spi_flash_ensure_unmodified_region(src_addr, size); + if (s_mmap_page_refcnt[0] == 0) { spi_flash_mmap_init(); } @@ -212,3 +225,59 @@ void spi_flash_mmap_dump() } } } + +/* 256-bit (up to 16MB of 64KB pages) bitset of all flash pages + that have been written to since last cache flush. + + Before mmaping a page, need to flush caches if that page has been + written to. + + Note: It's possible to do some additional performance tweaks to + this algorithm, as we actually only need to flush caches if a page + was first mmapped, then written to, then is about to be mmaped a + second time. This is a fair bit more complex though, so unless + there's an access pattern that this would significantly boost then + it's probably not worth it. +*/ +static uint32_t written_pages[256/32]; + +static void update_written_pages(size_t start_addr, size_t length, bool mark); + +void IRAM_ATTR spi_flash_mark_modified_region(size_t start_addr, size_t length) +{ + update_written_pages(start_addr, length, true); +} + +static void IRAM_ATTR spi_flash_ensure_unmodified_region(size_t start_addr, size_t length) +{ + update_written_pages(start_addr, length, false); +} + +/* generic implementation for the previous two functions */ +static inline IRAM_ATTR void update_written_pages(size_t start_addr, size_t length, bool mark) +{ + for (uint32_t addr = start_addr; addr < start_addr + length; addr += FLASH_PAGE_SIZE) { + int page = addr / FLASH_PAGE_SIZE; + if (page >= 256) { + return; /* invalid address */ + } + + int idx = page / 32; + uint32_t bit = 1 << (page % 32); + + if (mark) { + written_pages[idx] |= bit; + } else if (written_pages[idx] & bit) { + /* it is tempting to write a version of this that only + flushes each CPU's cache as needed. However this is + tricky because mmaped memory can be used on un-pinned + cores, or the pointer passed between CPUs. + */ + Cache_Flush(0); +#ifndef CONFIG_FREERTOS_UNICORE + Cache_Flush(1); +#endif + bzero(written_pages, sizeof(written_pages)); + } + } +} diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 22070eb5ff..4bcb7b3aef 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -250,6 +250,11 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size) } out: COUNTER_STOP(write); + + spi_flash_op_lock(); + spi_flash_mark_modified_region(dst, size); + spi_flash_op_unlock(); + return spi_flash_translate_rc(rc); } @@ -286,6 +291,11 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, bzero(encrypt_buf, sizeof(encrypt_buf)); } COUNTER_ADD_BYTES(write, size); + + spi_flash_op_lock(); + spi_flash_mark_modified_region(dest_addr, size); + spi_flash_op_unlock(); + return spi_flash_translate_rc(rc); } diff --git a/components/spi_flash/test/test_config.h b/components/spi_flash/test/test_config.h new file mode 100644 index 0000000000..45e73661bb --- /dev/null +++ b/components/spi_flash/test/test_config.h @@ -0,0 +1,24 @@ +// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Common header for SPI flash test data +#pragma once + +/* Define a region of flash we can mess up for testing... + + This is pretty ugly, better to do something with a partition but + this is OK for now. + */ +#define TEST_REGION_START 0x180000 +#define TEST_REGION_END 0x1E0000 diff --git a/components/spi_flash/test/test_mmap.c b/components/spi_flash/test/test_mmap.c index d3d16802ea..464a876428 100644 --- a/components/spi_flash/test/test_mmap.c +++ b/components/spi_flash/test/test_mmap.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,14 +8,17 @@ #include #include #include +#include -uint32_t buffer[1024]; +#include "test_config.h" +static uint32_t buffer[1024]; + +/* read-only region used for mmap tests */ static const uint32_t start = 0x100000; static const uint32_t end = 0x200000; - TEST_CASE("Prepare data for mmap tests", "[mmap]") { srand(0); @@ -81,3 +85,49 @@ TEST_CASE("Can mmap into data address space", "[mmap]") printf("Unmapping handle3\n"); spi_flash_munmap(handle3); } + +TEST_CASE("flash_mmap invalidates just-written data", "[spi_flash]") +{ + spi_flash_mmap_handle_t handle1; + const void *ptr1; + + const size_t test_size = 128; + + if (esp_flash_encryption_enabled()) { + TEST_IGNORE_MESSAGE("flash encryption enabled, spi_flash_write_encrypted() test won't pass as-is"); + } + + ESP_ERROR_CHECK( spi_flash_erase_sector(TEST_REGION_START / SPI_FLASH_SEC_SIZE) ); + + /* map erased test region to ptr1 */ + ESP_ERROR_CHECK( spi_flash_mmap(TEST_REGION_START, test_size, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); + printf("mmap_res ptr1: handle=%d ptr=%p\n", handle1, ptr1); + + /* verify it's all 0xFF */ + for (int i = 0; i < test_size; i++) { + TEST_ASSERT_EQUAL_HEX(0xFF, ((uint8_t *)ptr1)[i]); + } + + /* unmap the erased region */ + spi_flash_munmap(handle1); + + /* write flash region to 0xEE */ + uint8_t buf[test_size]; + memset(buf, 0xEE, test_size); + ESP_ERROR_CHECK( spi_flash_write(TEST_REGION_START, buf, test_size) ); + + /* re-map the test region at ptr1. + + this is a fresh mmap call so should trigger a cache flush, + ensuring we see the updated flash. + */ + ESP_ERROR_CHECK( spi_flash_mmap(TEST_REGION_START, test_size, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); + printf("mmap_res ptr1 #2: handle=%d ptr=%p\n", handle1, ptr1); + + /* assert that ptr1 now maps to the new values on flash, + ie contents of buf array. + */ + TEST_ASSERT_EQUAL_HEX8_ARRAY(buf, ptr1, test_size); + + spi_flash_munmap(handle1); +} diff --git a/components/spi_flash/test/test_read_write.c b/components/spi_flash/test/test_read_write.c index c9067463e4..37edbbb944 100644 --- a/components/spi_flash/test/test_read_write.c +++ b/components/spi_flash/test/test_read_write.c @@ -27,8 +27,10 @@ #include "soc/timer_group_struct.h" #include "soc/timer_group_reg.h" +#include "test_config.h" + /* Base offset in flash for tests. */ -#define FLASH_BASE 0x120000 +#define FLASH_BASE TEST_REGION_START #ifndef CONFIG_SPI_FLASH_MINIMAL_TEST #define CONFIG_SPI_FLASH_MINIMAL_TEST 1 diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index ecc472ac0e..90d0cc1fdc 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -7,6 +7,8 @@ #include #include +#include "test_config.h" + struct flash_test_ctx { uint32_t offset; bool fail; @@ -31,8 +33,7 @@ static void flash_test_task(void *arg) vTaskDelay(0 / portTICK_PERIOD_MS); uint32_t val = 0xabcd1234; - const uint32_t n = 4096; - for (uint32_t offset = 0; offset < n; offset += 4) { + for (uint32_t offset = 0; offset < SPI_FLASH_SEC_SIZE; offset += 4) { if (spi_flash_write(sector * SPI_FLASH_SEC_SIZE + offset, (const uint8_t *) &val, 4) != ESP_OK) { printf("Write failed at offset=%d\r\n", offset); ctx->fail = true; @@ -44,7 +45,7 @@ static void flash_test_task(void *arg) vTaskDelay(0 / portTICK_PERIOD_MS); uint32_t val_read; - for (uint32_t offset = 0; offset < n; offset += 4) { + for (uint32_t offset = 0; offset < SPI_FLASH_SEC_SIZE; offset += 4) { if (spi_flash_read(sector * SPI_FLASH_SEC_SIZE + offset, (uint8_t *) &val_read, 4) != ESP_OK) { printf("Read failed at offset=%d\r\n", offset); ctx->fail = true; From adc590ff69181fa5f4b1088f06446ee2218c2149 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 4 Jan 2017 17:53:15 +1100 Subject: [PATCH 064/139] spi_flash_write_encrypted: Allow 16-byte aligned block writes As each 32 byte write has two identical 16 byte AES blocks, it's possible to write them separately. --- components/spi_flash/flash_ops.c | 54 ++++++++--- components/spi_flash/include/esp_spi_flash.h | 14 +-- .../spi_flash/test/test_flash_encryption.c | 91 +++++++++++++++++++ 3 files changed, 140 insertions(+), 19 deletions(-) create mode 100644 components/spi_flash/test/test_flash_encryption.c diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 4bcb7b3aef..76a5a6171d 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -90,7 +90,7 @@ size_t spi_flash_get_chip_size() return g_rom_flashchip.chip_size; } -SpiFlashOpResult IRAM_ATTR spi_flash_unlock() +static SpiFlashOpResult IRAM_ATTR spi_flash_unlock() { static bool unlocked = false; if (!unlocked) { @@ -260,30 +260,58 @@ out: esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size) { - if ((dest_addr % 32) != 0) { + const uint8_t *ssrc = (const uint8_t *)src; + if ((dest_addr % 16) != 0) { return ESP_ERR_INVALID_ARG; } - if ((size % 32) != 0) { + if ((size % 16) != 0) { return ESP_ERR_INVALID_SIZE; } - if ((uint32_t) src < 0x3ff00000) { - // if source address is in DROM, we won't be able to read it - // from within SPIWrite - // TODO: consider buffering source data using heap and writing it anyway? - return ESP_ERR_INVALID_ARG; - } + COUNTER_START(); spi_flash_disable_interrupts_caches_and_other_cpu(); SpiFlashOpResult rc; rc = spi_flash_unlock(); + spi_flash_enable_interrupts_caches_and_other_cpu(); + if (rc == SPI_FLASH_RESULT_OK) { /* SPI_Encrypt_Write encrypts data in RAM as it writes, so copy to a temporary buffer - 32 bytes at a time. + + Each call to SPI_Encrypt_Write takes a 32 byte "row" of + data to encrypt, and each row is two 16 byte AES blocks + that share a key (as derived from flash address). */ - uint32_t encrypt_buf[32/sizeof(uint32_t)]; - for (size_t i = 0; i < size; i += 32) { - memcpy(encrypt_buf, ((const uint8_t *)src) + i, 32); - rc = SPI_Encrypt_Write((uint32_t) dest_addr + i, encrypt_buf, 32); + uint8_t encrypt_buf[32] __attribute__((aligned(4))); + uint32_t row_size; + for (size_t i = 0; i < size; i += row_size) { + uint32_t row_addr = dest_addr + i; + if (i == 0 && (row_addr % 32) != 0) { + /* writing to second block of a 32 byte row */ + row_size = 16; + row_addr -= 16; + /* copy to second block in buffer */ + memcpy(encrypt_buf + 16, ssrc + i, 16); + /* decrypt the first block from flash, will reencrypt to same bytes */ + spi_flash_read_encrypted(row_addr, encrypt_buf, 16); + } + else if (size - i == 16) { + /* 16 bytes left, is first block of a 32 byte row */ + row_size = 16; + /* copy to first block in buffer */ + memcpy(encrypt_buf, ssrc + i, 16); + /* decrypt the second block from flash, will reencrypt to same bytes */ + spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16); + } + else { + /* Writing a full 32 byte row (2 blocks) */ + row_size = 32; + memcpy(encrypt_buf, ssrc + i, 32); + } + + spi_flash_disable_interrupts_caches_and_other_cpu(); + rc = SPI_Encrypt_Write(row_addr, (uint32_t *)encrypt_buf, 32); + spi_flash_enable_interrupts_caches_and_other_cpu(); if (rc != SPI_FLASH_RESULT_OK) { break; } diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index d0b6cd20b9..32ab3a6853 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -92,14 +92,16 @@ esp_err_t spi_flash_write(size_t dest_addr, const void *src, size_t size); * * @note Flash encryption must be enabled for this function to work. * - * @note Address in flash, dest, has to be 32-byte aligned. + * @note Destination flash address and length must be 16-byte + * aligned. Due to hardware limitations, this function is more + * efficient if both these arguments are 32-byte aligned. This is + * because the encryption engine natively deals with 32-byte rows of + * two AES blocks. Writing half a row (16 bytes) requires reading out + * the other 16 bytes and re-encrypting them back to the same value. * - * @note If source address is in DROM, this function will return - * ESP_ERR_INVALID_ARG. - * - * @param dest_addr destination address in Flash. Must be a multiple of 32 bytes. + * @param dest_addr destination address in Flash. Must be a multiple of 16 bytes. * @param src pointer to the source buffer. - * @param size length of data, in bytes. Must be a multiple of 32 bytes. + * @param size length of data, in bytes. Must be a multiple of 16 bytes. * * @return esp_err_t */ diff --git a/components/spi_flash/test/test_flash_encryption.c b/components/spi_flash/test/test_flash_encryption.c new file mode 100644 index 0000000000..b8d8018ae4 --- /dev/null +++ b/components/spi_flash/test/test_flash_encryption.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "test_config.h" + +static void test_encrypted_write(size_t offset, const uint8_t *data, size_t length); +static void verify_erased_flash(size_t offset, size_t length); + +TEST_CASE("test 16 byte encrypted writes", "[spi_flash]") +{ + if (!esp_flash_encryption_enabled()) { + TEST_IGNORE_MESSAGE("flash encryption disabled, skipping spi_flash_write_encrypted() tests"); + } + + TEST_ASSERT_EQUAL_HEX(ESP_OK, + spi_flash_erase_sector(TEST_REGION_START / SPI_FLASH_SEC_SIZE)); + + uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47 + for(int i = 0; i < sizeof(fortyeight_bytes); i++) { + fortyeight_bytes[i] = i; + } + + /* Verify unaligned start or length fails */ + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, + spi_flash_write_encrypted(TEST_REGION_START+1, fortyeight_bytes, 32)); + + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE, + spi_flash_write_encrypted(TEST_REGION_START, fortyeight_bytes, 15)); + + /* ensure nothing happened to the flash yet */ + verify_erased_flash(TEST_REGION_START, 0x20); + + /* Write 32 byte block, this is the "normal" encrypted write */ + test_encrypted_write(TEST_REGION_START, fortyeight_bytes, 0x20); + verify_erased_flash(TEST_REGION_START + 0x20, 0x20); + + /* Slip in an unaligned spi_flash_read_encrypted() test */ + uint8_t buf[0x10]; + spi_flash_read_encrypted(TEST_REGION_START+0x10, buf, 0x10); + TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16); + + /* Write 16 bytes unaligned */ + test_encrypted_write(TEST_REGION_START + 0x30, fortyeight_bytes, 0x10); + /* the 16 byte regions before and after the 16 bytes we just wrote should still be 0xFF */ + verify_erased_flash(TEST_REGION_START + 0x20, 0x10); + verify_erased_flash(TEST_REGION_START + 0x40, 0x10); + + /* Write 48 bytes starting at a 32-byte aligned offset */ + test_encrypted_write(TEST_REGION_START + 0x40, fortyeight_bytes, 0x30); + /* 16 bytes after this write should still be 0xFF -unencrypted- */ + verify_erased_flash(TEST_REGION_START + 0x70, 0x10); + + /* Write 48 bytes starting at a 16-byte aligned offset */ + test_encrypted_write(TEST_REGION_START + 0x90, fortyeight_bytes, 0x30); + /* 16 bytes after this write should still be 0xFF -unencrypted- */ + verify_erased_flash(TEST_REGION_START + 0x120, 0x10); +} + +static void test_encrypted_write(size_t offset, const uint8_t *data, size_t length) +{ + uint8_t readback[length]; + printf("encrypt %d bytes at 0x%x\n", length, offset); + TEST_ASSERT_EQUAL_HEX(ESP_OK, + spi_flash_write_encrypted(offset, data, length)); + + TEST_ASSERT_EQUAL_HEX(ESP_OK, + spi_flash_read_encrypted(offset, readback, length)); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(data, readback, length); +} + +static void verify_erased_flash(size_t offset, size_t length) +{ + uint8_t readback[length]; + printf("verify erased 0x%x - 0x%x\n", offset, offset + length); + TEST_ASSERT_EQUAL_HEX(ESP_OK, + spi_flash_read(offset, readback, length)); + for (int i = 0; i < length; i++) { + char message[32]; + sprintf(message, "unerased flash @ 0x%08x", offset + i); + TEST_ASSERT_EQUAL_HEX_MESSAGE(0xFF, readback[i], message); + } +} + From 14aa1d1b3e979e3f85b0c4669e1bd0e00cb9837b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 6 Jan 2017 11:17:29 +1100 Subject: [PATCH 065/139] docs: spi_flash: Add flash encryption ops, remove boilerplate --- components/spi_flash/include/esp_partition.h | 7 +++++++ components/spi_flash/include/esp_spi_flash.h | 18 ++++++++++-------- docs/api/storage/spi_flash.rst | 11 ++++------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index b149e10234..28f8551dcb 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -191,6 +191,13 @@ esp_err_t esp_partition_read(const esp_partition_t* partition, * Before writing data to flash, corresponding region of flash needs to be erased. * This can be done using esp_partition_erase_range function. * + * Partitions marked with an encryption flag will automatically be + * written via the spi_flash_write_encrypted() function. If writing to + * an encrypted partition, all write offsets and lengths must be + * multiples of 16 bytes. See the spi_flash_write_encrypted() function + * for more details. Unencrypted partitions do not have this + * restriction. + * * @param partition Pointer to partition structure obtained using * esp_partition_find_first or esp_partition_get. * Must be non-NULL. diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 32ab3a6853..3761ec665d 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -92,12 +92,14 @@ esp_err_t spi_flash_write(size_t dest_addr, const void *src, size_t size); * * @note Flash encryption must be enabled for this function to work. * - * @note Destination flash address and length must be 16-byte - * aligned. Due to hardware limitations, this function is more - * efficient if both these arguments are 32-byte aligned. This is - * because the encryption engine natively deals with 32-byte rows of - * two AES blocks. Writing half a row (16 bytes) requires reading out - * the other 16 bytes and re-encrypting them back to the same value. + * @note Flash encryption must be enabled when calling this function. + * If flash encryption is disabled, the function returns + * ESP_ERR_INVALID_STATE. Use esp_flash_encryption_enabled() + * function to determine if flash encryption is enabled. + * + * @note Both dest_addr and size must be multiples of 16 bytes. For + * absolute best performance, both dest_addr and size arguments should + * be multiples of 32 bytes. * * @param dest_addr destination address in Flash. Must be a multiple of 16 bytes. * @param src pointer to the source buffer. @@ -125,7 +127,7 @@ esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size); * If flash encryption is enabled, this function will transparently decrypt data as it is read. * If flash encryption is not enabled, this function behaves the same as spi_flash_read(). * - * See @ref esp_flash_encryption_enabled() for a function to check if flash encryption is enabled. + * See esp_flash_encryption_enabled() for a function to check if flash encryption is enabled. * * @param src source address of the data in Flash. * @param dest pointer to the destination buffer @@ -133,7 +135,7 @@ esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size); * * @return esp_err_t */ -esp_err_t spi_flash_read_encrypted(size_t src, void *dstv, size_t size); +esp_err_t spi_flash_read_encrypted(size_t src, void *dest, size_t size); /** * @brief Enumeration which specifies memory space requested in an mmap call diff --git a/docs/api/storage/spi_flash.rst b/docs/api/storage/spi_flash.rst index ab03b38faa..2530db6d42 100644 --- a/docs/api/storage/spi_flash.rst +++ b/docs/api/storage/spi_flash.rst @@ -1,12 +1,5 @@ .. include:: ../../../components/spi_flash/README.rst -Application Example -------------------- - -`Instructions`_ - -.. _Instructions: ../template.html - API Reference ------------- @@ -15,6 +8,7 @@ Header Files * :component_file:`spi_flash/include/esp_spi_flash.h` * :component_file:`spi_flash/include/esp_partition.h` + * :component_file:`esp32/include/esp_flash_encrypt.h` Macros ^^^^^^ @@ -51,7 +45,9 @@ Functions .. doxygenfunction:: spi_flash_erase_sector .. doxygenfunction:: spi_flash_erase_range .. doxygenfunction:: spi_flash_write +.. doxygenfunction:: spi_flash_write_encrypted .. doxygenfunction:: spi_flash_read +.. doxygenfunction:: spi_flash_read_encrypted .. doxygenfunction:: spi_flash_mmap .. doxygenfunction:: spi_flash_munmap .. doxygenfunction:: spi_flash_mmap_dump @@ -64,4 +60,5 @@ Functions .. doxygenfunction:: esp_partition_write .. doxygenfunction:: esp_partition_erase_range .. doxygenfunction:: esp_partition_mmap +.. doxygenfunction:: esp_flash_encryption_enabled From d4462664b781f609622905003c9248b87477053d Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 6 Jan 2017 11:24:24 +1100 Subject: [PATCH 066/139] spi_flash: Move FLASH_PAGE_SIZE constant into esp_spi_flash.h --- components/spi_flash/flash_mmap.c | 13 ++++++------- components/spi_flash/flash_ops.c | 4 +--- components/spi_flash/include/esp_spi_flash.h | 5 ++++- docs/api/storage/spi_flash.rst | 1 + 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 0b83ac33c0..837fe0cc37 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -39,12 +39,11 @@ #define REGIONS_COUNT 4 #define PAGES_PER_REGION 64 -#define FLASH_PAGE_SIZE 0x10000 #define INVALID_ENTRY_VAL 0x100 #define VADDR0_START_ADDR 0x3F400000 #define VADDR1_START_ADDR 0x40000000 #define VADDR1_FIRST_USABLE_ADDR 0x400D0000 -#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / FLASH_PAGE_SIZE + 64) +#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + 64) /* Ensure pages in a region haven't been marked as written via spi_flash_mark_modified_region(). If the page has @@ -124,8 +123,8 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ region_addr = VADDR1_FIRST_USABLE_ADDR; } // region which should be mapped - int phys_page = src_addr / FLASH_PAGE_SIZE; - int page_count = (size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE; + int phys_page = src_addr / SPI_FLASH_MMU_PAGE_SIZE; + int page_count = (size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE; // The following part searches for a range of MMU entries which can be used. // Algorithm is essentially naïve strstr algorithm, except that unused MMU // entries are treated as wildcards. @@ -171,7 +170,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ new_entry->count = page_count; new_entry->handle = ++s_mmap_last_handle; *out_handle = new_entry->handle; - *out_ptr = (void*) (region_addr + start * FLASH_PAGE_SIZE); + *out_ptr = (void*) (region_addr + start * SPI_FLASH_MMU_PAGE_SIZE); ret = ESP_OK; } spi_flash_enable_interrupts_caches_and_other_cpu(); @@ -256,8 +255,8 @@ static void IRAM_ATTR spi_flash_ensure_unmodified_region(size_t start_addr, size /* generic implementation for the previous two functions */ static inline IRAM_ATTR void update_written_pages(size_t start_addr, size_t length, bool mark) { - for (uint32_t addr = start_addr; addr < start_addr + length; addr += FLASH_PAGE_SIZE) { - int page = addr / FLASH_PAGE_SIZE; + for (uint32_t addr = start_addr; addr < start_addr + length; addr += SPI_FLASH_MMU_PAGE_SIZE) { + int page = addr / SPI_FLASH_MMU_PAGE_SIZE; if (page >= 256) { return; /* invalid address */ } diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 76a5a6171d..0d3e0da87c 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -419,8 +419,6 @@ out: return spi_flash_translate_rc(rc); } -#define FLASH_PAGE_SIZE 0x10000 - esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size) { if (src + size > g_rom_flashchip.chip_size) { @@ -433,7 +431,7 @@ esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size esp_err_t err; const uint8_t *map; spi_flash_mmap_handle_t map_handle; - size_t map_src = src & ~(FLASH_PAGE_SIZE-1); + size_t map_src = src & ~(SPI_FLASH_MMU_PAGE_SIZE-1); size_t map_size = size + (src - map_src); err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle); diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 3761ec665d..c1ad7d56fa 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -31,6 +31,8 @@ extern "C" { #define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */ +#define SPI_FLASH_MMU_PAGE_SIZE 0x10000 /**< Flash cache MMU mapping page size */ + /** * @brief Initialize SPI flash access driver * @@ -161,7 +163,8 @@ typedef uint32_t spi_flash_mmap_handle_t; * page allocation, use spi_flash_mmap_dump function. * * @param src_addr Physical address in flash where requested region starts. - * This address *must* be aligned to 64kB boundary. + * This address *must* be aligned to 64kB boundary + * (SPI_FLASH_MMU_PAGE_SIZE). * @param size Size of region which has to be mapped. This size will be rounded * up to a 64k boundary. * @param memory Memory space where the region should be mapped diff --git a/docs/api/storage/spi_flash.rst b/docs/api/storage/spi_flash.rst index 2530db6d42..cbb2be0d70 100644 --- a/docs/api/storage/spi_flash.rst +++ b/docs/api/storage/spi_flash.rst @@ -17,6 +17,7 @@ Macros .. doxygendefine:: ESP_ERR_FLASH_OP_FAIL .. doxygendefine:: ESP_ERR_FLASH_OP_TIMEOUT .. doxygendefine:: SPI_FLASH_SEC_SIZE +.. doxygendefine:: SPI_FLASH_MMU_PAGE_SIZE .. doxygendefine:: ESP_PARTITION_SUBTYPE_OTA Type Definitions From 03e3b137bfcc88d521f56be4d0a26c10256215af Mon Sep 17 00:00:00 2001 From: qiyueixa Date: Sun, 22 Jan 2017 20:32:39 +0800 Subject: [PATCH 067/139] lwip: optimize the dhcp client 1. modify the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s. 2. add DHCP_DOES_ARP_CHECK to menuconfig for users to specify if do a ARP check on the offered address. If enable, one more second will be taken in obtaining IP address. 3. update wifi libs --- components/esp32/lib | 2 +- components/lwip/Kconfig | 7 +++++++ components/lwip/core/ipv4/dhcp.c | 7 ++++++- components/lwip/include/lwip/port/lwipopts.h | 5 +++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/components/esp32/lib b/components/esp32/lib index fc92f2e5bc..6e50eb85a0 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit fc92f2e5bcd34fa945445e8cad47cbf1f2a4bdb6 +Subproject commit 6e50eb85a07d12ded45d8765fc82bb7ab929e441 diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index f7bae32581..0070ef4668 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -82,6 +82,13 @@ config TCP_SYNMAXRTX help Set maximum number of retransmissions of SYN segments. +config LWIP_DHCP_DOES_ARP_CHECK + bool "Enable an ARP check on the offered address" + default 1 + help + Enabling this option allows check if the offered IP address is not already + in use by another host on the network. + endmenu diff --git a/components/lwip/core/ipv4/dhcp.c b/components/lwip/core/ipv4/dhcp.c index 887af91fe3..86336d4f7b 100755 --- a/components/lwip/core/ipv4/dhcp.c +++ b/components/lwip/core/ipv4/dhcp.c @@ -1029,7 +1029,12 @@ dhcp_discover(struct netif *netif) autoip_start(netif); } #endif /* LWIP_DHCP_AUTOIP_COOP */ - msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + + /* Since for embedded devices it's not that hard to miss a discover packet, so lower + * the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s. + * Original msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + */ + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 250; dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); return result; diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 638c1f7404..dc82649479 100644 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -206,6 +206,11 @@ #define DHCP_MAXRTX 0 +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#define DHCP_DOES_ARP_CHECK CONFIG_LWIP_DHCP_DOES_ARP_CHECK + /* ------------------------------------ ---------- AUTOIP options ---------- From d193424ae89fc49467d94c31f5e05b93fee3196f Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Tue, 24 Jan 2017 15:05:39 +0800 Subject: [PATCH 068/139] CI: add job to check build esp-at in esp-idf --- .gitlab-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5685c83367..5cd5fcecec 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -79,6 +79,15 @@ build_ssc: - chmod +x gen_misc_ng.sh - ./gen_misc_ng.sh +build_at: + <<: *build_template + script: + - git clone $GITLAB_SSH_SERVER/application/esp-at.git + - cd esp-at + - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-at default branch..." + - make defconfig + - make + build_esp_idf_tests: <<: *build_template artifacts: From 1d0c909daf45d929f957931f7decc2ff881414f8 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 24 Jan 2017 17:36:32 +0800 Subject: [PATCH 069/139] components/openssl: fixes for github issues 219 "SSL_write" doesn't send large buffers correctly --- components/openssl/library/ssl_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 43c130077e..8b539826dc 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -463,7 +463,7 @@ int SSL_write(SSL *ssl, const void *buffer, int len) else bytes = send_bytes; - ret = SSL_METHOD_CALL(send, ssl, buffer, bytes); + ret = SSL_METHOD_CALL(send, ssl, pbuf, bytes); if (ret > 0) { pbuf += ret; send_bytes -= ret; From 74f78540ae2bd66269a78d4ede57337f1347e806 Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Wed, 21 Dec 2016 18:18:42 +0000 Subject: [PATCH 070/139] Allow providing custom PARTITION_TABLE_CSV_PATH Provide direct absolute path to CSV, without project_path --- components/partition_table/Makefile.projbuild | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index 5d1e726a86..4d548f7e2d 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -14,10 +14,12 @@ GEN_ESP32PART := $(PYTHON) $(COMPONENT_PATH)/gen_esp32part.py -q # Has a matching value in bootloader_support esp_flash_partitions.h PARTITION_TABLE_OFFSET := 0x8000 +ifndef PARTITION_TABLE_CSV_PATH # Path to partition CSV file is relative to project path for custom # partition CSV files, but relative to component dir otherwise.$ PARTITION_TABLE_ROOT := $(call dequote,$(if $(CONFIG_PARTITION_TABLE_CUSTOM),$(PROJECT_PATH),$(COMPONENT_PATH))) PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(subst $(quote),,$(CONFIG_PARTITION_TABLE_FILENAME)))) +endif PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(notdir $(PARTITION_TABLE_CSV_PATH:.csv=.bin)) From c6bb239f0cf330ef9fc0e8d68f3cdc910f232b06 Mon Sep 17 00:00:00 2001 From: Island Date: Tue, 24 Jan 2017 18:38:50 +0800 Subject: [PATCH 071/139] component/bt: Fix Gatt table read_req bug and advertising channel 39 not available bug --- components/bt/bluedroid/api/include/esp_gap_ble_api.h | 2 +- components/bt/bluedroid/stack/gatt/gatt_db.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/bt/bluedroid/api/include/esp_gap_ble_api.h b/components/bt/bluedroid/api/include/esp_gap_ble_api.h index fa8eb2432e..64aff1fb1a 100644 --- a/components/bt/bluedroid/api/include/esp_gap_ble_api.h +++ b/components/bt/bluedroid/api/include/esp_gap_ble_api.h @@ -95,7 +95,7 @@ typedef enum { typedef enum { ADV_CHNL_37 = 0x01, ADV_CHNL_38 = 0x02, - ADV_CHNL_39 = 0x03, + ADV_CHNL_39 = 0x04, ADV_CHNL_ALL = 0x07, } esp_ble_adv_channel_t; diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index a574b5d1ed..03919d483c 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -1332,7 +1332,13 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_READ, &sr_data); - return (tGATT_STATUS) GATT_PENDING; + + if (need_rsp) { + return (tGATT_STATUS) GATT_PENDING; + } + else{ + return (tGATT_STATUS) GATT_STACK_RSP; + } } else { return (tGATT_STATUS) GATT_BUSY; /* max pending command, application error */ } From 33500f256194bc65870323a2368563c4d3769e9e Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sat, 21 Jan 2017 15:39:36 +0000 Subject: [PATCH 072/139] Add missing variable initialisation. Signed-off-by: Jeroen Domburg --- components/driver/spi_master.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 6162edba36..f37f7aaf19 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -502,6 +502,7 @@ static void IRAM_ATTR spi_intr(void *arg) //We have a transaction. Send it. spi_device_t *dev=host->device[i]; host->cur_trans=trans; + host->cur_cs=i; //We should be done with the transmission. assert(host->hw->cmd.usr == 0); @@ -510,7 +511,7 @@ static void IRAM_ATTR spi_intr(void *arg) trans->rxlength=trans->length; } - //Reconfigure accoding to device settings, but only if we change CSses. + //Reconfigure according to device settings, but only if we change CSses. if (i!=prevCs) { //Assumes a hardcoded 80MHz Fapb for now. ToDo: figure out something better once we have //clock scaling working. From 4f7e4dd0f5766f900ae1e00b8f79bf6a7213ffad Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Tue, 24 Jan 2017 14:42:02 +0000 Subject: [PATCH 073/139] Use PART_FLAG_ENCRYPTED value in gen_esp32part.py Currently paritions marked as encrypted by gen_esp32part.py are not recognized as such and encrypted writes don't work. This is part of espressif/esp-idf#253 --- components/partition_table/gen_esp32part.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index 0491204885..56bfe29fb8 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -144,7 +144,7 @@ class PartitionDefinition(object): # dictionary maps flag name (as used in CSV flags list, property name) # to bit set in flags words in binary format FLAGS = { - "encrypted" : 1 + "encrypted" : 0 } # add subtypes for the 16 OTA slot values ("ota_XXX, etc.") From 93395a3370c362dc1ac1e13efaa3591aa7a08551 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Thu, 26 Jan 2017 10:12:58 +0800 Subject: [PATCH 074/139] components/openssl: Add more debugging information at platform level --- components/openssl/platform/ssl_pm.c | 77 +++++++++++++--------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index b175b38262..1281965e2c 100755 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -238,10 +238,12 @@ static int ssl_pm_reload_crt(SSL *ssl) ret = 0; } - if (ret) - return -1; + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_conf_own_cert() return -0x%x", -ret); + ret = -1; + } - return 0; + return ret; } /* @@ -252,8 +254,7 @@ static int mbedtls_handshake( mbedtls_ssl_context *ssl ) { int ret = 0; - while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) - { + while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { ret = mbedtls_ssl_handshake_step(ssl); SSL_DEBUG(SSL_PLATFORM_DEBUG_LEVEL, "ssl ret %d state %d", ret, ssl->state); @@ -267,32 +268,31 @@ static int mbedtls_handshake( mbedtls_ssl_context *ssl ) int ssl_pm_handshake(SSL *ssl) { - int ret, mbed_ret; + int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - mbed_ret = ssl_pm_reload_crt(ssl); - if (mbed_ret) + ret = ssl_pm_reload_crt(ssl); + if (ret) return 0; ssl_speed_up_enter(); - while((mbed_ret = mbedtls_handshake(&ssl_pm->ssl)) != 0) { - if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + while((ret = mbedtls_handshake(&ssl_pm->ssl)) != 0) { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { break; } } ssl_speed_up_exit(); - if (!mbed_ret) { + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -ret); + ret = 0; + } else { struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; - ret = 1; - x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); - } else { - ret = 0; - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -mbed_ret); + ret = 1; } return ret; @@ -300,19 +300,18 @@ int ssl_pm_handshake(SSL *ssl) int ssl_pm_shutdown(SSL *ssl) { - int ret, mbed_ret; + int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - mbed_ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); - if (!mbed_ret) { + ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_close_notify() return -0x%x", -ret); + ret = -1; + } else { struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; - ret = 0; - x509_pm->ex_crt = NULL; } - else - ret = -1; return ret; } @@ -325,32 +324,28 @@ int ssl_pm_clear(SSL *ssl) int ssl_pm_read(SSL *ssl, void *buffer, int len) { - int ret, mbed_ret; + int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - mbed_ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len); - if (mbed_ret < 0) + ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len); + if (ret < 0) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_read() return -0x%x", -ret); ret = -1; - else if (mbed_ret == 0) - ret = 0; - else - ret = mbed_ret; + } return ret; } int ssl_pm_send(SSL *ssl, const void *buffer, int len) { - int ret, mbed_ret; + int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - mbed_ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); - if (mbed_ret < 0) + ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); + if (ret < 0) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); ret = -1; - else if (mbed_ret == 0) - ret = 0; - else - ret = mbed_ret; + } return ret; } @@ -656,11 +651,11 @@ long ssl_pm_get_verify_result(const SSL *ssl) struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); - - if (!ret) - verify_result = X509_V_OK; - else + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_get_verify_result() return -0x%x", -ret); verify_result = X509_V_ERR_UNSPECIFIED; + } else + verify_result = X509_V_OK; return verify_result; } From 2173ad3b4543553383edd795e7fa04416d682ebc Mon Sep 17 00:00:00 2001 From: Tian Zhong Xing Date: Tue, 24 Jan 2017 18:30:13 +0800 Subject: [PATCH 075/139] bootloader_support: fix bug OTA & flash encryption incompatible ota data partition should be encrypted unconditionally when flash encrypt enable --- components/bootloader_support/src/flash_encrypt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 8b9ca60cd1..8ba068d03b 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -285,6 +285,9 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit } else { should_encrypt = false; } + } else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) { + /* check if we have ota data partition and the partition should be encrypted unconditionally */ + should_encrypt = true; } if (!should_encrypt) { From 813395adcb76819b18de13569699997abd3490f4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 26 Jan 2017 16:19:45 +1100 Subject: [PATCH 076/139] OTA: Fall back to factory partition if ota data partition is invalid --- components/app_update/esp_ota_ops.c | 15 ++++++++------- components/bootloader/src/main/bootloader_start.c | 11 +++++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 439117b596..8b1a43163e 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -349,33 +349,34 @@ const esp_partition_t *esp_ota_get_boot_partition(void) } ota_app_count = get_ota_partition_count(); - ESP_LOGD(TAG, "found ota bin max = %d", ota_app_count); + ESP_LOGD(TAG, "found ota app max = %d", ota_app_count); + if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) { - ESP_LOGD(TAG, "finding factory bin......"); + ESP_LOGD(TAG, "finding factory app......"); return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); } else if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) { - ESP_LOGD(TAG, "finding ota_%d bin......", \ + ESP_LOGD(TAG, "finding ota_%d app......", \ ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count)); return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \ ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count), NULL); } else if (ota_select_valid(&s_ota_select[0])) { - ESP_LOGD(TAG, "finding ota_%d bin......", \ + ESP_LOGD(TAG, "finding ota_%d app......", \ ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count); return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \ ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count, NULL); } else if (ota_select_valid(&s_ota_select[1])) { - ESP_LOGD(TAG, "finding ota_%d bin......", \ + ESP_LOGD(TAG, "finding ota_%d app......", \ ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count); return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \ ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL); } else { - ESP_LOGE(TAG, "not found current bin"); - return NULL; + ESP_LOGE(TAG, "ota data invalid, no current app. Falling back to factory"); + return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); } } diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index a374c4306d..43066aa3d7 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -323,12 +323,15 @@ void bootloader_main() } else { if(ota_select_valid(&sa) && ota_select_valid(&sb)) { load_part_pos = bs.ota[(((sa.ota_seq > sb.ota_seq)?sa.ota_seq:sb.ota_seq) - 1)%bs.app_count]; - }else if(ota_select_valid(&sa)) { + } else if(ota_select_valid(&sa)) { load_part_pos = bs.ota[(sa.ota_seq - 1) % bs.app_count]; - }else if(ota_select_valid(&sb)) { + } else if(ota_select_valid(&sb)) { load_part_pos = bs.ota[(sb.ota_seq - 1) % bs.app_count]; - }else { - ESP_LOGE(TAG, "ota data partition info error"); + } else if (bs.factory.offset != 0) { + ESP_LOGE(TAG, "ota data partition invalid, falling back to factory"); + load_part_pos = bs.factory; + } else { + ESP_LOGE(TAG, "ota data partition invalid and no factory, can't boot"); return; } } From 67336672bddb761b7f448b10c44f930655f6686e Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 26 Jan 2017 16:18:58 +1100 Subject: [PATCH 077/139] OTA: Improve verification of OTA image before writing, incl. secure boot Verify 0xE9 magic byte on first write, verify entire image before switching. Enable verification for secure boot signature (was using invalid ifdef guard) --- components/app_update/esp_ota_ops.c | 25 +++++++++++++++++-------- examples/system/ota/main/ota.c | 19 ++++++------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 8b1a43163e..23b6f870c6 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -106,6 +106,7 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size) { + const uint8_t *data_bytes = (const uint8_t *)data; esp_err_t ret; ota_ops_entry_t *it; @@ -119,6 +120,12 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size) if (it->handle == handle) { // must erase the partition before writing to it assert(it->erased_size > 0 && "must erase the partition before writing to it"); + + if(it->wrote_size == 0 && size > 0 && data_bytes[0] != 0xE9) { + ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]); + return ESP_ERR_OTA_VALIDATE_FAILED; + } + ret = esp_partition_write(&it->part, it->wrote_size, data, size); if(ret == ESP_OK){ it->wrote_size += size; @@ -135,6 +142,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size) esp_err_t esp_ota_end(esp_ota_handle_t handle) { ota_ops_entry_t *it; + size_t image_size; for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { if (it->handle == handle) { // an ota handle need to be ended after erased and wrote data in it @@ -142,12 +150,12 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle) return ESP_ERR_INVALID_ARG; } -#ifdef CONFIG_SECUREBOOTLOADER - esp_err_t ret; - size_t image_size; - if (esp_image_basic_verify(it->part.address, &image_size) != ESP_OK) { + if (esp_image_basic_verify(it->part.address, true, &image_size) != ESP_OK) { return ESP_ERR_OTA_VALIDATE_FAILED; } + +#ifdef CONFIG_SECURE_BOOT_ENABLED + esp_err_t ret; ret = esp_secure_boot_verify_signature(it->part.address, image_size); if (ret != ESP_OK) { return ESP_ERR_OTA_VALIDATE_FAILED; @@ -285,17 +293,18 @@ static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype) esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition) { + size_t image_size; const esp_partition_t *find_partition = NULL; if (partition == NULL) { return ESP_ERR_INVALID_ARG; } -#ifdef CONFIG_SECUREBOOTLOADER - size_t image_size; - if (esp_image_basic_verify(partition->address, &image_size) != ESP_OK) { + if (esp_image_basic_verify(partition->address, true, &image_size) != ESP_OK) { return ESP_ERR_OTA_VALIDATE_FAILED; } - ret = esp_secure_boot_verify_signature(partition->address, image_size); + +#ifdef CONFIG_SECURE_BOOT_ENABLED + esp_err_t ret = esp_secure_boot_verify_signature(partition->address, image_size); if (ret != ESP_OK) { return ESP_ERR_OTA_VALIDATE_FAILED; } diff --git a/examples/system/ota/main/ota.c b/examples/system/ota/main/ota.c index 4956129e5d..21ebcc3c21 100644 --- a/examples/system/ota/main/ota.c +++ b/examples/system/ota/main/ota.c @@ -95,7 +95,7 @@ static void initialise_wifi(void) } /*read buffer by byte still delim ,return read bytes counts*/ -int read_until(char *buffer, char delim, int len) +static int read_until(char *buffer, char delim, int len) { // /*TODO: delim check,buffer check,further: do an buffer length limited*/ int i = 0; @@ -109,7 +109,7 @@ int read_until(char *buffer, char delim, int len) * return true if packet including \r\n\r\n that means http packet header finished,start to receive packet body * otherwise return false * */ -bool resolve_pkg(char text[], int total_len, esp_ota_handle_t out_handle) +static bool read_past_http_header(char text[], int total_len, esp_ota_handle_t out_handle) { /* i means current position */ int i = 0, i_read_len = 0; @@ -121,13 +121,6 @@ bool resolve_pkg(char text[], int total_len, esp_ota_handle_t out_handle) memset(ota_write_data, 0, BUFFSIZE); /*copy first http packet body to write buffer*/ memcpy(ota_write_data, &(text[i + 2]), i_write_len); - /*check write packet header first byte:0xE9 second byte:0x09 */ - if (ota_write_data[0] == 0xE9 && i_write_len >= 2 && ota_write_data[1] == 0x09) { - ESP_LOGI(TAG, "OTA Write Header format Check OK. first byte is %02x ,second byte is %02x", ota_write_data[0], ota_write_data[1]); - } else { - ESP_LOGE(TAG, "OTA Write Header format Check Failed! first byte is %02x ,second byte is %02x", ota_write_data[0], ota_write_data[1]); - return false; - } esp_err_t err = esp_ota_write( out_handle, (const void *)ota_write_data, i_write_len); if (err != ESP_OK) { @@ -266,7 +259,7 @@ void main_task(void *pvParameter) task_fatal_error(); } - bool pkg_body_start = false, flag = true; + bool resp_body_start = false, flag = true; /*deal with all receive packet*/ while (flag) { memset(text, 0, TEXT_BUFFSIZE); @@ -275,10 +268,10 @@ void main_task(void *pvParameter) if (buff_len < 0) { /*receive error*/ ESP_LOGE(TAG, "Error: receive data error! errno=%d", errno); task_fatal_error(); - } else if (buff_len > 0 && !pkg_body_start) { /*deal with packet header*/ + } else if (buff_len > 0 && !resp_body_start) { /*deal with response header*/ memcpy(ota_write_data, text, buff_len); - pkg_body_start = resolve_pkg(text, buff_len, out_handle); - } else if (buff_len > 0 && pkg_body_start) { /*deal with packet body*/ + resp_body_start = read_past_http_header(text, buff_len, out_handle); + } else if (buff_len > 0 && resp_body_start) { /*deal with response body*/ memcpy(ota_write_data, text, buff_len); err = esp_ota_write( out_handle, (const void *)ota_write_data, buff_len); if (err != ESP_OK) { From d8aae55eebc8c47703593d8c9222dd339d7f5b82 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 26 Jan 2017 18:29:18 +1100 Subject: [PATCH 078/139] Flash encryption: Temporary fix for issue with stale cache reads Seems doing certain kinds of short reads while flash encryption is enabled will return stale data. This fixes it, but is probably a little heavy-handed performance wise. --- .../include/esp_flash_encrypt.h | 15 +++++-- components/spi_flash/flash_mmap.c | 45 ++++++++++++++----- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/components/bootloader_support/include/esp_flash_encrypt.h b/components/bootloader_support/include/esp_flash_encrypt.h index 015dea030a..ff1a5f3306 100644 --- a/components/bootloader_support/include/esp_flash_encrypt.h +++ b/components/bootloader_support/include/esp_flash_encrypt.h @@ -15,7 +15,8 @@ #define __ESP32_FLASH_ENCRYPT_H #include -#include +#include "esp_attr.h" +#include "esp_err.h" #include "esp_spi_flash.h" #include "soc/efuse_reg.h" @@ -30,9 +31,17 @@ * * @return true if flash encryption is enabled. */ -static inline bool esp_flash_encryption_enabled(void) { +static inline IRAM_ATTR bool esp_flash_encryption_enabled(void) { uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT); - return __builtin_parity(flash_crypt_cnt) == 1; + /* __builtin_parity is in flash, so we calculate parity inline */ + bool enabled = false; + while(flash_crypt_cnt) { + if (flash_crypt_cnt & 1) { + enabled = !enabled; + } + flash_crypt_cnt >>= 1; + } + return enabled; } /* @brief Update on-device flash encryption diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 837fe0cc37..f8d2e3297d 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -28,6 +28,7 @@ #include "esp_ipc.h" #include "esp_attr.h" #include "esp_spi_flash.h" +#include "esp_flash_encrypt.h" #include "esp_log.h" #include "cache_utils.h" @@ -52,8 +53,10 @@ This ensures stale cache entries are never read after fresh calls to spi_flash_mmap(), while keeping the number of cache flushes to a minimum. + + Returns true if cache was flushed. */ -static void spi_flash_ensure_unmodified_region(size_t start_addr, size_t length); +static bool spi_flash_ensure_unmodified_region(size_t start_addr, size_t length); typedef struct mmap_entry_{ uint32_t handle; @@ -89,6 +92,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ const void** out_ptr, spi_flash_mmap_handle_t* out_handle) { esp_err_t ret; + bool did_flush, need_flush = false; mmap_entry_t* new_entry = (mmap_entry_t*) malloc(sizeof(mmap_entry_t)); if (new_entry == 0) { return ESP_ERR_NO_MEM; @@ -102,7 +106,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ spi_flash_disable_interrupts_caches_and_other_cpu(); - spi_flash_ensure_unmodified_region(src_addr, size); + did_flush = spi_flash_ensure_unmodified_region(src_addr, size); if (s_mmap_page_refcnt[0] == 0) { spi_flash_mmap_init(); @@ -159,8 +163,11 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ (DPORT_PRO_FLASH_MMU_TABLE[i] == entry_val && DPORT_APP_FLASH_MMU_TABLE[i] == entry_val)); if (s_mmap_page_refcnt[i] == 0) { - DPORT_PRO_FLASH_MMU_TABLE[i] = entry_val; - DPORT_APP_FLASH_MMU_TABLE[i] = entry_val; + if (DPORT_PRO_FLASH_MMU_TABLE[i] != entry_val || DPORT_APP_FLASH_MMU_TABLE[i] != entry_val) { + DPORT_PRO_FLASH_MMU_TABLE[i] = entry_val; + DPORT_APP_FLASH_MMU_TABLE[i] = entry_val; + need_flush = true; + } } ++s_mmap_page_refcnt[i]; } @@ -173,6 +180,18 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_ *out_ptr = (void*) (region_addr + start * SPI_FLASH_MMU_PAGE_SIZE); ret = ESP_OK; } + + /* This is a temporary fix for an issue where some + encrypted cache reads may see stale data. + + Working on a long term fix that doesn't require invalidating + entire cache. + */ + if (esp_flash_encryption_enabled() && !did_flush && need_flush) { + Cache_Flush(0); + Cache_Flush(1); + } + spi_flash_enable_interrupts_caches_and_other_cpu(); if (*out_ptr == NULL) { free(new_entry); @@ -240,25 +259,29 @@ void spi_flash_mmap_dump() */ static uint32_t written_pages[256/32]; -static void update_written_pages(size_t start_addr, size_t length, bool mark); +static bool update_written_pages(size_t start_addr, size_t length, bool mark); void IRAM_ATTR spi_flash_mark_modified_region(size_t start_addr, size_t length) { update_written_pages(start_addr, length, true); } -static void IRAM_ATTR spi_flash_ensure_unmodified_region(size_t start_addr, size_t length) +static IRAM_ATTR bool spi_flash_ensure_unmodified_region(size_t start_addr, size_t length) { - update_written_pages(start_addr, length, false); + return update_written_pages(start_addr, length, false); } /* generic implementation for the previous two functions */ -static inline IRAM_ATTR void update_written_pages(size_t start_addr, size_t length, bool mark) +static inline IRAM_ATTR bool update_written_pages(size_t start_addr, size_t length, bool mark) { - for (uint32_t addr = start_addr; addr < start_addr + length; addr += SPI_FLASH_MMU_PAGE_SIZE) { + /* align start_addr & length to full MMU pages */ + uint32_t page_start_addr = start_addr & ~(SPI_FLASH_MMU_PAGE_SIZE-1); + length += (start_addr - page_start_addr); + length = (length + SPI_FLASH_MMU_PAGE_SIZE - 1) & ~(SPI_FLASH_MMU_PAGE_SIZE-1); + for (uint32_t addr = page_start_addr; addr < page_start_addr + length; addr += SPI_FLASH_MMU_PAGE_SIZE) { int page = addr / SPI_FLASH_MMU_PAGE_SIZE; if (page >= 256) { - return; /* invalid address */ + return false; /* invalid address */ } int idx = page / 32; @@ -277,6 +300,8 @@ static inline IRAM_ATTR void update_written_pages(size_t start_addr, size_t leng Cache_Flush(1); #endif bzero(written_pages, sizeof(written_pages)); + return true; } } + return false; } From 385c61e183a8d3750d9e5f851dce5cb822348889 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Thu, 26 Jan 2017 15:35:04 +0800 Subject: [PATCH 079/139] esp32: udpate wifi lib to fix two datapath issues 1. fix ampdu<->mpdu<->ampdu switch may cause rx slow issue by put mpdu into ampdu reorder queue 2. fix each ac first sending always fail issue by adding retry --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 6e50eb85a0..45414a6778 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 6e50eb85a07d12ded45d8765fc82bb7ab929e441 +Subproject commit 45414a6778e1bf2855f18a8c6b954d5cf575bb40 From eea2788f5a9ea3eb8717145734f6ad6991fc66d3 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 26 Jan 2017 18:30:32 +1100 Subject: [PATCH 080/139] OTA: Fix issues with encrypted OTA - OTA source can write non-16-byte multiples of data - Assumption that empty ota_data is 0xFFFFFFFF untrue when encrypted --- components/app_update/esp_ota_ops.c | 63 +++++++++++++++++-- .../bootloader_support/src/bootloader_flash.c | 7 ++- components/spi_flash/partition.c | 8 ++- examples/system/ota/main/ota.c | 4 +- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 23b6f870c6..2338753898 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -27,6 +27,7 @@ #include "esp_spi_flash.h" #include "esp_image_format.h" #include "esp_secure_boot.h" +#include "esp_flash_encrypt.h" #include "sdkconfig.h" #include "esp_ota_ops.h" @@ -44,6 +45,10 @@ typedef struct ota_ops_entry_ { esp_partition_t part; uint32_t erased_size; uint32_t wrote_size; +#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED + uint8_t partial_bytes; + uint8_t partial_data[16]; +#endif LIST_ENTRY(ota_ops_entry_) entries; } ota_ops_entry_t; @@ -126,7 +131,41 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size) return ESP_ERR_OTA_VALIDATE_FAILED; } - ret = esp_partition_write(&it->part, it->wrote_size, data, size); +#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED + if (esp_flash_encryption_enabled()) { + /* Can only write 16 byte blocks to flash, so need to cache anything else */ + size_t copy_len; + + /* check if we have partially written data from earlier */ + if (it->partial_bytes != 0) { + copy_len = OTA_MIN(16 - it->partial_bytes, size); + memcpy(it->partial_data + it->partial_bytes, data_bytes, copy_len); + it->partial_bytes += copy_len; + if (it->partial_bytes != 16) { + return ESP_OK; /* nothing to write yet, just filling buffer */ + } + /* write 16 byte to partition */ + ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16); + if (ret != ESP_OK) { + return ret; + } + it->partial_bytes = 0; + memset(it->partial_data, 0xFF, 16); + it->wrote_size += 16; + data_bytes += copy_len; + size -= copy_len; + } + + /* check if we need to save trailing data that we're about to write */ + it->partial_bytes = size % 16; + if (it->partial_bytes != 0) { + size -= it->partial_bytes; + memcpy(it->partial_data, data_bytes + size, it->partial_bytes); + } + } +#endif + + ret = esp_partition_write(&it->part, it->wrote_size, data_bytes, size); if(ret == ESP_OK){ it->wrote_size += size; } @@ -143,6 +182,8 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle) { ota_ops_entry_t *it; size_t image_size; + esp_err_t __attribute__((unused)) ret; + for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { if (it->handle == handle) { // an ota handle need to be ended after erased and wrote data in it @@ -150,6 +191,18 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle) return ESP_ERR_INVALID_ARG; } +#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED + if (it->partial_bytes > 0 && esp_flash_encryption_enabled()) { + /* Write out last 16 bytes, if necessary */ + ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16); + if (ret != ESP_OK) { + return ret; + } + it->wrote_size += 16; + it->partial_bytes = 0; + } +#endif + if (esp_image_basic_verify(it->part.address, true, &image_size) != ESP_OK) { return ESP_ERR_OTA_VALIDATE_FAILED; } @@ -279,11 +332,9 @@ static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype) } return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition); - } else if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) { - return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition); - } else { - return ESP_ERR_OTA_SELECT_INFO_INVALID; + /* Both OTA slots are invalid, probably because unformatted... */ + return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition); } } else { @@ -385,7 +436,7 @@ const esp_partition_t *esp_ota_get_boot_partition(void) ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL); } else { - ESP_LOGE(TAG, "ota data invalid, no current app. Falling back to factory"); + ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory"); return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); } } diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index 405da732b3..da77b1dc28 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -16,6 +16,7 @@ #include #include #include /* including in bootloader for error values */ +#include #ifndef BOOTLOADER_BUILD /* Normal app version maps to esp_spi_flash.h operations... @@ -48,7 +49,11 @@ void bootloader_munmap(const void *mapping) esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_decrypt) { - return spi_flash_read(src, dest, size); + if (allow_decrypt && esp_flash_encryption_enabled()) { + return spi_flash_read_encrypted(src, dest, size); + } else { + return spi_flash_read(src, dest, size); + } } esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted) diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index 45f66d696b..76036b305e 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -166,10 +166,14 @@ static esp_err_t load_partitions() item->info.type = it->type; item->info.subtype = it->subtype; item->info.encrypted = it->flags & PART_FLAG_ENCRYPTED; - if (esp_flash_encryption_enabled() && it->type == PART_TYPE_APP) { - /* All app partitions are encrypted if encryption is turned on */ + if (esp_flash_encryption_enabled() && ( + it->type == PART_TYPE_APP + || (it->type == PART_TYPE_DATA && it->subtype == PART_SUBTYPE_DATA_OTA))) { + /* 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(it->label)); item->info.label[sizeof(it->label)] = 0; diff --git a/examples/system/ota/main/ota.c b/examples/system/ota/main/ota.c index 21ebcc3c21..2dfda1c828 100644 --- a/examples/system/ota/main/ota.c +++ b/examples/system/ota/main/ota.c @@ -124,7 +124,7 @@ static bool read_past_http_header(char text[], int total_len, esp_ota_handle_t o esp_err_t err = esp_ota_write( out_handle, (const void *)ota_write_data, i_write_len); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error: esp_ota_write failed! err=%x", err); + ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%x", err); return false; } else { ESP_LOGI(TAG, "esp_ota_write header OK"); @@ -275,7 +275,7 @@ void main_task(void *pvParameter) memcpy(ota_write_data, text, buff_len); err = esp_ota_write( out_handle, (const void *)ota_write_data, buff_len); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error: esp_ota_write failed! err=%x", err); + ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%x", err); task_fatal_error(); } binary_file_length += buff_len; From b6a2329f0f6efa8c254a7ff980df7538dc0a3723 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 26 Jan 2017 18:31:15 +1100 Subject: [PATCH 081/139] FreeRTOS: esp_crosscore_int_send_yield() should be in IRAM Possible for xQueueGenericSendFromISR -> xTaskRemoveFromEventQueueList -> taskYIELD_OTHER_CORE code path to occur while cache is off. --- components/esp32/crosscore_int.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 1e131eeef7..f75f0eba7d 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -82,7 +82,7 @@ void esp_crosscore_int_init() { assert(err == ESP_OK); } -void esp_crosscore_int_send_yield(int coreId) { +void IRAM_ATTR esp_crosscore_int_send_yield(int coreId) { assert(coreId Date: Thu, 26 Jan 2017 18:47:10 +0300 Subject: [PATCH 082/139] esp32: Fixed and updated core dump docs --- docs/core_dump.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/core_dump.rst b/docs/core_dump.rst index a8e328996f..47cfd89c07 100644 --- a/docs/core_dump.rst +++ b/docs/core_dump.rst @@ -16,13 +16,18 @@ ESP-IDF provides special script `espcoredump.py` to help users to retrieve and a Configuration ------------- -Currently there are three options related to core dump generation which user can choose in configuration menu of the application (`make menuconfig`): +There are a number of core dump related configuration options which user can choose in configuration menu of the application (`make menuconfig`). + +1. Core dump data destination (`Components -> ESP32-specific config -> Core dump destination`): * Disable core dump generation * Save core dump to flash * Print core dump to UART -These options can be choosen in Components -> ESP32-specific config -> Core dump destination menu item. +2. Logging level of core dump module (`Components -> ESP32-specific config -> Core dump module logging level`). Value is a number from 0 (no output) to 5 (most verbose). + +3. Delay before core dump will be printed to UART (`Components -> ESP32-specific config -> Core dump print to UART delay`). Value is in ms. + Save core dump to flash ----------------------- @@ -49,8 +54,8 @@ Print core dump to UART ----------------------- When this option is selected base64-encoded core dumps are printed on UART upon system panic. In this case user should save core dump text body to some file manually and -then run the following command: `espcoredump.py -p info_corefile -t b64 -c ` -or `espcoredump.py -p dbg_corefile -t b64 -c ` +then run the following command: `espcoredump.py info_corefile -t b64 -c ` +or `espcoredump.py dbg_corefile -t b64 -c ` Base64-encoded body of core dump will be between the following header and footer:: From f512923791655badf071d7329fb6d7b89bccc3a3 Mon Sep 17 00:00:00 2001 From: Alexey Gerenkov Date: Thu, 26 Jan 2017 18:01:55 +0300 Subject: [PATCH 083/139] esp32: Fixed search path for esptool --- components/espcoredump/espcoredump.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/espcoredump/espcoredump.py b/components/espcoredump/espcoredump.py index 1589a362b9..521f211c17 100755 --- a/components/espcoredump/espcoredump.py +++ b/components/espcoredump/espcoredump.py @@ -12,15 +12,15 @@ import array import errno import base64 +idf_path = os.getenv('IDF_PATH') +if idf_path: + sys.path.insert(0, os.path.join(idf_path, 'components', 'esptool_py', 'esptool')) + try: import esptool except ImportError: - idf_path = os.getenv('IDF_PATH') - if idf_path is None: - print "Esptool is not found! Install it or set proper $IDF_PATH in environment." - sys.exit(2) - sys.path.append('%s/components/esptool_py/esptool' % idf_path) - import esptool + print "Esptool is not found! Set proper $IDF_PATH in environment." + sys.exit(2) __version__ = "0.1-dev" From 04acc88023caae96c02d8c2a80f4a904de035e07 Mon Sep 17 00:00:00 2001 From: Alexey Gerenkov Date: Thu, 19 Jan 2017 20:24:55 +0300 Subject: [PATCH 084/139] esp32: Fixes watchdog problem when printing core dump to uart Also fixes generation of core dumps when flash cache is disabled --- components/esp32/core_dump.c | 39 +++++++++-------- components/esp32/cpu_start.c | 8 ++-- components/esp32/intr_alloc.c | 4 +- components/esp32/ld/esp32.common.ld | 1 + components/esp32/panic.c | 6 ++- components/spi_flash/flash_ops.c | 44 ++++++++++++++------ components/spi_flash/include/esp_spi_flash.h | 34 +++++++++++++-- 7 files changed, 93 insertions(+), 43 deletions(-) diff --git a/components/esp32/core_dump.c b/components/esp32/core_dump.c index 85301f4dd6..ecc658ebdc 100644 --- a/components/esp32/core_dump.c +++ b/components/esp32/core_dump.c @@ -26,16 +26,17 @@ #if CONFIG_ESP32_ENABLE_COREDUMP #define LOG_LOCAL_LEVEL CONFIG_ESP32_CORE_DUMP_LOG_LEVEL #include "esp_log.h" -const static char *TAG = "esp_core_dump"; +const static DRAM_ATTR char TAG[] = "esp_core_dump"; -#define ESP_COREDUMP_LOGE( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { ets_printf(LOG_FORMAT(E, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); } -#define ESP_COREDUMP_LOGW( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { ets_printf(LOG_FORMAT(W, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); } -#define ESP_COREDUMP_LOGI( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { ets_printf(LOG_FORMAT(I, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); } -#define ESP_COREDUMP_LOGD( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); } -#define ESP_COREDUMP_LOGV( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { ets_printf(LOG_FORMAT(V, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); } +#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { ets_printf(DRAM_STR(format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); } +#define ESP_COREDUMP_LOGE( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_ERROR, LOG_FORMAT(E, format), ##__VA_ARGS__) +#define ESP_COREDUMP_LOGW( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_WARN, LOG_FORMAT(W, format), ##__VA_ARGS__) +#define ESP_COREDUMP_LOGI( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_INFO, LOG_FORMAT(I, format), ##__VA_ARGS__) +#define ESP_COREDUMP_LOGD( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_DEBUG, LOG_FORMAT(D, format), ##__VA_ARGS__) +#define ESP_COREDUMP_LOGV( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_VERBOSE, LOG_FORMAT(V, format), ##__VA_ARGS__) #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH -#define ESP_COREDUMP_LOG_PROCESS( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); } +#define ESP_COREDUMP_LOG_PROCESS( format, ... ) ESP_COREDUMP_LOGD(format, ##__VA_ARGS__) #else #define ESP_COREDUMP_LOG_PROCESS( format, ... ) do{/*(__VA_ARGS__);*/}while(0) #endif @@ -345,8 +346,9 @@ void esp_core_dump_to_flash(XtExcFrame *frame) #endif #if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART + static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) { - static const char *b64 = + const static DRAM_ATTR char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int i, j, a, b, c; @@ -373,14 +375,14 @@ static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8 static esp_err_t esp_core_dump_uart_write_start(void *priv) { esp_err_t err = ESP_OK; - ets_printf("================= CORE DUMP START =================\r\n"); + ets_printf(DRAM_STR("================= CORE DUMP START =================\r\n")); return err; } static esp_err_t esp_core_dump_uart_write_end(void *priv) { esp_err_t err = ESP_OK; - ets_printf("================= CORE DUMP END =================\r\n"); + ets_printf(DRAM_STR("================= CORE DUMP END =================\r\n")); return err; } @@ -398,7 +400,7 @@ static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t memcpy(tmp, addr, len); esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf); addr += len; - ets_printf("%s\r\n", buf); + ets_printf(DRAM_STR("%s\r\n"), buf); } return err; @@ -427,7 +429,8 @@ void esp_core_dump_to_uart(XtExcFrame *frame) wr_cfg.priv = NULL; //Make sure txd/rxd are enabled - gpio_pullup_dis(1); + // use direct reg access instead of gpio_pullup_dis which can cause exception when flash cache is disabled + REG_CLR_BIT(GPIO_PIN_REG_1, FUN_PU); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD); @@ -438,10 +441,6 @@ void esp_core_dump_to_uart(XtExcFrame *frame) tm_cur = xthal_get_ccount() / (XT_CLOCK_FREQ / 1000); if (tm_cur >= tm_end) break; - /* Feed the Cerberus. */ - TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_feed = 1; - TIMERG0.wdt_wprotect = 0; ch = esp_core_dump_uart_get_char(); } ESP_COREDUMP_LOGI("Print core dump to uart..."); @@ -455,18 +454,18 @@ void esp_core_dump_init() #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH const esp_partition_t *core_part; - ESP_LOGI(TAG, "Init core dump to flash"); + ESP_COREDUMP_LOGI("Init core dump to flash"); core_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, NULL); if (!core_part) { - ESP_LOGE(TAG, "No core dump partition found!"); + ESP_COREDUMP_LOGE("No core dump partition found!"); return; } - ESP_LOGI(TAG, "Found partition '%s' @ %x %d bytes", core_part->label, core_part->address, core_part->size); + ESP_COREDUMP_LOGI("Found partition '%s' @ %x %d bytes", core_part->label, core_part->address, core_part->size); s_core_part_start = core_part->address; s_core_part_size = core_part->size; #endif #if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART - ESP_LOGI(TAG, "Init core dump to UART"); + ESP_COREDUMP_LOGI("Init core dump to UART"); #endif } diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index edc2881a28..001d1706e1 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -210,6 +210,10 @@ void start_cpu0_default(void) /* init default OS-aware flash access critical section */ spi_flash_guard_set(&g_flash_guard_default_ops); +#if CONFIG_ESP32_ENABLE_COREDUMP + esp_core_dump_init(); +#endif + #if CONFIG_ESP32_PHY_AUTO_INIT nvs_flash_init(); do_phy_init(); @@ -221,10 +225,6 @@ void start_cpu0_default(void) } #endif -#if CONFIG_ESP32_ENABLE_COREDUMP - esp_core_dump_init(); -#endif - xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, ESP_TASK_MAIN_PRIO, NULL, 0); diff --git a/components/esp32/intr_alloc.c b/components/esp32/intr_alloc.c index d9cc627e17..b35973144c 100644 --- a/components/esp32/intr_alloc.c +++ b/components/esp32/intr_alloc.c @@ -686,7 +686,7 @@ esp_err_t IRAM_ATTR esp_intr_disable(intr_handle_t handle) } -void esp_intr_noniram_disable() +void IRAM_ATTR esp_intr_noniram_disable() { int oldint; int cpu=xPortGetCoreID(); @@ -705,7 +705,7 @@ void esp_intr_noniram_disable() non_iram_int_disabled[cpu]=oldint&non_iram_int_mask[cpu]; } -void esp_intr_noniram_enable() +void IRAM_ATTR esp_intr_noniram_enable() { int cpu=xPortGetCoreID(); int intmask=non_iram_int_disabled[cpu]; diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index 3e5d6b7d83..ac04c07d57 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -80,6 +80,7 @@ SECTIONS *(.iram1 .iram1.*) *libfreertos.a:(.literal .text .literal.* .text.*) *libesp32.a:panic.o(.literal .text .literal.* .text.*) + *libesp32.a:core_dump.o(.literal .text .literal.* .text.*) *libphy.a:(.literal .text .literal.* .text.*) *librtc.a:(.literal .text .literal.* .text.*) *libpp.a:(.literal .text .literal.* .text.*) diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 6180770bd6..4f0497d6ea 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -267,7 +267,7 @@ static void reconfigureAllWdts() TIMERG1.wdt_wprotect = 0; } -#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT +#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT || CONFIG_ESP32_ENABLE_COREDUMP /* This disables all the watchdogs for when we call the gdbstub. */ @@ -367,11 +367,15 @@ static void commonErrorHandler(XtExcFrame *frame) panicPutStr("Entering gdb stub now.\r\n"); esp_gdbstub_panic_handler(frame); #else +#if CONFIG_ESP32_ENABLE_COREDUMP + disableAllWdts(); #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH esp_core_dump_to_flash(frame); #endif #if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP32_PANIC_SILENT_REBOOT esp_core_dump_to_uart(frame); +#endif + reconfigureAllWdts(); #endif #if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT panicPutStr("Rebooting...\r\n"); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 0d3e0da87c..3581b34141 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -61,13 +61,17 @@ static spi_flash_counters_t s_flash_stats; static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc); const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = { - .start = spi_flash_disable_interrupts_caches_and_other_cpu, - .end = spi_flash_enable_interrupts_caches_and_other_cpu + .start = spi_flash_disable_interrupts_caches_and_other_cpu, + .end = spi_flash_enable_interrupts_caches_and_other_cpu, + .op_lock = spi_flash_op_lock, + .op_unlock = spi_flash_op_unlock }; const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_no_os_ops = { - .start = spi_flash_disable_interrupts_caches_and_other_cpu_no_os, - .end = spi_flash_enable_interrupts_caches_no_os + .start = spi_flash_disable_interrupts_caches_and_other_cpu_no_os, + .end = spi_flash_enable_interrupts_caches_no_os, + .op_lock = 0, + .op_unlock = 0 }; static const spi_flash_guard_funcs_t *s_flash_guard_ops; @@ -80,12 +84,12 @@ void spi_flash_init() #endif } -void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs) +void IRAM_ATTR spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs) { s_flash_guard_ops = funcs; } -size_t spi_flash_get_chip_size() +size_t IRAM_ATTR spi_flash_get_chip_size() { return g_rom_flashchip.chip_size; } @@ -105,18 +109,32 @@ static SpiFlashOpResult IRAM_ATTR spi_flash_unlock() static inline void IRAM_ATTR spi_flash_guard_start() { - if (s_flash_guard_ops) { + if (s_flash_guard_ops && s_flash_guard_ops->start) { s_flash_guard_ops->start(); } } static inline void IRAM_ATTR spi_flash_guard_end() { - if (s_flash_guard_ops) { + if (s_flash_guard_ops && s_flash_guard_ops->end) { s_flash_guard_ops->end(); } } +static inline void IRAM_ATTR spi_flash_guard_op_lock() +{ + if (s_flash_guard_ops && s_flash_guard_ops->op_lock) { + s_flash_guard_ops->op_lock(); + } +} + +static inline void IRAM_ATTR spi_flash_guard_op_unlock() +{ + if (s_flash_guard_ops && s_flash_guard_ops->op_unlock) { + s_flash_guard_ops->op_unlock(); + } +} + esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec) { return spi_flash_erase_range(sec * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE); @@ -251,9 +269,9 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size) out: COUNTER_STOP(write); - spi_flash_op_lock(); + spi_flash_guard_op_lock(); spi_flash_mark_modified_region(dst, size); - spi_flash_op_unlock(); + spi_flash_guard_op_unlock(); return spi_flash_translate_rc(rc); } @@ -320,9 +338,9 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, } COUNTER_ADD_BYTES(write, size); - spi_flash_op_lock(); + spi_flash_guard_op_lock(); spi_flash_mark_modified_region(dest_addr, size); - spi_flash_op_unlock(); + spi_flash_guard_op_unlock(); return spi_flash_translate_rc(rc); } @@ -444,7 +462,7 @@ esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size } -static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc) +static esp_err_t IRAM_ATTR spi_flash_translate_rc(SpiFlashOpResult rc) { switch (rc) { case SPI_FLASH_RESULT_OK: diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index c1ad7d56fa..060d598ec0 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -205,16 +205,44 @@ typedef void (*spi_flash_guard_start_func_t)(void); * @brief SPI flash critical section exit function. */ typedef void (*spi_flash_guard_end_func_t)(void); +/** + * @brief SPI flash operation lock function. + */ +typedef void (*spi_flash_op_lock_func_t)(void); +/** + * @brief SPI flash operation unlock function. + */ +typedef void (*spi_flash_op_unlock_func_t)(void); /** - * Structure holding SPI flash access critical section management functions + * Structure holding SPI flash access critical sections management functions. + * + * Flash API uses two types of flash access management functions: + * 1) Functions which prepare/restore flash cache and interrupts before calling + * appropriate ROM functions (SPIWrite, SPIRead and SPIEraseBlock): + * - 'start' function should disables flash cache and non-IRAM interrupts and + * is invoked before the call to one of ROM function above. + * - 'end' function should restore state of flash cache and non-IRAM interrupts and + * is invoked after the call to one of ROM function above. + * 2) Functions which synchronizes access to internal data used by flash API. + * This functions are mostly intended to synchronize access to flash API internal data + * in multithreaded environment and use OS primitives: + * - 'op_lock' locks access to flash API internal data. + * - 'op_unlock' unlocks access to flash API internal data. + * Different versions of the guarding functions should be used depending on the context of + * execution (with or without functional OS). In normal conditions when flash API is called + * from task the functions use OS primitives. When there is no OS at all or when + * it is not guaranteed that OS is functional (accessing flash from exception handler) these + * functions cannot use OS primitives or even does not need them (multithreaded access is not possible). * * @note Structure and corresponding guard functions should not reside in flash. * For example structure can be placed in DRAM and functions in IRAM sections. */ typedef struct { - spi_flash_guard_start_func_t start; /**< critical section start func */ - spi_flash_guard_end_func_t end; /**< critical section end func */ + spi_flash_guard_start_func_t start; /**< critical section start func */ + spi_flash_guard_end_func_t end; /**< critical section end func */ + spi_flash_op_lock_func_t op_lock; /**< flash access API lock func */ + spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock func */ } spi_flash_guard_funcs_t; /** From 732a5fd0b2c2e6ff3742781714c4d3d204d90865 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Thu, 2 Feb 2017 21:59:00 +0800 Subject: [PATCH 085/139] CI: get test env config from gitlab Previous design was put test env config on local runners. It's not easy to manage as test runners count growing. Now we'll put config files for test runners to a Gitlab repository. Test runners will get its config from Gitlab every time before running. --- .gitlab-ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5cd5fcecec..8ea64e142b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -291,8 +291,7 @@ check_doc_links: allow_failure: true variables: - # LOCAL_ENV_CONFIG_PATH: define in template and jobs can overwrite if required - LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF + LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF BIN_PATH: "$CI_PROJECT_DIR/SSC/ssc_bin/SSC" APP_NAME: "ssc" LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" @@ -317,6 +316,8 @@ check_doc_links: - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + # clone local test env configs + - git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git # clone test bench - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script @@ -342,6 +343,8 @@ check_doc_links: - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + # clone local test env configs + - git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git # clone test bench - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script @@ -355,8 +358,7 @@ check_doc_links: stage: unit_test variables: - # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary - LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF + LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF BIN_PATH: "$CI_PROJECT_DIR/tools/unit-test-app/build/" LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" APP_NAME: "ut" From 2d5162dc3c375332657264b39f13e4031e7a8765 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 3 Feb 2017 10:07:30 +1100 Subject: [PATCH 086/139] OTA: Always clean up OTA handle regardless of esp_ota_end() result As reported on forum: http://esp32.com/viewtopic.php?f=14&t=1093 --- components/app_update/esp_ota_ops.c | 70 +++++++++++---------- components/app_update/include/esp_ota_ops.h | 13 ++-- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 2338753898..c702a203e2 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -182,40 +182,10 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle) { ota_ops_entry_t *it; size_t image_size; - esp_err_t __attribute__((unused)) ret; + esp_err_t ret = ESP_OK; for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { if (it->handle == handle) { - // an ota handle need to be ended after erased and wrote data in it - if ((it->erased_size == 0) || (it->wrote_size == 0)) { - return ESP_ERR_INVALID_ARG; - } - -#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED - if (it->partial_bytes > 0 && esp_flash_encryption_enabled()) { - /* Write out last 16 bytes, if necessary */ - ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16); - if (ret != ESP_OK) { - return ret; - } - it->wrote_size += 16; - it->partial_bytes = 0; - } -#endif - - if (esp_image_basic_verify(it->part.address, true, &image_size) != ESP_OK) { - return ESP_ERR_OTA_VALIDATE_FAILED; - } - -#ifdef CONFIG_SECURE_BOOT_ENABLED - esp_err_t ret; - ret = esp_secure_boot_verify_signature(it->part.address, image_size); - if (ret != ESP_OK) { - return ESP_ERR_OTA_VALIDATE_FAILED; - } -#endif - - LIST_REMOVE(it, entries); break; } } @@ -224,8 +194,44 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle) return ESP_ERR_NOT_FOUND; } + /* 'it' holds the ota_ops_entry_t for 'handle' */ + + // esp_ota_end() is only valid if some data was written to this handle + if ((it->erased_size == 0) || (it->wrote_size == 0)) { + ret = ESP_ERR_INVALID_ARG; + goto cleanup; + } + +#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED + if (it->partial_bytes > 0 && esp_flash_encryption_enabled()) { + /* Write out last 16 bytes, if necessary */ + ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16); + if (ret != ESP_OK) { + ret = ESP_ERR_INVALID_STATE; + goto cleanup; + } + it->wrote_size += 16; + it->partial_bytes = 0; + } +#endif + + if (esp_image_basic_verify(it->part.address, true, &image_size) != ESP_OK) { + ret = ESP_ERR_OTA_VALIDATE_FAILED; + goto cleanup; + } + +#ifdef CONFIG_SECURE_BOOT_ENABLED + ret = esp_secure_boot_verify_signature(it->part.address, image_size); + if (ret != ESP_OK) { + ret = ESP_ERR_OTA_VALIDATE_FAILED; + goto cleanup; + } +#endif + + cleanup: + LIST_REMOVE(it, entries); free(it); - return ESP_OK; + return ret; } static uint32_t ota_select_crc(const ota_select *s) diff --git a/components/app_update/include/esp_ota_ops.h b/components/app_update/include/esp_ota_ops.h index 846aa2b2cf..fe3307763f 100755 --- a/components/app_update/include/esp_ota_ops.h +++ b/components/app_update/include/esp_ota_ops.h @@ -73,11 +73,16 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size); /** * @brief Finish the update and validate written data * - * @param handle Handle obtained from esp_ota_begin + * @param handle Handle obtained from esp_ota_begin. * - * @return: - * - ESP_OK: if validate ota image pass - * - ESP_ERR_OTA_VALIDATE_FAILED: validate the ota image is invalid + * @note After calling esp_ota_end(), the handle is no longer valid and any memory associated with it is freed (regardless of result). + * + * @return: + * - ESP_OK: Newly written OTA app image is valid. + * - ESP_ERR_NOT_FOUND: OTA handle was not found. + * - ESP_ERR_INVALID_ARG: Handle was never written to. + * - ESP_ERR_OTA_VALIDATE_FAILED: OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.) + * - ESP_ERR_INVALID_STATE: If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash. */ esp_err_t esp_ota_end(esp_ota_handle_t handle); From 627bc23b1c3aa049b5d65762ba6ae996ebe13aaf Mon Sep 17 00:00:00 2001 From: shangke Date: Mon, 6 Feb 2017 11:19:16 +0800 Subject: [PATCH 087/139] ethernet:disable flow control when select l2_to_l3_copy_mode --- components/ethernet/emac_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index 853887cfc5..fd0f59604f 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -537,6 +537,10 @@ static void emac_check_phy_init(void) } else { REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED); } +#if CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE + emac_disable_flowctrl(); + emac_config.emac_flow_ctrl_partner_support = false; +#else if (emac_config.emac_flow_ctrl_enable == true) { if (emac_config.emac_phy_get_partner_pause_enable() == true && emac_config.emac_phy_get_duplex_mode() == ETH_MDOE_FULLDUPLEX) { emac_enable_flowctrl(); @@ -549,6 +553,7 @@ static void emac_check_phy_init(void) emac_disable_flowctrl(); emac_config.emac_flow_ctrl_partner_support = false; } +#endif emac_mac_enable_txrx(); } static void emac_process_link_updown(bool link_status) From d07a149e2cc32ecb9b5d933ff88e3e1613ce3fc7 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 27 Jan 2017 17:17:05 +0800 Subject: [PATCH 088/139] Fix interrupting task on other CPU that has lower prio than current task on current CPU --- components/freertos/tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 0b5cc42957..f885e9c013 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -632,7 +632,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode */ void taskYIELD_OTHER_CORE( BaseType_t xCoreID, UBaseType_t uxPriority ) { - TCB_t *curTCB = xTaskGetCurrentTaskHandle(); + TCB_t *curTCB = pxCurrentTCB[xCoreID]; BaseType_t i; if (xCoreID != tskNO_AFFINITY) { From b748a63a43efa4118157fed4f4c0488b0baf38c9 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Mon, 6 Feb 2017 17:56:42 +0800 Subject: [PATCH 089/139] esp32: fix several misc wifi issue 1. Fix ssid_str not free issue 2. Fix sniffer not work issue 3. Fix null parameter cause esp_wifi_init crash issue 4. Enable ap ampdu rx interface --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 45414a6778..d0b9797601 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 45414a6778e1bf2855f18a8c6b954d5cf575bb40 +Subproject commit d0b97976010528cbb469d5bb12f2c20449ca6c5b From 777816cb99874b9c7f53ad93365fd5fffbefd364 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 7 Feb 2017 15:14:45 +0800 Subject: [PATCH 090/139] =?UTF-8?q?phy=5Finit:=20don=E2=80=99t=20rewrite?= =?UTF-8?q?=20valid=20calibration=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the default PHY init routine, calibration data is loaded from NVS. Most of the time the incremental changes to calibration will be fairly small, so we don’t need to rewrite the existing calibration data stored in the NVS. Possible enhancement to be done in the future: expose a function in PHY library to tell how big was the change in calibration data. If the change was significant, then calibration data stored in NVS should be updated. --- components/esp32/cpu_start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 001d1706e1..5278f9b166 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -294,7 +294,7 @@ static void do_phy_init() esp_phy_init(init_data, calibration_mode, cal_data); - if (calibration_mode != PHY_RF_CAL_NONE) { + if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) { err = esp_phy_store_cal_data_to_nvs(cal_data); } else { err = ESP_OK; From 7093c59a7484400489d1c5a3a51680cd68721637 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Fri, 10 Feb 2017 10:28:03 +0800 Subject: [PATCH 091/139] esp32: update wifi lib for some fixes and optimizations 1. Reduce the default static rx buffer size from 25 to 10 2. Adjust ampdu interrupt size to 3, namely, raise 1 interrupt per 3-mpdu 3. Make a copy for all received packets, including AMSDU/AMPDU/MPDU 4. Fix softap mis-forward issue 5. Fix pp q full issue 6. Fix sniffer copy wrong content issue --- components/esp32/Kconfig | 2 +- components/esp32/lib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index c6e4cc7e22..db9bb2539f 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -495,7 +495,7 @@ config ESP32_WIFI_RX_BUFFER_NUM int "Max number of WiFi RX buffers" depends on WIFI_ENABLED range 2 25 - default 25 + default 10 help Set the number of WiFi rx buffers. Each buffer takes approximately 1.6KB of RAM. Larger number for higher throughput but more memory. Smaller number for lower diff --git a/components/esp32/lib b/components/esp32/lib index d0b9797601..1627461bf2 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit d0b97976010528cbb469d5bb12f2c20449ca6c5b +Subproject commit 1627461bf2fc2ec8a090b30cddae2118d542c454 From 0017e75bdad9bb48c2161063793ac423de4a609f Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 24 Jan 2017 20:40:14 +0800 Subject: [PATCH 092/139] freertos: fix protection issue in freertos queue event list When functions in queue.c calls listLIST_IS_EMPTY() to check queue event list, the queue list is protected by queue mutex, on the other hand, when xTaskIncrementTick() modify the queue list, the queue list is protected by xTaskQueueMutex, this may cause xTaskRemoveFromEventList operate on the empty queue list and cause problem. This commit is to fix this bug. may cause --- components/freertos/tasks.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index f885e9c013..02d1842874 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -3012,9 +3012,14 @@ BaseType_t xReturn; This function assumes that a check has already been made to ensure that pxEventList is not empty. */ - pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); - configASSERT( pxUnblockedTCB ); - ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + if ( ( listLIST_IS_EMPTY( pxEventList ) ) == pdFALSE ) { + pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + } else { + taskEXIT_CRITICAL_ISR(&xTaskQueueMutex); + return pdFALSE; + } if( uxSchedulerSuspended[ xPortGetCoreID() ] == ( UBaseType_t ) pdFALSE ) { @@ -3025,9 +3030,7 @@ BaseType_t xReturn; { /* The delayed and ready lists cannot be accessed, so hold this task pending until the scheduler is resumed. */ - taskENTER_CRITICAL(&xTaskQueueMutex); vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxUnblockedTCB->xEventListItem ) ); - taskEXIT_CRITICAL(&xTaskQueueMutex); } if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) From 2c334b46e06cddbc2cf9dc155c233e2d27d8cde0 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Wed, 8 Feb 2017 15:03:57 +0800 Subject: [PATCH 093/139] component/bt : fix BLUFI bug with small MTU size --- .../bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c | 13 +++++++++---- .../btc/profile/esp/blufi/include/blufi_int.h | 5 ++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c b/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c index 15b4ccf5a9..bf9ba35a04 100644 --- a/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c +++ b/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c @@ -177,6 +177,10 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) blufi_env.prepare_buf = NULL; } + break; + case BTA_GATTS_MTU_EVT: + LOG_DEBUG("MTU size %d\n", p_data->req_data.p_data->mtu); + blufi_env.frag_size = p_data->req_data.p_data->mtu - BLUFI_MTU_RESERVED_SIZE; break; case BTA_GATTS_CONF_EVT: LOG_DEBUG("CONIRM EVT\n"); @@ -294,6 +298,7 @@ static tGATT_STATUS btc_blufi_profile_init(void) memset(&blufi_env, 0x0, sizeof(blufi_env)); blufi_env.cbs = store_p; /* if set callback prior, restore the point */ + blufi_env.frag_size = BLUFI_FRAG_DATA_DEFAULT_LEN; /* register the BLUFI profile to the BTA_GATTS module*/ BTA_GATTS_AppRegister(&blufi_app_uuid, blufi_profile_cb); @@ -406,16 +411,16 @@ void btc_blufi_send_encap(uint8_t type, uint8_t *data, int total_data_len) int ret; while (remain_len > 0) { - if (remain_len > BLUFI_FRAG_DATA_MAX_LEN) { - hdr = GKI_getbuf(sizeof(struct blufi_hdr) + 2 + BLUFI_FRAG_DATA_MAX_LEN + 2); + if (remain_len > blufi_env.frag_size) { + hdr = GKI_getbuf(sizeof(struct blufi_hdr) + 2 + blufi_env.frag_size + 2); if (hdr == NULL) { LOG_ERROR("%s no mem\n", __func__); return; } hdr->fc = 0x0; - hdr->data_len = BLUFI_FRAG_DATA_MAX_LEN + 2; + hdr->data_len = blufi_env.frag_size + 2; *(uint16_t *)hdr->data = remain_len; - memcpy(hdr->data + 2, &data[total_data_len - remain_len], BLUFI_FRAG_DATA_MAX_LEN); //copy first, easy for check sum + memcpy(hdr->data + 2, &data[total_data_len - remain_len], blufi_env.frag_size); //copy first, easy for check sum hdr->fc |= BLUFI_FC_FRAG; } else { hdr = GKI_getbuf(sizeof(struct blufi_hdr) + remain_len + 2); diff --git a/components/bt/bluedroid/btc/profile/esp/blufi/include/blufi_int.h b/components/bt/bluedroid/btc/profile/esp/blufi/include/blufi_int.h index c21b41c4ca..c8b002348d 100644 --- a/components/bt/bluedroid/btc/profile/esp/blufi/include/blufi_int.h +++ b/components/bt/bluedroid/btc/profile/esp/blufi/include/blufi_int.h @@ -33,6 +33,7 @@ typedef struct { BD_ADDR remote_bda; UINT32 trans_id; UINT8 congest; + UINT16 frag_size; #define BLUFI_PREPAIR_BUF_MAX_SIZE 1024 uint8_t *prepare_buf; int prepare_len; @@ -160,7 +161,9 @@ typedef struct blufi_frag_hdr blufi_frag_hdr_t; #define BLUFI_FC_IS_REQ_ACK(fc) ((fc) & BLUFI_FC_REQ_ACK_MASK) #define BLUFI_FC_IS_FRAG(fc) ((fc) & BLUFI_FC_FRAG_MASK) -#define BLUFI_FRAG_DATA_MAX_LEN 50 +/* BLUFI HEADER + TOTAL(REMAIN) LENGTH + CRC + L2CAP RESERVED */ +#define BLUFI_MTU_RESERVED_SIZE (sizeof(struct blufi_hdr) + 2 + 2 + 3) +#define BLUFI_FRAG_DATA_DEFAULT_LEN (GATT_DEF_BLE_MTU_SIZE - BLUFI_MTU_RESERVED_SIZE) //function declare void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len); From cf917567e9ae55aa96633094afcc9b771fb466e4 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Fri, 10 Feb 2017 11:02:10 +0800 Subject: [PATCH 094/139] component/bt : use real adv data to set raw adv data --- examples/bluetooth/gatt_server/main/Kconfig | 10 +++++---- .../bluetooth/gatt_server/main/gatts_demo.c | 22 +++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/examples/bluetooth/gatt_server/main/Kconfig b/examples/bluetooth/gatt_server/main/Kconfig index e37d40057f..7f01d57447 100644 --- a/examples/bluetooth/gatt_server/main/Kconfig +++ b/examples/bluetooth/gatt_server/main/Kconfig @@ -1,10 +1,12 @@ menu "Example 'GATT SERVER' Config" config SET_RAW_ADV_DATA - bool "adv data or scan_rsp data use raw data or structure" - default "y" + bool "Use raw data for advertising packets and scan response data" help - Set raw advertising data/scan response data by self or use adv_data/scan_rsp_data structure to - set advertising data/scan response data. If use structure, lower layer will encapsulate the packets. + If this config item is set, raw binary data will be used to generate advertising & scan response data. + This option uses the esp_ble_gap_config_adv_data_raw() and esp_ble_gap_config_scan_rsp_data_raw() functions. + + If this config item is unset, advertising & scan response data is provided via a higher-level esp_ble_adv_data_t structure. + The lower layer will generate the BLE packets. This option has higher overhead at runtime. endmenu diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index a018ddb752..0afa1630ba 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -51,21 +51,25 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i #define TEST_DEVICE_NAME "ESP_GATTS_DEMO" #define TEST_MANUFACTURER_DATA_LEN 17 -#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 +#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 uint8_t char1_str[] = {0x11,0x22,0x33}; esp_attr_value_t gatts_demo_char1_val = { - .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, - .attr_len = sizeof(char1_str), - .attr_value = char1_str, + .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, + .attr_len = sizeof(char1_str), + .attr_value = char1_str, }; #ifdef CONFIG_SET_RAW_ADV_DATA -static uint8_t raw_adv_data[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe}; -static uint8_t raw_scan_rsp_data[] = {0x7, 0x7, 0x7, 0x7, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, - 0xb, 0xb, 0xb, 0xb, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xe, 0xe, 0xe}; +static uint8_t raw_adv_data[] = { + 0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, + 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd +}; +static uint8_t raw_scan_rsp_data[] = { + 0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, + 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd +}; #else static uint8_t test_service_uuid128[32] = { /* LSB <--------------------------------------------------------------------------------> MSB */ @@ -211,7 +215,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i case ESP_GATTS_ADD_INCL_SRVC_EVT: break; case ESP_GATTS_ADD_CHAR_EVT: { - uint16_t length = 0; + uint16_t length = 0; const uint8_t *prf_char; ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", From 9893b71096a2d2e0ee2e377128cd775226741170 Mon Sep 17 00:00:00 2001 From: shangke Date: Sat, 11 Feb 2017 15:19:53 +0800 Subject: [PATCH 095/139] ethernet: add a gpio to enable/disable phy power --- components/ethernet/emac_common.h | 1 + components/ethernet/emac_main.c | 8 +++++++ components/ethernet/include/esp_eth.h | 3 ++- .../ethernet/ethernet/main/ethernet_main.c | 22 ++++++++++++++----- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/components/ethernet/emac_common.h b/components/ethernet/emac_common.h index 957337d2a7..d68c20a056 100644 --- a/components/ethernet/emac_common.h +++ b/components/ethernet/emac_common.h @@ -75,6 +75,7 @@ struct emac_config_data { bool emac_flow_ctrl_enable; bool emac_flow_ctrl_partner_support; eth_phy_get_partner_pause_enable_func emac_phy_get_partner_pause_enable; + eth_phy_power_enable_func emac_phy_power_enable; }; enum emac_post_type { diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index fd0f59604f..5479ec399e 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -225,6 +225,7 @@ static void emac_set_user_config_data(eth_config_t *config ) emac_config.emac_flow_ctrl_enable = false; #endif emac_config.emac_phy_get_partner_pause_enable = config->phy_get_partner_pause_enable; + emac_config.emac_phy_power_enable = config->phy_power_enable; } static void emac_enable_intr() @@ -291,6 +292,11 @@ static esp_err_t emac_verify_args(void) ret = ESP_FAIL; } + if(emac_config.emac_phy_power_enable == NULL) { + ESP_LOGE(TAG, "phy power enable func is null"); + ret = ESP_FAIL; + } + return ret; } @@ -943,6 +949,8 @@ esp_err_t esp_eth_init(eth_config_t *config) emac_set_user_config_data(config); } + emac_config.emac_phy_power_enable(true); + ret = emac_verify_args(); if (ret != ESP_OK) { diff --git a/components/ethernet/include/esp_eth.h b/components/ethernet/include/esp_eth.h index e36c3ebfe6..2fea05c923 100644 --- a/components/ethernet/include/esp_eth.h +++ b/components/ethernet/include/esp_eth.h @@ -80,7 +80,7 @@ typedef void (*eth_phy_func)(void); typedef esp_err_t (*eth_tcpip_input_func)(void *buffer, uint16_t len, void *eb); typedef void (*eth_gpio_config_func)(void); typedef bool (*eth_phy_get_partner_pause_enable_func)(void); - +typedef void (*eth_phy_power_enable_func)(bool enable); /** * @brief ethernet configuration @@ -98,6 +98,7 @@ typedef struct { eth_gpio_config_func gpio_config; /*!< gpio config func */ bool flow_ctrl_enable; /*!< flag of flow ctrl enable */ eth_phy_get_partner_pause_enable_func phy_get_partner_pause_enable; /*!< get partner pause enable */ + eth_phy_power_enable_func phy_power_enable; } eth_config_t; diff --git a/examples/ethernet/ethernet/main/ethernet_main.c b/examples/ethernet/ethernet/main/ethernet_main.c index 57c6f97357..8cb9ca5e52 100644 --- a/examples/ethernet/ethernet/main/ethernet_main.c +++ b/examples/ethernet/ethernet/main/ethernet_main.c @@ -87,6 +87,17 @@ void phy_enable_flow_ctrl(void) esp_eth_smi_write(AUTO_NEG_ADVERTISEMENT_REG,data|ASM_DIR|PAUSE); } +void phy_tlk110_power_enable(bool enable) +{ + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_GPIO17); + gpio_set_direction(17,GPIO_MODE_OUTPUT); + if(enable == true) { + gpio_set_level(17, 1); + } else { + gpio_set_level(17, 0); + } +} + void phy_tlk110_init(void) { esp_eth_smi_write(PHY_RESET_CONTROL_REG, SOFTWARE_RESET); @@ -117,11 +128,11 @@ void eth_gpio_config_rmii(void) //rmii clk ,can not change gpio_set_direction(0, GPIO_MODE_INPUT); - //mdc to gpio4 - gpio_matrix_out(4, EMAC_MDC_O_IDX, 0, 0); - //mdio to gpio2 - gpio_matrix_out(2, EMAC_MDO_O_IDX, 0, 0); - gpio_matrix_in(2, EMAC_MDI_I_IDX, 0); + //mdc to gpio23 + gpio_matrix_out(23, EMAC_MDC_O_IDX, 0, 0); + //mdio to gpio18 + gpio_matrix_out(18, EMAC_MDO_O_IDX, 0, 0); + gpio_matrix_in(18, EMAC_MDI_I_IDX, 0); } void eth_task(void *pvParameter) @@ -163,6 +174,7 @@ void app_main() //Only FULLDUPLEX mode support flow ctrl now! config.flow_ctrl_enable = true; config.phy_get_partner_pause_enable = phy_tlk110_get_partner_pause_enable; + config.phy_power_enable = phy_tlk110_power_enable; ret = esp_eth_init(&config); From e8b7670db3b2d74861d98637d389d0008d9b0891 Mon Sep 17 00:00:00 2001 From: shangke Date: Sat, 11 Feb 2017 16:42:16 +0800 Subject: [PATCH 096/139] ethernet: add doc --- components/ethernet/include/esp_eth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ethernet/include/esp_eth.h b/components/ethernet/include/esp_eth.h index 2fea05c923..c2a3554b11 100644 --- a/components/ethernet/include/esp_eth.h +++ b/components/ethernet/include/esp_eth.h @@ -98,7 +98,7 @@ typedef struct { eth_gpio_config_func gpio_config; /*!< gpio config func */ bool flow_ctrl_enable; /*!< flag of flow ctrl enable */ eth_phy_get_partner_pause_enable_func phy_get_partner_pause_enable; /*!< get partner pause enable */ - eth_phy_power_enable_func phy_power_enable; + eth_phy_power_enable_func phy_power_enable; /*!< enable or disable phy power */ } eth_config_t; From 3aa2b571ae8fd07a289cc174e877f077456f794c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lourens=20Naud=C3=A9?= Date: Sun, 12 Feb 2017 22:48:41 +0000 Subject: [PATCH 097/139] Add espcoredump to the add_path shell helper --- add_path.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add_path.sh b/add_path.sh index 6b69f8d44f..1c0b0ed0ed 100644 --- a/add_path.sh +++ b/add_path.sh @@ -9,7 +9,7 @@ if [ -z ${IDF_PATH} ]; then echo "IDF_PATH must be set before including this script." else - IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/partition_table/" + IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/espcoredump:${IDF_PATH}/components/partition_table/" export PATH="${PATH}:${IDF_ADD_PATHS_EXTRAS}" echo "Added to PATH: ${IDF_ADD_PATHS_EXTRAS}" fi From 5fd7bd14dbc3adc6aedb74918103c9999f1dc322 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Mon, 13 Feb 2017 14:00:26 +0800 Subject: [PATCH 098/139] component/bt : fix GATT disconnect memory leak bug --- components/bt/bluedroid/stack/gatt/gatt_sr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index a7ee3b5ad0..793ac1a9b0 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -1162,6 +1162,10 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 } else if (reason == GATT_SUCCESS || reason == GATT_STACK_RSP) { attp_send_sr_msg(p_tcb, p_msg); gatt_dequeue_sr_cmd(p_tcb); + } else { + if (p_msg) { + GKI_freebuf(p_msg); + } } } From 473f2cff51e13bbbc98b77f791430625ce047ce7 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 9 Feb 2017 12:12:28 +1100 Subject: [PATCH 099/139] kconfig: Remove gperf 3.1+ incompatible kconf_conf_id forward declaration Forward declaration was unused. gperf 3.1+ changed parameter type from 'unsigned int' to 'size_t'. --- tools/kconfig/zconf.gperf | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/kconfig/zconf.gperf b/tools/kconfig/zconf.gperf index ac498f01b4..d1ede16a80 100644 --- a/tools/kconfig/zconf.gperf +++ b/tools/kconfig/zconf.gperf @@ -9,8 +9,6 @@ struct kconf_id; -static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); - %% mainmenu, T_MAINMENU, TF_COMMAND menu, T_MENU, TF_COMMAND From dcd5c5bb7301e675556412100d7dad07bf49195a Mon Sep 17 00:00:00 2001 From: Malte Janduda Date: Tue, 10 Jan 2017 21:48:15 +0100 Subject: [PATCH 100/139] Example 10_openssl_server should use TLSv1.2 instead of SSLv3; fixed corrupted HTTP Header --- examples/protocols/openssl_server/main/openssl_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/protocols/openssl_server/main/openssl_server.c b/examples/protocols/openssl_server/main/openssl_server.c index 1eea2110ce..7569124f7f 100755 --- a/examples/protocols/openssl_server/main/openssl_server.c +++ b/examples/protocols/openssl_server/main/openssl_server.c @@ -37,7 +37,7 @@ const static char *TAG = "Openssl_demo"; #define OPENSSL_DEMO_SERVER_ACK "HTTP/1.1 200 OK\r\n" \ "Content-Type: text/html\r\n" \ - "Content-Length: 98\r\n" \ + "Content-Length: 98\r\n\r\n" \ "\r\n" \ "\r\n" \ "OpenSSL demo\r\n" \ @@ -71,7 +71,7 @@ static void openssl_demo_thread(void *p) const unsigned int prvtkey_pem_bytes = prvtkey_pem_end - prvtkey_pem_start; ESP_LOGI(TAG, "SSL server context create ......"); - ctx = SSL_CTX_new(TLS_server_method()); + ctx = SSL_CTX_new(TLSv1_2_server_method()); if (!ctx) { ESP_LOGI(TAG, "failed"); goto failed1; From 10c2e984dcb112604c91457a2975fa3b4c3418d7 Mon Sep 17 00:00:00 2001 From: Marcin Galczynski Date: Tue, 17 Jan 2017 18:20:17 +0100 Subject: [PATCH 101/139] esp32: Move esp_crosscore_int_send_yield() to IRAM --- components/esp32/crosscore_int.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 1e131eeef7..f75f0eba7d 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -82,7 +82,7 @@ void esp_crosscore_int_init() { assert(err == ESP_OK); } -void esp_crosscore_int_send_yield(int coreId) { +void IRAM_ATTR esp_crosscore_int_send_yield(int coreId) { assert(coreId Date: Thu, 26 Jan 2017 09:30:12 +0700 Subject: [PATCH 102/139] =?UTF-8?q?Fix=20fopen()=20in=20=E2=80=9Ca?= =?UTF-8?q?=E2=80=9D=20(append)=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fopen() does not work when file is opened in “a” (append) mode --- components/fatfs/src/vfs_fat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/fatfs/src/vfs_fat.c b/components/fatfs/src/vfs_fat.c index 4ef387b43b..73bed5eaa1 100644 --- a/components/fatfs/src/vfs_fat.c +++ b/components/fatfs/src/vfs_fat.c @@ -152,7 +152,7 @@ static int fat_mode_conv(int m) } if ((m & O_CREAT) && (m & O_EXCL)) { res |= FA_CREATE_NEW; - } else if (m & O_CREAT) { + } else if ((m & O_CREAT) && (m & O_TRUNC)) { res |= FA_CREATE_ALWAYS; } else if (m & O_APPEND) { res |= FA_OPEN_ALWAYS; From 22c38771837ce8be8208d40fafbdc1d35c055a56 Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Thu, 26 Jan 2017 01:47:53 +0000 Subject: [PATCH 103/139] Expand environment variables in gen_esp32part Allows parametrizing partition table with (exported) make variables. --- components/partition_table/gen_esp32part.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index 0491204885..6d6137f172 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -5,8 +5,10 @@ # Converts partition tables to/from CSV and binary formats. # # See the sdkng README.md file for details about how to use this tool. -import struct import argparse +import os +import re +import struct import sys MAX_PARTITION_LENGTH = 0xC00 # 3K for partition data (96 entries) leaves 1K in a 4K sector for signature @@ -163,7 +165,13 @@ class PartitionDefinition(object): def from_csv(cls, line): """ Parse a line from the CSV """ line_w_defaults = line + ",,,," # lazy way to support default fields - fields = [ f.strip() for f in line_w_defaults.split(",") ] + def expand_vars(f): + f = os.path.expandvars(f) + m = re.match(r'(?>sys.stderr, e sys.exit(2) From 7c7edab328e4c193f12b118a44501a7c9dbc6905 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 14 Feb 2017 12:48:28 +1100 Subject: [PATCH 104/139] flash encryption/secure boot: Restructure documentation Also add steps to disable flash encryption, as some people seem to accidentally enable it. Explicitly mark the flash encryption and secure boot as "READ DOCS FIRST" in menuconfig. --- README.md | 2 +- components/bootloader/Kconfig.projbuild | 18 +- .../include/esp_flash_encrypt.h | 10 +- docs/Doxyfile | 3 +- docs/api/storage/spi_flash.rst | 2 +- docs/security/flash-encryption.rst | 354 +++++++++++------- docs/security/secure-boot.rst | 62 +-- 7 files changed, 273 insertions(+), 178 deletions(-) diff --git a/README.md b/README.md index 59191bc7d9..cae4646309 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ After the initial flash, you may just want to build and flash just your app, not `make app-flash` will automatically rebuild the app if it needs it. -(There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) +(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) ## Parallel Builds diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 798fcf0b23..ac4d1d14b9 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -35,16 +35,16 @@ endmenu menu "Security features" config SECURE_BOOT_ENABLED - bool "Enable secure boot in bootloader" + bool "Enable secure boot in bootloader (READ DOCS FIRST)" default N help Build a bootloader which enables secure boot on first boot. - Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition table or boot an app if the data has a verified digital signature. + Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition table or boot an app if the data has a verified digital signature. There are implications for reflashing updated apps once secure boot is enabled. When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default. - See docs/security/secure-boot.rst for details. + Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling. choice SECURE_BOOTLOADER_MODE bool "Secure bootloader mode" @@ -108,7 +108,7 @@ config SECURE_BOOT_VERIFICATION_KEY PEM formatted private key using the espsecure.py extract_public_key command. - See docs/security/secure-boot.rst for details. + Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling. config SECURE_BOOT_INSECURE bool "Allow potentially insecure options" @@ -119,16 +119,18 @@ config SECURE_BOOT_INSECURE Only enable these options if you are very sure. - Refer to docs/security/secure-boot.rst and docs/security/flash-encryption.rst for details. + Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling. config FLASH_ENCRYPTION_ENABLED - bool "Enable flash encryption on boot" + bool "Enable flash encryption on boot (READ DOCS FIRST)" default N help If this option is set, flash contents will be encrypted by the bootloader on first boot. - Note: After first boot, the system will be permanently encrypted. - See docs/securityflash-encryption.rst for details. + Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted + system is complicated and not always possible. + + Read http://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html before enabling. config FLASH_ENCRYPTION_INSECURE bool "Allow potentially insecure options" diff --git a/components/bootloader_support/include/esp_flash_encrypt.h b/components/bootloader_support/include/esp_flash_encrypt.h index 015dea030a..867d600ae7 100644 --- a/components/bootloader_support/include/esp_flash_encrypt.h +++ b/components/bootloader_support/include/esp_flash_encrypt.h @@ -19,10 +19,12 @@ #include "esp_spi_flash.h" #include "soc/efuse_reg.h" -/* Support functions for flash encryption features. - - Can be compiled as part of app or bootloader code. -*/ +/** + * @file esp_partition.h + * @brief Support functions for flash encryption features + * + * Can be compiled as part of app or bootloader code. + */ /** @brief Is flash encryption currently enabled in hardware? * diff --git a/docs/Doxyfile b/docs/Doxyfile index aa6c87476e..43d2273819 100755 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -37,7 +37,8 @@ INPUT = ../components/esp32/include/esp_wifi.h \ ../components/fatfs/src/esp_vfs_fat.h \ ../components/fatfs/src/diskio.h \ ../components/esp32/include/esp_core_dump.h \ - ../components/mdns/include/mdns.h + ../components/mdns/include/mdns.h \ + ../components/bootloader_support/include/esp_flash_encrypt.h ## Get warnings for functions that have no documentation for their parameters or return value ## diff --git a/docs/api/storage/spi_flash.rst b/docs/api/storage/spi_flash.rst index cbb2be0d70..5725ceb0c9 100644 --- a/docs/api/storage/spi_flash.rst +++ b/docs/api/storage/spi_flash.rst @@ -8,7 +8,7 @@ Header Files * :component_file:`spi_flash/include/esp_spi_flash.h` * :component_file:`spi_flash/include/esp_partition.h` - * :component_file:`esp32/include/esp_flash_encrypt.h` + * :component_file:`bootloader_support/include/esp_flash_encrypt.h` Macros ^^^^^^ diff --git a/docs/security/flash-encryption.rst b/docs/security/flash-encryption.rst index 8c6bd4c857..8448f020bd 100644 --- a/docs/security/flash-encryption.rst +++ b/docs/security/flash-encryption.rst @@ -3,9 +3,9 @@ Flash Encryption Flash Encryption is a feature for encrypting the contents of the ESP32's attached SPI flash. When flash encryption is enabled, physical readout of the SPI flash is not sufficient to recover most flash contents. -Flash Encryption is separate from the `Secure Boot` feature, and you can use flash encryption without enabling secure boot. However we recommend using both features together for a secure environment. +Flash Encryption is separate from the :doc:`Secure Boot ` feature, and you can use flash encryption without enabling secure boot. However we recommend using both features together for a secure environment. -**IMPORTANT: Enabling flash encryption limits your options for further updates of your ESP32. Make sure to read this document (including `Limitations of Flash Encryption` and understand the implications of enabling flash encryption.** +**IMPORTANT: Enabling flash encryption limits your options for further updates of your ESP32. Make sure to read this document (including :ref:`flash-encryption-limitations`) and understand the implications of enabling flash encryption.** Background ---------- @@ -17,6 +17,7 @@ Background - Encryption is applied by flashing the ESP32 with plaintext data, and (if encryption is enabled) the bootloader encrypts the data in place on first boot. - Not all of the flash is encrypted. The following kinds of flash data are encrypted: + - Bootloader - Secure boot bootloader digest (if secure boot is enabled) - Partition Table @@ -29,58 +30,75 @@ Background - The `flash encryption algorithm` is AES-256, where the key is "tweaked" with the offset address of each 32 byte block of flash. This means every 32 byte block (two consecutive 16 byte AES blocks) is encrypted with a unique key derived from the flash encryption key. -- Although software running on the chip can transparently decrypt flash contents, by default it is made possible for the UART bootloader to decrypt (or encrypt) data when flash encryption is enabled. +- Although software running on the chip can transparently decrypt flash contents, by default it is made impossible for the UART bootloader to decrypt (or encrypt) data when flash encryption is enabled. + +- If flash encrption may be enabled, the programmer must take certain precautions when writing code that :ref:`uses encrypted flash `. + +.. _flash-encryption-initialisation: Flash Encryption Initialisation ------------------------------- -This is the default (and recommended) flash encryption initialisation process. It is possible to customise this process for development or other purposes, see `Flash Encryption Advanced Features` for details. +This is the default (and recommended) flash encryption initialisation process. It is possible to customise this process for development or other purposes, see :ref:`flash-encryption-advanced-features` for details. -**IMPORTANT: Once flash encryption is enabled on first boot, the hardware allows a maximum of 3 subsequent flash updates via physical re-flashing. If secure boot is enabled, no physical re-flashes are possible. OTA updates can be used to update flash content without counting towards this limit. When enabling flash encryption in development, use a `precalculated flash encryption key` to allow physically re-flashing an unlimited number of times with pre-encrypted data.** +**IMPORTANT: Once flash encryption is enabled on first boot, the hardware allows a maximum of 3 subsequent flash updates via serial re-flashing.** A special procedure (documented in :ref:`updating-encrypted-flash-serial`) must be followed to perform these updates. -- The bootloader must be compiled with flash encryption support enabled. In ``make menuconfig``, navigate to "Security Features" and select "Yes" for "Enable flash nencryption on boot". +- If secure boot is enabled, no physical re-flashes are possible. +- OTA updates can be used to update flash content without counting towards this limit. +- When enabling flash encryption in development, use a `pregenerated flash encryption key` to allow physically re-flashing an unlimited number of times with pre-encrypted data.** -- If enabling Secure Boot at the same time, you can simultaneously select those options now. See the `Secure Boot` documentation for details. +Process to enable flash encryption: + +- The bootloader must be compiled with flash encryption support enabled. In ``make menuconfig``, navigate to "Security Features" and select "Yes" for "Enable flash encryption on boot". + +- If enabling Secure Boot at the same time, it is best to simultaneously select those options now. Read the :doc:`Secure Boot ` documentation first. - Build and flash the bootloader, partition table and factory app image as normal. These partitions are initially written to the flash unencrypted. -- On first boot, the bootloader sees ``FLASH_CRYPT_CNT`` efuse is set to 0 so it generates a flash encryption key using the hardware random number generator. This key is stored in efuse. The key is read and write protected against further software access. +- On first boot, the bootloader sees :ref:`FLASH_CRYPT_CNT` is set to 0 (factory default) so it generates a flash encryption key using the hardware random number generator. This key is stored in efuse. The key is read and write protected against further software access. - All of the encrypted partitions are then encrypted in-place by the bootloader. Encrypting in-place can take some time (up to a minute for large partitions.) -**IMPORTANT: Do not interrupt power to the ESP32 while the first boot encryption pass is running. If power is interrupted, the flash contents will be corrupted and require flashing with unencrypted data again. This re-flash will not count towards the flashing limit, as ``FLASH_CRYPT_CNT`` is only updated after this process finishes.** +**IMPORTANT: Do not interrupt power to the ESP32 while the first boot encryption pass is running. If power is interrupted, the flash contents will be corrupted and require flashing with unencrypted data again. A reflash like this will not count towards the flashing limit.** -- Once flashing is complete. efuses are blown (by default) to disable encrypted flash access while the UART bootloader is running. +- Once flashing is complete. efuses are blown (by default) to disable encrypted flash access while the UART bootloader is running. See :ref:`uart-bootloader-encryption` for advanced details. -- If not already write-protected, the ``FLASH_CRYPT_CONFIG`` efuse is also burned to the maximum value (``0xF``) to maximise the number of key bits which are tweaked in the flash algorithm. See `Setting FLASH_CRYPT_CONFIG` for details of this efuse. +- The ``FLASH_CRYPT_CONFIG`` efuse is also burned to the maximum value (``0xF``) to maximise the number of key bits which are tweaked in the flash algorithm. See :ref:`setting-flash-crypt-config` for advanced details. -- Finally, the ``FLASH_CRYPT_CNT`` efuse is burned with the initial value 1. It is this efuse which activates the transparent flash encryption layer, and limits the number of subsequent reflashes. See the `Updating Encrypted Flash` section for details about ``FLASH_CRYPT_CNT``. +- Finally, the :ref:`FLASH_CRYPT_CNT` is burned with the initial value 1. It is this efuse which activates the transparent flash encryption layer, and limits the number of subsequent reflashes. See the :ref:`updating-encrypted-flash` section for details about :ref:`FLASH_CRYPT_CNT`. - The bootloader resets itself to reboot from the newly encrypted flash. +.. _using-encrypted-flash: -Encrypted Flash Access ----------------------- +Using Encrypted Flash +--------------------- -Reading Encrypted Flash -^^^^^^^^^^^^^^^^^^^^^^^ +ESP32 app code can check if flash encryption is currently enabled by calling :func:`esp_flash_encryption_enabled`. -Whenever the ``FLASH_CRYPT_CNT`` efuse is set to a value with an odd number of bits set, all flash content which is accessed via the MMU's flash cache is transparently decrypted. This includes: +Once flash encryption is enabled, some care needs to be taken when accessing flash contents from code. + +Scope of Flash Encryption +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Whenever the :ref:`FLASH_CRYPT_CNT` is set to a value with an odd number of bits set, all flash content which is accessed via the MMU's flash cache is transparently decrypted. This includes: - Executable application code in flash (IROM). - All read-only data stored in flash (DROM). -- Any data accessed via ``esp_spi_flash_mmap``. +- Any data accessed via :func:`esp_spi_flash_mmap`. - The software bootloader image when it is read by the ROM bootloader. **IMPORTANT: The MMU flash cache unconditionally decrypts all data. Data which is stored unencrypted in the flash will be "transparently decrypted" via the flash cache and appear to software like random garbage.** -To read data without using a flash cache MMU mapping, we recommend using the partition read function ``esp_partition_read``. When using this function, data will only be decrypted when it is read from an encrypted partition. Other partitions will be read unencrypted. In this way, software can access encrypted and non-encrypted flash in the same way. +Reading Encrypted Flash +^^^^^^^^^^^^^^^^^^^^^^^ +To read data without using a flash cache MMU mapping, we recommend using the partition read function :func:`esp_partition_read`. When using this function, data will only be decrypted when it is read from an encrypted partition. Other partitions will be read unencrypted. In this way, software can access encrypted and non-encrypted flash in the same way. Data which is read via other SPI read APIs are not decrypted: -- Data read via ``esp_spi_flash_read`` is not decrypted -- Data read via ROM function ``SPIRead`` is not decrypted (this function is not supported in esp-idf apps). -- Data stored using the Non-Volatile Storage (NVS) API is always stored decrypted. +- Data read via :func:`esp_spi_flash_read` is not decrypted +- Data read via ROM function :func:`SPIRead` is not decrypted (this function is not supported in esp-idf apps). +- Data stored using the Non-Volatile Storage (NVS) API is always stored and read decrypted. Writing Encrypted Flash @@ -92,92 +110,179 @@ The ``esp_spi_flash_write`` function will write data when the write_encrypted pa The ROM function ``SPI_Encrypt_Write`` will write encrypted data to flash, the ROM function ``SPIWrite`` will write unencrypted to flash. (these function are not supported in esp-idf apps). -The minimum write size for unencrypted data is 4 bytes (and the alignment is 4 bytes). Because data is encrypted in blocks, the minimum write size for encrypted data is 32 bytes (and the alignment is 32 bytes.) +The minimum write size for unencrypted data is 4 bytes (and the alignment is 4 bytes). Because data is encrypted in blocks, the minimum write size for encrypted data is 16 bytes (and the alignment is 16 bytes.) + +.. _updating-encrypted-flash: Updating Encrypted Flash ------------------------ +.. _updating-encrypted-flash-ota: + OTA Updates ^^^^^^^^^^^ OTA updates to encrypted partitions will automatically write encrypted, as long as the ``esp_partition_write`` function is used. +.. _updating-encrypted-flash-serial: + Serial Flashing ^^^^^^^^^^^^^^^ -Provided secure boot is not used, the ``FLASH_CRYPT_CNT`` registers allow the flash to be updated with new plaintext data via serial flashing (or other physical methods), up to 3 additional times. ``FLASH_CRYPT_CNT`` efuse is an 8-bit value, and the flash encryption enables or disables based on the number of bits which are set to "1": +Provided secure boot is not used, the :ref:`FLASH_CRYPT_CNT` allows the flash to be updated with new plaintext data via serial flashing (or other physical methods), up to 3 additional times. -- Even number (0-6) bits are set: Transparent reading of encrypted flash is disabled, any encrypted data cannot be decrypted. If the bootloader was built with "Enable flash encryption on boot" then it will see this situation and immediately re-encrypt the flash wherever it finds unencrypted data. Once done, it sets another bit in the efuse to '1' meaning an odd number of bits are now set. - -- Odd number (1-7) bits are set: Transparent reading of encrypted flash is enabled. - -- All 8 bits are set (valuye 0: Transparent reading of encrypted flash is disabled, any encrypted data is inaccessible. Bootloader will normally detect this condition and halt. To avoid use of this state to load unauthorised code, secure boot must be used or ``FLASH_CRYPT_CNT`` must be write-protected. - -The espefuse.py tool can be used to manually change the number of bits set in ``FLASH_CRYPT_CNT``, via serial bootloader. +The process involves flashing plaintext data, and then bumping the value of :ref:`FLASH_CRYPT_CNT` which causes the bootloader to re-encrypt this data. Limited Updates -^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~ -Only 4 physical flash updates (writing plaintext data which is then encrypted) are possible: +Only 4 serial flash update cycles of this kind are possible, including the initial encrypted flash. -1. On first plaintext boot, bit count has brand new value 0 and bootloader changes to 1 (0x01) following encryption. -2. On next plaintext flash update, bit count is manually updated to 2 (0x03) and bootloader changes to 4 (0x07) following encryption. -3. Then bit count is manually updated to 4 (0x0F) and the bootloader changes efuse bit count to 5 (0x1F). -4. Finally bootloader is manually updated to 6 (0x3F) and bootloader changes efuse bit count to 7 (0x7F). +After the fourth time encryption is disabled, :ref:`FLASH_CRYPT_CNT` has the maximum value `0xFF` and encryption is permanently disabled. -Cautions With Re-Flashing -^^^^^^^^^^^^^^^^^^^^^^^^^^ +Using :ref:`updating-encrypted-flash-ota` or :ref:`pregenerated-flash-encryption-key` allows you to exceed this limit. -- When reflashing via serial, reflash every partition that was previously written with plaintext (including bootloader). It is possible to skip app partitions which are not the "currently selected" OTA partition (these will not be re-encrypted unless a plaintext app image is found there.) However any partition marked with the "encrypt" flag will be unconditionally re-encrypted, meaning that any already encrypted data will be encrypted twice and corrupted. +Cautions With Serial Flashing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- If secure boot is enabled, you can't reflash via serial at all unless you used chosen the "Reflashable" option for Secure Boot, pre-generated a key and burned it to the ESP32. In this case you can re-flash a plaintext secure boot digest and bootloader image at offset 0 (see `Secure Boot` documentation.) In production secure boot configuration, the secure boot digest is stored encrypted - so if ``FLASH_CRYPT_CNT`` is set to an even value then the ROM bootloader will read the encrypted digest as-is and therefore will fail to verify any bootloader image as valid. +- When reflashing via serial, reflash every partition that was initially written with plaintext data (including bootloader). It is possible to skip app partitions which are not the "currently selected" OTA partition (these will not be re-encrypted unless a plaintext app image is found there.) However any partition marked with the "encrypt" flag will be unconditionally re-encrypted, meaning that any already encrypted data will be encrypted twice and corrupted. -Re-Flashing Procedure -^^^^^^^^^^^^^^^^^^^^^ + - Using ``make flash`` should flash all partitions which need to be flashed. -The steps to update a device with plaintext via UART bootloader, when flash encryption is enabled are: +- If secure boot is enabled, you can't reflash via serial at all unless you used the "Reflashable" option for Secure Boot, pre-generated a key and burned it to the ESP32 (refer to :doc:`Secure Boot ` docs.). In this case you can re-flash a plaintext secure boot digest and bootloader image at offset 0x0. It is necessary to re-flash this digest before flashing other plaintext data. + +Serial Re-Flashing Procedure +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Build the application as usual. -- Burn the ``FLASH_CRYPT_CNT`` efuse by running the command ``espefuse.py burn_efuse FLASH_CRYPT_CNT``. espefuse.py will automatically increment the bit count by 1. +- Flash the device with plaintext data as usual (``make flash`` or ``esptool.py`` commands.) Flash all previously encrypted partitions, including the bootloader (see previous section). -- Flash the device with plaintext data as usual (``make flash`` or ``esptool.py`` commands.) Flash all previously encrypted partitions, including the bootloader. If secure boot is enabled, it must be enabled in "Reflashable" mode and a pre-generated key burned to the ESP32 - flash the bootloader-reflash-digest.bin file at offset 0x0. +- At this point, the device will fail to boot (message is ``flash read err, 1000``) because it expects to see an encrypted bootloader, but the bootloader is plaintext. -- Reset the device and it will re-encrypt plaintext partitions, burn the ``FLASH_CRYPT_CNT`` flag to re-enable encryption. +- Burn the :ref:`FLASH_CRYPT_CNT` by running the command ``espefuse.py burn_efuse FLASH_CRYPT_CNT``. espefuse.py will automatically increment the bit count by 1, which disables encryption. + +- Reset the device and it will re-encrypt plaintext partitions, then burn the :ref:`FLASH_CRYPT_CNT` again to re-enable encryption. -Disabling Updates -^^^^^^^^^^^^^^^^^ +Disabling Serial Updates +~~~~~~~~~~~~~~~~~~~~~~~~ -To prevent further plaintext updates via physical access, use espefuse.py to write protect the ``FLASH_CRYPT_CNT`` efuse after flash encryption has been enabled (ie after first boot is complete):: +To prevent further plaintext updates via serial, use espefuse.py to write protect the :ref:`FLASH_CRYPT_CNT` after flash encryption has been enabled (ie after first boot is complete):: - espefuse.py write_protect_efuse FLASH_CRYPT_CNT + espefuse.py --port PORT write_protect_efuse FLASH_CRYPT_CNT This prevents any further modifications to disable or re-enable flash encryption. +.. _pregenerated-flash-encryption-key: + +Reflashing via Pregenerated Flash Encryption Key +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is possible to pregenerate a flash encryption key on the host computer and burn it into the ESP32's efuse key block. This allows data to be pre-encrypted on the host and flashed to the ESP32 without needing a plaintext flash update. + +This is useful for development, because it removes the 4 time reflashing limit. It also allows reflashing with secure boot enabled, because the bootloader doesn't need to be reflashed each time. + +**IMPORTANT This method is intended to assist with development only, not for production devices. If pre-generating flash encryption for production, ensure the keys are generated from a high quality random number source and do not share the same flash encryption key across multiple devices.** + +Pregenerating a Flash Encryption Key +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Flash encryption keys are 32 bytes of random data. You can generate a random key with espsecure.py:: + + espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin + +(The randomness of this data is only as good as the OS and it's Python installation's random data source.) + +Alternatively, if you're using :doc:`secure boot ` and have a secure boot signing key then you can generate a deterministic SHA-256 digest of the secure boot private signing key and use this as the flash encryption key:: + + espsecure.py digest_private-key --keyfile secure_boot_signing_key.pem my_flash_encryption_key.bin + +(The same 32 bytes is used as the secure boot digest key if you enable :ref:`reflashable mode` for secure boot.) + +Generating the flash encryption key from the secure boot signing key in this way means that you only need to store one key file. However this method is **not at all suitable** for production devices. + +Burning Flash Encryption Key +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you have generated a flash encryption key, you need to burn it to the ESP32's efuse key block. **This must be done before first encrypted boot**, otherwise the ESP32 will generate a random key that software can't access or modify. + +To burn a key to the device (one time only):: + + espefuse.py --port PORT burn_key flash_encryption my_flash_encryption_key.bin + +First Flash with pregenerated key +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After flashing the key, follow the same steps as for default :ref:`flash-encryption-initialisation` and flash a plaintext image for the first boot. The bootloader will enable flash encryption using the pre-burned key and encrypt all partitions. + +Reflashing with pregenerated key +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After encryption is enabled on first boot, reflashing an encrypted image requires an additional manual step. This is where we pre-encrypt the data that we wish to update in flash. + +Suppose that this is the normal command used to flash plaintext data:: + + esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash 0x10000 build/my-app.bin + +Binary app image ``build/my-app.bin`` is written to offset ``0x10000``. This file name and offset need to be used to encrypt the data, as follows:: + + espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x10000 -o build/my-app-encrypted.bin build/my-app.bin + +This example command will encrypts ``my-app.bin`` using the supplied key, and produce an encrypted file ``my-app-encrypted.bin``. Be sure that the address argument matches the address where you plan to flash the binary. + +Then, flash the encrypted binary with esptool.py:: + + esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash 0x10000 build/my-app-encrypted.bin + +No further steps or efuse manipulation is necessary, because the data is already encrypted when we flash it. + +Disabling Flash Encryption +-------------------------- + +If you've accidentally enabled flash encryption for some reason, the next flash of plaintext data will soft-brick the ESP32 (the device will reboot continously, printing the error ``flash read err, 1000``). + +You can disable flash encryption again by writing :ref:`FLASH_CRYPT_CNT`: + +- First, run ``make menuconfig`` and uncheck "Enable flash encryption boot" under "Security Features". +- Exit menuconfig and save the new configuration. +- Run ``make menuconfig`` again and double-check you really disabled this option! *If this option is left enabled, the bootloader will immediately re-enable encryption when it boots*. +- Run ``make flash`` to build and flash a new bootloader and app, without flash encryption enabled. +- Run ``espefuse.py`` (in ``components/esptool_py/esptool``) to disable the :ref:`FLASH_CRYPT_CNT`):: + espefuse.py burn_efuse FLASH_CRYPT_CNT + +Reset the ESP32 and flash encryption should be disabled, the bootloader will boot as normal. + +.. _flash-encryption-limitations: + Limitations of Flash Encryption ------------------------------- Flash Encryption prevents plaintext readout of the encrypted flash, to protect firmware against unauthorised readout and modification. It is important to understand the limitations of the flash encryption system: -- Flash encryption is only as strong as the key. For this reason, we recommend keys are generated on the device during first boot (default behaviour). If generating keys off-device to burn with ``esp_efuse.py burn_key``, ensure they are generated from a quality random number source, kept secure, and never shared between devices. +- Flash encryption is only as strong as the key. For this reason, we recommend keys are generated on the device during first boot (default behaviour). If generating keys off-device (see :ref:`pregenerated-flash-encryption-key`), ensure proper procedure is followed. - Not all data is stored encrypted. If storing data on flash, check if the method you are using (library, API, etc.) supports flash encryption. -- Flash encryption does not prevent an attacker from understanding the high-level layout of the flash. This is because the same AES key is used for every two 16 byte AES blocks. When both adjacent 16 byte blocks contain identical content (such as empty or padding areas), these blocks will encrypt to produce matching pairs of encrypted blocks. This may allow an attacker to make high-level comparisons between encrypted devices (ie to tell if two devices are probably running the same firmware version). +- Flash encryption does not prevent an attacker from understanding the high-level layout of the flash. This is because the same AES key is used for every pair of adjacent 16 byte AES blocks. When these adjacent 16 byte blocks contain identical content (such as empty or padding areas), these blocks will encrypt to produce matching pairs of encrypted blocks. This may allow an attacker to make high-level comparisons between encrypted devices (ie to tell if two devices are probably running the same firmware version). -- For the same reason, an attacker can always guess when two adjacent 16 byte blocks (32 byte aligned) contain identical content. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). +- For the same reason, an attacker can always tell when a pair of adjacent 16 byte blocks (32 byte aligned) contain identical content. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). -- Flash encryption alone may not prevent an attacker from modifying the firmware of the device. Always use flash encryption in combination with Secure Boot. +- Flash encryption alone may not prevent an attacker from modifying the firmware of the device. To prevent unauthorised firmware from runningon the device, use flash encryption in combination with :doc:`Secure Boot `. +.. _flash-encryption-advanced-features: Flash Encryption Advanced Features ---------------------------------- +The following information is useful for advanced use of flash encryption: + Encrypted Partition Flag ^^^^^^^^^^^^^^^^^^^^^^^^ -In the `partition table` description CSV files, there is a field for flags. +Some partitions are encrypted by default. Otherwise, it is possible to mark any partition as requiring encryption: + +In the :doc:`partition table ` description CSV files, there is a field for flags. Usually left blank, if you write "encrypted" in this field then the partition will be marked as encrypted in the partition table, and data written here will be treated as encrypted (same as an app partition):: @@ -187,7 +292,7 @@ Usually left blank, if you write "encrypted" in this field then the partition wi factory, app, factory, 0x10000, 1M secret_data, 0x40, 0x01, 0x20000, 256K, encrypted -- None of the default partition formats have any encrypted data partitions. +- None of the default partition tables include any encrypted data partitions. - It is not necessary to mark "app" partitions as encrypted, they are always treated as encrypted. @@ -197,88 +302,70 @@ Usually left blank, if you write "encrypted" in this field then the partition wi - It is not possible to mark the ``nvs`` partition as encrypted. -Precalculated Flash Encryption Key -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is possible to pre-generate a flash encryption key on the host computer and burn it into the ESP32 efuse. This allows data to be per-encrypted on the host and flashed to the ESP32 without needing a plaintext flash update. - -This is useful for development, because it removes the 4 flash limit and allows reflashing with secure boot enabled. - -**IMPORTANT** This method is intended to assist with development only, not for production devices. If pre-generating flash encryption for production, ensure the keys are generated from a high quality random number source and do not share the same flash encryption key across multiple devices. - -Obtaining Flash Encryption Key -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Flash encryption keys are 32 bytes of random data. You can generate a random key with espsecure.py:: - - espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin - -(The randomness of this data is only as good as the OS and it's Python installation's random data source.) - -Alternatively, if you're using `secure boot` and have a secure boot signing key then you can generate a deterministic SHA-256 digest of the secure boot private key to use:: - - espsecure.py digest_private-key --keyfile secure_boot_signing_key.pem my_flash_encryption_key.bin - -The same key is used as the secure boot digest key if you enabled "Reflashable" mode for secure boot. - -This means you can always re-calculate the flash encryption key from the secure boot private signing key. This method is **not at all suitable** for production devices. - -Burning Flash Encryption Key -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Once you have generated a flash encryption key, you need to burn it to efuse on the device. This **must be done before first boot**, otherwise the ESP32 will generate a random key that software can't access. - -To burn a key to the device (possible one time only):: - - espefuse.py burn_key flash_encryption my_flash_encryption_key.bin - -First Flash -~~~~~~~~~~~ - -For the first flash, follow the same steps as for default `Flash Encryption Initialisation` and flash a plaintext image. The bootloader will enable flash encryption using the pre-burned key and encrypt all partitions. - -Reflashing -~~~~~~~~~~ - -To reflash an encrypted image requires an additional manual update step, to encrypt the data you wish to flash. - -Suppose that this is the normal flashing non-encrypted flashing step:: - - esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x10000 build/my-app.bin - -The data needs to be pre-encrypted with knowledge of the address (0x10000) and the binary file name:: - - espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x10000 -o build/my-app-encrypted.bin build/my-app.bin - -This step will encrypt ``my-app.bin`` using the supplied key, and produce an encrypted file ``my-app-encrypted.bin``. Be sure that the address argument matches the address where you plan to flash the binary. - -Then, flash the encrypted binary with esptool.py:: - - esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x10000 build/my-app-encrypted.bin +.. _uart-bootloader-encryption: Enabling UART Bootloader Encryption/Decryption ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -By default, on first boot the flash encryption process will burn efuses ``DISABLE_DL_ENCRYPT``, ``DISABLE_DL_DECRYPT`` and ``DISABLE_DL_CACHE``. +By default, on first boot the flash encryption process will burn efuses ``DISABLE_DL_ENCRYPT``, ``DISABLE_DL_DECRYPT`` and ``DISABLE_DL_CACHE``: - ``DISABLE_DL_ENCRYPT`` disables the flash encryption operations when running in UART bootloader boot mode. -- ``DISABLE_DL_DECRYPT`` disables transparent flash decryption when running in UART bootloader mode, even if ``FLASH_CRYPT_CNT`` is set to enable it in normal operation. +- ``DISABLE_DL_DECRYPT`` disables transparent flash decryption when running in UART bootloader mode, even if :ref:`FLASH_CRYPT_CNT` is set to enable it in normal operation. - ``DISABLE_DL_CACHE`` disables the entire MMU flash cache when running in UART bootloader mode. -It is possible to burn only some of these efuses, and write-protect the rest (with unset value 0) before the first boot, in order to preserve them:: +It is possible to burn only some of these efuses, and write-protect the rest (with unset value 0) before the first boot, in order to preserve them. For example:: - espefuse.py burn_efuse DISABLE_DL_DECRYPT - espefuse.py write_protect_efuse DISABLE_DL_ENCRYPT + espefuse.py --port PORT burn_efuse DISABLE_DL_DECRYPT + espefuse.py --port PORT write_protect_efuse DISABLE_DL_ENCRYPT -(Note that all 3 of these efuses are disabled via one write protect bit, so write protecting one will write protect all of them.) +(Note that all 3 of these efuses are disabled via one write protect bit, so write protecting one will write protect all of them. For this reason, it's necessary to set any bits before write-protecting.) -Write protecting these efuses when they are unset (0) is not currently useful, as ``esptool.py`` does not support flash encryption functions. +**IMPORTANT**: Write protecting these efuses to keep them unset is not currently very useful, as ``esptool.py`` does not support writing or reading encrypted flash. + +**IMPORTANT**: If ``DISABLE_DL_DECRYPT`` is left unset (0) this effectively makes flash encryption useless, as an attacker with physical access can use UART bootloader mode (with custom stub code) to read out the flash contents. + +.. _setting-flash-crypt-config: + +Setting FLASH_CRYPT_CONFIG +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``FLASH_CRYPT_CONFIG`` efuse determines the number of bits in the flash encryption key which are "tweaked" with the block offset. See :ref:`flash-encryption-algorithm` for details. + +First boot of the bootloader always sets this value to the maximum `0xF`. + +It is possible to write these efuse manually, and write protect it before first boot in order to select different tweak values. This is not recommended. + +It is strongly recommended to never write protect ``FLASH_CRYPT_CONFIG`` when it the value is zero. If this efuse is set to zero, no bits in the flash encryption key are tweaked and the flash encryption algorithm is equivalent to AES ECB mode. -However, note that write protecting ``DISABLE_DL_DECRYPT`` when it is unset (0) effectively makes flash encryption useless, as an attacker with physical access can use UART bootloader mode to read out the flash. Technical Details ----------------- +The following sections provide some reference information about the operation of flash encryption. + +.. _FLASH_CRYPT_CNT: + +FLASH_CRYPT_CNT efuse +^^^^^^^^^^^^^^^^^^^^^ + +``FLASH_CRYPT_CNT`` is an 8-bit efuse field which controls flash encryption. Flash encryption enables or disables based on the number of bits in this efuse which are set to "1": + +- When an even number of bits (0,2,4,6,8) are set: Flash encryption is disabled, any encrypted data cannot be decrypted. + + - If the bootloader was built with "Enable flash encryption on boot" then it will see this situation and immediately re-encrypt the flash wherever it finds unencrypted data. Once done, it sets another bit in the efuse to '1' meaning an odd number of bits are now set. + + 1. On first plaintext boot, bit count has brand new value 0 and bootloader changes it to bit count 1 (value 0x01) following encryption. + 2. After next plaintext flash update, bit count is manually updated to 2 (value 0x03). After re-encrypting the bootloader changes efuse bit count to 3 (value 0x07). + 3. After next plaintext flash, bit count is manually updated to 4 (value 0x0F). After re-encrypting the bootloader changes efuse bit count to 5 (value 0x1F). + 4. After final plaintext flash, bit count is manually updated to 6 (value 0x3F). After re-encrypting the bootloader changes efuse bit count to 7 (value 0x7F). + +- When an odd number of bits (1,3,5,7) are set: Transparent reading of encrypted flash is enabled. + +- After all 8 bits are set (efuse value 0xFF): Transparent reading of encrypted flash is disabled, any encrypted data is permanently inaccessible. Bootloader will normally detect this condition and halt. To avoid use of this state to load unauthorised code, secure boot must be used or :ref:`FLASH_CRYPT_CNT` must be write-protected. + + +.. _flash-encryption-algorithm: + Flash Encryption Algorithm ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -288,7 +375,7 @@ Flash Encryption Algorithm - The main flash encryption key is stored in efuse (BLK2) and by default is protected from further writes or software readout. -- Each 32 byte block is encrypted with a unique key which is derived from this main flash encryption key XORed with the offset of this block in the flash (a "key tweak"). +- Each 32 byte block (two adjacent 16 byte AES blocks) is encrypted with a unique key. The key is derived from the main flash encryption key in efuse, XORed with the offset of this block in the flash (a "key tweak"). - The specific tweak depends on the setting of ``FLASH_CRYPT_CONFIG`` efuse. This is a 4 bit efuse, where each bit enables XORing of a particular range of the key bits: @@ -297,24 +384,11 @@ Flash Encryption Algorithm - Bit 3, bits 132-194 of the key are XORed. - Bit 4, bits 195-256 of the key are XORed. - It is recommended that ``FLASH_CRYPT_CONFIG`` is always left to set the default value `0xF`, so that all key bits are XORed with the block offset. See `Setting FLASH_CRYPT_CONFIG` for details. + It is recommended that ``FLASH_CRYPT_CONFIG`` is always left to set the default value `0xF`, so that all key bits are XORed with the block offset. See :ref:`setting-flash-crypt-config` for details. - The high 19 bits of the block offset (bit 5 to bit 23) are XORed with the main flash encryption key. This range is chosen for two reasons: the maximum flash size is 16MB (24 bits), and each block is 32 bytes so the least significant 5 bits are always zero. -- There is a particular mapping from each of the 19 block offset bits to the 256 bits of the flash encryption key, to determine which bit is XORed with which. See the variable _FLASH_ENCRYPTION_TWEAK_PATTERN in espsecure.py for a list of these. +- There is a particular mapping from each of the 19 block offset bits to the 256 bits of the flash encryption key, to determine which bit is XORed with which. See the variable ``_FLASH_ENCRYPTION_TWEAK_PATTERN`` in the espsecure.py source code for the complete mapping. -- For the full algorithm implemented in Python, see `_flash_encryption_operation()` in the espsecure.py source code. +- To see the full flash encryption algorithm implemented in Python, refer to the `_flash_encryption_operation()` function in the espsecure.py source code. -Setting FLASH_CRYPT_CONFIG -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``FLASH_CRYPT_CONFIG`` efuse determines the number of bits in the flash encryption key which are "tweaked" with the block offset. See `Flash Encryption Algorithm` for details. - -First boot of the bootloader always sets this value to the maximum `0xF`. - -It is possible to write these efuse manually, and write protect it before first boot in order to select different tweak values. This is not recommended. - -It is strongly recommended to never write protect ``FLASH_CRYPT_CONFIG`` when it the value is zero. If this efuse is set to zero, no bits in the flash encryption key are tweaked and the flash encryption algorithm is equivalent to AES ECB mode. - -.. _Secure Boot: secure-boot.rst -.. _partition table: ../partition-tables.rst diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst index 3c247d4a46..f90141a5ea 100644 --- a/docs/security/secure-boot.rst +++ b/docs/security/secure-boot.rst @@ -3,7 +3,9 @@ Secure Boot Secure Boot is a feature for ensuring only your code can run on the chip. Data loaded from flash is verified on each reset. -Secure Boot is separate from the `Flash Encryption` feature, and you can use secure boot without encrypting the flash contents. However we recommend using both features together for a secure environment. +Secure Boot is separate from the :doc:`Flash Encryption ` feature, and you can use secure boot without encrypting the flash contents. However we recommend using both features together for a secure environment. + +**IMPORTANT: Enabling secure boot limits your options for further updates of your ESP32. Make sure to read this document throughly and understand the implications of enabling secure boot.** Background ---------- @@ -19,7 +21,7 @@ Background Secure Boot Process Overview ---------------------------- -This is a high level overview of the secure boot process. Step by step instructions are supplied under `How To Enable Secure Boot`. Further in-depth details are supplied under `Technical Details`: +This is a high level overview of the secure boot process. Step by step instructions are supplied under :ref:`secure-boot-howto`. Further in-depth details are supplied under :ref:`secure-boot-technical-details`: 1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Secure Boot Configuration". @@ -34,7 +36,7 @@ This is a high level overview of the secure boot process. Step by step instructi - Depending on Secure Boot Configuration, efuses are burned to disable JTAG and the ROM BASIC interpreter (it is strongly recommended these options are turned on.) - Bootloader permanently enables secure boot by burning the ABS_DONE_0 efuse. The software bootloader then becomes protected (the chip will only boot a bootloader image if the digest matches.) -5. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. The digest and comparison are performed entirely by hardware, and the calculated digest is not readable by software. For technical details see `Hardware Secure Boot Support`. +5. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. The digest and comparison are performed entirely by hardware, and the calculated digest is not readable by software. For technical details see :ref:`secure-boot-hardware-support`. 6. When running in secure boot mode, the software bootloader uses the secure boot signing key (the public key of which is embedded in the bootloader itself, and therefore validated as part of the bootloader) to verify the signature appended to all subsequent partition tables and app images before they are booted. @@ -43,19 +45,20 @@ Keys The following keys are used by the secure boot process: -- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from the internal hardware random number generator, the user does not need to supply it (it is optionally possible to supply this key, see `Re-Flashable Software Bootloader`). The Efuse holding this key is read & write protected (preventing software access) before secure boot is enabled. +- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from the internal hardware random number generator, the user does not need to supply it (it is optionally possible to supply this key, see :ref:`secure-boot-reflashable`). The Efuse holding this key is read & write protected (preventing software access) before secure boot is enabled. -- "secure boot signing key" is a standard ECDSA public/private key pair (see `Image Signing Algorithm`) in PEM format. +- "secure boot signing key" is a standard ECDSA public/private key pair (see :ref:`secure-boot-image-signing-algorithm`) in PEM format. - The public key from this key pair (for signature verificaton but not signature creation) is compiled into the software bootloader and used to verify the second stage of booting (partition table, app image) before booting continues. The public key can be freely distributed, it does not need to be kept secret. - The private key from this key pair *must be securely kept private*, as anyone who has this key can authenticate to any bootloader that is configured with secure boot and the matching public key. +.. _secure-boot-howto: How To Enable Secure Boot ------------------------- -1. Run ``make menuconfig``, navigate to "Secure Boot Configuration" and select the option "One-time Flash". (To understand the alternative "Reflashable" choice, see `Re-Flashable Software Bootloader`.) +1. Run ``make menuconfig``, navigate to "Secure Boot Configuration" and select the option "One-time Flash". (To understand the alternative "Reflashable" choice, see :ref:`secure-boot-reflashable`.) 2. Select a name for the secure boot signing key. This option will appear after secure boot is enabled. The file can be anywhere on your system. A relative path will be evaluated from the project directory. The file does not need to exist yet. @@ -65,22 +68,26 @@ How To Enable Secure Boot **IMPORTANT** A signing key generated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. - **IMPORTANT** For production environments, we recommend generating the keypair using openssl or another industry standard encryption program. See `Generating Secure Boot Signing Key` for more details. + **IMPORTANT** For production environments, we recommend generating the keypair using openssl or another industry standard encryption program. See :ref:`secure-boot-generate-key` for more details. -5. Run ``make bootloader`` to build a secure boot enabled bootloader. The output of `make` will include a prompt for a flashing command, using `esptool.py write_flash`. +5. Run ``make bootloader`` to build a secure boot enabled bootloader. The output of ``make`` will include a prompt for a flashing command, using ``esptool.py write_flash``. + +.. _secure-boot-resume-normal-flashing: 6. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by make) and then wait for flashing to complete. **Remember this is a one time flash, you can't change the bootloader after this!**. -7. Run `make flash` to build and flash the partition table and the just-built app image. The app image will be signed using the signing key you generated in step 4. +7. Run ``make flash`` to build and flash the partition table and the just-built app image. The app image will be signed using the signing key you generated in step 4. - *NOTE*: `make flash` doesn't flash the bootloader if secure boot is enabled. + *NOTE*: ``make flash`` doesn't flash the bootloader if secure boot is enabled. 8. Reset the ESP32 and it will boot the software bootloader you flashed. The software bootloader will enable secure boot on the chip, and then it verifies the app image signature and boots the app. You should watch the serial console output from the ESP32 to verify that secure boot is enabled and no errors have occured due to the build configuration. -*NOTE* Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. +**NOTE** Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. 9. On subsequent boots, the secure boot hardware will verify the software bootloader has not changed (using the secure bootloader key) and then the software bootloader will verify the signed partition table and app image (using the public key portion of the secure boot signing key). +.. _secure-boot-reflashable: + Re-Flashable Software Bootloader -------------------------------- @@ -90,7 +97,7 @@ However, an alternative mode "Secure Boot: Reflashable" is also available. This In the esp-idf build process, this 256-bit key file is derived from the app signing key generated during the generate_signing_key step above. The private key's SHA-256 digest is used as the 256-bit secure bootloader key. This is a convenience so you only need to generate/protect a single private key. -*NOTE*: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. The "One-Time Flash" option is recommended for production environments. +**NOTE**: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. The "One-Time Flash" option is recommended for production environments. To enable a reflashable bootloader: @@ -100,7 +107,9 @@ To enable a reflashable bootloader: 3. Run ``make bootloader``. A 256-bit key file will be created, derived from the private key that is used for signing. Two sets of flashing steps will be printed - the first set of steps includes an ``espefuse.py burn_key`` command which is used to write the bootloader key to efuse. (Flashing this key is a one-time-only process.) The second set of steps can be used to reflash the bootloader with a pre-calculated digest (generated during the build process). -4. Resume from `Step 6` of the one-time process, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. +4. Resume from :ref:`Step 6 of the one-time flashing process `, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. + +.. _secure-boot-generate-key: Generating Secure Boot Signing Key ---------------------------------- @@ -134,7 +143,7 @@ After the app image and partition table are built, the build system will print s espsecure.py sign_data --keyfile PRIVATE_SIGNING_KEY BINARY_FILE -The above command appends the image signature to the existing binary. You can use the --output argument to place the binary with signature appended into a separate file:: +The above command appends the image signature to the existing binary. You can use the `--output` argument to write the signed binary to a separate file:: espsecure.py sign_data --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE @@ -145,16 +154,21 @@ Secure Boot Best Practices * Keep the signing key private at all times. A leak of this key will compromise the secure boot system. * Do not allow any third party to observe any aspects of the key generation or signing process using espsecure.py. Both processes are vulnerable to timing or other side-channel attacks. * Enable all secure boot options in the Secure Boot Configuration. These include flash encryption, disabling of JTAG, disabling BASIC ROM interpeter, and disabling the UART bootloader encrypted flash access. +* Use secure boot in combination with :doc:`flash encryption` to prevent local readout of the flash contents. + +.. _secure-boot-technical-details: Technical Details ----------------- -The following sections contain low-level descriptions of various technical functions: +The following sections contain low-level reference descriptions of various secure boot elements: -Hardware Secure Boot Support +.. _secure-boot-hardware-support: + +Secure Boot Hardware Support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The Secure Boot support hardware can perform three basic operations: +The first stage of secure boot verification (checking the software bootloader) is done via hardware. The ESP32's Secure Boot support hardware can perform three basic operations: 1. Generate a random sequence of bytes from a hardware random number generator. @@ -167,7 +181,7 @@ Secure Bootloader Digest Algorithm Starting with an "image" of binary data as input, this algorithm generates a digest as output. The digest is sometimes referred to as an "abstract" in hardware documentation. -For a Python version of this algorithm, see the `espsecure.py` tool in the components/esptool_py directory. +For a Python version of this algorithm, see the ``espsecure.py`` tool in the components/esptool_py directory (specifically, the ``digest_secure_bootloader`` command). Items marked with (^) are to fulfill hardware restrictions, as opposed to cryptographic restrictions. @@ -183,23 +197,27 @@ Items marked with (^) are to fulfill hardware restrictions, as opposed to crypto Output digest is 192 bytes of data: The 128 byte IV, followed by the 64 byte SHA-512 digest. +.. _secure-boot-image-signing-algorithm: + Image Signing Algorithm ~~~~~~~~~~~~~~~~~~~~~~~ -Deterministic ECDSA as specified by `RFC6979`. +Deterministic ECDSA as specified by `RFC 6979 `_. - Curve is NIST256p (openssl calls this curve "prime256v1", it is also sometimes called secp256r1). - Hash function is SHA256. - Key format used for storage is PEM. + - In the bootloader, the public key (for signature verification) is flashed as 64 raw bytes. + - Image signature is 68 bytes - a 4 byte version word (currently zero), followed by a 64 bytes of signature data. These 68 bytes are appended to an app image or partition table data. Manual Commands ~~~~~~~~~~~~~~~ -Secure boot is integrated into the esp-idf build system, so `make` will automatically sign an app image if secure boot is enabled. `make bootloader` will produce a bootloader digest if menuconfig is configured for it. +Secure boot is integrated into the esp-idf build system, so ``make`` will automatically sign an app image if secure boot is enabled. ``make bootloader`` will produce a bootloader digest if menuconfig is configured for it. -However, it is possible to use the `espsecure.py` tool to make standalone signatures and digests. +However, it is possible to use the ``espsecure.py`` tool to make standalone signatures and digests. To sign a binary image:: @@ -215,5 +233,3 @@ Keyfile is the 32 byte raw secure boot key for the device. To flash this digest esptool.py write_flash 0x0 bootloader-digest.bin -.. _RFC6979: https://tools.ietf.org/html/rfc6979 -.. _Flash Encryption: flash-encryption.rst From 0eb5c06ad4f3ab77adb5cff2dff0761ff818b56b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 14 Feb 2017 12:56:13 +1100 Subject: [PATCH 105/139] README: Add some tips on using menuconfig --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index cae4646309..312817b3a5 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,16 @@ Once you've found the project you want to work with, change to its directory and `make menuconfig` +* Opens a text-based configuration menu for the project. +* Use up & down arrow keys to navigate the menu. +* Use Enter key to go into a submenu, Escape key to go out or to exit. +* Type `?` to see a help screen. Enter key exits the help screen. +* Use Space key, or `Y` and `N` keys to enable (Yes) and disable (No) configuration items with checkboxes "`[*]`" +* Pressing `?` while highlighting a configuration item displays help about that item. +* Type `/` to search the configuration items. + +Once done configuring, press Escape multiple times to exit and say "Yes" to save the new configuration when prompted. + ## Compiling the Project `make all` From 4c9fdb7c5242f00a27971f758ae832203f06a805 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 14 Feb 2017 12:56:51 +1100 Subject: [PATCH 106/139] Docs: Mark PDF links as such in the documentation index Nothing worse than clicking what you think is an internal page link and finding a PDF downloading! --- docs/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 488471dfe1..4beb326285 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -53,10 +53,10 @@ Contents: .. toctree:: :caption: Hardware Reference - Technical Reference Manual - Pin List and Functions - Chip Pinout - Silicon Errata + Technical Reference Manual (PDF) + Pin List and Functions (PDF) + Chip Pinout (PDF) + Silicon Errata (PDF) .. toctree:: :caption: Contribute @@ -78,4 +78,4 @@ Contents: Indices ======= -* :ref:`genindex` \ No newline at end of file +* :ref:`genindex` From 24cfe78962887b85f49c56eea8d7a9f127805900 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 15 Feb 2017 10:28:45 +1100 Subject: [PATCH 107/139] partition table: Fix comment at top of gen_esp32part.py --- components/partition_table/gen_esp32part.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index 6d6137f172..e4c999ab0f 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -4,7 +4,8 @@ # # Converts partition tables to/from CSV and binary formats. # -# See the sdkng README.md file for details about how to use this tool. +# See http://esp-idf.readthedocs.io/en/latest/partition-tables.html for explanation of +# partition table structure and uses. import argparse import os import re From 39c546d63f23725ab724d99ddcb3e2f31fbb89f8 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 15 Feb 2017 17:18:01 +1100 Subject: [PATCH 108/139] openssl_server example: Roll back to TLS_server_method() for compatibility Add a comment recommending TLS v1.2. --- examples/protocols/openssl_server/main/openssl_server.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/protocols/openssl_server/main/openssl_server.c b/examples/protocols/openssl_server/main/openssl_server.c index 7569124f7f..c74bb0e41f 100755 --- a/examples/protocols/openssl_server/main/openssl_server.c +++ b/examples/protocols/openssl_server/main/openssl_server.c @@ -71,7 +71,11 @@ static void openssl_demo_thread(void *p) const unsigned int prvtkey_pem_bytes = prvtkey_pem_end - prvtkey_pem_start; ESP_LOGI(TAG, "SSL server context create ......"); - ctx = SSL_CTX_new(TLSv1_2_server_method()); + /* For security reasons, it is best if you can use + TLSv1_2_server_method() here instead of TLS_server_method(). + However some old browsers may not support TLS v1.2. + */ + ctx = SSL_CTX_new(TLS_server_method()); if (!ctx) { ESP_LOGI(TAG, "failed"); goto failed1; From 9cea5ea0753be5f943ba00666ef5d108a592d5f4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 15 Feb 2017 18:04:28 +1100 Subject: [PATCH 109/139] fatfs: Add unit test for overwrite/append fix --- components/fatfs/test/test_fatfs.c | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/components/fatfs/test/test_fatfs.c b/components/fatfs/test/test_fatfs.c index c2331d6e26..4f6482740c 100644 --- a/components/fatfs/test/test_fatfs.c +++ b/components/fatfs/test/test_fatfs.c @@ -69,6 +69,55 @@ TEST_CASE("can create and write file on sd card", "[fatfs][ignore]") HEAP_SIZE_CHECK(0); } +TEST_CASE("overwrite and append file on sd card", "[fatfs][ignore]") +{ + HEAP_SIZE_CAPTURE(); + + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = true, + .max_files = 5 + }; + TEST_ESP_OK(esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, NULL)); + + /* Create new file with 'aaaa' */ + const char *NAME = "/sdcard/hello.txt"; + create_file_with_text(NAME, "aaaa"); + + /* Append 'bbbb' to file */ + FILE *f_a = fopen(NAME, "a"); + TEST_ASSERT_NOT_NULL(f_a); + TEST_ASSERT_NOT_EQUAL(EOF, fputs("bbbb", f_a)); + TEST_ASSERT_EQUAL(0, fclose(f_a)); + + /* Read back 8 bytes from file, verify it's 'aaaabbbb' */ + char buf[10] = { 0 }; + FILE *f_r = fopen(NAME, "r"); + TEST_ASSERT_NOT_NULL(f_r); + TEST_ASSERT_EQUAL(8, fread(buf, 1, 8, f_r)); + TEST_ASSERT_EQUAL_STRING_LEN("aaaabbbb", buf, 8); + + /* Be sure we're at end of file */ + TEST_ASSERT_EQUAL(0, fread(buf, 1, 8, f_r)); + + TEST_ASSERT_EQUAL(0, fclose(f_r)); + + /* Overwrite file with 'cccc' */ + create_file_with_text(NAME, "cccc"); + + /* Verify file now only contains 'cccc' */ + f_r = fopen(NAME, "r"); + TEST_ASSERT_NOT_NULL(f_r); + bzero(buf, sizeof(buf)); + TEST_ASSERT_EQUAL(4, fread(buf, 1, 8, f_r)); // trying to read 8 bytes, only expecting 4 + TEST_ASSERT_EQUAL_STRING_LEN("cccc", buf, 4); + TEST_ASSERT_EQUAL(0, fclose(f_r)); + + TEST_ESP_OK(esp_vfs_fat_sdmmc_unmount()); + HEAP_SIZE_CHECK(0); +} + TEST_CASE("can read file on sd card", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); From 5023e30a33f27a5b2b61a57dc073f6e261579996 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Wed, 15 Feb 2017 20:08:39 +0800 Subject: [PATCH 110/139] component/bt : fix gatt write memory leak --- components/bt/bluedroid/stack/gatt/gatt_sr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index 793ac1a9b0..2d34a05045 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -1073,9 +1073,11 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, GATTS_REQ_TYPE_WRITE, &sr_data); - if(status == GATT_SUCCESS){ + if (status == GATT_SUCCESS) { attp_send_sr_msg(p_tcb, p_msg); gatt_dequeue_sr_cmd(p_tcb); + } else { + GKI_freebuf(p_msg); } } else { From 6648ff427cfa41f23c232731bdd132272e961d43 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Thu, 16 Feb 2017 14:10:44 +0800 Subject: [PATCH 111/139] component/bt : fix connection bug of Iphone7 10.0.2 This connection error caused by iPhone, it think that TX data length must large than 27 when slave support EXTEND_DATA_LENGTH. But this should be allow. Besides, the problem cannot be found on higher version of Iphone7, apple seemed to have fixed it. Actually maybe other BLE device have the same problem. --- components/bt/bluedroid/device/controller.c | 4 ++++ components/bt/bluedroid/hci/hci_packet_factory.c | 12 ++++++++++++ .../bt/bluedroid/hci/include/hci_packet_factory.h | 1 + 3 files changed, 17 insertions(+) diff --git a/components/bt/bluedroid/device/controller.c b/components/bt/bluedroid/device/controller.c index c7fc98d6c8..08564052d8 100644 --- a/components/bt/bluedroid/device/controller.c +++ b/components/bt/bluedroid/device/controller.c @@ -221,6 +221,10 @@ static void start_up(void) } if (HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array)) { + /* set default tx data length to MAX 251 */ + response = AWAIT_COMMAND(packet_factory->make_ble_write_suggested_default_data_length(BTM_BLE_DATA_SIZE_MAX, BTM_BLE_DATA_TX_TIME_MAX)); + packet_parser->parse_generic_command_complete(response); + response = AWAIT_COMMAND(packet_factory->make_ble_read_suggested_default_data_length()); packet_parser->parse_ble_read_suggested_default_data_length_response( response, diff --git a/components/bt/bluedroid/hci/hci_packet_factory.c b/components/bt/bluedroid/hci/hci_packet_factory.c index 6d5592b758..c4bb96b162 100644 --- a/components/bt/bluedroid/hci/hci_packet_factory.c +++ b/components/bt/bluedroid/hci/hci_packet_factory.c @@ -154,6 +154,17 @@ static BT_HDR *make_ble_read_suggested_default_data_length(void) return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH); } +static BT_HDR *make_ble_write_suggested_default_data_length(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime) +{ + uint8_t *stream; + uint8_t parameter_size = sizeof(uint16_t) + sizeof(uint16_t); + BT_HDR *packet = make_command(HCI_BLE_WRITE_DEFAULT_DATA_LENGTH, parameter_size, &stream); + + UINT16_TO_STREAM(stream, SuggestedMaxTxOctets); + UINT16_TO_STREAM(stream, SuggestedMaxTxTime); + return packet; +} + static BT_HDR *make_ble_set_event_mask(const bt_event_mask_t *event_mask) { uint8_t *stream; @@ -215,6 +226,7 @@ static const hci_packet_factory_t interface = { make_ble_read_local_supported_features, make_ble_read_resolving_list_size, make_ble_read_suggested_default_data_length, + make_ble_write_suggested_default_data_length, make_ble_set_event_mask }; diff --git a/components/bt/bluedroid/hci/include/hci_packet_factory.h b/components/bt/bluedroid/hci/include/hci_packet_factory.h index 879962c2fc..11f0053a58 100644 --- a/components/bt/bluedroid/hci/include/hci_packet_factory.h +++ b/components/bt/bluedroid/hci/include/hci_packet_factory.h @@ -40,6 +40,7 @@ typedef struct { BT_HDR *(*make_ble_read_local_supported_features)(void); BT_HDR *(*make_ble_read_resolving_list_size)(void); BT_HDR *(*make_ble_read_suggested_default_data_length)(void); + BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime); BT_HDR *(*make_ble_set_event_mask)(const bt_event_mask_t *event_mask); } hci_packet_factory_t; From 2fc4413dae511d848757e4db5598d6134355011e Mon Sep 17 00:00:00 2001 From: shangke Date: Thu, 16 Feb 2017 14:36:46 +0800 Subject: [PATCH 112/139] ethernet: add pin macro --- examples/ethernet/ethernet/main/ethernet_main.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/ethernet/ethernet/main/ethernet_main.c b/examples/ethernet/ethernet/main/ethernet_main.c index 8cb9ca5e52..6419c41843 100644 --- a/examples/ethernet/ethernet/main/ethernet_main.c +++ b/examples/ethernet/ethernet/main/ethernet_main.c @@ -37,6 +37,9 @@ static const char *TAG = "eth_demo"; #define DEFAULT_PHY_CONFIG (AUTO_MDIX_ENABLE|AUTO_NEGOTIATION_ENABLE|AN_1|AN_0|LED_CFG) +#define PIN_PHY_POWER 17 +#define PIN_SMI_MDC 23 +#define PIN_SMI_MDIO 18 void phy_tlk110_check_phy_init(void) { @@ -89,12 +92,12 @@ void phy_enable_flow_ctrl(void) void phy_tlk110_power_enable(bool enable) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_GPIO17); - gpio_set_direction(17,GPIO_MODE_OUTPUT); + gpio_pad_select_gpio(PIN_PHY_POWER); + gpio_set_direction(PIN_PHY_POWER,GPIO_MODE_OUTPUT); if(enable == true) { - gpio_set_level(17, 1); + gpio_set_level(PIN_PHY_POWER, 1); } else { - gpio_set_level(17, 0); + gpio_set_level(PIN_PHY_POWER, 0); } } @@ -129,10 +132,10 @@ void eth_gpio_config_rmii(void) gpio_set_direction(0, GPIO_MODE_INPUT); //mdc to gpio23 - gpio_matrix_out(23, EMAC_MDC_O_IDX, 0, 0); + gpio_matrix_out(PIN_SMI_MDC, EMAC_MDC_O_IDX, 0, 0); //mdio to gpio18 - gpio_matrix_out(18, EMAC_MDO_O_IDX, 0, 0); - gpio_matrix_in(18, EMAC_MDI_I_IDX, 0); + gpio_matrix_out(PIN_SMI_MDIO, EMAC_MDO_O_IDX, 0, 0); + gpio_matrix_in(PIN_SMI_MDIO, EMAC_MDI_I_IDX, 0); } void eth_task(void *pvParameter) From eb14284c92a79ccbe41647600c565f162a1b78fb Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Thu, 16 Feb 2017 19:05:07 +0800 Subject: [PATCH 113/139] disable PHY and RF when stop WiFi and disable BT 1. Add disable PHY and RF when WiFi and BT are both disabled(including call sniffer disable API). 2. Do not init PHY and RF when cpu start. Init PHY and RF when call Wifi or BT start APIs(including sniffer enable API). 3. Add a temporary lib: librtc_clk.a and will delete it when CPU frequency switching function is done. 4. Add an function to get OS tick rate. 5. Do not put the whole pp.a in iram0, only put lmac.o, ieee80211_misc.o, ets_time.o and wdev.o in iram0. --- components/bootloader/src/main/component.mk | 2 +- components/bt/bluedroid/api/esp_bt_main.c | 4 + components/bt/bt.c | 5 + components/esp32/Kconfig | 15 --- components/esp32/component.mk | 2 +- components/esp32/cpu_start.c | 44 ------- components/esp32/include/esp_phy_init.h | 28 +++-- components/esp32/ld/esp32.common.ld | 6 +- components/esp32/lib | 2 +- components/esp32/phy_init.c | 108 +++++++++++++++--- components/esp32/rtc.h | 4 + .../freertos/include/freertos/portable.h | 3 + components/freertos/port.c | 4 +- 13 files changed, 139 insertions(+), 88 deletions(-) diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 73cd9287df..2069665d1a 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -18,6 +18,6 @@ ifdef IS_BOOTLOADER_BUILD # following lines are a workaround to link librtc into the # bootloader, until clock setting code is in a source-based esp-idf # component. See also rtc_printf() in bootloader_start.c -COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc +COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc_clk -lrtc COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/ endif diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index c9fe4fc060..f96cae1b3b 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -21,6 +21,8 @@ static bool esp_already_enable = false; static bool esp_already_init = false; +extern esp_err_t esp_phy_deinit(void); + esp_bluedroid_status_t esp_bluedroid_get_status(void) { if (esp_already_init) { @@ -164,6 +166,8 @@ esp_err_t esp_bluedroid_deinit(void) esp_already_init = false; + esp_phy_deinit(); + return ESP_OK; } diff --git a/components/bt/bt.c b/components/bt/bt.c index 5bad45ea2c..4378b4da6c 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -31,6 +31,8 @@ #if CONFIG_BT_ENABLED +extern void do_phy_init(void); + /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); extern void btdm_controller_init(void); @@ -145,6 +147,9 @@ void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) static void bt_controller_task(void *pvParam) { btdm_osi_funcs_register(&osi_funcs); + + do_phy_init(); + btdm_controller_init(); } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index db9bb2539f..5338e5f459 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -508,21 +508,6 @@ config PHY_ENABLED menu PHY visible if PHY_ENABLED -config ESP32_PHY_AUTO_INIT - bool "Initialize PHY in startup code" - depends on PHY_ENABLED - default y - help - If enabled, PHY will be initialized in startup code, before - app_main function runs. - If this is undesired, disable this option and call esp_phy_init - from the application before enabling WiFi or BT. - - If this option is enabled, startup code will also initialize - NVS prior to initializing PHY. - - If unsure, choose 'y'. - config ESP32_PHY_INIT_DATA_IN_PARTITION bool "Use a partition to store PHY init data" depends on PHY_ENABLED diff --git a/components/esp32/component.mk b/components/esp32/component.mk index a8109a0f5e..e7a88571ff 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -3,7 +3,7 @@ # COMPONENT_SRCDIRS := . hwcrypto -LIBS := core rtc +LIBS := core rtc rtc_clk ifdef CONFIG_PHY_ENABLED # BT || WIFI LIBS += phy coexist endif diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 5278f9b166..bc7ed6a71c 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -73,9 +73,6 @@ static bool app_cpu_started = false; static void do_global_ctors(void); static void main_task(void* args); extern void app_main(void); -#if CONFIG_ESP32_PHY_AUTO_INIT -static void do_phy_init(); -#endif extern int _bss_start; extern int _bss_end; @@ -214,11 +211,6 @@ void start_cpu0_default(void) esp_core_dump_init(); #endif -#if CONFIG_ESP32_PHY_AUTO_INIT - nvs_flash_init(); - do_phy_init(); -#endif - #if CONFIG_SW_COEXIST_ENABLE if (coex_init() == ESP_OK) { coexist_set_enable(true); @@ -268,39 +260,3 @@ static void main_task(void* args) vTaskDelete(NULL); } -#if CONFIG_ESP32_PHY_AUTO_INIT -static void do_phy_init() -{ - esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; - if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) { - calibration_mode = PHY_RF_CAL_NONE; - } - const esp_phy_init_data_t* init_data = esp_phy_get_init_data(); - if (init_data == NULL) { - ESP_LOGE(TAG, "failed to obtain PHY init data"); - abort(); - } - esp_phy_calibration_data_t* cal_data = - (esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1); - if (cal_data == NULL) { - ESP_LOGE(TAG, "failed to allocate memory for RF calibration data"); - abort(); - } - esp_err_t err = esp_phy_load_cal_data_from_nvs(cal_data); - if (err != ESP_OK) { - ESP_LOGW(TAG, "failed to load RF calibration data, falling back to full calibration"); - calibration_mode = PHY_RF_CAL_FULL; - } - - esp_phy_init(init_data, calibration_mode, cal_data); - - if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) { - err = esp_phy_store_cal_data_to_nvs(cal_data); - } else { - err = ESP_OK; - } - esp_phy_release_init_data(init_data); - free(cal_data); // PHY maintains a copy of calibration data, so we can free this -} -#endif //CONFIG_ESP32_PHY_AUTO_INIT - diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index e669a44151..55ce145e9d 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -223,25 +223,31 @@ esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_da * @brief Initialize PHY module * * PHY module should be initialized in order to use WiFi or BT. - * If "Initialize PHY in startup code" option is set in menuconfig, - * this function will be called automatically before app_main is called, - * using parameters obtained from esp_phy_get_init_data. - * - * Applications which don't need to enable PHY on every start up should - * disable this menuconfig option and call esp_phy_init before calling - * esp_wifi_init or esp_bt_controller_init. See do_phy_init function in - * cpu_start.c for an example of using this function. + * Now PHY initializing job is done automatically when start WiFi or BT. Users should not + * call this API in their application. * * @param init_data PHY parameters. Default set of parameters can * be obtained by calling esp_phy_get_default_init_data * function. * @param mode Calibration mode (Full, partial, or no calibration) * @param[inout] calibration_data + * @param WiFi is_Waked up from sleep or not + * @return ESP_OK on success. + * @return ESP_FAIL on fail. + */ +esp_err_t esp_phy_init(const void* init_data, + int mode, void* calibration_data, bool is_sleep); + +/** + * @brief De-initialize PHY module + * + * PHY module should be de-initialized in order to shutdown WiFi or BT. + * Now PHY de-initializing job is done automatically when stop WiFi or BT. Users should not + * call this API in their application. + * * @return ESP_OK on success. */ -esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data, - esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data); - +esp_err_t esp_phy_deinit(void); #ifdef __cplusplus } diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index ac04c07d57..43775a6c49 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -83,7 +83,11 @@ SECTIONS *libesp32.a:core_dump.o(.literal .text .literal.* .text.*) *libphy.a:(.literal .text .literal.* .text.*) *librtc.a:(.literal .text .literal.* .text.*) - *libpp.a:(.literal .text .literal.* .text.*) + *librtc_clk.a:(.literal .text .literal.* .text.*) + *libpp.a:lmac.o(.literal .text .literal.* .text.*) + *libpp.a:wdev.o(.literal .text .literal.* .text.*) + *libcore.a:ets_timer.o(.literal .text .literal.* .text.*) + *libnet80211.a:ieee80211_misc.o(.literal .text .literal.* .text.*) *libhal.a:(.literal .text .literal.* .text.*) *libcoexist.a:(.literal .text .literal.* .text.*) _iram_text_end = ABSOLUTE(.); diff --git a/components/esp32/lib b/components/esp32/lib index 1627461bf2..c0d9420360 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 1627461bf2fc2ec8a090b30cddae2118d542c454 +Subproject commit c0d94203602f7dd3d755bb1180a1640c3715c3ae diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 5b130eaf7a..6026da6acd 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -17,7 +17,14 @@ #include #include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/xtensa_api.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" + #include "rom/ets_sys.h" +#include "rom/rtc.h" #include "soc/dport_reg.h" #include "esp_err.h" @@ -25,30 +32,70 @@ #include "esp_system.h" #include "esp_log.h" #include "nvs.h" +#include "nvs_flash.h" #include "sdkconfig.h" #ifdef CONFIG_PHY_ENABLED #include "phy.h" #include "phy_init_data.h" +#include "rtc.h" static const char* TAG = "phy_init"; +/* Count value to indicate if there is peripheral that has initialized PHY and RF */ +int g_phy_rf_init_count = 0; -esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data, - esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data) +static xSemaphoreHandle g_phy_rf_init_mux = NULL; + +esp_err_t esp_phy_init(const void* init_data, + int mode, void* calibration_data, bool is_sleep) { - assert(init_data); - assert(calibration_data); + esp_phy_init_data_t* data = (esp_phy_init_data_t *)init_data; + esp_phy_calibration_mode_t cal_mode = (esp_phy_calibration_mode_t)mode; + esp_phy_calibration_data_t* cal_data = (esp_phy_calibration_data_t *)calibration_data; - REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); - REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); - // Enable WiFi peripheral clock - SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); - ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d", - init_data, calibration_data, mode); - phy_set_wifi_mode_only(0); - register_chipv7_phy(init_data, calibration_data, mode); - coex_bt_high_prio(); + assert((g_phy_rf_init_count <= 1) && (g_phy_rf_init_count >= 0)); + + if (g_phy_rf_init_mux == NULL) { + g_phy_rf_init_mux = xSemaphoreCreateMutex(); + if (g_phy_rf_init_mux == NULL) { + ESP_LOGE(TAG, "Create PHY RF mutex fail"); + return ESP_FAIL; + } + } + + xSemaphoreTake(g_phy_rf_init_mux, portMAX_DELAY); + if (g_phy_rf_init_count == 0) { + if (is_sleep == false) { + REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); + REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); + } + // Enable WiFi peripheral clock + SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); + ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d", + init_data, calibration_data, mode); + phy_set_wifi_mode_only(0); + register_chipv7_phy(data, cal_data, cal_mode); + coex_bt_high_prio(); + } + g_phy_rf_init_count++; + xSemaphoreGive(g_phy_rf_init_mux); + return ESP_OK; +} + +esp_err_t esp_phy_deinit(void) +{ + assert((g_phy_rf_init_count <= 2) && (g_phy_rf_init_count >= 1)); + + xSemaphoreTake(g_phy_rf_init_mux, portMAX_DELAY); + if (g_phy_rf_init_count == 1) { + // Disable PHY and RF. This is a teporary function. + pm_close_rf(); + // Disable WiFi peripheral clock + CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); + } + g_phy_rf_init_count--; + xSemaphoreGive(g_phy_rf_init_mux); return ESP_OK; } @@ -220,4 +267,39 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, return err; } +void do_phy_init(void) +{ + esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; + nvs_flash_init(); + if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) { + calibration_mode = PHY_RF_CAL_NONE; + } + const esp_phy_init_data_t* init_data = esp_phy_get_init_data(); + if (init_data == NULL) { + ESP_LOGE(TAG, "failed to obtain PHY init data"); + abort(); + } + esp_phy_calibration_data_t* cal_data = + (esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1); + if (cal_data == NULL) { + ESP_LOGE(TAG, "failed to allocate memory for RF calibration data"); + abort(); + } + esp_err_t err = esp_phy_load_cal_data_from_nvs(cal_data); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to load RF calibration data, falling back to full calibration"); + calibration_mode = PHY_RF_CAL_FULL; + } + + esp_phy_init(init_data, calibration_mode, cal_data, false); + + if (calibration_mode != PHY_RF_CAL_NONE) { + err = esp_phy_store_cal_data_to_nvs(cal_data); + } else { + err = ESP_OK; + } + esp_phy_release_init_data(init_data); + free(cal_data); // PHY maintains a copy of calibration data, so we can free this +} + #endif // CONFIG_PHY_ENABLED diff --git a/components/esp32/rtc.h b/components/esp32/rtc.h index e1cf33522d..48272259fa 100644 --- a/components/esp32/rtc.h +++ b/components/esp32/rtc.h @@ -135,6 +135,10 @@ void rtc_slp_prep_lite(uint32_t deep_slp, uint32_t cpu_lp_mode); */ uint32_t rtc_sleep(uint32_t cycles_h, uint32_t cycles_l, uint32_t wakeup_opt, uint32_t reject_opt); +/** + * @brief Shutdown PHY and RF. This is a temporary function. + */ +void pm_close_rf(void); #ifdef __cplusplus } diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index b05755da40..0c10ac36eb 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -216,6 +216,9 @@ static inline uint32_t xPortGetCoreID() { return id; } +/* Get tick rate per second */ +uint32_t xPortGetTickRateHz(void); + #ifdef __cplusplus } #endif diff --git a/components/freertos/port.c b/components/freertos/port.c index c778950d6d..ba4da3e284 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -406,7 +406,9 @@ void vPortSetStackWatchpoint( void* pxStackStart ) { esp_set_watchpoint(1, (char*)addr, 32, ESP_WATCHPOINT_STORE); } - +uint32_t xPortGetTickRateHz(void) { + return (uint32_t)configTICK_RATE_HZ; +} From cd13c9e95d24724aac77a40270546e1c8fd04822 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Thu, 16 Feb 2017 22:06:02 +0800 Subject: [PATCH 114/139] disable phy and rf 1. add a macro in menuconfig for users to choose whether store phy calibration data into NVS or not. 2. rename some disable phy and rf APIs so that existing code which calls old APIS will fail to compile. --- components/bt/bluedroid/api/esp_bt_main.c | 5 +- components/bt/bt.c | 5 +- components/esp32/Kconfig | 10 +++ components/esp32/include/esp_phy_init.h | 25 +++++--- components/esp32/lib | 2 +- components/esp32/phy_init.c | 78 ++++++++++------------- components/freertos/port.c | 2 +- 7 files changed, 64 insertions(+), 63 deletions(-) diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index f96cae1b3b..612a9e020a 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -17,12 +17,11 @@ #include "btc_task.h" #include "btc_main.h" #include "future.h" +#include "esp_phy_init.h" static bool esp_already_enable = false; static bool esp_already_init = false; -extern esp_err_t esp_phy_deinit(void); - esp_bluedroid_status_t esp_bluedroid_get_status(void) { if (esp_already_init) { @@ -166,7 +165,7 @@ esp_err_t esp_bluedroid_deinit(void) esp_already_init = false; - esp_phy_deinit(); + esp_phy_rf_deinit(); return ESP_OK; } diff --git a/components/bt/bt.c b/components/bt/bt.c index 4378b4da6c..2390456afb 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -27,12 +27,11 @@ #include "esp_task.h" #include "esp_intr.h" #include "esp_attr.h" +#include "esp_phy_init.h" #include "bt.h" #if CONFIG_BT_ENABLED -extern void do_phy_init(void); - /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); extern void btdm_controller_init(void); @@ -148,7 +147,7 @@ static void bt_controller_task(void *pvParam) { btdm_osi_funcs_register(&osi_funcs); - do_phy_init(); + esp_phy_load_cal_and_init(); btdm_controller_init(); } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 5338e5f459..d3441fa017 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -507,6 +507,16 @@ config PHY_ENABLED menu PHY visible if PHY_ENABLED + +config ESP32_STORE_PHY_CAL_DATA_INTO_NVS + bool "Store PHY calibration data into NVS" + depends on PHY_ENABLED + default y + help + If this option is enabled, PHY initialization will also calibrate PHY data, and + store it into NVS. + + If unsure, choose 'y'. config ESP32_PHY_INIT_DATA_IN_PARTITION bool "Use a partition to store PHY init data" diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 55ce145e9d..5ad06ee896 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -192,7 +192,7 @@ void esp_phy_release_init_data(const esp_phy_init_data_t* data); * mechanism for loading calibration data, disable * "Initialize PHY in startup code" option in menuconfig and call esp_phy_init * function from the application. For an example usage of esp_phy_init and - * this function, see do_phy_init function in cpu_start.c + * this function, see esp_phy_store_cal_data_to_nvs function in cpu_start.c * * @param out_cal_data pointer to calibration data structure to be filled with * loaded data. @@ -220,10 +220,10 @@ esp_err_t esp_phy_load_cal_data_from_nvs(esp_phy_calibration_data_t* out_cal_dat esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_data); /** - * @brief Initialize PHY module + * @brief Initialize PHY and RF module * - * PHY module should be initialized in order to use WiFi or BT. - * Now PHY initializing job is done automatically when start WiFi or BT. Users should not + * PHY and RF module should be initialized in order to use WiFi or BT. + * Now PHY and RF initializing job is done automatically when start WiFi or BT. Users should not * call this API in their application. * * @param init_data PHY parameters. Default set of parameters can @@ -231,23 +231,28 @@ esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_da * function. * @param mode Calibration mode (Full, partial, or no calibration) * @param[inout] calibration_data - * @param WiFi is_Waked up from sleep or not + * @param is_sleep WiFi wakes up from sleep or not * @return ESP_OK on success. * @return ESP_FAIL on fail. */ -esp_err_t esp_phy_init(const void* init_data, - int mode, void* calibration_data, bool is_sleep); +esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, + esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data, bool is_sleep); /** - * @brief De-initialize PHY module + * @brief De-initialize PHY and RF module * * PHY module should be de-initialized in order to shutdown WiFi or BT. - * Now PHY de-initializing job is done automatically when stop WiFi or BT. Users should not + * Now PHY and RF de-initializing job is done automatically when stop WiFi or BT. Users should not * call this API in their application. * * @return ESP_OK on success. */ -esp_err_t esp_phy_deinit(void); +esp_err_t esp_phy_rf_deinit(void); + +/** + * @brief Load calibration data from NVS and initialize PHY and RF module + */ +void esp_phy_load_cal_and_init(void); #ifdef __cplusplus } diff --git a/components/esp32/lib b/components/esp32/lib index c0d9420360..bc16e8c074 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit c0d94203602f7dd3d755bb1180a1640c3715c3ae +Subproject commit bc16e8c0749adefcd5bf44c9024849a504b8e839 diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 6026da6acd..1c67a404ab 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -17,11 +17,7 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/xtensa_api.h" -#include "freertos/task.h" -#include "freertos/ringbuf.h" +#include #include "rom/ets_sys.h" #include "rom/rtc.h" @@ -43,59 +39,47 @@ static const char* TAG = "phy_init"; /* Count value to indicate if there is peripheral that has initialized PHY and RF */ -int g_phy_rf_init_count = 0; +static int s_phy_rf_init_count = 0; -static xSemaphoreHandle g_phy_rf_init_mux = NULL; +static _lock_t s_phy_rf_init_lock; -esp_err_t esp_phy_init(const void* init_data, - int mode, void* calibration_data, bool is_sleep) +esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, + esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data, bool is_sleep) { - esp_phy_init_data_t* data = (esp_phy_init_data_t *)init_data; - esp_phy_calibration_mode_t cal_mode = (esp_phy_calibration_mode_t)mode; - esp_phy_calibration_data_t* cal_data = (esp_phy_calibration_data_t *)calibration_data; + assert((s_phy_rf_init_count <= 1) && (s_phy_rf_init_count >= 0)); - assert((g_phy_rf_init_count <= 1) && (g_phy_rf_init_count >= 0)); - - if (g_phy_rf_init_mux == NULL) { - g_phy_rf_init_mux = xSemaphoreCreateMutex(); - if (g_phy_rf_init_mux == NULL) { - ESP_LOGE(TAG, "Create PHY RF mutex fail"); - return ESP_FAIL; + _lock_acquire(&s_phy_rf_init_lock); + if (s_phy_rf_init_count == 0) { + if (is_sleep == false) { + REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); + REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); } - } - - xSemaphoreTake(g_phy_rf_init_mux, portMAX_DELAY); - if (g_phy_rf_init_count == 0) { - if (is_sleep == false) { - REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); - REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); - } - // Enable WiFi peripheral clock - SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); + // Enable WiFi peripheral clock + SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d", init_data, calibration_data, mode); phy_set_wifi_mode_only(0); - register_chipv7_phy(data, cal_data, cal_mode); + register_chipv7_phy(init_data, calibration_data, mode); coex_bt_high_prio(); } - g_phy_rf_init_count++; - xSemaphoreGive(g_phy_rf_init_mux); + s_phy_rf_init_count++; + _lock_release(&s_phy_rf_init_lock); return ESP_OK; } -esp_err_t esp_phy_deinit(void) +esp_err_t esp_phy_rf_deinit(void) { - assert((g_phy_rf_init_count <= 2) && (g_phy_rf_init_count >= 1)); + assert((s_phy_rf_init_count <= 2) && (s_phy_rf_init_count >= 1)); - xSemaphoreTake(g_phy_rf_init_mux, portMAX_DELAY); - if (g_phy_rf_init_count == 1) { - // Disable PHY and RF. This is a teporary function. + _lock_acquire(&s_phy_rf_init_lock); + if (s_phy_rf_init_count == 1) { + // Disable PHY and RF. This is a teporary function. pm_close_rf(); - // Disable WiFi peripheral clock - CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); + // Disable WiFi peripheral clock + CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); } - g_phy_rf_init_count--; - xSemaphoreGive(g_phy_rf_init_mux); + s_phy_rf_init_count--; + _lock_release(&s_phy_rf_init_lock); return ESP_OK; } @@ -267,10 +251,11 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, return err; } -void do_phy_init(void) +void esp_phy_load_cal_and_init(void) { - esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; +#ifdef CONFIG_ESP32_STORE_PHY_CAL_DATA_INTO_NVS nvs_flash_init(); + esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) { calibration_mode = PHY_RF_CAL_NONE; } @@ -291,15 +276,18 @@ void do_phy_init(void) calibration_mode = PHY_RF_CAL_FULL; } - esp_phy_init(init_data, calibration_mode, cal_data, false); + esp_phy_rf_init(init_data, calibration_mode, cal_data, false); - if (calibration_mode != PHY_RF_CAL_NONE) { + if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) { err = esp_phy_store_cal_data_to_nvs(cal_data); } else { err = ESP_OK; } esp_phy_release_init_data(init_data); free(cal_data); // PHY maintains a copy of calibration data, so we can free this +#else + esp_phy_rf_init(NULL, PHY_RF_CAL_NONE, NULL, false); +#endif } #endif // CONFIG_PHY_ENABLED diff --git a/components/freertos/port.c b/components/freertos/port.c index ba4da3e284..3c26edfabf 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -407,7 +407,7 @@ void vPortSetStackWatchpoint( void* pxStackStart ) { } uint32_t xPortGetTickRateHz(void) { - return (uint32_t)configTICK_RATE_HZ; + return (uint32_t)configTICK_RATE_HZ; } From ad890aa5eaae94336fd242003a40eecbb0c3a702 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Fri, 17 Feb 2017 12:26:28 +0800 Subject: [PATCH 115/139] component/bt : wide range work temperature for bluetooth RF 1. add PLL track for bluetooth RF for wide range temperature 2. move some initialized codes to cache --- components/bt/lib | 2 +- components/esp32/include/soc/soc.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/bt/lib b/components/bt/lib index 9c1eea6bb0..c70dc44f60 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 9c1eea6bb03adc3b3847fff79c3f017652840a46 +Subproject commit c70dc44f607bcd090197dbc50472836ad25310fb diff --git a/components/esp32/include/soc/soc.h b/components/esp32/include/soc/soc.h index 3e0360e249..1b3e35dd47 100755 --- a/components/esp32/include/soc/soc.h +++ b/components/esp32/include/soc/soc.h @@ -268,10 +268,10 @@ * 2 1 extern level * 3 1 extern level * 4 1 extern level WBB - * 5 1 extern level BT Controller + * 5 1 extern level BT/BLE Controller * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1) * 7 1 software Reserved Reserved - * 8 1 extern level BLE Controller + * 8 1 extern level BT/BLE BB(RX/TX) * 9 1 extern level * 10 1 extern edge Internal Timer * 11 3 profiling From 8f3d1d3184496f3ca9952fa762c0fd69bc027d33 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Fri, 17 Feb 2017 15:29:11 +0800 Subject: [PATCH 116/139] fix compile error that if enable CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION compile fail --- components/esp32/include/esp_phy_init.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 5ad06ee896..9990957e2c 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -14,6 +14,7 @@ #pragma once #include +#include #include "esp_err.h" #ifdef __cplusplus From 4bd5b0c91af842a6a612e1c9e8d50edf6a7835cd Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Fri, 17 Feb 2017 19:24:58 +0800 Subject: [PATCH 117/139] component/bt : add bt enable/disable for power save 1. add new APIs bt controller enable/disab/deinit 2. make bt controller work need to call two APIs of esp_bt_controller_init and enable 3. modify phy init to make mac reset once --- components/bt/bluedroid/api/esp_bt_main.c | 3 - components/bt/bt.c | 62 ++++++++++++++++++- components/bt/include/bt.h | 35 ++++++++++- components/bt/lib | 2 +- components/esp32/phy_init.c | 8 ++- docs/api/bluetooth/controller_vhci.rst | 4 ++ examples/bluetooth/ble_adv/main/app_bt.c | 5 ++ examples/bluetooth/blufi/main/blufi_main.c | 6 ++ .../bluetooth/gatt_client/main/gattc_demo.c | 2 + .../bluetooth/gatt_server/main/gatts_demo.c | 5 ++ .../main/gatts_table_creat_demo.c | 30 +++++---- 11 files changed, 141 insertions(+), 21 deletions(-) diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index 612a9e020a..c9fe4fc060 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -17,7 +17,6 @@ #include "btc_task.h" #include "btc_main.h" #include "future.h" -#include "esp_phy_init.h" static bool esp_already_enable = false; static bool esp_already_init = false; @@ -165,8 +164,6 @@ esp_err_t esp_bluedroid_deinit(void) esp_already_init = false; - esp_phy_rf_deinit(); - return ESP_OK; } diff --git a/components/bt/bt.c b/components/bt/bt.c index 2390456afb..440c960e64 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -35,6 +35,10 @@ /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); extern void btdm_controller_init(void); +extern void btdm_controller_deinit(void); +extern int btdm_controller_enable(esp_bt_mode_t mode); +extern int btdm_controller_disable(esp_bt_mode_t mode); +extern void btdm_rf_bb_init(void); /* VHCI function interface */ typedef struct vhci_host_callback { @@ -71,6 +75,11 @@ struct osi_funcs_t { esp_err_t (* _read_efuse_mac)(uint8_t mac[6]); }; +/* Static variable declare */ +static bool btdm_bb_init_flag = false; + +static xTaskHandle btControllerTaskHandle; + static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED; static void IRAM_ATTR interrupt_disable(void) @@ -147,16 +156,63 @@ static void bt_controller_task(void *pvParam) { btdm_osi_funcs_register(&osi_funcs); - esp_phy_load_cal_and_init(); - btdm_controller_init(); } +static bool bb_inited; void esp_bt_controller_init() { + bb_inited = false; xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, - ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0); + ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); +} + +void esp_bt_controller_deinit(void) +{ + vTaskDelete(btControllerTaskHandle); + bb_inited = false; +} + +esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) +{ + int ret; + + if (mode != ESP_BT_MODE_BTDM) { + return ESP_ERR_INVALID_ARG; + } + + esp_phy_load_cal_and_init(); + + if (btdm_bb_init_flag == false) { + btdm_bb_init_flag = true; + btdm_rf_bb_init(); /* only initialise once */ + } + + ret = btdm_controller_enable(mode); + if (ret) { + return ESP_ERR_INVALID_STATE; + } + + return ESP_OK; +} + +esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode) +{ + int ret; + + if (mode != ESP_BT_MODE_BTDM) { + return ESP_ERR_INVALID_ARG; + } + + ret = btdm_controller_disable(mode); + if (ret) { + return ESP_ERR_INVALID_STATE; + } + + esp_phy_rf_deinit(); + + return ESP_OK; } #endif diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index 926ecfadcd..91617a28f4 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -23,14 +23,47 @@ extern "C" { #endif +/** + * @brief Bluetooth mode for controller enable/disable + */ +typedef enum { + ESP_BT_MODE_ILDE = 0x00, /*!< Bluetooth is not run */ + ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ + ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */ + ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ +} esp_bt_mode_t; /** - * @brief Initialize BT controller + * @brief Initialize BT controller to allocate task and other resource. * * This function should be called only once, before any other BT functions are called. */ void esp_bt_controller_init(void); +/** + * @brief De-initialize BT controller to free resource and delete task. + * + * This function should be called only once, after any other BT functions are called. + * This function is not whole completed, esp_bt_controller_init cannot called after this function. + */ +void esp_bt_controller_deinit(void); + +/** + * @brief Enable BT controller + * @param mode : the mode(BLE/BT/BTDM) to enable. + * Now only support BTDM. + */ +esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); + +/** + * @brief Disable BT controller + * @param mode : the mode(BLE/BT/BTDM) to disable. + * Now only support BTDM. + */ +esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode); + + + /** @brief esp_vhci_host_callback * used for vhci call host function to notify what host need to do */ diff --git a/components/bt/lib b/components/bt/lib index 9c1eea6bb0..69616af765 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 9c1eea6bb03adc3b3847fff79c3f017652840a46 +Subproject commit 69616af7653f4de6e3b78f475dc10e73f0a20ece diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 1c67a404ab..340bd7ee72 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -40,6 +40,7 @@ static const char* TAG = "phy_init"; /* Count value to indicate if there is peripheral that has initialized PHY and RF */ static int s_phy_rf_init_count = 0; +static bool s_mac_rst_flag = false; static _lock_t s_phy_rf_init_lock; @@ -51,8 +52,11 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, _lock_acquire(&s_phy_rf_init_lock); if (s_phy_rf_init_count == 0) { if (is_sleep == false) { - REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); - REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); + if (s_mac_rst_flag == false) { + s_mac_rst_flag = true; + REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); + REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST); + } } // Enable WiFi peripheral clock SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 35248cbb1e..108a9f678d 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -33,6 +33,7 @@ Type Definitions Enumerations ^^^^^^^^^^^^ +.. doxygenenum:: esp_bt_mode_t Structures ^^^^^^^^^^ @@ -45,6 +46,9 @@ Functions ^^^^^^^^^ .. doxygenfunction:: esp_bt_controller_init +.. doxygenfunction:: esp_bt_controller_deinit +.. doxygenfunction:: esp_bt_controller_enable +.. doxygenfunction:: esp_bt_controller_disable .. doxygenfunction:: esp_vhci_host_check_send_available .. doxygenfunction:: esp_vhci_host_send_packet .. doxygenfunction:: esp_vhci_host_register_callback diff --git a/examples/bluetooth/ble_adv/main/app_bt.c b/examples/bluetooth/ble_adv/main/app_bt.c index f0780c950c..67ab2c8fe0 100644 --- a/examples/bluetooth/ble_adv/main/app_bt.c +++ b/examples/bluetooth/ble_adv/main/app_bt.c @@ -215,6 +215,11 @@ void bleAdvtTask(void *pvParameters) void app_main() { esp_bt_controller_init(); + + if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + return; + } + xTaskCreatePinnedToCore(&bleAdvtTask, "bleAdvtTask", 2048, NULL, 5, NULL, 0); } diff --git a/examples/bluetooth/blufi/main/blufi_main.c b/examples/bluetooth/blufi/main/blufi_main.c index a95db66eb5..b46ffb4648 100644 --- a/examples/bluetooth/blufi/main/blufi_main.c +++ b/examples/bluetooth/blufi/main/blufi_main.c @@ -317,6 +317,12 @@ void app_main() esp_bt_controller_init(); + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + BLUFI_ERROR("%s enable bt controller failed\n", __func__); + return; + } + ret = esp_bluedroid_init(); if (ret) { BLUFI_ERROR("%s init bluedroid failed\n", __func__); diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index e6ee867293..4a2fa0051d 100644 --- a/examples/bluetooth/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/gatt_client/main/gattc_demo.c @@ -397,6 +397,8 @@ void gattc_client_test(void) void app_main() { esp_bt_controller_init(); + esp_bt_controller_enable(ESP_BT_MODE_BTDM); + gattc_client_test(); } diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 0afa1630ba..acbf9195a0 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -394,6 +394,11 @@ void app_main() esp_bt_controller_init(); + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s enable controller failed\n", __func__); + return; + } ret = esp_bluedroid_init(); if (ret) { ESP_LOGE(GATTS_TAG, "%s init bluetooth failed\n", __func__); diff --git a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c index 024362c5b7..71baf1842c 100644 --- a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -29,6 +29,7 @@ #include "esp_bt_main.h" #include "gatts_table_creat_demo.h" +#define GATTS_TABLE_TAG "GATTS_TABLE_DEMO" #define HEART_PROFILE_NUM 1 #define HEART_PROFILE_APP_IDX 0 @@ -196,7 +197,7 @@ static const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] = static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { - LOG_ERROR("GAP_EVT, event %d\n", event); + ESP_LOGE(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event); switch (event) { case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: @@ -210,15 +211,15 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - LOG_ERROR("event = %x\n",event); + ESP_LOGE(GATTS_TABLE_TAG, "event = %x\n",event); switch (event) { case ESP_GATTS_REG_EVT: - LOG_INFO("%s %d\n", __func__, __LINE__); + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME); - LOG_INFO("%s %d\n", __func__, __LINE__); + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gap_config_adv_data(&heart_rate_adv_config); - LOG_INFO("%s %d\n", __func__, __LINE__); + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if, HRS_IDX_NB, HEART_RATE_SVC_INST_ID); break; @@ -256,7 +257,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, case ESP_GATTS_CONGEST_EVT: break; case ESP_GATTS_CREAT_ATTR_TAB_EVT:{ - LOG_ERROR("The number handle =%x\n",param->add_attr_tab.num_handle); + ESP_LOGE(GATTS_TABLE_TAG, "The number handle =%x\n",param->add_attr_tab.num_handle); if(param->add_attr_tab.num_handle == HRS_IDX_NB){ memcpy(heart_rate_handle_table, param->add_attr_tab.handles, sizeof(heart_rate_handle_table)); @@ -275,14 +276,14 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - LOG_INFO("EVT %d, gatts if %d\n", event, gatts_if); + ESP_LOGI(GATTS_TABLE_TAG, "EVT %d, gatts if %d\n", event, gatts_if); /* If event is register event, store the gatts_if for each profile */ if (event == ESP_GATTS_REG_EVT) { if (param->reg.status == ESP_GATT_OK) { heart_rate_profile_tab[HEART_PROFILE_APP_IDX].gatts_if = gatts_if; } else { - LOG_INFO("Reg app failed, app_id %04x, status %d\n", + ESP_LOGI(GATTS_TABLE_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status); return; @@ -307,15 +308,22 @@ void app_main() esp_err_t ret; esp_bt_controller_init(); - LOG_INFO("%s init bluetooth\n", __func__); + + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed\n", __func__); + return; + } + + ESP_LOGI(GATTS_TABLE_TAG, "%s init bluetooth\n", __func__); ret = esp_bluedroid_init(); if (ret) { - LOG_ERROR("%s init bluetooth failed\n", __func__); + ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); if (ret) { - LOG_ERROR("%s enable bluetooth failed\n", __func__); + ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed\n", __func__); return; } From 21964a42fb6a65adb2a53f310d2a6dd23d48a953 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 15 Feb 2017 11:50:21 +1100 Subject: [PATCH 118/139] rtc_gpio: Replace RTC_GPIO_IS_VALID_GPIO macro with inline function --- components/driver/include/driver/rtc_io.h | 16 ++++++++++++++-- components/driver/rtc_module.c | 14 +++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/components/driver/include/driver/rtc_io.h b/components/driver/include/driver/rtc_io.h index 3fc3287646..f55f8fab74 100644 --- a/components/driver/include/driver/rtc_io.h +++ b/components/driver/include/driver/rtc_io.h @@ -46,10 +46,22 @@ typedef enum { RTC_GPIO_MODE_DISABLED, /*!< Pad (output + input) disable */ } rtc_gpio_mode_t; -#define RTC_GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && rtc_gpio_desc[gpio_num].reg != 0)) //to decide whether it is a valid GPIO number - extern const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT]; +/** + * @brief Determine if the specified GPIO is a valid RTC GPIO. + * + * @param gpio_num GPIO number + * @return true if GPIO is valid for RTC GPIO use. talse otherwise. + */ +inline static bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num) +{ + return gpio_num < GPIO_PIN_COUNT + && rtc_gpio_desc[gpio_num].reg != 0; +} + +#define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid(gpio_num) // Deprecated, use rtc_gpio_is_valid_gpio() + /** * @brief Init a GPIO as RTC GPIO * diff --git a/components/driver/rtc_module.c b/components/driver/rtc_module.c index 19fd3123a9..3d3cab0682 100644 --- a/components/driver/rtc_module.c +++ b/components/driver/rtc_module.c @@ -87,7 +87,7 @@ const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = { ---------------------------------------------------------------*/ esp_err_t rtc_gpio_init(gpio_num_t gpio_num) { - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&rtc_spinlock); // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux)); @@ -100,7 +100,7 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num) esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num) { - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&rtc_spinlock); //Select Gpio as Digital Gpio CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux)); @@ -131,7 +131,7 @@ static esp_err_t rtc_gpio_output_disable(gpio_num_t gpio_num) static esp_err_t rtc_gpio_input_enable(gpio_num_t gpio_num) { - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&rtc_spinlock); SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie); portEXIT_CRITICAL(&rtc_spinlock); @@ -141,7 +141,7 @@ static esp_err_t rtc_gpio_input_enable(gpio_num_t gpio_num) static esp_err_t rtc_gpio_input_disable(gpio_num_t gpio_num) { - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&rtc_spinlock); CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie); portEXIT_CRITICAL(&rtc_spinlock); @@ -152,7 +152,7 @@ static esp_err_t rtc_gpio_input_disable(gpio_num_t gpio_num) esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level) { int rtc_gpio_num = rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;; - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); if (level) { WRITE_PERI_REG(RTC_GPIO_OUT_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_OUT_DATA_W1TS_S))); @@ -167,7 +167,7 @@ uint32_t rtc_gpio_get_level(gpio_num_t gpio_num) { uint32_t level = 0; int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num; - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&rtc_spinlock); level = READ_PERI_REG(RTC_GPIO_IN_REG); @@ -177,7 +177,7 @@ uint32_t rtc_gpio_get_level(gpio_num_t gpio_num) esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode) { - RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); switch (mode) { case RTC_GPIO_MODE_INPUT_ONLY: From bfdfcbfaef72bf9e6a4fe4854be5e9869bd07327 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 16 Feb 2017 13:59:50 +1100 Subject: [PATCH 119/139] docs: Add missing peripheral driver docs (ADC, DAC, RTC I/O, I2S) --- components/driver/include/driver/adc.h | 81 ++++++---- components/driver/include/driver/dac.h | 18 +-- components/driver/include/driver/gpio.h | 45 ++++-- components/driver/include/driver/i2s.h | 187 +++++++++------------- components/driver/include/driver/rtc_io.h | 14 +- docs/api/peripherals/adc.rst | 62 +++++++ docs/api/peripherals/dac.rst | 45 ++++++ docs/api/peripherals/gpio.rst | 47 +++++- docs/api/peripherals/i2s.rst | 131 +++++++++++++++ docs/api/peripherals/index.rst | 17 +- docs/api/peripherals/sigmadelta.rst | 2 +- 11 files changed, 464 insertions(+), 185 deletions(-) create mode 100644 docs/api/peripherals/adc.rst create mode 100644 docs/api/peripherals/dac.rst create mode 100644 docs/api/peripherals/i2s.rst diff --git a/components/driver/include/driver/adc.h b/components/driver/include/driver/adc.h index 56bdbc1790..d81be4ff9d 100644 --- a/components/driver/include/driver/adc.h +++ b/components/driver/include/driver/adc.h @@ -49,11 +49,11 @@ typedef enum { } adc1_channel_t; /** - * @brief Configuration ADC1 capture width. + * @brief Configure ADC1 capture width. * - * The configuration is in effect for all channels of ADC1 + * The configuration is for all channels of ADC1 * - * @param width_bit ADC1 + * @param width_bit Bit capture width for ADC1 * * @return * - ESP_OK success @@ -62,10 +62,29 @@ typedef enum { esp_err_t adc1_config_width(adc_bits_width_t width_bit); /** - * @brief Configuration ADC1 capture attenuation of channels. + * @brief Configure the ADC1 channel, including setting attenuation. * - * @param channel the ADC1 channel - * @param atten attenuation + * @note This function also configures the input GPIO pin mux to + * connect it to the ADC1 channel. It must be called before calling + * adc1_get_voltage() for this channel. + * + * The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage, + * usually 3.3V) requires setting >0dB signal attenuation for that ADC channel. + * + * When VDD_A is 3.3V: + * + * - 0dB attenuaton (ADC_ATTEN_0db) gives full-scale voltage 1.1V + * - 2.5dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5V + * - 6dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2V + * - 11dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9V (see note below) + * + * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured + * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) + * + * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. + * + * @param channel ADC1 channel to configure + * @param atten Attenuation level * * @return * - ESP_OK success @@ -74,46 +93,38 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit); esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten); /** - * @brief ADC1 get the value of the voltage. + * @brief Take an ADC1 reading on a single channel * - * @param channel the ADC1 channel + * @note Call adc1_config_width() before the first time this + * function is called. + * + * @note For a given channel, adc1_config_channel_atten(channel) + * must be called before the first time this function is called. + * + * @param channel ADC1 channel to read * * @return - * - -1 Parameter error - * - Other the value of ADC1 channel + * - -1: Parameter error + * - Other: ADC1 channel reading. */ int adc1_get_voltage(adc1_channel_t channel); /** - * @brief Hall Sensor output value. - * @note - * The Hall Sensor uses Channel_0 and Channel_3 of ADC1. - * So, firstly: please configure ADC1 module by calling adc1_config_width before calling hall_sensor_read. - We recommend that the WIDTH ADC1 be configured as 12Bit, because the values of hall_sensor_read are small and almost the same if WIDTH ADC1 is configured as 9Bit, 10Bit or 11Bit. - * secondly: when you use the hall sensor, please do not use Channel_0 and Channel_3 of ADC1 as - * ADC channels. + * @brief Read Hall Sensor * - * @return the value of hall sensor + * @note The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure + * these channels for use as ADC channels. + * + * @note The ADC1 module must be enabled by calling + * adc1_config_width() before calling hall_sensor_read(). ADC1 + * should be configured for 12 bit readings, as the hall sensor + * readings are low values and do not cover the full range of the + * ADC. + * + * @return The hall sensor reading. */ int hall_sensor_read(); -/** - *----------EXAMPLE TO USE ADC1------------ * - * @code{c} - * adc1_config_width(ADC_WIDTH_12Bit);//config adc1 width - * adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db);//config channel0 attenuation - * int val=adc1_get_voltage(ADC1_CHANNEL_0);//get the val of channel0 - * @endcode - **/ - -/** - *----------EXAMPLE TO USE HALL SENSOR------------ * - * @code{c} - * adc1_config_width(ADC_WIDTH_12Bit);//config adc1 width - * int val=hall_sensor_read(); - * @endcode - **/ - #ifdef __cplusplus } #endif diff --git a/components/driver/include/driver/dac.h b/components/driver/include/driver/dac.h index 49758f41b9..ce5a90b3c8 100644 --- a/components/driver/include/driver/dac.h +++ b/components/driver/include/driver/dac.h @@ -29,12 +29,15 @@ typedef enum { } dac_channel_t; /** - * @brief Set Dac output voltage. + * @brief Set DAC output voltage. * - * Dac width is 8bit ,and the voltage max is vdd + * DAC output is 8-bit. Maximum (255) corresponds to VDD. * - * @param channel dac channel - * @param dac_value dac output value + * @note When this function is called, function for the DAC + * channel's GPIO pin is reconfigured for RTC DAC function. + * + * @param channel DAC channel + * @param dac_value DAC output value * * @return * - ESP_OK success @@ -42,13 +45,6 @@ typedef enum { */ esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value); -/** - *----------EXAMPLE TO USE DAC------------ * - * @code{c} - * dac_out_voltage(DAC_CHANNEL_1,200);//the dac out voltage ≈ 200*vdd/255 - * @endcode - **/ - #ifdef __cplusplus } #endif diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 1472ba8352..485afb696e 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -302,9 +302,9 @@ int gpio_get_level(gpio_num_t gpio_num); esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); /** - * @brief GPIO set pull + * @brief Configure GPIO pull-up/pull-down resistors * - * User this Function,configure GPIO pull mode,such as pull-up,pull-down + * Only pins that support both input & output have integrated pull-up and pull-down resistors. Input-only GPIOs 34-39 do not. * * @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); * @param pull GPIO pull up/down mode. @@ -317,7 +317,7 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); /** - * @brief enable GPIO wake-up function. + * @brief Enable GPIO wake-up function. * * @param gpio_num GPIO number. * @@ -341,15 +341,23 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type); esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num); /** - * @brief register GPIO interrupt handler, the handler is an ISR. + * @brief Register GPIO interrupt handler, the handler is an ISR. * The handler will be attached to the same CPU core that this function is running on. * + * This ISR function is called whenever any GPIO interrupt occurs. See + * the alternative gpio_install_isr_service() and + * gpio_isr_handler_add() API in order to have the driver support + * per-GPIO ISRs. + * * @param fn Interrupt handler function. * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. * @param arg Parameter for handler function - * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will - * be returned here. + * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will be returned here. + * + * \verbatim embed:rst:leading-asterisk + * To disable or remove the ISR, pass the returned handle to the :doc:`interrupt allocation functions `. + * \endverbatim * * @return * - ESP_OK Success ; @@ -402,7 +410,9 @@ esp_err_t gpio_pulldown_en(gpio_num_t gpio_num); esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num); /** - * @brief Install a GPIO ISR service, so we can assign different ISR handler for different pins + * @brief Install the driver's GPIO ISR handler service, which allows per-pin GPIO interrupt handlers. + * + * This function is incompatible with gpio_isr_register() - if that function is used, a single global ISR is registered for all GPIO interrupts. If this function is used, the ISR service provides a global GPIO ISR and individual pin handlers are registered via the gpio_isr_register() function. * * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. @@ -415,17 +425,24 @@ esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num); esp_err_t gpio_install_isr_service(int intr_alloc_flags); /** - * @brief Un-install GPIO ISR service, free the resources. + * @brief Uninstall the driver's GPIO ISR service, freeing related resources. */ void gpio_uninstall_isr_service(); /** - * @brief Add ISR handler for the corresponding GPIO. + * @brief Add ISR handler for the corresponding GPIO pin. * - * Interrupt handlers no longer need to be declared with IRAM_ATTR, unless you pass the ESP_INTR_FLAG_IRAM flag - * when allocating the ISR in gpio_install_isr_service(). - * This ISR handler will be called from an ISR. So there probably is some stack size limit, and this limit - * is smaller compared to a "raw" interrupt handler due to another level of indirection. + * Call this function after using gpio_install_isr_service() to + * install the driver's GPIO ISR handler service. + * + * The pin ISR handlers no longer need to be declared with IRAM_ATTR, + * unless you pass the ESP_INTR_FLAG_IRAM flag when allocating the + * ISR in gpio_install_isr_service(). + * + * This ISR handler will be called from an ISR. So there is a stack + * size limit (configurable as "ISR stack size" in menuconfig). This + * limit is smaller compared to a global GPIO interrupt handler due + * to the additional level of indirection. * * @param gpio_num GPIO number * @param isr_handler ISR handler function for the corresponding GPIO number. @@ -439,7 +456,7 @@ void gpio_uninstall_isr_service(); esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void* args); /** - * @brief Remove ISR handler for the corresponding GPIO. + * @brief Remove ISR handler for the corresponding GPIO pin. * * @param gpio_num GPIO number * diff --git a/components/driver/include/driver/i2s.h b/components/driver/include/driver/i2s.h index d44bb676a3..b904b77140 100644 --- a/components/driver/include/driver/i2s.h +++ b/components/driver/include/driver/i2s.h @@ -32,9 +32,6 @@ extern "C" { #endif -#define I2S_PIN_NO_CHANGE (-1) - - /** * @brief I2S bit width per sample. * @@ -147,6 +144,8 @@ typedef struct { size_t size; /*!< I2S data size for I2S_DATA event*/ } i2s_event_t; +#define I2S_PIN_NO_CHANGE (-1) /*!< Use in i2s_pin_config_t for pins which should not be changed */ + /** * @brief I2S pin number for i2s_set_pin * @@ -160,15 +159,18 @@ typedef struct { typedef intr_handle_t i2s_isr_handle_t; /** - * @brief Set I2S pin number + * @brief Set I2S pin number * - * @note - * Internal signal can be output to multiple GPIO pads - * Only one GPIO pad can connect with input signal + * @note + * The I2S peripheral output signals can be connected to multiple GPIO pads. + * However, the I2S peripheral input signal can only be connected to one GPIO pad. * * @param i2s_num I2S_NUM_0 or I2S_NUM_1 * - * @param pin I2S Pin struct, or NULL for 2-channels, 8-bits DAC pin configuration (GPIO25 & GPIO26) + * @param pin I2S Pin structure, or NULL to set 2-channel 8-bit internal DAC pin configuration (GPIO25 & GPIO26) + * + * Inside the pin configuration structure, set I2S_PIN_NO_CHANGE for any pin where + * the current configuration should not be changed. * * @return * - ESP_OK Success @@ -177,15 +179,17 @@ typedef intr_handle_t i2s_isr_handle_t; esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin); /** - * @brief i2s install and start driver + * @brief Install and start I2S driver. * - * @param i2s_num I2S_NUM_0, I2S_NUM_1 + * @param i2s_num I2S_NUM_0, I2S_NUM_1 * - * @param i2s_config I2S configurations - see i2s_config_t struct + * @param i2s_config I2S configurations - see i2s_config_t struct * - * @param queue_size I2S event queue size/depth. + * @param queue_size I2S event queue size/depth. * - * @param i2s_queue I2S event queue handle, if set NULL, driver will not use an event queue. + * @param i2s_queue I2S event queue handle, if set NULL, driver will not use an event queue. + * + * This function must be called before any I2S driver read/write operations. * * @return * - ESP_OK Success @@ -205,68 +209,88 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num); /** - * @brief i2s read data buffer to i2s dma buffer + * @brief Write data to I2S DMA transmit buffer. * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * - * @param src source address to write + * @param src Source address to write from * - * @param size size of data (size in bytes) + * @param size Size of data in bytes * - * @param ticks_to_wait Write timeout + * @param ticks_to_wait TX buffer wait timeout in RTOS ticks. If this + * many ticks pass without space becoming available in the DMA + * transmit buffer, then the function will return (note that if the + * data is written to the DMA buffer in pieces, the overall operation + * may still take longer than this timeout.) Pass portMAX_DELAY for no + * timeout. * - * @return number of written bytes + * Format of the data in source buffer is determined by the I2S + * configuration (see i2s_config_t). + * + * @return Number of bytes written, or ESP_FAIL (-1) for parameter error. If a timeout occurred, bytes written will be less than total size. */ int i2s_write_bytes(i2s_port_t i2s_num, const char *src, size_t size, TickType_t ticks_to_wait); /** - * @brief i2s write data buffer to i2s dma buffer + * @brief Read data from I2S DMA receive buffer * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * - * @param dest destination address to read + * @param dest Destination address to read into * - * @param size size of data (size in bytes) + * @param size Size of data in bytes * - * @param ticks_to_wait Read timeout + * @param ticks_to_wait RX buffer wait timeout in RTOS ticks. If this many ticks pass without bytes becoming available in the DMA receive buffer, then the function will return (note that if data is read from the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout. * - * @return number of read bytes + * Format of the data in source buffer is determined by the I2S + * configuration (see i2s_config_t). + * + * @return Number of bytes read, or ESP_FAIL (-1) for parameter error. If a timeout occurred, bytes read will be less than total size. */ int i2s_read_bytes(i2s_port_t i2s_num, char* dest, size_t size, TickType_t ticks_to_wait); /** - * @brief i2s push 1 sample to i2s dma buffer, with the size parameter equal to one sample's size in bytes = bits_per_sample/8. + * @brief Push (write) a single sample to the I2S DMA TX buffer. + * + * Size of the sample is determined by the channel_format (mono or stereo)) & bits_per_sample configuration (see i2s_config_t). * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * - * @param sample destination address to write (depend on bits_per_sample, size of sample (in bytes) = 2*bits_per_sample/8) + * @param sample Pointer to buffer containing sample to write. Size of buffer (in bytes) = (number of channels) * bits_per_sample / 8. * - * @param ticks_to_wait Push timeout + * @param ticks_to_wait Push timeout in RTOS ticks. If space is not available in the DMA TX buffer within this period, no data is written and function returns 0. * - * @return number of push bytes + * @return Number of bytes successfully pushed to DMA buffer, or ESP_FAIL (-1) for parameter error. Will be either zero or the size of configured sample buffer. */ int i2s_push_sample(i2s_port_t i2s_num, const char *sample, TickType_t ticks_to_wait); /** - * @brief Pop 1 sample to i2s dma buffer, with the size parameter equal to one sample's size in bytes = bits_per_sample/8. + * @brief Pop (read) a single sample from the I2S DMA RX buffer. + * + * Size of the sample is determined by the channel_format (mono or stereo)) & bits_per_sample configuration (see i2s_config_t). * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * - * @param sample destination address to write (depend on bits_per_sample, size of sample (in bytes) = 2*bits_per_sample/8) + * @param sample Buffer sample data will be read into. Size of buffer (in bytes) = (number of channels) * bits_per_sample / 8. * - * @param ticks_to_wait Pop timeout + * @param ticks_to_wait Pop timeout in RTOS ticks. If a sample is not available in the DMA buffer within this period, no data is read and function returns zero. * - * @return number of pop bytes + * @return Number of bytes successfully read from DMA buffer, or ESP_FAIL (-1) for parameter error. Byte count will be either zero or the size of the configured sample buffer. + */ int i2s_pop_sample(i2s_port_t i2s_num, char *sample, TickType_t ticks_to_wait); /** - * @brief Set clock rate used for I2S RX and TX + * @brief Set sample rate used for I2S RX and TX. + * + * The bit clock rate is determined by the sample rate and i2s_config_t configuration parameters (number of channels, bits_per_sample). + * + * `bit_clock = rate * (number of channels) * bits_per_sample` * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * - * @param rate I2S clock (ex: 8000, 44100...) + * @param rate I2S sample rate (ex: 8000, 44100...) * * @return * - ESP_OK Success @@ -275,18 +299,9 @@ int i2s_pop_sample(i2s_port_t i2s_num, char *sample, TickType_t ticks_to_wait); esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate); /** - * @brief Start driver + * @brief Stop I2S driver * - * @param i2s_num I2S_NUM_0, I2S_NUM_1 - * -* @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t i2s_start(i2s_port_t i2s_num); - -/** - * @brief Stop driver + * Disables I2S TX/RX, until i2s_start() is called. * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * @@ -297,7 +312,23 @@ esp_err_t i2s_start(i2s_port_t i2s_num); esp_err_t i2s_stop(i2s_port_t i2s_num); /** - * @brief Set the TX DMA buffer contents to all zeroes + * @brief Start I2S driver + * + * It is not necessary to call this function after i2s_driver_install() (it is started automatically), however it is necessary to call it after i2s_stop(). + * + * + * @param i2s_num I2S_NUM_0, I2S_NUM_1 + * +* @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t i2s_start(i2s_port_t i2s_num); + +/** + * @brief Zero the contents of the TX DMA buffer. + * + * Pushes zero-byte samples into the TX DMA buffer, until it is full. * * @param i2s_num I2S_NUM_0, I2S_NUM_1 * @@ -307,72 +338,6 @@ esp_err_t i2s_stop(i2s_port_t i2s_num); */ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num); -/***************************EXAMPLE********************************** - * - * - * ----------------EXAMPLE OF I2S SETTING --------------------- - * @code{c} - * - * #include "freertos/queue.h" - * #define I2S_INTR_NUM 17 //choose one interrupt number from soc.h - * int i2s_num = 0; //i2s port number - * i2s_config_t i2s_config = { - * .mode = I2S_MODE_MASTER | I2S_MODE_TX, - * .sample_rate = 44100, - * .bits_per_sample = 16, //16, 32 - * .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //format LEFT_RIGHT - * .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB, - * .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, - * .dma_buf_count = 8, - * .dma_buf_len = 64 - * }; - * - * i2s_pin_config_t pin_config = { - * .bck_io_num = 26, - * .ws_io_num = 25, - * .data_out_num = 22, - * .data_in_num = I2S_PIN_NO_CHANGE - * }; - * - * i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - * - * i2s_set_pin(i2s_num, &pin_config); - * - * i2s_set_sample_rates(i2s_num, 22050); //set sample rates - * - * - * i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver - *@endcode - * - * ----------------EXAMPLE USING I2S WITH DAC --------------------- - * @code{c} - * - * #include "freertos/queue.h" - * #define I2S_INTR_NUM 17 //choose one interrupt number from soc.h - * int i2s_num = 0; //i2s port number - * i2s_config_t i2s_config = { - * .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, - * .sample_rate = 44100, - * .bits_per_sample = 8, // Only 8-bit DAC support - * .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // - * .communication_format = I2S_COMM_FORMAT_I2S_MSB, - * .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, - * .dma_buf_count = 8, - * .dma_buf_len = 64 - * }; - * - * - * i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - * - * i2s_set_pin(i2s_num, NULL); //for internal DAC - * - * i2s_set_sample_rates(i2s_num, 22050); //set sample rates - * - * i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver - *@endcode - *-----------------------------------------------------------------------------* - ***************************END OF EXAMPLE**********************************/ - #ifdef __cplusplus } #endif diff --git a/components/driver/include/driver/rtc_io.h b/components/driver/include/driver/rtc_io.h index f55f8fab74..3a27a34765 100644 --- a/components/driver/include/driver/rtc_io.h +++ b/components/driver/include/driver/rtc_io.h @@ -24,7 +24,10 @@ extern "C" { #endif /** - * @brief Pullup/pulldown information for a single GPIO pad + * @brief Pin function information for a single GPIO pad's RTC functions. + * + * This is an internal function of the driver, and is not usually useful + * for external use. */ typedef struct { uint32_t reg; /*!< Register of RTC pad, or 0 if not an RTC GPIO */ @@ -46,6 +49,13 @@ typedef enum { RTC_GPIO_MODE_DISABLED, /*!< Pad (output + input) disable */ } rtc_gpio_mode_t; +/** + * @brief Provides access to a constant table of RTC I/O pin + * function information. + * + * This is an internal function of the driver, and is not usually useful + * for external use. + */ extern const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT]; /** @@ -60,7 +70,7 @@ inline static bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num) && rtc_gpio_desc[gpio_num].reg != 0; } -#define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid(gpio_num) // Deprecated, use rtc_gpio_is_valid_gpio() +#define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid_gpio(gpio_num) // Deprecated, use rtc_gpio_is_valid_gpio() /** * @brief Init a GPIO as RTC GPIO diff --git a/docs/api/peripherals/adc.rst b/docs/api/peripherals/adc.rst new file mode 100644 index 0000000000..8d598f327f --- /dev/null +++ b/docs/api/peripherals/adc.rst @@ -0,0 +1,62 @@ +Analog to Digital Converter +=========================== + +Overview +-------- + +ESP32 integrates two 12-bit SAR ("Successive Approximation Register") ADCs (Analog to Digital Converters) and supports measurements on 18 channels (analog enabled pins). Some of these pins can be used to build a programmable gain amplifier which is used for the measurement of small +analog signals. + +The ADC driver API currently only supports ADC1 (9 channels, attached to GPIOs 32-39). + +Taking an ADC reading involves configuring the ADC with the desired precision and attentuation settings, and then calling adc1_get_voltage() to read the channel. + +It is also possible to read the internal hall effect sensor via ADC1. + +Application Example +------------------- + +Reading voltage on ADC1 channel 0 (GPIO 36):: + + #include + + ... + + adc1_config_width(ADC_WIDTH_12Bit); + adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db); + int val = adc1_get_voltage(ADC1_CHANNEL_0); + +Reading the internal hall effect sensor:: + + #include + + ... + + adc1_config_width(ADC_WIDTH_12Bit); + int val = hall_sensor_read(); + +The value read in both these examples is 12 bits wide (range 0-4095). + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `components/driver/include/driver/adc.h` + +Enumerations +^^^^^^^^^^^^ + + .. doxygenenum:: adc1_channel_t + .. doxygenenum:: adc_atten_t + .. doxygenenum:: adc_bits_width_t + +Functions +^^^^^^^^^ + + .. doxygenfunction:: adc1_config_width + .. doxygenfunction:: adc1_config_channel_atten + .. doxygenfunction:: adc1_get_voltage + .. doxygenfunction:: hall_sensor_read + diff --git a/docs/api/peripherals/dac.rst b/docs/api/peripherals/dac.rst new file mode 100644 index 0000000000..ec17c31cac --- /dev/null +++ b/docs/api/peripherals/dac.rst @@ -0,0 +1,45 @@ +Digital To Analog Converter +=========================== + +Overview +-------- + +ESP32 has two 8-bit DAC (digital to analog converter) channels, connected to GPIO25 (Channel 1) and GPIO26 (Channel 2). + +The DAC driver allows these channels to be set to arbitrary voltages. + +The DAC channels can also be driven with DMA-style written sample data, via the :doc:`I2S driver ` when using the "built-in DAC mode". + +For other analog output options, see the :doc:`Sigma-delta Modulation module ` and the :doc:`LED Control module `. Both these modules produce high frequency PWM output, which can be hardware low-pass filtered in order to generate a lower frequency analog output. + + +Application Example +------------------- + +Setting DAC channel 1 (GPIO 25) voltage to approx 0.78 of VDD_A voltage (VDD * 200 / 255). For VDD_A 3.3V, this is 2.59V:: + + #include + + ... + + dac_out_voltage(DAC_CHANNEL_1, 200); + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `components/driver/include/driver/dac.h` + +Enumerations +^^^^^^^^^^^^ + + .. doxygenenum:: dac_channel_t + +Functions +^^^^^^^^^ + + .. doxygenfunction:: dac_out_voltage + + diff --git a/docs/api/peripherals/gpio.rst b/docs/api/peripherals/gpio.rst index da3f4607ea..a4f2ea81d3 100644 --- a/docs/api/peripherals/gpio.rst +++ b/docs/api/peripherals/gpio.rst @@ -1,11 +1,15 @@ -GPIO -==== +GPIO & RTC GPIO +=============== Overview -------- The ESP32 chip features 40 physical GPIO pads. Some GPIO pads cannot be used or do not have the corresponding pin on the chip package(refer to technical reference manual ). Each pad can be used as a general purpose I/O or can be connected to an internal peripheral signal. -Note that GPIO6-11 are usually used for SPI flash. GPIO34-39 can only be set as input mode. + +- Note that GPIO6-11 are usually used for SPI flash. +- GPIO34-39 can only be set as input mode and do not have software pullup or pulldown functions. + +There is also separate "RTC GPIO" support, which functions when GPIOs are routed to the "RTC" low-power and analog subsystem. These pin functions can be used when in deep sleep, when the :doc:`Ultra Low Power co-processor ` is running, or when analog functions such as ADC/DAC/etc are in use. Application Example ------------------- @@ -19,10 +23,14 @@ Header Files ^^^^^^^^^^^^ * :component_file:`driver/include/driver/gpio.h` + * :component_file:`driver/include/driver/rtc_io.h` Macros ^^^^^^ +Normal GPIO +~~~~~~~~~~~ + .. doxygendefine:: GPIO_SEL_0 .. doxygendefine:: GPIO_SEL_1 .. doxygendefine:: GPIO_SEL_2 @@ -107,12 +115,18 @@ Macros Type Definitions ^^^^^^^^^^^^^^^^ +Normal GPIO +~~~~~~~~~~~ + .. doxygentypedef:: gpio_isr_t .. doxygentypedef:: gpio_isr_handle_t Enumerations ^^^^^^^^^^^^ +Normal GPIO +~~~~~~~~~~~ + .. doxygenenum:: gpio_num_t .. doxygenenum:: gpio_int_type_t .. doxygenenum:: gpio_mode_t @@ -120,16 +134,26 @@ Enumerations .. doxygenenum:: gpio_pulldown_t .. doxygenenum:: gpio_pull_mode_t +RTC GPIO +~~~~~~~~ + +.. doxygenenum:: rtc_gpio_mode_t + Structures ^^^^^^^^^^ +Normal GPIO +~~~~~~~~~~~ + .. doxygenstruct:: gpio_config_t :members: - Functions ^^^^^^^^^ +Normal GPIO +~~~~~~~~~~~ + .. doxygenfunction:: gpio_config .. doxygenfunction:: gpio_set_intr_type .. doxygenfunction:: gpio_intr_enable @@ -150,3 +174,18 @@ Functions .. doxygenfunction:: gpio_isr_handler_add .. doxygenfunction:: gpio_isr_handler_remove + +RTC GPIO +~~~~~~~~ + +.. doxygenfunction:: rtc_gpio_is_valid_gpio +.. doxygenfunction:: rtc_gpio_init +.. doxygenfunction:: rtc_gpio_deinit +.. doxygenfunction:: rtc_gpio_get_level +.. doxygenfunction:: rtc_gpio_set_level +.. doxygenfunction:: rtc_gpio_set_direction +.. doxygenfunction:: rtc_gpio_pullup_en +.. doxygenfunction:: rtc_gpio_pulldown_en +.. doxygenfunction:: rtc_gpio_pullup_dis +.. doxygenfunction:: rtc_gpio_pulldown_dis +.. doxygenfunction:: rtc_gpio_unhold_all diff --git a/docs/api/peripherals/i2s.rst b/docs/api/peripherals/i2s.rst new file mode 100644 index 0000000000..57ce422a8a --- /dev/null +++ b/docs/api/peripherals/i2s.rst @@ -0,0 +1,131 @@ +I2S +=== + +Overview +-------- + +ESP32 contains two I2S peripherals. These peripherals can be configured to input and output sample data via the I2S driver. + +The I2S peripheral supports DMA meaning it can stream sample data without requiring each sample to be read or written by the CPU. + +I2S output can also be routed directly to the Digital/Analog Converter output channels (GPIO 25 & GPIO 26) to produce analog output directly, rather than via an external I2S codec. + +Application Example +------------------- + +A full I2S example is available in esp-idf: :example:`peripherals/i2s`. + +Short example of I2S configuration:: + + #include "driver/i2s.h" + #include "freertos/queue.h" + + static const int i2s_num = 0; // i2s port number + + static const i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX, + .sample_rate = 44100, + .bits_per_sample = 16, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority + .dma_buf_count = 8, + .dma_buf_len = 64 + }; + + static const i2s_pin_config_t pin_config = { + .bck_io_num = 26, + .ws_io_num = 25, + .data_out_num = 22, + .data_in_num = I2S_PIN_NO_CHANGE + }; + + ... + + i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver + + i2s_set_pin(i2s_num, &pin_config); + + i2s_set_sample_rates(i2s_num, 22050); //set sample rates + + i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver + +Short example configuring I2S to use internal DAC for analog output:: + + #include "driver/i2s.h" + #include "freertos/queue.h" + + static const int i2s_num = 0; // i2s port number + + static const i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, + .sample_rate = 44100, + .bits_per_sample = 8, /* must be 8 for built-in DAC */ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority + .dma_buf_count = 8, + .dma_buf_len = 64 + }; + + ... + + i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver + + i2s_set_pin(i2s_num, NULL); //for internal DAC + + i2s_set_sample_rates(i2s_num, 22050); //set sample rates + + i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `components/driver/include/driver/i2s.h` + +Data Structures +^^^^^^^^^^^^^^^ + + .. doxygenstruct:: i2s_config_t + :members: + .. doxygenstruct:: i2s_event_t + :members: + .. doxygenstruct:: i2s_pin_config_t + :members: + +Macros +^^^^^^ + + .. doxygendefine:: I2S_PIN_NO_CHANGE + +Enumerations +^^^^^^^^^^^^ + + .. doxygenenum:: i2s_bits_per_sample_t + .. doxygenenum:: i2s_comm_format_t + .. doxygenenum:: i2s_channel_fmt_t + .. doxygenenum:: pdm_sample_rate_ratio_t + .. doxygenenum:: pdm_pcm_conv_t + .. doxygenenum:: i2s_port_t + .. doxygenenum:: i2s_mode_t + .. doxygenenum:: i2s_event_type_t + +Functions +^^^^^^^^^ + + .. doxygenfunction:: i2s_set_pin + .. doxygenfunction:: i2s_driver_install + .. doxygenfunction:: i2s_driver_uninstall + .. doxygenfunction:: i2s_write_bytes + .. doxygenfunction:: i2s_read_bytes + .. doxygenfunction:: i2s_push_sample + .. doxygenfunction:: i2s_pop_sample + .. doxygenfunction:: i2s_set_sample_rates + .. doxygenfunction:: i2s_start + .. doxygenfunction:: i2s_stop + .. doxygenfunction:: i2s_zero_dma_buffer + + diff --git a/docs/api/peripherals/index.rst b/docs/api/peripherals/index.rst index f3c1dbe4a3..167c7b9952 100644 --- a/docs/api/peripherals/index.rst +++ b/docs/api/peripherals/index.rst @@ -4,15 +4,18 @@ Peripherals API .. toctree:: :maxdepth: 1 - GPIO - UART + ADC + DAC + GPIO (including RTC low power I/O) I2C - SPI Master - Timer - Pulse Counter - Sigma-delta Modulation + I2S LED Control + Pulse Counter + SD/MMC Card Host <../storage/sdmmc> + Sigma-delta Modulation + SPI Master Remote Control - + Timer + UART Example code for this API section is provided in :example:`peripherals` directory of ESP-IDF examples. diff --git a/docs/api/peripherals/sigmadelta.rst b/docs/api/peripherals/sigmadelta.rst index fb51ae8b03..d2e423deb1 100644 --- a/docs/api/peripherals/sigmadelta.rst +++ b/docs/api/peripherals/sigmadelta.rst @@ -4,7 +4,7 @@ Sigma-delta Modulation Overview -------- -ESP32 has a second-order sigma-delta modulation module. +ESP32 has a second-order sigma-delta modulation module. This driver configures the channels of the sigma-delta module. Application Example From 4db4e28b6eb079bf93944c28c1d6d513b4012a39 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 17 Feb 2017 10:14:45 +1100 Subject: [PATCH 120/139] uart driver docs: Remove references to setting interrupt number Closes #185 https://github.com/espressif/esp-idf/issues/185 --- components/driver/include/driver/uart.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 68d02a5e0a..23635df27d 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -469,8 +469,6 @@ esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_ * @brief Install UART driver. * * UART ISR handler will be attached to the same CPU core that this function is running on. - * Users should know that which CPU is running and then pick a INUM that is not used by system. - * We can find the information of INUM and interrupt level in soc.h. * * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 * @param rx_buffer_size UART RX ring buffer size, rx_buffer_size should be greater than UART_FIFO_LEN. @@ -644,7 +642,6 @@ esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, u * @code{c} * //1. Setup UART * #include "freertos/queue.h" - * #define UART_INTR_NUM 17 //choose one interrupt number from soc.h * //a. Set UART parameter * int uart_num = 0; //uart port number * uart_config_t uart_config = { From 770c2ade05a91f9e0d924d7edc7a499a4cd0df56 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Mon, 20 Feb 2017 10:23:56 +0800 Subject: [PATCH 121/139] phy init: modify some comments --- components/esp32/Kconfig | 9 +++++---- components/esp32/phy_init.c | 4 ++-- components/esp32/rtc.h | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index d3441fa017..8aa0ed3b5f 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -508,13 +508,14 @@ config PHY_ENABLED menu PHY visible if PHY_ENABLED -config ESP32_STORE_PHY_CAL_DATA_INTO_NVS - bool "Store PHY calibration data into NVS" +config ESP32_PHY_CALIBRATION_AND_DATA_STORAGE + bool "Do phy calibration and store calibration data in NVS" depends on PHY_ENABLED default y help - If this option is enabled, PHY initialization will also calibrate PHY data, and - store it into NVS. + If this option is enabled, NVS will be initialized and calibration data will be loaded from there. + PHY calibration will be skipped on deep sleep wakeup. If calibration data is not found, full calibration + will be performed and stored in NVS. In all other cases, only partial calibration will be performed. If unsure, choose 'y'. diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 340bd7ee72..8ec518bac0 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -77,7 +77,7 @@ esp_err_t esp_phy_rf_deinit(void) _lock_acquire(&s_phy_rf_init_lock); if (s_phy_rf_init_count == 1) { - // Disable PHY and RF. This is a teporary function. + // Disable PHY and RF. TODO: convert this function to another one. pm_close_rf(); // Disable WiFi peripheral clock CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); @@ -257,7 +257,7 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, void esp_phy_load_cal_and_init(void) { -#ifdef CONFIG_ESP32_STORE_PHY_CAL_DATA_INTO_NVS +#ifdef CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE nvs_flash_init(); esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) { diff --git a/components/esp32/rtc.h b/components/esp32/rtc.h index 48272259fa..f21d0da83e 100644 --- a/components/esp32/rtc.h +++ b/components/esp32/rtc.h @@ -136,7 +136,7 @@ void rtc_slp_prep_lite(uint32_t deep_slp, uint32_t cpu_lp_mode); uint32_t rtc_sleep(uint32_t cycles_h, uint32_t cycles_l, uint32_t wakeup_opt, uint32_t reject_opt); /** - * @brief Shutdown PHY and RF. This is a temporary function. + * @brief Shutdown PHY and RF. TODO: convert this function to another one. */ void pm_close_rf(void); From bb0298bc715a2444a6822f4e04e9c188085bf862 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Mon, 20 Feb 2017 23:53:25 +0800 Subject: [PATCH 122/139] coexist: enable coexist when wifi&bt are enabled, disable coexist when one of wifi&bt is disabled. --- components/esp32/cpu_start.c | 6 ------ components/esp32/include/esp_coexist.h | 5 +++++ components/esp32/include/esp_wifi.h | 1 + components/esp32/lib | 2 +- components/esp32/phy_init.c | 9 +++++++++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index bc7ed6a71c..cf20083508 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -211,12 +211,6 @@ void start_cpu0_default(void) esp_core_dump_init(); #endif -#if CONFIG_SW_COEXIST_ENABLE - if (coex_init() == ESP_OK) { - coexist_set_enable(true); - } -#endif - xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, ESP_TASK_MAIN_PRIO, NULL, 0); diff --git a/components/esp32/include/esp_coexist.h b/components/esp32/include/esp_coexist.h index f58d2ef949..872b5e5ab7 100644 --- a/components/esp32/include/esp_coexist.h +++ b/components/esp32/include/esp_coexist.h @@ -25,6 +25,11 @@ extern "C" { */ esp_err_t coex_init(void); +/** + * @brief De-init software coexist + */ +void coex_deinit(void); + /** * @brief Get software coexist enable or not * diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 8d4fa17bb7..0f7e2996e8 100755 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -130,6 +130,7 @@ esp_err_t esp_wifi_init(wifi_init_config_t *config); * Free all resource allocated in esp_wifi_init and stop WiFi task * * @attention 1. This API should be called if you want to remove WiFi driver from the system + * @attention 2. This API can not be called yet and will be done in the future. * * @return ESP_OK: succeed */ diff --git a/components/esp32/lib b/components/esp32/lib index bc16e8c074..ed85cf9156 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit bc16e8c0749adefcd5bf44c9024849a504b8e839 +Subproject commit ed85cf9156f2ef358c29d07fb849a73c5758eecb diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 8ec518bac0..34e1a9f00e 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -35,6 +35,7 @@ #include "phy.h" #include "phy_init_data.h" #include "rtc.h" +#include "esp_coexist.h" static const char* TAG = "phy_init"; @@ -65,6 +66,10 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, phy_set_wifi_mode_only(0); register_chipv7_phy(init_data, calibration_data, mode); coex_bt_high_prio(); + } else { +#if CONFIG_SW_COEXIST_ENABLE + coex_init(); +#endif } s_phy_rf_init_count++; _lock_release(&s_phy_rf_init_lock); @@ -81,6 +86,10 @@ esp_err_t esp_phy_rf_deinit(void) pm_close_rf(); // Disable WiFi peripheral clock CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); + } else { +#if CONFIG_SW_COEXIST_ENABLE + coex_deinit(); +#endif } s_phy_rf_init_count--; _lock_release(&s_phy_rf_init_lock); From 12a7293b312d410be73e0da912f0bb55a8b13149 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Tue, 21 Feb 2017 01:05:37 +0800 Subject: [PATCH 123/139] component/bt : add bluetooth status check 1. add bluetooth controller/host initialize status check 2. separate bluetooth controller task schedule loop from controller init --- components/bt/bluedroid/api/esp_bt_main.c | 6 +++++ components/bt/bt.c | 31 ++++++++++++++++++++--- components/bt/include/bt.h | 18 ++++++++++++- components/bt/lib | 2 +- docs/api/bluetooth/controller_vhci.rst | 1 + 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index c9fe4fc060..5f7265e99c 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -16,6 +16,7 @@ #include "esp_bt_main.h" #include "btc_task.h" #include "btc_main.h" +#include "bt.h" #include "future.h" static bool esp_already_enable = false; @@ -103,6 +104,11 @@ esp_err_t esp_bluedroid_init(void) btc_msg_t msg; future_t **future_p; + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + LOG_ERROR("%s conroller not init\n", __func__); + return ESP_ERR_INVALID_STATE; + } + if (esp_already_init) { LOG_ERROR("%s already init\n", __func__); return ESP_ERR_INVALID_STATE; diff --git a/components/bt/bt.c b/components/bt/bt.c index 440c960e64..6a81d11acc 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -35,6 +35,7 @@ /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); extern void btdm_controller_init(void); +extern void btdm_controller_schedule(void); extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); extern int btdm_controller_disable(esp_bt_mode_t mode); @@ -77,6 +78,7 @@ struct osi_funcs_t { /* Static variable declare */ static bool btdm_bb_init_flag = false; +static esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; static xTaskHandle btControllerTaskHandle; @@ -157,12 +159,18 @@ static void bt_controller_task(void *pvParam) btdm_osi_funcs_register(&osi_funcs); btdm_controller_init(); + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; + + /* Loop */ + btdm_controller_schedule(); } -static bool bb_inited; void esp_bt_controller_init() { - bb_inited = false; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); @@ -171,13 +179,17 @@ void esp_bt_controller_init() void esp_bt_controller_deinit(void) { vTaskDelete(btControllerTaskHandle); - bb_inited = false; + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; } esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) { int ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) { + return ESP_ERR_INVALID_STATE; + } + if (mode != ESP_BT_MODE_BTDM) { return ESP_ERR_INVALID_ARG; } @@ -194,6 +206,8 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_ERR_INVALID_STATE; } + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED; + return ESP_OK; } @@ -201,6 +215,10 @@ esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode) { int ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (mode != ESP_BT_MODE_BTDM) { return ESP_ERR_INVALID_ARG; } @@ -212,7 +230,14 @@ esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode) esp_phy_rf_deinit(); + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; + return ESP_OK; } +esp_bt_controller_status_t esp_bt_controller_get_status(void) +{ + return btdm_controller_status; +} + #endif diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index 91617a28f4..2c652466bd 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -33,6 +33,16 @@ typedef enum { ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ } esp_bt_mode_t; +/** + * @brief Bluetooth controller enable/disable/initialised/de-initialised status + */ +typedef enum { + ESP_BT_CONTROLLER_STATUS_IDLE = 0, + ESP_BT_CONTROLLER_STATUS_INITED, + ESP_BT_CONTROLLER_STATUS_ENABLED, + ESP_BT_CONTROLLER_STATUS_NUM, +} esp_bt_controller_status_t; + /** * @brief Initialize BT controller to allocate task and other resource. * @@ -52,6 +62,7 @@ void esp_bt_controller_deinit(void); * @brief Enable BT controller * @param mode : the mode(BLE/BT/BTDM) to enable. * Now only support BTDM. + * @return ESP_OK - success, other - failed */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); @@ -59,10 +70,15 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); * @brief Disable BT controller * @param mode : the mode(BLE/BT/BTDM) to disable. * Now only support BTDM. + * @return ESP_OK - success, other - failed */ esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode); - +/** + * @brief Get BT controller is initialised/de-initialised/enabled/disabled + * @return status value + */ +esp_bt_controller_status_t esp_bt_controller_get_status(void); /** @brief esp_vhci_host_callback * used for vhci call host function to notify what host need to do diff --git a/components/bt/lib b/components/bt/lib index 69616af765..dbac82b5c2 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 69616af7653f4de6e3b78f475dc10e73f0a20ece +Subproject commit dbac82b5c2694f2639161b0a2b3c0bd8c7d3efc5 diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 108a9f678d..9fc5910c25 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -49,6 +49,7 @@ Functions .. doxygenfunction:: esp_bt_controller_deinit .. doxygenfunction:: esp_bt_controller_enable .. doxygenfunction:: esp_bt_controller_disable +.. doxygenfunction:: esp_bt_controller_get_status .. doxygenfunction:: esp_vhci_host_check_send_available .. doxygenfunction:: esp_vhci_host_send_packet .. doxygenfunction:: esp_vhci_host_register_callback From a51f378ecc75e319bda4280673dfb2d031d1e846 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Tue, 21 Feb 2017 14:25:34 +0800 Subject: [PATCH 124/139] bugfix: it causes exception that wifi interrupt happens when read/write flash, if pp_post() is on icache. --- components/esp32/ld/esp32.common.ld | 1 + 1 file changed, 1 insertion(+) diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index 43775a6c49..bc28e5ca99 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -84,6 +84,7 @@ SECTIONS *libphy.a:(.literal .text .literal.* .text.*) *librtc.a:(.literal .text .literal.* .text.*) *librtc_clk.a:(.literal .text .literal.* .text.*) + *libpp.a:pp.o(.literal .text .literal.* .text.*) *libpp.a:lmac.o(.literal .text .literal.* .text.*) *libpp.a:wdev.o(.literal .text .literal.* .text.*) *libcore.a:ets_timer.o(.literal .text .literal.* .text.*) From 3b583c150f672f7414b9c35b84d219237a2d4afb Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 21 Feb 2017 12:10:49 +0800 Subject: [PATCH 125/139] bootloader: disconnect VRTC from SAR input in bootloader_random_disable Bootloader enables SAR ADC in test mode to get some entropy for the RNG. The bits which control the ADC test mux were not disabled, which caused extra ~24uA current to be drawn from VRTC, increasing deep sleep current consumption. This change disables relevant test mode bits in bootloader_random_disable. --- components/bootloader_support/src/bootloader_random.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/bootloader_support/src/bootloader_random.c b/components/bootloader_support/src/bootloader_random.c index b58ebe941d..5a00d0cf5a 100644 --- a/components/bootloader_support/src/bootloader_random.c +++ b/components/bootloader_support/src/bootloader_random.c @@ -135,4 +135,8 @@ void bootloader_random_disable(void) /* Reset i2s peripheral */ SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + + /* Disable pull supply voltage to SAR ADC */ + CLEAR_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC); + SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 0, RTC_CNTL_DTEST_RTC_S); } From d3fde5188e3df788764edf7317b10034a7c724d1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 21 Feb 2017 17:00:43 +0800 Subject: [PATCH 126/139] deep sleep: bring some registers into known state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case WiFi/BT stack has been enabled but wasn’t disabled, some RTC bits may be left enabled, causing increased current consumption. This change returns some of the bits back to their default values. --- components/esp32/deep_sleep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/esp32/deep_sleep.c b/components/esp32/deep_sleep.c index 3eef7ca29d..4d672402e1 100644 --- a/components/esp32/deep_sleep.c +++ b/components/esp32/deep_sleep.c @@ -22,6 +22,7 @@ #include "rom/uart.h" #include "soc/cpu.h" #include "soc/rtc_cntl_reg.h" +#include "soc/sens_reg.h" #include "soc/dport_reg.h" #include "driver/rtc_io.h" #include "freertos/FreeRTOS.h" @@ -111,6 +112,13 @@ void IRAM_ATTR esp_deep_sleep_start() // Decide which power domains can be powered down uint32_t pd_flags = get_power_down_flags(); + // Shut down parts of RTC which may have been left enabled by the wireless drivers + 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); + + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M, 0, SENS_FORCE_XPD_SAR_S); + // Configure pins for external wakeup if (s_config.wakeup_triggers & EXT_EVENT0_TRIG_EN) { ext0_wakeup_prepare(); From 26dec992eb4c23bae6c81df5948d3103ba8c2580 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 21 Feb 2017 12:29:25 +0800 Subject: [PATCH 127/139] deep sleep: add note about disabling WiFi and BT This change adds a note to esp_deep_sleep that applications should disable WiFi and BT before going into deep sleep. SNTP example is also updated. --- components/esp32/include/esp_deep_sleep.h | 8 ++++++++ examples/protocols/sntp/main/sntp_main.c | 2 ++ 2 files changed, 10 insertions(+) diff --git a/components/esp32/include/esp_deep_sleep.h b/components/esp32/include/esp_deep_sleep.h index a6251e2dec..aba74b30da 100644 --- a/components/esp32/include/esp_deep_sleep.h +++ b/components/esp32/include/esp_deep_sleep.h @@ -164,6 +164,14 @@ void esp_deep_sleep_start() __attribute__((noreturn)); * Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup * followed by a call to esp_deep_sleep_start. * + * esp_deep_sleep does not shut down WiFi, BT, and higher level protocol + * connections gracefully. + * Make sure relevant WiFi and BT stack functions are called to close any + * connections and deinitialize the peripherals. These include: + * - esp_bluedroid_disable + * - esp_bt_controller_disable + * - esp_wifi_stop + * * This function does not return. * * @param time_in_us deep-sleep time, unit: microsecond diff --git a/examples/protocols/sntp/main/sntp_main.c b/examples/protocols/sntp/main/sntp_main.c index f128323dcb..438505d7b6 100644 --- a/examples/protocols/sntp/main/sntp_main.c +++ b/examples/protocols/sntp/main/sntp_main.c @@ -110,6 +110,8 @@ static void obtain_time(void) time(&now); localtime_r(&now, &timeinfo); } + + ESP_ERROR_CHECK( esp_wifi_stop() ); } static void initialize_sntp(void) From 04f7d966232a3697691d065544e5784c2063cd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lourens=20Naud=C3=A9?= Date: Sun, 12 Feb 2017 22:59:09 +0000 Subject: [PATCH 128/139] Fix SPI read edges in spi_intr Signed-off-by: Jeroen Domburg --- components/driver/spi_master.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index f37f7aaf19..4f977c889e 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -625,9 +625,9 @@ static void IRAM_ATTR spi_intr(void *arg) } else { data=(uint32_t *)trans->tx_buffer; } - if (trans->rxlength < 8*32) { + if (trans->length < 8*32) { //No need for DMA. - for (int x=0; x < trans->rxlength; x+=32) { + for (int x=0; x < trans->length; x+=32) { //Use memcpy to get around alignment issues for txdata uint32_t word; memcpy(&word, &data[x/32], 4); @@ -656,7 +656,7 @@ static void IRAM_ATTR spi_intr(void *arg) host->hw->addr=trans->address & 0xffffffff; } host->hw->user.usr_mosi=(trans->tx_buffer==NULL)?0:1; - host->hw->user.usr_miso=(trans->tx_buffer==NULL)?0:1; + host->hw->user.usr_miso=(trans->rx_buffer==NULL)?0:1; //Call pre-transmission callback, if any if (dev->cfg.pre_cb) dev->cfg.pre_cb(trans); From e35ebbf813a24a1985469242a760f53f724801fa Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 21 Feb 2017 18:27:56 +0800 Subject: [PATCH 129/139] Use THRESH_DMA_TRANS define everywhere, make code match "smaller or equal" description --- components/driver/spi_master.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 4f977c889e..17a68c3235 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -600,7 +600,7 @@ static void IRAM_ATTR spi_intr(void *arg) } else { data=trans->rx_buffer; } - if (trans->rxlengthrxlength <= THRESH_DMA_TRANS) { //No need for DMA; we'll copy the result out of the work registers directly later. } else { host->hw->user.usr_miso_highpart=0; @@ -625,7 +625,7 @@ static void IRAM_ATTR spi_intr(void *arg) } else { data=(uint32_t *)trans->tx_buffer; } - if (trans->length < 8*32) { + if (trans->length <= THRESH_DMA_TRANS) { //No need for DMA. for (int x=0; x < trans->length; x+=32) { //Use memcpy to get around alignment issues for txdata From e76c187efb20facf8cad410aae5102a58d2e9145 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 21 Feb 2017 21:57:53 +0800 Subject: [PATCH 130/139] spi_flash: protect esp_intr_noniram_{disable,enable} in 1-core config MR !441 (7c155ab) has fixed issue with esp_intr_noniram_{disable,enable} calls not being properly protected by spi_flash_op_{lock,unlock}. Unit test was added, but the unit test environment tests only dual-core config. Similar issue was present in the code path for the single-core config, where esp_intr_noniram_{disable,enable} calls were unprotected. This change fixes the protection issue and updates the unit test to run properly in single core config as well. The issue with running unit tests for single core config will be addressed in a separate MR. --- components/spi_flash/cache_utils.c | 4 ++-- components/spi_flash/test/test_spi_flash.c | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index df9d18c443..5e880ab493 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -205,16 +205,16 @@ void spi_flash_op_unlock() void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() { - esp_intr_noniram_disable(); spi_flash_op_lock(); + esp_intr_noniram_disable(); spi_flash_disable_cache(0, &s_flash_op_cache_state[0]); } void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() { spi_flash_restore_cache(0, s_flash_op_cache_state[0]); - spi_flash_op_unlock(); esp_intr_noniram_enable(); + spi_flash_op_unlock(); } void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os() diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index 90d0cc1fdc..597568ec6a 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -65,19 +65,24 @@ static void flash_test_task(void *arg) TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash][ignore]") { SemaphoreHandle_t done = xSemaphoreCreateCounting(4, 0); - struct flash_test_ctx ctx[4] = { + struct flash_test_ctx ctx[] = { { .offset = 0x100 + 6, .done = done }, { .offset = 0x100 + 7, .done = done }, { .offset = 0x100 + 8, .done = done }, +#ifndef CONFIG_FREERTOS_UNICORE { .offset = 0x100 + 9, .done = done } +#endif }; - xTaskCreatePinnedToCore(flash_test_task, "1", 2048, &ctx[0], 3, NULL, 0); - xTaskCreatePinnedToCore(flash_test_task, "2", 2048, &ctx[1], 3, NULL, 1); - xTaskCreatePinnedToCore(flash_test_task, "3", 2048, &ctx[2], 3, NULL, tskNO_AFFINITY); - xTaskCreatePinnedToCore(flash_test_task, "4", 2048, &ctx[3], 3, NULL, tskNO_AFFINITY); + xTaskCreatePinnedToCore(flash_test_task, "t0", 2048, &ctx[0], 3, NULL, 0); + xTaskCreatePinnedToCore(flash_test_task, "t1", 2048, &ctx[1], 3, NULL, tskNO_AFFINITY); + xTaskCreatePinnedToCore(flash_test_task, "t2", 2048, &ctx[2], 3, NULL, tskNO_AFFINITY); +#ifndef CONFIG_FREERTOS_UNICORE + xTaskCreatePinnedToCore(flash_test_task, "t3", 2048, &ctx[3], 3, NULL, 1); +#endif - for (int i = 0; i < 4; ++i) { + const size_t task_count = sizeof(ctx)/sizeof(ctx[0]); + for (int i = 0; i < task_count; ++i) { xSemaphoreTake(done, portMAX_DELAY); TEST_ASSERT_FALSE(ctx[i].fail); } From e91d436e456553743dbd5d0fd6a89b71887ef4c0 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 3 Feb 2017 16:02:22 +1100 Subject: [PATCH 131/139] build system: Probable fix for errors due to bad config bypassing components See github #311 https://github.com/espressif/esp-idf/issues/311 Should fix weird compiler/linker bugs where config says something is enabled, but build system says it is disabled. Particularly noticeable when WiFi/BT libraries fail to compile/link despite being enabled. Underlying cause is configuration file regenerating, but component Makefiles not reevaluating. Entirely removes the idea that we don't need to generate config for some targets (like 'clean'). We need valid config for these targets, otherwise they don't know which files to clean (etc). --- make/common.mk | 4 ++-- make/project.mk | 7 +------ make/project_config.mk | 19 ++----------------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/make/common.mk b/make/common.mk index 605b8ab862..d19f7eb46c 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,8 +6,8 @@ # # (Note that we only rebuild this makefile automatically for some # targets, see project_config.mk for details.) -SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) --include $(SDKCONFIG_MAKEFILE) +SDKCONFIG_MAKEFILE ?= $(BUILD_DIR_BASE)/include/config/auto.conf +include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path #Handling of V=1/VERBOSE=1 flag diff --git a/make/project.mk b/make/project.mk index bebb1fc7d4..02ef7bb174 100644 --- a/make/project.mk +++ b/make/project.mk @@ -370,12 +370,7 @@ $(BUILD_DIR_BASE)/$(2)/lib$(2).a: $(2)-build # If any component_project_vars.mk file is out of date, the make # process will call this target to rebuild it and then restart. # -# Note: $(SDKCONFIG) is a normal prereq as we need to rebuild these -# files whenever the config changes. $(SDKCONFIG_MAKEFILE) is an -# order-only prereq because if it hasn't been rebuilt, we need to -# build it first - but including it as a normal prereq can lead to -# infinite restarts as the conf process will keep updating it. -$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) $(SDKCONFIG_MAKEFILE) +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG_MAKEFILE) | $(BUILD_DIR_BASE)/$(2) $(call ComponentMake,$(1),$(2)) component_project_vars.mk endef diff --git a/make/project_config.mk b/make/project_config.mk index 011aa1ff0e..d33ae11969 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -48,26 +48,11 @@ endif mkdir -p $(BUILD_DIR_BASE)/include/config $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig -# Work out of whether we have to build the Kconfig makefile -# (auto.conf), or if we're in a situation where we don't need it -NON_CONFIG_TARGETS := clean %-clean help menuconfig defconfig -AUTO_CONF_REGEN_TARGET := $(SDKCONFIG_MAKEFILE) - -# disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets -# (and not building default target) -ifneq ("$(MAKECMDGOALS)","") -ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS)) -AUTO_CONF_REGEN_TARGET := -# dummy target -$(SDKCONFIG_MAKEFILE): -endif -endif - -$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG mkdir -p $(BUILD_DIR_BASE)/include/config cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h + touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) From 3c900323692704b2b860feb23b1f14e2023ad096 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 6 Feb 2017 17:02:07 +1100 Subject: [PATCH 132/139] build system: Fix parallel & double menuconfig issues when sdkconfig missing Fixes misbehaviour of default menuconfig when sdkconfig is missing. (Either appearing twice, or breaking if make -jN is used.) --- make/common.mk | 2 +- make/project_config.mk | 70 +++++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/make/common.mk b/make/common.mk index d19f7eb46c..4281bad94b 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,7 +6,7 @@ # # (Note that we only rebuild this makefile automatically for some # targets, see project_config.mk for details.) -SDKCONFIG_MAKEFILE ?= $(BUILD_DIR_BASE)/include/config/auto.conf +SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path diff --git a/make/project_config.mk b/make/project_config.mk index d33ae11969..3537f786ba 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -20,44 +20,66 @@ $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \ $(MAKE) -C $(KCONFIG_TOOL_DIR) -# use a wrapper environment for where we run Kconfig tools -KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" - -menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(call prereq_if_explicit,defconfig) - $(summary) MENUCONFIG - $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig - ifeq ("$(wildcard $(SDKCONFIG))","") -ifeq ("$(call prereq_if_explicit,defconfig)","") -# if not configuration is present and defconfig is not a target, run defconfig then menuconfig -$(SDKCONFIG): defconfig menuconfig +ifeq ("$(filter defconfig, $(MAKECMDGOALS))","") +# if no configuration file is present and defconfig is not a named +# target, run defconfig then menuconfig to get the initial config +$(SDKCONFIG): menuconfig +menuconfig: defconfig else -# otherwise, just defconfig +# otherwise, just run defconfig $(SDKCONFIG): defconfig endif endif +# macro for the commands to run kconfig tools conf or mconf. +# $1 is the name (& args) of the conf tool to run +define RunConf + mkdir -p $(BUILD_DIR_BASE)/include/config + cd $(BUILD_DIR_BASE); KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ + COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ + COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ + $(KCONFIG_TOOL_DIR)/$1 $(IDF_PATH)/Kconfig +endef + +ifeq ("$(MAKE_RESTARTS)","") +# menuconfig, defconfig and "GENCONFIG" configuration generation only +# ever run on the first make pass, subsequent passes don't run these +# (make often wants to re-run them as the conf tool can regenerate the +# sdkconfig input file as an output file, but this is not what the +# user wants - a single config pass is enough to produce all output +# files.) +# +# To prevent problems missing genconfig, ensure none of these targets +# depend on any prerequisite that may cause a make restart as part of +# the prerequisite's own recipe. + +menuconfig: $(KCONFIG_TOOL_DIR)/mconf + $(summary) MENUCONFIG + $(call RunConf,mconf) + # defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present -defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) +defconfig: $(KCONFIG_TOOL_DIR)/conf $(summary) DEFCONFIG ifneq ("$(wildcard $(SDKCONFIG_DEFAULTS))","") cat $(SDKCONFIG_DEFAULTS) >> $(SDKCONFIG) # append defaults to sdkconfig, will override existing values endif - mkdir -p $(BUILD_DIR_BASE)/include/config - $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + $(call RunConf,conf --olddefconfig) -$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to +# ensure generated config files are up to date +$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(KCONFIG_TOOL_DIR)/conf $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig) $(summary) GENCONFIG - mkdir -p $(BUILD_DIR_BASE)/include/config - cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h -# touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, -# sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer -# than the target(!) + $(call RunConf,conf --silentoldconfig) + touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig -.PHONY: config-clean +else # "$(MAKE_RESTARTS)" != "" +# on subsequent make passes, skip config generation entirely +defconfig: +menuconfig: +endif + +.PHONY: config-clean defconfig menuconfig config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean From c3544dc0901222dd13fa95690ca7cb12aed62a07 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 6 Feb 2017 17:12:16 +1100 Subject: [PATCH 133/139] Build system: Fix error if librtc submodule not available to bootloader Closes #220 https://github.com/espressif/esp-idf/issues/220 --- components/bootloader/src/main/Makefile.projbuild | 4 ++++ components/bootloader/src/main/component.mk | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 components/bootloader/src/main/Makefile.projbuild diff --git a/components/bootloader/src/main/Makefile.projbuild b/components/bootloader/src/main/Makefile.projbuild new file mode 100644 index 0000000000..c368c68416 --- /dev/null +++ b/components/bootloader/src/main/Makefile.projbuild @@ -0,0 +1,4 @@ +# Submodules normally added in component.mk, but fully qualified +# paths can be added at this level (we need binary librtc to be +# available to link bootloader). +COMPONENT_SUBMODULES += $(IDF_PATH)/components/esp32/lib diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 2069665d1a..12fdf8efa0 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -14,10 +14,10 @@ COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SC COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS) -ifdef IS_BOOTLOADER_BUILD # following lines are a workaround to link librtc into the # bootloader, until clock setting code is in a source-based esp-idf # component. See also rtc_printf() in bootloader_start.c +# +# See also matching COMPONENT_SUBMODULES line in Makefile.projbuild COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc_clk -lrtc COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/ -endif From d28ee9a25ed504ebf4cdbfc13b6aed00ea766cc9 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 4 Jan 2017 12:36:59 +1100 Subject: [PATCH 134/139] build system: Account for Windows behaviour of make wildcard for some dirs See github #166 --- make/project.mk | 15 ++++++++++++--- tools/windows/eclipse_make.sh | 5 +++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/make/project.mk b/make/project.mk index 02ef7bb174..04015a8a8c 100644 --- a/make/project.mk +++ b/make/project.mk @@ -49,14 +49,23 @@ endif # make IDF_PATH a "real" absolute path # * works around the case where a shell character is embedded in the environment variable value. # * changes Windows-style C:/blah/ paths to MSYS/Cygwin style /c/blah -export IDF_PATH:=$(realpath $(wildcard $(IDF_PATH))) +ifeq ("$(OS)","Windows_NT") +# On Windows MSYS2, make wildcard function returns empty string for paths of form /xyz +# where /xyz is a directory inside the MSYS root - so we don't use it. +SANITISED_IDF_PATH:=$(realpath $(IDF_PATH)) +else +SANITISED_IDF_PATH:=$(realpath $(wildcard $(IDF_PATH))) +endif + +export IDF_PATH := $(SANITISED_IDF_PATH) ifndef IDF_PATH $(error IDF_PATH variable is not set to a valid directory.) endif -ifneq ("$(IDF_PATH)","$(realpath $(wildcard $(IDF_PATH)))") -# due to the way make manages variables, this is hard to account for +ifneq ("$(IDF_PATH)","$(SANITISED_IDF_PATH)") +# implies IDF_PATH was overriden on make command line. +# Due to the way make manages variables, this is hard to account for # # if you see this error, do the shell expansion in the shell ie # make IDF_PATH=~/blah not make IDF_PATH="~/blah" diff --git a/tools/windows/eclipse_make.sh b/tools/windows/eclipse_make.sh index 200d798ffa..848705fba4 100755 --- a/tools/windows/eclipse_make.sh +++ b/tools/windows/eclipse_make.sh @@ -4,6 +4,7 @@ # Eclipse's output parser expects to see output of the form C:/dir/dir/file but our Make # process uses MinGW paths of the form /c/dir/dir/file. So parse these out... # -# (regexp deliberate only matches after a space character to try and avoid false-positives.) +# A little hacky as it looks for any single character of form /X/something. +# echo "Running make in $(pwd)" -make $@ V=1 | sed -E "s@ /([a-z])/(.+)/@ \1:/\2/@g" | sed -E "s@-I/([a-z])/(.+)/@-I\1:/\2/@g" | sed -E "s@-L/([a-z])/(.+)/@-L\1:/\2/@g" +make $@ V=1 | sed -E "s@/([a-z])/([^/+])@\1:/\2@g" From 8dede8f8a46f42661665e9b924b7f455d06ef00a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 7 Feb 2017 14:21:58 +1100 Subject: [PATCH 135/139] Eclipse: Process Windows paths correctly using cygpath Includes splitting the Windows Eclipse setup doc into a separate page, as it has so many additional steps. Addresses github #17 and #166 https://github.com/espressif/esp-idf/issues/17 https://github.com/espressif/esp-idf/issues/166 --- docs/eclipse-setup-windows.rst | 77 ++++++++++++++++++++++++++++++++++ docs/eclipse-setup.rst | 42 ++++++++++++------- tools/windows/eclipse_make.py | 36 ++++++++++++++++ tools/windows/eclipse_make.sh | 12 ++---- 4 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 docs/eclipse-setup-windows.rst create mode 100644 tools/windows/eclipse_make.py diff --git a/docs/eclipse-setup-windows.rst b/docs/eclipse-setup-windows.rst new file mode 100644 index 0000000000..4cf8fe5fb5 --- /dev/null +++ b/docs/eclipse-setup-windows.rst @@ -0,0 +1,77 @@ +Eclipse IDE on Windows +********************** + +Configuring Eclipse on Windows requires some different steps. The full configuration steps for Windows are shown below. + +(For OS X and Linux instructions, see the :doc:`Eclipse IDE page `.) + +Installing Eclipse IDE +====================== + +Follow the steps under :ref:`Installing Eclipse IDE ` for all platforms. + +.. _eclipse-windows-setup: + +Setting up Eclipse on Windows +============================= + +Once your new Eclipse installation launches, follow these steps: + +Import New Project +------------------ + +* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the idf-template project from github, or open one of the examples in the esp-idf examples subdirectory. + +* Once Eclipse is running, choose File -> Import... + +* In the dialog that pops up, choose "C/C++" -> "Existing Code as Makefile Project" and click Next. + +* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself (that comes later). The directory you specify should contain a file named "Makefile" (the project Makefile). + +* On the same page, under "Toolchain for Indexer Settings" uncheck "Show only available toolchains that support this platform". + +* On the extended list that appears, choose "Cygwin GCC". Then click Finish. + +*Note: you may see warnings in the UI that Cygwin GCC Toolchain could not be found. This is OK, we're going to reconfigure Eclipse to find our toolchain.* + +Project Properties +------------------ + +* The new project will appear under Project Explorer. Right-click the project and choose Properties from the context menu. + +* Click on the "C/C++ Build" properties page (top-level): + + * Uncheck "Use default build command" and enter this for the custom build command: ``python ${IDF_PATH}/tools/windows/eclipse_make.py``. + +* Click on the "Environment" properties page under "C/C++ Build": + + * Click "Add..." and enter name ``V`` and value ``1``. + + * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. The IDF_PATH directory should be specified using forwards slashes not backslashes, ie *C:/Users/MyUser/Development/esp-idf*. + + * Edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match). + +* Click on "C/C++ General" -> "Preprocessor Include Paths, Macros,etc." property page: + + * Click the "Providers" tab + + * In the list of providers, click "CDT GCC Built-in Compiler Settings Cygwin". Under "Command to get compiler specs", replace the text ``${COMMAND}`` at the beginning of the line with ``xtensa-esp32-elf-gcc``. This means the full "Command to get compiler specs" should be ``xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"``. + + * In the list of providers, click "CDT GCC Build Output Parser" and type ``xtensa-esp32-elf-`` at the beginning of the Compiler command pattern. This means the full Compiler command pattern should be ``xtensa-esp32-elf-(g?cc)|([gc]\+\+)|(clang)`` + + +Building in Eclipse +------------------- + +Continue from :ref:`Building in Eclipse ` for all platforms. + +Technical Details +================= + +**Of interest to Windows gurus or very curious parties, only.** + +Explanations of the technical reasons for some of these steps. You don't need to know this in order to use esp-idf with Eclipse on Windows, but it may be helpful background knowledge if you plan to do dig into the Eclipse support: + +* The xtensa-esp32-elf-gcc cross-compiler is *not* a Cygwin toolchain, even though we tell Eclipse that it is one. This is because msys2 uses Cygwin and supports Cygwin paths (of the type ``/c/blah`` instead of ``c:/blah`` or ``c:\\blah``). In particular, xtensa-esp32-elf-gcc reports to the Eclipse "built-in compiler settings" function that its built-in include directories are all under ``/usr/``, which is a Unix/Cygwin-style path that Eclipse otherwise can't resolve. By telling Eclipse the compiler is Cygwin, it resolves these paths internally using the ``cygpath`` utility. + +* The same problem occurs when parsing make output from esp-idf. Eclipse parses this output to find header directories, but it can't resolve include directories of the form ``/c/blah`` without using ``cygpath``. There is a heuristic that Eclipse Build Output Parser uses to determine whether it should call ``cygpath``, but for currently unknown reasons the esp-idf configuration doesn't trigger it. For this reason the ``eclipse_make.py`` wrapper script is used to call ``make`` and then use ``cygpath`` to process the output for Eclipse. diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index fbad93be6c..1716dbf167 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -1,6 +1,8 @@ Build and Flash with Eclipse IDE ******************************** +.. _eclipse-install-steps: + Installing Eclipse IDE ====================== @@ -8,10 +10,17 @@ The Eclipse IDE gives you a graphical integrated development environment for wri * Start by installing the esp-idf for your platform (see files in this directory with steps for Windows, OS X, Linux). +* We suggest building a project from the command line first, to get a feel for how that process works. You also need to use the command line to configure your esp-idf project (via ``make menuconfig``), this is not currently supported inside Eclipse. + * Download the Eclipse Installer for your platform from eclipse.org_. * When running the Eclipse Installer, choose "Eclipse for C/C++ Development" (in other places you'll see this referred to as CDT.) +Windows Users +============= + +Using ESP-IDF with Eclipse on Windows requires different configuration steps. :ref:`See the Eclipse IDE on Windows guide `. + Setting up Eclipse ================== @@ -20,13 +29,13 @@ Once your new Eclipse installation launches, follow these steps: Import New Project ------------------ -* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the skeleton project from github. +* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the idf-template project from github, or open one of the examples in the esp-idf examples subdirectory. * Once Eclipse is running, choose File -> Import... * In the dialog that pops up, choose "C/C++" -> "Existing Code as Makefile Project" and click Next. -* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself. +* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself (that comes later). The directory you specify should contain a file named "Makefile" (the project Makefile). * On the same page, under "Toolchain for Indexer Settings" choose "Cross GCC". Then click Finish. @@ -38,13 +47,7 @@ Project Properties * Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``V`` and value ``1``. -* Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. *Windows users: Use forward-slashes not backslashes for this path, ie C:/Users/MyUser/Development/esp-idf*. - -*Windows users only, follow these two additional steps:* - -* On the same Environment property page, edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match). - -* Click on the "C/C++ Build" top-level properties page then uncheck "Use default build command" and enter this for the custom build command: ``bash ${IDF_PATH}/tools/windows/eclipse_make.sh``. +* Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. *All users, continue with these steps:* @@ -56,7 +59,22 @@ Navigate to "C/C++ General" -> "Preprocessor Include Paths" property page: * In the list of providers, click "CDT GCC Build Output Parser" and type ``xtensa-esp32-elf-`` at the beginning of the Compiler command pattern. This means the full Compiler command pattern should be ``xtensa-esp32-elf-(g?cc)|([gc]\+\+)|(clang)`` -* Click OK to close the Properties dialog, and choose Project -> Build to build your project. +.. _eclipse-build-project: + +Building in Eclipse +------------------- + +Before your project is first built, Eclipse may show a lot of errors and warnings about undefined values. This is because some source files are automatically generated as part of the esp-idf build process. These errors and warnings will go away after you build the project. + +* Click OK to close the Properties dialog in Eclipse. + +* Outside Eclipse, open a command line prompt. Navigate to your project directory, and run ``make menuconfig`` to configure your project's esp-idf settings. This step currently has to be run outside Eclipse. + +*If you try to build without running a configuration step first, esp-idf will prompt for configuration on the command line - but Eclipse is not able to deal with this, so the build will hang or fail.* + +* Back in Eclipse, choose Project -> Build to build your project. + +**TIP**: If your project had already been built outside Eclipse, you may need to do a Project -> Clean before chosing Project -> Build. This is so Eclipse can see the compiler arguments for all source files. It uses these to determine the header include paths. Flash from Eclipse ------------------ @@ -77,7 +95,3 @@ Follow the same steps to add ``bootloader`` and ``partition_table`` targets, if .. _eclipse.org: http://www.eclipse.org/ -Eclipse Troubleshooting ------------------------ - -* ``*** Make was invoked from ... However please do not run make from the sdk or a component directory; ...`` - Eclipse will detect any directory with a Makefile in it as being a possible directory to run "make" in. All component directories also contain a Makefile (the wrong one), so it is important when using Project -> Make Target to always select the top-level project directory in Project Explorer. diff --git a/tools/windows/eclipse_make.py b/tools/windows/eclipse_make.py new file mode 100644 index 0000000000..572e171e26 --- /dev/null +++ b/tools/windows/eclipse_make.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# +# Wrapper to run make and preprocess any paths in the output from MSYS/Cygwin paths +# to Windows paths, for Eclipse +from __future__ import print_function, division +import sys, subprocess, os.path, re + +UNIX_PATH_RE = re.compile(r'(/[^ \'"]+)+') + +paths = {} +def check_path(path): + try: + return paths[path] + except KeyError: + pass + paths[path] = path # cache as failed, replace with success if it works + try: + winpath = subprocess.check_output(["cygpath", "-w", path]).strip() + except subprocess.CalledProcessError: + return path # something went wrong running cygpath, assume this is not a path! + if not os.path.exists(winpath): + return path # not actually a valid path + winpath = winpath.replace("\\", "/") # make consistent with forward-slashes used elsewhere + paths[path] = winpath + return winpath + +def main(): + print("Running make in '%s'" % check_path(os.getcwd())) + make = subprocess.Popen(["make"] + sys.argv[1:] + ["V=1"], stdout=subprocess.PIPE) + for line in iter(make.stdout.readline, ''): + line = re.sub(UNIX_PATH_RE, lambda m: check_path(m.group(0)), line) + print(line.rstrip()) + sys.exit(make.wait()) + +if __name__ == "__main__": + main() diff --git a/tools/windows/eclipse_make.sh b/tools/windows/eclipse_make.sh index 848705fba4..769bca2695 100755 --- a/tools/windows/eclipse_make.sh +++ b/tools/windows/eclipse_make.sh @@ -1,10 +1,4 @@ #!/bin/bash -# A wrapper for make on Windows with Eclipse -# -# Eclipse's output parser expects to see output of the form C:/dir/dir/file but our Make -# process uses MinGW paths of the form /c/dir/dir/file. So parse these out... -# -# A little hacky as it looks for any single character of form /X/something. -# -echo "Running make in $(pwd)" -make $@ V=1 | sed -E "s@/([a-z])/([^/+])@\1:/\2@g" +echo "eclipse_make.sh has been replaced with eclipse_make.py. Check the Windows Eclipse docs for the new command." +echo "This shell script will continue to work until the next major release." +python ${IDF_PATH}/tools/windows/eclipse_make.py $@ From c0f155f6ff58376c8b17051b24e1a478c058eefe Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 7 Feb 2017 14:28:23 +1100 Subject: [PATCH 136/139] kconfig: Ignore Windows host-compiled executables --- tools/kconfig/.gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/kconfig/.gitignore b/tools/kconfig/.gitignore index be603c4fef..977c274ce3 100644 --- a/tools/kconfig/.gitignore +++ b/tools/kconfig/.gitignore @@ -20,3 +20,11 @@ nconf qconf gconf kxgettext + +# configuration programs, Windows +conf.exe +mconf.exe +nconf.exe +qconf.exe +gconf.exe +kxgettext.exe From f29768c404cf7d6eab618002b42d5cb9e67f4e52 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 10 Feb 2017 17:38:24 +1100 Subject: [PATCH 137/139] Build system: Add new BATCH_BUILD flag to disable interactive parts of the build Mostly useful for Eclipse (where accidentally running interactive config hangs the build), but also good for CI and other automated build systems. --- .gitlab-ci.yml | 6 +++--- docs/build-system.rst | 11 +++++++++++ docs/eclipse-setup-windows.rst | 2 +- docs/eclipse-setup.rst | 2 +- make/build_examples.sh | 5 ++++- make/common.mk | 5 +++++ make/project_config.mk | 11 +++++++++++ tools/windows/eclipse_make.py | 2 +- 8 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8ea64e142b..96bc56e3e6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,6 +31,7 @@ build_template_app: SDK_PATH: "$CI_PROJECT_DIR" IDF_PATH: "$CI_PROJECT_DIR" GIT_STRATEGY: clone + BATCH_BUILD: "1" script: - git clone https://github.com/espressif/esp-idf-template.git @@ -39,13 +40,11 @@ build_template_app: # using on esp-idf. If it doesn't exist then just stick to the default # branch - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." - - make defconfig # Test debug build (default) - make all V=1 # Now test release build - make clean - sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig - - make defconfig - make all V=1 # Check if there are any stray printf/ets_printf references in WiFi libs - cd ../components/esp32/lib @@ -63,6 +62,8 @@ build_template_app: SDK_PATH: "$CI_PROJECT_DIR" IDF_PATH: "$CI_PROJECT_DIR" GIT_STRATEGY: clone + BATCH_BUILD: "1" + build_ssc: <<: *build_template @@ -103,7 +104,6 @@ build_esp_idf_tests: script: - cd tools/unit-test-app - git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..." - - make defconfig - make TESTS_ALL=1 - python UnitTestParser.py diff --git a/docs/build-system.rst b/docs/build-system.rst index 0973eeb31f..b3abbd28f5 100644 --- a/docs/build-system.rst +++ b/docs/build-system.rst @@ -305,6 +305,17 @@ Second Level: Component Makefiles To better understand the component make process, have a read through the ``component_wrapper.mk`` file and some of the ``component.mk`` files included with esp-idf. +Running Make Non-Interactively +------------------------------ + +When running ``make`` in a situation where you don't want interactive prompts (for example: inside an IDE or an automated build system) append ``BATCH_BUILD=1`` to the make arguments (or set it as an environment variable). + +Setting ``BATCH_BUILD`` implies the following: + +- Verbose output (same as ``V=1``, see below). If you don't want verbose output, also set ``V=0``. +- If the project configuration is missing new configuration items (from new components or esp-idf updates) then the project use the default values, instead of prompting the user for each item. +- If the build system needs to invoke ``menuconfig``, an error is printed and the build fails. + Debugging The Make Process -------------------------- diff --git a/docs/eclipse-setup-windows.rst b/docs/eclipse-setup-windows.rst index 4cf8fe5fb5..aeb011c0c1 100644 --- a/docs/eclipse-setup-windows.rst +++ b/docs/eclipse-setup-windows.rst @@ -45,7 +45,7 @@ Project Properties * Click on the "Environment" properties page under "C/C++ Build": - * Click "Add..." and enter name ``V`` and value ``1``. + * Click "Add..." and enter name ``BATCH_BUILD`` and value ``1``. * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. The IDF_PATH directory should be specified using forwards slashes not backslashes, ie *C:/Users/MyUser/Development/esp-idf*. diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index 1716dbf167..140e81e173 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -45,7 +45,7 @@ Project Properties * The new project will appear under Project Explorer. Right-click the project and choose Properties from the context menu. -* Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``V`` and value ``1``. +* Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``BATCH_BUILD`` and value ``1``. * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. diff --git a/make/build_examples.sh b/make/build_examples.sh index e85ec26a70..ee429309e1 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -9,6 +9,9 @@ # [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set" && exit 1 +export BATCH_BUILD=1 +export V=0 # only build verbose if there's an error + EXAMPLE_NUM=1 RESULT=0 FAILED_EXAMPLES="" @@ -36,7 +39,7 @@ for category in ${IDF_PATH}/examples/*; do set -e make clean defconfig make $* all 2>&1 | tee $BUILDLOG - ) || { RESULT=$?; FAILED_EXAMPLES+=" ${example}"; make V=1; } # only build verbose if there's an error + ) || { RESULT=$?; FAILED_EXAMPLES+=" ${example}"; make V=1; } # verbose output for errors popd EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) diff --git a/make/common.mk b/make/common.mk index 4281bad94b..41a87b3a64 100644 --- a/make/common.mk +++ b/make/common.mk @@ -10,6 +10,11 @@ SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path +# BATCH_BUILD flag disables interactive terminal features, defaults to verbose build +ifdef BATCH_BUILD +V ?= 1 +endif + #Handling of V=1/VERBOSE=1 flag # # if V=1, $(summary) does nothing and $(details) will echo extra details diff --git a/make/project_config.mk b/make/project_config.mk index 3537f786ba..c0369f95f8 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -56,7 +56,15 @@ ifeq ("$(MAKE_RESTARTS)","") menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(summary) MENUCONFIG +ifdef BATCH_BUILD + @echo "Can't run interactive configuration inside non-interactive build process." + @echo "" + @echo "Open a command line terminal and run 'make menuconfig' from there." + @echo "See esp-idf documentation for more details." + @exit 1 +else $(call RunConf,mconf) +endif # defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present defconfig: $(KCONFIG_TOOL_DIR)/conf @@ -70,6 +78,9 @@ endif # ensure generated config files are up to date $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(KCONFIG_TOOL_DIR)/conf $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig) $(summary) GENCONFIG +ifdef BATCH_BUILD # can't prompt for new config values like on terminal + $(call RunConf,conf --olddefconfig) +endif $(call RunConf,conf --silentoldconfig) touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig diff --git a/tools/windows/eclipse_make.py b/tools/windows/eclipse_make.py index 572e171e26..e65cfc9cc3 100644 --- a/tools/windows/eclipse_make.py +++ b/tools/windows/eclipse_make.py @@ -26,7 +26,7 @@ def check_path(path): def main(): print("Running make in '%s'" % check_path(os.getcwd())) - make = subprocess.Popen(["make"] + sys.argv[1:] + ["V=1"], stdout=subprocess.PIPE) + make = subprocess.Popen(["make"] + sys.argv[1:] + ["BATCH_BUILD=1"], stdout=subprocess.PIPE) for line in iter(make.stdout.readline, ''): line = re.sub(UNIX_PATH_RE, lambda m: check_path(m.group(0)), line) print(line.rstrip()) From cbb71baca96d5f4c22be017dafef8d745834dac5 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 22 Feb 2017 12:51:16 +0800 Subject: [PATCH 138/139] spi_flash: protect spi_flash_unlock spi_flash_unlock was missing spi_flash_guard_start, which caused cache to be enabled during unlock operation, causing hard-to-trace crashes and cache data corruption. --- components/spi_flash/flash_ops.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 3581b34141..324c02a3d0 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -202,7 +202,9 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size) size_t mid_size = (size - left_size) & ~3U; size_t right_off = left_size + mid_size; size_t right_size = size - mid_size - left_size; + spi_flash_guard_start(); rc = spi_flash_unlock(); + spi_flash_guard_end(); if (rc != SPI_FLASH_RESULT_OK) { goto out; } @@ -289,7 +291,9 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, COUNTER_START(); spi_flash_disable_interrupts_caches_and_other_cpu(); SpiFlashOpResult rc; + spi_flash_guard_start(); rc = spi_flash_unlock(); + spi_flash_guard_end(); spi_flash_enable_interrupts_caches_and_other_cpu(); if (rc == SPI_FLASH_RESULT_OK) { From ce7d0a70150a7b0caf0df026c5ef0305ec39f435 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 22 Feb 2017 17:04:51 +0800 Subject: [PATCH 139/139] Fixed a small bug where a task could initially be scheduled on a wrong CPU, and a much bigger bug where a yield was performed with a held mux. --- components/freertos/tasks.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 02d1842874..0804bb3eb5 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -1056,11 +1056,15 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode taskENTER_CRITICAL(&xTaskQueueMutex); { uxCurrentNumberOfTasks++; - if( pxCurrentTCB[ xPortGetCoreID() ] == NULL ) + //If the task has no affinity and nothing is scheduled on this core, just throw it this core. + //If it has affinity, throw it on the core that needs it if nothing is already scheduled there. + BaseType_t xMyCore = xCoreID; + if ( xMyCore == tskNO_AFFINITY) xMyCore = xPortGetCoreID(); + if( pxCurrentTCB[ xMyCore ] == NULL ) { /* There are no other tasks, or all the other tasks are in the suspended state - make this the current task. */ - pxCurrentTCB[ xPortGetCoreID() ] = pxNewTCB; + pxCurrentTCB[ xMyCore ] = pxNewTCB; if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) { @@ -1121,12 +1125,13 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode portSETUP_TCB( pxNewTCB ); } - curTCB = pxCurrentTCB[ xPortGetCoreID() ]; + taskEXIT_CRITICAL(&xTaskQueueMutex); if( xSchedulerRunning != pdFALSE ) { taskENTER_CRITICAL(&xTaskQueueMutex); + curTCB = pxCurrentTCB[ xPortGetCoreID() ]; /* Scheduler is running. If the created task is of a higher priority than an executing task then it should run now. ToDo: This only works for the current core. If a task is scheduled on an other processor, @@ -1141,7 +1146,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode */ if( tskCAN_RUN_HERE( xCoreID ) && curTCB->uxPriority < pxNewTCB->uxPriority ) { - taskYIELD_IF_USING_PREEMPTION(); + taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex); } else if( xCoreID != xPortGetCoreID() ) { taskYIELD_OTHER_CORE(xCoreID, pxNewTCB->uxPriority); @@ -2659,11 +2664,13 @@ BaseType_t xSwitchRequired = pdFALSE; void vTaskSwitchContext( void ) { - tskTCB * pxTCB; - //This can be called both from IRQ as well as normal context, so we can't - //use taskENTER_CRITICAL() here. Instead, save the irq status and disable - //IRQs, so we can use taskENTER_CRITICAL_ISR and friends. + //Note: This can be called from interrupt context as well as from non-interrupt context (voluntary yield). The + //taskENTER_CRITICAL/taskEXIT_CRITICAL is modified to work in both scenarios for the ESP32, so we can freely use + //them here. However, in case of a voluntary yield, a nonvoluntary yield can still happen *during* the voluntary + //yield. Disabling interrupts using portENTER_CRITICAL_NESTED puts a stop to this and makes the rest of the code a + //bit neater. int irqstate=portENTER_CRITICAL_NESTED(); + tskTCB * pxTCB; if( uxSchedulerSuspended[ xPortGetCoreID() ] != ( UBaseType_t ) pdFALSE ) { /* The scheduler is currently suspended - do not allow a context