/* */ #include #include #include #include #include #include #include #include "nvs_eepom.h" // #define LOG_TAG "DB" // 该模块对应的标签。不定义时,默认:NO_TAG #define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别 #include // 必须在 LOG_TAG与LOG_LVL下面 #define file_path "data/db.bin" /* https://c.biancheng.net/view/2071.html https://c.biancheng.net/view/399.html 1、文件的打开:fopen() 用法:fopen("文件位置","打开方式"); "r":以只读方式打开文本文件 "r+":以读写方式打开文本文件 "rb":以只读方式打开二进制文件 "rb+":以读写方式打开二进制文件 "w":以写的方式新建文本文件(会覆盖同名文件) "w+":以读写方式新建文本文件(会覆盖同名文件) "wb":以写的方式新建二进制文件(会覆盖同名文件) "wb+":以读写方式新建二进制文件(会覆盖同名文件 不存在则新建) "a":以"尾部追加"写的方式打开文本文件 "a+":以"尾部追加"读写的方式打开文本文件 "ab":以"尾部追加"写的方式打开二进制文件 "ab+":以"尾部追加"读写的方式打开二进制文件 2、文件的关闭:fclose() 用来把打开的文件关闭,当进行写操作后,会将所写内容存入缓冲区,关闭文件或者程序运行结束后才会写入文件中 3、文件读fread() size_t fread ( void *ptr, size_t size, size_t count, FILE *fp ); 函数用来从指定文件中读取块数据。所谓块数据,也就是若干个字节的数据,可以是一个字符,可以是一个字符串,可以是多行数据,并没有什么限制。fread() 的原型为: 4、文件写fwrite() size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp ); 函数用来向文件中写入块数据,它的原型为: 对参数的说明: ptr 为内存区块的指针,它可以是数组、变量、结构体等。fread() 中的 ptr 用来存放读取到的数据,fwrite() 中的 ptr 用来存放要写入的数据。 size:表示每个数据块的字节数。 count:表示要读写的数据块的块数。 fp:表示文件指针。 理论上,每次读写 size*count 个字节的数据。 */ static void nvs_eepom_sysInfo_factoryinfo(void); nvs_Sys_Info nvs_SysInfo; static void show_speed(char *msg, u32 len, u32 us) { u32 tmp, speed; /* Split to serval step to avoid overflow */ tmp = 1000 * len; tmp = tmp / us; tmp = 1000 * tmp; speed = tmp / 1024; printf("%s: %d byte, %d us -> %d KB/s\n", msg, len, us, speed); } static int nvs_EEPOM_write_SysInfo_flash(void) { // "w+"以“写入/更新”方式打开文件,相当于w和r+叠加的效果。既可以读取也可以写入,也就是随意更新文件。 // 如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件) FILE *fp=NULL; do{ fp = fopen(file_path, "wb+");//打开二进制文件 if (fp == NULL) { printf("write Open file %s failed!\n", file_path); //重新创建 printf("write create new file %s!\n", file_path); } }while(!fp); printf("write Open file %s suss!\n", file_path); //写入数据 uint32_t start_us = aic_get_time_us(); if (sizeof(nvs_SysInfo) != fwrite(&nvs_SysInfo, sizeof(char), sizeof(nvs_SysInfo), fp)) { printf("Fs write data failed!"); goto write_err; } show_speed("Filesystem write speed", sizeof(nvs_SysInfo), aic_get_time_us() - start_us); write_err: //关闭文件 fclose(fp); return 1; } static int nvs_EEPOM_read_SysInfo_flash(void) { FILE *fp=NULL; //"r":以“只读”方式打开文件。只允许读取,不允许写入。文件必须存在,否则打开失败 fp = fopen(file_path, "rb");//打开二进制文件 if (fp == NULL) { printf("read Open file %s failed!\n", file_path); return 0; } printf("read Open file %s suss!\n", file_path); //读取数据 uint32_t start_us = aic_get_time_us(); if (sizeof(nvs_SysInfo) != fread(&nvs_SysInfo, sizeof(char), sizeof(nvs_SysInfo), fp)) { printf("Fs read data failed!\n"); goto read_err; } show_speed("Filesystem read speed", sizeof(nvs_SysInfo), aic_get_time_us() - start_us); read_err: //关闭文件 fclose(fp); return 1; } static void nvs_eepom_sysInfo_factoryinfo(void)//出厂设置 { memset(&nvs_SysInfo,0,sizeof(nvs_SysInfo)); nvs_SysInfo.flag=0x55; #if defined(CONFIG_USER_RELAY_4) nvs_SysInfo.language=LANG_EN;//LANG_CH //#elif defined(CONFIG_USER_RELAY_1)||defined(CONFIG_USER_RELAY_3) #else nvs_SysInfo.language=LANG_EN; #endif //------------------------------------------------- #if defined(CONFIG_USER_RELAY_1) nvs_SysInfo.totalrelay=RELAY_1gang; nvs_SysInfo.currentrelay=RELAY_1gang; nvs_SysInfo.relay1.port=1; nvs_SysInfo.relay2.port=2; #elif defined(CONFIG_USER_RELAY_2) nvs_SysInfo.totalrelay=RELAY_2gang; nvs_SysInfo.currentrelay=RELAY_2gang; nvs_SysInfo.relay1.port=1; nvs_SysInfo.relay2.port=2; #elif defined(CONFIG_USER_RELAY_3) nvs_SysInfo.totalrelay=RELAY_3gang; nvs_SysInfo.currentrelay=RELAY_3gang; nvs_SysInfo.relay1.port=1; nvs_SysInfo.relay2.port=2; nvs_SysInfo.relay3.port=3; #elif defined(CONFIG_USER_RELAY_4) nvs_SysInfo.totalrelay=RELAY_4gang; nvs_SysInfo.currentrelay=RELAY_4gang; nvs_SysInfo.relay1.port=1; nvs_SysInfo.relay2.port=2; nvs_SysInfo.relay3.port=3; nvs_SysInfo.relay4.port=4; #endif nvs_SysInfo.firstmode=FIRST_SWITCH; //------------------------------------------------- nvs_SysInfo.backlight=100; nvs_SysInfo.autobacklight=1;//自动亮度是否开启(功能改为屏保是否启用) nvs_SysInfo.autoupdatetime=1; nvs_SysInfo.autoScreentime=30;//默认30s nvs_SysInfo.subdevice_array[3]=1; //默认显示场景开关4路 memcpy(nvs_SysInfo.tzzone,(const char *)"GMT-8",strlen((const char *)"GMT-8")); } static void nvs_eepom_sysInfo_factory(void)//出厂设置 { nvs_eepom_sysInfo_factoryinfo(); nvs_EEPOM_write_SysInfo_flash(); } void nvs_eepom_sysInfo_update(void)//更新 { nvs_EEPOM_write_SysInfo_flash(); } static void nvs_eepom_sysInfo_Init(void) { rt_kprintf("nvs_SysInfo:%d\r\n",sizeof(nvs_SysInfo)); memset(&nvs_SysInfo,0,sizeof(nvs_SysInfo)); nvs_EEPOM_read_SysInfo_flash(); //if( (nvs_SysInfo.flag!=0x55)||(nvs_SysInfo.language>=LANG_MAX)||(nvs_SysInfo.ssid[0]>0x7F)||(nvs_SysInfo.password[0]>0x7F) ) if( (nvs_SysInfo.flag!=0x55) ||(nvs_SysInfo.backlight<=0x09) ||(nvs_SysInfo.language>=LANG_MAX) ) { rt_kprintf("SysInfo factory\r\n"); nvs_eepom_sysInfo_factory(); //vTaskDelay(pdMS_TO_TICKS(2000)); } //上电根据上电状态设置是不是:断电记忆 断电 通电 默认断电 #if defined(CONFIG_USER_RELAY_1) nvs_SysInfo.relay1.status |=relayfirst_powerflag;//bit7=1是上电标记 #elif defined(CONFIG_USER_RELAY_2) nvs_SysInfo.relay1.status |=relayfirst_powerflag;//bit7=1是上电标记 nvs_SysInfo.relay2.status |=relayfirst_powerflag;//bit7=1是上电标记 #elif defined(CONFIG_USER_RELAY_3) nvs_SysInfo.relay1.status |=relayfirst_powerflag;//bit7=1是上电标记 nvs_SysInfo.relay2.status |=relayfirst_powerflag;//bit7=1是上电标记 nvs_SysInfo.relay3.status |=relayfirst_powerflag;//bit7=1是上电标记 #elif defined(CONFIG_USER_RELAY_4) nvs_SysInfo.relay1.status |=relayfirst_powerflag;//bit7=1是上电标记 nvs_SysInfo.relay2.status |=relayfirst_powerflag;//bit7=1是上电标记 nvs_SysInfo.relay3.status |=relayfirst_powerflag;//bit7=1是上电标记 nvs_SysInfo.relay4.status |=relayfirst_powerflag;//bit7=1是上电标记 #endif // rt_thread_mdelay(500); nvs_eepom_sysInfo_update();//更新一次上电标记 使用后删除(第一次显示) rt_kprintf("backlight:0x%02X\r\n",nvs_SysInfo.backlight); rt_kprintf("relay1.status:0x%02X\r\n",nvs_SysInfo.relay1.status); rt_kprintf("relay2.status:0x%02X\r\n",nvs_SysInfo.relay2.status); rt_kprintf("relay3.status:0x%02X\r\n",nvs_SysInfo.relay3.status); rt_kprintf("relay4.status:0x%02X\r\n",nvs_SysInfo.relay4.status); rt_kprintf("relay1.relay:0x%02X\r\n",nvs_SysInfo.relay1.relay); rt_kprintf("relay2.relay:0x%02X\r\n",nvs_SysInfo.relay2.relay); rt_kprintf("relay3.relay:0x%02X\r\n",nvs_SysInfo.relay3.relay); rt_kprintf("relay4.relay:0x%02X\r\n",nvs_SysInfo.relay4.relay); rt_kprintf("relay1.Label:%s\r\n",nvs_SysInfo.relay1.Label); rt_kprintf("relay2.Label:%s\r\n",nvs_SysInfo.relay2.Label); rt_kprintf("relay3.Label:%s\r\n",nvs_SysInfo.relay3.Label); rt_kprintf("relay4.Label:%s\r\n",nvs_SysInfo.relay4.Label); rt_kprintf("relay1.icon:0x%x\r\n",(uint32_t)nvs_SysInfo.relay1.icon); rt_kprintf("relay2.icon:0x%x\r\n",(uint32_t)nvs_SysInfo.relay2.icon); rt_kprintf("relay3.icon:0x%x\r\n",(uint32_t)nvs_SysInfo.relay3.icon); rt_kprintf("relay4.icon:0x%x\r\n",(uint32_t)nvs_SysInfo.relay4.icon); rt_kprintf("language:%d\r\n",nvs_SysInfo.language); rt_kprintf("firstmode:%d\r\n",nvs_SysInfo.firstmode); rt_kprintf("backlight:%d\r\n",GET_nvs_Sys_Info_backlight()); rt_kprintf("downlights[0].GroupID:0x%x\r\n",nvs_SysInfo.downlights[0].GroupID); rt_kprintf("downlights[1].GroupID:0x%x\r\n",nvs_SysInfo.downlights[1].GroupID); rt_kprintf("downlights[2].GroupID:0x%x\r\n",nvs_SysInfo.downlights[2].GroupID); rt_kprintf("downlights[3].GroupID:0x%x\r\n",nvs_SysInfo.downlights[3].GroupID); rt_kprintf("curtains[0].GroupID:0x%x\r\n",nvs_SysInfo.curtains[0].GroupID); rt_kprintf("curtains[1].GroupID:0x%x\r\n",nvs_SysInfo.curtains[1].GroupID); rt_kprintf("curtains[2].GroupID:0x%x\r\n",nvs_SysInfo.curtains[2].GroupID); rt_kprintf("curtains[3].GroupID:0x%x\r\n",nvs_SysInfo.curtains[3].GroupID); } void nvs_eepom_init(void) //开机读取信息 { rt_kprintf("nvs_SysInfo size:%d\r\n",sizeof(nvs_SysInfo)); // rt_thread_mdelay(5000); nvs_eepom_sysInfo_Init(); //内部默认的nvs分区 } void nvs_eepom_factory(void) { nvs_eepom_sysInfo_factory(); }