Você está na página 1de 11

NanoStack Reference

NanoStack Reference

v1.0.1

2007 Sensinode Ltd.

1/11

NanoStack Reference

Table of Contents
1 Introduction.....................................................................................................................................................3 2 NanoStack Configuration Files.......................................................................................................................3 2.1 FreeRTOS configuration.........................................................................................................................3 2.2 NanoStack configuration.........................................................................................................................3 3 Starting NanoStack.........................................................................................................................................5 4 NanoStack Communication Basics.................................................................................................................7 4.1 Creating a socket.....................................................................................................................................7 4.2 Ports.........................................................................................................................................................7 4.3 Address structure ....................................................................................................................................7 4.4 Receiving.................................................................................................................................................8 4.5 Sending....................................................................................................................................................8 4.6 Control Sockets.......................................................................................................................................9 4.7 Notes on application design....................................................................................................................9 5 NanoStack Run-time Configuration.............................................................................................................10 5.1 Function APIs........................................................................................................................................10 5.2 Routing..................................................................................................................................................10 5.3 Routing errors........................................................................................................................................11 6 Port-specific notes.........................................................................................................................................11 6.1 GCC compiler notes..............................................................................................................................11 6.2 SDCC compiler notes............................................................................................................................11

v1.0.1

2007 Sensinode Ltd.

2/11

NanoStack Reference

Introduction

1 Introduction
This document is intended to help NanoStack software developer in writing applications and getting NanoStack configured to suit their application requirements. This reference covers NanoStack configuration, FreeRTOS configuration, stack initialization, socket API usage, and run-time configuration. Please also see the Doxygen reference in /NanoStack/Docs for more detailed information on function parameters and data structures.

2 NanoStack Configuration Files


NanoStack has multiple layers of configuration: compile-time preprocessor definitions can be divided into two categories: FreeRTOS configuration and NanoStack protocol stack configuration. NanoStack also has multiple APIs for the run-time configuration of drivers and protocol modules.

2.1

FreeRTOS configuration

The FreeRTOS configuration file is named FreeRTOSConfig.h. It is located in the application directory e.g. /NanoStack/Example/micro_example_u100. Table 1: FreeRTOS relevant parameters.
Parameter configCPU_CLOCK_HZ configTICK_RATE_HZ configMINIMAL_STACK_SIZE configTOTAL_HEAP_SIZE Description System clock frequency in Hz System timer tick resolution in Hz Stack minimum size in bytes Size of dynamic memory area Options Default Platform dep. 1000 200 RAM size - 2kB

2.2

NanoStack configuration

The NanoStack configuration file is named app.rules, and is located in the application directory along with Makefile, FreeRTOSConfig.h etc. The app.rules file has defaults for all parameters except MAC_MODE, which always must be set. Binary options use 1 for on and 0 for off. Table 2: General configuration parameters.
Parameter STACK_BUFFERS_MAX STACK_BUFFERS_MIN SOCKETS_MAX HAVE_DEBUG HAVE_EVENT_TIMERS HAVE_POWERSAVE Description Upper limit for allocated buffers Minimum amount of allocated buffers Amount of available sockets Enable debugging library on UART Number of available event timers Turn on automatic powersave features (experimental) Options Max 10 Min 4 6 4 4 1 8 0 Default

v1.0.1

2007 Sensinode Ltd.

3/11

NanoStack Reference

NanoStack Configuration Files

Table 3: Module selection.


Parameter HAVE_CUDP HAVE_ICMP HAVE_CIPV6 HAVE_ROUTING HAVE_RF_802_15_4 HAVE_SSI HAVE_802_15_4_RAW Description Enable compressed UDP module Enable ICMP module Enable compressed IPV6 module Enable routing functionality Enable full functionality MAC Enable SSI sensor data server Enable minimal MAC (CCA only) Options 1 1 1 1 1 0 0 Default

Table 4: MAC module configuration parameters.


Parameter MAC_MODE RX_ON_WHEN_IDLE Description Set the mode of the 802.15.4 MAC Receiver never shuts down Options 0 = Ad-hoc mode 1 = Beacon RFD mode 2 = Beacon FFD mode Default 0

1 7

MAX_PENDING_BUFFER_COUNT Size of the MAC pending queue

Table 5: Routing module configuration parameters.


Parameter MAX_NEIGHBOR_COUNT MAX_ROUTE_INFO_COUNT Description Maximum nr. of children/neighbors Maximum nr. of stored routes Options 20 15 Default

Table 6: RF driver configuration parameters.


Parameter RF_DEFAULT_POWER RF_DEFAULT_CHANNEL HAVE_RF_LED Description Transmit power (in percent) Default RF channel Enable RF activity led Options 0 - 100 11 - 25 0 = off U100: 1 = green, 2 = red 100 18 0 Default

