linux spi驅動總體架構
在2.6的linux核心中,spi的驅動架構可以分為如下三個層次:spi 核心層、spi控制器驅動層和spi裝置驅動層。
linux 中spi驅動**位於drivers/spi目錄。
linux spi體系結構圖
本文對驅動框架不做詳細分析(可參見孟浩依然的博文《linux核心spi匯流排驅動分析》),只闡述spi驅動各環節銜接過程,因為我發現在缺乏必要的驅動理論基礎的前提下,對模組分而治之就像瞎子摸象,缺少整體感和流暢性。
linux中spi子系統的初始化是從drivers/spi/spi.c檔案中的spi_init函式開始的,看看它的定義:
初始化過程主要為匯流排分配記憶體資源、完成匯流排註冊,這裡涉及到spi匯流排結構體,定義如下:static int __init spi_init(void)
status = bus_register(&spi_bus_type);
if (status < 0)
goto err1;
status = class_register(&spi_master_class);
if (status < 0)
goto err2;
return 0;
err2:
bus_unregister(&spi_bus_type);
err1:
kfree(buf);
buf = null;
err0:
return status;
}
struct bus_type spi_bus_type = ;
其中包含了最重要的match函式,該函式作用是匹配匯流排裝置與驅動,在spi_driver註冊時,會被用於掃瞄spi匯流排上的裝置,詳見match定義
。補充知識:
device naming and driver binding
platform_device.dev.bus_id是乙個裝置在匯流排上的名字,它包含兩部分:
* platform_device.name 裝置名字,用來進行driver的匹配
* platform_device.id 裝置例項的標號,如果是-1,表示同樣名字的裝置只有乙個
舉個簡單的例子,name/id是「serial/1」則它的bus_id就是serial.1 如果name/id是「serial/0」則它的bus_id就是serial.0 ,如果它的name/id是「serial/-1」則它的bus_id就是serial。
driver的繫結是通過driver core自動完成的,完成driver和device的匹配後以後會自動執行probe()函式,如果函式執行成功,則driver和device就繫結在一起了,drvier和device匹配的方法有3種:
* 當乙個裝置註冊的時候,會在匯流排上尋找匹配的driver,platform device一般在系統啟動很早的時候就註冊了。
* 當乙個驅動註冊[platform_driver_register()]的時候,會遍歷所有匯流排上的裝置來尋找匹配,在啟動的過程驅動的註冊一般比較晚,或者在模組載入的時候
* 當乙個驅動註冊[platform_driver_probe()]的時候, 功能上和使用platform_driver_register()是一樣的,唯一的區別是它不能被以後其他的device probe了,也就是說這個driver只能和乙個device繫結。
spi_device 和spi_master
platform匯流排有platform_device和platform_driver,對於spi匯流排,也有對應的spi_device和spi_driver。
struct spi_device ;
spi_device通常在bsp的板檔案中定義,它的板資訊用spi_board_info結構體描述,該結構體記錄spi外設使用的主機控制器序號、片選序號、資料位元率、spi傳輸模式(即使)等。spi_board_info結構體宣告如下:
struct spi_board_info ;
在系統開機時,在機器初始化函式init_machine()中將通過spi_register_board_info()將spi_board_info註冊到鍊錶board_list上,這一點與啟動時通過
platform_add_devices()函式統一註冊platform_device(歸納為乙個陣列)過程非常相似。
但是必須要強調的是,此時並未建立spi_device或者spi_master。
spi控制器驅動
spi控制器驅動層,每種處理器平台都有自己的控制器驅動,屬於平台移植相關層。它的職責是為系統中每條spi匯流排實現相應的讀寫方法,
乙個控制器驅動用於支援一條特定的spi匯流排的讀寫。
在物理上,每個spi控制器可以連線若干個spi從裝置。
一般在系統開機時,spi控制器驅動被首先裝載。
在spi_device封裝了乙個spi_master結構體,
事實上spi_master的註冊會在spi_register_board_info之後。
struct spi_master ;
另外,一般來說裝置是不能被熱插拔的,所以可以將probe()函式放在spi控制器驅動init段裡面來節省driver執行時候的記憶體開銷:
在s3c6410中,spi控制器驅動在裝置與驅動匹配成功後才建立並註冊的,詳見s3c64xx_spi_probe函式定義。static int __init s3c64xx_spi_init(void)
spi_driver在驅動模組載入時進行初始化並註冊,註冊時會掃瞄匯流排上的裝置,通過匯流排match函式進行裝置與驅動匹配,若成功,則呼叫spi_driver的probe函式,
通過platform_get_resource等函式獲取spi_board_info中定義的資源資訊,
建立並註冊
spi_master,spi_master註冊過程會呼叫scan_boardinfo掃瞄board_list,通過匯流排號(bus_num)找到掛接在它上面的spi裝置,建立並註冊乙個spi_device。
spi外設驅動
spi外設驅動遍布於核心的drivers、sounds各個子目錄之下,spi只是一種匯流排,spi_driver的作用只是將spi外設掛接在該匯流排上,因此在spi_driver的probe函式中,將註冊本身所屬裝置驅動的型別。
Linux裝置驅動 SPI驅動
spi驅動匯流排架構 spi核心層 x spi控制器驅動層 x spi裝置驅動層 spi函式介面 api 簡單介紹spi協議,硬體原理 4412datasheet sdi 資料輸入buf i2c scl6 sdo 資料輸出buf i2c sda6 sclk 時鐘buf gpc1 1 cs 片選bk ...
linux下spi驅動分析
核心版本 linux 2.6.29 主要的幾個結構platform device platform driver s3c24xx spi spi master spi bitbang spi device spi driver spidev data s3c spi info第一步 註冊platfo...
Linux下SPI驅動分析 2
接上乙個繼續看spi.c。名詞解釋of openfirmware 呼叫層次spi match device of driver match device of match device of match node 用於驅動程式檢查platform device是否在其支援列表裡 80static i...