cjson 是否能用于 STM32,如果能用,需要做哪些适配和修改?

是的,cJSON 可以用于 STM32。cJSON 是一个轻量级的 JSON 解析库,代码简洁且不依赖外部库,非常适合在资源受限的嵌入式系统(如 STM32)中使用。不过,由于 STM32 的资源有限(如 RAM 和 Flash 较小),在使用 cJSON 时需要进行一些适配和优化。


1. cJSON 的基本适配

(1)下载 cJSON 源码

从 cJSON 的官方 GitHub 仓库下载源码:
cJSON GitHub

将以下文件添加到 STM32 项目中:

  • cJSON.c

  • cJSON.h

(2)修改内存管理函数

cJSON 默认使用标准库的 malloc 和 free 进行动态内存分配,但在 STM32 中,动态内存分配可能会导致内存碎片问题。建议使用静态内存池或修改为使用 STM32 的堆内存管理函数。

修改方法:
在 cJSON.h 中,找到以下代码:

c
复制
#ifndef cJSON_malloc
#define cJSON_malloc malloc
#endif

#ifndef cJSON_free
#define cJSON_free free
#endif

将其替换为 STM32 的内存管理函数,例如:

c
复制
#include "stm32f1xx_hal.h"  // 根据你的 STM32 型号包含对应的 HAL 库

#ifndef cJSON_malloc
#define cJSON_malloc pvPortMalloc  // 如果使用 FreeRTOS
// #define cJSON_malloc malloc  // 如果使用标准库
#endif

#ifndef cJSON_free
#define cJSON_free vPortFree  // 如果使用 FreeRTOS
// #define cJSON_free free  // 如果使用标准库
#endif

如果使用静态内存池,可以自定义内存管理函数:

c
复制
static char cjson_mem_pool[1024];  // 静态内存池
static size_t cjson_mem_offset = 0;

void* cJSON_malloc(size_t size) {
    if (cjson_mem_offset + size > sizeof(cjson_mem_pool)) {
        return NULL;  // 内存不足
    }
    void* ptr = &cjson_mem_pool[cjson_mem_offset];
    cjson_mem_offset += size;
    return ptr;
}

void cJSON_free(void* ptr) {
    // 静态内存池不需要释放
    (void)ptr;
}

(3)启用浮点数支持(可选)

cJSON 默认禁用浮点数支持以节省空间。如果需要解析或生成浮点数,可以在 cJSON.h 中启用:

c
复制
#define CJSON_ENABLE_FLOATS 1

2. 优化 cJSON 以适应 STM32

(1)减少内存使用

  • 使用静态内存池代替动态内存分配,避免内存碎片。

  • 限制 JSON 数据的最大嵌套深度,减少栈空间占用:

    c
    复制
    #define CJSON_NESTING_LIMIT 10  // 根据需求调整

(2)优化性能

  • 避免频繁解析和生成 JSON 数据,尽量复用 cJSON 对象。

  • 如果 JSON 数据较大,可以分段解析或生成。

(3)裁剪功能

如果不需要某些功能(如浮点数支持、注释支持等),可以在 cJSON.h 中禁用相关宏定义以节省空间:

c
复制
#define CJSON_ENABLE_COMMENTS 0  // 禁用注释支持
#define CJSON_ENABLE_FLOATS 0    // 禁用浮点数支持

3. 在 STM32 中使用 cJSON 的示例

以下是一个简单的示例,演示如何在 STM32 中使用 cJSON 解析和生成 JSON 数据。

(1)解析 JSON 数据

c
复制
#include "cJSON.h"
#include "stm32f1xx_hal.h"
#include <stdio.h>

void parse_json(const char* json_string) {
    cJSON* root = cJSON_Parse(json_string);
    if (root == NULL) {
        printf("JSON parse error!\n");
        return;
    }

    cJSON* name = cJSON_GetObjectItem(root, "name");
    if (cJSON_IsString(name)) {
        printf("Name: %s\n", name->valuestring);
    }

    cJSON* age = cJSON_GetObjectItem(root, "age");
    if (cJSON_IsNumber(age)) {
        printf("Age: %d\n", age->valueint);
    }

    cJSON_Delete(root);
}

int main(void) {
    HAL_Init();
    SystemClock_Config();

    const char* json_string = "{\"name\":\"Alice\",\"age\":25}";
    parse_json(json_string);

    while (1) {
    }
}

(2)生成 JSON 数据

c
复制
#include "cJSON.h"
#include "stm32f1xx_hal.h"
#include <stdio.h>

void generate_json(void) {
    cJSON* root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "name", "Bob");
    cJSON_AddNumberToObject(root, "age", 30);

    char* json_string = cJSON_Print(root);
    printf("Generated JSON: %s\n", json_string);

    cJSON_free(json_string);
    cJSON_Delete(root);
}

int main(void) {
    HAL_Init();
    SystemClock_Config();

    generate_json();

    while (1) {
    }
}

4. 注意事项

  • 内存管理:在 STM32 中,动态内存分配容易导致内存碎片,建议使用静态内存池。

  • 性能优化:避免频繁解析和生成 JSON 数据,尽量复用 cJSON 对象。

  • 调试:如果使用串口输出调试信息,确保串口初始化正确。


5. 总结

cJSON 可以很好地适配 STM32,但需要根据 STM32 的资源限制进行优化:

  • 修改内存管理函数,避免动态内存分配。

  • 裁剪不需要的功能以节省空间。

  • 优化性能,避免频繁解析和生成 JSON 数据。

通过以上适配和优化,cJSON 可以在 STM32 中高效运行。如果你有更多问题,欢迎继续讨论!

 
 
 
 
 
 
posted @   FBshark  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2024-02-26 【JLC专栏】立创eda批量修改已有封装
2024-02-26 万用表用二极管档测三极管好坏
2019-02-26 Ruby 基础教程 第一部分总结
点击右上角即可分享
微信分享提示