VisualHMI RW

版本 内 容 摘 要 日期
V1.0 首次发布 2026/3/18

VisualHMI RW 存储区使用说明与寿命风险提示

VisualHMI 提供 RW(掉电保持)存储区,地址范围 0x0000~0x7FFF,共 64 KB(32,768 × 2 字节)。该区域基于 Flash 存储介质实现,出厂时默认值为 0xFFFF(Flash 空白状态)。

⚠️ 关键风险说明

  1. Flash 寿命限制: Flash 存储单元的额定擦除次数约为 10 万次。每次擦除操作均会导致存储单元电子栅逐渐退化,超过额定次数后电荷无法稳定保持,导致数据丢失或错误。
  2. 内部写入机制: 系统内置 4 KB 写入缓存队列,大约每累积 400 次写入 后触发一次 Flash 擦写操作。频繁、分散的写入将显著加速擦除次数消耗
  3. 严重系统风险: RW 存储区与固件存储区域物理相邻。若 RW 区因过度擦写导致 Flash 单元失效,可能扩散至固件区域,造成:
    • 固件数据损坏(即使单个比特错误)
      • “黑屏,设备无法启动
      • “no firmware” 蓝屏错误,设备无法启动
    • RW数据损坏损坏
      • RW区域掉电不存储
  4. 按扇区顺序落盘: RW 日志缓存写满后,系统会按扇区地址从低到高依次写入 Flash,而不是按“最后一次修改顺序”写入。以 4 KB 扇区为例,RW0000~RW07FF 所在扇区会早于 RW0800~RW0FFF 写入,最后才轮到高地址扇区。因此即使先修改了高地址标志位,后续又修改了低地址参数,真正落盘时仍可能是低地址扇区先写、高地址扇区后写。
  5. 跨扇区标志位存在一致性风险: 若“初始化标志位 / 有效标志位”与其保护的参数不在同一扇区,则掉电或异常中断时,可能出现“参数已部分写入,但标志位未落盘”或“标志位已更新,但部分参数未完成”的情况。此时仅依赖单个远端标志位判断 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 存储区适用于非频繁更新的配置参数或历史数据记录,严禁用于高频实时数据保存。正确规划存储策略与写入方式,是保障系统长期稳定运行的关键。

Copyright ©Dacai all right reserved,powered by Gitbook该文件修订时间: 2026-05-09 16:27:10

results matching ""

    No results matching ""