Ich versuche, IOKit zu verstehen, und ich fühle, dass ich nah dran bin, aber noch nicht da. Entschuldige meine Verwirrung.Rückruf mit IOKit über einen Interrupt-Eingabe-Endpunkt
Ich habe es geschafft, Code zu schreiben, der mein USB-Gerät erkennt (eine einfache Taste am Ende eines USB-Kabels, das einen Windows-Treiber, aber keinen Mac-Treiber hat).
Ich versuche, eine Art Rückruf zu erhalten, wenn die Taste gedrückt wird.
Ich bekomme einen Rückruf, wenn das Gerät an USB angeschlossen oder entfernt ist. Jetzt versuche ich herauszufinden, wie man informiert wird, wenn der Knopf gedrückt wird, aber ich kann es nicht herausfinden. Die Dokumentation ist sehr verwirrend für mich, da IOKit scheint sowohl eine C++ und c je nachdem, wie Sie darauf zugreifen (Kernel Extension oder User-Space-Treiber oder etwas ähnliches. Nicht sicher, ich habe die richtige Terminologie.
Ich habe versucht, ein paar Methoden hinzufügen, um einen Rückruf zu erhalten, wenn ein Interrupt-Wert ändert, wie Sie in den Code sehen. Aber nichts passiert.
Hier ist meine aktuelle AppDelegate.m-Datei sowie die USB-Sonde Informationen auf der . Vorrichtung
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
Die App Delegate.m Datei:
//
// 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);
// Sollte für Fehler überprüfen hier ...
IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, Handle_IOHIDDeviceInputValueCallback, NULL);
// Muss auch hier wieder für Runloop registrieren ... auch IOHIDDeviceScheduleWithRunLoop (inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes) fehlte;
}
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
Ich bin nicht einmal sicher, dass das Gerät etwas sendet ... Ich versuche Protokollierung USB Logger verwenden, in Stufe 7, aber nur die Taste drücken scheint nichts anzuzeigen ... wie kann ich stellen Sie sicher, dass es tatsächlich funktioniert?
UPDATE: Ich konnte Tasten drücken, die this Ruby Open Source project für den BigRedButton verwenden, den ich benutze, um das zu lernen. Ich weiß, dass es funktioniert. Ich habe auch meinen Code überarbeitet, um Wertänderungen nur dann zu registrieren, wenn das Gerät tatsächlich erkannt wird, und es zu entfernen, wenn das Gerät entfernt wird. Immer noch nichts an diesem Punkt.
UPDATE 2: Das funktioniert! Zwei Probleme ... Ich habe das Gerät nicht zum Lesen geöffnet und auch nicht das Gerät selbst auf dem aktuellen RunLoop registriert, das auch benötigt wird. Ein großartiges WWDC Video auf Userland Gerätezugriff von WWDC 2011 hat sehr geholfen. Ich muss auch sagen, dass die BigRedBUtton, die ich benutzt habe, vielleicht kein Standardgerät ist und das nie wie geplant funktioniert hat, aber das eigentliche Gerät, mit dem ich arbeiten wollte, funktioniert wie ein Zauber und gibt mir Input! Es ist also alles gut, dank der WWDC-Videos!
Ich benutze tatsächlich den gleichen Stück Code, den Sie hier von Michael Dolinars Tutorial haben. Könnten Sie mir den Code-Teil, in dem Sie das Gerät öffnen (nicht nur den HID-Manager), senden oder mir vielleicht schicken und ihn dann zur Run-Schleife hinzufügen? Dies ist, wo ich derzeit gerade bin. –
Eigentlich scratchen, dass ich sehe, was passiert ist, Ihre Codeblöcke wurden aufgebrochen und einige Teile sahen einfach wie Text aus. –