eric2013 发表于 2018-8-29 18:24:07

【原创开源应用第5期】基于RL-USB+RL-FlashFS的外挂U盘解决方案

说明:
1、RL-USB外挂U盘的例子,最近太多网友咨询,再不做一个例子就说不过去了。此例子为此而生。
2、RTX及其所有中间件基本都做例子了,就差这个USB Host功能了,这次算是补上,所有功能基本已经做全面。
3、此例子仅支持MDK4.74版本,因为RTX,RL-FlashFS,RL-USB都是来自MDK4.74的安装目录,使用MDK4.74才是最佳组合。要使用MDK5的话,看此贴说明:链接
4、RL-FlashFS的文件名仅支持ASCII,不支持中文,这点要特别注意。
5、RL-FlashFS的函数是标准的C库函数,跟电脑端的文件系统使用方法一样。
6、相比ST的USB库,兼容性稍好点。

static/image/hrline/4.gif
使用说明:

大家首次测试时,先将U盘插上,上电后会进行枚举并串口打印是否连接成功。如果能够识别U盘并且操作也正常,后续就可以测试热插拔操作是否正常。

支持热插拔,可以自动识别并做初始化操作,无需调用加载和卸载指令.
请选择串口操作命令,电脑键盘打印数字即可:
L - 加载USB
U - 卸载USB
1 - 显示SD卡容量和剩余容量
2 - 显示SD卡根目录下的文件
3 - 创建三个text文本并使用不同函数写入内容
4 - 使用三个不同函数读取文本
5 - 创建一个text文本并指定一个位置对其进行读写操作
6 - 删除文件夹和文件
7 - 测试文件读写速度
8 - 写数据到CSV文件中
9 - 从CSV文件中读数据

static/image/hrline/4.gif
注意事项:
当前RL-USB的Host功能,仅调通了STM32的FS接口外接U盘,而HS接口外接U盘未做调试。
对于我们的V5和V6开发板来说,FS接口是做为Device使用的,要做Host功能使用的话,需要对外做5V供电。解决办法这里接1个5V杜邦线。看下面两个红色方框的地方进行连接即可。


接口要使用MicroUSB接口,也就是需要大家外接一个转接线接测试U盘了。


static/image/hrline/4.gif
百度云:
链接: https://pan.baidu.com/s/12s6FMD7fQ5yxLOAoDFsbOg 提取码: dbjh

例程下载:



static/image/hrline/4.gif


static/image/hrline/4.gif
兼容性方便,手头这4个U盘都可以成功识别并测试。
https://img.anfulai.cn/dz/attachment/forum/pw/Fid_47/47_58_ca0e5ffd31b6881.png






sanit 发表于 2018-8-29 19:12:28

几年过去了,还是这四个U盘啊。老大体贴民众,赞赞赞赞

eric2013 发表于 2018-8-30 00:46:20

sanit 发表于 2018-8-29 19:12
几年过去了,还是这四个U盘啊。老大体贴民众,赞赞赞赞

这几个U盘跟了我好几年了:lol

永恒的_eSg02 发表于 2018-8-30 11:15:14

还有机会出HS接口外接U盘的例程吗?

eric2013 发表于 2018-8-30 12:01:15

永恒的_eSg02 发表于 2018-8-30 11:15
还有机会出HS接口外接U盘的例程吗?

后面有精力做下,没精力的话,可能就不做了:handshake

永恒的_eSg02 发表于 2018-8-30 12:04:17

eric2013 发表于 2018-8-30 12:01
后面有精力做下,没精力的话,可能就不做了

:)辛苦了,点赞!

waterx3 发表于 2018-8-30 17:13:03

V5板是不是改下引脚就可以用USB-A的插座?

waterx3 发表于 2018-8-30 17:27:58

一个不幸的消息,程序直接下载到V5板,然后就不识别CPU了。:L

waterx3 发表于 2018-8-30 17:28:33

蜂鸣器上和右侧的灯一直在闪

eric2013 发表于 2018-8-31 00:33:41

waterx3 发表于 2018-8-30 17:13
V5板是不是改下引脚就可以用USB-A的插座?

不能哦,好像底层驱动要稍微修改,具体还没有去研究。

eric2013 发表于 2018-8-31 00:33:58

waterx3 发表于 2018-8-30 17:27
一个不幸的消息,程序直接下载到V5板,然后就不识别CPU了。

多试试。

waterx3 发表于 2018-8-31 09:55:13

eric2013 发表于 2018-8-31 00:33
多试试。

MDK,debug的Settings里也看不到CPU了,降速也看不到。

