linux匯流排驅動
1. linux驅動程序有幾種載入方式以及它們之間的區別
linux關於匯流排、設備、驅動的注冊順序
設備掛接到匯流排上時,與匯流排上的所有驅動進行匹配(用bus_type.match進行匹配),
如果匹配成功,則調用bus_type.probe或者driver.probe初始化該設備,掛接到匯流排上
如果匹配失敗,則只是將該設備掛接到匯流排上。
驅動掛接到匯流排上時,與匯流排上的所有設備進行匹配(用bus_type.match進行匹配),
如果匹配成功,則調用bus_type.probe或者driver.probe初始化該設備;掛接到匯流排上
如果匹配失敗,則只是將該驅動掛接到匯流排上。
需要重點關注的是匯流排的匹配函數match(),驅動的初始化函數probe()
1.
platform_bus_type--匯流排先被kenrel注冊。
2.
系統初始化過程中調用platform_add_devices或者platform_device_register,將平台設備(platform
devices)注冊到平台匯流排中(platform_bus_type)
3.
平台驅動(platform
driver)與平台設備(platform
device)的關聯是在platform_driver_register或者driver_register中實現,一般這個函數在驅動的初始化過程調用。
通過這三步,就將平台匯流排,設備,驅動關聯起來。
1.
platform
bus先被kenrel注冊。
------------------------------------------------------
do_basic_setup()
-->-driver_init()
-->-platform_bus_init()-->bus_register()
2.
系統初始化過程中調用platform_add_devices或者platform_device_register,將平台設備(platform
devices)注冊到平台匯流排中(platform_bus_type)
------------------------------------------------------
系統啟動階段,匯流排的驅動鏈表還是空的,所以啟動階段的platform_add_devices()只負責將設備添加到匯流排的設備鏈表上。
2. 在linux上怎樣增加一個i2c設備
假設手上有一塊從淘寶上買來的開發板,我要在開發板的I2C匯流排上增加一個從設備(如at24c08),那麼我要怎樣寫這個「I2C設備驅動」,讓
應用程序可以訪問at24c08呢?
先來看一個最簡單的i2c設備驅動:
static struct i2c_board_info at24cxx_info = { //所支持的i2c設備的列表
I2C_BOARD_INFO("at24c08", 0x50), //一項代表一個支持的設備,它的名字叫做「at24c08」,器件地址是0x50
};
static struct i2c_client *at24cxx_client;
static int at24cxx_dev_init(void)
{
struct i2c_adapter *i2c_adap; //分配一個適配器的指針
i2c_adap = i2c_get_adapter(0); //調用core層的函數,獲得一個i2c匯流排。這里我們已經知道新增的器件掛接在編號為0的i2c匯流排上
at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info); // 把i2c適配器和新增的I2C器件關聯起來,這個用了i2c匯流排0,地址是0x50。這就組成了一個客戶端
at24cxx_client i2c_put_adapter(i2c_adap);
return 0;
}
static void at24cxx_dev_exit(void)
{
i2c_unregister_device(at24cxx_client);
}
mole_init(at24cxx_dev_init);
mole_exit(at24cxx_dev_exit);
從上面的程序可以看到,寫一個i2c設備驅動程序,與寫普通的字元驅動基本一樣。特別之處是它調用了i2c的core層的函數,以獲得對i2c匯流排的控制。因為用的是開發板,板上的與soc晶元(一般來說就是arm的晶元)i2c匯流排驅動一般都做好了,直接調用core層的函數就可以控制soc的i2c模塊了。也就是說,寫i2c設備驅動不需要關注arm內部的i2c模塊的寄存器,我們需要關注的是設備(at24c08)的寄存器以及它的datasheet對時序的要求。
其實,添加i2c設備的方法很靈活。根據Linux的官方文檔《linux-3.4.2\Documentation\i2c\instantiating-devices》,添加i2c設備的方法總結有4種:
1. i2c_register_board_info:根據匯流排編號、設備名字(「at24c08」)、設備地址(0x50)注冊一個字元驅動。這種方法最簡單、最粗暴,最貼近平時在開片機上開發i2c器件的。
2. i2c_new_device:根據i2c匯流排的編號,聲明一個i2c設備:這種方法就是上面例子用的方法。這種方法也簡單,但是需要事先知道器件掛接在哪條匯流排上。對於設備,還實現知道了設備地址0x50,匯流排適配器也支持名字為「at24c08」的設備
3. i2c_new_probed_device:
4.從用戶空間實例化一個器件:這個方法相當智能快速,如下輸入指令,即可增加一個i2c設備,同時增加了對應的設備文件。
# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
根據英文文檔的標題,添加i2c設備有稱之為「i2c設備的實例化」。
從上述可以知道,在實例化一個i2c設備之前,除了有對應的驅動支持匯流排外(這里是匯流排0),還需要有一個驅動使用了匯流排0發送時序,支持名字為"at24c08"的器件。這個驅動用匯流排驅動的函數,配置了at24c08的寄存器。
3. linux中的網卡驅動函數probe的具體作用。
probe在設備驅動被注冊到內核中的時候,被匯流排型驅動調用。
匯流排驅動類似於用輪訓方法探測匯流排上的所有設備,將設備的識別型信息和關鍵數據結構 (pci ids, usb ids, i2c ids and etc.)傳遞給probe函數,probe就會識別是否是自己負責驅動的設備,並負責完成該設備的初始化操作。
4. linux 下platform設備和驅動注冊的先後順序
Linux關於匯流排、設備、驅動的注冊順序
設備掛接到匯流排上時,與匯流排上的所有驅動進行匹配(用bus_type.match進行匹配),
如果匹配成功,則調用bus_type.probe或者driver.probe初始化該設備,掛接到匯流排上
如果匹配失敗,則只是將該設備掛接到匯流排上。
驅動掛接到匯流排上時,與匯流排上的所有設備進行匹配(用bus_type.match進行匹配),
如果匹配成功,則調用bus_type.probe或者driver.probe初始化該設備;掛接到匯流排上
如果匹配失敗,則只是將該驅動掛接到匯流排上。
需要重點關注的是匯流排的匹配函數match(),驅動的初始化函數probe()
1. platform_bus_type--匯流排先被kenrel注冊。
2. 系統初始化過程中調用platform_add_devices或者platform_device_register,將平台設備(platform devices)注冊到平台匯流排中(platform_bus_type)
3. 平台驅動(platform driver)與平台設備(platform device)的關聯是在platform_driver_register或者driver_register中實現,一般這個函數在驅動的初始化過程調用。
通過這三步,就將平台匯流排,設備,驅動關聯起來。
1. platform bus先被kenrel注冊。
------------------------------------------------------
do_basic_setup() -->-driver_init() -->-platform_bus_init()-->bus_register()
2. 系統初始化過程中調用platform_add_devices或者platform_device_register,將平台設備(platform devices)注冊到平台匯流排中(platform_bus_type)
------------------------------------------------------
系統啟動階段,匯流排的驅動鏈表還是空的,所以啟動階段的platform_add_devices()只負責將設備添加到匯流排的設備鏈表上。
5. linux內核中i2c匯流排驅動對所有的i2c設備是否是通用的
i2C匯流排的驅動程序一般針對不同的CPU是不一樣的,所以都位於arch目錄下對應的cpu架構的common文件夾下。
對同一種架構的來看,I2C驅動僅實現底層的通信。故其是通用的。
6. linux驅動開發設備樹和匯流排之間的關系
在 Linux 系統中,設備樹(Device Tree)是一種數據結構,它用於描述硬體結構,幫助內核在啟動時確定硬體設備的位置和如何使用它們。在設備樹中,節點表示硬體設備,而邊表示設備之間的關系。
匯流排(Bus)是用於在計算機系統中傳輸數據的通道。它通常是一組連接設備的線路,並允許設備之間交塵掘換數據。在 Linux 中,匯流排也在設備樹中表示為節點,並且設備節點與匯流排節點之派培核間存在邊。
因此,在 Linux 系統中,設備樹用於描述硬體結構,其中包含設備和匯流排,以及它們之間的關系。在驅動程序開發中,開發人員通常使用設備樹來確定特定設備的位置中頌和如何與其通信。