Software Architecture

From NESTFE Wiki

Jump to: navigation, search

The nestFE trio demos are all run within the Kraken library, which in itself does not do anything but includes several other libraries with the help of its make system. This page is intended to serve as an entry point to the new user of Kraken, explaining which libraries are used, what they do, and how the make system works.

Contents

Kraken nesC Library

The Kraken library is located in tinyos-1.x/contrib/nestfe/nesc/lib/kraken. The main module is KrakenC.nc. There are two steps required to include the Kraken library in your application:

1. Include the KrakenC module somewhere in your app and wire it to StdControl, eg:

 components Main, KrakenC....
 Main.StdControl -> KrakenC;

2. Make your makefile look like the following:

COMPONENT = MyApp

....


KRAKEN_MAKERULES ?= $(TOSDIR)/../contrib/nestfe/make/kraken.Makerules
include $(KRAKEN_MAKERULES)

The first step includes the KrakenC file, which is what pulls all other libraries into your application. The second step causes your application to be made using the Kraken makesystem, which includes all the correct paths and builds things in the correct order. (Be sure that you are using the new tinyos makesystem as well, ie. that your MAKERULES environment variable is set to tinyos/tools/make/Makerules).

Kraken Makesystem

The Kraken make system is embodied in a single file at tinyos-1.x/contrib/nestfe/make/kraken.Makerules. This Makefile adds all the correct include directories to your compiler path for the libraries described below and passes environment variables to your application.

Important: the prometheus driver crashes any telos that is not attached to the trio board. Read below to see how to not include the prometheus driver in a Kraken application

Because the trio only has 48K of program memory, the makesystem was built to allow the user to compile in or not compile in several different aspects of the Kraken libraries. By default, all libraries are compiled in. To tell the makesystem not to compile a library in, the NO_XXX flag should be set to TRUE. For example, the following makefile for nestfe/nesc/apps/TestDetectionEvent causes the makesystem not to compile in Deluge or UART because they do not fit in flash. It also tells it not to compile in Prometheus because this node does not have a trio board attached.

COMPONENT = TestDetectionEventC
  
#NO_LOCATION = TRUE
#NO_TIMESYNC = TRUE
#NO_FILESET = TRUE
#NO_HOOD = TRUE
#NO_REGISTRY = TRUE
#NO_REGISTRY_STORE = TRUE
#NO_NUCLEUS = TRUE
#NO_RPC = TRUE
#NO_RPC_FOR_REGISTRY = TRUE
#NO_PYTHON = TRUE
#NO_SENSORS = TRUE
#NO_SUPPLEMENT = TRUE
NO_UART = TRUE
NO_PROMETHEUS = TRUE
NO_DELUGE = TRUE

#PLATFORM=pc

#PFLAGS += -DRPC_LEDS

KRAKEN_MAKERULES ?= $(TOSDIR)/../contrib/nestfe/make/kraken.Makerules
include $(KRAKEN_MAKERULES)

If your application is compiling very slowly, you can remove more items above to make it compile faster. The items that take the longest time to compile are: fileset, nucleus, rpc, python, supplement.

The PLATFORM flag towards the end should be uncommented if the application is being compiled for the PC. It automatically causes the correct libraries to be installed. Some applications, such as those that depend on hardware or timesync, simply cannot be compiled for the PC platform.

#PLATFORM=pc

The final flag in this example makefile is used to indicate that rpc should use leds. A green light should toggle whenever an rpc command is received and a red led toggles whenever a response is sent. A yellow led toggles whenever an error in rpc is detected. Other applications may use other flags.

#PFLAGS += -DRPC_LEDS

Fileset is a tool that allows multiple people test an application even while all of the kraken libraries are constantly changing. When a kraken application is compiled, the fileset_<platform>.txt file is created in the build/<platform> directory and indicates the cvs version of all files used in the application. If the user is sure that this set of files is a good, working version, the fileset file can be copied into the main application directory and checked into cvs. Then, whenever anybody else checks out the application and compiles, the fileset tool will compare the generated build/<platform>/fileset_<platform>.txt file with the file in cvs. If they differ, it will provide a warning. That way, the user knows that the version of the files they have checked out of cvs are different from those that are known to work.

