Embedded Freaks..

September 24, 2008

Bare NesC: Wiring The Components

Filed under: WSN — Tags: , — kunilkuda @ 2:06 pm

Bare NesC is my term for NesC without TinyOS (refer to this post for my experiment with bare NesC). This post will continue the experiment, by interfacing the bare NesC program with other components.

Purpose

To check whether the wiring mechanism still works without TinyOS

Testing Program


#include <avr/io.h>

module MainC
{
  uses
  {
    interface Init as PeripheralInit;
    interface Leds;
  }
}
implementation
{
  void blinkLeds();

  int main() __attribute__ ((C, spontaneous))
  {
    // Init the peripherals
    call PeripheralInit.init();

    // Blink leds once it ready
    blinkLeds();

    while(1){
    }
  }

  void blinkLeds()
  {
    uint16_t delay;

    // Blink the leds once we're ready
    call Leds.set(7);
    for(delay = 0; delay < 0xFFFF; delay++);
    call Leds.set(0);
  }
}

Needed Files

Init.nc


// $Id: Init.nc,v 1.4 2006/12/12 18:23:14 vlahan Exp $
/*                                    tab:4
 * "Copyright (c) 2004-5 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 * Copyright (c) 2004-5 Intel Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE
 * file. If you do not find these files, copies can be found by writing to
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
 * 94704.  Attention:  Intel License Inquiry.
 */

/** The basic synchronous initialization interface.
  *
  * @author Philip Levis
  * @date   January 17 2005
  */

#include "TinyError.h"

interface Init {

  /**
   * Initialize this component. Initialization should not assume that
   * any component is running: init() cannot call any commands besides
   * those that initialize other components.
   *
   * @return SUCCESS if initialized properly, FAIL otherwise.
   * @see TEP 107: Boot Sequence
   *
   */
  command error_t init();
}

This is TinyOS’ interface, and needed to be copied into the local directory since we dont link with TinyOS anymore. Note that the file needs TinyError.h, to be included in the local directory too.

TinyError.h


// $Id: TinyError.h,v 1.5 2007/04/15 21:11:38 klueska Exp $
/*                                    tab:4
 * "Copyright (c) 2000-2005 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * @author Phil Levis
 * @author David Gay
 * Revision:  $Revision: 1.5 $
 *
 * Defines global error codes for error_t in TinyOS.
 */

#ifndef TINY_ERROR_H_INCLUDED
#define TINY_ERROR_H_INCLUDED

enum {
  SUCCESS        = 0,
  FAIL           = 1,           // Generic condition: backwards compatible
  ESIZE          = 2,           // Parameter passed in was too big.
  ECANCEL        = 3,           // Operation cancelled by a call.
  EOFF           = 4,           // Subsystem is not active
  EBUSY          = 5,           // The underlying system is busy; retry later
  EINVAL         = 6,           // An invalid parameter was passed
  ERETRY         = 7,           // A rare and transient failure: can retry
  ERESERVE       = 8,           // Reservation required before usage
  EALREADY       = 9,           // The device state you are requesting is already set
};

typedef uint8_t error_t __attribute__((combine(ecombine)));

error_t ecombine(error_t r1, error_t r2)
/* Returns: r1 if r1 == r2, FAIL otherwise. This is the standard error
     combination function: two successes, or two identical errors are
     preserved, while conflicting errors are represented by FAIL.
*/
{
  return r1 == r2 ? r1 : FAIL;
}

#endif

The header file contains error_t type definition. Although we can re-declare it, I think it’s faster to copy it from TinyOS directory.

Leds.nc


// $Id: Leds.nc,v 1.4 2006/12/12 18:23:14 vlahan Exp $
/*                                    tab:4
 * "Copyright (c) 2005-2005 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * Commands for controlling three LEDs. A platform can provide this
 * interface if it has more than or fewer than three LEDs. In the
 * former case, these commands refer to the first three LEDs. In the
 * latter case, some of the commands are null operations, and the set
 * of non-null operations must be contiguous and start at Led1. That
 * is, on platforms with 2 LEDs, LED 3's commands are null operations,
 * while on platforms with 1 LED, LED 2 and LED 3's commands are null
 * opertations.
 *
 * @author Joe Polastre
 * @author Philip Levis
 */

interface Leds {

  /**
   * Turn on LED 0. The color of this LED depends on the platform.
   */
  async command void led0On();

  /**
   * Turn off LED 0. The color of this LED depends on the platform.
   */
  async command void led0Off();

  /**
   * Toggle LED 0; if it was off, turn it on, if was on, turn it off.
   * The color of this LED depends on the platform.
   */
  async command void led0Toggle();

  /**
   * Turn on LED 1. The color of this LED depends on the platform.
   */
  async command void led1On();

  /**
   * Turn off LED 1. The color of this LED depends on the platform.
   */
  async command void led1Off();