eric2013 发表于 2018-9-1 01:20:09

waterx3 发表于 2018-8-31 09:55
MDK,debug的Settings里也看不到CPU了,降速也看不到。

改用串口下载一次,估计是你的SWD接口锁住了。

活出自我 发表于 2018-9-4 12:58:15

硬汉大神,请教个问题:keil RTX的USB Device协议栈是以库的形式提供吗?提供协议栈源码吗?

昵哥 发表于 2018-9-4 14:26:42

虽然我已经调试出来了,但是还是要赞一下硬汉。正是需要这个东东的时候,刚好可以拿来做参考。硬汉!真是服了你了。刚开始还不习惯你的代码风格,刚开始用原子的,后来慢慢发现,还是硬汉厉害!!!!!

eric2013 发表于 2018-9-4 15:30:33

活出自我 发表于 2018-9-4 12:58
硬汉大神,请教个问题:keil RTX的USB Device协议栈是以库的形式提供吗?提供协议栈源码吗?

keil的除了RTX4和RTX5有源码,其它的中间件都只有库:handshake

小狐狸 发表于 2018-9-5 15:04:17

eric2013 发表于 2018-9-4 15:30
keil的除了RTX4和RTX5有源码,其它的中间件都只有库

FSN_CM3.lib库是不支持FAT长文件名的,但是看手册这个库FS_CM3.lib是支持的呀,硬汉哥有没有试过这个库呢?


现在我移植这个例子到我的板子上,到 finit("U0:"); 这里板子就开始一直复位了,拔掉U盘就又不复位,在、不知咋回事

eric2013 发表于 2018-9-5 15:07:02

小狐狸 发表于 2018-9-5 15:04
FSN_CM3.lib库是不支持FAT长文件名的,但是看手册这个库FS_CM3.lib是支持的呀,硬汉哥有没有试过这个库呢 ...

有时间我试试。

小狐狸 发表于 2018-9-6 17:37:12

eric2013 发表于 2018-9-5 15:07
有时间我试试。

今天使用你的例子测试了下FlashFS和RL-USB驱动,得出如下结论:
1、FlashFS的部分功能比FATFS要少许多,例如没有新建文件夹的函数,不支持中文文件名,不支持长文件名的文件夹等等,但是FlashFS也有自己的特点,比如均衡,支持的flash类型多,稳定性高等等。
下面是FlashFS支持的api












下面是FATFS支持的:
FatFs provides various filesystem functions for the applications as shown below.
[*]File Access
[*]f_open - Open/Create a file
[*]f_close - Close an open file
[*]f_read - Read data from the file
[*]f_write - Write data to the file
[*]f_lseek - Move read/write pointer, Expand size
[*]f_truncate - Truncate file size
[*]f_sync - Flush cached data
[*]f_forward - Forward data to the stream
[*]f_expand - Allocate a contiguous block to the file
[*]f_gets - Read a string
[*]f_putc - Write a character
[*]f_puts - Write a string
[*]f_printf - Write a formatted string
[*]f_tell - Get current read/write pointer
[*]f_eof - Test for end-of-file
[*]f_size - Get size
[*]f_error - Test for an error

[*]Directory Access
[*]f_opendir - Open a directory
[*]f_closedir - Close an open directory
[*]f_readdir - Read an directory item
[*]f_findfirst - Open a directory and read the first item matched
[*]f_findnext - Read a next item matched

[*]File and Directory Management
[*]f_stat - Check existance of a file or sub-directory
[*]f_unlink - Remove a file or sub-directory
[*]f_rename - Rename/Move a file or sub-directory
[*]f_chmod - Change attribute of a file or sub-directory
[*]f_utime - Change timestamp of a file or sub-directory
[*]f_mkdir - Create a sub-directory
[*]f_chdir - Change current directory
[*]f_chdrive - Change current drive
[*]f_getcwd - Retrieve the current directory and drive

[*]Volume Management and System Configuration

[*]f_mount - Register/Unregister the work area of the volume
[*]f_mkfs - Create an FAT volume on the logical drive
[*]f_fdisk - Create logical drives on the physical drive
[*]f_getfree - Get total size and free size on the volume
[*]f_getlabel - Get volume label
[*]f_setlabel - Set volume label
[*]f_setcp - Set active code page
2、RL-USB驱动的稳定性和兼容性比STM32F407自带的好很多很多,同样的板子,1个FAT16的1G TF卡转U盘,1个FAT32的8G TF卡转U盘,1个FAT32的16G U盘,RL-USB驱动时3个U盘随意插拔读写,没有出现1次不成功或者U盘不识别的。但是使用407自带的驱动,几乎每次都出现加载U盘驱动失败的情况,也有可能是我的驱动+FATFS移植的不好,造成407自带的USB驱动兼容性较差。



