Flash基础入门:fatfs移植和使用(在SPI_FLASH上建立文件系统)
小标 2018-07-09 来源 : 阅读 2203 评论 0

摘要:本文主要向大家介绍了Flash基础入门的fatfs移植和使用,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。

本文主要向大家介绍了Flash基础入门的fatfs移植和使用,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。

文件系统对于嵌入式系统的重要性是不言而喻的,有了文件系统管理数据和外设变得方便许多,同时简化了应用的开发。今天我们来以在SPI_FLASH上建立文件系统为例,看看FATFS文件系统怎么移植和使用。

需要准备的材料有:

(1)FATFS文件系统源码(点此下载最新FATFS源码)。

(2)单片机平台一个(内存大一些更好)。

(3)SPI_FLASH芯片一个(如:W25Q32)。

FATFS是一个通用的嵌入式文件系统,对不同的平台支持很好,大到硬盘、U盘、存储卡,小到spi_flash芯片甚至单片机内部FLASH都可以使用FATFS。今天我们就在一个4M大小的SPI_FLASH( W25Q32 )上建立一个文件系统,主控制器是飞思卡尔K60单片机。在做文件系统移植前,你需要把操作SPI_FLASH的驱动调通,能读写SPI_FLASH就可以了。

step 0.1:下载最新的FATFS源码,当前版本:R0.13。

step 0.2 解压缩新下载的FATFS源码,看看里面都是些什么文件。如下图所示,红色框是移植FATFS所必须的文件,蓝色框内的文件是可选的移植文件。

diskio.c个diskio.h是和存储器读写控制相关的驱动接口,比如SPI_FLASH的读写函数接口,都要映射到这里面。必须的文件 

ff.h和ff.h是FATFS的核心文件,必须的文件

ffconf.h是FATFS的配置文件,用来裁剪FATFS,必须的文件

integer.h是FATFS所用到的数据类型定义,用以兼容不同字长CPU,必须的文件

ffsystem.c是一些关于在带操作系统平台中,使用的示例,可选文件

ffunicode.c是万国码编码文件,文件里主要是大数组定义,假如你需要让文件名支持中文就需要这个文件,这个文件会使代码空间急剧变大,可选文件

step 0.3 本次FATFS移植未使用操作系统,文件系统支持中文路径和名称,所以需要ff.c、ff.h、ffconf.h、diskio.c、diskio.h、ffunicode.c和integer.h这六个文件添加到工程中即可。

step 1.0 修改ffconf.h文件,来裁剪我们的FATFS,通过宏开关来去掉不用的功能,来精简文件系统。想知道每个宏的功能?(点击这里)

需要注意的是:由于我们此次移植支持了中文路径和名称,所以这个要设置这个宏    #define FF_CODE_PAGE936 /*936代表 简体中文*/

step 1.1 修改diskio.c 来映射我们的存储器读写控制接口,如下:

[objc] view plain copy

1. /*-----------------------------------------------------------------------*/  

2. /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */  

3. /*-----------------------------------------------------------------------*/  

4. /* If a working storage control module is available, it should be        */  

5. /* attached to the FatFs via a glue function rather than modifying it.   */  

6. /* This is an example of glue functions to attach various exsisting      */  

7. /* storage control modules to the FatFs module with a defined API.       */  

8. /*-----------------------------------------------------------------------*/  

9.   

10. #include "diskio.h"     /* FatFs lower layer API */  

11. #include "w25qxx.h"  

12. #include "debug.h"  

13.   

14. #define DISKIO_DEBUG 1  

15. #if defined DISKIO_DEBUG&&(DISKIO_DEBUG)  

16. #define diskio_printf  uart_printf  

17. #else  

18. #define diskio_printf(a,...)  

19. #endif  

20.   

21. /* Definitions of physical drive number for each drive */  

22. #define SPI_FLASH       0   /* Example: Map Ramdisk to physical drive 0 */  

23.   

24. /*-----------------------------------------------------------------------*/  

25. /* Get Drive Status                                                      */  

26. /*-----------------------------------------------------------------------*/  

27.   

28. DSTATUS disk_status (  

29.     BYTE pdrv       /* Physical drive nmuber to identify the drive */  

30. )  

