一.前言
在上节我们实现了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卡能够正常被电脑识别了,类似读卡器的功能就实现了。