基于S3C2440和μC/OS的FAT文件系统的设计与实现
2013-08-20赵英俊
费 超,赵英俊
(华中科技大学 机械科学与工程学院,湖北 武汉 430074)
嵌入式实时操作系统μC/OS具有源代码公开、良好的实时性等优点,广泛应用于各种嵌入式系统中,特别是实时数据采集与处理的嵌入式系统。这种嵌入式系统往往需要存储大量的数据,并且需要将存储的数据方便地转移到PC平台进行后续的离线分析。
常见的嵌入式系统往往采用EEPROM外部存储芯片,容量小、速度慢而且不便于数据的移动,因此需要结合硬件平台选择一种大容量且具有移动灵活性的存储设备。另外,考虑到在PC平台的离线处理的便捷需要,存储系统采用广泛应用的FAT文件系统。
1 方案选择
由于S3C2440具有专门的SDIO接口,且SD卡具有容量大、速度快、移动灵活和安全性高等优点[1]。综合考虑,选择采用SD卡作为移动存储设备。
软件设计上,首先要实现在μC/OS下的SD卡驱动,同时要保证兼容标准SD卡和SDHC卡。完成SD卡驱动后,还要在基于μC/OS的嵌入式系统中方便地实现对FAT文件系统下的文件的多种操作。如果从无到有设计FAT文件系统软件模块,将费时费力并且难以保证软件模块的可靠性。因此,最好的方案是采用通用的FAT文件系统软件模块,只需要进行较少的移植工作,完成项目效率大大增加。
通用的 FAT 文件系统主要有 μC/FS、FatFs、EFSL、ZLG/FS、znFAT等。其中μC/FS是Micrium公司开发的一个商业用途的文件系统,兼容性、稳定性较好。ZLG/FS和znFAT主要面向学习用途。而FatFs是免费开源的项目,具有代码精简、易于移植、支持RTOS、支持Unicode长文件名等特点,特别是其提供的底层读写函数,具有读写块数量的参数,可以一次命令读写多个扇区,在速度与效率上具有明显优势,而μC/FS和EFSL都不提供块数量参数。因此,选择FatFs作为文件系统软件模块。
图1 系统总体结构图Fig.1 Structure diagram of the system
总体方案采用基于SDIO接口的SD卡存储设备和FatFs文件系统,其系统总体结构如图1所示。SD卡从S3C2440微处理器的SDIO接口接入硬件层,通过SD卡驱动程序提供给FatFs文件系统进行管理,然后用户在功能层调用FatFs提供的文件接口函数进行数据存储等任务。
2 硬件电路
如图2所示为本次SD卡硬件电路图,其中S3C2440微处理器上有SDIO控制器,连接的SD总线包括时钟线CLK、命令线CMD及4根数据线 (DAT0~DAT3)[2]。S3C2440通过SDIO接口与SD卡座相连,其中卡座上除了6根SD总线外,还有3根电源线,以及无卡检测引脚nCD和写保护引脚WP。其中nCD和WP是连接到卡座上的两个常开型机械开关,开关的另一端接地。当插入SD卡时,开关合上,nCD从高电平变为低电平,当插入的是未写保护的SD卡时,另一个开关也会合上,WP从高电平变为低电平,而未插入SD卡以及插入写保护的SD卡时,WP被上拉成高电平。SD卡侧面的写保护的拨动开关实现写保护的原理不是通过开闭SD卡内部的线路,而是通过不同位置作用于SD卡座内的机械弹性开关的开闭。SD卡有9个引脚,支持SD和SPI两种总线方式,其中SD总线方式又分为1位数据模式和4位数据模式,本文设计采用采用4位数据模式,可以获得更高传输速率,具体过程在SD卡驱动中实现。
图2 硬件电路图Fig.2 Hardware circuit diagram
3 软件实现
3.1 SD卡驱动
SD卡驱动程序的功能是给FatFs文件系统提供对SD卡的读写操作接口,屏蔽掉上层软件对硬件的直接操作,其中主要包括初始化SD卡、读数据、写数据等。现在市场上的SD卡有SD1.0协议下的标准容量卡、SD2.0协议下的标准容量卡和高容量卡(SDHC),为了使驱动程序兼容性好,必须同时支持这些类型。
在初始化SD卡时,要识别并记录SD卡的类型,然后在读写数据时,根据不同类型进行操作。SD卡通信是由主机控制,通过CMD线发出不同类型的命令(Command),然后被寻址的SD卡在CMD线上产生相应的响应(Response),当CMD线上是数据传输命令时,数据线DAT0或DAT0~DAT3接着进行数据传输。
SD卡初始化流程图如图 3所示,最开始初始化SD卡控制器时,配置SD卡工作在传输效率较高的4位数据传输模式。命令CMD0实现复位SD卡,使其进入到空闲状态,命令CMD8是SD2.0协议新增加的接口条件检查命令,用来检查电压匹配和扩展SD1.0协议中某些原有命令的功能,例如命令ACMD41在参数中增加了HCS(Host Capacity Support)位,在响应中增加了CCS(Card Capacity Status)位,同时也能根据SD卡是否产生响应来判断SD卡版本,SD1.0版本的SD卡不能识别该命令,不会产生响应。同时通过SD卡返回的响应中的CCS位来判断是否为SDHC卡。另外,针对读写SD卡时的差异,将SD卡总结为两种类型,标准容量SD卡 (包括SD1.0和SD2.0标准容量卡)和高容量SD卡,在后面进行读写数据时,要分别处理。最后发送命令CMD2和CMD3使SD卡从卡识别模式进入数据传输模式,处于等待状态,后面可以发送相关存储器访问命令。
在本设计中,结合FatFs的移植需要,将用到的存储器访问 命 令 有 块 读 取 命 令 (CMD17,CMD18), 块 写 入 命 令(CMD24,CMD25),其中 CMD17和 CMD24为单块操作命令,CMD18和CMD25为连续多块操作命令[3]。以下为标准容量SD卡和高容量SD卡在存储器访问命令上的主要功能区别。
1)存储器访问的命令参数(Command Argument)。标准容量SD卡的32位命令参数是对字节寻址,高容量SD卡的命令参数是对块寻址。
2)块长度。标准容量SD卡的块长度根据CMD16命令设置大小,而高容量SD卡的块大小固定为512字节,必须设置块大小寄存器为0x200。
除此之外,两者还有局部寻址、写保护、读写超时等方面的区别,针对以上主要区别,采用以下解决办法实现同时兼容两种SD卡。读写数据函数给上层文件系统模块提供对SD卡的块地址访问,并统一块大小为512Byte。如图 4为SD卡读取单块数据的流程图,在发送读取命令CMD17前先根据初始化SD卡时确定的卡类型来进行处理。
图3 SD卡初始化流程图Fig.3 SD cardinitialization flow chart
提供的变量是块地址,因此可以直接作为高容量卡的命令参数,而标准容量SD卡的命令参数是字节单位,需要块地址乘以块大小(512Byte),即左移9位,转换为字节地址。其他块读写命令CMD18、CMD24、CMD25处理办法与此相同,实现多块读取函数、单块写入函数、多块写入函数。
图4 读取单块数据流程图Fig.4 Flow chart of reading a block
SD卡驱动程序还支持SD卡插拔检测和写保护功能。配置无卡检测接入引脚为外部中断方式,并设计中断处理函数,随时通知软件系统当前SD卡的插拔状态。SD卡的写保护采用软件方式实现,实现方法有两种,一种是在SD卡的两个写数据的驱动函数开始处加入查询写保护引脚状态,一旦写保护开启,则通知软件系统,并取消执行后面写数据流程。另一种可选方法是在FatFs文件系统层实现。
3.2 FatFs文件系统移植
FatFS是一个为小型嵌入式系统设计的通用FAT文件系统模块。FatFs的编写遵循ANSI C,并且完全与磁盘I/O层分开。因此,它独立于硬件架构。它可以被嵌入到低成本的微控制器中而不需要做任何修改。FatFs已经封装了对文件系统层和磁盘管理层的操作。对它的移植,主要在于配置FatFs功能和写好SD卡驱动接口[4]。
FatFs的配置选项在ffconf.h中,实现文件系统接口函数的剪裁,需要结合嵌入式系统硬件平台和具体应用来设置。由于本次系统平台是小端模式,为了获得较好的软件性能,_WORD_ACCESS设为1,配置为字访问,比字节访问快;由于SD卡属于Menory Card,_MAX_SS必须设为512,代表块大小最大为512 Byte;其他采用默认设置即可。
底层接口函数有6个,位于diskio.c中,主要是调用SD卡驱动程序实现。
1)disk_initialize():磁盘初始化函数,调用 SD 卡初始化函数实现。
2)disk_read:读扇区函数,调用SD卡块读取函数实现。
3)disk_write:写扇区函数,调用SD卡块写入函数实现。
4)disk_status:状态检测函数,共包含三种返回状态,包括STA_NOINIT ( 未 初 始 化 )、STA_NODISK ( 无 磁 盘 )、STA_PROCTECTED(卡保护)。可以在此处查询SD卡写保护引脚的状态,返回STA_POCTECTED卡保护状态。正常返回0即可。
5)disk_ioctl:磁盘控制函数,包括获取磁盘容量等,在文件系统实现一些复杂功能时会用到,简单应用直接返回0即可。
6)get_fattime:获取当前系统时间,查询 S3C2440的实时时钟[5],并转换为32位无符号整数返回即可。
完成FatFs移植后,上层应用经常访问的API有:f_mount()注册或注销一个工作区域、f_open()打开或创建一个文件、f_close()关闭文件、f_read()读取数据、f_write()写数据、f_lseek()移动读写指针等。
4 实验测试
在μC/OS系统下增加数据存储任务测试FatFs文件系统能否满足本次数据采集系统数据保存的需要。其中数据采集部分是采用一个具有SPI接口的TLC2543模数转换器以200 Hz的采样频率采集12位精度的数据。数据存储任务实现将采集任务发送过来的缓存数据保存到SD卡中,存储任务[6]设计如图5所示。
采集并保存半小时的数据到SD卡中,关机后,将SD卡取出插入到计算机中,将文件中的数据绘制曲线,与数据采集输入的信号吻合,验证了FAT文件系统能够正常工作,并且已经满足当前数据采集系统数据存储和数据转移的需求。另外,系统运行过程中,由于软件实现了无卡检测功能,支持热插拔,系统可以长时间工作仍能稳定运行。
图5 数据存储任务流程图Fig.5 Flow chart of data storage task
5 结 论
本设计在硬件上采用S3C2440的SDIO接口实现底层驱动,软件上采用FatFs实现μC/OS下FAT文件系统的管理,满足数据存储和数据移动的需求。其中兼容标准SD卡和SDHC卡的驱动实现方法可以应用到其他具有SDIO接口的硬件平台,通用性好。另外,FatFs经过了大量用户的使用和测试,运行稳定可靠,并且其具有较多的上层接口,可以应用于更多复杂文件管理功能的任务。
[1]刘荣林,程晓东.基于ARM和μC/OS的SD卡文件系统设计[J].内蒙古大学学报:自然科学版,2009, 40(3):309-314.
LIU Rong-lin,CHENG Xiao-dong.Design of the SD card file systems based on ARM and μC/OS-Ⅱ [J].Journ al of Inner Mongolia University:Natural Science,2009,40(3):309-314.
[2]师超.SDIO接口的软硬件实现及性能评估[D].南京:东南大学,2006.
[3]SD Card Association.SD SpecificationsPart1:Physical LayerSimplifiedSpecification Version 2.00[EB/OL].(2006-09-25)[2013-03-10].https://www.sdcard.org/downloads/pls/simplified_specs/archive/part1_200.pdf.
[4]李世奇,董浩斌,李荣生.基于FatFs文件系统的SD卡存储器设计[J].测控技术,2011(12):79-81.
LI Shi-ji,DONG Hao-bin,LI Rong-sheng.Design of SD memory card based on FatFs file system[J].Measurement&Control Technology,2011(12):79-81.
[5]Samsungsemiconductor.S3C2440A32-BitCMOSMicrocontroller User’s Manual[EB/OL].(2004-06-03)[2013-3-11]http://wenku.baidu.com/view/2adfbaea5ef7ba0d 4a733b54.html.
[6]周慈航.基于嵌入式实时操作系统的程序设计技术[M].2版.北京:北京航空航天大学出版社,2011.