有一次移植fatfs忘了很多东西,进行一次详细的记录。(主要是对本人自己记不清的地方查漏补缺,因此此贴不能当作教程使用。)
fatfs的下载链接 https://github.com/abbrev/fatfs 。将source内的文件都放入工程。
文件加入之后就是适配了,fatfs的适配主要工作是:ffconf.h的宏定义,disk.c的接口函数实现。
一:
配置ffconf.h内的宏定义,引用一个链接来描述(网上有很多就不再赘述)。
主要就是是否支持中文,块的字节数,长文件名,时间戳。
二:
disk.c的适配主要是五个函数的填充。
DSTATUS disk_initialize (BYTE pdrv ) /* Physical drive nmuber to identify the drive 初始化函数,一般放入储存设备初始化函数,放在其他地方的话直接返回0就可以了*/
DSTATUS disk_status (BYTE pdrv ) /* Physical drive nmuber to identify the drive 获取磁盘状态,一般读取ID检测是否与磁盘通信成功,可以直接返回0*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
读写函数都是相似的,主要解释一下参数的意思。drv是盘符,*buff是数据流地址,sector是起始地址(以扇区为单位)。count是数据流长度(以扇区为单位)。
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
解释参数:drv为盘符,cmd为命令,*buff为返回值。
这个上个例程就一目了然了
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE: //得到flash硬件 一个扇区的大小。单位为字节
*(WORD*)buff = 256;
res = RES_OK;
break;
case GET_BLOCK_SIZE: //得到flash硬件擦除的最小单元,单位为硬件扇区
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_SECTOR_COUNT: //得到flash有多少个扇区(ps:那么磁盘大小就可以算出来为SIZE*COUNT)
*(DWORD*)buff = 65536;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
以上就是移植的忽略点(记不详细)。然后再补充一点块设备的常识。
在操作系统里一般通用的名词是:SECTOR(扇区),BLOCK(块)。具体解释如下:
block:操作系统里可操作的最小单元,一般为4096,2048,1024*32等等,block的目的是为了包含不同规格的存储器。(举个栗子,文件系统把256,512等等扇区大小的存储器封装成统一块大小的磁盘,操作系统就不需要关注那些硬件细节了。)
在文件系统里通用的名词
sector:硬件里可写入的最小单元,有256,512(Byte)类型
block: 由于有些硬件写入和擦除的最小单元不一致,所以把sector当作最小写入单元,block当做最小擦除单元。(往往最小擦除单元大于最小写入单元且是整数倍关系,所以block就是最小可读写单元,符合操作系统上block的定义)
在flash硬件层面,就比较复杂,有PAGE(页),SECTOR(扇区),BLOCK(块),关系为,一个储存器由x个块组成,一个块由y个扇区组成,一个扇区由z个页组成,一页由m个字节组成。
PAGE(页):
SECTOR(扇区):
BLOCK(块):
NOR FLASH
可以随机读取写入,但是写入前需要先检查是否需要擦除。
擦除最小单元可能是sector或者page(取决于硬件组成)。
NAND FLASH
块Block,是Nand Flash的擦除操作的基本/最小单位
只支持按page读取写入,写入需要先按Block擦除,再按照page写入。