1. 程式人生 > >[Android6.0][RK3399] PCIe 介面 4G模組 EC20 除錯記錄

[Android6.0][RK3399] PCIe 介面 4G模組 EC20 除錯記錄

Platform: RK3399
OS: Android 6.0
Kernel: 4.4
Version: v2017.04
4G Module: EC20-CE

一、基本概念

1. USB 部分的功能介面

Quectel 3G/4G模組(UMTS/HSPA/LTE)的 USB 部分包括了幾個不同的功能介面。

USB Serial
ttyUSB0 代表 DM
ttyUSB1 代表 GPS NMEA (GPS導航裝置統一的RTCM標準協議)資訊輸出
ttyUSB2 代表 AT commands
ttyUSB3 代表 PPP 連線

GobiNet
在移植了 GobiNet 驅動後,會產生一個網路裝置和一個 QMI channel。
網路裝置叫做 ethX(在核心版本2.6.39前叫做 usbX)QMI channel 叫做 /dev/qcqmiX 的節點。
網路裝置用來進行資料傳輸,QMI 通道用來進行 QMI 資訊互動。
Qualcomm

Gobi is a family of embedded mobile broadband modem products by Qualcomm. Gobi technology was designed to allow for any product with the embedded solution to connect to the internet anywhere a wireless carrier provides data coverage. One of the more notable products that contain a Gobi modem is the iPhone 4 for Verizon, which contains a MDM6600™, however it does not take advantage of the support for HSPA+

QMI WWAN
當移植了 QMI WWAN 驅動後,驅動將會建立網路裝置和 QMI channel,網路裝置被稱作 wwanX,QMI 通道被命名為 /dev/cdc-wdmX。
網路裝置用來進行資料傳輸,QMI 通道用來進行 QMI 資料互動。

CDC ACM
在移植完了 CDC ACM 驅動後,將會在 /dev 下建立如下節點
ttyACM0 用於 PPP聯結器 或者 AT命令
ttyACM1 用於 Trace1
ttyACM2 用於 Trace2
ttyACM3 用於 AT commands
ttyACM4 用於 AT commands

USB 的 CDC 類是 USB 通訊裝置類 (Communication Device Class)的簡稱。
CDC 類 是 USB 組織定義的一類專門給各種通訊裝置(電信通訊裝置和中速網路通訊裝置)使用的 USB 子類。

2. APN

APN 指一種網路接入技術,是通過手機上網時必須配置的一個引數,它決定了手機通過哪種接入方式來訪問網路

二、驅動移植

1. USB Driver

主要參考官方文件《Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.5.pdf》
精簡版的移植手冊可以參考 http://blog.csdn.net/hnjztyx/article/details/72495433 這篇,三星平臺 Android5.1 的,寫的比較清晰。

另外有部分地方需要強調一下。

  1. 如果是 EC20 需要將其 VendorID 和 ProductID 打印出來看一下,因為有的 EC20 是有兩個版本的,分別是 EC20-C 和 EC20-CE。
    EC20-C IDVendor=0x05c6 IDProduct=0x9215
    EC20-CE IDVendor=0x2c7c IDProduct=0x0125
    插拔裝置出現資訊如下:
    [ 723.730113] usb 1-1: New USB device found, idVendor=2c7c, idProduct=0125
    可見我的裝置是 EC20-CE。
    務必確認好自己的物料版本。
  2. 移植的時候最好先控制變數,第一步只移植 USB Serial Driver 部分。完成這部分的移植後 /dev/下就應該生成 ttyUSB0-ttyUSB4 。一次新增的東西多瞭如果出現問題不好定位問題出現的地方。

2. GobiNet Driver 或者 QMI WWAN

GobiNet Driver 和 QMI WWAN 兩者的作用相同,只不過一個是在 Kernel Space 實現,一個是在 Userspace 實現。
對於 GobiNet Driver,需要在 Kernel 中新增 供應商提供的 GobiNet 的原始碼;
對於 QMI WWAN ,預設 Android 6.0 中已經實現了這種方式,我們只需要新增 ID 即可,所以我選擇的後者。
除錯完成後會在 /dev 下生成cdc-wdmX節點。

3. PPP 撥號配置

在驅動部分參考手冊開啟對應的巨集即可。
下面是關於 APN 的配置,在我們完成 RIL 的移植後進行。

APN : Access Point Names 。
ChinaUnicom 聯通 3gnet ,ChinaMobile 移動 cmnet,ChinaTelecom 電信 ctnet。

三、RIL 移植

RIL 在 Android 中的位置如下圖

RIL 在 Android 架構中的位置

