☰
工业控制器三级存储设计:EEPROM、NOR Flash与SD卡分工与避坑指南
2026/9/28 2:02:58 网站建设 项目流程

做工业控制器的存储这块,踩过的坑是真不少。早期做数据管理,往往一拍脑袋“参数放EEPROM,日志放SD卡”,结果现场跑一段时间就出问题,不是EEPROM写坏了,就是SD卡文件系统损坏,要不就是设备断电瞬间数据全丢。后来慢慢摸出一套分级存储的思路——按数据的性质、容量、写入频率去匹配不同的存储介质,效果好了很多。这篇就结合STM32+FPGA的典型架构,把这套方案里EEPROM、NOR Flash、SD卡怎么分工、怎么设计、怎么避坑,一次性讲透。

适合正在做工业控制器、边缘计算网关、数据采集终端的开发者看,也适合刚把STM32或FPGA入门、准备给自己的项目加存储功能的同学。文章不会堆大段代码,重点讲原理、思路和实际工程中的取舍,但会给出关键的结构和流程,照着设计完全没问题。

1. 为什么工业控制器要把存储拆成“三级”?

先说一个核心观念:存储不是越大越好,也不是越贵越好,而是越匹配越好。工业控制器里的数据,性质差异非常大,混在一起用同一种介质,通常会顾此失彼。

1.1 数据分级模型:改配置、存参数、记历史

我习惯把工业控制器的数据分成三个层级:

  • 第一级:关键配置参数,容量KB级,写入频率极低。比如设备出厂编号、校准系数、IP地址、PID参数、报警阈值。这类数据丢了设备就废了,但要改的频率很低,可能几个月才动一次,甚至整机生命周期只写几次。
  • 第二级:动态运行参数与逻辑配置,容量MB级,写入频率中等。比如FPGA的固件镜像、控制逻辑版本、运行统计、掉电保存的中间状态。这类数据的特点是“偶尔要大面积更新”,一旦写入就是几十KB到几MB,对可靠性要求同样很高。
  • 第三级:历史数据与日志,容量GB级,持续高频写入。比如温度曲线、振动波形、报警事件、操作日志。这类数据追求的是“装得下、能追加、能导出”。

对应到介质,就是我在这期硬件篇里反复提的组合:EEPROM管关键参数,NOR Flash管FPGA配置和参数块,SD卡管历史数据。

1.2 分级不是堆料,而是性价比和可靠性的平衡

有人会问:全上SD卡不就行了吗?容量大还能按文件来组织。这个问题我刚开始也想过,但实际一测就发现问题。

SD卡以及其底层的Flash,是按扇区、块来管理的,写一个字节往往要先读整块、改整块、再擦除整块。而EEPROM擅长随机字节读写,NOR Flash擅长按地址读、按块擦。举个例子,设备每次开机要读一组校准参数,如果用SD卡,需要FAT文件系统初始化、打开文件、寻址、读取,整个过程几十毫秒到几百毫秒,而EEPROM几个微秒就完事了,而且不依赖文件系统的正确性。

再从可靠性角度讲,SD卡的卡座是机械结构,振动环境下有接触不良风险,文件系统还可能在掉电时损坏。关键参数放SD卡,等于把身家性命押在一个可插拔的介质上,风险不可控。反过来说,温度曲线放进EEPROM或NOR Flash,要么容量不够,要么价格感人,毫无性价比。

所以分级存储的本质是:每一类数据找到最能匹配它的介质,让成本和可靠性都达到最优。

1.3 MCU和FPGA的分工

在STM32+FPGA架构里,存储系统的设计还要考虑控制权的分配问题,这也是很多项目混乱的地方。

我的习惯是:

  • STM32作为主控,管理所有“业务数据”。EEPROM、SD卡挂在STM32下,所有算法参数、历史记录都由ARM侧负责读写,这样逻辑清晰,调试方便,也便于用RTOS的任务来管理。
  • FPGA管理“与硬件时序强相关的数据”。最典型的就是FPGA自己的配置镜像,存放在NOR Flash里。上电后FPGA从Flash加载逻辑,这个过程由FPGA的专用配置引脚或SPI控制器自动完成,不经过STM32。另一类是FPGA在做高速采集时,需要把原始采样数据先缓存到自己的BRAM或外部SRAM,再由STM32批量搬到SD卡。这里FPGA管的是“RAM级别的临时存储”,不是长久的非易失存储。

简单说:长时非易失数据,尽量统一由STM32主控管理;FPGA只负责需要紧密配合硬件的存储行为。分层清晰之后,后续查问题会舒服很多。

