孫 宏,柯 捷
(桂林航天工業學院,廣西 桂林 541004)
智能家居網關用以實現家庭網絡與Internet互聯,還可作為服務器,為用戶提供家居設備的遠程訪問服務。智能家居終端連網方式包括有線(以太網)和無線(WiFi)兩種[1]。用戶也可利用網關享受文件信息服務和安防功能。
自從Backf i re版本出現后,OpenWRT的功能趨于穩定,且新版本持續更新,亦可在開發者論壇獲取豐富的信息。本文旨在應用簡單的方式實現網關的功能多樣化。
本設計是一個軟硬件結合的產品,開發板通過移植OpenWRT系統對其進行編譯和配置,之后使用PPPOE方式實現與Internet交互的功能。用戶可使用手機或電腦通過網關連接到互聯網,獲取信息。還可使用瀏覽器控制家用電器和實現離線下載,進行遠程監控。網關是整個智能家居系統的中樞,具有數據通信、業務處理、信息存儲等功能,可為用戶提供一個友好的操作界面。系統總體設計如圖1所示。
本文使用Linux系統進行開發。硬件使用聯發科技的MT7688主板搭配MT7628開發底板,其中底板集成了GPIO,TTL,RS 232串口,1個WAN接口及2個LAN接口,紅外發射與紅外接收器,4個USB接口等。
本文移植的系統是OpenWRT。OpenWRT是一個高度可擴展嵌入式設備的GNU/Linux發行版本。由于它擁有眾多網絡組件和良好的擴展性,常常被應用于工業控制、機器人、智能家居等領域。OpenWRT項目的建立從零開始,可被視為一個全功能的、易于修改的路由操作系統[2]。
OpenWRT的開發需要宿主機,為便于開發,本設計使用Windows系統的主機作為宿主機,使用帶有圖形界面的串口工具和文件傳輸工具。并安裝一個Ubuntu系統的虛擬機,與OpenWRT同為Linux系統,便于編譯固件。
首先進行編譯環境的搭建,在宿主機的Linux環境下預裝一些軟件[3]。
(1)源碼下載之后,進入源碼的根目錄。運行make menuconf i g命令進入編譯管理器;
(2)選擇適配的CPU型號和子型號;
(3)添加Luci支持:Luci作為Lua和Uci(統一配置接口)的結合體,用于實現網關的網頁配置界面;
(4)添加Luci中文支持:在之后的Web界面上將英文自動替換為已設置好的中文;
(5)添加完上述幾項基礎固件之后運行make V=s命令進行固件的編譯,再將生成的固件通過燒錄器寫進開發板。
經過燒錄之后的開發板已攜帶了Uhttpd服務器,以實現對Web的支持。B/S工作原理如圖2所示。

圖2 B/S工作原理
用戶通過Web瀏覽器以get或post方式向Uhttpd服務器提交請求,并將提交的數據發送給Uhttpd服務器,服務器為CGI應用程序Fork的一個子進程,并使用Setenv將固定格式的數據(如PATH_INFO)保存到環境變量[4]。另外的非固定格式數據由父進程通過w_pipe傳遞給Luci的Stdin。返回數據則由Luci輸出到Stdout上[5],父進程通過r_pipe讀取。
Web交互過程如圖3所示。

