Files
luban-lite-t3e-pro/application/rt-thread/t3e-pro/components/nvs_eepom.c
2025-09-30 11:56:06 +08:00

280 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <finsh.h>
#include <aic_core.h>
#include "nvs_eepom.h"
// #define LOG_TAG "DB" // 该模块对应的标签。不定义时默认NO_TAG
#define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
#include <ulog.h> // 必须在 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();
}