Thread: NCP

The Thread NCP sample demonstrates the usage of OpenThread’s Network Co-Processor (NCP) architecture inside the Zephyr environment.

The sample is based on Zephyr’s OpenThread NCP sample. However, it customizes Zephyr’s sample to the NCS requirements (for example, by increasing the stack size dedicated for the user application), and also extends it with several features:

  • Increased mbedTLS heap size.

  • Lowered main stack size to increase user application space.

  • No obsolete configuration options.

  • Vendor hooks for NCP allowing User to extend handled properties by its own, customized functionalities.

This sample supports optional Vendor hooks extension and logging extension, which can be turned on or off independently. See Activating sample extensions for details.

Overview

The sample demonstrates using an NCP target on the MCU to communicate with Userspace WPAN Network Daemon (wpantund) on Unix-like operating system. According to the NCP architecture, the MCU part needs to cooperate with user higher layer process to establish the complete full stack application. The sample shows how to set connection between NCP and wpantund.

This sample comes with the full set of OpenThread functionalities enabled (CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER).

Vendor hooks extension

The vendor hook feature extension allows you to define your own commands and properties for the Spinel protocol, and extend the standard set used in communication with NCP. Thanks to this feature, you can add new custom functionalities and manage them from host device by using serial interface - in the same way as the default functionalities.

For more detailed information about the vendor hooks feature and host device configuration, see Vendor hooks. For information about how to enable the vendor hook feature for this sample, see Activating vendor hook feature.

Logging extension

This sample by default uses Spinel logging backend, which allows sending log messages to the host device using the Spinel protocol. This feature is very useful, because it does not require having separate interfaces to communicate with NCP through the Spinel protocol and collect log messages. Moreover, selecting the Spinel logging backend (by setting CONFIG_LOG_BACKEND_SPINEL) does not exclude using another backend like UART or RTT at the same time.

By default, the log levels for all modules are set to critical to not engage the microprocessor in unnecessary activities. To make the solution flexible, you can change independently the log levels for your modules, for the whole Zephyr system, and for OpenThread. Use the overlay-logging.conf overlay file as reference for this purpose.

Requirements

The sample supports the following development kits for testing the network status:

Hardware platforms

PCA

Board name

Build target

nRF52840 DK

PCA10056

nrf52840dk_nrf52840

nrf52840dk_nrf52840

nRF52833 DK

PCA10010

nrf52833dk_nrf52833

nrf52833dk_nrf52833

To test the sample, you need at least one development kit NCP board. Additional NCP boards can be used for the optional testing of network joining.

Moreover, the sample requires a Userspace higher layer process running on user’s device in order to communicate with the MCU NCP part. This sample uses wpantund as reference.

User interface

All the interactions with the application are handled using serial communication.

For the interaction with the application, this sample uses wpantund process with wpanctl commands. It is also possible to communicate with NCP board using PySpinel commands.

You can use your own application instead of wpantund and PySpinel provided that it supports the spinel communication protocol.

Note

Thread samples have Hardware Flow Control mechanism enabled by default in serial communication. When enabled, it allows devices to manage transmission by informing each other about their current state, and ensures more reliable connection in high-speed communication scenarios. In addition, the NCP sample by default reconfigures the baud rate to 1000000 bit/s.

Building and running

Make sure to enable the OpenThread stack before building and testing this sample. See Working with Thread for more information.

This sample can be found under samples/openthread/ncp in the nRF Connect SDK folder structure.

See Building and programming a sample application for information about how to build and program the application.

Activating sample extensions

To activate the optional extensions supported by this sample, modify OVERLAY_CONFIG in the following manner:

  • For the vendor hooks feature support, set overlay-vendor_hook.conf. See Activating vendor hook feature for more information.

  • For the logging variant that presents how to change log levels of specific modules, set overlay-logging.conf.

See Providing CMake options for instructions on how to add this option. For more information about using configuration overlay files, see Important Build System Variables in the Zephyr documentation.

Activating vendor hook feature

For this sample, handling of extension commands and properties is done through the vendor hook .cpp file, which is dynamically attached to the NCP component during the compilation.

To enable the feature:

  1. Provide the implementation of this file.

  2. Insert information about the file location in the CONFIG_OPENTHREAD_NCP_VENDOR_HOOK_SOURCE field. This field is located in the overlay configuration file (see overlay-vendor_hook.conf). The inserted path must be relative to the NCP sample directory.

The NCP sample provides the vendor hook user_vendor_hook.cpp file in the src directory that demonstrates the proposed implementation of handler methods. You can either:

  • Use the provided user_vendor_hook.cpp file.

  • Provide your own implementation and replace the CONFIG_OPENTHREAD_NCP_VENDOR_HOOK_SOURCE option value in the overlay file with the path to your file.

For information about how to test the vendor hook feature, see Testing vendor hooks after configuration.

Testing

