Thread: CLI

The Thread CLI sample demonstrates how to send commands to a Thread device using the OpenThread Command Line Interface (CLI). The CLI is integrated into the Zephyr shell.

Requirements

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

Hardware platforms

PCA

Board name

Board target

nRF54L15 DK

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l15/cpuapp

nRF54H20 DK

PCA10175

nrf54h20dk

nrf54h20dk/nrf54h20/cpuapp

nRF5340 DK

PCA10095

nrf5340dk

nrf5340dk/nrf5340/cpuapp/ns nrf5340dk/nrf5340/cpuapp

nRF52840 Dongle

PCA10059

nrf52840dongle

nrf52840dongle/nrf52840

nRF52840 DK

PCA10056

nrf52840dk

nrf52840dk/nrf52840

nRF21540 DK

PCA10112

nrf21540dk

nrf21540dk/nrf52840

Optionally, you can use one or more compatible development kits programmed with this sample or another Thread sample for testing communication or diagnostics and Configuring on-mesh Thread commissioning.

You need nRF Sniffer for 802.15.4 to observe messages sent from the router to the leader kit when Testing Thread 1.2 and Thread 1.3 features.

When built for a board target with the */ns variant, the sample is configured to compile and run as a non-secure application with Cortex-M Security Extensions enabled. Therefore, it automatically includes Trusted Firmware-M that prepares the required peripherals and secure services to be available for the application.

Overview

The sample demonstrates the usage of commands listed in OpenThread CLI Reference. OpenThread CLI is integrated into the system shell accessible over serial connection. To indicate a Thread command, the ot keyword needs to precede the command.

The number of commands you can test depends on the application configuration. The CLI sample comes with the full set of OpenThread functionalities enabled (CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER). Thread 1.2 version is selected as default.

If used alone, the sample allows you to test the network status. It is recommended to use at least two development kits running the same sample for testing the communication.

Certification tests with CLI sample

You can use the Thread CLI sample to run certification tests. See Thread certification for information on how to use this sample on Thread Certification Test Harness.

User interface

All interactions with the application are handled using serial communication. See OpenThread CLI Reference for the list of available serial commands.

Diagnostic module

By default, the CLI sample comes with the CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER feature set enabled, which allows you to use Zephyr’s diagnostic module with its diag commands. Use these commands to manually check hardware-related functionalities without running a Thread network. For example, to ensure radio communication is working when adding a new functionality or during the manufacturing process. See Testing diagnostic module section for an example.

Note

If you disable the CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER feature set, you can enable the diagnostic module with the CONFIG_OPENTHREAD_DIAG Kconfig option.

Rebooting to bootloader

For the nrf52840dongle/nrf52840 board target, the device can reboot to bootloader by triggering a GPIO pin. To enable this behavior, enable the CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO Kconfig option and configure the Devicetree overlay in the boards/nrf52840dongle_nrf52840.overlay file. For this sample, the bootloader-gpios property in the openthread_config node is pre-configured for the P0.19 pin, which is connected to the RESET pin on the nRF52840 Dongle. This functionality is not enabled by other commands, such as factoryreset, as they can only trigger a software reset, skipping the bootloader.

To reboot to the bootloader, run the following command on the device:

uart:~$ ot reset bootloader

Configuration

See Configuring and building for information about how to permanently or temporarily change the configuration.

Snippets

The sample provides predefined Snippets for typical use cases, and to activate sample extensions. You can find the snippets in the snippets directory of the sample.

Specify the corresponding snippet names in the cli_SNIPPET CMake option. For more information about using snippets, see Using Snippets in the Zephyr documentation.

