1099247_zh-CN

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

1099247_zh-CN

1099247_zh-CN

Kinetis W:[主题] CoAP 基础知识和实践<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Thread 使用 UDP 上的单播和多播传输提供应用程序框架实现所需的基本服务。

线程规范仅关注网络层;由于它与应用层无关,因此可以设计许多应用层无问题运行。

在该实验室中,用户将使用该应用层的约束应用协议 (CoAP),因为 Thread 堆栈使用 CoAP 进行大多数多跳网络管理和调试消息。

受限应用协议 (CoAP) 是一种专门用于物联网中受限节点和受限网络的 Web 传输协议。它使用具有四种方法的二进制 RESTful 协议

  • 邮政
  • 得到
  • 放
  • 删除

CoAP 还使用 ACK 响应;可确认(请求 ACK)和不可确认的消息。

Thread 堆栈使用 CoAP 来处理大多数多跳网络管理和调试消息

 

目标

通过本实验用户将修改固件以实现以下列表:

  • 添加2个新的COAP URI资源“/resource1”和“/resource2”。
  • 如果按照 CoAP 标准的规定收到 CON 请求,则在“/resource1”中发送 ACK 消息。ACK 消息中包含默认有效载荷。
  • 所有发往“/resource1”的数据包都将触发一个 NON POST 数据包回复(独立于预期的 ACK 数据包),该回复发往具有默认有效负载的“/resource2”URI 路径。
  • 在 shell 中打印所有 CoAP 事务,以充分了解请求何时发送以及何时收到响应,并指明方法和资源,例如
  • 如果收到了 CON POST,则在 shell 上打印“收到了‘NON’数据包,‘POST’带有有效载荷‘’
  • 如果发送了 NON POST,则在 shell 上打印“已发送‘NON’数据包,带有有效载荷‘’的‘POST’

实验室期望的流程行为如图 1 所示。

1.PNG

图 1 实验室期望行为示意图


 

设置

在下面的列表中,带有破折号(—)的组件将用于创建此实验室。

 

  • 2 FRDM-KW41Z

—牧师一个

  • 来自最新 NXP 版本的 连接软件 。

— Thread Router 合格设备项目

  • 串行终端

— TeraTerm

 IMAG0218.png

图2 FRDM-KW41Z


 

修改固件

将在 router_eligible_device_app.c 文件 中进行以下更改 。

1.定义在 shell 中用于访问资源的 URI 路径名。

#定义APP_RESOURCE1_URI_PATH“/resource1”

#定义 APP_RESOURCE2_URI_PATH“/resource2”

2.PNG

2. 使用 coapUriPath_t 声明 URI 资源。使用此结构时,用户必须输入 URI 路径的长度和上一步创建的路径。

const coapUriPath_t gAPP_RESOURCE1_URI_PATH = {SizeOfString(APP_RESOURCE1_URI_PATH), APP_RESOURCE1_URI_PATH};

const coapUriPath_t gAPP_RESOURCE2_URI_PATH = {SizeOfString(APP_RESOURCE2_URI_PATH), APP_RESOURCE2_URI_PATH};

3.PNG

3.创建资源的回调。此回调将处理接收到的数据包并根据接收到的 COAP 方法类型执行所需的操作。

static void APP_CoapResource1Cb(coapSessionStatus_t sessionStatus, void *pData, coapSession_t *pSession, uint32_t dataLen);

static void APP_CoapResource2Cb(coapSessionStatus_t sessionStatus, void *pData, coapSession_t *pSession, uint32_t dataLen);

4.PNG

4. 为接收到的数据包添加回调处理程序,在此函数中将定义根据接收到的 COAP 方法类型执行哪些操作。

  • APP_CoapResource1Cb

静态无效APP_CoapResource1Cb
 (
 coapSessionStatus_t 会话状态,
无效* pData,
 coapSession_t *pSession,
 uint32_t 数据长度
)

 {
静态 uint8_t pMySessionPayload[3]={0x31,0x32,0x33};
静态uint32_t pMyPayloadSize = 3;
 coapSession_t *pMySession = NULL;
 pMySession = COAP_OpenSession(mAppCoapInstId);
 COAP_AddOptionToList(pMySession,COAP_URI_PATH_OPTION,APP_RESOURCE2_URI_PATH,SizeOfString(APP_RESOURCE2_URI_PATH));

如果(gCoapConfirmable_c == pSession->msgType)
 {
如果(gCoapGET_c == pSession->代码)
 {
 shell_write("'CON' 数据包已接收 'GET',有效载荷为:");
 }
如果(gCoapPOST_c == pSession->代码)
 {
 shell_write("'CON' 数据包已接收带有有效载荷的 'POST':");
 }
如果(gCoapPUT_c == pSession->代码)
 {
 shell_write("'CON' 数据包已接收 'PUT',有效载荷为:");
 }
如果(gCoapFailure_c!=sessionStatus)
 {
 COAP_Send(pSession,gCoapMsgTypeAckSuccessChanged_c,pMySessionPayload,pMyPayloadSize);
 }
 }

否则,如果(gCoapNonConfirmable_c == pSession->msgType)
 {
如果(gCoapGET_c == pSession->代码)
 {
 shell_write("'NON' 数据包已接收 'GET',有效载荷为:");
 }
如果(gCoapPOST_c == pSession->代码)
 {
 shell_write("'NON' 数据包接收到了带有有效载荷的 'POST': ");
 }
如果(gCoapPUT_c == pSession->代码)
 {
 shell_write("'NON' 数据包已接收 'PUT',有效载荷为:");
 }
 }
 shell_writeN(pData,dataLen);
 shell_write("\r\n");
 pMySession->msgType=gCoapNonConfirmable_c;
 pMySession->代码=gCoapPOST_c;
 pMySession->pCallback =NULL;
 FLib_MemCpy(&pMySession->remoteAddr,&gCoapDestAddress,sizeof(ipAddr_t));
 COAP_SendMsg(pMySession,pMySessionPayload,pMyPayloadSize);
 shell_write("'NON' 数据包以 'POST' 形式发送,有效载荷为:");
 shell_writeN((char*)pMySessionPayload,pMyPayloadSize);
 shell_write("\r\n");
 }

5.PNG

6.PNG

7.PNG

8.PNG

每个 UDP 端口可以有一个 COAP 实例,如果应用程序只使用一个端口,则一个实例就足够了。

每个实例可以有多个 COAP 会话,每个数据包/事务都有一个 COAP 会话。在这种情况下,由于期望的结果是获得不同的 ACK 响应,因此需要使用新资源创建新的会话。

  • APP_CoapResource2Cb

 

静态无效APP_CoapResource2Cb
 (
 coapSessionStatus_t 会话状态,
无效* pData,
 coapSession_t *pSession,
 uint32_t 数据长度
)

 {
如果(gCoapNonConfirmable_c == pSession->msgType)
 {
 shell_write("'NON' 数据包接收到了带有有效载荷的 'POST': ");
 shell_writeN(pData,dataLen);
 shell_write("\r\n");
 }
 }

5. 创建回调后,必须在函数APP_InitCoapDemo(void)中将其注册到 CoAP 回调数组中。

{APP_CoapResource1Cb, (coapUriPath_t*)&gAPP_RESOURCE1_URI_PATH},

{APP_CoapResource2Cb,(coapUriPath_t*)&gAPP_RESOURCE2_URI_PATH},

 

9.PNG

关于 CoAP 库的使用,有一些事情需要提及,这些事情在本实验室中没有使用,但可能对其他类型的应用程序有用。

当使用COAP_SendMsg()时,会话将默认自动关闭,除非使用pSession->autoClose进行指示。

发送消息时有两个选项:

可确认( CON ) :等待 ACK 回复,直到收到消息后才会关闭会话,或者在重传次数耗尽时关闭会话。

不可确认( NON ) :对于 NON,在发送消息后立即生效。

如果发送了一条消息但没有得到响应,则会在每个 COAP_ACK_TIMEOUT (以毫秒为单位)后发送一次重新传输,重新传输将以指数方式发送:首先在随机(2,3)秒后,接下来将超时时间加倍,依此类推,直到 达到 COAP_MAX_RETRANSMIT 。

重传停止后,会话将自动关闭并通知应用程序失败,应用程序回调将以状态 gCoapFailure_c 调用 。

当调用回调时当前会话仍然有效,但退出函数后CoAP会话将关闭它。有两种不同的解决方法:

必须创建一个新会话

设置pSession->autoClose = FALSE 。如果 autoClose 设置为 FALSE,请不要忘记使用COAP_CloseSession()从应用程序关闭会话。

 

 

运行演示

1.下载修改后的固件到开发板

2. 为每块板子打开一个串口终端,波特率为115200

10.PNG

图3 串行终端及其配置 

3. 在其中一个板子的终端输入“ thr create ” ,该板子将成为领导者。

11.PNG

图 4 带有命令“thr create”的板 1

12.PNG

图 5 执行“thr create”命令后的 Board 1

 

4. 网络创建完成后, 在第二块板的终端中 输入“thr join” 。

13.PNG

图 6 使用命令“thr join”的板 2

14.PNG

图 7 执行“thr join”命令后的板 2

5. 在两个串行终端中输入命令“ifconfig” 。此命令将显示板的所有地址。

15.PNG

图 8 使用“ifconfig”命令后,板 1

16.PNG

图 9 执行“ifconfig”命令后的板 2

 

6. 为了测试创建的回调,必须发送 CoAP 消息。必须输入以下命令;

coap

                                                                                    

coap CON POST fe80::5df0:2bf0:d69b:1b3c  /resource1 hello

                                                                                    

17.PNG

图10 CoAP命令发送

7. 发送的结果必须是这样的:

—董事会 1

董事会 1 将向董事会 2 请求资源 1

18.PNG

图 11 发送 CoAP 命令之前的 Board 1

由于它已被编码,另一块板将发送 ACK 并打印消息。

19.PNG

图 12 发送 CoAP 命令后的 Board 1

—董事会 2

20.PNG

图13 收到CoAP命令后的Board 2

如果使用CON消息,请求板将收到响应,而如果消息是NON类型,则不会收到响应。

当使用这种类型的消息时,无论包类型如何,发送消息时都会打开一个新会话,并且它将发送非类型的消息。

Tags (1)
No ratings
Version history
Last update:
a week ago
Updated by: