1. 程式人生 > >i2c_register_board_info沒有EXPORT_SYMBOL_GPL匯出的解決方法

i2c_register_board_info沒有EXPORT_SYMBOL_GPL匯出的解決方法

近期除錯I2C驅動(pca9544,pcf8574,PI3??)遇到不少問題,沒及時記錄,也沒整理,先把剛解決的這個問題記錄下。


1、把I2C介面卡驅動和各裝置驅動的資源資訊在board檔案裡註冊;

2、然後把各驅動新增到kernel中編譯;

3、編譯出的kernel image在板子上跑,各驅動均正常。


但在載入了broadcom交換晶片SDK的ko模組後,發現I2C的各裝置都不能正常訪問了。

跟蹤SDK程式碼發現,在SDK初始化時有個CMIC_CPS_RESET暫存器把整個CMIC相關暫存器都reset了,而I2C介面卡驅動在此之前已經初始化過,reset後導致I2C裝置不能正常訪問。

kernel image(含 I2C drivers) -> SDK -> -> I2C read/write不能操作I2C裝置


於是嘗試將I2C介面卡驅動和各裝置驅動作為模組來編譯:

kernel image -> I2C drivers -> I2C read/write  一切正常

kernel image -> SDK -> I2C drivers -> I2C read/write一切正常


從日後升級維護方面考慮,打算將I2C介面卡驅動和各裝置驅動直接隨核心編譯,把資源資訊從board檔案中拿出來作為模組動態載入。


在board檔案中,資源資訊的註冊用到了platform_add_devices和i2c_register_board_info 兩個函式。在編譯時提示“i2c_register_board_info undefined!”,雖然可以編譯通過,但在insmod使由於找不到i2c_register_board_info ,照樣載入不成功。

查程式碼發現platform_add_devices通過EXPORT_SYMBOL_GPL進行匯出,可供其它模組呼叫,但i2c_register_board_info 沒有匯出,所以提示“i2c_register_board_info undefined!”。


分析i2c_register_board_info 函式發現,在板檔案中註冊的資訊只是放到一個連結串列中,只有在呼叫的驅動的probe函式裡的i2c_add_numbered_adapter時會遍歷此連結串列的裝置資訊新增裝置,這個連結串列可以理解為靜態連結串列,初始化時寫死的,後期不會改動。

既然有靜態新增的方式,那我們就可以動態註冊,方法如下:

先通過platform_add_devices註冊介面卡資訊,與驅動匹配成功後,介面卡註冊完成;

然後通過adap = i2c_get_adapter(0)獲取介面卡;

呼叫i2c_new_device(adap,&board_info)新增其它裝置的資訊;


這樣就完成了I2C裝置的動態新增。