Coobila 发表于 2014-7-11 00:46:02

K21在UCOS III下USB HID通讯的奇怪问题

本帖最后由 Coobila 于 2014-7-11 00:43 编辑

最近公司有个项目K21平台采用UCOS III系统,本人负责移植USB自定义HID通信部分。采用官方USB库,本以为很快搞定,没想到这两天使用HID测试工具测试时,发现PC发数据到K21时,数据居然会有选择性???
比如发送01 00 04 00 11 22 33 44 00是正常,发送01 00 04 00 55 66 77 88 00居然被device stall掉了。调试发现没有进入USB_APP_DATA_RECEIVED的事件,甚是纳闷啊。在裸机下,同样的代码没发现这个问题,难道UCOS下有什么特别要注意的么?我不是很熟悉这个。
下面是我的代码,请高手指教啊。

/*****************************************************************************
* Global Functions
*****************************************************************************/
static boolean gHid_device_init=FALSE;            /* Application Init Flag */

#define HID_REC_BUF_SIZE    1024
uint8 *gHid_rec_data_buff = NULL;

static boolean gRecieveflag=FALSE;
static boolean gTransferflag=FALSE;

#define usb_frame_len(id)        (((uint16)1 << (id - 1)) * 8 + 1)

/******************************************************************************
*
*    @name      USB_App_Callback
*
*    @brief       This function handles the callback
*
*    @param       controller_ID    : Controller ID
*    @param       event_type       : value of the event
*    @param       val            : gives the configuration value
*
*    @return      None
*
*****************************************************************************
* This function is called from the class layer whenever reset occurs or enum
* is complete. after the enum is complete this function sets a variable so
* that the application can start
*****************************************************************************/
void USB_App_Callback(
      uint_8 controller_ID,/* Controller ID */
      uint_8 event_type,   /* value of the event*/
      void* val            /* gives the configuration value*/
)
{
    uint32 i;
    //static USB_DEV_EVENT_STRUCT even_back;
    static volatile boolean first_pkt = TRUE;
   
    //uart_printf("controller_ID:%d,event_type.....%d\r\n", controller_ID, event_type);
   
    //UNUSED (controller_ID)
    //UNUSED (val)
    if((event_type == USB_APP_BUS_RESET) || (event_type == USB_APP_CONFIG_CHANGED))
    {
                USB_ClearFlagStatus(USB_ENUM_COMPLETE);
                USB_ClearFlagStatus(USB_RECV_FLAG);
                USB_ClearFlagStatus(USB_SEND_FLAG);
    }
    else if(event_type == USB_APP_ENUM_COMPLETE)
    {
      /* if enumeration is complete set gHid_device_init so that application can start */
      USB_SetFlagStatus(USB_ENUM_COMPLETE);
      
      USB_ClearFlagStatus(USB_RECV_FLAG);
        USB_ClearFlagStatus(USB_SEND_FLAG);

        first_pkt = TRUE;
    }
    else if ((event_type == USB_APP_DATA_RECEIVED) && (TRUE == USB_GetFlagStatus(USB_ENUM_COMPLETE)))
    {
        PTR_USB_DEV_EVENT_STRUCT event = (PTR_USB_DEV_EVENT_STRUCT)val;
      uint16 next_len;
      uint16 dat_ptr;
      uint16 frame_len;
      uint8 report_id;

      if(first_pkt) // receive first usb packet
      {
              /* copy 1st packet data to receive buff */
              memcpy(gHid_rec_data_buff, event->buffer_ptr, event->len);

                /* get usb frame report id */
              report_id = gHid_rec_data_buff;

                /* PC out data frame length */
                if(report_id >= 0x08)
              {
                      frame_len = 1024;
              }
              else
              {
                      frame_len = usb_frame_len(report_id);
              }

              /* need to receive 2nd packet */
                if(report_id >= 0x04)
                {
                        first_pkt = FALSE;                                        // for 2nd receive
                        dat_ptr = event->len;
                        next_len = frame_len - event->len;        // 2nd pkt data length
                }
                else                                // no more pkt
                {
                        dat_ptr = 0;
                        next_len = 0;        // receive data complete
                        USB_SetFlagStatus(USB_RECV_FLAG);
                }
      }
      else        // for 2nd receive
      {
              first_pkt = TRUE;        // 2nd pkt over, then goto 1st
              dat_ptr = 0;
              next_len = 0;                // receive data complete
                USB_SetFlagStatus(USB_RECV_FLAG);
      }

      USB_Class_HID_Recv_Data(controller_ID, HID_OUT_ENDPOINT, &gHid_rec_data_buff, next_len);
    }
    else if((event_type == USB_APP_SEND_COMPLETE) && (TRUE == USB_GetFlagStatus(USB_ENUM_COMPLETE)))
    {
      USB_ClearFlagStatus(USB_SEND_FLAG);
      uart_printf("USB_APP_SEND_COMPLETE\r\n");   
    }
    return;
}
report表:
        0x06, 0x00, 0xff,                           // USAGE_PAGE (Vendor Defined Page 1)
        0x09, 0x01,                                    // USAGE (Vendor Usage 1)
        0xa1, 0x01,                                    // COLLECTION (Application)

        0x85, 0x01,                                    //        REPORT_ID (1)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x08,                                    //        REPORT_COUNT (8)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x08,                                    //        REPORT_COUNT (8)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x02,                                    //        REPORT_ID (2)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x10,                                    //        REPORT_COUNT (16)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x10,                                    //        REPORT_COUNT (16)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x03,                                    //        REPORT_ID (3)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x20,                                    //        REPORT_COUNT (32)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x20,                                    //        REPORT_COUNT (32)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x04,                                    //        REPORT_ID (4)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x40,                                    //        REPORT_COUNT (64)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x40,                                    //        REPORT_COUNT (64)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x05,                                    //        REPORT_ID (5)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x80,                                    //        REPORT_COUNT (128)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x95, 0x80,                                    //        REPORT_COUNT (128)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x06,                                    //        REPORT_ID (6)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x96, 0x00, 0x01,                           //        REPORT_COUNT (256)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x96, 0x00, 0x01,                           //        REPORT_COUNT (256)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x07,                                    //        REPORT_ID (7)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x96, 0x00, 0x02,                           //        REPORT_COUNT (512)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x96, 0x00, 0x02,                           //        REPORT_COUNT (512)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

        0x85, 0x08,                                    //        REPORT_ID (8)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x15, 0x00,                                    //        LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,                           //        LOGICAL_MAXIMUM (255)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x96, 0xFF, 0x03,                           //        REPORT_COUNT (1024)
        0x81, 0x02,                                    //        INPUT (Data,Var,Abs)
        0x09, 0x02,                                    //        USAGE (Vendor Usage 2)
        0x75, 0x08,                                    //        REPORT_SIZE (8)
        0x96, 0xFF, 0x03,                           //        REPORT_COUNT (1024)
        0x91, 0x02,                                    //        OUTPUT (Data,Var,Abs)

Coobila 发表于 2014-7-14 12:38:04

向PC发数据没这问题。。有做过自定义HID双向通信的大神给点意见吧,或者有参考代码借鉴下啊{:smile:}

一品电子 发表于 2014-7-16 17:57:14

我总觉得uc 对usb设备有缺陷,感觉不是很完美,当然也可能是我水品太低了了

FSL_TICS_Robin 发表于 2014-7-30 10:16:50

楼主你好
建议你到飞思卡尔英文论坛发帖问问

fengyunyu 发表于 2014-8-3 21:48:20

LZ,选ucos iii,不选ucos ii,为何?是用的官方移植么?
页: [1]
查看完整版本: K21在UCOS III下USB HID通讯的奇怪问题