3、使用FSN_CM3.lib库时文件名是支持ASCII码格式的长文件名的,但是文件夹还是不支持长文件名,不知为什么

4、demo文件中 DemoFlashFS 函数存在板子上电时如果不插U盘,第一次插入时U盘时会出现U盘没有被挂载器问题(仿真发现是没有进行U盘初始化),拔出,第二次插入后就好了。我修改了这个问题,硬汉哥看看对不对。
void DemoFlashFS(void)
{
int8_t cmd = 0;
uint8_t con, con_ex;
uint8_t ucRunFlag=1;

/* 打印命令列表,用户可以通过串口操作指令 */
DispMenu();

con = InitUSB();
if(con)
{
    ucRunFlag = 0;//初始化成功后,后面就不用再初始化,2018-09-06
}
con_ex = con | 0x80;/* 首次上电强制执行一次if(con^con_ex)里面的内容 */

while (1)
{
    /* 断开连接后,此函数也会卸载资源 */
    usbh_engine(0);
    con = usbh_msc_status(0, 0);
    if (con ^ con_ex)
    {
      if (!con)
      {
      ucRunFlag = 1;//下次插入U盘后需要重新初始化一次,2018-09-06
      printf("U盘已经拔出\r\n");
      printf("------------------------------------------------------------------\r\n");
      }
      else
      {
      /* 系统上电首次运行和调用指令L后,不需要重复初始化 */
      if (ucRunFlag)
      {
          ucRunFlag = 0;
          con = InitUSB();
      }
      }
      con_ex = con;
    }

    cmd = getkey();
    if (cmd > 0)
    {
      switch (cmd)
      {
      case 'L':
          printf("【L - InitUSB】\r\n");
          con = InitUSB();/* U盘的挂载,卸载及其容量显示 */
          break;

      case 'U':
          printf("【U - UnInitUSB】\r\n");
          UnInitUSB();    /* U盘挂载,卸载及其容量显示 */
          break;

      case '1':
          printf("【1 - ViewSDCapacity】\r\n");
          ViewSDCapacity();   /* U盘挂载,卸载及其容量显示 */
          break;

      case '2':
          printf("【2 - ViewRootDir】\r\n");
          ViewRootDir();      /* 显示U盘根目录下的文件名 */
          break;

      case '3':
          printf("【3 - CreateNewFile】\r\n");
          CreateNewFile();      /* 创建三个text文本并使用不同函数写入内容 */
          break;

      case '4':
          printf("【4 - ReadFileData】\r\n");
          ReadFileData();         /* 使用三个不同函数读取文本*/
          break;

      case '5':
          printf("【5 - SeekFileData】\r\n");
          SeekFileData();         /* 创建一个text文本,在指定位置对其进行读写操作*/
          break;

      case '6':
          printf("【6 - DeleteDirFile】\r\n");
          DeleteDirFile();      /* 删除文件夹和文件*/
          break;

      case '7':
          printf("【7 - WriteFileTest】\r\n");
          WriteFileTest();      /* 测试文件读写速度*/
          break;

      case '8':
          printf("【8 - WriteCSVFile】\r\n");
          WriteCSVFile();         /* 写数据到CSV文件中*/
          break;

      case '9':
          printf("【9 - ReadCSVFileData】\r\n");
          ReadCSVFileData();      /* 从CSV文件中读数据*/
          break;
         
      default:
          DispMenu();
          break;
      }
    }

    os_dly_wait(1);
}
}


小狐狸 发表于 2018-9-6 17:49:13

刚写了600个文件,一切正常。每个文件夹中写60个文件,每个文件10K,写了10个文件夹



eric2013 发表于 2018-9-7 01:07:25

小狐狸 发表于 2018-9-6 17:49
刚写了600个文件,一切正常。每个文件夹中写60个文件,每个文件10K,写了10个文件夹

flashfs是采用的标准C库API,电脑端的文件系统也是这些API,你说的创建文件夹是支持的,长文件名应该也没问题的,使用库文件FS_CM3.lib,后面我试试文件夹的长文件名问题。

小狐狸 发表于 2018-9-7 10:31:06

eric2013 发表于 2018-9-7 01:07
flashfs是采用的标准C库API,电脑端的文件系统也是这些API,你说的创建文件夹是支持的,长文件名应该也没 ...

