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:
Sun Aug 14 11:06:53 2016 +0000
Revision:
46:971bdaa3507c
Parent:
45:8d18a95fcf8a
Child:
47:d92d2c5b8073
Initial version, support RPC over HTTP with new eeprom emulation

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 40:c966abbe2d62 113 HTTPServer create_simple_server()
olympux 40:c966abbe2d62 114 {
olympux 40:c966abbe2d62 115 HTTPServer srv;
olympux 40:c966abbe2d62 116 srv.add_request_handler("DELETE", new DeleteRequestHandler());
olympux 40:c966abbe2d62 117 srv.add_request_handler("GET", new GetRequestHandler());
olympux 40:c966abbe2d62 118 srv.add_request_handler("PUT", new PutRequestHandler());
olympux 40:c966abbe2d62 119 return srv;
olympux 40:c966abbe2d62 120 }
olympux 40:c966abbe2d62 121
olympux 40:c966abbe2d62 122 HTTPServer create_interactive_server()
olympux 39:083cf93121a9 123 {
olympux 40:c966abbe2d62 124 HTTPServer srv(new InteractiveHTMLFormatter());
olympux 40:c966abbe2d62 125 srv.add_request_handler("GET", new ComplexRequestHandler());
olympux 40:c966abbe2d62 126 return srv;
olympux 38:f8735ae519aa 127 }
olympux 38:f8735ae519aa 128
olympux 45:8d18a95fcf8a 129
olympux 38:f8735ae519aa 130 // Main code
olympux 4:568c97f2a407 131 int main()
olympux 4:568c97f2a407 132 {
olympux 42:d0ff08711ca5 133 int ret;
olympux 42:d0ff08711ca5 134
olympux 20:71c7950fdd91 135 Thread::wait(500); // turn on delay
olympux 31:2e4b6de6c2f3 136
olympux 4:568c97f2a407 137 /*
olympux 46:971bdaa3507c 138 * Configure
olympux 46:971bdaa3507c 139 */
olympux 46:971bdaa3507c 140 pc.baud(115200);
olympux 36:dc6f079777bb 141 DBG("Starting...");
olympux 31:2e4b6de6c2f3 142
olympux 31:2e4b6de6c2f3 143 // check watchdog
olympux 20:71c7950fdd91 144 if (wdt.WatchdogCausedReset())
olympux 20:71c7950fdd91 145 DBG("Watchdog caused reset.");
olympux 20:71c7950fdd91 146 wdt.Configure(4);
olympux 46:971bdaa3507c 147
olympux 46:971bdaa3507c 148 /*reset_device_configuration();
olympux 46:971bdaa3507c 149 uint16_t ip[4] = {192,168,0,120};
olympux 46:971bdaa3507c 150 uint16_t subnet[4] = {255,255,255,0};
olympux 46:971bdaa3507c 151 uint16_t gateway[4] = {192,168,0,1};
olympux 46:971bdaa3507c 152 uint16_t mac[3] = {0,0,1};
olympux 46:971bdaa3507c 153 uint16_t tcp_port = DEFAULT_LOCAL_TCP_SERVER_PORT;
olympux 46:971bdaa3507c 154 uint16_t udp_port = DEFAULT_LOCAL_UDP_PORT;
olympux 46:971bdaa3507c 155 uint16_t remote_ip[4] = {0,0,0,0};
olympux 46:971bdaa3507c 156 uint16_t remote_port = 12000;
olympux 46:971bdaa3507c 157 uint16_t auto_transmit = DEFAULT_DISABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 158 uint16_t transmit_period = 1000;
olympux 46:971bdaa3507c 159 uint16_t enable_tcp_server = DEFAULT_DISABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 160 uint16_t enable_tcp_client = DEFAULT_DISABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 161 uint16_t enable_udp = DEFAULT_ENABLE_FLAG_VALUE;
olympux 46:971bdaa3507c 162
olympux 46:971bdaa3507c 163 write_device_configuration(ip, subnet, gateway, mac,
olympux 46:971bdaa3507c 164 tcp_port, udp_port,
olympux 46:971bdaa3507c 165 remote_ip, remote_port, auto_transmit, transmit_period,
olympux 46:971bdaa3507c 166 enable_tcp_server, enable_tcp_client, enable_udp);*/
olympux 46:971bdaa3507c 167
olympux 46:971bdaa3507c 168 read_device_configuration();
olympux 46:971bdaa3507c 169
olympux 46:971bdaa3507c 170
olympux 6:d054e394fba3 171 /*
olympux 46:971bdaa3507c 172 * UI threads
olympux 46:971bdaa3507c 173 */
olympux 46:971bdaa3507c 174 Thread t0(wdt_reset_thread);
olympux 40:c966abbe2d62 175
olympux 40:c966abbe2d62 176 // rpc
olympux 40:c966abbe2d62 177 RPCType::instance().register_types();
olympux 46:971bdaa3507c 178
olympux 4:568c97f2a407 179 /*
olympux 4:568c97f2a407 180 * Ethernet
olympux 4:568c97f2a407 181 */
olympux 6:d054e394fba3 182 ret = ethernet_init();
olympux 4:568c97f2a407 183 if (ret) {
olympux 18:ca499a2e7da6 184 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 185 while (true) {};
olympux 4:568c97f2a407 186 }
olympux 31:2e4b6de6c2f3 187
olympux 23:47ee805435b1 188 Thread::wait(2000); // TCP/UDP stack delay
olympux 46:971bdaa3507c 189
olympux 40:c966abbe2d62 190 // create rpc http server
olympux 40:c966abbe2d62 191 HTTPServer srv = create_interactive_server();
olympux 26:09e0dd020900 192
olympux 40:c966abbe2d62 193 if(!srv.init(SERVER_PORT))
olympux 40:c966abbe2d62 194 {
olympux 40:c966abbe2d62 195 eth.disconnect();
olympux 40:c966abbe2d62 196 return -1;
olympux 27:22f289beceb8 197 }
olympux 31:2e4b6de6c2f3 198
olympux 46:971bdaa3507c 199 srv.run();
olympux 26:09e0dd020900 200 }
olympux 26:09e0dd020900 201
olympux 26:09e0dd020900 202 /*
olympux 42:d0ff08711ca5 203 * W5500 Ethernet init
olympux 42:d0ff08711ca5 204 */
olympux 31:2e4b6de6c2f3 205 int ethernet_init(void)
olympux 31:2e4b6de6c2f3 206 {
olympux 26:09e0dd020900 207 int dhcp_ret, ret;
olympux 31:2e4b6de6c2f3 208
olympux 27:22f289beceb8 209 DBG("Initialising ethernet...");
olympux 31:2e4b6de6c2f3 210
olympux 26:09e0dd020900 211 // if not configured, try dhcp
olympux 26:09e0dd020900 212 dhcp_ret = -1;
olympux 46:971bdaa3507c 213 if (u16DeviceConfiguredFlag != DEFAULT_ENABLE_FLAG_VALUE) {
olympux 27:22f289beceb8 214 DBG("Connecting to DHCP server...");
olympux 46:971bdaa3507c 215 dhcp_ret = eth.init(u8MacAddr);
olympux 26:09e0dd020900 216 if (dhcp_ret == 0)
olympux 26:09e0dd020900 217 dhcp_ret = eth.connect();
olympux 26:09e0dd020900 218 }
olympux 31:2e4b6de6c2f3 219
olympux 26:09e0dd020900 220 if (dhcp_ret != 0) {
olympux 26:09e0dd020900 221 DBG("No DHCP, load static IP configuration");
olympux 46:971bdaa3507c 222 ret = eth.init(u8MacAddr, strIpAddr, strIpSubnet, strIpGateway); // static
olympux 26:09e0dd020900 223 } else {
olympux 46:971bdaa3507c 224 snprintf(strIpAddr, 16, "%s", eth.getIPAddress());
olympux 46:971bdaa3507c 225 snprintf(strIpSubnet, 16, "%s", eth.getNetworkMask());
olympux 46:971bdaa3507c 226 snprintf(strIpGateway, 16, "%s", eth.getGateway());
olympux 26:09e0dd020900 227 ret = 0;
olympux 26:09e0dd020900 228 }
olympux 26:09e0dd020900 229
olympux 26:09e0dd020900 230 if (ret == 0) {
olympux 26:09e0dd020900 231 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 26:09e0dd020900 232 } else {
olympux 26:09e0dd020900 233 ERR("Error eth.init() - ret = %d", ret);
olympux 26:09e0dd020900 234 return -1;
olympux 26:09e0dd020900 235 }
olympux 26:09e0dd020900 236
olympux 26:09e0dd020900 237 ret = eth.connect();
olympux 26:09e0dd020900 238 if (!ret) {
olympux 26:09e0dd020900 239 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 26:09e0dd020900 240 } else {
olympux 26:09e0dd020900 241 ERR("Error eth.connect() - ret = %d", ret);
olympux 26:09e0dd020900 242 return -1;
olympux 26:09e0dd020900 243 }
olympux 31:2e4b6de6c2f3 244
olympux 26:09e0dd020900 245 return 0;
olympux 26:09e0dd020900 246 }
olympux 26:09e0dd020900 247