Network TCP/IP performance tester ported from Kai-Uwe Rommels NetIO 1.32 2012/11/22
Dependencies: EALib EthernetInterface NTPClient mbed-rtos mbed
main.cpp@0:a8301fc87d39, 2015-04-21 (annotated)
- Committer:
- jmehring
- Date:
- Tue Apr 21 09:36:19 2015 +0000
- Revision:
- 0:a8301fc87d39
initial port of NetIO from Kai-Uwe Rommel
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jmehring | 0:a8301fc87d39 | 1 | |
jmehring | 0:a8301fc87d39 | 2 | #include "mbed.h" |
jmehring | 0:a8301fc87d39 | 3 | #include "sdram.h" |
jmehring | 0:a8301fc87d39 | 4 | |
jmehring | 0:a8301fc87d39 | 5 | #define MEM_LIBC_MALLOC 1 |
jmehring | 0:a8301fc87d39 | 6 | #include "EthernetInterface.h" |
jmehring | 0:a8301fc87d39 | 7 | // #include "NTPClient.h" |
jmehring | 0:a8301fc87d39 | 8 | #include "lwip/opt.h" |
jmehring | 0:a8301fc87d39 | 9 | #include "lwip/sockets.h" |
jmehring | 0:a8301fc87d39 | 10 | #include "lwip/sys.h" |
jmehring | 0:a8301fc87d39 | 11 | |
jmehring | 0:a8301fc87d39 | 12 | // mbed stuff |
jmehring | 0:a8301fc87d39 | 13 | DigitalOut led1(LED1); |
jmehring | 0:a8301fc87d39 | 14 | Serial pc(USBTX, USBRX); |
jmehring | 0:a8301fc87d39 | 15 | Timer t; |
jmehring | 0:a8301fc87d39 | 16 | Ticker blinker; |
jmehring | 0:a8301fc87d39 | 17 | |
jmehring | 0:a8301fc87d39 | 18 | |
jmehring | 0:a8301fc87d39 | 19 | #define DEFAULTPORT 0x494F /* "IO" */ |
jmehring | 0:a8301fc87d39 | 20 | |
jmehring | 0:a8301fc87d39 | 21 | #define INTERVAL 6 |
jmehring | 0:a8301fc87d39 | 22 | |
jmehring | 0:a8301fc87d39 | 23 | int nSizes[] = {1024, 2048, 4096, 8192, 16384, 32768}; |
jmehring | 0:a8301fc87d39 | 24 | size_t nnSizes = sizeof(nSizes) / sizeof(int); |
jmehring | 0:a8301fc87d39 | 25 | #define NMAXSIZE 65536 |
jmehring | 0:a8301fc87d39 | 26 | |
jmehring | 0:a8301fc87d39 | 27 | int tSizes[] = {1024, 2048, 4096, 8192, 16384, 32767}; |
jmehring | 0:a8301fc87d39 | 28 | size_t ntSizes = sizeof(tSizes) / sizeof(int); |
jmehring | 0:a8301fc87d39 | 29 | #define TMAXSIZE 65536 |
jmehring | 0:a8301fc87d39 | 30 | |
jmehring | 0:a8301fc87d39 | 31 | |
jmehring | 0:a8301fc87d39 | 32 | #define KB(nSize) ((nSize) + 512) / 1024 |
jmehring | 0:a8301fc87d39 | 33 | |
jmehring | 0:a8301fc87d39 | 34 | typedef struct { |
jmehring | 0:a8301fc87d39 | 35 | uint32_t cmd; |
jmehring | 0:a8301fc87d39 | 36 | uint32_t data; |
jmehring | 0:a8301fc87d39 | 37 | } CONTROL; |
jmehring | 0:a8301fc87d39 | 38 | |
jmehring | 0:a8301fc87d39 | 39 | #define CMD_NONE 0 |
jmehring | 0:a8301fc87d39 | 40 | #define CMD_C2S 1 |
jmehring | 0:a8301fc87d39 | 41 | #define CMD_S2C 2 |
jmehring | 0:a8301fc87d39 | 42 | #define CMD_RES 3 |
jmehring | 0:a8301fc87d39 | 43 | |
jmehring | 0:a8301fc87d39 | 44 | #define CTLSIZE sizeof(CONTROL) |
jmehring | 0:a8301fc87d39 | 45 | |
jmehring | 0:a8301fc87d39 | 46 | int nPort = DEFAULTPORT; |
jmehring | 0:a8301fc87d39 | 47 | |
jmehring | 0:a8301fc87d39 | 48 | |
jmehring | 0:a8301fc87d39 | 49 | static void blink(void) { |
jmehring | 0:a8301fc87d39 | 50 | led1 = !led1; |
jmehring | 0:a8301fc87d39 | 51 | } |
jmehring | 0:a8301fc87d39 | 52 | |
jmehring | 0:a8301fc87d39 | 53 | |
jmehring | 0:a8301fc87d39 | 54 | static void StartTimer(void) { |
jmehring | 0:a8301fc87d39 | 55 | t.reset(); |
jmehring | 0:a8301fc87d39 | 56 | t.start(); |
jmehring | 0:a8301fc87d39 | 57 | } |
jmehring | 0:a8301fc87d39 | 58 | |
jmehring | 0:a8301fc87d39 | 59 | |
jmehring | 0:a8301fc87d39 | 60 | static float ReadTimer(void) { |
jmehring | 0:a8301fc87d39 | 61 | return t.read(); |
jmehring | 0:a8301fc87d39 | 62 | } |
jmehring | 0:a8301fc87d39 | 63 | |
jmehring | 0:a8301fc87d39 | 64 | |
jmehring | 0:a8301fc87d39 | 65 | static float StopTimer(void) { |
jmehring | 0:a8301fc87d39 | 66 | t.stop(); |
jmehring | 0:a8301fc87d39 | 67 | return ReadTimer(); |
jmehring | 0:a8301fc87d39 | 68 | } |
jmehring | 0:a8301fc87d39 | 69 | |
jmehring | 0:a8301fc87d39 | 70 | |
jmehring | 0:a8301fc87d39 | 71 | static void GenerateRandomData(char *cBuffer, size_t nSize) { |
jmehring | 0:a8301fc87d39 | 72 | if (cBuffer != NULL) { |
jmehring | 0:a8301fc87d39 | 73 | size_t i; |
jmehring | 0:a8301fc87d39 | 74 | |
jmehring | 0:a8301fc87d39 | 75 | cBuffer[0] = 0; |
jmehring | 0:a8301fc87d39 | 76 | srand(time(NULL)); |
jmehring | 0:a8301fc87d39 | 77 | |
jmehring | 0:a8301fc87d39 | 78 | for (i = 1; i < nSize; i++) |
jmehring | 0:a8301fc87d39 | 79 | cBuffer[i] = (char) rand(); |
jmehring | 0:a8301fc87d39 | 80 | } |
jmehring | 0:a8301fc87d39 | 81 | } |
jmehring | 0:a8301fc87d39 | 82 | |
jmehring | 0:a8301fc87d39 | 83 | |
jmehring | 0:a8301fc87d39 | 84 | static char *InitBuffer(size_t nSize) { |
jmehring | 0:a8301fc87d39 | 85 | char *cBuffer = (char *)malloc(nSize); |
jmehring | 0:a8301fc87d39 | 86 | |
jmehring | 0:a8301fc87d39 | 87 | GenerateRandomData(cBuffer, nSize); |
jmehring | 0:a8301fc87d39 | 88 | return cBuffer; |
jmehring | 0:a8301fc87d39 | 89 | } |
jmehring | 0:a8301fc87d39 | 90 | |
jmehring | 0:a8301fc87d39 | 91 | |
jmehring | 0:a8301fc87d39 | 92 | static int send_data(int socket, void *buffer, size_t size, int flags) { |
jmehring | 0:a8301fc87d39 | 93 | int rc = lwip_send(socket, buffer, size, flags); |
jmehring | 0:a8301fc87d39 | 94 | |
jmehring | 0:a8301fc87d39 | 95 | if (rc < 0) { |
jmehring | 0:a8301fc87d39 | 96 | printf("send error\n"); |
jmehring | 0:a8301fc87d39 | 97 | return -1; |
jmehring | 0:a8301fc87d39 | 98 | } |
jmehring | 0:a8301fc87d39 | 99 | |
jmehring | 0:a8301fc87d39 | 100 | if (rc != size) |
jmehring | 0:a8301fc87d39 | 101 | return 1; |
jmehring | 0:a8301fc87d39 | 102 | |
jmehring | 0:a8301fc87d39 | 103 | return 0; |
jmehring | 0:a8301fc87d39 | 104 | } |
jmehring | 0:a8301fc87d39 | 105 | |
jmehring | 0:a8301fc87d39 | 106 | |
jmehring | 0:a8301fc87d39 | 107 | static int recv_data(int socket, void *buffer, size_t size, int flags) { |
jmehring | 0:a8301fc87d39 | 108 | int rc = lwip_recv(socket, buffer, size, flags); |
jmehring | 0:a8301fc87d39 | 109 | |
jmehring | 0:a8301fc87d39 | 110 | if (rc < 0) { |
jmehring | 0:a8301fc87d39 | 111 | printf("recv error\n"); |
jmehring | 0:a8301fc87d39 | 112 | return -1; |
jmehring | 0:a8301fc87d39 | 113 | } |
jmehring | 0:a8301fc87d39 | 114 | |
jmehring | 0:a8301fc87d39 | 115 | if (rc != size) |
jmehring | 0:a8301fc87d39 | 116 | return 1; |
jmehring | 0:a8301fc87d39 | 117 | |
jmehring | 0:a8301fc87d39 | 118 | return 0; |
jmehring | 0:a8301fc87d39 | 119 | } |
jmehring | 0:a8301fc87d39 | 120 | |
jmehring | 0:a8301fc87d39 | 121 | |
jmehring | 0:a8301fc87d39 | 122 | static void netio_server (const void *arg) { |
jmehring | 0:a8301fc87d39 | 123 | char *cBuffer; |
jmehring | 0:a8301fc87d39 | 124 | CONTROL ctl; |
jmehring | 0:a8301fc87d39 | 125 | float nTime; |
jmehring | 0:a8301fc87d39 | 126 | long long nData; |
jmehring | 0:a8301fc87d39 | 127 | struct sockaddr_in sa_server, sa_client; |
jmehring | 0:a8301fc87d39 | 128 | int server, client; |
jmehring | 0:a8301fc87d39 | 129 | socklen_t length; |
jmehring | 0:a8301fc87d39 | 130 | struct timeval tv; |
jmehring | 0:a8301fc87d39 | 131 | fd_set fds; |
jmehring | 0:a8301fc87d39 | 132 | int rc; |
jmehring | 0:a8301fc87d39 | 133 | int nByte; |
jmehring | 0:a8301fc87d39 | 134 | |
jmehring | 0:a8301fc87d39 | 135 | if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) { |
jmehring | 0:a8301fc87d39 | 136 | printf("malloc error\n"); |
jmehring | 0:a8301fc87d39 | 137 | return; |
jmehring | 0:a8301fc87d39 | 138 | } |
jmehring | 0:a8301fc87d39 | 139 | |
jmehring | 0:a8301fc87d39 | 140 | server = lwip_socket(AF_INET, SOCK_STREAM, 0); |
jmehring | 0:a8301fc87d39 | 141 | if (server < 0) { |
jmehring | 0:a8301fc87d39 | 142 | printf("socket error\n"); |
jmehring | 0:a8301fc87d39 | 143 | free(cBuffer); |
jmehring | 0:a8301fc87d39 | 144 | return; |
jmehring | 0:a8301fc87d39 | 145 | } |
jmehring | 0:a8301fc87d39 | 146 | |
jmehring | 0:a8301fc87d39 | 147 | sa_server.sin_family = AF_INET; |
jmehring | 0:a8301fc87d39 | 148 | sa_server.sin_port = htons(nPort); |
jmehring | 0:a8301fc87d39 | 149 | sa_server.sin_addr.s_addr = INADDR_ANY; |
jmehring | 0:a8301fc87d39 | 150 | if (lwip_bind(server, (struct sockaddr *)&sa_server, sizeof(sa_server)) < 0) { |
jmehring | 0:a8301fc87d39 | 151 | printf("bind error\n"); |
jmehring | 0:a8301fc87d39 | 152 | lwip_close(server); |
jmehring | 0:a8301fc87d39 | 153 | free(cBuffer); |
jmehring | 0:a8301fc87d39 | 154 | return; |
jmehring | 0:a8301fc87d39 | 155 | } |
jmehring | 0:a8301fc87d39 | 156 | |
jmehring | 0:a8301fc87d39 | 157 | if (lwip_listen(server, 1) != 0) { |
jmehring | 0:a8301fc87d39 | 158 | printf("listen error\n"); |
jmehring | 0:a8301fc87d39 | 159 | lwip_close(server); |
jmehring | 0:a8301fc87d39 | 160 | free(cBuffer); |
jmehring | 0:a8301fc87d39 | 161 | return; |
jmehring | 0:a8301fc87d39 | 162 | } |
jmehring | 0:a8301fc87d39 | 163 | |
jmehring | 0:a8301fc87d39 | 164 | for (;;) { |
jmehring | 0:a8301fc87d39 | 165 | printf("TCP server listening.\n"); |
jmehring | 0:a8301fc87d39 | 166 | |
jmehring | 0:a8301fc87d39 | 167 | FD_ZERO(&fds); |
jmehring | 0:a8301fc87d39 | 168 | FD_SET(server, &fds); |
jmehring | 0:a8301fc87d39 | 169 | tv.tv_sec = 3600; |
jmehring | 0:a8301fc87d39 | 170 | tv.tv_usec = 0; |
jmehring | 0:a8301fc87d39 | 171 | |
jmehring | 0:a8301fc87d39 | 172 | if ((rc = lwip_select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0) { |
jmehring | 0:a8301fc87d39 | 173 | printf("select error\n"); |
jmehring | 0:a8301fc87d39 | 174 | break; |
jmehring | 0:a8301fc87d39 | 175 | } |
jmehring | 0:a8301fc87d39 | 176 | |
jmehring | 0:a8301fc87d39 | 177 | if (rc == 0 || FD_ISSET(server, &fds) == 0) |
jmehring | 0:a8301fc87d39 | 178 | continue; |
jmehring | 0:a8301fc87d39 | 179 | |
jmehring | 0:a8301fc87d39 | 180 | length = sizeof(sa_client); |
jmehring | 0:a8301fc87d39 | 181 | if ((client = lwip_accept(server, (struct sockaddr *) &sa_client, &length)) == -1) |
jmehring | 0:a8301fc87d39 | 182 | continue; |
jmehring | 0:a8301fc87d39 | 183 | |
jmehring | 0:a8301fc87d39 | 184 | printf("TCP connection established.\n"); |
jmehring | 0:a8301fc87d39 | 185 | |
jmehring | 0:a8301fc87d39 | 186 | for (;;) { |
jmehring | 0:a8301fc87d39 | 187 | if (recv_data(client, (void *) &ctl, CTLSIZE, 0)) |
jmehring | 0:a8301fc87d39 | 188 | break; |
jmehring | 0:a8301fc87d39 | 189 | |
jmehring | 0:a8301fc87d39 | 190 | ctl.cmd = ntohl(ctl.cmd); |
jmehring | 0:a8301fc87d39 | 191 | ctl.data = ntohl(ctl.data); |
jmehring | 0:a8301fc87d39 | 192 | |
jmehring | 0:a8301fc87d39 | 193 | if (ctl.cmd == CMD_C2S) { |
jmehring | 0:a8301fc87d39 | 194 | printf("Packet size %2uk bytes: ", KB(ctl.data)); |
jmehring | 0:a8301fc87d39 | 195 | fflush(stdout); |
jmehring | 0:a8301fc87d39 | 196 | nData = 0; |
jmehring | 0:a8301fc87d39 | 197 | StartTimer(); |
jmehring | 0:a8301fc87d39 | 198 | |
jmehring | 0:a8301fc87d39 | 199 | do { |
jmehring | 0:a8301fc87d39 | 200 | for (nByte = 0; nByte < ctl.data; ) { |
jmehring | 0:a8301fc87d39 | 201 | rc = lwip_recv(client, cBuffer + nByte, ctl.data - nByte, 0); |
jmehring | 0:a8301fc87d39 | 202 | |
jmehring | 0:a8301fc87d39 | 203 | if (rc < 0) { |
jmehring | 0:a8301fc87d39 | 204 | printf("recv error\n"); |
jmehring | 0:a8301fc87d39 | 205 | break; |
jmehring | 0:a8301fc87d39 | 206 | } |
jmehring | 0:a8301fc87d39 | 207 | |
jmehring | 0:a8301fc87d39 | 208 | if (rc > 0) |
jmehring | 0:a8301fc87d39 | 209 | nByte += rc; |
jmehring | 0:a8301fc87d39 | 210 | } |
jmehring | 0:a8301fc87d39 | 211 | |
jmehring | 0:a8301fc87d39 | 212 | nData += ctl.data; |
jmehring | 0:a8301fc87d39 | 213 | } while (cBuffer[0] == 0 && rc > 0); |
jmehring | 0:a8301fc87d39 | 214 | |
jmehring | 0:a8301fc87d39 | 215 | if ((nTime = StopTimer()) != -1) { |
jmehring | 0:a8301fc87d39 | 216 | printf(" %0.2f KByte/s Rx", nData / 1024 / nTime); |
jmehring | 0:a8301fc87d39 | 217 | fflush(stdout); |
jmehring | 0:a8301fc87d39 | 218 | } |
jmehring | 0:a8301fc87d39 | 219 | } else if (ctl.cmd == CMD_S2C) { |
jmehring | 0:a8301fc87d39 | 220 | cBuffer[0] = 0; |
jmehring | 0:a8301fc87d39 | 221 | nData = 0; |
jmehring | 0:a8301fc87d39 | 222 | |
jmehring | 0:a8301fc87d39 | 223 | StartTimer(); |
jmehring | 0:a8301fc87d39 | 224 | |
jmehring | 0:a8301fc87d39 | 225 | while (ReadTimer() < INTERVAL) { |
jmehring | 0:a8301fc87d39 | 226 | //GenerateRandomData(cBuffer, ctl.data); |
jmehring | 0:a8301fc87d39 | 227 | |
jmehring | 0:a8301fc87d39 | 228 | for (nByte = 0; nByte < ctl.data; ) { |
jmehring | 0:a8301fc87d39 | 229 | rc = lwip_send(client, cBuffer + nByte, ctl.data - nByte, 0); |
jmehring | 0:a8301fc87d39 | 230 | |
jmehring | 0:a8301fc87d39 | 231 | if (rc < 0) { |
jmehring | 0:a8301fc87d39 | 232 | printf("send error\n"); |
jmehring | 0:a8301fc87d39 | 233 | break; |
jmehring | 0:a8301fc87d39 | 234 | } |
jmehring | 0:a8301fc87d39 | 235 | |
jmehring | 0:a8301fc87d39 | 236 | if (rc > 0) |
jmehring | 0:a8301fc87d39 | 237 | nByte += rc; |
jmehring | 0:a8301fc87d39 | 238 | } |
jmehring | 0:a8301fc87d39 | 239 | |
jmehring | 0:a8301fc87d39 | 240 | nData += ctl.data; |
jmehring | 0:a8301fc87d39 | 241 | } |
jmehring | 0:a8301fc87d39 | 242 | |
jmehring | 0:a8301fc87d39 | 243 | cBuffer[0] = 1; |
jmehring | 0:a8301fc87d39 | 244 | |
jmehring | 0:a8301fc87d39 | 245 | if (send_data(client, cBuffer, ctl.data, 0)) |
jmehring | 0:a8301fc87d39 | 246 | break; |
jmehring | 0:a8301fc87d39 | 247 | |
jmehring | 0:a8301fc87d39 | 248 | if ((nTime = StopTimer()) != -1) { |
jmehring | 0:a8301fc87d39 | 249 | printf(", %0.2f KByte/s Tx\n", nData / 1024 / nTime); |
jmehring | 0:a8301fc87d39 | 250 | } |
jmehring | 0:a8301fc87d39 | 251 | } else { |
jmehring | 0:a8301fc87d39 | 252 | // quit |
jmehring | 0:a8301fc87d39 | 253 | break; |
jmehring | 0:a8301fc87d39 | 254 | } |
jmehring | 0:a8301fc87d39 | 255 | } |
jmehring | 0:a8301fc87d39 | 256 | printf("Done.\n"); |
jmehring | 0:a8301fc87d39 | 257 | |
jmehring | 0:a8301fc87d39 | 258 | lwip_close(client); |
jmehring | 0:a8301fc87d39 | 259 | |
jmehring | 0:a8301fc87d39 | 260 | if (rc < 0) |
jmehring | 0:a8301fc87d39 | 261 | break; |
jmehring | 0:a8301fc87d39 | 262 | } |
jmehring | 0:a8301fc87d39 | 263 | lwip_close(server); |
jmehring | 0:a8301fc87d39 | 264 | |
jmehring | 0:a8301fc87d39 | 265 | free(cBuffer); |
jmehring | 0:a8301fc87d39 | 266 | } |
jmehring | 0:a8301fc87d39 | 267 | |
jmehring | 0:a8301fc87d39 | 268 | |
jmehring | 0:a8301fc87d39 | 269 | int main() { |
jmehring | 0:a8301fc87d39 | 270 | pc.baud(115200); |
jmehring | 0:a8301fc87d39 | 271 | |
jmehring | 0:a8301fc87d39 | 272 | if (sdram_init() == 0) { |
jmehring | 0:a8301fc87d39 | 273 | printf("SDRAM initialized\n"); |
jmehring | 0:a8301fc87d39 | 274 | } else { |
jmehring | 0:a8301fc87d39 | 275 | printf("Failed to initialized SDRAM\n"); |
jmehring | 0:a8301fc87d39 | 276 | } |
jmehring | 0:a8301fc87d39 | 277 | |
jmehring | 0:a8301fc87d39 | 278 | blinker.attach(&blink, 0.5); |
jmehring | 0:a8301fc87d39 | 279 | |
jmehring | 0:a8301fc87d39 | 280 | EthernetInterface eth; |
jmehring | 0:a8301fc87d39 | 281 | eth.init(); // Use DHCP |
jmehring | 0:a8301fc87d39 | 282 | eth.connect(); |
jmehring | 0:a8301fc87d39 | 283 | printf("IP Address is %s\n", eth.getIPAddress()); |
jmehring | 0:a8301fc87d39 | 284 | |
jmehring | 0:a8301fc87d39 | 285 | /* |
jmehring | 0:a8301fc87d39 | 286 | NTPClient ntp; |
jmehring | 0:a8301fc87d39 | 287 | if (ntp.setTime("0.pool.ntp.org") == 0) { |
jmehring | 0:a8301fc87d39 | 288 | printf("Set time successfully\n"); |
jmehring | 0:a8301fc87d39 | 289 | time_t rawtime = time(NULL) + (2 * 60 * 60); |
jmehring | 0:a8301fc87d39 | 290 | struct tm *timeinfo = localtime(&rawtime); |
jmehring | 0:a8301fc87d39 | 291 | strftime(buffer, sizeof(buffer), "Time: %d.%m.%Y %H:%M:%S", timeinfo); |
jmehring | 0:a8301fc87d39 | 292 | printf("%s\n", buffer); |
jmehring | 0:a8301fc87d39 | 293 | } else { |
jmehring | 0:a8301fc87d39 | 294 | printf("NTP Error\n"); |
jmehring | 0:a8301fc87d39 | 295 | } |
jmehring | 0:a8301fc87d39 | 296 | */ |
jmehring | 0:a8301fc87d39 | 297 | |
jmehring | 0:a8301fc87d39 | 298 | Thread thread(netio_server); |
jmehring | 0:a8301fc87d39 | 299 | |
jmehring | 0:a8301fc87d39 | 300 | while(1) { |
jmehring | 0:a8301fc87d39 | 301 | Thread::wait(60000); |
jmehring | 0:a8301fc87d39 | 302 | } |
jmehring | 0:a8301fc87d39 | 303 | |
jmehring | 0:a8301fc87d39 | 304 | // eth.disconnect(); |
jmehring | 0:a8301fc87d39 | 305 | } |