[Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/rincon/docs TinyOS 1.x Style Guide.doc, NONE, 1.1

dmm rincon at users.sourceforge.net
Tue Aug 1 16:07:45 PDT 2006


Update of /cvsroot/tinyos/tinyos-1.x/contrib/rincon/docs
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv32618/contrib/rincon/docs

Added Files:
	TinyOS 1.x Style Guide.doc 
Log Message:
Uploaded the style guide


--- NEW FILE: TinyOS 1.x Style Guide.doc ---
ÐÏࡱá






ce file contains a single configuration, module, or interface.   Unless there is a compelling reason not to do so, each interface should be implemented in a single module, and each module should have a corresponding configuration file.
Configuration Source Files
Each module should have an associated configuration file, even if the configuration file serves only to redirect interfaces to the module.

NesC configuration files have the following ordering: 

Beginning comments
Includes statements
Configuration declaration, including interfaces provided and used.
Implementation declaration
Components
Pass-through interface wiring, separated by module (=)
Interface wirings, separated by module (->)

Module Source Files
NesC module files have the following ordering: 

Beginning comments 
Includes statements
Module declaration, including interfaces provided and used.
Implementation declaration
Global Variables
Prototypes
Commands, separated by interface type
Events, separated by interface type
Tasks
Functions
Defaults

Sections and sets of interface commands and events should be separated by comments.  

Interface Source Files
Interfaces should be well defined and each interface should be implemented in a separate module when possible, promoting better architecture and readability.  

Interfaces should never be renamed using “as” unless:

One interface is used more than once in a single module, accessing multiple modules or different parameterized interfaces.

Renaming the interface adds clarity to the code by describing the function of the interface.  For example, “Timer as WatchdogTimer”

Do not rename an interface in a module or component simply to make its name shorter.  Avoid renaming interfaces whenever possible.

Beginning comments
Each source file should have an optional copyright notice at the top, followed by a commented description of the source file and author(s).  The copyright block comments begin with only one asterisk.  All description blocks begin with two asterisks.


/*
 * Optional copyright information
 */

/**
 * Source file description
 * 
 * @author <author name>
 */

Import statements
The first non-commented line of most nesC source files is an import statement.  After that, the module, interface, or configuration declaration can begin.  The “includes” keyword is used freely in TinyOS 1.x to prevent header files from being imported and parsed multiple times, but #include is used in TinyOS 2.x.  The “#include” preprocessor command can be used in TinyOS 1.x as well, but with care.  Not all header files in TinyOS 1.x are setup to parse only once.

Indentation
Two spaces should be used as the unit of indentation.  Tabs should never be used, unless the text editor being used is setup to automatically replace the tab key with the proper number of spaces.

Line Length
Avoid lines longer than 80 characters, since they’re not handled well by many terminals and tools.

Examples for use in documentation should have a shorter line length, generally no more than 70 characters.

Wrapping Lines
When an expression will not fit on a single line, break it according to these general principles:

Break after a comma
Break before an operator
Prefer higher-level breaks to lower-level breaks
Align the new line with the beginning of the expression at the same level on the previous line, and then indent 4 spaces to promote readable code.

Here are some examples of breaking functions calls:

someFunction(expression1, expression2, expression3,
    expression4, expression5);

var = someFunction(expression1, 
          someFunction2(expression2,
              expression3));

Following are two examples of breaking an arithmetic expression.  The first is preferred, since the break occurs outside the parenthesized expression, which is at a higher level.

// Preferred
longName1 = longName2 * (longName3 + longName4 – longName5)
                + 4 * longname6;

// Avoid
longName1 = longName2 * (longName3 + longName4
                -longName5) + 4 * longName6;

Following is an example of indenting function/command declarations.  

command void MyInterface.myCommand(uint8_t arg1,
    uint16_t arg2, void *arg3,
    uint32_t arg4) {

  ...
}

Line wrapping for if statements should use the 4-space rule, making the body easy to see.  Blank lines can optionally be placed between indented code and the body to promote readability, and definitely before each else-statement.  Below is an example of an incorrectly formatted if-statement, and a properly formatted if-statement:

// BAD - Incorrectly formatted, bad style, don’t use:
if((condition1 && condition2)
  || (condition3 && condition4)
  || !(condition5 && condition6)) {
  // Easy to miss:
  doSomething();  
} else {
  // Smashed together with the lines above:
  doSomethingElse();
}



// Properly formatted if-statement:
if((condition1 && condition2)
    || (condition3 && condition4)
    || !(condition5 && condition6)) {

  // Easy to see:
  doSomething();

} else {
  // Easy to read and see the else-statement:
  doSomethingElse();
}



// Or use this properly formatted if-statement:
If((condition1 && condition2) || (condition3 && condition4)
    || !(condition5 && condition6)) {
  doSomething();

} else {
  doSomethingElse();
}

Comments
NesC programs can have two kinds of comments: implementation comments and documentation comments. Implementation comments are those found in C++, which are delimited by /*...*/, and //. Documentation comments (known as "doc comments") are those found in Java, delimited by /**...*/.  These two comment types have different color schemes when opened with a code development studio, like Eclipse for example.

Implementation comments are meant for copyright information, commenting out code, or for comments about the particular implementation within a command or function. 

Doc comments are meant to describe the specification of the code, from an implementation-free perspective, to be read by developers who might not necessarily have the source code at hand.  Doc comments should be used at the top of every source file to describe what the source file does overall.  They should also be used as one-line comments above each global variable, and multi-line comments describing each command or event.

Comments should be used to give overviews of code and provide additional information that is not readily available in the code itself.  Comments should contain only information that is relevant to reading and understanding the program. For example, information about how the corresponding module is built or in what directory it resides should not be included as a comment. 

Discussion of nontrivial or not-so-obvious design decisions is appropriate, but avoid duplicating information that is present in (and clear from) the code. It is too easy for redundant comments to get out of date. In general, avoid any comments that are likely to get out of date as the code evolves. 

The frequency of comments sometimes reflects poor quality of code.   Well written code should be mostly self-documenting.  When you feel compelled to add a comment inside a block of code, consider rewriting the code to make it clearer. 

Comments should not be enclosed in large boxes drawn with asterisks or other characters. 
Comments should never include special characters such as form-feed and backspace.

5.1 Implementation Comments
Programs can have three styles of implementation comments: block, single-line, and divisor comments.
5.1.1 Block and Documentation Comments
Doc comments are used to provide descriptions of files, functions, commands, and data structures.  Doc comments should be used at the beginning of each configuration and module, and before each command, function, and task.

Block comments, with only one asterisk, can be used within the code itself to form a multi-line comment.  They may also be used in a one-line format as well.

A block comment should be preceded by a blank line to set it apart from the rest of the code.

/**
 * Here is a block comment, describing the following 
 * command or function.  Note the two asterisks.
 * @param arg1 the first argument
 * @param arg2 the second argument
 * @retur
n SUCCESS if the command will be processed.
 */
command result_t MyInterface.myCommand(uint8_t arg1, 
    uint8_t arg2) {

  /*
   * This is a multi-line comment within the code 
   * itself, and should be used less often. 
   * Note the single asterisk.
   * The code should already be described in the 
   * command’s block comment at the top.  Consider
   * rewriting code if you require multi-line block
   * comments in the middle of a function.
   */
   if(doSomething()) {
    /* This is a single line block comment */
    i = 5;
    return SUCCESS;
   } 

   return FAIL;
}

5.1.2 Single-Line Comments
Short comments can appear on a single line indented to the level of the code that follows.  If a comment can’t be written in a single line, it should follow the block comment format above.   If possible, single-line comments should not be written to the right side of code.  Instead, single-line comments should be located just above the code being described, which prevents problems with comment alignments.  If comments have to be written to the right side of the code, all end-of-line comments should align.  

The // comment delimiter can comment out a complete line or only a partial line.  It shouldn’t be used on consecutive multiple lines for text comments; however, it can be used in consecutive multiple lines for commenting out sections of code.
 
/** Single-line description of the global variable */
uint8_t global;


if(condition) {
  uint8_t var;       // this type of comment is
  uint8_t var2 = 5;  // not preferred due to
                     // alignment issues

  // Single-line description of the following line
  doSomething(arg1, arg2);

  /* Another single line comment inside this block */
  //if(condition1) {
  //  doSomethingElse();
  //}
}
5.1.2 Section Divisor Comments
Sections in a module should be grouped in the order described in Sec. 3, and then by individual interfaces.  

Commands and events from an individual interface should not be scattered throughout the file; they should be grouped together.  

Each section and group of interface commands or events should be separated with a few blank lines and a comment describing the new section.  The comment can be in any format, so long as consistency is upheld.  A unique, easy to see single-line comment is preferred over multi-line comment divisors to keep code clean, short, and readable.

One example of a single-line divisor is the /** */ comment with a set number of asterisks to each side and the description in the middle.  In the case of this example, there are 15 asterisks on each side of the section divisor comment.  15 asterisks on each side is easier to spot than a standard /** */ comment:

/***************** MyModule Commands ****************/
Variable Declarations
6.1 Number Per Line
One declaration per line is recommended since it encourages commenting and is easy to read and find variables.

/** Global indentation level */
uint8_t level;

/** Size of the table */
uint8_t size;

should be used instead of:
 
uint8_t level, size;
6.2 Initialization
It is easiest to initialize all global variables for a given module inside the StdControl.init() command.  Any module that needs to initialize variables should provide the StdControl interface to do so.

Local variables should be defined at the top of the function they are used within.  After all local variables are defined at the top of the function, they can be initialized individually.  The last local variable defined can be initialized inline.  This is more of a compiler requirement.

If necessary, local variables can declared in the block they are used within, but it is preferred to have all locals declared at the top of the function.  Having all variables defined in one location makes it easier to find all of the function’s variable declarations, and prevents the possibility of having a duplicate variable name in the function.
6.3 Placement
Put variable declarations only at the beginning of blocks (between the “{“ and “}”).   Global variables should always be defined first at the top of the implementation of a module, and local variables should be defined at the top of the function.  It doesn’t hurt to add the one-line doc comment above local variables describing what they do, when needed.

void myMethod() {
  uint8_t varA;
  uint8_t varB;
  uint8_t varC = 3;

  varA = 1;
  varB = 2;

  if(condition) {
    /* Not good practice, but if absolutely necessary: */
    uint8_t var2 = 0;
    ...
  }
}

Avoid local declarations that hide higher level declarations.  For example, do not declare the same variable name in an inner block:

int count;
...
void myFunction() {
  int count = 0;
  ...
}

Do not declare the same name as a global variable as a parameter in a function.  This may generate compiler warnings and is confusing to the reader.  A better method is to change the local argument’s name to not match the global variable name:

uint16_t count;

/** * Even if the local variable refers to the same concept
 * as an existing global, rename it.
 */
void setCount(uint16_t myCount) {
  count = myCount;
}


Statements
Simple Statements
Each line should contain at most one statement.  Example:

// Correct:
argv++;
argc--;

// Bad:
argv++; argc--;

Compound Statements
Compound statements are statements that contain lists of statements enclosed in braces:

if(condition1) {
  // compound statement
}

The enclosed statements should be indented one more level than the compound statement.
The opening brace should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement.
Braces are used around all statements, even single statements, when they are part of a control structure, such as an if-else or for statement.  This makes it easier to add statements without accidentally introducing bugs due to forgetting to add or correctly match braces.

Return Statements
A return statement with a value should not use parentheses unless they make the return value more obvious in some way.  Example:

	return;

	return var1;

	return (var1 == 0);


if, if-else, if else-if Statements
The if-else class of statements should have the following form:

// if-statement:
if(condition) {
  statements;
}


// if-else statement:
if(condition) {
  statements;

} else {
  statements;
}


// if else-if statement:
if(condition) {
  statements;

} else if(condition) {
  statements;
	
} else {
  statements;
}

If statements always use braces {}.  Avoid the following error-prone form:

// NEVER USE!
if(condition)
  statement;

Avoid explicitly comparing values or return values to TRUE.  The boolean variable TRUE takes on a single value, while the function could return any non-zero value to indicate success.  An exception to this is the TinyOS SUCCESS definition, whose value is changed from a 1 to a 0 in TinyOS 2.x.  In TinyOS 1.x, not comparing a return value to SUCCESS is ok, but developers should become aware that future code will need to make the explicit comparison.
 
// AVOID:
if(bar == TRUE) {
  statement;
} 

// CORRECT:
if(result != SUCCESS) {
  statement;
}

// CORRECT:
if(bar) {
  statement;
}

// Optional in TinyOS 1.x, but be aware that 2.x requires // the explicit comparison:
if(!result) {
  statement;
}

for Statements
A for statement should have the following form:

for(initialization; condition; update) {
  statements;
}

An empty for statement (one in which all the work is done in the initialization, condition, and update clauses) should have the following form:

for(initialization; condition; update);

Avoid using the comma operator in the initialization or update clause of a for statement.  If needed, use separate statements before the for loop (for the initialization clause) or at the end of the loop (for the update clause).


while Statements
A while statement should have the following form:

while(condition) {
  statements;
}

An empty while statement should have the following form:

while(condition);

do-while Statements
A do-while statement should have the following form:

do {
  statements;
} while(condition);

switch Statements

A switch st
atement should have the following form:

switch(condition) {

case ABC:
  statements;
  /** falls through */

case DEF:
  statements;
  break;

case XYZ:
  statements;
  break;

default:
  statements;
  break;
}

Every time a case falls through (doesn’t include a break statement), add a comment where the break statement would normally be.  This is shown in the preceding code example with the /** falls through */ comment.

Every switch statement should include a default case.  The break in the default case is redundant, but it prevents a fall-through error if another case is added in the future.

Provides and Uses Statements
Modules and components should define the interfaces they provide or use like the following example shows:

module MyModuleM {
  provides {
    interface StdControl;
    interface MyModule;
  }

  uses {
    interface Timer;
  }
}

Do not define provides or uses statement in one line, even if only one interfaces is required.  If the module does not have interfaces in the provides or uses block, that block may be omitted.

Default Event Handlers
Default event handlers are used when a module provides an interface that signals events, but no external module handles the event.  An empty default statement should have the following form:

default event void MyInterface.mySignal() {
}

default event void MyInterface.myOtherSignal() {
}




White Space
Blank Lines
Blank lines improve readability by setting off sections of code that are logically related.

Two blank lines should always be used between sections of a source file.

One blank line should be used in the following circumstances:

Between functions
Between the local variables in a method and its first statement
Before a block or single-line comment.
Between logical sections inside a function to improve readability, including between the statements in an if-block and its subsequent else-statement(s).

Blank Spaces
Blank spaces can optionally be used between a keyword and its arguments, as long as the consistency is kept up throughout the code.


// This is ok:
while (true) {
  ...
}

// This is ok:
while(true) {
  ...
}

Blank spaces should not be used between a function name and its opening parenthesis.  

A blank space should appear after all commas in argument lists.

A blank space should appear before the asterisk on a pointer, not between the asterisk and the variable name:

void *buffer;

All binary operators except ‘.’ Should be separated from their operands by spaces.  Blank spaces should never separate unary operators such as unary minus, increment (“++”), and decrement (“--”) from their operands.  Example:

a += c + d;
a = (a + b) / (c * d);

while ((d++) < 10) {
  n++;
}

printSize(“size is “ + foo + “\n”);

The expression in a for statement should be separated by blank spaces.  Example:

for(expr1; expr2; expr3) {
  ...
}

Casts should be followed by a blank space.  Examples:

myFunction((char) aLetter, (uint8_t *) x);
myFunction((char) (cp + 5), ((int) (i + 3))
    + 1);

Naming Conventions
Naming conventions make programs more understandable by making them easier to read.  They can also give information about the function of the identifier – for example, whether it’s a constant, variable, interface, or command – which can be helpful in understanding the code.

Configurations
Configurations should be nouns, in mixed case, with the first letter of each internal word capitalized.  Try to keep your configuration names simple and descriptive.  Use whole words – avoid using acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as Crc or Rssi).  Avoid using two capital letters side-by-side.  Configuration names end with a capital C, for configuration:

