Transcript
Page 1: Sensinode Reference Nanostack v1.0.1

NanoStack Reference

NanoStack Reference

v1.0.1 ©2007 Sensinode Ltd. 1/11

Page 2: Sensinode Reference Nanostack v1.0.1

NanoStack Reference

Table of Contents1 Introduction.....................................................................................................................................................32 NanoStack Configuration Files.......................................................................................................................3

2.1 FreeRTOS configuration.........................................................................................................................32.2 NanoStack configuration.........................................................................................................................3

3 Starting NanoStack.........................................................................................................................................54 NanoStack Communication Basics.................................................................................................................7

4.1 Creating a socket.....................................................................................................................................74.2 Ports.........................................................................................................................................................74.3 Address structure ....................................................................................................................................74.4 Receiving.................................................................................................................................................84.5 Sending....................................................................................................................................................84.6 Control Sockets.......................................................................................................................................94.7 Notes on application design....................................................................................................................9

5 NanoStack Run-time Configuration.............................................................................................................105.1 Function APIs........................................................................................................................................105.2 Routing..................................................................................................................................................105.3 Routing errors........................................................................................................................................11

6 Port-specific notes.........................................................................................................................................116.1 GCC compiler notes..............................................................................................................................116.2 SDCC compiler notes............................................................................................................................11

v1.0.1 ©2007 Sensinode Ltd. 2/11

Page 3: Sensinode Reference Nanostack v1.0.1

NanoStack Reference Introduction

1 IntroductionThis 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 FilesNanoStack 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 configurationThe 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 Description Options Default

configCPU_CLOCK_HZ System clock frequency in Hz Platform dep.

configTICK_RATE_HZ System timer tick resolution in Hz 1000

configMINIMAL_STACK_SIZE Stack minimum size in bytes 200

configTOTAL_HEAP_SIZE Size of dynamic memory area RAM size - 2kB

2.2 NanoStack configurationThe 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 Description Options Default

STACK_BUFFERS_MAX Upper limit for allocated buffers Max 10 6

STACK_BUFFERS_MIN Minimum amount of allocated buffers

Min 4 4

SOCKETS_MAX Amount of available sockets 4

HAVE_DEBUG Enable debugging library on UART 1

HAVE_EVENT_TIMERS Number of available event timers 8

HAVE_POWERSAVE Turn on automatic powersave features (experimental)

0

v1.0.1 ©2007 Sensinode Ltd. 3/11

Page 4: Sensinode Reference Nanostack v1.0.1

NanoStack Reference NanoStack Configuration Files

Table 3: Module selection.Parameter Description Options Default

HAVE_CUDP Enable compressed UDP module 1

HAVE_ICMP Enable ICMP module 1

HAVE_CIPV6 Enable compressed IPV6 module 1

HAVE_ROUTING Enable routing functionality 1

HAVE_RF_802_15_4 Enable full functionality MAC 1

HAVE_SSI Enable SSI sensor data server 0

HAVE_802_15_4_RAW Enable minimal MAC (CCA only) 0

Table 4: MAC module configuration parameters.Parameter Description Options Default

MAC_MODE Set the mode of the 802.15.4 MAC

0 = Ad-hoc mode1 = Beacon RFD mode2 = Beacon FFD mode

0

RX_ON_WHEN_IDLE Receiver never shuts down 1

MAX_PENDING_BUFFER_COUNT Size of the MAC pending queue 7

Table 5: Routing module configuration parameters.Parameter Description Options Default

MAX_NEIGHBOR_COUNT Maximum nr. of children/neighbors 20

MAX_ROUTE_INFO_COUNT Maximum nr. of stored routes 15

Table 6: RF driver configuration parameters.Parameter Description Options Default

RF_DEFAULT_POWER Transmit power (in percent) 0 - 100 100

RF_DEFAULT_CHANNEL Default RF channel 11 - 25 18

HAVE_RF_LED Enable RF activity led 0 = offU100: 1 = green, 2 = red

0

Table 7: UART driver configuration parameters.Parameter Description Options Default

HAVE_UARTx Support for UART x enabled platform dep.

UARTx_RX_BUFFER_SIZE Size of UART x receive buffer 8

