一、有哪些参数需要管理?
在智能硬件产品中,一般有三类数据需要存储并管理:
1、系统设置数据
系统设置数据是指
产品自身正常工作所依赖的一些参数
。
这类数据的特点:只能在生产过程中修改,
出厂后用户无权限修改
。
比如:产品 SN、产品密钥/token/license、传感器校准值。
2、用户设置数据
用户设置数据是指在用户使用过程中,
由用户根据自身喜好所设置的一些参数
。
这类数据的特点:
出厂时恢复默认
,出厂后由用户动态修改。
比如:检测类产品的告警阈值、模块化功能是否打开。
3、用户使用数据
用户使用数据是指在用户使用过程中,
产品工作产生的一系列用户数据
。
这类数据的特点:数据量较大,且
用户需要查看历史数据
。
比如:过去一小时的语音数据、过去一天的监测数据、过去一周的视频数据等等。
二、参数的硬件存储方案
一些常见的参数存储方案如下,每种存储方案在不同的智能硬件产品中都有其独特的应用场景,
选择合适的存储方案需要根据具体的需求、成本和技术限制来决定
。
1、EEPROM
EEPROM 是一种容量较小的存储器,在产品中需要外挂一片 EEPROM,适用于存储
少量
的数据。
优点:
缺点:
比如:
智能家居产品中用户设定的温度阈值设定可以存储在 EEPROM 中
。
2、Flash
Flash 是一种容量较大的存储器,比如 Spi Flash/Nand Flash/Emmc,适用于存储
大量
参数数据。
优点:
缺点:
-
擦写操作需要按块(通常是几 KB 到几 MB)进行
-
比如:
智能手表中的用户使用数据(如步数、心率记录)可以存储在 Flash 中
。
3、FRAM
FRAM(Ferroelectric RAM)是一种结合了 RAM 速度和 EEPROM 数据保存能力的存储器,适用于需要
高频读写和数据保持
的应用场景。
优点:
缺点:
比如:
医疗产品中的病人数据记录器,可以使用 FRAM 来存储重要的参数和数据
。
4、SD卡或硬盘
SD 卡和硬盘适用于需要大容量存储的应用场景。
优点:
缺点:
比如:
智能监控摄像头会使用 SD 卡来存储视频录制文件
。
5、云存储
云存储是一种通过互联网将数据存储在远程服务器上的方法,适用于需要大容量和易于共享的场景。
优点:
缺点:
比如:
智能家居系统中将过去一天的监测数据上传到云端进行存储和分析
。
三、参数的软件管理方案
参数能通过硬件进行存储后,还需要进行软件的管理,比如参数读取、参数写入、参数备份、参数重置、参数更新等软件功能。
一些常见的软件管理方案如下,这些方案都有其适用的场景,根据存储介质的特点和具体应用场景进行权衡,在使用过程中需要灵活使用,甚至可以配合使用。
一般来说:
1、文件系统
适用场景:
大容量存储,如 Flash 或 SD 卡。
方法:
-
使用嵌入式文件系统,如 FATFS、LittleFS 或 SPIFFS,
将参数存储为文件
,可以方便地进行读取和修改。
-
文件内容格式可以是 ini、json、xml 等。
示例代码(使用 SPIFFS):
#include
void setup() {
if (!SPIFFS.begin(true)) {
Serial.println("SPIFFS Mount Failed");
return;
}
File file = SPIFFS.open("/config.txt", FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing");
return;
}
file.println("parameter1=value1");
file.println("parameter2=value2");
file.close();
}
void loop() {
// 读取和处理参数
File file = SPIFFS.open("/config.txt");
if (!file) {
Serial.println("Failed to open file for reading");
return;
}
while (file.available()) {
Serial.println(file.readStringUntil('\n'));
}
file.close();
}
2、数据库
适用场景:
需要管理大量复杂参数或历史记录。
方法:
-
使用嵌入式数据库,如 SQLite,数据库可以提供强大的查询和管理功能。
示例代码(使用 SQLite):
#include
void setup() {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("/mydb.db", &db);
if (rc) {
Serial.printf("Can't open database: %s\n", sqlite3_errmsg(db));
return;
}
const char* sql = "CREATE TABLE IF NOT EXISTS CONFIG ("
"ID INTEGER PRIMARY KEY AUTOINCREMENT,"
"KEY TEXT NOT NULL,"
"VALUE TEXT NOT NULL);";
rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);
if (rc != SQLITE_OK) {
Serial.printf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
}
void loop() {
// 数据库操作示例
}
3、键值存储(KV-存储)
适用场景:
少量配置参数,频繁读写,如 EEPROM、FRAM。
方法:
-
使用键值对存储结构,常见库如 FlashDB、EEPROM 库、Preferences 库。
示例代码(使用 FlashDB):
#include
#ifdef FDB_USING_KVDB
#define FDB_LOG_TAG "[sample][kvdb][basic]"
void kvdb_basic_sample(fdb_kvdb_t kvdb)
{
struct fdb_blob blob;
int boot_count = 0;
FDB_INFO("==================== kvdb_basic_sample ====================\n");
{ /* GET the KV value */
/* get the "boot_count" KV value */
fdb_kv_get_blob(kvdb, "boot_count", fdb_blob_make(&blob, &boot_count, sizeof(boot_count)));
/* the blob.saved.len is more than 0 when get the value successful */
if (blob.saved.len > 0) {
FDB_INFO("get the 'boot_count' value is %d\n", boot_count);
} else {
FDB_INFO("get the 'boot_count' failed\n"