From 30de4508164752da6dcaea9186e6b397f8a27d0e Mon Sep 17 00:00:00 2001
From: Dong Heng <dongheng@espressif.com>
Date: Fri, 11 May 2018 17:27:54 +0800
Subject: [PATCH 1/5] feat(newlib): Add newlib platform function

---
 components/esp8266/component.mk               |   2 +-
 components/esp8266/include/c_types.h          |   1 -
 .../esp8266/source/esp_wifi_os_adapter.c      |   8 +-
 .../include/port/freertos/portmacro.h         |  11 ++
 components/freertos/port/impure.c             |  44 +++++++
 components/newlib/component.mk                |   5 +-
 components/newlib/newlib/port/esp_newlib.c    |  68 ++++++++++
 components/newlib/newlib/port/fputc.c         |  26 ++++
 .../newlib/newlib/port/include/esp_newlib.h   |  39 ++++++
 components/newlib/newlib/port/syscall.c       | 123 ++++++++++++++++++
 components/spiffs/library/esp_spiffs.c        |  16 +--
 11 files changed, 330 insertions(+), 13 deletions(-)
 create mode 100644 components/freertos/port/impure.c
 create mode 100644 components/newlib/newlib/port/esp_newlib.c
 create mode 100644 components/newlib/newlib/port/fputc.c
 create mode 100644 components/newlib/newlib/port/include/esp_newlib.h
 create mode 100644 components/newlib/newlib/port/syscall.c

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/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/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    <xtensa/xtruntime.h>
 #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..3425de64
