,,
(國電南京自動化股份有限公司,南京210032)
隨著電力系統智能化的不斷發展,對自動化裝置的通信技術要求也越來越高,除了要求通信穩定可靠外,還要求通信接口冗余、網絡接口盡量多等,而傳統的通信模件一般是利用CPU自帶的MAC控制器外加獨立PHY的方式實現網絡通信,由于資源的限制通常一個CPU僅提供2個MAC控制器,限制了對通網絡信口的擴展,而通過采用網絡交換芯片88e6060可以很方便地設計出5網口甚至以上的通信模組,能最大化滿足電力系統通信需求。
QNX是類UNIX操作系統,由加拿大QSSL公司(QNX Software System Ltd)開發的分布式實時操作系統。它采用獨特的微內核結構,由內核實現進程通信、進程調度、中斷處理和底層網絡通信,因此內核非常小,運行速度極快。將驅動程序、應用程序、網絡協議、文件系統存放的地址空間和內核存放的地址空間分離,應用程序無法直接訪問內核空間,這種封閉的微內核結構使得任何外部模塊的故障都不會影響內核的運行,系統穩定性大大提高,同時QNX支持裁剪和擴展,能針對用戶需求定制不同的功能模塊,實現靈活的嵌入式開發。

圖1 交換芯片與CPU的連接示意圖
通信模件采用AM3352為主控CPU,它是一款基于ARM Cortex-A8內核的微處理器,主頻最高支持720 MHz,運算能力高達1600 DMIPS,具有豐富的外圍接口,能搭配DDR3,支持大容量的eMMC和NAND Flash。圖1給出了網絡交換芯片88e6060與CPU的連接示意圖,交換芯片作為10/100 BaseT網絡收發器,其端口P5設計成MII-PHY模式與CPU連接,P0、P1、P2、P3、P4用于與信息子站、DCS、錄波器等網絡通信。
QNX網絡模塊采用層次化結構設計,如圖2所示,網絡設備驅動模塊處于最底層,接受io-pkt的調度和管理,負責向io-pkt報告數據收發情況,接收和傳遞數據。中間層是底層和頂層的數據橋梁,它提供統一接口給協議模塊。頂層resource manager提供了Socket API調用的open、write、read等函數,通過read應用層接收來自io-pkt的數據,通過write應用層發送數據到io-pkt,由io-pkt調用協議模塊實現IP、TCP、UDP等網絡傳輸協議。

圖2 網絡模塊層次結構圖
網絡設備驅動程序按功能可劃分為初始化模塊、中斷處理模塊、接收數據模塊、發送數據模塊、網絡設備信息統計模塊。
3.2.1 初始化
初始化模塊對寄存器地址空間進行映射,完成對寄存器的配置,向系統注冊中斷處理函數、收包函數、發包函數,讓系統知道網絡設備存在網絡通信的能力,并最終由io-pkt調用收包函數、發包函數實現數據的收發。程序首先清空RX_HDP和TX_HDP,將CPPI前4 KB空間分配給接收隊列描述字Rx_Descriptors,后4 KB空間分配給發送隊列描述字Tx_Descriptors。Rx_Descriptors是按下面結構體定義的數組,其成員Next指向下一個Rx_Descriptor,成員Buffer指向數據體存放的RAM空間, 成員off_len存放Buffer中有效數據的長度,成員flag_len存儲Buffer狀態信息和數據包的有效長度。
typedef struct{
uint32_t next; /*Pointer to next descriptor*/
uint32_t buffer; /*Pointer to data buffer*/
uint32_t off_len; /*Buffer offset and length*/
uint32_t flag_len; /*Packet flag and length*/
} cppi_desc_t;
建立Rx_Descriptors的單向鏈接表,使RX_HDP指向鏈表的首端。建立起的鏈表如圖3所示。

