加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

FATFS移植—STM32+SDCARD

(2013-12-09 16:59:34)
标签:

fatfs

it

 

(测试环境:IAR540 + STM32F103VBT6 + SDCSPI方式) + ucOS-II + TFT(ILI9325) )

  FATFS官网:http://elm-chan.org/fsw/ff/00index_e.html

  下载最新版本FatFs R0.09 (November 14,2011)

  解压缩后有两个文件夹docsrc,把src拷贝到工程中,其中包括diskio.hff.cff.hinteger.hffconf.h

  diskio.hff.cff.hinteger.h四个文件都不需要修改,移植需要做的:(1)配置ffconf.h。(2)创建底层驱动diskio.c文件。

 

一、根据系统类型配置ffconf.h

_FFCONF是代表了版本号,不做处理。

  函数和缓冲区配置

_FS_TINY设置缓冲区的位置,假如设置为0,也就是每个文件(FIL结构体)中带一个buf,否则的话,整个文件系统公用一个buf。内存还是够的,所以选择为0

_FS_READONLY设置是否文件只读,系统需要可读写的,设置为0

_FS_MINIMIZE设置为0,因为以下的那些函数要用到,不简化。

_USE_STRFUNC设置是否使用字符串函数,主要有f_gets, f_putc, f_puts, f_printf四个函数,暂时不用,因为我们的数据都是自定义结构体的存储方式,为了节省空间这个设置为0

_USE_MKFS设置是否实现f_mkfs函数。我们需要在设备初始化时完全格式化Flash,所以此函数需要。

_USE_FORWORD设置

_USE_FASTSEEK设置是否支持文件快速定位,它主要采用缓冲区来存储簇链映射图,以空间换时间,对于我们系统不合算,还是采用普通定位方式好。

  本地化和命名空间配置

_CODE_PAGE设置目标系统的本地化设置,本系统有ASCII支持就足够了,支持本地化的情况下,模块的大小将大幅增加,反而不符合我们选择FatFs的初衷,所以选择1

_USE_LFN设置长文件名,我们系统不支持,设为0

_MAX_LFN不用设置,因为不支持长文件名。

_LFN_UNICODE设置长文件名是否支持Unicode,我们选择不支持,因为不支持长文件名。

_FS_RPATH设置相对路径支持。相对路径在编程的时候特别方便,但是为了先移植成功,暂不支持。

  物理驱动器配置

_VOLUMES设置逻辑驱动器的个数,默认为1

_MULTI_PARTITION设置是否多个分区。不分区,设为0

_USE_ERASE设置擦除扇区。在f_mkfsremove_chain两个函数中添加擦除的代码,设置为0

  系统配置

_WORD_ACCESS设置是否支持字访问。不支持。

_FS_REENTRANT设置是否重入。因为我们的系统文件访问不是很频繁,而且都是在一个任务中访问,所以不支持重入。

_FS_TIMEOUT超时设置。

_SYNC_t访问重入时的同步句柄。

_FS_SHARE设置文件共享,能同时被几个文件同时打开。设置为0

 

二、配置完成后,编译一下程序。此时编译是不会成功的,从错误提示中可见,缺少六个函数disk_initializedisk_writedisk_readget_fattimedisk_ioctldisk_status。这几个函数在diskio.h中有声明,是底层驱动的接口,需要创建diskio.c并自己编写这几个函数。

 

三、创建diskio.c。

  该次测试的SDCARD用的是SPI方式,关于SDCARD的读写和SPI的应用在该博客其它文章中有详细说明,这里就不多讲了,只对FATFS相关文件作说明。

(1)get_fattime——得到系统时间。可以从RTC中获取时间,作为测试,此处只是随便返回一个数。
DWORD get_fattime (void)
{
  return   ((DWORD)(2010 - 1980) << 25) 
     | ((DWORD)1 << 21)
     | ((DWORD)1 << 16)
     | ((DWORD)0 << 11)
     | ((DWORD)0 << 5)
     | ((DWORD)0 >> 1);
}

(2)disk_initialize——磁盘初始化。这里只用了一个卡,驱动器号为0即可。

DSTATUS disk_initialize (BYTE drv)
{
  while(SD_Init()!=0);  // SD_Init为SD卡初始化
  return 0;
}

(3)disk_status——获取磁盘状态。这里直接返回0,表示状态OK,以后再写

DSTATUS disk_status (
 BYTE drv   
)
{
  return 0;
}

(4)disk_ioctl——实现控制I/O的特性设置。这里直接返回0表示OK,以后再写
DRESULT disk_ioctl (
 BYTE drv,  
 BYTE ctrl,  
 void *buff  
)
{
  return RES_OK; 
}

(5)disk_read——磁盘读
DRESULT disk_read (
 BYTE drv,   
 BYTE *buff,   
 DWORD sector,  
 BYTE count   
)
 
  if(count>1)
    SD_ReadMultiBlock(sector, buff, count); 
  else
    SD_ReadSingleBlock(sector, buff);    
  return RES_OK; 
}

(6)disk_write——磁盘写
DRESULT disk_write (
 BYTE drv,   
 const BYTE *buff, 
 DWORD sector,  
 BYTE count   
)

  if(count>1)
    SD_WriteMultiBlock(sector, buff, count); 
  else
    SD_WriteSingleBlock(sector, buff); 
  return RES_OK;
}

 

四、编译程序成功。开始FATFS的API。
 FRESULT res;   
 FATFS fatfs;   
 FIL fil;    
 DIR dirs;    
 FILINFO finfo;   
 UINT br;
 BYTE buff[128];
 char  diskname[20] = {"newdir"};

disk_initialize(0);
f_mount(0, &fatfs);
res = f_mkdir(diskname);                                    // 新建文件夹,名为newdir
res = f_open(&fil, "123.txt", FA_OPEN_EXISTING | FA_READ);      // 打开123.txt 文件
if(res==FR_OK)
{
  res = f_read(&fil,buff,sizeof(buff),&br);  // 读文件
  for(i=0;i

    send_data(buff[i]);        // 通过串口把读到的数据送到PC,校验正确性
  f_close(&fil);             // 关闭文件
}
f_mount(0, NULL);


来源:http://flying-in-rain.blog.163.com/blog/static/131868594201206111953388/

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有