项目中使用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–