Contiki-NG Overview
Learning outcomes
- Familiarity with Contiki-NG basics
- Be able to list the key features of Contiki-NG
- Know how to compile a simple application
What is Contiki?
- Light-weight, open-source OS for IoT.
- Connects tiny low-cost, low-power microcontrollers to the Internet.
- Powerful tool for building complex wireless applications
- Remote house monitoring, intrusion detection, industrial monitoring, streetlights, and so on.
Contiki or Contiki-NG?
- We are using Contiki-NG throughout
- Contiki-NG is a fork from Contiki from 2017
- Focus is on reliability, better documentation, and more regular release cycles
- However, pretty much everything that we are doing can also be done with vanilla Contiki
Key features
Rapid development
- Standard C
- Cooja simulator
- Instant Contiki (we’re not using this as it is quite old)
- Open-source and active community
Full IP networking
- Fully standard IPv4 and IPv6
- Support for standard IP protocols: TCP, UDP, HTTP, MQTT
- Support for low-power wireless standards: 6lowpan, RPL and CoAP
Rime stack
- If bandwidth is limited or full IPv6 stack is an overkill
- Supports simple operations such as unicast, broadcast, flooding, and address-free multi-hop
A selection of hardware
Zolertia Firefly Mote
- Zoul module
- CC2538 ARM Cortex-M3
- 2 on-board IEEE802.15.4-compliant transceivers
- 2.4GHz and 863-950MHz
- 512KB programmable flash
- Low-power IoT development platform
- Active state: 20mA; Idle state (3 modes) : 0.4uA - 0.6mA
- On-board pin connectors: SPI and I2C interface support
Protothreads
- Low overhead mechanism for concurrent programming
- Mixture of event-driven and multi-threaded programming mechanisms
- Each Contiki-NG process is a protothread
Coffee flash file system
- Open, read, write, append and close functions on files on the external flash
Power awareness
- Mechanisms to estimate and understand the power consumption of the system
- Enable motes to run for years on AA batteries
Dynamic Module Loading
- Supports dynamic linking and loading of modules at run-time
- Over-the-air programming
Build system
- Make files
- Easy to compile on any supported hardware
Examples
contiki/examples
- iot-workshop/examples/zolertia
Getting started with Contiki-NG
We are using the vagrant image but there are several other options (including running native on Windows).
Contiki-NG structure: Exploring Contiki
Directory structure
contiki-ng/
arch # architecture dependent
examples # generic examples
os # main contiki operating system
tests # test code
tools # tools for users (including cooja)
See https://github.com/contiki-ng/contiki-ng/wiki/Repository-structure
Hello World!
#include "contiki.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
static struct etimer timer;
PROCESS_BEGIN();
/* Setup a periodic timer that expires after 10 seconds. */
etimer_set(&timer, CLOCK_SECOND * 10);
while(1) {
printf("Hello, world\n");
/* Wait for the periodic timer to expire and then restart the timer. */
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
etimer_reset(&timer);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
Makefile
CONTIKI_PROJECT = hello-world
all: $(CONTIKI_PROJECT)
CONTIKI = ../..
include $(CONTIKI)/Makefile.include
Connect the mote
- When physically connecting the mote to your laptop, be careful of the USB connector
- e.g. use an extender, hub, or prop the laptop on a book to make sure that the connector doesn’t break
- Since we are using a VM, we need to give the VM access to the physical device.
- it is possible to do this in the gui (but error prone)
- to make sure you get the right settings, edit Vagrant file and restart the VM
config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--usb", "on", "--usbxhci", "on", "--paravirtprovider", "kvm"] vb.customize ["usbfilter", "add", "0", "--target", :id, "--name", "MTM-CM5000MSP", "--vendorid", "0x0403", "--productid", "0x6001"] # # Display the VirtualBox GUI when booting the machine # vb.gui = true # # # Customize the amount of memory on the VM: # vb.memory = "1024" end
- Check that the mote has connected ok
make TARGET=sky motelist
Compile and upload Hello World
- To access the device, you’ll need to have
dialout
access$ id uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant),20(dialout),998(docker)
- For each
make
command, you can specifyTARGET
(will be eithersky
ornative
)BOARD
(only needed for some boards)PORT
(e.g.,/dev/ttyUSB0
)
- Save typing by saving the
TARGET
(gets saved just for that directory)make TARGET=sky savetarget
You can also set the
PORT
(for that login session) using:export PORT=/dev/ttyUSB0
- Compile your code
$ make hello-world
- Upload your code to the device (you may need to tell it the
PORT
):$ make hello-world.upload
- To see the output from the program, connect to the serial port using:
$ make login
- If you get some garbled output, try resetting the mote using the reset button.
Contiki-NG build system: quick look
See https://github.com/contiki-ng/contiki-ng/wiki/The-Contiki%E2%80%90NG-build-system
The build system is comprised of multiple Makefile
files
projectdir/Makefile
contains options and instructions for that project and aninclude
for the master Contiki makefile. e.g.,CONTIKI_PROJECT = udp-client udp-server all: $(CONTIKI_PROJECT) CONTIKI=../.. include $(CONTIKI)/Makefile.include
Makefile.include
is in the root of the Contiki-NG source tree. It includes:- C files needed for core system
- includes
Makefile.$TARGET
andapp
Makefiles
Makefile.$(TARGET)
where$(TARGET)
is the platform (e.g.,sky
)- located in
arch/platforms/$(TARGET)
- includes C files that are specific to that platform (e.g.,
sht11-sensor.c
)
- located in
Makefile.$(CPU)
where$(CPU)
is the processor (e.g.,msp430
)- located in
arch/cpu/$(CPU)
- includes code specific to that processor (e.g.,
flash.c
)
- located in
Makefile.$(MODULE)
where$(MODULE)
is the name of a module in theos
directory.
Things to try out
contiki/examples
iot-workshop
branch in https://github.com/alignan/contiki
Useful resources
- Get started with Contiki-NG: https://www.contiki-ng.org/
- IoT in five days: https://github.com/marcozennaro/IPv6-WSN-book/releases/
- Contiki tutorial: https://www.slideshare.net/salahecom/contiki-seminar-1
- Contiki tutorials: https://anrg.usc.edu/contiki/index.php/Contiki_tutorials
Thank you!
Additional info
Creating your own Contiki application
- Go to your home directory and create a subdirectory
my-first-app
$ cd $ mkdir my-first-app
- Inside the folder create a new C file
My-first-app.c
- It may help to look at the examples to ensure you include all the right bits.
- Create a
Makefile
in the same folder. Ensure you specify the right directoryCONTIKI_PROJECT = my-first-app all: $(CONTIKI_PROJECT) CONTIKI=~/contiki-ng include $(CONTIKI)/Makefile.include
- You should now be able to compile and upload the program
$ make TARGET=sky savetarget
$ make my-first-app
$ make my-first-app.upload
$ make login
Generic Structure of a Contiki Program
/* header files */
#include <...>
/* declare processes */
PROCESS(name, "description of process");
/* ... */
/* autostart processes */
AUTOSTART_PROCESSES(name);
/* ... */
/* define process */
PROCESS_THREAD(name, ev, data)
{
/* declare and static init vars */
PROCESS_BEGIN();
/* main code */
PROCESS_END();
}
Contiki APIs: Process
Function | Description |
---|---|
PROCESS_BEGIN() | Define the beginning of a process |
PROCESS_END() | Define the end of a process |
PROCESS_WAIT_EVENT() | Wait for an event to be posted to the process |
Blocks the currently running process until an event is received | |
PROCESS_WAIT_EVENT_UNTIL(c) | Wait for an event to be posted to the process, with an extra condition |
PROCESS_YIELD() | Yield the currently running process |
PROCESS_YIELD_UNTIL(c) | Yield the currently running process until a condition occurs |
PROCESS_WAIT_UNTIL(c) | Wait for a condition to occur |
PROCESS_EXIT() | Exit the currently running process |
PROCESS_PAUSE() | Yield the process for a short while |
Contiki APIs: Sensor
Each sensor has a set of functions for controlling it and query it for its state. Some sensors also generate events when sensor values change. A sensor must be activated before it generates events or relevant values.
Function | Description |
---|---|
SENSORS_ACTIVATE(sensor) | Activate the sensor |
SENSORS_DEACTIVATE(sensor) | Deactivate the sensor |
sensor.value(o) | Query the sensor for its last value (e.g. button pressed or not) |
sensor_event | Event sent when a sensor has changed |
Contiki APIs: LED
Function | Description |
---|---|
leds_on() | Turn LEDs on |
leds_off() | Turn LEDs off |
leds_invert() | Toggle LEDs |
leds_blink() | Blink all LEDs |