Android 指纹调试流程(高通、MTK均适用)
前言:指紋調(diào)試我們只需要關(guān)注kernel、hal、ta就可以將其點(diǎn)亮,高通使用自己的tee環(huán)境,MTK則需要使用第三方tee OS,三方tee的集成調(diào)試一般會(huì)有廠家配合,主要是調(diào)試spi ta,在此就不做闡述了,下面重點(diǎn)介紹指紋bring up。
一、驅(qū)動(dòng)調(diào)試
驅(qū)動(dòng)調(diào)試分為兩個(gè)方面,dts中配置上電、reset、irq、pinctrl和移植driver代碼調(diào)試驅(qū)動(dòng)節(jié)點(diǎn)。
1.dts配置
一般高通和MTK平臺(tái)代碼中都會(huì)有默認(rèn)集成的一家指紋,只需要copy過來改下gpio,如果有用到pinctrl,也要把pinctrl name改成與驅(qū)動(dòng)中的name 統(tǒng)一。
kernel/msm-4.9/arch/arm64/boot/dts/qcom/(對(duì)應(yīng)自己項(xiàng)目的dts)
fpc1020 {
compatible = "fpc,fpc1020";
interrupt-parent = <&tlmm>;
interrupts = <48 0>;
fpc,gpio_rst = <&tlmm 124 0x0>;
fpc,gpio_irq = <&tlmm 48 0>;
vcc_spi-supply = <&pm8953_l5>;
vdd_io-supply = <&pm8953_l5>;
vdd_ana-supply = <&pm8953_l5>;
pinctrl-names = "fpc1020_reset_reset",
"fpc1020_reset_active",
"fpc1020_irq_active";
pinctrl-0 = <&fpc_reset_low>;
pinctrl-1 = <&fpc_reset_high>;
pinctrl-2 = <&fpc_int_low>;
};
以上dts段,我們移植到新項(xiàng)目需要修改:
(1)compatible:驅(qū)動(dòng)代碼里的device_id與此處的compatible匹配后,才會(huì)走probe函數(shù)。
static const struct of_device_id fpc1020_of_match[] = {
{ .compatible = "fpc,fpc1020", },
{}
};
(2)GPIO:將reset、irq、中斷號(hào)等改成自己項(xiàng)目的。
(3)上電:由于指紋即使滅屏休眠狀態(tài)下也要能夠解鎖亮屏,所以指紋一般要設(shè)置為長供電,例所示為LDO供電,根據(jù)原理圖,確認(rèn)好自己用哪路LDO,如果該路供電非長供電,可以在rpm那邊修改。
(4)pinctrl:如果廠家驅(qū)動(dòng)driver不使用pinctrl操作gpio則不需要配置,如果廠家驅(qū)動(dòng)driver中要求使用pinctrl,找到對(duì)應(yīng)項(xiàng)目的pinctrl.dtsi,如下圖所示.
fpc_reset_int {
fpc_reset_low: reset_low {
mux {
pins = "gpio124";
function = "fpc_reset_gpio_low";
};
config {
pins = "gpio124";
drive-strength = <2>;
bias-disable;
output-low;
};
};
fpc_reset_high: reset_high {
mux {
pins = "gpio124";
function = "fpc_reset_gpio_high";
};
config {
pins = "gpio124";
drive-strength = <2>;
bias-disable;
output-high;
};
};
fpc_int_low: int_low {
mux {
pins = "gpio48";
};
config {
pins = "gpio48";
drive-strength = <2>;
bias-pull-down;
input-enable;
};
};
};
(a)要檢查gpio是否是自己項(xiàng)目的,下屬的label例如fpc_reset_low與dtsi中pinctrl-0 = <&fpc_reset_low>是否匹配。
? (b)檢查項(xiàng)目dts中,pinctrl-names = "fpc1020_reset_reset",
?? ??? ??? ??? ?"fpc1020_reset_active",
?? ??? ??? ??? ?"fpc1020_irq_active";
?與驅(qū)動(dòng)driver probe函數(shù)解析dts時(shí),name是否統(tǒng)一,如不統(tǒng)一很有可能會(huì)死機(jī),需要抓串口分析。
rc = select_pin_ctl(fpc1020, "fpc1020_reset_reset");
rc = select_pin_ctl(fpc1020, "fpc1020_irq_active");
2.驅(qū)動(dòng)driver移植
(1)在kernel/driver/input下,新建fingerprint/fpc文件夾,將廠商提供的驅(qū)動(dòng)代碼放到kernel/driver/input/fingerprint/fpc,同時(shí)編寫Kconfig和Makefile文件。
Kconfig:
menu "FingerprintCard fingerprint driver"
config FINGERPRINT_FPC
default n
tristate "FPC_BTP fingerprint sensor support"
depends on SPI_MASTER
endmenu
Makefile:
obj-$(FINGERPRINT_FPC) += fpc1020.o
(2)Kconfig和Makefile在kernel中是從頂層開始遞歸調(diào)用的,所以還要將新添加的納入上一層目錄的Kconfig和Makefile中,這里就不贅述了,做過驅(qū)動(dòng)的都知道。
(3)在kernel/arch/arm64/configs/ 目錄下找到自己項(xiàng)目對(duì)應(yīng)的deconfig和perf-deconfig,加入
CONFIG_FINGERPRINT_FPC=y? ?注:這里FINGERPRINT_FPC要與(1)中Kconfig和Makefile中保持一致
?
以上完成后,單編boot和dtbo,單獨(dú)刷機(jī)驗(yàn)證,確認(rèn)能否開機(jī),以及設(shè)備節(jié)點(diǎn)是否生成。(此處多數(shù)廠家指紋無法通過串口log打印確認(rèn)dts是否正確被解析,因?yàn)檫@些廠家指紋的dts解析,是由廠家ca發(fā)命令解析的,要等ca集成后再看。)
二、hal層移植
1.so庫
一般廠家是釋放so庫的,極少數(shù)廠家釋放半開源代碼給你,這就需要自己調(diào)試編譯。so一般有fingerprint.default.so和廠家的例如匯頂?shù)膅f_hal、gf_ca、工模相關(guān)so等。
以so庫釋放:將so放置在對(duì)應(yīng)目錄下,在項(xiàng)目的mk文件里將so納入版本編譯,例如:
PRODUCT_COPY_FILES+= vendor/fingerprint/goodix/fingerprint.default.so:vendor/lib64/hw/fingerprint.default.so非so庫釋放:編寫Android.mk即可
so只要編譯出來是可以單獨(dú)push的。
2.hal 服務(wù)
(1)需要檢查下out目錄里是否編譯出android.hardware.biometrics.fingerprint@2.1-service相關(guān)的so和bin文件,一般默認(rèn)是沒有的。沒有的話要將這塊納入編譯,也可以單獨(dú)編譯push。
(2)需要確認(rèn)下在hardware/interfaces/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp? ?openhal函數(shù)中打開的so庫,是否與自己調(diào)試的這家name匹配,FINGERPRINT_HARDWARE_MODULE_ID默認(rèn)是fingerpritn.default.so,如果不一致將FINGERPRINT_HARDWARE_MODULE_ID定義為自己的就行了。
(3)將android.hardware.biometrics.fingerprint@2.1-service.rc 納入編譯,配置該服務(wù)開機(jī)自啟動(dòng)
(4)hidl修改
Android P以及之后需要修改三處:
device/$product/manifest.xml
hardware/interfaces/compatibility_matrices/...
device/qcom/common/vendor_framework_compatibility_matrix.xml
<hal format="hidl" optional="true">
<name>android.hardware.biometrics.fingerprint</name>
<version>2.1</version>
<interface>
<name>IBiometricsFingerprint</name>
<instance>default</instance>
</interface>
</hal>
注:語法不一樣,device/$product/manifest.xml中添加時(shí)是需要去除上述圖中optional="true"的。
三、TA移植
這個(gè)移植過程按照廠商給的文檔一步步移植就可以了,這個(gè)在此就不贅述了,最后編譯出來的ta在調(diào)試階段也可以單獨(dú)push 驗(yàn)證。
四、其他配置
(1)在init rc中修改節(jié)點(diǎn)權(quán)限
chown system system dev/goodix_fp
chmod 0664 /dev/goodix_fp
(2)打開setting中指紋選項(xiàng)
PRODUCT_COPY_FILES := frameworks/native/data/etc/android.hardware.fingerprint.xml:vendor/etc/permissions/android.hardware.fingerprint.xml(3)確認(rèn)spi號(hào),kernel側(cè)檢查dts中端口的配置是否正確,在tz側(cè)修改成指紋要用的spi號(hào)。
五、模組兼容
一般手機(jī)外設(shè)器件為了降低風(fēng)險(xiǎn),模組會(huì)有多供料,一般是不同IC的。如果是同一IC,不同模組的,這個(gè)不需要我們自己做什么工作了,IC廠家otp中會(huì)燒錄自己會(huì)識(shí)別,我們下面重點(diǎn)介紹不同IC的兼容。
方法一:硬件ID兼容
一般硬件會(huì)預(yù)留ID pin,一個(gè)ID pin高低可以兼容兩家,兩個(gè)ID pin可以兼容四家。
1.在lk階段讀取fp_id pin腳value
gpio_get_value(unsigned gpio)//這個(gè)是返回寄存器的值 ,需要換算成二進(jìn)制,再結(jié)合數(shù)據(jù)手冊(cè)看下gpio哪一位是表示高低電平的2.利用cmdline,將value值從lk傳遞至kernel
3.kernel讀取saved_command_line值,創(chuàng)建節(jié)點(diǎn)并寫入值
4.hal中通過讀取節(jié)點(diǎn)值來加載不同廠商的so
方法二:輪詢加載兼容
1.驅(qū)動(dòng)只創(chuàng)建設(shè)備結(jié)點(diǎn),不申請(qǐng)配置GPIO和中斷
2.在BiometricsFingerprint.cpp的openhal函數(shù)中輪詢加載各家fingerprint.default.so
3.在ca中去配置GPIO,由供應(yīng)商在so中完成ID檢測,在沒有檢測到自家指紋模組的時(shí)候返回
六、selinux權(quán)限
上述是在userdebug版本上關(guān)閉selinux權(quán)限調(diào)試的,需要調(diào)試selinux權(quán)限保證打開selinux時(shí),指紋仍可用。
調(diào)試方法:
adb shell getenforce //查看selinux權(quán)限狀態(tài),enforcing打開、permissive關(guān)閉
adb shell setenforce ?0 //關(guān)閉selinux權(quán)限
adb shell setenforce ?1 //打開selniux權(quán)限
adb shell stop //上述關(guān)閉重啟后就會(huì)再次打開,可以在關(guān)閉selinux權(quán)限后執(zhí)行stop start,這樣設(shè)備重啟后,selinux也不會(huì)再次被打開,方便調(diào)試
adb shell start
關(guān)于selinux權(quán)限如何配置,網(wǎng)上資料很多,在此就不贅述了。
七、常見問題
1.死機(jī)
常見原因:
(1)dts配置有問題:一般就是前面介紹的name不匹配造成的,抓取串口log,probr=e函數(shù)解析dts的代碼逐行添加log,確認(rèn)是哪里出錯(cuò)的,修改即可。
(2)tz內(nèi)存:移植ta后需要擴(kuò)大tz內(nèi)存,不然很有可能會(huì)造成死機(jī),每個(gè)平臺(tái)修改的方式不太一樣,這個(gè)可以問平臺(tái)方要文檔,比對(duì)文檔修改即可。
Android P高通平臺(tái)的可以參照:https://blog.csdn.net/dshine_/article/details/85101887
(3)指針異常:找到異常地址處,使用add2line解析出是哪個(gè)文件哪一行的代碼再分析。
2.無法讀取到sensor ID
常見原因:
(1)上電:電壓表測量下供電是否符合廠商datasheet要求
(2)spi不通:檢查下tz側(cè)的端口號(hào)配置是否正確,該spi端口號(hào)是否是tz側(cè)用的。(如果是AP側(cè)則需要修改)
3.ta load 不起來
99%是tz內(nèi)存有問題,如果你堅(jiān)持認(rèn)為你按照平臺(tái)文檔已經(jīng)修改了,那么請(qǐng)你檢查你的修改是否生效了
4.setting里沒有指紋選項(xiàng)
檢查manifest.xml和android.hardware.fingerprint.xml 是否在手機(jī)里,要兩者都配置了才會(huì)出來指紋選項(xiàng)。
八、總結(jié)
指紋調(diào)試過程中,驅(qū)動(dòng)、so、ta、rc這些都是可以單獨(dú)刷機(jī)或者push的,但是內(nèi)存和manifest.xml(有的平臺(tái)能夠單獨(dú)push,在vendor/etc/vintf目錄下,但是有的平臺(tái)push是會(huì)死機(jī)的,所以不建議單獨(dú)push)這個(gè)是需要全編譯生效的,所以在三大件點(diǎn)亮正式開始調(diào)試之前一定要先編個(gè)已經(jīng)配置好這些并且能正常開機(jī)的版本。
另,指紋其他的如果單獨(dú)push很可能會(huì)亂掉,忘記push 哪一個(gè)再回來抓log查看,會(huì)非常費(fèi)時(shí)費(fèi)力,所以建議調(diào)試前編譯第一個(gè)版本的時(shí)候,就先把so 、ta、2.1相關(guān)、rc等等先全部預(yù)置進(jìn)去,后期哪里有問題,再單獨(dú)push替換即可。
總結(jié)
以上是生活随笔為你收集整理的Android 指纹调试流程(高通、MTK均适用)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CAN总线在嵌入式Linux下驱动程序的
- 下一篇: 【Device Tree】设备树(一)—