D3嵌入式文件系统FatFs
3.1FAT32文件分配表引入
3.1.1为什么需要文件系统
浏览器如何从服务器获取网页
文件系统的作用
3.1.2磁盘工作原理
硬盘容量 = 盘面数 × 柱面数 × 扇区数 × 512字节
SD卡存储结构
SD卡操作流程
read
/* @brief Reads Sector(s)
* @param lun : not used
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
wirte
/* @brief Writes Sector(s)
* @param lun : not used
* @param *buff: Data to be written
* @param sector: Sector address (LBA)
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count);
3.1.3Fat32文件分配表
文件系统如何管理磁盘
window下文件系统
FAT12/FAT16/FAT32
exFAT
NTFS
Linux下文件系统
ext2/ext3
NFS
jffs2
yaffs
磁盘管理工具
以管理员身份打开
FAT32存储结构
3.2FAT32文件文件存储原理
3.2.1FAT32怎么管理数据
簇---- 文件存储的最小单元
文件信息
100kb空间如何管理文件
分配方案
目录分配方案
当文件需要删除/增加
3.2.2 文件信息FAT32FAT表
添加FAT表
FAT表格式
采用链式结构管理文件的时序逻辑
FAT表解决文件删除/添加问题
FAT32存储原理
3.2.3FAT32表项及目录
FAT表取值
FAT目录项
短文件名目录项
长文件名目录项
3.3FatFs介绍及配置
3.3.1FatFS介绍
官方网站
http://elm-chan.org/fsw/ff/00index_e.html
应用接口
介质访问接口
相关资源
3.3.2STM32Cube集成FatFS
FatFS中间件模块架构
FatFS配置
1. 打开FatFS
2. 使能磁盘为SD卡
3. 配置中文编码
4. 配置命名空间为HEAP
1. 增大C库堆空间
3.3.3 FatFS示例代码
uint8_t u8chr[] = "hello";
uint32_t u32Wbytes;
/* USER CODE END Variables */
void MX_FATFS_Init(void)
{
/*## FatFS: Link the SD driver ###########################*/
retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
/* USER CODE BEGIN Init */
if(f_mount(&SDFatFS,SDPath,1) == FR_OK)
{
if(f_open(&SDFile,(const char*)"fatfs.txt",FA_CREATE_ALWAYS|FA_WRITE) == FR_OK)
{
if(f_write(&SDFile,u8chr,sizeof(u8chr),&u32Wbytes) == FR_OK)
{
f_close(&SDFile);
}
}
}
/* additional user code for init */
/* USER CODE END Init */
}
3.4FatFs应用编程上
3.4.1FstFs提供的应用接口
3.4.2API学习方法
学习步骤
项目当中用到的API
f_mkfs //物理磁盘的格式
f_mount
f_open
f_read
f_write
f_size
f_close
3.4.3API分析
f_mkfs
FRESULT f_mkfs (
const TCHAR* path, /* [IN] Logical drive number */
BYTE opt, /* [IN] Format options */
DWORD au, /* [IN] Size of the allocation unit */
void* work, /* [-] Working buffer */
UINT len /* [IN] Size of working buffer */
);
f_mount
FRESULT f_mount (
FATFS* fs, /* [IN] File system object */
const TCHAR* path, /* [IN] Logical drive number */
BYTE opt /* [IN] Initialization option */
);
f_open
FRESULT f_open (
FIL* fp, /* [OUT] Pointer to the file object structure */
const TCHAR* path, /* [IN] File name */
BYTE mode /* [IN] Mode flags */
);
f_close
FRESULT f_close (
FIL* fp /* [IN] Pointer to the file object */
);
f_read
FRESULT f_read (
FIL* fp, /* [IN] File object */
void* buff, /* [OUT] Buffer to store read data */
UINT btr, /* [IN] Number of bytes to read */
UINT* br /* [OUT] Number of bytes read */
);
f_write
FRESULT f_write (
FIL* fp, /* [IN] Pointer to the file object structure */
const void* buff, /* [IN] Pointer to the data to be written */
UINT btw, /* [IN] Number of bytes to write */
UINT* bw /* [OUT] Pointer to the variable to return number of bytes written */
);
f_size
FSIZE_t f_size (
FIL* fp /* [IN] File object */
);
3.5FatFs应用编程下
3.5.1实际文件系统应用案例分析
//远程终端单元( Remote Terminal Unit,RTU)
3.5.2怎么储存历史数据呢
历史数据的目的是什么
csv格式文件
注意用英文逗号
3.5.3历史数据储存功能实现
//´´½¨Îļþ
if(f_open(&SDFile,(const char*)"Sensor.csv",FA_CREATE_ALWAYS|FA_WRITE) == FR_OK){
//¸ñʽ»¯ÎļþÁ÷
//´´½¨±íÍ·
sprintf(SensorBuff,"ÐòºÅ,ζÈ,ʪ¶È\r\n");
f_write(&SDFile,SensorBuff,strlen(SensorBuff),&u32Wbytes);
//Ñ»·Ð´Èë±íÏî
for(int i; i < 10; i++){
sprintf(SensorBuff,"%d,%d,%d,%d\r\n",i+1, i+20, i+30, i+40);
f_write(&SDFile,SensorBuff,strlen(SensorBuff),&u32Wbytes);
//ˢе½ÎļþÖÐ
// f_sync(&SDFile);
}
//¹Ø±ÕÎļþ£¬»º´æдÈëÎļþÄÚ
f_close(&SDFile);
}
3.6FatFs底层实现
3.6.1通用底层驱动API
3.6.2驱动包含哪些文件
ff_gen_drv.c
//FatFS 提供的通用驱动文件的实现
/**
* @brief Disk IO Driver structure definition
*/
typedef struct
{
DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
#if _USE_WRITE == 1
DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
#endif /* _USE_IOCTL == 1 */
}Diskio_drvTypeDef;
/**
* @brief Global Disk IO Drivers structure definition
*/
typedef struct
{
uint8_t is_initialized[_VOLUMES]; //磁盘是否初始化
const Diskio_drvTypeDef *drv[_VOLUMES]; //磁盘的驱动
uint8_t lun[_VOLUMES]; //磁盘的编号
volatile uint8_t nbr;
}Disk_drvTypeDef;
sd_diskio.c
//针对SD底层驱动实现,封装成为通用的底层驱动API
//如果使能freeRTOS,在read和Write里面,会用到操作系统的消息队列
bsp_driver_sd.c
//HAL库的二次封装,把所有基于SD卡的操作都在bsp_driver_sd实现
3.6.3驱动装载
/**
* @brief Links a compatible diskio driver/lun id and increments the number of active
* linked drivers.
* @note The number of linked drivers (volumes) is up to 10 due to FatFs limits.
* @param drv: pointer to the disk IO Driver structure
* @param path: pointer to the logical drive path
* @param lun : only used for USB Key Disk to add multi-lun management
else the parameter must be equal to 0
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, uint8_t lun)
{
uint8_t ret = 1;
uint8_t DiskNum = 0;
//判断是否超出了fatfs最大的卷数量
if(disk.nbr < _VOLUMES)
{
//未初始化
disk.is_initialized[disk.nbr] = 0;
//把驱动进行链接
disk.drv[disk.nbr] = drv;
disk.lun[disk.nbr] = lun;
DiskNum = disk.nbr++;
path[0] = DiskNum + '0'; //"1:/"
path[1] = ':';
path[2] = '/';
path[3] = 0;
ret = 0;
}
return ret;
}