The Source Code


How look like an ethernet frame and how the protocol works ?

The purpose of this section is to describe the dialog/protocol using ethernet frames, and more especially the one we will use. To make and understand the underlying software, we musy
An ethernet frame is a series of bytes, gathered into serial packets sent over the network. The packet length could be between 32 to 1518 bytes.
Every ethernet devices has a fixed 6 bytes MAC address like 00:50:23:89:FA:04, this one is unique and provided by a consorsium to avoid same adresses. In our case, since we don't plan to use our device over very large Local Networks Area (LAN), we don't care giving any MAC address we want. When two ethernet devices are connected in a LAN, to be able to communicate with the IP protocol (or any other protocol), they must ask each other which MAC address correspond to their IP address, for instance the ethernet device having the 00:50:23:89:FA:04 MAC address, has an IP address such as 134.171.12.124, the other ethernet device (another PC for instance) has a MAC adress of 00:56:11:33:FC:07 with an IP address of 134.171.12.127. One can see that the two sets of addresses are completely decorelated.

 

STEP 1 : ARP Discussion

The ARP protocol is used to resolve MAC addresses into IP adresses between devices over the LAN. For that purpose, whenever a PC starts to speak to our Embedded Ethernet Device (let's call it EED in the following text) having this IP address 134.171.12.146 , it says : who is 134.171.12.146 ? and which MAC address does it have ?

This means that our EED MUST respond to ARP request to be identified by a client PC.

This is how look like a ARP REQUEST ethernet frame, sent by the PC to the EED :

Offset Value Type Offset Value Type Offset Value Type
00 00 LengthHigh 10 00 Hardware Type 20 0C senders IP address 4
01 3C LengthLow 11 01 Hardware Type 21 7F senders IP address 3
02 FF Dest MAC 1 12 08 Protocol Type 22 00 target hardware addr MAC1
03 FF Dest MAC 2 13 00 ProtocolType 23 00 target hardware addr MAC2
04 FF Dest MAC 3 14 06 hardware address length 24 00 target hardware addr MAC3
05 FF Dest MAC 4 15 04 protocol address length 25 00 target hardware addr MAC4
06 FF Dest MAC 5 16 00 ARP operation 26 00 target hardware addr MAC5
07 FF Dest MAC 6 17 01 ARP operation 27 00 target hardware addr MAC6
08 00 Src MAC1 18 00 senders hardware addr MAC1 28 86 target IP address 1
09 50 Src MAC2 19 50 senders hardware addr MAC2 29 AB target IP address 2
0A DA Src MAC3 1A DA senders hardware addr MAC3 2A 0C target IP address 3
0B B0 Src MAC4 1B B0 senders hardware addr MAC4 2B 23 target IP address 4
0C 6C Src MAC5 1C 6C senders hardware addr MAC5 2C  
0D 57 Src MAC6 1D 57 senders hardware addr MAC6 2D
0E 08 TypeProtoHigh(1) 1E 86 senders IP address 1 2E
0F 06 TypeProtoLow(2) 1F AB senders IP address 2 2F

ARP operation (1=request, 2=reply)
Type Protocol = $0806 for ARP, $0800 for IP 8137 IPX 8035 RARP

If one use a sofware able to catch ethernet frames coming out form the PC (such as SNIFFER PRO), this is, for example, a 60 byte frame sent by the PC to the network to identify our EED :
- Top window indicate that the PC (Laptop called GtwCom548297) has sent a broadcast ARP request to 134.171.12.146. Broadcast because the target MAC address is FF:FF:FF:FF:FF:FF.
- Middle window has decoded the frame to make it readable (that's very very nice !!)
- Bottom window shows the raw data (serial bytes from the ethernet frame)

Our EED must respond to ARP request with this frame :

Once an ARP request has been recevied by our EED, we must send back a reply to the requestor (PC laptop or GtwCom548297). Destination and target addresses are swapped and the FF:FF:FF:FF:FF:FF Mac address of our EED is now provided and sent back to the requestor (The PC).


This ARP request process is done every N minutes by the PC to check out devices over the LAN. So that, the PC maintains a translation table of IP and MAC adresses.

If one issue a ARP -A command in a DOS window, this is what he should get :

Interface: 134.171.12.94 on Interface 0x2 Internet
Address (IP) Physical Address (MAC) Type
134.171.13.18 00-a0-24-c5-82-a8 dynamic
134.171.13.185 00-10-4b-45-a0-d5 dynamic
134.171.13.199 00-00-0c-07-ac-00 dynamic
134.171.12.146 00-00-86-54-82-96 dynamic

Now, the PC knows that 134.171.12.146 is 00-00-86-54-82-96, our EED has replied properly to the PC ARP request.

Our EED does not make any ARP requests over the network, since it behaves like a server except here :
If our EED has to send packet thru Gateway machines, it must send a broadcast ARP request to the Gateway (IP of the gateway and MAC dest equal to FF:FF:FF:FF) otherwise, our EED will mess up completely the network. At ESO, such failure/forgotten request end up to make crash the whole network (!!). This request to the Gateway must be done every 5 minutes to allow the gateway to update his ARP table (otherwise our EED will be forgotten by the Gateway).

 


Once this process is done, IP dialog can start between the two devices, if ARP request is not completed, the PC and the EED WILL NOT COMMUNICATE.

 

STEP 2: PING Discussion

To check that everything is OK, we must PING our embedded ethernet device. The ping command is well known, especially in the UNIX world ! It consists in sending an IP frame toward a target and the target replies to sender telling that everything is OK, I'm alive.

This command is used to debug an IP link between two devices over the network (can be also worldwide used form machine to machine). Our EED responds to PING request so as to check that the connection between the PC and the EED is OK. The Ping request obey to the IP/ICMP protocol. The PC sends a Ping request using this multi-layer protocol encapsulated frame :

Frame coding :
ARP LAYER IP LAYER ICMP LAYER

Echoes request/reply message for PING requests, hereafter a request, IC code is 40 bytes, so 40+20(IP header)=60=0x3C

Offset Value Type Offset Value Type Offset Value Type
00 00 LengthHigh 10 45 version and header length(in longs), beginning of IP header 20 86 IP address of target 1
01 4A LengthLow 11 00 type of service 21 AB IP address of target 2
02 11 Dest MAC 1 12 00 packet length (length+header_length) 22 0C IP address of target 3
03 22 Dest MAC 2 13 3C packet length (length+header_length) 23 23 IP address of target 4; end of IP header, 20 bytes
04 33 Dest MAC 3 14 F0 datagram id 24 08 IC Type **
05 44 Dest MAC 4 15 0E datagram id 25 00 IC code
06 55 Dest MAC 5 16 00 fragment offset 26 8D IC Checksum (header+data )
07 66 Dest MAC 6 17 00 fragment offset 27 5B IC Checksum (header+data)
08 00 Src MAC1 18 20 time to live (in gateway hops) 28 01 message id
09 50 Src MAC2 19 01 protocol * 29 00 message id
0A DA Src MAC3 1A 84 IP header checksum High 2A BF sequence number
0B B0 Src MAC4 1B BA IP header checksum Low 2B 00 sequence number
0C 6C Src MAC5 1C 86 IP address of source 1 2C 61 Data....
0D 57 Src MAC6 1D AB IP address of source 2 2D 62 Data....
0E 08 TypeProtoHigh 1E 0C IP address of source 3 2E 63 Data....
0F 00 TypeProtoLow 1F 7F IP address of source 4 2F 64 Data ....

* protocol (ICMP=1, TCP=6, EGP=8, UDP=17)
** IC types : 0=reply, 8=request, others=who-cares

The IP checksum algorithm at offsets 1A and 1B: The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header. For purposes of computing the checksum, the value of the checksum field is zero. IP checksum concerns ONLY IP data field (nor ICMP, neither whatever).

For instance if the IP header data from above is used from offset 10 to 23 :

Const Data:Array [1..10] of Word=($4500,$003C,$F00E,$0000,$2001,$0000,$86AB,$0C7F,$86AB,$0C23); // $84BA

The result is $84BA as seen at offsets 1A and 1B.

This routine works is the number of data is even. if not the last data has to be turned into a 16 bit value.

In Pascal
Var i,Inter:Integer; //32 bits
Cksum:Word; //16 bits

begin
Inter:=0;
For i:=1 to 10 do Inter:=Inter+Data[i];
Cksum:=((Inter and $FFFF) + (Inter shr 16)) Xor $FFFF;
end;

in C :

u_short checksum(u_short * data,u_short length)
{
register long value;
u_short i;
for(i=0;i<(length>>1);i++) value+=data[i]; // add
if((length&1)==1) value+=(data[i]<<8); // compensate of odd amount of datas
value=(value&65535)+(value>>16); // complements one to one
return(~value); // XOR the result
}

ICMP cheksum :

The checksum is the 16-bit one's complement of the one's complement sum of the entire ICMPv6 message starting with the ICMPv6 message type field, prepended with a "pseudo-header" of IPv6 header fields. The Next Header value used in the pseudo-header is 58. (NOTE: the inclusion of a pseudo-header in the ICMPv6 checksum is a change from IPv4; see [IPv6] for the rationale for this change.) For computing the checksum, the checksum field is set to zero. The data range is offset 24 to the last data byte at the end of the ICMP frame.

Once the EED has received an ICMP frame, it decodes it so as to check that this frame is intended for him.

Our EED, then SWAP the target destination adresses and fill the offset 24 with a reply code. The IP/ICMP frame is sent to the requestor.


This DOS command window shows the results issued from a PING command send to our EED (134.171.12.146), obviously it works, our EED responds in less than 10ms over the LAN.

The following windows show a captured data form the network board displaying Ping (ICMP) request form my PC (134.171.73.42) to the EED (134.171.73.45) and the reply.

STEP 3: The final IP/UDP discussion

The UDP protocol has been chosen to exchange datas between our EED and the PC. We have secured this UDP handshakes scheme to avoid any packets losses. Why didn't we use TCP/IP instead of UPD/IP ? If one looks to the TCP/IP protocol specification compared to the UDP, the TCP/IP is really less straightforward to implement to a 8 bit SX52 microcontroller. TCP/IP has a large header, which can end up to non-negligeable overheads. Since we use handshaked UDP protocol, packet losses has been completely overcome by the use of a 2K SRAM. It allows to store the all IP frame in the EED and to re-send the frame to the PC if necessary. First of all, let's have a look to the UDP protocol.

IP/UDP

Frame coding :

ARP LAYER IP LAYER UDP LAYER

 

Offset Value Type Offset Value Type Offset Value Type
SX52 Bank $20 SX52 Bank $30 SX52 Bank $40
00   LengthHigh 10 45 version and header length(in longs) 20 86 IP address of target 1 %
01   LengthLow 11 00 type of service 21 AB IP address of target 2 %
02 00 Dest MAC 1 12 00 packet length (length+header_length) 22 49 IP address of target 3 %
03 11 Dest MAC 2 13 1E packet length (length+header_length) 23 2D IP address of target 4 %
04 86 Dest MAC 3 14 18 datagram id 24 00 UDP Source Port Number High
05 54 Dest MAC 4 15 55 datagram id 25 BF UDP Source Port Number Low
06 80 Dest MAC 5 16 00 fragment offset 26 00 UDP Destination port Number High
07 96 Dest MAC 6 17 00 fragment offset 27 BF UDP Destination port Number Low
08 00 Src MAC1 18 80 time to live TTL 28 00 Length of UDP (header+data) High %
09 00 Src MAC2 19 11 IP protocol % UDP 29 0A Length of UDP (header+data) Low %
0A E8 Src MAC3 1A 82 header checksum 2A DD ** Checksum High, not critical can be eventually set to zero
0B D7 Src MAC4 1B CC header checksum 2B AD ** Checksum Low, not critical can be eventually set to zero
0C B5 Src MAC5 1C 86 IP address of source 1 % 2C XX Data1 (Data length must be EVEN)
Here, we can use it as we want !!
0D 9F Src MAC6 1D AB IP address of source 2 % 2D XX Data2
Here, we can use it as we want !!
0E 08 TypeProtoHigh 1E 49 IP address of source 3 % 2E XX Data3.
Here, we can use it as we want !!
0F 00 TypeProtoLow 1F 2A IP address of source 4 % 2F XX ....
........

** Note: UDP checksum is calculated by taking the 16 bit sums of :
- IP address of source : 2 x 16 bits words at offsets 1C to 1F
- IP address of target : 2 x 16 bits words at offsets 20 to 23
- IP protocol : 8 bits words at offset 19, padded with a zero high byte to make a 16 bit word.
- Length of UDP frame (header+Data) : 2x 16 bits words at offsets 28-29
- Finally, the sum starting at UDP Source Port Number, offset 24
Yes, this means that Length of UDP word is taken twice! Cksum word is zero during the calculation. The sum is then one's complemented, as all previous checksums.

% = means that the first UDP checksum is computed using those value !

The table shows a standard UDP frame, what's interest us is the part Data1, Data2 and so on... because we can write here whatever we want, up to 1500 bytes per frames. As a reply, we send this kind of frame with swapped addresses and UDP port, the checksum is left to $0000 for the reply.

How the handshake UDP protocol has been implemented ?

This is for instance a complete sequence for a single event : it consists in 4 frames.

Step 1 : PC send an UDP frame to the EED, the UDP data section contains something like "Do something..." coded as $82,$01,$03, Herefter, this is frame number 6.
Step 2 : EED sends back to the PC an UDP frame, the UDP data section contains something like "Ok, I'm alive..." coded as $82,$01, Hereafter, this is frame number 7.
Step 3 : EED sends to the PC an UDP frame, the UDP data section contains something like "Ok, This is the DATA you requested from step 1..." coded as series of datas, this is frame number 8, the one selected on the window.
Step 4 : PC acknowledge the frame from the EED, the UDP data section contains something like "Ok, all data received..." Here after this is frame number 9.

Step 2 is necessary to check that the request from the PC has not been lost somewhere, if step 2 is not fullfilled, the PC raises a timeout/connection error with the EED.

Just after step 2, the PC starts a timeout counter, excepting step 3 coming, if nothing comes from EED, it raises a timeout error.

Step 4 is necessary to check that the data from the EED has not been lost somewhere, if step 4 is not fullfilled, the EED sends the data again, up to N times (N can be defined as we want...) and gives up if N is reached. N can be indefinite.

How this can be applied ?

For instance, let's consider the opening of a shutter controlled by the EED :

Step 1 : PC send an UDP frame to the EED, the UDP data section contains codes/bytes that will be interpreted like "Open the shutter" by the EED.
Step 2 : EED sends back to the PC an UDP frame, the UDP data section contains codes/bytes that will be interpreted by the PC like "EED is alive, request properly received and will be processed" by the EED.
Step 3 : EED sends to the PC an UDP frame, the UDP data section contains codes/bytes that will be interpreted by the PC like "EED has opened the shutter".
Step 4 : PC acknowledge the frame from the EED, the UDP data section contains codes/bytes that will be interpreted by the EED like "OK, done.."

This protocol is secure : It was used to read a CCD camera, the RJ45 wire was disconnected for a while and connected back, the reading out of the rest of the CCD data went fine and no pixel losses.

 

The embedded ethernet controller SX52 micro-controller source code

The scenix SX52 is the core of our EED, controlling the ethernet circuit cs8900, the 2 FIFOs and the SRAM. The Sx52 read/write frames to cs8900, decode incoming frames, build response frames, send/read data/commands to the 2 FIFOs. The following source code comes as it whithout any warranties.

- V5.01 17/11/00 , interfacing 2K SRAM.

The slave microcontroller source code

- PIC16c74 microcontroller

This is, for instance the code employed for the PIC16C74 small temperature board.
Another example, this is the code to control a CCD camera

- Another SX52 microcontroller

Coming soon.... when ready....

Delphi source code

- Code used to debug CCD communication (Delphi), Oct 2000, this code communicates with the SX52 V5.00 release code. This delphi code is also mandatory to compile the previous code.

 


By C.CAVADORE and B.GAILLARD, 16 Nov 2000