2015-02-10 16 views
5

Chúng tôi có một thiết bị nhúng dựa trên CC2531 của TI trong đó có (ngoài kiểm soát EP0 và một số điểm cuối IN) một điểm cuối là cả IN và OUT. Chúng tôi đã nhận thấy một sự khác biệt trong cách cửa sổ gửi OUT báo cáo và làm thế nào Linux hiện này. Điều này đã thực sự boggled chúng tôi một thời gian, nhưng chúng tôi chưa bao giờ có thể tìm thấy một lời giải thích.Báo cáo USB HID OUT - điểm cuối nào là đúng?

Dường như với tôi linux nào đó cách thức mà nó được coi là: báo cáo OUT được truyền qua các thiết bị đầu cuối được kết hợp với báo cáo HID, như chúng ta có được nó từ libusb:

Item    | Dev | EP | Status | Speed |Payload 
-----------------+-----+----+--------+-------+------------------------------- 
OUT transaction | 13 | 4 | ACK | FS | 64 bytes (90 13 00 00 00 00 .. 

Mặt khác, Windows gửi nó qua điểm cuối điều khiển (EP0). Chúng tôi sử dụng API thiết lập để tìm thiết bị có các tập quán mà chúng tôi cần, mở nó cho IN và OUT và sử dụng cùng một bộ mô tả tệp để đọc và viết. Các EP4 TRÊN báo cáo được độc đáo nhận được thông qua bộ mô tả tập tin này, nhưng viết một báo cáo qua mô tả cùng một tập tin, kết thúc lên trên EP0:.

Item    | Dev | EP | Status | Speed |Payload 
-------------------+-----+----+--------+-------+------------------------------- 
Class request OUT | 25 | 0 | OK | FS | 64 bytes (90 13 00 00 00 00 .. 

(xin lỗi, không thể đăng ảnh (chưa) tôi đã sao chép Ellisys báo cáo bằng tay)

Thiết bị nhúng không kiểm tra xem báo cáo OUT nào nhận được (tức là SET báo cáo trên EP0 sẽ kênh vào cùng chức năng như OUT báo cáo tìm thấy trên các thiết bị đầu cuối khác khi xử lý sự kiện HID), vì vậy nó sẽ trả lời theo một trong hai cách.

Câu hỏi của tôi là: cả hai cách đều chính xác, và nếu không, đó là chính xác và điều nào không đúng? Nó có thể là một lỗi trong mô tả của chúng tôi gây ra hành vi này trên cửa sổ?

Để được hoàn thành: đây là mô tả của chúng tôi: http://tny.cz/ac745a8f (lột từ xác định nhà cung cấp để giữ cho ông chủ của tôi hạnh phúc :))

Phóng to vào báo cáo khi trên cửa sổ: (Joy tôi được phép làm ảnh bây giờ:))

enter image description here

toàn bộ giao dịch:

enter image description here

Thư viện đã sử dụng trên Windows: hid.lib, hidclass.lib và setupapi.lib. Khi viết một báo cáo, chúng tôi sử dụng các hàm HidP_SetUsageValueArray và HidD_SetOutputReport. PHIDP_PREPARSED_DATA và HIDP_CAPS được tìm thấy với các hàm HidD_GetAttributes, HidD_GetPreparsedData và HidP_GetCaps. Đường dẫn tệp cho thiết bị được tìm thấy bằng SetupDiEnumDeviceInterfaces. Nếu chúng ta tìm thấy một thiết bị có đúng VID, PID, caps.UsagePage và caps.Usage, đó là thiết bị chúng ta sử dụng.

Trên Linux, điều này hơi phức tạp hơn một chút vì tôi không phải là người triển khai mã Linux. Những gì tôi có thể nói là libusb-1.0.9 được sử dụng, thiết bị được mở bằng cách sử dụng libusb_open_device_with_vid_pid, các báo cáo được gửi với libusb_fill_interrupt_transfer và libusb_submit_transfer. Tôi thấy rằng libuwand_fill_interrupt_transfer chấp nhận một điểm cuối làm tham số, vì vậy tôi nghĩ chỉ cần xử lý từ libusb_open_device_with_vid_pid và truyền tham số đúng làm điểm cuối, libusb sẽ tìm ra nơi để đặt báo cáo.

+0

Điểm cuối 0 được dành riêng cho chuyển điều khiển, vì vậy phải có gói SETUP 8 byte được gửi trước tải trọng, với các tham số như bRequestType, bRequest, wValue và tương tự. Bạn có thể đăng các giá trị của gói SETUP đó không? Có thông tin đó sẽ cho phép chúng ta nhìn vào đặc tả HID và xem yêu cầu Windows gửi đi, và liệu nó có hợp lệ hay không. Ngoài ra, bạn đang sử dụng ngăn xếp trình điều khiển/thư viện nào để gửi dữ liệu trên Linux và Windows? Điểm cuối mà Windows sử dụng có thể phụ thuộc vào trình điều khiển (ví dụ: hidusb.sys) và thư viện bạn sử dụng để nói chuyện với trình điều khiển (ví dụ: libusb) và mã của bạn. –

+0

"Thiết bị nhúng không kiểm tra xem báo cáo OUT nào được nhận": Điều đó nghe có vẻ bất thường đối với tôi. Nó hoạt động như thế nào? Cấu trúc của các chuyển điều khiển được gửi trên điểm cuối 0 phức tạp hơn nhiều so với dữ liệu trên điểm ngắt hoặc điểm cuối bình thường, vì vậy bạn cần mã đặc biệt để xử lý dữ liệu điểm cuối 0 ở vị trí đầu tiên. –

Trả lời

1

Tôi nghĩ rằng tôi đã tìm thấy câu trả lời.

hoàn toàn là trùng hợp ngẫu nhiên Tôi tình cờ gặp diễn đàn Keil nơi tôi tìm thấy câu lệnh 'HidD_SetOutputReport sẽ sử dụng điểm cuối điều khiển, nếu bạn muốn thông qua điểm cuối khác, hãy sử dụng WriteFile'. Tôi biết rằng hơn 5 năm trước, tôi đã thử đường đó nhưng tôi bị mắc kẹt trong IO không đồng bộ với cấu trúc chồng chéo.Vì nó xuất hiện tôi đã có một lối thoát (sử dụng HidD_SetOutputReport), tôi đã bỏ qua đường dẫn WriteFile. Vì vậy, bây giờ là lúc để tìm kiếm con đường đó một lần nữa, và tôi đã làm. Mã này:

res = HidD_SetOutputReport(m_DeviceControl[dev], report, m_CapsControl[dev].OutputReportByteLength); 

đã được thay thế bởi

   DWORD bytesWritten; 
       OVERLAPPED eventWrite = {0}; 

       eventWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 

       int rv3 = WriteFile(m_DeviceControl[dev], report, m_CapsControl[dev].OutputReportByteLength, &bytesWritten, &eventWrite); 
       if (rv3 == 0) 
       { 
        int err = GetLastError(); 

        if (err == ERROR_IO_PENDING) 
        { 
         bool done = false; 

         do 
         { 
          // yes. Wait till pending state has gone 
          rv3 = WaitForSingleObject(eventWrite.hEvent, 25); 
          if (rv3 == WAIT_OBJECT_0) 
          { 
           GetOverlappedResult(m_DeviceControl[dev], &eventWrite, &bytesWritten, FALSE); 
           done = true; 
           res = TRUE; 
          } 
          else if (rv3 == WAIT_TIMEOUT) 
          { 
           // Need to try again. 
          } 
          else 
          { 
           m_StoppingControlOut = true; 
           done = true; 
          } 
         } 
         while (!done && !m_StoppingControlOut); 
        } 
       } 
      } 

và điều này làm cho các yêu cầu đi qua các thiết bị đầu cuối phù hợp.

Vì vậy, tôi đi đến kết luận sau:

  • Tôi nghĩ rằng đó là sai lầm rằng thiết bị HID giải thích các báo cáo OUT gửi thông qua thiết bị đầu cuối kiểm soát.
  • Sử dụng WriteFile chính xác (với IO chồng chéo) làm cho báo cáo OUT sử dụng điểm cuối chính xác.
Các vấn đề liên quan