朱海蕊
(中國礦業大學(北京) 機電與信息工程學院,北京 100083)
基于Linux的加速度傳感器mma8653驅動程序的設計
朱海蕊
(中國礦業大學(北京) 機電與信息工程學院,北京 100083)
文章首先闡述了mma8653加速度傳感器以及在應用中的優勢,介紹了嵌入式Linux系統驅動程序的框架結構并分別介紹各層的作用,然后分析了IIC總線數據傳輸的時序、嵌入式Linux系統IIC設備驅動程序的設計,最后介紹了基于Linux的加速度傳感器mma8653設備驅動程序的具體實現。
Linux;IIC總線;驅動程序;mma8653
加速度傳感器是一類能夠感知物體的加速度變化,并將其轉變為可用輸出信號的傳感器。隨著制造工藝的日益成熟和加速度測量技術的迅速發展,加速度傳感器測量精度不斷提高,廣泛應用于智能手機、平板電腦、數碼相機、便攜式導航解決方案和醫療應用中。然而現有的采集平臺大多考慮了高效穩定的數據采集傳輸,而忽略了應用中對芯片的尺寸和功耗的要求。
mma8653是飛思卡爾生產的加速度傳感器,具有體積小、低功率、噪音低、運動精度高的特點。引腳兼容型Xtrinsic mma8652FC 12位和mma8653FC 10位加速計。適用于對功率和空間具有限制的移動器件。mma8653的工作電壓1.95V-3.6V,支持IIC總線接口。
準確的加速度數據測量是嵌入式系統中重要的一點,在Linux操作系統下使用加速度傳感器mma8653,不僅可以采集到高精度的數據,而且硬件簡單可靠。
IIC(Inter-Integrated Circuit)總線是一種由PHILIPS公司開發的兩線式串行總線,在嵌入式設備中得到廣泛的應用[1]。IIC串行總線一般有兩根信號線,一根是雙向的數據線SDA,另一根是時鐘線SCL。所有接到IIC總線設備上的串行數據SDA都接到總線的SDA上,各設備的時鐘線SCL接到總線的SCL上。
Linux的IIC體系結構主要由3個部分構成,分別是IIC核心、IIC總線驅動和IIC設備驅動[2],其體系結構如圖1所示。
IIC核心層作為IIC總線的驅動和設備驅動之間的紐帶,提供了一組接口函數,這些接口函數不依賴于具體的硬件平臺,其中包括IIC總線驅動和設備驅動的注冊函數和注銷函數等,IIC核心層提供的傳輸、發送和接受函數,可用來完成消息的讀寫。
IIC總線驅動是對IIC硬件體系結構中IIC控制器的實現,IIC控制器與CPU鏈接,受CPU的控制,IIC控制器可以直接集成在CPU的內部[3]。由IIC總線驅動控制的代碼,可以控制IIC控制器以主動的方式產生IIC在通信過程中所必須開始位、停止位、讀寫周期,以及以從設備方式被讀寫,產生的應答信號(ACK)等。