2. EEPROM:关键参数的“保险箱”

EEPROM这类器件,型号上最常碰到的就是AT24C02/04/08系列(I2C接口),还有SPI接口的25AA系列。STM32内部也有一部分“模拟EEPROM”的Flash区域可以用,但容量和寿命有限。外挂一颗串行EEPROM,是工业控制板上最常见的做法。

2.1 I2C接口与页写细节

先说说I2C读写EEPROM最容易翻车的几个点。

第一个是页写(Page Write)边界。AT24C02的页大小是8字节,AT24C04/08是16字节,AT24C256是64字节。很多人第一次写EEPROM都遇到过:连续写一串超过页大小的数据,结果数据错位,前面的覆盖了后面的,或者后面写到别的地址去了。原因就是EEPROM内部页缓冲区只有那么大,一旦跨页,地址会回卷(roll over)。正确做法是写入前判断本次写入是否跨页,跨页就拆成多次写,每次都不超过页大小。

第二个是写周期时间。EEPROM每次写入后内部需要tWR时间(通常5ms)才能真正落盘,期间不响应指令。你写完一个字节或一页,必须等待或轮询ACK。很多HAL库的例程直接塞个延时5ms,这样可用,但效率低。更专业的是用“轮询ACK”方式,写完继续发一条任意命令,直到器件响应为止,这样能把连续写入时间压缩到接近理论值。

第三个是地址管理要规划好,不要随手用。我习惯在任何项目一开始就建一张地址分配表,就像内存布局一样,把不同类参数固定分区分块:

起始地址长度(字节)内容说明
0x000016设备出厂信息序列号、硬件版本、生产日期
0x001064校准系数块A温度校准、增益校正值
0x005064校准系数块B双备份,与A互为校验
0x009032通信参数IP、波特率、站号
............

这么做的最直接好处是:新老固件升级兼容好,避免地址重叠导致参数互相覆盖。我在固件升级踩过一次坑,新版本在某个绝对地址塞了新字段,结果把旧版的报警阈值覆盖了,现场一批设备报警乱跳,查了整整一天才定位。从那以后地址表就成了评审必须项。

2.2 场景:校准值、出厂编号、运行计数

EEPROM在工业控制器里的典型场景,我列几个实际做过的:

  • 校准系数存储。比方说一个带温度传感器的控制器,每个设备的传感器存在个体差异,出厂时要写入一组校准系数。这类数据写入次数极少,但每次开机或触发校准流程后都要读取、校验。EEPROM正好匹配。
  • 运行计数和累计量。比如设备累计运行小时数、开关次数,需要时不时写一次。这里有个隐藏问题:如果设备每运行10分钟就更新一次计数,一年就要写5万多次,EEPROM寿命(通常100万次擦写)看似够,但如果按“每次掉电都写”的频率,有些设备一天启停几十次,一年就上万次。所以我在设计时通常把累计量放在RAM里累积,只有变化量超过阈值或掉电前才真正写一次EEPROM,把写次数砍掉一个数量级。
  • 配置参数的存档。IP地址、设备号这类参数,人机交互修改后要立即保存,同时掉电后不能丢。用EEPROM的好处是支持字节级修改,不需要整块擦除。

2.3 磨损均衡和双备份的实操做法

EEPROM虽然寿命比普通Flash强,但也不是无限写。AT24系列标称10万次或100万次擦写,对于频繁记录运行状态的应用,还是要做磨损均衡和备份。

我的做法是:对小而高频变化的参数,开辟两个“槽位”,交替写入。比如一个2字节的运行计数,你准备8个字节的空间,每次写入时先读槽位状态字,选一个空的或最旧的槽位写,并更新状态字。这样把同一地址的写入次数分散到几个地址上,等效寿命翻倍。

双备份就更简单了:两份数据+CRC校验。每次读取优先取校验通过的副本,如果两份都坏了,取版本号大的;如果版本号一致但CRC不一致,以先写的为准并触发重新校准告警。这套机制我写过很多次,代码成本不高,但对“参数不明原因被改”这类问题几乎是降维打击。

再有就是掉电瞬间的写保护。EEPROM写入过程中如果电源抖动,可能导致半字节写入或内部状态混乱。硬件上加个小电容保证掉电后还能维持几十毫秒,软件上利用STM32的PVD(可编程电压检测)中断,检测到掉电后在最后几毫秒把紧急参数写入EEPROM。这个方案我在不少项目里落地,效果非常稳定。

