VisualHMI RW
| 版本 | 内 容 摘 要 | 日期 |
|---|---|---|
| V1.0 | 首次发布 | 2026/3/18 |
VisualHMI RW 存储区使用说明与寿命风险提示
VisualHMI 提供 RW(掉电保持)存储区,地址范围 0x0000~0x7FFF,共 64 KB(32,768 × 2 字节)。该区域基于 Flash 存储介质实现,出厂时默认值为 0xFFFF(Flash 空白状态)。
⚠️ 关键风险说明
- Flash 寿命限制: Flash 存储单元的额定擦除次数约为 10 万次。每次擦除操作均会导致存储单元电子栅逐渐退化,超过额定次数后电荷无法稳定保持,导致数据丢失或错误。
- 内部写入机制: 系统内置 4 KB 写入缓存队列,大约每累积 400 次写入 后触发一次 Flash 擦写操作。频繁、分散的写入将显著加速擦除次数消耗。
- 严重系统风险: RW 存储区与固件存储区域物理相邻。若 RW 区因过度擦写导致 Flash 单元失效,可能扩散至固件区域,造成:
- 固件数据损坏(即使单个比特错误)
- “黑屏,设备无法启动
- “no firmware” 蓝屏错误,设备无法启动
- RW数据损坏损坏
- RW区域掉电不存储
- 固件数据损坏(即使单个比特错误)
- 按扇区顺序落盘: RW 日志缓存写满后,系统会按扇区地址从低到高依次写入 Flash,而不是按“最后一次修改顺序”写入。以 4 KB 扇区为例,
RW0000~RW07FF所在扇区会早于RW0800~RW0FFF写入,最后才轮到高地址扇区。因此即使先修改了高地址标志位,后续又修改了低地址参数,真正落盘时仍可能是低地址扇区先写、高地址扇区后写。 - 跨扇区标志位存在一致性风险: 若“初始化标志位 / 有效标志位”与其保护的参数不在同一扇区,则掉电或异常中断时,可能出现“参数已部分写入,但标志位未落盘”或“标志位已更新,但部分参数未完成”的情况。此时仅依赖单个远端标志位判断 RW 参数是否有效,并不可靠。
✅ 使用建议
- 规划地址连续分配,避免频繁随机写入。
- 优先使用
set_array批量写入,减少单次擦写触发频率。 - 控制写入频率与数据量,若需频繁保存变量,建议通过逻辑层聚合写入操作。
- 一次写入多个 RW 变量时,应根据 400 次/擦除 的机制折算实际寿命,合理安排存储策略。
- 标志位应与参数放在同一扇区。例如参数位于
RW1000~RW100F,则其标志位应放在同扇区内,而不应放到类似RW7FFF的远端地址。 - 启动时必须做边界值检查。即使标志位正确,也应校验参数是否落在合法范围内;若读到
0xFFFF、越界值或明显异常值,应恢复到安全默认值。 - 减少多次重置操作。不要发现一个异常值就立刻写一次 RW;应先集中读取、统一判断、再尽量一次性修正,降低中途掉电导致“部分参数恢复、部分参数未恢复”的风险。
- 推荐使用“同扇区标志 + 参数边界检查”双重策略,不要只依赖一个全局初始化标志位。
推荐初始化方式
不推荐使用“参数与标志位分属不同扇区”的写法,例如:
local fst = get_uint16(VT_RW, 0x7FFF)
if fst ~= 0x55AA then
set_uint16(VT_RW, 0x1000, 0)
set_uint16(VT_RW, 0x1001, 80)
set_uint16(VT_RW, 0x7FFF, 0x55AA)
end
更推荐的做法是将标志位与参数放在同一扇区,并在初始化时同时进行边界值校验:
local RW_CFG_BASE = 0x1000
local RW_CFG_MAGIC = 0x17FF
local function clamp_u16(val, min_v, max_v, def)
if val == 0xFFFF or val < min_v or val > max_v then
return def, true
end
return val, false
end
function on_init()
local need_fix = false
local magic = get_uint16(VT_RW, RW_CFG_MAGIC)
local lang, bad1 = clamp_u16(get_uint16(VT_RW, RW_CFG_BASE + 0), 0, 2, 0)
local vol, bad2 = clamp_u16(get_uint16(VT_RW, RW_CFG_BASE + 1), 0, 100, 80)
if magic ~= 0x55AA then
need_fix = true
end
if bad1 or bad2 then
need_fix = true
end
if need_fix then
set_uint16(VT_RW, RW_CFG_BASE + 0, lang)
set_uint16(VT_RW, RW_CFG_BASE + 1, vol)
set_uint16(VT_RW, RW_CFG_MAGIC, 0x55AA)
end
end
总结
RW 存储区适用于非频繁更新的配置参数或历史数据记录,严禁用于高频实时数据保存。正确规划存储策略与写入方式,是保障系统长期稳定运行的关键。