Tôi đang cố gắng nắm bắt IOKit và tôi cảm thấy mình thân thiết, nhưng chưa có. Vì vậy, xin lỗi sự nhầm lẫn của tôi.Nhận gọi lại bằng cách sử dụng IOKit bằng cách sử dụng Điểm ngắt Đầu vào Ngắt
Tôi đã quản lý để viết mã phát hiện thiết bị USB của tôi (một Nút đơn giản ở đầu cáp USB có Trình điều khiển Windows, nhưng không có trình điều khiển Mac).
Tôi đang cố gắng nhận một số loại gọi lại khi nhấn nút.
Tôi quản lý để nhận cuộc gọi lại khi thiết bị được kết nối với USB hoặc bị xóa. Bây giờ, tôi đang cố gắng tìm hiểu làm thế nào để có được thông báo khi nút được nhấn, nhưng tôi không thể tìm ra nó. Tài liệu này rất khó hiểu với tôi, vì IOKit dường như có sẵn cả C++ và c tùy thuộc vào cách bạn truy cập nó (Trình mở rộng Kernel hoặc trình điều khiển không gian người dùng hoặc một cái gì đó tương tự. Tôi đã thử thêm một vài phương pháp để có được một cuộc gọi lại khi bất kỳ thay đổi giá trị gián đoạn như bạn sẽ thấy trong mã.Nhưng không có gì xảy ra. . thiết bị
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
File 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);
// nên kiểm tra xem có lỗi ở đây ...
IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, Handle_IOHIDDeviceInputValueCallback, NULL);
// Cũng phải đăng ký runloop lại đây ... cũng đã mất tích 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
Tôi thậm chí không chắc chắn rằng thiết bị đang gửi bất cứ điều gì ... Tôi cố gắng đăng nhập Sử dụng USB Logger, ở Level 7, nhưng chỉ nhấn nút dường như không hiển thị bất cứ điều gì ... làm thế nào tôi có thể đảm bảo nó thực sự hoạt động?
CẬP NHẬT: Đã có thể phát hiện các lần nhấn nút bằng cách sử dụng this Ruby Open Source project cho BigRedButton mà tôi đang sử dụng để tìm hiểu điều này. Vì vậy, tôi biết nó thực sự hoạt động. Tôi cũng đã làm lại mã của mình để đăng ký thay đổi giá trị chỉ khi thiết bị thực sự được phát hiện và xóa nó khi thiết bị bị xóa. Vẫn không có gì vào thời điểm này.
CẬP NHẬT 2: Có tính năng này để hoạt động! Hai vấn đề ... Tôi đã không mở thiết bị để đọc, và cũng không đăng ký thiết bị trên RunLoop hiện tại cũng được yêu cầu. Một video WWDC tuyệt vời về truy cập thiết bị Userland từ WWDC 2011 đã giúp ích rất nhiều. Tôi cũng phải nói rằng BigRedBUtton mà tôi đang sử dụng có lẽ không phải là một thiết bị tiêu chuẩn và không bao giờ làm việc như kế hoạch, nhưng thiết bị thực sự tôi muốn làm việc với các tác phẩm như một sự quyến rũ và cho tôi đầu vào! Vì vậy, nó là tất cả tốt bây giờ, nhờ vào các video WWDC!
Tôi thực sự đang sử dụng cùng một đoạn mã mà bạn có ở đây từ hướng dẫn của Michael Dolinars. Bạn có thể gửi hoặc có lẽ gửi cho tôi đoạn mã mà bạn mở thiết bị (không chỉ là trình quản lý HID) và sau đó thêm nó vào vòng lặp chạy? Đây là nơi bản thân tôi hiện đang bị mắc kẹt ngay bây giờ. –
Trên thực tế, tôi thấy những gì đã xảy ra, các khối mã của bạn đã bị phá vỡ và một số phần của nó trông giống như văn bản. –