使用IOKit获取USB设备的BSD名称以写入设备?

时间:2013-02-12 20:32:19

标签: macos core-foundation iokit

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

我有一个看起来像虚拟串口的USB CDC设备,我想得到BSD设备路径,这样我就可以做一个fopen(“/ dev / tty.usbmodem123”)。我有一个程序,它接受VID和PID并等待插入设备,然后我想使用BSD名称写入设备。设备在每个系统上的安装方式不同,我试图将其用作教学工具,因此我需要在写入设备之前先搜索设备,而无需手动检查/dev/tty.*设备的安装位置。

我有3个问题。

首先,可以使用CFSTR(kIOBSDNameKey)获取虚拟串口的BSD名称吗? IORegistryEntrySearchCFProperty()FindProp()始终返回“null”。有谁知道非块设备是否可以返回BSD名称? 我目前正在这样做:

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

其次,我已经能够获得服务平面名称: IOService:/ AppleACPIPlatformExpert / PCI0 @ 0 / AppleACPIPCI / OHC1 @ 4 / AppleUSBOHCI /电子简介@ 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的设备。

2 个答案:

答案 0 :(得分: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
希望它可以帮到某人。

答案 1 :(得分: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"

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