如果你正在设计一个带有可移动存储设备的系统,请尝试使用文件存储系统,比如FAT文件系统。乔治描述了如何利用系统打开文件,使用CF卡,以及执行其他基本操作。
Open Files and Perform Operations
If you are designing a system with a removable memory device, try
using a file storage system such as the FAT file system. George
describes how to open files with the system, use a CompactFlash
card, and perform other basic operations.
For the past two years, we ’ve been exploring the C language and
specifically how to use it in embedded systems. I’ve introduced you
to the language and described how to use it to construct typical
systems. I’ve also described how to include more aspects of a
design such as flowcharts, UML diagrams, and other development
tools. Well, it’s time to move on from the lower-level details of
the language and move up a level or two, although from time to time
I ’ll revisit the basics. Feel free to e-mail me if you have
questions about embedded C systems.
FAT FILE SYSTEMIf you’re planning an embedded system, it’s probably not going to
be a simple design with just a push button as an input and an LED
as an output.In today’s environment, it ’s going to be rather
complicated and full of features. How in the heck do you design
such a system? I will answer that question indirectly because I
don’t believe there is a simple single answer. There are families
of answers (or approaches) to the design. My goal is to present you
with several alternatives. Your goal is to understand each one and
decide how they might best fit your application.
If you ’ve been reading Circuit Cellar for the past few years, you
may remember reading articles about the FAT file system. A few of
the articles are listed at the end of this article.In fact, Jeff
Bachiochi recently completed a two-part series on the topic
(“Access SD Memory Cards,”Circuit Cellar 222 and 223, 2009).For
many of today ’s embedded systems,it ’s likely that one feature on
the requirements list is a removable memory device. Years ago, we
actually put EPROMs on plug-in memoryIf you want to design your own
file system, good luck. You ’ve got a lot of work ahead of
you and you ’ll need it. If, on the other hand, you want to
leverage the PC with Windows,MAC with OS X, and other off-the-shelf
computers (some using Linux), then look into using an existing file
system.cards. (Remember the early video games?) Today you would
either use a CompactFlash card or a MultiMediaCard (SD/MMC). To
meet that requirement, you need a hardware interface to the card,
and you have to design your own file system or use an existing file
system.
With DOS, Microsoft created a file system, the same system that
first appeared on floppy disks and evolved onto hard disks. As disk
capacity grew, the file system changed to make room for larger
capacity disks. That file system is referred to as FAT, FAT12,
FAT16, and FAT32. Somewhere in the mix of designs, long file names
were included. (Refer to the Resources at the end of the article
for information about the file systems.)
If you purchase a CF or SD/MMC memory card, it will come
preformatted in one of the FAT file systems.The problem you are
going to run into using the off-the-shelf cards is the same problem
you had with EPROM memory devices. The size of the devices keeps
growing and the one you designed with is no longer available or is
available only at a higher cost. Try to purchase a 1-KB EPROM (or
even a 32-KB device). If you need only 32 MB on a memory card,
that’s great today. But someday you’ll find that size is no longer
manufactured. As the device card grows, an older file system won’t
be able to access the entire available memory. And changing file
systems is a big task.
It looks like I’ve come up with more issues than answers (or even
the hope of answers). So, let’s get into the next part: “What are
we going to do?” From the top of the design pile, if you look at
the C language,you’ll find it supports file I/O. You’ll find a good
description at
http://en.wikipedia.org/wiki/C_file_input/output).
FILE OPs & PROTOTYPESThe most basic file operations are open, close, read, and write.
Their prototypes in C are in Listing 1.
There are alternatives to the basic reading and writing of one
character at a time. One common pair of procedures
is reading and writing a string (see Listing 2).
By now, you should be starting to understand what these prototypes
mean. The new construct in all of these prototypes is the FILE *fp.
It is a pointer to a structure that can be seen in Listing 3.
Every time you open a file using C, you are creating a structure
and filling in the details. The structure is all that is needed to
perform all the file operations that the C language has to offer.
This is a simple straightforward interface, and you should be
suspicious that it’s too easy. I suspect that there is a lot of
code to support the simplicity of this interface. For example,
*buffer is a pointer to a character buffer. What ’s up with that?
Where is that buffer stored and how big is it? A useful assignment
that would give you a lot of insight into this problem is to find
and review the Linux file I/O code.
OPEN A FILE
Let’s examine how to open a file.The fopen procedure takes two
parameters. The first is the complete file name including the path.
So E:\Data\CCI\Code\Test\TestFile.txt is a string that can be used
as a complete reference to the file. Note that it’s a string and
you pass a pointer to that string. If you are running C on a PC,
the OS takes care of translating that path and file name into a
specific hardware location. If you’re designing an embedded
system,you’re responsible for that translation.The second parameter
is the mode that you are using to open the file. Different modes
are “r ” (read),“w ” (write), and “a ” (append). With these and
other characters, you can specify operations, such as append, start
from the beginning, and open for both reading and writing.
The return parameter from the fopen procedure is a pointer to the
FILE data structure. If the pointer is NULL (a C-defined constant),
the command failed to open the file. Aren’t you glad you read and
paid close attention to my articles on structures and pointers!
(Refer to Circuit Cellar issues 198, 200, 202, 204, 206, 208, 210,
212, and 214.)
I am going to skip over the middle of the FAT file system design
and examine the lowest level interface to the hardware. It’s the
only other piece of information that’s solid at this point. Again
using the Internet, I came up with several links to CompactFlash
information.
CompactFlash
There are several ways to design a hardware interface around a CF
card.One simple method has eight registers (using three address
lines) that provide commands, data, and status information.Also,
either an 8- or 16-bit data interface is available. The hardware
interfacing to an SD/MMC card basically uses the serial peripheral
interface (SPI) format. I have not yet done this type of design
work, so I ’ll say no more at this point about SD/MMC card
interfacing. Again,refer to Jeff ’s articles for details about an
SD hardware interface.
The lowest level of CompactFlashhardware and software interface
canbe accomplished in the routines in Listing 4. The Init_CF()
routinegrounds the RESET pin on the CompactFlashcard. Note that not
allcards respond correctly or completelyto this reset. Some require
thatpower actually be removed. Somedesigns have a high-side FET
actuallydisconnecting the power supply.So look out.
The next four routines—CFCheck_RDY(), Wait_RDY(),
CFCheck_RDY_ALT(), and Wait_RDY_ALT()—look at a ready or alternate
ready signal from the CF card. This signal is the reply that
indicates that the CF card has completed the previous
operation.Sometimes you just want to look at the signal (the check
procedures);other times, you want to wait until the previous
operation has completed (the wait procedures). Be careful. You will
hang the system if you are waiting for a ready signal that never
materializes. This probably is not a good situation in an embedded
system.
The next four routines—ReadRegB(),ReadRegW(), WriteRegW(), and
WriteRegB()—all read and write to a register in the CF card.
Again,check the literature about Compact-Flash cards. The CF
hardware interface provides for an 8- or 16-bit data path. If
you’ve got a smaller system, an 8-bit interface might make the most
sense. If, on the other hand,you ’re looking for maximum
performance, the 16-bit data path is available.
The next four routines —ReadCF_SectorB(),
ReadCF_SectorW(),WriteCF_SectorB(), and WriteCF _SectorW()—read
from and write to a sector on the CF card. The basic information is
accessed in 512 × 8 bit or 256 × 16 bit blocks. A special routine
ReadIdentityInfoW() reads words from a specific card location to
get the identification information about the CF card. I included
the prototype for reading bytes ReadIdentityInfoB(),but I didn ’t
code that one because I have a 16-bit interface.
The next four routines—CFByte Swap(), Get8Bits(), Get16Bits(),and
Get32Bits()—deal with manipulating the data that has been read from
the card. CFByteSwap deals with the Big Endian/Little Endian
issues. This concerns the byte order used when saving data.
Murphy’s law says it won’t be what you want it to be. If these
Endian issues are a new topic to you, please look them up. The
GetnBits() routines return the specified amount of data from the
buffer. Different parameters are saved as 8, 16, or 32 bits for
efficiency.They are packed with no padding between parameters. Any
size parameter could start at any memory location.
The LBALocation is a 32-bit number specifying the location
(address) on the CF card. Disk drives use heads, cylinders, tracks,
and sectors to get to a specific location on a drive. The CF card
uses a formula that equates the LBALocation to a head, cylinder, or
sector notation.The LBALocation is the head (8 bits), cylinder (16
bits), and sector (8 bits), all combined into a 32-bit number.
APPLICATION REQUIREMENTSI think we’ve got both the highleveland the low-level ends of
thedesign covered. All you have to donext is fill in the middle. I
originallywanted to write this article as a callfor a FAT file
system design (sort of a “roll our own” project). But I cameto my
senses and decided this wastoo big a project to tackle. There areso
many CF cards and I should alsodeal with SD and MMC cards.
Also,each application has its ownresources and requirements.
Onesuch requirement is how many filescan be open. Each open file
has aFILE structure associated with itand probably buffers for
data. Ifyou’re building a simple system, orjust using the card for
programupdates, then a fancy file systemmakes no sense. On the
other hand,if you’ve got one of the new ARMCPUs with an Ethernet
interfacebuilt in (all for about $5) and lots ofsystem memory, then
you wouldwant and could use a much morerobust file system.
Let’s explore the FAT file systemin more detail, as designed
byMicrosoft and extended by the cardmanufacturers and others.
TheWikipedia reference is a good condensedexplanation of the
differentFAT versions. The original FAT,sometimes referred to as
FAT12, isprobably old enough that you don’tneed to support it. The
FAT16 versionsupports volumes up to 2 GB,and that’s probably
sufficient fortoday’s designs. But when will youno longer be able
to purchase 2-GBCF cards? When will the largercapacity cards be
less expensive? Itprobably won’t happen next year, butit probably
will in the next four tofive years. So designing a systemcompatible
with FAT16 has a shelflife and you better consider FAT32as a real
possibility. Why not designor plan for both?
Another consideration is long filename support. This is one
decisionthat’s clearly application-dependent.The systems I’m
working on canrequire all file names to be in the8.3 format (eight
characters for thename and three for the extension).And also any
directory names can belimited to eight characters. If yoursystem
can’t meet these requirements,you need to include supportfor long
file names.
The last major consideration isthe requirement that the CF or
SD/MMC card format be compatiblewith another computer system.
Astraightforward example is that thecard be readable and writable
in yourembedded system and in a PC. Thenthe questions become: Which
OS isthe PC running? Does that OS supportthe same file system as
yourembedded system does? If you aregoing to read and write
memorycards only in your system, compatibilitywith an existing OS
in not anissue.
WORKING WITH THE SYSTEMSo how does one work with theFAT file system? I urge you to
searchthe ’Net and get as much informationas you can stand. And
there is alot available. You’ll find that youneed to detect and
initialize thecard, read the identity information, and build the
information that youwill use to access the card from theidentity
information.
Jeff described this process for anSD card. In the files section of
thisarticle, I took code from a 2005 CircuitCellar article by Ivan
Sham,William Hue, and Pete Rizun andpassed it through
SourcePublisherfrom Scientific Toolworks (“PortableFAT Library for
MCU Applications,”
Circuit Cellar 176, 2005). I used thisprogram to document my work
andhelp organize other C code. I includedthe original files and the
outputfrom SourcePublisher. Together withthese links and Jeff’s
most recentcolumns, you now have an introductionto a file system.
But wait. There’s more. Nexttime, I’ll get into the heart of someC
code for a file system.
George Martin (
gmm50@att.net) began his career in the aerospace industry in1969. After five
years at a real job, he set out on his own and co-founded adesign
and manufacturing firm (
www.embedded-designer.com). His designs typicallyinclude servo-motion control, graphical
input and output, data acquisition,and remote control systems.
George is a charter member of the Ciarcia DesignWorks Team. He’s
currently working on a mobile communications system thatannounces
highway info. He is also a nationally ranked revolver shooter.
PROJECT FILESTo download code, go to
ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2009/224.
RESOURCESCompactFlash Association, “CF+ and CompactFlash Specification
Revision 2.0,” 2003.
Compu Phase, “Implementing FAT on CompactFlash cards, SD/MMC cards
and USB sticks,” 2008,
www.compuphase.com/mbr_fat.htm.
Microsoft Corp., “Microsoft Extensible Firmware Initiative FAT32
File System Specification,” 2000.
C. Quirke, “Understanding FAT,”
http://users.iafrica.com/c/cq/cquirke/fat.htm.
M. Samuels, “PIC a CompactFlash Card,” Circuit Cellar Online 127,
2001.
I. Sham, W. Hue, and P. Rizun, “Portable FAT Library for MCU
Applications,”Circuit Cellar 176, 2005.
Wikipedia, “CompactFlash,”
http://en.wikipedia.org/wiki/CompactFlash.
———, “File Allocation Table,”
http://en.wikipedia.org/wiki/File_Allocation_Table.