uIPv6

This is a standalone port of the uIPv6 library available in the operating system Contiki. The motivation behind this is to be able to utilize IPv6 on micro-controllers without the need to run the whole Contiki operating system.

The stack has been used successfully with an AVR ATmega644.

This is currently a work in progress and everything might not work as expected! Beware of dog! Slippery when wet!

Status

IPv6/ND/ICMP6: Working
TCP: Listening mode working, active mode untested
UDP: Untested
6LowPAN: Not working

Requirements

Absolute minimum: 2KB RAM/10-20KB ROM
Recommended minimum: 4KB RAM/32KB ROM

A software system timer for the target platform capable of measuring elapsed time with sub-second precision is required. A frequency of 32Hz is good enough.

Platforms

The stack is platform independent.

Full support for:

Download

Snapshot tarball: uipv6-trunk.tar

SVN repository: http://svn.h3q.net/uipv6

svn co http://svn.h3q.net/uipv6

SVN web: http://svnview.h3q.net/uipv6

Usage guide

The Contiki operating features a process model with various processes running the IPv6 stack. These processes have been eliminated an are executed through either timers or manual polling methods.

Compiling

Chances are that you’ll need to write your own Makefiles, however two are supplied.

Compiling for POSIX (native Linux/FreeBSD/etc)

gmake -f Makefile.posix

Compiling for AVR with avr-gcc. MCU sets target uC and FREQ sets CPU frequency.

gmake -f Makefile.avr MCU=atmega644p FREQ=8000000

These Makefiles produces a static library called uipv6.a which you simply link with your code.

Configuration

Various options can be set in the files contiki-conf.h and uipopt.h

CLOCK_CONF_SECOND must be set to the number of ticks that represent one second in your system timer.

System timer

The following methods needs to be implemented for your platform.

void clock_init(void)

Clock initialization/setup.

clock_time_t clock_time(void)

Should return the current number of clock ticks.

unsigned long clock_seconds(void)

Return number of seconds.

A sample implementation for AVR can be found in arch/avr/clock.c

API

Ethernet drivers etc are currently not integrated into the stack.

Since much is executed by timers you need either call etimer_poll() in your clock implementation (on tick increase) or continuously call etimer_poll() from your main application loop.

Example of a pure polling driven solution.

#include "contiki-net.h"
#include "uip.h"
#include "uip_arp.h"
#include "etimer.h"
#include "psock.h"
#include "tcpip.h"
 
uint8_t
eth_output(uip_lladdr_t *lladdr)
{
    /* Setup MAC address */
    if (lladdr == NULL) {
        (&BUF->dest)->addr[0] = 0x33;
        (&BUF->dest)->addr[1] = 0x33;
        (&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12];
        (&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13];
        (&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14];
        (&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15];
    }
    else {
        memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN);
    }
    memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN);
    BUF->type = HTONS(UIP_ETHTYPE_IPV6);
    uip_len += sizeof(struct uip_eth_hdr);
 
    /* Pass the frame to the ethernet driver */
    return enc28j60_frame_send(uip_len, (char *)uip_buf);
}
 
static void
eth_poll()
{
    uip_len = enc28j60_frame_recv((char *)uip_buf, UIP_BUFSIZE);
    if (uip_len > 0) {
        if (BUF->type == htons(UIP_ETHTYPE_IPV6)) {
            tcpip_input();
        }
    }
}
 
int main()
{
 
    tcpip_set_outputfunc(eth_output);
    tcpip_init();
    clock_init();
 
    for (;;) {
        eth_poll(); /* Check for packets */
        etimer_poll(); /* Poll timers */
    }
}

Comments are closed.