Visual HMIファイルIO:LUA読み書きSDカード/USBドライブ/フラッシュとカタログ列挙

無料無料技术资料

这篇内容可直接阅读,适合用于基础学习和検索引流。

ファイル読み書きAPIのフルスイート:txt/csv/binの読み取り、ファイルの書き込み、ディレクトリのトラバース、コピー/削除。基本的なアイデアは1つです。ストリーミング、メモリに2 KB以上のバッファを同時に存在させない。HMIメモリは非常に小さく、ウォッチドッグの直接リセットに違反し、デバイスは警告なしに再起動します。

1.ストレージデバイスID(Mシリーズvs DHシリーズ)

設備はMシリーズDHシリーズ
SDカード。1:/1.txt/sdcard/1.txt
Uディスク。2:/1.txt/udisk/1.txt
内部 Flash3:/1.txt/data/1.txt

パスの区切り文字は/でなければなりません。

2.ドキュメントAPI概要

関数の機能パラメータ説明書は
dofile(name)luaファイルのパスロード実行.luaモジュール、大規模プロジェクトのモジュール解除
list_dir(path)ディレクトリ·パスディレクトリを非同期スキャンし、結果を項目ごとにコールバックon_list_dir
on_list_dir(path,filename,type,fsize)type 0=フォルダ/1=ファイル;fsizeバイト検索結果のコールバック、検索されたエントリごとに1回
file_open(path,mode)mode 0= FA_READ読み取り専用/1= FA_WRITE上書き書き込み/2= FA_WRITE_ADD追加書き込みファイルを開き、ブール値を返す
file_close()-ファイルを閉じ、書き込み後に調整する必要があり、データのドロップ防止
file_size()-現在開いているファイルの合計バイト数
file_seek(offset)バイトオフセット、0=ファイルの開始読み取りと書き込みの位置
file_read(count)1 ≤ count ≤ 2048バイト配列(テーブル、インデックス1から)を読み取り、失敗してnilを返す
file_write(data)バイトテーブル、1 ≤ #data ≤ 20 4 8バイト配列を書き込み、ブール値を返す
file_delete(path)フルパスを参照。ファイルの削除、復元不可
file_copy(src,dst)ソース/ターゲットフルパスファイルのコピー、進行状況コールバックon_copy_file_process
on_copy_file_process(status,filesize,transfersize)status 0失敗/1進行中/2成功コピーの進行状況コールバック、transfersizeコピーされたバイト
mkdir(dir)完全なディレクトリパス同期フォルダの作成

3.メモリセキュリティ

複数の読み取りデータをグローバル変数や長寿命バッファに蓄積することは禁止します。典型的なエラー:最初の読み取りは2 KBグローバルテーブルを格納し、その後の読み取りは毎回追加されます。大きなファイルを処理するとメモリが成長し続け、ウォッチドッグのリセットが直接トリガーされます。

正しい姿勢:フロー処理--各file_read(2048)の直後に解析/検証/書き込み/表示され、処理が完了すると解放され、いつでもメモリ内には≤ 2 KBの一時バッファが1つしかない。ファイルを書くのと同じです:一度に2048バイト以下のブロックを準備するたびに、一度にfile_writeを作成し、最初に数MBの大きなテーブルをスクランブルしないでください(データ準備段階でメモリオーバーフローが発生します)。

4.ファイルの読み取りストリーミングチャンク+コールバック

正式に閉鎖。file.read_stream(filepath, on_chunk)開く→サイズを取る→ループseek+readコールバックはfalseを返し、大きなファイルループはfeed_dogを犬にフィードします。

4.1 txtを読む行ごとに表示

