H743 USBHOST协议栈 CPU占用率高的问题。

news/2024/11/29 2:53:10/

经过查看,是因为USBHOST频繁的进入中断导致,单步执行发现,是因为发生了USB_OTG_HCINT_CHH或者USB_OTG_HCINT_NAK中断了,只在CHH中断服务函数里,给USB主线程发了1个消息,又引起了USBH_Process_OS主线程的频繁运行,最终导致整个H743的资源都用在了USB上面,连个printf()打印调试信息都卡。

  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)

  {

    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);

    HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);

  }

  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)

  {

    if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)

    {

      hhcd->hc[ch_num].ErrCnt = 0U;

      __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);

      (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);

    }

    else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||

             (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))

    {

      hhcd->hc[ch_num].ErrCnt = 0U;

#if 0

      if (hhcd->Init.dma_enable == 0U)

      {

        hhcd->hc[ch_num].state = HC_NAK;

        __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);

        (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);

      }

#else       //###### Fri May 26 16:56:16 CST 2023

            /* re-activate the channel */

      hhcd->hc[ch_num].state = HC_NAK;

      tmpreg = USBx_HC(chnum)->HCCHAR;

      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;

      tmpreg |= USB_OTG_HCCHAR_CHENA;

      USBx_HC(chnum)->HCCHAR = tmpreg;

#endif

    }

    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);

  }

解决过程如下:

      这段程序我之间用在F437上,是没有问题的,为了对比起见,专门把F437的相应程序运行起来,确实没有这种情况,经过对比,我发现F437的USB并没有频繁的进入USB_OTG_HCINT_CHH导致的中断,2个工程对应的驱动与上层应用是一样的,唯一不一样的是USB协议栈,一个是F437的USB协议栈,比较老,20年左右的, 而现在用的H743的USB协议栈是最新的。我对比了一下,确实存在不同,由于USB协议栈没有版本记录,所以不能简单的从USB协议栈版本加以区分,但对比程序源码,除了协议栈结构相似外,内容细节还是有很大不同的。于是就慢慢的分析,

发现只要我一启动接收就会出来卡顿的情况

    USBH_CDC_Receive(modem->phost, modem->bulk_in_buf, MODEM_RX_BUFSIZE);   //启动接收

说明就是这里引起的,由于这是一个4G模块 驱动 , 4G模块在正常识别后,就会启动接收数据,这种设备不像U盘,发送与接收的字节数都是应用确实好的,发送与接收数据的时刻也是上层应用确定的,这种设备由于接收数据的不确定性,所以上电会就要马上启动接收线程,这本身是没问题的,但是F437也是这种的驱动结构,F437就没有问题,思来想去,还是USB协议栈的问题,

    为什么会进USB_OTG_HCINT_CHH中断呢,官方文档说有2种可能,1是USB事务错误,1是应用关闭USB导致

我启动USBH_CDC_Receive()接收后,但是4G模块这时没有数据,就会改善NAK包,NAK包也会产生USB_OTG_HCINT_NAK中断,这在F437中也验证了,进入NAK中断是正常的,经过对比2个USB协议栈对NAK的处理,发现点猫腻,就是我上面列出的程序时处理的那样

F437是如果端点是ctrl 或者bulk的话,重新启动re-activate the channel USB,但是H743确实直接关闭USB通道,我

猜测正是这个操作,刚好符合”2应用关闭USB导致CHH“,所以后面紧接着就产生了CHH中断,从而造成了系统循环在USB中断中运行,最终导致USB占用CPU奇高的问题,

      解决方法,按F437的方法修改H743的USB协议栈,其实也是不是协议栈,是stm32h7xx_hal_hcd.c,修改如上面代码,问题解决。


http://www.ppmy.cn/news/96036.html

相关文章

七、Django DRF框架GenericAPIView--搜索排序分页

上一章: 六、DRF框架APIView--request&response解析器&渲染器_做测试的喵酱的博客-CSDN博客 下一章: 一、GenericAPIView介绍 APIView 继承 View GenericAPIView 继承 APIView。 GenericAPIView 功能: a.具备View的所有特性 …

达梦8逻辑备份导出导入dexp/dimp

逻辑导出(dexp)和逻辑导入(dimp)是 DM 数据库的两个命令行工具,分别用来实现对 DM 数据库的逻辑备份和逻辑还原。逻辑备份和逻辑还原都是在联机方式下完成,联机方式是指数据库服务器正常运行过程中进行的备…

深度学习进阶篇-预训练模型[4]:RoBERTa、SpanBERT、KBERT、ALBERT、ELECTRA算法原理模型结构应用场景区别等详解

【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化…

从代码角度理解DETR

一个cnn的backbone, 提图像的feature, 比如, HWC.同时对这个feature做position_embedding.然后二者相加 (在Transformer里面就是二者相加)输入encoder,输入decoder (这里有object queries.)然后接Prediction Heads, 比如分类和回归. 下面的代码参考自: https://github.com/fac…

Ovirt 开源虚拟化平台安装

ovirt官网 一、资源规划介绍 1.1、服务规划 ovirt版本 ovirt engine 4.3.10 ovirt node 4.3.10 ovirt.node01.opsvv.com 负责托管引擎服务 1.2、资源划分 1.2.1、节点划分 密码均为:12345678 Node02无法开启虚拟化,只演示加入集群节点使用 节点…

Mac下好用的日记、电子书阅读器、RSS订阅软件​

Mac下好用的日记笔记本、电子书阅读器和RSS订阅、播客订阅等软件推荐。我们收录到 Mac下好用的日记、电子书阅读器、RSS订阅软件​http://www.webhub123.com/#/home/detail?pLZPL-2ofIu 收录效果如下 ​也可以使用分组视图来查看各类软件网址 ​ 登录后可一键保存全部软件网址…

C语言中获得结构体成员的相对偏移量(Linux内核源码解读)

问题起源 这篇文章的起源是读到了一句代码 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)这是一个宏定义,这个宏定义来自Linux内核源码,它的作用是获取一个结构体中的变量相对于这个结构体的偏移量。这么讲有点抽象&#xf…

Pandas识别中文日期,这4步轻松搞定!

在使用Pandas处理含有中文日期的CSV文件时,中文日期列无法直接被识别为datetime类型,这会造成该列无法进行时间序列操作。那么,如何让Pandas正确解析中文日期列,并将其转换为datetime64类型呢? 今天分享在Pandas识别中文日期的4大…