Transplantation of fatfs File System

Source: Internet
Author: User

I haven't updated my blog for a long time. I am very busy. I have transplanted a file system two days ago. I feel that I am still wrong, so I am afraid I will forget it, second, we can give more reference to our friends so that we can take less detours, so we will take the time to write down it.

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 versions, one of which is efsl and the other is 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, which 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 are some simple information about the CF card and hard disk. the CF card has three modes, one of which is true.
IDE, connected to this mode, is the same as his mode name, he is a hard disk, read and write to him, it is equivalent to reading and writing to a hard disk. When the pin OE (it seems to be called Oe, For details, refer
CF card documentation) when the power-on detects a low pull, then 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, read or write more
The time required to read or write a command to read or write 256 sectors, it takes much less time to read and write these sectors than 256 times, and the efficiency is much higher. What I need now is a file system with fast read and 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 more information, see the uC/fs documentation ).
Division, stability should be good, the function to be provided is also read sector, write sector and so on several. However, the function of the underlying read/write sector does not need to provide the slice counter count parameter.
The file system cannot read or write multiple sectors when writing only one read or write command. A file system with good performance will greatly reduce the efficiency.


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, and it feels relatively simple, the same
As shown in the preceding figure, the layers are also 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 can read and write data.
No problem. 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 start testing the speed.
Degree, unexpected don't know, a test scared! It's too fast. TMD, only 5 to 6 K bytes per second !!!!! (My driver has been tested, with M bytes per second)
So I tracked the data and found a very, very, and very serious problem: zlg/fs provides a function to read a byte. I forgot what it is called.
Readonebyte (***), then read multiple bytes, or read the functions of 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 the file system is on
If writing is exhausting, writing is not necessarily efficient, and the speed is fast. Therefore, you can find a file system that is highly efficient on the Internet.


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 day is free and change the fatfs, let him 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. I store small pieces of data through the buffer. I directly access large pieces of data, which is much faster and more efficient, figure:

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, one of which is Doc release, which briefly introduces fatfshe fatfs/tiny, including the APIS they support and how to configure fatfs.


The first problem of porting is the data type. Define the Data Type in integer. h. The second is to configure and open ff. H (I used fatfs, not tiny), _ mcu_endian, choose whether your CPU is big endding or little endding, usually using small-end storage, 1 is a small terminal, 2 is a large terminal. 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 thisDRVParameters.

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_syncCommand to directly return 0;
Get_sector_countTo obtain the number of available sectors (logical addressing is LBA addressing)
Get_block_sizeTo 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 in integer. h defines a 16-bit unsigned number. What this requires is to load a 16-bit number, or two bytes, followed
PTR is a 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, 2 bytes are taken
A 16-bit unsigned number is taken out, and the two bytes are little endding, that is, the small-end mode, the low-byte is 8-bit, and the high-byte is 8-bit.

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 soon, the data termination exception occurs, and then the Pointer Points
Buf [3], Buf [5], and so on are odd. They are all such problems. I am depressed. TMD, compiler problems !!!! 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! @~~~~~ If you have tested common functions, there are no problems, including formatting (f_mkfs, provided that your disk_ioctl is correct) and testing
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 WebsiteHttp://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.

I did not write it a few days ago. I hope you can make it up today!

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.