嵌入式系统配置参数存储方案

gxichun 2025-04-10 14:12:30

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#define DBG_TAG "config"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <config/config_file.h>

void backup_config(const char* fpath, const char* bak_fpath)
{
    rt_err_t result = -RT_ERROR;

    result = access(bak_fpath, F_OK|R_OK|W_OK);

    if(result == 0)//文件存在
    {
        LOG_E("backup file [%s] existed.", bak_fpath);
        if (dfs_file_unlink(bak_fpath) < 0)
        {
            LOG_E("Delete %s failed\n", bak_fpath);
            return;
        }
    }
    copy(fpath, bak_fpath);
}

void restore_config(const char* fpath, const char* bak_fpath)
{
    rt_err_t result = -RT_ERROR;

    result = access(fpath, F_OK|R_OK|W_OK);

    if(result == 0)//文件存在
    {
        rm(bak_fpath);
    }
    copy(bak_fpath, fpath);
}

rt_bool_t check_file_exist(const char* path)
{
    rt_err_t result = -RT_ERROR;

    result = access(path, F_OK/*|R_OK|W_OK*/);

    if(result == 0)//文件存在
    {
        return RT_TRUE;
    }
    return RT_FALSE;
}

struct tm * get_date_time(uint16_t year, uint8_t mon, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
{
    struct tm * time = rt_malloc(sizeof(struct tm));
    time->tm_year = year;
    time->tm_mon = mon;
    time->tm_mday = day;
    time->tm_hour = hour;
    time->tm_min = min;
    time->tm_sec = sec;
    return time;
}

char* read_config_file(const char* file_path)
{
    int fd = -1;
    int ret = -1;
    if (strstr(file_path, ".json") != RT_NULL)
    {
        /* try to open program */
        fd = open(file_path, O_RDWR, 0);
        /* search in /bin path */
        if (fd < 0)
        {
            LOG_E("settings file open error.");
            return RT_NULL;
        }
    }
    /* found script */
    char *line_buf = RT_NULL;
    int length = lseek(fd, 0L, SEEK_END);
    if(length < 0)
    {
        return RT_NULL;
    }
    line_buf =  (char *) rt_malloc(length + 1);
    if(line_buf==RT_NULL)
    {
        return RT_NULL;
    }
    lseek(fd, 0L, SEEK_SET);
    ret = read(fd, line_buf, length);
    if(ret!=length)
    {
        return RT_NULL;
    }
    close(fd);
    return line_buf;
}

rt_bool_t save_config_file(const char* path, cJSON* json_root)
{
    char* json_buf = RT_NULL;
    int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 777);//重新创建文件

    if (fd < 0)
    {
        LOG_E("open file %s failed\n", path);
        return RT_FALSE;
    }

    if(json_root==RT_NULL)
    {
        close(fd);
        return RT_FALSE;
    }

    json_buf = cJSON_Print(json_root);
    if(json_buf==RT_NULL)
    {
        close(fd);
        LOG_E("%s file cJSON_Print error.", path);
        return RT_FALSE;;
    }

    int len = strlen(json_buf);

    if (flock(fd, LOCK_EX) == -1) {
        LOG_E("%s file add lock error.", path);
        cJSON_free(json_buf);
        close(fd);
        return RT_FALSE;
    }

    if(len != write(fd, json_buf, len))
    {
        LOG_E("%s file write size error.", path);
        cJSON_free(json_buf);
        close(fd);
        return RT_FALSE;
    }

    if (flock(fd, LOCK_UN) == -1)
    { // 解锁
        LOG_E("%s file unlock error.", path);
        return RT_FALSE;
    }
    cJSON_free(json_buf);
    close(fd);
    return RT_TRUE;
}


