王龍奇,樊明輝,陳麗紅
(福州大學(xué)物理與信息工程學(xué)院,福建福州350000)
基于Linux設(shè)備模型的單總線接口的設(shè)計
王龍奇,樊明輝*,陳麗紅
(福州大學(xué)物理與信息工程學(xué)院,福建福州350000)
單總線是一些傳感器和低速器件與主機(jī)通信常用一種總線協(xié)議,如智能溫度傳感器DS18B20,A/D轉(zhuǎn)換芯片等。隨著物聯(lián)網(wǎng)的發(fā)展,這些傳感器的應(yīng)用將越來越廣泛,而這些接口沒有與內(nèi)核緊密聯(lián)系,內(nèi)核無法進(jìn)行統(tǒng)一管理,穩(wěn)定性和可靠性無法得到保證。在符合Linux內(nèi)核設(shè)備模型[2]的前提下,實(shí)現(xiàn)一個穩(wěn)定的單總線接口,將整個控制器分為頂層設(shè)備接口、核心層、底層硬件接口由上到下3個部分;同時對驅(qū)動和設(shè)備分離、頂層設(shè)備接口和具體硬件操作分離。
單總線;Linux;嵌入式系統(tǒng);分層;分離
Linux系統(tǒng)以其開放、穩(wěn)定、功能強(qiáng)大著稱,在其內(nèi)核源碼中提供眾多接口和協(xié)議的實(shí)現(xiàn),其中包括PCI、USB、I2C、SPI等等,各種總線的實(shí)現(xiàn)都是基于內(nèi)核的設(shè)備模型,具有穩(wěn)定、功能豐富、擴(kuò)展性強(qiáng)的優(yōu)點(diǎn)。而單總線,由于其應(yīng)用的特殊性——主要應(yīng)用于EEPROM存儲器控制、數(shù)字電位器控制、傳感器控制、時鐘控制等方面,Linux內(nèi)核尚未提供總線的支持。而這些應(yīng)用正漸漸成為許多完整系統(tǒng)不可或缺的一部分、如智能系統(tǒng)中傳感器的控制,同步系統(tǒng)中同步時鐘的獲取等等,課題正是基于這種現(xiàn)狀,遵循Linux內(nèi)核的分層、分離思想,實(shí)現(xiàn)了一個符合Linux內(nèi)核設(shè)備模型的單總線控制器。
單總線協(xié)議[3],即1-wire protocol,是 Dallas公司提出一種串行總線協(xié)議。與其他的串行總線如I2C、SPI類似,1-wire的命令、數(shù)據(jù)傳輸也是通過串行方式,但是1-wire具備了最少資源占用的優(yōu)勢,僅使用一根信號線,同時用于傳輸時鐘、數(shù)據(jù)、命令,并且是雙向傳輸。除此之外,它還具有成本低廉、可擴(kuò)展性強(qiáng)、維護(hù)方便等特點(diǎn)。
單總線協(xié)議只適用于單主機(jī)場合,易于實(shí)現(xiàn)一主多從的網(wǎng)絡(luò)連接,如常用的多點(diǎn)溫度采集系統(tǒng)[4]。節(jié)點(diǎn)之間的識別通過一串64bit專用ID進(jìn)行識別[5-6]。單總線協(xié)議還定義了單主單從的簡單通信方式,主機(jī)不用發(fā)送識別碼即可與從機(jī)進(jìn)行通信。
單總線協(xié)議包含了3種最基本時序,即復(fù)位時序、寫時序和讀時序[7]。在3種基本時序的基礎(chǔ)上,總線協(xié)議定義了尋址方式、命令傳輸方式、數(shù)據(jù)傳輸方式,這就是課題要實(shí)現(xiàn)的物理層部分。
在linux內(nèi)核中,幾乎所有的設(shè)計都是基于模塊化、分層、分離[8]等思想,在這些思想的指導(dǎo)下,以切合實(shí)際應(yīng)用為出發(fā)點(diǎn),課題實(shí)現(xiàn)了一種基于Linux設(shè)備模型的分層單總線控制器,它的整體原理框圖如圖1所示。
圖1 單線總線協(xié)議實(shí)現(xiàn)的原理框圖
在物理層中,本層向上層(核心層)屏蔽了下層通信線路的機(jī)械、電氣特性等。機(jī)械特性主要是指總線連接的接口、外設(shè)的拓?fù)浣Y(jié)構(gòu)、引腳數(shù)量及其排列等。而電氣特性規(guī)定了系統(tǒng)的供電范圍、比特與電平的對應(yīng)關(guān)系、比特流的組織方式等。該層最重要的功能是提供了硬件的操作接口,上層通過這些API實(shí)現(xiàn)了命令的傳送和數(shù)據(jù)的收發(fā),所以,對上層而言,下層是完全透明的,不需要直接參與底層物理特性的控制。
核心層是本系統(tǒng)最重要的一層,起到了承上啟下的作用,包括了設(shè)備、設(shè)備驅(qū)動、通用API接口、適配器4個部分。
在完整的內(nèi)核驅(qū)動中,Linux正是通過設(shè)備模型實(shí)現(xiàn)設(shè)備的統(tǒng)一管理——也就是在kobject、kset等底層內(nèi)核對象的基礎(chǔ)上,將設(shè)備device、設(shè)備驅(qū)動devive_driver和總線bus_type[9]以合適的方式組織在一起,它們的關(guān)系如圖2所示。
總線是連接設(shè)備和設(shè)備驅(qū)動的媒介,當(dāng)有新的設(shè)備接入時,系統(tǒng)自動匹配總線上掛載的所有驅(qū)動,一旦匹配成功就將設(shè)備和設(shè)備驅(qū)動進(jìn)行綁定。這個過程比較繁瑣,首先是總線注冊后會在/sys文件系統(tǒng)下生成總線目錄,相應(yīng)地也會在該目錄下創(chuàng)建devices、drivers兩個目錄,以及關(guān)于自動匹配和熱插拔的一些屬性文件。當(dāng)一個設(shè)備驅(qū)動注冊并匹配成功后,會在總線目錄下的驅(qū)動目錄生成關(guān)于這個設(shè)備驅(qū)動的屬性文件和鏈接文件。設(shè)備注冊會復(fù)雜一些,內(nèi)核會先判斷該設(shè)備是否指明父設(shè)備,是否指明所屬類,也就是說至少存在4種組合,這里,設(shè)備都沒有指定父設(shè)備,但指定了所屬類,適配器所屬的類是oneWire_adapter_class,單總線設(shè)備所屬的類是oneWire_dev_class,那么設(shè)備注冊之后,屬性文件并不存在于總線目錄,而是存在于類目錄下,同時會創(chuàng)建總線到設(shè)備、設(shè)備到總線、設(shè)備到類等鏈接??偩€目錄如下所示。
圖2 Linux的設(shè)備模型
設(shè)備目錄如下所示:.
除了探測功能,總線和設(shè)備驅(qū)動還要承擔(dān)設(shè)備刪除、熱插拔事件、電源控制等處理。設(shè)備刪除完成的是與探測相反的工作,判斷設(shè)備是否處于忙狀態(tài),如果忙則拒絕刪除,只有當(dāng)設(shè)備處于空閑狀態(tài)才會完成刪除操作,包括阻止設(shè)備的新請求、等待未執(zhí)行請求、與綁定的驅(qū)動脫離、刪除sys文件系統(tǒng)下的目錄和節(jié)點(diǎn)。電源管理主要是指某些硬件設(shè)備支持多種工作模式,設(shè)備驅(qū)動的suspend和resume方法可以實(shí)現(xiàn)工作模式的切換,使設(shè)備進(jìn)入休眠,或者恢復(fù)到正常工作狀態(tài)。
設(shè)備層相對簡單,主要是將底層的API封裝成統(tǒng)一的文件接口提供給應(yīng)用層。Linux下的設(shè)備一般可分為3類——字符設(shè)備、網(wǎng)絡(luò)設(shè)備、塊設(shè)備[10],每一種設(shè)備都有各自的應(yīng)用場合和特點(diǎn),差別比較大,這里單總線接口也屬于字符設(shè)備,所以使用的是字符設(shè)備接口。字符設(shè)備通過一個核心結(jié)構(gòu)體——file_operations封裝所有接口函數(shù)原型,最新版的內(nèi)核已經(jīng)提供了25種操作接口,而事實(shí)上常用的只有不到10種,這里用到的包括:
(1)設(shè)備打開——oneWire_open,分配一個新的用戶句柄,綁定適配器,同時將用戶句柄也作為設(shè)備注冊進(jìn)內(nèi)核由內(nèi)核統(tǒng)一管理。
(2)設(shè)備關(guān)閉——oneWire_close,從內(nèi)核中卸載用戶句柄,將用戶句柄和適配器分離,注銷用戶句柄。
(3)設(shè)備控制——oneWire_ioctl,用于除讀寫之外的一些特殊控制,比如復(fù)位、設(shè)置句柄標(biāo)志等等。
(4)設(shè)備讀——oneWire_read,用于從片外設(shè)備讀取數(shù)據(jù)到應(yīng)用層。
(5)設(shè)備寫——oneWire_write,用于將應(yīng)用層數(shù)據(jù)傳輸?shù)狡庠O(shè)備。
應(yīng)用層已經(jīng)涉及到了應(yīng)用程序的編寫,并不是課題要討論的部分,但考慮到系統(tǒng)的完整性,還是將其作為測試,用來驗(yàn)證系統(tǒng)設(shè)計的可行性,在最后一節(jié)展開介紹。
課題設(shè)計的最終目標(biāo)是要求能夠在多用戶態(tài)下正常使用,那就不可避免地會遇到這樣的問題——不同用戶下多應(yīng)用程序同時打開設(shè)備的問題。課題采用了動態(tài)分配用戶句柄的方式解決這個問題,每次有新的應(yīng)用程序打開設(shè)備都會創(chuàng)建一個用戶句柄,而適配器是共用的,新增加的用戶句柄作為一個節(jié)點(diǎn)添加到適配器關(guān)于用戶句柄的鏈表上,在驅(qū)動卸載時遍歷所有句柄,處理所有請求。
多適配器問題和多用戶句柄問題不同,適配器包含具體外設(shè)信息,直接對外實(shí)現(xiàn)控制,是最接近外設(shè)的實(shí)際意義上的設(shè)備。每一個適配器都要求有一個次設(shè)備號,用于標(biāo)識其對應(yīng)的外設(shè)。這部分內(nèi)容與平臺相關(guān),是驅(qū)動移植主要修改的部分。課題采用的解決方案是——用S3C2440的GPB作為單總線接口,GPB共有11個端口,也就是說可以有11個單總線接口,GPB0對應(yīng)的次設(shè)備號為0,GPB1對應(yīng)的次設(shè)備號為1,其他的類似。
在多用戶句柄的情況下,適配器是共用的,這必然會產(chǎn)生互斥問題[11]。在Linux內(nèi)核中,解決互斥問題的方法有自旋鎖、信號量、原子操作、讀寫鎖、順序鎖、RCU、完成事件等。每一種互斥機(jī)制根據(jù)自身的特點(diǎn)都有對應(yīng)的應(yīng)用場合。自旋鎖主要應(yīng)用于多處理器環(huán)境下,它不會引起睡眠,當(dāng)鎖已經(jīng)被其他用戶搶占,當(dāng)前請求者會不斷查詢鎖的保持者是否已經(jīng)釋放鎖,這種特性避免了調(diào)用進(jìn)程的掛起。信號量與自旋鎖的功能類似,但是實(shí)現(xiàn)的辦法完全不同,當(dāng)請求者無法立即獲得信號量時將直接進(jìn)入睡眠,它允許并行訪問,并行訪問的數(shù)量在信號量被創(chuàng)建時初始化,即可以由多個內(nèi)核同時控制該信號量,所以信號量不僅適用于單處理器,也適用于多處理器系統(tǒng)。原子量是最底層的控制方式,是一系列不可中斷操作的集合,它的操作過程是封閉的,不可中斷的,一般很少直接使用。讀寫鎖的特性是對訪問者進(jìn)行區(qū)分,分為讀者和寫者,這類鎖相對于自旋鎖而言,它可以同時有多個讀者進(jìn)行讀訪問,而寫者一個時刻只能有一個,也就是說讀寫鎖同時只能有一個讀者或者多個讀者,但不能既有讀者又有寫者。完成事件,是基于資源保護(hù)而提出的,是一種簡單的同步機(jī)制,可以實(shí)現(xiàn)簡單休眠和喚醒,并且不會引起競爭。其他幾種鎖也各有優(yōu)缺點(diǎn)。
基于上述介紹,課題的互斥機(jī)制采用的是自旋鎖和完成事件。在適配器注冊和卸載的時候采用自旋鎖,防止有未完成的任務(wù)存在時設(shè)備被卸載,以及當(dāng)有新的適配器加入時,訪問設(shè)備鏈表發(fā)生沖突。用戶句柄的添加刪除到適配器關(guān)于用戶句柄的鏈表,也需要自旋鎖實(shí)現(xiàn)串行訪問,因?yàn)槿魏螘r刻對于新添加的句柄,僅有一個可以訪問到該鏈表,否則可能造成鏈表的添加和刪除操作紊亂。設(shè)備卸載使用的互斥機(jī)制是完成事件,等待設(shè)備注銷完成、刪除sys文件系統(tǒng)下的屬性文件以后,才允許退出設(shè)備卸載處理程序。
設(shè)備驅(qū)動、設(shè)備、總線的組織方式最初只有一種方式,由設(shè)計者自行設(shè)計,也就是定義一種專用總線,而新的內(nèi)核提供另一種組織方式,即平臺設(shè)備。對應(yīng)的總線稱為平臺總線,由設(shè)計者提供一些私有參數(shù),通過平臺設(shè)備結(jié)構(gòu)體傳入探測函數(shù)實(shí)現(xiàn)設(shè)備的注冊和初始化。
3.4.1 專用總線
將相關(guān)的設(shè)備和驅(qū)動都掛載在專用總線上,這是傳統(tǒng)方式。像I2C、SPI等總線都提供了這種方式,它的一個特點(diǎn)就是專用性,可以做到高效簡潔,因?yàn)樗?fù)責(zé)專門的設(shè)備注冊、驅(qū)動注冊。多數(shù)設(shè)備都提供這種方式,課題的設(shè)計也提供了這種方式。
3.4.2 平臺總線
平臺總線是一種虛擬總線,相比于USB、PCI等專用總線,它主要用于描述片上資源,如LCD、看門狗等等,平臺設(shè)備所描述的資源有一個共同點(diǎn)——允許總線直接尋址。它需要分配一些特殊的資源,如中斷號、物理地址映射范圍等等。當(dāng)有新的設(shè)備或驅(qū)動注冊時,內(nèi)核會調(diào)用虛擬總線的探測函數(shù),對分配到的資源進(jìn)行初始化,注冊到內(nèi)核,從本質(zhì)上說,平臺設(shè)備只是標(biāo)準(zhǔn)設(shè)備一種擴(kuò)展。課題在驗(yàn)證設(shè)計的正確與否采用就是這種組織方式。
圖3是基于ARM920T平臺的外設(shè)連接方式,這里的驗(yàn)證僅取兩條總線,每一條總線上掛載一個DS18B20[12]作為測試設(shè)備,在一個循環(huán)里每次輪流讀取溫度傳感器傳回的數(shù)據(jù),并將其從二進(jìn)制轉(zhuǎn)為十進(jìn)制顯示(僅考慮正溫度的情況)。二進(jìn)制小數(shù)的提取采用的是比較原始的辦法——查表法,因?yàn)镈S18B20的小數(shù)只用4bit表示,也就是說只有16種取值,所以不會占用很大內(nèi)存。
圖3 外設(shè)拓?fù)鋱D
得益于字符設(shè)備的統(tǒng)一接口,應(yīng)用層的調(diào)用非常簡單,只需要打開設(shè)備,就可以讀寫數(shù)據(jù)。而在退出程序時,關(guān)閉設(shè)備是必須的,這樣才能釋放不用的資源。測試程序比較簡短,其主程序片段如下所示(注:未寫出出錯處理代碼):
下面是程序運(yùn)行結(jié)果,總共有4個模塊需要加載,分別是核心模塊、底層接口模塊、設(shè)備接口模塊、外設(shè)注冊模塊。當(dāng)運(yùn)行test程序時,就啟動溫度轉(zhuǎn)換和采集,然后將采集的數(shù)據(jù)進(jìn)行處理后打印到終端,溫度的單位為開爾文,如23.2500+273.15K,表示當(dāng)前環(huán)境溫度為23.2500攝氏度。Sensor1、sensor2分別標(biāo)識傳感器1和傳感器2,通過對比可以發(fā)現(xiàn)它們的采樣還是有零點(diǎn)幾度的偏差的。
[root@EmbedSkywlq1988]#insmod oneWire_core.ko.
[root@EmbedSkywlq1988]#insmod oneWire_s3c2440.ko.
[root@EmbedSkywlq1988]#insmod oneWire_dev.ko.
[root@EmbedSkywlq1988]#insmod oneWire_device.ko.
[root@EmbedSkywlq1988]#./test
ds18b20 test.
open success.
cureent temperature:sensor1:23.2500+273.15 K
cureent temperature:sensor1:23.3125+273.15 K
cureent temperature:sensor1:23.2500+273.15 K
cureent temperature:sensor2:23.3125+273.15 K
…
測試程序簡單地驗(yàn)證了設(shè)計的正確性,這是兩條總線一對一的情況。通過簡單配置還可以實(shí)現(xiàn)掛載更多的設(shè)備,也就一對多,多對多的情況。
課題實(shí)現(xiàn)了linux框架下的單總線控制器,整個設(shè)計利用linux內(nèi)核的一些同步措施保障了系統(tǒng)運(yùn)行的穩(wěn)定性。同時,由于整個設(shè)計過程采用了分離、分層思想,所以,使用者只需對底層接口稍加修改即可實(shí)現(xiàn)移植,并將其嵌入到更多的嵌入式系統(tǒng)中,具有一定的實(shí)用意義。
[1]李正平,徐超,陳軍寧.Linux 2.6內(nèi)核設(shè)備模型分析[J].計算機(jī)技術(shù)與發(fā)展,2007,17(3):141-143.
[2]劉軍衛(wèi),李曦,陳香蘭.用戶態(tài)驅(qū)動框架的研究與實(shí)現(xiàn)[J].計算機(jī)系統(tǒng)與應(yīng)用,2011,20(11):67-71.
[3]馮國進(jìn).嵌入式Linux驅(qū)動程序設(shè)計從入門到精通[M].北京:清華大學(xué)出版社,2008:10-35.
[4]秦芹.一種基于DS18B2O的溫度采集新方案[J].電子技術(shù)設(shè)計與運(yùn)用,2010,37(37):62-64.
[5]張會新,龔進(jìn),樊姣榮.分布式數(shù)字無線測溫系統(tǒng)[J].化工自動化及儀表,2011,38(12):1493-1495.
[6]任兵,任小洪,李國志.基于ARM-Linux的多路溫度采集系統(tǒng)的設(shè)計[J].工業(yè)控制計算,2011,24(11):44-45.
[7]陳聰慧,蘇偉達(dá),蔡聲鎮(zhèn).一種單總線接口時序分析儀的研制木[J].微計算機(jī)應(yīng)用,2008,29(6):50-53.
[8]陳曦,呂湘曄,劉艷防.基于嵌入式Linux新型模塊化工業(yè)控制器設(shè)計[J].儀表技術(shù)與傳感器,2010(11):27-29.
[9]陳生翰,劉其洪,丁注.單總線數(shù)字溫度傳感器DS18B20自動識別的設(shè)計與實(shí)現(xiàn)[J].儀表技術(shù)與傳感器,2010(5):16-18.
[10]舒克毅,胡榮強(qiáng).嵌人式Linux字符設(shè)備驅(qū)動程序設(shè)計[J].儀表技術(shù),2010(2):4-8.
[11]張祖昌,曾夏夏.互斥技術(shù)在嵌人式系統(tǒng)中的應(yīng)用[J].閩江學(xué)院學(xué)報,2007,28(5):68-71.
[12]陳志英,李光輝.單總線(1-Wire Bus)技術(shù)及其應(yīng)用[J].國外電子元器件,2003(8):4-7.
Imp lementation of 1-W ire Interface Based on Linux Devicemodel
WANG Longqi,F(xiàn)AN Minghui*,CHEN Lihong
(Department of Physics and Information Engineering,F(xiàn)uzhou University,F(xiàn)uzhou Fujian 350000,China)
1-Wire Bus is a bus protocol which connects some sensors and low-speed devices with the host,such as the smart temperature sensor DS18B20,A/D chip,and so on.With the developmentof the internetof things,the application of these sensorswill becomemore widespread,but their interfaces are not closely linked with the kernel,the kernel can not unify themanagement,so stability and reliabilitymay not be guaranteed.In linewith the premise of the Linux kernel devicemodel,a stable 1-Wire interface is given.the controller will be divided into three parts,top-level device interface,the core layer and the underlying hardware interface;menuwhile the driver and the device,the top-level device interface and the specific hardware are seperated in operations.
the 1-Wwire bus;Linux;embedded system;stratification;separation
10.3969/j.issn.1005-9490.2014.01.025
TP316.2 文獻(xiàn)標(biāo)識碼:A 文章編號:1005-9490(2014)01-0103-05
2013-04-11修改日期:2013-05-20
EEACC:6150M
王龍奇(1988-)男,碩士研究生,主要研究方向?yàn)榍度胧较到y(tǒng)設(shè)計,393146277@ qq.com;
樊明輝(1974-),男,副研究員,博士,主要研究方向?yàn)橛嬎銠C(jī)應(yīng)用和地理信息系統(tǒng),fanmh@fzu.edu.cn。