圖3 Web交互過程
(1)開始時,服務器已將初始頁面定位到了www/index.html,此頁面通過href="cgi-bin/luci"自動跳轉[6]。
(2)第一次執行Luci,會使用Entry中的Alise方法,定位到Admin(索引到一個根節點,并執行Target方法),返回一個登錄界面。
(3)此時服務器已經獲取到了登錄信息,并且使用Session保存了用戶信息。此時的索引不再是索引根節點,而是索引子節點,返回Admin/Status.html,此時進入網關的Web主頁面。
(4)此后的每個主頁面的按鈕都會帶一個由服務器生成的Stok值,放在URL中,并且之后的每一個請求都會帶有Session,與Stok一起對用戶進行聯合驗證。
MVC,即 Model,View,Controller。Luci從功能的實現上來講屬于MVC模式,使用WinSCP工具執行 cd /usr/lib/lua/luci/ 可發現此路徑下有Model,View,Controller三個目錄。
Controller主要存放Lua文件,用于接收用戶的請求,調用相關函數模型來響應用戶的請求,在此目錄下,每一個Lua程序都以function index()作為函數的起點,且通過調用entry()函數創建子節點,選擇View文件進行顯示。其中entry有多種不同的調用方式[6]:
call()方法可直接調用指定的函數,如通過點擊按鈕實現某種功能,可直接執行簡短的腳本命令。
template()方法可直接調用位于View文件夾中的html。
cbi()方法主要用來配置頁面,往往用于調用Model文件夾中的子模塊Lua文件.
alias()方法可實現網頁節點之間的鏈接。如用戶成功登錄路由器后,進入的網頁節點未定義內容,可通過此方法自動鏈接到有內容的Web頁面中[5]。
Model的作用是封裝應用程序狀態,響應來自Controller的請求,對來自用戶的請求做業務邏輯層面的處理,并通知視圖層進行更新。
View顯示當前的系統狀態,主要由html文件構成。
本節主要以控制照明工具為例,用詳細的代碼講解如何實現控制GPIO串口。
MT7628 datasheet文件中定義了GPIO的復用關系。并在源碼目錄下的/target/linux/ramips/dts/mt7628an.dtsi中可查看GPIO的分組。
在 /build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7620n/linux-3.10.28/arch/mips/ralink/mt7620.c中可看到引腳復用定義。
在/target/linux/ramips/dts/WRTNODE.dts里可注冊通過GPIO接口控制的設備。使用GPIO接口首先要使能GPIO并釋放GPIO引腳復用功能:
GPIO2:gpio@660 {
//gpio2 和gpio3兩組GPIO引腳是處于使能GPIO的狀態
status = "okay";
};
GPIO3:GPIO@688 {
status = "okay";
};
結合mt7628an.dtsi文件將需要釋放的GPIO引腳復用釋放,如需要釋放GPIO#18和GPIO#19,需將“PWM1”和“PWM0”寫入到ralink,group中。重新編譯將固件刷入開發板。
pinctrl { //引腳復用釋放核心代碼
state_default: pinctrl0 {
default {
ralink,group = "ephy","wled","pa","i2c","wdt","uartf","PWM1","PWM0";
ralink,function = "gpio";
};
};
};
通過SecureCRT連接開發板,執行cd/sys/class/gpio目錄。可看到export和unexport兩個文件。
export用于通知系統需要導出控制的GPIO引腳編號,此時的權限從用戶態過渡到內核態運行以下命令:
echo 18 > export
echo 19 > export
再次查看當前目錄會發現多出GPIO18和GPIO19兩個目錄。
更改電流輸出方向,將兩個針腳都設置為電流輸出:
echo out > GPIO18/direction
echo out > GPIO19/ direction
為電流大小設置指定值,18號針腳設置為高電平,19號設置為低電平:
echo out > 1 GPIO18/value
echo out > 0 GPIO19/value
此時若上述命令都能正常運行,使用一個發光二極管連接這兩個針腳,會有電流通過該二極管。
在此使用Luci實現,首先打開Lua文件:
vi /usr/lib/lua/luci/controller/admin/
system.lua
在function index()下添加GPIO控制選項:
entry({"admin","system","test"},cbi("admin_system/test"),_("GPIO Conf i gration"),3).index = true其中:第一個{ }內的內容是定義菜單欄的顯示;第二個參數是target方式,此處采用cbi方式定位到admin_system/test.lua文件;第三個參數是菜單欄顯示名稱。3代表同級菜單下,此選項的顯示位置,從小到大。
再次進入Web頁面可看到系統菜單欄中有了GPIO Conf i guration選項。
編寫test.lua 實現按鈕控制腳本。
在/usr/lib/lua/luci/model/cbi/admin_system 路徑下創建一個test.lua文件。部分業務處理代碼如圖4所示。
在etc/conf i g/network文件的最后添加conf i g gpioset,保存后重啟開發板查看Web。點擊GPIO Conf i guration后會跳轉至新頁面,通過點擊網頁的“開燈”“關燈”兩個按鈕,并使用繼電器連接開發板和電燈的控制電路,可實現對220 V家庭電路的控制。

