STMCU小助手
发布时间:2022-3-4 18:36
|
前言+ \0 P2 m5 ?0 y" v/ d4 J& s 在 STM32 OTA 例程中,设备端(stm32F769 探索版)与云端交换数据使用的是 json 格式。在本篇文章中,将对 json 格式以及 Cjson 的使用及注意事项进行说明。 JSON 格式 JSON(JavaScript Object Notation)是一个轻量级的数据交换格式。既便于开发者读写,也便于机器分析和构建。它独立于开发语言,是一种文本格式,很适用描述在各个系统间交换的数据。 JSON 格式的数据看起来就像下面这个样子: { “Room1”: { “LED”: “on”,) @, Z/ G. b+ Z; S “Temperature”: “36”9 O9 U6 d7 b) G5 [2 ?8 g } }3 d) `& P7 p0 o9 ]. O6 {" J 这个 JSON 数据描述的是 Room1 的 LED 灯状态以及温度值。它由一组“名称(key)”以及对应的“ 值(value)”组成。“名称”和“ 值”间由“ :”分开。各组“名称:值”对之间由“,”符号进行分割。 ; A- [5 N8 c6 V$ B cJSON 的使用 针对不同的开发语言,网上有很多 JSON 的实现, demo 里使用的是 Cjson,版本 1.6。 将 Cjson 添加到工程5 {: _4 @. I0 a Cjson 只有一个 C 文件 Cjson.C 和一个头文件 Cjson.h。所以只需要将这两个文件拷贝到工程文件夹中,并将 Cjson.C 添加到工程中就可以了。& b5 H% V9 j9 {4 H: x2 [0 k8 \ # S* B# u1 j" c! P. I0 c, ^ y 数据结构3 z; w# W) P. E Cjson 中使用下面的数据结构来表示 JSON 数据。 4 S" N- e' D4 x5 p2 k
*next 和*prev 指针可以用来遍历“矩阵”或者“对象”类型的 JSON 数据链表;这两种类型的 JSON 数据还会有一个子数据指针*child type : 表示该 json 数据的类型,比如数字,字符串、矩阵、对象等*valuestring, valueint, valuedouble 和*string 指针分别指向该 json 数据类型具体的值,视其类型而定。 使用 cjson 生成 json 数据7 U3 F, n' b- o, G } 下面我们看看如何使用 cjson 来生成下面的数据:0 r2 m3 x: ]7 k. i" q. a {9 t. A3 b5 r4 @$ s* ?1 y “reported”: {3 F' Y2 n8 [9 {' Z# i5 ]. a% Q “LED”: “on”," c! K% [& I/ L: E “status” : “normal”$ q5 f" D4 |/ R8 l }$ s% H; G, p, L: E# J+ D) }1 V8 U( Z( ]5 B } 见下面的代码:
现在就已经在 cjson 中,构件好了和前面的数据对应的数据结构。但现在这个数据结构还不能发送出去,需要调用% ]& T) Z9 S3 o& K% B cJSON_Print 将其打印成串行的数据,存放在 buffer 中,以便后面进行发送。. w% @; m. \$ m& Z: X
cJSON_Print 执行的时候会向系统申请一段内存来保存串行化了的数据,并返回其指针。这里一定要注意的是,cJSON_Print中申请的内存,一定要记得释放(cjson 的代码中不会自动去做释放动作),否则就会出现内存泄漏。8 q% u }' \ m! ]# V4 L: j5 R4 v 通过 cJSON_CreateObject 创建的对象,也需要调用 cJSON_Delete 来进行删除并释放占用的内存。否则也会出现内存泄漏。见下面的代码:
仔细的同学可能会发现为什么调用了两次 cJSON_CreateObject,但只看到释放了其中的 device_obj。这里也是需要注意的一个地方,从前面的代码中,我们可以看到,reported_obj 最终是作为子对象添加到了 device_obj 中,所以在删除 device_obj时,cJSON_Delete 会自动删除 device_obj 中所有的子对像,故而不需要再调用 cJSON_Delete 对 reported_obj 进行删除。1 s. } B! x" d2 o9 ? . @8 R# }* ^- ~& n; F0 n1 y4 e 9 o7 n5 f+ q" V/ J+ c2 t3 { 使用 cjson 解析 json 数据; u; T$ Z/ j9 ~3 |* `! `3 X 可以通过 cJSON_Parse()函数来解析接收到的 json 数据,cJSON_Parse()函数会对数据进行解析,并申请一段内存保存解析后的 cjson 的数据结构,并返回指针。 通过 cJSON_GetObjectItem()函数可以获取解析后的 cjson 数据结构中的第一级子对象。2 a7 c& I& j7 R 使用 cJSON_Parse()后,切记也一定要通过 cJSON_Delete 释放之前所申请的内存。 下面代码是对收到的 json 数据的解析过程。收到的数据内容为: { “desired”: {* O; a: u" o$ `* E( d “LED”: “on”,; k2 [' [( ]+ m: Z6 l; ~; G “SW_Version” : “02010100”6 @2 B8 ^( K. i9 \ }% R- x1 U: ?% m* M0 K0 `4 _) | }1 j2 ^* a# o- L- d2 h- P5 H 6 A ]0 ~$ S2 Y" I
总结 cJSON 代码量不大,用起来也方便。使用的时候一定要注意前面提到对使用完的内存空间进行释放。否则会造成内存泄漏。9 U+ `! J9 `- d3 _. ] Q |
想找个ST芯片
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
技术手册stm32f1xx中的一个小问题
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
OpenSTLinux 6.1发布:M33-TD加持+安全升级,STM32MPU开发效率翻倍!
微信公众号
手机版