rt_bool_t parse_general_config(cJSON* json_root, general_config_t *p_config)
{
    cJSON *general_json = NULL;
    //获取general配置项
    general_json = cJSON_GetObjectItem(json_root, "general");
    if(general_json==NULL)
    {
        return RT_FALSE;
    }
    cJSON *lang = cJSON_GetObjectItem(general_json, "lang");
    if(lang!=NULL&&cJSON_IsNumber(lang))
    {
        p_config->lang = lang->valueint;
    }

    cJSON *model = cJSON_GetObjectItem(general_json, "model");
    if(model!=NULL&&cJSON_IsString(model))
    {
        sprintf(p_config->model, "%s", model->valuestring);
    }

    cJSON *version = cJSON_GetObjectItem(general_json, "version");
    if(version!=NULL&&cJSON_IsString(version))
    {
        sscanf(version->valuestring, "%d.%d.%d",&p_config->version.major,
                &p_config->version.minor, &p_config->version.build);
    }

    cJSON *keytone = cJSON_GetObjectItem(general_json, "keytone");
    if(keytone!=NULL&&cJSON_IsNumber(keytone))
    {
        p_config->keytone = keytone->valueint;
    }
    return RT_TRUE;
}

//当前参数转换到json格式(仅配置参数)
cJSON* general_config_to_json(general_config_t *p_control)
{
    assert(p_control);

    cJSON *root = cJSON_CreateObject();
    if(root==NULL)
    {
        return NULL;
    }
    cJSON *general = cJSON_CreateObject();
    if(general!=NULL)
    {
        cJSON_AddItemToObject(root, "general", general);
    }
    cJSON_AddNumberToObject(general, "lang", p_control->lang);
    cJSON_AddStringToObject(general, "model", p_control->model);
    char temp[32];
    sprintf(temp, "%d.%d.%d", p_control->version.major,p_control->version.minor,p_control->version.build);
    cJSON_AddStringToObject(general, "version", temp);
    cJSON_AddNumberToObject(general, "keytone", p_control->keytone);

    return root;
}

//从json文件中读取电流配置
void read_general_config(const char* path, general_config_t *p_control)
{
    cJSON* json_root = RT_NULL;
    char* json_buf = RT_NULL;
    if(!check_file_exist(path))
    {
        if(check_file_exist(GENERAL_CONFIG_FILE_BAK))
        {
            restore_config(path, GENERAL_CONFIG_FILE_BAK);
        }
        else {
            reset_general_config(p_control);
            save_general_config(p_control, path);
        }
    }

    json_buf = read_config_file(path);

    if(json_buf==RT_NULL)
    {
        reset_general_config(p_control);
        save_general_config(p_control, path);
        json_buf = read_config_file(path);
    }

    json_root = cJSON_Parse(json_buf);

    if(json_root==RT_NULL)
    {
        free(json_buf);
        return ;
    }
    parse_general_config(json_root, p_control);
    if(!check_file_exist(GENERAL_CONFIG_FILE_BAK))
    {
        backup_config(path, GENERAL_CONFIG_FILE_BAK);
    }
    cJSON_free(json_root);
    free(json_buf);
}

...全文
55 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
内容概要:本文档详细介绍了微型嵌入式门禁系统的各项技术规格与工程实施标准。系统由室外单元、室内单元和控制模块组成,分别具有特定的尺寸规范与防护等级。硬件技术方面,采用了高分辨率的电容式指纹传感器和符合国际标准的射频识别单元。机械结构特性上,强调了精确的安装规范和高质量的材料工艺标准。电气性能涵盖电源管理和多种通信协议的支持。系统集成方案包括基础配置如指纹识别、IC卡读卡器,以及扩展功能如状态指示灯和应急机械钥匙仓。智能管理平台提供大容量的用户数据存储和远程管理功能。最后,文档还规定了严格的工程实施标准,确保系统在各种环境下的稳定运行,并提供了详细的可靠性测试数据和安全认证。 适合人群:从事门禁系统设计、安装及维护的技术人员,以及负责安防工程项目规划的管理人员。 使用场景及目标:①为技术人员提供详细的硬件参数和技术规格,以便进行系统选型和设计;②指导安装人员按照规范进行设备安装和布线;③帮助项目管理人员评估系统性能和安全性,确保工程顺利实施。 阅读建议:建议读者重点关注系统的关键技术参数、安装规范和可靠性测试结果,结合实际应用场景进行参考。同时,对于智能管理平台的功能,应特别关注其用户容量和远程管理能力,以满足不同规模项目的需要。

24,857

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