Ren*_*oly 5 usb cocoa driver iokit
我正在努力掌握IOKit,我觉得我很接近,但还没有.请原谅我的困惑.
我设法编写了检测我的USB设备的代码(USB电缆末端的一个简单按钮,它有一个Windows驱动程序,但没有Mac驱动程序).
我按下按钮时试图获得某种回调.
当设备连接到USB或移除时,我设法收到回叫.现在,我试图找出按下按钮时如何获得通知,但我无法弄明白.文档对我来说非常混乱,因为IOKit似乎可以同时使用c ++和c,具体取决于你如何访问它(内核扩展或用户空间驱动程序,或类似的东西.不确定我有正确的术语.
我已经尝试添加一些方法来获取回调,当任何中断值发生变化时,您将在代码中看到.但没有任何反应.
这是我当前的AppDelegate.m文件以及设备上的USB Probe信息.
Low Speed device @ 5 (0x14100000): ............................................. Composite device: "DL100B Dream Cheeky Generic Controller"
Port Information: 0x101a
Number Of Endpoints (includes EP0):
Device Descriptor
Configuration Descriptor (current config)
Length (and contents): 34
Number of Interfaces: 1
Configuration Value: 1
Attributes: 0x80 (bus-powered)
MaxPower: 500 mA
Interface #0 - HID
Alternate Setting 0
Number of Endpoints 1
Interface Class: 3 (HID)
Interface Subclass; 0
Interface Protocol: 0
HID Descriptor
Endpoint 0x81 - Interrupt Input
Address: 0x81 (IN)
Attributes: 0x03 (Interrupt)
Max Packet Size: 8
Polling Interval: 10 ms
Run Code Online (Sandbox Code Playgroud)
App Delegate.m文件:
//
// USBHIDAppDelegate.m
// USBHID
//
// Created by Michael Dolinar on 12-05-02.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "USBHIDAppDelegate.h"
#import "IOKit/hid/IOHIDManager.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
#include <IOKit/usb/USBSpec.h>
@implementation USBHIDAppDelegate
@synthesize window = _window;
// New USB device specified in the matching dictionary has been added (callback function)
static void Handle_DeviceMatchingCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef){
// Retrieve the device name & serial number
NSString *devName = [NSString stringWithUTF8String:
CFStringGetCStringPtr(
IOHIDDeviceGetProperty(inIOHIDDeviceRef,
CFSTR("Product")),
kCFStringEncodingMacRoman)];
UInt32 serialString = CFStringGetCStringPtr(
IOHIDDeviceGetProperty(inIOHIDDeviceRef,
CFSTR("SerialNumber")),
kCFStringEncodingMacRoman);
NSString *devSerialNumber;
if (serialString == 0) {
devSerialNumber = @"No Serial Number";
} else {
devSerialNumber = [NSString stringWithUTF8String:serialString];
}
// Log the device reference, Name, Serial Number & device count
NSLog(@"\nDevice added: %p\nModel: %@\nSerial Number:%@\nDevice count: %ld",
inIOHIDDeviceRef,
devName,
devSerialNumber,
USBDeviceCount(inSender));
//Open the device (Was missing)
IOReturn err = IOHIDDeviceOpen(inIOHIDDeviceRef, 0);
Run Code Online (Sandbox Code Playgroud)
//应该在这里检查错误......
IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, Handle_IOHIDDeviceInputValueCallback, NULL);
Run Code Online (Sandbox Code Playgroud)
//还必须在这里再次注册RunLoop ...还缺少IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef,CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
}
static void Handle_IOHIDDeviceInputValueCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDValueRef inIOHIDValueRef
)
{
NSLog(@"Value changed");
}
// USB device specified in the matching dictionary has been removed (callback function)
static void Handle_DeviceRemovalCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef){
// Log the device ID & device count
NSLog(@"\nDevice removed: %p\nDevice count: %ld",
(void *)inIOHIDDeviceRef,
USBDeviceCount(inSender));
IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, NULL, NULL); //Remove callback
}
// Counts the number of devices in the device set (incudes all USB devices that match our dictionary)
static long USBDeviceCount(IOHIDManagerRef HIDManager){
// The device set includes all USB devices that match our matching dictionary. Fetch it.
CFSetRef devSet = IOHIDManagerCopyDevices(HIDManager);
// The devSet will be NULL if there are 0 devices, so only try to count the devices if devSet exists
if(devSet) return CFSetGetCount(devSet);
// There were no matching devices (devSet was NULL), so return a count of 0
return 0;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
SInt32 idVendor = 0x1D34;//0x062A;//0x1d34; //0x1AAD; //// set vendor id
SInt32 idProduct = 0x000D;//0x0000;//0x000d; //0x000F; //// set product id
// Create an HID Manager
IOHIDManagerRef HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
// Create a Matching Dictionary
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Specify a device manufacturer in the Matching Dictionary
CFDictionarySetValue(matchDict,
CFSTR(kIOHIDVendorIDKey),
CFNumberCreate(kCFAllocatorDefault,
kCFNumberSInt32Type, &idVendor));
CFDictionarySetValue(matchDict,
CFSTR(kIOHIDProductKey),
CFNumberCreate(kCFAllocatorDefault,
kCFNumberSInt32Type, &idProduct));
// Register the Matching Dictionary to the HID Manager
IOHIDManagerSetDeviceMatching(HIDManager, matchDict);
// Register a callback for USB device detection with the HID Manager
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &Handle_DeviceMatchingCallback, NULL);
// Register a callback fro USB device removal with the HID Manager
IOHIDManagerRegisterDeviceRemovalCallback(HIDManager, &Handle_DeviceRemovalCallback, NULL);
// Register the HID Manager on our app’s run loop
IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
// Open the HID Manager
IOReturn IOReturn = IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone);
if(IOReturn) NSLog(@"IOHIDManagerOpen failed."); // Couldn't open the HID manager! TODO: proper error handling
}
@end
Run Code Online (Sandbox Code Playgroud)
我甚至不确定设备是否正在发送任何东西......我尝试在7级中使用USB记录器进行记录,但只按下按钮似乎没有显示任何内容......我怎样才能确保它实际上正在工作?
更新:能够使用这个用于了解BigRedButton的Ruby Open Source项目来检测按钮按下.所以我知道它确实有效.我还重新编写了代码,仅在实际检测到设备时注册值更改,并在删除设备时将其删除.此时仍然没有.
更新2:让这个工作!两个问题......我没有打开设备进行读取,也没有在Current RunLoop上注册设备本身,这也是必需的.来自WWDC 2011的Userland设备访问的WWDC视频非常有用.我还必须说,我使用的BigRedBUtton可能不是一个标准设备,并且从未像计划那样工作,但我想要使用的实际设备就像一个魅力并且给我输入!因为WWDC视频,现在一切都很好!
最后,上面的代码现在可以工作了,因为我已经打开了设备并在当前运行循环上安排了设备。此外,更改设备使我可以使用其他设备,这似乎提供了更可预测的更改其值的体验。我建议任何对此进行研究的人观看 WWDC 2011 的 Userland Device Access 视频,以深入了解其工作原理(视频播放约 30 分钟)
更新:设备反应不同的原因有点复杂。首先,每个 USB HID 设备都可以有多个“配置”,并且可能不会启用默认配置。你必须明确地这样做。然后,第二部分是关于理解从设备发送的值。这是通过理解“HID 设备报告描述符”来完成的,它详细描述了返回的每种值(称为报告)及其位和字节的排列方式。
在 OS X 上,一个很好的读物是适用于 Mac OS X 版本 10.5技术说明的新 HID 管理器 API。虽然它是 10.5 的最新版本,但它是最新版本,包含所有适当的调用,并且可以更好地理解这一切是如何工作的。
此外,要了解描述符,本教程很有帮助。
| 归档时间: |
|
| 查看次数: |
1254 次 |
| 最近记录: |