一、Mac机器人和HID的USB单片机设备通讯

如何通过xcode编程使MAC机器和HID的USB单片机设备进行通讯

头文件

#import <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h>

@protocol UsbHIDDelegate <NSObject>
@optional
- (void)usbhidDidRecvData:(uint8_t*)recvData length:(CFIndex)reportLength;
- (void)usbhidDidMatch;
- (void)usbhidDidRemove;
@end

@interface UsbHID : NSObject {
    IOHIDManagerRef managerRef;
    IOHIDDeviceRef deviceRef;
}

@property(nonatomic,strong)id<UsbHIDDelegate> delegate;

+ (UsbHID *)sharedManager;
- (void)connectHID;
- (void)senddata:(char*)outbuffer;
- (IOHIDManagerRef)getManageRef;
- (void)setManageRef:(IOHIDManagerRef)ref;
- (IOHIDDeviceRef)getDeviceRef;
- (void)setDeviceRef:(IOHIDDeviceRef)ref;

@end
类文件

#import "UsbHID.h"

@implementation UsbHID

static UsbHID *_sharedManager = nil;

@synthesize delegate;

static void MyInputCallback(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength) {
    [[[UsbHID sharedManager] delegate] usbhidDidRecvData:report length:reportLength];
}

static void Handle_DeviceMatchingCallback(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {
    [[UsbHID sharedManager] setDeviceRef:inIOHIDDeviceRef];
    char *inputbuffer = malloc(64);
    IOHIDDeviceRegisterInputReportCallback([[UsbHID sharedManager]getDeviceRef], (uint8_t*)inputbuffer, 64, MyInputCallback, NULL);
    NSLog(@"%p设备插入,现在usb设备数量:%ld",(void *)inIOHIDDeviceRef,USBDeviceCount(inSender));
    [[[UsbHID sharedManager] delegate] usbhidDidMatch];
}

static void Handle_DeviceRemovalCallback(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {
    [[UsbHID sharedManager] setDeviceRef:nil];
    NSLog(@"%p设备拔出,现在usb设备数量:%ld",(void *)inIOHIDDeviceRef,USBDeviceCount(inSender));
    [[[UsbHID sharedManager] delegate] usbhidDidRemove];
}

static long USBDeviceCount(IOHIDManagerRef HIDManager){
    CFSetRef devSet = IOHIDManagerCopyDevices(HIDManager);
    if(devSet)
        return CFSetGetCount(devSet);
    return 0;
}

+(UsbHID *)sharedManager {
    @synchronized( [UsbHID class] ){
        if(!_sharedManager)
            _sharedManager = [[self alloc] init];
        return _sharedManager;
    }
    return nil;
}

+(id)alloc {
    @synchronized ([UsbHID class]){
        NSAssert(_sharedManager == nil,
                 @"Attempted to allocated a second instance");
        _sharedManager = [super alloc];
        return _sharedManager;
    }
    return nil;
}

- (id)init {
    self = [super init];
    if (self) {
        managerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
        IOHIDManagerScheduleWithRunLoop(managerRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
        IOReturn ret = IOHIDManagerOpen(managerRef, 0L);
        if (ret != kIOReturnSuccess) {
            NSAlert* alert = [NSAlert alertWithMessageText:@"error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"打开设备失败!"];
            [alert runModal];
            return self;
        }
        const long vendorID = 0x1391;
        const long productID = 0x2111;
        NSMutableDictionary* dict= [NSMutableDictionary dictionary];
        [dict setValue:[NSNumber numberWithLong:productID] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]];
        [dict setValue:[NSNumber numberWithLong:vendorID] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]];
        IOHIDManagerSetDeviceMatching(managerRef, (__bridge CFMutableDictionaryRef)dict);

        IOHIDManagerRegisterDeviceMatchingCallback(managerRef, &Handle_DeviceMatchingCallback, NULL);
        IOHIDManagerRegisterDeviceRemovalCallback(managerRef, &Handle_DeviceRemovalCallback, NULL);

        NSSet* allDevices = (__bridge NSSet*)(IOHIDManagerCopyDevices(managerRef));
        NSArray* deviceRefs = [allDevices allObjects];
        if (deviceRefs.count==0) {

        }
    }
    return self;
}

- (void)dealloc {
    IOReturn ret = IOHIDDeviceClose(deviceRef, 0L);
    if (ret == kIOReturnSuccess) {
        deviceRef = nil;
    }
    ret = IOHIDManagerClose(managerRef, 0L);
    if (ret == kIOReturnSuccess) {
        managerRef = nil;
    }
}

- (void)connectHID {
    NSSet* allDevices = (__bridge NSSet*)(IOHIDManagerCopyDevices(managerRef));
    NSArray* deviceRefs = [allDevices allObjects];
    deviceRef = (deviceRefs.count)?(__bridge IOHIDDeviceRef)[deviceRefs objectAtIndex:0]:nil;
}

- (void)senddata:(char*)outbuffer {
    if (!deviceRef) {
        return ;
    }
    IOReturn ret = IOHIDDeviceSetReport(deviceRef, kIOHIDReportTypeOutput, 0, (uint8_t*)outbuffer, sizeof(outbuffer));
    if (ret != kIOReturnSuccess) {
        NSAlert* alert = [NSAlert alertWithMessageText:@"error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"发送数据失败!"];
        [alert runModal];
    }
}

- (IOHIDManagerRef)getManageRef {
    return managerRef;
}

- (void)setManageRef:(IOHIDManagerRef)ref {
    managerRef = ref;
}

- (IOHIDDeviceRef)getDeviceRef {
    return deviceRef;
}

- (void)setDeviceRef:(IOHIDDeviceRef)ref {
    deviceRef = ref;
}
@end

猜你喜欢

转载自blog.csdn.net/xp_zyl/article/details/79866977