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:
Fri Aug 19 20:17:00 2016 +0000
Revision:
47:d92d2c5b8073
Parent:
46:971bdaa3507c
forked to create a new repo for webserver on F103+W5500. No other functions

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 46:971bdaa3507c 3 //#include "mbed_rpc.h"
olympux 27:22f289beceb8 4 #include "Arguments.h"
olympux 27:22f289beceb8 5
olympux 0:c2eac797face 6 #include "EthernetInterface.h"
olympux 9:d2534ecf88c6 7 #include "NTPClient.h"
olympux 46:971bdaa3507c 8 #include "Watchdog.h"
olympux 0:c2eac797face 9
olympux 46:971bdaa3507c 10 #include "eeprom_flash.h"
olympux 46:971bdaa3507c 11 #include "device_configuration.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 46:971bdaa3507c 37
olympux 16:84a5bf7285d0 38
olympux 2:18f10e7209f4 39 /*
olympux 45:8d18a95fcf8a 40 * Hardware defines
olympux 45:8d18a95fcf8a 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 46:971bdaa3507c 47 Serial pc(USBTX,USBRX);
olympux 46:971bdaa3507c 48 Watchdog wdt;
olympux 45:8d18a95fcf8a 49
olympux 30:15e23257e786 50
olympux 45:8d18a95fcf8a 51 /*
olympux 46:971bdaa3507c 52 * Variables for network configuration
olympux 45:8d18a95fcf8a 53 */
olympux 46:971bdaa3507c 54 // Device configuration
olympux 46:971bdaa3507c 55 extern uint16_t u16IpAddr[4], u16IpSubnet[4], u16IpGateway[4], u16MacAddr[3]; // 16-bits variables to be compatible with eeprom functions
olympux 46:971bdaa3507c 56 extern char strIpAddr[16], strIpSubnet[16], strIpGateway[16], strMacAddr[20]; // RPC variables, converted from 16-bits u16ip_xxx
olympux 46:971bdaa3507c 57 extern uint16_t u16DeviceConfiguredFlag; // flag indicates whether device has been configured (0xA5A5) or not
olympux 46:971bdaa3507c 58 // TCP server/UDP
olympux 46:971bdaa3507c 59 extern uint16_t u16LocalTcpServerPort;
olympux 46:971bdaa3507c 60 extern uint16_t u16LocalUdpPort;
olympux 46:971bdaa3507c 61 // TCP client mode, set parameters of the remote TCP server this device connects to.
olympux 46:971bdaa3507c 62 // When enabled, this device will send its status to the server every transmit_time_period.
olympux 46:971bdaa3507c 63 extern uint16_t u16RemoteTcpServerIpAddr[4]; // 16-bit variable to be compatible with eeprom functions
olympux 46:971bdaa3507c 64 extern char strRemoteTcpServerIpAddr[16]; // RPC variable, converted from 16-bits u16server_ip_addr
olympux 46:971bdaa3507c 65 extern uint16_t u16RemoteTcpServerPort; // 16-bit variable to be compatible with eeprom functions
olympux 46:971bdaa3507c 66 extern uint16_t u16AutoTransmitFlag, u16TransmitPeriod; // auto transmit status, time period = 1s
olympux 46:971bdaa3507c 67 // enable modes
olympux 46:971bdaa3507c 68 extern uint16_t u16EnableTcpServer, u16EnableTcpClient, u16EnableUdp; // flags for enabling TCP server/client and UDP (UDP is always on for configuration)
olympux 46:971bdaa3507c 69 // extra
olympux 46:971bdaa3507c 70 extern uint8_t u8IpAddr[4]; // keep device ip address in 8-bits
olympux 46:971bdaa3507c 71 extern uint8_t u8MacAddr[6]; // keep mac in 8-bits
olympux 46:971bdaa3507c 72 extern uint8_t u8RemoteTcpServerIpAddr[4]; // remote TCP server ip address in 8-bits
olympux 20:71c7950fdd91 73
olympux 26:09e0dd020900 74
olympux 46:971bdaa3507c 75 // Corresponding RPC variables
olympux 46:971bdaa3507c 76 RPCVariable<char*> rpcIPAddress(strIpAddr, 16, "ipaddr");
olympux 46:971bdaa3507c 77 RPCVariable<char*> rpcSubnet(strIpSubnet, 16, "subnet");
olympux 46:971bdaa3507c 78 RPCVariable<char*> rpcGateway(strIpGateway, 16, "gateway");
olympux 46:971bdaa3507c 79 RPCVariable<char*> rpcMac(strMacAddr, 20, "mac");
olympux 46:971bdaa3507c 80 RPCVariable<unsigned short> rpcLocalTCPServerPort(&u16LocalTcpServerPort, "localtcpserverport");
olympux 46:971bdaa3507c 81 RPCVariable<unsigned short> rpcLocalUDPPort(&u16LocalUdpPort, "localudpport");
olympux 46:971bdaa3507c 82
olympux 46:971bdaa3507c 83 RPCVariable<unsigned short> rpcEnableTCPServer(&u16EnableTcpServer, "enabletcpserver");
olympux 46:971bdaa3507c 84 RPCVariable<unsigned short> rpcEnableTCPClient(&u16EnableTcpClient, "enabletcpclient");
olympux 46:971bdaa3507c 85 RPCVariable<unsigned short> rpcEnableUDP(&u16EnableUdp, "enableudp");
olympux 46:971bdaa3507c 86
olympux 46:971bdaa3507c 87 RPCVariable<char*> rpcRemoteTCPServerIPAddress(strRemoteTcpServerIpAddr, 16, "remotetcpserveripaddr");
olympux 46:971bdaa3507c 88 RPCVariable<unsigned short> rpcRemoteTCPServerPort(&u16RemoteTcpServerPort, "remotetcpserverport");
olympux 46:971bdaa3507c 89 RPCVariable<unsigned short> rpcAutoTransmit(&u16AutoTransmitFlag, "autotransmit");
olympux 46:971bdaa3507c 90 RPCVariable<unsigned short> rpcTransmitPeriod(&u16TransmitPeriod, "transmitperiod");
olympux 45:8d18a95fcf8a 91
olympux 45:8d18a95fcf8a 92 // RPC function definitions
olympux 46:971bdaa3507c 93 // save ip address only
olympux 46:971bdaa3507c 94 void show_device_config(Arguments* args, Reply* rep){
olympux 46:971bdaa3507c 95 DBG("IP: %s", strIpAddr);
olympux 46:971bdaa3507c 96 DBG("Subnet: %s", strIpSubnet);
olympux 46:971bdaa3507c 97 DBG("Gateway: %s", strIpGateway);
olympux 46:971bdaa3507c 98 DBG("MAC: %s", strMacAddr);
olympux 45:8d18a95fcf8a 99 }
olympux 46:971bdaa3507c 100 // Attach eeprom functions to RPC functions
olympux 46:971bdaa3507c 101 RPCFunction rpcShowConfig(&show_device_config, "showdevconf");
olympux 26:09e0dd020900 102
olympux 2:18f10e7209f4 103 /*
olympux 42:d0ff08711ca5 104 * Threads
olympux 42:d0ff08711ca5 105 */
olympux 20:71c7950fdd91 106 // WDT reset
olympux 31:2e4b6de6c2f3 107 void wdt_reset_thread(void const* args)
olympux 31:2e4b6de6c2f3 108 {
olympux 20:71c7950fdd91 109 while (true)
olympux 20:71c7950fdd91 110 wdt.Service();
olympux 20:71c7950fdd91 111 }
olympux 20:71c7950fdd91 112
olympux 47:d92d2c5b8073 113 /*
olympux 47:d92d2c5b8073 114 * HTTP server
olympux 47:d92d2c5b8073 115 */
olympux 40:c966abbe2d62 116 HTTPServer create_simple_server()
olympux 40:c966abbe2d62 117 {
olympux 40:c966abbe2d62 118 HTTPServer srv;
olympux 40:c966abbe2d62 119 srv.add_request_handler("DELETE", new DeleteRequestHandler());
olympux 40:c966abbe2d62 120 srv.add_request_handler("GET", new GetRequestHandler());
olympux 40:c966abbe2d62 121 srv.add_request_handler("PUT", new PutRequestHandler());
olympux 40:c966abbe2d62 122 return srv;
olympux 40:c966abbe2d62 123 }
olympux 40:c966abbe2d62 124
olympux 40:c966abbe2d62 125 HTTPServer create_interactive_server()
olympux 39:083cf93121a9 126 {
olympux 40:c966abbe2d62 127 HTTPServer srv(new InteractiveHTMLFormatter());
olympux 40:c966abbe2d62 128 srv.add_request_handler("GET", new ComplexRequestHandler());
olympux 40:c966abbe2d62 129 return srv;
olympux 38:f8735ae519aa 130 }
olympux 38:f8735ae519aa 131
olympux 45:8d18a95fcf8a 132
olympux 38:f8735ae519aa 133 // Main code
olympux 4:568c97f2a407 134 int main()
olympux 4:568c97f2a407 135 {
olympux 42:d0ff08711ca5 136 int ret;
olympux 42:d0ff08711ca5 137
olympux 20:71c7950fdd91 138 Thread::wait(500); // turn on delay
olympux 31:2e4b6de6c2f3 139
olympux 4:568c97f2a407 140 /*
olympux 47:d92d2c5b8073 141 * Configure hardware
olympux 46:971bdaa3507c 142 */
olympux 46:971bdaa3507c 143 pc.baud(115200);
olympux 36:dc6f079777bb 144 DBG("Starting...");
olympux 31:2e4b6de6c2f3 145
olympux 31:2e4b6de6c2f3 146 // check watchdog
olympux 20:71c7950fdd91 147 if (wdt.WatchdogCausedReset())
olympux 20:71c7950fdd91 148 DBG("Watchdog caused reset.");
olympux 20:71c7950fdd91 149 wdt.Configure(4);
olympux 46:971bdaa3507c 150
olympux 46:971bdaa3507c 151 /*reset_device_configuration();
olympux 46:971bdaa3507c 152 uint16_t ip[4] = {192,168,0,120};
olympux 46:971bdaa3507c 153 uint16_t subnet[4] = {255,255,255,0};
olympux 46:971bdaa3507c 154 uint16_t gateway[4] = {192,168,0,1};
olympux 46:971bdaa3507c 155 uint16_t mac[3] = {0,0,1};
olympux 46:971bdaa3507c 156 uint16_t tcp_port = DEFAULT_LOCAL_TCP_SERVER_PORT;
olympux 46:971bdaa3507c 157 uint16_t udp_port = DEFAULT_LOCAL_UDP_PORT;
olympux 46:971bdaa3507c 158 uint16_t remote_ip[4] = {0,0,0,0};
olympux 46:971bdaa3507c 159 uint16_t remote_port = 12000;
olympux 46:971bdaa3507c 160 uint16_t auto_transmit = DEFAULT_DISABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 161 uint16_t transmit_period = 1000;
olympux 46:971bdaa3507c 162 uint16_t enable_tcp_server = DEFAULT_DISABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 163 uint16_t enable_tcp_client = DEFAULT_DISABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 164 uint16_t enable_udp = DEFAULT_ENABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 165
olympux 46:971bdaa3507c 166 write_device_configuration(ip, subnet, gateway, mac,
olympux 46:971bdaa3507c 167 tcp_port, udp_port,
olympux 46:971bdaa3507c 168 remote_ip, remote_port, auto_transmit, transmit_period,
olympux 46:971bdaa3507c 169 enable_tcp_server, enable_tcp_client, enable_udp);*/
olympux 46:971bdaa3507c 170
olympux 46:971bdaa3507c 171 read_device_configuration();
olympux 46:971bdaa3507c 172
olympux 46:971bdaa3507c 173
olympux 6:d054e394fba3 174 /*
olympux 47:d92d2c5b8073 175 * Threads
olympux 46:971bdaa3507c 176 */
olympux 46:971bdaa3507c 177 Thread t0(wdt_reset_thread);
olympux 40:c966abbe2d62 178
olympux 40:c966abbe2d62 179 // rpc
olympux 40:c966abbe2d62 180 RPCType::instance().register_types();
olympux 46:971bdaa3507c 181
olympux 4:568c97f2a407 182 /*
olympux 47:d92d2c5b8073 183 * Ethernet
olympux 47:d92d2c5b8073 184 */
olympux 6:d054e394fba3 185 ret = ethernet_init();
olympux 4:568c97f2a407 186 if (ret) {
olympux 18:ca499a2e7da6 187 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 188 while (true) {};
olympux 4:568c97f2a407 189 }
olympux 31:2e4b6de6c2f3 190
olympux 23:47ee805435b1 191 Thread::wait(2000); // TCP/UDP stack delay
olympux 46:971bdaa3507c 192
olympux 47:d92d2c5b8073 193 /*
olympux 47:d92d2c5b8073 194 * HTTP server
olympux 47:d92d2c5b8073 195 */
olympux 40:c966abbe2d62 196 // create rpc http server
olympux 40:c966abbe2d62 197 HTTPServer srv = create_interactive_server();
olympux 26:09e0dd020900 198
olympux 40:c966abbe2d62 199 if(!srv.init(SERVER_PORT))
olympux 40:c966abbe2d62 200 {
olympux 40:c966abbe2d62 201 eth.disconnect();
olympux 40:c966abbe2d62 202 return -1;
olympux 27:22f289beceb8 203 }
olympux 31:2e4b6de6c2f3 204
olympux 46:971bdaa3507c 205 srv.run();
olympux 26:09e0dd020900 206 }
olympux 26:09e0dd020900 207
olympux 26:09e0dd020900 208 /*
olympux 42:d0ff08711ca5 209 * W5500 Ethernet init
olympux 42:d0ff08711ca5 210 */
olympux 31:2e4b6de6c2f3 211 int ethernet_init(void)
olympux 31:2e4b6de6c2f3 212 {
olympux 26:09e0dd020900 213 int dhcp_ret, ret;
olympux 31:2e4b6de6c2f3 214
olympux 27:22f289beceb8 215 DBG("Initialising ethernet...");
olympux 31:2e4b6de6c2f3 216
olympux 26:09e0dd020900 217 // if not configured, try dhcp
olympux 26:09e0dd020900 218 dhcp_ret = -1;
olympux 46:971bdaa3507c 219 if (u16DeviceConfiguredFlag != DEFAULT_ENABLE_FLAG_VALUE) {
olympux 27:22f289beceb8 220 DBG("Connecting to DHCP server...");
olympux 46:971bdaa3507c 221 dhcp_ret = eth.init(u8MacAddr);
olympux 26:09e0dd020900 222 if (dhcp_ret == 0)
olympux 26:09e0dd020900 223 dhcp_ret = eth.connect();
olympux 26:09e0dd020900 224 }
olympux 31:2e4b6de6c2f3 225
olympux 26:09e0dd020900 226 if (dhcp_ret != 0) {
olympux 26:09e0dd020900 227 DBG("No DHCP, load static IP configuration");
olympux 46:971bdaa3507c 228 ret = eth.init(u8MacAddr, strIpAddr, strIpSubnet, strIpGateway); // static
olympux 26:09e0dd020900 229 } else {
olympux 46:971bdaa3507c 230 snprintf(strIpAddr, 16, "%s", eth.getIPAddress());
olympux 46:971bdaa3507c 231 snprintf(strIpSubnet, 16, "%s", eth.getNetworkMask());
olympux 46:971bdaa3507c 232 snprintf(strIpGateway, 16, "%s", eth.getGateway());
olympux 26:09e0dd020900 233 ret = 0;
olympux 26:09e0dd020900 234 }
olympux 26:09e0dd020900 235
olympux 26:09e0dd020900 236 if (ret == 0) {
olympux 26:09e0dd020900 237 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 26:09e0dd020900 238 } else {
olympux 26:09e0dd020900 239 ERR("Error eth.init() - ret = %d", ret);
olympux 26:09e0dd020900 240 return -1;
olympux 26:09e0dd020900 241 }
olympux 26:09e0dd020900 242
olympux 26:09e0dd020900 243 ret = eth.connect();
olympux 26:09e0dd020900 244 if (!ret) {
olympux 26:09e0dd020900 245 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 26:09e0dd020900 246 } else {
olympux 26:09e0dd020900 247 ERR("Error eth.connect() - ret = %d", ret);
olympux 26:09e0dd020900 248 return -1;
olympux 26:09e0dd020900 249 }
olympux 31:2e4b6de6c2f3 250
olympux 26:09e0dd020900 251 return 0;
olympux 26:09e0dd020900 252 }
olympux 26:09e0dd020900 253