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

gxichun gxichun 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

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

...全文

相关推荐

行业-电子政务-具有嵌入式EEPROM的电可编程器件及其制作方法.zip

**系统配置**:电子政务系统往往需要根据不同的应用场景进行定制化配置,如网络设置、安全参数等,嵌入式EEPROM可以方便地存储这些配置信息。2.

programcx

C2000微控制器EEPROM操作与应用实战项目

在实时控制系统中,数据的持久化存储至关重要。C2000系列微控制器凭借其高性能CPU、低延迟外设和专为控制环路优化的架构,广泛应用于电机驱动、数字电源等对可靠性要求极高的场景。系统运行中的校准参数、用户配置及故障日志需在断电后长期保存,这正是EEPROM发挥关键作用的核心领域。

红廉骑士兽

嵌入式系统/ARM技术中的嵌入式Linux的文件系统制作

这种单一执行文件的设计减少了代码重复,甚至共享了文件头、内存中的程序控制块等资源,对于资源受限的嵌入式系统来说,是一个理想的解决方案。

weixin_38687904

嵌入式Web服务器GoAhead在电力系统通信中应用

因此,对于复杂的交换功能配置,采用Goform过程能根据功能参数动态生成页面,提高用户体验并减少存储需求。

weixin_38501363

行业资料-电子功用-具有嵌入式非易失性存储器的集成电路的制作方法的说明分析.rar

微控制器与处理器:嵌入式非易失性存储器是微控制器和处理器的核心组成部分,存储程序代码和系统配置,使得设备在启动时能快速运行。2.

mYlEaVeiSmVp
评论
收藏 已收藏
分享
返回顶部
gxichun
工具平台和程序库 24,850 成员 27,330 内容