使用场景
项目中使用stm32f1系列芯片+FreeRTOS系统,需要解析json格式数据。
问题
在网上找到了cJson库,cJson库相对来说还是比较简单方便的,具体怎么用的,网上很多介绍,这里说一下遇到的问题:
直接引用头文件,把c文件加入工程,编译使用,但在解析某些数据的时候直接返回空指针,如下:
root = cJSON_Parse((char*)source);
if(root==cJSON_Invalid)
{
//报错
}
直接报错,有些时候又正常。后来发现跟数据长度有关,长的会报错,短的不会。所以马上想到是因为内存申请不够的原因,后面分析cJson的代码发现,它申请和释放内存是直接调用的C的标准函数malloc和free,但我们在FreeRTOS里面的内存申请和释放是要用pvPortMalloc和vPortFree的,因为FreeRTOS 的pvPortMalloc 和 C的标准函数malloc的区别是:pvPortMalloc是从configTOTAL_HEAP_SIZE中申请内存,而malloc是直接从SRAM 堆 中申请内存,是和全局变量一个地位。我们在定义操作系统的时候已经把堆占得差不多了,所以自然申请不了多少就不够用了。
解决方案
其实cJson也给出了解决方案,只是我没注意,在它的头文件中有定义:结构体cJSON_Hooks和函数cJSON_InitHooks,用这两个就可以把我们的pvPortMalloc和vPortFree函数指针替换它原来的申请和释放内存了。具体代码:
cJSON_Hooks hooks;
hooks.malloc_fn = pvPortMalloc;
hooks.free_fn = vPortFree;
cJSON_InitHooks(&hooks);
这样,只要把当前任务的stacksz(注意它*4才是实际占用的字节数哦)设置到足够大就OK了。
/* definition and creation of NetTask */
osThreadDef(NetTask, StartNetTask, osPriorityNormal, 0, 1200);
NetTaskHandle = osThreadCreate(osThread(NetTask), NULL);
我这里是1200,也就是4800字节,一般情况下的json参数设置也就够了。
最后别忘了cJSON_Delete(root);释放资源哦。
–the end–
在STM32F1系列芯片的FreeRTOS系统上使用cJSON库解析JSON数据时遇到问题,由于cJSON库内部使用malloc/free进行内存管理,与FreeRTOS的pvPortMalloc/vPortFree不兼容,导致解析长数据时返回空指针。通过定义cJSON_Hooks结构体并替换内存管理函数为FreeRTOS的函数,解决了内存申请失败的问题。确保任务栈大小足够,并使用cJSON_Delete释放资源。
1051

被折叠的 条评论
为什么被折叠?



