2013-12-15 14 views
5

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!

+0

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ờ. –

+0

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. –

Trả lời

4

Cuối cùng, mã ở trên hoạt động ngay bây giờ mà tôi đã Mở thiết bị và lên lịch thiết bị trên vòng chạy hiện tại. Ngoài ra, việc thay đổi thiết bị cho phép tôi làm việc với một thiết bị khác có vẻ như mang đến trải nghiệm có thể đoán trước nhiều hơn thay đổi giá trị của thiết bị. Tôi khuyên mọi người nên xem video này để xem video Truy cập thiết bị của người dùng từ WWDC 2011 để hiểu rõ cách thức hoạt động (khoảng 30 phút vào video)

CẬP NHẬT: Lý do tại sao các thiết bị phản ứng khác nhau là một chút phức tạp. Đầu tiên, mỗi thiết bị USB HID có thể có nhiều "Cấu hình" và một thiết bị mặc định có thể không được bật. Bạn phải làm điều này một cách rõ ràng.Sau đó, phần thứ hai là tất cả về sự hiểu biết các giá trị được gửi từ thiết bị. Điều này được thực hiện bằng cách hiểu "Trình mô tả báo cáo thiết bị HID" mô tả chi tiết từng loại giá trị được trả về (được gọi là báo cáo) và cách sắp xếp các bit và byte của nó.

Trên OS X, đây là bài đọc tuyệt vời cho bài viết này là New HID Manager APIs for Mac OS X version 10.5 TechNote. Mặc dù nó có giá trị là 10.5, đây là phiên bản mới nhất của phiên bản này và chứa tất cả các cuộc gọi thích hợp và giúp hiểu rõ hơn về cách hoạt động của tất cả.

Ngoài ra, để tìm hiểu về Trình mô tả, this tutorial là hữu ích.

Các vấn đề liên quan