3. NOR Flash:FPGA配置和参数块的“战场”

NOR Flash,最具代表性的就是W25Q系列,比如W25Q64(8MB)、W25Q128(16MB)。它和EEPROM最大的区别是:必须按扇区擦除后才能写,而且擦除以扇区为单位,读却可以按字节随机读。这个“读随机、写要擦”的特性,让很多第一次做Flash存储的人很痛苦。

3.1 存储原理和接口操作

理解NOR Flash,抓住三个操作:读、写(编程)、擦除。

  • 读:最灵活,按字节随机读,速度也最快,这也是为什么NOR Flash适合做芯片内执行(XIP)的原因。
  • 写(Page Program):也是按字节写的,但只能把1变成0,不能在1的位置写0回去。所以写之前必须先擦除。单次编程最大长度通常是一个Page,W25Q系列是256字节。
  • 擦除(Erase):最小单位是扇区(Sector,通常4KB),也有32KB/64KB的块擦除方式。擦除会把整个扇区全部恢复成0xFF。

在STM32上控制W25Q,一般用SPI接口,HAL库的HAL_SPI_TransmitReceive就能完成。关键操作序列其实很典型:

  • 使能写:发送0x06(Write Enable)命令;
  • 写数据:发送0x02(Page Program),附24位地址和最多256字节数据;
  • 等待完成:轮询状态寄存器(0x05,Read Status Register-1),直到WIP(Write In Progress)位清零;
  • 擦除:发送0x20(Sector Erase)或0xD8(Block Erase),同样要等WIP清零。

有个细节:写使能命令每次写/擦除前都要发,不能发一次管好几次。这也是很多入门的人卡壳的地方,逻辑看着对,就是不写入,检查了半天发现是把Write Enable命令放到了循环外。

3.2 设计要点:扇区划分与双区备份

NOR Flash最常见的两个工业应用场景,一个是存FPGA的固件镜像(bitstream),另一个是存设备的二进制参数、升级包。

先说FPGA配置镜像。Xilinx、Intel(Altera)这些主流FPGA都支持上电时主动从SPI Flash加载配置。设计上要注意几点:

  • 镜像文件大小和存放地址要对齐。比如某款FPGA的bitstream是2.1MB,你给它分配的起始地址可能要放在0x000000,而后续别的镜像放在0x300000,预留足够的间隔,防止交叉覆盖。
  • 多镜像冗余存储。我现在的项目基本都会放两份甚至三份镜像:A区是新版本,B区是上一版本,C区是出厂版本。上电后先从A区加载,A区校验失败自动回退B区,再失败就加载C区。这直接应对“传输中途断电导致Flash里是半截镜像”的情况。
  • 版本头信息单独放一个扇区,比如flash偏移0x0处放结构体:魔数、镜像长度、CRC、版本号、时间戳。这样上电就能快速判断镜像是否完整。加载逻辑可以做成:先读头部,校验CRC,通过再按头部信息去加载镜像。

再说参数块的方案。如果参数比较大(比如几百条曲线、设备配置表),EEPROM放不下,就放NOR Flash。我的做法是双Bank交替:

  • Bank A存当前参数,Bank B存上次参数。
  • 每次更新时,先写备用Bank,写完后更新“当前有效Bank”指针(这个指针我放在扇区头部,也带CRC)。
  • 如果写入过程中掉电,备用Bank数据不完整,但当前Bank还是好的,设备可以用上一版参数启动。

还有一种思路是日志型追加写:每次把新参数整包追加到Flash的空闲区,读到最后一条有效记录即最新值。这种方案符合NOR Flash“按块擦、按序写”的特性,避免了反复擦同一扇区,能显著延长寿命。缺点是Flash空间利用率低,因为要预留很大的循环区。我一般只在小容量嵌入式项目里用,大容量还是双Bank直观。

3.3 FPGA配置加载实战

这里单独讲讲FPGA从NOR Flash加载配置的实操,因为我见过不少人在这个环节把板子调崩溃。

以Xilinx的Spartan-6 / Artix-7系列为例,SPI配置模式上电时序大概是这样:FPGA上电后拉低INIT_B,等待电源稳定,然后从SPI Flash的0x000000地址读取配置头。如果Flash里没数据或者头信息错误,INIT_B会不拉高,DONE信号一直为低,FPGA就是“不进逻辑”的状态。