configuration MyComponentC {
  ...
}
implementation {
  ...
}

Modules
Each module should ideally have a corresponding configuration and main interface it implements.  Module names should be chosen and capitalized like configuration names.  Module names should end with an M, for module:

module MyComponentM {
  ...
}
implementation {
  ...
}

Interfaces
Interface names should be capitalized like configuration and module names:

interface MyConfig {
  ...
}

interface RssiMeasurement {
  ...
}

Commands, Events, Tasks, and Functions
These should be verbs, in mixed case with the first letter lowercase and the first letter of each internal word capitalized.  Names should not contain an underscore _.

command void measureRssi();

event void batteryDepleted();

task void run();

uint64_t getCrc64();

Variables
Variable names should start with a lower case letter, with each internal word capitalized.  

Variable names should be short, yet meaningful.  The choice of a variable name should be mnemonic – that is, designed to indicate to the casual observer the intent of its use.  One-character, abbreviated, or cryptic variable names should avoided except for temporary “throwaway” variables.  Common names for temporary variables are i, j, k, m, and n for integers; c, d, and e for characters.

The use of underscores in variable names is allowed, but should be avoided – especially between words in a variable.  Some programmers prefer global variables to start with an underscore (“_”) which is allowed, as long as the variable name itself is descriptive and the consistency is upheld throughout the source file.

