STMCU小助手
发布时间:2022-3-4 18:36
|
前言4 v# h* d$ i, E3 | 在 STM32 OTA 例程中,设备端(stm32F769 探索版)与云端交换数据使用的是 json 格式。在本篇文章中,将对 json 格式以及 Cjson 的使用及注意事项进行说明。 JSON 格式 JSON(JavaScript Object Notation)是一个轻量级的数据交换格式。既便于开发者读写,也便于机器分析和构建。它独立于开发语言,是一种文本格式,很适用描述在各个系统间交换的数据。 JSON 格式的数据看起来就像下面这个样子: { “Room1”: { “LED”: “on”,- o5 p3 M" e0 n" I5 b “Temperature”: “36”, m5 X9 J& q9 E! i; w! { } }9 @& e4 e; e! i8 }0 L+ D 这个 JSON 数据描述的是 Room1 的 LED 灯状态以及温度值。它由一组“名称(key)”以及对应的“ 值(value)”组成。“名称”和“ 值”间由“ :”分开。各组“名称:值”对之间由“,”符号进行分割。; b9 F, q* S, k( ~( p4 I3 X: V7 c% B 1 d$ E0 W$ T. E. F9 `. E cJSON 的使用 针对不同的开发语言,网上有很多 JSON 的实现, demo 里使用的是 Cjson,版本 1.6。7 K' b) x$ a d; w8 H- y 将 Cjson 添加到工程 Cjson 只有一个 C 文件 Cjson.C 和一个头文件 Cjson.h。所以只需要将这两个文件拷贝到工程文件夹中,并将 Cjson.C 添加到工程中就可以了。 数据结构9 @& ^. J# M5 q/ b Cjson 中使用下面的数据结构来表示 JSON 数据。 ) }: d4 K0 Z- P4 _
5 t; c- D u# w: c8 E3 Y *next 和*prev 指针可以用来遍历“矩阵”或者“对象”类型的 JSON 数据链表;这两种类型的 JSON 数据还会有一个子数据指针*child( n5 S* M" T8 j n3 j type : 表示该 json 数据的类型,比如数字,字符串、矩阵、对象等*valuestring, valueint, valuedouble 和*string 指针分别指向该 json 数据类型具体的值,视其类型而定。* M% U5 S6 ~' h; u; @ ( B: h' ]1 P& I; r9 U7 R 使用 cjson 生成 json 数据 下面我们看看如何使用 cjson 来生成下面的数据:! ]. z. j; R. h1 }1 ? ` m; V9 Y { “reported”: { “LED”: “on”, “status” : “normal” } }9 W4 Y- R4 Q( J9 f) A6 h 见下面的代码:1 q- Z' }' l8 p0 O' w
现在就已经在 cjson 中,构件好了和前面的数据对应的数据结构。但现在这个数据结构还不能发送出去,需要调用 cJSON_Print 将其打印成串行的数据,存放在 buffer 中,以便后面进行发送。
cJSON_Print 执行的时候会向系统申请一段内存来保存串行化了的数据,并返回其指针。这里一定要注意的是,cJSON_Print中申请的内存,一定要记得释放(cjson 的代码中不会自动去做释放动作),否则就会出现内存泄漏。7 f) x( | a- P& J. F4 j0 z3 H 通过 cJSON_CreateObject 创建的对象,也需要调用 cJSON_Delete 来进行删除并释放占用的内存。否则也会出现内存泄漏。见下面的代码:
仔细的同学可能会发现为什么调用了两次 cJSON_CreateObject,但只看到释放了其中的 device_obj。这里也是需要注意的一个地方,从前面的代码中,我们可以看到,reported_obj 最终是作为子对象添加到了 device_obj 中,所以在删除 device_obj时,cJSON_Delete 会自动删除 device_obj 中所有的子对像,故而不需要再调用 cJSON_Delete 对 reported_obj 进行删除。 2 C$ _- t. y* \4 ^ 使用 cjson 解析 json 数据8 H! g G2 Y4 j8 E/ }) m8 E* @ 可以通过 cJSON_Parse()函数来解析接收到的 json 数据,cJSON_Parse()函数会对数据进行解析,并申请一段内存保存解析后的 cjson 的数据结构,并返回指针。 通过 cJSON_GetObjectItem()函数可以获取解析后的 cjson 数据结构中的第一级子对象。- k2 l4 {% a' u$ o 使用 cJSON_Parse()后,切记也一定要通过 cJSON_Delete 释放之前所申请的内存。 下面代码是对收到的 json 数据的解析过程。收到的数据内容为:% f! R# U* W0 ^, N { “desired”: {0 \1 t- P; t% T& y6 K( T0 m; {- c “LED”: “on”, “SW_Version” : “02010100”6 [2 G9 O* Q8 x2 L8 E! C }3 y, |; k# b9 [# @' M- A( V5 j3 s9 O }
总结 cJSON 代码量不大,用起来也方便。使用的时候一定要注意前面提到对使用完的内存空间进行释放。否则会造成内存泄漏。8 G5 B) E1 x% c( |! x/ J+ `5 } # C9 F! G4 ^% b9 r * H4 v% N# h7 _7 i2 t0 l- Z |
【经验分享】STM32语音识别的智能蓝牙音箱(源程序+原理图+PCB+设计说明书+PPT)
想找个ST芯片
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
技术手册stm32f1xx中的一个小问题
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
微信公众号
手机版