搜索
查看: 2133|回复: 4

[求助] stm32 f107 usb hid 接收PC下发数据时死机

[复制链接]

该用户从未签到

1

主题

4

帖子

2

蝴蝶豆

中级会员

最后登录
2020-11-17
发表于 2019-3-11 16:55:51 | 显示全部楼层 |阅读模式
本帖最后由 一页繁华 于 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 捕获如下图所示:

出错2.PNG

pc端枚举如下图:

错误3.PNG


接收和发送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 如下图所示:
错误1.PNG

经过定位发现出错位置在

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)时进入硬件错误中断,不知道有没有朋友遇到过这个问题。






回复

使用道具 举报

该用户从未签到

1

主题

4

帖子

2

蝴蝶豆

中级会员

最后登录
2020-11-17
 楼主| 发表于 2019-3-12 16:17:44 | 显示全部楼层
已解决,通过将USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt)函数修改如下的到解决:
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);
}

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2 自主解决

查看全部评分

回复 支持 反对

使用道具 举报

该用户从未签到

10

主题

195

帖子

65

蝴蝶豆

金牌会员

最后登录
2023-9-26
发表于 2019-4-11 23:09:59 | 显示全部楼层
没遇到你这个问题,应该是数组越界了,

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

回复 支持 反对

使用道具 举报

该用户从未签到

10

主题

195

帖子

65

蝴蝶豆

金牌会员

最后登录
2023-9-26
发表于 2019-4-11 23:12:15 | 显示全部楼层
天臆弄人 发表于 2019-4-11 23:09
没遇到你这个问题,应该是数组越界了,

我用的是2..1.0, 代码是一样的

#define HID_IN_EP                    0x81
#define HID_OUT_EP                   0x01

用的是这2个,没有用复合设备,USB HID 还可以一次发几K 数据包都没死过

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

4

帖子

2

蝴蝶豆

中级会员

最后登录
2020-11-17
 楼主| 发表于 2019-5-14 09:15:39 | 显示全部楼层
本帖最后由 一页繁华 于 2019-5-14 09:23 编辑
天臆弄人 发表于 2019-4-11 23:12
我用的是2..1.0, 代码是一样的

#define HID_IN_EP                    0x81

感谢老兄的关注,这个问题由于当时应用上面的方法可以使用了,加之忙于其他的事情,便没有在继续调试找出问题的真正原因,看到老兄的回复,我又调试了几遍,找到了问题的原因。当数据来的时候,调试发现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)
通过修改,问题得到了解决。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-9 04:06 , Processed in 1.179350 second(s), 41 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表