拟用单片机CH579移植FATFS1.3便于数据管理,简要介绍移植的注意事项和误区。
需要准备的资料如下
)1) FATFS文件系统源代码FATFS1.3 )单击此处下载最新的FATFS源代码。
)2)一个单片机平台(CH579 )。
)3)一个SPI_FLASH芯片(例如W25Q16 )。
FATFS是一个通用的嵌入式文件系统,对不同平台支持好,大硬盘、u盘、存储卡、小spi_FLASH芯片甚至单片机内部的今天在2M大小的SPI_flash(w25q16 )上构建文件系统。 主控制器是CH579单片机。 在移植文件系统之前,必须打开用于操作SPI_FLASH的驱动程序,以便可以读写SPI_FLASH。
第一步,解压缩新下载的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是一个万国码编码文件,该文件主要包含大型数组定义。 如果需要文件名支持中文,则需要此文件。 此文件会急剧增加代码空间。 选项文件
第二步、由于这次的FATFS移植中没有使用操作系统,文件系统支持中文路径和名称,所以ff.c、ff.h、ffconf.h、diskio
第三步,修改ffconf.h文件并修剪FATFS,通过宏开关移除不必要的功能,从而简化文件系统。 你想知道每个宏的功能吗? (单击此处)
请注意,由于此次移植支持中文路径和名称,这是因为此宏#define FF_CODE_PAGE936 /*936支持简体中文*/
注:修改下图时,FF_MAX_SS的值必须始终与FLASH块的值相同。 我在这里误入歧途,试了半天。 那默认为512。 网络上的其他文档没有提示这里的修改。
在第四步中,按如下方式修改diskio.c以映射存储读写控制界面:
请参阅/---------------- -见
/* lowleveldiski/omoduleskeletonforfatfs (c ) ChaN,2016 */) /
请参阅/---------------- -见
/* ifaworkingstoragecontrolmoduleisavailable,it should be */
/* attachedtothefatfsviaagluefunctionratherthanmodifyingit.* /
/* thisisanexampleofgluefunctionstoattachvariousexsisting * /
/* storagecontrolmodulestothefatfsmodulewithadefinedapi.* /
请参阅/---------------- -见
# include ' ff.h '/* obtainsintegertypes * /
# include ' diskio.h '/* declarationsofdiskfunctions * /
#include 'SPIFlash.H '
/* definitionsofphysicaldrivenumberforeachdrive * /
# defines pi _ flash0/* example : mapramdisktophysicaldrive0* /
请参阅/---------------- -见
/*获取驱动器状态
*//*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if(pdrv == SPI_FLASH)
{
PRINT("!!!disk_status OKrn");
return RES_OK; //Ö±½Ó·µ»ØOK¼´¿É
}
else
{
PRINT("!!!disk_status ERRrn");
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if(pdrv == SPI_FLASH)
{
SPIFlash_Init();//³õʼ»¯spi flash
PRINT("!!!disk_initialize OKrn");
return RES_OK;
}
else
{
PRINT("!!!disk_initialize ERRrn");
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
PRINT("disk_read---sector:%d,count:%drn",sector,count);
if(pdrv == SPI_FLASH)
{
for(;count>0;count--)
{
ReadExternalFlash_SPI_DAN(sector*4096,4096,buff);//spi flashµÄ¶Áº¯Êý£¬×¢Òâ²ÎÊýÀàÐÍÒ»ÖÂ
sector++;
buff+=4096;
}
res = RES_OK; //ĬÈÏдÈëÕý³££¬¿ÉÒÔ¼Ó
return res;
}
else
{
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
PRINT("disk_write---sector:%d,count:%drn",sector,count);
if(pdrv == SPI_FLASH)
{
for(;count>0;count--)
{
EraseExternal4KFlash_SPI(sector*4096);
BlukWriteExternalFlash_SPI(sector*4096,4096,(uint8_t *)buff);//spi flashµÄдº¯Êý£¬×¢Òâ²ÎÊýÀàÐÍÒ»ÖÂ
sector++;
buff+=4096;
}
res=RES_OK;
return res;
}
else
{
PRINT("!!!disk_write ERRrn");
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
if (pdrv == SPI_FLASH)
{
switch (cmd)
{
case CTRL_SYNC:
return RES_OK;
/* ÉÈÇøÊýÁ¿ 1024*1024*1024 =4 (MB) */
case GET_SECTOR_COUNT:
*(DWORD * )buff = 512;spi flashµÄ¿é´óСÊÇ4K Bytes
// *(DWORD * )buff = 8*1024;//W25Q16 ÓÐ512´óСΪ4k bytesµÄÉÈÇø
return RES_OK;
/* ÉÈÇø´óС*/
case GET_SECTOR_SIZE :
*(WORD * )buff = 4096;//spi flashµÄ¿é´óСÊÇ4K Bytes
// *(WORD * )buff = 512;//spi flashµÄ¿é´óСÊÇ4K Bytes
return RES_OK;
/*¿é */
case GET_BLOCK_SIZE :
*(DWORD * )buff =1;
return RES_OK;
default:
return RES_PARERR;
}
}
else
{
PRINT("!!!disk_ioctl ERRrn");
return RES_PARERR;
}
}
DWORD get_fattime(void) {
// DWORD time;
return 0;
}
这里面一定注意,FLASH读写函数驱动的调用。很关键,决定是否能移植成功。