Webserver only w/o any other functions, single thread. Running on STM32F013+W5500

Dependencies:   NTPClient W5500Interface Watchdog device_configuration eeprom_flash mbed-rpc-nucleo mbed-rtos mbed

Fork of F103-Serial-to-Ethernet by Chau Vo

Files at this revision

API Documentation at this revision

Comitter:
olympux
Date:
Wed Dec 24 13:23:33 2014 +0000
Parent:
25:48dd18cc147c
Child:
27:22f289beceb8
Commit message:
Rearrange source code. Use official mbed-rtos

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
readme.txt Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Sun Dec 07 00:18:07 2014 +0000
+++ b/main.cpp	Wed Dec 24 13:23:33 2014 +0000
@@ -72,10 +72,6 @@
 Watchdog wdt;
 
 
-void update_digital_outputs(char* buf);
-void update_sending_frame(char* buf);
-
-
 
 /*
 * EEPROM section
@@ -161,9 +157,9 @@
 
 #define RECEIVING_PROTOCOL_LENGTH           58
 #define SENDING_PROTOCOL_LENGTH             39
-#define QUERY_CMD_LENGTH                    6
+#define QUERY_NETWORK_CONFIG_CMD_LENGTH     6
 #define SET_NETWORK_CONFIG_CMD_LENGTH       19
-#define UPDATE_TCP_SERVER_INFO_CMD_LENGTH   12
+#define UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH   12
 
 #define QUERY_DISCOVERY_CMD                 "NNIODS"
 #define QUERY_IP_CMD                        "NNIOIP"
@@ -218,6 +214,15 @@
 Queue<bool, 1> auto_update_queue;
 
 
+
+// Prototypes
+int ethernet_init(void);
+void process_control_command(char* received_buffer, int len);
+void process_config_command(char* received_buffer, int len);
+void update_digital_outputs(char* buf);
+void update_sending_frame(char* buf);
+
+
 /*
 * Threads
 */
@@ -240,118 +245,6 @@
 }
 
 
