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

Committer:
olympux
Date:
Thu Jun 16 19:22:36 2016 +0000
Revision:
42:d0ff08711ca5
Parent:
41:a50a534a2fbb
Child:
43:48ca8c6f6f49
Update HTML and add RPC variables for configuration

Who changed what in which revision?

UserRevisionLine numberNew contents of line
olympux 0:c2eac797face 1 #include "mbed.h"
olympux 27:22f289beceb8 2 #include "rtos.h"
olympux 27:22f289beceb8 3 #include "mbed_rpc.h"
olympux 27:22f289beceb8 4 #include "Arguments.h"
olympux 27:22f289beceb8 5
olympux 12:7c152c0ca4d8 6 #include "eeprom.h"
olympux 0:c2eac797face 7 #include "EthernetInterface.h"
olympux 9:d2534ecf88c6 8 #include "NTPClient.h"
olympux 0:c2eac797face 9
olympux 12:7c152c0ca4d8 10 #include "my_eeprom_funcs.h"
olympux 20:71c7950fdd91 11 #include "Watchdog.h"
olympux 12:7c152c0ca4d8 12
olympux 40:c966abbe2d62 13 #include "RPCCommand.h"
olympux 40:c966abbe2d62 14 #include "HTTPServer.h"
olympux 40:c966abbe2d62 15 #include "Formatter.h"
olympux 40:c966abbe2d62 16 #include "RequestHandler.h"
olympux 40:c966abbe2d62 17 #include "RPCType.h"
olympux 40:c966abbe2d62 18
olympux 40:c966abbe2d62 19 #define SERVER_PORT 80
olympux 40:c966abbe2d62 20
olympux 0:c2eac797face 21
olympux 42:d0ff08711ca5 22 /*
olympux 42:d0ff08711ca5 23 * Debug option
olympux 31:2e4b6de6c2f3 24 */
olympux 25:48dd18cc147c 25 #if 1
olympux 16:84a5bf7285d0 26 //Enable debug
olympux 16:84a5bf7285d0 27 #include <cstdio>
olympux 31:2e4b6de6c2f3 28 #define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__);
olympux 31:2e4b6de6c2f3 29 #define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__);
olympux 31:2e4b6de6c2f3 30 #define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__);
olympux 16:84a5bf7285d0 31 #else
olympux 16:84a5bf7285d0 32 //Disable debug
olympux 31:2e4b6de6c2f3 33 #define DBG(x, ...)
olympux 16:84a5bf7285d0 34 #define WARN(x, ...)
olympux 31:2e4b6de6c2f3 35 #define ERR(x, ...)
olympux 16:84a5bf7285d0 36 #endif
olympux 16:84a5bf7285d0 37
olympux 16:84a5bf7285d0 38
olympux 2:18f10e7209f4 39 /*
olympux 2:18f10e7209f4 40 * Hardware defines
olympux 0:c2eac797face 41 */
olympux 9:d2534ecf88c6 42 // Ethernet
olympux 0:c2eac797face 43 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
olympux 11:709f90a3b599 44 EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset
olympux 40:c966abbe2d62 45 int ethernet_init(void);
olympux 30:15e23257e786 46
olympux 30:15e23257e786 47 /*
olympux 30:15e23257e786 48 * EEPROM section
olympux 30:15e23257e786 49 */
olympux 30:15e23257e786 50 // Virtual address defined by the user: 0xFFFF value is prohibited
olympux 30:15e23257e786 51 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
olympux 30:15e23257e786 52 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
olympux 30:15e23257e786 53 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
olympux 30:15e23257e786 54 0x4212, // TCP server port, not used
olympux 30:15e23257e786 55 0x5212, // UDP server port, not used
olympux 42:d0ff08711ca5 56 0x8888, // 1st run? 0xA5A5 = static IP has been configured
olympux 30:15e23257e786 57 0x6212, 0x6313, 0x6414, // MAC
olympux 31:2e4b6de6c2f3 58
olympux 30:15e23257e786 59 // this section is for the TCP server that this device connects to in TCP client mode
olympux 30:15e23257e786 60 0x7212, 0x7313, // 0xA5A5 = auto transmit status, time period
olympux 30:15e23257e786 61 0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address
olympux 30:15e23257e786 62 0x9212, // TCP server port
olympux 31:2e4b6de6c2f3 63
olympux 30:15e23257e786 64 // this section is for selecting protocol, not used
olympux 30:15e23257e786 65 0xA212, // 0xA5A5 = enable TCP server
olympux 30:15e23257e786 66 0xA313, // 0xA5A5 = eanble TCP client
olympux 42:d0ff08711ca5 67 0xA414 // 0xA5A5 = enable UDP server, always enabled for configuration
olympux 31:2e4b6de6c2f3 68 };
olympux 31:2e4b6de6c2f3 69
olympux 30:15e23257e786 70
olympux 30:15e23257e786 71 /*
olympux 42:d0ff08711ca5 72 * Variables for network configuration, TCP server
olympux 42:d0ff08711ca5 73 */
olympux 42:d0ff08711ca5 74 // Device configuration
olympux 42:d0ff08711ca5 75 uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4], u16mac_addr[3]; // 16-bits, directly loaded from eeprom
olympux 42:d0ff08711ca5 76 char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16], str_mac_addr[16]; // for printf and RPC, converted from 16-bits u16ip_xxx
olympux 42:d0ff08711ca5 77 uint8_t u8ip_addr[4];// keep ip address in 8-bits
olympux 42:d0ff08711ca5 78 uint16_t configured_ip = 0; // flag indicates a static ip has been configured 0xA5A5
olympux 42:d0ff08711ca5 79 uint8_t u8mac[6]; // mac in 8-bits
olympux 30:15e23257e786 80
olympux 42:d0ff08711ca5 81 // TCP/UDP server
olympux 42:d0ff08711ca5 82 uint16_t tcp_server_local_port = 10000; // change to 7000 if internet required
olympux 42:d0ff08711ca5 83 uint16_t udp_server_local_port = 11000;
olympux 30:15e23257e786 84
olympux 42:d0ff08711ca5 85 // TCP client
olympux 42:d0ff08711ca5 86 // this section is used to set the TCP server that this device connects to in TCP client mode.
olympux 42:d0ff08711ca5 87 // this device will update its status to the server every transmit_time_period.
olympux 30:15e23257e786 88 uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s
olympux 30:15e23257e786 89 uint16_t u16server_ip_addr[4]; // directly loaded from eeprom
olympux 30:15e23257e786 90 uint8_t u8server_ip_addr[4]; // server ip address in 8-bits
olympux 30:15e23257e786 91 char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr
olympux 30:15e23257e786 92 uint16_t u16tcp_server_port; // directly loaded from eeprom
olympux 42:d0ff08711ca5 93 uint16_t u16enable_tcp_server, u16enable_tcp_client;// flags for enabling TCP client or TCP server
olympux 42:d0ff08711ca5 94
olympux 42:d0ff08711ca5 95 // Corresponding RPC variables
olympux 42:d0ff08711ca5 96 RPCVariable<char*> rpcIPAddress(str_ip_addr, 16, "ipaddr");
olympux 42:d0ff08711ca5 97 RPCVariable<char*> rpcSubnet(str_ip_subnet, 16, "subnet");
olympux 42:d0ff08711ca5 98 RPCVariable<char*> rpcGateway(str_ip_gateway, 16, "gateway");
olympux 42:d0ff08711ca5 99 RPCVariable<char*> rpcMac(str_mac_addr, 16, "mac");
olympux 42:d0ff08711ca5 100 RPCVariable<unsigned short> rpcLocalTCPServerPort(&tcp_server_local_port, "localtcpserverport");
olympux 42:d0ff08711ca5 101 RPCVariable<unsigned short> rpcLocalUDPPort(&udp_server_local_port, "localudpport");
olympux 42:d0ff08711ca5 102 RPCVariable<unsigned short> rpcEnableTCPServer(&u16enable_tcp_server, "enabletcpserver");
olympux 30:15e23257e786 103
olympux 30:15e23257e786 104
olympux 27:22f289beceb8 105 // Serial
olympux 27:22f289beceb8 106 Serial uart(USBTX,USBRX);
olympux 20:71c7950fdd91 107 // Watchdog
olympux 20:71c7950fdd91 108 Watchdog wdt;
olympux 20:71c7950fdd91 109
olympux 26:09e0dd020900 110
olympux 26:09e0dd020900 111
olympux 2:18f10e7209f4 112 /*
olympux 42:d0ff08711ca5 113 * Threads
olympux 42:d0ff08711ca5 114 */
olympux 20:71c7950fdd91 115 // WDT reset
olympux 31:2e4b6de6c2f3 116 void wdt_reset_thread(void const* args)
olympux 31:2e4b6de6c2f3 117 {
olympux 20:71c7950fdd91 118 while (true)
olympux 20:71c7950fdd91 119 wdt.Service();
olympux 20:71c7950fdd91 120 }
olympux 20:71c7950fdd91 121
olympux 40:c966abbe2d62 122
olympux 40:c966abbe2d62 123 HTTPServer create_simple_server()
olympux 40:c966abbe2d62 124 {
olympux 40:c966abbe2d62 125 HTTPServer srv;
olympux 40:c966abbe2d62 126 srv.add_request_handler("DELETE", new DeleteRequestHandler());
olympux 40:c966abbe2d62 127 srv.add_request_handler("GET", new GetRequestHandler());
olympux 40:c966abbe2d62 128 srv.add_request_handler("PUT", new PutRequestHandler());
olympux 40:c966abbe2d62 129 return srv;
olympux 40:c966abbe2d62 130 }
olympux 40:c966abbe2d62 131
olympux 40:c966abbe2d62 132 HTTPServer create_interactive_server()
olympux 39:083cf93121a9 133 {
olympux 40:c966abbe2d62 134 HTTPServer srv(new InteractiveHTMLFormatter());
olympux 40:c966abbe2d62 135 srv.add_request_handler("GET", new ComplexRequestHandler());
olympux 40:c966abbe2d62 136 return srv;
olympux 38:f8735ae519aa 137 }
olympux 38:f8735ae519aa 138
olympux 38:f8735ae519aa 139 // Main code
olympux 4:568c97f2a407 140 int main()
olympux 4:568c97f2a407 141 {
olympux 42:d0ff08711ca5 142 int ret;
olympux 42:d0ff08711ca5 143
olympux 20:71c7950fdd91 144 Thread::wait(500); // turn on delay
olympux 31:2e4b6de6c2f3 145
olympux 4:568c97f2a407 146 /*
olympux 9:d2534ecf88c6 147 * Configure
olympux 4:568c97f2a407 148 */
olympux 11:709f90a3b599 149 uart.baud(115200);
olympux 36:dc6f079777bb 150 DBG("Starting...");
olympux 31:2e4b6de6c2f3 151
olympux 31:2e4b6de6c2f3 152 // check watchdog
olympux 20:71c7950fdd91 153 if (wdt.WatchdogCausedReset())
olympux 20:71c7950fdd91 154 DBG("Watchdog caused reset.");
olympux 20:71c7950fdd91 155 wdt.Configure(4);
olympux 31:2e4b6de6c2f3 156
olympux 6:d054e394fba3 157 /*
olympux 6:d054e394fba3 158 * FLASH
olympux 6:d054e394fba3 159 */
olympux 12:7c152c0ca4d8 160 load_eeprom_network();
olympux 15:edeb0aed160d 161 load_eeprom_tcpserver();
olympux 31:2e4b6de6c2f3 162
olympux 20:71c7950fdd91 163 /*
olympux 20:71c7950fdd91 164 * UI threads
olympux 20:71c7950fdd91 165 */
olympux 20:71c7950fdd91 166 Thread t3(wdt_reset_thread);
olympux 40:c966abbe2d62 167
olympux 40:c966abbe2d62 168 // rpc
olympux 40:c966abbe2d62 169 RPCType::instance().register_types();
olympux 31:2e4b6de6c2f3 170
olympux 4:568c97f2a407 171 /*
olympux 4:568c97f2a407 172 * Ethernet
olympux 4:568c97f2a407 173 */
olympux 6:d054e394fba3 174 ret = ethernet_init();
olympux 4:568c97f2a407 175 if (ret) {
olympux 18:ca499a2e7da6 176 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 177 while (true) {};
olympux 4:568c97f2a407 178 }
olympux 31:2e4b6de6c2f3 179
olympux 23:47ee805435b1 180 Thread::wait(2000); // TCP/UDP stack delay
olympux 40:c966abbe2d62 181
olympux 40:c966abbe2d62 182 // Test parsing ip address string
olympux 40:c966abbe2d62 183 char* ipaddr = "192.168.0.121";
olympux 40:c966abbe2d62 184 int b[4];
olympux 40:c966abbe2d62 185 sscanf(ipaddr, "%d.%d.%d.%d", &b[0], &b[1], &b[2], &b[3]);
olympux 40:c966abbe2d62 186 DBG("%d.%d.%d.%d",b[0],b[1],b[2],b[3]);
olympux 31:2e4b6de6c2f3 187
olympux 40:c966abbe2d62 188 // create rpc http server
olympux 40:c966abbe2d62 189 HTTPServer srv = create_interactive_server();
olympux 26:09e0dd020900 190
olympux 40:c966abbe2d62 191 if(!srv.init(SERVER_PORT))
olympux 40:c966abbe2d62 192 {
olympux 40:c966abbe2d62 193 eth.disconnect();
olympux 40:c966abbe2d62 194 return -1;
olympux 27:22f289beceb8 195 }
olympux 31:2e4b6de6c2f3 196
olympux 40:c966abbe2d62 197 srv.run();
olympux 26:09e0dd020900 198 }
olympux 26:09e0dd020900 199
olympux 26:09e0dd020900 200
olympux 26:09e0dd020900 201 /*
olympux 42:d0ff08711ca5 202 * W5500 Ethernet init
olympux 42:d0ff08711ca5 203 */
olympux 31:2e4b6de6c2f3 204 int ethernet_init(void)
olympux 31:2e4b6de6c2f3 205 {
olympux 26:09e0dd020900 206 int dhcp_ret, ret;
olympux 31:2e4b6de6c2f3 207
olympux 27:22f289beceb8 208 DBG("Initialising ethernet...");
olympux 31:2e4b6de6c2f3 209
olympux 26:09e0dd020900 210 // if not configured, try dhcp
olympux 26:09e0dd020900 211 dhcp_ret = -1;
olympux 26:09e0dd020900 212 if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
olympux 27:22f289beceb8 213 DBG("Connecting to DHCP server...");
olympux 26:09e0dd020900 214 dhcp_ret = eth.init(u8mac);
olympux 26:09e0dd020900 215 if (dhcp_ret == 0)
olympux 26:09e0dd020900 216 dhcp_ret = eth.connect();
olympux 26:09e0dd020900 217 }
olympux 31:2e4b6de6c2f3 218
olympux 26:09e0dd020900 219 if (dhcp_ret != 0) {
olympux 26:09e0dd020900 220 DBG("No DHCP, load static IP configuration");
olympux 26:09e0dd020900 221 ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
olympux 26:09e0dd020900 222 } else {
olympux 26:09e0dd020900 223 snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
olympux 26:09e0dd020900 224 snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
olympux 26:09e0dd020900 225 snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
olympux 26:09e0dd020900 226 ret = 0;
olympux 26:09e0dd020900 227 }
olympux 26:09e0dd020900 228
olympux 26:09e0dd020900 229 if (ret == 0) {
olympux 26:09e0dd020900 230 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 26:09e0dd020900 231 } else {
olympux 26:09e0dd020900 232 ERR("Error eth.init() - ret = %d", ret);
olympux 26:09e0dd020900 233 return -1;
olympux 26:09e0dd020900 234 }
olympux 26:09e0dd020900 235
olympux 26:09e0dd020900 236 ret = eth.connect();
olympux 26:09e0dd020900 237 if (!ret) {
olympux 26:09e0dd020900 238 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 26:09e0dd020900 239 } else {
olympux 26:09e0dd020900 240 ERR("Error eth.connect() - ret = %d", ret);
olympux 26:09e0dd020900 241 return -1;
olympux 26:09e0dd020900 242 }
olympux 31:2e4b6de6c2f3 243
olympux 26:09e0dd020900 244 return 0;
olympux 26:09e0dd020900 245 }
olympux 26:09e0dd020900 246