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

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);
}

...全文
33 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

24,860

社区成员

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

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