怯肇乾,陳永超
(北京新大陸有限公司,北 京100044)
ARM-Linux操作系統(tǒng)下,SPI總線操作,自上而下分為3個(gè)層次:平臺(tái)依賴層、硬件抽象層和用戶接口層。平臺(tái)依賴層對(duì)應(yīng)微處理器里集成的一個(gè)或多個(gè)SPI主機(jī)控制器,包括平臺(tái)設(shè)備(Platform Device)和平臺(tái)驅(qū)動(dòng)程序,每種處理器平臺(tái)都有自己特定的SPI控制器驅(qū)動(dòng),屬于平臺(tái)移植相關(guān)層,主要是按照核心層定義的接口實(shí)現(xiàn)具體的spi_master。硬件抽象層提供核心數(shù)據(jù)結(jié)構(gòu)的定義、SPI控制器驅(qū)動(dòng)和設(shè)備驅(qū)動(dòng)的注冊(cè)、注銷管理,它面向平臺(tái)依賴層屏蔽實(shí)際總線控制器的差異,定義了統(tǒng)一的訪問(wèn)策略和接口。面向用戶接口層提供統(tǒng)一的接口,以便SPI設(shè)備驅(qū)動(dòng)通過(guò)總線控制器進(jìn)行數(shù)據(jù)收發(fā),其主體框架程序是GPIO模擬SPI時(shí)序spi_bitbang.c和可進(jìn)行同/異步消息傳輸?shù)炔僮鞯膕pi.c。用戶接口層即設(shè)備驅(qū)動(dòng)層,為用戶提供了通過(guò)SPI總線訪問(wèn)具體設(shè)備的接口,包括SPI設(shè)備和SPI驅(qū)動(dòng)程序。ARM-Linux下SPI總線的層次結(jié)構(gòu)圖如圖1所示。
圖1 ARM-Linux下SPI總線的層次結(jié)構(gòu)圖
嵌入式ARM-Linux操作系統(tǒng)對(duì)SPI總線提供完整而成熟的硬件抽象層和通用的SPI驅(qū)動(dòng)spi_driver。針對(duì)具體的ARM內(nèi)核微處理器體系,如Samsung公司基于Cortex-A8的S5PV110/S5PV210、TI公司基于 Cortex-A8的AM3515/AM3715、Freescale公 司 基 于 Cortex-A8 的i.MX515/i.MX535等,半導(dǎo)體廠商通常提供其SPI控制器驅(qū)動(dòng)的platform_driver和對(duì)應(yīng)的platform_device配置,還有通用spi_driver對(duì)應(yīng)的spi_device配置。platform_device配置定義SPI主機(jī)信號(hào)與從機(jī)的片選信號(hào)和中斷信號(hào)。spi_device配置指定具體SPI設(shè)備對(duì)應(yīng)的SPI主機(jī)號(hào)、采用的SPI通信模式與傳輸速度和其使用的中斷等。platform_device和spi_device配置通常定義在平臺(tái)匹配文件 mach_xxx.c,如 mach_smdkc110.c。
所以,在ARM-Linux中添加SPI設(shè)備,可以借用SPI通用驅(qū)動(dòng)快速實(shí)現(xiàn),可以為其編寫特定的SPI驅(qū)動(dòng)。ARM-Linux設(shè)備驅(qū)動(dòng)通常采用靜態(tài)加載操作,它有兩種方式:適配(adapter)和探測(cè)(probe),大多數(shù)設(shè)備驅(qū)動(dòng)越來(lái)越趨向探測(cè)方式,也可以采用動(dòng)態(tài)加載方式編寫簡(jiǎn)易的SPI“設(shè)備-驅(qū)動(dòng)”。SPI時(shí)序可以選擇由微處理器集成的SPI總線控制器產(chǎn)生,也可以選擇由微處理器的通用輸入/輸出口GPIO模擬產(chǎn)生。
對(duì)于一些常規(guī)的SPI設(shè)備,如存儲(chǔ)器、溫度傳感器等,可以將其連接到選定的SPI主機(jī)控制器總線上,借用系統(tǒng)提供的通用spi-dev.c程序直接實(shí)現(xiàn)串行通信操作。需要做的是在平臺(tái)匹配文件mach_xxx.c中添加或修改片選、中斷信號(hào),指定SPI的工作模式、傳輸速度、主機(jī)編號(hào)、中斷編號(hào)等關(guān)鍵信息,相關(guān)的代碼添加與變化如下(其中粗體部分為需要添加或修改的):
probe方式的驅(qū)動(dòng)會(huì)根據(jù)事先的配置安排加載并通過(guò)探測(cè)初始化進(jìn)而啟用硬件設(shè)備。它以xxx_driver框架作統(tǒng)領(lǐng),以xxx_probe函數(shù)完成設(shè)備的探測(cè)與初始化,以xxx_remove函數(shù)完成設(shè)備的去除。相應(yīng)的設(shè)備操作配置靠mach_xxx.c文件指定。這里以SPI接口的4線電阻式觸摸屏控制器驅(qū)動(dòng)設(shè)計(jì)為例加以說(shuō)明。該設(shè)備既是SPI設(shè)備,也是輸入設(shè)備。
mach_xxx.c中需要增加的SPI設(shè)備信息如下:
設(shè)備驅(qū)動(dòng)程序,通過(guò)硬件中斷以消息傳遞形式異步完成數(shù)據(jù)采集并形成公共信息廣播給上層應(yīng)用系統(tǒng)。由于中斷中不能展開(kāi)SPI通信進(jìn)程,這里采用了異步傳輸和“自旋鎖”機(jī)制,由回調(diào)函數(shù)完成數(shù)據(jù)處理和上傳。限于篇幅,沒(méi)有考慮“去抖”濾波。主要代碼略——編者注。
動(dòng)態(tài)加載形式的設(shè)備驅(qū)動(dòng)便于調(diào)試、用時(shí)掛載,不用隨時(shí)缷載,因而廣泛采用。特別稱之為簡(jiǎn)易“設(shè)備-驅(qū)動(dòng)”型設(shè)備驅(qū)動(dòng)。上述觸摸屏驅(qū)動(dòng)程序很容易變成這種形式,不同之處在于需要在初始化時(shí)完成xxx_probe函數(shù)功能和mach_xxx.c中SPI設(shè)備的配置,在缷載時(shí)完成xxx_remove函數(shù)功能。主要程序代碼略——編者注。
選擇GPIO端口模擬SPI總線驅(qū)動(dòng)SPI設(shè)備,雖然對(duì)于系統(tǒng)整體效率不高,但是直截了當(dāng),易于操作實(shí)現(xiàn)??梢圆捎肁RM-Linux已有的GPIO模擬程序,也可以選擇GPIO自行獨(dú)立設(shè)計(jì)。這里仍以上述觸摸屏為例,自選GPIO模擬SPI時(shí)序,對(duì)動(dòng)態(tài)加載形式的字符型SPI輸入的簡(jiǎn)易“設(shè)備-驅(qū)動(dòng)”設(shè)計(jì)加以說(shuō)明。通過(guò)系統(tǒng)定時(shí)器進(jìn)行了去抖,并對(duì)測(cè)量結(jié)果剪切和均值濾波進(jìn)行處理(主要程序代碼略——編者注)。
編者注:本文為期刊縮略版,全文見(jiàn)本刊網(wǎng)站www.mesnet.com.cn。
[1]怯肇乾.基于底層硬體的軟件設(shè)計(jì)[M].北京:航空航天大學(xué)出版社,2008.
[2]宋寶華.Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解[M].北京:人民郵電出版社,2008.
[3]劉紅波.Linux下 SPI驅(qū)動(dòng)開(kāi)發(fā)[EB/OL].[2011-12].http://www.linuxidc.com/Linux/2011-09/41981p2.html.
[4]CSDN博客.PowerPC+Linux2.6.25平臺(tái)下的SPI驅(qū)動(dòng)架構(gòu)分析[EB/OL].[2011-12].http://blog.csdn.net/sailor_8318/article/details/5977733.
[5]博客園.移植 ADS7846驅(qū)動(dòng)到 Tiny6410[EB/OL].[2011-12].http://www.cnblogs.com/liu_xf/archive/2011/06/22/2086750.html.
[6]王選民,李明利,張利川,等.基于ADS7846的電阻式觸摸屏接口設(shè)計(jì)[J].現(xiàn)代電子技術(shù),2010(11).