Sensinode Reference Nanostack v1.0.1

  • Published on
    05-Mar-2015

  • View
    69

  • Download
    2

Transcript

NanoStack ReferenceNanoStack Referencev1.0.12007 Sensinode Ltd.1/11NanoStack ReferenceTable of Contents1 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............................................................................................................................11v1.0.12007 Sensinode Ltd.2/11NanoStack ReferenceIntroduction1 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.1FreeRTOS 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 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 - 2kB2.2NanoStack 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 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 Defaultv1.0.12007 Sensinode Ltd.3/11NanoStack ReferenceNanoStack Configuration FilesTable 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 DefaultTable 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 01 7MAX_PENDING_BUFFER_COUNT Size of the MAC pending queueTable 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 DefaultTable 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 DefaultTable 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 128Table 8: Debugging library configuration.v1.0.12007 Sensinode Ltd.4/11NanoStack ReferenceParameter DEBUG_RX_LEN DEBUG_TX_LEN Description Size of UART RX buffer Size of UART TX bufferNanoStack Configuration FilesOptions 8 64 DefaultTable 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 DefaultSTACK_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_DEBUG0 0 0 0 0 0 0 0 0 0 0Selecting 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 NanoStackHW 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.12007 Sensinode Ltd.5/11NanoStack ReferenceStarting NanoStackNULL );xTaskCreate( application_task, "App", , , ,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 coordinatorsValid 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.12007 Sensinode Ltd.6/11NanoStack 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 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.1Creating 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_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.2PortsPort 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.3Address structureThe 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_SHORTv1.0.1No address 64-bit 802.15.4 address 16-bit 802.15.4 address2007 Sensinode Ltd.7/11NanoStack ReferenceNanoStack Communication BasicsADDR_802_15_4_PAN_SHORT ADDR_802_15_4_PAN_LONG ADDR_SHORT ADDR_PAN ADDR_DATA ADDR_BROADCAST ADDR_COORDINATOR16-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 mode4.4ReceivingReceiving 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 */ /* 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.5SendingData 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.12007 Sensinode Ltd.8/11NanoStack ReferenceNanoStack Communication Basics} 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.6Control 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 CUDP_CTRL_PORT CIPV6_CTRL_PORT MAC_CTRL_PORT 1 2 3 4Modules 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.7Notes 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.12007 Sensinode Ltd.9/11NanoStack ReferenceNanoStack Communication BasicsA 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.1Function 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-26int8_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.2RoutingThe 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.12007 Sensinode Ltd.10/11NanoStack ReferenceNanoStack Run-time ConfigurationRouter_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.3Routing 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.1GCC 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.2SDCC 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.12007 Sensinode Ltd.11/11