--- /dev/null
+++ b/components/newlib/newlib/port/esp_newlib.c
@@ -0,0 +1,68 @@
+// 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 <reent.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * @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;
+
+    return 0;
+
+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 <stdio.h>
+
+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 <reent.h>
+
+/*
+ * @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 <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#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;

From 4048ed82de77267d4f3d4fd0faa3416153717391 Mon Sep 17 00:00:00 2001
From: Dong Heng <dongheng@espressif.com>
Date: Mon, 14 May 2018 14:42:28 +0800
Subject: [PATCH 2/5] feat(main): Update library to 0b78c0f

1. remove "syscall" and "printf"
2. remove global "errno"
---
 components/esp8266/lib/VERSION       |   4 ++--
 components/esp8266/lib/libcore.a     | Bin 173792 -> 162318 bytes
 components/esp8266/lib/libnet80211.a | Bin 243994 -> 244382 bytes
 3 files changed, 2 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 components/esp8266/lib/libcore.a

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 8ce0e1d81690fb3fbf575582c20e859caeaff7a4..dfc2ad5d9b3a7f8818b97367a1cca9b5c4f07877
GIT binary patch
delta 7269
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
Fe*l0qSMdM<

delta 15198
zcmcIq3wRaPxt%?EGbc|1AtdM_0ZBARk{BRLA_?+HFu4XrK+z@vf~1B7lb~q19za2?
z)PhGlR(u4cTCcQ%(8ha9HStwYsGz8*&|<5tSRY8$3oUZ)S~LH~$@%Kz-tW4<Z=b#X
z^{@T!J$v@-*)wNu|1{yy?tW{sf+b_l88vE5k>6kFXY&5~{iBOVl{&P)p`T%>D8tAa
z^ncG~HycJ|4n`9H%AVY17~eKuy3sInp0(XDz99#{N$?%}gWuT0@3sTMZyuuWv;)C!
zI6vQM<7oT;{rszKn~bl_PrhTQzBw34{I6^?zsvZSdCGf+`K@y0w-tV+?vCig!TPp^
zO|A9qMtyrz<6M^4wKsP*5wvtPHC;_Gr=_jKVcMHo8y7feQEN+ctK*#4(b?EZRmbdh
zhgi_q($Y4E3?gbc=M<XP-sD7RTHM@ev~_I#Tl782F-`65t!?(YcU5la;q*5P7B1?X
zGrzIjSlHg&+UfqzGeCA2^=|i!rp}If$2)K9(g7iJ@TsM6RADhzJ@>b$uyFL~t${)R
zP+#Y-96WAlNlWwWIcK+xbQetg7L6+Y>X0RVfAN^olF$uP@`lu4VKtCTP#8v@k!B=2
zD6RKMAS(3Il>>u;sPbsDF-n~X_ZUWeQCe?G;*l>UU*}6GQeSu~`OL&4OOE!<<h(gH
z95yCjaKU;0ygBV{9UYx*ZK2?x8hgN_Dmj5&j7F}r1COeVgmgd?d5~TEsLBdvh<Of5
zrg&ssL**GpDQvB|hyo;P>W~?gnrSF?*!jRr)aXPF6ZLGGB~yGJE@m3qp)0}R1kk+C
zkvkO(V$G*`cw)`7Gfa#_ta;oCokX5Enuoz2WxKpnfmm1Ydw62a5A*QEoDGaK!Uzo-
zH!8Gx?}$+IxXVJVHF=?bd$~-_5A7Y%KXm`gDG94^h-)BBvBPhv)78D9mufQX(FatD
z3qu26Nr}0aft(uWzmk$LD8X=!ImLe908U>aoJ`Mz+G;b>E(eNpZ1?9~BXs1Ifdg7#
zDGxmahCkGp*?+)QV0jQa4MX(8P-=eviPwYj)+vXv+CymA37t2>G(@0|<DY21^h=c$
zvlBzHJhZGjH!(ZbF!sQi3a1s?Qk@m^0lNFs(BA5zP}!>~p_W%u?4^&X6ni0mx*k)0
zdk=m>+u{3<Gy4VEP!5g|Z8(i;oAEG`4oClBU_CKt=fY-(w7vjXPXzi$!*(Zt8@~d!
zKJWBb!}c38J4s9h!C(xMhSNO@rA};UHZlY7QlWnVN}cFmgsd+m`mu>PmFQoIJPldL
zzuobQih>aGFl5d&cF6ed7I1eZ=Q<wL%eO4)xF=}F1xCHB>nx0VXK_adnbZKcv{0nW
z<RP|%=kO~I7t$HX)Q}^#gr8ahLuKLzX*@DT<cKZd>wr}jevo)ts3Ave3D1#B$E+M?
z&v;zzu&oZ$7rJlKzR(+EG6D;lJHGurVCyf&zGi*hZ6z@1uPU&pvAy$K-&VGEOgS0z
zbs=x7dvZ$b=+R?FHJ)?RMeDjRTBp*IzDD2ugGbb9{c^tHK2|)sB=mzRBg{1;Lfh*G
zcc0v<{u-ms?f%Pusy*>)Q+M~%YK>Bt+f~o1o7HXIyPs91(IebG<ooBeEm+vx(lpm!
z;jdiS?k^tgFD@)9^%spf@0@ebD<0Ebuv4YSslw2vp;_H^d(=agnNn&WdrMucO1P}q
z-#eg6)e_r2pgvZe_ALk1S!Q%nsAXSH?2;>RnI+i=4yqh=)D9n1BVsq7iE|fc7yLox
z#BMIaypOdj9z*c5SO3dC|BtFBSO`Ba%~T`Ss6olO#++)z7&B3FT_{H8W!H*QCtg)c
zwSkiMtr7N}5jK}*ov441YXq<RG017SEH`N{N(#0_*w01Sdm`*Z5%!S?JBmjpiSd2P
z-FG+?iR{q9vrZ458zGw%VNZ>)XGPfGkFXa-*vljA2m0DUqqi?%ycl8sF~WWq_93io
z({KnJM-vyTPCTr%2zx|?UDn6Ox_NOQ!Z5Cku&;vcN23)Cj+t?Dgx`*^e+K(R4A)+_
zgTIdOKMT76ce@+u58?=RM+p89VSfz!04lUez>^XFG_LfLI08c>?2!@nxgI;n3X?qq
z?aL$VmI(WY5%vQS_Tv%uGqB&m2#!E(j^Hb>Yj9)2aRi-P)L%i=xrAdMgFO>AZ`?e`
z18~)L!d@r#8N7-mvBQA~dwhg_S%lqs%0^HIxGD6<H%<>ea*B4@ry}fq5%yaV_Qw%+
zG-iQLY{iPObNbprV`N{#I6uO^B*Jcuu$M;IKZ>v)h_IjTW8+%b)rY`Yi?BbAu(6Py
zN<6~22s<mn&VkMAXEA02XF|a1=jfH$liyXBx{rI^c-$KhYd`)sm47L>VMryYt5BDz
zkhsOghrp>RE<QlaZ5dJn@mLq95KEkB;!)j&AE<Gr8elK{NM!_Nx4}85cO<xpIGY4=
z#Ck_Eff{Z>khrntMuHr%C43dI-jK`|4LM@HA^D;3kE66>KUS&Lr9eml1Y}TVVoUfz
z!0KFAGe!L5h%Mpk$fw&4AFHQStL;CcGKR~|tc4>c-P;b#=;Vm4LG~3#)Vk_`8=Pwf
z-3#F&wuJA5twUTO8gj(?$QL^ryW$g-p$6GAKT-9W>2B2frN+Z3mr&Ja@1d&Ae(w`C
zR%O}4j;h?uajy7ojJlHfaVPQlcEeGXQGT)O=JS!d#Kkug3%`^Yo4KXv{SsoCvWtmF
z+uM#h4IM$G>Zxw+I(h`xI4YN~^56-?5~;$&mlD_6b$?g6=zb@P;pe-xr(tQ~OI4<A
zI1DBHX5uV+``^{NAiBxB%SH|bFmFv=f}>IOPQhKcGS&!w59MlN3B5{qo~S!<$a;Uv
z2Q7_PX$;NH#4@V(YoDt8MA<>JpK4&Y?=$sctQu_Z|EC(6$%iGR>rf{heK;NE-K?K&
z`%kEhOm1h8ct@uDILdqJ9%9$Q9US7iyGWhp;*%mJM{Ehd(W6N~FBy&;vDW;Yn$z7l
z$)X`gYze=K8o#Tt|8hd52F2J+$57WXR4S7rwuIkCO^&PKu7RB(M{EiI1U0#?CLkJe
z#Fp^esTt;K>}$V3C&cKXW4P<6kjmtUE#aS~<_uR;FB)>hmhd~M8R2T0L_?0)5`Gso
zdD4m4lUQ2B*h5FY>)@5kqa;Uc3BQjT?xvA$5DhtE>rA`hBre0VT=!vdZ$e3I3BMUw
z6}XzCq9I3Y71-NO;xY`_M-XYaEG<v4#@TL-F__)#7&&6=Y`Y+gOKhZF7sh%q(w-ky
zBg;p+;u}QV12M5BJU3cO@Cwn8Beq7``@-l#(OoHKMkd#Gq(rpHR)-@WfC%0SGXuXf
z&D`O9FhFV(O$|z7OZYlqm3dc}nK4|RHm5m^TWbX{Ba<VxGVeNI=Bmt}D8$dS2Ptzh
ziUwFgsqMpJqi-LLz^qM<Sl>QUJen5KkR#TbbdP4SXvh(3%^;7){#==<x)a$R$L+xE
z1UX_|+3(T(R5av>wPu({vr#nUh_z;u@C|6=@;n$yUNpWg4syhn@P8s-=#KCE9$Wyd
z_~?)HA$bHOM{JeYhfFhfLAmR`4+|mPc_@i3;hz9j6|Uybq9I3Y3BR41N>_7OG~|da
z;d`hVZ!e58GpfhC(q~Cs;Ns7K**rO7OZXksOmH<8ZX?u?Beo{kd!o$T%!#f$L)^RI
zCblNpzG%#>Np@khnQ`ePSGA7;C%ZUbYLFwggdZt<Da!rSSGoFP;mHwORrbAXVVd28
z7KZaN3~3|pgO|Ga>IApT<cO_H?Gvmq-S)@eVw>)&ek`hIQEp=G8Fn4q)iYf8W>PgS
zeqN;Hh%Mo_Q8Uxk>=g|;Vr!<onXSp?bWq$+z)fsr+J|DyvBNKOYY*w?c6mG8#Fp?q
zY~gadA{LRjxkI{Kq}QT+mhM^hLb_+U?z!ULl!$Xi_Z4;*-FRKW#9BO^D^Tuo-Fx5;
zihB<!ncugGlpL|1_xq^1(hav(G~|da;rCM`>*_|)kR#SxxnByu6{S5d&P=WTo*T4R
z90yQ=*b@GbC+N$fAxEr(zC%sD-4lm1S?`8>&!Jpw;JqFXpB%9zniTRExtji>DM0xF
z>o(Z_cr23*c4<5&exs`zBdQ}%5L=CQC)~l=uDe#;pTbRS34e?MYhBGHq9I3Y312V#
z6*z?_sFyj^Bs@7{y>juLvzp_^v<D`bsl&yHrbAYuPN__e7%Ndtf_Yt|#C}uU@o*FC
z*gl33%|As$j#z6_JepXaJHX_KG0%tf!>GyZ93bv=xQVS<c0<1}C+}(E=06F<aIb;8
zS~_s1xU=CV)*bM}R&(6}C>9MlVoUg8)HK;g5N>#rE6pP{&&AWE8aZNXo?T#J&A7_0
zvvBUOvgcdo$ZEMVUJ!91#Kii_DDeb*T{Pr~EorEfn)&u2M9rM<w*5Y(WiBqG`$9X#
z2ls_8bta|(=j>x}RnR@du7DfGOrLp^9$8-RR84?_7(@4|&m4=(zc3NvE9|O7bEFo3
zCgK{1i8;=R=GA(fTaw&Z4Je8AICl$=`Dd&KR?Th?e=9sWVyoGnkYrwx`F+=YMBHmo
z5?kN5Hz%1R)z$W)By{cS?qf;jZ=zLHcgc<FmiX?m+2&hn+%a@ZKk&H!qXs%U=Qg%q
zg}2q;^xtP`$>`AaQ}Tm#Xbcber~dlv@4RcllYj4#ov8^5|6T4j;|;&Rvj-b!U%c9p
z+ULK|1hx9<DzkWk5pQPUNnoXEsN>;yqtMaED_5J=d+2cG@u>-^=Qh4kv~%b|b9eMZ
z=|v`9Ekp%Z@9`N~MzN`~a;9Grp2QctWzoO$NBev$(Xm}U1xda$8k$lX-U-21kQDds
zfG>OxWv2uZ%adY`g{@uF%fdb%t0k8<7DpL7)xG@#i4#8$S2bpZi=$Q6gzCoW&zyWH
zJGne5koerEZjJfsAD_pk?ijkiC>Th7ukzT`v|hjbpX;8EwBDXK)*j!I-+2Ahgll##
zJG_2()Q8bNqc*m>@<3F%GAq@Uab<>CX-qsCj`agrzuCL`-Ff%>UJDt8Jq^CJ{9g1a
zp?A}!qeD{yzVak>IE(>&=#J<!N9H{JeDTwT*1>?UxYh{5^$uOT&FQnhsOp_rxvAvd
zOXp9`n3tN@Snx{B`{BivzHIBd>nkTk89twNuwei4T7$>yD^JX8tg4(jb>jQs7jkwi
z+rRd`^~bivUz65b(dSTjDtj)wCSlp(Ej!n~vHp1P!Pqa%-BEA<cep${J}G!^BO1@2
zie<oO49rdZ&?vb4;ZRnwPi5^Ic!}@f{wZZf!Twu9Lwp%oyC9krV+4{{910g)p7oI<
zn*R3_lSUZ6xVVtdcZMTrxXvHf|I>@RI?C1+9P!1D+1!83*p#eY4fDDR=dGFj{2oM!
z{YQ94C?$JUVq);ZgRlSGe7?enzvlT$<BqPmcF25wgz<P+b9cyGIovS27RN!kJTVc%
z4dx^YCsi8byB1Ccy~3e?X0E&d^vVgw6{~Ium1f`Su#cE4CzGu*J~ZN|4*hL-b^Q~`
zzJ41nG<Ku~j2@p6zih|a{lWEtq+`ABZE;4;>{=8TN|eTOYSB`<G5(qRrqBK4%a+D6
zW|_ghqepqs@z=zfM)s|7`Kq8czA=#O+vppxp{uc9dGRaZ;@okMs1<KvuqLG%**C`x
zJEiGYesNbL6~WwbmnmP&#5X94|58*NJN1sR4iZQ%9Cg!`anHR7(ffaj-4OP~%8ou2
z%MG<+A5<$p>#Omtj8MhA3{~t0;b{?}Y6iIdW~XBIuv35jGE!}9Ai20V#TV1>N6Ytz
zm*<VUxH5HlWy+Ot6Q6c^_WTdRxP1H-p=Gm&1%DBh*1LJ<)N-@>?aMxy-I&ten3~^v
z_?m>uHyV#G^VL4G_h@gS`Y`-qa@=?`HrG%e@hY%#{5h3}a#AmRdR9(;k$RupLDRi>
z)StqyZ%8XUy7%p{um8DgKR=)XzTIYQjFDF~etnWJrrc16T)i*4dTp?@H;`ECQwK;L
zPCc$_ldnuFPkeKU&-7K@I&?vN&SV1*8+WhWZGMm+NG#eN9=|?Qy-fAWXanNp<LY>-
z&s>n$JQO-Cf|dIl-@7K@JGN{GmW#SXZfcBj6YJ#AFTx32hJB`9@Zbs1?t3BjU83h0
zd990DTJrHI+tJVdWTz@g>?7z7yr5oJ&Rg_hh=<#jaSWNQ@_hvEheip=Jd|ZI_SuiB
zfkD1tS&p2G%)}2PbX^5ZE#IJ0BTrFIJYwusj19<D$asQqux$36ICbE3{5D|RdK}FX
zluYsbpMZvm%s@9HW7Fy2RVbMtGKg`%aroO%>Ogk`Gf_jV<J==0V=|{oxfLZ7^~5Is
zg{R<G$hc=a_(_!g1@A?v8{P-Zcj45(gRFyo2F%2f)1$3`4U9P7QY=Rv3CzTXiTQ4h
zaV7;l4*o@FilYh`)58(f0;dVC2iBFZ1?KQF&|SbxY=D@jnhme_@WeX)gTNfcAS?5Q
zSu#rEr*s7zfu1uw8oqbZNApi$-SA*WL}J6l9L43xxxjjUobAyN)7*eu$nn=lISQ<<
zPywt@M>ViM;s#(QHb$I|asx8oaWRo6#s%W=_j!0?9cSAq9_OFNK&kM;DF=3-!1{c@
z2|P$NeAC6m#+)}`C^sO-a-txSC)SM(@$kglJW+oZd9?3TprJ1zY)MWHQ3){KAUhQ<
zVg)2NK&<uCJ^Gm*eTPR+to3}C#$#Y7f=ggzig6dPJ{|V}GqEvZU3opQuKXad?%b0e
zJ+an5=h6QTcnIRL;dfkp&}o2%uJAWcg%5%Gu9_9%xSAocL&RF21gtxh0-Os!_2+1P
z-j|D>0=@!#6a34Od!sS_`iP&`72qJ|s>eY5H;}6xG2f^$u@l64oj40vuLosXgT{y%
zmJL?`bDpu`=~`0+L#JrD^jLu+mP~9+r)U-Oj|<@QvVrzTZ>l{5v8&@cW5kMpPo>ji
zLaSfSN!WqTO~5FnIv<*uKa2_OsTt^eX_mSM%~wbb7Ac`0*JQ+yjppYWO*P=WQM=&b
zrJ$3>GeA%$?@Eo$&~fF_$vJcw^N^`46vuYxW`(w7_AlpcfoD>u3>*mGyX&OkG7uWm
z_Yx`<@_V)gynpDCqQ{3BS%s3PgMFco<?YDc2w_Bc0{zfQ`)&o{jW-SPsAIe&_v^N9
zteiH#ZcC^F%a`nF_Q*e|(_;o<$bYFnZL>Gyi#F%`ww}lERa>8r+*0gAbZ&puA57}g
zD~>GBH+#S(mVc(|(T3?@`S*sVV-ItX`$O$0WG>hI3ySr}!se_$gp&4nlsfT>F{(pt
zubm!TtT~hnvm(M?9bx|jww}`ryH5O!$UpZVMConTsOQ(cMf{xC`Np@te$j%qxgE{t
z;M?9sbDPh<mawD#y5@P!^=%!^_45|B&gtm;C2&V)drMQRvAC|Sy>mumYiHBkOPX(J
zs%&Y#sx@@l2U)>|*V0q#e4%D6Xj(95;q`_?P2$ICU-2C=y2;B_KNMG>|BA;zo*1LZ
zRO;cKKWb#|@J}4Y$-%|E=S#!cMJe86C27o?Tsm}2=OGhw!g7rv9)|LI!Q2q>Jdo$c
z=PtqA;A|HBE0hKBrz<RGyp><z7zm2;4#B+N-|xY13ucEiaD;3Cw`1ch!MjlMgBkL?
z179PUw~KoObNSyQm`nTbf?{yl{=HxhPZVqh;>~HWU{1U|!Mw@wb82dM4_fHKHwxyE
z+k&~b_>D*Nw%{NuM<cKfR4AAgmI~$u_!okCPJbns=lU7JT=Eleei?`JVSr#R^AiPg
z&IIHX@YK!W`DX=gM6VVH7pH3lbE#V@coj;XL+ZDpe87Vr5}b$fQNbHfZWp{4WshKL
zelPe*ZYJnt(05So7fjJX!Q8}V!A}i0qWOaBz?TT-K6JDP^HVbF$#YH-bMJW!b@az)
z{G2SEn^}@HtYiSB8FV0X<9Y(N;?jb2weaMKE#W(a=ce}t!Q8km5zNi)QV+gGFb^{L
zs2Dt&PX%)u#|<kx!3}B@GBIa39>Y)ZiGsO7%@)j{d4d^(R|xA?pez^6eJigJ@Ihx&
zS|g4Il+3KaO=+{>Hk2)bxh=a+@V}$HK`{4;O9kWom~oSbzf~|dw08);8|7Ul&OaOD
zcCAYs+}u7Q_%W251aphV57?;ZCiW@8&!K!;Fn48p1#<)ZnP6^i`K=o3avz$2Oq|Q>
zpC7H!7=&_wU~boP1#_bt5X_D4WWl@(P8G}z?bRNBk>DFpt`W>re6L{cNq>zTWWx;9
zBMxpp`G>FO|00-s%&><~KnJPeUNT=W8*u*K1%Dg3Rl;-IHvw4j;RA_2)&&=I3`-nU
z6mb)Y^ni%S5$g|*_;0h~rV#02(U2pygx@SY_oUke_oA#r)}K$m<nTEEBx&gHr>9Xg
z$Zg<lN96ulO{~A`IZ2)mm`E|Qx^bnO$+~<tKuQ*#9I<|NeFk}{I|c7mjP(A7J)l!f
z>b~i56{Wfdr<xN@t_w_67;+_eng=&{FuzIEn#CS`vj=kyXbtCp#y|JqZ5|xte9)p@
z9=zX!Ioq}7hzFnW;CPOR9030m(Ae+61s?3|8MrPmIg>^zJLgU?_eeU>d=KvQ;H4hC
z+Jo=*;Ef*4Iiq84=R=M*c6c27Jou0Yf8fE#JUAMsSI6P!2pVU5u=5AM99W6wdHmcd
z>IyX;Jkx{cdhkLIUgE*4h_TKv-ARno!_?)${NzBP<4he3o9petr<uuL_r3fDr<pI#
F`X8^cW%K|5

diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a
index 5bf1f109dff97030630616e91ec247b21bc9cda5..a3477c0d73548d511bdab1bb323dc71a87adbd0e 100644
GIT binary patch
delta 1823
zcmbRBiErLlz6sLoW=7_ghK9x)m1-F4=eRI1Qh=F+4H)29?g#@DHmtLTfe9P7+`>@L
z1SIfc?>P)i*l_3)1}4gJJ?VxVox#9_1v5)uV;~xvv@tM)aXpMdcRDjQHPymkvKXtt
zbOkj=;mP-yxi_C+Ruxfzqz)qm1p@^TfRKg;24*HE3JNAhhLa8RG&h?`qzm9zX=Y*$
zR{2cBT2czPnVYSh9x39JH&406iBDcTPmKege0G@<r#x=^fqpVHn{1G$wfS0oIvaj3
z8JZYPc68F*+}2jliqA^<p1dYJ^4pj5F@Dp)r(pI>#utp!=UXxg;Zt?mlF^S>3BT7&
z49!d?^Gm32PjY8;H^*lh(9V~P)7LaG3gQn0Gb0O7AZ%xAWUQ7Tpw!HC`ofuvn!*<t
zfPk5S!30DzXfSXxuuWF1h?#t4r}XrkdPcwLcIOxsCdbKfFe*-#_fuz7pM1Yiol$2x
z_iRRWM$_s3mW=A6f)FFXCV+@OAa<H;-=fTG!NkCj0OWB1G27()7HQTQKoQ2t{Vj%*
zAGA0avNAAm=^I%Xf|E0pFf=uS1e`G}g(Ic&?dxYVUMhnI7FGqbg_x?i@hQ-kV>-u+
zPl31&(>oq~3gj)B&I#gE!0yfT4wf^pI+8z>=~g~8ePB}nO!`KKMwUk4^kH<ANj?}F
koj4Sm4W8&M&xudY$kof&Cn`GYrI@El;0sE9W9HYb0HAe&Jpcdz

delta 1641
zcmbRDm2cK3z6sLoCg#SbrWU3fm1-F4XE!l0Qh=F+@)+P)j){Q@8`gfsz=RE3d}63)
z0up$!*DVGnY&hf*0~6)Ao^(TwTw`Fuf|;d)7>LHkObpCmTn}T=oz6^6O|>wXEXFD@
zT|tdec=A1F?#(BdRYeq_sY5}*)WApqMj9Fzn3<U<D3}--PBzTb+-xS1E`VR9nTa`A
z<ueUyNh#cBZnk!Mq^O8n9%!eLiG{`V2Rcj|o6}NObK)~gJ5P-RpL}+i5~n;~y9~`H
z8{}zizE+>khTnUJCPtGToisPMwbirYvr@h%uSp5Nl?EoJM$;eaFsX09#>aSE1HZi{
z=0?*O&Sccw{>+^5G$S6Hx1Y9T^y4L9wTYpb3B>9ocSd(};;r7vIDK^kqY!=#W=0mE
zFxt-6$XG3bUn#P;b~5T1Sr`J79vm2&8sQGY?S*p~FO}g7iCAH#DsFrVKFTqj<He`o
zrVi6P9()QOS~8sz#HZk-H`6<OX?Od@P^Me?_@m3n(8v;+QobBzk`E?6NOv$Am*>PM
rXXNVT>qA2oZ<qpeotcptIP#2SnA0WjyUW<b$jkzgj2@XV?`Z`9XRm0s


From 7df0212b925a937b374aaa7413abb2454548a64b Mon Sep 17 00:00:00 2001
From: Dong Heng <dongheng@espressif.com>
Date: Mon, 14 May 2018 14:51:49 +0800
Subject: [PATCH 3/5] feat(ld): add "ets_printf" to rom link file

---
 components/esp8266/ld/eagle.rom.addr.v6.ld | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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

From 08c3dbe2ba6645fb5274eb428a8bde81b8b18b00 Mon Sep 17 00:00:00 2001
From: Dong Heng <dongheng@espressif.com>
Date: Mon, 14 May 2018 15:50:55 +0800
Subject: [PATCH 4/5] feat(newlib): Initialize environ

---
 components/newlib/newlib/port/esp_newlib.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/components/newlib/newlib/port/esp_newlib.c b/components/newlib/newlib/port/esp_newlib.c
index 3425de64..f93e32cf 100644
--- a/components/newlib/newlib/port/esp_newlib.c
+++ b/components/newlib/newlib/port/esp_newlib.c
@@ -14,7 +14,9 @@
 
 #include <reent.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 /*
  * @brief Initialize global and thread's private reent object data. We add this instead of
@@ -57,8 +59,15 @@ int esp_newlib_init(void)
     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:

From 0c633ce7ce21f8bfa521d5ea723f3416dc234a02 Mon Sep 17 00:00:00 2001
From: Dong Heng <dongheng@espressif.com>
Date: Mon, 14 May 2018 17:19:31 +0800
Subject: [PATCH 5/5] feat(freertos): Use "reent" default.

---
 components/freertos/include/port/freertos/FreeRTOSConfig.h | 2 ++
 1 file changed, 2 insertions(+)

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