专栏名称: 嵌入式微处理器
关注这个时代最火的嵌入式微处理器,你想知道的都在这里。
目录
相关文章推荐
数据何规  ·  上海AIGC备案公告,华师大EduChat通 ... ·  2 天前  
数据何规  ·  上海AIGC备案公告,华师大EduChat通 ... ·  2 天前  
sven_shi  ·  消失的中产 -20250222062317 ·  2 天前  
杨浦科技创业中心  ·  喜报丨杨浦科技创业中心进入上海市海聚英才创新 ... ·  3 天前  
杨浦科技创业中心  ·  喜报丨杨浦科技创业中心进入上海市海聚英才创新 ... ·  3 天前  
51好读  ›  专栏  ›  嵌入式微处理器

智能硬件产品中,常用的参数存储和管理方案

嵌入式微处理器  · 公众号  · 科技自媒体  · 2024-06-12 13:00

主要观点总结

本文介绍了智能硬件产品中参数管理的三个方面:需要管理的参数类型、参数的硬件存储方案以及参数的软件管理方案。总结了各种方案的适用场景、特点和示例代码。

关键观点总结

关键观点1: 参数类型

智能硬件产品中需要管理的参数包括系统设置数据、用户设置数据和用户使用数据三类。

关键观点2: 硬件存储方案

常见的参数存储方案包括EEPROM、Flash、FRAM、SD卡或硬盘以及云存储等,选择合适的存储方案需要根据具体的需求、成本和技术限制来决定。

关键观点3: 软件管理方案

参数的软件管理包括参数的读取、写入、备份、重置和更新等功能。常见的软件管理方案包括文件系统、数据库、键值存储和云存储。根据存储介质的特点和具体应用场景进行权衡,使用过程中需要灵活使用,甚至配合使用。


正文

一、有哪些参数需要管理?

在智能硬件产品中,一般有三类数据需要存储并管理:

1、系统设置数据

系统设置数据是指 产品自身正常工作所依赖的一些参数

这类数据的特点:只能在生产过程中修改, 出厂后用户无权限修改

比如:产品 SN、产品密钥/token/license、传感器校准值。

2、用户设置数据

用户设置数据是指在用户使用过程中, 由用户根据自身喜好所设置的一些参数

这类数据的特点: 出厂时恢复默认 ,出厂后由用户动态修改。

比如:检测类产品的告警阈值、模块化功能是否打开。

3、用户使用数据

用户使用数据是指在用户使用过程中, 产品工作产生的一系列用户数据

这类数据的特点:数据量较大,且 用户需要查看历史数据

比如:过去一小时的语音数据、过去一天的监测数据、过去一周的视频数据等等。

二、参数的硬件存储方案

一些常见的参数存储方案如下,每种存储方案在不同的智能硬件产品中都有其独特的应用场景, 选择合适的存储方案需要根据具体的需求、成本和技术限制来决定

1、EEPROM

EEPROM 是一种容量较小的存储器,在产品中需要外挂一片 EEPROM,适用于存储 少量 的数据。

优点:

  • 可以进行字节级别的擦写操作
  • 寿命较长,擦写次数通常在 10 万次左右
  • 价格低

缺点:

  • 容量较小,一般为几 KB 到几百 KB

比如: 智能家居产品中用户设定的温度阈值设定可以存储在 EEPROM 中

2、Flash

Flash 是一种容量较大的存储器,比如 Spi Flash/Nand Flash/Emmc,适用于存储 大量 参数数据。

优点:

  • 容量较大,从几 MB 到几 GB 不等。
  • 擦写寿命较长,通常可达数十万次。

缺点:

  • 擦写操作需要按块(通常是几 KB 到几 MB)进行
  • 擦写时间较长

比如: 智能手表中的用户使用数据(如步数、心率记录)可以存储在 Flash 中

3、FRAM

FRAM(Ferroelectric RAM)是一种结合了 RAM 速度和 EEPROM 数据保存能力的存储器,适用于需要 高频读写和数据保持 的应用场景。

优点:

  • 擦写速度快,接近于 RAM。
  • 擦写寿命极长,通常在 10 亿次以上。
  • 非易失性,断电数据不丢失。

缺点:

  • 容量相对较小,通常为几 KB 到几 MB。

比如: 医疗产品中的病人数据记录器,可以使用 FRAM 来存储重要的参数和数据

4、SD卡或硬盘

SD 卡和硬盘适用于需要大容量存储的应用场景。

优点:

  • 容量大,从几 GB 到几 TB 不等。
  • 便于更换和升级。

缺点:

  • 可靠性相对较低,易受物理损坏。
  • 速度较慢,特别是与内部存储器相比。

比如: 智能监控摄像头会使用 SD 卡来存储视频录制文件

5、云存储

云存储是一种通过互联网将数据存储在远程服务器上的方法,适用于需要大容量和易于共享的场景。

优点:

  • 理论上容量无限
  • 易于访问和共享
  • 数据安全和备份有保障

缺点:

  • 依赖网络连接。
  • 存在隐私和安全风险。

比如: 智能家居系统中将过去一天的监测数据上传到云端进行存储和分析

三、参数的软件管理方案

参数能通过硬件进行存储后,还需要进行软件的管理,比如参数读取、参数写入、参数备份、参数重置、参数更新等软件功能。

一些常见的软件管理方案如下,这些方案都有其适用的场景,根据存储介质的特点和具体应用场景进行权衡,在使用过程中需要灵活使用,甚至可以配合使用。

一般来说:

  • 简单的参数存储:选 KV 存储或配置文件
  • 大量复杂数据或历史记录:嵌入式数据库
  • 远程访问和备份数据:云存储

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, 00, &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"






请到「今天看啥」查看全文