📄 disk.c
字号:
#define IN_DISK
#include "SYS_Config.h"
#include "FS_Config.h"
#include "USART1.h"
#include "fat.h"
Disk_Info DiskInfo[MAX_DRIVES];//逻辑盘信息
/*********************************************************************************************************
** 函数名称: DiskInit
** 功能描述: 初始化逻辑盘管理模块
** 输 入: 无
** 输 出: 无
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
void DiskInit(void)
{
INT8U i ;
for(i=0;i<MAX_DRIVES;i++)
{
DiskInfo[i].Drive=EMPTY_DRIVE ; // 没有分配
DiskInfo[i].FATType=0xff ; // 无效的文件系统
DiskInfo[i].SecPerClus=0 ; // 每簇扇区数
DiskInfo[i].NumFATs=0 ; // FAT表数
DiskInfo[i].SecPerDisk=0xffffffff ; // 逻辑驱动器包含扇区数
DiskInfo[i].BytsPerSec=0 ; // 每扇区字节数
DiskInfo[i].RootDirTable=0 ; // 根目录开始扇区号(FAT32为开始簇号)
DiskInfo[i].RootSecCnt=0 ; // 根目录占用扇区数
DiskInfo[i].FATStartSec=0 ; // FAT表开始扇区号
DiskInfo[i].FATSecCnt=0 ; // 每个FAT占用扇区数
DiskInfo[i].DataStartSec=0 ; // 数据区开始扇区号
DiskInfo[i].PathClusIndex=0 ; // 当前目录
DiskInfo[i].DiskCommand=NULL ; // 驱动程序
}
CacheInit();
//初始化磁盘cache
}
/*********************************************************************************************************
** 函数名称: GetDiskInfo
** 功能描述: 获取指定逻辑盘信息
** 输 入: 逻辑盘号
** 输 出: 指向逻辑盘信息的结构体指针
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
Disk_Info *GetDiskInfo(INT8U Drive)
{
Disk_Info *Rt ;
Rt=NULL ;
if(Drive<MAX_DRIVES)
{
if(DiskInfo[Drive].Drive!=EMPTY_DRIVE)
{
Rt=DiskInfo+Drive ;
}
}
return Rt ;
}
/*********************************************************************************************************
** 函数名称: GetEmptyDiskInfoAddr
** 功能描述: 获取空闲逻辑盘
** 输 入: 无
** 输 出: 指向逻辑盘信息的结构体指针
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
Disk_Info *GetEmptyDiskInfoAddr(void)
{
INT8U i ;
Disk_Info *Rt ;
Rt=NULL ;
for(i=0;i<MAX_DRIVES;i++)
{
// 逻辑盘号空闲
if(DiskInfo[i].Drive==EMPTY_DRIVE)
{
Rt=DiskInfo+i ;
DiskInfo[i].Drive=i ;
break ;
}
}
return Rt ;
}
/*********************************************************************************************************
** 函数名称: AddFileDriver
** 功能描述: 增加一个底层驱动程序
** 输 入: DiskCommand:驱动程序接口函数
** 输 出: 无
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
void AddFileDriver( INT16U(* DiskCommand)(INT8U Command,void *Parameter) )
{
INT8U i ;
INT8U *Buf ;
INT16U temp ;
INT32U temp1 ;
if(DiskCommand==NULL)// 参数无效退出
{
return ;
}
if(DiskCommand(DISK_INIT,NULL)==DISK_INIT_NOT_OK)// 底层驱动初始化不成功退出
{
#if FS_DEBUG_EN
#if USART1_EN
Uart1_SendString("\nSD/MMC INIT NOT OK");//调试用,初始化失败
#endif
#endif
return ;
}
for(i=0;i<MAX_DRIVES;i++)/* 重新获取逻辑盘信息 */
{
/* 逻辑盘已分配 */
if(DiskInfo[i].Drive!=EMPTY_DRIVE)
{
Buf=OpenSec(DiskInfo[i].Drive,0);/* 打开扇区0(保留扇区) */
ReadSec(DiskInfo[i].Drive,0);
if(Buf!=NULL)
{
/* 每扇区字节数 */
DiskInfo[i].BytsPerSec=((INT16U)Buf[12]<<8)+Buf[11];
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 1.BytsPerSec:");//调试用,每扇区字节数
PUT_INT32U_DecTOString(DiskInfo[i].BytsPerSec);
}
#endif
#endif
/* 每簇扇区数 */
DiskInfo[i].SecPerClus=Buf[13];
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 2.SecPerClus:");//调试用 ,每簇扇区数
PUT_INT32U_DecTOString(DiskInfo[i].SecPerClus);
}
#endif
#endif
/* FAT开始扇区号 */
DiskInfo[i].FATStartSec=((INT16U)Buf[15]<<8)+Buf[14];
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 3.FATStartSec:");//调试用 ,FAT开始扇区号
PUT_INT32U_DecTOString(DiskInfo[i].FATStartSec);
}
#endif
#endif
/* FAT表占用扇区数 */
temp=((INT32U)Buf[23]<<8)+Buf[22];
if(temp!=0)
DiskInfo[i].FATSecCnt=temp ;
else
{
DiskInfo[i].FATSecCnt=((INT32U)Buf[37]<<8)+Buf[36];
DiskInfo[i].FATSecCnt|=(((INT32U)Buf[38]<<16)+((INT32U)Buf[39]<<24));
}
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 4.FATSecCnt:");//FAT表占用扇区数
PUT_INT32U_DecTOString(DiskInfo[i].FATSecCnt);
}
#endif
#endif
/* FAT表个数 */
DiskInfo[i].NumFATs=Buf[16];
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 5.NumFATs:");//调试用 ,FAT表个数
PUT_INT32U_DecTOString(DiskInfo[i].NumFATs);
}
#endif
#endif
/* 根目录占扇区数 */
DiskInfo[i].RootSecCnt=((((INT16U)Buf[18]<<8)+Buf[17])*32+DiskInfo[i].BytsPerSec-1)/DiskInfo[i].BytsPerSec ;
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 6.RootSecCnt:");//根目录占扇区数
PUT_INT32U_DecTOString(DiskInfo[i].RootSecCnt);
}
#endif
#endif
/* 逻辑盘(卷)占扇区数 */
temp=((INT16U)Buf[20]<<8)+Buf[19];
if(temp!=0)
DiskInfo[i].SecPerDisk=temp ;
else
{
DiskInfo[i].SecPerDisk=((INT32U)Buf[33]<<8)+Buf[32];
DiskInfo[i].SecPerDisk|=(((INT32U)Buf[34]<<16)+((INT32U)Buf[35]<<24));
}
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 7.SecPerDisk:");//逻辑盘(卷)占扇区数
PUT_INT32U_DecTOString(DiskInfo[i].SecPerDisk);
}
#endif
#endif
DiskInfo[i].PathClusIndex=0 ;/* 当前目录为根目录 */
/* 根目录开始扇区号 */
DiskInfo[i].RootDirTable=DiskInfo[i].NumFATs*DiskInfo[i].FATSecCnt+DiskInfo[i].FATStartSec ;
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 8.RootDirTable:");//根目录开始扇区号
PUT_INT32U_DecTOString(DiskInfo[i].RootDirTable);
}
#endif
#endif
/* 数据区开始扇区号 */
DiskInfo[i].DataStartSec=DiskInfo[i].RootDirTable+DiskInfo[i].RootSecCnt ;
#if FS_DEBUG_EN
#if USART1_EN
{
Uart1_SendString("\n 9.DataStartSec:");//数据区开始扇区号
PUT_INT32U_DecTOString(DiskInfo[i].DataStartSec);
}
#endif
#endif
temp1=DiskInfo[i].SecPerDisk-DiskInfo[i].DataStartSec ;
temp1=temp1/DiskInfo[i].SecPerClus ;
DiskInfo[i].ClusPerData=temp1 ;
/* 判断是FAT12、FAT16还是FAT32 */
if(temp1<4085)
{
DiskInfo[i].FATType=FAT12 ;
#if FS_DEBUG_EN
#if USART1_EN
Uart1_SendString("\n10.File System is FAT12\n");//调试用
#endif
#endif
}
else if(temp1<65525)
{
DiskInfo[i].FATType=FAT16 ;
#if FS_DEBUG_EN
#if USART1_EN
Uart1_SendString("\n10.File System is FAT16\n");//调试用
#endif
#endif
}
else
{
DiskInfo[i].FATType=FAT32 ;
#if FS_DEBUG_EN
//#if USART1_EN
Uart1_SendString("\n10.File System is FAT32\n");//调试用
//#endif
#endif
/* FAT32 RootDirTable为开始簇号 */
DiskInfo[i].RootDirTable= ((INT32U)Buf[45]<<8)+Buf[44];
DiskInfo[i].RootDirTable|=(((INT32U)Buf[46]<<16)+((INT32U)Buf[47]<<24));
DiskInfo[i].PathClusIndex=DiskInfo[i].RootDirTable ;
}
}
CloseSec(DiskInfo[i].Drive,0);/* 关闭扇区 */
}
}
}
/*********************************************************************************************************
** 函数名称: RemoveFileDriver
** 功能描述: 删除一个底层驱动程序
** 输 入: Drive:逻辑驱动器号
** 输 出: 无
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
void RemoveFileDriver(INT8U Drive)
{
Disk_RW_Parameter Pa ;
if(Drive<MAX_DRIVES)
if(DiskInfo[Drive].Drive!=EMPTY_DRIVE)
{
AllCacheWriteBack();
Pa.Drive=Drive ;
Pa.RsvdForLow=DiskInfo[Drive].RsvdForLow ;
DiskInfo[Drive].DiskCommand(DISK_CLOSE,&Pa);
DiskInfo[Drive].Drive=EMPTY_DRIVE ; // 没有分配
DiskInfo[Drive].FATType=0xff ; // 无效的文件系统
DiskInfo[Drive].SecPerClus=0 ; // 每簇扇区数
DiskInfo[Drive].NumFATs=0 ; // FAT表数
DiskInfo[Drive].SecPerDisk=0xffffffff ;// 逻辑驱动器包含扇区数
DiskInfo[Drive].BytsPerSec=0 ; // 每扇区字节数
DiskInfo[Drive].RootDirTable=0 ; // 根目录开始扇区号(FAT32为开始簇号)
DiskInfo[Drive].RootSecCnt=0 ; // 根目录占用扇区数
DiskInfo[Drive].FATStartSec=0 ; // FAT表开始扇区号
DiskInfo[Drive].FATSecCnt=0 ; // 每个FAT占用扇区数
DiskInfo[Drive].DataStartSec=0 ; // 数据区开始扇区号
DiskInfo[Drive].PathClusIndex=0 ; // 当前目录
DiskInfo[Drive].DiskCommand=NULL ; // 驱动程序
}
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -