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) 向PC发数据没这问题。。有做过自定义HID双向通信的大神给点意见吧,或者有参考代码借鉴下啊{:smile:} 我总觉得uc 对usb设备有缺陷,感觉不是很完美,当然也可能是我水品太低了了 楼主你好
建议你到飞思卡尔英文论坛发帖问问 LZ,选ucos iii,不选ucos ii,为何?是用的官方移植么?
页:
[1]