UARTx_TX_BUFFER_SIZE Size of UART x transmit buffer 128

Table 8: Debugging library configuration.

v1.0.1 ©2007 Sensinode Ltd. 4/11

Page 5: Sensinode Reference Nanostack v1.0.1

NanoStack Reference NanoStack Configuration Files

Parameter Description Options DefaultDEBUG_RX_LEN Size of UART RX buffer 8DEBUG_TX_LEN Size of UART TX buffer 64

Table 9: Debugging selection.Parameter Description Options Default

HAVE_DEBUG Turn on debugging, must be enabled to use other debug options below

0

STACK_DEBUG Protocol core tracing 0SOCKET_DEBUG Socket API tracing 0CIPV6_DEBUG CIPV6 protocol tracing 0CIPV6_CONTROL_DEBUG CIPV6 control socket tracing 0CUDP_DEBUG CUDP Protocol tracing 0ROUTING_DEBUG Routing module tracing 0NWK_CONFIG_DEBUG Network manager tracing 0RF_802_15_4_DEBUG MAC module tracing 0CC2420_DEBUG RF driver tracing 0CC2420_DEBUG_RSSI Limited RF driver trace: RX only 0B1W_DEBUG 1-wire driver tracing 0

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

3 Starting NanoStackAn 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

Page 6: Sensinode Reference Nanostack v1.0.1

NanoStack Reference Starting NanoStack

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

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 type; uint8_t channel; uint8_t pan_id[2]; uint8_t short_address[2]; uint8_t use_sw_mac; uint8_t mac_address[8]; uint8_t pending_ttl_time;} stack_init_t;

The type field specifies one of the following operation modes:AD_HOC_DEVICE Device in ad-hoc modeBEACON_ENABLE_CLIENT A client in a coordinated networkBEACON_ENABLE_COORDINATOR Network coordinator/routerBEACON_ENABLE_GATEWAY Gateway device, gathering data from

coordinatorsValid values for channel are 11-26. The PAN ID and MAC address fields are used to set device 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

Page 7: Sensinode Reference Nanostack v1.0.1

NanoStack Reference Starting NanoStack

...process data...socket_buffer_free(buf); /*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 BasicsNanoStack 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 socketA 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_CUDP2. 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 PortsPort 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 addr_type; /*!< Type of address */ address_t address; /*!< Source or destination address */ uint16_t port; /*!< Source or destination port */} sockaddr_t;

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 No addressADDR_802_15_4_LONG 64-bit 802.15.4 addressADDR_802_15_4_SHORT 16-bit 802.15.4 address

v1.0.1 ©2007 Sensinode Ltd. 7/11

Page 8: Sensinode Reference Nanostack v1.0.1

NanoStack Reference NanoStack Communication Basics

ADDR_802_15_4_PAN_SHORT 16-bit PAN with 16-bit 802.15.4 addressADDR_802_15_4_PAN_LONG 16-bit PAN with 64-bit 802.15.4 addressADDR_SHORT 8-bit address in octet 0ADDR_PAN 16-bit PAN-idADDR_DATA Attribute-based data-centric queryADDR_BROADCAST Broadcast addressADDR_COORDINATOR Coordinator address only for Beacon enable mode

4.4 ReceivingReceiving 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 SendingData 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

Page 9: Sensinode Reference Nanostack v1.0.1

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 SocketsSockets 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 1CUDP_CTRL_PORT 2CIPV6_CTRL_PORT 3MAC_CTRL_PORT 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 designDo 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

Page 10: Sensinode Reference Nanostack v1.0.1

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 ConfigurationMany 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 APIsControlling 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 RoutingThe 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

Page 11: Sensinode Reference Nanostack v1.0.1

NanoStack Reference NanoStack Run-time Configuration

Router_DISCOVER: initiates gateway discovery procedureRouter_DISCOVER_RESPONSE: this contains the results of gateway discoveryRouter_ADVERT_SEND: the gateway advertises itself to the network using this message.

5.3 Routing errorsThe 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 notesThis chapter lists options available in only specific compiler/platform environments.

6.1 GCC compiler notes1. 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 notes1. 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