实操时容易踩的坑:

  • MODE引脚没拨对。开发板上有跳线或拨码,M[2:0]要按SPI模式设置,不然FPGA不认Flash。
  • 镜像生成时没选对SPI模式选项。在Vivado或ISE生成bin文件时,有一个SPI x1/x2/x4的选项,必须和板卡上Flash的实际接法匹配。用x4模式但Flash只接了x1,上电永远配置不进去。
  • Flash型号没设置对。很多工具生成配置镜像时要填Flash的容量和型号,填小了生成的文件不完整,填大了地址映射错乱。

调试方法上,最靠谱的是先只加载一个最小灯闪烁工程到Flash,排除镜像问题;然后用逻辑分析仪或示波器盯FPGA的CCLK、CS、MOSI、DONE引脚,看上电瞬间是否有时钟和命令。我通常抓一段波形:先看到CS拉低,然后MISO上有数据;如果什么都没动,先查MODE引脚和电源稳定;如果只有空操作没有读地址,再查镜像文件生成选项。

4. SD卡:历史数据和日志的“仓库”

SD卡在工业控制器中的角色,一句话概括:解决“大批量数据往哪放”的问题。它兼容性好、容量大、可拆卸,所以在现场数据分析、设备升级、远程运维中都绕不开。

4.1 SDIO还是SPI,怎么选?

STM32驱动SD卡有两条路:SPI方式,或者SDIO(SDMMC)方式。

  • SPI方式:优点在于任何带SPI的单片机都能用,接线只要4根线(CS、SCK、MOSI、MISO),速度通常能跑到几十Mbps,对日志记录够用。缺点是协议要自己适配SD卡命令,某些SD卡在SPI模式下的初始化时序微秒级差异都可能导致失败,兼容性要调。
  • SDIO方式:STM32系列里F4、H7这些型号都带SDMMC外设,支持1位或4位总线,速度能上100Mbps以上。4位模式接线多三根(SDIO_D1、D2、D3),但读写性能完全不是一个级别。对需要大量波形记录或持续采样的工业设备,SDIO几乎是必选。

我的选型建议很直接:如果只是记设备日志、报警事件,SPI完全够用,体积小、引脚少;如果数据量大,比如要做连续波形记录、跑文件系统还要保证吞吐,就老老实实用SDIO。

不过SDIO模式下有一个老生常谈的坑:很多TF卡(microSD)在4位模式下的电气特性要求更高,信号线要短、要加电阻上拉。我量产的一块板子曾经在部分卡上初始化失败,查了波形发现是上拉电阻阻值不对,10k改成4.7k后问题消失。这类问题在嵌入式项目里非常典型,一般先查电源纹波、CLK线上的振铃,再查初始化频率(SDIO初始化时要把时钟降到400kHz以下,兼容老卡)。

4.2 FATFS还是LittleFS?

文件系统的选择,比很多人想象的更重要。

  • FATFS + FAT32/FAT16:如果你需要把SD卡拔出来插到电脑上直接读数据、拷贝数据,首选FATFS。缺点是FAT本身是中心化的目录+文件分配表架构,掉电时容易造成文件系统结构损坏,每写一个文件都要更新目录区,慢而且脆弱。
  • LittleFS:专为嵌入式设计,自带掉电保护、磨损均衡、目录区冗余。缺点是它默认不兼容PC直接识别,通常要配套自己的上位机工具才能解析数据。
  • 只写式日志系统(Log-only / Ring Buffer):不做文件系统,SD卡直接固定块地址轮转写。这种方式最可靠,速度最快,但是导出数据必须用自定义工具离线解析。

具体到我的项目,目前采用“混合策略”:参数和配置文件放FATFS的特定目录(方便现场升级和导出),高频运行的历史数据用一个独立的二进制日志文件追加写,并定期刷新FAT表。这样既保留了PC直读的便利,又减少了FAT的频繁更新。

这里必须提醒一个常见误区:把FATFS的写操作当成“像串口打印一样随意”。FATFS写入有缓存,f_write只是把数据放到缓冲区,真正落盘要靠f_sync或f_close。频繁调用f_sync会严重影响吞吐,但完全不调又可能在掉电时丢很多数据。

我现在的做法是:日志数据先攒够一批(通常是512字节对齐或4KB块对齐)再f_write一次,每写满一定量(比如1MB)做一次f_sync。测试下来,吞吐和可靠性能同时兼顾。想深入了解的话,我在前几篇里写过FATFS的调优心得,比如_MAX_SS设为4096、启用_FS_EXFAT、选择合适扇区大小的策略,这里就不重复展开了。

4.3 掉电保护和文件系统可靠性

