朱海蕊
(中國礦業(yè)大學(xué)(北京) 機電與信息工程學(xué)院,北京 100083)
基于Linux的加速度傳感器mma8653驅(qū)動程序的設(shè)計
朱海蕊
(中國礦業(yè)大學(xué)(北京) 機電與信息工程學(xué)院,北京 100083)
文章首先闡述了mma8653加速度傳感器以及在應(yīng)用中的優(yōu)勢,介紹了嵌入式Linux系統(tǒng)驅(qū)動程序的框架結(jié)構(gòu)并分別介紹各層的作用,然后分析了IIC總線數(shù)據(jù)傳輸?shù)臅r序、嵌入式Linux系統(tǒng)IIC設(shè)備驅(qū)動程序的設(shè)計,最后介紹了基于Linux的加速度傳感器mma8653設(shè)備驅(qū)動程序的具體實現(xiàn)。
Linux;IIC總線;驅(qū)動程序;mma8653
加速度傳感器是一類能夠感知物體的加速度變化,并將其轉(zhuǎn)變?yōu)榭捎幂敵鲂盘柕膫鞲衅鳌kS著制造工藝的日益成熟和加速度測量技術(shù)的迅速發(fā)展,加速度傳感器測量精度不斷提高,廣泛應(yīng)用于智能手機、平板電腦、數(shù)碼相機、便攜式導(dǎo)航解決方案和醫(yī)療應(yīng)用中。然而現(xiàn)有的采集平臺大多考慮了高效穩(wěn)定的數(shù)據(jù)采集傳輸,而忽略了應(yīng)用中對芯片的尺寸和功耗的要求。
mma8653是飛思卡爾生產(chǎn)的加速度傳感器,具有體積小、低功率、噪音低、運動精度高的特點。引腳兼容型Xtrinsic mma8652FC 12位和mma8653FC 10位加速計。適用于對功率和空間具有限制的移動器件。mma8653的工作電壓1.95V-3.6V,支持IIC總線接口。
準確的加速度數(shù)據(jù)測量是嵌入式系統(tǒng)中重要的一點,在Linux操作系統(tǒng)下使用加速度傳感器mma8653,不僅可以采集到高精度的數(shù)據(jù),而且硬件簡單可靠。
IIC(Inter-Integrated Circuit)總線是一種由PHILIPS公司開發(fā)的兩線式串行總線,在嵌入式設(shè)備中得到廣泛的應(yīng)用[1]。IIC串行總線一般有兩根信號線,一根是雙向的數(shù)據(jù)線SDA,另一根是時鐘線SCL。所有接到IIC總線設(shè)備上的串行數(shù)據(jù)SDA都接到總線的SDA上,各設(shè)備的時鐘線SCL接到總線的SCL上。
Linux的IIC體系結(jié)構(gòu)主要由3個部分構(gòu)成,分別是IIC核心、IIC總線驅(qū)動和IIC設(shè)備驅(qū)動[2],其體系結(jié)構(gòu)如圖1所示。
IIC核心層作為IIC總線的驅(qū)動和設(shè)備驅(qū)動之間的紐帶,提供了一組接口函數(shù),這些接口函數(shù)不依賴于具體的硬件平臺,其中包括IIC總線驅(qū)動和設(shè)備驅(qū)動的注冊函數(shù)和注銷函數(shù)等,IIC核心層提供的傳輸、發(fā)送和接受函數(shù),可用來完成消息的讀寫。
IIC總線驅(qū)動是對IIC硬件體系結(jié)構(gòu)中IIC控制器的實現(xiàn),IIC控制器與CPU鏈接,受CPU的控制,IIC控制器可以直接集成在CPU的內(nèi)部[3]。由IIC總線驅(qū)動控制的代碼,可以控制IIC控制器以主動的方式產(chǎn)生IIC在通信過程中所必須開始位、停止位、讀寫周期,以及以從設(shè)備方式被讀寫,產(chǎn)生的應(yīng)答信號(ACK)等。
圖1 Linux中IIC體系結(jié)構(gòu)
IIC設(shè)備驅(qū)動是對IIC體系結(jié)構(gòu)中的設(shè)備端的實現(xiàn),設(shè)備一般掛在受CPU控制的IIC控制器上[4],設(shè)備通過IIC控制器與CPU進行數(shù)據(jù)的傳輸,IIC設(shè)備層由IIC設(shè)備和對應(yīng)的設(shè)備驅(qū)動組成。
mma8653采用設(shè)備-總線-驅(qū)動編程模型,內(nèi)核定義一個虛擬總線i2c_bus_type,虛擬總線上維護著設(shè)備相關(guān)的硬件信息鏈表和設(shè)備相關(guān)的驅(qū)動的鏈表,其中設(shè)備相關(guān)的硬件信息鏈表描述的IIC外設(shè)的純硬件信息,每一個節(jié)點的數(shù)據(jù)結(jié)構(gòu)為struct i2c_client,設(shè)備相關(guān)的驅(qū)動的鏈表描述IIC外設(shè)的純軟件信息,每一個節(jié)點的數(shù)據(jù)結(jié)構(gòu)為struct i2c_driver,驅(qū)動開發(fā)者只需用這兩個數(shù)據(jù)結(jié)構(gòu)定義初始化一個對象,然后向?qū)?yīng)的鏈表添加,內(nèi)核會調(diào)用match函數(shù)來比較硬件節(jié)點的name和軟件節(jié)點的name進行匹配,如果匹配成功,內(nèi)核會調(diào)用軟件節(jié)點的probe函數(shù),并把硬件節(jié)點的首地址傳遞給probe函數(shù)。
在ARM嵌入式系統(tǒng)IIC總線中,一般微處理器(如:S5P6818)是總線上的主機,其他是從機,IIC總線上可同時接多個從機,每個從機都有一個唯一的地址,主機負責IIC總線的初始化、數(shù)據(jù)傳輸、產(chǎn)生時鐘信號等工作。IIC總線傳輸?shù)臅r序如圖2所示:在I2C總線傳輸過程中,將兩種特定的情況定義為開始和停止條件:當SCL保持“高”時,SDA由“高”變?yōu)椤暗汀睘殚_始(START)條件;當SCL保持“高”且SDA由“低”變?yōu)椤案摺睍r為停止(STOP)條件。開始和停止條件均由主控制器產(chǎn)生。
SDA線上的數(shù)據(jù)在時鐘“高”期間必須是穩(wěn)定的,只有當SCL線上的時鐘信號為低時,數(shù)據(jù)線上的“高”或“低”狀態(tài)才可以改變。輸出到SDA線上的每個字節(jié)必須是8位,每次傳輸?shù)淖止?jié)不受限制,但每個字節(jié)必須要有一個應(yīng)答ACK。如果接收器件在完成其他功能(如內(nèi)部中斷)前不能接收另一數(shù)據(jù)的完整字節(jié)時,它可以保持時鐘線SCL為低,以促使發(fā)送器進入等待狀態(tài);當接收器準備好接收數(shù)據(jù)的其他字節(jié)并釋放時鐘SCL后,數(shù)據(jù)傳輸繼續(xù)進行。
2.1 IIC總線寫操作時序
IIC總線寫操作有二種方式:字節(jié)寫和頁面寫。字節(jié)寫是指:每次在指定位置寫入一個字節(jié)數(shù)據(jù),時序如圖3(a)所示。首先CPU向總線發(fā)送START信號,然后CPU向總線上發(fā)送mma8653的設(shè)備地址和寫位,表明CPU要將訪問的片內(nèi)寄存器地址告訴mma8653,如果外設(shè)存在于總線上,外設(shè)會在第九個時鐘周期給CPU一個ACK應(yīng)答信號;當應(yīng)答信號來到之后再發(fā)一個器件內(nèi)部地址,外設(shè)接收到要訪問的片內(nèi)寄存器以后,給CPU一個應(yīng)答信號ACK;當應(yīng)答信號來到之后立即發(fā)送數(shù)據(jù),當下一個應(yīng)答信號來到之后發(fā)送停止(STOP)信號。頁面寫和字節(jié)寫操作很類似,只是主機在完成第一輪數(shù)據(jù)傳送之后不發(fā)送停止信號,而繼續(xù)發(fā)送數(shù)據(jù),時序如圖3(b)所示:IIC字節(jié)寫和頁面寫所對應(yīng)的函數(shù)分別是i2c_smbus_write_byte_data()和i2c_smbus_write_block_ data()。
2.2 IIC總線讀操作時序
IIC總線讀操作主要有2種方式:指定位置讀和連續(xù)讀。指定位置讀時序如圖4(a)所示,CPU首先向總線發(fā)送START信號,然后向總線上發(fā)送mma8653的設(shè)備地址和寫位,如果設(shè)備存在于總線上,設(shè)備在第九個時鐘周期給CPU發(fā)送一個ACK信號,CPU然后向外設(shè)發(fā)送要訪問的片內(nèi)寄存器的地址,外設(shè)給CPU發(fā)送一個ACK信號,CPU重發(fā)START信號,CPU繼續(xù)重發(fā)外設(shè)的設(shè)備地址和讀位,表明CPU要開始讀取數(shù)據(jù),外設(shè)繼續(xù)給CPU一個ACK信號,外設(shè)最終將數(shù)據(jù)發(fā)送給CPU,CPU接收到數(shù)據(jù),沒有給外設(shè)一個有效的ACK信號,CPU數(shù)據(jù)讀取操作完畢,最后發(fā)送STOP信號。連續(xù)讀時序如圖4(b)所示;IIC指定位置讀和連續(xù)讀所對應(yīng)的函數(shù)分別是i2c_smbus_ read_byte_data()和i2c_smbus_read_block_data()。
Linux的內(nèi)核是一個整體的內(nèi)核,即所有的內(nèi)核功能鏈接在一起,在同一個地址空間執(zhí)行,如果新增加或去除一個硬件驅(qū)動,需要把原有的內(nèi)核重新編譯一遍,這樣會帶來很多不便和浪費。Linux操作系統(tǒng)提供內(nèi)核模塊機制來解決此問題。
模塊是設(shè)備驅(qū)動程序,在編譯內(nèi)核時并沒有以靜態(tài)地方式鏈接進內(nèi)核,而是被分別編譯并鏈接成一組目標文件,以模塊加載的方式加載進內(nèi)核,或從正在運行的內(nèi)核中被卸載[5]。這樣保證了內(nèi)核能達到最小,并且在使用的過程中非常靈活。
內(nèi)核在運行insmod命令后由系統(tǒng)調(diào)用mma8653_init()函數(shù),完成驅(qū)動模塊的加載工作,在內(nèi)核中完成各種函數(shù)的注冊,在注冊之后,應(yīng)用程序調(diào)用函數(shù)時,內(nèi)核將查表獲得相應(yīng)函數(shù)的位置并調(diào)用;運行rmmod命令后有系統(tǒng)調(diào)用mma8653_exit()函數(shù),此時完成驅(qū)動模塊卸載時的各種清理工作,把注冊到內(nèi)核中的函數(shù)卸載,mma8653_exit()函數(shù)必須把注冊到內(nèi)核的功能函數(shù)完全卸載,否則,再次調(diào)用此模塊時,會因為有相同的函數(shù)名而導(dǎo)致調(diào)用失敗。
圖2 IIC總線數(shù)據(jù)傳輸時序
圖3 IIC總線寫數(shù)據(jù)時序
圖4 IIC總線讀數(shù)據(jù)時序
mma8653是由飛思卡爾公司開發(fā)的高性能、低功耗的三軸加速計,適用于對功率和空間具有限制的移動器件。mma8653采用IIC接口,體積小使用方便,mma8653的2、10腳分別和S5P6818的IIC控制的時鐘(SCL)和數(shù)據(jù)管腳(SDA)連接,然后通過對S5P6818的控制器進行編程,以IIC的方式控制和訪問mma8653,從而獲得mma8653的三個軸向的加速度值。mma8653電路如圖5所示。
mma8653驅(qū)動最終能否得以正常運行,獲得實時溫度值,關(guān)鍵在于能否正確地編寫初始化硬件程序、讀寫操作的程序。
4.1 設(shè)備的初始化、退出處理模塊
設(shè)備初始化模塊的主要功能是:向內(nèi)核注冊設(shè)備節(jié)點,mma8653_init()函數(shù)執(zhí)行的時候,函數(shù)i2c_add_ driver(&mma8653_drv)執(zhí)行,如果i2c_ driver的id_ table中的name和client中的name匹配后,內(nèi)核調(diào)用i2c_ driver_probe()函數(shù),調(diào)用 mma8653_exit(void)會進行設(shè)備的卸載,具體函數(shù)實現(xiàn)如下。
圖5 mma8653電路
4.2 初始化mma8653硬件程序
對mma8653進行操作之前要對采集數(shù)據(jù)的模式、采集數(shù)據(jù)的范圍進行設(shè)置。IIC設(shè)備驅(qū)動調(diào)用SMBUS接口函數(shù)來操作IIC控制器,從而發(fā)起硬件的操作時序。
下面是初始化硬件程序代碼:
4.3 讀數(shù)據(jù)模塊
Mma8653需要連續(xù)的讀取加速度的數(shù)據(jù)值,具體實現(xiàn)的函數(shù)如下:
4.4 應(yīng)用層接口函數(shù)
4.5 硬件信息
要向內(nèi)核中添加mma8653的硬件相關(guān)的信息,內(nèi)核根據(jù)硬件信息定義初始化硬件節(jié)點,具體代碼如下:
本文采用設(shè)備—總線—驅(qū)動模型來編寫mma8653驅(qū)動程序,采用模塊化加載的方式來調(diào)試mma8653的驅(qū)動程序,mma8653采集數(shù)據(jù)的結(jié)果如圖6所示。
圖6 mma8653采集數(shù)據(jù)結(jié)果
[1]朱華生,葉軍.嵌入式系統(tǒng)IIC設(shè)備驅(qū)動程序設(shè)計與實現(xiàn)[J].微計算機信息,2006(10):170-172.
[2]怯肇乾,吳志亮. ARM-Linux-IIC設(shè)備的添加與驅(qū)動[J].電腦編程技巧與維護,2012(15):14-18.
[3]李植,李哲,牟云飛.IIC總線在Linux下驅(qū)動程序的設(shè)計與實現(xiàn)[J].工業(yè)控制計算機,2015(5):16-18.
[4]何亞軍,鄧飛其.嵌入式Linux中I2C總線驅(qū)動程序設(shè)計[J].計算機工程與設(shè)計,2008(10):2517-2519,2522.
[5]董志國,李式巨.嵌入式Linux設(shè)備驅(qū)動程序開發(fā)[J].計算機工程與設(shè)計,2006(20):3737-3740.
Design of acceleration sensor mma8653 driver based on Linux
Zhu Hairui
(Mechatronics and Information Engineering College of China University of Mining and Technology(Beijing), Beijing 100083, China)
Firstly, this paper expounded the mma8653 acceleration sensor and its advantages in application.,and introduced the frame structure of the embedded Linux system driver and respectively introduced the role of each layer., and then analyzed the IIC bus data transmission sequence and the design of the embedded Linux system IIC device driver, fnally introduced the concrete implementation of the device driver of acceleration sensor mma8653 based on Linux.
Linux; IIC bus; drivers; mma8653
朱海蕊(1988— ),女,河南安陽,碩士;研究方向:計算機應(yīng)用技術(shù)。