Table 7: UART driver configuration parameters.


Parameter HAVE_UARTx UARTx_RX_BUFFER_SIZE UARTx_TX_BUFFER_SIZE Description Support for UART x enabled Size of UART x receive buffer Size of UART x transmit buffer Options Default platform dep. 8 128

Table 8: Debugging library configuration.


v1.0.1
2007 Sensinode Ltd.

4/11

NanoStack Reference
Parameter DEBUG_RX_LEN DEBUG_TX_LEN Description Size of UART RX buffer Size of UART TX buffer

NanoStack Configuration Files


Options 8 64 Default

Table 9: Debugging selection.


Parameter HAVE_DEBUG Description Turn on debugging, must be enabled to use other debug options below Protocol core tracing Socket API tracing CIPV6 protocol tracing CIPV6 control socket tracing CUDP Protocol tracing Routing module tracing Network manager tracing MAC module tracing RF driver tracing Limited RF driver trace: RX only 1-wire driver tracing Options 0 Default

STACK_DEBUG SOCKET_DEBUG CIPV6_DEBUG CIPV6_CONTROL_DEBUG CUDP_DEBUG ROUTING_DEBUG NWK_CONFIG_DEBUG RF_802_15_4_DEBUG CC2420_DEBUG CC2420_DEBUG_RSSI B1W_DEBUG

0 0 0 0 0 0 0 0 0 0 0

Selecting many tracing sections simultaneously may affect system timings and severely compromise correct protocol functionality.

3 Starting NanoStack
An application based on NanoStack is started in 4 phases:

HW initialization Creating initial tasks Starting the FreeRTOS scheduler Starting NanoStack

HW initialization is performed by the bus_init() function, which is included in /Platform under the correct platform directory. The function typically contains only essential initialization steps, such as configuring the system clock source. Additional initialization may be performed in the main() function in cases where the application does not do all its initialization via driver modules. If the debug library is used, the debug_init(speed) call should be done right after calling bus_init() in the main() function. The main() function is also responsible of initial application task creation. Platform hardware initialization:
bus_init();

Example of task creation:


static void application_task( void *pvParameters );

Inside the main() function:


v1.0.1
2007 Sensinode Ltd.

5/11

NanoStack Reference

Starting NanoStack
NULL );