31. {  

32.     if(pdrv == SPI_FLASH)   

33.     {  

34.         return RES_OK; //直接返回OK即可  

35.     }  

36.     else  

37.     {  

38.         diskio_printf("!!!disk_status ERR\r\n");  

39.         return RES_PARERR;  

40.     }  

41. }  

42.   

43.   

44.   

45. /*-----------------------------------------------------------------------*/  

46. /* Inidialize a Drive                                                    */  

47. /*-----------------------------------------------------------------------*/  

48.   

49. DSTATUS disk_initialize (  

50.     BYTE pdrv               /* Physical drive nmuber to identify the drive */  

51. )  

52. {  

53.     if(pdrv == SPI_FLASH)   

54.     {  

55.         w25qxx_init();//初始化 spi flash  

56.         return RES_OK;  

57.     }  

58.     else  

59.     {  

60.         diskio_printf("!!!disk_initialize ERR\r\n");  

61.         return RES_PARERR;  

62.     }  

63. }  

64.   

65.   

66.   

67. /*-----------------------------------------------------------------------*/  

68. /* Read Sector(s)                                                        */  

69. /*-----------------------------------------------------------------------*/  

70.   

71. DRESULT disk_read (  

72.     BYTE pdrv,      /* Physical drive nmuber to identify the drive */  

73.     BYTEBYTE *buff,     /* Data buffer to store read data */  

74.     DWORD sector,   /* Start sector in LBA */  

75.     UINT count      /* Number of sectors to read */  

76. )  

77. {  

78.     DRESULT res;  

79.     //uart_printf("disk_read---sector:%d,count:%d\r\n",sector,count);  

80.     if(pdrv == SPI_FLASH)   

81.     {  

82.         res = FS_SpiFlash_Read(buff,sector,count);<span style="font-family:Arial, Helvetica, sans-serif;">//spi flash的读接口,注意函数参数类型一致性</span>  

83.   

84.         return res;  

85.     }  

86.     else  

87.     {  

88.         diskio_printf("!!!disk_read ERR\r\n");  

89.         return RES_PARERR;  

90.     }  

91. }  

92.   

93.   

94.   

95. /*-----------------------------------------------------------------------*/  

96. /* Write Sector(s)                                                       */  

97. /*-----------------------------------------------------------------------*/  

98.   

99. DRESULT disk_write (  

100.     BYTE pdrv,          /* Physical drive nmuber to identify the drive */  

101.     const BYTEBYTE *buff,   /* Data to be written */  

102.     DWORD sector,       /* Start sector in LBA */  

103.     UINT count          /* Number of sectors to write */  

104. )  

105. {  

106.     DRESULT res;  

107.   

108.     if(pdrv == SPI_FLASH)   

109.     {  

110.         res = FS_SpiFlash_Write((uint8_t *)buff,sector,count);//spi flash的写接口,注意函数参数类型一致性  

111.         return res;  

112.     }  

113.     else  

114.     {  

115.         diskio_printf("!!!disk_write ERR\r\n");  

116.         return RES_PARERR;  

117.     }  

118. }  

119.   

120.   

121.   

122. /*-----------------------------------------------------------------------*/  

123. /* Miscellaneous Functions                                               */  

124. /*-----------------------------------------------------------------------*/  

125.   

126. DRESULT disk_ioctl (  

127.     BYTE pdrv,      /* Physical drive nmuber (0..) */  

128.     BYTE cmd,       /* Control code */  

129.     voidvoid *buff      /* Buffer to send/receive control data */  

130. )  

131. {  

132.     if (pdrv == SPI_FLASH)  

133.     {  

134.         switch (cmd)   

135.         {  

136.          case CTRL_SYNC:  

137.              return RES_OK;  

138.   

139.          /* 扇区数量 1024*1024*1024 =4 (MB) */  

140.   

141.          case GET_SECTOR_COUNT:  

142.   

143.              *(DWORDDWORD * )buff = 1024;//W25Q32 有1024个大小为4k bytes 的扇区  

144.              return RES_OK;  

145.   

146.          /* 扇区大小 */  

147.   

148.          case GET_SECTOR_SIZE :  

149.   

150.              *(WORDWORD * )buff = 4096;//spi flash的扇区大小是 4K Bytes  

151.              return RES_OK;  

152.   

153.          /*块大小 */  

154.   

155.          case GET_BLOCK_SIZE :  

156.              *(DWORDDWORD * )buff = 1;  

157.              return RES_OK;  

158.                

159.          default:  

160.              return RES_PARERR;  

161.          }  

162.     }  

163.     else  

164.     {  

165.         diskio_printf("!!!disk_ioctl ERR\r\n");  

166.         return RES_PARERR;  

167.     }  

168. }  

[objc] view plain copy

1. DWORD get_fattime(void)  

2. {  

3.     DWORD time;  

4.       

5.     /* 返回当前时间戳 */ <span style="font-family:Arial, Helvetica, sans-serif;">//暂不添加时间获取,需要的话就把RTC数据传入这里</span>  

[objc] view plain copy

1. <span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space:pre;"> </span></span>  

[objc] view plain copy

1. return 0;  

要修改的文件就这么多了,其他文件直接使用,不用改动。

step2.0  下面写个测试函数,来测测我们移植成功 了没有。

[objc] view plain copy

1. void fs_test(void)  

2. {  

3.     FATFS fs;           /* Filesystem object */  

4.     FIL fil;            /* File object */  

5.     FRESULT res;  /* API result code */  

6.     UINT bw;            /* Bytes written */  

7.     BYTE work[FF_MAX_SS]; /* Work area (larger is better for processing time) */  

8.     BYTE mm[50];  

9.     UINT i;  

10.       

11.     uart_printf("文件系统测试开始:\r\n");  

12.     /* 格式化文件系统 */  

13.     res = f_mkfs("0:", FM_ANY, 0, work, sizeof work);//"0:"是卷标,来自于 #define SPI_FLASH        0  

14.     if (res)  

15.     {  

16.         uart_printf("文件系统格式化失败.\r\n");  

17.         return ;  

18.     }  

19.     else  

20.     {  

21.         uart_printf("文件系统格式化成功.\r\n");  

22.     }  

23.     /* 挂载文件系统 */  

24.     res = f_mount(&fs, "0:", 0);  

25.     if (res)  

26.     {  

27.         uart_printf("文件系统挂载失败.\r\n");  

28.     }  

29.     else  

30.     {  

31.         uart_printf("文件系统挂载成功.\r\n");  

32.     }  

33.     /* Create a file as new */  

34.     res = f_open(&fil, "0:/测试文件.txt", FA_CREATE_NEW|FA_WRITE|FA_READ);  

35.     if (res)  

36.     {  

37.         uart_printf("打开文件失败.\r\n");  

38.     }  

39.     else  

40.     {  

41.         uart_printf("打开文件成功.\r\n");  

42.     }  

43.     /* Write a message */  

44.     res = f_write(&fil, "Hello,World!", 12, &bw);  

45.     //uart_printf("res write:%d\r\n",res);  

46.     if (bw == 12)  

47.     {  

48.         uart_printf("写文件成功!\r\n");  

49.     }  

50.     else  

51.     {  

52.         uart_printf("写文件失败!\r\n");  

53.     }  

54.     res = f_size(&fil);  

55.     uart_printf("文件大小:%d Bytes.\r\n",res);  

56.     memset(mm,0x0,50);  

57.     f_lseek(&fil,0);  

58.     res = f_read(&fil,mm,12,&i);  

59.     if (res == FR_OK)  

60.     {  

61.         uart_printf("读文件成功!\r\n");  

62.         uart_printf("读到数据长度:%d Bytes.\r\n",i);  

63.     }  

64.     else  

65.     {  

66.         uart_printf("读文件失败!\r\n");  

67.     }  

68.     uart_printf("读到如下数据:\r\n");  

69.     buff_print((charchar *)mm,12);  

70.     /* Close the file */  

71.     f_close(&fil);  

72.     /*卸载文件系统*/  

73.     f_mount(0, "0:", 0);  

74.     uart_printf("文件系统测试完毕.\r\n");  

step2.1  Congratulations!!!瞧, 我们成功了,尽情享用文件系统带来的便利吧。

[objc] view plain copy

以上就介绍了Flash的相关知识,希望对Flash有兴趣的朋友有所帮助。了解更多内容,请关注职坐标常用软件Flash频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程