# 简介
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 的接口了,我们不需要再额外修改了。
编写测试代码验证
编写如下代码验证组包逻辑:
#include <rtthread.h>
#include <cJSON.h>
#include <stdio.h>
#include <stdlib.h>
void json_pack(rt_uint16_t date1 ,rt_uint16_t date2 ,rt_uint16_t date3)
{
char *str=NULL;
cJSON *cupload = cJSON_CreateObject();
cJSON *cdate1 = cJSON_CreateNumber(date1);
cJSON *cdate2 = cJSON_CreateNumber(date2);
cJSON *cdate3 = cJSON_CreateNumber(date3);
cJSON *cparams = cJSON_CreateObject();
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");
cJSON_AddItemToObject(cupload, "method", creport);
cJSON_AddItemToObject(cupload, "clientToken", cclientToken);
cJSON_AddItemToObject(cupload, "params", cparams);
str=cJSON_Print(cupload);
rt_kprintf("cjson:%s",str);
cJSON_free(str);
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);
编写如下代码验证解包逻辑:
{
"method": "report",
"clientToken": "clientToken-18b42b4ee12",
"params": {
"date1": 1,
"date2": 2,
"date3": 3
}
*/
void json_unpack()
{
char *json_str =" {\"method\":\"report\",\"clientToken\": \"clientToken-18b42b4ee12\",\"params\":{\"date1\": 1,\"date2\": 2,\"date3\": 3}}";
char *str=NULL;
rt_uint8_t date;
cJSON *cjson_data;
cjson_data = cJSON_Parse(json_str);
if(!cjson_data)
{
rt_kprintf("json phase error%s\r\n",cjson_data);
cJSON_Delete(cjson_data);
return;
}
cJSON* cparams = cJSON_GetObjectItem(cjson_data,"params");
if(cparams)
{
str = cJSON_Print(cJSON_GetObjectItem(cparams,"date1"));
date= atoi(str);
if(date)rt_kprintf("date:%d\r\n",date);
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");
}
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 命令也按照预期解析到数据了。