技術頻道

娓娓工業(yè)
您現(xiàn)在的位置: 中國傳動網(wǎng) > 技術頻道 > 技術百科 > 嵌入式Linux系統(tǒng)中I2C總線設備的驅(qū)動設計

嵌入式Linux系統(tǒng)中I2C總線設備的驅(qū)動設計

時間:2007-12-21 16:44:00來源:caojing

導語:?本文分析了Linux系統(tǒng)中I2C驅(qū)動程序的結(jié)構(gòu),并以AT91RM9200和X1227為例,介紹了如何在嵌入式Linux系統(tǒng)中實現(xiàn)I2C總線適配器及I2C設備驅(qū)動。
摘要: 本文分析了Linux系統(tǒng)中I2C驅(qū)動程序的結(jié)構(gòu),并以AT91RM9200和X1227為例,介紹了如何在嵌入式Linux系統(tǒng)中實現(xiàn)I2C總線適配器及I2C設備驅(qū)動。 關鍵詞: Linux I2C總線 I2C設備 驅(qū)動 引言 I2C總線是PHILIPS公司推出的兩線式串行總線,用于連接微控制器及其外圍設備,具有簡單、高效等特點。由于其接口直接在組件之上,因此I2C總線占用的空間非常小,減少了電路板的空間和芯片引腳的數(shù)量,降低了互聯(lián)成本,特別適用于嵌入式產(chǎn)品。 而Linux系統(tǒng)具有開源、免費、網(wǎng)上資源豐富等優(yōu)點,目前已成為嵌入式系統(tǒng)的主流選擇。因此如何在嵌入式Linux系統(tǒng)中實現(xiàn)I2C功能成為實際開發(fā)中的問題。 1.I2C總線 I2C 總線通過串行數(shù)據(jù)SDA 和串行時鐘SCL線在連接到總線的器件間傳遞信息,每個器件都有一個唯一的地址識別。根據(jù)數(shù)據(jù)傳輸時的功能不同,把器件分為主機和從機。主機是初始化總線的數(shù)據(jù)傳輸并產(chǎn)生允許傳輸?shù)臅r鐘信號的器件,通常是微控制器。此時,任何被尋址的器件都被認為是從機,例如LCD驅(qū)動器、E2PROM等。 I2C總線協(xié)議規(guī)定,各主機進行通信時都要有起始、結(jié)束、發(fā)送數(shù)據(jù)和應答信號。這些信號都是通信過程中的基本單元。起始信號就是在SCL線為高時SDA線從高變化到低;停止信號就是在SCL線為高時SDA線從低變化到高;應答信號是在SCL為高時SDA為低;非應答信號相反,是在SCL為高時SDA為高。 總線傳送的每1幀數(shù)據(jù)均是1個字節(jié)。協(xié)議規(guī)定,在啟動總線后的第1個字節(jié)的高7位是對從機的尋址地址,第8位為方向位(“0”表示主機對從機的寫操作;“1”表示主機對從機的讀操作),其余的字節(jié)為操作數(shù)據(jù)。數(shù)據(jù)傳送過程是:在I2C總線發(fā)送起始信號后,發(fā)送從機的7位尋址地址和1位表示這次操作性質(zhì)的讀寫位,在有應答信號后開始傳送數(shù)據(jù),直到發(fā)送停止信號。主機每發(fā)送1個字節(jié)就要檢測SDA線上有沒有收到應答信號,有則繼續(xù)發(fā)送,否則將停止發(fā)送數(shù)據(jù)。 2.Linux中I2C總線驅(qū)動結(jié)構(gòu) Linux系統(tǒng)對I2C總線具有很好的支持。與硬件物理連接相對應的,Linux的I2C框架中各個部分的關系如圖1所示。
圖1 Linux內(nèi)核I2C總線驅(qū)動程序構(gòu)架
內(nèi)核中I2C相關代碼可以分為三個層次: 1. I2C core框架:提供了核心數(shù)據(jù)結(jié)構(gòu)的定義和相關接口函數(shù),用來實現(xiàn)I2C適配器驅(qū)動和設備驅(qū)動的注冊、注銷管理,以及I2C通信方法上層的、與具體適配器無關的代碼,為系統(tǒng)中每個I2C總線增加相應的讀寫方法。 2. I2C總線適配器驅(qū)動:定義描述具體I2C總線適配器的i2c_adapter數(shù)據(jù)結(jié)構(gòu)、實現(xiàn)在具體I2C適配器上的I2C總線通信方法,并由i2c_algorithm數(shù)據(jù)結(jié)構(gòu)進行描述。 3. I2C 設備驅(qū)動:定義描述具體設備的i2c_client和可能的私有數(shù)據(jù)結(jié)構(gòu)、借助I2C core提供的函數(shù)接口完成設備在內(nèi)核的注冊,并實現(xiàn)具體的功能,包括read, write以及ioctl等對用戶層操作的接口。 總體而言,Linux中I2C總線的驅(qū)動分為兩個部分:總線驅(qū)動(BUS)和設備驅(qū)動(DEVICE)。I2C core與I2C總線適配器驅(qū)動完成了硬件上的主機總線驅(qū)動(BUS),而I2C driver則實現(xiàn)了從機設備驅(qū)動。在設計中,I2C core提供的接口是統(tǒng)一的,不需要修改,我們只需要實現(xiàn)特定I2C總線適配器驅(qū)動和I2C設備驅(qū)動,這樣大大提高了系統(tǒng)的可移植性。 筆者在某個產(chǎn)品中曾用AT91RM9200和X1227構(gòu)成嵌入式系統(tǒng)的時鐘模塊。在該設計中,AT91RM9200作為I2C的主機部分,X1227作為從機。下面以此為例,具體介紹這兩部分驅(qū)動的實現(xiàn)。 3.AT91RM9200 I2C總線驅(qū)動實現(xiàn) AT91RM9200是ARM920T處理器,它提供標準的兩線接口TWI,即I2C接口,主機工作模式。通過TWI 控制寄存器TWI_CR設置I2C工作模式和狀態(tài)。時鐘由寄存器TWI_CWGR中編程值產(chǎn)生。該寄存器定義了TWCK 信號,使接口適應寬范圍時鐘。 具體在linux中AT91RM9200 I2C總線適配器驅(qū)動的實現(xiàn),首先初始化AT91RM9200 I2C的工作模式,然后裝載I2C總線驅(qū)動,這需要兩個結(jié)構(gòu)模塊來描述:struct i2c_adapter和struct i2c_algorithm。 初始化i2c_adapter結(jié)構(gòu)成員如下: static struct i2c_adapter at91rm9200_adapter = { name: "AT91RM9200", id: I2C_ALGO_SMBUS, algo: &at91_algorithm, algo_data: NULL, inc_use:at91_inc, dec_use:at91_dec, ... ... }; 這個模塊并未提供讀寫函數(shù),具體的讀寫方法由第二個模塊struct i2c_algorithm提供。 static struct i2c_algorithm at91_algorithm = { name: "at91 i2c", id: I2C_ALGO_SMBUS, smbus_xfer: at91_smbus_xfer, master_xfer: at91_xfer, functionality: at91_func, }; 通過調(diào)用I2C core中的接口函數(shù)i2c_add_adapter將這兩個模塊注冊到操作系統(tǒng)里,總線驅(qū)動就算裝上了。由此可見,i2c_algorithm實現(xiàn)了i2c通信具體方法。針對本文at91rm9200 I2C適配器, at91_xfer最為關鍵。分析內(nèi)核可知,I2C core框架中提供給主機使用的數(shù)據(jù)傳輸接口:i2c_master_send,i2c_master_recv,i2c_transfer最終都是通過調(diào)用at91_xfer實現(xiàn)。 數(shù)據(jù)傳輸處理如下:數(shù)據(jù)發(fā)送主機初始化Start狀態(tài)后,向主機模式寄存器TWI_MMR中DADR發(fā)送一個7位從機地址,以通知從機器件。從機地址后的位表示傳輸方向(寫或讀)。該位為0,說明是寫操作(發(fā)送操作);若該位為1,說明為數(shù)據(jù)讀請求( 接收操作)。TWI 傳輸要求從機每收到一個字節(jié)后均要給出應答。在應答時鐘脈沖中,主機釋放數(shù)據(jù)線(HIGH),將從機拉低以產(chǎn)生應答。主機在該時鐘脈沖中輪詢數(shù)據(jù)線,可使用輪詢或中斷方式來檢驗狀態(tài)位。若從機未應答該字節(jié),將置位狀態(tài)寄存器TWI_SR的NAK 位。 寫操作則發(fā)送數(shù)據(jù)至保持寄存器TWI_THR,設置TWI_CR的START 位以啟動傳輸。數(shù)據(jù)在內(nèi)部移位寄存器中移位,當檢測到應答,TXRDY位置位,直到TWI_THR中有新數(shù)據(jù)寫入,才清除該位。主機產(chǎn)生STOP 狀態(tài)來結(jié)束傳輸。設置START 后開始讀序列。當狀態(tài)寄存器中RXRDY 位置位時,接收保持寄存器(TWI_RHR)以收到一個字符。當讀TWI_RHR 時RXRDY 位復位。 TWI接口可執(zhí)行多種傳輸格式:7位從機地址和10位從機地址。通過主機模式寄存器TWI_MMR配置三個內(nèi)部地址字節(jié)。若從機僅支持7 位地址,IADRSZ 必須置為0。若從機地址大于7 位,用戶必須配置地址大小IADRSZ 并在內(nèi)部地址寄存器TWI_IADR中設置其他從機地址位。 4.X1227的設備驅(qū)動實現(xiàn) X1227 是一個帶有時鐘、日歷、CPU 監(jiān)控電路和兩路查詢報警的實時時鐘。時鐘使用一個低成本的32.768kHz 的晶體作為輸入,可精密地用秒、分鐘、小時、日期、星期、月、年來顯示時間,它可以自動調(diào)整閏年至2096年。同時X1227有一個看門狗定時器、3個超時時間可供選擇。另外,X1227有一個4K位的EEPROM陣列,可用作某些用戶配置數(shù)據(jù)的存儲器。下面以X1227為例,說明一個具體的I2C設備驅(qū)動程序的設計要點。 如前所述,I2C總線驅(qū)動只是提供了對一條總線的讀寫機制,本身并不會去做通信。通信是由I2C設備驅(qū)動來做的,設備驅(qū)動透過I2C總線同具體的設備進行通訊。一個設備驅(qū)動有兩個模塊來描述,struct i2c_client和struct i2c_driver。i2c_client用來描述一個具體的I2C設備,i2c_driver結(jié)構(gòu)提供了i2c_adapter與i2c_client之間的通信方式。 struct i2c_driver x1227_driver = { name: 襒1227? id: I2C_DRIVERID_X1227, flags: I2C_DF_NOTIFY, attach_adapter: x1227_probe, detach_client: x1227_detach, command: x1227_command }; 其中:attach_adapter利用適配器驅(qū)動提供的I2C總線訪問方法,利用設備驅(qū)動程序模塊中提供的地址線索信息,檢測可能存在的設備及其地址。如果成功發(fā)現(xiàn)設備,則創(chuàng)建一個struct i2c_client來標識這個設備,并向該適配器的數(shù)據(jù)結(jié)構(gòu)注冊。detach_client用于從總線上注銷設備、并釋放i2c_client及相應的私有數(shù)據(jù)結(jié)構(gòu)。command是用戶接口中的ioctl功能的底層實現(xiàn)。 I2C設備驅(qū)動需要實現(xiàn)兩個方面的接口,一個是對I2C core框架的接口,設備初始化時通過函數(shù)i2c_add_driver調(diào)用,來實現(xiàn)驅(qū)動的注冊。這個i2c_driver一旦裝入完成,其中的attach_adapter函數(shù)就會被調(diào)用。 另一個是對用戶應用層的接口,提供用戶程序訪問I2C設備的接口,包括實現(xiàn)open,release,read,write以及最重要的ioctl等標準文件操作的接口函數(shù)。每個設備驅(qū)動程序都有一個稱為file_operations的數(shù)據(jù)結(jié)構(gòu),用來實現(xiàn)接口函數(shù)。 static struct file_operations rtc_fops = { owner: THIS_MODULE, ioctl: x1227_rtc_ioctl, open: x1227_rtc_open, release: x1227_rtc_release, }; 其中open和release用來打開和關閉X1227,x1227_rtc_ioctl則向用戶提供的一系列控制時鐘芯片的具體命令:RTC_GET_TIME(以固定的數(shù)據(jù)格式讀取實時時鐘的時間)、RTC_SET_TIME(以固定的數(shù)據(jù)格式設定實時時鐘的時間)以及E2PROM讀寫等。 對于X1227,一般注冊為一個miscdevice設備(所有miscdevice設備共同一個主設備號,不同的次設備號)。 static struct miscdevice x1227_rtc_miscdev = { RTC_MINOR, tc? &rtc_fops }; 初始化時,通過misc_register (&x1227_rtc_miscdev)注冊X1227,這樣用戶程序可以通過主設備號10 次設備號 135的設備節(jié)點/dev/rtc來訪問X1227。 要測試X1227的時鐘功能,首先把AT91RM9200的I2C總線驅(qū)動模塊和X1227模塊在系統(tǒng)啟動時先后加載。需要指出的是,Linux將時鐘分為系統(tǒng)時鐘和硬件時鐘兩種。系統(tǒng)時鐘是指當前Linux Kernel中的時鐘,而硬件時鐘則是主板上由電池供電的那個主板硬件時鐘,也就是本文中的X1227。 在Linux中,用于時鐘查看和設置的命令主要有date、hwclock。首先設置系統(tǒng)時鐘,比如設置為2006年8月17日12點30分:date 081712302006,然后設置硬件時鐘為當前系統(tǒng)時鐘時間,使用命令/sbin/hwclock 衧ystohc,則X1227中的時間設置為當前系統(tǒng)時間。然后,通常在操作系統(tǒng)啟動時設置啟動腳本/sbin/hwclock 衕ctosys,利用X1227內(nèi)的時間更新系統(tǒng)時鐘,然后直到重啟或關閉系統(tǒng),由系統(tǒng)時鐘來記錄時間。 5.結(jié)語 本文介紹了I2C總線適配器及I2C設備驅(qū)動的實現(xiàn)。該設計成功用于某網(wǎng)絡測試設備的主控模塊上,實現(xiàn)了設備的實時時鐘功能,便于整個系統(tǒng)的監(jiān)控。I2C總線在目前的嵌入式領域中應用非常廣泛,如音/視頻的控制,存儲設備的通訊等,而Linux也已成為嵌入式系統(tǒng)的主流。從linux內(nèi)核看,I2C的驅(qū)動程序具有清晰的層次結(jié)構(gòu),為編程者開發(fā)I2C相關驅(qū)動提供了規(guī)范的框架。

