7

我正在尝试在 MacOS 下使用 IOKit 确定虚拟串口的 BSD 名称。

我有一个看起来像虚拟串行端口的 USB CDC 设备,我想获取 BSD 设备路径,以便我可以执行 fopen("/dev/tty.usbmodem123")。我有一个程序,它获取 VID 和 PID 并等待设备插入,然后我想使用 BSD 名称写入设备。该设备在每个系统上的安装方式都不同,我正在尝试将其用作教学工具,因此我需要在写入之前搜索设备,而无需手动检查 /dev/tty.* 以了解设备的安装位置。

我有 3 个问题。

首先,可以使用 获取虚拟串行端口的 BSD 名称CFSTR(kIOBSDNameKey)吗? IORegistryEntrySearchCFProperty()FindProp()始终返回“null”。有谁知道非块设备是否可以返回 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 句柄,有没有办法使用它将数据写入设备?我只需要发送一些 ASCII 字节来闪烁一些 LED。

任何建议将不胜感激。

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 回答
0

也许在 OS X 10.10 中情况发生了变化?您的最后一个代码段似乎/dev/tty.usbmodem00054741在我的系统上找不到该设备:

io_iterator_t devlisthndl = 0;
CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOSerialBSDServiceValue);
CFIndex dict_count = CFDictionaryGetCount(matchingDictionary);
CFDictionarySetValue(matchingDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType));
kern_return_t kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &devlisthndl);

(lldb) p matchingDictionary
(CFMutableDictionaryRef) $3 = 0x0000610000267780 @"0 entries"

您最终是如何获得挂载点字符串的?

于 2015-06-05T23:27:58.627 回答