The following snippets are available:

  • usb - Enables USB transport support.

  • logging - Enables logging using RTT. For additional options, refer to RTT logging.

  • debug - Enables debugging the Thread sample with GDB thread awareness.

  • ci - Disables boot banner and shell prompt.

  • multiprotocol - Enables Bluetooth LE support in this sample. Not compatible with the tcat snippet.

    Note

    When building with the multiprotocol snippet for the nrf5340dk/nrf5340/cpuapp board target, set the FILE_SUFFIX CMake option to ble. See Custom configurations and Providing CMake options for more information.

  • tcat - Enables support for Thread commissioning over authenticated TLS.

    Note

    When building with the tcat snippet for the nrf5340dk/nrf5340/cpuapp board target, set the FILE_SUFFIX CMake option to ble. See Custom configurations and Providing CMake options for more information.

    Not compatible with the multiprotocol snippet. For using TCAT, refer to the Thread Commissioning Over Authenticated TLS page.

  • tcp - Enables experimental TCP support in this sample.

  • low_power - Enables low power consumption mode in this sample.

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 Developing with 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, for example SHIELD=nrf21540ek. This variable instructs the build system to append the appropriate devicetree overlay file.

    To build the sample in the nRF Connect for VS Code IDE for an nRF52840 DK with the nRF21540 EK attached, add the shield variable in the build configuration’s Extra CMake arguments and rebuild the build configuration. For example: -DSHIELD=nrf21540ek.

    See nRF Connect for VS Code extension pack documentation for more information.

    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 Developing with 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.

Memory optimization

See Memory footprint optimization for actions and configuration options you can use to optimize the memory footprint of the sample.

Serial transport

The Thread CLI sample supports UART and USB CDC ACM as serial transports. By default, it uses USB CDC ACM transport for nrf52840dongle/nrf52840, and UART transport for other board targets. To switch to USB transport on targets that use UART by default, activate the USB snippet.

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/cli in the nRF Connect SDK folder structure.

When built as firmware image for a board target with the */ns variant, the sample has Cortex-M Security Extensions (CMSE) enabled and separates the firmware between Non-Secure Processing Environment (NSPE) and Secure Processing Environment (SPE). Because of this, it automatically includes the Trusted Firmware-M (TF-M). To read more about CMSE, see Processing environments.

To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.

Note

When building repository applications in the SDK repositories, building with sysbuild is enabled by default. If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.

To update the OpenThread libraries provided by nrfxlib, use the following commands:

west build -b nrf52840dk/nrf52840
west build -d build/cli -t install_openthread_libraries

Testing

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

  1. Turn on the development kit.

  2. Open a serial port connection to the kit using a terminal emulator that supports VT100/ANSI escape characters (for example, nRF Connect Serial Terminal). See Testing and optimization for the required settings and steps.

    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.

  3. Configure the required Thread network parameters with the ot channel, ot panid, and ot networkkey commands. Make sure to use the same parameters for all nodes that you add to the network. The following example uses the default OpenThread parameters:

    uart:~$ ot channel 11
    Done
    uart:~$ ot panid 0xabcd
    Done
    uart:~$ ot networkkey 00112233445566778899aabbccddeeff
    Done
    
  4. Enable the Thread network with the ot ifconfig up and ot thread start commands:

    uart:~$ ot ifconfig up
    Done
    uart:~$ ot thread start
    Done
    
  5. Invoke some of the OpenThread commands:

    1. Test the state of the Thread network with the ot state command. For example:

      uart:~$ ot state
      leader
      Done
      
    2. Get the Thread network name with the ot networkname command. For example:

      uart:~$ ot networkname
      OpenThread
      Done
      
    3. Get the IP addresses of the current Thread network with the ot ipaddr command. For example:

      uart:~$ ot ipaddr
      fdde:ad00:beef:0:0:ff:fe00:800
      fdde:ad00:beef:0:3102:d00b:5cbe:a61
      fe80:0:0:0:8467:5746:a29f:1196
      Done
      

Testing with multiple kits

If you are using more than one development kit for testing the CLI sample, you can also complete additional testing procedures.

Note

The following testing procedures assume you are using two development kits.

Testing communication between kits

