cJSON移植到STM32

2023-11-17

项目中用到JSON接收网络数据,具体是STM32串口接收JSON数据,提取需要的内容。

本来KEIL MDK是自带JSON的,但是我不习惯使用KEIL自带的那些第三方的东西,很杂乱的感觉。

cJSON的移植比较简单,一下子就可以搞定。

1.下载源文件。

http://sourceforge.net/projects/cjson/

只需要两个文件cJSON.c,cJSON.h;下载的包里面还有一个test.c,里面是测试的例子。

http://www.json.org/json-zh.html

这个是JSON的中文说明,明了清晰。

2.实现内存管理接口。

这个可以直接使用原子的Malloc.c,Malloc.h,并修改合适的管理内存大小MEM_MAX_SIZE。

3.修改源代码

将cJSON.c里面所有的malloc何free为自定义内存管理函数。注意是所有。

4.测试。

下载的包里面test.c里面有很多例子,可以拿来测试。

4.1

这个是解析JSON字符串的:

/* Parse text to JSON, then render back to text, and print! */
void doit(char *text)
{
    char *out;cJSON *json;
    
    json=cJSON_Parse(text);
    if (!json) {printf("Error before: [%s]\n",cJSON_GetErrorPtr());}
    else
    {
        out=cJSON_Print(json);
        cJSON_Delete(json);
        printf("%s\n",out);
        myfree(out);
    }
}

使用PC串口根据和STM32的串口测试一段字符串:

接收的文本为

{
	"a":	"1",
	"b":	{
		"a1":	1.100000
	}
}

故意发送弄个不合规范的试试:

4.2

还有生成JSON的代码:

/* Used by some code below as an example datatype. */
struct record {const char *precision;double lat,lon;const char *address,*city,*state,*zip,*country; };

/* Create a bunch of objects as demonstration. */
void create_objects()
{
    cJSON *root,*fmt,*img,*thm,*fld;char *out;int i;    /* declare a few. */
    /* Our "days of the week" array: */
    const char *strings[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
    /* Our matrix: */
    int numbers[3][3]={{0,-1,0},{1,0,0},{0,0,1}};
    /* Our "gallery" item: */
    int ids[4]={116,943,234,38793};
    /* Our array of "records": */
    struct record fields[2]={
        {"zip",37.7668,-1.223959e+2,"","SAN FRANCISCO","CA","94107","US"},
        {"zip",37.371991,-1.22026e+2,"","SUNNYVALE","CA","94085","US"}};

    /* Here we construct some JSON standards, from the JSON site. */
        
    printf("\r\n ***start***%d%% \r\n",mem_perused());
    /* Our "Video" datatype: */
    root=cJSON_CreateObject();    
    cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
    cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
    cJSON_AddStringToObject(fmt,"type",        "rect");
    cJSON_AddNumberToObject(fmt,"width",        1920);
    cJSON_AddNumberToObject(fmt,"height",        1080);
    cJSON_AddFalseToObject (fmt,"interlace");
    cJSON_AddNumberToObject(fmt,"frame rate",    24);
    
    out=cJSON_Print(root);    cJSON_Delete(root);    printf("%s\n",out);    myfree(out);    /* Print to text, Delete the cJSON, print it, release the string. */

    /* Our "days of the week" array: */
    root=cJSON_CreateStringArray(strings,7);

    out=cJSON_Print(root);    cJSON_Delete(root);    printf("%s\n",out);    myfree(out);

    /* Our matrix: */
    root=cJSON_CreateArray();
    for (i=0;i<3;i++) cJSON_AddItemToArray(root,cJSON_CreateIntArray(numbers[i],3));

/*    cJSON_ReplaceItemInArray(root,1,cJSON_CreateString("Replacement")); */
    
    out=cJSON_Print(root);    cJSON_Delete(root);    printf("%s\n",out);    myfree(out);


    /* Our "gallery" item: */
    root=cJSON_CreateObject();
    cJSON_AddItemToObject(root, "Image", img=cJSON_CreateObject());
    cJSON_AddNumberToObject(img,"Width",800);
    cJSON_AddNumberToObject(img,"Height",600);
    cJSON_AddStringToObject(img,"Title","View from 15th Floor");
    cJSON_AddItemToObject(img, "Thumbnail", thm=cJSON_CreateObject());
    cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943");
    cJSON_AddNumberToObject(thm,"Height",125);
    cJSON_AddStringToObject(thm,"Width","100");
    cJSON_AddItemToObject(img,"IDs", cJSON_CreateIntArray(ids,4));

    out=cJSON_Print(root);    cJSON_Delete(root);    printf("%s\n",out);    myfree(out);

    /* Our array of "records": */

    root=cJSON_CreateArray();
    for (i=0;i<2;i++)
    {
        cJSON_AddItemToArray(root,fld=cJSON_CreateObject());
        cJSON_AddStringToObject(fld, "precision", fields[i].precision);
        cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat);
        cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon);
        cJSON_AddStringToObject(fld, "Address", fields[i].address);
        cJSON_AddStringToObject(fld, "City", fields[i].city);
        cJSON_AddStringToObject(fld, "State", fields[i].state);
        cJSON_AddStringToObject(fld, "Zip", fields[i].zip);
        cJSON_AddStringToObject(fld, "Country", fields[i].country);
    }
    
