Select a fatfs File System

Source: Internet
Author: User

A file system is transplanted because you need it and don't want to write it on your own.

Let's talk about my hardware and development tools: connect to the CF card in the true ide mode (that is, equivalent to a hard disk), and Samsung S3C2440's ARM9. the development tool is the very old d version of ads1.2.

I have seen many commonly used file systems on the embedded system on the Internet, such as uC/Fs of ucoⅱ, CF card, hard disk, SD/mmccard, and NAND Flash, zlg/FS, which is only commercially available and requires silver. zlg/FS, we also found two open-source and free, one of which is called
Efsl, also known as fatfs.

Select a suitable file system without considering the copyright issue. There is nothing to say about the first uC/fs file system. The ucosii company developed, stability, and compatibility should not be poor. The second is zlg/Fs. Many of Zhou ligong's development boards provided the source code of the file system. They found a ready-made read/write hard disk on the Internet, but it was based on the processor of the lpc2200 series. The third is efsl,
It is an open-source project and is free of charge. You only need to provide two functions: Read sector and write sector. The fourth is fatfs. Like efsl, it is also an open-source project. There are several simpler functions than efsl for porting.


Here we will add some simple information about the CF card and hard disk. There are three modes of the CF card, one of which is called True ide. After the mode is connected, it will be the same as its model name, it is a hard disk. It reads and writes to it, which is equivalent to reading and writing to a hard disk. When the pin OE (which seems to be called Oe, refer to the CF card documentation for details) detects a low pull during power-on, the CF card enters the true ide mode. When reading and writing a hard disk, you can read or write up to 256 sectors (of course, you can also read one sector) when only one LBA command (read or write) is sent, number of read or write sectors in the slice
The time required to send a read or write command to read or write 256 sectors is much shorter than the time required to read or write 256 sectors, the efficiency is much higher. What I need now is a file system with fast read/write speed and high efficiency. Therefore, the underlying read/write sector must be able to read and write multiple sectors each time you write a command. The function of the read/write sector must have the sector counter (the previous count) parameter to meet the requirements.


UC/FS also found a code on the Internet. After reading the code, there are several standard layers: What hardware layer, file system layer, and API layer, and so on (For details, refer to the uC/fs documentation). For a company with ucoⅱ, the stability should be good. The functions to be provided are also read sectors, write sectors, and so on. However, the underlying read/write sector function does not need to provide the sector counter count parameter. That is to say, the file system cannot write only one read or write command, reading or writing multiple slices can greatly reduce the efficiency of a file system.


Then I read the file system efls, open-source projects, free projects, good things, and transplantation, which also provides functions such as read/write sectors, however, as with uC/FS, each read/write operation can only read and write one sector.

 

In desperation, I saw Zhou ligong's file system. I probably did not read the source code carefully. The hardware driver can read and write multiple sectors when sending a READ command, in addition, it feels relatively simple. Similarly, the layers are quite clear. What we need to do after porting is to modify the read/write sectors and other functions. So I started it. After a few days, the CF card was able to read and write data on the computer. Reading files from the CF card and printing them to the Super Terminal is okay. I thought everything was okay. I thought what we needed was the most important thing. The first thing was speed, then we started to test the speed. I don't know what to expect. I was shocked by a test! It's too fast. TMD, only 5 K bytes.
Every second !!!!! (My driver has been tested, M bytes per second), so I tracked it into the write and found a very, very, very serious problem: ZLG/FS provides a function for reading a byte, which is called ReadOneByte (***) for the time being, and then reads multiple bytes, or what are the functions used to read large bytes,

For (I = 0; I <N; I ++) ReadOneByte (***). This mechanism is not slow !!! So sadly, ZLG/FS was abandoned. This is a good thing to learn. If it is commercially available, it would be too far away !!!


I can't go to the file system, but I have to have a file storage protocol, or a file system called my own. I have written a simple storage protocol and tried it. It is very troublesome. However, if you write your own files on the file system, the writing will be exhausting. The writing will not necessarily be highly efficient, and the speed will be faster, I think it should be highly efficient for file systems.


I finally found out what I was using, FatFs, open source, free, and efficient! (Let's take a look at the disadvantages of several file systems. Due to Microsoft's FAT copyright issue, FatFs, ZLG/FS, and efsl support only DOS 8.3 file names, that is, an 8-byte file name ". ", then the three-byte extension is not supported by the UC/FS that I found. I don't know if it is supported in the updated version. Check which one day is available.
Change FatFs to support it ). At the bottom layer of FatFs, you can write a command to read and write multiple sectors. The read/write idea of FatFs design is very good. For small pieces of data, I store them through Buffer. For large pieces of data, I directly access them. This speed and efficiency are much higher.
:

The structure of the FatFs file system is also clear, as shown in the figure below:

In addition, the authors of FatFs wrote two articles: one is the authentic FatFs, which is suitable for large RAM devices and the other is FatFs/Tiny, which is suitable for small RAM systems, such as single-chip microcomputer, fatFs/Tiny takes up a small amount of RAM, at a lower read/write speed and less API functions. However, both support FAT12, FAT16, and FAT32 file systems.


 

The downloaded FatFs has two folders: doc and FatFs description, including features, system functions, and possible problems. The other is the source code folder src, A total of 8 files, diskio. c and diskio. h is the hardware layer, ff. c and ff. h is the file system layer of FatFs and the API layer of the file system.
Integer. h is the definition of the data type used by the file system,
Tff. c and tff. h is the file system layer of Tiny and the file system API layer. A 00readme.txt briefly introduces FatFSHE FatFs/Tiny, including the APIS they support and how to configure them.


