AVR web server and web client, stack version 5.X
The main new feature in stack version 5.X is the addition of a DHCP client
and a general overhaul of all client related interfaces.
Most client functions what now a IP address and a MAC address as arguments.
This change opens the possibility to do proper routing for client applications.
That is: if the server you want to reach is on your local LAN the you use the IP
address of the server and the MAC address of the servers interface.
If it is a server somewhere on the internet then you would use
the IP address of the server and the MAC address of the internal interface of your gateway (e.g
DSL router).
A new interface is provided to lookup MAC addresses.
The web server code is mostly unaffected by the changes although some functions have
been renamed.
cgi-script to receive data and store on your web-server
In the cgi-bin directory a perl cgi-script is provided
to store data received from the web client on the avr-ethernet board.
The idea is that the avr-ethernet board is used to take measurements (e.g of
temperature or records events) and this data is then up-loaded by the board
to a central server on the internet for storage and further processing.
The sdat cgi-script receives and stores the data. It can as well be used
to view data that was received.
What is where?
See file
WhatIsWhat.htm
There is as well detailed documentation and other applications of this TCP/IP stack at http://tuxgraphics.org/electronics/
All parts needed to build this AVR ethernet solution can be ordered from
http://shop.tuxgraphics.org/.
You can also order the email account which you need for the test_emailnotify
application from the tuxgraphics online shop.
The characteristics of this TCP/IP stack
The tuxgraphics TCP/IP stack was written with a web server in mind and is optimized
for size. It is the smallest stack and the fastest web server at the same time. It does
not have any hard-coded limit on the amount of parallel web connections/transactions.
Most TCP/IP stacks for embedded systems are limited very much in the number of connections
and can thus easily be taken down by a SYN-attack (even hardware implementations have
that limitation). This stack does not have this problem.
The trade off is however that you can not send large files or show big web pages.
Everything must fit into one IP packet. You can produce bigger web pages by splitting
up the page or using the <iframe src="url">
License
Copyright of the software and all diagrams: Guido Socher, tuxgraphics
The libraries
dhcp_client, dnslkup, ip_arp_udp_tcp, enc28j60 and websrv_help_functions
are licensed under LGPL V2
See http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html
All other parts are GPL V2
See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
Other licenses are available on request.
Configuration (!! READ THIS BEFORE YOU COMPILE THE CODE !!)
Edit the C-file of the application which you plan to compile from
the appropriate sub-directory and change the lines:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x29};
static uint8_t myip[4] = {10,0,0,29};
Which IP address should I use for myip? You need an IP address that
is in the same range as your LAN.
Example: your wlan router might have 192.168.1.1, your PC might have
192.168.1.2. This means you could e.g use 192.168.1.10 and leave some
room for more PCs.
Only in the case of the example in client-www-dhcp you will not need to change
the myip[] variable as DHCP will be used to obtain the IP address.
You must however still assign a MAC address to each board such that there are
no two boards in your local network with the same MAC address.
In case of the web client applications (test_web_client.c, test_identi_ca.c and test_emailnotify.c)
you will in addition need to edit the following line:
// Default gateway. The internal IP address of your DSL router.
static uint8_t gwip[4] = {10,0,0,2};
Check the file "Makevars.mk" on the top level. This file contains common settings
included in all the Makefiles used here.
Make sure the MCU is set correctly:
MCU=atmega168
DUDECPUTYPE=m168
or
MCU=atmega88
DUDECPUTYPE=m88
or
MCU=atmega328p
DUDECPUTYPE=m328p
or
MCU=atmega644
DUDECPUTYPE=m644
The code for only the web server fits into an atmega88 chip but
a combined web client and web server needs a atmega168/atmega328p or atmega644.
The each directory contains a file called ip_config.h. This file is used
to configure the features that the stack provides. This file is tailored
to the specific use to keep the IP stack as small as possible.
That way you can have really efficient and small code.
Compiling the code
You need an avr-gcc development environment in order to compile this.
See http://tuxgraphics.org/electronics/200901/avr-gcc-linux.shtml
Each of the examples can be compiled from the corresponding sub-directory
Just use the command:
make
Note: windows users may use and modify the supplied winmake.bat to setup the
environment correctly. See details below on how to compile this under windows.
More information about Makefiles can be found at:
http://tuxgraphics.org/electronics/200912/makefiles.shtml
In the variouse sub-directories you can use a command like:
make load_TheNameOfTheApplication
E.g in server-www-simple to compile and load test_OKworks.c you run
make load_test_OKworks
This will execute the avrdude command to load the software
E.g something like:
avrdude -p m88 -c stk500v2 -e -U flash:w:test_OKworks.hex
For the "make load" stuff to work you will have to set the LOADCMD variable
in the Makevars.mk.
It is as well possible to compile everything from the top level make file
but loading is obviously not possible from there.
To see a list of all possible build targets run the command:
make help
Selecting the right clock source (fuse settings) !you do this only once per board!
Tuxgraphics hardware sold as of march 2007 is prepared to use the clock
signal from the enc28j60. To use this you need to change the
low fuse byte once from 0x62 to 0x60:
avrdude -p m88 -c stk500v2 -u -v -U lfuse:w:0x60:m
or
avrdude -p m168 -c stk500v2 -u -v -U lfuse:w:0x60:m
or
avrdude -p m328p -c stk500v2 -u -v -U lfuse:w:0x60:m
or
avrdude -p m644 -c stk500v2 -u -v -U lfuse:w:0x60:m
The above command can as well be executed by using the make
file. In a Linux shell you can just make sure the Makevars.mk is correct and
then type:
make fuse
Note: windows users may use and modify the supplied winsetfuse.bat script.
After programming the fuse settings of atmega168 and atmega88 should be:
low fuse: 0x60
high fuse: 0xdf
ext. fuse: 0x01
For the atmega328p the hfuse and efuse bytes look slightly different.
The idea is however the same. Just change the lfuse from factory default
to 0x60. The fuse settings of the atmega328p are after programming
should be as below (default factory settings for atmega328p, the
efuse has some not used bits and is dependent on the chip revision):
lfuse reads as 0x60
hfuse reads as 0xD9
efuse reads as 0x07
Fuses of the atmega644/atmega644a after programming:
Device signature = 0x1e9609
lfuse reads as 60
hfuse reads as 99
efuse reads as FF
details of the lfuse bits:
CKDIV8 = 0
CKOUT = 1
SUT1 = 1
SUT0 = 0
CKSEL3 = 0
CKSEL2 = 0
CKSEL1 = 0
CKSEL0 = 0
If you are unsure what the current fuse setting are on the atmega
then you can read the fuse settings with a command like:
avrdude -p m168 -c stk500v2 -v -q
The below list of fuses shows for reference purpose the settings
of a new and never programmed chip.
The result should be this (default factory settings for atmega168):
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as 1
The result should be this (default factory settings for atmega328p):
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7
The result should be this (default factory settings for atmega644/atmega644a):
avrdude: Device signature = 0x1e9609
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as 99
avrdude: safemode: efuse reads as FF
Compiling on non-Unix systems
Please use the provided Makefiles !!!
Those Makefiles will work under Windows.
Take a look at the supplied winmake.bat, winclean.bat and winsetfuse.bat file. The bat script
might need to be adapted to set the environment correctly.
Both script call then the Makefile to run the actual commands.
Edit the Makevars.mk to make the needed adjustments.
More information about Makefiles can be found at:
http://tuxgraphics.org/electronics/200912/makefiles.shtml
After adjusting both the batch script and the Makevars.mk you can
use this system as follows:
- Compilation: just double click on the winmake.bat in the filemanager. This
will compile the whole tree.
- Loading of the resulting hex files into the board: I recommend to use the
win-avrdude zip-package as described in:
http://tuxgraphics.org/electronics/201205/windows-avr-microcontroller-programming.shtml
- Setting fuse bytes (needs to be done only once per board): double click on winsetfuse.bat
- Clean-up of object files (needs to be run after changing any settings in Makefiles): double click on winclean.bat
Adapting code from stack version 4.X to this version
The the client interfaces have changed a lot and most function signatures
have changed. I recommend you to look at the examples in the client-www directory
and adapt your code line by line.
For a web server the changes are much smaller. All you have to do is replace the function:
init_ip_arp_udp_tcp(mymac,myip,mywwwport);
with
init_udp_or_www_server(mymac,myip);
www_server_port(mywwwport); // only needed if mywwwport!=80
Revision history
2009-05-05: version 3.2 -- first version of the new stack.
2009-05-18: version 3.3 -- get rid of avr_compat.h, add twitter and identi.ca
2009-06-02: version 3.4 -- added make target "main" to compile eth_rem_dev_tcp.hex
updated delay functions.
2009-06-21: version 3.5 -- added a smiley for the remote switch (main.c)
2009-12-30: version 3.6 -- improvements to Makefile
2010-02-26: version 4.0 -- added generic udp client code (from alarm system)
-- added a generic TCP client interface
-- add a length parameter to the browser callback
-- added a dns resolver
2010-03-13: version 4.1 -- clean-up code for enc28j60 B4 errata point 13
2010-03-21: version 4.2 -- ping client code update
-- arp refresh procedure uses now bit-mapped flags
2010-06-27: version 4.3 -- added atmega644 support
2011-10-18: version 4.4 -- various error fixes by:
- Marc Bouget - add missing check for IP protocol field, ip_arp_udp_tcp.c
- Andras Tucsni - increase TCP_WIN_SIZE size, ip_arp_udp_tcp.c
- Andras Tucsni - zero 12 bytes not 10, dnslkup.c
-- changed license of the stack code to allow use of
those files as a library in combination with
proprietary code. Without a need to release that
code to the receiver of the application or hardware
running it:
dnslkup.c: Copyright:LGPL V2
dnslkup.h: Copyright:LGPL V2
enc28j60.c: Copyright:LGPL V2
enc28j60.h: Copyright:LGPL V2
ip_arp_udp_tcp.c: Copyright:LGPL V2
ip_arp_udp_tcp.h: Copyright:LGPL V2
ip_config.h: Copyright:LGPL V2
net.h: Copyright:LGPL V2
websrv_help_functions.c: Copyright:LGPL V2
2011-10-22: version 4.5 -- this is a bug fix only release. There was one
correction forgotten in the 4.4 release. We release
it now. It affects only the file dnslkup.c:
- Andras Tucsni - dnslkup.c: search all answer sections until
we find an A record (important only for CNAME or sub domains)
- Guido Socher - dnslkup.c: incorrect handling of
lencnt. It must be 1 at start.
2011-11-22: version 4.6 -- fix wol packet, WOL is UDP, there was a copy/paste
error when code for ICMP was reused.
2012-02-02: version 5.0 -- added a dhcp client. Major client code re-write.
2012-04-12: version 5.1 -- added #define __PROG_TYPES_COMPAT__ before
avr/pgmspace.h as this is needed for the new avr-libc-1.8
see http://www.nongnu.org/avr-libc/changes-1.8.html:
-- changed in websrv_help_functions the return value
of find_key_val
-- The client_browse_url function will retrun the full status code
and not only the first digit.
Note: this change is incompatible with the previous version!
2013-02-15: version 5.2 -- bug fix by Michael Maurer for enc28j60linkup
-- bug fix by Andrei: remove "Connection: close" from
http user agent code as this creates connections in
state TIME_WAIT on the server
-- bug fix for ntp client: send only data to network
buffer if link is up.
2013-05-17: version 5.3 -- bug fix in TCP client code: add RST if we get a packet after dialog is over
2014-02-20: version 5.4 -- fixed incorrect handling of non TCP packets in ip_arp_udp_tcp.c (incorrect check of IP protocol type and packet length)
2014-03-03 version 5.5 -- bug fix in enc28j60.c, incorrect initialisation of pins in enc28j60Init(). Thanks to Thomas Hellstroem. The consequence is that the system can get stuck if power fluctuates.
2014-03-15 version 5.6 -- missing ifdef dependency for GRATARP
-- get rid of -Wno-deprecated-declarations -D__PROG_TYPES_COMPAT__ and use the "new PROGMEM".
-- added code size optimisations for ENC28J60_BROADCAST (thanks to Thomas Hellstroem)
2014-03-23 version 5.7 -- adjusted incorrect #ifdef statements for WOL client
-- incorrect handling of previously changed PROGMEM code causes corrupted hostname in the web client code
2014-07-27 version 5.8 -- udpcom updated, thanks to Allard Lamberink for reporting the bug
2014-10-29 version 5.9 -- put an ifdef around F_CPU to allow for easier
inclusion into other project/code
-- fix in enc28j60PacketSend: Magnus Kasper points out that the while
loop can lead to a deadlock if looping over the reset of the transmit logic.
See as well blog:
http://forum.mysensors.org/topic/536/problems-with-enc28j60-losing-connection-freezing-using-uipethernet-or-ethershield-read-this
2015-03-05 version 5.10 -- Incorrect setting of hop count in dhcp_client.c, found by Kent Kristiansson
vim:sw=8:ts=8:si:et