顧小峰 肖五生
摘 要:從2016年開始,電能表引入了面向對象通信協議《DL/T 698.45面向對象的用電信息數據交換協議》,而此協議與原有電能表通信協議《DL/T 645—2007多功能電能表通信協議》相比,對電能表的資源需求有了一個明顯提高。主要體現是通訊緩存和記錄數據的需求量大幅提升。
關鍵詞:面向對象通訊協議;動態RAM;鏈路層分幀
中圖分類號:TM933 文獻標識碼:A 文章編號:1671-2064(2018)14-0098-02
1 背景描述
從2016年開始,電能表引入了面向對象通信協議《DL/T 698.45面向對象的用電信息數據交換協議》,而此協議與原有電能表通信協議《DL/T 645—2007多功能電能表通信協議》相比,對電能表的資源需求有了一個明顯提高。主要體現是通訊緩存和記錄數據的需求量大幅提升。
而我們這里主要講的是通訊緩存。通訊緩存從原先每通道212字節(數據域最大200+幀頭、幀尾等幀格式數據),上升到每通道512字節;而DL/T 698.45協議還支持鏈路層分幀,最到可處理APDU為2000字節,而這些幀數據都用RAM的話,那么每通道RAM需求量就至少需要2000+幀頭幀尾字節數據,又由于DL/T 698.45幀格式相對靈活,我們一般會預留到2K字節。這樣的話,一個通道的通訊緩存RAM需求,DL/T 698.45就比DL/T 645協議增加1836字節。對三相電能表來說,可能會有4個通訊通道,要保證各通道能同時通訊,RAM需求量就需要增加1836*4=7344字節;單相表會少1個通道,需增加1836*3=5508字節。
RAM的大幅度增加,勢必需要更換RAM更大的MCU,而對于成本要求很高的電能表來說,這勢必又是雪上加霜。
當然我們也可以考慮將緩存數據放到其它存儲器,比如EEPROM、FLASH等,但這里畢竟是通訊,要保證傳輸速度,而EEPROM、FLASH的存儲和讀取速度是相對較慢的,另外它們的使用壽命相對較小,要保證使用壽命,必須預留更多倍的存儲空間,這樣是非常不劃算的。
2 方案設計
不管是單相電能表,還是三相電能表,雖然都設計有多個通信通道,但現場應用時,一般只有一個通信通道在使用;如模塊表,基本是采用模塊進行數據傳輸,485表只采用485口。當然也不排除現場表型混用,如模塊表用于485口通訊的場合;由于通信模塊即使沒有采集終端對其通訊,它也會經常從電能表獲取數據,這時對電能表來說,就有可能涉及到2個通訊通道同時通訊。
由此,我們可以看出,對于電能表經常通訊的通道其實頂多就2個。另外,其實我們也知道平常通訊時每次操作(讀取、設置等)時,APDU數據并不會達到最大可處理APDU的數據量。這樣我們完全可考慮,分配一塊并不是很大的RAM緩存用動態分配的形式,供各個通道使用,先到先得,用完立即釋放。下面我們就對這種通訊緩存的分配方式進行詳細說明。
2.1 動態RAM的分配
由于電能表一般都采用普通單片機,基本不使用操作系統設計,因此我們這里需要單獨分配一塊RAM區作為動態RAM。這塊區域可以根據系統RAM資源進行適當調整,這個區域不能小于一個通道所需要的緩存(2Kbyte)。為了便于內存的分配和回收,可以建立兩張信息表:內存分配表、空閑分區表。
2.1.1 內存分配表
(1)此表可存儲M條信息;
(2)每條信息內容包括:標識、分區起始地址、長度;
標識:某作業內存名稱(1字節);用非0數據表示,0-空欄目;
分區起始地址:該作業區內存起始地址(2字節);當標識為0時,無效;
長度:該作業區內存分配長度(2字節);當標識為0時,無效;
2.1.2 空閑分區表
(1)此表可存儲N條信息;
(2)每條信息內容包括:分區起始地址、長度、標識;
標識:某空閑內存標志(1字節);0-空欄目,1-未分配;
分區起始地址:該空閑區內存起始地址(2字節);當標識為0時,無效;
長度:該空閑區內存分配長度(2字節);當標識為0時,無效;
2.1.3 分配內存
分配內存步驟如下:
(1)從“空閑分區表”中找到標識為“1”(未分配)且滿足作業需求內存大小的最小空閑區。
(2)判別該空閑區大小與作業所需內存的差值是否小于最小值MinSize;如果小于,那么將該空閑區標識改為“0”,同時在“內存分配區”中找到標識為“0”的空欄目,并將新的作業名稱、起始地址、長度登記進去;如果差值大于等于MinSize,將該部分區域分成兩部分,一部分做為作業區內存,另一部分仍舊做空閑區,這時只要更改該空閑區長度,并把新裝入的作業內存登記到“內存分配區”。
2.1.4 回收內存
回收內存步驟如下:
(1)先將“內存分配表”對應的標識改為“0”(空欄目);
(2)檢查“空閑分區表”中標識為“1”(未分配)的欄目,查找是否有相鄰的空閑區;如果有,合并處理,修改該空閑區起始地址和長度;如果沒有,在“空閑分區表”中找到標識為“0”的欄目,將該欄目標識改為“1”,同時將回收的內存起始地址和長度記錄到相應位置。
內存分配表和空閑分區表的信息條數,可以根據系統實際使用情況分配。
2.2 鏈路層分幀數據的管理
上面提到用動態RAM來維持正常情況下的通訊緩存開銷,但也會有偶爾出現這樣的情況,動態RAM已被占用完,這時又有其它通道有通訊產生(如現場紅外抄讀數據);為了保證這種情況下通訊正常,這時我們就需要啟動備用緩存方案,而備用緩存可以采用非易失性存儲器(如EEPROM、FLASH等)。由于備用緩存應用頻率較低,只要預留少部分資源就可以滿足壽命需求。
考慮到鏈路層分幀時完整的APDU數據是通過一幀幀的數據組成的,而每一幀的數據小于512字節;另外,鏈路層分幀每幀包含的APDU片段都是不可自解析的,因此在所有幀接收完成前,是不知道的APDU數據總長度的。為了不浪費資源,我們需要根據接收幀逐塊申請緩存。
由于是逐塊申請緩存,那么一個完整的APDU緩存就可能是幾個地址不連續的塊組成,這樣我們就需要有一個管理信息來表達每個通道的APDU緩存。
本方案每個通道數據管理信息包括:數據信息緩存、數據總長度。
數據信息緩存:4字節數組(接收時最小申請內存大小為512byte),用來存放內存塊標識名;此數組長度可以根據實際情況調整。每個字節最高位表示存儲類型,0表示動態RAM,1表示非易失性存儲器;低7位為標識名,最高位為1時(空間分配在非易失性存儲器),標識名不做識別,分配空間統一按2K大小處理;信息字節為0xFF,表示未使用;要求信息從第一個字節開始放置,沒用到的信息字節填0xFF,建議使用前將信息初始化為0xFF。動態RAM類型的標識名,每個標識代表一個數據塊,前面數據塊內數據都是有效數據,最后一個有效標識的有效數據數是與數據總長度有關的,即:L末=L總-L前;
L末:最后有效標識代表的數據塊的有效數據長度;
L總:數據總長度;
L前:前面所有數據塊長度之和。
數據總長度:保存數據的總長度。
2.3 鏈路層分幀數據存儲實現
698通訊上用到的鏈路層分幀有兩種情況:接收鏈路層分幀和發送鏈路層分幀。接收時數據存儲內存需要一塊一塊申請,發送時可以根據需要發送數據的長度一次性申請。下面就具體說明一下這兩種情況的處理方法(以下都是按通道單獨處理):
(1)接收:當需要保存接收分幀的APDU片段時,先識別是否有已分配空間,如果有且夠用就直接保存數據并更改存儲信息;如果沒有已分配空間或不夠用,就申請空間,再保存數據且更改存信息。
(2)發送:需要分幀發送時,存儲相對就簡單了,只要根據需要發送數據的長度,申請存儲空間,進行數據保存且更改存儲信息就可以了。
不管是接收保存還是發送保存,其中都會涉及到申請存儲空間的操作。由于存儲RAM空間有限,申請存儲空間時不一定能申請到動態RAM,這時申請到的存儲空間就會是非易失性存儲器的存儲空間。
需要注意的是,接收申請存儲空間過程中,在申請動態RAM時,由于不知道后面具體有多少數據,且接收一幀最大長度為512byte,為了減少浪費RAM的使用,每次申請都只申請512byte的內存。
另外,在每次保存數據后,都需要更改管理信息,申請空間需要增加一個數據信息隊列數據并更改存儲數據總長度,不申請空間只需要更改存儲數據總長度。
分幀數據存儲功能對外接口參數:通道號、保存數據指針、數據長度、數據偏移。
2.4 鏈路層分幀數據讀取
上面講的是存儲鏈路層分幀的APDU數據,這里就需要說一下如何讀取這些存儲的數據。
由于根據上面數據的存儲方式,這些存儲數據并不是連續的,而是分塊的,甚至是不同設備中存儲的,因此讀取就不可能像我們平時讀取其它數據一樣,簡單地根據起始地址和數
據長度得到。我們需要根據存儲信息隊列,找到待讀數據的存儲位置,然后再從找到的位置開始逐塊讀取,直到讀到需要的數據量為止。
分幀數據讀取對外接口參數:通道號、輸出數據指針、數據長度、數據偏移。
3 結語
本方案宗旨是在通訊時盡量采用動態RAM資源,使用完成后,需及時釋放資源。在RAM資源緊缺時臨時采用非易失性存儲器,保證在這種情況下的通訊成功率。另外需注意,如果在使用非易失性存儲器存儲或者讀取失敗時,也需要做好合理的應答,不能產生不可預知的錯誤。
參考文獻
[1]鄭天,曹凱,楊東華,賀云隆.智能電能表的發展與應用探討[J].科技展望,2015,(27)105.