news 2026/9/30 1:33:08

STM32+FPGA工业控制器分级存储:EEPROM、NOR Flash与SD卡协同设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32+FPGA工业控制器分级存储:EEPROM、NOR Flash与SD卡协同设计

做工业控制器的朋友应该都有过这种经历:设备在现场跑得好好的,突然断电,再上电,参数丢了;或者客户反馈日志文件损坏,一查是 SD 卡写坏了;更头疼的是程序版本自己乱跳,配置被改得面目全非,最后却查不出是代码问题还是存储介质的问题。

STM32+FPGA 这种架构在工业控制器里太常见了,STM32 管通信和运算,FPGA 管时序和高速采集,但数据最终要落到存储介质上,绕不开三样东西:EEPROM、NOR Flash、SD 卡。这三样东西的电气特性、寿命、容量、读写方式完全不同,把它们组织成一套分级存储方案,让配置不丢、固件能升、日志能查、掉电不坏,是整个硬件设计的核心命题。

这篇文章就是来拆解这套方案的。我不会讲太多手册里有的东西,更多是项目调试中踩过的坑和最终沉淀下来的架构思路,适合正在做工业控制器、边缘网关,或者刚把手伸进 STM32+FPGA 联合调试的工程师参考。

1. 分级存储的由来:先把数据分好类,再谈怎么存

很多新手拿到"NAND 便宜容量大"的说法,就想着把什么数据都往一块大 Flash 里塞。这种思路在做消费级产品可能勉强够用,放到工业现场基本是给自己埋雷。

1.1 工业控制器的三类数据,生命周期完全不同

工业控制器里流转的数据,按生命周期可以分成三类,这是我做方案时的第一层划分依据。

第一类是配置参数类。包括设备地址、通信波特率、校准系数、增益值、用户设定的温度曲线、报警阈值等。这类数据的特征是字节量小,通常在几十字节到几 KB 之间;改写频率极低,可能一天改一次,也可能一年都不动;但要求极高可靠性,掉电不能丢,重复改写不能失效。

第二类是运行状态与日志类。包括实时采集的温度、压力、速度、故障事件、操作记录。特征是个头大,一天跑下来可能产生几十 MB 到几百 MB;持续写入,系统上电就在写;允许按时间翻查,掉电后要保留。

第三类是程序与固件类。包括 Bootloader、应用程序镜像、FPGA 配置文件。特征是大块数据,几百 KB 到几 MB;更新频率很低,只有在现场升级时才写入;要求原子性,升级到一半掉电不能变砖。

这三类数据,写入频率、容量要求、可靠性要求完全不是一个数量级的。用同一块存储介质处理,等于让一个仓库同时存档案文件、流水账本和大型设备,管理效率和安全性都无从谈起。

1.2 分级存储的核心理念:合适的数据进合适的介质

分级存储的核心判断依据有三个参数:写入频率、单次数据量、可靠性要求。

配置参数类,写入频率极低但可靠性要求极高,适合放进 EEPROM。EEPROM 可以按字节擦写,寿命通常标称 100 万次擦写,数据保持能力是温度相关的,工业级芯片在 85 度环境下也能保持几十年。关键是它的"按字节改写"特性,让修改单个配置项不需要整体擦除重写。

运行日志类,数据量大、写入频繁、要求掉电保留,适合放进 SD 卡。SD 卡容量以 GB 计,内置磨损均衡算法,配合文件系统可以做时间片轮转、循环覆盖,这是 EEPROM 和 NOR Flash 完全做不到的。

程序固件类,块擦写、可靠性高、可随机读取,适合放进 NOR Flash。NOR Flash 支持 XIP(Execute in Place),可以像内存一样直接在 Flash 里执行代码,缺点是写前必须擦除、擦除粒度大(通常是 4KB 扇区),寿命约 10 万次擦写。

1.3 STM32 和 FPGA 在存储分工上各管哪一段

STM32 和 FPGA 的组合里,我习惯把存储访问的"控制权"统一交给 STM32,FPGA 只做数据搬运和缓存,不做存储介质的主控。

