Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface mbed-rtos mbed
Fork of FRDM_K64F-Ethernet by
Diff: main.cpp
- Revision:
- 1:2944c0d494ff
- Parent:
- 0:bbc9cfdee3bc
- Child:
- 2:28ddb9b073ec
--- a/main.cpp Mon Sep 22 02:34:12 2014 +0000
+++ b/main.cpp Thu Oct 11 15:25:58 2018 +0000
@@ -1,38 +1,143 @@
+/*
+** Super lightweight, not at all robust, TFTP server for FRDM-K64F eval board.
+** This tool supports read-only access to one file. It does not support NACK responses
+** or timeouts. The tool is intended for use by our test department to check out Ethernet
+** functionality on our main processor board.
+**
+** 11 October 2018
+** - am
+*/
+
#include "mbed.h"
#include "EthernetInterface.h"
-
-#define MBED_DEV_IP "192.168.0.52"
-#define MBED_DEV_MASK "255.255.255.0"
-#define MBED_DEV_GW "0.0.0.0"
-#define ECHO_SERVER_PORT 5000
+#include "string.h"
+
+#include "env.h"
+
+#define IP_ADDR "192.168.1.10"
+#define NET_MASK "255.255.255.0"
+#define GATEWAY "192.168.1.1"
+#define TFTP_PORT 69
+
+#define LED_ON 0
+#define LED_OFF 1
+
+// status LEDs
+DigitalOut led_error(LED1); // red
+DigitalOut led_waiting(LED2); // green
+DigitalOut led_connected(LED3); // blue
+
+// TFTP opcodes
+enum opcode { RRQ=1, WRQ, DATA, ACK, ERROR };
+
+// TFTP packet structure
+typedef union {
+
+ uint16_t opcode;
+
+ struct {
+ uint16_t opcode; // RRQ or WRQ
+ char filename_and_mode[512];
+ } request;
-
+ struct {
+ uint16_t opcode; // DATA
+ uint16_t block_number;
+ char data[512];
+ } data;
+
+ struct {
+ uint16_t opcode; // ACK
+ uint16_t block_number;
+ } ack;
+
+ struct {
+ uint16_t opcode; // ERROR
+ uint16_t error_code;
+ char error_string[512];
+ } error;
+
+} tftp_packet_t;
+
+int tftp_send_error(UDPSocket socket, Endpoint end_point, int error_code, char *error_string) {
+
+ tftp_packet_t packet;
+ char *packet_ptr = (char *)&packet;
+
+ packet.opcode = htons(ERROR);
+ packet.error.error_code = htons(error_code);
+ strcpy(packet.error.error_string, error_string);
+
+ return socket.sendTo(end_point, packet_ptr, 4 + strlen(error_string)); // 4 = sizeof(opcode + error_code)
+}
+
int main (void) {
+
EthernetInterface eth;
- eth.init(MBED_DEV_IP, MBED_DEV_MASK, MBED_DEV_GW); //Assign a device ip, mask and gateway
+ UDPSocket tftp_server;
+ Endpoint client;
+
+ // create data packet storage
+ tftp_packet_t packet;
+ char *packet_ptr = (char *)&packet;
+
+ // assign ip address, net mask and gateway to Ethernet interface
+ eth.init(IP_ADDR, NET_MASK, GATEWAY);
eth.connect();
- printf("IP Address is %s\n", eth.getIPAddress());
- TCPSocketServer server;
- server.bind(ECHO_SERVER_PORT);
- server.listen();
-
+ // main loop
while (true) {
- printf("\nWait for new connection...\n");
- TCPSocketConnection client;
- server.accept(client);
- client.set_blocking(false, 1500); // Timeout after (1.5)s
-
- printf("Connection from: %s\n", client.get_address());
- char buffer[256];
- while (true) {
- int n = client.receive(buffer, sizeof(buffer));
- if (n <= 0) break;
-
- client.send_all(buffer, n);
- if (n <= 0) break;
+
+ // clear status LEDs
+ led_error = LED_OFF;
+ led_waiting = LED_OFF;
+ led_connected = LED_OFF;
+ wait(1); // one second
+
+ // wait for request
+ led_waiting = LED_ON;
+ tftp_server.bind(TFTP_PORT);
+ tftp_server.receiveFrom(client, packet_ptr, sizeof(packet));
+
+ // if it's a read request
+ if (ntohs(packet.opcode) == RRQ) {
+ // and it's for the environment file
+ if (!strncmp(packet.request.filename_and_mode, "/production/u-boot-env_txt", 26)) {
+ led_waiting = LED_OFF;
+ // send file
+ int i_block = 1;
+ int i_string = 0;
+ int i_char = 0;
+ int i_buff = 512;
+ while (i_buff == 512) {
+ led_connected = LED_ON;
+ i_buff = 0;
+ packet.opcode = htons(DATA);
+ packet.data.block_number = htons(i_block++);
+ do {
+ packet.data.data[i_buff++] = env_string[i_string][i_char++];
+ // check for end of string
+ if (env_string[i_string][i_char] == '\0') {
+ i_char = 0;
+ i_string++;
+ }
+ } while ((i_buff < 512) && (env_string[i_string][0] != '\0'));
+ tftp_server.sendTo(client, packet_ptr, 4 + i_buff); // 4 = sizeof(opcode + block_number)
+ led_connected = LED_OFF;
+ led_error = LED_ON;
+ tftp_server.receiveFrom(client, packet_ptr, sizeof(packet)); // wait for ACK
+ led_error = LED_OFF;
+ };
+ }
+ // error, we only support the u-boot-env.txt file
+ else tftp_send_error(tftp_server, client, 0, "this test board only supports reading the u-boot-env.txt file");
}
-
- client.close();
+ // error, we only support read requests
+ else tftp_send_error(tftp_server, client, 0, "this test board only supports reading the u-boot-env.txt file");
+
+ led_connected = LED_ON;
+ led_waiting = LED_ON;
+ wait(1); // one second
+ tftp_server.close();
}
-}
\ No newline at end of file
+}