圖1 Linux中IIC體系結構
IIC設備驅動是對IIC體系結構中的設備端的實現,設備一般掛在受CPU控制的IIC控制器上[4],設備通過IIC控制器與CPU進行數據的傳輸,IIC設備層由IIC設備和對應的設備驅動組成。
mma8653采用設備-總線-驅動編程模型,內核定義一個虛擬總線i2c_bus_type,虛擬總線上維護著設備相關的硬件信息鏈表和設備相關的驅動的鏈表,其中設備相關的硬件信息鏈表描述的IIC外設的純硬件信息,每一個節點的數據結構為struct i2c_client,設備相關的驅動的鏈表描述IIC外設的純軟件信息,每一個節點的數據結構為struct i2c_driver,驅動開發者只需用這兩個數據結構定義初始化一個對象,然后向對應的鏈表添加,內核會調用match函數來比較硬件節點的name和軟件節點的name進行匹配,如果匹配成功,內核會調用軟件節點的probe函數,并把硬件節點的首地址傳遞給probe函數。
在ARM嵌入式系統IIC總線中,一般微處理器(如:S5P6818)是總線上的主機,其他是從機,IIC總線上可同時接多個從機,每個從機都有一個唯一的地址,主機負責IIC總線的初始化、數據傳輸、產生時鐘信號等工作。IIC總線傳輸的時序如圖2所示:在I2C總線傳輸過程中,將兩種特定的情況定義為開始和停止條件:當SCL保持“高”時,SDA由“高”變為“低”為開始(START)條件;當SCL保持“高”且SDA由“低”變為“高”時為停止(STOP)條件。開始和停止條件均由主控制器產生。
SDA線上的數據在時鐘“高”期間必須是穩定的,只有當SCL線上的時鐘信號為低時,數據線上的“高”或“低”狀態才可以改變。輸出到SDA線上的每個字節必須是8位,每次傳輸的字節不受限制,但每個字節必須要有一個應答ACK。如果接收器件在完成其他功能(如內部中斷)前不能接收另一數據的完整字節時,它可以保持時鐘線SCL為低,以促使發送器進入等待狀態;當接收器準備好接收數據的其他字節并釋放時鐘SCL后,數據傳輸繼續進行。
2.1 IIC總線寫操作時序
IIC總線寫操作有二種方式:字節寫和頁面寫。字節寫是指:每次在指定位置寫入一個字節數據,時序如圖3(a)所示。首先CPU向總線發送START信號,然后CPU向總線上發送mma8653的設備地址和寫位,表明CPU要將訪問的片內寄存器地址告訴mma8653,如果外設存在于總線上,外設會在第九個時鐘周期給CPU一個ACK應答信號;當應答信號來到之后再發一個器件內部地址,外設接收到要訪問的片內寄存器以后,給CPU一個應答信號ACK;當應答信號來到之后立即發送數據,當下一個應答信號來到之后發送停止(STOP)信號。頁面寫和字節寫操作很類似,只是主機在完成第一輪數據傳送之后不發送停止信號,而繼續發送數據,時序如圖3(b)所示:IIC字節寫和頁面寫所對應的函數分別是i2c_smbus_write_byte_data()和i2c_smbus_write_block_ data()。
2.2 IIC總線讀操作時序
IIC總線讀操作主要有2種方式:指定位置讀和連續讀。指定位置讀時序如圖4(a)所示,CPU首先向總線發送START信號,然后向總線上發送mma8653的設備地址和寫位,如果設備存在于總線上,設備在第九個時鐘周期給CPU發送一個ACK信號,CPU然后向外設發送要訪問的片內寄存器的地址,外設給CPU發送一個ACK信號,CPU重發START信號,CPU繼續重發外設的設備地址和讀位,表明CPU要開始讀取數據,外設繼續給CPU一個ACK信號,外設最終將數據發送給CPU,CPU接收到數據,沒有給外設一個有效的ACK信號,CPU數據讀取操作完畢,最后發送STOP信號。連續讀時序如圖4(b)所示;IIC指定位置讀和連續讀所對應的函數分別是i2c_smbus_ read_byte_data()和i2c_smbus_read_block_data()。
Linux的內核是一個整體的內核,即所有的內核功能鏈接在一起,在同一個地址空間執行,如果新增加或去除一個硬件驅動,需要把原有的內核重新編譯一遍,這樣會帶來很多不便和浪費。Linux操作系統提供內核模塊機制來解決此問題。
模塊是設備驅動程序,在編譯內核時并沒有以靜態地方式鏈接進內核,而是被分別編譯并鏈接成一組目標文件,以模塊加載的方式加載進內核,或從正在運行的內核中被卸載[5]。這樣保證了內核能達到最小,并且在使用的過程中非常靈活。
內核在運行insmod命令后由系統調用mma8653_init()函數,完成驅動模塊的加載工作,在內核中完成各種函數的注冊,在注冊之后,應用程序調用函數時,內核將查表獲得相應函數的位置并調用;運行rmmod命令后有系統調用mma8653_exit()函數,此時完成驅動模塊卸載時的各種清理工作,把注冊到內核中的函數卸載,mma8653_exit()函數必須把注冊到內核的功能函數完全卸載,否則,再次調用此模塊時,會因為有相同的函數名而導致調用失敗。

圖2 IIC總線數據傳輸時序

圖3 IIC總線寫數據時序

圖4 IIC總線讀數據時序
mma8653是由飛思卡爾公司開發的高性能、低功耗的三軸加速計,適用于對功率和空間具有限制的移動器件。mma8653采用IIC接口,體積小使用方便,mma8653的2、10腳分別和S5P6818的IIC控制的時鐘(SCL)和數據管腳(SDA)連接,然后通過對S5P6818的控制器進行編程,以IIC的方式控制和訪問mma8653,從而獲得mma8653的三個軸向的加速度值。mma8653電路如圖5所示。
mma8653驅動最終能否得以正常運行,獲得實時溫度值,關鍵在于能否正確地編寫初始化硬件程序、讀寫操作的程序。
4.1 設備的初始化、退出處理模塊
設備初始化模塊的主要功能是:向內核注冊設備節點,mma8653_init()函數執行的時候,函數i2c_add_ driver(&mma8653_drv)執行,如果i2c_ driver的id_ table中的name和client中的name匹配后,內核調用i2c_ driver_probe()函數,調用 mma8653_exit(void)會進行設備的卸載,具體函數實現如下。





圖5 mma8653電路
4.2 初始化mma8653硬件程序
對mma8653進行操作之前要對采集數據的模式、采集數據的范圍進行設置。IIC設備驅動調用SMBUS接口函數來操作IIC控制器,從而發起硬件的操作時序。
下面是初始化硬件程序代碼:


4.3 讀數據模塊
Mma8653需要連續的讀取加速度的數據值,具體實現的函數如下:

4.4 應用層接口函數


4.5 硬件信息
要向內核中添加mma8653的硬件相關的信息,內核根據硬件信息定義初始化硬件節點,具體代碼如下:

本文采用設備—總線—驅動模型來編寫mma8653驅動程序,采用模塊化加載的方式來調試mma8653的驅動程序,mma8653采集數據的結果如圖6所示。

圖6 mma8653采集數據結果
[1]朱華生,葉軍.嵌入式系統IIC設備驅動程序設計與實現[J].微計算機信息,2006(10):170-172.
[2]怯肇乾,吳志亮. ARM-Linux-IIC設備的添加與驅動[J].電腦編程技巧與維護,2012(15):14-18.
[3]李植,李哲,牟云飛.IIC總線在Linux下驅動程序的設計與實現[J].工業控制計算機,2015(5):16-18.
[4]何亞軍,鄧飛其.嵌入式Linux中I2C總線驅動程序設計[J].計算機工程與設計,2008(10):2517-2519,2522.
[5]董志國,李式巨.嵌入式Linux設備驅動程序開發[J].計算機工程與設計,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— ),女,河南安陽,碩士;研究方向:計算機應用技術。