mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'master' into feature/freertos_static_buffers
This commit is contained in:
commit
50bd28353d
3
.gitignore
vendored
3
.gitignore
vendored
@ -19,6 +19,3 @@ GPATH
|
|||||||
examples/*/sdkconfig
|
examples/*/sdkconfig
|
||||||
examples/*/sdkconfig.old
|
examples/*/sdkconfig.old
|
||||||
examples/*/build
|
examples/*/build
|
||||||
|
|
||||||
# Bootloader files
|
|
||||||
components/bootloader/src/sdkconfig.old
|
|
@ -37,6 +37,12 @@ build_template_app:
|
|||||||
# branch
|
# branch
|
||||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||||
- make defconfig
|
- 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
|
- make all V=1
|
||||||
|
|
||||||
|
|
||||||
|
20
Kconfig
20
Kconfig
@ -23,6 +23,26 @@ endmenu
|
|||||||
|
|
||||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||||
|
|
||||||
|
choice OPTIMIZATION_LEVEL
|
||||||
|
prompt "Optimization level"
|
||||||
|
default OPTIMIZATION_LEVEL_DEBUG
|
||||||
|
help
|
||||||
|
This option sets optimization level.
|
||||||
|
|
||||||
|
- for "Release" setting, -Os flag is added to CFLAGS,
|
||||||
|
and -DNDEBUG flag is added to CPPFLAGS.
|
||||||
|
|
||||||
|
- for "Debug" setting, -Og flag is added to CFLAGS.
|
||||||
|
|
||||||
|
To override any of these settings, set CFLAGS and/or CPPFLAGS
|
||||||
|
in project makefile, before including $(IDF_PATH)/make/project.mk.
|
||||||
|
|
||||||
|
config OPTIMIZATION_LEVEL_DEBUG
|
||||||
|
bool "Debug"
|
||||||
|
config OPTIMIZATION_LEVEL_RELEASE
|
||||||
|
bool "Release"
|
||||||
|
endchoice
|
||||||
|
|
||||||
menu "Component config"
|
menu "Component config"
|
||||||
source "$COMPONENT_KCONFIGS"
|
source "$COMPONENT_KCONFIGS"
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -8,23 +8,26 @@
|
|||||||
# basically runs Make in the src/ directory but it needs to zero some variables
|
# basically runs Make in the src/ directory but it needs to zero some variables
|
||||||
# the ESP-IDF project.mk makefile exports first, to not let them interfere.
|
# the ESP-IDF project.mk makefile exports first, to not let them interfere.
|
||||||
#
|
#
|
||||||
ifeq ("$(IS_BOOTLOADER_BUILD)","")
|
ifndef IS_BOOTLOADER_BUILD
|
||||||
|
|
||||||
BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH)
|
BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH)
|
||||||
BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader
|
BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader)
|
||||||
BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||||
|
BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig
|
||||||
|
|
||||||
|
# Custom recursive make for bootloader sub-project
|
||||||
|
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
||||||
|
V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \
|
||||||
|
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||||
|
|
||||||
.PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN)
|
.PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN)
|
||||||
|
|
||||||
$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig
|
$(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig
|
||||||
$(Q) PROJECT_PATH= \
|
$(Q) $(BOOTLOADER_MAKE) $@
|
||||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
|
||||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN)
|
|
||||||
|
|
||||||
bootloader-clean:
|
bootloader-clean:
|
||||||
$(Q) PROJECT_PATH= \
|
$(Q) $(BOOTLOADER_MAKE) app-clean config-clean
|
||||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
$(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old
|
||||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V)
|
|
||||||
|
|
||||||
clean: bootloader-clean
|
clean: bootloader-clean
|
||||||
|
|
||||||
@ -36,14 +39,17 @@ all_binaries: $(BOOTLOADER_BIN)
|
|||||||
|
|
||||||
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
||||||
|
|
||||||
# synchronise the project level config to the component's
|
|
||||||
# config
|
|
||||||
$(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig
|
|
||||||
$(Q) cp $< $@
|
|
||||||
|
|
||||||
# bootloader-flash calls flash in the bootloader dummy project
|
# bootloader-flash calls flash in the bootloader dummy project
|
||||||
bootloader-flash: $(BOOTLOADER_BIN)
|
bootloader-flash: $(BOOTLOADER_BIN)
|
||||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src flash MAKEFLAGS= V=$(V)
|
$(BOOTLOADER_MAKE) flash
|
||||||
|
|
||||||
|
# synchronise the project level config to the bootloader's
|
||||||
|
# config
|
||||||
|
$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR)
|
||||||
|
$(Q) cp $< $@
|
||||||
|
|
||||||
|
$(BOOTLOADER_BUILD_DIR):
|
||||||
|
$(Q) mkdir -p $@
|
||||||
|
|
||||||
else
|
else
|
||||||
CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include
|
CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include
|
||||||
|
@ -4,12 +4,13 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
PROJECT_NAME := bootloader
|
PROJECT_NAME := bootloader
|
||||||
COMPONENTS := esptool_py bootloader log
|
COMPONENTS := esptool_py bootloader log spi_flash
|
||||||
|
|
||||||
# The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included.
|
# The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included.
|
||||||
#
|
#
|
||||||
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
|
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
|
||||||
IS_BOOTLOADER_BUILD := 1
|
IS_BOOTLOADER_BUILD := 1
|
||||||
|
export IS_BOOTLOADER_BUILD
|
||||||
|
|
||||||
#We cannot include the esp32 component directly but we need its includes.
|
#We cannot include the esp32 component directly but we need its includes.
|
||||||
#This is fixed by adding CFLAGS from Makefile.projbuild
|
#This is fixed by adding CFLAGS from Makefile.projbuild
|
||||||
|
@ -51,7 +51,7 @@ enum {
|
|||||||
SPI_SPEED_20M,
|
SPI_SPEED_20M,
|
||||||
SPI_SPEED_80M = 0xF
|
SPI_SPEED_80M = 0xF
|
||||||
};
|
};
|
||||||
/*suppport flash size in esp32 */
|
/*supported flash sizes*/
|
||||||
enum {
|
enum {
|
||||||
SPI_SIZE_1MB = 0,
|
SPI_SIZE_1MB = 0,
|
||||||
SPI_SIZE_2MB,
|
SPI_SIZE_2MB,
|
||||||
|
@ -58,6 +58,7 @@ void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr,
|
|||||||
uint32_t irom_load_addr,
|
uint32_t irom_load_addr,
|
||||||
uint32_t irom_size,
|
uint32_t irom_size,
|
||||||
uint32_t entry_addr);
|
uint32_t entry_addr);
|
||||||
|
static void update_flash_config(struct flash_hdr* pfhdr);
|
||||||
|
|
||||||
|
|
||||||
void IRAM_ATTR call_start_cpu0()
|
void IRAM_ATTR call_start_cpu0()
|
||||||
@ -258,7 +259,7 @@ void bootloader_main()
|
|||||||
memset(&bs, 0, sizeof(bs));
|
memset(&bs, 0, sizeof(bs));
|
||||||
|
|
||||||
ESP_LOGI(TAG, "compile time " __TIME__ );
|
ESP_LOGI(TAG, "compile time " __TIME__ );
|
||||||
/* close watch dog here */
|
/* disable watch dog here */
|
||||||
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
|
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
|
||||||
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||||
SPIUnlock();
|
SPIUnlock();
|
||||||
@ -269,6 +270,8 @@ void bootloader_main()
|
|||||||
|
|
||||||
print_flash_info(&fhdr);
|
print_flash_info(&fhdr);
|
||||||
|
|
||||||
|
update_flash_config(&fhdr);
|
||||||
|
|
||||||
if (!load_partition_table(&bs, PARTITION_ADD)) {
|
if (!load_partition_table(&bs, PARTITION_ADD)) {
|
||||||
ESP_LOGE(TAG, "load partition table error!");
|
ESP_LOGE(TAG, "load partition table error!");
|
||||||
return;
|
return;
|
||||||
@ -364,7 +367,7 @@ void unpack_load_app(const partition_pos_t* partition)
|
|||||||
uint32_t irom_size = 0;
|
uint32_t irom_size = 0;
|
||||||
|
|
||||||
/* Reload the RTC memory sections whenever a non-deepsleep reset
|
/* Reload the RTC memory sections whenever a non-deepsleep reset
|
||||||
is occuring */
|
is occurring */
|
||||||
bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
|
bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic,
|
ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic,
|
||||||
@ -482,6 +485,36 @@ void IRAM_ATTR set_cache_and_start_app(
|
|||||||
(*entry)();
|
(*entry)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_flash_config(struct flash_hdr* pfhdr)
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
switch(pfhdr->spi_size) {
|
||||||
|
case SPI_SIZE_1MB:
|
||||||
|
size = 1;
|
||||||
|
break;
|
||||||
|
case SPI_SIZE_2MB:
|
||||||
|
size = 2;
|
||||||
|
break;
|
||||||
|
case SPI_SIZE_4MB:
|
||||||
|
size = 4;
|
||||||
|
break;
|
||||||
|
case SPI_SIZE_8MB:
|
||||||
|
size = 8;
|
||||||
|
break;
|
||||||
|
case SPI_SIZE_16MB:
|
||||||
|
size = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
size = 2;
|
||||||
|
}
|
||||||
|
Cache_Read_Disable( 0 );
|
||||||
|
// Set flash chip size
|
||||||
|
SPIParamCfg(g_rom_flashchip.deviceId, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
||||||
|
// TODO: set mode
|
||||||
|
// TODO: set frequency
|
||||||
|
Cache_Flush(0);
|
||||||
|
Cache_Read_Enable( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
void print_flash_info(struct flash_hdr* pfhdr)
|
void print_flash_info(struct flash_hdr* pfhdr)
|
||||||
{
|
{
|
||||||
|
@ -63,10 +63,22 @@ config MEMMAP_TRACEMEM
|
|||||||
of memory that can't be used for general purposes anymore. Disable this if you do not know
|
of memory that can't be used for general purposes anymore. Disable this if you do not know
|
||||||
what this is.
|
what this is.
|
||||||
|
|
||||||
|
config MEMMAP_TRACEMEM_TWOBANKS
|
||||||
|
bool "Reserve memory for tracing both pro as well as app cpu execution"
|
||||||
|
default "n"
|
||||||
|
depends on MEMMAP_TRACEMEM && MEMMAP_SMP
|
||||||
|
help
|
||||||
|
The ESP32 contains a feature which allows you to trace the execution path the processor
|
||||||
|
has taken through the program. This is stored in a chunk of 32K (16K for single-processor)
|
||||||
|
of memory that can't be used for general purposes anymore. Disable this if you do not know
|
||||||
|
what this is.
|
||||||
|
|
||||||
|
|
||||||
# Memory to reverse for trace, used in linker script
|
# Memory to reverse for trace, used in linker script
|
||||||
config TRACEMEM_RESERVE_DRAM
|
config TRACEMEM_RESERVE_DRAM
|
||||||
hex
|
hex
|
||||||
default 0x8000 if MEMMAP_TRACEMEM
|
default 0x8000 if MEMMAP_TRACEMEM && MEMMAP_TRACEMEM_TWOBANKS
|
||||||
|
default 0x4000 if MEMMAP_TRACEMEM && !MEMMAP_TRACEMEM_TWOBANKS
|
||||||
default 0x0
|
default 0x0
|
||||||
|
|
||||||
config MEMMAP_SPISRAM
|
config MEMMAP_SPISRAM
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
||||||
# please read the esp-idf build system document if you need to do this.
|
# please read the esp-idf build system document if you need to do this.
|
||||||
#
|
#
|
||||||
-include $(PROJECT_PATH)/build/include/config/auto.conf
|
-include include/config/auto.conf
|
||||||
|
|
||||||
COMPONENT_SRCDIRS := . hwcrypto
|
COMPONENT_SRCDIRS := . hwcrypto
|
||||||
|
|
||||||
@ -44,6 +44,8 @@ $(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
|
|||||||
# saves us from having to add the target to a Makefile.projbuild
|
# saves us from having to add the target to a Makefile.projbuild
|
||||||
$(COMPONENT_LIBRARY): esp32_out.ld
|
$(COMPONENT_LIBRARY): esp32_out.ld
|
||||||
|
|
||||||
|
# .. is BUILD_DIR_BASE here, as component makefiles
|
||||||
|
# are evaluated with CWD=component build dir
|
||||||
esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
||||||
$(CC) -I ../include -C -P -x c -E $< -o $@
|
$(CC) -I ../include -C -P -x c -E $< -o $@
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
#include "esp_ipc.h"
|
#include "esp_ipc.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#include "trax.h"
|
||||||
|
|
||||||
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
|
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
|
||||||
void start_cpu0_default(void) IRAM_ATTR;
|
void start_cpu0_default(void) IRAM_ATTR;
|
||||||
#if !CONFIG_FREERTOS_UNICORE
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
@ -131,6 +133,15 @@ void IRAM_ATTR call_start_cpu1()
|
|||||||
|
|
||||||
void start_cpu0_default(void)
|
void start_cpu0_default(void)
|
||||||
{
|
{
|
||||||
|
//Enable trace memory and immediately start trace.
|
||||||
|
#if CONFIG_MEMMAP_TRACEMEM
|
||||||
|
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
|
||||||
|
trax_enable(TRAX_ENA_PRO_APP);
|
||||||
|
#else
|
||||||
|
trax_enable(TRAX_ENA_PRO);
|
||||||
|
#endif
|
||||||
|
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
|
||||||
|
#endif
|
||||||
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
|
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
|
||||||
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
||||||
ets_setup_syscalls();
|
ets_setup_syscalls();
|
||||||
@ -147,6 +158,9 @@ void start_cpu0_default(void)
|
|||||||
#if !CONFIG_FREERTOS_UNICORE
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
void start_cpu1_default(void)
|
void start_cpu1_default(void)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
|
||||||
|
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
|
||||||
|
#endif
|
||||||
// Wait for FreeRTOS initialization to finish on PRO CPU
|
// Wait for FreeRTOS initialization to finish on PRO CPU
|
||||||
while (port_xSchedulerRunning[0] == 0) {
|
while (port_xSchedulerRunning[0] == 0) {
|
||||||
;
|
;
|
||||||
|
@ -186,7 +186,11 @@ void heap_alloc_caps_init() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MEMMAP_TRACEMEM
|
#if CONFIG_MEMMAP_TRACEMEM
|
||||||
|
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
|
||||||
disable_mem_region((void*)0x3fff8000, (void*)0x40000000); //knock out trace mem region
|
disable_mem_region((void*)0x3fff8000, (void*)0x40000000); //knock out trace mem region
|
||||||
|
#else
|
||||||
|
disable_mem_region((void*)0x3fff8000, (void*)0x3fffc000); //knock out trace mem region
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -191,14 +191,14 @@ esp_err_t esp_wifi_disconnect(void);
|
|||||||
esp_err_t esp_wifi_clear_fast_connect(void);
|
esp_err_t esp_wifi_clear_fast_connect(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Kick the all station or associated id equals to aid
|
* @brief deauthenticate all stations or associated id equals to aid
|
||||||
*
|
*
|
||||||
* @param uint16_t aid : when aid is 0, kick all stations, otherwise kick station whose associated id is aid
|
* @param uint16_t aid : when aid is 0, deauthenticate all stations, otherwise deauthenticate station whose associated id is aid
|
||||||
*
|
*
|
||||||
* @return ESP_OK : succeed
|
* @return ESP_OK : succeed
|
||||||
* @return others : fail
|
* @return others : fail
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_wifi_kick_station(uint16_t aid);
|
esp_err_t esp_wifi_deauth_sta(uint16_t aid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scan all available APs.
|
* @brief Scan all available APs.
|
||||||
@ -235,19 +235,30 @@ esp_err_t esp_wifi_scan_stop(void);
|
|||||||
* @return ESP_OK : succeed
|
* @return ESP_OK : succeed
|
||||||
* @return others : fail
|
* @return others : fail
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_wifi_get_ap_num(uint16_t *number);
|
esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get AP list found in last scan
|
* @brief Get AP list found in last scan
|
||||||
*
|
*
|
||||||
* @param uint16_t *number : as input param, it stores max AP number ap_list can hold, as output param, it store
|
* @param uint16_t *number : as input param, it stores max AP number ap_records can hold, as output param, it store
|
||||||
the actual AP number this API returns
|
the actual AP number this API returns
|
||||||
* @param wifi_ap_list_t *ap_list : a list to hold the found APs
|
* @param wifi_ap_record_t *ap_records: wifi_ap_record_t array to hold the found APs
|
||||||
*
|
*
|
||||||
* @return ESP_OK : succeed
|
* @return ESP_OK : succeed
|
||||||
* @return others : fail
|
* @return others : fail
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_wifi_get_ap_list(uint16_t *number, wifi_ap_list_t *ap_list);
|
esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get information of AP associated with ESP32 station
|
||||||
|
*
|
||||||
|
* @param wifi_ap_record_t *ap_info: the wifi_ap_record_t to hold station assocated AP
|
||||||
|
*
|
||||||
|
* @return ESP_OK : succeed
|
||||||
|
* @return others : fail
|
||||||
|
*/
|
||||||
|
esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t *ap_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set current power save type
|
* @brief Set current power save type
|
||||||
@ -471,14 +482,13 @@ esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf);
|
|||||||
*
|
*
|
||||||
* @attention SSC only API
|
* @attention SSC only API
|
||||||
*
|
*
|
||||||
* @param struct station_info **station : station list
|
* @param wifi_sta_list_t *sta: station list
|
||||||
*
|
*
|
||||||
* @return ESP_OK : succeed
|
* @return ESP_OK : succeed
|
||||||
* @return others : fail
|
* @return others : fail
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_wifi_get_station_list(struct station_info **station);
|
esp_err_t esp_wifi_ap_get_sta_list(wifi_sta_list_t *sta);
|
||||||
|
|
||||||
esp_err_t esp_wifi_free_station_list(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the WiFi API configuration storage type
|
* @brief Set the WiFi API configuration storage type
|
||||||
|
80
components/esp32/include/esp_wifi_internal.h
Normal file
80
components/esp32/include/esp_wifi_internal.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the APIs declared here are internal only APIs, it can only be used by
|
||||||
|
* espressif internal modules, such as SSC, LWIP, TCPIP adapter etc, espressif
|
||||||
|
* customers are not recommended to use them.
|
||||||
|
*
|
||||||
|
* If someone really want to use specified APIs declared in here, please contact
|
||||||
|
* espressif AE/developer to make sure you know the limitations or risk of
|
||||||
|
* the API, otherwise you may get unexpected behavior!!!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ESP_WIFI_INTERNAL_H__
|
||||||
|
#define __ESP_WIFI_INTERNAL_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "rom/queue.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_wifi_types.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get whether the wifi driver is allowed to transmit data or not
|
||||||
|
*
|
||||||
|
* @param none
|
||||||
|
*
|
||||||
|
* @return true : upper layer should stop to transmit data to wifi driver
|
||||||
|
* @return false : upper layer can transmit data to wifi driver
|
||||||
|
*/
|
||||||
|
bool esp_wifi_internal_tx_is_stop(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief free the rx buffer which allocated by wifi driver
|
||||||
|
*
|
||||||
|
* @param void* buffer: rx buffer pointer
|
||||||
|
*
|
||||||
|
* @return nonoe
|
||||||
|
*/
|
||||||
|
void esp_wifi_internal_free_rx_buffer(void* buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief transmit the buffer via wifi driver
|
||||||
|
*
|
||||||
|
* @attention1 TODO should modify the return type from bool to int
|
||||||
|
*
|
||||||
|
* @param wifi_interface_t wifi_if : wifi interface id
|
||||||
|
* @param void *buffer : the buffer to be tansmit
|
||||||
|
* @param u16_t len : the length of buffer
|
||||||
|
*
|
||||||
|
* @return True : success transmit the buffer to wifi driver
|
||||||
|
* False : failed to transmit the buffer to wifi driver
|
||||||
|
*/
|
||||||
|
bool esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, u16_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __ESP_WIFI_H__ */
|
@ -109,7 +109,7 @@ typedef struct {
|
|||||||
wifi_second_chan_t second; /**< second channel of AP */
|
wifi_second_chan_t second; /**< second channel of AP */
|
||||||
int8_t rssi; /**< signal strength of AP */
|
int8_t rssi; /**< signal strength of AP */
|
||||||
wifi_auth_mode_t authmode; /**< authmode of AP */
|
wifi_auth_mode_t authmode; /**< authmode of AP */
|
||||||
} wifi_ap_list_t;
|
} wifi_ap_record_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WIFI_PS_NONE, /**< No power save */
|
WIFI_PS_NONE, /**< No power save */
|
||||||
@ -150,10 +150,15 @@ typedef union {
|
|||||||
wifi_sta_config_t sta; /**< configuration of STA */
|
wifi_sta_config_t sta; /**< configuration of STA */
|
||||||
} wifi_config_t;
|
} wifi_config_t;
|
||||||
|
|
||||||
struct station_info {
|
typedef struct {
|
||||||
STAILQ_ENTRY(station_info) next;
|
uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */
|
||||||
uint8_t bssid[6];
|
}wifi_sta_info_t;
|
||||||
};
|
|
||||||
|
#define ESP_WIFI_MAX_CONN_NUM (8+2) /**< max number of sta the eSP32 soft-AP can connect */
|
||||||
|
typedef struct {
|
||||||
|
wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< station list */
|
||||||
|
uint8_t num; /**< number of station that associated with ESP32 soft-AP */
|
||||||
|
}wifi_sta_list_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WIFI_STORAGE_FLASH, /**< all configuration will strore in both memory and flash */
|
WIFI_STORAGE_FLASH, /**< all configuration will strore in both memory and flash */
|
||||||
|
@ -218,7 +218,7 @@ void SelectSpiFunction(uint32_t ishspi);
|
|||||||
void spi_flash_attach(uint32_t ishspi, bool legacy);
|
void spi_flash_attach(uint32_t ishspi, bool legacy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SPI Read Flash status register. We use CMD 0x05.
|
* @brief SPI Read Flash status register. We use CMD 0x05 (RDSR).
|
||||||
* Please do not call this function in SDK.
|
* Please do not call this function in SDK.
|
||||||
*
|
*
|
||||||
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
||||||
@ -232,7 +232,7 @@ void spi_flash_attach(uint32_t ishspi, bool legacy);
|
|||||||
SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
|
SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SPI Read Flash status register high 16 bit. We use CMD 0x35.
|
* @brief SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2).
|
||||||
* Please do not call this function in SDK.
|
* Please do not call this function in SDK.
|
||||||
*
|
*
|
||||||
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
||||||
@ -243,7 +243,7 @@ SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
|
|||||||
* SPI_FLASH_RESULT_ERR : read error.
|
* SPI_FLASH_RESULT_ERR : read error.
|
||||||
* SPI_FLASH_RESULT_TIMEOUT : read timeout.
|
* SPI_FLASH_RESULT_TIMEOUT : read timeout.
|
||||||
*/
|
*/
|
||||||
SpiFlashOpResult SPI_read_status_high(SpiFlashChip *spi, uint32_t *status);
|
SpiFlashOpResult SPI_read_status_high(uint32_t *status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write status to Falsh status register.
|
* @brief Write status to Falsh status register.
|
||||||
@ -503,6 +503,12 @@ void SPI_Write_Encrypt_Disable(void);
|
|||||||
*/
|
*/
|
||||||
SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t len);
|
SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief Global SpiFlashChip structure used by ROM functions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
extern SpiFlashChip g_rom_flashchip;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
@ -286,6 +286,7 @@ PROVIDE ( _global_impure_ptr = 0x3ffae0b0 );
|
|||||||
PROVIDE ( gmtime = 0x40059848 );
|
PROVIDE ( gmtime = 0x40059848 );
|
||||||
PROVIDE ( gmtime_r = 0x40059868 );
|
PROVIDE ( gmtime_r = 0x40059868 );
|
||||||
PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 );
|
PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 );
|
||||||
|
PROVIDE ( g_rom_flashchip = 0x3ffae270 );
|
||||||
PROVIDE ( gpio_init = 0x40009c20 );
|
PROVIDE ( gpio_init = 0x40009c20 );
|
||||||
PROVIDE ( gpio_input_get = 0x40009b88 );
|
PROVIDE ( gpio_input_get = 0x40009b88 );
|
||||||
PROVIDE ( gpio_input_get_high = 0x40009b9c );
|
PROVIDE ( gpio_input_get_high = 0x40009b9c );
|
||||||
@ -1584,6 +1585,8 @@ PROVIDE ( SPIEraseBlock = 0x40062c4c );
|
|||||||
PROVIDE ( SPIEraseChip = 0x40062c14 );
|
PROVIDE ( SPIEraseChip = 0x40062c14 );
|
||||||
PROVIDE ( SPIEraseSector = 0x40062ccc );
|
PROVIDE ( SPIEraseSector = 0x40062ccc );
|
||||||
PROVIDE ( spi_flash_attach = 0x40062a6c );
|
PROVIDE ( spi_flash_attach = 0x40062a6c );
|
||||||
|
/* NB: SPIUnlock @ 0x400628b0 has been replaced with an updated
|
||||||
|
version in the "spi_flash" component */
|
||||||
PROVIDE ( SPILock = 0x400628f0 );
|
PROVIDE ( SPILock = 0x400628f0 );
|
||||||
PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 );
|
PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 );
|
||||||
PROVIDE ( spi_modes = 0x3ff99270 );
|
PROVIDE ( spi_modes = 0x3ff99270 );
|
||||||
@ -1595,9 +1598,8 @@ PROVIDE ( SPIReadModeCnfig = 0x40062944 );
|
|||||||
PROVIDE ( SPI_read_status = 0x4006226c );
|
PROVIDE ( SPI_read_status = 0x4006226c );
|
||||||
/* This is static function, but can be used, not generated by script*/
|
/* This is static function, but can be used, not generated by script*/
|
||||||
PROVIDE ( SPI_read_status_high = 0x40062448 );
|
PROVIDE ( SPI_read_status_high = 0x40062448 );
|
||||||
PROVIDE ( SPIUnlock = 0x400628b0 );
|
|
||||||
PROVIDE ( SPI_user_command_read = 0x400621b0 );
|
PROVIDE ( SPI_user_command_read = 0x400621b0 );
|
||||||
PROVIDE ( spi_w25q16 = 0x3ffae270 );
|
PROVIDE ( SPI_flashchip_data = 0x3ffae270 );
|
||||||
PROVIDE ( SPIWrite = 0x40062d50 );
|
PROVIDE ( SPIWrite = 0x40062d50 );
|
||||||
/* This is static function, but can be used, not generated by script*/
|
/* This is static function, but can be used, not generated by script*/
|
||||||
PROVIDE ( SPI_write_enable = 0x40062320 );
|
PROVIDE ( SPI_write_enable = 0x40062320 );
|
||||||
|
@ -94,4 +94,31 @@ config ESPTOOLPY_FLASHFREQ
|
|||||||
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
||||||
default "20m" if ESPTOOLPY_FLASHFREQ_20M
|
default "20m" if ESPTOOLPY_FLASHFREQ_20M
|
||||||
|
|
||||||
|
|
||||||
|
choice ESPTOOLPY_FLASHSIZE
|
||||||
|
prompt "Flash size"
|
||||||
|
default ESPTOOLPY_FLASHSIZE_2MB
|
||||||
|
help
|
||||||
|
SPI flash size, in megabytes
|
||||||
|
|
||||||
|
config ESPTOOLPY_FLASHSIZE_1MB
|
||||||
|
bool "1 MB"
|
||||||
|
config ESPTOOLPY_FLASHSIZE_2MB
|
||||||
|
bool "2 MB"
|
||||||
|
config ESPTOOLPY_FLASHSIZE_4MB
|
||||||
|
bool "4 MB"
|
||||||
|
config ESPTOOLPY_FLASHSIZE_8MB
|
||||||
|
bool "8 MB"
|
||||||
|
config ESPTOOLPY_FLASHSIZE_16MB
|
||||||
|
bool "16 MB"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config ESPTOOLPY_FLASHSIZE
|
||||||
|
string
|
||||||
|
default "1MB" if ESPTOOLPY_FLASHSIZE_1MB
|
||||||
|
default "2MB" if ESPTOOLPY_FLASHSIZE_2MB
|
||||||
|
default "4MB" if ESPTOOLPY_FLASHSIZE_4MB
|
||||||
|
default "8MB" if ESPTOOLPY_FLASHSIZE_8MB
|
||||||
|
default "16MB" if ESPTOOLPY_FLASHSIZE_16MB
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -4,6 +4,7 @@ ESPPORT ?= $(CONFIG_ESPTOOLPY_PORT)
|
|||||||
ESPBAUD ?= $(CONFIG_ESPTOOLPY_BAUD)
|
ESPBAUD ?= $(CONFIG_ESPTOOLPY_BAUD)
|
||||||
ESPFLASHMODE ?= $(CONFIG_ESPTOOLPY_FLASHMODE)
|
ESPFLASHMODE ?= $(CONFIG_ESPTOOLPY_FLASHMODE)
|
||||||
ESPFLASHFREQ ?= $(CONFIG_ESPTOOLPY_FLASHFREQ)
|
ESPFLASHFREQ ?= $(CONFIG_ESPTOOLPY_FLASHFREQ)
|
||||||
|
ESPFLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE)
|
||||||
|
|
||||||
PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
||||||
|
|
||||||
@ -15,13 +16,15 @@ ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py
|
|||||||
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
||||||
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
|
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
|
||||||
|
|
||||||
|
ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE)
|
||||||
|
|
||||||
# the no-stub argument is temporary until esptool.py fully supports compressed uploads
|
# the no-stub argument is temporary until esptool.py fully supports compressed uploads
|
||||||
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ)
|
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS)
|
||||||
|
|
||||||
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||||
|
|
||||||
$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
|
$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
|
||||||
$(Q) $(ESPTOOLPY) elf2image --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) -o $@ $<
|
$(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $<
|
||||||
|
|
||||||
flash: all_binaries $(ESPTOOLPY_SRC)
|
flash: all_binaries $(ESPTOOLPY_SRC)
|
||||||
@echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..."
|
@echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..."
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 197ba605fe0c05e16bf4c5ec07b726adc8d86abc
|
Subproject commit 5c6962e894e0a118c9a4b5760876433493449260
|
@ -192,8 +192,14 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Multi-core: get current core ID */
|
/* Multi-core: get current core ID */
|
||||||
int xPortGetCoreID( void );
|
static inline uint32_t xPortGetCoreID() {
|
||||||
|
int id;
|
||||||
|
asm volatile(
|
||||||
|
"rsr.prid %0\n"
|
||||||
|
" extui %0,%0,13,1"
|
||||||
|
:"=r"(id));
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,26 @@ static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_I
|
|||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare
|
||||||
|
* *mux to compare, and if it's the same, will set *mux to set. It will return the old value
|
||||||
|
* of *addr in *set.
|
||||||
|
*
|
||||||
|
* Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the
|
||||||
|
* *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the
|
||||||
|
* ESP32, though. (Would show up directly if it did because the magic wouldn't match.)
|
||||||
|
*/
|
||||||
|
static inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) {
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"WSR %2,SCOMPARE1 \n"
|
||||||
|
"ISYNC \n"
|
||||||
|
"S32C1I %0, %1, 0 \n"
|
||||||
|
:"=r"(*set)
|
||||||
|
:"r"(addr), "r"(compare), "0"(*set)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
|
@ -322,12 +322,7 @@ STRUCT_END(XtSolFrame)
|
|||||||
#ifdef __ASSEMBLER__
|
#ifdef __ASSEMBLER__
|
||||||
.macro getcoreid reg
|
.macro getcoreid reg
|
||||||
rsr.prid \reg
|
rsr.prid \reg
|
||||||
bbci \reg,1,1f
|
extui \reg,\reg,13,1
|
||||||
movi \reg,1
|
|
||||||
j 2f
|
|
||||||
1:
|
|
||||||
movi \reg,0
|
|
||||||
2:
|
|
||||||
.endm
|
.endm
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -76,7 +76,6 @@ inline static void panicPutHex(int a) { }
|
|||||||
inline static void panicPutDec(int a) { }
|
inline static void panicPutDec(int a) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int xPortGetCoreID();
|
|
||||||
|
|
||||||
void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) {
|
void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) {
|
||||||
panicPutStr("***ERROR*** A stack overflow in task ");
|
panicPutStr("***ERROR*** A stack overflow in task ");
|
||||||
|
@ -253,28 +253,6 @@ void vPortAssertIfInISR()
|
|||||||
configASSERT(port_interruptNesting[xPortGetCoreID()]==0)
|
configASSERT(port_interruptNesting[xPortGetCoreID()]==0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare
|
|
||||||
* *mux to compare, and if it's the same, will set *mux to set. It will return the old value
|
|
||||||
* of *addr.
|
|
||||||
*
|
|
||||||
* Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the
|
|
||||||
* *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the
|
|
||||||
* ESP32, though. (Would show up directly if it did because the magic wouldn't match.)
|
|
||||||
*/
|
|
||||||
uint32_t uxPortCompareSet(volatile uint32_t *mux, uint32_t compare, uint32_t set)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"WSR %2,SCOMPARE1 \n" //initialize SCOMPARE1
|
|
||||||
"ISYNC \n" //wait sync
|
|
||||||
"S32C1I %0, %1, 0 \n" //store id into the lock, if the lock is the same as comparel. Otherwise, no write-access
|
|
||||||
:"=r"(set) \
|
|
||||||
:"r"(mux), "r"(compare), "0"(set) \
|
|
||||||
);
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For kernel use: Initialize a per-CPU mux. Mux will be initialized unlocked.
|
* For kernel use: Initialize a per-CPU mux. Mux will be initialized unlocked.
|
||||||
*/
|
*/
|
||||||
@ -310,7 +288,8 @@ void vPortCPUAcquireMutex(portMUX_TYPE *mux) {
|
|||||||
irqStatus=portENTER_CRITICAL_NESTED();
|
irqStatus=portENTER_CRITICAL_NESTED();
|
||||||
do {
|
do {
|
||||||
//Lock mux if it's currently unlocked
|
//Lock mux if it's currently unlocked
|
||||||
res=uxPortCompareSet(&mux->mux, portMUX_FREE_VAL, (xPortGetCoreID()<<portMUX_VAL_SHIFT)|portMUX_MAGIC_VAL);
|
res=(xPortGetCoreID()<<portMUX_VAL_SHIFT)|portMUX_MAGIC_VAL;
|
||||||
|
uxPortCompareSet(&mux->mux, portMUX_FREE_VAL, &res);
|
||||||
//If it wasn't free and we're the owner of the lock, we are locking recursively.
|
//If it wasn't free and we're the owner of the lock, we are locking recursively.
|
||||||
if ( (res != portMUX_FREE_VAL) && (((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT) == xPortGetCoreID()) ) {
|
if ( (res != portMUX_FREE_VAL) && (((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT) == xPortGetCoreID()) ) {
|
||||||
//Mux was already locked by us. Just bump the recurse count by one.
|
//Mux was already locked by us. Just bump the recurse count by one.
|
||||||
@ -362,29 +341,33 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux) {
|
|||||||
if ( (mux->mux & portMUX_MAGIC_MASK) != portMUX_MAGIC_VAL ) ets_printf("ERROR: vPortCPUReleaseMutex: mux %p is uninitialized (0x%X)!\n", mux, mux->mux);
|
if ( (mux->mux & portMUX_MAGIC_MASK) != portMUX_MAGIC_VAL ) ets_printf("ERROR: vPortCPUReleaseMutex: mux %p is uninitialized (0x%X)!\n", mux, mux->mux);
|
||||||
#endif
|
#endif
|
||||||
//Unlock mux if it's currently locked with a recurse count of 0
|
//Unlock mux if it's currently locked with a recurse count of 0
|
||||||
res=uxPortCompareSet(&mux->mux, (xPortGetCoreID()<<portMUX_VAL_SHIFT)|portMUX_MAGIC_VAL, portMUX_FREE_VAL);
|
res=portMUX_FREE_VAL;
|
||||||
|
uxPortCompareSet(&mux->mux, (xPortGetCoreID()<<portMUX_VAL_SHIFT)|portMUX_MAGIC_VAL, &res);
|
||||||
|
|
||||||
if ( res == portMUX_FREE_VAL ) {
|
if ( ((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT) == xPortGetCoreID() ) {
|
||||||
|
//Lock is valid, we can return safely. Just need to check if it's a recursive lock; if so we need to decrease the refcount.
|
||||||
|
if ( ((res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT)!=0) {
|
||||||
|
//We locked this, but the reccount isn't zero. Decrease refcount and continue.
|
||||||
|
recCnt=(res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT;
|
||||||
|
recCnt--;
|
||||||
|
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE
|
||||||
|
ets_printf("Recursive unlock: recCnt=%d last locked %s line %d, curr %s line %d\n", recCnt, lastLockedFn, lastLockedLine, fnName, line);
|
||||||
|
#endif
|
||||||
|
mux->mux=portMUX_MAGIC_VAL|(recCnt<<portMUX_CNT_SHIFT)|(xPortGetCoreID()<<portMUX_VAL_SHIFT);
|
||||||
|
}
|
||||||
|
} else if ( res == portMUX_FREE_VAL ) {
|
||||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
|
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
|
||||||
ets_printf("ERROR: vPortCPUReleaseMutex: mux %p was already unlocked!\n", mux);
|
ets_printf("ERROR: vPortCPUReleaseMutex: mux %p was already unlocked!\n", mux);
|
||||||
ets_printf("Last non-recursive unlock %s line %d, curr unlock %s line %d\n", lastLockedFn, lastLockedLine, fnName, line);
|
ets_printf("Last non-recursive unlock %s line %d, curr unlock %s line %d\n", lastLockedFn, lastLockedLine, fnName, line);
|
||||||
#endif
|
#endif
|
||||||
ret=pdFALSE;
|
ret=pdFALSE;
|
||||||
} else if ( ((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT) != xPortGetCoreID() ) {
|
} else {
|
||||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
|
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
|
||||||
ets_printf("ERROR: vPortCPUReleaseMutex: mux %p wasn't locked by this core (%d) but by core %d (ret=%x, mux=%x).\n", mux, xPortGetCoreID(), ((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT), res, mux->mux);
|
ets_printf("ERROR: vPortCPUReleaseMutex: mux %p wasn't locked by this core (%d) but by core %d (ret=%x, mux=%x).\n", mux, xPortGetCoreID(), ((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT), res, mux->mux);
|
||||||
ets_printf("Last non-recursive lock %s line %d\n", lastLockedFn, lastLockedLine);
|
ets_printf("Last non-recursive lock %s line %d\n", lastLockedFn, lastLockedLine);
|
||||||
ets_printf("Called by %s line %d\n", fnName, line);
|
ets_printf("Called by %s line %d\n", fnName, line);
|
||||||
#endif
|
#endif
|
||||||
ret=pdFALSE;
|
ret=pdFALSE;
|
||||||
} else if ( ((res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT)!=0) {
|
|
||||||
//We locked this, but the reccount isn't zero. Decrease refcount and continue.
|
|
||||||
recCnt=(res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT;
|
|
||||||
recCnt--;
|
|
||||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE
|
|
||||||
ets_printf("Recursive unlock: recCnt=%d last locked %s line %d, curr %s line %d\n", recCnt, lastLockedFn, lastLockedLine, fnName, line);
|
|
||||||
#endif
|
|
||||||
mux->mux=portMUX_MAGIC_VAL|(recCnt<<portMUX_CNT_SHIFT)|(xPortGetCoreID()<<portMUX_VAL_SHIFT);
|
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL_NESTED(irqStatus);
|
portEXIT_CRITICAL_NESTED(irqStatus);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -51,18 +51,6 @@ port_switch_flag:
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* C function to get proc ID.*/
|
|
||||||
.global xPortGetCoreID
|
|
||||||
.type xPortGetCoreID,@function
|
|
||||||
.align 4
|
|
||||||
xPortGetCoreID:
|
|
||||||
ENTRY(16)
|
|
||||||
getcoreid a2
|
|
||||||
RET(16)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
* _frxt_setup_switch
|
* _frxt_setup_switch
|
||||||
@ -81,9 +69,8 @@ _frxt_setup_switch:
|
|||||||
ENTRY(16)
|
ENTRY(16)
|
||||||
|
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
slli a3, a3, 2
|
|
||||||
movi a2, port_switch_flag
|
movi a2, port_switch_flag
|
||||||
add a2, a2, a3
|
addx4 a2, a3, a2
|
||||||
|
|
||||||
movi a3, 1
|
movi a3, 1
|
||||||
s32i a3, a2, 0
|
s32i a3, a2, 0
|
||||||
@ -128,12 +115,11 @@ _frxt_int_enter:
|
|||||||
Manage nesting directly rather than call the generic IntEnter()
|
Manage nesting directly rather than call the generic IntEnter()
|
||||||
(in windowed ABI we can't call a C function here anyway because PS.EXCM is still set).
|
(in windowed ABI we can't call a C function here anyway because PS.EXCM is still set).
|
||||||
*/
|
*/
|
||||||
getcoreid a3
|
getcoreid a4
|
||||||
slli a4, a3, 2 /* a4 = cpuid * 4 */
|
|
||||||
movi a2, port_xSchedulerRunning
|
movi a2, port_xSchedulerRunning
|
||||||
add a2, a2, a4
|
addx4 a2, a4, a2
|
||||||
movi a3, port_interruptNesting
|
movi a3, port_interruptNesting
|
||||||
add a3, a3, a4
|
addx4 a3, a4, a3
|
||||||
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
||||||
beqz a2, 1f /* scheduler not running, no tasks */
|
beqz a2, 1f /* scheduler not running, no tasks */
|
||||||
l32i a2, a3, 0 /* a2 = port_interruptNesting */
|
l32i a2, a3, 0 /* a2 = port_interruptNesting */
|
||||||
@ -142,14 +128,13 @@ _frxt_int_enter:
|
|||||||
bnei a2, 1, .Lnested /* !=0 before incr, so nested */
|
bnei a2, 1, .Lnested /* !=0 before incr, so nested */
|
||||||
|
|
||||||
movi a2, pxCurrentTCB
|
movi a2, pxCurrentTCB
|
||||||
add a2, a2, a4
|
addx4 a2, a4, a2
|
||||||
l32i a2, a2, 0 /* a2 = current TCB */
|
l32i a2, a2, 0 /* a2 = current TCB */
|
||||||
beqz a2, 1f
|
beqz a2, 1f
|
||||||
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
|
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
|
||||||
movi a1, port_IntStackTop /* a1 = top of intr stack */
|
movi a1, port_IntStackTop /* a1 = top of intr stack */
|
||||||
movi a2, configISR_STACK_SIZE
|
movi a2, configISR_STACK_SIZE
|
||||||
getcoreid a3
|
mull a2, a4, a2
|
||||||
mull a2, a3, a2
|
|
||||||
add a1, a1, a2 /* for current proc */
|
add a1, a1, a2 /* for current proc */
|
||||||
|
|
||||||
.Lnested:
|
.Lnested:
|
||||||
@ -177,12 +162,11 @@ _frxt_int_enter:
|
|||||||
.align 4
|
.align 4
|
||||||
_frxt_int_exit:
|
_frxt_int_exit:
|
||||||
|
|
||||||
getcoreid a3
|
getcoreid a4
|
||||||
slli a4, a3, 2 /* a4 is core * 4 */
|
|
||||||
movi a2, port_xSchedulerRunning
|
movi a2, port_xSchedulerRunning
|
||||||
add a2, a2, a4
|
addx4 a2, a4, a2
|
||||||
movi a3, port_interruptNesting
|
movi a3, port_interruptNesting
|
||||||
add a3, a3, a4
|
addx4 a3, a4, a3
|
||||||
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
|
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
|
||||||
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
||||||
beqz a2, .Lnoswitch /* scheduler not running, no tasks */
|
beqz a2, .Lnoswitch /* scheduler not running, no tasks */
|
||||||
@ -192,13 +176,13 @@ _frxt_int_exit:
|
|||||||
bnez a2, .Lnesting /* !=0 after decr so still nested */
|
bnez a2, .Lnesting /* !=0 after decr so still nested */
|
||||||
|
|
||||||
movi a2, pxCurrentTCB
|
movi a2, pxCurrentTCB
|
||||||
add a2, a2, a4
|
addx4 a2, a4, a2
|
||||||
l32i a2, a2, 0 /* a2 = current TCB */
|
l32i a2, a2, 0 /* a2 = current TCB */
|
||||||
beqz a2, 1f /* no task ? go to dispatcher */
|
beqz a2, 1f /* no task ? go to dispatcher */
|
||||||
l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */
|
l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */
|
||||||
|
|
||||||
movi a2, port_switch_flag /* address of switch flag */
|
movi a2, port_switch_flag /* address of switch flag */
|
||||||
add a2, a2, a4 /* point to flag for this cpu */
|
addx4 a2, a4, a2 /* point to flag for this cpu */
|
||||||
l32i a3, a2, 0 /* a3 = port_switch_flag */
|
l32i a3, a2, 0 /* a3 = port_switch_flag */
|
||||||
beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */
|
beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */
|
||||||
movi a3, 0
|
movi a3, 0
|
||||||
@ -404,14 +388,12 @@ _frxt_dispatch:
|
|||||||
call0 vTaskSwitchContext // Get next TCB to resume
|
call0 vTaskSwitchContext // Get next TCB to resume
|
||||||
movi a2, pxCurrentTCB
|
movi a2, pxCurrentTCB
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
slli a3, a3, 2
|
addx4 a2, a3, a2
|
||||||
add a2, a2, a3
|
|
||||||
#else
|
#else
|
||||||
call4 vTaskSwitchContext // Get next TCB to resume
|
call4 vTaskSwitchContext // Get next TCB to resume
|
||||||
movi a2, pxCurrentTCB
|
movi a2, pxCurrentTCB
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
slli a3, a3, 2
|
addx4 a2, a3, a2
|
||||||
add a2, a2, a3
|
|
||||||
#endif
|
#endif
|
||||||
l32i a3, a2, 0
|
l32i a3, a2, 0
|
||||||
l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */
|
l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */
|
||||||
@ -451,8 +433,7 @@ _frxt_dispatch:
|
|||||||
/* Restore CPENABLE from task's co-processor save area. */
|
/* Restore CPENABLE from task's co-processor save area. */
|
||||||
movi a3, pxCurrentTCB /* cp_state = */
|
movi a3, pxCurrentTCB /* cp_state = */
|
||||||
getcoreid a2
|
getcoreid a2
|
||||||
slli a2, a2, 2
|
addx4 a3, a2, a3
|
||||||
add a3, a2, a3
|
|
||||||
l32i a3, a3, 0
|
l32i a3, a3, 0
|
||||||
l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */
|
l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */
|
||||||
l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */
|
l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */
|
||||||
@ -541,8 +522,7 @@ vPortYield:
|
|||||||
|
|
||||||
movi a2, pxCurrentTCB
|
movi a2, pxCurrentTCB
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
slli a3, a3, 2
|
addx4 a2, a3, a2
|
||||||
add a2, a2, a3
|
|
||||||
l32i a2, a2, 0 /* a2 = pxCurrentTCB */
|
l32i a2, a2, 0 /* a2 = pxCurrentTCB */
|
||||||
movi a3, 0
|
movi a3, 0
|
||||||
s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */
|
s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */
|
||||||
@ -593,8 +573,7 @@ vPortYieldFromInt:
|
|||||||
/* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */
|
/* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */
|
||||||
movi a3, pxCurrentTCB /* cp_state = */
|
movi a3, pxCurrentTCB /* cp_state = */
|
||||||
getcoreid a2
|
getcoreid a2
|
||||||
slli a2, a2, 2
|
addx4 a3, a2, a3
|
||||||
add a3, a2, a3
|
|
||||||
l32i a3, a3, 0
|
l32i a3, a3, 0
|
||||||
|
|
||||||
l32i a2, a3, CP_TOPOFSTACK_OFFS
|
l32i a2, a3, CP_TOPOFSTACK_OFFS
|
||||||
@ -637,18 +616,17 @@ _frxt_task_coproc_state:
|
|||||||
|
|
||||||
/* We can use a3 as a scratchpad, the instances of code calling XT_RTOS_CP_STATE don't seem to need it saved. */
|
/* We can use a3 as a scratchpad, the instances of code calling XT_RTOS_CP_STATE don't seem to need it saved. */
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
slli a3, a3, 2 /* a3=coreid*4 */
|
|
||||||
movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */
|
movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */
|
||||||
add a15, a15, a3
|
addx4 a15, a3,a15
|
||||||
l32i a15, a15, 0
|
l32i a15, a15, 0
|
||||||
beqz a15, 1f
|
beqz a15, 1f
|
||||||
movi a15, port_interruptNesting /* && port_interruptNesting == 0 */
|
movi a15, port_interruptNesting /* && port_interruptNesting == 0 */
|
||||||
add a15, a15, a3
|
addx4 a15, a3, a15
|
||||||
l32i a15, a15, 0
|
l32i a15, a15, 0
|
||||||
bnez a15, 1f
|
bnez a15, 1f
|
||||||
|
|
||||||
movi a15, pxCurrentTCB
|
movi a15, pxCurrentTCB
|
||||||
add a15, a3, a15
|
addx4 a15, a3, a15
|
||||||
l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */
|
l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */
|
||||||
|
|
||||||
|
|
||||||
|
@ -3913,9 +3913,8 @@ In fact, nothing below this line has/is.
|
|||||||
|
|
||||||
/* Gotcha (which seems to be deliberate in FreeRTOS, according to
|
/* Gotcha (which seems to be deliberate in FreeRTOS, according to
|
||||||
http://www.freertos.org/FreeRTOS_Support_Forum_Archive/December_2012/freertos_PIC32_Bug_-_vTaskEnterCritical_6400806.html
|
http://www.freertos.org/FreeRTOS_Support_Forum_Archive/December_2012/freertos_PIC32_Bug_-_vTaskEnterCritical_6400806.html
|
||||||
) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED! Re-enabling the
|
) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED when the scheduler
|
||||||
scheduler will re-enable the interrupts instead. */
|
is not running. Re-enabling the scheduler will re-enable the interrupts instead. */
|
||||||
|
|
||||||
|
|
||||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||||
|
|
||||||
|
@ -904,16 +904,13 @@ _xt_coproc_exc:
|
|||||||
core we're running on now. */
|
core we're running on now. */
|
||||||
movi a2, pxCurrentTCB
|
movi a2, pxCurrentTCB
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
slli a3, a3, 2
|
addx4 a2, a3, a2
|
||||||
add a2, a2, a3
|
|
||||||
l32i a2, a2, 0 /* a2 = start of pxCurrentTCB[cpuid] */
|
l32i a2, a2, 0 /* a2 = start of pxCurrentTCB[cpuid] */
|
||||||
addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */
|
addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */
|
||||||
getcoreid a3
|
|
||||||
s32i a3, a2, 0 /* store current cpuid */
|
s32i a3, a2, 0 /* store current cpuid */
|
||||||
|
|
||||||
/* Grab correct xt_coproc_owner_sa for this core */
|
/* Grab correct xt_coproc_owner_sa for this core */
|
||||||
getcoreid a2
|
movi a2, XCHAL_CP_MAX << 2
|
||||||
movi a3, XCHAL_CP_MAX << 2
|
|
||||||
mull a2, a2, a3
|
mull a2, a2, a3
|
||||||
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
|
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
|
||||||
add a3, a3, a2
|
add a3, a3, a2
|
||||||
|
@ -284,7 +284,7 @@ static inline void heap_swap(int i, int j)
|
|||||||
}
|
}
|
||||||
#endif //BOOTLOADER_BUILD
|
#endif //BOOTLOADER_BUILD
|
||||||
|
|
||||||
inline IRAM_ATTR uint32_t esp_log_early_timestamp()
|
IRAM_ATTR uint32_t esp_log_early_timestamp()
|
||||||
{
|
{
|
||||||
return xthal_get_ccount() / (CPU_CLK_FREQ_ROM / 1000);
|
return xthal_get_ccount() / (CPU_CLK_FREQ_ROM / 1000);
|
||||||
}
|
}
|
||||||
|
@ -314,8 +314,8 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
|
|||||||
if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
|
if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
|
||||||
/* If the queued byte- or pbuf-count drops below the configured low-water limit,
|
/* If the queued byte- or pbuf-count drops below the configured low-water limit,
|
||||||
let select mark this pcb as writable again. */
|
let select mark this pcb as writable again. */
|
||||||
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
|
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT(conn->pcb.tcp)) &&
|
||||||
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
|
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT(conn->pcb.tcp))) {
|
||||||
conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
|
conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||||
}
|
}
|
||||||
@ -348,8 +348,8 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
|
|||||||
|
|
||||||
/* If the queued byte- or pbuf-count drops below the configured low-water limit,
|
/* If the queued byte- or pbuf-count drops below the configured low-water limit,
|
||||||
let select mark this pcb as writable again. */
|
let select mark this pcb as writable again. */
|
||||||
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
|
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT(conn->pcb.tcp) &&
|
||||||
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
|
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT(conn->pcb.tcp)))) {
|
||||||
conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
|
conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
|
API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
|
||||||
}
|
}
|
||||||
@ -1540,8 +1540,8 @@ err_mem:
|
|||||||
and let poll_tcp check writable space to mark the pcb writable again */
|
and let poll_tcp check writable space to mark the pcb writable again */
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
||||||
conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
|
conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
|
||||||
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
|
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT(conn->pcb.tcp)) ||
|
||||||
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
|
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT(conn->pcb.tcp))) {
|
||||||
/* The queued byte- or pbuf-count exceeds the configured low-water limit,
|
/* The queued byte- or pbuf-count exceeds the configured low-water limit,
|
||||||
let select mark this pcb as non-writable. */
|
let select mark this pcb as non-writable. */
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
||||||
|
@ -48,6 +48,9 @@ static void dbg_lwip_tcp_pcb_one_show(struct tcp_pcb* pcb)
|
|||||||
printf("rttest=%d rtseq=%d sa=%d sv=%d\n", pcb->rttest, pcb->rtseq, pcb->sa, pcb->sv);
|
printf("rttest=%d rtseq=%d sa=%d sv=%d\n", pcb->rttest, pcb->rtseq, pcb->sa, pcb->sv);
|
||||||
printf("rto=%d nrtx=%d\n", pcb->rto, pcb->nrtx);
|
printf("rto=%d nrtx=%d\n", pcb->rto, pcb->nrtx);
|
||||||
printf("dupacks=%d lastack=%d\n", pcb->dupacks, pcb->lastack);
|
printf("dupacks=%d lastack=%d\n", pcb->dupacks, pcb->lastack);
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
printf("per_soc_window=%d per_soc_snd_buf=%d\n", pcb->per_soc_tcp_wnd, pcb->per_soc_tcp_snd_buf);
|
||||||
|
#endif
|
||||||
printf("cwnd=%d ssthreash=%d\n", pcb->cwnd, pcb->ssthresh);
|
printf("cwnd=%d ssthreash=%d\n", pcb->cwnd, pcb->ssthresh);
|
||||||
printf("snd_next=%d snd_wl1=%d snd_wl2=%d\n", pcb->snd_nxt, pcb->snd_wl1, pcb->snd_wl2);
|
printf("snd_next=%d snd_wl1=%d snd_wl2=%d\n", pcb->snd_nxt, pcb->snd_wl1, pcb->snd_wl2);
|
||||||
printf("snd_lbb=%d snd_wnd=%d snd_wnd_max=%d\n", pcb->snd_lbb, pcb->snd_wnd, pcb->snd_wnd_max);
|
printf("snd_lbb=%d snd_wnd=%d snd_wnd_max=%d\n", pcb->snd_lbb, pcb->snd_wnd, pcb->snd_wnd_max);
|
||||||
|
@ -388,10 +388,8 @@ static void lwip_socket_drop_registered_memberships(int s);
|
|||||||
#endif /* LWIP_IGMP */
|
#endif /* LWIP_IGMP */
|
||||||
|
|
||||||
#ifdef LWIP_ESP8266
|
#ifdef LWIP_ESP8266
|
||||||
|
#include "esp_wifi_internal.h"
|
||||||
/* Since esp_wifi_tx_is_stop/system_get_free_heap_size are not an public wifi API, so extern them here*/
|
#include "esp_system.h"
|
||||||
extern size_t system_get_free_heap_size(void);
|
|
||||||
extern bool esp_wifi_tx_is_stop(void);
|
|
||||||
|
|
||||||
/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue.
|
/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue.
|
||||||
* Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket
|
* Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket
|
||||||
@ -402,9 +400,9 @@ extern bool esp_wifi_tx_is_stop(void);
|
|||||||
*/
|
*/
|
||||||
static inline void esp32_tx_flow_ctrl(void)
|
static inline void esp32_tx_flow_ctrl(void)
|
||||||
{
|
{
|
||||||
uint8_t _wait_delay = 0;
|
uint8_t _wait_delay = 1;
|
||||||
|
|
||||||
while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){
|
while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){
|
||||||
vTaskDelay(_wait_delay/portTICK_RATE_MS);
|
vTaskDelay(_wait_delay/portTICK_RATE_MS);
|
||||||
if (_wait_delay < 64) _wait_delay *= 2;
|
if (_wait_delay < 64) _wait_delay *= 2;
|
||||||
}
|
}
|
||||||
@ -2395,6 +2393,16 @@ lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *opt
|
|||||||
s, *(int *)optval));
|
s, *(int *)optval));
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP_KEEPALIVE */
|
#endif /* LWIP_TCP_KEEPALIVE */
|
||||||
|
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
case TCP_WINDOW:
|
||||||
|
*(int*)optval = (int)sock->conn->pcb.tcp->per_soc_tcp_wnd;
|
||||||
|
break;
|
||||||
|
case TCP_SNDBUF:
|
||||||
|
*(int*)optval = (int)sock->conn->pcb.tcp->per_soc_tcp_snd_buf;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
||||||
s, optname));
|
s, optname));
|
||||||
@ -2792,6 +2800,16 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
|
|||||||
s, sock->conn->pcb.tcp->keep_cnt));
|
s, sock->conn->pcb.tcp->keep_cnt));
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP_KEEPALIVE */
|
#endif /* LWIP_TCP_KEEPALIVE */
|
||||||
|
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
case TCP_WINDOW:
|
||||||
|
sock->conn->pcb.tcp->per_soc_tcp_wnd = ((u32_t)(*(const int*)optval)) * TCP_MSS;
|
||||||
|
break;
|
||||||
|
case TCP_SNDBUF:
|
||||||
|
sock->conn->pcb.tcp->per_soc_tcp_snd_buf = ((u32_t)(*(const int*)optval)) * TCP_MSS;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
||||||
s, optname));
|
s, optname));
|
||||||
|
@ -135,13 +135,15 @@
|
|||||||
//#endif
|
//#endif
|
||||||
#else /* LWIP_WND_SCALE */
|
#else /* LWIP_WND_SCALE */
|
||||||
|
|
||||||
#ifndef LWIP_ESP8266
|
#if (ESP_PER_SOC_TCP_WND == 0)
|
||||||
#if (LWIP_TCP && (TCP_WND > 0xffff))
|
#if (LWIP_TCP && (TCP_WND > 0xffff))
|
||||||
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
|
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* LWIP_WND_SCALE */
|
#endif /* LWIP_WND_SCALE */
|
||||||
|
|
||||||
|
#if (ESP_PER_SOC_TCP_WND == 0)
|
||||||
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
|
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
|
||||||
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
|
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
@ -149,7 +151,6 @@
|
|||||||
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LWIP_ESP8266
|
|
||||||
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
|
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
|
||||||
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
|
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
@ -289,6 +290,8 @@
|
|||||||
#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
|
#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
|
||||||
#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (ESP_PER_SOC_TCP_WND == 0)
|
||||||
#if TCP_SND_BUF < (2 * TCP_MSS)
|
#if TCP_SND_BUF < (2 * TCP_MSS)
|
||||||
#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||||
#endif
|
#endif
|
||||||
@ -304,6 +307,8 @@
|
|||||||
#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
|
#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
|
||||||
#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !MEMP_MEM_MALLOC && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
|
#if !MEMP_MEM_MALLOC && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
|
||||||
#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||||
#endif
|
#endif
|
||||||
@ -328,13 +333,6 @@
|
|||||||
void
|
void
|
||||||
lwip_init(void)
|
lwip_init(void)
|
||||||
{
|
{
|
||||||
#ifdef LWIP_ESP8266
|
|
||||||
// MEMP_NUM_TCP_PCB = 5;
|
|
||||||
// TCP_WND = (4 * TCP_MSS);
|
|
||||||
// TCP_MAXRTX = 12;
|
|
||||||
// TCP_SYNMAXRTX = 6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Modules initialization */
|
/* Modules initialization */
|
||||||
stats_init();
|
stats_init();
|
||||||
#if !NO_SYS
|
#if !NO_SYS
|
||||||
|
@ -83,6 +83,7 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LWIP_ESP8266
|
#ifdef LWIP_ESP8266
|
||||||
|
#include "esp_wifi_internal.h"
|
||||||
#define EP_OFFSET 0
|
#define EP_OFFSET 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -764,8 +765,7 @@ pbuf_free(struct pbuf *p)
|
|||||||
} else if (type == PBUF_ROM || type == PBUF_REF) {
|
} else if (type == PBUF_ROM || type == PBUF_REF) {
|
||||||
|
|
||||||
#ifdef LWIP_ESP8266
|
#ifdef LWIP_ESP8266
|
||||||
extern void system_pp_recycle_rx_pkt(void*);
|
if (type == PBUF_REF && p->eb != NULL ) esp_wifi_internal_free_rx_buffer(p->eb);
|
||||||
if (type == PBUF_REF && p->eb != NULL ) system_pp_recycle_rx_pkt(p->eb);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memp_free(MEMP_PBUF, p);
|
memp_free(MEMP_PBUF, p);
|
||||||
|
@ -638,7 +638,7 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
|
|||||||
{
|
{
|
||||||
u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
|
u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
|
||||||
|
|
||||||
if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
|
if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND(pcb) / 2), pcb->mss))) {
|
||||||
/* we can advertise more window */
|
/* we can advertise more window */
|
||||||
pcb->rcv_ann_wnd = pcb->rcv_wnd;
|
pcb->rcv_ann_wnd = pcb->rcv_wnd;
|
||||||
return new_right_edge - pcb->rcv_ann_right_edge;
|
return new_right_edge - pcb->rcv_ann_right_edge;
|
||||||
@ -694,10 +694,10 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
|||||||
wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
|
wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
|
||||||
|
|
||||||
/* If the change in the right edge of window is significant (default
|
/* If the change in the right edge of window is significant (default
|
||||||
* watermark is TCP_WND/4), then send an explicit update now.
|
* watermark is TCP_WND(pcb)/4), then send an explicit update now.
|
||||||
* Otherwise wait for a packet to be sent in the normal course of
|
* Otherwise wait for a packet to be sent in the normal course of
|
||||||
* events (or more window to be available later) */
|
* events (or more window to be available later) */
|
||||||
if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
|
if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD(pcb)) {
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
tcp_output(pcb);
|
tcp_output(pcb);
|
||||||
}
|
}
|
||||||
@ -827,9 +827,9 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
|||||||
pcb->snd_lbb = iss - 1;
|
pcb->snd_lbb = iss - 1;
|
||||||
/* Start with a window that does not need scaling. When window scaling is
|
/* Start with a window that does not need scaling. When window scaling is
|
||||||
enabled and used, the window is enlarged when both sides agree on scaling. */
|
enabled and used, the window is enlarged when both sides agree on scaling. */
|
||||||
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
|
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND(pcb));
|
||||||
pcb->rcv_ann_right_edge = pcb->rcv_nxt;
|
pcb->rcv_ann_right_edge = pcb->rcv_nxt;
|
||||||
pcb->snd_wnd = TCP_WND;
|
pcb->snd_wnd = TCP_WND(pcb);
|
||||||
/* As initial send MSS, we use TCP_MSS but limit it to 536.
|
/* As initial send MSS, we use TCP_MSS but limit it to 536.
|
||||||
The send MSS is updated when an MSS option is received. */
|
The send MSS is updated when an MSS option is received. */
|
||||||
pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
|
pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
|
||||||
@ -837,7 +837,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
|||||||
pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
|
pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
|
||||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||||
pcb->cwnd = 1;
|
pcb->cwnd = 1;
|
||||||
pcb->ssthresh = TCP_WND;
|
pcb->ssthresh = TCP_WND(pcb);
|
||||||
#if LWIP_CALLBACK_API
|
#if LWIP_CALLBACK_API
|
||||||
pcb->connected = connected;
|
pcb->connected = connected;
|
||||||
#else /* LWIP_CALLBACK_API */
|
#else /* LWIP_CALLBACK_API */
|
||||||
@ -1581,11 +1581,11 @@ tcp_alloc(u8_t prio)
|
|||||||
if (pcb != NULL) {
|
if (pcb != NULL) {
|
||||||
memset(pcb, 0, sizeof(struct tcp_pcb));
|
memset(pcb, 0, sizeof(struct tcp_pcb));
|
||||||
pcb->prio = prio;
|
pcb->prio = prio;
|
||||||
pcb->snd_buf = TCP_SND_BUF;
|
pcb->snd_buf = TCP_SND_BUF_DEFAULT;
|
||||||
pcb->snd_queuelen = 0;
|
pcb->snd_queuelen = 0;
|
||||||
/* Start with a window that does not need scaling. When window scaling is
|
/* Start with a window that does not need scaling. When window scaling is
|
||||||
enabled and used, the window is enlarged when both sides agree on scaling. */
|
enabled and used, the window is enlarged when both sides agree on scaling. */
|
||||||
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
|
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND(pcb));
|
||||||
#if LWIP_WND_SCALE
|
#if LWIP_WND_SCALE
|
||||||
/* snd_scale and rcv_scale are zero unless both sides agree to use scaling */
|
/* snd_scale and rcv_scale are zero unless both sides agree to use scaling */
|
||||||
pcb->snd_scale = 0;
|
pcb->snd_scale = 0;
|
||||||
@ -1608,7 +1608,6 @@ tcp_alloc(u8_t prio)
|
|||||||
pcb->snd_lbb = iss;
|
pcb->snd_lbb = iss;
|
||||||
pcb->tmr = tcp_ticks;
|
pcb->tmr = tcp_ticks;
|
||||||
pcb->last_timer = tcp_timer_ctr;
|
pcb->last_timer = tcp_timer_ctr;
|
||||||
|
|
||||||
pcb->polltmr = 0;
|
pcb->polltmr = 0;
|
||||||
|
|
||||||
#if LWIP_CALLBACK_API
|
#if LWIP_CALLBACK_API
|
||||||
@ -1624,7 +1623,13 @@ tcp_alloc(u8_t prio)
|
|||||||
#endif /* LWIP_TCP_KEEPALIVE */
|
#endif /* LWIP_TCP_KEEPALIVE */
|
||||||
|
|
||||||
pcb->keep_cnt_sent = 0;
|
pcb->keep_cnt_sent = 0;
|
||||||
|
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
pcb->per_soc_tcp_wnd = TCP_WND_DEFAULT;
|
||||||
|
pcb->per_soc_tcp_snd_buf = TCP_SND_BUF_DEFAULT;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return pcb;
|
return pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1745,9 +1745,9 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
|||||||
pcb->rcv_scale = TCP_RCV_SCALE;
|
pcb->rcv_scale = TCP_RCV_SCALE;
|
||||||
pcb->flags |= TF_WND_SCALE;
|
pcb->flags |= TF_WND_SCALE;
|
||||||
/* window scaling is enabled, we can use the full receive window */
|
/* window scaling is enabled, we can use the full receive window */
|
||||||
LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND));
|
LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND(pcb)));
|
||||||
LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND));
|
LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND(pcb)));
|
||||||
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND;
|
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND(pcb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -336,9 +336,9 @@ tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
|
|||||||
/* If total number of pbufs on the unsent/unacked queues exceeds the
|
/* If total number of pbufs on the unsent/unacked queues exceeds the
|
||||||
* configured maximum, return an error */
|
* configured maximum, return an error */
|
||||||
/* check for configured max queuelen and possible overflow */
|
/* check for configured max queuelen and possible overflow */
|
||||||
if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
|
if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN(pcb)) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
|
||||||
pcb->snd_queuelen, TCP_SND_QUEUELEN));
|
pcb->snd_queuelen, TCP_SND_QUEUELEN(pcb)));
|
||||||
TCP_STATS_INC(tcp.memerr);
|
TCP_STATS_INC(tcp.memerr);
|
||||||
pcb->flags |= TF_NAGLEMEMERR;
|
pcb->flags |= TF_NAGLEMEMERR;
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
@ -606,9 +606,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||||||
/* Now that there are more segments queued, we check again if the
|
/* Now that there are more segments queued, we check again if the
|
||||||
* length of the queue exceeds the configured maximum or
|
* length of the queue exceeds the configured maximum or
|
||||||
* overflows. */
|
* overflows. */
|
||||||
if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
|
if ((queuelen > TCP_SND_QUEUELEN(pcb)) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n",
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n",
|
||||||
queuelen, (int)TCP_SND_QUEUELEN));
|
queuelen, (int)TCP_SND_QUEUELEN(pcb)));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
@ -766,10 +766,10 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
|
|||||||
(flags & (TCP_SYN | TCP_FIN)) != 0);
|
(flags & (TCP_SYN | TCP_FIN)) != 0);
|
||||||
|
|
||||||
/* check for configured max queuelen and possible overflow (FIN flag should always come through!) */
|
/* check for configured max queuelen and possible overflow (FIN flag should always come through!) */
|
||||||
if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) &&
|
if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN(pcb)) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) &&
|
||||||
((flags & TCP_FIN) == 0)) {
|
((flags & TCP_FIN) == 0)) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
|
||||||
pcb->snd_queuelen, TCP_SND_QUEUELEN));
|
pcb->snd_queuelen, TCP_SND_QUEUELEN(pcb)));
|
||||||
TCP_STATS_INC(tcp.memerr);
|
TCP_STATS_INC(tcp.memerr);
|
||||||
pcb->flags |= TF_NAGLEMEMERR;
|
pcb->flags |= TF_NAGLEMEMERR;
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
@ -1301,6 +1301,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
|||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
struct tcp_hdr *tcphdr;
|
struct tcp_hdr *tcphdr;
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
|
|
||||||
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
|
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
|
||||||
@ -1315,10 +1316,18 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
|||||||
tcphdr->seqno = htonl(seqno);
|
tcphdr->seqno = htonl(seqno);
|
||||||
tcphdr->ackno = htonl(ackno);
|
tcphdr->ackno = htonl(ackno);
|
||||||
TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
|
TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
#if LWIP_WND_SCALE
|
||||||
|
tcphdr->wnd = PP_HTONS(((TCP_WND_DEFAULT >> TCP_RCV_SCALE) & 0xFFFF));
|
||||||
|
#else
|
||||||
|
tcphdr->wnd = PP_HTONS(TCP_WND_DEFAULT);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#if LWIP_WND_SCALE
|
#if LWIP_WND_SCALE
|
||||||
tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF));
|
tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF));
|
||||||
#else
|
#else
|
||||||
tcphdr->wnd = PP_HTONS(TCP_WND);
|
tcphdr->wnd = PP_HTONS(TCP_WND);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
tcphdr->urgp = 0;
|
tcphdr->urgp = 0;
|
||||||
|
@ -986,7 +986,7 @@
|
|||||||
* (2 * TCP_MSS) for things to work well
|
* (2 * TCP_MSS) for things to work well
|
||||||
*/
|
*/
|
||||||
#ifndef TCP_WND
|
#ifndef TCP_WND
|
||||||
#define TCP_WND (4 * TCP_MSS)
|
#define TCP_WND(pcb) (4 * TCP_MSS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1040,7 +1040,7 @@
|
|||||||
* To achieve good performance, this should be at least 2 * TCP_MSS.
|
* To achieve good performance, this should be at least 2 * TCP_MSS.
|
||||||
*/
|
*/
|
||||||
#ifndef TCP_SND_BUF
|
#ifndef TCP_SND_BUF
|
||||||
#define TCP_SND_BUF (2 * TCP_MSS)
|
#define TCP_SND_BUF(pcb) (2 * TCP_MSS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1048,7 +1048,7 @@
|
|||||||
* as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
|
* as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
|
||||||
*/
|
*/
|
||||||
#ifndef TCP_SND_QUEUELEN
|
#ifndef TCP_SND_QUEUELEN
|
||||||
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
|
#define TCP_SND_QUEUELEN(pcb) ((4 * (TCP_SND_BUF((pcb))) + (TCP_MSS - 1))/(TCP_MSS))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1057,7 +1057,7 @@
|
|||||||
* TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT).
|
* TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT).
|
||||||
*/
|
*/
|
||||||
#ifndef TCP_SNDLOWAT
|
#ifndef TCP_SNDLOWAT
|
||||||
#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
|
#define TCP_SNDLOWAT(pcb) LWIP_MIN(LWIP_MAX(((TCP_SND_BUF((pcb)))/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF((pcb))) - 1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1066,7 +1066,7 @@
|
|||||||
* this number, select returns writable (combined with TCP_SNDLOWAT).
|
* this number, select returns writable (combined with TCP_SNDLOWAT).
|
||||||
*/
|
*/
|
||||||
#ifndef TCP_SNDQUEUELOWAT
|
#ifndef TCP_SNDQUEUELOWAT
|
||||||
#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
|
#define TCP_SNDQUEUELOWAT(pcb) LWIP_MAX(((TCP_SND_QUEUELEN((pcb)))/2), 5)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1134,7 +1134,7 @@
|
|||||||
* explicit window update
|
* explicit window update
|
||||||
*/
|
*/
|
||||||
#ifndef TCP_WND_UPDATE_THRESHOLD
|
#ifndef TCP_WND_UPDATE_THRESHOLD
|
||||||
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
|
#define TCP_WND_UPDATE_THRESHOLD(pcb) LWIP_MIN((TCP_WND((pcb)) / 4), (TCP_MSS * 4))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,7 +92,7 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
|
|||||||
((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
|
((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
|
||||||
(((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
|
(((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
|
||||||
((tpcb)->unsent->len >= (tpcb)->mss))) || \
|
((tpcb)->unsent->len >= (tpcb)->mss))) || \
|
||||||
((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \
|
((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN(tpcb))) \
|
||||||
) ? 1 : 0)
|
) ? 1 : 0)
|
||||||
#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
|
#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
|
||||||
|
|
||||||
|
@ -190,7 +190,6 @@ struct msghdr {
|
|||||||
#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
|
#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
|
||||||
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
|
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure used for manipulating linger option.
|
* Structure used for manipulating linger option.
|
||||||
*/
|
*/
|
||||||
@ -250,6 +249,11 @@ struct linger {
|
|||||||
#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
|
#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
|
||||||
#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
|
#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
|
||||||
#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
|
#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
#define TCP_WINDOW 0x06 /* set pcb->per_soc_tcp_wnd */
|
||||||
|
#define TCP_SNDBUF 0x07 /* set pcb->per_soc_tcp_snd_buf */
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
|
|
||||||
#if LWIP_IPV6
|
#if LWIP_IPV6
|
||||||
|
@ -129,14 +129,14 @@ typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
|
|||||||
#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale))
|
#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale))
|
||||||
#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
|
#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
|
||||||
#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF))
|
#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF))
|
||||||
#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND)))
|
#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND(pcb) : TCPWND16(TCP_WND(pcb))))
|
||||||
typedef u32_t tcpwnd_size_t;
|
typedef u32_t tcpwnd_size_t;
|
||||||
typedef u16_t tcpflags_t;
|
typedef u16_t tcpflags_t;
|
||||||
#else
|
#else
|
||||||
#define RCV_WND_SCALE(pcb, wnd) (wnd)
|
#define RCV_WND_SCALE(pcb, wnd) (wnd)
|
||||||
#define SND_WND_SCALE(pcb, wnd) (wnd)
|
#define SND_WND_SCALE(pcb, wnd) (wnd)
|
||||||
#define TCPWND16(x) (x)
|
#define TCPWND16(x) (x)
|
||||||
#define TCP_WND_MAX(pcb) TCP_WND
|
#define TCP_WND_MAX(pcb) TCP_WND(pcb)
|
||||||
typedef u16_t tcpwnd_size_t;
|
typedef u16_t tcpwnd_size_t;
|
||||||
typedef u8_t tcpflags_t;
|
typedef u8_t tcpflags_t;
|
||||||
#endif
|
#endif
|
||||||
@ -236,6 +236,11 @@ struct tcp_pcb {
|
|||||||
u8_t dupacks;
|
u8_t dupacks;
|
||||||
u32_t lastack; /* Highest acknowledged seqno. */
|
u32_t lastack; /* Highest acknowledged seqno. */
|
||||||
|
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
tcpwnd_size_t per_soc_tcp_wnd; /* per tcp socket tcp window size */
|
||||||
|
tcpwnd_size_t per_soc_tcp_snd_buf; /* per tcp socket tcp send buffer size */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* congestion avoidance/control variables */
|
/* congestion avoidance/control variables */
|
||||||
tcpwnd_size_t cwnd;
|
tcpwnd_size_t cwnd;
|
||||||
tcpwnd_size_t ssthresh;
|
tcpwnd_size_t ssthresh;
|
||||||
@ -402,6 +407,10 @@ const char* tcp_debug_state_str(enum tcp_state s);
|
|||||||
/* for compatibility with older implementation */
|
/* for compatibility with older implementation */
|
||||||
#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
|
#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
|
||||||
|
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
#define PER_SOC_WND(pcb) (pcb->per_soc_wnd)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -225,18 +225,21 @@ extern unsigned long os_random(void);
|
|||||||
* TCP_WND: The size of a TCP window. This must be at least
|
* TCP_WND: The size of a TCP window. This must be at least
|
||||||
* (2 * TCP_MSS) for things to work well
|
* (2 * TCP_MSS) for things to work well
|
||||||
*/
|
*/
|
||||||
#define PERF 1
|
|
||||||
|
#define ESP_PER_SOC_TCP_WND 1
|
||||||
|
#if ESP_PER_SOC_TCP_WND
|
||||||
|
#define TCP_WND_DEFAULT (4*TCP_MSS)
|
||||||
|
#define TCP_SND_BUF_DEFAULT (2*TCP_MSS)
|
||||||
|
|
||||||
|
#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd)
|
||||||
|
#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf)
|
||||||
|
#else
|
||||||
#ifdef PERF
|
#ifdef PERF
|
||||||
extern unsigned char misc_prof_get_tcpw(void);
|
extern unsigned char misc_prof_get_tcpw(void);
|
||||||
extern unsigned char misc_prof_get_tcp_snd_buf(void);
|
extern unsigned char misc_prof_get_tcp_snd_buf(void);
|
||||||
#define TCP_WND (misc_prof_get_tcpw()*TCP_MSS)
|
#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS)
|
||||||
#define TCP_SND_BUF (misc_prof_get_tcp_snd_buf()*TCP_MSS)
|
#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS)
|
||||||
|
#endif
|
||||||
#else
|
|
||||||
|
|
||||||
#define TCP_WND (4 * TCP_MSS)
|
|
||||||
#define TCP_SND_BUF (2 * TCP_MSS)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
|
|
||||||
|
#include "esp_wifi_internal.h"
|
||||||
|
|
||||||
#include "lwip/err.h"
|
#include "lwip/err.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -18,8 +20,6 @@ err_t wlanif_init(struct netif *netif);
|
|||||||
|
|
||||||
void wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb);
|
void wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb);
|
||||||
|
|
||||||
bool ieee80211_output(wifi_interface_t wifi_if, void *buffer, u16_t len);
|
|
||||||
|
|
||||||
wifi_interface_t wifi_get_interface(void *dev);
|
wifi_interface_t wifi_get_interface(void *dev);
|
||||||
|
|
||||||
void netif_reg_addr_change_cb(void* cb);
|
void netif_reg_addr_change_cb(void* cb);
|
||||||
|
@ -150,12 +150,12 @@ low_level_output(struct netif *netif, struct pbuf *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_output(wifi_if, q->payload, pbuf_x_len);
|
esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for(q = p; q != NULL; q = q->next) {
|
||||||
ieee80211_output(wifi_if, q->payload, q->len);
|
esp_wifi_internal_tx(wifi_if, q->payload, q->len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7177,7 +7177,7 @@ uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session,
|
|||||||
return session->remote_settings.max_header_list_size;
|
return session->remote_settings.max_header_list_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nghttp2_session_upgrade_internal(nghttp2_session *session,
|
static int nghttp2_session_upgrade_internal(nghttp2_session *session,
|
||||||
|
@ -769,7 +769,7 @@ void Page::invalidateCache()
|
|||||||
|
|
||||||
void Page::debugDump() const
|
void Page::debugDump() const
|
||||||
{
|
{
|
||||||
printf("state=%x addr=%x seq=%d\nfirstUsed=%d nextFree=%d used=%d erased=%d\n", mState, mBaseAddress, mSeqNumber, static_cast<int>(mFirstUsedEntry), static_cast<int>(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount);
|
printf("state=%x addr=%x seq=%d\nfirstUsed=%d nextFree=%d used=%d erased=%d\n", (int) mState, mBaseAddress, mSeqNumber, static_cast<int>(mFirstUsedEntry), static_cast<int>(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount);
|
||||||
size_t skip = 0;
|
size_t skip = 0;
|
||||||
for (size_t i = 0; i < ENTRY_COUNT; ++i) {
|
for (size_t i = 0; i < ENTRY_COUNT; ++i) {
|
||||||
printf("%3d: ", static_cast<int>(i));
|
printf("%3d: ", static_cast<int>(i));
|
||||||
|
@ -49,7 +49,7 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount)
|
|||||||
return activatePage();
|
return activatePage();
|
||||||
} else {
|
} else {
|
||||||
uint32_t lastSeqNo;
|
uint32_t lastSeqNo;
|
||||||
assert(mPageList.back().getSeqNumber(lastSeqNo) == ESP_OK);
|
ESP_ERROR_CHECK( mPageList.back().getSeqNumber(lastSeqNo) );
|
||||||
mSeqNumber = lastSeqNo + 1;
|
mSeqNumber = lastSeqNo + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,9 @@ esp_err_t PageManager::requestNewPage()
|
|||||||
Page* newPage = &mPageList.back();
|
Page* newPage = &mPageList.back();
|
||||||
|
|
||||||
Page* erasedPage = maxErasedItemsPageIt;
|
Page* erasedPage = maxErasedItemsPageIt;
|
||||||
|
#ifndef NDEBUG
|
||||||
size_t usedEntries = erasedPage->getUsedEntryCount();
|
size_t usedEntries = erasedPage->getUsedEntryCount();
|
||||||
|
#endif
|
||||||
err = erasedPage->markFreeing();
|
err = erasedPage->markFreeing();
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -123,8 +123,7 @@ esp_err_t Storage::writeItem(uint8_t nsIndex, ItemType datatype, const char* key
|
|||||||
if (findPage) {
|
if (findPage) {
|
||||||
if (findPage->state() == Page::PageState::UNINITIALIZED ||
|
if (findPage->state() == Page::PageState::UNINITIALIZED ||
|
||||||
findPage->state() == Page::PageState::INVALID) {
|
findPage->state() == Page::PageState::INVALID) {
|
||||||
auto err = findItem(nsIndex, datatype, key, findPage, item);
|
ESP_ERROR_CHECK( findItem(nsIndex, datatype, key, findPage, item) );
|
||||||
assert(err == ESP_OK);
|
|
||||||
}
|
}
|
||||||
err = findPage->eraseItem(nsIndex, datatype, key);
|
err = findPage->eraseItem(nsIndex, datatype, key);
|
||||||
if (err == ESP_ERR_FLASH_OP_FAIL) {
|
if (err == ESP_ERR_FLASH_OP_FAIL) {
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
COMPONENT_ADD_INCLUDEDIRS := include
|
COMPONENT_ADD_INCLUDEDIRS := include
|
||||||
|
|
||||||
|
ifdef IS_BOOTLOADER_BUILD
|
||||||
|
# Bootloader needs updated SPIUnlock from this file
|
||||||
|
COMPONENT_OBJS := spi_flash_rom_patch.o
|
||||||
|
endif
|
||||||
|
|
||||||
include $(IDF_PATH)/make/component_common.mk
|
include $(IDF_PATH)/make/component_common.mk
|
||||||
|
72
components/spi_flash/spi_flash_rom_patch.c
Normal file
72
components/spi_flash/spi_flash_rom_patch.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include "rom/spi_flash.h"
|
||||||
|
#include "soc/spi_reg.h"
|
||||||
|
|
||||||
|
static const uint32_t STATUS_QIE_BIT = (1 << 9); /* Quad Enable */
|
||||||
|
|
||||||
|
#define SPI_IDX 1
|
||||||
|
#define OTH_IDX 0
|
||||||
|
|
||||||
|
extern SpiFlashChip SPI_flashchip_data;
|
||||||
|
|
||||||
|
static void IRAM_ATTR Wait_SPI_Idle(void)
|
||||||
|
{
|
||||||
|
/* Wait for SPI state machine to be idle */
|
||||||
|
while((REG_READ(SPI_EXT2_REG(SPI_IDX)) & SPI_ST)) {
|
||||||
|
}
|
||||||
|
while(REG_READ(SPI_EXT2_REG(OTH_IDX)) & SPI_ST) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modified version of SPIUnlock() that replaces version in ROM.
|
||||||
|
|
||||||
|
This works around a bug where SPIUnlock sometimes reads the wrong
|
||||||
|
high status byte (RDSR2 result) and then copies it back to the
|
||||||
|
flash status, which can cause the CMP bit or Status Register
|
||||||
|
Protect bit to become set.
|
||||||
|
|
||||||
|
Like other ROM SPI functions, this function is not designed to be
|
||||||
|
called directly from an RTOS environment without taking precautions
|
||||||
|
about interrupts, CPU coordination, flash mapping. However some of
|
||||||
|
the functions in esp_spi_flash.c call it.
|
||||||
|
*/
|
||||||
|
SpiFlashOpResult IRAM_ATTR SPIUnlock(void)
|
||||||
|
{
|
||||||
|
uint32_t status;
|
||||||
|
|
||||||
|
Wait_SPI_Idle();
|
||||||
|
|
||||||
|
if (SPI_read_status_high(&status) != SPI_FLASH_RESULT_OK) {
|
||||||
|
return SPI_FLASH_RESULT_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear all bits except QIE, if it is set.
|
||||||
|
(This is different from ROM SPIUnlock, which keeps all bits as-is.)
|
||||||
|
*/
|
||||||
|
status &= STATUS_QIE_BIT;
|
||||||
|
|
||||||
|
Wait_SPI_Idle();
|
||||||
|
REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
|
||||||
|
while(REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
|
||||||
|
}
|
||||||
|
Wait_SPI_Idle();
|
||||||
|
|
||||||
|
SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
|
||||||
|
if (SPI_write_status(&SPI_flashchip_data, status) != SPI_FLASH_RESULT_OK) {
|
||||||
|
return SPI_FLASH_RESULT_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPI_FLASH_RESULT_OK;
|
||||||
|
}
|
@ -67,11 +67,15 @@ typedef struct {
|
|||||||
typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t;
|
typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t;
|
||||||
|
|
||||||
#if CONFIG_DHCP_STA_LIST
|
#if CONFIG_DHCP_STA_LIST
|
||||||
struct station_list {
|
typedef struct {
|
||||||
STAILQ_ENTRY(station_list) next;
|
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
ip4_addr_t ip;
|
ip4_addr_t ip;
|
||||||
};
|
}tcpip_adapter_sta_info_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM+2];
|
||||||
|
uint8_t num;
|
||||||
|
}tcpip_adapter_sta_list_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -359,26 +363,14 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev);
|
|||||||
/**
|
/**
|
||||||
* @brief Get the station information list
|
* @brief Get the station information list
|
||||||
*
|
*
|
||||||
* @note This function should be called in AP mode and dhcp server started, and the list should
|
* @param[in] wifi_sta_list_t *wifi_sta_list: station list info
|
||||||
* be by using tcpip_adapter_free_sta_list.
|
* @param[out] tcpip_adapter_sta_list_t *tcpip_sta_list: station list info
|
||||||
*
|
|
||||||
* @param[in] sta_info: station information
|
|
||||||
* @param[out] sta_list: station information list
|
|
||||||
*
|
*
|
||||||
* @return ESP_OK
|
* @return ESP_OK
|
||||||
* ESP_ERR_TCPIP_ADAPTER_NO_MEM
|
* ESP_ERR_TCPIP_ADAPTER_NO_MEM
|
||||||
* ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
|
* ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
|
||||||
*/
|
*/
|
||||||
esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **sta_list);
|
esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Free the station information list's memory
|
|
||||||
*
|
|
||||||
* @param sta_list: station information list
|
|
||||||
*
|
|
||||||
* @return ESP_OK
|
|
||||||
*/
|
|
||||||
esp_err_t tcpip_adapter_free_sta_list(struct station_list *sta_list);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,9 @@ esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
|
|||||||
|
|
||||||
if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
|
if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
|
||||||
dhcps_stop(esp_netif[tcpip_if]); // TODO: dhcps checks status by its self
|
dhcps_stop(esp_netif[tcpip_if]); // TODO: dhcps checks status by its self
|
||||||
dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
|
if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status){
|
||||||
|
dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
|
||||||
|
}
|
||||||
} else if (tcpip_if == TCPIP_ADAPTER_IF_STA) {
|
} else if (tcpip_if == TCPIP_ADAPTER_IF_STA) {
|
||||||
dhcp_release(esp_netif[tcpip_if]);
|
dhcp_release(esp_netif[tcpip_if]);
|
||||||
dhcp_stop(esp_netif[tcpip_if]);
|
dhcp_stop(esp_netif[tcpip_if]);
|
||||||
@ -588,45 +590,17 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev)
|
|||||||
return WIFI_IF_MAX;
|
return WIFI_IF_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **sta_list)
|
esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list)
|
||||||
{
|
{
|
||||||
struct station_info *info = sta_info;
|
int i;
|
||||||
struct station_list *list;
|
|
||||||
STAILQ_HEAD(, station_list) list_head;
|
|
||||||
|
|
||||||
if (sta_list == NULL)
|
if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL))
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
|
|
||||||
STAILQ_INIT(&list_head);
|
memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t));
|
||||||
|
for (i=0; i<wifi_sta_list->num; i++){
|
||||||
while (info != NULL) {
|
memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
|
||||||
list = (struct station_list *)malloc(sizeof(struct station_list));
|
dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip);
|
||||||
memset(list, 0, sizeof (struct station_list));
|
|
||||||
|
|
||||||
if (list == NULL) {
|
|
||||||
return ESP_ERR_TCPIP_ADAPTER_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(list->mac, info->bssid, 6);
|
|
||||||
dhcp_search_ip_on_mac(list->mac, &list->ip);
|
|
||||||
STAILQ_INSERT_TAIL(&list_head, list, next);
|
|
||||||
|
|
||||||
info = STAILQ_NEXT(info, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
*sta_list = STAILQ_FIRST(&list_head);
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_free_sta_list(struct station_list *sta_list)
|
|
||||||
{
|
|
||||||
struct station_list *list = sta_list;
|
|
||||||
|
|
||||||
while (sta_list != NULL) {
|
|
||||||
list = sta_list;
|
|
||||||
sta_list = STAILQ_NEXT(sta_list, next);
|
|
||||||
free(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
5
components/xtensa-debug-module/component.mk
Executable file
5
components/xtensa-debug-module/component.mk
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Component Makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(IDF_PATH)/make/component_common.mk
|
32
components/xtensa-debug-module/eri.c
Normal file
32
components/xtensa-debug-module/eri.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "eri.h"
|
||||||
|
|
||||||
|
uint32_t eri_read(int addr) {
|
||||||
|
uint32_t ret;
|
||||||
|
asm(
|
||||||
|
"RER %0,%1"
|
||||||
|
:"=r"(ret):"r"(addr)
|
||||||
|
);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eri_write(int addr, uint32_t data) {
|
||||||
|
asm volatile (
|
||||||
|
"WER %0,%1"
|
||||||
|
::"r"(data),"r"(addr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
31
components/xtensa-debug-module/include/eri.h
Normal file
31
components/xtensa-debug-module/include/eri.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef ERI_H
|
||||||
|
#define ERI_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
The ERI is a bus internal to each Xtensa core. It connects, amongst others, to the debug interface, where it
|
||||||
|
allows reading/writing the same registers as available over JTAG.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform an ERI read
|
||||||
|
* @param addr : ERI register to read from
|
||||||
|
*
|
||||||
|
* @return Value read
|
||||||
|
*/
|
||||||
|
uint32_t eri_read(int addr);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform an ERI write
|
||||||
|
* @param addr : ERI register to write to
|
||||||
|
* @param data : Value to write
|
||||||
|
*
|
||||||
|
* @return Value read
|
||||||
|
*/
|
||||||
|
void eri_write(int addr, uint32_t data);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
62
components/xtensa-debug-module/include/trax.h
Normal file
62
components/xtensa-debug-module/include/trax.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "eri.h"
|
||||||
|
#include "xtensa-debug-module.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TRAX_DOWNCOUNT_WORDS,
|
||||||
|
TRAX_DOWNCOUNT_INSTRUCTIONS
|
||||||
|
} trax_downcount_unit_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TRAX_ENA_NONE = 0,
|
||||||
|
TRAX_ENA_PRO,
|
||||||
|
TRAX_ENA_APP,
|
||||||
|
TRAX_ENA_PRO_APP,
|
||||||
|
TRAX_ENA_PRO_APP_SWAP
|
||||||
|
} trax_ena_select_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the trax memory blocks to be used as Trax memory.
|
||||||
|
*
|
||||||
|
* @param pro_cpu_enable : true if Trax needs to be enabled for the pro CPU
|
||||||
|
* @param app_cpu_enable : true if Trax needs to be enabled for the pro CPU
|
||||||
|
* @param swap_regions : Normally, the pro CPU writes to Trax mem block 0 while
|
||||||
|
* the app cpu writes to block 1. Setting this to true
|
||||||
|
* inverts this.
|
||||||
|
*
|
||||||
|
* @return esp_err_t. Fails with ESP_ERR_NO_MEM if Trax enable is requested for 2 CPUs
|
||||||
|
* but memmap only has room for 1, or if Trax memmap is disabled
|
||||||
|
* entirely.
|
||||||
|
*/
|
||||||
|
int trax_enable(trax_ena_select_t ena);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start a Trax trace on the current CPU
|
||||||
|
*
|
||||||
|
* @param units_until_stop : Set the units of the delay that gets passed to
|
||||||
|
* trax_trigger_traceend_after_delay. One of TRAX_DOWNCOUNT_WORDS
|
||||||
|
* or TRAX_DOWNCOUNT_INSTRUCTIONS.
|
||||||
|
*
|
||||||
|
* @return esp_err_t. Fails with ESP_ERR_NO_MEM if Trax is disabled.
|
||||||
|
*/
|
||||||
|
int trax_start_trace(trax_downcount_unit_t units_until_stop);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger a Trax trace stop after the indicated delay. If this is called
|
||||||
|
* before and the previous delay hasn't ended yet, this will overwrite
|
||||||
|
* that delay with the new value. The delay will always start at the time
|
||||||
|
* the function is called.
|
||||||
|
*
|
||||||
|
* @param delay : The delay to stop the trace in, in the unit indicated to
|
||||||
|
* trax_start_trace. Note: the trace memory has 4K words available.
|
||||||
|
*
|
||||||
|
* @return esp_err_t
|
||||||
|
*/
|
||||||
|
int trax_trigger_traceend_after_delay(int delay);
|
||||||
|
|
||||||
|
|
75
components/xtensa-debug-module/include/xtensa-debug-module.h
Normal file
75
components/xtensa-debug-module/include/xtensa-debug-module.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#ifndef XTENSA_DEBUG_MODULE_H
|
||||||
|
#define XTENSA_DEBUG_MODULE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
ERI registers / OCD offsets and field definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ERI_DEBUG_OFFSET 0x100000
|
||||||
|
|
||||||
|
#define ERI_TRAX_OFFSET (ERI_DEBUG_OFFSET+0)
|
||||||
|
#define ERI_PERFMON_OFFSET (ERI_DEBUG_OFFSET+0x1000)
|
||||||
|
#define ERI_OCDREG_OFFSET (ERI_DEBUG_OFFSET+0x2000)
|
||||||
|
#define ERI_MISCDBG_OFFSET (ERI_DEBUG_OFFSET+0x3000)
|
||||||
|
#define ERI_CORESIGHT_OFFSET (ERI_DEBUG_OFFSET+0x3F00)
|
||||||
|
|
||||||
|
#define ERI_TRAX_TRAXID (ERI_TRAX_OFFSET+0x00)
|
||||||
|
#define ERI_TRAX_TRAXCTRL (ERI_TRAX_OFFSET+0x04)
|
||||||
|
#define ERI_TRAX_TRAXSTAT (ERI_TRAX_OFFSET+0x08)
|
||||||
|
#define ERI_TRAX_TRAXDATA (ERI_TRAX_OFFSET+0x0C)
|
||||||
|
#define ERI_TRAX_TRAXADDR (ERI_TRAX_OFFSET+0x10)
|
||||||
|
#define ERI_TRAX_TRIGGERPC (ERI_TRAX_OFFSET+0x14)
|
||||||
|
#define ERI_TRAX_PCMATCHCTRL (ERI_TRAX_OFFSET+0x18)
|
||||||
|
#define ERI_TRAX_DELAYCNT (ERI_TRAX_OFFSET+0x1C)
|
||||||
|
#define ERI_TRAX_MEMADDRSTART (ERI_TRAX_OFFSET+0x20)
|
||||||
|
#define ERI_TRAX_MEMADDREND (ERI_TRAX_OFFSET+0x24)
|
||||||
|
|
||||||
|
#define TRAXCTRL_TREN (1<<0) //Trace enable. Tracing starts on 0->1
|
||||||
|
#define TRAXCTRL_TRSTP (1<<1) //Trace Stop. Make 1 to stop trace.
|
||||||
|
#define TRAXCTRL_PCMEN (1<<2) //PC match enable
|
||||||
|
#define TRAXCTRL_PTIEN (1<<4) //Processor-trigger enable
|
||||||
|
#define TRAXCTRL_CTIEN (1<<5) //Cross-trigger enable
|
||||||
|
#define TRAXCTRL_TMEN (1<<7) //Tracemem Enable. Always set.
|
||||||
|
#define TRAXCTRL_CNTU (1<<9) //Post-stop-trigger countdown units; selects when DelayCount-- happens.
|
||||||
|
//0 - every 32-bit word written to tracemem, 1 - every cpu instruction
|
||||||
|
#define TRAXCTRL_TSEN (1<<11) //Undocumented/deprecated?
|
||||||
|
#define TRAXCTRL_SMPER_SHIFT 12 //Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg
|
||||||
|
#define TRAXCTRL_SMPER_MASK 0x7 //Synchronization message period
|
||||||
|
#define TRAXCTRL_PTOWT (1<<16) //Processor Trigger Out (OCD halt) enabled when stop triggered
|
||||||
|
#define TRAXCTRL_PTOWS (1<<17) //Processor Trigger Out (OCD halt) enabled when trace stop completes
|
||||||
|
#define TRAXCTRL_CTOWT (1<<20) //Cross-trigger Out enabled when stop triggered
|
||||||
|
#define TRAXCTRL_CTOWS (1<<21) //Cross-trigger Out enabled when trace stop completes
|
||||||
|
#define TRAXCTRL_ITCTO (1<<22) //Integration mode: cross-trigger output
|
||||||
|
#define TRAXCTRL_ITCTIA (1<<23) //Integration mode: cross-trigger ack
|
||||||
|
#define TRAXCTRL_ITATV (1<<24) //replaces ATID when in integration mode: ATVALID output
|
||||||
|
#define TRAXCTRL_ATID_MASK 0x7F //ARB source ID
|
||||||
|
#define TRAXCTRL_ATID_SHIFT 24
|
||||||
|
#define TRAXCTRL_ATEN (1<<31) //ATB interface enable
|
||||||
|
|
||||||
|
#define TRAXSTAT_TRACT (1<<0) //Trace active flag.
|
||||||
|
#define TRAXSTAT_TRIG (1<<1) //Trace stop trigger. Clears on TREN 1->0
|
||||||
|
#define TRAXSTAT_PCMTG (1<<2) //Stop trigger caused by PC match. Clears on TREN 1->0
|
||||||
|
#define TRAXSTAT_PJTR (1<<3) //JTAG transaction result. 1=err in preceding jtag transaction.
|
||||||
|
#define TRAXSTAT_PTITG (1<<4) //Stop trigger caused by Processor Trigger Input. Clears on TREN 1->0
|
||||||
|
#define TRAXSTAT_CTITG (1<<5) //Stop trigger caused by Cross-Trigger Input. Clears on TREN 1->0
|
||||||
|
#define TRAXSTAT_MEMSZ_SHIFT 8 //Traceram size inducator. Usable trace ram is 2^MEMSZ bytes.
|
||||||
|
#define TRAXSTAT_MEMSZ_MASK 0x1F
|
||||||
|
#define TRAXSTAT_PTO (1<<16) //Processor Trigger Output: current value
|
||||||
|
#define TRAXSTAT_CTO (1<<17) //Cross-Trigger Output: current value
|
||||||
|
#define TRAXSTAT_ITCTOA (1<<22) //Cross-Trigger Out Ack: current value
|
||||||
|
#define TRAXSTAT_ITCTI (1<<23) //Cross-Trigger Input: current value
|
||||||
|
#define TRAXSTAT_ITATR (1<<24) //ATREADY Input: current value
|
||||||
|
|
||||||
|
#define TRAXADDR_TADDR_SHIFT 0 //Trax memory address, in 32-bit words.
|
||||||
|
#define TRAXADDR_TADDR_MASK 0x1FFFFF //Actually is only as big as the trace buffer size max addr.
|
||||||
|
#define TRAXADDR_TWRAP_SHIFT 21 //Amount of times TADDR has overflown
|
||||||
|
#define TRAXADDR_TWRAP_MASK 0x3FF
|
||||||
|
#define TRAXADDR_TWSAT (1<<31) //1 if TWRAP has overflown, clear by disabling tren.
|
||||||
|
|
||||||
|
#define PCMATCHCTRL_PCML_SHIFT 0 //Amount of lower bits to ignore in pc trigger register
|
||||||
|
#define PCMATCHCTRL_PCML_MASK 0x1F
|
||||||
|
#define PCMATCHCTRL_PCMS (1<<31) //PC Match Sense, 0 - match when procs PC is in-range, 1 - match when
|
||||||
|
//out-of-range
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
84
components/xtensa-debug-module/trax.c
Normal file
84
components/xtensa-debug-module/trax.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "eri.h"
|
||||||
|
#include "xtensa-debug-module.h"
|
||||||
|
#include "trax.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
|
||||||
|
#define TRACEMEM_MUX_BLK0_ONLY 1
|
||||||
|
#define TRACEMEM_MUX_BLK1_ONLY 2
|
||||||
|
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
|
||||||
|
|
||||||
|
static const char* TAG = "trax";
|
||||||
|
|
||||||
|
int trax_enable(trax_ena_select_t which)
|
||||||
|
{
|
||||||
|
#if !CONFIG_MEMMAP_TRACEMEM
|
||||||
|
ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
#endif
|
||||||
|
#if !CONFIG_MEMMAP_TRACEMEM_TWOBANKS
|
||||||
|
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM;
|
||||||
|
#endif
|
||||||
|
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) {
|
||||||
|
WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, (which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1);
|
||||||
|
} else {
|
||||||
|
WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK0_ONLY);
|
||||||
|
}
|
||||||
|
WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO));
|
||||||
|
WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP));
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int trax_start_trace(trax_downcount_unit_t units_until_stop)
|
||||||
|
{
|
||||||
|
#if !CONFIG_MEMMAP_TRACEMEM
|
||||||
|
ESP_LOGE(TAG, "Trax_start_trace called, but trax is disabled in menuconfig!");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
#endif
|
||||||
|
uint32_t v;
|
||||||
|
if (eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT) {
|
||||||
|
ESP_LOGI(TAG, "Stopping active trace first.");
|
||||||
|
//Trace is active. Stop trace.
|
||||||
|
eri_write(ERI_TRAX_DELAYCNT, 0);
|
||||||
|
eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP);
|
||||||
|
//ToDo: This will probably trigger a trace done interrupt. ToDo: Fix, but how? -JD
|
||||||
|
eri_write(ERI_TRAX_TRAXCTRL, 0);
|
||||||
|
}
|
||||||
|
eri_write(ERI_TRAX_PCMATCHCTRL, 31); //do not stop at any pc match
|
||||||
|
v=TRAXCTRL_TREN | TRAXCTRL_TMEN | TRAXCTRL_PTOWS | (1<<TRAXCTRL_SMPER_SHIFT);
|
||||||
|
if (units_until_stop == TRAX_DOWNCOUNT_INSTRUCTIONS) v|=TRAXCTRL_CNTU;
|
||||||
|
//Enable trace. This trace has no stop condition and will just keep on running.
|
||||||
|
eri_write(ERI_TRAX_TRAXCTRL, v);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int trax_trigger_traceend_after_delay(int delay)
|
||||||
|
{
|
||||||
|
#if !CONFIG_MEMMAP_TRACEMEM
|
||||||
|
ESP_LOGE(TAG, "Trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
#endif
|
||||||
|
eri_write(ERI_TRAX_DELAYCNT, delay);
|
||||||
|
eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
# (Note that we only rebuild auto.conf automatically for some targets,
|
# (Note that we only rebuild auto.conf automatically for some targets,
|
||||||
# see project_config.mk for details.)
|
# see project_config.mk for details.)
|
||||||
-include $(PROJECT_PATH)/build/include/config/auto.conf
|
-include $(BUILD_DIR_BASE)/include/config/auto.conf
|
||||||
|
|
||||||
#Handling of V=1/VERBOSE=1 flag
|
#Handling of V=1/VERBOSE=1 flag
|
||||||
#
|
#
|
||||||
|
@ -91,15 +91,15 @@ define GenerateCompileTargets
|
|||||||
# $(1) - directory containing source files, relative to $(COMPONENT_PATH)
|
# $(1) - directory containing source files, relative to $(COMPONENT_PATH)
|
||||||
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1)
|
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1)
|
||||||
$$(summary) CC $$@
|
$$(summary) CC $$@
|
||||||
$$(Q) $$(CC) $$(CFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
$$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
||||||
|
|
||||||
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1)
|
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1)
|
||||||
$$(summary) CC $$@
|
$$(summary) CXX $$@
|
||||||
$$(Q) $$(CXX) $$(CXXFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
$$(Q) $$(CXX) $$(CXXFLAGS) $(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
||||||
|
|
||||||
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1)
|
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1)
|
||||||
$$(summary) CC $$@
|
$$(summary) AS $$@
|
||||||
$$(Q) $$(CC) $$(CFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
$$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
||||||
|
|
||||||
# CWD is build dir, create the build subdirectory if it doesn't exist
|
# CWD is build dir, create the build subdirectory if it doesn't exist
|
||||||
$(1):
|
$(1):
|
||||||
|
@ -37,6 +37,7 @@ help:
|
|||||||
@echo "'make partition_table', etc, etc."
|
@echo "'make partition_table', etc, etc."
|
||||||
|
|
||||||
# disable built-in make rules, makes debugging saner
|
# disable built-in make rules, makes debugging saner
|
||||||
|
MAKEFLAGS_OLD := $(MAKEFLAGS)
|
||||||
MAKEFLAGS +=-rR
|
MAKEFLAGS +=-rR
|
||||||
|
|
||||||
# Figure out PROJECT_PATH if not set
|
# Figure out PROJECT_PATH if not set
|
||||||
@ -50,6 +51,7 @@ endif
|
|||||||
#The directory where we put all objects/libraries/binaries. The project Makefile can
|
#The directory where we put all objects/libraries/binaries. The project Makefile can
|
||||||
#configure this if needed.
|
#configure this if needed.
|
||||||
BUILD_DIR_BASE ?= $(PROJECT_PATH)/build
|
BUILD_DIR_BASE ?= $(PROJECT_PATH)/build
|
||||||
|
export BUILD_DIR_BASE
|
||||||
|
|
||||||
#Component directories. These directories are searched for components.
|
#Component directories. These directories are searched for components.
|
||||||
#The project Makefile can override these component dirs, or define extra component directories.
|
#The project Makefile can override these component dirs, or define extra component directories.
|
||||||
@ -105,7 +107,7 @@ COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(ad
|
|||||||
$(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS))))
|
$(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS))))
|
||||||
|
|
||||||
#Also add project include path, for sdk includes
|
#Also add project include path, for sdk includes
|
||||||
COMPONENT_INCLUDES += $(PROJECT_PATH)/build/include/
|
COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/)
|
||||||
export COMPONENT_INCLUDES
|
export COMPONENT_INCLUDES
|
||||||
|
|
||||||
#COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected
|
#COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected
|
||||||
@ -149,23 +151,61 @@ LDFLAGS ?= -nostdlib \
|
|||||||
-Wl,-EL
|
-Wl,-EL
|
||||||
|
|
||||||
# Set default CPPFLAGS, CFLAGS, CXXFLAGS
|
# Set default CPPFLAGS, CFLAGS, CXXFLAGS
|
||||||
#
|
|
||||||
# These are exported so that components can use them when compiling.
|
# These are exported so that components can use them when compiling.
|
||||||
#
|
|
||||||
# If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile.
|
# If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile.
|
||||||
#
|
|
||||||
# If you need your component to add CFLAGS/etc globally for all source
|
# If you need your component to add CFLAGS/etc globally for all source
|
||||||
# files, set CFLAGS += in your component's Makefile.projbuild
|
# files, set CFLAGS += in your component's Makefile.projbuild
|
||||||
|
# If you need to set CFLAGS/CPPFLAGS/CXXFLAGS at project level, set them in application Makefile
|
||||||
|
# before including project.mk. Default flags will be added before the ones provided in application Makefile.
|
||||||
|
|
||||||
# CPPFLAGS used by an compile pass that uses the C preprocessor
|
# CPPFLAGS used by C preprocessor
|
||||||
CPPFLAGS = -DESP_PLATFORM -Og -g3 -Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable \
|
# If any flags are defined in application Makefile, add them at the end.
|
||||||
-Wno-error=unused-variable -Wall -ffunction-sections -fdata-sections -mlongcalls -nostdlib -MMD -MP
|
CPPFLAGS := -DESP_PLATFORM $(CPPFLAGS)
|
||||||
|
|
||||||
# C flags use by C only
|
# Warnings-related flags relevant both for C and C++
|
||||||
CFLAGS = $(CPPFLAGS) -std=gnu99 -g3 -fstrict-volatile-bitfields
|
COMMON_WARNING_FLAGS = -Wall -Werror \
|
||||||
|
-Wno-error=unused-function \
|
||||||
|
-Wno-error=unused-but-set-variable \
|
||||||
|
-Wno-error=unused-variable
|
||||||
|
|
||||||
# CXXFLAGS uses by C++ only
|
# Flags which control code generation and dependency generation, both for C and C++
|
||||||
CXXFLAGS = $(CPPFLAGS) -Og -std=gnu++11 -g3 -fno-exceptions -fstrict-volatile-bitfields -fno-rtti
|
COMMON_FLAGS = \
|
||||||
|
-ffunction-sections -fdata-sections \
|
||||||
|
-fstrict-volatile-bitfields \
|
||||||
|
-mlongcalls \
|
||||||
|
-nostdlib \
|
||||||
|
-MMD -MP
|
||||||
|
|
||||||
|
# Optimization flags are set based on menuconfig choice
|
||||||
|
ifneq ("$(CONFIG_OPTIMIZATION_LEVEL_RELEASE)","")
|
||||||
|
OPTIMIZATION_FLAGS = -Os
|
||||||
|
CPPFLAGS += -DNDEBUG
|
||||||
|
else
|
||||||
|
OPTIMIZATION_FLAGS = -Og
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Enable generation of debugging symbols
|
||||||
|
OPTIMIZATION_FLAGS += -ggdb
|
||||||
|
|
||||||
|
# List of flags to pass to C compiler
|
||||||
|
# If any flags are defined in application Makefile, add them at the end.
|
||||||
|
CFLAGS := $(strip \
|
||||||
|
-std=gnu99 \
|
||||||
|
$(OPTIMIZATION_FLAGS) \
|
||||||
|
$(COMMON_FLAGS) \
|
||||||
|
$(COMMON_WARNING_FLAGS) \
|
||||||
|
$(CFLAGS))
|
||||||
|
|
||||||
|
# List of flags to pass to C++ compiler
|
||||||
|
# If any flags are defined in application Makefile, add them at the end.
|
||||||
|
CXXFLAGS := $(strip \
|
||||||
|
-std=gnu++11 \
|
||||||
|
-fno-exceptions \
|
||||||
|
-fno-rtti \
|
||||||
|
$(OPTIMIZATION_FLAGS) \
|
||||||
|
$(COMMON_FLAGS) \
|
||||||
|
$(COMMON_WARNING_FLAGS) \
|
||||||
|
$(CXXFLAGS))
|
||||||
|
|
||||||
export CFLAGS CPPFLAGS CXXFLAGS
|
export CFLAGS CPPFLAGS CXXFLAGS
|
||||||
|
|
||||||
@ -174,6 +214,7 @@ HOSTCC := $(CC)
|
|||||||
HOSTLD := $(LD)
|
HOSTLD := $(LD)
|
||||||
HOSTAR := $(AR)
|
HOSTAR := $(AR)
|
||||||
HOSTOBJCOPY := $(OBJCOPY)
|
HOSTOBJCOPY := $(OBJCOPY)
|
||||||
|
export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY
|
||||||
|
|
||||||
#Set target compiler. Defaults to whatever the user has
|
#Set target compiler. Defaults to whatever the user has
|
||||||
#configured as prefix + yer olde gcc commands
|
#configured as prefix + yer olde gcc commands
|
||||||
@ -230,7 +271,7 @@ define GenerateComponentPhonyTarget
|
|||||||
# $(2) - target to generate (build, clean)
|
# $(2) - target to generate (build, clean)
|
||||||
.PHONY: $(notdir $(1))-$(2)
|
.PHONY: $(notdir $(1))-$(2)
|
||||||
$(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1))
|
$(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1))
|
||||||
@+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2)
|
$(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define GenerateComponentTargets
|
define GenerateComponentTargets
|
||||||
|
@ -7,38 +7,38 @@ COMPONENT_KCONFIGS_PROJBUILD := $(foreach component,$(COMPONENT_PATHS),$(wildcar
|
|||||||
#For doing make menuconfig etc
|
#For doing make menuconfig etc
|
||||||
KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig
|
KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig
|
||||||
|
|
||||||
# clear MAKEFLAGS as the menuconfig makefile uses implicit compile rules
|
# set SDKCONFIG to the project's sdkconfig,
|
||||||
|
# unless it's overriden (happens for bootloader)
|
||||||
|
SDKCONFIG ?= $(PROJECT_PATH)/sdkconfig
|
||||||
|
|
||||||
|
# reset MAKEFLAGS as the menuconfig makefile uses implicit compile rules
|
||||||
$(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf:
|
$(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf:
|
||||||
MAKEFLAGS="" \
|
MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \
|
||||||
CC=$(HOSTCC) LD=$(HOSTLD) \
|
|
||||||
$(MAKE) -C $(KCONFIG_TOOL_DIR)
|
$(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 $(BUILD_DIR_BASE)
|
menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE)
|
||||||
$(summary) MENUCONFIG
|
$(summary) MENUCONFIG
|
||||||
$(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \
|
$(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig
|
||||||
KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \
|
|
||||||
COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \
|
|
||||||
COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
|
||||||
$(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig
|
|
||||||
|
|
||||||
ifeq ("$(wildcard $(PROJECT_PATH)/sdkconfig)","")
|
ifeq ("$(wildcard $(SDKCONFIG))","")
|
||||||
#No sdkconfig found. Need to run menuconfig to make this if we need it.
|
#No sdkconfig found. Need to run menuconfig to make this if we need it.
|
||||||
$(PROJECT_PATH)/sdkconfig: menuconfig
|
$(SDKCONFIG): menuconfig
|
||||||
endif
|
endif
|
||||||
|
|
||||||
defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE)
|
defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE)
|
||||||
$(summary) DEFCONFIG
|
$(summary) DEFCONFIG
|
||||||
$(Q) mkdir -p $(PROJECT_PATH)/build/include/config
|
$(Q) mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||||
$(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \
|
$(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig
|
||||||
KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \
|
|
||||||
COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \
|
|
||||||
COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
|
||||||
$(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig
|
|
||||||
|
|
||||||
# Work out of whether we have to build the Kconfig makefile
|
# 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
|
# (auto.conf), or if we're in a situation where we don't need it
|
||||||
NON_CONFIG_TARGETS := clean %-clean get_variable help menuconfig defconfig
|
NON_CONFIG_TARGETS := clean %-clean get_variable help menuconfig defconfig
|
||||||
AUTO_CONF_REGEN_TARGET := $(PROJECT_PATH)/build/include/config/auto.conf
|
AUTO_CONF_REGEN_TARGET := $(BUILD_DIR_BASE)/include/config/auto.conf
|
||||||
|
|
||||||
# disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets
|
# disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets
|
||||||
# (and not building default target)
|
# (and not building default target)
|
||||||
@ -46,19 +46,15 @@ ifneq ("$(MAKECMDGOALS)","")
|
|||||||
ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
||||||
AUTO_CONF_REGEN_TARGET :=
|
AUTO_CONF_REGEN_TARGET :=
|
||||||
# dummy target
|
# dummy target
|
||||||
$(PROJECT_PATH)/build/include/config/auto.conf:
|
$(BUILD_DIR_BASE)/include/config/auto.conf:
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(AUTO_CONF_REGEN_TARGET) $(PROJECT_PATH)/build/include/sdkconfig.h: $(PROJECT_PATH)/sdkconfig $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD)
|
$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD)
|
||||||
$(summary) GENCONFIG
|
$(summary) GENCONFIG
|
||||||
$(Q) mkdir -p $(PROJECT_PATH)/build/include/config
|
$(Q) mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||||
$(Q) cd build; KCONFIG_AUTOHEADER="$(PROJECT_PATH)/build/include/sdkconfig.h" \
|
$(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig
|
||||||
KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \
|
$(Q) touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h
|
||||||
COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \
|
|
||||||
COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
|
||||||
$(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig
|
|
||||||
$(Q) touch $(AUTO_CONF_REGEN_TARGET) $(PROJECT_PATH)/build/include/sdkconfig.h
|
|
||||||
# touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this,
|
# 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
|
# sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer
|
||||||
# than the target(!)
|
# than the target(!)
|
||||||
@ -68,4 +64,4 @@ clean: config-clean
|
|||||||
config-clean:
|
config-clean:
|
||||||
$(summary RM CONFIG)
|
$(summary RM CONFIG)
|
||||||
$(MAKE) -C $(KCONFIG_TOOL_DIR) clean
|
$(MAKE) -C $(KCONFIG_TOOL_DIR) clean
|
||||||
$(Q) rm -rf $(PROJECT_PATH)/build/include/config $(PROJECT_PATH)/build/include/sdkconfig.h
|
$(Q) rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# Test the build system for basic consistency
|
# Test the build system for basic consistency
|
||||||
#
|
#
|
||||||
# Just a bash script that tests some likely make failure scenarios in a row
|
# A bash script that tests some likely make failure scenarios in a row
|
||||||
# Creates its own test build directory under TMP and cleans it up when done.
|
# Creates its own test build directory under TMP and cleans it up when done.
|
||||||
#
|
#
|
||||||
# Environment variables:
|
# Environment variables:
|
||||||
@ -11,6 +11,18 @@
|
|||||||
# ESP_IDF_TEMPLATE_GIT - Can override git clone source for template app. Otherwise github.
|
# ESP_IDF_TEMPLATE_GIT - Can override git clone source for template app. Otherwise github.
|
||||||
# NOCLEANUP - Set to '1' if you want the script to leave its temporary directory when done, for post-mortem.
|
# NOCLEANUP - Set to '1' if you want the script to leave its temporary directory when done, for post-mortem.
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Internals:
|
||||||
|
# * The tests run in sequence & the system keeps track of all failures to print at the end.
|
||||||
|
# * BUILD directory is set to default BUILD_DIR_BASE
|
||||||
|
# * The "print_status" function both prints a status line to the log and keeps track of which test is running.
|
||||||
|
# * Calling the "failure" function prints a failure message to the log and also adds to the list of failures to print at the end.
|
||||||
|
# * The function "assert_built" tests for a file relative to the BUILD directory.
|
||||||
|
# * The function "take_build_snapshot" can be paired with the functions "assert_rebuilt" and "assert_not_rebuilt" to compare file timestamps and verify if they were rebuilt or not since the snapshot was taken.
|
||||||
|
#
|
||||||
|
# To add a new test case, add it to the end of the run_tests function. Note that not all test cases do comprehensive cleanup
|
||||||
|
# (although very invasive ones like appending CRLFs to all files take a copy of the esp-idf tree), however the clean_build_dir
|
||||||
|
# function can be used to force-delete all files from the build output directory.
|
||||||
|
|
||||||
# Set up some variables
|
# Set up some variables
|
||||||
#
|
#
|
||||||
@ -21,103 +33,137 @@ export V=1
|
|||||||
|
|
||||||
function run_tests()
|
function run_tests()
|
||||||
{
|
{
|
||||||
FAILURES=
|
FAILURES=
|
||||||
STATUS="Starting"
|
STATUS="Starting"
|
||||||
print_status "Checking prerequisites"
|
print_status "Checking prerequisites"
|
||||||
[ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2
|
[ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2
|
||||||
|
|
||||||
print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..."
|
print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..."
|
||||||
git clone ${ESP_IDF_TEMPLATE_GIT} template
|
git clone ${ESP_IDF_TEMPLATE_GIT} template
|
||||||
cd template
|
cd template
|
||||||
git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||||
|
|
||||||
print_status "Updating template config..."
|
print_status "Updating template config..."
|
||||||
make defconfig || exit $?
|
make defconfig || exit $?
|
||||||
|
|
||||||
BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin"
|
BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin"
|
||||||
APP_BINS="app-template.elf app-template.bin"
|
APP_BINS="app-template.elf app-template.bin"
|
||||||
|
|
||||||
print_status "Initial clean build"
|
print_status "Initial clean build"
|
||||||
# if make fails here, everything fails
|
# if make fails here, everything fails
|
||||||
make || exit $?
|
make || exit $?
|
||||||
# check all the expected build artifacts from the clean build
|
# check all the expected build artifacts from the clean build
|
||||||
assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
|
assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||||
[ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built"
|
[ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built"
|
||||||
|
|
||||||
print_status "Updating component source file rebuilds component"
|
print_status "Updating component source file rebuilds component"
|
||||||
# touch a file & do a build
|
# touch a file & do a build
|
||||||
take_build_snapshot
|
take_build_snapshot
|
||||||
touch ${IDF_PATH}/components/esp32/syscalls.c
|
touch ${IDF_PATH}/components/esp32/syscalls.c
|
||||||
make || failure "Failed to partial build"
|
make || failure "Failed to partial build"
|
||||||
assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o
|
assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o
|
||||||
assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin
|
assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||||
|
|
||||||
print_status "Bootloader source file rebuilds bootloader"
|
print_status "Bootloader source file rebuilds bootloader"
|
||||||
take_build_snapshot
|
take_build_snapshot
|
||||||
touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c
|
touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c
|
||||||
make bootloader || failure "Failed to partial build bootloader"
|
make bootloader || failure "Failed to partial build bootloader"
|
||||||
assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o
|
assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o
|
||||||
assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin
|
assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin
|
||||||
|
|
||||||
print_status "Partition CSV file rebuilds partitions"
|
print_status "Partition CSV file rebuilds partitions"
|
||||||
take_build_snapshot
|
take_build_snapshot
|
||||||
touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv
|
touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv
|
||||||
make partition_table
|
make partition_table || failure "Failed to build partition table"
|
||||||
assert_rebuilt partitions_singleapp.bin
|
assert_rebuilt partitions_singleapp.bin
|
||||||
assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS}
|
assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS}
|
||||||
|
|
||||||
print_status "Partial build doesn't compile anything by default"
|
print_status "Partial build doesn't compile anything by default"
|
||||||
take_build_snapshot
|
take_build_snapshot
|
||||||
# verify no build files are refreshed by a partial make
|
# verify no build files are refreshed by a partial make
|
||||||
ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@")
|
ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@")
|
||||||
make
|
make || failure "Partial build failed"
|
||||||
assert_not_rebuilt ${ALL_BUILD_FILES}
|
assert_not_rebuilt ${ALL_BUILD_FILES}
|
||||||
|
|
||||||
print_status "Cleaning should remove all files from build"
|
print_status "Cleaning should remove all files from build"
|
||||||
make clean
|
make clean || failure "Failed to make clean"
|
||||||
ALL_BUILD_FILES=$(find ${BUILD} -type f)
|
ALL_BUILD_FILES=$(find ${BUILD} -type f)
|
||||||
if [ -n "${ALL_BUILD_FILES}" ]; then
|
if [ -n "${ALL_BUILD_FILES}" ]; then
|
||||||
failure "Files weren't cleaned: ${ALL_BUILD_FILES}"
|
failure "Files weren't cleaned: ${ALL_BUILD_FILES}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
print_status "Can still clean build if all text files are CRLFs"
|
print_status "Bootloader build shouldn't leave build output anywhere else"
|
||||||
make clean
|
clean_build_dir
|
||||||
find . -exec unix2dos {} \; # CRLFify template dir
|
make bootloader
|
||||||
# make a copy of esp-idf and CRLFify it
|
# find wizardry: find any file not named sdkconfig.h that
|
||||||
CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf
|
# isn't in the "bootloader" or "config" directories
|
||||||
mkdir -p ${CRLF_ESPIDF}
|
find ${BUILD} -type d \( -name bootloader -o -name config \) -prune , -type f ! -name sdkconfig.h || failure "Bootloader built files outside the bootloader or config directories"
|
||||||
cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF}
|
|
||||||
# don't CRLFify executable files, as Linux will fail to execute them
|
|
||||||
find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \;
|
|
||||||
make IDF_PATH=${CRLF_ESPIDF}
|
|
||||||
# do the same checks we do for the clean build
|
|
||||||
assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
|
|
||||||
[ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode"
|
|
||||||
|
|
||||||
# NOTE: If adding new tests, add them above this CRLF test...
|
print_status "Moving BUILD_DIR_BASE out of tree"
|
||||||
|
clean_build_dir
|
||||||
|
OUTOFTREE_BUILD=${TESTDIR}/alt_build
|
||||||
|
make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden"
|
||||||
|
NEW_BUILD_FILES=$(find ${OUTOFREE_BUILD} -type f)
|
||||||
|
if [ -z "${NEW_BUILD_FILES}" ]; then
|
||||||
|
failure "No files found in new build directory!"
|
||||||
|
fi
|
||||||
|
DEFAULT_BUILD_FILES=$(find ${BUILD} -mindepth 1)
|
||||||
|
if [ -n "${DEFAULT_BUILD_FILES}" ]; then
|
||||||
|
failure "Some files were incorrectly put into the default build directory: ${DEFAULT_BUILD_FILES}"
|
||||||
|
fi
|
||||||
|
|
||||||
print_status "All tests completed"
|
print_status "BUILD_DIR_BASE inside default build directory"
|
||||||
if [ -n "${FAILURES}" ]; then
|
clean_build_dir
|
||||||
echo "Some failures were detected:"
|
make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir"
|
||||||
echo -e "${FAILURES}"
|
NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f)
|
||||||
exit 1
|
if [ -z "${NEW_BUILD_FILES}" ]; then
|
||||||
else
|
failure "No files found in new build directory!"
|
||||||
echo "Build tests passed."
|
fi
|
||||||
fi
|
|
||||||
|
print_status "Parallel builds should work OK"
|
||||||
|
clean_build_dir
|
||||||
|
(make -j5 2>&1 | tee ${TESTDIR}/parallel_build.log) || failure "Failed to build in parallel"
|
||||||
|
if grep -q "warning: jobserver unavailable" ${TESTDIR}/parallel_build.log; then
|
||||||
|
failure "Parallel build prints 'warning: jobserver unavailable' errors"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_status "Can still clean build if all text files are CRLFs"
|
||||||
|
make clean || failure "Unexpected failure to make clean"
|
||||||
|
find . -exec unix2dos {} \; # CRLFify template dir
|
||||||
|
# make a copy of esp-idf and CRLFify it
|
||||||
|
CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf
|
||||||
|
mkdir -p ${CRLF_ESPIDF}
|
||||||
|
cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF}
|
||||||
|
# don't CRLFify executable files, as Linux will fail to execute them
|
||||||
|
find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \;
|
||||||
|
make IDF_PATH=${CRLF_ESPIDF} || failure "Failed to build with CRLFs in source"
|
||||||
|
# do the same checks we do for the clean build
|
||||||
|
assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||||
|
[ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode"
|
||||||
|
|
||||||
|
|
||||||
|
print_status "All tests completed"
|
||||||
|
if [ -n "${FAILURES}" ]; then
|
||||||
|
echo "Some failures were detected:"
|
||||||
|
echo -e "${FAILURES}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Build tests passed."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function print_status()
|
function print_status()
|
||||||
{
|
{
|
||||||
echo "******** $1"
|
echo "******** $1"
|
||||||
STATUS="$1"
|
STATUS="$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
function failure()
|
function failure()
|
||||||
{
|
{
|
||||||
echo "!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!"
|
||||||
echo "FAILURE: $1"
|
echo "FAILURE: $1"
|
||||||
echo "!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!"
|
||||||
FAILURES="${FAILURES}${STATUS} :: $1\n"
|
FAILURES="${FAILURES}${STATUS} :: $1\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
TESTDIR=${TMP}/build_system_tests_$$
|
TESTDIR=${TMP}/build_system_tests_$$
|
||||||
@ -133,62 +179,68 @@ BUILD=${TESTDIR}/template/build
|
|||||||
# copy all the build output to a snapshot directory
|
# copy all the build output to a snapshot directory
|
||||||
function take_build_snapshot()
|
function take_build_snapshot()
|
||||||
{
|
{
|
||||||
rm -rf ${SNAPSHOT}
|
rm -rf ${SNAPSHOT}
|
||||||
cp -ap ${TESTDIR}/template/build ${SNAPSHOT}
|
cp -ap ${TESTDIR}/template/build ${SNAPSHOT}
|
||||||
}
|
}
|
||||||
|
|
||||||
# verify that all the arguments are present in the build output directory
|
# verify that all the arguments are present in the build output directory
|
||||||
function assert_built()
|
function assert_built()
|
||||||
{
|
{
|
||||||
until [ -z "$1" ]; do
|
until [ -z "$1" ]; do
|
||||||
if [ ! -f "${BUILD}/$1" ]; then
|
if [ ! -f "${BUILD}/$1" ]; then
|
||||||
failure "File $1 should be in the build output directory"
|
failure "File $1 should be in the build output directory"
|
||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Test if a file has been rebuilt.
|
# Test if a file has been rebuilt.
|
||||||
function file_was_rebuilt()
|
function file_was_rebuilt()
|
||||||
{
|
{
|
||||||
# can't use [ a -ot b ] here as -ot only gives second resolution
|
# can't use [ a -ot b ] here as -ot only gives second resolution
|
||||||
# but stat -c %y seems to be microsecond at least for tmpfs, ext4..
|
# but stat -c %y seems to be microsecond at least for tmpfs, ext4..
|
||||||
if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then
|
if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# verify all the arguments passed in were rebuilt relative to the snapshot
|
# verify all the arguments passed in were rebuilt relative to the snapshot
|
||||||
function assert_rebuilt()
|
function assert_rebuilt()
|
||||||
{
|
{
|
||||||
until [ -z "$1" ]; do
|
until [ -z "$1" ]; do
|
||||||
assert_built "$1"
|
assert_built "$1"
|
||||||
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
||||||
failure "File $1 should have been original build snapshot"
|
failure "File $1 should have been original build snapshot"
|
||||||
fi
|
fi
|
||||||
if ! file_was_rebuilt "$1"; then
|
if ! file_was_rebuilt "$1"; then
|
||||||
failure "File $1 should have been rebuilt"
|
failure "File $1 should have been rebuilt"
|
||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# verify all the arguments are in the build directory & snapshot,
|
# verify all the arguments are in the build directory & snapshot,
|
||||||
# but were not rebuilt
|
# but were not rebuilt
|
||||||
function assert_not_rebuilt()
|
function assert_not_rebuilt()
|
||||||
{
|
{
|
||||||
until [ -z "$1" ]; do
|
until [ -z "$1" ]; do
|
||||||
assert_built "$1"
|
assert_built "$1"
|
||||||
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
||||||
failure "File $1 should be in snapshot build directory"
|
failure "File $1 should be in snapshot build directory"
|
||||||
fi
|
fi
|
||||||
if file_was_rebuilt "$1"; then
|
if file_was_rebuilt "$1"; then
|
||||||
failure "File $1 should not have been rebuilt"
|
failure "File $1 should not have been rebuilt"
|
||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# do a "clean" that doesn't depend on 'make clean'
|
||||||
|
function clean_build_dir()
|
||||||
|
{
|
||||||
|
rm -rf --preserve-root ${BUILD}/*
|
||||||
}
|
}
|
||||||
|
|
||||||
cd ${TESTDIR}
|
cd ${TESTDIR}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user