王 浩,郭兰英,惠 飞,贺春峰
(长安大学 信息工程学院,陕西 西安 710064)
随着嵌入式式技术的不断发展,ARM处理器凭借其高性能、廉价、耗能低的优质特性而得到广泛应用。文中主要针对货车动态称重系统中大量实时载重数据存取的需求,在ARM9嵌入式处理器和μC/OS-II操作系统基础上,设计实现了一种SD卡文件系统。该系统具有实时性强、存取速率高、易维护,易移植等特点。
本系统硬件开发平台处理器为S3C2440A,是三星公司推出的16/32位RISC微处理器[1],ARM920T内核,主频400 MHz,最高可达533 MHz,内部具有丰富的系统外围控制器和多种通信接口。SD卡支持SPI和SD两种通信模式,S3C2440A具有SD卡接口,支持SD总线模式,所以不再像低端的ARM处理器那样采用SPI模式,而是采用SD总线模式,这样可以大大提高SD卡的读写速度。S3C2440A与SD卡读写器的接口电路如图1所示。
SD 卡的 DAT0~DAT3、CLK(时钟线)和 CMD(命令线)分别连接到 S3C2440A的 SDDATA0~SDDATA3、SDCLK和SDCMD引脚。SD卡支持单线和宽总线的数据传输,宽总线数据一次传4位,数度更快,因此,此设计采用宽总线方式。
μC/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务小型的嵌入式操作系统,它采用可剥离式内核实施任务调度,实时性很强,而且每个任务具有唯一的优先级,能够保证就续表中任务优先级最高的任务优先执行。μC/OS-II大部分代码是用移植性很高的C语言编写的,只极少部分与处理器密切相关的部分代码用汇编语言编写[2],因此只需要做很少的工作就可以很方便地将它移植到各种不同构架的微处理器上。
为了增强软件的可移植性,易维护性,程序设计时采用层次化,模块化设计。模块化结构如图2所示,除了用来进行管理的操作系统外,共分为4个模块,包括SD卡底层驱动,文件系统,API接口,用户应用程序。底层驱动完成SD卡初始化,以及实质上的读写功能;文件系统采用PC机普遍支持的FAT32文件系统规范来设计,完成文件的创建,读写,删除功能;API接口封装文件系统提供的函数,供上层应用使用;用户应用程序通过调用文件系统提供的API函数,完成相应的功能。各个模块的具体实现下面会做以说明。
2.1.1 SD卡初始化
图1 SD卡接口电路Fig.1 SD card interface circuit
图2 SD卡文件系统模块化结构Fig.2 Modular structure of SD kard file system
SD卡读写操作都是基于命令的,通过向SD卡发送命令并读取命令的响应来实现对SD卡的控制。在SD卡读写之前,首先要进行初始化操作。这是确保SD卡能进行正常数据读写的前提,SD卡初始化完成了SD卡上电,确认,设置逻辑地址,使其进入传输状态以及设置总线带宽几大主要工作。需要注意的是,在发送使SD卡空闲命令CMD0之前至少等待74个时钟,确保SD卡进入SD总线模式。SD卡初始化代码编写如下:
U8 SD_Init(void)
{
U32 i;
rGPECON|=0xaaaaa800; /*设置 GPE5~10为SD卡功能*/
rSDIPRE=PCLK/(SD_BAUD_RATE) -1; /*SD 接口波特率为500 kh
rSDICON= (1<<4)|1; /*SD 类型, 时钟使能 */
rSDIFSTA=rSDIFSTA|(1<<16); /*FIFO 复位 */
for(i=0;i<0x1000;i++); /* 等待 74 个 SDCLK*/
CMD0(); /*先执行CMD0命令,使卡进入idel状态*/
Check_SD_OCR(); /*检测SD卡是否准备好*/
Read_Card_CID (SDCard_Info->CardCID); /*获取 SD卡的CID*/
Set_Card_RCA (0,&SDCard_Info->CardRCA) /* 设置RCA卡逻辑地址*/
/*CSD卡特性寄存器*/
Read_Card_CSD (SDCard_Info ->CardRCA,SDCard_Info->CardCSD);
/*选中卡入传输状态*/
Select_or_Deselect_Card(1,SDCard_Info->CardRCA);
/*设置总线带宽*/
Set_DataBus_Width(SDCard_Info->CardType,1,SDCard_Info->CardRCA);
return 1;
}
2.1.2 SD卡读写实现
初始化完戚之后,就可对SD卡进行读写操作,通过设置SDI数据控制寄存器SDIDCON来确定SD卡的读写长度,读操作时数据长度作没有明确限制,写操作时,每次写的长度必须为BLOCK的倍数。SD卡的读写可以一次性读写单块数据,也可以一次性读写多块数据,多块数据的读写结束时,要发送CMD12结束指令。主要实现函数:Write_Card_Block()-写入单块数据;Write_Card_Data()-写入多块数据;Read_Card_Block()-读多块数据;Read_Card_Data()-读多块数据。
2.2.1 FAT32文件系统概述
Windows95 OSR2和Windows 98开始支持FAT32文件系统,它是对早期DOS的FAT文件系统的增强,由于文件系统的核心--文件分配表FAT扩充为32位,所以称为FAT32文件系统。FAT32包含DBR、保留扇区、FAT1、FAT2(第一个FAT的备份)、根目录、数据区5部分。DBR(Dos Boot Record)是操作系统引导记录区;保留扇区是为了对DBR作备份或留待以后升级时用;文件分配表区共保存了两个相同的FAT表,文件所占用的存储空间(簇链)及空闲空间的管理都是通过FAT实现的;FAT32根目录区 (ROOT区)不再是固定区域、固定大小,可看作是数据区的一部分;数据区用来存放真正要记录的文件数据,本系统定义的一簇为4K个字节。
2.2.2 文件系统初始化
文件系统初始主要是读取SD卡的DBR扇区 (0扇区),并分析该扇区内容,从而获取每扇区字节数,每簇扇区数,FAT开始扇区号,根目录开始扇区号等关键信息,为文件的创建,读写等操作做准备,文件系统初始化函数代码如下:
void FAT32_Init(void)
{
FAT32_BPB*bpb;
FAT32_Read_Card_Sector (0,32*)FAT32_Buffer);/*DBR所在扇区*/
/*数据缓冲区指针转为FAT32_BPB型指针*/
bpb=(FAT32_BPB*)(FAT32_Buffer);
Disk_Info ->SectorsPerClust=(bpb ->BPB_SecCntPerClust[0]);/*每簇扇区数 */
/*每扇区字节数*/
Disk_Info->BytesPerSector=(bpb->BPB_BytesPerSec[1]<<8)|(bpb->BPB_BytesPerSec[0]);
*第一个FAT表扇区号,FAT表开始位置*/
Disk_Info ->FirstFATSector=(Disk_Info ->RsvdSecCnt) +Disk_Info->BPBSectorNum;
/*FAT表占用的扇区数,FAT表大小*/
Disk_Info->FATSecCnt=(bpb->BPB_SecCntPerFAT[3]<<24)|
(bpb->BPB_SecCntPerFAT[2]<<16)|
(bpb->BPB_SecCntPerFAT[1]<<8)|
(bpb->BPB_SecCntPerFAT[0]<<0);
/*根目录簇号*/
Disk_Info->FirstDirClust=(bpb->BPB_RootDirClust[3]<<24)|
(bpb->BPB_RootDirClust[2]<<16)|
(bpb->BPB_RootDirClust[1]<<8)|
(bpb->BPB_RootDirClust[0]<<0);
/*磁盘的总扇区数*/
Disk_Info->TotalSecCnt=(bpb->BPB_TotalSec32[3]<<24)|
(bpb->BPB_TotalSec32[2]<<16)|
(bpb->BPB_TotalSec32[1]<<8)|
(bpb->BPB_TotalSec32[0]<<0);
/*磁盘的总容量 ,以字节为单位*/
Disk_Info ->DiskTotalSize=(Disk_Info ->TotalSecCnt)*
(Disk_Info->BytesPerSector);
}
2.2.3 文件创建
SD卡上创建文件或目录的过程就是在文件目录表FDT中申请登记项的过程,为此程序设计时定义了如下结构体:typedef struct fat32_directory
{
char File_Name[8]; //文件名,不足部分以空格补充
char File_Extension[3]; //扩展名,不足部分以空格补充
U8 File_Attributes; //文件属性
U8 File_LowerCase; //0,保留给 window NT 使用
U8 File_CHundredth; //世纪
U8 File_CrtTime[2]; //创建时间
U8 File_CrtDate[2]; //创建日期
U8 File_ALastAccDate[2]; //最后访问日期
U8 File_FstClustHI[2]; //该文件开始簇号的高位字
U8 File_WrtTime[2]; //上次更新时间
U8 File_WrtDate[2]; //上次更新改日期
U8 File_FstClustLO[2]; //该文件开始簇号的低字位
U8 File_FileSize[4]; //文件大小
}FAT32_DIRECTORY;
在文件目录项FDT中申请登记项动作就是通过对上述结构体的操做来完成的,操作流程,也是文件创建流程如图3所示,当把SD卡插入卡插槽时,系统首先初始化SD卡,即读取SD卡的DBR扇区(0扇区)获取相关信息,接下来打开所要创建文件的路径,如果路径不存在,创建该路径,如果存在,搜寻FAT表,找空闲簇。再接下来把要创建的文件的相关信息(文件名,文件大小,创建时间,属性等)填入上述结构体,把该结构体写入文件目录项FDT,相应的扇区写入数据,最后更新FAT链表。文件创建实现函数为FAT32_Creat_File()。
2.2.4 文件读写
文件系统对SD卡上文件的管理都是以簇为单位进行的。要读文件,就要首先找到文件,查找文件就是把文件名和文件目录项FDT中的文件名匹配。如果匹配不成功,说明该文件不存,此时就可以利用函数FAT32_Creat_File()创建。如果匹配成功读就找到了该文件,在匹配成功的那个目录登记项中找到该文件的起始簇号,知道了该起始簇号,就可以根据FAT表中的簇链关系找到到第2簇,第3簇,直到最后一簇文件结束。写文件时,由于FAT2是FAT1的备份,要保证两者的一致性,就要对它们做同样的写操作。主要的函数有:FAT32_Open_File()-打开文件;FAT32_Read_File()-读文件;FAT32_Write_File()-写文件;FAT32_Close_File()-关闭文件。
2.2.5 文件删除
FAT32文件系统中所谓的删除实际上只是把文件名称的第一个字母改成一个特殊字符(在文件目录登记项上做一个删除标记),把文件在FAT表中占用的簇标记为空簇,但文件包含的数据仍在磁盘上,下次将新的文件保存到磁盘时,这些簇可能被新的文件使用,从而覆盖原来的数据。因此,只要不保存新的文件,被删除文件的数据实际上仍旧完整无缺地保存在磁盘上。文件删除函数为:FAT32_DeleteFile()。
API接口模块要是向用户应用程序提供文件的创建读写删除功能,该模块通过调用文件系统的相关函数来实现。主要的借口函数有:OS_CreateFile()-创建文件;OS_OpenFile()-打开文件;OS_WriteFile()-文件写入数据;OS_WriteFile()-读文件数据;OS_CloseFile ()-关闭文件;OS_DeleteFile-删除文件。
该模块通过直接运用文件系统提供的API接口函数完成对称重数据信息的操作,只需要对μC/OS-II操作系统直接负责,并不需要考虑文件系统的具体实现问题以及底层硬件驱动问题。
本设计作为货车车载动态称重系统的数据存储模块,采用容量大、体积小、性价比高的存储介质SD卡来存储长时间段的测量数据,对FAT32进行了裁剪,并结合SD卡的底层的读写程序,从而实现了嵌入式SD卡文件系统,这样就能很方便通过上位机对SD卡记录货车称重数据进行查询,综合分析以及备份。同时该方法为其它数据采集系统提供了一种非易失性存储器的解决方案,采集到的数据会以标准文件的格式记录到SD卡上,便于文件的统一管理。
[1]闪迪公司.SD卡用户手册 [EB/OL](2004).http://www.pudn.com/downloads77/ebook/detail293590.html.
[2]任哲.嵌入式实时操作系统μC/OS-II原理与应用 [M].北京:北京航空航天大学出版社,2009.
[3]纪竞舟,付宇卓.嵌入式Linux下的MMC/SD卡的原理及实现[J].计算机仿真,2005(1):160-163.JI Jing-zhou,FU Yu-zhuo.The theory and implementation of MMC/SD card based on embedded Linux[J].Computer Simulation,2005(1):160-163.
[4]石磊,袁杰.嵌入式系统中存储器性能研究[J].现代电子技术,2012(2):13-16.SHI Lei,YUAN Jie.Performance of DRAM in embedded system[J].Modern Electronics Technique,2012(2):13-16.
[5]陈正江.OMAP— L13 8处理器的SD卡 FAT文件系统读写[J].新器件新技术,2011(12):36-39.CHEN Zheng-jiang.Reading and writing SD card FAT file system with OMAP—L138[J].New Product&Tech,2011(12):36-39.
[6]马林.文件系统原理精解与数据恢复最佳实践 [M].北京:清华大学出版社,2009.