圖4 部分業務處理代碼
通過上述方式,實現對更多家用電器的控制。使用同樣的前后端交互模式實現紅外收發以控制空調等電器。安裝各類傳感器,編寫自動控制觸發條件實現更深層次的智能化。
在網關上添加文件信息服務功能,可實現文件共享。關鍵之處在于要先建立一個Samba文件服務器。它是一個開源實現SMB(Server Message Block,SMB)協議的軟件,客戶機可通過SMB協議訪問服務器上的共享文件系統。將Samba36-Server軟件編譯成ipk包安裝至開發板后,對配置文件Smb.conf作出修改才可讓服務器正常運行[7]。配置文件主要包含四個方面,分別是全局配置段、家目錄段、共享段、自定義段。對不同的段進行修改,可修改和添加用戶、密碼、共享文件夾目錄和訪問權限。
使用Transmission實現網關的脫機下載服務。此軟件具有多平臺、低功耗、支持Web界面、遠程控制等特點[5]。
因網關內存較小,不適合大容量文件的保存。因此需要設置USB掛載,使大容量U盤能夠掛載到網關平臺上,實現邏輯上的內存擴展。此過程需要安裝USB驅動和文件系統格式。
考慮到NTFS格式的文件系統并非Linux的原生態文件系統,因此將掛載的U盤格式化為ext4格式,有助于提高讀寫速度。
Transmission-Daemon是一個Transmission的后臺守護程序,本身不具備操作指令,通過Web來進行控制,因此需要再添加Transmission-Eeb安裝包。安裝成功之后首先需要運行一次以便生成相應的配置文件,在/var/lib/transmissiondaemon/info/setting.json 下設置配置下載名單,Password設置為明文,啟動Daemon后會自動檢查密碼設置,若密碼配置發生變動,Deamon會自動計算修改后的密碼hash值,并替換配置密碼中的明文密碼,這樣會使文件下載系統更加安全。此外還可進行上傳/下載速度限制,DHT配置,端口設置等。可在瀏覽器中輸入IP+端口號登錄Web界面,設置文件下載路徑和粘貼BT進行下載。
MT7628開發板沒有專門的攝像頭接口,因此采用USB的UVC攝像頭,也稱作免驅攝像頭,在主流的操作系統中都提供有UVC設備驅動程序,而OpenWRT又是基于Linux內核的系統,免去了驅動配置環節,便于開發。在Linux下,USB攝像頭通過UVC驅動捕捉圖像[8]。
需在OpenWRT中添加驅動支持,在編譯模式下,選擇Device Drivers--->Kernel modules--->Video Supinterface--->[*]kmod-video-uvc,編譯之后將ipk寫入開發板。當攝像頭插入時會在/dev路徑下生成一個Video 0文件。
使用V4L2接口獲取并處理攝像頭采集的數據幀,V4L2(Video 4 Linux 2)為Linux訪問圖像采集設備提供了統一的接口,完成對硬件設備的驅動和圖像信息的獲取[9]。該接口驅動的攝像頭對用戶空間調用I/O通道管理函數和mmap映射內存空間。V4L2和圖像采集設備以及用戶程序組合構成的三級結構如圖5所示。

圖5 視頻采集結構
攝像頭通過兩個內存空間緩存圖像隊列交替覆蓋緩存進行采集,過程與上圖的層次結構相對應,如圖6所示。

圖6 圖像緩存過程
MJPEG-Streamer是一個開源的視頻服務器,源碼包括三部分:V4L2接口、Socket編程和多線程編程。
(1)V4L2接口定義了攝像頭采集的圖像信息,首先封裝一個結構體描述攝像頭的信息,定義圖像的像素大小、圖片格式等。其次I/O通道管理函數將此結構體寫入驅動中,按照約定初始化攝像頭,并通過mmap完成內存的映射。使用ioct完成圖片的過濾,將獲取的數據寫入文件構成圖片,連續傳輸的圖片構成視頻。
(2)Socket編程中使用的是TCP套接字,當有連接請求時,創建一個線程單獨和此請求通信。將TCP/IP數據報的繁瑣操作抽象成一個簡單接口,提供給用戶層,以實現在網絡中通信。
(3)使用多線程的目的是為了同時響應多個客戶端的請求,每個請求建立一個連接,每個連接就是一個線程[10]。
MJPEG-Streamer的工作流程如圖7所示。箭頭方向代表圖像數據流向。

圖7 MJPEG-Streamer工作流程
同樣需要在Linux下編譯生成新的固件,重啟設備后通過瀏覽器查看視頻畫面。
本文基于OpenWRT系統實現了多功能智能家居網關,描述了前后端交互的工作原理、工作框架、交互流程。以實例的方式簡述了設備控制方法,并對文件服務器、視頻服務器作了簡明分析,實現了在網關平臺上集成多功能服務,為廣大開發者和電子愛好者提供了智能家居產品的開發思路。