f_mkdir建立文件函数是哪个呢,在flashfs中,我就想单独的建立多个文件夹,暂时不先建立文件,怎么实现呢

eric2013 发表于 2018-9-7 10:50:39

小狐狸 发表于 2018-9-7 10:31
f_mkdir建立文件函数是哪个呢,在flashfs中,我就想单独的建立多个文件夹,暂时不先建立文件,怎么实现呢

函数fout = fopen ("N0:\\test\\", "w"); 就可以创建

小狐狸 发表于 2018-9-8 12:13:39

eric2013 发表于 2018-9-7 10:50
函数fout = fopen ("N0:\\test\\", "w"); 就可以创建

谢谢啦

没有专门的函数,这样实现也行

eric2013 发表于 2018-9-8 12:15:35

小狐狸 发表于 2018-9-8 12:13
谢谢啦

没有专门的函数,这样实现也行

C标准库没有mkdir函数的,就是靠这个函数创建的。

小狐狸 发表于 2018-9-8 12:30:19

eric2013 发表于 2018-9-8 12:15
C标准库没有mkdir函数的,就是靠这个函数创建的。

恩恩,谢谢
老大对这些研究的很透彻{:8:}{:8:}{:8:}

eric2013 发表于 2018-9-8 14:30:34

小狐狸 发表于 2018-9-8 12:30
恩恩,谢谢
老大对这些研究的很透彻

{:33:}

要努力_rSaUr 发表于 2018-10-30 11:31:19

挂载文件系统失败 (1:IO错误,I/O驱动初始化失败,或者没有存储设备,或者设备初始化失败)   怎么解决?

eric2013 发表于 2018-10-30 13:44:16

要努力_rSaUr 发表于 2018-10-30 11:31
挂载文件系统失败 (1:IO错误,I/O驱动初始化失败,或者没有存储设备,或者设备初始化失败)   怎么解决?

估计是没有移植成功。另外换几个U盘试试。

要努力_rSaUr 发表于 2018-10-30 15:17:06

eric2013 发表于 2018-10-30 13:44
估计是没有移植成功。另外换几个U盘试试。

找到原因了,是我自己的板子换成了8M晶振,配置没改:L,谢谢eric 大神

eric2013 发表于 2018-10-30 16:29:46

要努力_rSaUr 发表于 2018-10-30 15:17
找到原因了,是我自己的板子换成了8M晶振,配置没改,谢谢eric 大神

好的:handshake

吻云浩 发表于 2019-2-15 17:53:59

请教下eric RL_usb 和 RL_FLashFs现在有没有教程,或者什么时候嗯那个出来

eric2013 发表于 2019-2-15 17:55:47

吻云浩 发表于 2019-2-15 17:53
请教下eric RL_usb 和 RL_FLashFs现在有没有教程,或者什么时候嗯那个出来

看这个就行

http://www.armbbs.cn/forum.php?mod=viewthread&tid=2988&highlight=RL-CAN

younew 发表于 2019-5-12 00:31:51

测了2个USB3.0的u盘都不行啊!!(一个16G的,一个32G的)

eric2013 发表于 2019-5-12 02:25:46

younew 发表于 2019-5-12 00:31
测了2个USB3.0的u盘都不行啊!!(一个16G的,一个32G的)

3.0的话,务必格式化为FAT32格式,这样就木问题了。

takent 发表于 2019-8-9 11:33:56

我的开发板V6用SanDiskU盘8G识别不了,用V6-348-FreeRTOS实验_FreeRTOS+STemWin+FatFS+USB Host综合这个例程就可以识别,什么原因啊,RL-USB比ST 库还差?

takent 发表于 2019-8-9 15:20:54

看了注意事项才发现用FS接口的。我硬件仅有HS接口

eric2013 发表于 2019-8-9 15:50:43

takent 发表于 2019-8-9 15:20
看了注意事项才发现用FS接口的。我硬件仅有HS接口

对,使用的接口不同。

wlx18682353162 发表于 2020-9-22 15:51:50

MDK4.74编译STM32F107系列的USB HOST   
U盘读不成功   硬汉哥了解这个情况不

eric2013 发表于 2020-9-24 10:15:43

wlx18682353162 发表于 2020-9-22 15:51
MDK4.74编译STM32F107系列的USB HOST   
U盘读不成功   硬汉哥了解这个情况不

估计是哪里没有移植好。
页: [1] 2
查看完整版本: 【原创开源应用第5期】基于RL-USB+RL-FlashFS的外挂U盘解决方案