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:
Sat Nov 15 11:46:12 2014 +0000
Parent:
19:05934ee9ee67
Child:
21:fae96e0d6bb1
Commit message:
Added watchdog timer.; Config mode is looped forever.

Changed in this revision

Watchdog.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.bld 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Watchdog.lib	Sat Nov 15 11:46:12 2014 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/olympux/code/Watchdog/#38379e44fae3
--- a/main.cpp	Sat Oct 25 10:47:05 2014 +0000
+++ b/main.cpp	Sat Nov 15 11:46:12 2014 +0000
@@ -10,6 +10,7 @@
 #include "rtos.h"
 
 #include "my_eeprom_funcs.h"
+#include "Watchdog.h"
 
 
 //Debug is disabled by default
@@ -68,6 +69,10 @@
 //AnalogOut ano0(PA_8);
 //AnalogOut ano1(PA_15);
 
+// Watchdog
+Watchdog wdt;
+
+
 void update_digital_outputs(char* buf);
 void update_sending_frame(char* buf);
 
@@ -105,10 +110,10 @@
 //#define UDP_CLIENT
 #define NTP
 
-#define TCP_SERVER_WAIT_CLIENT_TIMEOUT     200
-#define TCP_SERVER_RECEIVE_TIMEOUT         2000
-#define TCP_CLIENT_RECEIVE_TIMEOUT         100
-#define UDP_SERVER_RECEIVE_TIMEOUT         200
+#define TCP_SERVER_WAIT_CLIENT_TIMEOUT     200 // timeout for local tcp server wait for a remote client
+#define TCP_SERVER_RECEIVE_TIMEOUT         2000 // timeout for local tcp server wait to receive from remote client
+#define TCP_CLIENT_RECEIVE_TIMEOUT         200 // timeout for local tcp client try to connect remote server
+#define UDP_SERVER_RECEIVE_TIMEOUT         100 // timeout for checking config command
 
 
 // TCP server function
@@ -219,22 +224,6 @@
 /*
 * Threads
 */
-void uart_thread(void const *args) {
-    message_t *p_message;
-    
-    while (true) {
-        osEvent evt = uart_queue.get();
-        if (evt.status == osEventMessage) {
-            p_message = (message_t*)evt.value.p;
-            uart_mutex.lock(); // mutex for stdio is not neccessary
-            //DBG("len=%d\n", p_message->len);
-            DBG("%s\n", p_message->msg);
-            uart_mutex.unlock();
-        }
-    }
-}
-
-
 // Timer thread for auto update
 void auto_update_timer_thread(void const* args) {
     bool update_flag = true;
@@ -247,6 +236,13 @@
 }
 
 
+// WDT reset
+void wdt_reset_thread(void const* args) {
+    while (true)
+        wdt.Service();
+}
+
+
 /*
 * Ethernet init
 */
@@ -341,29 +337,32 @@
 
 int main()
 {
-    message_t message;
     int n, ret;
     
-    Thread::wait(2000); // turn on delay
-    
+    Thread::wait(500); // turn on delay
+        
     /*
     * Configure
     */
     uart.baud(115200);
     DBG("\r\nStarting...");
-  
-    /*
-    * UI threads
-    */
-    Thread t1(uart_thread);
-    Thread t2(auto_update_timer_thread);    
+    
+    if (wdt.WatchdogCausedReset())
+        DBG("Watchdog caused reset.");
+    wdt.Configure(4);
     
     /*
     * FLASH
     */
     load_eeprom_network();
     load_eeprom_tcpserver();
-        
+    
+    /*
+    * UI threads
+    */
+    Thread t2(auto_update_timer_thread);
+    Thread t3(wdt_reset_thread);
+    
     /*
     * Ethernet
     */
@@ -373,10 +372,18 @@
         while (true) {};
     }
     
+    Thread::wait(2000); // turn on delay
 
 /*
-* TCP/UDP setup
+* UDP server
+* TCP server/client
 */
