wakojosin 发表于 2024-3-24 11:54

KW41Z板卡-openthread的udp通讯

本帖最后由 wakojosin 于 2024-3-24 11:54 编辑

<p><span style="font-size:16px;"><strong>测试环境</strong></span></p>

<p>使用的硬件是KW41Z开发板和nrf52840开发板,两者都跑openthread协议栈进行下面的实验。</p>

<p>固件方面两者烧写的是各自的ftd-cli工程。</p>

<p>下面测试过程用NRF代表NRF52840,NXP代表KW41Z。</p>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><strong>测试过程</strong></span></p>

<p>启动接口。</p>

<p>NRF:</p>

<pre>
<code>&gt; ifconfig up
Done
&gt; thread start
Done
&gt;
&gt; state
leader
Done
&gt;
</code></pre>

<p>NXP:</p>

<pre>
<code>&gt; eui64
1bf3040000000000
Done
&gt; ifconfig up
Done
&gt; </code></pre>

<p>入网,此时使用NRF作为leader设备,NXP作为节点(会自动升级为rooter)。</p>

<p>NRF:</p>

<pre>
<code>&gt; commissioner start
Commissioner: petitioning
Done
&gt; Commissioner: active
commissioner joiner add 1bf3040000000000 PPSSKK
Done
&gt; ~ Discovery Request from 12954efa1b74f63f: version=4,joiner=1
Commissioner: Joiner start 5795cc01d9ef484e
Commissioner: Joiner connect 5795cc01d9ef484e
=========[ direction=recv | type=JOIN_FIN.req | len=048]==========
| 10 01 01 21 0A 4F 50 45 | 4E 54 48 52 45 41 44 22 | ...!.OPENTHREAD"
| 05 4B 57 34 31 5A 23 10 | 74 68 72 65 61 64 2D 72 | .KW41Z#.thread-r
| 65 66 65 72 65 6E 63 65 | 25 06 18 B4 30 00 00 10 | eference%..40...
------------------------------------------------------------------------
=========[ direction=send | type=JOIN_FIN.rsp | len=003]==========
| 10 01 01 .. .. .. .. .. | .. .. .. .. .. .. .. .. | ................
------------------------------------------------------------------------
Commissioner: Joiner finalize 5795cc01d9ef484e
-MESH-CP-: direction=send | type=JOIN_ENT.ntf
-MESH-CP-: direction=recv | type=JOIN_ENT.rsp
Commissioner: Joiner end 5795cc01d9ef484e
Commissioner: Joiner remove 5795cc01d9ef484e
&gt;
&gt; ipaddr
fd9f:129:4246:a051:0:ff:fe00:fc31
fd9f:129:4246:a051:0:ff:fe00:fc00
fd9f:129:4246:a051:0:ff:fe00:2400
fd9f:129:4246:a051:b860:2a7f:75dd:e101
fe80:0:0:0:28f0:3f23:5560:65b0
Done
</code></pre>

<p>NXP:</p>

<pre>
<code>&gt; joiner start PPSSKK
Done
&gt; Join success
&gt;
&gt; thread start
Done
&gt;
&gt; state
child
Done
&gt;
&gt; ipaddr
fd9f:129:4246:a051:0:ff:fe00:2401
fd9f:129:4246:a051:104e:6c93:d338:7114
fe80:0:0:0:4c86:1466:c96e:a32c
Done
</code></pre>

<p><span style="font-size:16px;"><strong>UDP测试</strong></span></p>

<p>NRF:</p>

<pre>
<code>&gt; udp open
Done
&gt; udp bind :: 1234
Done
&gt; udp send fd9f:129:4246:a051:104e:6c93:d338:7114 2345 hello41z
Done
&gt; 10 bytes from fd9f:129:4246:a051:104e:6c93:d338:7114 2345 hello52840</code></pre>

<p>NXP:</p>

<pre>
<code>&gt; udp open
Done
&gt; udp bind :: 2345
Done
&gt; 8 bytes from fd9f:129:4246:a051:b860:2a7f:75dd:e101 1234 hello41z

&gt; udp send fd9f:129:4246:a051:b860:2a7f:75dd:e101 1234 hello52840
Done
&gt;
</code></pre>

<p><span style="font-size:16px;"><strong>UDP命令分析</strong></span></p>

<p>路径位于:ot-kw41z/openthread/src/cli/cli_udp.cpp</p>

<p>udp open</p>

<pre>
<code>//这个命令主要是调用otUdpOpen,HandleUdpReceive函数用来处理接收到的数据
otUdpOpen(GetInstancePtr(), &amp;mSocket, HandleUdpReceive, this);
</code></pre>

<p>udp bind</p>

<pre>
<code>//这个命令主要是调用otUdpBind来开启端口监听
otUdpBind(GetInstancePtr(), &amp;mSocket, &amp;sockaddr, netif);</code></pre>

<p>udp send</p>