To test communication between kits, complete the following steps:

  1. Make sure both development kits are programmed with the CLI sample.

  2. Turn on the developments kits.

  3. Connect to both kits with a terminal emulator that supports VT100/ANSI escape characters (for example, nRF Connect Serial Terminal). See Testing and optimization for the required settings and steps.

    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.

  4. Configure the required Thread network parameters with the ot channel, ot panid, and ot networkkey commands. Make sure to use the same parameters for all nodes that you add to the network. The following example uses the default OpenThread parameters:

    uart:~$ ot channel 11
    Done
    uart:~$ ot panid 0xabcd
    Done
    uart:~$ ot networkkey 00112233445566778899aabbccddeeff
    Done
    
  5. Enable the Thread network with the ot ifconfig up and ot thread start commands:

    uart:~$ ot ifconfig up
    Done
    uart:~$ ot thread start
    Done
    
  6. Test communication between the kits with the following command:

    ot ping ip_address_of_the_first_kit

    For example:

    uart:~$ ot ping fdde:ad00:beef:0:3102:d00b:5cbe:a61
    16 bytes from fdde:ad00:beef:0:3102:d00b:5cbe:a61: icmp_seq=3 hlim=64 time=23ms
    1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/av
    Done
    
Testing diagnostic module

To test diagnostic commands, complete the following steps:

  1. Make sure both development kits are programmed with the CLI sample.

  2. Turn on the developments kits.

  3. Connect to both kits with a terminal emulator that supports VT100/ANSI escape characters (for example, nRF Connect Serial Terminal). See Testing and optimization for the required settings and steps.

    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..

  4. Make sure that the diagnostic module is enabled and configured with proper radio channel and transmission power. Run the following commands on both devices:

    uart:~$ ot diag start
    start diagnostics mode
    status 0x00
    Done
    uart:~$ ot diag channel 11
    set channel to 11
    status 0x00
    Done
    uart:~$ ot diag power 0
    set tx power to 0 dBm
    status 0x00
    Done
    
  5. Transmit a fixed number of packets with the given length from one of the devices. For example, to transmit 20 packets that contain 100 B of random data, run the following command:

    uart:~$ ot diag send 20 100
    sending 0x14 packet(s), length 0x64
    status 0x00
    Done
    
  6. To read the radio statistics on the other device, run the following command:

    uart:~$ ot diag stats
    received packets: 20
    sent packets: 0
    first received packet: rssi=-29, lqi=255
    last received packet: rssi=-30, lqi=255
    Done
    
Testing Thread 1.2 and Thread 1.3 features

