Showing posts with label OpenThread Border Router. Show all posts
Showing posts with label OpenThread Border Router. Show all posts

Friday, February 11, 2022

Build and run OpenThread Border Router for NXP i.MX6ULL with Silicon Labs EFR32 as RCP

This tutorial shows you how to build and run OpenThread Border Router for NXP i.MX6ULL with Silicon Labs EFR32 as RCP.

1. Setup build environment and build OpenThread Border Router for NXP i.MX6ULL EVK.

 sudo apt-get install -y gcc make perl curl nodejs npm
  • 1.3 Setup Yocto build environment.
mkdir ~/bin
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=${PATH}:~/bin

sudo update-ca-certificates
mkdir yocto-otbr
cd yocto-otbr
git config --global user.email "youremail@email.com"
git config --global user.name "yourname"
repo init -u https://source.codeaurora.org/external/imx/imx-manifest -b imx-linux-hardknott -m imx-5.10.35-2.0.0.xml
repo sync
  • 1.4 Integrate the meta-matter recipe into the Yocto code base
cd yocto-otbr/sources
git clone https://github.com/NXPmicro/meta-matter.git
  • 1.5 Install necessary package to build the Yocto Project.
sudo apt-get install -y gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm
  • 1.6 Download 0001-Add-TUN-device-support-for-arm.patch into yocto-otbr/sources/meta-imx folder and run the following git command to patch it (This will build /dev/net/tun on i.MX6ULL system for otbr-agent).
git am -3 0001-Add-TUN-device-support-for-arm.patch
  • 1.7 Generate the Yocto image with OpenThread Border Router support.
MACHINE=imx6ullevk DISTRO=fsl-imx-xwayland source sources/meta-matter/tools/imx-iot-setup.sh bld-xwayland
bitbake imx-image-multimedia
  • 1.8 After previous two commands are excuted successfully, the Yocto image imx-image-multimedia-imx6ullevk.wic.bz2 will be generated under yocto-otbr/bld-xwayland/tmp/deploy/images/imx6ullevk/. imx-image-multimedia-imx6ullevk.wic.bz2 should be unzip to imx-image-multimedia-imx6ullevk.wic.
 
  • 1.9 Use "ls /dev/sd*" to check the sd card name. In my , it's "sdb" Use dd command to program imx-image-multimedia-imx6ullevk.wic.bz2 to a microSD.
 sudo dd if=imx-image-multimedia-imx6ullevk.wic of=/dev/sdb bs=4096 conv=fsync status=progress
  •  1.10 After previous step is done, the microSD card can be used to boot i.MX6ULL EVK with OpenThread Border Router capability.
 

2. Download OT-RCP into Silicon Labs BRD4161A (EFR32 radio board) using Simplicity Studio v5.

  • 2.1 Instead of building OT-RCP for Silicon Labs BRD4161A by myself, I install Simplicity Studio v5 and Gecko SDK Suite v3.2.3 with OpenThread 1.2.3.0
 


  • 2.2 Download prebuilt OT-RCP into Silicon Labs BRD4161A directly.


3. Connect NXP i.MX6ULL EVK with Silicon Labs EFR32 as RCP to test OpenThread Border Router.

  • 3.1 Connect Silicon Labs BRD4161A+BRD4001A to i.MX6ULL EVK with USB cable and put the the microSD (built in step 1) to power on i.MX6ULL EVK.
 

  • 3.2 Use root to login i.MX6ULL EVK debug console and run the following command to start otbr-agent
 otbr-agent -I wpan0 -B eth0 spinel+hdlc+uart:///dev/ttyACM0 &
 
P.S.Since we use Silicon Labs BRD4161A+BRD4001A, it should emulate ttyACM0 after connecting to i.MX6ULL EVK with USB cable. If you use othe OT-RCP hardware, you might need to check physical device name that is emulated by your hardware.
  • 3.3 Run ot-ctl, which is a command line utility provided with OTBR. It is used to communicate with the Thread PAN interface (default is wpan0) that otbr-agent is bound to in the RCP design, to start test everything.
 P.S. If you see "connection session failed: No such file or directory" problem when running ot-ctl, you can use "cat /var/log/syslog" to check what's wrong with otbr-agent.
 

  • 3.4 You can refer to step 5, 6, and 7 in this post to test OTBR and an OT-CLI-FTD node.

 

