在寫這篇部落格時我先深深的反省了一下!
一直以來我自認為工作嚴謹,我曾鄙視別人把沒有編譯驗證的代碼提交的伺服器上,從而導致伺服器代碼編譯出錯。
我自己多年來一直堅持在push代碼前一定要編譯一次來進行確認。因此從來沒有出現過編譯事故。
就在上周我還向一個朋友抱怨我們公司經常出現伺服器編譯錯誤這樣的問題。似乎顯得我很認真很嚴謹一樣!
我想我是驕傲了吧。。。
我昨天就幹了一件讓我很後悔的事情,ltr558的驅動先前是編譯進核心的,一直工作的很好。因為考慮到這個驅動在probe的過程中初始化部分有600ms的延時,為了加速啟動過程,需要把這個驅動編譯為module後期在用insmod進行載入。
這很簡單,只要在arch/arm/configs/XXXdefconfig 中將對應的CONFIG_INPUT_LTR558_I2C=y 改為 CONFIG_INPUT_LTR558_I2C=m即可。這樣編譯kernel時便會將對應的驅動編譯為ko放到/system/lib/modules/中,然後在相關的init.rc中通過insmod命令載入該ko即可。如此想當然,我便修改了這樣兩處,並檢查了編譯結果,看到確實有相關的ko產生。我認為這肯定沒問題了。所以就沒有下載到手機上進行測試,就直接push了代碼。
今天早上就收到了測試人員的郵件,P&L-sensor失效了!我趕緊將昨天的img燒到手機確認,,,果然掛了。。。
要是我昨天不想當然的話,,也不至於這麼尷尬啊。。。
今天找了一天這個問題。
#if(defined(CONFIG_INPUT_LTR558_I2C))
註冊ltr_558als對應的i2c device
#endif
原來是因為當CONFIG_INPUT_LTR558_I2C=m 後,這個宏判斷的結果就為假,因此這註冊裝置的代碼就不會編譯!
改為下邊即可:
#if(defined(CONFIG_INPUT_LTR558_I2C)||defined(CONFIG_INPUT_LTR558_I2C_MODULE))
註冊ltr_558als對應的i2c device
#endif
當CONFIG_INPUT_LTR558_I2C=m 時,宏CONFIG_INPUT_LTR558_I2C_MODULE會被自動定義!
我沒有找到 宏CONFIG_INPUT_LTR558_I2C_MODULE到底在哪裡被定義了,但是通過實驗方法,我得到了一個結論:
CONFIG_INPUT_LTR558_I2C=y時:defined(CONFIG_INPUT_LTR558_I2C)返回真 defined(CONFIG_INPUT_LTR558_I2C_MODULE)返回假
CONFIG_INPUT_LTR558_I2C=m時:defined(CONFIG_INPUT_LTR558_I2C)返回假 defined(CONFIG_INPUT_LTR558_I2C_MODULE)返回真
順便發現一個android4.1的特性
init: skipping insecure file '/system/lib/modules/ltr_558als.ko'
如果你的ko許可權不對的話,在通過init.rc載入模組時也會報上述出錯資訊!這些ko檔案的許可權應為 0644
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
root cause:
在arch/arm/configs/中將ltr558的編譯方式該為 =m 後,卻忽視了board.c中的相關宏開關,導致ltr558的device未註冊,繼而導致驅動的probe未執行。表現為P&L-sensor失效。