圖3 接收隊列鏈表圖
隊列描述表建立好后,驅動需要調用設備綁定函數dev_attach為每個端口分配一個網絡設備dev,dev封裝了網絡接口ifnet用于網絡設備的管理,ifnet定義了啟動分組的傳輸函數if_start、初始化接口函數if_init、控制命令函數if_ioctl。QNX下的網絡驅動不直接響應中斷處理,而是由io-pkt接管中斷間接調用驅動提供的process_interrupt函數處理中斷,為此需要對結構體iopkt_inter定義中斷處理函數process_interrupt和中斷使能函數enable_interrupt,最后調用interrupt_entry_init、if_attach、ether_ifattach將上述函數注冊進io-pkt。
為了保證網絡上網絡設備MAC地址的唯一性,采取了將IP地址映射到MAC地址的方法,由初始化程序讀配置文件獲取各網絡設備的IP地址,然后將MAC[3:0]設置成IP[3:0],從而實現了網絡設備MAC地址與IP地址的同步。
電力系統通信的主要特點是正常運行流量較小,突發流量較大[1]。不同特點的報文在網絡上傳輸會產生不同流量特征,如果網絡配置不當,將會產生不合理的報文傳輸,造成網絡風暴[2],使網絡通信系統癱瘓,因此要求通信裝置有抵御網絡風暴的能力。為此可以通過配置AM335X的RX_IMAX和INT_CONTROL寄存器,對每毫秒接收中斷次數加以限制,風暴來臨時能控制系統資源消耗,風暴消失后能快速恢復通信能力。
接下來需要配置DMA引擎,開放DMA接收使能和發送使能,使能DMA中斷。最后通過SMI對交換芯片進行配置,配置PHY為全雙工速率的自動協商工作模式。將P5口設置成egress trailer模式,出該端口的數據尾端都會被88e6060打上4字節的trailer標簽。同樣CPU發往該端口的數據由驅動程序在數據尾端打上4字節trailer標簽,通知88e6060數據要發到哪個端口。trailer標簽的格式如圖4所示,DPV[5:0]標識了數據要發往哪個端口。P0、P1、P2、P3、P4設置成普通模式,進出該端口的數據是不被修改的未標記幀。

圖4 Marvell trailer標簽格式
為了實現多網口的網絡通信,需要按表1配置交換機路由表。

表1 VLANTable設置
配置完成后形成圖5所示的連接關系,P0、P1、P2、P3、P4同P5保持雙向的連接,P0、P1、P2、P3、P4接收外部請求后通過P5接口把請求數據轉發給CPU,CPU處理完畢后,由P5接口把數據轉發給請求端口。

圖5 路由圖連接關系
由于P5接口收到的包可能來自P0~P4中的任意一個端口,所以需要在收包函數Receive里告訴io-pkt收到的數據來自哪一個端口,為此在網絡設備dev里定義了數組成員common_ecom[0~5]用于存儲各網絡設備和各網絡接口的對應關系,從而通過網絡設備可以快速找到網絡接口ifnet。
3.2.2 中斷處理
當網絡數據到來時,由DMA控制器將數據放到外部Buffer,CPU更新Rx_descriptor的Buffer 域、off_len域和flag_len域,同時中斷控制器產生中斷信號,io-pkt接管中斷,間接調用驅動提供的process_interrupt函數,通過process_interrupt函數調用Receive函數接收數據。
3.2.3 接收數據
Receive函數從接收隊列描述字獲取有效數據長度,用這個長度更新接收數據鏈mbuf的m_pkthdr.len域和mlen域。由于通過RMMI收到的來自交換芯片P5接口的數據是尾部被打上4字節tailer標簽的標記幀,所以數據送到io-pkt前需要去掉tailer標簽,為此只需要對mbuf的m_pkthdr.len域和mlen域做減4操作,同時要告知io-pkt數據是來自哪一個網絡接口。標記幀的tailer標簽DPV[5:0]域指明了數據是來自哪一個端口,通過DPV[5:0]可以找到網絡設備dev對應的common_ecom[]數組成員,從而確定網絡接口ifnet,將ifnet作為參數傳入ip_input,這樣io-pkt就知道數據來自哪一個網絡接口以及應答數據要送往哪一個網絡接口。
3.2.4 發送數據
由io-pkt啟動分組傳輸函數if_start將應答數據發往對應的網絡接口。由于P5接口設置成了egress trailer模式,需要由驅動在應答數據末尾加上4字節的tailer標簽,為此,通過m_get函數從系統空間分配數據區m3用于存放tailer標簽。通過if_start函數的ifnet參數可以找到對應的網絡設備,網絡設備的device_index成員存儲了設備ID即數據要發往的端口號,把1左移device_index位后寫到m3的數據成員m_data[1],用于通知88e6060數據要發往哪個端口,然后將m3鏈接到m2的尾端形成如圖6所示的鏈表。因為增加了4字節的tailer標簽,m1成員m_pkthdr.len需要加4。最后更新發送隊列描述字,向TX_HDP寫入發送隊列描述字首地址啟動TX DMA發送數據。
驅動程序編寫好后需要配置腳本文件,通過腳本啟動網絡設備。腳本配置如下:
io-pkt-v4-hc-dam335x deviceindex=0
ifconfig dm0 172.20.6.220 up
ifconfig dm1 172.30.6.220 up
……
利用交換芯片88e6060可以很方便、容易地擴展網絡接口,能滿足電力系統自動化裝置對多通信口的需求。對利用88e6060設計出來的通信模件進行了實測,
其網絡通信可靠、穩定,能抵御網絡風暴,將其應用于電力系統能大大提高電力系統的穩定性。

圖6 添加tailer標簽示意圖