本文目录
- 1. 1. Flash 寿命风险(必须知道)
- 2. 2. 按扇区顺序落盘(重要机制)
- 3. 3. 使用建议
- 4. 4. 推荐初始化写法
RW 是 VisualHMI 的掉电保持存储区(64KB,地址 0x0000~0x7FFF,共 32768 个 16 位寄存器),基于 Flash 实现,出厂默认 0xFFFF。参数、配置、历史数据存这里,断电不丢。但这块区域有严重的寿命和使用规范问题,用不好会搞坏设备。
1. Flash 寿命风险(必须知道)
- 擦写寿命 10 万次:Flash 存储单元额定擦除约 10 万次,超限后电荷无法稳定保持,数据丢失或出错
- 4KB 写入缓存队列:系统内置 4KB 缓存,约每累积 400 次写入触发一次 Flash 擦写——频繁分散写入会加速消耗
- 严重系统风险:RW 区与固件区物理相邻,过度擦写导致 Flash 单元失效可能扩散到固件区:固件损坏、黑屏、”no firmware” 蓝屏、设备无法启动
2. 按扇区顺序落盘(重要机制)
RW 日志缓存写满后,系统按扇区地址从低到高依次写入,不是按”最后修改顺序”。以 4KB 扇区为例,RW0000~RW07FF 所在扇区早于 RW0800~RW0FFF 写入。因此:
- 即使先改高地址标志位、后改低地址参数,落盘时仍可能低地址先写、高地址后写
- 跨扇区标志位一致性风险:标志位和参数不在同一扇区时,掉电可能”参数写了一半、标志位没落盘”或反之——只靠一个远端标志位判断 RW 参数有效性不可靠
3. 使用建议
- 地址连续分配,避免频繁随机写入
- 优先用
set_array批量写入,减少擦写触发 - 控制写入频率;频繁保存的变量在逻辑层聚合后再写
- 按 400 次/擦除 的机制折算实际寿命
- 标志位和参数放同一扇区(如参数 RW1000~RW100F,标志位放同区,别放 RW7FFF)
- 启动必做边界值检查:即使标志位对,也要校验参数范围,读到 0xFFFF/越界值恢复默认
- 别发现一个异常值就写一次 RW——集中读取、统一判断、一次性修正
4. 推荐初始化写法
不推荐(标志位在远端):
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 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 区只适合非频繁更新的配置/历史数据,严禁高频实时数据。400 次写入才擦一次,看着省,但 10 万次擦除寿命 ÷ 每天擦写次数 = 实际可用天数,算清楚再设计存储策略。
整理自 广州大彩科技 VisualHMI 开发文档(hmi-doc.gz-dc.com)LUA 教程「RW 存储区」,版权归大彩科技所有。
发表回复