工业控制器最恶劣的上电掉电场景,SD卡这块必须做保护设计,否则现场一堆“数据丢失”“损坏TF卡”的售后问题在等你。

硬件层面要做几点:

  • 供电要稳。SD卡对电源瞬断非常敏感,我在电源上加了TVS和大容量钽/电解电容,掉电后维持几十毫秒的余量,足够完成最后一次flush。
  • 卡座选带锁扣的。工业现场振动大,普通按出式卡座时间长了接触不良,SD卡写文件随机出现I/O错误,排查起来非常费神。换成推拉式物理锁卡座后,这类故障基本绝迹。
  • 加检测引脚。用卡座上的card detect引脚配合外部中断,卡拔出的瞬间就能感知,及时停掉写入任务,避免文件系统错乱。

软件层面,日志写入我采用“双文件轮转”策略:当天写LOG_20250101.BIN,超过一定大小自动切换为LOG_20250101_2.BIN,并且每个文件都是“魔法数+头部信息+数据帧长度+CRC”的结构。即使某个文件损坏,解析程序能从下一个有效帧继续恢复数据。这套结构在数据恢复测试里表现非常出色。

还有一个细节:写SD卡时不要在循环里直接操作文件,而是通过队列往一个写任务里投递。这样可以把零散的小写合并成大块写,减少FAT更新次数,也避免多个任务同时操作同一个文件导致互锁。实时操作系统加文件系统后,这种设计几乎可以让写入线程永远只做一件事:从队列取数据,攒够大小,落盘。

5. 三级存储的完整实操流程

前面把每个模块的原理和关键点讲完了,现在串起来看一整个工业控制器的存储系统,从零设计到量产,过程大概是什么样的。

5.1 一个单板存储方案的设计案例

举例:做一个带温度采集、报警输出、远程通信的边缘控制器,主控是STM32H743,逻辑用一颗Artix-7系列FPGA,要求存储数据包括校准参数、FPGA镜像、半小时采一次的历史温度曲线(存一年)。

我的设计可能是这样:

  • 校准参数(8字节左右):AT24C02,I2C接口,地址0x10~0x1F,双备份+CRC。
  • FPGA镜像(几MB):W25Q128(16MB),分A/B/C三区双冗余,用SPI接口,速率50MHz。
  • 温度曲线(365天 × 48条/天,每条带时间戳16字节,约2.8MB):用SD卡,SDIO 4位模式,FAT32文件系统,按年/月拆分文件夹,每小时一个日志文件。
  • 运行统计(累计运行时间、总报警次数):EEPROM或NOR Flash双槽位交替写,每掉电前更新。

写在设计文档里,分区表、地址表、文件名规则、CRC规则全部明确。这一步做扎实了,后面编程只是按图施工。

5.2 关键流程和逻辑思路

存储系统的软件框架,我按功能拆成了几个独立模块:

  • 存储介质驱动层:EEPROM的I2C驱动、Flash的SPI驱动、SD卡的SDIO驱动,只负责最底层的读写擦操作。
  • 存储管理层:CRC校验、双备份逻辑、扇区分配、Flash磨损均衡、SD日志文件管理。这层是不同项目差异最大的地方,要仔细设计。
  • 业务接口层:向业务代码提供SaveCalibParam()、LoadConfig()、AppendLog()这样的接口。业务代码完全不关心底层用什么介质。

启动时的初始化顺序也很有讲究,我的习惯是:

  1. 初始化电源检测(PVD)和系统时钟;
  2. 初始化EEPROM,读取关键配置;
  3. 校验参数,如果双备份都坏了,进入“恢复出厂设置”流程;
  4. 初始化NOR Flash,校验FPGA镜像是否需要回退加载;
  5. 初始化SD卡和文件系统,挂载失败则继续运行(不因存储卡异常阻塞主业务);
  6. 创建日志任务,开始接受写入请求。

这个顺序保证了一件事:即使SD卡坏了,控制器还能带基础参数正常运行,只是不记日志。工业设备最忌讳“因为存储坏了连设备都起不来”。

5.3 批量生产的镜像与测试

