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的,故在上传了这个老版本的库
这个库中没有任何关于文件系统的代码,即文件系统的实现都是由操作系统完成的,这个库中只需要对操作系统发过来的读取与写入命令负责即可。
库中的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的代码去掉,这样可以避免用户修改内容
用户1667055 2015-5-30 18:55
用户1683831 2012-2-29 09:54
用户1505000 2011-3-11 10:28
用户1505000 2011-3-9 08:44
用户20718 2010-9-30 14:58
tengjingshu_112148725 2010-4-9 00:31
sunke9_998892717 2010-3-9 08:22