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 21:51:38 2016 +0000
Revision:
44:4e8a9b466695
Parent:
43:48ca8c6f6f49
Child:
45:8d18a95fcf8a
Enable configured flag with RPC command

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 43:48ca8c6f6f49 76 char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16], str_mac_addr[20]; // 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 43:48ca8c6f6f49 99 RPCVariable<char*> rpcMac(str_mac_addr, 20, "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 43:48ca8c6f6f49 104 // RPC function definitions
olympux 43:48ca8c6f6f49 105 // Create a function of the required format
olympux 43:48ca8c6f6f49 106 void save_ip_addr(Arguments* args, Reply* rep);
olympux 43:48ca8c6f6f49 107 void disable_static_ip_addr_flag(Arguments* args, Reply* rep);
olympux 43:48ca8c6f6f49 108
olympux 43:48ca8c6f6f49 109 void save_ip_addr(Arguments* args, Reply* rep){
olympux 43:48ca8c6f6f49 110 int b[4], n, i;
olympux 43:48ca8c6f6f49 111 char ipaddr[4];
olympux 43:48ca8c6f6f49 112
olympux 43:48ca8c6f6f49 113 n = sscanf(str_ip_addr, "%d.%d.%d.%d", &b[0], &b[1], &b[2], &b[3]);
olympux 43:48ca8c6f6f49 114 if (n == 4) {
olympux 43:48ca8c6f6f49 115 DBG("%d.%d.%d.%d",b[0],b[1],b[2],b[3]);
olympux 43:48ca8c6f6f49 116 for (i = 0; i < 4; i++) {
olympux 43:48ca8c6f6f49 117 ipaddr[i] = b[i] & 0x00FF;
olympux 43:48ca8c6f6f49 118 }
olympux 43:48ca8c6f6f49 119 save_ip_addr(ipaddr);
olympux 43:48ca8c6f6f49 120 NVIC_SystemReset();
olympux 43:48ca8c6f6f49 121 }
olympux 43:48ca8c6f6f49 122 else {
olympux 43:48ca8c6f6f49 123 DBG("Saving IP address failed");
olympux 43:48ca8c6f6f49 124 }
olympux 43:48ca8c6f6f49 125 }
olympux 44:4e8a9b466695 126 void set_configuration(Arguments* args, Reply* rep){
olympux 44:4e8a9b466695 127 set_conf();
olympux 44:4e8a9b466695 128 }
olympux 43:48ca8c6f6f49 129 void reset_configuration(Arguments* args, Reply* rep){
olympux 43:48ca8c6f6f49 130 reset_conf();
olympux 43:48ca8c6f6f49 131 }
olympux 43:48ca8c6f6f49 132 // Attach it to an RPC object
olympux 43:48ca8c6f6f49 133 RPCFunction rpcSaveIPAddr(&save_ip_addr, "saveipaddr");
olympux 44:4e8a9b466695 134 RPCFunction rpcSetConfiguration(&set_configuration, "setconf");
olympux 43:48ca8c6f6f49 135 RPCFunction rpcResetConfiguration(&reset_configuration, "resetconf");
olympux 30:15e23257e786 136
olympux 27:22f289beceb8 137 // Serial
olympux 27:22f289beceb8 138 Serial uart(USBTX,USBRX);
olympux 20:71c7950fdd91 139 // Watchdog
olympux 20:71c7950fdd91 140 Watchdog wdt;
olympux 20:71c7950fdd91 141
olympux 26:09e0dd020900 142
olympux 26:09e0dd020900 143
olympux 2:18f10e7209f4 144 /*
olympux 42:d0ff08711ca5 145 * Threads
olympux 42:d0ff08711ca5 146 */
olympux 20:71c7950fdd91 147 // WDT reset
olympux 31:2e4b6de6c2f3 148 void wdt_reset_thread(void const* args)
olympux 31:2e4b6de6c2f3 149 {
olympux 20:71c7950fdd91 150 while (true)
olympux 20:71c7950fdd91 151 wdt.Service();
olympux 20:71c7950fdd91 152 }
olympux 20:71c7950fdd91 153
olympux 40:c966abbe2d62 154
olympux 40:c966abbe2d62 155 HTTPServer create_simple_server()
olympux 40:c966abbe2d62 156 {
olympux 40:c966abbe2d62 157 HTTPServer srv;
olympux 40:c966abbe2d62 158 srv.add_request_handler("DELETE", new DeleteRequestHandler());
olympux 40:c966abbe2d62 159 srv.add_request_handler("GET", new GetRequestHandler());
olympux 40:c966abbe2d62 160 srv.add_request_handler("PUT", new PutRequestHandler());
olympux 40:c966abbe2d62 161 return srv;
olympux 40:c966abbe2d62 162 }
olympux 40:c966abbe2d62 163
olympux 40:c966abbe2d62 164 HTTPServer create_interactive_server()
olympux 39:083cf93121a9 165 {
olympux 40:c966abbe2d62 166 HTTPServer srv(new InteractiveHTMLFormatter());
olympux 40:c966abbe2d62 167 srv.add_request_handler("GET", new ComplexRequestHandler());
olympux 40:c966abbe2d62 168 return srv;
olympux 38:f8735ae519aa 169 }
olympux 38:f8735ae519aa 170
olympux 38:f8735ae519aa 171 // Main code
olympux 4:568c97f2a407 172 int main()
olympux 4:568c97f2a407 173 {
olympux 42:d0ff08711ca5 174 int ret;
olympux 42:d0ff08711ca5 175
olympux 20:71c7950fdd91 176 Thread::wait(500); // turn on delay
olympux 31:2e4b6de6c2f3 177
olympux 4:568c97f2a407 178 /*
olympux 9:d2534ecf88c6 179 * Configure
olympux 4:568c97f2a407 180 */
olympux 11:709f90a3b599 181 uart.baud(115200);
olympux 36:dc6f079777bb 182 DBG("Starting...");
olympux 31:2e4b6de6c2f3 183
olympux 31:2e4b6de6c2f3 184 // check watchdog
olympux 20:71c7950fdd91 185 if (wdt.WatchdogCausedReset())
olympux 20:71c7950fdd91 186 DBG("Watchdog caused reset.");
olympux 20:71c7950fdd91 187 wdt.Configure(4);
olympux 31:2e4b6de6c2f3 188
olympux 6:d054e394fba3 189 /*
olympux 6:d054e394fba3 190 * FLASH
olympux 6:d054e394fba3 191 */
olympux 12:7c152c0ca4d8 192 load_eeprom_network();
olympux 15:edeb0aed160d 193 load_eeprom_tcpserver();
olympux 31:2e4b6de6c2f3 194
olympux 20:71c7950fdd91 195 /*
olympux 20:71c7950fdd91 196 * UI threads
olympux 20:71c7950fdd91 197 */
olympux 20:71c7950fdd91 198 Thread t3(wdt_reset_thread);
olympux 40:c966abbe2d62 199
olympux 40:c966abbe2d62 200 // rpc
olympux 40:c966abbe2d62 201 RPCType::instance().register_types();
olympux 31:2e4b6de6c2f3 202
olympux 4:568c97f2a407 203 /*
olympux 4:568c97f2a407 204 * Ethernet
olympux 4:568c97f2a407 205 */
olympux 6:d054e394fba3 206 ret = ethernet_init();
olympux 4:568c97f2a407 207 if (ret) {
olympux 18:ca499a2e7da6 208 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 209 while (true) {};
olympux 4:568c97f2a407 210 }
olympux 31:2e4b6de6c2f3 211
olympux 23:47ee805435b1 212 Thread::wait(2000); // TCP/UDP stack delay
olympux 31:2e4b6de6c2f3 213
olympux 40:c966abbe2d62 214 // create rpc http server
olympux 40:c966abbe2d62 215 HTTPServer srv = create_interactive_server();
olympux 26:09e0dd020900 216
olympux 40:c966abbe2d62 217 if(!srv.init(SERVER_PORT))
olympux 40:c966abbe2d62 218 {
olympux 40:c966abbe2d62 219 eth.disconnect();
olympux 40:c966abbe2d62 220 return -1;
olympux 27:22f289beceb8 221 }
olympux 31:2e4b6de6c2f3 222
olympux 40:c966abbe2d62 223 srv.run();
olympux 26:09e0dd020900 224 }
olympux 26:09e0dd020900 225
olympux 26:09e0dd020900 226
olympux 26:09e0dd020900 227 /*
olympux 42:d0ff08711ca5 228 * W5500 Ethernet init
olympux 42:d0ff08711ca5 229 */
olympux 31:2e4b6de6c2f3 230 int ethernet_init(void)
olympux 31:2e4b6de6c2f3 231 {
olympux 26:09e0dd020900 232 int dhcp_ret, ret;
olympux 31:2e4b6de6c2f3 233
olympux 27:22f289beceb8 234 DBG("Initialising ethernet...");
olympux 31:2e4b6de6c2f3 235
olympux 26:09e0dd020900 236 // if not configured, try dhcp
olympux 26:09e0dd020900 237 dhcp_ret = -1;
olympux 26:09e0dd020900 238 if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
olympux 27:22f289beceb8 239 DBG("Connecting to DHCP server...");
olympux 26:09e0dd020900 240 dhcp_ret = eth.init(u8mac);
olympux 26:09e0dd020900 241 if (dhcp_ret == 0)
olympux 26:09e0dd020900 242 dhcp_ret = eth.connect();
olympux 26:09e0dd020900 243 }
olympux 31:2e4b6de6c2f3 244
olympux 26:09e0dd020900 245 if (dhcp_ret != 0) {
olympux 26:09e0dd020900 246 DBG("No DHCP, load static IP configuration");
olympux 26:09e0dd020900 247 ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
olympux 26:09e0dd020900 248 } else {
olympux 26:09e0dd020900 249 snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
olympux 26:09e0dd020900 250 snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
olympux 26:09e0dd020900 251 snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
olympux 26:09e0dd020900 252 ret = 0;
olympux 26:09e0dd020900 253 }
olympux 26:09e0dd020900 254
olympux 26:09e0dd020900 255 if (ret == 0) {
olympux 26:09e0dd020900 256 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 26:09e0dd020900 257 } else {
olympux 26:09e0dd020900 258 ERR("Error eth.init() - ret = %d", ret);
olympux 26:09e0dd020900 259 return -1;
olympux 26:09e0dd020900 260 }
olympux 26:09e0dd020900 261
olympux 26:09e0dd020900 262 ret = eth.connect();
olympux 26:09e0dd020900 263 if (!ret) {
olympux 26:09e0dd020900 264 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 26:09e0dd020900 265 } else {
olympux 26:09e0dd020900 266 ERR("Error eth.connect() - ret = %d", ret);
olympux 26:09e0dd020900 267 return -1;
olympux 26:09e0dd020900 268 }
olympux 31:2e4b6de6c2f3 269
olympux 26:09e0dd020900 270 return 0;
olympux 26:09e0dd020900 271 }
olympux 26:09e0dd020900 272