diff --git a/components/esp8266/component.mk b/components/esp8266/component.mk index b4c12229..30b35609 100644 --- a/components/esp8266/component.mk +++ b/components/esp8266/component.mk @@ -7,7 +7,7 @@ COMPONENT_SRCDIRS := driver source LIBS ?= ifndef CONFIG_NO_BLOBS -LIBS += airkiss cirom crypto espnow gcc hal core mirom net80211 \ +LIBS += airkiss crypto espnow gcc hal core net80211 \ phy pp pwm smartconfig ssc wpa wps endif diff --git a/components/esp8266/include/c_types.h b/components/esp8266/include/c_types.h index 78934168..54ee4c21 100644 --- a/components/esp8266/include/c_types.h +++ b/components/esp8266/include/c_types.h @@ -86,7 +86,6 @@ typedef enum { #define REG_SET_BIT(_r, _b) (*(volatile uint32 *)(_r) |= (_b)) #define REG_CLR_BIT(_r, _b) (*(volatile uint32 *)(_r) &= ~(_b)) -#define __packed __attribute__((packed)) #define STORE_ATTR __attribute__((aligned(4))) #define SHMEM_ATTR diff --git a/components/esp8266/ld/eagle.rom.addr.v6.ld b/components/esp8266/ld/eagle.rom.addr.v6.ld index 6f05cc72..4fc9d36f 100644 --- a/components/esp8266/ld/eagle.rom.addr.v6.ld +++ b/components/esp8266/ld/eagle.rom.addr.v6.ld @@ -55,4 +55,6 @@ PROVIDE ( strstr = 0x4000e1e0 ); PROVIDE ( gpio_input_get = 0x40004cf0 ); PROVIDE ( gpio_pin_wakeup_disable = 0x40004ed4 ); -PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 ); \ No newline at end of file +PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 ); + +PROVIDE ( ets_printf = 0x400024cc ); \ No newline at end of file diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index e04139ca..3956705b 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,9 +1,9 @@ gwen: crypto: 5fc5b4f espnow: 5fc5b4f - core: 06675a3 + core: 0b78c0f minic: 5fc5b4f - net80211: 06675a3 + net80211: 0b78c0f pp: 06675a3 pwm: 5fc5b4f smartconfig:9ec59b5 diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a old mode 100755 new mode 100644 index 8ce0e1d8..dfc2ad5d Binary files a/components/esp8266/lib/libcore.a and b/components/esp8266/lib/libcore.a differ diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index 5bf1f109..a3477c0d 100644 Binary files a/components/esp8266/lib/libnet80211.a and b/components/esp8266/lib/libnet80211.a differ diff --git a/components/esp8266/source/esp_wifi_os_adapter.c b/components/esp8266/source/esp_wifi_os_adapter.c index 561b10f9..1f429232 100644 --- a/components/esp8266/source/esp_wifi_os_adapter.c +++ b/components/esp8266/source/esp_wifi_os_adapter.c @@ -21,6 +21,10 @@ #include "freertos/semphr.h" #include "freertos/timers.h" +#if defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL) || defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NANO) +#include "esp_newlib.h" +#endif + static uint32_t enter_critical_wrapper(void) { taskENTER_CRITICAL(); @@ -90,7 +94,9 @@ static void task_resume_all_wrapper(void) static void os_init_wrapper(void) { - /* empty function */ +#if defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL) || defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NANO) + esp_newlib_init(); +#endif } static void os_start_wrapper(void) diff --git a/components/freertos/include/port/freertos/FreeRTOSConfig.h b/components/freertos/include/port/freertos/FreeRTOSConfig.h index 93d005b6..ca9b8c26 100644 --- a/components/freertos/include/port/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/port/freertos/FreeRTOSConfig.h @@ -142,6 +142,8 @@ configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest NVIC value of 255. */ #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 +// add it to menuconfig later +#define CONFIG_FREERTOS_ENABLE_REENT #ifdef CONFIG_FREERTOS_ENABLE_REENT #define configUSE_NEWLIB_REENTRANT 1 #endif diff --git a/components/freertos/include/port/freertos/portmacro.h b/components/freertos/include/port/freertos/portmacro.h index 9c60a8fd..222a6952 100644 --- a/components/freertos/include/port/freertos/portmacro.h +++ b/components/freertos/include/port/freertos/portmacro.h @@ -77,6 +77,17 @@ extern "C" { #include #include "xtensa_rtos.h" +#if defined(configUSE_NEWLIB_REENTRANT) && configUSE_NEWLIB_REENTRANT == 1 +#if defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL) || defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NANO) +#include "esp_newlib.h" + +#define _impure_ptr _global_impure_ptr + +#undef _REENT_INIT_PTR +#define _REENT_INIT_PTR(p) esp_reent_init(p) +#endif +#endif + /*----------------------------------------------------------- * Port specific definitions. * diff --git a/components/freertos/port/impure.c b/components/freertos/port/impure.c new file mode 100644 index 00000000..44e511db --- /dev/null +++ b/components/freertos/port/impure.c @@ -0,0 +1,44 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +static struct _reent impure_data; +struct _reent *_global_impure_ptr = &impure_data; + +struct _reent *__getreent() +{ + extern char _xt_isr_status; + + /* + * Locking mutex(only mutex, not ISR mutex) at the following three + * state may cause OS death. So we use a extra _reent data instead + * of task private reent data. + * + * But although at the state none of "taskSCHEDULER_RUNNING", exception + * can cause CPU swicth context, then Locking mutex may cause OS death. + * So we command that use ets_printf(ROM function) instead of "printf" + * at exception and system kernal critical state. + */ + if (_xt_isr_status + || !xTaskGetCurrentTaskHandle() + || xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) + return &impure_data; + + /* + * When scheduler starts, _global_impure_ptr = pxCurrentTCB->xNewLib_reent. + */ + return _global_impure_ptr; +} diff --git a/components/newlib/component.mk b/components/newlib/component.mk index 8f87cc2b..d3110c83 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -12,7 +12,7 @@ LIBC_PATH := $(COMPONENT_PATH)/newlib/lib/libc.a LIBM_PATH := $(COMPONENT_PATH)/newlib/lib/libm.a ADD_NEW_NEWLIB := 1 else -ifdef NEWLIB_LIBRARY_LEVEL_NANO +ifdef CONFIG_NEWLIB_LIBRARY_LEVEL_NANO LIBC_PATH := $(COMPONENT_PATH)/newlib/lib/libc_nano.a LIBM_PATH := $(COMPONENT_PATH)/newlib/lib/libm.a ADD_NEW_NEWLIB := 1 @@ -20,7 +20,8 @@ endif endif ifeq ($(ADD_NEW_NEWLIB),1) -COMPONENT_ADD_INCLUDEDIRS += newlib/include +COMPONENT_ADD_INCLUDEDIRS += newlib/include newlib/port/include +COMPONENT_SRCDIRS += newlib/port COMPONENT_ADD_LDFLAGS := $(LIBC_PATH) $(LIBM_PATH) -lnewlib COMPONENT_ADD_LINKER_DEPS := $(LIBC_PATH) $(LIBM_PATH) endif diff --git a/components/newlib/newlib/port/esp_newlib.c b/components/newlib/newlib/port/esp_newlib.c new file mode 100644 index 00000000..f93e32cf --- /dev/null +++ b/components/newlib/newlib/port/esp_newlib.c @@ -0,0 +1,77 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include + +/* + * @brief Initialize global and thread's private reent object data. We add this instead of + * newlib's initialization function to avoid some unnecessary cost and unused function. + */ +void esp_reent_init(struct _reent* r) +{ + extern void _cleanup(struct _reent *r); + + memset(r, 0, sizeof(*r)); + + r->_stdout = _GLOBAL_REENT->_stdout; + r->_stderr = _GLOBAL_REENT->_stderr; + r->_stdin = _GLOBAL_REENT->_stdin; + + r->__cleanup = _cleanup; + r->__sglue._next = NULL; + r->__sglue._niobs = 0; + r->__sglue._iobs = NULL; + r->_current_locale = "C"; + r->__sdidinit = 1; +} + +/* + * @brief Initialize newlib's platform object data + */ +int esp_newlib_init(void) +{ + esp_reent_init(_global_impure_ptr); + + _GLOBAL_REENT->_stdout = fopen("uart/0", "w"); + if (!_GLOBAL_REENT->_stdout) + goto err; + + _GLOBAL_REENT->_stderr = fopen("uart/0", "w"); + if (!_GLOBAL_REENT->_stderr) + goto err_fail; + + _GLOBAL_REENT->_stdin = fopen("uart/0", "r"); + if (!_GLOBAL_REENT->_stdin) + goto err_in; + + environ = malloc(sizeof(char*)); + if (!environ) + goto environ_in; + environ[0] = NULL; + + return 0; + +environ_in: + fclose(_GLOBAL_REENT->_stdin); +err_in: + fclose(_GLOBAL_REENT->_stderr); +err_fail: + fclose(_GLOBAL_REENT->_stdout); +err: + return -1; +} diff --git a/components/newlib/newlib/port/fputc.c b/components/newlib/newlib/port/fputc.c new file mode 100644 index 00000000..a5fada9a --- /dev/null +++ b/components/newlib/newlib/port/fputc.c @@ -0,0 +1,26 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <_ansi.h> +#include + +int _fputc_r(struct _reent *ptr, int ch, FILE *fp) +{ + return fp->_write(ptr, fp->_cookie, (char *)&ch, 1); +} + +int fputc(int ch, FILE *fp) +{ + return _fputc_r (_REENT, ch, fp); +} diff --git a/components/newlib/newlib/port/include/esp_newlib.h b/components/newlib/newlib/port/include/esp_newlib.h new file mode 100644 index 00000000..3fa555f2 --- /dev/null +++ b/components/newlib/newlib/port/include/esp_newlib.h @@ -0,0 +1,39 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_NEWLIB_H +#define _ESP_NEWLIB_H + +#include + +/* + * @brief Initialize global and thread's private reent object data. We add this instead of + * newlib's initialization function to avoid some unnecessary cost and unused function. + * + * @param r reent pointer + * + * @return none + */ +void esp_reent_init(struct _reent* r); + +/* + * @brief Initialize newlib's platform object data + * + * @param none + * + * @return 0 if successful or -1 if failed + */ +int esp_newlib_init(void); + +#endif diff --git a/components/newlib/newlib/port/syscall.c b/components/newlib/newlib/port/syscall.c new file mode 100644 index 00000000..23b9b67e --- /dev/null +++ b/components/newlib/newlib/port/syscall.c @@ -0,0 +1,123 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "c_types.h" + +#include "esp8266/ets_sys.h" +#include "esp8266/eagle_soc.h" +#include "esp8266/uart_register.h" + +#define PANIC_UART 0 + +static inline void panit_putc(char c) +{ + while (1) { + uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(PANIC_UART)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); + + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) + break; + } + + WRITE_PERI_REG(UART_FIFO(PANIC_UART) , c); +} + +int _open_r(struct _reent *r, const char *filename, int flags, int mode) +{ + return 0; +} + +int _read_r(struct _reent *r, int fd, void *buf, int len) +{ + return 0; +} + +int _write_r(struct _reent *r, int fd, void *buf, int len) +{ + int i; + const char *cbuf = buf; + + for (i = 0; i < len; i++) + panit_putc(cbuf[i]); + + return len; +} + +_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence) +{ + return 0; +} + +int _close_r(struct _reent *r, int fd) +{ + return 0; +} + +int _rename_r(struct _reent *r, const char *from, const char *to) +{ + return 0; +} + +int _unlink_r(struct _reent *r, const char *filename) +{ + return 0; +} + +int _fstat_r(struct _reent *r, int fd, struct stat *s) +{ + return 0; +} + +void _sbrk_r(void *ptr, int incr) +{ + return ; +} + +void *_malloc_r(struct _reent *r, size_t n) +{ + return pvPortMalloc(n); +} + +void *_realloc_r(struct _reent *r, void *old_ptr, size_t n) +{ + void *p = pvPortMalloc(n); + if (p && old_ptr) { + memcpy(p, old_ptr, n); + vPortFree(old_ptr); + } + + return p; +} + +void *_calloc_r(struct _reent *r, size_t c, size_t s) +{ + char *p = pvPortMalloc(c * s); + if (p) + memset(p, 0, c * s); + + return p; +} + +void *_free_r(struct _reent *r, void *ptr) +{ + vPortFree(ptr); +} + +void _exit(int status) +{ + while (1); +} diff --git a/components/spiffs/library/esp_spiffs.c b/components/spiffs/library/esp_spiffs.c index 9d3fbbc7..87e4ec1d 100644 --- a/components/spiffs/library/esp_spiffs.c +++ b/components/spiffs/library/esp_spiffs.c @@ -162,7 +162,7 @@ void esp_spiffs_deinit(u8_t format) } } -int _open_r(struct _reent *r, const char *filename, int flags, int mode) +int _spiffs_open_r(struct _reent *r, const char *filename, int flags, int mode) { spiffs_mode sm = 0; int res; @@ -201,7 +201,7 @@ int _open_r(struct _reent *r, const char *filename, int flags, int mode) return res; } -_ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len) +_ssize_t _spiffs_read_r(struct _reent *r, int fd, void *buf, size_t len) { ssize_t res; @@ -215,7 +215,7 @@ _ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len) return res; } -_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) +_ssize_t _spiffs_write_r(struct _reent *r, int fd, void *buf, size_t len) { if (fd < NUM_SYS_FD) { @@ -226,7 +226,7 @@ _ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) return res; } -_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence) +_off_t _spiffs_lseek_r(struct _reent *r, int fd, _off_t where, int whence) { ssize_t res; @@ -240,7 +240,7 @@ _off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence) return res; } -int _close_r(struct _reent *r, int fd) +int _spiffs_close_r(struct _reent *r, int fd) { if (fd < NUM_SYS_FD) { @@ -251,21 +251,21 @@ int _close_r(struct _reent *r, int fd) return 0; } -int _rename_r(struct _reent *r, const char *from, const char *to) +int _spiffs_rename_r(struct _reent *r, const char *from, const char *to) { int res = SPIFFS_rename(&fs, (char *) from, (char *) to); return res; } -int _unlink_r(struct _reent *r, const char *filename) +int _spiffs_unlink_r(struct _reent *r, const char *filename) { int res = SPIFFS_remove(&fs, (char *) filename); return res; } -int _fstat_r(struct _reent *r, int fd, struct stat *s) +int _spiffs_fstat_r(struct _reent *r, int fd, struct stat *s) { int res;