After building the sample and programming it to your development kit, test it by performing the following steps:

  1. Connect the NCP board’s SEGGER J-Link USB port to the PC USB port with an USB cable.

  2. Get the board’s serial port name (e.g. /dev/ttyACM0).

  3. Run and configure wpantund and wpanctl as described in Configuring wpantund.

  4. In the wpanctl shell, run the following command to check the NCP board state:

    wpanctl:leader_if> status
    

    The output will look similar to the following:

    leader_if => [
      "NCP:State" => "offline"
      "Daemon:Enabled" => true
      "NCP:Version" => "OPENTHREAD/gde3f05d8; NONE; Jul  7 2020 10:04:51"
      "Daemon:Version" => "0.08.00d (0.07.01-343-g3f10844; Jul  2 2020 09:07:40)"
      "Config:NCP:DriverName" => "spinel"
      "NCP:HardwareAddress" => [E8F947748F493141]
    ]
    

    This output means that NCP is offline.

  5. In the wpanctl shell, run the following command to set up a Thread network:

    wpanctl:leader_if> form "My_OpenThread_network"
    

    The output will look similar to the following:

    Forming WPAN "New_network" as node type "router"
    Successfully formed!
    

    This output means that the network was formed successfully.

  6. In the wpanctl shell, run the status command again to see that “My_OpenThread_network” was formed by NCP:

    wpanctl:leader_if> status
    

The final output will be similar to the following:

leader_if => [
  "NCP:State" => "associated"
  "Daemon:Enabled" => true
  "NCP:Version" => "OPENTHREAD/gde3f05d8; NONE; Jul  7 2020 10:04:51"
  "Daemon:Version" => "0.08.00d (0.07.01-343-g3f10844; Jul  2 2020 09:07:40)"
  "Config:NCP:DriverName" => "spinel"
  "NCP:HardwareAddress" => [E8F947748F493141]
  "NCP:Channel" => 26
  "Network:NodeType" => "leader"
  "Network:Name" => "My_OpenThread_network"
  "Network:XPANID" => 0x048CA9024CD7D40F
  "Network:PANID" => 0xDB92
  "IPv6:MeshLocalAddress" => "fd04:8ca9:24c:0:ebb8:4ef3:d96:c4bd"
  "IPv6:MeshLocalPrefix" => "fd04:8ca9:24c::/64"
  "com.nestlabs.internal:Network:AllowingJoin" => false
]

This output means that you have successfully formed the Thread network.

Testing network joining with more NCP boards

Optionally, if you are using more than one NCP board, you can test the network joining process by completing the following steps:

  1. Connect the second NCP board’s SEGGER J-Link USB port to the PC USB port with an USB cable.

  2. Get the board’s serial port name.

  3. Open a shell and run another wpantund process for the second board by using the following command:

    wpantund -I <network_interface_name_board2> -s <serial_port_name_board2> -b <baudrate>
    

    For baudrate, use value 1000000. For serial_port_name_board2, use the value from the previous step. For network_interface_name_board2, use a name of your choice. In this testing procedure, this will be joiner_if.

  4. Open another shell and run another wpanctl process for the second board by using following command:

    wpanctl -I joiner_if
    
  5. In the wpanctl shell, run the following command to check the NCP board state:

    wpanctl:joiner_if> status
    

    The output will look similar to the following:

    joiner_if => [
       "NCP:State" => "offline"
       "Daemon:Enabled" => true
       "NCP:Version" => "OPENTHREAD/gde3f05d8; NONE; Jul  7 2020 10:04:51"
       "Daemon:Version" => "0.08.00d (0.07.01-343-g3f10844; Jul  2 2020 09:07:40)"
       "Config:NCP:DriverName" => "spinel"
       "NCP:HardwareAddress" => [E8F947748F493141]
    ]
    

    This output means that NCP is offline.

  6. In the wpanctl shell of the first NCP board, run the following command to get the network key from the leader NCP board:

    wpanctl:leader_if> get Network:Key
    

    The output will look similar to the following:

    Network:Key = [2429EFAF21421AE3CB30B9204016EDC9]
    
  7. Copy the network key form the output and set it on the second (joiner) NCP board by running the following command in the second board’s wpanctl shell:

    wpanctl:joiner_if> set Network:Key 2429EFAF21421AE3CB30B9204016EDC9
    
  8. In the second board’s wpanctl shell, run the following command to scan your neighborhood and find the network formed with the leader NCP board:

    wpanctl:joiner_if> scan
    

    The output will look similar to the following:

      | Joinable | NetworkName             | PAN ID | Ch | XPanID           | HWAddr           | RSSI
    --+----------+-------------------------+--------+----+------------------+------------------+------
    1 |       NO | "OpenThread"            | 0xABCD | 11 | DEAD00BEEF00CAFE | 621757E184CEF8E5 |  -82
    2 |       NO | "My_OpenThread_network" | 0xF54B | 13 | 77969855F947758D | 62AAC622CB3ACD9F |  -34
    

    The first column is the network ID number. For the network formed for this testing procedure, the ID equals 2.

  9. In the second board’s wpanctl shell, run the following command with the network ID as variable to join your joiner NCP board to the network:

    wpanctl:joiner_if> join 2
    

    The output will look similar to the following:

    Joining WPAN "My_OpenThread_network" as node type "end-device", channel:13, panid:0xF54B, xpanid:0x77969855F947758D [scanned network index 2]
    Successfully Joined!
    

This output means that the joiner board node has successfully joined the network.

Dependencies

This sample uses the following Zephyr libraries: