本帖最后由 一页繁华 于 2019-3-11 17:05 编辑 我使用的是stm32f107的芯片,移植了STM32_USB-Host-Device_Lib_V2.2.0 官方usb固件库,实现了两个接口的hid 组合设备(通过修改msc-hid复合设备例程)在UCOSII操作系统中运行,目前接口1(端点1)上传报文没有问题,但是接口2(端点2)在接收PC下发的报文时出现死机,程序转到硬件错误中断,pc机下发数据长度为64字节,数据通过bus hound 捕获如下图所示: pc端枚举如下图: 接收和发送SIZE定义如下: #define Interface1_EPIN_SIZE 64 #define Interface2_EPOUT_SIZE 64 fifo长度定义如下: #define RX_FIFO_FS_SIZE 128 #define TX0_FIFO_FS_SIZE 64 #define TX1_FIFO_FS_SIZE 64 #define TX2_FIFO_FS_SIZE 64 堆栈定义如下: Stack_Size EQU 0x00002000 Heap_Size EQU 0x00002000 出错时的register value 如下图所示: 经过定位发现出错位置在 DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)调用的USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt)函数中; 该函数源代码如下: void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev, uint8_t *dest, uint16_t len) { uint32_t i=0; uint32_t count32b = (len + 3) / 4; __IO uint32_t *fifo = pdev->regs.DFIFO[0]; for( i = 0; i < count32b; i++) { *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo); dest += 4 ; } return ((void *)dest); } 当执行到 *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo)时进入硬件错误中断,不知道有没有朋友遇到过这个问题。 |
typedef union {
uint32_t USB_32byte;
uint8_t USB_8byte[4];
}
Rx_usb;
Rx_usb Rx_data[64];
void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev,
uint8_t *dest,
uint16_t len)
{
uint32_t i=0;
uint32_t count32b = (len + 3) / 4;
u8 j=0;
__IO uint32_t *fifo = pdev->regs.DFIFO[0];
for( i = 0; i < count32b; i++)
{
if( len == 64)
{
Rx_data[i].USB_32byte = USB_OTG_READ_REG32(fifo);
}
else
{
*(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo);
}
dest += 4 ;
}
return ((void *)dest);
}
评分
查看全部评分
评分
查看全部评分
我用的是2..1.0, 代码是一样的
#define HID_IN_EP 0x81
#define HID_OUT_EP 0x01
用的是这2个,没有用复合设备,USB HID 还可以一次发几K 数据包都没死过
评分
查看全部评分
感谢老兄的关注,这个问题由于当时应用上面的方法可以使用了,加之忙于其他的事情,便没有在继续调试找出问题的真正原因,看到老兄的回复,我又调试了几遍,找到了问题的原因。当数据来的时候,调试发现USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);中的ep->xfer为零,导致进入到函数以后进入硬件错误中断,对比了以下库的原例程,发现是我在进行初始化的时候粗心漏了调用如下函数将接收数据缓冲数组地址传入。
uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint16_t buf_len)
通过修改,问题得到了解决。