Fall Semester 2009
Eran Cohen, 038175436
Bar Avidan, 300319886
Our project implements a tftp-server (Trivial File Transfer Protocol) over uIP connections with our LPC Board. The data is read from / written to the CAT non-volatile memory using I2C transactions.
The device is connected to any PC via usb, and registers itself as an ethernet device. The PC sends ethernet packets as if our device is a regular ethernet card. The uIP module analyzes those packets to see if they are addressed to the local TFTP server. If so, it forwards the relevant packets that are handled by the TFTP.
As you would guess, the project uses the open source library uIP, ported for LPC2148 processors. Other than that, we've implemented the following modules:
1. A module to read & write ethernet packets. Reads bytes directly from the usb endpoint, and analyzes the ethernet header. The main goal of this module is to read / write whole packets from the bytes stream.
The code can be found under: ethernet
2. A module to handle the TFTP packets. We've chosen TFTP for two main reasons:
It's a simple protocol.
It's a well-defined one, with various clients that can be used from/ installed on any OS.
NOTE: We've implemented a tftp client suited for our needs, meaning it can read up to 256 bytes of DATA. An attempt to write a file larger than that or read a non existing file is replied by the appropriate error code.
The code can be found under: tftp
3. A module to use the CAT memory. We were able to use our I2C transactions code from class exercise #4, and implement a driver from reading and writing to the memory. We also implemented a
The code can be found under: cat
4. A simple file system, over the CAT memory, Since the "FS" is rather small, we keep only a single file, and its name.
The code can be found under: fs
1. We thought it would be nice to write the name of the current file on the LCD (done!)
2. We can implement virtual files (e.g. /proc/temp that would return the current temperature, or /proc/buzzer that would turn the buzzer on/off etc)
This can be done quite easily, and would make it 'cooler', but unfortunately we had no time to do so.
3. We can use an SD card on the board, and build a real file system.
A little bit about TFTP:
TFTP supports five types of packets, all of which have been mentioned above:
1 Read request (RRQ)
2 Write request (WRQ)
3 Data (DATA)
4 Acknowledgment (ACK)
5 Error (ERROR)
The TFTP header of a packet contains the opcode associated with that packet.
2 bytes string 1 byte string 1 byte
| Opcode | Filename | 0 | Mode | 0 |
Figure 1: RRQ/WRQ packet
2 bytes 2 bytes n bytes
| Opcode | Block # | Data |
Figure 2: DATA packet
For a full tftp description you can view the TFTP definition (RFC #783)
You can also find a sample tftp-client here: http://www.cs.tau.ac.il/~baravid1/tftp
1. To register the device we used a USB decriptor for Belkin: vendor - 0x050d, product - 0x0004, BCD - 0x0100.
2. The TFTP-server's address is hard coded. The address is 10.0.0.66
3. Before starting to use the device, please give it an appropriate IP address. Use: ifconfig usb0 [ip_addr]. We recommend giving it an IP in the segment 10.0.0.xxx so the routing tables will automatically route messages for 10.0.0.66 through this device.
4. Since we used cdc_subset drivers to subscribe our device as an ethernet device, the project doesn't work in the school's labs (The relevant driver is not installed), We've tested it on our ubuntu liveCD, and it works.
The Tale of the vanishing packets (Bar & Eran's Blog):
Here we will include our insights from the projects / course.
Some of the difficulties we encountered (given by chronological order) :
1. Failing to find a matching USB descriptor: Most usb providers don't have any reason to put their usb descriptor for open source use. Our first attempts to write our own driver, without really knowing what's required by the PC-installed driver took a loooong time.
2. Failing to read/write ethernet packets: This stage held several difficulties. First, we needed to understand what packets are we handling. Since we are impersonating an ethernet card, we receive the packets in it's raw form (without the premble). After we were able to resolve that matter, we needed to handle the endpoints used by the cdc_subset driver. This driver has very poor documentation online, so we needed to drill through it's source code and sample files to understand how to fully use it. We didn't even know how to see the data written to the MCU. After many searching we found usbmon to do so.
3. Intergrating the uIP module: WOW. This was a tough one. Let's start by having to choose an appropriate uIP port. Some of these ports are poorly written, others had unnecessary modules that didn't compile etc. Once we found a good uIP, we needed to integrate it onto our code. Luckily for us, uIP has plentiful documentation.
4. In the rest of the code (CAT, TFTP) we faced a clock problem - we had a problem synchronizing I2C clock with the USB clock.
Another problem we had, was that structs, whose size in bytes weren't a multiplication of 4, were padded with zeros, which caused us offsets while using a struct within another struct.
Overall, we found the course to be very interesting even though (or because) we are used to "higher level programming" at our work.
in retrospect, we can tell that there are substantial knowledge gaps between the different groups in the class. Coming in to this without any prior knowledge, system-wise or embedded-wise had taken a great toll.
Having no experience whatsoever, we encountered numerous difficulties during the assignment, that eventually took us about a MONTH to complete. We can't really say it was all fun, but having succeeded makes it worthwhile.