可以看到,RIL 在 Android 架構中的位置處於 Kernel 和 Framework 之間。
Libraries 中的 RIL 被分為兩個部分,RILD 和 Vendor RIL。
RILD 負責 Socket 和 Framework 之間的通訊。
Vendor RIL 負責 和 Radio 的通訊(通過 AT command channel 與 Packet data channel(PDCH))。AT command channel 用來直接和 Radio 通訊,PDCH 用以 data service。
Java framework 中的 RIL 也被分為來兩個部分,一部分是 RIL module 另一部分是 Phone module。
The RIL modeule 用來和底層的 RILD 通訊,The Phone module 直接為應用層(Application)提供電話功能的介面。

1. RIL Driver Integration

以 Quectel 的 EC20 為例。
Quectel 以原始碼形式提供了 RIL driver(package/reference-ril)。我們只需要拷貝到我們的 Android 原始碼的正確路徑並編譯即可。

相應 Android 原始碼路徑為:
hardware/ril/reference-ril ,用代理商提供的程式碼替換即可。

並且修改 init.rc

service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so
    class main
    socket rild stream 660 root radio 
    socket rild-debug stream 666 radio system 
    user root 
    group radio cache inet misc audio sdcard_rw log

禁能切換使用者 hardware/ril/rild/rild.c

OpenLib:
    #endif
      //switchUser();

如果需要在 非root 下進行除錯的話,還可以在 common/ueventd.rockchip.rc 中加上:

# for radio
/dev/ttyUSB0              0666   radio      radio
/dev/ttyUSB1              0666   radio      radio
/dev/ttyUSB2              0666   radio      radio
/dev/ttyUSB3              0666   radio      radio

重新編譯即可。

2. 抓取 Android Log

# 只看 RIL module 的 log
adb logcat -b radio -v time

3. RIL 移植問題彙總

1. 程式碼出現大量 error

EC20 的代理程式碼釋放有誤,Android6.0 對應的程式碼是《Quectel_Android_RIL_SR01A41V17》。

2. 出現模組衝突報錯:

build/core/base_rules.mk:157: *** hardware/ril/reference-ril: MODULE.TARGET.EXECUTABLES.chat alread defined by external/ppp/chat。

直接刪除 rk 的 chat 模組即可

rm externel/ppp/chat -rf 

3. RIL 沒有生效(完成了 RIL 部分的移植後,看起來 4G 模組沒有起作用)

1)確認 RIL 程序有沒有執行

# getprop init.svc.ril-daemon
應該得到 Running ,如果得到的是 Stopped 或者 Restarting,則需要重新檢查移植步驟

2)看一下 lib 是否是 Quectel 的

# getprop gsm.version.ril-impl
如果是 Quectel 的應該是
Quectel_Android_RIL_SR 開頭的

如果這裡顯示的是
RIL_RK_DATA_V3.6_android6.0 //說明呼叫到 rk 自己的 ril 庫了,去下一步確定 init.rc 的修改有沒有成功,如果沒成功參照 第4點。
如果這裡顯示的是 空
說明 庫 和平臺不相容,檢查是不是呼叫和自己平臺相容的庫,
比如 32 位是在 system/lib 下,64位 是在 system/lib64 下

3)確認一下 init.rc 中的修改有沒有成功

cat init.rc | grep ril-daemon

沒有成功請參照後面的第4點。

4)確認 SELinux 沒有開啟

# getenforce 來獲取 SELinux 的狀態

# setenforce 0 將其設定為 Permissive

4. init.rc 中的修改沒有生效

在 device/rockchip/rk3399/init.rc 中的修改沒有生效
去 out/…/rk3399_mid/root/init.rc 中看,並沒有產生我們需要的修改

在 rk3399/device.mk 中可以看到

#ifeq ($(strip $(TARGET_BOARD_PLATFORM_PRODUCT)), tablet)
#PRODUCT_COPY_FILES += \
    $(LOCAL_PATH)/rk3399_32/init.rc:root/init.rc
#endif

如果是 tablet 產品,會 copy rk3399_32 中的 init rc 到 mid/init.rc 中。
所以這個地方的邏輯修改為

PRODUCT_COPY_FILES += \
    $(LOCAL_PATH)/init.rc:root/init.rc

另外,在3399 平臺,會在 device.mk 中追加一次 lib 的路徑
./rockchip/common/device.mk:588: rild.libpath=/system/lib64/libril-rk29-dataonly.so
它會將之前我們指定的庫的路徑覆蓋,需要將這一行刪掉。

5. 不修改 init.rc ,修改 system.prop 的方式指定 lib 庫

有些產品,比如 vr、box 會在 system.prop 中指定 rild.libpath 。。所以我們也可以參考 RK 提供的做法來完成 庫 路徑的指定:
比如我是 mid 產品,指定 lib 路徑為 64 bit 的庫路徑:

vi device/rockchip/rk3399/rk3399_mid/system.prop
-- rild.libpath=/system/lib/libril-rk29-dataonly.so
-- rild.libargs=-d /dev/ttyACM0
++ rild.libpath=/system/lib64/libreference-ril.so
++ rild.libargs=-d /dev/ttyUSB0