文章目录

  • 前言
  • 一、问题现象
  • 二、确定BUG类型,硬件BUG?软件BUG?
  • 三、解决问题
  • 四、如何让U盘和文件系统共存
  • 总结



前言


这几天为了公司案子在玩弄文件系统和U盘,今天用探索者开发板的W25Q128虚拟成U盘的时候又发现BUG,个人认为这个BUG不是RTT软件本身,应该是属于芯片自身问题,后面会讲到我的依据,如有讲错,大佬嘴下留情别喷我。我项目功能要求Flash需要搭载文件系统,USB插上电脑后,电脑能将其当做U盘一样进行文件操作,然而无法识别U盘拔出是很致命的,因为拔出U盘后我需要将USB占用W25Q128给解除掉,切换到文件系统上,无法识别拔出那么我就不知道什么时候解除,什么时候挂载。莫得办法!!赶紧找BUG吧!!


一、问题现象

1、将W25Q128虚拟成U盘插到电脑,可以正常识别,但是拔出U盘时却没有任何拔出的提示
2、无论多少次拔出都是一样,没有任何提示信息

二、确定BUG类型,硬件BUG?软件BUG?

1、我在网上也找了相关问题资料,找了很久只发现一篇文章讲了相关问题,但是讲的解决方案我并没有采纳,因为他也没有找到BUG根源。

2、最后我决定使用正点原子官方例程USB读卡器例程测试测试一下,令人惊讶的是虽然表面看起来正常,其实也存在这个问题,不看代码是看不出问题所在的。

3、原子的usbd_user.c这个是编写用户代码的文件,里面写了很多回调函数,其中有一个拔出U盘回调响应函数打印出USB Device Disconnected.的信息,然而事实上却没有打印出来。

android U盘拔出信号_rtt


4、原子程序运行的时候拔出U盘打印未连接信息是在man函数中的一个字符串USB DisConnected ,他通过判断变量USB_STATUS_REG的USB的轮询状态来确定当然USB连接状态。

android U盘拔出信号_usb_02


android U盘拔出信号_嵌入式_03


5、为什么原子哥偏要使用这个轮训状态来判断U盘是否拔出,不直接使用回调函数,这样不香吗?不简单吗?原子哥也不傻,肯定是遇到和我一样的问题并且没法解决,所以我大概率觉得是芯片自身的问题,并非软件BUG,我也不能完全肯定,也希望知道真相的大佬能和我讨论一下。

三、解决问题

1、方法有三种:

  • 芯片换方案
  • 用某种方式掩盖BUG
  • 提桶跑路

很明显要选择第二种方法挣扎一下啦!!不会吧~不会吧!难道真的有人想要选择提桶跑路吧!本人并没有使用原子哥的方案,因为有点麻烦,而且用他的方案用到我的工程中会有耦合性。

2、在USB的中断服务函数中发现了几个中断类型,其中一个是挂起和复位中断,挂起中断是在拔出U盘和挂起的时候会被触发,复位中断是在U盘插入的时候会触发,利用这个规律我们就可以干他!!

挂起中断:

android U盘拔出信号_rtt_04


复位中断(部分截图):

android U盘拔出信号_嵌入式_05


3、自定义一个局部的静态连接状态变量usb_connect_status,复位的时候置位,挂起的时候清零。HAL_PCD_SuspendCallback(hpcd);函数是用来解除U盘这个设备的,解除之后我才能让W25Q128挂载文件系统,这个函数我又是怎么知道的,往后看。

android U盘拔出信号_单片机_06


4、在USB中断服务函数中有相关的断开连接后执行的代码,实际上由于BUG的存在这些代码写了个寂寞,没啥乱用。我们有样学样,直接用这个函数来解除,至于其余代码就没必要了,因为存在BUG都没有作用。

android U盘拔出信号_rtt_07


5、实际上HAL_PCD_DisconnectCallback(hpcd);是用来回调下面的函数的,下面的函数就是用来解除的,执行了这个函数后就可以挂载文件系统了。

android U盘拔出信号_嵌入式_08

四、如何让U盘和文件系统共存

1、list_device的时候我们能发现Block Device的值,通过这个值就可以判断有没有东西在用W25Q128了,被占用那就不能挂载文件系统或者不能将其切换成U盘。这个就很简单啦~~

android U盘拔出信号_usb_09

总结

一天过去了,飘落的秀发就和时间一样,无法挽回!我又能怎样呢?我可以回去躺尸~~