量产时,存储相关的环节经常被忽视,但问题恰恰会集中爆发在这里。我梳理一下必须准备的几项工作:

  • FPGA镜像烧录。NOR Flash在贴片前可以先用烧录器写入出厂镜像,也可以用STM32在测试工装里写。用STM32写的优点是灵活,但必须校验烧录后的CRC,并且烧完后回读比对。我见过烧录过程中断导致整批镜像无法加载的案例,就是因为少了回读确认。
  • SD卡镜像批量制作。工厂几十张卡逐张格式化和拷贝太慢了。正确做法是做一张“母卡”,用镜像工具(比如Win32DiskImager,Linux下的dd)把整卡做成镜像文件,然后在产线批量烧写。卡里可以预置目录结构、空白的日志占位文件、校准参数文件。此外,我还习惯在卡根目录放一个“启动配置”文本,方便现场改波特率或IP,不需要重刷固件。
  • 整机测试。我强烈建议在产线增加一个“存储自检”步骤:设备上电后自动执行EEPROM读写回读测试、NOR Flash特定区域的写擦测试、SD卡写一个临时文件再删掉,把测试结果通过串口或指示灯上报。一个小小自检能挡住一大批存储问题,投入产出比极高。

6. 常见问题排查速查与实战心得

最后把这些年经验里最高频的问题集中列一列,做成排查速查表,方便以后现场遇到问题能快速定位。

现象可能原因解决思路
EEPROM写入后数据不对跨页写入 / 地址回卷检查页大小,拆分跨页写入;打印每次写入的起始地址
EEPROM偶尔写不进I2C总线无上拉或上拉太小确认I2C上拉电阻2.2k~4.7k;降低I2C速率测试
NOR Flash擦除后读出来还是旧数据WP引脚拉低 / 状态寄存器SRP位被置位读出状态寄存器全字节,确认保护位;检查WP引脚接线
Flash写入超时卡死擦除等待时间不够 / SPI时钟不稳擦除等待改为带超时循环,清零超时;降低SPI速率验证
FPGA上电DONE信号不拉高镜像生成选项不对 / MODE引脚不对按5.3节流程检查MODE引脚,重新生成镜像,抓CCLK/MISO波形
SD卡时好时坏接触不良 / 电源纹波 / 上拉阻值换锁卡座;示波器看VDD纹波和CLK振铃;调整上拉电阻
FATFS频繁写后文件系统损坏掉电没有f_sync / FAT频繁更新批量写入,按时或按量f_sync;改用二进制日志文件结构
SDIO初始化兼容性差时钟频率过高 / 电平不匹配初始化时先用400kHz,再加电压适配逻辑
掉电时参数丢失没做掉电检测 / EEPROM写入时间不足加PVD中断,掉电后利用电容余量写关键参数
设备存储没问题但数据解析不对字节序 / CRC算法不一致统一使用小端格式,CRC采用标准CRC32或CRC16,文档写明多项式

这些坑,大部分我自己都踩过。印象最深的是有一次现场批量设备报“参数偶尔恢复出厂值”,排查到最后是EEPROM的写保护引脚没拉高,导致写入操作被硬件拒绝,但I2C总线又没有报错,程序不知道写失败了。后来在写函数里加了“写入后回读校验”,失败就重试并告警,问题彻底消失。这让我养成了一个习惯:存储器写操作,一律采用“写→读回→比对”的闭环,宁可慢一点,绝不能不校验。

6.2 关于磨损均衡与寿命,我再补一句

很多人觉得存储介质寿命是纸面参数,跟实际关系不大。但工业设备通常要跑十年以上,这个账必须算清楚。

以W25Q128为例,标称擦写次数10万次。如果你有一个参数每分钟保存一次,一年就52万次,单个扇区最多用不到两个月。所以前面提到的双Bank交替、日志追加、RAM缓存累积,这些设计不是在追求代码优雅,而是在把存储寿命从“纸面够用”变成“实际够用”。

我的实操经验是:凡是写入频率超过每10分钟一次的数据,都不要直接写固定扇区;凡是每天超过一次的写入,都要加磨损均衡或至少双槽轮换。这个阈值不一定适合所有项目,但对于大部分工业控制器来说,按这个标准设计基本不会出寿命问题。

写这篇文章时我特意回顾了最近接手的一个项目:STM32F4负责通信和业务,FPGA做高速采集,所有历史数据走SD卡,关键参数走EEPROM,FPGA逻辑走NOR Flash,整体存储系统在高温和频繁掉电测试下跑了一周,数据全部完整。回头看,分级存储这个思路最大的价值不是“把存储做得高大上”,而是让每种介质都只干自己最擅长的那一件事,整个系统自然就稳定了。

这篇是硬件篇的第十二期,存储这个话题总算讲到了硬件层面。下一篇我打算把FATFS和日志存储的数据结构设计展开讲一讲,顺便附几个实际项目的文件解析代码,想继续看的朋友可以留意。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询