/*    cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root,1),"City",cJSON_CreateIntArray(ids,4)); */
    printf("\r\n ***mem***%d%% \r\n",mem_perused());
    out=cJSON_Print(root);    cJSON_Delete(root);    printf("%s\n",out);    myfree(out);
    printf("\r\n ***end***%d%% \r\n",mem_perused());
}

其中函数mem_perused()为获取管理内存的使用率函数。

因为之前看网上有人移植后内存出现问题,估计是没有使用正确的内存释放函数。而这里,经过上百次连续使用,内存使用没有问题。如下:

	 ***start***0% 
{
	"name":	"Jack (\"Bee\") Nimble",
	"format":	{
		"type":	"rect",
		"width":	1920,
		"height":	1080,
		"interlace":	false,
		"frame rate":	24
	}
}
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
[[0, -1, 0], [1, 0, 0], [0, 0, 1]]
{
	"Image":	{
		"Width":	800,
		"Height":	600,
		"Title":	"View from 15th Floor",
		"Thumbnail":	{
			"Url":	"http:/*www.example.com/image/481989943",
			"Height":	125,
			"Width":	"100"
		},
		"IDs":	[116, 943, 234, 38793]
	}
}

 ***mem***12% 
[{
		"precision":	"zip",
		"Latitude":	37.766800,
		"Longitude":	-122.395900,
		"Address":	"",
		"City":	"SAN FRANCISCO",
		"State":	"CA",
		"Zip":	"94107",
		"Country":	"US"
	}, {
		"precision":	"zip",
		"Latitude":	37.371991,
		"Longitude":	-122.026000,
		"Address":	"",
		"City":	"SUNNYVALE",
		"State":	"CA",
		"Zip":	"94085",
		"Country":	"US"
	}]

 ***end***0% 

我的管理内存总共为16K,一开始使用率为0%,中间出现过使用率为12%,最后完全释放,又恢复0%。循环测试几百遍都OK。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cJSON移植到STM32 的相关文章

  • 在地址“0xXXXXXX”处中断,没有可用的调试信息,或在程序代码之外

    配置 使用 Nucleo L476RG 使用 GNU ARM Eclipse 我从 STM32CubeMX 生成了一个极简代码 我已经在我的板载 ST Link 中刷新了 J link 驱动程序 一直在尝试为我的代码运行调试器 但我的程序计
  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • 当数据大小较小时,内存到内存 DMA 传输是否需要权衡?

    我正在学习 STM32 F4 微控制器 我正在尝试找出使用 DMA 的限制 根据我的理解和研究 我知道如果数据量较小 即设备使用DMA生成或消耗少量数据 则开销会增加 因为DMA传输需要DMA控制器执行操作 从而不必要地增加系统成本 我做了
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • rt-thread studio中新建5.0不能用

    文章目录 一 版本对比 二 文件和文件夹打斜杠 在使用RT Thread studio创建新工程5 0版本的时候 结果发现新建完成之后程序不能正常运行 但是创建4 10版本的时候却能运行 那肯定是新版本出现了BUG 一 版本对比 首先对比了
  • 匹配 STM32F0 和 zlib 中的 CRC32

    我正在研究运行 Linux 的计算机和 STM32F0 之间的通信链路 我想对我的数据包使用某种错误检测 并且由于 STM32F0 有 CRC32 硬件 并且我在 Linux 上有带有 CRC32 的 zlib 所以我认为在我的项目中使用
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE

