STM32的FATFS文件系统移植笔记
作者:
时间:2016-11-26
来源:网络
收藏
复制代码 MSD0_WriteSingleBlock()和MSD0_WriteMultiBlock()函数都是SD卡操作的底层函数,我们在SPI_MSD0_Driver.c文件中实现。
7、实现disk_ioctl()函数
该函数在磁盘格式化、获取文件系统信息等操作时会被调用。
实现后的程序如下:
本文引用地址:https://www.eepw.com.cn/article/201611/321826.htm- DRESULT disk_ioctl (
- BYTE drv, /* Physical drive nmuber (0..) */
- BYTE ctrl, /* Control code */
- void *buff /* Buffer to send/receive control data */
- )
- {
- if (drv==0)
- {
- MSD0_GetCardInfo(&SD0_CardInfo);
- switch (ctrl)
- {
- case CTRL_SYNC :
- return RES_OK;
- case GET_SECTOR_COUNT :
- *(DWORD*)buff = SD0_CardInfo.Capacity/SD0_CardInfo.BlockSize;
- return RES_OK;
- case GET_BLOCK_SIZE :
- *(WORD*)buff = SD0_CardInfo.BlockSize;
- return RES_OK;
- case CTRL_POWER :
- break;
- case CTRL_LOCK :
- break;
- case CTRL_EJECT :
- break;
- /* MMC/SDC command */
- case MMC_GET_TYPE :
- break;
- case MMC_GET_CSD :
- break;
- case MMC_GET_CID :
- break;
- case MMC_GET_OCR :
- break;
- case MMC_GET_SDSTAT :
- break;
- }
- }else if(drv==1){
- switch (ctrl)
- {
- case CTRL_SYNC :
- return RES_OK;
- case GET_SECTOR_COUNT :
- return RES_OK;
- case GET_SECTOR_SIZE :
- return RES_OK;
- case GET_BLOCK_SIZE :
- return RES_OK;
- case CTRL_POWER :
- break;
- case CTRL_LOCK :
- break;
- case CTRL_EJECT :
- break;
- /* MMC/SDC command */
- case MMC_GET_TYPE :
- break;
- case MMC_GET_CSD :
- break;
- case MMC_GET_CID :
- break;
- case MMC_GET_OCR :
- break;
- case MMC_GET_SDSTAT :
- break;
- }
- }
- else{
- return RES_PARERR;
- }
- return RES_PARERR;
- }
复制代码
MSD0_GetCardInfo()函数也在SPI_MSD0_Driver.c文件中实现,其中SD0_CardInfo为PMSD_CARDINFO类型的全局变量,它在SPI_MSD0_Driver.h文件中被定义。
8、到此diskio.c这个文件中的所有函数就已经实现,下一步就是实现SPI_MSD0_Driver.c文件中的相关函数,SPI_MSD0_Driver.c文件可以在网上下载,参考的程序比较多,本工程使用的这个文件也是在网上下载并进行一定的修改过的。本文件中函数的实现方式可以参考源代码。
五、文件系统测试
1、测试写文件
测试代码如下:
- //写文件测试
- printf("write file test......");
- res = f_open(&fdst, "0:/test.txt", FA_CREATE_ALWAYS | FA_WRITE);
- if(res != FR_OK){
- printf("open file error : %d",res);
- }else{
- res = f_write(&fdst, textFileBuffer, sizeof(textFileBuffer), &bw); /* Write it to the dst file */
- if(res == FR_OK){
- printf("write data ok! %d",bw);
- }else{
- printf("write data error : %d",res);
- }
- /*close file */
- f_close(&fdst);
- }
复制代码
注意:成功打开文件后一定要调用f_close()函数,否则数据无法写入SD卡中。
2、测试读文件
- //读文件测试
- printf("read file test......");
- res = f_open(&fsrc, "0:/test.txt", FA_OPEN_EXISTING | FA_READ);
- if(res != FR_OK){
- printf("open file error : %d",res);
- }else{
- res = f_read(&fsrc, buffer, sizeof(textFileBuffer), &br); /* Read a chunk of src file */
- if(res==FR_OK){
- printf("read data num : %d",br);
- printf("%s",buffer);
- }else{
- printf("read file error : %d",res);
- }
- /*close file */
- f_close(&fsrc);
- }
复制代码
3、测试结果
测试结果如图2所示。

图2
六、中文长文件名支持
1、要支持长文件名需要在ffconf.h文件中修改两个宏定义。如下为我们修改后的宏定义。
#define _CODE_PAGE 936
#define _USE_LFN 1 /* 0 to 3 */
2、添加支持中文编码的文件
重新编译会发现有如图3的错误。原因是要支持中文文件名需要包含另外一个文件cc936.c,该文件在FATFS文件系统源码的.srcoption目录下,将它添加到工程文件目录FATFS中。如图4是我们添加文件后的工程文件结构,再次编译就通过了。如图5所示。我们发现增加这个文件后代码量增加了很多,主要原因是这个文件是我们支持中文所需要的中文编码文件。

图3

图4

图5
3、再次下载到板子中运行,发现中文的长文件名显示正常了。如图6所示。

4、若不需要支持中文长文件名而只支持英文长文件名则可以将宏定义做如下修改:
#define _CODE_PAGE 437
#define _USE_LFN 1 /* 0 to 3 */
同时将ccsbcs.c添加到工程目录中,这样就可以减小很多大代码量。将程序下载板子后再次运行结果如图7所示,可以看到可以支持英文的长文件名。

七、源文件下载
STM32_FATFS_SPI.rar
技术专区
评论