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

5分钟用STM32的内置Flash做一个超小U盘

[复制链接]
萧星-96138 发布时间:2010-4-6 18:16
5分钟用STM32的内置Flash做一个超小U盘9 ]9 G3 Q2 u. b) l. H2 n& t+ B$ U
可以用来实现驱动的自动安装功能,或是通过Ini文件配置硬件4 T8 O- A# c1 g. i9 F$ W4 N
Build a mini U-Disk in STM32 in 5 minutes, W& `+ [, y" \/ l* x
Install device driver automatically
; U: R2 c8 k: Q3 d5 o) q' c& [Or config hardware through visiable ini file& g- f) V1 H8 r+ p; P  |
开发环境6 w5 @1 d) |8 ~3 C# o
IDE&Compiler    IAR 4.42 32K 限制版
" |$ {5 j- ?* h! ?USB固件库       2.017 u2 D6 i( Z- {# y% D
硬件            万利199元开发板  STM3210B-LK1
- `" w+ @7 M$ O! V( Z# i) D% e2 N5分钟要实现一个完整的Usb Mass Storage功能是不现实的,好在网络如此发达,并不是每件事情都需要从轮子做起。& s  K3 i. A/ b: _" A$ T* I
ST的官方网站的UM0424中有一个关于使用STM32做Mass Storage的例子,这个mini U盘就是根据这个例子修改而来的: b# j: i; H, m# b/ Z8 t
ST官网的库已经更新到3.0,我用的UM0424是2.20的,故在上传了这个老版本的库
6 w& \9 b1 _+ Q4 g这个库中没有任何关于文件系统的代码,即文件系统的实现都是由操作系统完成的,这个库中只需要对操作系统发过来的读取与写入命令负责即可。1 C7 g4 G. G# _
库中的mass_mal.c为文件系统与存储介质的访问接口(Medium Access Layer interface),负责将文件存储在实际的介质上,如NAND-Flash,SD卡等6 h5 o, ~+ s7 X# |1 O& j9 R( ]) k1 c
我们需要把文件存储在STM32的内部Flash中,因此更改这里的接口即可
" k) @6 l: U. ?4 I7 G' Dmass_mal向外提供了四个函数
% a% t2 n; w7 s2 L5 \/ Uu16 MAL_Init (u8 lun);% J8 ]" p8 q/ Y  \
初始化介质,由于是内部Flash,为了能写入,只需Unlock FLASH2 c+ }! r% e0 n8 T6 a, g- G, `9 ?; S
u16 MAL_GetStatus (u8 lun);
6 V& R! J. }' f0 r: K; o  c8 }读取介质的参数,页大小,总页数,以及总大小,这个视STM32的内Flash情况而定,为文件系统format介质提供依据+ }) T; j5 k& j" e" {
u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length);4 q4 o- r1 h9 E; N
读取介质上的一块区域8 `1 b# d4 ^5 i, N
u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length);0 h/ `$ v* j: S, @- C
写入介质上的一块区域
" Q) W/ ~* P! F/ z这里的Memory_Offset是从零偏移开始的,用作U盘的STM32内部Flash需要从代码之后开始$ J3 e+ E4 W5 }6 z3 L0 F
我这里编译结束后代码在0x0800252B,取mini U盘开始地址为0x08003000/ i  j+ H! A4 K1 G1 S/ U
万利板上的芯片为103VBT6,Flash为64K,还剩余52K即0xD000,每一页为1K
! ~1 f, f2 ^: z0 }根据以上信息,mass_mal更改为:" S9 S4 u1 R8 ~1 r
- Z* B5 W# m9 ~  E* v, Y' p* L3 ~
/*0001*/ #include "platform_config.h"   c4 |7 A  s9 B8 @9 A
/*0002*/ #ifdef USE_STM3210E_EVAL   H" H6 |9 a* Y  T  @
/*0003*/ #include "sdcard.h" ! s6 i' E0 E7 }- p# o5 B
/*0004*/ #else / X# e) \6 L4 i4 F- y/ Q; V5 O/ D
/*0005*/ #include "msd.h" / T: o+ Z0 \8 ^3 Z3 D6 ~
/*0006*/ #endif ! N. v; K. b2 ^' ^* L
/*0007*/ #include "fsmc_nand.h"
# P8 L% ?8 c3 W# K% j/*0008*/ #include "nand_if.h"
3 w- T" e8 P, A! R; \% M/*0009*/ #include "mass_mal.h"
  E- v$ i/ j- B( B- F' f9 X3 a6 q/*0010*/
! D/ b" k& |! {. G0 O  T/ O/*0011*/ /* Private typedef -----------------------------------------------------------*/
+ u# s3 R# E) ^. w( t" z8 ?- [1 S/*0012*/ /* Private define ------------------------------------------------------------*/ 4 f" `% g+ h0 E, b. x3 ]9 k
/*0013*/ #define     FLASH_START_ADDR        0x08003000    // Flash start address
3 r: G0 v7 C) o2 q* K+ `/*0014*/ #define     FLASH_SIZE              0xD000        // 
4 g% O& \* |8 E2 i7 J' g# E# b7 |7 m/*0015*/ #define     FLASH_PAGE_SIZE         0x400         // 1K per page
; B! V' A9 W. A/*0016*/ #define     FLASH_WAIT_TIMEOUT      100000 0 V8 i) t6 {+ F7 |$ p. B( }, I
/*0017*/ # Z, r% `& A$ Q! g1 v( u5 R7 v
/*0018*/ /* Private macro -------------------------------------------------------------*/
  i- y- A: i2 Q4 R* C/*0019*/ /* Private variables ---------------------------------------------------------*/ 4 W% i" E! d& n7 A7 e( E! o
/*0020*/ u32 Mass_Memory_Size[2];
8 C9 t5 r1 e2 Z1 \! Q5 Z- W/*0021*/ u32 Mass_Block_Size[2]; . u$ s+ A% l. o
/*0022*/ u32 Mass_Block_Count[2];
' W3 u8 w0 _. J" h, I; S/*0023*/ 9 D0 v# O- h: ~( v8 n0 Y0 O! k
/*0024*/ u16 MAL_Init(u8 lun)
, F' l: L, k3 S  V/*0025*/ {
- R& C. t" {# T0 o; o/*0026*/   FLASH_Unlock();
" y" Y: z& @3 Y6 U0 H& y/*0027*/   return lun == 0 ? MAL_OK : MAL_FAIL; + d) Q4 M& S" ?4 d% A# n9 g
/*0028*/ }
  I7 A$ [* Y) e! N% o" V/*0029*/
3 j- z: `3 c1 D7 R" ]( i8 z4 ?  D/ U/*0030*/ u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length)
- p0 Q% B& a1 e1 q& j+ H8 n/*0031*/ { 9 i" Z" C7 J, k/ f) ~* m% M8 W# x
/*0032*/   if(lun == 0){   d9 v9 U# s0 i  v7 `
/*0033*/     for(u16 i=0; i2]);
# b0 n# ]/ ?. t/*0044*/     } 8 |" Y4 p% q6 E+ q
/*0045*/     return MAL_OK;
% z1 g, t1 k1 O" h; h" q* S5 ^/ w/*0046*/   }
( ]& j! ~" `5 }/ A0 o/*0047*/   return MAL_FAIL; / a6 m7 H# X2 q
/*0048*/ } - Y7 ?/ L8 J( y/ \. n, e
/*0049*/ ; ~* R) y3 z9 y8 R) s- J
/*0050*/ u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length)
. ?9 v. u- ?# j  B3 [0 [0 ]/*0051*/ {
6 y1 ?6 p0 _  b' s3 D/*0052*/   if(lun == 0){ # R7 `" s* g% E* C! m. a4 Y
/*0053*/     for(u16 i=0;i>2] = ((vu32*)(FLASH_START_ADDR + Memory_Offset))[i>>2]; ) Y* m' f8 N( s  v/ [) x
/*0055*/     }
) R1 `9 w4 o% m1 U: w, o" l/ K- ~: A/*0056*/     return MAL_OK; ! t7 w9 t2 t+ i
/*0057*/   }
1 A3 e* a  [5 z8 q! q) F  B/*0058*/   return MAL_FAIL;
; y& i/ Q0 ?& I; Q/*0059*/ }
- l. u8 G6 s( ]9 }9 _4 B& k+ |/*0060*/
2 A, z% O, `2 R+ l" N* L9 s/*0061*/ u16 MAL_GetStatus (u8 lun)   }3 I; u5 d& `) r
/*0062*/ {
, g5 l! Q3 y! V: @3 M& G/*0063*/   if(lun == 0){
5 P' q! O; F$ N. |, ^9 ]/*0064*/     Mass_Block_Count[0] = FLASH_SIZE/FLASH_PAGE_SIZE; # d+ [+ Z! p' l9 U
/*0065*/     Mass_Block_Size[0] =  FLASH_PAGE_SIZE;
7 V( q( o  A' V  N8 Z4 Z8 i( ~/ f' u/*0066*/     Mass_Memory_Size[0] = FLASH_SIZE; # J2 I8 {6 t4 b9 D
/*0067*/     GPIO_SetBits(USB_LED_PORT, GPIO_Pin_7); ; v3 I7 H+ x1 q9 O1 ]4 W
/*0068*/     return MAL_OK;
3 a& A1 z1 l) f/ h% _% T/*0069*/   }
/ d- s( y$ y! u0 }" m/*0070*/   GPIO_ResetBits(USB_LED_PORT, GPIO_Pin_7);
* I- J4 t. x/ Y1 t& t2 a/*0071*/   return MAL_FAIL; ! A* t& X0 H4 t2 O
/*0072*/ } ) u" h2 Q2 d$ f) Q# m# P
/*0073*/

9 |3 A0 {$ Z/ \( {4 J: j6 k' Y* V7 z0 H) z9 I: X& C% g: z
改好了之后文件的存储目标就变成了STM32的内部Flash" v* U4 P# c8 Y6 C
实际运行中还有一个问题,那就是在memory.c中Data_Buffer定义大小为512Bytes,这里我们的Flash是1K一页,要将Data_Buffer重新定义成1KBytes的+ U& _# Y2 g$ q
u32 Data_Buffer[BULK_MAX_PACKET_SIZE *4]; /* 1024 bytes*/

/ x1 V& E8 N9 u* V) Q# |# p编译好后烧到板子上,电脑会提示格式化磁盘,格式化后就可以像一般的U盘那样使用这个mini U盘了
1 I) M/ n4 n( @. H虽然小了点,但是装个驱动程序、写点广告什么的还是够用了6 H* n0 \; F' a8 Y
想要的文件放好后可以将写入Flash的代码去掉,这样可以避免用户修改内容
0 e. F7 }: G* ? 
赞 收藏 评论0 发布时间:2010-4-6 18:16

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版