原因很简单:STM32 上有现成的 I2C、SPI、SDIO 外设,有成熟的 FATFS 文件系统移植经验,调试工具链也完善。FPGA 虽然也能写 SPI 控制器、I2C 控制器,甚至能挂 eMMC 的 IP 核,但那是把简单问题复杂化——除非你有特殊需求,比如要用 FPGA 直接实时采样并落盘、绕开 STM32 参与,否则存储管理这件事交给 STM32 是性价比最高的。

FPGA 的职责收缩为:接收模拟前端或编码器的高速数据流,拼接时间戳、通道号、校验码,缓存进内部 RAM/双口 RAM,然后通知 STM32 来取。STM32 拿到打包好的数据块,再按类型分发到对应的存储介质。

2. 存储介质选型:EEPROM、NOR Flash、SD 卡只有分工不同

选型不该看哪个"先进"哪个"过时",而是看哪个最匹配你的数据特征。我把这三样介质从工程师视角重新拆一遍,你会发现在工业场景下它们各自有不可替代的位置。

2.1 EEPROM:配置参数的小仓库,按字节改写的底气

EEPROM 最常见的封装是 SOIC-8 或 TSSOP-8,典型型号 AT24C256、CAT24C256、M24M02,容量从 2Kbit 到 2Mbit 不等,接口基本都是 I2C。工业控制器里选型我通常用 256Kbit(32KB),存配置参数足够了,价格也就一两块钱。

EEPROM 最大的价值是按字节读写。NOR Flash 要改一个字节,得先把整个扇区擦了再写,而 EEPROM 可以直接对任意地址改写,不需要擦除动作。这意味着配置参数的每次修改,只需要一次写操作,没有"先擦后写"的中间状态,配合掉电检测,几乎不会出现参数写到一半被断电打乱的局面。

另一个被忽略的参数是写周期时间(Write Cycle Time)。I2C EEPROM 每写一页(Page,常见 8 字节或 32 字节),内部需要大约 5ms 的编程时间。很多新手不管这个,连续对同一页做两次写操作,第二次写直接失败或者写错,因为没有等待上一次编程完成。解决方法是每条写命令后加应答轮询(Acknowledge Polling):持续发起始条件加器件地址,直到从机返回 ACK,说明内部编程已完成,再进行下一条写。

注意 WP 引脚。EEPROM 的 WP(Write Protect)高电平有效,拉高后整个芯片只读。工业产品里我会把 WP 接 STM32 的 GPIO,平时拉低允许写,只有在固件升级或者参数批量下发时才拉高锁死,防止干扰脉冲把配置打乱。

2.2 NOR Flash:程序代码的常住地,也可做关键数据中转

NOR Flash 的代表型号是 Winbond 的 W25Q64/W25Q128、Macronix 的 MX25L 系列,SPI 接口,容量 8MB 到 64MB 很常见。工业控制器里,STM32 片内 Flash 空间不够时,程序镜像就放 NOR Flash,上电由 Bootloader 搬运到 STM32 RAM 或直接 XIP 执行。

NOR Flash 的写入必须遵循"先擦除,后编程"的规则。擦除最小单位是扇区(Sector),W25Q 系列一个扇区 4KB,擦除时间典型值 45ms 到 400ms;编程最小单位是页(Page),一页 256 字节,页编程时间典型值 0.4ms 到 3ms。这个时间参数直接决定了你升一次级的耗时,更决定了你做掉电保护时"必须覆盖多长时间窗口"。

SPI NOR Flash 还有一组容易被忽略的状态寄存器。SR1 里的 BUSY 位表示内部擦写是否完成,WEL 位表示写使能锁存。每次写操作前必须先发 Write Enable(0x06),写完再清掉。很多人单独测试读写正常,一到高低温就打不稳,多半是 WEL 时序不规范,或者中断打断了正在进行的页编程。

NOR Flash 的 WP 保护比 EEPROM 复杂一点,除了硬件 WP 引脚(低电平有效,注意跟 EEPROM 相反),还有块保护位(BP0-BP3),可以软件锁定指定地址范围的扇区。工业产品里,Bootloader 所在的低地址扇区必须设块保护,防止应用在异常时把引导区冲掉。

2.3 SD 卡:日志记录的主战场,容量与便携的平衡

