Próbuję uzyskać zrozumienie dla IOKit i czuję, że jestem blisko, ale jeszcze nie. Więc przepraszam za zamieszanie.Uzyskaj oddzwonienie za pomocą IOKit za pomocą punktu przerwania Input Endpoint
Udało mi się napisać kod, który wykrywa moje urządzenie USB (prosty przycisk na końcu kabla USB z sterownikiem Windows, ale bez sterownika Mac).
Próbuję uzyskać jakieś wywołanie zwrotne po naciśnięciu przycisku.
Udało mi się uzyskać wywołanie zwrotne, gdy urządzenie jest podłączone do USB lub usunięte. Teraz próbuję dowiedzieć się, jak uzyskać informacje, gdy przycisk jest wciśnięty, ale nie mogę tego rozgryźć. Dokumentacja jest dla mnie bardzo kłopotliwa, ponieważ wydaje mi się, że IOKit jest dostępny zarówno w języku C++, jak i c, w zależności od tego, w jaki sposób uzyskuje się do niego dostęp (rozszerzenie jądra lub sterownik przestrzeni użytkownika, lub coś podobnego.) Nie jestem pewien, czy mam właściwą terminologię:
Próbowałem dodać kilka metod, aby uzyskać wywołanie zwrotne, gdy jakakolwiek wartość przerwania zmieni się, jak widać w kodzie, ale nic się nie dzieje
Oto mój obecny plik AppDelegate.m, a także informacje o sondzie USB na . urządzenie
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
plik 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);
// powinien sprawdzić błędu tutaj ...
IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, Handle_IOHIDDeviceInputValueCallback, NULL);
// Musi również rejestrować RunLoop znowu tutaj ... również brakuje 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
Nie jestem nawet pewien, urządzenie wysyła niczego ... Staram zalogowaniu Korzystanie Logger USB, na poziomie 7, ale tylko naciśnięcie przycisku wydaje się nie wyświetla niczego ... jak mogę upewnić się, że faktycznie działa?
AKTUALIZACJA: Był w stanie wykryć naciśnięcia przycisków za pomocą this Ruby Open Source project dla BigRedButton, którego używam, aby się tego nauczyć. Więc wiem, że to działa. Przebudowałem również mój kod, aby rejestrować zmiany wartości tylko wtedy, gdy urządzenie zostanie wykryte i usunięte po usunięciu urządzenia. Wciąż nic w tym momencie.
AKTUALIZACJA 2: Gotowe! Dwa problemy ... Nie otwierałem urządzenia do czytania, a także nie rejestrowałem samego urządzenia w bieżącej RunLoop, która jest również wymagana. Świetny film WWDC na temat dostępu do urządzenia Userland z WWDC 2011 znacznie pomógł. Muszę też powiedzieć, że BigRedBUtton, którego używałem, nie jest całkiem standardowym urządzeniem i nigdy nie działało jak zaplanowane, ale rzeczywiste urządzenie, z którym chciałem pracować, działa jak urok i daje mi dane wejściowe! Teraz wszystko jest dobrze, dzięki filmom z WWDC!
Używam tego samego fragmentu kodu, który masz tutaj z samouczka Michaela Dolinarsa. Czy mógłbyś opublikować lub może wysłać mi fragment kodu, w którym otwierasz urządzenie (nie tylko menedżera HID), a następnie dodać go do pętli uruchamiania? To jest miejsce, w którym ja sam obecnie utknąłem. –
Właściwie to podrapałem się, że widzę, co się stało, twoje bloki kodu zostały zerwane, a niektóre jego części wyglądały po prostu jak tekst. –