TOSBoot and Formatting the Flash

Before using a Kraken application, make sure you have done the following:

  1. Install nestfe/nesc/apps/FormatFlash and wait about 30 seconds (the green LED will turn on when complete, but it's difficult to see in a trio node)
  2. Install your Kraken application. If everything goes well, will be installed as part of the install process.

The flash format is as follows:

  1. One slot for the golden image (0xDF, 0xF0000)
  2. Six 64k partitions for program images: trio demo, deluge demo, nucleus demo, straw demo, detection demo, and one extra slot (0xD0-0xD5)
  3. The other 9 partitions for logging (0x00 -0x08)

Libraries

TOSBoot Bootloader

TOSBoot runs at startup, and can load and execute any Deluge image. It provides support for the Golden Gesture, which returns the node to a basic Golden Image containing enough functionality to load a new program.

Grenade Timer

The Grenade timer is armed at startup, and returns the node to the Golden Image after an unchangeable period of time has elapsed, providing a failsafe against buggy programs that hang the node.

KrakenMain Initialization

KrakenMain transforms the StdControl.init() call into a two-part PreControl.init() and AppControl.init() sequence, and transforms the StdControl.start() call into a two-part PreControl.start() and split-phase SplitInit.init(), which calls AppControl.start() when finished. This multi-phase boot sequence is required to successfully initialize the Trio node's many components.

Prometheus and VoltageHysteresis

Prometheus controls the battery, supercapacitor, and solar charging system to keep the node running while energy availability conditions change over time.

VoltageHysteresis works with KrakenMain to delay the initialization of the rest of the node until enough voltage is available to initialize it successfully.

EventGenerator

EventGenerators produce detection events by signaling the DetectionEvent component directly or by updating a Registry value that signals the DetectionEvent component, and provide remote control of detection parameters using Registry attributes.

PIR EventGenerator PIR EventGenerator takes input from the PIR sensors and runs a smoothing, filtering, and threshholding algorithm that produces a stream of detection events with associated confidence values for moving objects.

PIRSimpleThresh EventGenerator PIRSimpleThresh EventGenerator takes input from the PIR sensors and compares it to a simple threshhold, signalling a detection event if the value rises above it.

UserButton EventGenerator UserButton EventGenerator signals a detection event every time the user button on a particular Trio is pressed, for testing purposes.

Dummy EventGenerator Dummy EventGenerator provides a source of detection events that simulates an entity moving past every node simultaneously.

TimeSync

TimeSync is a protocol that lets each node determine its temporal location relative to a global clock, enabling correlated timestamping of data. (Vanderbilt University)

Drip/Drain

Drip is an epidemic single-message dissemination protocol used for sending commands and data to every mote.

DripSend is a layer on top of Drip that disseminates single messages to all nodes within a named group composed of endpoints, which receive the message, and forwarders.

Drain is a single-message collection tree protocol with per-link reliable transfer, used for collecting data and command responses from any mote.

DrainGroup is an interface that a node calls to join a named group as an endpoint, which then causes all other nodes on that node's path to the root to join that group as forwarders.

Deluge

Deluge is an epidemic dissemination protocol for large binary program images and basic image switching commands, which we use to reprogram the entire network.

Supplement

Supplement is a tool for disseminating a file along with a Deluge image, which we use to store application metadata and attribute schemas directly on the node and retrieve them later.

Straw

Straw is a data collection protocol for large binary data objects with end-to-end reliablility for one node at a time that runs over the Drain tree and uses Bcast to send acknowledgement messages.

DetectionLog

DetectionLog records a sequence of values from the PIR motion detector to a partition on the flash, and exports the data from this partition to Straw.

DetectionEvent

DetectionEvent is a component that aggregates events from each detector, stamps them with temporal and spatial location, and sends them to the root over Drain.

Nucleus

Nucleus is a basic network management protocol that runs atop Drip and Drain, providing get() and set() commands for single or multiple Nucleus attributes or RAM symbols.

Rpc

Rpc: a tool for calling arbitrary functions on a node from the PC. The user places the "@rpc()" tag after an provided/used interface or function declaration. Then, the function is automatically imported and made available from the pc-side python command line.

RamSymbols

Ram Symbols: a tool for getting and setting arbitrary module variables from the pc. The code takes about 100bytes of ram, and simply does a memcpy to/from a specified memory address. All the ram symbols are imported by the pytos pc-side tool and can be get/set using the "poke" and "peek" tools

Registry

Registry: a tool for caching "Attributes", which are shared variables that can be get/set by any module; a module can "import" the attribute into scope by "using" the Attribute interface, and all such modules are notified through the "updated" event whenever the attribute changes. The user can also get/set the node attributes through Rpc.

Registry Store

Registry Store: a tool for specifying a set of Registry attributes to be made persistent. These attributes are stored in flash and restored when the node reboots. The save/restore commands are available as Rpc commands in pytos, or can be called from the node itself using it's own logic of when to save/restore.

Hood

Hood: a tool for sharing Registry Attributes between nodes. A module can import/export an attribute to/from neighboring nodes by using the "Reflection" interface. All "reflected" attributes of a node are cached on all neighboring nodes, and the values are automatically updated when they change.

Location

The location library is a configuration file that declares several registry attributes:

  • GpsLocation: the location set by the dgps unit
  • RssiLocation: the location set by rssi localization
  • TrueLocation: the true location (perhaps using rulers)

All applications should use the "Location" registry attribute, which is the abstract location value provided by the LocationMuxM component. The "Location" attribute takes the value of one of the three locations above, depending on the "channel" that the LocationMux module is set to. The LocationMux module has two rpc functions, that allow one to get and set the location channel:

>>> app.LocationMuxM
...
              uint8_t getChannel( )
                 void select(  uint8_t channel )

The channel number can be gotten in the pytos environment from the attribute enums, as follows:

>>> app.LocationMuxM.select(app.enums.attributes.ATTRIBUTE_RSSILOCATION)

Here is an example transaction, where we first set the "Location" attribute when it is pointing at "GpsLocation". Then, we switch to "TrueLocation" and see that the value has changed. Then, we switch back to "GpsLocation" and see that the value has changed back.

>>> app.LocationMuxM.getChannel()

        TosMsg(am=1) uint8_t,  nodeID=1:
                 uint8_t value  : 2

>>> app.RegistryC.Location.set.val.x=101
>>> app.RegistryC.Location.set.val.y=98
>>> app.RegistryC.Location.set()
>>> app.RegistryC.Location.get()

        TosMsg(am=17) location_t,  nodeID=1:
                     int32_t x  : 101
                     int32_t y  : 98

>>> app.LocationMuxM.select(app.enums.attributes.ATTRIBUTE_TRUELOCATION)
>>> app.LocationMuxM.getChannel()

        TosMsg(am=1) uint8_t,  nodeID=1:
                 uint8_t value  : 10

>>> app.RegistryC.Location.get()

        TosMsg(am=17) location_t,  nodeID=1:
                     int32_t x  : 0
                     int32_t y  : 0

>>> app.LocationMuxM.select(app.enums.attributes.ATTRIBUTE_GPSLOCATION)
>>> app.RegistryC.Location.get()

        TosMsg(am=17) location_t,  nodeID=1:
                     int32_t x  : 101
                     int32_t y  : 98


The LocationMuxM module can actually be used to multiplex any set of registry attributes that have the same type. However, a search/replace must be used on the module to change it to another type of mux. Documentation is in the code.

Personal tools