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