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.old
|
||||
examples/*/build
|
||||
|
||||
# Bootloader files
|
||||
components/bootloader/src/sdkconfig.old
|
@ -37,6 +37,12 @@ build_template_app:
|
||||
# branch
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
- make defconfig
|
||||
# Test debug build (default)
|
||||
- make all V=1
|
||||
# Now test release build
|
||||
- make clean
|
||||
- sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig
|
||||
- make defconfig
|
||||
- make all V=1
|
||||
|
||||
|
||||
|
20
Kconfig
20
Kconfig
@ -23,6 +23,26 @@ endmenu
|
||||
|
||||
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"
|
||||
source "$COMPONENT_KCONFIGS"
|
||||
endmenu
|
||||
|
@ -8,23 +8,26 @@
|
||||
# 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.
|
||||
#
|
||||
ifeq ("$(IS_BOOTLOADER_BUILD)","")
|
||||
ifndef IS_BOOTLOADER_BUILD
|
||||
|
||||
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_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)
|
||||
|
||||
$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig
|
||||
$(Q) PROJECT_PATH= \
|
||||
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_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig
|
||||
$(Q) $(BOOTLOADER_MAKE) $@
|
||||
|
||||
bootloader-clean:
|
||||
$(Q) PROJECT_PATH= \
|
||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V)
|
||||
$(Q) $(BOOTLOADER_MAKE) app-clean config-clean
|
||||
$(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old
|
||||
|
||||
clean: bootloader-clean
|
||||
|
||||
@ -36,14 +39,17 @@ all_binaries: $(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: $(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
|
||||
CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include
|
||||
|
@ -4,12 +4,13 @@
|
||||
#
|
||||
|
||||
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.
|
||||
#
|
||||
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
|
||||
IS_BOOTLOADER_BUILD := 1
|
||||
export IS_BOOTLOADER_BUILD
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes.
|
||||
#This is fixed by adding CFLAGS from Makefile.projbuild
|
||||
|
@ -51,7 +51,7 @@ enum {
|
||||
SPI_SPEED_20M,
|
||||
SPI_SPEED_80M = 0xF
|
||||
};
|
||||
/*suppport flash size in esp32 */
|
||||
/*supported flash sizes*/
|
||||
enum {
|
||||
SPI_SIZE_1MB = 0,
|
||||
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_size,
|
||||
uint32_t entry_addr);
|
||||
static void update_flash_config(struct flash_hdr* pfhdr);
|
||||
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
@ -258,7 +259,7 @@ void bootloader_main()
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
|
||||
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( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||
SPIUnlock();
|
||||
@ -269,6 +270,8 @@ void bootloader_main()
|
||||
|
||||
print_flash_info(&fhdr);
|
||||
|
||||
update_flash_config(&fhdr);
|
||||
|
||||
if (!load_partition_table(&bs, PARTITION_ADD)) {
|
||||
ESP_LOGE(TAG, "load partition table error!");
|
||||
return;
|
||||
@ -364,7 +367,7 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
uint32_t irom_size = 0;
|
||||
|
||||
/* 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;
|
||||
|
||||
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)();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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
|
||||
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
|
||||
config TRACEMEM_RESERVE_DRAM
|
||||
hex
|
||||
default 0x8000 if MEMMAP_TRACEMEM
|
||||
default 0x8000 if MEMMAP_TRACEMEM && MEMMAP_TRACEMEM_TWOBANKS
|
||||
default 0x4000 if MEMMAP_TRACEMEM && !MEMMAP_TRACEMEM_TWOBANKS
|
||||
default 0x0
|
||||
|
||||
config MEMMAP_SPISRAM
|
||||
|
@ -6,7 +6,7 @@
|
||||
# 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.
|
||||
#
|
||||
-include $(PROJECT_PATH)/build/include/config/auto.conf
|
||||
-include include/config/auto.conf
|
||||
|
||||
COMPONENT_SRCDIRS := . hwcrypto
|
||||
|
||||
@ -44,6 +44,8 @@ $(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
|
||||
# saves us from having to add the target to a Makefile.projbuild
|
||||
$(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
|
||||
$(CC) -I ../include -C -P -x c -E $< -o $@
|
||||
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "esp_ipc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "trax.h"
|
||||
|
||||
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
|
||||
void start_cpu0_default(void) IRAM_ATTR;
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
@ -131,6 +133,15 @@ void IRAM_ATTR call_start_cpu1()
|
||||
|
||||
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
|
||||
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
||||
ets_setup_syscalls();
|
||||
@ -147,6 +158,9 @@ void start_cpu0_default(void)
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
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
|
||||
while (port_xSchedulerRunning[0] == 0) {
|
||||
;
|
||||
|
@ -186,7 +186,11 @@ void heap_alloc_caps_init() {
|
||||
#endif
|
||||
|
||||
#if CONFIG_MEMMAP_TRACEMEM
|
||||
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
|
||||
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
|
||||
|
||||
#if 0
|
||||
|
@ -191,14 +191,14 @@ esp_err_t esp_wifi_disconnect(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 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.
|
||||
@ -235,19 +235,30 @@ esp_err_t esp_wifi_scan_stop(void);
|
||||
* @return ESP_OK : succeed
|
||||
* @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
|
||||
*
|
||||
* @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
|
||||
* @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 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
|
||||
@ -471,14 +482,13 @@ esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf);
|
||||
*
|
||||
* @attention SSC only API
|
||||
*
|
||||
* @param struct station_info **station : station list
|
||||
* @param wifi_sta_list_t *sta: station list
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @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
|
||||
|
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 */
|
||||
int8_t rssi; /**< signal strength of AP */
|
||||
wifi_auth_mode_t authmode; /**< authmode of AP */
|
||||
} wifi_ap_list_t;
|
||||
} wifi_ap_record_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_PS_NONE, /**< No power save */
|
||||
@ -150,10 +150,15 @@ typedef union {
|
||||
wifi_sta_config_t sta; /**< configuration of STA */
|
||||
} wifi_config_t;
|
||||
|
||||
struct station_info {
|
||||
STAILQ_ENTRY(station_info) next;
|
||||
uint8_t bssid[6];
|
||||
};
|
||||
typedef struct {
|
||||
uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */
|
||||
}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 {
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @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_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.
|
||||
@ -503,6 +503,12 @@ void SPI_Write_Encrypt_Disable(void);
|
||||
*/
|
||||
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_r = 0x40059868 );
|
||||
PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 );
|
||||
PROVIDE ( g_rom_flashchip = 0x3ffae270 );
|
||||
PROVIDE ( gpio_init = 0x40009c20 );
|
||||
PROVIDE ( gpio_input_get = 0x40009b88 );
|
||||
PROVIDE ( gpio_input_get_high = 0x40009b9c );
|
||||
@ -1584,6 +1585,8 @@ PROVIDE ( SPIEraseBlock = 0x40062c4c );
|
||||
PROVIDE ( SPIEraseChip = 0x40062c14 );
|
||||
PROVIDE ( SPIEraseSector = 0x40062ccc );
|
||||
PROVIDE ( spi_flash_attach = 0x40062a6c );
|
||||
/* NB: SPIUnlock @ 0x400628b0 has been replaced with an updated
|
||||
version in the "spi_flash" component */
|
||||
PROVIDE ( SPILock = 0x400628f0 );
|
||||
PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 );
|
||||
PROVIDE ( spi_modes = 0x3ff99270 );
|
||||
@ -1595,9 +1598,8 @@ PROVIDE ( SPIReadModeCnfig = 0x40062944 );
|
||||
PROVIDE ( SPI_read_status = 0x4006226c );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( SPI_read_status_high = 0x40062448 );
|
||||
PROVIDE ( SPIUnlock = 0x400628b0 );
|
||||
PROVIDE ( SPI_user_command_read = 0x400621b0 );
|
||||
PROVIDE ( spi_w25q16 = 0x3ffae270 );
|
||||
PROVIDE ( SPI_flashchip_data = 0x3ffae270 );
|
||||
PROVIDE ( SPIWrite = 0x40062d50 );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( SPI_write_enable = 0x40062320 );
|
||||
|
@ -94,4 +94,31 @@ config ESPTOOLPY_FLASHFREQ
|
||||
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
||||
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
|
||||
|
@ -4,6 +4,7 @@ ESPPORT ?= $(CONFIG_ESPTOOLPY_PORT)
|
||||
ESPBAUD ?= $(CONFIG_ESPTOOLPY_BAUD)
|
||||
ESPFLASHMODE ?= $(CONFIG_ESPTOOLPY_FLASHMODE)
|
||||
ESPFLASHFREQ ?= $(CONFIG_ESPTOOLPY_FLASHFREQ)
|
||||
ESPFLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE)
|
||||
|
||||
PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
||||
|
||||
@ -15,13 +16,15 @@ ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py
|
||||
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
||||
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
|
||||
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)
|
||||
|
||||
$(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)
|
||||
@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
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
||||
/*
|
||||
* 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. */
|
||||
|
@ -322,12 +322,7 @@ STRUCT_END(XtSolFrame)
|
||||
#ifdef __ASSEMBLER__
|
||||
.macro getcoreid reg
|
||||
rsr.prid \reg
|
||||
bbci \reg,1,1f
|
||||
movi \reg,1
|
||||
j 2f
|
||||
1:
|
||||
movi \reg,0
|
||||
2:
|
||||
extui \reg,\reg,13,1
|
||||
.endm
|
||||
#endif
|
||||
|
||||
|
@ -76,7 +76,6 @@ inline static void panicPutHex(int a) { }
|
||||
inline static void panicPutDec(int a) { }
|
||||
#endif
|
||||
|
||||
int xPortGetCoreID();
|
||||
|
||||
void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) {
|
||||
panicPutStr("***ERROR*** A stack overflow in task ");
|
||||
|
@ -253,28 +253,6 @@ void vPortAssertIfInISR()
|
||||
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.
|
||||
*/
|
||||
@ -310,7 +288,8 @@ void vPortCPUAcquireMutex(portMUX_TYPE *mux) {
|
||||
irqStatus=portENTER_CRITICAL_NESTED();
|
||||
do {
|
||||
//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 ( (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.
|
||||
@ -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);
|
||||
#endif
|
||||
//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
|
||||
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);
|
||||
#endif
|
||||
ret=pdFALSE;
|
||||
} else if ( ((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT) != xPortGetCoreID() ) {
|
||||
} else {
|
||||
#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("Last non-recursive lock %s line %d\n", lastLockedFn, lastLockedLine);
|
||||
ets_printf("Called by %s line %d\n", fnName, line);
|
||||
#endif
|
||||
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);
|
||||
return ret;
|
||||
|
@ -51,18 +51,6 @@ port_switch_flag:
|
||||
|
||||
.text
|
||||
|
||||
|
||||
|
||||
/* C function to get proc ID.*/
|
||||
.global xPortGetCoreID
|
||||
.type xPortGetCoreID,@function
|
||||
.align 4
|
||||
xPortGetCoreID:
|
||||
ENTRY(16)
|
||||
getcoreid a2
|
||||
RET(16)
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* _frxt_setup_switch
|
||||
@ -81,9 +69,8 @@ _frxt_setup_switch:
|
||||
ENTRY(16)
|
||||
|
||||
getcoreid a3
|
||||
slli a3, a3, 2
|
||||
movi a2, port_switch_flag
|
||||
add a2, a2, a3
|
||||
addx4 a2, a3, a2
|
||||
|
||||
movi a3, 1
|
||||
s32i a3, a2, 0
|
||||
@ -128,12 +115,11 @@ _frxt_int_enter:
|
||||
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).
|
||||
*/
|
||||
getcoreid a3
|
||||
slli a4, a3, 2 /* a4 = cpuid * 4 */
|
||||
getcoreid a4
|
||||
movi a2, port_xSchedulerRunning
|
||||
add a2, a2, a4
|
||||
addx4 a2, a4, a2
|
||||
movi a3, port_interruptNesting
|
||||
add a3, a3, a4
|
||||
addx4 a3, a4, a3
|
||||
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
||||
beqz a2, 1f /* scheduler not running, no tasks */
|
||||
l32i a2, a3, 0 /* a2 = port_interruptNesting */
|
||||
@ -142,14 +128,13 @@ _frxt_int_enter:
|
||||
bnei a2, 1, .Lnested /* !=0 before incr, so nested */
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
add a2, a2, a4
|
||||
addx4 a2, a4, a2
|
||||
l32i a2, a2, 0 /* a2 = current TCB */
|
||||
beqz a2, 1f
|
||||
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
|
||||
movi a1, port_IntStackTop /* a1 = top of intr stack */
|
||||
movi a2, configISR_STACK_SIZE
|
||||
getcoreid a3
|
||||
mull a2, a3, a2
|
||||
mull a2, a4, a2
|
||||
add a1, a1, a2 /* for current proc */
|
||||
|
||||
.Lnested:
|
||||
@ -177,12 +162,11 @@ _frxt_int_enter:
|
||||
.align 4
|
||||
_frxt_int_exit:
|
||||
|
||||
getcoreid a3
|
||||
slli a4, a3, 2 /* a4 is core * 4 */
|
||||
getcoreid a4
|
||||
movi a2, port_xSchedulerRunning
|
||||
add a2, a2, a4
|
||||
addx4 a2, a4, a2
|
||||
movi a3, port_interruptNesting
|
||||
add a3, a3, a4
|
||||
addx4 a3, a4, a3
|
||||
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
|
||||
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
|
||||
beqz a2, .Lnoswitch /* scheduler not running, no tasks */
|
||||
@ -192,13 +176,13 @@ _frxt_int_exit:
|
||||
bnez a2, .Lnesting /* !=0 after decr so still nested */
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
add a2, a2, a4
|
||||
addx4 a2, a4, a2
|
||||
l32i a2, a2, 0 /* a2 = current TCB */
|
||||
beqz a2, 1f /* no task ? go to dispatcher */
|
||||
l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */
|
||||
|
||||
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 */
|
||||
beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */
|
||||
movi a3, 0
|
||||
@ -404,14 +388,12 @@ _frxt_dispatch:
|
||||
call0 vTaskSwitchContext // Get next TCB to resume
|
||||
movi a2, pxCurrentTCB
|
||||
getcoreid a3
|
||||
slli a3, a3, 2
|
||||
add a2, a2, a3
|
||||
addx4 a2, a3, a2
|
||||
#else
|
||||
call4 vTaskSwitchContext // Get next TCB to resume
|
||||
movi a2, pxCurrentTCB
|
||||
getcoreid a3
|
||||
slli a3, a3, 2
|
||||
add a2, a2, a3
|
||||
addx4 a2, a3, a2
|
||||
#endif
|
||||
l32i a3, a2, 0
|
||||
l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */
|
||||
@ -451,8 +433,7 @@ _frxt_dispatch:
|
||||
/* Restore CPENABLE from task's co-processor save area. */
|
||||
movi a3, pxCurrentTCB /* cp_state = */
|
||||
getcoreid a2
|
||||
slli a2, a2, 2
|
||||
add a3, a2, a3
|
||||
addx4 a3, a2, a3
|
||||
l32i a3, a3, 0
|
||||
l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */
|
||||
l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */
|
||||
@ -541,8 +522,7 @@ vPortYield:
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
getcoreid a3
|
||||
slli a3, a3, 2
|
||||
add a2, a2, a3
|
||||
addx4 a2, a3, a2
|
||||
l32i a2, a2, 0 /* a2 = pxCurrentTCB */
|
||||
movi a3, 0
|
||||
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. */
|
||||
movi a3, pxCurrentTCB /* cp_state = */
|
||||
getcoreid a2
|
||||
slli a2, a2, 2
|
||||
add a3, a2, a3
|
||||
addx4 a3, a2, a3
|
||||
l32i a3, a3, 0
|
||||
|
||||
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. */
|
||||
getcoreid a3
|
||||
slli a3, a3, 2 /* a3=coreid*4 */
|
||||
movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */
|
||||
add a15, a15, a3
|
||||
addx4 a15, a3,a15
|
||||
l32i a15, a15, 0
|
||||
beqz a15, 1f
|
||||
movi a15, port_interruptNesting /* && port_interruptNesting == 0 */
|
||||
add a15, a15, a3
|
||||
addx4 a15, a3, a15
|
||||
l32i a15, a15, 0
|
||||
bnez a15, 1f
|
||||
|
||||
movi a15, pxCurrentTCB
|
||||
add a15, a3, a15
|
||||
addx4 a15, a3, a15
|
||||
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
|
||||
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
|
||||
scheduler will re-enable the interrupts instead. */
|
||||
|
||||
) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED when the scheduler
|
||||
is not running. Re-enabling the scheduler will re-enable the interrupts instead. */
|
||||
|
||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||
|
||||
|
@ -904,16 +904,13 @@ _xt_coproc_exc:
|
||||
core we're running on now. */
|
||||
movi a2, pxCurrentTCB
|
||||
getcoreid a3
|
||||
slli a3, a3, 2
|
||||
add a2, a2, a3
|
||||
addx4 a2, a3, a2
|
||||
l32i a2, a2, 0 /* a2 = start of pxCurrentTCB[cpuid] */
|
||||
addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */
|
||||
getcoreid a3
|
||||
s32i a3, a2, 0 /* store current cpuid */
|
||||
|
||||
/* Grab correct xt_coproc_owner_sa for this core */
|
||||
getcoreid a2
|
||||
movi a3, XCHAL_CP_MAX << 2
|
||||
movi a2, XCHAL_CP_MAX << 2
|
||||
mull a2, a2, a3
|
||||
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
|
||||
add a3, a3, a2
|
||||
|
@ -284,7 +284,7 @@ static inline void heap_swap(int i, int j)
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
@ -314,8 +314,8 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
|
||||
if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
|
||||
/* If the queued byte- or pbuf-count drops below the configured low-water limit,
|
||||
let select mark this pcb as writable again. */
|
||||
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
|
||||
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT(conn->pcb.tcp)) &&
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT(conn->pcb.tcp))) {
|
||||
conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
|
||||
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,
|
||||
let select mark this pcb as writable again. */
|
||||
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
|
||||
if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT(conn->pcb.tcp) &&
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT(conn->pcb.tcp)))) {
|
||||
conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
|
||||
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 */
|
||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
||||
conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
|
||||
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
|
||||
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT(conn->pcb.tcp)) ||
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT(conn->pcb.tcp))) {
|
||||
/* The queued byte- or pbuf-count exceeds the configured low-water limit,
|
||||
let select mark this pcb as non-writable. */
|
||||
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("rto=%d nrtx=%d\n", pcb->rto, pcb->nrtx);
|
||||
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("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);
|
||||
|
@ -388,10 +388,8 @@ static void lwip_socket_drop_registered_memberships(int s);
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
#ifdef LWIP_ESP8266
|
||||
|
||||
/* Since esp_wifi_tx_is_stop/system_get_free_heap_size are not an public wifi API, so extern them here*/
|
||||
extern size_t system_get_free_heap_size(void);
|
||||
extern bool esp_wifi_tx_is_stop(void);
|
||||
#include "esp_wifi_internal.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
/* 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
|
||||
@ -402,9 +400,9 @@ extern bool esp_wifi_tx_is_stop(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);
|
||||
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));
|
||||
break;
|
||||
#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:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
||||
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));
|
||||
break;
|
||||
#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:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
||||
s, optname));
|
||||
|
@ -135,13 +135,15 @@
|
||||
//#endif
|
||||
#else /* LWIP_WND_SCALE */
|
||||
|
||||
#ifndef LWIP_ESP8266
|
||||
#if (ESP_PER_SOC_TCP_WND == 0)
|
||||
#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)"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_WND_SCALE */
|
||||
|
||||
#if (ESP_PER_SOC_TCP_WND == 0)
|
||||
#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"
|
||||
#endif
|
||||
@ -149,7 +151,6 @@
|
||||
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_ESP8266
|
||||
#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"
|
||||
#endif
|
||||
@ -289,6 +290,8 @@
|
||||
#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."
|
||||
#endif
|
||||
|
||||
#if (ESP_PER_SOC_TCP_WND == 0)
|
||||
#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."
|
||||
#endif
|
||||
@ -304,6 +307,8 @@
|
||||
#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."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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."
|
||||
#endif
|
||||
@ -328,13 +333,6 @@
|
||||
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 */
|
||||
stats_init();
|
||||
#if !NO_SYS
|
||||
|
@ -83,6 +83,7 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_ESP8266
|
||||
#include "esp_wifi_internal.h"
|
||||
#define EP_OFFSET 0
|
||||
#endif
|
||||
|
||||
@ -764,8 +765,7 @@ pbuf_free(struct pbuf *p)
|
||||
} else if (type == PBUF_ROM || type == PBUF_REF) {
|
||||
|
||||
#ifdef LWIP_ESP8266
|
||||
extern void system_pp_recycle_rx_pkt(void*);
|
||||
if (type == PBUF_REF && p->eb != NULL ) system_pp_recycle_rx_pkt(p->eb);
|
||||
if (type == PBUF_REF && p->eb != NULL ) esp_wifi_internal_free_rx_buffer(p->eb);
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
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 */
|
||||
pcb->rcv_ann_wnd = pcb->rcv_wnd;
|
||||
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);
|
||||
|
||||
/* 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
|
||||
* 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_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;
|
||||
/* 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. */
|
||||
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->snd_wnd = TCP_WND;
|
||||
pcb->snd_wnd = TCP_WND(pcb);
|
||||
/* As initial send MSS, we use TCP_MSS but limit it to 536.
|
||||
The send MSS is updated when an MSS option is received. */
|
||||
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);
|
||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||
pcb->cwnd = 1;
|
||||
pcb->ssthresh = TCP_WND;
|
||||
pcb->ssthresh = TCP_WND(pcb);
|
||||
#if LWIP_CALLBACK_API
|
||||
pcb->connected = connected;
|
||||
#else /* LWIP_CALLBACK_API */
|
||||
@ -1581,11 +1581,11 @@ tcp_alloc(u8_t prio)
|
||||
if (pcb != NULL) {
|
||||
memset(pcb, 0, sizeof(struct tcp_pcb));
|
||||
pcb->prio = prio;
|
||||
pcb->snd_buf = TCP_SND_BUF;
|
||||
pcb->snd_buf = TCP_SND_BUF_DEFAULT;
|
||||
pcb->snd_queuelen = 0;
|
||||
/* 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. */
|
||||
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
|
||||
/* snd_scale and rcv_scale are zero unless both sides agree to use scaling */
|
||||
pcb->snd_scale = 0;
|
||||
@ -1608,7 +1608,6 @@ tcp_alloc(u8_t prio)
|
||||
pcb->snd_lbb = iss;
|
||||
pcb->tmr = tcp_ticks;
|
||||
pcb->last_timer = tcp_timer_ctr;
|
||||
|
||||
pcb->polltmr = 0;
|
||||
|
||||
#if LWIP_CALLBACK_API
|
||||
@ -1624,7 +1623,13 @@ tcp_alloc(u8_t prio)
|
||||
#endif /* LWIP_TCP_KEEPALIVE */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1745,9 +1745,9 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
||||
pcb->rcv_scale = TCP_RCV_SCALE;
|
||||
pcb->flags |= TF_WND_SCALE;
|
||||
/* 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_ann_wnd == TCPWND_MIN16(TCP_WND));
|
||||
pcb->rcv_wnd = pcb->rcv_ann_wnd = 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(pcb)));
|
||||
pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND(pcb);
|
||||
}
|
||||
break;
|
||||
#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
|
||||
* configured maximum, return an error */
|
||||
/* 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",
|
||||
pcb->snd_queuelen, TCP_SND_QUEUELEN));
|
||||
pcb->snd_queuelen, TCP_SND_QUEUELEN(pcb)));
|
||||
TCP_STATS_INC(tcp.memerr);
|
||||
pcb->flags |= TF_NAGLEMEMERR;
|
||||
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
|
||||
* length of the queue exceeds the configured maximum or
|
||||
* 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",
|
||||
queuelen, (int)TCP_SND_QUEUELEN));
|
||||
queuelen, (int)TCP_SND_QUEUELEN(pcb)));
|
||||
pbuf_free(p);
|
||||
goto memerr;
|
||||
}
|
||||
@ -766,10 +766,10 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
|
||||
(flags & (TCP_SYN | TCP_FIN)) != 0);
|
||||
|
||||
/* 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)) {
|
||||
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);
|
||||
pcb->flags |= TF_NAGLEMEMERR;
|
||||
return ERR_MEM;
|
||||
@ -1301,6 +1301,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
||||
struct pbuf *p;
|
||||
struct tcp_hdr *tcphdr;
|
||||
struct netif *netif;
|
||||
|
||||
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
|
||||
if (p == NULL) {
|
||||
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->ackno = htonl(ackno);
|
||||
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
|
||||
tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF));
|
||||
#else
|
||||
tcphdr->wnd = PP_HTONS(TCP_WND);
|
||||
#endif
|
||||
#endif
|
||||
tcphdr->chksum = 0;
|
||||
tcphdr->urgp = 0;
|
||||
|
@ -986,7 +986,7 @@
|
||||
* (2 * TCP_MSS) for things to work well
|
||||
*/
|
||||
#ifndef TCP_WND
|
||||
#define TCP_WND (4 * TCP_MSS)
|
||||
#define TCP_WND(pcb) (4 * TCP_MSS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -1040,7 +1040,7 @@
|
||||
* To achieve good performance, this should be at least 2 * TCP_MSS.
|
||||
*/
|
||||
#ifndef TCP_SND_BUF
|
||||
#define TCP_SND_BUF (2 * TCP_MSS)
|
||||
#define TCP_SND_BUF(pcb) (2 * TCP_MSS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -1048,7 +1048,7 @@
|
||||
* as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
|
||||
*/
|
||||
#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
|
||||
|
||||
/**
|
||||
@ -1057,7 +1057,7 @@
|
||||
* TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT).
|
||||
*/
|
||||
#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
|
||||
|
||||
/**
|
||||
@ -1066,7 +1066,7 @@
|
||||
* this number, select returns writable (combined with TCP_SNDLOWAT).
|
||||
*/
|
||||
#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
|
||||
|
||||
/**
|
||||
@ -1134,7 +1134,7 @@
|
||||
* explicit window update
|
||||
*/
|
||||
#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
|
||||
|
||||
/**
|
||||
|
@ -92,7 +92,7 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
|
||||
((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
|
||||
(((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
|
||||
((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)
|
||||
#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_NO_CHECK 0x100a /* don't create UDP checksum */
|
||||
|
||||
|
||||
/*
|
||||
* 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_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 */
|
||||
#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 */
|
||||
|
||||
#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 SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
|
||||
#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 u16_t tcpflags_t;
|
||||
#else
|
||||
#define RCV_WND_SCALE(pcb, wnd) (wnd)
|
||||
#define SND_WND_SCALE(pcb, wnd) (wnd)
|
||||
#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 u8_t tcpflags_t;
|
||||
#endif
|
||||
@ -236,6 +236,11 @@ struct tcp_pcb {
|
||||
u8_t dupacks;
|
||||
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 */
|
||||
tcpwnd_size_t cwnd;
|
||||
tcpwnd_size_t ssthresh;
|
||||
@ -402,6 +407,10 @@ const char* tcp_debug_state_str(enum tcp_state s);
|
||||
/* for compatibility with older implementation */
|
||||
#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
|
||||
}
|
||||
#endif
|
||||
|
@ -225,18 +225,21 @@ extern unsigned long os_random(void);
|
||||
* TCP_WND: The size of a TCP window. This must be at least
|
||||
* (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
|
||||
extern unsigned char misc_prof_get_tcpw(void);
|
||||
extern unsigned char misc_prof_get_tcp_snd_buf(void);
|
||||
#define TCP_WND (misc_prof_get_tcpw()*TCP_MSS)
|
||||
#define TCP_SND_BUF (misc_prof_get_tcp_snd_buf()*TCP_MSS)
|
||||
|
||||
#else
|
||||
|
||||
#define TCP_WND (4 * TCP_MSS)
|
||||
#define TCP_SND_BUF (2 * TCP_MSS)
|
||||
|
||||
#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS)
|
||||
#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#include "esp_wifi_internal.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#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);
|
||||
|
||||
bool ieee80211_output(wifi_interface_t wifi_if, void *buffer, u16_t len);
|
||||
|
||||
wifi_interface_t wifi_get_interface(void *dev);
|
||||
|
||||
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;
|
||||
|
||||
#else
|
||||
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
|
||||
|
||||
|
@ -7177,7 +7177,7 @@ uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session,
|
||||
return session->remote_settings.max_header_list_size;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
abort();
|
||||
}
|
||||
|
||||
static int nghttp2_session_upgrade_internal(nghttp2_session *session,
|
||||
|
@ -769,7 +769,7 @@ void Page::invalidateCache()
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < ENTRY_COUNT; ++i) {
|
||||
printf("%3d: ", static_cast<int>(i));
|
||||
|
@ -49,7 +49,7 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount)
|
||||
return activatePage();
|
||||
} else {
|
||||
uint32_t lastSeqNo;
|
||||
assert(mPageList.back().getSeqNumber(lastSeqNo) == ESP_OK);
|
||||
ESP_ERROR_CHECK( mPageList.back().getSeqNumber(lastSeqNo) );
|
||||
mSeqNumber = lastSeqNo + 1;
|
||||
}
|
||||
|
||||
@ -142,7 +142,9 @@ esp_err_t PageManager::requestNewPage()
|
||||
Page* newPage = &mPageList.back();
|
||||
|
||||
Page* erasedPage = maxErasedItemsPageIt;
|
||||
#ifndef NDEBUG
|
||||
size_t usedEntries = erasedPage->getUsedEntryCount();
|
||||
#endif
|
||||
err = erasedPage->markFreeing();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
|
@ -123,8 +123,7 @@ esp_err_t Storage::writeItem(uint8_t nsIndex, ItemType datatype, const char* key
|
||||
if (findPage) {
|
||||
if (findPage->state() == Page::PageState::UNINITIALIZED ||
|
||||
findPage->state() == Page::PageState::INVALID) {
|
||||
auto err = findItem(nsIndex, datatype, key, findPage, item);
|
||||
assert(err == ESP_OK);
|
||||
ESP_ERROR_CHECK( findItem(nsIndex, datatype, key, findPage, item) );
|
||||
}
|
||||
err = findPage->eraseItem(nsIndex, datatype, key);
|
||||
if (err == ESP_ERR_FLASH_OP_FAIL) {
|
||||
|
@ -1,3 +1,8 @@
|
||||
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
|
||||
|
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;
|
||||
|
||||
#if CONFIG_DHCP_STA_LIST
|
||||
struct station_list {
|
||||
STAILQ_ENTRY(station_list) next;
|
||||
typedef struct {
|
||||
uint8_t mac[6];
|
||||
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
|
||||
@ -359,26 +363,14 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev);
|
||||
/**
|
||||
* @brief Get the station information list
|
||||
*
|
||||
* @note This function should be called in AP mode and dhcp server started, and the list should
|
||||
* be by using tcpip_adapter_free_sta_list.
|
||||
*
|
||||
* @param[in] sta_info: station information
|
||||
* @param[out] sta_list: station information list
|
||||
* @param[in] wifi_sta_list_t *wifi_sta_list: station list info
|
||||
* @param[out] tcpip_adapter_sta_list_t *tcpip_sta_list: station list info
|
||||
*
|
||||
* @return ESP_OK
|
||||
* ESP_ERR_TCPIP_ADAPTER_NO_MEM
|
||||
* ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
|
||||
*/
|
||||
esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **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);
|
||||
esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list);
|
||||
|
||||
#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) {
|
||||
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) {
|
||||
dhcp_release(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;
|
||||
}
|
||||
|
||||
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;
|
||||
struct station_list *list;
|
||||
STAILQ_HEAD(, station_list) list_head;
|
||||
int i;
|
||||
|
||||
if (sta_list == NULL)
|
||||
if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL))
|
||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||
|
||||
STAILQ_INIT(&list_head);
|
||||
|
||||
while (info != NULL) {
|
||||
list = (struct station_list *)malloc(sizeof(struct station_list));
|
||||
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);
|
||||
memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t));
|
||||
for (i=0; i<wifi_sta_list->num; i++){
|
||||
memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
|
||||
dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip);
|
||||
}
|
||||
|
||||
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,
|
||||
# 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
|
||||
#
|
||||
|
@ -91,15 +91,15 @@ define GenerateCompileTargets
|
||||
# $(1) - directory containing source files, relative to $(COMPONENT_PATH)
|
||||
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1)
|
||||
$$(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)
|
||||
$$(summary) CC $$@
|
||||
$$(Q) $$(CXX) $$(CXXFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
||||
$$(summary) CXX $$@
|
||||
$$(Q) $$(CXX) $$(CXXFLAGS) $(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
||||
|
||||
$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1)
|
||||
$$(summary) CC $$@
|
||||
$$(Q) $$(CC) $$(CFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
|
||||
$$(summary) AS $$@
|
||||
$$(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
|
||||
$(1):
|
||||
|
@ -37,6 +37,7 @@ help:
|
||||
@echo "'make partition_table', etc, etc."
|
||||
|
||||
# disable built-in make rules, makes debugging saner
|
||||
MAKEFLAGS_OLD := $(MAKEFLAGS)
|
||||
MAKEFLAGS +=-rR
|
||||
|
||||
# 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
|
||||
#configure this if needed.
|
||||
BUILD_DIR_BASE ?= $(PROJECT_PATH)/build
|
||||
export BUILD_DIR_BASE
|
||||
|
||||
#Component directories. These directories are searched for components.
|
||||
#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))))
|
||||
|
||||
#Also add project include path, for sdk includes
|
||||
COMPONENT_INCLUDES += $(PROJECT_PATH)/build/include/
|
||||
COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/)
|
||||
export COMPONENT_INCLUDES
|
||||
|
||||
#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
|
||||
|
||||
# Set default CPPFLAGS, CFLAGS, CXXFLAGS
|
||||
#
|
||||
# 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 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 = -DESP_PLATFORM -Og -g3 -Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable \
|
||||
-Wno-error=unused-variable -Wall -ffunction-sections -fdata-sections -mlongcalls -nostdlib -MMD -MP
|
||||
# CPPFLAGS used by C preprocessor
|
||||
# If any flags are defined in application Makefile, add them at the end.
|
||||
CPPFLAGS := -DESP_PLATFORM $(CPPFLAGS)
|
||||
|
||||
# C flags use by C only
|
||||
CFLAGS = $(CPPFLAGS) -std=gnu99 -g3 -fstrict-volatile-bitfields
|
||||
# Warnings-related flags relevant both for C and C++
|
||||
COMMON_WARNING_FLAGS = -Wall -Werror \
|
||||
-Wno-error=unused-function \
|
||||
-Wno-error=unused-but-set-variable \
|
||||
-Wno-error=unused-variable
|
||||
|
||||
# CXXFLAGS uses by C++ only
|
||||
CXXFLAGS = $(CPPFLAGS) -Og -std=gnu++11 -g3 -fno-exceptions -fstrict-volatile-bitfields -fno-rtti
|
||||
# Flags which control code generation and dependency generation, both for C and C++
|
||||
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
|
||||
|
||||
@ -174,6 +214,7 @@ HOSTCC := $(CC)
|
||||
HOSTLD := $(LD)
|
||||
HOSTAR := $(AR)
|
||||
HOSTOBJCOPY := $(OBJCOPY)
|
||||
export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY
|
||||
|
||||
#Set target compiler. Defaults to whatever the user has
|
||||
#configured as prefix + yer olde gcc commands
|
||||
@ -230,7 +271,7 @@ define GenerateComponentPhonyTarget
|
||||
# $(2) - target to generate (build, clean)
|
||||
.PHONY: $(notdir $(1))-$(2)
|
||||
$(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
|
||||
|
||||
define GenerateComponentTargets
|
||||
|
@ -7,38 +7,38 @@ COMPONENT_KCONFIGS_PROJBUILD := $(foreach component,$(COMPONENT_PATHS),$(wildcar
|
||||
#For doing make menuconfig etc
|
||||
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:
|
||||
MAKEFLAGS="" \
|
||||
CC=$(HOSTCC) LD=$(HOSTLD) \
|
||||
MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \
|
||||
$(MAKE) -C $(KCONFIG_TOOL_DIR)
|
||||
|
||||
# use a wrapper environment for where we run Kconfig tools
|
||||
KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \
|
||||
COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \
|
||||
COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)"
|
||||
|
||||
menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE)
|
||||
$(summary) MENUCONFIG
|
||||
$(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \
|
||||
KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \
|
||||
COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \
|
||||
COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
||||
$(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig
|
||||
$(Q) $(KCONFIG_TOOL_ENV) $(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.
|
||||
$(PROJECT_PATH)/sdkconfig: menuconfig
|
||||
$(SDKCONFIG): menuconfig
|
||||
endif
|
||||
|
||||
defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE)
|
||||
$(summary) DEFCONFIG
|
||||
$(Q) mkdir -p $(PROJECT_PATH)/build/include/config
|
||||
$(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \
|
||||
KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \
|
||||
COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \
|
||||
COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
||||
$(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig
|
||||
$(Q) mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||
$(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig
|
||||
|
||||
# Work out of whether we have to build the Kconfig makefile
|
||||
# (auto.conf), or if we're in a situation where we don't need it
|
||||
NON_CONFIG_TARGETS := clean %-clean 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
|
||||
# (and not building default target)
|
||||
@ -46,19 +46,15 @@ ifneq ("$(MAKECMDGOALS)","")
|
||||
ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
||||
AUTO_CONF_REGEN_TARGET :=
|
||||
# dummy target
|
||||
$(PROJECT_PATH)/build/include/config/auto.conf:
|
||||
$(BUILD_DIR_BASE)/include/config/auto.conf:
|
||||
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
|
||||
$(Q) mkdir -p $(PROJECT_PATH)/build/include/config
|
||||
$(Q) cd build; KCONFIG_AUTOHEADER="$(PROJECT_PATH)/build/include/sdkconfig.h" \
|
||||
KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \
|
||||
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
|
||||
$(Q) mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||
$(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig
|
||||
$(Q) touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h
|
||||
# touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this,
|
||||
# sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer
|
||||
# than the target(!)
|
||||
@ -68,4 +64,4 @@ clean: config-clean
|
||||
config-clean:
|
||||
$(summary RM CONFIG)
|
||||
$(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
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Environment variables:
|
||||
@ -11,6 +11,18 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
# 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
|
||||
#
|
||||
@ -21,103 +33,137 @@ export V=1
|
||||
|
||||
function run_tests()
|
||||
{
|
||||
FAILURES=
|
||||
STATUS="Starting"
|
||||
print_status "Checking prerequisites"
|
||||
[ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2
|
||||
FAILURES=
|
||||
STATUS="Starting"
|
||||
print_status "Checking prerequisites"
|
||||
[ -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}..."
|
||||
git clone ${ESP_IDF_TEMPLATE_GIT} template
|
||||
cd template
|
||||
git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..."
|
||||
git clone ${ESP_IDF_TEMPLATE_GIT} template
|
||||
cd template
|
||||
git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
|
||||
print_status "Updating template config..."
|
||||
make defconfig || exit $?
|
||||
print_status "Updating template config..."
|
||||
make defconfig || exit $?
|
||||
|
||||
BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin"
|
||||
APP_BINS="app-template.elf app-template.bin"
|
||||
BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin"
|
||||
APP_BINS="app-template.elf app-template.bin"
|
||||
|
||||
print_status "Initial clean build"
|
||||
# if make fails here, everything fails
|
||||
make || exit $?
|
||||
# check all the expected build artifacts from the clean build
|
||||
assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||
[ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built"
|
||||
print_status "Initial clean build"
|
||||
# if make fails here, everything fails
|
||||
make || exit $?
|
||||
# check all the expected build artifacts from the clean build
|
||||
assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||
[ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built"
|
||||
|
||||
print_status "Updating component source file rebuilds component"
|
||||
# touch a file & do a build
|
||||
take_build_snapshot
|
||||
touch ${IDF_PATH}/components/esp32/syscalls.c
|
||||
make || failure "Failed to partial build"
|
||||
assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o
|
||||
assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||
print_status "Updating component source file rebuilds component"
|
||||
# touch a file & do a build
|
||||
take_build_snapshot
|
||||
touch ${IDF_PATH}/components/esp32/syscalls.c
|
||||
make || failure "Failed to partial build"
|
||||
assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o
|
||||
assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin
|
||||
|
||||
print_status "Bootloader source file rebuilds bootloader"
|
||||
take_build_snapshot
|
||||
touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c
|
||||
make bootloader || failure "Failed to partial build bootloader"
|
||||
assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o
|
||||
assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin
|
||||
print_status "Bootloader source file rebuilds bootloader"
|
||||
take_build_snapshot
|
||||
touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c
|
||||
make bootloader || failure "Failed to partial build bootloader"
|
||||
assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o
|
||||
assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin
|
||||
|
||||
print_status "Partition CSV file rebuilds partitions"
|
||||
take_build_snapshot
|
||||
touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv
|
||||
make partition_table
|
||||
assert_rebuilt partitions_singleapp.bin
|
||||
assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS}
|
||||
print_status "Partition CSV file rebuilds partitions"
|
||||
take_build_snapshot
|
||||
touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv
|
||||
make partition_table || failure "Failed to build partition table"
|
||||
assert_rebuilt partitions_singleapp.bin
|
||||
assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS}
|
||||
|
||||
print_status "Partial build doesn't compile anything by default"
|
||||
take_build_snapshot
|
||||
# verify no build files are refreshed by a partial make
|
||||
ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@")
|
||||
make
|
||||
assert_not_rebuilt ${ALL_BUILD_FILES}
|
||||
print_status "Partial build doesn't compile anything by default"
|
||||
take_build_snapshot
|
||||
# verify no build files are refreshed by a partial make
|
||||
ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@")
|
||||
make || failure "Partial build failed"
|
||||
assert_not_rebuilt ${ALL_BUILD_FILES}
|
||||
|
||||
print_status "Cleaning should remove all files from build"
|
||||
make clean
|
||||
ALL_BUILD_FILES=$(find ${BUILD} -type f)
|
||||
if [ -n "${ALL_BUILD_FILES}" ]; then
|
||||
failure "Files weren't cleaned: ${ALL_BUILD_FILES}"
|
||||
fi
|
||||
print_status "Cleaning should remove all files from build"
|
||||
make clean || failure "Failed to make clean"
|
||||
ALL_BUILD_FILES=$(find ${BUILD} -type f)
|
||||
if [ -n "${ALL_BUILD_FILES}" ]; then
|
||||
failure "Files weren't cleaned: ${ALL_BUILD_FILES}"
|
||||
fi
|
||||
|
||||
print_status "Can still clean build if all text files are CRLFs"
|
||||
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}
|
||||
# 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 "Bootloader build shouldn't leave build output anywhere else"
|
||||
clean_build_dir
|
||||
make bootloader
|
||||
# find wizardry: find any file not named sdkconfig.h that
|
||||
# isn't in the "bootloader" or "config" directories
|
||||
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"
|
||||
|
||||
# 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"
|
||||
if [ -n "${FAILURES}" ]; then
|
||||
echo "Some failures were detected:"
|
||||
echo -e "${FAILURES}"
|
||||
exit 1
|
||||
else
|
||||
echo "Build tests passed."
|
||||
fi
|
||||
print_status "BUILD_DIR_BASE inside default build directory"
|
||||
clean_build_dir
|
||||
make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir"
|
||||
NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f)
|
||||
if [ -z "${NEW_BUILD_FILES}" ]; then
|
||||
failure "No files found in new build directory!"
|
||||
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()
|
||||
{
|
||||
echo "******** $1"
|
||||
STATUS="$1"
|
||||
echo "******** $1"
|
||||
STATUS="$1"
|
||||
}
|
||||
|
||||
function failure()
|
||||
{
|
||||
echo "!!!!!!!!!!!!!!!!!!!"
|
||||
echo "FAILURE: $1"
|
||||
echo "!!!!!!!!!!!!!!!!!!!"
|
||||
FAILURES="${FAILURES}${STATUS} :: $1\n"
|
||||
echo "!!!!!!!!!!!!!!!!!!!"
|
||||
echo "FAILURE: $1"
|
||||
echo "!!!!!!!!!!!!!!!!!!!"
|
||||
FAILURES="${FAILURES}${STATUS} :: $1\n"
|
||||
}
|
||||
|
||||
TESTDIR=${TMP}/build_system_tests_$$
|
||||
@ -133,62 +179,68 @@ BUILD=${TESTDIR}/template/build
|
||||
# copy all the build output to a snapshot directory
|
||||
function take_build_snapshot()
|
||||
{
|
||||
rm -rf ${SNAPSHOT}
|
||||
cp -ap ${TESTDIR}/template/build ${SNAPSHOT}
|
||||
rm -rf ${SNAPSHOT}
|
||||
cp -ap ${TESTDIR}/template/build ${SNAPSHOT}
|
||||
}
|
||||
|
||||
# verify that all the arguments are present in the build output directory
|
||||
function assert_built()
|
||||
{
|
||||
until [ -z "$1" ]; do
|
||||
if [ ! -f "${BUILD}/$1" ]; then
|
||||
failure "File $1 should be in the build output directory"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
until [ -z "$1" ]; do
|
||||
if [ ! -f "${BUILD}/$1" ]; then
|
||||
failure "File $1 should be in the build output directory"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
# Test if a file has been rebuilt.
|
||||
function file_was_rebuilt()
|
||||
{
|
||||
# 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..
|
||||
if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
# 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..
|
||||
if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# verify all the arguments passed in were rebuilt relative to the snapshot
|
||||
function assert_rebuilt()
|
||||
{
|
||||
until [ -z "$1" ]; do
|
||||
assert_built "$1"
|
||||
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
||||
failure "File $1 should have been original build snapshot"
|
||||
fi
|
||||
if ! file_was_rebuilt "$1"; then
|
||||
failure "File $1 should have been rebuilt"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
until [ -z "$1" ]; do
|
||||
assert_built "$1"
|
||||
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
||||
failure "File $1 should have been original build snapshot"
|
||||
fi
|
||||
if ! file_was_rebuilt "$1"; then
|
||||
failure "File $1 should have been rebuilt"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
# verify all the arguments are in the build directory & snapshot,
|
||||
# but were not rebuilt
|
||||
function assert_not_rebuilt()
|
||||
{
|
||||
until [ -z "$1" ]; do
|
||||
assert_built "$1"
|
||||
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
||||
failure "File $1 should be in snapshot build directory"
|
||||
fi
|
||||
if file_was_rebuilt "$1"; then
|
||||
failure "File $1 should not have been rebuilt"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
until [ -z "$1" ]; do
|
||||
assert_built "$1"
|
||||
if [ ! -f "${SNAPSHOT}/$1" ]; then
|
||||
failure "File $1 should be in snapshot build directory"
|
||||
fi
|
||||
if file_was_rebuilt "$1"; then
|
||||
failure "File $1 should not have been rebuilt"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
# do a "clean" that doesn't depend on 'make clean'
|
||||
function clean_build_dir()
|
||||
{
|
||||
rm -rf --preserve-root ${BUILD}/*
|
||||
}
|
||||
|
||||
cd ${TESTDIR}
|
||||
|
Loading…
x
Reference in New Issue
Block a user