From 22c38771837ce8be8208d40fafbdc1d35c055a56 Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Thu, 26 Jan 2017 01:47:53 +0000 Subject: [PATCH 01/24] 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 24cfe78962887b85f49c56eea8d7a9f127805900 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 15 Feb 2017 10:28:45 +1100 Subject: [PATCH 02/24] 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 abf87b000d3ae6af326b2cbbd39dbac7b61645b8 Mon Sep 17 00:00:00 2001 From: Yulong Date: Mon, 20 Feb 2017 08:50:02 -0500 Subject: [PATCH 03/24] component/bt:fixed the write ccc crash bug error --- components/bt/bluedroid/stack/gatt/gatt_db.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index 03919d483c..bb9bfc5f72 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -597,11 +597,14 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, } p_char_dscptr->p_value->attr_val.attr_len = attr_val->attr_len; p_char_dscptr->p_value->attr_val.attr_max_len = attr_val->attr_max_len; - if (attr_val->attr_val != NULL) { + if (attr_val->attr_max_len != 0) { p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len); if (p_char_dscptr->p_value->attr_val.attr_val != NULL) { memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); - memcpy(p_char_dscptr->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len); + if(attr_val->attr_val != NULL) { + memcpy(p_char_dscptr->p_value->attr_val.attr_val, + attr_val->attr_val, attr_val->attr_len); + } } } } @@ -873,7 +876,7 @@ tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db, } if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >= - offset + len)) { + offset + len) && p_attr->p_value->attr_val.attr_val != NULL) { memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len); p_attr->p_value->attr_val.attr_len = len + offset; return GATT_SUCCESS; From a51f378ecc75e319bda4280673dfb2d031d1e846 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Tue, 21 Feb 2017 14:25:34 +0800 Subject: [PATCH 04/24] 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 05/24] 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 06/24] 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 07/24] 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 55693b1168d4d6f9b97445b92dedb066599fe133 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Tue, 21 Feb 2017 17:46:59 +0800 Subject: [PATCH 08/24] component/bt : add option to release about 30K from BT if BLE only 1. later BT/BLE will be separated by BT/BLE macro, but this option should use when user make sure that in BLE only mode. --- components/bt/Kconfig | 9 +++++++++ components/bt/bt.c | 23 +++++++++++++++++++++-- components/bt/lib | 2 +- components/esp32/heap_alloc_caps.c | 6 ++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/components/bt/Kconfig b/components/bt/Kconfig index d2227868ce..63dce8d1f9 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -17,6 +17,15 @@ config BLUEDROID_MEM_DEBUG help Bluedroid memory debug +config BT_DRAM_RELEASE + bool "Release DRAM from Classic BT controller" + depends on BT_ENABLED + default n + help + This option should only be used when BLE only. + Open this option will release about 30K DRAM from Classic BT. + The released DRAM will be used as system heap memory. + # Memory reserved at start of DRAM for Bluetooth stack config BT_RESERVE_DRAM hex diff --git a/components/bt/bt.c b/components/bt/bt.c index 6a81d11acc..4943b9acbf 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -32,9 +32,14 @@ #if CONFIG_BT_ENABLED +/* Bluetooth system and controller config */ +#define BTDM_CFG_BT_EM_RELEASE (1<<0) +#define BTDM_CFG_BT_DATA_RELEASE (1<<1) +/* Other reserved for future */ + /* 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_init(uint32_t config_mask); extern void btdm_controller_schedule(void); extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); @@ -154,11 +159,25 @@ void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) API_vhci_host_register_callback((const vhci_host_callback_t *)callback); } +static uint32_t btdm_config_mask_load(void) +{ + uint32_t mask = 0x0; + +#ifdef CONFIG_BT_DRAM_RELEASE + mask |= (BTDM_CFG_BT_EM_RELEASE | BTDM_CFG_BT_DATA_RELEASE); +#endif + return mask; +} + static void bt_controller_task(void *pvParam) { + uint32_t btdm_cfg_mask = 0; + btdm_osi_funcs_register(&osi_funcs); - btdm_controller_init(); + btdm_cfg_mask = btdm_config_mask_load(); + btdm_controller_init(btdm_cfg_mask); + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; /* Loop */ diff --git a/components/bt/lib b/components/bt/lib index dbac82b5c2..9f9f6a004e 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit dbac82b5c2694f2639161b0a2b3c0bd8c7d3efc5 +Subproject commit 9f9f6a004e42519f54555c42a037b8ef25bf2238 diff --git a/components/esp32/heap_alloc_caps.c b/components/esp32/heap_alloc_caps.c index a4ff870f39..7d2a26e64e 100644 --- a/components/esp32/heap_alloc_caps.c +++ b/components/esp32/heap_alloc_caps.c @@ -193,8 +193,14 @@ void heap_alloc_caps_init() { disable_mem_region((void*)0x3ffe0000, (void*)0x3ffe8000); //knock out ROM data region #if CONFIG_BT_ENABLED +#if CONFIG_BT_DRAM_RELEASE + disable_mem_region((void*)0x3ffb0000, (void*)0x3ffb3000); //knock out BT data region + disable_mem_region((void*)0x3ffb8000, (void*)0x3ffbbb28); //knock out BT data region + disable_mem_region((void*)0x3ffbdb28, (void*)0x3ffc0000); //knock out BT data region +#else disable_mem_region((void*)0x3ffb0000, (void*)0x3ffc0000); //knock out BT data region #endif +#endif #if CONFIG_MEMMAP_TRACEMEM #if CONFIG_MEMMAP_TRACEMEM_TWOBANKS 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 09/24] 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 10/24] 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 11/24] 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 12/24] 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 13/24] 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 14/24] 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 15/24] 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 16/24] 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 17/24] 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 18/24] 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 19/24] 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 20/24] 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 From b5826978892da8230ac0084c4d8e22ab6844f43a Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Thu, 23 Feb 2017 17:32:46 +0800 Subject: [PATCH 21/24] component/bt : add adv/scan start complete event 1. indicate adv/scan start complete success or failed 2. controller do limit of adv/scan concurrence, so add some codes to report adv/scan start failed or not. --- .../bluedroid/api/include/esp_gap_ble_api.h | 14 ++++ components/bt/bluedroid/bta/dm/bta_dm_act.c | 21 ++++-- components/bt/bluedroid/bta/dm/bta_dm_api.c | 7 +- components/bt/bluedroid/bta/dm/bta_dm_int.h | 4 +- components/bt/bluedroid/bta/include/bta_api.h | 9 ++- .../btc/profile/std/gap/btc_gap_ble.c | 65 ++++++++++++++++--- .../bt/bluedroid/stack/btm/btm_ble_gap.c | 38 +++++++---- docs/api/bluetooth/esp_gap_ble.rst | 6 ++ .../bluetooth/gatt_client/main/gattc_demo.c | 6 ++ .../bluetooth/gatt_server/main/gatts_demo.c | 6 ++ .../main/gatts_table_creat_demo.c | 6 ++ 11 files changed, 149 insertions(+), 33 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 64aff1fb1a..8b5882d270 100644 --- a/components/bt/bluedroid/api/include/esp_gap_ble_api.h +++ b/components/bt/bluedroid/api/include/esp_gap_ble_api.h @@ -46,6 +46,8 @@ typedef enum { 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_ADV_START_COMPLETE_EVT, /*!< When start advertising complete, the event comes */ + ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, /*!< When start scan complete, the event comes */ } esp_gap_ble_cb_event_t; /// Advertising data maximum length @@ -284,6 +286,18 @@ typedef union { 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 */ + /** + * @brief ESP_GAP_BLE_ADV_START_COMPLETE_EVT + */ + struct ble_adv_start_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate advertising start operation success status */ + } adv_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_START_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_START_COMPLETE_EVT + */ + struct ble_scan_start_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate scan start operation success status */ + } scan_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_START_COMPLETE_EVT */ } esp_ble_gap_cb_param_t; /** diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c index 66eb55dac2..8ebd3a8f31 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -4534,12 +4534,11 @@ void bta_dm_ble_observe (tBTA_DM_MSG *p_data) bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback; if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration, bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) { - tBTA_DM_SEARCH data; APPL_TRACE_WARNING(" %s BTM_BleObserve failed. status %d\n", __FUNCTION__, status); - data.inq_cmpl.num_resps = 0; - if (bta_dm_search_cb.p_scan_cback) { - bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data); - } + } + if (p_data->ble_observe.p_start_scan_cback) { + status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE); + p_data->ble_observe.p_start_scan_cback(status); } } else { bta_dm_search_cb.p_scan_cback = NULL; @@ -4576,13 +4575,21 @@ void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data) *******************************************************************************/ void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data) { - BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min, + tBTA_STATUS status = BTA_FAILURE; + + if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min, p_data->ble_set_adv_params_all.adv_int_max, p_data->ble_set_adv_params_all.adv_type, p_data->ble_set_adv_params_all.addr_type_own, p_data->ble_set_adv_params_all.p_dir_bda, p_data->ble_set_adv_params_all.channel_map, - p_data->ble_set_adv_params_all.adv_filter_policy); + p_data->ble_set_adv_params_all.adv_filter_policy) == BTM_SUCCESS) { + status = BTA_SUCCESS; + } + + if (p_data->ble_set_adv_params_all.p_start_adv_cback) { + (*p_data->ble_set_adv_params_all.p_start_adv_cback)(status); + } } /******************************************************************************* diff --git a/components/bt/bluedroid/bta/dm/bta_dm_api.c b/components/bt/bluedroid/bta/dm/bta_dm_api.c index 132d2ea8f7..413d6de559 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_api.c @@ -1009,7 +1009,7 @@ void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max, void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max, UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own, tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol, - tBLE_BD_ADDR *p_dir_bda) + tBLE_BD_ADDR *p_dir_bda, tBTA_START_ADV_CMPL_CBACK p_start_adv_cb) { #if BLE_INCLUDED == TRUE tBTA_DM_API_BLE_ADV_PARAMS_ALL *p_msg; @@ -1029,6 +1029,7 @@ void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max, p_msg->addr_type_own = addr_type_own; p_msg->channel_map = chnl_map; p_msg->adv_filter_policy = adv_fil_pol; + p_msg->p_start_adv_cback = p_start_adv_cb; if (p_dir_bda != NULL) { p_msg->p_dir_bda = (tBLE_BD_ADDR *)(p_msg + 1); memcpy(p_msg->p_dir_bda, p_dir_bda, sizeof(tBLE_BD_ADDR)); @@ -2127,7 +2128,8 @@ void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transpor ** *******************************************************************************/ extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration, - tBTA_DM_SEARCH_CBACK *p_results_cb) + tBTA_DM_SEARCH_CBACK *p_results_cb, + tBTA_START_SCAN_CMPL_CBACK *p_start_scan_cb) { tBTA_DM_API_BLE_OBSERVE *p_msg; @@ -2140,6 +2142,7 @@ extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration, p_msg->start = start; p_msg->duration = duration; p_msg->p_cback = p_results_cb; + p_msg->p_start_scan_cback = p_start_scan_cb; bta_sys_sendmsg(p_msg); } diff --git a/components/bt/bluedroid/bta/dm/bta_dm_int.h b/components/bt/bluedroid/bta/dm/bta_dm_int.h index 7475ad254e..9c5cbc4d8d 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_int.h +++ b/components/bt/bluedroid/bta/dm/bta_dm_int.h @@ -471,7 +471,8 @@ typedef struct { BT_HDR hdr; BOOLEAN start; UINT16 duration; - tBTA_DM_SEARCH_CBACK *p_cback; + tBTA_DM_SEARCH_CBACK *p_cback; + tBTA_START_SCAN_CMPL_CBACK *p_start_scan_cback; } tBTA_DM_API_BLE_OBSERVE; typedef struct { @@ -506,6 +507,7 @@ typedef struct { tBTM_BLE_ADV_CHNL_MAP channel_map; tBTM_BLE_AFP adv_filter_policy; tBLE_BD_ADDR *p_dir_bda; + tBTA_START_ADV_CMPL_CBACK *p_start_adv_cback; } tBTA_DM_API_BLE_ADV_PARAMS_ALL; diff --git a/components/bt/bluedroid/bta/include/bta_api.h b/components/bt/bluedroid/bta/include/bta_api.h index 1b97dc4fc6..8e4b927aa4 100644 --- a/components/bt/bluedroid/bta/include/bta_api.h +++ b/components/bt/bluedroid/bta/include/bta_api.h @@ -400,6 +400,8 @@ typedef struct { typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status); +typedef void (tBTA_START_ADV_CMPL_CBACK) (tBTA_STATUS status); + /* advertising channel map */ #define BTA_BLE_ADV_CHNL_37 BTM_BLE_ADV_CHNL_37 #define BTA_BLE_ADV_CHNL_38 BTM_BLE_ADV_CHNL_38 @@ -1095,6 +1097,8 @@ typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt, tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status); +typedef void (tBTA_START_SCAN_CMPL_CBACK) (tBTA_STATUS status); + typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status, tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_DM_BLE_REF_VALUE ref_value); @@ -1891,7 +1895,7 @@ extern void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max, extern void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max, UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own, tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol, - tBLE_BD_ADDR *p_dir_bda); + tBLE_BD_ADDR *p_dir_bda, tBTA_START_ADV_CMPL_CBACK p_start_adv_cb); /******************************************************************************* @@ -1997,7 +2001,8 @@ extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, ** *******************************************************************************/ extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration, - tBTA_DM_SEARCH_CBACK *p_results_cb); + tBTA_DM_SEARCH_CBACK *p_results_cb, + tBTA_START_SCAN_CMPL_CBACK *p_start_scan_cb); extern void BTA_DmBleStopAdvertising(void); 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 339ff68420..8fea801b0a 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 @@ -367,7 +367,26 @@ static void btc_ble_set_scan_rsp_data_raw(uint8_t *raw_scan_rsp, uint32_t raw_sc 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) +static void btc_start_adv_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_START_COMPLETE_EVT; + param.adv_start_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_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback) { tBLE_BD_ADDR peer_addr; @@ -398,7 +417,8 @@ static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params) ble_adv_params->own_addr_type, ble_adv_params->channel_map, ble_adv_params->adv_filter_policy, - &peer_addr); + &peer_addr, + start_adv_cback); } @@ -487,12 +507,33 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), NULL); } - -static void btc_ble_start_scanning(uint8_t duration, tBTA_DM_SEARCH_CBACK *results_cb) +static void btc_start_scan_callback(tBTA_STATUS status) { - if ((duration != 0) && (results_cb != NULL)) { + 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_START_COMPLETE_EVT; + param.scan_start_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_start_scanning(uint8_t duration, + tBTA_DM_SEARCH_CBACK *results_cb, + tBTA_START_SCAN_CMPL_CBACK *start_scan_cb) +{ + if ((duration != 0) && (results_cb != NULL) && (start_scan_cb != NULL)) { ///Start scan the device - BTA_DmBleObserve(true, duration, results_cb); + BTA_DmBleObserve(true, duration, results_cb, start_scan_cb); } else { LOG_ERROR("The scan duration or p_results_cb invalid\n"); } @@ -501,7 +542,7 @@ static void btc_ble_start_scanning(uint8_t duration, tBTA_DM_SEARCH_CBACK *resul static void btc_ble_stop_scanning(void) { uint8_t duration = 0; - BTA_DmBleObserve(false, duration, NULL); + BTA_DmBleObserve(false, duration, NULL, NULL); } @@ -576,6 +617,12 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg) 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; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_START_COMPLETE_EVT, param); + break; + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, param); + break; default: break; @@ -695,13 +742,13 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) btc_ble_set_scan_params(&arg->set_scan_param.scan_params, btc_scan_params_callback); break; case BTC_GAP_BLE_ACT_START_SCAN: - btc_ble_start_scanning(arg->start_scan.duration, btc_search_callback); + btc_ble_start_scanning(arg->start_scan.duration, btc_search_callback, btc_start_scan_callback); break; case BTC_GAP_BLE_ACT_STOP_SCAN: btc_ble_stop_scanning(); break; case BTC_GAP_BLE_ACT_START_ADV: - btc_ble_start_advertising(&arg->start_adv.adv_params); + btc_ble_start_advertising(&arg->start_adv.adv_params, btc_start_adv_callback); break; case BTC_GAP_BLE_ACT_STOP_ADV: btc_ble_stop_advertising(); diff --git a/components/bt/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/bluedroid/stack/btm/btm_ble_gap.c index 4cfce3b667..07c63b4963 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c @@ -2935,14 +2935,18 @@ tBTM_STATUS btm_ble_start_scan(void) tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS status = BTM_CMD_STARTED; - /* start scan, disable duplicate filtering */ - if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) { + if (p_inq->adv_mode != BTM_BLE_ADV_DISABLE) { status = BTM_NO_RESOURCES; } else { - if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) { - btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + /* start scan, disable duplicate filtering */ + if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) { + status = BTM_NO_RESOURCES; } else { - btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); + if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) { + btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + } else { + btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); + } } } return status; @@ -2961,15 +2965,17 @@ void btm_ble_stop_scan(void) { BTM_TRACE_EVENT ("btm_ble_stop_scan "); - /* Clear the inquiry callback if set */ - btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; + if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_DISABLE) { + /* Clear the inquiry callback if set */ + btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; - /* stop discovery now */ - btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); + /* stop discovery now */ + btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); - btm_update_scanner_filter_policy(SP_ADV_ALL); + btm_update_scanner_filter_policy(SP_ADV_ALL); - btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN; + btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN; + } } /******************************************************************************* ** @@ -3089,9 +3095,15 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI *******************************************************************************/ tBTM_STATUS btm_ble_start_adv(void) { + tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb; tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS rt = BTM_NO_RESOURCES; BTM_TRACE_EVENT ("btm_ble_start_adv\n"); + + if (BTM_BLE_IS_OBS_ACTIVE(p_ble_cb->scan_activity)) { + return BTM_NO_RESOURCES; + } + if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type)) { return BTM_WRONG_MODE; } @@ -3133,10 +3145,12 @@ tBTM_STATUS btm_ble_start_adv(void) *******************************************************************************/ tBTM_STATUS btm_ble_stop_adv(void) { + tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb; tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS rt = BTM_SUCCESS; - if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { + if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE + && !BTM_BLE_IS_OBS_ACTIVE(p_ble_cb->scan_activity)) { if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) { p_cb->fast_adv_on = FALSE; p_cb->adv_mode = BTM_BLE_ADV_DISABLE; diff --git a/docs/api/bluetooth/esp_gap_ble.rst b/docs/api/bluetooth/esp_gap_ble.rst index fea9376304..41bffa0956 100644 --- a/docs/api/bluetooth/esp_gap_ble.rst +++ b/docs/api/bluetooth/esp_gap_ble.rst @@ -93,6 +93,12 @@ Structures .. doxygenstruct:: esp_ble_gap_cb_param_t::ble_scan_rsp_data_raw_cmpl_evt_param :members: +.. doxygenstruct:: esp_ble_gap_cb_param_t::ble_adv_start_cmpl_evt_param + :members: + +.. doxygenstruct:: esp_ble_gap_cb_param_t::ble_scan_start_cmpl_evt_param + :members: + Functions ^^^^^^^^^ diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index 4a2fa0051d..2904484913 100644 --- a/examples/bluetooth/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/gatt_client/main/gattc_demo.c @@ -295,6 +295,12 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par esp_ble_gap_start_scanning(duration); break; } + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + //scan start complete event to indicate scan start successfully or failed + if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTC_TAG, "Scan start failed\n"); + } + break; case ESP_GAP_BLE_SCAN_RESULT_EVT: { esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; switch (scan_result->scan_rst.search_evt) { diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index acbf9195a0..39d33286a0 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -151,6 +151,12 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: esp_ble_gap_start_advertising(&test_adv_params); break; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + //advertising start complete event to indicate advertising start successfully or failed + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); + } + break; default: break; } 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 71baf1842c..9bb03e7e89 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 @@ -203,6 +203,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(&heart_rate_adv_params); break; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + //advertising start complete event to indicate advertising start successfully or failed + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTS_TABLE_TAG, "Advertising start failed\n"); + } + break; default: break; } From ff81e1750449474e710b5dc291c017bbd59d7bb3 Mon Sep 17 00:00:00 2001 From: qiyueixa Date: Fri, 24 Feb 2017 15:19:31 +0800 Subject: [PATCH 22/24] wifi: fix issue in setting channel before sniffer is enabled --- components/esp32/include/esp_wifi.h | 1 + components/esp32/lib | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 0f7e2996e8..9f3b1ed70d 100755 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -422,6 +422,7 @@ esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw); * @brief Set primary/secondary channel of ESP32 * * @attention 1. This is a special API for sniffer + * @attention 2. This API should be called after esp_wifi_start() or esp_wifi_set_promiscuous() * * @param primary for HT20, primary is the channel number, for HT40, primary is the primary channel * @param second for HT20, second is ignored, for HT40, second is the second channel diff --git a/components/esp32/lib b/components/esp32/lib index ed85cf9156..0be74cb72f 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit ed85cf9156f2ef358c29d07fb849a73c5758eecb +Subproject commit 0be74cb72fba4502a685c9f0df26689592018f78 From c17e05040ae6c18895a414950538ddfd5e9c5419 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 24 Feb 2017 21:04:22 +0800 Subject: [PATCH 23/24] vfs_fat_sdmmc: if card init fails, fail cleanly This fixes the issue with sdmmc_host not returned to clean state after a failed attempt to mount the card, with no SD card in the slot. --- components/fatfs/src/vfs_fat_sdmmc.c | 12 +++++++++--- components/fatfs/test/test_fatfs.c | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/components/fatfs/src/vfs_fat_sdmmc.c b/components/fatfs/src/vfs_fat_sdmmc.c index e5956dd7b2..77620f5d87 100644 --- a/components/fatfs/src/vfs_fat_sdmmc.c +++ b/components/fatfs/src/vfs_fat_sdmmc.c @@ -39,14 +39,19 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path, sdmmc_host_init(); // enable card slot - sdmmc_host_init_slot(host_config->slot, slot_config); + esp_err_t err = sdmmc_host_init_slot(host_config->slot, slot_config); + if (err != ESP_OK) { + return err; + } + s_card = malloc(sizeof(sdmmc_card_t)); if (s_card == NULL) { - return ESP_ERR_NO_MEM; + err = ESP_ERR_NO_MEM; + goto fail; } // probe and initialize card - esp_err_t err = sdmmc_card_init(host_config, s_card); + err = sdmmc_card_init(host_config, s_card); if (err != ESP_OK) { ESP_LOGD(TAG, "sdmmc_card_init failed 0x(%x)", err); goto fail; @@ -104,6 +109,7 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path, return ESP_OK; fail: + sdmmc_host_deinit(); free(workbuf); esp_vfs_unregister(base_path); free(s_card); diff --git a/components/fatfs/test/test_fatfs.c b/components/fatfs/test/test_fatfs.c index 4f6482740c..d518652bc4 100644 --- a/components/fatfs/test/test_fatfs.c +++ b/components/fatfs/test/test_fatfs.c @@ -52,6 +52,25 @@ static void create_file_with_text(const char* name, const char* text) TEST_ASSERT_EQUAL(0, fclose(f)); } +TEST_CASE("Mount fails cleanly without card inserted", "[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 = false, + .max_files = 5 + }; + + for (int i = 0; i < 3; ++i) { + printf("Initializing card, attempt %d ", i); + esp_err_t err = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, NULL); + printf(" err=%d\n", err); + TEST_ESP_ERR(ESP_FAIL, err); + } + HEAP_SIZE_CHECK(0); +} + TEST_CASE("can create and write file on sd card", "[fatfs][ignore]") { HEAP_SIZE_CAPTURE(); From d9c649d26e071811c1777020c2f0ac0e0bda36ce Mon Sep 17 00:00:00 2001 From: qiyueixa Date: Fri, 24 Feb 2017 22:08:54 +0800 Subject: [PATCH 24/24] wifi: fix issue in setting channel API --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 0be74cb72f..28c6ee924c 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 0be74cb72fba4502a685c9f0df26689592018f78 +Subproject commit 28c6ee924ca6efc71bb77dcb040efd07d4d8a000