To test the Thread 1.2 and Thread 1.3 features, complete the following steps:

  1. Enable the extra options CONFIG_OPENTHREAD_BORDER_ROUTER, CONFIG_OPENTHREAD_BACKBONE_ROUTER and CONFIG_OPENTHREAD_SRP_SERVER when building the CLI sample.

  2. Make sure both development kits are programmed with the CLI sample.

  3. Turn on the developments kits.

  4. Connect to both kits with a terminal emulator that supports VT100/ANSI escape characters (for example, nRF Connect Serial Terminal). See Testing and optimization for the required settings and steps.

  5. Configure the required Thread network parameters with the ot channel, ot panid, and ot networkkey commands. Make sure to use the same parameters for all nodes that you add to the network. The following example uses the default OpenThread parameters:

    uart:~$ ot channel 11
    Done
    uart:~$ ot panid 0xabcd
    Done
    uart:~$ ot networkkey 00112233445566778899aabbccddeeff
    Done
    
  6. Enable the Thread network with the ot ifconfig up and ot thread start commands:

    uart:~$ ot ifconfig up
    Done
    uart:~$ ot thread start
    Done
    
  7. Test the state of the Thread network with the ot state command to see which kit is the leader:

    uart:~$ ot state
    leader
    Done
    
  8. On the leader kit, enable the Backbone Router function:

    uart:~$ ot bbr enable
    Done
    
  9. On the leader kit, configure the Domain prefix:

    uart:~$ ot prefix add fd00:7d03:7d03:7d03::/64 prosD med
    Done
    uart:~$ ot netdata register
    Done
    
  10. On the router kit, display the autoconfigured Domain Unicast Address and set another one manually:

    uart:~$ ot ipaddr
    fd00:7d03:7d03:7d03:ee2d:eed:4b59:2736
    fdde:ad00:beef:0:0:ff:fe00:c400
    fdde:ad00:beef:0:e0fc:dc28:1d12:8c2
    fe80:0:0:0:acbd:53bf:1461:a861
    Done
    uart:~$ ot dua iid 0004000300020001
    Done
    uart:~$ ot ipaddr
    fd00:7d03:7d03:7d03:4:3:2:1
    fdde:ad00:beef:0:0:ff:fe00:c400
    fdde:ad00:beef:0:e0fc:dc28:1d12:8c2
    fe80:0:0:0:acbd:53bf:1461:a861
    Done
    
  11. On the router kit, configure a multicast address with a scope greater than realm-local:

    uart:~$ ot ipmaddr add ff04::1
    Done
    uart:~$ ot ipmaddr
    ff04:0:0:0:0:0:0:1
    ff33:40:fdde:ad00:beef:0:0:1
    ff32:40:fdde:ad00:beef:0:0:1
    ff02:0:0:0:0:0:0:2
    ff03:0:0:0:0:0:0:2
    ff02:0:0:0:0:0:0:1
    ff03:0:0:0:0:0:0:1
    ff03:0:0:0:0:0:0:fc
    Done
    

    The router kit sends an MLR.req message and a DUA.req message to the leader kit (Backbone Router). Use the nRF Sniffer for 802.15.4 to observe this.

  12. On the leader kit, list the IPv6 addresses:

    uart:~$ ot ipaddr
    fd00:7d03:7d03:7d03:84c9:572d:be24:cbe
    fdde:ad00:beef:0:0:ff:fe00:fc10
    fdde:ad00:beef:0:0:ff:fe00:fc38
    fdde:ad00:beef:0:0:ff:fe00:fc00
    fdde:ad00:beef:0:0:ff:fe00:7000
    fdde:ad00:beef:0:a318:bf4f:b9c6:5f7d
    fe80:0:0:0:10b1:93ea:c0ee:eeb7
    

    Note down the link-local address. You must use this address when sending Link Metrics commands from the router kit to the leader kit.

    The following steps use the address fe80:0:0:0:10b1:93ea:c0ee:eeb7. Replace it with the link-local address of your leader kit in all commands.

  13. Run the following commands on the router kit:

    1. Reattach the router kit as Sleepy End Device (SED) with a polling period of three seconds:

      uart:~$ ot pollperiod 3000
      Done
      uart:~$ ot mode -
      Done
      
    2. Perform a Link Metrics query (Single Probe):

      uart:~$ ot linkmetrics query fe80:0:0:0:10b1:93ea:c0ee:eeb7 single qmr
      Done
      Received Link Metrics Report from: fe80:0:0:0:10b1:93ea:c0ee:eeb7
      - LQI: 220 (Exponential Moving Average)
      - Margin: 60 (dB) (Exponential Moving Average)
      - RSSI: -40 (dBm) (Exponential Moving Average)
      
    3. Send a Link Metrics Management Request to configure a Forward Tracking Series:

      uart:~$ ot linkmetrics mgmt fe80:0:0:0:10b1:93ea:c0ee:eeb7 forward 1 dra pqmr
      Done
      Received Link Metrics Management Response from: fe80:0:0:0:10b1:93ea:c0ee:eeb7
      Status: Success
      
    4. Send an MLE Link Probe message to the peer:

      uart:~$ ot linkmetrics probe fe80:0:0:0:10b1:93ea:c0ee:eeb7 1 10
      Done
      
    5. Perform a Link Metrics query (Forward Tracking Series):

      uart:~$ ot linkmetrics query fe80:0:0:0:10b1:93ea:c0ee:eeb7 forward 1
      Done
      Received Link Metrics Report from: fe80:0:0:0:10b1:93ea:c0ee:eeb7
      - PDU Counter: 13 (Count/Summation)
      - LQI: 212 (Exponential Moving Average)
      - Margin: 60 (dB) (Exponential Moving Average)
      - RSSI: -40 (dBm) (Exponential Moving Average)
      
    6. Send a Link Metrics Management Request to register an Enhanced ACK-based Probing:

      uart:~$ ot linkmetrics mgmt fe80:0:0:0:10b1:93ea:c0ee:eeb7 enhanced-ack register qm
      Done
      Received Link Metrics data in Enh Ack from neighbor, short address:0xa400 , extended address:12b193eac0eeeeb7
      - LQI: 255 (Exponential Moving Average)
      - Margin: 68 (dB) (Exponential Moving Average)
      
    7. Send a Link Metrics Management Request to clear an Enhanced ACK-based Probing:

      uart:~$ ot linkmetrics mgmt fe80:0:0:0:10b1:93ea:c0ee:eeb7 enhanced-ack clear
      Done
      Received Link Metrics Management Response from: fe80:0:0:0:10b1:93ea:c0ee:eeb7
      Status: Success
      
  14. Verify the Coordinated Sampled Listening (CSL) functionality.

    The following steps use the address fe80:0:0:0:acbd:53bf:1461:a861. Replace it with the link-local address of your router kit in all commands.

    1. Send an ICMPv6 Echo Request from the leader kit to link-local address of the router kit:

      uart:~$ ot ping fe80:0:0:0:acbd:53bf:1461:a861
      16 bytes from fe80:0:0:0:acbd:53bf:1461:a861: icmp_seq=2 hlim=64 time=2494ms
      1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/a
      Done
      

      Observe that there is a long latency, up to 3000 ms, on the reply. This is due to the indirect transmission mechanism based on data polling.

    2. Stop frequent polling on the router kit (now SED) by configuring a polling period of 240 seconds:

      uart:~$ ot pollperiod 240000
      Done
      
    3. Enable a CSL Receiver on the router kit (now SED) by configuring a CSL period of 0.5 seconds:

      uart:~$ ot csl period 500000
      Done
      
    4. Send an ICMPv6 Echo Request from the leader kit to the link-local address of the router kit:

      uart:~$ ot ping fe80:0:0:0:acbd:53bf:1461:a861
      16 bytes from fe80:0:0:0:acbd:53bf:1461:a861: icmp_seq=3 hlim=64 time=421ms
      1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/a
      Done
      

      Observe that the reply latency is reduced to a value below 500 ms. The reduction occurs because the transmission from the leader is performed using CSL, based on the CSL Information Elements sent by the CSL Receiver.

  15. Verify the Service Registration Protocol (SRP) functionality.

    1. On the leader kit, enable the SRP Server function:

      uart:~$ ot srp server enable
      Done
      
    2. Register an _ipps._tcp service on the router kit (now SED):

      uart:~$ ot srp client host name my-host
      Done
      uart:~$ ot srp client host address fdde:ad00:beef:0:e0fc:dc28:1d12:8c2
      Done
      uart:~$ ot srp client service add my-service _ipps._tcp 12345
      Done
      uart:~$ ot srp client autostart enable
      Done
      
    3. On the router kit (now SED), check that the host and service have been successfully registered:

      uart:~$ ot srp client host
      name:"my-host", state:Registered, addrs:[fdde:ad00:beef:0:e0fc:dc28:1d12:8c2]
      Done
      
    4. Check the host and service on the leader kit:

      uart:~$ ot srp server host
      my-host.default.service.arpa.
         deleted: false
         addresses: [fdde:ad00:beef:0:e0fc:dc28:1d12:8c2]
      Done
      uart:~$ ot srp server service
      my-service._ipps._tcp.default.service.arpa.
         deleted: false
         subtypes: (null)
         port: 12345
         priority: 0
         weight: 0
         ttl: 7200
         TXT: []
         host: my-host.default.service.arpa.
         addresses: [fdde:ad00:beef:0:e0fc:dc28:1d12:8c2]
      Done
      

Power consumption measurements

You can use the Thread CLI sample to perform power consumption measurements for Sleepy End Devices.

After building and flashing with the low_power snippet, the device will start regular operation with the UART console enabled. This allows for easy configuration of the device, specifically the Sleepy End Device polling period or the Synchronized Sleepy End Device (SSED) CSL period and other relevant parameters.

When the device becomes attached to a Thread Router it will automatically suspend UART operation and power down unused RAM. In this mode, you cannot use the CLI to control the device. Instead, the device will periodically wake up from deep sleep mode and turn on the radio to receive any messages from its parent.

If the device is connected to a Power Profiler Kit II (PPK2), you can perform detailed power consumption measurements.

See OpenThread power consumption for more information.

Dependencies

This sample uses the following Zephyr libraries:

The following dependencies are added by the optional multiprotocol Bluetooth® LE extension:

In addition, it uses the following secure firmware component: