歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux裡SPI與I2C創建設備的流程

Linux裡SPI與I2C創建設備的流程

日期:2017/3/1 10:08:04   编辑:Linux編程

Soc裡怎麼知道設備的存在? 我高中的時候就曾想過,Windows怎麼知道我電腦上有什麼硬件呢?後來剛接觸驅動這一塊時,被Soc上設備的創建困惑了好一陣子。當然現在看起來已經清晰不少了。Linux下的SPI與I2C算是輕量級框架了,是去熟悉Linux驅動模型一個不錯的切入點。當初在學校盡去關心操作系統的實現而無視驅動開發這一塊,後來找工作時才發現,滿大街招的都是搞驅動的。於是轉回去熟悉Linux的設備驅動模型。實習的時候接觸了第一個子系統是I2C,當初強行看了四五天,愣是看出一點名堂。可惜後面沒有從事相關方面的項目,也沒有及時總結,後來都忘的差不多了。

歪題了。因為簡歷上寫了SPI與I2C的內容,今天大致浏覽了一下兩個子系統的代碼。比較在意的是SPI設備與I2C設備的創建。Soc中,SPI控制器與I2C控制器是由platform_device與platform_driver帶入系統中來的。其對應的probe與兩個子系統交互,從而告知系統自身的存在。如果系統中有四個相同型號的控制器,那麼就有4個platform_device和1個platform_driver。注冊到子系統這一過程,最主要是把自己加到子系統維護的控制器列表裡。SPI裡是spi_register_master,I2C裡是i2c_register_adapter。然而,這兩個函數裡還有一個任務:把掛在控制器(總線)上的設備帶到系統中來。

這樣做其實相當無奈。像PCI,USB這類協議,設備都是即時產生的,你把設備插上去,系統就能知道它的存在。而Soc上沒有這麼動態,系統上有什麼設備必需在平台相關的代碼寫出來。這件事就在注冊控制器的時候做。spi_register_master的最後會遍歷一個叫board_list的鏈表,平台相關文件會把平台上有的SPI設備一相相關信息掛在上面。其中最重要的是bus number。spi_master一個屬性就是bus number,這是私下約定的控制器的標識。於是,每新加一個spi_master,就去這個鏈表上找相符的“設備原型”,並將其實例化,也就是從設備原型提供的信息來構建spi_device。設備就是在這裡出現!然後將設備注冊進Linux設備驅動模型裡,後面與驅動的匹配就是標准的那一套了。但是這些過程都被拆散了,一口氣調用了幾個函數。

每個spi_device生成的時候都於其所處的spi_master綁定了。也就是說spi_master與spi_device融為一體,得到spi_device的引用就可以用spi_master裡的方法進行數據傳輸了。有spi_register_master而沒有spi_register_device,至於後者對應的方法--spi_register_driver--基本上不需做什麼事,設備已被加入標准設備驅動模型裡,驅動也只需加入其中即可。

I2C框架看起來要更高級一些。SPI經歷的那些它都經歷了:i2c_register_adapter裡將i2c_adapter加入控制器列表(直接加在了i2c_bus上),遍歷一些預定義的設備原型鏈表,bus number匹配則用i2c_new_device生成設備,i2c_device與i2c_adapter的綁定,將i2c_device注冊到標准設備驅動模型。I2C高級的地方在於,它有一定的動態性。它用一個很簡單的機制來決定i2c_adapter需不需要靜態掃描預定義的鏈表。如果不掃描列表,怎麼知道新加入的i2c_adapterr上有哪些設備呢?由i2c_driver去發現!也就是說,每次加入一個i2c_adapter就會挨個讓已注冊的i2c_adapter在它上面肆虐一把,找找有沒有自己支持的設備。其中有一部分2.4裡面的老模型流程還留著,一些老流程的公共代碼抽出來了,一個新模型的i2c_driver->detect方法來做更精確的設備探測。找到設備便生成i2c_device,並將其注入標准設備驅動模型。

這裡有個與SPI不同的假定。SPI裡生成設備的機會只有一次,就是在添加spi_master時掃描預定義設備模型鏈表。以後似乎就沒有機會加入設備了。而I2C裡生成設備的時機卻更靈活:除了添加i2c_adapter時掃描預定義設備模型鏈表,添加i2c_adpater或i2c_driver時都有可能觸發新設備的建立。這像標准設備驅動模型裡device與driver的匹配,所有可能的匹配都不會落下。當然,I2C的工作量更大了,不僅新加i2c_adapter時要去遍歷驅動,新加i2c_driver時也要去遍歷i2c_adapter。這個工作自然是在i2c_register_driver裡做。這個遍歷又比較蹊跷,spi_master有一個單獨的鏈表連起來(雖然好像沒有人會去遍歷它),i2c_adapter卻掛在i2c_bus上--i2c_adapter和i2c_device都擠在i2c_bus的device鏈表上。

整體看起來,SPI框架還處於I2C框架的早期水平。不過不能在初始化以外的地方添加SPI設備有點不爽,不能在模塊動態創建,這意味著調試SPI設備驅動時每次都得從編內核,重新燒錄,重新啟動。以前就確實有過這樣的經歷,當時似乎改了讓系統可以動態添加SPI設備,現在是一點也記不得了。內核的I2C框架其實已經有點小復雜了,不過它文檔挺好的。以前浏覽了一遍,有些東西不好一次看懂,也就沒有深究,以後有機會再去文檔裡找找關於設計方面的內容吧。

Copyright © Linux教程網 All Rights Reserved