+#ifdef UDP_SERVER
+    ret = udp_server.bind(udp_server_local_port);
+    DBG("UDP server started (sock.bind = %d)...", ret);
+    udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
+#endif
+
 #ifdef TCP_SERVER
     tcp_server.bind(tcp_server_local_port);
     tcp_server.listen();
@@ -388,13 +395,6 @@
 
 #endif
     
-#ifdef UDP_SERVER
-    ret = udp_server.bind(udp_server_local_port);
-    DBG("UDP started (sock.bind = %d)", ret);
-    udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
-#endif
-
-
     /*
     * Network loop processor
     */
@@ -405,7 +405,7 @@
         if (auto_transmit_flag == 0xA5A5) {
             // connect to TCP server if required
             if (!tcp_sock.is_connected()) {
-                ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port);
+                ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port); // timeout is default in connect() in W5500.h
                 if (ret > -1) {
                     DBG("Successfully connected to %s on port %d", str_server_ip_addr, u16tcp_server_port);
                 }
@@ -440,7 +440,8 @@
 #ifdef TCP_SERVER
         // no tcp client connected
         //if ((u16enable_tcp_server == 0xA5A5) && (!tcp_client.is_connected())) {
-        if (!tcp_client.is_connected()) {
+        //if (!tcp_client.is_connected()) {
+        if (1) {
             // wait for client within timeout
             ret = tcp_server.accept(tcp_client);
             
@@ -458,116 +459,121 @@
                     DBG("TCP server received: %s", tcp_receiving_buffer);
                     process_received_tcp_data(tcp_receiving_buffer, n);
                 } // end loop if no data received within timeout
-                tcp_client.close();
             } // if client connected
+            tcp_client.close();
         } // if tcp server enabled && no client connected
 #endif
-    
-    
-    
-// ALWAYS ENABLED, ONLY FOR CONFIGRATION
+
 #ifdef UDP_SERVER
-        // wait for udp packet within timeout
         n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
-        if (n <= 0) continue;
-
-        // 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
-        switch (n) {
-            // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
-            // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
-            case QUERY_CMD_LENGTH:
-                // discovery command
-                if (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL) {
-                    char str[30];
-                    sprintf(str, "%s%s", DEVICE_ID, eth.getIPAddress());
-                    udp_server.sendTo(ep_udp_client, str, strlen(str));
-                } // NNIODS
-                else 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) {
+        if (n > 0) {
+            // if receive any config command, stay in config mode forever
+            DBG("Enabled configuration mode...");
+            DBG("!!! RESET when finished");
+            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
+                switch (n) {
+                    // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
+                    // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
+                    case QUERY_CMD_LENGTH:
+                        // discovery command
+                        if (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL) {
+                            char str[30];
+                            sprintf(str, "%s%s", DEVICE_ID, eth.getIPAddress());
+                            udp_server.sendTo(ep_udp_client, str, strlen(str));
+                        } // NNIODS
+                        else 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));
-                    }
+                            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));
+                            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;
+                        } // 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)
                 
-                DBG("Received TCP server configuration");
-                write_eeprom_tcpserver(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
-                break;
-            }
-            default:
-                break;
-        }
+                // 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 (1): config commands processor
+        } // udp config timeout?
 #endif
     } // network processor
 }
--- a/mbed.bld	Sat Oct 25 10:47:05 2014 +0000
+++ b/mbed.bld	Sat Nov 15 11:46:12 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89
\ No newline at end of file
--- a/readme.txt	Sat Oct 25 10:47:05 2014 +0000
+++ b/readme.txt	Sat Nov 15 11:46:12 2014 +0000
@@ -8,3 +8,8 @@
 
 v1.0 25/10/2014
     + Added: process many receiving frames in one tcp packet
+    + Bug: TCP server will reply with error #10061 if a previous tcp client connects and quickly disconnects.
+
+v1.1 15/11/2014
+    + Added: watchdog timer
+    + Modified: when received config data from udp, enter config mode forever