物聯(lián)網(wǎng)的出現(xiàn)及迅猛發(fā)展為世界經(jīng)濟(jì)帶來了新的增長點(diǎn),將那些傳統(tǒng)的儀器設(shè)備采用統(tǒng)一的方式接入LAN/Internet 勢在必行。而眾多的設(shè)備采用各種串口方式進(jìn)行通信,當(dāng)前出現(xiàn)了稱為串口服務(wù)器的工具來將這些設(shè)備接入LAN/Internet,一般都采用微控制器實(shí)現(xiàn),其功能比較簡單。同時由于互聯(lián)網(wǎng)在安全性方面存在眾多的問題,有許多儀器設(shè)備的數(shù)據(jù)關(guān)系到企業(yè)乃至國家的信息安全,因此設(shè)計(jì)與開發(fā)具備良好安全性的串口服務(wù)器極為重要,本文采用ARM9 微處理器和Linux 操作系統(tǒng),設(shè)計(jì)開發(fā)了具有多用戶訪問,使用SSL 協(xié)議的安全型串口服務(wù)器。
1 硬件電路組成
所采用的主控微處理器為AT91SAM9261[2],它擴(kuò)展了 DSP 指令集和Janelle java 加速器,主時鐘頻率達(dá)到190MHz,為大量復(fù)雜的運(yùn)算提供了強(qiáng)大了支持。
同時,其眾多的外部接口包括了從UART 到USB 的廣泛支持。其自身只帶有四個UART 接口,可以直接用來做為四串口服務(wù)器使用。另外,由軟件控制的功率管理器(PMC)可以有選擇地關(guān)閉和開啟處理器核心和各種外設(shè)或降低其工作頻率,能使得系統(tǒng)的功耗保持在最小。
使用 DM9000A 作為以太網(wǎng)控制芯片,其集成10/100M 物理層接口;內(nèi)部帶有16K 字節(jié)SRAM 用作接收發(fā)送的FIFO 緩存;支持8/16bit 兩種主機(jī)工作模式;支持TCP/IP 加速減輕CPU 負(fù)擔(dān),提高整機(jī)效能。
另外做為系統(tǒng)必需,還包括了電源模塊、32M 的SDRAM、2G 的NAND Flash 以及4M 的Data Flash(用于存放U-boot 和Linux 內(nèi)核)。系統(tǒng)的硬件框圖如圖1所示。
圖 1 硬件組成
2 軟件平臺構(gòu)建
系統(tǒng)的軟件平臺基于嵌入式 Linux 操作系統(tǒng),主要的工作包括引導(dǎo)程序的移植,嵌入式Linux 內(nèi)核的編譯,及根文件系統(tǒng)的生成。在做這些工作之前,需要建立一個完整的交叉編譯環(huán)境,包含gcc、glibc 等等,用來在PC 機(jī)上產(chǎn)生ARM 處理器能執(zhí)行的二進(jìn)制代碼。
引導(dǎo)程序采用廣泛使用的U-boot,其功能強(qiáng)大,包含了對TFTP、NFS 以及NAND的支持。同時ATMEL發(fā)布了專門針對其產(chǎn)生的處理器的U-boot 修改版本,對快速的產(chǎn)品開發(fā)起到了很大的幫助。從其專門網(wǎng)站下載U-boot 源代碼,解壓生成uboot 源代碼目錄,在其中運(yùn)行“make at91sam9261ek_config; make”即可生成uboot.bin 的二進(jìn)制文件,通過使用ATMEL 的ISP工具將其寫入到DATA FLASH 的8000 位置,復(fù)位AT91SAM9261 之后即能看到“U-boot>”字樣的提示符,表示U-boot 運(yùn)行成功。
第二步為編譯Linux 的內(nèi)核,同樣有針對AT91SAM926X 型號處理器的專門修改版本,考慮系統(tǒng)的穩(wěn)定性,采用Linux-2.6.24 的內(nèi)核版本。下載之后解壓生成Linux-2.6.24 的目錄,運(yùn)行“make ARCH=armCROSS_COMPILE=arm-linux-menuconfig”命令,表示使用Linux 的處理器架構(gòu)為ARM,交叉編譯器的前端為“arm-linux-”,同時使用菜單的方式對Linux 進(jìn)行配置,只需將其中的芯片選為AT91SAM9261 即可。此后即可用make 命令編譯生成二進(jìn)制映像文件,為了讓U-boot 能向內(nèi)核傳遞一些保正正確啟動的參數(shù),二進(jìn)制映像文件還需要使用U-boot 的mkImage 工具進(jìn)行包裹之后才能被U-boot 使用。
下一步,還需要制作根文件系統(tǒng)[3],即以”/”為起點(diǎn)的文件系統(tǒng),在PC 機(jī)上制作rootfs 目錄來模擬,在其下生成etc、bin、lib 等Linux 所需的目錄結(jié)構(gòu),使用busybox 工具在bin 目錄中生成基本命令工具集,同時將交叉編譯器所使用的glibc 的庫文件拷貝到lib目錄下,再經(jīng)過對etc 目錄的配置之后,完整的嵌入式Linux 系統(tǒng)即構(gòu)建完成。
最后,為了滿足應(yīng)用軟件的需要,還需要編譯出openSSL、XML 等支持庫,將它們拷貝到根文件系統(tǒng)的/lib 或/usr/lib 目錄下,將來應(yīng)用軟件運(yùn)行時就會自動連接到這些庫調(diào)用所需要的功能。
3 軟件實(shí)現(xiàn)
3.1 總體架構(gòu)
串口服務(wù)器的應(yīng)用軟件采用C 語言進(jìn)行線程化及模塊化設(shè)計(jì),總體架構(gòu)如圖2 所示。
圖 2 軟件框架
在設(shè)計(jì)中借用了Unix/Linux 的設(shè)計(jì)思想,Unix/Linux 在系統(tǒng)層將所有的設(shè)備及接口都視為文件,采用統(tǒng)一的接口規(guī)范,使得應(yīng)用程序只需使用read、write等操作即可與設(shè)備進(jìn)行交互,極大地方便了程序的開發(fā)及維護(hù),同時具有極高的可擴(kuò)展性。在本設(shè)計(jì)中,將串行接口以及TCP 通信采用統(tǒng)一的接口框架,可以帶來擴(kuò)展支持更多接口的好處,比如MODBUS 總線協(xié)議,CAN 總線等等,另外SSL 也就是在這個基礎(chǔ)上的擴(kuò)展支持。定義結(jié)構(gòu)體如下:
struct Interface{
int type;
int fd; //file descriptor
int init(int num);
int (*read)(int clientfd, BufPtr buf, int size);
int (*write)(int clientfd, BufPtr buf, int size);
int (*accept)(int sockfd);
int (*disconn)(int fd);
…
}
結(jié)構(gòu)體中使用了Buf 緩沖塊結(jié)構(gòu)體,用來存儲接收或者發(fā)送的數(shù)據(jù)。同時定義了接口的回調(diào)函數(shù)比如讀寫,連接等操作,這些函數(shù)根據(jù)不同的接口就有不同的實(shí)現(xiàn)。
接口模塊與處理模塊之間采用隊(duì)列的方式進(jìn)行通信,為了充分利用Linux 系統(tǒng)的特性,采用信號量的方式來模擬出生產(chǎn)者-消費(fèi)者模型,當(dāng)隊(duì)列為空時使得接收線程進(jìn)入睡眠狀態(tài),降低系統(tǒng)資源消耗。數(shù)據(jù)包處理線程負(fù)責(zé)根據(jù)轉(zhuǎn)發(fā)策略來處理來自串口或者以太網(wǎng)的數(shù)據(jù)、用戶的登錄以及設(shè)備配置操作等等。
3.2 多用戶支持及工作模式
為了使得多個用戶同時在不同地點(diǎn)都能訪問到服務(wù)器,設(shè)計(jì)了用戶管理模塊,將用戶分為兩類:一類為管理員用戶,除了對串口的通信操作之外,還可以對串口服務(wù)器進(jìn)行配置操作(以太網(wǎng)參數(shù),串口參數(shù)等);另一類為普通用戶,它只能與串口進(jìn)行數(shù)據(jù)的通信。進(jìn)行這樣的劃分之后,可以避免掉許多普通訪問者對設(shè)備進(jìn)行篡改,造成不必要的故障。
每個創(chuàng)建的用戶都被保存在user.xml 文件當(dāng)中,采用的格式如下,其中的password 節(jié)點(diǎn)不以明文的方式來存取,而是使用MD5 算法對“用戶名+密碼”字符串生成16 字節(jié)的摘要字串進(jìn)行保存,這樣可以方式被非法獲取到密碼。
test
16 字節(jié)MD5
normal
用戶對串口的操作應(yīng)是互不影響的。用戶A 對串口1 進(jìn)行操作的時候,意味得用戶B 此時不能對串口1 進(jìn)行操作,但可能可以對串口2 進(jìn)行操作,如果串口2 處在空閑的狀態(tài)下。因此,對串口操作定義兩種工作模式:
(1)響應(yīng)模式,在此模式下,定義用戶對串口(也即串口所接設(shè)備)發(fā)送請求數(shù)據(jù)和串口對用戶的請求回應(yīng)數(shù)據(jù)這一過程稱為一個響應(yīng)過程,響應(yīng)過程過程是互斥的。響應(yīng)模式可以使得多個用戶能更充分地利用串口, 當(dāng)多個用戶進(jìn)行相同的數(shù)據(jù)請求時,可以合成為一個請求,從而較大地提高訪問效率。
(2)獨(dú)占模式,在此模式下,串口為某用戶獨(dú)自占有,一直到其明確地釋放了該串口。這一模式的好處是如果需要長時間與串口進(jìn)行通信,可以避免其它用戶的干擾。
3.3 接口模塊
接口模塊是整個系統(tǒng)中最重要的部分,TCP 數(shù)據(jù)的接收及串口數(shù)據(jù)的接收都依賴于它的實(shí)現(xiàn),前文提到了TCP 以及串口采用統(tǒng)一的接口進(jìn)行抽象,串口服務(wù)器的TCP 連接同時采用了C/S 模式和S/C,也即串口服務(wù)器同時以服務(wù)器的形式供上位機(jī)連接,還能以客戶端的方式主動地去連接上位機(jī),這在服務(wù)器地IP 地址為通過DHCP 自動獲取時非常有用,因?yàn)榇藭r上位機(jī)無從知曉串口服務(wù)器的IP 地址而無法連接。
由于要同時服務(wù)于多個用戶,同時又要隨時地接收來自串口的數(shù)據(jù),也就是說串口服務(wù)器應(yīng)該具有良好的并發(fā)性,以不至于在多個用戶同時訪問時產(chǎn)生瓶頸。采用Select 模型來實(shí)現(xiàn)I/O 的操作,該模型首先使用FD_SET 將需要偵聽的客戶fd,TCP 偵聽fd 以及串口fd 加入到偵聽集當(dāng)中,然后使用函數(shù)select()偵聽,當(dāng)任何一個fd 上有數(shù)據(jù)到來時馬上返回,將數(shù)據(jù)接收完成后放入接收數(shù)據(jù)隊(duì)列后返回繼續(xù)進(jìn)行偵聽,流程如圖3 所示。
圖 3 select 模型流程
3.4 SSL 的擴(kuò)展
針對 ARM9 的運(yùn)算能力,只要求上位機(jī)對串口服務(wù)器的數(shù)字證書進(jìn)行驗(yàn)證,服務(wù)器證書名為server.pem,由CA 進(jìn)行簽證。CA 可以是正規(guī)證書簽發(fā)機(jī)構(gòu),也可以是自已建立的非正式簽發(fā)機(jī)構(gòu)。根據(jù)非對稱密碼學(xué),CA 使用其私鑰簽名的數(shù)據(jù)證書只有其公鑰才能解密,將其公鑰及相關(guān)信息做為根證書,只要上位機(jī)保證從安全的途徑得到根證書,因?yàn)橹恍枰淮潍@取,從而不會出現(xiàn)中間人攻擊的情況。
因?yàn)镾SL 通信是建立在TCP 協(xié)議基礎(chǔ)之上,可以在原socket 程序代碼之上實(shí)現(xiàn)SSL 程序,openSSL 很好地對SSL 進(jìn)行了封裝,且在1.0 之后的版本中提供了對ARM處理器的支持,使用openSSL 對原有TCP通信代碼進(jìn)行修改即可實(shí)現(xiàn)SSL 安全通信。修改分別針對于struct Interface 中的accept、write、read。對于SSL,它們分別指向SSLaccept、SSLdisconn、SSLwrite、SSLread,在SSLaccept 函數(shù)中,在原有TCP 連接建立之后再進(jìn)行SSL 協(xié)議的握手過程,在此過程中進(jìn)行服務(wù)器數(shù)字證書的驗(yàn)證并交換臨時密鑰,代碼如下:
clientFd=accept(listenerFd,(struct
sockaddr *)(&tmpAddr),(socklen_t *)&len);
bio=BIO_new_socket(clientFd,BIO_NOCLOSE);
ssl=SSL_new(ctx);
SSL_set_bio(cli->ssl,cli->sbio,cli->sbio);
//SSL 握手
if(( ret=SSL_accept(cli->ssl)) <= 0 ) {
sslErr(ssl);
}
在SSLwrite 及SSLread 函數(shù)中可以簡單地將原socket 中的read 及write 函數(shù)替換為openSSL 庫中的SSL_write 和SSL_read 函數(shù)。不過對于SSLread,由于使用了select 并發(fā)模型,只要fd 上有數(shù)據(jù)出現(xiàn)select函數(shù)即馬上返回,而此時可能openSSL 正在進(jìn)行數(shù)據(jù)解密操作,SSL_write 函數(shù)則返回錯誤的信息。對此必須對返回的錯誤進(jìn)行處理,一直等到解密完成才能讀取返回:
do {
ret=SSL_read(ssl,buf, size);
switch(SSL_get_error(ssl,ret)){
case SSL_ERROR_NONE:
goto read_done; //真正讀完
case SSL_ERROR_ZERO_RETURN:
ret=SSL_shutdown(ssl);
goto end;
case SSL_ERROR_WANT_READ:
read_blocked=1;
break;
default:
DBG("SSL read problem\n");
}
} while (SSL_pending(ssl)&& !read_blocked);
3.5 SSL 的擴(kuò)展
在ARM這種相對于PC 處理器運(yùn)算能力弱很多的處理器上,必須選擇安全性高且速度有快的加密算法,RC4 是最理想的選擇,下表為采用SSL_RC4_MD5 加密方式的傳輸與普通TCP 傳輸?shù)囊唤M速率對比:
表 1 TCP 和SSL 傳輸速率測試(處理器:190MHz,以太網(wǎng):100M)
從表中可以看到隨著傳輸數(shù)據(jù)量的增大,傳輸率逐步趨于穩(wěn)定,可以推測出為最大的數(shù)據(jù)傳輸率,TCP約為5.2MB/S,SSL 約為2.34MB/S。在SSL 下,若以半雙工的方式傳輸,而根據(jù)串口固定的波特率,可以以“波特率*N<最大數(shù)據(jù)傳輸率”的公式求得在此波特率下可支持的串口數(shù),在測試中,以四個串口為例,當(dāng)四個串口波特率都設(shè)為460800bps 時,仍能正常通信。
4 總結(jié)
通過對設(shè)計(jì)目標(biāo)的需求分析,結(jié)合ARM9 及Linux軟硬件平臺豐富資源的優(yōu)勢整合,設(shè)計(jì)的串口服務(wù)器實(shí)現(xiàn)了多用戶多點(diǎn)訪問以及安全通信。為串口設(shè)備接入互聯(lián)網(wǎng)提供了更好的選擇。
-
嵌入式
+關(guān)注
關(guān)注
5083文章
19129瀏覽量
305400 -
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2909文章
44661瀏覽量
373515 -
Linux
+關(guān)注
關(guān)注
87文章
11306瀏覽量
209570 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9176瀏覽量
85460
發(fā)布評論請先 登錄
相關(guān)推薦
評論