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

2009-11-6 20:02 13561 7 14 分类: 软件与OS

5分钟用STM32的内置Flash做一个超小U盘
可以用来实现驱动的自动安装功能,或是通过Ini文件配置硬件
Build a mini U-Disk in STM32 in 5 minutes
Install device driver automatically
Or config hardware through visiable ini file


开发环境
IDE&Compiler    IAR 4.42 32K 限制版
USB固件库       2.01
硬件            万利199元开发板  STM3210B-LK1


5分钟要实现一个完整的Usb Mass Storage功能是不现实的,好在网络如此发达,并不是每件事情都需要从轮子做起。
ST的官方网站的UM0424中有一个关于使用STM32做Mass Storage的例子,这个mini U盘就是根据这个例子修改而来的
ST官网的库已经更新到3.0,我用的UM0424是2.20的,故在上传了这个老版本的库zip


这个库中没有任何关于文件系统的代码,即文件系统的实现都是由操作系统完成的,这个库中只需要对操作系统发过来的读取与写入命令负责即可。
库中的mass_mal.c为文件系统与存储介质的访问接口(Medium Access Layer interface),负责将文件存储在实际的介质上,如NAND-Flash,SD卡等
我们需要把文件存储在STM32的内部Flash中,因此更改这里的接口即可
mass_mal向外提供了四个函数
u16 MAL_Init (u8 lun);
初始化介质,由于是内部Flash,为了能写入,只需Unlock FLASH


u16 MAL_GetStatus (u8 lun);
读取介质的参数,页大小,总页数,以及总大小,这个视STM32的内Flash情况而定,为文件系统format介质提供依据


u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length);
读取介质上的一块区域


u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length);
写入介质上的一块区域


这里的Memory_Offset是从零偏移开始的,用作U盘的STM32内部Flash需要从代码之后开始
我这里编译结束后代码在0x0800252B,取mini U盘开始地址为0x08003000
万利板上的芯片为103VBT6,Flash为64K,还剩余52K即0xD000,每一页为1K
根据以上信息,mass_mal更改为:



/*0001*/ #include "platform_config.h"
/*0002*/ #ifdef USE_STM3210E_EVAL
/*0003*/ #include "sdcard.h"
/*0004*/ #else
/*0005*/ #include "msd.h"
/*0006*/ #endif
/*0007*/ #include "fsmc_nand.h"
/*0008*/ #include "nand_if.h"
/*0009*/ #include "mass_mal.h"
/*0010*/
/*0011*/ /* Private typedef -----------------------------------------------------------*/
/*0012*/ /* Private define ------------------------------------------------------------*/
/*0013*/ #define     FLASH_START_ADDR        0x08003000    // Flash start address
/*0014*/ #define     FLASH_SIZE              0xD000        // 
/*0015*/ #define     FLASH_PAGE_SIZE         0x400         // 1K per page
/*0016*/ #define     FLASH_WAIT_TIMEOUT      100000
/*0017*/
/*0018*/ /* Private macro -------------------------------------------------------------*/
/*0019*/ /* Private variables ---------------------------------------------------------*/
/*0020*/ u32 Mass_Memory_Size[2];
/*0021*/ u32 Mass_Block_Size[2];
/*0022*/ u32 Mass_Block_Count[2];
/*0023*/
/*0024*/ u16 MAL_Init(u8 lun)
/*0025*/ {
/*0026*/   FLASH_Unlock();
/*0027*/   return lun == 0 ? MAL_OK : MAL_FAIL;
/*0028*/ }
/*0029*/
/*0030*/ u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length)
/*0031*/ {
/*0032*/   if(lun == 0){
/*0033*/     for(u16 i=0; i<Transfer_Length;i+=FLASH_PAGE_SIZE){
/*0034*/       if(FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT)!=FLASH_TIMEOUT){
/*0035*/         FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
/*0036*/       }
/*0037*/       FLASH_ErasePage(FLASH_START_ADDR + Memory_Offset + i);
/*0038*/     }
/*0039*/     for(u16 i=0;i<Transfer_Length;i+=4){
/*0040*/       if(FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT)!=FLASH_TIMEOUT){
/*0041*/         FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
/*0042*/       }
/*0043*/       FLASH_ProgramWord(FLASH_START_ADDR + Memory_Offset + i , Writebuff[i>>2]);
/*0044*/     }
/*0045*/     return MAL_OK;
/*0046*/   }
/*0047*/   return MAL_FAIL;
/*0048*/ }
/*0049*/
/*0050*/ u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length)
/*0051*/ {
/*0052*/   if(lun == 0){
/*0053*/     for(u16 i=0;i<Transfer_Length;i+=4){
/*0054*/       Readbuff[i>>2] = ((vu32*)(FLASH_START_ADDR + Memory_Offset))[i>>2];
/*0055*/     }
/*0056*/     return MAL_OK;
/*0057*/   }
/*0058*/   return MAL_FAIL;
/*0059*/ }
/*0060*/
/*0061*/ u16 MAL_GetStatus (u8 lun)
/*0062*/ {
/*0063*/   if(lun == 0){
/*0064*/     Mass_Block_Count[0] = FLASH_SIZE/FLASH_PAGE_SIZE;
/*0065*/     Mass_Block_Size[0] =  FLASH_PAGE_SIZE;
/*0066*/     Mass_Memory_Size[0] = FLASH_SIZE;
/*0067*/     GPIO_SetBits(USB_LED_PORT, GPIO_Pin_7);
/*0068*/     return MAL_OK;
/*0069*/   }
/*0070*/   GPIO_ResetBits(USB_LED_PORT, GPIO_Pin_7);
/*0071*/   return MAL_FAIL;
/*0072*/ }
/*0073*/