SD 卡在工业控制器里是用来扛大流量的。SPI 模式兼容性好、接线简单,但带宽有限,实测在 STM32F4 上 SPI 模式读能到 10-15Mbps,写因为文件系统和擦写开销,稳定速度更低;SDIO 模式是 4 位并行,理论带宽能到 48MHz 时钟下的 24MB/s,实际稳定写能到 3-8MB/s,这个差距决定了一天能攒下多少日志。

工业级 SD 卡和消费级 SD 卡的价格差距可达十倍以上。工业卡用了 SLC 颗粒,磨损均衡和掉电保护电路更完善,写寿命长、温度范围宽(-40 到 85 度)。如果你的设备每天写几百 MB 日志,消费卡用不了几个月就会因为 ECC 失效开始丢数据。这个钱省不得。

SD 卡最怕的是边写边掉电。文件系统(FATFS)在写数据时,FAT 表和目录项是分开更新的,掉电点落在哪个环节,决定了丢一个簇、坏一个文件、还是整个文件系统崩溃。后文我会讲怎么从机制上规避。

2.4 参数速查表与选型建议

我把三种介质的关键差异整理成一张表,方便你在方案评审时直接对照:

介质典型容量接口擦写方式典型寿命掉电保留适合的数据
EEPROM2Kbit-2MbitI2C按字节写、无需擦除100 万次擦写10-100 年配置参数、校准系数
NOR Flash1MB-64MBSPI扇区擦除(4KB)+ 页编程(256B)10 万次擦写20 年以上固件镜像、FPGA 配置、关键日志
SD 卡512MB-32GBSPI/SDIO内部 FTL 磨损均衡取决于 P/E 周期静态数据可靠运行日志、历史曲线、升级包缓存

选型建议很直接:配置进 EEPROM,固件进 NOR Flash,日志进 SD 卡。有的方案为了省一颗芯片,用 NOR Flash 模拟 EEPROM 存参数——不是不行,但你要自己处理"读-改-擦-写"的原子性问题,还要保证 10 万次擦写寿命足够,复杂度远高于直接加一颗 EEPROM。EEPROM 也就几毛钱的事,别省。

3. 硬件架构与接口规划:STM32+FPGA 怎么把三块存储组织起来

介质选完了,接下来是电路和总线层面的组织。这个章节只讲架构相关的关键决策,具体时序配置留到下一节。

3.1 接口分配与总线带宽预算

STM32 这边,资源分配大概是这个格局:

  • I2C1:挂 EEPROM,400kHz 快速模式。EEPROM 数据量小,400kHz 足够,别为了跑更快用 1MHz 高速模式,对 PCB 布线更敏感,工业现场干扰下更容易出错。
  • SPI1:挂 NOR Flash,时钟 20-40MHz。这个 SPI 只服务 NOR Flash,不要跟其他设备共享,防止片选切换时残留数据搞坏 Flash 状态。
  • SDIO 或 SPI2:挂 SD 卡。优先用 SDIO 四线模式,因为日志写入是大流量;如果引脚资源紧张或对速度不敏感,SPI2 也能用,但带宽会差一个数量级。

FPGA 这边,它需要跟 STM32 之间有一个高速数据通路。我会用 FSMC 或者 FMC 接口把 FPGA 映射成 STM32 的外部存储器,STM32 直接读写 FPGA 内部的双口 RAM,速度可以跑到 10MB/s 以上。采集数据从 FPGA 的采集逻辑进双口 RAM,STM32 用 DMA 搬运到内存,再落 SD 卡。这条链路的好处是 STM32 的 CPU 几乎不参与数据搬运,中断负载极小。

3.2 掉电检测与硬件写保护电路

工业产品掉电是常态,不是异常。存储方案的成败就看掉电那一瞬间系统能做什么。

我的标准做法是 STM32 的PVD(可编程电压检测)加外部掉电检测组合。PVD 阈值设置在 2.9V 左右,当 VDD 跌到阈值以下,PVD 中断触发,STM32 立即停止一切非关键任务,进入掉电处理流程:把当前配置参数写回 EEPROM、把日志 buffer 刷到 SD 卡、关闭 NOR Flash 写使能。这个过程需要时间,所以电源后端必须有一个"续命电容"——超级电容 0.1F-1F,或者电解电容加大容量的组合,确保 PVD 触发后还能维持 5-50ms 的稳定供电。

写保护电路上,EEPROM 的 WP 和 NOR Flash 的 WP 都必须接可控引脚,不要直接接死。正常运行时 WP 置为允许写,PVD 掉电中断触发后,第一个动作不是去写数据,而是先把 WP 置为禁止写。这样做的好处是:哪怕后续电源跌落导致 MCU 跑飞,也无法对存储介质产生写操作,数据不会因为总线上的毛刺被改写。

3.3 地址空间与数据通路设计

逻辑上,把存储资源做一个统一抽象:

  • 配置参数区:EEPROM 从 0x0000 到 0x7FFF,按固定偏移区分参数版本、设备信息、用户配置、校准数据。每个逻辑段头部放 CRC 和状态字。
  • 固件区:NOR Flash 的低 1MB 放 Bootloader 和 FPGA 配置镜像,高地址区放应用镜像 A/B。做 A/B 双备份,升级时写非活动区,完成后切标志位。
  • 日志区:SD 卡用 FAT32,分区里建 LOG 目录,按天生成文件,单文件超过 50MB 自动滚动到下一个文件,保留最近 30 天。

这三块存储的物理地址空间完全独立,STM32 侧的驱动层按设备抽象。上层业务代码只调param_set()、log_write()这类接口,底层是 EEPROM 还是 NOR Flash,业务层完全不关心。这是架构层面最重要的分层,否则后期加一块存储就要改所有业务逻辑,会非常痛苦。

4. 实操细节:EEPROM 和 NOR Flash 读写时的关键几步

选型是纸面工作,真正决定产品可靠性的,是底层驱动的每一个时序和边界条件。

4.1 EEPROM I2C 读写:页写入、应答轮询与磨损管理

EEPROM 的驱动有三个关键点。

第一,页写入边界。AT24C256 的页大小是 64 字节,但 I2C 单次写操作一次最多写一页。这一页的物理地址必须对齐,如果你从地址 0x3F 开始写 10 个字节,第 1 个字节落在页 0 的末尾,剩下的 9 个字节会回卷写到页 0 的开头,而不是页 1。这是无数"EEPROM 数据错乱" bug 的来源。驱动里必须做分页处理:计算当前页剩余空间,逐页切分写入。

第二,应答轮询代替固定延时。写周期时间 tWR 典型值 5ms,最高到 10ms。如果用delay_ms(10)等,效率太低;用应答轮询,时序更紧凑且自适应。代码写法是:写入后发一个起始条件 + 器件地址 + 写位,收到 ACK 说明内部编程完成,继续下一条;NO ACK 就循环等待。

第三,磨损均衡。EEPROM 虽然寿命 100 万次,但如果每次都写同一个地址(比如计数器的当前值),这个地址很快耗尽,而整个芯片其他地址还是全新的。工业产品的计数器、运行时间累计这类高频参数,我建议用一种简单的轮转存储:把同一参数散落到 N 个地址,每次写下一个地址,读时扫描最近有效的那个,N 取 64 或 128,等于把寿命乘以 N。

4.2 NOR Flash SPI 操作:扇区擦除、写使能与状态轮询

NOR Flash 的驱动细节主要集中在状态处理上。

先强调最基本的顺序:写使能(0x06)→ 页编程(0x02)→ 等待 BUSY 清除 → 读状态确认。三条指令缺一不可,顺序错了或者中间被高优先级中断打断,极大概率写进去的是乱码。

扇区擦除是另一个耗时大户。擦除前务必做好两件事:一是确认擦除地址对齐到 4KB 边界,二是确认 WEL 位已经置 1。擦除过程中要轮询状态寄存器的 BUSY 位,不要用固定延时,因为擦除时间随温度和芯片批次变化很大,固定延时要么过长拖慢升级,要么过短直接擦除失败。

NOR Flash 还有一个"编程前检查"的细节:在写一页 256 字节之前,读取目标区的当前内容,确认全是 0xFF 或者确认旧数据已擦除。如果目标区有旧数据,页编程并不会覆盖,Flash 位只能从 1 变 0,0 不能变回 1,所以旧数据所在位直接写不进去。这个问题在调试的时候非常隐蔽:代码逻辑没问题,就是写一次成功,第二次再写同样地址直接失败,原因就是没擦除。

