2022年1月31日月曜日

【Android USB oscilloscope】(7) USB COM ICに適するdriverを選ぶ

余っているAndroidスマホをオシロにしよう!

オシロとは直接の関係はないけど、Android StudioとJAVAの勉強のため、usb-serial-for-androidを読んでUSB COMのドライバがどんな動作しているのかを調べているところです.

しかしながら、言語能力がCとC++で停まっているひら的にはどうにもJAVAのsourceってのは判りにくい.次の1~5をイメージさせ得る言語仕様になってないようで不安感がつのります.
1)memoryへの展開状況が見えない
2)関数の引数でobjectを受け取るとき、ポインタ渡しか、現物コピーかわからない
3)classのリストってのは、classのポインタを並べているのか、object現物を並べているのかわからない (Arrayの種類に依るらしいが...)
4)newしたobjectのmemory上の生存期間ってどうなってるんだろう(GCの挙動...)
5)なんでmalloc()を見かけないんだろう? 大丈夫なの?

JAVAに熟達すればmemory展開を察知できるものなのか、それともmemory展開を見ようとするのが無理筋なのか、それはまだわたしには不明です.

それと、JAVAの小技がチクチクと在り、幻惑されっぱなしだよ.
  static method              →staticはnewせんでも使える
  method chaining          →関数().関数()みたく連結してもよい
  getMethod()                →関数ポインタを取得するもの
  default constructor       →constructorを記述しなくてもよい
  <? extends >               →引数に派生クラスを許容する

ーーーー
前回、Android OSがUSB COMの接続に気づいたらonNewIntent()がcallされるんだよね、てなところまでは会得しました.今回はその先の動作です.多種類あるUSB COM ICに適するdriverを選ぶ辺りです.

以下で使ったAndroid Studioのproject folder詰め合わせをupしておきます.kotlinです.
今回からはusb-serial-for-androidのドライバをimportして使っています.

わたしがスマホにOTG接続しているarduinoには、CH340というUSB COM ICが載っています.CH340は、VID=1a86H、PID=7523Hです.このVID/PIDはUSBの国際機関が発行したIC固有のナンバーです.このVID/PIDを材料にして、CH340用のdriverを選ぶのが以下で説明する事柄です.

「多種類あるUSB COM ICに適するdriverを選ぶ」のはonNewIntent()の中でやります.この2行です.
1)manager = getSystemService(Context.USB_SERVICE) as UsbManager
2)availableDrivers: List<UsbSerialDriver> =
                UsbSerialProber.getDefaultProber().findAllDrivers(manager)
1行目はAndroid OSの機能ですから、black-boxとしてスルーします.

2行目はusb-serial-for-androidが実装しているUSB COMドライバの機能です.2行目の仕組みを以下で見てゆきます.

2行目左辺の型はUsbSerialDriverクラスのリストです.リストに入るのはUsbSerialDriverクラスを継承したこの5つのいずれかです.
  CdcAcmSerialDriver     CDCのIC
  Ch34xSerialDriver        CH340とか
  Cp21xxSerialDriver      SilabsのIC
  FtdiSerialDriver           おなじみFTDIのIC
  ProlificSerialDriver       ProlificのIC
画面上でいうとこれらの.javaファイルです.codeを見ると最もhardware寄りの制御をしているっぽい.
今わたしが使っているArduinoにはCH340が載っているので、左辺のリストの中身はCh34xSerialDriverが期待値です.スマホのUSBコネクタは1つだけなので左辺がリストである意味はほとんど無いですね.

次に2行目右辺の仕組みについて.
UsbSerialProberクラスの仕事は、managerから抽出したVID/PIDをkeyとし、5つのドライバのいずれかをセレクトすることです.

最初にVID/PID vs driverのtableを作らなくちゃいけません.tableをJAVAではMapと呼びます.getDefaultProber()がMap作り関数です.
keyとしてVID/PIDが、valueとして5つのドライバのいずれか を格納したMapです.例えばこんな形式です.
    {key,value} = { {0x1a86,0x7523}, Ch34xSerialDriver }
素材は、UsbId.javaにこんな風に記載されています.
    public static final int VENDOR_QINHENG = 0x1a86;    ←VID
    public static final int QINHENG_CH340 = 0x7523;       ←PID
    public static final int QINHENG_CH341A = 0x5523;     ←PID
このMapの実装が非常にめんどくさいので説明する気が失せましたのでスルーします.

めんどくさい点をひとつだけ書くと、getMethod("")という機能を使ってます.getMethodはメンバ関数のポインタを「関数名文字列」指定で取り出すというなんとも原初的な仕組みです.なんでこんな紛らわしいやり方をせにゃいかんのかというとたぶんJAVAにはポインタが無いからだと思います.

Mapが出来たらあとは簡単です.findAllDrivers()でVID/PIDのkeyサーチしてドライバを得ます.

という流れで「2行目」の説明は終了です.

ーーーー
2行目に関連するobjectの中身を覗いてみます.
 ①UsbManagerに何個のエントリがあるのか?    →1個
 ②そのエントリのkey    →/dev/bus/isb/001/002
 ③そのエントリのvalue      →USBのパラメータがたくさんある
 ④VID    →1A86H
 ⑤PID    →7523
 ⑥選ばれたdriver     →Ch34xSerialDriverが選ばれた

今宵はここまでにしとうございます.

6へ          8へ

かしこ

0 件のコメント:

コメントを投稿