P.S. Thanks Elven Wang @NXP and Jonathan Hui @Google for their great help to make all of these work together. The followings are reference links of previous works that help me lots.

https://github.com/openthread/ot-br-posix/issues/1200#

https://github.com/NXPmicro/meta-matter

Thursday, July 1, 2021

How to build OpenThread Sleepy MTD CoAP temperature sensor using Simplicity Studio v5 and BRD4161A

The following steps show you how to build an OpenThread Sleepy MTD CoAP temperature sensor using Simplicity Studio v5 and BRD4161A

1. Start Simplicity Studio v5 and connect EFR32MG12 BRD4161A. Form Launcher tab, select sleepy-demo-mtd (I use OpenThread SDK 1.2.0.0 when I test this) to create the project.

 


2.  We will add temperature reading (from Si7021) related codes in this step.

2.1 In Simplicity IDE tab, open sleepy-demo-mtd.slcp to make sure you enable "Relative Humidity and Temperature sensor" and set proper I2C pins.



2.2 You also need to check sl_board_control_config.h and make sure SL_BOARD_ENABLE_SENSOR_RHT is defined as "1" and SL_BOARD_ENABLE_SENSOR_RHT_PORT/SL_BOARD_ENABLE_SENSOR_RHT_PIN are defined to correct port/pin which is PB10 on BRD4161A. 

2.3 Set "sl_i2cspm_t *i2cspm_sensor = sl_i2cspm_inst0;" in sl_sensor_select.c.

2.4 Create periodic event to read temperature from humidity/temperature sensor Si7021.

2.4.1 Add the following header files for humidity/temperature reading and timer event.

#include "sl_i2cspm_instances.h"
#include "sl_si70xx.h"
#include "sl_sleeptimer.h"
#include <stdio.h>
#include <string.h>


2.4.2 Add the following lines in app_init in app.c to initialize Si7021 humidity/temperature sensor.

    otCliOutputFormat("app_init: sl_si70xx_init\r\n");
    sl_si70xx_init(sl_i2cspm_inst0, SI7021_ADDR);
 


 2.4.3 Add timer related defines/variables/callback function and add timer start in app_init in app.c.

#define MEASUREMENT_INTERVAL_MS      5000
static sl_sleeptimer_timer_handle_t measurement_timer;



static void measurement_callback(sl_sleeptimer_timer_handle_t *handle, void *data)
{
  otCliOutputFormat("measurement_callback\r\n");
  sl_si70xx_measure_rh_and_temp(sl_i2cspm_inst0, SI7021_ADDR, &rh_data, &temp_data);
  memset(str_buf,0,64);
  sprintf(str_buf,"rh=%f, temperature=%f\r\n",((float)rh_data/1000.0),((float)temp_data/1000.0));
  otCliOutputFormat(str_buf);
}



void app_init(void)
{
... 
otCliOutputFormat("app_init: Setup periodic measurement timer \r\n");
sl_sleeptimer_start_periodic_timer_ms(&measurement_timer, MEASUREMENT_INTERVAL_MS, measurement_callback, NULL, 0, 0);
...
}


3.  Change related network settings in setNetworkConfiguration function (in sleepy-mtd.c) so the device can join matched OpenThread Border Router network (refer to here to setup OpenThread Border Router).



4. Implement CoAP related codes.

4.1 Add the following header files in app.c

#include <openthread/coap.h>
#include "utils/code_utils.h"


 4.2 Add CoAP related defines and variables.

#define TEMPERATURE_STATE_URI     "temp/celcius"
otCoapResource mResource_TEMPERATURE_STATE;
const char mTEMPERATUREStateUriPath[]=TEMPERATURE_STATE_URI;

