标签:nios2;fat32
1. 概述
FAT32是Windows系统硬盘分区格式的一种,最大单文件大小为4GB。
FAT32由下面3个部分组成:
MBR: Master Boot Record, 512KB, 硬盘的物理0地址,以0x55aa结束分区;
FAT: File Allocation Table, 512*2KB, 32位的文件分配表,最大单文件大小为4GB,以0x55aa结束分区;
File and Directory Data:数据与目录区域。
比如,一个42B的文件会占用2K=4个sector(512KB)。
2. FATFS源码介绍
FATFS是免费开源的FAT文件系统,特别适合小型嵌入式设备使用,FATFS支持FAT12/FAT16/FAT32。
FATFS文件系统结构:
FATFS源码文件如下表:
文件名  | 功能  | 说明  | 
ffconf.h  | FATFS模块配置文件  | 需要根据需求配置参数  | 
ff.h  | FATFS和应用模块公用的头文件  | 不修改  | 
ff.c  | FATFS模块源码  | 不修改  | 
diskio.h  | FATFS和disk I/O模块公用的头文件  | 不修改  | 
diskio.c  | FATFS和disk I/O模块接口层文件  | 与平台相关的代码,需要根据介质编写函数  | 
integer.h  | 数据类型定义  | 与编译器相关  | 
option文件夹  | 可选的外部功能  | 比如要支持汉字需要修改  | 
3. FATFS源码移植
FATFS移植的三个步骤
数据类型:在integer.h里面去定义好数据的类型
配置:通过ffconf.h配置FATFS的相关功能
函数编写:在diskio.c中进行底层驱动编写,一般需要编写5个函数disk_status, disk_initialize
disk_read, disk_write, disk_ioctl, get_fattime
在ffconf.h中,主要修改支持的函数齐全程度,支持的字体格式等。
#define _FS_MINIMIZE 0 /* This option defines minimization level to remove some basic API functions. / / 0: All basic functions are enabled. / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() / are removed. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 3: f_lseek() function is removed in addition to 2. */ #define _CODE_PAGE 1 /* This option specifies the OEM code page to be used on the target system. / Incorrect setting of the code page can cause a file open failure. / / 1 - ASCII (No extended character. Non-LFN cfg. only) / 437 - U.S. / 936 - Simplified Chinese (DBCS) */ #define _USE_LFN 0 #define _MAX_LFN 255 #define _LFN_UNICODE 0 /* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16) / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. / This option also affects behavior of string I/O functions. */
在diskio.c中,修改对应的驱动程序(SPI底层驱动查看博文"NIOS2随笔——SD卡之SPI操作
"),修改好的代码如下:
//filename: diskio.c
//author:   shugen.yin
//date:     2016.12.22
//function: FATFS Lower layer API
#include "diskio.h"		/* FatFs lower layer API */
#include "sd_spi.h"	
//初始化磁盘
DSTATUS disk_initialize (
	BYTE pdrv
)
{
	u8 res=0;	    
	res = SD_Initialize();//SD_Initialize()
	if(res)return  STA_NOINIT;
	else return 0; //初始化成功
}  
//获得磁盘状态
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber (0..) */
)
{ 
	return 0;
} 
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	UINT count		/* Number of sectors to read (1..128) */
)
{
	u8 res=0; 
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误		 	 
	res=SD_ReadDisk(buff,sector,count);
   //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res==0x00)return RES_OK;	 
    else return RES_ERROR;	   
}
#if _USE_WRITE
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber (0..) */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address (LBA) */
	UINT count			/* Number of sectors to write (1..128) */
)
{
	u8 res=0;  
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误		 	 
	res=SD_WriteDisk((u8*)buff,sector,count);
    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res == 0x00)return RES_OK;	 
    else return RES_ERROR;	
}
#endif
#if _USE_IOCTL
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;						  			     
	switch(cmd)
	{
		    case CTRL_SYNC:
				SD_CS_SET;
		        if(SD_WaitReady()==0)res = RES_OK; 
		        else res = RES_ERROR;	  
				SD_CS_CLR;
		        break;	 
		    case GET_SECTOR_SIZE:
		        *(WORD*)buff = 512;
		        res = RES_OK;
		        break;	 
		    case GET_BLOCK_SIZE:
		        *(WORD*)buff = 8;
		        res = RES_OK;
		        break;	 
		    case GET_SECTOR_COUNT:
		        *(DWORD*)buff = SD_GetSectorCount();
		        res = RES_OK;
		        break;
		    default:
		        res = RES_PARERR;
		        break;
	    }
    return res;
}
#endif
DWORD get_fattime (void)
{				 
	return 0;
}			 
//动态分配内存
void *ff_memalloc (UINT size)			
{
	return (void*)size;
}
//释放内存
void ff_memfree (void* mf)		 
{
}4. 搭建软硬件环境
这里沿用博文"NIOS2随笔——SD卡之SPI操作"中的工程,将TF卡(2GB)借SD卡套插入SD卡卡座,如下图所示:
编写main函数,最终编译运行:终端显示file write成功
5. 最终结果
用读卡器打开TF卡,HELLO.TXT文件生成,打开文件内容正确写入。
本文出自 “shugenyin的博客” 博客,请务必保留此出处http://shugenyin.blog.51cto.com/4259554/1885326
标签:nios2;fat32
原文地址:http://shugenyin.blog.51cto.com/4259554/1885326