Linux 与Golang中的USB设备交互

Linux 与Golang中的USB设备交互,linux,go,usb,hardware,Linux,Go,Usb,Hardware,我正在尝试在Linux下与golang的USB设备()通信 到目前为止,我的情况如下: 我的电脑看到了硬件:我在我的/dev/bus/usb 硬件工作正常:他们提供的演示软件工作正常(在windows下,他们没有Linux版本) 看来我可以打开端点了 看来我可以给这个设备写东西了 现在,当我尝试从硬件读取数据时,我总是得到一个超时。我是一个完全的硬件初学者,任何帮助都将不胜感激,也许这个问题实际上是非常基本的 我非常简单的代码库如下: package main import ( "fm

我正在尝试在Linux下与golang的USB设备()通信

到目前为止,我的情况如下:

  • 我的电脑看到了硬件:我在我的
    /dev/bus/usb

  • 硬件工作正常:他们提供的演示软件工作正常(在windows下,他们没有Linux版本)

  • 看来我可以打开端点了

  • 看来我可以给这个设备写东西了

  • 现在,当我尝试从硬件读取数据时,我总是得到一个超时。我是一个完全的硬件初学者,任何帮助都将不胜感激,也许这个问题实际上是非常基本的

    我非常简单的代码库如下:

    package main
    
    import (
        "fmt"
        "log"
        "strconv"
    
        "github.com/jpoirier/gousb/usb"
    )
    
    func main() {
        // Only one context should be needed for an application.  It should always be closed.
        ctx := usb.NewContext()
        defer func() {
            errCl := ctx.Close()
            if errCl != nil {
                log.Fatal(errCl)
            }
        }()
    
        ctx.Debug(1)
    
        // ListDevices is used to find the devices to open.
        devs, err := ctx.ListDevices(
            func(desc *usb.Descriptor) bool {
                if desc.Vendor == GetCottonwoodVendor() && desc.Product == GetCottonwoodProduct() {
                    return true
                }
                return false
            })
    
        // All Devices returned from ListDevices must be closed.
        defer func() {
            for _, dev := range devs {
                errCl := dev.Close()
                if errCl != nil {
                    log.Fatal(errCl)
                }
            }
        }()
    
        // ListDevices can occasionally  fail, so be sure to check its return value.
        if err != nil {
            log.Fatalf("list: %s", err)
        }
    
    for _, dev := range devs {
        // Once the device has been selected from ListDevices, it is opened
        // and can be interacted with.
        // Open up two ep for read and write
    
        epBulkWrite, err := dev.OpenEndpoint(1, 0, 0, 2|uint8(usb.ENDPOINT_DIR_OUT))
        if err != nil {
            log.Fatalf("OpenEndpoint Write error for %v: %v", dev.Address, err)
        }
    
        // Poll Firmware/Hardware Version ID
    
        // AntennaOn
        // outAntennaPowerOnCmd := []byte{0x18, 0x03, 0xFF}
        outFirmIdCmd := []byte{0x10, 0x03, 0x00}
        // outHardIdCmd := []byte{0x10, 0x03, 0x01}
    
        i, err := epBulkWrite.Write(outFirmIdCmd)
        if err != nil {
            log.Fatalf("Cannot write command: %v\n", err)
        }
        log.Printf("%v bytes sent", i)
    
        time.Sleep(1 * time.Second)
    
        epBulkRead, err := dev.OpenEndpoint(1, 0, 0, 1|uint8(usb.ENDPOINT_DIR_IN))
        if err != nil {
            log.Fatalf("OpenEndpoint Read error for %v: %v", dev.Address, err)
        }
    
        readBuffer := make([]byte, 64)
        n, errRead := epBulkRead.Read(readBuffer)
        log.Printf("read %d bytes: %v", n, readBuffer)
        if errRead != nil {
            log.Printf("error reading: %v", errRead)
            break
        }
    }
    
    // GetCottonwoodVendor returns the vendor ID of cottonwood UHF reader
    func GetCottonwoodVendor() usb.ID {
        value, err := strconv.ParseUint("1325", 16, 16)
        if err != nil {
            log.Fatal(err)
        }
        return usb.ID(value)
    }
    
    // GetCottonwoodProduct returns the product ID of cottonwood UHF reader
    func GetCottonwoodProduct() usb.ID {
        value, err := strconv.ParseUint("c029", 16, 16)
        if err != nil {
            log.Fatal(err)
        }
        return usb.ID(value)
    }
    
    第一次启动时,我得到:

    2016/12/14 19:19:18 3 bytes sent
    2016/12/14 19:19:20 read 0 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    2016/12/14 19:19:20 error reading: libusb: timeout [code -7]
    
    第二次和之后:

    2016/12/14 19:21:21 Cannot write command: libusb: timeout [code -7]
    

    我尝试使用hidraw使用另一个库,但它似乎也不起作用(可能是分离usb设备的问题)。

    运行程序时收到的确切错误消息是什么?只是添加了它!基本上,它可以写,然后不能读任何东西,然后超时。我认为真正的问题是,你在程序第一次运行时读取零字节。如果您可以解决这个问题,那么第二次运行时的写入超时可能会消失。我怀疑设备正在等待您读取对您的命令的响应,然后再处理来自您的任何其他命令。我不知道为什么阅读会失败。也许它实际上是一个非阻塞读取?你能试着在发出读取之前延迟,比如说100毫秒吗?如果连续读几次,其间有100毫秒的延迟呢?我只是在写和读之间加了1秒的睡眠,但问题是一样的。我还尝试了1s间隔的循环读取,总是读取0字节。我想知道我是否应该尝试使用HID LIB来检查它是否工作得更好。我会试试看,我没有多少想法了。