7

MacOS で IOKit を使用して、仮想シリアル ポートの BSD 名を特定しようとしています。

仮想シリアル ポートのような USB CDC デバイスがあり、fopen("/dev/tty.usbmodem123") を実行できるように BSD デバイス パスを取得したいと考えています。VID と PID を受け取り、デバイスが接続されるのを待つプログラムがあり、BSD 名を使用してデバイスに書き込みたいと考えています。デバイスのマウント方法はシステムごとに異なります。これを教育ツールとして使用しようとしているので、デバイスがマウントされている場所を /dev/tty.* で手動で調べることなく、デバイスに書き込む前にデバイスを検索する必要があります。

3 つの質問があります。

まず、を使用して仮想シリアルポートの BSD 名を取得できCFSTR(kIOBSDNameKey)ますか? 常に「null」を返しますIORegistryEntrySearchCFProperty()FindProp()非ブロックデバイスが BSD 名を返すことができるかどうかは誰にもわかりませんか? 私は現在これをやっています:

bsdName = IORegistryEntrySearchCFProperty(p_usb_ref, kIOServicePlane, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kIORegistryIterateRecursively );

次に、サービス プレーン名を取得できました: IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/OHC1@4/AppleUSBOHCI/Intro to Electronics@4100000 で、これは /dev/tty.usbmodem411 のマウント ポイントに対応します。サービスプレーン名を開発ツリー名に変換する方法を知っている人はいますか?

第三に、これを複雑にしすぎていませんか? デバイスの io ハンドルは既に知っていますが、それを使用してデバイスにデータを書き込む方法はありますか? いくつかの LED を点滅させるために、いくつかの ASCII バイトを送信する必要があるだけです。

アドバイスをいただければ幸いです。

EDIT:

これを見てさらに時間を費やした後、私の問題は、CDC ドライバーがロードされる前に BSD 名を照会していたことにあることがわかりました。現在、BSD 名を取得し、VID と PID を分類しています。

上記の問題を解決したコードは次のとおりです。

matchingDictionary = IOServiceMatching(kIOSerialBSDServiceValue);
CFDictionarySetValue(matchingDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType));
kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter);

iter次に、正しい ID を持つデバイスを見つけるまで繰り返します。

4

2 に答える 2

2

これは、USB シリアル デバイスを追加するときに IONotification で使用するものです。10.11 では空になりました。多くのことを試した後、これが私の解決策でした:

while ((usbDevice = IOIteratorNext(iterator)))
{
  //when hotplugging under OSX 10.11:
  sleep(1);//otherwise the property will be empty.

  CFStringRef deviceBSDName_cf = (CFStringRef) IORegistryEntrySearchCFProperty (usbDevice,
  kIOServicePlane,
  CFSTR (kIOCalloutDeviceKey),
  kCFAllocatorDefault,
  kIORegistryIterateRecursively );

  NSLog(@"device path: %@", deviceBSDName_cf);

}

次のようなものが見つかるはずです: /dev/cu.xxxxx
誰かの役に立てば幸いです。

于 2016-08-30T23:10:36.057 に答える