随机推荐

  • Loaded runtime CuDNN library: 8.0.5 but source was compiled with: 8.1.0. CuDNN library needs to hav

    2021 08 16 Loaded runtime CuDNN library 8 0 5 but source was compiled with 8 1 0 CuDNN library needs to have matching ma
  • 行业经验

    原文地址 http www blogjava net ITdavid archive 2008 01 21 176730 html 很多职场新人都谈到了工作经验的问题 似乎招聘公司不给你机会 你就没办法获得必要的工作经验 其实并不一定 很多
  • 前端用js实现粘贴图片实现上传图片功能

    前端实现粘贴复制图片 引入实现粘贴复制功能的外部js文件 设置放置图片的盒子 监听粘贴事件 实现上传功能 粘贴即上传 实现效果截图 引入实现粘贴复制功能的外部js文件 引入复制的外部js文件 设置放置图片的盒子 给放置图片的盒子设置可编辑里
  • React (七)

    React 组件 API 在本章节中我们将讨论 React 组件 API 我们将讲解以下7个方法 设置状态 setState 替换状态 replaceState 设置属性 setProps 替换属性 replaceProps 强制更新 fo
  • Qt5.15.2安装

    解释一下 Qt 的版本号 比如 5 15 2 是完整的 Qt 版本号 第一个数字 5 是大版本号 major 第二个数字 15 是小版本号 minor 第三个数字 2 是补丁号 patch 只要前面两个数字相同 Qt 的特性就是一致的 最后
  • Jenkins (二)

    Jenkins 二 使用pipeline script 简单编译 发布war工程到远程tomcat中 配置所需 下载 apache maven 3 9 3 tar gz 解压 apache maven 3 9 3 bin tar gz 拷贝
  • XP 和 win10 系统 bios配制

    因搞嵌入式 家里有好多老式MCU 用到XP系统相关的编译器和相关的调试工具 专门买了台X230 配两个硬盘XP和win10 发现BIOS配置不一样 在这里记录一下 1 config 下面的 serial ATA 系统 serial ATA
  • 工作流选型

    对比 Activiti Flowable
  • 什么是护网(HVV)_需要什么技能?

    HVV介绍 1 什么是护网 护网的定义是以国家组织组织事业单位 国企单位 名企单位等开展攻防两方的网络安全演习 进攻方一个月内采取不限方式对防守方展开进攻 不管任何手段只要攻破防守方的网络并且留下标记即成功 直接冲到防守方的办公大楼 然后物
  • spring-boot 实现定时任务@Scheduled

    Scheduled 只适合处理简单的计划任务 不能处理分布式计划任务 优势 是spring框架提供的计划任务 开发简单 执行效率比较高 且在计划任务数量太多的时候 可能出现阻塞 崩溃 延迟启动等问题 启动类中加入 EnableSchedul
  • 【转载】Linux 之 makefile详细教程

    什么是makefile 或许很多Winodws的程序员都不知道这个东西 因为那些Windows的IDE都为你做了这个工作 但我觉得要作一个好的和 professional的程序员 makefile还是要懂 这就好像现在有这么多的HTML的编
  • docker run -it 和 docker exec -it具有什么功能呢?

    Docker Docker是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中 然后发布到任何流行的 Linux或Windows操作系统的机器上 也可以实现虚拟化 容器是完全使用沙箱机制 相互之间不会有任何接口
  • 有关联想拯救者Y7000重装window10系统

    文章目录 1 联想拯救者使用U盘重装系统不需要进入bios 2 总结 由于C盘爆满了 所以选择重装系统来重新给C盘分下区 给C盘分大点 然后重装系统的具体流程参照的是博客使用U盘重装Windows10系统详细步骤及配图 官方纯净版 然后写这
  • 03 什么是预训练(Transformer 前奏)

    博客配套视频链接 https space bilibili com 383551518 spm id from 333 1007 0 0 b 站直接看 配套 github 链接 https github com nickchen121 Pr
  • 20145334赵文豪《网络对抗》—— 网络欺诈技术防范

    1 实验后回答问题 1 通常在什么场景下容易受到DNS spoof攻击 局域网内的攻击 连接公共场所的wifi 2 在日常生活工作中如何防范以上两种攻击方法 输入个人信息前 仔细检查核对域名是否正确 使用入侵检测系统 使用防火墙进行保护 d
  • 关闭bat运行python时的chromedriver窗口

    运行python 查看三方库的安装位置 打开文件位置 默认conda在这里 找到selenium webdriver common service py 添加依赖 修改70行左右代码 self process subprocess Pope
  • 深度学习之心得——dropout

    作用 防止过拟合 什么时候过拟合 网络参数多 训练数据少的时候 容易过拟合 原理 前向传播过程中暂时屏蔽一些节点 暂时不更新它的参数 这样就可以训练多个不同的网络 降低过拟合的可能 Dropout层的位置 Dropout一般放在全连接层防止
  • python垃圾回收 (GC) 机制

    Python 能够自动进行内存分配和释放 但了解 python 垃圾回收 garbage collection GC 的工作原理可以帮助你写出更好更快的 Python 程序 Python 使用两种算法进行垃圾回收 分别是引用计数 Refer
  • 六、Kafka consumer及ConsumerRebalanceListener实现

    1 comsumer代码示例 public class ConsumerMessage private static final String TOPIC NAME topic 07 public static void main Stri
  • cJSON移植到STM32

    项目中用到JSON接收网络数据 具体是STM32串口接收JSON数据 提取需要的内容 本来KEIL MDK是自带JSON的 但是我不习惯使用KEIL自带的那些第三方的东西 很杂乱的感觉 cJSON的移植比较简单 一下子就可以搞定 1 下载源