11.RT-thread项目实战--usb_device 模拟读卡器

一.前言

在上节我们实现了FTP网络传输功能,实现了通过网络对设备的文件进行读写的功能,但是我们要是没网呢,想要导出数据文件怎么办??

首先想到了USB,这次我们通过usb的otg接口,实现一个模拟读卡器的功能,将设备插入到电脑后,将我们的sdcard作为一个U盘,我们就可以直接通过电脑进行拷贝了。

此次我们选用usb-device模式,usb提供的复合设备类型,可以让给usb添加虚拟串口及读卡器的功能,这里只说读卡器功能。

目前rt-thread的usb组件通过此次的添加,发现还是有一些不稳定的,不过目前实现的功能还是没有太大问题。

事先说明:此次添加组件,遇到了很多问题,下面会进行记录和解决方法的说明。

 

二.usb组件添加

1.添加usb_device

2.

上面的几个框内容要格外注意:ID,大容量存储设备 MSC类磁盘名。

注:

如果配置出错,电脑识别不出来usb,同时注意MSC磁盘名要和自己的对应上。

上面这些报错,都是配置有问题出现的。

我的用的是sdcard,选用sd0(需要看自己代码中的定义),自己通过指令查看一下:

如果选择错误,会报错:no data->disk named sd0(测试时一直都在插着stm32的USB到电脑,导致烧写完程序后运行时未正常打开USB,要烧写完成正常运行的时候再把USB插入电脑。还有一点注意的问题,在menuconfig中usb启用时设备名默认是“flash0”,我的是“sd0”,把这里修改为“sd0”,否则提示找不到硬盘设备。

3.注意还要打开虚拟文件系统,这里我们之前已经打开过了。(这个是基于之前的文件系统历程做的)

4.打开stm32h7xx_hal_conf.h

我们是从机,检查下PCD的是否使能了。作为主机的时候检查HCD。

 

5.

我们做完了上面的几个步骤可以先下载试一下,发现还是会报错,提示

disk open error

通过定位发现是mstorage.c文件下rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK出现了报错,难道是我们的SD卡有问题?

但是我们sd卡是正常的:(确保sd卡可以识别,我之前就是用的特制的sd卡导致异常

usb设备也注册上了:

那么是什么原因呢??

打开设备失败?难道是不能二次打开设备??通过在论坛查找答案,确实找到了几个回答.

https://club.rt-thread.org/ask/question/5651.html

https://club.rt-thread.org/ask/question/428813.html

https://club.rt-thread.org/ask/question/12310.html

这个帖子主要说了模拟U盘和文件系统不能共存的问题,也确实有人回答了block只能被打开一次

其实现在问题已经明确了,上电之后,我们的SD卡已经挂接到文件系统上,供设备使用,这时候usb插入,再次打开出现了报错。

那么问题知道了,解决方法也就好说了;

主要有两种方案;

方案1:当usb插入后,先将sd卡unmount掉,再打开就没有问题了。

void my_sdcard_unmount(void)
{
    _sdcard_unmount();
}
void my_sdcard_mount(void)
{
     _sdcard_mount();
}

usb插入后会触发到这个函数。mstorage.c

static rt_err_t _function_enable(ufunction_t func)

my_sdcard_unmount();//放在开始位置

拔掉后使用哪个函数呢?需要将sdcard挂接回去。

但是发现这个程序能够正常识别插入,但是拔出识别不是很稳定,有时能够触发,有时触发不了。

static rt_err_t _function_disable(ufunction_t func)

my_sdcard_mount();//函数最后

注:这个方法测试是可以的,但是usb插入能够检测到,拔出检测不到,有网友利用ADC检测电压进行插拔检测

测试:插入usb后会打印如下信息

方案2:usb mstorage.c 的_function_enable函数那里在open前先做判断,如果已经open了,则不需要再open了:

 if ((data->disk->flag & RT_DEVICE_FLAG_STANDALONE) &&(!(data->disk->open_flag & RT_DEVICE_OFLAG_OPEN)))
 {
        if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
        {
            rt_kprintf("disk open error\n");
            return -RT_ERROR;
        }
 }

一个简单的判断,就实现了模拟U盘和文件系统的共存,但是这种方法要考虑互斥问题,测试的时候也发现,修改一方文件,另一方不重启是刷新不了的,不过好在我们只复制不修改问题,之后再进行优化。

 

6.此时sd卡能够正常被电脑识别了,类似读卡器的功能就实现了。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章