Thread: Co-processor
The Thread Co-processor sample demonstrates how to implement OpenThread’s Co-processor designs inside the Zephyr environment. Depending on the configuration, the sample uses the Network co-processor (NCP) architecture or Radio co-processor (RCP) architecture.
The sample is based on Zephyr’s OpenThread Co-Processor sample. However, it customizes Zephyr’s sample to fulfill the nRF Connect SDK requirements (for example, by increasing the stack size dedicated for the user application), and also extends it with features such as:
Increased Mbed TLS heap size.
Lowered main stack size to increase user application space.
No obsolete configuration options.
Vendor hooks for co-processor architecture allowing users to extend handled properties by their own, customized functionalities.
This sample supports optional Vendor hooks extension and logging extension, which can be turned on or off independently. See Configuration files for details.
Requirements
The sample supports the following development kits for testing the network status:
Hardware platforms |
PCA |
Board name |
Build target |
---|---|---|---|
PCA10056 |
|
||
PCA10059 |
|
||
PCA10100 |
|
||
nRF21540 DK |
PCA10112 |
|
To test the sample, you need at least one development kit. You can use additional development kits programmed with the Co-processor sample for the optional testing of network joining.
Moreover, the sample requires a Userspace higher layer process running on your device to communicate with the MCU co-processor part. This sample uses wpantund as reference.
Overview
The sample demonstrates using a co-processor target on the MCU to communicate with Userspace WPAN Network Daemon (wpantund) on Unix-like operating system. According to the co-processor architecture, the MCU part must cooperate with user higher layer process to establish the complete full stack application. The sample shows how to set up the connection between the co-processor 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 the co-processor. Thanks to this feature, you can add new custom functionalities and manage them from a 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 the vendor hook feature.
Logging extension
By default, this sample uses Spinel logging backend for sending log messages to the host device using the Spinel protocol.
This is a useful feature, because it does not require separate interfaces to communicate with the co-processor through the Spinel protocol and collect log messages.
Moreover, using 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.
FEM support
You can add support for the nRF21540 front-end module to this sample by using one of the following options, depending on your hardware:
Build the sample for one board that contains the nRF21540 FEM, such as nrf21540dk_nrf52840.
Manually create a devicetree overlay file that describes how FEM is connected to the nRF5 SoC in your device. See Set devicetree overlays for different ways of adding the overlay file.
Provide nRF21540 FEM capabilities by using a shield, for example the nRF21540 EK shield that is available in the nRF Connect SDK. In this case, build the project for a board connected to the shield you are using with an appropriate variable included in the build command. This variable instructs the build system to append the appropriate devicetree overlay file. For example, to build the sample from the command line for an nRF52833 DK with the nRF21540 EK attached, use the following command within the sample directory:
west build -b nrf52833dk_nrf52833 -- -DSHIELD=nrf21540_ek
This command builds the application firmware. See Programming nRF21540 EK for information about how to program when you are using a board with a network core, for example nRF5340 DK.
Each of these options adds the description of the nRF21540 FEM to the devicetree. See Working with RF front-end modules for more information about FEM in the nRF Connect SDK.
To add support for other front-end modules, add the respective devicetree file entries to the board devicetree file or the devicetree overlay file.
User interface
All the interactions with the application are handled using serial communication.
You can interact with the sample through wpantund, using wpanctl
commands.
If you use the RCP architecture (see CONFIG_OPENTHREAD_COPROCESSOR_RCP
), you can alternatively use ot-daemon
or ot-cli
with commands listed in OpenThread CLI Reference.
See OpenThread POSIX applications for more information.
Both NCP and RCP support communication with the development kit using Pyspinel commands.
You can also use your own application, provided that it supports the Spinel communication protocol.
Note
This sample has 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 Co-processor sample reconfigures the baud rate to 1000000 bit/s by default.
Configuration
See Configuring your application for information about how to permanently or temporarily change the configuration.
Check and configure the following library options that are used by the sample:
CONFIG_OPENTHREAD_COPROCESSOR_NCP
- Selects the NCP architecture for the sample. This is the default.CONFIG_OPENTHREAD_COPROCESSOR_RCP
- Selects the RCP architecture for the sample.
Configuration files
The sample provides predefined configuration files for typical use cases, and to activate sample extensions. You can find the configuration files in the root directory of the sample.
Specify the corresponding file names in the OVERLAY_CONFIG option when building. 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.
The following configuration files are available:
overlay-vendor_hook.conf
- Enables the vendor hooks extension. It also specifies the source file to use. See Activating the vendor hook feature for more information.overlay-logging.conf
- Enables the logging extension. This file configures different log levels for the sample, the Zephyr system, and OpenThread.overlay-rcp.conf
- Enables the RCP architecture. This file configures the sample to use the RCP architecture instead of the NCP architecture.overlay-minimal_rcp.conf
- Enables a minimal configuration that reduces the code size and RAM usage. This file enables the RCP architecture with basic functionality and optimizes stacks and buffer sizes. For more information, see Memory footprint optimization.overlay-usb.conf
- Enables emulating a serial port over USB for Spinel communication with the host. Additionally, you need to set DTC_OVERLAY_FILE tousb.overlay
.
Building and running
Make sure to enable the OpenThread stack before building and testing this sample. See Thread for more information.
This sample can be found under samples/openthread/coprocessor
in the nRF Connect SDK folder structure.
See Building and programming an application for information about how to build and program the application.
Activating the vendor hook feature
The vendor hook .cpp
file handles the extension commands and properties.
It is attached to the Co-processor sample during the linking.
To enable the feature:
Provide the implementation of this file.
Insert information about the file location in the
CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE
field in theoverlay-vendor_hook.conf
file. The inserted path must be relative to the Co-processor sample directory.
The Co-processor sample provides the vendor hook user_vendor_hook.cpp
file in the src
directory.
It demonstrates the proposed implementation of handler methods.
You can choose one of the following two options:
Use the provided
user_vendor_hook.cpp
file.Provide your own implementation and replace the
CONFIG_OPENTHREAD_COPROCESSOR_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, complete the following steps to test it:
Connect the development kit’s SEGGER J-Link USB port to the PC USB port with a USB cable.
Get the kit’s serial port name (for example,
/dev/ttyACM0
).Run and configure wpantund and wpanctl as described in Configuring wpantund.
In the wpanctl shell, run the following command to check the kit 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.
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.
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 kits
If you are using more than one kit, you can test the network joining process by completing the following steps:
Connect the second kit’s SEGGER J-Link USB port to the PC USB port with a USB cable.
Get the kit’s serial port name.
Open a shell and run another wpantund process for the second kit as described in Configuring wpantund. Make sure to use the correct serial port name for the second kit (for example,
/dev/ACM1
) and a different network interface name (for example,joiner_if
).To open another shell and run another wpanctl process for the second kit, use the following command:
wpanctl -I joiner_if
In the wpanctl shell, run the following command to check the kit 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.
In the wpanctl shell of the first kit, run the following command to get the network key from the leader kit:
wpanctl:leader_if> get Network:Key
The output will look similar to the following:
Network:Key = [2429EFAF21421AE3CB30B9204016EDC9]
To copy the network key from the output and set it on the second (joiner) kit, run the following command in the second kit’s wpanctl shell:
wpanctl:joiner_if> set Network:Key 2429EFAF21421AE3CB30B9204016EDC9
In the second kit’s wpanctl shell, run the following command to scan your neighborhood and find the network formed with the leader kit:
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
.In the second kit’s wpanctl shell, run the following command with the network ID as variable to join your joiner kit 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 kit node has successfully joined the network.
Dependencies
This sample uses the following Zephyr libraries:
-
include/kernel.h
-
include/logging/log.h