4.3 Implement CoAP processing callback

static void temperature_state_coapHandler(void *aContext, otMessage *aMessage,
                             const otMessageInfo *aMessageInfo)
{
    otCliOutputFormat("sleepy-demo-mtd temperature_state_coapHandler\r\n");
    otError error = OT_ERROR_NONE;
    otMessage *responseMessage;
    otCoapCode responseCode = OT_COAP_CODE_CHANGED;
    otCoapCode messageCode = otCoapMessageGetCode(aMessage);
    otCoapType messageType = otCoapMessageGetType(aMessage);

    responseMessage = otCoapNewMessage((otInstance*)aContext, NULL);
    otEXPECT_ACTION(responseMessage != NULL, error = OT_ERROR_NO_BUFS);

    otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode);
    otCoapMessageSetToken(responseMessage, otCoapMessageGetToken(aMessage),
                         otCoapMessageGetTokenLength(aMessage));
    otCoapMessageSetPayloadMarker(responseMessage);

    if(OT_COAP_CODE_GET == messageCode)
    {
        memset(str_buf,0,64);
        sprintf(str_buf,"%f",((float)temp_data/1000.0));
         otCliOutputFormat("\r\nsleepy-demo-mtd coap get\r\n");
        otCliOutputFormat(str_buf);
        error = otMessageAppend(responseMessage, str_buf,
                                strlen((const char*)str_buf));
        otEXPECT(OT_ERROR_NONE == error);

        error = otCoapSendResponse((otInstance*)aContext, responseMessage,
                                   aMessageInfo);
        otEXPECT(OT_ERROR_NONE == error);
    }

exit:

    if (error != OT_ERROR_NONE && responseMessage != NULL)
    {
        otMessageFree(responseMessage);
    }
}


 4.4 Add CoAP start codes in app_init.

otCoapStart(otGetInstance(),OT_DEFAULT_COAP_PORT);

mResource_TEMPERATURE_STATE.mUriPath = mTEMPERATUREStateUriPath;    

mResource_TEMPERATURE_STATE.mContext = otGetInstance(); 

mResource_TEMPERATURE_STATE.mHandler = &temperature_state_coapHandler;

strncpy(mTEMPERATUREStateUriPath, TEMPERATURE_STATE_URI, sizeof(TEMPERATURE_STATE_URI));

otCoapAddResource(otGetInstance(),&mResource_TEMPERATURE_STATE);


 5. Build and download sleepy-demo-mtd.hex into your BRD4161A.


6.Reset BRD4161A to join OpenThread Border Router and use CLI command "ipaddr" to output IPv6 address of Sleepy End Device. 

 

7.Now, you can run coap-client (install libCoAP) on Raspberry Pi OTBR to get temperature reading through CoAP server running on BRD4161A Sleepy End Device.

 


 

Wednesday, February 24, 2021

Project Connected Home over IP (ProjectCHIP) demonstration with EFR32 as ProjectCHIP node, Raspberry Pi as OTBR, and Ubuntu VM as chip-tool

 The follow steps show you how to setup Project Connected Home over IP (ProjectCHIP) demonstration with EFR32 as ProjectCHIP node, Raspberry Pi as OTBR, and Ubuntu VM as chip-tool like in the diagram.



1. Install VirtualBox and Ubuntu 20.04 on your Desktop. Remember select "Bridged Adapter" in your network settings of VirtualBox/Ubuntu.

2. Setup environment (run the following commands in Ubuntu terminal) for building CHIP examples on Ubuntu VM.

    2.1 sudo apt-get install git gcc g++ python pkg-config libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev unzip

    2.2.1 cd ~
    2.2.2 git clone https://github.com/SiliconLabs/sdk_support.git
    2.2.3 cd sdk_support
    2.2.4 git checkout ff45be117a5a1a20d27296628b0632523f65c66a

    2.3.1 cd ~
    2.3.2 git clone https://github.com/project-chip/connectedhomeip.git
    2.3.3 cd connectedhomeip
    2.3.4 git checkout 122da92801fd38f49b8fe3db397ccaa4eb0e4798
    2.3.5 source scripts/activate.sh
    2.3.6 gn gen out/host
    2.3.7 ninja -C out/host

