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
main.cpp
- Committer:
- audim
- Date:
- 2018-10-11
- Revision:
- 1:2944c0d494ff
- Parent:
- 0:bbc9cfdee3bc
- Child:
- 2:28ddb9b073ec
File content as of revision 1:2944c0d494ff:
/*
** 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"
#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;
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();
// main loop
while (true) {
// 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");
}
// 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();
}
}
