/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-05-29 murmur the first version */ //#include "../packages/minIni-v1.2.0/dev/minIni.h" #include "minIni.h" #include "cfg.h" #ifdef PKG_USING_MININI //#define LJW_CFG_FILE_NAME "/cfg.ini" //#define FILE_TO_SEND "/sd/tosend.ini"//避免读写出错造成系统配置文件丢失 #define LOG_TAG "cfg" #define LOG_LVL LOG_LVL_DBG #include volatile static uint8_t islock=0; static rt_mutex_t isCfgOk=RT_NULL; static rt_mutex_t isTosendOk=RT_NULL; void initCfgMutex() { isCfgOk = rt_mutex_create("isCfgOk", RT_IPC_FLAG_FIFO); isTosendOk = rt_mutex_create("isTosendOk", RT_IPC_FLAG_FIFO); } INIT_APP_EXPORT(initCfgMutex); static void setLock() { rt_mutex_take(isCfgOk, RT_WAITING_FOREVER); // LOG_W("------file locked------"); return; while(islock) { rt_thread_mdelay(1000); LOG_W("------file locked"); } islock=1; } static void clearLock() { rt_mutex_release(isCfgOk); // LOG_W("=====file unlocked====="); return; islock=0; LOG_W("------file unlocked"); } extern rt_sem_t cfgUpdate; int get_cfg(const char *k); typedef struct { char fname[60]; uint8_t index; }FILE_INFO; /** * 设置config项 * @param s * @param k * @param v * @return */ int set_cfg(const char *k, long v) { int rst = 0; if (v == get_cfg(k)) { // LOG_D("nothing needs to change."); rst = 1; } else { setLock(); // int rst = ini_puts("config",k,v,LJW_CFG_FILE_NAME); rst = ini_putl("config", k, v, LJW_CFG_FILE_NAME); clearLock(); } if (rst == 1) { // LOG_I("set value success."); } else { LOG_E("set %s value fault.",k); } return rst; } int set_cfgs(const char *k, const char * v) { int rst=0; if (strcmp(v,"NULL") == 0) {//delete key v = NULL; } char tmp[128]; get_cfgs(k,tmp); // LOG_D("v=%s-----%s",v,tmp); if (strcmp(v,tmp) == 0) { // LOG_D("nothing needs to change."); rst = 1; } else { setLock(); rst = ini_puts("config",k,v,LJW_CFG_FILE_NAME); clearLock(); } // int rst = ini_putl("config", k, v, LJW_CFG_FILE_NAME); if (rst == 1) { // LOG_I("set value success."); } else { LOG_E("set %s value fault.",k); } return rst; } /** * 返回指定键的值 * @param k * @return */ int get_cfg(const char *k) { // setLock(); // char buf[MAX_KEY_LEN]; // int rst = ini_gets("config",k,"000000",buf,MAX_KEY_LEN,LJW_CFG_FILE_NAME); // if(strcmp(buf, "000000") == 0) { // // 采用默认值 int rst = ini_getl("config", k, -3.14, LJW_CFG_FILE_NAME); if (rst == -3.14) { LOG_W("no such KEY:%s",k); // clearLock(); // return -RT_ERROR; } else { // LOG_I("%s = %s",k,buf); // LOG_I("%s = %d",k,rst); } // clearLock(); return rst; } int get_cfgs(const char *k, char *str) { // setLock(); char buf[MAX_KEY_LEN]; int rst = ini_gets("config",k,"000000",buf,MAX_KEY_LEN,LJW_CFG_FILE_NAME); if(strcmp(buf, "000000") == 0) { // // 采用默认值 // int rst = ini_getl("config", k, -1, LJW_CFG_FILE_NAME); // if (rst == -1) { LOG_W("no such KEY:%s",k); // clearLock(); return -RT_ERROR; } else { // LOG_I("%s = %s",k,buf); // LOG_I("%s = %d",k,rst); strcpy(str,buf); } // clearLock(); return rst; } static void get_cfg_all(void) { char buf[MAX_KEY_LEN]; char kstr[MAX_KEY_LEN]; LOG_I("%23s","---CONFIG---"); for (size_t k = 0; ini_getkey("config", k, kstr, MAX_KEY_LEN, LJW_CFG_FILE_NAME) > 0; k++) { int rst = ini_gets("config",kstr,"000000",buf,MAX_KEY_LEN,LJW_CFG_FILE_NAME); LOG_I("%16s = %s",kstr,buf); } } static void cfg(int argc, char ** argv) { if (argc == 1) {//无键无值,遍历 get_cfg_all(); } if (argc == 2) {//有键无值,查询 get_cfg(argv[1]); } if (argc == 3) {//有键有值,设置 set_cfgs(argv[1], argv[2]); } } static void get_sta_all(void) { char buf[MAX_KEY_LEN]; char kstr[MAX_KEY_LEN]; LOG_I("%23s","---STATS---"); for (size_t k = 0; ini_getkey("stats", k, kstr, MAX_KEY_LEN, LJW_CFG_FILE_NAME) > 0; k++) { int rst = ini_gets("stats",kstr,"000000",buf,MAX_KEY_LEN,LJW_CFG_FILE_NAME); LOG_I("%16s = %s",kstr,buf); } } //以下针对stats /** * 读取stats节信息 * @param k * return 成功返回值,错误返回RT_ERROR */ long get_val(const char *k) { // setLock(); long v= ini_getl("stats", k, -1, LJW_CFG_FILE_NAME); if( v == -1) { LOG_W("no such KEY:%s",k); // clearLock(); return -RT_ERROR; } else { // clearLock(); return v; } } int set_val(const char *k, long v) { setLock(); if(!ini_putl("stats",k,v,LJW_CFG_FILE_NAME)) { LOG_E("write %s error.",k); clearLock(); return -RT_ERROR; } clearLock(); return RT_EOK; } /** * 更新统计值,每次自加1 * @param k * @return */ int add_val(const char *k) { // setLock(); long ori = get_val(k); rt_thread_mdelay(100); if (ori != -1) { setLock(); int ret = set_val(k, ori+1); clearLock(); rt_thread_mdelay(100); return ret; } else { return ori; } // clearLock(); } static void get_sta(const char *k) { long v = get_val(k); if (!v) { LOG_I("%s = %d",k,v); } } static void sta(int argc, char ** argv) { if (argc == 1) { //无键无值,遍历 get_sta_all(); } if (argc == 2) { //有键无值,查询 get_sta(argv[1]); } if (argc == 3) { LOG_W("READ ONLY."); } } static void clear_sta(void) { char buf[16]; char kstr[16]; for (size_t k = 0; ini_getkey("stats", k, kstr, 16, LJW_CFG_FILE_NAME) > 0; k++) { if (rt_strcmp("swCnt",kstr) != 0) { set_val(kstr, NULL); } } } MSH_CMD_EXPORT_ALIAS(clear_sta,clsSta, reset sta info) volatile size_t nislock=0; static void nsetLock() { rt_mutex_take(isTosendOk, RT_WAITING_FOREVER); // LOG_W("------file locked------"); return; // LOG_D("--%d--",nislock); size_t cnt=10; while(nislock) { rt_thread_mdelay(1000); LOG_W("file is locked."); cnt += 1; if (cnt>10) { break; } } nislock=1; } static void nclearLock() { rt_mutex_release(isTosendOk); // LOG_W("=====file unlocked====="); return; nislock=0; LOG_W("file is unlocked."); } static int setFileToSend_thread_entry(void *parameter) { FILE_INFO *msg; msg=(FILE_INFO * )parameter; nsetLock(); int rst = ini_putl(SECTION_TO_SEND, msg->fname, msg->index, FILE_TO_SEND); nclearLock(); if (!rst) { LOG_E("add file to send error."); } LOG_D("add %s-%d to list.",msg->fname,msg->index); fileIsReady(); // list_thread(); // return RT_EOK; } void manualAaddlst(char *f) { nsetLock(); int rst = ini_putl(SECTION_TO_SEND, f, 0, FILE_TO_SEND); nclearLock(); if (!rst) { LOG_E("manual add file to send error."); } LOG_D("add %s-0 to list.",f); } /** * 添加待发文件到列表 * @param fin * @param index */ void postFileInfo(const char *fin, uint8_t index) { static FILE_INFO msg; strcpy(msg.fname,fin); msg.index=index; /* 创建 serial 线程 */ rt_thread_t thread = rt_thread_create("filelist", setFileToSend_thread_entry, (void *)&msg, 1024*5, 30-2, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { LOG_E("thread 'updatelist' create failure."); } } /** * 获取待发送文件列表,未减小内存占用,暂每次只读取5个 * @param kstr 待发包文件名,二维数组 * @param v 对应包文件的索引,默认为0即全发 * @return 待发文件个数 */ size_t getFilesToSend(char (*kstr)[MAX_KEY_LEN], int *v) { // char buf[MAX_KEY_LEN]; // char kstr[MAX_KEY_LEN]; // nsetLock(); size_t len=0; for (size_t k = 0; ini_getkey(SECTION_TO_SEND, k, kstr[len], MAX_KEY_LEN, FILE_TO_SEND) > 0; k++) { v[len] = ini_getl(SECTION_TO_SEND, kstr[len], -1, FILE_TO_SEND); len +=1; if (len>5) { // break; } } // nclearLock(); return len; } /** * 获取待发文件个数 * @return */ size_t getCntOfFileToSend(void) { size_t len=0; char tmp[100]; for (size_t k = 0; ini_getkey(SECTION_TO_SEND, k, tmp, sizeof(tmp), FILE_TO_SEND) > 0; k++) { len = k + 1; } // LOG_D("cnt=%d",len); return len; } /** * 清空待发送文件记录 */ int clearFileToSend(const char *k) { nsetLock(); int rst = ini_puts(SECTION_TO_SEND, k, NULL, FILE_TO_SEND); if (!rst) { LOG_E("clear file to send error."); } nclearLock(); return rst; } static void gf() { size_t cnt = getCntOfFileToSend(); // return; int v[MAX_KEY_LEN]; char kstr[cnt][MAX_KEY_LEN]; if (!cnt) { LOG_D("no files waiting to be sent"); } else { getFilesToSend(kstr, v); for (size_t var = 0; var < cnt; var++) { LOG_I("%s -- %d", kstr[var], v[var]); } } } static void add(int argc, char **argv) { if (argc == 3) { postFileInfo(argv[1],atoi(argv[2])); } // gf(); // clearFileToSend(argv[1]); // gf(); } /** * 更新最后缓存的文件 * @param k * @return */ int setLstFile(const char *fin) { nsetLock(); int rst = ini_puts(SECTION_LST_FILE, "lst", fin, FILE_TO_SEND); nclearLock(); if (!rst) { LOG_E("set lst file error."); return RT_ERROR; } return RT_EOK; } /** * 获取最后缓存的文件 * @param k * @return */ int getLstFile(const char *k) { // nsetLock(); char tmp[60]; int rst = ini_gets(SECTION_LST_FILE, "lst", "000",tmp,60, FILE_TO_SEND); if (strcmp(tmp,"000") == 0) { rst=0; } strcpy(k,tmp); // nclearLock(); return rst; } MSH_CMD_EXPORT(gf, 查看待发送文件列表) MSH_CMD_EXPORT_ALIAS(add, cf,add file to list) MSH_CMD_EXPORT(sta, check sta info) MSH_CMD_EXPORT(cfg, 配置系统参数,支持参数) //set_if() #endif