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裝置的動態新增。