3. Build and download CHIP lock-app for EFR32 (In my examples, I use BRD4180A with BRD4001A to act as Thread node running CHIP protocol)

    3.1 cd ~/connectedhomeip/examples/lock-app/efr32
    3.2 git submodule update --init
    3.3 source third_party/connectedhomeip/scripts/activate.sh
    3.4 export EFR32_SDK_ROOT=~/sdk_support
    3.5 export EFR32_BOARD=BRD4180A
    3.6 gn gen out/debug --args="efr32_sdk_root=\"${EFR32_SDK_ROOT}\" efr32_board=\"${EFR32_BOARD}\""
    3.7 ninja -C out/debug
    3.8 Using Simplicity Studio Commander to download chip-efr32-lock-example.s37 under out/debug folder into BRD4180A.

4. Refer to "Running OpenThread Border Router and device with Raspberry Pi and Silicon Labs EFR32 Kits" to setup OpenThread Border Router on Raspberry Pi.

5. Run the following commands in OpenThread Border Router terminal to setup Thread network for commission.

    5.1.1 sudo ot-ctl dataset init new
    5.1.2 sudo ot-ctl dataset channel 13
    5.1.3 sudo ot-ctl dataset panid 0xface
    5.1.4 sudo ot-ctl dataset extpanid face1111face2222
    5.1.5 sudo ot-ctl dataset networkname OpenThreadYKTest
    5.1.6 sudo ot-ctl dataset masterkey 00112233445566778899aabbccddeeff
    5.1.7 sudo ot-ctl dataset commit active

    5.2.1 sudo ot-ctl prefix add 2001:db8::/64 pasor
    5.2.2 sudo ot-ctl ifconfig up
    5.2.3 sudo ot-ctl thread start
    5.2.4 sudo ot-ctl netdata register
    5.2.5 sudo ot-ctl state
    5.2.6 sudo ot-ctl ipaddr


    5.3.1 sudo ip addr add dev eth0 2002::2/64

 
6. Run the following commands on terminal of EFR32 CHIP lock-app device (build and download in step 3)

    6.1 factoryreset
    6.2 dataset channel 13
    6.3 dataset panid 0xface
    6.4 dataset masterkey 00112233445566778899aabbccddeeff
    6.5 dataset commit active
    6.6 ifconfig up
    6.7 thread start
    6.8 ipaddr

7. Try to ping EFR32 CHIP lock-app device from Raspberry Pi border router to make sure it respond.


8. Add route (enp0s3 might be different on your VM) on Ubuntu VM to access to EFR32 CHIP lock-app device

    8.1 sudo ifconfig enp0s3 inet6 add 2002::1/64
    8.2 sudo ip route add 2001:db8:0:0::/64 via 2002::2
    8.3 sudo ip route add fd38:117c:3b66::/64 via 2002::2


     8.4Try to ping EFR32 CHIP lock-app device from Ununtu VM terminal this time to make sure it respond.

 


9. Build and run chip-tool on Ubuntu VM

    9.1 cd ~/connectedhomeip/examples/chip-tool
    9.2 git submodule update --init
    9.3 source third_party/connectedhomeip/scripts/activate.sh
    9.4 gn gen out/debug
    9.5 ninja -C out/debug

    9.6 run "./chip-tool onoff on 2001:DB8::C6CC:14E9:E7D1:A3EA 11097 1" to send onoff command on Ubuntu VM terminal to control EFR32 CHIP lock-app device

 


    9.7 Using J-link RTT Viewer to check if EFR32 CHIP lock-app device receives CHIP command.


P.S. This demostartion is based on steps in https://www.silabs.com/documents/public/training/wireless/chip-connected-home-over-ip-lab.pdf. However, there are some typo and ambiguous in the document and here I share the whole steps again according to my test.