三個概念先分開
可見性回答誰能用名稱存取,生命週期回答資料在連續呼叫間何時建立與重設,斷電保持回答重啟、下載或清除後是否恢復。全域變數可能人人看得到卻不保持;局部 Function Block 變數可在同一實例跨呼叫保留狀態,也不代表斷電後仍在。
案例使用四種資料:累計產量 TotalGood、暫存索引 BufferIndex、Busy 狀態與配方校驗 RecipeCrc。TotalGood可能需要保存,BufferIndex通常重建,Busy不能盲目保持,RecipeCrc用來判斷保存設定是否仍與目前配方相符。先寫用途再選作用域與保存政策。
實作時先畫一張資料所有權圖:批次模組唯一寫TotalGood,緩衝模組唯一寫BufferIndex,流程模組唯一寫Busy,配方模組唯一寫RecipeCrc。其他模組只能讀取快照或提出命令;這比把所有欄位放進全域區更容易追蹤。
若資料被多個畫面讀取,讀取者不代表所有者;重置命令仍應回到批次模組。可見範圍越大,越要用命名與介面限制寫入。
以下是教學偽碼與離線案例,不能直接編譯。跨呼叫狀態來自同一FB實例仍存在,不等於平台提供斷電保存;實際宣告、初始化和重啟行為依CPU與工程軟體手冊核對。
同一 FB 實例跨呼叫
假設fbBatch收到GoodEdge便把TotalGood加一,並將BufferIndex指向下一格。只要實例未重建或重置,下一次呼叫可讀到自己的上次資料;這是正常執行生命週期,不需要變數是全域,也不表示關機後一定恢復。
| 資料 | 正常呼叫 | 重啟策略 | 保持判斷 |
|---|---|---|---|
| TotalGood | 沿用累加 | 依政策恢復 | 需明訂 |
| BufferIndex | 指向下一格 | 掃描重建 | 通常不直接保持 |
| Busy | 工作中TRUE | 清FALSE再握手 | 不盲保持 |
| RecipeCrc | 比對版本 | 重算核對 | 可保存證據 |
Busy在Start接受時變TRUE,完成或Cancel才變FALSE。它描述目前運轉上下文,重啟後不應直接照舊恢復;應先清FALSE,再檢查命令、回饋與流程前提。保存舊Busy可能讓畫面顯示工作中,實際設備卻早已失去上下文。
連續呼叫測試要固定同一個FB實例。若每次都宣告暫時實例,前次狀態自然不會留下;若宣告持久實例卻在初始化分支每掃描重設,也會看起來像生命週期錯誤。先看實例存在時間,再看初始化條件。
測試時連續呼叫三次,再故意送Reset一次,觀察哪些欄位清除、哪些欄位保留。這能把正常生命週期與應用程式自訂復歸分開。
每個跨模組資料指定唯一所有者,其他程式透過介面使用;作用域不是權限系統,即使平台允許全域存取,也應限制寫入者。
斷電保持依平台核對
CODESYS官方Reset範例中,普通變數在Warm時回初值,RETAIN在Warm保留但Cold回初值,PERSISTENT在Warm與Cold保留,Origin則全部回初值。這是重置命令的規則;非預期斷電能否可靠保存還取決於目標設備與持久化機制,不能只看宣告。
對Q06UDVCPU所屬QnU範圍,SH080807ENG-AF第4.2.3與4.2.4分別說明M內部繼電器與L鎖存繼電器:M不因名稱或全域使用而取得斷電保持,L採電池備援保持。仍需核對電池狀態、清除與重置操作;這不等於L可無條件永久保存,也不適用於所有其他三菱系列。
不同重啟的預期不可混為一談。Warm、Cold、下載和清除保持記憶都要獨立列行;每行附上設定檔、操作步驟與預期證據。沒有做過的行標為待驗證,不寫成通過。
電池異常的案例只能依手冊與工程設定驗證,不能從變數編號猜保存結果。若證據不足,就讓啟動流程把資料標成無效並要求確認。
在CODESYS獨立Reset試驗中,可把三種變數初值都設0,試驗前各寫37;Warm預期0、37、37,Cold預期0、0、37,Origin預期0、0、0。每列都從各寫37的新基線開始,不把前一列的結果當下一列起點;真正觀察值另欄記錄。
建立Cold、Warm、下載、清除保持與電池異常矩陣,記錄啟動前後值和證據。不用一次重啟看到數值仍在,就推論所有類型都保持。RecipeCrc可在啟動重算並比對,不一致便拒絕舊設定。
四種資料的重建案例
假設批次完成後TotalGood=120、BufferIndex=7、Busy=FALSE、RecipeCrc=0x31A2。一般重啟後,TotalGood依平台及報表政策核對,BufferIndex由有效資料重建,Busy清除並重新握手,RecipeCrc重算比對。四欄不能用一個保持開關處理。
| 情境 | TotalGood | BufferIndex | Busy | RecipeCrc |
|---|---|---|---|---|
| 連續呼叫 | 120並累加 | 7 | 依流程 | 0x31A2 |
| 一般重啟 | 依配置 | 重建 | FALSE | 重算 |
| 清除保持 | 預設或無效 | 重建 | FALSE | 重新確認 |
| 電池異常 | 待核對 | 重建 | FALSE | 拒絕舊值 |
表中的依配置核對不是通過證據;測試紀錄要寫CPU、記憶區、電池、下載選項和Reset命令。若產量不可遺失,還要有資料庫或上位系統交付策略,單靠PLC變數名稱不能證明報表可靠保存。
RecipeCrc只表示保存內容與校驗值相符,不能保證配方適合目前硬體。啟動時還要核對設備型號、量程和版本;不相符便讓設定失效並要求重新確認。
若產量跨班次保存,應把批次號與保存時間一併記錄;單獨一個TotalGood無法說明它屬於哪一段生產資料。
若啟動時資料無法驗證,預期結果應是明確無效與可追查,而不是悄悄採用零。保留原始檔、校驗值和啟動事件,才能在後續報表核對時知道資料曾經被拒絕。
BufferIndex應掃描有效記錄或序號重建,不直接相信斷電前索引。Busy則反向處理:清除後重新建立狀態,比假裝流程仍在更容易驗收。
完成預期 排查與 FAQ
完成後每欄都要回答:唯一寫入者是誰、同一實例下次呼叫讀到什麼、每種重啟後要恢復還是重建。驗收記錄包含初值、呼叫次數、重啟類型、下載或清除選項、電池條件、實際值與手冊章節。
失敗先查作用域、同名變數、實例是否相同、初始化是否每次呼叫執行,再查Reset類型與保持區。在隔離示範的啟動流程中,Busy不符時先查重建規則,不直接手動改位元;真實設備需先確認輸出、回饋與未完成工作的處置。TotalGood少一筆時查提交時機和斷電窗口。
FAQ:一、局部FB變數會跨呼叫嗎?同一實例未重置時可以,但不等於斷電保持。二、全域就是保持嗎?不是。三、Busy能保持嗎?本案例不直接保持,重啟後重建。四、Q06UDVCPU的M/L都能斷電保持嗎?不能,QnU手冊區分M與電池備援的L,仍需核對保存條件與清除操作。
適用限制:CODESYS來源用於RETAIN/PERSISTENT具體差異;Q系列只引用官方手冊,不擴張未驗證規則。
參考:CODESYS 持久資料
參考:CODESYS Resetting Applications
問答之外,交接文件應保存變數名稱、初值、所有者、清除條件和重啟矩陣。下一位工程師才能從資料用途推回保存決策,而不是看到RETAIN或M字樣就自行猜測。
四個FAQ回答的是設計政策,不是平台承諾;移植前仍要逐項閱讀目標CPU的記憶體與重置章節。