NuMaker Transfer data UART to Ethernet

Fork of Serial-to-Ethernet by Morgan Du

Files at this revision

API Documentation at this revision

Comitter:
SHLIU1@OANBE02333.nuvoton.com
Date:
Tue Mar 02 10:09:10 2021 +0800
Parent:
5:b079098a3f0b
Child:
7:c03b2ed97d94
Commit message:
Support the both V5.X and V6.X for mbed-os

Changed in this revision

BufferSerial/BufferSerial.cpp Show annotated file Show diff for this revision Revisions of this file
BufferSerial/BufferSerial.h Show annotated file Show diff for this revision Revisions of this file
BufferSerial/MyBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
BufferSerial/MyBuffer.h Show annotated file Show diff for this revision Revisions of this file
BufferSerial/MyUnbufferedSerial.cpp Show annotated file Show diff for this revision Revisions of this file
BufferSerial/MyUnbufferedSerial.h Show annotated file Show diff for this revision Revisions of this file
BufferedSerial.lib Show diff for this revision Revisions of this file
NuMaker-mbed-SD-driver.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
ste_config.h Show annotated file Show diff for this revision Revisions of this file
uweb_server.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferSerial/BufferSerial.cpp	Tue Mar 02 10:09:10 2021 +0800
@@ -0,0 +1,183 @@
+/**
+ * @file    BufferSerial.cpp
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * 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 "BufferSerial.h"
+#include <stdarg.h>
+
+#if MBED_MAJOR_VERSION >= 6
+
+BufferSerial::BufferSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+    : MyUnbufferedSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+#else
+BufferSerial::BufferSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+    : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+#endif
+{
+#if MBED_MAJOR_VERSION >= 6
+    MyUnbufferedSerial::attach(callback(this, &BufferSerial::rxIrq), SerialBase::RxIrq);
+#else
+    RawSerial::attach(this, &BufferSerial::rxIrq, Serial::RxIrq);
+#endif
+    this->_buf_size = buf_size;
+    this->_tx_multiple = tx_multiple;   
+    return;
+}
+
+BufferSerial::~BufferSerial(void)
+{
+#if MBED_MAJOR_VERSION >= 6
+    MyUnbufferedSerial::attach(NULL, MyUnbufferedSerial::RxIrq);
+    MyUnbufferedSerial::attach(NULL, MyUnbufferedSerial::TxIrq);
+#else
+    RawSerial::attach(NULL, RawSerial::RxIrq);
+    RawSerial::attach(NULL, RawSerial::TxIrq);
+#endif
+
+    return;
+}
+
+int BufferSerial::readable(void)
+{
+    return _rxbuf.available();  // note: look if things are in the buffer
+}
+
+int BufferSerial::writeable(void)
+{
+    return 1;   // buffer allows overwriting by design, always true
+}
+
+int BufferSerial::getc(void)
+{
+    return _rxbuf;
+}
+
+int BufferSerial::putc(int c)
+{
+    _txbuf = (char)c;
+    BufferSerial::prime();
+
+    return c;
+}
+
+int BufferSerial::puts(const char *s)
+{
+    if (s != NULL) {
+        const char* ptr = s;
+    
+        while(*(ptr) != 0) {
+            _txbuf = *(ptr++);
+        }
+        _txbuf = '\n';  // done per puts definition
+        BufferSerial::prime();
+    
+        return (ptr - s) + 1;
+    }
+    return 0;
+}
+
+int BufferSerial::printf(const char* format, ...)
+{
+    char buffer[this->_buf_size];
+    memset(buffer,0,this->_buf_size);
+    int r = 0;
+
+    va_list arg;
+    va_start(arg, format);
+    r = vsprintf(buffer, format, arg);
+    // this may not hit the heap but should alert the user anyways
+    if(r > this->_buf_size) {
+        error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
+        va_end(arg);
+        return 0;
+    }
+    va_end(arg);
+    r = BufferSerial::write(buffer, r);
+
+    return r;
+}
+
+ssize_t BufferSerial::write(const void *s, size_t length)
+{
+    if (s != NULL && length > 0) {
+        const char* ptr = (const char*)s;
+        const char* end = ptr + length;
+    
+        while (ptr != end) {
+            _txbuf = *(ptr++);
+        }
+        BufferSerial::prime();
+    
+        return ptr - (const char*)s;
+    }
+    return 0;
+}
+
+
+void BufferSerial::rxIrq(void)
+{
+    // read from the peripheral and make sure something is available
+    if(serial_readable(&_serial)) {
+        _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+    }
+
+    return;
+}
+
+void BufferSerial::txIrq(void)
+{
+    // see if there is room in the hardware fifo and if something is in the software fifo
+    while(serial_writable(&_serial)) {
+        if(_txbuf.available()) {
+            serial_putc(&_serial, (int)_txbuf.get());
+        } else {
+            // disable the TX interrupt when there is nothing left to send
+#if MBED_MAJOR_VERSION >= 6
+            MyUnbufferedSerial::attach(NULL, MyUnbufferedSerial::TxIrq);
+#else
+            RawSerial::attach(NULL, RawSerial::TxIrq);
+#endif
+            break;
+        }
+    }
+
+    return;
+}
+
+void BufferSerial::prime(void)
+{
+    // if already busy then the irq will pick this up
+    if(serial_writable(&_serial)) {
+#if MBED_MAJOR_VERSION >= 6
+        MyUnbufferedSerial::attach(NULL, MyUnbufferedSerial::TxIrq);    // make sure not to cause contention in the irq
+        BufferSerial::txIrq();                // only write to hardware in one place
+        MyUnbufferedSerial::attach(callback(this, &BufferSerial::txIrq), MyUnbufferedSerial::TxIrq);
+#else
+        RawSerial::attach(NULL, RawSerial::TxIrq);    // make sure not to cause contention in the irq
+        BufferSerial::txIrq();                // only write to hardware in one place
+        RawSerial::attach(this, &BufferSerial::txIrq, RawSerial::TxIrq);
+#endif
+    }
+
+    return;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferSerial/BufferSerial.h	Tue Mar 02 10:09:10 2021 +0800
@@ -0,0 +1,154 @@
+
+/**
+ * @file    BufferSerial.h
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * 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 BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+ 
+#include "mbed.h"
+#include "MyBuffer.h"
+
+#if (MBED_MAJOR_VERSION == 5) && (MBED_MINOR_VERSION >= 2)
+#elif (MBED_MAJOR_VERSION == 2) && (MBED_PATCH_VERSION > 130)
+#else
+//#error "BufferSerial version 13 and newer requires use of Mbed OS 5.2.0 and newer or Mbed 2 version 130 and newer. Use BufferSerial version 12 and older or upgrade the Mbed version.
+#endif
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "BufferSerial.h"
+ *
+ *  BufferSerial pc(USBTX, USBRX);
+ *
+ *  int main()
+ *  { 
+ *      while(1)
+ *      {
+ *          Timer s;
+ *        
+ *          s.start();
+ *          pc.printf("Hello World - buffer\n");
+ *          int buffer_time = s.read_us();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          s.reset();
+ *          printf("Hello World - blocking\n");
+ *          int polled_time = s.read_us();
+ *          s.stop();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          pc.printf("printf buffer took %d us\n", buffer_time);
+ *          pc.printf("printf blocking took %d us\n", polled_time);
+ *          wait(0.5f);
+ *      }
+ *  }
+ * @endcode
+ */
+
+/**
+ *  @class BufferSerial
+ *  @brief Software buffers and interrupt driven tx and rx for Serial
+ */  
+
+#if MBED_MAJOR_VERSION >= 6 
+#include "MyUnbufferedSerial.h"
+class BufferSerial : public MyUnbufferedSerial
+{
+#else
+class BufferSerial : public RawSerial 
+{
+#endif
+
+private:
+    MyBuffer <char> _rxbuf;
+    MyBuffer <char> _txbuf;
+    uint32_t      _buf_size;
+    uint32_t      _tx_multiple;
+ 
+    void rxIrq(void);
+    void txIrq(void);
+    void prime(void);
+    
+public:
+    /** Create a BufferSerial port, connected to the specified transmit and receive pins
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *  @param buf_size printf() buffer size
+     *  @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+     *  @param name optional name
+     *  @note Either tx or rx may be specified as NC if unused
+     */
+    BufferSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+    
+    /** Destroy a BufferSerial port
+     */
+    virtual ~BufferSerial(void);
+    
+    /** Check on how many bytes are in the rx buffer
+     *  @return 1 if something exists, 0 otherwise
+     */
+    virtual int readable(void);
+    
+    /** Check to see if the tx buffer has room
+     *  @return 1 always has room and can overwrite previous content if too small / slow
+     */
+    virtual int writeable(void);
+    
+    /** Get a single byte from the BufferSerial Port.
+     *  Should check readable() before calling this.
+     *  @return A byte that came in on the Serial Port
+     */
+    virtual int getc(void);
+    
+    /** Write a single byte to the BufferSerial Port.
+     *  @param c The byte to write to the Serial Port
+     *  @return The byte that was written to the Serial Port Buffer
+     */
+    virtual int putc(int c);
+    
+    /** Write a string to the BufferSerial Port. Must be NULL terminated
+     *  @param s The string to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int puts(const char *s);
+    
+    /** Write a formatted string to the BufferSerial Port.
+     *  @param format The string + format specifiers to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int printf(const char* format, ...);
+    
+    /** Write data to the Buffer Serial Port
+     *  @param s A pointer to data to send
+     *  @param length The amount of data being pointed to
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual ssize_t write(const void *s, std::size_t length);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferSerial/MyBuffer.cpp	Tue Mar 02 10:09:10 2021 +0800
@@ -0,0 +1,76 @@
+
+/**
+ * @file    Buffer.cpp
+ * @brief   Software Buffer - Templated Ring Buffer for most data types
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * 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 "MyBuffer.h"
+
+template <class T>
+MyBuffer<T>::MyBuffer(uint32_t size)
+{
+    _buf = new T [size];
+    _size = size;
+    clear();
+    
+    return;
+}
+
+template <class T>
+MyBuffer<T>::~MyBuffer()
+{
+    delete [] _buf;
+    
+    return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::getSize() 
+{ 
+    return this->_size; 
+}
+
+template <class T>
+void MyBuffer<T>::clear(void)
+{
+    _wloc = 0;
+    _rloc = 0;
+    memset(_buf, 0, _size);
+    
+    return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::peek(char c)
+{
+    return 1;
+}
+
+// make the linker aware of some possible types
+template class MyBuffer<uint8_t>;
+template class MyBuffer<int8_t>;
+template class MyBuffer<uint16_t>;
+template class MyBuffer<int16_t>;
+template class MyBuffer<uint32_t>;
+template class MyBuffer<int32_t>;
+template class MyBuffer<uint64_t>;
+template class MyBuffer<int64_t>;
+template class MyBuffer<char>;
+template class MyBuffer<wchar_t>;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferSerial/MyBuffer.h	Tue Mar 02 10:09:10 2021 +0800
@@ -0,0 +1,163 @@
+
+/**
+ * @file    Buffer.h
+ * @brief   Software Buffer - Templated Ring Buffer for most data types
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * 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 MYBUFFER_H
+#define MYBUFFER_H
+
+#include <stdint.h>
+#include <string.h>
+
+/** A templated software ring buffer
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "MyBuffer.h"
+ *
+ *  MyBuffer <char> buf;
+ *
+ *  int main()
+ *  {
+ *      buf = 'a';
+ *      buf.put('b');
+ *      char *head = buf.head();
+ *      puts(head);
+ *
+ *      char whats_in_there[2] = {0};
+ *      int pos = 0;
+ *
+ *      while(buf.available())
+ *      {   
+ *          whats_in_there[pos++] = buf;
+ *      }
+ *      printf("%c %c\n", whats_in_there[0], whats_in_there[1]);
+ *      buf.clear();
+ *      error("done\n\n\n");
+ *  }
+ * @endcode
+ */
+
+template <typename T>
+class MyBuffer
+{
+private:
+    T   *_buf;
+    volatile uint32_t   _wloc;
+    volatile uint32_t   _rloc;
+    uint32_t            _size;
+
+public:
+    /** Create a Buffer and allocate memory for it
+     *  @param size The size of the buffer
+     */
+    MyBuffer(uint32_t size = 0x100);
+    
+    /** Get the size of the ring buffer
+     * @return the size of the ring buffer
+     */
+     uint32_t getSize();
+    
+    /** Destry a Buffer and release it's allocated memory
+     */
+    ~MyBuffer();
+    
+    /** Add a data element into the buffer
+     *  @param data Something to add to the buffer
+     */
+    void put(T data);
+    
+    /** Remove a data element from the buffer
+     *  @return Pull the oldest element from the buffer
+     */
+    T get(void);
+    
+    /** Get the address to the head of the buffer
+     *  @return The address of element 0 in the buffer
+     */
+    T *head(void);
+    
+    /** Reset the buffer to 0. Useful if using head() to parse packeted data
+     */
+    void clear(void);
+    
+    /** Determine if anything is readable in the buffer
+     *  @return 1 if something can be read, 0 otherwise
+     */
+    uint32_t available(void);
+    
+    /** Overloaded operator for writing to the buffer
+     *  @param data Something to put in the buffer
+     *  @return
+     */
+    MyBuffer &operator= (T data)
+    {
+        put(data);
+        return *this;
+    }
+    
+    /** Overloaded operator for reading from the buffer
+     *  @return Pull the oldest element from the buffer 
+     */  
+    operator int(void)
+    {
+        return get();
+    }
+    
+     uint32_t peek(char c);
+    
+};
+
+template <class T>
+inline void MyBuffer<T>::put(T data)
+{
+    _buf[_wloc++] = data;
+    _wloc %= (_size-1);
+    
+    return;
+}
+
+template <class T>
+inline T MyBuffer<T>::get(void)
+{
+    T data_pos = _buf[_rloc++];
+    _rloc %= (_size-1);
+    
+    return data_pos;
+}
+
+template <class T>
+inline T *MyBuffer<T>::head(void)
+{
+    T *data_pos = &_buf[0];
+    
+    return data_pos;
+}
+
+template <class T>
+inline uint32_t MyBuffer<T>::available(void)
+{
+    return (_wloc == _rloc) ? 0 : 1;
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferSerial/MyUnbufferedSerial.cpp	Tue Mar 02 10:09:10 2021 +0800
@@ -0,0 +1,128 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2019 ARM Limited
+ * 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.
+ */
+
+#include "MyUnbufferedSerial.h"
+#if (MBED_MAJOR_VERSION >= 6)
+#if DEVICE_SERIAL
+
+#include "platform/mbed_critical.h"
+
+namespace mbed {
+
+MyUnbufferedSerial::MyUnbufferedSerial(
+    PinName tx,
+    PinName rx,
+    int baud
+) : SerialBase(tx, rx, baud)
+{
+    // No lock needed in the constructor
+}
+
+MyUnbufferedSerial::MyUnbufferedSerial(
+    const serial_pinmap_t &static_pinmap, int baud
+) : SerialBase(static_pinmap, baud)
+{
+    // No lock needed in the constructor
+}
+
+ssize_t MyUnbufferedSerial::write(const void *buffer, size_t size)
+{
+    const unsigned char *buf = static_cast<const unsigned char *>(buffer);
+
+    if (size == 0) {
+        return 0;
+    }
+
+    bool lock_api = !core_util_in_critical_section();
+
+    if (lock_api) {
+        lock();
+    }
+
+    for (size_t i = 0; i < size; i++) {
+        _base_putc(buf[i]);
+    }
+
+    if (lock_api) {
+        unlock();
+    }
+
+    return size;
+}
+
+ssize_t MyUnbufferedSerial::read(void *buffer, size_t size)
+{
+    unsigned char *buf = static_cast<unsigned char *>(buffer);
+
+    if (size == 0) {
+        return 0;
+    }
+
+    lock();
+
+    buf[0] = _base_getc();
+
+    unlock();
+
+    return 1;
+}
+
+short MyUnbufferedSerial::poll(short events) const
+{
+    short revents = 0;
+    if (
+        (events & POLLIN)
+        && (const_cast <MyUnbufferedSerial *>(this))->SerialBase::readable()
+    ) {
+        revents |= POLLIN;
+    }
+    if (
+        (events & POLLOUT)
+        && (const_cast <MyUnbufferedSerial *>(this))->SerialBase::writeable()
+    ) {
+        revents |= POLLOUT;
+    }
+    return revents;
+}
+
+int MyUnbufferedSerial::enable_input(bool enabled)
+{
+    SerialBase::enable_input(enabled);
+
+    return 0;
+}
+
+int MyUnbufferedSerial::enable_output(bool enabled)
+{
+    SerialBase::enable_output(enabled);
+
+    return 0;
+}
+
+#if DEVICE_SERIAL_FC
+void MyUnbufferedSerial::set_flow_control(Flow type, PinName flow1, PinName flow2)
+{
+    lock();
+    SerialBase::set_flow_control(type, flow1, flow2);
+    unlock();
+}
+#endif // DEVICE_SERIAL_FC
+
+} // namespace mbed
+
+#endif // #if DEVICE_SERIAL
+#endif // (MBED_MAJOR_VERSION >= 6 )
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferSerial/MyUnbufferedSerial.h	Tue Mar 02 10:09:10 2021 +0800
@@ -0,0 +1,223 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2019 ARM Limited
+ * 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.
+ */
+#ifndef MBED_MYUNBUFFERED_SERIAL_H
+#define MBED_MYUNBUFFERED_SERIAL_H
+#include "mbed.h"
+#if (MBED_MAJOR_VERSION >= 6)
+
+#include "platform/platform.h"
+
+#if DEVICE_SERIAL || defined(DOXYGEN_ONLY)
+
+#include <cstdarg>
+
+#include "drivers/SerialBase.h"
+#include "platform/FileHandle.h"
+#include "platform/mbed_toolchain.h"
+#include "platform/NonCopyable.h"
+
+
+namespace mbed {
+/** \defgroup drivers-public-api-uart UART
+ * \ingroup drivers-public-api
+ */
+
+/**
+ * \defgroup drivers_MyUnbufferedSerial MyUnbufferedSerial class
+ * \ingroup drivers-public-api-uart
+ * @{
+ */
+
+/**
+ * Class implementation for unbuffered I/O for an interrupt driven application
+ * or one that needs to have more control.
+ */
+class MyUnbufferedSerial:
+    public SerialBase,
+    public FileHandle,
+    private NonCopyable<MyUnbufferedSerial> {
+public:
+    /**
+     * Create a serial port instance connected to the specified transmit and
+     * receive pins, with the specified baud rate.
+     *
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *  @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
+     *
+     *  @note
+     *    Either tx or rx may be specified as NC if unused
+     */
+    MyUnbufferedSerial(
+        PinName tx,
+        PinName rx,
+        int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE
+    );
+
+    /** Create a MyUnbufferedSerial port, connected to the specified transmit and
+     *  receive pins, with a particular baud rate.
+     *  @param static_pinmap reference to structure which holds static pinmap
+     *  @param baud The baud rate of the serial port (optional, defaults to
+     *              MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
+     */
+    MyUnbufferedSerial(
+        const serial_pinmap_t &static_pinmap,
+        int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE
+    );
+
+    /** Write the contents of a buffer to a file
+     *
+     * Blocks until all data is written
+     *
+     *  @param buffer   The buffer to write from
+     *  @param size     The number of bytes to write
+     *  @return         The number of bytes written
+     */
+    ssize_t write(const void *buffer, size_t size) override;
+
+    /** Read the contents of a file into a buffer
+     *
+     *  Blocks and reads exactly one character
+     *
+     *  @param buffer   The buffer to read in to
+     *  @param size     The number of bytes to read
+     *  @return         The number of bytes read
+     */
+    ssize_t read(void *buffer, size_t size) override;
+
+    /** Move the file position to a given offset from from a given location
+     *
+     * Not valid for a device type FileHandle like MyUnbufferedSerial.
+     * In case of MyUnbufferedSerial, returns ESPIPE
+     *
+     *  @param offset   The offset from whence to move to
+     *  @param whence   The start of where to seek
+     *      SEEK_SET to start from beginning of file,
+     *      SEEK_CUR to start from current position in file,
+     *      SEEK_END to start from end of file
+     *  @return         The new offset of the file, negative error code on failure
+     */
+    off_t seek(off_t offset, int whence = SEEK_SET) override
+    {
+        return -ESPIPE;
+    }
+
+    /** Get the size of the file
+     *
+     *  @return         Size of the file in bytes
+     */
+    off_t size() override
+    {
+        return -EINVAL;
+    }
+
+    /** Check if the file in an interactive terminal device
+     *
+     *  @return         True if the file is a terminal
+     *  @return         False if the file is not a terminal
+     *  @return         Negative error code on failure
+     */
+    int isatty() override
+    {
+        return true;
+    }
+
+    /** Close a file
+     *
+     *  @return         0 on success, negative error code on failure
+     */
+    int close() override
+    {
+        return 0;
+    }
+
+    /** Enable or disable input
+     *
+     * Control enabling of device for input. This is primarily intended
+     * for temporary power-saving; the overall ability of the device to operate
+     * for input and/or output may be fixed at creation time, but this call can
+     * allow input to be temporarily disabled to permit power saving without
+     * losing device state.
+     *
+     *  @param enabled      true to enable input, false to disable.
+     *
+     *  @return             0 on success
+     *  @return             Negative error code on failure
+     */
+    int enable_input(bool enabled) override;
+
+    /** Enable or disable output
+     *
+     * Control enabling of device for output. This is primarily intended
+     * for temporary power-saving; the overall ability of the device to operate
+     * for input and/or output may be fixed at creation time, but this call can
+     * allow output to be temporarily disabled to permit power saving without
+     * losing device state.
+     *
+     *  @param enabled      true to enable output, false to disable.
+     *
+     *  @return             0 on success
+     *  @return             Negative error code on failure
+     */
+    int enable_output(bool enabled) override;
+
+    /** Check for poll event flags
+     * Check the events listed in events to see if data can be read or written
+     * without blocking.
+     * Call is nonblocking - returns state of events.
+     *
+     * @param events        bitmask of poll events we're interested in - POLLIN/POLLOUT etc.
+     *
+     * @returns             bitmask of poll events that have occurred.
+     */
+    short poll(short events) const override;
+
+    using SerialBase::attach;
+    using SerialBase::baud;
+    using SerialBase::format;
+    using SerialBase::readable;
+    using SerialBase::writeable;
+    using SerialBase::IrqCnt;
+    using SerialBase::RxIrq;
+    using SerialBase::TxIrq;
+
+#if DEVICE_SERIAL_FC
+    // For now use the base enum - but in future we may have extra options
+    // such as XON/XOFF or manual GPIO RTSCTS.
+    using SerialBase::Flow;
+    // In C++11, we wouldn't need to also have using directives for each value
+    using SerialBase::Disabled;
+    using SerialBase::RTS;
+    using SerialBase::CTS;
+    using SerialBase::RTSCTS;
+
+    /** Set the flow control type on the serial port
+     *
+     *  @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
+     *  @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
+     *  @param flow2 the second flow control pin (CTS for RTSCTS)
+     */
+    void set_flow_control(Flow type, PinName flow1 = NC, PinName flow2 = NC);
+#endif // DEVICE_SERIAL_FC
+};
+
+} // namespace mbed
+
+#endif // DEVICE_SERIAL || defined(DOXYGEN_ONLY)
+
+#endif  // (MBED_MAJOR_VERSION >= 6 )
+#endif // MBED_MYUNBUFFERED_SERIAL_H
--- a/BufferedSerial.lib	Thu Apr 19 14:03:33 2018 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/sam_grove/code/BufferedSerial/#a0d37088b405
--- a/NuMaker-mbed-SD-driver.lib	Thu Apr 19 14:03:33 2018 +0800
+++ b/NuMaker-mbed-SD-driver.lib	Tue Mar 02 10:09:10 2021 +0800
@@ -1,1 +1,1 @@
-https://github.com/OpenNuvoton/NuMaker-mbed-SD-driver/#7b763a96fa361da47a294efbe4bc201f7fb9c818
+https://github.com/OpenNuvoton/NuMaker-mbed-SD-driver/#8027c2c886a6bb2d850d3121ec3e2e179450e41c
--- a/main.cpp	Thu Apr 19 14:03:33 2018 +0800
+++ b/main.cpp	Tue Mar 02 10:09:10 2021 +0800
@@ -5,10 +5,9 @@
  * 
  *
  */
- 
 #include "ste_config.h"
 
-/* If define USE_STATIC_IP, specify the default IP address. */
+/* If choose static IP, specify the default IP address here. */
 #if 0
     // private IP address for general purpose
 #define IP_ADDRESS      "192.168.1.2"
@@ -16,25 +15,38 @@
 #define GATEWAY_ADDRESS "192.168.1.1"
 #else
     // private IP address only for test with Windows when DHCP server doesn't exist.
+    // Windows set its LAN IP address to 169.254.xxx.xxx / 255.255.0.0 
 #define IP_ADDRESS      "169.254.108.2"
 #define NETWORK_MASK    "255.255.0.0"
 #define GATEWAY_ADDRESS "169.254.108.1"
 #endif
 
-/* Default configuration for network */
+/* Default IP configuration for Ethernet network */
 S_NET_CONFIG net_config = {IP_STATIC_MODE, IP_ADDRESS, NETWORK_MASK, GATEWAY_ADDRESS};
 
-#if defined (TARGET_NUMAKER_PFM_M487)
-BufferedSerial serial_0(PH_8, PH_9, 256, 4);    // UART1
-BufferedSerial serial_1(PC_12, PC_11, 256, 4);  // UART0
-BufferedSerial serial_2(PA_3, PA_2, 256, 4);  // UART4
+#if defined (TARGET_NUMAKER_PFM_M487) || defined(TARGET_NUMAKER_IOT_M487)
+#if MBED_MAJOR_VERSION <= 5
+BufferSerial serial_0(PB_3, PB_2, 256, 4);    // UART1
+BufferSerial serial_1(PA_5, PA_4, 256, 4);    // UART5
+//BufferSerial serial_2(PB_13, PB_12, 256, 4);  // UART0, Debug
+#else
+BufferSerial serial_0(PB_3, PB_2);    // UART1
+BufferSerial serial_1(PA_5, PA_4);    // UART5
+//BufferSerial serial_2(PB_13, PB_12);  // UART0, Debug
+#endif
 
 #elif defined (TARGET_NUMAKER_PFM_NUC472)
-BufferedSerial serial_0(PH_1, PH_0, 256, 4);    // UART4
-BufferedSerial serial_1(PG_2, PG_1, 256, 4);    // UART0
-BufferedSerial serial_2(PC_11, PC_10, 256, 4);  // UART2
+#if MBED_MAJOR_VERSION <= 5
+BufferSerial serial_0(PH_1, PH_0, 256, 4);    // UART4
+BufferSerial serial_1(PG_2, PG_1, 256, 4);    // UART0
+BufferSerial serial_2(PC_11, PC_10, 256, 4);  // UART2
+#else
+BufferSerial serial_0(PH_1, PH_0);    // UART4
+BufferSerial serial_1(PG_2, PG_1);    // UART0
+BufferSerial serial_2(PC_11, PC_10);  // UART2
+#endif
 
-#elif defined (TARGET_NUMAKER_PFM_M453)
+#elif defined (TARGET_NUMAKER_PFM_M453) || defined(TARGET_NUMAKER_PFM_NANO130) || defined(TARGET_NUMAKER_PFM_M2351)
 #error The board has no Ethernet.
 
 #else
@@ -61,14 +73,12 @@
 #endif
 };
 
-/* UART port to output debug message */
-RawSerial output(USBTX, USBRX);             // UART3 on NuMaker-PFM-NUC472
 EthernetInterface eth;
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
 
 /* Declare the SD card as storage */
-NuSDBlockDevice bd;
+NuSDBlockDevice *bd = new NuSDBlockDevice();
 FATFileSystem fs("fs");
 bool SD_Card_Mounted = FALSE;
 
@@ -86,80 +96,92 @@
     unsigned char s_buf[256];
     int n_len = 0, n_index = 0;
     int s_len = 0, s_index = 0;
+    unsigned int eth_tx_count = 0;
     
     while(1)
     {   
         /*** Network to Serial ***/
         
-        if (n_len < 0 || n_len == n_index)
+        if (n_len == 0)
         {
             // net buffer is empty, try to get new data from network.
             n_len = psocket->recv(n_buf, sizeof(n_buf));
-            if (n_len == NSAPI_ERROR_WOULD_BLOCK)
+            if (n_len == 0)
             {
+                eth_tx_count += 3;
+            }
+            else if (n_len == NSAPI_ERROR_WOULD_BLOCK)
+            {
+                n_len = 0;
             }
             else if (n_len < 0)
             {
                 printf("Socket Recv Err (%d)\r\n", n_len);
-                psocket->close();
                 break;
             }
-            else
-            {
-                n_index = 0;
-            }
         }
         else
         {
-            // send data to serial port.
-            for(;n_index < n_len && pmap->pserial->writeable(); n_index++)
+            n_index += pmap->pserial->write(n_buf+n_index, n_len-n_index);
+            if (n_index == n_len)
             {
-                pmap->pserial->putc(n_buf[n_index]);
+                n_len = 0;
+                n_index = 0;
             }
         }
 
         /*** Serial to Network ***/
-        
+
+        // try to get more data from serial port
+#if MBED_MAJOR_VERSION <= 5        
+        for(; s_index < sizeof(s_buf) && pmap->pserial->readable(); s_index++)
+            s_buf[s_index] = pmap->pserial->getc();
+#else
         if (pmap->pserial->readable())
         {
-            // try to get more data from serial port
-            for(s_index = 0; s_index < sizeof(s_buf) && pmap->pserial->readable(); s_index++)
-                s_buf[s_index] = pmap->pserial->getc();
-            
-            // send all data to network.
-            if (s_index > 0)
+            s_len = pmap->pserial->read(s_buf+s_index, sizeof(s_buf)-s_index);
+            if (s_len > 0)
+                s_index += s_len;
+        }
+#endif
+        
+        if (s_index >= 240 || (s_index != 0 && ++eth_tx_count >= 5))
+        {
+            s_len = psocket->send(s_buf, s_index); 
+
+            if (s_len == NSAPI_ERROR_WOULD_BLOCK)
+            {
+                printf("Socket Send no block.\r\n");
+            }               
+            else if (s_len < 0)
             {
-                s_len = psocket->send(s_buf, s_index); 
-                if (s_len == NSAPI_ERROR_WOULD_BLOCK)
-                {
-                    printf("Socket Send no block.\r\n");
-                }               
-                else if (s_len < 0)
-                {
-                    printf("Socket Send Err (%d)\r\n", s_len);
-                    psocket->close();
-                    break;
-                }
-                else if (s_len != s_index)
-                {
-                    printf("Socket Send not complete.\r\n");
-                    psocket->close();
-                    break;
-                }
+                printf("Socket Send Err (%d)\r\n", s_len);
+                break;
             }
-        }
+            else // s_len >= s_index
+            {
+                unsigned int i;
+
+                // move remain data if existed.
+                for(i=0; s_len < s_index; i++, s_len++)
+                    s_buf[i] = s_buf[s_len];
+
+                s_index = i;
+                eth_tx_count = 0;
+            }
+        }       
     }
 }   