4.3 数据完整性与掉电恢复策略

存储驱动的更高一级要求是:任何时刻掉电,重启后系统都知道"上次写到哪一步了,这步数据是否完整"。

我的做法是"双区交替 + CRC + 状态标志"三层结构。以配置参数为例:

  • 把参数区划分为 A/B 两个区域,大小相同。区头放格式版本号、数据长度、CRC32、完整标志。
  • 写参数时,先写备用区,数据写完后再更新完整标志。标志有两种状态:COMMITTED(已提交)和PENDING(未完成)。
  • 上电读参数时,先检查 A/B 两区的完整标志,读 CRC 有效的那个。如果 A 区完整,B 区不完整,说明上次在写 B 中间掉电,直接用 A 区,下次写时先覆盖 B。

这个策略的核心是把"写数据"和"写完整标志"拆成两个不可分割的动作,而完整标志本身只占一个字节,单个字节的编程在掉电窗口里失败概率极低,加上 WP 保护,基本能做到 100% 掉电安全。

5. FPGA 在存储环节中扮演的加速与缓冲角色

存储虽然主控在 STM32,但 FPGA 不是旁观者。它在数据流入存储之前做了大量关键工作。

5.1 数据先入 FPGA RAM,再统一搬运的原因

工业采集系统的数据是源源不断的。如果 STM32 直接接管 AD 采样数据再写 SD 卡,会有两个问题:一是 STM32 的 CPU 会被中断和大块数据搬运占据太多时间,影响通信和实时控制;二是采样数据到达的节奏和 SD 卡写的节奏完全不同步,直接耦合会导致丢数据。

FPGA 做的事就是加一个缓冲水池。它把高速采集的数据按固定长度打成一个一个帧,存进内部的双口 RAM 或 FIFO;当积累了足够的数据块(比如 4KB),通过中断通知 STM32。STM32 用 DMA 一次性搬走,再落 SD 卡。这个异步过程消除了双方的速度失配,数据不会丢。

5.2 多通道采集的打包、定帧与时钟域处理

FPGA 端的数据帧格式要在方案阶段就定死。我常用的帧结构是:

  • 帧头 2 字节(固定值,如 0xAA55,用于同步)
  • 时间戳 4 字节(百微秒或毫秒计数,由 FPGA 内部时基产生,或从外部 GPS/PPS 同步)
  • 通道号 1 字节
  • 数据长度 2 字节
  • 数据负载 N 字节(对齐到 4 字节边界)
  • CRC32 4 字节

定帧的好处是 STM32 解析简单,掉电恢复时定位坏块容易。时钟域处理上,ADC 采样时钟通常是独立时钟域,而双口 RAM 的写入端、读取端各用一个时钟,全部走异步 FIFO,避免跨时钟域采样造成的数据错位。

5.3 与 STM32 的握手协议和状态机设计

FPGA 和 STM32 之间的交互不要做太复杂,我的经验是一个简单的寄存器组加两个中断就够了:

  • 状态寄存器:FPGA 报告 FIFO 空/半满/满、当前帧序号
  • 控制寄存器:STM32 控制 FPGA 启动采集、复位 FIFO、清中断
  • 数据寄存器:STM32 按地址读取双口 RAM
  • 中断信号:数据块准备好中断、FIFO 溢出中断

状态机方面,STM32 侧是标准"查询空闲 → 启动 DMA 搬运 → 等待完成 → 解析帧 → 落盘"循环;FPGA 侧是"半满置中断 → 等待 STM32 读取 → 释放空间 → 继续写入"。注意 FIFO 的半满阈值设置不要超过 STM32 DMA 单次搬运能力的 80%,否则高优先级任务抢占了搬运用时会溢。

6. SD 卡存储与文件系统的长周期验证

SD 卡是整套存储方案里最容易出问题的环节,因为文件系统把问题抽象得太高,出了问题反而不容易定位。这一节全是长期运行验证出来的实战细节。

6.1 FATFS 移植要点与格式化陷阱

