使用中断输入端点使用IOKit获取回调

 usually111131 发布于 2023-02-10 12:10

我正在努力掌握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

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 
#include 
#include 
#include 

@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);

//应该在这里检查错误......

IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, Handle_IOHIDDeviceInputValueCallback, NULL);

//还必须在这里再次注册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

我甚至不确定设备是否正在发送任何东西......我尝试在7级中使用USB记录器进行记录,但只按下按钮似乎没有显示任何内容......我怎样才能确保它实际上正在工作?

更新:能够使用这个用于了解BigRedButton的Ruby Open Source项目来检测按钮按下.所以我知道它确实有效.我还重新编写了代码,仅在实际检测到设备时注册值更改,并在删除设备时将其删除.此时仍然没有.

更新2:让这个工作!两个问题......我没有打开设备进行读取,也没有在Current RunLoop上注册设备本身,这也是必需的.来自WWDC 2011的Userland设备访问的WWDC视频非常有用.我还必须说,我使用的BigRedBUtton可能不是一个标准设备,并且从未像计划那样工作,但我想要使用的实际设备就像一个魅力并且给我输入!因为WWDC视频,现在一切都很好!

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有