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@41:a50a534a2fbb, 2016-06-16 (annotated)
- Committer:
- olympux
- Date:
- Thu Jun 16 09:12:20 2016 +0000
- Revision:
- 41:a50a534a2fbb
- Parent:
- 40:c966abbe2d62
- Child:
- 42:d0ff08711ca5
Fixed usage of string RPCVariable to include buffer length
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
olympux | 0:c2eac797face | 1 | /* |
olympux | 30:15e23257e786 | 2 | * Firmware supports NNIO and RPC protocols |
olympux | 30:15e23257e786 | 3 | */ |
olympux | 0:c2eac797face | 4 | #include "mbed.h" |
olympux | 27:22f289beceb8 | 5 | #include "rtos.h" |
olympux | 27:22f289beceb8 | 6 | #include "mbed_rpc.h" |
olympux | 27:22f289beceb8 | 7 | #include "Arguments.h" |
olympux | 27:22f289beceb8 | 8 | |
olympux | 12:7c152c0ca4d8 | 9 | #include "eeprom.h" |
olympux | 0:c2eac797face | 10 | #include "EthernetInterface.h" |
olympux | 9:d2534ecf88c6 | 11 | #include "NTPClient.h" |
olympux | 0:c2eac797face | 12 | |
olympux | 12:7c152c0ca4d8 | 13 | #include "my_eeprom_funcs.h" |
olympux | 20:71c7950fdd91 | 14 | #include "Watchdog.h" |
olympux | 12:7c152c0ca4d8 | 15 | |
olympux | 40:c966abbe2d62 | 16 | #include "RPCCommand.h" |
olympux | 40:c966abbe2d62 | 17 | #include "HTTPServer.h" |
olympux | 40:c966abbe2d62 | 18 | #include "Formatter.h" |
olympux | 40:c966abbe2d62 | 19 | #include "RequestHandler.h" |
olympux | 40:c966abbe2d62 | 20 | #include "RPCType.h" |
olympux | 40:c966abbe2d62 | 21 | |
olympux | 40:c966abbe2d62 | 22 | #define SERVER_PORT 80 |
olympux | 40:c966abbe2d62 | 23 | |
olympux | 0:c2eac797face | 24 | |
olympux | 31:2e4b6de6c2f3 | 25 | /** Debug option |
olympux | 31:2e4b6de6c2f3 | 26 | * |
olympux | 31:2e4b6de6c2f3 | 27 | */ |
olympux | 25:48dd18cc147c | 28 | #if 1 |
olympux | 16:84a5bf7285d0 | 29 | //Enable debug |
olympux | 16:84a5bf7285d0 | 30 | #include <cstdio> |
olympux | 31:2e4b6de6c2f3 | 31 | #define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__); |
olympux | 31:2e4b6de6c2f3 | 32 | #define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__); |
olympux | 31:2e4b6de6c2f3 | 33 | #define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__); |
olympux | 16:84a5bf7285d0 | 34 | #else |
olympux | 16:84a5bf7285d0 | 35 | //Disable debug |
olympux | 31:2e4b6de6c2f3 | 36 | #define DBG(x, ...) |
olympux | 16:84a5bf7285d0 | 37 | #define WARN(x, ...) |
olympux | 31:2e4b6de6c2f3 | 38 | #define ERR(x, ...) |
olympux | 16:84a5bf7285d0 | 39 | #endif |
olympux | 16:84a5bf7285d0 | 40 | |
olympux | 16:84a5bf7285d0 | 41 | |
olympux | 2:18f10e7209f4 | 42 | /* |
olympux | 2:18f10e7209f4 | 43 | * Hardware defines |
olympux | 0:c2eac797face | 44 | */ |
olympux | 9:d2534ecf88c6 | 45 | // Ethernet |
olympux | 0:c2eac797face | 46 | SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk |
olympux | 11:709f90a3b599 | 47 | EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset |
olympux | 40:c966abbe2d62 | 48 | int ethernet_init(void); |
olympux | 30:15e23257e786 | 49 | |
olympux | 30:15e23257e786 | 50 | /* |
olympux | 30:15e23257e786 | 51 | * EEPROM section |
olympux | 30:15e23257e786 | 52 | */ |
olympux | 30:15e23257e786 | 53 | // Virtual address defined by the user: 0xFFFF value is prohibited |
olympux | 30:15e23257e786 | 54 | uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr |
olympux | 30:15e23257e786 | 55 | 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet |
olympux | 30:15e23257e786 | 56 | 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway |
olympux | 30:15e23257e786 | 57 | 0x4212, // TCP server port, not used |
olympux | 30:15e23257e786 | 58 | 0x5212, // UDP server port, not used |
olympux | 30:15e23257e786 | 59 | 0x8888, // 1st run? 0xA5A5 = configured |
olympux | 30:15e23257e786 | 60 | 0x6212, 0x6313, 0x6414, // MAC |
olympux | 31:2e4b6de6c2f3 | 61 | |
olympux | 30:15e23257e786 | 62 | // this section is for the TCP server that this device connects to in TCP client mode |
olympux | 30:15e23257e786 | 63 | 0x7212, 0x7313, // 0xA5A5 = auto transmit status, time period |
olympux | 30:15e23257e786 | 64 | 0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address |
olympux | 30:15e23257e786 | 65 | 0x9212, // TCP server port |
olympux | 31:2e4b6de6c2f3 | 66 | |
olympux | 30:15e23257e786 | 67 | // this section is for selecting protocol, not used |
olympux | 30:15e23257e786 | 68 | 0xA212, // 0xA5A5 = enable TCP server |
olympux | 30:15e23257e786 | 69 | 0xA313, // 0xA5A5 = eanble TCP client |
olympux | 30:15e23257e786 | 70 | 0xA414 // 0xA5A5 = enable UDP server |
olympux | 31:2e4b6de6c2f3 | 71 | }; |
olympux | 31:2e4b6de6c2f3 | 72 | |
olympux | 30:15e23257e786 | 73 | |
olympux | 30:15e23257e786 | 74 | /* |
olympux | 30:15e23257e786 | 75 | * Variables for network configuration, TCP server |
olympux | 30:15e23257e786 | 76 | */ |
olympux | 30:15e23257e786 | 77 | uint8_t u8mac[6], u8ip_addr[4];// keep mac and ip address in 8-bits |
olympux | 30:15e23257e786 | 78 | uint16_t u16mac_addr[3], u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // 16-bits, directly loaded from eeprom |
olympux | 30:15e23257e786 | 79 | char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16]; // for printf, converted from 16-bits u16ip_xxx |
olympux | 30:15e23257e786 | 80 | uint16_t configured_ip = 0; // static ip configured flag |
olympux | 30:15e23257e786 | 81 | |
olympux | 30:15e23257e786 | 82 | const uint16_t tcp_server_local_port = 10000; // fixed, change to 7000 if internet required |
olympux | 30:15e23257e786 | 83 | const uint16_t udp_server_local_port = 11000; // fixed |
olympux | 30:15e23257e786 | 84 | |
olympux | 30:15e23257e786 | 85 | // TCP client: this section is used for the TCP server that this device connects to in TCP client mode |
olympux | 30:15e23257e786 | 86 | // this device will transmit status every transmit_time_period |
olympux | 30:15e23257e786 | 87 | uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s |
olympux | 30:15e23257e786 | 88 | uint16_t u16server_ip_addr[4]; // directly loaded from eeprom |
olympux | 30:15e23257e786 | 89 | uint8_t u8server_ip_addr[4]; // server ip address in 8-bits |
olympux | 30:15e23257e786 | 90 | char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr |
olympux | 30:15e23257e786 | 91 | uint16_t u16tcp_server_port; // directly loaded from eeprom |
olympux | 30:15e23257e786 | 92 | uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server |
olympux | 30:15e23257e786 | 93 | |
olympux | 30:15e23257e786 | 94 | |
olympux | 27:22f289beceb8 | 95 | // Serial |
olympux | 27:22f289beceb8 | 96 | Serial uart(USBTX,USBRX); |
olympux | 20:71c7950fdd91 | 97 | // Watchdog |
olympux | 20:71c7950fdd91 | 98 | Watchdog wdt; |
olympux | 20:71c7950fdd91 | 99 | |
olympux | 40:c966abbe2d62 | 100 | float speed; |
olympux | 40:c966abbe2d62 | 101 | RPCVariable<float> rpcSpeed(&speed, "speed"); |
olympux | 40:c966abbe2d62 | 102 | char stripaddr[20]; |
olympux | 41:a50a534a2fbb | 103 | RPCVariable<char*> rpcIPAddress(stripaddr, 20, "ipaddr"); |
olympux | 26:09e0dd020900 | 104 | |
olympux | 26:09e0dd020900 | 105 | |
olympux | 2:18f10e7209f4 | 106 | /* |
olympux | 2:18f10e7209f4 | 107 | * Threads |
olympux | 2:18f10e7209f4 | 108 | */ |
olympux | 20:71c7950fdd91 | 109 | // WDT reset |
olympux | 31:2e4b6de6c2f3 | 110 | void wdt_reset_thread(void const* args) |
olympux | 31:2e4b6de6c2f3 | 111 | { |
olympux | 20:71c7950fdd91 | 112 | while (true) |
olympux | 20:71c7950fdd91 | 113 | wdt.Service(); |
olympux | 20:71c7950fdd91 | 114 | } |
olympux | 20:71c7950fdd91 | 115 | |
olympux | 40:c966abbe2d62 | 116 | |
olympux | 40:c966abbe2d62 | 117 | HTTPServer create_simple_server() |
olympux | 40:c966abbe2d62 | 118 | { |
olympux | 40:c966abbe2d62 | 119 | HTTPServer srv; |
olympux | 40:c966abbe2d62 | 120 | srv.add_request_handler("DELETE", new DeleteRequestHandler()); |
olympux | 40:c966abbe2d62 | 121 | srv.add_request_handler("GET", new GetRequestHandler()); |
olympux | 40:c966abbe2d62 | 122 | srv.add_request_handler("PUT", new PutRequestHandler()); |
olympux | 40:c966abbe2d62 | 123 | return srv; |
olympux | 40:c966abbe2d62 | 124 | } |
olympux | 40:c966abbe2d62 | 125 | |
olympux | 40:c966abbe2d62 | 126 | HTTPServer create_interactive_server() |
olympux | 39:083cf93121a9 | 127 | { |
olympux | 40:c966abbe2d62 | 128 | HTTPServer srv(new InteractiveHTMLFormatter()); |
olympux | 40:c966abbe2d62 | 129 | srv.add_request_handler("GET", new ComplexRequestHandler()); |
olympux | 40:c966abbe2d62 | 130 | return srv; |
olympux | 38:f8735ae519aa | 131 | } |
olympux | 38:f8735ae519aa | 132 | |
olympux | 38:f8735ae519aa | 133 | // Main code |
olympux | 4:568c97f2a407 | 134 | int main() |
olympux | 4:568c97f2a407 | 135 | { |
olympux | 9:d2534ecf88c6 | 136 | int n, ret; |
olympux | 31:2e4b6de6c2f3 | 137 | |
olympux | 20:71c7950fdd91 | 138 | Thread::wait(500); // turn on delay |
olympux | 31:2e4b6de6c2f3 | 139 | |
olympux | 4:568c97f2a407 | 140 | /* |
olympux | 9:d2534ecf88c6 | 141 | * Configure |
olympux | 4:568c97f2a407 | 142 | */ |
olympux | 11:709f90a3b599 | 143 | uart.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 | 31:2e4b6de6c2f3 | 150 | |
olympux | 6:d054e394fba3 | 151 | /* |
olympux | 6:d054e394fba3 | 152 | * FLASH |
olympux | 6:d054e394fba3 | 153 | */ |
olympux | 12:7c152c0ca4d8 | 154 | load_eeprom_network(); |
olympux | 15:edeb0aed160d | 155 | load_eeprom_tcpserver(); |
olympux | 31:2e4b6de6c2f3 | 156 | |
olympux | 20:71c7950fdd91 | 157 | /* |
olympux | 20:71c7950fdd91 | 158 | * UI threads |
olympux | 20:71c7950fdd91 | 159 | */ |
olympux | 20:71c7950fdd91 | 160 | Thread t3(wdt_reset_thread); |
olympux | 40:c966abbe2d62 | 161 | |
olympux | 40:c966abbe2d62 | 162 | // rpc |
olympux | 40:c966abbe2d62 | 163 | RPCType::instance().register_types(); |
olympux | 31:2e4b6de6c2f3 | 164 | |
olympux | 4:568c97f2a407 | 165 | /* |
olympux | 4:568c97f2a407 | 166 | * Ethernet |
olympux | 4:568c97f2a407 | 167 | */ |
olympux | 6:d054e394fba3 | 168 | ret = ethernet_init(); |
olympux | 4:568c97f2a407 | 169 | if (ret) { |
olympux | 18:ca499a2e7da6 | 170 | ERR("Ethernet initialisation failed. App halted."); |
olympux | 4:568c97f2a407 | 171 | while (true) {}; |
olympux | 4:568c97f2a407 | 172 | } |
olympux | 31:2e4b6de6c2f3 | 173 | |
olympux | 23:47ee805435b1 | 174 | Thread::wait(2000); // TCP/UDP stack delay |
olympux | 40:c966abbe2d62 | 175 | |
olympux | 40:c966abbe2d62 | 176 | // Test parsing ip address string |
olympux | 40:c966abbe2d62 | 177 | char* ipaddr = "192.168.0.121"; |
olympux | 40:c966abbe2d62 | 178 | int b[4]; |
olympux | 40:c966abbe2d62 | 179 | sscanf(ipaddr, "%d.%d.%d.%d", &b[0], &b[1], &b[2], &b[3]); |
olympux | 40:c966abbe2d62 | 180 | DBG("%d.%d.%d.%d",b[0],b[1],b[2],b[3]); |
olympux | 31:2e4b6de6c2f3 | 181 | |
olympux | 40:c966abbe2d62 | 182 | // create rpc http server |
olympux | 40:c966abbe2d62 | 183 | HTTPServer srv = create_interactive_server(); |
olympux | 26:09e0dd020900 | 184 | |
olympux | 40:c966abbe2d62 | 185 | if(!srv.init(SERVER_PORT)) |
olympux | 40:c966abbe2d62 | 186 | { |
olympux | 40:c966abbe2d62 | 187 | eth.disconnect(); |
olympux | 40:c966abbe2d62 | 188 | return -1; |
olympux | 27:22f289beceb8 | 189 | } |
olympux | 31:2e4b6de6c2f3 | 190 | |
olympux | 40:c966abbe2d62 | 191 | srv.run(); |
olympux | 26:09e0dd020900 | 192 | } |
olympux | 26:09e0dd020900 | 193 | |
olympux | 26:09e0dd020900 | 194 | |
olympux | 26:09e0dd020900 | 195 | /* |
olympux | 26:09e0dd020900 | 196 | * W5500 Ethernet init |
olympux | 26:09e0dd020900 | 197 | */ |
olympux | 31:2e4b6de6c2f3 | 198 | int ethernet_init(void) |
olympux | 31:2e4b6de6c2f3 | 199 | { |
olympux | 26:09e0dd020900 | 200 | int dhcp_ret, ret; |
olympux | 31:2e4b6de6c2f3 | 201 | |
olympux | 27:22f289beceb8 | 202 | DBG("Initialising ethernet..."); |
olympux | 31:2e4b6de6c2f3 | 203 | |
olympux | 26:09e0dd020900 | 204 | // if not configured, try dhcp |
olympux | 26:09e0dd020900 | 205 | dhcp_ret = -1; |
olympux | 26:09e0dd020900 | 206 | if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) { |
olympux | 27:22f289beceb8 | 207 | DBG("Connecting to DHCP server..."); |
olympux | 26:09e0dd020900 | 208 | dhcp_ret = eth.init(u8mac); |
olympux | 26:09e0dd020900 | 209 | if (dhcp_ret == 0) |
olympux | 26:09e0dd020900 | 210 | dhcp_ret = eth.connect(); |
olympux | 26:09e0dd020900 | 211 | } |
olympux | 31:2e4b6de6c2f3 | 212 | |
olympux | 26:09e0dd020900 | 213 | if (dhcp_ret != 0) { |
olympux | 26:09e0dd020900 | 214 | DBG("No DHCP, load static IP configuration"); |
olympux | 26:09e0dd020900 | 215 | ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static |
olympux | 26:09e0dd020900 | 216 | } else { |
olympux | 26:09e0dd020900 | 217 | snprintf(str_ip_addr, 16, "%s", eth.getIPAddress()); |
olympux | 26:09e0dd020900 | 218 | snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask()); |
olympux | 26:09e0dd020900 | 219 | snprintf(str_ip_gateway, 16, "%s", eth.getGateway()); |
olympux | 26:09e0dd020900 | 220 | ret = 0; |
olympux | 26:09e0dd020900 | 221 | } |
olympux | 26:09e0dd020900 | 222 | |
olympux | 26:09e0dd020900 | 223 | if (ret == 0) { |
olympux | 26:09e0dd020900 | 224 | DBG("Initialized, MAC: %s", eth.getMACAddress()); |
olympux | 26:09e0dd020900 | 225 | } else { |
olympux | 26:09e0dd020900 | 226 | ERR("Error eth.init() - ret = %d", ret); |
olympux | 26:09e0dd020900 | 227 | return -1; |
olympux | 26:09e0dd020900 | 228 | } |
olympux | 26:09e0dd020900 | 229 | |
olympux | 26:09e0dd020900 | 230 | ret = eth.connect(); |
olympux | 26:09e0dd020900 | 231 | if (!ret) { |
olympux | 26:09e0dd020900 | 232 | DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway()); |
olympux | 26:09e0dd020900 | 233 | } else { |
olympux | 26:09e0dd020900 | 234 | ERR("Error eth.connect() - ret = %d", ret); |
olympux | 26:09e0dd020900 | 235 | return -1; |
olympux | 26:09e0dd020900 | 236 | } |
olympux | 31:2e4b6de6c2f3 | 237 | |
olympux | 26:09e0dd020900 | 238 | return 0; |
olympux | 26:09e0dd020900 | 239 | } |
olympux | 26:09e0dd020900 | 240 |