Porting Contiki to the LPC2148 Education Board

 

Final project in Embedded Systems course at Tel-Aviv University

 

Yair Hershkovitz <yairhr@gmail.com>

Demitry Lev <demitryl@post.tau.ac.il>

 

 

 

1.     Introduction:
    
Contiki is an open source, highly portable, multi-tasking operating system for memory-efficient networked embedded systems and wireless sensor networks.

The goal of this project is to have the LPC2148 Education Board operated and controlled by Contiki. The project includes integration with the Contiki Makefile system, creating the linker scripts and startup code for the LPC2148 board, and implementing the standard Contiki primitives and the standard LPC2148 board interfaces.

 

2.      Makefile System:

When compiling a Contiki program the target platform must be defined by setting the TARGET environment variable to the platform name (e.g. make TARGET=lpc2148edu). The Makefile system then expects to find platform specific Makefile in the “platforms/$(TARGET)/Makefile.$(TARGET)” location. The platform  Makefile must define the following variables:

·        CONTIKI_TARGET_MAIN: The source file which implements the main Contiki event loop.

·        CONTIKI_SOURCEFILES: All sources files which should be compiled for supporting the platform. This list should include all relevant platform drivers in addition to the main target.

·        CONTIKI_CPU: The directory where the platform CPU support is found. For the LPC2148 platform that is “cpu/lpc2148”.

 

