首页 > 编程语言 >【c&c++】 cjson使用_Keil环境下Jansson解析库的使用——基于STM32F103

【c&c++】 cjson使用_Keil环境下Jansson解析库的使用——基于STM32F103

时间:2022-11-03 10:15:54浏览次数:50  
标签:STM32F103 object Keil cjson LOG1 char json error root

前言

之前我曾经写过几个JSON解析库的使用方法:

Qt平台下使用QJson解析和构建JSON字符串

使用cJSON库解析JSON

使用cJSON库构建JSON

对于嵌入式开发,比较常用的就是cJSON解析库了,但是使用这个库对内存开销比较大,需要大量使用malloc和free进行动态内存分配和释放。对于单片机这种资源短缺的芯片来说,简直是太吃力了。使用STM32等单片机,不能解析多层JSON时,还需要调大堆栈。

今天来了解一下一个和cJSON非常类似的解析库——Jansson的使用,支持解析和构建JSON字符串,不需要动态分配内存,使用方法和cJSON几乎一样。

本文以Keil环境下的Jansson为例,介绍多种不同格式的JSON字符串解析。

示例工程下载:whik1194-JanssonDemo.rar

Jansson的安装

Jansson的安装非常简单,到Keil官网下载一个Jansson的Pack包即可: Keil.Jansson.1.0.0.pack,点击直接下载。

安装完成之后,如果要在当前项目中添加Jansson解析库,在Keil中勾选上Jansson即可,选择完成之后,在当前工程下会出现两个文件:jansson_CM3LE.libjansson_config.c

 

 

 在要使用的文件中包含头文件:#include <jansson.h>

为了方便调试,自定义实现了一个串口格式化输出函数:LOG1。

void LOG1(char *fmt,...)
{
    unsigned char UsartPrintfBuf[296];
    va_list ap;
    unsigned char *pStr = UsartPrintfBuf;
 
    va_start(ap, fmt);
    vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);                         //格式化
    va_end(ap);
 
    while(*pStr != 0)
    {
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
        USART_SendData(USART1, *pStr++);
    }
}

示例1:纯键值对

JSON字符串,包括字符串、整形和布尔类型三种类型的键值对:

{
    "status": true,
    "age": 20,
    "name": "whik1194",
    "blog": "https://blog.csdn.net/whik1194",
    "wechat": "mcu149"
}

解析函数:

uint8_t Jansson1_Demo(void)
{
    const char *text = "{"status":true,"age":20,"score":78.4,"name":"whik1194","blog":"https://blog.csdn.net/whik1194","wechat":"mcu149"}";
 
    json_error_t error;
    json_t *root;
    json_t *status;
 
    char *name, *blog, *wechat;
    int age;
    double score;
 
    root = json_loads((const char*)text, 0, &error); 
    if(json_is_object(root))
    {
        LOG1("root format correctrn");
 
        /* string 类型的解析 */
        name = (char *)json_string_value(json_object_get(root, "name"));
        blog = (char *)json_string_value(json_object_get(root, "blog"));
        wechat = (char *)json_string_value(json_object_get(root, "wechat"));
 
        LOG1("name: %srn", name);
        LOG1("blog: %srn", blog);
        LOG1("wechat: %srn", wechat);
 
        /* int 类型的解析 */
        age = json_integer_value(json_object_get(root, "age"));
        LOG1("age: %drn", age);
 
        /* double 类型的解析 */
        score = json_real_value(json_object_get(root, "score"));
        LOG1("score: %.1frn", score);
 
        /* bool 类型的解析 */
        status = json_object_get(root, "status");
        if(json_is_true(status))
            LOG1("status: truern");
        else if(json_is_false(status))
            LOG1("status: falsern");
    }
    else
    {
        printf("root format error:%d-%srn", error.line, error.text);
        return 1;
    }
    return 0;
}

运行结果: 

 

 

示例2:键的值是一个对象

JSON字符串,其中result键的值是一个JSON对象,包括几组键值对:

{
    "success": "1",
    "result": {
        "timestamp": "1592640249",
        "datetime_1": "2020-06-20 16:04:09",
        "week_1": "6",
        "week_2": "Saturday"
    }
}

解析函数:

uint8_t Jansson2_Demo(void)
{
    const char *text = "{"success":"1","result":{"timestamp":"1592640249","datetime_1":"2020-06-20 16:04:09","week_1":"6","week_2":"Saturday"}}";
    json_error_t error;
    json_t *root;
    json_t *result;
 
    char *success;
    char *timestamp;
    char *datetime_1;
    char *week_1;
 
    root = json_loads((const char*)text, 0, &error); 
    if(json_is_object(root))
    {
        LOG1("root format correctrn");
        success = (char *)json_string_value(json_object_get(root, "success"));
        LOG1("success:%srn", success);
 
        result = json_object_get(root, "result");
        if(json_is_object(result))
        {
            timestamp = (char *)json_string_value(json_object_get(result, "timestamp"));
            datetime_1 = (char *)json_string_value(json_object_get(result, "datetime_1"));
            week_1 = (char *)json_string_value(json_object_get(result, "week_1"));
 
            LOG1("timestamp:%srn", timestamp);
            LOG1("datetime_1:%srn", datetime_1);
            LOG1("week_1:%srn", week_1);
        }
        else 
        {
            LOG1("reuslt format errorrn");
            return 1;
        }
    }
    else
    {
        LOG1("root format error:%d-%srn", error.line, error.text);
        return 1;
    }
    return 0;
}