改好了之后文件的存储目标就变成了STM32的内部Flash


实际运行中还有一个问题,那就是在memory.c中Data_Buffer定义大小为512Bytes,这里我们的Flash是1K一页,要将Data_Buffer重新定义成1KBytes的
u32 Data_Buffer[BULK_MAX_PACKET_SIZE *4]; /* 1024 bytes*/

编译好后烧到板子上,电脑会提示格式化磁盘,格式化后就可以像一般的U盘那样使用这个mini U盘了
虽然小了点,但是装个驱动程序、写点广告什么的还是够用了
想要的文件放好后可以将写入Flash的代码去掉,这样可以避免用户修改内容

文章评论7条评论)

登录后参与讨论

用户1667055 2015-5-30 18:55

直接下载的程序里面不是用stm32内部flash的??

用户1683831 2012-2-29 09:54

楼主,我也是格式化老通不过,在网上搜索了半天,好像还真没有详细的解释,有一些疑问想请教你一下,可否加一下qq,2449633872

用户1505000 2011-3-11 10:28

多谢啊,搞定了,方法可行

用户1505000 2011-3-9 08:44

按博主的方法试了一下,不行啊,老是格式化不能通过,显示大小为零。怎么联系啊,我的qq24717275

用户20718 2010-9-30 14:58

谢谢楼主,我QQ516160826,还有一些疑问想请教,可否加为好友?

tengjingshu_112148725 2010-4-9 00:31

博主真牛啊

sunke9_998892717 2010-3-9 08:22

好东西肯定能用得上,以后仔细研究。
相关推荐阅读
用户236335 2011-05-16 17:36
[原创]操作DS18B20的程序(C写的 带ROMSearch和CRC校验)
调试环境:MPLAB 7.5PICC  8.05 PL1PIC16F88,DS18B20 两颗,晶振4MHz(如换其它晶振,需要更改WriteBit和ReadBit中的等待操作以及延时函数)我只有两颗...
用户236335 2011-04-08 09:17
[原创]用PIC10F200实现三色LED亮度调节
10F200资源:一个8位timer,一个WDT可以工作在 2.0~5.5V内置晶振,单一频率4MHz 精度1%三个IO,一个Input指令空间: 255目标:使用串口通讯方式,波特率38400,8位...
用户236335 2010-04-09 16:35
[原创]DIY一个多功能手柄
打造一个属于自己的多功能手柄多功能手柄的视频演示http://v.youku.com/v_show/id_XMTYyOTcwNjUy.html预览小结:芯片: STM32F103C8T6,MMA726...
用户236335 2010-04-09 14:12
[原创]STM32迷你OLed显示屏
之前买了几块128X64的OLed屏,用开发板驱动起来玩了一下,感觉显示效果还蛮不错的去赛格逛的时候又看到了这么一个小盒子,比划了一下觉得把这个屏放进去还能加点东西在上面盒子内部大小为44mm X 2...
用户236335 2010-04-07 23:28
FPM不能使用?(Foot Print Maker)别急,那是作者的小玩笑
用Candence来画PCB很不错,但是做封装很麻烦还好有人做了一个免费的小软件FPM(Foot Print Maker),用来生成封装很方便但是作者开了个小玩笑,0.0.8.0版本的从2010年4月...
用户236335 2010-03-28 15:57
[原创]用STM32 199元的开发板来玩俄罗斯方块
开发板是万利的那个带有ST-Link2的199开发板  STM3210B-LK1上面有一块STM32F103VBT6,这个片子有128K的Flash,20K的RAM开发板上面可以用到的资源·1 个LC...
我要评论
7
7
关闭 站长推荐上一条 /2 下一条