<html><head><title>znfat.rar znFAT.c</title>
<LINK href="/inc/read_style.css" type=text/css rel=stylesheet></head>
<body>
<p><a href=http://www.pudn.com>www.pudn.com</a> > <a href="http://www.pudn.com/downloads193/sourcecode/embed/detail909939.html">znfat.rar</a> > znFAT.c, change:2009-07-17,size:48054b</p><!-- saved from http://www.pudn.com -->
<script src="/inc/gg_read1.js"></script><BR>
<pre name="code" class="c">
#include "znfat.h"
#include "sd.h" //存储设备的扇区读写驱动,这里是SD卡
//#include "ch375.h" //存储设备的扇区读写驱动,这里是U盘
//#include "cf.h"
#include "string.h"
/*******************************************************
+-----------------------------------------+
|振南电子 原创程序模块 znFAT文件系统 4.01 |
+-----------------------------------------+
此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
严禁随意用于商业目的,违者必究,后果自负
振南电子
->产品网站 http://www.znmcu.cn/
->产品论坛 http://bbs.znmcu.cn/
->产品网店 http://shop.znmcu.cn/
->产品咨询 QQ:987582714 MSN:yzn07@126.com
WW:yzn07
说明:znFAT经多方测试,确保其正确性与稳定性,请放心使用,
如有bug敬请告知,谢谢!!
********************************************************/
//全局变量定义
struct direntry data temp_rec;
INT8 temp_dir_name[13];
UINT32 temp_dir_cluster,temp_last_cluster;
UINT8 FAT32_Buffer[512]; //扇区数据读写缓冲区,由外部提供
extern struct FAT32_Init_Arg *pArg; //初始化参数结构体指针,用以指向某一存储设备的初始化参数结构体,由外部提供
unsigned char (*pRS)(unsigned long,unsigned char *); //指向实际存储设备的读扇区函数的函数指针,用以实现对设备的支持
unsigned char (*pWS)(unsigned long,unsigned char *); //指向实际存储设备的写扇区函数的函数指针,用以实现对设备的支持
extern unsigned char Dev_No;
/******************************************************************
- 功能描述:znFAT的存储设备底层驱动接口,读取存储设备的addr扇区的
512个字节的数据放入buf数据缓冲区中
- 隶属模块:znFAT文件系统模块
- 函数属性:内部(用于与存储设备的底层驱动对接)
- 参数说明:addr:扇区地址
buf:指向数据缓冲区
- 返回说明:0表示读取扇区成功,否则失败
- 注:这里加入了天狼星精华板上的三种存储设备,即SD卡(有效)、U盘、
CF卡通过在程序中动态的切换不同的设备驱动,从而实现多设备(即同
时对多种存储设备进行操作,比如从SD卡拷贝文件到U盘等等),不同
驱动的切换,只需要在程序中改变Dev_No这个全局变量的值即可
******************************************************************/
UINT8 FAT32_ReadSector(UINT32 addr,UINT8 *buf)
{
switch(Dev_No)
{
case SDCARD:
pRS=SD_Read_Sector;
break;
case UDISK:
//pRS=CH375_Read_Sector;
break;
case CFCARD:
//pRS=CF_Read_Sector;
//无
break;
case OTHER:
//无
break;
}
return (*pRS)(addr,buf); //替换成实际存储器的扇区读函数,这里是SD卡扇区读函数
}
/******************************************************************
- 功能描述:znFAT的存储设备底层驱动接口,将buf数据缓冲区中的512个
字节的数据写入到存储设备的addr扇区中
- 隶属模块:znFAT文件系统模块
- 函数属性:内部(用于与存储设备的底层驱动对接)
- 参数说明:addr:扇区地址
buf:指向数据缓冲区
- 返回说明:0表示读取扇区成功,否则失败
- 注:略
******************************************************************/
UINT8 FAT32_WriteSector(UINT32 addr,UINT8 *buf)
{
switch(Dev_No)
{
case SDCARD:
pWS=SD_Write_Sector;
break;
case UDISK:
//pWS=CH375_Write_Sector;
break;
case CFCARD:
//pWS=CF_Write_Sector;
//无
break;
case OTHER:
//无
break;
}
return (*pWS)(addr,buf); //替换成实际存储器的扇区写函数,这里是SD卡扇区写函数
}
/******************************************************************
- 功能描述:小端转大端,即LittleEndian车BigEndian
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:dat:指向要转为大端的字节序列
len:要转为大端的字节序列长度
- 返回说明:转为大端模式后,字节序列所表达的数据
- 注:比如:小端模块的 0x33 0x22 0x11 0x00 (低字节在前)
转为大端模式后为 0x00 0x11 0x22 0x33 (高字节在前)
所表达的数值为 0x00112233
(CISC的CPU通常是小端的,所以FAT32也设计为小端,而单片机
这种RISC的CPU,通常来说都是大端的,所以需要这个函数将字
节的存放次序进行调整,才能得到正确的数值)
******************************************************************/
UINT32 LE2BE(UINT8 *dat,UINT8 len)
{
UINT32 temp=0;
UINT32 fact=1;
UINT8 i=0;
for(i=0;i<len;i++)
{
temp+=dat[i]*fact;
fact*=256;
}
return temp;
}
/******************************************************************
- 功能描述:将小字字符转为大写
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:c:要转换为大写的字符
- 返回说明:要转换的字节的相应的大写字符
- 注:只对小写字符有效,如果不是a~z的小写字符,将直接返回
******************************************************************/
INT8 L2U(INT8 c)
{
if(c>='a' && c='z') return c+'A'-'a';
else return c;
}
/******************************************************************
- 功能描述:读取0扇区,检测有没有MBR(主引导记录)
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:无
- 返回说明:1表示检测到MBR,0表示没有检测到MBR
- 注:有些存储设备格式化为FAT32以后,没有MBR,则0扇区就是DBR
如果有MBR,就需要对其进行解析,以得到DBR的扇区位置,同时MBR中
还含分区、分区容量等信息
******************************************************************/
UINT8 FAT32_is_MBR()
{
UINT8 result;
FAT32_ReadSector(0,FAT32_Buffer);
if(FAT32_Buffer[0]!=0xeb)
{
result=1;
}
else
{
result=0;
}
return result;
}
/***********************************************************************
- 功能描述:得到DBR所在的扇区号(如果没有MBR,则DBR就在0扇区)
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:无
- 返回说明:DBR的扇区地址
- 注:DBR中包含了很多有用的参数信息,因此正确定位DBR扇区的位置,是极为
重要的,后面将有专门的函数对DBR进行解析,正确解析DBR是实现FAT32的
基础
***********************************************************************/
UINT16 FAT32_Find_DBR()
{
UINT16 sec_dbr;
FAT32_ReadSector(0,FAT32_Buffer);
if(FAT32_Buffer[0]!=0xeb)
{
sec_dbr=LE2BE(((((struct PartSector *)(FAT32_Buffer))->Part[0]).StartLBA),4);
}
else
{
sec_dbr=0;
}
return sec_dbr;
}
/***********************************************************************
- 功能描述:获取分区的总容量
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:无
- 返回说明:分区容量值,单位为M
- 注:这里得到的总容量是FAT32分区的容量,一定小于实际的物理容量
***********************************************************************/
UINT32 FAT32_Get_Total_Size()
{
UINT16 temp;
FAT32_ReadSector(pArg->BPB_Sector_No,FAT32_Buffer);
temp=((float)(LE2BE((((struct FAT32_BPB *)(FAT32_Buffer))->BPB_TotSec32),4)))*0.0004883;
return temp;
}
/***********************************************************************
- 功能描述:二分搜索
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:无
- 返回说明:分区容量值,单位为M
- 注:这里使用二分搜索算法,快速定位空闲簇的位置,如果从头开始一个个簇
检查是不是空闲,效率极低。快速定位到空闲簇直接影响到建立文件/目录
以及写入数据的效率
***********************************************************************/
UINT32 Binary_Search()
{
INT32 head,tail,tem