运行结果: 

 

示例3:键的值是一个数组

JSON字符串,键的值是一个JSON数组,包含两个JSON对象:

{
    "location": [{
        "name": "Faye",
        "address": "Beijing"
    }, {
        "name": "Andy",
        "address": "ShangHai"
    }, {
        "name": "Lisa",
        "address": "ShenZhen"
    }],
    "time": "2018-11-17"
}

解析函数:

uint8_t Jansson3_Demo(void)
{
    const char *text = "{"location":[{"name":"Faye","address":"Beijing"},{"name":"Andy","address":"ShangHai"},{"name":"Lisa","address":"ShenZhen"}],"time":"2018-11-17"}";
 
    json_error_t error;
    json_t *root;
    json_t *location_arr;
    json_t *location;
 
    char *name, *address;
    char *time;
    int idx;
 
    root = json_loads((const char*)text, 0, &error); 
    if(json_is_object(root))
    {
        LOG1("root format correctrn");
        time = (char *)json_string_value(json_object_get(root, "time"));
        location_arr = json_object_get(root, "location");
        if(json_is_array(location_arr))
        {
            for(idx = 0; idx < json_array_size(location_arr); idx++)
            {
                location = json_array_get(location_arr, idx);
                name = (char *)json_string_value(json_object_get(location, "name"));
                address = (char *)json_string_value(json_object_get(location, "address"));
                LOG1("%d: %s-%srn", idx, name, address);
            }
        }
    }
    else
    {
        LOG1("root format error:%d-%srn", error.line, error.text);
        return 1;
    }
    return 0;
}

运行结果: 

 

 

注意

如果出现解析失败,或者解析错误,可以尝试增加Heap_Size大小: 

 

 不知道是不是编码的问题,Jansson并不支持含有中文的JSON字符串解析,会报格式错误。

 

标签:STM32F103,object,Keil,cjson,LOG1,char,json,error,root
From: https://www.cnblogs.com/opensmarty/p/16853469.html

相关文章

  • Keil历史版本的几种下载方法
    Keil历史版本的几种下载方法MDKlegacyC51keil简单介绍官网正规步骤下载网址直接下载1.KeilMDK有规律的下载地址2.KeilC51有规律的下载地址3.KeilC251有规律的下载地址4......
  • [单片机][cx32][boot] boot配置 中断向量表 跳转 keil5
    boot第一步:keil配置第二步:生产bin文件$K\ARM\ARMCC\bin\fromelf.exe--bin--output=.\out\[email protected]!L第三步:优化代码第四步:编写跳转代码/******************************......
  • [keil][python][单片机] keil 集成bin文件生成 boot+app合并 dfu生成
    一、首先配置keil执行工具.\file_handling.bat@L!L$K输出文件名根据自身定义参数名注释@L输出文件名(上图所示位置)!L输出文件名.axf$Kkeil路径二、编写bat脚本(此处......
  • STMicroelectronics STM32F103C8
    STMicroelectronics STM32F103C8ARMCortex-M3,72MHz,64kBROM,20kBRAMSTMicroelectronics'STM32F1seriesofmainstreamMCUscoverstheneedsofalar......
  • 问题:keil使用局部变量出错
    发现在中断程序里定义变量容易出未知性错误://对count,sec计数voidtimer0()interrupt1{ staticunsignedcharcount=0; //unsignedcharK=0;//放这里没问题,定......
  • AT24C02 by stm32f103 hal
    AT24C02是一款拥有256bytes(32Page)的EEPROM.一:特点(部分)1:双线接口;2:双向数据传输协议;3:400KHz波特率;4:硬件写保护;5:最大5ms写入同步;6:100万次写操作;7:100年数据存储。......
  • keil提示:unprintable character 0xA1 skipped
    我将代码全部复制到其他编程软件:总结:keil提示这个的时候,直接把这行删了重新写......
  • STM32L4 Keil ST-Link 连接失败
    ST-LINK连接失败的问题有两种,一个是驱动问题,一个是插线问题。连接正常的情况如下图所示,SWDIO能显示你的设备信息:注意使用SW端口,JTAG端口导致无法识别设备。还有一个......
  • keil 里面的枚举变量被装换为uint8_t
    在调试lorawan代码时,发现枚举变量被强行转换成了uint8_t类型。typedefenum{MCU_PINS,IOE_PINS,//NotconnectedNC=(int)0xFFFFFFFF}PinNames......
  • QEMU 仿真模拟 STM32 最小开发板 STM32F103
    软件介绍QEMU是一款开源虚拟机,可以用来模拟各种系统开发板,当然也可以用来模拟stm32的开发板QEMU官方说明文档在此https://www.qemu.org/docs/master/system/ar......