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
main.cpp@47:d92d2c5b8073, 2016-08-19 (annotated)
- 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?
User | Revision | Line number | New 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 |