The first problem of porting is the data type. Define the Data Type in integer. h. The second one is the configuration. Open ff. h (I used FatFs, not Tiny), _ MCU_ENDIAN
Choose whether your CPU is big endding or little endding. Generally, you use small-end storage. 1 is small-end, and 2 is large-end. This is very important. I will talk about it later. Others are configured according to your own needs. The instructions are clear enough, so I won't say much about it.


The third thing is to write the underlying driver functions, including:

  • Disk_initialize-Initialize disk drive
  • Disk_status-Get disk status
  • Disk_read-Read sector (s)
  • Disk_write-Write sector (s)
  • Disk_ioctl-Control device dependent features
  • Get_fattime-Get current time

All functions involve the selection of the first disk. If only one disk is used, ignore thisDrv
Parameters.

Disk_initialize. If not required, return 0 directly.

Disk_status

Disk_read-Read sector (s)
Disk_write-Write sector (s)
Read/write slice. Pay attention to the parameters!

Disk_ioctl needs to respond to the ctrl_sync, get_sector_count, and get_block_size commands. If the correct return value is 0

Res_ OK. res_error is returned incorrectly.
All commands are read from ctrl. The returned value only returns whether this operation is valid, and the data to be passed back is in the buff.
Here is my:
CTRL_SYNC
Command to directly return 0;
GET_SECTOR_COUNT
To obtain the number of available sectors (logical addressing is LBA addressing)
GET_BLOCK_SIZE
To obtain the number of bytes in each slice, for example, * (DWORD *) buff) = 512;
For other commands, res_parerr is returned.

The disk_ioctl function is used only during formatting. When debugging and reading/writing, this function directly returns 0 to be OK.

Get_fattime-obtain the system time. For the format, see the document. If not, return 0.

This porting will basically succeed, but it will not work on my board. Each time I execute several macro definitions, such
LD_WORD (ptr) (WORD) (* (WORD *) (BYTE *) (ptr) generates a DATA termination exception (data abort exception ), but a brother on the Internet (a brother on ouravr, the SD card, the IAR compiler, and the platform is STM32. It has been successful and the source code has been published. There is no problem here ), no problem. Analyze the meanings of these macros:

LD_WORD (ptr) (WORD) (* (WORD *) (BYTE *) (ptr ))
It is defined in little endding.

LD_WORD (ptr), LD is load, WORD is in integer. h defines a 16-bit unsigned number. What this requires is to load a 16-bit number, or two bytes, followed by the ptr parameter. (WORD) (* (WORD *) (BYTE *) (ptr). First, convert this ptr into a pointer pointing to BYTE data.(BYTE *)
To convert the pointer to a 16-bit unsigned number pointer (WORD *)
And then use"*
"To extract the data and convert it into an unsigned 16-bit data, this is only from the perspective of the C language. In fact, what this completes is from the position pointed by the ptr pointer, two bytes are taken out as a 16-bit unsigned number, and the two bytes are little endding, that is, the small-end mode, and the low-byte is 8-bit, the height is 8 bits.

In this case, the test defines a BYTE buf [512], defines a WORD type zz, and uses a pointer pt to let pt point
Buf [0], call LD_WORD (ptr), zz = LD_WORD (pt); no problem, point pt to buf [1], haha, the problem is coming out immediately, data termination exception, then I tested the odd number of pointers pointing to buf [3], buf [5], and so on. This is the problem. I am depressed. TMD, the compiler problem !!!! However, if you find the problem, you can solve the problem.
In the macro definition in ff. h, comment out this item and write these macro definitions into functions in ff. c. paste them here:
WORD LD_WORD (void * pt)
{
BYTE * PT = (BYTE *) pt; // defines a pointer to assign the value of the address pointed to by the current pointer to PT
Return (WORD) (PT [0] + PT [1] * 256); // calculate this 16-digit number (the 8-bit low is in front and the 8-bit high is in the back ), and a forced type conversion
// Change and return
}
Note that LD_WORD must return WORD. In this way, most compilers can also be compiled, but analyticdb does not work. There are three parts,
Finfo-> fsize = LD_DWORD (& dir [DIR_FileSize]);/* Size */
Finfo-> fdate = ld_word (& dir [dir_wrtdate]);/* date */
Finfo-> ftime = ld_word (& dir [dir_wrttime]);/* time */

Here, DIR is defined as const byte * dir. The Compiler reports that the type does not match. Therefore, several ld_word and ld_dword here are rewritten to define the same type:
Word ld_word_1 (const byte * PT)
{
Byte * PT = (byte *) pt;
Return (Word) (PT [0] + Pt [1] * 256 );
}

DWORD ld_dword_1 (const byte * PT)
{
Byte * PT = (byte *) pt;
Return (DWORD) Pt [0] + (DWORD) (PT [1] * 256) + (DWORD) (PT [2] * 65536) + (DWORD) (Pt [3] * 16777216 ));

}

The following is changed:
Finfo-> fsize = LD_DWORD_1 (& dir [DIR_FileSize]);/* Size */
Finfo-> fdate = LD_WORD_1 (& dir [DIR_WrtDate]);/* Date */
Finfo-> ftime = LD_WORD_1 (& dir [DIR_WrtTime]);/* Time */

Compile, all the way to OK, and then write a file, wow, Hahahaha !!!! Finally, it came out !!!! There is no problem in writing files, and reading is OK! @~~~~~ There is no problem with testing common functions, including formatting (f_mkfs, provided that your
Disk_ioctl no problem), test
The lower speed, read 6.5 MB of MP3, about 3 seconds, write this MB MP3 about seconds, barely meet the requirements, and then optimize the driver that can be faster! ~~~~~~~

Send a FatFs Official Website
Http://elm-chan.org/fsw/ff/00index_e.html

To sum up this porting, the almost failed problem lies in the pointer conversion problem of the compiler. I hope that the siblings will not encounter this problem during the porting.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.