FATFS 是小型嵌入式系统的事实标准,移植本身不难,但要配置好三个参数:

  • _FS_TINY:选 0 或 1 取决于 RAM 是否紧张,但日志写入场景我建议_FS_TINY=0,缓存大一点,批量写效率高很多。
  • _MAX_SS:如果 SD 卡容量超过 2GB,FAT32 要求扇区大小 512 字节,_MAX_SS设置成 4096 兼容大扇区卡。但要注意:如果 SD 卡实际扇区是 512,而_MAX_SS=4096,FATFS 会在初始化时按 4096 去读,可能读不到正确的引导扇区,导致挂载失败。稳妥做法是_MAX_SS=512,扇区大小只设 512。
  • _FS_LOCK:日志系统会同时管理目录和多个文件,把这个值设成文件句柄数的两倍,避免资源不足。

格式化陷阱:SPI 模式下的 SD 卡,如果直接用 STM32 程序初始化,遇到"这张卡在电脑上好好的,插到设备上挂载失败",大概率是卡的分区格式不对。SD 卡用专用工具格式化成 FAT32、簇大小 32KB、分区起始对齐到 1MB,不要用 Windows 默认的快速格式化(它有时候会写一个只被 Windows 认识的隐藏分区结构)。

6.2 掉电时丢文件问题的排查

掉电丢文件,行业里叫"FAT 表撕裂"。FATFS 在追加写数据时,先更新数据区,再更新 FAT 表,最后更新目录项。掉电点如果刚好落在"数据区已写、FAT 表还没更新"的窗口,重启后这个文件的簇链就断了,表现为文件存在但实际内容是空或者乱码。

解决思路有两个层面。应用层:日志文件不要攒到最后统一 flush,定期(比如每写完 4KB)调用f_sync(),把 FATFS 内部缓存强制落盘;另一个实用技巧是日志系统只操作固定两个文件名交替写(LOG1.LOG / LOG2.LOG),每次打开文件时先检查文件长度,异常长度就切换另一个文件,损失最多一个文件的数据。

驱动层:SD 卡写入用多块写命令(CMD25),比单块写(CMD24)效率高,但掉电风险窗口更长。权衡下来,我建议日志写入用单块写+外部缓存,写入频率做限速。测试下来,单块写模式下掉电损坏概率显著低于多块写,而且速度也足够工业日志使用。

6.3 写卡性能瓶颈与缓存策略

SD 卡标称速度的坑在于,那是顺序写大块数据的最优工况。日志系统如果每次只写几十字节,实际吞吐会跌到标称值的十分之一以下。原因是 SD 卡内部按页组织写入,每次小写都会触发读-改-写周期。

解决方式是分层缓存。STM32 内存开一个 8-16KB 的日志缓冲池,日志数据先填充缓冲池,到 4KB 对齐时调用一次写操作,用多块或单块连写。FPGA 端也做了同步配合,采集数据累积到一整个日志帧(比如 1KB 的整数倍)再交给 STM32,避免碎片化小写。实测下来,这个策略能稳定达到 SD 卡标称写速度的 60%-80%。

7. 常见问题排查与避坑记录

这个章节不是理论,是我在这些年调试工业控制器存储问题时,反复踩过的坑的总结。

7.1 问题速查表

现象可能原因排查方向
EEPROM 写入后读回部分数据错误页写跨页回卷检查写入地址是否跨页,分页写入
EEPROM 偶发写不进漏掉应答轮询,连续写分析 I2C 波形,确认每页写间隔
NOR Flash 写入失败,但读正常未先擦除,或 WEL 未置位读状态寄存器,确认擦除动作
NOR Flash 高低温下程序起不来扇区擦除时序不满足,固定延时太短换用 BUSY 位轮询,别用固定延时
SD 卡上电挂载失败分区格式不对或 SPI 模式初始化失败换读卡器格式化,或逻辑分析仪抓 CMD 响应
掉电后配置参数随机丢WP 未接管,或参数区未做双区备份检查掉电时序,确认 WP 置位顺序
掉电后日志文件损坏FAT 撕裂,掉电时未 flush增加 f_sync 频率,双文件轮转
FPGA 缓存数据错位跨时钟域未处理检查异步 FIFO 是否规范,帧头是否同步

7.2 我踩过的几个坑