addr === 0 x 1501の場合
  local idx = get_uint16 vtype addr
  Ix == 0の場合、終了を返す
  local path = idx == 1 and "1/1.txt" or "1/2.txt"
  record_clear 0
  g_line_bu = """                       - ラインバッファ。
  file.read_stream path function chunk offset is_last
    local str = ""
    for _b in ipairs chunk do =.. string.char b end
    g_line_bu = g_line_bu.. str
    local lines = my_split g_line_buffer "n"--行ごとに分割
    g_line_buffer = lines[#lines]          --不完全な行を保持するブロックにまたがる可能性がある
    for i = 1 #line-1 do
      if #lines[i] 0 then record_write_string 0 lines[i] end
    End of Endシングル
    真のリターン
  end nParticle
  if string.len g_line_buffer 0then    - 最後の行。
    record__string 0 g_line_bu
  End of Endシングル
End of Endシングル

クロスブロック行バッファに注意してください:改行は2つのブロックの間に入る可能性があるので、g_line_bufferを維持して不完全な行を次のブロックに残します。

4.2 binを16バイト1行で読み取る

elseif addr == 0 x 150 2 then
  local idx = get_uint16 vtype addr
  Ix == 0の場合、終了を返す
  local path = idx == 1 and "1/1.bin" or "1/2.bin"
  record_clear 1
  g_byte_bu = {}
  file.read_stream path function chunk offset is_last
    for _b in ipairs chunk do
      table.insert g_byte_buffer b
      if #g_byte_buffer = 16 then        --フル16バイトごとに1行コミット
        ローカル線= {}
        for i = 1 16 do line[i] = g_byte_bu [i] end
        record_write_data 1、line
        for i = 1 16 do table.remove g_byte_buffer 1 end
      End of Endシングル
    End of Endシングル
    真のリターン
  end nParticle
  if #g_byte_buffer 0 then              --末尾が16バイト未満で補数0
    while #g_byte_bu16 do table.insert g_byte_bu0 end
    record__data 1 g_byte_bu
  End of Endシングル

5.文書を書く。

カプセル化するfile.write_chunk(filepath, data, mode)モード1=上書き書き込み、2=追加書き込み、データは文字列またはバイトテーブル(≤ 20 4 8)をサポートします。

function file._chunk filepath data mode
  if mode ~= file.mode.create and mode ~= file.mode.append false endを返す
  local t = type data
  local len = t == "string" or t == "table" and #data or -1
  もしlen chunk_sizeがfalseを返す   - メモリオーバーフロー防止
  local ok = file_open filepath mode
  OKでない場合はfalse endを返す
  mode == file.mode.append then            -- 追加モードは手動で設定する必要があります!
    local size = file_size
    if not file_seek size then file_close; return false end
  End of Endシングル
  local buf = {}
  if t == "String" then
    for i = 1 len do buf[i] = string.byte data i end
  elseさん
    for i = 1 len do buf[i] = data[i] end
  End of Endシングル
  local ret = file_buf
  file_cl
  Return toレット
End of Endシングル

シナリオ1:新規執筆
local name = get_string VT_LW、0x1510
local msg = get_string_LW、0x1520
名前がない場合、#name == 0またはmsgでない場合、終了します。
file._chunk "1/"..名前は。".txt"、msg..“n”1

シナリオ2:追加書き込み
file._chunk "1/"..名前は。".txt"、msg..“n”2

️追加の書き込みは明示的にfile_seek file_sizeを行う必要があります。HMIのfile_open(mode=2)はPOSIXのO_APPENDと等しくないため、自動的に最後に設定されません。seekせずにオフセット0から書き込みを開始し、元のファイルの先頭を上書きします。

6.トラバース+コピー削除

6.1 SDルートをトラバースしてデータログコントロールに表示

function get_extension
  local dot = string.find filename ". "1 true
  If Dot Thenより
    return string. 1 dot-1 string. dot +1 l
  End of Endシングル
  return filename "不明"
End of Endシングル

function on_list_dir path、、type、fsize
  ローカルMSG
  type == 0の場合
    msg = filename..“;フォルダ;”
  elseさん
    ローカルSz
    if fsize = 1024 ^3 then sz = string." %. 2fG" fsize/1024 ^3
    elseif fsize = 1024 ^2 then sz = string." %. 2fM" fsize/1024 ^2
    elseif fsize = 1024 then sz = string." %. 2fKB" fsize/1024
    else sz = fsize.. "byte" end
    local name ext = get_extension
    msg = name.. ";".. Ext..。";".. SZ..。";"
  End of Endシングル
  record_write_string 2、msg
End of Endシングル

更新ボタンLW1504=1
function on_update slave vtype
  if vtype ==_LW then
    if addr === 0x1504 and get_uint16 vtype addr == 1 then
      record_clear 2
      list_dir "1"          --SDルートディレクトリを横断する
    End of Endシングル
  End of Endシングル
End of Endシングル

6.2コピー +削除(プログレスバー付き)

function on__file_status filesize transfersize
  ステータス== 0の場合
    set_uint16 VT_LW、0x1507、3           - 失敗した
  elseif status == 1 then
    local p = math.floor transfersize * 100 / filesize
    set_uint16 VT_LW、0x1506、p           - プログレス·バー
    refresh_screen
  elseifステータス== 2倍
    set_uint16 VT_LW、0x1506、100
    set_uint16 VT_LW、0x1507、2           【成功】
    refresh_screen
  End of Endシングル
End of Endシングル

function on_update slave vtype
  vtype == VT_LWとaddr == 0 x 150 5の場合
    local mode = get_uint16 vtype
    mode == 1の場合                      - コピーする。
      if file.exists "1/1.txt" then
        file_copy "1/1.txt"、"1/1_copy.txt"
      elseさん
        set_uint16 VT_LW、0x1507、1
      End of Endシングル
      mkdir "1/test"
    elseif mode == 2 then                  --削除する
      file_"1/test"
      if file.exists "1/1_y.txt" then
        file_"1/1_y.txt"
        if not file.exists "1/1_y.txt" then
          set_uint16 VT_LW、0x1507、4
        elseさん
          set_uint16 VT_LW、0x1507、5
        End of Endシングル
      elseさん
        set_uint16 VT_LW、0x1507、1
      End of Endシングル
    End of Endシングル
    refresh_screen
  End of Endシングル
End of Endシングル
5つの穴がある。メモリの鉄の法則-大域累積大バッファの禁止一度に≤ 2 KBのブロックのみを保持するか、ウォッチドッグがリセットされます。2追加の書き込みはfile_seek file_sizeHMIのappendはO_APPENDではない。パスにはデバイスプレフィックスと/が必要です。--“1/config.txt”が正しく、“1 config.txt”が間違っています。④大きなファイル読み込みループでは_dogが必要時間のかかることを避ける。⑤ファイル书き込み直后file_cl停電はファイルや部分的な書き込みを損傷します。

広州大彩科技Visual HMI開発ドキュメント(hmi-doc.gz-dc.com)LUAチュートリアル“ファイルの読み書き”、著作権は大彩科技に帰属します。

この資料を実際のプロジェクトに活用しませんか?

ツールセンターで電文解析、CRCチェック、デバイスデバッグを行うか、要件を送信して選定と接続のアドバイスを受けましょう。

エンジニア会員

この記事を実行可能なデバッグ資料に

登録すると、高度な電文解析、資料パックのダウンロード、コード例、エンジニアリングケース、優先技術サポートが利用可能に。実際のプロジェクト納品に最適です。

高度なツール無制限
資料パックとコードパック
完全なエンジニアリングケースライブラリ
優先技術サポート窓口

发表回复

あなたのメールアドレスアドレス不会被公开。 必須項目已用 * 标注