uint8_t minTime;

Constants
The names of variables declared constants and of ANSI constants should be all uppercase with words separated by underscores (“_”).  ANSI constants should be avoided, for ease of debugging.

const uint8_t MIN_TIME = 4;

#ifndef MAX_TOS_MSGS
#define MAX_TOS_MSGS 4
#endif

enum {
  ONE_SECOND = 1024,
};

typedefs and structs
The first letter of each component of the name of the type definition is capitalized.  Structs should be defined so the largest variable types are placed at the top, and the smallest variable types are placed at the bottom.  Arrays should be located at the very bottom of the struct.  Structs setup in this manner will avoid misaligned bytes and endian conversion problems due to word-aligned microcontrollers like the MSP430.

Doc comments can be provided above each variable to describe what the variable does, but style should be carried throughout.  Example:

typedef struct CalendarInfo {
  uint64_t timestamp;
  uint32_t utcStart;
  uint16_t uid;
  char type;
  uint8_t state;
  bool on;
  uint8_t data[16];
} CalendarInfo;


/**
 * Payload type from my custom component
 */
typedef struct AM_MYCUSTOMMSG {
  /** The current frame count */
  uint32_t frame;

  /** Data */
  uint8_t data[TOSH_DATA_LENGTH – 4];

} CalendarInfo;
Programming Practices
Provides and Uses Blocks
Each line within provides and uses blocks should be an interface.  Do not share access to an individual commands or events in provides or uses.