<pre>
<code>//这个命令主要是构建一个message,将数据写进message中,然后通过otUdpSend发送
message = otUdpNewMessage(GetInstancePtr(), &amp;messageSettings);
otMessageAppend(message, aArgs.GetCString(), aArgs.GetLength());
otUdpSend(GetInstancePtr(), &amp;mSocket, message, &amp;messageInfo);</code></pre>

<p>udp connect:调用otUdpConnect来与指定主机建立连接。</p>

<p>udp close:调用otUdpClose来关闭UDP客户端。</p>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><strong>写自己的demo</strong></span></p>

<p>在ot-kw41z/openthread/examples/apps路径下,复制cli,重命名为demo,然后修改此目录下的CMakeLists.txt,前后内容如下</p>

<p>修改前:</p>

<pre>
<code>if(OT_APP_CLI)
    add_subdirectory(cli)
endif()

add_subdirectory(ncp)
</code></pre>

<p>修改后:</p>

<pre>
<code>if(OT_APP_CLI)
    add_subdirectory(cli)
    add_subdirectory(demo)
endif()

add_subdirectory(ncp)
</code></pre>

<p>增加demo.c,主要代码如下:</p>

<pre>
<code>

static otMessage    *mMessage = NULL;
static otMessageInfo mMessageInfo;
static otUdpSocket   mSocket;
void DemoProcess(otInstance *instance)
{
    if(NULL == instance)
    {
      return;
    }
    if(!otUdpIsOpen(instance, &amp;mSocket))
    {
      return;
    }
    otMessage *message = mMessage;
    if(message != NULL)
    {
      mMessage = NULL;
      if(OT_ERROR_NONE != otUdpSend(instance, &amp;mSocket, message, &amp;(mMessageInfo)))
      {
            DBG_INFO_OUT("send message failed!\n");
            otMessageFree(message);
      }
    }
}
bool DemoMessageSet(otMessage *message, const otMessageInfo *info)
{
    if(mMessage == NULL)
    {
      mMessage = message;
      memcpy(&amp;mMessageInfo.mPeerAddr, &amp;(info-&gt;mPeerAddr), sizeof(mMessageInfo.mPeerAddr));
      mMessageInfo.mPeerPort = info-&gt;mPeerPort;
      return true;
    }
    else
    {
      return false;
    }
}
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
    char buf;
    intlength;
    bool isSecurity = otMessageIsLinkSecurityEnabled(aMessage);

    DBG_INFO_OUT("%d bytes from ", otMessageGetLength(aMessage) - otMessageGetOffset(aMessage));
    otIp6AddressToString(&amp;aMessageInfo-&gt;mPeerAddr, buf, sizeof(buf));
    DBG_INFO_OUT("%s:%d (%d) ", buf, aMessageInfo-&gt;mPeerPort, isSecurity);

    length      = otMessageRead(aMessage, otMessageGetOffset(aMessage), buf, sizeof(buf) - 1);
    buf = '\0';
    DBG_INFO_OUT("%s\n", buf);
    // create message
    otInstance *instance = (otInstance *)aContext;
    if(instance)
    {
      otMessage *message = otUdpNewMessage(instance, NULL);
      if(message)
      {
            if(OT_ERROR_NONE == otMessageAppend(message, buf, length))
            {
                if(DemoMessageSet(message, aMessageInfo))
                {
                  message = NULL;
                }
            }
            if(message)
            {
                otMessageFree(message);
            }
      }
    }
}
void DemoInit(otInstance *instance)
{
    otSockAddr sockaddr;

    if(instance== NULL)
    {
      return ;
    }
    if(otUdpIsOpen(instance, &amp;mSocket))
    {
      return ;
    }
    memset(&amp;mSocket, 0, sizeof(mSocket));
    if(OT_ERROR_NONE != otUdpOpen(instance, &amp;mSocket, HandleUdpReceive, instance))
    {
      return ;
    }
    memset(&amp;sockaddr, 0, sizeof(sockaddr));
    otIp6AddressFromString("::", &amp;sockaddr.mAddress);
    sockaddr.mPort = 12345;
    if(OT_ERROR_NONE != otUdpBind(instance, &amp;mSocket, &amp;sockaddr, OT_NETIF_THREAD))
    {
      return ;
    }
}</code></pre>

<p>代码实现的是echo功能。</p>

Jacktang 发表于 2024-3-25 07:48

<p>KW41Z开发板和nrf52840开发板,都跑openthread协议栈进行的实验测试后情况如何</p>

freebsder 发表于 2024-3-26 15:51

<p>KW41Z 应该不是nxp主推的了吧</p>

wakojosin 发表于 2024-3-26 22:10

Jacktang 发表于 2024-3-25 07:48
KW41Z开发板和nrf52840开发板,都跑openthread协议栈进行的实验测试后情况如何

<p>可以正常组网</p>

wakojosin 发表于 2024-3-26 22:11

freebsder 发表于 2024-3-26 15:51
KW41Z 应该不是nxp主推的了吧

<p>nxp对这块的推广力度感觉不大</p>
页: [1]
查看完整版本: KW41Z板卡-openthread的udp通讯