你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 FOTA 例程之 cJSON 使用

[复制链接]
STMCU小助手 发布时间:2022-3-4 18:36
前言
在 STM32 OTA 例程中,设备端(stm32F769 探索版)与云端交换数据使用的是 json 格式。在本篇文章中,将对 json 格式以及 Cjson 的使用及注意事项进行说明。

JSON 格式
JSON(JavaScript Object Notation)是一个轻量级的数据交换格式。既便于开发者读写,也便于机器分析和构建。它独立于开发语言,是一种文本格式,很适用描述在各个系统间交换的数据。
JSON 格式的数据看起来就像下面这个样子:
{
“Room1”: {
“LED”: “on”,
“Temperature”: “36”
}
}
这个 JSON 数据描述的是 Room1 的 LED 灯状态以及温度值。它由一组“名称(key)”以及对应的“ 值(value)”组成。“名称”和“ 值”间由“ :”分开。各组“名称:值”对之间由“,”符号进行分割。

cJSON 的使用
针对不同的开发语言,网上有很多 JSON 的实现, demo 里使用的是 Cjson,版本 1.6。

将 Cjson 添加到工程
Cjson 只有一个 C 文件 Cjson.C 和一个头文件 Cjson.h。所以只需要将这两个文件拷贝到工程文件夹中,并将 Cjson.C 添加到工程中就可以了。

数据结构
Cjson 中使用下面的数据结构来表示 JSON 数据。

}E$LN1AD)@5TAKGS[YQFWAP.png

*next 和*prev 指针可以用来遍历“矩阵”或者“对象”类型的 JSON 数据链表;这两种类型的 JSON 数据还会有一个子数据指针*child
type : 表示该 json 数据的类型,比如数字,字符串、矩阵、对象等*valuestring, valueint, valuedouble 和*string 指针分别指向该 json 数据类型具体的值,视其类型而定。

使用 cjson 生成 json 数据
下面我们看看如何使用 cjson 来生成下面的数据:
{
“reported”: {
“LED”: “on”,
“status” : “normal”
}
}
见下面的代码:
  1. cJSON * reported_obj;
  2. cJSON * device_obj;

  3. reported_obj = cJSON_CreateObject();                                             <font color="#00ff00"> //创建空的对象:reproted_obj和 device_obj</font>

  4. device_obj = cJSON_CreateObject();

  5. //add LED status
  6. if(flag_led)
  7. cJSON_AddStringToObject(reported_obj, "LED", "on");
  8. else                                                                                           <font color="#00ff00">   //在 reproted_obj 中添加对象“LED”作为它的子集</font>
  9. cJSON_AddStringToObject(reported_obj, "LED", "off");

  10. //add device status
  11. cJSON_AddStringToObject(reported_obj,"status", "normal");              <font color="#00ff00">//在 reproted_obj 中添加对象“status”作为它的子集</font>
  12. cJSON_AddItemToObject(device_obj, "reported", reported_obj);      <font color="#00ff00" style=""> //reproted_obj 添加到device_obj,作为它的子集</font>
复制代码

现在就已经在 cjson 中,构件好了和前面的数据对应的数据结构。但现在这个数据结构还不能发送出去,需要调用
cJSON_Print 将其打印成串行的数据,存放在 buffer 中,以便后面进行发送。
  1. cjson_print_buf = cJSON_Print(device_obj);
复制代码

cJSON_Print 执行的时候会向系统申请一段内存来保存串行化了的数据,并返回其指针。这里一定要注意的是,cJSON_Print中申请的内存,一定要记得释放(cjson 的代码中不会自动去做释放动作),否则就会出现内存泄漏。
通过 cJSON_CreateObject 创建的对象,也需要调用 cJSON_Delete 来进行删除并释放占用的内存。否则也会出现内存泄漏。见下面的代码:
  1. if(cjson_print_buf!=NULL)
  2. {
  3. snprintfreturn = snprintf(buf,bufsize,cjson_print_buf);
  4. cJSON_free(cjson_print_buf);
  5. }
  6. cJSON_Delete(device_obj);
复制代码

仔细的同学可能会发现为什么调用了两次 cJSON_CreateObject,但只看到释放了其中的 device_obj。这里也是需要注意的一个地方,从前面的代码中,我们可以看到,reported_obj 最终是作为子对象添加到了 device_obj 中,所以在删除 device_obj时,cJSON_Delete 会自动删除 device_obj 中所有的子对像,故而不需要再调用 cJSON_Delete 对 reported_obj 进行删除。


使用 cjson 解析 json 数据
可以通过 cJSON_Parse()函数来解析接收到的 json 数据,cJSON_Parse()函数会对数据进行解析,并申请一段内存保存解析后的 cjson 的数据结构,并返回指针。
通过 cJSON_GetObjectItem()函数可以获取解析后的 cjson 数据结构中的第一级子对象。
使用 cJSON_Parse()后,切记也一定要通过 cJSON_Delete 释放之前所申请的内存。
下面代码是对收到的 json 数据的解析过程。收到的数据内容为:
{
“desired”: {
“LED”: “on”,
“SW_Version” : “02010100”
}
}

  1. receive_obj = cJSON_Parse((char*)message->payload);                 <font color="#00ff00">//解析收到的消息 message-> payload</font>
  2. desired_obj = cJSON_GetObjectItem(receive_obj, "desired");         <font color="#00ff00">//提取 desired 对象</font>
  3. item_obj = desired_obj->child;            
  4. while(item_obj)                                                
  5. {
  6. string = item_obj->string;
  7. if(!strcmp(string, "LED")){
  8. if(!strcmp(item_obj->valuestring,"on"))        <font color="#00ff00">    //依次解析 desired 对象下的子对象值</font>
  9. {
  10. Led_On();
  11. flag_led = 1;
  12. msg_info("LED On!\n");
  13. }
  14. else
  15. {
  16. Led_Off();
  17. flag_led =0;
  18. msg_info("LED Off!\n");
  19. }
  20. }

  21. item_obj = item_obj->next;
  22. }

  23. cJSON_Delete(receive_obj);             <font color="#00ff00"> //释放 receieve_obj 及其子对象</font>
复制代码

总结
cJSON 代码量不大,用起来也方便。使用的时候一定要注意前面提到对使用完的内存空间进行释放。否则会造成内存泄漏。


收藏 评论0 发布时间:2022-3-4 18:36

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版