解决STM32+cJSON+FreeRTOS中解析或者输出的结果为NULL的问题

硬件平台 STM32F103ZET6
开发工具KEIL5
任务堆栈1024
程序逻辑:每秒构造一个json字符串,然后用串口发出去。
问题描述:刚开始的几分钟可以,之后就出现了问题,每次在构造玩json后调用cJSON_PrintUnformatted函数总是返回NULL。系统也不崩溃。该任务剩余堆栈888.

问题排查,先跟踪cJSON_PrintUnformatted源代码,每个节点都创建成功,但是在最后组成总体json字符串时申请内存空间失败,导致了每次返回都是NULL。
检查代码的内存释放部分发现,调用的free函数,使用FreeRTOS后应该使用vPortFree函数来释放内存的。
修改为vPortFree函数后再次测试,问题未再出现。 特此记录

关于cJSON中使用FreeRTOS来管理内存的修改部分如下:
修改内容都在cjson.c中

修改点一:
static void *(*cJSON_malloc)(size_t sz) = pvPortMalloc;
static void (*cJSON_free)(void *ptr) = vPortFree;
修改点二:
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
    if (!hooks) { /* Reset hooks */
        cJSON_malloc = pvPortMalloc;
        cJSON_free = vPortFree;
        return;
    }
	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:pvPortMalloc;
	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:vPortFree;
}

### 使用cJSONFreeRTOS环境下的内存分配 在FreeRTOS环境中使用cJSON时,为了确保内存管理和线程安全性的正确处理,应当通过`cJSON_InitHooks`函数自定义内存分配器。默认情况下,cJSON采用标准库中的`malloc`和`free`进行动态内存管理;然而,在实时操作系统(RTOS)环境下,尤其是像FreeRTOS这样的系统中,推荐使用由该操作系统提供的特定API来代替这些通用函数。 对于FreeRTOS而言,可以利用其内置的`pvPortMalloc`作为替代`malloc`的方式用于分配内存,并用`vPortFree`取代`free`完成资源回收工作[^2]。下面展示了一个初始化过程的例子: ```c #include "cjson.h" // ...其他必要的头文件... void Init_cJSON_with_FreeRTOS() { cJSON_Hooks cJsonNhooks_freeRTOS; cJsonNhooks_freeRTOS.malloc_fn = pvPortMalloc; // 设置为FreeRTOS的内存分配函数 cJsonNhooks_freeRTOS.free_fn = vPortFree; // 设置为FreeRTOS的内存释放函数 cJSON_InitHooks(&cJsonNhooks_freeRTOS); // 初始化挂钩以覆盖默认行为 } ``` 此配置允许应用程序充分利用FreeRTOS内核所提供的特性,比如更精确地控制堆栈大小以及更好地适应多任务调度需求。此外,这样做还可以避免因不同组件间共享同一套不兼容的内存管理机制而导致潜在冲突或不稳定现象的发生[^3]。 当创建新的JSON对象实例时,只需按照常规流程调用相应构造函数即可,无需额外考虑底层实现细节。例如,要建立一个简单的字符串数组结构体并遍历输出其中的内容,可参照如下代码片段: ```c cJSON *root = cJSON_CreateArray(); if (NULL == root) { // 错误处理逻辑... } char const *items[] = {"123456", "nihaihaoma", "jintianxingqiwule"}; for(size_t idx=0u ; idx<sizeof(items)/sizeof(*items) ; ++idx){ cJSON_AddItemToArray(root, cJSON_CreateString(items[idx])); } /* 遍历打印 */ printf("Array elements:\n"); for(int i = 0; i < cJSON_GetArraySize(root); ++i){ printf("%s\n", cJSON_GetArrayItem(root,i)->valuestring); } // 清理不再使用的节点 cJSON_Delete(root); ``` 上述程序段展示了如何在一个基于FreeRTOS的应用场景下高效且稳定地运用cJSON库执行基本的数据序列化/反序列化操作[^5]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值