From d6855818296b769a4f6c2b9fd4a7bffb203d0ddb Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 10 Aug 2015 11:52:26 +1000 Subject: [PATCH 001/105] Syscall hander: Fix a3 save address (SDK doesn't use syscall exception so bug probably never hit?) --- core/exception_vectors.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 9085ca2..43dbd12 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -230,7 +230,7 @@ UserIntExit: UserSyscallHandler: addi sp, sp, -0x10 s32i a2, sp, 0x08 - s32i a2, sp, 0x0c + s32i a3, sp, 0x0c rsr.epc1 a2 addi a3, a2, 0x3 wsr.epc1 a3 From 25e124a612d928e428fe4f98cdc87db9eabfe5bc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 10 Aug 2015 11:53:37 +1000 Subject: [PATCH 002/105] ld: Link memmove into IRAM (used by sprintf, etc.) --- ld/eagle.app.v6.ld | 1 + 1 file changed, 1 insertion(+) diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index ae5c23b..73342e6 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -241,6 +241,7 @@ SECTIONS *libc.a:*memcpy.o(.literal .text .literal.* .text.*) *libc.a:*memset.o(.literal .text .literal.* .text.*) *libc.a:*memcmp.o(.literal .text .literal.* .text.*) + *libc.a:*memmove.o(.literal .text .literal.* .text.*) *libc.a:*rand.o(.literal .text .literal.* .text.*) *libc.a:*bzero.o(.literal .text .literal.* .text.*) *libc.a:*lock.o(.literal .text .literal.* .text.*) From bfd38cd1e2282d37e942efddcbef4d587131c03e Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 10 Aug 2015 11:51:46 +1000 Subject: [PATCH 003/105] Experimental support for storing const strings in SPI flash or IRAM As discussed in #11 Known limitations: - Only supports l8ui/l16ui - Unoptimised load routine - Not called from DoubleExceptionHandler but should be - Doesn't restore state properly when falling through to fatal exception handler --- core/exception_vectors.S | 128 ++++++++++++++++++ examples/experiments/unaligned_load/Makefile | 2 + .../unaligned_load/unaligned_load.c | 117 ++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 examples/experiments/unaligned_load/Makefile create mode 100644 examples/experiments/unaligned_load/unaligned_load.c diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 43dbd12..3b4a559 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -173,12 +173,14 @@ CallNMIExceptionHandler: /* Some UserException causes, see table Table 4–64 in ISA reference */ #define CAUSE_SYSCALL 1 +#define CAUSE_LOADSTORE 3 #define CAUSE_LVL1INT 4 .type CallUserExceptionHandler, @function CallUserExceptionHandler: rsr.exccause a0 beqi a0, CAUSE_SYSCALL, UserSyscallHandler + beqi a0, CAUSE_LOADSTORE, UserLoadStoreExceptionHandler mov a0, sp addi sp, sp, -0x50 s32i a0, sp, 0x10 @@ -242,6 +244,132 @@ UserSyscallHandler: rsr.excsave1 a0 rfe + + .section .bss + .global LoadStoreErrorFlag + .align 4 +LoadStoreErrorFlag: + .long 0 + .long 0 + .long 0 + .long 0 + + .section .data + .align 4 +PRINT_ADDR: + .string "0x%08lx '%c'\r\n" +PRINT_MULTI: + .string "a3=0x%08lx a4=0x%08lx a5=0x%08lx a6=0x%08lx a7=0x%08lx\r\n" + + .text + .section .vecbase.text + .literal_position + .align 4 + .global UserLoadStoreExceptionHandler +/* "Fix" LoadStoreException exceptions thatare l8/l16 from an Instruction region */ +UserLoadStoreExceptionHandler: + addi sp, sp, -0x40 + s32i a2, sp, 0x08 + rsr.excsave1 a2 /* a0 value */ + s32i a2, sp, 0x00 + addi a2, sp, 0x40 + s32i a2, sp, 0x04 /* original sp value */ + s32i a3, sp, 0x0c + s32i a4, sp, 0x10 + s32i a5, sp, 0x14 + s32i a6, sp, 0x18 + s32i a7, sp, 0x1c + s32i a8, sp, 0x20 + s32i a9, sp, 0x24 + s32i a10, sp, 0x28 + s32i a11, sp, 0x2c + s32i a12, sp, 0x30 + s32i a13, sp, 0x34 + s32i a14, sp, 0x38 + s32i a15, sp, 0x3c + + /* Check the top nibble of the faulting address is 4, otherwise + we can't help out here */ + rsr.excvaddr a2 + extui a2, a2, 28, 4 + bnei a2, 0x4, .Lcant_fix + + /* Load the instruction we failed to execute */ + rsr.epc1 a3 + movi a4, ~3 + and a2, a3, a4 + l32i a4, a2, 0 + l32i a5, a2, 4 + ssa8l a3 + src a4, a5, a4 + /* a4 is now the instruction that failed */ + + /* example l8ui instr 040c72 */ + movi a2, 0x00F00F /* l8ui/l16ui opcode mask */ + and a3, a4, a2 + movi a8, 0xFF + movi a5, 0x000002 /* l8ui opcode after masking */ + beq a3, a5, .Lcan_fix + + movi a8, 0xFFFF + movi a5, 0x001002 /* l16ui opcode after masking */ + beq a3, a5, .Lcan_fix + +.Lcant_fix: + /* not an l8ui or an l16ui, or not in the instruction space, so bomb out +TODO: the exception dump will have some wrong values in it */ + movi a2, PRINT_ADDR + movi a3, 0xafafafaf + call0 printf + call0 sdk_user_fatal_exception_handler +.Lcan_fix: + /* verified an 8- or 16-bit read in an instruction address space. + + a4 holds instruction, a8 holds mask + */ + extui a2, a4, 4, 4 /* a2 is destination register 0-15 */ + slli a2, a2, 2 /* a2 is now offset of destination register, relative to stack pointer */ + + rsr.sar a6 + rsr.excvaddr a3 + ssa8l a3 /* sar is the shift to extract a3's byte */ + movi a4, ~3 + and a4, a3, a4 /* a4 is word aligned read address */ + + l32i a5, a4, 0 /* perform the actual read */ + srl a5, a5 + and a5, a5, a8 /* mask off bits we need for an l8/l16 */ + + wsr.sar a6 + + add a6, sp, a2 + s32i a5, a6, 0 /* overwrite correct value on register slot @ stack+a2 */ + + /* Footer*/ + //Increment PC + rsr.epc1 a2 + addi a3, a2, 0x3 + wsr.epc1 a3 + + // Restore registers + l32i a0, sp, 0x00 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + l32i a5, sp, 0x14 + l32i a6, sp, 0x18 + l32i a7, sp, 0x1c + l32i a8, sp, 0x20 + l32i a9, sp, 0x24 + l32i a10, sp, 0x28 + l32i a11, sp, 0x2c + l32i a12, sp, 0x30 + l32i a13, sp, 0x34 + l32i a14, sp, 0x38 + l32i a15, sp, 0x3c + l32i sp, sp, 0x04 + rfe + .global _xt_user_exit .type _xt_user_exit, @function _xt_user_exit: diff --git a/examples/experiments/unaligned_load/Makefile b/examples/experiments/unaligned_load/Makefile new file mode 100644 index 0000000..158bfb3 --- /dev/null +++ b/examples/experiments/unaligned_load/Makefile @@ -0,0 +1,2 @@ +PROGRAM=unaligned_load +include ../../../common.mk diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c new file mode 100644 index 0000000..033c7be --- /dev/null +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -0,0 +1,117 @@ +/* Very basic example that just demonstrates we can run at all! + */ +#include "esp/rom.h" +#include "espressif/esp_common.h" +#include "espressif/sdk_private.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#include "string.h" +#include "strings.h" + +#define TESTSTRING "O hai there! %d %d %d" + +const char *dramtest = TESTSTRING; +const __attribute__((section(".iram1.notrodata"))) char iramtest[] = TESTSTRING; +const __attribute__((section(".text.notrodata"))) char iromtest[] = TESTSTRING; + +INLINED uint32_t get_ccount (void) +{ + uint32_t ccount; + asm volatile ("rsr.ccount %0" : "=a" (ccount)); + return ccount; +} + +typedef void (* test_with_fn_t)(const char *string); + +char buf[64]; + +void test_memcpy_aligned(const char *string) +{ + memcpy(buf, string, 16); +} + +void test_memcpy_unaligned(const char *string) +{ + memcpy(buf, string, 15); +} + +void test_memcpy_unaligned2(const char *string) +{ + memcpy(buf, string+1, 15); +} + +void test_strcpy(const char *string) +{ + strcpy(buf, string); +} + +void test_sprintf(const char *string) +{ + sprintf(buf, string, 1, 2, 3); +} + +void test_sprintf_arg(const char *string) +{ + sprintf(buf, "%s", string); +} + +void test_naive_strcpy(const char *string) +{ + char *to = buf; + while((*to++ = *string++)) + ; +} + +#define TEST_REPEATS 1000 + +void test_noop(const char *string) +{ + +} + +uint32_t IRAM run_test(const char *string, test_with_fn_t testfn, const char *testfn_label, uint32_t nullvalue, bool evict_cache) +{ + printf(" .. against %30s: ", testfn_label); + vPortEnterCritical(); + uint32_t before = get_ccount(); + for(int i = 0; i < TEST_REPEATS; i++) { + testfn(string); + if(evict_cache) { + Cache_Read_Disable(); + Cache_Read_Enable(0,0,1); + } + } + uint32_t after = get_ccount(); + vPortExitCritical(); + uint32_t instructions = (after-before)/TEST_REPEATS - nullvalue; + printf("%5ld instructions\r\n", instructions); + return instructions; +} + +void test_string(const char *string, char *label, bool evict_cache) +{ + printf("Testing %s (%p) '%s'\r\n", label, string, string); + printf("Formats as: '"); + printf(string, 1, 2, 3); + printf("'\r\n"); + uint32_t nullvalue = run_test(string, test_noop, "null op", 0, evict_cache); + run_test(string, test_memcpy_aligned, "memcpy - aligned len", nullvalue, evict_cache); + run_test(string, test_memcpy_unaligned, "memcpy - unaligned len", nullvalue, evict_cache); + run_test(string, test_memcpy_unaligned2, "memcpy - unaligned start&len", nullvalue, evict_cache); + run_test(string, test_strcpy, "strcpy", nullvalue, evict_cache); + run_test(string, test_naive_strcpy, "naive strcpy", nullvalue, evict_cache); + run_test(string, test_sprintf, "sprintf", nullvalue, evict_cache); + run_test(string, test_sprintf_arg, "sprintf format arg", nullvalue, evict_cache); +} + +void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + printf("\r\n\r\nSDK version:%s\r\n", sdk_system_get_sdk_version()); + test_string(dramtest, "DRAM", 0); + test_string(iramtest, "IRAM", 0); + test_string(iromtest, "Cached flash", 0); + test_string(iromtest, "'Uncached' flash", 1); +} From da6b5f74bb066a23a9dcb4cf030cfa4ffc9e5c72 Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Thu, 30 Jul 2015 19:34:13 +0200 Subject: [PATCH 004/105] Mostly updated header files for use in C++ --- axtls/include/version.h | 2 +- common.mk | 17 ++++++++++++----- core/include/common_macros.h | 6 +++++- include/espressif/esp8266/esp8266.h | 8 ++++++++ include/espressif/esp_misc.h | 8 ++++++++ include/espressif/esp_softap.h | 8 ++++++++ include/espressif/esp_sta.h | 8 ++++++++ include/espressif/esp_system.h | 8 ++++++++ include/espressif/esp_timer.h | 8 ++++++++ include/espressif/esp_wifi.h | 10 +++++++++- include/espressif/sdk_private.h | 9 +++++++++ include/espressif/spi_flash.h | 10 ++++++++++ ld/eagle.app.v6.ld | 3 +++ 13 files changed, 97 insertions(+), 8 deletions(-) diff --git a/axtls/include/version.h b/axtls/include/version.h index 43c7194..8fee21b 100644 --- a/axtls/include/version.h +++ b/axtls/include/version.h @@ -5,6 +5,6 @@ #ifndef _VERSION_H -#define AXTLS_VERSION "esp-open-rtos axTLS "GITSHORTREV +#define AXTLS_VERSION "esp-open-rtos axTLS " GITSHORTREV #endif diff --git a/common.mk b/common.mk index 323d13d..199dd0a 100644 --- a/common.mk +++ b/common.mk @@ -94,14 +94,19 @@ OWN_LIBC ?= 1 # Note: you will need a recent esp ENTRY_SYMBOL ?= call_user_start -CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 $(CPPFLAGS) +# Common flags for both C & C++_ +C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals $(CPPFLAGS) +# Flags for C only +CFLAGS = $(C_CXX_FLAGS) -std=gnu99 +# Flags for C++ only +CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS) ifeq ($(FLAVOR),debug) - CFLAGS += -g -O0 + C_CXX_FLAGS += -g -O0 LDFLAGS += -g -O0 else - CFLAGS += -g -O2 + C_CXX_FLAGS += -g -O2 LDFLAGS += -g -O2 endif @@ -138,8 +143,8 @@ endif LINKER_SCRIPTS_PROCESSED = $(addprefix $(LD_DIR),$(LINKER_SCRIPTS)) # derive various parts of compiler/linker arguments -SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS)) -LIB_ARGS = $(addprefix -l,$(LIBS)) +SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS)) +LIB_ARGS = $(addprefix -l,$(LIBS)) PROGRAM_OUT = $(BUILD_DIR)$(PROGRAM).out LDFLAGS += $(addprefix -T,$(LINKER_SCRIPTS_PROCESSED)) @@ -229,7 +234,9 @@ $(1)_MAKEFILE ?= $(lastword $(MAKEFILE_LIST)) ### determine compiler arguments ### $(1)_CFLAGS ?= $(CFLAGS) +$(1)_CXXFLAGS ?= $(CXXFLAGS) $(1)_CC_ARGS = $(Q) $(CC) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CFLAGS) +$(1)_CXX_ARGS = $(Q) $(C++) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CXXFLAGS) $(1)_AR = $(call lc,$(BUILD_DIR)$(1).a) $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR) diff --git a/core/include/common_macros.h b/core/include/common_macros.h index fa13ff9..3afd593 100644 --- a/core/include/common_macros.h +++ b/core/include/common_macros.h @@ -26,7 +26,11 @@ 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.literal"))) const +#ifdef __cplusplus + #define IROM __attribute__((section(".irom0.literal"))) +#else + #define IROM __attribute__((section(".irom0.literal"))) const +#endif #define INLINED inline static __attribute__((always_inline)) __attribute__((unused)) diff --git a/include/espressif/esp8266/esp8266.h b/include/espressif/esp8266/esp8266.h index 2d8b21b..4bf1a7a 100644 --- a/include/espressif/esp8266/esp8266.h +++ b/include/espressif/esp8266/esp8266.h @@ -6,6 +6,10 @@ #ifndef __ESP8266_H__ #define __ESP8266_H__ +#ifdef __cplusplus +extern "C" { +#endif + #include "ets_sys.h" #include "eagle_soc.h" #include "gpio_register.h" @@ -14,5 +18,9 @@ #include "timer_register.h" #include "uart_register.h" +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_misc.h b/include/espressif/esp_misc.h index d8ce65e..6490fa5 100644 --- a/include/espressif/esp_misc.h +++ b/include/espressif/esp_misc.h @@ -8,6 +8,10 @@ #include "lwip/ip_addr.h" +#ifdef __cplusplus +extern "C" { +#endif + #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" @@ -23,4 +27,8 @@ void sdk_os_delay_us(uint16_t us); void sdk_os_install_putc1(void (*p)(char c)); void sdk_os_putc(char c); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_softap.h b/include/espressif/esp_softap.h index 44f06cc..8a81aef 100644 --- a/include/espressif/esp_softap.h +++ b/include/espressif/esp_softap.h @@ -6,6 +6,10 @@ #ifndef __ESP_SOFTAP_H__ #define __ESP_SOFTAP_H__ +#ifdef __cplusplus +extern "C" { +#endif + struct sdk_softap_config { uint8_t ssid[32]; uint8_t password[64]; @@ -20,4 +24,8 @@ struct sdk_softap_config { bool sdk_wifi_softap_get_config(struct sdk_softap_config *config); bool sdk_wifi_softap_set_config(struct sdk_softap_config *config); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_sta.h b/include/espressif/esp_sta.h index 8b9059a..0c94a6c 100644 --- a/include/espressif/esp_sta.h +++ b/include/espressif/esp_sta.h @@ -10,6 +10,10 @@ #include "queue.h" +#ifdef __cplusplus +extern "C" { +#endif + struct sdk_station_config { uint8_t ssid[32]; uint8_t password[64]; @@ -68,4 +72,8 @@ enum { uint8_t sdk_wifi_station_get_connect_status(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_system.h b/include/espressif/esp_system.h index 93eea64..e37263e 100644 --- a/include/espressif/esp_system.h +++ b/include/espressif/esp_system.h @@ -6,6 +6,10 @@ #ifndef __ESP_SYSTEM_H__ #define __ESP_SYSTEM_H__ +#ifdef __cplusplus +extern "C" { +#endif + enum sdk_rst_reason { DEFAULT_RST = 0, WDT_RST = 1, @@ -54,4 +58,8 @@ bool sdk_system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n); void sdk_system_uart_swap(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_timer.h b/include/espressif/esp_timer.h index 6f05547..0ceb131 100644 --- a/include/espressif/esp_timer.h +++ b/include/espressif/esp_timer.h @@ -6,6 +6,10 @@ #ifndef __ESP_TIMER_H__ #define __ESP_TIMER_H__ +#ifdef __cplusplus +extern "C" { +#endif + /* timer related */ typedef void sdk_os_timer_func_t(void *timer_arg); @@ -19,4 +23,8 @@ typedef struct _os_timer_t { void *timer_arg; } sdk_os_timer_t; +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h index e2274f1..c966f3d 100644 --- a/include/espressif/esp_wifi.h +++ b/include/espressif/esp_wifi.h @@ -9,6 +9,10 @@ #ifndef __ESP_WIFI_H__ #define __ESP_WIFI_H__ +#ifdef __cplusplus +extern "C" { +#endif + enum { NULL_MODE = 0, STATION_MODE, @@ -63,7 +67,11 @@ enum sdk_phy_mode { PHY_MODE_11N = 3 }; -enum phy_mode sdk_wifi_get_phy_mode(void); +enum sdk_phy_mode sdk_wifi_get_phy_mode(void); bool sdk_wifi_set_phy_mode(enum sdk_phy_mode mode); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/sdk_private.h b/include/espressif/sdk_private.h index 4340999..fa643a7 100644 --- a/include/espressif/sdk_private.h +++ b/include/espressif/sdk_private.h @@ -15,6 +15,11 @@ #define SDK_PRIVATE_H #include + +#ifdef __cplusplus +extern "C" { +#endif + struct ip_addr; /********************************************* @@ -49,4 +54,8 @@ void sdk_system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_m */ void sdk_system_pp_recycle_rx_pkt(void *eb); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/spi_flash.h b/include/espressif/spi_flash.h index 1805cc7..224bce4 100644 --- a/include/espressif/spi_flash.h +++ b/include/espressif/spi_flash.h @@ -6,6 +6,10 @@ #ifndef __SPI_FLASH_H__ #define __SPI_FLASH_H__ +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { SPI_FLASH_RESULT_OK, SPI_FLASH_RESULT_ERR, @@ -21,6 +25,7 @@ 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); + /* SDK uses this structure internally to account for flash size. chip_size field is initialised during startup from the flash size @@ -42,4 +47,9 @@ typedef struct { extern sdk_flashchip_t sdk_flashchip; + +#ifdef __cplusplus +} +#endif + #endif diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index ae5c23b..1c45f1d 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -166,11 +166,14 @@ SECTIONS *(.gnu.linkonce.e.*) *(.gnu.version_r) *(.eh_frame) + . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ + __init_array_start = ABSOLUTE(.); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) + __init_array_end = ABSOLUTE(.); KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) From 424dc0f3b0bed8e963c2a592517b4c2eb53633cf Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 10 Aug 2015 15:51:57 +1000 Subject: [PATCH 005/105] Add C++ support to Makefile, and proof-of-concept simple.cpp example This is a work in progress based on @mikejac's work. Missing: * No 'new' operator. * I don't think STL is currently supported. --- FreeRTOS/Source/portable/esp8266/port.c | 11 ++++++ common.mk | 14 +++++-- core/sdk_compat.c | 15 +++++++ examples/simple_cplusplus/Makefile | 3 ++ examples/simple_cplusplus/simple.cpp | 52 +++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 examples/simple_cplusplus/Makefile create mode 100644 examples/simple_cplusplus/simple.cpp diff --git a/FreeRTOS/Source/portable/esp8266/port.c b/FreeRTOS/Source/portable/esp8266/port.c index 1632fe1..71c6658 100644 --- a/FreeRTOS/Source/portable/esp8266/port.c +++ b/FreeRTOS/Source/portable/esp8266/port.c @@ -178,6 +178,9 @@ void xPortSysTickHandle (void) //OpenNMI(); } +static bool sdk_compat_initialised; +void sdk_compat_initialise(void); + /* * See header file for description. */ @@ -186,6 +189,14 @@ portBASE_TYPE xPortStartScheduler( void ) _xt_isr_attach(INUM_SOFT, SV_ISR); _xt_isr_unmask(BIT(INUM_SOFT)); + /* ENORMOUS HACK: Call the sdk_compat_initialise() function. + This can be removed happily once we have open source startup code. + */ + if(!sdk_compat_initialised) { + sdk_compat_initialised = true; + sdk_compat_initialise(); + } + /* Initialize system tick timer interrupt and schedule the first tick. */ sdk__xt_tick_timer_init(); diff --git a/common.mk b/common.mk index 199dd0a..4a2bd5b 100644 --- a/common.mk +++ b/common.mk @@ -221,13 +221,15 @@ COMPONENT_ARS = define component_compile_rules $(1)_OBJ_DIR = $(call lc,$(BUILD_DIR)$(1)/) ### determine source files and object files ### -$(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \ - $$(wildcard $$(sdir)/*.c) $$(wildcard $$(sdir)/*.S)) \ +$(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \ + $$(wildcard $$(sdir)/*.c) $$(wildcard $$(sdir)/*.S) \ + $$(wildcard $$(sdir)/*.cpp)) \ $$($(1)_EXTRA_SRC_FILES) $(1)_REAL_SRC_FILES = $$(foreach sfile,$$($(1)_SRC_FILES),$$(realpath $$(sfile))) $(1)_REAL_ROOT = $$(realpath $$($(1)_ROOT)) # patsubst here substitutes real component root path for the relative OBJ_DIR path, making things short again -$(1)_OBJ_FILES_C = $$(patsubst $$($(1)_REAL_ROOT)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_REAL_SRC_FILES)) +$(1)_OBJ_FILES_CXX = $$(patsubst $$($(1)_REAL_ROOT)%.cpp,$$($(1)_OBJ_DIR)%.o,$$($(1)_REAL_SRC_FILES)) +$(1)_OBJ_FILES_C = $$(patsubst $$($(1)_REAL_ROOT)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_CXX)) $(1)_OBJ_FILES = $$(patsubst $$($(1)_REAL_ROOT)%.S,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_C)) # the last included makefile is our component's component.mk makefile (rebuild the component if it changes) $(1)_MAKEFILE ?= $(lastword $(MAKEFILE_LIST)) @@ -245,6 +247,12 @@ $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)* $$($(1)_CC_ARGS) -c $$< -o $$@ $$($(1)_CC_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$< +$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.cpp $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR) + $(vecho) "C++ $$<" + $(Q) mkdir -p $$(dir $$@) + $$($(1)_CXX_ARGS) -c $$< -o $$@ + $$($(1)_CXX_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$< + $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.S $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR) $(vecho) "AS $$<" $(Q) mkdir -p $$(dir $$@) diff --git a/core/sdk_compat.c b/core/sdk_compat.c index d141708..b6bb6b3 100644 --- a/core/sdk_compat.c +++ b/core/sdk_compat.c @@ -14,3 +14,18 @@ void IRAM *zalloc(size_t nbytes) { return calloc(1, nbytes); } + +extern void (*__init_array_start)(void); +extern void (*__init_array_end)(void); + +/* Do things which should be done as part of the startup code, but aren't. + + Can be replaced with _start() once we have open source startup code. +*/ +void sdk_compat_initialise() +{ + /* Call C++ constructors or C functions marked with __attribute__((constructor)) */ + void (**p)(void); + for ( p = &__init_array_start; p != &__init_array_end; ++p) + (*p)(); +} diff --git a/examples/simple_cplusplus/Makefile b/examples/simple_cplusplus/Makefile new file mode 100644 index 0000000..717b163 --- /dev/null +++ b/examples/simple_cplusplus/Makefile @@ -0,0 +1,3 @@ +# Simple makefile for simple example +PROGRAM=simple +include ../../common.mk diff --git a/examples/simple_cplusplus/simple.cpp b/examples/simple_cplusplus/simple.cpp new file mode 100644 index 0000000..dada441 --- /dev/null +++ b/examples/simple_cplusplus/simple.cpp @@ -0,0 +1,52 @@ +/* A very basic C++ example, really just proof of concept for C++ + + This sample code is in the public domain. + */ +#include "espressif/esp_common.h" +#include "espressif/sdk_private.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +class Counter +{ +private: + uint32_t _count; +public: + Counter(uint32_t initial_count) + { + this->_count = initial_count; + printf("Counter initialised with count %ld\r\n", initial_count); + } + + void Increment() + { + _count++; + } + + uint32_t getCount() + { + return _count; + } +}; + +static Counter static_counter(99); + +void task1(void *pvParameters) +{ + Counter local_counter = Counter(12); + while(1) { + Counter &counter = rand() % 2 ? static_counter : local_counter; + counter.Increment(); + printf("local counter %ld static counter %ld\r\n", local_counter.getCount(), + static_counter.getCount()); + vTaskDelay(100); + } +} + +extern "C" void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + xTaskCreate(task1, (signed char *)"tsk1", 256, NULL, 2, NULL); +} From 773a046dc34a77f45c1e5127bdc26c68930eb6bf Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 11 Aug 2015 14:23:41 +1000 Subject: [PATCH 006/105] Unaligned loader: clean up, reduce number of registers --- core/exception_vectors.S | 85 +++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 3b4a559..bfda81e 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -270,10 +270,6 @@ PRINT_MULTI: UserLoadStoreExceptionHandler: addi sp, sp, -0x40 s32i a2, sp, 0x08 - rsr.excsave1 a2 /* a0 value */ - s32i a2, sp, 0x00 - addi a2, sp, 0x40 - s32i a2, sp, 0x04 /* original sp value */ s32i a3, sp, 0x0c s32i a4, sp, 0x10 s32i a5, sp, 0x14 @@ -287,33 +283,24 @@ UserLoadStoreExceptionHandler: s32i a13, sp, 0x34 s32i a14, sp, 0x38 s32i a15, sp, 0x3c - - /* Check the top nibble of the faulting address is 4, otherwise - we can't help out here */ - rsr.excvaddr a2 - extui a2, a2, 28, 4 - bnei a2, 0x4, .Lcant_fix + rsr.sar a0 // save sar in a0 /* Load the instruction we failed to execute */ - rsr.epc1 a3 - movi a4, ~3 - and a2, a3, a4 - l32i a4, a2, 0 - l32i a5, a2, 4 - ssa8l a3 - src a4, a5, a4 - /* a4 is now the instruction that failed */ + rsr.epc1 a2 + ssa8l a2 // sar is now correct shift to read a3 + movi a3, ~3 + and a2, a2, a3 // a2 now 4-byte aligned address of instruction + l32i a3, a2, 0 + l32i a4, a2, 4 + src a2, a4, a3 // a2 now instruction that failed - /* example l8ui instr 040c72 */ - movi a2, 0x00F00F /* l8ui/l16ui opcode mask */ - and a3, a4, a2 - movi a8, 0xFF - movi a5, 0x000002 /* l8ui opcode after masking */ - beq a3, a5, .Lcan_fix + /* Check if a2 matches l8ui or l16ui */ + movi a3, 0x00F00F /* opcode mask */ + and a3, a2, a3 + beqi a3, 0x000002, .Lcan_fix_8bit /* l8ui opcode after masking */ - movi a8, 0xFFFF - movi a5, 0x001002 /* l16ui opcode after masking */ - beq a3, a5, .Lcan_fix + movi a4, 0x001002 /* l16ui opcode after masking */ + beq a3, a4, .Lcan_fix_16bit .Lcant_fix: /* not an l8ui or an l16ui, or not in the instruction space, so bomb out @@ -322,28 +309,36 @@ TODO: the exception dump will have some wrong values in it */ movi a3, 0xafafafaf call0 printf call0 sdk_user_fatal_exception_handler + +.Lcan_fix_16bit: + movi a5, 0xFFFF + j .Lcan_fix +.Lcan_fix_8bit: + movi a5, 0xFF .Lcan_fix: - /* verified an 8- or 16-bit read in an instruction address space. - - a4 holds instruction, a8 holds mask + /* verified an 8- or 16-bit read + a2 holds instruction, a5 holds mask to apply to read value */ - extui a2, a4, 4, 4 /* a2 is destination register 0-15 */ - slli a2, a2, 2 /* a2 is now offset of destination register, relative to stack pointer */ + extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ + slli a2, a2, 2 /* a2 now offset of destination register, relative to stack pointer */ - rsr.sar a6 - rsr.excvaddr a3 - ssa8l a3 /* sar is the shift to extract a3's byte */ + rsr.excvaddr a3 // read faulting address + ssa8l a3 /* sar is now shift to extract a3's byte */ movi a4, ~3 - and a4, a3, a4 /* a4 is word aligned read address */ + and a3, a3, a4 /* a3 now word aligned read address */ - l32i a5, a4, 0 /* perform the actual read */ - srl a5, a5 - and a5, a5, a8 /* mask off bits we need for an l8/l16 */ + /* Sanity check the top nibble of the faulting address is 4, otherwise + we can't help out here */ + extui a4, a3, 28, 4 + bnei a4, 0x4, .Lcant_fix - wsr.sar a6 + l32i a3, a3, 0 /* perform the actual read */ + srl a3, a3 /* shift right correct distance */ + and a3, a3, a5 /* mask off bits we need for an l8/l16 */ - add a6, sp, a2 - s32i a5, a6, 0 /* overwrite correct value on register slot @ stack+a2 */ + /* write read value to register slot */ + add a5, sp, a2 + s32i a3, a5, 0 /* Footer*/ //Increment PC @@ -351,8 +346,10 @@ TODO: the exception dump will have some wrong values in it */ addi a3, a2, 0x3 wsr.epc1 a3 +.Lexit: + wsr.sar a0 // restore saved sar // Restore registers - l32i a0, sp, 0x00 + rsr.excsave1 a0 // restore a0 saved in exception vector l32i a2, sp, 0x08 l32i a3, sp, 0x0c l32i a4, sp, 0x10 @@ -367,7 +364,7 @@ TODO: the exception dump will have some wrong values in it */ l32i a13, sp, 0x34 l32i a14, sp, 0x38 l32i a15, sp, 0x3c - l32i sp, sp, 0x04 + addi sp, sp, 0x40 rfe .global _xt_user_exit From 8ea4ae27e20766362f72b76b65d422296ad7bdcc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 11 Aug 2015 15:03:53 +1000 Subject: [PATCH 007/105] Unaligned loader: Support l16si --- core/exception_vectors.S | 20 +++++++++++++++++-- .../unaligned_load/unaligned_load.c | 12 +++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index bfda81e..eda3389 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -302,6 +302,8 @@ UserLoadStoreExceptionHandler: movi a4, 0x001002 /* l16ui opcode after masking */ beq a3, a4, .Lcan_fix_16bit + movi a4, 0x009002 /* l16si opcode after masking */ + beq a3, a4, .Lcan_fix_16bit_signed .Lcant_fix: /* not an l8ui or an l16ui, or not in the instruction space, so bomb out TODO: the exception dump will have some wrong values in it */ @@ -310,6 +312,9 @@ TODO: the exception dump will have some wrong values in it */ call0 printf call0 sdk_user_fatal_exception_handler +.Lcan_fix_16bit_signed: + movi a5, 0x7FFF + j .Lcan_fix .Lcan_fix_16bit: movi a5, 0xFFFF j .Lcan_fix @@ -334,11 +339,15 @@ TODO: the exception dump will have some wrong values in it */ l32i a3, a3, 0 /* perform the actual read */ srl a3, a3 /* shift right correct distance */ - and a3, a3, a5 /* mask off bits we need for an l8/l16 */ + and a4, a3, a5 /* mask off bits we need for an l8/l16 */ + + bbci a5, 15, .Lextend_sign +.Lafter_extend_sign: + /* a4 holds the correctly read value */ /* write read value to register slot */ add a5, sp, a2 - s32i a3, a5, 0 + s32i a4, a5, 0 /* Footer*/ //Increment PC @@ -367,6 +376,13 @@ TODO: the exception dump will have some wrong values in it */ addi sp, sp, 0x40 rfe +.Lextend_sign: /* apply 16-bit sign extension if necessary + a3 holds raw value, a4 holds masked */ + bbci a3, 15, .Lafter_extend_sign /* sign bit not set, do nothing */ + movi a3, (1<<31) + or a4, a3, a4 /* set sign bit */ + j .Lafter_extend_sign + .global _xt_user_exit .type _xt_user_exit, @function _xt_user_exit: diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index 033c7be..c65a818 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -64,6 +64,17 @@ void test_naive_strcpy(const char *string) ; } +void test_l16si(const char *string) +{ + /* This follows most of the l16si path, but as the + values in the string are all 7 bit none of them get sign extended */ + int16_t *src_int16 = (int16_t *)string; + int32_t *dst_int32 = (int32_t *)buf; + dst_int32[0] = src_int16[0]; + dst_int32[1] = src_int16[1]; + dst_int32[2] = src_int16[2]; +} + #define TEST_REPEATS 1000 void test_noop(const char *string) @@ -104,6 +115,7 @@ void test_string(const char *string, char *label, bool evict_cache) run_test(string, test_naive_strcpy, "naive strcpy", nullvalue, evict_cache); run_test(string, test_sprintf, "sprintf", nullvalue, evict_cache); run_test(string, test_sprintf_arg, "sprintf format arg", nullvalue, evict_cache); + run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache); } void user_init(void) From 3b3f5ea771f6e3aa0ceb2563e84d95c7281c6a89 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 11 Aug 2015 15:29:53 +1000 Subject: [PATCH 008/105] Unaligned loads: Only save working registers, use jump table to load non-working registers --- core/exception_vectors.S | 76 ++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index eda3389..b96f60a 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -273,16 +273,6 @@ UserLoadStoreExceptionHandler: s32i a3, sp, 0x0c s32i a4, sp, 0x10 s32i a5, sp, 0x14 - s32i a6, sp, 0x18 - s32i a7, sp, 0x1c - s32i a8, sp, 0x20 - s32i a9, sp, 0x24 - s32i a10, sp, 0x28 - s32i a11, sp, 0x2c - s32i a12, sp, 0x30 - s32i a13, sp, 0x34 - s32i a14, sp, 0x38 - s32i a15, sp, 0x3c rsr.sar a0 // save sar in a0 /* Load the instruction we failed to execute */ @@ -324,8 +314,6 @@ TODO: the exception dump will have some wrong values in it */ /* verified an 8- or 16-bit read a2 holds instruction, a5 holds mask to apply to read value */ - extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ - slli a2, a2, 2 /* a2 now offset of destination register, relative to stack pointer */ rsr.excvaddr a3 // read faulting address ssa8l a3 /* sar is now shift to extract a3's byte */ @@ -344,11 +332,19 @@ TODO: the exception dump will have some wrong values in it */ bbci a5, 15, .Lextend_sign .Lafter_extend_sign: /* a4 holds the correctly read value */ + extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ - /* write read value to register slot */ + /* test if a4 needs to be written directly to a register (ie not a working register) */ + bgei a2, 6, .Lwrite_value_direct_reg + /* test if a4 needs to be written to a0 */ + beqz a2, .Lwrite_value_a0_reg + + /* otherwise, a4 needs to be written to a saved working register 'slot' on the stack */ + slli a2, a2, 2 add a5, sp, a2 s32i a4, a5, 0 +.Lafter_write_value: /* Footer*/ //Increment PC rsr.epc1 a2 @@ -363,16 +359,6 @@ TODO: the exception dump will have some wrong values in it */ l32i a3, sp, 0x0c l32i a4, sp, 0x10 l32i a5, sp, 0x14 - l32i a6, sp, 0x18 - l32i a7, sp, 0x1c - l32i a8, sp, 0x20 - l32i a9, sp, 0x24 - l32i a10, sp, 0x28 - l32i a11, sp, 0x2c - l32i a12, sp, 0x30 - l32i a13, sp, 0x34 - l32i a14, sp, 0x38 - l32i a15, sp, 0x3c addi sp, sp, 0x40 rfe @@ -383,6 +369,50 @@ TODO: the exception dump will have some wrong values in it */ or a4, a3, a4 /* set sign bit */ j .Lafter_extend_sign +.Lwrite_value_direct_reg: + /* Directly update register index a2, in range 6-15, using value in a4 */ + addi a2, a2, -6 + slli a2, a2, 3 /* offset from a6, x8 */ + movi a3, .Ldirect_reg_jumptable + add a2, a2, a3 + jx a2 + .align 8 +.Ldirect_reg_jumptable: + mov a6, a4 + j .Lafter_write_value + .align 8 + mov a7, a4 + j .Lafter_write_value + .align 8 + mov a8, a4 + j .Lafter_write_value + .align 8 + mov a9, a4 + j .Lafter_write_value + .align 8 + mov a10, a4 + j .Lafter_write_value + .align 8 + mov a11, a4 + j .Lafter_write_value + .align 8 + mov a12, a4 + j .Lafter_write_value + .align 8 + mov a13, a4 + j .Lafter_write_value + .align 8 + mov a14, a4 + j .Lafter_write_value + .align 8 + mov a15, a4 + j .Lafter_write_value + +.Lwrite_value_a0_reg: + /* a0 is saved in excsave1,so just update this with value */ + wsr.excsave1 a4 + j .Lafter_write_value + .global _xt_user_exit .type _xt_user_exit, @function _xt_user_exit: From e3b24df043dc8370d7865604d12644672616b7b6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 11 Aug 2015 16:25:11 +1000 Subject: [PATCH 009/105] Unaligned load: Shave a few more instructions off --- core/exception_vectors.S | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index b96f60a..dcdee1d 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -268,7 +268,7 @@ PRINT_MULTI: .global UserLoadStoreExceptionHandler /* "Fix" LoadStoreException exceptions thatare l8/l16 from an Instruction region */ UserLoadStoreExceptionHandler: - addi sp, sp, -0x40 + addi sp, sp, -0x18 s32i a2, sp, 0x08 s32i a3, sp, 0x0c s32i a4, sp, 0x10 @@ -284,7 +284,7 @@ UserLoadStoreExceptionHandler: l32i a4, a2, 4 src a2, a4, a3 // a2 now instruction that failed - /* Check if a2 matches l8ui or l16ui */ + /* Check if a2 matches l8ui, l16ui or l16si opcodes */ movi a3, 0x00F00F /* opcode mask */ and a3, a2, a3 beqi a3, 0x000002, .Lcan_fix_8bit /* l8ui opcode after masking */ @@ -320,18 +320,17 @@ TODO: the exception dump will have some wrong values in it */ movi a4, ~3 and a3, a3, a4 /* a3 now word aligned read address */ - /* Sanity check the top nibble of the faulting address is 4, otherwise - we can't help out here */ - extui a4, a3, 28, 4 - bnei a4, 0x4, .Lcant_fix - l32i a3, a3, 0 /* perform the actual read */ srl a3, a3 /* shift right correct distance */ and a4, a3, a5 /* mask off bits we need for an l8/l16 */ - bbci a5, 15, .Lextend_sign + bbci a5, 14, .Lafter_extend_sign /* 8-bit, no sign extension */ + bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ + bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ + movi a3, (1<<31) + or a4, a3, a4 /* set 32-bit sign bit */ .Lafter_extend_sign: - /* a4 holds the correctly read value */ + /* a2 holds instruction, a4 holds the correctly read value */ extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ /* test if a4 needs to be written directly to a register (ie not a working register) */ @@ -339,9 +338,8 @@ TODO: the exception dump will have some wrong values in it */ /* test if a4 needs to be written to a0 */ beqz a2, .Lwrite_value_a0_reg - /* otherwise, a4 needs to be written to a saved working register 'slot' on the stack */ - slli a2, a2, 2 - add a5, sp, a2 + /* otherwise, a4 can be written to a saved working register 'slot' on the stack */ + addx4 a5, a2, sp s32i a4, a5, 0 .Lafter_write_value: @@ -359,7 +357,7 @@ TODO: the exception dump will have some wrong values in it */ l32i a3, sp, 0x0c l32i a4, sp, 0x10 l32i a5, sp, 0x14 - addi sp, sp, 0x40 + addi sp, sp, 0x18 rfe .Lextend_sign: /* apply 16-bit sign extension if necessary From 7f338e66cbe66e32c58fa8bd2a1769fcea0b58b6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 11 Aug 2015 16:25:35 +1000 Subject: [PATCH 010/105] Unaligned load: Remove debugging variables --- core/exception_vectors.S | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index dcdee1d..00c511d 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -245,22 +245,6 @@ UserSyscallHandler: rfe - .section .bss - .global LoadStoreErrorFlag - .align 4 -LoadStoreErrorFlag: - .long 0 - .long 0 - .long 0 - .long 0 - - .section .data - .align 4 -PRINT_ADDR: - .string "0x%08lx '%c'\r\n" -PRINT_MULTI: - .string "a3=0x%08lx a4=0x%08lx a5=0x%08lx a6=0x%08lx a7=0x%08lx\r\n" - .text .section .vecbase.text .literal_position @@ -295,11 +279,8 @@ UserLoadStoreExceptionHandler: movi a4, 0x009002 /* l16si opcode after masking */ beq a3, a4, .Lcan_fix_16bit_signed .Lcant_fix: - /* not an l8ui or an l16ui, or not in the instruction space, so bomb out -TODO: the exception dump will have some wrong values in it */ - movi a2, PRINT_ADDR - movi a3, 0xafafafaf - call0 printf + /* not an opcode we can try to fix, so bomb out + TODO: the exception dump will have some wrong values in it */ call0 sdk_user_fatal_exception_handler .Lcan_fix_16bit_signed: From 7d480876fa81e7a0920a00d415e3e1fa92fc801b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 13 Aug 2015 08:32:34 +1000 Subject: [PATCH 011/105] Add basic C++ new/delete operators, as contributed by @mikejac in #24 --- core/cplusplus_operators.cpp | 25 +++++++++++++++++++++++++ examples/simple_cplusplus/simple.cpp | 20 ++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 core/cplusplus_operators.cpp diff --git a/core/cplusplus_operators.cpp b/core/cplusplus_operators.cpp new file mode 100644 index 0000000..86f4477 --- /dev/null +++ b/core/cplusplus_operators.cpp @@ -0,0 +1,25 @@ +/* Part of esp-open-rtos + * BSD Licensed as described in the file LICENSE + */ +#include +#include + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} diff --git a/examples/simple_cplusplus/simple.cpp b/examples/simple_cplusplus/simple.cpp index dada441..8d964fa 100644 --- a/examples/simple_cplusplus/simple.cpp +++ b/examples/simple_cplusplus/simple.cpp @@ -35,11 +35,23 @@ static Counter static_counter(99); void task1(void *pvParameters) { Counter local_counter = Counter(12); + Counter *new_counter = new Counter(24); while(1) { - Counter &counter = rand() % 2 ? static_counter : local_counter; - counter.Increment(); - printf("local counter %ld static counter %ld\r\n", local_counter.getCount(), - static_counter.getCount()); + Counter *counter = NULL; + switch(rand() % 3) { + case 0: + counter = &local_counter; + break; + case 1: + counter = &static_counter; + break; + default: + counter = new_counter; + break; + } + counter->Increment(); + printf("local counter %ld static counter %ld newly allocated counter %ld\r\n", local_counter.getCount(), + static_counter.getCount(), new_counter->getCount()); vTaskDelay(100); } } From 2a939e97b538a8913b0c1d78d8a1b1218c286c1b Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 17:07:06 -0700 Subject: [PATCH 012/105] Remove unnecessary AND for VAL2FIELD macro Added VAL2FIELD_M / SET_FIELD_M for rare cases when there might actually be some need for it. --- core/include/common_macros.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/include/common_macros.h b/core/include/common_macros.h index 669203a..b0c7a08 100644 --- a/core/include/common_macros.h +++ b/core/include/common_macros.h @@ -20,12 +20,21 @@ * and shift) constants. Used primarily with ESP8266 register access. */ -#define VAL2FIELD(fieldname, value) (((value) & fieldname##_M) << fieldname##_S) +#define VAL2FIELD(fieldname, value) ((value) << fieldname##_S) #define FIELD2VAL(fieldname, regbits) (((regbits) >> fieldname##_S) & fieldname##_M) #define FIELD_MASK(fieldname) (fieldname##_M << fieldname##_S) #define SET_FIELD(regbits, fieldname, value) (((regbits) & ~FIELD_MASK(fieldname)) | VAL2FIELD(fieldname, value)) +/* VAL2FIELD/SET_FIELD do not normally check to make sure that the passed value + * will fit in the specified field (without clobbering other bits). This makes + * them faster and is usually fine. If you do need to make sure that the value + * will not overflow the field, use VAL2FIELD_M or SET_FIELD_M (which will + * first mask the supplied value to only the allowed number of bits) instead. + */ +#define VAL2FIELD_M(fieldname, value) (((value) & fieldname##_M) << fieldname##_S) +#define SET_FIELD_M(regbits, fieldname, value) (((regbits) & ~FIELD_MASK(fieldname)) | VAL2FIELD_M(fieldname, value)) + /* Use this macro to store constant values in IROM flash instead of having them loaded into rodata (which resides in DRAM) From e2e841c66081f77079e03fc2a7681ade8678b75f Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 17:13:13 -0700 Subject: [PATCH 013/105] Remove 'packed' attribute from all regs structs --- core/include/esp/dport_regs.h | 2 +- core/include/esp/gpio_regs.h | 2 +- core/include/esp/iomux_regs.h | 2 +- core/include/esp/spi_regs.h | 2 +- core/include/esp/timer_regs.h | 2 +- core/include/esp/uart_regs.h | 2 +- core/include/esp/wdt_regs.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/include/esp/dport_regs.h b/core/include/esp/dport_regs.h index 44a3b5b..df17103 100644 --- a/core/include/esp/dport_regs.h +++ b/core/include/esp/dport_regs.h @@ -45,7 +45,7 @@ struct DPORT_REGS { uint32_t volatile OTP_MAC1; // 0x54 uint32_t volatile OTP_CHIPID; // 0x58 uint32_t volatile OTP_MAC2; // 0x5c -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct DPORT_REGS) == 0x60, "DPORT_REGS is the wrong size"); diff --git a/core/include/esp/gpio_regs.h b/core/include/esp/gpio_regs.h index 21e2c29..3d91efb 100644 --- a/core/include/esp/gpio_regs.h +++ b/core/include/esp/gpio_regs.h @@ -57,7 +57,7 @@ struct GPIO_REGS { uint32_t volatile PWM; // 0x68 uint32_t volatile RTC_CALIB; // 0x6c uint32_t volatile RTC_CALIB_RESULT; // 0x70 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); diff --git a/core/include/esp/iomux_regs.h b/core/include/esp/iomux_regs.h index d3b9653..4ea3be2 100644 --- a/core/include/esp/iomux_regs.h +++ b/core/include/esp/iomux_regs.h @@ -20,7 +20,7 @@ struct IOMUX_REGS { uint32_t volatile CONF; // 0x00 uint32_t volatile PIN[16]; // 0x04 - 0x40 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct IOMUX_REGS) == 0x44, "IOMUX_REGS is the wrong size"); diff --git a/core/include/esp/spi_regs.h b/core/include/esp/spi_regs.h index 7dcf4db..dfcf998 100644 --- a/core/include/esp/spi_regs.h +++ b/core/include/esp/spi_regs.h @@ -67,7 +67,7 @@ struct SPI_REGS { uint32_t volatile EXT1; // 0xf4 uint32_t volatile EXT2; // 0xf8 uint32_t volatile EXT3; // 0xfc -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct SPI_REGS) == 0x100, "SPI_REGS is the wrong size"); diff --git a/core/include/esp/timer_regs.h b/core/include/esp/timer_regs.h index f2aacfc..867d63f 100644 --- a/core/include/esp/timer_regs.h +++ b/core/include/esp/timer_regs.h @@ -36,7 +36,7 @@ struct TIMER_REGS { // FRC1 FRC2 uint32_t volatile CTRL; // 0x08 0x28 uint32_t volatile STATUS; // 0x0c 0x2c uint32_t volatile ALARM; // 0x30 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct TIMER_REGS) == 0x14, "TIMER_REGS is the wrong size"); diff --git a/core/include/esp/uart_regs.h b/core/include/esp/uart_regs.h index fe8e03d..4726823 100644 --- a/core/include/esp/uart_regs.h +++ b/core/include/esp/uart_regs.h @@ -46,7 +46,7 @@ struct UART_REGS { uint32_t volatile _unused[17]; // 0x34 - 0x74 uint32_t volatile DATE; // 0x78 uint32_t volatile ID; // 0x7c -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size"); diff --git a/core/include/esp/wdt_regs.h b/core/include/esp/wdt_regs.h index a9ee063..eb51f57 100644 --- a/core/include/esp/wdt_regs.h +++ b/core/include/esp/wdt_regs.h @@ -27,7 +27,7 @@ struct WDT_REGS { uint32_t volatile REG2; // 0x08 uint32_t volatile _unused[2]; // 0x0c - 0x10 uint32_t volatile FEED; // 0x14 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct WDT_REGS) == 0x18, "WDT_REGS is the wrong size"); From 1282e11c088254a8ab3cfa4b179a35392748d27c Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Wed, 19 Aug 2015 08:38:15 +0200 Subject: [PATCH 014/105] Added C++ base components and example --- common.mk | 4 +- examples/cpp_01_tasks/Makefile | 3 + examples/cpp_01_tasks/main.cpp | 100 +++++++++++++++++++++++++++ extras/cplusplus/component.mk | 3 + extras/cplusplus/cplusplus.hpp | 68 +++++++++++++++++++ extras/thread/component.mk | 3 + extras/thread/mutex.hpp | 90 +++++++++++++++++++++++++ extras/thread/queue.hpp | 120 +++++++++++++++++++++++++++++++++ extras/thread/task.hpp | 99 +++++++++++++++++++++++++++ extras/timer/component.mk | 3 + extras/timer/countdown.hpp | 95 ++++++++++++++++++++++++++ 11 files changed, 586 insertions(+), 2 deletions(-) create mode 100644 examples/cpp_01_tasks/Makefile create mode 100644 examples/cpp_01_tasks/main.cpp create mode 100644 extras/cplusplus/component.mk create mode 100644 extras/cplusplus/cplusplus.hpp create mode 100644 extras/thread/component.mk create mode 100644 extras/thread/mutex.hpp create mode 100644 extras/thread/queue.hpp create mode 100644 extras/thread/task.hpp create mode 100644 extras/timer/component.mk create mode 100644 extras/timer/countdown.hpp diff --git a/common.mk b/common.mk index 4a2bd5b..a73092c 100644 --- a/common.mk +++ b/common.mk @@ -99,7 +99,7 @@ C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-lit # Flags for C only CFLAGS = $(C_CXX_FLAGS) -std=gnu99 # Flags for C++ only -CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions +CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions -fno-rtti LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS) ifeq ($(FLAVOR),debug) @@ -177,7 +177,7 @@ IMGTOOL_ARGS=-$(IMGTOOL_FLASH_SIZE) -$(FLASH_MODE) -$(FLASH_SPEED) # Placing $(PROGRAM_DIR) and $(PROGRAM_DIR)include first allows # programs to have their own copies of header config files for components # , which is useful for overriding things. -INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include +INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include $(ROOT)extras ifeq ($(OWN_LIBC),1) INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include diff --git a/examples/cpp_01_tasks/Makefile b/examples/cpp_01_tasks/Makefile new file mode 100644 index 0000000..458932f --- /dev/null +++ b/examples/cpp_01_tasks/Makefile @@ -0,0 +1,3 @@ +# Simple makefile for simple example +PROGRAM=cpp_01_tasks +include ../../common.mk diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp new file mode 100644 index 0000000..133d1c5 --- /dev/null +++ b/examples/cpp_01_tasks/main.cpp @@ -0,0 +1,100 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#include "cplusplus/cplusplus.hpp" +#include "thread/task.hpp" +#include "thread/queue.hpp" + +#include "espressif/esp_common.h" + +/****************************************************************************************************************** + * task_1_t + * + */ +class task_1_t: public esp_open_rtos::thread::task_t +{ +public: + esp_open_rtos::thread::queue_t queue; + +private: + void task() + { + printf("task_1_t::task(): start\n"); + + uint32_t count = 0; + + while(true) { + sleep(1000); + queue.post(count); + count++; + } + } +}; +/****************************************************************************************************************** + * task_2_t + * + */ +class task_2_t: public esp_open_rtos::thread::task_t +{ +public: + esp_open_rtos::thread::queue_t queue; + +private: + void task() + { + printf("task_2_t::task(): start\n"); + + while(true) { + uint32_t count; + + if(queue.receive(count, 1500) == 0) { + printf("task_2_t::task(): got %lu\n", count); + } + else { + printf("task_2_t::task(): no msg\n"); + } + } + } +}; +/****************************************************************************************************************** + * globals + * + */ +task_1_t task_1; +task_2_t task_2; + +esp_open_rtos::thread::queue_t MyQueue; + +/** + * + */ +extern "C" void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + + MyQueue.create(10); + + task_1.queue = MyQueue; + task_2.queue = MyQueue; + + task_1.task_create("tsk1"); + task_2.task_create("tsk2"); +} \ No newline at end of file diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk new file mode 100644 index 0000000..3f5673d --- /dev/null +++ b/extras/cplusplus/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/cplusplus + +INC_DIRS += $(ROOT)extras diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp new file mode 100644 index 0000000..cc58031 --- /dev/null +++ b/extras/cplusplus/cplusplus.hpp @@ -0,0 +1,68 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP + +#include + +/****************************************************************************************************************** + * C++ new and delete operators + * + */ + +/** + * + * @param size + * @return + */ +inline void *operator new(size_t size) +{ + return malloc(size); +} +/** + * + * @param size + * @return + */ +inline void *operator new[](size_t size) +{ + return malloc(size); +} +/** + * + * @param ptr + */ +inline void operator delete(void * ptr) +{ + free(ptr); +} +/** + * + * @param ptr + */ +inline void operator delete[](void * ptr) +{ + free(ptr); +} + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP */ + diff --git a/extras/thread/component.mk b/extras/thread/component.mk new file mode 100644 index 0000000..46193ef --- /dev/null +++ b/extras/thread/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/thread + +INC_DIRS += $(ROOT)extras diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp new file mode 100644 index 0000000..d3db1da --- /dev/null +++ b/extras/thread/mutex.hpp @@ -0,0 +1,90 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP + +#include "semphr.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * class mutex_t + * + */ +class mutex_t +{ +public: + /** + * + */ + inline mutex_t() + { + mutex = xSemaphoreCreateMutex(); + } + /** + * + */ + inline ~mutex_t() + { + vQueueDelete(mutex); + } + /** + * + * @return + */ + inline int lock() + { + return (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE) ? 0 : -1; + } + /** + * + * @param ms + * @return + */ + inline int try_lock(unsigned long ms) + { + return (xSemaphoreTake(mutex, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @return + */ + inline int unlock() + { + return (xSemaphoreGive(mutex) == pdTRUE) ? 0 : -1; + } + +private: + xSemaphoreHandle mutex; + + // Disable copy construction and assignment. + mutex_t (const mutex_t&); + const mutex_t &operator = (const mutex_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP */ + diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp new file mode 100644 index 0000000..fd14166 --- /dev/null +++ b/extras/thread/queue.hpp @@ -0,0 +1,120 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP + +#include "FreeRTOS.h" +#include "queue.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * class queue_t + * + */ +template +class queue_t +{ +public: + /** + * + */ + inline queue_t() + { + queue = 0; + } + /** + * + * @param uxQueueLength + * @param uxItemSize + * @return + */ + inline int create(unsigned portBASE_TYPE uxQueueLength) + { + queue = xQueueCreate(uxQueueLength, sizeof(Data)); + + if(queue == NULL) { + return -1; + } + else { + return 0; + } + } + /** + * + * @param data + * @param ms + * @return + */ + inline void destroy() + { + vQueueDelete(queue); + queue = 0; + } + /** + * + * @param data + * @param ms + * @return + */ + inline int post(const Data& data, unsigned long ms = 0) + { + return (xQueueSend(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @param data + * @param ms + * @return + */ + inline int receive(Data& data, unsigned long ms = 0) + { + return (xQueueReceive(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @param other + * @return + */ + const queue_t &operator = (const queue_t& other) + { + if(this != &other) { // protect against invalid self-assignment + queue = other.queue; + } + + return *this; + } + +private: + xQueueHandle queue; + + // Disable copy construction. + queue_t (const queue_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP */ + diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp new file mode 100644 index 0000000..dc527f0 --- /dev/null +++ b/extras/thread/task.hpp @@ -0,0 +1,99 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP + +#include "FreeRTOS.h" +#include "task.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * task_t + * + */ +class task_t +{ +public: + /** + * + */ + task_t() + {} + /** + * + * @param pcName + * @param usStackDepth + * @param uxPriority + * @return + */ + int task_create(const char* const pcName, unsigned short usStackDepth = 256, unsigned portBASE_TYPE uxPriority = 2) + { + return xTaskCreate(task_t::_task, (signed char *)pcName, usStackDepth, this, uxPriority, NULL); + } + +protected: + /** + * + * @param ms + */ + void sleep(unsigned long ms) + { + vTaskDelay(ms / portTICK_RATE_MS); + } + /** + * + * @return + */ + inline unsigned long millis() + { + return xTaskGetTickCount() * portTICK_RATE_MS; + } + +private: + /** + * + */ + virtual void task() = 0; + /** + * + * @param pvParameters + */ + static void _task(void* pvParameters) + { + if(pvParameters != 0) { + ((task_t*)(pvParameters))->task(); + } + } + + // no copy and no = operator + task_t(const task_t&); + task_t &operator=(const task_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP */ + diff --git a/extras/timer/component.mk b/extras/timer/component.mk new file mode 100644 index 0000000..255ebae --- /dev/null +++ b/extras/timer/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/timer + +INC_DIRS += $(ROOT)extras diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp new file mode 100644 index 0000000..ff1a2bf --- /dev/null +++ b/extras/timer/countdown.hpp @@ -0,0 +1,95 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP + +#include "FreeRTOS.h" +#include "task.h" + +namespace esp_open_rtos { +namespace timer { + +#define __millis() (xTaskGetTickCount() * portTICK_RATE_MS) + +/****************************************************************************************************************** + * countdown_t + * + */ +class countdown_t +{ +public: + /** + * + */ + countdown_t() + { + interval_end_ms = 0L; + } + /** + * + * @param ms + */ + countdown_t(int ms) + { + countdown_ms(ms); + } + /** + * + * @return + */ + bool expired() + { + return (interval_end_ms > 0L) && (__millis() >= interval_end_ms); + } + /** + * + * @param ms + */ + void countdown_ms(unsigned long ms) + { + interval_end_ms = __millis() + ms; + } + /** + * + * @param seconds + */ + void countdown(int seconds) + { + countdown_ms((unsigned long)seconds * 1000L); + } + /** + * + * @return + */ + int left_ms() + { + return interval_end_ms - __millis(); + } + +private: + portTickType interval_end_ms; +}; + +} // namespace timer { +} // namespace esp_open_rtos { + +#endif From 4f7d1c2393d10d5b068c8450def03471d9e4046c Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Wed, 19 Aug 2015 08:44:41 +0200 Subject: [PATCH 015/105] Header files adjustments --- extras/cplusplus/cplusplus.hpp | 6 +++--- extras/thread/mutex.hpp | 6 +++--- extras/thread/queue.hpp | 6 +++--- extras/thread/task.hpp | 6 +++--- extras/timer/countdown.hpp | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp index cc58031..a78e146 100644 --- a/extras/cplusplus/cplusplus.hpp +++ b/extras/cplusplus/cplusplus.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP +#ifndef ESP_OPEN_RTOS_CPLUSPLUS_HPP +#define ESP_OPEN_RTOS_CPLUSPLUS_HPP #include @@ -64,5 +64,5 @@ inline void operator delete[](void * ptr) free(ptr); } -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP */ +#endif /* ESP_OPEN_RTOS_CPLUSPLUS_HPP */ diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp index d3db1da..b4e56a4 100644 --- a/extras/thread/mutex.hpp +++ b/extras/thread/mutex.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP +#ifndef ESP_OPEN_RTOS_MUTEX_HPP +#define ESP_OPEN_RTOS_MUTEX_HPP #include "semphr.h" @@ -86,5 +86,5 @@ private: } //namespace esp_open_rtos { -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP */ +#endif /* ESP_OPEN_RTOS_MUTEX_HPP */ diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp index fd14166..e02bec6 100644 --- a/extras/thread/queue.hpp +++ b/extras/thread/queue.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP +#ifndef ESP_OPEN_RTOS_QUEUE_HPP +#define ESP_OPEN_RTOS_QUEUE_HPP #include "FreeRTOS.h" #include "queue.h" @@ -116,5 +116,5 @@ private: } //namespace esp_open_rtos { -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP */ +#endif /* ESP_OPEN_RTOS_QUEUE_HPP */ diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp index dc527f0..a8a5c5b 100644 --- a/extras/thread/task.hpp +++ b/extras/thread/task.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP +#ifndef ESP_OPEN_RTOS_TASK_HPP +#define ESP_OPEN_RTOS_TASK_HPP #include "FreeRTOS.h" #include "task.h" @@ -95,5 +95,5 @@ private: } //namespace esp_open_rtos { -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP */ +#endif /* ESP_OPEN_RTOS_TASK_HPP */ diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp index ff1a2bf..71dd55c 100644 --- a/extras/timer/countdown.hpp +++ b/extras/timer/countdown.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP +#ifndef ESP_OPEN_RTOS_TIMER_HPP +#define ESP_OPEN_RTOS_TIMER_HPP #include "FreeRTOS.h" #include "task.h" From 6bc95994b70d3b2d1ddd9a657366cda7af4f0c6a Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Thu, 20 Aug 2015 10:04:59 +0200 Subject: [PATCH 016/105] Updated license --- examples/cpp_01_tasks/main.cpp | 31 +++++++++++++++++++------------ extras/cplusplus/cplusplus.hpp | 33 ++++++++++++++++++++------------- extras/thread/mutex.hpp | 31 +++++++++++++++++++------------ extras/thread/queue.hpp | 31 +++++++++++++++++++------------ extras/thread/task.hpp | 31 +++++++++++++++++++------------ extras/timer/countdown.hpp | 31 +++++++++++++++++++------------ 6 files changed, 115 insertions(+), 73 deletions(-) diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 133d1c5..0b9fe1f 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp index a78e146..bf006a8 100644 --- a/extras/cplusplus/cplusplus.hpp +++ b/extras/cplusplus/cplusplus.hpp @@ -1,24 +1,31 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ - + #ifndef ESP_OPEN_RTOS_CPLUSPLUS_HPP #define ESP_OPEN_RTOS_CPLUSPLUS_HPP diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp index b4e56a4..714c585 100644 --- a/extras/thread/mutex.hpp +++ b/extras/thread/mutex.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp index e02bec6..a24f302 100644 --- a/extras/thread/queue.hpp +++ b/extras/thread/queue.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp index a8a5c5b..cb1cb45 100644 --- a/extras/thread/task.hpp +++ b/extras/thread/task.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp index 71dd55c..87c8f3f 100644 --- a/extras/timer/countdown.hpp +++ b/extras/timer/countdown.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ From 94a953d3e34bb2c9afcc5b7e42ccd4eef3098860 Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Fri, 21 Aug 2015 08:30:52 +0200 Subject: [PATCH 017/105] Header files re-arrangement --- common.mk | 2 +- examples/cpp_01_tasks/Makefile | 2 ++ examples/cpp_01_tasks/main.cpp | 6 +++--- extras/cpp_support/component.mk | 8 ++++++++ extras/{timer => cpp_support/include}/countdown.hpp | 0 extras/{cplusplus => cpp_support/include}/cplusplus.hpp | 0 extras/{thread => cpp_support/include}/mutex.hpp | 0 extras/{thread => cpp_support/include}/queue.hpp | 0 extras/{thread => cpp_support/include}/task.hpp | 0 9 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 extras/cpp_support/component.mk rename extras/{timer => cpp_support/include}/countdown.hpp (100%) rename extras/{cplusplus => cpp_support/include}/cplusplus.hpp (100%) rename extras/{thread => cpp_support/include}/mutex.hpp (100%) rename extras/{thread => cpp_support/include}/queue.hpp (100%) rename extras/{thread => cpp_support/include}/task.hpp (100%) diff --git a/common.mk b/common.mk index a73092c..342bae2 100644 --- a/common.mk +++ b/common.mk @@ -177,7 +177,7 @@ IMGTOOL_ARGS=-$(IMGTOOL_FLASH_SIZE) -$(FLASH_MODE) -$(FLASH_SPEED) # Placing $(PROGRAM_DIR) and $(PROGRAM_DIR)include first allows # programs to have their own copies of header config files for components # , which is useful for overriding things. -INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include $(ROOT)extras +INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include ifeq ($(OWN_LIBC),1) INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include diff --git a/examples/cpp_01_tasks/Makefile b/examples/cpp_01_tasks/Makefile index 458932f..f9254cf 100644 --- a/examples/cpp_01_tasks/Makefile +++ b/examples/cpp_01_tasks/Makefile @@ -1,3 +1,5 @@ # Simple makefile for simple example PROGRAM=cpp_01_tasks +OTA=0 +EXTRA_COMPONENTS=extras/cpp_support include ../../common.mk diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 0b9fe1f..219be74 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -26,9 +26,9 @@ * */ -#include "cplusplus/cplusplus.hpp" -#include "thread/task.hpp" -#include "thread/queue.hpp" +#include "cplusplus.hpp" +#include "task.hpp" +#include "queue.hpp" #include "espressif/esp_common.h" diff --git a/extras/cpp_support/component.mk b/extras/cpp_support/component.mk new file mode 100644 index 0000000..6bc4ada --- /dev/null +++ b/extras/cpp_support/component.mk @@ -0,0 +1,8 @@ +# Component makefile for extras/cpp_support +INC_DIRS += $(ROOT)extras/cpp_support/include + +# args for passing into compile rule generation +# extras/mqtt-client_INC_DIR = $(ROOT)extras/mqtt-client +# extras/mqtt-client_SRC_DIR = $(ROOT)extras/mqtt-client + +# $(eval $(call component_compile_rules,extras/mqtt-client)) diff --git a/extras/timer/countdown.hpp b/extras/cpp_support/include/countdown.hpp similarity index 100% rename from extras/timer/countdown.hpp rename to extras/cpp_support/include/countdown.hpp diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cpp_support/include/cplusplus.hpp similarity index 100% rename from extras/cplusplus/cplusplus.hpp rename to extras/cpp_support/include/cplusplus.hpp diff --git a/extras/thread/mutex.hpp b/extras/cpp_support/include/mutex.hpp similarity index 100% rename from extras/thread/mutex.hpp rename to extras/cpp_support/include/mutex.hpp diff --git a/extras/thread/queue.hpp b/extras/cpp_support/include/queue.hpp similarity index 100% rename from extras/thread/queue.hpp rename to extras/cpp_support/include/queue.hpp diff --git a/extras/thread/task.hpp b/extras/cpp_support/include/task.hpp similarity index 100% rename from extras/thread/task.hpp rename to extras/cpp_support/include/task.hpp From 5c1ce0a508971179f457ab9c0f4b67609282a9d8 Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Sun, 23 Aug 2015 10:21:42 +0200 Subject: [PATCH 018/105] Header files adjustment (MQTT changes split from original commit - @projectgus.) --- examples/cpp_01_tasks/main.cpp | 4 ++-- extras/cpp_support/include/mutex.hpp | 20 ++++++++++++++++++-- extras/cpp_support/include/queue.hpp | 7 ++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 219be74..1295327 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -95,9 +95,9 @@ esp_open_rtos::thread::queue_t MyQueue; */ extern "C" void user_init(void) { - sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); - MyQueue.create(10); + MyQueue.queue_create(10); task_1.queue = MyQueue; task_2.queue = MyQueue; diff --git a/extras/cpp_support/include/mutex.hpp b/extras/cpp_support/include/mutex.hpp index 714c585..aaf29db 100644 --- a/extras/cpp_support/include/mutex.hpp +++ b/extras/cpp_support/include/mutex.hpp @@ -46,14 +46,30 @@ public: */ inline mutex_t() { - mutex = xSemaphoreCreateMutex(); + mutex = 0; + } + /** + * + * @return + */ + inline int mutex_create() + { + mutex = xSemaphoreCreateMutex(); + + if(mutex == NULL) { + return -1; + } + else { + return 0; + } } /** * */ - inline ~mutex_t() + inline void mutex_destroy() { vQueueDelete(mutex); + mutex = 0; } /** * diff --git a/extras/cpp_support/include/queue.hpp b/extras/cpp_support/include/queue.hpp index a24f302..047ce29 100644 --- a/extras/cpp_support/include/queue.hpp +++ b/extras/cpp_support/include/queue.hpp @@ -56,7 +56,7 @@ public: * @param uxItemSize * @return */ - inline int create(unsigned portBASE_TYPE uxQueueLength) + inline int queue_create(unsigned portBASE_TYPE uxQueueLength) { queue = xQueueCreate(uxQueueLength, sizeof(Data)); @@ -69,11 +69,8 @@ public: } /** * - * @param data - * @param ms - * @return */ - inline void destroy() + inline void queue_destroy() { vQueueDelete(queue); queue = 0; From e9b1df5cb5615dcaba9bcf0a36b1343b20a3cba4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 10:36:40 +1000 Subject: [PATCH 019/105] Post-merge cleanup of extras/cpp_support --- core/cplusplus_operators.cpp | 25 ------------------- examples/cpp_01_tasks/main.cpp | 4 +-- extras/cplusplus/component.mk | 3 --- .../{cplusplus.hpp => cpp_operators.hpp} | 0 4 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 core/cplusplus_operators.cpp delete mode 100644 extras/cplusplus/component.mk rename extras/cpp_support/include/{cplusplus.hpp => cpp_operators.hpp} (100%) diff --git a/core/cplusplus_operators.cpp b/core/cplusplus_operators.cpp deleted file mode 100644 index 86f4477..0000000 --- a/core/cplusplus_operators.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* Part of esp-open-rtos - * BSD Licensed as described in the file LICENSE - */ -#include -#include - -void *operator new(size_t size) -{ - return malloc(size); -} - -void *operator new[](size_t size) -{ - return malloc(size); -} - -void operator delete(void * ptr) -{ - free(ptr); -} - -void operator delete[](void * ptr) -{ - free(ptr); -} diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 1295327..cf751d6 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -26,7 +26,7 @@ * */ -#include "cplusplus.hpp" +#include "cpp_operators.hpp" #include "task.hpp" #include "queue.hpp" @@ -104,4 +104,4 @@ extern "C" void user_init(void) task_1.task_create("tsk1"); task_2.task_create("tsk2"); -} \ No newline at end of file +} diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk deleted file mode 100644 index 3f5673d..0000000 --- a/extras/cplusplus/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -# Component makefile for extras/cplusplus - -INC_DIRS += $(ROOT)extras diff --git a/extras/cpp_support/include/cplusplus.hpp b/extras/cpp_support/include/cpp_operators.hpp similarity index 100% rename from extras/cpp_support/include/cplusplus.hpp rename to extras/cpp_support/include/cpp_operators.hpp From c565e2b90d091ec80ef4620dd668407e951edea6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 10:49:00 +1000 Subject: [PATCH 020/105] gpio.h: Explicit cast to enum type (needed for g++) --- core/include/esp/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/esp/gpio.h b/core/include/esp/gpio.h index 1f1ce14..679fff2 100644 --- a/core/include/esp/gpio.h +++ b/core/include/esp/gpio.h @@ -124,7 +124,7 @@ INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int /* Return the interrupt type set for a pin */ INLINED gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num) { - return FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]); + return (gpio_inttype_t)FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]); } #endif From 43ecec547062b09e70339476388ce01f6e97c827 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:07:06 +1000 Subject: [PATCH 021/105] Move c++ operators back to link-time resolutions, part of 'core' This reverts commit e9b1df5cb5615dcaba9bcf0a36b1343b20a3cba4. --- core/cplusplus_operators.cpp | 25 +++++++ examples/cpp_01_tasks/main.cpp | 3 +- extras/cplusplus/component.mk | 3 + extras/cpp_support/include/cpp_operators.hpp | 75 -------------------- 4 files changed, 29 insertions(+), 77 deletions(-) create mode 100644 core/cplusplus_operators.cpp create mode 100644 extras/cplusplus/component.mk delete mode 100644 extras/cpp_support/include/cpp_operators.hpp diff --git a/core/cplusplus_operators.cpp b/core/cplusplus_operators.cpp new file mode 100644 index 0000000..86f4477 --- /dev/null +++ b/core/cplusplus_operators.cpp @@ -0,0 +1,25 @@ +/* Part of esp-open-rtos + * BSD Licensed as described in the file LICENSE + */ +#include +#include + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index cf751d6..160a0c8 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -26,7 +26,6 @@ * */ -#include "cpp_operators.hpp" #include "task.hpp" #include "queue.hpp" @@ -104,4 +103,4 @@ extern "C" void user_init(void) task_1.task_create("tsk1"); task_2.task_create("tsk2"); -} +} \ No newline at end of file diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk new file mode 100644 index 0000000..3f5673d --- /dev/null +++ b/extras/cplusplus/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/cplusplus + +INC_DIRS += $(ROOT)extras diff --git a/extras/cpp_support/include/cpp_operators.hpp b/extras/cpp_support/include/cpp_operators.hpp deleted file mode 100644 index bf006a8..0000000 --- a/extras/cpp_support/include/cpp_operators.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * The MIT License (MIT) - * - * ESP8266 FreeRTOS Firmware - * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * https://github.com/SuperHouse/esp-open-rtos - * - */ - -#ifndef ESP_OPEN_RTOS_CPLUSPLUS_HPP -#define ESP_OPEN_RTOS_CPLUSPLUS_HPP - -#include - -/****************************************************************************************************************** - * C++ new and delete operators - * - */ - -/** - * - * @param size - * @return - */ -inline void *operator new(size_t size) -{ - return malloc(size); -} -/** - * - * @param size - * @return - */ -inline void *operator new[](size_t size) -{ - return malloc(size); -} -/** - * - * @param ptr - */ -inline void operator delete(void * ptr) -{ - free(ptr); -} -/** - * - * @param ptr - */ -inline void operator delete[](void * ptr) -{ - free(ptr); -} - -#endif /* ESP_OPEN_RTOS_CPLUSPLUS_HPP */ - From c824bcf74a1781df0225cb811fc27fe7b2f99beb Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:11:31 +1000 Subject: [PATCH 022/105] common_macros: Include sys/cdefs.h, defines _Static_assert among others --- core/include/common_macros.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/include/common_macros.h b/core/include/common_macros.h index 2b4d73b..7ef2e60 100644 --- a/core/include/common_macros.h +++ b/core/include/common_macros.h @@ -10,6 +10,8 @@ #ifndef _COMMON_MACROS_H #define _COMMON_MACROS_H +#include + #define UNUSED __attributed((unused)) #ifndef BIT From 778b94cf404b7ed52272a6023da18f426cd57408 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:14:34 +1000 Subject: [PATCH 023/105] examples/Makefile: Use MAKE to properly invoke make recursively --- examples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 0436a13..2f816e5 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -22,10 +22,10 @@ build-examples: $(EXAMPLES_BUILD) rebuild-examples: $(EXAMPLES_REBUILD) %.dummybuild: - make -C $(dir $@) + $(MAKE) -C $(dir $@) %.dummyrebuild: - make -C $(dir $@) rebuild + $(MAKE) -C $(dir $@) rebuild .PHONY: warning rebuild-examples build-examples .NOTPARALLEL: From 18d1bb21f796d9a92362a7310105c2dc88030996 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:16:58 +1000 Subject: [PATCH 024/105] Remove stray extras/cplusplus --- extras/cplusplus/component.mk | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 extras/cplusplus/component.mk diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk deleted file mode 100644 index 3f5673d..0000000 --- a/extras/cplusplus/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -# Component makefile for extras/cplusplus - -INC_DIRS += $(ROOT)extras From da48a6b0dfedaa9bfcf430118b9b7d434c4facd2 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 17:13:13 -0700 Subject: [PATCH 025/105] Remove 'packed' attribute from all regs structs --- core/include/esp/dport_regs.h | 2 +- core/include/esp/gpio_regs.h | 2 +- core/include/esp/iomux_regs.h | 2 +- core/include/esp/spi_regs.h | 2 +- core/include/esp/timer_regs.h | 2 +- core/include/esp/uart_regs.h | 2 +- core/include/esp/wdt_regs.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/include/esp/dport_regs.h b/core/include/esp/dport_regs.h index 44a3b5b..df17103 100644 --- a/core/include/esp/dport_regs.h +++ b/core/include/esp/dport_regs.h @@ -45,7 +45,7 @@ struct DPORT_REGS { uint32_t volatile OTP_MAC1; // 0x54 uint32_t volatile OTP_CHIPID; // 0x58 uint32_t volatile OTP_MAC2; // 0x5c -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct DPORT_REGS) == 0x60, "DPORT_REGS is the wrong size"); diff --git a/core/include/esp/gpio_regs.h b/core/include/esp/gpio_regs.h index 21e2c29..3d91efb 100644 --- a/core/include/esp/gpio_regs.h +++ b/core/include/esp/gpio_regs.h @@ -57,7 +57,7 @@ struct GPIO_REGS { uint32_t volatile PWM; // 0x68 uint32_t volatile RTC_CALIB; // 0x6c uint32_t volatile RTC_CALIB_RESULT; // 0x70 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); diff --git a/core/include/esp/iomux_regs.h b/core/include/esp/iomux_regs.h index d3b9653..4ea3be2 100644 --- a/core/include/esp/iomux_regs.h +++ b/core/include/esp/iomux_regs.h @@ -20,7 +20,7 @@ struct IOMUX_REGS { uint32_t volatile CONF; // 0x00 uint32_t volatile PIN[16]; // 0x04 - 0x40 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct IOMUX_REGS) == 0x44, "IOMUX_REGS is the wrong size"); diff --git a/core/include/esp/spi_regs.h b/core/include/esp/spi_regs.h index 7dcf4db..dfcf998 100644 --- a/core/include/esp/spi_regs.h +++ b/core/include/esp/spi_regs.h @@ -67,7 +67,7 @@ struct SPI_REGS { uint32_t volatile EXT1; // 0xf4 uint32_t volatile EXT2; // 0xf8 uint32_t volatile EXT3; // 0xfc -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct SPI_REGS) == 0x100, "SPI_REGS is the wrong size"); diff --git a/core/include/esp/timer_regs.h b/core/include/esp/timer_regs.h index f2aacfc..867d63f 100644 --- a/core/include/esp/timer_regs.h +++ b/core/include/esp/timer_regs.h @@ -36,7 +36,7 @@ struct TIMER_REGS { // FRC1 FRC2 uint32_t volatile CTRL; // 0x08 0x28 uint32_t volatile STATUS; // 0x0c 0x2c uint32_t volatile ALARM; // 0x30 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct TIMER_REGS) == 0x14, "TIMER_REGS is the wrong size"); diff --git a/core/include/esp/uart_regs.h b/core/include/esp/uart_regs.h index fe8e03d..4726823 100644 --- a/core/include/esp/uart_regs.h +++ b/core/include/esp/uart_regs.h @@ -46,7 +46,7 @@ struct UART_REGS { uint32_t volatile _unused[17]; // 0x34 - 0x74 uint32_t volatile DATE; // 0x78 uint32_t volatile ID; // 0x7c -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size"); diff --git a/core/include/esp/wdt_regs.h b/core/include/esp/wdt_regs.h index a9ee063..eb51f57 100644 --- a/core/include/esp/wdt_regs.h +++ b/core/include/esp/wdt_regs.h @@ -27,7 +27,7 @@ struct WDT_REGS { uint32_t volatile REG2; // 0x08 uint32_t volatile _unused[2]; // 0x0c - 0x10 uint32_t volatile FEED; // 0x14 -} __attribute__ (( packed )); +}; _Static_assert(sizeof(struct WDT_REGS) == 0x18, "WDT_REGS is the wrong size"); From b0206d0ca638fd80f3bae755d97bb3453adfb093 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 22:31:47 -0700 Subject: [PATCH 026/105] Fix broken UART(i) definition --- core/include/esp/uart_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/esp/uart_regs.h b/core/include/esp/uart_regs.h index 4726823..671754d 100644 --- a/core/include/esp/uart_regs.h +++ b/core/include/esp/uart_regs.h @@ -24,7 +24,7 @@ */ #define UART_BASE 0x60000000 -#define UART(i) (*(struct UART_REGS *)(0x60000200 - (i)*0xf00)) +#define UART(i) (*(struct UART_REGS *)(UART_BASE + (i)*0xf00)) #define UART0_BASE UART_BASE #define UART1_BASE (UART_BASE + 0xf00) From c30f48c3b1c83ce5d4d00c8e1af13f5c27880d25 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Thu, 27 Aug 2015 13:54:30 -0700 Subject: [PATCH 027/105] Fix linker script handling of irom/irom0 segments --- ld/eagle.app.v6.ld | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index ae5c23b..abf7c2c 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -267,8 +267,8 @@ SECTIONS (except for libgcc which is matched above.) */ *(.literal .text .literal.* .text.*) - /* SDK libraries expect ICACHE_FLASH_ATTR/etc functions to be loaded explicitly as IROM */ - *sdklib*:*(.irom.* .irom.*.* .irom0.*) + /* Anything explicitly marked as "irom" or "irom0" should go here */ + *(.irom.* .irom.*.* .irom0.*) _irom0_text_end = ABSOLUTE(.); } >irom0_0_seg :irom0_0_phdr From 8b8f7c9de4c7685869f2ecd58c91f7ad6d69274f Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 09:31:02 -0700 Subject: [PATCH 028/105] Use fixed symbol rename list To keep things from changing out from under us as we slowly replace bits of the SDK libs, changing Makefiles to not auto-generate the list of symbols to rename, but always use the same list every time. --- common.mk | 22 +- lib/allsymbols.rename | 839 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 842 insertions(+), 19 deletions(-) create mode 100644 lib/allsymbols.rename diff --git a/common.mk b/common.mk index 323d13d..e05e78e 100644 --- a/common.mk +++ b/common.mk @@ -280,25 +280,9 @@ $(BUILD_DIR)sdklib/%_stage1.a: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/%.remove | $(BU $(Q) cat $< > $@ $(Q) $(AR) d $@ @$(word 2,$^) -# Generate a regex to match symbols we don't want to rename, listed in -# symbols_norename.txt -$(BUILD_DIR)sdklib/norename.match: $(ROOT)lib/symbols_norename.txt | $(BUILD_DIR)sdklib - cat $< | grep -v "^#" | sed ':begin;$!N;s/\n/\\|/;tbegin' > $@ - -# Stage 2: Build a list of defined symbols per library, renamed with sdk_ prefix -$(BUILD_DIR)sdklib/%.rename: $(BUILD_DIR)sdklib/%_stage1.a $(BUILD_DIR)sdklib/norename.match - @echo "SDK processing stage 2: Building symbol list for $< -> $@" - $(Q) $(OBJDUMP) -t $< | grep ' g ' \ - | sed -r 's/^.+ ([^ ]+)$$/\1 sdk_\1/' \ - | grep -v `cat $(BUILD_DIR)sdklib/norename.match` > $@ - -# Build a master list of all SDK-defined symbols to rename across all libraries -$(BUILD_DIR)sdklib/allsymbols.rename: $(patsubst %.a,%.rename,$(SDK_PROCESSED_LIBS)) - cat $^ > $@ - -# Stage 3: Redefine all SDK symbols as sdk_, weaken all symbols. -$(BUILD_DIR)sdklib/%.a: $(BUILD_DIR)sdklib/%_stage1.a $(BUILD_DIR)sdklib/allsymbols.rename - @echo "SDK processing stage 3: Renaming symbols in SDK library $< -> $@" +# Stage 2: Redefine all SDK symbols as sdk_, weaken all symbols. +$(BUILD_DIR)sdklib/%.a: $(BUILD_DIR)sdklib/%_stage1.a $(ROOT)lib/allsymbols.rename + @echo "SDK processing stage 2: Renaming symbols in SDK library $< -> $@" $(Q) $(OBJCOPY) --redefine-syms $(word 2,$^) --weaken $< $@ # include "dummy component" for the 'program' object files, defined in the Makefile diff --git a/lib/allsymbols.rename b/lib/allsymbols.rename new file mode 100644 index 0000000..2f455f0 --- /dev/null +++ b/lib/allsymbols.rename @@ -0,0 +1,839 @@ +aes_decrypt_deinit sdk_aes_decrypt_deinit +aes_decrypt_init sdk_aes_decrypt_init +aes_decrypt sdk_aes_decrypt +aes_encrypt_deinit sdk_aes_encrypt_deinit +aes_encrypt_init sdk_aes_encrypt_init +aes_encrypt sdk_aes_encrypt +aes_unwrap sdk_aes_unwrap +aes_wrap sdk_aes_wrap +ant_switch_init sdk_ant_switch_init +auth_type sdk_auth_type +bb_init sdk_bb_init +bbpll_cal_flag sdk_bbpll_cal_flag +bbpll_cal sdk_bbpll_cal +cal_rf_ana_gain sdk_cal_rf_ana_gain +cannel_scan_connect_state sdk_cannel_scan_connect_state +ccmp sdk_ccmp +change_bbpll160 sdk_change_bbpll160 +change_bbpll160_sleep sdk_change_bbpll160_sleep +check_data_flag sdk_check_data_flag +check_data_func sdk_check_data_func +check_result sdk_check_result +chip_60_set_channel sdk_chip_60_set_channel +chip6_phy_init_ctrl sdk_chip6_phy_init_ctrl +chip6_sleep_params sdk_chip6_sleep_params +chip_v6_get_sense sdk_chip_v6_get_sense +chip_v6_initialize_bb sdk_chip_v6_initialize_bb +chip_v6_rf_init sdk_chip_v6_rf_init +chip_v6_rxmax_ext_ana sdk_chip_v6_rxmax_ext_ana +chip_v6_rxmax_ext_dig sdk_chip_v6_rxmax_ext_dig +chip_v6_rxmax_ext sdk_chip_v6_rxmax_ext +chip_v6_set_chanfreq sdk_chip_v6_set_chanfreq +chip_v6_set_chan_misc sdk_chip_v6_set_chan_misc +chip_v6_set_chan_offset sdk_chip_v6_set_chan_offset +chip_v6_set_chan_rx_cmp sdk_chip_v6_set_chan_rx_cmp +chip_v6_set_chan sdk_chip_v6_set_chan +chip_v6_set_chan_wakeup sdk_chip_v6_set_chan_wakeup +chip_v6_set_sense sdk_chip_v6_set_sense +chip_v6_unset_chanfreq sdk_chip_v6_unset_chanfreq +chip_version sdk_chip_version +chm_acquire_lock sdk_chm_acquire_lock +chm_cancel_op sdk_chm_cancel_op +chm_check_same_channel sdk_chm_check_same_channel +chm_end_op sdk_chm_end_op +chm_freq2index sdk_chm_freq2index +chm_get_current_channel sdk_chm_get_current_channel +chm_init sdk_chm_init +chm_release_lock sdk_chm_release_lock +chm_return_home_channel sdk_chm_return_home_channel +chm_set_current_channel sdk_chm_set_current_channel +chm_start_op sdk_chm_start_op +clockgate_watchdog sdk_clockgate_watchdog +cnx_add_rc sdk_cnx_add_rc +cnx_attach sdk_cnx_attach +cnx_bss_alloc sdk_cnx_bss_alloc +cnx_connect_timeout sdk_cnx_connect_timeout +cnx_node_alloc sdk_cnx_node_alloc +cnx_node_join sdk_cnx_node_join +cnx_node_leave sdk_cnx_node_leave +cnx_node_remove sdk_cnx_node_remove +cnx_node_search sdk_cnx_node_search +cnx_rc_search sdk_cnx_rc_search +cnx_rc_update_age sdk_cnx_rc_update_age +cnx_rc_update_rssi sdk_cnx_rc_update_rssi +cnx_rc_update_state_metric sdk_cnx_rc_update_state_metric +cnx_remove_rc sdk_cnx_remove_rc +cnx_sta_associated sdk_cnx_sta_associated +cnx_sta_connect_cmd sdk_cnx_sta_connect_cmd +cnx_sta_connect_led_timer_cb sdk_cnx_sta_connect_led_timer_cb +cnx_sta_leave sdk_cnx_sta_leave +cnx_start_handoff_cb sdk_cnx_start_handoff_cb +cnx_sta_scan_cmd sdk_cnx_sta_scan_cmd +cnx_update_bss_more sdk_cnx_update_bss_more +cnx_update_bss sdk_cnx_update_bss +correct_rf_ana_gain sdk_correct_rf_ana_gain +cpu_overclock sdk_cpu_overclock +data_collect sdk_data_collect +dbg_stop_hw_wdt sdk_dbg_stop_hw_wdt +dbg_stop_sw_wdt sdk_dbg_stop_sw_wdt +dcoindex2txbbgain sdk_dcoindex2txbbgain +debug_timerfn sdk_debug_timerfn +debug_timer sdk_debug_timer +deep_sleep_en sdk_deep_sleep_en +dhcp_bind_check sdk_dhcp_bind_check +dhcpc_flag sdk_dhcpc_flag +do_noisefloor_lsleep_v50 sdk_do_noisefloor_lsleep_v50 +do_noisefloor sdk_do_noisefloor +do_pwctrl_flag sdk_do_pwctrl_flag +dpd_db2linear sdk_dpd_db2linear +dpd_index sdk_dpd_index +dpd_init sdk_dpd_init +dpd_mem_write sdk_dpd_mem_write +dpd_scale_set sdk_dpd_scale_set +eagle_auth_done sdk_eagle_auth_done +eapol_txcb sdk_eapol_txcb +eloop_cancel_timeout sdk_eloop_cancel_timeout +eloop_register_timeout sdk_eloop_register_timeout +esf_buf_alloc sdk_esf_buf_alloc +esf_buf_recycle sdk_esf_buf_recycle +esf_buf_setup sdk_esf_buf_setup +esf_rx_buf_alloc sdk_esf_rx_buf_alloc +ets_delay_us sdk_ets_delay_us +ets_timer_arm_ms_us sdk_ets_timer_arm_ms_us +ets_timer_arm sdk_ets_timer_arm +ets_timer_arm_us sdk_ets_timer_arm_us +ets_timer_disarm sdk_ets_timer_disarm +ets_timer_done sdk_ets_timer_done +ets_timer_handler_isr sdk_ets_timer_handler_isr +ets_timer_init sdk_ets_timer_init +ets_timer_setfn sdk_ets_timer_setfn +ets_update_cpu_frequency sdk_ets_update_cpu_frequency +flashchip sdk_flashchip +g_cnx_probe_rc_list_cb sdk_g_cnx_probe_rc_list_cb +gen_rx_gain_table sdk_gen_rx_gain_table +GetAccess sdk_GetAccess +get_check_flag sdk_get_check_flag +get_chip_version sdk_get_chip_version +get_fcc_1m2m_pwr_offset sdk_get_fcc_1m2m_pwr_offset +get_noisefloor_sat sdk_get_noisefloor_sat +get_pwctrl_correct sdk_get_pwctrl_correct +get_rf_gain_qdb sdk_get_rf_gain_qdb +get_sar_dout sdk_get_sar_dout +get_target_power_offset sdk_get_target_power_offset +g_ic sdk_g_ic +g_phyFuns_instance sdk_g_phyFuns_instance +g_phyFuns sdk_g_phyFuns +gpio_output_set sdk_gpio_output_set +gScanStruct sdk_gScanStruct +hardware_reject sdk_hardware_reject +hex2byte sdk_hex2byte +hexstr2bin sdk_hexstr2bin +hmac_md5 sdk_hmac_md5 +hmac_md5_vector sdk_hmac_md5_vector +hmac_sha1 sdk_hmac_sha1 +hmac_sha1_vector sdk_hmac_sha1_vector +hostapd_config_defaults_bss sdk_hostapd_config_defaults_bss +hostapd_config_defaults sdk_hostapd_config_defaults +hostapd_get_psk sdk_hostapd_get_psk +hostapd_mac_comp_empty sdk_hostapd_mac_comp_empty +hostapd_mac_comp sdk_hostapd_mac_comp +hostapd_maclist_found sdk_hostapd_maclist_found +hostapd_rate_found sdk_hostapd_rate_found +hostapd_setup_wpa_psk sdk_hostapd_setup_wpa_psk +hostapd_wep_key_cmp sdk_hostapd_wep_key_cmp +hostap_handle_timer sdk_hostap_handle_timer +hostap_input sdk_hostap_input +ic_bss_info_update sdk_ic_bss_info_update +ic_disable_interface sdk_ic_disable_interface +ic_enable_interface sdk_ic_enable_interface +ic_get_addr sdk_ic_get_addr +ic_get_gtk_alg sdk_ic_get_gtk_alg +ic_get_ptk_alg sdk_ic_get_ptk_alg +ic_interface_enabled sdk_ic_interface_enabled +ic_interface_is_p2p sdk_ic_interface_is_p2p +ic_is_pure_sta sdk_ic_is_pure_sta +ic_remove_key sdk_ic_remove_key +ic_set_gtk_alg sdk_ic_set_gtk_alg +ic_set_key sdk_ic_set_key +ic_set_opmode sdk_ic_set_opmode +ic_set_ptk_alg sdk_ic_set_ptk_alg +ic_set_sta sdk_ic_set_sta +ic_set_vif sdk_ic_set_vif +ieee80211_addbasicrates sdk_ieee80211_addbasicrates +ieee80211_add_htcap sdk_ieee80211_add_htcap +ieee80211_add_htcap_vendor sdk_ieee80211_add_htcap_vendor +ieee80211_add_htinfo sdk_ieee80211_add_htinfo +ieee80211_add_htinfo_vendor sdk_ieee80211_add_htinfo_vendor +ieee80211_add_rates sdk_ieee80211_add_rates +ieee80211_addr_bcast sdk_ieee80211_addr_bcast +ieee80211_add_xrates sdk_ieee80211_add_xrates +ieee80211_alloc_challenge sdk_ieee80211_alloc_challenge +ieee80211_alloc_proberesp sdk_ieee80211_alloc_proberesp +ieee80211_beacon_alloc sdk_ieee80211_beacon_alloc +ieee80211_chan2ieee sdk_ieee80211_chan2ieee +ieee80211_compute_duration sdk_ieee80211_compute_duration +ieee80211_crypto_attach sdk_ieee80211_crypto_attach +ieee80211_crypto_available sdk_ieee80211_crypto_available +ieee80211_crypto_decap sdk_ieee80211_crypto_decap +ieee80211_crypto_encap sdk_ieee80211_crypto_encap +ieee80211_crypto_setkey sdk_ieee80211_crypto_setkey +ieee80211_decap sdk_ieee80211_decap +ieee80211_deliver_data sdk_ieee80211_deliver_data +ieee80211_dot11Rate_rix sdk_ieee80211_dot11Rate_rix +ieee80211_find_channel_byieee sdk_ieee80211_find_channel_byieee +ieee80211_find_channel sdk_ieee80211_find_channel +ieee80211_get_11g_ratetable sdk_ieee80211_get_11g_ratetable +ieee80211_getcapinfo sdk_ieee80211_getcapinfo +ieee80211_getmgtframe sdk_ieee80211_getmgtframe +ieee80211_get_ratetable sdk_ieee80211_get_ratetable +ieee80211_hostap_attach sdk_ieee80211_hostap_attach +ieee80211_ht_attach sdk_ieee80211_ht_attach +ieee80211_ht_node_cleanup sdk_ieee80211_ht_node_cleanup +ieee80211_ht_node_init sdk_ieee80211_ht_node_init +ieee80211_ht_updateparams sdk_ieee80211_ht_updateparams +ieee80211_ieee2mhz sdk_ieee80211_ieee2mhz +ieee80211_ifattach sdk_ieee80211_ifattach +ieee80211_iserp_rateset sdk_ieee80211_iserp_rateset +ieee80211_mgmt_output sdk_ieee80211_mgmt_output +ieee80211_mhz2ieee sdk_ieee80211_mhz2ieee +ieee80211_mlme_connect_bss sdk_ieee80211_mlme_connect_bss +ieee80211_node_pwrsave sdk_ieee80211_node_pwrsave +ieee80211_opcap sdk_ieee80211_opcap +ieee80211_output_pbuf sdk_ieee80211_output_pbuf +ieee80211_parse_action sdk_ieee80211_parse_action +ieee80211_parse_beacon sdk_ieee80211_parse_beacon +ieee80211_parse_htcap sdk_ieee80211_parse_htcap +ieee80211_parse_rsn sdk_ieee80211_parse_rsn +ieee80211_parse_wmeparams sdk_ieee80211_parse_wmeparams +ieee80211_parse_wpa sdk_ieee80211_parse_wpa +ieee80211_phy_init sdk_ieee80211_phy_init +ieee80211_phy_type_get sdk_ieee80211_phy_type_get +ieee80211_proto_attach sdk_ieee80211_proto_attach +ieee80211_psq_cleanup sdk_ieee80211_psq_cleanup +ieee80211_psq_init sdk_ieee80211_psq_init +ieee80211_pwrsave sdk_ieee80211_pwrsave +ieee80211_recv_action_register sdk_ieee80211_recv_action_register +ieee80211_recv_action sdk_ieee80211_recv_action +ieee80211_recv_action_unregister sdk_ieee80211_recv_action_unregister +ieee80211_scan_attach sdk_ieee80211_scan_attach +ieee80211_send_action_register sdk_ieee80211_send_action_register +ieee80211_send_action sdk_ieee80211_send_action +ieee80211_send_action_unregister sdk_ieee80211_send_action_unregister +ieee80211_send_mgmt sdk_ieee80211_send_mgmt +ieee80211_send_nulldata sdk_ieee80211_send_nulldata +ieee80211_send_probereq sdk_ieee80211_send_probereq +ieee80211_send_proberesp sdk_ieee80211_send_proberesp +ieee80211_send_setup sdk_ieee80211_send_setup +ieee80211_setbasicrates sdk_ieee80211_setbasicrates +ieee80211_set_shortslottime sdk_ieee80211_set_shortslottime +ieee80211_set_tim sdk_ieee80211_set_tim +ieee80211_setup_basic_htrates sdk_ieee80211_setup_basic_htrates +ieee80211_setup_htrates sdk_ieee80211_setup_htrates +ieee80211_setup_rateset sdk_ieee80211_setup_rateset +ieee80211_setup_rates sdk_ieee80211_setup_rates +ieee80211_setup_ratetable sdk_ieee80211_setup_ratetable +ieee80211_sta_new_state sdk_ieee80211_sta_new_state +ieee80211_tx_mgt_cb sdk_ieee80211_tx_mgt_cb +ieee80211_wme_initparams sdk_ieee80211_wme_initparams +ieee80211_wme_updateparams sdk_ieee80211_wme_updateparams +ieee802_1x_receive sdk_ieee802_1x_receive +if_ctrl sdk_if_ctrl +inc_byte_array sdk_inc_byte_array +info sdk_info +init_cal_dcoffset sdk_init_cal_dcoffset +interface_mask sdk_interface_mask +lmacConfMib sdk_lmacConfMib +lmacDiscardAgedMSDU sdk_lmacDiscardAgedMSDU +lmacInitAc sdk_lmacInitAc +lmacInit sdk_lmacInit +lmacIsActive sdk_lmacIsActive +lmacIsIdle sdk_lmacIsIdle +lmacMSDUAged sdk_lmacMSDUAged +lmacProcessAckTimeout sdk_lmacProcessAckTimeout +lmacProcessCollision sdk_lmacProcessCollision +lmacProcessCollisions sdk_lmacProcessCollisions +lmacProcessCtsTimeout sdk_lmacProcessCtsTimeout +lmacProcessRtsStart sdk_lmacProcessRtsStart +lmacProcessTxError sdk_lmacProcessTxError +lmacProcessTxRtsError sdk_lmacProcessTxRtsError +lmacProcessTXStartData sdk_lmacProcessTXStartData +lmacProcessTxSuccess sdk_lmacProcessTxSuccess +lmacRecycleMPDU sdk_lmacRecycleMPDU +lmacRxDone sdk_lmacRxDone +lmacSetAcParam sdk_lmacSetAcParam +lmacTxFrame sdk_lmacTxFrame +loop_pwctrl_correct_atten_high_power sdk_loop_pwctrl_correct_atten_high_power +loop_pwctrl_pwdet_error_accum_high_power sdk_loop_pwctrl_pwdet_error_accum_high_power +low_power_set sdk_low_power_set +MacIsrSigPostDefHdl sdk_MacIsrSigPostDefHdl +MD5Final sdk_MD5Final +MD5Init sdk_MD5Init +MD5Update sdk_MD5Update +md5_vector sdk_md5_vector +meas_tone_pwr_db sdk_meas_tone_pwr_db +NMIIrqIsOn sdk_NMIIrqIsOn +noise_array sdk_noise_array +noise_check_loop sdk_noise_check_loop +noise_init sdk_noise_init +NoiseTimerInterval sdk_NoiseTimerInterval +operation_test sdk_operation_test +os_delay_us sdk_os_delay_us +os_get_cpu_frequency sdk_os_get_cpu_frequency +os_get_time sdk_os_get_time +os_install_putc1 sdk_os_install_putc1 +os_putc sdk_os_putc +os_timer_arm sdk_os_timer_arm +os_timer_disarm sdk_os_timer_disarm +os_timer_setfn sdk_os_timer_setfn +os_update_cpu_frequency sdk_os_update_cpu_frequency +pbkdf2_sha1 sdk_pbkdf2_sha1 +pbus_set_rxbbgain sdk_pbus_set_rxbbgain +pend_flag_noise_check sdk_pend_flag_noise_check +pend_flag_periodic_cal sdk_pend_flag_periodic_cal +PendFreeBcnEb sdk_PendFreeBcnEb +periodic_cal_dc_num sdk_periodic_cal_dc_num +periodic_cal_flag sdk_periodic_cal_flag +periodic_cal_sat sdk_periodic_cal_sat +periodic_cal sdk_periodic_cal +periodic_cal_top sdk_periodic_cal_top +phy_bb_rx_cfg sdk_phy_bb_rx_cfg +phy_change_channel sdk_phy_change_channel +phy_delete_channel sdk_phy_delete_channel +phy_dig_spur_prot sdk_phy_dig_spur_prot +phy_dig_spur_set sdk_phy_dig_spur_set +phy_disable_agc sdk_phy_disable_agc +phy_enable_agc sdk_phy_enable_agc +phy_freq_offset sdk_phy_freq_offset +phy_get_mactime sdk_phy_get_mactime +phy_get_romfuncs sdk_phy_get_romfuncs +phy_gpio_cfg sdk_phy_gpio_cfg +phy_initialize_bb sdk_phy_initialize_bb +phy_init sdk_phy_init +phy_pbus_soc_cfg sdk_phy_pbus_soc_cfg +phy_set_sense sdk_phy_set_sense +pm_allow_tx sdk_pm_allow_tx +pm_assoc_parse sdk_pm_assoc_parse +pm_attach sdk_pm_attach +pm_check_mac_idle sdk_pm_check_mac_idle +pm_enable_gpio_wakeup sdk_pm_enable_gpio_wakeup +pm_force_scan_unlock sdk_pm_force_scan_unlock +pm_get_idle_wait_time sdk_pm_get_idle_wait_time +pm_get_sleep_type sdk_pm_get_sleep_type +pm_goto_sleep sdk_pm_goto_sleep +pm_idle_sleep sdk_pm_idle_sleep +pm_is_open sdk_pm_is_open +pm_is_waked sdk_pm_is_waked +pm_onBcnRx sdk_pm_onBcnRx +pm_open_rf sdk_pm_open_rf +pm_open sdk_pm_open +pm_post sdk_pm_post +pm_prepare_to_sleep sdk_pm_prepare_to_sleep +pm_reset_idle_sleep sdk_pm_reset_idle_sleep +pm_rf_is_closed sdk_pm_rf_is_closed +pm_rtc2usec sdk_pm_rtc2usec +pm_rtc_clock_cali_proc sdk_pm_rtc_clock_cali_proc +pm_rtc_clock_cali sdk_pm_rtc_clock_cali +pm_scan_lock sdk_pm_scan_lock +pm_scan_unlocked sdk_pm_scan_unlocked +pm_sdio_nidle sdk_pm_sdio_nidle +pm_send_nullfunc sdk_pm_send_nullfunc +pm_set_addr sdk_pm_set_addr +pm_set_pll_xtal_wait_time sdk_pm_set_pll_xtal_wait_time +pm_set_sleep_btco sdk_pm_set_sleep_btco +pm_set_sleep_cycles sdk_pm_set_sleep_cycles +pm_set_sleep_mode sdk_pm_set_sleep_mode +pm_set_sleep_time sdk_pm_set_sleep_time +pm_set_sleep_type_from_upper sdk_pm_set_sleep_type_from_upper +pm_set_wakeup_btco sdk_pm_set_wakeup_btco +pm_set_wakeup_mac sdk_pm_set_wakeup_mac +pm_shutdown sdk_pm_shutdown +pm_sleep_for sdk_pm_sleep_for +pm_sleep_opt_bb_off sdk_pm_sleep_opt_bb_off +pm_sleep_opt_bb_on sdk_pm_sleep_opt_bb_on +pm_sleep_opt sdk_pm_sleep_opt +pm_sleep_set_mac sdk_pm_sleep_set_mac +pm_suspend sdk_pm_suspend +pm_try_scan_unlock sdk_pm_try_scan_unlock +pm_unmask_bt sdk_pm_unmask_bt +pm_usec2rtc sdk_pm_usec2rtc +pm_wait4wakeup sdk_pm_wait4wakeup +pm_wakeup_init sdk_pm_wakeup_init +pm_wakeup_opt sdk_pm_wakeup_opt +pp_attach sdk_pp_attach +ppCalFrameTimes sdk_ppCalFrameTimes +ppCalTxop sdk_ppCalTxop +ppCheckTxIdle sdk_ppCheckTxIdle +ppDequeueTxQ sdk_ppDequeueTxQ +pp_disable_idle_timer sdk_pp_disable_idle_timer +pp_disable_noise_timer sdk_pp_disable_noise_timer +ppDiscardMPDU sdk_ppDiscardMPDU +pp_enable_idle_timer sdk_pp_enable_idle_timer +pp_enable_noise_timer sdk_pp_enable_noise_timer +ppEnqueueRxq sdk_ppEnqueueRxq +ppEnqueueTxDone sdk_ppEnqueueTxDone +ppFetchTxQFirstAvail sdk_ppFetchTxQFirstAvail +ppGetTxQFirstAvail_Locked sdk_ppGetTxQFirstAvail_Locked +ppInstallKey sdk_ppInstallKey +pp_michael_mic_failure sdk_pp_michael_mic_failure +pp_noise_test sdk_pp_noise_test +ppPeocessRxPktHdr sdk_ppPeocessRxPktHdr +pp_post sdk_pp_post +ppProcessTxQ sdk_ppProcessTxQ +ppProcessWaitQ sdk_ppProcessWaitQ +ppRecordBarRRC sdk_ppRecordBarRRC +ppRecycleRxPkt sdk_ppRecycleRxPkt +ppRegisterTxCallback sdk_ppRegisterTxCallback +ppRollBackTxQ sdk_ppRollBackTxQ +pp_soft_wdt_feed sdk_pp_soft_wdt_feed +pp_soft_wdt_init sdk_pp_soft_wdt_init +ppTask sdk_ppTask +pp_try_enable_idle_timer sdk_pp_try_enable_idle_timer +ppTxPkt sdk_ppTxPkt +ppTxqUpdateBitmap sdk_ppTxqUpdateBitmap +PPWdtReset sdk_PPWdtReset +promiscuous_cb sdk_promiscuous_cb +_putc1 sdk__putc1 +pwctrl_debug sdk_pwctrl_debug +ram_cal_tos_v60 sdk_ram_cal_tos_v60 +ram_chip_v6_rx_init sdk_ram_chip_v6_rx_init +ram_get_bb_atten sdk_ram_get_bb_atten +ram_get_corr_power sdk_ram_get_corr_power +ram_get_fm_sar_dout sdk_ram_get_fm_sar_dout +ram_get_noisefloor sdk_ram_get_noisefloor +ram_pbus_debugmode sdk_ram_pbus_debugmode +ram_pbus_set_rxgain sdk_ram_pbus_set_rxgain +ram_pbus_xpd_tx_on sdk_ram_pbus_xpd_tx_on +ram_restart_cal sdk_ram_restart_cal +ram_rfcal_pwrctrl sdk_ram_rfcal_pwrctrl +ram_rfcal_rxiq sdk_ram_rfcal_rxiq +ram_rfcal_txcap sdk_ram_rfcal_txcap +ram_rfcal_txiq sdk_ram_rfcal_txiq +ram_rfpll_set_freq sdk_ram_rfpll_set_freq +ram_rxiq_cover_mg_mp sdk_ram_rxiq_cover_mg_mp +ram_rxiq_get_mis sdk_ram_rxiq_get_mis +ram_set_channel_freq sdk_ram_set_channel_freq +ram_set_noise_floor sdk_ram_set_noise_floor +ram_set_txbb_atten sdk_ram_set_txbb_atten +ram_start_noisefloor sdk_ram_start_noisefloor +ram_tx_mac_disable sdk_ram_tx_mac_disable +ram_tx_mac_enable sdk_ram_tx_mac_enable +rc4_skip sdk_rc4_skip +rcAttach sdk_rcAttach +rc_cal sdk_rc_cal +rc_disable_trc_by_interface sdk_rc_disable_trc_by_interface +rc_disable_trc sdk_rc_disable_trc +rc_enable_trc sdk_rc_enable_trc +RC_GetAckRate sdk_RC_GetAckRate +RC_GetAckTime sdk_RC_GetAckTime +RC_GetBlockAckTime sdk_RC_GetBlockAckTime +RC_GetCtsTime sdk_RC_GetCtsTime +rc_get_mask sdk_rc_get_mask +rcGetRate sdk_rcGetRate +RC_GetRtsRate sdk_RC_GetRtsRate +rcGetSched sdk_rcGetSched +rc_get_sta_trc sdk_rc_get_sta_trc +rc_get_trc_by_index sdk_rc_get_trc_by_index +rc_get_trc sdk_rc_get_trc +rcGetTrc sdk_rcGetTrc +rc_only_sta_trc sdk_rc_only_sta_trc +rcons sdk_rcons +rcReachRetryLimit sdk_rcReachRetryLimit +RC_SetBasicRate sdk_RC_SetBasicRate +rcUpdateDataRxDone sdk_rcUpdateDataRxDone +rcUpdatePhyMode sdk_rcUpdatePhyMode +rcUpdateRxDone sdk_rcUpdateRxDone +rcUpdateTxDone sdk_rcUpdateTxDone +read_hw_noisefloor sdk_read_hw_noisefloor +read_sar_dout sdk_read_sar_dout +readvdd33 sdk_readvdd33 +register_chipv6_phy_init_param sdk_register_chipv6_phy_init_param +register_chipv6_phy sdk_register_chipv6_phy +register_phy_ops sdk_register_phy_ops +reset_noise_timer sdk_reset_noise_timer +RFChannelSel sdk_RFChannelSel +rf_init sdk_rf_init +rijndaelEncrypt sdk_rijndaelEncrypt +rijndaelKeySetupDec sdk_rijndaelKeySetupDec +rijndaelKeySetupEnc sdk_rijndaelKeySetupEnc +rom_abs_temp sdk_rom_abs_temp +rom_ana_inf_gating_en sdk_rom_ana_inf_gating_en +rom_cal_tos_v50 sdk_rom_cal_tos_v50 +rom_chip_50_set_channel sdk_rom_chip_50_set_channel +rom_chip_v5_disable_cca sdk_rom_chip_v5_disable_cca +rom_chip_v5_enable_cca sdk_rom_chip_v5_enable_cca +rom_chip_v5_rx_init sdk_rom_chip_v5_rx_init +rom_chip_v5_sense_backoff sdk_rom_chip_v5_sense_backoff +rom_chip_v5_tx_init sdk_rom_chip_v5_tx_init +rom_dc_iq_est sdk_rom_dc_iq_est +rom_en_pwdet sdk_rom_en_pwdet +rom_get_bb_atten sdk_rom_get_bb_atten +rom_get_corr_power sdk_rom_get_corr_power +rom_get_fm_sar_dout sdk_rom_get_fm_sar_dout +rom_get_noisefloor sdk_rom_get_noisefloor +rom_get_power_db sdk_rom_get_power_db +rom_i2c_readReg_Mask sdk_rom_i2c_readReg_Mask +rom_i2c_readReg sdk_rom_i2c_readReg +rom_i2c_writeReg_Mask sdk_rom_i2c_writeReg_Mask +rom_i2c_writeReg sdk_rom_i2c_writeReg +rom_iq_est_disable sdk_rom_iq_est_disable +rom_iq_est_enable sdk_rom_iq_est_enable +rom_linear_to_db sdk_rom_linear_to_db +rom_mhz2ieee sdk_rom_mhz2ieee +rom_pbus_dco___SA2 sdk_rom_pbus_dco___SA2 +rom_pbus_debugmode sdk_rom_pbus_debugmode +rom_pbus_enter_debugmode sdk_rom_pbus_enter_debugmode +rom_pbus_exit_debugmode sdk_rom_pbus_exit_debugmode +rom_pbus_force_test sdk_rom_pbus_force_test +rom_pbus_rd sdk_rom_pbus_rd +rom_pbus_set_rxgain sdk_rom_pbus_set_rxgain +rom_pbus_set_txgain sdk_rom_pbus_set_txgain +rom_pbus_workmode sdk_rom_pbus_workmode +rom_pbus_xpd_rx_off sdk_rom_pbus_xpd_rx_off +rom_pbus_xpd_rx_on sdk_rom_pbus_xpd_rx_on +rom_pbus_xpd_tx_off sdk_rom_pbus_xpd_tx_off +rom_pbus_xpd_tx_on__low_gain sdk_rom_pbus_xpd_tx_on__low_gain +rom_pbus_xpd_tx_on sdk_rom_pbus_xpd_tx_on +rom_phy_reset_req sdk_rom_phy_reset_req +rom_restart_cal sdk_rom_restart_cal +rom_rfcal_pwrctrl sdk_rom_rfcal_pwrctrl +rom_rfcal_rxiq sdk_rom_rfcal_rxiq +rom_rfcal_rxiq_set_reg sdk_rom_rfcal_rxiq_set_reg +rom_rfcal_txcap sdk_rom_rfcal_txcap +rom_rfcal_txiq_cover sdk_rom_rfcal_txiq_cover +rom_rfcal_txiq sdk_rom_rfcal_txiq +rom_rfcal_txiq_set_reg sdk_rom_rfcal_txiq_set_reg +rom_rfpll_reset sdk_rom_rfpll_reset +rom_rfpll_set_freq sdk_rom_rfpll_set_freq +rom_rxiq_cover_mg_mp sdk_rom_rxiq_cover_mg_mp +rom_rxiq_get_mis sdk_rom_rxiq_get_mis +rom_sar_init sdk_rom_sar_init +rom_set_ana_inf_tx_scale sdk_rom_set_ana_inf_tx_scale +rom_set_channel_freq sdk_rom_set_channel_freq +rom_set_loopback_gain sdk_rom_set_loopback_gain +rom_set_noise_floor sdk_rom_set_noise_floor +rom_set_rxclk_en sdk_rom_set_rxclk_en +rom_set_txbb_atten sdk_rom_set_txbb_atten +rom_set_txclk_en sdk_rom_set_txclk_en +rom_set_txiq_cal sdk_rom_set_txiq_cal +rom_start_noisefloor sdk_rom_start_noisefloor +rom_start_tx_tone sdk_rom_start_tx_tone +rom_stop_tx_tone sdk_rom_stop_tx_tone +rom_tx_mac_disable sdk_rom_tx_mac_disable +rom_tx_mac_enable sdk_rom_tx_mac_enable +rom_txtone_linear_pwr sdk_rom_txtone_linear_pwr +rom_write_rfpll_sdm sdk_rom_write_rfpll_sdm +rsn_cipher_put_suites sdk_rsn_cipher_put_suites +rsn_pmkid sdk_rsn_pmkid +rst_if sdk_rst_if +rtc_get_reset_reason sdk_rtc_get_reset_reason +rtc_mem_backup sdk_rtc_mem_backup +rtc_mem_recovery sdk_rtc_mem_recovery +rxdc_init_flag sdk_rxdc_init_flag +rx_gain_swp sdk_rx_gain_swp +rxiq_compute_num sdk_rxiq_compute_num +rxiq_cover_fail_num sdk_rxiq_cover_fail_num +RxNodeNum sdk_RxNodeNum +scan_add_bssid sdk_scan_add_bssid +scan_add_probe_ssid sdk_scan_add_probe_ssid +scan_cancel sdk_scan_cancel +scan_check_hidden sdk_scan_check_hidden +scan_clear_channles sdk_scan_clear_channles +scan_connect_state sdk_scan_connect_state +scan_get_type sdk_scan_get_type +scan_hidden_ssid sdk_scan_hidden_ssid +scannum sdk_scannum +scan_parse_beacon sdk_scan_parse_beacon +scan_pm_channel_op_cb sdk_scan_pm_channel_op_cb +scan_profile_check sdk_scan_profile_check +scan_remove_bssid sdk_scan_remove_bssid +scan_remove_probe_ssid sdk_scan_remove_probe_ssid +scan_set_desChan sdk_scan_set_desChan +scan_start sdk_scan_start +SDIO_slp_reject sdk_SDIO_slp_reject +sdt_on_noise_start sdk_sdt_on_noise_start +set_cal_rxdc sdk_set_cal_rxdc +set_crystal_uart sdk_set_crystal_uart +set_rfanagain_dc_reg sdk_set_rfanagain_dc_reg +set_rf_freq_offset sdk_set_rf_freq_offset +set_rx_gain_cal_iq sdk_set_rx_gain_cal_iq +set_rx_gain_testchip_50 sdk_set_rx_gain_testchip_50 +set_txcap_reg sdk_set_txcap_reg +set_txdc_pbus sdk_set_txdc_pbus +SHA1Final sdk_SHA1Final +SHA1Init sdk_SHA1Init +sha1_prf sdk_sha1_prf +SHA1Transform sdk_SHA1Transform +SHA1Update sdk_SHA1Update +sha1_vector sdk_sha1_vector +sleep_opt_8266 sdk_sleep_opt_8266 +sleep_opt_bb_on_8266 sdk_sleep_opt_bb_on_8266 +sleep_reset_analog_rtcreg_8266 sdk_sleep_reset_analog_rtcreg_8266 +sleep_start_wait_time sdk_sleep_start_wait_time +slop_test sdk_slop_test +slop_wdt_feed sdk_slop_wdt_feed +software_slp_reject sdk_software_slp_reject +SPIEraseSector sdk_SPIEraseSector +spi_flash_erase_sector sdk_spi_flash_erase_sector +spi_flash_get_id sdk_spi_flash_get_id +spi_flash_read sdk_spi_flash_read +spi_flash_read_status sdk_spi_flash_read_status +spi_flash_write sdk_spi_flash_write +spi_flash_write_status sdk_spi_flash_write_status +SPIReadModeCnfig sdk_SPIReadModeCnfig +SPIRead sdk_SPIRead +SPIWrite sdk_SPIWrite +sta_con_timer sdk_sta_con_timer +sta_input sdk_sta_input +start_dig_rx sdk_start_dig_rx +sta_status_set sdk_sta_status_set +stop_dig_rx sdk_stop_dig_rx +sw_scan_mode sdk_sw_scan_mode +system_adc_read sdk_system_adc_read +system_deep_sleep sdk_system_deep_sleep +system_get_boot_mode sdk_system_get_boot_mode +system_get_boot_version sdk_system_get_boot_version +system_get_checksum sdk_system_get_checksum +system_get_chip_id sdk_system_get_chip_id +system_get_cpu_freq sdk_system_get_cpu_freq +system_get_free_heap_size sdk_system_get_free_heap_size +system_get_rst_info sdk_system_get_rst_info +system_get_rtc_time sdk_system_get_rtc_time +system_get_sdk_version sdk_system_get_sdk_version +system_get_test_result sdk_system_get_test_result +system_get_time sdk_system_get_time +system_get_userbin_addr sdk_system_get_userbin_addr +system_overclock sdk_system_overclock +system_pp_recycle_rx_pkt sdk_system_pp_recycle_rx_pkt +system_print_meminfo sdk_system_print_meminfo +system_relative_time sdk_system_relative_time +system_restart_enhance sdk_system_restart_enhance +system_restart_in_nmi sdk_system_restart_in_nmi +system_restart sdk_system_restart +system_restoreclock sdk_system_restoreclock +system_restore sdk_system_restore +system_rtc_clock_cali_proc sdk_system_rtc_clock_cali_proc +system_rtc_mem_read sdk_system_rtc_mem_read +system_rtc_mem_write sdk_system_rtc_mem_write +system_station_got_ip_set sdk_system_station_got_ip_set +system_uart_swap sdk_system_uart_swap +system_update_cpu_freq sdk_system_update_cpu_freq +system_upgrade_flag_check sdk_system_upgrade_flag_check +system_upgrade_flag_set sdk_system_upgrade_flag_set +system_upgrade_reboot sdk_system_upgrade_reboot +system_upgrade_userbin_check sdk_system_upgrade_userbin_check +system_upgrade_userbin_set sdk_system_upgrade_userbin_set +target_power_add_backoff sdk_target_power_add_backoff +target_power_backoff sdk_target_power_backoff +Td0 sdk_Td0 +Td4s_rom sdk_Td4s_rom +Te0 sdk_Te0 +test_rffreq_txcap sdk_test_rffreq_txcap +test_tout sdk_test_tout +tkip sdk_tkip +TmpSTAAPCloseAP sdk_TmpSTAAPCloseAP +trc_NeedRTS sdk_trc_NeedRTS +trc_onDisconnect sdk_trc_onDisconnect +trc_onScanDone sdk_trc_onScanDone +trc_onScanStart sdk_trc_onScanStart +tsen_meas sdk_tsen_meas +tx_atten_set_interp sdk_tx_atten_set_interp +txbbgain2dcoindex sdk_txbbgain2dcoindex +txbk_dpdby_flag sdk_txbk_dpdby_flag +tx_cap_init sdk_tx_cap_init +tx_cont_cfg sdk_tx_cont_cfg +tx_cont_dis sdk_tx_cont_dis +tx_cont_en sdk_tx_cont_en +Tx_Copy2Queue sdk_Tx_Copy2Queue +txiq_cover sdk_txiq_cover +txiq_get_mis_pwr sdk_txiq_get_mis_pwr +TxNodeNum sdk_TxNodeNum +tx_pwctrl_atten_init_en sdk_tx_pwctrl_atten_init_en +tx_pwctrl_atten_init sdk_tx_pwctrl_atten_init +tx_pwctrl_background sdk_tx_pwctrl_background +tx_pwctrl_bg_init sdk_tx_pwctrl_bg_init +tx_pwctrl_cal sdk_tx_pwctrl_cal +tx_pwctrl_init_cal sdk_tx_pwctrl_init_cal +tx_pwctrl_init sdk_tx_pwctrl_init +tx_pwctrl_pk_num sdk_tx_pwctrl_pk_num +tx_pwctrl_set_chan_flag sdk_tx_pwctrl_set_chan_flag +tx_pwr_backoff sdk_tx_pwr_backoff +txpwr_offset sdk_txpwr_offset +tx_rf_ana_gain sdk_tx_rf_ana_gain +uart_buff_switch sdk_uart_buff_switch +uart_div_modify sdk_uart_div_modify +Uart_Init sdk_Uart_Init +uart_rx_one_char sdk_uart_rx_one_char +uart_tx_flush sdk_uart_tx_flush +uart_wait_idle sdk_uart_wait_idle +user_fatal_exception_handler sdk_user_fatal_exception_handler +user_init_flag sdk_user_init_flag +user_init_task sdk_user_init_task +user_start sdk_user_start +vApplicationIdleHook sdk_vApplicationIdleHook +vApplicationStackOverflowHook sdk_vApplicationStackOverflowHook +vApplicationTickHook sdk_vApplicationTickHook +vPortYield sdk_vPortYield +wait_rfpll_cal_end sdk_wait_rfpll_cal_end +wDev_AppendRxAmpduLensBlocks sdk_wDev_AppendRxAmpduLensBlocks +wDev_AppendRxBlocks sdk_wDev_AppendRxBlocks +wDev_ClearBssid sdk_wDev_ClearBssid +wDev_ClearTxqCollisions sdk_wDev_ClearTxqCollisions +wDev_ClearWaitingQueue sdk_wDev_ClearWaitingQueue +wDev_Crypto_Conf sdk_wDev_Crypto_Conf +wDev_Crypto_Disable sdk_wDev_Crypto_Disable +wDevCtrl sdk_wDevCtrl +wDev_Disable_Beacon_Tsf sdk_wDev_Disable_Beacon_Tsf +wDevDisableRx sdk_wDevDisableRx +wDev_DisableTransmit sdk_wDev_DisableTransmit +wDev_Enable_Beacon_Tsf sdk_wDev_Enable_Beacon_Tsf +wDevEnableRx sdk_wDevEnableRx +wDev_EnableTransmit sdk_wDev_EnableTransmit +wdev_exit_sniffer sdk_wdev_exit_sniffer +wDevForceAck6M sdk_wDevForceAck6M +wDev_GetBAInfo sdk_wDev_GetBAInfo +wDev_Get_Next_TBTT sdk_wDev_Get_Next_TBTT +wDev_GetTxqCollisions sdk_wDev_GetTxqCollisions +wdev_go_sniffer sdk_wdev_go_sniffer +wDev_Initialize sdk_wDev_Initialize +wDev_Insert_KeyEntry sdk_wDev_Insert_KeyEntry +wDev_MacTim1Arm sdk_wDev_MacTim1Arm +wDev_MacTim1SetFunc sdk_wDev_MacTim1SetFunc +wDev_MacTimArm sdk_wDev_MacTimArm +wDev_MacTimSetFunc sdk_wDev_MacTimSetFunc +wDev_Option_Init sdk_wDev_Option_Init +wDev_ProcessCollision sdk_wDev_ProcessCollision +wDev_ProcessFiq sdk_wDev_ProcessFiq +wDev_remove_KeyEntry sdk_wDev_remove_KeyEntry +wDev_Reset_TBTT sdk_wDev_Reset_TBTT +wDev_Set_Beacon_Int sdk_wDev_Set_Beacon_Int +wDev_SetBssid sdk_wDev_SetBssid +wDev_SetFrameAckType sdk_wDev_SetFrameAckType +wDev_SetMacAddress sdk_wDev_SetMacAddress +wDev_SetRxPolicy sdk_wDev_SetRxPolicy +wDev_SetWaitingQueue sdk_wDev_SetWaitingQueue +WdevTimOffSet sdk_WdevTimOffSet +wd_reset_cnt sdk_wd_reset_cnt +wdt_init sdk_wdt_init +wep sdk_wep +wifi_get_channel sdk_wifi_get_channel +wifi_get_ip_info sdk_wifi_get_ip_info +wifi_get_macaddr sdk_wifi_get_macaddr +wifi_get_opmode_default sdk_wifi_get_opmode_default +wifi_get_opmode sdk_wifi_get_opmode +wifi_get_phy_mode sdk_wifi_get_phy_mode +wifi_get_sleep_type sdk_wifi_get_sleep_type +wifi_mode_set sdk_wifi_mode_set +wifi_param_save_protect sdk_wifi_param_save_protect +wifi_promiscuous_enable sdk_wifi_promiscuous_enable +wifi_promiscuous_set_mac sdk_wifi_promiscuous_set_mac +wifi_set_channel sdk_wifi_set_channel +wifi_set_ip_info sdk_wifi_set_ip_info +wifi_set_macaddr sdk_wifi_set_macaddr +wifi_set_opmode_current sdk_wifi_set_opmode_current +wifi_set_opmode_local sdk_wifi_set_opmode_local +wifi_set_opmode sdk_wifi_set_opmode +wifi_set_phy_mode sdk_wifi_set_phy_mode +wifi_set_promiscuous_rx_cb sdk_wifi_set_promiscuous_rx_cb +wifi_set_sleep_type sdk_wifi_set_sleep_type +wifi_softap_cacl_mac sdk_wifi_softap_cacl_mac +wifi_softap_deauth sdk_wifi_softap_deauth +wifi_softap_free_station_info sdk_wifi_softap_free_station_info +wifi_softap_get_config_default sdk_wifi_softap_get_config_default +wifi_softap_get_config sdk_wifi_softap_get_config +wifi_softap_get_station_info sdk_wifi_softap_get_station_info +wifi_softap_set_config_current sdk_wifi_softap_set_config_current +wifi_softap_set_config sdk_wifi_softap_set_config +wifi_softap_set_default_ssid sdk_wifi_softap_set_default_ssid +wifi_softap_set_station_info sdk_wifi_softap_set_station_info +wifi_softap_start sdk_wifi_softap_start +wifi_softap_stop sdk_wifi_softap_stop +wifi_station_ap_change sdk_wifi_station_ap_change +wifi_station_ap_check sdk_wifi_station_ap_check +wifi_station_ap_number_set sdk_wifi_station_ap_number_set +wifi_station_connect sdk_wifi_station_connect +wifi_station_dhcpc_start sdk_wifi_station_dhcpc_start +wifi_station_dhcpc_status sdk_wifi_station_dhcpc_status +wifi_station_dhcpc_stop sdk_wifi_station_dhcpc_stop +wifi_station_disconnect sdk_wifi_station_disconnect +wifi_station_get_ap_info sdk_wifi_station_get_ap_info +wifi_station_get_auto_connect sdk_wifi_station_get_auto_connect +wifi_station_get_config_default sdk_wifi_station_get_config_default +wifi_station_get_config sdk_wifi_station_get_config +wifi_station_get_connect_status sdk_wifi_station_get_connect_status +wifi_station_get_current_ap_id sdk_wifi_station_get_current_ap_id +wifi_station_scan sdk_wifi_station_scan +wifi_station_set_auto_connect sdk_wifi_station_set_auto_connect +wifi_station_set_config_current sdk_wifi_station_set_config_current +wifi_station_set_config sdk_wifi_station_set_config +wifi_station_start sdk_wifi_station_start +wifi_station_stop sdk_wifi_station_stop +wifi_status_led_install sdk_wifi_status_led_install +wpa_add_kde sdk_wpa_add_kde +wpa_attach sdk_wpa_attach +wpa_auth_for_each_sta sdk_wpa_auth_for_each_sta +wpa_auth_gen_wpa_ie sdk_wpa_auth_gen_wpa_ie +wpa_auth_sm_event sdk_wpa_auth_sm_event +wpa_auth_sta_associated sdk_wpa_auth_sta_associated +wpa_auth_sta_deinit sdk_wpa_auth_sta_deinit +wpa_auth_sta_init sdk_wpa_auth_sta_init +wpa_auth_sta_no_wpa sdk_wpa_auth_sta_no_wpa +wpa_auth_uses_mfp sdk_wpa_auth_uses_mfp +wpabuf_alloc_copy sdk_wpabuf_alloc_copy +wpabuf_alloc_ext_data sdk_wpabuf_alloc_ext_data +wpabuf_alloc sdk_wpabuf_alloc +wpabuf_concat sdk_wpabuf_concat +wpabuf_dup sdk_wpabuf_dup +wpabuf_free sdk_wpabuf_free +wpabuf_put sdk_wpabuf_put +wpabuf_resize sdk_wpabuf_resize +wpabuf_zeropad sdk_wpabuf_zeropad +wpa_cipher_key_len sdk_wpa_cipher_key_len +wpa_cipher_put_suites sdk_wpa_cipher_put_suites +wpa_cipher_to_alg sdk_wpa_cipher_to_alg +wpa_cipher_to_suite sdk_wpa_cipher_to_suite +wpa_compare_rsn_ie sdk_wpa_compare_rsn_ie +wpa_config_assoc_ie sdk_wpa_config_assoc_ie +wpa_config_bss sdk_wpa_config_bss +wpa_config_parse_string sdk_wpa_config_parse_string +wpa_config_profile sdk_wpa_config_profile +wpa_eapol_key_mic sdk_wpa_eapol_key_mic +wpa_gen_wpa_ie sdk_wpa_gen_wpa_ie +wpa_get_ntp_timestamp sdk_wpa_get_ntp_timestamp +wpa_init sdk_wpa_init +wpa_neg_complete sdk_wpa_neg_complete +wpa_parse_kde_ies sdk_wpa_parse_kde_ies +wpa_parse_wpa_ie_rsn sdk_wpa_parse_wpa_ie_rsn +wpa_parse_wpa_ie sdk_wpa_parse_wpa_ie +wpa_parse_wpa_ie_wpa sdk_wpa_parse_wpa_ie_wpa +wpa_pmk_to_ptk sdk_wpa_pmk_to_ptk +wpa_receive sdk_wpa_receive +wpa_register sdk_wpa_register +wpa_remove_ptk sdk_wpa_remove_ptk +__wpa_send_eapol sdk___wpa_send_eapol +wpa_set_bss sdk_wpa_set_bss +wpa_set_pmk sdk_wpa_set_pmk +wpa_set_profile sdk_wpa_set_profile +wpa_sm_alloc_eapol sdk_wpa_sm_alloc_eapol +wpa_sm_deauthenticate sdk_wpa_sm_deauthenticate +wpa_sm_disassociate sdk_wpa_sm_disassociate +wpa_sm_get_beacon_ie sdk_wpa_sm_get_beacon_ie +wpa_sm_mlme_setprotection sdk_wpa_sm_mlme_setprotection +wpa_sm_rx_eapol sdk_wpa_sm_rx_eapol +wpa_sm_set_state sdk_wpa_sm_set_state +wpa_supplicant_parse_ies sdk_wpa_supplicant_parse_ies +wpa_validate_wpa_ie sdk_wpa_validate_wpa_ie +wpa_write_rsn_ie sdk_wpa_write_rsn_ie +xieee80211Queue sdk_xieee80211Queue +_xt_clear_ints sdk__xt_clear_ints +_xt_context_restore sdk__xt_context_restore +_xt_context_save sdk__xt_context_save +_xt_int_enter sdk__xt_int_enter +_xt_int_exit sdk__xt_int_exit +_xt_isr_mask sdk__xt_isr_mask +_xt_isr_unmask sdk__xt_isr_unmask +_xt_read_ints sdk__xt_read_ints +_xt_tick_timer_init sdk__xt_tick_timer_init +_xt_timer_int1 sdk__xt_timer_int1 +_xt_timer_int sdk__xt_timer_int +xUserTaskHandle sdk_xUserTaskHandle +xWatchDogTaskHandle sdk_xWatchDogTaskHandle From a044c061d51a954434661d1c0292f46799c1da68 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 09:34:37 -0700 Subject: [PATCH 029/105] Replace libmain:app_main.o with core/app_main.c --- core/app_main.c | 501 +++++++++++++++++++++++++++++++++++ core/include/esp/wdev_regs.h | 30 +++ core/include/esp/wdt_regs.h | 11 + core/include/os_version.h | 6 + core/include/sdk_internal.h | 235 ++++++++++++++++ core/include/xtensa_ops.h | 21 ++ lib/libmain.remove | 1 + 7 files changed, 805 insertions(+) create mode 100644 core/app_main.c create mode 100644 core/include/esp/wdev_regs.h create mode 100644 core/include/os_version.h create mode 100644 core/include/sdk_internal.h create mode 100644 core/include/xtensa_ops.h diff --git a/core/app_main.c b/core/app_main.c new file mode 100644 index 0000000..86d1cb3 --- /dev/null +++ b/core/app_main.c @@ -0,0 +1,501 @@ +/* Implementation of libmain/app_main.o from the Espressif SDK. + * + * This contains most of the startup code for the SDK/OS, some event handlers, + * etc. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ + +#include +#include +#include +#include + +#include "common_macros.h" +#include "xtensa_ops.h" +#include "esp/rom.h" +#include "esp/iomux_regs.h" +#include "esp/uart_regs.h" +#include "esp/spi_regs.h" +#include "esp/dport_regs.h" +#include "esp/wdev_regs.h" +#include "os_version.h" + +#include "espressif/esp_system.h" +#include "sdk_internal.h" + +/* This is not declared in any header file (but arguably should be) */ + +void user_init(void); + +#define UART_DIVISOR 1068 // 74906 bps (yeah, I don't understand it either) +#define BOOT_INFO_SIZE 28 +//TODO: phy_info should probably be a struct (no idea about its organization, though) +#define PHY_INFO_SIZE 128 + +// These are the offsets of these values within the RTCMEM regions. It appears +// that the ROM saves them to RTCMEM before calling us, and we pull them out of +// there to display them in startup messages (not sure why it works that way). +#define RTCMEM_BACKUP_PHY_VER 31 +#define RTCMEM_SYSTEM_PP_VER 62 + +#define halt() while (1) {} + +extern uint32_t *_bss_start; +extern uint32_t *_bss_end; + +// .Ldata003 -- .irom.text+0x0 +static const uint8_t IROM default_phy_info[PHY_INFO_SIZE] = { + 0x05, 0x00, 0x04, 0x02, 0x05, 0x05, 0x05, 0x02, + 0x05, 0x00, 0x04, 0x05, 0x05, 0x04, 0x05, 0x05, + 0x04, 0xfe, 0xfd, 0xff, 0xf0, 0xf0, 0xf0, 0xe0, + 0xe0, 0xe0, 0xe1, 0x0a, 0xff, 0xff, 0xf8, 0x00, + 0xf8, 0xf8, 0x52, 0x4e, 0x4a, 0x44, 0x40, 0x38, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x93, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +// user_init_flag -- .bss+0x0 +uint8_t sdk_user_init_flag; + +// info -- .bss+0x4 +struct sdk_info_st sdk_info; + +// xUserTaskHandle -- .bss+0x28 +xTaskHandle sdk_xUserTaskHandle; + +// xWatchDogTaskHandle -- .bss+0x2c +xTaskHandle sdk_xWatchDogTaskHandle; + +/* Static function prototypes */ + +static void IRAM get_otp_mac_address(uint8_t *buf); +static void IRAM set_spi0_divisor(uint32_t divisor); +static void IRAM default_putc(uint8_t c); +static void IRAM default_putc1(uint8_t c); +static void zero_bss(void); +static void init_networking(uint8_t *phy_info, uint8_t *mac_addr); +static void init_g_ic(void); +static void dump_excinfo(void); +static void user_start_phase2(void); +static void dump_flash_data(uint32_t start_addr, uint32_t length); +static void dump_flash_config_sectors(uint32_t start_addr); + +// .Lfunc001 -- .text+0x14 +static void IRAM get_otp_mac_address(uint8_t *buf) { + uint32_t otp_flags; + uint32_t otp_id0, otp_id1; + uint32_t otp_vendor_id; + + otp_flags = DPORT.OTP_CHIPID; + otp_id1 = DPORT.OTP_MAC1; + otp_id0 = DPORT.OTP_MAC0; + if (!(otp_flags & 0x8000)) { + //FIXME: do we really need this check? + printf("Firmware ONLY supports ESP8266!!!\n"); + halt(); + } + if (otp_id0 == 0 && otp_id1 == 0) { + printf("empty otp\n"); + halt(); + } + if (otp_flags & 0x1000) { + // If bit 12 is set, it indicates that the vendor portion of the MAC + // address is stored in DPORT.OTP_MAC2. + otp_vendor_id = DPORT.OTP_MAC2; + buf[0] = otp_vendor_id >> 16; + buf[1] = otp_vendor_id >> 8; + buf[2] = otp_vendor_id; + } else { + // If bit 12 is clear, there's no MAC vendor in DPORT.OTP_MAC2, so + // default to the Espressif MAC vendor prefix instead. + buf[1] = 0xfe; + buf[0] = 0x18; + buf[2] = 0x34; + } + buf[3] = otp_id1 >> 8; + buf[4] = otp_id1; + buf[5] = otp_id0 >> 24; +} + +// .Lfunc002 -- .text+0xa0 +static void IRAM set_spi0_divisor(uint32_t divisor) { + int cycle_len, half_cycle_len, clkdiv; + + if (divisor < 2) { + clkdiv = 0; + SPI(0).CTRL0 |= SPI_CTRL0_CLOCK_EQU_SYS_CLOCK; + IOMUX.CONF |= IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK; + } else { + cycle_len = divisor - 1; + half_cycle_len = (divisor / 2) - 1; + clkdiv = VAL2FIELD(SPI_CTRL0_CLOCK_NUM, cycle_len) + | VAL2FIELD(SPI_CTRL0_CLOCK_HIGH, half_cycle_len) + | VAL2FIELD(SPI_CTRL0_CLOCK_LOW, cycle_len); + SPI(0).CTRL0 &= ~SPI_CTRL0_CLOCK_EQU_SYS_CLOCK; + IOMUX.CONF &= ~IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK; + } + SPI(0).CTRL0 = SET_FIELD(SPI(0).CTRL0, SPI_CTRL0_CLOCK, clkdiv); +} + +// .text+0x148 +void sdk_user_fatal_exception_handler(void) { + if (!sdk_NMIIrqIsOn) { + vPortEnterCritical(); + do { + DPORT.DPORT0 &= 0xffffffe0; + } while (DPORT.DPORT0 & 0x00000001); + } + Cache_Read_Disable(); + Cache_Read_Enable(0, 0, 1); + dump_excinfo(); + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS)) {} + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS)) {} + sdk_system_restart_in_nmi(); + halt(); +} + +// .Lfunc003 -- .text+0x1d0 +static void IRAM default_putc(uint8_t c) { + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 125) {} + UART(0).FIFO = c; +} + +// .Lfunc004 -- .text+0x1f4 +static void IRAM default_putc1(uint8_t c) { + if (c == '\n') { + default_putc('\r'); + } else if (c == '\r') { + return; + } + default_putc(c); +} + +// .text+0x258 +void IRAM sdk_user_start(void) { + uint32_t buf32[sizeof(struct sdk_g_ic_saved_st) / 4]; + uint8_t *buf8 = (uint8_t *)buf32; + uint32_t flash_speed_divisor; + uint32_t flash_sectors; + uint32_t flash_size; + int boot_slot; + uint32_t cksum_magic; + uint32_t cksum_len; + uint32_t cksum_value; + uint32_t ic_flash_addr; + + SPI(0).USER0 |= SPI_USER0_CS_SETUP; + sdk_SPIRead(0, buf32, 4); + + switch (buf8[3] & 0x0f) { + case 0xf: // 80 MHz + flash_speed_divisor = 1; + break; + case 0x0: // 40 MHz + flash_speed_divisor = 2; + break; + case 0x1: // 26 MHz + flash_speed_divisor = 3; + break; + case 0x2: // 20 MHz + flash_speed_divisor = 4; + break; + default: // Invalid -- Assume 40 MHz + flash_speed_divisor = 2; + } + switch (buf8[3] >> 4) { + case 0x0: // 4 Mbit (512 KByte) + flash_sectors = 128; + break; + case 0x1: // 2 Mbit (256 Kbyte) + flash_sectors = 64; + break; + case 0x2: // 8 Mbit (1 Mbyte) + flash_sectors = 256; + break; + case 0x3: // 16 Mbit (2 Mbyte) + flash_sectors = 512; + break; + case 0x4: // 32 Mbit (4 Mbyte) + flash_sectors = 1024; + break; + default: // Invalid -- Assume 4 Mbit (512 KByte) + flash_sectors = 128; + } + //FIXME: we should probably calculate flash_sectors by starting with flash_size and dividing by sdk_flashchip.sector_size instead of vice-versa. + flash_size = flash_sectors * 4096; + sdk_flashchip.chip_size = flash_size; + set_spi0_divisor(flash_speed_divisor); + sdk_SPIRead(flash_size - 256, buf32, BOOT_INFO_SIZE); + boot_slot = buf8[0]; + cksum_magic = buf32[1]; + cksum_len = buf32[3 + boot_slot]; + cksum_value = buf32[5 + boot_slot]; + ic_flash_addr = (flash_sectors - 2 + boot_slot) * sdk_flashchip.sector_size; + sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st)); + Cache_Read_Enable(0, 0, 1); + zero_bss(); + sdk_os_install_putc1(default_putc1); + if (cksum_magic == 0xffffffff) { + // No checksum required + } else if ((cksum_magic == 0x55aa55aa) && + (sdk_system_get_checksum(buf8, cksum_len) == cksum_value)) { + // Checksum OK + } else { + // Bad checksum or bad cksum_magic value + dump_flash_config_sectors(flash_sectors - 4); + //FIXME: should we halt here? (original SDK code doesn't) + } + memcpy(&sdk_g_ic.s, buf32, sizeof(struct sdk_g_ic_saved_st)); + + user_start_phase2(); +} + +// .text+0x3a8 +void vApplicationStackOverflowHook(xTaskHandle task, char *task_name) { + printf("\"%s\"(stack_size = %lu) overflow the heap_size.\n", task_name, uxTaskGetStackHighWaterMark(task)); +} + +// .text+0x3d8 +void vApplicationIdleHook(void) { + printf("idle %lu\n", WDEV.SYS_TIME); +} + +// .text+0x404 +void vApplicationTickHook(void) { + printf("tick %lu\n", WDEV.SYS_TIME); +} + +// .Lfunc005 -- .irom0.text+0x8 +static void zero_bss(void) { + uint32_t *addr; + + for (addr = _bss_start; addr < _bss_end; addr++) { + *addr = 0; + } +} + +// .Lfunc006 -- .irom0.text+0x70 +static void init_networking(uint8_t *phy_info, uint8_t *mac_addr) { + if (sdk_register_chipv6_phy(phy_info)) { + printf("FATAL: sdk_register_chipv6_phy failed"); + halt(); + } + sdk_uart_div_modify(0, UART_DIVISOR); + sdk_uart_div_modify(1, UART_DIVISOR); + sdk_phy_disable_agc(); + sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode); + sdk_lmacInit(); + sdk_wDev_Initialize(); + sdk_pp_attach(); + sdk_ieee80211_ifattach(sdk_g_ic, mac_addr); + _xt_isr_mask(1); + DPORT.DPORT0 = SET_FIELD(DPORT.DPORT0, DPORT_DPORT0_FIELD0, 1); + sdk_pm_attach(); + sdk_phy_enable_agc(); + sdk_cnx_attach(sdk_g_ic); + sdk_wDevEnableRx(); +} + +// .Lfunc007 -- .irom0.text+0x148 +static void init_g_ic(void) { + if (sdk_g_ic.s.wifi_mode == 0xff) { + sdk_g_ic.s.wifi_mode = 2; + } + sdk_wifi_softap_set_default_ssid(); + if (sdk_g_ic.s._unknown30d < 1 || sdk_g_ic.s._unknown30d > 14) { + sdk_g_ic.s._unknown30d = 1; + } + if (sdk_g_ic.s._unknown544 < 100 || sdk_g_ic.s._unknown544 > 60000) { + sdk_g_ic.s._unknown544 = 100; + } + if (sdk_g_ic.s._unknown30e == 1 || sdk_g_ic.s._unknown30e > 4) { + sdk_g_ic.s._unknown30e = 0; + } + bzero(sdk_g_ic.s._unknown2ac, sizeof(sdk_g_ic.s._unknown2ac)); + if (sdk_g_ic.s._unknown30f > 1) { + sdk_g_ic.s._unknown30f = 0; + } + if (sdk_g_ic.s._unknown310 > 4) { + sdk_g_ic.s._unknown310 = 4; + } + if (sdk_g_ic.s._unknown1e4._unknown1e4 == 0xffffffff) { + bzero(&sdk_g_ic.s._unknown1e4, sizeof(sdk_g_ic.s._unknown1e4)); + bzero(&sdk_g_ic.s._unknown20f, sizeof(sdk_g_ic.s._unknown20f)); + } + sdk_g_ic.s.wifi_led_enable = 0; + if (sdk_g_ic.s._unknown281 > 1) { + sdk_g_ic.s._unknown281 = 0; + } + if (sdk_g_ic.s.ap_number > 5) { + sdk_g_ic.s.ap_number = 1; + } + if (sdk_g_ic.s.phy_mode < 1 || sdk_g_ic.s.phy_mode > 3) { + sdk_g_ic.s.phy_mode = PHY_MODE_11N; + } +} + +// .Lfunc008 -- .irom0.text+0x2a0 +static void dump_excinfo(void) { + uint32_t exccause, epc1, epc2, epc3, excvaddr, depc, excsave1; + uint32_t excinfo[8]; + + RSR(exccause, exccause); + printf("Fatal exception (%d): \n", (int)exccause); + RSR(epc1, epc1); + RSR(epc2, epc2); + RSR(epc3, epc3); + RSR(excvaddr, excvaddr); + RSR(depc, depc); + RSR(excsave1, excsave1); + printf("%s=0x%08lx\n", "epc1", epc1); + printf("%s=0x%08lx\n", "epc2", epc2); + printf("%s=0x%08lx\n", "epc3", epc3); + printf("%s=0x%08lx\n", "excvaddr", excvaddr); + printf("%s=0x%08lx\n", "depc", depc); + printf("%s=0x%08lx\n", "excsave1", excsave1); + sdk_system_rtc_mem_read(0, excinfo, 32); // Why? + excinfo[0] = 2; + excinfo[1] = exccause; + excinfo[2] = epc1; + excinfo[3] = epc2; + excinfo[4] = epc3; + excinfo[5] = excvaddr; + excinfo[6] = depc; + excinfo[7] = excsave1; + sdk_system_rtc_mem_write(0, excinfo, 32); +} + +// .irom0.text+0x368 +int sdk_uart_rx_one_char(char *buf) { + if (FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(0).STATUS)) { + *buf = UART(0).FIFO; + return 0; + } + return 1; +} + +// .irom0.text+0x398 +void sdk_wdt_init(void) { + WDT.CTRL &= ~WDT_CTRL_ENABLE; + DPORT.INT_ENABLE |= DPORT_INT_ENABLE_WDT; + WDT.REG1 = 0x0000000b; + WDT.REG2 = 0x0000000c; + WDT.CTRL |= WDT_CTRL_FLAG3 | WDT_CTRL_FLAG4 | WDT_CTRL_FLAG5; + WDT.CTRL = SET_FIELD(WDT.CTRL, WDT_CTRL_FIELD0, 0); + WDT.CTRL |= WDT_CTRL_ENABLE; + sdk_pp_soft_wdt_init(); +} + +// .irom0.text+0x474 +void sdk_user_init_task(void *params) { + int phy_ver, pp_ver; + + sdk_ets_timer_init(); + printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__); + phy_ver = RTCMEM_BACKUP[RTCMEM_BACKUP_PHY_VER] >> 16; + printf("phy ver: %d, ", phy_ver); + pp_ver = RTCMEM_SYSTEM[RTCMEM_SYSTEM_PP_VER]; + printf("pp ver: %d.%d\n\n", (pp_ver >> 8) & 0xff, pp_ver & 0xff); + user_init(); + sdk_user_init_flag = 1; + sdk_wifi_mode_set(sdk_g_ic.s.wifi_mode); + if (sdk_g_ic.s.wifi_mode == 1) { + sdk_wifi_station_start(); + netif_set_default(sdk_g_ic.v.station_netif_info->netif); + } + if (sdk_g_ic.s.wifi_mode == 2) { + sdk_wifi_softap_start(); + netif_set_default(sdk_g_ic.v.softap_netif_info->netif); + } + if (sdk_g_ic.s.wifi_mode == 3) { + sdk_wifi_station_start(); + sdk_wifi_softap_start(); + netif_set_default(sdk_g_ic.v.softap_netif_info->netif); + } + if (sdk_wifi_station_get_auto_connect()) { + sdk_wifi_station_connect(); + } + vTaskDelete(NULL); +} + +// .Lfunc009 -- .irom0.text+0x5b4 +static void user_start_phase2(void) { + uint8_t *buf; + uint8_t *phy_info; + + sdk_system_rtc_mem_read(0, &sdk_rst_if, sizeof(sdk_rst_if)); + if (sdk_rst_if.version > 3) { + // Bad version number. Probably garbage. + bzero(&sdk_rst_if, sizeof(sdk_rst_if)); + } + buf = malloc(sizeof(sdk_rst_if)); + bzero(buf, sizeof(sdk_rst_if)); + sdk_system_rtc_mem_write(0, buf, sizeof(sdk_rst_if)); + free(buf); + sdk_sleep_reset_analog_rtcreg_8266(); + get_otp_mac_address(sdk_info.sta_mac_addr); + sdk_wifi_softap_cacl_mac(sdk_info.softap_mac_addr, sdk_info.sta_mac_addr); + sdk_info._unknown0 = 0x0104a8c0; + sdk_info._unknown1 = 0x00ffffff; + sdk_info._unknown2 = 0x0104a8c0; + init_g_ic(); + phy_info = malloc(PHY_INFO_SIZE); + sdk_spi_flash_read(sdk_flashchip.chip_size - sdk_flashchip.sector_size * 4, (uint32_t *)phy_info, PHY_INFO_SIZE); + + // Wait for UARTs to finish sending anything in their queues. + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 0) {} + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS) > 0) {} + + if (phy_info[0] != 5) { + // Bad version byte. Discard what we read and use default values + // instead. + memcpy(phy_info, default_phy_info, PHY_INFO_SIZE); + } + init_networking(phy_info, sdk_info.sta_mac_addr); + free(phy_info); + tcpip_init(NULL, NULL); + sdk_wdt_init(); + xTaskCreate(sdk_user_init_task, (signed char *)"uiT", 1024, 0, 14, sdk_xUserTaskHandle); +} + +// .Lfunc010 -- .irom0.text+0x710 +static void dump_flash_data(uint32_t start_addr, uint32_t length) { + uint8_t *buf; + int bufsize, i; + + bufsize = (length + 3) & 0xfffc; + buf = malloc(bufsize); + sdk_spi_flash_read(start_addr, (uint32_t *)buf, bufsize); + for (i = 0; i < length; ) { + printf("%02x ", buf[i]); + if ((i & 0x1f) == 0) { + printf("\n"); + } + } + printf("\n"); + free(buf); +} + +// .Lfunc011 -- .irom0.text+0x790 +static void dump_flash_config_sectors(uint32_t start_addr) { + printf("system param error\n"); + // The original code used start_addr+1, start_addr+2, etc. This is + // obviously wrong as start_addr is clearly a byte address, not a sector + // address. + dump_flash_data(start_addr + sdk_flashchip.sector_size, sizeof(struct sdk_g_ic_saved_st)); + dump_flash_data(start_addr + sdk_flashchip.sector_size * 2, sizeof(struct sdk_g_ic_saved_st)); + dump_flash_data(start_addr + sdk_flashchip.sector_size * 3, BOOT_INFO_SIZE); +} + diff --git a/core/include/esp/wdev_regs.h b/core/include/esp/wdev_regs.h new file mode 100644 index 0000000..74788ca --- /dev/null +++ b/core/include/esp/wdev_regs.h @@ -0,0 +1,30 @@ +/* esp/wdev_regs.h + * + * ESP8266 register definitions for the "wdev" region (0x3FF2xxx) + * + * Not compatible with ESP SDK register access code. + */ + +#ifndef _ESP_WDEV_REGS_H +#define _ESP_WDEV_REGS_H + +#include "esp/types.h" +#include "common_macros.h" + +#define WDEV_BASE 0x3FF20000 +#define WDEV (*(struct WDEV_REGS *)(WDEV_BASE)) + +/* Note: This memory region is not currently well understood. Pretty much all + * of the definitions here are from reverse-engineering the Espressif SDK code, + * many are just educated guesses, and almost certainly some are misleading or + * wrong. If you can improve on any of this, please contribute! + */ + +struct WDEV_REGS { + uint32_t volatile _unknown[768]; // 0x0000 - 0x0bfc + uint32_t volatile SYS_TIME; // 0x0c00 +} __attribute__ (( packed )); + +_Static_assert(sizeof(struct WDEV_REGS) == 0xc04, "WDEV_REGS is the wrong size"); + +#endif /* _ESP_WDEV_REGS_H */ diff --git a/core/include/esp/wdt_regs.h b/core/include/esp/wdt_regs.h index eb51f57..66bf1d0 100644 --- a/core/include/esp/wdt_regs.h +++ b/core/include/esp/wdt_regs.h @@ -31,6 +31,17 @@ struct WDT_REGS { _Static_assert(sizeof(struct WDT_REGS) == 0x18, "WDT_REGS is the wrong size"); +/* Details for CTRL register */ + +/* Note: these are currently just guesses based on interpretation of the startup code */ + +#define WDT_CTRL_ENABLE BIT(0) +#define WDT_CTRL_FIELD0_M 0x00000003 +#define WDT_CTRL_FIELD0_S 1 +#define WDT_CTRL_FLAG3 BIT(3) +#define WDT_CTRL_FLAG4 BIT(4) +#define WDT_CTRL_FLAG5 BIT(5) + /* Writing WDT_FEED_MAGIC to WDT.FEED register "feeds the dog" and holds off * triggering for another cycle (unconfirmed) */ #define WDT_FEED_MAGIC 0x73 diff --git a/core/include/os_version.h b/core/include/os_version.h new file mode 100644 index 0000000..86b3bd8 --- /dev/null +++ b/core/include/os_version.h @@ -0,0 +1,6 @@ +#ifndef _VERSION_H +#define _VERSION_H + +#define OS_VERSION_STR "0.0.1" + +#endif /* _VERSION_H */ diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h new file mode 100644 index 0000000..314d2ca --- /dev/null +++ b/core/include/sdk_internal.h @@ -0,0 +1,235 @@ +#ifndef _INTERNAL_SDK_STRUCTURES_H +#define _INTERNAL_SDK_STRUCTURES_H + +#include "espressif/esp_wifi.h" +#include "espressif/spi_flash.h" +#include "lwip/netif.h" + +/////////////////////////////////////////////////////////////////////////////// +// Internal structures and data objects // +/////////////////////////////////////////////////////////////////////////////// + +// 'info' is declared in app_main.o at .bss+0x4 + +struct sdk_info_st { + uint32_t _unknown0; + uint32_t _unknown1; + uint32_t _unknown2; + uint8_t _unknown3[12]; + uint8_t softap_mac_addr[6]; + uint8_t sta_mac_addr[6]; +}; + +extern struct sdk_info_st sdk_info; + +// 'rst_if' is declared in user_interface.o at .bss+0xfc + +struct sdk_rst_if_st { + uint32_t version; + uint8_t _unknown[28]; +}; + +extern struct sdk_rst_if_st sdk_rst_if; + +// 'g_ic' is declared in libnet80211/ieee80211.o at .bss+0x0 +// See also: http://esp8266-re.foogod.com/wiki/G_ic_(IoT_RTOS_SDK_0.9.9) + +struct sdk_g_ic_netif_info { + struct netif *netif; + //TODO: rest of this structure is unknown. +}; + +// This is the portion of g_ic which is not loaded/saved to the flash ROM, and +// starts out zeroed on every boot. +struct sdk_g_ic_volatile_st { + void *_unknown0; + void *_unknown4; + + uint8_t _unknown8[8]; + + struct sdk_g_ic_netif_info *station_netif_info; + struct sdk_g_ic_netif_info *softap_netif_info; + uint8_t _unknown18; + uint32_t _unknown1c; + uint32_t _unknown20; + + uint8_t _unknown24[8]; + + uint8_t _unknown2c; + + uint8_t _unknown30[76]; + + uint8_t _unknown7c; + uint8_t _unknown7d; + uint8_t _unknown7e; + uint8_t _unknown7f; + + uint8_t _unknown80[204]; + + void *_unknown14c; + + uint8_t _unknown150[20]; + + uint32_t _unknown164; + void *_unknown168; + void *_unknown16c; + void *_unknown170; + void *_unknown174; + void *_unknown178; + + uint8_t _unknown17c[4]; + + void *_unknown180; + void *_unknown184; + struct station_info *station_info_head; + struct station_info *station_info_tail; + uint32_t _unknown190; + uint32_t _unknown194; + + uint8_t _unknown198[40]; + + void *_unknown1c0; + void *_unknown1c4; + uint32_t _unknown1c8; + + uint8_t _unknown1cc[4]; + + uint16_t _unknown1d0; + + uint8_t _unknown1d2[2]; + + uint8_t _unknown1d4; + + uint8_t _unknown1d5[3]; +}; + +struct sdk_g_ic_unk0_st { + uint32_t _unknown1e4; + uint8_t _unknown1e8[32]; +}; + +// This is the portion of g_ic which is loaded/saved to the flash ROM, and thus +// is preserved across reboots. +struct sdk_g_ic_saved_st { + uint8_t _unknown1d8; + uint8_t boot_info; + uint8_t user0_addr[3]; + uint8_t user1_addr[3]; + uint8_t wifi_mode; + uint8_t wifi_led_enable; + uint8_t wifi_led_gpio; + uint8_t _unknown1e3; + + struct sdk_g_ic_unk0_st _unknown1e4; + + uint8_t _unknown208; + uint8_t _unknown209; + uint8_t _unknown20a; + uint8_t _unknown20b; + uint8_t _unknown20c; + uint8_t _unknown20d; + uint8_t _unknown20e; + uint8_t _unknown20f[64]; + uint8_t _unknown24f; + + uint8_t _unknown250[49]; + + uint8_t _unknown281; + + uint8_t _unknown282[6]; + + uint32_t _unknown288; + uint8_t _unknown28c; + + uint8_t _unknown290[28]; + + uint8_t _unknown2ac[64]; + uint8_t _unknonwn2ec; + + uint8_t _unknown2ed[32]; + + uint8_t _unknown30d; + uint8_t _unknown30e; + uint8_t _unknown30f; + uint8_t _unknown310; + + uint8_t _unknown311[3]; + + uint8_t ap_number; + uint8_t current_ap_id; + + uint8_t _unknown316[502]; + + uint32_t _unknown50c; + uint16_t _unknown510; + uint16_t _unknown512; + uint16_t _unknown514; + + uint8_t _unknown516[2]; + + uint8_t auto_connect; + + uint8_t _unknown519[3]; + + enum sdk_phy_mode phy_mode; + + uint8_t _unknown520[36]; + + uint16_t _unknown544; + + uint8_t _unknown546[2]; +}; + +struct sdk_g_ic_st { + struct sdk_g_ic_volatile_st v; // 0x0 - 0x1d8 + struct sdk_g_ic_saved_st s; // 0x1d8 - 0x548 +}; + +extern struct sdk_g_ic_st sdk_g_ic; + +/////////////////////////////////////////////////////////////////////////////// +// The above structures all refer to data regions outside our control, and a +// simple mistake/misunderstanding editing things here can completely screw up +// how we access them, so do some basic sanity checks to make sure that they +// appear to match up correctly with the actual data structures other parts of +// the SDK are expecting. +/////////////////////////////////////////////////////////////////////////////// + +_Static_assert(sizeof(struct sdk_info_st) == 0x24, "info_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_rst_if_st) == 0x20, "sdk_rst_if_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_g_ic_volatile_st) == 0x1d8, "sdk_g_ic_volatile_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_g_ic_saved_st) == 0x370, "sdk_g_ic_saved_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong size!"); + +/////////////////////////////////////////////////////////////////////////////// +// Function Prototypes // +/////////////////////////////////////////////////////////////////////////////// + +sdk_SpiFlashOpResult sdk_SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size); +sdk_SpiFlashOpResult sdk_SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size); +void sdk_cnx_attach(struct sdk_g_ic_st); +void sdk_ets_timer_init(void); +void sdk_ieee80211_ifattach(struct sdk_g_ic_st, uint8_t *); +void sdk_ieee80211_phy_init(enum sdk_phy_mode); +void sdk_lmacInit(void); +void sdk_os_install_putc1( void (*func)(uint8_t) ); +void sdk_phy_disable_agc(void); +void sdk_phy_enable_agc(void); +void sdk_pm_attach(void); +void sdk_pp_attach(void); +void sdk_pp_soft_wdt_init(void); +int sdk_register_chipv6_phy(uint8_t *); +void sdk_sleep_reset_analog_rtcreg_8266(void); +uint32_t sdk_system_get_checksum(uint8_t *, uint32_t); +void sdk_system_restart_in_nmi(void); +void sdk_wDevEnableRx(void); +void sdk_wDev_Initialize(void); +void sdk_wifi_mode_set(uint8_t); +void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *); +void sdk_wifi_softap_set_default_ssid(void); +void sdk_wifi_softap_start(void); +void sdk_wifi_station_connect(void); +bool sdk_wifi_station_get_auto_connect(void); +void sdk_wifi_station_start(void); + +#endif /* _INTERNAL_SDK_STRUCTURES_H */ diff --git a/core/include/xtensa_ops.h b/core/include/xtensa_ops.h new file mode 100644 index 0000000..49d1fbe --- /dev/null +++ b/core/include/xtensa_ops.h @@ -0,0 +1,21 @@ +/** xtensa_ops.h + * + * Special macros/etc which deal with Xtensa-specific architecture/CPU + * considerations. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ + +#ifndef _XTENSA_OPS_H +#define _XTENSA_OPS_H + +// GCC macros for reading, writing, and exchanging Xtensa processor special +// registers: + +#define RSR(var, reg) asm volatile ("rsr %0, " #reg : "=r" (var)); +#define WSR(var, reg) asm volatile ("wsr %0, " #reg : : "r" (var)); +#define XSR(var, reg) asm volatile ("xsr %0, " #reg : "+r" (var)); + +#endif /* _XTENSA_OPS_H */ diff --git a/lib/libmain.remove b/lib/libmain.remove index ae569f8..35145b3 100644 --- a/lib/libmain.remove +++ b/lib/libmain.remove @@ -2,3 +2,4 @@ printf-stdarg.o libc.o xtensa_vectors.o +app_main.o From 43a712572ce1b541cce1767574c15a32b48b87cf Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 09:41:49 -0700 Subject: [PATCH 030/105] Don't rename FreeRTOS hook symbols --- FreeRTOS/Source/portable/esp8266/portmacro.h | 3 --- lib/allsymbols.rename | 4 ---- 2 files changed, 7 deletions(-) diff --git a/FreeRTOS/Source/portable/esp8266/portmacro.h b/FreeRTOS/Source/portable/esp8266/portmacro.h index c7f0501..da68720 100644 --- a/FreeRTOS/Source/portable/esp8266/portmacro.h +++ b/FreeRTOS/Source/portable/esp8266/portmacro.h @@ -182,9 +182,6 @@ 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 - #ifdef __cplusplus } #endif diff --git a/lib/allsymbols.rename b/lib/allsymbols.rename index 2f455f0..7f56f1f 100644 --- a/lib/allsymbols.rename +++ b/lib/allsymbols.rename @@ -669,10 +669,6 @@ user_fatal_exception_handler sdk_user_fatal_exception_handler user_init_flag sdk_user_init_flag user_init_task sdk_user_init_task user_start sdk_user_start -vApplicationIdleHook sdk_vApplicationIdleHook -vApplicationStackOverflowHook sdk_vApplicationStackOverflowHook -vApplicationTickHook sdk_vApplicationTickHook -vPortYield sdk_vPortYield wait_rfpll_cal_end sdk_wait_rfpll_cal_end wDev_AppendRxAmpduLensBlocks sdk_wDev_AppendRxAmpduLensBlocks wDev_AppendRxBlocks sdk_wDev_AppendRxBlocks From c16dd2ef2321e1aa61a6e375b23a7eefbd159bd2 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 17:21:51 -0700 Subject: [PATCH 031/105] Add 'sdklike' FLAVOR to makefile --- common.mk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common.mk b/common.mk index e05e78e..245e277 100644 --- a/common.mk +++ b/common.mk @@ -100,6 +100,13 @@ LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(RO ifeq ($(FLAVOR),debug) CFLAGS += -g -O0 LDFLAGS += -g -O0 +else ifeq ($(FLAVOR),sdklike) + # These are flags intended to produce object code as similar as possible to + # the output of the compiler used to build the SDK libs (for comparison of + # disassemblies when coding replacement routines). It is not normally + # intended to be used otherwise. + CFLAGS += -O2 -Os -fno-inline -fno-ipa-cp -fno-toplevel-reorder + LDFLAGS += -O2 else CFLAGS += -g -O2 LDFLAGS += -g -O2 From aa7f305e167e0115867ac1223ad08c77fcf66cf6 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 25 Aug 2015 17:22:38 -0700 Subject: [PATCH 032/105] Various app_main.c bug fixes --- core/app_main.c | 18 +++++++++--------- core/include/esp/dport_regs.h | 2 +- core/include/sdk_internal.h | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index 86d1cb3..ae8fa07 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -43,8 +43,8 @@ void user_init(void); #define halt() while (1) {} -extern uint32_t *_bss_start; -extern uint32_t *_bss_end; +extern uint32_t _bss_start; +extern uint32_t _bss_end; // .Ldata003 -- .irom.text+0x0 static const uint8_t IROM default_phy_info[PHY_INFO_SIZE] = { @@ -150,7 +150,7 @@ static void IRAM set_spi0_divisor(uint32_t divisor) { } // .text+0x148 -void sdk_user_fatal_exception_handler(void) { +void IRAM sdk_user_fatal_exception_handler(void) { if (!sdk_NMIIrqIsOn) { vPortEnterCritical(); do { @@ -263,17 +263,17 @@ void IRAM sdk_user_start(void) { } // .text+0x3a8 -void vApplicationStackOverflowHook(xTaskHandle task, char *task_name) { +void IRAM vApplicationStackOverflowHook(xTaskHandle task, char *task_name) { printf("\"%s\"(stack_size = %lu) overflow the heap_size.\n", task_name, uxTaskGetStackHighWaterMark(task)); } // .text+0x3d8 -void vApplicationIdleHook(void) { +void IRAM vApplicationIdleHook(void) { printf("idle %lu\n", WDEV.SYS_TIME); } // .text+0x404 -void vApplicationTickHook(void) { +void IRAM vApplicationTickHook(void) { printf("tick %lu\n", WDEV.SYS_TIME); } @@ -281,7 +281,7 @@ void vApplicationTickHook(void) { static void zero_bss(void) { uint32_t *addr; - for (addr = _bss_start; addr < _bss_end; addr++) { + for (addr = &_bss_start; addr < &_bss_end; addr++) { *addr = 0; } } @@ -299,12 +299,12 @@ static void init_networking(uint8_t *phy_info, uint8_t *mac_addr) { sdk_lmacInit(); sdk_wDev_Initialize(); sdk_pp_attach(); - sdk_ieee80211_ifattach(sdk_g_ic, mac_addr); + sdk_ieee80211_ifattach(&sdk_g_ic, mac_addr); _xt_isr_mask(1); DPORT.DPORT0 = SET_FIELD(DPORT.DPORT0, DPORT_DPORT0_FIELD0, 1); sdk_pm_attach(); sdk_phy_enable_agc(); - sdk_cnx_attach(sdk_g_ic); + sdk_cnx_attach(&sdk_g_ic); sdk_wDevEnableRx(); } diff --git a/core/include/esp/dport_regs.h b/core/include/esp/dport_regs.h index df17103..87efca1 100644 --- a/core/include/esp/dport_regs.h +++ b/core/include/esp/dport_regs.h @@ -53,7 +53,7 @@ _Static_assert(sizeof(struct DPORT_REGS) == 0x60, "DPORT_REGS is the wrong size" /* Currently very little known about this register. The following is based on analysis of the startup code in the Espressif SDK: */ -#define DPORT_DPORT0_FIELD0_M 0x0000007f +#define DPORT_DPORT0_FIELD0_M 0x0000001f #define DPORT_DPORT0_FIELD0_S 0 /* Details for INT_ENABLE register */ diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h index 314d2ca..6764094 100644 --- a/core/include/sdk_internal.h +++ b/core/include/sdk_internal.h @@ -207,9 +207,9 @@ _Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong si sdk_SpiFlashOpResult sdk_SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size); sdk_SpiFlashOpResult sdk_SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size); -void sdk_cnx_attach(struct sdk_g_ic_st); +void sdk_cnx_attach(struct sdk_g_ic_st *); void sdk_ets_timer_init(void); -void sdk_ieee80211_ifattach(struct sdk_g_ic_st, uint8_t *); +void sdk_ieee80211_ifattach(struct sdk_g_ic_st *, uint8_t *); void sdk_ieee80211_phy_init(enum sdk_phy_mode); void sdk_lmacInit(void); void sdk_os_install_putc1( void (*func)(uint8_t) ); From a9eb3a38e328cd91035c5788d78426f15c40fbdd Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Wed, 26 Aug 2015 13:19:53 -0700 Subject: [PATCH 033/105] More app_main fixups from object code comparisons --- core/app_main.c | 7 ++++--- core/include/sdk_internal.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index ae8fa07..8d5a2b9 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -82,7 +82,7 @@ xTaskHandle sdk_xWatchDogTaskHandle; static void IRAM get_otp_mac_address(uint8_t *buf); static void IRAM set_spi0_divisor(uint32_t divisor); -static void IRAM default_putc(uint8_t c); +static int IRAM default_putc(uint8_t c); static void IRAM default_putc1(uint8_t c); static void zero_bss(void); static void init_networking(uint8_t *phy_info, uint8_t *mac_addr); @@ -167,9 +167,10 @@ void IRAM sdk_user_fatal_exception_handler(void) { } // .Lfunc003 -- .text+0x1d0 -static void IRAM default_putc(uint8_t c) { +static int IRAM default_putc(uint8_t c) { while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 125) {} UART(0).FIFO = c; + return 0; } // .Lfunc004 -- .text+0x1f4 @@ -467,7 +468,7 @@ static void user_start_phase2(void) { free(phy_info); tcpip_init(NULL, NULL); sdk_wdt_init(); - xTaskCreate(sdk_user_init_task, (signed char *)"uiT", 1024, 0, 14, sdk_xUserTaskHandle); + xTaskCreate(sdk_user_init_task, (signed char *)"uiT", 1024, 0, 14, &sdk_xUserTaskHandle); } // .Lfunc010 -- .irom0.text+0x710 diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h index 6764094..9c4da3e 100644 --- a/core/include/sdk_internal.h +++ b/core/include/sdk_internal.h @@ -141,7 +141,7 @@ struct sdk_g_ic_saved_st { uint32_t _unknown288; uint8_t _unknown28c; - uint8_t _unknown290[28]; + uint8_t _unknown28d[31]; uint8_t _unknown2ac[64]; uint8_t _unknonwn2ec; From a88f36d98695438d439b8272da88c453f06dbd05 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Fri, 28 Aug 2015 17:45:38 -0700 Subject: [PATCH 034/105] More app_main.c fixups It's alive! IT'S ALIVE!! --- core/app_main.c | 15 ++++++++------- core/include/sdk_internal.h | 3 --- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index 8d5a2b9..025ca9f 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -23,7 +23,7 @@ #include "esp/wdev_regs.h" #include "os_version.h" -#include "espressif/esp_system.h" +#include "espressif/esp_common.h" #include "sdk_internal.h" /* This is not declared in any header file (but arguably should be) */ @@ -82,8 +82,8 @@ xTaskHandle sdk_xWatchDogTaskHandle; static void IRAM get_otp_mac_address(uint8_t *buf); static void IRAM set_spi0_divisor(uint32_t divisor); -static int IRAM default_putc(uint8_t c); -static void IRAM default_putc1(uint8_t c); +static int IRAM default_putc(char c); +static void IRAM default_putc1(char c); static void zero_bss(void); static void init_networking(uint8_t *phy_info, uint8_t *mac_addr); static void init_g_ic(void); @@ -167,14 +167,14 @@ void IRAM sdk_user_fatal_exception_handler(void) { } // .Lfunc003 -- .text+0x1d0 -static int IRAM default_putc(uint8_t c) { +static int IRAM default_putc(char c) { while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 125) {} UART(0).FIFO = c; return 0; } // .Lfunc004 -- .text+0x1f4 -static void IRAM default_putc1(uint8_t c) { +static void IRAM default_putc1(char c) { if (c == '\n') { default_putc('\r'); } else if (c == '\r') { @@ -238,8 +238,8 @@ void IRAM sdk_user_start(void) { flash_size = flash_sectors * 4096; sdk_flashchip.chip_size = flash_size; set_spi0_divisor(flash_speed_divisor); - sdk_SPIRead(flash_size - 256, buf32, BOOT_INFO_SIZE); - boot_slot = buf8[0]; + sdk_SPIRead(flash_size - 4096, buf32, BOOT_INFO_SIZE); + boot_slot = buf8[0] & 1; cksum_magic = buf32[1]; cksum_len = buf32[3 + boot_slot]; cksum_value = buf32[5 + boot_slot]; @@ -469,6 +469,7 @@ static void user_start_phase2(void) { tcpip_init(NULL, NULL); sdk_wdt_init(); xTaskCreate(sdk_user_init_task, (signed char *)"uiT", 1024, 0, 14, &sdk_xUserTaskHandle); + vTaskStartScheduler(); } // .Lfunc010 -- .irom0.text+0x710 diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h index 9c4da3e..5a5aee5 100644 --- a/core/include/sdk_internal.h +++ b/core/include/sdk_internal.h @@ -212,7 +212,6 @@ void sdk_ets_timer_init(void); void sdk_ieee80211_ifattach(struct sdk_g_ic_st *, uint8_t *); void sdk_ieee80211_phy_init(enum sdk_phy_mode); void sdk_lmacInit(void); -void sdk_os_install_putc1( void (*func)(uint8_t) ); void sdk_phy_disable_agc(void); void sdk_phy_enable_agc(void); void sdk_pm_attach(void); @@ -228,8 +227,6 @@ void sdk_wifi_mode_set(uint8_t); void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *); void sdk_wifi_softap_set_default_ssid(void); void sdk_wifi_softap_start(void); -void sdk_wifi_station_connect(void); -bool sdk_wifi_station_get_auto_connect(void); void sdk_wifi_station_start(void); #endif /* _INTERNAL_SDK_STRUCTURES_H */ From 8b5e8b923e4b85fb93da9867a93c645f1dc69a32 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Sun, 30 Aug 2015 12:11:08 -0700 Subject: [PATCH 035/105] Bug fix for dump_flash_config_sectors --- core/app_main.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index 025ca9f..3136b2a 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -89,8 +89,8 @@ static void init_networking(uint8_t *phy_info, uint8_t *mac_addr); static void init_g_ic(void); static void dump_excinfo(void); static void user_start_phase2(void); -static void dump_flash_data(uint32_t start_addr, uint32_t length); -static void dump_flash_config_sectors(uint32_t start_addr); +static void dump_flash_sector(uint32_t start_sector, uint32_t length); +static void dump_flash_config_sectors(uint32_t start_sector); // .Lfunc001 -- .text+0x14 static void IRAM get_otp_mac_address(uint8_t *buf) { @@ -473,31 +473,38 @@ static void user_start_phase2(void) { } // .Lfunc010 -- .irom0.text+0x710 -static void dump_flash_data(uint32_t start_addr, uint32_t length) { +static void dump_flash_sector(uint32_t start_sector, uint32_t length) { uint8_t *buf; int bufsize, i; bufsize = (length + 3) & 0xfffc; buf = malloc(bufsize); - sdk_spi_flash_read(start_addr, (uint32_t *)buf, bufsize); - for (i = 0; i < length; ) { - printf("%02x ", buf[i]); - if ((i & 0x1f) == 0) { - printf("\n"); + sdk_spi_flash_read(start_sector * sdk_flashchip.sector_size, (uint32_t *)buf +, bufsize); + for (i = 0; i < length; i++) { + if ((i & 0xf) == 0) { + if (i) { + printf("\n"); + } + printf("%04x:", i); } + printf(" %02x", buf[i]); } printf("\n"); free(buf); } // .Lfunc011 -- .irom0.text+0x790 -static void dump_flash_config_sectors(uint32_t start_addr) { +static void dump_flash_config_sectors(uint32_t start_sector) { printf("system param error\n"); - // The original code used start_addr+1, start_addr+2, etc. This is - // obviously wrong as start_addr is clearly a byte address, not a sector - // address. - dump_flash_data(start_addr + sdk_flashchip.sector_size, sizeof(struct sdk_g_ic_saved_st)); - dump_flash_data(start_addr + sdk_flashchip.sector_size * 2, sizeof(struct sdk_g_ic_saved_st)); - dump_flash_data(start_addr + sdk_flashchip.sector_size * 3, BOOT_INFO_SIZE); + // Note: original SDK code didn't dump PHY info + printf("phy_info:\n"); + dump_flash_sector(start_sector, PHY_INFO_SIZE); + printf("\ng_ic saved 0:\n"); + dump_flash_sector(start_sector + 1, sizeof(struct sdk_g_ic_saved_st)); + printf("\ng_ic saved 1:\n"); + dump_flash_sector(start_sector + 2, sizeof(struct sdk_g_ic_saved_st)); + printf("\nboot info:\n"); + dump_flash_sector(start_sector + 3, BOOT_INFO_SIZE); } From 19f01b2f7272284fb8478d06433cc92a52c261e6 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Sun, 30 Aug 2015 13:37:40 -0700 Subject: [PATCH 036/105] app_main.c: load correct g_ic sector from flash --- core/app_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index 3136b2a..1989234 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -239,11 +239,11 @@ void IRAM sdk_user_start(void) { sdk_flashchip.chip_size = flash_size; set_spi0_divisor(flash_speed_divisor); sdk_SPIRead(flash_size - 4096, buf32, BOOT_INFO_SIZE); - boot_slot = buf8[0] & 1; + boot_slot = buf8[0] ? 1 : 0; cksum_magic = buf32[1]; cksum_len = buf32[3 + boot_slot]; cksum_value = buf32[5 + boot_slot]; - ic_flash_addr = (flash_sectors - 2 + boot_slot) * sdk_flashchip.sector_size; + ic_flash_addr = (flash_sectors - 3 + boot_slot) * sdk_flashchip.sector_size; sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st)); Cache_Read_Enable(0, 0, 1); zero_bss(); From 0090153fa7d2cc5e36806ec51307c288e75546b7 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 31 Aug 2015 16:56:16 +1000 Subject: [PATCH 037/105] Reorder library arguments so component libraries come first This allows components to override weak linked symbols in the core or the SDK libraries, without needing to force symbol discovery. Will help with #24, for instance. --- common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index 323d13d..1c2424f 100644 --- a/common.mk +++ b/common.mk @@ -80,7 +80,7 @@ OBJDUMP = $(CROSS)objdump # Source components to compile and link. Each of these are subdirectories # of the root, with a 'component.mk' file. -COMPONENTS ?= core FreeRTOS lwip axtls $(EXTRA_COMPONENTS) +COMPONENTS ?= $(EXTRA_COMPONENTS) FreeRTOS lwip axtls core # binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking. SDK_LIBS ?= main net80211 phy pp wpa @@ -318,7 +318,7 @@ $(LD_DIR)%.ld: $(ROOT)ld/%.ld | $(LD_DIR) # final linking step to produce .elf $(PROGRAM_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS_PROCESSED) $(vecho) "LD $@" - $(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(SDK_LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@ + $(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(COMPONENT_ARS) $(LIB_ARGS) $(SDK_LIB_ARGS) -Wl,--end-group -o $@ $(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib $(LD_DIR): $(Q) mkdir -p $@ From fd1081a0cc1e0f8723087b366aa81750f4638d1f Mon Sep 17 00:00:00 2001 From: Angus71 Date: Tue, 25 Aug 2015 14:45:48 +0200 Subject: [PATCH 038/105] Added BMP180 and I2C driver and example Fixed reference to unknown environment var Moved drivers into extras folder and added additional documentations. Changed LOCAL to static and renamed DEBUG to BMP180_DEBUG --- examples/bmp180_i2c/Makefile | 3 + examples/bmp180_i2c/README.md | 7 + examples/bmp180_i2c/bmp180_i2c.c | 132 ++++++++++++ extras/README.md | 10 + extras/bmp180/LICENSE | 22 ++ extras/bmp180/README.md | 56 +++++ extras/bmp180/bmp180.c | 351 +++++++++++++++++++++++++++++++ extras/bmp180/bmp180.h | 55 +++++ extras/bmp180/component.mk | 9 + extras/i2c/LICENSE | 22 ++ extras/i2c/README.md | 40 ++++ extras/i2c/component.mk | 9 + extras/i2c/i2c.c | 229 ++++++++++++++++++++ extras/i2c/i2c.h | 51 +++++ 14 files changed, 996 insertions(+) create mode 100644 examples/bmp180_i2c/Makefile create mode 100644 examples/bmp180_i2c/README.md create mode 100644 examples/bmp180_i2c/bmp180_i2c.c create mode 100644 extras/README.md create mode 100644 extras/bmp180/LICENSE create mode 100644 extras/bmp180/README.md create mode 100644 extras/bmp180/bmp180.c create mode 100644 extras/bmp180/bmp180.h create mode 100644 extras/bmp180/component.mk create mode 100644 extras/i2c/LICENSE create mode 100644 extras/i2c/README.md create mode 100644 extras/i2c/component.mk create mode 100644 extras/i2c/i2c.c create mode 100644 extras/i2c/i2c.h diff --git a/examples/bmp180_i2c/Makefile b/examples/bmp180_i2c/Makefile new file mode 100644 index 0000000..dd5eaf6 --- /dev/null +++ b/examples/bmp180_i2c/Makefile @@ -0,0 +1,3 @@ +PROGRAM=BMP180_Reader +EXTRA_COMPONENTS = extras/i2c extras/bmp180 +include ../../common.mk diff --git a/examples/bmp180_i2c/README.md b/examples/bmp180_i2c/README.md new file mode 100644 index 0000000..21d754a --- /dev/null +++ b/examples/bmp180_i2c/README.md @@ -0,0 +1,7 @@ +# I2C / BMP180 Example + +This example references two addtional drivers [i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c) and [bmp180](https://github.com/Angus71/esp-open-rtos-driver-bmp180), which are provided in the `../../extras` folder. + +If you plan to use one or both of this drivers in your own projects, please check the main development pages for updated versions or reported issues. + +To run this example connect the BMP085/BMP180 SCL to GPIO0 and SDA to GPIO2. diff --git a/examples/bmp180_i2c/bmp180_i2c.c b/examples/bmp180_i2c/bmp180_i2c.c new file mode 100644 index 0000000..76b3705 --- /dev/null +++ b/examples/bmp180_i2c/bmp180_i2c.c @@ -0,0 +1,132 @@ +/* Simple example for I2C / BMP180 / Timer & Event Handling + * + * This sample code is in the public domain. + */ +#include "espressif/esp_common.h" +#include "espressif/sdk_private.h" + +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "queue.h" + +// BMP180 driver +#include "bmp180/bmp180.h" + +#define MY_EVT_TIMER 0x01 +#define MY_EVT_BMP180 0x02 + +#define SCL_PIN GPIO_ID_PIN((0)) +#define SDA_PIN GPIO_ID_PIN((2)) + +typedef struct +{ + uint8_t event_type; + bmp180_result_t bmp180_data; +} my_event_t; + +// Communication Queue +static xQueueHandle mainqueue; +static xTimerHandle timerHandle; + +// Own BMP180 User Inform Implementation +bool bmp180_i2c_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) +{ + my_event_t ev; + + ev.event_type = MY_EVT_BMP180; + ev.bmp180_data.cmd = cmd; + ev.bmp180_data.temperatue = temperatue; + ev.bmp180_data.pressure = pressure; + + return (xQueueSend(*resultQueue, &ev, 0) == pdTRUE); +} + +// Timer call back +static void bmp180_i2c_timer_cb(xTimerHandle xTimer) +{ + my_event_t ev; + ev.event_type = MY_EVT_TIMER; + + xQueueSend(mainqueue, &ev, 0); +} + +// Check for communiction events +void bmp180_task(void *pvParameters) +{ + // Received pvParameters is communication queue + xQueueHandle *com_queue = (xQueueHandle *)pvParameters; + + printf("%s: Started user interface task\n", __FUNCTION__); + + while(1) + { + my_event_t ev; + + xQueueReceive(*com_queue, &ev, portMAX_DELAY); + + switch(ev.event_type) + { + case MY_EVT_TIMER: + printf("%s: Received Timer Event\n", __FUNCTION__); + + bmp180_trigger_measurement(com_queue); + break; + case MY_EVT_BMP180: + printf("%s: Received BMP180 Event temp:=%ld.%d°C press=%ld.%02ldhPa\n", __FUNCTION__, \ + (int32_t)ev.bmp180_data.temperatue, abs((int32_t)(ev.bmp180_data.temperatue*10)%10), \ + ev.bmp180_data.pressure/100, ev.bmp180_data.pressure%100 ); + break; + default: + break; + } + } +} + +// Setup HW +void user_setup(void) +{ + // Set UART Parameter + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + + // Give the UART some time to settle + sdk_os_delay_us(500); +} + +void user_init(void) +{ + // Setup HW + user_setup(); + + // Just some infomations + printf("\n"); + printf("SDK version : %s\n", sdk_system_get_sdk_version()); + printf("GIT version : %s\n", GITSHORTREV); + + // Use our user inform implementation + bmp180_informUser = bmp180_i2c_informUser; + + // Init BMP180 Interface + bmp180_init(SCL_PIN, SDA_PIN); + + // Create Main Communication Queue + mainqueue = xQueueCreate(10, sizeof(my_event_t)); + + // Create user interface task + xTaskCreate(bmp180_task, (signed char *)"bmp180_task", 256, &mainqueue, 2, NULL); + + // Create Timer (Trigger a measurement every second) + timerHandle = xTimerCreate((signed char *)"BMP180 Trigger", 1000/portTICK_RATE_MS, pdTRUE, NULL, bmp180_i2c_timer_cb); + + if (timerHandle != NULL) + { + if (xTimerStart(timerHandle, 0) != pdPASS) + { + printf("%s: Unable to start Timer ...\n", __FUNCTION__); + } + } + else + { + printf("%s: Unable to create Timer ...\n", __FUNCTION__); + } +} diff --git a/extras/README.md b/extras/README.md new file mode 100644 index 0000000..1bc0a52 --- /dev/null +++ b/extras/README.md @@ -0,0 +1,10 @@ +# extras + +This folder contains supportive source code. + +For current versions or reporting issues etc. please check the main development pages. + +- [bmp180](https://github.com/Angus71/esp-open-rtos-driver-bmp180) +- [i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c) +- [rboot-ota](http://richard.burtons.org/) + diff --git a/extras/bmp180/LICENSE b/extras/bmp180/LICENSE new file mode 100644 index 0000000..1f44f09 --- /dev/null +++ b/extras/bmp180/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Frank Bargstedt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/extras/bmp180/README.md b/extras/bmp180/README.md new file mode 100644 index 0000000..d6073c6 --- /dev/null +++ b/extras/bmp180/README.md @@ -0,0 +1,56 @@ +# Driver for BMP085/BMP180 digital pressure sensor + +This driver is written for usage with the ESP8266 and FreeRTOS ([esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos) and [esp-open-rtos-driver-i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c)). + +### Usage + +Before using the BMP180 module, the function `bmp180_init(SCL_PIN, SDA_PIN)` needs to be called to setup the I2C interface and do validation if the BMP180/BMP085 is accessible. + +If the setup is sucessfully and a measurement is triggered, the result of the measurement is provided to the user as an event send via the `qQueue` provided with `bmp180_trigger_*measurement(pQueue);` + +#### Example + +``` +#define SCL_PIN GPIO_ID_PIN(0) +#define SDA_PIN GPIO_ID_PIN(2) +... + +if (!bmp180_init(SCL_PIN, SDA_PIN)) { +// An error occured, while dong the init (E.g device not found etc.) +} + +// Trigger a measurement +bmp180_trigger_measurement(pQueue); + +``` + +#### Change queue event + +Per default the event send to the user via the provided queue is of the type `bmp180_result_t`. As this might not always be desired, a way is provided so that the user can provide a function, which creates and sends the event via the provided queue. + +As all data aqquired from the BMP180/BMP085 is provided to the `bmp180_informUser` function, it is also possible to calculate new informations (E.g altitude etc.) + +##### Example + +``` +// Own BMP180 User Inform Implementation +bool my_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) { + my_event_t ev; + + ev.event_type = MY_EVT_BMP180; + ev.bmp180_data.cmd = cmd; + ev.bmp180_data.temperatue = temperatue; + ev.bmp180_data.pressure = pressure; + + return (xQueueSend(*resultQueue, &ev, 0) == pdTRUE); +} + +... + +// Use our user inform implementation +// needs to be set before first measurement is triggered +bmp180_informUser = my_informUser; + + +``` + diff --git a/extras/bmp180/bmp180.c b/extras/bmp180/bmp180.c new file mode 100644 index 0000000..66203b0 --- /dev/null +++ b/extras/bmp180/bmp180.c @@ -0,0 +1,351 @@ +#include "bmp180.h" + +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" + +#include "espressif/esp_common.h" +#include "espressif/sdk_private.h" + +#include "i2c/i2c.h" + +#define BMP180_RX_QUEUE_SIZE 10 +#define BMP180_TASK_PRIORITY 9 + +#define BMP180_DEVICE_ADDRESS 0x77 + +#define BMP180_VERSION_REG 0xD0 +#define BMP180_CONTROL_REG 0xF4 +#define BMP180_RESET_REG 0xE0 +#define BMP180_OUT_MSB_REG 0xF6 +#define BMP180_OUT_LSB_REG 0xF7 +#define BMP180_OUT_XLSB_REG 0xF8 + +#define BMP180_CALIBRATION_REG 0xAA + +// +// Values for BMP180_CONTROL_REG +// +#define BMP180_MEASURE_TEMP 0x2E +#define BMP180_MEASURE_PRESS_OSS0 0x34 +#define BMP180_MEASURE_PRESS_OSS1 0x74 +#define BMP180_MEASURE_PRESS_OSS2 0xB4 +#define BMP180_MEASURE_PRESS_OSS3 0xF4 + +#define BMP180_DEFAULT_CONV_TIME 5000 + +// +// CHIP ID stored in BMP180_VERSION_REG +// +#define BMP180_CHIP_ID 0x55 + +// +// Reset value for BMP180_RESET_REG +// +#define BMP180_RESET_VALUE 0xB6 + + +// BMP180_Event_Command +typedef struct +{ + uint8_t cmd; + const xQueueHandle* resultQueue; +} bmp180_command_t; + +// Just works due to the fact that xQueueHandle is a "void *" +static xQueueHandle bmp180_rx_queue = NULL; +static xTaskHandle bmp180_task_handle = NULL; + +// Calibration constants +static int16_t AC1; +static int16_t AC2; +static int16_t AC3; +static uint16_t AC4; +static uint16_t AC5; +static uint16_t AC6; + +static int16_t B1; +static int16_t B2; + +static int16_t MB; +static int16_t MC; +static int16_t MD; + +// +// Forward declarations +// +static void bmp180_meassure(const bmp180_command_t* command); +static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure); + +// Set default implementation .. User gets result as bmp180_result_t event +bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) = bmp180_informUser_Impl; + +// I2C Driver Task +static void bmp180_driver_task(void *pvParameters) +{ + // Data to be received from user + bmp180_command_t current_command; + +#ifdef BMP180_DEBUG + // Wait for commands from the outside + printf("%s: Started Task\n", __FUNCTION__); +#endif + + while(1) + { + // Wait for user to insert commands + if (xQueueReceive(bmp180_rx_queue, ¤t_command, portMAX_DELAY) == pdTRUE) + { +#ifdef BMP180_DEBUG + printf("%s: Received user command %d 0x%p\n", __FUNCTION__, current_command.cmd, current_command.resultQueue); +#endif + // use user provided queue + if (current_command.resultQueue != NULL) + { + // Work on it ... + bmp180_meassure(¤t_command); + } + } + } +} + +static uint8_t bmp180_readRegister8(uint8_t reg) +{ + uint8_t r = 0; + + if (!i2c_slave_read(BMP180_DEVICE_ADDRESS, reg, &r, 1)) + { + r = 0; + } + return r; +} + + +static int16_t bmp180_readRegister16(uint8_t reg) +{ + uint8_t d[] = { 0, 0 }; + int16_t r = 0; + + if (i2c_slave_read(BMP180_DEVICE_ADDRESS, reg, d, 2)) + { + r = ((int16_t)d[0]<<8) | (d[1]); + } + return r; +} + +static void bmp180_start_Messurement(uint8_t cmd) +{ + uint8_t d[] = { BMP180_CONTROL_REG, cmd }; + + i2c_slave_write(BMP180_DEVICE_ADDRESS, d, 2); +} + +static int16_t bmp180_getUncompensatedMessurement(uint8_t cmd) +{ + // Write Start Code into reg 0xF4 (Currently without oversampling ...) + bmp180_start_Messurement((cmd==BMP180_TEMPERATURE)?BMP180_MEASURE_TEMP:BMP180_MEASURE_PRESS_OSS0); + + // Wait 5ms Datasheet states 4.5ms + sdk_os_delay_us(BMP180_DEFAULT_CONV_TIME); + + return (int16_t)bmp180_readRegister16(BMP180_OUT_MSB_REG); +} + +static void bmp180_fillInternalConstants(void) +{ + AC1 = bmp180_readRegister16(BMP180_CALIBRATION_REG+0); + AC2 = bmp180_readRegister16(BMP180_CALIBRATION_REG+2); + AC3 = bmp180_readRegister16(BMP180_CALIBRATION_REG+4); + AC4 = bmp180_readRegister16(BMP180_CALIBRATION_REG+6); + AC5 = bmp180_readRegister16(BMP180_CALIBRATION_REG+8); + AC6 = bmp180_readRegister16(BMP180_CALIBRATION_REG+10); + + B1 = bmp180_readRegister16(BMP180_CALIBRATION_REG+12); + B2 = bmp180_readRegister16(BMP180_CALIBRATION_REG+14); + + MB = bmp180_readRegister16(BMP180_CALIBRATION_REG+16); + MC = bmp180_readRegister16(BMP180_CALIBRATION_REG+18); + MD = bmp180_readRegister16(BMP180_CALIBRATION_REG+20); + +#ifdef BMP180_DEBUG + printf("%s: AC1:=%d AC2:=%d AC3:=%d AC4:=%u AC5:=%u AC6:=%u \n", __FUNCTION__, AC1, AC2, AC3, AC4, AC5, AC6); + printf("%s: B1:=%d B2:=%d\n", __FUNCTION__, B1, B2); + printf("%s: MB:=%d MC:=%d MD:=%d\n", __FUNCTION__, MB, MC, MD); +#endif +} + +static bool bmp180_create_communication_queues() +{ + // Just create them once + if (bmp180_rx_queue==NULL) + { + bmp180_rx_queue = xQueueCreate(BMP180_RX_QUEUE_SIZE, sizeof(bmp180_result_t)); + } + + return (bmp180_rx_queue!=NULL); +} + +static bool bmp180_is_avaialble() +{ + return (bmp180_readRegister8(BMP180_VERSION_REG)==BMP180_CHIP_ID); +} + +static bool bmp180_createTask() +{ + // We already have a task + portBASE_TYPE x = pdPASS; + + if (bmp180_task_handle==NULL) + { + x = xTaskCreate(bmp180_driver_task, (signed char *)"bmp180_driver_task", 256, NULL, BMP180_TASK_PRIORITY, &bmp180_task_handle); + } + return (x==pdPASS); +} + +static void bmp180_meassure(const bmp180_command_t* command) +{ + int32_t T, P; + + // Init result to 0 + T = P = 0; + + if (command->resultQueue != NULL) + { + int32_t UT, X1, X2, B5; + + // + // Temperature is always needed ... Also required for pressure only + // + // Calculation taken from BMP180 Datasheet + UT = (int32_t)bmp180_getUncompensatedMessurement(BMP180_TEMPERATURE); + + X1 = (UT - (int32_t)AC6) * ((int32_t)AC5) >> 15; + X2 = ((int32_t)MC << 11) / (X1 + (int32_t)MD); + B5 = X1 + X2; + + T = (B5 + 8) >> 4; + +#ifdef BMP180_DEBUG + printf("%s: T:= %ld.%d\n", __FUNCTION__, T/10, abs(T%10)); +#endif + + // Do we also need pressure? + if (command->cmd & BMP180_PRESSURE) + { + int32_t X3, B3, B6; + uint32_t B4, B7, UP; + + UP = ((uint32_t)bmp180_getUncompensatedMessurement(BMP180_PRESSURE) & 0xFFFF); + + // Calculation taken from BMP180 Datasheet + B6 = B5 - 4000; + X1 = ((int32_t)B2 * ((B6 * B6) >> 12)) >> 11; + X2 = ((int32_t)AC2 * B6) >> 11; + X3 = X1 + X2; + + B3 = (((int32_t)AC1 * 4 + X3) + 2) >> 2; + X1 = ((int32_t)AC3 * B6) >> 13; + X2 = ((int32_t)B1 * ((B6 * B6) >> 12)) >> 16; + X3 = ((X1 + X2) + 2) >> 2; + B4 = ((uint32_t)AC4 * (uint32_t)(X3 + 32768)) >> 15; + B7 = (UP - B3) * (uint32_t)(50000UL); + + if (B7 < 0x80000000) + { + P = (B7 * 2) / B4; + } + else + { + P = (B7 / B4) * 2; + } + + X1 = (P >> 8) * (P >> 8); + X1 = (X1 * 3038) >> 16; + X2 = (-7357 * P) >> 16; + P = P + ((X1 + X2 + (int32_t)3791) >> 4); + +#ifdef BMP180_DEBUG + printf("%s: P:= %ld\n", __FUNCTION__, P); +#endif + } + + // Inform the user ... + if (!bmp180_informUser(command->resultQueue, command->cmd, ((bmp180_temp_t)T)/10.0, (bmp180_press_t)P)) + { + // Failed to send info to user + printf("%s: Unable to inform user bmp180_informUser returned \"false\"\n", __FUNCTION__); + } + } +} + +// Default user inform implementation +static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) +{ + bmp180_result_t result; + + result.cmd = cmd; + result.temperatue = temperatue; + result.pressure = pressure; + + return (xQueueSend(*resultQueue, &result, 0) == pdTRUE); +} + +// Just init all needed queues +bool bmp180_init(uint8_t scl, uint8_t sda) +{ + // 1. Create required queues + bool result = false; + + if (bmp180_create_communication_queues()) + { + // 2. Init i2c driver + i2c_init(scl, sda); + + // 3. Check for bmp180 ... + if (bmp180_is_avaialble()) + { + // 4. Init all internal constants ... + bmp180_fillInternalConstants(); + + // 5. Start driver task + if (bmp180_createTask()) + { + // We are finished + result = true; + } + } + } + + return result; +} + +void bmp180_trigger_measurement(const xQueueHandle* resultQueue) +{ + bmp180_command_t c; + + c.cmd = BMP180_PRESSURE + BMP180_TEMPERATURE; + c.resultQueue = resultQueue; + + xQueueSend(bmp180_rx_queue, &c, 0); +} + + +void bmp180_trigger_pressure_measurement(const xQueueHandle* resultQueue) +{ + bmp180_command_t c; + + c.cmd = BMP180_PRESSURE; + c.resultQueue = resultQueue; + + xQueueSend(bmp180_rx_queue, &c, 0); +} + +void bmp180_trigger_temperature_measurement(const xQueueHandle* resultQueue) +{ + bmp180_command_t c; + + c.cmd = BMP180_TEMPERATURE; + c.resultQueue = resultQueue; + + xQueueSend(bmp180_rx_queue, &c, 0); +} diff --git a/extras/bmp180/bmp180.h b/extras/bmp180/bmp180.h new file mode 100644 index 0000000..73709ff --- /dev/null +++ b/extras/bmp180/bmp180.h @@ -0,0 +1,55 @@ +/* + * bmp180.h + * + * Created on: 23.08.2015 + * Author: fbargste + */ + +#ifndef DRIVER_BMP180_H_ +#define DRIVER_BMP180_H_ + +#include "stdint.h" +#include "stdbool.h" + +#include "FreeRTOS.h" +#include "queue.h" + +// Uncomment to enable debug output +//#define BMP180_DEBUG + +#define BMP180_TEMPERATURE (1<<0) +#define BMP180_PRESSURE (1<<1) + +// +// Create bmp180_types +// + +// temperature in °C +typedef float bmp180_temp_t; +// pressure in mPa (To get hPa divide by 100) +typedef uint32_t bmp180_press_t; + +// BMP180_Event_Result +typedef struct +{ + uint8_t cmd; + bmp180_temp_t temperatue; + bmp180_press_t pressure; +} bmp180_result_t; + +// Init bmp180 driver ... +bool bmp180_init(uint8_t scl, uint8_t sda); + +// Trigger a "complete" measurement (temperature and pressure will be valid when given to "bmp180_informUser) +void bmp180_trigger_measurement(const xQueueHandle* resultQueue); + +// Trigger a "temperature only" measurement (only temperature will be valid when given to "bmp180_informUser) +void bmp180_trigger_temperature_measurement(const xQueueHandle* resultQueue); + +// Trigger a "pressure only" measurement (only pressure will be valid when given to "bmp180_informUser) +void bmp180_trigger_pressure_measurement(const xQueueHandle* resultQueue); + +// Give the user the chance to create it's own handler +extern bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure); + +#endif /* DRIVER_BMP180_H_ */ diff --git a/extras/bmp180/component.mk b/extras/bmp180/component.mk new file mode 100644 index 0000000..5efc68a --- /dev/null +++ b/extras/bmp180/component.mk @@ -0,0 +1,9 @@ +# Component makefile for extras/bmp180 + +INC_DIRS += $(ROOT)extras + +# args for passing into compile rule generation +extras/bmp180_INC_DIR = $(ROOT)extras +extras/bmp180_SRC_DIR = $(ROOT)extras/bmp180 + +$(eval $(call component_compile_rules,extras/bmp180)) diff --git a/extras/i2c/LICENSE b/extras/i2c/LICENSE new file mode 100644 index 0000000..85820f6 --- /dev/null +++ b/extras/i2c/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Johan Kanflo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/extras/i2c/README.md b/extras/i2c/README.md new file mode 100644 index 0000000..7ab90f6 --- /dev/null +++ b/extras/i2c/README.md @@ -0,0 +1,40 @@ +# Yet another I2C driver for the ESP8266 + +This time a driver for the excellent esp-open-rtos. This is a bit banging I2C driver based on the Wikipedia pesudo C code [1]. + +### Adding to your project + +Add the driver to your project as a submodule rather than cloning it: + +```` +% git submodule add https://github.com/kanflo/esp-open-rtos-driver-i2c.git i2c +```` +The esp-open-rtos makefile-fu will make sure the driver is built. + +### Usage + + +```` +#include + +#define SCL_PIN (0) +#define SDA_PIN (2) + +uint8_t slave_addr = 0x20; +uint8_t reg_addr = 0x1f; +uint8_t reg_data; +uint8_t data[] = {reg_addr, 0xc8}; + +i2c_init(SCL_PIN, SDA_PIN); + +// Write data to slave +bool success = i2c_slave_write(slave_addr, data, sizeof(data)); + +// Issue write to slave, sending reg_addr, followed by reading 1 byte +success = i2c_slave_read(slave_addr, ®_addr, reg_data, 1); + +```` + +The driver is released under the MIT license. + +[1] https://en.wikipedia.org/wiki/I²C#Example_of_bit-banging_the_I.C2.B2C_Master_protocol \ No newline at end of file diff --git a/extras/i2c/component.mk b/extras/i2c/component.mk new file mode 100644 index 0000000..13b0f83 --- /dev/null +++ b/extras/i2c/component.mk @@ -0,0 +1,9 @@ +# Component makefile for extras/i2c + +INC_DIRS += $(ROOT)extras + +# args for passing into compile rule generation +extras/i2c_INC_DIR = $(ROOT)extras +extras/i2c_SRC_DIR = $(ROOT)extras/i2c + +$(eval $(call component_compile_rules,extras/i2c)) diff --git a/extras/i2c/i2c.c b/extras/i2c/i2c.c new file mode 100644 index 0000000..ef19c45 --- /dev/null +++ b/extras/i2c/i2c.c @@ -0,0 +1,229 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Johan Kanflo (github.com/kanflo) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include // sdk_os_delay_us +#include "i2c.h" + + +// I2C driver for ESP8266 written for use with esp-open-rtos +// Based on https://en.wikipedia.org/wiki/I²C#Example_of_bit-banging_the_I.C2.B2C_Master_protocol + +// With calling overhead, we end up at ~100kbit/s +#define CLK_HALF_PERIOD_US (1) + +#define CLK_STRETCH (10) + +static bool started; +static uint8_t g_scl_pin; +static uint8_t g_sda_pin; + +void i2c_init(uint8_t scl_pin, uint8_t sda_pin) +{ + started = false; + g_scl_pin = scl_pin; + g_sda_pin = sda_pin; +} + +static void i2c_delay(void) +{ + sdk_os_delay_us(CLK_HALF_PERIOD_US); +} + +// Set SCL as input and return current level of line, 0 or 1 +static bool read_scl(void) +{ + gpio_enable(g_scl_pin, GPIO_INPUT); + return gpio_read(g_scl_pin); // Clock high, valid ACK +} + +// Set SDA as input and return current level of line, 0 or 1 +static bool read_sda(void) +{ + gpio_enable(g_sda_pin, GPIO_INPUT); + // TODO: Without this delay we get arbitration lost in i2c_stop + i2c_delay(); + return gpio_read(g_sda_pin); // Clock high, valid ACK +} + +// Actively drive SCL signal low +static void clear_scl(void) +{ + gpio_enable(g_scl_pin, GPIO_OUTPUT); + gpio_write(g_scl_pin, 0); +} + +// Actively drive SDA signal low +static void clear_sda(void) +{ + gpio_enable(g_sda_pin, GPIO_OUTPUT); + gpio_write(g_sda_pin, 0); +} + +// Output start condition +void i2c_start(void) +{ + uint32_t clk_stretch = CLK_STRETCH; + if (started) { // if started, do a restart cond + // Set SDA to 1 + (void) read_sda(); + i2c_delay(); + while (read_scl() == 0 && clk_stretch--) ; + // Repeated start setup time, minimum 4.7us + i2c_delay(); + } + if (read_sda() == 0) { + printf("I2C: arbitration lost in i2c_start\n"); + } + // SCL is high, set SDA from 1 to 0. + clear_sda(); + i2c_delay(); + clear_scl(); + started = true; +} + +// Output stop condition +void i2c_stop(void) +{ + uint32_t clk_stretch = CLK_STRETCH; + // Set SDA to 0 + clear_sda(); + i2c_delay(); + // Clock stretching + while (read_scl() == 0 && clk_stretch--) ; + // Stop bit setup time, minimum 4us + i2c_delay(); + // SCL is high, set SDA from 0 to 1 + if (read_sda() == 0) { + printf("I2C: arbitration lost in i2c_stop\n"); + } + i2c_delay(); + started = false; +} + +// Write a bit to I2C bus +static void i2c_write_bit(bool bit) +{ + uint32_t clk_stretch = CLK_STRETCH; + if (bit) { + (void) read_sda(); + } else { + clear_sda(); + } + i2c_delay(); + // Clock stretching + while (read_scl() == 0 && clk_stretch--) ; + // SCL is high, now data is valid + // If SDA is high, check that nobody else is driving SDA + if (bit && read_sda() == 0) { + printf("I2C: arbitration lost in i2c_write_bit\n"); + } + i2c_delay(); + clear_scl(); +} + +// Read a bit from I2C bus +static bool i2c_read_bit(void) +{ + uint32_t clk_stretch = CLK_STRETCH; + bool bit; + // Let the slave drive data + (void) read_sda(); + i2c_delay(); + // Clock stretching + while (read_scl() == 0 && clk_stretch--) ; + // SCL is high, now data is valid + bit = read_sda(); + i2c_delay(); + clear_scl(); + return bit; +} + +bool i2c_write(uint8_t byte) +{ + bool nack; + uint8_t bit; + for (bit = 0; bit < 8; bit++) { + i2c_write_bit((byte & 0x80) != 0); + byte <<= 1; + } + nack = i2c_read_bit(); + return !nack; +} + +uint8_t i2c_read(bool ack) +{ + uint8_t byte = 0; + uint8_t bit; + for (bit = 0; bit < 8; bit++) { + byte = (byte << 1) | i2c_read_bit(); + } + i2c_write_bit(ack); + return byte; +} + +bool i2c_slave_write(uint8_t slave_addr, uint8_t *data, uint8_t len) +{ + bool success = false; + do { + i2c_start(); + if (!i2c_write(slave_addr << 1)) + break; + while (len--) { + if (!i2c_write(*data++)) + break; + } + i2c_stop(); + success = true; + } while(0); + return success; +} + +bool i2c_slave_read(uint8_t slave_addr, uint8_t data, uint8_t *buf, uint32_t len) +{ + bool success = false; + do { + i2c_start(); + if (!i2c_write(slave_addr << 1)) { + break; + } + i2c_write(data); + i2c_stop(); + i2c_start(); + if (!i2c_write(slave_addr << 1 | 1)) { // Slave address + read + break; + } + while(len) { + *buf = i2c_read(len == 1); + buf++; + len--; + } + success = true; + } while(0); + i2c_stop(); + if (!success) { + printf("I2C: write error\n"); + } + return success; +} diff --git a/extras/i2c/i2c.h b/extras/i2c/i2c.h new file mode 100644 index 0000000..ac3163f --- /dev/null +++ b/extras/i2c/i2c.h @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Johan Kanflo (github.com/kanflo) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __I2C_H__ +#define __I2C_H__ +#endif + +#include +#include + +// Init bitbanging I2C driver on given pins +void i2c_init(uint8_t scl_pin, uint8_t sda_pin); + +// Write a byte to I2C bus. Return true if slave acked. +bool i2c_write(uint8_t byte); + +// Read a byte from I2C bus. Return true if slave acked. +uint8_t i2c_read(bool ack); + +// Write 'len' bytes from 'buf' to slave. Return true if slave acked. +bool i2c_slave_write(uint8_t slave_addr, uint8_t *buf, uint8_t len); + +// Issue a read operation and send 'data', followed by reading 'len' bytes +// from slave into 'buf'. Return true if slave acked. +bool i2c_slave_read(uint8_t slave_addr, uint8_t data, uint8_t *buf, uint32_t len); + +// Send start and stop conditions. Only needed when implementing protocols for +// devices where the i2c_slave_[read|write] functions above are of no use. +void i2c_start(void); +void i2c_stop(void); From 568ebc0fdcb5b51c589cfd0ab4d4b18ae29731fb Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 3 Sep 2015 11:14:44 +1000 Subject: [PATCH 039/105] libc read()/write() syscalls - return EBADF if fd is not stdin/stdout as applicable As discussed in #41 Also fixes indent in _read_r --- core/newlib_syscalls.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/core/newlib_syscalls.c b/core/newlib_syscalls.c index fb97f7b..bb35ce0 100644 --- a/core/newlib_syscalls.c +++ b/core/newlib_syscalls.c @@ -6,6 +6,7 @@ */ #include #include +#include #include #include #include @@ -37,6 +38,10 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr) */ long _write_r(struct _reent *r, int fd, const char *ptr, int len ) { + if(fd != r->_stdout->_file) { + r->_errno = EBADF; + return -1; + } for(int i = 0; i < len; i++) sdk_os_putc(ptr[i]); return len; @@ -48,13 +53,16 @@ long _write_r(struct _reent *r, int fd, const char *ptr, int len ) */ long _read_r( struct _reent *r, int fd, char *ptr, int len ) { - for(int i = 0; i < len; i++) { - char ch; - while (sdk_uart_rx_one_char(&ch)) ; - ptr[i] = ch; - - } - return len; + if(fd != r->_stdin->_file) { + r->_errno = EBADF; + return -1; + } + for(int i = 0; i < len; i++) { + char ch; + while (sdk_uart_rx_one_char(&ch)) ; + ptr[i] = ch; + } + return len; } /* These are stub implementations for the reentrant syscalls that From 920ee8bf8550f596c9b59cfadb72419a620d4875 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 3 Sep 2015 11:15:05 +1000 Subject: [PATCH 040/105] libc syscalls: ENOSYS implementations for open,fstat,close,lseek Closes #41 --- core/newlib_syscalls.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/core/newlib_syscalls.c b/core/newlib_syscalls.c index bb35ce0..767dd2d 100644 --- a/core/newlib_syscalls.c +++ b/core/newlib_syscalls.c @@ -65,20 +65,19 @@ long _read_r( struct _reent *r, int fd, char *ptr, int len ) return len; } -/* These are stub implementations for the reentrant syscalls that - * newlib is configured to expect */ -int _fstat_r(struct _reent *r, int fd, void *buf) +/* Stub syscall implementations follow, to allow compiling newlib functions that + pull these in via various codepaths +*/ +__attribute__((alias("syscall_returns_enosys"))) int _open_r(struct _reent *r, const char *pathname, int flags, int mode); +__attribute__((alias("syscall_returns_enosys"))) int _fstat_r(struct _reent *r, int fd, void *buf); +__attribute__((alias("syscall_returns_enosys"))) int _close_r(struct _reent *r, int fd); +__attribute__((alias("syscall_returns_enosys"))) off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence); + +/* Generic stub for any newlib syscall that fails with errno ENOSYS + ("Function not implemented") and a return value equivalent to + (int)-1. */ +static int syscall_returns_enosys(struct _reent *r) { + r->_errno=ENOSYS; return -1; } - -int _close_r(struct _reent *r, int fd) -{ - return -1; -} - -off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence) -{ - return (off_t)-1; -} - From 7ed064a750b36e16efb44bb1090f019784fb92b8 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 5 Sep 2015 12:54:09 +1000 Subject: [PATCH 041/105] libc: Redefine int32_t/uint32_t as 'int' not 'long' libc built from projectgus/newlib-xtensa@007777696321407 Closes #42 --- core/include/esp/timer_private.h | 2 +- examples/bmp180_i2c/bmp180_i2c.c | 2 +- examples/button/button.c | 4 +- examples/experiments/timers/timers.c | 16 +- examples/ota_basic/ota_basic.c | 2 +- examples/simple/simple.c | 2 +- .../include/machine/_default_types.h | 176 +----------------- libc/xtensa-lx106-elf/lib/libc.a | Bin 5104804 -> 5105508 bytes libc/xtensa-lx106-elf/lib/libg.a | Bin 5104804 -> 5105508 bytes libc/xtensa-lx106-elf/lib/libm.a | Bin 2239598 -> 2241938 bytes 10 files changed, 18 insertions(+), 186 deletions(-) diff --git a/core/include/esp/timer_private.h b/core/include/esp/timer_private.h index 530a396..a5fc246 100644 --- a/core/include/esp/timer_private.h +++ b/core/include/esp/timer_private.h @@ -193,7 +193,7 @@ INLINED bool _timer_set_frequency_impl(const timer_frc_t frc, uint32_t freq) counts = timer_freq_to_count(frc, freq, div); if(counts == 0) { - printf("ABORT: No counter for timer %u frequency %lu\r\n", frc, freq); + printf("ABORT: No counter for timer %u frequency %u\r\n", frc, freq); abort(); } diff --git a/examples/bmp180_i2c/bmp180_i2c.c b/examples/bmp180_i2c/bmp180_i2c.c index 76b3705..15c0508 100644 --- a/examples/bmp180_i2c/bmp180_i2c.c +++ b/examples/bmp180_i2c/bmp180_i2c.c @@ -73,7 +73,7 @@ void bmp180_task(void *pvParameters) bmp180_trigger_measurement(com_queue); break; case MY_EVT_BMP180: - printf("%s: Received BMP180 Event temp:=%ld.%d°C press=%ld.%02ldhPa\n", __FUNCTION__, \ + printf("%s: Received BMP180 Event temp:=%d.%d°C press=%d.%02dhPa\n", __FUNCTION__, \ (int32_t)ev.bmp180_data.temperatue, abs((int32_t)(ev.bmp180_data.temperatue*10)%10), \ ev.bmp180_data.pressure/100, ev.bmp180_data.pressure%100 ); break; diff --git a/examples/button/button.c b/examples/button/button.c index bcca2b3..e197ffc 100644 --- a/examples/button/button.c +++ b/examples/button/button.c @@ -34,7 +34,7 @@ void buttonPollTask(void *pvParameters) { taskYIELD(); } - printf("Polled for button press at %ldms\r\n", xTaskGetTickCount()*portTICK_RATE_MS); + printf("Polled for button press at %dms\r\n", xTaskGetTickCount()*portTICK_RATE_MS); vTaskDelay(200 / portTICK_RATE_MS); } } @@ -59,7 +59,7 @@ void buttonIntTask(void *pvParameters) xQueueReceive(*tsqueue, &button_ts, portMAX_DELAY); button_ts *= portTICK_RATE_MS; if(last < button_ts-200) { - printf("Button interrupt fired at %ldms\r\n", button_ts); + printf("Button interrupt fired at %dms\r\n", button_ts); last = button_ts; } } diff --git a/examples/experiments/timers/timers.c b/examples/experiments/timers/timers.c index a840159..2a11bec 100644 --- a/examples/experiments/timers/timers.c +++ b/examples/experiments/timers/timers.c @@ -20,8 +20,8 @@ IRAM void dump_frc1_seq(void) uint32_t f1_a = TIMER(0).COUNT; uint32_t f1_b = TIMER(0).COUNT; uint32_t f1_c = TIMER(0).COUNT; - printf("FRC1 sequence 0x%08lx 0x%08lx 0x%08lx\r\n", f1_a, f1_b, f1_c); - printf("FRC1 deltas %ld %ld \r\n", f1_b-f1_a, f1_c-f1_b); + printf("FRC1 sequence 0x%08x 0x%08x 0x%08x\r\n", f1_a, f1_b, f1_c); + printf("FRC1 deltas %d %d \r\n", f1_b-f1_a, f1_c-f1_b); } IRAM void dump_frc2_seq(void) @@ -37,8 +37,8 @@ IRAM void dump_frc2_seq(void) uint32_t f2_a = TIMER(1).COUNT; uint32_t f2_b = TIMER(1).COUNT; uint32_t f2_c = TIMER(1).COUNT; - printf("FRC2 sequence 0x%08lx 0x%08lx 0x%08lx\r\n", f2_a, f2_b, f2_c); - printf("FRC2 deltas %ld %ld \r\n", f2_b-f2_a, f2_c-f2_b); + printf("FRC2 sequence 0x%08x 0x%08x 0x%08x\r\n", f2_a, f2_b, f2_c); + printf("FRC2 deltas %d %d \r\n", f2_b-f2_a, f2_c-f2_b); } IRAM void dump_timer_regs(const char *msg) @@ -56,7 +56,7 @@ IRAM void dump_timer_regs(const char *msg) for(int i = 0; i < DUMP_SZ; i++) { if(i % 4 == 0) printf("%s0x%02x: ", i ? "\r\n" : "", i*4); - printf("%08lx ", chunk[i]); + printf("%08x ", chunk[i]); } printf("\r\n"); @@ -77,7 +77,7 @@ static volatile uint32_t frc1_last_count_val; void timerRegTask(void *pvParameters) { while(1) { - printf("state at task tick count %ld:\r\n", xTaskGetTickCount()); + printf("state at task tick count %d:\r\n", xTaskGetTickCount()); dump_timer_regs(""); /* @@ -87,10 +87,10 @@ void timerRegTask(void *pvParameters) printf("INUM_MAX count %d\r\n", max_count); */ - printf("frc1 handler called %ld times, last value 0x%08lx\r\n", frc1_handler_call_count, + printf("frc1 handler called %d times, last value 0x%08x\r\n", frc1_handler_call_count, frc1_last_count_val); - printf("frc2 handler called %ld times, last value 0x%08lx\r\n", frc2_handler_call_count, + printf("frc2 handler called %d times, last value 0x%08x\r\n", frc2_handler_call_count, frc2_last_count_val); vTaskDelay(500 / portTICK_RATE_MS); diff --git a/examples/ota_basic/ota_basic.c b/examples/ota_basic/ota_basic.c index 23df052..69751d0 100644 --- a/examples/ota_basic/ota_basic.c +++ b/examples/ota_basic/ota_basic.c @@ -26,7 +26,7 @@ void user_init(void) printf("Image addresses in flash:\r\n"); for(int i = 0; i -/* - * Guess on types by examining *_MIN / *_MAX defines. - */ -#if __GNUC_PREREQ (3, 3) -/* GCC >= 3.3.0 has ____ implicitly defined. */ -#define __EXP(x) __##x##__ -#else -/* Fall back to POSIX versions from */ -#define __EXP(x) x -#include -#endif - #ifdef __cplusplus extern "C" { #endif -#ifdef __INT8_TYPE__ -typedef __INT8_TYPE__ __int8_t; -#ifdef __UINT8_TYPE__ -typedef __UINT8_TYPE__ __uint8_t; -#else -typedef unsigned __INT8_TYPE__ __uint8_t; -#endif -#define ___int8_t_defined 1 -#elif __EXP(SCHAR_MAX) == 0x7f typedef signed char __int8_t ; typedef unsigned char __uint8_t ; #define ___int8_t_defined 1 -#endif -#ifdef __INT16_TYPE__ -typedef __INT16_TYPE__ __int16_t; -#ifdef __UINT16_TYPE__ -typedef __UINT16_TYPE__ __uint16_t; -#else -typedef unsigned __INT16_TYPE__ __uint16_t; -#endif -#define ___int16_t_defined 1 -#elif __EXP(INT_MAX) == 0x7fff -typedef signed int __int16_t; -typedef unsigned int __uint16_t; -#define ___int16_t_defined 1 -#elif __EXP(SHRT_MAX) == 0x7fff typedef signed short __int16_t; typedef unsigned short __uint16_t; #define ___int16_t_defined 1 -#elif __EXP(SCHAR_MAX) == 0x7fff -typedef signed char __int16_t; -typedef unsigned char __uint16_t; -#define ___int16_t_defined 1 -#endif -#ifdef __INT32_TYPE__ -typedef __INT32_TYPE__ __int32_t; -#ifdef __UINT32_TYPE__ -typedef __UINT32_TYPE__ __uint32_t; -#else -typedef unsigned __INT32_TYPE__ __uint32_t; -#endif -#define ___int32_t_defined 1 -#elif __EXP(INT_MAX) == 0x7fffffffL typedef signed int __int32_t; typedef unsigned int __uint32_t; #define ___int32_t_defined 1 -#elif __EXP(LONG_MAX) == 0x7fffffffL -typedef signed long __int32_t; -typedef unsigned long __uint32_t; -#define ___int32_t_defined 1 -#elif __EXP(SHRT_MAX) == 0x7fffffffL -typedef signed short __int32_t; -typedef unsigned short __uint32_t; -#define ___int32_t_defined 1 -#elif __EXP(SCHAR_MAX) == 0x7fffffffL -typedef signed char __int32_t; -typedef unsigned char __uint32_t; -#define ___int32_t_defined 1 -#endif -#ifdef __INT64_TYPE__ -typedef __INT64_TYPE__ __int64_t; -#ifdef __UINT64_TYPE__ -typedef __UINT64_TYPE__ __uint64_t; -#else -typedef unsigned __INT64_TYPE__ __uint64_t; -#endif -#define ___int64_t_defined 1 -#elif __EXP(LONG_MAX) > 0x7fffffff -typedef signed long __int64_t; -typedef unsigned long __uint64_t; -#define ___int64_t_defined 1 - -/* GCC has __LONG_LONG_MAX__ */ -#elif defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) typedef signed long long __int64_t; typedef unsigned long long __uint64_t; #define ___int64_t_defined 1 -/* POSIX mandates LLONG_MAX in */ -#elif defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) -typedef signed long long __int64_t; -typedef unsigned long long __uint64_t; -#define ___int64_t_defined 1 - -#elif __EXP(INT_MAX) > 0x7fffffff -typedef signed int __int64_t; -typedef unsigned int __uint64_t; -#define ___int64_t_defined 1 -#endif - -#ifdef __INT_LEAST8_TYPE__ -typedef __INT_LEAST8_TYPE__ __int_least8_t; -#ifdef __UINT_LEAST8_TYPE__ -typedef __UINT_LEAST8_TYPE__ __uint_least8_t; -#else -typedef unsigned __INT_LEAST8_TYPE__ __uint_least8_t; -#endif -#define ___int_least8_t_defined 1 -#elif defined(___int8_t_defined) typedef __int8_t __int_least8_t; typedef __uint8_t __uint_least8_t; -#define ___int_least8_t_defined 1 -#elif defined(___int16_t_defined) -typedef __int16_t __int_least8_t; -typedef __uint16_t __uint_least8_t; -#define ___int_least8_t_defined 1 -#elif defined(___int32_t_defined) -typedef __int32_t __int_least8_t; -typedef __uint32_t __uint_least8_t; -#define ___int_least8_t_defined 1 -#elif defined(___int64_t_defined) -typedef __int64_t __int_least8_t; -typedef __uint64_t __uint_least8_t; -#define ___int_least8_t_defined 1 -#endif -#ifdef __INT_LEAST16_TYPE__ -typedef __INT_LEAST16_TYPE__ __int_least16_t; -#ifdef __UINT_LEAST16_TYPE__ -typedef __UINT_LEAST16_TYPE__ __uint_least16_t; -#else -typedef unsigned __INT_LEAST16_TYPE__ __uint_least16_t; -#endif -#define ___int_least16_t_defined 1 -#elif defined(___int16_t_defined) typedef __int16_t __int_least16_t; typedef __uint16_t __uint_least16_t; -#define ___int_least16_t_defined 1 -#elif defined(___int32_t_defined) -typedef __int32_t __int_least16_t; -typedef __uint32_t __uint_least16_t; -#define ___int_least16_t_defined 1 -#elif defined(___int64_t_defined) -typedef __int64_t __int_least16_t; -typedef __uint64_t __uint_least16_t; -#define ___int_least16_t_defined 1 -#endif -#ifdef __INT_LEAST32_TYPE__ -typedef __INT_LEAST32_TYPE__ __int_least32_t; -#ifdef __UINT_LEAST32_TYPE__ -typedef __UINT_LEAST32_TYPE__ __uint_least32_t; -#else -typedef unsigned __INT_LEAST32_TYPE__ __uint_least32_t; -#endif -#define ___int_least32_t_defined 1 -#elif defined(___int32_t_defined) typedef __int32_t __int_least32_t; typedef __uint32_t __uint_least32_t; -#define ___int_least32_t_defined 1 -#elif defined(___int64_t_defined) -typedef __int64_t __int_least32_t; -typedef __uint64_t __uint_least32_t; -#define ___int_least32_t_defined 1 -#endif -#ifdef __INT_LEAST64_TYPE__ -typedef __INT_LEAST64_TYPE__ __int_least64_t; -#ifdef __UINT_LEAST64_TYPE__ -typedef __UINT_LEAST64_TYPE__ __uint_least64_t; -#else -typedef unsigned __INT_LEAST64_TYPE__ __uint_least64_t; -#endif -#define ___int_least64_t_defined 1 -#elif defined(___int64_t_defined) typedef __int64_t __int_least64_t; typedef __uint64_t __uint_least64_t; -#define ___int_least64_t_defined 1 -#endif -#ifdef __INTPTR_TYPE__ typedef __INTPTR_TYPE__ __intptr_t; -#ifdef __UINTPTR_TYPE__ typedef __UINTPTR_TYPE__ __uintptr_t; -#else -typedef unsigned __INTPTR_TYPE__ __uintptr_t; -#endif -#elif defined(__PTRDIFF_TYPE__) -typedef __PTRDIFF_TYPE__ __intptr_t; -typedef unsigned __PTRDIFF_TYPE__ __uintptr_t; -#else -typedef long __intptr_t; -typedef unsigned long __uintptr_t; -#endif - -#undef __EXP #ifdef __cplusplus } diff --git a/libc/xtensa-lx106-elf/lib/libc.a b/libc/xtensa-lx106-elf/lib/libc.a index bf519fd73f5d5502c8c15429b200069196195743..f46ae7bb3b0b8d3da2f36c534ae148ca77f056f1 100644 GIT binary patch delta 370672 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

3!$NCuv6Jsdw9P1!te~e7>eYw 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

3!$NCuv6Jsdw9P1!te~e7>eYw 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 Fs)sTi8=U|E delta 366027 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 z zJZrvUp~5r;)8xbW9578gCBRma1;X>e%Y^xQt`>eB z{HE|$Fb4|Yjy?i!75);uQ}_t@knnNv=fXdOk2@s)zkq-q*5ViNMM?BK_zz*a&s-A@ z1=Bji14o0yg-e6kh|c&}u(m1J1+z%Wcs7h^lX63jK%s5QcVLCKDf3loDjU!wn=9N2 ze3x)vaChNB;QNIi1P>DC8}oqhQ(ziWcoK8KG^7~$|0@WvgFjdBZD6N<@*40g;f-J= zycN7a_&xB;!c@ApM;`^RllbG{4Z zp5F=6(D{=v8%%x?t_`Nuh8L3n=AZ%O`e3nN=lR`ry_(5U50UVcr z@q7cG5PlatLzn}*aEt<`IS77Em>wXs!Z7|YSR1^*=KHTL-oJyj!JDI@y)7Hi_PAZR z7NhdEt8C-@r!xe+L3rWCd-8+Q`k}E@;}} z##FsFa`yn2k@#NVIN?#?D#GKzdT@!S!HE(-51cOi5=WrPkpNZPSeVLfF6;$sBlp|j zE)u^H+(VeHD)$Q?0uK`Y98CKXFW@NnLE+=zJcIH6|AoLLS;4VWo)o5ykv1r9912## zk>CZw6zD6$)xfU_*9Ge#C1?)ZEb-03?+de0<$!q>xGDtnI1+4CIVy<;fKLez0&Al< zO@P`c{xH~vvO7<795_grVvP`<42}|>296ibdjWxJ5}+#U2(JSt3wyzt!W3nF;SJzB zg*Sm)3hx4I!}*8cdnBG?Txi4jH((gf&GP>-1Rj(`C%_!9fLBAc(uzh#J=z-bfdb{Y z1dJ~R=C}mp2(Y%O(?LmF)YMwcn!FQ@CI;QVK$Oz3q19ZE%A}yyoM5B>q%4LQs7+S81P-f9H*j- zFa^{@xF-01;dR{Cea8zc=ivsIXy*;xe7pBvLWyI)qU1Zy+>YVcu+e;xd-FwM3< z3U2}bEc_mrHcIaEL-3!%YO6SN5TyX|mLYSf{CHyi2U*}r@G)w0e>Jc+_osmyg-W8v2sH7|-=A^b$3qx4>}XqEb+BhtHQVQO z)g2nD8h@X0H~e*7D3-xwT@OVD`0LW0Mf>Zr4qU)rmj&Oy`|EbXme-rC>B=J}>$|Z3 z8=I_Ig|ST5zW%z6xd&~r9#bBtA|~q%T%rASJ&4!-x&=(upZ$<;vSxv!P?Pn-lZMIq z(n-T)J@dzm8Mc>I?5T{XFw-0NTkahe>PDyXE!1OA-I|5^j?;#P`t#EnbjeLPlc8O5 zIRmj}jvk1wlwpqUeI`TugqJ&l%#5`z(#i@Wf5@{%|g%IxWy}$F1SbzK{_RP?z@Q z|0ADVHSCuRmtkP`@xg72s}&#IB(xhG`X%GmoNw2LsTg;|aPK#7rhkQLe9B~Q3}rJ< zq~VRLwrq~KtHs;XTVU8`!y&hc>5%)p>5$vrbjbBH9daxF%^}zSuNmrU^~}nSirFa0 z(ZpP0?!iXk{@?m|<~mHz+-zUZ+;Gz~x3TG&8-ux*;hDRyh2@$1x#5}XIN2V~7ceP5 zKnwh?~s3E%e6z3riE zXaaiBCfC~@y0<-asfpVjy0<-asRJ6WE5K4hzU`rV+e4Q+sDgUuZ4X`EiQ68!U%{lq zJJB6>=wrftz_&egc~@?G=-&3wHC~UK^w1smXl7v^x)GgE5z;1~E{Ghi(7kqTbS6D?KYu#&zj)|wn~j~^f`{((Ihpj(jh&mRJ#_h* zv^;d_UtxLZCUec-Jakvi&Ab&4-A`}UL${5}EX*)EM`ikW=sMNBX-4cs3wWDq;2Cl<`7e&T<=)A>5@Xs(4M*LF3vtx_t1G^I*E#B9^a48SwlE!an_TaxJEd?(-Idol z>W(lSb<6rX>gHVUs5{!%QMaBr>gF{m=&0Mmbkx1ma@1XKI_mC%qwd;#N8OLV$}}By zHyp{l?WlX(QP=ovEyR0%+fkP#x!aDq5%_}fPQWGowxh0bCvH3HYOC>WN8Q_wy0;y5 zZ#(MVcGNXK47VM1Z#(L;sC3&=_qL-hb#U8J_qL-hb@2ZuN8LZ_W?ko~8>K?Bv-Y<0 zw>$R3tbj>&CUFt$IBG0{6czz?N58=%xDEk7`)6E}$}Y=@X#oSI!yafiwz36pWr7{} z7x2LVRn?PK)Aoq>E>G4sPStv5OoDo9W=yCWTP!l#JEd9Hr#?fgCyXx^?R~UmRyN1A zu1lk)J;?5_*5_u$=S|@5e!zpWhtnh;z)o~_(>l&>%$9ZB-s}sk4q|6+dy7@XGu%;2 z#+u{Q{s;)+KV$ITl}K15*nVdOQaL%sp}lD(CN+k|wYOpib`0Ko7oCCax#zeQyYSlE zv0pU?@9jaWIj!T9TW57GQVpvX;1}|vI^8;JMR|t(Y!UUbaO5(;v3lv}%TYd&=*>1+ z?QB1)?9Aq+RD9d43AQR~N!zR$HP|`3wX+}oI}Rt|2<@FlH{GKg@1diUy(b;VdBRif5{WoW11n+^2 z-OFL^a6Vn`%9@4qsXGZ{Oo!Z^l_}#{WMeNFbG;K1bu=eQ>EX}A_jPfQK#c#-z);st zo^LPz2=(CIS&7MvTkPUs02m9Kft9Xd_>Zx$8Cd5U!ZrPkz(yCx8^BoD5$f38Sut@u zF%0UPK~`Lso?n zylm4<9^^;1I~%Aqzugh#E#EP#ZnQd((!VVDpb6_u;i>pEH5~Ebjvi_moy(i;7wyUAt{iD6-MrM8OGY3}e zI>`F$!&woOH8+Q>f3T^)9@VmDzkQK4`-zIIk0ADXS#wxqk@W%Y=!UW$iiDP|Px{FE z99he{g^#Q`nVKbQj?rhxdQVOQK+o{7-z`3<@l`UptT>zXU(W&DjF`x zmZIC>3>~8Adrd{F1rxGjwU$4caBEtA@iDDs-RM(5#t-n2h06Fjo+M@b?xd{5OjE`a z8K-63p4Y8q+>mRujN38*86&}VR~Z%YhtqWvV(vM)P%$r^>?3B^<5?Aq9s-t_y>~pG z^{nfENx|b@&U(RTI3i;TZJv z7Zq?CoO@;Ao8ht8;@F;`lB&o<#fy6VU(0HI3zHCRSp^Xv!c2t~U8?WutooRVV9O)L z^-Ki6@gnu?E8}=-#_TJrk^Az}7P~lpvo#Yz8(g$C69FeFv1THu#{g%%==x~!o0;)q z!(2Ni0a}w)*c=2$9xYx*9bc2>!fDH_fvIb=_WkorD{l863Lx}F2P5rn>i*7BYWKMFy(K1AI9T0oH=$O@r=)S;BxUuLsJh3G@Luewp zH+cXpx@aHK&EWpD==x~Uc|Ry9y0UxoMaQ8^3KiY=dkxWL>@!67={`$zb-0Cyj^lo4 z(bW*qB{YuIqVsOq&s;NHEj(h6jeH6lvafe!S)5oT2iS>xYWBh=<*+{D{oqJrwlNd{ z>Lb}NNQT+Qo;qOYt=z#ZJrUJqUQ>5}4lU5pmBS#t&3aYjK)qJ(G%v7jai(E6*de1dOt(UJ^YDHVNrPeMuL#@_WY6n^5 zraBe1T2;LR*=63mmYsGBie2NM%^dQDL)luf91X=%Y!Z*E6?=(mbbk37&y$MXACRpT zJD+iS=9YVT>3ZgtPF$mB2%e4SqIVa^Hj02VNp%JK2e|e@NpkzW~w*)(}x3b!8*Q#cWbxoM29-?ZAz?) zj>(>$|Be{>^7}E_KS1f_C@6bSS$}oxAx}(+BDmZBp+=G5G#)+muD&UoT|F-shjBcO zC?BzZi@2btn5@NmVj!_4V@xWExu~v|%U)5QVU!0rT9hM~0oK#%V##7O z674LX-OhGVm5I%M4n11EvDvyj&MU>{we} z?^AKvm{X{_HapOIa5xiu{l{vyV4nL>@G=5QC zt6*uILl{Hj9KNEX>s21Chd=L3U)K_@>1hOpx|Z|wdij@8PgaD+nP9Q&S;qA>60CIf zMHDp7HS1i=>7a22HoER*V1NyVdvmVAU>SYXnVT3VLFGS90 znZ&Xz>tz?!h)NLoMfLSWPj*rB^6VV*K5%TVI$tTfWc+w+VZX?jx0&nOIiy?QJG463 zpTXG#ZdjzcKjv|(&Xu$8v*oI-m9wK-Qc|%_W_v-&9D|^ulX+E83gfFfIr30YD!Hcf zar_TTBPTdJ;-&|sZwkR+%6`F&+7Ar5=&e*Gy9P$j`^7(6B}{7?tv2582%S?iK2&9$ zj0;tJa)Luu$8bleTG=BfG;ANX(^bIF)xmeFN2!%q8OBK>bUX@3uLVV^ji^z2Tg>-F z2YTz(&)()!yfMnuaSgNi!8m~(;x+Qx)R3}~F?q9a`SKdE7%ZO+b`6t4PASCtyh+=z zc~A+aG(Q`L^l$jt;LWu@8yp--ze&r<_-s_d&i(9@xxZYRP3(8$y7a4L=O9AHXXArL zc$0ie)^!`>O_Gu|JK7fd*|^*oZ_**v>JGd~;p)^K)|-TbTAz(r99n-i`1RsvWv#_c0$#6HbUMG$vWPLIcc|`rmFp59=lQEX($WO+mX4WTznVt2? zsE8Y7eKL%?g8pP=Fq!^jymgbGj9$$P{ban--1n0a)gs##@&C*xR55=`NTs73` zUfCP-OYui+YDw>GnJtl44iUINo`MLxuyRp-rZfeuRu9ASYY%$QrYcR*(&ZqbBHb4$E_0&K zN{GEaZ!VuN-Idhd4W-*035~p2t)7x?P4xLSH#eo*lbh=je6mPaU7S)dEAI3}zGD6O z+zOjlF@CC{*iloBtho4-*)wX4$Ng;WtjW77_05_%w9bmplVzesx6ee2e?56iQr$Jp zkZR}YR(8CH*VSF>oDN^9e#kXis*`!1%#OdGo~saRM)03)9UtIy=}lbf+~ta~Nf*UkZ%MXOeC)vAuU)7E~FJzA|>p4}+F zP_WUaep#+1$MUF1jzvt7Tsg#EFS%%@G;_-(xD7X!9DALclFM6>FF6i|DU$2L&9&q> zn~d@Ge{V%W$yIwbUve~;7b>|6uNsoOW2GUv<0~!6`R0s#fwbgKkwtPfd?dH`wOf+h zyw!%}s;{vm$59C_$zA19bqQdHujH%}z*}o9$rZ>8*~nu_uJF9D+}fLxT$iJC?7t45#V!Wu?U;r;!f0_%}Fgp9n@&A$yW8%lzrEW@-v1fcWX_yrp zXR~SUJ%h`GCU@A>nX_7x9FSPDKBGCn{MsfX_WG=^4pW+0-)f5chF@DgU8^QEk@=|@ z(4HitCS(*G&l+EE^Ycrakd+tq)_LKEp9|)Nap&^oc!f`@Fgcz&XXJ&R^G06y<$0?n zRGV9f{<3g}Ixn>0q>vY?=@;^ALfbFglKy61GV;N3n~S(q+ArDllY8UXtzCv?SATy? z@~}EHwEGqnC-Ouo!d1Um)u9oL(-yQ^zUoWj8vXrk$bha6y?c|@p?1F(nj@-TtsJqa zln%effdki%SCPMEKNLP5$1*M8{K`a*_a=0T7;RGvlOpP>nWOA=RqoK{tGtyjXOI1t z;$i59>S*B&-&!%+Td$bM<>R0*G-wpv@< zBlB_B%9raql-CXA+R0b0ySN{b>jAQsE32=C)pMqZT3OG*VT}2>o0aesn2&qsli}sm zdnG(i>3V!oq%2gugCjkx$8U@DupWO;Ne?IG4xb*bC*|hwVEV&d&*#J4#D(p!#eZy{ zh>Z5o+PgH`!%4ZXMtgKq7>B5~3Wm>6T@hQw`8nea0~o9 ziC+l+8Ll&&Y=J%oydWpr9JK2UM%k_oCxf?<5WX|aKXB4W*CJK1>UsP^PO5KHJuAvH43jMF(~evQXp*IIwGWPpL@U!Eq?2>gp})%N`E<{W zO0*p6$_s}`Y45Cpq>iJsXLfW}H3S*1T4#7-ZI!*lGCZ)zR#r17mWYj{p^-!3MRK!9 z9wbt!+9P4zuB__ERE><_CBr1kTi~Qg_M~c?1tFePC$b>KAu1~yLga1e>yjLjfuXMP z*Z@KdS3|QsiCK(W>>AFvzWxlXbk)Fr6c-s-=W=sReQ63_jm2&x!lhmDc$!8m z!Yjx%dWb&M2E@HS7W2SH9L6zW)%(VGW7=nfSOK!P;N=Ce0%UK=So0Yk0fg|MA!D|; zQO5Mlanc5AZ<@fQ&b8!L^dYnR`A5lKB0J-#Nc2k=$oPnA+7&u3qrU6vnNiu)F`tIxa8*OcW{rp<>FBJ2 z({LPj*wnM#Jmqa=yzg{_ke%FP8i#WhkS%N0*F@ z;N^>?{V3@p>bZL%=_BgkE675ccK2ka3_+6CuB+GqYDO)MriM%&y@x+F#moG14*Q@iL zSuBi&S1tNK)S0V+QLxYU=oaPedZ^_UyLxv;Yzft3YsE1tVXS9Wex1xHLtGi_@o83T zZZxaKhYi3U?eVzvEJLWMhdt7uwhL$NQ~3QB$$~f=hBT;gyv`dpsQrqyEd26no$c|E zb!nn2xz%?_6THuQMG#% zvahRte$*&FpYb$+6T#buX9E86xv=Gp(b6>Z6Q==-8donVw5 zW=ueq%>(px9pt6_t;y`Y2`D=-!F5e$a}k9sn`>^+WTt9N^u*jmV_Dyc$gBU}ShjK^ zG-@`MHI~M*I=CICwbT9^PB!qlL_Qs3)YbLliPf0EY&)Y>Qrgb8;T)yyY+fnaN~4`8 zuz64-+sk5{%prr4a#h46PgF8jS9NkEio%-BWsHi|}nQ-jD~VchkkfP7RwiL{6IS^O9`ChCyYR(ySpa!#%ojk^4?0 zv}%Z)07SneMloI&xm)_USlq+?X=@qhu`ynf%$MUm zB!|?d#YP#s^AePC_^?|W)B5QeVpW`>t|4~E39^P*bScU>(pJ`JDR%PT3*6z$i~{$f zWghKb@hh*XyBKFj@QAu{$cZDtj37 zJHN75ygY?&+9vvPe_DCdwDLypEU3IAJM)#tdB_V@-qKx$@-FW(ls9*`XGTp^d7Jsr z#5Pe3$J5H&!+5dNHuIZp`>K@I-?%-uq`ww>4gGz+*V11c52f|j7B|DvAIDL(^v9`X zj5=WdeID)J^C!<(*8y3avh)|hPk^oi?%__gapGp(dy4HZRDSLDTk=)X`THbG`EpdZzrd zg#vDrC|fW5-QM1N?t4$O>zxfco%FCN>jaJn0i!7^{YNd}Db$XcbsAm(rhsWkyI#Q6 zn9>yRKR0D{MM6u!PvFsL0nZ}qtn-qOajihxR*n{M(5Zp~9&{>Sz&C8$O8LnU@YJ6? zx;1vHTG$GH8Vyf-3Tur`!O3bZ2T?}HFVDXGrIm?>pSdLwA3ke{c<|4bhzodCa&9k6 z#09)6txWXt&z6Y!sk20!;45M&Q!{(D%G3;OcfEI$7Pc496)NIy&sicyGgrIwo-h8n znag|lk+dsz?~&k~^y@X4TqMUwgWuUyNoS6D0=z_JnHt)A;?`EF)81A2yXKIH?Sjgt6Z?0t3R-KO53RS`5vLe))Ex}>FAMmE3 zIV&p52mD4Y4!HH@{lcfKh-+EVs%}_L5V}} znSkst^+?M*g2d~*fI{2;t3s8hc+Sl@2Ru|fr?3zF=HfZ|7B+945;L!Ti)ZUsoU656t$7R9-@smwetd(P0AOh%iE;co~or_Iv6>gu{)Yvb; z#~5MQ)C?7yHnop&LvCzSn}m%mn;JdPwM`8k=sq?zP7NqFwO-txwyBvO=rBfHsg+Z} zrq-)=j%8D`@sSi}Q>$4A@;a%;)qzGUtC$36)HFsImZ`(0QH`!S+Nf58IyoM$4kYBn z!l-sWA?KEiYKPp==SkH&F^5LAjfpwhs1{^Oke}?KuE+6E45Qk)#2jr@8^btlRHIKN zzU)lB&XvYB+NgFX1KOze!%Z92<|ILRC$VioquLiqP@ZK}Ynq(%m~D}Fe{xQd;{R+f zFdPa053FTgSj&7(zpc|FgY?UV1vH&fIoI zg4ACV%ZGSpw9Q#kboQ1-32J3PK(zPa9y!B(+-Ab>436@K_06ejoSsqWu?MANPdGjN z=jk=)ey#qbMHy)i8eyJZ-+nneab5}ib1Gxep?}UDSQI$E!tpb_Q3GztMyu0_ z4MM$*#^g*5$hWC*8g=iPhjLPF@aJc%01i{hI0bzssb*vco43&;IsJ7`xqJXFlm~3w{R+hny;P@**+SJjgGxtxPtVUO=X)vd2D!Xd7vwYz;6smM9%B#sm`4eAEX6@_ zS2<03{t59+kYs^zLTd5CoIm53F+2T=jK^XUqMZx}nqfY4=K!_krJO1_x0759SK*6t z$|6*IQBDsmW-iLf!eZZ|oS5R>uw|t2Z$Hiim)K2homjq`TJ0%aMmb-JF7BQ5a?S@4 zwnnP)n>lsD?nfG11peV~uy@*FROdDA{%Dhbrt+1T&-2Xs)6#;c-~vCn36dZgeaM-PfDpU@13B0HR5Zj zyyG2OhLQAwS?|?Qj~(w2QVYlO)0Sn_(B*_C>qk#$vi5(~!LlhtUkV8hXtQCFb#;@h zk=o0Z6{aU{{Pl&CcA_3*!uPSEI6NXsJ$;iWQ6-$}a1**(#?77-_2{V(nb!^{^Ym~s zzobku_k7dA(j}8`hL&Kh*%p?OVVPvE?)c_{Cb(LUe9st9S$gC@z6nt|mS8u0+ab}0 z>)oe29QUY6b5j!OPr)5W>qncLFOS2#)jh$C+TGRwT2V$A)|-PQ>nCCHdUKG(>&-!e zqw$(nIaQ2@*4RI`t93ucCK?svygS3T3eR1P(f_+j-eyrCcPDPb{P~zorB?OI{P{G# zzRaH!Ice59X$LuZ*rb`$80RSFG&OjXFP&e5_dGI&GS( z_Hw$sHrbn$!p98t@K|2(X$D4n7N99HU4~-rlVoqRwv1fmna0SWI>#DMM?`^wnX%aK|B zTWsp7QJ25_*?LU0N}mC>T@9mp2k)#(VUxlaoC(IB&fXKT#c|&Fl)gr_YrU&nrQ+%h zDG`T`k!XB%leZ5s87vvH^c+rpHkgWX zONJc7ceJKB(HAY*JZf#C72Ru73(Fq({Yiz(jTb@##CU|Sx zl)8C>w+$}qCU`x#yfneG$5iLC%n;@FcP*d>FsQFj1{R3uvg;X>kVVn zQ+E}_8wc<3F8iCQQn5vx^3JqF{~g%``{cf9lxSoqZ~w4SVf41-M78aH@1aDyV>+G* z+UFz?)2BK5;w(@PE%PR*7ngYx6WJU1R|7xWvN!NQW1uD~;;v^ssjF%{#Oqc&S9@=29C~IZ%EB|B*B56uTDY8m^0BLHw|KkP;xdcE2UqAH7CRiK-Ep0nJ7c1HbBlKbmS*1Pz4cNi zA}-p#OaGsZVycd1>4O;UQkB{}nyN|ds|Af;pZ89S)9cOxy1&7uN4M(R>2kN4`Fk`L zpL@L1!#Nt)Mk8#lA9gEK>T#Dc5N2b}G)od#Mpm!Up_U1wF zQd@6h{^^UwFG=D^UF}z4^A`#?4=PE83iTFo_**%sB47t$Hz~XyHIwv`_1k zpWp-R&Xy6Xozqu63bGP4-0ACY8?FvGeJLpFYo{;W9ojx5ZMA-8RH7PNF0Q&UIo`K4 zj0E(WwzbC>wz>0nb8~0)UEp%EsC@=dIKDRFgjwjZga%cvAdxs}AS6uwOTOHBnLIaY znv?wp6MP{dcM|%yEL%$$EfD!-sf6IC_QS7N(cUZO7~+CJa<6%~YN`$0&3 zn?SUkIO!SLVCGIhE4iUR`dNg%>KC)ADR8SE1NV> zH&^#Hk@f5`zHwh+_Fg{PTF-vL6pPu9M|Cu_f2X>y%!$6(FPY4~5p!G2o~(?_UbU~` zyAVnC+K*#X)Gu9{l*Q)1`#3gPeNe*}=0D}Kn!f%2?>Gf`({9{$xvzW}vFj=SBQ1Rm z9hlir_=+ii|46m3txu->+>9+#{<&y!neu-PiYPth=WbA$^5+wt*J$qw6d9WGk7uDG zyy2WBH0A#=Y|6ij6|<)NJk-SD!Ib~L3}5(^e{nlsXvXiu4Q0;w_p}3<9#+-cgWi+X z=Jr0zX0ILTKy3CRNoYsSC4knme}WnKs1D#ZGW%cIfyDmLXa6_&K<$T>&F||WmU@+7 zq6b1ZE%hQv+m@vs{Ro5>1TUC`j_SX}QLyWW*1UK@{tp&j~OtBUOG;|0p2v%R{ zf}mNZudD^Z*i4_bAP_seC@z+w$6urVlj-YbyGG?@`SP(=Sd`_f8HIP<81Qwd#`-j% z{gZPFXFf4~@hKm4YwN!9xxR!*eAN26zOHE53Aw(uSYbSu>sytoy#HyDSfrN^6>t~+ zrr>82td|dhmxRTy48wXoA$fL&#UBmBdOaa|^m;Z78t7f1m6OPnI@rN3`xnnn38i2eP$#kcLyhcM+DTD6MS`S0}S^> z-;tQGv5nH=nCZT1VdI_droNTF9Ini1zJ_iZ6{)5@>Z{d%EQ_U#Rk|s6mP$7rf!NaB zl*q#(sh)eR zxLw#jEVa|#p8qwlDCV|Pjn4GMR zt@kyvjWyz*_AN>IYgN~Un#L~cN~`ee?sd717H|5tg)ODEPteLA`|8qpq6c*V)&2+P zj34vW>Nf?oi`q+CG<||PG}R7fQyoKW7}dUyI44E#;ym#q7Ia?ciOZ3ZR9i`HJLdD$ z--4S#w7HsSPxG1cdAsETbb=;YxB!j(1Vqc}Fm*2QMmh8o5G}*debmFHOkauVpMvyG zs5?Ie(biXKpMhwXsHZ;z(VEUauhm3b3Aguh4JhI4)Ac!t_MbcZeD@0w?FlvPOAzht zYR8wpq+~v3sOJ`wXc-voS%~U`Xe+57zQnYMajQIcGS2db*d0-zS*C38WHZI`hS-$> zI`!;*9Mhr`2tjW27fwCzI}Va%Hc_*RQ_myEL9&)p&yFX232r{C23UTCbJIF?;|X6q z+d8%6gzxe4yctQ0@%@}D*Qt(Q`4W&c_$%Km+Z5x>SH9f||E9mh5mEjx$`$im@>ezS zSmS)I@O(I6t(d;rJ(A2+=d?al1;5?>zC;qeKyHB5mh`+ zG(&7ykK2zMo%9|c+X$#m`nvFyQ!5_hGaq3EcAEYBJ@I_WNm zabtXjKYTi;j%N5n^SMaeQRcYuL_0s{bHBCob3V7Uz2BP8ah74t=UStN)_ksy?vvof z9Xt4~`JAe`Jg2-duY(`%9{>5Iu9MHtN!>A@-g&?BgarryxC0|811>6 zRn=17QGUNQsT;>gYf{&YuWwE2S~JBOTXGq&q`b)&I;pFi=`U+icY3%hS>2fF_uw_K z&7z&P!-Cy4dUUdSGt=K14HTE<&rar$QYqFNar9tQ=P=@;Cu+Iyn}1_RaiN1t*uIM; zf2714iM{>R!gkVW1znduXn4?jA|4NVhsDp)z81ZIN-8#Y(bDF%LhzCk9HqovP-5 zW(lfUfB#Ht{}DIPl}Y=D`)k@yAE0S}{{TPdOuYyC6ZAI4p03^|snf#8qx!UqEQfEW zl^4c9-1uKm`qaUi(yI>fbILSwh(9UKB&4KExj{YK*B& zwg|i@-_auQOr}@_-h}~+z>_YNz;lL{N#HYv`mI$9Nc`MTf9*KZafB-k|C|xYM#EwL zbDn=^TI3#_Gr^%6w+*1IjQ~f5<6pEVI9X%-&U$K0j+ajFl&mb{AqJo`csf*(Mo%rdB;aM~$sN=l6 zEnkg;yHoqWkBClYDXq*WQAq1-Z9b{HBf=ZuY{P&%noA*PTjGk*^fT+sAdZi|lQ*{` zPKVJ27ClMY#Cw?nO!Nig07&uL~*bm^uDS zp)7fLj=vE?2j=)MakDUc`98N|uGCva&h=jwXFiIZ&AH<-)qXDeac?!>N-2mgWXk(5 zssnTV39T{_=oy{CdVRvL(JOiw>;5SV85mK87dnKC*Z)`{a~EQ7Rehd673H>{=Wm|O zTopZ+;=eO9@|qZA@^IIrGdr@knmNy(gnW=zj-+`&p%Foxt*ZEu(EZKrQr*` ziljt^e--Sj@W0Al#C}&YJEOFf67sysJiL_~c#Dff3U^d#8caiq{?w5SqnhbDLY{mHJ)xv8KwgpJXi77>vdqOr#}P3bzrxL zhuk?wMDnfnLAa0Sy@fjIS4c9$Jmp4*oo4uq4l83JSQ}rZdW35r?rw#b1r`0W5Uj1D zx^$7h7T&k>B7e2I=KI=j#FJuLus!VA$RE|8GW8m?t&DjYS?4VBcfsY8MSd?XwHNz` zLe@WXu|FohgoXhdi1QjGs>j+2pU4prsx(V3X1P z49FZ(50$&gU!&+f)WVs^MAL5f9o~E1z3}8%9MIWbu0t$GCa@n6TU+7VF<@?mpUL8^ z@jMSyM7amJ9@mcW%`jb^+~mJ9d{=zHz*LswIQT$AT*|cIt@s>zGc0JI!*E`2@n$`m z&)w`#D9<6Pr>irb4|`pkdT3+Csw!nlm2$B2op-aNs`1rk4(I=TKm4ZWF`OS)xm)#c zzGAE2GTrS1s)PiD?K0XU!+AyZ)>eP>%Ne)IGZk-yF`R)l9`RShzy?nyQ!LY68N(~8 zj2HYV7qAh2+zTLaGUJjqyDz)|5)awzUb+pVHy38s=v~j~z0L2mA;+K>{g2unR_^Wo zhG-Tzlgl$EZTB~>`qu;d|G>0?|VVP*tWvDuroNN=Xn)}~%!3_9vRP#F~a3@8H> zd)lFz{>N_}9iEE{+x0HMs1FIvqr*Q#?{t`g5DtlQba*UcL(4Kp@H6Ch21y15dIZyZ z_6iwm9*#nVPb~lGt?^&tbYieIOe-`%$*QI{Yr&5;{735VH-4Oi{o7>~EgI23+N#E4%2SkqoTyjN`4tbYO#r-Z`SL*MY5` zwM-eV1G_y*c6Gyy)>YH^O&~s*i0bb}i|KEK{qGEapu_5+bD(%;6N;|^rj9rG{2VC$ zj4Jx3O*>q={Q`>Tn@6}(@EDvOuI@xsB*a&%fAJ^Vrl^;H@&Aa7FZ>F-oXx8FZ~ps` zXuSTLzaY}Kd1FfERZ;1D2%g;@m(3NWF7?gu9xIG*$@KSiSgnZ4Tx*-9I@&WcJfypQ zFb0mV3lQO3hH6x(+DxsmXSTq1c-x-25f`h&)wdbHL}yM+a#nySJu;%5O1mNZQMLWn z$avMd!6n;Ng~wZuGw!ODxvZv|yFaUyt*7ek&+KGNRcrm3-`ZBF2Qm@LP^U68Z?(Ou z-grH$zM7epd5LYkN;?Sr5%F8uBdekc zsaL9-UmEEa3(N^L&kRoo-MdL@KV9-9V-NLo${pM zDZm>A-wnJqGNMQqGz)=OBw;!5A;DaNyeIfMV6N5q;1_`DJdk)F@DG9y0skhLBYYG( z9`k$#94q)+;0l6&ioi^V9&DJ28)vvJikb_)@`~uG1Y8^K;~GEw~AA z2f<`~*@C;M*QZxZD560_4~e=F_&UMkfd>hm3Oqva-N1C{%E#ObJWlXz;7Nk#0#6q_ zA9$wVg~0O#E8rzj(%|fWD4d6DNgA4 zfUEJN69D3V_;nXN9Jse&I&7dTIp*n(mnx!TBnAc|Fj_Dbqqhsb5ty1X<|zWcSMU_z zMS|}HULly@`cc8lfY%7-=jHr@<*WjJ&csC#Pawek(@b~)c#mLy(>Ddb0{p(&xVLAf4B;g+51A^xPza^O8 z@ngX|fIk=f8t}J*4*>rx_zhq?<|r(mpRT-Me!4`#pWD&@YfIob5}FA98o0G!e%~y? zr-3^O{vNoyV1D<0g1Liqh+z81x=}Dc@9lz zzxA_%eZVgW=68QZa5v!ng1IPpS8#veV}b_(pDdEV2n2o|t1YQ6R2!0W`i(pDZdJ5(tfBgl& z4m?6I{o33t_&wk|1fK++Ciq9-*@AxoUg8w~{~H1iN&<;ywcu*N>jhT_-XfTELWu}l zg>nM=BO`7F{GMRa%n`wPz{drXX1*7Ebu_*|eRuHYzDS71G?sWIuv_r0z#hTlfl~!f z1a2gF8gRPcdx0|q&ja=gCM^{Rei*n1aS28YnZqQa$F3Bk`N8tP%tUIsbDv7OTi6*GX&=X`vsE_ za|MqE?kM;s;I4vi0lr4?Cg8rY!vA+5aJ?kF3Oq(IPk<~EOv1WLFjqmd1s?`pB={)s zGQpn%KP>nJ@DqYh0p^I^eGa_XYk=@L=GdfHnUgia->sEm-Kyz_EhI0#^}y7jSjKB);Hg4Y4(3nn3U6Z~8Z`hOn@yo7{7f=PTg2tEWnPVn2n(*%D6JVWrOz;gv32fknM zIpBu`{|5Y|;PQC$jT+KNZ{>_>^ET@L9oyz`qIZ z4D587t$P)4CBfZ*Q;HG!04aB@;KzX{34R)QhTsjra|Le(zF#m2_hG>#+{Xp)1zsok5b$$? z-v!?368`@g0{bMP8k+4L!IuIb72Fy4E5Ut%&j=m>d`|FiU!A}5t1(UFH1g`@w6ucg|tKesVuMxZf zxF0e3|0V>6O2YHNqXh2+9wYc|;PHY#1fC@L1n_jhCxK@Q{sDNt;B&xB1pf-WT<{;j zMXMwbg(h4rI2w4p;27Xdg5!X<3a$YBir{$QHv~5ZephfF@G-&n0e>y{0pK4@Tokbq zfj=Z+HLxSj{2Z?Uy9LKGT`<3Cb-`7EYYV;{xS`;2z)b~D0B$RoE#(vZ1aNMg@c&Z? zbd-eCz*h_Y4S0aycwC1GPRI3T!BcRZDELlX?-G13uJZ)X$5jb_3fJX=zbgWGLIP)S zeO9o&Jm%+u(|~sgz6p50;9G#-6?{AJF~L)SzZCo+@VA1G0-qE732+2{n*Y->)rkOm zL4Dvj!3}_`2yP6VBsc(EQ*aQtuHY+y8wu_ToG!RKaE9Psz&V1)R6zePkia}7bQf#@ z_Z7Su_35oBIXhC2PiN>pWemaLyE zAua2lw>7hbtpDuR%#f^q4c@R!S^xGIGAZki-_r=TveQtSAR}VZ7 zqJ7-n%jJnu`Cqk3LOw0wzwbrdioidW@DJXRNeTZ?J2Gho*?DJXQZk=2)bl8$A$ zHHTW9KW%4b^UIlGm4^mpA#wgk3|Qj)XINcJoWFwsi1XFSotY^YAjfa8E3+&){>WXK zVRHP#yD}{~ekRJN96xS%W=;1L1fpv2Q{o8sR=YDNK!(3@cjgIP9(*bDZHn^8zMNS; z8bD3omznOREFZFa>Ji34D6jPj)T#GDd<8oxpn`oc{>L!lek(`Ch{St=E7+SEXZK}p zvE`8}o9{*;t~$JDY!xgmDCm!9{thei2=QD-YSqhiXj(mhN0i&dl&3-|o7K4knQ7&y zq4=1Q%~ajjGlM$ZJf2}=-0PXi@lFmckr8!EsRNAlqqDy(XH+_!`DA4^t16CfKNy)+ z#}==~&Cc!=`D-7wcXsy6PzTJLlif(QvLk7dIyNV}zM5vw>Kr|HD(YB6EgzdwOZ{rk zx+F67VYTg(G|%E&Qz|;VEg}CR87b1B}!2vn$$+2{Bm-Hd||BVQf}>wQgETfT4qbT1g-nFA-rA zJUa|84a2L#@Ka%Ui}FoKNl+ttT;{f&RX4t0J0XdxSgSa#DUhNsQ9F8EmS7C6larAz^_HhjO8=}ha_PRn$6NnP~Lt-;wdu!Oz=ivOGoh>Fg+vi0lR^J6#NSCuYwN( zb6XMfybT;9_&sjOEH44_p?JZ^fU61q3^-LV_Y>9=d=j{^;2(gS3H}MVmEhlj+Y7ei z;aP&q0p|nj84HZbBDzRIMc}IiR{`!T*aJLRFlGCe2BQY>O%h)l_%^|Hf$tDpA9$MJ zhQKofU&`-4R|3tEaGziw@I!*LfFBo3`TSFYdjQkLHJh{-ep>}|gUe3A{efQPc zPy2rGlxAdrf%yz?(lQI2zc}PS7q+ zv=b3=z&j-m6?3qYGgX9iCG(afGzI=Za5nH!!Bne#A^1ArlY;vJpA}33{Y@|puIYS^ zEi@LGeqxEKVoMY}AqwBWh6L!`w2t5fzzqd22fkeJ3g8UEj{^Gz8^E-F)u0W`L>?iny6TRY*{<8x`v&xH9myf~nCOB)BHT;6A65Wgw}%30DA>T;GsE!9l!;GsrIr|Dm4G>De?T)*9qpg z9w^uce7)ctU`n+sbNs&=fw7X%3wV-X&UB{>raEk<;G2Nw3#JBRiC})~<$~`9UL}~{ z-BQ6&Ik8^iR|9XN#G1{u9)Ycbp99`0nBSKobmpNJ;*j9Cfhj^~Je3Nc3jPlGE5YZ0 zPYaI0^%ub|Ty2ow^4_9E1Y8nG2Cgc&IMa@r{8S3%(4vnc!x?mY(KvU`tPv z0bD3~IstbT%+CdTVw3-mK!Eae*60Rc%F~H&1Rf!n>ad#x^K;!Mn4fE^;Jbh=UCu&a zOP8a7EnUu1;8l`;nG@fCwFI6(!g|5a0b7cl=Ye-h{42ngUS|*R0f~PX_$|Rlfh`@+ zH^4_Fo(8;M2tEgVl9>FTDzon;As*MC1SjAciTO8Mq8f0F;F`cy1YZVRO)x)2s$eg0 zJ;9m4jRofcHxtZHQPfHT*CNnfaBtu&!2^JUg85k}e`kgGS-J}z4@{9e<0k_57fcl! z#q5kf2s}zK6%V2lDvEdyf$@^SW}77VFz|H2Y{Hp>shyZFn9aFF@VCIr1>104CAcE4 zs|Bavx?b=lxNfpER*ev#%$+q&$CWa7;wy07FE|6&w*+^<^#j3OaXl)S>aZ^a_rdj~ zU@9KI7t9vu9nuRDzK?_!ZaG#QaVwswiiEEnyqtC za9vy}>t{SQA;&aE|8ENLwIsB}mBM~zYK<#=u4@b$ng1ygm>&eB*FA&@Hxvw$tF(^6nd>qJ$ErFGg0Y-ycd1s*E*z6U%?@NwWV zg3kbt7i`DXQbrY3MPRxlu*S0lH^p_KU@xxJIPmRz;<`d`A6y?5%*w10JP_As1P{j5 z(o$Uyyi4M5!ga5uv0^O`O2TAZEsYgbV;@O8ANq;lhjBeF_z_&c5&R^sX9Tas)zW0K zGL&BM1-1Z33x2@`$&IDf+Rhs#;Z8dLPcGFoHEyS| zqF>fmrL4pwo3&6o&X#XrTV}vYd`M-LaYxn=n2N8*loR6PZ*bV}9a(>ED*g!u^*@`6 zI}ux2eB2hx1Q8!=Iq-SK$22|)iI01Pn~G0Ddxhl3T!M)Bn39H&_;@1%T6{dND653{ z_~W9ikoY(rV_ccyny#S5lnrCNgI zDN|6$e<4WjI4z5UH>hrs^dLW0<{+=w_iyQaen^n?a{5fbww2)a0#$UCI2i8c$UZ zJl@)6q^`@lLF~u7n)c%#IqxXLYvirX_hN+Zq~?cd{L% z{dgmr*p8ouKvitV9od~AzfzN7Qf}L2+K+!8Za-e#v>*4H_TzO;`|$$Pete#3KfX-c zkJ~bgD-UJuJCD)0|Lv^*M~uclau|J2XZ31y(R3U%deL+ojd0O)JRL&~rwkWO$1j?W zlMXJLj$1O)i>Bk2{PUve_(juk@`j71<9bAUzg;F*G+4B>=5b#D<&( zMx~Vi6h?~@;5I@_2|%mtGx!xdjOm8ELs|f??<^zopNK6ZaxQ^I2|#PVkP_flO6Wb1 zFaH+EE};Y%keeM+0&Ky{l&J)0oR>`{z@)rvDgjc0*_IOE22{~f0??AoQUY{lJd^+j zgV|657~ci6aeC=LHzYq)kWKmjz`|@Al5Z`{whYM^hYR~@IX==Yu>bvz*zpn2a^fic+;|c zOvtjl#mB7HBb!ymHQ7lOXhyy^%#3{CHQA;a`C-$He9kr5rWtv9yf!2M^qTA|{>qGe zPIWc6D!j~S1M)iBfE>Qc_RP+H#a2N3@lLk6G#$Sc9$v1V3*+*prmeWzJ~unwCWhi& z9}XFc+ZL!a8iWrGHxi#=8j0@=Hxj?wG!oyN2V;dWBk_f%k$88g8nuzQ`Y1Z9vF+DI z{pxG$@cNOk3r}2>UGe`FyYS;rWnZ)lx9kEznuoyWI3QoN3%_U=PCB?~7k<$$oOE!} zF8rchIO*V`UHC=2aMHm=yYP#4;iQ9$cHtN8!bt}g?ZPkGg_900+J#@V3nv{|cHya~ zvcv7d57v)OFdCfA?m#d1JaP=@PF0CigMP}c)o(b&5B3jnuN*bYLptPe@mmmE`fzdX zyO(oke`P_1J8^$RjE_PL{9^episi3BM)Ta+Z-2`6)L)5s9Lho8;&SdRUB8CT62FQv zUz|Iun*R*hZe=7*$1nDfTKY3&y9`IzD$%QdnP-XjKL^?FA+_loWV;nrmtV52BWB^1 zA;LOKoSp%!BW8P}8rBiBQ^Jmz&G;1sUEq1*iF{SK1NY(b0|b!z)lqDwy3tlHQQdp0 zPMm7-d-fny?7rW#dt5#c`8st)b&)+cCvDZuUi1d;rdjt@lT^b=>S@ zjI+)bzlCivEb<)UHh3tLg)4jpwtDgz;Bm7!ZT3Qrn|%#WsKj@HWAMhfaI0ACp+yyP ztnc-0LQ;N8+T#i1b^97;DGo%>vuzN3J zOVeW;<}6UG6`diRpC0K`H+0xNH~U+M-LEI^xH6)yCQ$Al7XqEg@~#?-qTP0T&?3-A zsW~MGbY5ysh(OEpqjVy*(pf!yV|2n(LB-dk<&Z$vrR9)7gSB$3!|uZgG=RJofu^Dw zAW-#tt(;Wcacr-%s`4IeSKjc~&cP94|MbNB#dULd2J-y6ITk(E3#Z2xe5!T)af@(z zT!>cC^jM=_PV=@Tv{jx7jI-!5pRfLx^oZQMJs&L?9rUD;+TgAJT0G%#O>GD}%`kUG zqQPE&vt5e%xL!_KXCOQ4hmoebwSH;ZG#;y;Gx6_8N?mou1l4C*0Fy%1R0>p;2WA@;Fz83vM+Y25hJV3%Y z?;&?|y%0L|i~f+UGeWpWKXk}l=b8+4`V8eoO=Ef1At5FQ#UXds1wf$m#bO@%rFI8E zpbUe9*21OCgT7|vfc2VeE5AczW7Vf1XAtUexI<(E^-V!e6CC_iy)ef*D>Z16BM&AT?Rgw;W1eT%r7*`j z&u%Uwt>eDB@J+4bzNpFz9rx9T0qeN0niqQ9*N=rcWu0f&rXy(4JjxE2)g3{LC6D|1 zpkvM*|K4$5-NO!k#2H`JjA^5D3P_`M@Va27XKiZ#ji6CIsJ{w=5++I?Bf>=KbG$SY zy^1+aCVG?wop(^@=9&-_rN3{BiS8o?6Ghn(_RC14!bBIdJd242EGByYO(mJA?dD=8 zN|*O#GSR&^YbIJ_jAo)+#+1oK`=W*x6ZNASWTK;PDQ2R3H^x>qHs68)=pQptHTqV~ zMI&zuanVb|xhTD~hq!3lGP&sN+sfvm1NrWM&qaT~KrZ@PmOVvv8doM4ePA zW$PsQ7;`#fU##w^pOaE@v^NsQ=QO|o^h0E#YC0?Le8YW;!>G6@XGT=9J3D<2-IgUL zALUV3Fh+1is@(f5KKePS(L6k{QZXOpj`h-fbR2Vy~v4_=;#+Ox5J(uNp!3}U? zXp(wnSsRV#6q!PQsk6nX`a?$DBJ@(0LD> zo{Ws7XdWcu;%N#NMbpKPz2g>?0N;x(%$dPygraU`dDaQkJUzleyP5lTgQB_odjP-K z6N_I0K{JSnK~-GJJb-%7OCY`zs`|@dy7krOmqErnzR4ov7AU)`i$1d)M`^p#(-lCS z9G_G&j|6@3(zJ58ZF^&PRb%BVB;$X6AoUG!YMr z^Zc+x&8anAe~H-AbWI~Lp=$@>dFlEQq=xAF$1u94i?a}2UlT^x&$D8GqU$E7OVG7i zc)FOdgSewi!tVW@ChVub(}Z34J!ZU1)Zy=Q65>oc9w~GTcAP3Ctde^alsB^f!xh*+ zr{ky}a)gc>sBJ%BntQuC^+S$zx_Sx9JqTg|1Fodfe$25>SEoZp@L!X1@8R27luJW4 z@L!X1>GP44t43Z^a3QCwzltdBnn#%q#kA)Wz}HCCU^d8X?B z4w)*DX;%Y`_~9@ftc3`b69PffYB@9kX1<4Q>gvQmt%O_o-t=f^uXrut`y{3M*Q)QH zXjG->04r>=-Iatdlbi|}8xg~oIf7p-|7i)utzvj80hpl z0*(nR?y4z(Zo7lt@*JN22*k}oJPvJ~pt@gPSYKV86lhqk2BPNU7kfm_N(!v5$1vD1 z{m42xF~E5R3GrG~LRYC~M8(-^a?8R*bxXBC3)>O3x?13VTZ+m_4$P@XE4a=sQ<%^| zvt(14Kw9YOx(roxd=hO_f7HsUsw$=g%Hh5atqQ9eO;ZBk$ti04z(%R@>7a{El0Boo|Yy{?x$;Ox;Wq2cQJyts z;a%$Ek<}7Z?vsAET3xA9qOGzzRijmck@0e)SM5e>zraZd7Am%HWz5Y8RJIk*oi&y3 zY-dt=JSqYz|K6rzI|OPKX)33WMWJ%~%>b3-srJ_p3yw@lUNpp3n&dk&XTeHDIX~nZ zotNZqM@DjFHm++w3(c#GyCPg~6I&$T%;dBvR;#=$+~@Zh^!MpNSH92WK9#b5Lv?^3uhXv#AwgM3}~``Ej!RGgORH|GZ<-+ zbsxUGMb<&4T(9rl>baVM;X1I}V~bL6_!?Ec0J^>*r%bwjHYc2}YX<_g^{^J51p-(8ZxD0KFg~s4%3}uxUe~9P$Kcg*c=xBg#5gvh9+5Flj#0 zS@cQbj<@l-Bi$p}HYE3`iatWRNsX#c7@dt+h%*KPJMB@y-MGedV9tW2g!@obRN-#+ zjEGqFiMQ}8$A9`H@zKcXiiryRiU>E)p^Gw45_caW?)V6z!QwAxpwov4IHs_?t8OD~ zrHP#fi4O^+*5xV7c6TGjnFooxCm^ed-R==)ysEg#o=`-2;&l9UH84ETWWA2#@;`8K zuVKmNx#4a+8c#6`)(oEYaSc!ejG30Fpmv)bG&kx$A-Iae%lrB_MBlS2}hSjvtlwl4RU>Nqr@&kY|MxD>}=K0Gv_&kY|M2s=02 z!E?ih1?1dt_fM?3x{i*7}us}j9C!W~Toy&@S!nW__?!wB4 zpBr8sZxFBlu|o0P&;#RfZus?qRFvEP`T)<|UjLDYr-RSDKA;Z?zdoQ33CG3BR>J~8 z?WCNs)9DO@2*pA^os zw4?}iqY)cliBuJ7QW^C@XumVV1I=|+?4BCxpb=Y7bsZ5%Pc$=DJLu>cc{fHUPal3P zeMkT*tt09oX$T$FE==86Hdd{1Q}96KYa~4pUyQ z!%iJ`Mo?gnSB-nam7=1`H%ZXVP(31cAj+jG32DEK1T%U|r4Nka!Qqq2H>p<5Yy!MA zx^N4&Rt>r`jZVgq@6$$UqFX%*{Jgh%X;fflBHwN|e#!XRmMw_IVHN`-Y}fWy!)^%h zWbv&xFt73M4S_h1K2m&5R8*qM$hEm~k^=NmjR!WZq<;JCGN;lfFt6#?!EJk2`QA*q zY{ATxZd(=O>FI$x!$hm6S3`l=Jx=kuK~+Z0S{4A#Ve!)#^NXbm>er_+=8JfN>xD8`VJ|%cK5;@NJ&Q5F zzS{UK=CYiIc6O0hJ3cbS3!DR6;syHnhIqlIUc9VMRTVB@cyI#;{eQkL8@>sn{t5Nl zrhp}1sD{stQQwp=Ea8JK`2zj%hU5#ASyism?lA(^D(xo5S*x_``1aN+tr=6SRho|h zuF}3U0vEDMYw{dM`#%d6Zh8(KObZpti%?-0nk+h_lKS?!zzW+5WA5g_!hd^(cG9le zYFVXn%%*5t4eQY ztE1M>4`do0KMG7ouic8S%SpCz@_3+4m||}9w&XCaA+d2VTdWC(TR`nRntpJNC0?B<|dIF3`qZeCNR-cyK*u z?gzM&0yjL9n&INN;_3yFxHB~-w_*9>JM}Y%d2&C+osXHB%48;4He*CW?(&kgO;io* z>Sw-Y-YM^?ConN#?^&l_?#rcXTdsNTDLiu@?gSf|#7m6hZGCZ4+JwkFn~~5W*A-S< zEwT6eb4QW`eQoB7i&SeebA{fHiLehySZ4y3i6 z!hwE3p9^uIKo|$&NiiV~#KTZE2O6K1TY>`}&B_gNpkMGRWpbb=vUACSe#_1!2U?nw zYY8~RIS?hV76;-DF<%X|};?>A2ke zxC|Men{S(~o*ke2pEOSNToLYvaUn&=F&u4%kL$4U%I&$2*=!??8z$yvMA-%#YbNFP zv9)8qKd|2Z7*BV%M<5e(6n%HB8NSL2*F>(jn5!;w4b!nIcM2$Jwi-4ix3g`e+A<~g zrg9Xn(iLv4!K&rd+(yw;5Uw>veb@4`JY)UT+=IDscOb?(mwl=+YhUgIZHil_Vjw2L z$aChkw}Am1M^3!>jl6{BAyduB&Nkz*n7pUri*MEZdu;W*Sl;@+nQKvrTgk*w9{AOR zHS#_Vo5Fz8C9363@($z9H_c3(xfMT@t3BN5w;A_emNzwwU+FK|E+cQ04PWw9S-0v{ z^zBFyE`wrv+0?u3@}}svahq+UUhJFKNOgR&n#(xSKCdD6K|dM5XaeF}(0HZWXk3u@ zN!Vb*r>aXk<$aI(-fupXQ)ASZf>)4FKQj_<+M#paQ(;_^jik!=$@>9!K4fMp^G$JQ z?Y?=xgtd`=X1mdOKjKc!i|tOHNK@QKE6w6KLA)`qe%PIQ99cRkZ+nkOyW+Xn8UN_A|l@!i2n|fYGjtJ4KKEsRk%d6>QSR_QtKz@)vZD9 zLDm;LI>P4TS0vrwa1oM%YodDN+X`(}#ehA|Z0h$bw5p&!%4uFfb-FSyUNxH0(q*ii zl6Pgf;%WE@!|PTbb;xzAUJ1brWA3cHFT$leo%;WI#(84^b8PXT!C1^QgPnVun zVm?b5RtI(ET@|V!Tg5FEY8y)zpQ2-c6{* z36;mq=e{L*mb#%s_+WAu@8CrCmL+-CL{^JBtch$(zNIyhZN=QyL^i+xC$fi^w^)d>iv0vq>d)fHf(b!PIeiL8~7vW(xaJ`d1g!k4Ak}WF>hhLBH7Y&Y@0E4r0uK&+ZJ^j6SYlX4vqmr!PB_g57Pn^>Oo78DF2) zC1|-Z%ER>KisWFQD#g@_=(G1P1Ju~6wXZxLI)rUHcqGQemZq}6M9*1hgE>zV~i3^4J{gP{RN z3-CHooI=eY6NFa(N~)A)PV=n;ZY|rx!4S^#VpP#r;;E>MHHo$OL0%d75FQ zY^;}Pj2I9+7bZW{lz-<9!74UT{&y%9L&Iadn3FsVH=E7KE;i%2(ZS`Fiz#1sx7owf z8>$skgB)(=A}1z*sl0^dh!poCvX{-cZCbE$SfAq_5%t9U;73K6UY!i7m@hswu_rl(Rw0@YKxoGY_dZ76udhkt0R8IL#I`rE;$SHyO~=JSQPQ~n!)orRsAen%8|bZ$ zAf*>yroc6Vm41IR{&#i_WFK`|_ak3{ zm|lVR^j0%ekXoB<3jBi4YwF42OXoz+N46Fo#6&o9p#k__1*ynMTB0xBCBbo8XTw~k zZGtXa2Yaj8)dQZMGjVIN>4HvXl%=y-i95B<=ED+2;DFj!5TU7!M}ui<1E*_@TeXG5 zA>~~fY#yVB9?wCWn%ARBqFS&t*k1PjXcf*v@H~&UdZP;G1a3gxtKS!_m&`UA>KVfi zXYK2u+b!_KbLu)|C}P1YJohle5WRb6m1hsXjkT$QLO(D_mb1b0HE*>x`P|7AZ1TZn zw}%$5A+3!zdRT=z>9+|tieQHdH;Oo>hAnkivGDvK#0XNW2B z$V7`NLCIRolqfJ1rZj-%i8Z`q7&2K*sUI+z5~N0BkcZYnxVY#Y-flOc;)HDfMeR+q9u!mLayK9gBBXZ+tYtCzNFX7$C^VDrn_K`VNyvGB~u zhM@O&kDlCTYlUl5k6yi7{A(J^C;#gBf@WN|n3rWQ{9oi>%eHBDbZ}d+H~Mgs7lR(# zK$ZQXjvV)5h)0#!>vb1jmpp0KacvQ!E}OG6AM+^#oXs#iJUK zVl2(_|Aa^N*pjEt|o42&P>D zYDQ4Kwj+3LFO#3mjn(`N?^E|-q(;|a<|h#uuK*(ICgT;Nb%EQ9Bkhc=#++}5BI|K` zVYKe8@yd8;zH_2Yt#91=a&`KbU^7)S!4_?d*d08Yc!4|;hGIwUM#WEq)5F9P<~rw8 z@HWjFsoel;d>eH?A8ULXY4(Q9V6sL|0)#a#0u7S?zt@>r~q!a&U$FNKTeKEs6z z+FgSgFWixGJc~OXHsdvSEUJNo`S{76-8kx#V1h$ohKs^(F~MA(qMAC%jiCcX}t1@XP8Bj1FX&-+x!kFiC-BGED#Xnqdz8UNg+a-v=9&C$ZTv z@^YFIH(XWfT_M@6|lNUSYL4y_@%=&h*lcA=a5mQn03XA=VjvHpDuwVndh7IyF=Md)BGVcmE0N zeDZ9Wtn=HmrCDcr&H*DMY8=BQdY(^>_$ipJ8UJKNq~081o5eFEcQep$04#52bE1-k z_ew=z4r%W`1k%=_m27jF76W2Q9W`i3gl!&EgA8g0tb?-=Ov__t9ef?ZT6K^ux*U$- z#e-_wx(qRj$1X}_ zIYw$e&GQt^$Oh{e`DZ?DfKQJ|`X6!U)a3kiVfrk+7XPMx{xK}W$xpC~ugXhk6<^OOjCYke-yEh zUo~Yb!s?eC)k(dl$glRGpz}z5Q9fsUA^Fu;XcK#05CufIcm%yAzl!WuEcJ~nVtFFJ zitLSQX!+Ha*7+smSE+6CL-H#cGnFazJ<%qg@~d`j^C`c2ziob5`ganLCGZ`JN>QLS zD(mLc@QrIteP-YR4^OT1MlN=;gFLE^10-u#ewi(k45 zCZv!6F81b|;;mY$|YXj*VYof-_7dYS+;Gn`CFk48&W@laGkS zf_)J&EZ9xuMflE)xx-NOKi`?rYdEMHH5;C9?aa_R2g`)L3LC=OnQ35kH0z^m=Ni{dea-L+x}; zyeudhdoaG6kuN)qo+UAvJB?bS6}ZzV{oZ`pX>`HcF784pAtJ8LazueZd-4zwn+j@8 z!}Cy;5Dm{{^P4-39!9+0X|(s={42xBx$ewjaz5_{jBjRYa`w*xD^5{IX64Vp8JnYK z=O6+h}#iy!@mzK4hr5o5-TfjU+5mCas^p zQ3tc30e)j%e!Oh6c$CQ&dGtVB{o-5hkc=$g!?myu>9=XlZ87^#<$INCyR zNacL%s;VBG=1f+dzp3R=)xQbG896WJf2+5A{D`V!S<2Z5mZf~DKS}H!L7JU>R+gpT zqASRloS|i@jirhjA(q%uBMd;p%d&JR z%d;eQQ;^A8mW~J3YJ}vS`IZ`CB;#c5*&jDrYtPMQ{GTLqlXvD@Y6Qw7td-^-G?XQo zyV?OPlDS(@d26LfHfXIhxA9(CY3e;uveMK?GGn26-II+P)z!Pe3uHuN$0#1r!juWY zUHMcdjNX+`Wy11Z`BWzC-IZTTneh9rd`p?|1uKgc=JGX-s;eHm^IPJE*}L;CjY1PX zNi+)KLb^7rzbrGyqPeYQrkC-5zsyW}36sCxYWdnmjbjvV_hU^t>ZN>3vG5S%EWsQV zS6VRl@JsnrEbK8ar(eqdzo%F@{c^swHKembAI|d5xC1CDdHLsy}w8SGDZ< z+Ov4mo{zlPTCPU*WS62lj3zY-N-S3w)+h)qS0l)_$}+d;U9*78)u(F~aJgETTAwF|gJT~xb(<`$=F7g**Nn!#IEN7K=~ zdOey}r@%4=*Q+jTJ=&D-ROWir$6KxSXxxRGg1?OCl(8A5T-}0F))sB?foQ{bSKWeI zFt%7-w_sm6TCmKAtS7#{F{xfb<0}910`;WbDCkg7tCX>?G0Rs_&IY2MM^dyqIT%P1NeZRRtj%RjLw&rYG=r%Y)Z8ulJYaeWAWER^tg}5H@^alp^fj z_(&w|;nx-nwyiS`U0ZP7zinIhlih%%<$%3d$fErM?7h99KdJE&)BuG1Q~-=KUB0>#s2G_>XSZ30WM zrp@s*2a^EKRPd3UXZ=UMYfZLI>oZ`*G5TFx^!O(u>0Q@5FF-xQGOA$8r<0?ThE zHE9qM`lHb|%nh}c-%L7a3Mm8@vSV^y_SIA{Wlp$Oc~Y6dnu^g_0aR;F#ZED|W#XYl zESCE8oeT8%HfI`0S7u%msF}`O)tl2mx`))2NA2xwhm6cS3$Bh=ljf!*s`0RCi{mI^ zS*T4>_XIO)cUuz{WrX3k!|*3z_?s|H4rvv~g@%Qz7!R$ne{5I3&VZqZcc$H8_#P~X z3!8Q{om?T&81-;LIofXeNkE#iZ+QfKb~p;Phf(%mCYx?y+2DUc*;|>ja3}6Bi?Sa_ zw5DwJ$0OjgEBTlRdwek=7xDH#5pw3EB?(wj5i%#G z79pQtd`Ut!3ZD3{C^_*-P06dDEa=g8AYQh!M|*B9laik=i;{8AZJu6g^#1lqs@s}^ z_{&YAt{hI(TDNEs^@(tz-izBY(>RCaBHR*@Q2*Kw?1yX0r01Gz!|8d>+JbS(s!iS4 z#JVF;qAd>p@TbXI@Dzlt_*ts@srm^fiA%C3alx9z1%DEDnL{|kTglTc-Fy%nSCMti3l7S`r4HD9SnxIswM9fG{faJTq^T* zA}TZjN!Y7XCR9Fb+pO|#PmWPXyElzD=D%A|Ev|S2t-=P{j7^^x%nq9h&AqQ$qFVQ5 z!78`Q*El(bJ$?C`~!I8SrK1&NAWt;oZ;xf7C6E3ft46mq%&M3;S^F{vEmSwZE~ci7g6i z_2c(-yoBB_@?;14jc7>rA-1%Jgbp)AL-HYQ@@-Htep%8ic^1_fpq&)5@79VkbC<>ABEeoj-Inc6@66EWzC@jl0 zRbN!dQh@X$+n@rZW~;)QwiE+isi4jK#}27d+Z2jJss`%AHib>ZE0wrsHQo2z!be)V zkG2%ASrTUULJZba$Fwc9-1l&X6Ot>p=Zjl%2zB?TLAT-UQFtz#VNl#V@mS-0wd$I} zjGA_b7@?Evfs@rmtH3gS4nub5PUDYj3ZD#9qG+Pu(+@;nDdev0GkuHWN!2GY;2HWA zC?d+OJHR25wW(0~jU;NS2;WC+=?>s!&VrR}ko_p_{2f3cqp4j{>jxB8wR(V;#hX3A zTuV(sQEt0~h6z-ssQ(No*#oW~Slk1ukr2vK3Dz2tV>$AG=M|+SgRK_FS{3fIjpc* zOV%vp>z#oM^3A4R9NZ}R0^C>KdwrSo|N8ae^xt9lpXmRF;f0g`SLok(@6N)?VRKTw z_IKS=I6vHn)p0Zf6dKe>L7~CnuGj>5H`3t4svWbKKCC_>@tQuYUIR2$8jkPq0Zf%f z^ccj7N+aaMY7}#tKCIqAQBmjjVa1hO$cNSIELD71am5$%Vbz8K(}&evEYI{|r8g#U zFT}0)7Fs^6nv(uaC5C%4vWgPJbSc%exAtKbTEoG+&*6IuMTz0&kR?hC_lKl+@mQ5k z`ZARm?x#>)QDV4hcqmE?_gLO59;@h6(ehaJG~=Pf=svUX?;Tb>I#TouT_g@q09AFUm?ZZ5aBLl1H3;K@6y?w$2a<@I_lHa zeLHJ@)QQxd?n2h~lV6eA%dH(ngsU%@Jn46=Ll z3D}m6u~yILMAAi73(s~wmo~<~&n~1YqwXAiDVS4esxtn+@oQBuw~)$+NplN(qnVG) zEu>ZP4`yVA-1vIQY>c6v8YWv|pxAkpx_(}vrJ)$i)-BUtRX3*my}znhHoc{xxDbC; zmb4)ebTLXN-!m({E4m-N2Z= zy=Stoi|F)#2{H!Ldw~6F$x4tk50C(Y79fVP`==M)cMzX`row<{`YmAJ+x9w=ixZ;yiR6)PDfgv7jwN+~+~MJXL`t z12h+-niut;s6%`A|JZ$xeb_Y?@ph)4Or(&Pq*9-Y<2bkbp&uT0quYtweA68KLAa2 zMsV|j*pFDD%WmRrnYe)ZCT!#p-LAX?ROym`*82OMz*_h2^u}GlS{GC=1c-q;Y`|LA z7d%h|YQ6z$T~H`xh`k0S-Xt)mKM9-DqJ5QUN<_9o*!Aowcq8%383q z))#_Ih23Z&MC^?gn|1@Uz+IqL;3SwVmXS*u=-%a^ z!FuWKy?cG7MW!1pWt5nn)2qmXcJa?Cdk&z`KQ^A}9T`eI(`$eSyYRjRnhiV5<>&Ob g|JcMC1t%xQif@m(n2#AP?kjNlngrJBKkc2@5MGPEF zAr~bm7f}HNK@KWIKvYE3py)+J4T?A+7Zeo{_5JSdUCF_Fx&DUdpLeb2tktPcRd-iU zwTIeO-8p$^zP9As`C3(yJ3lYKQ(o8H{KaWQDz-KX@kW9Whmn50S%|a4gccPdG;fX2 zI*t%pzdb@5gXJ!i&yEq=gfL3a3S;gVVbqihf^^ywo!H$@1~y$6Lyx`k&y7)wyW6nk0i6+u{n zol8Y<#%2*bVu%PnK1PIiGek&-1QBvsjR@IXQ7S@q_ZJ}t4vNqlQbgz-t3~L;BSdKJ z3K6=aN`&q&6QPGoMd(+>A}p?}2+Qas!a663u-;2VSW%D&8#!Bq-H|E6rmqoU3!W5V zPk$rAURff-lMjpVE-gj)ZCG9zC&G`M6cNw06cLT%M8wJ8MZ|Bqhzxd$$cn@$5t$Vx zBD(~M$Sa16$Uy@{Op^;UW<=@wkY(Z-R(=2mq(^2N8ewa1p<7k%)in zSrPyAOCo+3wmBFl;y;@z5<<6#gp9!=;cs0`AU_icPv0pLcFYtBM>dIs z(>+C^W2#7uKi<5ggF97=#KH$f;(!Sv@#cz6BC+&)kvJn$BtA4)BtCvlB;pw+zJ}$~ zYLOJ*QY5vWD3UHq5=lev6iHIq)72>5h<+(i!wmWl!P zf`fYx{3N_5mWWi>RFT^C85f zWb~xF>PpQ`QMN+N@775cW<ox^`y4zJliDB-u64zjja;`<9?$X3hLz?$% zIF$6f??7hX=KWUM`@LiDH_+biVNrKU);|OG!||T?y_z4e-*kJwbr&4(Hc{8EOW^U! z+9f{k+jV)se*d`OcvsoS^9i}KMoXycb;Zu+gI4E-CHPtvecXJmGyc;tCy2V_L8C*P zuhCnWQs*leb$RoC7dcm%7aNvPS2ybQ=3`3h2IbumaKd-n2Yti7P`*K4yFQG!+^%-&(yQ{;n z&bW^@?@0U7k80IcP|loIA+$^)=gmH2gwJr^BeZNQKiFqn=QCVsSa%-FCM<64I>(P8 zt%a*Q7rq`?*bkXVoX_W~Fs!v(8|?ToytVL@qO1$nSp}i3aWZblB$NeZ^ub?!6djTF z4JHsl$@t?C#I#c|w*T`V5pq8Y_5QR?@Q-rwV#nCJ?a!5IvhH0oSypY&-6gle+!4ZWK=EJTQ6-=JCPvT&bn_=;*X%&jOo z-M6B)+*g0V&`N#1XQ!JfIGHPblWWptWwK^y-F%BtI9eCN@6&dt`|?*M_-YnM zX!*X6H)fgL9YVbA+to7KcM4_0eC;=7X>K{|Dl^(wH77>D%9QoLg~rLo`?Lt{c3M0wb2GK)e5aAw6YiUc%tyZ7zASTF5S{I=x#@aJh%A05{GjyS z7#1OG-Em%7I5aA%?%?JIorEQFEbfekt?5U%T9dQ-Iiux>ZhA;)9p!P}^xG>BbTHyu zp9QMTe+%F!T(c_g>dTWI<@pJ^*SB`-qGlCSEt|#Y?n`BLaNRTJIqc?kn-fA&BV$Js12*w)1G_Mm07FT8uyXHMFhgRjaYe7WZg_<@tFnLh7E} z=F#N*(xfQgJKL|WOWV<1m%Z-y6qrNM3hjnjbHB&%)z@dp+8Jner>vG4va4KQ9qQ{j zJ5wK~$-+g6alV>&Bh0g*LRjrmpQ_8EF=3f<_9v-!v&^-cWj>naLDekHA>l%l`tmlV zn{GUxL}q>@f0HQ6V?RX9GB}k!}kp-zzWMpvNbEX4Qp1 z__^@_R3i*tvBXhT)SV3+TbQ^uoBljs267HQc*Ye&2^#j zL_x@ky8RzM+pOK$t{u9lwYbi%&wBobi*4E}QTO_hW}D_KoPX9=_)So=KzW~vOsu>8 zo4AXg=jC?2<@R|t+qK$nYntrZ7%l3q+a`|dFsY+AFW>4bl55o1J~g2(?3a;xz&Vpa zfE^B{%XPb`#o`{6*cWfuNt&qp`>z|LEDPs95~jW8XgXbTMC8y@dRr|6_AOC5qqS)j zEwGzX0B@s0?RWechlPHf>;y+K+EMkIb2mz$2gq1K4_LNNcRi2X#q>Z9))|&uc0LBA zAJwX@pqx1^6=sddvS${sJ&Q!)w^&}19b&XrLE$)jP&$>#8)CGU5mx|%Den-pSGe4D ztCko%2&gAfL5S2wh86g#o(uLh%!u;;5u-h#$y?JMURfWf#Rk}$ldowR{^jx78cp^} z)C#oua`JR7OV%W6+0{SmhE`5eEKenB;zjzfq`Nr1H-zClZ}v_^TFc1a+yl?}h>ZrN`p zWTIw?;XAV=Lwe7lWEo1dA`)LMUml%_&Byp7TWH_@R|}GITno`&mfejU5dv_^Sy#5A71*GOIv{ft;d^ zoB^VZ%%Ma#bE)CzuA|6Ztc{GuI)e;`-f1KL(vPasR#1*?#Z3fGY9lvqlmn+~u|v0_ z!18%MC+LPhR6>S;+M0VB{x}5fbp(s&Kl~w;zZmO++TxF%NSk^#%HF#}u9xBWXrIbW z8QMECVYrjDy+>|nt%doP%q;T#v3{Uze?B_M*RW%xe}AUdUX!)UL%YFUL9-dCEtI>a zYb$*{W@np?sPRWjfs?+UuUd-!z9y?WM#cF~y&IuTwwudZYA)JhIS38G+z-o8ZmIg) z(NelwE#)6pOL^UHDSyZVv5t6|I};8`AK9B)gNxL>RwNfw<`S!&Bv|c4?-wj9tHa{_ z-U_X==8tc$?b0r);bo6U^$=~PTy?uU#mgSai?|Baa6S#-V{%qU?Z>9JA{$o4C-|## zwO~hw=BGRyJ3w8%WhJg#DKX4$)E*4iM^?_&#{W)d?XoCKW&79m)w(vTD_M1AYP|oq ztF(vofI6wIpiXMgP=RH3ow&JF=O=b@iGNFf?Oe320t-vDCyb`^{7V%`ZC6XjpM_ZH z_wOq3E0m&n&!nVD1-_45^M%LJx~BfpjmQ~R7wQsHP4xSpP=R#q!Q^3GpaL`K_O|@b zD$t?Hp0{Z)+Iq0f1TCyt5Bd*H&{qFnr~jWXPb zi>t)f@hG&P@n;kk`UR-Omyt!AxtbE)Y-_8;wa7KMnG5^aq?L?x+O8|9Ci-2d5{FQ+ zr4on!KU0alvHf4G#9`PfD4&koB0wejp%U+Ia(@4$4#|Sb#@jU0Uv;nckNPKNuF9?+s` zGL2mSiN9;r0g4gPs3)ZN`OrvNP@@Hec&6L6y<=CyA)ecWA2F$b7>}gbiT}~{+VnuT z^>TXVO)4wLu4%#rHAM@5ujjSMa9go9?$DMrJJ@!m_pWkWqRG9xw2KFi3hbKa*fm$u zQ4N<@_&e{`Qtg^$(J&*yfBt~>{hzB3J*aIBJm(8VW`B4{PE3HSE6_}!Emw(&OT3{@R zqHpqzUjm=ae7mBfc18SbrV4+@a~C|DvV_ zF|A}s2mO#gcZ|L-xVdVp#Uz&LlLBwlg?FEy>(lo2afb}g)jwH38fG_TJlA6X{8{?p zfJcz~GW>?wbM%!LuerZfrMbked8~czxx!y`zh2DGwf|E6?dD2h-FA7?97m#m|L1zWeGLD$llrs^o~qR^4v5fCwNICI$xZg@ zek}ago!0LO2+><|KI;!XKnGJ-1Q%+_o#A3R&lLVI|Ih<7MUlkwk-=5^?7#J8>Mn`p<)`h!W&)Vm3mt6(*@NrXa7XIWG zj>p(7?vv*@-s~1jufN6R{wZA@cL!E#1>@ajHtp|rQU3}TcB@@mS38*|{0Rk)W9+{# z>+c8)sMOLLuNFCap;yp6lpq)1kO-w_X(YpSpIy%wAv+It^wVyaGX^_OY5n|nT<5qU zl$<(h4{QBZC60h-j%{pi9PKC#tT{zS-WrFRDQbZ0Wvy8vRpXe@EQi(ug^j-}u;vRjYY)4X)Y&!PYo9;NK=Mnu&n#c;dq)@P2l zPnJb}rtnY7GrovyvgINEQ&$*i0rsWxd_qF?2MKNcBl;Spfj9XDyY>R>Uc0OiqG67( zYq!EfhHIGc|9qwK1~)!<3f%)Lwodt(;l@{5z-@TIuJku6aV@39FmJRgwIWc4Yp8$c z2;-`7>o!RE2*rNm4kJL?Wn)ELf`7|I1G`Lz?26fCvd-ObSvTEqwe{aL*;pTG zSB(3c;NLdK=o@gxtJh0Tr(oV^vHz33mC3oHC z$2T<$j9P^U`nE0za>i!L-0cP;p70&Fe0=J92qBNu&e-wFn2TT zGAi#0PT=y(!7Z6x1ovQ0Fon46a?Ye6(~sE;9>ClIJcPL) zcsTPQ@JLzkk@5APbVa9v&YgU{6SDODSXrMKp5UK%#Axfvvvq}Kww11k#m#`OAZ-L) z@f76@SBRaI3wiW&Bm2*0CjOZ5GxS9G7lza6dK9Oki?{$Y^X0e3Gp2mxv{B%!OvZUb zNhF1($y2AHBo4O31ce|BjiI3Mdnkz&ZDj5yjA}Q258HBTfoW(n z0VZmzJn#bs79W$7FM}F5B2&*8S>`Q~81MJ(>X5E=kdsk>VU5Ypd*Z9#(j(4omthMI^6tV|A>FD2FFnJTHqk(;C%H>gRfac`QW+6!i>t`O0lIrilN~%c`l~kVvE2&PxF_cv2gOyYll5{Gu?h968eKlB#^%1ZV>(9WJSR*}- zMM?FL0I4np(?!uT8my#xELcf3sTPvz3fgEIGD@sT&nU5;4OU{k8?3~7FIY+S+h8Tt zN5D#|PlAEXnajadBO*;->;l<(XdY5s2E<_YDE?xLI8;zn>YGU zl=)_O3AR{>!-kaJE3_+0qA<~+V%07G9ul~HtQifXKck$oNg9ro8`uIc$}qD%P`w% zJ8i{LB?o1gS>`I(>sKwsF;1>Rfj&Q6Mr?+nsF$ZHTi({z8+&E%)@GJ-E+StMx~y#x zmZlw&i&12zz-cVAbjL#f(bnc@_l3H{4|g@${g<99ba#{5aD$cFAXTB%26?SYZA60y z)1i_8X{DH)pnj!hk7v#SPh{>0p2FM>JdL?0xRRM- z2J@KFPHwT}jt*Rk6-#)6$E-Mxl%t>`CxfUTfAE7itl^(|cmDx$dt!y?7{1s)W>vQY9DjK;SwxsS@e{D^-#T zR;q-wN0TbaL`Hca*z%*&#ScQ${^zN&aFW9;i)Lmg;jYMCmucx*ciDR!8rhq6;N?4+N=>n~ z-7xoC4O4F)WOa^x4F@A|$UHPg?K^1&VREgesnz4Vh7S<;#I2YZ-{rB?3wKz5vBHV-ODxOjC=S=A9ZT=@_BKj3a_FfYsC?Ruih;q?tY(q-gN zN%;Yht9Te{Oi4&O`YG~L zIKy)fyse$oj!iX?kRctUVQ~&`Hzu#h>i}XFER>(Sj z$ScS?e#-m=(l3}vjJ{=tcOrgb&I13&+!^e^LU(R17Nr?J0f%!rNn9-Rx76oO=FBOi zbP(G4EEcMm_;)PrnMt+h`G2f2uWue9w@qqpXZzKWujH;=E#ANGNz>3X6WQ~_eI*rA zONn8gv=SHH0cesZg#Uxp=2VA^Zi0?CHy57^$(M!Cn%?Ruq1iHbf!TVNY$wz5VzF(PkVvW3LKe$hXc3mf_nRDq0=TH~@b+&=nsUuY0|W== zra^ZjtVm-IjUV8Nk7;j@JyiY^p3|Q8GOWKlQ#Sk)&pTVD9>Vjkmy;{kl`rJ#T_nPobZLZV~L+@6>J*^Ve8{^XS z7<;I}+?s-JnLIiGHFWc@I&8kl(Zvv4KYrFg!zel6#_(cUyvP$Gvs0ZzNOJu_+=2JROz`B6d4O$lFn!2U7AXK2Z#&{wN)ol)36il!Hl2P&p}fQkBGCB2^uUQ()DR zAWv!?Z}THk)sN_-BTlfDS6qtNRJw2bTt%$bTXHL)u04LBWXP?YrqN2wcr$a?~mq-0pkIf zDd^~2&`D}nYuWz$eljb}Tw6k)paUrhC4&bEC3mS=LVvJwt~+JUdA!S4;=kp*xy0kT z5l6eQM z>tou;Q#4L^B-B}?N94#3Va@^QpFGkrHcPG!!v^PbWg`X&&1F!iH`|h$BU^+!v&krz>ui!aXs0HbBX>*59JyO8a}|Q@fD*c1U?p_dgCTTQ%NYq) zGB*aSWNsc<$=qVFlDVZ|C36z2WDc%&lgyD$ZyGW%kx@c71gwOP®D3AK_rI;fJl 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 z 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

;?paN=3u4cz`b@V^+7UAvX>7T`A-ZwG!~ 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 From 7de923ec8de2d93d34a8adfdb4df75987a91fe6a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 7 Sep 2015 17:04:14 +1000 Subject: [PATCH 042/105] Add link to mailing list, and code of conduct from CoralineAda/contributor_covenant (thank you!) --- README.md | 8 ++++++++ code_of_conduct.md | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 code_of_conduct.md diff --git a/README.md b/README.md index 7bfa2e0..917f6eb 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,16 @@ A community developed open source [FreeRTOS](http://www.freertos.org/)-based fra Originally based on, but substantially different from, the [Espressif IOT RTOS SDK](https://github.com/espressif/esp_iot_rtos_sdk). +## Resources + [![Build Status](https://travis-ci.org/SuperHouse/esp-open-rtos.svg?branch=master)](https://travis-ci.org/SuperHouse/esp-open-rtos) +Email discussion list: https://groups.google.com/d/forum/esp-open-rtos + +Github issues list/bugtracker: http://github.com/superhouse/esp-open-rtos/issues + +Please note that this project is released with a [Contributor Code of Conduct](https://github.com/SuperHouse/esp-open-rtos/blob/master/code_of_conduct.md). By participating in this project you agree to abide by its terms. + ## Quick Start * Install [esp-open-sdk](https://github.com/pfalcon/esp-open-sdk/), build it with `make STANDALONE=n`, then edit your PATH and add the generated toolchain `bin` directory. (Despite the similar name esp-open-sdk has different maintainers - but we think it's fantastic!) diff --git a/code_of_conduct.md b/code_of_conduct.md new file mode 100644 index 0000000..01b8644 --- /dev/null +++ b/code_of_conduct.md @@ -0,0 +1,22 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) From ed2c1ad7136862aaec9f91478ae3b6bdab9668b9 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 7 Sep 2015 17:52:01 +1000 Subject: [PATCH 043/105] Update README with some recent developments --- README.md | 32 ++++++++++++++++++++------------ extras/README.md | 10 ---------- 2 files changed, 20 insertions(+), 22 deletions(-) delete mode 100644 extras/README.md diff --git a/README.md b/README.md index 917f6eb..d91cd05 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Please note that this project is released with a [Contributor Code of Conduct](h * Install [esptool.py](https://github.com/themadinventor/esptool) and make it available on your PATH. If you used esp-open-sdk then this is done already. -* The esp-open-rtos build process uses `GNU Make`, and the utilities `sed` and `grep`. If you built esp-open-sdk then you probably have these already. +* The esp-open-rtos build process uses `GNU Make`, and the utilities `sed` and `grep`. If you built esp-open-sdk then you have these already. * Use git to clone the esp-open-rtos project (note the `--recursive`): @@ -38,7 +38,7 @@ cd esp-open-rtos #define WIFI_PASS "my secret password" ``` -Remove the `#warning` and follow the git ignore instructions to keep your credentials from being pushed to Github. +Remove the `#warning` line and follow the git ignore instructions written in the header file to keep your credentials from being pushed to Github. * Build an example project (found in the 'examples' directory) and flash it to a serial port: @@ -48,6 +48,8 @@ make flash -j4 -C examples/http_get ESPPORT=/dev/ttyUSB0 Run `make help -C examples/http_get` for a summary of other Make targets. +(Note: the `-C` option to make is the same as changing to that directory, then running make.) + The [Build Process wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Build-Process) has in-depth details of the build process. ## Goals @@ -57,7 +59,20 @@ The [Build Process wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/B * Leave upstream source clean, for easy interaction with upstream projects. * Flexible build and compilation settings. -Current status is alpha quality, under development. AP STATION mode (ie wifi client mode) and UDP/TCP client modes are tested. Other functionality should work. Contributors and testers are welcome! +Current status is alpha quality, actively developed. AP STATION mode (ie wifi client mode) and UDP/TCP client modes are tested. Other functionality should work. Contributors and testers are welcome! + +## Code Structure + +* `examples` contains a range of example projects (one per subdirectory). Check them out! +* `include` contains header files from Espressif RTOS SDK, relating to the binary libraries & Xtensa core. +* `core` contains source & headers for low-level ESP8266 functions & peripherals. `core/include/esp` contains useful headers for peripheral access, etc. Minimal to no FreeRTOS dependencies. +* `extras` is a directory that contains optional components that can be added to your project. Most 'extras' components will have a corresponding example in the `examples` directory. Extras include: + - i2c - software i2c driver ([upstream project](https://github.com/kanflo/esp-open-rtos-driver-i2c)) + - rboot-ota - OTA support (over-the-air updates) including a TFTP server for receiving updates ([for rboot by @raburton](http://richard.burtons.org/2015/05/18/rboot-a-new-boot-loader-for-esp8266/)) + - bmp180 driver for digital pressure sensor ([upstream project](https://github.com/Angus71/esp-open-rtos-driver-bmp180)) +* `FreeRTOS` contains FreeRTOS implementation, subdirectory structure is the standard FreeRTOS structure. `FreeRTOS/source/portable/esp8266/` contains the ESP8266 port. +* `lwip` and `axtls` contain the lwIP TCP/IP library and the axTLS TLS library ('libssl' in the esp8266 SDKs), respectively. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details. +* `libc` contains the newlib libc. [Libc details here](https://github.com/SuperHouse/esp-open-rtos/wiki/libc-configuration). ## Open Source Components @@ -79,15 +94,6 @@ Some binary libraries appear to contain unattributed open source code: * libnet80211.a & libwpa.a appear to be based on FreeBSD net80211/wpa, or forks of them. ([See this issue](https://github.com/SuperHouse/esp-open-rtos/issues/4)). * libudhcp has been removed from esp-open-rtos. It was released with the Espressif RTOS SDK but udhcp is GPL licensed. -## Code Structure - -* `examples` contains a range of example projects (one per subdirectory). Check them out! -* `include` contains header files from Espressif RTOS SDK, relating to the binary libraries & Xtensa core. -* `core` contains source & headers for low-level ESP8266 functions & peripherals. `core/include/esp` contains useful headers for peripheral access, etc. Still being fleshed out. Minimal to no FreeRTOS dependencies. -* `FreeRTOS` contains FreeRTOS implementation, subdirectory structure is the standard FreeRTOS structure. `FreeRTOS/source/portable/esp8266/` contains the ESP8266 port. -* `lwip` and `axtls` contain the lwIP TCP/IP library and the axTLS TLS library ('libssl' in the esp8266 SDKs), respectively. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details. - - ## Licensing * BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki), and [axTLS](http://axtls.sourceforge.net/). lwIP is Copyright (C) Swedish Institute of Computer Science. axTLS is Copyright (C) Cameron Rich. @@ -98,6 +104,8 @@ Some binary libraries appear to contain unattributed open source code: * Newlib is covered by several copyrights and licenses, as per the files in the `libc` directory. +Components under `extras/` may contain different licenses, please see those directories for details. + ## Contributions Contributions are very welcome! diff --git a/extras/README.md b/extras/README.md deleted file mode 100644 index 1bc0a52..0000000 --- a/extras/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# extras - -This folder contains supportive source code. - -For current versions or reporting issues etc. please check the main development pages. - -- [bmp180](https://github.com/Angus71/esp-open-rtos-driver-bmp180) -- [i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c) -- [rboot-ota](http://richard.burtons.org/) - From 7e736938985f72f01467d2d48c13adb74e9bda32 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 8 Sep 2015 09:59:59 +1000 Subject: [PATCH 044/105] Rework component makefiles to have a default _ROOT This fixes a long-standing bug where build directories sometimes expanded many levels deeper than they should have. Component names can now no longer contains slashes (ie the component name for 'extras/i2c' is now just 'i2c') --- FreeRTOS/component.mk | 3 +-- axtls/component.mk | 7 +++---- common.mk | 3 +++ core/component.mk | 2 +- extras/bmp180/component.mk | 8 ++++---- extras/i2c/component.mk | 9 +++++---- extras/rboot-ota/component.mk | 8 ++++---- lwip/component.mk | 7 +++---- 8 files changed, 24 insertions(+), 23 deletions(-) diff --git a/FreeRTOS/component.mk b/FreeRTOS/component.mk index 437fccb..4b63b73 100644 --- a/FreeRTOS/component.mk +++ b/FreeRTOS/component.mk @@ -1,8 +1,7 @@ -INC_DIRS += $(freertos_MAIN)/include $(freertos_MAIN)/portable/esp8266 +INC_DIRS += $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266 # args for passing into compile rule generation -freertos_ROOT = $(ROOT)FreeRTOS/ freertos_MAIN = $(freertos_ROOT)Source/ freertos_INC_DIR = $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266 freertos_SRC_DIR = $(freertos_MAIN) $(freertos_MAIN)portable/esp8266 diff --git a/axtls/component.mk b/axtls/component.mk index 44da5a0..73859a2 100644 --- a/axtls/component.mk +++ b/axtls/component.mk @@ -6,13 +6,12 @@ # We supply our own hand tweaked config.h in the external 'include' dir. -AXTLS_DIR = $(ROOT)axtls/axtls/ -INC_DIRS += $(ROOT)axtls/include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto +AXTLS_DIR = $(axtls_ROOT)axtls/ +INC_DIRS += $(axtls_ROOT)include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto # args for passing into compile rule generation -axtls_ROOT = $(ROOT)axtls axtls_INC_DIR = $(AXTLS_DIR)include $(AXTLS_DIR) -axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(ROOT)axtls +axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(axtls_ROOT) #axtls_CFLAGS = $(CFLAGS) -Wno-address diff --git a/common.mk b/common.mk index 1c2424f..6772ba8 100644 --- a/common.mk +++ b/common.mk @@ -200,6 +200,7 @@ all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) $(FW_FILE) # Expects that the following component-specific variables are defined: # # $(1)_ROOT = Top-level dir containing component. Can be in-tree or out-of-tree. +# (if this variable isn't defined, directory containing component.mk is used) # $(1)_SRC_DIR = List of source directories for the component. All must be under $(1)_ROOT # $(1)_INC_DIR = List of include directories specific for the component # @@ -214,6 +215,8 @@ all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) $(FW_FILE) # Each call appends to COMPONENT_ARS which is a list of archive files for compiled components COMPONENT_ARS = define component_compile_rules +$(1)_DEFAULT_ROOT := $(dir $(lastword $(MAKEFILE_LIST))) +$(1)_ROOT ?= $$($(1)_DEFAULT_ROOT) $(1)_OBJ_DIR = $(call lc,$(BUILD_DIR)$(1)/) ### determine source files and object files ### $(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \ diff --git a/core/component.mk b/core/component.mk index b4eca35..d6bc1da 100644 --- a/core/component.mk +++ b/core/component.mk @@ -1,6 +1,6 @@ INC_DIRS += $(core_ROOT)include # args for passing into compile rule generation -core_ROOT = $(ROOT)core/ core_SRC_DIR = $(core_ROOT) + $(eval $(call component_compile_rules,core)) diff --git a/extras/bmp180/component.mk b/extras/bmp180/component.mk index 5efc68a..2c6b4c8 100644 --- a/extras/bmp180/component.mk +++ b/extras/bmp180/component.mk @@ -1,9 +1,9 @@ # Component makefile for extras/bmp180 -INC_DIRS += $(ROOT)extras +# expected anyone using bmp driver includes it as 'bmp180/bmp180.h' +INC_DIRS += $(bmp180_ROOT).. # args for passing into compile rule generation -extras/bmp180_INC_DIR = $(ROOT)extras -extras/bmp180_SRC_DIR = $(ROOT)extras/bmp180 +bmp180_SRC_DIR = $(bmp180_ROOT) -$(eval $(call component_compile_rules,extras/bmp180)) +$(eval $(call component_compile_rules,bmp180)) diff --git a/extras/i2c/component.mk b/extras/i2c/component.mk index 13b0f83..0ac3165 100644 --- a/extras/i2c/component.mk +++ b/extras/i2c/component.mk @@ -1,9 +1,10 @@ # Component makefile for extras/i2c -INC_DIRS += $(ROOT)extras +# expected anyone using i2c driver includes it as 'i2c/i2c.h' +INC_DIRS += $(i2c_ROOT).. # args for passing into compile rule generation -extras/i2c_INC_DIR = $(ROOT)extras -extras/i2c_SRC_DIR = $(ROOT)extras/i2c +i2c_INC_DIR = +i2c_SRC_DIR = $(i2c_ROOT) -$(eval $(call component_compile_rules,extras/i2c)) +$(eval $(call component_compile_rules,i2c)) diff --git a/extras/rboot-ota/component.mk b/extras/rboot-ota/component.mk index 598e355..690b7bc 100644 --- a/extras/rboot-ota/component.mk +++ b/extras/rboot-ota/component.mk @@ -1,9 +1,9 @@ # Component makefile for extras/rboot-ota -INC_DIRS += $(ROOT)extras/rboot-ota +INC_DIRS += $(rboot-ota_ROOT) # args for passing into compile rule generation -extras/rboot-ota_INC_DIR = $(ROOT)extras/rboot-ota -extras/rboot-ota_SRC_DIR = $(ROOT)extras/rboot-ota +rboot-ota_SRC_DIR = $(rboot-ota_ROOT) + +$(eval $(call component_compile_rules,rboot-ota)) -$(eval $(call component_compile_rules,extras/rboot-ota)) diff --git a/lwip/component.mk b/lwip/component.mk index 4257689..e16baa0 100644 --- a/lwip/component.mk +++ b/lwip/component.mk @@ -1,12 +1,11 @@ # Component makefile for LWIP -LWIP_DIR = $(ROOT)lwip/lwip/src/ -INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(ROOT)lwip/include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip +LWIP_DIR = $(lwip_ROOT)lwip/src/ +INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip # args for passing into compile rule generation -lwip_ROOT = $(ROOT)/lwip lwip_INC_DIR = # all in INC_DIRS, needed for normal operation -lwip_SRC_DIR = $(ROOT)/lwip $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)netif +lwip_SRC_DIR = $(lwip_ROOT) $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)netif # LWIP 1.4.1 generates a single warning so we need to disable -Werror when building it lwip_CFLAGS = $(CFLAGS) -Wno-address From 9f5bc3735e927c7445d2caadc37fc671c3a6b878 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 8 Sep 2015 10:36:03 +1000 Subject: [PATCH 045/105] Add link from common.mk components section to wiki page --- common.mk | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/common.mk b/common.mk index 6772ba8..b143653 100644 --- a/common.mk +++ b/common.mk @@ -194,6 +194,9 @@ all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) $(FW_FILE) # component_compile_rules: Produces compilation rules for a given # component # +# For user-facing documentation, see: +# https://github.com/SuperHouse/esp-open-rtos/wiki/Build-Process#adding-a-new-component +# # Call arguments are: # $(1) - component name # @@ -204,13 +207,6 @@ all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) $(FW_FILE) # $(1)_SRC_DIR = List of source directories for the component. All must be under $(1)_ROOT # $(1)_INC_DIR = List of include directories specific for the component # -# As an alternative to $(1)_SRC_DIR, you can specify source filenames -# as $(1)_SRC_FILES. If you want to specify both directories and -# some additional files, specify directories in $(1)_SRC_DIR and -# additional files in $(1)_EXTRA_SRC_FILES. -# -# Optional variables: -# $(1)_CFLAGS = CFLAGS to override the default CFLAGS for this component only. # # Each call appends to COMPONENT_ARS which is a list of archive files for compiled components COMPONENT_ARS = From 421f8ddaa572a813bee5169c33b277b5325fae93 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 8 Sep 2015 10:36:19 +1000 Subject: [PATCH 046/105] Allow properly for out-of-tree components (was a hack before) --- common.mk | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index b143653..f1d6477 100644 --- a/common.mk +++ b/common.mk @@ -307,8 +307,15 @@ PROGRAM_MAKEFILE = $(firstword $(MAKEFILE_LIST)) $(eval $(call component_compile_rules,PROGRAM)) ## Include other components (this is where the actual compiler sections are generated) -$(foreach component,$(COMPONENTS), $(eval include $(ROOT)$(component)/component.mk)) - +## +## if component directory exists relative to $(ROOT), use that. +## otherwise try to resolve it as an absolute path +$(foreach component,$(COMPONENTS), \ + $(if $(wildcard $(ROOT)$(component)), \ + $(eval include $(ROOT)$(component)/component.mk), \ + $(eval include $(component)/component.mk) \ + ) \ +) ## Run linker scripts via C preprocessor to evaluate macros $(LD_DIR)%.ld: $(ROOT)ld/%.ld | $(LD_DIR) From e6b862e0f76eb4672dca9acec0be44cd3c78943c Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Sep 2015 08:25:34 +1000 Subject: [PATCH 047/105] libc: Fix _default_types.h so uint_least8/16/32_t properly recognised by newlib Newlib built from projectgus/newlib-xtensa 514f105b0 (thanks @Frans-Willem for the fix) --- .../include/machine/_default_types.h | 4 ++++ libc/xtensa-lx106-elf/lib/libc.a | Bin 5105508 -> 5105508 bytes libc/xtensa-lx106-elf/lib/libg.a | Bin 5105508 -> 5105508 bytes libc/xtensa-lx106-elf/lib/libm.a | Bin 2241938 -> 2241938 bytes 4 files changed, 4 insertions(+) diff --git a/libc/xtensa-lx106-elf/include/machine/_default_types.h b/libc/xtensa-lx106-elf/include/machine/_default_types.h index 1d55697..03bdc52 100644 --- a/libc/xtensa-lx106-elf/include/machine/_default_types.h +++ b/libc/xtensa-lx106-elf/include/machine/_default_types.h @@ -32,15 +32,19 @@ typedef unsigned long long __uint64_t; typedef __int8_t __int_least8_t; typedef __uint8_t __uint_least8_t; +#define ___int_least8_t_defined typedef __int16_t __int_least16_t; typedef __uint16_t __uint_least16_t; +#define ___int_least16_t_defined typedef __int32_t __int_least32_t; typedef __uint32_t __uint_least32_t; +#define ___int_least32_t_defined typedef __int64_t __int_least64_t; typedef __uint64_t __uint_least64_t; +#define ___int_least64_t_defined typedef __INTPTR_TYPE__ __intptr_t; typedef __UINTPTR_TYPE__ __uintptr_t; diff --git a/libc/xtensa-lx106-elf/lib/libc.a b/libc/xtensa-lx106-elf/lib/libc.a index f46ae7bb3b0b8d3da2f36c534ae148ca77f056f1..596e9f61e44bee4456c22f75a2e9a37a2211a733 100644 GIT binary patch delta 9194 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 delta 9194 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 diff --git a/libc/xtensa-lx106-elf/lib/libg.a b/libc/xtensa-lx106-elf/lib/libg.a index f46ae7bb3b0b8d3da2f36c534ae148ca77f056f1..596e9f61e44bee4456c22f75a2e9a37a2211a733 100644 GIT binary patch delta 9194 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 delta 9194 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 diff --git a/libc/xtensa-lx106-elf/lib/libm.a b/libc/xtensa-lx106-elf/lib/libm.a index 8ea5c1cf270b11361dad01d62cfeaed8e8ec02b9..697d2abbabf92cd861d9a667855c38f1e991c493 100644 GIT binary patch delta 5663 zcmaJ_dvw$F6+cPZKxvaUNt682qYRi0UOg-Dr=7?QUA{IuQhIks( zjvL0**av;@6cl9}WAEmV768Q>WABve5+&8vO=?-IEhE-caYDpMZ|Kw{y)N^Et99k3 zPMZ>|uWhz+6lhIRtLEFnvDGW81g%?;?T)2A|3(&z5%9@&M>1ghi#Hh<``!*4t7xv) z)z==3eR#G*!hHO%w$fPEmk;Tl_Gh|dE3T^^R;#;^<$*ixh9^ZtGo-G3!q5qaLx$~Q zs&0R#0`-Fo_lRmsYpw#FV+1Ehw<$p9Zr? zN)tfwb%S1}ma7goY)Ca88Op8*d8)|RK7^4v&3XMC<2?>RG`HV8Wqd)*SGcTh*tOm` zIfG>g>GP6tydad;A9fj!h!!CWTa5P#f?5iEcG7rU$Uu5LaO#5bj38R!G_G%juiK3G z3A0*;fNefX1gi%48sUp{Q=TALN;eGlm}-Rmj$J+l-pV&s=5XK?R6)7vw-OW~$EKNz z1c@g%*ECU*BVoR4j9083&}ayBJwx@+h!vRLZ1mMk;=$DByoErA@q-O!RpmuR7)D`T)@yJNk4= zr|{GCG1_U^oZ>I+vJ>6y#|pKkygY;rQ#ji!seAhiqM4ajnEI7&CS-TRvI(i6jji~s z(vq0;MC!PKf@nwM{g+asx|ZgA(VM9wZWkG?U(bA#T9ePn&FNc`A@$v z-z6n&(!Aez%zP@@d)spJ9Eq8T|J`e5y%dyJ?P2p*LNobV{`cuPMlM-C^PhJHIz7^wajYpN)S)SS!+FJo0Av}~efwh)R$xZ&^BmKOpnL&&qwT6*T7wO101 z(m%0?K2Y#hm*@jB-6?_7UE8$J5r+ES*3B}+f0FC@+pK!7@(hrN$p2P(h!z$&UXh@u ztpaeq(kiQ zuRZI2VHA-@IC3MaoDm47+svYX>^H($k4^71Ogsj-E#AcnDluH)&S`+phT4`3OpV-Y zlr5=|8^Au!rXM3}MgV}SX(w|= zwq5uF9HL+8eW6`nEhYBCfn5b_uCXr?M;ei^aiLvYH?Ow4Azxr0tT>F|roV0(@N8BaT&8Nmv)eBu#%pJkx#14m(y zwUNq!e6vyCtqwxnpR!)q&pAlXJ%jF*$60jQ8v+z z$1$wB`s|a7IjqQO_g?6c>C_i&D(c^S&Mm`O2CG&Iua9^7ICPb~Uz_F}FBc?oTnhDb zoww^UxTvdFUU7%Py3`p-4t(-P=S?OTs&+d6$XPVMss9g~k2#01luBo^{hYH%GK*Yu zu4TQbcEMaQxs0;#VgHswILjsPO3i*(QcIM=!Tv5iTrB|=6HuVC$Q6_<=n!h-9uAIm z>0^!va6I6eAp~f9h1xzfkOyzgcCF^+0x;}KS?K5jJ-X2~tbnPd)Y%x8(H5c85+~i z(Ew#5J^Dz-X2u~@<_SxLgnT;1(=!qAK%Z)llMyIc;OWah;?yo(HU^#1t-#cQC)$*0)aQ^)APW# zY2{o2uk0WBhxRe45w4B(=@%frFHV;VZ9eQPRfA&SnCmYXogw1&G@le?cIiYuL3nY%^IP%E$Bk~>bqAtYsQZlNIB7X}r- zFofZmmfUW;B=%$R$T0zEK zoD$q-ghj={jdG9>DwR`6!)npu;C11Qtghb@oX1un>try>F~uvq|4Q%>Be14hXihSN z-r=Ej96|gT9;pb;;8Mnsd#gh=i~znu92A1-ePZjML(Pmp)jJ_SUo$EZxAA-^EW}}r b6!^3)v`BnX)fRW}8I%5|@lX-$S?c^RA7Rvt delta 5663 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 Yb9j;Xq^d3M+C3)yP2-_7)V;|4U#j`b&;S4c From 6439aba2d932f987aa2783faf0f0dc5baec546b2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Sep 2015 16:22:08 +1000 Subject: [PATCH 048/105] libc: More int32_t fixes to not expect 'long' libc built from projectgus/newlib-xtensa@45ed90066 --- libc/xtensa-lx106-elf/include/sys/_intsup.h | 20 ++------------------ libc/xtensa-lx106-elf/lib/libc.a | Bin 5105508 -> 5105508 bytes libc/xtensa-lx106-elf/lib/libg.a | Bin 5105508 -> 5105508 bytes libc/xtensa-lx106-elf/lib/libm.a | Bin 2241938 -> 2241938 bytes 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/libc/xtensa-lx106-elf/include/sys/_intsup.h b/libc/xtensa-lx106-elf/include/sys/_intsup.h index 7c3bc01..fa78426 100644 --- a/libc/xtensa-lx106-elf/include/sys/_intsup.h +++ b/libc/xtensa-lx106-elf/include/sys/_intsup.h @@ -4,6 +4,8 @@ * * Permission to use, copy, modify, and distribute this software * is freely granted, provided that this notice is preserved. + * + * Modified for xtensa arch & non-long int32_t, removes automatic setting of __have_long32. */ #ifndef _SYS__INTSUP_H @@ -11,26 +13,8 @@ #include -#if __GNUC_PREREQ (3, 2) -/* gcc > 3.2 implicitly defines the values we are interested */ #define __STDINT_EXP(x) __##x##__ -#else -#define __STDINT_EXP(x) x -#include -#endif -/* Check if "long long" is 64bit wide */ -/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */ -#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) #define __have_longlong64 1 -#endif - -/* Check if "long" is 64bit or 32bit wide */ -#if __STDINT_EXP(LONG_MAX) > 0x7fffffff -#define __have_long64 1 -#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) -#define __have_long32 1 -#endif #endif /* _SYS__INTSUP_H */ diff --git a/libc/xtensa-lx106-elf/lib/libc.a b/libc/xtensa-lx106-elf/lib/libc.a index 596e9f61e44bee4456c22f75a2e9a37a2211a733..33cfced655688d52c43010ecc882d3c052c4d5c9 100644 GIT binary patch delta 251 zcmWN~Syn*-0D$3>XdWd^h`-E3T{onnlG0>RJ^b%&#<2^la8BFE!}t8nXVb`h;Wr)Y zblXArgDgozmL)1NS&>y)lXcmUP1%xd*^yn@lYNQHfh6Qml5!-+aw4a4CMiivM$RQG zIaw?haw&N!NKr~smWouRCUt4Zm0U|8O$p^jTGEz|+)7vOnG zM_~{&$H;=jWKotRE(uwd6XdWd^h`-E3T{onnlG0>RJ^b%&#<2^la8BFE!}t8nXVb`h;Wr)Y zblXArgDgozmL)1NS&>y)lXcmUP1%xd*^yn@lYNQHfh6Qml5!-+aw4a4CMiivM$RQG zIaw?haw&N!NKr~smWouRCUt4Zm0U|8O$p^jTGEz|+)7vOnG zM_~{&$H;=jWKotRE(uwd6wWa+0$YQc5Kkxqjf)`~dJuAHo0t delta 122 zcmWN=$qj-4006tO wOeK^^W-^zBEG3qetYsrx*-0X)?ByUw$>b!toTZS9T;(RE+@+FQ9$)CYAL_0jwEzGB From 1aaef737df3e82e423a223bd854f45582f27a9a4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Sep 2015 21:10:49 +1000 Subject: [PATCH 049/105] Fix printf format string changed in merge --- examples/experiments/unaligned_load/unaligned_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index c65a818..e7c7c8e 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -97,7 +97,7 @@ uint32_t IRAM run_test(const char *string, test_with_fn_t testfn, const char *te uint32_t after = get_ccount(); vPortExitCritical(); uint32_t instructions = (after-before)/TEST_REPEATS - nullvalue; - printf("%5ld instructions\r\n", instructions); + printf("%5d instructions\r\n", instructions); return instructions; } From 91d897dbbe7793727c33a4b5a9cec0f89ff35819 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 12 Sep 2015 15:23:42 +1000 Subject: [PATCH 050/105] iomux: Fix setting of invalid bits when masking in iomux fields Fixes regression from 2a939e97 Part of issue #45 --- core/include/esp/iomux_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/esp/iomux_regs.h b/core/include/esp/iomux_regs.h index 4ea3be2..2600da9 100644 --- a/core/include/esp/iomux_regs.h +++ b/core/include/esp/iomux_regs.h @@ -45,7 +45,7 @@ _Static_assert(sizeof(struct IOMUX_REGS) == 0x44, "IOMUX_REGS is the wrong size" #define IOMUX_PIN_FUNC_MASK 0x00001030 /* WARNING: Macro evaluates argument twice */ -#define IOMUX_FUNC(val) (VAL2FIELD(IOMUX_PIN_FUNC_LOW, val) | VAL2FIELD(IOMUX_PIN_FUNC_HIGH, val)) +#define IOMUX_FUNC(val) (VAL2FIELD_M(IOMUX_PIN_FUNC_LOW, val) | VAL2FIELD_M(IOMUX_PIN_FUNC_HIGH, val)) /* WARNING: Macro evaluates argument twice */ #define IOMUX_FUNC_VALUE(regbits) (FIELD2VAL(IOMUX_PIN_FUNC_LOW, regbits) | FIELD2VAL(IOMUX_PIN_FUNC_HIGH, regbits)) From c45e84d61d2d3f784b0fae4d4612dc2a13ff714e Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 12 Sep 2015 16:20:05 +1000 Subject: [PATCH 051/105] Rename GPIO_CONF_PUSH_PULL to GPIO_CONF_OPEN_DRAIN Seems I got the functionality of this bit inverted when initially testing. In testing it also seems open drain mode is ignored on some pins, which still source current. Needs more investigation though (may be pullups internal to the ESP modules or set by default in software.) Relates to #45 --- core/include/esp/gpio.h | 10 ++++------ core/include/esp/gpio_regs.h | 15 ++++++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/core/include/esp/gpio.h b/core/include/esp/gpio.h index 1f1ce14..456625a 100644 --- a/core/include/esp/gpio.h +++ b/core/include/esp/gpio.h @@ -27,28 +27,26 @@ typedef enum { INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction) { uint32_t iomux_flags; - uint32_t ctrl_val; switch(direction) { case GPIO_INPUT: iomux_flags = 0; - ctrl_val = 0; break; case GPIO_OUTPUT: iomux_flags = IOMUX_PIN_OUTPUT_ENABLE; - ctrl_val = GPIO_CONF_PUSH_PULL; break; case GPIO_OUT_OPEN_DRAIN: iomux_flags = IOMUX_PIN_OUTPUT_ENABLE; - ctrl_val = 0; break; case GPIO_INPUT_PULLUP: iomux_flags = IOMUX_PIN_PULLUP; - ctrl_val = 0; break; } iomux_set_gpio_function(gpio_num, iomux_flags); - GPIO.CONF[gpio_num] = (GPIO.CONF[gpio_num] & FIELD_MASK(GPIO_CONF_INTTYPE)) | ctrl_val; + if(direction == GPIO_OUT_OPEN_DRAIN) + GPIO.CONF[gpio_num] |= GPIO_CONF_OPEN_DRAIN; + else + GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN; if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE) GPIO.ENABLE_OUT_SET = BIT(gpio_num); else diff --git a/core/include/esp/gpio_regs.h b/core/include/esp/gpio_regs.h index 3d91efb..815e7c1 100644 --- a/core/include/esp/gpio_regs.h +++ b/core/include/esp/gpio_regs.h @@ -76,10 +76,15 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); * Under what conditions this GPIO input should generate an interrupt. * (see gpio_inttype_t enum below for values) * - * GPIO_CONF_PUSH_PULL (boolean) - * When set, a high output state will pull the pin up to +Vcc (3.3V). When - * cleared, output functions in "open drain" mode (low state will pull down - * to ground, but high state allows output to "float"). + * GPIO_CONF_OPEN_DRAIN (boolean) + * If this bit is set, the pin is in "open drain" mode - a high output state + * will leave the pin floating but not source any current. If bit is cleared, + * the pin is in push/pull mode so a high output state will drive the pin up + * to +Vcc (3.3V). In either case, a low output state will pull the pin down + * to ground. + * + * GPIO_CONF_OPEN_DRAIN does not appear to work on all pins. + * * * GPIO_CONF_SOURCE_PWM (boolean) * When set, GPIO pin output will be connected to the sigma-delta PWM @@ -93,7 +98,7 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); #define GPIO_CONF_WAKEUP_ENABLE BIT(10) #define GPIO_CONF_INTTYPE_M 0x00000007 #define GPIO_CONF_INTTYPE_S 7 -#define GPIO_CONF_PUSH_PULL BIT(2) +#define GPIO_CONF_OPEN_DRAIN BIT(2) #define GPIO_CONF_SOURCE_PWM BIT(0) /* Valid values for the GPIO_CONF_INTTYPE field */ From 347f9d3a853605b5cae28d57f040b41932bdb1d2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 12 Sep 2015 16:28:11 +1000 Subject: [PATCH 052/105] Rename main.cpp in tasks example --- examples/cpp_01_tasks/{main.cpp => cpp_tasks.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/cpp_01_tasks/{main.cpp => cpp_tasks.cpp} (100%) diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/cpp_tasks.cpp similarity index 100% rename from examples/cpp_01_tasks/main.cpp rename to examples/cpp_01_tasks/cpp_tasks.cpp From a5a179beef0ab6aacd02420a997bc4a1f63f70a6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Sep 2015 15:02:47 +1000 Subject: [PATCH 053/105] Extended unaligned load support to work from DoubleExceptionVector Allows handling bad loads that occur inside level 1 exception handlers. --- core/exception_vectors.S | 99 ++++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 00c511d..a771667 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -15,6 +15,12 @@ Additions Copyright (C) Superhouse Automation Pty Ltd BSD Licensed as described in the file LICENSE */ + +/* Some UserException causes, see table Table 4–64 in ISA reference */ +#define CAUSE_SYSCALL 1 +#define CAUSE_LOADSTORE 3 +#define CAUSE_LVL1INT 4 + .text .section .vecbase.text, "x" .align 256 @@ -48,15 +54,15 @@ KernelExceptionVector: .align 16 UserExceptionVector: wsr.excsave1 a0 - call0 CallUserExceptionHandler - rfe /* CallUserExceptionHandler should call rfe itself */ - .align 16 -.L_EmptyVectorEntry2: - nop + rsr.exccause a0 + beqi a0, CAUSE_SYSCALL, UserSyscallHandler + beqi a0, CAUSE_LOADSTORE, UserExceptionLoadStoreHandler + j UserExceptionHandler + /* Empty exception slot goes here, but previous slot is large enough we can skip it */ .align 16 DoubleExceptionVector: break 1, 4 - call0 sdk_user_fatal_exception_handler + j DoubleExceptionHandler .align 16 .L_UnusedResetVector: /* reset vector slot doesn't get used, as vecbase goes back to mask ROM on reset */ @@ -171,24 +177,16 @@ CallNMIExceptionHandler: LOAD_REG a1, 1 rfi 0x3 -/* Some UserException causes, see table Table 4–64 in ISA reference */ -#define CAUSE_SYSCALL 1 -#define CAUSE_LOADSTORE 3 -#define CAUSE_LVL1INT 4 - - .type CallUserExceptionHandler, @function -CallUserExceptionHandler: - rsr.exccause a0 - beqi a0, CAUSE_SYSCALL, UserSyscallHandler - beqi a0, CAUSE_LOADSTORE, UserLoadStoreExceptionHandler - mov a0, sp + .type UserExceptionHandler, @function +UserExceptionHandler: + mov a0, sp /* a0 was saved in UserExceptionVector */ addi sp, sp, -0x50 s32i a0, sp, 0x10 rsr.ps a0 s32i a0, sp, 0x08 rsr.epc1 a0 s32i a0, sp, 0x04 - rsr.excsave1 a0 /* a0 was saved in UserExceptionVector */ + rsr.excsave1 a0 s32i a0, sp, 0x0c movi a0, _xt_user_exit s32i a0, sp, 0x0 @@ -244,24 +242,51 @@ UserSyscallHandler: rsr.excsave1 a0 rfe + .text + .section .vecbase.text + .literal_position + .align 4 +DoubleExceptionHandler: + rsr.exccause a0 + beqi a0, CAUSE_LOADSTORE, DoubleExceptionLoadStoreHandler + call0 sdk_user_fatal_exception_handler .text .section .vecbase.text .literal_position .align 4 - .global UserLoadStoreExceptionHandler -/* "Fix" LoadStoreException exceptions thatare l8/l16 from an Instruction region */ -UserLoadStoreExceptionHandler: + +/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, + DoubleException exception variant (ie load happened in a level1 exception handler). */ +DoubleExceptionLoadStoreHandler: addi sp, sp, -0x18 s32i a2, sp, 0x08 + rsr.epc2 a2 + j InnerLoadStoreExceptionHandler + + .text + .section .vecbase.text + .literal_position + .align 4 + +/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, + normal exception variant. */ +UserExceptionLoadStoreHandler: + addi sp, sp, -0x18 + s32i a2, sp, 0x08 + rsr.epc1 a2 +/* Inner UserLoadStoreExceptionHandler handlers. Works for both level1 & level 2 interrupt level. + * + * Called from level-specific handler above which sets up stack and loads epcX into a2. + */ +InnerLoadStoreExceptionHandler: s32i a3, sp, 0x0c s32i a4, sp, 0x10 s32i a5, sp, 0x14 rsr.sar a0 // save sar in a0 - /* Load the instruction we failed to execute */ - rsr.epc1 a2 - ssa8l a2 // sar is now correct shift to read a3 + /* Examine the instruction we failed to execute (in a2) */ + ssa8l a2 // sar is now correct shift for aligned read movi a3, ~3 and a2, a2, a3 // a2 now 4-byte aligned address of instruction l32i a3, a2, 0 @@ -324,16 +349,18 @@ UserLoadStoreExceptionHandler: s32i a4, a5, 0 .Lafter_write_value: - /* Footer*/ - //Increment PC + /* test PS.INTLEVEL (1=User, 2=Double) to see which interrupt level we restore from + */ + rsr.ps a2 + bbsi a2, 1, .Lincrement_PC_intlevel2 +.Lincrement_PC_intlevel1: rsr.epc1 a2 addi a3, a2, 0x3 wsr.epc1 a3 - -.Lexit: wsr.sar a0 // restore saved sar - // Restore registers rsr.excsave1 a0 // restore a0 saved in exception vector +.Lafter_increment_PC: + // Restore registers l32i a2, sp, 0x08 l32i a3, sp, 0x0c l32i a4, sp, 0x10 @@ -341,6 +368,14 @@ UserLoadStoreExceptionHandler: addi sp, sp, 0x18 rfe +.Lincrement_PC_intlevel2: + rsr.epc2 a2 + addi a3, a2, 0x3 + wsr.epc2 a3 + wsr.sar a0 // restore saved sar + rsr.excsave2 a0 // restore a0 saved in exception vector + j .Lafter_increment_PC + .Lextend_sign: /* apply 16-bit sign extension if necessary a3 holds raw value, a4 holds masked */ bbci a3, 15, .Lafter_extend_sign /* sign bit not set, do nothing */ @@ -388,10 +423,14 @@ UserLoadStoreExceptionHandler: j .Lafter_write_value .Lwrite_value_a0_reg: - /* a0 is saved in excsave1,so just update this with value */ + /* a0 is saved in excsave1,so just update this with value + TODO: This won't work with interrupt level 2 + */ wsr.excsave1 a4 j .Lafter_write_value +/* End of InnerUserLoadStoreExceptionHandler */ + .global _xt_user_exit .type _xt_user_exit, @function _xt_user_exit: From 45d4e0da2d231f7975ca51d5a8d22cfc51a8c1a1 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Sep 2015 21:35:18 +1000 Subject: [PATCH 054/105] Exception vectors: Rearrange to use absolute offets instead of .align hacks --- core/exception_vectors.S | 44 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index a771667..7e8241c 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -12,7 +12,7 @@ Part of esp-open-rtos Original vector contents Copyright (C) 2014-2015 Espressif Systems - Additions Copyright (C) Superhouse Automation Pty Ltd + Additions Copyright (C) Superhouse Automation Pty Ltd and Angus Gratton BSD Licensed as described in the file LICENSE */ @@ -23,9 +23,9 @@ .text .section .vecbase.text, "x" - .align 256 .global VecBase .type VecBase, @function /* it's not really a function, but treat it like one */ + .org 0 VecBase: /* IMPORTANT: exception vector literals will go here, but we can't have more than 4 otherwise we push DebugExceptionVector past @@ -33,40 +33,43 @@ VecBase: and also keep the VecBase offsets easy to read, but this works for now. */ .literal_position - .align 16 + .org 0x10 DebugExceptionVector: wsr.excsave2 a0 call0 sdk_user_fatal_exception_handler rfi 2 - .align 16 + + .org 0x20 NMIExceptionVector: wsr.excsave3 a0 call0 CallNMIExceptionHandler rfi 3 /* CallNMIExceptionHandler should call rfi itself */ - .align 16 + + .org 0x30 KernelExceptionVector: break 1, 0 call0 sdk_user_fatal_exception_handler rfe - .align 16 -.L_EmptyVectorEntry: - nop - .align 16 + + .org 0x50 UserExceptionVector: wsr.excsave1 a0 rsr.exccause a0 beqi a0, CAUSE_SYSCALL, UserSyscallHandler beqi a0, CAUSE_LOADSTORE, UserExceptionLoadStoreHandler j UserExceptionHandler - /* Empty exception slot goes here, but previous slot is large enough we can skip it */ - .align 16 + + .org 0x70 DoubleExceptionVector: break 1, 4 - j DoubleExceptionHandler - .align 16 -.L_UnusedResetVector: - /* reset vector slot doesn't get used, as vecbase goes back to mask ROM on reset */ - nop + rsr.exccause a0 + beqi a0, CAUSE_LOADSTORE, DoubleExceptionLoadStoreHandler + call0 sdk_user_fatal_exception_handler + +/* Reset vector would go here at offset 0x80 but should be unused, + as vecbase goes back to mask ROM vectors on reset */ + +/***** end of exception vectors *****/ .section .bss NMIHandlerStack: /* stack space for NMI handler */ @@ -242,15 +245,6 @@ UserSyscallHandler: rsr.excsave1 a0 rfe - .text - .section .vecbase.text - .literal_position - .align 4 -DoubleExceptionHandler: - rsr.exccause a0 - beqi a0, CAUSE_LOADSTORE, DoubleExceptionLoadStoreHandler - call0 sdk_user_fatal_exception_handler - .text .section .vecbase.text .literal_position From 0432ae374547f65eedababcf91bca77f047b7ba5 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Sep 2015 17:19:09 +1000 Subject: [PATCH 055/105] Use GPIO2 for led_debug.S --- core/exception_vectors.S | 3 ++- core/led_debug.s | 8 +++++--- examples/experiments/unaligned_load/unaligned_load.c | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 7e8241c..9d700b2 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -16,6 +16,8 @@ BSD Licensed as described in the file LICENSE */ +#include "led_debug.s" + /* Some UserException causes, see table Table 4–64 in ISA reference */ #define CAUSE_SYSCALL 1 #define CAUSE_LOADSTORE 3 @@ -314,7 +316,6 @@ InnerLoadStoreExceptionHandler: /* verified an 8- or 16-bit read a2 holds instruction, a5 holds mask to apply to read value */ - rsr.excvaddr a3 // read faulting address ssa8l a3 /* sar is now shift to extract a3's byte */ movi a4, ~3 diff --git a/core/led_debug.s b/core/led_debug.s index 8196c9e..28caf65 100644 --- a/core/led_debug.s +++ b/core/led_debug.s @@ -4,6 +4,8 @@ * * To have this work from initial reset, without needing an iomux call * first, choose a pin where iomux defaults to GPIO (ie 0,2,4,5) + * + * Current sets on=LOW, as the GPIO2 pin is active low */ LED_GPIO=2 GPIO_DIR_SET = 0x6000030c @@ -19,11 +21,11 @@ GPIO_OUT_CLEAR = 0x60000308 .endm // Turn LED on. rega, regb will be clobbered -.macro led_on rega, regb +.macro led_off rega, regb led_op \rega, \regb, GPIO_OUT_SET .endm -// Turn LED off. rega, regb will be clobbered -.macro led_off rega, regb +// Turn LED on. rega, regb will be clobbered +.macro led_on rega, regb led_op \rega, \regb, GPIO_OUT_CLEAR .endm diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index e7c7c8e..dd45a44 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -121,6 +121,10 @@ void test_string(const char *string, char *label, bool evict_cache) void user_init(void) { sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + + gpio_enable(2, GPIO_OUTPUT); /* used for LED debug */ + gpio_write(2, 1); /* active low */ + printf("\r\n\r\nSDK version:%s\r\n", sdk_system_get_sdk_version()); test_string(dramtest, "DRAM", 0); test_string(iramtest, "IRAM", 0); From 9c15b757d329e4bd971a6ab8a283e415db2cde81 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Sep 2015 17:22:50 +1000 Subject: [PATCH 056/105] Exception handlers: remove unused NMIHandlerAddress --- core/exception_vectors.S | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 9d700b2..1ba2eee 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -76,15 +76,10 @@ DoubleExceptionVector: .section .bss NMIHandlerStack: /* stack space for NMI handler */ .skip 4*0x100 +.LNMIHandlerStackTop: NMIRegisterSaved: /* register space for saving NMI registers */ .skip 4*(0x16 + 6) -/* this symbol is _Pri_3_HandlerAddress in the RTOS SDK, appears totally - unused (stays zero at all times) */ - .global NMIHandlerAddress -NMIHandlerAddress: - .long 0 - /* Save register relative to a0 */ .macro SAVE_REG register, regnum s32i \register, a0, (0x20 + 4 * \regnum) @@ -112,11 +107,9 @@ call_user_start: CallNMIExceptionHandler: movi a0, NMIRegisterSaved SAVE_REG a2, 2 - movi a2, NMIHandlerAddress - l32i a2, a2, 0 SAVE_REG sp, 1 SAVE_REG a3, 3 - xsr.excsave3 a2 /* excsave3 is now NMIHandlerAddress, a2 is former a0 */ + rsr.excsave3 a2 /* a2 is now former a0 */ SAVE_REG a4, 4 SAVE_REG a2, 0 rsr.epc1 a3 @@ -138,7 +131,7 @@ CallNMIExceptionHandler: SAVE_REG a13, 13 SAVE_REG a14, 14 SAVE_REG a15, 15 - movi sp, NMIRegisterSaved /* also top of NMIHandlerStack */ + movi sp, .LNMIHandlerStackTop movi a0, 0 movi a2, 0x23 /* argument for handler */ wsr.ps a2 From 0e0c5d89b8671373298d88a383b490814384346f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Sep 2015 17:43:29 +1000 Subject: [PATCH 057/105] NMI exception handler: Fix reserving too much RAM for registers --- core/exception_vectors.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 1ba2eee..5d5b74e 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -78,7 +78,7 @@ NMIHandlerStack: /* stack space for NMI handler */ .skip 4*0x100 .LNMIHandlerStackTop: NMIRegisterSaved: /* register space for saving NMI registers */ - .skip 4*(0x16 + 6) + .skip 4*(16 + 6) /* Save register relative to a0 */ .macro SAVE_REG register, regnum From 259c9b643fdc5f81b0e13f43812dd400523279bc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Sep 2015 18:17:45 +1000 Subject: [PATCH 058/105] Exception vectors: Remove no-op syscallhandler --- core/exception_vectors.S | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 5d5b74e..9df4f0d 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -57,7 +57,6 @@ KernelExceptionVector: UserExceptionVector: wsr.excsave1 a0 rsr.exccause a0 - beqi a0, CAUSE_SYSCALL, UserSyscallHandler beqi a0, CAUSE_LOADSTORE, UserExceptionLoadStoreHandler j UserExceptionHandler @@ -224,22 +223,6 @@ UserIntDone: UserIntExit: call0 sdk__xt_int_exit /* calls rfi */ -/* As far as I can tell, the syscall handler is basically a no-op */ -UserSyscallHandler: - addi sp, sp, -0x10 - s32i a2, sp, 0x08 - s32i a3, sp, 0x0c - rsr.epc1 a2 - addi a3, a2, 0x3 - wsr.epc1 a3 - l32i a2, sp, 0x8 - l32i a3, sp, 0xc - addi sp, sp, 0x10 - movi a0, 0x7f - movnez a2, a0, a2 - rsr.excsave1 a0 - rfe - .text .section .vecbase.text .literal_position From 26e1ce325ea5834dda3cea7f54d15ea3080db370 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Sep 2015 18:30:11 +1000 Subject: [PATCH 059/105] Fix sign extension as suggested by @foogod Also removes a branch from l8ui path, saves some cycles --- core/exception_vectors.S | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 9df4f0d..588a6a7 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -301,11 +301,7 @@ InnerLoadStoreExceptionHandler: srl a3, a3 /* shift right correct distance */ and a4, a3, a5 /* mask off bits we need for an l8/l16 */ - bbci a5, 14, .Lafter_extend_sign /* 8-bit, no sign extension */ - bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ - bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ - movi a3, (1<<31) - or a4, a3, a4 /* set 32-bit sign bit */ + bbsi a5, 14, .Lmaybe_extend_sign .Lafter_extend_sign: /* a2 holds instruction, a4 holds the correctly read value */ extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ @@ -347,11 +343,12 @@ InnerLoadStoreExceptionHandler: rsr.excsave2 a0 // restore a0 saved in exception vector j .Lafter_increment_PC -.Lextend_sign: /* apply 16-bit sign extension if necessary - a3 holds raw value, a4 holds masked */ - bbci a3, 15, .Lafter_extend_sign /* sign bit not set, do nothing */ - movi a3, (1<<31) - or a4, a3, a4 /* set sign bit */ +.Lmaybe_extend_sign: /* apply 16-bit sign extension if necessary + a3 holds raw value, a4 holds masked */ + bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ + bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ + movi a3, 0xFFFF0000 + or a4, a3, a4 /* set 32-bit sign bits */ j .Lafter_extend_sign .Lwrite_value_direct_reg: From 3911a94cc861ecb661612f246be0d53295cadcfa Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 15 Sep 2015 07:37:38 +1000 Subject: [PATCH 060/105] Remove one more branch from l8ui code path Thanks for @foogod for the heads-up on this. --- core/exception_vectors.S | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 588a6a7..c573d67 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -265,29 +265,16 @@ InnerLoadStoreExceptionHandler: l32i a4, a2, 4 src a2, a4, a3 // a2 now instruction that failed - /* Check if a2 matches l8ui, l16ui or l16si opcodes */ - movi a3, 0x00F00F /* opcode mask */ + /* Check if a2 matches l16ui, l16si or l8ui opcode */ + movi a3, 0x00700F /* opcode mask */ and a3, a2, a3 - beqi a3, 0x000002, .Lcan_fix_8bit /* l8ui opcode after masking */ - movi a4, 0x001002 /* l16ui opcode after masking */ + movi a4, 0x001002 /* l16si or l16ui opcode after masking */ beq a3, a4, .Lcan_fix_16bit - movi a4, 0x009002 /* l16si opcode after masking */ - beq a3, a4, .Lcan_fix_16bit_signed -.Lcant_fix: - /* not an opcode we can try to fix, so bomb out - TODO: the exception dump will have some wrong values in it */ - call0 sdk_user_fatal_exception_handler - -.Lcan_fix_16bit_signed: - movi a5, 0x7FFF - j .Lcan_fix -.Lcan_fix_16bit: - movi a5, 0xFFFF - j .Lcan_fix -.Lcan_fix_8bit: + bnei a3, 0x000002, .Lcant_fix /* no l8ui opcode, then can't fix */ movi a5, 0xFF + .Lcan_fix: /* verified an 8- or 16-bit read a2 holds instruction, a5 holds mask to apply to read value @@ -335,6 +322,15 @@ InnerLoadStoreExceptionHandler: addi sp, sp, 0x18 rfe +.Lcan_fix_16bit: + movi a5, 0xFFFF + j .Lcan_fix + +.Lcant_fix: + /* not an opcode we can try to fix, so bomb out + TODO: the exception dump will have some wrong values in it */ + call0 sdk_user_fatal_exception_handler + .Lincrement_PC_intlevel2: rsr.epc2 a2 addi a3, a2, 0x3 From c7a7dfdf828158c7539c3b8c49a6381aee8f0558 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 15 Sep 2015 11:22:59 +1000 Subject: [PATCH 061/105] Remove the unaligned load handler to its own source file as it was getting quite complex The downside here is needing to use #include so the 'beq' in the exception vector can land on it directly, save an instruction. There might be a better way to do this, but it seems hard to "curate" the order that symbols appear in each section. --- common.mk | 1 + core/exception_unaligned_load.S.inc | 191 ++++++++++++++++++++++++++++ core/exception_vectors.S | 180 ++------------------------ 3 files changed, 201 insertions(+), 171 deletions(-) create mode 100644 core/exception_unaligned_load.S.inc diff --git a/common.mk b/common.mk index f1d6477..a893e29 100644 --- a/common.mk +++ b/common.mk @@ -241,6 +241,7 @@ $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.S $$($(1)_MAKEFILE) $(wildcard $(ROOT)* $(vecho) "AS $$<" $(Q) mkdir -p $$(dir $$@) $$($(1)_CC_ARGS) -c $$< -o $$@ + $$($(1)_CC_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$< # the component is shown to depend on both obj and source files so we get a meaningful error message # for missing explicitly named source files diff --git a/core/exception_unaligned_load.S.inc b/core/exception_unaligned_load.S.inc new file mode 100644 index 0000000..5963746 --- /dev/null +++ b/core/exception_unaligned_load.S.inc @@ -0,0 +1,191 @@ +/* Xtensa Exception unaligned load handler + + Completes l8/l16 load instructions from Instruction address space, + that the architecture require to be 4 byte aligned word reads. + + Called from either UserExceptionVector or DoubleExceptionVector + depending on where the exception happened. + + Fast path (no branches) is for l8ui. + + Part of esp-open-rtos + Copyright (C) Angus Gratton + BSD Licensed as described in the file LICENSE +*/ + .text + .section .vecbase.text, "x" + .literal_position + +/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, + normal exception variant. */ +UserExceptionLoadStoreHandler: + addi sp, sp, -0x18 + s32i a2, sp, 0x08 + rsr.epc1 a2 +/* Inner UserLoadStoreExceptionHandler handlers. Works for both level1 & level 2 interrupt level. + * + * Called from level-specific handler above which sets up stack and loads epcX into a2. + */ +InnerLoadStoreExceptionHandler: + s32i a3, sp, 0x0c + s32i a4, sp, 0x10 + s32i a5, sp, 0x14 + rsr.sar a0 // save sar in a0 + + /* Examine the instruction we failed to execute (in a2) */ + ssa8l a2 // sar is now correct shift for aligned read + movi a3, ~3 + and a2, a2, a3 // a2 now 4-byte aligned address of instruction + l32i a3, a2, 0 + l32i a4, a2, 4 + src a2, a4, a3 // a2 now instruction that failed + + /* Check if a2 matches l16ui, l16si or l8ui opcode */ + movi a3, 0x00700F /* opcode mask */ + and a3, a2, a3 + + movi a4, 0x001002 /* l16si or l16ui opcode after masking */ + beq a3, a4, .Lcan_fix_16bit + + bnei a3, 0x000002, .Lcant_fix /* no l8ui opcode, then can't fix */ + movi a5, 0xFF + +.Lcan_fix: + /* verified an 8- or 16-bit read + a2 holds instruction, a5 holds mask to apply to read value + */ + rsr.excvaddr a3 // read faulting address + ssa8l a3 /* sar is now shift to extract a3's byte */ + movi a4, ~3 + and a3, a3, a4 /* a3 now word aligned read address */ + + l32i a3, a3, 0 /* perform the actual read */ + srl a3, a3 /* shift right correct distance */ + and a4, a3, a5 /* mask off bits we need for an l8/l16 */ + + bbsi a5, 14, .Lmaybe_extend_sign +.Lafter_extend_sign: + /* a2 holds instruction, a4 holds the correctly read value */ + extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ + + /* test if a4 needs to be written directly to a register (ie not a working register) */ + bgei a2, 6, .Lwrite_value_direct_reg + /* test if a4 needs to be written to a0 */ + beqz a2, .Lwrite_value_a0_reg + + /* otherwise, a4 can be written to a saved working register 'slot' on the stack */ + addx4 a5, a2, sp + s32i a4, a5, 0 + +.Lafter_write_value: + /* test PS.INTLEVEL (1=User, 2=Double) to see which interrupt level we restore from + */ + rsr.ps a2 + bbsi a2, 1, .Lincrement_PC_intlevel2 +.Lincrement_PC_intlevel1: + rsr.epc1 a2 + addi a3, a2, 0x3 + wsr.epc1 a3 + wsr.sar a0 // restore saved sar + rsr.excsave1 a0 // restore a0 saved in exception vector +.Lafter_increment_PC: + // Restore registers + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + l32i a5, sp, 0x14 + addi sp, sp, 0x18 + rfe + + + .literal_position +/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, + DoubleException exception variant (ie load happened in a level1 exception handler). */ +DoubleExceptionLoadStoreHandler: + addi sp, sp, -0x18 + s32i a2, sp, 0x08 + rsr.epc2 a2 + j InnerLoadStoreExceptionHandler + +/* Load mask for an l16si/16ui instruction that needs loading + + First test for a signed vs unsigned load. + + a2 is the instruction, need to load a5 with the mask to use */ +.Lcan_fix_16bit: + bbsi a2, 15, .Lcan_fix_16bit_signed + movi a5, 0xFFFF + j .Lcan_fix +.Lcan_fix_16bit_signed: + movi a5, 0x7FFF + j .Lcan_fix + +/* not an opcode we can try to fix, so bomb out + TODO: the exception dump will have some wrong values in it */ +.Lcant_fix: + call0 sdk_user_fatal_exception_handler + +/* increment PC for a DoubleException */ +.Lincrement_PC_intlevel2: + rsr.epc2 a2 + addi a3, a2, 0x3 + wsr.epc2 a3 + wsr.sar a0 // restore saved sar + rsr.excsave2 a0 // restore a0 saved in exception vector + j .Lafter_increment_PC + +.Lmaybe_extend_sign: /* apply 16-bit sign extension if necessary + a3 holds raw value, a4 holds masked */ + bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ + bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ + movi a3, 0xFFFF0000 + or a4, a3, a4 /* set 32-bit sign bits */ + j .Lafter_extend_sign + +.Lwrite_value_direct_reg: + /* Directly update register index a2, in range 6-15, using value in a4 */ + addi a2, a2, -6 + slli a2, a2, 3 /* offset from a6, x8 */ + movi a3, .Ldirect_reg_jumptable + add a2, a2, a3 + jx a2 + .align 8 +.Ldirect_reg_jumptable: + mov a6, a4 + j .Lafter_write_value + .align 8 + mov a7, a4 + j .Lafter_write_value + .align 8 + mov a8, a4 + j .Lafter_write_value + .align 8 + mov a9, a4 + j .Lafter_write_value + .align 8 + mov a10, a4 + j .Lafter_write_value + .align 8 + mov a11, a4 + j .Lafter_write_value + .align 8 + mov a12, a4 + j .Lafter_write_value + .align 8 + mov a13, a4 + j .Lafter_write_value + .align 8 + mov a14, a4 + j .Lafter_write_value + .align 8 + mov a15, a4 + j .Lafter_write_value + +.Lwrite_value_a0_reg: + /* a0 is saved in excsave1,so just update this with value + TODO: This won't work with interrupt level 2 + */ + wsr.excsave1 a4 + j .Lafter_write_value + +/* End of InnerUserLoadStoreExceptionHandler */ diff --git a/core/exception_vectors.S b/core/exception_vectors.S index c573d67..270b711 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -72,6 +72,11 @@ DoubleExceptionVector: /***** end of exception vectors *****/ +/* We include this here so UserExceptionLoadStoreHandler is within + the range of a 'beq' instruction jump. +*/ +#include "exception_unaligned_load.S.inc" + .section .bss NMIHandlerStack: /* stack space for NMI handler */ .skip 4*0x100 @@ -223,178 +228,11 @@ UserIntDone: UserIntExit: call0 sdk__xt_int_exit /* calls rfi */ +/* _xt_user_exit is used to exit interrupt context. + TODO: Find a better place for this to live. +*/ .text - .section .vecbase.text - .literal_position - .align 4 - -/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, - DoubleException exception variant (ie load happened in a level1 exception handler). */ -DoubleExceptionLoadStoreHandler: - addi sp, sp, -0x18 - s32i a2, sp, 0x08 - rsr.epc2 a2 - j InnerLoadStoreExceptionHandler - - .text - .section .vecbase.text - .literal_position - .align 4 - -/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, - normal exception variant. */ -UserExceptionLoadStoreHandler: - addi sp, sp, -0x18 - s32i a2, sp, 0x08 - rsr.epc1 a2 -/* Inner UserLoadStoreExceptionHandler handlers. Works for both level1 & level 2 interrupt level. - * - * Called from level-specific handler above which sets up stack and loads epcX into a2. - */ -InnerLoadStoreExceptionHandler: - s32i a3, sp, 0x0c - s32i a4, sp, 0x10 - s32i a5, sp, 0x14 - rsr.sar a0 // save sar in a0 - - /* Examine the instruction we failed to execute (in a2) */ - ssa8l a2 // sar is now correct shift for aligned read - movi a3, ~3 - and a2, a2, a3 // a2 now 4-byte aligned address of instruction - l32i a3, a2, 0 - l32i a4, a2, 4 - src a2, a4, a3 // a2 now instruction that failed - - /* Check if a2 matches l16ui, l16si or l8ui opcode */ - movi a3, 0x00700F /* opcode mask */ - and a3, a2, a3 - - movi a4, 0x001002 /* l16si or l16ui opcode after masking */ - beq a3, a4, .Lcan_fix_16bit - - bnei a3, 0x000002, .Lcant_fix /* no l8ui opcode, then can't fix */ - movi a5, 0xFF - -.Lcan_fix: - /* verified an 8- or 16-bit read - a2 holds instruction, a5 holds mask to apply to read value - */ - rsr.excvaddr a3 // read faulting address - ssa8l a3 /* sar is now shift to extract a3's byte */ - movi a4, ~3 - and a3, a3, a4 /* a3 now word aligned read address */ - - l32i a3, a3, 0 /* perform the actual read */ - srl a3, a3 /* shift right correct distance */ - and a4, a3, a5 /* mask off bits we need for an l8/l16 */ - - bbsi a5, 14, .Lmaybe_extend_sign -.Lafter_extend_sign: - /* a2 holds instruction, a4 holds the correctly read value */ - extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ - - /* test if a4 needs to be written directly to a register (ie not a working register) */ - bgei a2, 6, .Lwrite_value_direct_reg - /* test if a4 needs to be written to a0 */ - beqz a2, .Lwrite_value_a0_reg - - /* otherwise, a4 can be written to a saved working register 'slot' on the stack */ - addx4 a5, a2, sp - s32i a4, a5, 0 - -.Lafter_write_value: - /* test PS.INTLEVEL (1=User, 2=Double) to see which interrupt level we restore from - */ - rsr.ps a2 - bbsi a2, 1, .Lincrement_PC_intlevel2 -.Lincrement_PC_intlevel1: - rsr.epc1 a2 - addi a3, a2, 0x3 - wsr.epc1 a3 - wsr.sar a0 // restore saved sar - rsr.excsave1 a0 // restore a0 saved in exception vector -.Lafter_increment_PC: - // Restore registers - l32i a2, sp, 0x08 - l32i a3, sp, 0x0c - l32i a4, sp, 0x10 - l32i a5, sp, 0x14 - addi sp, sp, 0x18 - rfe - -.Lcan_fix_16bit: - movi a5, 0xFFFF - j .Lcan_fix - -.Lcant_fix: - /* not an opcode we can try to fix, so bomb out - TODO: the exception dump will have some wrong values in it */ - call0 sdk_user_fatal_exception_handler - -.Lincrement_PC_intlevel2: - rsr.epc2 a2 - addi a3, a2, 0x3 - wsr.epc2 a3 - wsr.sar a0 // restore saved sar - rsr.excsave2 a0 // restore a0 saved in exception vector - j .Lafter_increment_PC - -.Lmaybe_extend_sign: /* apply 16-bit sign extension if necessary - a3 holds raw value, a4 holds masked */ - bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ - bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ - movi a3, 0xFFFF0000 - or a4, a3, a4 /* set 32-bit sign bits */ - j .Lafter_extend_sign - -.Lwrite_value_direct_reg: - /* Directly update register index a2, in range 6-15, using value in a4 */ - addi a2, a2, -6 - slli a2, a2, 3 /* offset from a6, x8 */ - movi a3, .Ldirect_reg_jumptable - add a2, a2, a3 - jx a2 - .align 8 -.Ldirect_reg_jumptable: - mov a6, a4 - j .Lafter_write_value - .align 8 - mov a7, a4 - j .Lafter_write_value - .align 8 - mov a8, a4 - j .Lafter_write_value - .align 8 - mov a9, a4 - j .Lafter_write_value - .align 8 - mov a10, a4 - j .Lafter_write_value - .align 8 - mov a11, a4 - j .Lafter_write_value - .align 8 - mov a12, a4 - j .Lafter_write_value - .align 8 - mov a13, a4 - j .Lafter_write_value - .align 8 - mov a14, a4 - j .Lafter_write_value - .align 8 - mov a15, a4 - j .Lafter_write_value - -.Lwrite_value_a0_reg: - /* a0 is saved in excsave1,so just update this with value - TODO: This won't work with interrupt level 2 - */ - wsr.excsave1 a4 - j .Lafter_write_value - -/* End of InnerUserLoadStoreExceptionHandler */ - + .section .text .global _xt_user_exit .type _xt_user_exit, @function _xt_user_exit: From 7ebebf6d2286c7586a631cd6ba4bd6cf61e8f024 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 15 Sep 2015 11:44:56 +1000 Subject: [PATCH 062/105] unaligned_load: Add doubleexceptionvector behaviour test --- .../unaligned_load/unaligned_load.c | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index dd45a44..e70538b 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -1,6 +1,7 @@ /* Very basic example that just demonstrates we can run at all! */ #include "esp/rom.h" +#include "esp/timer.h" #include "espressif/esp_common.h" #include "espressif/sdk_private.h" #include "FreeRTOS.h" @@ -118,6 +119,8 @@ void test_string(const char *string, char *label, bool evict_cache) run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache); } +static void test_doubleexceptions(); + void user_init(void) { sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); @@ -130,4 +133,39 @@ void user_init(void) test_string(iramtest, "IRAM", 0); test_string(iromtest, "Cached flash", 0); test_string(iromtest, "'Uncached' flash", 1); + + test_doubleexceptions(); +} + +static volatile bool frc1_ran; +static volatile bool frc1_finished; +static volatile char frc1_buf[80]; + +static void frc1_interrupt_handler(void) +{ + frc1_ran = true; + timer_set_run(FRC1, false); + strcpy((char *)frc1_buf, iramtest); + frc1_finished = true; +} + +static void test_doubleexceptions() +{ + printf("Testing DoubleException behaviour...\r\n"); + timer_set_interrupts(FRC1, false); + timer_set_run(FRC1, false); + _xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler); + timer_set_frequency(FRC1, 1000); + timer_set_interrupts(FRC1, true); + timer_set_run(FRC1, true); + sdk_os_delay_us(2000); + + if(!frc1_ran) + printf("ERROR: FRC1 timer exception never fired.\r\n"); + else if(!frc1_finished) + printf("ERROR: FRC1 timer exception never finished.\r\n"); + else if(strcmp((char *)frc1_buf, iramtest)) + printf("ERROR: FRC1 strcpy from IRAM failed.\r\n"); + else + printf("PASSED\r\n"); } From 7d779389ab86c42d04131af2d304ff78cfa4c0dc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 15 Sep 2015 12:00:06 +1000 Subject: [PATCH 063/105] unaligned_load: Fix sign extension, add test case for sign extension H/T to @foogod again for this. --- core/exception_unaligned_load.S.inc | 2 +- .../unaligned_load/unaligned_load.c | 28 ++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/core/exception_unaligned_load.S.inc b/core/exception_unaligned_load.S.inc index 5963746..553fe84 100644 --- a/core/exception_unaligned_load.S.inc +++ b/core/exception_unaligned_load.S.inc @@ -138,7 +138,7 @@ DoubleExceptionLoadStoreHandler: a3 holds raw value, a4 holds masked */ bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ - movi a3, 0xFFFF0000 + movi a3, 0xFFFF8000 or a4, a3, a4 /* set 32-bit sign bits */ j .Lafter_extend_sign diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index e70538b..ddf251b 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -68,7 +68,11 @@ void test_naive_strcpy(const char *string) void test_l16si(const char *string) { /* This follows most of the l16si path, but as the - values in the string are all 7 bit none of them get sign extended */ + values in the string are all 7 bit none of them get sign extended. + + See separate test_sign_extension function which validates + sign extension works as expected. + */ int16_t *src_int16 = (int16_t *)string; int32_t *dst_int32 = (int32_t *)buf; dst_int32[0] = src_int16[0]; @@ -119,7 +123,8 @@ void test_string(const char *string, char *label, bool evict_cache) run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache); } -static void test_doubleexceptions(); +static void test_doubleexception(); +static void test_sign_extension(); void user_init(void) { @@ -134,7 +139,8 @@ void user_init(void) test_string(iromtest, "Cached flash", 0); test_string(iromtest, "'Uncached' flash", 1); - test_doubleexceptions(); + test_doubleexception(); + test_sign_extension(); } static volatile bool frc1_ran; @@ -149,7 +155,7 @@ static void frc1_interrupt_handler(void) frc1_finished = true; } -static void test_doubleexceptions() +static void test_doubleexception() { printf("Testing DoubleException behaviour...\r\n"); timer_set_interrupts(FRC1, false); @@ -169,3 +175,17 @@ static void test_doubleexceptions() else printf("PASSED\r\n"); } + +const volatile __attribute__((section(".iram1.notliterals"))) int16_t unsigned_shorts[] = { -3, -4, -5, -32767, 44 }; + +static void test_sign_extension() +{ + /* this step seems to be necessary so the compiler will actually generate l16si */ + int16_t *shorts_p = (int16_t *)unsigned_shorts; + if(shorts_p[0] == -3 && shorts_p[1] == -4 && shorts_p[2] == -5 && shorts_p[3] == -32767 && shorts_p[4] == 44) + { + printf("l16si sign extension worked as expected.\r\n"); + } else { + printf("l16si sign extension failed. Got values %d %d %d %d %d\r\n", shorts_p[0], shorts_p[1], shorts_p[2], shorts_p[3], shorts_p[4]); + } +} From 9cd23e08a4f5ea8d39140ea3002667883db4e71a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 15 Sep 2015 15:00:56 +1000 Subject: [PATCH 064/105] Fix performance regression in 3911a94cc --- core/exception_unaligned_load.S.inc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/core/exception_unaligned_load.S.inc b/core/exception_unaligned_load.S.inc index 553fe84..5540f72 100644 --- a/core/exception_unaligned_load.S.inc +++ b/core/exception_unaligned_load.S.inc @@ -40,14 +40,10 @@ InnerLoadStoreExceptionHandler: l32i a4, a2, 4 src a2, a4, a3 // a2 now instruction that failed - /* Check if a2 matches l16ui, l16si or l8ui opcode */ - movi a3, 0x00700F /* opcode mask */ + /* check for l8ui opcode 0x000002, or branch to check l16 */ + movi a3, 0x00700F /* opcode mask for l8ui/l16si/l16ui */ and a3, a2, a3 - - movi a4, 0x001002 /* l16si or l16ui opcode after masking */ - beq a3, a4, .Lcan_fix_16bit - - bnei a3, 0x000002, .Lcant_fix /* no l8ui opcode, then can't fix */ + bnei a3, 0x000002, .Lcheck_fix_16bit movi a5, 0xFF .Lcan_fix: @@ -107,12 +103,15 @@ DoubleExceptionLoadStoreHandler: rsr.epc2 a2 j InnerLoadStoreExceptionHandler -/* Load mask for an l16si/16ui instruction that needs loading +/* Check the load instruction a2 for an l16si/16ui instruction First test for a signed vs unsigned load. a2 is the instruction, need to load a5 with the mask to use */ -.Lcan_fix_16bit: +.Lcheck_fix_16bit: + movi a4, 0x001002 /* l16si or l16ui opcode after masking */ + bne a3, a4, .Lcant_fix + bbsi a2, 15, .Lcan_fix_16bit_signed movi a5, 0xFFFF j .Lcan_fix From f47aa77982509d14bcc84cd47ec38f588b6ac832 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 15 Sep 2015 15:09:42 +1000 Subject: [PATCH 065/105] Moved DoubleLoadStorageHandler to end of functions, improve fast path l8ui performance This allows a conditional branch that previously required a full jump instruction not to require it. --- core/exception_unaligned_load.S.inc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/exception_unaligned_load.S.inc b/core/exception_unaligned_load.S.inc index 5540f72..03c9830 100644 --- a/core/exception_unaligned_load.S.inc +++ b/core/exception_unaligned_load.S.inc @@ -94,15 +94,6 @@ InnerLoadStoreExceptionHandler: rfe - .literal_position -/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, - DoubleException exception variant (ie load happened in a level1 exception handler). */ -DoubleExceptionLoadStoreHandler: - addi sp, sp, -0x18 - s32i a2, sp, 0x08 - rsr.epc2 a2 - j InnerLoadStoreExceptionHandler - /* Check the load instruction a2 for an l16si/16ui instruction First test for a signed vs unsigned load. @@ -187,4 +178,13 @@ DoubleExceptionLoadStoreHandler: wsr.excsave1 a4 j .Lafter_write_value + .literal_position +/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, + DoubleException exception variant (ie load happened in a level1 exception handler). */ +DoubleExceptionLoadStoreHandler: + addi sp, sp, -0x18 + s32i a2, sp, 0x08 + rsr.epc2 a2 + j InnerLoadStoreExceptionHandler + /* End of InnerUserLoadStoreExceptionHandler */ From cceb9de300affe5b4092951a9d252df05a28d870 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 18 Sep 2015 17:59:47 +1000 Subject: [PATCH 066/105] bmp180 i2c: Fix typo temperatue->temperature. Closes #47 --- examples/bmp180_i2c/bmp180_i2c.c | 6 +++--- extras/bmp180/bmp180.c | 8 ++++---- extras/bmp180/bmp180.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/bmp180_i2c/bmp180_i2c.c b/examples/bmp180_i2c/bmp180_i2c.c index 15c0508..578db67 100644 --- a/examples/bmp180_i2c/bmp180_i2c.c +++ b/examples/bmp180_i2c/bmp180_i2c.c @@ -30,13 +30,13 @@ static xQueueHandle mainqueue; static xTimerHandle timerHandle; // Own BMP180 User Inform Implementation -bool bmp180_i2c_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) +bool bmp180_i2c_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure) { my_event_t ev; ev.event_type = MY_EVT_BMP180; ev.bmp180_data.cmd = cmd; - ev.bmp180_data.temperatue = temperatue; + ev.bmp180_data.temperature = temperature; ev.bmp180_data.pressure = pressure; return (xQueueSend(*resultQueue, &ev, 0) == pdTRUE); @@ -74,7 +74,7 @@ void bmp180_task(void *pvParameters) break; case MY_EVT_BMP180: printf("%s: Received BMP180 Event temp:=%d.%d°C press=%d.%02dhPa\n", __FUNCTION__, \ - (int32_t)ev.bmp180_data.temperatue, abs((int32_t)(ev.bmp180_data.temperatue*10)%10), \ + (int32_t)ev.bmp180_data.temperature, abs((int32_t)(ev.bmp180_data.temperature*10)%10), \ ev.bmp180_data.pressure/100, ev.bmp180_data.pressure%100 ); break; default: diff --git a/extras/bmp180/bmp180.c b/extras/bmp180/bmp180.c index 66203b0..7291236 100644 --- a/extras/bmp180/bmp180.c +++ b/extras/bmp180/bmp180.c @@ -75,10 +75,10 @@ static int16_t MD; // Forward declarations // static void bmp180_meassure(const bmp180_command_t* command); -static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure); +static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure); // Set default implementation .. User gets result as bmp180_result_t event -bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) = bmp180_informUser_Impl; +bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure) = bmp180_informUser_Impl; // I2C Driver Task static void bmp180_driver_task(void *pvParameters) @@ -279,12 +279,12 @@ static void bmp180_meassure(const bmp180_command_t* command) } // Default user inform implementation -static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) +static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure) { bmp180_result_t result; result.cmd = cmd; - result.temperatue = temperatue; + result.temperature = temperature; result.pressure = pressure; return (xQueueSend(*resultQueue, &result, 0) == pdTRUE); diff --git a/extras/bmp180/bmp180.h b/extras/bmp180/bmp180.h index 73709ff..b675130 100644 --- a/extras/bmp180/bmp180.h +++ b/extras/bmp180/bmp180.h @@ -33,7 +33,7 @@ typedef uint32_t bmp180_press_t; typedef struct { uint8_t cmd; - bmp180_temp_t temperatue; + bmp180_temp_t temperature; bmp180_press_t pressure; } bmp180_result_t; @@ -50,6 +50,6 @@ void bmp180_trigger_temperature_measurement(const xQueueHandle* resultQueue); void bmp180_trigger_pressure_measurement(const xQueueHandle* resultQueue); // Give the user the chance to create it's own handler -extern bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure); +extern bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure); #endif /* DRIVER_BMP180_H_ */ From 4c89a0574b97a893dc7984431a5a4257298907d3 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Sat, 19 Sep 2015 15:16:44 -0700 Subject: [PATCH 067/105] Add sanity-test suite to unaligned_load.c Tests are designed to methodically exercise all code paths/opcodes/offsets/etc. --- .../unaligned_load/unaligned_load.c | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index ddf251b..3cfe471 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -125,6 +125,7 @@ void test_string(const char *string, char *label, bool evict_cache) static void test_doubleexception(); static void test_sign_extension(); +void sanity_tests(void); void user_init(void) { @@ -134,6 +135,7 @@ void user_init(void) gpio_write(2, 1); /* active low */ printf("\r\n\r\nSDK version:%s\r\n", sdk_system_get_sdk_version()); + sanity_tests(); test_string(dramtest, "DRAM", 0); test_string(iramtest, "IRAM", 0); test_string(iromtest, "Cached flash", 0); @@ -189,3 +191,126 @@ static void test_sign_extension() printf("l16si sign extension failed. Got values %d %d %d %d %d\r\n", shorts_p[0], shorts_p[1], shorts_p[2], shorts_p[3], shorts_p[4]); } } + +/* The following "sanity tests" are designed to try to execute every code path + * of the LoadStoreError handler, with a variety of offsets and data values + * designed to catch any mask/shift errors, sign-extension bugs, etc */ + +/* (Contrary to expectations, 'mov a15, a15' in Xtensa is not technically a + * no-op, but is officially "undefined and reserved for future use", so we need + * a special case in the case where reg == "a15" so we don't end up generating + * those opcodes. GCC is smart enough to optimize away the whole conditional + * and just insert the correct asm block, since `reg` is a static argument.) */ +#define LOAD_VIA_REG(op, reg, addr, var) \ + if (strcmp(reg, "a15")) { \ + asm volatile ( \ + "mov a15, " reg "\n\t" \ + op " " reg ", %1, 0\n\t" \ + "mov %0, " reg "\n\t" \ + "mov " reg ", a15\n\t" \ + : "=r" (var) : "r" (addr) : "a15" ); \ + } else { \ + asm volatile ( \ + op " " reg ", %1, 0\n\t" \ + "mov %0, " reg "\n\t" \ + : "=r" (var) : "r" (addr) : "a15" ); \ + } + +#define TEST_LOAD(op, reg, addr, value) \ + { \ + int32_t result; \ + LOAD_VIA_REG(op, reg, addr, result); \ + if (result != value) sanity_test_failed(op, reg, addr, value, result); \ + } + +void sanity_test_failed(const char *testname, const char *reg, const void *addr, int32_t value, int32_t result) { + uint32_t actual_data = *(uint32_t *)((uint32_t)addr & 0xfffffffc); + + printf("*** SANITY TEST FAILED: '%s %s' from %p (underlying 32-bit value: 0x%x): Expected 0x%08x (%d), got 0x%08x (%d)\n", testname, reg, addr, actual_data, value, value, result, result); +} + +const __attribute__((section(".iram1.notrodata"))) char sanity_test_data[] = { + 0x01, 0x55, 0x7e, 0x2a, 0x81, 0xd5, 0xfe, 0xaa +}; + +void sanity_test_l8ui(const void *addr, int32_t value) { + TEST_LOAD("l8ui", "a0", addr, value); + TEST_LOAD("l8ui", "a1", addr, value); + TEST_LOAD("l8ui", "a2", addr, value); + TEST_LOAD("l8ui", "a3", addr, value); + TEST_LOAD("l8ui", "a4", addr, value); + TEST_LOAD("l8ui", "a5", addr, value); + TEST_LOAD("l8ui", "a6", addr, value); + TEST_LOAD("l8ui", "a7", addr, value); + TEST_LOAD("l8ui", "a8", addr, value); + TEST_LOAD("l8ui", "a9", addr, value); + TEST_LOAD("l8ui", "a10", addr, value); + TEST_LOAD("l8ui", "a11", addr, value); + TEST_LOAD("l8ui", "a12", addr, value); + TEST_LOAD("l8ui", "a13", addr, value); + TEST_LOAD("l8ui", "a14", addr, value); + TEST_LOAD("l8ui", "a15", addr, value); +} + +void sanity_test_l16ui(const void *addr, int32_t value) { + TEST_LOAD("l16ui", "a0", addr, value); + TEST_LOAD("l16ui", "a1", addr, value); + TEST_LOAD("l16ui", "a2", addr, value); + TEST_LOAD("l16ui", "a3", addr, value); + TEST_LOAD("l16ui", "a4", addr, value); + TEST_LOAD("l16ui", "a5", addr, value); + TEST_LOAD("l16ui", "a6", addr, value); + TEST_LOAD("l16ui", "a7", addr, value); + TEST_LOAD("l16ui", "a8", addr, value); + TEST_LOAD("l16ui", "a9", addr, value); + TEST_LOAD("l16ui", "a10", addr, value); + TEST_LOAD("l16ui", "a11", addr, value); + TEST_LOAD("l16ui", "a12", addr, value); + TEST_LOAD("l16ui", "a13", addr, value); + TEST_LOAD("l16ui", "a14", addr, value); + TEST_LOAD("l16ui", "a15", addr, value); +} + +void sanity_test_l16si(const void *addr, int32_t value) { + TEST_LOAD("l16si", "a0", addr, value); + TEST_LOAD("l16si", "a1", addr, value); + TEST_LOAD("l16si", "a2", addr, value); + TEST_LOAD("l16si", "a3", addr, value); + TEST_LOAD("l16si", "a4", addr, value); + TEST_LOAD("l16si", "a5", addr, value); + TEST_LOAD("l16si", "a6", addr, value); + TEST_LOAD("l16si", "a7", addr, value); + TEST_LOAD("l16si", "a8", addr, value); + TEST_LOAD("l16si", "a9", addr, value); + TEST_LOAD("l16si", "a10", addr, value); + TEST_LOAD("l16si", "a11", addr, value); + TEST_LOAD("l16si", "a12", addr, value); + TEST_LOAD("l16si", "a13", addr, value); + TEST_LOAD("l16si", "a14", addr, value); + TEST_LOAD("l16si", "a15", addr, value); +} + +void sanity_tests(void) { + printf("== Performing sanity tests (sanity_test_data @ %p)...\n", sanity_test_data); + + sanity_test_l8ui(sanity_test_data + 0, 0x01); + sanity_test_l8ui(sanity_test_data + 1, 0x55); + sanity_test_l8ui(sanity_test_data + 2, 0x7e); + sanity_test_l8ui(sanity_test_data + 3, 0x2a); + sanity_test_l8ui(sanity_test_data + 4, 0x81); + sanity_test_l8ui(sanity_test_data + 5, 0xd5); + sanity_test_l8ui(sanity_test_data + 6, 0xfe); + sanity_test_l8ui(sanity_test_data + 7, 0xaa); + + sanity_test_l16ui(sanity_test_data + 0, 0x5501); + sanity_test_l16ui(sanity_test_data + 2, 0x2a7e); + sanity_test_l16ui(sanity_test_data + 4, 0xd581); + sanity_test_l16ui(sanity_test_data + 6, 0xaafe); + + sanity_test_l16si(sanity_test_data + 0, 0x5501); + sanity_test_l16si(sanity_test_data + 2, 0x2a7e); + sanity_test_l16si(sanity_test_data + 4, -10879); + sanity_test_l16si(sanity_test_data + 6, -21762); + + printf("== Sanity tests completed.\n"); +} From a3d7732da8d25b40e23b41d4264eb3e578b74803 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Sat, 19 Sep 2015 20:03:22 -0700 Subject: [PATCH 068/105] unaligned_load.c: Added more naive_strcpy tests Added tests for naive_strcpy using a variety of different regs, as execution time can depend on which register is being used. --- .../unaligned_load/unaligned_load.c | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index 3cfe471..d2d132f 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -65,6 +65,84 @@ void test_naive_strcpy(const char *string) ; } +void test_naive_strcpy_a0(const char *string) +{ + asm volatile ( +" mov a8, %0 \n" +" mov a9, %1 \n" +"tns_loop%=: l8ui a0, a9, 0 \n" +" addi.n a9, a9, 1 \n" +" s8i a0, a8, 0 \n" +" addi.n a8, a8, 1 \n" +" bnez a0, tns_loop%=\n" + : : "r" (buf), "r" (string) : "a0", "a8", "a9"); +} + +void test_naive_strcpy_a2(const char *string) +{ + asm volatile ( +" mov a8, %0 \n" +" mov a9, %1 \n" +"tns_loop%=: l8ui a2, a9, 0 \n" +" addi.n a9, a9, 1 \n" +" s8i a2, a8, 0 \n" +" addi.n a8, a8, 1 \n" +" bnez a2, tns_loop%=\n" + : : "r" (buf), "r" (string) : "a2", "a8", "a9"); +} + +void test_naive_strcpy_a3(const char *string) +{ + asm volatile ( +" mov a8, %0 \n" +" mov a9, %1 \n" +"tns_loop%=: l8ui a3, a9, 0 \n" +" addi.n a9, a9, 1 \n" +" s8i a3, a8, 0 \n" +" addi.n a8, a8, 1 \n" +" bnez a3, tns_loop%=\n" + : : "r" (buf), "r" (string) : "a3", "a8", "a9"); +} + +void test_naive_strcpy_a4(const char *string) +{ + asm volatile ( +" mov a8, %0 \n" +" mov a9, %1 \n" +"tns_loop%=: l8ui a4, a9, 0 \n" +" addi.n a9, a9, 1 \n" +" s8i a4, a8, 0 \n" +" addi.n a8, a8, 1 \n" +" bnez a4, tns_loop%=\n" + : : "r" (buf), "r" (string) : "a4", "a8", "a9"); +} + +void test_naive_strcpy_a5(const char *string) +{ + asm volatile ( +" mov a8, %0 \n" +" mov a9, %1 \n" +"tns_loop%=: l8ui a5, a9, 0 \n" +" addi.n a9, a9, 1 \n" +" s8i a5, a8, 0 \n" +" addi.n a8, a8, 1 \n" +" bnez a5, tns_loop%=\n" + : : "r" (buf), "r" (string) : "a5", "a8", "a9"); +} + +void test_naive_strcpy_a6(const char *string) +{ + asm volatile ( +" mov a8, %0 \n" +" mov a9, %1 \n" +"tns_loop%=: l8ui a6, a9, 0 \n" +" addi.n a9, a9, 1 \n" +" s8i a6, a8, 0 \n" +" addi.n a8, a8, 1 \n" +" bnez a6, tns_loop%=\n" + : : "r" (buf), "r" (string) : "a6", "a8", "a9"); +} + void test_l16si(const char *string) { /* This follows most of the l16si path, but as the @@ -118,6 +196,12 @@ void test_string(const char *string, char *label, bool evict_cache) run_test(string, test_memcpy_unaligned2, "memcpy - unaligned start&len", nullvalue, evict_cache); run_test(string, test_strcpy, "strcpy", nullvalue, evict_cache); run_test(string, test_naive_strcpy, "naive strcpy", nullvalue, evict_cache); + run_test(string, test_naive_strcpy_a0, "naive strcpy (a0)", nullvalue, evict_cache); + run_test(string, test_naive_strcpy_a2, "naive strcpy (a2)", nullvalue, evict_cache); + run_test(string, test_naive_strcpy_a3, "naive strcpy (a3)", nullvalue, evict_cache); + run_test(string, test_naive_strcpy_a4, "naive strcpy (a4)", nullvalue, evict_cache); + run_test(string, test_naive_strcpy_a5, "naive strcpy (a5)", nullvalue, evict_cache); + run_test(string, test_naive_strcpy_a6, "naive strcpy (a6)", nullvalue, evict_cache); run_test(string, test_sprintf, "sprintf", nullvalue, evict_cache); run_test(string, test_sprintf_arg, "sprintf format arg", nullvalue, evict_cache); run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache); From 372827ac4217f0df39cc9b688d5d75a3d0d97a4f Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Thu, 30 Jul 2015 19:34:13 +0200 Subject: [PATCH 069/105] Mostly updated header files for use in C++ --- axtls/include/version.h | 2 +- common.mk | 17 ++++++++++++----- core/include/common_macros.h | 6 +++++- include/espressif/esp8266/esp8266.h | 8 ++++++++ include/espressif/esp_misc.h | 8 ++++++++ include/espressif/esp_softap.h | 8 ++++++++ include/espressif/esp_sta.h | 8 ++++++++ include/espressif/esp_system.h | 8 ++++++++ include/espressif/esp_timer.h | 8 ++++++++ include/espressif/esp_wifi.h | 10 +++++++++- include/espressif/sdk_private.h | 9 +++++++++ include/espressif/spi_flash.h | 10 ++++++++++ ld/eagle.app.v6.ld | 3 +++ 13 files changed, 97 insertions(+), 8 deletions(-) diff --git a/axtls/include/version.h b/axtls/include/version.h index 43c7194..8fee21b 100644 --- a/axtls/include/version.h +++ b/axtls/include/version.h @@ -5,6 +5,6 @@ #ifndef _VERSION_H -#define AXTLS_VERSION "esp-open-rtos axTLS "GITSHORTREV +#define AXTLS_VERSION "esp-open-rtos axTLS " GITSHORTREV #endif diff --git a/common.mk b/common.mk index a893e29..00a77dd 100644 --- a/common.mk +++ b/common.mk @@ -94,14 +94,19 @@ OWN_LIBC ?= 1 # Note: you will need a recent esp ENTRY_SYMBOL ?= call_user_start -CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 $(CPPFLAGS) +# Common flags for both C & C++_ +C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals $(CPPFLAGS) +# Flags for C only +CFLAGS = $(C_CXX_FLAGS) -std=gnu99 +# Flags for C++ only +CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS) ifeq ($(FLAVOR),debug) - CFLAGS += -g -O0 + C_CXX_FLAGS += -g -O0 LDFLAGS += -g -O0 else - CFLAGS += -g -O2 + C_CXX_FLAGS += -g -O2 LDFLAGS += -g -O2 endif @@ -138,8 +143,8 @@ endif LINKER_SCRIPTS_PROCESSED = $(addprefix $(LD_DIR),$(LINKER_SCRIPTS)) # derive various parts of compiler/linker arguments -SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS)) -LIB_ARGS = $(addprefix -l,$(LIBS)) +SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS)) +LIB_ARGS = $(addprefix -l,$(LIBS)) PROGRAM_OUT = $(BUILD_DIR)$(PROGRAM).out LDFLAGS += $(addprefix -T,$(LINKER_SCRIPTS_PROCESSED)) @@ -228,7 +233,9 @@ $(1)_MAKEFILE ?= $(lastword $(MAKEFILE_LIST)) ### determine compiler arguments ### $(1)_CFLAGS ?= $(CFLAGS) +$(1)_CXXFLAGS ?= $(CXXFLAGS) $(1)_CC_ARGS = $(Q) $(CC) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CFLAGS) +$(1)_CXX_ARGS = $(Q) $(C++) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CXXFLAGS) $(1)_AR = $(call lc,$(BUILD_DIR)$(1).a) $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR) diff --git a/core/include/common_macros.h b/core/include/common_macros.h index b0c7a08..b0d89e1 100644 --- a/core/include/common_macros.h +++ b/core/include/common_macros.h @@ -45,7 +45,11 @@ 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.literal"))) const +#ifdef __cplusplus + #define IROM __attribute__((section(".irom0.literal"))) +#else + #define IROM __attribute__((section(".irom0.literal"))) const +#endif #define INLINED inline static __attribute__((always_inline)) __attribute__((unused)) diff --git a/include/espressif/esp8266/esp8266.h b/include/espressif/esp8266/esp8266.h index 2d8b21b..4bf1a7a 100644 --- a/include/espressif/esp8266/esp8266.h +++ b/include/espressif/esp8266/esp8266.h @@ -6,6 +6,10 @@ #ifndef __ESP8266_H__ #define __ESP8266_H__ +#ifdef __cplusplus +extern "C" { +#endif + #include "ets_sys.h" #include "eagle_soc.h" #include "gpio_register.h" @@ -14,5 +18,9 @@ #include "timer_register.h" #include "uart_register.h" +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_misc.h b/include/espressif/esp_misc.h index d8ce65e..6490fa5 100644 --- a/include/espressif/esp_misc.h +++ b/include/espressif/esp_misc.h @@ -8,6 +8,10 @@ #include "lwip/ip_addr.h" +#ifdef __cplusplus +extern "C" { +#endif + #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" @@ -23,4 +27,8 @@ void sdk_os_delay_us(uint16_t us); void sdk_os_install_putc1(void (*p)(char c)); void sdk_os_putc(char c); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_softap.h b/include/espressif/esp_softap.h index 44f06cc..8a81aef 100644 --- a/include/espressif/esp_softap.h +++ b/include/espressif/esp_softap.h @@ -6,6 +6,10 @@ #ifndef __ESP_SOFTAP_H__ #define __ESP_SOFTAP_H__ +#ifdef __cplusplus +extern "C" { +#endif + struct sdk_softap_config { uint8_t ssid[32]; uint8_t password[64]; @@ -20,4 +24,8 @@ struct sdk_softap_config { bool sdk_wifi_softap_get_config(struct sdk_softap_config *config); bool sdk_wifi_softap_set_config(struct sdk_softap_config *config); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_sta.h b/include/espressif/esp_sta.h index 8b9059a..0c94a6c 100644 --- a/include/espressif/esp_sta.h +++ b/include/espressif/esp_sta.h @@ -10,6 +10,10 @@ #include "queue.h" +#ifdef __cplusplus +extern "C" { +#endif + struct sdk_station_config { uint8_t ssid[32]; uint8_t password[64]; @@ -68,4 +72,8 @@ enum { uint8_t sdk_wifi_station_get_connect_status(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_system.h b/include/espressif/esp_system.h index 93eea64..e37263e 100644 --- a/include/espressif/esp_system.h +++ b/include/espressif/esp_system.h @@ -6,6 +6,10 @@ #ifndef __ESP_SYSTEM_H__ #define __ESP_SYSTEM_H__ +#ifdef __cplusplus +extern "C" { +#endif + enum sdk_rst_reason { DEFAULT_RST = 0, WDT_RST = 1, @@ -54,4 +58,8 @@ bool sdk_system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n); void sdk_system_uart_swap(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_timer.h b/include/espressif/esp_timer.h index 6f05547..0ceb131 100644 --- a/include/espressif/esp_timer.h +++ b/include/espressif/esp_timer.h @@ -6,6 +6,10 @@ #ifndef __ESP_TIMER_H__ #define __ESP_TIMER_H__ +#ifdef __cplusplus +extern "C" { +#endif + /* timer related */ typedef void sdk_os_timer_func_t(void *timer_arg); @@ -19,4 +23,8 @@ typedef struct _os_timer_t { void *timer_arg; } sdk_os_timer_t; +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h index 5dae103..5d9ba19 100644 --- a/include/espressif/esp_wifi.h +++ b/include/espressif/esp_wifi.h @@ -13,6 +13,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + enum { NULL_MODE = 0, STATION_MODE, @@ -67,7 +71,11 @@ enum sdk_phy_mode { PHY_MODE_11N = 3 }; -enum phy_mode sdk_wifi_get_phy_mode(void); +enum sdk_phy_mode sdk_wifi_get_phy_mode(void); bool sdk_wifi_set_phy_mode(enum sdk_phy_mode mode); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/sdk_private.h b/include/espressif/sdk_private.h index 4340999..fa643a7 100644 --- a/include/espressif/sdk_private.h +++ b/include/espressif/sdk_private.h @@ -15,6 +15,11 @@ #define SDK_PRIVATE_H #include + +#ifdef __cplusplus +extern "C" { +#endif + struct ip_addr; /********************************************* @@ -49,4 +54,8 @@ void sdk_system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_m */ void sdk_system_pp_recycle_rx_pkt(void *eb); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/spi_flash.h b/include/espressif/spi_flash.h index 1805cc7..224bce4 100644 --- a/include/espressif/spi_flash.h +++ b/include/espressif/spi_flash.h @@ -6,6 +6,10 @@ #ifndef __SPI_FLASH_H__ #define __SPI_FLASH_H__ +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { SPI_FLASH_RESULT_OK, SPI_FLASH_RESULT_ERR, @@ -21,6 +25,7 @@ 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); + /* SDK uses this structure internally to account for flash size. chip_size field is initialised during startup from the flash size @@ -42,4 +47,9 @@ typedef struct { extern sdk_flashchip_t sdk_flashchip; + +#ifdef __cplusplus +} +#endif + #endif diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index 412441d..566ad67 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -166,11 +166,14 @@ SECTIONS *(.gnu.linkonce.e.*) *(.gnu.version_r) *(.eh_frame) + . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ + __init_array_start = ABSOLUTE(.); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) + __init_array_end = ABSOLUTE(.); KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) From cc97067fa1e1ff207434f43072da8916677b05ba Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 10 Aug 2015 15:51:57 +1000 Subject: [PATCH 070/105] Add C++ support to Makefile, and proof-of-concept simple.cpp example This is a work in progress based on @mikejac's work. Missing: * No 'new' operator. * I don't think STL is currently supported. --- FreeRTOS/Source/portable/esp8266/port.c | 11 ++++++ common.mk | 14 +++++-- core/sdk_compat.c | 15 +++++++ examples/simple_cplusplus/Makefile | 3 ++ examples/simple_cplusplus/simple.cpp | 52 +++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 examples/simple_cplusplus/Makefile create mode 100644 examples/simple_cplusplus/simple.cpp diff --git a/FreeRTOS/Source/portable/esp8266/port.c b/FreeRTOS/Source/portable/esp8266/port.c index 1632fe1..71c6658 100644 --- a/FreeRTOS/Source/portable/esp8266/port.c +++ b/FreeRTOS/Source/portable/esp8266/port.c @@ -178,6 +178,9 @@ void xPortSysTickHandle (void) //OpenNMI(); } +static bool sdk_compat_initialised; +void sdk_compat_initialise(void); + /* * See header file for description. */ @@ -186,6 +189,14 @@ portBASE_TYPE xPortStartScheduler( void ) _xt_isr_attach(INUM_SOFT, SV_ISR); _xt_isr_unmask(BIT(INUM_SOFT)); + /* ENORMOUS HACK: Call the sdk_compat_initialise() function. + This can be removed happily once we have open source startup code. + */ + if(!sdk_compat_initialised) { + sdk_compat_initialised = true; + sdk_compat_initialise(); + } + /* Initialize system tick timer interrupt and schedule the first tick. */ sdk__xt_tick_timer_init(); diff --git a/common.mk b/common.mk index 00a77dd..7361f70 100644 --- a/common.mk +++ b/common.mk @@ -220,13 +220,15 @@ $(1)_DEFAULT_ROOT := $(dir $(lastword $(MAKEFILE_LIST))) $(1)_ROOT ?= $$($(1)_DEFAULT_ROOT) $(1)_OBJ_DIR = $(call lc,$(BUILD_DIR)$(1)/) ### determine source files and object files ### -$(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \ - $$(wildcard $$(sdir)/*.c) $$(wildcard $$(sdir)/*.S)) \ +$(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \ + $$(wildcard $$(sdir)/*.c) $$(wildcard $$(sdir)/*.S) \ + $$(wildcard $$(sdir)/*.cpp)) \ $$($(1)_EXTRA_SRC_FILES) $(1)_REAL_SRC_FILES = $$(foreach sfile,$$($(1)_SRC_FILES),$$(realpath $$(sfile))) $(1)_REAL_ROOT = $$(realpath $$($(1)_ROOT)) # patsubst here substitutes real component root path for the relative OBJ_DIR path, making things short again -$(1)_OBJ_FILES_C = $$(patsubst $$($(1)_REAL_ROOT)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_REAL_SRC_FILES)) +$(1)_OBJ_FILES_CXX = $$(patsubst $$($(1)_REAL_ROOT)%.cpp,$$($(1)_OBJ_DIR)%.o,$$($(1)_REAL_SRC_FILES)) +$(1)_OBJ_FILES_C = $$(patsubst $$($(1)_REAL_ROOT)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_CXX)) $(1)_OBJ_FILES = $$(patsubst $$($(1)_REAL_ROOT)%.S,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_C)) # the last included makefile is our component's component.mk makefile (rebuild the component if it changes) $(1)_MAKEFILE ?= $(lastword $(MAKEFILE_LIST)) @@ -244,6 +246,12 @@ $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)* $$($(1)_CC_ARGS) -c $$< -o $$@ $$($(1)_CC_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$< +$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.cpp $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR) + $(vecho) "C++ $$<" + $(Q) mkdir -p $$(dir $$@) + $$($(1)_CXX_ARGS) -c $$< -o $$@ + $$($(1)_CXX_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$< + $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.S $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR) $(vecho) "AS $$<" $(Q) mkdir -p $$(dir $$@) diff --git a/core/sdk_compat.c b/core/sdk_compat.c index d141708..b6bb6b3 100644 --- a/core/sdk_compat.c +++ b/core/sdk_compat.c @@ -14,3 +14,18 @@ void IRAM *zalloc(size_t nbytes) { return calloc(1, nbytes); } + +extern void (*__init_array_start)(void); +extern void (*__init_array_end)(void); + +/* Do things which should be done as part of the startup code, but aren't. + + Can be replaced with _start() once we have open source startup code. +*/ +void sdk_compat_initialise() +{ + /* Call C++ constructors or C functions marked with __attribute__((constructor)) */ + void (**p)(void); + for ( p = &__init_array_start; p != &__init_array_end; ++p) + (*p)(); +} diff --git a/examples/simple_cplusplus/Makefile b/examples/simple_cplusplus/Makefile new file mode 100644 index 0000000..717b163 --- /dev/null +++ b/examples/simple_cplusplus/Makefile @@ -0,0 +1,3 @@ +# Simple makefile for simple example +PROGRAM=simple +include ../../common.mk diff --git a/examples/simple_cplusplus/simple.cpp b/examples/simple_cplusplus/simple.cpp new file mode 100644 index 0000000..dada441 --- /dev/null +++ b/examples/simple_cplusplus/simple.cpp @@ -0,0 +1,52 @@ +/* A very basic C++ example, really just proof of concept for C++ + + This sample code is in the public domain. + */ +#include "espressif/esp_common.h" +#include "espressif/sdk_private.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +class Counter +{ +private: + uint32_t _count; +public: + Counter(uint32_t initial_count) + { + this->_count = initial_count; + printf("Counter initialised with count %ld\r\n", initial_count); + } + + void Increment() + { + _count++; + } + + uint32_t getCount() + { + return _count; + } +}; + +static Counter static_counter(99); + +void task1(void *pvParameters) +{ + Counter local_counter = Counter(12); + while(1) { + Counter &counter = rand() % 2 ? static_counter : local_counter; + counter.Increment(); + printf("local counter %ld static counter %ld\r\n", local_counter.getCount(), + static_counter.getCount()); + vTaskDelay(100); + } +} + +extern "C" void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + xTaskCreate(task1, (signed char *)"tsk1", 256, NULL, 2, NULL); +} From 94fabc6ceb58b7acf4f4085f110b8e8e7adfe3a7 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 13 Aug 2015 08:32:34 +1000 Subject: [PATCH 071/105] Add basic C++ new/delete operators, as contributed by @mikejac in #24 --- core/cplusplus_operators.cpp | 25 +++++++++++++++++++++++++ examples/simple_cplusplus/simple.cpp | 20 ++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 core/cplusplus_operators.cpp diff --git a/core/cplusplus_operators.cpp b/core/cplusplus_operators.cpp new file mode 100644 index 0000000..86f4477 --- /dev/null +++ b/core/cplusplus_operators.cpp @@ -0,0 +1,25 @@ +/* Part of esp-open-rtos + * BSD Licensed as described in the file LICENSE + */ +#include +#include + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} diff --git a/examples/simple_cplusplus/simple.cpp b/examples/simple_cplusplus/simple.cpp index dada441..8d964fa 100644 --- a/examples/simple_cplusplus/simple.cpp +++ b/examples/simple_cplusplus/simple.cpp @@ -35,11 +35,23 @@ static Counter static_counter(99); void task1(void *pvParameters) { Counter local_counter = Counter(12); + Counter *new_counter = new Counter(24); while(1) { - Counter &counter = rand() % 2 ? static_counter : local_counter; - counter.Increment(); - printf("local counter %ld static counter %ld\r\n", local_counter.getCount(), - static_counter.getCount()); + Counter *counter = NULL; + switch(rand() % 3) { + case 0: + counter = &local_counter; + break; + case 1: + counter = &static_counter; + break; + default: + counter = new_counter; + break; + } + counter->Increment(); + printf("local counter %ld static counter %ld newly allocated counter %ld\r\n", local_counter.getCount(), + static_counter.getCount(), new_counter->getCount()); vTaskDelay(100); } } From 627b78331accc07aa62af94dc23fce319ceff6c8 Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Wed, 19 Aug 2015 08:38:15 +0200 Subject: [PATCH 072/105] Added C++ base components and example --- common.mk | 4 +- examples/cpp_01_tasks/Makefile | 3 + examples/cpp_01_tasks/main.cpp | 100 +++++++++++++++++++++++++++ extras/cplusplus/component.mk | 3 + extras/cplusplus/cplusplus.hpp | 68 +++++++++++++++++++ extras/thread/component.mk | 3 + extras/thread/mutex.hpp | 90 +++++++++++++++++++++++++ extras/thread/queue.hpp | 120 +++++++++++++++++++++++++++++++++ extras/thread/task.hpp | 99 +++++++++++++++++++++++++++ extras/timer/component.mk | 3 + extras/timer/countdown.hpp | 95 ++++++++++++++++++++++++++ 11 files changed, 586 insertions(+), 2 deletions(-) create mode 100644 examples/cpp_01_tasks/Makefile create mode 100644 examples/cpp_01_tasks/main.cpp create mode 100644 extras/cplusplus/component.mk create mode 100644 extras/cplusplus/cplusplus.hpp create mode 100644 extras/thread/component.mk create mode 100644 extras/thread/mutex.hpp create mode 100644 extras/thread/queue.hpp create mode 100644 extras/thread/task.hpp create mode 100644 extras/timer/component.mk create mode 100644 extras/timer/countdown.hpp diff --git a/common.mk b/common.mk index 7361f70..2880752 100644 --- a/common.mk +++ b/common.mk @@ -99,7 +99,7 @@ C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-lit # Flags for C only CFLAGS = $(C_CXX_FLAGS) -std=gnu99 # Flags for C++ only -CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions +CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions -fno-rtti LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS) ifeq ($(FLAVOR),debug) @@ -177,7 +177,7 @@ IMGTOOL_ARGS=-$(IMGTOOL_FLASH_SIZE) -$(FLASH_MODE) -$(FLASH_SPEED) # Placing $(PROGRAM_DIR) and $(PROGRAM_DIR)include first allows # programs to have their own copies of header config files for components # , which is useful for overriding things. -INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include +INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include $(ROOT)extras ifeq ($(OWN_LIBC),1) INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include diff --git a/examples/cpp_01_tasks/Makefile b/examples/cpp_01_tasks/Makefile new file mode 100644 index 0000000..458932f --- /dev/null +++ b/examples/cpp_01_tasks/Makefile @@ -0,0 +1,3 @@ +# Simple makefile for simple example +PROGRAM=cpp_01_tasks +include ../../common.mk diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp new file mode 100644 index 0000000..133d1c5 --- /dev/null +++ b/examples/cpp_01_tasks/main.cpp @@ -0,0 +1,100 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#include "cplusplus/cplusplus.hpp" +#include "thread/task.hpp" +#include "thread/queue.hpp" + +#include "espressif/esp_common.h" + +/****************************************************************************************************************** + * task_1_t + * + */ +class task_1_t: public esp_open_rtos::thread::task_t +{ +public: + esp_open_rtos::thread::queue_t queue; + +private: + void task() + { + printf("task_1_t::task(): start\n"); + + uint32_t count = 0; + + while(true) { + sleep(1000); + queue.post(count); + count++; + } + } +}; +/****************************************************************************************************************** + * task_2_t + * + */ +class task_2_t: public esp_open_rtos::thread::task_t +{ +public: + esp_open_rtos::thread::queue_t queue; + +private: + void task() + { + printf("task_2_t::task(): start\n"); + + while(true) { + uint32_t count; + + if(queue.receive(count, 1500) == 0) { + printf("task_2_t::task(): got %lu\n", count); + } + else { + printf("task_2_t::task(): no msg\n"); + } + } + } +}; +/****************************************************************************************************************** + * globals + * + */ +task_1_t task_1; +task_2_t task_2; + +esp_open_rtos::thread::queue_t MyQueue; + +/** + * + */ +extern "C" void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + + MyQueue.create(10); + + task_1.queue = MyQueue; + task_2.queue = MyQueue; + + task_1.task_create("tsk1"); + task_2.task_create("tsk2"); +} \ No newline at end of file diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk new file mode 100644 index 0000000..3f5673d --- /dev/null +++ b/extras/cplusplus/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/cplusplus + +INC_DIRS += $(ROOT)extras diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp new file mode 100644 index 0000000..cc58031 --- /dev/null +++ b/extras/cplusplus/cplusplus.hpp @@ -0,0 +1,68 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP + +#include + +/****************************************************************************************************************** + * C++ new and delete operators + * + */ + +/** + * + * @param size + * @return + */ +inline void *operator new(size_t size) +{ + return malloc(size); +} +/** + * + * @param size + * @return + */ +inline void *operator new[](size_t size) +{ + return malloc(size); +} +/** + * + * @param ptr + */ +inline void operator delete(void * ptr) +{ + free(ptr); +} +/** + * + * @param ptr + */ +inline void operator delete[](void * ptr) +{ + free(ptr); +} + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP */ + diff --git a/extras/thread/component.mk b/extras/thread/component.mk new file mode 100644 index 0000000..46193ef --- /dev/null +++ b/extras/thread/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/thread + +INC_DIRS += $(ROOT)extras diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp new file mode 100644 index 0000000..d3db1da --- /dev/null +++ b/extras/thread/mutex.hpp @@ -0,0 +1,90 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP + +#include "semphr.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * class mutex_t + * + */ +class mutex_t +{ +public: + /** + * + */ + inline mutex_t() + { + mutex = xSemaphoreCreateMutex(); + } + /** + * + */ + inline ~mutex_t() + { + vQueueDelete(mutex); + } + /** + * + * @return + */ + inline int lock() + { + return (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE) ? 0 : -1; + } + /** + * + * @param ms + * @return + */ + inline int try_lock(unsigned long ms) + { + return (xSemaphoreTake(mutex, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @return + */ + inline int unlock() + { + return (xSemaphoreGive(mutex) == pdTRUE) ? 0 : -1; + } + +private: + xSemaphoreHandle mutex; + + // Disable copy construction and assignment. + mutex_t (const mutex_t&); + const mutex_t &operator = (const mutex_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP */ + diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp new file mode 100644 index 0000000..fd14166 --- /dev/null +++ b/extras/thread/queue.hpp @@ -0,0 +1,120 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP + +#include "FreeRTOS.h" +#include "queue.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * class queue_t + * + */ +template +class queue_t +{ +public: + /** + * + */ + inline queue_t() + { + queue = 0; + } + /** + * + * @param uxQueueLength + * @param uxItemSize + * @return + */ + inline int create(unsigned portBASE_TYPE uxQueueLength) + { + queue = xQueueCreate(uxQueueLength, sizeof(Data)); + + if(queue == NULL) { + return -1; + } + else { + return 0; + } + } + /** + * + * @param data + * @param ms + * @return + */ + inline void destroy() + { + vQueueDelete(queue); + queue = 0; + } + /** + * + * @param data + * @param ms + * @return + */ + inline int post(const Data& data, unsigned long ms = 0) + { + return (xQueueSend(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @param data + * @param ms + * @return + */ + inline int receive(Data& data, unsigned long ms = 0) + { + return (xQueueReceive(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @param other + * @return + */ + const queue_t &operator = (const queue_t& other) + { + if(this != &other) { // protect against invalid self-assignment + queue = other.queue; + } + + return *this; + } + +private: + xQueueHandle queue; + + // Disable copy construction. + queue_t (const queue_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP */ + diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp new file mode 100644 index 0000000..dc527f0 --- /dev/null +++ b/extras/thread/task.hpp @@ -0,0 +1,99 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP + +#include "FreeRTOS.h" +#include "task.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * task_t + * + */ +class task_t +{ +public: + /** + * + */ + task_t() + {} + /** + * + * @param pcName + * @param usStackDepth + * @param uxPriority + * @return + */ + int task_create(const char* const pcName, unsigned short usStackDepth = 256, unsigned portBASE_TYPE uxPriority = 2) + { + return xTaskCreate(task_t::_task, (signed char *)pcName, usStackDepth, this, uxPriority, NULL); + } + +protected: + /** + * + * @param ms + */ + void sleep(unsigned long ms) + { + vTaskDelay(ms / portTICK_RATE_MS); + } + /** + * + * @return + */ + inline unsigned long millis() + { + return xTaskGetTickCount() * portTICK_RATE_MS; + } + +private: + /** + * + */ + virtual void task() = 0; + /** + * + * @param pvParameters + */ + static void _task(void* pvParameters) + { + if(pvParameters != 0) { + ((task_t*)(pvParameters))->task(); + } + } + + // no copy and no = operator + task_t(const task_t&); + task_t &operator=(const task_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP */ + diff --git a/extras/timer/component.mk b/extras/timer/component.mk new file mode 100644 index 0000000..255ebae --- /dev/null +++ b/extras/timer/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/timer + +INC_DIRS += $(ROOT)extras diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp new file mode 100644 index 0000000..ff1a2bf --- /dev/null +++ b/extras/timer/countdown.hpp @@ -0,0 +1,95 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP + +#include "FreeRTOS.h" +#include "task.h" + +namespace esp_open_rtos { +namespace timer { + +#define __millis() (xTaskGetTickCount() * portTICK_RATE_MS) + +/****************************************************************************************************************** + * countdown_t + * + */ +class countdown_t +{ +public: + /** + * + */ + countdown_t() + { + interval_end_ms = 0L; + } + /** + * + * @param ms + */ + countdown_t(int ms) + { + countdown_ms(ms); + } + /** + * + * @return + */ + bool expired() + { + return (interval_end_ms > 0L) && (__millis() >= interval_end_ms); + } + /** + * + * @param ms + */ + void countdown_ms(unsigned long ms) + { + interval_end_ms = __millis() + ms; + } + /** + * + * @param seconds + */ + void countdown(int seconds) + { + countdown_ms((unsigned long)seconds * 1000L); + } + /** + * + * @return + */ + int left_ms() + { + return interval_end_ms - __millis(); + } + +private: + portTickType interval_end_ms; +}; + +} // namespace timer { +} // namespace esp_open_rtos { + +#endif From 63bbf92a76a47e31d27845e5a82be4614a9444e0 Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Wed, 19 Aug 2015 08:44:41 +0200 Subject: [PATCH 073/105] Header files adjustments --- extras/cplusplus/cplusplus.hpp | 6 +++--- extras/thread/mutex.hpp | 6 +++--- extras/thread/queue.hpp | 6 +++--- extras/thread/task.hpp | 6 +++--- extras/timer/countdown.hpp | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp index cc58031..a78e146 100644 --- a/extras/cplusplus/cplusplus.hpp +++ b/extras/cplusplus/cplusplus.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP +#ifndef ESP_OPEN_RTOS_CPLUSPLUS_HPP +#define ESP_OPEN_RTOS_CPLUSPLUS_HPP #include @@ -64,5 +64,5 @@ inline void operator delete[](void * ptr) free(ptr); } -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP */ +#endif /* ESP_OPEN_RTOS_CPLUSPLUS_HPP */ diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp index d3db1da..b4e56a4 100644 --- a/extras/thread/mutex.hpp +++ b/extras/thread/mutex.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP +#ifndef ESP_OPEN_RTOS_MUTEX_HPP +#define ESP_OPEN_RTOS_MUTEX_HPP #include "semphr.h" @@ -86,5 +86,5 @@ private: } //namespace esp_open_rtos { -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP */ +#endif /* ESP_OPEN_RTOS_MUTEX_HPP */ diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp index fd14166..e02bec6 100644 --- a/extras/thread/queue.hpp +++ b/extras/thread/queue.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP +#ifndef ESP_OPEN_RTOS_QUEUE_HPP +#define ESP_OPEN_RTOS_QUEUE_HPP #include "FreeRTOS.h" #include "queue.h" @@ -116,5 +116,5 @@ private: } //namespace esp_open_rtos { -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP */ +#endif /* ESP_OPEN_RTOS_QUEUE_HPP */ diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp index dc527f0..a8a5c5b 100644 --- a/extras/thread/task.hpp +++ b/extras/thread/task.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP +#ifndef ESP_OPEN_RTOS_TASK_HPP +#define ESP_OPEN_RTOS_TASK_HPP #include "FreeRTOS.h" #include "task.h" @@ -95,5 +95,5 @@ private: } //namespace esp_open_rtos { -#endif /* COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP */ +#endif /* ESP_OPEN_RTOS_TASK_HPP */ diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp index ff1a2bf..71dd55c 100644 --- a/extras/timer/countdown.hpp +++ b/extras/timer/countdown.hpp @@ -19,8 +19,8 @@ * */ -#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP -#define COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP +#ifndef ESP_OPEN_RTOS_TIMER_HPP +#define ESP_OPEN_RTOS_TIMER_HPP #include "FreeRTOS.h" #include "task.h" From 028451fa8477905b249c3d8dfe2dab8d8b2a95a4 Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Thu, 20 Aug 2015 10:04:59 +0200 Subject: [PATCH 074/105] Updated license --- examples/cpp_01_tasks/main.cpp | 31 +++++++++++++++++++------------ extras/cplusplus/cplusplus.hpp | 33 ++++++++++++++++++++------------- extras/thread/mutex.hpp | 31 +++++++++++++++++++------------ extras/thread/queue.hpp | 31 +++++++++++++++++++------------ extras/thread/task.hpp | 31 +++++++++++++++++++------------ extras/timer/countdown.hpp | 31 +++++++++++++++++++------------ 6 files changed, 115 insertions(+), 73 deletions(-) diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 133d1c5..0b9fe1f 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp index a78e146..bf006a8 100644 --- a/extras/cplusplus/cplusplus.hpp +++ b/extras/cplusplus/cplusplus.hpp @@ -1,24 +1,31 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ - + #ifndef ESP_OPEN_RTOS_CPLUSPLUS_HPP #define ESP_OPEN_RTOS_CPLUSPLUS_HPP diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp index b4e56a4..714c585 100644 --- a/extras/thread/mutex.hpp +++ b/extras/thread/mutex.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp index e02bec6..a24f302 100644 --- a/extras/thread/queue.hpp +++ b/extras/thread/queue.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp index a8a5c5b..cb1cb45 100644 --- a/extras/thread/task.hpp +++ b/extras/thread/task.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp index 71dd55c..87c8f3f 100644 --- a/extras/timer/countdown.hpp +++ b/extras/timer/countdown.hpp @@ -1,20 +1,27 @@ /* + * The MIT License (MIT) + * * ESP8266 FreeRTOS Firmware - * Copyright (C) 2015 Michael Jacobsen + * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * https://github.com/SuperHouse/esp-open-rtos * */ From 602d3e2d986c6c1afa9ee6cee9a9228ea951fe3a Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Fri, 21 Aug 2015 08:30:52 +0200 Subject: [PATCH 075/105] Header files re-arrangement --- common.mk | 2 +- examples/cpp_01_tasks/Makefile | 2 ++ examples/cpp_01_tasks/main.cpp | 6 +++--- extras/cpp_support/component.mk | 8 ++++++++ extras/{timer => cpp_support/include}/countdown.hpp | 0 extras/{cplusplus => cpp_support/include}/cplusplus.hpp | 0 extras/{thread => cpp_support/include}/mutex.hpp | 0 extras/{thread => cpp_support/include}/queue.hpp | 0 extras/{thread => cpp_support/include}/task.hpp | 0 9 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 extras/cpp_support/component.mk rename extras/{timer => cpp_support/include}/countdown.hpp (100%) rename extras/{cplusplus => cpp_support/include}/cplusplus.hpp (100%) rename extras/{thread => cpp_support/include}/mutex.hpp (100%) rename extras/{thread => cpp_support/include}/queue.hpp (100%) rename extras/{thread => cpp_support/include}/task.hpp (100%) diff --git a/common.mk b/common.mk index 2880752..e6e6c84 100644 --- a/common.mk +++ b/common.mk @@ -177,7 +177,7 @@ IMGTOOL_ARGS=-$(IMGTOOL_FLASH_SIZE) -$(FLASH_MODE) -$(FLASH_SPEED) # Placing $(PROGRAM_DIR) and $(PROGRAM_DIR)include first allows # programs to have their own copies of header config files for components # , which is useful for overriding things. -INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include $(ROOT)extras +INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include ifeq ($(OWN_LIBC),1) INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include diff --git a/examples/cpp_01_tasks/Makefile b/examples/cpp_01_tasks/Makefile index 458932f..f9254cf 100644 --- a/examples/cpp_01_tasks/Makefile +++ b/examples/cpp_01_tasks/Makefile @@ -1,3 +1,5 @@ # Simple makefile for simple example PROGRAM=cpp_01_tasks +OTA=0 +EXTRA_COMPONENTS=extras/cpp_support include ../../common.mk diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 0b9fe1f..219be74 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -26,9 +26,9 @@ * */ -#include "cplusplus/cplusplus.hpp" -#include "thread/task.hpp" -#include "thread/queue.hpp" +#include "cplusplus.hpp" +#include "task.hpp" +#include "queue.hpp" #include "espressif/esp_common.h" diff --git a/extras/cpp_support/component.mk b/extras/cpp_support/component.mk new file mode 100644 index 0000000..6bc4ada --- /dev/null +++ b/extras/cpp_support/component.mk @@ -0,0 +1,8 @@ +# Component makefile for extras/cpp_support +INC_DIRS += $(ROOT)extras/cpp_support/include + +# args for passing into compile rule generation +# extras/mqtt-client_INC_DIR = $(ROOT)extras/mqtt-client +# extras/mqtt-client_SRC_DIR = $(ROOT)extras/mqtt-client + +# $(eval $(call component_compile_rules,extras/mqtt-client)) diff --git a/extras/timer/countdown.hpp b/extras/cpp_support/include/countdown.hpp similarity index 100% rename from extras/timer/countdown.hpp rename to extras/cpp_support/include/countdown.hpp diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cpp_support/include/cplusplus.hpp similarity index 100% rename from extras/cplusplus/cplusplus.hpp rename to extras/cpp_support/include/cplusplus.hpp diff --git a/extras/thread/mutex.hpp b/extras/cpp_support/include/mutex.hpp similarity index 100% rename from extras/thread/mutex.hpp rename to extras/cpp_support/include/mutex.hpp diff --git a/extras/thread/queue.hpp b/extras/cpp_support/include/queue.hpp similarity index 100% rename from extras/thread/queue.hpp rename to extras/cpp_support/include/queue.hpp diff --git a/extras/thread/task.hpp b/extras/cpp_support/include/task.hpp similarity index 100% rename from extras/thread/task.hpp rename to extras/cpp_support/include/task.hpp From fbb01c81ad3edac407e59d14ad19cc2b231cf38a Mon Sep 17 00:00:00 2001 From: Michael Jacobsen Date: Sun, 23 Aug 2015 10:21:42 +0200 Subject: [PATCH 076/105] Header files adjustment (MQTT changes split from original commit - @projectgus.) --- examples/cpp_01_tasks/main.cpp | 4 ++-- extras/cpp_support/include/mutex.hpp | 20 ++++++++++++++++++-- extras/cpp_support/include/queue.hpp | 7 ++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 219be74..1295327 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -95,9 +95,9 @@ esp_open_rtos::thread::queue_t MyQueue; */ extern "C" void user_init(void) { - sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); - MyQueue.create(10); + MyQueue.queue_create(10); task_1.queue = MyQueue; task_2.queue = MyQueue; diff --git a/extras/cpp_support/include/mutex.hpp b/extras/cpp_support/include/mutex.hpp index 714c585..aaf29db 100644 --- a/extras/cpp_support/include/mutex.hpp +++ b/extras/cpp_support/include/mutex.hpp @@ -46,14 +46,30 @@ public: */ inline mutex_t() { - mutex = xSemaphoreCreateMutex(); + mutex = 0; + } + /** + * + * @return + */ + inline int mutex_create() + { + mutex = xSemaphoreCreateMutex(); + + if(mutex == NULL) { + return -1; + } + else { + return 0; + } } /** * */ - inline ~mutex_t() + inline void mutex_destroy() { vQueueDelete(mutex); + mutex = 0; } /** * diff --git a/extras/cpp_support/include/queue.hpp b/extras/cpp_support/include/queue.hpp index a24f302..047ce29 100644 --- a/extras/cpp_support/include/queue.hpp +++ b/extras/cpp_support/include/queue.hpp @@ -56,7 +56,7 @@ public: * @param uxItemSize * @return */ - inline int create(unsigned portBASE_TYPE uxQueueLength) + inline int queue_create(unsigned portBASE_TYPE uxQueueLength) { queue = xQueueCreate(uxQueueLength, sizeof(Data)); @@ -69,11 +69,8 @@ public: } /** * - * @param data - * @param ms - * @return */ - inline void destroy() + inline void queue_destroy() { vQueueDelete(queue); queue = 0; From 6416fe7329947c58882f5662b65fb67243c69ef3 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 10:36:40 +1000 Subject: [PATCH 077/105] Post-merge cleanup of extras/cpp_support --- core/cplusplus_operators.cpp | 25 ------------------- examples/cpp_01_tasks/main.cpp | 4 +-- extras/cplusplus/component.mk | 3 --- .../{cplusplus.hpp => cpp_operators.hpp} | 0 4 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 core/cplusplus_operators.cpp delete mode 100644 extras/cplusplus/component.mk rename extras/cpp_support/include/{cplusplus.hpp => cpp_operators.hpp} (100%) diff --git a/core/cplusplus_operators.cpp b/core/cplusplus_operators.cpp deleted file mode 100644 index 86f4477..0000000 --- a/core/cplusplus_operators.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* Part of esp-open-rtos - * BSD Licensed as described in the file LICENSE - */ -#include -#include - -void *operator new(size_t size) -{ - return malloc(size); -} - -void *operator new[](size_t size) -{ - return malloc(size); -} - -void operator delete(void * ptr) -{ - free(ptr); -} - -void operator delete[](void * ptr) -{ - free(ptr); -} diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index 1295327..cf751d6 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -26,7 +26,7 @@ * */ -#include "cplusplus.hpp" +#include "cpp_operators.hpp" #include "task.hpp" #include "queue.hpp" @@ -104,4 +104,4 @@ extern "C" void user_init(void) task_1.task_create("tsk1"); task_2.task_create("tsk2"); -} \ No newline at end of file +} diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk deleted file mode 100644 index 3f5673d..0000000 --- a/extras/cplusplus/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -# Component makefile for extras/cplusplus - -INC_DIRS += $(ROOT)extras diff --git a/extras/cpp_support/include/cplusplus.hpp b/extras/cpp_support/include/cpp_operators.hpp similarity index 100% rename from extras/cpp_support/include/cplusplus.hpp rename to extras/cpp_support/include/cpp_operators.hpp From 7be365ef0814cd33a0f7e6eed29ab65abef6b199 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 10:49:00 +1000 Subject: [PATCH 078/105] gpio.h: Explicit cast to enum type (needed for g++) --- core/include/esp/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/esp/gpio.h b/core/include/esp/gpio.h index 1f1ce14..679fff2 100644 --- a/core/include/esp/gpio.h +++ b/core/include/esp/gpio.h @@ -124,7 +124,7 @@ INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int /* Return the interrupt type set for a pin */ INLINED gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num) { - return FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]); + return (gpio_inttype_t)FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]); } #endif From 1c8017484c97272c4769851583b867a8f1eefd78 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:07:06 +1000 Subject: [PATCH 079/105] Move c++ operators back to link-time resolutions, part of 'core' This reverts commit e9b1df5cb5615dcaba9bcf0a36b1343b20a3cba4. --- core/cplusplus_operators.cpp | 25 +++++++ examples/cpp_01_tasks/main.cpp | 3 +- extras/cplusplus/component.mk | 3 + extras/cpp_support/include/cpp_operators.hpp | 75 -------------------- 4 files changed, 29 insertions(+), 77 deletions(-) create mode 100644 core/cplusplus_operators.cpp create mode 100644 extras/cplusplus/component.mk delete mode 100644 extras/cpp_support/include/cpp_operators.hpp diff --git a/core/cplusplus_operators.cpp b/core/cplusplus_operators.cpp new file mode 100644 index 0000000..86f4477 --- /dev/null +++ b/core/cplusplus_operators.cpp @@ -0,0 +1,25 @@ +/* Part of esp-open-rtos + * BSD Licensed as described in the file LICENSE + */ +#include +#include + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp index cf751d6..160a0c8 100644 --- a/examples/cpp_01_tasks/main.cpp +++ b/examples/cpp_01_tasks/main.cpp @@ -26,7 +26,6 @@ * */ -#include "cpp_operators.hpp" #include "task.hpp" #include "queue.hpp" @@ -104,4 +103,4 @@ extern "C" void user_init(void) task_1.task_create("tsk1"); task_2.task_create("tsk2"); -} +} \ No newline at end of file diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk new file mode 100644 index 0000000..3f5673d --- /dev/null +++ b/extras/cplusplus/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/cplusplus + +INC_DIRS += $(ROOT)extras diff --git a/extras/cpp_support/include/cpp_operators.hpp b/extras/cpp_support/include/cpp_operators.hpp deleted file mode 100644 index bf006a8..0000000 --- a/extras/cpp_support/include/cpp_operators.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * The MIT License (MIT) - * - * ESP8266 FreeRTOS Firmware - * Copyright (c) 2015 Michael Jacobsen (github.com/mikejac) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * https://github.com/SuperHouse/esp-open-rtos - * - */ - -#ifndef ESP_OPEN_RTOS_CPLUSPLUS_HPP -#define ESP_OPEN_RTOS_CPLUSPLUS_HPP - -#include - -/****************************************************************************************************************** - * C++ new and delete operators - * - */ - -/** - * - * @param size - * @return - */ -inline void *operator new(size_t size) -{ - return malloc(size); -} -/** - * - * @param size - * @return - */ -inline void *operator new[](size_t size) -{ - return malloc(size); -} -/** - * - * @param ptr - */ -inline void operator delete(void * ptr) -{ - free(ptr); -} -/** - * - * @param ptr - */ -inline void operator delete[](void * ptr) -{ - free(ptr); -} - -#endif /* ESP_OPEN_RTOS_CPLUSPLUS_HPP */ - From 6c06e5e91ea956b198f2c0f839cd9382ba095ef3 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:11:31 +1000 Subject: [PATCH 080/105] common_macros: Include sys/cdefs.h, defines _Static_assert among others --- core/include/common_macros.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/include/common_macros.h b/core/include/common_macros.h index b0d89e1..355248b 100644 --- a/core/include/common_macros.h +++ b/core/include/common_macros.h @@ -10,6 +10,8 @@ #ifndef _COMMON_MACROS_H #define _COMMON_MACROS_H +#include + #define UNUSED __attributed((unused)) #ifndef BIT From 8a29e46319ca012daf0a7b5c071cf6aee80156b2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:14:34 +1000 Subject: [PATCH 081/105] examples/Makefile: Use MAKE to properly invoke make recursively --- examples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 0436a13..2f816e5 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -22,10 +22,10 @@ build-examples: $(EXAMPLES_BUILD) rebuild-examples: $(EXAMPLES_REBUILD) %.dummybuild: - make -C $(dir $@) + $(MAKE) -C $(dir $@) %.dummyrebuild: - make -C $(dir $@) rebuild + $(MAKE) -C $(dir $@) rebuild .PHONY: warning rebuild-examples build-examples .NOTPARALLEL: From a5ba05b5f9ea4141371a22ec9ec3cb633fd48916 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 26 Aug 2015 11:16:58 +1000 Subject: [PATCH 082/105] Remove stray extras/cplusplus --- extras/cplusplus/component.mk | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 extras/cplusplus/component.mk diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk deleted file mode 100644 index 3f5673d..0000000 --- a/extras/cplusplus/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -# Component makefile for extras/cplusplus - -INC_DIRS += $(ROOT)extras From f31daa7f9ac46df798df33503b14f6faf790b876 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 12 Sep 2015 15:23:42 +1000 Subject: [PATCH 083/105] iomux: Fix setting of invalid bits when masking in iomux fields Fixes regression from 2a939e97 Part of issue #45 --- core/include/esp/iomux_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/esp/iomux_regs.h b/core/include/esp/iomux_regs.h index 4ea3be2..2600da9 100644 --- a/core/include/esp/iomux_regs.h +++ b/core/include/esp/iomux_regs.h @@ -45,7 +45,7 @@ _Static_assert(sizeof(struct IOMUX_REGS) == 0x44, "IOMUX_REGS is the wrong size" #define IOMUX_PIN_FUNC_MASK 0x00001030 /* WARNING: Macro evaluates argument twice */ -#define IOMUX_FUNC(val) (VAL2FIELD(IOMUX_PIN_FUNC_LOW, val) | VAL2FIELD(IOMUX_PIN_FUNC_HIGH, val)) +#define IOMUX_FUNC(val) (VAL2FIELD_M(IOMUX_PIN_FUNC_LOW, val) | VAL2FIELD_M(IOMUX_PIN_FUNC_HIGH, val)) /* WARNING: Macro evaluates argument twice */ #define IOMUX_FUNC_VALUE(regbits) (FIELD2VAL(IOMUX_PIN_FUNC_LOW, regbits) | FIELD2VAL(IOMUX_PIN_FUNC_HIGH, regbits)) From 3aff91c85c1c5bc9d2f783aa62826edb85ac908e Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 12 Sep 2015 16:20:05 +1000 Subject: [PATCH 084/105] Rename GPIO_CONF_PUSH_PULL to GPIO_CONF_OPEN_DRAIN Seems I got the functionality of this bit inverted when initially testing. In testing it also seems open drain mode is ignored on some pins, which still source current. Needs more investigation though (may be pullups internal to the ESP modules or set by default in software.) Relates to #45 --- core/include/esp/gpio.h | 10 ++++------ core/include/esp/gpio_regs.h | 15 ++++++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/core/include/esp/gpio.h b/core/include/esp/gpio.h index 679fff2..4f431f2 100644 --- a/core/include/esp/gpio.h +++ b/core/include/esp/gpio.h @@ -27,28 +27,26 @@ typedef enum { INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction) { uint32_t iomux_flags; - uint32_t ctrl_val; switch(direction) { case GPIO_INPUT: iomux_flags = 0; - ctrl_val = 0; break; case GPIO_OUTPUT: iomux_flags = IOMUX_PIN_OUTPUT_ENABLE; - ctrl_val = GPIO_CONF_PUSH_PULL; break; case GPIO_OUT_OPEN_DRAIN: iomux_flags = IOMUX_PIN_OUTPUT_ENABLE; - ctrl_val = 0; break; case GPIO_INPUT_PULLUP: iomux_flags = IOMUX_PIN_PULLUP; - ctrl_val = 0; break; } iomux_set_gpio_function(gpio_num, iomux_flags); - GPIO.CONF[gpio_num] = (GPIO.CONF[gpio_num] & FIELD_MASK(GPIO_CONF_INTTYPE)) | ctrl_val; + if(direction == GPIO_OUT_OPEN_DRAIN) + GPIO.CONF[gpio_num] |= GPIO_CONF_OPEN_DRAIN; + else + GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN; if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE) GPIO.ENABLE_OUT_SET = BIT(gpio_num); else diff --git a/core/include/esp/gpio_regs.h b/core/include/esp/gpio_regs.h index 3d91efb..815e7c1 100644 --- a/core/include/esp/gpio_regs.h +++ b/core/include/esp/gpio_regs.h @@ -76,10 +76,15 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); * Under what conditions this GPIO input should generate an interrupt. * (see gpio_inttype_t enum below for values) * - * GPIO_CONF_PUSH_PULL (boolean) - * When set, a high output state will pull the pin up to +Vcc (3.3V). When - * cleared, output functions in "open drain" mode (low state will pull down - * to ground, but high state allows output to "float"). + * GPIO_CONF_OPEN_DRAIN (boolean) + * If this bit is set, the pin is in "open drain" mode - a high output state + * will leave the pin floating but not source any current. If bit is cleared, + * the pin is in push/pull mode so a high output state will drive the pin up + * to +Vcc (3.3V). In either case, a low output state will pull the pin down + * to ground. + * + * GPIO_CONF_OPEN_DRAIN does not appear to work on all pins. + * * * GPIO_CONF_SOURCE_PWM (boolean) * When set, GPIO pin output will be connected to the sigma-delta PWM @@ -93,7 +98,7 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); #define GPIO_CONF_WAKEUP_ENABLE BIT(10) #define GPIO_CONF_INTTYPE_M 0x00000007 #define GPIO_CONF_INTTYPE_S 7 -#define GPIO_CONF_PUSH_PULL BIT(2) +#define GPIO_CONF_OPEN_DRAIN BIT(2) #define GPIO_CONF_SOURCE_PWM BIT(0) /* Valid values for the GPIO_CONF_INTTYPE field */ From 0da6c97a9d320dff6a01818accd6cd2c84ff876f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sat, 12 Sep 2015 16:28:11 +1000 Subject: [PATCH 085/105] Rename main.cpp in tasks example --- examples/cpp_01_tasks/{main.cpp => cpp_tasks.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/cpp_01_tasks/{main.cpp => cpp_tasks.cpp} (100%) diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/cpp_tasks.cpp similarity index 100% rename from examples/cpp_01_tasks/main.cpp rename to examples/cpp_01_tasks/cpp_tasks.cpp From 1c9e106db84766a1ecc35cb1476514932d4a3e29 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 27 Aug 2015 16:47:38 +1000 Subject: [PATCH 086/105] Compile with -ffunction-sectons -fdata-sections, link with -gc-sections This seems to shrink code size by abou 3.5%. Not sure if there are any downsides. --- common.mk | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/common.mk b/common.mk index e6e6c84..83c4f1f 100644 --- a/common.mk +++ b/common.mk @@ -94,14 +94,25 @@ OWN_LIBC ?= 1 # Note: you will need a recent esp ENTRY_SYMBOL ?= call_user_start +# Set this to zero if you don't want individual function & data sections +# (some code may be slightly slower, linking will be slighty slower, +# but compiled code size will come down a small amount.) +SPLIT_SECTIONS ?= 1 + # Common flags for both C & C++_ C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals $(CPPFLAGS) # Flags for C only CFLAGS = $(C_CXX_FLAGS) -std=gnu99 # Flags for C++ only CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions -fno-rtti + LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS) +ifeq ($(SPLIT_SECTIONS),1) + C_CXX_FLAGS += -ffunction-sections -fdata-sections + LDFLAGS += -Wl,-gc-sections +endif + ifeq ($(FLAVOR),debug) C_CXX_FLAGS += -g -O0 LDFLAGS += -g -O0 From f230fbcd65df45854baab39d0c066ac605443dfc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 18 Sep 2015 13:45:44 +1000 Subject: [PATCH 087/105] Move start of IROM0 to 0x40220000, save 128kB of flash Old starting point left 256kB for RAM sections, but I think they shouldn't ever possibly exceed 128kB. --- common.mk | 2 +- ld/eagle.app.v6.ld | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index 83c4f1f..f67e814 100644 --- a/common.mk +++ b/common.mk @@ -163,7 +163,7 @@ ifeq ($(OTA),0) # for non-OTA, we create two different files for uploading into the flash # these are the names and options to generate them FW_ADDR_1 = 0x00000 -FW_ADDR_2 = 0x40000 +FW_ADDR_2 = 0x20000 FW_FILE_1 = $(addprefix $(FW_BASE),$(FW_ADDR_1).bin) FW_FILE_2 = $(addprefix $(FW_BASE),$(FW_ADDR_2).bin) else diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index 566ad67..f1d11cc 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -32,7 +32,7 @@ ets_printf = printf; */ #ifndef OTA -#define IROM0_START 0x40240000 +#define IROM0_START 0x40220000 /* Non-OTA sizes */ #if FLASH_SIZE == 2 /* 256kB */ From 1b22cc088eadf8e0b907592356c07766f2a0fbf7 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 17 Sep 2015 20:35:39 +1000 Subject: [PATCH 088/105] Add initial mbedTLS and HTTPS example project (using howsmyssl.com JSON API) mbedTLS version 2.1.0 (current stable) Has some known issues/hacks: * Entropy source not hooked in at all * Linker script has a messy hack in it to store some (not all) data in irom --- .gitmodules | 3 + examples/http_get_mbedtls/Makefile | 4 + examples/http_get_mbedtls/http_get_mbedtls.c | 347 +++ .../http_get_mbedtls/include/mbedtls/config.h | 27 + extras/mbedtls/component.mk | 56 + extras/mbedtls/include/mbedtls/config.h | 2444 +++++++++++++++++ extras/mbedtls/mbedtls | 1 + extras/mbedtls/net_lwip.c | 510 ++++ ld/eagle.app.v6.ld | 119 +- lwip/component.mk | 2 +- 10 files changed, 3455 insertions(+), 58 deletions(-) create mode 100644 examples/http_get_mbedtls/Makefile create mode 100644 examples/http_get_mbedtls/http_get_mbedtls.c create mode 100644 examples/http_get_mbedtls/include/mbedtls/config.h create mode 100644 extras/mbedtls/component.mk create mode 100644 extras/mbedtls/include/mbedtls/config.h create mode 160000 extras/mbedtls/mbedtls create mode 100644 extras/mbedtls/net_lwip.c diff --git a/.gitmodules b/.gitmodules index 6a00a93..74c2102 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ path = axtls/axtls url = https://github.com/SuperHouse/axtls.git +[submodule "extras/mbedtls/mbedtls"] + path = extras/mbedtls/mbedtls + url = https://github.com/ARMmbed/mbedtls.git diff --git a/examples/http_get_mbedtls/Makefile b/examples/http_get_mbedtls/Makefile new file mode 100644 index 0000000..fc9a4fa --- /dev/null +++ b/examples/http_get_mbedtls/Makefile @@ -0,0 +1,4 @@ +PROGRAM=http_get_mbedtls +COMPONENTS = FreeRTOS lwip core extras/mbedtls + +include ../../common.mk diff --git a/examples/http_get_mbedtls/http_get_mbedtls.c b/examples/http_get_mbedtls/http_get_mbedtls.c new file mode 100644 index 0000000..d1fbf0d --- /dev/null +++ b/examples/http_get_mbedtls/http_get_mbedtls.c @@ -0,0 +1,347 @@ +/* http_get_mbedtls - HTTPS version of the http_get example, using mbed TLS. + * + * Retrieves a JSON response from the howsmyssl.com API via HTTPS over TLS v1.2. + * + * Validates the server's certificate using the root CA loaded (in PEM format) in cert.c. + * + * Adapted from the ssl_client1 example in mbedtls. + * + * Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License. + * Additions Copyright (C) 2015 Angus Gratton, Apache 2.0 License. + */ +#include "espressif/esp_common.h" +#include "espressif/sdk_private.h" + +#include + +#include "FreeRTOS.h" +#include "task.h" + +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include "lwip/netdb.h" +#include "lwip/dns.h" +#include "lwip/api.h" + +#include "ssid_config.h" + +/* mbedtls/config.h MUST appear before all other mbedtls headers, or + you'll get the default config. + + (Although mostly that isn't a big problem, you just might get + errors at link time if functions don't exist.) */ +#include "mbedtls/config.h" + +#include "mbedtls/net.h" +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" + +#define WEB_SERVER "howsmyssl.com" +#define WEB_PORT "443" +#define WEB_URL "https://www.howsmyssl.com/a/check" + +#define GET_REQUEST "GET "WEB_URL" HTTP/1.1\n\n" + +/* Root cert for howsmyssl.com, stored in cert.c */ +extern const char *server_root_cert; + +/* MBEDTLS_DEBUG_C disabled by default to save substantial bloating of + * firmware, define it in + * examples/http_get_mbedtls/include/mbedtls/config.h if you'd like + * debugging output. + */ +#ifdef MBEDTLS_DEBUG_C + + +/* Increase this value to see more TLS debug details, + 0 prints nothing, 1 will print any errors, 4 will print _everything_ +*/ +#define DEBUG_LEVEL 4 + +static void my_debug(void *ctx, int level, + const char *file, int line, + const char *str) +{ + ((void) level); + + /* Shorten 'file' from the whole file path to just the filename + + This is a bit wasteful because the macros are compiled in with + the full _FILE_ path in each case, so the firmware is bloated out + by a few kb. But there's not a lot we can do about it... + */ + char *file_sep = rindex(file, '/'); + if(file_sep) + file = file_sep+1; + + printf("%s:%04d: %s", file, line, str); + fflush(stdout); +} +#endif + +void http_get_task(void *pvParameters) +{ + int successes = 0, failures = 0, ret; + printf("HTTP get task starting...\n"); + + uint32_t flags; + unsigned char buf[1024]; + const char *pers = "ssl_client1"; + + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_x509_crt cacert; + mbedtls_ssl_config conf; + mbedtls_net_context server_fd; + + /* + * 0. Initialize the RNG and the session data + */ + mbedtls_ssl_init(&ssl); + mbedtls_x509_crt_init(&cacert); + mbedtls_ctr_drbg_init(&ctr_drbg); + printf("\n . Seeding the random number generator..."); + fflush(stdout); + + mbedtls_ssl_config_init(&conf); + + mbedtls_entropy_init(&entropy); + if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *) pers, + strlen(pers))) != 0) + { + printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret); + while(1) {} /* todo: replace with abort() */ + } + + printf(" ok\n"); + + /* + * 0. Initialize certificates + */ + printf(" . Loading the CA root certificate ..."); + fflush(stdout); + + ret = mbedtls_x509_crt_parse(&cacert, (uint8_t*)server_root_cert, strlen(server_root_cert)+1); + if(ret < 0) + { + printf(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); + while(1) {} /* todo: replace with abort() */ + } + + printf(" ok (%d skipped)\n", ret); + + /* Hostname set here should match CN in server certificate */ + if((ret = mbedtls_ssl_set_hostname(&ssl, WEB_SERVER)) != 0) + { + printf(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); + while(1) {} /* todo: replace with abort() */ + } + + /* + * 2. Setup stuff + */ + printf(" . Setting up the SSL/TLS structure..."); + fflush(stdout); + + if((ret = mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT)) != 0) + { + printf(" failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret); + goto exit; + } + + printf(" ok\n"); + + /* OPTIONAL is not optimal for security, in this example it will print + a warning if CA verification fails but it will continue to connect. + */ + mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); + mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); +#ifdef MBEDTLS_DEBUG_C + mbedtls_debug_set_threshold(DEBUG_LEVEL); + mbedtls_ssl_conf_dbg(&conf, my_debug, stdout); +#endif + + if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) + { + printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret); + goto exit; + } + + /* Wait until we can resolve the DNS for the server, as an indication + our network is probably working... + */ + printf("Waiting for server DNS to resolve... "); + fflush(stdout); + err_t dns_err; + ip_addr_t host_ip; + do { + vTaskDelay(500 / portTICK_RATE_MS); + dns_err = netconn_gethostbyname(WEB_SERVER, &host_ip); + } while(dns_err != ERR_OK); + printf("done.\n"); + + while(1) { + mbedtls_net_init(&server_fd); + printf("top of loop, free heap = %u\n", xPortGetFreeHeapSize()); + /* + * 1. Start the connection + */ + printf(" . Connecting to %s:%s...", WEB_SERVER, WEB_PORT); + fflush(stdout); + + if((ret = mbedtls_net_connect(&server_fd, WEB_SERVER, + WEB_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) + { + printf(" failed\n ! mbedtls_net_connect returned %d\n\n", ret); + goto exit; + } + + printf(" ok\n"); + + mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL); + + /* + * 4. Handshake + */ + printf(" . Performing the SSL/TLS handshake..."); + fflush(stdout); + + while((ret = mbedtls_ssl_handshake(&ssl)) != 0) + { + if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) + { + printf(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret); + goto exit; + } + } + + printf(" ok\n"); + + /* + * 5. Verify the server certificate + */ + printf(" . Verifying peer X.509 certificate..."); + + /* In real life, we probably want to bail out when ret != 0 */ + if((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) + { + char vrfy_buf[512]; + + printf(" failed\n"); + + mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); + + printf("%s\n", vrfy_buf); + } + else + printf(" ok\n"); + + /* + * 3. Write the GET request + */ + printf(" > Write to server:"); + fflush(stdout); + + int len = sprintf((char *) buf, GET_REQUEST); + + while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) + { + if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) + { + printf(" failed\n ! mbedtls_ssl_write returned %d\n\n", ret); + goto exit; + } + } + + len = ret; + printf(" %d bytes written\n\n%s", len, (char *) buf); + + /* + * 7. Read the HTTP response + */ + printf(" < Read from server:"); + fflush(stdout); + + do + { + len = sizeof(buf) - 1; + memset(buf, 0, sizeof(buf)); + ret = mbedtls_ssl_read(&ssl, buf, len); + + if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) + continue; + + if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + ret = 0; + break; + } + + if(ret < 0) + { + printf("failed\n ! mbedtls_ssl_read returned %d\n\n", ret); + break; + } + + if(ret == 0) + { + printf("\n\nEOF\n\n"); + break; + } + + len = ret; + printf(" %d bytes read\n\n%s", len, (char *) buf); + } while(1); + + mbedtls_ssl_close_notify(&ssl); + + exit: + mbedtls_ssl_session_reset(&ssl); + mbedtls_net_free(&server_fd); + + if(ret != 0) + { + char error_buf[100]; + mbedtls_strerror(ret, error_buf, 100); + printf("\n\nLast error was: %d - %s\n\n", ret, error_buf); + failures++; + } else { + successes++; + } + + printf("\n\nsuccesses = %d failures = %d\n", successes, failures); + for(int countdown = successes ? 10 : 5; countdown >= 0; countdown--) { + printf("%d... ", countdown); + fflush(stdout); + vTaskDelay(1000 / portTICK_RATE_MS); + } + printf("\nStarting again!\n"); + } +} + +void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + + struct sdk_station_config config = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + }; + + /* required to call wifi_set_opmode before station_set_config */ + sdk_wifi_set_opmode(STATION_MODE); + sdk_wifi_station_set_config(&config); + + xTaskCreate(&http_get_task, (signed char *)"get_task", 2048, NULL, 2, NULL); +} diff --git a/examples/http_get_mbedtls/include/mbedtls/config.h b/examples/http_get_mbedtls/include/mbedtls/config.h new file mode 100644 index 0000000..2674292 --- /dev/null +++ b/examples/http_get_mbedtls/include/mbedtls/config.h @@ -0,0 +1,27 @@ +/* Special mbedTLS config file for http_get_mbedtls example, + overrides supported cipher suite list. + + Overriding the set of cipher suites saves small amounts of ROM and + RAM, and is a good practice in general if you know what server(s) + you want to connect to. + + However it's extra important here because the howsmyssl API sends + back the list of ciphers we send it as a JSON list in the, and we + only have a 4096kB receive buffer. If the server supported maximum + fragment length option then we wouldn't have this problem either, + but we do so this is a good workaround. + + The ciphers chosen below are common ECDHE ciphers, the same ones + Firefox uses when connecting to a TLSv1.2 server. +*/ +#ifndef MBEDTLS_CONFIG_H + +/* include_next picks up default config from extras/mbedtls/include/mbedtls/config.h */ +#include_next + +#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + +/* uncomment next line to include debug output from example */ +//#define MBEDTLS_DEBUG_C + +#endif diff --git a/extras/mbedtls/component.mk b/extras/mbedtls/component.mk new file mode 100644 index 0000000..c392471 --- /dev/null +++ b/extras/mbedtls/component.mk @@ -0,0 +1,56 @@ +# Component makefile for mbedtls + +# mbedtls by default builds into 3 libraries not one. We just use one for now (doesn't make a huge difference when static linking) + +# Config: +# We supply our own hand tweaked mbedtls/config.h in our 'include' dir, the rest of upstream mbedtls is not changed. + +MBEDTLS_DIR = $(mbedtls_ROOT)mbedtls/ +INC_DIRS += $(mbedtls_ROOT)include $(MBEDTLS_DIR)include + +# these OBJS_xxx variables are copied directly from mbedtls/mbedtls/Makefile, +# minus a few values (noted in comments) +# +# If updating to a future mbedtls version you can just copy these in. +OBJS_CRYPTO= aes.o aesni.o arc4.o \ + asn1parse.o asn1write.o base64.o \ + bignum.o blowfish.o camellia.o \ + ccm.o cipher.o cipher_wrap.o \ + ctr_drbg.o des.o dhm.o \ + ecdh.o ecdsa.o ecp.o \ + ecp_curves.o entropy.o entropy_poll.o \ + error.o gcm.o havege.o \ + hmac_drbg.o md.o md2.o \ + md4.o md5.o md_wrap.o \ + memory_buffer_alloc.o oid.o \ + padlock.o pem.o pk.o \ + pk_wrap.o pkcs12.o pkcs5.o \ + pkparse.o pkwrite.o platform.o \ + ripemd160.o rsa.o sha1.o \ + sha256.o sha512.o threading.o \ + timing.o version.o \ + version_features.o xtea.o +# minus net.o + +OBJS_X509= certs.o pkcs11.o x509.o \ + x509_create.o x509_crl.o x509_crt.o \ + x509_csr.o x509write_crt.o x509write_csr.o + +OBJS_TLS= debug.o ssl_cache.o \ + ssl_ciphersuites.o ssl_cli.o \ + ssl_cookie.o ssl_srv.o ssl_ticket.o \ + ssl_tls.o + +# args for passing into compile rule generation +mbedtls_INC_DIR = +mbedtls_SRC_DIR = $(mbedtls_ROOT) +mbedtls_EXTRA_SRC_FILES = $(patsubst %.o,$(MBEDTLS_DIR)library/%.c,$(OBJS_CRYPTO) $(OBJS_X509) $(OBJS_TLS)) + +# depending on cipher configuration, some mbedTLS variables are unused +mbedtls_CFLAGS = -Wno-error=unused-but-set-variable -Wno-error=unused-variable $(CFLAGS) + +$(eval $(call component_compile_rules,mbedtls)) + +# Helpful error if git submodule not initialised +$(MBEDTLS_DIR): + $(error "mbedtls git submodule not installed. Please run 'git submodule update --init'") diff --git a/extras/mbedtls/include/mbedtls/config.h b/extras/mbedtls/include/mbedtls/config.h new file mode 100644 index 0000000..903006d --- /dev/null +++ b/extras/mbedtls/include/mbedtls/config.h @@ -0,0 +1,2444 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/mbedtls/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Comment if your system does not support time functions + */ +//#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h and time(), gmtime() and the clock is correct. + * The time needs to be correct (not necesarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_XXX_ALT + * + * Uncomment a macro to let mbed TLS support the function in the platform + * abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS__MODULE_NAME__ALT + * + * Uncomment a macro to let mbed TLS use your alternate core implementation of + * a symmetric crypto or hash module (e.g. platform specific assembly + * optimized implementations). Keep in mind that the function prototypes + * should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_XTEA_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT + +/** + * \def MBEDTLS__FUNCTION_NAME__ALT + * + * Uncomment a macro to let mbed TLS use you alternate core implementation of + * symmetric crypto or hash function. Keep in mind that function prototypes + * should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * Note: if you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + */ +#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_XXX + * + * Uncomment or comment macros to add support for specific padding modes + * in the cipher layer with cipher modes that support padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES + +/** + * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES + +/** + * \def MBEDTLS_ECP_XXXX_ENABLED + * + * Enables specific curves within the Elliptic Curve module. + * By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + */ +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_SSL_AEAD_RANDOM_IV + * + * Generate a random IV rather than using the record sequence number as a + * nonce for ciphersuites using and AEAD algorithm (GCM or CCM). + * + * Using the sequence number is generally recommended. + * + * Uncomment this macro to always use random IVs with AEAD ciphersuites. + */ +//#define MBEDTLS_SSL_AEAD_RANDOM_IV + +/** + * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, mbed TLS can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/** + * \def MBEDTLS_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define MBEDTLS_SSL_DEBUG_ALL + +/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC + * + * Enable support for Encrypt-then-MAC, RFC 7366. + * + * This allows peers that both support it to use a more robust protection for + * ciphersuites using CBC, providing deep resistance against timing attacks + * on the padding or underlying cipher. + * + * This only affects CBC ciphersuites, and is useless if none is defined. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Encrypt-then-MAC + */ +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC + +/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET + * + * Enable support for Extended Master Secret, aka Session Hash + * (draft-ietf-tls-session-hash-02). + * + * This was introduced as "the proper fix" to the Triple Handshake familiy of + * attacks, but it is recommended to always use it (even if you disable + * renegotiation), since it actually fixes a more fundamental issue in the + * original SSL/TLS design, and has implications beyond Triple Handshake. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Extended Master Secret. + */ +#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +/** + * \def MBEDTLS_SSL_FALLBACK_SCSV + * + * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). + * + * For servers, it is recommended to always enable this, unless you support + * only one version of TLS, or know for sure that none of your clients + * implements a fallback strategy. + * + * For clients, you only need this if you're using a fallback strategy, which + * is not recommended in the first place, unless you absolutely need it to + * interoperate with buggy (version-intolerant) servers. + * + * Comment this macro to disable support for FALLBACK_SCSV + */ +#define MBEDTLS_SSL_FALLBACK_SCSV + +/** + * \def MBEDTLS_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define MBEDTLS_SSL_HW_RECORD_ACCEL + +/** + * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING + * + * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. + * + * This is a countermeasure to the BEAST attack, which also minimizes the risk + * of interoperability issues compared to sending 0-length records. + * + * Comment this macro to disable 1/n-1 record splitting. + */ +#define MBEDTLS_SSL_CBC_RECORD_SPLITTING + +/** + * \def MBEDTLS_SSL_RENEGOTIATION + * + * Disable support for TLS renegotiation. + * + * The two main uses of renegotiation are (1) refresh keys on long-lived + * connections and (2) client authentication after the initial handshake. + * If you don't need renegotiation, it's probably better to disable it, since + * it has been associated with security issues in the past and is easy to + * misuse/misunderstand. + * + * Comment this to disable support for renegotiation. + */ +#define MBEDTLS_SSL_RENEGOTIATION + +/** + * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to enable support for SSLv2 Client Hello messages. + */ +//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def MBEDTLS_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +#define MBEDTLS_SSL_PROTO_SSL3 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +#define MBEDTLS_SSL_PROTO_TLS1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 + */ +#define MBEDTLS_SSL_PROTO_TLS1_1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * + * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 + */ +#define MBEDTLS_SSL_PROTO_TLS1_2 + +/** + * \def MBEDTLS_SSL_PROTO_DTLS + * + * Enable support for DTLS (all available versions). + * + * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, + * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_1 + * or MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for DTLS + */ +#define MBEDTLS_SSL_PROTO_DTLS + +/** + * \def MBEDTLS_SSL_ALPN + * + * Enable support for RFC 7301 Application Layer Protocol Negotiation. + * + * Comment this macro to disable support for ALPN. + */ +#define MBEDTLS_SSL_ALPN + +/** + * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY + * + * Enable support for the anti-replay mechanism in DTLS. + * + * Requires: MBEDTLS_SSL_TLS_C + * MBEDTLS_SSL_PROTO_DTLS + * + * \warning Disabling this is often a security risk! + * See mbedtls_ssl_conf_dtls_anti_replay() for details. + * + * Comment this to disable anti-replay in DTLS. + */ +#define MBEDTLS_SSL_DTLS_ANTI_REPLAY + +/** + * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * \warning Disabling this can ba a security risk! (see above) + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +#define MBEDTLS_SSL_DTLS_HELLO_VERIFY + +/** + * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT + * + * Enable support for a limit of records with bad MAC. + * + * See mbedtls_ssl_conf_dtls_badmac_limit(). + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + */ +#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT + +/** + * \def MBEDTLS_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * Client-side, provides full support for session tickets (maintainance of a + * session store remains the responsibility of the application, though). + * Server-side, you also need to provide callbacks for writing and parsing + * tickets, including authenticated encryption and key management. Example + * callbacks are provided by MBEDTLS_SSL_TICKET_C. + * + * Comment this macro to disable support for SSL session tickets + */ +#define MBEDTLS_SSL_SESSION_TICKETS + +/** + * \def MBEDTLS_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Comment this macro to disable support for server name indication in SSL + */ +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/** + * \def MBEDTLS_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +#define MBEDTLS_SSL_TRUNCATED_HMAC + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +#define MBEDTLS_VERSION_FEATURES + +/** + * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def MBEDTLS_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +#define MBEDTLS_X509_CHECK_KEY_USAGE + +/** + * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +#define MBEDTLS_X509_RSASSA_PSS_SUPPORT + +/** + * \def MBEDTLS_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * \note Currently compression can't be used with DTLS. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define MBEDTLS_ZLIB_SUPPORT +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +#define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/mbedtls_x509write_csr.c + */ +#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +#define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * This module is used for testing (ssl_client/server). + */ +#define MBEDTLS_CERTS_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +//#define MBEDTLS_DEBUG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/mbedtls_md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/mbedtls_md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/mbedtls_md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/mbedtls_md5.c + * Caller: library/mbedtls_md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * + * This module provides TCP/IP networking routines. + */ +#define MBEDTLS_NET_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/mbedtls_x509_crl.c + * library/mbedtls_x509_crt.c + * library/mbedtls_x509_csr.c + * library/x509write_crt.c + * library/mbedtls_x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/mbedtls_x509_crl.c + * library/mbedtls_x509_crt.c + * library/mbedtls_x509_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/mbedtls_x509write_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/mbedtls_x509_crt.c + * library/mbedtls_x509_csr.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: MBEDTLS_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define MBEDTLS_PKCS11_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/mbedtls_ripemd160.c + * Caller: library/mbedtls_md.c + * + */ +#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +#define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/mbedtls_sha1.c + * Caller: library/mbedtls_md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/mbedtls_sha256.c + * Caller: library/entropy.c + * library/mbedtls_md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/mbedtls_sha512.c + * Caller: library/entropy.c + * library/mbedtls_md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: MBEDTLS_SSL_CACHE_C + */ +#define MBEDTLS_SSL_CACHE_C + +/** + * \def MBEDTLS_SSL_COOKIE_C + * + * Enable basic implementation of DTLS cookies for hello verification. + * + * Module: library/ssl_cookie.c + * Caller: + */ +#define MBEDTLS_SSL_COOKIE_C + +/** + * \def MBEDTLS_SSL_TICKET_C + * + * Enable an implementation of TLS server-side callbacks for session tickets. + * + * Module: library/ssl_ticket.c + * Caller: + * + * Requires: MBEDTLS_CIPHER_C + */ +#define MBEDTLS_SSL_TICKET_C + +/** + * \def MBEDTLS_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define MBEDTLS_SSL_CLI_C + +/** + * \def MBEDTLS_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +#define MBEDTLS_SSL_SRV_C + +/** + * \def MBEDTLS_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * and at least one of the MBEDTLS_SSL_PROTO_XXX defines + * + * This module is required for SSL/TLS. + */ +#define MBEDTLS_SSL_TLS_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/mbedtls_x509_crl.c + * library/mbedtls_x509_crt.c + * library/mbedtls_x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, + * MBEDTLS_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/mbedtls_x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +#define MBEDTLS_X509_CRT_PARSE_C + +/** + * \def MBEDTLS_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/mbedtls_x509_crl.c + * Caller: library/mbedtls_x509_crt.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +#define MBEDTLS_X509_CRL_PARSE_C + +/** + * \def MBEDTLS_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/mbedtls_x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +#define MBEDTLS_X509_CSR_PARSE_C + +/** + * \def MBEDTLS_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +#define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +#define MBEDTLS_X509_CRT_WRITE_C + +/** + * \def MBEDTLS_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +#define MBEDTLS_X509_CSR_WRITE_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +#define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */ +#define MBEDTLS_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ + +/* SSL Cache options */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 4096 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ +//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* X509 options */ +//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ + +/* \} name SECTION: Module configuration options */ + +#if defined(TARGET_LIKE_MBED) +#include "mbedtls/target_config.h" +#endif + +/* + * Allow user to override any previous default. + * + * Use two macro names for that, as: + * - with yotta the prefix YOTTA_CFG_ is forced + * - without yotta is looks weird to have a YOTTA prefix. + */ +#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE +#elif defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "mbedtls/check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/extras/mbedtls/mbedtls b/extras/mbedtls/mbedtls new file mode 160000 index 0000000..0a0c22e --- /dev/null +++ b/extras/mbedtls/mbedtls @@ -0,0 +1 @@ +Subproject commit 0a0c22e0efcf2f8f71d7e16712f80b8f77326f72 diff --git a/extras/mbedtls/net_lwip.c b/extras/mbedtls/net_lwip.c new file mode 100644 index 0000000..10dba89 --- /dev/null +++ b/extras/mbedtls/net_lwip.c @@ -0,0 +1,510 @@ +/* + * TCP/IP or UDP/IP networking functions + * modified for LWIP support on ESP8266 + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Additions Copyright (C) 2015 Angus Gratton + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_NET_C) + +#include "mbedtls/net.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +/* + * Prepare for using the sockets interface + */ +static int net_prepare( void ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + WSADATA wsaData; + + if( wsa_init_done == 0 ) + { + if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) + return( MBEDTLS_ERR_NET_SOCKET_FAILED ); + + wsa_init_done = 1; + } +#else +#endif + return( 0 ); +} + +/* + * Initialize a context + */ +void mbedtls_net_init( mbedtls_net_context *ctx ) +{ + ctx->fd = -1; +} + +/* + * Initiate a TCP connection with host:port and the given protocol + */ +int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ) +{ + int ret; + struct addrinfo hints, *addr_list, *cur; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* Do name resolution with both IPv6 and IPv4 */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; + + if( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) + return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a connection succeeds */ + ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( ctx->fd < 0 ) + { + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + if( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 ) + { + ret = 0; + break; + } + + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_CONNECT_FAILED; + } + + freeaddrinfo( addr_list ); + + return( ret ); +} + +/* + * Create a listening socket on bind_ip:port + */ +int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ) +{ + int n, ret; + struct addrinfo hints, *addr_list, *cur; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* Bind to IPv6 and/or IPv4, but only in the desired protocol */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; + + if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) + return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a binding succeeds */ + ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( ctx->fd < 0 ) + { + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + n = 1; + if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &n, sizeof( n ) ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + if( bind( ctx->fd, cur->ai_addr, cur->ai_addrlen ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_BIND_FAILED; + continue; + } + + /* Listen only makes sense for TCP */ + if( proto == MBEDTLS_NET_PROTO_TCP ) + { + if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_LISTEN_FAILED; + continue; + } + } + + /* I we ever get there, it's a success */ + ret = 0; + break; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +} + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + */ +static int net_would_block( const mbedtls_net_context *ctx ) +{ + ((void) ctx); + return( WSAGetLastError() == WSAEWOULDBLOCK ); +} +#else +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + * + * Note: on a blocking socket this function always returns 0! + */ +static int net_would_block( const mbedtls_net_context *ctx ) +{ + /* + * Never return 'WOULD BLOCK' on a non-blocking socket + */ + if( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK ) + return( 0 ); + + switch( errno ) + { +#if defined EAGAIN + case EAGAIN: +#endif +#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + return( 1 ); + } + return( 0 ); +} +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +/* + * Accept a connection from a remote client + */ +int mbedtls_net_accept( mbedtls_net_context *bind_ctx, + mbedtls_net_context *client_ctx, + void *client_ip, size_t buf_size, size_t *ip_len ) +{ + int ret; + int type; + + struct sockaddr_in client_addr; + + socklen_t n = (socklen_t) sizeof( client_addr ); + socklen_t type_len = (socklen_t) sizeof( type ); + + /* Is this a TCP or UDP socket? */ + if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, + (void *) &type, (socklen_t *) &type_len ) != 0 || + ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) + { + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + } + + if( type == SOCK_STREAM ) + { + /* TCP: actual accept() */ + ret = client_ctx->fd = (int) accept( bind_ctx->fd, + (struct sockaddr *) &client_addr, &n ); + } + else + { + /* UDP: wait for a message, but keep it in the queue */ + char buf[1] = { 0 }; + + ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, + (struct sockaddr *) &client_addr, &n ); + +#if defined(_WIN32) + if( ret == SOCKET_ERROR && + WSAGetLastError() == WSAEMSGSIZE ) + { + /* We know buf is too small, thanks, just peeking here */ + ret = 0; + } +#endif + } + + if( ret < 0 ) + { + if( net_would_block( bind_ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + } + + /* UDP: hijack the listening socket to communicate with the client, + * then bind a new socket to accept new connections */ + if( type != SOCK_STREAM ) + { + struct sockaddr_in local_addr; + int one = 1; + + if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + + client_ctx->fd = bind_ctx->fd; + bind_ctx->fd = -1; /* In case we exit early */ + + n = sizeof( struct sockaddr_in ); + if( getsockname( client_ctx->fd, + (struct sockaddr *) &local_addr, &n ) != 0 || + ( bind_ctx->fd = (int) socket( AF_INET, + SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || + setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &one, sizeof( one ) ) != 0 ) + { + return( MBEDTLS_ERR_NET_SOCKET_FAILED ); + } + + if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) + { + return( MBEDTLS_ERR_NET_BIND_FAILED ); + } + } + + if( client_ip != NULL ) + { + struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; + *ip_len = sizeof( addr4->sin_addr.s_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); + } + + return( 0 ); +} + +/* + * Set the socket blocking or non-blocking + */ +int mbedtls_net_set_block( mbedtls_net_context *ctx ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + u_long n = 0; + return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); +#else + return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) ); +#endif +} + +int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + u_long n = 1; + return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); +#else + return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) ); +#endif +} + +/* + * Portable usleep helper + */ +void mbedtls_net_usleep( unsigned long usec ) +{ +#if defined(_WIN32) + Sleep( ( usec + 999 ) / 1000 ); +#else + struct timeval tv; + tv.tv_sec = usec / 1000000; +#if defined(__unix__) || defined(__unix) || \ + ( defined(__APPLE__) && defined(__MACH__) ) + tv.tv_usec = (suseconds_t) usec % 1000000; +#else + tv.tv_usec = usec % 1000000; +#endif + select( 0, NULL, NULL, NULL, &tv ); +#endif +} + +/* + * Read at most 'len' characters + */ +int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ) +{ + int ret; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + ret = (int) read( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); +#else + if( errno == EPIPE || errno == ECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + + return( MBEDTLS_ERR_NET_RECV_FAILED ); + } + + return( ret ); +} + +/* + * Read at most 'len' characters, blocking for at most 'timeout' ms + */ +int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ) +{ + int ret; + struct timeval tv; + fd_set read_fds; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + FD_ZERO( &read_fds ); + FD_SET( fd, &read_fds ); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = ( timeout % 1000 ) * 1000; + + ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); + + /* Zero fds ready means we timed out */ + if( ret == 0 ) + return( MBEDTLS_ERR_SSL_TIMEOUT ); + + if( ret < 0 ) + { +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAEINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#else + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + + return( MBEDTLS_ERR_NET_RECV_FAILED ); + } + + /* This call will not block */ + return( mbedtls_net_recv( ctx, buf, len ) ); +} + +/* + * Write at most 'len' characters + */ +int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) +{ + int ret; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + ret = (int) write( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_WRITE ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); +#else + if( errno == EPIPE || errno == ECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_WRITE ); +#endif + + return( MBEDTLS_ERR_NET_SEND_FAILED ); + } + + return( ret ); +} + +/* + * Gracefully close the connection + */ +void mbedtls_net_free( mbedtls_net_context *ctx ) +{ + if( ctx->fd == -1 ) + return; + + shutdown( ctx->fd, 2 ); + close( ctx->fd ); + + ctx->fd = -1; +} + +#endif /* MBEDTLS_NET_C */ diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index f1d11cc..3a52fed 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -136,6 +136,68 @@ SECTIONS _dport0_data_end = ABSOLUTE(.); } >dport0_0_seg :dport0_0_phdr + .text : ALIGN(4) /* IRAM */ + { + _stext = .; + _text_start = ABSOLUTE(.); + . = ALIGN (16); + *(.vecbase.text) + *(.entry.text) + *(.init.literal) + *(.init) + /* esp-open-rtos compiled source files use the .iram1.* section names for IRAM + functions, etc. */ + *(.iram1.*) + /* SDK libraries expect their .text sections to link to iram, not irom */ + *sdklib*:*(.literal .text .literal.* .text.*) + /* libgcc integer functions also need to be in .text, as some are called before + flash is mapped (also performance) + */ + *libgcc.a:*i3.o(.literal .text .literal.* .text.*) + + /* libc also in IRAM */ + *libc.a:*malloc.o(.literal .text .literal.* .text.*) + *libc.a:*mallocr.o(.literal .text .literal.* .text.*) + *libc.a:*freer.o(.literal .text .literal.* .text.*) + *libc.a:*memcpy.o(.literal .text .literal.* .text.*) + *libc.a:*memset.o(.literal .text .literal.* .text.*) + *libc.a:*memcmp.o(.literal .text .literal.* .text.*) + *libc.a:*memmove.o(.literal .text .literal.* .text.*) + *libc.a:*rand.o(.literal .text .literal.* .text.*) + *libc.a:*bzero.o(.literal .text .literal.* .text.*) + *libc.a:*lock.o(.literal .text .literal.* .text.*) + + *libc.a:*printf.o(.literal .text .literal.* .text.*) + *libc.a:*findfp.o(.literal .text .literal.* .text.*) + *libc.a:*fputwc.o(.literal .text .literal.* .text.*) + + /* xthal_set_intset() called from PendSV in NMI context */ + *libhal.a:*set_intset.o(.literal .text .literal.* .text.*) + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >iram1_0_seg :iram1_0_phdr + + .irom0.text : ALIGN(4) + { + _irom0_text_start = ABSOLUTE(.); + /* esp-open-rtos compiled code goes into IROM by default + (except for libgcc which is matched above.) + */ + *(.literal .text .literal.* .text.*) + /* mbedtls rodata */ + *mbedtls.a:*.o(.rodata.* .rodata) + /* actual certificate in example (TEMPORARY HACK) */ + *:cert.o(.rodata.* .rodata) + /* Anything explicitly marked as "irom" or "irom0" should go here */ + *(.irom.* .irom.*.* .irom0.*) + _irom0_text_end = ABSOLUTE(.); + } >irom0_0_seg :irom0_0_phdr + .data : ALIGN(4) { _data_start = ABSOLUTE(.); @@ -218,63 +280,6 @@ SECTIONS } >dram0_0_seg :dram0_0_bss_phdr /* __stack = 0x3ffc8000; */ - .text : ALIGN(4) /* IRAM */ - { - _stext = .; - _text_start = ABSOLUTE(.); - . = ALIGN (16); - *(.vecbase.text) - *(.entry.text) - *(.init.literal) - *(.init) - /* esp-open-rtos compiled source files use the .iram1.* section names for IRAM - functions, etc. */ - *(.iram1.*) - /* SDK libraries expect their .text sections to link to iram, not irom */ - *sdklib*:*(.literal .text .literal.* .text.*) - /* libgcc integer functions also need to be in .text, as some are called before - flash is mapped (also performance) - */ - *libgcc.a:*i3.o(.literal .text .literal.* .text.*) - - /* libc also in IRAM */ - *libc.a:*malloc.o(.literal .text .literal.* .text.*) - *libc.a:*mallocr.o(.literal .text .literal.* .text.*) - *libc.a:*freer.o(.literal .text .literal.* .text.*) - *libc.a:*memcpy.o(.literal .text .literal.* .text.*) - *libc.a:*memset.o(.literal .text .literal.* .text.*) - *libc.a:*memcmp.o(.literal .text .literal.* .text.*) - *libc.a:*memmove.o(.literal .text .literal.* .text.*) - *libc.a:*rand.o(.literal .text .literal.* .text.*) - *libc.a:*bzero.o(.literal .text .literal.* .text.*) - *libc.a:*lock.o(.literal .text .literal.* .text.*) - - *libc.a:*printf.o(.literal .text .literal.* .text.*) - *libc.a:*findfp.o(.literal .text .literal.* .text.*) - *libc.a:*fputwc.o(.literal .text .literal.* .text.*) - - /* xthal_set_intset() called from PendSV in NMI context */ - *libhal.a:*set_intset.o(.literal .text .literal.* .text.*) - - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _text_end = ABSOLUTE(.); - _etext = .; - } >iram1_0_seg :iram1_0_phdr - - .irom0.text : ALIGN(4) - { - _irom0_text_start = ABSOLUTE(.); - /* esp-open-rtos compiled code goes into IROM by default - (except for libgcc which is matched above.) - */ - *(.literal .text .literal.* .text.*) - /* Anything explicitly marked as "irom" or "irom0" should go here */ - *(.irom.* .irom.*.* .irom0.*) - _irom0_text_end = ABSOLUTE(.); - } >irom0_0_seg :irom0_0_phdr .lit4 : ALIGN(4) { diff --git a/lwip/component.mk b/lwip/component.mk index e16baa0..1bbe21c 100644 --- a/lwip/component.mk +++ b/lwip/component.mk @@ -1,7 +1,7 @@ # Component makefile for LWIP LWIP_DIR = $(lwip_ROOT)lwip/src/ -INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip +INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip # args for passing into compile rule generation lwip_INC_DIR = # all in INC_DIRS, needed for normal operation From b03f279f747197c5ab1621b0852f0bd949e68109 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 18 Sep 2015 15:12:09 +1000 Subject: [PATCH 089/105] mbedTLS: Add ESP8266 hardware entropy source discovered by @foogod Addresses #3, provided turns out to be an effective HWRNG. --- core/include/esp/wdev_regs.h | 44 +++++++++++++++++++++++++ extras/mbedtls/hardware_entropy.c | 27 +++++++++++++++ extras/mbedtls/include/mbedtls/config.h | 8 +++-- 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 core/include/esp/wdev_regs.h create mode 100644 extras/mbedtls/hardware_entropy.c diff --git a/core/include/esp/wdev_regs.h b/core/include/esp/wdev_regs.h new file mode 100644 index 0000000..bc7d54b --- /dev/null +++ b/core/include/esp/wdev_regs.h @@ -0,0 +1,44 @@ +/* esp/dport_regs.h + * + * ESP8266 WDEV register definitions + * + * In the DPORT memory space, alongside DPORT regs. However mostly + * concerned with the WiFi hardware interface. + * + * Not well understood at all, 100% figured out via reverse engineering. + */ + +#ifndef _ESP_WDEV__REGS_H +#define _ESP_WDEV__REGS_H + +#include "esp/types.h" +#include "common_macros.h" + +#define WDEV_BASE 0x3ff20e00 +#define WDEV (*(struct WDEV_REGS *)(WDEV_BASE)) + +/* WDEV registers +*/ + +struct WDEV_REGS { + uint32_t volatile _unknown00; // 0x00 + uint32_t volatile _unknown04; // 0x04 + uint32_t volatile _unknown08; // 0x08 + uint32_t volatile _unknown0c; // 0x0c + uint32_t volatile _unknown10; // 0x10 + uint32_t volatile _unknown14; // 0x14 + uint32_t volatile _unknown18; // 0x18 + uint32_t volatile _unknown1c; // 0x1c + uint32_t volatile _unknown20; // 0x20 + uint32_t volatile _unknown24; // 0x24 + uint32_t volatile _unknown28; // 0x28 + uint32_t volatile _unknown2c; // 0x2c + uint32_t volatile _unknown30; // 0x30 + uint32_t volatile _unknown34; // 0x34 + uint32_t volatile _unknown38; // 0x38 + uint32_t volatile _unknown3c; // 0x3c + uint32_t volatile _unknown40; // 0x40 + uint32_t volatile HWRNG; // 0x44 Appears to be HW RNG, see https://github.com/SuperHouse/esp-open-rtos/issues/3#issuecomment-139453094 +}; + +#endif diff --git a/extras/mbedtls/hardware_entropy.c b/extras/mbedtls/hardware_entropy.c new file mode 100644 index 0000000..85dd00d --- /dev/null +++ b/extras/mbedtls/hardware_entropy.c @@ -0,0 +1,27 @@ +/* ESP8266 "Hardware RNG" (validity still being confirmed) support for ESP8266 + * + * Based on research done by @foogod. + * + * Please don't rely on this too much as an entropy source, quite yet... + * + * Part of esp-open-rtos + * Copyright (C) 2015 Angus Gratton + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include + +int mbedtls_hardware_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + (void)(data); + for(int i = 0; i < len; i+=4) { + uint32_t random = WDEV.HWRNG; + /* using memcpy here in case output is unaligned */ + memcpy(output + i, &random, (i+4 <= len) ? 4 : (len % 4)); + } + if(olen) + *olen = len; + return 0; +} diff --git a/extras/mbedtls/include/mbedtls/config.h b/extras/mbedtls/include/mbedtls/config.h index 903006d..54ce5be 100644 --- a/extras/mbedtls/include/mbedtls/config.h +++ b/extras/mbedtls/include/mbedtls/config.h @@ -289,7 +289,8 @@ * * Uncomment to use your own hardware entropy collector. */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT +/* hardware RNG interface provided in hardware_entropy.c */ +#define MBEDTLS_ENTROPY_HARDWARE_ALT /** * \def MBEDTLS_AES_ROM_TABLES @@ -777,7 +778,7 @@ * This option is only useful if both MBEDTLS_SHA256_C and * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 +#define MBEDTLS_ENTROPY_FORCE_SHA256 /** * \def MBEDTLS_MEMORY_DEBUG @@ -2350,7 +2351,8 @@ /* CTR_DRBG options */ //#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +/* this is normally 10x higher, but reseeding seems quite inexpensive on esp8266 */ +#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 1000 /**< Interval before reseed is performed by default */ //#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ //#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ //#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ From 59a0a6f86e1a1a987f2b89537d3acac0070e3568 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sun, 20 Sep 2015 21:41:39 +1000 Subject: [PATCH 090/105] http_get_mbedtls: Add root cert used by howmyssl.com --- examples/http_get_mbedtls/cert.c | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/http_get_mbedtls/cert.c diff --git a/examples/http_get_mbedtls/cert.c b/examples/http_get_mbedtls/cert.c new file mode 100644 index 0000000..a0050a6 --- /dev/null +++ b/examples/http_get_mbedtls/cert.c @@ -0,0 +1,39 @@ +/* This is the root certificate for the CA trust chain of + www.howsmyssl.com in PEM format, as dumped via: + + openssl s_client -showcerts -connect www.howsmyssl.com:443 +#include +#include + +const char *server_root_cert = "-----BEGIN CERTIFICATE-----\r\n" +"MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\r\n" +"MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i\r\n" +"YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG\r\n" +"EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg\r\n" +"U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP\r\n" +"2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP\r\n" +"UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L\r\n" +"avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX\r\n" +"HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y\r\n" +"TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O\r\n" +"bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk\r\n" +"DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T\r\n" +"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp\r\n" +"aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB\r\n" +"BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w\r\n" +"TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93\r\n" +"d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ\r\n" +"BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9\r\n" +"WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/\r\n" +"qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG\r\n" +"mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry\r\n" +"lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY\r\n" +"R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn\r\n" +"TOCAXi25KhV6vGb4NQ==\r\n" +"-----END CERTIFICATE-----\r\n"; + + From b280f8a725f18999f2a501cd0b07a852bb454622 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Sun, 20 Sep 2015 14:09:30 -0700 Subject: [PATCH 091/105] Fix format strings in app_main.c --- core/app_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index 1989234..88ac743 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -270,12 +270,12 @@ void IRAM vApplicationStackOverflowHook(xTaskHandle task, char *task_name) { // .text+0x3d8 void IRAM vApplicationIdleHook(void) { - printf("idle %lu\n", WDEV.SYS_TIME); + printf("idle %u\n", WDEV.SYS_TIME); } // .text+0x404 void IRAM vApplicationTickHook(void) { - printf("tick %lu\n", WDEV.SYS_TIME); + printf("tick %u\n", WDEV.SYS_TIME); } // .Lfunc005 -- .irom0.text+0x8 @@ -360,12 +360,12 @@ static void dump_excinfo(void) { RSR(excvaddr, excvaddr); RSR(depc, depc); RSR(excsave1, excsave1); - printf("%s=0x%08lx\n", "epc1", epc1); - printf("%s=0x%08lx\n", "epc2", epc2); - printf("%s=0x%08lx\n", "epc3", epc3); - printf("%s=0x%08lx\n", "excvaddr", excvaddr); - printf("%s=0x%08lx\n", "depc", depc); - printf("%s=0x%08lx\n", "excsave1", excsave1); + printf("%s=0x%08x\n", "epc1", epc1); + printf("%s=0x%08x\n", "epc2", epc2); + printf("%s=0x%08x\n", "epc3", epc3); + printf("%s=0x%08x\n", "excvaddr", excvaddr); + printf("%s=0x%08x\n", "depc", depc); + printf("%s=0x%08x\n", "excsave1", excsave1); sdk_system_rtc_mem_read(0, excinfo, 32); // Why? excinfo[0] = 2; excinfo[1] = exccause; From c5a53c87fa04bfbf17324741e1ed02b89d216311 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 21 Sep 2015 08:46:45 +1000 Subject: [PATCH 092/105] bmp180: Fix more 'temperatue' typos (thanks @atomman) --- extras/bmp180/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/bmp180/README.md b/extras/bmp180/README.md index d6073c6..a8c41f5 100644 --- a/extras/bmp180/README.md +++ b/extras/bmp180/README.md @@ -34,12 +34,12 @@ As all data aqquired from the BMP180/BMP085 is provided to the `bmp180_informUse ``` // Own BMP180 User Inform Implementation -bool my_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) { +bool my_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure) { my_event_t ev; ev.event_type = MY_EVT_BMP180; ev.bmp180_data.cmd = cmd; - ev.bmp180_data.temperatue = temperatue; + ev.bmp180_data.temperature = temperature; ev.bmp180_data.pressure = pressure; return (xQueueSend(*resultQueue, &ev, 0) == pdTRUE); From f1bff97103c56748ef672b62330e05341911937b Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Mon, 21 Sep 2015 22:13:14 -0700 Subject: [PATCH 093/105] Further optimizations for LoadStoreErrorHandler --- core/exception_unaligned_load.S.inc | 190 ------------------- core/exception_vectors.S | 278 +++++++++++++++++++++++++++- 2 files changed, 268 insertions(+), 200 deletions(-) delete mode 100644 core/exception_unaligned_load.S.inc diff --git a/core/exception_unaligned_load.S.inc b/core/exception_unaligned_load.S.inc deleted file mode 100644 index 03c9830..0000000 --- a/core/exception_unaligned_load.S.inc +++ /dev/null @@ -1,190 +0,0 @@ -/* Xtensa Exception unaligned load handler - - Completes l8/l16 load instructions from Instruction address space, - that the architecture require to be 4 byte aligned word reads. - - Called from either UserExceptionVector or DoubleExceptionVector - depending on where the exception happened. - - Fast path (no branches) is for l8ui. - - Part of esp-open-rtos - Copyright (C) Angus Gratton - BSD Licensed as described in the file LICENSE -*/ - .text - .section .vecbase.text, "x" - .literal_position - -/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, - normal exception variant. */ -UserExceptionLoadStoreHandler: - addi sp, sp, -0x18 - s32i a2, sp, 0x08 - rsr.epc1 a2 -/* Inner UserLoadStoreExceptionHandler handlers. Works for both level1 & level 2 interrupt level. - * - * Called from level-specific handler above which sets up stack and loads epcX into a2. - */ -InnerLoadStoreExceptionHandler: - s32i a3, sp, 0x0c - s32i a4, sp, 0x10 - s32i a5, sp, 0x14 - rsr.sar a0 // save sar in a0 - - /* Examine the instruction we failed to execute (in a2) */ - ssa8l a2 // sar is now correct shift for aligned read - movi a3, ~3 - and a2, a2, a3 // a2 now 4-byte aligned address of instruction - l32i a3, a2, 0 - l32i a4, a2, 4 - src a2, a4, a3 // a2 now instruction that failed - - /* check for l8ui opcode 0x000002, or branch to check l16 */ - movi a3, 0x00700F /* opcode mask for l8ui/l16si/l16ui */ - and a3, a2, a3 - bnei a3, 0x000002, .Lcheck_fix_16bit - movi a5, 0xFF - -.Lcan_fix: - /* verified an 8- or 16-bit read - a2 holds instruction, a5 holds mask to apply to read value - */ - rsr.excvaddr a3 // read faulting address - ssa8l a3 /* sar is now shift to extract a3's byte */ - movi a4, ~3 - and a3, a3, a4 /* a3 now word aligned read address */ - - l32i a3, a3, 0 /* perform the actual read */ - srl a3, a3 /* shift right correct distance */ - and a4, a3, a5 /* mask off bits we need for an l8/l16 */ - - bbsi a5, 14, .Lmaybe_extend_sign -.Lafter_extend_sign: - /* a2 holds instruction, a4 holds the correctly read value */ - extui a2, a2, 4, 4 /* a2 now destination register 0-15 */ - - /* test if a4 needs to be written directly to a register (ie not a working register) */ - bgei a2, 6, .Lwrite_value_direct_reg - /* test if a4 needs to be written to a0 */ - beqz a2, .Lwrite_value_a0_reg - - /* otherwise, a4 can be written to a saved working register 'slot' on the stack */ - addx4 a5, a2, sp - s32i a4, a5, 0 - -.Lafter_write_value: - /* test PS.INTLEVEL (1=User, 2=Double) to see which interrupt level we restore from - */ - rsr.ps a2 - bbsi a2, 1, .Lincrement_PC_intlevel2 -.Lincrement_PC_intlevel1: - rsr.epc1 a2 - addi a3, a2, 0x3 - wsr.epc1 a3 - wsr.sar a0 // restore saved sar - rsr.excsave1 a0 // restore a0 saved in exception vector -.Lafter_increment_PC: - // Restore registers - l32i a2, sp, 0x08 - l32i a3, sp, 0x0c - l32i a4, sp, 0x10 - l32i a5, sp, 0x14 - addi sp, sp, 0x18 - rfe - - -/* Check the load instruction a2 for an l16si/16ui instruction - - First test for a signed vs unsigned load. - - a2 is the instruction, need to load a5 with the mask to use */ -.Lcheck_fix_16bit: - movi a4, 0x001002 /* l16si or l16ui opcode after masking */ - bne a3, a4, .Lcant_fix - - bbsi a2, 15, .Lcan_fix_16bit_signed - movi a5, 0xFFFF - j .Lcan_fix -.Lcan_fix_16bit_signed: - movi a5, 0x7FFF - j .Lcan_fix - -/* not an opcode we can try to fix, so bomb out - TODO: the exception dump will have some wrong values in it */ -.Lcant_fix: - call0 sdk_user_fatal_exception_handler - -/* increment PC for a DoubleException */ -.Lincrement_PC_intlevel2: - rsr.epc2 a2 - addi a3, a2, 0x3 - wsr.epc2 a3 - wsr.sar a0 // restore saved sar - rsr.excsave2 a0 // restore a0 saved in exception vector - j .Lafter_increment_PC - -.Lmaybe_extend_sign: /* apply 16-bit sign extension if necessary - a3 holds raw value, a4 holds masked */ - bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */ - bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */ - movi a3, 0xFFFF8000 - or a4, a3, a4 /* set 32-bit sign bits */ - j .Lafter_extend_sign - -.Lwrite_value_direct_reg: - /* Directly update register index a2, in range 6-15, using value in a4 */ - addi a2, a2, -6 - slli a2, a2, 3 /* offset from a6, x8 */ - movi a3, .Ldirect_reg_jumptable - add a2, a2, a3 - jx a2 - .align 8 -.Ldirect_reg_jumptable: - mov a6, a4 - j .Lafter_write_value - .align 8 - mov a7, a4 - j .Lafter_write_value - .align 8 - mov a8, a4 - j .Lafter_write_value - .align 8 - mov a9, a4 - j .Lafter_write_value - .align 8 - mov a10, a4 - j .Lafter_write_value - .align 8 - mov a11, a4 - j .Lafter_write_value - .align 8 - mov a12, a4 - j .Lafter_write_value - .align 8 - mov a13, a4 - j .Lafter_write_value - .align 8 - mov a14, a4 - j .Lafter_write_value - .align 8 - mov a15, a4 - j .Lafter_write_value - -.Lwrite_value_a0_reg: - /* a0 is saved in excsave1,so just update this with value - TODO: This won't work with interrupt level 2 - */ - wsr.excsave1 a4 - j .Lafter_write_value - - .literal_position -/* "Fix" LoadStoreException exceptions that are l8/l16 from an Instruction region, - DoubleException exception variant (ie load happened in a level1 exception handler). */ -DoubleExceptionLoadStoreHandler: - addi sp, sp, -0x18 - s32i a2, sp, 0x08 - rsr.epc2 a2 - j InnerLoadStoreExceptionHandler - -/* End of InnerUserLoadStoreExceptionHandler */ diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 270b711..a577034 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -26,7 +26,6 @@ .text .section .vecbase.text, "x" .global VecBase - .type VecBase, @function /* it's not really a function, but treat it like one */ .org 0 VecBase: /* IMPORTANT: exception vector literals will go here, but we @@ -36,35 +35,38 @@ VecBase: */ .literal_position .org 0x10 + .type DebugExceptionVector, @function DebugExceptionVector: wsr.excsave2 a0 call0 sdk_user_fatal_exception_handler rfi 2 .org 0x20 + .type NMIExceptionVector, @function NMIExceptionVector: wsr.excsave3 a0 call0 CallNMIExceptionHandler rfi 3 /* CallNMIExceptionHandler should call rfi itself */ .org 0x30 + .type KernelExceptionVector, @function KernelExceptionVector: break 1, 0 call0 sdk_user_fatal_exception_handler rfe .org 0x50 + .type UserExceptionVector, @function UserExceptionVector: wsr.excsave1 a0 rsr.exccause a0 - beqi a0, CAUSE_LOADSTORE, UserExceptionLoadStoreHandler + beqi a0, CAUSE_LOADSTORE, LoadStoreErrorHandler j UserExceptionHandler .org 0x70 + .type DoubleExceptionVector, @function DoubleExceptionVector: break 1, 4 - rsr.exccause a0 - beqi a0, CAUSE_LOADSTORE, DoubleExceptionLoadStoreHandler call0 sdk_user_fatal_exception_handler /* Reset vector would go here at offset 0x80 but should be unused, @@ -72,10 +74,260 @@ DoubleExceptionVector: /***** end of exception vectors *****/ -/* We include this here so UserExceptionLoadStoreHandler is within - the range of a 'beq' instruction jump. +/* Xtensa Exception unaligned load handler + + Completes l8/l16 load instructions from Instruction address space, + for which the architecture only supports 32-bit reads. + + Called from UserExceptionVector if EXCCAUSE is LoadStoreErrorCause + + Fast path (no branches) is for l8ui. */ -#include "exception_unaligned_load.S.inc" + .literal_position + + .type LoadStoreErrorHandler, @function +LoadStoreErrorHandler: + # Note: we use a0 as our "stack pointer" here because it's already been + # saved in UserExceptionVector, and we never call out to other routines + # so we don't have to worry about it being clobbered. It would be + # preferable to use a1 instead, but this would require changes to other + # parts of UserExceptionHandler code which we haven't gotten around to + # yet. + # TODO: Eventually, switch everything over to saving a1 instead of a0 + # in UserExceptionVector so we can use the more mnemonic SP for this. + + # Note: registers are saved in the (regnum * 4) address so calculation + # is easier later on. This means we don't use the first two entries + # (since we don't save a0 or a1 here), so we just adjust the pointer in + # a0 to pretend we have two extra slots at the beginning. + movi a0, LoadStoreErrorHandlerStack - 8 + s32i a2, a0, 0x08 + s32i a3, a0, 0x0c + s32i a4, a0, 0x10 + s32i a5, a0, 0x14 + rsr.sar a5 # Save SAR in a5 to restore later + + # Examine the opcode which generated the exception + # Note: Instructions are in this order to avoid pipeline stalls. + rsr.epc1 a2 + movi a3, ~3 + ssa8l a2 // sar is now correct shift for aligned read + and a2, a2, a3 // a2 now 4-byte aligned address of instruction + l32i a4, a2, 0 + l32i a2, a2, 4 + movi a3, 0x00700F // opcode mask for l8ui/l16si/l16ui + src a2, a2, a4 // a2 now instruction that failed + and a3, a2, a3 + bnei a3, 0x000002, .LSE_check_l16 + + # Note: At this point, opcode could technically be one of two things: + # xx0xx2 (L8UI) + # xx8xx2 (Reserved (invalid) opcode) + # It is assumed that we'll never get to this point from an illegal + # opcode, so we don't bother to check for that case and presume this is + # always an L8UI. + + /* a2 holds instruction */ + movi a4, ~3 + rsr.excvaddr a3 // read faulting address + and a4, a3, a4 /* a4 now word aligned read address */ + + l32i a4, a4, 0 /* perform the actual read */ + ssa8l a3 /* sar is now shift to extract a3's byte */ + srl a3, a4 /* shift right correct distance */ + extui a4, a3, 0, 8 /* mask off bits we need for an l8 */ + +.LSE_post_fetch: + # We jump back here after either the L8UI or the L16*I routines do the + # necessary work to read the value from memory. + # At this point, a2 holds the faulting instruction and a4 holds the + # correctly read value. + + # Restore original SAR value (saved in a5) and update EPC so we'll + # return back to the instruction following the one we just emulated + # Note: Instructions are in this order to avoid pipeline stalls + rsr.epc1 a3 + wsr.sar a5 + addi a3, a3, 0x3 + wsr.epc1 a3 + + # Stupid opcode tricks: The jumptable we use later on needs 16 bytes + # per entry (so we can avoid a second jump by just doing a RFE inside + # each entry). Unfortunately, however, Xtensa doesn't have an addx16 + # operation to make that easy for us. Luckily, all of the faulting + # opcodes we're processing are guaranteed to have bit 3 be zero, which + # means if we just shift the register bits of the opcode down by 3 + # instead of 4, we will get the register number multiplied by 2. This + # combined with an addx8 will give us an effective addx16 without + # needing any extra shift operations. + extui a2, a2, 3, 5 /* a2 now destination register 0-15 times 2 */ + + bgei a2, 12, .LSE_assign_reg # a6..a15 use jumptable + blti a2, 4, .LSE_assign_reg # a0..a1 use jumptable + + # We're storing into a2..a5, which are all saved in our "stack" area. + # Calculate the correct address and stick the value in there, then just + # do our normal restore and RFE (no jumps required, which actually + # makes a2..a5 substantially faster). + addx2 a2, a2, a0 + s32i a4, a2, 0 + + # Restore all regs and return + l32i a2, a0, 0x08 + l32i a3, a0, 0x0c + l32i a4, a0, 0x10 + l32i a5, a0, 0x14 + rsr.excsave1 a0 # restore a0 saved by UserExceptionVector + rfe + +.LSE_assign_reg: + # At this point, a2 contains the register number times 2, a4 is the + # read value. + + movi a3, .LSE_assign_jumptable + addx8 a2, a2, a3 # a2 is now the address to jump to + + # Restore everything except a2 and a4 + l32i a3, a0, 0x0c + l32i a5, a0, 0x14 + + jx a2 + +/* Check the load instruction a2 for an l16si/16ui instruction + + a2 is the instruction, a3 is masked instruction */ + .balign 4 +.LSE_check_l16: + movi a4, 0x001002 /* l16si or l16ui opcode after masking */ + bne a3, a4, .LSE_wrong_opcode + + # Note: At this point, the opcode could be one of two things: + # xx1xx2 (L16UI) + # xx9xx2 (L16SI) + # Both of these we can handle. + + movi a4, ~3 + rsr.excvaddr a3 // read faulting address + and a4, a3, a4 /* a4 now word aligned read address */ + + l32i a4, a4, 0 /* perform the actual read */ + ssa8l a3 /* sar is now shift to extract a3's byte */ + srl a3, a4 /* shift right correct distance */ + extui a4, a3, 0, 16 /* mask off bits we need for an l16 */ + + bbci a2, 15, .LSE_post_fetch # Not a signed op + bbci a4, 15, .LSE_post_fetch # Value does not require sign-extension + + movi a3, 0xFFFF0000 + or a4, a3, a4 /* set 32-bit sign bits */ + j .LSE_post_fetch + +/* If we got here it's not an opcode we can try to fix, so bomb out */ +.LSE_wrong_opcode: + # Restore registers so any dump the fatal exception routine produces + # will have correct values + wsr.sar a5 # Restore SAR saved in a5 + l32i a2, a0, 0x08 + l32i a3, a0, 0x0c + l32i a4, a0, 0x10 + l32i a5, a0, 0x14 + call0 sdk_user_fatal_exception_handler + + .balign 4 +.LSE_assign_jumptable: + .org .LSE_assign_jumptable + (16 * 0) + # a0 is saved in excsave1, so just update that with the value + wsr.excsave1 a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 1) + mov a1, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + # NOTE: Opcodes a2 .. a5 are not handled by the jumptable routines + # (they're taken care of directly in .LSE_post_fetch above) + # This leaves 64 bytes of wasted space here. We could fill it with + # other things, but that would just make it harder to understand what's + # going on, and that's bad enough with this routine already. Even on + # the ESP8266, 64 bytes of IRAM wasted aren't the end of the world.. + + .org .LSE_assign_jumptable + (16 * 6) + mov a6, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 7) + mov a7, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 8) + mov a8, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 9) + mov a9, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 10) + mov a10, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 11) + mov a11, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 12) + mov a12, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 13) + mov a13, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 14) + mov a14, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + + .org .LSE_assign_jumptable + (16 * 15) + mov a15, a4 + l32i a2, a0, 0x08 + l32i a4, a0, 0x10 + rsr.excsave1 a0 + rfe + +/* End of LoadStoreErrorHandler */ .section .bss NMIHandlerStack: /* stack space for NMI handler */ @@ -84,6 +336,12 @@ NMIHandlerStack: /* stack space for NMI handler */ NMIRegisterSaved: /* register space for saving NMI registers */ .skip 4*(16 + 6) +LoadStoreErrorHandlerStack: + .word 0 # a2 + .word 0 # a3 + .word 0 # a4 + .word 0 # a5 + /* Save register relative to a0 */ .macro SAVE_REG register, regnum s32i \register, a0, (0x20 + 4 * \regnum) @@ -181,7 +439,7 @@ CallNMIExceptionHandler: .type UserExceptionHandler, @function UserExceptionHandler: - mov a0, sp /* a0 was saved in UserExceptionVector */ + mov a0, sp /* a0 was saved by UserExceptionVector */ addi sp, sp, -0x50 s32i a0, sp, 0x10 rsr.ps a0 @@ -214,7 +472,7 @@ UserHandleTimer: and a3, a2, a3 /* a3 = a2 & 0xFFBF, ie remove 0x40 from a2 if set */ bnez a3, UserTimerDone /* bits other than 0x40 are set */ movi a3, 0x40 - sub a12, a2, a3 /* a12 - a2 - 0x40 - I think a12 _must_ be zero here? */ + sub a12, a2, a3 /* a12 = a2 - 0x40 -- Will be zero if bit 6 set */ call0 sdk__xt_timer_int /* tick timer interrupt */ mov a2, a12 /* restore a2 from a12, ie zero */ beqz a2, UserIntDone @@ -226,7 +484,7 @@ UserIntDone: break 1, 1 /* non-zero remnant in a2 means fail */ call0 sdk_user_fatal_exception_handler UserIntExit: - call0 sdk__xt_int_exit /* calls rfi */ + call0 sdk__xt_int_exit /* jumps to _xt_user_exit. Never returns here */ /* _xt_user_exit is used to exit interrupt context. TODO: Find a better place for this to live. From b15d149b09ef7066e8fd946604c9d6c28e23ff20 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Wed, 23 Sep 2015 08:51:36 -0700 Subject: [PATCH 094/105] More LoadStoreErrorHandler performance improvements --- core/exception_vectors.S | 207 +++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 105 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index a577034..a8d513a 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -58,9 +58,9 @@ KernelExceptionVector: .org 0x50 .type UserExceptionVector, @function UserExceptionVector: - wsr.excsave1 a0 - rsr.exccause a0 - beqi a0, CAUSE_LOADSTORE, LoadStoreErrorHandler + wsr.excsave1 a1 + rsr.exccause a1 + beqi a1, CAUSE_LOADSTORE, LoadStoreErrorHandler j UserExceptionHandler .org 0x70 @@ -87,25 +87,15 @@ DoubleExceptionVector: .type LoadStoreErrorHandler, @function LoadStoreErrorHandler: - # Note: we use a0 as our "stack pointer" here because it's already been - # saved in UserExceptionVector, and we never call out to other routines - # so we don't have to worry about it being clobbered. It would be - # preferable to use a1 instead, but this would require changes to other - # parts of UserExceptionHandler code which we haven't gotten around to - # yet. - # TODO: Eventually, switch everything over to saving a1 instead of a0 - # in UserExceptionVector so we can use the more mnemonic SP for this. - - # Note: registers are saved in the (regnum * 4) address so calculation - # is easier later on. This means we don't use the first two entries - # (since we don't save a0 or a1 here), so we just adjust the pointer in - # a0 to pretend we have two extra slots at the beginning. - movi a0, LoadStoreErrorHandlerStack - 8 - s32i a2, a0, 0x08 - s32i a3, a0, 0x0c - s32i a4, a0, 0x10 - s32i a5, a0, 0x14 - rsr.sar a5 # Save SAR in a5 to restore later + # Note: registers are saved in the address corresponding to their + # register number times 4. This allows a quick and easy mapping later + # on when needing to store the value to a particular register number. + movi sp, LoadStoreErrorHandlerStack + s32i a0, sp, 0 + s32i a2, sp, 0x08 + s32i a3, sp, 0x0c + s32i a4, sp, 0x10 + rsr.sar a0 # Save SAR in a0 to restore later # Examine the opcode which generated the exception # Note: Instructions are in this order to avoid pipeline stalls. @@ -143,11 +133,11 @@ LoadStoreErrorHandler: # At this point, a2 holds the faulting instruction and a4 holds the # correctly read value. - # Restore original SAR value (saved in a5) and update EPC so we'll + # Restore original SAR value (saved in a0) and update EPC so we'll # return back to the instruction following the one we just emulated # Note: Instructions are in this order to avoid pipeline stalls rsr.epc1 a3 - wsr.sar a5 + wsr.sar a0 addi a3, a3, 0x3 wsr.epc1 a3 @@ -162,34 +152,35 @@ LoadStoreErrorHandler: # needing any extra shift operations. extui a2, a2, 3, 5 /* a2 now destination register 0-15 times 2 */ - bgei a2, 12, .LSE_assign_reg # a6..a15 use jumptable - blti a2, 4, .LSE_assign_reg # a0..a1 use jumptable + bgei a2, 10, .LSE_assign_reg # a5..a15 use jumptable + beqi a2, 2, .LSE_assign_a1 # a1 uses a special routine - # We're storing into a2..a5, which are all saved in our "stack" area. + # We're storing into a0 or a2..a4, which are all saved in our "stack" area. # Calculate the correct address and stick the value in there, then just # do our normal restore and RFE (no jumps required, which actually - # makes a2..a5 substantially faster). - addx2 a2, a2, a0 + # makes a0..a4 substantially faster). + addx2 a2, a2, sp s32i a4, a2, 0 # Restore all regs and return - l32i a2, a0, 0x08 - l32i a3, a0, 0x0c - l32i a4, a0, 0x10 - l32i a5, a0, 0x14 - rsr.excsave1 a0 # restore a0 saved by UserExceptionVector + l32i a0, sp, 0 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + rsr.excsave1 a1 # restore a1 saved by UserExceptionVector rfe .LSE_assign_reg: # At this point, a2 contains the register number times 2, a4 is the # read value. - movi a3, .LSE_assign_jumptable - addx8 a2, a2, a3 # a2 is now the address to jump to - - # Restore everything except a2 and a4 - l32i a3, a0, 0x0c - l32i a5, a0, 0x14 + # Calculate the jumptable address, and restore regs except a2 and a4 + # so we have less to do after jumping. + # Note: Instructions are in this order to avoid pipeline stalls. + movi a3, .LSE_jumptable_base + l32i a0, sp, 0 + addx8 a2, a2, a3 # a2 is now the address to jump to + l32i a3, sp, 0x0c jx a2 @@ -226,105 +217,109 @@ LoadStoreErrorHandler: .LSE_wrong_opcode: # Restore registers so any dump the fatal exception routine produces # will have correct values - wsr.sar a5 # Restore SAR saved in a5 - l32i a2, a0, 0x08 - l32i a3, a0, 0x0c - l32i a4, a0, 0x10 - l32i a5, a0, 0x14 + wsr.sar a0 # Restore SAR saved in a0 + l32i a0, sp, 0 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + rsr.excsave1 a1 call0 sdk_user_fatal_exception_handler .balign 4 -.LSE_assign_jumptable: - .org .LSE_assign_jumptable + (16 * 0) - # a0 is saved in excsave1, so just update that with the value +.LSE_assign_a1: + # a1 is saved in excsave1, so just update that with the value wsr.excsave1 a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + # Restore all regs and return + l32i a0, sp, 0 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + rsr.excsave1 a1 # restore a1 saved by UserExceptionVector rfe - .org .LSE_assign_jumptable + (16 * 1) - mov a1, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + .balign 4 +.LSE_jumptable: + # The first 5 entries (80 bytes) of this table are unused (registers + # a0..a4 are handled separately above). Rather than have a whole bunch + # of wasted space, we just pretend that the table starts 80 bytes + # earlier in memory. + .set .LSE_jumptable_base, .LSE_jumptable - (16 * 5) + + .org .LSE_jumptable_base + (16 * 5) + mov a5, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - # NOTE: Opcodes a2 .. a5 are not handled by the jumptable routines - # (they're taken care of directly in .LSE_post_fetch above) - # This leaves 64 bytes of wasted space here. We could fill it with - # other things, but that would just make it harder to understand what's - # going on, and that's bad enough with this routine already. Even on - # the ESP8266, 64 bytes of IRAM wasted aren't the end of the world.. - - .org .LSE_assign_jumptable + (16 * 6) + .org .LSE_jumptable_base + (16 * 6) mov a6, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 7) + .org .LSE_jumptable_base + (16 * 7) mov a7, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 8) + .org .LSE_jumptable_base + (16 * 8) mov a8, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 9) + .org .LSE_jumptable_base + (16 * 9) mov a9, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 10) + .org .LSE_jumptable_base + (16 * 10) mov a10, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 11) + .org .LSE_jumptable_base + (16 * 11) mov a11, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 12) + .org .LSE_jumptable_base + (16 * 12) mov a12, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 13) + .org .LSE_jumptable_base + (16 * 13) mov a13, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 14) + .org .LSE_jumptable_base + (16 * 14) mov a14, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe - .org .LSE_assign_jumptable + (16 * 15) + .org .LSE_jumptable_base + (16 * 15) mov a15, a4 - l32i a2, a0, 0x08 - l32i a4, a0, 0x10 - rsr.excsave1 a0 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr.excsave1 a1 rfe /* End of LoadStoreErrorHandler */ @@ -337,10 +332,11 @@ NMIRegisterSaved: /* register space for saving NMI registers */ .skip 4*(16 + 6) LoadStoreErrorHandlerStack: + .word 0 # a0 + .word 0 # (unused) .word 0 # a2 .word 0 # a3 .word 0 # a4 - .word 0 # a5 /* Save register relative to a0 */ .macro SAVE_REG register, regnum @@ -439,7 +435,8 @@ CallNMIExceptionHandler: .type UserExceptionHandler, @function UserExceptionHandler: - mov a0, sp /* a0 was saved by UserExceptionVector */ + xsr.excsave1 a0 # a0 now contains sp + mov sp, a0 addi sp, sp, -0x50 s32i a0, sp, 0x10 rsr.ps a0 From 87f77b10217aec7317caf99ff47b233d6bfc51c9 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 24 Sep 2015 20:48:16 +1000 Subject: [PATCH 095/105] Refactor Hardware RNG functions to esp/hwrand.h As suggested by @foogod, thanks! --- core/esp_hwrand.c | 27 +++++++++++++++++++++++++++ core/include/esp/hwrand.h | 22 ++++++++++++++++++++++ extras/mbedtls/hardware_entropy.c | 9 ++------- 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 core/esp_hwrand.c create mode 100644 core/include/esp/hwrand.h diff --git a/core/esp_hwrand.c b/core/esp_hwrand.c new file mode 100644 index 0000000..7a591eb --- /dev/null +++ b/core/esp_hwrand.c @@ -0,0 +1,27 @@ +/* Hardware Random Number Generator Functions + * + * For documentation, see http://esp8266-re.foogod.com/wiki/Random_Number_Generator + * + * Part of esp-open-rtos + * Copyright (C) 2015 Angus Gratton + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include + +/* Return a random 32-bit number */ +uint32_t hwrand(void) +{ + return WDEV.HWRNG; +} + +/* Fill a variable size buffer with data from the Hardware RNG */ +void hwrand_fill(uint8_t *buf, size_t len) +{ + for(size_t i = 0; i < len; i+=4) { + uint32_t random = WDEV.HWRNG; + /* using memcpy here in case 'buf' is unaligned */ + memcpy(buf + i, &random, (i+4 <= len) ? 4 : (len % 4)); + } +} diff --git a/core/include/esp/hwrand.h b/core/include/esp/hwrand.h new file mode 100644 index 0000000..8ec75e1 --- /dev/null +++ b/core/include/esp/hwrand.h @@ -0,0 +1,22 @@ +/** esp/hwrand.h + * + * Hardware Random Number Generator functions. + * + * For documentation, see http://esp8266-re.foogod.com/wiki/Random_Number_Generator + * + * Part of esp-open-rtos + * Copyright (C) 2015 Angus Gratton + * BSD Licensed as described in the file LICENSE + */ +#ifndef _ESP_RNG_H +#define _ESP_RNG_H +#include +#include + +/* Return a random 32-bit number */ +uint32_t hwrand(void); + +/* Fill a variable size buffer with data from the Hardware RNG */ +void hwrand_fill(uint8_t *buf, size_t len); + +#endif diff --git a/extras/mbedtls/hardware_entropy.c b/extras/mbedtls/hardware_entropy.c index 85dd00d..0d197cd 100644 --- a/extras/mbedtls/hardware_entropy.c +++ b/extras/mbedtls/hardware_entropy.c @@ -9,18 +9,13 @@ * BSD Licensed as described in the file LICENSE */ #include -#include -#include +#include int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) { (void)(data); - for(int i = 0; i < len; i+=4) { - uint32_t random = WDEV.HWRNG; - /* using memcpy here in case output is unaligned */ - memcpy(output + i, &random, (i+4 <= len) ? 4 : (len % 4)); - } + hwrand_fill(output, len); if(olen) *olen = len; return 0; From edbfd3a66ecd32e6f8daaa199d38d98e1ba85e65 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 25 Sep 2015 09:22:06 +1000 Subject: [PATCH 096/105] unaligned_load tests: Remove incorrect references to DoubleException --- examples/experiments/unaligned_load/unaligned_load.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index d2d132f..d7f7203 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -207,7 +207,7 @@ void test_string(const char *string, char *label, bool evict_cache) run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache); } -static void test_doubleexception(); +static void test_isr(); static void test_sign_extension(); void sanity_tests(void); @@ -225,7 +225,7 @@ void user_init(void) test_string(iromtest, "Cached flash", 0); test_string(iromtest, "'Uncached' flash", 1); - test_doubleexception(); + test_isr(); test_sign_extension(); } @@ -241,9 +241,9 @@ static void frc1_interrupt_handler(void) frc1_finished = true; } -static void test_doubleexception() +static void test_isr() { - printf("Testing DoubleException behaviour...\r\n"); + printf("Testing behaviour inside ISRs...\r\n"); timer_set_interrupts(FRC1, false); timer_set_run(FRC1, false); _xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler); From 4dd87125268eb86ff58ea2f45b205b2d22861f88 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 25 Sep 2015 09:41:51 +1000 Subject: [PATCH 097/105] unaligned_load: Run some tests after scheduler/network/wifi all up and running As written this doesn't expose any new bugs. --- .../unaligned_load/unaligned_load.c | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index d7f7203..1574172 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -209,6 +209,7 @@ void test_string(const char *string, char *label, bool evict_cache) static void test_isr(); static void test_sign_extension(); +static void test_system_interaction(); void sanity_tests(void); void user_init(void) @@ -227,6 +228,9 @@ void user_init(void) test_isr(); test_sign_extension(); + + xTaskHandle taskHandle; + xTaskCreate(test_system_interaction, (signed char *)"interactionTask", 256, &taskHandle, 2, NULL); } static volatile bool frc1_ran; @@ -270,12 +274,40 @@ static void test_sign_extension() int16_t *shorts_p = (int16_t *)unsigned_shorts; if(shorts_p[0] == -3 && shorts_p[1] == -4 && shorts_p[2] == -5 && shorts_p[3] == -32767 && shorts_p[4] == 44) { - printf("l16si sign extension worked as expected.\r\n"); + printf("l16si sign extension PASSED.\r\n"); } else { - printf("l16si sign extension failed. Got values %d %d %d %d %d\r\n", shorts_p[0], shorts_p[1], shorts_p[2], shorts_p[3], shorts_p[4]); + printf("ERROR: l16si sign extension failed. Got values %d %d %d %d %d\r\n", shorts_p[0], shorts_p[1], shorts_p[2], shorts_p[3], shorts_p[4]); } } + +/* test that running unaligned loads in a running FreeRTOS system doesn't break things + + The following tests run inside a FreeRTOS task, after everything else. +*/ +static void test_system_interaction() +{ + uint32_t start = xTaskGetTickCount(); + printf("Starting system/timer interaction test (takes approx 30 seconds)...\n"); + for(int i = 0; i < 200*1000; i++) { + test_naive_strcpy_a0(iromtest); + test_naive_strcpy_a2(iromtest); + test_naive_strcpy_a3(iromtest); + test_naive_strcpy_a4(iromtest); + test_naive_strcpy_a5(iromtest); + test_naive_strcpy_a6(iromtest); + /* + const volatile char *string = iromtest; + volatile char *to = dest; + while((*to++ = *string++)) + ; + */ + } + uint32_t ticks = xTaskGetTickCount() - start; + printf("Timer interaction test PASSED after %dms.\n", ticks*portTICK_RATE_MS); + while(1) {} +} + /* The following "sanity tests" are designed to try to execute every code path * of the LoadStoreError handler, with a variety of offsets and data values * designed to catch any mask/shift errors, sign-extension bugs, etc */ From b6c2e4df597d17b13ceb154012a5efec153893e3 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Thu, 24 Sep 2015 18:32:32 -0700 Subject: [PATCH 098/105] Fix bad memory access in NMI handler CallNMIExceptionHandler was saving/restoring registers to the wrong offsets, causing it to potentially corrupt the first two slots of the LoadStoreErrorHandler's save area. --- core/exception_vectors.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index a8d513a..26e542f 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -340,12 +340,12 @@ LoadStoreErrorHandlerStack: /* Save register relative to a0 */ .macro SAVE_REG register, regnum - s32i \register, a0, (0x20 + 4 * \regnum) + s32i \register, a0, (4 * (\regnum + 6)) .endm /* Load register relative to sp */ .macro LOAD_REG register, regnum - l32i \register, sp, (0x20 + 4 * \regnum) + l32i \register, sp, (4 * (\regnum + 6)) .endm .text From b8134895243a7f8d803cf9f3da60895603e59e1d Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Thu, 24 Sep 2015 22:43:29 -0700 Subject: [PATCH 099/105] Code reformat/cleanup of exception_vectors.S --- core/exception_vectors.S | 973 ++++++++++++++++++++------------------- 1 file changed, 506 insertions(+), 467 deletions(-) diff --git a/core/exception_vectors.S b/core/exception_vectors.S index 26e542f..5e7f20e 100644 --- a/core/exception_vectors.S +++ b/core/exception_vectors.S @@ -1,502 +1,541 @@ /* Xtensa Exception (ie interrupt) Vectors & low-level handler code - - Core exception handler code is placed in the .vecbase section, - which gets picked up specially in the linker script and placed - at beginning of IRAM. - - The actual VecBase symbol should be the first thing in .vecbase - (this is not strictly important as it gets set by symbol lookup not - by hardcoded address, but having it at 0x40100000 means that the - exception vectors have memorable offsets, which match the default - Boot ROM vector offsets. So convenient for human understanding. - - Part of esp-open-rtos - Original vector contents Copyright (C) 2014-2015 Espressif Systems - Additions Copyright (C) Superhouse Automation Pty Ltd and Angus Gratton - BSD Licensed as described in the file LICENSE -*/ + * + * Core exception handler code is placed in the .vecbase section, which gets + * picked up specially in the linker script and placed at beginning of IRAM. + * + * The actual VecBase symbol should be the first thing in .vecbase (this is not + * strictly important as it gets set by symbol lookup not by hardcoded address, + * but having it at 0x40100000 means that the exception vectors have memorable + * offsets, which match the default Boot ROM vector offsets. So convenient for + * human understanding. + * + * Part of esp-open-rtos + * Original vector contents Copyright (C) 2014-2015 Espressif Systems + * Additions Copyright (C) Superhouse Automation Pty Ltd and Angus Gratton + * BSD Licensed as described in the file LICENSE + */ #include "led_debug.s" /* Some UserException causes, see table Table 4–64 in ISA reference */ + #define CAUSE_SYSCALL 1 #define CAUSE_LOADSTORE 3 #define CAUSE_LVL1INT 4 - .text - .section .vecbase.text, "x" - .global VecBase - .org 0 -VecBase: - /* IMPORTANT: exception vector literals will go here, but we - can't have more than 4 otherwise we push DebugExceptionVector past - offset 0x10 relative to VecBase. There should be ways to avoid this, - and also keep the VecBase offsets easy to read, but this works for now. - */ - .literal_position - .org 0x10 - .type DebugExceptionVector, @function -DebugExceptionVector: - wsr.excsave2 a0 - call0 sdk_user_fatal_exception_handler - rfi 2 + .section .bss - .org 0x20 - .type NMIExceptionVector, @function -NMIExceptionVector: - wsr.excsave3 a0 - call0 CallNMIExceptionHandler - rfi 3 /* CallNMIExceptionHandler should call rfi itself */ - - .org 0x30 - .type KernelExceptionVector, @function -KernelExceptionVector: - break 1, 0 - call0 sdk_user_fatal_exception_handler - rfe - - .org 0x50 - .type UserExceptionVector, @function -UserExceptionVector: - wsr.excsave1 a1 - rsr.exccause a1 - beqi a1, CAUSE_LOADSTORE, LoadStoreErrorHandler - j UserExceptionHandler - - .org 0x70 - .type DoubleExceptionVector, @function -DoubleExceptionVector: - break 1, 4 - call0 sdk_user_fatal_exception_handler - -/* Reset vector would go here at offset 0x80 but should be unused, - as vecbase goes back to mask ROM vectors on reset */ - -/***** end of exception vectors *****/ - -/* Xtensa Exception unaligned load handler - - Completes l8/l16 load instructions from Instruction address space, - for which the architecture only supports 32-bit reads. - - Called from UserExceptionVector if EXCCAUSE is LoadStoreErrorCause - - Fast path (no branches) is for l8ui. -*/ - .literal_position - - .type LoadStoreErrorHandler, @function -LoadStoreErrorHandler: - # Note: registers are saved in the address corresponding to their - # register number times 4. This allows a quick and easy mapping later - # on when needing to store the value to a particular register number. - movi sp, LoadStoreErrorHandlerStack - s32i a0, sp, 0 - s32i a2, sp, 0x08 - s32i a3, sp, 0x0c - s32i a4, sp, 0x10 - rsr.sar a0 # Save SAR in a0 to restore later - - # Examine the opcode which generated the exception - # Note: Instructions are in this order to avoid pipeline stalls. - rsr.epc1 a2 - movi a3, ~3 - ssa8l a2 // sar is now correct shift for aligned read - and a2, a2, a3 // a2 now 4-byte aligned address of instruction - l32i a4, a2, 0 - l32i a2, a2, 4 - movi a3, 0x00700F // opcode mask for l8ui/l16si/l16ui - src a2, a2, a4 // a2 now instruction that failed - and a3, a2, a3 - bnei a3, 0x000002, .LSE_check_l16 - - # Note: At this point, opcode could technically be one of two things: - # xx0xx2 (L8UI) - # xx8xx2 (Reserved (invalid) opcode) - # It is assumed that we'll never get to this point from an illegal - # opcode, so we don't bother to check for that case and presume this is - # always an L8UI. - - /* a2 holds instruction */ - movi a4, ~3 - rsr.excvaddr a3 // read faulting address - and a4, a3, a4 /* a4 now word aligned read address */ - - l32i a4, a4, 0 /* perform the actual read */ - ssa8l a3 /* sar is now shift to extract a3's byte */ - srl a3, a4 /* shift right correct distance */ - extui a4, a3, 0, 8 /* mask off bits we need for an l8 */ - -.LSE_post_fetch: - # We jump back here after either the L8UI or the L16*I routines do the - # necessary work to read the value from memory. - # At this point, a2 holds the faulting instruction and a4 holds the - # correctly read value. - - # Restore original SAR value (saved in a0) and update EPC so we'll - # return back to the instruction following the one we just emulated - # Note: Instructions are in this order to avoid pipeline stalls - rsr.epc1 a3 - wsr.sar a0 - addi a3, a3, 0x3 - wsr.epc1 a3 - - # Stupid opcode tricks: The jumptable we use later on needs 16 bytes - # per entry (so we can avoid a second jump by just doing a RFE inside - # each entry). Unfortunately, however, Xtensa doesn't have an addx16 - # operation to make that easy for us. Luckily, all of the faulting - # opcodes we're processing are guaranteed to have bit 3 be zero, which - # means if we just shift the register bits of the opcode down by 3 - # instead of 4, we will get the register number multiplied by 2. This - # combined with an addx8 will give us an effective addx16 without - # needing any extra shift operations. - extui a2, a2, 3, 5 /* a2 now destination register 0-15 times 2 */ - - bgei a2, 10, .LSE_assign_reg # a5..a15 use jumptable - beqi a2, 2, .LSE_assign_a1 # a1 uses a special routine - - # We're storing into a0 or a2..a4, which are all saved in our "stack" area. - # Calculate the correct address and stick the value in there, then just - # do our normal restore and RFE (no jumps required, which actually - # makes a0..a4 substantially faster). - addx2 a2, a2, sp - s32i a4, a2, 0 - - # Restore all regs and return - l32i a0, sp, 0 - l32i a2, sp, 0x08 - l32i a3, sp, 0x0c - l32i a4, sp, 0x10 - rsr.excsave1 a1 # restore a1 saved by UserExceptionVector - rfe - -.LSE_assign_reg: - # At this point, a2 contains the register number times 2, a4 is the - # read value. - - # Calculate the jumptable address, and restore regs except a2 and a4 - # so we have less to do after jumping. - # Note: Instructions are in this order to avoid pipeline stalls. - movi a3, .LSE_jumptable_base - l32i a0, sp, 0 - addx8 a2, a2, a3 # a2 is now the address to jump to - l32i a3, sp, 0x0c - - jx a2 - -/* Check the load instruction a2 for an l16si/16ui instruction - - a2 is the instruction, a3 is masked instruction */ - .balign 4 -.LSE_check_l16: - movi a4, 0x001002 /* l16si or l16ui opcode after masking */ - bne a3, a4, .LSE_wrong_opcode - - # Note: At this point, the opcode could be one of two things: - # xx1xx2 (L16UI) - # xx9xx2 (L16SI) - # Both of these we can handle. - - movi a4, ~3 - rsr.excvaddr a3 // read faulting address - and a4, a3, a4 /* a4 now word aligned read address */ - - l32i a4, a4, 0 /* perform the actual read */ - ssa8l a3 /* sar is now shift to extract a3's byte */ - srl a3, a4 /* shift right correct distance */ - extui a4, a3, 0, 16 /* mask off bits we need for an l16 */ - - bbci a2, 15, .LSE_post_fetch # Not a signed op - bbci a4, 15, .LSE_post_fetch # Value does not require sign-extension - - movi a3, 0xFFFF0000 - or a4, a3, a4 /* set 32-bit sign bits */ - j .LSE_post_fetch - -/* If we got here it's not an opcode we can try to fix, so bomb out */ -.LSE_wrong_opcode: - # Restore registers so any dump the fatal exception routine produces - # will have correct values - wsr.sar a0 # Restore SAR saved in a0 - l32i a0, sp, 0 - l32i a2, sp, 0x08 - l32i a3, sp, 0x0c - l32i a4, sp, 0x10 - rsr.excsave1 a1 - call0 sdk_user_fatal_exception_handler - - .balign 4 -.LSE_assign_a1: - # a1 is saved in excsave1, so just update that with the value - wsr.excsave1 a4 - # Restore all regs and return - l32i a0, sp, 0 - l32i a2, sp, 0x08 - l32i a3, sp, 0x0c - l32i a4, sp, 0x10 - rsr.excsave1 a1 # restore a1 saved by UserExceptionVector - rfe - - .balign 4 -.LSE_jumptable: - # The first 5 entries (80 bytes) of this table are unused (registers - # a0..a4 are handled separately above). Rather than have a whole bunch - # of wasted space, we just pretend that the table starts 80 bytes - # earlier in memory. - .set .LSE_jumptable_base, .LSE_jumptable - (16 * 5) - - .org .LSE_jumptable_base + (16 * 5) - mov a5, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 6) - mov a6, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 7) - mov a7, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 8) - mov a8, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 9) - mov a9, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 10) - mov a10, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 11) - mov a11, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 12) - mov a12, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 13) - mov a13, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 14) - mov a14, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - - .org .LSE_jumptable_base + (16 * 15) - mov a15, a4 - l32i a2, sp, 0x08 - l32i a4, sp, 0x10 - rsr.excsave1 a1 - rfe - -/* End of LoadStoreErrorHandler */ - - .section .bss -NMIHandlerStack: /* stack space for NMI handler */ - .skip 4*0x100 +NMIHandlerStack: # stack space for NMI handler + .skip 4*0x100 .LNMIHandlerStackTop: -NMIRegisterSaved: /* register space for saving NMI registers */ - .skip 4*(16 + 6) +NMIRegisterSaved: # register space for saving NMI registers + .skip 4*(16 + 6) LoadStoreErrorHandlerStack: - .word 0 # a0 - .word 0 # (unused) - .word 0 # a2 - .word 0 # a3 - .word 0 # a4 + .word 0 # a0 + .word 0 # (unused) + .word 0 # a2 + .word 0 # a3 + .word 0 # a4 + +/***************************** Exception Vectors *****************************/ + + .section .vecbase.text, "x" + +/* Note: Exception vectors must be aligned on a 256-byte (0x100) boundary or + * they will not function properly. (This is taken care of in the linker + * script by ensuring .vecbase.text is aligned properly, and putting VecBase + * right at the beginning of .vecbase.text) */ + .org 0 +VecBase: + .global VecBase + /* IMPORTANT: exception vector literals will go here, but we + * can't have more than 4 otherwise we push DebugExceptionVector past + * offset 0x10 relative to VecBase. There should be ways to avoid this, + * and also keep the VecBase offsets easy to read, but this works for + * now. */ + .literal_position + + .org VecBase + 0x10 +DebugExceptionVector: + .type DebugExceptionVector, @function + + wsr a0, excsave2 + call0 sdk_user_fatal_exception_handler + rfi 2 + + .org VecBase + 0x20 +NMIExceptionVector: + .type NMIExceptionVector, @function + + wsr a0, excsave3 + call0 CallNMIExceptionHandler + rfi 3 # Should never be reached + + .org VecBase + 0x30 +KernelExceptionVector: + .type KernelExceptionVector, @function + + break 1, 0 + call0 sdk_user_fatal_exception_handler + rfe + + .org VecBase + 0x50 +UserExceptionVector: + .type UserExceptionVector, @function + + wsr a1, excsave1 + rsr a1, exccause + beqi a1, CAUSE_LOADSTORE, LoadStoreErrorHandler + j UserExceptionHandler + + .org VecBase + 0x70 +DoubleExceptionVector: + .type DoubleExceptionVector, @function + + break 1, 4 + call0 sdk_user_fatal_exception_handler + +/* Reset vector at offset 0x80 is unused, as vecbase gets reset to mask ROM + * vectors on chip reset. */ + +/*************************** LoadStoreError Handler **************************/ + + .section .vecbase.text, "x" + +/* Xtensa "Load/Store Exception" handler: + * Completes L8/L16 load instructions from Instruction address space, for which + * the architecture only supports 32-bit reads. + * + * Called from UserExceptionVector if EXCCAUSE is LoadStoreErrorCause + * + * (Fast path (no branches) is for L8UI) + */ + .literal_position + + .balign 4 +LoadStoreErrorHandler: + .type LoadStoreErrorHandler, @function + + /* Registers are saved in the address corresponding to their register + * number times 4. This allows a quick and easy mapping later on when + * needing to store the value to a particular register number. */ + movi sp, LoadStoreErrorHandlerStack + s32i a0, sp, 0 + s32i a2, sp, 0x08 + s32i a3, sp, 0x0c + s32i a4, sp, 0x10 + rsr a0, sar # Save SAR in a0 to restore later + + /* Examine the opcode which generated the exception */ + /* Note: Instructions are in this order to avoid pipeline stalls. */ + rsr a2, epc1 + movi a3, ~3 + ssa8l a2 # sar is now correct shift for aligned read + and a2, a2, a3 # a2 now 4-byte aligned address of instruction + l32i a4, a2, 0 + l32i a2, a2, 4 + movi a3, 0x00700F # opcode mask for l8ui/l16si/l16ui + src a2, a2, a4 # a2 now instruction that failed + and a3, a2, a3 # a3 is masked instruction + bnei a3, 0x000002, .LSE_check_l16 + + /* Note: At this point, opcode could technically be one of two things: + * xx0xx2 (L8UI) + * xx8xx2 (Reserved (invalid) opcode) + * It is assumed that we'll never get to this point from an illegal + * opcode, so we don't bother to check for that case and presume this + * is always an L8UI. */ + + movi a4, ~3 + rsr a3, excvaddr # read faulting address + and a4, a3, a4 # a4 now word aligned read address + + l32i a4, a4, 0 # perform the actual read + ssa8l a3 # sar is now shift to extract a3's byte + srl a3, a4 # shift right correct distance + extui a4, a3, 0, 8 # mask off bits we need for an l8 + +.LSE_post_fetch: + /* We jump back here after either the L8UI or the L16*I routines do the + * necessary work to read the value from memory. + * At this point, a2 holds the faulting instruction and a4 holds the + * correctly read value. + + * Restore original SAR value (saved in a0) and update EPC so we'll + * return back to the instruction following the one we just emulated */ + + /* Note: Instructions are in this order to avoid pipeline stalls */ + rsr a3, epc1 + wsr a0, sar + addi a3, a3, 0x3 + wsr a3, epc1 + + /* Stupid opcode tricks: The jumptable we use later on needs 16 bytes + * per entry (so we can avoid a second jump by just doing a RFE inside + * each entry). Unfortunately, however, Xtensa doesn't have an addx16 + * operation to make that easy for us. Luckily, all of the faulting + * opcodes we're processing are guaranteed to have bit 3 be zero, which + * means if we just shift the register bits of the opcode down by 3 + * instead of 4, we will get the register number multiplied by 2. This + * combined with an addx8 will give us an effective addx16 without + * needing any extra shift operations. */ + extui a2, a2, 3, 5 # a2 is now destination register 0-15 times 2 + + bgei a2, 10, .LSE_assign_reg # a5..a15 use jumptable + beqi a2, 2, .LSE_assign_a1 # a1 uses a special routine + + /* We're storing into a0 or a2..a4, which are all saved in our "stack" + * area. Calculate the correct address and stick the value in there, + * then just do our normal restore and RFE (no jumps required, which + * actually makes a0..a4 substantially faster). */ + addx2 a2, a2, sp + s32i a4, a2, 0 + + /* Restore all regs and return */ + l32i a0, sp, 0 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + rsr a1, excsave1 # restore a1 saved by UserExceptionVector + rfe + +.LSE_assign_reg: + /* At this point, a2 contains the register number times 2, a4 is the + * read value. */ + + /* Calculate the jumptable address, and restore all regs except a2 and + * a4 so we have less to do after jumping. */ + /* Note: Instructions are in this order to avoid pipeline stalls. */ + movi a3, .LSE_jumptable_base + l32i a0, sp, 0 + addx8 a2, a2, a3 # a2 is now the address to jump to + l32i a3, sp, 0x0c + + jx a2 + + .balign 4 +.LSE_check_l16: + /* At this point, a2 contains the opcode, a3 is masked opcode */ + movi a4, 0x001002 # l16si or l16ui opcode after masking + bne a3, a4, .LSE_wrong_opcode + + /* Note: At this point, the opcode could be one of two things: + * xx1xx2 (L16UI) + * xx9xx2 (L16SI) + * Both of these we can handle. */ + + movi a4, ~3 + rsr a3, excvaddr # read faulting address + and a4, a3, a4 # a4 now word aligned read address + + l32i a4, a4, 0 # perform the actual read + ssa8l a3 # sar is now shift to extract a3's bytes + srl a3, a4 # shift right correct distance + extui a4, a3, 0, 16 # mask off bits we need for an l16 + + bbci a2, 15, .LSE_post_fetch # Not a signed op + bbci a4, 15, .LSE_post_fetch # Value does not need sign-extension + + movi a3, 0xFFFF0000 + or a4, a3, a4 # set 32-bit sign bits + j .LSE_post_fetch + +.LSE_wrong_opcode: + /* If we got here it's not an opcode we can try to fix, so bomb out. + * Restore registers so any dump the fatal exception routine produces + * will have correct values */ + wsr a0, sar + l32i a0, sp, 0 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + rsr a1, excsave1 + call0 sdk_user_fatal_exception_handler + + .balign 4 +.LSE_assign_a1: + /* a1 is saved in excsave1, so just update that with the value, */ + wsr a4, excsave1 + /* Then restore all regs and return */ + l32i a0, sp, 0 + l32i a2, sp, 0x08 + l32i a3, sp, 0x0c + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .balign 4 +.LSE_jumptable: + /* The first 5 entries (80 bytes) of this table are unused (registers + * a0..a4 are handled separately above). Rather than have a whole bunch + * of wasted space, we just pretend that the table starts 80 bytes + * earlier in memory. */ + .set .LSE_jumptable_base, .LSE_jumptable - (16 * 5) + + .org .LSE_jumptable_base + (16 * 5) + mov a5, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 6) + mov a6, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 7) + mov a7, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 8) + mov a8, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 9) + mov a9, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 10) + mov a10, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 11) + mov a11, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 12) + mov a12, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 13) + mov a13, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 14) + mov a14, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + + .org .LSE_jumptable_base + (16 * 15) + mov a15, a4 + l32i a2, sp, 0x08 + l32i a4, sp, 0x10 + rsr a1, excsave1 + rfe + +/****************************** call_user_start ******************************/ + + .section .vecbase.text, "x" + +/* This is the first entrypoint called from the ROM after loading the image + * into IRAM. It just sets up the VECBASE register to point at our own + * exception vectors and then calls sdk_user_start() */ + + .literal_position + + .balign 4 +call_user_start: + .global call_user_start + .type call_user_start, @function + + movi a2, VecBase + wsr a2, vecbase + call0 sdk_user_start + +/*************************** NMI Exception Handler ***************************/ + + .section .vecbase.text, "x" /* Save register relative to a0 */ .macro SAVE_REG register, regnum - s32i \register, a0, (4 * (\regnum + 6)) + s32i \register, a0, (4 * (\regnum + 6)) .endm /* Load register relative to sp */ .macro LOAD_REG register, regnum - l32i \register, sp, (4 * (\regnum + 6)) + l32i \register, sp, (4 * (\regnum + 6)) .endm - .text - .section .vecbase.text - .literal_position - .align 4 - .global call_user_start - .type call_user_start, @function -call_user_start: - movi a2, VecBase - wsr.vecbase a2 - call0 sdk_user_start + .literal_position - .literal_position - .align 16 - .type CallNMIExceptionHandler, @function + .balign 16 CallNMIExceptionHandler: - movi a0, NMIRegisterSaved - SAVE_REG a2, 2 - SAVE_REG sp, 1 - SAVE_REG a3, 3 - rsr.excsave3 a2 /* a2 is now former a0 */ - SAVE_REG a4, 4 - SAVE_REG a2, 0 - rsr.epc1 a3 - rsr.exccause a4 - SAVE_REG a3, -5 - SAVE_REG a4, -4 - rsr.excvaddr a3 - SAVE_REG a3, -3 - rsr.excsave1 a3 - SAVE_REG a3, -2 - SAVE_REG a5, 5 - SAVE_REG a6, 6 - SAVE_REG a7, 7 - SAVE_REG a8, 8 - SAVE_REG a9, 9 - SAVE_REG a10, 10 - SAVE_REG a11, 11 - SAVE_REG a12, 12 - SAVE_REG a13, 13 - SAVE_REG a14, 14 - SAVE_REG a15, 15 - movi sp, .LNMIHandlerStackTop - movi a0, 0 - movi a2, 0x23 /* argument for handler */ - wsr.ps a2 - rsync - rsr.sar a14 - s32i a14, sp, 0 /* this is also NMIRegisterSaved+0 */ - call0 sdk_wDev_ProcessFiq - l32i a15, sp, 0 - wsr.sar a15 - movi a2, 0x33 - wsr.ps a2 - rsync - LOAD_REG a4, 4 - LOAD_REG a5, 5 - LOAD_REG a6, 6 - LOAD_REG a7, 7 - LOAD_REG a8, 8 - LOAD_REG a9, 9 - LOAD_REG a10, 10 - LOAD_REG a11, 11 - LOAD_REG a12, 12 - LOAD_REG a13, 13 - LOAD_REG a14, 14 - LOAD_REG a15, 15 - LOAD_REG a2, -5 - LOAD_REG a3, -4 - wsr.epc1 a2 - wsr.exccause a3 - LOAD_REG a2, -3 - LOAD_REG a3, -2 - wsr.excvaddr a2 - wsr.excsave1 a3 - LOAD_REG a0, 0 - /* set dport nmi status bit 0 (wDev_ProcessFiq clears & verifies this bit stays cleared, - see http://esp8266-re.foogod.com/wiki/WDev_ProcessFiq_%28IoT_RTOS_SDK_0.9.9%29) */ - movi a2, 0x3ff00000 - movi a3, 0x1 - s32i a3, a2, 0 - LOAD_REG a2, 2 - LOAD_REG a3, 3 - LOAD_REG a1, 1 - rfi 0x3 + .type CallNMIExceptionHandler, @function - .type UserExceptionHandler, @function + movi a0, NMIRegisterSaved + SAVE_REG a2, 2 + SAVE_REG sp, 1 + SAVE_REG a3, 3 + rsr a2, excsave3 # a2 is now former a0 + SAVE_REG a4, 4 + SAVE_REG a2, 0 + rsr a3, epc1 + rsr a4, exccause + SAVE_REG a3, -5 + SAVE_REG a4, -4 + rsr a3, excvaddr + SAVE_REG a3, -3 + rsr a3, excsave1 + SAVE_REG a3, -2 + SAVE_REG a5, 5 + SAVE_REG a6, 6 + SAVE_REG a7, 7 + SAVE_REG a8, 8 + SAVE_REG a9, 9 + SAVE_REG a10, 10 + SAVE_REG a11, 11 + SAVE_REG a12, 12 + SAVE_REG a13, 13 + SAVE_REG a14, 14 + SAVE_REG a15, 15 + movi sp, .LNMIHandlerStackTop + movi a0, 0 + movi a2, 0x23 # argument for handler + wsr a2, ps + rsync + rsr a14, sar + s32i a14, sp, 0 # this is also NMIRegisterSaved+0 + call0 sdk_wDev_ProcessFiq + l32i a15, sp, 0 + wsr a15, sar + movi a2, 0x33 + wsr a2, ps + rsync + LOAD_REG a4, 4 + LOAD_REG a5, 5 + LOAD_REG a6, 6 + LOAD_REG a7, 7 + LOAD_REG a8, 8 + LOAD_REG a9, 9 + LOAD_REG a10, 10 + LOAD_REG a11, 11 + LOAD_REG a12, 12 + LOAD_REG a13, 13 + LOAD_REG a14, 14 + LOAD_REG a15, 15 + LOAD_REG a2, -5 + LOAD_REG a3, -4 + wsr a2, epc1 + wsr a3, exccause + LOAD_REG a2, -3 + LOAD_REG a3, -2 + wsr a2, excvaddr + wsr a3, excsave1 + LOAD_REG a0, 0 + /* set dport nmi status bit 0 (wDev_ProcessFiq clears & verifies this + * bit stays cleared, see + * http://esp8266-re.foogod.com/wiki/WDev_ProcessFiq_%28IoT_RTOS_SDK_0.9.9%29) + */ + movi a2, 0x3ff00000 + movi a3, 0x1 + s32i a3, a2, 0 + LOAD_REG a2, 2 + LOAD_REG a3, 3 + LOAD_REG a1, 1 + rfi 3 + +/*********************** General UserException Handler ***********************/ + + .section .vecbase.text, "x" + +/* Called by UserExceptionVector if EXCCAUSE is anything other than + * LoadStoreCause. */ + + .literal_position + + .balign 4 UserExceptionHandler: - xsr.excsave1 a0 # a0 now contains sp - mov sp, a0 - addi sp, sp, -0x50 - s32i a0, sp, 0x10 - rsr.ps a0 - s32i a0, sp, 0x08 - rsr.epc1 a0 - s32i a0, sp, 0x04 - rsr.excsave1 a0 - s32i a0, sp, 0x0c - movi a0, _xt_user_exit - s32i a0, sp, 0x0 - call0 sdk__xt_int_enter - movi a0, 0x23 - wsr.ps a0 - rsync - rsr.exccause a2 - beqi a2, CAUSE_LVL1INT, UserHandleInterrupt - /* Any UserException cause other than level 1 interrupt triggers a panic */ + .type UserExceptionHandler, @function + xsr a0, excsave1 # a0 now contains sp + mov sp, a0 + addi sp, sp, -0x50 + s32i a0, sp, 0x10 + rsr a0, ps + s32i a0, sp, 0x08 + rsr a0, epc1 + s32i a0, sp, 0x04 + rsr a0, excsave1 + s32i a0, sp, 0x0c + movi a0, _xt_user_exit + s32i a0, sp, 0x0 + call0 sdk__xt_int_enter + movi a0, 0x23 + wsr a0, ps + rsync + rsr a2, exccause + beqi a2, CAUSE_LVL1INT, UserHandleInterrupt + /* Any UserException cause other than level 1 interrupt should panic */ UserFailOtherExceptionCause: - break 1, 1 - call0 sdk_user_fatal_exception_handler + break 1, 1 + call0 sdk_user_fatal_exception_handler UserHandleInterrupt: - rsil a0, 1 - rsr.intenable a2 - rsr.interrupt a3 - movi a4, 0x3fff - and a2, a2, a3 - and a2, a2, a4 /* a2 = 0x3FFF & INTENABLE & INTERRUPT */ + rsil a0, 1 + rsr a2, intenable + rsr a3, interrupt + movi a4, 0x3fff + and a2, a2, a3 + and a2, a2, a4 # a2 = 0x3FFF & INTENABLE & INTERRUPT UserHandleTimer: - movi a3, 0xffbf - and a3, a2, a3 /* a3 = a2 & 0xFFBF, ie remove 0x40 from a2 if set */ - bnez a3, UserTimerDone /* bits other than 0x40 are set */ - movi a3, 0x40 - sub a12, a2, a3 /* a12 = a2 - 0x40 -- Will be zero if bit 6 set */ - call0 sdk__xt_timer_int /* tick timer interrupt */ - mov a2, a12 /* restore a2 from a12, ie zero */ - beqz a2, UserIntDone + movi a3, 0xffbf + and a3, a2, a3 # a3 = a2 with bit 6 cleared + bnez a3, UserTimerDone # If any non-timer interrupt bits set + movi a3, 0x40 + sub a12, a2, a3 # a12 = a2 - 0x40 -- Will be zero if bit 6 set + call0 sdk__xt_timer_int # tick timer interrupt + mov a2, a12 # restore a2 from a12, ie zero + beqz a2, UserIntDone UserTimerDone: - call0 _xt_isr_handler - bnez a2, UserHandleTimer + call0 _xt_isr_handler + bnez a2, UserHandleTimer UserIntDone: - beqz a2, UserIntExit - break 1, 1 /* non-zero remnant in a2 means fail */ - call0 sdk_user_fatal_exception_handler + beqz a2, UserIntExit + /* FIXME: this code will never be reached */ + break 1, 1 + call0 sdk_user_fatal_exception_handler UserIntExit: - call0 sdk__xt_int_exit /* jumps to _xt_user_exit. Never returns here */ + call0 sdk__xt_int_exit # jumps to _xt_user_exit. Never returns here -/* _xt_user_exit is used to exit interrupt context. - TODO: Find a better place for this to live. -*/ - .text - .section .text - .global _xt_user_exit - .type _xt_user_exit, @function + .section .text + +/* _xt_user_exit is used to exit interrupt context. */ +/* TODO: Find a better place for this to live. */ _xt_user_exit: - l32i a0, sp, 0x8 - wsr.ps a0 - l32i a0, sp, 0x4 - wsr.epc1 a0 - l32i a0, sp, 0xc - l32i sp, sp, 0x10 - rsync - rfe + .global _xt_user_exit + .type _xt_user_exit, @function + + l32i a0, sp, 0x8 + wsr a0, ps + l32i a0, sp, 0x4 + wsr a0, epc1 + l32i a0, sp, 0xc + l32i sp, sp, 0x10 + rsync + rfe From 1907e3c45ea9b287ec2a821cdaac04c79343fe83 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 25 Sep 2015 18:20:51 +1000 Subject: [PATCH 100/105] Remove extraneous extras/ subdirs - all merged into cpp_support now --- extras/thread/component.mk | 3 --- extras/timer/component.mk | 3 --- 2 files changed, 6 deletions(-) delete mode 100644 extras/thread/component.mk delete mode 100644 extras/timer/component.mk diff --git a/extras/thread/component.mk b/extras/thread/component.mk deleted file mode 100644 index 46193ef..0000000 --- a/extras/thread/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -# Component makefile for extras/thread - -INC_DIRS += $(ROOT)extras diff --git a/extras/timer/component.mk b/extras/timer/component.mk deleted file mode 100644 index 255ebae..0000000 --- a/extras/timer/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -# Component makefile for extras/timer - -INC_DIRS += $(ROOT)extras From 8117ae330b2175bb8c6df17ccb9e33fc7e1f5bfc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 25 Sep 2015 18:23:36 +1000 Subject: [PATCH 101/105] Add link to IRC channel --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d91cd05..c825277 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Originally based on, but substantially different from, the [Espressif IOT RTOS S Email discussion list: https://groups.google.com/d/forum/esp-open-rtos +IRC channel: #esp-open-rtos on Freenode ([Web Chat Link](http://webchat.freenode.net/?channels=%23esp-open-rtos&uio=d4)). + Github issues list/bugtracker: http://github.com/superhouse/esp-open-rtos/issues Please note that this project is released with a [Contributor Code of Conduct](https://github.com/SuperHouse/esp-open-rtos/blob/master/code_of_conduct.md). By participating in this project you agree to abide by its terms. From 99facb808e72171ae2807a3969fbd8474dd50f38 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 28 Sep 2015 13:01:13 +1000 Subject: [PATCH 102/105] hmac_test_vectors test: Replace axTLS with mbedTLS --- examples/tests/hmac_test_vectors/Makefile | 1 + .../hmac_test_vectors/hmac_test_vectors.c | 27 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/examples/tests/hmac_test_vectors/Makefile b/examples/tests/hmac_test_vectors/Makefile index ea2761a..f314ff7 100644 --- a/examples/tests/hmac_test_vectors/Makefile +++ b/examples/tests/hmac_test_vectors/Makefile @@ -1,2 +1,3 @@ PROGRAM=hmac_test +EXTRA_COMPONENTS=extras/mbedtls include ../../../common.mk diff --git a/examples/tests/hmac_test_vectors/hmac_test_vectors.c b/examples/tests/hmac_test_vectors/hmac_test_vectors.c index 426f217..a6a20f9 100644 --- a/examples/tests/hmac_test_vectors/hmac_test_vectors.c +++ b/examples/tests/hmac_test_vectors/hmac_test_vectors.c @@ -10,7 +10,7 @@ #include "espressif/esp_common.h" #include "espressif/sdk_private.h" #include "FreeRTOS.h" -#include "ssl.h" +#include "mbedtls/md.h" #include @@ -31,9 +31,7 @@ static const uint8_t aa_80_times[] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa}; -/* NOTE: Vectors 6 & 7 currently cause a fault as the axTLS - routines don't support keys longer than the block size. */ -const uint8_t NUM_MD5_VECTORS = 5; +const uint8_t NUM_MD5_VECTORS = 7; static const struct test_vector md5_vectors[] = { { /* vector 1*/ @@ -88,15 +86,30 @@ static const struct test_vector md5_vectors[] = { }, }; +static void print_blob(const char *label, const uint8_t *data, const uint32_t len) +{ + printf("%s:", label); + for(int i = 0; i < len; i++) { + if(i % 16 == 0) + printf("\n%02x:", i); + printf(" %02x", data[i]); + } +} + static void test_md5(void) { printf("\r\nTesting MD5 vectors...\r\n"); - uint8_t test_digest[16]; + + const mbedtls_md_info_t *md5_hmac = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); + for(int i = 0; i < NUM_MD5_VECTORS; i++) { const struct test_vector *vector = &md5_vectors[i]; printf("Test case %d: ", i+1); - hmac_md5(vector->data, vector->data_len, vector->key, vector->key_len, test_digest); - if(memcmp(test_digest, vector->digest, 16)) { + + uint8_t test_digest[16]; + mbedtls_md_hmac(md5_hmac, vector->key, vector->key_len, vector->data, vector->data_len, test_digest); + + if(memcmp(vector->digest, test_digest, 16)) { uint8_t first = 0; for(first = 0; first < 16; first++) { if(test_digest[first] != vector->digest[first]) { From 233e5f377a1193b803a32ed5e8a0c3c76f5cc0fd Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 28 Sep 2015 13:00:56 +1000 Subject: [PATCH 103/105] Remove axTLS --- .gitmodules | 4 - README.md | 5 +- axtls/axtls | 1 - axtls/axtls_esp_stubs.c | 33 ---- axtls/component.mk | 22 --- axtls/include/config.h | 128 --------------- axtls/include/os_int.h | 6 - axtls/include/os_port.h | 95 ------------ axtls/include/version.h | 10 -- common.mk | 2 +- examples/http_get_ssl/Makefile | 2 - examples/http_get_ssl/http_get_ssl.c | 223 --------------------------- 12 files changed, 3 insertions(+), 528 deletions(-) delete mode 160000 axtls/axtls delete mode 100644 axtls/axtls_esp_stubs.c delete mode 100644 axtls/component.mk delete mode 100644 axtls/include/config.h delete mode 100644 axtls/include/os_int.h delete mode 100644 axtls/include/os_port.h delete mode 100644 axtls/include/version.h delete mode 100644 examples/http_get_ssl/Makefile delete mode 100644 examples/http_get_ssl/http_get_ssl.c diff --git a/.gitmodules b/.gitmodules index 74c2102..8dc737e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,6 @@ [submodule "lwip/lwip"] path = lwip/lwip url = https://github.com/SuperHouse/esp-lwip.git -[submodule "axtls/axtls"] - path = axtls/axtls - url = https://github.com/SuperHouse/axtls.git - [submodule "extras/mbedtls/mbedtls"] path = extras/mbedtls/mbedtls url = https://github.com/ARMmbed/mbedtls.git diff --git a/README.md b/README.md index d91cd05..5b8f64f 100644 --- a/README.md +++ b/README.md @@ -71,14 +71,13 @@ Current status is alpha quality, actively developed. AP STATION mode (ie wifi cl - rboot-ota - OTA support (over-the-air updates) including a TFTP server for receiving updates ([for rboot by @raburton](http://richard.burtons.org/2015/05/18/rboot-a-new-boot-loader-for-esp8266/)) - bmp180 driver for digital pressure sensor ([upstream project](https://github.com/Angus71/esp-open-rtos-driver-bmp180)) * `FreeRTOS` contains FreeRTOS implementation, subdirectory structure is the standard FreeRTOS structure. `FreeRTOS/source/portable/esp8266/` contains the ESP8266 port. -* `lwip` and `axtls` contain the lwIP TCP/IP library and the axTLS TLS library ('libssl' in the esp8266 SDKs), respectively. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details. +* `lwip` contains the lwIP TCP/IP library. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details. * `libc` contains the newlib libc. [Libc details here](https://github.com/SuperHouse/esp-open-rtos/wiki/libc-configuration). ## Open Source Components * [FreeRTOS](http://freertos.org) V7.5.2 * [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v1.4.1, modified via the [esp-lwip project](https://github.com/kadamski/esp-lwip) by @kadamski. -* [axTLS](http://axtls.sourceforge.net/) compiled from development version v1.5.3, plus modifications for low memory devices. * [newlib](https://github.com/projectgus/newlib-xtensa) v2.2.0, with patches for xtensa support and locking stubs for thread-safe operation on FreeRTOS. For details of how third party libraries are integrated, [see the wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries). @@ -96,7 +95,7 @@ Some binary libraries appear to contain unattributed open source code: ## Licensing -* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki), and [axTLS](http://axtls.sourceforge.net/). lwIP is Copyright (C) Swedish Institute of Computer Science. axTLS is Copyright (C) Cameron Rich. +* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki). lwIP is Copyright (C) Swedish Institute of Computer Science. * FreeRTOS is provided under the GPL with the FreeRTOS linking exception, allowing non-GPL firmwares to be produced using FreeRTOS as the RTOS core. License details in files under FreeRTOS dir. FreeRTOS is Copyright (C) Real Time Engineers Ltd. diff --git a/axtls/axtls b/axtls/axtls deleted file mode 160000 index a4860ef..0000000 --- a/axtls/axtls +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a4860ef68d7f5d98a8731f99787d51cc44c433c9 diff --git a/axtls/axtls_esp_stubs.c b/axtls/axtls_esp_stubs.c deleted file mode 100644 index 3182594..0000000 --- a/axtls/axtls_esp_stubs.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Stub time-related functions for TLS time-related operations - * - * ESPTODO: Revisit these ASAP as gettimeofday() is used for entropy - * - * Part of esp-open-rtos - * Copyright (C) 2015 Superhouse Automation Pty Ltd - * BSD Licensed as described in the file LICENSE - */ -#include -#include -#include - -time_t time(time_t *t) -{ - return 0; -} - -time_t mktime(struct tm *tm) -{ - return 0; -} - -int gettimeofday(struct timeval *tv, void *tz) -{ - return 0; -} - -void abort(void) -{ - printf("abort() was called.\r\n"); - while(1) {} -} diff --git a/axtls/component.mk b/axtls/component.mk deleted file mode 100644 index 73859a2..0000000 --- a/axtls/component.mk +++ /dev/null @@ -1,22 +0,0 @@ -# Component makefile for axTLS - -# axTLS has its own configure and build system, but it's not particularly -# designed for embedded systems. For now we're just imposing the ESP Open RTOS -# build system over the top. - -# We supply our own hand tweaked config.h in the external 'include' dir. - -AXTLS_DIR = $(axtls_ROOT)axtls/ -INC_DIRS += $(axtls_ROOT)include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto - -# args for passing into compile rule generation -axtls_INC_DIR = $(AXTLS_DIR)include $(AXTLS_DIR) -axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(axtls_ROOT) - -#axtls_CFLAGS = $(CFLAGS) -Wno-address - -$(eval $(call component_compile_rules,axtls)) - -# Helpful error if git submodule not initialised -$(axtls_SRC_DIR): - $(error "axtls git submodule not installed. Please run 'git submodule init' then 'git submodule update'") diff --git a/axtls/include/config.h b/axtls/include/config.h deleted file mode 100644 index 175d083..0000000 --- a/axtls/include/config.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Automatically generated header file: don't edit - */ -#define HAVE_DOT_CONFIG 0 -#undef CONFIG_PLATFORM_LINUX -#undef CONFIG_PLATFORM_CYGWIN -#undef CONFIG_PLATFORM_WIN32 - -/* - * General Configuration - */ -#define PREFIX "/usr/local" -#define CROSS "xtensa-lx106-elf-" -#undef CONFIG_DEBUG -#define CONFIG_STRIP_UNWANTED_SECTIONS 1 -#undef CONFIG_VISUAL_STUDIO_7_0 -#undef CONFIG_VISUAL_STUDIO_8_0 -#undef CONFIG_VISUAL_STUDIO_10_0 -#define CONFIG_VISUAL_STUDIO_7_0_BASE "" -#define CONFIG_VISUAL_STUDIO_8_0_BASE "" -#define CONFIG_VISUAL_STUDIO_10_0_BASE "" -#define CONFIG_EXTRA_CFLAGS_OPTIONS "" -#define CONFIG_EXTRA_LDFLAGS_OPTIONS "" - -/* - * Embedded System Options (added for ESP RTOS SDK, don't have config entries yetr) - */ -#define CONFIG_NO_FILESYSTEM 1 -#define CONFIG_USE_RAND 1 -#define CONFIG_MAX_PLAIN_LENGTH 1024 -#define CONFIG_MAX_KEY_BYTE_SIZE 256 /* for max 2048 bit keys (untested with >1024 bit keys) */ - -/* - * SSL Library - */ -#undef CONFIG_SSL_SERVER_ONLY -#undef CONFIG_SSL_CERT_VERIFICATION -#define CONFIG_SSL_ENABLE_CLIENT 1 -#undef CONFIG_SSL_FULL_MODE -#undef CONFIG_SSL_SKELETON_MODE -#undef CONFIG_SSL_PROT_LOW -#define CONFIG_SSL_PROT_MEDIUM 1 -#undef CONFIG_SSL_PROT_HIGH -#undef CONFIG_SSL_USE_DEFAULT_KEY -#define CONFIG_SSL_PRIVATE_KEY_LOCATION "" -#define CONFIG_SSL_PRIVATE_KEY_PASSWORD "" -#define CONFIG_SSL_X509_CERT_LOCATION "" -#undef CONFIG_SSL_GENERATE_X509_CERT -#define CONFIG_SSL_X509_COMMON_NAME "" -#define CONFIG_SSL_X509_ORGANIZATION_NAME "" -#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME "" -#undef CONFIG_SSL_ENABLE_V23_HANDSHAKE -#undef CONFIG_SSL_HAS_PEM -#undef CONFIG_SSL_USE_PKCS12 -#define CONFIG_SSL_EXPIRY_TIME 24 -#define CONFIG_X509_MAX_CA_CERTS 1 -#define CONFIG_SSL_MAX_CERTS 3 -#undef CONFIG_SSL_CTX_MUTEXING -#undef CONFIG_USE_DEV_URANDOM -#undef CONFIG_WIN32_USE_CRYPTO_LIB -#undef CONFIG_OPENSSL_COMPATIBLE -#undef CONFIG_PERFORMANCE_TESTING -#undef CONFIG_SSL_TEST -#undef CONFIG_AXTLSWRAP -#undef CONFIG_AXHTTPD -#undef CONFIG_HTTP_STATIC_BUILD -#define CONFIG_HTTP_PORT -#define CONFIG_HTTP_HTTPS_PORT -#define CONFIG_HTTP_SESSION_CACHE_SIZE -#define CONFIG_HTTP_WEBROOT "" -#define CONFIG_HTTP_TIMEOUT -#undef CONFIG_HTTP_HAS_CGI -#define CONFIG_HTTP_CGI_EXTENSIONS "" -#undef CONFIG_HTTP_ENABLE_LUA -#define CONFIG_HTTP_LUA_PREFIX "" -#undef CONFIG_HTTP_BUILD_LUA -#define CONFIG_HTTP_CGI_LAUNCHER "" -#undef CONFIG_HTTP_DIRECTORIES -#undef CONFIG_HTTP_HAS_AUTHORIZATION -#undef CONFIG_HTTP_HAS_IPV6 -#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER -#define CONFIG_HTTP_USER "" -#undef CONFIG_HTTP_VERBOSE -#undef CONFIG_HTTP_IS_DAEMON - -/* - * Language Bindings - */ -#undef CONFIG_BINDINGS -#undef CONFIG_CSHARP_BINDINGS -#undef CONFIG_VBNET_BINDINGS -#define CONFIG_DOT_NET_FRAMEWORK_BASE "" -#undef CONFIG_JAVA_BINDINGS -#define CONFIG_JAVA_HOME "" -#undef CONFIG_PERL_BINDINGS -#define CONFIG_PERL_CORE "" -#define CONFIG_PERL_LIB "" -#undef CONFIG_LUA_BINDINGS -#define CONFIG_LUA_CORE "" - -/* - * Samples - */ -#undef CONFIG_SAMPLES -#undef CONFIG_C_SAMPLES -#undef CONFIG_CSHARP_SAMPLES -#undef CONFIG_VBNET_SAMPLES -#undef CONFIG_JAVA_SAMPLES -#undef CONFIG_PERL_SAMPLES -#undef CONFIG_LUA_SAMPLES - -/* - * BigInt Options - */ -#undef CONFIG_BIGINT_CLASSICAL -#undef CONFIG_BIGINT_MONTGOMERY -#define CONFIG_BIGINT_BARRETT 1 -#define CONFIG_BIGINT_CRT 1 -#undef CONFIG_BIGINT_KARATSUBA -#define MUL_KARATSUBA_THRESH -#define SQU_KARATSUBA_THRESH -#define CONFIG_BIGINT_SLIDING_WINDOW 1 -#define CONFIG_BIGINT_SQUARE 1 -#define CONFIG_BIGINT_CHECK_ON 1 -#define CONFIG_INTEGER_32BIT 1 -#undef CONFIG_INTEGER_16BIT -#undef CONFIG_INTEGER_8BIT - diff --git a/axtls/include/os_int.h b/axtls/include/os_int.h deleted file mode 100644 index 3fc09cd..0000000 --- a/axtls/include/os_int.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _OS_INT_H -#define _OS_INT_H - -#include - -#endif diff --git a/axtls/include/os_port.h b/axtls/include/os_port.h deleted file mode 100644 index 67fc3db..0000000 --- a/axtls/include/os_port.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2007-2015, Cameron Rich - * Modifications Copyright (c) 2015 Superhouse Automation Pty Ltd - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file os_port.h - * - * Some stuff to minimise the differences between windows and linux/unix - */ - -#ifndef _HEADER_OS_PORT_H -#define _HEADER_OS_PORT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "FreeRTOS.h" -#include "os_int.h" -#include "config.h" -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_SSL_CTX_MUTEXING) -#include "semphr.h" -#endif - -#define SOCKET_READ(A,B,C) read(A,B,C) -#define SOCKET_WRITE(A,B,C) write(A,B,C) -#define SOCKET_CLOSE(A) if (A >= 0) close(A) -#define TTY_FLUSH() - -static inline uint64_t be64toh(uint64_t x) { - return ntohl(x>>32) | ((uint64_t)(ntohl(x)) << 32); -} - -void exit_now(const char *format, ...) __attribute((noreturn)); - -#define EXP_FUNC -#define STDCALL - -/* Mutex definitions */ -#if defined(CONFIG_SSL_CTX_MUTEXING) -#define SSL_CTX_MUTEX_TYPE xSemaphoreHandle -#define SSL_CTX_MUTEX_INIT(A) vSemaphoreCreateBinaryCreateMutex(A) -#define SSL_CTX_MUTEX_DESTROY(A) vSemaphoreDelete(A) -#define SSL_CTX_LOCK(A) xSemaphoreTakeRecursive(A, portMAX_DELAY) -#define SSL_CTX_UNLOCK(A) xSemaphoreGiveRecursive(A) -#else -#define SSL_CTX_MUTEX_TYPE -#define SSL_CTX_MUTEX_INIT(A) -#define SSL_CTX_MUTEX_DESTROY(A) -#define SSL_CTX_LOCK(A) -#define SSL_CTX_UNLOCK(A) -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/axtls/include/version.h b/axtls/include/version.h deleted file mode 100644 index 8fee21b..0000000 --- a/axtls/include/version.h +++ /dev/null @@ -1,10 +0,0 @@ -/* axTLS version header - - We need this because we're using axTLS from source repo, not from a release. -*/ - -#ifndef _VERSION_H - -#define AXTLS_VERSION "esp-open-rtos axTLS " GITSHORTREV - -#endif diff --git a/common.mk b/common.mk index 0f07811..7b236fb 100644 --- a/common.mk +++ b/common.mk @@ -80,7 +80,7 @@ OBJDUMP = $(CROSS)objdump # Source components to compile and link. Each of these are subdirectories # of the root, with a 'component.mk' file. -COMPONENTS ?= $(EXTRA_COMPONENTS) FreeRTOS lwip axtls core +COMPONENTS ?= $(EXTRA_COMPONENTS) FreeRTOS lwip core # binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking. SDK_LIBS ?= main net80211 phy pp wpa diff --git a/examples/http_get_ssl/Makefile b/examples/http_get_ssl/Makefile deleted file mode 100644 index fe64c2c..0000000 --- a/examples/http_get_ssl/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -PROGRAM=http_get_ssl -include ../../common.mk diff --git a/examples/http_get_ssl/http_get_ssl.c b/examples/http_get_ssl/http_get_ssl.c deleted file mode 100644 index 22351b9..0000000 --- a/examples/http_get_ssl/http_get_ssl.c +++ /dev/null @@ -1,223 +0,0 @@ -/* http_get_ssl - HTTPS version of the http_get example. - * - * Retrieves a web page over HTTPS (TLS) using GET. - * - * Does not validate server certificate. - * - * This sample code is in the public domain., - */ -#include "espressif/esp_common.h" -#include "espressif/sdk_private.h" - -#include - -#include "FreeRTOS.h" -#include "task.h" - -#include "lwip/err.h" -#include "lwip/sockets.h" -#include "lwip/sys.h" -#include "lwip/netdb.h" -#include "lwip/dns.h" - -#include "ssl.h" - -#include "ssid_config.h" - -#define WEB_SERVER "192.168.0.18" -#define WEB_PORT "8000" -#define WEB_URL "/test" - -static void display_cipher(SSL *ssl); -static void display_session_id(SSL *ssl); - -void http_get_task(void *pvParameters) -{ - int successes = 0, failures = 0; - SSL_CTX *ssl_ctx; - uint32_t options = SSL_SERVER_VERIFY_LATER|SSL_DISPLAY_CERTS; - printf("HTTP get task starting...\r\n"); - - printf("free heap = %u\r\n", xPortGetFreeHeapSize()); - if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) - { - printf("Error: SSL Client context is invalid\n"); - while(1) {} - } - printf("Got SSL context."); - - while(1) { - const struct addrinfo hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM, - }; - struct addrinfo *res; - - printf("top of loop, free heap = %u\r\n", xPortGetFreeHeapSize()); - - printf("Running DNS lookup for %s...\r\n", WEB_SERVER); - int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res); - - if(err != 0 || res == NULL) { - printf("DNS lookup failed err=%d res=%p\r\n", err, res); - if(res) - freeaddrinfo(res); - vTaskDelay(1000 / portTICK_RATE_MS); - failures++; - continue; - } - /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ - struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; - printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(*addr)); - - int s = socket(res->ai_family, res->ai_socktype, 0); - if(s < 0) { - printf("... Failed to allocate socket.\r\n"); - freeaddrinfo(res); - vTaskDelay(1000 / portTICK_RATE_MS); - failures++; - continue; - } - - printf("... allocated socket\r\n"); - - if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { - close(s); - freeaddrinfo(res); - printf("... socket connect failed.\r\n"); - vTaskDelay(4000 / portTICK_RATE_MS); - failures++; - continue; - } - - printf("... connected. starting TLS session...\r\n"); - freeaddrinfo(res); - - SSL *ssl = ssl_client_new(ssl_ctx, s, NULL, 0); - printf("initial status %p %d\r\n", ssl, ssl_handshake_status(ssl)); - if((err = ssl_handshake_status(ssl)) != SSL_OK) { - ssl_free(ssl); - close(s); - printf("SSL handshake failed. :( %d\r\n", err); - vTaskDelay(4000 / portTICK_RATE_MS); - failures++; - continue; - } - - const char *common_name = ssl_get_cert_dn(ssl, - SSL_X509_CERT_COMMON_NAME); - if (common_name) - { - printf("Common Name:\t\t\t%s\n", common_name); - } - - display_session_id(ssl); - display_cipher(ssl); - - const char *req = - "GET "WEB_URL"\r\n" - "User-Agent: esp-open-rtos/0.1 esp8266\r\n" - "\r\n"; - if (ssl_write(ssl, (uint8_t *)req, strlen(req)) < 0) { - printf("... socket send failed\r\n"); - ssl_free(ssl); - close(s); - vTaskDelay(4000 / portTICK_RATE_MS); - failures++; - continue; - } - printf("... socket send success\r\n"); - - uint8_t *recv_buf; - int r; - do { - r = ssl_read(ssl, &recv_buf); - for(int i = 0; i < r; i++) - printf("%c", recv_buf[i]); - } while(r > 0); - - printf("... done reading from socket. Last read return=%d errno=%d\r\n", r, errno); - if(r != 0) - failures++; - else - successes++; - ssl_free(ssl); - close(s); - printf("successes = %d failures = %d\r\n", successes, failures); - for(int countdown = 10; countdown >= 0; countdown--) { - printf("%d... ", countdown); - vTaskDelay(1000 / portTICK_RATE_MS); - } - printf("\r\nStarting again!\r\n"); - } -} - -void user_init(void) -{ - sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); - printf("SDK version:%s\n", sdk_system_get_sdk_version()); - - struct sdk_station_config config = { - .ssid = WIFI_SSID, - .password = WIFI_PASS, - }; - - /* required to call wifi_set_opmode before station_set_config */ - sdk_wifi_set_opmode(STATION_MODE); - sdk_wifi_station_set_config(&config); - - xTaskCreate(&http_get_task, (signed char *)"get_task", 2048, NULL, 2, NULL); -} - -/** - * Display what session id we have. - */ -static void display_session_id(SSL *ssl) -{ - int i; - const uint8_t *session_id = ssl_get_session_id(ssl); - int sess_id_size = ssl_get_session_id_size(ssl); - - if (sess_id_size > 0) - { - printf("-----BEGIN SSL SESSION PARAMETERS-----\n"); - for (i = 0; i < sess_id_size; i++) - { - printf("%02x", session_id[i]); - } - - printf("\n-----END SSL SESSION PARAMETERS-----\n"); - } -} - -/** - * Display what cipher we are using - */ -static void display_cipher(SSL *ssl) -{ - printf("CIPHER is "); - switch (ssl_get_cipher_id(ssl)) - { - case SSL_AES128_SHA: - printf("AES128-SHA"); - break; - - case SSL_AES256_SHA: - printf("AES256-SHA"); - break; - - case SSL_RC4_128_SHA: - printf("RC4-SHA"); - break; - - case SSL_RC4_128_MD5: - printf("RC4-MD5"); - break; - - default: - printf("Unknown - %d", ssl_get_cipher_id(ssl)); - break; - } - - printf("\n"); -} From 0f960f0b2c8b20cdf097f5c366241dc696b937ee Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 28 Sep 2015 13:09:07 +1000 Subject: [PATCH 104/105] Update README regarding mbedTLS --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 5b8f64f..a202dbd 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ Current status is alpha quality, actively developed. AP STATION mode (ie wifi cl * `include` contains header files from Espressif RTOS SDK, relating to the binary libraries & Xtensa core. * `core` contains source & headers for low-level ESP8266 functions & peripherals. `core/include/esp` contains useful headers for peripheral access, etc. Minimal to no FreeRTOS dependencies. * `extras` is a directory that contains optional components that can be added to your project. Most 'extras' components will have a corresponding example in the `examples` directory. Extras include: + - mbedtls - [mbedTLS](https://tls.mbed.org/) is a TLS/SSL library providing up to date secure connectivity and encryption support. - i2c - software i2c driver ([upstream project](https://github.com/kanflo/esp-open-rtos-driver-i2c)) - rboot-ota - OTA support (over-the-air updates) including a TFTP server for receiving updates ([for rboot by @raburton](http://richard.burtons.org/2015/05/18/rboot-a-new-boot-loader-for-esp8266/)) - bmp180 driver for digital pressure sensor ([upstream project](https://github.com/Angus71/esp-open-rtos-driver-bmp180)) @@ -88,6 +89,8 @@ Binary libraries (inside the `lib` dir) are all supplied by Espressif as part of As part of the esp-open-rtos build process, all binary SDK symbols are prefixed with `sdk_`. This makes it easier to differentiate binary & open source code, and also prevents namespace conflicts. +Espressif's RTOS SDK provided a "libssl" based on axTLS. This has been replaced with the more up to date mbedTLS library (see below). + Some binary libraries appear to contain unattributed open source code: * libnet80211.a & libwpa.a appear to be based on FreeBSD net80211/wpa, or forks of them. ([See this issue](https://github.com/SuperHouse/esp-open-rtos/issues/4)). @@ -103,6 +106,8 @@ Some binary libraries appear to contain unattributed open source code: * Newlib is covered by several copyrights and licenses, as per the files in the `libc` directory. +* [mbedTLS](https://tls.mbed.org/) is provided under the Apache 2.0 license as described in the file extras/mbedtls/mbedtls/apache-2.0.txt. mbedTLS is Copyright (C) ARM Limited. + Components under `extras/` may contain different licenses, please see those directories for details. ## Contributions From afd58bc1ffb1aa9cf2f030d05d7491906925c3e6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 5 Oct 2015 18:33:32 +1100 Subject: [PATCH 105/105] core headers: Add C++ linker compatibility --- core/include/esp/hwrand.h | 8 ++++++++ core/include/esp/iomux.h | 8 ++++++++ core/include/esp/rom.h | 9 ++++++++- core/include/esp/timer.h | 8 ++++++++ core/include/esp/timer_private.h | 8 +++++++- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/core/include/esp/hwrand.h b/core/include/esp/hwrand.h index 8ec75e1..95143db 100644 --- a/core/include/esp/hwrand.h +++ b/core/include/esp/hwrand.h @@ -13,10 +13,18 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Return a random 32-bit number */ uint32_t hwrand(void); /* Fill a variable size buffer with data from the Hardware RNG */ void hwrand_fill(uint8_t *buf, size_t len); +#ifdef __cplusplus +} +#endif + #endif diff --git a/core/include/esp/iomux.h b/core/include/esp/iomux.h index f6715f4..a893f4e 100644 --- a/core/include/esp/iomux.h +++ b/core/include/esp/iomux.h @@ -11,6 +11,10 @@ #include "esp/types.h" #include "esp/iomux_regs.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Convert a GPIO pin number to an iomux register index. * @@ -64,4 +68,8 @@ inline static void iomux_set_gpio_function(const uint8_t gpio_number, const uint declared above */ #include "esp/iomux_private.h" +#ifdef __cplusplus +} +#endif + #endif diff --git a/core/include/esp/rom.h b/core/include/esp/rom.h index 0fbf4bd..c2f8759 100644 --- a/core/include/esp/rom.h +++ b/core/include/esp/rom.h @@ -5,9 +5,12 @@ */ #ifndef _ESP_ROM_H #define _ESP_ROM_H - #include +#ifdef __cplusplus +extern "C" { +#endif + void Cache_Read_Disable(void); /* http://esp8266-re.foogod.com/wiki/Cache_Read_Enable @@ -18,4 +21,8 @@ void Cache_Read_Disable(void); */ void Cache_Read_Enable(uint32_t odd_even, uint32_t mb_count, uint32_t no_idea); +#ifdef __cplusplus +} +#endif + #endif diff --git a/core/include/esp/timer.h b/core/include/esp/timer.h index b83a0ee..0fb27ef 100644 --- a/core/include/esp/timer.h +++ b/core/include/esp/timer.h @@ -14,6 +14,10 @@ #include "esp/timer_regs.h" #include "esp/cpu.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { FRC1 = 0, FRC2 = 1, @@ -129,4 +133,8 @@ INLINED bool timer_set_timeout(const timer_frc_t frc, uint32_t us); #include "timer_private.h" +#ifdef __cplusplus +} +#endif + #endif diff --git a/core/include/esp/timer_private.h b/core/include/esp/timer_private.h index a5fc246..e57fd24 100644 --- a/core/include/esp/timer_private.h +++ b/core/include/esp/timer_private.h @@ -7,6 +7,10 @@ #ifndef _ESP_TIMER_PRIVATE_H #define _ESP_TIMER_PRIVATE_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include #include @@ -255,6 +259,8 @@ INLINED bool timer_set_timeout(const timer_frc_t frc, uint32_t us) return _timer_set_timeout_runtime(frc, us); } - +#ifdef __cplusplus +} +#endif #endif

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 Fs)sTi8=U|E delta 366027 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 z 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 g|JcMC1t%xQif@m(%}MeZ?o3 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