2、cjson在单片机中的主要应用


1、动态配置管理

痛点:传统配置方式需将参数硬编码在代码中,修改配置需重新编译固件,无法动态更新。

解决方案:将配置存储在JSON文件中,通过cJSON解析,增删都很方便,有较好的兼容性,支持OTA动态更新,当然还是会占一些内存。

示例代码:解析Wi-Fi配置

// config.json
{
  "wifi": {
    "ssid": "MyIoT",
    "password": "123456"
  },
  "sampling_interval": 5000
}
voidload_config(void){
    // 从Flash或SD卡读取JSON文件
    char *json_str = read_file("config.json");
    cJSON *root = cJSON_Parse(json_str);

    cJSON *wifi = cJSON_GetObjectItem(root, "wifi");
    char *ssid = cJSON_GetObjectItem(wifi, "ssid")->valuestring;
    char *password = cJSON_GetObjectItem(wifi, "password")->valuestring;
    int interval = cJSON_GetObjectItem(root, "sampling_interval")->valueint;

    printf("Wi-Fi: %s/%s, 采样间隔: %dms\n", ssid, password, interval);

    cJSON_Delete(root);
    free(json_str);
}

2、设备间通信协议

痛点:自定义二进制协议调试困难,扩展性差。

解决方案:使用JSON定义通信指令,可读性不错,方便调试扯皮,扩展性不错增删都能够较好兼容。

下面的例子是一个非常有意思的玩法,作为参数动态扩展。

示例代码:解析控制指令

// 收到指令:{"cmd": "set_led", "args": {"id": 1, "brightness": 80}}
voidhandle_command(const char *json_str){
    cJSON *root = cJSON_Parse(json_str);
    char *cmd = cJSON_GetObjectItem(root, "cmd")->valuestring;
    
    if (strcmp(cmd, "set_led") == 0) {
        cJSON *args = cJSON_GetObjectItem(root, "args");
        int id = cJSON_GetObjectItem(args, "id")->valueint;
        int brightness = cJSON_GetObjectItem(args, "brightness")->valueint;
        led_set(id, brightness);  // 实际控制函数
    }
    
    cJSON_Delete(root);
}

3、本地数据存储与日志记录

痛点:传感器数据若以二进制格式存储,导出后需专用工具解析。

解决方案:将数据序列化为JSON字符串,直接存储为文本文件。

示例代码:记录温度数据

voidlog_sensor_data(float temp, float humidity){
    cJSON *root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "temp", temp);
    cJSON_AddNumberToObject(root, "humidity", humidity);
    cJSON_AddStringToObject(root, "timestamp", "2023-08-15T14:30:00Z");
    
    char *json_str = cJSON_PrintUnformatted(root);  // 紧凑模式节省空间
    write_to_sd_card("log.json", json_str);
    
    free(json_str);
    cJSON_Delete(root);
}



3、使用过程的注意事项


1、要注意调用cJSON_Delete()free()及时的释放资源,防止内存泄漏,不然跑着跑着就奔了~。

2、想省一些内存和带宽,json相关的命名最好不要太长。

3、cjson支持

cJSON_ParseWithOpts流式解析,这在解析大型JSON时比较有用。每接收到一部分数据即可立即解析,无需等待全部数据到达,算是一种低延时的增量处理。

而且对于单片机的RAM资源有限,一次性加载大型JSON字符串可能导致内存溢出。有了流式解析后,解析完部分数据后,可立即释放相关内存,维持低内存占用。


(完结)

硬创社

还没有评论,抢个沙发!