   /**
   * Toggle LED 1; if it was off, turn it on, if was on, turn it off.
   * The color of this LED depends on the platform.
   */
  async command void led1Toggle();

  /**
   * Turn on LED 2. The color of this LED depends on the platform.
   */
  async command void led2On();

  /**
   * Turn off LED 2. The color of this LED depends on the platform.
   */
  async command void led2Off();

   /**
   * Toggle LED 2; if it was off, turn it on, if was on, turn it off.
   * The color of this LED depends on the platform.
   */
  async command void led2Toggle();

  /**
   * Get the current LED settings as a bitmask. Each bit corresponds to
   * whether an LED is on; bit 0 is LED 0, bit 1 is LED 1, etc. You can
   * also use the enums LEDS_LED0, LEDS_LED1. For example, this expression
   * will determine whether LED 2 is on:
   *
   *
<pre> (call Leds.get() & LEDS_LED2)</pre>
*
   * This command supports up to 8 LEDs; if a platform has fewer, then
   * those LEDs should always be off (their bit is zero). Also see
   * <tt>set()</tt>.
   *
   * @return a bitmask describing which LEDs are on and which are off
   */
  async command uint8_t get();

  /**
   * Set the current LED configuration using a bitmask.  Each bit
   * corresponds to whether an LED is on; bit 0 is LED 0, bit 1 is LED
   * 1, etc. You can also use the enums LEDS_LED0, LEDS_LED1. For example,
   * this statement will configure the LEDs so LED 0 and LED 2 are on:
   *
   *
<pre> call Leds.set(LEDS_LED0 | LEDS_LED2);</pre>
*
   * This statement will turn LED 1 on if it was not already:
   *
   *
<pre>call Leds.set(call Leds.get() | LEDS_LED1);</pre>
*
   * @param  val   a bitmask describing the on/off settings of the LEDs
   */
   async command void set(uint8_t val);

}

The Leds.nc file contains Leds interface description. Note that it is the same TinyOS Leds interface description, but without Leds.h header (I don’t think Leds.h is needed in my program).

Now, that’s all of the files that I borrowed from TinyOS.

Components

Here’s my own component: LedsC.nc. Although it has the same name as TinyOS version, I’ve changed it to directly interface with AVR’s hardware.

LedsC.nc


#include <avr/io.h>

typedef uint8_t bool;

module LedsC
{
  provides
  {
    interface Init;
    interface Leds;
  }
}
implementation
{
  bool isLed0On();
  bool isLed1On();
  bool isLed2On();

  // Initialize the port as output
  command error_t Init.init()
  {
    DDRA |= (1 << PA0) | (1 << PA1) | (1 << PA2);
  }

  async command void Leds.led0On()
  {
    PORTA &= ~(1 << PA0);
  }

  async command void Leds.led0Off()
  {
    PORTA |= (1 << PA0);
  }

  async command void Leds.led0Toggle()
  {
    if (isLed0On()) {
      call Leds.led0Off();
    }
    else {
      call Leds.led0On();
    }
  }

  async command void Leds.led1On()
  {
    PORTA &= ~(1 << PA1);
  }

  async command void Leds.led1Off()
  {
    PORTA |= (1 << PA1);
  }

  async command void Leds.led1Toggle()
  {
    if (isLed1On()) {
      call Leds.led1Off();
    }
    else {
      call Leds.led1On();
    }
  }

  async command void Leds.led2On()
  {
    PORTA &= ~(1 << PA2);
  }

  async command void Leds.led2Off()
  {
    PORTA |= (1 << PA2);
  }

  async command void Leds.led2Toggle()
  {
    if (isLed2On()) {
      call Leds.led2Off();
    }
    else {
      call Leds.led2On();
    }
  }

  async command uint8_t Leds.get()
  {
    uint8_t result = PORTA;
    return (result & 0x07);
  }

  async command void Leds.set(uint8_t val)
  {
    uint8_t portVal = PORTA & 0xF8;
    portVal |= (~val & 0x07);

    PORTA = portVal;
  }

  bool isLed0On()
  {
    return (bit_is_clear(PORTA, PA0));
  }

  bool isLed1On()
  {
    return (bit_is_clear(PORTA, PA1));
  }

  bool isLed2On()
  {
    return (bit_is_clear(PORTA, PA2));
  }
}

MainAppC.nc


configuration MainAppC
{
}
implementation
{
  components MainC;
  components LedsC;

  MainC.PeripheralInit -> LedsC;
  MainC.Leds -> LedsC;
}

The last of all is MainAppC.nc which wired all the needed components into single application.

Compilation

The compilation is simple:


$ nescc -gcc=avr-gcc -mmcu=atmega128 -Os -g -I. MainAppC.nc -o main.elf

Conclusion

The wiring still works. Plus, the compilation result (program size) is not much different with simple C compilation.

Advertisements

1 Comment »

  1. What should be the name of the file that includes the “Testing Program” content?

    Comment by Shakthi Kannan — August 6, 2010 @ 6:43 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: