发 帖  
原厂入驻New
LiteOS云端对接教程07-LiteOS基于CoAP对接华为OC平台实战
2020-2-27 08:47:39  253 单片机 华为云 Liteos 小熊派BearPi 嵌入式
分享
本帖最后由 小熊派开源社区 于 2020-2-27 08:48 编辑

1. LiteOS OC COAP 抽象组件

概述

为了适应各种各样的使用coap接入华为OC的模式,特采用该层次接口,对上提供应用所需的接口,对下允许接入方式的灵活适配。
OC COAP AL的api接口声明在<oc_coap_al.h>中,使用相关的接口需要包含该头文件。

配置并连接

对接服务器的所有信息保存在结构体<code]oc_coap_al.h中,如下:
其中boot_mode是对接模式,对应华为平台的两种模式:
  1. typedef enum
  2. {
  3.     en_oc_boot_strap_mode_factory = 0,
  4.     en_oc_boot_strap_mode_client_initialize,
  5.     en_oc_boot_strap_mode_sequence,
  6. }en_oc_boot_strap_mode_t;
复制代码
app_server参数是服务器信息,定义如下:
  1. typedef struct
  2. {
  3.     char *ep_id;                  ///< endpoint identIFier, which could be recognized by the server
  4.     char *address;                ///< server address,maybe domain name
  5.     char *port;                   ///< server port
  6.     char *psk_id;                 ///< server encode by psk, if not set NULL here
  7.     char *psk;
  8.     int   psk_len;
  9. }oc_server_t;
复制代码
参数说明如下:
  • ep_id:设备标识符
  • address:服务器地址
  • port:服务器端口
  • psk_id:DTLS使用,不使用的话设置为NULL
rcv_func是回调函数的函数指针,当设备接收到coap消息后回调:
  1. typedef int (*fn_oc_coap_msg_deal)(void *msg, int len);
复制代码
在配置结构体完成之后,调用配置函数进行配置并连接,API如下:
  1. /**
  2. * [url=home.php?mod=space&uid=2666770]@Brief[/url] the application use this function to configure the coap agent
  3. * @param[in] param, refer to tag_oc_coap_config
  4. * [url=home.php?mod=space&uid=1141835]@Return[/url] oc coap handle else NULL faiLED
  5. */
  6. void *oc_coap_config(oc_config_param_t *param);
复制代码
函数参数很清楚,将存放对接信息的结构体指针传入即可,API的返回值是oc coap handle指针,后续使用。

数据上报

连接成功之后,因为平台部署了编解码插件,直接向华为云平台上报二进制数据即可,oc_coap提供的API如下:
  1. /**
  2. * @brief the application use this function to send the message to the cdp
  3. * @param[in] hanlde:the coap handle returned by oc_coap_config
  4. * @param[in] report:the message to report
  5. *
  6. * @return 0 success while <0 failed
  7. */
  8. int oc_coap_report(void *handle,char *msg,int len);
复制代码
命令接收
当OC平台发布该主题数据时,oc_coap组件会拉起接收回调函数将数据保存,进而用户解析接收到的数据即可。
oc_coap组件自动初始化
在SDK目录中的IoT_LINK_1.0.0\iot_link\link_main.c中可以看到自动初始化函数:

2. 配置准备

Makefile配置

因为本次实验用到的组件较多:
  • AT框架
  • ESP8266设备驱动
  • 串口驱动框架
  • SAL组件
  • coap组件
  • oc_coap组件
这些实验代码全部编译下来,有350KB,而小熊派开发板所使用的主控芯片STM32L431RCT6的 Flash 仅有256KB,会导致编译器无法链接出可执行文件,所以要在makefile中修改优化选项,修改为-OS参数,即最大限度的优化代码尺寸,并去掉-g参数,即代码只能下载运行,无法调试,如图:

ESP8266设备配置
在工程目录中的OS_CONFIG/iot_link_config.h文件中,配置ESP8266设备的波特率和设备名称:
SDK:C:\Users\Administrator\.icode\sdk\IoT_LINK_1.0.0(其中Administrator是实验电脑的用户名)。
在SDK目录中的<iot_link\network\tcpip\esp8266_socket\esp8266_socket_imp.c文件中,配置连接信息:
在 Demo 文件夹下创建cloud_test_demo文件夹,在其中创建oc_coap_demo.c文件。
编写以下代码:
  1. #include <osal.h>
  2. #include <oc_coap_al.h>
  3. #include <link_endian.h>
  4. #include <string.h>

  5. #define cn_endpoint_id        "654654654"
  6. #define cn_app_server         "49.4.85.232"
  7. #define cn_app_port           "5683"

  8. #define cn_app_light           0
  9. #define cn_app_ledcmd          1

  10. #pragma pack(1)

  11. typedef struct
  12. {
  13.     int8_t msgid;
  14.     uint16_t intensity;
  15. }app_light_intensity_t;


  16. typedef struct
  17. {
  18.     int8_t msgid;
  19.     char led[3];
  20. }app_led_cmd_t;

  21. #pragma pack()

  22. #define cn_app_rcv_buf_len 128
  23. static int8_t          s_rcv_buffer[cn_app_rcv_buf_len];
  24. static int             s_rcv_datalen;
  25. static osal_semp_t     s_rcv_sync;

  26. static void           *s_coap_handle = NULL;

  27. static int app_msg_deal(void *msg, int len)
  28. {
  29.     int ret = -1;

  30.     if(len <= cn_app_rcv_buf_len)
  31.     {
  32.         memcpy(s_rcv_buffer,msg,len);
  33.         s_rcv_datalen = len;

  34.         osal_semp_post(s_rcv_sync);

  35.         ret = 0;

  36.     }
  37.     return ret;
  38. }


  39. static int app_cmd_task_entry()
  40. {
  41.     int ret = -1;
  42.     app_led_cmd_t *led_cmd;
  43.     int8_t msgid;

  44.     while(1)
  45.     {
  46.         if(osal_semp_pend(s_rcv_sync,cn_osal_timeout_forever))
  47.         {
  48.             msgid = s_rcv_buffer[0];
  49.             switch (msgid)
  50.             {
  51.                 case cn_app_ledcmd:
  52.                     led_cmd = (app_led_cmd_t *)s_rcv_buffer;
  53.                     printf("LEDCMD:msgid:%d msg:%s \n\r",led_cmd->msgid, led_cmd->led);
  54.                     if (led_cmd->led[0] == 'o' && led_cmd->led[1] == 'n')
  55.                     {
  56.                         printf("--------------- LED ON! --------------------\r\n");
  57.                     }

  58.                     else if (led_cmd->led[0] == 'o' && led_cmd->led[1] == 'f' && led_cmd->led[2] == 'f')
  59.                     {
  60.                         printf("--------------- LED OFF! --------------------\r\n");
  61.                     }
  62.                     else
  63.                     {

  64.                     }
  65.                     break;
  66.                 default:
  67.                     break;
  68.             }
  69.         }
  70.     }

  71.     return ret;
  72. }

  73. static int app_report_task_entry()
  74. {
  75.     int ret = -1;
  76.     int lux = 0;

  77.     oc_config_param_t      oc_param;
  78.     app_light_intensity_t  light;

  79.     memset(&oc_param,0,sizeof(oc_param));

  80.     oc_param.app_server.address = cn_app_server;
  81.     oc_param.app_server.port = cn_app_port;
  82.     oc_param.app_server.ep_id = cn_endpoint_id;
  83.     oc_param.boot_mode = en_oc_boot_strap_mode_factory;
  84.     oc_param.rcv_func = app_msg_deal;

  85.     s_coap_handle = oc_coap_config(&oc_param);

  86.     if(NULL != s_coap_handle)   
  87.     {
  88.         while(1)
  89.         {
  90.             lux++;
  91.             lux= lux%10000;
  92.             printf("lux is %d!\r\n",lux);

  93.             light.msgid = cn_app_light;
  94.             light.intensity = htons(lux);
  95.             oc_coap_report(s_coap_handle,(char *)&light,sizeof(light));
  96.             osal_task_sleep(5*1000);
  97.         }
  98.     }

  99.     return ret;
  100. }

  101. int standard_app_demo_main()
  102. {
  103.     osal_semp_create(&s_rcv_sync,1,0);

  104.     osal_task_create("app_report",app_report_task_entry,NULL,0x1000,NULL,2);
  105.     osal_task_create("app_command",app_cmd_task_entry,NULL,0x1000,NULL,3);

  106.     return 0;
  107. }
复制代码
添加路径
在user_demo.mk中添加如下:
  1.         #example for oc_coap_demo
  2.         ifeq ($(CONFIG_USER_DEMO), "oc_coap_demo")        
  3.                 user_demo_src  = ${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Demos/cloud_test_demo/oc_coap_demo.c}
  4.         endif
复制代码
添加位置如下:

配置.sdkconfig

上报数据实验结果
编译,下载,在云端的实验现象如下:

在本地的实验现象如下:

命令下发实验结果

在云端下发“on”命令:

在串口助手中可以看到:

下发“off”命令:

在串口助手中可以看到:




0
分享淘帖 显示全部楼层

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发资料
关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表