1 はじめに
今年の 3 月に RK3568 ドライバーが発送されましたが、その時は時間の問題により、AP6275S Bluetooth ドライバーは正常にデバッグできませんでした。次に、デバイス ツリーの構成を注意深く確認します。
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;
uart_rts_gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart8m0_rtsn>;
pinctrl-1 = <&uart8_gpios>;
BT,reset_gpio = <&gpio4 RK_PB7 GPIO_ACTIVE_HIGH>;
BT,wake_gpio = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
BT,wake_host_irq = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
status = "okay";
};
AP6275S は外部クロックを使用しており、RK3568 プログラムが動作した後、hciconfig は Bluetooth デバイスを認識できません。dmesg によって開始されたプロセスを検出すると、Bluetooth 部分に関する問題は見つかりませんでした。
firefly@firefly:~$
firefly@firefly:~$ dmesg | grep BT
[ 1.649733] [BT_RFKILL]: Enter rfkill_rk_init
[ 1.651127] [BT_RFKILL]: bluetooth_platdata_parse_dt: get property: uart_rts_gpios = 73.
[ 1.651169] [BT_RFKILL]: bluetooth_platdata_parse_dt: get property: BT,reset_gpio = 143.
[ 1.651186] [BT_RFKILL]: bluetooth_platdata_parse_dt: get property: BT,wake_gpio = 142.
[ 1.651202] [BT_RFKILL]: bluetooth_platdata_parse_dt: get property: BT,wake_host_irq = 135.
[ 1.651273] [BT_RFKILL]: Request irq for bt wakeup host
[ 1.651367] [BT_RFKILL]: ** disable irq
[ 1.651500] [BT_RFKILL]: bt_default device registered.
[ 7.877390] [BT_RFKILL]: rfkill_rk_set_power: set bt wake_host high!
[ 7.930246] [BT_RFKILL]: ENABLE UART_RTS
[ 8.036706] [BT_RFKILL]: DISABLE UART_RTS
[ 8.036757] [BT_RFKILL]: bt turn on power
[ 8.036787] [BT_RFKILL]: Request irq for bt wakeup host
[ 8.036829] [BT_RFKILL]: ** disable irq
firefly@firefly:~$
その後、ハードウェアの回路図と開発ボードの回路図を比較したところ、AP6275S の Bluetooth シリアル ポートの RTS と CTS が接続されていないことが判明したため、ハードウェアのフライング ワイヤ接続を修正し、Bluetoothまだ出てきませんでした。
2. 転送
Bluetooth がデバッグされていないこの期間、私はプロジェクト管理の雑事 (コードを書くことはありません) で忙しく、いつも昼寝をしているときにこの疑問を考えていました。なぜ Bluetooth が機能しないのですか? Bluetooth はシリアルを使用します。通信用のポート、およびシリアル ポートがデバイス ツリー内にあります。設定はなく、Bluetooth ドライバーを表示するときにシリアル ポート関連の操作はなく、シリアル ポートの RTS、CTS レベルの制御のみが行われます。この疑問がずっと頭の中に残っているのですが、なぜでしょうか?
記事を書いている最後の週までに、ある記事を見て問題を解決する新しい方法を見つけました: AP6275S 移植の概要
brcm_patchram_plus -d --enable_hci --no2bytes --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/BCM4362A2.hcd /dev/ttyS4 があります。このコマンドは、 Bluetoothモジュール。すぐに自分のデバイスで試してみたところ、デバイスには brcm_patchram_plus コマンドはなく、brcm_patchram_plus1 コマンドがあることがわかりました。次に、brcm_patchram_plus1 を使用してテストします。実際の接続はシリアル ポート 8 であるため、コマンドを 1 回変更し、Bluetooth デバイスを出てくる。問題の原因は、このコマンドのエクスポートが実行されていないことにあるようです。
すぐに開発されたファイル システム ps -ef | grep brcm をチェックしたところ、このスレッドが動作していることがわかりました。
firefly@firefly:~$ ps -ef | grep brcm
root 673 1 0 17:44 ? 00:00:00 /usr/bin/brcm_patchram_plus1 --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/BCM4362A2.hcd /dev/ttyS8
firefly 1506 1329 0 18:25 pts/0 00:00:00 grep --color=auto brcm
firefly@firefly:~$
3. 起動時に Bluetooth を自動的に開始します
問題を見つけた後、なぜ自分で作成したボードのシステムが Bluetooth ファームウェアをダウンロードする機能を自動的に実行できないのかを解決する必要があります。
システムの起動とデバッグに関する関連知識を手動で学習すると、次のコマンドを使用してスレッドが開始される場所を見つけることができると結論付けられます。brcm_patchram_plus1 プログラムは init プロセスによって開始されますが、どこから開始されるのでしょうか?
pstree -a コマンドを使用してプロセス ツリーを取得します。systemd プログラムによって開始された brcm_patchram_plus
systemctl statusを利用して、システムサービス関連のプログラムであるsystemdプログラムを見つけているようです。bt-attach.service サービスが開始されていることがわかりました。
/etc/systemd/system$ で bt-attach.service の場所を見つけます。
サービスの内容を確認すると、起動するプログラムが /usr/bin/bt-attach であることがわかります。問題はここにあるはずです。
firefly@firefly:/usr/bin$ cat bt-attach
#!/usr/bin/env bash
model_name=$(tr -d '\0' </sys/firmware/devicetree/base/model | tr 'a-z' 'A-Z')
while read line
do
chip_name=$(echo ${line} | cut -d ' ' -f 1)
if [[ ${model_name} == *3588* ]]; then
uart=$(basename /sys/firmware/devicetree/base/pinctrl/wireless-bluetooth/uart*-gpios | tr -cd "[0-9]")
uart="/dev/ttyS${uart}"
break
elif [[ ${model_name} == *${chip_name}* ]]; then
uart=$(echo ${line} | cut -d ' ' -f 2)
break
fi
done < /usr/bin/bt_uart.cfg
bt_type=$(rk_wifi_gettype)
rtk_attach() {
ret=`ps -ef |grep rtk_hciattach |grep -v "grep" |wc -l`
if [ ${ret} = 1 ]; then
killall rtk_hciattach
sleep 1
fi
/usr/bin/rtk_hciattach -n -s 115200 ${uart} rtk_h5 1500000 noflow &
}
if [[ ${bt_type} = "RTL"* ]]; then
rtk_attach
exit 0
else
killall brcm_patchram_plus1
#uart="/dev/ttyS8"
fwname=$(/usr/bin/bt_fwname ${uart})
echo "zsm $fwname"
if [[ ${fwname} = "bcm43438a1.hcd" ]]; then
ln -sf /vendor/etc/firmware/nvram_ap6212a.txt /vendor/etc/firmware/nvram.txt
elif [[ ${fwname} = "BCM4345C0.hcd" ]]; then
ln -sf /vendor/etc/firmware/nvram_ap6255.txt /vendor/etc/firmware/nvram.txt
fi
start-stop-daemon --start --oknodo --pidfile /var/run/hciattach.pid --background --startas \
/usr/bin/brcm_patchram_plus1 -- --enable_hci --no2bytes --use_baudrate_for_download \
--tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/${fwname} ${uart}
fi
exit 0
このスクリプトを注意深く分析すると、ファイル /sys/firmware/devicetree/base/model が読み取られます。このファイルの内容はデバイス ツリーから取得されます。スクリプトはここから CPU モデルを読み取り、次に bt_uart.cfg から Bluetooth シリアル ポート番号設定を読み取ります。問題は、デバイス ツリーのモデルを変更し、CPU モデルを書き込んでいなかったことですが、CPU モデル RK3568 を追加した後、スクリプト プログラムはシリアル ポート番号を正常に読み取り、Bluetooth モジュール AP6275S を起動できるようになりました。