xTaskCreate( application_task, "App", <stack size>, <task parameter>, <task priority>,

Starting scheduler in the main() function:


vTaskStartScheduler();

In this phase execution continues in your application task (or the task with the highest priority, in case you created multiple tasks in main() function). NanoStack is started by the stack_start() function. This function initializes all resources required by the protocol stack core and the RF driver. No NanoStack API calls may be called before the stack_start() function has been executed. The function must be executed inside the application task. If NULL is passed as a parameter stack_start() uses default values for the current MAC mode defined in app.rules.
typedef struct { log_dev_type_t uint8_t uint8_t uint8_t uint8_t uint8_t uint8_t } stack_init_t; type; channel; pan_id[2]; short_address[2]; use_sw_mac; mac_address[8]; pending_ttl_time;

The type field specifies one of the following operation modes: AD_HOC_DEVICE BEACON_ENABLE_CLIENT BEACON_ENABLE_COORDINATOR BEACON_ENABLE_GATEWAY Device in ad-hoc mode A client in a coordinated network Network coordinator/router Gateway device, gathering data from coordinators

Valid values for channel are 11-26. The PAN ID and MAC address fields are used to setdevice address for coordinator and gateway devices. Set use_sw_mac to 0 and the MAC address is set automatically, or 1 to set it manually. The pending_ttl_time specifies the time a coordinator will store a data packet for a child device. The time is in multiples of 15 seconds, the default value is 5. A task, such as the application task, runs in an endless for loop. It is important that this for loop spends most of its time sleeping so that the scheduler can handle other tasks. Sleeping occurs when blocking on a queue or semaphore (socket_read() blocks on a queue), or by explicitly calling vTaskDelay() or vTaskDelayUntil(). Simple example skeleton of an application task:
static void application_task( void *pvParameters ) { socket_t *app_socket; sockaddr_t sa; buffer_t *buf = 0; debug_init(115200); /*debug functions may be called now*/ debug("Start NanoStack.\r\n"); if(stack_start(NULL)==START_SUCCESS) { debug("Start OK.\r\n"); } app_socket = socket(MODULE_CUDP, 0); sa.port = 253; socket_bind(app_socket, &sa); /*listen to port 253*/ for(;;) { /*wait for packets, timeout 1 second*/ buf = socket_read(app_socket, 1000); if (buf) { /*data received*/

v1.0.1

2007 Sensinode Ltd.

6/11

NanoStack Reference
...process data... socket_buffer_free(buf); } } }

Starting NanoStack

/*free buffer*/

See /Examples/micro_beacon_gateway for an example of manually setting all the start_init structure for use with a FFD device acting as a gateway.

4 NanoStack Communication Basics


NanoStack communication features are accessed via the Socket API. The example application code in Chapter 3 contains an example of a basic receiver application.

4.1

Creating a socket

A socket is created by the socket() function call which has 2 parameters: 1. Protocol type: what protocol this socket is going to use, e.g. MODULE_CUDP 2. Handler function: if you prefer implementing reception in a callback fashion, insert your handler function pointer here. A null pointer means callback is not used. After the socket has been created, you can specify additional protocol multiplexer (port number) by calling socket_bind(), again with 2 parameters: 1. Pointer to your socket (returned by call to socket() previously) 2. Pointer to a sockaddr_t struct, containing the port number in the port field If you are about to use your socket only for sending or expect your peer to respond with your address (most client-type applications), calling bind is not necessary. A random port will be allocated when first packet is sent.

4.2

Ports

Port ranges in NanoStack are used identically to ports in any TCP/IP stack. When using UDP in uncompressed mode, the 16-bit port range from 5-65536. When using UDP in compressed mode ports are restricted to a 4-bit range from 61616-61631 as in the 6LoWPAN specification. Ports 1-4 are reserved for use with control sockets.

4.3

Address structure

The address structure used by the Socket API is called sockaddr_t and includes the following fields:
typedef struct { addrtype_t address_t uint16_t } sockaddr_t; addr_type; address; port; /*!< Type of address */ /*!< Source or destination address */ /*!< Source or destination port */

The addr_type field defines what kind of address in included, and port field is defined above. The following address types are defined. ADDR_NONE ADDR_802_15_4_LONG ADDR_802_15_4_SHORT
v1.0.1

No address 64-bit 802.15.4 address 16-bit 802.15.4 address


2007 Sensinode Ltd.

7/11

NanoStack Reference

NanoStack Communication Basics

ADDR_802_15_4_PAN_SHORT ADDR_802_15_4_PAN_LONG ADDR_SHORT ADDR_PAN ADDR_DATA ADDR_BROADCAST ADDR_COORDINATOR

16-bit PAN with 16-bit 802.15.4 address 16-bit PAN with 64-bit 802.15.4 address 8-bit address in octet 0 16-bit PAN-id Attribute-based data-centric query Broadcast address Coordinator address only for Beacon enable mode

4.4

Receiving

Receiving data from a socket has 2 options: 1. using socket_read() 2. using a callback function, given as a parameter to socket() The socket_read() function returns a pointer to a buffer_t structure (data received) or 0 (timed out). The function has 2 parameters: 1. Pointer to your socket (returned by call to socket() previously) 2. Timeout value in milliseconds (a value of 0 can be used to poll the socket) All received buffers must be freed using socket_buffer_free() once the data has been handled. The buffer may also be re-used for sending data: in this case the buffer must not be freed. In case of callback reception, the user has to implement a handler function with the following return type and parameters:
portCHAR my_handler_function_name(buffer_t *buffer)

example of a callback function:


portCHAR my_handler_function_name(buffer_t *buffer) { /* parse and handle received data here */ <your application code> /* free buffer */ socket_buffer_free(buffer); return pdTRUE; }

The handler function should never block. The function is called from the protocol stack task: if the function blocks, the protocol core (and drivers) will be halted for that time.

4.5

Sending

Data is sent via the socket using socket_sendto(). The function returns pdTRUE on success and pdFALSE on failure. In case of failure, the application may opt to resend the buffer (after some delay, preferably) or just free the buffer. In case of success, the buffer will be freed by the RF driver after packet has been sent. Do not try to free the buffer yourself after re-sending. Example of sending:
buffer_t *buffer = socket_buffer_get(socket, timeout); int retry = 0; sockaddr_t dest_address; if (buffer) {

v1.0.1

2007 Sensinode Ltd.

8/11

NanoStack Reference

NanoStack Communication Basics

<code fills in the address data> <code creates the data packet> while ( (socket_sendto(socket, &dest_address, buffer) == pdFALSE) && (retry++ < 3)) { vTaskDelay(5); /*wait for 5 ticks on failure*/ } if (retry >= 3) socket_buffer_free(buffer); /*sending failed*/

4.6

Control Sockets

Sockets are also used to send and receive control messages from protocol modules in NanoStack. A control socket uses the module identifier (e.g. MODULE_ICMP) to send or receive messages with a module. In addition ports (1-4) are reserved for use with control sockets. Use a matching socket type and port define with control sockets. Control socket port definitions: ICMP_CTRL_PORT CUDP_CTRL_PORT CIPV6_CTRL_PORT MAC_CTRL_PORT 1 2 3 4

Modules with a control interface: MODULE_ICMP, MODULE_CUDP, MODULE_CIPV6, MODULE_MAC Example of binding to a control socket:
sockaddr_t control_address = { ADDR_NONE, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, ICMP_CTRL_PORT }; task() { ... socket_t *icmp_control=0; icmp_control = socket(MODULE_ICMP, 0); if (icmp_control) { if (socket_bind(icmp_control, &control_address)!=pdTRUE) debug("Bind fail icmp.\r\n"); } }

4.7

Notes on application design

Do not declare too many variables inside the application main function. Since these variables will be present always during program execution, it is easier to estimate RAM usage when variables are declared as static variables. This reduces the application stack size and the linker will give you an error if you run out of RAM. In this case you can adjust the size of the dynamic RAM area to give room for your static variables. This significantly simplifies application development. Another way of simplifying RAM management is to allocate buffers using socket_buffer_get() for larger data structures that are only required temporarily.

v1.0.1

2007 Sensinode Ltd.

9/11

NanoStack Reference

NanoStack Communication Basics

A task, such as the application task, runs in an endless for loop. It is important that this for loop spends most of its time sleeping so that the scheduler can handle other tasks. Sleeping occurs when blocking on a queue or semaphore (socket_read() blocks on a queue), or by explicitly calling vTaskDelay() or vTaskDelayUntil().

5 NanoStack Run-time Configuration


Many NanoStack modules also have a run-time configuration API. These functions are mostly for upper layer modules that require control over lower layer parameters. Functions may also be called directly by application, but the application developer should be aware of protocol modules' functionality to avoid conflicting parameter setups.

5.1

Function APIs

Controlling 6loWPAN header compression options: For cIPv6:


cipv6_compress_mode(mode) (1=on, 0=off)

For cUDP:
cudp_compress_mode(mode) (1=on, 0=off)

Compression is enabled by default for both IPv6 and UDP modules, and does not need to be manually set. MAC module configuration API: Get coordinator address (on client)
portCHAR get_coord_address(sockaddr_t *address)

RF driver configuration API: Transmit power, power in per cent (0-100)


int8_t rf_power_set(uint8_t new_power)

Channel setup, valid channels 11-26


int8_t rf_channel_set(uint8_t channel)

Turn off receiver (radio shutdown):


portCHAR rf_rx_disable(void)

Turn receiver back on:


portCHAR rf_rx_enable(void)

Set MAC address:


void rf_set_address(sockaddr_t *address)

5.2

Routing

The cIPv6 NanoMesh routing module is configured using a control socket. Control socket message types are defined in control_message.h. A control socket is created by calling socket(MODULE_CIPV6, handler). The socket has the following message types:

v1.0.1

2007 Sensinode Ltd.

10/11

NanoStack Reference

NanoStack Run-time Configuration

Router_DISCOVER: initiates gateway discovery procedure Router_DISCOVER_RESPONSE: this contains the results of gateway discovery Router_ADVERT_SEND: the gateway advertises itself to the network using this message.

5.3

Routing errors

The ICMP module is responsible for handling routing errors: a control socket is created by calling socket(MODULE_ICMP, handler). The socket has the following message types: ICMP_ERROR: the ID field contains the error type. The ID BROKEN_LINK returns the address of the peer that could not be reached. In the current implementation the packet data is lost: the coordinator should proxy the data for 200 milliseconds to allow resending. This will be fixed in the next release: the error packet will contain also the application data within the data field of the ICMP message. This data may then be re-sent by the application.

6 Port-specific notes
This chapter lists options available in only specific compiler/platform environments.

6.1

GCC compiler notes

1. All GCC ports should be configured so that the compiler generates re-entrant functions. Otherwise any code that is called from multiple tasks will eventually fail.

6.2

SDCC compiler notes

1. Because of SDCC and 8051 architecture limitations, the heavy use of pointers in FreeRTOS makes the code size generated by SDCC large. 64 kB of ROM is available for use on NanoModule N120, which currently allows for basic ad-hoc MAC and 6lowpan/UDP/ICMP modules to be used with ample space for application code. A patch for using all 128 kB with SDCC is also now available, although not part of the core releases yet. This issue will be fixed with a new scheduler in NanoStack v2.x. 2. Interrupts need special consideration when using SDCC. When creating an interrupt in the application, you must create a header file included in the application (main.c) with a prototype of the interrupt. Otherwise the interrupt vector isn't registered with SDCC.

v1.0.1

2007 Sensinode Ltd.

11/11