-/*
-* Ethernet init
-*/
-int ethernet_init(void) {
-    int dhcp_ret, ret;
-    
-    DBG("Start initialising ethernet");
-    
-    // if not configured, try dhcp
-    dhcp_ret = -1;
-    if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
-        DBG("Connecting DHCP server...");
-        dhcp_ret = eth.init(u8mac);
-        if (dhcp_ret == 0)
-            dhcp_ret = eth.connect();
-    }
-    
-    if (dhcp_ret != 0) {
-        DBG("No DHCP, load static IP configuration");
-        ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
-    } else {
-        snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
-        snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
-        snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
-        ret = 0;
-    }
-
-    if (ret == 0) {
-        DBG("Initialized, MAC: %s", eth.getMACAddress());
-    } else {
-        ERR("Error eth.init() - ret = %d", ret);
-        return -1;
-    }
-
-    ret = eth.connect();
-    if (!ret) {
-        DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
-    } else {
-        ERR("Error eth.connect() - ret = %d", ret);
-        return -1;
-    }
-    
-    return 0;
-}
-
-
-/*
-* Procedure to process receiving protocol
-*/
-void process_received_net_data(char* received_buffer, int len)
-{
-    char* received_frame;
-    int pos;
-    
-    while (len >= RECEIVING_PROTOCOL_LENGTH) {
-        // find device ID
-        DBG("Checking device ID...");
-        char* id = strstr(received_buffer, DEVICE_ID);
-        if (id == NULL) {
-            DBG("No device ID found");
-            break;
-        }
-        pos = id - received_buffer;
-        DBG("Found a frame at %d", pos);
-        
-        // extract this frame
-        received_frame = &received_buffer[pos];
-        // calculate the rest
-        received_buffer = &received_buffer[pos + RECEIVING_PROTOCOL_LENGTH];
-        len -= RECEIVING_PROTOCOL_LENGTH;
-        
-        // process this received frame
-        // firstly, update outputs if required
-        // digital outputs
-        if (received_frame[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-            DBG("Update digital outputs");
-            char str_dout[9];
-            memcpy(str_dout, &received_frame[RECEIVING_PROTOCOL_DO_POS], 8);
-            str_dout[8] = '\0';
-            update_digital_outputs(str_dout);
-        }
-        // analog output 0
-        if (received_frame[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-            DBG("Update analog output 0");
-        }
-        // analog output 1
-        if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-            DBG("Update analog output 1");
-        }
-        // UART
-        if (received_frame[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-            DBG("UART data: ");
-            char str_uart[33];
-            memcpy(str_uart, &received_frame[RECEIVING_PROTOCOL_UART_POS], 32);
-            str_uart[32] = '\0';
-            uart.printf("%s\r\n", str_uart);
-        }
-                            
-        // then, check query status command and sending protocol if required
-        if (received_frame[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
-            DBG("Requested to send device status through TCP");
-            // sending protocol
-            update_sending_frame(tcp_sending_buffer);
-            tcp_client.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
-            DBG("Sent");
-        }
-    }
-    
-    DBG("Successful");
-}
-
-
 int main()
 {
     int n, ret;
@@ -446,7 +339,7 @@
                 if (n > 0) {
                     // got some data, test it
                     DBG("TCP client received %d bytes: %s", n, tcp_receiving_buffer);
-                    process_received_net_data(tcp_receiving_buffer, n);
+                    process_control_command(tcp_receiving_buffer, n);
                 }
             }
         } // if tcp client enabled && auto transmit
@@ -474,7 +367,7 @@
                     
                     // got some data, test it
                     DBG("TCP server received: %s", tcp_receiving_buffer);
-                    process_received_net_data(tcp_receiving_buffer, n);
+                    process_control_command(tcp_receiving_buffer, n);
                 } // end loop if no data received within timeout
             } // if client connected
             tcp_client.close();
@@ -489,134 +382,252 @@
         // check to see if it is a query command
         // if yes, is it a discovery command or an ip query to enter config mode
         config_mode_flag = false;