-
+   
 void bridge_net_client(S_PORT_CONFIG *pmap)
 {
     TCPSocket socket;
-    SocketAddress server_address;
+    SocketAddress server_ipaddr;
     nsapi_error_t err;
 
     printf("Thread %x in TCP client mode.\r\n", (unsigned int)pmap);
 
-    if ((err=socket.open(&eth)) < 0)
+    if ((err=socket.open(&eth)) != NSAPI_ERROR_OK)
     {
         printf("TCP socket can't open (%d)(%x).\r\n", err, (unsigned int)pmap);
         return;
@@ -168,31 +190,35 @@
     printf("Connecting server %s:%d ...\r\n", pmap->server_addr, pmap->server_port);
     while(1)
     {
-        if ((err=socket.connect(pmap->server_addr, pmap->server_port)) >= 0)
+        server_ipaddr.set_ip_address(pmap->server_addr);
+        server_ipaddr.set_port(pmap->server_port);
+        if ((err=socket.connect(server_ipaddr)) >= 0)
+        {
+            printf("\r\nConnected.");
             break;
+        }
     }
     
-    printf("\r\nConnected.");
-
     socket.set_timeout(1);
     exchange_data(pmap, &socket);
+    socket.close();
 }
 
 void bridge_net_server(S_PORT_CONFIG *pmap)
 {
-    TCPServer tcp_server;
-    TCPSocket client_socket;
-    SocketAddress client_address;
+    TCPSocket tcp_server;
+    TCPSocket *client_socket;
+    SocketAddress client_ipaddr;
     nsapi_error_t err;
     
     printf("Thread %x in TCP server mode.\r\n", (unsigned int)pmap);
     
-    if ((err=tcp_server.open(&eth)) < 0)
+    if ((err=tcp_server.open(&eth)) != NSAPI_ERROR_OK)
     {
         printf("TCP server can't open (%d)(%x).\r\n", err, (unsigned int)pmap);
         return;
     }
-    if ((err=tcp_server.bind(eth.get_ip_address(), pmap->port)) < 0)
+    if ((err=tcp_server.bind(pmap->port)) != NSAPI_ERROR_OK)
     {
         printf("TCP server can't bind address and port (%d)(%x).\r\n", err, (unsigned int)pmap);
         return;
@@ -203,36 +229,46 @@
         return;
     }
 
-    client_socket.set_timeout(1);
-
     while(1)
     {   
-        if ((err=tcp_server.accept(&client_socket, &client_address)) < 0)
+        client_socket = tcp_server.accept(&err);
+        if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_WOULD_BLOCK)
         {
             printf("TCP server fail to accept connection (%d)(%x).\r\n", err, (unsigned int)pmap);
             return;
         }
-
-        printf("Connect (%d) from %s:%d ...\r\n", pmap->port, client_address.get_ip_address(), client_address.get_port());
-
-        exchange_data(pmap, &client_socket);        
+        else
+        {
+            client_socket->getpeername(&client_ipaddr);
+            printf("Connect (%d) from %s:%d ...\r\n", pmap->port, client_ipaddr.get_ip_address(), client_ipaddr.get_port());
+  
+            client_socket->set_timeout(1);
+            exchange_data(pmap, client_socket);
+            client_socket->close();
+        }
     }
 }   
 
 int main()
 {
-    /* Set the console baud-rate */
-    output.baud(115200);
-    printf("\r\nmbed OS version is %d.\r\n", MBED_VERSION);
+    SocketAddress ip_addr;
+    SocketAddress ip_mask;
+    SocketAddress ip_gwaddr;
+    
+#ifdef MBED_MAJOR_VERSION
+    printf("Mbed OS version %d.%d.%d\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
+#endif
     printf("Start Serial-to-Ethernet...\r\n");
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
 
     /* Restore configuration from SD card */
     
-    SD_Card_Mounted = (fs.mount(&bd) >= 0);
+    printf("Mounting SD card...\r\n");
+    SD_Card_Mounted = (fs.mount(bd) == 0);
     if (SD_Card_Mounted)
     {
+        printf("SD card mounted. Read configuration file...\r\n");
         FILE *fd = fopen(SER_CONFIG_FILE, "r");
         if (fd != NULL)
         {
@@ -276,6 +312,7 @@
 
 #endif
     
+    /* Configure serial ports */
     printf("Configure UART ports...\r\n");
     for(int i=0; i<MAX_UART_PORTS; i++)
     {
@@ -283,21 +320,27 @@
         port_config[i].pserial->format(port_config[i].data, port_config[i].parity, port_config[i].stop);
     }
     
+    /* Configure network IP address */
     if (net_config.mode == IP_STATIC_MODE)
     {
         printf("Start Ethernet in Static mode.\r\n");
         eth.disconnect();
-        ((NetworkInterface *)&eth)->set_network(net_config.ip, net_config.mask, net_config.gateway);
+        
+        ip_addr.set_ip_address(net_config.ip);
+        ip_mask.set_ip_address(net_config.mask);
+        ip_gwaddr.set_ip_address(net_config.gateway);
+        ((NetworkInterface *)&eth)->set_network(ip_addr, ip_mask, ip_gwaddr);
     }
     else
         printf("Start Ethernet in DHCP mode.\r\n");
     
     eth.connect();
-    printf("IP Address is %s\r\n", eth.get_ip_address());
-    
+    eth.get_ip_address(&ip_addr);
+    printf("IP Address is %s\r\n", ip_addr.get_ip_address());
+
     Thread thread[MAX_UART_PORTS];
     
-    // Folk thread for each port
+    /* Folk thread for each serial port */  
     for(int i=0; i<MAX_UART_PORTS; i++)
     {
         if (port_config[i].mode == NET_SERVER_MODE)
@@ -310,7 +353,7 @@
         }
     }
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
     
     /*** main thread to be a web server for configuration ***/
     start_httpd();
--- a/mbed-os.lib	Thu Apr 19 14:03:33 2018 +0800
+++ b/mbed-os.lib	Tue Mar 02 10:09:10 2021 +0800
@@ -1,1 +1,1 @@
-https://github.com/ARMmbed/mbed-os/#f9ee4e849f8cbd64f1ec5fdd4ad256585a208360
+https://github.com/ARMmbed/mbed-os/#b114a9c878519d6489ac3426697196bbea34c8ea
--- a/ste_config.h	Thu Apr 19 14:03:33 2018 +0800
+++ b/ste_config.h	Tue Mar 02 10:09:10 2021 +0800
@@ -10,37 +10,44 @@
 
 #include "mbed.h"
 #include "EthernetInterface.h"
-#include "TCPSocket.h"
-#include "TCPServer.h"
-#include "BufferedSerial.h"
 #include "FATFileSystem.h"
 #include "NuSDBlockDevice.h"
 
 
-//#define ENABLE_WEB_CONFIG             // Define this to active a simple web sever for
-                                        // UART ports and Ethernet port parameters configuration.
+#include "BufferSerial.h"
+
 
-/* Maximum UART ports supported */
+/* A simple web server for network and UART configuration
+   0: Disable the web server.
+   1: Enable the web server
+*/
+#define ENABLE_WEB_CONFIG   1
+
+/* Maximum UART ports supported.
+   Must define enough tuples of mapping table "port_config[]" in main.c
+*/
 #define MAX_UART_PORTS      2
 
 /* Default UART baud */
 #define DEFAULT_UART_BAUD   115200
 
 /* Network base port number to listen.
-   So the base port maps to the 1st UART port,
-   the (base port + 1) maps to the 2nd UART port, etc. */
+   The base port maps to the 1st UART port,
+   the (base port + 1) maps to the 2nd UART port, etc.
+*/
 #define NET_PORT_BASE   10001
 
-/* Path and Filename of configuration files */
+/* Files in SD card to store settings via web configuration */
 #define SER_CONFIG_FILE "/fs/STE_SER.TXT"   // for serial ports
 #define NET_CONFIG_FILE "/fs/STE_NET.TXT"   // for network
 
-/* Maximum size of server address */
+/* Maximum size of server domain name or address for web configuration */
 #define MAX_SERVER_ADDRESS_SIZE     63
 
-/* Maximum size of IP address */
+/* Maximum size of IP address for web configuration */
 #define MAX_IPV4_ADDRESS_SIZE       15
 
+
 /* Functions and global variables declaration. */
 
 typedef enum {
@@ -62,8 +69,8 @@
 
 typedef struct {
     E_NetMode       mode;       // Network server or client mode
-    int             port;       // Network port number
-    BufferedSerial  *pserial;   // UART number
+    int             port;       // Network port number (Server mode)
+    BufferSerial  *pserial;   // UART number
     int             baud;       // UART baud
     int             data;       // UART data bits
     int             stop;       // UART stop bits
@@ -72,7 +79,7 @@
     unsigned short  server_port;    // Server port for TCP client mode
 } S_PORT_CONFIG;
 
-extern RawSerial output;        // for debug output
+//extern RawSerial output;        // for debug output
 extern EthernetInterface eth;
 extern S_PORT_CONFIG port_config[MAX_UART_PORTS];
 extern S_NET_CONFIG net_config;
--- a/uweb_server.cpp	Thu Apr 19 14:03:33 2018 +0800
+++ b/uweb_server.cpp	Tue Mar 02 10:09:10 2021 +0800
@@ -5,11 +5,11 @@
  * 
  *
  */
- 
+  
 #include <string.h>
 #include "ste_config.h"
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
 
 #define PAGE_HEADER \
 "<html><head>\r\n" \
@@ -408,10 +408,10 @@
     send_web_body(socket, 4);
 
     printf("Restart system...\r\n");
-    wait(1);    // wait 1 second
+    ThisThread::sleep_for(1000);    // wait 1 second
 //  SYS_ResetCPU();
     SYS_ResetChip();
-    wait(100);
+    ThisThread::sleep_for(100000);
 }
 
 void process_http_resetconf_html(TCPSocket *socket, char *pbuf)
@@ -497,16 +497,17 @@
 
 void start_httpd(void)
 {
-    TCPServer http_server;
-    TCPSocket http_socket;
+    TCPSocket http_server;
+    TCPSocket *http_socket;
     SocketAddress http_address;
+    nsapi_error_t err_t;
 
     if (http_server.open(&eth) < 0)
     {
-        printf("http server can't open.\r\n");
+        printf("http server can't be created.\r\n");
         return;
     }
-    if (http_server.bind(eth.get_ip_address(), 80) < 0)
+    if (http_server.bind(80) < 0)
     {
         printf("http server can't bind address and port.\r\n");
         return;
@@ -521,15 +522,17 @@
 
     while(1)
     {
-        if (http_server.accept(&http_socket, &http_address) < 0)
+        http_socket = http_server.accept(&err_t);
+        if (err_t < 0)
         {
             printf("http server fail to accept connection.\r\n");
             return;
         }
         
+        http_socket->getpeername(&http_address);
         printf("http from %s:%d ...\r\n", http_address.get_ip_address(), http_address.get_port());
-        process_http_request(&http_socket);
-        http_socket.close();
+        process_http_request(http_socket);
+        http_socket->close();
     }
 }