From b9b401ee39bb8390bcbff4a80ba7eddcdbf7d1c1 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Wed, 20 Feb 2019 21:01:27 +0800 Subject: [PATCH] Decouple WiFi and BT with coexist to reduce bin size 1. Do not link WiFi code when only BT or BLE is used and WiFi is not used. 2. Do not link coexist code when CONFIG_SW_COEXIST_ENABLE is disabled. --- .gitlab-ci.yml | 6 + components/bt/bt.c | 17 ++ components/bt/lib | 2 +- components/esp32/CMakeLists.txt | 2 +- components/esp32/Kconfig | 2 + components/esp32/coexist.c | 2 +- components/esp32/coexist_internal.h | 77 ------- components/esp32/cpu_start.c | 6 +- .../{wifi_os_adapter.c => esp_adapter.c} | 202 +++++++++++++----- .../esp32/include/esp_coexist_adapter.h | 59 +++++ .../esp32/include/esp_coexist_internal.h | 163 ++++++++++++++ components/esp32/include/esp_wifi_internal.h | 9 + .../esp32/include/esp_wifi_os_adapter.h | 13 +- components/esp32/lib | 2 +- components/esp32/phy_init.c | 15 +- components/esp32/test/CMakeLists.txt | 7 + components/esp32/test/component.mk | 3 + components/esp32/test/test_header_files_md5.c | 11 + components/esp32/wifi_init.c | 8 +- 19 files changed, 446 insertions(+), 160 deletions(-) delete mode 100644 components/esp32/coexist_internal.h rename components/esp32/{wifi_os_adapter.c => esp_adapter.c} (74%) create mode 100644 components/esp32/include/esp_coexist_adapter.h create mode 100644 components/esp32/include/esp_coexist_internal.h diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0c55ce4cd..08156cfe8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1299,6 +1299,12 @@ UT_001_42: - ESP32_IDF - UT_T1_1 +UT_001_43: + <<: *unit_test_template + tags: + - ESP32_IDF + - UT_T1_1 + UT_002_01: <<: *unit_test_template tags: diff --git a/components/bt/bt.c b/components/bt/bt.c index 82bf79fde..dc17d9b02 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -43,6 +43,7 @@ #include "soc/rtc_cntl_reg.h" #include "soc/soc_memory_layout.h" #include "esp_clk.h" +#include "esp_coexist_internal.h" #if CONFIG_BT_ENABLED @@ -166,6 +167,11 @@ struct osi_funcs_t { void (* _btdm_sleep_exit_phase1)(void); /* called from ISR */ void (* _btdm_sleep_exit_phase2)(void); /* called from ISR */ void (* _btdm_sleep_exit_phase3)(void); /* called from task */ + int (* _coex_bt_request)(uint32_t event, uint32_t latency, uint32_t duration); + int (* _coex_bt_release)(uint32_t event); + int (* _coex_register_bt_cb)(coex_func_cb_t cb); + uint32_t (* _coex_bb_reset_lock)(void); + void (* _coex_bb_reset_unlock)(uint32_t restore); uint32_t _magic; }; @@ -205,6 +211,12 @@ extern int bredr_txpwr_set(int min_power_level, int max_power_level); extern int bredr_txpwr_get(int *min_power_level, int *max_power_level); extern void bredr_sco_datapath_set(uint8_t data_path); extern void btdm_controller_scan_duplicate_list_clear(void); +/* Coexistence */ +extern int coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration); +extern int coex_bt_release_wrapper(uint32_t event); +extern int coex_register_bt_cb_wrapper(coex_func_cb_t cb); +extern uint32_t coex_bb_reset_lock_wrapper(void); +extern void coex_bb_reset_unlock_wrapper(uint32_t restore); extern char _bss_start_btdm; extern char _bss_end_btdm; @@ -311,6 +323,11 @@ static const struct osi_funcs_t osi_funcs_ro = { ._btdm_sleep_exit_phase1 = btdm_sleep_exit_phase1_wrapper, ._btdm_sleep_exit_phase2 = NULL, ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper, + ._coex_bt_request = coex_bt_request_wrapper, + ._coex_bt_release = coex_bt_release_wrapper, + ._coex_register_bt_cb = coex_register_bt_cb_wrapper, + ._coex_bb_reset_lock = coex_bb_reset_lock_wrapper, + ._coex_bb_reset_unlock = coex_bb_reset_unlock_wrapper, ._magic = OSI_MAGIC_VALUE, }; diff --git a/components/bt/lib b/components/bt/lib index 86fa066be..48ecf82c9 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 86fa066be494c2f3889dbea0821da44fdc1ba4df +Subproject commit 48ecf82c99f9e5d729e07c39a9d4c350a0f2f8e9 diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 75b76010d..9ad625631 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -19,6 +19,7 @@ else() "dbg_stubs.c" "dport_access.c" "dport_panic_highint_hdl.S" + "esp_adapter.c" "esp_err_to_name.c" "esp_timer.c" "esp_timer_esp32.c" @@ -48,7 +49,6 @@ else() "system_api.c" "task_wdt.c" "wifi_init.c" - "wifi_os_adapter.c" "hwcrypto/aes.c" "hwcrypto/sha.c") set(COMPONENT_ADD_INCLUDEDIRS "include") diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 1952e2feb..051c73326 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -924,6 +924,8 @@ menu Wi-Fi If enabled, WiFi & Bluetooth coexistence is controlled by software rather than hardware. Recommended for heavy traffic scenarios. Both coexistence configuration options are automatically managed, no user intervention is required. + If only Bluetooth is used, it is recommended to disable this option to reduce binary file + size. choice SW_COEXIST_PREFERENCE prompt "WiFi/Bluetooth coexistence performance preference" diff --git a/components/esp32/coexist.c b/components/esp32/coexist.c index 9eff30868..628269942 100644 --- a/components/esp32/coexist.c +++ b/components/esp32/coexist.c @@ -13,7 +13,7 @@ // limitations under the License. #include "esp_coexist.h" -#include "coexist_internal.h" +#include "esp_coexist_internal.h" const char *esp_coex_version_get(void) { diff --git a/components/esp32/coexist_internal.h b/components/esp32/coexist_internal.h deleted file mode 100644 index fb21e2487..000000000 --- a/components/esp32/coexist_internal.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2018-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __COEXIST_INTERNAL_H__ -#define __COEXIST_INTERNAL_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - COEX_PREFER_WIFI = 0, - COEX_PREFER_BT, - COEX_PREFER_BALANCE, - COEX_PREFER_NUM, -} coex_prefer_t; - -/** - * @brief Init software coexist - * extern function for internal use. - * - * @return Init ok or failed. - */ -esp_err_t coex_init(void); - -/** - * @brief De-init software coexist - * extern function for internal use. - */ -void coex_deinit(void); - -/** - * @brief Pause software coexist - * extern function for internal use. - */ -void coex_pause(void); - -/** - * @brief Resume software coexist - * extern function for internal use. - */ -void coex_resume(void); - -/** - * @brief Get software coexist version string - * extern function for internal use. - * @return : version string - */ -const char *coex_version_get(void); - -/** - * @brief Coexist performance preference set from libbt.a - * extern function for internal use. - * - * @param prefer : the prefer enumeration value - * @return : ESP_OK - success, other - failed - */ -esp_err_t coex_preference_set(coex_prefer_t prefer); - -#ifdef __cplusplus -} -#endif - -#endif /* __COEXIST_INTERNAL_H__ */ diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index bf28857fb..7e45abb03 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -59,7 +59,7 @@ #include "esp_task_wdt.h" #include "esp_phy_init.h" #include "esp_cache_err_int.h" -#include "esp_coexist.h" +#include "esp_coexist_internal.h" #include "esp_panic.h" #include "esp_core_dump.h" #include "esp_app_trace.h" @@ -412,6 +412,10 @@ void start_cpu0_default(void) } #endif +#if CONFIG_SW_COEXIST_ENABLE + esp_coex_adapter_register(&g_coex_adapter_funcs); +#endif + portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, ESP_TASK_MAIN_PRIO, NULL, 0); diff --git a/components/esp32/wifi_os_adapter.c b/components/esp32/esp_adapter.c similarity index 74% rename from components/esp32/wifi_os_adapter.c rename to components/esp32/esp_adapter.c index e63b0135f..342494233 100644 --- a/components/esp32/wifi_os_adapter.c +++ b/components/esp32/esp_adapter.c @@ -46,6 +46,8 @@ #include "os.h" #include "esp_smartconfig.h" #include "smartconfig_ack.h" +#include "esp_coexist_internal.h" +#include "esp_coexist_adapter.h" extern void esp_dport_access_stall_other_cpu_start_wrap(void); @@ -100,38 +102,38 @@ static void * IRAM_ATTR wifi_zalloc_wrapper(size_t size) } wifi_static_queue_t* wifi_create_queue( int queue_len, int item_size) -{ +{ wifi_static_queue_t *queue = NULL; - + queue = (wifi_static_queue_t*)heap_caps_malloc(sizeof(wifi_static_queue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue) { return NULL; } - + #if CONFIG_SPIRAM_USE_MALLOC queue->storage = heap_caps_calloc(1, sizeof(StaticQueue_t) + (queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue->storage) { goto _error; } - + queue->handle = xQueueCreateStatic( queue_len, item_size, ((uint8_t*)(queue->storage)) + sizeof(StaticQueue_t), (StaticQueue_t*)(queue->storage)); - + if (!queue->handle) { goto _error; } - + return queue; - + _error: if (queue) { if (queue->storage) { free(queue->storage); } - + free(queue); } - + return NULL; #else queue->handle = xQueueCreate( queue_len, item_size); @@ -154,26 +156,26 @@ void wifi_delete_queue(wifi_static_queue_t *queue) } } -static void * IRAM_ATTR wifi_create_queue_wrapper(int queue_len, int item_size) +static void * wifi_create_queue_wrapper(int queue_len, int item_size) { return wifi_create_queue(queue_len, item_size); } -static void IRAM_ATTR wifi_delete_queue_wrapper(void *queue) +static void wifi_delete_queue_wrapper(void *queue) { wifi_delete_queue(queue); } -static void IRAM_ATTR set_isr_wrapper(int32_t n, void *f, void *arg) +static void set_isr_wrapper(int32_t n, void *f, void *arg) { xt_set_interrupt_handler(n, (xt_handler)f, arg); } -static void * IRAM_ATTR spin_lock_create_wrapper(void) +static void * spin_lock_create_wrapper(void) { portMUX_TYPE tmp = portMUX_INITIALIZER_UNLOCKED; void *mux = malloc(sizeof(portMUX_TYPE)); - + if (mux) { memcpy(mux,&tmp,sizeof(portMUX_TYPE)); return mux; @@ -184,10 +186,10 @@ static void * IRAM_ATTR spin_lock_create_wrapper(void) static uint32_t IRAM_ATTR wifi_int_disable_wrapper(void *wifi_int_mux) { if (xPortInIsrContext()) { - portENTER_CRITICAL_ISR(wifi_int_mux); - } else { - portENTER_CRITICAL(wifi_int_mux); - } + portENTER_CRITICAL_ISR(wifi_int_mux); + } else { + portENTER_CRITICAL(wifi_int_mux); + } return 0; } @@ -195,10 +197,10 @@ static uint32_t IRAM_ATTR wifi_int_disable_wrapper(void *wifi_int_mux) static void IRAM_ATTR wifi_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp) { if (xPortInIsrContext()) { - portEXIT_CRITICAL_ISR(wifi_int_mux); - } else { - portEXIT_CRITICAL(wifi_int_mux); - } + portEXIT_CRITICAL_ISR(wifi_int_mux); + } else { + portEXIT_CRITICAL(wifi_int_mux); + } } static void IRAM_ATTR task_yield_from_isr_wrapper(void) @@ -206,12 +208,12 @@ static void IRAM_ATTR task_yield_from_isr_wrapper(void) portYIELD_FROM_ISR(); } -static void *IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init) +static void * semphr_create_wrapper(uint32_t max, uint32_t init) { return (void *)xSemaphoreCreateCounting(max, init); } -static void IRAM_ATTR semphr_delete_wrapper(void *semphr) +static void semphr_delete_wrapper(void *semphr) { vSemaphoreDelete(semphr); } @@ -226,7 +228,7 @@ static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw) return (int32_t)xSemaphoreGiveFromISR(semphr, hptw); } -static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_tick) +static int32_t semphr_take_wrapper(void *semphr, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (int32_t)xSemaphoreTake(semphr, portMAX_DELAY); @@ -235,22 +237,22 @@ static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_t } } -static int32_t IRAM_ATTR semphr_give_wrapper(void *semphr) +static int32_t semphr_give_wrapper(void *semphr) { return (int32_t)xSemaphoreGive(semphr); } -static void *IRAM_ATTR recursive_mutex_create_wrapper(void) +static void * recursive_mutex_create_wrapper(void) { return (void *)xSemaphoreCreateRecursiveMutex(); } -static void *IRAM_ATTR mutex_create_wrapper(void) +static void * mutex_create_wrapper(void) { return (void *)xSemaphoreCreateMutex(); } -static void IRAM_ATTR mutex_delete_wrapper(void *mutex) +static void mutex_delete_wrapper(void *mutex) { vSemaphoreDelete(mutex); } @@ -265,12 +267,12 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) return (int32_t)xSemaphoreGiveRecursive(mutex); } -static void *IRAM_ATTR queue_create_wrapper(uint32_t queue_len, uint32_t item_size) +static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { return (void *)xQueueCreate(queue_len, item_size); } -static int32_t IRAM_ATTR queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (int32_t)xQueueSend(queue, item, portMAX_DELAY); @@ -284,17 +286,17 @@ static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, vo return (int32_t)xQueueSendFromISR(queue, item, hptw); } -static int32_t IRAM_ATTR queue_send_to_back_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_send_to_back_wrapper(void *queue, void *item, uint32_t block_time_tick) { - return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_BACK); + return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_BACK); } -static int32_t IRAM_ATTR queue_send_to_front_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_send_to_front_wrapper(void *queue, void *item, uint32_t block_time_tick) { return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_FRONT); } -static int32_t IRAM_ATTR queue_recv_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (int32_t)xQueueReceive(queue, item, portMAX_DELAY); @@ -303,7 +305,7 @@ static int32_t IRAM_ATTR queue_recv_wrapper(void *queue, void *item, uint32_t bl } } -static uint32_t IRAM_ATTR event_group_wait_bits_wrapper(void *event, uint32_t bits_to_wait_for, int clear_on_exit, int wait_for_all_bits, uint32_t block_time_tick) +static uint32_t event_group_wait_bits_wrapper(void *event, uint32_t bits_to_wait_for, int clear_on_exit, int wait_for_all_bits, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (uint32_t)xEventGroupWaitBits(event, bits_to_wait_for, clear_on_exit, wait_for_all_bits, portMAX_DELAY); @@ -312,12 +314,12 @@ static uint32_t IRAM_ATTR event_group_wait_bits_wrapper(void *event, uint32_t bi } } -static int32_t IRAM_ATTR task_create_pinned_to_core_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) +static int32_t task_create_pinned_to_core_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY)); } -static int32_t IRAM_ATTR task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle) +static int32_t task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle) { return (uint32_t)xTaskCreate(task_func, name, stack_depth, param, prio, task_handle); } @@ -328,16 +330,11 @@ static int32_t IRAM_ATTR task_ms_to_tick_wrapper(uint32_t ms) } -static int32_t IRAM_ATTR task_get_max_priority_wrapper(void) +static int32_t task_get_max_priority_wrapper(void) { return (int32_t)(configMAX_PRIORITIES); } -static int32_t IRAM_ATTR phy_rf_init_wrapper(const void* init_data, uint32_t mode, void* calibration_data, uint32_t module) -{ - return esp_phy_rf_init( init_data, mode, calibration_data, module); -} - static void IRAM_ATTR timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat) { ets_timer_arm(timer, tmout, repeat); @@ -348,12 +345,12 @@ static void IRAM_ATTR timer_disarm_wrapper(void *timer) ets_timer_disarm(timer); } -static void IRAM_ATTR timer_done_wrapper(void *ptimer) +static void timer_done_wrapper(void *ptimer) { ets_timer_done(ptimer); } -static void IRAM_ATTR timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) +static void timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) { ets_timer_setfn(ptimer, pfunction, parg); } @@ -363,7 +360,7 @@ static void IRAM_ATTR timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repea ets_timer_arm_us(ptimer, us, repeat); } -static int IRAM_ATTR get_time_wrapper(void *t) +static int get_time_wrapper(void *t) { return os_get_time(t); } @@ -373,7 +370,7 @@ static void * IRAM_ATTR malloc_internal_wrapper(size_t size) return heap_caps_malloc(size, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); } -static void * IRAM_ATTR realloc_internal_wrapper(void *ptr, size_t size) +static void * IRAM_ATTR realloc_internal_wrapper(void *ptr, size_t size) { return heap_caps_realloc(ptr, size, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); } @@ -392,11 +389,81 @@ static void * IRAM_ATTR zalloc_internal_wrapper(size_t size) return ptr; } -static void IRAM_ATTR sc_ack_send_wrapper(void *param) +static void sc_ack_send_wrapper(void *param) { return sc_ack_send((sc_ack_t *)param); } +static uint32_t coex_status_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_status_get(); +#else + return 0; +#endif +} + +static int coex_wifi_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_wifi_request(event, latency, duration); +#else + return 0; +#endif +} + +static int coex_wifi_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_wifi_release(event); +#else + return 0; +#endif +} + +int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_bt_request(event, latency, duration); +#else + return 0; +#endif +} + +int IRAM_ATTR coex_bt_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_bt_release(event); +#else + return 0; +#endif +} + +int coex_register_bt_cb_wrapper(coex_func_cb_t cb) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_register_bt_cb(cb); +#else + return 0; +#endif +} + +uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_bb_reset_lock(); +#else + return 0; +#endif +} + +void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_bb_reset_unlock(restore); +#endif +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._set_isr = set_isr_wrapper, @@ -406,12 +473,9 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._spin_lock_delete = free, ._wifi_int_disable = wifi_int_disable_wrapper, ._wifi_int_restore = wifi_int_restore_wrapper, - ._task_yield = vPortYield, ._task_yield_from_isr = task_yield_from_isr_wrapper, ._semphr_create = semphr_create_wrapper, ._semphr_delete = semphr_delete_wrapper, - ._semphr_take_from_isr = semphr_take_from_isr_wrapper, - ._semphr_give_from_isr = semphr_give_from_isr_wrapper, ._semphr_take = semphr_take_wrapper, ._semphr_give = semphr_give_wrapper, ._mutex_create = mutex_create_wrapper, @@ -426,7 +490,6 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._queue_send_to_back = queue_send_to_back_wrapper, ._queue_send_to_front = queue_send_to_front_wrapper, ._queue_recv = queue_recv_wrapper, - ._queue_recv_from_isr = xQueueReceiveFromISR, ._queue_msg_waiting = uxQueueMessagesWaiting, ._event_group_create = xEventGroupCreate, ._event_group_delete = vEventGroupDelete, @@ -440,19 +503,15 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._task_ms_to_tick = task_ms_to_tick_wrapper, ._task_get_current_task = xTaskGetCurrentTaskHandle, ._task_get_max_priority = task_get_max_priority_wrapper, - ._is_in_isr = xPortInIsrContext, ._malloc = malloc, ._free = free, ._get_free_heap_size = esp_get_free_heap_size, ._rand = esp_random, ._dport_access_stall_other_cpu_start_wrap = esp_dport_access_stall_other_cpu_start_wrap, ._dport_access_stall_other_cpu_end_wrap = esp_dport_access_stall_other_cpu_end_wrap, - ._phy_rf_init = phy_rf_init_wrapper, ._phy_rf_deinit = esp_phy_rf_deinit, ._phy_load_cal_and_init = esp_phy_load_cal_and_init, ._read_mac = esp_read_mac, - ._timer_init = ets_timer_init, - ._timer_deinit = ets_timer_deinit, ._timer_arm = timer_arm_wrapper, ._timer_disarm = timer_disarm_wrapper, ._timer_done = timer_done_wrapper, @@ -481,7 +540,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._malloc_internal = malloc_internal_wrapper, ._realloc_internal = realloc_internal_wrapper, ._calloc_internal = calloc_internal_wrapper, - ._zalloc_internal = zalloc_internal_wrapper, + ._zalloc_internal = zalloc_internal_wrapper, ._wifi_malloc = wifi_malloc, ._wifi_realloc = wifi_realloc, ._wifi_calloc = wifi_calloc, @@ -494,5 +553,32 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._modem_sleep_deregister = esp_modem_sleep_deregister, ._sc_ack_send = sc_ack_send_wrapper, ._sc_ack_send_stop = sc_ack_send_stop, + ._coex_status_get = coex_status_get_wrapper, + ._coex_wifi_request = coex_wifi_request_wrapper, + ._coex_wifi_release = coex_wifi_release_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; + +coex_adapter_funcs_t g_coex_adapter_funcs = { + ._version = COEX_ADAPTER_VERSION, + ._spin_lock_create = spin_lock_create_wrapper, + ._spin_lock_delete = free, + ._int_disable = wifi_int_disable_wrapper, + ._int_enable = wifi_int_restore_wrapper, + ._task_yield_from_isr = task_yield_from_isr_wrapper, + ._semphr_create = semphr_create_wrapper, + ._semphr_delete = semphr_delete_wrapper, + ._semphr_take_from_isr = semphr_take_from_isr_wrapper, + ._semphr_give_from_isr = semphr_give_from_isr_wrapper, + ._semphr_take = semphr_take_wrapper, + ._semphr_give = semphr_give_wrapper, + ._is_in_isr = xPortInIsrContext, + ._malloc_internal = malloc_internal_wrapper, + ._free = free, + ._timer_disarm = timer_disarm_wrapper, + ._timer_done = timer_done_wrapper, + ._timer_setfn = timer_setfn_wrapper, + ._timer_arm_us = timer_arm_us_wrapper, + ._esp_timer_get_time = esp_timer_get_time, + ._magic = COEX_ADAPTER_MAGIC, +}; diff --git a/components/esp32/include/esp_coexist_adapter.h b/components/esp32/include/esp_coexist_adapter.h new file mode 100644 index 000000000..f2a38c31e --- /dev/null +++ b/components/esp32/include/esp_coexist_adapter.h @@ -0,0 +1,59 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_COEXIST_ADAPTER_H__ +#define __ESP_COEXIST_ADAPTER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define COEX_ADAPTER_VERSION 0x00000001 +#define COEX_ADAPTER_MAGIC 0xDEADBEAF + +#define COEX_ADAPTER_FUNCS_TIME_BLOCKING 0xffffffff + +typedef struct { + int32_t _version; + void *(* _spin_lock_create)(void); + void (* _spin_lock_delete)(void *lock); + uint32_t (*_int_disable)(void *mux); + void (*_int_enable)(void *mux, uint32_t tmp); + void (*_task_yield_from_isr)(void); + void *(*_semphr_create)(uint32_t max, uint32_t init); + void (*_semphr_delete)(void *semphr); + int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw); + int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw); + int32_t (*_semphr_take)(void *semphr, uint32_t block_time_tick); + int32_t (*_semphr_give)(void *semphr); + int32_t (* _is_in_isr)(void); + void * (* _malloc_internal)(size_t size); + void (* _free)(void *p); + void (* _timer_disarm)(void *timer); + void (* _timer_done)(void *ptimer); + void (* _timer_setfn)(void *ptimer, void *pfunction, void *parg); + void (* _timer_arm_us)(void *ptimer, uint32_t us, bool repeat); + int64_t (* _esp_timer_get_time)(void); + int32_t _magic; +} coex_adapter_funcs_t; + +extern coex_adapter_funcs_t g_coex_adapter_funcs; + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_COEXIST_ADAPTER_H__ */ diff --git a/components/esp32/include/esp_coexist_internal.h b/components/esp32/include/esp_coexist_internal.h new file mode 100644 index 000000000..1d94d6db7 --- /dev/null +++ b/components/esp32/include/esp_coexist_internal.h @@ -0,0 +1,163 @@ +// Copyright 2018-2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_COEXIST_INTERNAL_H__ +#define __ESP_COEXIST_INTERNAL_H__ + +#include +#include "esp_coexist_adapter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + COEX_PREFER_WIFI = 0, + COEX_PREFER_BT, + COEX_PREFER_BALANCE, + COEX_PREFER_NUM, +} coex_prefer_t; + +typedef void (* coex_func_cb_t)(uint32_t event, int sched_cnt); + +/** + * @brief Init software coexist + * extern function for internal use. + * + * @return Init ok or failed. + */ +esp_err_t coex_init(void); + +/** + * @brief De-init software coexist + * extern function for internal use. + */ +void coex_deinit(void); + +/** + * @brief Pause software coexist + * extern function for internal use. + */ +void coex_pause(void); + +/** + * @brief Resume software coexist + * extern function for internal use. + */ +void coex_resume(void); + +/** + * @brief Get software coexist version string + * extern function for internal use. + * @return : version string + */ +const char *coex_version_get(void); + +/** + * @brief Coexist performance preference set from libbt.a + * extern function for internal use. + * + * @param prefer : the prefer enumeration value + * @return : ESP_OK - success, other - failed + */ +esp_err_t coex_preference_set(coex_prefer_t prefer); + +/** + * @brief Get software coexist status. + * @return : software coexist status + */ +uint32_t coex_status_get(void); + +/** + * @brief WiFi requests coexistence. + * + * @param event : WiFi event + * @param latency : WiFi will request coexistence after latency + * @param duration : duration for WiFi to request coexistence + * @return : 0 - success, other - failed + */ +int coex_wifi_request(uint32_t event, uint32_t latency, uint32_t duration); + +/** + * @brief WiFi release coexistence. + * + * @param event : WiFi event + * @return : 0 - success, other - failed + */ +int coex_wifi_release(uint32_t event); + +/** + * @brief Blue tooth requests coexistence. + * + * @param event : blue tooth event + * @param latency : blue tooth will request coexistence after latency + * @param duration : duration for blue tooth to request coexistence + * @return : 0 - success, other - failed + */ +int coex_bt_request(uint32_t event, uint32_t latency, uint32_t duration); + +/** + * @brief Blue tooth release coexistence. + * + * @param event : blue tooth event + * @return : 0 - success, other - failed + */ +int coex_bt_release(uint32_t event); + +/** + * @brief Register callback function for blue tooth. + * + * @param cb : callback function + * @return : 0 - success, other - failed + */ +int coex_register_bt_cb(coex_func_cb_t cb); + +/** + * @brief Lock before reset base band. + * + * @return : lock value + */ +uint32_t coex_bb_reset_lock(void); + +/** + * @brief Unlock after reset base band. + * + * @param restore : lock value + */ +void coex_bb_reset_unlock(uint32_t restore); + +/** + * @brief Register coexistence adapter functions. + * + * @param funcs : coexistence adapter functions + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); + +/** + * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library + * + * @attention 1. It is used for internal CI version check + * + * @return + * - ESP_OK : succeed + * - ESP_WIFI_INVALID_ARG : MD5 check fail + */ +esp_err_t esp_coex_adapter_funcs_md5_check(const char *md5); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_COEXIST_INTERNAL_H__ */ diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h index 67bfd926d..979d0134e 100644 --- a/components/esp32/include/esp_wifi_internal.h +++ b/components/esp32/include/esp_wifi_internal.h @@ -249,6 +249,15 @@ void *wifi_realloc( void *ptr, size_t size ); */ void *wifi_calloc( size_t n, size_t size ); +/** + * @brief Update WiFi MAC time + * + * @param uint32_t time_delta : time duration since the WiFi/BT common clock is disabled + * + * @return Always returns ESP_OK + */ +typedef esp_err_t (* wifi_mac_time_update_cb_t)( uint32_t time_delta ); + /** * @brief Update WiFi MAC time * diff --git a/components/esp32/include/esp_wifi_os_adapter.h b/components/esp32/include/esp_wifi_os_adapter.h index 1dd522c49..752ccf990 100644 --- a/components/esp32/include/esp_wifi_os_adapter.h +++ b/components/esp32/include/esp_wifi_os_adapter.h @@ -21,7 +21,7 @@ extern "C" { #endif -#define ESP_WIFI_OS_ADAPTER_VERSION 0x00000001 +#define ESP_WIFI_OS_ADAPTER_VERSION 0x00000002 #define ESP_WIFI_OS_ADAPTER_MAGIC 0xDEADBEAF #define OSI_FUNCS_TIME_BLOCKING 0xffffffff @@ -39,12 +39,9 @@ typedef struct { void (* _spin_lock_delete)(void *lock); uint32_t (*_wifi_int_disable)(void *wifi_int_mux); void (*_wifi_int_restore)(void *wifi_int_mux, uint32_t tmp); - void (*_task_yield)(void); void (*_task_yield_from_isr)(void); void *(*_semphr_create)(uint32_t max, uint32_t init); void (*_semphr_delete)(void *semphr); - int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw); - int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw); int32_t (*_semphr_take)(void *semphr, uint32_t block_time_tick); int32_t (*_semphr_give)(void *semphr); void *(*_mutex_create)(void); @@ -59,7 +56,6 @@ typedef struct { int32_t (* _queue_send_to_back)(void *queue, void *item, uint32_t block_time_tick); int32_t (* _queue_send_to_front)(void *queue, void *item, uint32_t block_time_tick); int32_t (* _queue_recv)(void *queue, void *item, uint32_t block_time_tick); - int32_t (* _queue_recv_from_isr)(void *queue, void * const item, int32_t * const hptw); uint32_t (* _queue_msg_waiting)(void *queue); void *(* _event_group_create)(void); void (* _event_group_delete)(void *event); @@ -73,19 +69,15 @@ typedef struct { int32_t (* _task_ms_to_tick)(uint32_t ms); void *(* _task_get_current_task)(void); int32_t (* _task_get_max_priority)(void); - int32_t (* _is_in_isr)(void); void *(* _malloc)(uint32_t size); void (* _free)(void *p); uint32_t (* _get_free_heap_size)(void); uint32_t (* _rand)(void); void (* _dport_access_stall_other_cpu_start_wrap)(void); void (* _dport_access_stall_other_cpu_end_wrap)(void); - int32_t (* _phy_rf_init)(const void * init_data, uint32_t mode, void * calibration_data, uint32_t module); int32_t (* _phy_rf_deinit)(uint32_t module); void (* _phy_load_cal_and_init)(uint32_t module); int32_t (* _read_mac)(uint8_t* mac, uint32_t type); - void (* _timer_init)(void); - void (* _timer_deinit)(void); void (* _timer_arm)(void *timer, uint32_t tmout, bool repeat); void (* _timer_disarm)(void *timer); void (* _timer_done)(void *ptimer); @@ -127,6 +119,9 @@ typedef struct { int32_t (* _modem_sleep_deregister)(uint32_t module); void (* _sc_ack_send)(void *param); void (* _sc_ack_send_stop)(void); + uint32_t (* _coex_status_get)(void); + int32_t (* _coex_wifi_request)(uint32_t event, uint32_t latency, uint32_t duration); + int32_t (* _coex_wifi_release)(uint32_t event); int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp32/lib b/components/esp32/lib index 8ab53aee3..61530b0bd 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 8ab53aee3dff28cf374d25a8defdea0dc7c2fa32 +Subproject commit 61530b0bddb1de1cdcc73b8aa5f290da970bd1fe diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index d72f60dc0..18b3fa8b4 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -36,10 +36,11 @@ #include "freertos/portmacro.h" #include "phy.h" #include "phy_init_data.h" -#include "coexist_internal.h" +#include "esp_coexist_internal.h" #include "driver/periph_ctrl.h" #include "esp_wifi_internal.h" +extern wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb; static const char* TAG = "phy_init"; @@ -92,7 +93,9 @@ static inline void phy_update_wifi_mac_time(bool en_clock_stopped, int64_t now) if (s_common_clock_disable_time) { uint32_t diff = (uint64_t)now - s_common_clock_disable_time; - esp_wifi_internal_update_mac_time(diff); + if (s_wifi_mac_time_update_cb) { + s_wifi_mac_time_update_cb(diff); + } s_common_clock_disable_time = 0; ESP_LOGD(TAG, "wifi mac time delta: %u", diff); } @@ -159,14 +162,6 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat #endif } - -extern esp_err_t wifi_osi_funcs_register(wifi_osi_funcs_t *osi_funcs); - status = wifi_osi_funcs_register(&g_wifi_osi_funcs); - if(status != ESP_OK) { - ESP_LOGE(TAG, "failed to register wifi os adapter, ret(%d)", status); - _lock_release(&s_phy_rf_init_lock); - return ESP_FAIL; - } coex_bt_high_prio(); } } diff --git a/components/esp32/test/CMakeLists.txt b/components/esp32/test/CMakeLists.txt index 939b386a5..b99e2888b 100644 --- a/components/esp32/test/CMakeLists.txt +++ b/components/esp32/test/CMakeLists.txt @@ -21,9 +21,16 @@ execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_cry COMMAND cut -c 1-7 OUTPUT_VARIABLE WIFI_CRYPTO_MD5 OUTPUT_STRIP_TRAILING_WHITESPACE) + +# Calculate MD5 value of header file esp_coexist_adapter.h +execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_coexist_adapter.h + COMMAND cut -c 1-7 + OUTPUT_VARIABLE COEX_ADAPTER_MD5 + OUTPUT_STRIP_TRAILING_WHITESPACE) add_definitions(-DWIFI_OS_ADAPTER_MD5=\"${WIFI_OS_ADAPTER_MD5}\") add_definitions(-DWIFI_CRYPTO_MD5=\"${WIFI_CRYPTO_MD5}\") +add_definitions(-DCOEX_ADAPTER_MD5=\"${COEX_ADAPTER_MD5}\") add_custom_target(esp32_test_logo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h") diff --git a/components/esp32/test/component.mk b/components/esp32/test/component.mk index 11e0f7ed7..6fb41f30a 100644 --- a/components/esp32/test/component.mk +++ b/components/esp32/test/component.mk @@ -16,6 +16,9 @@ CFLAGS+=-DWIFI_OS_ADAPTER_MD5=$(WIFI_OS_ADAPTER_MD5_VAL) WIFI_CRYPTO_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_wifi_crypto_types.h | cut -c 1-7)\" CFLAGS+=-DWIFI_CRYPTO_MD5=$(WIFI_CRYPTO_MD5_VAL) +# Calculate MD5 value of header file esp_coexist_adapter.h +COEX_ADAPTER_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_coexist_adapter.h | cut -c 1-7)\" +CFLAGS+=-DCOEX_ADAPTER_MD5=$(COEX_ADAPTER_MD5_VAL) test_tjpgd.o: test_tjpgd_logo.h diff --git a/components/esp32/test/test_header_files_md5.c b/components/esp32/test/test_header_files_md5.c index 009de0ea5..c2d80350a 100644 --- a/components/esp32/test/test_header_files_md5.c +++ b/components/esp32/test/test_header_files_md5.c @@ -4,6 +4,7 @@ #include "unity.h" #include "esp_log.h" #include "esp_wifi_internal.h" +#include "esp_coexist_internal.h" static const char* TAG = "test_header_files_md5"; @@ -26,3 +27,13 @@ TEST_CASE("wifi crypto types MD5","[wifi]") ESP_LOGI(TAG, "test passed..."); } + +TEST_CASE("coexist adapter MD5","[coex]") +{ + const char *test_coex_adapter_funcs_md5 = COEX_ADAPTER_MD5; + + ESP_LOGI(TAG, "test coexist adapter MD5..."); + TEST_ESP_OK(esp_coex_adapter_funcs_md5_check(test_coex_adapter_funcs_md5)); + + ESP_LOGI(TAG, "test passed..."); +} diff --git a/components/esp32/wifi_init.c b/components/esp32/wifi_init.c index 2b3dae6b0..cf5d79b7b 100644 --- a/components/esp32/wifi_init.c +++ b/components/esp32/wifi_init.c @@ -27,6 +27,9 @@ mesh_event_cb_t g_mesh_event_cb = NULL; static esp_pm_lock_handle_t s_wifi_modem_sleep_lock; #endif +/* Callback function to update WiFi MAC time */ +wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb = NULL; + static void __attribute__((constructor)) s_set_default_wifi_log_level() { /* WiFi libraries aren't compiled to know CONFIG_LOG_DEFAULT_LEVEL, @@ -97,7 +100,10 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) #endif esp_event_set_default_wifi_handlers(); esp_err_t result = esp_wifi_init_internal(config); - esp_wifi_set_debug_log(); + if (result == ESP_OK) { + esp_wifi_set_debug_log(); + s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time; + } return result; }