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@42:d0ff08711ca5, 2016-06-16 (annotated)
- 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?
User | Revision | Line number | New 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 |