The CPU Makefile ($(CONTIKI_CPU)/Makefile.$(CPU)  must also specify all the source files which are needed for the compilation. In addition it must define the cross compiler to use (CC, LD, AS, AR, NM, OBJCOPY, STRIP, BSL) and the compiler flags (CFLAGS, ASFLAGS, LDFLAGS).

 

3.     Implementation Details:

3.1. Development Tools: The following tools are used to compile and load the code to the LPC2148 board.

·        Toolchain: GNU ARM

·        C Library:  Newlib

·        Flash programmer: lpc21isp

3.2. Linker script: For the linker script we used the script that was provided at the beginning of the course with the next modification: We added an explicit stack section sized 0x900b to allow enough free memory for heap allocations.

3.3. Startup code: For the startup code (CPU, Interrupts, Stacks initialization) we used the startup code that was provided at the beginning of the course with a small modification: Changing the IRQ stack size from 0x400b to 0x100b to allow a bigger SYS stack of  0x700b.

3.4. Integrating with Newlib C library: The Newlib library leaves the following functions to be implemented by the target platform:

·        _sbrk_r() – This function is in-charge of allocating data segment memory which is then used by malloc() to dynamically allocate memory. This function is by setting the initial segment to the stack end and allowing it to grow until it reaches the end of memory boundary.

·        _write_r() – This function is in-charge of writing data to the device described by the given file-descriptor. Our implementation only handles the case when the file descriptor matches the STDOUT device. Then we simply write the input data to the UART transmit register.

·        _fstat_r(),_close_r(),_lseek_r(),_read_r(): All of these function are left with a stub implementation. This is satisfactory since we currently do not use their functionality.

3.5. Contiki Interfaces:

3.5.1.   Event Timers: In order to support the Contiki etimers it is enough to implement the “clock_time_t clock_time(void)” function. This function is expected to return the number of clock ticks since boot, when clock ticks rate is CLOCK_CONF_SECOND ticks per second. Our implementation sets CLOCK_CONF_SECOND to 100. We choose to use the TIMER0 clock to implement this functionality. We set the MCR to reset on every match, and MR0 to 29999 which means 100 times each second.

3.5.2.   Real-Time Timers: In order to support the Real-time timers we need to implement the “void rtimer_arch_schedule(rtimer_clock_t t)” function. This function is expected to schedule a call to “rtimer_run_next()” from interrupt context in ‘t’  time, where ‘t’ is a number of ticks so that RTIMER_ARCH_SECOND ticks are a second. Our implementation sets RTIMER_ARCH_SECOND to 65535, which is the maximum granularity allowed by Contiki. We choose to use the TIMER1 clock to implement this functionality. We set the MCR to reset on every match, and MR0 to (TICKS_PER_SECOND / RTIMER_ARCH_SECOND * t) – 1. Every time the interrupt is received the timer is disabled and we will be re-enabled by the rtimer system if required.
 

3.5.3.   LEDs: The LED support in Contiki assumes that there are 3 color LEDS – RED, GREEN & BLUE. To be aligned with this assumption we choose to have the LEDs interface to control the single RGB led on the board while each color is controlled separately.

The LED support in Contiki requires the following functions:

·        void leds_arch_init(void): Set initial LED states ( all off)

·        unsigned char leds_arch_get(void): Return a bit-mask of the LEDs which are on (LEDS_RED, LEDS_GREEN and LEDS_BLUE)

·        void leds_arch_set(unsigned char leds): Set the LEDs state according to the given bit-mask.

3.5.4.   SLIP (Serial Line Internet Protocol): Contiki implements a simple SLIP stack which can be used to operate the uIP stack over a serial port. The architecture is required to support a “void slip_arch_writeb(unsigned char c)” function which should output the given char to the serial port, and expected to call the “int slip_input_byte(unsigned char c)” when a char is received from the serial port. For supporting this we’ve implemented an interrupt handler to be able to pass received bytes from the serial port to the SLIP stack.

4.     Further enhancements:

There is still work that needs to be done to better utilize the capabilities of the LPC2148 Microcontroller and the interfaces of the LPC2148 Education Board. Following is a list of items that should be further investigated:

4.1. Power Save Support: The current implementation of the Contiki event loop uses busy polling, constantly seeking for processes to run although it is possible that none of the processes are pending execution. We can reduce our power consumption by using the LPC2148 power save functionalities, waking up when the next event (either an expired timer or an interrupt) is triggered.

4.2. Watchdog Support: The LPC2148 Microcontroller has a Watchdog Timer interface which can be used to auto-reset the board if we detected a long period of inactivity. Contiki already include Watchdog capabilities so we can hook them together.

4.3. IRQ Interrupts: There is no real justification for using the FIQ interrupt for the clock & UART. We should switch to using IRQs.

4.4. Buttons Support: We should support the LPC2148 Education Board buttons and joystick using the Contiki sensors interface.

 

4.5. Temperature Sensor: We can support the LPC2148 Education Board temperature sensor.

4.6. Real-Time Clock: We can use the LPC2148 Microcontroller RTC interface to support date and time functionalities.

5.     Example applications:

We have created 2 example application which demonstrates the programming the LPC2148 with the Contiki system.

5.1. Hello World: The Hello World application demonstrates the basics of Contiki - Processes, Timers, Real-Time Timers and LEDs support. It also demonstrates how standard output is mapped to the serial console and also using the LCD display.

Compiling and uploading the Hello-World application:




The Hello-World application in action:

 



5.2. Telnet Server: The Telnet Server application is intended to demonstrate the uIPv4 stack basic capabilities. In-order to be able to test this application, after uploading it to flash, it is needed to disable the automatic entrance to ISP mode when opening a serial connection (Remove from J6 the ISP-RESET and ISP-P0.14 pins).



Compiling and uploading the Telnet-Server application:



Running the SLIP driver on the host PC:



Connecting to the Telnet server:




6.     Source files

The code is provided as a full Contiki 2.3 archive which includes the LPC2148 support and as a diff file which can be patched against the original Contiki 2.3 release:

Contiki 2.3 with LPC2148 Support
Patch for LPC2148 Support on Contiki 2.3

·        platform/lpc2148edu/Makefile.lpc2148edu – Makefile for the LPC2148 Education Board platform

·        platform/lpc2148edu/lpc2148-flash.ld – Linker Script for the LPC2148 Education Board platform

·        platform/lpc2148edu/contiki-conf.h – Definitions of Contiki features set

·        platform/lpc2148edu/contiki-lpc2148edu-main.c – The main()  application which is in-charge of platform initialization and running the Contiki event loop

·        platform/lpc2148edu/ks0070b_lcd.c -  Driver for the KS0070B 2x16 character LCD

·        platform/lpc2148edu/lcd.c – Driver for enabling the KS00700B LCD on the LPC2148 Education Board platform

·        platform/lpc2148edu/lcd.h - Driver for enabling the KS00700B LCD on the LPC2148 Education Board platform

·        platform/lpc2148edu/leds-arch.c – LPC2148 Education Board support for the Contiki LEDs API

·        cpu/lpc2148/Makefile.lpc2148 – Makefile for the LPC2148 microcontroller

·        cpu/lpc2148/interrupt.h – Interrupts setup code for the LPC2148 Microcontroller

·        cpu/lpc2148/io.h – Defines for easier handling of writing/reading LPC2148 microcontroller registers

·        cpu/lpc2148/lpc214x.h – Defines for easier handling of writing/reading LPC2148 microcontroller registers

·        cpu/lpc2148/startup.S – Startup/Bootstrap code for the LPC2148 microcontroller

·        cpu/lpc2148/lpc2148def.h – Definitions of various size variables types

·        cpu/lpc2148/fiq.c – Generic interrupt handler for FIQ interrupts

·        cpu/lpc2148/lpc2148.c – Implementation of functionalities which are required by the newlib C library.

·        cpu/lpc2148/clock.c – LPC2148 Microcontroller support for the Contiki clock and event timers interfaces

·        cpu/lpc2148/rtimer-arch.c – LPC2148 Microcontroller support for Contiki Real-Time timers interface

·        cpu/lpc2148/rtimer-arch.h – LPC2148 Microcontroller support for Contiki Real-Time timers interface

·        cpu/lpc2148/uart.c – Driver for the UART0 port on the LPC2148 Microcontroller

·        cpu/lpc2148/uart.h – Driver for the UART0 port on the LPC2148 Microcontroller

·        cpu/lpc2148/slip_uart.c – LPC2148 Microcontroller support for the Contiki SLIP driver over the UART0 port

·        cpu/lpc2148/watchdog.c – Null support for reboot of the LPC2148 Microcontroller

·        cpu/lpc2148/mtarch.h – Null support for the Contiki Threads support

·        core/sys/rtimer.c – Bug fix in the Contiki Real-Time timers’ implementation of Timer entries which are scheduled twice – second time immediately following the first one

·        examples/lpc2148edu/Makefile – Makefile for generating the test application for the LPC2148 Education Board

·        examples/lpc2148edu/hello-world.c – Test application which print “Hello World” message to the UART and to the character LCD, and uses etimers and rtimers to control the color LED

·        examples/lpc2148edu/telnet-server.c – Test application which utilize the Contiki uIP stack and Telnet Server application and uses the SLIP over UART0 as the uIP network interface

·        tools/tunslip.c – Adjustments in the Contiki Linux SLIP driver to send the data to the UART slower to be able to work with the limited functionality of the UART0 driver implementation

 

7.     License:

Copyright (c) 2010, Yair Hershkovitz, Demitry Lev and the

School of Computer Science in Tel Aviv University.

All rights reserved.

Redistribution and use in source and binary forms, with or without

modification, are permitted provided that the following conditions

are met:

1. Redistributions of source code must retain the above copyright

   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright

   notice, this list of conditions and the following disclaimer in the

   documentation and/or other materials provided with the distribution.

3. The name of the author may not be used to endorse or promote

   products derived from this software without specific prior

   written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS' AND ANY EXPRESS

OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF IABILITY,

WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.