// INCORRECT:
configuration MyAppC {
  provides {
    interface StdControl;
    command result_t randomCommand();
    event void misplacedEvent();
  }
 
  uses {
    interface MyInterface;
  }
}


// CORRECT:
configuration MyAppC {
  provides {
    interface StdControl;
    interface MyInterface;
  }
 
  uses {
    interface AnotherInterface;
  }
}


// CORRECT:
configuration MyAppC {
  provides {
    interface StdControl;
  }
}

If a module provides a parameterized interface, the name of the unique identifier for the parameterized interface should be the name of the interface itself:

MyAppM.Timer -> TimerC.Timer[unique(“Timer”)];

Constants
Numerical constants (literals) should not be coded directly, except for -1, 0, and 1, which can appear in a for loop as counter values.  Use enum’s to hold arbitrary literals.

Variable Assignments
Avoid assigning several variables to the same value in a single statement.  It is hard to read.  Example:

// AVOID:
myStruct.var1 = myCharVar = ‘c’;

Do not use the assignment operator in a place where it can be easily confused with the equality operator.  Example:

if(c++ = d++) {
  ...
}


should be written as

if((c++ = d++) != 0) {
  ...
}
Do not use embedded assignments in an attempt to improve run-time performance.  This is the job of the compiler.  Example:

