From e743d03a78609745794762004d12c7379a5ad2ab Mon Sep 17 00:00:00 2001 From: Angus Gratton <gus@projectgus.com> Date: Sat, 30 May 2015 19:11:04 +1000 Subject: [PATCH] Preprocess all binary SDK symbols to add an sdk_ prefix * This fixes the problem of axTLS symbols hmac_md5/hmac_sha1 having same name as symbols in libwpa (which have incompatible signatures) * Also allows for easier identification and piece-by-piece removal of binary functions. * Some libc symbols are not renamed, list is in lib/symbols_norename.txt --- FreeRTOS/Source/portable/esp8266/port.c | 16 +++--- FreeRTOS/Source/portable/esp8266/portmacro.h | 21 ++++--- common.mk | 57 ++++++++++++++++--- examples/http_get/main.c | 10 ++-- include/esp8266.h | 33 +++++++++++ include/espressif/esp_misc.h | 6 +- include/espressif/esp_softap.h | 6 +- include/espressif/esp_sta.h | 28 ++++----- include/espressif/esp_system.h | 32 +++++------ include/espressif/esp_timer.h | 6 +- include/espressif/esp_wifi.h | 33 ++++++----- include/espressif/sdk_prototypes.h | 23 ++++++-- include/espressif/spi_flash.h | 14 ++--- ld/eagle.app.v6.ld | 18 +++--- lib/libhal.a | Bin 162888 -> 0 bytes lib/symbols_norename.txt | 6 ++ lwip/esp_interface.c | 4 +- lwip/include/arch/cc.h | 8 +++ lwip/include/arch/sys_arch.h | 2 + 19 files changed, 220 insertions(+), 103 deletions(-) create mode 100644 include/esp8266.h delete mode 100644 lib/libhal.a create mode 100644 lib/symbols_norename.txt diff --git a/FreeRTOS/Source/portable/esp8266/port.c b/FreeRTOS/Source/portable/esp8266/port.c index 0aaed7b..42cb36a 100644 --- a/FreeRTOS/Source/portable/esp8266/port.c +++ b/FreeRTOS/Source/portable/esp8266/port.c @@ -99,7 +99,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE SET_STKREG( XT_STK_A0, 0 ); /* to terminate GDB backtrace */ SET_STKREG( XT_STK_A1, (uint32_t)sp + XT_STK_FRMSZ ); /* physical top of stack frame */ SET_STKREG( XT_STK_A2, pvParameters ); /* parameters */ - SET_STKREG( XT_STK_EXIT, _xt_user_exit ); /* user exception exit dispatcher */ + SET_STKREG( XT_STK_EXIT, sdk__xt_user_exit ); /* user exception exit dispatcher */ /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */ SET_STKREG( XT_STK_PS, PS_UM | PS_EXCM ); @@ -139,19 +139,19 @@ void PendSV(enum SVC_ReqType req) * after a Blob SV requests a soft interrupt by calling * PendSV(SVC_MACLayer). */ -extern portBASE_TYPE MacIsrSigPostDefHdl(void); +extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void); void SV_ISR(void) { portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ; if(pending_maclayer_sv) { - xHigherPriorityTaskWoken = MacIsrSigPostDefHdl(); + xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl(); pending_maclayer_sv = 0; } if( xHigherPriorityTaskWoken || pending_soft_sv) { - _xt_timer_int1(); + sdk__xt_timer_int1(); pending_soft_sv = 0; } } @@ -175,14 +175,14 @@ void xPortSysTickHandle (void) portBASE_TYPE xPortStartScheduler( void ) { _xt_isr_attach(ETS_SOFT_INUM, SV_ISR); - _xt_isr_unmask(1<<ETS_SOFT_INUM); + sdk__xt_isr_unmask(1<<ETS_SOFT_INUM); /* Initialize system tick timer interrupt and schedule the first tick. */ - _xt_tick_timer_init(); + sdk__xt_tick_timer_init(); vTaskSwitchContext(); - _xt_int_exit(); + sdk__xt_int_exit(); /* Should not get here as the tasks are now running! */ return pdTRUE; @@ -254,7 +254,7 @@ uint16_t _xt_isr_handler(uint16_t i) } } - _xt_clear_ints(1<<index); + sdk__xt_clear_ints(1<<index); isr[index](); diff --git a/FreeRTOS/Source/portable/esp8266/portmacro.h b/FreeRTOS/Source/portable/esp8266/portmacro.h index 6cdf8c7..a41b1f7 100644 --- a/FreeRTOS/Source/portable/esp8266/portmacro.h +++ b/FreeRTOS/Source/portable/esp8266/portmacro.h @@ -183,18 +183,21 @@ not necessary for to use this port. They are defined so the common demo files #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*-----------------------------------------------------------*/ +/* ESPTODO: These parts of the FreeRTOS support are still in binary libraries */ +#define vApplicationStackOverflowHook sdk_vApplicationStackOverflowHook + /* XTensa interrupt management functions, used in port.c. - Implementations in blob libs */ -void _xt_int_exit (void); -void _xt_user_exit (void); -void _xt_tick_timer_init (void); -void _xt_isr_unmask (uint32_t unmask); -void _xt_isr_mask (uint32_t mask); -uint32_t _xt_read_ints (void); -void _xt_clear_ints(uint32_t mask); + Some (w/ sdk_ prefix) are implemented in blob libs */ +void sdk__xt_int_exit (void); +void sdk__xt_user_exit (void); +void sdk__xt_tick_timer_init (void); +void sdk__xt_isr_unmask (uint32_t unmask); +void sdk__xt_isr_mask (uint32_t mask); +uint32_t sdk__xt_read_ints (void); +void sdk__xt_clear_ints(uint32_t mask); typedef void (* _xt_isr)(void); void _xt_isr_attach (uint8_t i, _xt_isr func); -void _xt_timer_int1(void); +void sdk__xt_timer_int1(void); #ifdef __cplusplus } diff --git a/common.mk b/common.mk index 1d17564..70309b9 100644 --- a/common.mk +++ b/common.mk @@ -55,11 +55,16 @@ OBJCOPY = $(CROSS)objcopy # of the root, with a 'component.mk' file. COMPONENTS ?= FreeRTOS lwip -# libraries to link, mainly blobs provided by the esp-iot-rtos SDK -LIBS ?= gcc main net80211 phy pp ssl wpa hal +# binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking. +SDK_LIBS ?= main net80211 phy pp wpa + +# open source libraries linked in +LIBS ?= gcc hal + +ENTRY_SYMBOL ?= sdk_call_user_start CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 -LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(ROOT)lib -u call_user_start -Wl,-static -Wl,-Map=build/${TARGET}.map +LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${TARGET}.map ifeq ($(FLAVOR),debug) CFLAGS += -g -O0 @@ -86,7 +91,8 @@ TARGET_DIR := $(dir $(firstword $(MAKEFILE_LIST))) ROOT := $(dir $(lastword $(MAKEFILE_LIST))) # derive various parts of compiler/linker arguments -LIB_ARGS = $(addprefix -l,$(LIBS)) +SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS)) +LIB_ARGS = $(addprefix -l,$(LIBS)) TARGET_OUT = $(BUILD_DIR)$(TARGET).out LDFLAGS += $(addprefix -T$(ROOT),$(LINKER_SCRIPTS)) FW_FILE_1 = $(addprefix $(FW_BASE)/,$(FW_1).bin) @@ -158,6 +164,37 @@ COMPONENT_ARS += $$($(1)_AR) -include $$($(1)_OBJ_FILES:.o=.d) endef + +## Linking rules for SDK libraries +## SDK libraries are preprocessed to: +# - prefix all defined symbols with 'sdk_' +# - weaken all global symbols so they can be overriden from the open SDK side + +# SDK binary libraries are preprocessed into build/lib +SDK_PROCESSED_LIBS = $(addsuffix .a,$(addprefix $(BUILD_DIR)sdklib/lib,$(SDK_LIBS))) + +# Make rule for preprocessing each SDK library +# +$(BUILD_DIR)sdklib/%.a: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/allsymbols.rename + $(vecho) "Pre-processing SDK library $< -> $@" + $(Q) $(OBJCOPY) --redefine-syms $(word 2,$^) --weaken $< $@ + + +# Generate a regex to match symbols we don't want to rename, by parsing +# a list of symbol names +$(BUILD_DIR)sdklib/norename.match: $(ROOT)lib/symbols_norename.txt | $(BUILD_DIR)sdklib + grep -v "^#" $< | sed ':begin;$!N;s/\n/\\|/;tbegin' > $@ + +# Generate list of symbols to rename from a single library. Uses grep & sed. +$(BUILD_DIR)sdklib/%.rename: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/norename.match + $(vecho) "Building symbol list for $< -> $@" + $(Q) $(NM) --defined $< | grep ' T ' | sed -r 's/(.+) T (.+)/\2 sdk_\2/' | grep -v `cat $(BUILD_DIR)sdklib/norename.match` > $@ + +# Build master list of all SDK-defined symbols to rename +$(BUILD_DIR)sdklib/allsymbols.rename: $(patsubst %.a,%.rename,$(SDK_PROCESSED_LIBS)) + cat $^ > $@ + + ## Include components (this is where the actual compiler sections are generated) $(foreach component,$(COMPONENTS), $(eval include $(ROOT)/$(component)/component.mk)) @@ -167,16 +204,16 @@ target_ROOT=$(TARGET_DIR) $(eval $(call component_compile_rules,target)) # final linking step to produce .elf -$(TARGET_OUT): $(COMPONENT_ARS) +$(TARGET_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(vecho) "LD $@" - $(Q) $(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@ + $(Q) $(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(SDK_LIB_ARGS) $(LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@ -$(BUILD_DIR) $(FW_BASE): +$(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib: $(Q) mkdir -p $@ $(FW_FILE_1) $(FW_FILE_2): $(TARGET_OUT) $(FW_BASE) $(vecho) "FW $@" - $(ESPTOOL) elf2image $< -o $(FW_BASE) + $(ESPTOOL) elf2image --entry-symbol $(ENTRY_SYMBOL) $< -o $(FW_BASE) flash: $(FW_FILE_1) $(FW_FILE_2) $(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2) @@ -196,3 +233,7 @@ rebuild: clean: $(Q) rm -rf $(BUILD_DIR) $(Q) rm -rf $(FW_BASE) + +# prevent "intermediate" files from being deleted +.SECONDARY: + diff --git a/examples/http_get/main.c b/examples/http_get/main.c index fc12910..6af7e34 100644 --- a/examples/http_get/main.c +++ b/examples/http_get/main.c @@ -109,17 +109,17 @@ void http_get_task(void *pvParameters) void user_init(void) { - uart_div_modify(0, UART_CLK_FREQ / 115200); - printf("SDK version:%s\n", system_get_sdk_version()); + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); - struct station_config config = { + struct sdk_station_config config = { .ssid = WIFI_SSID, .password = WIFI_PASS, }; /* required to call wifi_set_opmode before station_set_config */ - wifi_set_opmode(STATION_MODE); - wifi_station_set_config(&config); + sdk_wifi_set_opmode(STATION_MODE); + sdk_wifi_station_set_config(&config); xTaskCreate(&http_get_task, (signed char *)"get_task", 256, NULL, 2, NULL); } diff --git a/include/esp8266.h b/include/esp8266.h new file mode 100644 index 0000000..a58a9be --- /dev/null +++ b/include/esp8266.h @@ -0,0 +1,33 @@ +/* esp8266.h + * + * ESP-specific SoC-level addresses, macros, etc. + * Part of esp-open-rtos + * + * Copyright (C) 2105 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#include <stdint.h> + +#ifndef _ESP8266_H +#define _ESP8266_H + +/* Use this macro to store constant values in IROM flash instead + of having them loaded into rodata (which resides in DRAM) + + Unlike the ESP8266 SDK you don't need an attribute like this for + standard functions. They're stored in flash by default. But + variables need them. + + Important to note: IROM flash can only be accessed via 32-bit word + aligned reads. It's up to the user of this attribute to ensure this. +*/ +#define IROM __attribute__((section(".irom0"))) const + + +/* Register addresses + + ESPTODO: break this out to its own header file and clean it up, add other regs, etc. +*/ +static volatile __attribute__((unused)) uint32_t *ESP_REG_WDT = (uint32_t *)0x60000900; + +#endif diff --git a/include/espressif/esp_misc.h b/include/espressif/esp_misc.h index 68d9724..d8ce65e 100644 --- a/include/espressif/esp_misc.h +++ b/include/espressif/esp_misc.h @@ -18,9 +18,9 @@ #define IPSTR "%d.%d.%d.%d" -void os_delay_us(uint16_t us); +void sdk_os_delay_us(uint16_t us); -void os_install_putc1(void (*p)(char c)); -void os_putc(char c); +void sdk_os_install_putc1(void (*p)(char c)); +void sdk_os_putc(char c); #endif diff --git a/include/espressif/esp_softap.h b/include/espressif/esp_softap.h index c2bbe42..44f06cc 100644 --- a/include/espressif/esp_softap.h +++ b/include/espressif/esp_softap.h @@ -6,7 +6,7 @@ #ifndef __ESP_SOFTAP_H__ #define __ESP_SOFTAP_H__ -struct softap_config { +struct sdk_softap_config { uint8_t ssid[32]; uint8_t password[64]; uint8_t ssid_len; @@ -17,7 +17,7 @@ struct softap_config { uint16_t beacon_interval; }; -bool wifi_softap_get_config(struct softap_config *config); -bool wifi_softap_set_config(struct softap_config *config); +bool sdk_wifi_softap_get_config(struct sdk_softap_config *config); +bool sdk_wifi_softap_set_config(struct sdk_softap_config *config); #endif diff --git a/include/espressif/esp_sta.h b/include/espressif/esp_sta.h index 779242f..8b9059a 100644 --- a/include/espressif/esp_sta.h +++ b/include/espressif/esp_sta.h @@ -1,6 +1,8 @@ /* * Copyright (C) 2013 -2014 Espressif System * + * + * Adapted from BSD licensed esp_iot_rtos_sdk v0.9.9 */ #ifndef __ESP_STA_H__ @@ -8,27 +10,27 @@ #include "queue.h" -struct station_config { +struct sdk_station_config { uint8_t ssid[32]; uint8_t password[64]; uint8_t bssid_set; uint8_t bssid[6]; }; -bool wifi_station_get_config(struct station_config *config); -bool wifi_station_set_config(struct station_config *config); +bool sdk_wifi_station_get_config(struct sdk_station_config *config); +bool sdk_wifi_station_set_config(struct sdk_station_config *config); -bool wifi_station_connect(void); -bool wifi_station_disconnect(void); +bool sdk_wifi_station_connect(void); +bool sdk_wifi_station_disconnect(void); -struct scan_config { +struct sdk_scan_config { uint8_t *ssid; uint8_t *bssid; uint8_t channel; uint8_t show_hidden; }; -struct bss_info { +struct sdk_bss_info { STAILQ_ENTRY(bss_info) next; uint8_t bssid[6]; @@ -46,14 +48,14 @@ typedef enum { SCAN_PENDING, SCAN_BUSY, SCAN_CANCEL, -} scan_status_t; +} sdk_scan_status_t; -typedef void (* scan_done_cb_t)(void *arg, scan_status_t status); +typedef void (* sdk_scan_done_cb_t)(void *arg, sdk_scan_status_t status); -bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb); +bool sdk_wifi_station_scan(struct sdk_scan_config *config, sdk_scan_done_cb_t cb); -uint8_t wifi_station_get_auto_connect(void); -bool wifi_station_set_auto_connect(uint8_t set); +uint8_t sdk_wifi_station_get_auto_connect(void); +bool sdk_wifi_station_set_auto_connect(uint8_t set); enum { STATION_IDLE = 0, @@ -64,6 +66,6 @@ enum { STATION_GOT_IP }; -uint8_t wifi_station_get_connect_status(void); +uint8_t sdk_wifi_station_get_connect_status(void); #endif diff --git a/include/espressif/esp_system.h b/include/espressif/esp_system.h index be3e6a0..265bc8c 100644 --- a/include/espressif/esp_system.h +++ b/include/espressif/esp_system.h @@ -6,14 +6,14 @@ #ifndef __ESP_SYSTEM_H__ #define __ESP_SYSTEM_H__ -enum rst_reason { +enum sdk_rst_reason { DEFAULT_RST = 0, WDT_RST = 1, EXCEPTION_RST = 2, SOFT_RST = 3 }; -struct rst_info{ +struct sdk_rst_info{ uint32_t reason; uint32_t exccause; uint32_t epc1; @@ -24,26 +24,26 @@ struct rst_info{ uint32_t rtn_addr; }; -struct rst_info* system_get_rst_info(void); +struct rst_info* sdk_system_get_rst_info(void); -const char* system_get_sdk_version(void); +const char* sdk_system_get_sdk_version(void); -void system_restore(void); -void system_restart(void); -void system_deep_sleep(uint32_t time_in_us); +void sdk_system_restore(void); +void sdk_system_restart(void); +void sdk_system_deep_sleep(uint32_t time_in_us); -uint32_t system_get_time(void); +uint32_t sdk_system_get_time(void); -void system_print_meminfo(void); -uint32_t system_get_free_heap_size(void); -uint32_t system_get_chip_id(void); +void sdk_system_print_meminfo(void); +uint32_t sdk_system_get_free_heap_size(void); +uint32_t sdk_system_get_chip_id(void); -uint32_t system_rtc_clock_cali_proc(void); -uint32_t system_get_rtc_time(void); +uint32_t sdk_system_rtc_clock_cali_proc(void); +uint32_t sdk_system_get_rtc_time(void); -bool system_rtc_mem_read(uint8_t src, void *dst, uint16_t n); -bool system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n); +bool sdk_system_rtc_mem_read(uint8_t src, void *dst, uint16_t n); +bool sdk_system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n); -void system_uart_swap(void); +void sdk_system_uart_swap(void); #endif diff --git a/include/espressif/esp_timer.h b/include/espressif/esp_timer.h index 8ba6295..6f05547 100644 --- a/include/espressif/esp_timer.h +++ b/include/espressif/esp_timer.h @@ -7,16 +7,16 @@ #define __ESP_TIMER_H__ /* timer related */ -typedef void os_timer_func_t(void *timer_arg); +typedef void sdk_os_timer_func_t(void *timer_arg); typedef struct _os_timer_t { struct _os_timer_t *timer_next; void *freerots_handle; uint32_t timer_expire; uint32_t timer_period; - os_timer_func_t *timer_func; + sdk_os_timer_func_t *timer_func; bool timer_repeat_flag; void *timer_arg; -} os_timer_t; +} sdk_os_timer_t; #endif diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h index 08824d6..e2274f1 100644 --- a/include/espressif/esp_wifi.h +++ b/include/espressif/esp_wifi.h @@ -1,6 +1,9 @@ /* * Copyright (C) 2013 -2014 Espressif System * + * Adapted from BSD licensed esp_iot_rtos_sdk v0.9.9 + * + * Functions declared in this header are defined in libmain.a */ #ifndef __ESP_WIFI_H__ @@ -23,8 +26,8 @@ typedef enum _auth_mode { AUTH_MAX } AUTH_MODE; -uint8_t wifi_get_opmode(void); -bool wifi_set_opmode(uint8_t opmode); +uint8_t sdk_wifi_get_opmode(void); +bool sdk_wifi_set_opmode(uint8_t opmode); enum { STATION_IF = 0, @@ -38,29 +41,29 @@ struct ip_info { struct ip_addr gw; }; -bool wifi_get_ip_info(uint8_t if_index, struct ip_info *info); -bool wifi_set_ip_info(uint8_t if_index, struct ip_info *info); -bool wifi_get_macaddr(uint8_t if_index, uint8_t *macaddr); -bool wifi_set_macaddr(uint8_t if_index, uint8_t *macaddr); +bool sdk_wifi_get_ip_info(uint8_t if_index, struct ip_info *info); +bool sdk_wifi_set_ip_info(uint8_t if_index, struct ip_info *info); +bool sdk_wifi_get_macaddr(uint8_t if_index, uint8_t *macaddr); +bool sdk_wifi_set_macaddr(uint8_t if_index, uint8_t *macaddr); -uint8_t wifi_get_channel(void); -bool wifi_set_channel(uint8_t channel); +uint8_t sdk_wifi_get_channel(void); +bool sdk_wifi_set_channel(uint8_t channel); -void wifi_status_led_install(uint8_t gpio_id, uint32_t gpio_name, uint8_t gpio_func); +void sdk_wifi_status_led_install(uint8_t gpio_id, uint32_t gpio_name, uint8_t gpio_func); -void wifi_promiscuous_enable(uint8_t promiscuous); +void sdk_wifi_promiscuous_enable(uint8_t promiscuous); -typedef void (* wifi_promiscuous_cb_t)(uint8_t *buf, uint16_t len); +typedef void (* sdk_wifi_promiscuous_cb_t)(uint8_t *buf, uint16_t len); -void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); +void sdk_wifi_set_promiscuous_rx_cb(sdk_wifi_promiscuous_cb_t cb); -enum phy_mode { +enum sdk_phy_mode { PHY_MODE_11B = 1, PHY_MODE_11G = 2, PHY_MODE_11N = 3 }; -enum phy_mode wifi_get_phy_mode(void); -bool wifi_set_phy_mode(enum phy_mode mode); +enum phy_mode sdk_wifi_get_phy_mode(void); +bool sdk_wifi_set_phy_mode(enum sdk_phy_mode mode); #endif diff --git a/include/espressif/sdk_prototypes.h b/include/espressif/sdk_prototypes.h index 2817a72..4b5e3df 100644 --- a/include/espressif/sdk_prototypes.h +++ b/include/espressif/sdk_prototypes.h @@ -1,6 +1,11 @@ -/* This source file contains function prototypes for functions defined +/* sdk_prototypes.h + + This source file contains function prototypes for functions defined in the remaining "binary blob" ESP IoT RTOS SDK libraries. Sorted by which library they appear in. + + Function names here have the 'sdk_' prefix that is put on all binary library functions + by the Open RTOS SDK. */ #ifndef SDK_PROTOTYPES_H #define SDK_PROTOTYPES_H @@ -18,18 +23,28 @@ struct ip_addr; uart_no = 0 or 1 for which UART new_divisor = Calculated in the form UART_CLK_FREQ / BAUD */ -void uart_div_modify(uint32_t uart_no, uint32_t new_divisor); +void sdk_uart_div_modify(uint32_t uart_no, uint32_t new_divisor); + +/* Read a single character from the UART. + */ +char sdk_uart_rx_one_char(void); + +/* Write a single character to the UART. + */ +void sdk_os_putc(char c); /* Called when an IP gets set on the "station" (client) interface. */ -void system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_mask, struct ip_addr *gw_addr); +void sdk_system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_mask, struct ip_addr *gw_addr); /* This is a no-op wrapper around ppRecycleRxPkt, which is defined in libpp.a It's called when a pbuf is freed, and allows pp to reuse the 'eb' pointer to ESP-specific pbuf data. (See esp-lwip pbuf.h) */ -void system_pp_recycle_rx_pkt(void *eb); +void sdk_system_pp_recycle_rx_pkt(void *eb); + +const char* sdk_system_get_sdk_version(void); #endif diff --git a/include/espressif/spi_flash.h b/include/espressif/spi_flash.h index b4761f4..719c045 100644 --- a/include/espressif/spi_flash.h +++ b/include/espressif/spi_flash.h @@ -10,15 +10,15 @@ typedef enum { SPI_FLASH_RESULT_OK, SPI_FLASH_RESULT_ERR, SPI_FLASH_RESULT_TIMEOUT -} SpiFlashOpResult; +} sdk_SpiFlashOpResult; #define SPI_FLASH_SEC_SIZE 4096 -uint32_t spi_flash_get_id(void); -SpiFlashOpResult spi_flash_read_status(uint32_t *status); -SpiFlashOpResult spi_flash_write_status(uint32_t status_value); -SpiFlashOpResult spi_flash_erase_sector(uint16_t sec); -SpiFlashOpResult spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size); -SpiFlashOpResult spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size); +uint32_t sdk_spi_flash_get_id(void); +sdk_SpiFlashOpResult sdk_spi_flash_read_status(uint32_t *status); +sdk_SpiFlashOpResult sdk_spi_flash_write_status(uint32_t status_value); +sdk_SpiFlashOpResult sdk_spi_flash_erase_sector(uint16_t sec); +sdk_SpiFlashOpResult sdk_spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size); +sdk_SpiFlashOpResult sdk_spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size); #endif diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index daeff21..538a6c5 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -1,4 +1,8 @@ -/* This linker script generated from xt-genldscripts.tpp for LSP . */ +/* This linker script generated from xt-genldscripts.tpp for LSP . + + Modified for esp open RTOS, this linker script is no longer the same as the esp_iot_rtos_sdk one. +*/ + /* Linker Script for ld -N */ MEMORY { @@ -19,12 +23,12 @@ PHDRS /* Default entry point: */ -ENTRY(call_user_start) -EXTERN(_DebugExceptionVector) -EXTERN(_DoubleExceptionVector) -EXTERN(_KernelExceptionVector) -EXTERN(_NMIExceptionVector) -EXTERN(_UserExceptionVector) +ENTRY(sdk_call_user_start) +EXTERN(sdk__DebugExceptionVector) +EXTERN(sdk__DoubleExceptionVector) +EXTERN(sdk__KernelExceptionVector) +EXTERN(sdk__NMIExceptionVector) +EXTERN(sdk__UserExceptionVector) PROVIDE(_memmap_vecbase_reset = 0x40000000); /* Various memory-map dependent cache attribute settings: */ _memmap_cacheattr_wb_base = 0x00000110; diff --git a/lib/libhal.a b/lib/libhal.a deleted file mode 100644 index 728a0184b3ed8a0a8a65b929ae8262a74140675d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162888 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 KXFxQ;@;Lw?n+)Xu diff --git a/lib/symbols_norename.txt b/lib/symbols_norename.txt new file mode 100644 index 0000000..8d762b4 --- /dev/null +++ b/lib/symbols_norename.txt @@ -0,0 +1,6 @@ +# this is a stop-gap to avoid renaming some useful libc +# symbols to sdk_xxx +puts +printf +putchar +atoi diff --git a/lwip/esp_interface.c b/lwip/esp_interface.c index 034c1b6..6f37b5a 100644 --- a/lwip/esp_interface.c +++ b/lwip/esp_interface.c @@ -47,7 +47,7 @@ #include "netif/etharp.h" /* declared in libnet80211.a */ -int8_t ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb); +int8_t sdk_ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb); static err_t low_level_output(struct netif *netif, struct pbuf *p) @@ -55,7 +55,7 @@ low_level_output(struct netif *netif, struct pbuf *p) struct pbuf *q; for(q = p; q != NULL; q = q->next) { - ieee80211_output_pbuf(netif, q); + sdk_ieee80211_output_pbuf(netif, q); } LINK_STATS_INC(link.xmit); diff --git a/lwip/include/arch/cc.h b/lwip/include/arch/cc.h index 507409c..fe10d25 100644 --- a/lwip/include/arch/cc.h +++ b/lwip/include/arch/cc.h @@ -35,6 +35,14 @@ /* include ESP SDK prototypes as they're used in some LWIP routines */ #include "espressif/sdk_prototypes.h" +/* ESP8266 SDK Interface + + The lwip-esp stack is designed to be also compatible with other ESP8266 SDKs, + so we can't use our 'sdk_' prefixes there +*/ +#define system_station_got_ip_set sdk_system_station_got_ip_set +#define system_pp_recycle_rx_pkt sdk_system_pp_recycle_rx_pkt + /* Include some files for defining library routines */ #include <stdio.h> /* printf, fflush, FILE */ #include <stdlib.h> /* abort */ diff --git a/lwip/include/arch/sys_arch.h b/lwip/include/arch/sys_arch.h index 3daf87b..ac616c9 100644 --- a/lwip/include/arch/sys_arch.h +++ b/lwip/include/arch/sys_arch.h @@ -37,6 +37,8 @@ #include "queue.h" #include "semphr.h" +/* MBOX primitives */ + #define SYS_MBOX_NULL ( ( xQueueHandle ) NULL ) #define SYS_SEM_NULL ( ( xSemaphoreHandle ) NULL ) #define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE