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文件生成,打开文件内容正确写入。

时间: 2024-10-15 19:36:52

NIOS2随笔——FAT32文件系统的相关文章

NIOS2随笔——JPEG解码与VGA显示

1. 系统概述 本设计采用NIOS2 32位处理器,通过SPI接口将SD/TF卡中的JPEG图片数据读取到内存中,SD/TF卡的文件系统为FAT32,NIOS2软件实现JPEG解码后,启动framereader和Clocked Video Output模块,最终在VGA显示器上显示JPEG图像,系统框图如下: 2. JPEG格式 JPEG(Joint Photographic Experts Group)是第一个国际图像压缩标准,提供了良好的压缩性能的同时,具有较好的图像质量,被广泛应用电子产品

FAT32文件系统学习(1) —— BPB的理解

FAT 32 文件系统学习 1.本文的目标 本文将通过实际读取一个FAT32格式的U盘来简单了解和学习FAT32文件系统的格式.虽然目前windwos操作系统的主流文件系统格式是NTFS,但是FAT32由于其兼容性原因,还是有一定的学习价值.为了能做出一个窗体程序提供直观的感觉,本文的代码采用c#编写,对应的c++代码也会附上. 2.本文目录 1.本文的目标 2.什么是FAT32 3.引导区 2.什么是FAT32 FAT32是Windwos系统硬盘格式分区的一种.这种格式采用32位的文件分配表,

FAT32文件系统学习(3) —— 数据区(DATA区)

FAT32文件系统学习(3) —— 数据区(DATA区) 今天继续学习FAT32文件系统的数据区部分(Data区).其实这一篇应该是最有意思的,我们可以通过在U盘内放入一些文件,然后在程序中读取出来:反过来也可以用程序在U盘内写入一下数据,然后在windows下可以看到写入的文件.这些笔者都会在这篇文章中演示.同时,在写这篇文章的时候笔者也发现了许多意想不到的规律. 1.本文目录 1.读取根目录 2.短文件名目录项 3.长文件名目录项 4.U盘写入文件夹 5.参考文献 2.读取根目录 两张FAT

FAT32文件系统--For TF卡

1. TF卡空间是如何分配的? 下面以4GB TF卡为例,通过WinHex工具进行分析,其空间分配如下图所示: FAT32把目录当做文件来管理,所以没有独立的目录区,所有的文件目录项都是在数据区里面的. 2. 启动扇区 (DBR) DBR(DOS BOOT RECORD,DOS引导记录),位于柱面0,磁头1,扇区1,即逻辑扇区0 ;    DBR包括: •  一个引导程序: DOS 引导程序完成DOS系统文件(IO.SYS,MSDOS.SYS)的定位与装载 • 一个BPB:  BPB用来描述本D

【转载】FAT32文件系统详解

硬盘是用来存储数据的,为了使用和管理方便,这些数据以文件的形式存储在硬盘上.任何操作系统都有自己的文件管理系统,不同的文件系统又有各自不同的逻辑组织方式.例如:常见的文件系统有FAT,NTFS,EXT,UFS,HFS+等等.作者后面的文章会一一讲到,下面就来学习一下基于Windows的FAT32文件系统. FAT32文件系统由DBR及其保留扇区,FAT1,FAT2 和 DATA 四个部分组成,其机构如下图: 这些结构是在分区被格式化时创建出来的,含义解释如下: DBR及其保留扇区:DBR的含义是

FAT32文件系统学习(2) —— FAT表

1.题外话 在继续本文学习FAT32文件系统之前,先来插入一点别的话题.我们都知道U盘有一个属性是容量,就拿笔者的U盘为例,笔者手上的U盘是金士顿的DataTraveler G3 4GB的一个U盘.电脑上显示的容量如图1所示为3.75GB.那么这个3.75GB是怎么计算出来的呢? 图 1 系统显示U盘属性 我们先来回顾一下上一篇BPB参数当中的Sectors(扇区总数)这个参数,这一参数代表了这个U盘在出厂时的总扇区数,笔者手上这个是7884672个,可以从图2中看到.其中每个扇区为512 B,

SD卡FAT32文件系统格式

一.SD卡FAT32文件系统 二.DBR(DOS BOOT RECORD,DOS引导记录) 1.DBR [1]0x00~0x02:3字节,"EB5890",跳转指令. [2]0x03~0x0A:8字节,文件系统标志和版本号,这里为MSDOS5.0. [3]0x0B~0x0C:2字节,每扇区字节数,512(0X02 00). [4]0x0D~0x0D:1字节,每簇扇区数,8(0x08),这个值不能为0,而且必须是2的整数次方,比如1.2.4.8.16.32.64.128. [5]0x0E

FAT32文件系统的存储组织结构(二)

前面已经基于一个格式化的空U盘分析了一下FAT32文件系统存储的组织结构,下面我们从文件操作的角度来分析一下文件系统的运作机制.由于换了个U盘,所以仍然贴出刚格式化的空U盘的几个重要的数据区如下:   我们可以看出,在分区格式化的时候,系统将卷标TEST_FAT32存储在2号簇,即跟目录区,如上面根目录贴图所示.同时,在FDT区2号簇标记位置写入了文件结束符FF FF FF 0F.显然,FAT32文件系统将目录当做普通文件来处理的. 下面我们在根目录下新建一个文件夹TEST1,看会有什么变化:

FAT32文件系统的存储组织结构(一)

对磁盘的物理结构,逻辑结构和存储结构有了比较深入的了解后,我们来仔细探讨FAT32文件系统的存储组织结构.说到文件系统的组织结构,我们应该马上意识到,这指的是文件系统在同一个分区内的组织结构,在这个话题上,我们完全可以不管分区之外的所有事情. 为了分析FAT32文件系统的存储组织结构,我们来建立一个实实在在的文件系统:将U盘插入电脑,将U盘格式化成FAT32分区格式: 以建好的U盘FAT32文件系统为基础,下面从文件系统的各个组成来分别加以介绍. 分区引导扇区DBR 用winhex打开U盘显示如