你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

如何在 STM32 上使用 USB Host 读写 U 盘?

[复制链接]
gaosmile 发布时间:2020-4-1 18:47
微信图片_20200401184454.png
简介
USB(Universal Serial Bus)是一种支持热插拔的通用串行总线。它使用差分信号来传输数据,在 USB 1.0和 USB 1.1 版本中,只支持 1.5Mb/s 的低速(low-speed)模式和 12Mb/s 的全速(full-speed)模式,在 USB 2.0 中,又加入了480Mb/s 的高速模式,USB 3.0(super speed),传输速率最大5Gbps。, l- v3 I7 g" w7 c: x& X
在 USB 体系中又包括 USB Host(主机)和USB Device(设备)USB Host任何USB系统中只有一个主机。主机系统的USB接口被称为主机控制器。主机控制器可以以硬件,固件或软件的组合来实现。根集线器集成在主机系统内以提供一个或多个连接点。USB Device 可以分为 USB Hub 和 USB FunctionUSB Hub 提供了一种低成本、低复杂度的 USB接口扩展方法。Hub 的上行端口面向 HOST,下行端口面向设备(Hub 或功能设备)。在下行端口上,Hub 提供了设备连接检测和设备移除检测的能力,并给各下行端口供电。Hub 可以单独使能各下行端口。不同端口可以工作在不同的速度等级(高速/全速/低速)。USB Function 能够通过总线传输或接收数据或控制信息的设备,在 USB2.0 标准中,别称为 Class
! S; C2 c* K- m' g! r# k本文主要是基于正点原子 stm32f767-atk-apollo 开发板,给出了 USB Host 读写 U 盘的配置和使用示例。本文准备资料如下:
  • RT-Thread 源码
  • Env 工具
  • U 盘
    * d! H+ i; z% {5 s2 W( a
6 H6 h, a# r1 V, @; Z% g* n+ o, v+ L
依赖
  • RT-Thread 4.0.2+
  • RT-Thread 设备驱动框架
    / K6 k+ m6 [, a
* L% R; t# _# z. ]# U8 ~2 w8 K% D
硬件连接准备

本文是基于 U 盘的读写,所以需要准备好一个 U 盘,并插入开发板上的 U 盘接口。

ENV 配置
打开 USB Host: N3 S/ L" \. a- J2 u/ H- s; B' k

RT-Thread 可以很方便的通过 ENV 来配置和生成工程。在 rt-thread\bsp\stm32\stm32f767-atk-apollo 目录下打开 ENV 工具,使用 menuconfig 进入如下配置界面并选中。

1---- Hardware Drivers Config
; n* ]; W: F+ X7 R( @8 r2    ----On-Chip Peripheral Drivers
* r& a# H, P% W" U  \: I3        ----Enable USH Host6 U) R2 c9 n3 L* q
4            ----Enable Udisk Drivers
- n! |% n% {4 L% ]1 ~( Q( b

5 X; B) P6 L0 r. L- a
配置界面如下图所示

微信图片_20200401184502.png

打开文件系统

本文使用的是 USB Host 读写 U 盘的功能,所以需要打开 RT-Thread 的虚拟文件系统功能,打开文件系统的操作如下

1---- RT-Thread Components
: E. o7 ]' \( g. Z3 _2    ----Device virtual file system: x# ]. [" ^4 r5 N1 @
3        ----Using device virtual file system
5 S% o7 S# V& i& \& v! m& {; H
配置界面如下图所示

微信图片_20200401184506.png

生成工程并下载

在 ENV 中打开 USB Host 和虚拟文件系统的功能之后,工程配置就结束了,退出配置界面并保存。在 ENV 工具中使用 scons --target=mdk5 命令重新生成工程并打开。工程打开之后可以看到 USB Host 的框架代码和驱动代码都已经自动加入到工程里面了,如下图所示

微信图片_20200401184509.png

在 main.c 文件中加入以下测试代码并下载

(向右滑动查看全部代码)
: v) \, m, N8 y# d% T# k0 G

1#include <dfs_posix.h>
2 v, j7 F3 q/ ?/ L/ W 2#define TEST_FN     "/test_usbh.c"- p2 ~0 G5 }0 u( S/ N0 ?$ F7 o# Z
3static char test_data[120], buffer[120];
4 _6 F8 p% e" H' W, X 4, N! ?/ z5 c; R0 I7 m% A
5void readwrite(const char* filename)
' u7 A$ M  `4 S& S4 ^- b! ]: F3 @ 6
{# u8 h/ W5 w7 C1 j) ^( x, n1 d
7    int fd;
  B8 R+ R" V' Z: D1 s* D 8    int index, length;# Q. h; ~0 Z# n: I+ c4 o4 s
9
4 a5 S' w  x2 Z) p10    fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);4 K! J8 z  j# B# q0 T2 ~, c
11    if (fd < 0)
: f$ [" t& Q& y12    {
; a! n% W6 M# P  J7 R13        rt_kprintf("open file for write failed\n");
5 W+ {. f+ M0 E4 D1 R* i14        return;8 T' G2 [8 t8 H+ L$ w
15    }6 q9 C6 ]4 |# U% G
167 W  k$ ]4 M: e) A" a
17    for (index = 0; index < sizeof(test_data); index ++)
; X8 b) k' Y3 R: J" l7 N% j- ^18    {
& [9 w+ A- o7 u6 m, n7 h19        test_data[index] = index + 27;# C! E  b% O; _# G9 T! u
20    }
) b  E7 D2 f( J& c21) S+ s& m6 q" y7 l9 p
22    length = write(fd, test_data, sizeof(test_data));! A, d7 P/ [* X! G/ h; [
23    if (length != sizeof(test_data))/ S. {/ I/ q. Q( s4 N, S
24    {7 g! e3 I5 i4 v" h
25        rt_kprintf("write data failed\n");/ e4 {8 @& A" @# w) \$ c2 i
26        close(fd);
5 w( P/ m6 `/ `. K: e! ]7 Q) U27        return;
& d$ X2 Q7 [( q5 O+ O- e28    }
* V* U2 C- t' r29# I! E9 h: w. ^# f( D- L8 R) Z
30    close(fd);
0 N& ~  r1 p6 d9 l, f* @31
' U) R( o8 T( y) d8 l9 }7 Q32    fd = open(TEST_FN, O_RDONLY, 0);
4 H+ N" F, B% {4 a, W33    if (fd < 0)1 G" a$ t, T9 h. [* d( G$ K
34    {7 j' L0 `! q: Q3 e( h
35        rt_kprintf("check: open file for read failed\n");( Q( h% {: x: G. M# X0 ~- X
36        return;
0 d  f9 Z  C7 N* F0 X6 d. B37    }
' `3 y6 d. C5 V2 |- T/ p) c2 x) w; n38; V! `' `2 A0 s: K$ {
39    length = read(fd, buffer, sizeof(buffer));/ `& @9 s* D4 z" S
40    if (length != sizeof(buffer))
& u6 h* Z5 |; U. b8 E+ p+ q) ~41    {
. Q( O7 t. N1 A42        rt_kprintf("check: read file failed\n");
) h; ?- C) x7 S9 D& @43        close(fd);
( A& P: p2 E1 K: D. j44        return;
+ m; ]0 y, _2 f& b7 H: T+ i45    }
5 P# T5 A- L1 d8 Y2 B460 N. S$ m+ c. i* a6 Q
47    for (index = 0; index < sizeof(test_data); index ++)
- H% q: Y, s) a# ]: C48    {: `$ s0 G$ {8 S1 Q( ?& W
49        if (test_data[index] != buffer[index])4 \/ A+ i3 \- @9 w4 V/ y
50        {
7 u4 F! v; Z9 h51            rt_kprintf("check: check data failed at %d\n", index);
; c  t$ d; r. j% r6 Z9 @% n0 i52            close(fd);3 f2 b8 i' _- J( Y
53            return;2 Z6 F2 o2 E7 c( y6 D
54        }+ ^0 Y4 c3 j2 x5 y$ D- N8 v7 H! l
55    }( B% @2 D+ u, Z, K* _( y: Q! G
56
9 g6 S: j, D) V- D% N57    rt_kprintf("usb host read/write udisk successful\r\n");
* w  v" t, h/ _8 P7 {+ ^* h58
: m5 @6 }  i# H8 }  R  N4 {- m! p8 j59    close(fd);9 }- r  i# V/ M) j
60}
' {" J4 H' G$ u! f7 m1 F61% z5 m6 }, t+ P5 N; M
62MSH_CMD_EXPORT(readwrite, usb host read write test);
$ o3 Z* e  L" P# |

( a; g* g/ y5 Z" d/ B! ?( m1 [

运行测试程序3 X4 F: ^8 ^/ U& C

将以上程序下载入开发板之后连接串口调试工具可以看到如下调试信息

微信图片_20200401184512.png

这里可以看到 U 盘的大小约为 7.4G,说明 U 盘已经成功挂载到开发板上面的文件系统了。使用文件系统的 ls 命令查看 U 盘目录的结果如下图:

微信图片_20200401184515.png

在串口运行导出的 readwrite 测试函数的结果如下图所示 微信图片_20200401184518.png 再次使用 ls 命令可以看到在 U 盘的根目录下已经新建了一个 test_usbh.c 文件,并且大小为 120 个字节,如下图所示

微信图片_20200401184520.png

我们可以将 U 盘拔出并插在电脑上验证一下我们刚才写入的文件。

微信图片_20200401184524.png

从电脑上我们可以看到已经成功创建了一个 test_usbh.c 的文件。到这一步为止,在 STM32 上使用 USB Host 读写 U 盘的介绍就结束了
收藏 1 评论0 发布时间:2020-4-1 18:47

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版