-        if ((n == QUERY_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) {
+        if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) {
             DBG("Received discovery command");
             char str[50];
             sprintf(str, "%s%s%s", DEVICE_ID, eth.getMACAddress(), eth.getIPAddress());
             udp_server.sendTo(ep_udp_client, str, strlen(str));
         } // NNIODS
-        else if ((n == QUERY_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) {
+        else if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) {
             config_mode_flag = true;
             DBG("Enabled configuration mode...");
             DBG("!!! RESET when finished");
-        }
+        } // NNIOIP
         
+        // if received NNIOIP, enter config mode
         if (config_mode_flag) {
-            // if receive any config command, stay in config mode forever
-            while (n > 0) {
+            while (n > 0)
+            {
                 // got some data, test it
                 DBG("UDP received (%s) from (%s) and port (%d)", udp_receiving_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
-                
-                // process received data
-                // a configuration command always starts with NN
-                if ((udp_receiving_buffer[0] == 'N') && (udp_receiving_buffer[1] == 'N')) {
-                    switch (n) {
-                        // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
-                        // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
-                        case QUERY_CMD_LENGTH:
-                            if (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL) {
-                                udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
-                            } // NNIOIP
-                            else if (strstr(udp_receiving_buffer, QUERY_SUBNET_CMD) != NULL) {
-                                udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
-                            } // NNIOSN
-                            else if (strstr(udp_receiving_buffer, QUERY_GATEWAY_CMD) != NULL) {
-                                udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
-                            } // NNIOGW
-                            else if (strstr(udp_receiving_buffer, QUERY_MAC_CMD) != NULL) {
-                                udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress()));
-                            } // NNIOMC
-                            // ask for TCP server port
-                            else if (strstr(udp_receiving_buffer, QUERY_TCP_PORT_CMD) != NULL) {
-                                char port[5];
-                                sprintf(port, "%5d", tcp_server_local_port);
-                                udp_server.sendTo(ep_udp_client, port, strlen(port));
-                            } // NNIOTP
-                            // ask for UDP server port
-                            else if (strstr(udp_receiving_buffer, QUERY_UDP_PORT_CMD) != NULL) {
-                                char port[5];
-                                sprintf(port, "%5d", udp_server_local_port);
-                                udp_server.sendTo(ep_udp_client, port, strlen(port));
-                            } // NNIOUP
-                            else if (strstr(udp_receiving_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
-    #ifdef NTP
-                                char str_time[50];
-                                
-                                DBG("Trying to update time...");
-                                if (ntp.setTime("0.pool.ntp.org") == 0) {
-                                    DBG("Set time successfully");
-                                    time_t ctTime;
-                                    ctTime = time(NULL);
-                                    
-                                    DBG("Time is set to (UTC): %s", ctime(&ctTime));
-                                    sprintf(str_time, "%s", ctime(&ctTime));
-                                    udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
-                                }
-                                else {
-                                    WARN("Error");
-                                    sprintf(str_time, "ERR");
-                                    udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
-                                }
-    #elif
-                                WARN("NTP disabled");
-                                sprintf(str_time, "DIS");
-                                udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
-    #endif
-                            } // NNIOTM
-            
-                            break;
-                        // length = 19, SET NETWORK CONFIGURATION
-                        // Format: 4E 4E 49 4F      C0 A8 00 78        FF FF FF 00            C0 A8 00 01      00 00 01
-                        //        (NNIO;            IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
-                        case SET_NETWORK_CONFIG_CMD_LENGTH: {
-                            // check device id
-                            char* id = strstr(udp_receiving_buffer, DEVICE_ID);
-                            if (id == NULL)
-                                break;
-                            else if ((id - udp_receiving_buffer) > 0)
-                                break;
-            
-                            DBG("Received user configuration");
-                            write_eeprom_network(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
-                            break;
-                        }
-                        // length = 12, SET TCP SERVER CONFIGURATION
-                        // auto update & its time period, TCP server configuration (IP & port)
-                        // Format: 4E 4E 49 4F   'Y'     01   C0 A8 00 09   E0 2E (LSB MSB)
-                        //         NNIO          Auto   1s   192.168.0.9   12000
-                        case UPDATE_TCP_SERVER_INFO_CMD_LENGTH: {
-                            char* id = strstr(udp_receiving_buffer, DEVICE_ID);
-                            if (id == NULL)
-                                break;
-                            else if ((id - udp_receiving_buffer) > 0)
-                                break;
-                            
-                            DBG("Received TCP server configuration");
-                            write_eeprom_tcpserver(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
-                            break;
-                        }
-                        default:
-                            break;
-                    } // switch (n), check configuration command length
-                } // if starts with NN, a config command
-                else { // if not a command, check to see if it is a 6-byte data package
-                    // process 6-byte data package
-                }
-                
+                process_config_command(udp_receiving_buffer, n);
                 // wait to receive new config command
                 udp_server.set_blocking(true);
                 n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
-            } // while (n > 0): config commands processor
+            } // while (n > 0), config loop
         } // if (config_mode_flag)
-        else if (n > 0) { // process other data packages sent using UDP
-            process_received_net_data(udp_receiving_buffer, n);
+        else if (n > 0) { // process control packages sent using UDP
+            process_control_command(udp_receiving_buffer, n);
         }
 #endif
     } // network processor
 }
 
+
+void process_config_command(char* received_buffer, int len)
+{
+    // process received data
+    // a configuration command always starts with NN
+    if ((received_buffer[0] == 'N') && (received_buffer[1] == 'N')) {
+        switch (len) {
+            // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
+            // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
+            case QUERY_NETWORK_CONFIG_CMD_LENGTH:
+                if (strstr(received_buffer, QUERY_IP_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
+                } // NNIOIP
+                else if (strstr(received_buffer, QUERY_SUBNET_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
+                } // NNIOSN
+                else if (strstr(received_buffer, QUERY_GATEWAY_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
+                } // NNIOGW
+                else if (strstr(received_buffer, QUERY_MAC_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress()));
+                } // NNIOMC
+                // ask for TCP server port
+                else if (strstr(received_buffer, QUERY_TCP_PORT_CMD) != NULL) {
+                    char port[5];
+                    sprintf(port, "%5d", tcp_server_local_port);
+                    udp_server.sendTo(ep_udp_client, port, strlen(port));
+                } // NNIOTP
+                // ask for UDP server port
+                else if (strstr(received_buffer, QUERY_UDP_PORT_CMD) != NULL) {
+                    char port[5];
+                    sprintf(port, "%5d", udp_server_local_port);
+                    udp_server.sendTo(ep_udp_client, port, strlen(port));
+                } // NNIOUP
+                else if (strstr(received_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
+#ifdef NTP
+                    char str_time[50];
+
+                    DBG("Trying to update time...");
+                    if (ntp.setTime("0.pool.ntp.org") == 0) {
+                        DBG("Set time successfully");
+                        time_t ctTime;
+                        ctTime = time(NULL);
+
+                        DBG("Time is set to (UTC): %s", ctime(&ctTime));
+                        sprintf(str_time, "%s", ctime(&ctTime));
+                        udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
+                    } else {
+                        WARN("Error");
+                        sprintf(str_time, "ERR");
+                        udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
+                    }
+#elif
+                    WARN("NTP disabled");
+                    sprintf(str_time, "DIS");
+                    udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
+#endif
+                } // NNIOTM
+
+                break;
+                // length = 19, SET NETWORK CONFIGURATION
+                // Format: 4E 4E 49 4F      C0 A8 00 78        FF FF FF 00            C0 A8 00 01      00 00 01
+                //        (NNIO;            IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
+            case SET_NETWORK_CONFIG_CMD_LENGTH: {
+                // check device id
+                char* id = strstr(received_buffer, DEVICE_ID);
+                if (id == NULL)
+                    break;
+                else if ((id - received_buffer) > 0)
+                    break;
+
+                DBG("Received user configuration");
+                write_eeprom_network(&received_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
+                break;
+            }
+            // length = 12, SET TCP SERVER CONFIGURATION
+            // auto update & its time period, TCP server configuration (IP & port)
+            // Format: 4E 4E 49 4F   'Y'     01   C0 A8 00 09   E0 2E (LSB MSB)
+            //         NNIO          Auto    1s   192.168.0.9   12000
+            case UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH: {
+                char* id = strstr(received_buffer, DEVICE_ID);
+                if (id == NULL)
+                    break;
+                else if ((id - received_buffer) > 0)
+                    break;
+
+                DBG("Received TCP server configuration");
+                write_eeprom_tcpserver(&received_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
+                break;
+            }
+            default:
+                break;
+        } // switch (n), check configuration command length
+    } // if starts with NN, a config command
+    else { // if not a command, check to see if it is a 6-byte data package
+        // process 6-byte data package
+    }
+}
+
 /*
-* Update digital outputs following receiving frame from TCP client
+* Procedure to process receiving protocol, which includes command to control outputs
+*/
+void process_control_command(char* received_buffer, int len)
+{
+    char* received_frame;
+    int pos;
+    
+    while (len >= RECEIVING_PROTOCOL_LENGTH) {
+        // find device ID
+        DBG("Checking device ID...");
+        char* id = strstr(received_buffer, DEVICE_ID);
+        if (id == NULL) {
+            DBG("No device ID found");
+            break;
+        }
+        pos = id - received_buffer;
+        DBG("Found a frame at %d", pos);
+        
+        // extract this frame
+        received_frame = &received_buffer[pos];
+        // calculate the rest
+        received_buffer = &received_buffer[pos + RECEIVING_PROTOCOL_LENGTH];
+        len -= RECEIVING_PROTOCOL_LENGTH;
+        
+        // process this received frame
+        // firstly, update outputs if required
+        // digital outputs
+        if (received_frame[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update digital outputs");
+            char str_dout[9];
+            memcpy(str_dout, &received_frame[RECEIVING_PROTOCOL_DO_POS], 8);
+            str_dout[8] = '\0';
+            update_digital_outputs(str_dout);
+        }
+        // analog output 0
+        if (received_frame[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update analog output 0");
+            //TODO Update analog output
+        }
+        // analog output 1
+        if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update analog output 1");
+            //TODO Update analog output
+        }
+        // UART
+        if (received_frame[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("UART data: ");
+            char str_uart[33];
+            memcpy(str_uart, &received_frame[RECEIVING_PROTOCOL_UART_POS], 32);
+            str_uart[32] = '\0';
+            uart.printf("%s\r\n", str_uart);
+        }
+                            
+        // then, check query status command and sending protocol if required
+        if (received_frame[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
+            DBG("Requested to send device status through TCP");
+            // sending protocol
+            update_sending_frame(tcp_sending_buffer);
+            tcp_client.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
+            DBG("Sent");
+        }
+    }
+    
+    DBG("Successful");
+}
+
+
+/*
+* W5500 Ethernet init
+*/
+int ethernet_init(void) {
+    int dhcp_ret, ret;
+    
+    DBG("Start initialising ethernet");
+    
+    // if not configured, try dhcp
+    dhcp_ret = -1;
+    if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
+        DBG("Connecting DHCP server...");
+        dhcp_ret = eth.init(u8mac);
+        if (dhcp_ret == 0)
+            dhcp_ret = eth.connect();
+    }
+    
+    if (dhcp_ret != 0) {
+        DBG("No DHCP, load static IP configuration");
+        ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
+    } else {
+        snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
+        snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
+        snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
+        ret = 0;
+    }
+
+    if (ret == 0) {
+        DBG("Initialized, MAC: %s", eth.getMACAddress());
+    } else {
+        ERR("Error eth.init() - ret = %d", ret);
+        return -1;
+    }
+
+    ret = eth.connect();
+    if (!ret) {
+        DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
+    } else {
+        ERR("Error eth.connect() - ret = %d", ret);
+        return -1;
+    }
+    
+    return 0;
+}
+
+
+/*
+* Update digital outputs according to receiving protocol
 */
 void update_digital_outputs(char* buf) {
     DBG("Digital outputs: %s", buf);
@@ -631,6 +642,9 @@
     dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0;
 }
 
+/*
+* Prepare a frame for sending protocol, which includes status of I/Os
+*/
 void update_sending_frame(char* buf) {
     memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_ID, 4); // device id
     memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);
--- a/mbed-rtos.lib	Sun Dec 07 00:18:07 2014 +0000
+++ b/mbed-rtos.lib	Wed Dec 24 13:23:33 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/olympux/code/mbed-rtos/#fd9580752759
+http://developer.mbed.org/users/mbed_official/code/mbed-rtos/#13a25134ac60
--- a/readme.txt	Sun Dec 07 00:18:07 2014 +0000
+++ b/readme.txt	Wed Dec 24 13:23:33 2014 +0000
@@ -1,3 +1,16 @@
+#NNIO Command and Configuration Processors
+
+This version is forked from F103_NNIO git rev25:48dd18cc147c, which is used for running demos.
+It intends to separate command processor and method to receive commands.
+
+v2.0 24/12/2014
+    + Use official mbed-rtos.
+
+
+
+
+
+
 Features
 0. Wait for 2s after resetting for ethernet to work.
 1. When auto update enabled and no TCP server is running, module will try to connect to server which results in a timeout every 15s.