andeyqi 发表于 2024-8-16 21:50

【匠芯创D133CBS】--2.Rt-thread系统下使用CJSON组包解包数据

<div class='showpostmsg'># 简介
cJSON是一个用C语言的轻量级JSON编解码器,它允许开发者在C程序中轻松地创建、解析和处理JSON数据。cJSON库的主要特点包括轻便、易用和跨平台,使其成为处理JSON数据的理想选择,特别是在资源受限的环境中,如嵌入式系统和单片机开发中。在开发中经常会使用到JSON 来配置用户信息,及解析网络或本地的JSON文件从中提取配置信息。匠芯创的开发包的RT-thread 系统内部已经支持了cJSON 的软件包我们不需要额外的修改即可直接在RT-thread 平台上使用CJSON,本次我们基于RT-thread 环境下使用CJSON 来打包及解包CJSON 数据。

## CJSON 代码加入编译
在RT-thread 环境下使用CJSON 软件包非常的简单只要在menucoonfig界面下打开CJOSN 配置开关即可。

配置开启后在命令行使用scons 工具编译代码发现CJSON 的源代码已经被加入工程编译了

CJSON 对数据的组包过程需要动态申请内存,及删除的时候需要释放内存,其中会依赖平台相关的内存动态申请释放的接口在RT-thread 的CJSON软件包里面已经做了这方面的适配工作,对应的处理如下已经对接到RT-thread 的接口了,我们不需要再额外修改了。


## 编写测试代码验证
编写如下代码验证组包逻辑:
```c
#include <rtthread.h>
#include <cJSON.h>
#include <stdio.h>
#include <stdlib.h>


voidjson_pack(rt_uint16_t date1 ,rt_uint16_t date2 ,rt_uint16_t date3)
{
      char *str=NULL;
      /* 创建一个JSON数据对象(链表头结点) */
      cJSON *cupload = cJSON_CreateObject();
      /* 创建int类型数据 */
      cJSON *cdate1 = cJSON_CreateNumber(date1);
      cJSON *cdate2 = cJSON_CreateNumber(date2);
      cJSON *cdate3 = cJSON_CreateNumber(date3);
      /* 创建一个JSON数据对象(链表结点) //创建JSON对象,{}扩起来的*/
      cJSON *cparams = cJSON_CreateObject();
      /* 创建 "date": cdate键值对,加入到 cparams对象中*/
      cJSON_AddItemToObject(cparams, "date1", cdate1);
      cJSON_AddItemToObject(cparams, "date2", cdate2);
      cJSON_AddItemToObject(cparams, "date3", cdate3);
      /* 创建字符串类型数据 */
      cJSON *cclientToken = cJSON_CreateString("clientToken-18b42b4ee12");
      cJSON *creport = cJSON_CreateString("report");
      /* 加入到JSON数据对象cupload */
      cJSON_AddItemToObject(cupload, "method", creport);
      cJSON_AddItemToObject(cupload, "clientToken", cclientToken);
      cJSON_AddItemToObject(cupload, "params", cparams);
      /* 转换为标准JSON数据格式 */
      str=cJSON_Print(cupload);
      rt_kprintf("cjson:%s",str);
      /* 释放str内存 */
      cJSON_free(str);
      /* 删除json对象,释放内存 */
      cJSON_Delete(cupload);
}


static int cmd_cjson_package(int argc, char **argv)
{

    json_pack(100 ,200 ,300);
    return 0;
}
MSH_CMD_EXPORT_ALIAS(cmd_cjson_package, cjsonp, package json data);
```
编写如下代码验证解包逻辑:
```c
/*
{
   "method":   "report",
   "clientToken":"clientToken-18b42b4ee12",
   "params":   {
         "date1":    1,
         "date2":    2,
         "date3":    3
   }
*/
void json_unpack()
{

   /* json_str为模拟需要解析的json数据包 */
      char *json_str =" {\"method\":\"report\",\"clientToken\":\"clientToken-18b42b4ee12\",\"params\":{\"date1\": 1,\"date2\": 2,\"date3\": 3}}";
      char *str=NULL;
      rt_uint8_tdate;
   cJSON *cjson_data;

   cjson_data = cJSON_Parse(json_str);//将json字符串转化成CJSON结构体类型的数据

   if(!cjson_data)
   {
         //转换错误则退出解析
         rt_kprintf("json phase error%s\r\n",cjson_data);
         cJSON_Delete(cjson_data);
         return;
   }

   /*将"params"成员 放入cparams*/
   cJSON* cparams = cJSON_GetObjectItem(cjson_data,"params");

   if(cparams)
   {
         /* 将"params"成员里面的"date1"转换为标准JSON数据格式 */
         str = cJSON_Print(cJSON_GetObjectItem(cparams,"date1"));
         /* 将str转换int类型*/
         date= atoi(str);
         if(date)rt_kprintf("date:%d\r\n",date);
         /* 释放str内存*/
         cJSON_free(str);

         str = cJSON_Print(cJSON_GetObjectItem(cparams,"date2"));
         date= atoi(str);
         if(date)rt_kprintf("date2:%d\r\n",date);
         cJSON_free(str);

         str = cJSON_Print(cJSON_GetObjectItem(cparams,"date3"));
         date= atoi(str);
         if(date)rt_kprintf("date3:%d\r\n",date);
         cJSON_free(str);


         }
          else
         {
         rt_kprintf("str phase error\r\n");
         }
       /* 删除json对象,释放内存 */
      cJSON_Delete(cjson_data);


}


static int cmd_cjson_unpackage(int argc, char **argv)
{

    json_unpack();
    return 0;
}
MSH_CMD_EXPORT_ALIAS(cmd_cjson_unpackage, cjsonup, unpackage json data);

```

## 烧写板卡验证
输入测试命令cjsonp 验证打包逻辑,输入后发现打印输出不完整没有打印完整整包数据:


调查发现是因为console 的输出buff 不够造成的打印被截断,按照如下方法修改buff 大小配置


修改后发现已经可以按照预期的打印出组包的数据了:


输入cjsonup 命令也按照预期解析到数据了。

</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                               
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

damiaa 发表于 2024-8-19 13:51

<p>RT-thread 越来越做得不错了很多软件库都直接包含进去了。用CJSON比直接解析方便多了。</p>

andeyqi 发表于 2024-8-21 20:12

damiaa 发表于 2024-8-19 13:51
RT-thread 越来越做得不错了很多软件库都直接包含进去了。用CJSON比直接解析方便多了。

<p>相对组件很丰富,好多现成的软件包可以拿来使用这点比较方便</p>
页: [1]
查看完整版本: 【匠芯创D133CBS】--2.Rt-thread系统下使用CJSON组包解包数据