// AVOID:
d = (a
 = b + c) + r;

should be written as

a = b + c;
d = a + r;

Miscellaneous Practices
10.4.1 Parentheses
It is generally a good idea to use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems.  Even if the operator precedence seems clear to you, it might not be to others – you shouldn’t assume that other programmers know precedence as well as you do.

// AVOID:
if(a == b && c == d) {

// CORRECT:
if((a == b) && (c == d)) {

10.4.2  Returning Values
Try to make the structure of your program match the intent.  Example:

if(booleanExpression) {
  return true;

} else {
  return false;
}

should instead be written as:

return booleanExpression;

10.4.3  Ternary Expressions
Ternary expressions ( (condition) ? true : false ) should be avoided.  A standard if-statement should be used in place of ternary expressions.

Wiring
Wiring in configuration files should always be written with the arrow pointing to the right.  Whenever possible, do not reiterate the interface being connected on the module that provides the interface. Example:

Module.Uses1 -> ProvidesModule;
Module.Uses2 -> ProvidesModule;

Keep all the wiring for an individual module in the same location, and separate the wiring of that module from the other modules with blank lines:

Module1.Uses1 -> Module2;
Module1.Uses2 -> Module3;
Module1.Uses3 -> Module2.DifferentNameInterface;

Module2.Uses4 -> Module3;

Module3.Uses5 -> Module1;
Module3.IntName -> Module2.IntName[unique(“IntName”)];
StdControl
The StdControl (or equivalent) interface should be used to initialize and start each component.  Do not allow a module to initialize other modules through the implementation of the module.  All modules should be initialized through proper wiring of the StdControl interface.  When possible, construct the application to direct the StdControl interface to each configuration and module exactly once.  Usually, the highest level of configuration where a module could be accessed will wire the StdControl interface.  For example, a Timer interface is used everywhere, but is most likely used at the top-most application level; therefore, StdControl should be wired to the Timer component at the highest application level.  An interface specific to a component, say FlashBridge, would only be used up to the top of the file system; therefore, the top level file system configuration file would take care of wiring StdControl to the FlashBridge.
Because of aggressive inlining, the compiler may duplicate code in ROM if the StdControl command is wired to a configuration or module multiple times. 

If the wiring of StdControl is ambiguous, make a comment about the assumptions of how StdControl (and any other required interface) should be wired at the top of your configuration file.

Commands
Commands should only return a result_t value when it is possible for the command to begin a split-phase task, or if it is possible for the command to not go through.  If the result_t return event will never be checked, the command should return void instead.

// Correct:
command result_t ReadFlash.start() {
  if(busy) {
    return FAIL;
  }

  post readFlash();
  return SUCCESS;
}


// INCORRECT: no possible way to fail, why return a result?
command result_t ByteWriter.setChar(char c) {
  myChar = c;
  return SUCCESS;
}


// CORRECT:
command void ByteWriter.setChar(char c) {
  myChar = c;
}

Events
Events should always return void.  Never create an event that returns a result_t or any other value.  If the event is handled or implemented in more than one location, there is no way to tell which result is the correct result to accept.  If the module needs results from several components after signaling an event, it should provide a command that will take the results and combine them properly.

// AVOID:
event result_t fired();

// CORRECT:
event void fired();

Examples
Interface Example

/*
 * Copyright Info
 */

/**
 * This is an example of an interface.  This is
 * where the overall description would go.
 *
 * @author Author Name
 */

interface MyModule {

  /**   * Command description
   * @param param1 description of param1
   * @return description of return value
   */
  command uint8_t doSomething(uint16_t param);

  /**
   * Another command 
   */
  command void doSomethingElse();


  /**
   * An event. Note how this is separated by
   * an extra blank line from the commands
   */
  event void doneSomething();

  /**
   * Another event
   */
  event void formatted();

}

Configuration Example

/*
 * Copyright Info
 */

/**
 * This is an example of a configuration.  This is
 * where the overall component description would go.
 * Note how the wiring of each module is done with
 * blank lines separating them from the other modules.
 * Do not intermingle the wiring of modules.  It makes
 * the wiring difficult to understand.
 *
 * @author Author Name
 */

includes MyModule;

configuration MyModuleC {
  provides {
    interface MyModule;
    interface StdControl;
  }
}

implementation {
  components MyModuleM, AnotherModuleC;
  components ExampleOne, ExampleTwo;
  components ExampleThree,
             ExampleFour,
             ExampleFive,
             ExampleSix;

  MyModule = MyModuleM;
  StdControl = MyModuleM;

  MyModuleM.InterfaceC -> AnotherModuleC;

  ExampleOne.InterfaceOne -> ExampleTwo;
  ExampleOne.InterfaceTwo -> ExampleThree;
  ExampleOne.InterfaceFour -> MyModuleM;

  ExampleTwo.InterfaceFive -> ExampleFour;
  ExampleTwo.InterfaceSix -> ExampleSix.DifferentName;
}

Module Example

/*
 * Copyright Info
 */

/**
 * This is an example of a module.  This is where
 * the overall component description would go.
 * The comments separating each section and set
 * of interfaces is a /**  */ comment with
 * 15 asterisks on each side.
 * 
 * @author Author Name
 */

includes MyModule;

module MyModuleM {
  provides {
    interface StdControl; 
    interface MyModule; 
  }

  uses {
    interface InterfaceC;
  }
}

implementation {

  /** The count maintained by this example */
  uint8_t count;

  /**
   * Constants for my module
   */
  enum {
    CONSTANT_VARIABLE,
    MAX_SIZE = 5,
  };

  /***************** Prototypes ****************/
  /** Optional one-line description of the task/function */
  task void myTask();

  void myFunction();


  /***************** StdControl Commands ****************/
  command result_t StdControl.init() {
    count = 0;
    return SUCCESS;
  }

  command result_t StdControl.start() {
    ...
    return SUCCESS;
  }

  command result_t StdControl.stop() {
    return SUCCESS;
  }


  /***************** MyModule Commands ****************/
  /**   * Command description – same comment as found
   * in the original interface, with any extra
   * details about the implementation.
   * Note that all of ‘MyModule’ commands would go
   * in this location.
   *
   * @param param1 description of param1
   * @return description of return value
   */
  command uint8_t MyModule.doSomething(uint16_t param) {
    // Do something here
    ...
  }

  
  /***************** InterfaceC Events ****************/
  /**
   * Description of the event, from the interface
   */
  event void InterfaceC.processed() {
    ...
  }


  /***************** Tasks ****************/
  /**   * Optional description of the task, if needed
   */
  task void myTask() {
    ...
  }


  /***************** Functions ****************/
  /**
   * Optional description of the function, if needed
   */
  void myFunction() {
    if(!call InterfaceC.isOpen()) {
      ...
    }
  }
}
hÅH…
hU|Ì
l
l
l
l
l
l
l
×










































































&
&
&



&F

&
-"
l
l
l
&F

&
l
'
&
&
&
&F
&F
&F
&
&F

&
&F
&
&F
5

&

&
&

&
&
&
&
&
&
&
e
&
e
&
&F	

&
&
&F	
&

&



&F
&F
&F
&F

&F




&F

&


&F



&F

&F
&F
&F
•
&F
&F$

&
”
•
&F$
™
&F$
™




l








]
Œ

‘





]
Œ

‘

@ 0










s
s
s
s
s
s
s
s
@ 0




















”
Æÿÿÿÿÿÿÿÿÿ
tV„ÿÿÿÿÿÿÿÿÿ
C Ž0ÿÿÿÿÿÿÿÿÿ
Ö5Ü0–ÿÿÿÿÿÿÿÿÿ
²ÜÁÿÿÿÿÿÿÿÿÿ
¦N¼7B²ÿÿÿÿÿÿÿÿÿ















„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(








„XüÆ
^„°
`„Xüo(

















„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(















„XüÆ
^„°
`„Xüo(









„XüÆ
^„°
`„Xüo(








„XüÆ
^„°
`„Xüo(












„XüÆ
^„°
`„Xü‡h




„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(

„XüÆ
^„°
`„Xüo(
























„XüÆ
^„°
`„Xüo(
¦N
C

Ö5
q€B

‡












More information about the Tinyos-contrib-commits mailing list