项目中用到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。