第一个坑是 EEPROM 页写回卷。当年做校准系统,工程师写了一个通用的 "写入任意长度" 函数,逻辑看着没问题,数据库遍历测试也好,但现场客户反馈校准参数偶尔错乱,重新校准一次又好了。查到最后,是函数没处理页边界,7100 系列芯片页大小 8 字节,写 10 字节就有大概率回卷。后来所有 EEPROM 驱动都强制做分页切分,不再允许裸写。

第二个坑是 NOR Flash 的擦除延时。当时用固定延时 100ms 等擦除完成,常温没问题,低温试验 -40 度时,擦除时间翻了倍,程序直接擦到一半就返回来继续写页编程,结果固件上电起不来。改成 BUSY 位轮询后,高低温一律通过。从此我给自己立了一条规矩:凡是有内部编程状态的芯片,一律用状态轮询,不用固定延时。

第三个坑是 SD 卡连续写死机。设备连跑 72 小时,SD 卡写入突然卡住,表现出来是f_write返回 OK 但等待时间无限长。查下来是 FATFS 的f_sync在高频调用时和 DMA 搬运冲突,一个在写 FAT 表,一个在覆盖 buffer,二者没有互斥。加一个信号量保护文件系统操作后,问题彻底消失。多任务下文件系统不加锁,迟早出事。

7.3 调试工具与排查方法

存储相关的疑难问题,光用调试器看变量是不够的,我常用的工具组合是逻辑分析仪 + 示波器。

逻辑分析仪抓 I2C 和 SPI 时序最有效率,尤其适合确认 ACK/NACK 时序是否符合预期。20MHz 采样率就能覆盖常见存储接口。遇到 EEPROM 写失败,直接抓 I2C 总线上有没有应答轮询和等待时间;遇到 NOR Flash 擦除失败,抓 SPI 的读状态寄存器命令是否正常发出。

示波器则用来测掉电相关的问题。PVD 中断触发电平设置、掉电后供电曲线是否满足 5ms 以上的稳定窗口、WP 置位的时序和电源跌落是否在允许窗口内,这些都需要示波器来量。掉电保护做得好不好,最终就是看这两条曲线:系统供电下降沿,和 WP 引脚的动作沿,两者时间差一定要留够余量。

7.4 给方案定型前的最后检查清单

送样前我会对照着检查一遍,这几项都过了,存储部分的可靠性才有底气:

  • EEPROM 驱动做了页写切分,且写周期用应答轮询
  • NOR Flash 擦写全部走状态轮询,Bootloader 区块保护已使能
  • 配置参数区双区交替 + CRC,掉电标志完整
  • SD 卡日志在每 4KB 数据后强制同步,文件采用双文件轮转
  • 掉电检测触发后,WP 引脚动作早于数据写入
  • SD 卡格式化规范,簇大小 32KB,分区起始对齐
  • FPGA 到 STM32 的帧格式有 CRC 校验,FIFO 溢出有告警
  • 文件系统操作加互斥锁,DMA 和 CPU 访问不冲突

这套分级存储方案在我经手的几个工业控制器项目里运行下来,EEPROM 部分几乎没有返修,SD 卡日志在最极端情况下也只出现过一次坏文件,靠双文件轮转自动恢复了。做工业硬件,存储方案的架构价值要在现场跑几个月后才能体现出来——前期多花点心思在这上面,比后期去现场救火要划算得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 1:33:08

Lp空间与lp序列空间:从范数定义到对偶理论的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 1:32:45

Windows启动模式判断:UEFI与Legacy BIOS精准识别指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 1:32:36

Mac虚拟机安装Windows 10全指南:Parallels Desktop配置与排障详解

前几天一个朋友找我,说公司财务系统强制要求Windows环境,而他手里只有一台MacBook。这大概是Mac用户最常遇到也最头疼的场景之一。我的回答一直很直接:装个虚拟机,首选Parallels Desktop,系统装Windows 10。这篇文章就…

作者头像 李华
网站建设 2026/9/30 1:32:08

Windows Server 2012多用户RDP并发登录原理与合规方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 1:30:22

从选型到实战:用Python Pyecharts打造交互式图表与HTML报告

很多人问我“现在做Python图表,到底该学Matplotlib还是Pyecharts?”我一般不会直接回答学哪个,而是反问一句:你要的是论文用的静态配图,还是要一份能点、能缩放、能交出去的HTML报告?如果是后者&#xff0c…

作者头像 李华