VisualHMI 简易데이터库:easydb_* 与데이터记录控件自定义모드

무료무료 기술 자료

이 글은 바로 읽을 수 있으며 기초 학습과 검색 유입에 적합합니다.

简易데이터库(定制固件专属)是一个轻量级、无文件系统的嵌入式데이터库:在 Flash 里划一块连续区域,按固定길이记录存结构化데이터(매개변수설정、事件로그、运行记录),掉电不丢,支持运行时按需初始化。데이터记录控件用「自定义」데이터源모드对接,实现增删改查全流程。

1. ⚠️ Flash 주소规划(不看会变砖)

简易데이터库直接操作 Flash,没有文件系统隔离机制,flashaddr 시작주소必须严格避开四类高风险区域:

  • 엔지니어링자료存储区
  • 자료采样块存储区
  • 操作记录块存储区
  • OTA 업그레이드备份区域

总占用空间 = 데이터RowSize × maxCount,规划주소时把这段空间算进去,别和别的功能打架。

2. API 总表

函数매개변수설명
easydb_열기(flashaddr, createIfNotExist, 데이터RowSize, maxCount)flashaddr Flash 시작주소;createIfNotExist 0=仅열기/1=不存在则创建;데이터RowSize ≥1;maxCount 最大条数열기或创建데이터库,返回句柄(非 0 成功,0 失败)
easydb_close(db)句柄닫기데이터库,释放자료
easydb_get_count(db)句柄当前有效记录数
easydb_get(db, idx)idx 从 0 开始读指定索引记录,成功返回문자串,失败 nil
easydb_add(db, 데이터set)문자串데이터末尾追加一条记录
easydb_update(db, idx, 데이터set)idx + 新콘텐츠更新指定记录,데이터set 길이必须严格等于 데이터RowSize
easydb_del(db, idx)idx삭제指定记录
easydb_clear(db)句柄모두 지우기记录

3. 데이터记录控件「自定义」모드

데이터来源设为自定义时,系统不知道有多少行데이터,必须由两个回调提供:

  • 记录数量回调 on_get_record_count(screen_id, control_id):返回总行数,内部调 easydb_get_count(g_db_handle)
  • 记录콘텐츠回调 on_get_record_row(screen_id, control_id, row):返回第 row 行的문자串콘텐츠
function on_get_record_count(screen_id, control_id)
  if screen_id == 0 and control_id == 1 then
    return db.getCnt(g_db_handle)
  end
end

function on_get_record_row(screen_id, control_id, row)
  local ret, msg = db.get(g_db_handle, row)
  if ret == 0 then
    return msg
  end
end

控件설정:데이터来源=自定义、문자编码=UTF8、翻页控制√、控制주소 LW4000、选中行通知√(LW4004,UINT32)——选中某行时索引写进 LW4004,增删改都靠它定位。

4. 적용:db.lua 句柄封装 + 增删改查

4.1 初始化(on_init)

function on_init()
  dofile("db.lua")
  _EN_ON_UP데이터_API_ = 0
  -- 10MB 시작、不存在则创建、单条1000바이트、最多1000条
  g_db_handle = db.열기(10*1024*1024, 1, 1000, 1000)
  if g_db_handle == 0 then
    print("ERROR: 无法열기데이터库!")
    return
  end
  db.clear(g_db_handle)               -- 지우기旧데이터(可选)
  db.add(g_db_handle, "Alice;Engineer;30")
  db.add(g_db_handle, "Bob;Technician;25")
  db.add(g_db_handle, "Charlie;Manager;40")
  db.add(g_db_handle, "Harden;Basketball players;36")
  _EN_ON_UP데이터_API_ = 1
end

记录형식「姓名;职业;年龄」,英文分号分隔,和表格控件분석规则一致,直接映射多列。

4.2 增删改(LW5000 按键分发)

function on_update(slave, vtype, addr)
  if addr == 0x4004 then              -- 选中行通知
    local idx = get_uint32(VT_LW, addr)
    local ret, msg = db.get(g_db_handle, idx)
    if ret == 0 then
      local parts = my_split(msg, ";")
      if parts ~= nil then
        set_uint16(VT_LW, 0x4530, idx)   -- 记录当前选中索引
        set_string(VT_LW, 0x4500, (parts[1] == nil) and "--" or parts[1])
        set_string(VT_LW, 0x4510, (parts[2] == nil) and "--" or parts[2])
        set_string(VT_LW, 0x4520, (parts[3] == nil) and "--" or parts[3])
      end
      show_dialog(1, 232, 33, 50)        -- 弹窗显示详情
    end
  elseif addr == 0x5000 then
    local key = get_uint16(VT_LW, addr)
    if key == 0 then                    -- 추가
      local name = get_string(VT_LW, 0x5010)
      local position = get_string(VT_LW, 0x5020)
      local age = get_string(VT_LW, 0x5030)
      db.add(g_db_handle, name..";"..position..";"..age..";")
    elseif key == 1 then                -- 修改(改选中行)
      local name = get_string(VT_LW, 0x4500)
      local position = get_string(VT_LW, 0x4510)
      local age = get_string(VT_LW, 0x4520)
      local idx = get_uint16(VT_LW, 0x4530)
      db.modify(g_db_handle, idx, name..";"..position..";"..age..";")
    elseif key == 2 then                -- 삭제(删选中行)
      local idx = get_uint16(VT_LW, 0x4530)
      db.del(g_db_handle, idx)
    end
  end
end

db.lua 封装层每个函数都做句柄체크섬 + 索引越界检查(idx = count 返回 -2),这是句柄驱动设计的표준姿势:不合法就直接返回错误码,绝不往下传。

四个坑:①flashaddr 必须避开엔지니어링자료/자료采样/操作记录/OTA 备份四区,直接操作 Flash 无隔离,选错주소데이터互相覆盖甚至变砖;②easydb_update 的 데이터set 길이必须严格等于创建时的 데이터RowSize,长了短了都会失败;③记录用英文分号 ; 分隔,和表格控件분석规则对齐,别用중국어分号;④句柄是全局生命周期자료,on_init 里开一次全程持有,操作前先체크섬句柄非 0、索引在范围内。定制固件才有这套 API,普通固件没有。

整理自 广州大彩科技 VisualHMI 개발문서(hmi-doc.gz-dc.com)LUA 튜토리얼「简易데이터库」,版权归大彩科技所有。

실제 프로젝트에 이 자료를 활용하시겠습니까?

도구 센터에서 프레임 분석, CRC 검증, 장비 디버깅을 진행하거나 요청을 제출하여 선정 및 연동 제안을 받아보세요.

엔지니어 회원

이 글을 실행 가능한 디버깅 자료로 활용하세요

가입하면 고급 프레임 분석, 자료 패키지 다운로드, 코드 예제, 엔지니어링 사례, 우선 기술 지원을 이용할 수 있어 실제 프로젝트 납품에 적합합니다.

고급 도구 무제한 이용
자료 패키지와 코드 패키지
완전한 엔지니어링 사례 라이브러리
우선 기술 지원 채널

답글 작성

이메일 주소는 공개되지 않습니다. 必填项已用 * 标注