Start返回0xE00002C7如果我的驱动程序继承IOUserUSBSerial



我正在开发一个单端口usb串行适配器的DriverKit驱动程序。我有一个简单的驱动程序代码如下:

class MyDriver: public IOUserUSBSerial
{
public:
virtual bool init() override;
virtual kern_return_t Start(IOService *provider) override;
virtual kern_return_t Stop(IOService *provider) override;
virtual void free() override;
};
bool
MyDriver::init()
{
Log("Entered %s", __FUNCTION__);
return super::init();
}
void
MyDriver::free()
{
Log("Entered %s", __FUNCTION__);
super::free();
}
kern_return_t
IMPL(MyDriver, Start)
{
kern_return_t ret;
Log("Entered %s", __FUNCTION__);

ret = Start(provider, SUPERDISPATCH);

if( ret!=kIOReturnSuccess ){
Log("Start returns Error: 0x%Xn", ret);
return ret;
}

ret = RegisterService();
if( ret!=kIOReturnSuccess ){
Log("IOReturn Error: 0x%X @ %d, %sn", ret, __LINE__, __FUNCTION__);
return ret;
}
Log("Hello MyDriver is started...");
return ret;
}
kern_return_t
IMPL(MyDriver, Stop)
{
kern_return_t ret = kIOReturnSuccess;

Log("Entered %s", __FUNCTION__);

ret = Stop(provider, SUPERDISPATCH);
if( ret!=kIOReturnSuccess ){
Log("IOReturn Error: 0x%X @ %d, %sn", ret, __LINE__, __FUNCTION__);
}
return ret;
}
<key>IOKitPersonalities</key>
<dict>
<key>MyDriver</key>
<dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleIdentifierKernel</key>
<string>com.apple.driver.driverkit.serial</string>
<key>IOClass</key>
<string>IOUserSerial</string>
<key>IOMatchCategory</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOProviderClass</key>
<string>IOUSBHostDevice</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
<key>IOUserClass</key>
<string>MyDriver</string>
<key>IOUserServerName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>idVendor</key>
<integer>1234</integer>
<key>idProduct</key>
<integer>5678</integer>
<key>IOTTYBaseName</key>
<string>USB</string>
<key>IOTTYSuffix</key>
<string>4</string>
</dict>
</dict>

我的USB设备被系统检测到,init和Start被成功调用。然而,当我调用Start(provider, SUPERDISPATCH)时,它返回错误代码0xE00002C7(kIOReturnUnsupported)。

我已经提到了这个线程。如果我改变继承IOUserSerial类,调用Start返回成功。我猜问题是由CFBundleIdentifierKernel引起的,但我找不到任何有关的信息。

有没有专家能告诉我为什么Start返回错误?

我可以忽略对super::Start的呼叫吗?

如果我想开发一些特定的功能,我可以使用IOUserSerial子类吗?

我试着在网上阅读所有的文章,感到很沮丧。IOUserUSBSerial示例代码也无法在线获取。

免责声明:我还没有使用IOUserUSBSerial自己,但我有多年的经验与其他部分的DriverKit和IOKit和内核在那之前。在苹果的文档中,即使没有明确说明,你也必须从字里行间理解它所暗示的内容。

IOUserUSBSerial主要问题:

总之,我怀疑问题是这样的:

您有一个非类兼容(非acm)设备,您想为其开发一个驱动程序,使其充当macOS的串行端口。然而,我相信IOUserUSBSerial是专门用于在ACM设备上实现供应商特定行为的。

我从短语"这个类自动管理与设备的串行通信"中推断出这一点。IOUserUSBSerial如何知道如何"自动管理串行通信"?如果你的设备实现了自定义协议?它肯定是在实现ACM USB协议。

因此,您的设备是USB这一事实与选择IOUserUSBSerialIOUserSerial无关,实际上重要的是它是否是ACM兼容的设备。我同意你的观点,如果你的设备是基于USB的,但不遵循ACM,那么解决方案似乎是使用较低级别的IOUserSerial

对子问题的进一步评论和回答:

<key>IOMatchCategory</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>

在匹配真实硬件时不要使用IOMatchCategory。(除非在非常罕见的情况下,您希望多个驱动程序连接到同一个节点。)

可以忽略呼叫super::Start

一般:绝对不。

我猜问题是由CFBundleIdentifierKernel引起的,但我找不到任何有关的信息。

IOUserUSBSerial有点奇怪,因为它似乎完全在框架中实现,在DriverKit运行时内。与大多数DriverKit类不同,它没有内核类支持。因此,com.apple.driver.driverkit.serial实际上似乎是正确的CFBundleIdentifierKernel,而IOUserSerial似乎是正确的IOClass,这是不寻常的。

最新更新