標簽:

點贊

分享到:

上一篇:DCS/SIS一體化系統(tǒng)中的高級應...

下一篇:微能WIN-V63矢量控制變頻器在...

中國傳動網(wǎng)版權與免責聲明:凡本網(wǎng)注明[來源:中國傳動網(wǎng)]的所有文字、圖片、音視和視頻文件,版權均為中國傳動網(wǎng)(www.treenowplaneincome.com)獨家所有。如需轉(zhuǎn)載請與0755-82949061聯(lián)系。任何媒體、網(wǎng)站或個人轉(zhuǎn)載使用時須注明來源“中國傳動網(wǎng)”,違反者本網(wǎng)將追究其法律責任。

本網(wǎng)轉(zhuǎn)載并注明其他來源的稿件,均來自互聯(lián)網(wǎng)或業(yè)內(nèi)投稿人士,版權屬于原版權人。轉(zhuǎn)載請保留稿件來源及作者,禁止擅自篡改,違者自負版權法律責任。

網(wǎng)站簡介|會員服務|聯(lián)系方式|幫助信息|版權信息|網(wǎng)站地圖|友情鏈接|法律支持|意見反饋|sitemap

中國傳動網(wǎng)-工業(yè)自動化與智能制造的全媒體“互聯(lián)網(wǎng)+”創(chuàng)新服務平臺

網(wǎng)站客服服務咨詢采購咨詢媒體合作

Chuandong.com Copyright ?2005 - 2024 ,All Rights Reserved 版權所有 粵ICP備 14004826號 | 營業(yè)執(zhí)照證書 | 不良信息舉報中心 | 粵公網(wǎng)安備 44030402000946號

<small id="cc39o"></small>
  • <small id="cc39o"><noframes id="cc39o"></noframes></small>